diff --git a/.chglog/CHANGELOG.tpl.md b/.chglog/CHANGELOG.tpl.md index e0ffe4235e82a87acf75d4151ccf437736e8282f..14a3f0fb9a7a7cfc7c31920fb8212caed3bb48a3 100644 --- a/.chglog/CHANGELOG.tpl.md +++ b/.chglog/CHANGELOG.tpl.md @@ -1,27 +1,14 @@ {{ range .Versions }} -<a name="{{ .Tag.Name }}"></a> ## {{ if .Tag.Previous }}[{{ .Tag.Name }}]{{ else }}{{ .Tag.Name }}{{ end }} - {{ datetime "2006-01-02" .Tag.Date }} + {{ range .CommitGroups -}} + ### {{ .Title }} + {{ range .Commits -}} - {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }} -{{ end }} -{{ end -}} +{{ end }}{{ end -}} -{{- if .NoteGroups -}} -{{ range .NoteGroups -}} -### {{ .Title }} -{{ range .Notes }} -{{ .Body }} -{{ end }} -{{ end -}} -{{ end -}} {{ end -}} -{{- if .Versions }} -{{ range .Versions -}} -{{ if .Tag.Previous -}} -[{{ .Tag.Name }}]: {{ $.Info.RepositoryURL }}/compare/{{ .Tag.Previous.Name }}...{{ .Tag.Name }} -{{ end -}} -{{ end -}} -{{ end -}} + diff --git a/.devenv.flake.nix b/.devenv.flake.nix new file mode 100644 index 0000000000000000000000000000000000000000..8b866efb12252518d596456356bc744e060a8c98 --- /dev/null +++ b/.devenv.flake.nix @@ -0,0 +1,81 @@ +{ + inputs = { + pre-commit-hooks.url = "github:cachix/pre-commit-hooks.nix"; + pre-commit-hooks.inputs.nixpkgs.follows = "nixpkgs"; + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + devenv.url = "github:cachix/devenv?dir=src/modules"; + } // (if builtins.pathExists ./.devenv/flake.json + then builtins.fromJSON (builtins.readFile ./.devenv/flake.json) + else {}); + + outputs = { nixpkgs, ... }@inputs: + let + devenv = if builtins.pathExists ./.devenv/devenv.json + then builtins.fromJSON (builtins.readFile ./.devenv/devenv.json) + else {}; + getOverlays = inputName: inputAttrs: + map (overlay: let + input = inputs.${inputName} or (throw "No such input `${inputName}` while trying to configure overlays."); + in input.overlays.${overlay} or (throw "Input `${inputName}` has no overlay called `${overlay}`. Supported overlays: ${nixpkgs.lib.concatStringsSep ", " (builtins.attrNames input.overlays)}")) + inputAttrs.overlays or []; + overlays = nixpkgs.lib.flatten (nixpkgs.lib.mapAttrsToList getOverlays (devenv.inputs or {})); + pkgs = import nixpkgs { + system = "x86_64-linux"; + config = { + allowUnfree = devenv.allowUnfree or false; + permittedInsecurePackages = devenv.permittedInsecurePackages or []; + }; + inherit overlays; + }; + lib = pkgs.lib; + importModule = path: + if lib.hasPrefix "./" path + then ./. + (builtins.substring 1 255 path) + "/devenv.nix" + else if lib.hasPrefix "../" path + then throw "devenv: ../ is not supported for imports" + else let + paths = lib.splitString "/" path; + name = builtins.head paths; + input = inputs.${name} or (throw "Unknown input ${name}"); + subpath = "/${lib.concatStringsSep "/" (builtins.tail paths)}"; + devenvpath = "${input}" + subpath + "/devenv.nix"; + in if builtins.pathExists devenvpath + then devenvpath + else throw (devenvpath + " file does not exist for input ${name}."); + project = pkgs.lib.evalModules { + specialArgs = inputs // { inherit inputs pkgs; }; + modules = [ + (inputs.devenv.modules + /top-level.nix) + { devenv.cliVersion = "0.6.3"; } + ] ++ (map importModule (devenv.imports or [])) ++ [ + ./devenv.nix + (devenv.devenv or {}) + (if builtins.pathExists ./devenv.local.nix then ./devenv.local.nix else {}) + ]; + }; + config = project.config; + + options = pkgs.nixosOptionsDoc { + options = builtins.removeAttrs project.options [ "_module" ]; + # Unpack Nix types, e.g. literalExpression, mDoc. + transformOptions = + let isDocType = v: builtins.elem v [ "literalDocBook" "literalExpression" "literalMD" "mdDoc" ]; + in lib.attrsets.mapAttrs (_: v: + if v ? _type && isDocType v._type then + v.text + else if v ? _type && v._type == "derivation" then + v.name + else + v + ); + }; + in { + packages."x86_64-linux" = { + optionsJSON = options.optionsJSON; + inherit (config) info procfileScript procfileEnv procfile; + ci = config.ciDerivation; + }; + devenv.containers = config.containers; + devShell."x86_64-linux" = config.shell; + }; +} diff --git a/.gitignore b/.gitignore index 4f27f08467d75ca41396d2e9900145f064616740..1e040552378bb322e771bb9931f7179e0d005db5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,13 +1,5 @@ - -# Makefile comes from update -Makefile.example - -# Vendor -/development/vendor/ -/deployment/vendor/ - -# Created by https://www.toptal.com/developers/gitignore/api/intellij+iml,phpunit,git,vim,visualstudiocode,phpstorm,go,intellij+all,netbeans,dbeaver,node,yarn -# Edit at https://www.toptal.com/developers/gitignore?templates=intellij+iml,phpunit,git,vim,visualstudiocode,phpstorm,go,intellij+all,netbeans,dbeaver,node,yarn +# Created by https://www.toptal.com/developers/gitignore/api/go,git,vim,node,yarn,dbeaver,netbeans,phpstorm,intellij+all,intellij+iml,visualstudiocode +# Edit at https://www.toptal.com/developers/gitignore?templates=go,git,vim,node,yarn,dbeaver,netbeans,phpstorm,intellij+all,intellij+iml,visualstudiocode ### DBeaver ### # ide config file @@ -51,10 +43,6 @@ Makefile.example # Go workspace file go.work -### Go Patch ### -/vendor/ -/Godeps/ - ### Intellij+all ### # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 @@ -433,21 +421,6 @@ dist # https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij .idea/**/azureSettings.xml -### PHPUnit ### -# Covers PHPUnit -# Reference: https://phpunit.de/ - -# Generated files -.phpunit.result.cache -.phpunit.cache - -# PHPUnit -/app/phpunit.xml -/phpunit.xml - -# Build data -/build/ - ### Vim ### # Swap [._]*.s[a-v][a-z] @@ -488,12 +461,6 @@ tags .history .ionide -# Support for Project snippet scope -.vscode/*.code-snippets - -# Ignore code-workspaces -*.code-workspace - ### yarn ### # https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored @@ -511,7 +478,10 @@ tags # and uncomment the following lines # .pnp.* -# Devenv +# End of https://www.toptal.com/developers/gitignore/api/go,git,vim,node,yarn,dbeaver,netbeans,phpstorm,intellij+all,intellij+iml,visualstudiocode + + +.attach* .devenv* devenv.local.nix .direnv diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 73f69e0958611ac6e00bde95641f6699030ad235..0000000000000000000000000000000000000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml -# Editor-based HTTP Client requests -/httpRequests/ diff --git a/.idea/aws.xml b/.idea/aws.xml deleted file mode 100644 index b6e463134d97f44b890129bade0da34e1b656553..0000000000000000000000000000000000000000 --- a/.idea/aws.xml +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project version="4"> - <component name="accountSettings"> - <option name="activeProfile" value="profile:default" /> - <option name="activeRegion" value="eu-west-1" /> - <option name="recentlyUsedProfiles"> - <list> - <option value="profile:default" /> - </list> - </option> - <option name="recentlyUsedRegions"> - <list> - <option value="eu-west-1" /> - <option value="eu-central-1" /> - </list> - </option> - </component> -</project> \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml deleted file mode 100644 index a55e7a179bde3e4e772c29c0c85e53354aa54618..0000000000000000000000000000000000000000 --- a/.idea/codeStyles/codeStyleConfig.xml +++ /dev/null @@ -1,5 +0,0 @@ -<component name="ProjectCodeStyleConfiguration"> - <state> - <option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" /> - </state> -</component> \ No newline at end of file diff --git a/.idea/dbnavigator.xml b/.idea/dbnavigator.xml deleted file mode 100644 index 915a3ce72f902ab37d27583c01aa990acc08f028..0000000000000000000000000000000000000000 --- a/.idea/dbnavigator.xml +++ /dev/null @@ -1,459 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project version="4"> - <component name="DBNavigator.Project.DataEditorManager"> - <record-view-column-sorting-type value="BY_INDEX" /> - <value-preview-text-wrapping value="true" /> - <value-preview-pinned value="false" /> - </component> - <component name="DBNavigator.Project.DataExportManager"> - <export-instructions> - <create-header value="true" /> - <friendly-headers value="false" /> - <quote-values-containing-separator value="true" /> - <quote-all-values value="false" /> - <value-separator value="" /> - <file-name value="" /> - <file-location value="" /> - <scope value="GLOBAL" /> - <destination value="FILE" /> - <format value="EXCEL" /> - <charset value="UTF-8" /> - </export-instructions> - </component> - <component name="DBNavigator.Project.DatabaseBrowserManager"> - <autoscroll-to-editor value="false" /> - <autoscroll-from-editor value="true" /> - <show-object-properties value="true" /> - <loaded-nodes /> - </component> - <component name="DBNavigator.Project.DatabaseFileManager"> - <open-files /> - </component> - <component name="DBNavigator.Project.EditorStateManager"> - <last-used-providers /> - </component> - <component name="DBNavigator.Project.ExecutionManager"> - <retain-sticky-names value="false" /> - </component> - <component name="DBNavigator.Project.MethodExecutionManager"> - <method-browser /> - <execution-history> - <group-entries value="true" /> - <execution-inputs /> - </execution-history> - <argument-values-cache /> - </component> - <component name="DBNavigator.Project.ObjectDependencyManager"> - <last-used-dependency-type value="INCOMING" /> - </component> - <component name="DBNavigator.Project.ObjectQuickFilterManager"> - <last-used-operator value="EQUAL" /> - <filters /> - </component> - <component name="DBNavigator.Project.ScriptExecutionManager" clear-outputs="true"> - <recently-used-interfaces /> - </component> - <component name="DBNavigator.Project.Settings"> - <connections /> - <browser-settings> - <general> - <display-mode value="TABBED" /> - <navigation-history-size value="100" /> - <show-object-details value="false" /> - </general> - <filters> - <object-type-filter> - <object-type name="SCHEMA" enabled="true" /> - <object-type name="USER" enabled="true" /> - <object-type name="ROLE" enabled="true" /> - <object-type name="PRIVILEGE" enabled="true" /> - <object-type name="CHARSET" enabled="true" /> - <object-type name="TABLE" enabled="true" /> - <object-type name="VIEW" enabled="true" /> - <object-type name="MATERIALIZED_VIEW" enabled="true" /> - <object-type name="NESTED_TABLE" enabled="true" /> - <object-type name="COLUMN" enabled="true" /> - <object-type name="INDEX" enabled="true" /> - <object-type name="CONSTRAINT" enabled="true" /> - <object-type name="DATASET_TRIGGER" enabled="true" /> - <object-type name="DATABASE_TRIGGER" enabled="true" /> - <object-type name="SYNONYM" enabled="true" /> - <object-type name="SEQUENCE" enabled="true" /> - <object-type name="PROCEDURE" enabled="true" /> - <object-type name="FUNCTION" enabled="true" /> - <object-type name="PACKAGE" enabled="true" /> - <object-type name="TYPE" enabled="true" /> - <object-type name="TYPE_ATTRIBUTE" enabled="true" /> - <object-type name="ARGUMENT" enabled="true" /> - <object-type name="DIMENSION" enabled="true" /> - <object-type name="CLUSTER" enabled="true" /> - <object-type name="DBLINK" enabled="true" /> - </object-type-filter> - </filters> - <sorting> - <object-type name="COLUMN" sorting-type="NAME" /> - <object-type name="FUNCTION" sorting-type="NAME" /> - <object-type name="PROCEDURE" sorting-type="NAME" /> - <object-type name="ARGUMENT" sorting-type="POSITION" /> - </sorting> - <default-editors> - <object-type name="VIEW" editor-type="SELECTION" /> - <object-type name="PACKAGE" editor-type="SELECTION" /> - <object-type name="TYPE" editor-type="SELECTION" /> - </default-editors> - </browser-settings> - <navigation-settings> - <lookup-filters> - <lookup-objects> - <object-type name="SCHEMA" enabled="true" /> - <object-type name="USER" enabled="false" /> - <object-type name="ROLE" enabled="false" /> - <object-type name="PRIVILEGE" enabled="false" /> - <object-type name="CHARSET" enabled="false" /> - <object-type name="TABLE" enabled="true" /> - <object-type name="VIEW" enabled="true" /> - <object-type name="MATERIALIZED VIEW" enabled="true" /> - <object-type name="INDEX" enabled="true" /> - <object-type name="CONSTRAINT" enabled="true" /> - <object-type name="DATASET TRIGGER" enabled="true" /> - <object-type name="DATABASE TRIGGER" enabled="true" /> - <object-type name="SYNONYM" enabled="false" /> - <object-type name="SEQUENCE" enabled="true" /> - <object-type name="PROCEDURE" enabled="true" /> - <object-type name="FUNCTION" enabled="true" /> - <object-type name="PACKAGE" enabled="true" /> - <object-type name="TYPE" enabled="true" /> - <object-type name="DIMENSION" enabled="false" /> - <object-type name="CLUSTER" enabled="false" /> - <object-type name="DBLINK" enabled="true" /> - </lookup-objects> - <force-database-load value="false" /> - <prompt-connection-selection value="true" /> - <prompt-schema-selection value="true" /> - </lookup-filters> - </navigation-settings> - <dataset-grid-settings> - <general> - <enable-zooming value="true" /> - <enable-column-tooltip value="true" /> - </general> - <sorting> - <nulls-first value="true" /> - <max-sorting-columns value="4" /> - </sorting> - <tracking-columns> - <columnNames value="" /> - <visible value="true" /> - <editable value="false" /> - </tracking-columns> - </dataset-grid-settings> - <dataset-editor-settings> - <text-editor-popup> - <active value="false" /> - <active-if-empty value="false" /> - <data-length-threshold value="100" /> - <popup-delay value="1000" /> - </text-editor-popup> - <values-actions-popup> - <show-popup-button value="true" /> - <element-count-threshold value="1000" /> - <data-length-threshold value="250" /> - </values-actions-popup> - <general> - <fetch-block-size value="100" /> - <fetch-timeout value="30" /> - <trim-whitespaces value="true" /> - <convert-empty-strings-to-null value="true" /> - <select-content-on-cell-edit value="true" /> - <large-value-preview-active value="true" /> - </general> - <filters> - <prompt-filter-dialog value="true" /> - <default-filter-type value="BASIC" /> - </filters> - <qualified-text-editor text-length-threshold="300"> - <content-types> - <content-type name="Text" enabled="true" /> - <content-type name="Properties" enabled="true" /> - <content-type name="XML" enabled="true" /> - <content-type name="DTD" enabled="true" /> - <content-type name="HTML" enabled="true" /> - <content-type name="XHTML" enabled="true" /> - <content-type name="CSS" enabled="true" /> - <content-type name="Java" enabled="true" /> - <content-type name="SQL" enabled="true" /> - <content-type name="PL/SQL" enabled="true" /> - <content-type name="JavaScript" enabled="true" /> - <content-type name="JSON" enabled="true" /> - <content-type name="JSON5" enabled="true" /> - <content-type name="PHP" enabled="true" /> - <content-type name="YAML" enabled="true" /> - <content-type name="Manifest" enabled="true" /> - </content-types> - </qualified-text-editor> - <record-navigation> - <navigation-target value="VIEWER" /> - </record-navigation> - </dataset-editor-settings> - <code-editor-settings> - <general> - <show-object-navigation-gutter value="false" /> - <show-spec-declaration-navigation-gutter value="true" /> - <enable-spellchecking value="true" /> - <enable-reference-spellchecking value="false" /> - </general> - <confirmations> - <save-changes value="false" /> - <revert-changes value="true" /> - </confirmations> - </code-editor-settings> - <code-completion-settings> - <filters> - <basic-filter> - <filter-element type="RESERVED_WORD" id="keyword" selected="true" /> - <filter-element type="RESERVED_WORD" id="function" selected="true" /> - <filter-element type="RESERVED_WORD" id="parameter" selected="true" /> - <filter-element type="RESERVED_WORD" id="datatype" selected="true" /> - <filter-element type="RESERVED_WORD" id="exception" selected="true" /> - <filter-element type="OBJECT" id="schema" selected="true" /> - <filter-element type="OBJECT" id="role" selected="true" /> - <filter-element type="OBJECT" id="user" selected="true" /> - <filter-element type="OBJECT" id="privilege" selected="true" /> - <user-schema> - <filter-element type="OBJECT" id="table" selected="true" /> - <filter-element type="OBJECT" id="view" selected="true" /> - <filter-element type="OBJECT" id="materialized view" selected="true" /> - <filter-element type="OBJECT" id="index" selected="true" /> - <filter-element type="OBJECT" id="constraint" selected="true" /> - <filter-element type="OBJECT" id="trigger" selected="true" /> - <filter-element type="OBJECT" id="synonym" selected="false" /> - <filter-element type="OBJECT" id="sequence" selected="true" /> - <filter-element type="OBJECT" id="procedure" selected="true" /> - <filter-element type="OBJECT" id="function" selected="true" /> - <filter-element type="OBJECT" id="package" selected="true" /> - <filter-element type="OBJECT" id="type" selected="true" /> - <filter-element type="OBJECT" id="dimension" selected="true" /> - <filter-element type="OBJECT" id="cluster" selected="true" /> - <filter-element type="OBJECT" id="dblink" selected="true" /> - </user-schema> - <public-schema> - <filter-element type="OBJECT" id="table" selected="false" /> - <filter-element type="OBJECT" id="view" selected="false" /> - <filter-element type="OBJECT" id="materialized view" selected="false" /> - <filter-element type="OBJECT" id="index" selected="false" /> - <filter-element type="OBJECT" id="constraint" selected="false" /> - <filter-element type="OBJECT" id="trigger" selected="false" /> - <filter-element type="OBJECT" id="synonym" selected="false" /> - <filter-element type="OBJECT" id="sequence" selected="false" /> - <filter-element type="OBJECT" id="procedure" selected="false" /> - <filter-element type="OBJECT" id="function" selected="false" /> - <filter-element type="OBJECT" id="package" selected="false" /> - <filter-element type="OBJECT" id="type" selected="false" /> - <filter-element type="OBJECT" id="dimension" selected="false" /> - <filter-element type="OBJECT" id="cluster" selected="false" /> - <filter-element type="OBJECT" id="dblink" selected="false" /> - </public-schema> - <any-schema> - <filter-element type="OBJECT" id="table" selected="true" /> - <filter-element type="OBJECT" id="view" selected="true" /> - <filter-element type="OBJECT" id="materialized view" selected="true" /> - <filter-element type="OBJECT" id="index" selected="true" /> - <filter-element type="OBJECT" id="constraint" selected="true" /> - <filter-element type="OBJECT" id="trigger" selected="true" /> - <filter-element type="OBJECT" id="synonym" selected="true" /> - <filter-element type="OBJECT" id="sequence" selected="true" /> - <filter-element type="OBJECT" id="procedure" selected="true" /> - <filter-element type="OBJECT" id="function" selected="true" /> - <filter-element type="OBJECT" id="package" selected="true" /> - <filter-element type="OBJECT" id="type" selected="true" /> - <filter-element type="OBJECT" id="dimension" selected="true" /> - <filter-element type="OBJECT" id="cluster" selected="true" /> - <filter-element type="OBJECT" id="dblink" selected="true" /> - </any-schema> - </basic-filter> - <extended-filter> - <filter-element type="RESERVED_WORD" id="keyword" selected="true" /> - <filter-element type="RESERVED_WORD" id="function" selected="true" /> - <filter-element type="RESERVED_WORD" id="parameter" selected="true" /> - <filter-element type="RESERVED_WORD" id="datatype" selected="true" /> - <filter-element type="RESERVED_WORD" id="exception" selected="true" /> - <filter-element type="OBJECT" id="schema" selected="true" /> - <filter-element type="OBJECT" id="user" selected="true" /> - <filter-element type="OBJECT" id="role" selected="true" /> - <filter-element type="OBJECT" id="privilege" selected="true" /> - <user-schema> - <filter-element type="OBJECT" id="table" selected="true" /> - <filter-element type="OBJECT" id="view" selected="true" /> - <filter-element type="OBJECT" id="materialized view" selected="true" /> - <filter-element type="OBJECT" id="index" selected="true" /> - <filter-element type="OBJECT" id="constraint" selected="true" /> - <filter-element type="OBJECT" id="trigger" selected="true" /> - <filter-element type="OBJECT" id="synonym" selected="true" /> - <filter-element type="OBJECT" id="sequence" selected="true" /> - <filter-element type="OBJECT" id="procedure" selected="true" /> - <filter-element type="OBJECT" id="function" selected="true" /> - <filter-element type="OBJECT" id="package" selected="true" /> - <filter-element type="OBJECT" id="type" selected="true" /> - <filter-element type="OBJECT" id="dimension" selected="true" /> - <filter-element type="OBJECT" id="cluster" selected="true" /> - <filter-element type="OBJECT" id="dblink" selected="true" /> - </user-schema> - <public-schema> - <filter-element type="OBJECT" id="table" selected="true" /> - <filter-element type="OBJECT" id="view" selected="true" /> - <filter-element type="OBJECT" id="materialized view" selected="true" /> - <filter-element type="OBJECT" id="index" selected="true" /> - <filter-element type="OBJECT" id="constraint" selected="true" /> - <filter-element type="OBJECT" id="trigger" selected="true" /> - <filter-element type="OBJECT" id="synonym" selected="true" /> - <filter-element type="OBJECT" id="sequence" selected="true" /> - <filter-element type="OBJECT" id="procedure" selected="true" /> - <filter-element type="OBJECT" id="function" selected="true" /> - <filter-element type="OBJECT" id="package" selected="true" /> - <filter-element type="OBJECT" id="type" selected="true" /> - <filter-element type="OBJECT" id="dimension" selected="true" /> - <filter-element type="OBJECT" id="cluster" selected="true" /> - <filter-element type="OBJECT" id="dblink" selected="true" /> - </public-schema> - <any-schema> - <filter-element type="OBJECT" id="table" selected="true" /> - <filter-element type="OBJECT" id="view" selected="true" /> - <filter-element type="OBJECT" id="materialized view" selected="true" /> - <filter-element type="OBJECT" id="index" selected="true" /> - <filter-element type="OBJECT" id="constraint" selected="true" /> - <filter-element type="OBJECT" id="trigger" selected="true" /> - <filter-element type="OBJECT" id="synonym" selected="true" /> - <filter-element type="OBJECT" id="sequence" selected="true" /> - <filter-element type="OBJECT" id="procedure" selected="true" /> - <filter-element type="OBJECT" id="function" selected="true" /> - <filter-element type="OBJECT" id="package" selected="true" /> - <filter-element type="OBJECT" id="type" selected="true" /> - <filter-element type="OBJECT" id="dimension" selected="true" /> - <filter-element type="OBJECT" id="cluster" selected="true" /> - <filter-element type="OBJECT" id="dblink" selected="true" /> - </any-schema> - </extended-filter> - </filters> - <sorting enabled="true"> - <sorting-element type="RESERVED_WORD" id="keyword" /> - <sorting-element type="RESERVED_WORD" id="datatype" /> - <sorting-element type="OBJECT" id="column" /> - <sorting-element type="OBJECT" id="table" /> - <sorting-element type="OBJECT" id="view" /> - <sorting-element type="OBJECT" id="materialized view" /> - <sorting-element type="OBJECT" id="index" /> - <sorting-element type="OBJECT" id="constraint" /> - <sorting-element type="OBJECT" id="trigger" /> - <sorting-element type="OBJECT" id="synonym" /> - <sorting-element type="OBJECT" id="sequence" /> - <sorting-element type="OBJECT" id="procedure" /> - <sorting-element type="OBJECT" id="function" /> - <sorting-element type="OBJECT" id="package" /> - <sorting-element type="OBJECT" id="type" /> - <sorting-element type="OBJECT" id="dimension" /> - <sorting-element type="OBJECT" id="cluster" /> - <sorting-element type="OBJECT" id="dblink" /> - <sorting-element type="OBJECT" id="schema" /> - <sorting-element type="OBJECT" id="role" /> - <sorting-element type="OBJECT" id="user" /> - <sorting-element type="RESERVED_WORD" id="function" /> - <sorting-element type="RESERVED_WORD" id="parameter" /> - </sorting> - <format> - <enforce-code-style-case value="true" /> - </format> - </code-completion-settings> - <execution-engine-settings> - <statement-execution> - <fetch-block-size value="100" /> - <execution-timeout value="20" /> - <debug-execution-timeout value="600" /> - <focus-result value="false" /> - <prompt-execution value="false" /> - </statement-execution> - <script-execution> - <command-line-interfaces /> - <execution-timeout value="300" /> - </script-execution> - <method-execution> - <execution-timeout value="30" /> - <debug-execution-timeout value="600" /> - <parameter-history-size value="10" /> - </method-execution> - </execution-engine-settings> - <operation-settings> - <transactions> - <uncommitted-changes> - <on-project-close value="ASK" /> - <on-disconnect value="ASK" /> - <on-autocommit-toggle value="ASK" /> - </uncommitted-changes> - <multiple-uncommitted-changes> - <on-commit value="ASK" /> - <on-rollback value="ASK" /> - </multiple-uncommitted-changes> - </transactions> - <session-browser> - <disconnect-session value="ASK" /> - <kill-session value="ASK" /> - <reload-on-filter-change value="false" /> - </session-browser> - <compiler> - <compile-type value="KEEP" /> - <compile-dependencies value="ASK" /> - <always-show-controls value="false" /> - </compiler> - <debugger> - <debugger-type value="ASK" /> - <use-generic-runners value="true" /> - </debugger> - </operation-settings> - <ddl-file-settings> - <extensions> - <mapping file-type-id="VIEW" extensions="vw" /> - <mapping file-type-id="TRIGGER" extensions="trg" /> - <mapping file-type-id="PROCEDURE" extensions="prc" /> - <mapping file-type-id="FUNCTION" extensions="fnc" /> - <mapping file-type-id="PACKAGE" extensions="pkg" /> - <mapping file-type-id="PACKAGE_SPEC" extensions="pks" /> - <mapping file-type-id="PACKAGE_BODY" extensions="pkb" /> - <mapping file-type-id="TYPE" extensions="tpe" /> - <mapping file-type-id="TYPE_SPEC" extensions="tps" /> - <mapping file-type-id="TYPE_BODY" extensions="tpb" /> - </extensions> - <general> - <lookup-ddl-files value="true" /> - <create-ddl-files value="false" /> - <synchronize-ddl-files value="true" /> - <use-qualified-names value="false" /> - <make-scripts-rerunnable value="true" /> - </general> - </ddl-file-settings> - <general-settings> - <regional-settings> - <date-format value="MEDIUM" /> - <number-format value="UNGROUPED" /> - <locale value="SYSTEM_DEFAULT" /> - <use-custom-formats value="false" /> - </regional-settings> - <environment> - <environment-types> - <environment-type id="development" name="Development" description="Development environment" color="-2430209/-12296320" readonly-code="false" readonly-data="false" /> - <environment-type id="integration" name="Integration" description="Integration environment" color="-2621494/-12163514" readonly-code="true" readonly-data="false" /> - <environment-type id="production" name="Production" description="Productive environment" color="-11574/-10271420" readonly-code="true" readonly-data="true" /> - <environment-type id="other" name="Other" description="" color="-1576/-10724543" readonly-code="false" readonly-data="false" /> - </environment-types> - <visibility-settings> - <connection-tabs value="true" /> - <dialog-headers value="true" /> - <object-editor-tabs value="true" /> - <script-editor-tabs value="false" /> - <execution-result-tabs value="true" /> - </visibility-settings> - </environment> - </general-settings> - </component> - <component name="DBNavigator.Project.StatementExecutionManager"> - <execution-variables /> - </component> -</project> \ No newline at end of file diff --git a/.idea/fastRequestCollection.xml b/.idea/fastRequestCollection.xml deleted file mode 100644 index a433492a7727a3018c684dc0d7f70f3f028b6449..0000000000000000000000000000000000000000 --- a/.idea/fastRequestCollection.xml +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project version="4"> - <component name="fastRequestCollection"> - <option name="detail"> - <CollectionDetail> - <option name="childList"> - <list> - <CollectionDetail> - <option name="groupId" value="1" /> - <option name="id" value="1" /> - <option name="name" value="Default Group" /> - <option name="type" value="1" /> - </CollectionDetail> - </list> - </option> - <option name="groupId" value="-1" /> - <option name="id" value="0" /> - <option name="name" value="Root" /> - <option name="type" value="1" /> - </CollectionDetail> - </option> - </component> -</project> \ No newline at end of file diff --git a/.idea/git_toolbox_prj.xml b/.idea/git_toolbox_prj.xml deleted file mode 100644 index b3820067b4c6700f074fd771f517ee5d30b96dc5..0000000000000000000000000000000000000000 --- a/.idea/git_toolbox_prj.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project version="4"> - <component name="GitToolBoxProjectSettings"> - <option name="commitMessageIssueKeyValidationOverride"> - <BoolValueOverride> - <option name="enabled" value="true" /> - </BoolValueOverride> - </option> - <option name="commitMessageValidationConfigOverride"> - <CommitMessageValidationOverride> - <option name="enabled" value="true" /> - </CommitMessageValidationOverride> - </option> - </component> -</project> \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 699be15f1fab85f131663a8b41112926ac23deed..0000000000000000000000000000000000000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,129 +0,0 @@ -<component name="InspectionProjectProfileManager"> - <profile version="1.0"> - <option name="myName" value="Project Default" /> - <inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" /> - <inspection_tool class="ForgottenDebugOutputInspection" enabled="true" level="ERROR" enabled_by_default="true"> - <option name="configuration"> - <list> - <option value="\Codeception\Util\Debug::debug" /> - <option value="\Codeception\Util\Debug::pause" /> - <option value="\Doctrine\Common\Util\Debug::dump" /> - <option value="\Doctrine\Common\Util\Debug::export" /> - <option value="\Illuminate\Support\Debug\Dumper::dump" /> - <option value="\Symfony\Component\Debug\Debug::enable" /> - <option value="\Symfony\Component\Debug\DebugClassLoader::enable" /> - <option value="\Symfony\Component\Debug\ErrorHandler::register" /> - <option value="\Symfony\Component\Debug\ExceptionHandler::register" /> - <option value="\TYPO3\CMS\Core\Utility\DebugUtility::debug" /> - <option value="\Zend\Debug\Debug::dump" /> - <option value="\Zend\Di\Display\Console::export" /> - <option value="dd" /> - <option value="debug_print_backtrace" /> - <option value="debug_zval_dump" /> - <option value="dpm" /> - <option value="dpq" /> - <option value="dsm" /> - <option value="dump" /> - <option value="dvm" /> - <option value="error_log" /> - <option value="kpr" /> - <option value="phpinfo" /> - <option value="print_r" /> - <option value="var_dump" /> - <option value="var_export" /> - <option value="wp_die" /> - <option value="xdebug_break" /> - <option value="xdebug_call_class" /> - <option value="xdebug_call_file" /> - <option value="xdebug_call_function" /> - <option value="xdebug_call_line" /> - <option value="xdebug_code_coverage_started" /> - <option value="xdebug_debug_zval" /> - <option value="xdebug_debug_zval_stdout" /> - <option value="xdebug_dump_superglobals" /> - <option value="xdebug_enable" /> - <option value="xdebug_get_code_coverage" /> - <option value="xdebug_get_collected_errors" /> - <option value="xdebug_get_declared_vars" /> - <option value="xdebug_get_function_stack" /> - <option value="xdebug_get_headers" /> - <option value="xdebug_get_monitored_functions" /> - <option value="xdebug_get_profiler_filename" /> - <option value="xdebug_get_stack_depth" /> - <option value="xdebug_get_tracefile_name" /> - <option value="xdebug_is_enabled" /> - <option value="xdebug_memory_usage" /> - <option value="xdebug_peak_memory_usage" /> - <option value="xdebug_print_function_stack" /> - <option value="xdebug_start_code_coverage" /> - <option value="xdebug_start_error_collection" /> - <option value="xdebug_start_function_monitor" /> - <option value="xdebug_start_trace" /> - <option value="xdebug_stop_code_coverage" /> - <option value="xdebug_stop_error_collection" /> - <option value="xdebug_stop_function_monitor" /> - <option value="xdebug_stop_trace" /> - <option value="xdebug_time_index" /> - <option value="xdebug_var_dump" /> - </list> - </option> - <option name="migratedIntoUserSpace" value="true" /> - </inspection_tool> - <inspection_tool class="MdUnresolvedReference" enabled="false" level="TYPO" enabled_by_default="false" /> - <inspection_tool class="SecurityAdvisoriesInspection" enabled="true" level="WARNING" enabled_by_default="true"> - <option name="optionConfiguration"> - <list> - <option value="barryvdh/laravel-debugbar" /> - <option value="behat/behat" /> - <option value="brianium/paratest" /> - <option value="codeception/codeception" /> - <option value="codedungeon/phpunit-result-printer" /> - <option value="composer/composer" /> - <option value="doctrine/coding-standard" /> - <option value="filp/whoops" /> - <option value="friendsofphp/php-cs-fixer" /> - <option value="humbug/humbug" /> - <option value="infection/infection" /> - <option value="jakub-onderka/php-parallel-lint" /> - <option value="johnkary/phpunit-speedtrap" /> - <option value="kalessil/production-dependencies-guard" /> - <option value="mikey179/vfsStream" /> - <option value="mockery/mockery" /> - <option value="mybuilder/phpunit-accelerator" /> - <option value="orchestra/testbench" /> - <option value="pdepend/pdepend" /> - <option value="phan/phan" /> - <option value="phing/phing" /> - <option value="phpcompatibility/php-compatibility" /> - <option value="phpmd/phpmd" /> - <option value="phpro/grumphp" /> - <option value="phpspec/phpspec" /> - <option value="phpspec/prophecy" /> - <option value="phpstan/phpstan" /> - <option value="phpunit/phpunit" /> - <option value="povils/phpmnd" /> - <option value="roave/security-advisories" /> - <option value="satooshi/php-coveralls" /> - <option value="sebastian/phpcpd" /> - <option value="slevomat/coding-standard" /> - <option value="spatie/phpunit-watcher" /> - <option value="squizlabs/php_codesniffer" /> - <option value="sstalle/php7cc" /> - <option value="symfony/debug" /> - <option value="symfony/maker-bundle" /> - <option value="symfony/phpunit-bridge" /> - <option value="symfony/var-dumper" /> - <option value="vimeo/psalm" /> - <option value="wimg/php-compatibility" /> - <option value="wp-coding-standards/wpcs" /> - <option value="yiisoft/yii2-coding-standards" /> - <option value="yiisoft/yii2-debug" /> - <option value="yiisoft/yii2-gii" /> - <option value="zendframework/zend-coding-standard" /> - <option value="zendframework/zend-debug" /> - <option value="zendframework/zend-test" /> - </list> - </option> - </inspection_tool> - </profile> -</component> \ No newline at end of file diff --git a/.idea/markdown-navigator-enh.xml b/.idea/markdown-navigator-enh.xml deleted file mode 100644 index 6dd592746dbfe1c05e4423aaa835945f8c434b39..0000000000000000000000000000000000000000 --- a/.idea/markdown-navigator-enh.xml +++ /dev/null @@ -1,42 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project version="4"> - <component name="MarkdownEnhProjectSettings"> - <AnnotatorSettings targetHasSpaces="true" linkCaseMismatch="true" wikiCaseMismatch="true" wikiLinkHasDashes="true" notUnderWikiHome="true" targetNotWikiPageExt="true" notUnderSourceWikiHome="true" targetNameHasAnchor="true" targetPathHasAnchor="true" wikiLinkHasSlash="true" wikiLinkHasSubdir="true" wikiLinkHasOnlyAnchor="true" linkTargetsWikiHasExt="true" linkTargetsWikiHasBadExt="true" notUnderSameRepo="true" targetNotUnderVcs="false" linkNeedsExt="true" linkHasBadExt="true" linkTargetNeedsExt="true" linkTargetHasBadExt="true" wikiLinkNotInWiki="true" imageTargetNotInRaw="true" repoRelativeAcrossVcsRoots="true" multipleWikiTargetsMatch="true" unresolvedLinkReference="true" linkIsIgnored="true" anchorIsIgnored="true" anchorIsUnresolved="true" anchorLineReferenceIsUnresolved="true" anchorLineReferenceFormat="true" anchorHasDuplicates="true" abbreviationDuplicates="true" abbreviationNotUsed="true" attributeIdDuplicateDefinition="true" attributeIdNotUsed="true" footnoteDuplicateDefinition="true" footnoteUnresolved="true" footnoteDuplicates="true" footnoteNotUsed="true" macroDuplicateDefinition="true" macroUnresolved="true" macroDuplicates="true" macroNotUsed="true" referenceDuplicateDefinition="true" referenceUnresolved="true" referenceDuplicates="true" referenceNotUsed="true" referenceUnresolvedNumericId="true" enumRefDuplicateDefinition="true" enumRefUnresolved="true" enumRefDuplicates="true" enumRefNotUsed="true" enumRefLinkUnresolved="true" enumRefLinkDuplicates="true" simTocUpdateNeeded="true" simTocTitleSpaceNeeded="true" /> - <HtmlExportSettings updateOnSave="false" parentDir="" targetDir="" cssDir="css" scriptDir="js" plainHtml="false" imageDir="" copyLinkedImages="false" imagePathType="0" targetPathType="2" targetExt="" useTargetExt="false" noCssNoScripts="false" useElementStyleAttribute="false" linkToExportedHtml="true" exportOnSettingsChange="true" regenerateOnProjectOpen="false" linkFormatType="HTTP_ABSOLUTE" /> - <LinkMapSettings> - <textMaps /> - </LinkMapSettings> - </component> - <component name="MarkdownNavigatorHistory"> - <PasteImageHistory checkeredTransparentBackground="false" filename="image" directory="" onPasteImageTargetRef="3" onPasteLinkText="0" onPasteImageElement="1" onPasteLinkElement="1" onPasteReferenceElement="2" cornerRadius="20" borderColor="0" transparentColor="16777215" borderWidth="1" trimTop="0" trimBottom="0" trimLeft="0" trimRight="0" transparent="false" roundCorners="false" showPreview="true" bordered="false" scaled="false" cropped="false" hideInapplicableOperations="false" preserveLinkFormat="false" scale="50" scalingInterpolation="1" transparentTolerance="0" saveAsDefaultOnOK="false" linkFormat="0" addHighlights="false" showHighlightCoordinates="true" showHighlights="false" mouseSelectionAddsHighlight="false" outerFilled="false" outerFillColor="0" outerFillTransparent="true" outerFillAlpha="30"> - <highlightList /> - <directories /> - <filenames /> - </PasteImageHistory> - <CopyImageHistory checkeredTransparentBackground="false" filename="image" directory="" onPasteImageTargetRef="3" onPasteLinkText="0" onPasteImageElement="1" onPasteLinkElement="1" onPasteReferenceElement="2" cornerRadius="20" borderColor="0" transparentColor="16777215" borderWidth="1" trimTop="0" trimBottom="0" trimLeft="0" trimRight="0" transparent="false" roundCorners="false" showPreview="true" bordered="false" scaled="false" cropped="false" hideInapplicableOperations="false" preserveLinkFormat="false" scale="50" scalingInterpolation="1" transparentTolerance="0" saveAsDefaultOnOK="false" linkFormat="0" addHighlights="false" showHighlightCoordinates="true" showHighlights="false" mouseSelectionAddsHighlight="false" outerFilled="false" outerFillColor="0" outerFillTransparent="true" outerFillAlpha="30"> - <highlightList /> - <directories /> - <filenames /> - </CopyImageHistory> - <PasteLinkHistory onPasteImageTargetRef="3" onPasteTargetRef="1" onPasteLinkText="0" onPasteImageElement="1" onPasteLinkElement="1" onPasteWikiElement="2" onPasteReferenceElement="2" hideInapplicableOperations="false" preserveLinkFormat="false" useHeadingForLinkText="false" linkFormat="0" saveAsDefaultOnOK="false" /> - <TableToJsonHistory> - <entries /> - </TableToJsonHistory> - <TableSortHistory> - <entries> - <TableSortHistoryEntry name="" sortNumericSuffix="true"> - <columns> - <TableSortColumn index="0" isIncluded="true" isDescending="false" isNumeric="false" isNumericLast="false" headerText="command" /> - <TableSortColumn index="1" isIncluded="false" isDescending="false" isNumeric="false" isNumericLast="false" headerText="parameter" /> - <TableSortColumn index="2" isIncluded="false" isDescending="false" isNumeric="false" isNumericLast="false" headerText="alias" /> - <TableSortColumn index="3" isIncluded="false" isDescending="false" isNumeric="false" isNumericLast="false" headerText="description" /> - </columns> - <usedInFiles> - <option name="03-dom.md" /> - <option name="README.md" /> - </usedInFiles> - </TableSortHistoryEntry> - </entries> - </TableSortHistory> - </component> -</project> \ No newline at end of file diff --git a/.idea/markdown-navigator.xml b/.idea/markdown-navigator.xml deleted file mode 100644 index a2fc0864e7bc79d88eaf4d3f18785833dfe9d367..0000000000000000000000000000000000000000 --- a/.idea/markdown-navigator.xml +++ /dev/null @@ -1,62 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project version="4"> - <component name="MarkdownProjectSettings"> - <PreviewSettings splitEditorLayout="SPLIT" splitEditorPreview="PREVIEW" useGrayscaleRendering="false" zoomFactor="1.0" maxImageWidth="0" synchronizePreviewPosition="true" highlightPreviewType="LINE" highlightFadeOut="5" highlightOnTyping="true" synchronizeSourcePosition="true" verticallyAlignSourceAndPreviewSyncPosition="true" showSearchHighlightsInPreview="true" showSelectionInPreview="true" lastLayoutSetsDefault="false"> - <PanelProvider> - <provider providerId="com.vladsch.md.nav.editor.swing.html.panel" providerName="Default - Swing" /> - </PanelProvider> - </PreviewSettings> - <ParserSettings gitHubSyntaxChange="false" correctedInvalidSettings="false" emojiShortcuts="1" emojiImages="0"> - <PegdownExtensions> - <option name="ATXHEADERSPACE" value="true" /> - <option name="FENCED_CODE_BLOCKS" value="true" /> - <option name="INTELLIJ_DUMMY_IDENTIFIER" value="true" /> - <option name="RELAXEDHRULES" value="true" /> - <option name="STRIKETHROUGH" value="true" /> - <option name="TABLES" value="true" /> - <option name="TASKLISTITEMS" value="true" /> - </PegdownExtensions> - <ParserOptions> - <option name="COMMONMARK_LISTS" value="true" /> - <option name="EMOJI_SHORTCUTS" value="true" /> - <option name="GFM_TABLE_RENDERING" value="true" /> - <option name="PRODUCTION_SPEC_PARSER" value="true" /> - <option name="SIM_TOC_BLANK_LINE_SPACER" value="true" /> - </ParserOptions> - </ParserSettings> - <HtmlSettings headerTopEnabled="false" headerBottomEnabled="false" bodyTopEnabled="false" bodyBottomEnabled="false" addPageHeader="false" addAnchorLinks="false" anchorLinksWrapText="false" imageUriSerials="false" addDocTypeHtml="true" noParaTags="false" defaultUrlTitle="false" migratedPlantUml="true" migratedAnchorLinks="true" plantUmlConversion="0"> - <GeneratorProvider> - <provider providerId="com.vladsch.md.nav.editor.text.html.generator" providerName="Unmodified HTML Generator" /> - </GeneratorProvider> - <headerTop /> - <headerBottom /> - <bodyTop /> - <bodyBottom /> - <fencedCodeConversions> - <option name="c4plantuml" value="NONE" /> - <option name="ditaa" value="NONE" /> - <option name="erd" value="NONE" /> - <option name="graphviz" value="NONE" /> - <option name="latex" value="KATEX" /> - <option name="math" value="KATEX" /> - <option name="mermaid" value="NONE" /> - <option name="nomnoml" value="NONE" /> - <option name="plantuml" value="NONE" /> - <option name="puml" value="NONE" /> - <option name="svgbob" value="NONE" /> - <option name="umlet" value="NONE" /> - <option name="vega" value="NONE" /> - <option name="vegalite" value="NONE" /> - <option name="wavedrom" value="NONE" /> - </fencedCodeConversions> - </HtmlSettings> - <CssSettings previewScheme="UI_SCHEME" cssUri="" isCssUriEnabled="false" isCssUriSerial="true" isCssTextEnabled="false" isDynamicPageWidth="true"> - <StylesheetProvider> - <provider providerId="com.vladsch.md.nav.editor.text.html.css" providerName="No Stylesheet" /> - </StylesheetProvider> - <ScriptProviders /> - <cssText /> - <cssUriHistory /> - </CssSettings> - </component> -</project> \ No newline at end of file diff --git a/.idea/markdown.xml b/.idea/markdown.xml deleted file mode 100644 index ec0b30fa7ea2824af6923493653e32595b0907a8..0000000000000000000000000000000000000000 --- a/.idea/markdown.xml +++ /dev/null @@ -1,9 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project version="4"> - <component name="MarkdownSettings"> - <enabledExtensions> - <entry key="MermaidLanguageExtension" value="false" /> - <entry key="PlantUMLLanguageExtension" value="true" /> - </enabledExtensions> - </component> -</project> \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index a8e07707a3a886f1534aff0d65f0320ce89e30ff..ec328d0bbf68db9e7322932181cc811412e3ca87 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,13 +1,17 @@ <?xml version="1.0" encoding="UTF-8"?> <project version="4"> - <component name="JavaScriptSettings"> - <option name="languageLevel" value="FLOW" /> - </component> - <component name="PWA"> - <option name="enabled" value="true" /> - <option name="wasEnabledAtLeastOnce" value="true" /> - </component> - <component name="ProjectRootManager"> - <output url="file://$PROJECT_DIR$/out" /> + <component name="accountSettings"> + <option name="activeProfile" value="profile:default" /> + <option name="activeRegion" value="eu-west-1" /> + <option name="recentlyUsedProfiles"> + <list> + <option value="profile:default" /> + </list> + </option> + <option name="recentlyUsedRegions"> + <list> + <option value="eu-west-1" /> + </list> + </option> </component> </project> \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index dfffe473a0f9f70158c03e0b64ae57d7080434cb..0000000000000000000000000000000000000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,13 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project version="4"> - <component name="ProjectModuleManager"> - <modules> - <module fileurl="file://$PROJECT_DIR$/../../../../alvine/frontend/console/alvine.console/alvine.console.iml" filepath="$PROJECT_DIR$/../../../../alvine/frontend/console/alvine.console/alvine.console.iml" /> - <module fileurl="file://$PROJECT_DIR$/../web-components/form/form.iml" filepath="$PROJECT_DIR$/../web-components/form/form.iml" /> - <module fileurl="file://$PROJECT_DIR$/monster.iml" filepath="$PROJECT_DIR$/monster.iml" /> - <module fileurl="file://$PROJECT_DIR$/../web-components/notify/notify.iml" filepath="$PROJECT_DIR$/../web-components/notify/notify.iml" /> - <module fileurl="file://$PROJECT_DIR$/../web-components/template/template.iml" filepath="$PROJECT_DIR$/../web-components/template/template.iml" /> - <module fileurl="file://$PROJECT_DIR$/../web-components/treemenu/treemenu.iml" filepath="$PROJECT_DIR$/../web-components/treemenu/treemenu.iml" /> - </modules> - </component> -</project> \ No newline at end of file diff --git a/.idea/php-test-framework.xml b/.idea/php-test-framework.xml deleted file mode 100644 index 8297960c1d9432fd6adfdec8be281038d6add82c..0000000000000000000000000000000000000000 --- a/.idea/php-test-framework.xml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project version="4"> - <component name="PhpTestFrameworkVersionCache"> - <tools_cache> - <tool tool_name="PHPUnit"> - <cache> - <versions> - <info id="Local" version="9.5.8" /> - </versions> - </cache> - </tool> - </tools_cache> - </component> -</project> \ No newline at end of file diff --git a/.idea/php.xml b/.idea/php.xml deleted file mode 100644 index 5c4d9c85401df90a133e9a9daf2942be80b7e24a..0000000000000000000000000000000000000000 --- a/.idea/php.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project version="4"> - <component name="MessDetectorOptionsConfiguration"> - <option name="transferred" value="true" /> - </component> - <component name="PHPCSFixerOptionsConfiguration"> - <option name="transferred" value="true" /> - </component> - <component name="PHPCodeSnifferOptionsConfiguration"> - <option name="transferred" value="true" /> - </component> - <component name="PhpProjectSharedConfiguration" php_language_level="7.4"> - <option name="suggestChangeDefaultLanguageLevel" value="false" /> - </component> - <component name="PhpUnit"> - <phpunit_settings> - <PhpUnitSettings load_method="PHPUNIT_PHAR" custom_loader_path="$PROJECT_DIR$/../../../../alvine/components/alvine.application.workflow/deployment/vendor/phpunit-9.phar" phpunit_phar_path="$PROJECT_DIR$/../../../../alvine/components/alvine.application.workflow/deployment/vendor/phpunit-9.phar" /> - </phpunit_settings> - </component> -</project> \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1ddfbbc029bcab630581847471d7f238ec53..0000000000000000000000000000000000000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project version="4"> - <component name="VcsDirectoryMappings"> - <mapping directory="" vcs="Git" /> - </component> -</project> \ No newline at end of file diff --git a/development/.npmignore b/.npmignore similarity index 100% rename from development/.npmignore rename to .npmignore diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e3b0a1ebfef4872676c1a83314558b51292763f..dbb8d586fee1aeabbc41043e766a1c63b609bc1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,609 +1,613 @@ -<a name="v3.51.4"></a> +## [9.9.9] - 2023-06-19 + + ## [v3.51.4] - 2023-06-19 + ### Bug Fixes -- case if value === null +- case if value === null ### Changes -- update packages +- update packages -<a name="v3.51.3"></a> ## [v3.51.3] - 2023-06-19 + ### Code Refactoring -- introduce variable for better debugging +- introduce variable for better debugging -<a name="v3.51.2"></a> ## [v3.51.2] - 2023-06-19 + ### Bug Fixes -- [#122](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/122) +- [#122](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/122) -<a name="v3.51.1"></a> ## [v3.51.1] - 2023-06-19 + ### Bug Fixes -- issue [#121](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/121) bug in extractKeys +- issue [#121](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/121) bug in extractKeys -<a name="v3.51.0"></a> ## [v3.51.0] - 2023-06-15 + ### Changes -- update doc +- update doc -<a name="v3.50.0"></a> ## [v3.50.0] - 2023-05-24 + ### Add Features -- new datetimeformat +- new datetimeformat ### Changes -- update and format +- update and format -<a name="v3.49.0"></a> ## [v3.49.0] - 2023-05-07 + ### Changes -- update docs and struct +- update docs and struct -<a name="v3.48.0"></a> ## [v3.48.0] - 2023-05-07 + ### Bug Fixes -- tests +- tests ### Code Refactoring -- initCustomControlOptionCallback -> initCustomControlCallback +- initCustomControlOptionCallback -> initCustomControlCallback -<a name="v3.47.0"></a> ## [v3.47.0] - 2023-05-05 + ### Add Features -- configuration via callback host +- configuration via callback host -<a name="v3.46.0"></a> ## [v3.46.0] - 2023-05-02 + ### Bug Fixes -- tests +- tests ### Changes -- update packages +- update packages ### Code Refactoring -- attribute and form improvments +- attribute and form improvments -<a name="v3.44.1"></a> ## [v3.44.1] - 2023-05-01 + ### Bug Fixes -- Fixed mutation observer for custom controls. +- Fixed mutation observer for custom controls. -<a name="v3.44.0"></a> ## [v3.44.0] - 2023-05-01 + ### Changes -- doc +- doc ### Code Refactoring -- monitor all attribute changes +- monitor all attribute changes -<a name="v3.43.0"></a> ## [v3.43.0] - 2023-04-07 + ### Add Features -- new DataFetchError +- new DataFetchError -<a name="v3.42.1"></a> ## [v3.42.1] - 2023-04-03 + ### Bug Fixes -- watch only if Object.keys(self[attributeObserverSymbol].length > 0) +- watch only if Object.keys(self[attributeObserverSymbol].length > 0) -<a name="v3.42.0"></a> ## [v3.42.0] - 2023-04-03 + ### Changes -- update +- update -<a name="v3.41.0"></a> ## [v3.41.0] - 2023-04-03 + ### Changes -- update +- update -<a name="v3.40.0"></a> ## [v3.40.0] - 2023-04-03 + ### Add Features -- attribure observer +- attribure observer -<a name="v3.39.1"></a> ## [v3.39.1] - 2023-04-03 + ### Bug Fixes -- this[attributeObserverSymbol] = {}; should defined before +- this[attributeObserverSymbol] = {}; should defined before -<a name="v3.39.0"></a> ## [v3.39.0] - 2023-04-03 + ### Add Features -- monitoring attribute change +- monitoring attribute change -<a name="v3.38.1"></a> ## [v3.38.1] - 2023-04-03 + ### Bug Fixes -- case senstive options work now +- case senstive options work now ### Changes -- doc +- doc -<a name="v3.38.0"></a> ## [v3.38.0] - 2023-04-03 + ### Add Features -- new function initOptionsFromAttributes +- new function initOptionsFromAttributes -<a name="v3.37.0"></a> ## [v3.37.0] - 2023-04-02 + ### Add Features -- new functions parseBracketedKeyValueHash and createBracketedKeyValueHash +- new functions parseBracketedKeyValueHash and createBracketedKeyValueHash -<a name="v3.36.0"></a> ## [v3.36.0] - 2023-04-01 + ### Add Features -- new function getContainingDocument +- new function getContainingDocument -<a name="v3.35.4"></a> ## [v3.35.4] - 2023-03-28 + ### Bug Fixes -- check is value is a string +- check is value is a string -<a name="v3.35.3"></a> ## [v3.35.3] - 2023-03-28 -<a name="v3.35.2"></a> + ## [v3.35.2] - 2023-03-28 + ### Bug Fixes -- Updated regex to capture the negative sign +- Updated regex to capture the negative sign -<a name="v3.35.1"></a> ## [v3.35.1] - 2023-03-28 + ### Bug Fixes -- invalid input throws TypeError +- invalid input throws TypeError -<a name="v3.35.0"></a> ## [v3.35.0] - 2023-03-27 + ### Changes -- tidy and doc +- tidy and doc ### Documentation -- update +- update -<a name="v3.34.0"></a> ## [v3.34.0] - 2023-03-27 + ### Add Features -- new function detectRuntimeEnvironment and convertToPixels +- new function detectRuntimeEnvironment and convertToPixels ### Changes -- update packages +- update packages -<a name="v3.33.0"></a> ## [v3.33.0] - 2023-03-26 + ### Add Features -- new function getSlottedNodes() +- new function getSlottedNodes() ### Changes + - change since tag - updated packages - -<a name="v3.32.0"></a> ## [v3.32.0] - 2023-03-23 + ### Add Features + - \undefined and \null are special values - \undefined and \null are special values - -<a name="v3.31.1"></a> ## [v3.31.1] - 2023-03-20 + ### Bug Fixes + - check is attribute set - ATTRIBUTE_UPDATER_SELECT_THIS and no ATTRIBUTE_UPDATER_ATTRIBUTES fail - -<a name="v3.31.0"></a> ## [v3.31.0] - 2023-03-19 + ### Add Features -- new function generaterangecomparisonexpression +- new function generaterangecomparisonexpression -<a name="v3.30.0"></a> ## [v3.30.0] - 2023-03-16 + ### Add Features -- add util.findElementWithIdUpwards +- add util.findElementWithIdUpwards ### Changes -- update packages +- update packages -<a name="v3.29.0"></a> ## [v3.29.0] - 2023-03-16 + ### Add Features -- customevents are composed and should bubble across shadowRoot +- customevents are composed and should bubble across shadowRoot ### Changes -- update packages +- update packages -<a name="v3.28.0"></a> ## [v3.28.0] - 2023-03-14 + ### Add Features -- customcontrol.updatei18n can now plural rules +- customcontrol.updatei18n can now plural rules ### Changes -- update packages +- update packages -<a name="v3.27.0"></a> ## [v3.27.0] - 2023-03-14 + ### Add Features -- add instance getter +- add instance getter ### Changes -- update packages +- update packages -<a name="v3.26.0"></a> ## [v3.26.0] - 2023-03-08 + ### Add Features -- prevent has already defined error +- prevent has already defined error -<a name="v3.25.0"></a> ## [v3.25.0] - 2023-03-07 -<a name="v3.24.0"></a> + ## [v3.24.0] - 2023-03-07 + ### Add Features -- template mapping +- template mapping -<a name="v3.23.0"></a> ## [v3.23.0] - 2023-03-07 + ### Add Features -- template mapping +- template mapping ### Bug Fixes -- rebuild template insert hack +- rebuild template insert hack -<a name="v3.22.1"></a> ## [v3.22.1] - 2023-03-07 + ### Bug Fixes -- host checking +- host checking -<a name="v3.22.0"></a> ## [v3.22.0] - 2023-03-07 + ### Add Features -- check if element is in a shadowroot. +- check if element is in a shadowroot. -<a name="v3.21.1"></a> ## [v3.21.1] - 2023-03-07 + ### Changes -- update packages +- update packages ### Code Refactoring -- change fkt name internalTemplateLookUP git s +- change fkt name internalTemplateLookUP git s -<a name="v3.21.0"></a> ## [v3.21.0] - 2023-03-07 + ### Add Features -- new Template ID for insert +- new Template ID for insert -<a name="v3.20.0"></a> ## [v3.20.0] - 2023-03-01 + ### Add Features -- new equal command +- new equal command -<a name="v3.19.0"></a> ## [v3.19.0] - 2023-03-01 + ### Add Features -- new datetime and currency +- new datetime and currency -<a name="v3.18.0"></a> ## [v3.18.0] - 2023-02-28 + ### Add Features -- new contains and has-entries +- new contains and has-entries -<a name="v3.17.0"></a> ## [v3.17.0] - 2023-02-28 + ### Add Features -- new is- commands for transformer, not command +- new is- commands for transformer, not command -<a name="v3.16.1"></a> ## [v3.16.1] - 2023-02-26 + ### Changes + - update year - add pipe and i18n test - -<a name="v3.16.0"></a> ## [v3.16.0] - 2023-02-26 + ### Add Features -- new transformer commands (date, map, time, dayofweek, timestamp...) +- new transformer commands (date, map, time, dayofweek, timestamp...) -<a name="v3.15.0"></a> ## [v3.15.0] - 2023-02-23 + ### Add Features -- deprecate BaseWithOption in favorit of equipWithInternal +- deprecate BaseWithOption in favorit of equipWithInternal -<a name="v3.14.1"></a> ## [v3.14.1] - 2023-02-21 + ### Bug Fixes -- add empty strings +- add empty strings ### Changes -- add tests +- add tests -<a name="v3.14.0"></a> ## [v3.14.0] - 2023-02-21 + ### Add Features -- new transformer function concat +- new transformer function concat -<a name="v3.13.1"></a> ## [v3.13.1] - 2023-02-18 + ### Bug Fixes -- i18 does not work as first token +- i18 does not work as first token -<a name="v3.13.0"></a> ## [v3.13.0] - 2023-02-15 + ### Add Features -- new dom datasource +- new dom datasource ### Bug Fixes -- package updates +- package updates -<a name="v3.12.2"></a> ## [v3.12.2] - 2023-02-14 + ### Bug Fixes -- missing argument of the function read +- missing argument of the function read -<a name="v3.12.1"></a> ## [v3.12.1] - 2023-02-12 + ### Bug Fixes -- missing import +- missing import -<a name="v3.12.0"></a> ## [v3.12.0] - 2023-02-12 + ### Add Features -- add raw data to restapi respond +- add raw data to restapi respond -<a name="v3.11.0"></a> ## [v3.11.0] - 2023-02-12 + ### Add Features -- add callback configuration to restapi +- add callback configuration to restapi ### Changes + - update npm - update makefiles - -<a name="v3.10.1"></a> ## [v3.10.1] - 2023-02-04 + ### Bug Fixes -- make exeption messages more readable +- make exeption messages more readable -<a name="v3.10.0"></a> ## [v3.10.0] - 2023-02-04 + ### Add Features -- add CustomControl.updateI18n() +- add CustomControl.updateI18n() -<a name="v3.9.1"></a> ## [v3.9.1] - 2023-02-02 + ### Bug Fixes -- Object links can contain more objects +- Object links can contain more objects -<a name="v3.9.0"></a> ## [v3.9.0] - 2023-02-02 + ### Add Features -- document translations +- document translations ### Bug Fixes -- optimize i18n: transformer +- optimize i18n: transformer ### Changes + - move doc to monsterjs-org - write and update tests - change imports - -<a name="v3.8.0"></a> ## [v3.8.0] - 2023-02-01 + ### Add Features -- pathfinder now works with array +- pathfinder now works with array ### Changes + - code format (rome) - doc - docs - -<a name="v3.7.0"></a> ## [v3.7.0] - 2023-01-26 + ### Bug Fixes -- version test +- version test -<a name="v3.6.0"></a> ## [v3.6.0] - 2023-01-26 + ### Add Features -- add rome and do linting +- add rome and do linting ### Changes -- code format rome +- code format rome -<a name="v3.5.0"></a> ## [v3.5.0] - 2023-01-23 + ### Add Features + - check the navigator languages too - new embed i18n provider - ### Bug Fixes -- doc +- doc ### Changes + - update packages - update makefiles - move tutorials to monsterjs-org - -<a name="v3.4.2"></a> ## [v3.4.2] - 2023-01-15 + ### Bug Fixes -- error in the status processing +- error in the status processing ### Changes + - update makefiles - update makefiles - doc - -<a name="v3.4.1"></a> ## [v3.4.1] - 2023-01-08 + ### Bug Fixes -- writeerror has the wrong namespace +- writeerror has the wrong namespace -<a name="v3.4.0"></a> ## [v3.4.0] - 2023-01-08 + ### Add Features -- add new layer class Server +- add new layer class Server ### Changes -- remove unused code +- remove unused code -<a name="v3.3.0"></a> ## [v3.3.0] - 2023-01-07 + ### Add Features + - change to webconnect implementation - hide implementation in symbol - new Class - new Webconnect and Message - new Webconnect and Message - ### Changes -- doc +- doc -<a name="v3.2.0"></a> ## [v3.2.0] - 2023-01-06 + ### Add Features -- connect return now a promise +- connect return now a promise -<a name="v3.1.2"></a> ## [v3.1.2] - 2023-01-06 + ### Bug Fixes + - check read/write call - check socket state - -<a name="v3.1.1"></a> ## [v3.1.1] - 2023-01-06 + ### Bug Fixes -- wrong class name +- wrong class name -<a name="v3.1.0"></a> ## [v3.1.0] - 2023-01-06 + ### Add Features -- new websocket datasource +- new websocket datasource ### Bug Fixes + - return error in test - missing callbacks - ### Changes + - tests - administration changes - doc - remove unused import - doc + tidy - -<a name="v3.0.0"></a> ## [v3.0.0] - 2023-01-04 + ### Changes -- update web tests +- update web tests -<a name="v2.2.1"></a> ## [v2.2.1] - 2023-01-03 + ### Bug Fixes + - unreferenced value - add @@ to internal data symbol - -<a name="v2.2.0"></a> ## [v2.2.0] - 2023-01-02 + ### Add Features -- internalDataSymbol is now global symbol +- internalDataSymbol is now global symbol ### Changes + - update npm packages - add doc - -<a name="v2.1.1"></a> ## [v2.1.1] - 2022-12-30 + ### Bug Fixes -- symbols must be identical across realms. +- symbols must be identical across realms. -<a name="v2.1.0"></a> ## [v2.1.0] - 2022-12-30 + ### Add Features -- implement instanceof for multi realm +- implement instanceof for multi realm -<a name="v2.0.16"></a> ## [v2.0.16] - 2022-10-31 -<a name="v2.0.15"></a> + ## [v2.0.15] - 2022-10-31 + ### Changes + - commit save point - commit save point - commit save point @@ -661,106 +665,17 @@ - commit save point - commit save point - -<a name="1.30.1"></a> ## [1.30.1] - 2022-02-06 -<a name="1.31.0"></a> + ## [1.31.0] - 2022-02-05 -<a name="1.10.0"></a> + ## [1.10.0] - 2021-08-29 -<a name="1.9.0"></a> + ## [1.9.0] - 2021-08-17 -<a name="1.8.0"></a> + ## 1.8.0 - 2021-08-15 -[v3.51.4]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.51.3...v3.51.4 -[v3.51.3]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.51.2...v3.51.3 -[v3.51.2]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.51.1...v3.51.2 -[v3.51.1]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.51.0...v3.51.1 -[v3.51.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.50.0...v3.51.0 -[v3.50.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.49.0...v3.50.0 -[v3.49.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.48.0...v3.49.0 -[v3.48.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.47.0...v3.48.0 -[v3.47.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.46.0...v3.47.0 -[v3.46.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.44.1...v3.46.0 -[v3.44.1]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.44.0...v3.44.1 -[v3.44.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.43.0...v3.44.0 -[v3.43.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.42.1...v3.43.0 -[v3.42.1]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.42.0...v3.42.1 -[v3.42.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.41.0...v3.42.0 -[v3.41.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.40.0...v3.41.0 -[v3.40.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.39.1...v3.40.0 -[v3.39.1]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.39.0...v3.39.1 -[v3.39.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.38.1...v3.39.0 -[v3.38.1]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.38.0...v3.38.1 -[v3.38.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.37.0...v3.38.0 -[v3.37.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.36.0...v3.37.0 -[v3.36.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.35.4...v3.36.0 -[v3.35.4]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.35.3...v3.35.4 -[v3.35.3]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.35.2...v3.35.3 -[v3.35.2]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.35.1...v3.35.2 -[v3.35.1]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.35.0...v3.35.1 -[v3.35.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.34.0...v3.35.0 -[v3.34.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.33.0...v3.34.0 -[v3.33.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.32.0...v3.33.0 -[v3.32.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.31.1...v3.32.0 -[v3.31.1]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.31.0...v3.31.1 -[v3.31.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.30.0...v3.31.0 -[v3.30.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.29.0...v3.30.0 -[v3.29.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.28.0...v3.29.0 -[v3.28.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.27.0...v3.28.0 -[v3.27.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.26.0...v3.27.0 -[v3.26.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.25.0...v3.26.0 -[v3.25.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.24.0...v3.25.0 -[v3.24.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.23.0...v3.24.0 -[v3.23.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.22.1...v3.23.0 -[v3.22.1]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.22.0...v3.22.1 -[v3.22.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.21.1...v3.22.0 -[v3.21.1]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.21.0...v3.21.1 -[v3.21.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.20.0...v3.21.0 -[v3.20.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.19.0...v3.20.0 -[v3.19.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.18.0...v3.19.0 -[v3.18.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.17.0...v3.18.0 -[v3.17.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.16.1...v3.17.0 -[v3.16.1]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.16.0...v3.16.1 -[v3.16.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.15.0...v3.16.0 -[v3.15.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.14.1...v3.15.0 -[v3.14.1]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.14.0...v3.14.1 -[v3.14.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.13.1...v3.14.0 -[v3.13.1]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.13.0...v3.13.1 -[v3.13.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.12.2...v3.13.0 -[v3.12.2]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.12.1...v3.12.2 -[v3.12.1]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.12.0...v3.12.1 -[v3.12.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.11.0...v3.12.0 -[v3.11.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.10.1...v3.11.0 -[v3.10.1]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.10.0...v3.10.1 -[v3.10.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.9.1...v3.10.0 -[v3.9.1]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.9.0...v3.9.1 -[v3.9.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.8.0...v3.9.0 -[v3.8.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.7.0...v3.8.0 -[v3.7.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.6.0...v3.7.0 -[v3.6.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.5.0...v3.6.0 -[v3.5.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.4.2...v3.5.0 -[v3.4.2]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.4.1...v3.4.2 -[v3.4.1]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.4.0...v3.4.1 -[v3.4.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.3.0...v3.4.0 -[v3.3.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.2.0...v3.3.0 -[v3.2.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.1.2...v3.2.0 -[v3.1.2]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.1.1...v3.1.2 -[v3.1.1]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.1.0...v3.1.1 -[v3.1.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.0.0...v3.1.0 -[v3.0.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v2.2.1...v3.0.0 -[v2.2.1]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v2.2.0...v2.2.1 -[v2.2.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v2.1.1...v2.2.0 -[v2.1.1]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v2.1.0...v2.1.1 -[v2.1.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v2.0.16...v2.1.0 -[v2.0.16]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v2.0.15...v2.0.16 -[v2.0.15]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/1.30.1...v2.0.15 -[1.30.1]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/1.31.0...1.30.1 -[1.31.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/1.10.0...1.31.0 -[1.10.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/1.9.0...1.10.0 -[1.9.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/1.8.0...1.9.0 diff --git a/application/LICENSE b/LICENSE similarity index 100% rename from application/LICENSE rename to LICENSE diff --git a/Makefile b/Makefile deleted file mode 100644 index 1263639fe2e1596f5682efaf863fddee09e478d4..0000000000000000000000000000000000000000 --- a/Makefile +++ /dev/null @@ -1,105 +0,0 @@ -############################################################################################# -############################################################################################# -## -## PROJECT-DEFINITIONS -## -############################################################################################# -############################################################################################# - -COMPONENT_NAME := Monster - -############################################################################################# -############################################################################################# -## -## MORE GENERAL BLOCK WITH STANDARD DEFINITIONS -## -############################################################################################# -############################################################################################# - -# get Makefile directory name: http://stackoverflow.com/a/5982798/376773 -THIS_MAKEFILE_PATH:=$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)) -PROJECT_ROOT:=$(shell cd $(dir $(THIS_MAKEFILE_PATH));pwd)/ -THIS_MAKEFILE:=$(PROJECT_ROOT)$(THIS_MAKEFILE_PATH) - -# include project.mk only if it exists --include $(PROJECT_ROOT)project.mk - - -# Define the location of Makefiles -MAKEFILE_IMPORT_PATH?=$(PROJECT_ROOT)makefiles/ - -# include project.mk only if it exists --include $(MAKEFILE_IMPORT_PATH)project.mk - -############################################################################################# -############################################################################################# -## -## INCLUSION OF VARIOUS STANDARD RULES -## -############################################################################################# -############################################################################################# - -include $(MAKEFILE_IMPORT_PATH)directories-standard.mk -#include $(MAKEFILE_IMPORT_PATH)directories-go-lib.mk -#include $(MAKEFILE_IMPORT_PATH)directories-go-utilities.mk -#include $(MAKEFILE_IMPORT_PATH)directories-platform-part.mk -include $(MAKEFILE_IMPORT_PATH)go.mk -include $(MAKEFILE_IMPORT_PATH)jsdoc.mk -include $(MAKEFILE_IMPORT_PATH)output.mk -include $(MAKEFILE_IMPORT_PATH)placeholder.mk -include $(MAKEFILE_IMPORT_PATH)conan.mk -#include $(MAKEFILE_IMPORT_PATH)bob.mk -include $(MAKEFILE_IMPORT_PATH)s3.mk -#include $(MAKEFILE_IMPORT_PATH)readme-standard.mk -include $(MAKEFILE_IMPORT_PATH)readme-webcomponents.mk -#include $(MAKEFILE_IMPORT_PATH)readme-go-utilities.mk -#include $(MAKEFILE_IMPORT_PATH)readme-go-lib.mk -#include $(MAKEFILE_IMPORT_PATH)readme-platform-part.mk -include $(MAKEFILE_IMPORT_PATH)licenses.mk -include $(MAKEFILE_IMPORT_PATH)license-agpl3.mk -#include $(MAKEFILE_IMPORT_PATH)license-unlicensed.mk -#include $(MAKEFILE_IMPORT_PATH)license-all-rights-reserved.mk -include $(MAKEFILE_IMPORT_PATH)jsdoc-json.mk -include $(MAKEFILE_IMPORT_PATH)changelog.mk -#include $(MAKEFILE_IMPORT_PATH)docman.mk -#include $(MAKEFILE_IMPORT_PATH)reqman.mk -include $(MAKEFILE_IMPORT_PATH)git.mk -include $(MAKEFILE_IMPORT_PATH)gitignore.mk -include $(MAKEFILE_IMPORT_PATH)color.mk -include $(MAKEFILE_IMPORT_PATH)version.mk -#include $(MAKEFILE_IMPORT_PATH)docker.mk -include $(MAKEFILE_IMPORT_PATH)node.mk -include $(MAKEFILE_IMPORT_PATH)terminal.mk -include $(MAKEFILE_IMPORT_PATH)target-go-fetch-licenses.mk -include $(MAKEFILE_IMPORT_PATH)target-add-licenses.mk -#include $(MAKEFILE_IMPORT_PATH)target-deploy-tool.mk -include $(MAKEFILE_IMPORT_PATH)target-jsdoc-build.mk -#include $(MAKEFILE_IMPORT_PATH)target-docman.mk -#include $(MAKEFILE_IMPORT_PATH)target-caddy.mk -include $(MAKEFILE_IMPORT_PATH)target-conan.mk -#include $(MAKEFILE_IMPORT_PATH)target-bob.mk -#include $(MAKEFILE_IMPORT_PATH)target-phpunit.mk -#include $(MAKEFILE_IMPORT_PATH)target-jekyll.mk -include $(MAKEFILE_IMPORT_PATH)target-update-makefiles.mk -include $(MAKEFILE_IMPORT_PATH)target-help.mk -#include $(MAKEFILE_IMPORT_PATH)target-go-build.mk -include $(MAKEFILE_IMPORT_PATH)target-node-build.mk -include $(MAKEFILE_IMPORT_PATH)target-node-test.mk -include $(MAKEFILE_IMPORT_PATH)target-node-playground.mk -include $(MAKEFILE_IMPORT_PATH)target-npm-publish.mk -include $(MAKEFILE_IMPORT_PATH)target-npm.mk -include $(MAKEFILE_IMPORT_PATH)target-git.mk -#include $(MAKEFILE_IMPORT_PATH)target-init-standard.mk -#include $(MAKEFILE_IMPORT_PATH)target-init-webcomponent.mk -#include $(MAKEFILE_IMPORT_PATH)target-init-go-utilities.mk -#include $(MAKEFILE_IMPORT_PATH)target-init-go-lib.mk -#include $(MAKEFILE_IMPORT_PATH)target-init-platform-part.mk -include $(MAKEFILE_IMPORT_PATH)target-version.mk -include $(MAKEFILE_IMPORT_PATH)target-variable.mk -include $(MAKEFILE_IMPORT_PATH)terminal-check.mk - - -############################################################################################# - -# include target-project.mk only if it exists --include $(MAKEFILE_IMPORT_PATH)target-project.mk diff --git a/README.md b/README.md index 16bf8ba515c77358f57b9b3384d6694a7e231580..331c9772e1e04b397e29395982a9c98334451619 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ We do try to work around some browser bugs, but on the whole we don't use polyfi However, many functions can be mapped via [polyfill.io](https://polyfill.io/) and thus the compatibility can be increased. ```html -<script id="polyfill" src="https://polyfill.io/v3/polyfill.min.js?features=Array.from,Array.isArray,Array.prototype.entries,Array.prototype.fill,Array.prototype.filter,Array.prototype.forEach,Array.prototype.includes,Array.prototype.indexOf,Array.prototype.keys,Array.prototype.lastIndexOf,Array.prototype.map,Array.prototype.reduce,Array.prototype.sort,ArrayBuffer,atob,Blob,CustomEvent,DataView,document,Document,DocumentFragment,Element,Event,fetch,globalThis,HTMLDocument,HTMLTemplateElement,Intl,JSON,Map,Math.log2,Number.isInteger,Object.assign,Object.defineProperty,Object.entries,Object.freeze,Object.getOwnPropertyDescriptor,Object.getOwnPropertyNames,Object.getPrototypeOf,Object.keys,Promise,Reflect,Reflect.defineProperty,Reflect.get,Reflect.getOwnPropertyDescriptor,Reflect.setPrototypeOf,Set,String.prototype.endsWith,String.prototype.includes,String.prototype.matchAll,String.prototype.padStart,String.prototype.startsWith,String.prototype.trim,Symbol,Symbol.for,Symbol.hasInstance,Symbol.iterator,Uint16Array,Uint8Array,URL,WeakMap,WeakSet" +<script id="polyfill" src="https://polyfill.io/v3/polyfill.min.js?features=Array.from,Array.isArray,Array.prototype.entries,Array.prototype.fill,Array.prototype.filter,Array.prototype.forEach,Array.prototype.includes,Array.prototype.indexOf,Array.prototype.keys,Array.prototype.lastIndexOf,Array.prototype.map,Array.prototype.reduce,Array.prototype.sort,ArrayBuffer,atob,Blob,CustomEvent,DataView,document,Document,DocumentFragment,Element,Event,fetch,globalThis,HTMLDocument,HTMLTemplateElement,Intl,JSON,Map,Math.log2,MutationObserver,Number.isInteger,Object.assign,Object.defineProperty,Object.entries,Object.freeze,Object.getOwnPropertyDescriptor,Object.getOwnPropertyNames,Object.getPrototypeOf,Object.keys,Promise,Reflect,Reflect.defineProperty,Reflect.get,Reflect.getOwnPropertyDescriptor,Reflect.setPrototypeOf,Set,String.prototype.endsWith,String.prototype.includes,String.prototype.matchAll,String.prototype.padStart,String.prototype.startsWith,String.prototype.trim,Symbol,Symbol.for,Symbol.hasInstance,Symbol.iterator,Uint16Array,Uint8Array,URL,WeakMap,WeakSet" crossorigin="anonymous" referrerpolicy="no-referrer"></script> ``` @@ -90,7 +90,7 @@ issue. Issues not conforming to the guidelines may be closed immediately. ## License -Copyright © 2022 schukai GmbH +Copyright © 2023 schukai GmbH [AGPL](https://www.gnu.org/licenses/agpl-3.0.de.html) diff --git a/Taskfile.yml b/Taskfile.yml new file mode 100644 index 0000000000000000000000000000000000000000..1d80647aa7a788ebae02b1e12381ed35479bcdec --- /dev/null +++ b/Taskfile.yml @@ -0,0 +1,44 @@ + +# THIS FILE IS AUTOGENERATED BY THE DEVENVSHELL +# DO NOT EDIT THIS FILE MANUALLY +# INSTEAD EDIT THE DEVENVSHELL CONFIGURATION FILE devenv.nix +# AND OPEN A SHELL WITH THE COMMAND devenv shell +# +# Information about the task runner can be found here: +# https://taskfile.dev + +version: '3' + +tasks: + default: + cmds: + - task --list + silent: true + + commit: + desc: Commit changes to the repository. + aliases: + - c + cmds: + - do-commit + + build-doc: + desc: Build the documentation to dist/doc + aliases: + - bd + cmds: + - build-doc + + run-tests: + desc: Run the tests + aliases: + - rt + cmds: + - run-tests + + run-web-tests: + desc: Run the tests + aliases: + - rt + cmds: + - run-web-tests diff --git a/application/CHANGELOG b/application/CHANGELOG deleted file mode 100644 index 00f5e76aafc14276a7fe42ef1d36fd8df41a7395..0000000000000000000000000000000000000000 --- a/application/CHANGELOG +++ /dev/null @@ -1,438 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -## [2.0.0] - 2022-08-08 - -- New structure in the repo -- Remove namespace functionality -- Switching the tests to esbuild -- Actualization of the documentation template -- New URL of the documentation -- Bug fix typeOf (constructor name was recognized wrong) -- Removal of the built version of the library -- Switching from js to mjs - -## [1.31.0] - 2022-02-07 - -## Added - -- [new promise domReady and windowReady](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/116) - -## [1.30.0] - 2022-02-05 - -## Added - -- [new class DeadMansSwitch](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/115) - -## [1.29.3] - 2022-01-23 - -## Fixed - -- [CSSStyleSheet polyfill throws an error](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/113) - -## [1.29.2] - 2022-01-22 - -## Fixed - -- [CSSStyleSheet polyfill throws an error](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/113) - -## [1.29.1] - 2022-01-07 - -## Fixed - -- [TypeError: element.addNode is not a function](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/112) - -## [1.29.0] - 2021-12-29 - -## Added - -- [new class DeadMansSwitch](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/111) -- [new function fireCustomEvent](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/110) -- [extends CustomerElement.getSlottedElements() with parameter name](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/109) - - -## [1.28.1] - 2021-12-12 - -## Added - -- [new function fireCustomEvent](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/108) - -## [1.28.0] - 2021-12-11 - -## Added - -- [new data-monster-select-this attribute](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/105) -- [Node.toString()](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/107) - -## Changed - -- [add rootReference to buildTree ](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/106) - -## [1.27.0] - 2021-12-06 - -## Added - -- [extends Updater for manual update bindings](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/102) -- [new function findClosestByClass](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/104) - -## Changed - -- [refactoring updater with internalSymbol](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/103) - -## [1.26.1] - 2021-12-02 - -## Fixed - -- [themed templates are not found from the shadowroot](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/101) - -## [1.26.0] - 2021-12-02 - -## Added - -- [new class Worker](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/95) -- [new class NodeRecursiveIterator](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/97) -- [new class Node](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/98) -- [new class NodeList](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/99) -- [new function buildTree](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/100) - -## Fixed - -- [only one attribute is replaced with indexed path](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/96) - - -## [1.25.0] - 2021-11-13 - -## Added - -- [new class FocusManager](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/93) -- [new class ResourceManager](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/92) -- [new class Resource, Link, Stylesheet, Data and Script](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/91) -- [new class UUID](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/89) - -## Changed - -- [optimization of random](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/90) - - -## [1.24.0] - 2021-11-13 - -## Added - -- [new class WriteError](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/79) -- [new transformer commands nth, first, last and nth-last](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/78) -- [add Proxyobserver.setObject](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/80) -- [transform: new debug, to-base64, from-base64, path-exists and optimzed default command](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/84) -- [new function trimSpace](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/86) - -## Changed - -- [changeover to internalSymbol and uniform symbols and keys](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/81) -- [optimization of the datasources and the restapi](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/82) -- [optimization attribute monitoring](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/85) -- [Formatter: marker in marker](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/88) - -## [1.23.0] - 2021-10-28 - -## Added - -- [add the processing of slotted elements](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/76) - -## Changed - -- [datasource should work with proxy data](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/77) - -## [1.22.0] - 2021-10-25 - -## Added - -- [new DataSource classes](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/75) - -## [1.22.0] - 2021-10-23 - -## Fixed - -- [package.json](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/74) - -## [1.21.0] - 2021-10-22 - -## Added - -- [new class processing](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/73) - -## [1.20.2] - 2021-10-19 - -## Fixed - -- [the method getClone is not called for objects with this method.](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/72) - -## [1.20.1] - 2021-10-19 - -## Fixed - -- [the integration of class instances into empty arrays throws an exception](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/71) - -## [1.20.0] - 2021-10-18 - -## Fixed - -- [closest cannot be used, because closest is not correct for slotted elements](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/70) - -## [1.19.0] - 2021-10-16 - -## Added - -- [new method hasNode to check if a node is included](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/69) - -## Fixed - -- [value===NaN is always false](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/68) - - -## [1.18.0] - 2021-10-11 - -## Added - -- [option can be specified as DataURI](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/64) -- [MediaType class](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/65) -- [DataURI class](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/66) -- [toBinary & fromBinary functions](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/67) - -## [1.17.2] - 2021-10-09 - -## Fixed - -- [the diff function evaluates arrays incorrectly](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/62) - -## [1.17.1] - 2021-10-09 - -## Fixed - -- [diff throws an error at zero values](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/61) - -## [1.17.0] - 2021-10-07 - -## Changed - -- [In the templates of the buildmap function there should also be the possibility to specify parent values.](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/60) - -## [1.16.1] - 2021-09-29 - -## Fixed - -- [Uncaught TypeError: (0 , logging_namespace_namespaceObject.assignToNamespace) is not a function](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/59) - -## [1.16.0] - 2021-09-27 - -## Changed - -- documentation -- build scripts - -## [1.15.3] - 2021-09-20 - -### Fixed - -- [connectedCallback can be called more often and setTimeout prevents checking](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/57) - -## [1.15.1] - 2021-09-13 - -### Fixed - -- [TypeError: t.getElementById is not a function](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/56) - -## [1.15.0] - 2021-09-13 - -### Added - -- [when changing the option attribute, the options should also change](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/50) -- [new PROPERTY_KEY_INTERNALDATA internals](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/52) - -## Changed - -- [improvement of the prox handling in the proxobserver](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/55) -- [move observedAttributes to customelements](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/54) -- [optimization of the extends handling in distinction to Object.assign](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/53) -- [change from Monster.assignToNamespace to assignToNamespace an import](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/51) - -## [1.14.1] - 2021-09-12 - -### Fixed - -- [control and optimize customelement](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/49) - -## [1.14.0] - 2021-09-12 - -### Added - -- [control and optimize customelement](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/49) - -## [1.13.0] - 2021-09-06 - -### Added - -- [classes for localization and management of translations](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/48) - -## [1.12.0] - 2021-09-05 - -### Added - -- [a class to format texts](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/47) - - -## [1.11.1] - 2021-09-05 - -## Changed - -- [improvement of the entry points of the libraries](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/46) - - -## [1.11.0] - 2021-09-04 - -## Changed - -- [conversion from babelify to webpack](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/44) - -## [1.10.3] - 2021-09-01 - -## Changed - -- [older browsers have a problem with the proxy object](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/43) - - -## [1.10.2] - 2021-08-31 - -## Changed - -- [optimizations for old browsers](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/42) - -## [1.10.0] - 2021-08-25 - -### Added - -- [add extend function](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/35) -- [new method fireEvent](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/38) - -## Changed - -- [shadowRoot should be optional](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/36) - -### Fixed - -- [improve code coverage](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/40) -- [an empty object does not lead to an output](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/29) - -### Removed - -- [the updater class replace the handle class](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/34) - -## [1.9.0] - 2021-08-17 - -### Added - -- [create the possibility to bind form fields to the datset](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/30) -- [new attribute method to change tokens](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/31) -- [new function isSymbol and validateSymbol](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/32) - -## Changed - -- [Pipe should call callbacks in context](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/33) - -## Fixed - -- [an empty object does not lead to an output](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/29) - -## [1.8.0] - 2021-08-07 - -### Added - -- [new Monster.DOM.Updater](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/25) -- [add tojson to transformer](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/27) - -### Changed - -- [the validate functions now return the validated value](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/24) -- [introduce DOM constants](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/26) - -## [1.7.0] - 2021-08-07 - -### Added - -- [new Monster.DOM.CustomElement](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/20) -- [new Monster.DOM.Theme](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/21) -- [new Monster.Types.getType](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/22) -- [new Monster.Data.buildMap](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/23) - -## [1.6.0] - 2021-07-29 - -### Added - -- [new function getGobal()](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/15) -- [new Monster.DOM.Template](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/16) -- [new Monster.Type.RandomID](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/19) -- [new method Monster.Util.Pathfinder::deleteVia()](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/18) - -### Fixed - -- missing imports in monster.js - - -## [1.5.0] - 2021-07-06 - -### Added - -- [new Monster.Data.Transformer](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/9) -- [new Monster.Data.Pathfinder](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/9) -- [new functions Monster.Types.isInstance() and Monster.Types.validateInstance()](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/12) - -### Changed - -- [The class Monster.Types.Object is now called Monster.Types.Base](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/11) - -## [1.4.0] - 2021-07-04 - -### Added - -- [new Monster.Types.Queue](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/6) -- [new Monster.Types.UniqueQueue](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/6) -- [new Monster.Types.Stack](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/7) -- [new Monster.Types.validateInteger](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/8) -- [new Monster.Types.isInteger](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/8) -- [new Monster.Util.Pathfinder](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/9) - -### Changed - -- [ensure that an object is not informed of the same change more than once](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/5) - -## [1.3.0] - 2021-06-30 - -### Added - -- new class Monster.Util.Comparator -- new class Monster.Constraints.AbstractConstraint -- new class Monster.Constraints.AndOperator -- new class Monster.Constraints.OrOperator -- new class Monster.Constraints.Invalid -- new class Monster.Constraints.Valid -- new class Monster.Constraints.IsObject -- new class Monster.Constraints.IsArray - -### Changed - -- the return value of TokenList.replace() is now this -- change observer tags from `Set` to `TokenList` - -## [1.2.0] - 2021-06-30 - -### Added - -- Monster.Types.TokenList - -## [1.1.0] - 2021-06-28 - -### Added - -- Monster.Types -- Monster.Util -- Monster.Math - diff --git a/application/pnpm-lock.yaml b/application/pnpm-lock.yaml deleted file mode 100644 index 7a06cc7962bcd24662eb96ec5b88053b77233484..0000000000000000000000000000000000000000 --- a/application/pnpm-lock.yaml +++ /dev/null @@ -1 +0,0 @@ -lockfileVersion: '6.0' diff --git a/application/source/monster.mjs b/application/source/monster.mjs deleted file mode 100644 index 4debe5e1a7c4816ebfeaa6e63e1668ea43866b44..0000000000000000000000000000000000000000 --- a/application/source/monster.mjs +++ /dev/null @@ -1,244 +0,0 @@ -/** - * Copyright schukai GmbH and contributors 2023. All Rights Reserved. - * Node module: @schukai/monster - * This file is licensed under the AGPLv3 License. - * License text available at https://www.gnu.org/licenses/agpl-3.0.en.html - * SPDX-License-Identifier: AGPL-3.0-only or COMMERCIAL - */ - -/** - * Main namespace for Monster. - * - * @namespace Monster - * @author schukai GmbH - */ - -// development/script/grep-exports.cjs -export { IsObject } from "./constraints/isobject.mjs"; -export { Invalid } from "./constraints/invalid.mjs"; -export { AndOperator } from "./constraints/andoperator.mjs"; -export { OrOperator } from "./constraints/oroperator.mjs"; -export { AbstractConstraint } from "./constraints/abstract.mjs"; -export { IsArray } from "./constraints/isarray.mjs"; -export { AbstractOperator } from "./constraints/abstractoperator.mjs"; -export { Valid } from "./constraints/valid.mjs"; -export { - Logger, - ALL, - TRACE, - DEBUG, - INFO, - WARN, - ERROR, - FATAL, - OFF, -} from "./logging/logger.mjs"; -export { LogEntry } from "./logging/logentry.mjs"; -export { ConsoleHandler } from "./logging/handler/console.mjs"; -export { Handler } from "./logging/handler.mjs"; -export { Formatter } from "./text/formatter.mjs"; -export { Stylesheet } from "./dom/resource/link/stylesheet.mjs"; -export { Data } from "./dom/resource/data.mjs"; -export { Link } from "./dom/resource/link.mjs"; -export { Script } from "./dom/resource/script.mjs"; -export { Updater, addObjectWithUpdaterToElement } from "./dom/updater.mjs"; -export { CustomControl } from "./dom/customcontrol.mjs"; -export { getLocaleOfDocument } from "./dom/locale.mjs"; -export { Theme, getDocumentTheme } from "./dom/theme.mjs"; -export { - Resource, - KEY_DOCUMENT, - KEY_QUERY, - referenceSymbol, -} from "./dom/resource.mjs"; -export { ResourceManager } from "./dom/resourcemanager.mjs"; -export { - getDocument, - getWindow, - getDocumentFragmentFromString, -} from "./dom/util.mjs"; -export { - DEFAULT_THEME, - ATTRIBUTE_PREFIX, - ATTRIBUTE_OPTIONS, - ATTRIBUTE_OPTIONS_SELECTOR, - ATTRIBUTE_THEME_PREFIX, - ATTRIBUTE_THEME_NAME, - ATTRIBUTE_UPDATER_ATTRIBUTES, - ATTRIBUTE_UPDATER_SELECT_THIS, - ATTRIBUTE_UPDATER_REPLACE, - ATTRIBUTE_UPDATER_INSERT, - ATTRIBUTE_UPDATER_INSERT_REFERENCE, - ATTRIBUTE_UPDATER_REMOVE, - ATTRIBUTE_UPDATER_BIND, - ATTRIBUTE_TEMPLATE_PREFIX, - ATTRIBUTE_ROLE, - ATTRIBUTE_DISABLED, - ATTRIBUTE_VALUE, - ATTRIBUTE_OBJECTLINK, - ATTRIBUTE_ERRORMESSAGE, - TAG_SCRIPT, - TAG_STYLE, - TAG_LINK, - ATTRIBUTE_ID, - ATTRIBUTE_CLASS, - ATTRIBUTE_TITLE, - ATTRIBUTE_SRC, - ATTRIBUTE_HREF, - ATTRIBUTE_TYPE, - ATTRIBUTE_NONCE, - ATTRIBUTE_TRANSLATE, - ATTRIBUTE_TABINDEX, - ATTRIBUTE_SPELLCHECK, - ATTRIBUTE_SLOT, - ATTRIBUTE_PART, - ATTRIBUTE_LANG, - ATTRIBUTE_ITEMTYPE, - ATTRIBUTE_ITEMSCOPE, - ATTRIBUTE_ITEMREF, - ATTRIBUTE_ITEMID, - ATTRIBUTE_ITEMPROP, - ATTRIBUTE_IS, - ATTRIBUTE_INPUTMODE, - ATTRIBUTE_ACCESSKEY, - ATTRIBUTE_AUTOCAPITALIZE, - ATTRIBUTE_AUTOFOCUS, - ATTRIBUTE_CONTENTEDITABLE, - ATTRIBUTE_DIR, - ATTRIBUTE_DRAGGABLE, - ATTRIBUTE_ENTERKEYHINT, - ATTRIBUTE_EXPORTPARTS, - ATTRIBUTE_HIDDEN, - objectUpdaterLinkSymbol, - customElementUpdaterLinkSymbol, -} from "./dom/constants.mjs"; -export { - CustomElement, - initMethodSymbol, - assembleMethodSymbol, - attributeObserverSymbol, - registerCustomElement, - getSlottedElements, -} from "./dom/customelement.mjs"; -export { - findClosestObjectLink, - addToObjectLink, - removeObjectLink, - hasObjectLink, - getLinkedObjects, - toggleAttributeToken, - addAttributeToken, - removeAttributeToken, - containsAttributeToken, - replaceAttributeToken, - clearAttributeTokens, - findClosestByAttribute, - findClosestByClass, -} from "./dom/attributes.mjs"; -export { - fireEvent, - fireCustomEvent, - findTargetElementFromEvent, -} from "./dom/events.mjs"; -export { Factory } from "./dom/worker/factory.mjs"; -export { Template } from "./dom/template.mjs"; -export { domReady, windowReady } from "./dom/ready.mjs"; -export { FocusManager } from "./dom/focusmanager.mjs"; -export { ATTRIBUTEPREFIX, Assembler } from "./dom/assembler.mjs"; -export { Translations } from "./i18n/translations.mjs"; -export { Locale, parseLocale } from "./i18n/locale.mjs"; -export { Formatter as I18nFormatter } from "./i18n/formatter.mjs"; -export { Fetch } from "./i18n/providers/fetch.mjs"; -export { Provider } from "./i18n/provider.mjs"; -export { Message } from "./net/webconnect/message.mjs"; -export { WebConnect as NetWebConnect } from "./net/webconnect.mjs"; -export { - internalSymbol, - internalStateSymbol, - instanceSymbol, -} from "./constants.mjs"; -export { MediaType, parseMediaType } from "./types/mediatype.mjs"; -export { typeOf } from "./types/typeof.mjs"; -export { ObserverList } from "./types/observerlist.mjs"; -export { RandomID } from "./types/randomid.mjs"; -export { ObservableQueue } from "./types/observablequeue.mjs"; -export { UUID } from "./types/uuid.mjs"; -export { Observer } from "./types/observer.mjs"; -export { TokenList } from "./types/tokenlist.mjs"; -export { Queue } from "./types/queue.mjs"; -export { Stack } from "./types/stack.mjs"; -export { toBinary, fromBinary } from "./types/binary.mjs"; -export { BaseWithOptions } from "./types/basewithoptions.mjs"; -export { escapeString } from "./types/regex.mjs"; -export { ProxyObserver } from "./types/proxyobserver.mjs"; -export { NodeList } from "./types/nodelist.mjs"; -export { Version, getMonsterVersion } from "./types/version.mjs"; -export { Node } from "./types/node.mjs"; -export { NodeRecursiveIterator } from "./types/noderecursiveiterator.mjs"; -export { - getGlobal, - getGlobalObject, - getGlobalFunction, -} from "./types/global.mjs"; -export { DataUrl, parseDataURL } from "./types/dataurl.mjs"; -export { - validateIterable, - validatePrimitive, - validateBoolean, - validateString, - validateObject, - validateInstance, - validateArray, - validateSymbol, - validateFunction, - validateInteger, -} from "./types/validate.mjs"; -export { UniqueQueue } from "./types/uniquequeue.mjs"; -export { Base } from "./types/base.mjs"; -export { - isIterable, - isPrimitive, - isSymbol, - isBoolean, - isString, - isObject, - isInstance, - isArray, - isFunction, - isInteger, -} from "./types/is.mjs"; -export { ID } from "./types/id.mjs"; -export { trimSpaces } from "./util/trimspaces.mjs"; -export { DeadMansSwitch } from "./util/deadmansswitch.mjs"; -export { deepFreeze } from "./util/freeze.mjs"; -export { Comparator } from "./util/comparator.mjs"; -export { clone } from "./util/clone.mjs"; -export { Processing } from "./util/processing.mjs"; -export { extend } from "./data/extend.mjs"; -export { Pipe } from "./data/pipe.mjs"; -export { buildMap, PARENT, assembleParts } from "./data/buildmap.mjs"; -export { Datasource } from "./data/datasource.mjs"; -export { buildTree } from "./data/buildtree.mjs"; -export { Transformer } from "./data/transformer.mjs"; -export { Pathfinder, DELIMITER, WILDCARD } from "./data/pathfinder.mjs"; -export { diff } from "./data/diff.mjs"; -export { Server } from "./data/datasource/server.mjs"; -export { SessionStorage } from "./data/datasource/storage/sessionstorage.mjs"; -export { LocalStorage } from "./data/datasource/storage/localstorage.mjs"; -export { RestAPI } from "./data/datasource/server/restapi.mjs"; -export { WebConnect } from "./data/datasource/server/webconnect.mjs"; -export { WriteError } from "./data/datasource/server/restapi/writeerror.mjs"; -export { Storage, storageObjectSymbol } from "./data/datasource/storage.mjs"; -export { random } from "./math/random.mjs"; - -export { Monster }; - -/** - * This class has no other purpose than to exist. - * - * @license AGPLv3 - * @since 2.0.0 - * @copyright schukai GmbH - * @memberOf Monster - */ -class Monster {} diff --git a/biome.json b/biome.json new file mode 100644 index 0000000000000000000000000000000000000000..beec31eee9558fd01fa6cf68621c4366589cbc2b --- /dev/null +++ b/biome.json @@ -0,0 +1,12 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.2.2/schema.json", + "organizeImports": { + "enabled": false + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true + } + } +} \ No newline at end of file diff --git a/development/config/conan.cfg b/development/config/conan.cfg deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/development/makefiles/blackbox.mk b/development/makefiles/blackbox.mk deleted file mode 100644 index c1f3e5f9b6556778ca1ffa83715ac5d599652cf6..0000000000000000000000000000000000000000 --- a/development/makefiles/blackbox.mk +++ /dev/null @@ -1,111 +0,0 @@ -############################################################################################# -############################################################################################# -## -## DEFINE BLACKBOX -## -############################################################################################# -############################################################################################# - -EXECUTABLES = $(EXECUTABLES:-) gpgconf git - -BLACKBOX_ROOT_DIR = $(PROJECT_ROOT) -BLACKBOX_BUILD_DIR = $(BLACKBOX_ROOT_DIR)build/blackbox -BLACKBOX_CONFIG_PATH = $(BLACKBOX_ROOT_DIR).blackbox -BLACKBOX_GPG_PATH = $(shell gpgconf --list-dirs homedir) - -# The default image of blackbox -# only local image is supported -BLACKBOX_IMAGE_NAME= blackbox_local_temp_image -BLACKBOX_IMAGE_HASH = $(shell git log --format="%h" -n 1) -BLACKBOX_IMAGE = $(BLACKBOX_IMAGE_NAME):$(BLACKBOX_IMAGE_HASH) - -define BLACKBOX_RUN_SCRIPT -#!/bin/bash - -function cleanup() -{ - for FILE in $$(blackbox_list_files); do - blackbox_edit_end $${FILE} || exit 1 - done - exit 0 -} - -if [ "$$#" -ne 1 ]; then - ## args are: open, close, run - echo "Usage: $$0 open|close|run" - exit 1 -fi - -## trap if arg is run -if [ "$$1" == "run" ]; then - # Intercepts the signal and then executes the command to encrypt. - trap cleanup INT TERM SIGTERM SIGUSR1 -fi - -if [ "$$1" == "open" ] || [ "$$1" == "run" ]; then - echo "Opening files..." - for FILE in $$(blackbox_list_files); do - blackbox_edit_start $${FILE} || exit 1 - done -fi - -if [ "$$1" == "close" ]; then - echo "Closing files..." - for FILE in $$(blackbox_list_files); do - blackbox_edit_end $${FILE} || exit 1 - done -elif [ "$$1" == "run" ]; then - echo "Running command..." - while true; do - sleep 1 - done - -elif [ "$$1" == "open" ]; then - exit 0 - -else - echo "Unknown command: $$1" - exit 1 -fi - - -endef - -define BLACKBOX_DOCKERFILE -FROM docker-registry.schukai.com:443/debian-bullseye-amd64-slim:snapshot AS deb-builder - -RUN apt-get update && apt-get install git make rubygems build-essential -RUN cd /opt/ && \ - git clone https://github.com/StackExchange/blackbox.git - -RUN gem install fpm - -RUN cd /opt/blackbox && \ - make packages-deb - -FROM docker-registry.schukai.com:443/debian-bullseye-amd64-slim:snapshot - -RUN apt-get update && apt-get install git gnupg -RUN sed -i /NAME=/s/=.*/'="Blackbox"'/ /etc/container-release ; - -COPY --from=deb-builder /root/debbuild-stack_blackbox/ /tmp/ -RUN apt-get install /tmp/*.deb -RUN mkdir /repos /root/.gnupg - -VOLUME [ "/repos" ] -WORKDIR /repos - -COPY ./filesystem/bin /bin/ - -RUN chmod ugo+x /bin/run-blackbox.sh - -ARG UNAME=dummy -ARG UID=1000 -ARG GID=1000 - -RUN groupadd -g $$GID -o $$UNAME -RUN useradd -m -u $$UID -g $$GID -o -s /bin/bash $$UNAME - - -ENTRYPOINT [ "/bin/run-blackbox.sh" ] -endef \ No newline at end of file diff --git a/development/makefiles/bob.mk b/development/makefiles/bob.mk deleted file mode 100644 index c779df31757b1998fc2d40e0c64a1e30d864608c..0000000000000000000000000000000000000000 --- a/development/makefiles/bob.mk +++ /dev/null @@ -1,67 +0,0 @@ -############################################################################################# -############################################################################################# -## -## DEFINE BOB -## -############################################################################################# -############################################################################################# - - -BOB_BIN ?= $(VENDOR_PATH)bob -#BOB_SNIPPED_CONFIG ?= $(VENDOR_PATH)bob/snippet.yaml -BOB_SYNC_CONFIG ?= $(VENDOR_PATH)bob/sync.yaml - -BOB_SOURCE_PATH ?= $(SOURCE_PATH) - -BOB_DIST_PATH ?= $(DIST_PATH)bob/dist/ -BOB_HTML_TEMPLATES_PATH ?= $(BUILD_PATH)bob/build/ - -BOB_DATA_FILE ?= data.yaml - -define SYNCEXAMPLECONF -sync: - - - source: - path: '../original/test1.html' - selector: '#mainscript' - destination: - path: '../original/' - exclude: - - ../original/test1.html - - - source: - path: '../original/test1.html' - selector: '.deco' - destination: - path: '../original/' - exclude: - - ../original/test1.html - -endef - -export SYNCEXAMPLECONF - -define SNIPPETEXAMPLECONF -snippet: - - - source: ../../template.html - selector: 'h1' - destination: ../../snippets/meta/container.html - attribute: - - selector: 'li' - name: 'data-state' - value: 'monster' - replacement: - - - selector: 'li>span' - content: 'hello' -endef - -export SNIPPETEXAMPLECONF - -$(BOB_SNIPPED_CONFIG): - $(QUIET) $(ECHO) "$$BOB_SNIPPED_CONFIG" >> $@ - -$(BOB_SYNC_CONFIG): - $(QUIET) $(ECHO) "$$BOB_SYNC_CONFIG" >> $@ - diff --git a/development/makefiles/changelog.mk b/development/makefiles/changelog.mk deleted file mode 100644 index c3ae83114f80b47c10e7d99bb4a8c89eefeaa334..0000000000000000000000000000000000000000 --- a/development/makefiles/changelog.mk +++ /dev/null @@ -1,140 +0,0 @@ -############################################################################################# -############################################################################################# -## -## CHANGELOG -## -############################################################################################# -############################################################################################# - - -GIT_CHGLOG_BIN := $(shell command -v git-chglog 2> /dev/null) -GIT_CHGLOG_CONFIG_DIR := $(PROJECT_ROOT).chglog -REPOSURL := $(subst .git,,$(subst $(shell git config --get user.name)@,,$(shell git config --get remote.origin.url))) - -ifeq ($(GO),) - $(error $(ERRORMARKER) GO is not defined) -endif - -ifeq ($(GIT_CHGLOG_BIN),) - $(shell $(GO) install github.com/git-chglog/git-chglog/cmd/git-chglog@latest) - GIT_CHGLOG_BIN := $(shell command -v git-chglog 2> /dev/null) -endif - - -ifneq ($(shell test -d $(GIT_CHGLOG_CONFIG_DIR) && echo -n yes),yes) - $(shell mkdir -p $(GIT_CHGLOG_CONFIG_DIR)) -endif - -remove-config-files: - $(shell rm -Rf $(GIT_CHGLOG_CONFIG_DIR)/ && mkdir -p $(GIT_CHGLOG_CONFIG_DIR)) - -.PHONY: update-chglog-files -## update standard git-chglog configuration files -update-chglog-files: remove-config-files $(GIT_CHGLOG_CONFIG_DIR)/config.yml $(GIT_CHGLOG_CONFIG_DIR)/CHANGELOG.tpl.md - $(ECHOMARKER) "update standard git-chglog configuration files" - -define GIT_CHGLOG_CONFIG_FILE -style: gitlab -template: CHANGELOG.tpl.md -info: - title: CHANGELOG - repository_url: $(REPOSURL) -options: - commits: - filters: - Type: - - feat - - fix - - doc - - refactor - - perf - - test - - chore - ## deprecated types and typos - - docs - - documentation - - feat - - added - - add - - bugfix - - revert - - update - - updates - - change - - changed - commit_groups: - title_maps: - feat: Add Features - fix: Bug Fixes - doc: Documentation - refactor: Code Refactoring - perf: Performance Improvements - test: Tests - ## Chore is used for all other changes that don't fit in the other categories - chore: Changes - ## deprecated types and typos - docs: Documentation - documentation: Documentation - added: Add Features - add: Add Features - bugfix: Bug Fixes - revert: Reverts - update: Changes - updates: Changes - change: Changes - changed: Changes - header: - pattern: "^(\\w*)(?:\\(([\\w\\$$\\.\\-\\*\\s]*)\\))?\\:\\s(.*)$$" - pattern_maps: - - Type - - Scope - - Subject - notes: - keywords: - - BREAKING CHANGE -endef - -export GIT_CHGLOG_CONFIG_FILE - -$(GIT_CHGLOG_CONFIG_DIR)/config.yml: - $(QUIET) $(ECHO) "$$GIT_CHGLOG_CONFIG_FILE" >> $@ - -define GIT_CHGLOG_CONFIG_TEMPLATE -{{ range .Versions }} -<a name="{{ .Tag.Name }}"></a> -## {{ if .Tag.Previous }}[{{ .Tag.Name }}]{{ else }}{{ .Tag.Name }}{{ end }} - {{ datetime "2006-01-02" .Tag.Date }} -{{ range .CommitGroups -}} -### {{ .Title }} -{{ range .Commits -}} -- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }} -{{ end }} -{{ end -}} - -{{- if .NoteGroups -}} -{{ range .NoteGroups -}} -### {{ .Title }} -{{ range .Notes }} -{{ .Body }} -{{ end }} -{{ end -}} -{{ end -}} -{{ end -}} - -{{- if .Versions }} -{{ range .Versions -}} -{{ if .Tag.Previous -}} -[{{ .Tag.Name }}]: {{ $$.Info.RepositoryURL }}/compare/{{ .Tag.Previous.Name }}...{{ .Tag.Name }} -{{ end -}} -{{ end -}} -{{ end -}} -endef - -export GIT_CHGLOG_CONFIG_TEMPLATE - - -$(GIT_CHGLOG_CONFIG_DIR)/CHANGELOG.tpl.md: - $(QUIET) $(ECHO) "$$GIT_CHGLOG_CONFIG_TEMPLATE" >> $@ - -## location of CHANGELOG.md file -CHANGELOG_FILE ?= $(PROJECT_ROOT)CHANGELOG.md -EXECUTABLES = $(EXECUTABLES:-) $(GIT_CHGLOG_BIN) diff --git a/development/makefiles/color.mk b/development/makefiles/color.mk deleted file mode 100644 index 2c3fe3d1ba24854f1c05865705b6d9235fb02589..0000000000000000000000000000000000000000 --- a/development/makefiles/color.mk +++ /dev/null @@ -1,17 +0,0 @@ -############################################################################################# -############################################################################################# -## -## COLORS -## -############################################################################################# -############################################################################################# - -BLACK := $(shell tput -Txterm setaf 0) -RED := $(shell tput -Txterm setaf 1) -GREEN := $(shell tput -Txterm setaf 2) -YELLOW := $(shell tput -Txterm setaf 3) -LIGHTPURPLE := $(shell tput -Txterm setaf 4) -PURPLE := $(shell tput -Txterm setaf 5) -BLUE := $(shell tput -Txterm setaf 6) -WHITE := $(shell tput -Txterm setaf 7) -RESET := $(shell tput -Txterm sgr0) \ No newline at end of file diff --git a/development/makefiles/conan.mk b/development/makefiles/conan.mk deleted file mode 100644 index 7025948407cdc675d8f745fe39ab7a52d1ec78bf..0000000000000000000000000000000000000000 --- a/development/makefiles/conan.mk +++ /dev/null @@ -1,57 +0,0 @@ -############################################################################################# -############################################################################################# -## -## DEFINE CONAN -## -############################################################################################# -############################################################################################# - - -CONAN_BIN ?= $(VENDOR_PATH)conan -CONAN_CONFIG ?= $(VENDOR_PATH)conan.conf - -define CONANEXAMPLECONF -Server: - - # The hostname or IP address of the server (CONAN_SERVER_HOST) - # Domain, IP or hostname of the server - #Host: localhost:8080 - - # The port of the server (CONAN_SERVER_ADDRESS) - # Address: localhost - - # The port of the server (CONAN_SERVER_PORT) - # Port: 8080 - - # - Path: - # The path to the server (CONAN_SERVER_WEB_PATH) - Web: web - - Watch: - - Path: src - Command: /bin/bash -c "npx esbuild --bundle --outfile={{ .WebPath }}/scripts/bundle.js --sourcemap {{ .Path }}" - Exclude: - - ~$ - - ^\. - - Path: web - Exclude: - - ~$ - - ^\. - - Flags: - FollowSymlinks: true - -endef - -export CONANEXAMPLECONF - -$(CONAN_CONFIG): - $(QUIET) $(ECHO) "$$CONANEXAMPLECONF" >> $@ - - - -$(CONAN_BIN): - $(QUIET) $(MKDIR) -p $(VENDOR_PATH) - $(QUIET) $(WGET) -O $(CONAN_BIN) http://download.schukai.com/tools/conan/conan-$(shell uname -s | tr [:upper:] [:lower:])-$(shell echo `uname -m | sed s/aarch64/arm64/ | sed s/x86_64/amd64/`) - $(QUIET) $(CHMOD) u+x $(CONAN_BIN) diff --git a/development/makefiles/directories-go-lib.mk b/development/makefiles/directories-go-lib.mk deleted file mode 100644 index 257f8ab4051fe1852c021b00d509ba4a100d5361..0000000000000000000000000000000000000000 --- a/development/makefiles/directories-go-lib.mk +++ /dev/null @@ -1,33 +0,0 @@ -############################################################################################# -############################################################################################# -## -## DIRECTORIES -## -############################################################################################# -############################################################################################# - -APPLICATION_PATH ?= $(PROJECT_ROOT) -DEPLOYMENT_PATH ?= $(PROJECT_ROOT) -DEVELOPMENT_PATH ?= $(PROJECT_ROOT) -DOCUMENTATION_PATH ?= $(PROJECT_ROOT) -DOCUMENTATION_CONFIG_PATH ?= $(DOCUMENTATION_PATH)config/ - -RESOURCE_PATH ?= $(APPLICATION_PATH) -SOURCE_PATH ?= $(APPLICATION_PATH) - -## SCRIPTS_PATH IS DEPRECATED -SCRIPTS_PATH ?= $(DEVELOPMENT_PATH)script/ - -DEVELOPMENT_SCRIPTS_PATH ?= $(DEVELOPMENT_PATH)script/ -BUILD_PATH ?= $(DEPLOYMENT_PATH)build/ -VENDOR_PATH ?= $(DEPLOYMENT_PATH)vendor/ - -DEPLOYMENT_SCRIPTS_PATH ?= $(DEPLOYMENT_PATH)script/ -LICENSE_PATH ?= $(PROJECT_ROOT) - -PROJECT_DIRECTORIES := $(PROJECT_DIRECTORIES) \ - $(APPLICATION_PATH) \ - $(VENDOR_PATH) \ - $(DEVELOPMENT_SCRIPTS_PATH) \ - $(BUILD_PATH) - diff --git a/development/makefiles/directories-go-utilities.mk b/development/makefiles/directories-go-utilities.mk deleted file mode 100644 index 8fc26182636a50433b8832b20b36bd80c704140a..0000000000000000000000000000000000000000 --- a/development/makefiles/directories-go-utilities.mk +++ /dev/null @@ -1,42 +0,0 @@ -############################################################################################# -############################################################################################# -## -## DIRECTORIES -## -############################################################################################# -############################################################################################# - -APPLICATION_PATH ?= $(PROJECT_ROOT)application/ -DEPLOYMENT_PATH ?= $(PROJECT_ROOT)deployment/ -DEVELOPMENT_PATH ?= $(PROJECT_ROOT)development/ -DOCUMENTATION_PATH ?= $(PROJECT_ROOT)documentation/ -DOCUMENTATION_CONFIG_PATH ?= $(DOCUMENTATION_PATH)config/ - -RESOURCE_PATH ?= $(APPLICATION_PATH)resource/ -SOURCE_PATH ?= $(APPLICATION_PATH)source/ -WEB_PATH ?= $(APPLICATION_PATH)web/ - - -## SCRIPTS_PATH IS DEPRECATED -SCRIPTS_PATH ?= $(DEVELOPMENT_PATH)script/ - -DEVELOPMENT_SCRIPTS_PATH ?= $(DEVELOPMENT_PATH)script/ -BUILD_PATH ?= $(DEPLOYMENT_PATH)build/ -VENDOR_PATH ?= $(DEPLOYMENT_PATH)vendor/ - -DEPLOYMENT_SCRIPTS_PATH ?= $(DEPLOYMENT_PATH)script/ -LICENSE_PATH ?= $(PROJECT_ROOT) - -PROJECT_DIRECTORIES := $(PROJECT_DIRECTORIES) \ - $(APPLICATION_PATH) \ - $(RESOURCE_PATH) \ - $(SOURCE_PATH) \ - $(DEPLOYMENT_PATH) \ - $(VENDOR_PATH) \ - $(DEVELOPMENT_PATH) \ - $(DEVELOPMENT_SCRIPTS_PATH) \ - $(DEPLOYMENT_SCRIPTS_PATH) \ - $(DOCUMENTATION_PATH) \ - $(LICENSE_PATH) \ - $(BUILD_PATH) - diff --git a/development/makefiles/directories-platform-part.mk b/development/makefiles/directories-platform-part.mk deleted file mode 100644 index 8e17db76a718f84574e55049e470bcebdec3bbb4..0000000000000000000000000000000000000000 --- a/development/makefiles/directories-platform-part.mk +++ /dev/null @@ -1,46 +0,0 @@ -############################################################################################# -############################################################################################# -## -## DIRECTORIES -## -############################################################################################# -############################################################################################# - -SOURCE_PATH ?= $(PROJECT_ROOT)source/ - -RELATIVE_SCRIPT_PATH ?= script/ - -SCRIPT_PATH ?= $(PROJECT_ROOT)$(RELATIVE_SCRIPT_PATH) - -## DEPRECATED ALIAS -SCRIPTS_PATH = $(SCRIPT_PATH) - - -VENDOR_PATH ?= $(PROJECT_ROOT)vendor/ -NODE_PATH ?= $(PROJECT_ROOT)node_modules/ -TEST_PATH ?= $(PROJECT_ROOT)test/ -DEVELOPMENT_PATH ?= $(PROJECT_ROOT) - -LICENSE_PATH ?= $(PROJECT_ROOT) -DIST_PATH ?= $(PROJECT_ROOT)dist/ - -CONFIG_PATH ?= $(PROJECT_ROOT)config/ -BUILD_PATH ?= $(PROJECT_ROOT)build/ - -BOB_SNIPPED_CONFIG ?= $(CONFIG_PATH)snippet.conf -BOB_SYNC_CONFIG ?= $(CONFIG_PATH)sync.yaml - -BOB_BUILD_PATH ?= $(BUILD_PATH) -BOB_DIST_PATH ?= $(DIST_PATH) - -PROJECT_DIRECTORIES := $(PROJECT_DIRECTORIES) \ - $(SOURCE_PATH) \ - $(SCRIPT_PATH) \ - $(VENDOR_PATH) \ - $(NODE_PATH) \ - $(TEST_PATH) \ - $(LICENSE_PATH) \ - $(CONFIG_PATH) \ - $(BUILD_PATH) \ - $(DIST_PATH) - diff --git a/development/makefiles/directories-standard.mk b/development/makefiles/directories-standard.mk deleted file mode 100644 index 7a543a85f6971ba5bcb0d8e18c33a28c1cde0be8..0000000000000000000000000000000000000000 --- a/development/makefiles/directories-standard.mk +++ /dev/null @@ -1,52 +0,0 @@ -############################################################################################# -############################################################################################# -## -## DIRECTORIES -## -############################################################################################# -############################################################################################# - -APPLICATION_PATH ?= $(PROJECT_ROOT)application/ -DEPLOYMENT_PATH ?= $(PROJECT_ROOT)deployment/ -DEVELOPMENT_PATH ?= $(PROJECT_ROOT)development/ -DOCUMENTATION_PATH ?= $(PROJECT_ROOT)documentation/ -REQUIREMENT_PATH ?= $(PROJECT_ROOT)requirement/ -CREDENTIALS_PATH ?= $(PROJECT_ROOT)credential/ - -TUTORIALS_PATH ?= $(DOCUMENTATION_PATH)tutorial/ -DOCUMENTATION_CONFIG_PATH ?= $(DOCUMENTATION_PATH)config/ - -RESOURCE_PATH ?= $(APPLICATION_PATH)resource/ -SOURCE_PATH ?= $(APPLICATION_PATH)source/ -WEB_PATH ?= $(APPLICATION_PATH)web/ - -## SCRIPTS_PATH IS DEPRECATED -SCRIPTS_PATH ?= $(DEVELOPMENT_PATH)script/ - -DEVELOPMENT_SCRIPTS_PATH ?= $(DEVELOPMENT_PATH)script/ -BUILD_PATH ?= $(DEPLOYMENT_PATH)build/ -VENDOR_PATH ?= $(DEPLOYMENT_PATH)vendor/ -ALVINE_VENDOR_PATH ?= $(VENDOR_PATH)alvine/ -TEST_PATH ?= $(DEVELOPMENT_PATH)tests/ - -DEPLOYMENT_SCRIPTS_PATH ?= $(DEPLOYMENT_PATH)script/ -LICENSE_PATH ?= $(PROJECT_ROOT) - -PROJECT_DIRECTORIES := $(PROJECT_DIRECTORIES) \ - $(APPLICATION_PATH) \ - $(RESOURCE_PATH) \ - $(SOURCE_PATH) \ - $(WEB_PATH) \ - $(DEPLOYMENT_PATH) \ - $(VENDOR_PATH) \ - $(ALVINE_VENDOR_PATH) \ - $(TEST_PATH) \ - $(DEVELOPMENT_PATH) \ - $(DEVELOPMENT_SCRIPTS_PATH) \ - $(DEPLOYMENT_SCRIPTS_PATH) \ - $(DOCUMENTATION_PATH) \ - $(REQUIREMENT_PATH) \ - $(CREDENTIALS_PATH) \ - $(LICENSE_PATH) \ - $(BUILD_PATH) - diff --git a/development/makefiles/docker.mk b/development/makefiles/docker.mk deleted file mode 100644 index 4bc7f6c984beb519d1fbc767d0480920bc72f49a..0000000000000000000000000000000000000000 --- a/development/makefiles/docker.mk +++ /dev/null @@ -1,11 +0,0 @@ -############################################################################################# -############################################################################################# -## -## DOCKER -## -############################################################################################# -############################################################################################# - -DOCKER ?= docker -EXECUTABLES = $(EXECUTABLES:-) $(DOCKER); - diff --git a/development/makefiles/docman.mk b/development/makefiles/docman.mk deleted file mode 100644 index 40b21228b0786d9763014feadbe4b20b5dd86709..0000000000000000000000000000000000000000 --- a/development/makefiles/docman.mk +++ /dev/null @@ -1,19 +0,0 @@ -############################################################################################# -############################################################################################# -## -## DOCMAN -## -############################################################################################# -############################################################################################# - - -DOCMAN_BIN ?= $(VENDOR_PATH)docman -DOCMAN_CONFIG_PATH ?= $(DOCUMENTATION_CONFIG_PATH)docman.yaml -DOCMAN_HTML_ARTEFACT ?= $(PROJECT_ROOT)deployment/build/manual.html -DOCMAN_PDF_ARTEFACT ?= $(PROJECT_ROOT)deployment/build/manual.pdf -DOCMAN_SOURCE ?= $(shell find $(DOCUMENTATION_PATH) -type f) - -$(DOCMAN_BIN): - $(QUIET) $(MKDIR) -p $(VENDOR_PATH) - $(QUIET) $(WGET) -O $(DOCMAN_BIN) http://download.schukai.com/tools/docman/docman-$(shell uname -s | tr [:upper:] [:lower:])-$(shell echo `uname -m | sed s/aarch64/arm64/ | sed s/x86_64/amd64/`) - $(QUIET) $(CHMOD) u+x $(DOCMAN_BIN) diff --git a/development/makefiles/git.mk b/development/makefiles/git.mk deleted file mode 100644 index 5521077229d9fa29ad53cb945b872db978996347..0000000000000000000000000000000000000000 --- a/development/makefiles/git.mk +++ /dev/null @@ -1,12 +0,0 @@ -############################################################################################# -############################################################################################# -## -## GIT -## -############################################################################################# -############################################################################################# - -GIT ?= git -UUIDGEN ?= uuidgen - -EXECUTABLES = $(EXECUTABLES:-) $(UUIDGEN) $(GIT) \ No newline at end of file diff --git a/development/makefiles/gitignore.mk b/development/makefiles/gitignore.mk deleted file mode 100644 index 3ff75ff7a3b27130d09c06e0c80f05a45eaca0dd..0000000000000000000000000000000000000000 --- a/development/makefiles/gitignore.mk +++ /dev/null @@ -1,530 +0,0 @@ -############################################################################################# -############################################################################################# -## -## INSTALL .gitignore -## -############################################################################################# -############################################################################################# - -define GITIGNOREDS - -# Makefile comes from update -Makefile.example - -# Vendor -/development/vendor/ -/deployment/vendor/ - -# Created by https://www.toptal.com/developers/gitignore/api/intellij+iml,phpunit,git,vim,visualstudiocode,phpstorm,go,intellij+all,netbeans,dbeaver,node,yarn -# Edit at https://www.toptal.com/developers/gitignore?templates=intellij+iml,phpunit,git,vim,visualstudiocode,phpstorm,go,intellij+all,netbeans,dbeaver,node,yarn - -### DBeaver ### -# ide config file -.dbeaver-data-sources*.xml - -### Git ### -# Created by git for backups. To disable backups in Git: -# $ git config --global mergetool.keepBackup false -*.orig - -# Created by git when using merge tools for conflicts -*.BACKUP.* -*.BASE.* -*.LOCAL.* -*.REMOTE.* -*_BACKUP_*.txt -*_BASE_*.txt -*_LOCAL_*.txt -*_REMOTE_*.txt - -### Go ### -# If you prefer the allow list template instead of the deny list, see community template: -# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore -# -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib - -# Test binary, built with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Dependency directories (remove the comment below to include it) -# vendor/ - -# Go workspace file -go.work - -### Go Patch ### -/vendor/ -/Godeps/ - -### Intellij+all ### -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - -# User-specific stuff -.idea/**/workspace.xml -.idea/**/tasks.xml -.idea/**/usage.statistics.xml -.idea/**/dictionaries -.idea/**/shelf - -# AWS User-specific -.idea/**/aws.xml - -# Generated files -.idea/**/contentModel.xml - -# Sensitive or high-churn files -.idea/**/dataSources/ -.idea/**/dataSources.ids -.idea/**/dataSources.local.xml -.idea/**/sqlDataSources.xml -.idea/**/dynamic.xml -.idea/**/uiDesigner.xml -.idea/**/dbnavigator.xml - -# Gradle -.idea/**/gradle.xml -.idea/**/libraries - -# Gradle and Maven with auto-import -# When using Gradle or Maven with auto-import, you should exclude module files, -# since they will be recreated, and may cause churn. Uncomment if using -# auto-import. -# .idea/artifacts -# .idea/compiler.xml -# .idea/jarRepositories.xml -# .idea/modules.xml -# .idea/*.iml -# .idea/modules -# *.iml -# *.ipr - -# CMake -cmake-build-*/ - -# Mongo Explorer plugin -.idea/**/mongoSettings.xml - -# File-based project format -*.iws - -# IntelliJ -out/ - -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -# Cursive Clojure plugin -.idea/replstate.xml - -# SonarLint plugin -.idea/sonarlint/ - -# Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties -fabric.properties - -# Editor-based Rest Client -.idea/httpRequests - -# Android studio 3.1+ serialized cache file -.idea/caches/build_file_checksums.ser - -### Intellij+all Patch ### -# Ignore everything but code style settings and run configurations -# that are supposed to be shared within teams. - -.idea/* - -!.idea/codeStyles -!.idea/runConfigurations - -### Intellij+iml ### -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - -# User-specific stuff - -# AWS User-specific - -# Generated files - -# Sensitive or high-churn files - -# Gradle - -# Gradle and Maven with auto-import -# When using Gradle or Maven with auto-import, you should exclude module files, -# since they will be recreated, and may cause churn. Uncomment if using -# auto-import. -# .idea/artifacts -# .idea/compiler.xml -# .idea/jarRepositories.xml -# .idea/modules.xml -# .idea/*.iml -# .idea/modules -# *.iml -# *.ipr - -# CMake - -# Mongo Explorer plugin - -# File-based project format - -# IntelliJ - -# mpeltonen/sbt-idea plugin - -# JIRA plugin - -# Cursive Clojure plugin - -# SonarLint plugin - -# Crashlytics plugin (for Android Studio and IntelliJ) - -# Editor-based Rest Client - -# Android studio 3.1+ serialized cache file - -### Intellij+iml Patch ### -# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023 - -*.iml -modules.xml -.idea/misc.xml -*.ipr - -### NetBeans ### -**/nbproject/private/ -**/nbproject/Makefile-*.mk -**/nbproject/Package-*.bash -build/ -nbbuild/ -dist/ -nbdist/ -.nb-gradle/ - -### Node ### -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* -.pnpm-debug.log* - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage -*.lcov - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# Snowpack dependency directory (https://snowpack.dev/) -web_modules/ - -# TypeScript cache -*.tsbuildinfo - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Optional stylelint cache -.stylelintcache - -# Microbundle cache -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variable files -.env -.env.development.local -.env.test.local -.env.production.local -.env.local - -# parcel-bundler cache (https://parceljs.org/) -.cache -.parcel-cache - -# Next.js build output -.next -out - -# Nuxt.js build / generate output -.nuxt -dist - -# Gatsby files -.cache/ -# Comment in the public line in if your project uses Gatsby and not Next.js -# https://nextjs.org/blog/next-9-1#public-directory-support -# public - -# vuepress build output -.vuepress/dist - -# vuepress v2.x temp and cache directory -.temp - -# Docusaurus cache and generated files -.docusaurus - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# TernJS port file -.tern-port - -# Stores VSCode versions used for testing VSCode extensions -.vscode-test - -# yarn v2 -.yarn/cache -.yarn/unplugged -.yarn/build-state.yml -.yarn/install-state.gz -.pnp.* - -### Node Patch ### -# Serverless Webpack directories -.webpack/ - -# Optional stylelint cache - -# SvelteKit build / generate output -.svelte-kit - -### PhpStorm ### -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - -# User-specific stuff - -# AWS User-specific - -# Generated files - -# Sensitive or high-churn files - -# Gradle - -# Gradle and Maven with auto-import -# When using Gradle or Maven with auto-import, you should exclude module files, -# since they will be recreated, and may cause churn. Uncomment if using -# auto-import. -# .idea/artifacts -# .idea/compiler.xml -# .idea/jarRepositories.xml -# .idea/modules.xml -# .idea/*.iml -# .idea/modules -# *.iml -# *.ipr - -# CMake - -# Mongo Explorer plugin - -# File-based project format - -# IntelliJ - -# mpeltonen/sbt-idea plugin - -# JIRA plugin - -# Cursive Clojure plugin - -# SonarLint plugin - -# Crashlytics plugin (for Android Studio and IntelliJ) - -# Editor-based Rest Client - -# Android studio 3.1+ serialized cache file - -### PhpStorm Patch ### -# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 - -# *.iml -# modules.xml -# .idea/misc.xml -# *.ipr - -# Sonarlint plugin -# https://plugins.jetbrains.com/plugin/7973-sonarlint -.idea/**/sonarlint/ - -# SonarQube Plugin -# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin -.idea/**/sonarIssues.xml - -# Markdown Navigator plugin -# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced -.idea/**/markdown-navigator.xml -.idea/**/markdown-navigator-enh.xml -.idea/**/markdown-navigator/ - -# Cache file creation bug -# See https://youtrack.jetbrains.com/issue/JBR-2257 -.idea/$CACHE_FILE$ - -# CodeStream plugin -# https://plugins.jetbrains.com/plugin/12206-codestream -.idea/codestream.xml - -# Azure Toolkit for IntelliJ plugin -# https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij -.idea/**/azureSettings.xml - -### PHPUnit ### -# Covers PHPUnit -# Reference: https://phpunit.de/ - -# Generated files -.phpunit.result.cache -.phpunit.cache - -# PHPUnit -/app/phpunit.xml -/phpunit.xml - -# Build data -/build/ - -### Vim ### -# Swap -[._]*.s[a-v][a-z] -!*.svg # comment out if you don't need vector files -[._]*.sw[a-p] -[._]s[a-rt-v][a-z] -[._]ss[a-gi-z] -[._]sw[a-p] - -# Session -Session.vim -Sessionx.vim - -# Temporary -.netrwhist -*~ -# Auto-generated tag files -tags -# Persistent undo -[._]*.un~ - -### VisualStudioCode ### -.vscode/* -!.vscode/settings.json -!.vscode/tasks.json -!.vscode/launch.json -!.vscode/extensions.json -!.vscode/*.code-snippets - -# Local History for Visual Studio Code -.history/ - -# Built Visual Studio Code Extensions -*.vsix - -### VisualStudioCode Patch ### -# Ignore all local history of files -.history -.ionide - -# Support for Project snippet scope -.vscode/*.code-snippets - -# Ignore code-workspaces -*.code-workspace - -### yarn ### -# https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored - -.yarn/* -!.yarn/releases -!.yarn/patches -!.yarn/plugins -!.yarn/sdks -!.yarn/versions - -# if you are NOT using Zero-installs, then: -# comment the following lines -!.yarn/cache - -# and uncomment the following lines -# .pnp.* - -endef - -export GITIGNOREDS -$(PROJECT_ROOT).gitignore: - $(QUIET) $(ECHO) "$$GITIGNOREDS" >> $@ - - - diff --git a/development/makefiles/go.mk b/development/makefiles/go.mk deleted file mode 100644 index 679e0ac0b784d000b2cc036da2978f918028a865..0000000000000000000000000000000000000000 --- a/development/makefiles/go.mk +++ /dev/null @@ -1,34 +0,0 @@ -############################################################################################# -############################################################################################# -## -## COMMANDS GO -## -############################################################################################# -############################################################################################# - -# path and binaries -GO := go -GOLINT := golint - -EXECUTABLES = $(EXECUTABLES:-) $(GO) $(GOLINT); - -ifeq ($(shell command -v $(GO) 2> /dev/null),) - $(error "go is not installed. Please install go <https://go.dev/doc/install>") -endif - -GOPATH=$(shell go env GOPATH) - -ifeq ($(GOPATH),) - DIRS := bin pkg src - GOPATH=$(DEPLOYMENT_PATH)/go/ - $(shell mkdir -p $(GOPATH)) - $(shell $(foreach entry,$(DIRS),mkdir -p "$(GOPATH)$(entry)";)) - export PATH=$(PATH):$(GOPATH)/bin -endif - -ifdef SOURCE_PATH - PKG_LIST := $(shell if [ -d "SOURCE_PATH" ] ; then cd $(SOURCE_PATH); $(GO) list ./... | grep -v /vendor/ ; fi) - GO_FILES := $(shell if [ -d "SOURCE_PATH" ] ; then cd $(SOURCE_PATH); find . -name '*.go' | grep -v /vendor/ | grep -v _test.go; fi) -endif - - diff --git a/development/makefiles/jsdoc-json.mk b/development/makefiles/jsdoc-json.mk deleted file mode 100644 index e5315ac4d52e02c5e908b0d8295feb4ee1339d8c..0000000000000000000000000000000000000000 --- a/development/makefiles/jsdoc-json.mk +++ /dev/null @@ -1,115 +0,0 @@ -############################################################################################# -############################################################################################# -## -## INSTALL jsdoc.json -## -############################################################################################# -############################################################################################# - -define JSDOCJSON -{ - "tags": { - "allowUnknownTags": true - }, - "source": { - "include": "$(SOURCE_PATH)", - "includePattern": "\\.js$$", - "excludePattern": "" - }, - "plugins": [ - "plugins/markdown", - "jsdoc-plantuml" - ], - "opts": { - "template": "node_modules/clean-jsdoc-theme", - "encoding": "utf8", - "destination": "$(BUILD_PATH)/docs/", - "recurse": true, - "verbose": true, - "theme_opts": { - "theme": "light", - "title": "$(COMPONENT_NAME)", - "meta": [ - { - "name": "author", - "content": "schukai GmbH" - }, - { - "name": "description", - "content": "javascript library for ..." - } - ], - "search": true, - "add_style_path": [ - { - "href": "https://monsterjs.org/assets/prettify.css", - "crossorigin": "anonymous", - "rel": "stylesheet" - } - ], - "add_script_path": [ - { - "src": "https://code.jquery.com/jquery-3.5.1.js", - "integrity": "sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc=", - "crossorigin": "anonymous" - }, - ], - "footer": "<a href='https://about.schukai.com/de/impressum/'>Imprint</a>", - "overlay_scrollbar": { - "options": { - } - }, - "resizeable": { - "navbar": { - "min": "300", - "max": "600" - } - }, - "codepen": { - "enable_for": [ - "examples" - ], - "options": { - "title": "javascript library by schukai GmbH", - "description": "the example ...", - "editors": "0012" - } - }, - "sections": [ - "Tutorials", - "Namespaces", - "Classes", - "Modules", - "Externals", - "Events", - "Mixins", - "Interfaces", - "Global", - "Menu" - ] - } - }, - "templates": { - "cleverLinks": true, - "monospaceLinks": false, - "default": { - "outputSourceFiles": false - } - }, - "plantuml": { - "puml": { - "create": true, - "destination": "$(BUILD_PATH)/docs/puml" - }, - "images": { - "create": true, - "destination": "$(BUILD_PATH)/docs/images", - "defaultFormat": "svg" - } - } -} -endef - -export JSDOCJSON -$(DEPLOYMENT_PATH)jsdoc.json: - $(QUIET) $(ECHO) "$$JSDOCJSON" >> $@ \ No newline at end of file diff --git a/development/makefiles/jsdoc.mk b/development/makefiles/jsdoc.mk deleted file mode 100644 index b365b225c307486353885e0aa4f47021a0ede9f2..0000000000000000000000000000000000000000 --- a/development/makefiles/jsdoc.mk +++ /dev/null @@ -1,15 +0,0 @@ -############################################################################################# -############################################################################################# -## -## COMMANDS JSDOC -## -############################################################################################# -############################################################################################# - -# path and binaries -JSDOC ?= $(NODE_MODULES_BIN_DIR)jsdoc - -EXECUTABLES = $(EXECUTABLES:-) $(JSDOC); - -FIXBROKENPLANTUML ?= $(NODE_MODULES_DIR)jsdoc-plantuml/fixBrokenNodeJS.js -DOCUMENTATION_S3_PATH ?= s3://doc.alvine.io/en/oss/$(COMPONENT_SLUG)/ \ No newline at end of file diff --git a/development/makefiles/license-agpl3.mk b/development/makefiles/license-agpl3.mk deleted file mode 100644 index 9b3a5a9fa2093cf57953e04be5dce0d2079f44c8..0000000000000000000000000000000000000000 --- a/development/makefiles/license-agpl3.mk +++ /dev/null @@ -1,700 +0,0 @@ -############################################################################################# -############################################################################################# -## -## AGPL 3.0 LICENSE -## -############################################################################################# -############################################################################################# - -## License used in the project -LICENSE_TEXT ?= AGPL 3.0 - -## The spdx license identifier -SPDX_LICENSE_ID ?= AGPL-3.0 - -## Copyright holder of the project -COPYRIGHT_TEXT ?= © schukai GmbH, Released under the $(LICENSE_TEXT) License. - -## Copyright URL -COPYRIGHT_URL ?= [AGPL](https://www.gnu.org/licenses/agpl-3.0.de.html) - -## The owner of the project -COPYRIGHT_OWNER ?= schukai GmbH - - -define LICENSE_FILE_CONTENT -LICENSE - -* All content residing under the "documentation/" directory of this repository is licensed under "Creative Commons: CC BY-SA 4.0 license". -* All content that resides under the "application/" directory of this repository, if that directory exists, is licensed under the license defined in "application/LICENSE". -* All third-party components that are integrated into our software are licensed under the original licence provided by the owner of the respective component. -* Content outside the above directories or restrictions is available under the "AGPL 3.0" licence as defined here: https://www.gnu.org/licenses/agpl-3.0.en.html - -endef - - -define LICENSE_AGPL_FILE_CONTENT - GNU AFFERO GENERAL PUBLIC LICENSE - Version 3, 19 November 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU Affero General Public License is a free, copyleft license for -software and other kinds of works, specifically designed to ensure -cooperation with the community in the case of network server software. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -our General Public Licenses are intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - Developers that use our General Public Licenses protect your rights -with two steps: (1) assert copyright on the software, and (2) offer -you this License which gives you legal permission to copy, distribute -and/or modify the software. - - A secondary benefit of defending all users' freedom is that -improvements made in alternate versions of the program, if they -receive widespread use, become available for other developers to -incorporate. Many developers of free software are heartened and -encouraged by the resulting cooperation. However, in the case of -software used on network servers, this result may fail to come about. -The GNU General Public License permits making a modified version and -letting the public access it on a server without ever releasing its -source code to the public. - - The GNU Affero General Public License is designed specifically to -ensure that, in such cases, the modified source code becomes available -to the community. It requires the operator of a network server to -provide the source code of the modified version running there to the -users of that server. Therefore, public use of a modified version, on -a publicly accessible server, gives the public access to the source -code of the modified version. - - An older license, called the Affero General Public License and -published by Affero, was designed to accomplish similar goals. This is -a different license, not a version of the Affero GPL, but Affero has -released a new version of the Affero GPL which permits relicensing under -this license. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU Affero General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Remote Network Interaction; Use with the GNU General Public License. - - Notwithstanding any other provision of this License, if you modify the -Program, your modified version must prominently offer all users -interacting with it remotely through a computer network (if your version -supports such interaction) an opportunity to receive the Corresponding -Source of your version by providing access to the Corresponding Source -from a network server at no charge, through some standard or customary -means of facilitating copying of software. This Corresponding Source -shall include the Corresponding Source for any work covered by version 3 -of the GNU General Public License that is incorporated pursuant to the -following paragraph. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the work with which it is combined will remain governed by version -3 of the GNU General Public License. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU Affero General Public License from time to time. Such new versions -will be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU Affero General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU Affero General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU Affero General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. - -Also add information on how to contact you by electronic and paper mail. - - If your software can interact with users remotely through a computer -network, you should also make sure that it provides a way for users to -get its source. For example, if your program is a web application, its -interface could display a "Source" link that leads users to an archive -of the code. There are many ways you could offer source, and different -solutions will be better for different programs; see section 13 for the -specific requirements. - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU AGPL, see -<https://www.gnu.org/licenses/>. -endef - - diff --git a/development/makefiles/license-all-rights-reserved.mk b/development/makefiles/license-all-rights-reserved.mk deleted file mode 100644 index ea690fc4393b20a2f36b1e1811ec3c1b73518efc..0000000000000000000000000000000000000000 --- a/development/makefiles/license-all-rights-reserved.mk +++ /dev/null @@ -1,55 +0,0 @@ -############################################################################################# -############################################################################################# -## -## AGPL 3.0 LICENSE -## -############################################################################################# -############################################################################################# - -## License used in the project -LICENSE_TEXT ?= All rights reserved - -## The spdx license identifier -SPDX_LICENSE_ID ?= - -## Copyright holder of the project -COPYRIGHT_TEXT ?= © schukai GmbH, $(LICENSE_TEXT). - -## The owner of the project -COPYRIGHT_OWNER ?= schukai GmbH - -COPYRIGHT_URL ?= [LICENSE](https://www.schukai.com/) - -define LICENSE_FILE_CONTENT -The schukai Enterprise License (the "Enterprise License"). -Copyright © 2022 schukai GmbH. - -Regarding this Software, schukai GmbH is the licensor and you are the licensee. - -By using the Software, you agree to all the terms and conditions set forth below. - -This software and associated documentation files (the "Software") may be used in production only if you (and any company -you represent) have a valid Enterprise License corresponding to your use. Subject to the preceding sentence, you are free -to modify this Software and to release patches for the Software. You agree that schukai and/or its licensors (as applicable) -retain all right, title and interest in and to all such modifications and/or patches, and that all such modifications -and/or patches may be used, copied, modified, displayed, distributed or otherwise exploited only with a valid Enterprise -License for the appropriate use. Notwithstanding the foregoing, you may copy and modify the Software for development and -testing purposes without requiring a subscription. - -You agree that schukai and/or its licensors (if applicable) retain all right, title and interest in and to all such -modifications. No additional rights are granted to you beyond those expressly set forth herein. Subject to the foregoing, -you may not copy, merge, publish, distribute, sublicense and/or sell the Software. - -THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIMS, DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. - -For any third-party components incorporated into schukai's software, such components are licensed under the original license -provided by the owner of the applicable component. - -endef - - - - diff --git a/development/makefiles/license-unlicensed.mk b/development/makefiles/license-unlicensed.mk deleted file mode 100644 index 953b34bb8d7f667ee976c26a4de501d54ab48adf..0000000000000000000000000000000000000000 --- a/development/makefiles/license-unlicensed.mk +++ /dev/null @@ -1,21 +0,0 @@ -############################################################################################# -############################################################################################# -## -## UNLICENSED -## -############################################################################################# -############################################################################################# - -## License used in the project -LICENSE_TEXT ?= UNLICENSED - -## The spdx license identifier -SPDX_LICENSE_ID ?= - -## Copyright holder of the project -COPYRIGHT_TEXT ?= © schukai GmbH, $(LICENSE_TEXT). - -COPYRIGHT_URL ?= [LICENSE](https://www.schukai.com/) - -## The owner of the project -COPYRIGHT_OWNER ?= schukai GmbH diff --git a/development/makefiles/licenses.mk b/development/makefiles/licenses.mk deleted file mode 100644 index d8f289bc8ced8d444f5e14340167f0ac73a03b5d..0000000000000000000000000000000000000000 --- a/development/makefiles/licenses.mk +++ /dev/null @@ -1,25 +0,0 @@ -############################################################################################# -############################################################################################# -## -## LICENSE -## -############################################################################################# -############################################################################################# - -ifeq ($(GO),) - $(error $(ERRORMARKER) Go is not defined, check your Makefile if go.mk is included) -endif - -ifneq "$(wildcard $(SOURCE_PATH) )" "" - ## Files wich should be checked for license headers - LICENSE_FILE_PATTERN ?= $(shell find $(SOURCE_PATH) -type f \( -iname \*.go -o -iname \*.php -o -iname \*.js -o -iname \*.mjs -o -iname \*.cjs \) ) -endif - -# https://spdx.github.io/spdx-spec/v2.3/SPDX-license-list/ -ADDLICENSE_BIN ?= addlicense -ifeq ($(shell command -v $(ADDLICENSE_BIN) 2> /dev/null),) - $(shell $(GO) install github.com/google/addlicense@latest) - EXECUTABLES = $(EXECUTABLES:-) $(ADDLICENSE_BIN); -endif - -EXECUTABLES = $(EXECUTABLES:-) $(ADDLICENSE_BIN) diff --git a/development/makefiles/node.mk b/development/makefiles/node.mk deleted file mode 100644 index 4c1bf4e4330dbd5511e989adf86143ae8f1eadaf..0000000000000000000000000000000000000000 --- a/development/makefiles/node.mk +++ /dev/null @@ -1,55 +0,0 @@ -############################################################################################# -############################################################################################# -## -## COMMANDS NODEJS -## -############################################################################################# -############################################################################################# - -# path and binaries -NODEJS ?= node -NODE ?= node -NPM ?= pnpm - -EXECUTABLES = $(EXECUTABLES:-) $(NPM); - -NODE_PACKAGES := $(shell find $(PROJECT_ROOT) -type f -name 'package.json' -not -path '*/node_modules/*') -NODE_MODULES := $(shell find $(PROJECT_ROOT) -type d -name 'node_modules' -prune) - -NODE_MODULES_MODIFIED := $(shell find $(PROJECT_ROOT) -type f -name 'package.json' -not -path '*/node_modules/*' -exec sh -c 'F=$$(dirname {}); echo $${F}/node_modules/.modified' \;) - -$(NODE_MODULES_MODIFIED): $(NODE_PACKAGES) - $(ECHOMARKER) "Updating node modules..." - $(QUIET) for p in $(NODE_PACKAGES); do \ - DIR=$$(dirname $$p); \ - echo "Updating package: $${DIR}" ;\ - $(NPM) install --prefix $${DIR} ;\ - if [ -d $${DIR}/node_modules/ ]; then \ - touch $${DIR}/node_modules/.modified ;\ - fi ;\ - done - -## Main Develpoment Node Repos -NODE_ROOT_DIR ?= $(DEVELOPMENT_PATH) -NODE_MODULES_DIR ?= $(NODE_ROOT_DIR)node_modules/ -NODE_PACKAGE_PATH ?= $(NODE_ROOT_DIR)package.json -NODE_MODULES_BIN_DIR ?= $(NODE_MODULES_DIR).bin/ - -ESBUILD ?= $(NODE_MODULES_BIN_DIR)esbuild -WEBPACK ?= $(NODE_MODULES_BIN_DIR)webpack -BABEL ?= $(NODE_MODULES_BIN_DIR)babel -UGLIFYJS ?= $(NODE_MODULES_BIN_DIR)uglifyjs -C8 ?= $(NODE_MODULES_BIN_DIR)c8 -MOCHA ?= $(NODE_MODULES_BIN_DIR)mocha - -PACKAGE_JSON ?= $(NODE_ROOT_DIR)package.json - -ifneq "$(wildcard $(SOURCE_PATH) )" "" - MJS_SOURCE_FILES := $(shell find $(SOURCE_PATH) -name '*.mjs') - MJS_RELATIVE_SOURCE_FILES := $(shell find $(SOURCE_PATH) -name '*.mjs' -exec realpath --relative-to $(PROJECT_ROOT) {} \; ) - - JS_SOURCE_FILES := $(shell find $(SOURCE_PATH) -name '*.js') - JS_RELATIVE_SOURCE_FILES := $(shell find $(SOURCE_PATH) -name '*.js' -exec realpath --relative-to $(PROJECT_ROOT) {} \; ) -endif - - diff --git a/development/makefiles/output.mk b/development/makefiles/output.mk deleted file mode 100644 index 9aa5bb737e5b0a3fcb47ff40b40690f2c5cdc4be..0000000000000000000000000000000000000000 --- a/development/makefiles/output.mk +++ /dev/null @@ -1,54 +0,0 @@ -############################################################################################# -############################################################################################# -## -## COLORS -## -############################################################################################# -############################################################################################# - -INFO := $(GREEN) -COMMENT := $(YELLOW) - -############################################################################################# -############################################################################################# -## -## OUTPUT CONTROL AND STANDARD OUTPUTS -## -############################################################################################# -############################################################################################# - -MARKER := $(BLUE)[+]$(RESET) -ERRORMARKER := $(RED)[-]$(RESET) - -############################################################################################# -############################################################################################# -## -## DEACTIVATE THE QUIET MODE BY OVERWRITING THE VALUE WITH SPACE -## -############################################################################################# -############################################################################################# - -ifndef DEBUG - QUIET = @ -else - QUIET = -endif - -ifndef DONTOPENBROWSER - OPENBROWSER = false -else - OPENBROWSER = true -endif - -############################################################################################# -############################################################################################# -## -## COMMANDS -## -############################################################################################# -############################################################################################# - -ECHO := @echo -ECHOMARKER := @echo "$(MARKER) $0" -ECHOERRORMARKER := @echo "$(ERRORMARKER) $0" - diff --git a/development/makefiles/placeholder.mk b/development/makefiles/placeholder.mk deleted file mode 100644 index 7b79026ced6a04468d12c2407b5e4838509d69f0..0000000000000000000000000000000000000000 --- a/development/makefiles/placeholder.mk +++ /dev/null @@ -1,9 +0,0 @@ -############################################################################################# -############################################################################################# -## -## PLACEHOLDER -## -############################################################################################# -############################################################################################# - -COMPONENT_SLUG := $(shell echo "$(COMPONENT_NAME)" | tr '[:upper:]' '[:lower:]') diff --git a/development/makefiles/project.mk b/development/makefiles/project.mk deleted file mode 100644 index 36e051efc6ad73755b1ad792d05420b787ff64e0..0000000000000000000000000000000000000000 --- a/development/makefiles/project.mk +++ /dev/null @@ -1,5 +0,0 @@ - - - - -DOCUMENTATION_S3_PATH ?= s3://monsterjs.org/en/doc/$(COMPONENT_SLUG)/ \ No newline at end of file diff --git a/development/makefiles/readme-go-lib.mk b/development/makefiles/readme-go-lib.mk deleted file mode 100644 index ae10cdc29efd4bfaa2c8fa0bd6586eb2cc783cee..0000000000000000000000000000000000000000 --- a/development/makefiles/readme-go-lib.mk +++ /dev/null @@ -1,80 +0,0 @@ -############################################################################################# -############################################################################################# -## -## README -## -############################################################################################# -############################################################################################# - - -define README_FILE_CONTENT -# $(COMPONENT_NAME) - -$(COMPONENT_NAME) is ... - -## Documentation - -To check out docs and examples, visit .... - -## Installation - -```shell -go get $(shell git config --get remote.origin.url | sed -E 's/^\s*.*:\/\///g') -``` - -**Note:** This library uses [Go Modules](https://github.com/golang/go/wiki/Modules) to manage dependencies. - -## Usage - -## Contributing - -Merge requests are welcome. For major changes, please open an issue first to discuss what -you would like to change. **Please make sure to update tests as appropriate.** - -Versioning is done with [SemVer](https://semver.org/). -Changelog is generated with [git-chglog](https://github.com/git-chglog/git-chglog#git-chglog) - -Commit messages should follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification. -Messages are started with a type, which is one of the following: - -- **feat**: A new feature -- **fix**: A bug fix -- **doc**: Documentation only changes -- **refactor**: A code change that neither fixes a bug nor adds a feature -- **perf**: A code change that improves performance -- **test**: Adding missing or correcting existing tests -- **chore**: Other changes that don't modify src or test files - -The footer would be used for a reference to an issue or a breaking change. - -A commit that has a footer `BREAKING CHANGE:`, or appends a ! after the type/scope, -introduces a breaking API change (correlating with MAJOR in semantic versioning). -A BREAKING CHANGE can be part of commits of any type. - -the following is an example of a commit message: - -```text -feat: add 'extras' field -``` - -## Questions - -For questions and commercial support, please contact [schukai GmbH](https://www.schukai.com/). -The issue list of this repo is exclusively for bug reports and feature requests. - -## Issues - -Please make sure to read the Issue Reporting Checklist before opening an -issue. Issues not conforming to the guidelines may be closed immediately. - -## License - -$(COPYRIGHT_TEXT) - -$(COPYRIGHT_URL) - -You can also purchase a commercial license. - - -endef - diff --git a/development/makefiles/readme-go-utilities.mk b/development/makefiles/readme-go-utilities.mk deleted file mode 100644 index 48320cc61ea5bee35251288721fe461ba350a57d..0000000000000000000000000000000000000000 --- a/development/makefiles/readme-go-utilities.mk +++ /dev/null @@ -1,86 +0,0 @@ -############################################################################################# -############################################################################################# -## -## README -## -############################################################################################# -############################################################################################# - - -define README_FILE_CONTENT -# $(COMPONENT_NAME) - -$(COMPONENT_NAME) is ... - -## Documentation - -To check out docs and examples, visit .... - -## Installation - -If you want to install the latest version of this tool, you can use the following command: - -```shell -wget -O ./$(COMPONENT_SLUG) http://download.schukai.com/tools/$(COMPONENT_SLUG)/$(COMPONENT_SLUG)-$$( uname -s | tr [:upper:] [:lower:])-$$(echo uname -m | sed s/aarch64/arm64/ | sed s/x86_64/amd64/) -``` - -## Usage - -The following command will show you the help of the tool: - -```shell -$(COMPONENT_SLUG) help -``` - -## Contributing - -Merge requests are welcome. For major changes, please open an issue first to discuss what -you would like to change. **Please make sure to update tests as appropriate.** - -Versioning is done with [SemVer](https://semver.org/). -Changelog is generated with [git-chglog](https://github.com/git-chglog/git-chglog#git-chglog) - -Commit messages should follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification. -Messages are started with a type, which is one of the following: - -- **feat**: A new feature -- **fix**: A bug fix -- **doc**: Documentation only changes -- **refactor**: A code change that neither fixes a bug nor adds a feature -- **perf**: A code change that improves performance -- **test**: Adding missing or correcting existing tests -- **chore**: Other changes that don't modify src or test files - -The footer would be used for a reference to an issue or a breaking change. - -A commit that has a footer `BREAKING CHANGE:`, or appends a ! after the type/scope, -introduces a breaking API change (correlating with MAJOR in semantic versioning). -A BREAKING CHANGE can be part of commits of any type. - -the following is an example of a commit message: - -```text -feat: add 'extras' field -``` - -## Questions - -For questions and commercial support, please contact [schukai GmbH](https://www.schukai.com/). -The issue list of this repo is exclusively for bug reports and feature requests. - -## Issues - -Please make sure to read the Issue Reporting Checklist before opening an -issue. Issues not conforming to the guidelines may be closed immediately. - -## License - -$(COPYRIGHT_TEXT) - -$(COPYRIGHT_URL) - -You can also purchase a commercial license. - - -endef - diff --git a/development/makefiles/readme-platform-part.mk b/development/makefiles/readme-platform-part.mk deleted file mode 100644 index 6b3aba1bbf99232695954106b46e931c58b7eeca..0000000000000000000000000000000000000000 --- a/development/makefiles/readme-platform-part.mk +++ /dev/null @@ -1,92 +0,0 @@ -############################################################################################# -############################################################################################# -## -## README -## -############################################################################################# -############################################################################################# - - -define README_FILE_CONTENT -# $(COMPONENT_NAME) - -$(COMPONENT_NAME) is a part of the Alvine/Agenor project. - -This app is built with ES6 modules and uses [import](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/import) -and [export](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export). - -For some functions, you need additional [polyfills](#polyfill). - -## Documentation - -To check out docs and examples, visit [doc.alvine.io](https://doc.alvine.io). - -## Installation - -`pnpm install @oss/$(COMPONENT_SLUG)` - -## Usage - -A simple example of the use of functionality from $(COMPONENT_NAME). We create a small file `index.mjs`. -The `m` in `.mjs` stands for module. In the example we want to make substitutions in a string. - -```js -// script -``` - -To integrate this function into a website it is recommended to use a bundler like [esbuild](https://esbuild.github.io/). - -```sh -esbuild index.mjs --outfile dist.js -``` - -We can now integrate that into our website. - -```html -<!DOCTYPE html> -<html lang="en"> -<head> - <meta charset="UTF-8"> - <title>$(COMPONENT_NAME)</title> - <script src="dist.js"></script> -</head> -<body> -``` - -Voila! - - -### Polyfill - -We do try to work around some browser bugs, but on the whole we don't use polyfills and feature detection. - -However, many functions can be mapped via [polyfill.io](https://polyfill.io/) and thus the compatibility can be increased. - -```js -<script id="polyfill" src="https://polyfill.io/v3/polyfill.min.js?..." - crossorigin="anonymous" - referrerpolicy="no-referrer"></script> -``` - -## Questions - -For questions and commercial support, please contact [schukai GmbH](https://www.schukai.com/). -The issue list of this repo is exclusively for bug reports and feature requests. - -## Issues - -Please make sure to read the Issue Reporting Checklist before opening an -issue. Issues not conforming to the guidelines may be closed immediately. - -## License - -$(COPYRIGHT_TEXT) - -$(COPYRIGHT_URL) - -## Changelog - -Detailed changes for each release are documented in the CHANGELOG. - -endef - diff --git a/development/makefiles/readme-standard.mk b/development/makefiles/readme-standard.mk deleted file mode 100644 index d9fd70eaef9ef4f0ffaa1f786dd98771d3665ca1..0000000000000000000000000000000000000000 --- a/development/makefiles/readme-standard.mk +++ /dev/null @@ -1,45 +0,0 @@ -############################################################################################# -############################################################################################# -## -## README -## -############################################################################################# -############################################################################################# - - -define README_FILE_CONTENT -# $(COMPONENT_NAME) - -$(COMPONENT_NAME) is ... - -## Documentation - -To check out docs and examples, visit .... - -## Installation - - -## Usage - - -## Questions - -For questions and commercial support, please contact [schukai GmbH](https://www.schukai.com/). -The issue list of this repo is exclusively for bug reports and feature requests. - -## Issues - -Please make sure to read the Issue Reporting Checklist before opening an -issue. Issues not conforming to the guidelines may be closed immediately. - -## License - -$(COPYRIGHT_TEXT) - -$(COPYRIGHT_URL) - -You can also purchase a commercial license. - - -endef - diff --git a/development/makefiles/readme-webcomponents.mk b/development/makefiles/readme-webcomponents.mk deleted file mode 100644 index ed89adfc431b0ca5a3877873339631c4a131a1a6..0000000000000000000000000000000000000000 --- a/development/makefiles/readme-webcomponents.mk +++ /dev/null @@ -1,98 +0,0 @@ -############################################################################################# -############################################################################################# -## -## README -## -############################################################################################# -############################################################################################# - - -define README_FILE_CONTENT -# $(COMPONENT_NAME) - -$(COMPONENT_NAME) is a lightweight, robust and easy-to-use form library with modest ambitions. -The component easily integrates with your existing websites without taking over everything. - -One design target is to reach the shiny sun with as little JavaScript as possible. - -Monster was built with ES6 modules and uses [import](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/import) -and [export](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export). - -For some functions, you need additional [polyfills](#polyfill). - -## Documentation - -To check out docs and examples, visit [monsterjs.org/en/doc/$(COMPONENT_SLUG)/](https://monsterjs.org/en/doc/$(COMPONENT_SLUG)/). - -## Installation - -`npm install @schukai/component-$(COMPONENT_SLUG)`, `yarn install @schukai/component-$(COMPONENT_SLUG)` or `pnpm install @schukai/component-$(COMPONENT_SLUG)` - -## Usage - -A simple example of the use of functionality from $(COMPONENT_NAME). We create a small file `index.mjs`. -The `m` in `.mjs` stands for module. In the example we want to make substitutions in a string. - -```js -// example -``` - -To integrate this function into a website it is recommended to use a bundler like [esbuild](https://esbuild.github.io/). - -```sh -esbuild index.mjs --outfile dist.js -``` - -We can now integrate that into our website. - -```html -<!DOCTYPE html> -<html lang="en"> -<head> - <meta charset="UTF-8"> - <title>$(COMPONENT_NAME)</title> - <script src="dist.js"></script> -</head> -<body> -``` - -Voila! - - -### Polyfill - -We do try to work around some browser bugs, but on the whole we don't use polyfills and feature detection. - -However, many functions can be mapped via [polyfill.io](https://polyfill.io/) and thus the compatibility can be increased. - -```js -<script id="polyfill" src="https://polyfill.io/v3/polyfill.min.js?..." - crossorigin="anonymous" - referrerpolicy="no-referrer"></script> -``` - -## Questions - -For questions and commercial support, please contact [schukai GmbH](https://www.schukai.com/). -The issue list of this repo is exclusively for bug reports and feature requests. - -## Issues - -Please make sure to read the Issue Reporting Checklist before opening an -issue. Issues not conforming to the guidelines may be closed immediately. - -## License - -$(COPYRIGHT_TEXT) - -$(COPYRIGHT_URL) - -You can also purchase a commercial license. - -## Changelog - -Detailed changes for each release are documented in -the [CHANGELOG](https://gitlab.schukai.com/oss/libraries/javascript/web-components/$(COMPONENT_SLUG)). - -endef - diff --git a/development/makefiles/reqman.mk b/development/makefiles/reqman.mk deleted file mode 100644 index 64f4e1ab165dd831659cd207b5c8935f52d31f71..0000000000000000000000000000000000000000 --- a/development/makefiles/reqman.mk +++ /dev/null @@ -1,10 +0,0 @@ -############################################################################################# -############################################################################################# -## -## REQMAN -## -############################################################################################# -############################################################################################# - - -REQMAN_BIN ?= $(VENDOR_PATH)reqman diff --git a/development/makefiles/s3.mk b/development/makefiles/s3.mk deleted file mode 100644 index 9569d7e30471646060973003577880fdbc6fe560..0000000000000000000000000000000000000000 --- a/development/makefiles/s3.mk +++ /dev/null @@ -1,14 +0,0 @@ -############################################################################################# -############################################################################################# -## -## AMAZON S3 -## -############################################################################################# -############################################################################################# - -# path and binaries -AWS ?= aws -EXECUTABLES = $(EXECUTABLES:-) $(AWS) - -## Set AWS profile -AWS_PROFILE ?= schukai diff --git a/development/makefiles/target-add-licenses.mk b/development/makefiles/target-add-licenses.mk deleted file mode 100644 index 4750f2180582c45de35b7301d20fb14cdcdf8a1d..0000000000000000000000000000000000000000 --- a/development/makefiles/target-add-licenses.mk +++ /dev/null @@ -1,28 +0,0 @@ -############################################################################################# -############################################################################################# -## -## ADD SPDX LICENSES -## -## For commercial projects, it is not necessary to add the SPDX license identifier. -## The license header in each file is only for open-source projects, for example under -## the AGPL 3.0 license. -## -############################################################################################# -############################################################################################# - -ifeq ($(ADDLICENSE_BIN),) - $(error "addlicense is not installed. Please check your makefile and include the licenses.mk") -endif - -.PHONY: add-licenses -## Add license headers to all go files -add-licenses: - $(ECHOMARKER) "Add license headers to all sourche files" -ifeq ($(LICENSE_FILE_PATTERN),) - $(error "LICENSE_FILE_PATTERN is not set. Please check your makefile and include the licenses.mk") -endif - -ifndef SPDX_LICENSE_ID - $(error "SPDX_LICENSE_ID is not defined. Please check your makefile and include the licenses.mk") -endif - $(QUIET) $(ADDLICENSE_BIN) -c "$(COPYRIGHT_OWNER)" -s -l "$(SPDX_LICENSE_ID)" $(LICENSE_FILE_PATTERN) \ No newline at end of file diff --git a/development/makefiles/target-blackbox.mk b/development/makefiles/target-blackbox.mk deleted file mode 100644 index 2c8369dcd683cf83987ba263e3b5d564fbad81fa..0000000000000000000000000000000000000000 --- a/development/makefiles/target-blackbox.mk +++ /dev/null @@ -1,85 +0,0 @@ -############################################################################################# -############################################################################################# -## -## BLACKBOX -## -############################################################################################# -############################################################################################# - -ifndef BLACKBOX_DOCKERFILE - $(error $(ERRORMARKER) BLACKBOX_DOCKERFILE is not defined, check your Makefile if blackbox.mk is included) -endif - -ifndef BLACKBOX_RUN_SCRIPT - $(error $(ERRORMARKER) BLACKBOX_RUN_SCRIPT is not defined, check your Makefile if blackbox.mk is included) -endif - -export BLACKBOX_DOCKERFILE -export BLACKBOX_RUN_SCRIPT - -$(BLACKBOX_BUILD_DIR): - $(QUIET) $(MKDIR) -p $(BLACKBOX_BUILD_DIR) - -$(BLACKBOX_BUILD_DIR)/Dockerfile: $(BLACKBOX_BUILD_DIR) - $(QUIET) $(ECHO) "$$BLACKBOX_DOCKERFILE" > $@ - -$(BLACKBOX_BUILD_DIR)/filesystem: - $(QUIET) $(MKDIR) -p $(BLACKBOX_BUILD_DIR)/filesystem - -$(BLACKBOX_BUILD_DIR)/filesystem/bin: - $(QUIET) $(MKDIR) -p $(BLACKBOX_BUILD_DIR)/filesystem/bin - -$(BLACKBOX_BUILD_DIR)/filesystem/bin/run-blackbox.sh: $(BLACKBOX_BUILD_DIR)/filesystem/bin - $(QUIET) $(ECHO) "$$BLACKBOX_RUN_SCRIPT" > $@ - $(QUIET) $(CHMOD) u+x $@ - -.PHONY: blackbox-build-image -## build blackbox image -blackbox-build-image: $(BLACKBOX_BUILD_DIR)/Dockerfile $(BLACKBOX_BUILD_DIR)/filesystem/bin/run-blackbox.sh - $(ECHOMARKER) "build blackbox image" - $(QUIET) docker build --build-arg UID=$(shell id -u) \ - --build-arg GID=$(shell id -g) \ - --build-arg UNAME=$(shell id -un) \ - -t $(BLACKBOX_IMAGE) $(BLACKBOX_BUILD_DIR) - -.PHONY: blackbox-open -## open credential with blackbox -blackbox-open: -ifeq ($(shell docker images -q ${BLACKBOX_IMAGE} 2> /dev/null),) - $(QUIET) $(MAKE) blackbox-build-image -endif - $(ECHOMARKER) "open credential with blackbox" - $(QUIET) docker run --user $(shell id -u):$(shell id -g) \ - --rm -it \ - -v $(BLACKBOX_ROOT_DIR):/repos \ - -v $(BLACKBOX_GPG_PATH):/home/$(shell id -un)/.gnupg \ - $(BLACKBOX_IMAGE) open - -.PHONY: blackbox-close -## close credential with blackbox -blackbox-close: -ifeq ($(shell docker images -q ${BLACKBOX_IMAGE} 2> /dev/null),) - $(QUIET) $(MAKE) blackbox-build-image -endif - $(ECHOMARKER) "open credential with blackbox" - $(QUIET) docker run --user $(shell id -u):$(shell id -g) \ - --rm -it \ - -v $(BLACKBOX_ROOT_DIR):/repos \ - -v $(BLACKBOX_GPG_PATH):/home/$(shell id -un)/.gnupg \ - $(BLACKBOX_IMAGE) close - -.PHONY: blackbox-run -## run credential with blackbox -blackbox-run: -ifeq ($(shell docker images -q ${BLACKBOX_IMAGE} 2> /dev/null),) - $(QUIET) $(MAKE) blackbox-build-image -endif - $(ECHOMARKER) "open credential with blackbox" - $(QUIET) docker run --user $(shell id -u):$(shell id -g) \ - --rm -it \ - -v $(BLACKBOX_ROOT_DIR):/repos \ - -v $(BLACKBOX_GPG_PATH):/home/$(shell id -un)/.gnupg \ - $(BLACKBOX_IMAGE) run - - - diff --git a/development/makefiles/target-bob.mk b/development/makefiles/target-bob.mk deleted file mode 100644 index 072890b7568ecaeec23f11ebcd93a9cd00fff068..0000000000000000000000000000000000000000 --- a/development/makefiles/target-bob.mk +++ /dev/null @@ -1,70 +0,0 @@ -############################################################################################# -############################################################################################# -## -## SERVER BOB -## -############################################################################################# -############################################################################################# - -ifeq ($(BOB_BIN),) - $(error $(ERRORMARKER) Bob is not defined, check your Makefile if bob.mk is included) -endif - -ifndef BOB_HTML_TEMPLATES_PATH - $(error $(ERRORMARKER) BOB_HTML_TEMPLATES_PATH is not defined, check your Makefile if bob.mk is included) -endif - -ifndef BOB_DIST_PATH - $(error $(ERRORMARKER) BOB_DIST_PATH is not defined, check your Makefile if bob.mk is included) -endif - -ifndef SOURCE_PATH - $(error $(ERRORMARKER) SOURCE_PATH is not defined, check your Makefile if bob.mk is included) -endif - - -$(BOB_BIN): - $(QUIET) $(MKDIR) -p $(VENDOR_PATH) - $(QUIET) $(WGET) -O $(BOB_BIN) http://download.schukai.com/tools/bob/bob-$(shell uname -s | tr [:upper:] [:lower:])-$(shell echo `uname -m | sed s/aarch64/arm64/ | sed s/x86_64/amd64/`) - $(QUIET) $(CHMOD) u+x $(BOB_BIN) - -.PHONY: sync-pages -## Sync structure of pages -sync-pages: $(BOB_BIN) -ifeq ($(BOB_SYNC_CONFIG),) - $(ECHOMARKER) "BOB_SYNC_CONFIG is not set, check your Makefile if the variable is set" -endif - $(ECHOMARKER) "Sync structure of pages" - $(QUIET) $(BOB_BIN) html sync --specification $(BOB_SYNC_CONFIG) - -$(BOB_HTML_TEMPLATES_PATH): - $(ECHOMARKER) "Create template directory for bob" - $(QUIET) $(MKDIR) -p $(BOB_HTML_TEMPLATES_PATH) - -$(BOB_DIST_PATH): - $(ECHOMARKER) "Create dist directory for bob" - $(QUIET) $(MKDIR) -p $(BOB_DIST_PATH) - -.PHONY: generate-html -## Build the project with Bob -generate-html: $(BOB_BIN) $(BOB_HTML_TEMPLATES_PATH) $(BOB_DIST_PATH) - $(ECHOMARKER) "Generate html" - $(QUIET) $(BOB_BIN) html generate --input $(BOB_HTML_TEMPLATES_PATH) --output $(BOB_DIST_PATH) - -.PHONY: prepare-template -## Prepare template with Bob -prepare-template: $(BOB_BIN) $(BOB_HTML_TEMPLATES_PATH) - $(ECHOMARKER) "Generate templates" - $(QUIET) $(BOB_BIN) template prepare --input $(BOB_SOURCE_PATH) --output $(BOB_HTML_TEMPLATES_PATH) --data-file=$(BOB_DATA_FILE) - - - -.PHONY: init-template -## Init templates if not exist with Bob -init-template: $(BOB_BIN) $(BOB_HTML_TEMPLATES_PATH) - $(ECHOMARKER) "Generate templates" - $(QUIET) $(BOB_BIN) template prepare --input $(BOB_SOURCE_PATH) --output $(BOB_HTML_TEMPLATES_PATH) --data-file=en.yaml - - - - diff --git a/development/makefiles/target-caddy.mk b/development/makefiles/target-caddy.mk deleted file mode 100644 index 7258e3e180f6789c42d15d04f6fd70b5b9f10388..0000000000000000000000000000000000000000 --- a/development/makefiles/target-caddy.mk +++ /dev/null @@ -1,24 +0,0 @@ -############################################################################################# -############################################################################################# -## -## SERVER CADDY -## -############################################################################################# -############################################################################################# - -CADDY_VENDOR_PATH ?= $(VENDOR_PATH)caddy/ -CADDY_BIN ?= $(CADDY_VENDOR_PATH)caddy -CADDY_CONFIG ?= $(CADDY_VENDOR_PATH)caddy.conf -CADDY_PIDFILE ?= $(shell mktemp -d)/caddy.pid - -$(CADDY_BIN): - $(QUIET) $(MKDIR) -p $(CADDY_VENDOR_PATH) - $(QUIET) $(WGET) -O $(CADDY_BIN) "https://caddyserver.com/api/download?os=linux&arch=amd64&idempotency=75143981108035" - $(QUIET) $(CHMOD) u+x $(CADDY_BIN) - -.PHONY: run-caddy -## run caddy webserver -run-caddy: $(CADDY_BIN) - $(ECHOMARKER) "Run Caddy" - $(QUIET) $(CADDY_BIN) run -config $(CADDY_CONFIG) -pidfile $(CADDY_PIDFILE) -watch - diff --git a/development/makefiles/target-conan.mk b/development/makefiles/target-conan.mk deleted file mode 100644 index 1e42f1f4bdf341c6292655f5d09a6b623c9089c6..0000000000000000000000000000000000000000 --- a/development/makefiles/target-conan.mk +++ /dev/null @@ -1,17 +0,0 @@ -############################################################################################# -############################################################################################# -## -## SERVER CONAN -## -############################################################################################# -############################################################################################# - -ifeq ($(CONAN_BIN),) - $(error $(ERRORMARKER) Conan is not defined, check your Makefile if conan.mk is included) -endif - -.PHONY: run-conan -## run conan webserver -run-conan: $(CONAN_BIN) $(CONAN_CONFIG) - $(ECHOMARKER) "Run Conan" - $(QUIET) $(CONAN_BIN) server serve --config $(CONAN_CONFIG) diff --git a/development/makefiles/target-deploy-tool.mk b/development/makefiles/target-deploy-tool.mk deleted file mode 100644 index e47b8995407279b2184e50a1af9f77fa9a018632..0000000000000000000000000000000000000000 --- a/development/makefiles/target-deploy-tool.mk +++ /dev/null @@ -1,23 +0,0 @@ -############################################################################################# -############################################################################################# -## -## DEPLOY TOOLS -## -############################################################################################# -############################################################################################# - - -UPLOAD_TOOL_URL ?= s3://download.schukai.com/tools/$(COMPONENT_SLUG)/ - -.PHONY: deploy -## compile and deploy to S3 -deploy: compile - $(QUIET) AWS_PROFILE=$(AWS_PROFILE) find $(BUILD_PATH) -iname $(COMPONENT_SLUG)-* -exec $(AWS) s3 cp {} $(UPLOAD_TOOL_URL) \; - -.PHONY: overview-to-s3 -## overview-to-s3 -overview-to-s3: - $(ECHOMARKER) "Deploy to aws" - $(QUIET) AWS_PROFILE=$(AWS_PROFILE) $(AWS) s3 cp $(WEB_PATH)/index.html $(UPLOAD_TOOL_URL) - $(QUIET) AWS_PROFILE=$(AWS_PROFILE) $(AWS) s3 cp $(WEB_PATH)/index.css $(UPLOAD_TOOL_URL) - $(QUIET) AWS_PROFILE=$(AWS_PROFILE) $(AWS) s3 cp $(WEB_PATH)/index.js $(UPLOAD_TOOL_URL) diff --git a/development/makefiles/target-docman.mk b/development/makefiles/target-docman.mk deleted file mode 100644 index 2c8424b021d89735576befbc4016b647b8c84f26..0000000000000000000000000000000000000000 --- a/development/makefiles/target-docman.mk +++ /dev/null @@ -1,36 +0,0 @@ -############################################################################################# -############################################################################################# -## -## DOCMAN-TARGETS -## -############################################################################################# -############################################################################################# - -ifeq ($(DOCMAN_BIN),) - $(error "$(DOCMAN_BIN) is not installed. Please check your makefile and include the docman.mk") -endif - -$(DOCMAN_HTML_ARTEFACT): $(DOCMAN_BIN) $(DOCMAN_SOURCE) - $(ECHOMARKER) "Build HTML Documentation" - $(QUIET) $(DOCMAN_BIN) document html --config $(DOCMAN_CONFIG_PATH) - -$(DOCMAN_PDF_ARTEFACT): $(DOCMAN_BIN) $(DOCMAN_SOURCE) - $(ECHOMARKER) "Build PDF Documentation" - $(QUIET) $(DOCMAN_BIN) document pdf --config $(DOCMAN_CONFIG_PATH) - -.PHONY: build-doc-pdf -## creating the documentation in pdf format -build-doc-pdf: $(DOCMAN_PDF_ARTEFACT) - -.PHONY: build-doc-html -## creating the documentation in html format -build-doc-html: $(DOCMAN_HTML_ARTEFACT) - -.PHONY: build-doc -## creating the documentation in pdf and html format -build-doc: build-doc-pdf build-doc-html - - - - - diff --git a/development/makefiles/target-git.mk b/development/makefiles/target-git.mk deleted file mode 100644 index d4ac20d62ba4489b6ab175b615c2324b5674272b..0000000000000000000000000000000000000000 --- a/development/makefiles/target-git.mk +++ /dev/null @@ -1,58 +0,0 @@ -############################################################################################# -############################################################################################# -## -## GIT-TARGETS -## -############################################################################################# -############################################################################################# - -ifeq ($(GIT),) - $(error $(ERRORMARKER) Git is not defined, check your Makefile if git.mk is included) -endif - -## Current Branch-GIT_TAG -GIT_TAG := - - -## Git Commit GIT_MESSAGE for git-push -GIT_MESSAGE := current status - -.PHONY: git-branch -## create new branch (use GIT_TAG-Variable) -git-branch: - $(QUIET) export BRANCH="b$(GIT_TAG)/$(shell uuidgen --random)" ; \ - $(QUIET) $(GIT) checkout -b $${BRANCH} && \ - RESULT=$$($(GIT) push origin $$BRANCH 2>&1) && \ - RESULT2=$$($(GIT) branch --set-upstream-to=origin/$$BRANCH $$BRANCH) && \ - GITLABURL=$$(echo "$$RESULT" | tr '\n' '\#' | grep -o 'remote\:\s*https:\/\/gitlab\.schukai\.com[^ ]*' | cut -d " " -f2-9 | sed -e 's/^[ \t]*//') && \ - if $(OPENBROWSER) ; then google-chrome --profile-directory="Default" $$GITLABURL ; fi - -.PHONY: git-to-master -## git checkout master, fetch and merge -git-to-master: - $(QUIET) $(GIT) checkout master && $(GIT) fetch -pP && $(GIT) merge - -.PHONY: git-push-to-server -## git push changes to server -git-push-to-server: - $(QUIET) $(GIT) add -A - $(QUIET) $(GIT) commit -m"$(GIT_MESSAGE)" - $(QUIET) $(GIT) push - -.PHONY: git-push -## git create branch and push changes to server -git-push: git-branch git-push-to-server - -.PHONY: git-tag -## git create version tag -git-tag: - $(QUIET) $(GIT) tag -a "$(COMPONENT_VERSION)" -m "release $(COMPONENT_VERSION)" - -.PHONY: git-prune-remote -## removes your local remote tracking branches where the branch no longer exists on the remote -git-prune-remote: - $(QUIET) $(GIT) remote prune origin - -.PHONY: git-prune-local -## deletes local merged branches except the master branch -git-prune-local: - $(QUIET) $(GIT) branch --merged master | grep -v '^[ *]*master$$' | xargs git branch -d \ No newline at end of file diff --git a/development/makefiles/target-go-build.mk b/development/makefiles/target-go-build.mk deleted file mode 100644 index c21e4a4d07335f8bd26d610e4fede6aba5780552..0000000000000000000000000000000000000000 --- a/development/makefiles/target-go-build.mk +++ /dev/null @@ -1,58 +0,0 @@ -############################################################################################# -############################################################################################# -## -## BUILD GO -## -############################################################################################# -############################################################################################# - -ifeq ($(GO),) - $(error $(ERRORMARKER) Go is not defined, check your Makefile if go.mk is included) -endif - -GO_RELEASE_PACKAGE_NAME ?= main - -.PHONY: compile -## Compiling for every OS and Platform -compile: next-patch-version - $(ECHOMARKER) "Compiling for every OS and Platform" - $(ECHO) "Version: $(PROJECT_VERSION)" - $(ECHO) "Build: $(PROJECT_BUILD_DATE)" - $(QUIET) $(DEVELOPMENT_SCRIPTS_PATH)/go-compile.sh $(SOURCE_PATH) $(BUILD_PATH) $(COMPONENT_SLUG) $(GO_RELEASE_PACKAGE_NAME) $(PROJECT_VERSION) $(PROJECT_BUILD_DATE) - - -.PHONY: go-lint -## Lint the files -go-lint: - $(QUIET) $(GOLINT) -set_exit_status ${PKG_LIST} - -.PHONY: go-test -## Run unittests -go-test: - $(QUIET) $(GO) test -short ${PKG_LIST} - -.PHONY: go-race -## Run data race detector -go-race: go-dep - $(QUIET) $(GO) test -race -short ${PKG_LIST} - -.PHONY: go-msan -## Run memory sanitizer -go-msan: go-dep - $(QUIET) $(GO) test -msan -short ${PKG_LIST} - -.PHONY: go-coverage -## Generate global code coverage report -go-coverage: - $(QUIET) $(DEVELOPMENT_SCRIPTS_PATH)/go-coverage.sh $(SOURCE_PATH) $(DEVELOPMENT_PATH)/report ; - -.PHONY: go-cover-html -## Generate global code coverage report in HTML -go-cover-html: - $(QUIET) $(DEVELOPMENT_SCRIPTS_PATH)/go-coverage.sh $(SOURCE_PATH) $(DEVELOPMENT_PATH)/report html; - -.PHONY: go-dep -## Get the dependencies -go-dep: - $(QUIET) cd $(SOURCE_PATH); $(GO) get -v -d ./... ; cd -; - diff --git a/development/makefiles/target-go-fetch-licenses.mk b/development/makefiles/target-go-fetch-licenses.mk deleted file mode 100644 index 057b31b2e50357a44d09be7c654a14081dd6a27f..0000000000000000000000000000000000000000 --- a/development/makefiles/target-go-fetch-licenses.mk +++ /dev/null @@ -1,36 +0,0 @@ -############################################################################################# -############################################################################################# -## -## GET LICENSES -## -############################################################################################# -############################################################################################# - -ifeq ($(GO),) - $(error $(ERRORMARKER) Go is not defined, check your Makefile if go.mk is included) -endif - -GO_MOD_FILE := $(SOURCE_PATH)go.mod -GO_LICENSES_BIN := $(shell command -v go-licenses) - - -ifeq ($(GO_LICENSES_BIN),) - $(shell $(GO) install github.com/google/go-licenses@latest) - GO_LICENSES_BIN := $(shell command -v go-licenses 2> /dev/null) - EXECUTABLES = $(EXECUTABLES:-) go-licenses; -endif - -ifeq ($(shell test -e $(GO_MOD_FILE) && echo -n yes),yes) - GO_CURRENT_MODULE := $(shell cat $(GO_MOD_FILE) | head -n1 | cut -d" " -f2) -endif - -.PHONY: go-fetch-licenses -## Fetch licenses for all modules -go-fetch-licenses: -ifeq ($(GO_CURRENT_MODULE),) - $(QUIET) $(ECHOERRORMARKER) "no go.mod file found, skipping fetching licenses" -else - $(ECHOMARKER) "Fetch licenses" - $(QUIET) cd $(SOURCE_PATH); $(GO_LICENSES_BIN) save $(GO_CURRENT_MODULE) $(PKG_LIST) --force --save_path $(DOCUMENTATION_PATH)licenses/ ; cd - -endif - diff --git a/development/makefiles/target-help.mk b/development/makefiles/target-help.mk deleted file mode 100644 index abe1f924cbd4df3118ec7fd4ff02270d60e68f5d..0000000000000000000000000000000000000000 --- a/development/makefiles/target-help.mk +++ /dev/null @@ -1,46 +0,0 @@ -############################################################################################# -############################################################################################# -## -## HELP-TARGETS -## -############################################################################################# -############################################################################################# - -# @see .PHONY https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html#Phony-Targets -.DEFAULT_GOAL := help - -.PHONY: print -## Print Path -print: - $(ECHO) "THIS_MAKEFILE: $(THIS_MAKEFILE)" - $(ECHO) "THIS_MAKEFILE_PATH: $(THIS_MAKEFILE_PATH)" - $(ECHO) "PROJECT_ROOT: $(PROJECT_ROOT)" - -# Add a comment to the public targets so that it appears -# in this help Use two # characters for a help comment -.PHONY: help -help: - @printf "${COMMENT}Usage:${RESET}\n" - @printf " make [target] [arg=\"val\"...]\n\n" - @printf "${COMMENT}Available targets:${RESET}\n" - @awk '/^[a-zA-Z\-\\_0-9\.@]+:/ { \ - helpMessage = match(lastLine, /^## (.*)/); \ - if (helpMessage) { \ - helpCommand = substr($$1, 0, index($$1, ":")); \ - helpMessage = substr(lastLine, RSTART + 3, RLENGTH); \ - printf " ${INFO}%-22s${RESET} %s\n", helpCommand, helpMessage; \ - } \ - } \ - { lastLine = $$0 }' $(MAKEFILE_LIST) - @printf "\n${COMMENT}Available arguments:${RESET}\n\n" - @awk '/^(([a-zA-Z\-\\_0-9\.@]+)\s[?:]?=)/ { \ - helpMessage = match(lastLine, /^## (.*)/); \ - if (helpMessage) { \ - helpMessage = substr(lastLine, RSTART + 3, RLENGTH); \ - printf " ${INFO}%-22s${RESET} %s (Default: %s)\n", $$1, helpMessage, $$3; \ - } \ - } \ - { lastLine = $$0 }' $(MAKEFILE_LIST) - - - diff --git a/development/makefiles/target-init-go-lib.mk b/development/makefiles/target-init-go-lib.mk deleted file mode 100644 index 69c165e41024c52086971958f142bdf1df92dec7..0000000000000000000000000000000000000000 --- a/development/makefiles/target-init-go-lib.mk +++ /dev/null @@ -1,49 +0,0 @@ -############################################################################################# -############################################################################################# -## -## INIT-STANDARD -## -############################################################################################# -############################################################################################# - -# @see .PHONY https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html#Phony-Targets -.PHONY: init-go-lib - -# The default directories are defined in the -# directories-standard.mk file, but all other -# targets can define directories as well. - -$(PROJECT_DIRECTORIES): - $(foreach path,$(PROJECT_DIRECTORIES),\ - $(shell $(MKDIR) -p $(path))) - -## init go lib project -init-go-lib: $(PROJECT_DIRECTORIES) $(PROJECT_ROOT).gitignore $(PROJECT_ROOT)README.md $(LICENSE_PATH)LICENSE - $(ECHOMARKER) "Run init-go-lib" - $(ECHO) "Done" - -############################################################################################# -############################################################################################# -## -## LICENSE -## -############################################################################################# -############################################################################################# - -export LICENSE_FILE_CONTENT -$(LICENSE_PATH)LICENSE: - $(QUIET) $(ECHO) "$$LICENSE_FILE_CONTENT" >> $@ - -############################################################################################# -############################################################################################# -## -## README -## -############################################################################################# -############################################################################################# - -export README_FILE_CONTENT -$(PROJECT_ROOT)README.md: - $(QUIET) $(ECHO) "$$README_FILE_CONTENT" >> $@ - - diff --git a/development/makefiles/target-init-go-utilities.mk b/development/makefiles/target-init-go-utilities.mk deleted file mode 100644 index 5efeb0e55ff347ad3cfe1a003503e29d9357e1b6..0000000000000000000000000000000000000000 --- a/development/makefiles/target-init-go-utilities.mk +++ /dev/null @@ -1,48 +0,0 @@ -############################################################################################# -############################################################################################# -## -## INIT-STANDARD -## -############################################################################################# -############################################################################################# - -# @see .PHONY https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html#Phony-Targets -.PHONY: init-go-utilities - -# The default directories are defined in the -# directories-standard.mk file, but all other -# targets can define directories as well. - -$(PROJECT_DIRECTORIES): - $(foreach path,$(PROJECT_DIRECTORIES), $(shell $(MKDIR) -p $(path))) - -## init go utilities project -init-go-utilities: $(PROJECT_DIRECTORIES) $(PROJECT_ROOT).gitignore $(PROJECT_ROOT)README.md $(LICENSE_PATH)LICENSE - $(ECHOMARKER) "Run init-go-utilities" - $(ECHO) "Done" - -############################################################################################# -############################################################################################# -## -## LICENSE -## -############################################################################################# -############################################################################################# - -export LICENSE_FILE_CONTENT -$(LICENSE_PATH)LICENSE: - $(QUIET) $(ECHO) "$$LICENSE_FILE_CONTENT" >> $@ - -############################################################################################# -############################################################################################# -## -## README -## -############################################################################################# -############################################################################################# - -export README_FILE_CONTENT -$(PROJECT_ROOT)README.md: - $(QUIET) $(ECHO) "$$README_FILE_CONTENT" >> $@ - - diff --git a/development/makefiles/target-init-platform-part.mk b/development/makefiles/target-init-platform-part.mk deleted file mode 100644 index 4b8a15b1fadba5eb6ebfc69a3264e35a04ac7e41..0000000000000000000000000000000000000000 --- a/development/makefiles/target-init-platform-part.mk +++ /dev/null @@ -1,143 +0,0 @@ -############################################################################################# -############################################################################################# -## -## INIT-WEBCOMPONENTS -## -############################################################################################# -############################################################################################# - -# @see .PHONY https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html#Phony-Targets -.PHONY: init-platform-part - -# The default directories are defined in the -# directories-standard.mk file, but all other -# targets can define directories as well. - -$(PROJECT_DIRECTORIES): - $(foreach path,$(PROJECT_DIRECTORIES),\ - $(shell $(MKDIR) -p $(path))) - -## init standard project -init-platform-part: $(PROJECT_DIRECTORIES) $(PROJECT_ROOT).gitignore $(PROJECT_ROOT)package.json $(PROJECT_ROOT)README.md $(LICENSE_PATH)LICENSE - $(ECHOMARKER) "Run init-webapp" - $(ECHO) "Done" - -############################################################################################# -############################################################################################# -## -## LICENSE -## -############################################################################################# -############################################################################################# - -export LICENSE_FILE_CONTENT -$(LICENSE_PATH)LICENSE: - $(QUIET) $(ECHO) "$$LICENSE_FILE_CONTENT" >> $@ - - -############################################################################################# -############################################################################################# -## -## README -## -############################################################################################# -############################################################################################# - -export README_FILE_CONTENT -$(PROJECT_ROOT)README.md: - $(QUIET) $(ECHO) "$$README_FILE_CONTENT" >> $@ - -############################################################################################# -############################################################################################# -## -## BUILD PACKAGE JSON -## -############################################################################################# -############################################################################################# -define PLATFORM_PARTS_BUILD_PACKAGE_CONTENT -{ - "name": "@alvine/$(COMPONENT_SLUG)", - "version": "0.1.0", - "description": "$(COMPONENT_NAME)", - "repository": { - "type": "git", - "url": "https://gitlab.schukai.com/alvine/application/platform-apps/parts/$(COMPONENT_SLUG).git" - }, - "scripts": { - "build-and-publish": "script/build-and-publish.sh", - "semantic-release": "semantic-release", - "build": "vite --config ./vite.config.js build", - "preview": "vite --config ./vite.config.js preview", - "dev": "vite --config ./vite.config.js" - }, - "type": "module", - "author": "schukai GmbH", - "license": "see LICENSE file", - "dependencies": { - "@schukai/component-form": "^3.3.1", - "@schukai/component-notify": "^2.3.0", - "@schukai/component-state": "^2.3.0", - "@schukai/component-style": "^0.28.0", - "@schukai/monster": "^3.12.1" - }, - "devDependencies": { - "@peculiar/webcrypto": "^1.4.1", - "@semantic-release/changelog": "^6.0.2", - "@semantic-release/exec": "^6.0.3", - "@semantic-release/git": "^10.0.1", - "@semantic-release/gitlab": "^10.1.4", - "@semantic-release/npm": "^9.0.2", - "@vitejs/plugin-basic-ssl": "^1.0.1", - "autoprefixer": "^10.4.13", - "btoa": "^1.2.1", - "c8": "^7.12.0", - "chai": "^4.3.7", - "chai-dom": "^1.11.0", - "clean-jsdoc-theme": "^4.2.6", - "cli-real-favicon": "^0.0.8", - "create-polyfill-service-url": "^2.2.6", - "crypt": "^0.0.2", - "cssnano": "^5.1.14", - "esbuild": "^0.17.8", - "flow-bin": "^0.199.1", - "fs": "^0.0.1-security", - "glob": "^8.1.0", - "graphviz": "^0.0.9", - "jsdoc": "^4.0.0", - "jsdoc-external-example": "github:volker-schukai/jsdoc-external-example", - "jsdom": "^21.1.0", - "jsdom-global": "^3.0.2", - "mocha": "^10.2.0", - "npm-check-updates": "^16.7.4", - "postcss": "^8.4.21", - "postcss-color-mod-function": "^3.0.3", - "postcss-fluid": "^1.4.2", - "postcss-for": "^2.1.1", - "postcss-import": "^15.1.0", - "postcss-mixins": "^9.0.4", - "postcss-nesting": "^11.2.0", - "postcss-normalize": "^10.0.1", - "postcss-responsive-type": "^1.0.0", - "postcss-strip-units": "^2.0.1", - "process": "^0.11.10", - "semantic-release": "^20.1.0", - "sinon": "^15.0.1", - "svgo": "^3.0.2", - "url": "^0.11.0", - "url-exist": "3.0.1", - "util": "^0.12.5", - "vite": "^4.1.1", - "vite-plugin-banner": "^0.7.0", - "vite-plugin-list-directory-contents": "^1.4.5", - "vite-plugin-minify": "^1.5.2", - "vite-plugin-mkcert": "^1.13.0", - "vite-plugin-mpa": "^1.1.4" - } -} -endef - -export PLATFORM_PARTS_BUILD_PACKAGE_CONTENT -$(PROJECT_ROOT)package.json: - $(QUIET) $(ECHO) "$$PLATFORM_PARTS_BUILD_PACKAGE_CONTENT" >> $@ - -###### diff --git a/development/makefiles/target-init-standard.mk b/development/makefiles/target-init-standard.mk deleted file mode 100644 index 8679e58ea337fe4a06301ac784755a62263eb361..0000000000000000000000000000000000000000 --- a/development/makefiles/target-init-standard.mk +++ /dev/null @@ -1,49 +0,0 @@ -############################################################################################# -############################################################################################# -## -## INIT-STANDARD -## -############################################################################################# -############################################################################################# - -# @see .PHONY https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html#Phony-Targets -.PHONY: init-standard - -# The default directories are defined in the -# directories-standard.mk file, but all other -# targets can define directories as well. - -$(PROJECT_DIRECTORIES): - $(foreach path,$(PROJECT_DIRECTORIES),\ - $(shell $(MKDIR) -p $(path))) - -## init standard project -init-standard: $(PROJECT_DIRECTORIES) $(PROJECT_ROOT).gitignore $(PROJECT_ROOT)README.md $(LICENSE_PATH)LICENSE - $(ECHOMARKER) "Run init-standard" - $(ECHO) "Done" - -############################################################################################# -############################################################################################# -## -## LICENSE -## -############################################################################################# -############################################################################################# - -export LICENSE_FILE_CONTENT -$(LICENSE_PATH)LICENSE: - $(QUIET) $(ECHO) "$$LICENSE_FILE_CONTENT" >> $@ - -############################################################################################# -############################################################################################# -## -## README -## -############################################################################################# -############################################################################################# - -export README_FILE_CONTENT -$(PROJECT_ROOT)README.md: - $(QUIET) $(ECHO) "$$README_FILE_CONTENT" >> $@ - - diff --git a/development/makefiles/target-init-webcomponent.mk b/development/makefiles/target-init-webcomponent.mk deleted file mode 100644 index 6460767f247feeb21a3a081f45be40615d1d0ce7..0000000000000000000000000000000000000000 --- a/development/makefiles/target-init-webcomponent.mk +++ /dev/null @@ -1,193 +0,0 @@ -############################################################################################# -############################################################################################# -## -## INIT-WEBCOMPONENTS -## -############################################################################################# -############################################################################################# - -# @see .PHONY https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html#Phony-Targets -.PHONY: init-webcomponent - -# The default directories are defined in the -# directories-standard.mk file, but all other -# targets can define directories as well. - -$(PROJECT_DIRECTORIES): - $(foreach path,$(PROJECT_DIRECTORIES),\ - $(shell $(MKDIR) -p $(path))) - -## init standard project -init-webcomponent: $(PROJECT_DIRECTORIES) $(PROJECT_ROOT).gitignore $(DEVELOPMENT_PATH)package.json $(APPLICATION_PATH)package.json $(PROJECT_ROOT)README.md $(LICENSE_PATH)LICENSE $(APPLICATION_PATH)LICENSE - $(ECHOMARKER) "Run init-webcomponent" - $(ECHO) "Done" - -############################################################################################# -############################################################################################# -## -## LICENSE -## -############################################################################################# -############################################################################################# - -export LICENSE_FILE_CONTENT -$(LICENSE_PATH)LICENSE: - $(QUIET) $(ECHO) "$$LICENSE_FILE_CONTENT" >> $@ - -export LICENSE_AGPL_FILE_CONTENT -$(APPLICATION_PATH)LICENSE: - $(QUIET) $(ECHO) "$$LICENSE_AGPL_FILE_CONTENT" >> $@ - -############################################################################################# -############################################################################################# -## -## README -## -############################################################################################# -############################################################################################# - -export README_FILE_CONTENT -$(PROJECT_ROOT)README.md: - $(QUIET) $(ECHO) "$$README_FILE_CONTENT" >> $@ - - -############################################################################################# -############################################################################################# -## -## PACKAGE JSON -## -############################################################################################# -############################################################################################# -define WEBCOMPONENTS_PACKAGE_CONTENT -{ - "name": "component-$(COMPONENT_SLUG)", - "version": "0.1.0", - "description": "component $(COMPONENT_NAME)", - "repository": { - "type": "git", - "url": "https://gitlab.schukai.com/oss/libraries/javascript/web-components/$(COMPONENT_SLUG).git" - }, - "keywords": [ - "web", - "dom", - "css", - "mobile-first", - "app", - "front-end", - "ui", - "form", - "templates", - "schukai", - "component", - "web-component", - "monster" - ], - "dependencies": { - "@popperjs/core": "^2.11.6", - "@schukai/component-style": "^0.27.1", - "@schukai/monster": "^3.10.1" - }, - "main": "source/component.mjs", - "module": "source/component.mjs", - "type": "module", - "homepage": "https://monsterjs.org/", - "repository": { - "type": "git", - "url": "https://gitlab.schukai.com/oss/libraries/javascript/web-components/$(COMPONENT_SLUG).git" - }, - "author": "schukai GmbH", - "license": "AGPL 3.0" -} -endef - -export WEBCOMPONENTS_PACKAGE_CONTENT -$(APPLICATION_PATH)package.json: - $(QUIET) $(ECHO) "$$WEBCOMPONENTS_PACKAGE_CONTENT" >> $@ - -############################################################################################# -############################################################################################# -## -## BUILD PACKAGE JSON -## -############################################################################################# -############################################################################################# -define WEBCOMPONENTS_BUILD_PACKAGE_CONTENT -{ - "name": "component-$(COMPONENT_SLUG)", - "version": "0.1.0", - "description": "component $(COMPONENT_NAME)", - "repository": { - "type": "git", - "url": "https://gitlab.schukai.com/oss/libraries/javascript/web-components/$(COMPONENT_SLUG).git" - }, - "scripts": { - "test": "npx mocha --recursive test/cases/", - "web-test": "script/web-test.sh", - "publish": "script/release-and-publish.sh", - "build-doc": "script/build-doc.sh", - "build-style": "node script/build-stylesheets.cjs ." - }, - "type": "module", - "author": "schukai GmbH", - "license": "see LICENSE file", - "dependencies": { - "@popperjs/core": "^2.11.6", - "@schukai/component-style": "^0.27.1", - "@schukai/monster": "^3.10.1" - }, - "devDependencies": { - "@oss/web-components-build-tools": "^1.2.8", - "@peculiar/webcrypto": "^1.4.1", - "autoprefixer": "^10.4.13", - "browserslist": "^4.21.5", - "btoa": "^1.2.1", - "c8": "^7.12.0", - "chai": "^4.3.7", - "chai-dom": "^1.11.0", - "clean-jsdoc-theme": "^4.2.3", - "create-polyfill-service-url": "^2.2.6", - "crypt": "^0.0.2", - "cssnano": "^5.1.14", - "esbuild": "^0.17.5", - "flow-bin": "^0.199.1", - "fs": "0.0.1-security", - "glob": "^8.1.0", - "graphviz": "^0.0.9", - "jsdoc": "^4.0.0", - "jsdoc-external-example": "github:volker-schukai/jsdoc-external-example", - "jsdoc-plantuml": "^1.0.2", - "jsdom": "^21.1.0", - "jsdom-global": "^3.0.2", - "mocha": "^10.2.0", - "node-plantuml": "^0.9.0", - "postcss": "^8.4.21", - "postcss-fluid": "^1.4.2", - "postcss-for": "^2.1.1", - "postcss-import": "^15.1.0", - "postcss-load-config": "^4.0.1", - "postcss-mixins": "^9.0.4", - "postcss-nested": "^6.0.0", - "postcss-nesting": "^11.1.0", - "postcss-normalize": "^10.0.1", - "postcss-responsive-type": "^1.0.0", - "postcss-rtlcss": "^4.0.1", - "postcss-strip-units": "^2.0.1", - "rome": "^11.0.0", - "sinon": "^15.0.1", - "url": "^0.11.0", - "url-exist": "3.0.1", - "util": "^0.12.5", - "vite": "^4.1.1", - "vite-plugin-banner": "^0.7.0", - "vite-plugin-list-directory-contents": "^1.4.5", - "vite-plugin-minify": "^1.5.2", - "vite-plugin-mkcert": "^1.12.0" - } -} -endef - -export WEBCOMPONENTS_BUILD_PACKAGE_CONTENT -$(DEVELOPMENT_PATH)package.json: - $(QUIET) $(ECHO) "$$WEBCOMPONENTS_BUILD_PACKAGE_CONTENT" >> $@ - -###### diff --git a/development/makefiles/target-jekyll.mk b/development/makefiles/target-jekyll.mk deleted file mode 100644 index 8890741ae7d1b86664dfb1f264c34db88db10487..0000000000000000000000000000000000000000 --- a/development/makefiles/target-jekyll.mk +++ /dev/null @@ -1,39 +0,0 @@ -############################################################################################# -############################################################################################# -## -## JEKYLL-TARGETS -## -############################################################################################# -############################################################################################# - - -JEKYLL_VERSION := snapshot -JEKYLL_BIN := $(ALVINE_VENDOR_PATH)jekyll-$(JEKYLL_VERSION).phar -JEKYLL_PUBKEY := $(JEKYLL_BIN).pubkey - -$(JEKYLL_PUBKEY): - $(MKDIR) -p $(ALVINE_VENDOR_PATH) - $(WGET) -O $(JEKYLL_PUBKEY) http://download.alvine.io/phar/jekyll-$(JEKYLL_VERSION).phar.pubkey - -$(JEKYLL_BIN): $(JEKYLL_PUBKEY) - $(MKDIR) -p $(ALVINE_VENDOR_PATH) - $(WGET) -O $(JEKYLL_BIN) http://download.alvine.io/phar/jekyll-$(JEKYLL_VERSION).phar - $(CHMOD) u+x $(JEKYLL_BIN) - -.PHONY: run-jekyll -## run jekyll -run-jekyll: init $(JEKYLL_BIN) $(JEKYLL_PUBKEY) $(TEMP_PATH)jekyll.lock - $(ECHOMARKER) "Jekyll finished" - -.PHONY: run-jekyll-force -## run jekyll (-f) -run-jekyll-force: init $(JEKYLL_BIN) $(JEKYLL_PUBKEY) - $(RM) $(TEMP_PATH)jekyll.lock - $(MAKE) run-jekyll - $(ECHOMARKER) "Jekyll finished" - -$(TEMP_PATH)jekyll.lock: $(THIS_DIR).jekyll - $(ECHOMARKER) "Run Jekyll" - $(JEKYLL_BIN) fetch --force - $(JEKYLL_BIN) update - touch $(TEMP_PATH)jekyll.lock \ No newline at end of file diff --git a/development/makefiles/target-jsdoc-build.mk b/development/makefiles/target-jsdoc-build.mk deleted file mode 100644 index 2581d8535ce2a3dc424fd00c84f890a62b6f07ab..0000000000000000000000000000000000000000 --- a/development/makefiles/target-jsdoc-build.mk +++ /dev/null @@ -1,37 +0,0 @@ -############################################################################################# -############################################################################################# -## -## JSDOC-TARGETS -## -############################################################################################# -############################################################################################# - -ifndef DOCUMENTATION_S3_PATH - $(error $(ERRORMARKER) DOCUMENTATION_S3_PATH is not defined, check your Makefile if jsdoc.mk is included) -endif - -ifndef FIXBROKENPLANTUML - $(error $(ERRORMARKER) FIXBROKENPLANTUML is not defined, check your Makefile if jsdoc.mk is included) -endif - -.PHONY: jsdoc-build -## generate js api docs -jsdoc-build: $(DOCUMENTATION_CONFIG_PATH)jsdoc.json $(FIXBROKENPLANTUML).fixed - $(ECHOMARKER) "create api doc" - $(QUIET) $(NPM) --prefix $(NODE_ROOT_DIR) run build-doc - - -$(FIXBROKENPLANTUML).fixed: - $(ECHOMARKER) "fix broken plantuml" - $(QUIET) chmod u+x $(FIXBROKENPLANTUML) - $(QUIET) $(NODE) $(FIXBROKENPLANTUML) - $(QUIET) $(TOUCH) $(FIXBROKENPLANTUML).fixed - - - -.PHONY: jsdoc-to-s3 -## transfer doc to s3 -jsdoc-to-s3: jsdoc-build - $(ECHOMARKER) "transfer doc to s3" - $(QUIET) $(AWS) s3 --recursive --only-show-errors cp $(BUILD_PATH)docs $(DOCUMENTATION_S3_PATH) - diff --git a/development/makefiles/target-minerva.mk b/development/makefiles/target-minerva.mk deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/development/makefiles/target-node-build.mk b/development/makefiles/target-node-build.mk deleted file mode 100644 index 529bc2255af928d5845b20f1cc57a369c19a02f1..0000000000000000000000000000000000000000 --- a/development/makefiles/target-node-build.mk +++ /dev/null @@ -1,32 +0,0 @@ -############################################################################################# -############################################################################################# -## -## BUILD NODE -## -############################################################################################# -############################################################################################# - -SPONGE ?= sponge - -EXECUTABLES = $(EXECUTABLES:-) $(SPONGE); - - -.PHONY: node-create-polyfill -## create polyfill.io url -node-create-polyfill: $(MJS_RELATIVE_SOURCE_FILES) $(NODE_PACKAGES) - $(ECHOMARKER) "create and replace polyfill" - $(QUIET) $(DEVELOPMENT_SCRIPTS_PATH)create-polyfill.sh $(MJS_RELATIVE_SOURCE_FILES) - - -.PHONY: node-build -## Build Node Components -node-build: $(NODE_MODULES_MODIFIED) $(NODE_PACKAGES) - $(ECHOMARKER) "Building Node Components" - $(ECHO) "Version: $(PROJECT_VERSION)" - $(ECHO) "Source Path: $(SOURCE_PATH)" - $(QUIET) $(JQ) '.version = "$(PROJECT_VERSION)"' $(PACKAGE_JSON) | $(SPONGE) $(PACKAGE_JSON) - $(QUIET) for p in $(NODE_PACKAGES); do $(JQ) '.version = "$(PROJECT_VERSION)"' $${p} | $(SPONGE) $${p}; done - $(QUIET) $(SCRIPTS_PATH)update-version.sh - $(QUIET) $(NPM) --prefix $(NODE_ROOT_DIR) run --if-present build - - diff --git a/development/makefiles/target-node-playground.mk b/development/makefiles/target-node-playground.mk deleted file mode 100644 index 9ad098c4d8e0a89706f49582eb0d6cfe85b607d3..0000000000000000000000000000000000000000 --- a/development/makefiles/target-node-playground.mk +++ /dev/null @@ -1,13 +0,0 @@ -############################################################################################# -############################################################################################# -## -## RUN PLAYGROUND -## -############################################################################################# -############################################################################################# - -.PHONY: node-run-playground -## run playground (vite) -node-run-playground: - $(ECHOMARKER) "run playground" - $(QUIET) cd $(DEVELOPMENT_PATH)playground; npx vite; diff --git a/development/makefiles/target-node-test.mk b/development/makefiles/target-node-test.mk deleted file mode 100644 index 0a03f40ac2fb4618807a45e02f5392bbd6256cba..0000000000000000000000000000000000000000 --- a/development/makefiles/target-node-test.mk +++ /dev/null @@ -1,20 +0,0 @@ -############################################################################################# -############################################################################################# -## -## BUILD NODE -## -############################################################################################# -############################################################################################# - -.PHONY: node-test -## Test JS Components -node-test: $(NODE_MODULES_MODIFIED) - $(ECHOMARKER) "Test Node Components" - $(QUIET) $(NPM) --prefix $(NODE_ROOT_DIR) run test - -.PHONY: node-web-test -## Test JS Components -node-web-test: $(NODE_MODULES_MODIFIED) - $(ECHOMARKER) "Test Node Components" - $(QUIET) $(NPM) --prefix $(NODE_ROOT_DIR) run web-test - diff --git a/development/makefiles/target-npm-publish.mk b/development/makefiles/target-npm-publish.mk deleted file mode 100644 index d7f8b391edbf1eecc59b624f479d238e2ad57ba8..0000000000000000000000000000000000000000 --- a/development/makefiles/target-npm-publish.mk +++ /dev/null @@ -1,35 +0,0 @@ -############################################################################################# -############################################################################################# -## -## NPM -## -############################################################################################# -############################################################################################# - -.PHONY: npm-publish-major -## release major version of package -npm-publish-major: - $(ECHOMARKER) "release major version" - $(QUIET) $(MAKE) tag-major-version - $(QUIET) $(MAKE) node-build - $(QUIET) $(MAKE) node-test - $(QUIET) $(NPM) --prefix $(NODE_ROOT_DIR) run publish - -.PHONY: npm-publish-minor -## release minor version of package -npm-publish-minor: - $(ECHOMARKER) "release minor version" - $(QUIET) $(MAKE) tag-minor-version - $(QUIET) $(MAKE) node-build - $(QUIET) $(MAKE) node-test - $(QUIET) $(NPM) --prefix $(NODE_ROOT_DIR) run publish - -.PHONY: npm-publish-patch -## release patch version of package -npm-publish-patch: - $(ECHOMARKER) "release patch version" - $(QUIET) $(MAKE) tag-patch-version - $(QUIET) $(MAKE) node-build - $(QUIET) $(MAKE) node-test - $(QUIET) $(NPM) --prefix $(NODE_ROOT_DIR) run publish - diff --git a/development/makefiles/target-npm.mk b/development/makefiles/target-npm.mk deleted file mode 100644 index 29c8bcb3c2e5d58a35ba4a816d277dea485f9a5f..0000000000000000000000000000000000000000 --- a/development/makefiles/target-npm.mk +++ /dev/null @@ -1,34 +0,0 @@ -############################################################################################# -############################################################################################# -## -## RUN NPM BUILD, TEST AND DEV TASKS -## -############################################################################################# -############################################################################################# - -.PHONY: npm-dev -## run npm dev server -npm-dev: - $(ECHOMARKER) "start npm dev server" - $(QUIET) $(NPM) --prefix $(NODE_ROOT_DIR) run dev - -.PHONY: npm-build -## build npm project -npm-build: - $(ECHOMARKER) "build npm project" - $(QUIET) $(NPM) --prefix $(NODE_ROOT_DIR) run build - -.PHONY: npm-preview -## preview npm project -npm-preview: - $(ECHOMARKER) "preview npm project" - $(QUIET) $(NPM) --prefix $(NODE_ROOT_DIR) run build - $(QUIET) $(NPM) --prefix $(NODE_ROOT_DIR) run preview - - -.PHONY: npm-update-all -## Update Node Components -npm-update-all: - $(ECHOMARKER) "Search and Update recursive all node_modules (npm and pnpm)" - $(QUIET) $(FIND) . -type f ! -path '*node_modules*' -iname pnpm-lock.yaml -exec bash -c 'cd $$(dirname {} ) ; pwd; pnpm update -Lr ; cd - ' \; - $(QUIET) $(FIND) . -type f ! -path '*node_modules*' -iname package-lock.json -exec bash -c 'cd $$(dirname {} ) ; pwd; npm install -D npm-check-updates; npx npm-check-updates -u; npm install ; cd -' \; diff --git a/development/makefiles/target-phpunit.mk b/development/makefiles/target-phpunit.mk deleted file mode 100644 index 7120d7f08c5772cfa266338a0609ccb53ab9b239..0000000000000000000000000000000000000000 --- a/development/makefiles/target-phpunit.mk +++ /dev/null @@ -1,67 +0,0 @@ -############################################################################################# -############################################################################################# -## -## PHPUNIT -## -############################################################################################# -############################################################################################# - -# path and binaries -PARALLEL ?= parallel - -EXECUTABLES = $(EXECUTABLES:-) $(PARALLEL); - -PHPUNIT_PATH := $(VENDOR_PATH)phpunit/ -PHPUNIT_BIN := $(PHPUNIT_PATH)phpunit -PHPUNIT_SCRIPT_PATH := $(BUILD_PATH)/script - - -ifeq ($(shell command -v $(PARALLEL) 2> /dev/null),) - $(error "parallel is not installed. Please install parallel") -endif - -ifneq ($(shell test -d $(PHPUNIT_SCRIPT_PATH) && echo -n yes),yes) - $(shell mkdir -p $(PHPUNIT_SCRIPT_PATH)) -endif - -define UNITTEST_SH_SCRIPT -#!/bin/bash - -BIN=$$1 -BOOTSTRAP=$$2 -CONFIG=$$3 -TESTFILES=$$4 - -export DOCOVERAGE=true - -groups=$$($${BIN} \ - --list-groups \ - --bootstrap $${BOOTSTRAP} \ - --configuration $${CONFIG} \ - development/tests/ | sed -n -e '/^ - /p' | cut -d"-" -f2 | tr -d ' ') - -parallel \ - $${BIN} \ - --group {} \ - --configuration $${CONFIG} \ - --whitelist application/source/ \ - --bootstrap $${BOOTSTRAP} \ - $${TESTFILES} ::: $${groups} -endef - -export UNITTEST_SH_SCRIPT - -$(PHPUNIT_SCRIPT_PATH)/unittests.sh: - $(QUIET) $(ECHO) "$$UNITTEST_SH_SCRIPT" >> $@ - $(CHMOD) u+x $(PHPUNIT_SCRIPT_PATH)/unittests.sh - -$(PHPUNIT_BIN): - $(MKDIR) -p $(PHPUNIT_PATH) - $(WGET) -O $(PHPUNIT_BIN) https://phar.phpunit.de/phpunit-10.phar - $(CHMOD) u+x $(PHPUNIT_BIN) - $(CHMOD) u+x $(PHPUNIT_SCRIPT_PATH)/unittests.sh - -.PHONY: run-phpunit-tests -## run PHPUNIT Tests -run-phpunit-tests: $(PHPUNIT_SCRIPT_PATH)/unittests.sh $(PHPUNIT_BIN) - $(BUILD_SCRIPTS_PATH)unittests.sh "$(PHPUNIT_BIN)" "$(TEST_PATH)script/bootstrap.inc.php" "$(TEST_PATH)config/phpunit.xml" "$(TEST_PATH)" diff --git a/development/makefiles/target-project.mk b/development/makefiles/target-project.mk deleted file mode 100644 index ca5ef13bbb96f9d2ee4b62b189fe9c6825973a17..0000000000000000000000000000000000000000 --- a/development/makefiles/target-project.mk +++ /dev/null @@ -1,43 +0,0 @@ - -.PHONY: create-polyfill-monster -## create polyfill.io url -create-polyfill-monster: $(MONSTER_SOURCE_FILES) - $(ECHOMARKER) "create and replace polyfill" - $(QUIET) $(DEVELOPMENT_SCRIPTS_PATH)create-polyfill.sh $(MJS_RELATIVE_SOURCE_FILES) - - -.PHONY: test-browser-monster -## create test-browser-monster -test-browser-monster: create-polyfill-monster - $(ECHOMARKER) "create browser test and start chrome" - $(QUIET) $(FIND) $(TEST_PATH)cases -type f | $(SED) "s|^$(TEST_PATH)cases||" > $(TEST_PATH)web/import.js - $(QUIET) $(SED) -i 's|^|import "../cases|' $(TEST_PATH)web/import.js - $(QUIET) $(SED) -i 's|$$|";|' $(TEST_PATH)web/import.js - $(QUIET) $(SED) -i "1 i import \"./prepare.js\";" $(TEST_PATH)web/import.js - $(QUIET) $(SED) -i "1 i /** this file was created automatically by the make target test-browser-monster */" $(TEST_PATH)web/import.js - $(ESBUILD) --platform=browser --sourcemap=inline --external:ws --external:jsdom --external:process --external:crypto --bundle $(TEST_PATH)web/import.js --outfile=$(TEST_PATH)web/tests.js -# $(QUIET) $(CD) $(MONSTER_BUILD_TEST_BROWSER_DIR); $(WEBPACK) ; $(CD) - -# $(QUIET) $(SED) -i -E "/<h1/s_.*_ <h1 style='margin-bottom: 0.1em;'>Monster $(PROJECT_VERSION)</h1>_" $(TEST_PATH)web/test.html $(TEST_PATH)web/monster.html $(TEST_PATH)web/monster-dev.html -# $(QUIET) $(SED) -i -E "/id=\"lastupdate\"/s_.*_ <div id=\"lastupdate\" style='font-size:0.7em'>last update $(shell date)</div>_" $(TEST_PATH)web/test.html $(TEST_PATH)web/monster.html $(TEST_PATH)web/monster-dev.html -# $(QUIET) $(SED) -i -E "s_src=\"([\"]*)\.js.*\"_src=\"\1.js?r=$(shell date +"%T")\"_" $(TEST_PATH)web/test.html $(TEST_PATH)web/monster.html $(TEST_PATH)web/monster-dev.html -# $(QUIET) $(SED) -i -E "s_dist/([0-9]+\.[0-9]+\.[0-9]+)*/dist/monster_dist/$(PROJECT_VERSION)/dist/monster_" $(TEST_PATH)web/monster.html $(TEST_PATH)web/monster-dev.html -# #$(QUIET) if $(OPENBROWSER) ; then google-chrome --profile-directory="Default" $(TEST_PATH)web/test.html ; fi - - -## -> eigenes repos für monsterjs.org -#.PHONY: web-to-s3 -### transfer web to s3 -#web-to-s3: -# $(ECHOMARKER) "transfer web to s3" -# $(QUIET) $(AWS) s3 --recursive --only-show-errors cp $(DEPLOYMENT_PATH)web/assets/ s3://monsterjs.org/assets/ -# $(QUIET) $(AWS) s3 --recursive --only-show-errors cp $(DEPLOYMENT_PATH)web/vendor/ s3://monsterjs.org/vendor/ -# $(QUIET) $(AWS) s3 --only-show-errors cp $(DEPLOYMENT_PATH)web/index.html s3://monsterjs.org/index.html -# $(QUIET) $(AWS) s3 --only-show-errors cp $(DEPLOYMENT_PATH)web/error.html s3://monsterjs.org/error.html - - -.PHONY: doc-to-s3 -## transfer doc to s3 -doc-to-s3: jsdoc-build - $(ECHOMARKER) "transfer doc to s3" - $(QUIET) $(AWS) s3 --recursive --only-show-errors cp $(BUILD_PATH)docs s3://monsterjs.org/en/doc/monster/ - diff --git a/development/makefiles/target-reqman.mk b/development/makefiles/target-reqman.mk deleted file mode 100644 index 37db2ecad810f1ef0137cfe3bb4bb22bd025148b..0000000000000000000000000000000000000000 --- a/development/makefiles/target-reqman.mk +++ /dev/null @@ -1,40 +0,0 @@ -############################################################################################# -############################################################################################# -## -## REQMAN-TARGETS -## -############################################################################################# -############################################################################################# - - -# @TODO not working, check if this is a bug in this definition!!! - -ifeq ($(REQMAN_BIN),) - $(error "$(REQMAN_BIN) is not installed. Please check your makefile and include the reqman.mk") -endif - -$(REQMAN_BIN): - $(QUIET) $(MKDIR) -p $(VENDOR_PATH) - $(QUIET) $(WGET) -O $(REQMAN_BIN) http://download.schukai.com/tools/reqman/reqman-$(shell uname -s | tr [:upper:] [:lower:])-$(shell echo `uname -m | sed s/aarch64/arm64/ | sed s/x86_64/amd64/`) - $(QUIET) $(CHMOD) u+x $(REQMAN_BIN) - -$(PROJECT_ROOT)deployment/build/manual.html: $(DOCMAN_BIN) - $(REQMAN_BIN) print html --config $(PROJECT_ROOT)requirement/config.yaml - -$(PROJECT_ROOT)deployment/build/manual.pdf: $(DOCMAN_BIN) - $(REQMAN_BIN) print pdf --config $(PROJECT_ROOT)requirement/config.yaml - -.PHONY: build-req-pdf -## creating the requirement in pdf format -build-req-pdf: $(PROJECT_ROOT)deployment/build/requirement.pdf - -.PHONY: build-req-html -## creating the requirement in html format -build-req-html: $(PROJECT_ROOT)deployment/build/requirement.html - - -.PHONY: build-req -## creating the requirement in pdf and html format -build-req: build-req-pdf build-req-html - - diff --git a/development/makefiles/target-update-makefiles.mk b/development/makefiles/target-update-makefiles.mk deleted file mode 100644 index 284df847df3b474d9d040de2a4fc424bbcff9b85..0000000000000000000000000000000000000000 --- a/development/makefiles/target-update-makefiles.mk +++ /dev/null @@ -1,32 +0,0 @@ -############################################################################################# -############################################################################################# -## -## INIT-TARGETS -## -############################################################################################# -############################################################################################# - -ifeq ($(GIT),) - $(error $(ERRORMARKER) Git is not defined, check your Makefile if git.mk is included) -endif - -# @see .PHONY https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html#Phony-Targets -.PHONY: update-makefiles - -ifeq ($(QUIET),) - _COPYVERBOSE = -v -endif - -## update standard makefiles -update-makefiles: - $(ECHOMARKER) "update standard makefiles" - $(QUIET) $(eval TEMPD := $(shell mktemp -d)) - $(QUIET) $(GIT) clone --quiet --depth=1 https://gitlab.schukai.com/schukai/utilities/makefile.git/ "$(TEMPD)" - $(QUIET) $(CP) -r $(_COPYVERBOSE) $(TEMPD)/makefiles/* $(MAKEFILE_IMPORT_PATH) - $(QUIET) $(CP) -r $(_COPYVERBOSE) $(TEMPD)/Makefile $(PROJECT_ROOT)Makefile.example - $(QUIET) $(RM) -rf $(TEMPD) - - - - - diff --git a/development/makefiles/target-variable.mk b/development/makefiles/target-variable.mk deleted file mode 100644 index 3ad8267a765d377db7fa2d8e4037cfa7a4c6d698..0000000000000000000000000000000000000000 --- a/development/makefiles/target-variable.mk +++ /dev/null @@ -1,13 +0,0 @@ -############################################################################################# -############################################################################################# -## -## VARIABLES-TARGETS -## -############################################################################################# -############################################################################################# - -.PHONY: variables -## Print all variables -variables: - $(ECHOMARKER) "print all variables" - $(QUIET) $(foreach v, $(.VARIABLES), $(if $(filter file,$(origin $(v))), $(info $(INFO)$(v)$(RESET)=$($(v))$(RESET)))) \ No newline at end of file diff --git a/development/makefiles/target-version.mk b/development/makefiles/target-version.mk deleted file mode 100644 index 71c274d585d03cd082ed39ba7bd8a93973f0f196..0000000000000000000000000000000000000000 --- a/development/makefiles/target-version.mk +++ /dev/null @@ -1,71 +0,0 @@ -############################################################################################# -############################################################################################# -## -## VARIABLES-TARGETS -## -############################################################################################# -############################################################################################# - -ifeq ($(VERSION_BIN),) - $(error "$(VERSION_BIN) is not installed. Please check your makefile and include the version.mk") -endif - -ifeq ($(GIT),) - $(error $(ERRORMARKER) Git is not defined, check your Makefile if git.mk is included) -endif - -ifeq ($(GIT_CHGLOG_BIN),) - $(error $(ERRORMARKER) Chglog is not defined, check your Makefile if changelog.mk is included) -endif - -$(VERSION_BIN): - $(QUIET) $(MKDIR) -p $(VENDOR_PATH) - $(QUIET) $(WGET) -O $(VERSION_BIN) http://download.schukai.com/tools/version/version-$(shell uname -s | tr [:upper:] [:lower:])-$(shell echo `uname -m | sed s/aarch64/arm64/ | sed s/x86_64/amd64/`) - $(QUIET) $(CHMOD) u+x $(VERSION_BIN) - - -.PHONY: next-patch-version -next-patch-version: check-clean-repo $(VERSION_BIN) - $(ECHOMARKER) "Creating next version" - $(QUIET) $(VERSION_BIN) patch --path $(RELEASE_FILE) --selector "version" - $(QUIET) $(GIT) add $(RELEASE_FILE) && $(GIT) commit -m "Bump version to $$(cat $(RELEASE_FILE) | jq -r .version)" - -.PHONY: next-minor-version -next-minor-version: check-clean-repo $(VERSION_BIN) - $(ECHOMARKER) "Creating next minor version" - $(QUIET) $(VERSION_BIN) minor --path $(RELEASE_FILE) --selector "version" - $(QUIET) $(GIT) add $(RELEASE_FILE) && $(GIT) commit -m "Bump version to $$( cat $(RELEASE_FILE) | jq -r .version)" - -.PHONY: next-major-version -next-major-version: check-clean-repo $(VERSION_BIN) - $(ECHOMARKER) "Creating next minor version" - $(QUIET) $(VERSION_BIN) major --path $(RELEASE_FILE) --selector "version" - $(QUIET) $(GIT) add $(RELEASE_FILE) && $(GIT) commit -m "Bump version to $$(cat $(RELEASE_FILE) | jq -r .version)" - -.PHONY: check-clean-repo -check-clean-repo: - $(QUIET) $(GIT) diff-index --quiet HEAD || (echo "There are uncommitted changes after running make. Please commit or stash them before running make."; exit 1) - -## tag repository with next patch version -tag-patch-version: $(GIT_CHGLOG_CONFIG_DIR)/config.yml $(GIT_CHGLOG_CONFIG_DIR)/CHANGELOG.tpl.md next-patch-version - $(ECHOMARKER) "Tagging patch version" - $(eval PROJECT_VERSION := $(shell cat $(RELEASE_FILE) | jq -r .version)) - $(GIT_CHGLOG_BIN) --next-tag v$(PROJECT_VERSION) -o $(CHANGELOG_FILE) - $(QUIET) $(GIT) add $(CHANGELOG_FILE) && $(GIT) commit -m "Update changelog" - $(QUIET) $(GIT) tag -a v$(PROJECT_VERSION) -m "Version $(PROJECT_VERSION)" - -## tag repository with next minor version -tag-minor-version: $(GIT_CHGLOG_CONFIG_DIR)/config.yml $(GIT_CHGLOG_CONFIG_DIR)/CHANGELOG.tpl.md next-minor-version - $(ECHOMARKER) "Tagging minor version" - $(eval PROJECT_VERSION := $(shell cat $(RELEASE_FILE) | jq -r .version)) - $(GIT_CHGLOG_BIN) --next-tag v$(PROJECT_VERSION) -o $(CHANGELOG_FILE) - $(QUIET) $(GIT) add $(CHANGELOG_FILE) && $(GIT) commit -m "Update changelog" - $(QUIET) $(GIT) tag -a v$(PROJECT_VERSION) -m "Version $(PROJECT_VERSION)" - -## tag repository with next major version -tag-major-version: $(GIT_CHGLOG_CONFIG_DIR)/config.yml $(GIT_CHGLOG_CONFIG_DIR)/CHANGELOG.tpl.md next-major-version - $(ECHOMARKER) "Tagging major version" - $(eval PROJECT_VERSION := $(shell cat $(RELEASE_FILE) | jq -r .version)) - $(GIT_CHGLOG_BIN) --next-tag v$(PROJECT_VERSION) -o $(CHANGELOG_FILE) - $(QUIET) $(GIT) add $(CHANGELOG_FILE) && $(GIT) commit -m "Update changelog" - $(QUIET) $(GIT) tag -a v$(PROJECT_VERSION) -m "Version $(PROJECT_VERSION)" diff --git a/development/makefiles/terminal-check.mk b/development/makefiles/terminal-check.mk deleted file mode 100644 index 5db23c80e0215eaa75e1e10afbf242060fc69327..0000000000000000000000000000000000000000 --- a/development/makefiles/terminal-check.mk +++ /dev/null @@ -1,13 +0,0 @@ -############################################################################################# -############################################################################################# -## -## TERMINAL CHECK -## -############################################################################################# -############################################################################################# - - - -# Executable Programs the Installed be have to -K := $(foreach exec,$(EXECUTABLES),\ - $(if $(shell which $(exec)),some string,$(error "Missing $(exec) in PATH; please install"))) \ No newline at end of file diff --git a/development/makefiles/terminal.mk b/development/makefiles/terminal.mk deleted file mode 100644 index 905b88a161ddcd5fe32958201df6aac8639c88ae..0000000000000000000000000000000000000000 --- a/development/makefiles/terminal.mk +++ /dev/null @@ -1,40 +0,0 @@ -############################################################################################# -############################################################################################# -## -## COMMANDS -## -############################################################################################# -############################################################################################# - -# Use bash instead of sh -## Sets the shell used -SHELL = bash - -# path and binaries -AWK ?= awk -CP ?= cp -CD ?= cd -KILL ?= kill -MV ?= mv -RM ?= rm -MKDIR ?= mkdir -SED ?= sed -FIND ?= find -SORT ?= sort -TOUCH ?= touch -WGET ?= wget -CHMOD ?= chmod -RSYNC ?= rsync -XARGS ?= xargs -GREP ?= grep -MAKE ?= make -LN ?= ln -TOUCH ?= touch -TEST ?= test -JQ ?= jq - - -EXECUTABLES = $(EXECUTABLES:-) $(JQ) $(AWK) $(CP) $(KILL) $(MV) $(SED) $(FIND) $(SORT) $(TOUCH) $(WGET) $(CHMOD) $(RSYNC) $(XARGS) $(GREP) $(MAKE) $(LN) - - - \ No newline at end of file diff --git a/development/makefiles/version.mk b/development/makefiles/version.mk deleted file mode 100644 index 0f643ee2209221ea08cb31cb6ccd51bef825d8e8..0000000000000000000000000000000000000000 --- a/development/makefiles/version.mk +++ /dev/null @@ -1,17 +0,0 @@ -############################################################################################# -############################################################################################# -## -## VERSIONS -## -############################################################################################# -############################################################################################# - -VERSION_BIN ?= $(VENDOR_PATH)version -RELEASE_FILE ?= $(PROJECT_ROOT)release.json - -ifeq ("$(wildcard $(RELEASE_FILE))","") - $(shell echo '{"version":"0.1.0"}' > $(RELEASE_FILE)) -endif - -PROJECT_VERSION ?= $(shell cat $(RELEASE_FILE) | jq -r .version) -PROJECT_BUILD_DATE ?= $(shell $(VERSION_BIN) date) diff --git a/development/package.json b/development/package.json deleted file mode 100644 index 2e09b1880417331272fc1d831dfb73dd3e587fb1..0000000000000000000000000000000000000000 --- a/development/package.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "name": "monster", - "version": "3.51.4", - "description": "monster", - "repository": { - "type": "git", - "url": "https://gitlab.schukai.com/oss/libraries/javascript/monster.git" - }, - "bugs": { - "url": "https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues" - }, - "scripts": { - "test": "npx mocha --recursive test/cases/", - "web-test": "script/web-test.sh", - "publish": "script/release-and-publish.sh", - "build-doc": "script/build-doc.sh" - }, - "type": "module", - "keywords": [], - "author": "schukai GmbH", - "license": "see LICENSE file", - "devDependencies": { - "@oss/web-components-build-tools": "^1.2.8", - "@peculiar/webcrypto": "^1.4.3", - "autoprefixer": "^10.4.14", - "browserslist": "^4.21.9", - "btoa": "^1.2.1", - "c8": "^8.0.0", - "chai": "^4.3.7", - "chai-dom": "^1.11.0", - "clean-jsdoc-theme": "^4.2.9", - "create-polyfill-service-url": "^2.2.6", - "crypt": "^0.0.2", - "cssnano": "^6.0.1", - "element-internals-polyfill": "^1.3.5", - "esbuild": "^0.18.4", - "flow-bin": "^0.209.0", - "fs": "0.0.1-security", - "glob": "^10.2.7", - "graphviz": "^0.0.9", - "jsdoc": "^4.0.2", - "jsdoc-external-example": "github:volker-schukai/jsdoc-external-example", - "jsdoc-plantuml": "^1.0.3", - "jsdom": "^22.1.0", - "jsdom-global": "^3.0.2", - "mocha": "^10.2.0", - "node-plantuml": "^0.9.0", - "postcss": "^8.4.24", - "postcss-fluid": "^1.4.2", - "postcss-for": "^2.1.1", - "postcss-import": "^15.1.0", - "postcss-load-config": "^4.0.1", - "postcss-mixins": "^9.0.4", - "postcss-nested": "^6.0.1", - "postcss-nesting": "^11.3.0", - "postcss-normalize": "^10.0.1", - "postcss-responsive-type": "^1.0.0", - "postcss-rtlcss": "^4.0.6", - "postcss-strip-units": "^2.0.1", - "rome": "^12.1.3", - "sinon": "^15.1.2", - "url": "^0.11.1", - "url-exist": "3.0.1", - "util": "^0.12.5", - "vite": "^4.3.9", - "vite-plugin-banner": "^0.7.0", - "vite-plugin-list-directory-contents": "^1.4.5", - "vite-plugin-minify": "^1.5.2", - "vite-plugin-mkcert": "^1.15.0", - "ws": "^8.13.0" - } -} diff --git a/development/rome.json b/development/rome.json deleted file mode 100644 index 73c4ac10806a6c210f3e6ddf788ea6335f559e14..0000000000000000000000000000000000000000 --- a/development/rome.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "$schema": "./node_modules/rome/configuration_schema.json", - "linter": { - "enabled": true, - "rules": { - "recommended": true, - "performance": { - "noDelete": "off" - } - } - }, - "formatter": { - "enabled": true, - "indentStyle": "space", - "lineWidth": 120, - "indentSize": 4 - } -} \ No newline at end of file diff --git a/development/script/build-doc.sh b/development/script/build-doc.sh deleted file mode 100755 index 45ff852c5048da8d67401ff294f2dc481bfa0fc3..0000000000000000000000000000000000000000 --- a/development/script/build-doc.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash - -SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )/" -PROJECT_ROOT="$(realpath $SCRIPT_DIR'../../')/" - -TUTORIALS_PATH=${PROJECT_ROOT}documentation/tutorial/ -BUILD_PATH=${PROJECT_ROOT}deployment/build/docs/ -BUILD_TUTORIAL_PATH=${PROJECT_ROOT}deployment/build/docs/tutorials/ -DOCUMENTATION_CONFIG_PATH=${PROJECT_ROOT}documentation/config/jsdoc.json - -rm -rf $BUILD_PATH - - -npx jsdoc --tutorials ${TUTORIALS_PATH} \ - --readme ${PROJECT_ROOT}documentation/README.md \ - --configure ${DOCUMENTATION_CONFIG_PATH} \ - -mkdir -p ${BUILD_TUTORIAL_PATH}images/ -mkdir -p ${BUILD_TUTORIAL_PATH}videos/ - -mkdir -p ${TUTORIALS_PATH}images/ -mkdir -p ${TUTORIALS_PATH}videos/ - -rsync -av ${TUTORIALS_PATH}images/ ${BUILD_PATH}tutorials/images/ -rsync -av ${TUTORIALS_PATH}videos/ ${BUILD_PATH}tutorials/videos/ - -${SCRIPT_DIR}replace-codepen-skypack.cjs \ No newline at end of file diff --git a/development/script/create-polyfill.sh b/development/script/create-polyfill.sh deleted file mode 100755 index ef004c986ef5df40247d1ab62a3f0aef7a0806ae..0000000000000000000000000000000000000000 --- a/development/script/create-polyfill.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash - -SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )/" -PROJECT_ROOT="$(realpath $SCRIPT_DIR'../../')/" -SOURCE_PATH="${PROJECT_ROOT}application/source/" -TEST_PATH="$(realpath $SCRIPT_DIR'../test/')/" - -TMPFILE=monster.temp -touch $TMPFILE -trap "rm -f $TMPFILE" 0 2 3 15 - -${PROJECT_ROOT}development/node_modules/.bin/esbuild --platform=browser --bundle ${SOURCE_PATH}monster.mjs --outfile=${TMPFILE} -url="$(${PROJECT_ROOT}development/node_modules/.bin/create-polyfill-service-url analyse --file "$TMPFILE")" - -if [ ! -x {$url} ] -then - sed -i -E "/id=\"polyfill\"/s|.*| <script id=\"polyfill\" src=\"${url}\"|g" ${TEST_PATH}web/test.html - sed -i -E "/id=\"polyfill\"/s|.*|<script id=\"polyfill\" src=\"${url}\"|g" ${PROJECT_ROOT}README.md -fi diff --git a/development/script/grep-exports.cjs b/development/script/grep-exports.cjs deleted file mode 100755 index a8ee4018f6dcfb48b7e90b540a97ae390e45fef4..0000000000000000000000000000000000000000 --- a/development/script/grep-exports.cjs +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env node - -const regex = /^\s*(?<exp>(export\s+{[^}]+)})/gm; - -const fs = require('fs'); -var path = require('path') -const basename = __dirname + '/../../application/source/' - -let exportLines = [] - -function scanSymbols(root) { - - let f; - - const dir = fs.opendirSync(root); - while ((f = dir.readSync()) !== null) { - - if (f.isDirectory()) { - scanSymbols(path.join(root, f.name)); - continue; - } else if (!f.isFile()) { - continue; - } - - if(f.name==="monster.mjs") continue; - - if ((path.extname(f.name) !== ".mjs")) { - continue; - } - - const fn = path.join(root, f.name); - let content = fs.readFileSync(fn, 'utf8'); - - while ((m = regex.exec(content)) !== null) { - let exp = m.groups?.exp; - if (!exp) { - continue; - } - exportLines.push(exp + " from \"./" + path.relative(basename, fn) + "\""); - } - } -} - -scanSymbols(path.normalize(basename)) -console.log(exportLines.join("\n")); diff --git a/development/script/release-and-publish.sh b/development/script/release-and-publish.sh deleted file mode 100755 index d67a06ab9660b7165a711189f24b8a6c5df34dd8..0000000000000000000000000000000000000000 --- a/development/script/release-and-publish.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env bash - -SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )/" -PROJECT_ROOT="$(realpath $SCRIPT_DIR'../../')/" -APPLICATION_PATH="${PROJECT_ROOT}application/" -TEST_PATH="$(realpath $SCRIPT_DIR'../test/')/" -BUILD_PATH="${PROJECT_ROOT}deployment/build/npm/" -DEVELOPMENT_PATH="${PROJECT_ROOT}development/" - -if [ -d $BUILD_PATH ]; then - rm -rf ${BUILD_PATH} -fi - -mkdir -p ${BUILD_PATH} - -cp -r ${APPLICATION_PATH}* ${BUILD_PATH} -cp -r ${TEST_PATH} ${BUILD_PATH} -cp -r ${PROJECT_ROOT}README.md ${BUILD_PATH} - -git add ${APPLICATION_PATH}package.json -git add ${DEVELOPMENT_PATH}package.json -git add ${APPLICATION_PATH}source/types/version.mjs -git add ${TEST_PATH}cases/monster.mjs -git add ${PROJECT_ROOT}release.json -git commit -m "release and publish to npm" - -rm $BUILD_PATH/pnpm-lock.yaml - -cd ${BUILD_PATH} -## --dry-run -pnpm publish --access public -cd - - diff --git a/development/script/update-version.sh b/development/script/update-version.sh deleted file mode 100755 index f30fd769fef119511073999051330303173b1715..0000000000000000000000000000000000000000 --- a/development/script/update-version.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash - -SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )/" -PROJECT_ROOT="$(realpath $SCRIPT_DIR'../../')/" - -VERSION=$(cat "$PROJECT_ROOT/release.json" | jq -r '.version') - -sed -i -E "s_(\"[0-9]+\.[0-9]+\.[0-9]+\")_\"${VERSION}\"_g" "${PROJECT_ROOT}application/source/types/version.mjs" -sed -i -E "s_(\"[0-9]+\.[0-9]+\.[0-9]+\")_\"${VERSION}\"_g" "${PROJECT_ROOT}development/test/cases/monster.mjs" - - \ No newline at end of file diff --git a/development/script/web-test.sh b/development/script/web-test.sh deleted file mode 100755 index f1784fea0ee7afc5124668497ebe5c9fea4a7bfe..0000000000000000000000000000000000000000 --- a/development/script/web-test.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash - -SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" -PROJECT_ROOT="$(realpath "$SCRIPT_DIR/../../")" -TEST_PATH=$(realpath "$SCRIPT_DIR/../test/")/ -TEST_CASES_PATH=$(realpath "$TEST_PATH/cases/")/ - -VERSION=$(cat "$PROJECT_ROOT/release.json" | jq -r '.version') - -$SCRIPT_DIR/create-polyfill.sh - -find ${TEST_CASES_PATH} -type f | sed "s|^$TEST_CASES_PATH||" > ${TEST_PATH}web/import.js -sed -i 's|^|import "../cases/|' ${TEST_PATH}web/import.js -sed -i 's|$|";|' ${TEST_PATH}web/import.js -sed -i "1 i import \"./prepare.js\";" ${TEST_PATH}web/import.js -sed -i "1 i /** this file was created automatically by the make target test-browser-monster */" ${TEST_PATH}web/import.js - -npx esbuild --platform=browser --sourcemap=inline --external:ws --external:jsdom --external:process --external:crypto --bundle ${TEST_PATH}web/import.js --outfile=${TEST_PATH}web/tests.js - -sed -i -E "/<h1/s_.*_ <h1 style='margin-bottom: 0.1em;'>Monster ${VERSION}</h1>_" ${TEST_PATH}web/test.html -sed -i -E "/id=\"lastupdate\"/s_.*_ <div id=\"lastupdate\" style='font-size:0.7em'>last update $(date)</div>_" ${TEST_PATH}web/test.html -sed -i -E "s_src=\"([\"]*)\.js.*\"_src=\"\1.js?r=$(date +"%T")\"_" ${TEST_PATH}web/test.html - - - diff --git a/development/test/web/tests.js b/development/test/web/tests.js deleted file mode 100644 index 410dfd4ba4fc842447e39980ac9e5fcb80b080b6..0000000000000000000000000000000000000000 --- a/development/test/web/tests.js +++ /dev/null @@ -1,33879 +0,0 @@ -(() => { - var __create = Object.create; - var __defProp = Object.defineProperty; - var __getOwnPropDesc = Object.getOwnPropertyDescriptor; - var __getOwnPropNames = Object.getOwnPropertyNames; - var __getProtoOf = Object.getPrototypeOf; - var __hasOwnProp = Object.prototype.hasOwnProperty; - var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { - get: (a2, b) => (typeof require !== "undefined" ? require : a2)[b] - }) : x)(function(x) { - if (typeof require !== "undefined") - return require.apply(this, arguments); - throw new Error('Dynamic require of "' + x + '" is not supported'); - }); - var __esm = (fn, res) => function __init() { - return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; - }; - var __commonJS = (cb, mod) => function __require2() { - return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; - }; - var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); - }; - var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; - }; - var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( - // If the importer is in node compatibility mode or this is not an ESM - // file that has been converted to a CommonJS file using a Babel- - // compatible transform (i.e. "__esModule" has not been set), then set - // "default" to the CommonJS "module.exports" for node compatibility. - isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, - mod - )); - - // node_modules/.pnpm/assertion-error@1.1.0/node_modules/assertion-error/index.js - var require_assertion_error = __commonJS({ - "node_modules/.pnpm/assertion-error@1.1.0/node_modules/assertion-error/index.js"(exports, module) { - function exclude() { - var excludes = [].slice.call(arguments); - function excludeProps(res, obj) { - Object.keys(obj).forEach(function(key) { - if (!~excludes.indexOf(key)) - res[key] = obj[key]; - }); - } - return function extendExclude() { - var args = [].slice.call(arguments), i = 0, res = {}; - for (; i < args.length; i++) { - excludeProps(res, args[i]); - } - return res; - }; - } - module.exports = AssertionError2; - function AssertionError2(message, _props, ssf) { - var extend2 = exclude("name", "message", "stack", "constructor", "toJSON"), props = extend2(_props || {}); - this.message = message || "Unspecified AssertionError"; - this.showDiff = false; - for (var key in props) { - this[key] = props[key]; - } - ssf = ssf || AssertionError2; - if (Error.captureStackTrace) { - Error.captureStackTrace(this, ssf); - } else { - try { - throw new Error(); - } catch (e) { - this.stack = e.stack; - } - } - } - AssertionError2.prototype = Object.create(Error.prototype); - AssertionError2.prototype.name = "AssertionError"; - AssertionError2.prototype.constructor = AssertionError2; - AssertionError2.prototype.toJSON = function(stack) { - var extend2 = exclude("constructor", "toJSON", "stack"), props = extend2({ name: this.name }, this); - if (false !== stack && this.stack) { - props.stack = this.stack; - } - return props; - }; - } - }); - - // node_modules/.pnpm/pathval@1.1.1/node_modules/pathval/index.js - var require_pathval = __commonJS({ - "node_modules/.pnpm/pathval@1.1.1/node_modules/pathval/index.js"(exports, module) { - "use strict"; - function hasProperty(obj, name) { - if (typeof obj === "undefined" || obj === null) { - return false; - } - return name in Object(obj); - } - function parsePath(path) { - var str = path.replace(/([^\\])\[/g, "$1.["); - var parts = str.match(/(\\\.|[^.]+?)+/g); - return parts.map(function mapMatches(value) { - if (value === "constructor" || value === "__proto__" || value === "prototype") { - return {}; - } - var regexp = /^\[(\d+)\]$/; - var mArr = regexp.exec(value); - var parsed = null; - if (mArr) { - parsed = { i: parseFloat(mArr[1]) }; - } else { - parsed = { p: value.replace(/\\([.[\]])/g, "$1") }; - } - return parsed; - }); - } - function internalGetPathValue(obj, parsed, pathDepth) { - var temporaryValue = obj; - var res = null; - pathDepth = typeof pathDepth === "undefined" ? parsed.length : pathDepth; - for (var i = 0; i < pathDepth; i++) { - var part = parsed[i]; - if (temporaryValue) { - if (typeof part.p === "undefined") { - temporaryValue = temporaryValue[part.i]; - } else { - temporaryValue = temporaryValue[part.p]; - } - if (i === pathDepth - 1) { - res = temporaryValue; - } - } - } - return res; - } - function internalSetPathValue(obj, val, parsed) { - var tempObj = obj; - var pathDepth = parsed.length; - var part = null; - for (var i = 0; i < pathDepth; i++) { - var propName = null; - var propVal = null; - part = parsed[i]; - if (i === pathDepth - 1) { - propName = typeof part.p === "undefined" ? part.i : part.p; - tempObj[propName] = val; - } else if (typeof part.p !== "undefined" && tempObj[part.p]) { - tempObj = tempObj[part.p]; - } else if (typeof part.i !== "undefined" && tempObj[part.i]) { - tempObj = tempObj[part.i]; - } else { - var next = parsed[i + 1]; - propName = typeof part.p === "undefined" ? part.i : part.p; - propVal = typeof next.p === "undefined" ? [] : {}; - tempObj[propName] = propVal; - tempObj = tempObj[propName]; - } - } - } - function getPathInfo(obj, path) { - var parsed = parsePath(path); - var last = parsed[parsed.length - 1]; - var info = { - parent: parsed.length > 1 ? internalGetPathValue(obj, parsed, parsed.length - 1) : obj, - name: last.p || last.i, - value: internalGetPathValue(obj, parsed) - }; - info.exists = hasProperty(info.parent, info.name); - return info; - } - function getPathValue(obj, path) { - var info = getPathInfo(obj, path); - return info.value; - } - function setPathValue(obj, path, val) { - var parsed = parsePath(path); - internalSetPathValue(obj, val, parsed); - return obj; - } - module.exports = { - hasProperty, - getPathInfo, - getPathValue, - setPathValue - }; - } - }); - - // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/flag.js - var require_flag = __commonJS({ - "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/flag.js"(exports, module) { - module.exports = function flag(obj, key, value) { - var flags = obj.__flags || (obj.__flags = /* @__PURE__ */ Object.create(null)); - if (arguments.length === 3) { - flags[key] = value; - } else { - return flags[key]; - } - }; - } - }); - - // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/test.js - var require_test = __commonJS({ - "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/test.js"(exports, module) { - var flag = require_flag(); - module.exports = function test(obj, args) { - var negate = flag(obj, "negate"), expr = args[0]; - return negate ? !expr : expr; - }; - } - }); - - // node_modules/.pnpm/type-detect@4.0.8/node_modules/type-detect/type-detect.js - var require_type_detect = __commonJS({ - "node_modules/.pnpm/type-detect@4.0.8/node_modules/type-detect/type-detect.js"(exports, module) { - (function(global5, factory) { - typeof exports === "object" && typeof module !== "undefined" ? module.exports = factory() : typeof define === "function" && define.amd ? define(factory) : global5.typeDetect = factory(); - })(exports, function() { - "use strict"; - var promiseExists = typeof Promise === "function"; - var globalObject = typeof self === "object" ? self : global; - var symbolExists = typeof Symbol !== "undefined"; - var mapExists = typeof Map !== "undefined"; - var setExists = typeof Set !== "undefined"; - var weakMapExists = typeof WeakMap !== "undefined"; - var weakSetExists = typeof WeakSet !== "undefined"; - var dataViewExists = typeof DataView !== "undefined"; - var symbolIteratorExists = symbolExists && typeof Symbol.iterator !== "undefined"; - var symbolToStringTagExists = symbolExists && typeof Symbol.toStringTag !== "undefined"; - var setEntriesExists = setExists && typeof Set.prototype.entries === "function"; - var mapEntriesExists = mapExists && typeof Map.prototype.entries === "function"; - var setIteratorPrototype = setEntriesExists && Object.getPrototypeOf((/* @__PURE__ */ new Set()).entries()); - var mapIteratorPrototype = mapEntriesExists && Object.getPrototypeOf((/* @__PURE__ */ new Map()).entries()); - var arrayIteratorExists = symbolIteratorExists && typeof Array.prototype[Symbol.iterator] === "function"; - var arrayIteratorPrototype = arrayIteratorExists && Object.getPrototypeOf([][Symbol.iterator]()); - var stringIteratorExists = symbolIteratorExists && typeof String.prototype[Symbol.iterator] === "function"; - var stringIteratorPrototype = stringIteratorExists && Object.getPrototypeOf(""[Symbol.iterator]()); - var toStringLeftSliceLength = 8; - var toStringRightSliceLength = -1; - function typeDetect(obj) { - var typeofObj = typeof obj; - if (typeofObj !== "object") { - return typeofObj; - } - if (obj === null) { - return "null"; - } - if (obj === globalObject) { - return "global"; - } - if (Array.isArray(obj) && (symbolToStringTagExists === false || !(Symbol.toStringTag in obj))) { - return "Array"; - } - if (typeof window === "object" && window !== null) { - if (typeof window.location === "object" && obj === window.location) { - return "Location"; - } - if (typeof window.document === "object" && obj === window.document) { - return "Document"; - } - if (typeof window.navigator === "object") { - if (typeof window.navigator.mimeTypes === "object" && obj === window.navigator.mimeTypes) { - return "MimeTypeArray"; - } - if (typeof window.navigator.plugins === "object" && obj === window.navigator.plugins) { - return "PluginArray"; - } - } - if ((typeof window.HTMLElement === "function" || typeof window.HTMLElement === "object") && obj instanceof window.HTMLElement) { - if (obj.tagName === "BLOCKQUOTE") { - return "HTMLQuoteElement"; - } - if (obj.tagName === "TD") { - return "HTMLTableDataCellElement"; - } - if (obj.tagName === "TH") { - return "HTMLTableHeaderCellElement"; - } - } - } - var stringTag = symbolToStringTagExists && obj[Symbol.toStringTag]; - if (typeof stringTag === "string") { - return stringTag; - } - var objPrototype = Object.getPrototypeOf(obj); - if (objPrototype === RegExp.prototype) { - return "RegExp"; - } - if (objPrototype === Date.prototype) { - return "Date"; - } - if (promiseExists && objPrototype === Promise.prototype) { - return "Promise"; - } - if (setExists && objPrototype === Set.prototype) { - return "Set"; - } - if (mapExists && objPrototype === Map.prototype) { - return "Map"; - } - if (weakSetExists && objPrototype === WeakSet.prototype) { - return "WeakSet"; - } - if (weakMapExists && objPrototype === WeakMap.prototype) { - return "WeakMap"; - } - if (dataViewExists && objPrototype === DataView.prototype) { - return "DataView"; - } - if (mapExists && objPrototype === mapIteratorPrototype) { - return "Map Iterator"; - } - if (setExists && objPrototype === setIteratorPrototype) { - return "Set Iterator"; - } - if (arrayIteratorExists && objPrototype === arrayIteratorPrototype) { - return "Array Iterator"; - } - if (stringIteratorExists && objPrototype === stringIteratorPrototype) { - return "String Iterator"; - } - if (objPrototype === null) { - return "Object"; - } - return Object.prototype.toString.call(obj).slice(toStringLeftSliceLength, toStringRightSliceLength); - } - return typeDetect; - }); - } - }); - - // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/expectTypes.js - var require_expectTypes = __commonJS({ - "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/expectTypes.js"(exports, module) { - var AssertionError2 = require_assertion_error(); - var flag = require_flag(); - var type = require_type_detect(); - module.exports = function expectTypes(obj, types) { - var flagMsg = flag(obj, "message"); - var ssfi = flag(obj, "ssfi"); - flagMsg = flagMsg ? flagMsg + ": " : ""; - obj = flag(obj, "object"); - types = types.map(function(t) { - return t.toLowerCase(); - }); - types.sort(); - var str = types.map(function(t, index) { - var art = ~["a", "e", "i", "o", "u"].indexOf(t.charAt(0)) ? "an" : "a"; - var or = types.length > 1 && index === types.length - 1 ? "or " : ""; - return or + art + " " + t; - }).join(", "); - var objType = type(obj).toLowerCase(); - if (!types.some(function(expected) { - return objType === expected; - })) { - throw new AssertionError2( - flagMsg + "object tested must be " + str + ", but " + objType + " given", - void 0, - ssfi - ); - } - }; - } - }); - - // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/getActual.js - var require_getActual = __commonJS({ - "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/getActual.js"(exports, module) { - module.exports = function getActual(obj, args) { - return args.length > 4 ? args[4] : obj._obj; - }; - } - }); - - // node_modules/.pnpm/get-func-name@2.0.0/node_modules/get-func-name/index.js - var require_get_func_name = __commonJS({ - "node_modules/.pnpm/get-func-name@2.0.0/node_modules/get-func-name/index.js"(exports, module) { - "use strict"; - var toString = Function.prototype.toString; - var functionNameMatch = /\s*function(?:\s|\s*\/\*[^(?:*\/)]+\*\/\s*)*([^\s\(\/]+)/; - function getFuncName(aFunc) { - if (typeof aFunc !== "function") { - return null; - } - var name = ""; - if (typeof Function.prototype.name === "undefined" && typeof aFunc.name === "undefined") { - var match = toString.call(aFunc).match(functionNameMatch); - if (match) { - name = match[1]; - } - } else { - name = aFunc.name; - } - return name; - } - module.exports = getFuncName; - } - }); - - // (disabled):node_modules/.pnpm/util@0.12.5/node_modules/util/util.js - var require_util = __commonJS({ - "(disabled):node_modules/.pnpm/util@0.12.5/node_modules/util/util.js"() { - } - }); - - // node_modules/.pnpm/loupe@2.3.6/node_modules/loupe/loupe.js - var require_loupe = __commonJS({ - "node_modules/.pnpm/loupe@2.3.6/node_modules/loupe/loupe.js"(exports, module) { - (function(global5, factory) { - typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : (global5 = typeof globalThis !== "undefined" ? globalThis : global5 || self, factory(global5.loupe = {})); - })(exports, function(exports2) { - "use strict"; - function _typeof(obj) { - "@babel/helpers - typeof"; - if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { - _typeof = function(obj2) { - return typeof obj2; - }; - } else { - _typeof = function(obj2) { - return obj2 && typeof Symbol === "function" && obj2.constructor === Symbol && obj2 !== Symbol.prototype ? "symbol" : typeof obj2; - }; - } - return _typeof(obj); - } - function _slicedToArray(arr, i) { - return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); - } - function _arrayWithHoles(arr) { - if (Array.isArray(arr)) - return arr; - } - function _iterableToArrayLimit(arr, i) { - if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) - return; - var _arr = []; - var _n = true; - var _d = false; - var _e = void 0; - try { - for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { - _arr.push(_s.value); - if (i && _arr.length === i) - break; - } - } catch (err) { - _d = true; - _e = err; - } finally { - try { - if (!_n && _i["return"] != null) - _i["return"](); - } finally { - if (_d) - throw _e; - } - } - return _arr; - } - function _unsupportedIterableToArray(o, minLen) { - if (!o) - return; - if (typeof o === "string") - return _arrayLikeToArray(o, minLen); - var n = Object.prototype.toString.call(o).slice(8, -1); - if (n === "Object" && o.constructor) - n = o.constructor.name; - if (n === "Map" || n === "Set") - return Array.from(o); - if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) - return _arrayLikeToArray(o, minLen); - } - function _arrayLikeToArray(arr, len) { - if (len == null || len > arr.length) - len = arr.length; - for (var i = 0, arr2 = new Array(len); i < len; i++) - arr2[i] = arr[i]; - return arr2; - } - function _nonIterableRest() { - throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); - } - var ansiColors = { - bold: ["1", "22"], - dim: ["2", "22"], - italic: ["3", "23"], - underline: ["4", "24"], - // 5 & 6 are blinking - inverse: ["7", "27"], - hidden: ["8", "28"], - strike: ["9", "29"], - // 10-20 are fonts - // 21-29 are resets for 1-9 - black: ["30", "39"], - red: ["31", "39"], - green: ["32", "39"], - yellow: ["33", "39"], - blue: ["34", "39"], - magenta: ["35", "39"], - cyan: ["36", "39"], - white: ["37", "39"], - brightblack: ["30;1", "39"], - brightred: ["31;1", "39"], - brightgreen: ["32;1", "39"], - brightyellow: ["33;1", "39"], - brightblue: ["34;1", "39"], - brightmagenta: ["35;1", "39"], - brightcyan: ["36;1", "39"], - brightwhite: ["37;1", "39"], - grey: ["90", "39"] - }; - var styles = { - special: "cyan", - number: "yellow", - bigint: "yellow", - boolean: "yellow", - undefined: "grey", - null: "bold", - string: "green", - symbol: "green", - date: "magenta", - regexp: "red" - }; - var truncator = "\u2026"; - function colorise(value, styleType) { - var color = ansiColors[styles[styleType]] || ansiColors[styleType]; - if (!color) { - return String(value); - } - return "\x1B[".concat(color[0], "m").concat(String(value), "\x1B[").concat(color[1], "m"); - } - function normaliseOptions() { - var _ref = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {}, _ref$showHidden = _ref.showHidden, showHidden = _ref$showHidden === void 0 ? false : _ref$showHidden, _ref$depth = _ref.depth, depth = _ref$depth === void 0 ? 2 : _ref$depth, _ref$colors = _ref.colors, colors = _ref$colors === void 0 ? false : _ref$colors, _ref$customInspect = _ref.customInspect, customInspect = _ref$customInspect === void 0 ? true : _ref$customInspect, _ref$showProxy = _ref.showProxy, showProxy = _ref$showProxy === void 0 ? false : _ref$showProxy, _ref$maxArrayLength = _ref.maxArrayLength, maxArrayLength = _ref$maxArrayLength === void 0 ? Infinity : _ref$maxArrayLength, _ref$breakLength = _ref.breakLength, breakLength = _ref$breakLength === void 0 ? Infinity : _ref$breakLength, _ref$seen = _ref.seen, seen = _ref$seen === void 0 ? [] : _ref$seen, _ref$truncate = _ref.truncate, truncate2 = _ref$truncate === void 0 ? Infinity : _ref$truncate, _ref$stylize = _ref.stylize, stylize = _ref$stylize === void 0 ? String : _ref$stylize; - var options = { - showHidden: Boolean(showHidden), - depth: Number(depth), - colors: Boolean(colors), - customInspect: Boolean(customInspect), - showProxy: Boolean(showProxy), - maxArrayLength: Number(maxArrayLength), - breakLength: Number(breakLength), - truncate: Number(truncate2), - seen, - stylize - }; - if (options.colors) { - options.stylize = colorise; - } - return options; - } - function truncate(string, length) { - var tail = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : truncator; - string = String(string); - var tailLength = tail.length; - var stringLength = string.length; - if (tailLength > length && stringLength > tailLength) { - return tail; - } - if (stringLength > length && stringLength > tailLength) { - return "".concat(string.slice(0, length - tailLength)).concat(tail); - } - return string; - } - function inspectList(list, options, inspectItem) { - var separator = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : ", "; - inspectItem = inspectItem || options.inspect; - var size = list.length; - if (size === 0) - return ""; - var originalLength = options.truncate; - var output = ""; - var peek = ""; - var truncated = ""; - for (var i = 0; i < size; i += 1) { - var last = i + 1 === list.length; - var secondToLast = i + 2 === list.length; - truncated = "".concat(truncator, "(").concat(list.length - i, ")"); - var value = list[i]; - options.truncate = originalLength - output.length - (last ? 0 : separator.length); - var string = peek || inspectItem(value, options) + (last ? "" : separator); - var nextLength = output.length + string.length; - var truncatedLength = nextLength + truncated.length; - if (last && nextLength > originalLength && output.length + truncated.length <= originalLength) { - break; - } - if (!last && !secondToLast && truncatedLength > originalLength) { - break; - } - peek = last ? "" : inspectItem(list[i + 1], options) + (secondToLast ? "" : separator); - if (!last && secondToLast && truncatedLength > originalLength && nextLength + peek.length > originalLength) { - break; - } - output += string; - if (!last && !secondToLast && nextLength + peek.length >= originalLength) { - truncated = "".concat(truncator, "(").concat(list.length - i - 1, ")"); - break; - } - truncated = ""; - } - return "".concat(output).concat(truncated); - } - function quoteComplexKey(key) { - if (key.match(/^[a-zA-Z_][a-zA-Z_0-9]*$/)) { - return key; - } - return JSON.stringify(key).replace(/'/g, "\\'").replace(/\\"/g, '"').replace(/(^"|"$)/g, "'"); - } - function inspectProperty(_ref2, options) { - var _ref3 = _slicedToArray(_ref2, 2), key = _ref3[0], value = _ref3[1]; - options.truncate -= 2; - if (typeof key === "string") { - key = quoteComplexKey(key); - } else if (typeof key !== "number") { - key = "[".concat(options.inspect(key, options), "]"); - } - options.truncate -= key.length; - value = options.inspect(value, options); - return "".concat(key, ": ").concat(value); - } - function inspectArray(array, options) { - var nonIndexProperties = Object.keys(array).slice(array.length); - if (!array.length && !nonIndexProperties.length) - return "[]"; - options.truncate -= 4; - var listContents = inspectList(array, options); - options.truncate -= listContents.length; - var propertyContents = ""; - if (nonIndexProperties.length) { - propertyContents = inspectList(nonIndexProperties.map(function(key) { - return [key, array[key]]; - }), options, inspectProperty); - } - return "[ ".concat(listContents).concat(propertyContents ? ", ".concat(propertyContents) : "", " ]"); - } - var toString = Function.prototype.toString; - var functionNameMatch = /\s*function(?:\s|\s*\/\*[^(?:*\/)]+\*\/\s*)*([^\s\(\/]+)/; - function getFuncName(aFunc) { - if (typeof aFunc !== "function") { - return null; - } - var name = ""; - if (typeof Function.prototype.name === "undefined" && typeof aFunc.name === "undefined") { - var match = toString.call(aFunc).match(functionNameMatch); - if (match) { - name = match[1]; - } - } else { - name = aFunc.name; - } - return name; - } - var getFuncName_1 = getFuncName; - var getArrayName = function getArrayName2(array) { - if (typeof Buffer === "function" && array instanceof Buffer) { - return "Buffer"; - } - if (array[Symbol.toStringTag]) { - return array[Symbol.toStringTag]; - } - return getFuncName_1(array.constructor); - }; - function inspectTypedArray(array, options) { - var name = getArrayName(array); - options.truncate -= name.length + 4; - var nonIndexProperties = Object.keys(array).slice(array.length); - if (!array.length && !nonIndexProperties.length) - return "".concat(name, "[]"); - var output = ""; - for (var i = 0; i < array.length; i++) { - var string = "".concat(options.stylize(truncate(array[i], options.truncate), "number")).concat(i === array.length - 1 ? "" : ", "); - options.truncate -= string.length; - if (array[i] !== array.length && options.truncate <= 3) { - output += "".concat(truncator, "(").concat(array.length - array[i] + 1, ")"); - break; - } - output += string; - } - var propertyContents = ""; - if (nonIndexProperties.length) { - propertyContents = inspectList(nonIndexProperties.map(function(key) { - return [key, array[key]]; - }), options, inspectProperty); - } - return "".concat(name, "[ ").concat(output).concat(propertyContents ? ", ".concat(propertyContents) : "", " ]"); - } - function inspectDate(dateObject, options) { - var stringRepresentation = dateObject.toJSON(); - if (stringRepresentation === null) { - return "Invalid Date"; - } - var split = stringRepresentation.split("T"); - var date = split[0]; - return options.stylize("".concat(date, "T").concat(truncate(split[1], options.truncate - date.length - 1)), "date"); - } - function inspectFunction(func, options) { - var name = getFuncName_1(func); - if (!name) { - return options.stylize("[Function]", "special"); - } - return options.stylize("[Function ".concat(truncate(name, options.truncate - 11), "]"), "special"); - } - function inspectMapEntry(_ref, options) { - var _ref2 = _slicedToArray(_ref, 2), key = _ref2[0], value = _ref2[1]; - options.truncate -= 4; - key = options.inspect(key, options); - options.truncate -= key.length; - value = options.inspect(value, options); - return "".concat(key, " => ").concat(value); - } - function mapToEntries(map) { - var entries = []; - map.forEach(function(value, key) { - entries.push([key, value]); - }); - return entries; - } - function inspectMap(map, options) { - var size = map.size - 1; - if (size <= 0) { - return "Map{}"; - } - options.truncate -= 7; - return "Map{ ".concat(inspectList(mapToEntries(map), options, inspectMapEntry), " }"); - } - var isNaN2 = Number.isNaN || function(i) { - return i !== i; - }; - function inspectNumber(number, options) { - if (isNaN2(number)) { - return options.stylize("NaN", "number"); - } - if (number === Infinity) { - return options.stylize("Infinity", "number"); - } - if (number === -Infinity) { - return options.stylize("-Infinity", "number"); - } - if (number === 0) { - return options.stylize(1 / number === Infinity ? "+0" : "-0", "number"); - } - return options.stylize(truncate(number, options.truncate), "number"); - } - function inspectBigInt(number, options) { - var nums = truncate(number.toString(), options.truncate - 1); - if (nums !== truncator) - nums += "n"; - return options.stylize(nums, "bigint"); - } - function inspectRegExp(value, options) { - var flags = value.toString().split("/")[2]; - var sourceLength = options.truncate - (2 + flags.length); - var source = value.source; - return options.stylize("/".concat(truncate(source, sourceLength), "/").concat(flags), "regexp"); - } - function arrayFromSet(set) { - var values = []; - set.forEach(function(value) { - values.push(value); - }); - return values; - } - function inspectSet(set, options) { - if (set.size === 0) - return "Set{}"; - options.truncate -= 7; - return "Set{ ".concat(inspectList(arrayFromSet(set), options), " }"); - } - var stringEscapeChars = new RegExp("['\\u0000-\\u001f\\u007f-\\u009f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]", "g"); - var escapeCharacters = { - "\b": "\\b", - " ": "\\t", - "\n": "\\n", - "\f": "\\f", - "\r": "\\r", - "'": "\\'", - "\\": "\\\\" - }; - var hex = 16; - var unicodeLength = 4; - function escape2(char) { - return escapeCharacters[char] || "\\u".concat("0000".concat(char.charCodeAt(0).toString(hex)).slice(-unicodeLength)); - } - function inspectString(string, options) { - if (stringEscapeChars.test(string)) { - string = string.replace(stringEscapeChars, escape2); - } - return options.stylize("'".concat(truncate(string, options.truncate - 2), "'"), "string"); - } - function inspectSymbol(value) { - if ("description" in Symbol.prototype) { - return value.description ? "Symbol(".concat(value.description, ")") : "Symbol()"; - } - return value.toString(); - } - var getPromiseValue = function getPromiseValue2() { - return "Promise{\u2026}"; - }; - try { - var _process$binding = process.binding("util"), getPromiseDetails = _process$binding.getPromiseDetails, kPending = _process$binding.kPending, kRejected = _process$binding.kRejected; - if (Array.isArray(getPromiseDetails(Promise.resolve()))) { - getPromiseValue = function getPromiseValue2(value, options) { - var _getPromiseDetails = getPromiseDetails(value), _getPromiseDetails2 = _slicedToArray(_getPromiseDetails, 2), state = _getPromiseDetails2[0], innerValue = _getPromiseDetails2[1]; - if (state === kPending) { - return "Promise{<pending>}"; - } - return "Promise".concat(state === kRejected ? "!" : "", "{").concat(options.inspect(innerValue, options), "}"); - }; - } - } catch (notNode) { - } - var inspectPromise = getPromiseValue; - function inspectObject(object, options) { - var properties = Object.getOwnPropertyNames(object); - var symbols = Object.getOwnPropertySymbols ? Object.getOwnPropertySymbols(object) : []; - if (properties.length === 0 && symbols.length === 0) { - return "{}"; - } - options.truncate -= 4; - options.seen = options.seen || []; - if (options.seen.indexOf(object) >= 0) { - return "[Circular]"; - } - options.seen.push(object); - var propertyContents = inspectList(properties.map(function(key) { - return [key, object[key]]; - }), options, inspectProperty); - var symbolContents = inspectList(symbols.map(function(key) { - return [key, object[key]]; - }), options, inspectProperty); - options.seen.pop(); - var sep = ""; - if (propertyContents && symbolContents) { - sep = ", "; - } - return "{ ".concat(propertyContents).concat(sep).concat(symbolContents, " }"); - } - var toStringTag = typeof Symbol !== "undefined" && Symbol.toStringTag ? Symbol.toStringTag : false; - function inspectClass(value, options) { - var name = ""; - if (toStringTag && toStringTag in value) { - name = value[toStringTag]; - } - name = name || getFuncName_1(value.constructor); - if (!name || name === "_class") { - name = "<Anonymous Class>"; - } - options.truncate -= name.length; - return "".concat(name).concat(inspectObject(value, options)); - } - function inspectArguments(args, options) { - if (args.length === 0) - return "Arguments[]"; - options.truncate -= 13; - return "Arguments[ ".concat(inspectList(args, options), " ]"); - } - var errorKeys = ["stack", "line", "column", "name", "message", "fileName", "lineNumber", "columnNumber", "number", "description"]; - function inspectObject$1(error, options) { - var properties = Object.getOwnPropertyNames(error).filter(function(key) { - return errorKeys.indexOf(key) === -1; - }); - var name = error.name; - options.truncate -= name.length; - var message = ""; - if (typeof error.message === "string") { - message = truncate(error.message, options.truncate); - } else { - properties.unshift("message"); - } - message = message ? ": ".concat(message) : ""; - options.truncate -= message.length + 5; - var propertyContents = inspectList(properties.map(function(key) { - return [key, error[key]]; - }), options, inspectProperty); - return "".concat(name).concat(message).concat(propertyContents ? " { ".concat(propertyContents, " }") : ""); - } - function inspectAttribute(_ref, options) { - var _ref2 = _slicedToArray(_ref, 2), key = _ref2[0], value = _ref2[1]; - options.truncate -= 3; - if (!value) { - return "".concat(options.stylize(key, "yellow")); - } - return "".concat(options.stylize(key, "yellow"), "=").concat(options.stylize('"'.concat(value, '"'), "string")); - } - function inspectHTMLCollection(collection, options) { - return inspectList(collection, options, inspectHTML, "\n"); - } - function inspectHTML(element, options) { - var properties = element.getAttributeNames(); - var name = element.tagName.toLowerCase(); - var head = options.stylize("<".concat(name), "special"); - var headClose = options.stylize(">", "special"); - var tail = options.stylize("</".concat(name, ">"), "special"); - options.truncate -= name.length * 2 + 5; - var propertyContents = ""; - if (properties.length > 0) { - propertyContents += " "; - propertyContents += inspectList(properties.map(function(key) { - return [key, element.getAttribute(key)]; - }), options, inspectAttribute, " "); - } - options.truncate -= propertyContents.length; - var truncate2 = options.truncate; - var children = inspectHTMLCollection(element.children, options); - if (children && children.length > truncate2) { - children = "".concat(truncator, "(").concat(element.children.length, ")"); - } - return "".concat(head).concat(propertyContents).concat(headClose).concat(children).concat(tail); - } - var symbolsSupported = typeof Symbol === "function" && typeof Symbol.for === "function"; - var chaiInspect = symbolsSupported ? Symbol.for("chai/inspect") : "@@chai/inspect"; - var nodeInspect = false; - try { - var nodeUtil = require_util(); - nodeInspect = nodeUtil.inspect ? nodeUtil.inspect.custom : false; - } catch (noNodeInspect) { - nodeInspect = false; - } - function FakeMap() { - this.key = "chai/loupe__" + Math.random() + Date.now(); - } - FakeMap.prototype = { - // eslint-disable-next-line object-shorthand - get: function get(key) { - return key[this.key]; - }, - // eslint-disable-next-line object-shorthand - has: function has(key) { - return this.key in key; - }, - // eslint-disable-next-line object-shorthand - set: function set(key, value) { - if (Object.isExtensible(key)) { - Object.defineProperty(key, this.key, { - // eslint-disable-next-line object-shorthand - value, - configurable: true - }); - } - } - }; - var constructorMap = new (typeof WeakMap === "function" ? WeakMap : FakeMap)(); - var stringTagMap = {}; - var baseTypesMap = { - undefined: function undefined$1(value, options) { - return options.stylize("undefined", "undefined"); - }, - null: function _null(value, options) { - return options.stylize(null, "null"); - }, - boolean: function boolean(value, options) { - return options.stylize(value, "boolean"); - }, - Boolean: function Boolean3(value, options) { - return options.stylize(value, "boolean"); - }, - number: inspectNumber, - Number: inspectNumber, - bigint: inspectBigInt, - BigInt: inspectBigInt, - string: inspectString, - String: inspectString, - function: inspectFunction, - Function: inspectFunction, - symbol: inspectSymbol, - // A Symbol polyfill will return `Symbol` not `symbol` from typedetect - Symbol: inspectSymbol, - Array: inspectArray, - Date: inspectDate, - Map: inspectMap, - Set: inspectSet, - RegExp: inspectRegExp, - Promise: inspectPromise, - // WeakSet, WeakMap are totally opaque to us - WeakSet: function WeakSet2(value, options) { - return options.stylize("WeakSet{\u2026}", "special"); - }, - WeakMap: function WeakMap2(value, options) { - return options.stylize("WeakMap{\u2026}", "special"); - }, - Arguments: inspectArguments, - Int8Array: inspectTypedArray, - Uint8Array: inspectTypedArray, - Uint8ClampedArray: inspectTypedArray, - Int16Array: inspectTypedArray, - Uint16Array: inspectTypedArray, - Int32Array: inspectTypedArray, - Uint32Array: inspectTypedArray, - Float32Array: inspectTypedArray, - Float64Array: inspectTypedArray, - Generator: function Generator() { - return ""; - }, - DataView: function DataView2() { - return ""; - }, - ArrayBuffer: function ArrayBuffer2() { - return ""; - }, - Error: inspectObject$1, - HTMLCollection: inspectHTMLCollection, - NodeList: inspectHTMLCollection - }; - var inspectCustom = function inspectCustom2(value, options, type) { - if (chaiInspect in value && typeof value[chaiInspect] === "function") { - return value[chaiInspect](options); - } - if (nodeInspect && nodeInspect in value && typeof value[nodeInspect] === "function") { - return value[nodeInspect](options.depth, options); - } - if ("inspect" in value && typeof value.inspect === "function") { - return value.inspect(options.depth, options); - } - if ("constructor" in value && constructorMap.has(value.constructor)) { - return constructorMap.get(value.constructor)(value, options); - } - if (stringTagMap[type]) { - return stringTagMap[type](value, options); - } - return ""; - }; - var toString$1 = Object.prototype.toString; - function inspect(value, options) { - options = normaliseOptions(options); - options.inspect = inspect; - var _options = options, customInspect = _options.customInspect; - var type = value === null ? "null" : _typeof(value); - if (type === "object") { - type = toString$1.call(value).slice(8, -1); - } - if (baseTypesMap[type]) { - return baseTypesMap[type](value, options); - } - if (customInspect && value) { - var output = inspectCustom(value, options, type); - if (output) { - if (typeof output === "string") - return output; - return inspect(output, options); - } - } - var proto = value ? Object.getPrototypeOf(value) : false; - if (proto === Object.prototype || proto === null) { - return inspectObject(value, options); - } - if (value && typeof HTMLElement === "function" && value instanceof HTMLElement) { - return inspectHTML(value, options); - } - if ("constructor" in value) { - if (value.constructor !== Object) { - return inspectClass(value, options); - } - return inspectObject(value, options); - } - if (value === Object(value)) { - return inspectObject(value, options); - } - return options.stylize(String(value), type); - } - function registerConstructor(constructor, inspector) { - if (constructorMap.has(constructor)) { - return false; - } - constructorMap.set(constructor, inspector); - return true; - } - function registerStringTag(stringTag, inspector) { - if (stringTag in stringTagMap) { - return false; - } - stringTagMap[stringTag] = inspector; - return true; - } - var custom = chaiInspect; - exports2.custom = custom; - exports2.default = inspect; - exports2.inspect = inspect; - exports2.registerConstructor = registerConstructor; - exports2.registerStringTag = registerStringTag; - Object.defineProperty(exports2, "__esModule", { value: true }); - }); - } - }); - - // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/config.js - var require_config = __commonJS({ - "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/config.js"(exports, module) { - module.exports = { - /** - * ### config.includeStack - * - * User configurable property, influences whether stack trace - * is included in Assertion error message. Default of false - * suppresses stack trace in the error message. - * - * chai.config.includeStack = true; // enable stack on error - * - * @param {Boolean} - * @api public - */ - includeStack: false, - /** - * ### config.showDiff - * - * User configurable property, influences whether or not - * the `showDiff` flag should be included in the thrown - * AssertionErrors. `false` will always be `false`; `true` - * will be true when the assertion has requested a diff - * be shown. - * - * @param {Boolean} - * @api public - */ - showDiff: true, - /** - * ### config.truncateThreshold - * - * User configurable property, sets length threshold for actual and - * expected values in assertion errors. If this threshold is exceeded, for - * example for large data structures, the value is replaced with something - * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`. - * - * Set it to zero if you want to disable truncating altogether. - * - * This is especially userful when doing assertions on arrays: having this - * set to a reasonable large value makes the failure messages readily - * inspectable. - * - * chai.config.truncateThreshold = 0; // disable truncating - * - * @param {Number} - * @api public - */ - truncateThreshold: 40, - /** - * ### config.useProxy - * - * User configurable property, defines if chai will use a Proxy to throw - * an error when a non-existent property is read, which protects users - * from typos when using property-based assertions. - * - * Set it to false if you want to disable this feature. - * - * chai.config.useProxy = false; // disable use of Proxy - * - * This feature is automatically disabled regardless of this config value - * in environments that don't support proxies. - * - * @param {Boolean} - * @api public - */ - useProxy: true, - /** - * ### config.proxyExcludedKeys - * - * User configurable property, defines which properties should be ignored - * instead of throwing an error if they do not exist on the assertion. - * This is only applied if the environment Chai is running in supports proxies and - * if the `useProxy` configuration setting is enabled. - * By default, `then` and `inspect` will not throw an error if they do not exist on the - * assertion object because the `.inspect` property is read by `util.inspect` (for example, when - * using `console.log` on the assertion object) and `.then` is necessary for promise type-checking. - * - * // By default these keys will not throw an error if they do not exist on the assertion object - * chai.config.proxyExcludedKeys = ['then', 'inspect']; - * - * @param {Array} - * @api public - */ - proxyExcludedKeys: ["then", "catch", "inspect", "toJSON"] - }; - } - }); - - // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/inspect.js - var require_inspect = __commonJS({ - "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/inspect.js"(exports, module) { - var getName = require_get_func_name(); - var loupe = require_loupe(); - var config2 = require_config(); - module.exports = inspect; - function inspect(obj, showHidden, depth, colors) { - var options = { - colors, - depth: typeof depth === "undefined" ? 2 : depth, - showHidden, - truncate: config2.truncateThreshold ? config2.truncateThreshold : Infinity - }; - return loupe.inspect(obj, options); - } - } - }); - - // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/objDisplay.js - var require_objDisplay = __commonJS({ - "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/objDisplay.js"(exports, module) { - var inspect = require_inspect(); - var config2 = require_config(); - module.exports = function objDisplay(obj) { - var str = inspect(obj), type = Object.prototype.toString.call(obj); - if (config2.truncateThreshold && str.length >= config2.truncateThreshold) { - if (type === "[object Function]") { - return !obj.name || obj.name === "" ? "[Function]" : "[Function: " + obj.name + "]"; - } else if (type === "[object Array]") { - return "[ Array(" + obj.length + ") ]"; - } else if (type === "[object Object]") { - var keys = Object.keys(obj), kstr = keys.length > 2 ? keys.splice(0, 2).join(", ") + ", ..." : keys.join(", "); - return "{ Object (" + kstr + ") }"; - } else { - return str; - } - } else { - return str; - } - }; - } - }); - - // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/getMessage.js - var require_getMessage = __commonJS({ - "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/getMessage.js"(exports, module) { - var flag = require_flag(); - var getActual = require_getActual(); - var objDisplay = require_objDisplay(); - module.exports = function getMessage(obj, args) { - var negate = flag(obj, "negate"), val = flag(obj, "object"), expected = args[3], actual = getActual(obj, args), msg = negate ? args[2] : args[1], flagMsg = flag(obj, "message"); - if (typeof msg === "function") - msg = msg(); - msg = msg || ""; - msg = msg.replace(/#\{this\}/g, function() { - return objDisplay(val); - }).replace(/#\{act\}/g, function() { - return objDisplay(actual); - }).replace(/#\{exp\}/g, function() { - return objDisplay(expected); - }); - return flagMsg ? flagMsg + ": " + msg : msg; - }; - } - }); - - // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/transferFlags.js - var require_transferFlags = __commonJS({ - "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/transferFlags.js"(exports, module) { - module.exports = function transferFlags(assertion, object, includeAll) { - var flags = assertion.__flags || (assertion.__flags = /* @__PURE__ */ Object.create(null)); - if (!object.__flags) { - object.__flags = /* @__PURE__ */ Object.create(null); - } - includeAll = arguments.length === 3 ? includeAll : true; - for (var flag in flags) { - if (includeAll || flag !== "object" && flag !== "ssfi" && flag !== "lockSsfi" && flag != "message") { - object.__flags[flag] = flags[flag]; - } - } - }; - } - }); - - // node_modules/.pnpm/deep-eql@4.1.3/node_modules/deep-eql/index.js - var require_deep_eql = __commonJS({ - "node_modules/.pnpm/deep-eql@4.1.3/node_modules/deep-eql/index.js"(exports, module) { - "use strict"; - var type = require_type_detect(); - function FakeMap() { - this._key = "chai/deep-eql__" + Math.random() + Date.now(); - } - FakeMap.prototype = { - get: function get(key) { - return key[this._key]; - }, - set: function set(key, value) { - if (Object.isExtensible(key)) { - Object.defineProperty(key, this._key, { - value, - configurable: true - }); - } - } - }; - var MemoizeMap = typeof WeakMap === "function" ? WeakMap : FakeMap; - function memoizeCompare(leftHandOperand, rightHandOperand, memoizeMap) { - if (!memoizeMap || isPrimitive2(leftHandOperand) || isPrimitive2(rightHandOperand)) { - return null; - } - var leftHandMap = memoizeMap.get(leftHandOperand); - if (leftHandMap) { - var result = leftHandMap.get(rightHandOperand); - if (typeof result === "boolean") { - return result; - } - } - return null; - } - function memoizeSet(leftHandOperand, rightHandOperand, memoizeMap, result) { - if (!memoizeMap || isPrimitive2(leftHandOperand) || isPrimitive2(rightHandOperand)) { - return; - } - var leftHandMap = memoizeMap.get(leftHandOperand); - if (leftHandMap) { - leftHandMap.set(rightHandOperand, result); - } else { - leftHandMap = new MemoizeMap(); - leftHandMap.set(rightHandOperand, result); - memoizeMap.set(leftHandOperand, leftHandMap); - } - } - module.exports = deepEqual; - module.exports.MemoizeMap = MemoizeMap; - function deepEqual(leftHandOperand, rightHandOperand, options) { - if (options && options.comparator) { - return extensiveDeepEqual(leftHandOperand, rightHandOperand, options); - } - var simpleResult = simpleEqual(leftHandOperand, rightHandOperand); - if (simpleResult !== null) { - return simpleResult; - } - return extensiveDeepEqual(leftHandOperand, rightHandOperand, options); - } - function simpleEqual(leftHandOperand, rightHandOperand) { - if (leftHandOperand === rightHandOperand) { - return leftHandOperand !== 0 || 1 / leftHandOperand === 1 / rightHandOperand; - } - if (leftHandOperand !== leftHandOperand && // eslint-disable-line no-self-compare - rightHandOperand !== rightHandOperand) { - return true; - } - if (isPrimitive2(leftHandOperand) || isPrimitive2(rightHandOperand)) { - return false; - } - return null; - } - function extensiveDeepEqual(leftHandOperand, rightHandOperand, options) { - options = options || {}; - options.memoize = options.memoize === false ? false : options.memoize || new MemoizeMap(); - var comparator = options && options.comparator; - var memoizeResultLeft = memoizeCompare(leftHandOperand, rightHandOperand, options.memoize); - if (memoizeResultLeft !== null) { - return memoizeResultLeft; - } - var memoizeResultRight = memoizeCompare(rightHandOperand, leftHandOperand, options.memoize); - if (memoizeResultRight !== null) { - return memoizeResultRight; - } - if (comparator) { - var comparatorResult = comparator(leftHandOperand, rightHandOperand); - if (comparatorResult === false || comparatorResult === true) { - memoizeSet(leftHandOperand, rightHandOperand, options.memoize, comparatorResult); - return comparatorResult; - } - var simpleResult = simpleEqual(leftHandOperand, rightHandOperand); - if (simpleResult !== null) { - return simpleResult; - } - } - var leftHandType = type(leftHandOperand); - if (leftHandType !== type(rightHandOperand)) { - memoizeSet(leftHandOperand, rightHandOperand, options.memoize, false); - return false; - } - memoizeSet(leftHandOperand, rightHandOperand, options.memoize, true); - var result = extensiveDeepEqualByType(leftHandOperand, rightHandOperand, leftHandType, options); - memoizeSet(leftHandOperand, rightHandOperand, options.memoize, result); - return result; - } - function extensiveDeepEqualByType(leftHandOperand, rightHandOperand, leftHandType, options) { - switch (leftHandType) { - case "String": - case "Number": - case "Boolean": - case "Date": - return deepEqual(leftHandOperand.valueOf(), rightHandOperand.valueOf()); - case "Promise": - case "Symbol": - case "function": - case "WeakMap": - case "WeakSet": - return leftHandOperand === rightHandOperand; - case "Error": - return keysEqual(leftHandOperand, rightHandOperand, ["name", "message", "code"], options); - case "Arguments": - case "Int8Array": - case "Uint8Array": - case "Uint8ClampedArray": - case "Int16Array": - case "Uint16Array": - case "Int32Array": - case "Uint32Array": - case "Float32Array": - case "Float64Array": - case "Array": - return iterableEqual(leftHandOperand, rightHandOperand, options); - case "RegExp": - return regexpEqual(leftHandOperand, rightHandOperand); - case "Generator": - return generatorEqual(leftHandOperand, rightHandOperand, options); - case "DataView": - return iterableEqual(new Uint8Array(leftHandOperand.buffer), new Uint8Array(rightHandOperand.buffer), options); - case "ArrayBuffer": - return iterableEqual(new Uint8Array(leftHandOperand), new Uint8Array(rightHandOperand), options); - case "Set": - return entriesEqual(leftHandOperand, rightHandOperand, options); - case "Map": - return entriesEqual(leftHandOperand, rightHandOperand, options); - case "Temporal.PlainDate": - case "Temporal.PlainTime": - case "Temporal.PlainDateTime": - case "Temporal.Instant": - case "Temporal.ZonedDateTime": - case "Temporal.PlainYearMonth": - case "Temporal.PlainMonthDay": - return leftHandOperand.equals(rightHandOperand); - case "Temporal.Duration": - return leftHandOperand.total("nanoseconds") === rightHandOperand.total("nanoseconds"); - case "Temporal.TimeZone": - case "Temporal.Calendar": - return leftHandOperand.toString() === rightHandOperand.toString(); - default: - return objectEqual(leftHandOperand, rightHandOperand, options); - } - } - function regexpEqual(leftHandOperand, rightHandOperand) { - return leftHandOperand.toString() === rightHandOperand.toString(); - } - function entriesEqual(leftHandOperand, rightHandOperand, options) { - if (leftHandOperand.size !== rightHandOperand.size) { - return false; - } - if (leftHandOperand.size === 0) { - return true; - } - var leftHandItems = []; - var rightHandItems = []; - leftHandOperand.forEach(function gatherEntries(key, value) { - leftHandItems.push([key, value]); - }); - rightHandOperand.forEach(function gatherEntries(key, value) { - rightHandItems.push([key, value]); - }); - return iterableEqual(leftHandItems.sort(), rightHandItems.sort(), options); - } - function iterableEqual(leftHandOperand, rightHandOperand, options) { - var length = leftHandOperand.length; - if (length !== rightHandOperand.length) { - return false; - } - if (length === 0) { - return true; - } - var index = -1; - while (++index < length) { - if (deepEqual(leftHandOperand[index], rightHandOperand[index], options) === false) { - return false; - } - } - return true; - } - function generatorEqual(leftHandOperand, rightHandOperand, options) { - return iterableEqual(getGeneratorEntries(leftHandOperand), getGeneratorEntries(rightHandOperand), options); - } - function hasIteratorFunction(target) { - return typeof Symbol !== "undefined" && typeof target === "object" && typeof Symbol.iterator !== "undefined" && typeof target[Symbol.iterator] === "function"; - } - function getIteratorEntries(target) { - if (hasIteratorFunction(target)) { - try { - return getGeneratorEntries(target[Symbol.iterator]()); - } catch (iteratorError) { - return []; - } - } - return []; - } - function getGeneratorEntries(generator) { - var generatorResult = generator.next(); - var accumulator = [generatorResult.value]; - while (generatorResult.done === false) { - generatorResult = generator.next(); - accumulator.push(generatorResult.value); - } - return accumulator; - } - function getEnumerableKeys(target) { - var keys = []; - for (var key in target) { - keys.push(key); - } - return keys; - } - function getEnumerableSymbols(target) { - var keys = []; - var allKeys = Object.getOwnPropertySymbols(target); - for (var i = 0; i < allKeys.length; i += 1) { - var key = allKeys[i]; - if (Object.getOwnPropertyDescriptor(target, key).enumerable) { - keys.push(key); - } - } - return keys; - } - function keysEqual(leftHandOperand, rightHandOperand, keys, options) { - var length = keys.length; - if (length === 0) { - return true; - } - for (var i = 0; i < length; i += 1) { - if (deepEqual(leftHandOperand[keys[i]], rightHandOperand[keys[i]], options) === false) { - return false; - } - } - return true; - } - function objectEqual(leftHandOperand, rightHandOperand, options) { - var leftHandKeys = getEnumerableKeys(leftHandOperand); - var rightHandKeys = getEnumerableKeys(rightHandOperand); - var leftHandSymbols = getEnumerableSymbols(leftHandOperand); - var rightHandSymbols = getEnumerableSymbols(rightHandOperand); - leftHandKeys = leftHandKeys.concat(leftHandSymbols); - rightHandKeys = rightHandKeys.concat(rightHandSymbols); - if (leftHandKeys.length && leftHandKeys.length === rightHandKeys.length) { - if (iterableEqual(mapSymbols(leftHandKeys).sort(), mapSymbols(rightHandKeys).sort()) === false) { - return false; - } - return keysEqual(leftHandOperand, rightHandOperand, leftHandKeys, options); - } - var leftHandEntries = getIteratorEntries(leftHandOperand); - var rightHandEntries = getIteratorEntries(rightHandOperand); - if (leftHandEntries.length && leftHandEntries.length === rightHandEntries.length) { - leftHandEntries.sort(); - rightHandEntries.sort(); - return iterableEqual(leftHandEntries, rightHandEntries, options); - } - if (leftHandKeys.length === 0 && leftHandEntries.length === 0 && rightHandKeys.length === 0 && rightHandEntries.length === 0) { - return true; - } - return false; - } - function isPrimitive2(value) { - return value === null || typeof value !== "object"; - } - function mapSymbols(arr) { - return arr.map(function mapSymbol(entry) { - if (typeof entry === "symbol") { - return entry.toString(); - } - return entry; - }); - } - } - }); - - // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/isProxyEnabled.js - var require_isProxyEnabled = __commonJS({ - "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/isProxyEnabled.js"(exports, module) { - var config2 = require_config(); - module.exports = function isProxyEnabled() { - return config2.useProxy && typeof Proxy !== "undefined" && typeof Reflect !== "undefined"; - }; - } - }); - - // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/addProperty.js - var require_addProperty = __commonJS({ - "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/addProperty.js"(exports, module) { - var chai2 = require_chai(); - var flag = require_flag(); - var isProxyEnabled = require_isProxyEnabled(); - var transferFlags = require_transferFlags(); - module.exports = function addProperty(ctx, name, getter) { - getter = getter === void 0 ? function() { - } : getter; - Object.defineProperty( - ctx, - name, - { - get: function propertyGetter() { - if (!isProxyEnabled() && !flag(this, "lockSsfi")) { - flag(this, "ssfi", propertyGetter); - } - var result = getter.call(this); - if (result !== void 0) - return result; - var newAssertion = new chai2.Assertion(); - transferFlags(this, newAssertion); - return newAssertion; - }, - configurable: true - } - ); - }; - } - }); - - // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/addLengthGuard.js - var require_addLengthGuard = __commonJS({ - "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/addLengthGuard.js"(exports, module) { - var fnLengthDesc = Object.getOwnPropertyDescriptor(function() { - }, "length"); - module.exports = function addLengthGuard(fn, assertionName, isChainable) { - if (!fnLengthDesc.configurable) - return fn; - Object.defineProperty(fn, "length", { - get: function() { - if (isChainable) { - throw Error("Invalid Chai property: " + assertionName + '.length. Due to a compatibility issue, "length" cannot directly follow "' + assertionName + '". Use "' + assertionName + '.lengthOf" instead.'); - } - throw Error("Invalid Chai property: " + assertionName + '.length. See docs for proper usage of "' + assertionName + '".'); - } - }); - return fn; - }; - } - }); - - // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/getProperties.js - var require_getProperties = __commonJS({ - "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/getProperties.js"(exports, module) { - module.exports = function getProperties(object) { - var result = Object.getOwnPropertyNames(object); - function addProperty(property) { - if (result.indexOf(property) === -1) { - result.push(property); - } - } - var proto = Object.getPrototypeOf(object); - while (proto !== null) { - Object.getOwnPropertyNames(proto).forEach(addProperty); - proto = Object.getPrototypeOf(proto); - } - return result; - }; - } - }); - - // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/proxify.js - var require_proxify = __commonJS({ - "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/proxify.js"(exports, module) { - var config2 = require_config(); - var flag = require_flag(); - var getProperties = require_getProperties(); - var isProxyEnabled = require_isProxyEnabled(); - var builtins = ["__flags", "__methods", "_obj", "assert"]; - module.exports = function proxify(obj, nonChainableMethodName) { - if (!isProxyEnabled()) - return obj; - return new Proxy(obj, { - get: function proxyGetter(target, property) { - if (typeof property === "string" && config2.proxyExcludedKeys.indexOf(property) === -1 && !Reflect.has(target, property)) { - if (nonChainableMethodName) { - throw Error("Invalid Chai property: " + nonChainableMethodName + "." + property + '. See docs for proper usage of "' + nonChainableMethodName + '".'); - } - var suggestion = null; - var suggestionDistance = 4; - getProperties(target).forEach(function(prop) { - if (!Object.prototype.hasOwnProperty(prop) && builtins.indexOf(prop) === -1) { - var dist = stringDistanceCapped( - property, - prop, - suggestionDistance - ); - if (dist < suggestionDistance) { - suggestion = prop; - suggestionDistance = dist; - } - } - }); - if (suggestion !== null) { - throw Error("Invalid Chai property: " + property + '. Did you mean "' + suggestion + '"?'); - } else { - throw Error("Invalid Chai property: " + property); - } - } - if (builtins.indexOf(property) === -1 && !flag(target, "lockSsfi")) { - flag(target, "ssfi", proxyGetter); - } - return Reflect.get(target, property); - } - }); - }; - function stringDistanceCapped(strA, strB, cap) { - if (Math.abs(strA.length - strB.length) >= cap) { - return cap; - } - var memo = []; - for (var i = 0; i <= strA.length; i++) { - memo[i] = Array(strB.length + 1).fill(0); - memo[i][0] = i; - } - for (var j = 0; j < strB.length; j++) { - memo[0][j] = j; - } - for (var i = 1; i <= strA.length; i++) { - var ch = strA.charCodeAt(i - 1); - for (var j = 1; j <= strB.length; j++) { - if (Math.abs(i - j) >= cap) { - memo[i][j] = cap; - continue; - } - memo[i][j] = Math.min( - memo[i - 1][j] + 1, - memo[i][j - 1] + 1, - memo[i - 1][j - 1] + (ch === strB.charCodeAt(j - 1) ? 0 : 1) - ); - } - } - return memo[strA.length][strB.length]; - } - } - }); - - // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/addMethod.js - var require_addMethod = __commonJS({ - "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/addMethod.js"(exports, module) { - var addLengthGuard = require_addLengthGuard(); - var chai2 = require_chai(); - var flag = require_flag(); - var proxify = require_proxify(); - var transferFlags = require_transferFlags(); - module.exports = function addMethod(ctx, name, method) { - var methodWrapper = function() { - if (!flag(this, "lockSsfi")) { - flag(this, "ssfi", methodWrapper); - } - var result = method.apply(this, arguments); - if (result !== void 0) - return result; - var newAssertion = new chai2.Assertion(); - transferFlags(this, newAssertion); - return newAssertion; - }; - addLengthGuard(methodWrapper, name, false); - ctx[name] = proxify(methodWrapper, name); - }; - } - }); - - // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/overwriteProperty.js - var require_overwriteProperty = __commonJS({ - "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/overwriteProperty.js"(exports, module) { - var chai2 = require_chai(); - var flag = require_flag(); - var isProxyEnabled = require_isProxyEnabled(); - var transferFlags = require_transferFlags(); - module.exports = function overwriteProperty(ctx, name, getter) { - var _get = Object.getOwnPropertyDescriptor(ctx, name), _super = function() { - }; - if (_get && "function" === typeof _get.get) - _super = _get.get; - Object.defineProperty( - ctx, - name, - { - get: function overwritingPropertyGetter() { - if (!isProxyEnabled() && !flag(this, "lockSsfi")) { - flag(this, "ssfi", overwritingPropertyGetter); - } - var origLockSsfi = flag(this, "lockSsfi"); - flag(this, "lockSsfi", true); - var result = getter(_super).call(this); - flag(this, "lockSsfi", origLockSsfi); - if (result !== void 0) { - return result; - } - var newAssertion = new chai2.Assertion(); - transferFlags(this, newAssertion); - return newAssertion; - }, - configurable: true - } - ); - }; - } - }); - - // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/overwriteMethod.js - var require_overwriteMethod = __commonJS({ - "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/overwriteMethod.js"(exports, module) { - var addLengthGuard = require_addLengthGuard(); - var chai2 = require_chai(); - var flag = require_flag(); - var proxify = require_proxify(); - var transferFlags = require_transferFlags(); - module.exports = function overwriteMethod(ctx, name, method) { - var _method = ctx[name], _super = function() { - throw new Error(name + " is not a function"); - }; - if (_method && "function" === typeof _method) - _super = _method; - var overwritingMethodWrapper = function() { - if (!flag(this, "lockSsfi")) { - flag(this, "ssfi", overwritingMethodWrapper); - } - var origLockSsfi = flag(this, "lockSsfi"); - flag(this, "lockSsfi", true); - var result = method(_super).apply(this, arguments); - flag(this, "lockSsfi", origLockSsfi); - if (result !== void 0) { - return result; - } - var newAssertion = new chai2.Assertion(); - transferFlags(this, newAssertion); - return newAssertion; - }; - addLengthGuard(overwritingMethodWrapper, name, false); - ctx[name] = proxify(overwritingMethodWrapper, name); - }; - } - }); - - // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/addChainableMethod.js - var require_addChainableMethod = __commonJS({ - "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/addChainableMethod.js"(exports, module) { - var addLengthGuard = require_addLengthGuard(); - var chai2 = require_chai(); - var flag = require_flag(); - var proxify = require_proxify(); - var transferFlags = require_transferFlags(); - var canSetPrototype = typeof Object.setPrototypeOf === "function"; - var testFn = function() { - }; - var excludeNames = Object.getOwnPropertyNames(testFn).filter(function(name) { - var propDesc = Object.getOwnPropertyDescriptor(testFn, name); - if (typeof propDesc !== "object") - return true; - return !propDesc.configurable; - }); - var call = Function.prototype.call; - var apply = Function.prototype.apply; - module.exports = function addChainableMethod(ctx, name, method, chainingBehavior) { - if (typeof chainingBehavior !== "function") { - chainingBehavior = function() { - }; - } - var chainableBehavior = { - method, - chainingBehavior - }; - if (!ctx.__methods) { - ctx.__methods = {}; - } - ctx.__methods[name] = chainableBehavior; - Object.defineProperty( - ctx, - name, - { - get: function chainableMethodGetter() { - chainableBehavior.chainingBehavior.call(this); - var chainableMethodWrapper = function() { - if (!flag(this, "lockSsfi")) { - flag(this, "ssfi", chainableMethodWrapper); - } - var result = chainableBehavior.method.apply(this, arguments); - if (result !== void 0) { - return result; - } - var newAssertion = new chai2.Assertion(); - transferFlags(this, newAssertion); - return newAssertion; - }; - addLengthGuard(chainableMethodWrapper, name, true); - if (canSetPrototype) { - var prototype = Object.create(this); - prototype.call = call; - prototype.apply = apply; - Object.setPrototypeOf(chainableMethodWrapper, prototype); - } else { - var asserterNames = Object.getOwnPropertyNames(ctx); - asserterNames.forEach(function(asserterName) { - if (excludeNames.indexOf(asserterName) !== -1) { - return; - } - var pd = Object.getOwnPropertyDescriptor(ctx, asserterName); - Object.defineProperty(chainableMethodWrapper, asserterName, pd); - }); - } - transferFlags(this, chainableMethodWrapper); - return proxify(chainableMethodWrapper); - }, - configurable: true - } - ); - }; - } - }); - - // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/overwriteChainableMethod.js - var require_overwriteChainableMethod = __commonJS({ - "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/overwriteChainableMethod.js"(exports, module) { - var chai2 = require_chai(); - var transferFlags = require_transferFlags(); - module.exports = function overwriteChainableMethod(ctx, name, method, chainingBehavior) { - var chainableBehavior = ctx.__methods[name]; - var _chainingBehavior = chainableBehavior.chainingBehavior; - chainableBehavior.chainingBehavior = function overwritingChainableMethodGetter() { - var result = chainingBehavior(_chainingBehavior).call(this); - if (result !== void 0) { - return result; - } - var newAssertion = new chai2.Assertion(); - transferFlags(this, newAssertion); - return newAssertion; - }; - var _method = chainableBehavior.method; - chainableBehavior.method = function overwritingChainableMethodWrapper() { - var result = method(_method).apply(this, arguments); - if (result !== void 0) { - return result; - } - var newAssertion = new chai2.Assertion(); - transferFlags(this, newAssertion); - return newAssertion; - }; - }; - } - }); - - // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/compareByInspect.js - var require_compareByInspect = __commonJS({ - "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/compareByInspect.js"(exports, module) { - var inspect = require_inspect(); - module.exports = function compareByInspect(a2, b) { - return inspect(a2) < inspect(b) ? -1 : 1; - }; - } - }); - - // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/getOwnEnumerablePropertySymbols.js - var require_getOwnEnumerablePropertySymbols = __commonJS({ - "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/getOwnEnumerablePropertySymbols.js"(exports, module) { - module.exports = function getOwnEnumerablePropertySymbols(obj) { - if (typeof Object.getOwnPropertySymbols !== "function") - return []; - return Object.getOwnPropertySymbols(obj).filter(function(sym) { - return Object.getOwnPropertyDescriptor(obj, sym).enumerable; - }); - }; - } - }); - - // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/getOwnEnumerableProperties.js - var require_getOwnEnumerableProperties = __commonJS({ - "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/getOwnEnumerableProperties.js"(exports, module) { - var getOwnEnumerablePropertySymbols = require_getOwnEnumerablePropertySymbols(); - module.exports = function getOwnEnumerableProperties(obj) { - return Object.keys(obj).concat(getOwnEnumerablePropertySymbols(obj)); - }; - } - }); - - // node_modules/.pnpm/check-error@1.0.2/node_modules/check-error/index.js - var require_check_error = __commonJS({ - "node_modules/.pnpm/check-error@1.0.2/node_modules/check-error/index.js"(exports, module) { - "use strict"; - function compatibleInstance(thrown, errorLike) { - return errorLike instanceof Error && thrown === errorLike; - } - function compatibleConstructor(thrown, errorLike) { - if (errorLike instanceof Error) { - return thrown.constructor === errorLike.constructor || thrown instanceof errorLike.constructor; - } else if (errorLike.prototype instanceof Error || errorLike === Error) { - return thrown.constructor === errorLike || thrown instanceof errorLike; - } - return false; - } - function compatibleMessage(thrown, errMatcher) { - var comparisonString = typeof thrown === "string" ? thrown : thrown.message; - if (errMatcher instanceof RegExp) { - return errMatcher.test(comparisonString); - } else if (typeof errMatcher === "string") { - return comparisonString.indexOf(errMatcher) !== -1; - } - return false; - } - var functionNameMatch = /\s*function(?:\s|\s*\/\*[^(?:*\/)]+\*\/\s*)*([^\(\/]+)/; - function getFunctionName(constructorFn) { - var name = ""; - if (typeof constructorFn.name === "undefined") { - var match = String(constructorFn).match(functionNameMatch); - if (match) { - name = match[1]; - } - } else { - name = constructorFn.name; - } - return name; - } - function getConstructorName(errorLike) { - var constructorName = errorLike; - if (errorLike instanceof Error) { - constructorName = getFunctionName(errorLike.constructor); - } else if (typeof errorLike === "function") { - constructorName = getFunctionName(errorLike).trim() || getFunctionName(new errorLike()); - } - return constructorName; - } - function getMessage(errorLike) { - var msg = ""; - if (errorLike && errorLike.message) { - msg = errorLike.message; - } else if (typeof errorLike === "string") { - msg = errorLike; - } - return msg; - } - module.exports = { - compatibleInstance, - compatibleConstructor, - compatibleMessage, - getMessage, - getConstructorName - }; - } - }); - - // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/isNaN.js - var require_isNaN = __commonJS({ - "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/isNaN.js"(exports, module) { - function isNaN2(value) { - return value !== value; - } - module.exports = Number.isNaN || isNaN2; - } - }); - - // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/getOperator.js - var require_getOperator = __commonJS({ - "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/getOperator.js"(exports, module) { - var type = require_type_detect(); - var flag = require_flag(); - function isObjectType(obj) { - var objectType = type(obj); - var objectTypes = ["Array", "Object", "function"]; - return objectTypes.indexOf(objectType) !== -1; - } - module.exports = function getOperator2(obj, args) { - var operator = flag(obj, "operator"); - var negate = flag(obj, "negate"); - var expected = args[3]; - var msg = negate ? args[2] : args[1]; - if (operator) { - return operator; - } - if (typeof msg === "function") - msg = msg(); - msg = msg || ""; - if (!msg) { - return void 0; - } - if (/\shave\s/.test(msg)) { - return void 0; - } - var isObject2 = isObjectType(expected); - if (/\snot\s/.test(msg)) { - return isObject2 ? "notDeepStrictEqual" : "notStrictEqual"; - } - return isObject2 ? "deepStrictEqual" : "strictEqual"; - }; - } - }); - - // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/index.js - var require_utils = __commonJS({ - "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/index.js"(exports) { - var pathval = require_pathval(); - exports.test = require_test(); - exports.type = require_type_detect(); - exports.expectTypes = require_expectTypes(); - exports.getMessage = require_getMessage(); - exports.getActual = require_getActual(); - exports.inspect = require_inspect(); - exports.objDisplay = require_objDisplay(); - exports.flag = require_flag(); - exports.transferFlags = require_transferFlags(); - exports.eql = require_deep_eql(); - exports.getPathInfo = pathval.getPathInfo; - exports.hasProperty = pathval.hasProperty; - exports.getName = require_get_func_name(); - exports.addProperty = require_addProperty(); - exports.addMethod = require_addMethod(); - exports.overwriteProperty = require_overwriteProperty(); - exports.overwriteMethod = require_overwriteMethod(); - exports.addChainableMethod = require_addChainableMethod(); - exports.overwriteChainableMethod = require_overwriteChainableMethod(); - exports.compareByInspect = require_compareByInspect(); - exports.getOwnEnumerablePropertySymbols = require_getOwnEnumerablePropertySymbols(); - exports.getOwnEnumerableProperties = require_getOwnEnumerableProperties(); - exports.checkError = require_check_error(); - exports.proxify = require_proxify(); - exports.addLengthGuard = require_addLengthGuard(); - exports.isProxyEnabled = require_isProxyEnabled(); - exports.isNaN = require_isNaN(); - exports.getOperator = require_getOperator(); - } - }); - - // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/assertion.js - var require_assertion = __commonJS({ - "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/assertion.js"(exports, module) { - var config2 = require_config(); - module.exports = function(_chai, util2) { - var AssertionError2 = _chai.AssertionError, flag = util2.flag; - _chai.Assertion = Assertion2; - function Assertion2(obj, msg, ssfi, lockSsfi) { - flag(this, "ssfi", ssfi || Assertion2); - flag(this, "lockSsfi", lockSsfi); - flag(this, "object", obj); - flag(this, "message", msg); - return util2.proxify(this); - } - Object.defineProperty(Assertion2, "includeStack", { - get: function() { - console.warn("Assertion.includeStack is deprecated, use chai.config.includeStack instead."); - return config2.includeStack; - }, - set: function(value) { - console.warn("Assertion.includeStack is deprecated, use chai.config.includeStack instead."); - config2.includeStack = value; - } - }); - Object.defineProperty(Assertion2, "showDiff", { - get: function() { - console.warn("Assertion.showDiff is deprecated, use chai.config.showDiff instead."); - return config2.showDiff; - }, - set: function(value) { - console.warn("Assertion.showDiff is deprecated, use chai.config.showDiff instead."); - config2.showDiff = value; - } - }); - Assertion2.addProperty = function(name, fn) { - util2.addProperty(this.prototype, name, fn); - }; - Assertion2.addMethod = function(name, fn) { - util2.addMethod(this.prototype, name, fn); - }; - Assertion2.addChainableMethod = function(name, fn, chainingBehavior) { - util2.addChainableMethod(this.prototype, name, fn, chainingBehavior); - }; - Assertion2.overwriteProperty = function(name, fn) { - util2.overwriteProperty(this.prototype, name, fn); - }; - Assertion2.overwriteMethod = function(name, fn) { - util2.overwriteMethod(this.prototype, name, fn); - }; - Assertion2.overwriteChainableMethod = function(name, fn, chainingBehavior) { - util2.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior); - }; - Assertion2.prototype.assert = function(expr, msg, negateMsg, expected, _actual, showDiff) { - var ok = util2.test(this, arguments); - if (false !== showDiff) - showDiff = true; - if (void 0 === expected && void 0 === _actual) - showDiff = false; - if (true !== config2.showDiff) - showDiff = false; - if (!ok) { - msg = util2.getMessage(this, arguments); - var actual = util2.getActual(this, arguments); - var assertionErrorObjectProperties = { - actual, - expected, - showDiff - }; - var operator = util2.getOperator(this, arguments); - if (operator) { - assertionErrorObjectProperties.operator = operator; - } - throw new AssertionError2( - msg, - assertionErrorObjectProperties, - config2.includeStack ? this.assert : flag(this, "ssfi") - ); - } - }; - Object.defineProperty( - Assertion2.prototype, - "_obj", - { - get: function() { - return flag(this, "object"); - }, - set: function(val) { - flag(this, "object", val); - } - } - ); - }; - } - }); - - // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/core/assertions.js - var require_assertions = __commonJS({ - "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/core/assertions.js"(exports, module) { - module.exports = function(chai2, _) { - var Assertion2 = chai2.Assertion, AssertionError2 = chai2.AssertionError, flag = _.flag; - [ - "to", - "be", - "been", - "is", - "and", - "has", - "have", - "with", - "that", - "which", - "at", - "of", - "same", - "but", - "does", - "still", - "also" - ].forEach(function(chain) { - Assertion2.addProperty(chain); - }); - Assertion2.addProperty("not", function() { - flag(this, "negate", true); - }); - Assertion2.addProperty("deep", function() { - flag(this, "deep", true); - }); - Assertion2.addProperty("nested", function() { - flag(this, "nested", true); - }); - Assertion2.addProperty("own", function() { - flag(this, "own", true); - }); - Assertion2.addProperty("ordered", function() { - flag(this, "ordered", true); - }); - Assertion2.addProperty("any", function() { - flag(this, "any", true); - flag(this, "all", false); - }); - Assertion2.addProperty("all", function() { - flag(this, "all", true); - flag(this, "any", false); - }); - function an(type, msg) { - if (msg) - flag(this, "message", msg); - type = type.toLowerCase(); - var obj = flag(this, "object"), article = ~["a", "e", "i", "o", "u"].indexOf(type.charAt(0)) ? "an " : "a "; - this.assert( - type === _.type(obj).toLowerCase(), - "expected #{this} to be " + article + type, - "expected #{this} not to be " + article + type - ); - } - Assertion2.addChainableMethod("an", an); - Assertion2.addChainableMethod("a", an); - function SameValueZero(a2, b) { - return _.isNaN(a2) && _.isNaN(b) || a2 === b; - } - function includeChainingBehavior() { - flag(this, "contains", true); - } - function include(val, msg) { - if (msg) - flag(this, "message", msg); - var obj = flag(this, "object"), objType = _.type(obj).toLowerCase(), flagMsg = flag(this, "message"), negate = flag(this, "negate"), ssfi = flag(this, "ssfi"), isDeep = flag(this, "deep"), descriptor = isDeep ? "deep " : ""; - flagMsg = flagMsg ? flagMsg + ": " : ""; - var included = false; - switch (objType) { - case "string": - included = obj.indexOf(val) !== -1; - break; - case "weakset": - if (isDeep) { - throw new AssertionError2( - flagMsg + "unable to use .deep.include with WeakSet", - void 0, - ssfi - ); - } - included = obj.has(val); - break; - case "map": - var isEql = isDeep ? _.eql : SameValueZero; - obj.forEach(function(item) { - included = included || isEql(item, val); - }); - break; - case "set": - if (isDeep) { - obj.forEach(function(item) { - included = included || _.eql(item, val); - }); - } else { - included = obj.has(val); - } - break; - case "array": - if (isDeep) { - included = obj.some(function(item) { - return _.eql(item, val); - }); - } else { - included = obj.indexOf(val) !== -1; - } - break; - default: - if (val !== Object(val)) { - throw new AssertionError2( - flagMsg + "the given combination of arguments (" + objType + " and " + _.type(val).toLowerCase() + ") is invalid for this assertion. You can use an array, a map, an object, a set, a string, or a weakset instead of a " + _.type(val).toLowerCase(), - void 0, - ssfi - ); - } - var props = Object.keys(val), firstErr = null, numErrs = 0; - props.forEach(function(prop) { - var propAssertion = new Assertion2(obj); - _.transferFlags(this, propAssertion, true); - flag(propAssertion, "lockSsfi", true); - if (!negate || props.length === 1) { - propAssertion.property(prop, val[prop]); - return; - } - try { - propAssertion.property(prop, val[prop]); - } catch (err) { - if (!_.checkError.compatibleConstructor(err, AssertionError2)) { - throw err; - } - if (firstErr === null) - firstErr = err; - numErrs++; - } - }, this); - if (negate && props.length > 1 && numErrs === props.length) { - throw firstErr; - } - return; - } - this.assert( - included, - "expected #{this} to " + descriptor + "include " + _.inspect(val), - "expected #{this} to not " + descriptor + "include " + _.inspect(val) - ); - } - Assertion2.addChainableMethod("include", include, includeChainingBehavior); - Assertion2.addChainableMethod("contain", include, includeChainingBehavior); - Assertion2.addChainableMethod("contains", include, includeChainingBehavior); - Assertion2.addChainableMethod("includes", include, includeChainingBehavior); - Assertion2.addProperty("ok", function() { - this.assert( - flag(this, "object"), - "expected #{this} to be truthy", - "expected #{this} to be falsy" - ); - }); - Assertion2.addProperty("true", function() { - this.assert( - true === flag(this, "object"), - "expected #{this} to be true", - "expected #{this} to be false", - flag(this, "negate") ? false : true - ); - }); - Assertion2.addProperty("false", function() { - this.assert( - false === flag(this, "object"), - "expected #{this} to be false", - "expected #{this} to be true", - flag(this, "negate") ? true : false - ); - }); - Assertion2.addProperty("null", function() { - this.assert( - null === flag(this, "object"), - "expected #{this} to be null", - "expected #{this} not to be null" - ); - }); - Assertion2.addProperty("undefined", function() { - this.assert( - void 0 === flag(this, "object"), - "expected #{this} to be undefined", - "expected #{this} not to be undefined" - ); - }); - Assertion2.addProperty("NaN", function() { - this.assert( - _.isNaN(flag(this, "object")), - "expected #{this} to be NaN", - "expected #{this} not to be NaN" - ); - }); - function assertExist() { - var val = flag(this, "object"); - this.assert( - val !== null && val !== void 0, - "expected #{this} to exist", - "expected #{this} to not exist" - ); - } - Assertion2.addProperty("exist", assertExist); - Assertion2.addProperty("exists", assertExist); - Assertion2.addProperty("empty", function() { - var val = flag(this, "object"), ssfi = flag(this, "ssfi"), flagMsg = flag(this, "message"), itemsCount; - flagMsg = flagMsg ? flagMsg + ": " : ""; - switch (_.type(val).toLowerCase()) { - case "array": - case "string": - itemsCount = val.length; - break; - case "map": - case "set": - itemsCount = val.size; - break; - case "weakmap": - case "weakset": - throw new AssertionError2( - flagMsg + ".empty was passed a weak collection", - void 0, - ssfi - ); - case "function": - var msg = flagMsg + ".empty was passed a function " + _.getName(val); - throw new AssertionError2(msg.trim(), void 0, ssfi); - default: - if (val !== Object(val)) { - throw new AssertionError2( - flagMsg + ".empty was passed non-string primitive " + _.inspect(val), - void 0, - ssfi - ); - } - itemsCount = Object.keys(val).length; - } - this.assert( - 0 === itemsCount, - "expected #{this} to be empty", - "expected #{this} not to be empty" - ); - }); - function checkArguments() { - var obj = flag(this, "object"), type = _.type(obj); - this.assert( - "Arguments" === type, - "expected #{this} to be arguments but got " + type, - "expected #{this} to not be arguments" - ); - } - Assertion2.addProperty("arguments", checkArguments); - Assertion2.addProperty("Arguments", checkArguments); - function assertEqual(val, msg) { - if (msg) - flag(this, "message", msg); - var obj = flag(this, "object"); - if (flag(this, "deep")) { - var prevLockSsfi = flag(this, "lockSsfi"); - flag(this, "lockSsfi", true); - this.eql(val); - flag(this, "lockSsfi", prevLockSsfi); - } else { - this.assert( - val === obj, - "expected #{this} to equal #{exp}", - "expected #{this} to not equal #{exp}", - val, - this._obj, - true - ); - } - } - Assertion2.addMethod("equal", assertEqual); - Assertion2.addMethod("equals", assertEqual); - Assertion2.addMethod("eq", assertEqual); - function assertEql(obj, msg) { - if (msg) - flag(this, "message", msg); - this.assert( - _.eql(obj, flag(this, "object")), - "expected #{this} to deeply equal #{exp}", - "expected #{this} to not deeply equal #{exp}", - obj, - this._obj, - true - ); - } - Assertion2.addMethod("eql", assertEql); - Assertion2.addMethod("eqls", assertEql); - function assertAbove(n, msg) { - if (msg) - flag(this, "message", msg); - var obj = flag(this, "object"), doLength = flag(this, "doLength"), flagMsg = flag(this, "message"), msgPrefix = flagMsg ? flagMsg + ": " : "", ssfi = flag(this, "ssfi"), objType = _.type(obj).toLowerCase(), nType = _.type(n).toLowerCase(), errorMessage, shouldThrow = true; - if (doLength && objType !== "map" && objType !== "set") { - new Assertion2(obj, flagMsg, ssfi, true).to.have.property("length"); - } - if (!doLength && (objType === "date" && nType !== "date")) { - errorMessage = msgPrefix + "the argument to above must be a date"; - } else if (nType !== "number" && (doLength || objType === "number")) { - errorMessage = msgPrefix + "the argument to above must be a number"; - } else if (!doLength && (objType !== "date" && objType !== "number")) { - var printObj = objType === "string" ? "'" + obj + "'" : obj; - errorMessage = msgPrefix + "expected " + printObj + " to be a number or a date"; - } else { - shouldThrow = false; - } - if (shouldThrow) { - throw new AssertionError2(errorMessage, void 0, ssfi); - } - if (doLength) { - var descriptor = "length", itemsCount; - if (objType === "map" || objType === "set") { - descriptor = "size"; - itemsCount = obj.size; - } else { - itemsCount = obj.length; - } - this.assert( - itemsCount > n, - "expected #{this} to have a " + descriptor + " above #{exp} but got #{act}", - "expected #{this} to not have a " + descriptor + " above #{exp}", - n, - itemsCount - ); - } else { - this.assert( - obj > n, - "expected #{this} to be above #{exp}", - "expected #{this} to be at most #{exp}", - n - ); - } - } - Assertion2.addMethod("above", assertAbove); - Assertion2.addMethod("gt", assertAbove); - Assertion2.addMethod("greaterThan", assertAbove); - function assertLeast(n, msg) { - if (msg) - flag(this, "message", msg); - var obj = flag(this, "object"), doLength = flag(this, "doLength"), flagMsg = flag(this, "message"), msgPrefix = flagMsg ? flagMsg + ": " : "", ssfi = flag(this, "ssfi"), objType = _.type(obj).toLowerCase(), nType = _.type(n).toLowerCase(), errorMessage, shouldThrow = true; - if (doLength && objType !== "map" && objType !== "set") { - new Assertion2(obj, flagMsg, ssfi, true).to.have.property("length"); - } - if (!doLength && (objType === "date" && nType !== "date")) { - errorMessage = msgPrefix + "the argument to least must be a date"; - } else if (nType !== "number" && (doLength || objType === "number")) { - errorMessage = msgPrefix + "the argument to least must be a number"; - } else if (!doLength && (objType !== "date" && objType !== "number")) { - var printObj = objType === "string" ? "'" + obj + "'" : obj; - errorMessage = msgPrefix + "expected " + printObj + " to be a number or a date"; - } else { - shouldThrow = false; - } - if (shouldThrow) { - throw new AssertionError2(errorMessage, void 0, ssfi); - } - if (doLength) { - var descriptor = "length", itemsCount; - if (objType === "map" || objType === "set") { - descriptor = "size"; - itemsCount = obj.size; - } else { - itemsCount = obj.length; - } - this.assert( - itemsCount >= n, - "expected #{this} to have a " + descriptor + " at least #{exp} but got #{act}", - "expected #{this} to have a " + descriptor + " below #{exp}", - n, - itemsCount - ); - } else { - this.assert( - obj >= n, - "expected #{this} to be at least #{exp}", - "expected #{this} to be below #{exp}", - n - ); - } - } - Assertion2.addMethod("least", assertLeast); - Assertion2.addMethod("gte", assertLeast); - Assertion2.addMethod("greaterThanOrEqual", assertLeast); - function assertBelow(n, msg) { - if (msg) - flag(this, "message", msg); - var obj = flag(this, "object"), doLength = flag(this, "doLength"), flagMsg = flag(this, "message"), msgPrefix = flagMsg ? flagMsg + ": " : "", ssfi = flag(this, "ssfi"), objType = _.type(obj).toLowerCase(), nType = _.type(n).toLowerCase(), errorMessage, shouldThrow = true; - if (doLength && objType !== "map" && objType !== "set") { - new Assertion2(obj, flagMsg, ssfi, true).to.have.property("length"); - } - if (!doLength && (objType === "date" && nType !== "date")) { - errorMessage = msgPrefix + "the argument to below must be a date"; - } else if (nType !== "number" && (doLength || objType === "number")) { - errorMessage = msgPrefix + "the argument to below must be a number"; - } else if (!doLength && (objType !== "date" && objType !== "number")) { - var printObj = objType === "string" ? "'" + obj + "'" : obj; - errorMessage = msgPrefix + "expected " + printObj + " to be a number or a date"; - } else { - shouldThrow = false; - } - if (shouldThrow) { - throw new AssertionError2(errorMessage, void 0, ssfi); - } - if (doLength) { - var descriptor = "length", itemsCount; - if (objType === "map" || objType === "set") { - descriptor = "size"; - itemsCount = obj.size; - } else { - itemsCount = obj.length; - } - this.assert( - itemsCount < n, - "expected #{this} to have a " + descriptor + " below #{exp} but got #{act}", - "expected #{this} to not have a " + descriptor + " below #{exp}", - n, - itemsCount - ); - } else { - this.assert( - obj < n, - "expected #{this} to be below #{exp}", - "expected #{this} to be at least #{exp}", - n - ); - } - } - Assertion2.addMethod("below", assertBelow); - Assertion2.addMethod("lt", assertBelow); - Assertion2.addMethod("lessThan", assertBelow); - function assertMost(n, msg) { - if (msg) - flag(this, "message", msg); - var obj = flag(this, "object"), doLength = flag(this, "doLength"), flagMsg = flag(this, "message"), msgPrefix = flagMsg ? flagMsg + ": " : "", ssfi = flag(this, "ssfi"), objType = _.type(obj).toLowerCase(), nType = _.type(n).toLowerCase(), errorMessage, shouldThrow = true; - if (doLength && objType !== "map" && objType !== "set") { - new Assertion2(obj, flagMsg, ssfi, true).to.have.property("length"); - } - if (!doLength && (objType === "date" && nType !== "date")) { - errorMessage = msgPrefix + "the argument to most must be a date"; - } else if (nType !== "number" && (doLength || objType === "number")) { - errorMessage = msgPrefix + "the argument to most must be a number"; - } else if (!doLength && (objType !== "date" && objType !== "number")) { - var printObj = objType === "string" ? "'" + obj + "'" : obj; - errorMessage = msgPrefix + "expected " + printObj + " to be a number or a date"; - } else { - shouldThrow = false; - } - if (shouldThrow) { - throw new AssertionError2(errorMessage, void 0, ssfi); - } - if (doLength) { - var descriptor = "length", itemsCount; - if (objType === "map" || objType === "set") { - descriptor = "size"; - itemsCount = obj.size; - } else { - itemsCount = obj.length; - } - this.assert( - itemsCount <= n, - "expected #{this} to have a " + descriptor + " at most #{exp} but got #{act}", - "expected #{this} to have a " + descriptor + " above #{exp}", - n, - itemsCount - ); - } else { - this.assert( - obj <= n, - "expected #{this} to be at most #{exp}", - "expected #{this} to be above #{exp}", - n - ); - } - } - Assertion2.addMethod("most", assertMost); - Assertion2.addMethod("lte", assertMost); - Assertion2.addMethod("lessThanOrEqual", assertMost); - Assertion2.addMethod("within", function(start, finish, msg) { - if (msg) - flag(this, "message", msg); - var obj = flag(this, "object"), doLength = flag(this, "doLength"), flagMsg = flag(this, "message"), msgPrefix = flagMsg ? flagMsg + ": " : "", ssfi = flag(this, "ssfi"), objType = _.type(obj).toLowerCase(), startType = _.type(start).toLowerCase(), finishType = _.type(finish).toLowerCase(), errorMessage, shouldThrow = true, range = startType === "date" && finishType === "date" ? start.toISOString() + ".." + finish.toISOString() : start + ".." + finish; - if (doLength && objType !== "map" && objType !== "set") { - new Assertion2(obj, flagMsg, ssfi, true).to.have.property("length"); - } - if (!doLength && (objType === "date" && (startType !== "date" || finishType !== "date"))) { - errorMessage = msgPrefix + "the arguments to within must be dates"; - } else if ((startType !== "number" || finishType !== "number") && (doLength || objType === "number")) { - errorMessage = msgPrefix + "the arguments to within must be numbers"; - } else if (!doLength && (objType !== "date" && objType !== "number")) { - var printObj = objType === "string" ? "'" + obj + "'" : obj; - errorMessage = msgPrefix + "expected " + printObj + " to be a number or a date"; - } else { - shouldThrow = false; - } - if (shouldThrow) { - throw new AssertionError2(errorMessage, void 0, ssfi); - } - if (doLength) { - var descriptor = "length", itemsCount; - if (objType === "map" || objType === "set") { - descriptor = "size"; - itemsCount = obj.size; - } else { - itemsCount = obj.length; - } - this.assert( - itemsCount >= start && itemsCount <= finish, - "expected #{this} to have a " + descriptor + " within " + range, - "expected #{this} to not have a " + descriptor + " within " + range - ); - } else { - this.assert( - obj >= start && obj <= finish, - "expected #{this} to be within " + range, - "expected #{this} to not be within " + range - ); - } - }); - function assertInstanceOf(constructor, msg) { - if (msg) - flag(this, "message", msg); - var target = flag(this, "object"); - var ssfi = flag(this, "ssfi"); - var flagMsg = flag(this, "message"); - try { - var isInstanceOf = target instanceof constructor; - } catch (err) { - if (err instanceof TypeError) { - flagMsg = flagMsg ? flagMsg + ": " : ""; - throw new AssertionError2( - flagMsg + "The instanceof assertion needs a constructor but " + _.type(constructor) + " was given.", - void 0, - ssfi - ); - } - throw err; - } - var name = _.getName(constructor); - if (name === null) { - name = "an unnamed constructor"; - } - this.assert( - isInstanceOf, - "expected #{this} to be an instance of " + name, - "expected #{this} to not be an instance of " + name - ); - } - ; - Assertion2.addMethod("instanceof", assertInstanceOf); - Assertion2.addMethod("instanceOf", assertInstanceOf); - function assertProperty(name, val, msg) { - if (msg) - flag(this, "message", msg); - var isNested = flag(this, "nested"), isOwn = flag(this, "own"), flagMsg = flag(this, "message"), obj = flag(this, "object"), ssfi = flag(this, "ssfi"), nameType = typeof name; - flagMsg = flagMsg ? flagMsg + ": " : ""; - if (isNested) { - if (nameType !== "string") { - throw new AssertionError2( - flagMsg + "the argument to property must be a string when using nested syntax", - void 0, - ssfi - ); - } - } else { - if (nameType !== "string" && nameType !== "number" && nameType !== "symbol") { - throw new AssertionError2( - flagMsg + "the argument to property must be a string, number, or symbol", - void 0, - ssfi - ); - } - } - if (isNested && isOwn) { - throw new AssertionError2( - flagMsg + 'The "nested" and "own" flags cannot be combined.', - void 0, - ssfi - ); - } - if (obj === null || obj === void 0) { - throw new AssertionError2( - flagMsg + "Target cannot be null or undefined.", - void 0, - ssfi - ); - } - var isDeep = flag(this, "deep"), negate = flag(this, "negate"), pathInfo = isNested ? _.getPathInfo(obj, name) : null, value = isNested ? pathInfo.value : obj[name]; - var descriptor = ""; - if (isDeep) - descriptor += "deep "; - if (isOwn) - descriptor += "own "; - if (isNested) - descriptor += "nested "; - descriptor += "property "; - var hasProperty; - if (isOwn) - hasProperty = Object.prototype.hasOwnProperty.call(obj, name); - else if (isNested) - hasProperty = pathInfo.exists; - else - hasProperty = _.hasProperty(obj, name); - if (!negate || arguments.length === 1) { - this.assert( - hasProperty, - "expected #{this} to have " + descriptor + _.inspect(name), - "expected #{this} to not have " + descriptor + _.inspect(name) - ); - } - if (arguments.length > 1) { - this.assert( - hasProperty && (isDeep ? _.eql(val, value) : val === value), - "expected #{this} to have " + descriptor + _.inspect(name) + " of #{exp}, but got #{act}", - "expected #{this} to not have " + descriptor + _.inspect(name) + " of #{act}", - val, - value - ); - } - flag(this, "object", value); - } - Assertion2.addMethod("property", assertProperty); - function assertOwnProperty(name, value, msg) { - flag(this, "own", true); - assertProperty.apply(this, arguments); - } - Assertion2.addMethod("ownProperty", assertOwnProperty); - Assertion2.addMethod("haveOwnProperty", assertOwnProperty); - function assertOwnPropertyDescriptor(name, descriptor, msg) { - if (typeof descriptor === "string") { - msg = descriptor; - descriptor = null; - } - if (msg) - flag(this, "message", msg); - var obj = flag(this, "object"); - var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name); - if (actualDescriptor && descriptor) { - this.assert( - _.eql(descriptor, actualDescriptor), - "expected the own property descriptor for " + _.inspect(name) + " on #{this} to match " + _.inspect(descriptor) + ", got " + _.inspect(actualDescriptor), - "expected the own property descriptor for " + _.inspect(name) + " on #{this} to not match " + _.inspect(descriptor), - descriptor, - actualDescriptor, - true - ); - } else { - this.assert( - actualDescriptor, - "expected #{this} to have an own property descriptor for " + _.inspect(name), - "expected #{this} to not have an own property descriptor for " + _.inspect(name) - ); - } - flag(this, "object", actualDescriptor); - } - Assertion2.addMethod("ownPropertyDescriptor", assertOwnPropertyDescriptor); - Assertion2.addMethod("haveOwnPropertyDescriptor", assertOwnPropertyDescriptor); - function assertLengthChain() { - flag(this, "doLength", true); - } - function assertLength(n, msg) { - if (msg) - flag(this, "message", msg); - var obj = flag(this, "object"), objType = _.type(obj).toLowerCase(), flagMsg = flag(this, "message"), ssfi = flag(this, "ssfi"), descriptor = "length", itemsCount; - switch (objType) { - case "map": - case "set": - descriptor = "size"; - itemsCount = obj.size; - break; - default: - new Assertion2(obj, flagMsg, ssfi, true).to.have.property("length"); - itemsCount = obj.length; - } - this.assert( - itemsCount == n, - "expected #{this} to have a " + descriptor + " of #{exp} but got #{act}", - "expected #{this} to not have a " + descriptor + " of #{act}", - n, - itemsCount - ); - } - Assertion2.addChainableMethod("length", assertLength, assertLengthChain); - Assertion2.addChainableMethod("lengthOf", assertLength, assertLengthChain); - function assertMatch(re, msg) { - if (msg) - flag(this, "message", msg); - var obj = flag(this, "object"); - this.assert( - re.exec(obj), - "expected #{this} to match " + re, - "expected #{this} not to match " + re - ); - } - Assertion2.addMethod("match", assertMatch); - Assertion2.addMethod("matches", assertMatch); - Assertion2.addMethod("string", function(str, msg) { - if (msg) - flag(this, "message", msg); - var obj = flag(this, "object"), flagMsg = flag(this, "message"), ssfi = flag(this, "ssfi"); - new Assertion2(obj, flagMsg, ssfi, true).is.a("string"); - this.assert( - ~obj.indexOf(str), - "expected #{this} to contain " + _.inspect(str), - "expected #{this} to not contain " + _.inspect(str) - ); - }); - function assertKeys(keys) { - var obj = flag(this, "object"), objType = _.type(obj), keysType = _.type(keys), ssfi = flag(this, "ssfi"), isDeep = flag(this, "deep"), str, deepStr = "", actual, ok = true, flagMsg = flag(this, "message"); - flagMsg = flagMsg ? flagMsg + ": " : ""; - var mixedArgsMsg = flagMsg + "when testing keys against an object or an array you must give a single Array|Object|String argument or multiple String arguments"; - if (objType === "Map" || objType === "Set") { - deepStr = isDeep ? "deeply " : ""; - actual = []; - obj.forEach(function(val, key) { - actual.push(key); - }); - if (keysType !== "Array") { - keys = Array.prototype.slice.call(arguments); - } - } else { - actual = _.getOwnEnumerableProperties(obj); - switch (keysType) { - case "Array": - if (arguments.length > 1) { - throw new AssertionError2(mixedArgsMsg, void 0, ssfi); - } - break; - case "Object": - if (arguments.length > 1) { - throw new AssertionError2(mixedArgsMsg, void 0, ssfi); - } - keys = Object.keys(keys); - break; - default: - keys = Array.prototype.slice.call(arguments); - } - keys = keys.map(function(val) { - return typeof val === "symbol" ? val : String(val); - }); - } - if (!keys.length) { - throw new AssertionError2(flagMsg + "keys required", void 0, ssfi); - } - var len = keys.length, any = flag(this, "any"), all = flag(this, "all"), expected = keys; - if (!any && !all) { - all = true; - } - if (any) { - ok = expected.some(function(expectedKey) { - return actual.some(function(actualKey) { - if (isDeep) { - return _.eql(expectedKey, actualKey); - } else { - return expectedKey === actualKey; - } - }); - }); - } - if (all) { - ok = expected.every(function(expectedKey) { - return actual.some(function(actualKey) { - if (isDeep) { - return _.eql(expectedKey, actualKey); - } else { - return expectedKey === actualKey; - } - }); - }); - if (!flag(this, "contains")) { - ok = ok && keys.length == actual.length; - } - } - if (len > 1) { - keys = keys.map(function(key) { - return _.inspect(key); - }); - var last = keys.pop(); - if (all) { - str = keys.join(", ") + ", and " + last; - } - if (any) { - str = keys.join(", ") + ", or " + last; - } - } else { - str = _.inspect(keys[0]); - } - str = (len > 1 ? "keys " : "key ") + str; - str = (flag(this, "contains") ? "contain " : "have ") + str; - this.assert( - ok, - "expected #{this} to " + deepStr + str, - "expected #{this} to not " + deepStr + str, - expected.slice(0).sort(_.compareByInspect), - actual.sort(_.compareByInspect), - true - ); - } - Assertion2.addMethod("keys", assertKeys); - Assertion2.addMethod("key", assertKeys); - function assertThrows(errorLike, errMsgMatcher, msg) { - if (msg) - flag(this, "message", msg); - var obj = flag(this, "object"), ssfi = flag(this, "ssfi"), flagMsg = flag(this, "message"), negate = flag(this, "negate") || false; - new Assertion2(obj, flagMsg, ssfi, true).is.a("function"); - if (errorLike instanceof RegExp || typeof errorLike === "string") { - errMsgMatcher = errorLike; - errorLike = null; - } - var caughtErr; - try { - obj(); - } catch (err) { - caughtErr = err; - } - var everyArgIsUndefined = errorLike === void 0 && errMsgMatcher === void 0; - var everyArgIsDefined = Boolean(errorLike && errMsgMatcher); - var errorLikeFail = false; - var errMsgMatcherFail = false; - if (everyArgIsUndefined || !everyArgIsUndefined && !negate) { - var errorLikeString = "an error"; - if (errorLike instanceof Error) { - errorLikeString = "#{exp}"; - } else if (errorLike) { - errorLikeString = _.checkError.getConstructorName(errorLike); - } - this.assert( - caughtErr, - "expected #{this} to throw " + errorLikeString, - "expected #{this} to not throw an error but #{act} was thrown", - errorLike && errorLike.toString(), - caughtErr instanceof Error ? caughtErr.toString() : typeof caughtErr === "string" ? caughtErr : caughtErr && _.checkError.getConstructorName(caughtErr) - ); - } - if (errorLike && caughtErr) { - if (errorLike instanceof Error) { - var isCompatibleInstance = _.checkError.compatibleInstance(caughtErr, errorLike); - if (isCompatibleInstance === negate) { - if (everyArgIsDefined && negate) { - errorLikeFail = true; - } else { - this.assert( - negate, - "expected #{this} to throw #{exp} but #{act} was thrown", - "expected #{this} to not throw #{exp}" + (caughtErr && !negate ? " but #{act} was thrown" : ""), - errorLike.toString(), - caughtErr.toString() - ); - } - } - } - var isCompatibleConstructor = _.checkError.compatibleConstructor(caughtErr, errorLike); - if (isCompatibleConstructor === negate) { - if (everyArgIsDefined && negate) { - errorLikeFail = true; - } else { - this.assert( - negate, - "expected #{this} to throw #{exp} but #{act} was thrown", - "expected #{this} to not throw #{exp}" + (caughtErr ? " but #{act} was thrown" : ""), - errorLike instanceof Error ? errorLike.toString() : errorLike && _.checkError.getConstructorName(errorLike), - caughtErr instanceof Error ? caughtErr.toString() : caughtErr && _.checkError.getConstructorName(caughtErr) - ); - } - } - } - if (caughtErr && errMsgMatcher !== void 0 && errMsgMatcher !== null) { - var placeholder = "including"; - if (errMsgMatcher instanceof RegExp) { - placeholder = "matching"; - } - var isCompatibleMessage = _.checkError.compatibleMessage(caughtErr, errMsgMatcher); - if (isCompatibleMessage === negate) { - if (everyArgIsDefined && negate) { - errMsgMatcherFail = true; - } else { - this.assert( - negate, - "expected #{this} to throw error " + placeholder + " #{exp} but got #{act}", - "expected #{this} to throw error not " + placeholder + " #{exp}", - errMsgMatcher, - _.checkError.getMessage(caughtErr) - ); - } - } - } - if (errorLikeFail && errMsgMatcherFail) { - this.assert( - negate, - "expected #{this} to throw #{exp} but #{act} was thrown", - "expected #{this} to not throw #{exp}" + (caughtErr ? " but #{act} was thrown" : ""), - errorLike instanceof Error ? errorLike.toString() : errorLike && _.checkError.getConstructorName(errorLike), - caughtErr instanceof Error ? caughtErr.toString() : caughtErr && _.checkError.getConstructorName(caughtErr) - ); - } - flag(this, "object", caughtErr); - } - ; - Assertion2.addMethod("throw", assertThrows); - Assertion2.addMethod("throws", assertThrows); - Assertion2.addMethod("Throw", assertThrows); - function respondTo(method, msg) { - if (msg) - flag(this, "message", msg); - var obj = flag(this, "object"), itself = flag(this, "itself"), context = "function" === typeof obj && !itself ? obj.prototype[method] : obj[method]; - this.assert( - "function" === typeof context, - "expected #{this} to respond to " + _.inspect(method), - "expected #{this} to not respond to " + _.inspect(method) - ); - } - Assertion2.addMethod("respondTo", respondTo); - Assertion2.addMethod("respondsTo", respondTo); - Assertion2.addProperty("itself", function() { - flag(this, "itself", true); - }); - function satisfy(matcher, msg) { - if (msg) - flag(this, "message", msg); - var obj = flag(this, "object"); - var result = matcher(obj); - this.assert( - result, - "expected #{this} to satisfy " + _.objDisplay(matcher), - "expected #{this} to not satisfy" + _.objDisplay(matcher), - flag(this, "negate") ? false : true, - result - ); - } - Assertion2.addMethod("satisfy", satisfy); - Assertion2.addMethod("satisfies", satisfy); - function closeTo(expected, delta, msg) { - if (msg) - flag(this, "message", msg); - var obj = flag(this, "object"), flagMsg = flag(this, "message"), ssfi = flag(this, "ssfi"); - new Assertion2(obj, flagMsg, ssfi, true).is.a("number"); - if (typeof expected !== "number" || typeof delta !== "number") { - flagMsg = flagMsg ? flagMsg + ": " : ""; - var deltaMessage = delta === void 0 ? ", and a delta is required" : ""; - throw new AssertionError2( - flagMsg + "the arguments to closeTo or approximately must be numbers" + deltaMessage, - void 0, - ssfi - ); - } - this.assert( - Math.abs(obj - expected) <= delta, - "expected #{this} to be close to " + expected + " +/- " + delta, - "expected #{this} not to be close to " + expected + " +/- " + delta - ); - } - Assertion2.addMethod("closeTo", closeTo); - Assertion2.addMethod("approximately", closeTo); - function isSubsetOf(subset, superset, cmp, contains, ordered) { - if (!contains) { - if (subset.length !== superset.length) - return false; - superset = superset.slice(); - } - return subset.every(function(elem, idx) { - if (ordered) - return cmp ? cmp(elem, superset[idx]) : elem === superset[idx]; - if (!cmp) { - var matchIdx = superset.indexOf(elem); - if (matchIdx === -1) - return false; - if (!contains) - superset.splice(matchIdx, 1); - return true; - } - return superset.some(function(elem2, matchIdx2) { - if (!cmp(elem, elem2)) - return false; - if (!contains) - superset.splice(matchIdx2, 1); - return true; - }); - }); - } - Assertion2.addMethod("members", function(subset, msg) { - if (msg) - flag(this, "message", msg); - var obj = flag(this, "object"), flagMsg = flag(this, "message"), ssfi = flag(this, "ssfi"); - new Assertion2(obj, flagMsg, ssfi, true).to.be.an("array"); - new Assertion2(subset, flagMsg, ssfi, true).to.be.an("array"); - var contains = flag(this, "contains"); - var ordered = flag(this, "ordered"); - var subject, failMsg, failNegateMsg; - if (contains) { - subject = ordered ? "an ordered superset" : "a superset"; - failMsg = "expected #{this} to be " + subject + " of #{exp}"; - failNegateMsg = "expected #{this} to not be " + subject + " of #{exp}"; - } else { - subject = ordered ? "ordered members" : "members"; - failMsg = "expected #{this} to have the same " + subject + " as #{exp}"; - failNegateMsg = "expected #{this} to not have the same " + subject + " as #{exp}"; - } - var cmp = flag(this, "deep") ? _.eql : void 0; - this.assert( - isSubsetOf(subset, obj, cmp, contains, ordered), - failMsg, - failNegateMsg, - subset, - obj, - true - ); - }); - function oneOf(list, msg) { - if (msg) - flag(this, "message", msg); - var expected = flag(this, "object"), flagMsg = flag(this, "message"), ssfi = flag(this, "ssfi"), contains = flag(this, "contains"), isDeep = flag(this, "deep"); - new Assertion2(list, flagMsg, ssfi, true).to.be.an("array"); - if (contains) { - this.assert( - list.some(function(possibility) { - return expected.indexOf(possibility) > -1; - }), - "expected #{this} to contain one of #{exp}", - "expected #{this} to not contain one of #{exp}", - list, - expected - ); - } else { - if (isDeep) { - this.assert( - list.some(function(possibility) { - return _.eql(expected, possibility); - }), - "expected #{this} to deeply equal one of #{exp}", - "expected #{this} to deeply equal one of #{exp}", - list, - expected - ); - } else { - this.assert( - list.indexOf(expected) > -1, - "expected #{this} to be one of #{exp}", - "expected #{this} to not be one of #{exp}", - list, - expected - ); - } - } - } - Assertion2.addMethod("oneOf", oneOf); - function assertChanges(subject, prop, msg) { - if (msg) - flag(this, "message", msg); - var fn = flag(this, "object"), flagMsg = flag(this, "message"), ssfi = flag(this, "ssfi"); - new Assertion2(fn, flagMsg, ssfi, true).is.a("function"); - var initial; - if (!prop) { - new Assertion2(subject, flagMsg, ssfi, true).is.a("function"); - initial = subject(); - } else { - new Assertion2(subject, flagMsg, ssfi, true).to.have.property(prop); - initial = subject[prop]; - } - fn(); - var final = prop === void 0 || prop === null ? subject() : subject[prop]; - var msgObj = prop === void 0 || prop === null ? initial : "." + prop; - flag(this, "deltaMsgObj", msgObj); - flag(this, "initialDeltaValue", initial); - flag(this, "finalDeltaValue", final); - flag(this, "deltaBehavior", "change"); - flag(this, "realDelta", final !== initial); - this.assert( - initial !== final, - "expected " + msgObj + " to change", - "expected " + msgObj + " to not change" - ); - } - Assertion2.addMethod("change", assertChanges); - Assertion2.addMethod("changes", assertChanges); - function assertIncreases(subject, prop, msg) { - if (msg) - flag(this, "message", msg); - var fn = flag(this, "object"), flagMsg = flag(this, "message"), ssfi = flag(this, "ssfi"); - new Assertion2(fn, flagMsg, ssfi, true).is.a("function"); - var initial; - if (!prop) { - new Assertion2(subject, flagMsg, ssfi, true).is.a("function"); - initial = subject(); - } else { - new Assertion2(subject, flagMsg, ssfi, true).to.have.property(prop); - initial = subject[prop]; - } - new Assertion2(initial, flagMsg, ssfi, true).is.a("number"); - fn(); - var final = prop === void 0 || prop === null ? subject() : subject[prop]; - var msgObj = prop === void 0 || prop === null ? initial : "." + prop; - flag(this, "deltaMsgObj", msgObj); - flag(this, "initialDeltaValue", initial); - flag(this, "finalDeltaValue", final); - flag(this, "deltaBehavior", "increase"); - flag(this, "realDelta", final - initial); - this.assert( - final - initial > 0, - "expected " + msgObj + " to increase", - "expected " + msgObj + " to not increase" - ); - } - Assertion2.addMethod("increase", assertIncreases); - Assertion2.addMethod("increases", assertIncreases); - function assertDecreases(subject, prop, msg) { - if (msg) - flag(this, "message", msg); - var fn = flag(this, "object"), flagMsg = flag(this, "message"), ssfi = flag(this, "ssfi"); - new Assertion2(fn, flagMsg, ssfi, true).is.a("function"); - var initial; - if (!prop) { - new Assertion2(subject, flagMsg, ssfi, true).is.a("function"); - initial = subject(); - } else { - new Assertion2(subject, flagMsg, ssfi, true).to.have.property(prop); - initial = subject[prop]; - } - new Assertion2(initial, flagMsg, ssfi, true).is.a("number"); - fn(); - var final = prop === void 0 || prop === null ? subject() : subject[prop]; - var msgObj = prop === void 0 || prop === null ? initial : "." + prop; - flag(this, "deltaMsgObj", msgObj); - flag(this, "initialDeltaValue", initial); - flag(this, "finalDeltaValue", final); - flag(this, "deltaBehavior", "decrease"); - flag(this, "realDelta", initial - final); - this.assert( - final - initial < 0, - "expected " + msgObj + " to decrease", - "expected " + msgObj + " to not decrease" - ); - } - Assertion2.addMethod("decrease", assertDecreases); - Assertion2.addMethod("decreases", assertDecreases); - function assertDelta(delta, msg) { - if (msg) - flag(this, "message", msg); - var msgObj = flag(this, "deltaMsgObj"); - var initial = flag(this, "initialDeltaValue"); - var final = flag(this, "finalDeltaValue"); - var behavior = flag(this, "deltaBehavior"); - var realDelta = flag(this, "realDelta"); - var expression; - if (behavior === "change") { - expression = Math.abs(final - initial) === Math.abs(delta); - } else { - expression = realDelta === Math.abs(delta); - } - this.assert( - expression, - "expected " + msgObj + " to " + behavior + " by " + delta, - "expected " + msgObj + " to not " + behavior + " by " + delta - ); - } - Assertion2.addMethod("by", assertDelta); - Assertion2.addProperty("extensible", function() { - var obj = flag(this, "object"); - var isExtensible = obj === Object(obj) && Object.isExtensible(obj); - this.assert( - isExtensible, - "expected #{this} to be extensible", - "expected #{this} to not be extensible" - ); - }); - Assertion2.addProperty("sealed", function() { - var obj = flag(this, "object"); - var isSealed = obj === Object(obj) ? Object.isSealed(obj) : true; - this.assert( - isSealed, - "expected #{this} to be sealed", - "expected #{this} to not be sealed" - ); - }); - Assertion2.addProperty("frozen", function() { - var obj = flag(this, "object"); - var isFrozen = obj === Object(obj) ? Object.isFrozen(obj) : true; - this.assert( - isFrozen, - "expected #{this} to be frozen", - "expected #{this} to not be frozen" - ); - }); - Assertion2.addProperty("finite", function(msg) { - var obj = flag(this, "object"); - this.assert( - typeof obj === "number" && isFinite(obj), - "expected #{this} to be a finite number", - "expected #{this} to not be a finite number" - ); - }); - }; - } - }); - - // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/interface/expect.js - var require_expect = __commonJS({ - "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/interface/expect.js"(exports, module) { - module.exports = function(chai2, util2) { - chai2.expect = function(val, message) { - return new chai2.Assertion(val, message); - }; - chai2.expect.fail = function(actual, expected, message, operator) { - if (arguments.length < 2) { - message = actual; - actual = void 0; - } - message = message || "expect.fail()"; - throw new chai2.AssertionError(message, { - actual, - expected, - operator - }, chai2.expect.fail); - }; - }; - } - }); - - // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/interface/should.js - var require_should = __commonJS({ - "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/interface/should.js"(exports, module) { - module.exports = function(chai2, util2) { - var Assertion2 = chai2.Assertion; - function loadShould() { - function shouldGetter() { - if (this instanceof String || this instanceof Number || this instanceof Boolean || typeof Symbol === "function" && this instanceof Symbol || typeof BigInt === "function" && this instanceof BigInt) { - return new Assertion2(this.valueOf(), null, shouldGetter); - } - return new Assertion2(this, null, shouldGetter); - } - function shouldSetter(value) { - Object.defineProperty(this, "should", { - value, - enumerable: true, - configurable: true, - writable: true - }); - } - Object.defineProperty(Object.prototype, "should", { - set: shouldSetter, - get: shouldGetter, - configurable: true - }); - var should2 = {}; - should2.fail = function(actual, expected, message, operator) { - if (arguments.length < 2) { - message = actual; - actual = void 0; - } - message = message || "should.fail()"; - throw new chai2.AssertionError(message, { - actual, - expected, - operator - }, should2.fail); - }; - should2.equal = function(val1, val2, msg) { - new Assertion2(val1, msg).to.equal(val2); - }; - should2.Throw = function(fn, errt, errs, msg) { - new Assertion2(fn, msg).to.Throw(errt, errs); - }; - should2.exist = function(val, msg) { - new Assertion2(val, msg).to.exist; - }; - should2.not = {}; - should2.not.equal = function(val1, val2, msg) { - new Assertion2(val1, msg).to.not.equal(val2); - }; - should2.not.Throw = function(fn, errt, errs, msg) { - new Assertion2(fn, msg).to.not.Throw(errt, errs); - }; - should2.not.exist = function(val, msg) { - new Assertion2(val, msg).to.not.exist; - }; - should2["throw"] = should2["Throw"]; - should2.not["throw"] = should2.not["Throw"]; - return should2; - } - ; - chai2.should = loadShould; - chai2.Should = loadShould; - }; - } - }); - - // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/interface/assert.js - var require_assert = __commonJS({ - "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/interface/assert.js"(exports, module) { - module.exports = function(chai2, util2) { - var Assertion2 = chai2.Assertion, flag = util2.flag; - var assert2 = chai2.assert = function(express, errmsg) { - var test = new Assertion2(null, null, chai2.assert, true); - test.assert( - express, - errmsg, - "[ negation message unavailable ]" - ); - }; - assert2.fail = function(actual, expected, message, operator) { - if (arguments.length < 2) { - message = actual; - actual = void 0; - } - message = message || "assert.fail()"; - throw new chai2.AssertionError(message, { - actual, - expected, - operator - }, assert2.fail); - }; - assert2.isOk = function(val, msg) { - new Assertion2(val, msg, assert2.isOk, true).is.ok; - }; - assert2.isNotOk = function(val, msg) { - new Assertion2(val, msg, assert2.isNotOk, true).is.not.ok; - }; - assert2.equal = function(act, exp, msg) { - var test = new Assertion2(act, msg, assert2.equal, true); - test.assert( - exp == flag(test, "object"), - "expected #{this} to equal #{exp}", - "expected #{this} to not equal #{act}", - exp, - act, - true - ); - }; - assert2.notEqual = function(act, exp, msg) { - var test = new Assertion2(act, msg, assert2.notEqual, true); - test.assert( - exp != flag(test, "object"), - "expected #{this} to not equal #{exp}", - "expected #{this} to equal #{act}", - exp, - act, - true - ); - }; - assert2.strictEqual = function(act, exp, msg) { - new Assertion2(act, msg, assert2.strictEqual, true).to.equal(exp); - }; - assert2.notStrictEqual = function(act, exp, msg) { - new Assertion2(act, msg, assert2.notStrictEqual, true).to.not.equal(exp); - }; - assert2.deepEqual = assert2.deepStrictEqual = function(act, exp, msg) { - new Assertion2(act, msg, assert2.deepEqual, true).to.eql(exp); - }; - assert2.notDeepEqual = function(act, exp, msg) { - new Assertion2(act, msg, assert2.notDeepEqual, true).to.not.eql(exp); - }; - assert2.isAbove = function(val, abv, msg) { - new Assertion2(val, msg, assert2.isAbove, true).to.be.above(abv); - }; - assert2.isAtLeast = function(val, atlst, msg) { - new Assertion2(val, msg, assert2.isAtLeast, true).to.be.least(atlst); - }; - assert2.isBelow = function(val, blw, msg) { - new Assertion2(val, msg, assert2.isBelow, true).to.be.below(blw); - }; - assert2.isAtMost = function(val, atmst, msg) { - new Assertion2(val, msg, assert2.isAtMost, true).to.be.most(atmst); - }; - assert2.isTrue = function(val, msg) { - new Assertion2(val, msg, assert2.isTrue, true).is["true"]; - }; - assert2.isNotTrue = function(val, msg) { - new Assertion2(val, msg, assert2.isNotTrue, true).to.not.equal(true); - }; - assert2.isFalse = function(val, msg) { - new Assertion2(val, msg, assert2.isFalse, true).is["false"]; - }; - assert2.isNotFalse = function(val, msg) { - new Assertion2(val, msg, assert2.isNotFalse, true).to.not.equal(false); - }; - assert2.isNull = function(val, msg) { - new Assertion2(val, msg, assert2.isNull, true).to.equal(null); - }; - assert2.isNotNull = function(val, msg) { - new Assertion2(val, msg, assert2.isNotNull, true).to.not.equal(null); - }; - assert2.isNaN = function(val, msg) { - new Assertion2(val, msg, assert2.isNaN, true).to.be.NaN; - }; - assert2.isNotNaN = function(val, msg) { - new Assertion2(val, msg, assert2.isNotNaN, true).not.to.be.NaN; - }; - assert2.exists = function(val, msg) { - new Assertion2(val, msg, assert2.exists, true).to.exist; - }; - assert2.notExists = function(val, msg) { - new Assertion2(val, msg, assert2.notExists, true).to.not.exist; - }; - assert2.isUndefined = function(val, msg) { - new Assertion2(val, msg, assert2.isUndefined, true).to.equal(void 0); - }; - assert2.isDefined = function(val, msg) { - new Assertion2(val, msg, assert2.isDefined, true).to.not.equal(void 0); - }; - assert2.isFunction = function(val, msg) { - new Assertion2(val, msg, assert2.isFunction, true).to.be.a("function"); - }; - assert2.isNotFunction = function(val, msg) { - new Assertion2(val, msg, assert2.isNotFunction, true).to.not.be.a("function"); - }; - assert2.isObject = function(val, msg) { - new Assertion2(val, msg, assert2.isObject, true).to.be.a("object"); - }; - assert2.isNotObject = function(val, msg) { - new Assertion2(val, msg, assert2.isNotObject, true).to.not.be.a("object"); - }; - assert2.isArray = function(val, msg) { - new Assertion2(val, msg, assert2.isArray, true).to.be.an("array"); - }; - assert2.isNotArray = function(val, msg) { - new Assertion2(val, msg, assert2.isNotArray, true).to.not.be.an("array"); - }; - assert2.isString = function(val, msg) { - new Assertion2(val, msg, assert2.isString, true).to.be.a("string"); - }; - assert2.isNotString = function(val, msg) { - new Assertion2(val, msg, assert2.isNotString, true).to.not.be.a("string"); - }; - assert2.isNumber = function(val, msg) { - new Assertion2(val, msg, assert2.isNumber, true).to.be.a("number"); - }; - assert2.isNotNumber = function(val, msg) { - new Assertion2(val, msg, assert2.isNotNumber, true).to.not.be.a("number"); - }; - assert2.isFinite = function(val, msg) { - new Assertion2(val, msg, assert2.isFinite, true).to.be.finite; - }; - assert2.isBoolean = function(val, msg) { - new Assertion2(val, msg, assert2.isBoolean, true).to.be.a("boolean"); - }; - assert2.isNotBoolean = function(val, msg) { - new Assertion2(val, msg, assert2.isNotBoolean, true).to.not.be.a("boolean"); - }; - assert2.typeOf = function(val, type, msg) { - new Assertion2(val, msg, assert2.typeOf, true).to.be.a(type); - }; - assert2.notTypeOf = function(val, type, msg) { - new Assertion2(val, msg, assert2.notTypeOf, true).to.not.be.a(type); - }; - assert2.instanceOf = function(val, type, msg) { - new Assertion2(val, msg, assert2.instanceOf, true).to.be.instanceOf(type); - }; - assert2.notInstanceOf = function(val, type, msg) { - new Assertion2(val, msg, assert2.notInstanceOf, true).to.not.be.instanceOf(type); - }; - assert2.include = function(exp, inc, msg) { - new Assertion2(exp, msg, assert2.include, true).include(inc); - }; - assert2.notInclude = function(exp, inc, msg) { - new Assertion2(exp, msg, assert2.notInclude, true).not.include(inc); - }; - assert2.deepInclude = function(exp, inc, msg) { - new Assertion2(exp, msg, assert2.deepInclude, true).deep.include(inc); - }; - assert2.notDeepInclude = function(exp, inc, msg) { - new Assertion2(exp, msg, assert2.notDeepInclude, true).not.deep.include(inc); - }; - assert2.nestedInclude = function(exp, inc, msg) { - new Assertion2(exp, msg, assert2.nestedInclude, true).nested.include(inc); - }; - assert2.notNestedInclude = function(exp, inc, msg) { - new Assertion2(exp, msg, assert2.notNestedInclude, true).not.nested.include(inc); - }; - assert2.deepNestedInclude = function(exp, inc, msg) { - new Assertion2(exp, msg, assert2.deepNestedInclude, true).deep.nested.include(inc); - }; - assert2.notDeepNestedInclude = function(exp, inc, msg) { - new Assertion2(exp, msg, assert2.notDeepNestedInclude, true).not.deep.nested.include(inc); - }; - assert2.ownInclude = function(exp, inc, msg) { - new Assertion2(exp, msg, assert2.ownInclude, true).own.include(inc); - }; - assert2.notOwnInclude = function(exp, inc, msg) { - new Assertion2(exp, msg, assert2.notOwnInclude, true).not.own.include(inc); - }; - assert2.deepOwnInclude = function(exp, inc, msg) { - new Assertion2(exp, msg, assert2.deepOwnInclude, true).deep.own.include(inc); - }; - assert2.notDeepOwnInclude = function(exp, inc, msg) { - new Assertion2(exp, msg, assert2.notDeepOwnInclude, true).not.deep.own.include(inc); - }; - assert2.match = function(exp, re, msg) { - new Assertion2(exp, msg, assert2.match, true).to.match(re); - }; - assert2.notMatch = function(exp, re, msg) { - new Assertion2(exp, msg, assert2.notMatch, true).to.not.match(re); - }; - assert2.property = function(obj, prop, msg) { - new Assertion2(obj, msg, assert2.property, true).to.have.property(prop); - }; - assert2.notProperty = function(obj, prop, msg) { - new Assertion2(obj, msg, assert2.notProperty, true).to.not.have.property(prop); - }; - assert2.propertyVal = function(obj, prop, val, msg) { - new Assertion2(obj, msg, assert2.propertyVal, true).to.have.property(prop, val); - }; - assert2.notPropertyVal = function(obj, prop, val, msg) { - new Assertion2(obj, msg, assert2.notPropertyVal, true).to.not.have.property(prop, val); - }; - assert2.deepPropertyVal = function(obj, prop, val, msg) { - new Assertion2(obj, msg, assert2.deepPropertyVal, true).to.have.deep.property(prop, val); - }; - assert2.notDeepPropertyVal = function(obj, prop, val, msg) { - new Assertion2(obj, msg, assert2.notDeepPropertyVal, true).to.not.have.deep.property(prop, val); - }; - assert2.ownProperty = function(obj, prop, msg) { - new Assertion2(obj, msg, assert2.ownProperty, true).to.have.own.property(prop); - }; - assert2.notOwnProperty = function(obj, prop, msg) { - new Assertion2(obj, msg, assert2.notOwnProperty, true).to.not.have.own.property(prop); - }; - assert2.ownPropertyVal = function(obj, prop, value, msg) { - new Assertion2(obj, msg, assert2.ownPropertyVal, true).to.have.own.property(prop, value); - }; - assert2.notOwnPropertyVal = function(obj, prop, value, msg) { - new Assertion2(obj, msg, assert2.notOwnPropertyVal, true).to.not.have.own.property(prop, value); - }; - assert2.deepOwnPropertyVal = function(obj, prop, value, msg) { - new Assertion2(obj, msg, assert2.deepOwnPropertyVal, true).to.have.deep.own.property(prop, value); - }; - assert2.notDeepOwnPropertyVal = function(obj, prop, value, msg) { - new Assertion2(obj, msg, assert2.notDeepOwnPropertyVal, true).to.not.have.deep.own.property(prop, value); - }; - assert2.nestedProperty = function(obj, prop, msg) { - new Assertion2(obj, msg, assert2.nestedProperty, true).to.have.nested.property(prop); - }; - assert2.notNestedProperty = function(obj, prop, msg) { - new Assertion2(obj, msg, assert2.notNestedProperty, true).to.not.have.nested.property(prop); - }; - assert2.nestedPropertyVal = function(obj, prop, val, msg) { - new Assertion2(obj, msg, assert2.nestedPropertyVal, true).to.have.nested.property(prop, val); - }; - assert2.notNestedPropertyVal = function(obj, prop, val, msg) { - new Assertion2(obj, msg, assert2.notNestedPropertyVal, true).to.not.have.nested.property(prop, val); - }; - assert2.deepNestedPropertyVal = function(obj, prop, val, msg) { - new Assertion2(obj, msg, assert2.deepNestedPropertyVal, true).to.have.deep.nested.property(prop, val); - }; - assert2.notDeepNestedPropertyVal = function(obj, prop, val, msg) { - new Assertion2(obj, msg, assert2.notDeepNestedPropertyVal, true).to.not.have.deep.nested.property(prop, val); - }; - assert2.lengthOf = function(exp, len, msg) { - new Assertion2(exp, msg, assert2.lengthOf, true).to.have.lengthOf(len); - }; - assert2.hasAnyKeys = function(obj, keys, msg) { - new Assertion2(obj, msg, assert2.hasAnyKeys, true).to.have.any.keys(keys); - }; - assert2.hasAllKeys = function(obj, keys, msg) { - new Assertion2(obj, msg, assert2.hasAllKeys, true).to.have.all.keys(keys); - }; - assert2.containsAllKeys = function(obj, keys, msg) { - new Assertion2(obj, msg, assert2.containsAllKeys, true).to.contain.all.keys(keys); - }; - assert2.doesNotHaveAnyKeys = function(obj, keys, msg) { - new Assertion2(obj, msg, assert2.doesNotHaveAnyKeys, true).to.not.have.any.keys(keys); - }; - assert2.doesNotHaveAllKeys = function(obj, keys, msg) { - new Assertion2(obj, msg, assert2.doesNotHaveAllKeys, true).to.not.have.all.keys(keys); - }; - assert2.hasAnyDeepKeys = function(obj, keys, msg) { - new Assertion2(obj, msg, assert2.hasAnyDeepKeys, true).to.have.any.deep.keys(keys); - }; - assert2.hasAllDeepKeys = function(obj, keys, msg) { - new Assertion2(obj, msg, assert2.hasAllDeepKeys, true).to.have.all.deep.keys(keys); - }; - assert2.containsAllDeepKeys = function(obj, keys, msg) { - new Assertion2(obj, msg, assert2.containsAllDeepKeys, true).to.contain.all.deep.keys(keys); - }; - assert2.doesNotHaveAnyDeepKeys = function(obj, keys, msg) { - new Assertion2(obj, msg, assert2.doesNotHaveAnyDeepKeys, true).to.not.have.any.deep.keys(keys); - }; - assert2.doesNotHaveAllDeepKeys = function(obj, keys, msg) { - new Assertion2(obj, msg, assert2.doesNotHaveAllDeepKeys, true).to.not.have.all.deep.keys(keys); - }; - assert2.throws = function(fn, errorLike, errMsgMatcher, msg) { - if ("string" === typeof errorLike || errorLike instanceof RegExp) { - errMsgMatcher = errorLike; - errorLike = null; - } - var assertErr = new Assertion2(fn, msg, assert2.throws, true).to.throw(errorLike, errMsgMatcher); - return flag(assertErr, "object"); - }; - assert2.doesNotThrow = function(fn, errorLike, errMsgMatcher, msg) { - if ("string" === typeof errorLike || errorLike instanceof RegExp) { - errMsgMatcher = errorLike; - errorLike = null; - } - new Assertion2(fn, msg, assert2.doesNotThrow, true).to.not.throw(errorLike, errMsgMatcher); - }; - assert2.operator = function(val, operator, val2, msg) { - var ok; - switch (operator) { - case "==": - ok = val == val2; - break; - case "===": - ok = val === val2; - break; - case ">": - ok = val > val2; - break; - case ">=": - ok = val >= val2; - break; - case "<": - ok = val < val2; - break; - case "<=": - ok = val <= val2; - break; - case "!=": - ok = val != val2; - break; - case "!==": - ok = val !== val2; - break; - default: - msg = msg ? msg + ": " : msg; - throw new chai2.AssertionError( - msg + 'Invalid operator "' + operator + '"', - void 0, - assert2.operator - ); - } - var test = new Assertion2(ok, msg, assert2.operator, true); - test.assert( - true === flag(test, "object"), - "expected " + util2.inspect(val) + " to be " + operator + " " + util2.inspect(val2), - "expected " + util2.inspect(val) + " to not be " + operator + " " + util2.inspect(val2) - ); - }; - assert2.closeTo = function(act, exp, delta, msg) { - new Assertion2(act, msg, assert2.closeTo, true).to.be.closeTo(exp, delta); - }; - assert2.approximately = function(act, exp, delta, msg) { - new Assertion2(act, msg, assert2.approximately, true).to.be.approximately(exp, delta); - }; - assert2.sameMembers = function(set1, set2, msg) { - new Assertion2(set1, msg, assert2.sameMembers, true).to.have.same.members(set2); - }; - assert2.notSameMembers = function(set1, set2, msg) { - new Assertion2(set1, msg, assert2.notSameMembers, true).to.not.have.same.members(set2); - }; - assert2.sameDeepMembers = function(set1, set2, msg) { - new Assertion2(set1, msg, assert2.sameDeepMembers, true).to.have.same.deep.members(set2); - }; - assert2.notSameDeepMembers = function(set1, set2, msg) { - new Assertion2(set1, msg, assert2.notSameDeepMembers, true).to.not.have.same.deep.members(set2); - }; - assert2.sameOrderedMembers = function(set1, set2, msg) { - new Assertion2(set1, msg, assert2.sameOrderedMembers, true).to.have.same.ordered.members(set2); - }; - assert2.notSameOrderedMembers = function(set1, set2, msg) { - new Assertion2(set1, msg, assert2.notSameOrderedMembers, true).to.not.have.same.ordered.members(set2); - }; - assert2.sameDeepOrderedMembers = function(set1, set2, msg) { - new Assertion2(set1, msg, assert2.sameDeepOrderedMembers, true).to.have.same.deep.ordered.members(set2); - }; - assert2.notSameDeepOrderedMembers = function(set1, set2, msg) { - new Assertion2(set1, msg, assert2.notSameDeepOrderedMembers, true).to.not.have.same.deep.ordered.members(set2); - }; - assert2.includeMembers = function(superset, subset, msg) { - new Assertion2(superset, msg, assert2.includeMembers, true).to.include.members(subset); - }; - assert2.notIncludeMembers = function(superset, subset, msg) { - new Assertion2(superset, msg, assert2.notIncludeMembers, true).to.not.include.members(subset); - }; - assert2.includeDeepMembers = function(superset, subset, msg) { - new Assertion2(superset, msg, assert2.includeDeepMembers, true).to.include.deep.members(subset); - }; - assert2.notIncludeDeepMembers = function(superset, subset, msg) { - new Assertion2(superset, msg, assert2.notIncludeDeepMembers, true).to.not.include.deep.members(subset); - }; - assert2.includeOrderedMembers = function(superset, subset, msg) { - new Assertion2(superset, msg, assert2.includeOrderedMembers, true).to.include.ordered.members(subset); - }; - assert2.notIncludeOrderedMembers = function(superset, subset, msg) { - new Assertion2(superset, msg, assert2.notIncludeOrderedMembers, true).to.not.include.ordered.members(subset); - }; - assert2.includeDeepOrderedMembers = function(superset, subset, msg) { - new Assertion2(superset, msg, assert2.includeDeepOrderedMembers, true).to.include.deep.ordered.members(subset); - }; - assert2.notIncludeDeepOrderedMembers = function(superset, subset, msg) { - new Assertion2(superset, msg, assert2.notIncludeDeepOrderedMembers, true).to.not.include.deep.ordered.members(subset); - }; - assert2.oneOf = function(inList, list, msg) { - new Assertion2(inList, msg, assert2.oneOf, true).to.be.oneOf(list); - }; - assert2.changes = function(fn, obj, prop, msg) { - if (arguments.length === 3 && typeof obj === "function") { - msg = prop; - prop = null; - } - new Assertion2(fn, msg, assert2.changes, true).to.change(obj, prop); - }; - assert2.changesBy = function(fn, obj, prop, delta, msg) { - if (arguments.length === 4 && typeof obj === "function") { - var tmpMsg = delta; - delta = prop; - msg = tmpMsg; - } else if (arguments.length === 3) { - delta = prop; - prop = null; - } - new Assertion2(fn, msg, assert2.changesBy, true).to.change(obj, prop).by(delta); - }; - assert2.doesNotChange = function(fn, obj, prop, msg) { - if (arguments.length === 3 && typeof obj === "function") { - msg = prop; - prop = null; - } - return new Assertion2(fn, msg, assert2.doesNotChange, true).to.not.change(obj, prop); - }; - assert2.changesButNotBy = function(fn, obj, prop, delta, msg) { - if (arguments.length === 4 && typeof obj === "function") { - var tmpMsg = delta; - delta = prop; - msg = tmpMsg; - } else if (arguments.length === 3) { - delta = prop; - prop = null; - } - new Assertion2(fn, msg, assert2.changesButNotBy, true).to.change(obj, prop).but.not.by(delta); - }; - assert2.increases = function(fn, obj, prop, msg) { - if (arguments.length === 3 && typeof obj === "function") { - msg = prop; - prop = null; - } - return new Assertion2(fn, msg, assert2.increases, true).to.increase(obj, prop); - }; - assert2.increasesBy = function(fn, obj, prop, delta, msg) { - if (arguments.length === 4 && typeof obj === "function") { - var tmpMsg = delta; - delta = prop; - msg = tmpMsg; - } else if (arguments.length === 3) { - delta = prop; - prop = null; - } - new Assertion2(fn, msg, assert2.increasesBy, true).to.increase(obj, prop).by(delta); - }; - assert2.doesNotIncrease = function(fn, obj, prop, msg) { - if (arguments.length === 3 && typeof obj === "function") { - msg = prop; - prop = null; - } - return new Assertion2(fn, msg, assert2.doesNotIncrease, true).to.not.increase(obj, prop); - }; - assert2.increasesButNotBy = function(fn, obj, prop, delta, msg) { - if (arguments.length === 4 && typeof obj === "function") { - var tmpMsg = delta; - delta = prop; - msg = tmpMsg; - } else if (arguments.length === 3) { - delta = prop; - prop = null; - } - new Assertion2(fn, msg, assert2.increasesButNotBy, true).to.increase(obj, prop).but.not.by(delta); - }; - assert2.decreases = function(fn, obj, prop, msg) { - if (arguments.length === 3 && typeof obj === "function") { - msg = prop; - prop = null; - } - return new Assertion2(fn, msg, assert2.decreases, true).to.decrease(obj, prop); - }; - assert2.decreasesBy = function(fn, obj, prop, delta, msg) { - if (arguments.length === 4 && typeof obj === "function") { - var tmpMsg = delta; - delta = prop; - msg = tmpMsg; - } else if (arguments.length === 3) { - delta = prop; - prop = null; - } - new Assertion2(fn, msg, assert2.decreasesBy, true).to.decrease(obj, prop).by(delta); - }; - assert2.doesNotDecrease = function(fn, obj, prop, msg) { - if (arguments.length === 3 && typeof obj === "function") { - msg = prop; - prop = null; - } - return new Assertion2(fn, msg, assert2.doesNotDecrease, true).to.not.decrease(obj, prop); - }; - assert2.doesNotDecreaseBy = function(fn, obj, prop, delta, msg) { - if (arguments.length === 4 && typeof obj === "function") { - var tmpMsg = delta; - delta = prop; - msg = tmpMsg; - } else if (arguments.length === 3) { - delta = prop; - prop = null; - } - return new Assertion2(fn, msg, assert2.doesNotDecreaseBy, true).to.not.decrease(obj, prop).by(delta); - }; - assert2.decreasesButNotBy = function(fn, obj, prop, delta, msg) { - if (arguments.length === 4 && typeof obj === "function") { - var tmpMsg = delta; - delta = prop; - msg = tmpMsg; - } else if (arguments.length === 3) { - delta = prop; - prop = null; - } - new Assertion2(fn, msg, assert2.decreasesButNotBy, true).to.decrease(obj, prop).but.not.by(delta); - }; - assert2.ifError = function(val) { - if (val) { - throw val; - } - }; - assert2.isExtensible = function(obj, msg) { - new Assertion2(obj, msg, assert2.isExtensible, true).to.be.extensible; - }; - assert2.isNotExtensible = function(obj, msg) { - new Assertion2(obj, msg, assert2.isNotExtensible, true).to.not.be.extensible; - }; - assert2.isSealed = function(obj, msg) { - new Assertion2(obj, msg, assert2.isSealed, true).to.be.sealed; - }; - assert2.isNotSealed = function(obj, msg) { - new Assertion2(obj, msg, assert2.isNotSealed, true).to.not.be.sealed; - }; - assert2.isFrozen = function(obj, msg) { - new Assertion2(obj, msg, assert2.isFrozen, true).to.be.frozen; - }; - assert2.isNotFrozen = function(obj, msg) { - new Assertion2(obj, msg, assert2.isNotFrozen, true).to.not.be.frozen; - }; - assert2.isEmpty = function(val, msg) { - new Assertion2(val, msg, assert2.isEmpty, true).to.be.empty; - }; - assert2.isNotEmpty = function(val, msg) { - new Assertion2(val, msg, assert2.isNotEmpty, true).to.not.be.empty; - }; - (function alias(name, as) { - assert2[as] = assert2[name]; - return alias; - })("isOk", "ok")("isNotOk", "notOk")("throws", "throw")("throws", "Throw")("isExtensible", "extensible")("isNotExtensible", "notExtensible")("isSealed", "sealed")("isNotSealed", "notSealed")("isFrozen", "frozen")("isNotFrozen", "notFrozen")("isEmpty", "empty")("isNotEmpty", "notEmpty"); - }; - } - }); - - // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai.js - var require_chai = __commonJS({ - "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai.js"(exports) { - var used = []; - exports.version = "4.3.3"; - exports.AssertionError = require_assertion_error(); - var util2 = require_utils(); - exports.use = function(fn) { - if (!~used.indexOf(fn)) { - fn(exports, util2); - used.push(fn); - } - return exports; - }; - exports.util = util2; - var config2 = require_config(); - exports.config = config2; - var assertion = require_assertion(); - exports.use(assertion); - var core2 = require_assertions(); - exports.use(core2); - var expect9 = require_expect(); - exports.use(expect9); - var should2 = require_should(); - exports.use(should2); - var assert2 = require_assert(); - exports.use(assert2); - } - }); - - // node_modules/.pnpm/chai@4.3.7/node_modules/chai/index.js - var require_chai2 = __commonJS({ - "node_modules/.pnpm/chai@4.3.7/node_modules/chai/index.js"(exports, module) { - module.exports = require_chai(); - } - }); - - // ../application/source/constants.mjs - var internalSymbol, internalStateSymbol, instanceSymbol; - var init_constants = __esm({ - "../application/source/constants.mjs"() { - internalSymbol = Symbol.for("@schukai/monster/internal"); - internalStateSymbol = Symbol.for("@schukai/monster/state"); - instanceSymbol = Symbol.for("@schukai/monster/instance"); - } - }); - - // ../application/source/types/base.mjs - function checkInstanceSymbol(obj) { - if (this.hasOwnProperty(instanceSymbol) === false) { - return false; - } - const proto = obj?.constructor; - if (proto === void 0 || proto === null || typeof proto !== "object" && typeof proto !== "function") { - return false; - } - if (proto.hasOwnProperty(instanceSymbol) !== true) { - return checkInstanceSymbol.apply(this, [obj.__proto__]); - } - const symbol2 = proto[instanceSymbol]; - if (symbol2 === void 0) { - if (obj.__proto__) { - return checkInstanceSymbol(obj.__proto__); - } else { - return false; - } - } - if (symbol2 === this[instanceSymbol]) { - return true; - } - return checkInstanceSymbol.apply(this, [obj.__proto__]); - } - var Base; - var init_base = __esm({ - "../application/source/types/base.mjs"() { - init_constants(); - Base = class extends Object { - /** - * - * @returns {string} - */ - toString() { - return JSON.stringify(this); - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/types/base"); - } - /** - * This method is called by the `instanceof` operator. - * @param that - * @returns {boolean} - * @since 2.1.0 - */ - static [Symbol.hasInstance](that) { - if (that === void 0 || that === null || typeof that !== "object" && typeof that !== "function") { - return false; - } - const thatClass = Object.getPrototypeOf(that); - if (thatClass === void 0 || thatClass === null || typeof thatClass !== "object" && typeof thatClass !== "function") { - return false; - } - if (checkInstanceSymbol.apply(this, [thatClass]) === true) { - return true; - } - return super[Symbol.hasInstance](that); - } - }; - } - }); - - // ../application/source/types/is.mjs - function isIterable(value) { - if (value === void 0) - return false; - if (value === null) - return false; - return typeof value?.[Symbol.iterator] === "function"; - } - function isPrimitive(value) { - var type; - if (value === void 0 || value === null) { - return true; - } - type = typeof value; - if (type === "string" || type === "number" || type === "boolean" || type === "symbol") { - return true; - } - return false; - } - function isSymbol(value) { - return "symbol" === typeof value ? true : false; - } - function isBoolean(value) { - if (value === true || value === false) { - return true; - } - return false; - } - function isString(value) { - if (value === void 0 || typeof value !== "string") { - return false; - } - return true; - } - function isObject(value) { - if (isArray(value)) - return false; - if (isPrimitive(value)) - return false; - if (typeof value === "object") { - return true; - } - return false; - } - function isInstance(value, instance) { - if (!isObject(value)) - return false; - if (!isFunction(instance)) - return false; - if (!instance.hasOwnProperty("prototype")) - return false; - return value instanceof instance ? true : false; - } - function isArray(value) { - return Array.isArray(value); - } - function isFunction(value) { - if (isArray(value)) - return false; - if (isPrimitive(value)) - return false; - if (typeof value === "function") { - return true; - } - return false; - } - function isInteger(value) { - return Number.isInteger(value); - } - var init_is = __esm({ - "../application/source/types/is.mjs"() { - } - }); - - // ../application/source/types/validate.mjs - function validateIterable(value) { - if (!isIterable(value)) { - throw new TypeError("value is not iterable"); - } - return value; - } - function validatePrimitive(value) { - if (!isPrimitive(value)) { - throw new TypeError("value is not a primitive"); - } - return value; - } - function validateBoolean(value) { - if (!isBoolean(value)) { - throw new TypeError("value is not a boolean"); - } - return value; - } - function validateString(value) { - if (!isString(value)) { - throw new TypeError("value is not a string"); - } - return value; - } - function validateObject(value) { - if (!isObject(value)) { - throw new TypeError("value is not a object"); - } - return value; - } - function validateInstance(value, instance) { - if (!isInstance(value, instance)) { - let n = ""; - if (isObject(instance) || isFunction(instance)) { - n = instance?.["name"]; - } - if (n) { - n = ` ${n}`; - } - throw new TypeError(`value is not an instance of${n}`); - } - return value; - } - function validateArray(value) { - if (!isArray(value)) { - throw new TypeError("value is not an array"); - } - return value; - } - function validateSymbol(value) { - if (!isSymbol(value)) { - throw new TypeError("value is not an symbol"); - } - return value; - } - function validateFunction(value) { - if (!isFunction(value)) { - throw new TypeError("value is not a function"); - } - return value; - } - function validateInteger(value) { - if (!isInteger(value)) { - throw new TypeError("value is not an integer"); - } - return value; - } - var init_validate = __esm({ - "../application/source/types/validate.mjs"() { - init_is(); - } - }); - - // ../application/source/types/global.mjs - function getGlobal() { - return globalReference; - } - function getGlobalObject(name) { - validateString(name); - let o = globalReference?.[name]; - if (typeof o === "undefined") - throw new Error(`the object ${name} is not defined`); - validateObject(o); - return o; - } - function getGlobalFunction(name) { - validateString(name); - let f = globalReference?.[name]; - if (typeof f === "undefined") - throw new Error(`the function ${name} is not defined`); - validateFunction(f); - return f; - } - var globalReference; - var init_global = __esm({ - "../application/source/types/global.mjs"() { - init_validate(); - (function() { - if (typeof globalThis === "object") { - globalReference = globalThis; - return; - } - if (typeof self !== "undefined") { - globalReference = self; - return; - } else if (typeof window !== "undefined") { - globalReference = window; - return; - } - Object.defineProperty(Object.prototype, "__monster__", { - get: function() { - return this; - }, - configurable: true - }); - if (typeof __monster__ === "object") { - __monster__.globalThis = __monster__; - delete Object.prototype.__monster__; - globalReference = globalThis; - return; - } - try { - globalReference = Function("return this")(); - } catch (e) { - } - throw new Error("unsupported environment."); - })(); - } - }); - - // ../application/source/types/typeof.mjs - function typeOf(value) { - let type = {}.toString.call(value).match(/\s([a-zA-Z]+)/)[1]; - if ("Object" === type) { - const name = value.constructor.name; - if (name) { - return name.toLowerCase(); - } - const results = /^(class|function)\s+(\w+)/.exec(value.constructor.toString()); - type = results && results.length > 2 ? results[2] : ""; - } - return type.toLowerCase(); - } - var init_typeof = __esm({ - "../application/source/types/typeof.mjs"() { - } - }); - - // ../application/source/data/extend.mjs - function extend(...args) { - let o; - let i; - if (typeof args !== "object" || args[0] === null) { - throw new Error(`unsupported argument ${JSON.stringify(args[0])}`); - } - for (i = 0; i < args.length; i++) { - let a2 = args[i]; - if (!(isObject(a2) || isArray(a2))) { - throw new Error(`unsupported argument ${JSON.stringify(a2)}`); - } - if (o === void 0) { - o = a2; - continue; - } - for (let k in a2) { - let v = a2?.[k]; - if (v === o?.[k]) { - continue; - } - if (isObject(v) && typeOf(v) === "object" || isArray(v)) { - if (o[k] === void 0) { - if (isArray(v)) { - o[k] = []; - } else { - o[k] = {}; - } - } else { - if (typeOf(o[k]) !== typeOf(v)) { - throw new Error( - `type mismatch: ${JSON.stringify(o[k])}(${typeOf(o[k])}) != ${JSON.stringify(v)}(${typeOf( - v - )})` - ); - } - } - o[k] = extend(o[k], v); - } else { - o[k] = v; - } - } - } - return o; - } - var init_extend = __esm({ - "../application/source/data/extend.mjs"() { - init_is(); - init_typeof(); - } - }); - - // ../application/source/util/clone.mjs - function clone(obj) { - if (null === obj) { - return obj; - } - if (isPrimitive(obj)) { - return obj; - } - if (isFunction(obj)) { - return obj; - } - if (isArray(obj)) { - let copy = []; - for (var i = 0, len = obj.length; i < len; i++) { - copy[i] = clone(obj[i]); - } - return copy; - } - if (isObject(obj)) { - if (obj instanceof Date) { - let copy = /* @__PURE__ */ new Date(); - copy.setTime(obj.getTime()); - return copy; - } - if (typeof Element !== "undefined" && obj instanceof Element) - return obj; - if (typeof HTMLDocument !== "undefined" && obj instanceof HTMLDocument) - return obj; - if (typeof DocumentFragment !== "undefined" && obj instanceof DocumentFragment) - return obj; - if (obj === getGlobal()) - return obj; - if (typeof globalContext !== "undefined" && obj === globalContext) - return obj; - if (typeof window !== "undefined" && obj === window) - return obj; - if (typeof document !== "undefined" && obj === document) - return obj; - if (typeof navigator !== "undefined" && obj === navigator) - return obj; - if (typeof JSON !== "undefined" && obj === JSON) - return obj; - try { - if (obj instanceof Proxy) { - return obj; - } - } catch (e) { - } - return cloneObject(obj); - } - throw new Error("unable to clone obj! its type isn't supported."); - } - function cloneObject(obj) { - validateObject(obj); - const fkt = obj?.["constructor"]; - if (typeOf(fkt) === "function") { - const prototype = fkt?.prototype; - if (typeof prototype === "object") { - if (prototype.hasOwnProperty("getClone") && typeOf(obj.getClone) === "function") { - return obj.getClone(); - } - } - } - let copy = {}; - if (typeof obj.constructor === "function" && typeof obj.constructor.call === "function") { - copy = new obj.constructor(); - } - for (let key in obj) { - if (!obj.hasOwnProperty(key)) { - continue; - } - if (isPrimitive(obj[key])) { - copy[key] = obj[key]; - continue; - } - copy[key] = clone(obj[key]); - } - return copy; - } - var init_clone = __esm({ - "../application/source/util/clone.mjs"() { - init_global(); - init_is(); - init_typeof(); - init_validate(); - } - }); - - // ../application/source/i18n/locale.mjs - function parseLocale(locale) { - locale = validateString(locale).replace(/_/g, "-"); - let language; - let region; - let variants; - let parts; - let script; - let extlang; - let regexRegular = "(art-lojban|cel-gaulish|no-bok|no-nyn|zh-guoyu|zh-hakka|zh-min|zh-min-nan|zh-xiang)"; - let regexIrregular = "(en-GB-oed|i-ami|i-bnn|i-default|i-enochian|i-hak|i-klingon|i-lux|i-mingo|i-navajo|i-pwn|i-tao|i-tay|i-tsu|sgn-BE-FR|sgn-BE-NL|sgn-CH-DE)"; - let regexGrandfathered = `(${regexIrregular}|${regexRegular})`; - let regexPrivateUse = "(x(-[A-Za-z0-9]{1,8})+)"; - let regexSingleton = "[0-9A-WY-Za-wy-z]"; - let regexExtension = `(${regexSingleton}(-[A-Za-z0-9]{2,8})+)`; - let regexVariant = "([A-Za-z0-9]{5,8}|[0-9][A-Za-z0-9]{3})"; - let regexRegion = "([A-Za-z]{2}|[0-9]{3})"; - let regexScript = "([A-Za-z]{4})"; - let regexExtlang = "([A-Za-z]{3}(-[A-Za-z]{3}){0,2})"; - let regexLanguage = `(([A-Za-z]{2,3}(-${regexExtlang})?)|[A-Za-z]{4}|[A-Za-z]{5,8})`; - let regexLangtag = `(${regexLanguage}(-${regexScript})?(-${regexRegion})?(-${regexVariant})*(-${regexExtension})*(-${regexPrivateUse})?)`; - let regexLanguageTag = `^(${regexGrandfathered}|${regexLangtag}|${regexPrivateUse})$`; - let regex = new RegExp(regexLanguageTag); - let match; - if ((match = regex.exec(locale)) !== null) { - if (match.index === regex.lastIndex) { - regex.lastIndex++; - } - } - if (match === void 0 || match === null) { - throw new Error("unsupported locale"); - } - if (match[6] !== void 0) { - language = match[6]; - parts = language.split("-"); - if (parts.length > 1) { - language = parts[0]; - extlang = parts[1]; - } - } - if (match[14] !== void 0) { - region = match[14]; - } - if (match[12] !== void 0) { - script = match[12]; - } - if (match[16] !== void 0) { - variants = match[16]; - } - return new Locale(language, region, script, variants, extlang); - } - var propertiesSymbol, localeStringSymbol, Locale; - var init_locale = __esm({ - "../application/source/i18n/locale.mjs"() { - init_constants(); - init_base(); - init_validate(); - init_clone(); - propertiesSymbol = Symbol("properties"); - localeStringSymbol = Symbol("localeString"); - Locale = class extends Base { - /** - * @param {string} language - * @param {string} [region] - * @param {string} [script] - * @param {string} [variants] - * @param {string} [extlang] - * @param {string} [privateUse] - * @throws {Error} unsupported locale - */ - constructor(language, region, script, variants, extlang, privateUse) { - super(); - this[propertiesSymbol] = { - language: language === void 0 ? void 0 : validateString(language), - script: script === void 0 ? void 0 : validateString(script), - region: region === void 0 ? void 0 : validateString(region), - variants: variants === void 0 ? void 0 : validateString(variants), - extlang: extlang === void 0 ? void 0 : validateString(extlang), - privateUse: privateUse === void 0 ? void 0 : validateString(privateUse) - }; - let s = []; - if (language !== void 0) - s.push(language); - if (script !== void 0) - s.push(script); - if (region !== void 0) - s.push(region); - if (variants !== void 0) - s.push(variants); - if (extlang !== void 0) - s.push(extlang); - if (privateUse !== void 0) - s.push(privateUse); - if (s.length === 0) { - throw new Error("unsupported locale"); - } - this[localeStringSymbol] = s.join("-"); - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 3.27.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/i18n/locale@@instance"); - } - /** - * @return {string} - */ - get localeString() { - return this[localeStringSymbol]; - } - /** - * @return {string|undefined} - */ - get language() { - return this[propertiesSymbol].language; - } - /** - * @return {string|undefined} - */ - get region() { - return this[propertiesSymbol].region; - } - /** - * @return {string|undefined} - */ - get script() { - return this[propertiesSymbol].script; - } - /** - * @return {string|undefined} - */ - get variants() { - return this[propertiesSymbol].variants; - } - /** - * @return {string|undefined} - */ - get extlang() { - return this[propertiesSymbol].extlang; - } - /** - * @return {string|undefined} - */ - get privateUse() { - return this[propertiesSymbol].privateValue; - } - /** - * @return {string} - */ - toString() { - return `${this.localeString}`; - } - /** - * The structure has the following: language, script, region, variants, extlang, privateUse - * - * @return {Monster.I18n.LocaleMap} - */ - getMap() { - return clone(this[propertiesSymbol]); - } - }; - } - }); - - // ../application/source/dom/util.mjs - function getDocument() { - let document2 = getGlobal()?.["document"]; - if (typeof document2 !== "object") { - throw new Error("not supported environment"); - } - return document2; - } - function getWindow() { - let window2 = getGlobal()?.["window"]; - if (typeof window2 !== "object") { - throw new Error("not supported environment"); - } - return window2; - } - function getDocumentFragmentFromString(html) { - validateString(html); - const document2 = getDocument(); - const template = document2.createElement("template"); - template.innerHTML = html; - return template.content; - } - function findElementWithIdUpwards(element, targetId) { - if (!element) { - return null; - } - if (element.id === targetId) { - return element; - } - if (element.shadowRoot) { - const target = element.shadowRoot.getElementById(targetId); - if (target) { - return target; - } - } - if (element === document.documentElement) { - const target = document.getElementById(targetId); - if (target) { - return target; - } - } - const rootNode = element.getRootNode(); - if (rootNode && rootNode instanceof ShadowRoot) { - return findElementWithIdUpwards(rootNode.host, targetId); - } - return findElementWithIdUpwards(element.parentElement, targetId); - } - function traverseShadowRoots(element) { - let currentRoot = element.shadowRoot; - let currentParent = element.parentNode; - while (currentParent && currentParent.nodeType !== Node.DOCUMENT_NODE && currentParent.nodeType !== Node.DOCUMENT_FRAGMENT_NODE) { - if (currentRoot && currentRoot.parentNode) { - currentParent = currentRoot.parentNode; - currentRoot = currentParent.shadowRoot; - } else if (currentParent.parentNode) { - currentParent = currentParent.parentNode; - currentRoot = null; - } else if (currentRoot && currentRoot.host && currentRoot.host.nodeType === Node.DOCUMENT_NODE) { - currentParent = currentRoot.host; - currentRoot = null; - } else { - currentParent = null; - currentRoot = null; - } - } - return currentParent; - } - function getContainingDocument(element) { - if (!element || !(element instanceof HTMLElement || element instanceof element.ownerDocument.defaultView.HTMLElement)) { - throw new Error("Invalid argument. Expected an HTMLElement."); - } - return traverseShadowRoots(element) || null; - } - var init_util = __esm({ - "../application/source/dom/util.mjs"() { - init_global(); - init_validate(); - } - }); - - // ../application/source/dom/locale.mjs - function getLocaleOfDocument() { - const document2 = getDocument(); - let html = document2.querySelector("html"); - if (html instanceof HTMLElement && html.hasAttribute("lang")) { - let locale = html.getAttribute("lang"); - if (locale) { - return new parseLocale(locale); - } - } - let navigatorLanguage = getNavigatorLanguage(); - if (navigatorLanguage) { - return parseLocale(navigatorLanguage); - } - return parseLocale(DEFAULT_LANGUAGE); - } - var DEFAULT_LANGUAGE, getNavigatorLanguage; - var init_locale2 = __esm({ - "../application/source/dom/locale.mjs"() { - init_locale(); - init_util(); - init_global(); - DEFAULT_LANGUAGE = "en"; - getNavigatorLanguage = () => { - const navigator2 = getGlobalObject("navigator"); - if (navigator2 === void 0) { - return void 0; - } - if (navigator2.hasOwnProperty("language")) { - const language = navigator2.language; - if (typeof language === "string" && language.length > 0) { - return language; - } - } - const languages = navigator2?.languages; - if (Array.isArray(languages) && languages.length > 0) { - return languages[0]; - } - return void 0; - }; - } - }); - - // ../application/source/types/id.mjs - var internalCounter, ID; - var init_id = __esm({ - "../application/source/types/id.mjs"() { - init_base(); - init_validate(); - internalCounter = /* @__PURE__ */ new Map(); - ID = class extends Base { - /** - * create new id with prefix - * - * @param {string} prefix - */ - constructor(prefix) { - super(); - if (prefix === void 0) { - prefix = "id"; - } - validateString(prefix); - if (!internalCounter.has(prefix)) { - internalCounter.set(prefix, 1); - } - let count = internalCounter.get(prefix); - this.id = prefix + count; - internalCounter.set(prefix, ++count); - } - /** - * @return {string} - */ - toString() { - return this.id; - } - }; - } - }); - - // ../application/source/types/tokenlist.mjs - function toggleValue(token) { - if (!(this instanceof TokenList)) - throw Error("must be called with TokenList.call"); - validateString(token); - token = token.trim(); - if (this.contains(token)) { - this.remove(token); - return this; - } - this.add(token); - return this; - } - var TokenList; - var init_tokenlist = __esm({ - "../application/source/types/tokenlist.mjs"() { - init_is(); - init_validate(); - init_base(); - TokenList = class extends Base { - /** - * - * @param {array|string|iteratable} init - */ - constructor(init3) { - super(); - this.tokens = /* @__PURE__ */ new Set(); - if (typeof init3 !== "undefined") { - this.add(init3); - } - } - /** - * Iterator protocol - * - * @returns {Symbol.iterator} - */ - getIterator() { - return this[Symbol.iterator](); - } - /** - * Iterator - * - * @returns {{next: ((function(): ({value: *, done: boolean}))|*)}} - */ - [Symbol.iterator]() { - let index = 0; - let entries = this.entries(); - return { - next: () => { - if (index < entries.length) { - return { value: entries?.[index++], done: false }; - } else { - return { done: true }; - } - } - }; - } - /** - * Returns true if it contains token, otherwise false - * - * @externalExample ../../example/types/tokenlist-2.mjs - * @param {array|string|iteratable} value - * @returns {boolean} - */ - contains(value) { - if (isString(value)) { - value = value.trim(); - let counter = 0; - value.split(" ").forEach((token) => { - if (this.tokens.has(token.trim()) === false) - return false; - counter++; - }); - return counter > 0 ? true : false; - } - if (isIterable(value)) { - let counter = 0; - for (let token of value) { - validateString(token); - if (this.tokens.has(token.trim()) === false) - return false; - counter++; - } - return counter > 0 ? true : false; - } - return false; - } - /** - * Add tokens - * - * @externalExample ../../example/types/tokenlist-3.mjs - * @param {array|string|iteratable} value - * @returns {TokenList} - * @throws {TypeError} unsupported value - */ - add(value) { - if (isString(value)) { - value.split(" ").forEach((token) => { - this.tokens.add(token.trim()); - }); - } else if (isIterable(value)) { - for (let token of value) { - validateString(token); - this.tokens.add(token.trim()); - } - } else if (typeof value !== "undefined") { - throw new TypeError("unsupported value"); - } - return this; - } - /** - * remove all tokens - * - * @returns {TokenList} - */ - clear() { - this.tokens.clear(); - return this; - } - /** - * Removes token - * - * @externalExample ../../example/types/tokenlist-4.mjs - * @param {array|string|iteratable} value - * @returns {TokenList} - * @throws {TypeError} unsupported value - */ - remove(value) { - if (isString(value)) { - value.split(" ").forEach((token) => { - this.tokens.delete(token.trim()); - }); - } else if (isIterable(value)) { - for (let token of value) { - validateString(token); - this.tokens.delete(token.trim()); - } - } else if (typeof value !== "undefined") { - throw new TypeError("unsupported value", "types/tokenlist.mjs"); - } - return this; - } - /** - * this method replaces a token with a new token. - * - * if the passed token exists, it is replaced with newToken and TokenList is returned. - * if the token does not exist, newToken is not set and TokenList is returned. - * - * @param {string} token - * @param {string} newToken - * @returns {TokenList} - */ - replace(token, newToken) { - validateString(token); - validateString(newToken); - if (!this.contains(token)) { - return this; - } - let a2 = Array.from(this.tokens); - let i = a2.indexOf(token); - if (i === -1) - return this; - a2.splice(i, 1, newToken); - this.tokens = /* @__PURE__ */ new Set(); - this.add(a2); - return this; - } - /** - * Removes token from string. If token doesn't exist it's added. - * - * @externalExample ../../example/types/tokenlist-5.mjs - * @param {array|string|iteratable} value - * @returns {boolean} - * @throws {TypeError} unsupported value - */ - toggle(value) { - if (isString(value)) { - value.split(" ").forEach((token) => { - toggleValue.call(this, token); - }); - } else if (isIterable(value)) { - for (let token of value) { - toggleValue.call(this, token); - } - } else if (typeof value !== "undefined") { - throw new TypeError("unsupported value", "types/tokenlist.mjs"); - } - return this; - } - /** - * returns an array with all tokens - * - * @returns {array} - */ - entries() { - return Array.from(this.tokens); - } - /** - * executes the provided function with each value of the set - * - * @param {function} callback - * @returns {TokenList} - */ - forEach(callback) { - validateFunction(callback); - this.tokens.forEach(callback); - return this; - } - /** - * returns the individual tokens separated by a blank character - * - * @returns {string} - */ - toString() { - return this.entries().join(" "); - } - }; - } - }); - - // ../application/source/dom/constants.mjs - var DEFAULT_THEME, ATTRIBUTE_PREFIX, ATTRIBUTE_OPTIONS, ATTRIBUTE_OPTIONS_SELECTOR, ATTRIBUTE_THEME_PREFIX, ATTRIBUTE_THEME_NAME, ATTRIBUTE_UPDATER_ATTRIBUTES, ATTRIBUTE_UPDATER_SELECT_THIS, ATTRIBUTE_UPDATER_REPLACE, ATTRIBUTE_UPDATER_INSERT, ATTRIBUTE_UPDATER_INSERT_REFERENCE, ATTRIBUTE_UPDATER_REMOVE, ATTRIBUTE_UPDATER_BIND, ATTRIBUTE_TEMPLATE_PREFIX, ATTRIBUTE_ROLE, ATTRIBUTE_DISABLED, ATTRIBUTE_VALUE, ATTRIBUTE_OBJECTLINK, ATTRIBUTE_ERRORMESSAGE, objectUpdaterLinkSymbol, customElementUpdaterLinkSymbol, TAG_SCRIPT, TAG_LINK, ATTRIBUTE_ID, ATTRIBUTE_CLASS, ATTRIBUTE_TITLE, ATTRIBUTE_SRC, ATTRIBUTE_HREF, ATTRIBUTE_TYPE, ATTRIBUTE_NONCE; - var init_constants2 = __esm({ - "../application/source/dom/constants.mjs"() { - DEFAULT_THEME = "monster"; - ATTRIBUTE_PREFIX = "data-monster-"; - ATTRIBUTE_OPTIONS = `${ATTRIBUTE_PREFIX}options`; - ATTRIBUTE_OPTIONS_SELECTOR = `${ATTRIBUTE_PREFIX}options-selector`; - ATTRIBUTE_THEME_PREFIX = `${ATTRIBUTE_PREFIX}theme-`; - ATTRIBUTE_THEME_NAME = `${ATTRIBUTE_THEME_PREFIX}name`; - ATTRIBUTE_UPDATER_ATTRIBUTES = `${ATTRIBUTE_PREFIX}attributes`; - ATTRIBUTE_UPDATER_SELECT_THIS = `${ATTRIBUTE_PREFIX}select-this`; - ATTRIBUTE_UPDATER_REPLACE = `${ATTRIBUTE_PREFIX}replace`; - ATTRIBUTE_UPDATER_INSERT = `${ATTRIBUTE_PREFIX}insert`; - ATTRIBUTE_UPDATER_INSERT_REFERENCE = `${ATTRIBUTE_PREFIX}insert-reference`; - ATTRIBUTE_UPDATER_REMOVE = `${ATTRIBUTE_PREFIX}remove`; - ATTRIBUTE_UPDATER_BIND = `${ATTRIBUTE_PREFIX}bind`; - ATTRIBUTE_TEMPLATE_PREFIX = `${ATTRIBUTE_PREFIX}template-prefix`; - ATTRIBUTE_ROLE = `${ATTRIBUTE_PREFIX}role`; - ATTRIBUTE_DISABLED = "disabled"; - ATTRIBUTE_VALUE = "value"; - ATTRIBUTE_OBJECTLINK = `${ATTRIBUTE_PREFIX}objectlink`; - ATTRIBUTE_ERRORMESSAGE = `${ATTRIBUTE_PREFIX}error`; - objectUpdaterLinkSymbol = Symbol.for("@schukai/monster/dom/@@object-updater-link"); - customElementUpdaterLinkSymbol = Symbol.for("@schukai/monster/dom/custom-element@@options-updater-link"); - TAG_SCRIPT = "script"; - TAG_LINK = "link"; - ATTRIBUTE_ID = "id"; - ATTRIBUTE_CLASS = "class"; - ATTRIBUTE_TITLE = "title"; - ATTRIBUTE_SRC = "src"; - ATTRIBUTE_HREF = "href"; - ATTRIBUTE_TYPE = "type"; - ATTRIBUTE_NONCE = "nonce"; - } - }); - - // ../application/source/dom/attributes.mjs - function findClosestObjectLink(element) { - return findClosestByAttribute(element, ATTRIBUTE_OBJECTLINK); - } - function addToObjectLink(element, symbol2, object) { - validateInstance(element, HTMLElement); - validateSymbol(symbol2); - if (element?.[symbol2] === void 0) { - element[symbol2] = /* @__PURE__ */ new Set(); - } - addAttributeToken(element, ATTRIBUTE_OBJECTLINK, symbol2.toString()); - element[symbol2].add(object); - return element; - } - function removeObjectLink(element, symbol2) { - validateInstance(element, HTMLElement); - validateSymbol(symbol2); - if (element?.[symbol2] === void 0) { - return element; - } - removeAttributeToken(element, ATTRIBUTE_OBJECTLINK, symbol2.toString()); - delete element[symbol2]; - return element; - } - function hasObjectLink(element, symbol2) { - validateInstance(element, HTMLElement); - validateSymbol(symbol2); - if (element?.[symbol2] === void 0) { - return false; - } - return containsAttributeToken(element, ATTRIBUTE_OBJECTLINK, symbol2.toString()); - } - function getLinkedObjects(element, symbol2) { - validateInstance(element, HTMLElement); - validateSymbol(symbol2); - if (element?.[symbol2] === void 0) { - throw new Error(`there is no object link for ${symbol2.toString()}`); - } - return element?.[symbol2][Symbol.iterator](); - } - function toggleAttributeToken(element, key, token) { - validateInstance(element, HTMLElement); - validateString(token); - validateString(key); - if (!element.hasAttribute(key)) { - element.setAttribute(key, token); - return element; - } - element.setAttribute(key, new TokenList(element.getAttribute(key)).toggle(token).toString()); - return element; - } - function addAttributeToken(element, key, token) { - validateInstance(element, HTMLElement); - validateString(token); - validateString(key); - if (!element.hasAttribute(key)) { - element.setAttribute(key, token); - return element; - } - element.setAttribute(key, new TokenList(element.getAttribute(key)).add(token).toString()); - return element; - } - function removeAttributeToken(element, key, token) { - validateInstance(element, HTMLElement); - validateString(token); - validateString(key); - if (!element.hasAttribute(key)) { - return element; - } - element.setAttribute(key, new TokenList(element.getAttribute(key)).remove(token).toString()); - return element; - } - function containsAttributeToken(element, key, token) { - validateInstance(element, HTMLElement); - validateString(token); - validateString(key); - if (!element.hasAttribute(key)) { - return false; - } - return new TokenList(element.getAttribute(key)).contains(token); - } - function replaceAttributeToken(element, key, from, to) { - validateInstance(element, HTMLElement); - validateString(from); - validateString(to); - validateString(key); - if (!element.hasAttribute(key)) { - return element; - } - element.setAttribute(key, new TokenList(element.getAttribute(key)).replace(from, to).toString()); - return element; - } - function clearAttributeTokens(element, key) { - validateInstance(element, HTMLElement); - validateString(key); - if (!element.hasAttribute(key)) { - return element; - } - element.setAttribute(key, ""); - return element; - } - function findClosestByAttribute(element, key, value) { - validateInstance(element, getGlobalFunction("HTMLElement")); - if (element.hasAttribute(key)) { - if (value === void 0) { - return element; - } - if (element.getAttribute(key) === value) { - return element; - } - } - let selector = validateString(key); - if (value !== void 0) - selector += `=${validateString(value)}`; - let result = element.closest(`[${selector}]`); - if (result instanceof HTMLElement) { - return result; - } - return void 0; - } - function findClosestByClass(element, className) { - validateInstance(element, getGlobalFunction("HTMLElement")); - if (element?.classList?.contains(validateString(className))) { - return element; - } - let result = element.closest(`.${className}`); - if (result instanceof HTMLElement) { - return result; - } - return void 0; - } - var init_attributes = __esm({ - "../application/source/dom/attributes.mjs"() { - init_global(); - init_tokenlist(); - init_validate(); - init_constants2(); - } - }); - - // ../application/source/types/stack.mjs - var Stack; - var init_stack = __esm({ - "../application/source/types/stack.mjs"() { - init_base(); - init_constants(); - Stack = class extends Base { - /** - * - */ - constructor() { - super(); - this.data = []; - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/types/stack"); - } - /** - * @return {boolean} - */ - isEmpty() { - return this.data.length === 0; - } - /** - * looks at the object at the top of this stack without removing it from the stack. - * - * @return {*} - */ - peek() { - if (this.isEmpty()) { - return void 0; - } - return this.data?.[this.data.length - 1]; - } - /** - * pushes an item onto the top of this stack. - * - * @param {*} value - * @returns {Queue} - */ - push(value) { - this.data.push(value); - return this; - } - /** - * remove all entries - * - * @returns {Queue} - */ - clear() { - this.data = []; - return this; - } - /** - * removes the object at the top of this stack and returns - * that object as the value of this function. is the stack empty - * the return value is undefined. - * - * @return {*} - */ - pop() { - if (this.isEmpty()) { - return void 0; - } - return this.data.pop(); - } - }; - } - }); - - // ../application/source/data/pathfinder.mjs - function iterate(subject, path, check) { - if (check === void 0) { - check = false; - } - validateBoolean(check); - const result = /* @__PURE__ */ new Map(); - if (isArray(path)) { - path = path.join(DELIMITER); - } - if (isObject(subject) || isArray(subject)) { - for (const [key, value] of Object.entries(subject)) { - result.set(key, getValueViaPath.call(this, value, path, check)); - } - } else { - let key = path.split(DELIMITER).shift(); - result.set(key, getValueViaPath.call(this, subject, path, check)); - } - return result; - } - function getValueViaPath(subject, path, check) { - if (check === void 0) { - check = false; - } - validateBoolean(check); - if (!(isArray(path) || isString(path))) { - throw new Error("type error: path must be a string or an array"); - } - let parts; - if (isString(path)) { - if (path === "") { - return subject; - } - parts = path.split(DELIMITER); - } - let current = parts.shift(); - if (current === this.wildCard) { - return iterate.call(this, subject, parts.join(DELIMITER), check); - } - if (isObject(subject) || isArray(subject)) { - let anchor; - if (subject instanceof Map || subject instanceof WeakMap) { - anchor = subject.get(current); - } else if (subject instanceof Set || subject instanceof WeakSet) { - current = parseInt(current); - validateInteger(current); - anchor = [...subject]?.[current]; - } else if (typeof WeakRef === "function" && subject instanceof WeakRef) { - throw Error("unsupported action for this data type"); - } else if (isArray(subject)) { - current = parseInt(current); - validateInteger(current); - anchor = subject?.[current]; - } else { - anchor = subject?.[current]; - } - if (isObject(anchor) || isArray(anchor)) { - return getValueViaPath.call(this, anchor, parts.join(DELIMITER), check); - } - if (parts.length > 0) { - throw Error(`the journey is not at its end (${parts.join(DELIMITER)})`); - } - if (check === true) { - const descriptor = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(subject), current); - if (!subject.hasOwnProperty(current) && descriptor === void 0) { - throw Error("unknown value"); - } - } - return anchor; - } - throw TypeError(`unsupported type ${typeof subject}`); - } - function setValueViaPath(subject, path, value) { - if (!(isArray(path) || isString(path))) { - throw new Error("type error: path must be a string or an array"); - } - let parts; - if (isArray(path)) { - if (path.length === 0) { - return subject; - } - parts = path; - } else { - parts = path.split(DELIMITER); - } - let last = parts.pop(); - let subpath = parts.join(DELIMITER); - let stack = new Stack(); - let current = subpath; - while (true) { - try { - getValueViaPath.call(this, subject, current, true); - break; - } catch (e) { - } - stack.push(current); - parts.pop(); - current = parts.join(DELIMITER); - if (current === "") - break; - } - while (!stack.isEmpty()) { - current = stack.pop(); - let obj = {}; - if (!stack.isEmpty()) { - let n = stack.peek().split(DELIMITER).pop(); - if (isInteger(parseInt(n))) { - obj = []; - } - } - setValueViaPath.call(this, subject, current, obj); - } - let anchor = getValueViaPath.call(this, subject, subpath); - if (!(isObject(subject) || isArray(subject))) { - throw TypeError(`unsupported type: ${typeof subject}`); - } - if (anchor instanceof Map || anchor instanceof WeakMap) { - anchor.set(last, value); - } else if (anchor instanceof Set || anchor instanceof WeakSet) { - anchor.append(value); - } else if (typeof WeakRef === "function" && anchor instanceof WeakRef) { - throw Error("unsupported action for this data type"); - } else if (isArray(anchor)) { - last = parseInt(last); - validateInteger(last); - assignProperty(anchor, last, value); - } else { - assignProperty(anchor, last, value); - } - } - function assignProperty(object, key, value) { - if (!object.hasOwnProperty(key)) { - object[key] = value; - return; - } - if (value === void 0) { - delete object[key]; - } - object[key] = value; - } - function deleteValueViaPath(subject, path) { - if (!(isArray(path) || isString(path))) { - throw new Error("type error: path must be a string or an array"); - } - let parts; - if (isArray(path)) { - if (path.length === 0) { - return subject; - } - parts = path; - } else { - parts = path.split(DELIMITER); - } - let last = parts.pop(); - const subpath = parts.join(DELIMITER); - const anchor = getValueViaPath.call(this, subject, subpath); - if (anchor instanceof Map) { - anchor.delete(last); - } else if (anchor instanceof Set || anchor instanceof WeakMap || anchor instanceof WeakSet || typeof WeakRef === "function" && anchor instanceof WeakRef) { - throw Error("unsupported action for this data type"); - } else if (isArray(anchor)) { - last = parseInt(last); - validateInteger(last); - delete anchor[last]; - } else { - delete anchor[last]; - } - } - var DELIMITER, WILDCARD, Pathfinder; - var init_pathfinder = __esm({ - "../application/source/data/pathfinder.mjs"() { - init_base(); - init_is(); - init_stack(); - init_validate(); - DELIMITER = "."; - WILDCARD = "*"; - Pathfinder = class extends Base { - /** - * @param {array|object|Map|Set} value - * @since 1.4.0 - * @throws {Error} the parameter must not be a simple type - **/ - constructor(object) { - super(); - if (isPrimitive(object)) { - throw new Error("the parameter must not be a simple type"); - } - this.object = object; - this.wildCard = WILDCARD; - } - /** - * set wildcard - * - * @param {string} wildcard - * @return {Pathfinder} - * @since 1.7.0 - */ - setWildCard(wildcard) { - validateString(wildcard); - this.wildCard = wildcard; - return this; - } - /** - * - * @param {string|array} path - * @since 1.4.0 - * @returns {*} - * @throws {TypeError} unsupported type - * @throws {Error} the journey is not at its end - * @throws {TypeError} value is not a string - * @throws {TypeError} value is not an integer - * @throws {Error} unsupported action for this data type - */ - getVia(path) { - return getValueViaPath.call(this, this.object, path); - } - /** - * - * @param {string|array} path - * @param {*} value - * @returns {Pathfinder} - * @since 1.4.0 - * @throws {TypeError} unsupported type - * @throws {TypeError} value is not a string - * @throws {TypeError} value is not an integer - * @throws {Error} unsupported action for this data type - */ - setVia(path, value) { - setValueViaPath.call(this, this.object, path, value); - return this; - } - /** - * Delete Via Path - * - * @param {string|array} path - * @returns {Pathfinder} - * @since 1.6.0 - * @throws {TypeError} unsupported type - * @throws {TypeError} value is not a string - * @throws {TypeError} value is not an integer - * @throws {Error} unsupported action for this data type - */ - deleteVia(path) { - deleteValueViaPath.call(this, this.object, path); - return this; - } - /** - * - * @param {string|array} path - * @return {bool} - * @throws {TypeError} unsupported type - * @throws {TypeError} value is not a string - * @throws {TypeError} value is not an integer - * @since 1.4.0 - */ - exists(path) { - try { - getValueViaPath.call(this, this.object, path, true); - return true; - } catch (e) { - } - return false; - } - }; - } - }); - - // ../application/source/types/basewithoptions.mjs - var BaseWithOptions; - var init_basewithoptions = __esm({ - "../application/source/types/basewithoptions.mjs"() { - init_constants(); - init_extend(); - init_pathfinder(); - init_base(); - init_validate(); - BaseWithOptions = class extends Base { - /** - * - * @param {object} options - */ - constructor(options) { - super(); - if (options === void 0) { - options = {}; - } - this[internalSymbol] = extend({}, this.defaults, validateObject(options)); - } - /** - * This getter provides the options. Derived classes overwrite - * this getter with their own values. It is good karma to always include - * the values from the parent class. - * - * ```javascript - * get defaults() { - * return Object.assign({}, super.defaults, { - * mykey: true - * }); - * } - * - * ``` - * - * @return {object} - */ - get defaults() { - return {}; - } - /** - * nested options can be specified by path `a.b.c` - * - * @param {string} path - * @param {*} defaultValue - * @return {*} - * @since 1.10.0 - */ - getOption(path, defaultValue) { - let value; - try { - value = new Pathfinder(this[internalSymbol]).getVia(path); - } catch (e) { - } - if (value === void 0) - return defaultValue; - return value; - } - }; - } - }); - - // ../application/source/i18n/provider.mjs - var translationsLinkSymbol, Provider; - var init_provider = __esm({ - "../application/source/i18n/provider.mjs"() { - init_constants(); - init_attributes(); - init_locale2(); - init_basewithoptions(); - init_locale(); - init_translations(); - translationsLinkSymbol = Symbol.for("@schukai/monster/i18n/translations@@link"); - Provider = class extends BaseWithOptions { - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 3.27.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/i18n/provider@@instance"); - } - /** - * @param {Locale|string} locale - * @return {Promise} - */ - getTranslations(locale) { - if (locale === void 0) { - locale = getLocaleOfDocument(); - } - return new Promise((resolve, reject) => { - try { - resolve(new Translations(locale)); - } catch (e) { - reject(e); - } - }); - } - /** - * @param {Locale|string} locale - * @param {HTMLElement} element - * @return {Provider} - */ - assignToElement(locale, element) { - if (locale === void 0) { - locale = getLocaleOfDocument(); - } - if (!(locale instanceof Locale)) { - throw new Error("Locale is not an instance of Locale"); - } - if (!(element instanceof HTMLElement)) { - element = document.querySelector("body"); - } - if (!(element instanceof HTMLElement)) { - throw new Error("Element is not an HTMLElement"); - } - return this.getTranslations(locale).then((obj) => { - let translations = null; - if (hasObjectLink(element, translationsLinkSymbol)) { - const objects = getLinkedObjects(element, translationsLinkSymbol); - for (const o of objects) { - if (o instanceof Translations) { - translations = o; - break; - } - } - if (!(translations instanceof Translations)) { - throw new Error("Object is not an instance of Translations"); - } - translations.assignTranslations(obj); - } else { - addToObjectLink(element, translationsLinkSymbol, obj); - } - return obj; - }); - } - }; - } - }); - - // ../application/source/i18n/translations.mjs - function getDocumentTranslations(element) { - const d = getDocument(); - if (!(element instanceof HTMLElement)) { - element = d.querySelector(`[${ATTRIBUTE_OBJECTLINK}~="${translationsLinkSymbol.toString()}"]`); - if (element === null) { - throw new Error("Cannot find element with translations. Add a translations object to the document."); - } - } - if (!(element instanceof HTMLElement)) { - throw new Error("Element is not an HTMLElement."); - } - if (!hasObjectLink(element, translationsLinkSymbol)) { - throw new Error("This element has no translations."); - } - let obj = getLinkedObjects(element, translationsLinkSymbol); - for (const t of obj) { - if (t instanceof Translations) { - return t; - } - } - throw new Error("Missing translations."); - } - var Translations; - var init_translations = __esm({ - "../application/source/i18n/translations.mjs"() { - init_constants(); - init_attributes(); - init_constants2(); - init_util(); - init_base(); - init_is(); - init_validate(); - init_locale(); - init_provider(); - Translations = class extends Base { - /** - * - * @param {Locale} locale - */ - constructor(locale) { - super(); - if (locale instanceof Locale) { - this.locale = locale; - } else { - this.locale = parseLocale(validateString(locale)); - } - this.storage = /* @__PURE__ */ new Map(); - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 3.27.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/i18n/translations@@instance"); - } - /** - * Fetches a text using the specified key. - * If no suitable key is found, `defaultText` is taken. - * - * @param {string} key - * @param {string|undefined} defaultText - * @return {string} - * @throws {Error} key not found - */ - getText(key, defaultText) { - if (!this.storage.has(key)) { - if (defaultText === void 0) { - throw new Error(`key ${key} not found`); - } - return validateString(defaultText); - } - let r = this.storage.get(key); - if (isObject(r)) { - return this.getPluralRuleText(key, "other", defaultText); - } - return this.storage.get(key); - } - /** - * A number `count` can be passed to this method. In addition to a number, one of the keywords can also be passed directly. - * "zero", "one", "two", "few", "many" and "other". Remember: not every language has all rules. - * - * The appropriate text for this number is then selected. If no suitable key is found, `defaultText` is taken. - * - * @param {string} key - * @param {integer|count} count - * @param {string|undefined} defaultText - * @return {string} - */ - getPluralRuleText(key, count, defaultText) { - if (!this.storage.has(key)) { - return validateString(defaultText); - } - let r = validateObject(this.storage.get(key)); - let keyword; - if (isString(count)) { - keyword = count.toLocaleString(); - } else { - count = validateInteger(count); - if (count === 0) { - if (r.hasOwnProperty("zero")) { - return validateString(r["zero"]); - } - } - keyword = new Intl.PluralRules(this.locale.toString()).select(validateInteger(count)); - } - if (r.hasOwnProperty(keyword)) { - return validateString(r[keyword]); - } - return validateString(defaultText); - } - /** - * Set a text for a key - * - * ``` - * translations.setText("text1", "Make my day!"); - * // plural rules - * translations.setText("text6", { - * "zero": "There are no files on Disk.", - * "one": "There is one file on Disk.", - * "other": "There are files on Disk." - * "default": "There are files on Disk." - * }); - * ``` - * - * @param {string} key - * @param {string|object} text - * @return {Translations} - * @throws {TypeError} value is not a string or object - */ - setText(key, text) { - if (isString(text) || isObject(text)) { - this.storage.set(validateString(key), text); - return this; - } - throw new TypeError("value is not a string or object"); - } - /** - * This method can be used to transfer overlays from an object. The keys are transferred, and the values are entered - * as text. - * - * The values can either be character strings or, in the case of texts with plural forms, objects. The plural forms - * must be stored as text via a standard key "zero", "one", "two", "few", "many" and "other". - * - * Additionally, the key default can be specified, which will be used if no other key fits. - * - * In some languages, like for example in German, there is no own more number at the value 0. In these languages, - * the function applies additionally zero. - * - * ``` - * translations.assignTranslations({ - * "text1": "Make my day!", - * "text2": "I'll be back!", - * "text6": { - * "zero": "There are no files on Disk.", - * "one": "There is one file on Disk.", - * "other": "There are files on Disk." - * "default": "There are files on Disk." - * }); - * ``` - * - * @param {object} translations - * @return {Translations} - */ - assignTranslations(translations) { - validateObject(translations); - if (translations instanceof Translations) { - translations.storage.forEach((v, k) => { - this.setText(k, v); - }); - return this; - } - for (const [k, v] of Object.entries(translations)) { - this.setText(k, v); - } - return this; - } - }; - } - }); - - // ../application/source/data/transformer.mjs - function disassemble(command) { - validateString(command); - let placeholder = /* @__PURE__ */ new Map(); - const regex = /((?<pattern>\\(?<char>.)){1})/gim; - let result = command.matchAll(regex); - for (let m of result) { - let g = m?.["groups"]; - if (!isObject(g)) { - continue; - } - let p = g?.["pattern"]; - let c = g?.["char"]; - if (p && c) { - let r = `__${new ID().toString()}__`; - placeholder.set(r, c); - command = command.replace(p, r); - } - } - let parts = command.split(":"); - parts = parts.map(function(value) { - let v = value.trim(); - for (let k of placeholder) { - v = v.replace(k[0], k[1]); - } - return v; - }); - return parts; - } - function convertToString(value) { - if (isObject(value) && value.hasOwnProperty("toString")) { - value = value.toString(); - } - validateString(value); - return value; - } - function transform(value) { - const console2 = getGlobalObject("console"); - let args = clone(this.args); - let key; - let defaultValue; - let translations; - let date; - let locale; - let timestamp; - let map; - let keyValue; - switch (this.command) { - case "static": - return this.args.join(":"); - case "tolower": - case "strtolower": - case "tolowercase": - validateString(value); - return value.toLowerCase(); - case "contains": - if (isString(value)) { - return value.includes(args[0]); - } - if (isArray(value)) { - return value.includes(args[0]); - } - if (isObject(value)) { - return value.hasOwnProperty(args[0]); - } - return false; - case "has-entries": - case "hasentries": - if (isObject(value)) { - return Object.keys(value).length > 0; - } - if (isArray(value)) { - return value.length > 0; - } - return false; - case "isundefined": - case "is-undefined": - return value === void 0; - case "isnull": - case "is-null": - return value === null; - case "isset": - case "is-set": - return value !== void 0 && value !== null; - case "isnumber": - case "is-number": - return isPrimitive(value) && !isNaN(value); - case "isinteger": - case "is-integer": - return isPrimitive(value) && !isNaN(value) && value % 1 === 0; - case "isfloat": - case "is-float": - return isPrimitive(value) && !isNaN(value) && value % 1 !== 0; - case "isobject": - case "is-object": - return isObject(value); - case "isarray": - case "is-array": - return Array.isArray(value); - case "not": - validateBoolean(value); - return !value; - case "toupper": - case "strtoupper": - case "touppercase": - validateString(value); - return value.toUpperCase(); - case "tostring": - return `${value}`; - case "tointeger": - let n = parseInt(value); - validateInteger(n); - return n; - case "to-json": - case "tojson": - return JSON.stringify(value); - case "from-json": - case "fromjson": - return JSON.parse(value); - case "trim": - validateString(value); - return value.trim(); - case "rawurlencode": - validateString(value); - return encodeURIComponent(value).replace(/!/g, "%21").replace(/'/g, "%27").replace(/\(/g, "%28").replace(/\)/g, "%29").replace(/\*/g, "%2A"); - case "call": - let callback; - let callbackName = args.shift(); - let context = getGlobal(); - if (isObject(value) && value.hasOwnProperty(callbackName)) { - callback = value[callbackName]; - } else if (this.callbacks.has(callbackName)) { - let s = this.callbacks.get(callbackName); - callback = s?.["callback"]; - context = s?.["context"]; - } else if (typeof window === "object" && window.hasOwnProperty(callbackName)) { - callback = window[callbackName]; - } - validateFunction(callback); - args.unshift(value); - return callback.call(context, ...args); - case "plain": - case "plaintext": - validateString(value); - let doc = new DOMParser().parseFromString(value, "text/html"); - return doc.body.textContent || ""; - case "if": - case "?": - validatePrimitive(value); - let trueStatement = args.shift() || void 0; - let falseStatement = args.shift() || void 0; - if (trueStatement === "value") { - trueStatement = value; - } - if (trueStatement === "\\value") { - trueStatement = "value"; - } - if (trueStatement === "\\undefined") { - trueStatement = void 0; - } - if (trueStatement === "\\null") { - trueStatement = null; - } - if (falseStatement === "value") { - falseStatement = value; - } - if (falseStatement === "\\value") { - falseStatement = "value"; - } - if (falseStatement === "\\undefined") { - falseStatement = void 0; - } - if (falseStatement === "\\null") { - falseStatement = null; - } - let condition = value !== void 0 && value !== "" && value !== "off" && value !== "false" && value !== false || value === "on" || value === "true" || value === true; - return condition ? trueStatement : falseStatement; - case "ucfirst": - validateString(value); - let firstchar = value.charAt(0).toUpperCase(); - return firstchar + value.substr(1); - case "ucwords": - validateString(value); - return value.replace(/^([a-z\u00E0-\u00FC])|\s+([a-z\u00E0-\u00FC])/g, function(v) { - return v.toUpperCase(); - }); - case "count": - case "length": - if ((isString(value) || isObject(value) || isArray(value)) && value.hasOwnProperty("length")) { - return value.length; - } - throw new TypeError(`unsupported type ${typeof value}`); - case "to-base64": - case "btoa": - case "base64": - return btoa(convertToString(value)); - case "atob": - case "from-base64": - return atob(convertToString(value)); - case "empty": - return ""; - case "undefined": - return void 0; - case "debug": - if (isObject(console2)) { - console2.log(value); - } - return value; - case "prefix": - validateString(value); - let prefix = args?.[0]; - return prefix + value; - case "suffix": - validateString(value); - let suffix = args?.[0]; - return value + suffix; - case "uniqid": - return new ID().toString(); - case "first-key": - case "last-key": - case "nth-last-key": - case "nth-key": - if (!isObject(value)) { - throw new Error("type not supported"); - } - const keys = Object.keys(value).sort(); - if (this.command === "first-key") { - key = 0; - } else if (this.command === "last-key") { - key = keys.length - 1; - } else { - key = validateInteger(parseInt(args.shift())); - if (this.command === "nth-last-key") { - key = keys.length - key - 1; - } - } - defaultValue = args.shift() || ""; - let useKey = keys?.[key]; - if (value?.[useKey]) { - return value?.[useKey]; - } - return defaultValue; - case "key": - case "property": - case "index": - key = args.shift() || void 0; - if (key === void 0) { - throw new Error("missing key parameter"); - } - defaultValue = args.shift() || void 0; - if (value instanceof Map) { - if (!value.has(key)) { - return defaultValue; - } - return value.get(key); - } - if (isObject(value) || isArray(value)) { - if (value?.[key]) { - return value?.[key]; - } - return defaultValue; - } - throw new Error("type not supported"); - case "path-exists": - key = args.shift(); - if (key === void 0) { - throw new Error("missing key parameter"); - } - return new Pathfinder(value).exists(key); - case "concat": - let pf2 = new Pathfinder(value); - let concat2 = ""; - while (args.length > 0) { - key = args.shift(); - if (key === void 0) { - throw new Error("missing key parameter"); - } - if (isString(key) && key.trim() === "") { - concat2 += key; - continue; - } - if (!pf2.exists(key)) { - concat2 += key; - continue; - } - let v = pf2.getVia(key); - if (!isPrimitive(v)) { - throw new Error("value is not primitive"); - } - concat2 += v; - } - return concat2; - case "path": - key = args.shift(); - if (key === void 0) { - throw new Error("missing key parameter"); - } - let pf = new Pathfinder(value); - if (!pf.exists(key)) { - return void 0; - } - return pf.getVia(key); - case "substring": - validateString(value); - let start = parseInt(args[0]) || 0; - let end = (parseInt(args[1]) || 0) + start; - return value.substring(start, end); - case "nop": - return value; - case "??": - case "default": - if (value !== void 0 && value !== null) { - return value; - } - defaultValue = args.shift(); - let defaultType = args.shift(); - if (defaultType === void 0) { - defaultType = "string"; - } - switch (defaultType) { - case "int": - case "integer": - return parseInt(defaultValue); - case "float": - return parseFloat(defaultValue); - case "undefined": - return void 0; - case "bool": - case "boolean": - defaultValue = defaultValue.toLowerCase(); - return defaultValue !== "undefined" && defaultValue !== "" && defaultValue !== "off" && defaultValue !== "false" && defaultValue !== "false" || defaultValue === "on" || defaultValue === "true" || defaultValue === "true"; - case "string": - return `${defaultValue}`; - case "object": - return JSON.parse(atob(defaultValue)); - } - throw new Error("type not supported"); - case "map": - map = /* @__PURE__ */ new Map(); - while (args.length > 0) { - keyValue = args.shift(); - if (keyValue === void 0) { - throw new Error("missing key parameter"); - } - keyValue = keyValue.split("="); - map.set(keyValue[0], keyValue[1]); - } - return map.get(value); - case "equals": - if (args.length === 0) { - throw new Error("missing value parameter"); - } - validatePrimitive(value); - const equalsValue = args.shift(); - if (value === null) { - if (equalsValue === "null") { - return true; - } - return false; - } - const typeOfValue = typeof value; - switch (typeOfValue) { - case "string": - return value === equalsValue; - case "number": - return value === parseFloat(equalsValue); - case "boolean": - return value === (equalsValue === "true" || equalsValue === "on"); - case "undefined": - return equalsValue === "undefined"; - default: - throw new Error("type not supported"); - } - case "money": - case "currency": - try { - locale = getLocaleOfDocument(); - } catch (e) { - throw new Error(`unsupported locale or missing format (${e.message})`); - } - const currency = value.substring(0, 3); - if (!currency) { - throw new Error("missing currency parameter"); - } - const maximumFractionDigits = args?.[0] || 2; - const roundingIncrement = args?.[1] || 5; - const nf = new Intl.NumberFormat(locale, { - style: "currency", - currency, - maximumFractionDigits, - roundingIncrement - }); - return nf.format(value.substring(3)); - case "timestamp": - date = new Date(value); - timestamp = date.getTime(); - if (isNaN(timestamp)) { - throw new Error("invalid date"); - } - return timestamp; - case "time": - date = new Date(value); - if (isNaN(date.getTime())) { - throw new Error("invalid date"); - } - try { - locale = getLocaleOfDocument(); - return date.toLocaleTimeString(locale); - } catch (e) { - throw new Error(`unsupported locale or missing format (${e.message})`); - } - case "datetime": - date = new Date(value); - if (isNaN(date.getTime())) { - throw new Error("invalid date"); - } - try { - locale = getLocaleOfDocument(); - return date.toLocaleString(locale); - } catch (e) { - throw new Error(`unsupported locale or missing format (${e.message})`); - } - case "date": - date = new Date(value); - if (isNaN(date.getTime())) { - throw new Error("invalid date"); - } - try { - locale = getLocaleOfDocument(); - return date.toLocaleDateString(locale); - } catch (e) { - throw new Error(`unsupported locale or missing format (${e.message})`); - } - case "year": - date = new Date(value); - if (isNaN(date.getTime())) { - throw new Error("invalid date"); - } - return date.getFullYear(); - case "month": - date = new Date(value); - if (isNaN(date.getTime())) { - throw new Error("invalid date"); - } - return date.getMonth() + 1; - case "day": - date = new Date(value); - if (isNaN(date.getTime())) { - throw new Error("invalid date"); - } - return date.getDate(); - case "weekday": - date = new Date(value); - if (isNaN(date.getTime())) { - throw new Error("invalid date"); - } - return date.getDay(); - case "hour": - case "hours": - date = new Date(value); - if (isNaN(date.getTime())) { - throw new Error("invalid date"); - } - return date.getHours(); - case "minute": - case "minutes": - date = new Date(value); - if (isNaN(date.getTime())) { - throw new Error("invalid date"); - } - return date.getMinutes(); - case "second": - case "seconds": - date = new Date(value); - if (isNaN(date.getTime())) { - throw new Error("invalid date"); - } - return date.getSeconds(); - case "i18n": - case "translation": - translations = getDocumentTranslations(); - if (!(translations instanceof Translations)) { - throw new Error("missing translations"); - } - key = args.shift() || void 0; - if (key === void 0) { - key = value; - } - defaultValue = args.shift() || void 0; - return translations.getText(key, defaultValue); - default: - throw new Error(`unknown command ${this.command}`); - } - } - var Transformer; - var init_transformer = __esm({ - "../application/source/data/transformer.mjs"() { - init_locale2(); - init_base(); - init_global(); - init_id(); - init_is(); - init_translations(); - init_validate(); - init_clone(); - init_pathfinder(); - Transformer = class extends Base { - /** - * - * @param {string} definition - */ - constructor(definition) { - super(); - this.args = disassemble(definition); - this.command = this.args.shift(); - this.callbacks = /* @__PURE__ */ new Map(); - } - /** - * - * @param {string} name - * @param {function} callback - * @param {object} context - * @returns {Transformer} - * @throws {TypeError} value is not a string - * @throws {TypeError} value is not a function - */ - setCallback(name, callback, context) { - validateString(name); - validateFunction(callback); - if (context !== void 0) { - validateObject(context); - } - this.callbacks.set(name, { - callback, - context - }); - return this; - } - /** - * - * @param {*} value - * @returns {*} - * @throws {Error} unknown command - * @throws {TypeError} unsupported type - * @throws {Error} type not supported - */ - run(value) { - return transform.apply(this, [value]); - } - }; - } - }); - - // ../application/source/data/pipe.mjs - var DELIMITER2, Pipe; - var init_pipe = __esm({ - "../application/source/data/pipe.mjs"() { - init_base(); - init_validate(); - init_transformer(); - DELIMITER2 = "|"; - Pipe = class extends Base { - /** - * @param {string} pipe a pipe consists of commands whose input and output are connected with the pipe symbol `|`. - * @throws {TypeError} - */ - constructor(pipe) { - super(); - validateString(pipe); - this.pipe = pipe.split(DELIMITER2).map((v) => { - return new Transformer(v); - }); - } - /** - * @param {string} name - * @param {function} callback - * @param {object} context - * @returns {Transformer} - * @throws {TypeError} value is not a string - * @throws {TypeError} value is not a function - */ - setCallback(name, callback, context) { - for (const [, t] of Object.entries(this.pipe)) { - t.setCallback(name, callback, context); - } - return this; - } - /** - * run a pipe - * - * @param {*} value - * @returns {*} - */ - run(value) { - return this.pipe.reduce((accumulator, transformer, currentIndex, array) => { - return transformer.run(accumulator); - }, value); - } - }; - } - }); - - // ../application/source/text/formatter.mjs - function format(text) { - const self2 = this; - self2[watchdogSymbol]++; - if (this[watchdogSymbol] > 20) { - throw new Error("too deep nesting"); - } - let openMarker = self2[internalSymbol]["marker"]["open"]?.[this[markerOpenIndexSymbol]]; - let closeMarker = self2[internalSymbol]["marker"]["close"]?.[this[markerCloseIndexSymbol]]; - if (text.indexOf(openMarker) === -1 || text.indexOf(closeMarker) === -1) { - return text; - } - let result = tokenize.call(this, validateString(text), openMarker, closeMarker); - if (self2[internalSymbol]["marker"]["open"]?.[this[markerOpenIndexSymbol] + 1]) { - this[markerOpenIndexSymbol]++; - } - if (self2[internalSymbol]["marker"]["close"]?.[this[markerCloseIndexSymbol] + 1]) { - this[markerCloseIndexSymbol]++; - } - result = format.call(self2, result); - return result; - } - function tokenize(text, openMarker, closeMarker) { - const self2 = this; - let formatted = []; - const parameterAssignment = self2[internalSymbol]["parameter"]["assignment"]; - const parameterDelimiter = self2[internalSymbol]["parameter"]["delimiter"]; - const callbacks = self2[internalSymbol]["callbacks"]; - while (true) { - let startIndex = text.indexOf(openMarker); - if (startIndex === -1) { - formatted.push(text); - break; - } else if (startIndex > 0) { - formatted.push(text.substring(0, startIndex)); - text = text.substring(startIndex); - } - let endIndex = text.substring(openMarker.length).indexOf(closeMarker); - if (endIndex !== -1) - endIndex += openMarker.length; - let insideStartIndex = text.substring(openMarker.length).indexOf(openMarker); - if (insideStartIndex !== -1) { - insideStartIndex += openMarker.length; - if (insideStartIndex < endIndex) { - let result = tokenize.call(self2, text.substring(insideStartIndex), openMarker, closeMarker); - text = text.substring(0, insideStartIndex) + result; - endIndex = text.substring(openMarker.length).indexOf(closeMarker); - if (endIndex !== -1) - endIndex += openMarker.length; - } - } - if (endIndex === -1) { - throw new Error("syntax error in formatter template"); - } - let key = text.substring(openMarker.length, endIndex); - let parts = key.split(parameterDelimiter); - let currentPipe = parts.shift(); - self2[workingDataSymbol] = extend({}, self2[internalObjectSymbol], self2[workingDataSymbol]); - for (const kv of parts) { - const [k, v] = kv.split(parameterAssignment); - self2[workingDataSymbol][k] = v; - } - const t1 = key.split("|").shift().trim(); - const t2 = t1.split("::").shift().trim(); - const t3 = t2.split(".").shift().trim(); - let prefix = self2[workingDataSymbol]?.[t3] ? "path:" : "static:"; - let command = ""; - if (prefix && key.indexOf(prefix) !== 0 && key.indexOf("path:") !== 0 && key.indexOf("static:") !== 0) { - command = prefix; - } - command += currentPipe; - const pipe = new Pipe(command); - if (isObject(callbacks)) { - for (const [name, callback] of Object.entries(callbacks)) { - pipe.setCallback(name, callback); - } - } - formatted.push(validateString(pipe.run(self2[workingDataSymbol]))); - text = text.substring(endIndex + closeMarker.length); - } - return formatted.join(""); - } - var internalObjectSymbol, watchdogSymbol, markerOpenIndexSymbol, markerCloseIndexSymbol, workingDataSymbol, Formatter; - var init_formatter = __esm({ - "../application/source/text/formatter.mjs"() { - init_constants(); - init_extend(); - init_pipe(); - init_basewithoptions(); - init_is(); - init_validate(); - internalObjectSymbol = Symbol("internalObject"); - watchdogSymbol = Symbol("watchdog"); - markerOpenIndexSymbol = Symbol("markerOpenIndex"); - markerCloseIndexSymbol = Symbol("markercloseIndex"); - workingDataSymbol = Symbol("workingData"); - Formatter = class extends BaseWithOptions { - /** - * Default values for the markers are `${` and `}` - * - * @param {object} object - * @throws {TypeError} value is not a object - */ - constructor(object, options) { - super(options); - this[internalObjectSymbol] = object || {}; - this[markerOpenIndexSymbol] = 0; - this[markerCloseIndexSymbol] = 0; - } - /** - * @property {object} marker - * @property {array} marker.open=["${"] - * @property {array} marker.close=["${"] - * @property {object} parameter - * @property {string} parameter.delimiter="::" - * @property {string} parameter.assignment="=" - * @property {object} callbacks={} - */ - get defaults() { - return extend({}, super.defaults, { - marker: { - open: ["${"], - close: ["}"] - }, - parameter: { - delimiter: "::", - assignment: "=" - }, - callbacks: {} - }); - } - /** - * Set new Parameter Character - * - * Default values for the chars are `::` and `=` - * - * ``` - * formatter.setParameterChars('#'); - * formatter.setParameterChars('[',']'); - * formatter.setParameterChars('i18n{','}'); - * ``` - * - * @param {string} delimiter - * @param {string} assignment - * @return {Formatter} - * @since 1.24.0 - * @throws {TypeError} value is not a string - */ - setParameterChars(delimiter, assignment) { - if (delimiter !== void 0) { - this[internalSymbol]["parameter"]["delimiter"] = validateString(delimiter); - } - if (assignment !== void 0) { - this[internalSymbol]["parameter"]["assignment"] = validateString(assignment); - } - return this; - } - /** - * Set new Marker - * - * Default values for the markers are `${` and `}` - * - * ``` - * formatter.setMarker('#'); // open and close are both # - * formatter.setMarker('[',']'); - * formatter.setMarker('i18n{','}'); - * ``` - * - * @param {array|string} open - * @param {array|string|undefined} close - * @return {Formatter} - * @since 1.12.0 - * @throws {TypeError} value is not a string - */ - setMarker(open, close) { - if (close === void 0) { - close = open; - } - if (isString(open)) - open = [open]; - if (isString(close)) - close = [close]; - this[internalSymbol]["marker"]["open"] = validateArray(open); - this[internalSymbol]["marker"]["close"] = validateArray(close); - return this; - } - /** - * - * @param {string} text - * @return {string} - * @throws {TypeError} value is not a string - * @throws {Error} too deep nesting - */ - format(text) { - this[watchdogSymbol] = 0; - this[markerOpenIndexSymbol] = 0; - this[markerCloseIndexSymbol] = 0; - this[workingDataSymbol] = {}; - return format.call(this, text); - } - }; - } - }); - - // ../application/source/dom/slotted.mjs - function getSlottedNodes(query, name) { - const self2 = this; - const result = /* @__PURE__ */ new Set(); - if (!self2.shadowRoot) { - return result; - } - let selector = "slot"; - if (name !== void 0) { - if (name === null) { - selector += ":not([name])"; - } else { - selector += `[name=${validateString(name)}]`; - } - } - const slots = self2.shadowRoot.querySelectorAll(selector); - for (const [, slot] of Object.entries(slots)) { - slot.assignedNodes().forEach(function(node) { - if (node === null || node === void 0) { - return; - } - if (isString(query)) { - node.querySelectorAll(query).forEach(function(n) { - result.add(n); - }); - if (node.matches(query)) { - result.add(node); - } - } else if (query !== void 0) { - throw new Error("query must be a string"); - } else { - result.add(node); - } - }); - } - return result; - } - function getSlottedElements(query, name) { - const self2 = this; - const result = /* @__PURE__ */ new Set(); - if (!(self2.shadowRoot instanceof ShadowRoot)) { - return result; - } - let selector = "slot"; - if (name !== void 0) { - if (name === null) { - selector += ":not([name])"; - } else { - selector += `[name=${validateString(name)}]`; - } - } - const slots = self2.shadowRoot.querySelectorAll(selector); - for (const [, slot] of Object.entries(slots)) { - slot.assignedElements().forEach(function(node) { - if (!(node instanceof HTMLElement)) - return; - if (isString(query)) { - node.querySelectorAll(query).forEach(function(n) { - result.add(n); - }); - if (node.matches(query)) { - result.add(node); - } - } else if (query !== void 0) { - throw new Error("query must be a string"); - } else { - result.add(node); - } - }); - } - return result; - } - var init_slotted = __esm({ - "../application/source/dom/slotted.mjs"() { - init_is(); - init_validate(); - } - }); - - // ../application/source/types/queue.mjs - var Queue; - var init_queue = __esm({ - "../application/source/types/queue.mjs"() { - init_base(); - init_constants(); - Queue = class extends Base { - /** - * - */ - constructor() { - super(); - this.data = []; - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/types/queue"); - } - /** - * @return {boolean} - */ - isEmpty() { - return this.data.length === 0; - } - /** - * Read the element at the front of the queue without removing it. - * - * @return {*} - */ - peek() { - if (this.isEmpty()) { - return void 0; - } - return this.data[0]; - } - /** - * Add a new element to the end of the queue. - * - * @param {*} value - * @returns {Queue} - */ - add(value) { - this.data.push(value); - return this; - } - /** - * remove all entries - * - * @returns {Queue} - */ - clear() { - this.data = []; - return this; - } - /** - * Remove the element at the front of the queue - * If the queue is empty, return undefined. - * - * @return {*} - */ - poll() { - if (this.isEmpty()) { - return void 0; - } - return this.data.shift(); - } - }; - } - }); - - // ../application/source/types/uniquequeue.mjs - var UniqueQueue; - var init_uniquequeue = __esm({ - "../application/source/types/uniquequeue.mjs"() { - init_queue(); - init_constants(); - init_validate(); - UniqueQueue = class extends Queue { - /** - * - */ - constructor() { - super(); - this[internalSymbol] = { - unique: /* @__PURE__ */ new WeakSet() - }; - } - /** - * Add a new element to the end of the queue. - * - * @param {object} value - * @returns {Queue} - * @throws {TypeError} value is not a object - */ - add(value) { - validateObject(value); - if (!this[internalSymbol].unique.has(value)) { - this[internalSymbol].unique.add(value); - super.add(value); - } - return this; - } - /** - * remove all entries - * - * @returns {Queue} - */ - clear() { - super.clear(); - this[internalSymbol].unique = /* @__PURE__ */ new WeakSet(); - return this; - } - /** - * Remove the element at the front of the queue - * If the queue is empty, return undefined. - * - * @return {object} - */ - poll() { - if (this.isEmpty()) { - return void 0; - } - let value = this.data.shift(); - this[internalSymbol].unique.delete(value); - return value; - } - }; - } - }); - - // ../application/source/types/observer.mjs - var Observer; - var init_observer = __esm({ - "../application/source/types/observer.mjs"() { - init_base(); - init_is(); - init_tokenlist(); - init_uniquequeue(); - init_constants(); - Observer = class extends Base { - /** - * - * @param {function} callback - * @param {*} args - */ - constructor(callback, ...args) { - super(); - if (typeof callback !== "function") { - throw new Error("observer callback must be a function"); - } - this.callback = callback; - this.arguments = args; - this.tags = new TokenList(); - this.queue = new UniqueQueue(); - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/types/observer"); - } - /** - * - * @param {string} tag - * @returns {Observer} - */ - addTag(tag) { - this.tags.add(tag); - return this; - } - /** - * - * @param {string} tag - * @returns {Observer} - */ - removeTag(tag) { - this.tags.remove(tag); - return this; - } - /** - * - * @returns {Array} - */ - getTags() { - return this.tags.entries(); - } - /** - * - * @param {string} tag - * @returns {boolean} - */ - hasTag(tag) { - return this.tags.contains(tag); - } - /** - * - * @param {object} subject - * @returns {Promise} - */ - update(subject) { - let self2 = this; - return new Promise(function(resolve, reject) { - if (!isObject(subject)) { - reject("subject must be an object"); - return; - } - self2.queue.add(subject); - setTimeout(() => { - try { - if (self2.queue.isEmpty()) { - resolve(); - return; - } - let s = self2.queue.poll(); - let result = self2.callback.apply(s, self2.arguments); - if (isObject(result) && result instanceof Promise) { - result.then(resolve).catch(reject); - return; - } - resolve(result); - } catch (e) { - reject(e); - } - }, 0); - }); - } - }; - } - }); - - // ../application/source/types/observerlist.mjs - var ObserverList; - var init_observerlist = __esm({ - "../application/source/types/observerlist.mjs"() { - init_base(); - init_observer(); - init_validate(); - ObserverList = class extends Base { - /** - * - */ - constructor() { - super(); - this.observers = []; - } - /** - * - * @param {Observer} observer - * @return {ObserverList} - * @throws {TypeError} value is not an instance of Observer - */ - attach(observer) { - validateInstance(observer, Observer); - this.observers.push(observer); - return this; - } - /** - * - * @param {Observer} observer - * @return {ObserverList} - * @throws {TypeError} value is not an instance of Observer - */ - detach(observer) { - validateInstance(observer, Observer); - var i = 0; - var l = this.observers.length; - for (; i < l; i++) { - if (this.observers[i] === observer) { - this.observers.splice(i, 1); - } - } - return this; - } - /** - * - * @param {Observer} observer - * @return {boolean} - * @throws {TypeError} value is not an instance of Observer - */ - contains(observer) { - validateInstance(observer, Observer); - var i = 0; - var l = this.observers.length; - for (; i < l; i++) { - if (this.observers[i] === observer) { - return true; - } - } - return false; - } - /** - * - * @param subject - * @return {Promise} - */ - notify(subject) { - let pomises = []; - let i = 0; - let l = this.observers.length; - for (; i < l; i++) { - pomises.push(this.observers[i].update(subject)); - } - return Promise.all(pomises); - } - }; - } - }); - - // ../application/source/types/proxyobserver.mjs - function getHandler() { - const proxy = this; - const handler = { - // https://262.ecma-international.org/9.0/#sec-proxy-object-internal-methods-and-internal-slots-get-p-receiver - get: function(target, key, receiver) { - const value = Reflect.get(target, key, receiver); - if (typeof key === "symbol") { - return value; - } - if (isPrimitive(value)) { - return value; - } - if (isArray(value) || isObject(value)) { - if (proxy.objectMap.has(value)) { - return proxy.objectMap.get(value); - } else if (proxy.proxyMap.has(value)) { - return value; - } else { - let p = new Proxy(value, handler); - proxy.objectMap.set(value, p); - proxy.proxyMap.set(p, value); - return p; - } - } - return value; - }, - // https://262.ecma-international.org/9.0/#sec-proxy-object-internal-methods-and-internal-slots-set-p-v-receiver - set: function(target, key, value, receiver) { - if (proxy.proxyMap.has(value)) { - value = proxy.proxyMap.get(value); - } - if (proxy.proxyMap.has(target)) { - target = proxy.proxyMap.get(target); - } - let current = Reflect.get(target, key, receiver); - if (proxy.proxyMap.has(current)) { - current = proxy.proxyMap.get(current); - } - if (current === value) { - return true; - } - let result; - let descriptor = Reflect.getOwnPropertyDescriptor(target, key); - if (descriptor === void 0) { - descriptor = { - writable: true, - enumerable: true, - configurable: true - }; - } - descriptor["value"] = value; - result = Reflect.defineProperty(target, key, descriptor); - if (typeof key !== "symbol") { - proxy.observers.notify(proxy); - } - return result; - }, - // https://262.ecma-international.org/9.0/#sec-proxy-object-internal-methods-and-internal-slots-delete-p - deleteProperty: function(target, key) { - if (key in target) { - delete target[key]; - if (typeof key !== "symbol") { - proxy.observers.notify(proxy); - } - return true; - } - return false; - }, - // https://262.ecma-international.org/9.0/#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc - defineProperty: function(target, key, descriptor) { - let result = Reflect.defineProperty(target, key, descriptor); - if (typeof key !== "symbol") { - proxy.observers.notify(proxy); - } - return result; - }, - // https://262.ecma-international.org/9.0/#sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v - setPrototypeOf: function(target, key) { - let result = Reflect.setPrototypeOf(object1, key); - if (typeof key !== "symbol") { - proxy.observers.notify(proxy); - } - return result; - } - }; - return handler; - } - var ProxyObserver; - var init_proxyobserver = __esm({ - "../application/source/types/proxyobserver.mjs"() { - init_base(); - init_is(); - init_observer(); - init_observerlist(); - init_validate(); - init_extend(); - init_constants(); - ProxyObserver = class extends Base { - /** - * - * @param {object} object - * @throws {TypeError} value is not a object - */ - constructor(object) { - super(); - this.realSubject = validateObject(object); - this.subject = new Proxy(object, getHandler.call(this)); - this.objectMap = /* @__PURE__ */ new WeakMap(); - this.objectMap.set(this.realSubject, this.subject); - this.proxyMap = /* @__PURE__ */ new WeakMap(); - this.proxyMap.set(this.subject, this.realSubject); - this.observers = new ObserverList(); - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/types/proxy-observer"); - } - /** - * Get the real object - * - * Changes to this object are not noticed by the observers, so you can make a large number of changes and inform the observers later. - * - * @returns {object} - */ - getSubject() { - return this.subject; - } - /** - * @since 1.24.0 - * @param {Object} obj - * @return {Monster.Types.ProxyObserver} - */ - setSubject(obj) { - let i; - let k = Object.keys(this.subject); - for (i = 0; i < k.length; i++) { - delete this.subject[k[i]]; - } - this.subject = extend(this.subject, obj); - return this; - } - /** - * get the proxied object - * - * @returns {object} - */ - getRealSubject() { - return this.realSubject; - } - /** - * attach a new observer - * - * @param {Observer} observer - * @returns {ProxyObserver} - */ - attachObserver(observer) { - this.observers.attach(observer); - return this; - } - /** - * detach a observer - * - * @param {Observer} observer - * @returns {ProxyObserver} - */ - detachObserver(observer) { - this.observers.detach(observer); - return this; - } - /** - * notify all observer - * - * @returns {Promise} - */ - notifyObservers() { - return this.observers.notify(this); - } - /** - * @param {Observer} observer - * @returns {boolean} - */ - containsObserver(observer) { - return this.observers.contains(observer); - } - }; - } - }); - - // ../application/source/dom/resource.mjs - var resource_exports = {}; - __export(resource_exports, { - KEY_DOCUMENT: () => KEY_DOCUMENT, - KEY_QUERY: () => KEY_QUERY, - Resource: () => Resource, - referenceSymbol: () => referenceSymbol - }); - function appendToDocument() { - const self2 = this; - const targetNode = document.querySelector(self2.getOption(KEY_QUERY, "head")); - if (!(targetNode instanceof HTMLElement)) { - throw new Error("target not found"); - } - addEvents.call(self2); - targetNode.appendChild(self2[referenceSymbol]); - return self2; - } - function addEvents() { - const self2 = this; - const onError = () => { - self2[referenceSymbol].removeEventListener("error", onError); - self2[referenceSymbol].removeEventListener("load", onLoad); - self2[internalStateSymbol].setSubject({ - loaded: true, - error: `${self2[referenceSymbol][self2.constructor.getURLAttribute()]} is not available` - }); - return; - }; - const onLoad = () => { - self2[referenceSymbol].removeEventListener("error", onError); - self2[referenceSymbol].removeEventListener("load", onLoad); - self2[internalStateSymbol].getSubject()["loaded"] = true; - return; - }; - self2[referenceSymbol].addEventListener("load", onLoad, false); - self2[referenceSymbol].addEventListener("error", onError, false); - return self2; - } - var KEY_DOCUMENT, KEY_QUERY, KEY_TIMEOUT, referenceSymbol, Resource; - var init_resource = __esm({ - "../application/source/dom/resource.mjs"() { - init_constants(); - init_extend(); - init_basewithoptions(); - init_global(); - init_id(); - init_is(); - init_observer(); - init_proxyobserver(); - init_constants2(); - init_constants(); - KEY_DOCUMENT = "document"; - KEY_QUERY = "query"; - KEY_TIMEOUT = "timeout"; - referenceSymbol = Symbol("reference"); - Resource = class extends BaseWithOptions { - /** - * - * @param {Object|undefined} options - */ - constructor(options) { - super(options); - let uri = this.getOption(this.constructor.getURLAttribute()); - if (uri === void 0) { - throw new Error("missing source"); - } else if (uri instanceof URL) { - uri = uri.toString(); - } else if (!isString(uri)) { - throw new Error("unsupported url type"); - } - this[internalSymbol][this.constructor.getURLAttribute()] = uri; - this[internalStateSymbol] = new ProxyObserver({ - loaded: false, - error: void 0 - }); - this[referenceSymbol] = void 0; - } - /** - * @return {boolean} - */ - isConnected() { - if (this[referenceSymbol] instanceof HTMLElement) { - return this[referenceSymbol].isConnected; - } - return false; - } - /** - * This method is overridden by the special classes and creates the DOM object. - * This method is also called implicitly, if not yet done explicitly, by calling `connect()`. - * - * @throws {Error} this method must be implemented by derived classes - * @return {Monster.DOM.Resource} - */ - create() { - throw new Error("this method must be implemented by derived classes"); - } - /** - * This method appends the HTMLElement to the specified document. - * If the element has not yet been created, `create()` is called implicitly. - * - * throws {Error} target not found - * @return {Monster.DOM.Resource} - */ - connect() { - if (!(this[referenceSymbol] instanceof HTMLElement)) { - this.create(); - } - appendToDocument.call(this); - return this; - } - /** - * @property {Document} document the document object into which the node is to be appended - * @property {string} src/href url to the corresponding resource - * @property {string} query defines the location where the resource is to be hooked into the dom. - * @property {string} id element attribute id - * @property {string} title element attribute title - * @property {string} class element attribute class - * @property {int} timeout timeout - */ - get defaults() { - return extend({}, super.defaults, { - [this.constructor.getURLAttribute()]: void 0, - [KEY_DOCUMENT]: getGlobalObject("document"), - [KEY_QUERY]: "head", - [KEY_TIMEOUT]: 1e4, - [ATTRIBUTE_ID]: new ID("resource").toString(), - [ATTRIBUTE_CLASS]: void 0, - [ATTRIBUTE_TITLE]: void 0 - }); - } - /** - * With `available()` you can check if a resource is available. - * This is the case when the tag is included and the resource is loaded. - * - * @return {Promise} - */ - available() { - const self2 = this; - if (!(self2[referenceSymbol] instanceof HTMLElement)) { - return Promise.reject("no element"); - } - if (!self2.isConnected()) { - return Promise.reject("element not connected"); - } - if (self2[internalStateSymbol].getSubject()["loaded"] === true) { - if (self2[internalStateSymbol].getSubject()["error"] !== void 0) { - return Promise.reject(self2[internalStateSymbol].getSubject()["error"]); - } - return Promise.resolve(); - } - return new Promise(function(resolve, reject) { - const timeout = setTimeout(() => { - reject("timeout"); - }, self2.getOption("timeout")); - const observer = new Observer(() => { - clearTimeout(timeout); - self2[internalStateSymbol].detachObserver(observer); - resolve(); - }); - self2[internalStateSymbol].attachObserver(observer); - }); - } - /** - * @return {string} - */ - static getURLAttribute() { - throw new Error("this method must be implemented by derived classes"); - } - /** - * @return {symbol} - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/dom/resource"); - } - }; - } - }); - - // ../application/source/types/mediatype.mjs - function parseMediaType(mediatype) { - const regex = /(?<type>[A-Za-z]+|\*)\/(?<subtype>([a-zA-Z0-9.\+_\-]+)|\*|)(?<parameter>\s*;\s*([a-zA-Z0-9]+)\s*(=\s*("?[A-Za-z0-9_\-]+"?))?)*/g; - const result = regex.exec(validateString(mediatype)); - const groups = result?.["groups"]; - if (groups === void 0) { - throw new TypeError("the mimetype can not be parsed"); - } - const type = groups?.["type"]; - const subtype = groups?.["subtype"]; - const parameter = groups?.["parameter"]; - if (subtype === "" || type === "") { - throw new TypeError("blank value is not allowed"); - } - return new MediaType(type, subtype, parseParameter(parameter)); - } - function parseParameter(parameter) { - if (!isString(parameter)) { - return void 0; - } - let result = []; - parameter.split(";").forEach((entry) => { - entry = entry.trim(); - if (entry === "") { - return; - } - const kv = entry.split("="); - let key = validateString(kv?.[0]).trim(); - let value = validateString(kv?.[1]).trim(); - result.push({ - key, - value - }); - }); - return result; - } - var internal, MediaType; - var init_mediatype = __esm({ - "../application/source/types/mediatype.mjs"() { - init_base(); - init_is(); - init_validate(); - init_constants(); - internal = Symbol("internal"); - MediaType = class extends Base { - /** - * - * @param {String} type - * @param {String} subtype - * @param {Monster.Types.Parameter[]} parameter - */ - constructor(type, subtype, parameter) { - super(); - this[internal] = { - type: validateString(type).toLowerCase(), - subtype: validateString(subtype).toLowerCase(), - parameter: [] - }; - if (parameter !== void 0) { - this[internal]["parameter"] = validateArray(parameter); - } - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/types/media-type"); - } - /** - * @return {String} - */ - get type() { - return this[internal].type; - } - /** - * @return {String} - */ - get subtype() { - return this[internal].subtype; - } - /** - * @return {Monster.Types.Parameter[]} - */ - get parameter() { - return this[internal].parameter; - } - /** - * - * - * @return {Map} - */ - get parameter() { - const result = /* @__PURE__ */ new Map(); - this[internal]["parameter"].forEach((p) => { - let value = p.value; - if (value.startsWith('"') && value.endsWith('"')) { - value = value.substring(1, value.length - 1); - } - result.set(p.key, value); - }); - return result; - } - /** - * - * @return {string} - */ - toString() { - let parameter = []; - for (let a2 of this[internal].parameter) { - parameter.push(`${a2.key}=${a2.value}`); - } - return `${this[internal].type}/${this[internal].subtype}${parameter.length > 0 ? `;${parameter.join(";")}` : ""}`; - } - }; - } - }); - - // ../application/source/types/dataurl.mjs - function parseDataURL(dataurl) { - validateString(dataurl); - dataurl = dataurl.trim(); - if (dataurl.substring(0, 5) !== "data:") { - throw new TypeError("incorrect or missing data protocol"); - } - dataurl = dataurl.substring(5); - let p = dataurl.indexOf(","); - if (p === -1) { - throw new TypeError("malformed data url"); - } - let content = dataurl.substring(p + 1); - let mediatypeAndBase64 = dataurl.substring(0, p).trim(); - let mediatype = "text/plain;charset=US-ASCII"; - let base64Flag = false; - if (mediatypeAndBase64 !== "") { - mediatype = mediatypeAndBase64; - if (mediatypeAndBase64.endsWith("base64")) { - let i = mediatypeAndBase64.lastIndexOf(";"); - mediatype = mediatypeAndBase64.substring(0, i); - base64Flag = true; - } else { - content = decodeURIComponent(content); - } - mediatype = parseMediaType(mediatype); - } else { - content = decodeURIComponent(content); - } - return new DataUrl(content, mediatype, base64Flag); - } - var internal2, DataUrl; - var init_dataurl = __esm({ - "../application/source/types/dataurl.mjs"() { - init_base(); - init_is(); - init_mediatype(); - init_validate(); - init_constants(); - internal2 = Symbol("internal"); - DataUrl = class extends Base { - /** - * - * @param {String} content - * @param {String|Monster.Types.MediaType} mediatype - * @param {boolean} base64=true - */ - constructor(content, mediatype, base64) { - super(); - if (isString(mediatype)) { - mediatype = parseMediaType(mediatype); - } - this[internal2] = { - content: validateString(content), - mediatype: validateInstance(mediatype, MediaType), - base64: validateBoolean(base64 === void 0 ? true : base64) - }; - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/types/data-url"); - } - get content() { - return this[internal2].base64 ? atob(this[internal2].content) : this[internal2].content; - } - get mediatype() { - return this[internal2].mediatype; - } - /** - * - * @return {string} - * @see https://datatracker.ietf.org/doc/html/rfc2397 - */ - toString() { - let content = this[internal2].content; - if (this[internal2].base64 === true) { - content = `;base64,${content}`; - } else { - content = `,${encodeURIComponent(content)}`; - } - return `data:${this[internal2].mediatype.toString()}${content}`; - } - }; - } - }); - - // ../application/source/data/diff.mjs - function diff(first, second) { - return doDiff(first, second); - } - function getKeys(a2, b, type) { - if (isArray(type)) { - const keys = a2.length > b.length ? new Array(a2.length) : new Array(b.length); - keys.fill(0); - return new Set(keys.map((_, i) => i)); - } - return new Set(Object.keys(a2).concat(Object.keys(b))); - } - function doDiff(a2, b, path, diff2) { - let typeA = typeOf(a2); - let typeB = typeOf(b); - const currPath = path || []; - const currDiff = diff2 || []; - if (typeA === typeB && (typeA === "object" || typeA === "array")) { - getKeys(a2, b, typeA).forEach((v) => { - if (!Object.prototype.hasOwnProperty.call(a2, v)) { - currDiff.push(buildResult(a2[v], b[v], "add", currPath.concat(v))); - } else if (!Object.prototype.hasOwnProperty.call(b, v)) { - currDiff.push(buildResult(a2[v], b[v], "delete", currPath.concat(v))); - } else { - doDiff(a2[v], b[v], currPath.concat(v), currDiff); - } - }); - } else { - const o = getOperator(a2, b, typeA, typeB); - if (o !== void 0) { - currDiff.push(buildResult(a2, b, o, path)); - } - } - return currDiff; - } - function buildResult(a2, b, operator, path) { - const result = { - operator, - path - }; - if (operator !== "add") { - result.first = { - value: a2, - type: typeof a2 - }; - if (isObject(a2)) { - const name = Object.getPrototypeOf(a2)?.constructor?.name; - if (name !== void 0) { - result.first.instance = name; - } - } - } - if (operator === "add" || operator === "update") { - result.second = { - value: b, - type: typeof b - }; - if (isObject(b)) { - const name = Object.getPrototypeOf(b)?.constructor?.name; - if (name !== void 0) { - result.second.instance = name; - } - } - } - return result; - } - function isNotEqual(a2, b) { - if (typeof a2 !== typeof b) { - return true; - } - if (a2 instanceof Date && b instanceof Date) { - return a2.getTime() !== b.getTime(); - } - return a2 !== b; - } - function getOperator(a2, b) { - let operator; - let typeA = typeof a2; - let typeB = typeof b; - if (typeA === "undefined" && typeB !== "undefined") { - operator = "add"; - } else if (typeA !== "undefined" && typeB === "undefined") { - operator = "delete"; - } else if (isNotEqual(a2, b)) { - operator = "update"; - } - return operator; - } - var init_diff = __esm({ - "../application/source/data/diff.mjs"() { - init_is(); - init_typeof(); - } - }); - - // ../application/source/util/trimspaces.mjs - function trimSpaces(value) { - validateString(value); - let placeholder = /* @__PURE__ */ new Map(); - const regex = /((?<pattern>\\(?<char>.)){1})/gim; - let result = value.matchAll(regex); - for (let m of result) { - let g = m?.["groups"]; - if (!isObject(g)) { - continue; - } - let p = g?.["pattern"]; - let c = g?.["char"]; - if (p && c) { - let r = `__${new ID().toString()}__`; - placeholder.set(r, c); - value = value.replace(p, r); - } - } - value = value.trim(); - placeholder.forEach((v, k) => { - value = value.replace(k, `\\${v}`); - }); - return value; - } - var init_trimspaces = __esm({ - "../application/source/util/trimspaces.mjs"() { - init_id(); - init_is(); - init_validate(); - } - }); - - // ../application/source/dom/events.mjs - function fireEvent(element, type) { - const document2 = getDocument(); - if (element instanceof HTMLElement) { - if (type === "click") { - element.click(); - return; - } - let event = new Event(validateString(type), { - bubbles: true, - cancelable: true, - composed: true - }); - element.dispatchEvent(event); - } else if (element instanceof HTMLCollection || element instanceof NodeList) { - for (let e of element) { - fireEvent(e, type); - } - } else { - throw new TypeError("value is not an instance of HTMLElement or HTMLCollection"); - } - } - function fireCustomEvent(element, type, detail) { - const document2 = getDocument(); - if (element instanceof HTMLElement) { - if (!isObject(detail)) { - detail = { detail }; - } - let event = new CustomEvent(validateString(type), { - bubbles: true, - cancelable: true, - composed: true, - detail - }); - element.dispatchEvent(event); - } else if (element instanceof HTMLCollection || element instanceof NodeList) { - for (let e of element) { - fireCustomEvent(e, type, detail); - } - } else { - throw new TypeError("value is not an instance of HTMLElement or HTMLCollection"); - } - } - function findTargetElementFromEvent(event, attributeName, attributeValue) { - validateInstance(event, Event); - if (typeof event.composedPath !== "function") { - throw new Error("unsupported event"); - } - const path = event.composedPath(); - if (isArray(path)) { - for (let i = 0; i < path.length; i++) { - const o = path[i]; - if (o instanceof HTMLElement && o.hasAttribute(attributeName) && (attributeValue === void 0 || o.getAttribute(attributeName) === attributeValue)) { - return o; - } - } - } - return void 0; - } - var init_events = __esm({ - "../application/source/dom/events.mjs"() { - init_is(); - init_validate(); - init_util(); - } - }); - - // ../application/source/dom/theme.mjs - function getDocumentTheme() { - let document2 = getGlobalObject("document"); - let name = DEFAULT_THEME; - let element = document2.querySelector("html"); - if (element instanceof HTMLElement) { - let theme = element.getAttribute(ATTRIBUTE_THEME_NAME); - if (theme) { - name = theme; - } - } - return new Theme(name); - } - var Theme; - var init_theme = __esm({ - "../application/source/dom/theme.mjs"() { - init_base(); - init_global(); - init_validate(); - init_constants2(); - init_constants(); - Theme = class extends Base { - /** - * - * @param name - * @throws {TypeError} value is not a string - */ - constructor(name) { - super(); - validateString(name); - this.name = name; - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/dom/theme"); - } - /** - * - * @returns {string} - */ - getName() { - return this.name; - } - }; - } - }); - - // ../application/source/dom/template.mjs - function findDocumentTemplate(id, currentNode) { - validateString(id); - const document2 = getGlobalObject("document"); - const HTMLTemplateElement2 = getGlobalFunction("HTMLTemplateElement"); - const DocumentFragment2 = getGlobalFunction("DocumentFragment"); - const Document2 = getGlobalFunction("Document"); - let prefixID; - if (!(currentNode instanceof Document2 || currentNode instanceof DocumentFragment2)) { - if (currentNode instanceof Node) { - if (currentNode.hasAttribute(ATTRIBUTE_TEMPLATE_PREFIX)) { - prefixID = currentNode.getAttribute(ATTRIBUTE_TEMPLATE_PREFIX); - } - currentNode = currentNode.getRootNode(); - if (!(currentNode instanceof Document2 || currentNode instanceof DocumentFragment2)) { - currentNode = currentNode.ownerDocument; - } - } - if (!(currentNode instanceof Document2 || currentNode instanceof DocumentFragment2)) { - currentNode = document2; - } - } - let template; - let theme = getDocumentTheme(); - if (prefixID) { - let themedPrefixID = `${prefixID}-${id}-${theme.getName()}`; - template = currentNode.getElementById(themedPrefixID); - if (template instanceof HTMLTemplateElement2) { - return new Template(template); - } - template = document2.getElementById(themedPrefixID); - if (template instanceof HTMLTemplateElement2) { - return new Template(template); - } - } - let themedID = `${id}-${theme.getName()}`; - template = currentNode.getElementById(themedID); - if (template instanceof HTMLTemplateElement2) { - return new Template(template); - } - template = document2.getElementById(themedID); - if (template instanceof HTMLTemplateElement2) { - return new Template(template); - } - template = currentNode.getElementById(id); - if (template instanceof HTMLTemplateElement2) { - return new Template(template); - } - template = document2.getElementById(id); - if (template instanceof HTMLTemplateElement2) { - return new Template(template); - } - throw new Error(`template ${id} not found.`); - } - var Template; - var init_template = __esm({ - "../application/source/dom/template.mjs"() { - init_base(); - init_global(); - init_validate(); - init_constants2(); - init_theme(); - init_constants(); - Template = class extends Base { - /** - * - * @param {HTMLTemplateElement} template - * @throws {TypeError} value is not an instance of - * @throws {TypeError} value is not a function - * @throws {Error} the function is not defined - */ - constructor(template) { - super(); - const HTMLTemplateElement2 = getGlobalFunction("HTMLTemplateElement"); - validateInstance(template, HTMLTemplateElement2); - this.template = template; - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/dom/resource/template"); - } - /** - * - * @returns {HTMLTemplateElement} - */ - getTemplateElement() { - return this.template; - } - /** - * - * @return {DocumentFragment} - * @throws {TypeError} value is not an instance of - */ - createDocumentFragment() { - return this.template.content.cloneNode(true); - } - }; - } - }); - - // ../application/source/dom/updater.mjs - function getCheckStateCallback() { - const self2 = this; - return function(current) { - if (this instanceof HTMLInputElement) { - if (["radio", "checkbox"].indexOf(this.type) !== -1) { - return `${this.value}` === `${current}` ? "true" : void 0; - } - } else if (this instanceof HTMLOptionElement) { - if (isArray(current) && current.indexOf(this.value) !== -1) { - return "true"; - } - return void 0; - } - }; - } - function getControlEventHandler() { - const self2 = this; - if (self2[symbol]) { - return self2[symbol]; - } - self2[symbol] = (event) => { - const element = findTargetElementFromEvent(event, ATTRIBUTE_UPDATER_BIND); - if (element === void 0) { - return; - } - retrieveAndSetValue.call(self2, element); - }; - return self2[symbol]; - } - function retrieveAndSetValue(element) { - const self2 = this; - const pathfinder = new Pathfinder(self2[internalSymbol].subject.getSubject()); - let path = element.getAttribute(ATTRIBUTE_UPDATER_BIND); - if (path === null) - throw new Error("the bind argument must start as a value with a path"); - if (path.indexOf("path:") !== 0) { - throw new Error("the bind argument must start as a value with a path"); - } - path = path.substring(5); - let value; - if (element instanceof HTMLInputElement) { - switch (element.type) { - case "checkbox": - value = element.checked ? element.value : void 0; - break; - default: - value = element.value; - break; - } - } else if (element instanceof HTMLTextAreaElement) { - value = element.value; - } else if (element instanceof HTMLSelectElement) { - switch (element.type) { - case "select-one": - value = element.value; - break; - case "select-multiple": - value = element.value; - let options = element?.selectedOptions; - if (options === void 0) - options = element.querySelectorAll(":scope option:checked"); - value = Array.from(options).map(({ value: value2 }) => value2); - break; - } - } else if (element?.constructor?.prototype && !!Object.getOwnPropertyDescriptor(element.constructor.prototype, "value")?.["get"] || element.hasOwnProperty("value")) { - value = element?.["value"]; - } else { - throw new Error("unsupported object"); - } - const copy = clone(self2[internalSymbol].subject.getRealSubject()); - const pf = new Pathfinder(copy); - pf.setVia(path, value); - const diffResult = diff(copy, self2[internalSymbol].subject.getRealSubject()); - if (diffResult.length > 0) { - pathfinder.setVia(path, value); - } - } - function retrieveFromBindings() { - const self2 = this; - if (self2[internalSymbol].element.matches(`[${ATTRIBUTE_UPDATER_BIND}]`)) { - retrieveAndSetValue.call(self2, self2[internalSymbol].element); - } - for (const [, element] of self2[internalSymbol].element.querySelectorAll(`[${ATTRIBUTE_UPDATER_BIND}]`).entries()) { - retrieveAndSetValue.call(self2, element); - } - } - function removeElement(change) { - const self2 = this; - for (const [, element] of self2[internalSymbol].element.querySelectorAll(`:scope [${ATTRIBUTE_UPDATER_REMOVE}]`).entries()) { - element.parentNode.removeChild(element); - } - } - function insertElement(change) { - const self2 = this; - const subject = self2[internalSymbol].subject.getRealSubject(); - let mem = /* @__PURE__ */ new WeakSet(); - let wd = 0; - const container = self2[internalSymbol].element; - while (true) { - let found = false; - wd++; - let p = clone(change?.["path"]); - if (!isArray(p)) - return self2; - while (p.length > 0) { - const current = p.join("."); - let iterator = /* @__PURE__ */ new Set(); - const query = `[${ATTRIBUTE_UPDATER_INSERT}*="path:${current}"]`; - const e = container.querySelectorAll(query); - if (e.length > 0) { - iterator = /* @__PURE__ */ new Set([...e]); - } - if (container.matches(query)) { - iterator.add(container); - } - for (const [, containerElement] of iterator.entries()) { - if (mem.has(containerElement)) - continue; - mem.add(containerElement); - found = true; - const attributes = containerElement.getAttribute(ATTRIBUTE_UPDATER_INSERT); - if (attributes === null) - continue; - let def = trimSpaces(attributes); - let i = def.indexOf(" "); - let key = trimSpaces(def.substr(0, i)); - let refPrefix = `${key}-`; - let cmd = trimSpaces(def.substr(i)); - if (cmd.indexOf("|") > 0) { - throw new Error("pipes are not allowed when cloning a node."); - } - let pipe = new Pipe(cmd); - self2[internalSymbol].callbacks.forEach((f, n) => { - pipe.setCallback(n, f); - }); - let value; - try { - containerElement.removeAttribute(ATTRIBUTE_ERRORMESSAGE); - value = pipe.run(subject); - } catch (e2) { - containerElement.setAttribute(ATTRIBUTE_ERRORMESSAGE, e2.message); - } - let dataPath = cmd.split(":").pop(); - let insertPoint; - if (containerElement.hasChildNodes()) { - insertPoint = containerElement.lastChild; - } - if (!isIterable(value)) { - throw new Error("the value is not iterable"); - } - let available = /* @__PURE__ */ new Set(); - for (const [i2, obj] of Object.entries(value)) { - let ref = refPrefix + i2; - let currentPath = `${dataPath}.${i2}`; - available.add(ref); - let refElement = containerElement.querySelector(`[${ATTRIBUTE_UPDATER_INSERT_REFERENCE}="${ref}"]`); - if (refElement instanceof HTMLElement) { - insertPoint = refElement; - continue; - } - appendNewDocumentFragment(containerElement, key, ref, currentPath); - } - let nodes = containerElement.querySelectorAll( - `[${ATTRIBUTE_UPDATER_INSERT_REFERENCE}*="${refPrefix}"]` - ); - for (const [, node] of Object.entries(nodes)) { - if (!available.has(node.getAttribute(ATTRIBUTE_UPDATER_INSERT_REFERENCE))) { - try { - containerElement.removeChild(node); - } catch (e2) { - containerElement.setAttribute( - ATTRIBUTE_ERRORMESSAGE, - `${containerElement.getAttribute(ATTRIBUTE_ERRORMESSAGE)}, ${e2.message}`.trim() - ); - } - } - } - } - p.pop(); - } - if (found === false) - break; - if (wd++ > 200) { - throw new Error("the maximum depth for the recursion is reached."); - } - } - } - function appendNewDocumentFragment(container, key, ref, path) { - let template = findDocumentTemplate(key, container); - let nodes = template.createDocumentFragment(); - for (const [, node] of Object.entries(nodes.childNodes)) { - if (node instanceof HTMLElement) { - applyRecursive(node, key, path); - node.setAttribute(ATTRIBUTE_UPDATER_INSERT_REFERENCE, ref); - } - container.appendChild(node); - } - } - function applyRecursive(node, key, path) { - if (node instanceof HTMLElement) { - if (node.hasAttribute(ATTRIBUTE_UPDATER_REPLACE)) { - let value = node.getAttribute(ATTRIBUTE_UPDATER_REPLACE); - node.setAttribute(ATTRIBUTE_UPDATER_REPLACE, value.replaceAll(`path:${key}`, `path:${path}`)); - } - if (node.hasAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES)) { - let value = node.getAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES); - node.setAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES, value.replaceAll(`path:${key}`, `path:${path}`)); - } - for (const [, child] of Object.entries(node.childNodes)) { - applyRecursive(child, key, path); - } - } - } - function updateContent(change) { - const self2 = this; - const subject = self2[internalSymbol].subject.getRealSubject(); - let p = clone(change?.["path"]); - runUpdateContent.call(this, this[internalSymbol].element, p, subject); - const slots = this[internalSymbol].element.querySelectorAll("slot"); - if (slots.length > 0) { - for (const [, slot] of Object.entries(slots)) { - for (const [, element] of Object.entries(slot.assignedNodes())) { - runUpdateContent.call(this, element, p, subject); - } - } - } - } - function runUpdateContent(container, parts, subject) { - if (!isArray(parts)) - return; - if (!(container instanceof HTMLElement)) - return; - parts = clone(parts); - let mem = /* @__PURE__ */ new WeakSet(); - while (parts.length > 0) { - const current = parts.join("."); - parts.pop(); - const query = `[${ATTRIBUTE_UPDATER_REPLACE}^="path:${current}"], [${ATTRIBUTE_UPDATER_REPLACE}^="static:"], [${ATTRIBUTE_UPDATER_REPLACE}^="i18n:"]`; - const e = container.querySelectorAll(`${query}`); - const iterator = /* @__PURE__ */ new Set([...e]); - if (container.matches(query)) { - iterator.add(container); - } - for (const [element] of iterator.entries()) { - if (mem.has(element)) - return; - mem.add(element); - const attributes = element.getAttribute(ATTRIBUTE_UPDATER_REPLACE); - let cmd = trimSpaces(attributes); - let pipe = new Pipe(cmd); - this[internalSymbol].callbacks.forEach((f, n) => { - pipe.setCallback(n, f); - }); - let value; - try { - element.removeAttribute(ATTRIBUTE_ERRORMESSAGE); - value = pipe.run(subject); - } catch (e2) { - element.setAttribute(ATTRIBUTE_ERRORMESSAGE, e2.message); - } - if (value instanceof HTMLElement) { - while (element.firstChild) { - element.removeChild(element.firstChild); - } - try { - element.appendChild(value); - } catch (e2) { - element.setAttribute( - ATTRIBUTE_ERRORMESSAGE, - `${element.getAttribute(ATTRIBUTE_ERRORMESSAGE)}, ${e2.message}`.trim() - ); - } - } else { - element.innerHTML = value; - } - } - } - } - function updateAttributes(change) { - const subject = this[internalSymbol].subject.getRealSubject(); - let p = clone(change?.["path"]); - runUpdateAttributes.call(this, this[internalSymbol].element, p, subject); - } - function runUpdateAttributes(container, parts, subject) { - const self2 = this; - if (!isArray(parts)) - return; - parts = clone(parts); - let mem = /* @__PURE__ */ new WeakSet(); - while (parts.length > 0) { - const current = parts.join("."); - parts.pop(); - let iterator = /* @__PURE__ */ new Set(); - const query = `[${ATTRIBUTE_UPDATER_SELECT_THIS}][${ATTRIBUTE_UPDATER_ATTRIBUTES}], [${ATTRIBUTE_UPDATER_ATTRIBUTES}*="path:${current}"], [${ATTRIBUTE_UPDATER_ATTRIBUTES}^="static:"], [${ATTRIBUTE_UPDATER_ATTRIBUTES}^="i18n:"]`; - const e = container.querySelectorAll(query); - if (e.length > 0) { - iterator = /* @__PURE__ */ new Set([...e]); - } - if (container.matches(query)) { - iterator.add(container); - } - for (const [element] of iterator.entries()) { - if (mem.has(element)) - return; - mem.add(element); - if (!element.hasAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES)) { - continue; - } - const attributes = element.getAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES); - for (let [, def] of Object.entries(attributes.split(","))) { - def = trimSpaces(def); - let i = def.indexOf(" "); - let name = trimSpaces(def.substr(0, i)); - let cmd = trimSpaces(def.substr(i)); - let pipe = new Pipe(cmd); - self2[internalSymbol].callbacks.forEach((f, n) => { - pipe.setCallback(n, f, element); - }); - let value; - try { - element.removeAttribute(ATTRIBUTE_ERRORMESSAGE); - value = pipe.run(subject); - } catch (e2) { - element.setAttribute(ATTRIBUTE_ERRORMESSAGE, e2.message); - } - if (value === void 0) { - element.removeAttribute(name); - } else if (element.getAttribute(name) !== value) { - element.setAttribute(name, value); - } - handleInputControlAttributeUpdate.call(this, element, name, value); - } - } - } - } - function handleInputControlAttributeUpdate(element, name, value) { - const self2 = this; - if (element instanceof HTMLSelectElement) { - switch (element.type) { - case "select-multiple": - for (const [index, opt] of Object.entries(element.options)) { - if (value.indexOf(opt.value) !== -1) { - opt.selected = true; - } else { - opt.selected = false; - } - } - break; - case "select-one": - for (const [index, opt] of Object.entries(element.options)) { - if (opt.value === value) { - element.selectedIndex = index; - break; - } - } - break; - } - } else if (element instanceof HTMLInputElement) { - switch (element.type) { - case "radio": - if (name === "checked") { - if (value !== void 0) { - element.checked = true; - } else { - element.checked = false; - } - } - break; - case "checkbox": - if (name === "checked") { - if (value !== void 0) { - element.checked = true; - } else { - element.checked = false; - } - } - break; - case "text": - default: - if (name === "value") { - element.value = value === void 0 ? "" : value; - } - break; - } - } else if (element instanceof HTMLTextAreaElement) { - if (name === "value") { - element.value = value === void 0 ? "" : value; - } - } - } - function addObjectWithUpdaterToElement(elements, symbol2, object) { - const self2 = this; - if (!(self2 instanceof HTMLElement)) { - throw new TypeError("the context of this function must be an instance of HTMLElement"); - } - if (!(typeof symbol2 === "symbol")) { - throw new TypeError("symbol must be an instance of Symbol"); - } - const updaters = /* @__PURE__ */ new Set(); - if (elements instanceof NodeList) { - elements = /* @__PURE__ */ new Set([...elements]); - } else if (elements instanceof HTMLElement) { - elements = /* @__PURE__ */ new Set([elements]); - } else if (elements instanceof Set) { - } else { - throw new TypeError(`elements is not a valid type. (actual: ${typeof elements})`); - } - let result = []; - elements.forEach((element) => { - if (!(element instanceof HTMLElement)) - return; - if (element instanceof HTMLTemplateElement) - return; - const u = new Updater(element, object); - updaters.add(u); - result.push( - u.run().then(() => { - return u.enableEventProcessing(); - }) - ); - }); - if (updaters.size > 0) { - addToObjectLink(self2, symbol2, updaters); - } - return result; - } - var Updater, symbol; - var init_updater = __esm({ - "../application/source/dom/updater.mjs"() { - init_constants(); - init_diff(); - init_pathfinder(); - init_pipe(); - init_constants2(); - init_base(); - init_is(); - init_observer(); - init_proxyobserver(); - init_validate(); - init_clone(); - init_trimspaces(); - init_attributes(); - init_events(); - init_template(); - Updater = class extends Base { - /** - * @since 1.8.0 - * @param {HTMLElement} element - * @param {object|ProxyObserver|undefined} subject - * @throws {TypeError} value is not a object - * @throws {TypeError} value is not an instance of HTMLElement - * @see {@link Monster.DOM.findDocumentTemplate} - */ - constructor(element, subject) { - super(); - if (subject === void 0) - subject = {}; - if (!isInstance(subject, ProxyObserver)) { - subject = new ProxyObserver(subject); - } - this[internalSymbol] = { - element: validateInstance(element, HTMLElement), - last: {}, - callbacks: /* @__PURE__ */ new Map(), - eventTypes: ["keyup", "click", "change", "drop", "touchend", "input"], - subject - }; - this[internalSymbol].callbacks.set("checkstate", getCheckStateCallback.call(this)); - this[internalSymbol].subject.attachObserver( - new Observer(() => { - const s = this[internalSymbol].subject.getRealSubject(); - const diffResult = diff(this[internalSymbol].last, s); - this[internalSymbol].last = clone(s); - for (const [, change] of Object.entries(diffResult)) { - removeElement.call(this, change); - insertElement.call(this, change); - updateContent.call(this, change); - updateAttributes.call(this, change); - } - }) - ); - } - /** - * Defaults: 'keyup', 'click', 'change', 'drop', 'touchend' - * - * @see {@link https://developer.mozilla.org/de/docs/Web/Events} - * @since 1.9.0 - * @param {Array} types - * @return {Updater} - */ - setEventTypes(types) { - this[internalSymbol].eventTypes = validateArray(types); - return this; - } - /** - * With this method, the eventlisteners are hooked in and the magic begins. - * - * ``` - * updater.run().then(() => { - * updater.enableEventProcessing(); - * }); - * ``` - * - * @since 1.9.0 - * @return {Updater} - * @throws {Error} the bind argument must start as a value with a path - */ - enableEventProcessing() { - this.disableEventProcessing(); - for (const type of this[internalSymbol].eventTypes) { - this[internalSymbol].element.addEventListener(type, getControlEventHandler.call(this), { - capture: true, - passive: true - }); - } - return this; - } - /** - * This method turns off the magic or who loves it more profane it removes the eventListener. - * - * @since 1.9.0 - * @return {Updater} - */ - disableEventProcessing() { - for (const type of this[internalSymbol].eventTypes) { - this[internalSymbol].element.removeEventListener(type, getControlEventHandler.call(this)); - } - return this; - } - /** - * The run method must be called for the update to start working. - * The method ensures that changes are detected. - * - * ``` - * updater.run().then(() => { - * updater.enableEventProcessing(); - * }); - * ``` - * - * @summary Let the magic begin - * @return {Promise} - */ - run() { - this[internalSymbol].last = { __init__: true }; - return this[internalSymbol].subject.notifyObservers(); - } - /** - * Gets the values of bound elements and changes them in subject - * - * @since 1.27.0 - * @return {Monster.DOM.Updater} - */ - retrieve() { - retrieveFromBindings.call(this); - return this; - } - /** - * If you have passed a ProxyObserver in the constructor, you will get the object that the ProxyObserver manages here. - * However, if you passed a simple object, here you will get a proxy for that object. - * - * For changes the ProxyObserver must be used. - * - * @since 1.8.0 - * @return {Proxy} - */ - getSubject() { - return this[internalSymbol].subject.getSubject(); - } - /** - * This method can be used to register commands that can be called via call: instruction. - * This can be used to provide a pipe with its own functionality. - * - * @param {string} name - * @param {function} callback - * @returns {Transformer} - * @throws {TypeError} value is not a string - * @throws {TypeError} value is not a function - */ - setCallback(name, callback) { - this[internalSymbol].callbacks.set(name, callback); - return this; - } - }; - symbol = Symbol("@schukai/monster/updater@@EventHandler"); - } - }); - - // ../application/source/dom/customelement.mjs - var customelement_exports = {}; - __export(customelement_exports, { - CustomElement: () => CustomElement, - assembleMethodSymbol: () => assembleMethodSymbol, - attributeObserverSymbol: () => attributeObserverSymbol, - getSlottedElements: () => getSlottedElements, - initMethodSymbol: () => initMethodSymbol, - registerCustomElement: () => registerCustomElement - }); - function containChildNode(node) { - const self2 = this; - if (self2.contains(node)) { - return true; - } - for (const [, e] of Object.entries(self2.childNodes)) { - if (e.contains(node)) { - return true; - } - containChildNode.call(e, node); - } - return false; - } - function initOptionObserver() { - const self2 = this; - let lastDisabledValue = void 0; - self2.attachObserver( - new Observer(function() { - const flag = self2.getOption("disabled"); - if (flag === lastDisabledValue) { - return; - } - lastDisabledValue = flag; - if (!(self2.shadowRoot instanceof ShadowRoot)) { - return; - } - const query = "button, command, fieldset, keygen, optgroup, option, select, textarea, input, [data-monster-objectlink]"; - const elements = self2.shadowRoot.querySelectorAll(query); - let nodeList; - try { - nodeList = /* @__PURE__ */ new Set([...elements, ...getSlottedElements.call(self2, query)]); - } catch (e) { - nodeList = elements; - } - for (const element of [...nodeList]) { - if (flag === true) { - element.setAttribute(ATTRIBUTE_DISABLED, ""); - } else { - element.removeAttribute(ATTRIBUTE_DISABLED); - } - } - }) - ); - self2.attachObserver( - new Observer(function() { - if (!hasObjectLink(self2, customElementUpdaterLinkSymbol)) { - return; - } - const updaters = getLinkedObjects(self2, customElementUpdaterLinkSymbol); - for (const list of updaters) { - for (const updater of list) { - let d = clone(self2[internalSymbol].getRealSubject()["options"]); - Object.assign(updater.getSubject(), d); - } - } - }) - ); - self2[attributeObserverSymbol][ATTRIBUTE_DISABLED] = () => { - if (self2.hasAttribute(ATTRIBUTE_DISABLED)) { - self2.setOption(ATTRIBUTE_DISABLED, true); - } else { - self2.setOption(ATTRIBUTE_DISABLED, void 0); - } - }; - self2[attributeObserverSymbol][ATTRIBUTE_OPTIONS] = () => { - const options = getOptionsFromAttributes.call(self2); - if (isObject(options) && Object.keys(options).length > 0) { - self2.setOptions(options); - } - }; - self2[attributeObserverSymbol][ATTRIBUTE_OPTIONS_SELECTOR] = () => { - const options = getOptionsFromScriptTag.call(self2); - if (isObject(options) && Object.keys(options).length > 0) { - self2.setOptions(options); - } - }; - } - function getOptionsFromScriptTag() { - const self2 = this; - if (!self2.hasAttribute(ATTRIBUTE_OPTIONS_SELECTOR)) { - return {}; - } - const node = document.querySelector(self2.getAttribute(ATTRIBUTE_OPTIONS_SELECTOR)); - if (!(node instanceof HTMLScriptElement)) { - addAttributeToken( - self2, - ATTRIBUTE_ERRORMESSAGE, - `the selector ${ATTRIBUTE_OPTIONS_SELECTOR} for options was specified (${self2.getAttribute( - ATTRIBUTE_OPTIONS_SELECTOR - )}) but not found.` - ); - return {}; - } - let obj = {}; - try { - obj = parseOptionsJSON.call(this, node.textContent.trim()); - } catch (e) { - addAttributeToken( - self2, - ATTRIBUTE_ERRORMESSAGE, - `when analyzing the configuration from the script tag there was an error. ${e}` - ); - } - return obj; - } - function getOptionsFromAttributes() { - const self2 = this; - if (this.hasAttribute(ATTRIBUTE_OPTIONS)) { - try { - return parseOptionsJSON.call(self2, this.getAttribute(ATTRIBUTE_OPTIONS)); - } catch (e) { - addAttributeToken( - self2, - ATTRIBUTE_ERRORMESSAGE, - `the options attribute ${ATTRIBUTE_OPTIONS} does not contain a valid json definition (actual: ${this.getAttribute( - ATTRIBUTE_OPTIONS - )}).${e}` - ); - } - } - return {}; - } - function parseOptionsJSON(data) { - let obj = {}; - if (!isString(data)) { - return obj; - } - try { - let dataUrl = parseDataURL(data); - data = dataUrl.content; - } catch (e) { - } - try { - obj = JSON.parse(data); - } catch (e) { - throw e; - } - return validateObject(obj); - } - function initHtmlContent() { - try { - let template = findDocumentTemplate(this.constructor.getTag()); - this.appendChild(template.createDocumentFragment()); - } catch (e) { - let html = this.getOption("templates.main", ""); - if (isString(html) && html.length > 0) { - const mapping = this.getOption("templateMapping", {}); - if (isObject(mapping)) { - html = new Formatter(mapping).format(html); - } - this.innerHTML = html; - } - } - return this; - } - function initCSSStylesheet() { - const self2 = this; - if (!(this.shadowRoot instanceof ShadowRoot)) { - return self2; - } - const styleSheet = this.constructor.getCSSStyleSheet(); - if (styleSheet instanceof CSSStyleSheet) { - if (styleSheet.cssRules.length > 0) { - this.shadowRoot.adoptedStyleSheets = [styleSheet]; - } - } else if (isArray(styleSheet)) { - const assign = []; - for (let s of styleSheet) { - if (isString(s)) { - let trimedStyleSheet = s.trim(); - if (trimedStyleSheet !== "") { - const style = document.createElement("style"); - style.innerHTML = trimedStyleSheet; - self2.shadowRoot.prepend(style); - } - continue; - } - validateInstance(s, CSSStyleSheet); - if (s.cssRules.length > 0) { - assign.push(s); - } - } - if (assign.length > 0) { - this.shadowRoot.adoptedStyleSheets = assign; - } - } else if (isString(styleSheet)) { - let trimedStyleSheet = styleSheet.trim(); - if (trimedStyleSheet !== "") { - const style = document.createElement("style"); - style.innerHTML = styleSheet; - self2.shadowRoot.prepend(style); - } - } - return self2; - } - function initShadowRoot() { - let template; - let html; - try { - template = findDocumentTemplate(this.constructor.getTag()); - } catch (e) { - html = this.getOption("templates.main", ""); - if (!isString(html) || html === void 0 || html === "") { - throw new Error("html is not set."); - } - } - this.attachShadow({ - mode: this.getOption("shadowMode", "open"), - delegatesFocus: this.getOption("delegatesFocus", true) - }); - if (template instanceof Template) { - this.shadowRoot.appendChild(template.createDocumentFragment()); - return this; - } - const mapping = this.getOption("templateMapping", {}); - if (isObject(mapping)) { - html = new Formatter(mapping).format(html); - } - this.shadowRoot.innerHTML = html; - return this; - } - function registerCustomElement(element) { - validateFunction(element); - const customElements2 = getGlobalObject("customElements"); - if (customElements2 === void 0) { - throw new Error("customElements is not supported."); - } - if (customElements2.get(element.getTag()) !== void 0) { - return; - } - customElements2.define(element.getTag(), element); - } - var initMethodSymbol, assembleMethodSymbol, attributeObserverSymbol, CustomElement; - var init_customelement = __esm({ - "../application/source/dom/customelement.mjs"() { - init_constants(); - init_extend(); - init_pathfinder(); - init_formatter(); - init_dataurl(); - init_global(); - init_is(); - init_observer(); - init_proxyobserver(); - init_validate(); - init_clone(); - init_attributes(); - init_constants2(); - init_template(); - init_updater(); - init_constants(); - init_translations(); - init_slotted(); - initMethodSymbol = Symbol.for("@schukai/monster/dom/@@initMethodSymbol"); - assembleMethodSymbol = Symbol.for("@schukai/monster/dom/@@assembleMethodSymbol"); - attributeObserverSymbol = Symbol.for("@schukai/monster/dom/@@attributeObserver"); - CustomElement = class extends HTMLElement { - /** - * A new object is created. First the `initOptions` method is called. Here the - * options can be defined in derived classes. Subsequently, the shadowRoot is initialized. - * - * @throws {Error} the options attribute does not contain a valid json definition. - * @since 1.7.0 - */ - constructor() { - super(); - this[internalSymbol] = new ProxyObserver({ - options: extend({}, this.defaults) - }); - this[attributeObserverSymbol] = {}; - initOptionObserver.call(this); - this[initMethodSymbol](); - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/dom/custom-element"); - } - /** - * This method determines which attributes are to be monitored by `attributeChangedCallback()`. - * - * @return {string[]} - * @since 1.15.0 - */ - static get observedAttributes() { - return [ATTRIBUTE_OPTIONS, ATTRIBUTE_DISABLED]; - } - /** - * Derived classes can override and extend this method as follows. - * - * ``` - * get defaults() { - * return Object.assign({}, super.defaults, { - * myValue:true - * }); - * } - * ``` - * - * To set the options via the html tag the attribute data-monster-options must be set. - * As value a JSON object with the desired values must be defined. - * - * Since 1.18.0 the JSON can be specified as a DataURI. - * - * ``` - * new Monster.Types.DataUrl(btoa(JSON.stringify({ - * shadowMode: 'open', - * delegatesFocus: true, - * templates: { - * main: undefined - * } - * })),'application/json',true).toString() - * ``` - * - * The attribute data-monster-options-selector can be used to access a script tag that contains additional configuration. - * - * As value a selector must be specified, which belongs to a script tag and contains the configuration as json. - * - * ``` - * <script id="id-for-this-config" type="application/json"> - * { - * "config-key": "config-value" - * } - * <\/script> - * ``` - * - * The individual configuration values can be found in the table. - * - * @property {boolean} disabled=false Object The Boolean disabled attribute, when present, makes the element not mutable, focusable, or even submitted with the form. - * @property {string} shadowMode=open `open` Elements of the shadow root are accessible from JavaScript outside the root, for example using. `close` Denies access to the node(s) of a closed shadow root from JavaScript outside it - * @property {Boolean} delegatesFocus=true A boolean that, when set to true, specifies behavior that mitigates custom element issues around focusability. When a non-focusable part of the shadow DOM is clicked, the first focusable part is given focus, and the shadow host is given any available :focus styling. - * @property {Object} templates Templates - * @property {string} templates.main=undefined Main template - * @property {Object} templateMapping Template mapping - * - * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow - * @since 1.8.0 - */ - get defaults() { - return { - ATTRIBUTE_DISABLED: this.getAttribute(ATTRIBUTE_DISABLED), - shadowMode: "open", - delegatesFocus: true, - templates: { - main: void 0 - }, - templateMapping: {} - }; - } - /** - * This method updates the labels of the element. - * The labels are defined in the options object. - * The key of the label is used to retrieve the translation from the document. - * If the translation is different from the label, the label is updated. - * - * Before you can use this method, you must have loaded the translations. - * - * @returns {Monster.DOM.CustomElement} - * @throws {Error} Cannot find element with translations. Add a translations object to the document. - */ - updateI18n() { - const translations = getDocumentTranslations(); - if (!translations) { - return this; - } - let labels = this.getOption("labels"); - if (!(isObject(labels) || isIterable(labels))) { - return this; - } - for (const key in labels) { - const def = labels[key]; - if (isString(def)) { - const text = translations.getText(key, def); - if (text !== def) { - this.setOption(`labels.${key}`, text); - } - continue; - } else if (isObject(def)) { - for (const k in def) { - const d = def[k]; - const text = translations.getPluralRuleText(key, k, d); - if (!isString(text)) { - throw new Error("Invalid labels definition"); - } - if (text !== d) { - this.setOption(`labels.${key}.${k}`, text); - } - } - continue; - } - throw new Error("Invalid labels definition"); - } - return this; - } - /** - * There is no check on the name by this class. the developer is responsible for assigning an appropriate tag. - * if the name is not valid, registerCustomElement() will issue an error - * - * @link https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name - * @return {string} - * @throws {Error} the method getTag must be overwritten by the derived class. - * @since 1.7.0 - */ - static getTag() { - throw new Error("the method getTag must be overwritten by the derived class."); - } - /** - * At this point a `CSSStyleSheet` object can be returned. If the environment does not - * support a constructor, then an object can also be built using the following detour. - * - * If `undefined` is returned then the shadowRoot does not get a stylesheet. - * - * ``` - * const doc = document.implementation.createHTMLDocument('title'); - * - * let style = doc.createElement("style"); - * style.innerHTML="p{color:red;}"; - * - * // WebKit Hack - * style.appendChild(document.createTextNode("")); - * // Add the <style> element to the page - * doc.head.appendChild(style); - * return doc.styleSheets[0]; - * ; - * ``` - * - * @return {CSSStyleSheet|CSSStyleSheet[]|string|undefined} - */ - static getCSSStyleSheet() { - return void 0; - } - /** - * attach a new observer - * - * @param {Observer} observer - * @returns {CustomElement} - */ - attachObserver(observer) { - this[internalSymbol].attachObserver(observer); - return this; - } - /** - * detach a observer - * - * @param {Observer} observer - * @returns {CustomElement} - */ - detachObserver(observer) { - this[internalSymbol].detachObserver(observer); - return this; - } - /** - * @param {Observer} observer - * @returns {ProxyObserver} - */ - containsObserver(observer) { - return this[internalSymbol].containsObserver(observer); - } - /** - * nested options can be specified by path `a.b.c` - * - * @param {string} path - * @param {*} defaultValue - * @return {*} - * @since 1.10.0 - */ - getOption(path, defaultValue) { - let value; - try { - value = new Pathfinder(this[internalSymbol].getRealSubject()["options"]).getVia(path); - } catch (e) { - } - if (value === void 0) - return defaultValue; - return value; - } - /** - * Set option and inform elements - * - * @param {string} path - * @param {*} value - * @return {CustomElement} - * @since 1.14.0 - */ - setOption(path, value) { - new Pathfinder(this[internalSymbol].getSubject()["options"]).setVia(path, value); - return this; - } - /** - * @since 1.15.0 - * @param {string|object} options - * @return {CustomElement} - */ - setOptions(options) { - if (isString(options)) { - options = parseOptionsJSON.call(this, options); - } - const self2 = this; - extend(self2[internalSymbol].getSubject()["options"], self2.defaults, options); - return self2; - } - /** - * Is called once via the constructor - * - * @return {CustomElement} - * @since 1.8.0 - */ - [initMethodSymbol]() { - return this; - } - /** - * Is called once when the object is included in the DOM for the first time. - * - * @return {CustomElement} - * @since 1.8.0 - */ - [assembleMethodSymbol]() { - const self2 = this; - let elements; - let nodeList; - const AttributeOptions = getOptionsFromAttributes.call(self2); - if (isObject(AttributeOptions) && Object.keys(AttributeOptions).length > 0) { - self2.setOptions(AttributeOptions); - } - const ScriptOptions = getOptionsFromScriptTag.call(self2); - if (isObject(ScriptOptions) && Object.keys(ScriptOptions).length > 0) { - self2.setOptions(ScriptOptions); - } - if (self2.getOption("shadowMode", false) !== false) { - try { - initShadowRoot.call(self2); - elements = self2.shadowRoot.childNodes; - } catch (e) { - } - try { - initCSSStylesheet.call(this); - } catch (e) { - addAttributeToken(self2, ATTRIBUTE_ERRORMESSAGE, e.toString()); - } - } - if (!(elements instanceof NodeList)) { - if (!(elements instanceof NodeList)) { - initHtmlContent.call(this); - elements = this.childNodes; - } - } - try { - nodeList = /* @__PURE__ */ new Set([...elements, ...getSlottedElements.call(self2)]); - } catch (e) { - nodeList = elements; - } - addObjectWithUpdaterToElement.call( - self2, - nodeList, - customElementUpdaterLinkSymbol, - clone(self2[internalSymbol].getRealSubject()["options"]) - ); - return self2; - } - /** - * Called every time the element is inserted into the DOM. Useful for running setup code, such as - * fetching resources or rendering. Generally, you should try to delay work until this time. - * - * @return {void} - * @since 1.7.0 - */ - connectedCallback() { - let self2 = this; - if (!hasObjectLink(self2, customElementUpdaterLinkSymbol)) { - self2[assembleMethodSymbol](); - } - } - /** - * Called every time the element is removed from the DOM. Useful for running clean up code. - * - * @return {void} - * @since 1.7.0 - */ - disconnectedCallback() { - } - /** - * The custom element has been moved into a new document (e.g. someone called document.adoptNode(el)). - * - * @return {void} - * @since 1.7.0 - */ - adoptedCallback() { - } - /** - * Called when an observed attribute has been added, removed, updated, or replaced. Also called for initial - * values when an element is created by the parser, or upgraded. Note: only attributes listed in the observedAttributes - * property will receive this callback. - * - * @param {string} attrName - * @param {string} oldVal - * @param {string} newVal - * @return {void} - * @since 1.15.0 - */ - attributeChangedCallback(attrName, oldVal, newVal) { - const self2 = this; - const callback = self2[attributeObserverSymbol]?.[attrName]; - if (isFunction(callback)) { - callback.call(self2, newVal, oldVal); - } - } - /** - * - * @param {Node} node - * @return {boolean} - * @throws {TypeError} value is not an instance of - * @since 1.19.0 - */ - hasNode(node) { - const self2 = this; - if (containChildNode.call(self2, validateInstance(node, Node))) { - return true; - } - if (!(self2.shadowRoot instanceof ShadowRoot)) { - return false; - } - return containChildNode.call(self2.shadowRoot, node); - } - }; - } - }); - - // ../application/source/dom/customcontrol.mjs - var customcontrol_exports = {}; - __export(customcontrol_exports, { - CustomControl: () => CustomControl - }); - function getInternal() { - const self2 = this; - if (!(attachedInternalSymbol in this)) { - throw new Error("ElementInternals is not supported and a polyfill is necessary"); - } - return this[attachedInternalSymbol]; - } - function initObserver() { - const self2 = this; - self2[attributeObserverSymbol]["value"] = () => { - self2.setOption("value", self2.getAttribute("value")); - }; - } - var attachedInternalSymbol, CustomControl; - var init_customcontrol = __esm({ - "../application/source/dom/customcontrol.mjs"() { - init_extend(); - init_constants2(); - init_customelement(); - init_constants(); - attachedInternalSymbol = Symbol("attachedInternal"); - CustomControl = class extends CustomElement { - /** - * IMPORTANT: CustomControls instances are not created via the constructor, but either via a tag in the HTML or via <code>document.createElement()</code>. - * - * @throws {Error} the ElementInternals is not supported and a polyfill is necessary - * @summary create new Instance - */ - constructor() { - super(); - if (typeof this["attachInternals"] === "function") { - this[attachedInternalSymbol] = this.attachInternals(); - } - initObserver.call(this); - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/dom/custom-control"); - } - /** - * This method determines which attributes are to be monitored by `attributeChangedCallback()`. - * - * @return {string[]} - * @since 1.15.0 - */ - static get observedAttributes() { - const list = super.observedAttributes; - list.push(ATTRIBUTE_VALUE); - return list; - } - /** - * - * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/attachInternals} - * @since 1.14.0 - * @return {boolean} - */ - static get formAssociated() { - return true; - } - /** - * Derived classes can override and extend this method as follows. - * - * ``` - * get defaults() { - * return extends{}, super.defaults, { - * myValue:true - * }); - * } - * ``` - * - * @see {@link https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements-face-example} - * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/attachInternals} - * @return {object} - * @since 1.14.0 - */ - get defaults() { - return extend({}, super.defaults); - } - /** - * Must be overridden by a derived class and return the value of the control. - * - * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals) - * - * @since 1.14.0 - * @throws {Error} the value getter must be overwritten by the derived class - */ - get value() { - throw Error("the value getter must be overwritten by the derived class"); - } - /** - * Must be overridden by a derived class and return the value of the control. - * - * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals) - * - * @param {*} value - * @since 1.14.0 - * @throws {Error} the value setter must be overwritten by the derived class - */ - set value(value) { - throw Error("the value setter must be overwritten by the derived class"); - } - /** - * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals) - * - * @return {NodeList} - * @since 1.14.0 - * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/labels} - * @throws {Error} the ElementInternals is not supported and a polyfill is necessary - */ - get labels() { - return getInternal.call(this)?.labels; - } - /** - * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals) - * - * @return {string|null} - */ - get name() { - return this.getAttribute("name"); - } - /** - * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals) - * - * @return {string} - */ - get type() { - return this.constructor.getTag(); - } - /** - * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals) - * - * @return {ValidityState} - * @throws {Error} the ElementInternals is not supported and a polyfill is necessary - * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/ValidityState} - * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/validity} - */ - get validity() { - return getInternal.call(this)?.validity; - } - /** - * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals) - * - * @return {string} - * @since 1.14.0 - * @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/validationMessage - * @throws {Error} the ElementInternals is not supported and a polyfill is necessary - */ - get validationMessage() { - return getInternal.call(this)?.validationMessage; - } - /** - * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals) - * - * @return {boolean} - * @since 1.14.0 - * @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/willValidate - * @throws {Error} the ElementInternals is not supported and a polyfill is necessary - */ - get willValidate() { - return getInternal.call(this)?.willValidate; - } - /** - * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals) - * - * @return {CustomStateSet} - * @since 1.14.0 - * @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/states - * @throws {Error} the ElementInternals is not supported and a polyfill is necessary - */ - get states() { - return getInternal.call(this)?.states; - } - /** - * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals) - * - * @return {HTMLFontElement|null} - * @since 1.14.0 - * @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/form - * @throws {Error} the ElementInternals is not supported and a polyfill is necessary - */ - get form() { - return getInternal.call(this)?.form; - } - /** - * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals) - * - * ``` - * // Use the control's name as the base name for submitted data - * const n = this.getAttribute('name'); - * const entries = new FormData(); - * entries.append(n + '-first-name', this.firstName_); - * entries.append(n + '-last-name', this.lastName_); - * this.setFormValue(entries); - * ``` - * - * @param {File|string|FormData} value - * @param {File|string|FormData} state - * @since 1.14.0 - * @return {undefined} - * @throws {DOMException} NotSupportedError - * @throws {Error} the ElementInternals is not supported and a polyfill is necessary - * @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/setFormValue - */ - setFormValue(value, state) { - getInternal.call(this).setFormValue(value, state); - } - /** - * - * @param {object} flags - * @param {string|undefined} message - * @param {HTMLElement} anchor - * @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/setValidity - * @since 1.14.0 - * @return {undefined} - * @throws {DOMException} NotSupportedError - * @throws {Error} the ElementInternals is not supported and a polyfill is necessary - */ - setValidity(flags, message, anchor) { - getInternal.call(this).setValidity(flags, message, anchor); - } - /** - * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals) - * - * @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/checkValidity - * @since 1.14.0 - * @return {boolean} - * @throws {DOMException} NotSupportedError - * @throws {Error} the ElementInternals is not supported and a polyfill is necessary - */ - checkValidity() { - return getInternal.call(this)?.checkValidity(); - } - /** - * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals) - * - * @return {boolean} - * @since 1.14.0 - * @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/reportValidity - * @throws {Error} the ElementInternals is not supported and a polyfill is necessary - * @throws {DOMException} NotSupportedError - */ - reportValidity() { - return getInternal.call(this)?.reportValidity(); - } - }; - } - }); - - // ../application/source/dom/ready.mjs - var ready_exports = {}; - __export(ready_exports, { - domReady: () => domReady, - windowReady: () => windowReady - }); - var domReady, windowReady; - var init_ready = __esm({ - "../application/source/dom/ready.mjs"() { - init_util(); - domReady = new Promise((resolve) => { - const document2 = getDocument(); - if (document2.readyState === "loading") { - document2.addEventListener("DOMContentLoaded", resolve); - } else { - resolve(); - } - }); - windowReady = new Promise((resolve) => { - const document2 = getDocument(); - const window2 = getWindow(); - if (document2.readyState === "complete") { - resolve(); - } else { - window2.addEventListener("load", resolve); - } - }); - } - }); - - // node_modules/.pnpm/pvtsutils@1.3.2/node_modules/pvtsutils/build/index.js - var require_build = __commonJS({ - "node_modules/.pnpm/pvtsutils@1.3.2/node_modules/pvtsutils/build/index.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - var ARRAY_BUFFER_NAME = "[object ArrayBuffer]"; - var BufferSourceConverter8 = class { - static isArrayBuffer(data) { - return Object.prototype.toString.call(data) === ARRAY_BUFFER_NAME; - } - static toArrayBuffer(data) { - if (this.isArrayBuffer(data)) { - return data; - } - if (data.byteLength === data.buffer.byteLength) { - return data.buffer; - } - return this.toUint8Array(data).slice().buffer; - } - static toUint8Array(data) { - return this.toView(data, Uint8Array); - } - static toView(data, type) { - if (data.constructor === type) { - return data; - } - if (this.isArrayBuffer(data)) { - return new type(data); - } - if (this.isArrayBufferView(data)) { - return new type(data.buffer, data.byteOffset, data.byteLength); - } - throw new TypeError("The provided value is not of type '(ArrayBuffer or ArrayBufferView)'"); - } - static isBufferSource(data) { - return this.isArrayBufferView(data) || this.isArrayBuffer(data); - } - static isArrayBufferView(data) { - return ArrayBuffer.isView(data) || data && this.isArrayBuffer(data.buffer); - } - static isEqual(a2, b) { - const aView = BufferSourceConverter8.toUint8Array(a2); - const bView = BufferSourceConverter8.toUint8Array(b); - if (aView.length !== bView.byteLength) { - return false; - } - for (let i = 0; i < aView.length; i++) { - if (aView[i] !== bView[i]) { - return false; - } - } - return true; - } - static concat(...args) { - if (Array.isArray(args[0])) { - const buffers = args[0]; - let size = 0; - for (const buffer of buffers) { - size += buffer.byteLength; - } - const res = new Uint8Array(size); - let offset = 0; - for (const buffer of buffers) { - const view = this.toUint8Array(buffer); - res.set(view, offset); - offset += view.length; - } - if (args[1]) { - return this.toView(res, args[1]); - } - return res.buffer; - } else { - return this.concat(args); - } - } - }; - var Utf8Converter = class { - static fromString(text) { - const s = unescape(encodeURIComponent(text)); - const uintArray = new Uint8Array(s.length); - for (let i = 0; i < s.length; i++) { - uintArray[i] = s.charCodeAt(i); - } - return uintArray.buffer; - } - static toString(buffer) { - const buf = BufferSourceConverter8.toUint8Array(buffer); - let encodedString = ""; - for (let i = 0; i < buf.length; i++) { - encodedString += String.fromCharCode(buf[i]); - } - const decodedString = decodeURIComponent(escape(encodedString)); - return decodedString; - } - }; - var Utf16Converter = class { - static toString(buffer, littleEndian = false) { - const arrayBuffer = BufferSourceConverter8.toArrayBuffer(buffer); - const dataView = new DataView(arrayBuffer); - let res = ""; - for (let i = 0; i < arrayBuffer.byteLength; i += 2) { - const code = dataView.getUint16(i, littleEndian); - res += String.fromCharCode(code); - } - return res; - } - static fromString(text, littleEndian = false) { - const res = new ArrayBuffer(text.length * 2); - const dataView = new DataView(res); - for (let i = 0; i < text.length; i++) { - dataView.setUint16(i * 2, text.charCodeAt(i), littleEndian); - } - return res; - } - }; - var Convert4 = class { - static isHex(data) { - return typeof data === "string" && /^[a-z0-9]+$/i.test(data); - } - static isBase64(data) { - return typeof data === "string" && /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(data); - } - static isBase64Url(data) { - return typeof data === "string" && /^[a-zA-Z0-9-_]+$/i.test(data); - } - static ToString(buffer, enc = "utf8") { - const buf = BufferSourceConverter8.toUint8Array(buffer); - switch (enc.toLowerCase()) { - case "utf8": - return this.ToUtf8String(buf); - case "binary": - return this.ToBinary(buf); - case "hex": - return this.ToHex(buf); - case "base64": - return this.ToBase64(buf); - case "base64url": - return this.ToBase64Url(buf); - case "utf16le": - return Utf16Converter.toString(buf, true); - case "utf16": - case "utf16be": - return Utf16Converter.toString(buf); - default: - throw new Error(`Unknown type of encoding '${enc}'`); - } - } - static FromString(str, enc = "utf8") { - if (!str) { - return new ArrayBuffer(0); - } - switch (enc.toLowerCase()) { - case "utf8": - return this.FromUtf8String(str); - case "binary": - return this.FromBinary(str); - case "hex": - return this.FromHex(str); - case "base64": - return this.FromBase64(str); - case "base64url": - return this.FromBase64Url(str); - case "utf16le": - return Utf16Converter.fromString(str, true); - case "utf16": - case "utf16be": - return Utf16Converter.fromString(str); - default: - throw new Error(`Unknown type of encoding '${enc}'`); - } - } - static ToBase64(buffer) { - const buf = BufferSourceConverter8.toUint8Array(buffer); - if (typeof btoa !== "undefined") { - const binary = this.ToString(buf, "binary"); - return btoa(binary); - } else { - return Buffer.from(buf).toString("base64"); - } - } - static FromBase64(base64) { - const formatted = this.formatString(base64); - if (!formatted) { - return new ArrayBuffer(0); - } - if (!Convert4.isBase64(formatted)) { - throw new TypeError("Argument 'base64Text' is not Base64 encoded"); - } - if (typeof atob !== "undefined") { - return this.FromBinary(atob(formatted)); - } else { - return new Uint8Array(Buffer.from(formatted, "base64")).buffer; - } - } - static FromBase64Url(base64url) { - const formatted = this.formatString(base64url); - if (!formatted) { - return new ArrayBuffer(0); - } - if (!Convert4.isBase64Url(formatted)) { - throw new TypeError("Argument 'base64url' is not Base64Url encoded"); - } - return this.FromBase64(this.Base64Padding(formatted.replace(/\-/g, "+").replace(/\_/g, "/"))); - } - static ToBase64Url(data) { - return this.ToBase64(data).replace(/\+/g, "-").replace(/\//g, "_").replace(/\=/g, ""); - } - static FromUtf8String(text, encoding = Convert4.DEFAULT_UTF8_ENCODING) { - switch (encoding) { - case "ascii": - return this.FromBinary(text); - case "utf8": - return Utf8Converter.fromString(text); - case "utf16": - case "utf16be": - return Utf16Converter.fromString(text); - case "utf16le": - case "usc2": - return Utf16Converter.fromString(text, true); - default: - throw new Error(`Unknown type of encoding '${encoding}'`); - } - } - static ToUtf8String(buffer, encoding = Convert4.DEFAULT_UTF8_ENCODING) { - switch (encoding) { - case "ascii": - return this.ToBinary(buffer); - case "utf8": - return Utf8Converter.toString(buffer); - case "utf16": - case "utf16be": - return Utf16Converter.toString(buffer); - case "utf16le": - case "usc2": - return Utf16Converter.toString(buffer, true); - default: - throw new Error(`Unknown type of encoding '${encoding}'`); - } - } - static FromBinary(text) { - const stringLength = text.length; - const resultView = new Uint8Array(stringLength); - for (let i = 0; i < stringLength; i++) { - resultView[i] = text.charCodeAt(i); - } - return resultView.buffer; - } - static ToBinary(buffer) { - const buf = BufferSourceConverter8.toUint8Array(buffer); - let res = ""; - for (let i = 0; i < buf.length; i++) { - res += String.fromCharCode(buf[i]); - } - return res; - } - static ToHex(buffer) { - const buf = BufferSourceConverter8.toUint8Array(buffer); - const splitter = ""; - const res = []; - const len = buf.length; - for (let i = 0; i < len; i++) { - const char = buf[i].toString(16).padStart(2, "0"); - res.push(char); - } - return res.join(splitter); - } - static FromHex(hexString) { - let formatted = this.formatString(hexString); - if (!formatted) { - return new ArrayBuffer(0); - } - if (!Convert4.isHex(formatted)) { - throw new TypeError("Argument 'hexString' is not HEX encoded"); - } - if (formatted.length % 2) { - formatted = `0${formatted}`; - } - const res = new Uint8Array(formatted.length / 2); - for (let i = 0; i < formatted.length; i = i + 2) { - const c = formatted.slice(i, i + 2); - res[i / 2] = parseInt(c, 16); - } - return res.buffer; - } - static ToUtf16String(buffer, littleEndian = false) { - return Utf16Converter.toString(buffer, littleEndian); - } - static FromUtf16String(text, littleEndian = false) { - return Utf16Converter.fromString(text, littleEndian); - } - static Base64Padding(base64) { - const padCount = 4 - base64.length % 4; - if (padCount < 4) { - for (let i = 0; i < padCount; i++) { - base64 += "="; - } - } - return base64; - } - static formatString(data) { - return (data === null || data === void 0 ? void 0 : data.replace(/[\n\r\t ]/g, "")) || ""; - } - }; - Convert4.DEFAULT_UTF8_ENCODING = "utf8"; - function assign(target, ...sources) { - const res = arguments[0]; - for (let i = 1; i < arguments.length; i++) { - const obj = arguments[i]; - for (const prop in obj) { - res[prop] = obj[prop]; - } - } - return res; - } - function combine2(...buf) { - const totalByteLength = buf.map((item) => item.byteLength).reduce((prev, cur) => prev + cur); - const res = new Uint8Array(totalByteLength); - let currentPos = 0; - buf.map((item) => new Uint8Array(item)).forEach((arr) => { - for (const item2 of arr) { - res[currentPos++] = item2; - } - }); - return res.buffer; - } - function isEqual(bytes1, bytes2) { - if (!(bytes1 && bytes2)) { - return false; - } - if (bytes1.byteLength !== bytes2.byteLength) { - return false; - } - const b1 = new Uint8Array(bytes1); - const b2 = new Uint8Array(bytes2); - for (let i = 0; i < bytes1.byteLength; i++) { - if (b1[i] !== b2[i]) { - return false; - } - } - return true; - } - exports.BufferSourceConverter = BufferSourceConverter8; - exports.Convert = Convert4; - exports.assign = assign; - exports.combine = combine2; - exports.isEqual = isEqual; - } - }); - - // node_modules/.pnpm/pvutils@1.1.3/node_modules/pvutils/build/utils.es.js - function utilFromBase(inputBuffer, inputBase) { - let result = 0; - if (inputBuffer.length === 1) { - return inputBuffer[0]; - } - for (let i = inputBuffer.length - 1; i >= 0; i--) { - result += inputBuffer[inputBuffer.length - 1 - i] * Math.pow(2, inputBase * i); - } - return result; - } - function utilToBase(value, base, reserved = -1) { - const internalReserved = reserved; - let internalValue = value; - let result = 0; - let biggest = Math.pow(2, base); - for (let i = 1; i < 8; i++) { - if (value < biggest) { - let retBuf; - if (internalReserved < 0) { - retBuf = new ArrayBuffer(i); - result = i; - } else { - if (internalReserved < i) { - return new ArrayBuffer(0); - } - retBuf = new ArrayBuffer(internalReserved); - result = internalReserved; - } - const retView = new Uint8Array(retBuf); - for (let j = i - 1; j >= 0; j--) { - const basis = Math.pow(2, j * base); - retView[result - j - 1] = Math.floor(internalValue / basis); - internalValue -= retView[result - j - 1] * basis; - } - return retBuf; - } - biggest *= Math.pow(2, base); - } - return new ArrayBuffer(0); - } - function utilConcatView(...views) { - let outputLength = 0; - let prevLength = 0; - for (const view of views) { - outputLength += view.length; - } - const retBuf = new ArrayBuffer(outputLength); - const retView = new Uint8Array(retBuf); - for (const view of views) { - retView.set(view, prevLength); - prevLength += view.length; - } - return retView; - } - function utilDecodeTC() { - const buf = new Uint8Array(this.valueHex); - if (this.valueHex.byteLength >= 2) { - const condition1 = buf[0] === 255 && buf[1] & 128; - const condition2 = buf[0] === 0 && (buf[1] & 128) === 0; - if (condition1 || condition2) { - this.warnings.push("Needlessly long format"); - } - } - const bigIntBuffer = new ArrayBuffer(this.valueHex.byteLength); - const bigIntView = new Uint8Array(bigIntBuffer); - for (let i = 0; i < this.valueHex.byteLength; i++) { - bigIntView[i] = 0; - } - bigIntView[0] = buf[0] & 128; - const bigInt = utilFromBase(bigIntView, 8); - const smallIntBuffer = new ArrayBuffer(this.valueHex.byteLength); - const smallIntView = new Uint8Array(smallIntBuffer); - for (let j = 0; j < this.valueHex.byteLength; j++) { - smallIntView[j] = buf[j]; - } - smallIntView[0] &= 127; - const smallInt = utilFromBase(smallIntView, 8); - return smallInt - bigInt; - } - function utilEncodeTC(value) { - const modValue = value < 0 ? value * -1 : value; - let bigInt = 128; - for (let i = 1; i < 8; i++) { - if (modValue <= bigInt) { - if (value < 0) { - const smallInt = bigInt - modValue; - const retBuf2 = utilToBase(smallInt, 8, i); - const retView2 = new Uint8Array(retBuf2); - retView2[0] |= 128; - return retBuf2; - } - let retBuf = utilToBase(modValue, 8, i); - let retView = new Uint8Array(retBuf); - if (retView[0] & 128) { - const tempBuf = retBuf.slice(0); - const tempView = new Uint8Array(tempBuf); - retBuf = new ArrayBuffer(retBuf.byteLength + 1); - retView = new Uint8Array(retBuf); - for (let k = 0; k < tempBuf.byteLength; k++) { - retView[k + 1] = tempView[k]; - } - retView[0] = 0; - } - return retBuf; - } - bigInt *= Math.pow(2, 8); - } - return new ArrayBuffer(0); - } - function isEqualBuffer(inputBuffer1, inputBuffer2) { - if (inputBuffer1.byteLength !== inputBuffer2.byteLength) { - return false; - } - const view1 = new Uint8Array(inputBuffer1); - const view2 = new Uint8Array(inputBuffer2); - for (let i = 0; i < view1.length; i++) { - if (view1[i] !== view2[i]) { - return false; - } - } - return true; - } - function padNumber(inputNumber, fullLength) { - const str = inputNumber.toString(10); - if (fullLength < str.length) { - return ""; - } - const dif = fullLength - str.length; - const padding = new Array(dif); - for (let i = 0; i < dif; i++) { - padding[i] = "0"; - } - const paddingString = padding.join(""); - return paddingString.concat(str); - } - var log2; - var init_utils_es = __esm({ - "node_modules/.pnpm/pvutils@1.1.3/node_modules/pvutils/build/utils.es.js"() { - log2 = Math.log(2); - } - }); - - // node_modules/.pnpm/asn1js@3.0.5/node_modules/asn1js/build/index.es.js - var index_es_exports = {}; - __export(index_es_exports, { - Any: () => Any, - BaseBlock: () => BaseBlock, - BaseStringBlock: () => BaseStringBlock, - BitString: () => BitString, - BmpString: () => BmpString, - Boolean: () => Boolean2, - CharacterString: () => CharacterString, - Choice: () => Choice, - Constructed: () => Constructed, - DATE: () => DATE, - DateTime: () => DateTime, - Duration: () => Duration, - EndOfContent: () => EndOfContent, - Enumerated: () => Enumerated, - GeneralString: () => GeneralString, - GeneralizedTime: () => GeneralizedTime, - GraphicString: () => GraphicString, - HexBlock: () => HexBlock, - IA5String: () => IA5String, - Integer: () => Integer, - Null: () => Null, - NumericString: () => NumericString, - ObjectIdentifier: () => ObjectIdentifier, - OctetString: () => OctetString, - Primitive: () => Primitive, - PrintableString: () => PrintableString, - RawData: () => RawData, - RelativeObjectIdentifier: () => RelativeObjectIdentifier, - Repeated: () => Repeated, - Sequence: () => Sequence, - Set: () => Set2, - TIME: () => TIME, - TeletexString: () => TeletexString, - TimeOfDay: () => TimeOfDay, - UTCTime: () => UTCTime, - UniversalString: () => UniversalString, - Utf8String: () => Utf8String, - ValueBlock: () => ValueBlock, - VideotexString: () => VideotexString, - ViewWriter: () => ViewWriter, - VisibleString: () => VisibleString, - compareSchema: () => compareSchema, - fromBER: () => fromBER, - verifySchema: () => verifySchema - }); - function assertBigInt() { - if (typeof BigInt === "undefined") { - throw new Error("BigInt is not defined. Your environment doesn't implement BigInt."); - } - } - function concat(buffers) { - let outputLength = 0; - let prevLength = 0; - for (let i = 0; i < buffers.length; i++) { - const buffer = buffers[i]; - outputLength += buffer.byteLength; - } - const retView = new Uint8Array(outputLength); - for (let i = 0; i < buffers.length; i++) { - const buffer = buffers[i]; - retView.set(new Uint8Array(buffer), prevLength); - prevLength += buffer.byteLength; - } - return retView.buffer; - } - function checkBufferParams(baseBlock, inputBuffer, inputOffset, inputLength) { - if (!(inputBuffer instanceof Uint8Array)) { - baseBlock.error = "Wrong parameter: inputBuffer must be 'Uint8Array'"; - return false; - } - if (!inputBuffer.byteLength) { - baseBlock.error = "Wrong parameter: inputBuffer has zero length"; - return false; - } - if (inputOffset < 0) { - baseBlock.error = "Wrong parameter: inputOffset less than zero"; - return false; - } - if (inputLength < 0) { - baseBlock.error = "Wrong parameter: inputLength less than zero"; - return false; - } - if (inputBuffer.byteLength - inputOffset - inputLength < 0) { - baseBlock.error = "End of input reached before message was fully decoded (inconsistent offset and length values)"; - return false; - } - return true; - } - function HexBlock(BaseClass) { - var _a2; - return _a2 = class Some extends BaseClass { - constructor(...args) { - var _a3; - super(...args); - const params = args[0] || {}; - this.isHexOnly = (_a3 = params.isHexOnly) !== null && _a3 !== void 0 ? _a3 : false; - this.valueHexView = params.valueHex ? pvtsutils.BufferSourceConverter.toUint8Array(params.valueHex) : EMPTY_VIEW; - } - get valueHex() { - return this.valueHexView.slice().buffer; - } - set valueHex(value) { - this.valueHexView = new Uint8Array(value); - } - fromBER(inputBuffer, inputOffset, inputLength) { - const view = inputBuffer instanceof ArrayBuffer ? new Uint8Array(inputBuffer) : inputBuffer; - if (!checkBufferParams(this, view, inputOffset, inputLength)) { - return -1; - } - const endLength = inputOffset + inputLength; - this.valueHexView = view.subarray(inputOffset, endLength); - if (!this.valueHexView.length) { - this.warnings.push("Zero buffer length"); - return inputOffset; - } - this.blockLength = inputLength; - return endLength; - } - toBER(sizeOnly = false) { - if (!this.isHexOnly) { - this.error = "Flag 'isHexOnly' is not set, abort"; - return EMPTY_BUFFER; - } - if (sizeOnly) { - return new ArrayBuffer(this.valueHexView.byteLength); - } - return this.valueHexView.byteLength === this.valueHexView.buffer.byteLength ? this.valueHexView.buffer : this.valueHexView.slice().buffer; - } - toJSON() { - return { - ...super.toJSON(), - isHexOnly: this.isHexOnly, - valueHex: pvtsutils.Convert.ToHex(this.valueHexView) - }; - } - }, _a2.NAME = "hexBlock", _a2; - } - function prepareIndefiniteForm(baseBlock) { - if (baseBlock instanceof typeStore.Constructed) { - for (const value of baseBlock.valueBlock.value) { - if (prepareIndefiniteForm(value)) { - baseBlock.lenBlock.isIndefiniteForm = true; - } - } - } - return !!baseBlock.lenBlock.isIndefiniteForm; - } - function localChangeType(inputObject, newType) { - if (inputObject instanceof newType) { - return inputObject; - } - const newObject = new newType(); - newObject.idBlock = inputObject.idBlock; - newObject.lenBlock = inputObject.lenBlock; - newObject.warnings = inputObject.warnings; - newObject.valueBeforeDecodeView = inputObject.valueBeforeDecodeView; - return newObject; - } - function localFromBER(inputBuffer, inputOffset = 0, inputLength = inputBuffer.length) { - const incomingOffset = inputOffset; - let returnObject = new BaseBlock({}, ValueBlock); - const baseBlock = new LocalBaseBlock(); - if (!checkBufferParams(baseBlock, inputBuffer, inputOffset, inputLength)) { - returnObject.error = baseBlock.error; - return { - offset: -1, - result: returnObject - }; - } - const intBuffer = inputBuffer.subarray(inputOffset, inputOffset + inputLength); - if (!intBuffer.length) { - returnObject.error = "Zero buffer length"; - return { - offset: -1, - result: returnObject - }; - } - let resultOffset = returnObject.idBlock.fromBER(inputBuffer, inputOffset, inputLength); - if (returnObject.idBlock.warnings.length) { - returnObject.warnings.concat(returnObject.idBlock.warnings); - } - if (resultOffset === -1) { - returnObject.error = returnObject.idBlock.error; - return { - offset: -1, - result: returnObject - }; - } - inputOffset = resultOffset; - inputLength -= returnObject.idBlock.blockLength; - resultOffset = returnObject.lenBlock.fromBER(inputBuffer, inputOffset, inputLength); - if (returnObject.lenBlock.warnings.length) { - returnObject.warnings.concat(returnObject.lenBlock.warnings); - } - if (resultOffset === -1) { - returnObject.error = returnObject.lenBlock.error; - return { - offset: -1, - result: returnObject - }; - } - inputOffset = resultOffset; - inputLength -= returnObject.lenBlock.blockLength; - if (!returnObject.idBlock.isConstructed && returnObject.lenBlock.isIndefiniteForm) { - returnObject.error = "Indefinite length form used for primitive encoding form"; - return { - offset: -1, - result: returnObject - }; - } - let newASN1Type = BaseBlock; - switch (returnObject.idBlock.tagClass) { - case 1: - if (returnObject.idBlock.tagNumber >= 37 && returnObject.idBlock.isHexOnly === false) { - returnObject.error = "UNIVERSAL 37 and upper tags are reserved by ASN.1 standard"; - return { - offset: -1, - result: returnObject - }; - } - switch (returnObject.idBlock.tagNumber) { - case 0: - if (returnObject.idBlock.isConstructed && returnObject.lenBlock.length > 0) { - returnObject.error = "Type [UNIVERSAL 0] is reserved"; - return { - offset: -1, - result: returnObject - }; - } - newASN1Type = typeStore.EndOfContent; - break; - case 1: - newASN1Type = typeStore.Boolean; - break; - case 2: - newASN1Type = typeStore.Integer; - break; - case 3: - newASN1Type = typeStore.BitString; - break; - case 4: - newASN1Type = typeStore.OctetString; - break; - case 5: - newASN1Type = typeStore.Null; - break; - case 6: - newASN1Type = typeStore.ObjectIdentifier; - break; - case 10: - newASN1Type = typeStore.Enumerated; - break; - case 12: - newASN1Type = typeStore.Utf8String; - break; - case 13: - newASN1Type = typeStore.RelativeObjectIdentifier; - break; - case 14: - newASN1Type = typeStore.TIME; - break; - case 15: - returnObject.error = "[UNIVERSAL 15] is reserved by ASN.1 standard"; - return { - offset: -1, - result: returnObject - }; - case 16: - newASN1Type = typeStore.Sequence; - break; - case 17: - newASN1Type = typeStore.Set; - break; - case 18: - newASN1Type = typeStore.NumericString; - break; - case 19: - newASN1Type = typeStore.PrintableString; - break; - case 20: - newASN1Type = typeStore.TeletexString; - break; - case 21: - newASN1Type = typeStore.VideotexString; - break; - case 22: - newASN1Type = typeStore.IA5String; - break; - case 23: - newASN1Type = typeStore.UTCTime; - break; - case 24: - newASN1Type = typeStore.GeneralizedTime; - break; - case 25: - newASN1Type = typeStore.GraphicString; - break; - case 26: - newASN1Type = typeStore.VisibleString; - break; - case 27: - newASN1Type = typeStore.GeneralString; - break; - case 28: - newASN1Type = typeStore.UniversalString; - break; - case 29: - newASN1Type = typeStore.CharacterString; - break; - case 30: - newASN1Type = typeStore.BmpString; - break; - case 31: - newASN1Type = typeStore.DATE; - break; - case 32: - newASN1Type = typeStore.TimeOfDay; - break; - case 33: - newASN1Type = typeStore.DateTime; - break; - case 34: - newASN1Type = typeStore.Duration; - break; - default: { - const newObject = returnObject.idBlock.isConstructed ? new typeStore.Constructed() : new typeStore.Primitive(); - newObject.idBlock = returnObject.idBlock; - newObject.lenBlock = returnObject.lenBlock; - newObject.warnings = returnObject.warnings; - returnObject = newObject; - } - } - break; - case 2: - case 3: - case 4: - default: { - newASN1Type = returnObject.idBlock.isConstructed ? typeStore.Constructed : typeStore.Primitive; - } - } - returnObject = localChangeType(returnObject, newASN1Type); - resultOffset = returnObject.fromBER(inputBuffer, inputOffset, returnObject.lenBlock.isIndefiniteForm ? inputLength : returnObject.lenBlock.length); - returnObject.valueBeforeDecodeView = inputBuffer.subarray(incomingOffset, incomingOffset + returnObject.blockLength); - return { - offset: resultOffset, - result: returnObject - }; - } - function fromBER(inputBuffer) { - if (!inputBuffer.byteLength) { - const result = new BaseBlock({}, ValueBlock); - result.error = "Input buffer has zero length"; - return { - offset: -1, - result - }; - } - return localFromBER(pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer).slice(), 0, inputBuffer.byteLength); - } - function checkLen(indefiniteLength, length) { - if (indefiniteLength) { - return 1; - } - return length; - } - function viewAdd(first, second) { - const c = new Uint8Array([0]); - const firstView = new Uint8Array(first); - const secondView = new Uint8Array(second); - let firstViewCopy = firstView.slice(0); - const firstViewCopyLength = firstViewCopy.length - 1; - const secondViewCopy = secondView.slice(0); - const secondViewCopyLength = secondViewCopy.length - 1; - let value = 0; - const max = secondViewCopyLength < firstViewCopyLength ? firstViewCopyLength : secondViewCopyLength; - let counter = 0; - for (let i = max; i >= 0; i--, counter++) { - switch (true) { - case counter < secondViewCopy.length: - value = firstViewCopy[firstViewCopyLength - counter] + secondViewCopy[secondViewCopyLength - counter] + c[0]; - break; - default: - value = firstViewCopy[firstViewCopyLength - counter] + c[0]; - } - c[0] = value / 10; - switch (true) { - case counter >= firstViewCopy.length: - firstViewCopy = utilConcatView(new Uint8Array([value % 10]), firstViewCopy); - break; - default: - firstViewCopy[firstViewCopyLength - counter] = value % 10; - } - } - if (c[0] > 0) - firstViewCopy = utilConcatView(c, firstViewCopy); - return firstViewCopy; - } - function power2(n) { - if (n >= powers2.length) { - for (let p = powers2.length; p <= n; p++) { - const c = new Uint8Array([0]); - let digits = powers2[p - 1].slice(0); - for (let i = digits.length - 1; i >= 0; i--) { - const newValue = new Uint8Array([(digits[i] << 1) + c[0]]); - c[0] = newValue[0] / 10; - digits[i] = newValue[0] % 10; - } - if (c[0] > 0) - digits = utilConcatView(c, digits); - powers2.push(digits); - } - } - return powers2[n]; - } - function viewSub(first, second) { - let b = 0; - const firstView = new Uint8Array(first); - const secondView = new Uint8Array(second); - const firstViewCopy = firstView.slice(0); - const firstViewCopyLength = firstViewCopy.length - 1; - const secondViewCopy = secondView.slice(0); - const secondViewCopyLength = secondViewCopy.length - 1; - let value; - let counter = 0; - for (let i = secondViewCopyLength; i >= 0; i--, counter++) { - value = firstViewCopy[firstViewCopyLength - counter] - secondViewCopy[secondViewCopyLength - counter] - b; - switch (true) { - case value < 0: - b = 1; - firstViewCopy[firstViewCopyLength - counter] = value + 10; - break; - default: - b = 0; - firstViewCopy[firstViewCopyLength - counter] = value; - } - } - if (b > 0) { - for (let i = firstViewCopyLength - secondViewCopyLength + 1; i >= 0; i--, counter++) { - value = firstViewCopy[firstViewCopyLength - counter] - b; - if (value < 0) { - b = 1; - firstViewCopy[firstViewCopyLength - counter] = value + 10; - } else { - b = 0; - firstViewCopy[firstViewCopyLength - counter] = value; - break; - } - } - } - return firstViewCopy.slice(); - } - function compareSchema(root, inputData, inputSchema) { - if (inputSchema instanceof Choice) { - for (let j = 0; j < inputSchema.value.length; j++) { - const result = compareSchema(root, inputData, inputSchema.value[j]); - if (result.verified) { - return { - verified: true, - result: root - }; - } - } - { - const _result = { - verified: false, - result: { - error: "Wrong values for Choice type" - } - }; - if (inputSchema.hasOwnProperty(NAME)) - _result.name = inputSchema.name; - return _result; - } - } - if (inputSchema instanceof Any) { - if (inputSchema.hasOwnProperty(NAME)) - root[inputSchema.name] = inputData; - return { - verified: true, - result: root - }; - } - if (root instanceof Object === false) { - return { - verified: false, - result: { error: "Wrong root object" } - }; - } - if (inputData instanceof Object === false) { - return { - verified: false, - result: { error: "Wrong ASN.1 data" } - }; - } - if (inputSchema instanceof Object === false) { - return { - verified: false, - result: { error: "Wrong ASN.1 schema" } - }; - } - if (ID_BLOCK in inputSchema === false) { - return { - verified: false, - result: { error: "Wrong ASN.1 schema" } - }; - } - if (FROM_BER in inputSchema.idBlock === false) { - return { - verified: false, - result: { error: "Wrong ASN.1 schema" } - }; - } - if (TO_BER in inputSchema.idBlock === false) { - return { - verified: false, - result: { error: "Wrong ASN.1 schema" } - }; - } - const encodedId = inputSchema.idBlock.toBER(false); - if (encodedId.byteLength === 0) { - return { - verified: false, - result: { error: "Error encoding idBlock for ASN.1 schema" } - }; - } - const decodedOffset = inputSchema.idBlock.fromBER(encodedId, 0, encodedId.byteLength); - if (decodedOffset === -1) { - return { - verified: false, - result: { error: "Error decoding idBlock for ASN.1 schema" } - }; - } - if (inputSchema.idBlock.hasOwnProperty(TAG_CLASS) === false) { - return { - verified: false, - result: { error: "Wrong ASN.1 schema" } - }; - } - if (inputSchema.idBlock.tagClass !== inputData.idBlock.tagClass) { - return { - verified: false, - result: root - }; - } - if (inputSchema.idBlock.hasOwnProperty(TAG_NUMBER) === false) { - return { - verified: false, - result: { error: "Wrong ASN.1 schema" } - }; - } - if (inputSchema.idBlock.tagNumber !== inputData.idBlock.tagNumber) { - return { - verified: false, - result: root - }; - } - if (inputSchema.idBlock.hasOwnProperty(IS_CONSTRUCTED) === false) { - return { - verified: false, - result: { error: "Wrong ASN.1 schema" } - }; - } - if (inputSchema.idBlock.isConstructed !== inputData.idBlock.isConstructed) { - return { - verified: false, - result: root - }; - } - if (!(IS_HEX_ONLY in inputSchema.idBlock)) { - return { - verified: false, - result: { error: "Wrong ASN.1 schema" } - }; - } - if (inputSchema.idBlock.isHexOnly !== inputData.idBlock.isHexOnly) { - return { - verified: false, - result: root - }; - } - if (inputSchema.idBlock.isHexOnly) { - if (VALUE_HEX_VIEW in inputSchema.idBlock === false) { - return { - verified: false, - result: { error: "Wrong ASN.1 schema" } - }; - } - const schemaView = inputSchema.idBlock.valueHexView; - const asn1View = inputData.idBlock.valueHexView; - if (schemaView.length !== asn1View.length) { - return { - verified: false, - result: root - }; - } - for (let i = 0; i < schemaView.length; i++) { - if (schemaView[i] !== asn1View[1]) { - return { - verified: false, - result: root - }; - } - } - } - if (inputSchema.name) { - inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, EMPTY_STRING); - if (inputSchema.name) - root[inputSchema.name] = inputData; - } - if (inputSchema instanceof typeStore.Constructed) { - let admission = 0; - let result = { - verified: false, - result: { - error: "Unknown error" - } - }; - let maxLength = inputSchema.valueBlock.value.length; - if (maxLength > 0) { - if (inputSchema.valueBlock.value[0] instanceof Repeated) { - maxLength = inputData.valueBlock.value.length; - } - } - if (maxLength === 0) { - return { - verified: true, - result: root - }; - } - if (inputData.valueBlock.value.length === 0 && inputSchema.valueBlock.value.length !== 0) { - let _optional = true; - for (let i = 0; i < inputSchema.valueBlock.value.length; i++) - _optional = _optional && (inputSchema.valueBlock.value[i].optional || false); - if (_optional) { - return { - verified: true, - result: root - }; - } - if (inputSchema.name) { - inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, EMPTY_STRING); - if (inputSchema.name) - delete root[inputSchema.name]; - } - root.error = "Inconsistent object length"; - return { - verified: false, - result: root - }; - } - for (let i = 0; i < maxLength; i++) { - if (i - admission >= inputData.valueBlock.value.length) { - if (inputSchema.valueBlock.value[i].optional === false) { - const _result = { - verified: false, - result: root - }; - root.error = "Inconsistent length between ASN.1 data and schema"; - if (inputSchema.name) { - inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, EMPTY_STRING); - if (inputSchema.name) { - delete root[inputSchema.name]; - _result.name = inputSchema.name; - } - } - return _result; - } - } else { - if (inputSchema.valueBlock.value[0] instanceof Repeated) { - result = compareSchema(root, inputData.valueBlock.value[i], inputSchema.valueBlock.value[0].value); - if (result.verified === false) { - if (inputSchema.valueBlock.value[0].optional) - admission++; - else { - if (inputSchema.name) { - inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, EMPTY_STRING); - if (inputSchema.name) - delete root[inputSchema.name]; - } - return result; - } - } - if (NAME in inputSchema.valueBlock.value[0] && inputSchema.valueBlock.value[0].name.length > 0) { - let arrayRoot = {}; - if (LOCAL in inputSchema.valueBlock.value[0] && inputSchema.valueBlock.value[0].local) - arrayRoot = inputData; - else - arrayRoot = root; - if (typeof arrayRoot[inputSchema.valueBlock.value[0].name] === "undefined") - arrayRoot[inputSchema.valueBlock.value[0].name] = []; - arrayRoot[inputSchema.valueBlock.value[0].name].push(inputData.valueBlock.value[i]); - } - } else { - result = compareSchema(root, inputData.valueBlock.value[i - admission], inputSchema.valueBlock.value[i]); - if (result.verified === false) { - if (inputSchema.valueBlock.value[i].optional) - admission++; - else { - if (inputSchema.name) { - inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, EMPTY_STRING); - if (inputSchema.name) - delete root[inputSchema.name]; - } - return result; - } - } - } - } - } - if (result.verified === false) { - const _result = { - verified: false, - result: root - }; - if (inputSchema.name) { - inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, EMPTY_STRING); - if (inputSchema.name) { - delete root[inputSchema.name]; - _result.name = inputSchema.name; - } - } - return _result; - } - return { - verified: true, - result: root - }; - } - if (inputSchema.primitiveSchema && VALUE_HEX_VIEW in inputData.valueBlock) { - const asn1 = localFromBER(inputData.valueBlock.valueHexView); - if (asn1.offset === -1) { - const _result = { - verified: false, - result: asn1.result - }; - if (inputSchema.name) { - inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, EMPTY_STRING); - if (inputSchema.name) { - delete root[inputSchema.name]; - _result.name = inputSchema.name; - } - } - return _result; - } - return compareSchema(root, asn1.result, inputSchema.primitiveSchema); - } - return { - verified: true, - result: root - }; - } - function verifySchema(inputBuffer, inputSchema) { - if (inputSchema instanceof Object === false) { - return { - verified: false, - result: { error: "Wrong ASN.1 schema type" } - }; - } - const asn1 = localFromBER(pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer)); - if (asn1.offset === -1) { - return { - verified: false, - result: asn1.result - }; - } - return compareSchema(asn1.result, asn1.result, inputSchema); - } - var pvtsutils, ViewWriter, powers2, digitsString, NAME, VALUE_HEX_VIEW, IS_HEX_ONLY, ID_BLOCK, TAG_CLASS, TAG_NUMBER, IS_CONSTRUCTED, FROM_BER, TO_BER, LOCAL, EMPTY_STRING, EMPTY_BUFFER, EMPTY_VIEW, END_OF_CONTENT_NAME, OCTET_STRING_NAME, BIT_STRING_NAME, LocalBaseBlock, ValueBlock, LocalIdentificationBlock, LocalLengthBlock, typeStore, BaseBlock, BaseStringBlock, LocalPrimitiveValueBlock, _a$w, Primitive, LocalConstructedValueBlock, _a$v, Constructed, LocalEndOfContentValueBlock, _a$u, EndOfContent, _a$t, Null, LocalBooleanValueBlock, _a$s, Boolean2, LocalOctetStringValueBlock, _a$r, OctetString, LocalBitStringValueBlock, _a$q, BitString, _a$p, LocalIntegerValueBlock, _a$o, Integer, _a$n, Enumerated, LocalSidValueBlock, LocalObjectIdentifierValueBlock, _a$m, ObjectIdentifier, LocalRelativeSidValueBlock, LocalRelativeObjectIdentifierValueBlock, _a$l, RelativeObjectIdentifier, _a$k, Sequence, _a$j, Set2, LocalStringValueBlock, LocalSimpleStringValueBlock, LocalSimpleStringBlock, LocalUtf8StringValueBlock, _a$i, Utf8String, LocalBmpStringValueBlock, _a$h, BmpString, LocalUniversalStringValueBlock, _a$g, UniversalString, _a$f, NumericString, _a$e, PrintableString, _a$d, TeletexString, _a$c, VideotexString, _a$b, IA5String, _a$a, GraphicString, _a$9, VisibleString, _a$8, GeneralString, _a$7, CharacterString, _a$6, UTCTime, _a$5, GeneralizedTime, _a$4, DATE, _a$3, TimeOfDay, _a$2, DateTime, _a$1, Duration, _a, TIME, Any, Choice, Repeated, RawData; - var init_index_es = __esm({ - "node_modules/.pnpm/asn1js@3.0.5/node_modules/asn1js/build/index.es.js"() { - pvtsutils = __toESM(require_build()); - init_utils_es(); - ViewWriter = class { - constructor() { - this.items = []; - } - write(buf) { - this.items.push(buf); - } - final() { - return concat(this.items); - } - }; - powers2 = [new Uint8Array([1])]; - digitsString = "0123456789"; - NAME = "name"; - VALUE_HEX_VIEW = "valueHexView"; - IS_HEX_ONLY = "isHexOnly"; - ID_BLOCK = "idBlock"; - TAG_CLASS = "tagClass"; - TAG_NUMBER = "tagNumber"; - IS_CONSTRUCTED = "isConstructed"; - FROM_BER = "fromBER"; - TO_BER = "toBER"; - LOCAL = "local"; - EMPTY_STRING = ""; - EMPTY_BUFFER = new ArrayBuffer(0); - EMPTY_VIEW = new Uint8Array(0); - END_OF_CONTENT_NAME = "EndOfContent"; - OCTET_STRING_NAME = "OCTET STRING"; - BIT_STRING_NAME = "BIT STRING"; - LocalBaseBlock = class { - constructor({ blockLength = 0, error = EMPTY_STRING, warnings = [], valueBeforeDecode = EMPTY_VIEW } = {}) { - this.blockLength = blockLength; - this.error = error; - this.warnings = warnings; - this.valueBeforeDecodeView = pvtsutils.BufferSourceConverter.toUint8Array(valueBeforeDecode); - } - static blockName() { - return this.NAME; - } - get valueBeforeDecode() { - return this.valueBeforeDecodeView.slice().buffer; - } - set valueBeforeDecode(value) { - this.valueBeforeDecodeView = new Uint8Array(value); - } - toJSON() { - return { - blockName: this.constructor.NAME, - blockLength: this.blockLength, - error: this.error, - warnings: this.warnings, - valueBeforeDecode: pvtsutils.Convert.ToHex(this.valueBeforeDecodeView) - }; - } - }; - LocalBaseBlock.NAME = "baseBlock"; - ValueBlock = class extends LocalBaseBlock { - fromBER(inputBuffer, inputOffset, inputLength) { - throw TypeError("User need to make a specific function in a class which extends 'ValueBlock'"); - } - toBER(sizeOnly, writer) { - throw TypeError("User need to make a specific function in a class which extends 'ValueBlock'"); - } - }; - ValueBlock.NAME = "valueBlock"; - LocalIdentificationBlock = class extends HexBlock(LocalBaseBlock) { - constructor({ idBlock = {} } = {}) { - var _a2, _b, _c, _d; - super(); - if (idBlock) { - this.isHexOnly = (_a2 = idBlock.isHexOnly) !== null && _a2 !== void 0 ? _a2 : false; - this.valueHexView = idBlock.valueHex ? pvtsutils.BufferSourceConverter.toUint8Array(idBlock.valueHex) : EMPTY_VIEW; - this.tagClass = (_b = idBlock.tagClass) !== null && _b !== void 0 ? _b : -1; - this.tagNumber = (_c = idBlock.tagNumber) !== null && _c !== void 0 ? _c : -1; - this.isConstructed = (_d = idBlock.isConstructed) !== null && _d !== void 0 ? _d : false; - } else { - this.tagClass = -1; - this.tagNumber = -1; - this.isConstructed = false; - } - } - toBER(sizeOnly = false) { - let firstOctet = 0; - switch (this.tagClass) { - case 1: - firstOctet |= 0; - break; - case 2: - firstOctet |= 64; - break; - case 3: - firstOctet |= 128; - break; - case 4: - firstOctet |= 192; - break; - default: - this.error = "Unknown tag class"; - return EMPTY_BUFFER; - } - if (this.isConstructed) - firstOctet |= 32; - if (this.tagNumber < 31 && !this.isHexOnly) { - const retView2 = new Uint8Array(1); - if (!sizeOnly) { - let number = this.tagNumber; - number &= 31; - firstOctet |= number; - retView2[0] = firstOctet; - } - return retView2.buffer; - } - if (!this.isHexOnly) { - const encodedBuf = utilToBase(this.tagNumber, 7); - const encodedView = new Uint8Array(encodedBuf); - const size = encodedBuf.byteLength; - const retView2 = new Uint8Array(size + 1); - retView2[0] = firstOctet | 31; - if (!sizeOnly) { - for (let i = 0; i < size - 1; i++) - retView2[i + 1] = encodedView[i] | 128; - retView2[size] = encodedView[size - 1]; - } - return retView2.buffer; - } - const retView = new Uint8Array(this.valueHexView.byteLength + 1); - retView[0] = firstOctet | 31; - if (!sizeOnly) { - const curView = this.valueHexView; - for (let i = 0; i < curView.length - 1; i++) - retView[i + 1] = curView[i] | 128; - retView[this.valueHexView.byteLength] = curView[curView.length - 1]; - } - return retView.buffer; - } - fromBER(inputBuffer, inputOffset, inputLength) { - const inputView = pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer); - if (!checkBufferParams(this, inputView, inputOffset, inputLength)) { - return -1; - } - const intBuffer = inputView.subarray(inputOffset, inputOffset + inputLength); - if (intBuffer.length === 0) { - this.error = "Zero buffer length"; - return -1; - } - const tagClassMask = intBuffer[0] & 192; - switch (tagClassMask) { - case 0: - this.tagClass = 1; - break; - case 64: - this.tagClass = 2; - break; - case 128: - this.tagClass = 3; - break; - case 192: - this.tagClass = 4; - break; - default: - this.error = "Unknown tag class"; - return -1; - } - this.isConstructed = (intBuffer[0] & 32) === 32; - this.isHexOnly = false; - const tagNumberMask = intBuffer[0] & 31; - if (tagNumberMask !== 31) { - this.tagNumber = tagNumberMask; - this.blockLength = 1; - } else { - let count = 1; - let intTagNumberBuffer = this.valueHexView = new Uint8Array(255); - let tagNumberBufferMaxLength = 255; - while (intBuffer[count] & 128) { - intTagNumberBuffer[count - 1] = intBuffer[count] & 127; - count++; - if (count >= intBuffer.length) { - this.error = "End of input reached before message was fully decoded"; - return -1; - } - if (count === tagNumberBufferMaxLength) { - tagNumberBufferMaxLength += 255; - const tempBufferView2 = new Uint8Array(tagNumberBufferMaxLength); - for (let i = 0; i < intTagNumberBuffer.length; i++) - tempBufferView2[i] = intTagNumberBuffer[i]; - intTagNumberBuffer = this.valueHexView = new Uint8Array(tagNumberBufferMaxLength); - } - } - this.blockLength = count + 1; - intTagNumberBuffer[count - 1] = intBuffer[count] & 127; - const tempBufferView = new Uint8Array(count); - for (let i = 0; i < count; i++) - tempBufferView[i] = intTagNumberBuffer[i]; - intTagNumberBuffer = this.valueHexView = new Uint8Array(count); - intTagNumberBuffer.set(tempBufferView); - if (this.blockLength <= 9) - this.tagNumber = utilFromBase(intTagNumberBuffer, 7); - else { - this.isHexOnly = true; - this.warnings.push("Tag too long, represented as hex-coded"); - } - } - if (this.tagClass === 1 && this.isConstructed) { - switch (this.tagNumber) { - case 1: - case 2: - case 5: - case 6: - case 9: - case 13: - case 14: - case 23: - case 24: - case 31: - case 32: - case 33: - case 34: - this.error = "Constructed encoding used for primitive type"; - return -1; - } - } - return inputOffset + this.blockLength; - } - toJSON() { - return { - ...super.toJSON(), - tagClass: this.tagClass, - tagNumber: this.tagNumber, - isConstructed: this.isConstructed - }; - } - }; - LocalIdentificationBlock.NAME = "identificationBlock"; - LocalLengthBlock = class extends LocalBaseBlock { - constructor({ lenBlock = {} } = {}) { - var _a2, _b, _c; - super(); - this.isIndefiniteForm = (_a2 = lenBlock.isIndefiniteForm) !== null && _a2 !== void 0 ? _a2 : false; - this.longFormUsed = (_b = lenBlock.longFormUsed) !== null && _b !== void 0 ? _b : false; - this.length = (_c = lenBlock.length) !== null && _c !== void 0 ? _c : 0; - } - fromBER(inputBuffer, inputOffset, inputLength) { - const view = pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer); - if (!checkBufferParams(this, view, inputOffset, inputLength)) { - return -1; - } - const intBuffer = view.subarray(inputOffset, inputOffset + inputLength); - if (intBuffer.length === 0) { - this.error = "Zero buffer length"; - return -1; - } - if (intBuffer[0] === 255) { - this.error = "Length block 0xFF is reserved by standard"; - return -1; - } - this.isIndefiniteForm = intBuffer[0] === 128; - if (this.isIndefiniteForm) { - this.blockLength = 1; - return inputOffset + this.blockLength; - } - this.longFormUsed = !!(intBuffer[0] & 128); - if (this.longFormUsed === false) { - this.length = intBuffer[0]; - this.blockLength = 1; - return inputOffset + this.blockLength; - } - const count = intBuffer[0] & 127; - if (count > 8) { - this.error = "Too big integer"; - return -1; - } - if (count + 1 > intBuffer.length) { - this.error = "End of input reached before message was fully decoded"; - return -1; - } - const lenOffset = inputOffset + 1; - const lengthBufferView = view.subarray(lenOffset, lenOffset + count); - if (lengthBufferView[count - 1] === 0) - this.warnings.push("Needlessly long encoded length"); - this.length = utilFromBase(lengthBufferView, 8); - if (this.longFormUsed && this.length <= 127) - this.warnings.push("Unnecessary usage of long length form"); - this.blockLength = count + 1; - return inputOffset + this.blockLength; - } - toBER(sizeOnly = false) { - let retBuf; - let retView; - if (this.length > 127) - this.longFormUsed = true; - if (this.isIndefiniteForm) { - retBuf = new ArrayBuffer(1); - if (sizeOnly === false) { - retView = new Uint8Array(retBuf); - retView[0] = 128; - } - return retBuf; - } - if (this.longFormUsed) { - const encodedBuf = utilToBase(this.length, 8); - if (encodedBuf.byteLength > 127) { - this.error = "Too big length"; - return EMPTY_BUFFER; - } - retBuf = new ArrayBuffer(encodedBuf.byteLength + 1); - if (sizeOnly) - return retBuf; - const encodedView = new Uint8Array(encodedBuf); - retView = new Uint8Array(retBuf); - retView[0] = encodedBuf.byteLength | 128; - for (let i = 0; i < encodedBuf.byteLength; i++) - retView[i + 1] = encodedView[i]; - return retBuf; - } - retBuf = new ArrayBuffer(1); - if (sizeOnly === false) { - retView = new Uint8Array(retBuf); - retView[0] = this.length; - } - return retBuf; - } - toJSON() { - return { - ...super.toJSON(), - isIndefiniteForm: this.isIndefiniteForm, - longFormUsed: this.longFormUsed, - length: this.length - }; - } - }; - LocalLengthBlock.NAME = "lengthBlock"; - typeStore = {}; - BaseBlock = class extends LocalBaseBlock { - constructor({ name = EMPTY_STRING, optional = false, primitiveSchema, ...parameters } = {}, valueBlockType) { - super(parameters); - this.name = name; - this.optional = optional; - if (primitiveSchema) { - this.primitiveSchema = primitiveSchema; - } - this.idBlock = new LocalIdentificationBlock(parameters); - this.lenBlock = new LocalLengthBlock(parameters); - this.valueBlock = valueBlockType ? new valueBlockType(parameters) : new ValueBlock(parameters); - } - fromBER(inputBuffer, inputOffset, inputLength) { - const resultOffset = this.valueBlock.fromBER(inputBuffer, inputOffset, this.lenBlock.isIndefiniteForm ? inputLength : this.lenBlock.length); - if (resultOffset === -1) { - this.error = this.valueBlock.error; - return resultOffset; - } - if (!this.idBlock.error.length) - this.blockLength += this.idBlock.blockLength; - if (!this.lenBlock.error.length) - this.blockLength += this.lenBlock.blockLength; - if (!this.valueBlock.error.length) - this.blockLength += this.valueBlock.blockLength; - return resultOffset; - } - toBER(sizeOnly, writer) { - const _writer = writer || new ViewWriter(); - if (!writer) { - prepareIndefiniteForm(this); - } - const idBlockBuf = this.idBlock.toBER(sizeOnly); - _writer.write(idBlockBuf); - if (this.lenBlock.isIndefiniteForm) { - _writer.write(new Uint8Array([128]).buffer); - this.valueBlock.toBER(sizeOnly, _writer); - _writer.write(new ArrayBuffer(2)); - } else { - const valueBlockBuf = this.valueBlock.toBER(sizeOnly); - this.lenBlock.length = valueBlockBuf.byteLength; - const lenBlockBuf = this.lenBlock.toBER(sizeOnly); - _writer.write(lenBlockBuf); - _writer.write(valueBlockBuf); - } - if (!writer) { - return _writer.final(); - } - return EMPTY_BUFFER; - } - toJSON() { - const object = { - ...super.toJSON(), - idBlock: this.idBlock.toJSON(), - lenBlock: this.lenBlock.toJSON(), - valueBlock: this.valueBlock.toJSON(), - name: this.name, - optional: this.optional - }; - if (this.primitiveSchema) - object.primitiveSchema = this.primitiveSchema.toJSON(); - return object; - } - toString(encoding = "ascii") { - if (encoding === "ascii") { - return this.onAsciiEncoding(); - } - return pvtsutils.Convert.ToHex(this.toBER()); - } - onAsciiEncoding() { - return `${this.constructor.NAME} : ${pvtsutils.Convert.ToHex(this.valueBlock.valueBeforeDecodeView)}`; - } - isEqual(other) { - if (this === other) { - return true; - } - if (!(other instanceof this.constructor)) { - return false; - } - const thisRaw = this.toBER(); - const otherRaw = other.toBER(); - return isEqualBuffer(thisRaw, otherRaw); - } - }; - BaseBlock.NAME = "BaseBlock"; - BaseStringBlock = class extends BaseBlock { - constructor({ value = EMPTY_STRING, ...parameters } = {}, stringValueBlockType) { - super(parameters, stringValueBlockType); - if (value) { - this.fromString(value); - } - } - getValue() { - return this.valueBlock.value; - } - setValue(value) { - this.valueBlock.value = value; - } - fromBER(inputBuffer, inputOffset, inputLength) { - const resultOffset = this.valueBlock.fromBER(inputBuffer, inputOffset, this.lenBlock.isIndefiniteForm ? inputLength : this.lenBlock.length); - if (resultOffset === -1) { - this.error = this.valueBlock.error; - return resultOffset; - } - this.fromBuffer(this.valueBlock.valueHexView); - if (!this.idBlock.error.length) - this.blockLength += this.idBlock.blockLength; - if (!this.lenBlock.error.length) - this.blockLength += this.lenBlock.blockLength; - if (!this.valueBlock.error.length) - this.blockLength += this.valueBlock.blockLength; - return resultOffset; - } - onAsciiEncoding() { - return `${this.constructor.NAME} : '${this.valueBlock.value}'`; - } - }; - BaseStringBlock.NAME = "BaseStringBlock"; - LocalPrimitiveValueBlock = class extends HexBlock(ValueBlock) { - constructor({ isHexOnly = true, ...parameters } = {}) { - super(parameters); - this.isHexOnly = isHexOnly; - } - }; - LocalPrimitiveValueBlock.NAME = "PrimitiveValueBlock"; - Primitive = class extends BaseBlock { - constructor(parameters = {}) { - super(parameters, LocalPrimitiveValueBlock); - this.idBlock.isConstructed = false; - } - }; - _a$w = Primitive; - (() => { - typeStore.Primitive = _a$w; - })(); - Primitive.NAME = "PRIMITIVE"; - LocalConstructedValueBlock = class extends ValueBlock { - constructor({ value = [], isIndefiniteForm = false, ...parameters } = {}) { - super(parameters); - this.value = value; - this.isIndefiniteForm = isIndefiniteForm; - } - fromBER(inputBuffer, inputOffset, inputLength) { - const view = pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer); - if (!checkBufferParams(this, view, inputOffset, inputLength)) { - return -1; - } - this.valueBeforeDecodeView = view.subarray(inputOffset, inputOffset + inputLength); - if (this.valueBeforeDecodeView.length === 0) { - this.warnings.push("Zero buffer length"); - return inputOffset; - } - let currentOffset = inputOffset; - while (checkLen(this.isIndefiniteForm, inputLength) > 0) { - const returnObject = localFromBER(view, currentOffset, inputLength); - if (returnObject.offset === -1) { - this.error = returnObject.result.error; - this.warnings.concat(returnObject.result.warnings); - return -1; - } - currentOffset = returnObject.offset; - this.blockLength += returnObject.result.blockLength; - inputLength -= returnObject.result.blockLength; - this.value.push(returnObject.result); - if (this.isIndefiniteForm && returnObject.result.constructor.NAME === END_OF_CONTENT_NAME) { - break; - } - } - if (this.isIndefiniteForm) { - if (this.value[this.value.length - 1].constructor.NAME === END_OF_CONTENT_NAME) { - this.value.pop(); - } else { - this.warnings.push("No EndOfContent block encoded"); - } - } - return currentOffset; - } - toBER(sizeOnly, writer) { - const _writer = writer || new ViewWriter(); - for (let i = 0; i < this.value.length; i++) { - this.value[i].toBER(sizeOnly, _writer); - } - if (!writer) { - return _writer.final(); - } - return EMPTY_BUFFER; - } - toJSON() { - const object = { - ...super.toJSON(), - isIndefiniteForm: this.isIndefiniteForm, - value: [] - }; - for (const value of this.value) { - object.value.push(value.toJSON()); - } - return object; - } - }; - LocalConstructedValueBlock.NAME = "ConstructedValueBlock"; - Constructed = class extends BaseBlock { - constructor(parameters = {}) { - super(parameters, LocalConstructedValueBlock); - this.idBlock.isConstructed = true; - } - fromBER(inputBuffer, inputOffset, inputLength) { - this.valueBlock.isIndefiniteForm = this.lenBlock.isIndefiniteForm; - const resultOffset = this.valueBlock.fromBER(inputBuffer, inputOffset, this.lenBlock.isIndefiniteForm ? inputLength : this.lenBlock.length); - if (resultOffset === -1) { - this.error = this.valueBlock.error; - return resultOffset; - } - if (!this.idBlock.error.length) - this.blockLength += this.idBlock.blockLength; - if (!this.lenBlock.error.length) - this.blockLength += this.lenBlock.blockLength; - if (!this.valueBlock.error.length) - this.blockLength += this.valueBlock.blockLength; - return resultOffset; - } - onAsciiEncoding() { - const values = []; - for (const value of this.valueBlock.value) { - values.push(value.toString("ascii").split("\n").map((o) => ` ${o}`).join("\n")); - } - const blockName = this.idBlock.tagClass === 3 ? `[${this.idBlock.tagNumber}]` : this.constructor.NAME; - return values.length ? `${blockName} : -${values.join("\n")}` : `${blockName} :`; - } - }; - _a$v = Constructed; - (() => { - typeStore.Constructed = _a$v; - })(); - Constructed.NAME = "CONSTRUCTED"; - LocalEndOfContentValueBlock = class extends ValueBlock { - fromBER(inputBuffer, inputOffset, inputLength) { - return inputOffset; - } - toBER(sizeOnly) { - return EMPTY_BUFFER; - } - }; - LocalEndOfContentValueBlock.override = "EndOfContentValueBlock"; - EndOfContent = class extends BaseBlock { - constructor(parameters = {}) { - super(parameters, LocalEndOfContentValueBlock); - this.idBlock.tagClass = 1; - this.idBlock.tagNumber = 0; - } - }; - _a$u = EndOfContent; - (() => { - typeStore.EndOfContent = _a$u; - })(); - EndOfContent.NAME = END_OF_CONTENT_NAME; - Null = class extends BaseBlock { - constructor(parameters = {}) { - super(parameters, ValueBlock); - this.idBlock.tagClass = 1; - this.idBlock.tagNumber = 5; - } - fromBER(inputBuffer, inputOffset, inputLength) { - if (this.lenBlock.length > 0) - this.warnings.push("Non-zero length of value block for Null type"); - if (!this.idBlock.error.length) - this.blockLength += this.idBlock.blockLength; - if (!this.lenBlock.error.length) - this.blockLength += this.lenBlock.blockLength; - this.blockLength += inputLength; - if (inputOffset + inputLength > inputBuffer.byteLength) { - this.error = "End of input reached before message was fully decoded (inconsistent offset and length values)"; - return -1; - } - return inputOffset + inputLength; - } - toBER(sizeOnly, writer) { - const retBuf = new ArrayBuffer(2); - if (!sizeOnly) { - const retView = new Uint8Array(retBuf); - retView[0] = 5; - retView[1] = 0; - } - if (writer) { - writer.write(retBuf); - } - return retBuf; - } - onAsciiEncoding() { - return `${this.constructor.NAME}`; - } - }; - _a$t = Null; - (() => { - typeStore.Null = _a$t; - })(); - Null.NAME = "NULL"; - LocalBooleanValueBlock = class extends HexBlock(ValueBlock) { - constructor({ value, ...parameters } = {}) { - super(parameters); - if (parameters.valueHex) { - this.valueHexView = pvtsutils.BufferSourceConverter.toUint8Array(parameters.valueHex); - } else { - this.valueHexView = new Uint8Array(1); - } - if (value) { - this.value = value; - } - } - get value() { - for (const octet of this.valueHexView) { - if (octet > 0) { - return true; - } - } - return false; - } - set value(value) { - this.valueHexView[0] = value ? 255 : 0; - } - fromBER(inputBuffer, inputOffset, inputLength) { - const inputView = pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer); - if (!checkBufferParams(this, inputView, inputOffset, inputLength)) { - return -1; - } - this.valueHexView = inputView.subarray(inputOffset, inputOffset + inputLength); - if (inputLength > 1) - this.warnings.push("Boolean value encoded in more then 1 octet"); - this.isHexOnly = true; - utilDecodeTC.call(this); - this.blockLength = inputLength; - return inputOffset + inputLength; - } - toBER() { - return this.valueHexView.slice(); - } - toJSON() { - return { - ...super.toJSON(), - value: this.value - }; - } - }; - LocalBooleanValueBlock.NAME = "BooleanValueBlock"; - Boolean2 = class extends BaseBlock { - constructor(parameters = {}) { - super(parameters, LocalBooleanValueBlock); - this.idBlock.tagClass = 1; - this.idBlock.tagNumber = 1; - } - getValue() { - return this.valueBlock.value; - } - setValue(value) { - this.valueBlock.value = value; - } - onAsciiEncoding() { - return `${this.constructor.NAME} : ${this.getValue}`; - } - }; - _a$s = Boolean2; - (() => { - typeStore.Boolean = _a$s; - })(); - Boolean2.NAME = "BOOLEAN"; - LocalOctetStringValueBlock = class extends HexBlock(LocalConstructedValueBlock) { - constructor({ isConstructed = false, ...parameters } = {}) { - super(parameters); - this.isConstructed = isConstructed; - } - fromBER(inputBuffer, inputOffset, inputLength) { - let resultOffset = 0; - if (this.isConstructed) { - this.isHexOnly = false; - resultOffset = LocalConstructedValueBlock.prototype.fromBER.call(this, inputBuffer, inputOffset, inputLength); - if (resultOffset === -1) - return resultOffset; - for (let i = 0; i < this.value.length; i++) { - const currentBlockName = this.value[i].constructor.NAME; - if (currentBlockName === END_OF_CONTENT_NAME) { - if (this.isIndefiniteForm) - break; - else { - this.error = "EndOfContent is unexpected, OCTET STRING may consists of OCTET STRINGs only"; - return -1; - } - } - if (currentBlockName !== OCTET_STRING_NAME) { - this.error = "OCTET STRING may consists of OCTET STRINGs only"; - return -1; - } - } - } else { - this.isHexOnly = true; - resultOffset = super.fromBER(inputBuffer, inputOffset, inputLength); - this.blockLength = inputLength; - } - return resultOffset; - } - toBER(sizeOnly, writer) { - if (this.isConstructed) - return LocalConstructedValueBlock.prototype.toBER.call(this, sizeOnly, writer); - return sizeOnly ? new ArrayBuffer(this.valueHexView.byteLength) : this.valueHexView.slice().buffer; - } - toJSON() { - return { - ...super.toJSON(), - isConstructed: this.isConstructed - }; - } - }; - LocalOctetStringValueBlock.NAME = "OctetStringValueBlock"; - OctetString = class extends BaseBlock { - constructor({ idBlock = {}, lenBlock = {}, ...parameters } = {}) { - var _b, _c; - (_b = parameters.isConstructed) !== null && _b !== void 0 ? _b : parameters.isConstructed = !!((_c = parameters.value) === null || _c === void 0 ? void 0 : _c.length); - super({ - idBlock: { - isConstructed: parameters.isConstructed, - ...idBlock - }, - lenBlock: { - ...lenBlock, - isIndefiniteForm: !!parameters.isIndefiniteForm - }, - ...parameters - }, LocalOctetStringValueBlock); - this.idBlock.tagClass = 1; - this.idBlock.tagNumber = 4; - } - fromBER(inputBuffer, inputOffset, inputLength) { - this.valueBlock.isConstructed = this.idBlock.isConstructed; - this.valueBlock.isIndefiniteForm = this.lenBlock.isIndefiniteForm; - if (inputLength === 0) { - if (this.idBlock.error.length === 0) - this.blockLength += this.idBlock.blockLength; - if (this.lenBlock.error.length === 0) - this.blockLength += this.lenBlock.blockLength; - return inputOffset; - } - if (!this.valueBlock.isConstructed) { - const view = inputBuffer instanceof ArrayBuffer ? new Uint8Array(inputBuffer) : inputBuffer; - const buf = view.subarray(inputOffset, inputOffset + inputLength); - try { - if (buf.byteLength) { - const asn = localFromBER(buf, 0, buf.byteLength); - if (asn.offset !== -1 && asn.offset === inputLength) { - this.valueBlock.value = [asn.result]; - } - } - } catch (e) { - } - } - return super.fromBER(inputBuffer, inputOffset, inputLength); - } - onAsciiEncoding() { - if (this.valueBlock.isConstructed || this.valueBlock.value && this.valueBlock.value.length) { - return Constructed.prototype.onAsciiEncoding.call(this); - } - return `${this.constructor.NAME} : ${pvtsutils.Convert.ToHex(this.valueBlock.valueHexView)}`; - } - getValue() { - if (!this.idBlock.isConstructed) { - return this.valueBlock.valueHexView.slice().buffer; - } - const array = []; - for (const content of this.valueBlock.value) { - if (content instanceof OctetString) { - array.push(content.valueBlock.valueHexView); - } - } - return pvtsutils.BufferSourceConverter.concat(array); - } - }; - _a$r = OctetString; - (() => { - typeStore.OctetString = _a$r; - })(); - OctetString.NAME = OCTET_STRING_NAME; - LocalBitStringValueBlock = class extends HexBlock(LocalConstructedValueBlock) { - constructor({ unusedBits = 0, isConstructed = false, ...parameters } = {}) { - super(parameters); - this.unusedBits = unusedBits; - this.isConstructed = isConstructed; - this.blockLength = this.valueHexView.byteLength; - } - fromBER(inputBuffer, inputOffset, inputLength) { - if (!inputLength) { - return inputOffset; - } - let resultOffset = -1; - if (this.isConstructed) { - resultOffset = LocalConstructedValueBlock.prototype.fromBER.call(this, inputBuffer, inputOffset, inputLength); - if (resultOffset === -1) - return resultOffset; - for (const value of this.value) { - const currentBlockName = value.constructor.NAME; - if (currentBlockName === END_OF_CONTENT_NAME) { - if (this.isIndefiniteForm) - break; - else { - this.error = "EndOfContent is unexpected, BIT STRING may consists of BIT STRINGs only"; - return -1; - } - } - if (currentBlockName !== BIT_STRING_NAME) { - this.error = "BIT STRING may consists of BIT STRINGs only"; - return -1; - } - const valueBlock = value.valueBlock; - if (this.unusedBits > 0 && valueBlock.unusedBits > 0) { - this.error = 'Using of "unused bits" inside constructive BIT STRING allowed for least one only'; - return -1; - } - this.unusedBits = valueBlock.unusedBits; - } - return resultOffset; - } - const inputView = pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer); - if (!checkBufferParams(this, inputView, inputOffset, inputLength)) { - return -1; - } - const intBuffer = inputView.subarray(inputOffset, inputOffset + inputLength); - this.unusedBits = intBuffer[0]; - if (this.unusedBits > 7) { - this.error = "Unused bits for BitString must be in range 0-7"; - return -1; - } - if (!this.unusedBits) { - const buf = intBuffer.subarray(1); - try { - if (buf.byteLength) { - const asn = localFromBER(buf, 0, buf.byteLength); - if (asn.offset !== -1 && asn.offset === inputLength - 1) { - this.value = [asn.result]; - } - } - } catch (e) { - } - } - this.valueHexView = intBuffer.subarray(1); - this.blockLength = intBuffer.length; - return inputOffset + inputLength; - } - toBER(sizeOnly, writer) { - if (this.isConstructed) { - return LocalConstructedValueBlock.prototype.toBER.call(this, sizeOnly, writer); - } - if (sizeOnly) { - return new ArrayBuffer(this.valueHexView.byteLength + 1); - } - if (!this.valueHexView.byteLength) { - return EMPTY_BUFFER; - } - const retView = new Uint8Array(this.valueHexView.length + 1); - retView[0] = this.unusedBits; - retView.set(this.valueHexView, 1); - return retView.buffer; - } - toJSON() { - return { - ...super.toJSON(), - unusedBits: this.unusedBits, - isConstructed: this.isConstructed - }; - } - }; - LocalBitStringValueBlock.NAME = "BitStringValueBlock"; - BitString = class extends BaseBlock { - constructor({ idBlock = {}, lenBlock = {}, ...parameters } = {}) { - var _b, _c; - (_b = parameters.isConstructed) !== null && _b !== void 0 ? _b : parameters.isConstructed = !!((_c = parameters.value) === null || _c === void 0 ? void 0 : _c.length); - super({ - idBlock: { - isConstructed: parameters.isConstructed, - ...idBlock - }, - lenBlock: { - ...lenBlock, - isIndefiniteForm: !!parameters.isIndefiniteForm - }, - ...parameters - }, LocalBitStringValueBlock); - this.idBlock.tagClass = 1; - this.idBlock.tagNumber = 3; - } - fromBER(inputBuffer, inputOffset, inputLength) { - this.valueBlock.isConstructed = this.idBlock.isConstructed; - this.valueBlock.isIndefiniteForm = this.lenBlock.isIndefiniteForm; - return super.fromBER(inputBuffer, inputOffset, inputLength); - } - onAsciiEncoding() { - if (this.valueBlock.isConstructed || this.valueBlock.value && this.valueBlock.value.length) { - return Constructed.prototype.onAsciiEncoding.call(this); - } else { - const bits = []; - const valueHex = this.valueBlock.valueHexView; - for (const byte of valueHex) { - bits.push(byte.toString(2).padStart(8, "0")); - } - const bitsStr = bits.join(""); - return `${this.constructor.NAME} : ${bitsStr.substring(0, bitsStr.length - this.valueBlock.unusedBits)}`; - } - } - }; - _a$q = BitString; - (() => { - typeStore.BitString = _a$q; - })(); - BitString.NAME = BIT_STRING_NAME; - LocalIntegerValueBlock = class extends HexBlock(ValueBlock) { - constructor({ value, ...parameters } = {}) { - super(parameters); - this._valueDec = 0; - if (parameters.valueHex) { - this.setValueHex(); - } - if (value !== void 0) { - this.valueDec = value; - } - } - setValueHex() { - if (this.valueHexView.length >= 4) { - this.warnings.push("Too big Integer for decoding, hex only"); - this.isHexOnly = true; - this._valueDec = 0; - } else { - this.isHexOnly = false; - if (this.valueHexView.length > 0) { - this._valueDec = utilDecodeTC.call(this); - } - } - } - set valueDec(v) { - this._valueDec = v; - this.isHexOnly = false; - this.valueHexView = new Uint8Array(utilEncodeTC(v)); - } - get valueDec() { - return this._valueDec; - } - fromDER(inputBuffer, inputOffset, inputLength, expectedLength = 0) { - const offset = this.fromBER(inputBuffer, inputOffset, inputLength); - if (offset === -1) - return offset; - const view = this.valueHexView; - if (view[0] === 0 && (view[1] & 128) !== 0) { - this.valueHexView = view.subarray(1); - } else { - if (expectedLength !== 0) { - if (view.length < expectedLength) { - if (expectedLength - view.length > 1) - expectedLength = view.length + 1; - this.valueHexView = view.subarray(expectedLength - view.length); - } - } - } - return offset; - } - toDER(sizeOnly = false) { - const view = this.valueHexView; - switch (true) { - case (view[0] & 128) !== 0: - { - const updatedView = new Uint8Array(this.valueHexView.length + 1); - updatedView[0] = 0; - updatedView.set(view, 1); - this.valueHexView = updatedView; - } - break; - case (view[0] === 0 && (view[1] & 128) === 0): - { - this.valueHexView = this.valueHexView.subarray(1); - } - break; - } - return this.toBER(sizeOnly); - } - fromBER(inputBuffer, inputOffset, inputLength) { - const resultOffset = super.fromBER(inputBuffer, inputOffset, inputLength); - if (resultOffset === -1) { - return resultOffset; - } - this.setValueHex(); - return resultOffset; - } - toBER(sizeOnly) { - return sizeOnly ? new ArrayBuffer(this.valueHexView.length) : this.valueHexView.slice().buffer; - } - toJSON() { - return { - ...super.toJSON(), - valueDec: this.valueDec - }; - } - toString() { - const firstBit = this.valueHexView.length * 8 - 1; - let digits = new Uint8Array(this.valueHexView.length * 8 / 3); - let bitNumber = 0; - let currentByte; - const asn1View = this.valueHexView; - let result = ""; - let flag = false; - for (let byteNumber = asn1View.byteLength - 1; byteNumber >= 0; byteNumber--) { - currentByte = asn1View[byteNumber]; - for (let i = 0; i < 8; i++) { - if ((currentByte & 1) === 1) { - switch (bitNumber) { - case firstBit: - digits = viewSub(power2(bitNumber), digits); - result = "-"; - break; - default: - digits = viewAdd(digits, power2(bitNumber)); - } - } - bitNumber++; - currentByte >>= 1; - } - } - for (let i = 0; i < digits.length; i++) { - if (digits[i]) - flag = true; - if (flag) - result += digitsString.charAt(digits[i]); - } - if (flag === false) - result += digitsString.charAt(0); - return result; - } - }; - _a$p = LocalIntegerValueBlock; - LocalIntegerValueBlock.NAME = "IntegerValueBlock"; - (() => { - Object.defineProperty(_a$p.prototype, "valueHex", { - set: function(v) { - this.valueHexView = new Uint8Array(v); - this.setValueHex(); - }, - get: function() { - return this.valueHexView.slice().buffer; - } - }); - })(); - Integer = class extends BaseBlock { - constructor(parameters = {}) { - super(parameters, LocalIntegerValueBlock); - this.idBlock.tagClass = 1; - this.idBlock.tagNumber = 2; - } - toBigInt() { - assertBigInt(); - return BigInt(this.valueBlock.toString()); - } - static fromBigInt(value) { - assertBigInt(); - const bigIntValue = BigInt(value); - const writer = new ViewWriter(); - const hex = bigIntValue.toString(16).replace(/^-/, ""); - const view = new Uint8Array(pvtsutils.Convert.FromHex(hex)); - if (bigIntValue < 0) { - const first = new Uint8Array(view.length + (view[0] & 128 ? 1 : 0)); - first[0] |= 128; - const firstInt = BigInt(`0x${pvtsutils.Convert.ToHex(first)}`); - const secondInt = firstInt + bigIntValue; - const second = pvtsutils.BufferSourceConverter.toUint8Array(pvtsutils.Convert.FromHex(secondInt.toString(16))); - second[0] |= 128; - writer.write(second); - } else { - if (view[0] & 128) { - writer.write(new Uint8Array([0])); - } - writer.write(view); - } - const res = new Integer({ - valueHex: writer.final() - }); - return res; - } - convertToDER() { - const integer = new Integer({ valueHex: this.valueBlock.valueHexView }); - integer.valueBlock.toDER(); - return integer; - } - convertFromDER() { - return new Integer({ - valueHex: this.valueBlock.valueHexView[0] === 0 ? this.valueBlock.valueHexView.subarray(1) : this.valueBlock.valueHexView - }); - } - onAsciiEncoding() { - return `${this.constructor.NAME} : ${this.valueBlock.toString()}`; - } - }; - _a$o = Integer; - (() => { - typeStore.Integer = _a$o; - })(); - Integer.NAME = "INTEGER"; - Enumerated = class extends Integer { - constructor(parameters = {}) { - super(parameters); - this.idBlock.tagClass = 1; - this.idBlock.tagNumber = 10; - } - }; - _a$n = Enumerated; - (() => { - typeStore.Enumerated = _a$n; - })(); - Enumerated.NAME = "ENUMERATED"; - LocalSidValueBlock = class extends HexBlock(ValueBlock) { - constructor({ valueDec = -1, isFirstSid = false, ...parameters } = {}) { - super(parameters); - this.valueDec = valueDec; - this.isFirstSid = isFirstSid; - } - fromBER(inputBuffer, inputOffset, inputLength) { - if (!inputLength) { - return inputOffset; - } - const inputView = pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer); - if (!checkBufferParams(this, inputView, inputOffset, inputLength)) { - return -1; - } - const intBuffer = inputView.subarray(inputOffset, inputOffset + inputLength); - this.valueHexView = new Uint8Array(inputLength); - for (let i = 0; i < inputLength; i++) { - this.valueHexView[i] = intBuffer[i] & 127; - this.blockLength++; - if ((intBuffer[i] & 128) === 0) - break; - } - const tempView = new Uint8Array(this.blockLength); - for (let i = 0; i < this.blockLength; i++) { - tempView[i] = this.valueHexView[i]; - } - this.valueHexView = tempView; - if ((intBuffer[this.blockLength - 1] & 128) !== 0) { - this.error = "End of input reached before message was fully decoded"; - return -1; - } - if (this.valueHexView[0] === 0) - this.warnings.push("Needlessly long format of SID encoding"); - if (this.blockLength <= 8) - this.valueDec = utilFromBase(this.valueHexView, 7); - else { - this.isHexOnly = true; - this.warnings.push("Too big SID for decoding, hex only"); - } - return inputOffset + this.blockLength; - } - set valueBigInt(value) { - assertBigInt(); - let bits = BigInt(value).toString(2); - while (bits.length % 7) { - bits = "0" + bits; - } - const bytes = new Uint8Array(bits.length / 7); - for (let i = 0; i < bytes.length; i++) { - bytes[i] = parseInt(bits.slice(i * 7, i * 7 + 7), 2) + (i + 1 < bytes.length ? 128 : 0); - } - this.fromBER(bytes.buffer, 0, bytes.length); - } - toBER(sizeOnly) { - if (this.isHexOnly) { - if (sizeOnly) - return new ArrayBuffer(this.valueHexView.byteLength); - const curView = this.valueHexView; - const retView2 = new Uint8Array(this.blockLength); - for (let i = 0; i < this.blockLength - 1; i++) - retView2[i] = curView[i] | 128; - retView2[this.blockLength - 1] = curView[this.blockLength - 1]; - return retView2.buffer; - } - const encodedBuf = utilToBase(this.valueDec, 7); - if (encodedBuf.byteLength === 0) { - this.error = "Error during encoding SID value"; - return EMPTY_BUFFER; - } - const retView = new Uint8Array(encodedBuf.byteLength); - if (!sizeOnly) { - const encodedView = new Uint8Array(encodedBuf); - const len = encodedBuf.byteLength - 1; - for (let i = 0; i < len; i++) - retView[i] = encodedView[i] | 128; - retView[len] = encodedView[len]; - } - return retView; - } - toString() { - let result = ""; - if (this.isHexOnly) - result = pvtsutils.Convert.ToHex(this.valueHexView); - else { - if (this.isFirstSid) { - let sidValue = this.valueDec; - if (this.valueDec <= 39) - result = "0."; - else { - if (this.valueDec <= 79) { - result = "1."; - sidValue -= 40; - } else { - result = "2."; - sidValue -= 80; - } - } - result += sidValue.toString(); - } else - result = this.valueDec.toString(); - } - return result; - } - toJSON() { - return { - ...super.toJSON(), - valueDec: this.valueDec, - isFirstSid: this.isFirstSid - }; - } - }; - LocalSidValueBlock.NAME = "sidBlock"; - LocalObjectIdentifierValueBlock = class extends ValueBlock { - constructor({ value = EMPTY_STRING, ...parameters } = {}) { - super(parameters); - this.value = []; - if (value) { - this.fromString(value); - } - } - fromBER(inputBuffer, inputOffset, inputLength) { - let resultOffset = inputOffset; - while (inputLength > 0) { - const sidBlock = new LocalSidValueBlock(); - resultOffset = sidBlock.fromBER(inputBuffer, resultOffset, inputLength); - if (resultOffset === -1) { - this.blockLength = 0; - this.error = sidBlock.error; - return resultOffset; - } - if (this.value.length === 0) - sidBlock.isFirstSid = true; - this.blockLength += sidBlock.blockLength; - inputLength -= sidBlock.blockLength; - this.value.push(sidBlock); - } - return resultOffset; - } - toBER(sizeOnly) { - const retBuffers = []; - for (let i = 0; i < this.value.length; i++) { - const valueBuf = this.value[i].toBER(sizeOnly); - if (valueBuf.byteLength === 0) { - this.error = this.value[i].error; - return EMPTY_BUFFER; - } - retBuffers.push(valueBuf); - } - return concat(retBuffers); - } - fromString(string) { - this.value = []; - let pos1 = 0; - let pos2 = 0; - let sid = ""; - let flag = false; - do { - pos2 = string.indexOf(".", pos1); - if (pos2 === -1) - sid = string.substring(pos1); - else - sid = string.substring(pos1, pos2); - pos1 = pos2 + 1; - if (flag) { - const sidBlock = this.value[0]; - let plus = 0; - switch (sidBlock.valueDec) { - case 0: - break; - case 1: - plus = 40; - break; - case 2: - plus = 80; - break; - default: - this.value = []; - return; - } - const parsedSID = parseInt(sid, 10); - if (isNaN(parsedSID)) - return; - sidBlock.valueDec = parsedSID + plus; - flag = false; - } else { - const sidBlock = new LocalSidValueBlock(); - if (sid > Number.MAX_SAFE_INTEGER) { - assertBigInt(); - const sidValue = BigInt(sid); - sidBlock.valueBigInt = sidValue; - } else { - sidBlock.valueDec = parseInt(sid, 10); - if (isNaN(sidBlock.valueDec)) - return; - } - if (!this.value.length) { - sidBlock.isFirstSid = true; - flag = true; - } - this.value.push(sidBlock); - } - } while (pos2 !== -1); - } - toString() { - let result = ""; - let isHexOnly = false; - for (let i = 0; i < this.value.length; i++) { - isHexOnly = this.value[i].isHexOnly; - let sidStr = this.value[i].toString(); - if (i !== 0) - result = `${result}.`; - if (isHexOnly) { - sidStr = `{${sidStr}}`; - if (this.value[i].isFirstSid) - result = `2.{${sidStr} - 80}`; - else - result += sidStr; - } else - result += sidStr; - } - return result; - } - toJSON() { - const object = { - ...super.toJSON(), - value: this.toString(), - sidArray: [] - }; - for (let i = 0; i < this.value.length; i++) { - object.sidArray.push(this.value[i].toJSON()); - } - return object; - } - }; - LocalObjectIdentifierValueBlock.NAME = "ObjectIdentifierValueBlock"; - ObjectIdentifier = class extends BaseBlock { - constructor(parameters = {}) { - super(parameters, LocalObjectIdentifierValueBlock); - this.idBlock.tagClass = 1; - this.idBlock.tagNumber = 6; - } - getValue() { - return this.valueBlock.toString(); - } - setValue(value) { - this.valueBlock.fromString(value); - } - onAsciiEncoding() { - return `${this.constructor.NAME} : ${this.valueBlock.toString() || "empty"}`; - } - toJSON() { - return { - ...super.toJSON(), - value: this.getValue() - }; - } - }; - _a$m = ObjectIdentifier; - (() => { - typeStore.ObjectIdentifier = _a$m; - })(); - ObjectIdentifier.NAME = "OBJECT IDENTIFIER"; - LocalRelativeSidValueBlock = class extends HexBlock(LocalBaseBlock) { - constructor({ valueDec = 0, ...parameters } = {}) { - super(parameters); - this.valueDec = valueDec; - } - fromBER(inputBuffer, inputOffset, inputLength) { - if (inputLength === 0) - return inputOffset; - const inputView = pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer); - if (!checkBufferParams(this, inputView, inputOffset, inputLength)) - return -1; - const intBuffer = inputView.subarray(inputOffset, inputOffset + inputLength); - this.valueHexView = new Uint8Array(inputLength); - for (let i = 0; i < inputLength; i++) { - this.valueHexView[i] = intBuffer[i] & 127; - this.blockLength++; - if ((intBuffer[i] & 128) === 0) - break; - } - const tempView = new Uint8Array(this.blockLength); - for (let i = 0; i < this.blockLength; i++) - tempView[i] = this.valueHexView[i]; - this.valueHexView = tempView; - if ((intBuffer[this.blockLength - 1] & 128) !== 0) { - this.error = "End of input reached before message was fully decoded"; - return -1; - } - if (this.valueHexView[0] === 0) - this.warnings.push("Needlessly long format of SID encoding"); - if (this.blockLength <= 8) - this.valueDec = utilFromBase(this.valueHexView, 7); - else { - this.isHexOnly = true; - this.warnings.push("Too big SID for decoding, hex only"); - } - return inputOffset + this.blockLength; - } - toBER(sizeOnly) { - if (this.isHexOnly) { - if (sizeOnly) - return new ArrayBuffer(this.valueHexView.byteLength); - const curView = this.valueHexView; - const retView2 = new Uint8Array(this.blockLength); - for (let i = 0; i < this.blockLength - 1; i++) - retView2[i] = curView[i] | 128; - retView2[this.blockLength - 1] = curView[this.blockLength - 1]; - return retView2.buffer; - } - const encodedBuf = utilToBase(this.valueDec, 7); - if (encodedBuf.byteLength === 0) { - this.error = "Error during encoding SID value"; - return EMPTY_BUFFER; - } - const retView = new Uint8Array(encodedBuf.byteLength); - if (!sizeOnly) { - const encodedView = new Uint8Array(encodedBuf); - const len = encodedBuf.byteLength - 1; - for (let i = 0; i < len; i++) - retView[i] = encodedView[i] | 128; - retView[len] = encodedView[len]; - } - return retView.buffer; - } - toString() { - let result = ""; - if (this.isHexOnly) - result = pvtsutils.Convert.ToHex(this.valueHexView); - else { - result = this.valueDec.toString(); - } - return result; - } - toJSON() { - return { - ...super.toJSON(), - valueDec: this.valueDec - }; - } - }; - LocalRelativeSidValueBlock.NAME = "relativeSidBlock"; - LocalRelativeObjectIdentifierValueBlock = class extends ValueBlock { - constructor({ value = EMPTY_STRING, ...parameters } = {}) { - super(parameters); - this.value = []; - if (value) { - this.fromString(value); - } - } - fromBER(inputBuffer, inputOffset, inputLength) { - let resultOffset = inputOffset; - while (inputLength > 0) { - const sidBlock = new LocalRelativeSidValueBlock(); - resultOffset = sidBlock.fromBER(inputBuffer, resultOffset, inputLength); - if (resultOffset === -1) { - this.blockLength = 0; - this.error = sidBlock.error; - return resultOffset; - } - this.blockLength += sidBlock.blockLength; - inputLength -= sidBlock.blockLength; - this.value.push(sidBlock); - } - return resultOffset; - } - toBER(sizeOnly, writer) { - const retBuffers = []; - for (let i = 0; i < this.value.length; i++) { - const valueBuf = this.value[i].toBER(sizeOnly); - if (valueBuf.byteLength === 0) { - this.error = this.value[i].error; - return EMPTY_BUFFER; - } - retBuffers.push(valueBuf); - } - return concat(retBuffers); - } - fromString(string) { - this.value = []; - let pos1 = 0; - let pos2 = 0; - let sid = ""; - do { - pos2 = string.indexOf(".", pos1); - if (pos2 === -1) - sid = string.substring(pos1); - else - sid = string.substring(pos1, pos2); - pos1 = pos2 + 1; - const sidBlock = new LocalRelativeSidValueBlock(); - sidBlock.valueDec = parseInt(sid, 10); - if (isNaN(sidBlock.valueDec)) - return true; - this.value.push(sidBlock); - } while (pos2 !== -1); - return true; - } - toString() { - let result = ""; - let isHexOnly = false; - for (let i = 0; i < this.value.length; i++) { - isHexOnly = this.value[i].isHexOnly; - let sidStr = this.value[i].toString(); - if (i !== 0) - result = `${result}.`; - if (isHexOnly) { - sidStr = `{${sidStr}}`; - result += sidStr; - } else - result += sidStr; - } - return result; - } - toJSON() { - const object = { - ...super.toJSON(), - value: this.toString(), - sidArray: [] - }; - for (let i = 0; i < this.value.length; i++) - object.sidArray.push(this.value[i].toJSON()); - return object; - } - }; - LocalRelativeObjectIdentifierValueBlock.NAME = "RelativeObjectIdentifierValueBlock"; - RelativeObjectIdentifier = class extends BaseBlock { - constructor(parameters = {}) { - super(parameters, LocalRelativeObjectIdentifierValueBlock); - this.idBlock.tagClass = 1; - this.idBlock.tagNumber = 13; - } - getValue() { - return this.valueBlock.toString(); - } - setValue(value) { - this.valueBlock.fromString(value); - } - onAsciiEncoding() { - return `${this.constructor.NAME} : ${this.valueBlock.toString() || "empty"}`; - } - toJSON() { - return { - ...super.toJSON(), - value: this.getValue() - }; - } - }; - _a$l = RelativeObjectIdentifier; - (() => { - typeStore.RelativeObjectIdentifier = _a$l; - })(); - RelativeObjectIdentifier.NAME = "RelativeObjectIdentifier"; - Sequence = class extends Constructed { - constructor(parameters = {}) { - super(parameters); - this.idBlock.tagClass = 1; - this.idBlock.tagNumber = 16; - } - }; - _a$k = Sequence; - (() => { - typeStore.Sequence = _a$k; - })(); - Sequence.NAME = "SEQUENCE"; - Set2 = class extends Constructed { - constructor(parameters = {}) { - super(parameters); - this.idBlock.tagClass = 1; - this.idBlock.tagNumber = 17; - } - }; - _a$j = Set2; - (() => { - typeStore.Set = _a$j; - })(); - Set2.NAME = "SET"; - LocalStringValueBlock = class extends HexBlock(ValueBlock) { - constructor({ ...parameters } = {}) { - super(parameters); - this.isHexOnly = true; - this.value = EMPTY_STRING; - } - toJSON() { - return { - ...super.toJSON(), - value: this.value - }; - } - }; - LocalStringValueBlock.NAME = "StringValueBlock"; - LocalSimpleStringValueBlock = class extends LocalStringValueBlock { - }; - LocalSimpleStringValueBlock.NAME = "SimpleStringValueBlock"; - LocalSimpleStringBlock = class extends BaseStringBlock { - constructor({ ...parameters } = {}) { - super(parameters, LocalSimpleStringValueBlock); - } - fromBuffer(inputBuffer) { - this.valueBlock.value = String.fromCharCode.apply(null, pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer)); - } - fromString(inputString) { - const strLen = inputString.length; - const view = this.valueBlock.valueHexView = new Uint8Array(strLen); - for (let i = 0; i < strLen; i++) - view[i] = inputString.charCodeAt(i); - this.valueBlock.value = inputString; - } - }; - LocalSimpleStringBlock.NAME = "SIMPLE STRING"; - LocalUtf8StringValueBlock = class extends LocalSimpleStringBlock { - fromBuffer(inputBuffer) { - this.valueBlock.valueHexView = pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer); - try { - this.valueBlock.value = pvtsutils.Convert.ToUtf8String(inputBuffer); - } catch (ex) { - this.warnings.push(`Error during "decodeURIComponent": ${ex}, using raw string`); - this.valueBlock.value = pvtsutils.Convert.ToBinary(inputBuffer); - } - } - fromString(inputString) { - this.valueBlock.valueHexView = new Uint8Array(pvtsutils.Convert.FromUtf8String(inputString)); - this.valueBlock.value = inputString; - } - }; - LocalUtf8StringValueBlock.NAME = "Utf8StringValueBlock"; - Utf8String = class extends LocalUtf8StringValueBlock { - constructor(parameters = {}) { - super(parameters); - this.idBlock.tagClass = 1; - this.idBlock.tagNumber = 12; - } - }; - _a$i = Utf8String; - (() => { - typeStore.Utf8String = _a$i; - })(); - Utf8String.NAME = "UTF8String"; - LocalBmpStringValueBlock = class extends LocalSimpleStringBlock { - fromBuffer(inputBuffer) { - this.valueBlock.value = pvtsutils.Convert.ToUtf16String(inputBuffer); - this.valueBlock.valueHexView = pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer); - } - fromString(inputString) { - this.valueBlock.value = inputString; - this.valueBlock.valueHexView = new Uint8Array(pvtsutils.Convert.FromUtf16String(inputString)); - } - }; - LocalBmpStringValueBlock.NAME = "BmpStringValueBlock"; - BmpString = class extends LocalBmpStringValueBlock { - constructor({ ...parameters } = {}) { - super(parameters); - this.idBlock.tagClass = 1; - this.idBlock.tagNumber = 30; - } - }; - _a$h = BmpString; - (() => { - typeStore.BmpString = _a$h; - })(); - BmpString.NAME = "BMPString"; - LocalUniversalStringValueBlock = class extends LocalSimpleStringBlock { - fromBuffer(inputBuffer) { - const copyBuffer = ArrayBuffer.isView(inputBuffer) ? inputBuffer.slice().buffer : inputBuffer.slice(0); - const valueView = new Uint8Array(copyBuffer); - for (let i = 0; i < valueView.length; i += 4) { - valueView[i] = valueView[i + 3]; - valueView[i + 1] = valueView[i + 2]; - valueView[i + 2] = 0; - valueView[i + 3] = 0; - } - this.valueBlock.value = String.fromCharCode.apply(null, new Uint32Array(copyBuffer)); - } - fromString(inputString) { - const strLength = inputString.length; - const valueHexView = this.valueBlock.valueHexView = new Uint8Array(strLength * 4); - for (let i = 0; i < strLength; i++) { - const codeBuf = utilToBase(inputString.charCodeAt(i), 8); - const codeView = new Uint8Array(codeBuf); - if (codeView.length > 4) - continue; - const dif = 4 - codeView.length; - for (let j = codeView.length - 1; j >= 0; j--) - valueHexView[i * 4 + j + dif] = codeView[j]; - } - this.valueBlock.value = inputString; - } - }; - LocalUniversalStringValueBlock.NAME = "UniversalStringValueBlock"; - UniversalString = class extends LocalUniversalStringValueBlock { - constructor({ ...parameters } = {}) { - super(parameters); - this.idBlock.tagClass = 1; - this.idBlock.tagNumber = 28; - } - }; - _a$g = UniversalString; - (() => { - typeStore.UniversalString = _a$g; - })(); - UniversalString.NAME = "UniversalString"; - NumericString = class extends LocalSimpleStringBlock { - constructor(parameters = {}) { - super(parameters); - this.idBlock.tagClass = 1; - this.idBlock.tagNumber = 18; - } - }; - _a$f = NumericString; - (() => { - typeStore.NumericString = _a$f; - })(); - NumericString.NAME = "NumericString"; - PrintableString = class extends LocalSimpleStringBlock { - constructor(parameters = {}) { - super(parameters); - this.idBlock.tagClass = 1; - this.idBlock.tagNumber = 19; - } - }; - _a$e = PrintableString; - (() => { - typeStore.PrintableString = _a$e; - })(); - PrintableString.NAME = "PrintableString"; - TeletexString = class extends LocalSimpleStringBlock { - constructor(parameters = {}) { - super(parameters); - this.idBlock.tagClass = 1; - this.idBlock.tagNumber = 20; - } - }; - _a$d = TeletexString; - (() => { - typeStore.TeletexString = _a$d; - })(); - TeletexString.NAME = "TeletexString"; - VideotexString = class extends LocalSimpleStringBlock { - constructor(parameters = {}) { - super(parameters); - this.idBlock.tagClass = 1; - this.idBlock.tagNumber = 21; - } - }; - _a$c = VideotexString; - (() => { - typeStore.VideotexString = _a$c; - })(); - VideotexString.NAME = "VideotexString"; - IA5String = class extends LocalSimpleStringBlock { - constructor(parameters = {}) { - super(parameters); - this.idBlock.tagClass = 1; - this.idBlock.tagNumber = 22; - } - }; - _a$b = IA5String; - (() => { - typeStore.IA5String = _a$b; - })(); - IA5String.NAME = "IA5String"; - GraphicString = class extends LocalSimpleStringBlock { - constructor(parameters = {}) { - super(parameters); - this.idBlock.tagClass = 1; - this.idBlock.tagNumber = 25; - } - }; - _a$a = GraphicString; - (() => { - typeStore.GraphicString = _a$a; - })(); - GraphicString.NAME = "GraphicString"; - VisibleString = class extends LocalSimpleStringBlock { - constructor(parameters = {}) { - super(parameters); - this.idBlock.tagClass = 1; - this.idBlock.tagNumber = 26; - } - }; - _a$9 = VisibleString; - (() => { - typeStore.VisibleString = _a$9; - })(); - VisibleString.NAME = "VisibleString"; - GeneralString = class extends LocalSimpleStringBlock { - constructor(parameters = {}) { - super(parameters); - this.idBlock.tagClass = 1; - this.idBlock.tagNumber = 27; - } - }; - _a$8 = GeneralString; - (() => { - typeStore.GeneralString = _a$8; - })(); - GeneralString.NAME = "GeneralString"; - CharacterString = class extends LocalSimpleStringBlock { - constructor(parameters = {}) { - super(parameters); - this.idBlock.tagClass = 1; - this.idBlock.tagNumber = 29; - } - }; - _a$7 = CharacterString; - (() => { - typeStore.CharacterString = _a$7; - })(); - CharacterString.NAME = "CharacterString"; - UTCTime = class extends VisibleString { - constructor({ value, valueDate, ...parameters } = {}) { - super(parameters); - this.year = 0; - this.month = 0; - this.day = 0; - this.hour = 0; - this.minute = 0; - this.second = 0; - if (value) { - this.fromString(value); - this.valueBlock.valueHexView = new Uint8Array(value.length); - for (let i = 0; i < value.length; i++) - this.valueBlock.valueHexView[i] = value.charCodeAt(i); - } - if (valueDate) { - this.fromDate(valueDate); - this.valueBlock.valueHexView = new Uint8Array(this.toBuffer()); - } - this.idBlock.tagClass = 1; - this.idBlock.tagNumber = 23; - } - fromBuffer(inputBuffer) { - this.fromString(String.fromCharCode.apply(null, pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer))); - } - toBuffer() { - const str = this.toString(); - const buffer = new ArrayBuffer(str.length); - const view = new Uint8Array(buffer); - for (let i = 0; i < str.length; i++) - view[i] = str.charCodeAt(i); - return buffer; - } - fromDate(inputDate) { - this.year = inputDate.getUTCFullYear(); - this.month = inputDate.getUTCMonth() + 1; - this.day = inputDate.getUTCDate(); - this.hour = inputDate.getUTCHours(); - this.minute = inputDate.getUTCMinutes(); - this.second = inputDate.getUTCSeconds(); - } - toDate() { - return new Date(Date.UTC(this.year, this.month - 1, this.day, this.hour, this.minute, this.second)); - } - fromString(inputString) { - const parser = /(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})Z/ig; - const parserArray = parser.exec(inputString); - if (parserArray === null) { - this.error = "Wrong input string for conversion"; - return; - } - const year = parseInt(parserArray[1], 10); - if (year >= 50) - this.year = 1900 + year; - else - this.year = 2e3 + year; - this.month = parseInt(parserArray[2], 10); - this.day = parseInt(parserArray[3], 10); - this.hour = parseInt(parserArray[4], 10); - this.minute = parseInt(parserArray[5], 10); - this.second = parseInt(parserArray[6], 10); - } - toString(encoding = "iso") { - if (encoding === "iso") { - const outputArray = new Array(7); - outputArray[0] = padNumber(this.year < 2e3 ? this.year - 1900 : this.year - 2e3, 2); - outputArray[1] = padNumber(this.month, 2); - outputArray[2] = padNumber(this.day, 2); - outputArray[3] = padNumber(this.hour, 2); - outputArray[4] = padNumber(this.minute, 2); - outputArray[5] = padNumber(this.second, 2); - outputArray[6] = "Z"; - return outputArray.join(""); - } - return super.toString(encoding); - } - onAsciiEncoding() { - return `${this.constructor.NAME} : ${this.toDate().toISOString()}`; - } - toJSON() { - return { - ...super.toJSON(), - year: this.year, - month: this.month, - day: this.day, - hour: this.hour, - minute: this.minute, - second: this.second - }; - } - }; - _a$6 = UTCTime; - (() => { - typeStore.UTCTime = _a$6; - })(); - UTCTime.NAME = "UTCTime"; - GeneralizedTime = class extends UTCTime { - constructor(parameters = {}) { - var _b; - super(parameters); - (_b = this.millisecond) !== null && _b !== void 0 ? _b : this.millisecond = 0; - this.idBlock.tagClass = 1; - this.idBlock.tagNumber = 24; - } - fromDate(inputDate) { - super.fromDate(inputDate); - this.millisecond = inputDate.getUTCMilliseconds(); - } - toDate() { - return new Date(Date.UTC(this.year, this.month - 1, this.day, this.hour, this.minute, this.second, this.millisecond)); - } - fromString(inputString) { - let isUTC = false; - let timeString = ""; - let dateTimeString = ""; - let fractionPart = 0; - let parser; - let hourDifference = 0; - let minuteDifference = 0; - if (inputString[inputString.length - 1] === "Z") { - timeString = inputString.substring(0, inputString.length - 1); - isUTC = true; - } else { - const number = new Number(inputString[inputString.length - 1]); - if (isNaN(number.valueOf())) - throw new Error("Wrong input string for conversion"); - timeString = inputString; - } - if (isUTC) { - if (timeString.indexOf("+") !== -1) - throw new Error("Wrong input string for conversion"); - if (timeString.indexOf("-") !== -1) - throw new Error("Wrong input string for conversion"); - } else { - let multiplier = 1; - let differencePosition = timeString.indexOf("+"); - let differenceString = ""; - if (differencePosition === -1) { - differencePosition = timeString.indexOf("-"); - multiplier = -1; - } - if (differencePosition !== -1) { - differenceString = timeString.substring(differencePosition + 1); - timeString = timeString.substring(0, differencePosition); - if (differenceString.length !== 2 && differenceString.length !== 4) - throw new Error("Wrong input string for conversion"); - let number = parseInt(differenceString.substring(0, 2), 10); - if (isNaN(number.valueOf())) - throw new Error("Wrong input string for conversion"); - hourDifference = multiplier * number; - if (differenceString.length === 4) { - number = parseInt(differenceString.substring(2, 4), 10); - if (isNaN(number.valueOf())) - throw new Error("Wrong input string for conversion"); - minuteDifference = multiplier * number; - } - } - } - let fractionPointPosition = timeString.indexOf("."); - if (fractionPointPosition === -1) - fractionPointPosition = timeString.indexOf(","); - if (fractionPointPosition !== -1) { - const fractionPartCheck = new Number(`0${timeString.substring(fractionPointPosition)}`); - if (isNaN(fractionPartCheck.valueOf())) - throw new Error("Wrong input string for conversion"); - fractionPart = fractionPartCheck.valueOf(); - dateTimeString = timeString.substring(0, fractionPointPosition); - } else - dateTimeString = timeString; - switch (true) { - case dateTimeString.length === 8: - parser = /(\d{4})(\d{2})(\d{2})/ig; - if (fractionPointPosition !== -1) - throw new Error("Wrong input string for conversion"); - break; - case dateTimeString.length === 10: - parser = /(\d{4})(\d{2})(\d{2})(\d{2})/ig; - if (fractionPointPosition !== -1) { - let fractionResult = 60 * fractionPart; - this.minute = Math.floor(fractionResult); - fractionResult = 60 * (fractionResult - this.minute); - this.second = Math.floor(fractionResult); - fractionResult = 1e3 * (fractionResult - this.second); - this.millisecond = Math.floor(fractionResult); - } - break; - case dateTimeString.length === 12: - parser = /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})/ig; - if (fractionPointPosition !== -1) { - let fractionResult = 60 * fractionPart; - this.second = Math.floor(fractionResult); - fractionResult = 1e3 * (fractionResult - this.second); - this.millisecond = Math.floor(fractionResult); - } - break; - case dateTimeString.length === 14: - parser = /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/ig; - if (fractionPointPosition !== -1) { - const fractionResult = 1e3 * fractionPart; - this.millisecond = Math.floor(fractionResult); - } - break; - default: - throw new Error("Wrong input string for conversion"); - } - const parserArray = parser.exec(dateTimeString); - if (parserArray === null) - throw new Error("Wrong input string for conversion"); - for (let j = 1; j < parserArray.length; j++) { - switch (j) { - case 1: - this.year = parseInt(parserArray[j], 10); - break; - case 2: - this.month = parseInt(parserArray[j], 10); - break; - case 3: - this.day = parseInt(parserArray[j], 10); - break; - case 4: - this.hour = parseInt(parserArray[j], 10) + hourDifference; - break; - case 5: - this.minute = parseInt(parserArray[j], 10) + minuteDifference; - break; - case 6: - this.second = parseInt(parserArray[j], 10); - break; - default: - throw new Error("Wrong input string for conversion"); - } - } - if (isUTC === false) { - const tempDate = new Date(this.year, this.month, this.day, this.hour, this.minute, this.second, this.millisecond); - this.year = tempDate.getUTCFullYear(); - this.month = tempDate.getUTCMonth(); - this.day = tempDate.getUTCDay(); - this.hour = tempDate.getUTCHours(); - this.minute = tempDate.getUTCMinutes(); - this.second = tempDate.getUTCSeconds(); - this.millisecond = tempDate.getUTCMilliseconds(); - } - } - toString(encoding = "iso") { - if (encoding === "iso") { - const outputArray = []; - outputArray.push(padNumber(this.year, 4)); - outputArray.push(padNumber(this.month, 2)); - outputArray.push(padNumber(this.day, 2)); - outputArray.push(padNumber(this.hour, 2)); - outputArray.push(padNumber(this.minute, 2)); - outputArray.push(padNumber(this.second, 2)); - if (this.millisecond !== 0) { - outputArray.push("."); - outputArray.push(padNumber(this.millisecond, 3)); - } - outputArray.push("Z"); - return outputArray.join(""); - } - return super.toString(encoding); - } - toJSON() { - return { - ...super.toJSON(), - millisecond: this.millisecond - }; - } - }; - _a$5 = GeneralizedTime; - (() => { - typeStore.GeneralizedTime = _a$5; - })(); - GeneralizedTime.NAME = "GeneralizedTime"; - DATE = class extends Utf8String { - constructor(parameters = {}) { - super(parameters); - this.idBlock.tagClass = 1; - this.idBlock.tagNumber = 31; - } - }; - _a$4 = DATE; - (() => { - typeStore.DATE = _a$4; - })(); - DATE.NAME = "DATE"; - TimeOfDay = class extends Utf8String { - constructor(parameters = {}) { - super(parameters); - this.idBlock.tagClass = 1; - this.idBlock.tagNumber = 32; - } - }; - _a$3 = TimeOfDay; - (() => { - typeStore.TimeOfDay = _a$3; - })(); - TimeOfDay.NAME = "TimeOfDay"; - DateTime = class extends Utf8String { - constructor(parameters = {}) { - super(parameters); - this.idBlock.tagClass = 1; - this.idBlock.tagNumber = 33; - } - }; - _a$2 = DateTime; - (() => { - typeStore.DateTime = _a$2; - })(); - DateTime.NAME = "DateTime"; - Duration = class extends Utf8String { - constructor(parameters = {}) { - super(parameters); - this.idBlock.tagClass = 1; - this.idBlock.tagNumber = 34; - } - }; - _a$1 = Duration; - (() => { - typeStore.Duration = _a$1; - })(); - Duration.NAME = "Duration"; - TIME = class extends Utf8String { - constructor(parameters = {}) { - super(parameters); - this.idBlock.tagClass = 1; - this.idBlock.tagNumber = 14; - } - }; - _a = TIME; - (() => { - typeStore.TIME = _a; - })(); - TIME.NAME = "TIME"; - Any = class { - constructor({ name = EMPTY_STRING, optional = false } = {}) { - this.name = name; - this.optional = optional; - } - }; - Choice = class extends Any { - constructor({ value = [], ...parameters } = {}) { - super(parameters); - this.value = value; - } - }; - Repeated = class extends Any { - constructor({ value = new Any(), local = false, ...parameters } = {}) { - super(parameters); - this.value = value; - this.local = local; - } - }; - RawData = class { - constructor({ data = EMPTY_VIEW } = {}) { - this.dataView = pvtsutils.BufferSourceConverter.toUint8Array(data); - } - get data() { - return this.dataView.slice().buffer; - } - set data(value) { - this.dataView = pvtsutils.BufferSourceConverter.toUint8Array(value); - } - fromBER(inputBuffer, inputOffset, inputLength) { - const endLength = inputOffset + inputLength; - this.dataView = pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer).subarray(inputOffset, endLength); - return endLength; - } - toBER(sizeOnly) { - return this.dataView.slice().buffer; - } - }; - } - }); - - // node_modules/.pnpm/@peculiar+asn1-schema@2.3.6/node_modules/@peculiar/asn1-schema/build/es2015/enums.js - var AsnTypeTypes, AsnPropTypes; - var init_enums = __esm({ - "node_modules/.pnpm/@peculiar+asn1-schema@2.3.6/node_modules/@peculiar/asn1-schema/build/es2015/enums.js"() { - (function(AsnTypeTypes2) { - AsnTypeTypes2[AsnTypeTypes2["Sequence"] = 0] = "Sequence"; - AsnTypeTypes2[AsnTypeTypes2["Set"] = 1] = "Set"; - AsnTypeTypes2[AsnTypeTypes2["Choice"] = 2] = "Choice"; - })(AsnTypeTypes || (AsnTypeTypes = {})); - (function(AsnPropTypes2) { - AsnPropTypes2[AsnPropTypes2["Any"] = 1] = "Any"; - AsnPropTypes2[AsnPropTypes2["Boolean"] = 2] = "Boolean"; - AsnPropTypes2[AsnPropTypes2["OctetString"] = 3] = "OctetString"; - AsnPropTypes2[AsnPropTypes2["BitString"] = 4] = "BitString"; - AsnPropTypes2[AsnPropTypes2["Integer"] = 5] = "Integer"; - AsnPropTypes2[AsnPropTypes2["Enumerated"] = 6] = "Enumerated"; - AsnPropTypes2[AsnPropTypes2["ObjectIdentifier"] = 7] = "ObjectIdentifier"; - AsnPropTypes2[AsnPropTypes2["Utf8String"] = 8] = "Utf8String"; - AsnPropTypes2[AsnPropTypes2["BmpString"] = 9] = "BmpString"; - AsnPropTypes2[AsnPropTypes2["UniversalString"] = 10] = "UniversalString"; - AsnPropTypes2[AsnPropTypes2["NumericString"] = 11] = "NumericString"; - AsnPropTypes2[AsnPropTypes2["PrintableString"] = 12] = "PrintableString"; - AsnPropTypes2[AsnPropTypes2["TeletexString"] = 13] = "TeletexString"; - AsnPropTypes2[AsnPropTypes2["VideotexString"] = 14] = "VideotexString"; - AsnPropTypes2[AsnPropTypes2["IA5String"] = 15] = "IA5String"; - AsnPropTypes2[AsnPropTypes2["GraphicString"] = 16] = "GraphicString"; - AsnPropTypes2[AsnPropTypes2["VisibleString"] = 17] = "VisibleString"; - AsnPropTypes2[AsnPropTypes2["GeneralString"] = 18] = "GeneralString"; - AsnPropTypes2[AsnPropTypes2["CharacterString"] = 19] = "CharacterString"; - AsnPropTypes2[AsnPropTypes2["UTCTime"] = 20] = "UTCTime"; - AsnPropTypes2[AsnPropTypes2["GeneralizedTime"] = 21] = "GeneralizedTime"; - AsnPropTypes2[AsnPropTypes2["DATE"] = 22] = "DATE"; - AsnPropTypes2[AsnPropTypes2["TimeOfDay"] = 23] = "TimeOfDay"; - AsnPropTypes2[AsnPropTypes2["DateTime"] = 24] = "DateTime"; - AsnPropTypes2[AsnPropTypes2["Duration"] = 25] = "Duration"; - AsnPropTypes2[AsnPropTypes2["TIME"] = 26] = "TIME"; - AsnPropTypes2[AsnPropTypes2["Null"] = 27] = "Null"; - })(AsnPropTypes || (AsnPropTypes = {})); - } - }); - - // node_modules/.pnpm/@peculiar+asn1-schema@2.3.6/node_modules/@peculiar/asn1-schema/build/es2015/types/bit_string.js - var import_pvtsutils; - var init_bit_string = __esm({ - "node_modules/.pnpm/@peculiar+asn1-schema@2.3.6/node_modules/@peculiar/asn1-schema/build/es2015/types/bit_string.js"() { - init_index_es(); - import_pvtsutils = __toESM(require_build()); - } - }); - - // node_modules/.pnpm/@peculiar+asn1-schema@2.3.6/node_modules/@peculiar/asn1-schema/build/es2015/types/octet_string.js - var import_pvtsutils2; - var init_octet_string = __esm({ - "node_modules/.pnpm/@peculiar+asn1-schema@2.3.6/node_modules/@peculiar/asn1-schema/build/es2015/types/octet_string.js"() { - init_index_es(); - import_pvtsutils2 = __toESM(require_build()); - } - }); - - // node_modules/.pnpm/@peculiar+asn1-schema@2.3.6/node_modules/@peculiar/asn1-schema/build/es2015/types/index.js - var init_types = __esm({ - "node_modules/.pnpm/@peculiar+asn1-schema@2.3.6/node_modules/@peculiar/asn1-schema/build/es2015/types/index.js"() { - init_bit_string(); - init_octet_string(); - } - }); - - // node_modules/.pnpm/@peculiar+asn1-schema@2.3.6/node_modules/@peculiar/asn1-schema/build/es2015/converters.js - function createStringConverter(Asn1Type) { - return { - fromASN: (value) => value.valueBlock.value, - toASN: (value) => new Asn1Type({ value }) - }; - } - function defaultConverter(type) { - switch (type) { - case AsnPropTypes.Any: - return AsnAnyConverter; - case AsnPropTypes.BitString: - return AsnBitStringConverter; - case AsnPropTypes.BmpString: - return AsnBmpStringConverter; - case AsnPropTypes.Boolean: - return AsnBooleanConverter; - case AsnPropTypes.CharacterString: - return AsnCharacterStringConverter; - case AsnPropTypes.Enumerated: - return AsnEnumeratedConverter; - case AsnPropTypes.GeneralString: - return AsnGeneralStringConverter; - case AsnPropTypes.GeneralizedTime: - return AsnGeneralizedTimeConverter; - case AsnPropTypes.GraphicString: - return AsnGraphicStringConverter; - case AsnPropTypes.IA5String: - return AsnIA5StringConverter; - case AsnPropTypes.Integer: - return AsnIntegerConverter; - case AsnPropTypes.Null: - return AsnNullConverter; - case AsnPropTypes.NumericString: - return AsnNumericStringConverter; - case AsnPropTypes.ObjectIdentifier: - return AsnObjectIdentifierConverter; - case AsnPropTypes.OctetString: - return AsnOctetStringConverter; - case AsnPropTypes.PrintableString: - return AsnPrintableStringConverter; - case AsnPropTypes.TeletexString: - return AsnTeletexStringConverter; - case AsnPropTypes.UTCTime: - return AsnUTCTimeConverter; - case AsnPropTypes.UniversalString: - return AsnUniversalStringConverter; - case AsnPropTypes.Utf8String: - return AsnUtf8StringConverter; - case AsnPropTypes.VideotexString: - return AsnVideotexStringConverter; - case AsnPropTypes.VisibleString: - return AsnVisibleStringConverter; - default: - return null; - } - } - var AsnAnyConverter, AsnIntegerConverter, AsnEnumeratedConverter, AsnBitStringConverter, AsnObjectIdentifierConverter, AsnBooleanConverter, AsnOctetStringConverter, AsnUtf8StringConverter, AsnBmpStringConverter, AsnUniversalStringConverter, AsnNumericStringConverter, AsnPrintableStringConverter, AsnTeletexStringConverter, AsnVideotexStringConverter, AsnIA5StringConverter, AsnGraphicStringConverter, AsnVisibleStringConverter, AsnGeneralStringConverter, AsnCharacterStringConverter, AsnUTCTimeConverter, AsnGeneralizedTimeConverter, AsnNullConverter; - var init_converters = __esm({ - "node_modules/.pnpm/@peculiar+asn1-schema@2.3.6/node_modules/@peculiar/asn1-schema/build/es2015/converters.js"() { - init_index_es(); - init_enums(); - init_types(); - AsnAnyConverter = { - fromASN: (value) => value instanceof Null ? null : value.valueBeforeDecodeView, - toASN: (value) => { - if (value === null) { - return new Null(); - } - const schema = fromBER(value); - if (schema.result.error) { - throw new Error(schema.result.error); - } - return schema.result; - } - }; - AsnIntegerConverter = { - fromASN: (value) => value.valueBlock.valueHexView.byteLength >= 4 ? value.valueBlock.toString() : value.valueBlock.valueDec, - toASN: (value) => new Integer({ value: +value }) - }; - AsnEnumeratedConverter = { - fromASN: (value) => value.valueBlock.valueDec, - toASN: (value) => new Enumerated({ value }) - }; - AsnBitStringConverter = { - fromASN: (value) => value.valueBlock.valueHexView, - toASN: (value) => new BitString({ valueHex: value }) - }; - AsnObjectIdentifierConverter = { - fromASN: (value) => value.valueBlock.toString(), - toASN: (value) => new ObjectIdentifier({ value }) - }; - AsnBooleanConverter = { - fromASN: (value) => value.valueBlock.value, - toASN: (value) => new Boolean2({ value }) - }; - AsnOctetStringConverter = { - fromASN: (value) => value.valueBlock.valueHexView, - toASN: (value) => new OctetString({ valueHex: value }) - }; - AsnUtf8StringConverter = createStringConverter(Utf8String); - AsnBmpStringConverter = createStringConverter(BmpString); - AsnUniversalStringConverter = createStringConverter(UniversalString); - AsnNumericStringConverter = createStringConverter(NumericString); - AsnPrintableStringConverter = createStringConverter(PrintableString); - AsnTeletexStringConverter = createStringConverter(TeletexString); - AsnVideotexStringConverter = createStringConverter(VideotexString); - AsnIA5StringConverter = createStringConverter(IA5String); - AsnGraphicStringConverter = createStringConverter(GraphicString); - AsnVisibleStringConverter = createStringConverter(VisibleString); - AsnGeneralStringConverter = createStringConverter(GeneralString); - AsnCharacterStringConverter = createStringConverter(CharacterString); - AsnUTCTimeConverter = { - fromASN: (value) => value.toDate(), - toASN: (value) => new UTCTime({ valueDate: value }) - }; - AsnGeneralizedTimeConverter = { - fromASN: (value) => value.toDate(), - toASN: (value) => new GeneralizedTime({ valueDate: value }) - }; - AsnNullConverter = { - fromASN: () => null, - toASN: () => { - return new Null(); - } - }; - } - }); - - // node_modules/.pnpm/@peculiar+asn1-schema@2.3.6/node_modules/@peculiar/asn1-schema/build/es2015/helper.js - function isConvertible(target) { - if (typeof target === "function" && target.prototype) { - if (target.prototype.toASN && target.prototype.fromASN) { - return true; - } else { - return isConvertible(target.prototype); - } - } else { - return !!(target && typeof target === "object" && "toASN" in target && "fromASN" in target); - } - } - function isTypeOfArray(target) { - var _a2; - if (target) { - const proto = Object.getPrototypeOf(target); - if (((_a2 = proto === null || proto === void 0 ? void 0 : proto.prototype) === null || _a2 === void 0 ? void 0 : _a2.constructor) === Array) { - return true; - } - return isTypeOfArray(proto); - } - return false; - } - function isArrayEqual(bytes1, bytes2) { - if (!(bytes1 && bytes2)) { - return false; - } - if (bytes1.byteLength !== bytes2.byteLength) { - return false; - } - const b1 = new Uint8Array(bytes1); - const b2 = new Uint8Array(bytes2); - for (let i = 0; i < bytes1.byteLength; i++) { - if (b1[i] !== b2[i]) { - return false; - } - } - return true; - } - var init_helper = __esm({ - "node_modules/.pnpm/@peculiar+asn1-schema@2.3.6/node_modules/@peculiar/asn1-schema/build/es2015/helper.js"() { - } - }); - - // node_modules/.pnpm/@peculiar+asn1-schema@2.3.6/node_modules/@peculiar/asn1-schema/build/es2015/schema.js - var AsnSchemaStorage; - var init_schema = __esm({ - "node_modules/.pnpm/@peculiar+asn1-schema@2.3.6/node_modules/@peculiar/asn1-schema/build/es2015/schema.js"() { - init_index_es(); - init_enums(); - init_helper(); - AsnSchemaStorage = class { - constructor() { - this.items = /* @__PURE__ */ new WeakMap(); - } - has(target) { - return this.items.has(target); - } - get(target, checkSchema = false) { - const schema = this.items.get(target); - if (!schema) { - throw new Error(`Cannot get schema for '${target.prototype.constructor.name}' target`); - } - if (checkSchema && !schema.schema) { - throw new Error(`Schema '${target.prototype.constructor.name}' doesn't contain ASN.1 schema. Call 'AsnSchemaStorage.cache'.`); - } - return schema; - } - cache(target) { - const schema = this.get(target); - if (!schema.schema) { - schema.schema = this.create(target, true); - } - } - createDefault(target) { - const schema = { - type: AsnTypeTypes.Sequence, - items: {} - }; - const parentSchema = this.findParentSchema(target); - if (parentSchema) { - Object.assign(schema, parentSchema); - schema.items = Object.assign({}, schema.items, parentSchema.items); - } - return schema; - } - create(target, useNames) { - const schema = this.items.get(target) || this.createDefault(target); - const asn1Value = []; - for (const key in schema.items) { - const item = schema.items[key]; - const name = useNames ? key : ""; - let asn1Item; - if (typeof item.type === "number") { - const Asn1TypeName = AsnPropTypes[item.type]; - const Asn1Type = index_es_exports[Asn1TypeName]; - if (!Asn1Type) { - throw new Error(`Cannot get ASN1 class by name '${Asn1TypeName}'`); - } - asn1Item = new Asn1Type({ name }); - } else if (isConvertible(item.type)) { - const instance = new item.type(); - asn1Item = instance.toSchema(name); - } else if (item.optional) { - const itemSchema = this.get(item.type); - if (itemSchema.type === AsnTypeTypes.Choice) { - asn1Item = new Any({ name }); - } else { - asn1Item = this.create(item.type, false); - asn1Item.name = name; - } - } else { - asn1Item = new Any({ name }); - } - const optional = !!item.optional || item.defaultValue !== void 0; - if (item.repeated) { - asn1Item.name = ""; - const Container = item.repeated === "set" ? Set2 : Sequence; - asn1Item = new Container({ - name: "", - value: [ - new Repeated({ - name, - value: asn1Item - }) - ] - }); - } - if (item.context !== null && item.context !== void 0) { - if (item.implicit) { - if (typeof item.type === "number" || isConvertible(item.type)) { - const Container = item.repeated ? Constructed : Primitive; - asn1Value.push(new Container({ - name, - optional, - idBlock: { - tagClass: 3, - tagNumber: item.context - } - })); - } else { - this.cache(item.type); - const isRepeated = !!item.repeated; - let value = !isRepeated ? this.get(item.type, true).schema : asn1Item; - value = "valueBlock" in value ? value.valueBlock.value : value.value; - asn1Value.push(new Constructed({ - name: !isRepeated ? name : "", - optional, - idBlock: { - tagClass: 3, - tagNumber: item.context - }, - value - })); - } - } else { - asn1Value.push(new Constructed({ - optional, - idBlock: { - tagClass: 3, - tagNumber: item.context - }, - value: [asn1Item] - })); - } - } else { - asn1Item.optional = optional; - asn1Value.push(asn1Item); - } - } - switch (schema.type) { - case AsnTypeTypes.Sequence: - return new Sequence({ value: asn1Value, name: "" }); - case AsnTypeTypes.Set: - return new Set2({ value: asn1Value, name: "" }); - case AsnTypeTypes.Choice: - return new Choice({ value: asn1Value, name: "" }); - default: - throw new Error(`Unsupported ASN1 type in use`); - } - } - set(target, schema) { - this.items.set(target, schema); - return this; - } - findParentSchema(target) { - const parent = Object.getPrototypeOf(target); - if (parent) { - const schema = this.items.get(parent); - return schema || this.findParentSchema(parent); - } - return null; - } - }; - } - }); - - // node_modules/.pnpm/@peculiar+asn1-schema@2.3.6/node_modules/@peculiar/asn1-schema/build/es2015/storage.js - var schemaStorage; - var init_storage = __esm({ - "node_modules/.pnpm/@peculiar+asn1-schema@2.3.6/node_modules/@peculiar/asn1-schema/build/es2015/storage.js"() { - init_schema(); - schemaStorage = new AsnSchemaStorage(); - } - }); - - // node_modules/.pnpm/@peculiar+asn1-schema@2.3.6/node_modules/@peculiar/asn1-schema/build/es2015/decorators.js - var AsnType, AsnProp; - var init_decorators = __esm({ - "node_modules/.pnpm/@peculiar+asn1-schema@2.3.6/node_modules/@peculiar/asn1-schema/build/es2015/decorators.js"() { - init_converters(); - init_enums(); - init_storage(); - AsnType = (options) => (target) => { - let schema; - if (!schemaStorage.has(target)) { - schema = schemaStorage.createDefault(target); - schemaStorage.set(target, schema); - } else { - schema = schemaStorage.get(target); - } - Object.assign(schema, options); - }; - AsnProp = (options) => (target, propertyKey) => { - let schema; - if (!schemaStorage.has(target.constructor)) { - schema = schemaStorage.createDefault(target.constructor); - schemaStorage.set(target.constructor, schema); - } else { - schema = schemaStorage.get(target.constructor); - } - const copyOptions = Object.assign({}, options); - if (typeof copyOptions.type === "number" && !copyOptions.converter) { - const defaultConverter2 = defaultConverter(options.type); - if (!defaultConverter2) { - throw new Error(`Cannot get default converter for property '${propertyKey}' of ${target.constructor.name}`); - } - copyOptions.converter = defaultConverter2; - } - schema.items[propertyKey] = copyOptions; - }; - } - }); - - // node_modules/.pnpm/@peculiar+asn1-schema@2.3.6/node_modules/@peculiar/asn1-schema/build/es2015/errors/schema_validation.js - var AsnSchemaValidationError; - var init_schema_validation = __esm({ - "node_modules/.pnpm/@peculiar+asn1-schema@2.3.6/node_modules/@peculiar/asn1-schema/build/es2015/errors/schema_validation.js"() { - AsnSchemaValidationError = class extends Error { - constructor() { - super(...arguments); - this.schemas = []; - } - }; - } - }); - - // node_modules/.pnpm/@peculiar+asn1-schema@2.3.6/node_modules/@peculiar/asn1-schema/build/es2015/errors/index.js - var init_errors = __esm({ - "node_modules/.pnpm/@peculiar+asn1-schema@2.3.6/node_modules/@peculiar/asn1-schema/build/es2015/errors/index.js"() { - init_schema_validation(); - } - }); - - // node_modules/.pnpm/@peculiar+asn1-schema@2.3.6/node_modules/@peculiar/asn1-schema/build/es2015/parser.js - var AsnParser; - var init_parser = __esm({ - "node_modules/.pnpm/@peculiar+asn1-schema@2.3.6/node_modules/@peculiar/asn1-schema/build/es2015/parser.js"() { - init_index_es(); - init_enums(); - init_converters(); - init_errors(); - init_helper(); - init_storage(); - AsnParser = class { - static parse(data, target) { - const asn1Parsed = fromBER(data); - if (asn1Parsed.result.error) { - throw new Error(asn1Parsed.result.error); - } - const res = this.fromASN(asn1Parsed.result, target); - return res; - } - static fromASN(asn1Schema, target) { - var _a2; - try { - if (isConvertible(target)) { - const value = new target(); - return value.fromASN(asn1Schema); - } - const schema = schemaStorage.get(target); - schemaStorage.cache(target); - let targetSchema = schema.schema; - if (asn1Schema.constructor === Constructed && schema.type !== AsnTypeTypes.Choice) { - targetSchema = new Constructed({ - idBlock: { - tagClass: 3, - tagNumber: asn1Schema.idBlock.tagNumber - }, - value: schema.schema.valueBlock.value - }); - for (const key in schema.items) { - delete asn1Schema[key]; - } - } - const asn1ComparedSchema = compareSchema({}, asn1Schema, targetSchema); - if (!asn1ComparedSchema.verified) { - throw new AsnSchemaValidationError(`Data does not match to ${target.name} ASN1 schema. ${asn1ComparedSchema.result.error}`); - } - const res = new target(); - if (isTypeOfArray(target)) { - if (!("value" in asn1Schema.valueBlock && Array.isArray(asn1Schema.valueBlock.value))) { - throw new Error(`Cannot get items from the ASN.1 parsed value. ASN.1 object is not constructed.`); - } - const itemType = schema.itemType; - if (typeof itemType === "number") { - const converter = defaultConverter(itemType); - if (!converter) { - throw new Error(`Cannot get default converter for array item of ${target.name} ASN1 schema`); - } - return target.from(asn1Schema.valueBlock.value, (element) => converter.fromASN(element)); - } else { - return target.from(asn1Schema.valueBlock.value, (element) => this.fromASN(element, itemType)); - } - } - for (const key in schema.items) { - const asn1SchemaValue = asn1ComparedSchema.result[key]; - if (!asn1SchemaValue) { - continue; - } - const schemaItem = schema.items[key]; - const schemaItemType = schemaItem.type; - if (typeof schemaItemType === "number" || isConvertible(schemaItemType)) { - const converter = (_a2 = schemaItem.converter) !== null && _a2 !== void 0 ? _a2 : isConvertible(schemaItemType) ? new schemaItemType() : null; - if (!converter) { - throw new Error("Converter is empty"); - } - if (schemaItem.repeated) { - if (schemaItem.implicit) { - const Container = schemaItem.repeated === "sequence" ? Sequence : Set2; - const newItem = new Container(); - newItem.valueBlock = asn1SchemaValue.valueBlock; - const newItemAsn = fromBER(newItem.toBER(false)); - if (newItemAsn.offset === -1) { - throw new Error(`Cannot parse the child item. ${newItemAsn.result.error}`); - } - if (!("value" in newItemAsn.result.valueBlock && Array.isArray(newItemAsn.result.valueBlock.value))) { - throw new Error("Cannot get items from the ASN.1 parsed value. ASN.1 object is not constructed."); - } - const value = newItemAsn.result.valueBlock.value; - res[key] = Array.from(value, (element) => converter.fromASN(element)); - } else { - res[key] = Array.from(asn1SchemaValue, (element) => converter.fromASN(element)); - } - } else { - let value = asn1SchemaValue; - if (schemaItem.implicit) { - let newItem; - if (isConvertible(schemaItemType)) { - newItem = new schemaItemType().toSchema(""); - } else { - const Asn1TypeName = AsnPropTypes[schemaItemType]; - const Asn1Type = index_es_exports[Asn1TypeName]; - if (!Asn1Type) { - throw new Error(`Cannot get '${Asn1TypeName}' class from asn1js module`); - } - newItem = new Asn1Type(); - } - newItem.valueBlock = value.valueBlock; - value = fromBER(newItem.toBER(false)).result; - } - res[key] = converter.fromASN(value); - } - } else { - if (schemaItem.repeated) { - if (!Array.isArray(asn1SchemaValue)) { - throw new Error("Cannot get list of items from the ASN.1 parsed value. ASN.1 value should be iterable."); - } - res[key] = Array.from(asn1SchemaValue, (element) => this.fromASN(element, schemaItemType)); - } else { - res[key] = this.fromASN(asn1SchemaValue, schemaItemType); - } - } - } - return res; - } catch (error) { - if (error instanceof AsnSchemaValidationError) { - error.schemas.push(target.name); - } - throw error; - } - } - }; - } - }); - - // node_modules/.pnpm/@peculiar+asn1-schema@2.3.6/node_modules/@peculiar/asn1-schema/build/es2015/serializer.js - var AsnSerializer; - var init_serializer = __esm({ - "node_modules/.pnpm/@peculiar+asn1-schema@2.3.6/node_modules/@peculiar/asn1-schema/build/es2015/serializer.js"() { - init_index_es(); - init_converters(); - init_enums(); - init_helper(); - init_storage(); - AsnSerializer = class { - static serialize(obj) { - if (obj instanceof BaseBlock) { - return obj.toBER(false); - } - return this.toASN(obj).toBER(false); - } - static toASN(obj) { - if (obj && typeof obj === "object" && isConvertible(obj)) { - return obj.toASN(); - } - if (!(obj && typeof obj === "object")) { - throw new TypeError("Parameter 1 should be type of Object."); - } - const target = obj.constructor; - const schema = schemaStorage.get(target); - schemaStorage.cache(target); - let asn1Value = []; - if (schema.itemType) { - if (!Array.isArray(obj)) { - throw new TypeError("Parameter 1 should be type of Array."); - } - if (typeof schema.itemType === "number") { - const converter = defaultConverter(schema.itemType); - if (!converter) { - throw new Error(`Cannot get default converter for array item of ${target.name} ASN1 schema`); - } - asn1Value = obj.map((o) => converter.toASN(o)); - } else { - asn1Value = obj.map((o) => this.toAsnItem({ type: schema.itemType }, "[]", target, o)); - } - } else { - for (const key in schema.items) { - const schemaItem = schema.items[key]; - const objProp = obj[key]; - if (objProp === void 0 || schemaItem.defaultValue === objProp || typeof schemaItem.defaultValue === "object" && typeof objProp === "object" && isArrayEqual(this.serialize(schemaItem.defaultValue), this.serialize(objProp))) { - continue; - } - const asn1Item = AsnSerializer.toAsnItem(schemaItem, key, target, objProp); - if (typeof schemaItem.context === "number") { - if (schemaItem.implicit) { - if (!schemaItem.repeated && (typeof schemaItem.type === "number" || isConvertible(schemaItem.type))) { - const value = {}; - value.valueHex = asn1Item instanceof Null ? asn1Item.valueBeforeDecodeView : asn1Item.valueBlock.toBER(); - asn1Value.push(new Primitive({ - optional: schemaItem.optional, - idBlock: { - tagClass: 3, - tagNumber: schemaItem.context - }, - ...value - })); - } else { - asn1Value.push(new Constructed({ - optional: schemaItem.optional, - idBlock: { - tagClass: 3, - tagNumber: schemaItem.context - }, - value: asn1Item.valueBlock.value - })); - } - } else { - asn1Value.push(new Constructed({ - optional: schemaItem.optional, - idBlock: { - tagClass: 3, - tagNumber: schemaItem.context - }, - value: [asn1Item] - })); - } - } else if (schemaItem.repeated) { - asn1Value = asn1Value.concat(asn1Item); - } else { - asn1Value.push(asn1Item); - } - } - } - let asnSchema; - switch (schema.type) { - case AsnTypeTypes.Sequence: - asnSchema = new Sequence({ value: asn1Value }); - break; - case AsnTypeTypes.Set: - asnSchema = new Set2({ value: asn1Value }); - break; - case AsnTypeTypes.Choice: - if (!asn1Value[0]) { - throw new Error(`Schema '${target.name}' has wrong data. Choice cannot be empty.`); - } - asnSchema = asn1Value[0]; - break; - } - return asnSchema; - } - static toAsnItem(schemaItem, key, target, objProp) { - let asn1Item; - if (typeof schemaItem.type === "number") { - const converter = schemaItem.converter; - if (!converter) { - throw new Error(`Property '${key}' doesn't have converter for type ${AsnPropTypes[schemaItem.type]} in schema '${target.name}'`); - } - if (schemaItem.repeated) { - if (!Array.isArray(objProp)) { - throw new TypeError("Parameter 'objProp' should be type of Array."); - } - const items = Array.from(objProp, (element) => converter.toASN(element)); - const Container = schemaItem.repeated === "sequence" ? Sequence : Set2; - asn1Item = new Container({ - value: items - }); - } else { - asn1Item = converter.toASN(objProp); - } - } else { - if (schemaItem.repeated) { - if (!Array.isArray(objProp)) { - throw new TypeError("Parameter 'objProp' should be type of Array."); - } - const items = Array.from(objProp, (element) => this.toASN(element)); - const Container = schemaItem.repeated === "sequence" ? Sequence : Set2; - asn1Item = new Container({ - value: items - }); - } else { - asn1Item = this.toASN(objProp); - } - } - return asn1Item; - } - }; - } - }); - - // node_modules/.pnpm/@peculiar+asn1-schema@2.3.6/node_modules/@peculiar/asn1-schema/build/es2015/objects.js - var init_objects = __esm({ - "node_modules/.pnpm/@peculiar+asn1-schema@2.3.6/node_modules/@peculiar/asn1-schema/build/es2015/objects.js"() { - } - }); - - // node_modules/.pnpm/@peculiar+asn1-schema@2.3.6/node_modules/@peculiar/asn1-schema/build/es2015/convert.js - var import_pvtsutils3, AsnConvert; - var init_convert = __esm({ - "node_modules/.pnpm/@peculiar+asn1-schema@2.3.6/node_modules/@peculiar/asn1-schema/build/es2015/convert.js"() { - init_index_es(); - import_pvtsutils3 = __toESM(require_build()); - init_parser(); - init_serializer(); - AsnConvert = class { - static serialize(obj) { - return AsnSerializer.serialize(obj); - } - static parse(data, target) { - return AsnParser.parse(data, target); - } - static toString(data) { - const buf = import_pvtsutils3.BufferSourceConverter.isBufferSource(data) ? import_pvtsutils3.BufferSourceConverter.toArrayBuffer(data) : AsnConvert.serialize(data); - const asn = fromBER(buf); - if (asn.offset === -1) { - throw new Error(`Cannot decode ASN.1 data. ${asn.result.error}`); - } - return asn.result.toString(); - } - }; - } - }); - - // node_modules/.pnpm/@peculiar+asn1-schema@2.3.6/node_modules/@peculiar/asn1-schema/build/es2015/index.js - var init_es2015 = __esm({ - "node_modules/.pnpm/@peculiar+asn1-schema@2.3.6/node_modules/@peculiar/asn1-schema/build/es2015/index.js"() { - init_converters(); - init_types(); - init_decorators(); - init_enums(); - init_parser(); - init_serializer(); - init_errors(); - init_objects(); - init_convert(); - } - }); - - // node_modules/.pnpm/tslib@2.5.0/node_modules/tslib/tslib.es6.js - function __decorate(decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") - r = Reflect.decorate(decorators, target, key, desc); - else - for (var i = decorators.length - 1; i >= 0; i--) - if (d = decorators[i]) - r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; - } - var init_tslib_es6 = __esm({ - "node_modules/.pnpm/tslib@2.5.0/node_modules/tslib/tslib.es6.js"() { - } - }); - - // node_modules/.pnpm/@peculiar+json-schema@1.1.12/node_modules/@peculiar/json-schema/build/index.es.js - function checkType(value, type) { - switch (type) { - case JsonPropTypes.Boolean: - return typeof value === "boolean"; - case JsonPropTypes.Number: - return typeof value === "number"; - case JsonPropTypes.String: - return typeof value === "string"; - } - return true; - } - function throwIfTypeIsWrong(value, type) { - if (!checkType(value, type)) { - throw new TypeError(`Value must be ${JsonPropTypes[type]}`); - } - } - function isConvertible2(target) { - if (target && target.prototype) { - if (target.prototype.toJSON && target.prototype.fromJSON) { - return true; - } else { - return isConvertible2(target.prototype); - } - } else { - return !!(target && target.toJSON && target.fromJSON); - } - } - function getValidations(item) { - const validations = []; - if (item.pattern) { - validations.push(new PatternValidation(item.pattern)); - } - if (item.type === JsonPropTypes.Number || item.type === JsonPropTypes.Any) { - if (item.minInclusive !== void 0 || item.maxInclusive !== void 0) { - validations.push(new InclusiveValidation(item.minInclusive, item.maxInclusive)); - } - if (item.minExclusive !== void 0 || item.maxExclusive !== void 0) { - validations.push(new ExclusiveValidation(item.minExclusive, item.maxExclusive)); - } - if (item.enumeration !== void 0) { - validations.push(new EnumerationValidation(item.enumeration)); - } - } - if (item.type === JsonPropTypes.String || item.repeated || item.type === JsonPropTypes.Any) { - if (item.length !== void 0 || item.minLength !== void 0 || item.maxLength !== void 0) { - validations.push(new LengthValidation(item.length, item.minLength, item.maxLength)); - } - } - return validations; - } - var JsonError, TransformError, ParserError, ValidationError, SerializerError, KeyError, JsonPropTypes, JsonSchemaStorage, DEFAULT_SCHEMA, schemaStorage2, PatternValidation, InclusiveValidation, ExclusiveValidation, LengthValidation, EnumerationValidation, JsonTransform, JsonSerializer, JsonParser, JsonProp; - var init_index_es2 = __esm({ - "node_modules/.pnpm/@peculiar+json-schema@1.1.12/node_modules/@peculiar/json-schema/build/index.es.js"() { - JsonError = class extends Error { - constructor(message, innerError) { - super(innerError ? `${message}. See the inner exception for more details.` : message); - this.message = message; - this.innerError = innerError; - } - }; - TransformError = class extends JsonError { - constructor(schema, message, innerError) { - super(message, innerError); - this.schema = schema; - } - }; - ParserError = class extends TransformError { - constructor(schema, message, innerError) { - super(schema, `JSON doesn't match to '${schema.target.name}' schema. ${message}`, innerError); - } - }; - ValidationError = class extends JsonError { - }; - SerializerError = class extends JsonError { - constructor(schemaName, message, innerError) { - super(`Cannot serialize by '${schemaName}' schema. ${message}`, innerError); - this.schemaName = schemaName; - } - }; - KeyError = class extends ParserError { - constructor(schema, keys, errors = {}) { - super(schema, "Some keys doesn't match to schema"); - this.keys = keys; - this.errors = errors; - } - }; - (function(JsonPropTypes2) { - JsonPropTypes2[JsonPropTypes2["Any"] = 0] = "Any"; - JsonPropTypes2[JsonPropTypes2["Boolean"] = 1] = "Boolean"; - JsonPropTypes2[JsonPropTypes2["Number"] = 2] = "Number"; - JsonPropTypes2[JsonPropTypes2["String"] = 3] = "String"; - })(JsonPropTypes || (JsonPropTypes = {})); - JsonSchemaStorage = class { - constructor() { - this.items = /* @__PURE__ */ new Map(); - } - has(target) { - return this.items.has(target) || !!this.findParentSchema(target); - } - get(target) { - const schema = this.items.get(target) || this.findParentSchema(target); - if (!schema) { - throw new Error("Cannot get schema for current target"); - } - return schema; - } - create(target) { - const schema = { names: {} }; - const parentSchema = this.findParentSchema(target); - if (parentSchema) { - Object.assign(schema, parentSchema); - schema.names = {}; - for (const name in parentSchema.names) { - schema.names[name] = Object.assign({}, parentSchema.names[name]); - } - } - schema.target = target; - return schema; - } - set(target, schema) { - this.items.set(target, schema); - return this; - } - findParentSchema(target) { - const parent = target.__proto__; - if (parent) { - const schema = this.items.get(parent); - return schema || this.findParentSchema(parent); - } - return null; - } - }; - DEFAULT_SCHEMA = "default"; - schemaStorage2 = new JsonSchemaStorage(); - PatternValidation = class { - constructor(pattern) { - this.pattern = new RegExp(pattern); - } - validate(value) { - const pattern = new RegExp(this.pattern.source, this.pattern.flags); - if (typeof value !== "string") { - throw new ValidationError("Incoming value must be string"); - } - if (!pattern.exec(value)) { - throw new ValidationError(`Value doesn't match to pattern '${pattern.toString()}'`); - } - } - }; - InclusiveValidation = class { - constructor(min = Number.MIN_VALUE, max = Number.MAX_VALUE) { - this.min = min; - this.max = max; - } - validate(value) { - throwIfTypeIsWrong(value, JsonPropTypes.Number); - if (!(this.min <= value && value <= this.max)) { - const min = this.min === Number.MIN_VALUE ? "MIN" : this.min; - const max = this.max === Number.MAX_VALUE ? "MAX" : this.max; - throw new ValidationError(`Value doesn't match to diapason [${min},${max}]`); - } - } - }; - ExclusiveValidation = class { - constructor(min = Number.MIN_VALUE, max = Number.MAX_VALUE) { - this.min = min; - this.max = max; - } - validate(value) { - throwIfTypeIsWrong(value, JsonPropTypes.Number); - if (!(this.min < value && value < this.max)) { - const min = this.min === Number.MIN_VALUE ? "MIN" : this.min; - const max = this.max === Number.MAX_VALUE ? "MAX" : this.max; - throw new ValidationError(`Value doesn't match to diapason (${min},${max})`); - } - } - }; - LengthValidation = class { - constructor(length, minLength, maxLength) { - this.length = length; - this.minLength = minLength; - this.maxLength = maxLength; - } - validate(value) { - if (this.length !== void 0) { - if (value.length !== this.length) { - throw new ValidationError(`Value length must be exactly ${this.length}.`); - } - return; - } - if (this.minLength !== void 0) { - if (value.length < this.minLength) { - throw new ValidationError(`Value length must be more than ${this.minLength}.`); - } - } - if (this.maxLength !== void 0) { - if (value.length > this.maxLength) { - throw new ValidationError(`Value length must be less than ${this.maxLength}.`); - } - } - } - }; - EnumerationValidation = class { - constructor(enumeration) { - this.enumeration = enumeration; - } - validate(value) { - throwIfTypeIsWrong(value, JsonPropTypes.String); - if (!this.enumeration.includes(value)) { - throw new ValidationError(`Value must be one of ${this.enumeration.map((v) => `'${v}'`).join(", ")}`); - } - } - }; - JsonTransform = class { - static checkValues(data, schemaItem) { - const values = Array.isArray(data) ? data : [data]; - for (const value of values) { - for (const validation of schemaItem.validations) { - if (validation instanceof LengthValidation && schemaItem.repeated) { - validation.validate(data); - } else { - validation.validate(value); - } - } - } - } - static checkTypes(value, schemaItem) { - if (schemaItem.repeated && !Array.isArray(value)) { - throw new TypeError("Value must be Array"); - } - if (typeof schemaItem.type === "number") { - const values = Array.isArray(value) ? value : [value]; - for (const v of values) { - throwIfTypeIsWrong(v, schemaItem.type); - } - } - } - static getSchemaByName(schema, name = DEFAULT_SCHEMA) { - return { ...schema.names[DEFAULT_SCHEMA], ...schema.names[name] }; - } - }; - JsonSerializer = class extends JsonTransform { - static serialize(obj, options, replacer, space) { - const json = this.toJSON(obj, options); - return JSON.stringify(json, replacer, space); - } - static toJSON(obj, options = {}) { - let res; - let targetSchema = options.targetSchema; - const schemaName = options.schemaName || DEFAULT_SCHEMA; - if (isConvertible2(obj)) { - return obj.toJSON(); - } - if (Array.isArray(obj)) { - res = []; - for (const item of obj) { - res.push(this.toJSON(item, options)); - } - } else if (typeof obj === "object") { - if (targetSchema && !schemaStorage2.has(targetSchema)) { - throw new JsonError("Cannot get schema for `targetSchema` param"); - } - targetSchema = targetSchema || obj.constructor; - if (schemaStorage2.has(targetSchema)) { - const schema = schemaStorage2.get(targetSchema); - res = {}; - const namedSchema = this.getSchemaByName(schema, schemaName); - for (const key in namedSchema) { - try { - const item = namedSchema[key]; - const objItem = obj[key]; - let value; - if (item.optional && objItem === void 0 || item.defaultValue !== void 0 && objItem === item.defaultValue) { - continue; - } - if (!item.optional && objItem === void 0) { - throw new SerializerError(targetSchema.name, `Property '${key}' is required.`); - } - if (typeof item.type === "number") { - if (item.converter) { - if (item.repeated) { - value = objItem.map((el) => item.converter.toJSON(el, obj)); - } else { - value = item.converter.toJSON(objItem, obj); - } - } else { - value = objItem; - } - } else { - if (item.repeated) { - value = objItem.map((el) => this.toJSON(el, { schemaName })); - } else { - value = this.toJSON(objItem, { schemaName }); - } - } - this.checkTypes(value, item); - this.checkValues(value, item); - res[item.name || key] = value; - } catch (e) { - if (e instanceof SerializerError) { - throw e; - } else { - throw new SerializerError(schema.target.name, `Property '${key}' is wrong. ${e.message}`, e); - } - } - } - } else { - res = {}; - for (const key in obj) { - res[key] = this.toJSON(obj[key], { schemaName }); - } - } - } else { - res = obj; - } - return res; - } - }; - JsonParser = class extends JsonTransform { - static parse(data, options) { - const obj = JSON.parse(data); - return this.fromJSON(obj, options); - } - static fromJSON(target, options) { - const targetSchema = options.targetSchema; - const schemaName = options.schemaName || DEFAULT_SCHEMA; - const obj = new targetSchema(); - if (isConvertible2(obj)) { - return obj.fromJSON(target); - } - const schema = schemaStorage2.get(targetSchema); - const namedSchema = this.getSchemaByName(schema, schemaName); - const keyErrors = {}; - if (options.strictProperty && !Array.isArray(target)) { - JsonParser.checkStrictProperty(target, namedSchema, schema); - } - for (const key in namedSchema) { - try { - const item = namedSchema[key]; - const name = item.name || key; - const value = target[name]; - if (value === void 0 && (item.optional || item.defaultValue !== void 0)) { - continue; - } - if (!item.optional && value === void 0) { - throw new ParserError(schema, `Property '${name}' is required.`); - } - this.checkTypes(value, item); - this.checkValues(value, item); - if (typeof item.type === "number") { - if (item.converter) { - if (item.repeated) { - obj[key] = value.map((el) => item.converter.fromJSON(el, obj)); - } else { - obj[key] = item.converter.fromJSON(value, obj); - } - } else { - obj[key] = value; - } - } else { - const newOptions = { - ...options, - targetSchema: item.type, - schemaName - }; - if (item.repeated) { - obj[key] = value.map((el) => this.fromJSON(el, newOptions)); - } else { - obj[key] = this.fromJSON(value, newOptions); - } - } - } catch (e) { - if (!(e instanceof ParserError)) { - e = new ParserError(schema, `Property '${key}' is wrong. ${e.message}`, e); - } - if (options.strictAllKeys) { - keyErrors[key] = e; - } else { - throw e; - } - } - } - const keys = Object.keys(keyErrors); - if (keys.length) { - throw new KeyError(schema, keys, keyErrors); - } - return obj; - } - static checkStrictProperty(target, namedSchema, schema) { - const jsonProps = Object.keys(target); - const schemaProps = Object.keys(namedSchema); - const keys = []; - for (const key of jsonProps) { - if (schemaProps.indexOf(key) === -1) { - keys.push(key); - } - } - if (keys.length) { - throw new KeyError(schema, keys); - } - } - }; - JsonProp = (options = {}) => (target, propertyKey) => { - const errorMessage = `Cannot set type for ${propertyKey} property of ${target.constructor.name} schema`; - let schema; - if (!schemaStorage2.has(target.constructor)) { - schema = schemaStorage2.create(target.constructor); - schemaStorage2.set(target.constructor, schema); - } else { - schema = schemaStorage2.get(target.constructor); - if (schema.target !== target.constructor) { - schema = schemaStorage2.create(target.constructor); - schemaStorage2.set(target.constructor, schema); - } - } - const defaultSchema = { - type: JsonPropTypes.Any, - validations: [] - }; - const copyOptions = Object.assign(defaultSchema, options); - copyOptions.validations = getValidations(copyOptions); - if (typeof copyOptions.type !== "number") { - if (!schemaStorage2.has(copyOptions.type) && !isConvertible2(copyOptions.type)) { - throw new Error(`${errorMessage}. Assigning type doesn't have schema.`); - } - } - let schemaNames; - if (Array.isArray(options.schema)) { - schemaNames = options.schema; - } else { - schemaNames = [options.schema || DEFAULT_SCHEMA]; - } - for (const schemaName of schemaNames) { - if (!schema.names[schemaName]) { - schema.names[schemaName] = {}; - } - const namedSchema = schema.names[schemaName]; - namedSchema[propertyKey] = copyOptions; - } - }; - } - }); - - // node_modules/.pnpm/webcrypto-core@1.7.7/node_modules/webcrypto-core/build/webcrypto-core.es.js - function isJWK(data) { - return typeof data === "object" && "kty" in data; - } - var import_pvtsutils4, import_pvtsutils5, CryptoError, AlgorithmError, UnsupportedOperationError, OperationError, RequiredPropertyError, ProviderCrypto, AesProvider, AesCbcProvider, AesCmacProvider, AesCtrProvider, AesEcbProvider, AesGcmProvider, AesKwProvider, DesProvider, RsaProvider, RsaSsaProvider, RsaPssProvider, RsaOaepProvider, EllipticProvider, EcdsaProvider, KEY_TYPES, CryptoKey, EcdhProvider, EcdhEsProvider, EdDsaProvider, ObjectIdentifier2, AlgorithmIdentifier, PrivateKeyInfo, PublicKeyInfo, JsonBase64UrlArrayBufferConverter, AsnIntegerArrayBufferConverter, RsaPrivateKey, RsaPublicKey, EcPublicKey, EcPrivateKey, AsnIntegerWithoutPaddingConverter, index$2, EcUtils, EcDsaSignature, OneAsymmetricKey, EdPrivateKey, EdPublicKey, CurvePrivateKey, idSecp256r1, idEllipticCurve, idSecp384r1, idSecp521r1, idSecp256k1, idVersionOne, idBrainpoolP160r1, idBrainpoolP160t1, idBrainpoolP192r1, idBrainpoolP192t1, idBrainpoolP224r1, idBrainpoolP224t1, idBrainpoolP256r1, idBrainpoolP256t1, idBrainpoolP320r1, idBrainpoolP320t1, idBrainpoolP384r1, idBrainpoolP384t1, idBrainpoolP512r1, idBrainpoolP512t1, idX25519, idX448, idEd25519, idEd448, index$1, EcCurves, HmacProvider, Pbkdf2Provider, HkdfProvider, ShakeProvider, Shake128Provider, Shake256Provider, Crypto, ProviderStorage, SubtleCrypto; - var init_webcrypto_core_es = __esm({ - "node_modules/.pnpm/webcrypto-core@1.7.7/node_modules/webcrypto-core/build/webcrypto-core.es.js"() { - import_pvtsutils4 = __toESM(require_build()); - import_pvtsutils5 = __toESM(require_build()); - init_es2015(); - init_tslib_es6(); - init_index_es2(); - init_index_es(); - CryptoError = class extends Error { - }; - AlgorithmError = class extends CryptoError { - }; - UnsupportedOperationError = class extends CryptoError { - constructor(methodName) { - super(`Unsupported operation: ${methodName ? `${methodName}` : ""}`); - } - }; - OperationError = class extends CryptoError { - }; - RequiredPropertyError = class extends CryptoError { - constructor(propName) { - super(`${propName}: Missing required property`); - } - }; - ProviderCrypto = class { - async digest(...args) { - this.checkDigest.apply(this, args); - return this.onDigest.apply(this, args); - } - checkDigest(algorithm, data) { - this.checkAlgorithmName(algorithm); - } - async onDigest(algorithm, data) { - throw new UnsupportedOperationError("digest"); - } - async generateKey(...args) { - this.checkGenerateKey.apply(this, args); - return this.onGenerateKey.apply(this, args); - } - checkGenerateKey(algorithm, extractable, keyUsages, ...args) { - this.checkAlgorithmName(algorithm); - this.checkGenerateKeyParams(algorithm); - if (!(keyUsages && keyUsages.length)) { - throw new TypeError(`Usages cannot be empty when creating a key.`); - } - let allowedUsages; - if (Array.isArray(this.usages)) { - allowedUsages = this.usages; - } else { - allowedUsages = this.usages.privateKey.concat(this.usages.publicKey); - } - this.checkKeyUsages(keyUsages, allowedUsages); - } - checkGenerateKeyParams(algorithm) { - } - async onGenerateKey(algorithm, extractable, keyUsages, ...args) { - throw new UnsupportedOperationError("generateKey"); - } - async sign(...args) { - this.checkSign.apply(this, args); - return this.onSign.apply(this, args); - } - checkSign(algorithm, key, data, ...args) { - this.checkAlgorithmName(algorithm); - this.checkAlgorithmParams(algorithm); - this.checkCryptoKey(key, "sign"); - } - async onSign(algorithm, key, data, ...args) { - throw new UnsupportedOperationError("sign"); - } - async verify(...args) { - this.checkVerify.apply(this, args); - return this.onVerify.apply(this, args); - } - checkVerify(algorithm, key, signature, data, ...args) { - this.checkAlgorithmName(algorithm); - this.checkAlgorithmParams(algorithm); - this.checkCryptoKey(key, "verify"); - } - async onVerify(algorithm, key, signature, data, ...args) { - throw new UnsupportedOperationError("verify"); - } - async encrypt(...args) { - this.checkEncrypt.apply(this, args); - return this.onEncrypt.apply(this, args); - } - checkEncrypt(algorithm, key, data, options = {}, ...args) { - this.checkAlgorithmName(algorithm); - this.checkAlgorithmParams(algorithm); - this.checkCryptoKey(key, options.keyUsage ? "encrypt" : void 0); - } - async onEncrypt(algorithm, key, data, ...args) { - throw new UnsupportedOperationError("encrypt"); - } - async decrypt(...args) { - this.checkDecrypt.apply(this, args); - return this.onDecrypt.apply(this, args); - } - checkDecrypt(algorithm, key, data, options = {}, ...args) { - this.checkAlgorithmName(algorithm); - this.checkAlgorithmParams(algorithm); - this.checkCryptoKey(key, options.keyUsage ? "decrypt" : void 0); - } - async onDecrypt(algorithm, key, data, ...args) { - throw new UnsupportedOperationError("decrypt"); - } - async deriveBits(...args) { - this.checkDeriveBits.apply(this, args); - return this.onDeriveBits.apply(this, args); - } - checkDeriveBits(algorithm, baseKey, length, options = {}, ...args) { - this.checkAlgorithmName(algorithm); - this.checkAlgorithmParams(algorithm); - this.checkCryptoKey(baseKey, options.keyUsage ? "deriveBits" : void 0); - if (length % 8 !== 0) { - throw new OperationError("length: Is not multiple of 8"); - } - } - async onDeriveBits(algorithm, baseKey, length, ...args) { - throw new UnsupportedOperationError("deriveBits"); - } - async exportKey(...args) { - this.checkExportKey.apply(this, args); - return this.onExportKey.apply(this, args); - } - checkExportKey(format2, key, ...args) { - this.checkKeyFormat(format2); - this.checkCryptoKey(key); - if (!key.extractable) { - throw new CryptoError("key: Is not extractable"); - } - } - async onExportKey(format2, key, ...args) { - throw new UnsupportedOperationError("exportKey"); - } - async importKey(...args) { - this.checkImportKey.apply(this, args); - return this.onImportKey.apply(this, args); - } - checkImportKey(format2, keyData, algorithm, extractable, keyUsages, ...args) { - this.checkKeyFormat(format2); - this.checkKeyData(format2, keyData); - this.checkAlgorithmName(algorithm); - this.checkImportParams(algorithm); - if (Array.isArray(this.usages)) { - this.checkKeyUsages(keyUsages, this.usages); - } - } - async onImportKey(format2, keyData, algorithm, extractable, keyUsages, ...args) { - throw new UnsupportedOperationError("importKey"); - } - checkAlgorithmName(algorithm) { - if (algorithm.name.toLowerCase() !== this.name.toLowerCase()) { - throw new AlgorithmError("Unrecognized name"); - } - } - checkAlgorithmParams(algorithm) { - } - checkDerivedKeyParams(algorithm) { - } - checkKeyUsages(usages, allowed) { - for (const usage of usages) { - if (allowed.indexOf(usage) === -1) { - throw new TypeError("Cannot create a key using the specified key usages"); - } - } - } - checkCryptoKey(key, keyUsage) { - this.checkAlgorithmName(key.algorithm); - if (keyUsage && key.usages.indexOf(keyUsage) === -1) { - throw new CryptoError(`key does not match that of operation`); - } - } - checkRequiredProperty(data, propName) { - if (!(propName in data)) { - throw new RequiredPropertyError(propName); - } - } - checkHashAlgorithm(algorithm, hashAlgorithms) { - for (const item of hashAlgorithms) { - if (item.toLowerCase() === algorithm.name.toLowerCase()) { - return; - } - } - throw new OperationError(`hash: Must be one of ${hashAlgorithms.join(", ")}`); - } - checkImportParams(algorithm) { - } - checkKeyFormat(format2) { - switch (format2) { - case "raw": - case "pkcs8": - case "spki": - case "jwk": - break; - default: - throw new TypeError("format: Is invalid value. Must be 'jwk', 'raw', 'spki', or 'pkcs8'"); - } - } - checkKeyData(format2, keyData) { - if (!keyData) { - throw new TypeError("keyData: Cannot be empty on empty on key importing"); - } - if (format2 === "jwk") { - if (!isJWK(keyData)) { - throw new TypeError("keyData: Is not JsonWebToken"); - } - } else if (!import_pvtsutils4.BufferSourceConverter.isBufferSource(keyData)) { - throw new TypeError("keyData: Is not ArrayBufferView or ArrayBuffer"); - } - } - prepareData(data) { - return import_pvtsutils4.BufferSourceConverter.toArrayBuffer(data); - } - }; - AesProvider = class extends ProviderCrypto { - checkGenerateKeyParams(algorithm) { - this.checkRequiredProperty(algorithm, "length"); - if (typeof algorithm.length !== "number") { - throw new TypeError("length: Is not of type Number"); - } - switch (algorithm.length) { - case 128: - case 192: - case 256: - break; - default: - throw new TypeError("length: Must be 128, 192, or 256"); - } - } - checkDerivedKeyParams(algorithm) { - this.checkGenerateKeyParams(algorithm); - } - }; - AesCbcProvider = class extends AesProvider { - constructor() { - super(...arguments); - this.name = "AES-CBC"; - this.usages = ["encrypt", "decrypt", "wrapKey", "unwrapKey"]; - } - checkAlgorithmParams(algorithm) { - this.checkRequiredProperty(algorithm, "iv"); - if (!(algorithm.iv instanceof ArrayBuffer || ArrayBuffer.isView(algorithm.iv))) { - throw new TypeError("iv: Is not of type '(ArrayBuffer or ArrayBufferView)'"); - } - if (algorithm.iv.byteLength !== 16) { - throw new TypeError("iv: Must have length 16 bytes"); - } - } - }; - AesCmacProvider = class extends AesProvider { - constructor() { - super(...arguments); - this.name = "AES-CMAC"; - this.usages = ["sign", "verify"]; - } - checkAlgorithmParams(algorithm) { - this.checkRequiredProperty(algorithm, "length"); - if (typeof algorithm.length !== "number") { - throw new TypeError("length: Is not a Number"); - } - if (algorithm.length < 1) { - throw new OperationError("length: Must be more than 0"); - } - } - }; - AesCtrProvider = class extends AesProvider { - constructor() { - super(...arguments); - this.name = "AES-CTR"; - this.usages = ["encrypt", "decrypt", "wrapKey", "unwrapKey"]; - } - checkAlgorithmParams(algorithm) { - this.checkRequiredProperty(algorithm, "counter"); - if (!(algorithm.counter instanceof ArrayBuffer || ArrayBuffer.isView(algorithm.counter))) { - throw new TypeError("counter: Is not of type '(ArrayBuffer or ArrayBufferView)'"); - } - if (algorithm.counter.byteLength !== 16) { - throw new TypeError("iv: Must have length 16 bytes"); - } - this.checkRequiredProperty(algorithm, "length"); - if (typeof algorithm.length !== "number") { - throw new TypeError("length: Is not a Number"); - } - if (algorithm.length < 1) { - throw new OperationError("length: Must be more than 0"); - } - } - }; - AesEcbProvider = class extends AesProvider { - constructor() { - super(...arguments); - this.name = "AES-ECB"; - this.usages = ["encrypt", "decrypt", "wrapKey", "unwrapKey"]; - } - }; - AesGcmProvider = class extends AesProvider { - constructor() { - super(...arguments); - this.name = "AES-GCM"; - this.usages = ["encrypt", "decrypt", "wrapKey", "unwrapKey"]; - } - checkAlgorithmParams(algorithm) { - this.checkRequiredProperty(algorithm, "iv"); - if (!(algorithm.iv instanceof ArrayBuffer || ArrayBuffer.isView(algorithm.iv))) { - throw new TypeError("iv: Is not of type '(ArrayBuffer or ArrayBufferView)'"); - } - if (algorithm.iv.byteLength < 1) { - throw new OperationError("iv: Must have length more than 0 and less than 2^64 - 1"); - } - if (!("tagLength" in algorithm)) { - algorithm.tagLength = 128; - } - switch (algorithm.tagLength) { - case 32: - case 64: - case 96: - case 104: - case 112: - case 120: - case 128: - break; - default: - throw new OperationError("tagLength: Must be one of 32, 64, 96, 104, 112, 120 or 128"); - } - } - }; - AesKwProvider = class extends AesProvider { - constructor() { - super(...arguments); - this.name = "AES-KW"; - this.usages = ["wrapKey", "unwrapKey"]; - } - }; - DesProvider = class extends ProviderCrypto { - constructor() { - super(...arguments); - this.usages = ["encrypt", "decrypt", "wrapKey", "unwrapKey"]; - } - checkAlgorithmParams(algorithm) { - if (this.ivSize) { - this.checkRequiredProperty(algorithm, "iv"); - if (!(algorithm.iv instanceof ArrayBuffer || ArrayBuffer.isView(algorithm.iv))) { - throw new TypeError("iv: Is not of type '(ArrayBuffer or ArrayBufferView)'"); - } - if (algorithm.iv.byteLength !== this.ivSize) { - throw new TypeError(`iv: Must have length ${this.ivSize} bytes`); - } - } - } - checkGenerateKeyParams(algorithm) { - this.checkRequiredProperty(algorithm, "length"); - if (typeof algorithm.length !== "number") { - throw new TypeError("length: Is not of type Number"); - } - if (algorithm.length !== this.keySizeBits) { - throw new OperationError(`algorithm.length: Must be ${this.keySizeBits}`); - } - } - checkDerivedKeyParams(algorithm) { - this.checkGenerateKeyParams(algorithm); - } - }; - RsaProvider = class extends ProviderCrypto { - constructor() { - super(...arguments); - this.hashAlgorithms = ["SHA-1", "SHA-256", "SHA-384", "SHA-512"]; - } - checkGenerateKeyParams(algorithm) { - this.checkRequiredProperty(algorithm, "hash"); - this.checkHashAlgorithm(algorithm.hash, this.hashAlgorithms); - this.checkRequiredProperty(algorithm, "publicExponent"); - if (!(algorithm.publicExponent && algorithm.publicExponent instanceof Uint8Array)) { - throw new TypeError("publicExponent: Missing or not a Uint8Array"); - } - const publicExponent = import_pvtsutils4.Convert.ToBase64(algorithm.publicExponent); - if (!(publicExponent === "Aw==" || publicExponent === "AQAB")) { - throw new TypeError("publicExponent: Must be [3] or [1,0,1]"); - } - this.checkRequiredProperty(algorithm, "modulusLength"); - if (algorithm.modulusLength % 8 || algorithm.modulusLength < 256 || algorithm.modulusLength > 16384) { - throw new TypeError("The modulus length must be a multiple of 8 bits and >= 256 and <= 16384"); - } - } - checkImportParams(algorithm) { - this.checkRequiredProperty(algorithm, "hash"); - this.checkHashAlgorithm(algorithm.hash, this.hashAlgorithms); - } - }; - RsaSsaProvider = class extends RsaProvider { - constructor() { - super(...arguments); - this.name = "RSASSA-PKCS1-v1_5"; - this.usages = { - privateKey: ["sign"], - publicKey: ["verify"] - }; - } - }; - RsaPssProvider = class extends RsaProvider { - constructor() { - super(...arguments); - this.name = "RSA-PSS"; - this.usages = { - privateKey: ["sign"], - publicKey: ["verify"] - }; - } - checkAlgorithmParams(algorithm) { - this.checkRequiredProperty(algorithm, "saltLength"); - if (typeof algorithm.saltLength !== "number") { - throw new TypeError("saltLength: Is not a Number"); - } - if (algorithm.saltLength < 0) { - throw new RangeError("saltLength: Must be positive number"); - } - } - }; - RsaOaepProvider = class extends RsaProvider { - constructor() { - super(...arguments); - this.name = "RSA-OAEP"; - this.usages = { - privateKey: ["decrypt", "unwrapKey"], - publicKey: ["encrypt", "wrapKey"] - }; - } - checkAlgorithmParams(algorithm) { - if (algorithm.label && !(algorithm.label instanceof ArrayBuffer || ArrayBuffer.isView(algorithm.label))) { - throw new TypeError("label: Is not of type '(ArrayBuffer or ArrayBufferView)'"); - } - } - }; - EllipticProvider = class extends ProviderCrypto { - checkGenerateKeyParams(algorithm) { - this.checkRequiredProperty(algorithm, "namedCurve"); - this.checkNamedCurve(algorithm.namedCurve); - } - checkNamedCurve(namedCurve) { - for (const item of this.namedCurves) { - if (item.toLowerCase() === namedCurve.toLowerCase()) { - return; - } - } - throw new OperationError(`namedCurve: Must be one of ${this.namedCurves.join(", ")}`); - } - }; - EcdsaProvider = class extends EllipticProvider { - constructor() { - super(...arguments); - this.name = "ECDSA"; - this.hashAlgorithms = ["SHA-1", "SHA-256", "SHA-384", "SHA-512"]; - this.usages = { - privateKey: ["sign"], - publicKey: ["verify"] - }; - this.namedCurves = ["P-256", "P-384", "P-521", "K-256"]; - } - checkAlgorithmParams(algorithm) { - this.checkRequiredProperty(algorithm, "hash"); - this.checkHashAlgorithm(algorithm.hash, this.hashAlgorithms); - } - }; - KEY_TYPES = ["secret", "private", "public"]; - CryptoKey = class { - static create(algorithm, type, extractable, usages) { - const key = new this(); - key.algorithm = algorithm; - key.type = type; - key.extractable = extractable; - key.usages = usages; - return key; - } - static isKeyType(data) { - return KEY_TYPES.indexOf(data) !== -1; - } - get [Symbol.toStringTag]() { - return "CryptoKey"; - } - }; - EcdhProvider = class extends EllipticProvider { - constructor() { - super(...arguments); - this.name = "ECDH"; - this.usages = { - privateKey: ["deriveBits", "deriveKey"], - publicKey: [] - }; - this.namedCurves = ["P-256", "P-384", "P-521", "K-256"]; - } - checkAlgorithmParams(algorithm) { - this.checkRequiredProperty(algorithm, "public"); - if (!(algorithm.public instanceof CryptoKey)) { - throw new TypeError("public: Is not a CryptoKey"); - } - if (algorithm.public.type !== "public") { - throw new OperationError("public: Is not a public key"); - } - if (algorithm.public.algorithm.name !== this.name) { - throw new OperationError(`public: Is not ${this.name} key`); - } - } - }; - EcdhEsProvider = class extends EcdhProvider { - constructor() { - super(...arguments); - this.name = "ECDH-ES"; - this.namedCurves = ["X25519", "X448"]; - } - }; - EdDsaProvider = class extends EllipticProvider { - constructor() { - super(...arguments); - this.name = "EdDSA"; - this.usages = { - privateKey: ["sign"], - publicKey: ["verify"] - }; - this.namedCurves = ["Ed25519", "Ed448"]; - } - }; - ObjectIdentifier2 = class ObjectIdentifier3 { - constructor(value) { - if (value) { - this.value = value; - } - } - }; - __decorate([ - AsnProp({ type: AsnPropTypes.ObjectIdentifier }) - ], ObjectIdentifier2.prototype, "value", void 0); - ObjectIdentifier2 = __decorate([ - AsnType({ type: AsnTypeTypes.Choice }) - ], ObjectIdentifier2); - AlgorithmIdentifier = class { - constructor(params) { - Object.assign(this, params); - } - }; - __decorate([ - AsnProp({ - type: AsnPropTypes.ObjectIdentifier - }) - ], AlgorithmIdentifier.prototype, "algorithm", void 0); - __decorate([ - AsnProp({ - type: AsnPropTypes.Any, - optional: true - }) - ], AlgorithmIdentifier.prototype, "parameters", void 0); - PrivateKeyInfo = class { - constructor() { - this.version = 0; - this.privateKeyAlgorithm = new AlgorithmIdentifier(); - this.privateKey = new ArrayBuffer(0); - } - }; - __decorate([ - AsnProp({ type: AsnPropTypes.Integer }) - ], PrivateKeyInfo.prototype, "version", void 0); - __decorate([ - AsnProp({ type: AlgorithmIdentifier }) - ], PrivateKeyInfo.prototype, "privateKeyAlgorithm", void 0); - __decorate([ - AsnProp({ type: AsnPropTypes.OctetString }) - ], PrivateKeyInfo.prototype, "privateKey", void 0); - __decorate([ - AsnProp({ type: AsnPropTypes.Any, optional: true }) - ], PrivateKeyInfo.prototype, "attributes", void 0); - PublicKeyInfo = class { - constructor() { - this.publicKeyAlgorithm = new AlgorithmIdentifier(); - this.publicKey = new ArrayBuffer(0); - } - }; - __decorate([ - AsnProp({ type: AlgorithmIdentifier }) - ], PublicKeyInfo.prototype, "publicKeyAlgorithm", void 0); - __decorate([ - AsnProp({ type: AsnPropTypes.BitString }) - ], PublicKeyInfo.prototype, "publicKey", void 0); - JsonBase64UrlArrayBufferConverter = { - fromJSON: (value) => import_pvtsutils4.Convert.FromBase64Url(value), - toJSON: (value) => import_pvtsutils4.Convert.ToBase64Url(new Uint8Array(value)) - }; - AsnIntegerArrayBufferConverter = { - fromASN: (value) => { - const valueHex = value.valueBlock.valueHex; - return !new Uint8Array(valueHex)[0] ? value.valueBlock.valueHex.slice(1) : value.valueBlock.valueHex; - }, - toASN: (value) => { - const valueHex = new Uint8Array(value)[0] > 127 ? (0, import_pvtsutils4.combine)(new Uint8Array([0]).buffer, value) : value; - return new Integer({ valueHex }); - } - }; - RsaPrivateKey = class { - constructor() { - this.version = 0; - this.modulus = new ArrayBuffer(0); - this.publicExponent = new ArrayBuffer(0); - this.privateExponent = new ArrayBuffer(0); - this.prime1 = new ArrayBuffer(0); - this.prime2 = new ArrayBuffer(0); - this.exponent1 = new ArrayBuffer(0); - this.exponent2 = new ArrayBuffer(0); - this.coefficient = new ArrayBuffer(0); - } - }; - __decorate([ - AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerConverter }) - ], RsaPrivateKey.prototype, "version", void 0); - __decorate([ - AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerArrayBufferConverter }), - JsonProp({ name: "n", converter: JsonBase64UrlArrayBufferConverter }) - ], RsaPrivateKey.prototype, "modulus", void 0); - __decorate([ - AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerArrayBufferConverter }), - JsonProp({ name: "e", converter: JsonBase64UrlArrayBufferConverter }) - ], RsaPrivateKey.prototype, "publicExponent", void 0); - __decorate([ - AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerArrayBufferConverter }), - JsonProp({ name: "d", converter: JsonBase64UrlArrayBufferConverter }) - ], RsaPrivateKey.prototype, "privateExponent", void 0); - __decorate([ - AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerArrayBufferConverter }), - JsonProp({ name: "p", converter: JsonBase64UrlArrayBufferConverter }) - ], RsaPrivateKey.prototype, "prime1", void 0); - __decorate([ - AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerArrayBufferConverter }), - JsonProp({ name: "q", converter: JsonBase64UrlArrayBufferConverter }) - ], RsaPrivateKey.prototype, "prime2", void 0); - __decorate([ - AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerArrayBufferConverter }), - JsonProp({ name: "dp", converter: JsonBase64UrlArrayBufferConverter }) - ], RsaPrivateKey.prototype, "exponent1", void 0); - __decorate([ - AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerArrayBufferConverter }), - JsonProp({ name: "dq", converter: JsonBase64UrlArrayBufferConverter }) - ], RsaPrivateKey.prototype, "exponent2", void 0); - __decorate([ - AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerArrayBufferConverter }), - JsonProp({ name: "qi", converter: JsonBase64UrlArrayBufferConverter }) - ], RsaPrivateKey.prototype, "coefficient", void 0); - __decorate([ - AsnProp({ type: AsnPropTypes.Any, optional: true }) - ], RsaPrivateKey.prototype, "otherPrimeInfos", void 0); - RsaPublicKey = class { - constructor() { - this.modulus = new ArrayBuffer(0); - this.publicExponent = new ArrayBuffer(0); - } - }; - __decorate([ - AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerArrayBufferConverter }), - JsonProp({ name: "n", converter: JsonBase64UrlArrayBufferConverter }) - ], RsaPublicKey.prototype, "modulus", void 0); - __decorate([ - AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerArrayBufferConverter }), - JsonProp({ name: "e", converter: JsonBase64UrlArrayBufferConverter }) - ], RsaPublicKey.prototype, "publicExponent", void 0); - EcPublicKey = class EcPublicKey2 { - constructor(value) { - this.value = new ArrayBuffer(0); - if (value) { - this.value = value; - } - } - toJSON() { - let bytes = new Uint8Array(this.value); - if (bytes[0] !== 4) { - throw new CryptoError("Wrong ECPoint. Current version supports only Uncompressed (0x04) point"); - } - bytes = new Uint8Array(this.value.slice(1)); - const size = bytes.length / 2; - const offset = 0; - const json = { - x: import_pvtsutils4.Convert.ToBase64Url(bytes.buffer.slice(offset, offset + size)), - y: import_pvtsutils4.Convert.ToBase64Url(bytes.buffer.slice(offset + size, offset + size + size)) - }; - return json; - } - fromJSON(json) { - if (!("x" in json)) { - throw new Error("x: Missing required property"); - } - if (!("y" in json)) { - throw new Error("y: Missing required property"); - } - const x = import_pvtsutils4.Convert.FromBase64Url(json.x); - const y = import_pvtsutils4.Convert.FromBase64Url(json.y); - const value = (0, import_pvtsutils4.combine)(new Uint8Array([4]).buffer, x, y); - this.value = new Uint8Array(value).buffer; - return this; - } - }; - __decorate([ - AsnProp({ type: AsnPropTypes.OctetString }) - ], EcPublicKey.prototype, "value", void 0); - EcPublicKey = __decorate([ - AsnType({ type: AsnTypeTypes.Choice }) - ], EcPublicKey); - EcPrivateKey = class { - constructor() { - this.version = 1; - this.privateKey = new ArrayBuffer(0); - } - fromJSON(json) { - if (!("d" in json)) { - throw new Error("d: Missing required property"); - } - this.privateKey = import_pvtsutils4.Convert.FromBase64Url(json.d); - if ("x" in json) { - const publicKey = new EcPublicKey(); - publicKey.fromJSON(json); - const asn = AsnSerializer.toASN(publicKey); - if ("valueHex" in asn.valueBlock) { - this.publicKey = asn.valueBlock.valueHex; - } - } - return this; - } - toJSON() { - const jwk = {}; - jwk.d = import_pvtsutils4.Convert.ToBase64Url(this.privateKey); - if (this.publicKey) { - Object.assign(jwk, new EcPublicKey(this.publicKey).toJSON()); - } - return jwk; - } - }; - __decorate([ - AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerConverter }) - ], EcPrivateKey.prototype, "version", void 0); - __decorate([ - AsnProp({ type: AsnPropTypes.OctetString }) - ], EcPrivateKey.prototype, "privateKey", void 0); - __decorate([ - AsnProp({ context: 0, type: AsnPropTypes.Any, optional: true }) - ], EcPrivateKey.prototype, "parameters", void 0); - __decorate([ - AsnProp({ context: 1, type: AsnPropTypes.BitString, optional: true }) - ], EcPrivateKey.prototype, "publicKey", void 0); - AsnIntegerWithoutPaddingConverter = { - fromASN: (value) => { - const bytes = new Uint8Array(value.valueBlock.valueHex); - return bytes[0] === 0 ? bytes.buffer.slice(1) : bytes.buffer; - }, - toASN: (value) => { - const bytes = new Uint8Array(value); - if (bytes[0] > 127) { - const newValue = new Uint8Array(bytes.length + 1); - newValue.set(bytes, 1); - return new Integer({ valueHex: newValue.buffer }); - } - return new Integer({ valueHex: value }); - } - }; - index$2 = /* @__PURE__ */ Object.freeze({ - __proto__: null, - AsnIntegerWithoutPaddingConverter - }); - EcUtils = class { - static decodePoint(data, pointSize) { - const view = import_pvtsutils4.BufferSourceConverter.toUint8Array(data); - if (view.length === 0 || view[0] !== 4) { - throw new Error("Only uncompressed point format supported"); - } - const n = (view.length - 1) / 2; - if (n !== Math.ceil(pointSize / 8)) { - throw new Error("Point does not match field size"); - } - const xb = view.slice(1, n + 1); - const yb = view.slice(n + 1, n + 1 + n); - return { x: xb, y: yb }; - } - static encodePoint(point, pointSize) { - const size = Math.ceil(pointSize / 8); - if (point.x.byteLength !== size || point.y.byteLength !== size) { - throw new Error("X,Y coordinates don't match point size criteria"); - } - const x = import_pvtsutils4.BufferSourceConverter.toUint8Array(point.x); - const y = import_pvtsutils4.BufferSourceConverter.toUint8Array(point.y); - const res = new Uint8Array(size * 2 + 1); - res[0] = 4; - res.set(x, 1); - res.set(y, size + 1); - return res; - } - static getSize(pointSize) { - return Math.ceil(pointSize / 8); - } - static encodeSignature(signature, pointSize) { - const size = this.getSize(pointSize); - const r = import_pvtsutils4.BufferSourceConverter.toUint8Array(signature.r); - const s = import_pvtsutils4.BufferSourceConverter.toUint8Array(signature.s); - const res = new Uint8Array(size * 2); - res.set(this.padStart(r, size)); - res.set(this.padStart(s, size), size); - return res; - } - static decodeSignature(data, pointSize) { - const size = this.getSize(pointSize); - const view = import_pvtsutils4.BufferSourceConverter.toUint8Array(data); - if (view.length !== size * 2) { - throw new Error("Incorrect size of the signature"); - } - const r = view.slice(0, size); - const s = view.slice(size); - return { - r: this.trimStart(r), - s: this.trimStart(s) - }; - } - static trimStart(data) { - let i = 0; - while (i < data.length - 1 && data[i] === 0) { - i++; - } - if (i === 0) { - return data; - } - return data.slice(i, data.length); - } - static padStart(data, size) { - if (size === data.length) { - return data; - } - const res = new Uint8Array(size); - res.set(data, size - data.length); - return res; - } - }; - EcDsaSignature = class { - constructor() { - this.r = new ArrayBuffer(0); - this.s = new ArrayBuffer(0); - } - static fromWebCryptoSignature(value) { - const pointSize = value.byteLength / 2; - const point = EcUtils.decodeSignature(value, pointSize * 8); - const ecSignature = new EcDsaSignature(); - ecSignature.r = import_pvtsutils4.BufferSourceConverter.toArrayBuffer(point.r); - ecSignature.s = import_pvtsutils4.BufferSourceConverter.toArrayBuffer(point.s); - return ecSignature; - } - toWebCryptoSignature(pointSize) { - pointSize !== null && pointSize !== void 0 ? pointSize : pointSize = Math.max(this.r.byteLength, this.s.byteLength) * 8; - const signature = EcUtils.encodeSignature(this, pointSize); - return signature.buffer; - } - }; - __decorate([ - AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerWithoutPaddingConverter }) - ], EcDsaSignature.prototype, "r", void 0); - __decorate([ - AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerWithoutPaddingConverter }) - ], EcDsaSignature.prototype, "s", void 0); - OneAsymmetricKey = class extends PrivateKeyInfo { - }; - __decorate([ - AsnProp({ context: 1, implicit: true, type: AsnPropTypes.BitString, optional: true }) - ], OneAsymmetricKey.prototype, "publicKey", void 0); - EdPrivateKey = class EdPrivateKey2 { - constructor() { - this.value = new ArrayBuffer(0); - } - fromJSON(json) { - if (!json.d) { - throw new Error("d: Missing required property"); - } - this.value = import_pvtsutils4.Convert.FromBase64Url(json.d); - return this; - } - toJSON() { - const jwk = { - d: import_pvtsutils4.Convert.ToBase64Url(this.value) - }; - return jwk; - } - }; - __decorate([ - AsnProp({ type: AsnPropTypes.OctetString }) - ], EdPrivateKey.prototype, "value", void 0); - EdPrivateKey = __decorate([ - AsnType({ type: AsnTypeTypes.Choice }) - ], EdPrivateKey); - EdPublicKey = class EdPublicKey2 { - constructor(value) { - this.value = new ArrayBuffer(0); - if (value) { - this.value = value; - } - } - toJSON() { - const json = { - x: import_pvtsutils4.Convert.ToBase64Url(this.value) - }; - return json; - } - fromJSON(json) { - if (!("x" in json)) { - throw new Error("x: Missing required property"); - } - this.value = import_pvtsutils4.Convert.FromBase64Url(json.x); - return this; - } - }; - __decorate([ - AsnProp({ type: AsnPropTypes.BitString }) - ], EdPublicKey.prototype, "value", void 0); - EdPublicKey = __decorate([ - AsnType({ type: AsnTypeTypes.Choice }) - ], EdPublicKey); - CurvePrivateKey = class CurvePrivateKey2 { - }; - __decorate([ - AsnProp({ type: AsnPropTypes.OctetString }), - JsonProp({ type: JsonPropTypes.String, converter: JsonBase64UrlArrayBufferConverter }) - ], CurvePrivateKey.prototype, "d", void 0); - CurvePrivateKey = __decorate([ - AsnType({ type: AsnTypeTypes.Choice }) - ], CurvePrivateKey); - idSecp256r1 = "1.2.840.10045.3.1.7"; - idEllipticCurve = "1.3.132.0"; - idSecp384r1 = `${idEllipticCurve}.34`; - idSecp521r1 = `${idEllipticCurve}.35`; - idSecp256k1 = `${idEllipticCurve}.10`; - idVersionOne = "1.3.36.3.3.2.8.1.1"; - idBrainpoolP160r1 = `${idVersionOne}.1`; - idBrainpoolP160t1 = `${idVersionOne}.2`; - idBrainpoolP192r1 = `${idVersionOne}.3`; - idBrainpoolP192t1 = `${idVersionOne}.4`; - idBrainpoolP224r1 = `${idVersionOne}.5`; - idBrainpoolP224t1 = `${idVersionOne}.6`; - idBrainpoolP256r1 = `${idVersionOne}.7`; - idBrainpoolP256t1 = `${idVersionOne}.8`; - idBrainpoolP320r1 = `${idVersionOne}.9`; - idBrainpoolP320t1 = `${idVersionOne}.10`; - idBrainpoolP384r1 = `${idVersionOne}.11`; - idBrainpoolP384t1 = `${idVersionOne}.12`; - idBrainpoolP512r1 = `${idVersionOne}.13`; - idBrainpoolP512t1 = `${idVersionOne}.14`; - idX25519 = "1.3.101.110"; - idX448 = "1.3.101.111"; - idEd25519 = "1.3.101.112"; - idEd448 = "1.3.101.113"; - index$1 = /* @__PURE__ */ Object.freeze({ - __proto__: null, - AlgorithmIdentifier, - get CurvePrivateKey() { - return CurvePrivateKey; - }, - EcDsaSignature, - EcPrivateKey, - get EcPublicKey() { - return EcPublicKey; - }, - get EdPrivateKey() { - return EdPrivateKey; - }, - get EdPublicKey() { - return EdPublicKey; - }, - get ObjectIdentifier() { - return ObjectIdentifier2; - }, - OneAsymmetricKey, - PrivateKeyInfo, - PublicKeyInfo, - RsaPrivateKey, - RsaPublicKey, - converters: index$2, - idBrainpoolP160r1, - idBrainpoolP160t1, - idBrainpoolP192r1, - idBrainpoolP192t1, - idBrainpoolP224r1, - idBrainpoolP224t1, - idBrainpoolP256r1, - idBrainpoolP256t1, - idBrainpoolP320r1, - idBrainpoolP320t1, - idBrainpoolP384r1, - idBrainpoolP384t1, - idBrainpoolP512r1, - idBrainpoolP512t1, - idEd25519, - idEd448, - idEllipticCurve, - idSecp256k1, - idSecp256r1, - idSecp384r1, - idSecp521r1, - idVersionOne, - idX25519, - idX448 - }); - EcCurves = class { - constructor() { - } - static register(item) { - const oid = new ObjectIdentifier2(); - oid.value = item.id; - const raw = AsnConvert.serialize(oid); - this.items.push({ - ...item, - raw - }); - this.names.push(item.name); - } - static find(nameOrId) { - nameOrId = nameOrId.toUpperCase(); - for (const item of this.items) { - if (item.name.toUpperCase() === nameOrId || item.id.toUpperCase() === nameOrId) { - return item; - } - } - return null; - } - static get(nameOrId) { - const res = this.find(nameOrId); - if (!res) { - throw new Error(`Unsupported EC named curve '${nameOrId}'`); - } - return res; - } - }; - EcCurves.items = []; - EcCurves.names = []; - EcCurves.register({ name: "P-256", id: idSecp256r1, size: 256 }); - EcCurves.register({ name: "P-384", id: idSecp384r1, size: 384 }); - EcCurves.register({ name: "P-521", id: idSecp521r1, size: 521 }); - EcCurves.register({ name: "K-256", id: idSecp256k1, size: 256 }); - EcCurves.register({ name: "brainpoolP160r1", id: idBrainpoolP160r1, size: 160 }); - EcCurves.register({ name: "brainpoolP160t1", id: idBrainpoolP160t1, size: 160 }); - EcCurves.register({ name: "brainpoolP192r1", id: idBrainpoolP192r1, size: 192 }); - EcCurves.register({ name: "brainpoolP192t1", id: idBrainpoolP192t1, size: 192 }); - EcCurves.register({ name: "brainpoolP224r1", id: idBrainpoolP224r1, size: 224 }); - EcCurves.register({ name: "brainpoolP224t1", id: idBrainpoolP224t1, size: 224 }); - EcCurves.register({ name: "brainpoolP256r1", id: idBrainpoolP256r1, size: 256 }); - EcCurves.register({ name: "brainpoolP256t1", id: idBrainpoolP256t1, size: 256 }); - EcCurves.register({ name: "brainpoolP320r1", id: idBrainpoolP320r1, size: 320 }); - EcCurves.register({ name: "brainpoolP320t1", id: idBrainpoolP320t1, size: 320 }); - EcCurves.register({ name: "brainpoolP384r1", id: idBrainpoolP384r1, size: 384 }); - EcCurves.register({ name: "brainpoolP384t1", id: idBrainpoolP384t1, size: 384 }); - EcCurves.register({ name: "brainpoolP512r1", id: idBrainpoolP512r1, size: 512 }); - EcCurves.register({ name: "brainpoolP512t1", id: idBrainpoolP512t1, size: 512 }); - HmacProvider = class extends ProviderCrypto { - constructor() { - super(...arguments); - this.name = "HMAC"; - this.hashAlgorithms = ["SHA-1", "SHA-256", "SHA-384", "SHA-512"]; - this.usages = ["sign", "verify"]; - } - getDefaultLength(algName) { - switch (algName.toUpperCase()) { - case "SHA-1": - case "SHA-256": - case "SHA-384": - case "SHA-512": - return 512; - default: - throw new Error(`Unknown algorithm name '${algName}'`); - } - } - checkGenerateKeyParams(algorithm) { - this.checkRequiredProperty(algorithm, "hash"); - this.checkHashAlgorithm(algorithm.hash, this.hashAlgorithms); - if ("length" in algorithm) { - if (typeof algorithm.length !== "number") { - throw new TypeError("length: Is not a Number"); - } - if (algorithm.length < 1) { - throw new RangeError("length: Number is out of range"); - } - } - } - checkImportParams(algorithm) { - this.checkRequiredProperty(algorithm, "hash"); - this.checkHashAlgorithm(algorithm.hash, this.hashAlgorithms); - } - }; - Pbkdf2Provider = class extends ProviderCrypto { - constructor() { - super(...arguments); - this.name = "PBKDF2"; - this.hashAlgorithms = ["SHA-1", "SHA-256", "SHA-384", "SHA-512"]; - this.usages = ["deriveBits", "deriveKey"]; - } - checkAlgorithmParams(algorithm) { - this.checkRequiredProperty(algorithm, "hash"); - this.checkHashAlgorithm(algorithm.hash, this.hashAlgorithms); - this.checkRequiredProperty(algorithm, "salt"); - if (!(algorithm.salt instanceof ArrayBuffer || ArrayBuffer.isView(algorithm.salt))) { - throw new TypeError("salt: Is not of type '(ArrayBuffer or ArrayBufferView)'"); - } - this.checkRequiredProperty(algorithm, "iterations"); - if (typeof algorithm.iterations !== "number") { - throw new TypeError("iterations: Is not a Number"); - } - if (algorithm.iterations < 1) { - throw new TypeError("iterations: Is less than 1"); - } - } - checkImportKey(format2, keyData, algorithm, extractable, keyUsages, ...args) { - super.checkImportKey(format2, keyData, algorithm, extractable, keyUsages); - if (extractable) { - throw new SyntaxError("extractable: Must be 'false'"); - } - } - }; - HkdfProvider = class extends ProviderCrypto { - constructor() { - super(...arguments); - this.name = "HKDF"; - this.hashAlgorithms = ["SHA-1", "SHA-256", "SHA-384", "SHA-512"]; - this.usages = ["deriveKey", "deriveBits"]; - } - checkAlgorithmParams(algorithm) { - this.checkRequiredProperty(algorithm, "hash"); - this.checkHashAlgorithm(algorithm.hash, this.hashAlgorithms); - this.checkRequiredProperty(algorithm, "salt"); - if (!import_pvtsutils4.BufferSourceConverter.isBufferSource(algorithm.salt)) { - throw new TypeError("salt: Is not of type '(ArrayBuffer or ArrayBufferView)'"); - } - this.checkRequiredProperty(algorithm, "info"); - if (!import_pvtsutils4.BufferSourceConverter.isBufferSource(algorithm.info)) { - throw new TypeError("salt: Is not of type '(ArrayBuffer or ArrayBufferView)'"); - } - } - checkImportKey(format2, keyData, algorithm, extractable, keyUsages, ...args) { - super.checkImportKey(format2, keyData, algorithm, extractable, keyUsages); - if (extractable) { - throw new SyntaxError("extractable: Must be 'false'"); - } - } - }; - ShakeProvider = class extends ProviderCrypto { - constructor() { - super(...arguments); - this.usages = []; - this.defaultLength = 0; - } - digest(...args) { - args[0] = { length: this.defaultLength, ...args[0] }; - return super.digest.apply(this, args); - } - checkDigest(algorithm, data) { - super.checkDigest(algorithm, data); - const length = algorithm.length || 0; - if (typeof length !== "number") { - throw new TypeError("length: Is not a Number"); - } - if (length < 0) { - throw new TypeError("length: Is negative"); - } - } - }; - Shake128Provider = class extends ShakeProvider { - constructor() { - super(...arguments); - this.name = "shake128"; - this.defaultLength = 16; - } - }; - Shake256Provider = class extends ShakeProvider { - constructor() { - super(...arguments); - this.name = "shake256"; - this.defaultLength = 32; - } - }; - Crypto = class { - get [Symbol.toStringTag]() { - return "Crypto"; - } - randomUUID() { - const b = this.getRandomValues(new Uint8Array(16)); - b[6] = b[6] & 15 | 64; - b[8] = b[8] & 63 | 128; - const uuid = import_pvtsutils4.Convert.ToHex(b).toLowerCase(); - return `${uuid.substring(0, 8)}-${uuid.substring(8, 12)}-${uuid.substring(12, 16)}-${uuid.substring(16, 20)}-${uuid.substring(20)}`; - } - }; - ProviderStorage = class { - constructor() { - this.items = {}; - } - get(algorithmName) { - return this.items[algorithmName.toLowerCase()] || null; - } - set(provider) { - this.items[provider.name.toLowerCase()] = provider; - } - removeAt(algorithmName) { - const provider = this.get(algorithmName.toLowerCase()); - if (provider) { - delete this.items[algorithmName]; - } - return provider; - } - has(name) { - return !!this.get(name); - } - get length() { - return Object.keys(this.items).length; - } - get algorithms() { - const algorithms = []; - for (const key in this.items) { - const provider = this.items[key]; - algorithms.push(provider.name); - } - return algorithms.sort(); - } - }; - SubtleCrypto = class { - constructor() { - this.providers = new ProviderStorage(); - } - static isHashedAlgorithm(data) { - return data && typeof data === "object" && "name" in data && "hash" in data ? true : false; - } - get [Symbol.toStringTag]() { - return "SubtleCrypto"; - } - async digest(...args) { - this.checkRequiredArguments(args, 2, "digest"); - const [algorithm, data, ...params] = args; - const preparedAlgorithm = this.prepareAlgorithm(algorithm); - const preparedData = import_pvtsutils4.BufferSourceConverter.toArrayBuffer(data); - const provider = this.getProvider(preparedAlgorithm.name); - const result = await provider.digest(preparedAlgorithm, preparedData, ...params); - return result; - } - async generateKey(...args) { - this.checkRequiredArguments(args, 3, "generateKey"); - const [algorithm, extractable, keyUsages, ...params] = args; - const preparedAlgorithm = this.prepareAlgorithm(algorithm); - const provider = this.getProvider(preparedAlgorithm.name); - const result = await provider.generateKey({ ...preparedAlgorithm, name: provider.name }, extractable, keyUsages, ...params); - return result; - } - async sign(...args) { - this.checkRequiredArguments(args, 3, "sign"); - const [algorithm, key, data, ...params] = args; - this.checkCryptoKey(key); - const preparedAlgorithm = this.prepareAlgorithm(algorithm); - const preparedData = import_pvtsutils4.BufferSourceConverter.toArrayBuffer(data); - const provider = this.getProvider(preparedAlgorithm.name); - const result = await provider.sign({ ...preparedAlgorithm, name: provider.name }, key, preparedData, ...params); - return result; - } - async verify(...args) { - this.checkRequiredArguments(args, 4, "verify"); - const [algorithm, key, signature, data, ...params] = args; - this.checkCryptoKey(key); - const preparedAlgorithm = this.prepareAlgorithm(algorithm); - const preparedData = import_pvtsutils4.BufferSourceConverter.toArrayBuffer(data); - const preparedSignature = import_pvtsutils4.BufferSourceConverter.toArrayBuffer(signature); - const provider = this.getProvider(preparedAlgorithm.name); - const result = await provider.verify({ ...preparedAlgorithm, name: provider.name }, key, preparedSignature, preparedData, ...params); - return result; - } - async encrypt(...args) { - this.checkRequiredArguments(args, 3, "encrypt"); - const [algorithm, key, data, ...params] = args; - this.checkCryptoKey(key); - const preparedAlgorithm = this.prepareAlgorithm(algorithm); - const preparedData = import_pvtsutils4.BufferSourceConverter.toArrayBuffer(data); - const provider = this.getProvider(preparedAlgorithm.name); - const result = await provider.encrypt({ ...preparedAlgorithm, name: provider.name }, key, preparedData, { keyUsage: true }, ...params); - return result; - } - async decrypt(...args) { - this.checkRequiredArguments(args, 3, "decrypt"); - const [algorithm, key, data, ...params] = args; - this.checkCryptoKey(key); - const preparedAlgorithm = this.prepareAlgorithm(algorithm); - const preparedData = import_pvtsutils4.BufferSourceConverter.toArrayBuffer(data); - const provider = this.getProvider(preparedAlgorithm.name); - const result = await provider.decrypt({ ...preparedAlgorithm, name: provider.name }, key, preparedData, { keyUsage: true }, ...params); - return result; - } - async deriveBits(...args) { - this.checkRequiredArguments(args, 3, "deriveBits"); - const [algorithm, baseKey, length, ...params] = args; - this.checkCryptoKey(baseKey); - const preparedAlgorithm = this.prepareAlgorithm(algorithm); - const provider = this.getProvider(preparedAlgorithm.name); - const result = await provider.deriveBits({ ...preparedAlgorithm, name: provider.name }, baseKey, length, { keyUsage: true }, ...params); - return result; - } - async deriveKey(...args) { - this.checkRequiredArguments(args, 5, "deriveKey"); - const [algorithm, baseKey, derivedKeyType, extractable, keyUsages, ...params] = args; - const preparedDerivedKeyType = this.prepareAlgorithm(derivedKeyType); - const importProvider = this.getProvider(preparedDerivedKeyType.name); - importProvider.checkDerivedKeyParams(preparedDerivedKeyType); - const preparedAlgorithm = this.prepareAlgorithm(algorithm); - const provider = this.getProvider(preparedAlgorithm.name); - provider.checkCryptoKey(baseKey, "deriveKey"); - const derivedBits = await provider.deriveBits({ ...preparedAlgorithm, name: provider.name }, baseKey, derivedKeyType.length || 512, { keyUsage: false }, ...params); - return this.importKey("raw", derivedBits, derivedKeyType, extractable, keyUsages, ...params); - } - async exportKey(...args) { - this.checkRequiredArguments(args, 2, "exportKey"); - const [format2, key, ...params] = args; - this.checkCryptoKey(key); - const provider = this.getProvider(key.algorithm.name); - const result = await provider.exportKey(format2, key, ...params); - return result; - } - async importKey(...args) { - this.checkRequiredArguments(args, 5, "importKey"); - const [format2, keyData, algorithm, extractable, keyUsages, ...params] = args; - const preparedAlgorithm = this.prepareAlgorithm(algorithm); - const provider = this.getProvider(preparedAlgorithm.name); - if (["pkcs8", "spki", "raw"].indexOf(format2) !== -1) { - const preparedData = import_pvtsutils4.BufferSourceConverter.toArrayBuffer(keyData); - return provider.importKey(format2, preparedData, { ...preparedAlgorithm, name: provider.name }, extractable, keyUsages, ...params); - } else { - if (!keyData.kty) { - throw new TypeError("keyData: Is not JSON"); - } - } - return provider.importKey(format2, keyData, { ...preparedAlgorithm, name: provider.name }, extractable, keyUsages, ...params); - } - async wrapKey(format2, key, wrappingKey, wrapAlgorithm, ...args) { - let keyData = await this.exportKey(format2, key, ...args); - if (format2 === "jwk") { - const json = JSON.stringify(keyData); - keyData = import_pvtsutils4.Convert.FromUtf8String(json); - } - const preparedAlgorithm = this.prepareAlgorithm(wrapAlgorithm); - const preparedData = import_pvtsutils4.BufferSourceConverter.toArrayBuffer(keyData); - const provider = this.getProvider(preparedAlgorithm.name); - return provider.encrypt({ ...preparedAlgorithm, name: provider.name }, wrappingKey, preparedData, { keyUsage: false }, ...args); - } - async unwrapKey(format2, wrappedKey, unwrappingKey, unwrapAlgorithm, unwrappedKeyAlgorithm, extractable, keyUsages, ...args) { - const preparedAlgorithm = this.prepareAlgorithm(unwrapAlgorithm); - const preparedData = import_pvtsutils4.BufferSourceConverter.toArrayBuffer(wrappedKey); - const provider = this.getProvider(preparedAlgorithm.name); - let keyData = await provider.decrypt({ ...preparedAlgorithm, name: provider.name }, unwrappingKey, preparedData, { keyUsage: false }, ...args); - if (format2 === "jwk") { - try { - keyData = JSON.parse(import_pvtsutils4.Convert.ToUtf8String(keyData)); - } catch (e) { - const error = new TypeError("wrappedKey: Is not a JSON"); - error.internal = e; - throw error; - } - } - return this.importKey(format2, keyData, unwrappedKeyAlgorithm, extractable, keyUsages, ...args); - } - checkRequiredArguments(args, size, methodName) { - if (args.length < size) { - throw new TypeError(`Failed to execute '${methodName}' on 'SubtleCrypto': ${size} arguments required, but only ${args.length} present`); - } - } - prepareAlgorithm(algorithm) { - if (typeof algorithm === "string") { - return { - name: algorithm - }; - } - if (SubtleCrypto.isHashedAlgorithm(algorithm)) { - const preparedAlgorithm = { ...algorithm }; - preparedAlgorithm.hash = this.prepareAlgorithm(algorithm.hash); - return preparedAlgorithm; - } - return { ...algorithm }; - } - getProvider(name) { - const provider = this.providers.get(name); - if (!provider) { - throw new AlgorithmError("Unrecognized name"); - } - return provider; - } - checkCryptoKey(key) { - if (!(key instanceof CryptoKey)) { - throw new TypeError(`Key is not of type 'CryptoKey'`); - } - } - }; - } - }); - - // node_modules/.pnpm/@peculiar+webcrypto@1.4.3/node_modules/@peculiar/webcrypto/build/webcrypto.es.js - var webcrypto_es_exports = {}; - __export(webcrypto_es_exports, { - Crypto: () => Crypto2, - CryptoKey: () => CryptoKey - }); - function getCryptoKey(key) { - const res = keyStorage.get(key); - if (!res) { - throw new OperationError("Cannot get CryptoKey from secure storage"); - } - return res; - } - function setCryptoKey(value) { - const key = CryptoKey.create(value.algorithm, value.type, value.extractable, value.usages); - Object.freeze(key); - keyStorage.set(key, value); - return key; - } - function bitShiftLeft(buffer) { - const shifted = Buffer.alloc(buffer.length); - const last = buffer.length - 1; - for (let index = 0; index < last; index++) { - shifted[index] = buffer[index] << 1; - if (buffer[index + 1] & 128) { - shifted[index] += 1; - } - } - shifted[last] = buffer[last] << 1; - return shifted; - } - function xor(a2, b) { - const length = Math.min(a2.length, b.length); - const output = Buffer.alloc(length); - for (let index = 0; index < length; index++) { - output[index] = a2[index] ^ b[index]; - } - return output; - } - function aes(key, message) { - const cipher = crypto.createCipheriv(`aes${key.length << 3}`, key, zero); - const result = cipher.update(message); - cipher.final(); - return result; - } - function getMessageBlock(message, blockIndex) { - const block = Buffer.alloc(blockSize); - const start = blockIndex * blockSize; - const end = start + blockSize; - message.copy(block, 0, start, end); - return block; - } - function getPaddedMessageBlock(message, blockIndex) { - const block = Buffer.alloc(blockSize); - const start = blockIndex * blockSize; - const end = message.length; - block.fill(0); - message.copy(block, 0, start, end); - block[end - start] = 128; - return block; - } - function generateSubkeys(key) { - const l = aes(key, zero); - let subkey1 = bitShiftLeft(l); - if (l[0] & 128) { - subkey1 = xor(subkey1, rb); - } - let subkey2 = bitShiftLeft(subkey1); - if (subkey1[0] & 128) { - subkey2 = xor(subkey2, rb); - } - return { subkey1, subkey2 }; - } - function aesCmac(key, message) { - const subkeys = generateSubkeys(key); - let blockCount = Math.ceil(message.length / blockSize); - let lastBlockCompleteFlag; - let lastBlock; - if (blockCount === 0) { - blockCount = 1; - lastBlockCompleteFlag = false; - } else { - lastBlockCompleteFlag = message.length % blockSize === 0; - } - const lastBlockIndex = blockCount - 1; - if (lastBlockCompleteFlag) { - lastBlock = xor(getMessageBlock(message, lastBlockIndex), subkeys.subkey1); - } else { - lastBlock = xor(getPaddedMessageBlock(message, lastBlockIndex), subkeys.subkey2); - } - let x = zero; - let y; - for (let index = 0; index < lastBlockIndex; index++) { - y = xor(x, getMessageBlock(message, index)); - x = aes(key, y); - } - y = xor(lastBlock, x); - return aes(key, y); - } - function getJwkAlgorithm(algorithm) { - switch (algorithm.name.toUpperCase()) { - case "RSA-OAEP": { - const mdSize = /(\d+)$/.exec(algorithm.hash.name)[1]; - return `RSA-OAEP${mdSize !== "1" ? `-${mdSize}` : ""}`; - } - case "RSASSA-PKCS1-V1_5": - return `RS${/(\d+)$/.exec(algorithm.hash.name)[1]}`; - case "RSA-PSS": - return `PS${/(\d+)$/.exec(algorithm.hash.name)[1]}`; - case "RSA-PKCS1": - return `RS1`; - default: - throw new OperationError("algorithm: Is not recognized"); - } - } - function getOidByNamedCurve$1(namedCurve) { - const oid = namedOIDs[namedCurve]; - if (!oid) { - throw new OperationError(`Cannot convert WebCrypto named curve '${namedCurve}' to OID`); - } - return oid; - } - function getOidByNamedCurve(namedCurve) { - const oid = edOIDs[namedCurve.toLowerCase()]; - if (!oid) { - throw new OperationError(`Cannot convert WebCrypto named curve '${namedCurve}' to OID`); - } - return oid; - } - var crypto, import_crypto, process2, import_pvtsutils6, JsonBase64UrlConverter, CryptoKey2, SymmetricKey, AsymmetricKey, AesCryptoKey, AesCrypto, keyStorage, AesCbcProvider2, zero, rb, blockSize, AesCmacProvider2, AesCtrProvider2, AesGcmProvider2, AesKwProvider2, AesEcbProvider2, DesCryptoKey, DesCrypto, DesCbcProvider, DesEde3CbcProvider, RsaPrivateKey2, RsaPublicKey2, RsaCrypto, RsaSsaProvider2, RsaPssProvider2, ShaCrypto, RsaOaepProvider2, RsaEsProvider, namedOIDs, EcPrivateKey2, EcPublicKey3, Sha1Provider, Sha256Provider, Sha384Provider, Sha512Provider, Sha3256Provider, Sha3384Provider, Sha3512Provider, EcCrypto, EcdsaProvider2, EcdhProvider2, edOIDs, EdPrivateKey3, EdPublicKey3, EdCrypto, EdDsaProvider2, EcdhEsProvider2, PbkdfCryptoKey, Pbkdf2Provider2, HmacCryptoKey, HmacProvider2, HkdfCryptoKey, HkdfProvider2, ShakeCrypto, Shake128Provider2, Shake256Provider2, SubtleCrypto2, Crypto2; - var init_webcrypto_es = __esm({ - "node_modules/.pnpm/@peculiar+webcrypto@1.4.3/node_modules/@peculiar/webcrypto/build/webcrypto.es.js"() { - init_webcrypto_core_es(); - init_webcrypto_core_es(); - init_webcrypto_core_es(); - crypto = __toESM(__require("crypto")); - import_crypto = __toESM(__require("crypto")); - process2 = __toESM(__require("process")); - init_tslib_es6(); - init_index_es2(); - import_pvtsutils6 = __toESM(require_build()); - init_es2015(); - JsonBase64UrlConverter = { - fromJSON: (value) => Buffer.from(import_pvtsutils6.Convert.FromBase64Url(value)), - toJSON: (value) => import_pvtsutils6.Convert.ToBase64Url(value) - }; - CryptoKey2 = class extends CryptoKey { - constructor() { - super(...arguments); - this.data = Buffer.alloc(0); - this.algorithm = { name: "" }; - this.extractable = false; - this.type = "secret"; - this.usages = []; - this.kty = "oct"; - this.alg = ""; - } - }; - __decorate([ - JsonProp({ name: "ext", type: JsonPropTypes.Boolean, optional: true }) - ], CryptoKey2.prototype, "extractable", void 0); - __decorate([ - JsonProp({ name: "key_ops", type: JsonPropTypes.String, repeated: true, optional: true }) - ], CryptoKey2.prototype, "usages", void 0); - __decorate([ - JsonProp({ type: JsonPropTypes.String }) - ], CryptoKey2.prototype, "kty", void 0); - __decorate([ - JsonProp({ type: JsonPropTypes.String, optional: true }) - ], CryptoKey2.prototype, "alg", void 0); - SymmetricKey = class extends CryptoKey2 { - constructor() { - super(...arguments); - this.kty = "oct"; - this.type = "secret"; - } - }; - AsymmetricKey = class extends CryptoKey2 { - }; - AesCryptoKey = class extends SymmetricKey { - get alg() { - switch (this.algorithm.name.toUpperCase()) { - case "AES-CBC": - return `A${this.algorithm.length}CBC`; - case "AES-CTR": - return `A${this.algorithm.length}CTR`; - case "AES-GCM": - return `A${this.algorithm.length}GCM`; - case "AES-KW": - return `A${this.algorithm.length}KW`; - case "AES-CMAC": - return `A${this.algorithm.length}CMAC`; - case "AES-ECB": - return `A${this.algorithm.length}ECB`; - default: - throw new AlgorithmError("Unsupported algorithm name"); - } - } - set alg(value) { - } - }; - __decorate([ - JsonProp({ name: "k", converter: JsonBase64UrlConverter }) - ], AesCryptoKey.prototype, "data", void 0); - AesCrypto = class { - static async generateKey(algorithm, extractable, keyUsages) { - const key = new AesCryptoKey(); - key.algorithm = algorithm; - key.extractable = extractable; - key.usages = keyUsages; - key.data = import_crypto.default.randomBytes(algorithm.length >> 3); - return key; - } - static async exportKey(format2, key) { - if (!(key instanceof AesCryptoKey)) { - throw new Error("key: Is not AesCryptoKey"); - } - switch (format2.toLowerCase()) { - case "jwk": - return JsonSerializer.toJSON(key); - case "raw": - return new Uint8Array(key.data).buffer; - default: - throw new OperationError("format: Must be 'jwk' or 'raw'"); - } - } - static async importKey(format2, keyData, algorithm, extractable, keyUsages) { - let key; - switch (format2.toLowerCase()) { - case "jwk": - key = JsonParser.fromJSON(keyData, { targetSchema: AesCryptoKey }); - break; - case "raw": - key = new AesCryptoKey(); - key.data = Buffer.from(keyData); - break; - default: - throw new OperationError("format: Must be 'jwk' or 'raw'"); - } - key.algorithm = algorithm; - key.algorithm.length = key.data.length << 3; - key.extractable = extractable; - key.usages = keyUsages; - switch (key.algorithm.length) { - case 128: - case 192: - case 256: - break; - default: - throw new OperationError("keyData: Is wrong key length"); - } - return key; - } - static async encrypt(algorithm, key, data) { - switch (algorithm.name.toUpperCase()) { - case "AES-CBC": - return this.encryptAesCBC(algorithm, key, Buffer.from(data)); - case "AES-CTR": - return this.encryptAesCTR(algorithm, key, Buffer.from(data)); - case "AES-GCM": - return this.encryptAesGCM(algorithm, key, Buffer.from(data)); - case "AES-KW": - return this.encryptAesKW(algorithm, key, Buffer.from(data)); - case "AES-ECB": - return this.encryptAesECB(algorithm, key, Buffer.from(data)); - default: - throw new OperationError("algorithm: Is not recognized"); - } - } - static async decrypt(algorithm, key, data) { - if (!(key instanceof AesCryptoKey)) { - throw new Error("key: Is not AesCryptoKey"); - } - switch (algorithm.name.toUpperCase()) { - case "AES-CBC": - return this.decryptAesCBC(algorithm, key, Buffer.from(data)); - case "AES-CTR": - return this.decryptAesCTR(algorithm, key, Buffer.from(data)); - case "AES-GCM": - return this.decryptAesGCM(algorithm, key, Buffer.from(data)); - case "AES-KW": - return this.decryptAesKW(algorithm, key, Buffer.from(data)); - case "AES-ECB": - return this.decryptAesECB(algorithm, key, Buffer.from(data)); - default: - throw new OperationError("algorithm: Is not recognized"); - } - } - static async encryptAesCBC(algorithm, key, data) { - const cipher = import_crypto.default.createCipheriv(`aes-${key.algorithm.length}-cbc`, key.data, new Uint8Array(algorithm.iv)); - let enc = cipher.update(data); - enc = Buffer.concat([enc, cipher.final()]); - const res = new Uint8Array(enc).buffer; - return res; - } - static async decryptAesCBC(algorithm, key, data) { - const decipher = import_crypto.default.createDecipheriv(`aes-${key.algorithm.length}-cbc`, key.data, new Uint8Array(algorithm.iv)); - let dec = decipher.update(data); - dec = Buffer.concat([dec, decipher.final()]); - return new Uint8Array(dec).buffer; - } - static async encryptAesCTR(algorithm, key, data) { - const cipher = import_crypto.default.createCipheriv(`aes-${key.algorithm.length}-ctr`, key.data, Buffer.from(algorithm.counter)); - let enc = cipher.update(data); - enc = Buffer.concat([enc, cipher.final()]); - const res = new Uint8Array(enc).buffer; - return res; - } - static async decryptAesCTR(algorithm, key, data) { - const decipher = import_crypto.default.createDecipheriv(`aes-${key.algorithm.length}-ctr`, key.data, new Uint8Array(algorithm.counter)); - let dec = decipher.update(data); - dec = Buffer.concat([dec, decipher.final()]); - return new Uint8Array(dec).buffer; - } - static async encryptAesGCM(algorithm, key, data) { - const cipher = import_crypto.default.createCipheriv(`aes-${key.algorithm.length}-gcm`, key.data, Buffer.from(algorithm.iv), { - authTagLength: (algorithm.tagLength || 128) >> 3 - }); - if (algorithm.additionalData) { - cipher.setAAD(Buffer.from(algorithm.additionalData)); - } - let enc = cipher.update(data); - enc = Buffer.concat([enc, cipher.final(), cipher.getAuthTag()]); - const res = new Uint8Array(enc).buffer; - return res; - } - static async decryptAesGCM(algorithm, key, data) { - const decipher = import_crypto.default.createDecipheriv(`aes-${key.algorithm.length}-gcm`, key.data, new Uint8Array(algorithm.iv)); - const tagLength = (algorithm.tagLength || 128) >> 3; - const enc = data.slice(0, data.length - tagLength); - const tag = data.slice(data.length - tagLength); - if (algorithm.additionalData) { - decipher.setAAD(Buffer.from(algorithm.additionalData)); - } - decipher.setAuthTag(tag); - let dec = decipher.update(enc); - dec = Buffer.concat([dec, decipher.final()]); - return new Uint8Array(dec).buffer; - } - static async encryptAesKW(algorithm, key, data) { - const cipher = import_crypto.default.createCipheriv(`id-aes${key.algorithm.length}-wrap`, key.data, this.AES_KW_IV); - let enc = cipher.update(data); - enc = Buffer.concat([enc, cipher.final()]); - return new Uint8Array(enc).buffer; - } - static async decryptAesKW(algorithm, key, data) { - const decipher = import_crypto.default.createDecipheriv(`id-aes${key.algorithm.length}-wrap`, key.data, this.AES_KW_IV); - let dec = decipher.update(data); - dec = Buffer.concat([dec, decipher.final()]); - return new Uint8Array(dec).buffer; - } - static async encryptAesECB(algorithm, key, data) { - const cipher = import_crypto.default.createCipheriv(`aes-${key.algorithm.length}-ecb`, key.data, new Uint8Array(0)); - let enc = cipher.update(data); - enc = Buffer.concat([enc, cipher.final()]); - const res = new Uint8Array(enc).buffer; - return res; - } - static async decryptAesECB(algorithm, key, data) { - const decipher = import_crypto.default.createDecipheriv(`aes-${key.algorithm.length}-ecb`, key.data, new Uint8Array(0)); - let dec = decipher.update(data); - dec = Buffer.concat([dec, decipher.final()]); - return new Uint8Array(dec).buffer; - } - }; - AesCrypto.AES_KW_IV = Buffer.from("A6A6A6A6A6A6A6A6", "hex"); - keyStorage = /* @__PURE__ */ new WeakMap(); - AesCbcProvider2 = class extends AesCbcProvider { - async onGenerateKey(algorithm, extractable, keyUsages) { - const key = await AesCrypto.generateKey({ - name: this.name, - length: algorithm.length - }, extractable, keyUsages); - return setCryptoKey(key); - } - async onEncrypt(algorithm, key, data) { - return AesCrypto.encrypt(algorithm, getCryptoKey(key), new Uint8Array(data)); - } - async onDecrypt(algorithm, key, data) { - return AesCrypto.decrypt(algorithm, getCryptoKey(key), new Uint8Array(data)); - } - async onExportKey(format2, key) { - return AesCrypto.exportKey(format2, getCryptoKey(key)); - } - async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { - const key = await AesCrypto.importKey(format2, keyData, { name: algorithm.name }, extractable, keyUsages); - return setCryptoKey(key); - } - checkCryptoKey(key, keyUsage) { - super.checkCryptoKey(key, keyUsage); - if (!(getCryptoKey(key) instanceof AesCryptoKey)) { - throw new TypeError("key: Is not a AesCryptoKey"); - } - } - }; - zero = Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); - rb = Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135]); - blockSize = 16; - AesCmacProvider2 = class extends AesCmacProvider { - async onGenerateKey(algorithm, extractable, keyUsages) { - const key = await AesCrypto.generateKey({ - name: this.name, - length: algorithm.length - }, extractable, keyUsages); - return setCryptoKey(key); - } - async onSign(algorithm, key, data) { - const result = aesCmac(getCryptoKey(key).data, Buffer.from(data)); - return new Uint8Array(result).buffer; - } - async onVerify(algorithm, key, signature, data) { - const signature2 = await this.sign(algorithm, key, data); - return Buffer.from(signature).compare(Buffer.from(signature2)) === 0; - } - async onExportKey(format2, key) { - return AesCrypto.exportKey(format2, getCryptoKey(key)); - } - async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { - const res = await AesCrypto.importKey(format2, keyData, { name: algorithm.name }, extractable, keyUsages); - return setCryptoKey(res); - } - checkCryptoKey(key, keyUsage) { - super.checkCryptoKey(key, keyUsage); - if (!(getCryptoKey(key) instanceof AesCryptoKey)) { - throw new TypeError("key: Is not a AesCryptoKey"); - } - } - }; - AesCtrProvider2 = class extends AesCtrProvider { - async onGenerateKey(algorithm, extractable, keyUsages) { - const key = await AesCrypto.generateKey({ - name: this.name, - length: algorithm.length - }, extractable, keyUsages); - return setCryptoKey(key); - } - async onEncrypt(algorithm, key, data) { - return AesCrypto.encrypt(algorithm, getCryptoKey(key), new Uint8Array(data)); - } - async onDecrypt(algorithm, key, data) { - return AesCrypto.decrypt(algorithm, getCryptoKey(key), new Uint8Array(data)); - } - async onExportKey(format2, key) { - return AesCrypto.exportKey(format2, getCryptoKey(key)); - } - async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { - const res = await AesCrypto.importKey(format2, keyData, { name: algorithm.name }, extractable, keyUsages); - return setCryptoKey(res); - } - checkCryptoKey(key, keyUsage) { - super.checkCryptoKey(key, keyUsage); - if (!(getCryptoKey(key) instanceof AesCryptoKey)) { - throw new TypeError("key: Is not a AesCryptoKey"); - } - } - }; - AesGcmProvider2 = class extends AesGcmProvider { - async onGenerateKey(algorithm, extractable, keyUsages) { - const key = await AesCrypto.generateKey({ - name: this.name, - length: algorithm.length - }, extractable, keyUsages); - return setCryptoKey(key); - } - async onEncrypt(algorithm, key, data) { - return AesCrypto.encrypt(algorithm, getCryptoKey(key), new Uint8Array(data)); - } - async onDecrypt(algorithm, key, data) { - return AesCrypto.decrypt(algorithm, getCryptoKey(key), new Uint8Array(data)); - } - async onExportKey(format2, key) { - return AesCrypto.exportKey(format2, getCryptoKey(key)); - } - async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { - const res = await AesCrypto.importKey(format2, keyData, { name: algorithm.name }, extractable, keyUsages); - return setCryptoKey(res); - } - checkCryptoKey(key, keyUsage) { - super.checkCryptoKey(key, keyUsage); - if (!(getCryptoKey(key) instanceof AesCryptoKey)) { - throw new TypeError("key: Is not a AesCryptoKey"); - } - } - }; - AesKwProvider2 = class extends AesKwProvider { - async onGenerateKey(algorithm, extractable, keyUsages) { - const res = await AesCrypto.generateKey({ - name: this.name, - length: algorithm.length - }, extractable, keyUsages); - return setCryptoKey(res); - } - async onExportKey(format2, key) { - return AesCrypto.exportKey(format2, getCryptoKey(key)); - } - async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { - const res = await AesCrypto.importKey(format2, keyData, { name: algorithm.name }, extractable, keyUsages); - return setCryptoKey(res); - } - async onEncrypt(algorithm, key, data) { - return AesCrypto.encrypt(algorithm, getCryptoKey(key), new Uint8Array(data)); - } - async onDecrypt(algorithm, key, data) { - return AesCrypto.decrypt(algorithm, getCryptoKey(key), new Uint8Array(data)); - } - checkCryptoKey(key, keyUsage) { - super.checkCryptoKey(key, keyUsage); - if (!(getCryptoKey(key) instanceof AesCryptoKey)) { - throw new TypeError("key: Is not a AesCryptoKey"); - } - } - }; - AesEcbProvider2 = class extends AesEcbProvider { - async onGenerateKey(algorithm, extractable, keyUsages) { - const key = await AesCrypto.generateKey({ - name: this.name, - length: algorithm.length - }, extractable, keyUsages); - return setCryptoKey(key); - } - async onEncrypt(algorithm, key, data) { - return AesCrypto.encrypt(algorithm, getCryptoKey(key), new Uint8Array(data)); - } - async onDecrypt(algorithm, key, data) { - return AesCrypto.decrypt(algorithm, getCryptoKey(key), new Uint8Array(data)); - } - async onExportKey(format2, key) { - return AesCrypto.exportKey(format2, getCryptoKey(key)); - } - async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { - const res = await AesCrypto.importKey(format2, keyData, { name: algorithm.name }, extractable, keyUsages); - return setCryptoKey(res); - } - checkCryptoKey(key, keyUsage) { - super.checkCryptoKey(key, keyUsage); - if (!(getCryptoKey(key) instanceof AesCryptoKey)) { - throw new TypeError("key: Is not a AesCryptoKey"); - } - } - }; - DesCryptoKey = class extends SymmetricKey { - get alg() { - switch (this.algorithm.name.toUpperCase()) { - case "DES-CBC": - return `DES-CBC`; - case "DES-EDE3-CBC": - return `3DES-CBC`; - default: - throw new AlgorithmError("Unsupported algorithm name"); - } - } - set alg(value) { - } - }; - __decorate([ - JsonProp({ name: "k", converter: JsonBase64UrlConverter }) - ], DesCryptoKey.prototype, "data", void 0); - DesCrypto = class { - static async generateKey(algorithm, extractable, keyUsages) { - const key = new DesCryptoKey(); - key.algorithm = algorithm; - key.extractable = extractable; - key.usages = keyUsages; - key.data = import_crypto.default.randomBytes(algorithm.length >> 3); - return key; - } - static async exportKey(format2, key) { - switch (format2.toLowerCase()) { - case "jwk": - return JsonSerializer.toJSON(key); - case "raw": - return new Uint8Array(key.data).buffer; - default: - throw new OperationError("format: Must be 'jwk' or 'raw'"); - } - } - static async importKey(format2, keyData, algorithm, extractable, keyUsages) { - let key; - switch (format2.toLowerCase()) { - case "jwk": - key = JsonParser.fromJSON(keyData, { targetSchema: DesCryptoKey }); - break; - case "raw": - key = new DesCryptoKey(); - key.data = Buffer.from(keyData); - break; - default: - throw new OperationError("format: Must be 'jwk' or 'raw'"); - } - key.algorithm = algorithm; - key.extractable = extractable; - key.usages = keyUsages; - return key; - } - static async encrypt(algorithm, key, data) { - switch (algorithm.name.toUpperCase()) { - case "DES-CBC": - return this.encryptDesCBC(algorithm, key, Buffer.from(data)); - case "DES-EDE3-CBC": - return this.encryptDesEDE3CBC(algorithm, key, Buffer.from(data)); - default: - throw new OperationError("algorithm: Is not recognized"); - } - } - static async decrypt(algorithm, key, data) { - if (!(key instanceof DesCryptoKey)) { - throw new Error("key: Is not DesCryptoKey"); - } - switch (algorithm.name.toUpperCase()) { - case "DES-CBC": - return this.decryptDesCBC(algorithm, key, Buffer.from(data)); - case "DES-EDE3-CBC": - return this.decryptDesEDE3CBC(algorithm, key, Buffer.from(data)); - default: - throw new OperationError("algorithm: Is not recognized"); - } - } - static async encryptDesCBC(algorithm, key, data) { - const cipher = import_crypto.default.createCipheriv(`des-cbc`, key.data, new Uint8Array(algorithm.iv)); - let enc = cipher.update(data); - enc = Buffer.concat([enc, cipher.final()]); - const res = new Uint8Array(enc).buffer; - return res; - } - static async decryptDesCBC(algorithm, key, data) { - const decipher = import_crypto.default.createDecipheriv(`des-cbc`, key.data, new Uint8Array(algorithm.iv)); - let dec = decipher.update(data); - dec = Buffer.concat([dec, decipher.final()]); - return new Uint8Array(dec).buffer; - } - static async encryptDesEDE3CBC(algorithm, key, data) { - const cipher = import_crypto.default.createCipheriv(`des-ede3-cbc`, key.data, Buffer.from(algorithm.iv)); - let enc = cipher.update(data); - enc = Buffer.concat([enc, cipher.final()]); - const res = new Uint8Array(enc).buffer; - return res; - } - static async decryptDesEDE3CBC(algorithm, key, data) { - const decipher = import_crypto.default.createDecipheriv(`des-ede3-cbc`, key.data, new Uint8Array(algorithm.iv)); - let dec = decipher.update(data); - dec = Buffer.concat([dec, decipher.final()]); - return new Uint8Array(dec).buffer; - } - }; - DesCbcProvider = class extends DesProvider { - constructor() { - super(...arguments); - this.keySizeBits = 64; - this.ivSize = 8; - this.name = "DES-CBC"; - } - async onGenerateKey(algorithm, extractable, keyUsages) { - const key = await DesCrypto.generateKey({ - name: this.name, - length: this.keySizeBits - }, extractable, keyUsages); - return setCryptoKey(key); - } - async onEncrypt(algorithm, key, data) { - return DesCrypto.encrypt(algorithm, getCryptoKey(key), new Uint8Array(data)); - } - async onDecrypt(algorithm, key, data) { - return DesCrypto.decrypt(algorithm, getCryptoKey(key), new Uint8Array(data)); - } - async onExportKey(format2, key) { - return DesCrypto.exportKey(format2, getCryptoKey(key)); - } - async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { - const key = await DesCrypto.importKey(format2, keyData, { name: this.name, length: this.keySizeBits }, extractable, keyUsages); - if (key.data.length !== this.keySizeBits >> 3) { - throw new OperationError("keyData: Wrong key size"); - } - return setCryptoKey(key); - } - checkCryptoKey(key, keyUsage) { - super.checkCryptoKey(key, keyUsage); - if (!(getCryptoKey(key) instanceof DesCryptoKey)) { - throw new TypeError("key: Is not a DesCryptoKey"); - } - } - }; - DesEde3CbcProvider = class extends DesProvider { - constructor() { - super(...arguments); - this.keySizeBits = 192; - this.ivSize = 8; - this.name = "DES-EDE3-CBC"; - } - async onGenerateKey(algorithm, extractable, keyUsages) { - const key = await DesCrypto.generateKey({ - name: this.name, - length: this.keySizeBits - }, extractable, keyUsages); - return setCryptoKey(key); - } - async onEncrypt(algorithm, key, data) { - return DesCrypto.encrypt(algorithm, getCryptoKey(key), new Uint8Array(data)); - } - async onDecrypt(algorithm, key, data) { - return DesCrypto.decrypt(algorithm, getCryptoKey(key), new Uint8Array(data)); - } - async onExportKey(format2, key) { - return DesCrypto.exportKey(format2, getCryptoKey(key)); - } - async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { - const key = await DesCrypto.importKey(format2, keyData, { name: this.name, length: this.keySizeBits }, extractable, keyUsages); - if (key.data.length !== this.keySizeBits >> 3) { - throw new OperationError("keyData: Wrong key size"); - } - return setCryptoKey(key); - } - checkCryptoKey(key, keyUsage) { - super.checkCryptoKey(key, keyUsage); - if (!(getCryptoKey(key) instanceof DesCryptoKey)) { - throw new TypeError("key: Is not a DesCryptoKey"); - } - } - }; - RsaPrivateKey2 = class extends AsymmetricKey { - constructor() { - super(...arguments); - this.type = "private"; - } - getKey() { - const keyInfo = AsnParser.parse(this.data, index$1.PrivateKeyInfo); - return AsnParser.parse(keyInfo.privateKey, index$1.RsaPrivateKey); - } - toJSON() { - const key = this.getKey(); - const json = { - kty: "RSA", - alg: getJwkAlgorithm(this.algorithm), - key_ops: this.usages, - ext: this.extractable - }; - return Object.assign(json, JsonSerializer.toJSON(key)); - } - fromJSON(json) { - const key = JsonParser.fromJSON(json, { targetSchema: index$1.RsaPrivateKey }); - const keyInfo = new index$1.PrivateKeyInfo(); - keyInfo.privateKeyAlgorithm.algorithm = "1.2.840.113549.1.1.1"; - keyInfo.privateKeyAlgorithm.parameters = null; - keyInfo.privateKey = AsnSerializer.serialize(key); - this.data = Buffer.from(AsnSerializer.serialize(keyInfo)); - } - }; - RsaPublicKey2 = class extends AsymmetricKey { - constructor() { - super(...arguments); - this.type = "public"; - } - getKey() { - const keyInfo = AsnParser.parse(this.data, index$1.PublicKeyInfo); - return AsnParser.parse(keyInfo.publicKey, index$1.RsaPublicKey); - } - toJSON() { - const key = this.getKey(); - const json = { - kty: "RSA", - alg: getJwkAlgorithm(this.algorithm), - key_ops: this.usages, - ext: this.extractable - }; - return Object.assign(json, JsonSerializer.toJSON(key)); - } - fromJSON(json) { - const key = JsonParser.fromJSON(json, { targetSchema: index$1.RsaPublicKey }); - const keyInfo = new index$1.PublicKeyInfo(); - keyInfo.publicKeyAlgorithm.algorithm = "1.2.840.113549.1.1.1"; - keyInfo.publicKeyAlgorithm.parameters = null; - keyInfo.publicKey = AsnSerializer.serialize(key); - this.data = Buffer.from(AsnSerializer.serialize(keyInfo)); - } - }; - RsaCrypto = class { - static async generateKey(algorithm, extractable, keyUsages) { - const privateKey = new RsaPrivateKey2(); - privateKey.algorithm = algorithm; - privateKey.extractable = extractable; - privateKey.usages = keyUsages.filter((usage) => this.privateKeyUsages.indexOf(usage) !== -1); - const publicKey = new RsaPublicKey2(); - publicKey.algorithm = algorithm; - publicKey.extractable = true; - publicKey.usages = keyUsages.filter((usage) => this.publicKeyUsages.indexOf(usage) !== -1); - const publicExponent = Buffer.concat([ - Buffer.alloc(4 - algorithm.publicExponent.byteLength, 0), - Buffer.from(algorithm.publicExponent) - ]).readInt32BE(0); - const keys = import_crypto.default.generateKeyPairSync("rsa", { - modulusLength: algorithm.modulusLength, - publicExponent, - publicKeyEncoding: { - format: "der", - type: "spki" - }, - privateKeyEncoding: { - format: "der", - type: "pkcs8" - } - }); - privateKey.data = keys.privateKey; - publicKey.data = keys.publicKey; - const res = { - privateKey, - publicKey - }; - return res; - } - static async exportKey(format2, key) { - switch (format2.toLowerCase()) { - case "jwk": - return JsonSerializer.toJSON(key); - case "pkcs8": - case "spki": - return new Uint8Array(key.data).buffer; - default: - throw new OperationError("format: Must be 'jwk', 'pkcs8' or 'spki'"); - } - } - static async importKey(format2, keyData, algorithm, extractable, keyUsages) { - switch (format2.toLowerCase()) { - case "jwk": { - const jwk = keyData; - if (jwk.d) { - const asnKey = JsonParser.fromJSON(keyData, { targetSchema: index$1.RsaPrivateKey }); - return this.importPrivateKey(asnKey, algorithm, extractable, keyUsages); - } else { - const asnKey = JsonParser.fromJSON(keyData, { targetSchema: index$1.RsaPublicKey }); - return this.importPublicKey(asnKey, algorithm, extractable, keyUsages); - } - } - case "spki": { - const keyInfo = AsnParser.parse(new Uint8Array(keyData), index$1.PublicKeyInfo); - const asnKey = AsnParser.parse(keyInfo.publicKey, index$1.RsaPublicKey); - return this.importPublicKey(asnKey, algorithm, extractable, keyUsages); - } - case "pkcs8": { - const keyInfo = AsnParser.parse(new Uint8Array(keyData), index$1.PrivateKeyInfo); - const asnKey = AsnParser.parse(keyInfo.privateKey, index$1.RsaPrivateKey); - return this.importPrivateKey(asnKey, algorithm, extractable, keyUsages); - } - default: - throw new OperationError("format: Must be 'jwk', 'pkcs8' or 'spki'"); - } - } - static async sign(algorithm, key, data) { - switch (algorithm.name.toUpperCase()) { - case "RSA-PSS": - case "RSASSA-PKCS1-V1_5": - return this.signRsa(algorithm, key, data); - default: - throw new OperationError("algorithm: Is not recognized"); - } - } - static async verify(algorithm, key, signature, data) { - switch (algorithm.name.toUpperCase()) { - case "RSA-PSS": - case "RSASSA-PKCS1-V1_5": - return this.verifySSA(algorithm, key, data, signature); - default: - throw new OperationError("algorithm: Is not recognized"); - } - } - static async encrypt(algorithm, key, data) { - switch (algorithm.name.toUpperCase()) { - case "RSA-OAEP": - return this.encryptOAEP(algorithm, key, data); - default: - throw new OperationError("algorithm: Is not recognized"); - } - } - static async decrypt(algorithm, key, data) { - switch (algorithm.name.toUpperCase()) { - case "RSA-OAEP": - return this.decryptOAEP(algorithm, key, data); - default: - throw new OperationError("algorithm: Is not recognized"); - } - } - static importPrivateKey(asnKey, algorithm, extractable, keyUsages) { - const keyInfo = new index$1.PrivateKeyInfo(); - keyInfo.privateKeyAlgorithm.algorithm = "1.2.840.113549.1.1.1"; - keyInfo.privateKeyAlgorithm.parameters = null; - keyInfo.privateKey = AsnSerializer.serialize(asnKey); - const key = new RsaPrivateKey2(); - key.data = Buffer.from(AsnSerializer.serialize(keyInfo)); - key.algorithm = Object.assign({}, algorithm); - key.algorithm.publicExponent = new Uint8Array(asnKey.publicExponent); - key.algorithm.modulusLength = asnKey.modulus.byteLength << 3; - key.extractable = extractable; - key.usages = keyUsages; - return key; - } - static importPublicKey(asnKey, algorithm, extractable, keyUsages) { - const keyInfo = new index$1.PublicKeyInfo(); - keyInfo.publicKeyAlgorithm.algorithm = "1.2.840.113549.1.1.1"; - keyInfo.publicKeyAlgorithm.parameters = null; - keyInfo.publicKey = AsnSerializer.serialize(asnKey); - const key = new RsaPublicKey2(); - key.data = Buffer.from(AsnSerializer.serialize(keyInfo)); - key.algorithm = Object.assign({}, algorithm); - key.algorithm.publicExponent = new Uint8Array(asnKey.publicExponent); - key.algorithm.modulusLength = asnKey.modulus.byteLength << 3; - key.extractable = extractable; - key.usages = keyUsages; - return key; - } - static getCryptoAlgorithm(alg) { - switch (alg.hash.name.toUpperCase()) { - case "SHA-1": - return "RSA-SHA1"; - case "SHA-256": - return "RSA-SHA256"; - case "SHA-384": - return "RSA-SHA384"; - case "SHA-512": - return "RSA-SHA512"; - case "SHA3-256": - return "RSA-SHA3-256"; - case "SHA3-384": - return "RSA-SHA3-384"; - case "SHA3-512": - return "RSA-SHA3-512"; - default: - throw new OperationError("algorithm.hash: Is not recognized"); - } - } - static signRsa(algorithm, key, data) { - const cryptoAlg = this.getCryptoAlgorithm(key.algorithm); - const signer = import_crypto.default.createSign(cryptoAlg); - signer.update(Buffer.from(data)); - if (!key.pem) { - key.pem = `-----BEGIN PRIVATE KEY----- -${key.data.toString("base64")} ------END PRIVATE KEY-----`; - } - const options = { - key: key.pem - }; - if (algorithm.name.toUpperCase() === "RSA-PSS") { - options.padding = import_crypto.default.constants.RSA_PKCS1_PSS_PADDING; - options.saltLength = algorithm.saltLength; - } - const signature = signer.sign(options); - return new Uint8Array(signature).buffer; - } - static verifySSA(algorithm, key, data, signature) { - const cryptoAlg = this.getCryptoAlgorithm(key.algorithm); - const signer = import_crypto.default.createVerify(cryptoAlg); - signer.update(Buffer.from(data)); - if (!key.pem) { - key.pem = `-----BEGIN PUBLIC KEY----- -${key.data.toString("base64")} ------END PUBLIC KEY-----`; - } - const options = { - key: key.pem - }; - if (algorithm.name.toUpperCase() === "RSA-PSS") { - options.padding = import_crypto.default.constants.RSA_PKCS1_PSS_PADDING; - options.saltLength = algorithm.saltLength; - } - const ok = signer.verify(options, signature); - return ok; - } - static encryptOAEP(algorithm, key, data) { - const options = { - key: `-----BEGIN PUBLIC KEY----- -${key.data.toString("base64")} ------END PUBLIC KEY-----`, - padding: import_crypto.default.constants.RSA_PKCS1_OAEP_PADDING - }; - if (algorithm.label) - ; - return new Uint8Array(import_crypto.default.publicEncrypt(options, data)).buffer; - } - static decryptOAEP(algorithm, key, data) { - const options = { - key: `-----BEGIN PRIVATE KEY----- -${key.data.toString("base64")} ------END PRIVATE KEY-----`, - padding: import_crypto.default.constants.RSA_PKCS1_OAEP_PADDING - }; - if (algorithm.label) - ; - return new Uint8Array(import_crypto.default.privateDecrypt(options, data)).buffer; - } - }; - RsaCrypto.publicKeyUsages = ["verify", "encrypt", "wrapKey"]; - RsaCrypto.privateKeyUsages = ["sign", "decrypt", "unwrapKey"]; - RsaSsaProvider2 = class extends RsaSsaProvider { - constructor() { - super(...arguments); - this.hashAlgorithms = [ - "SHA-1", - "SHA-256", - "SHA-384", - "SHA-512", - "shake128", - "shake256", - "SHA3-256", - "SHA3-384", - "SHA3-512" - ]; - } - async onGenerateKey(algorithm, extractable, keyUsages) { - const keys = await RsaCrypto.generateKey({ - ...algorithm, - name: this.name - }, extractable, keyUsages); - return { - privateKey: setCryptoKey(keys.privateKey), - publicKey: setCryptoKey(keys.publicKey) - }; - } - async onSign(algorithm, key, data) { - return RsaCrypto.sign(algorithm, getCryptoKey(key), new Uint8Array(data)); - } - async onVerify(algorithm, key, signature, data) { - return RsaCrypto.verify(algorithm, getCryptoKey(key), new Uint8Array(signature), new Uint8Array(data)); - } - async onExportKey(format2, key) { - return RsaCrypto.exportKey(format2, getCryptoKey(key)); - } - async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { - const key = await RsaCrypto.importKey(format2, keyData, { ...algorithm, name: this.name }, extractable, keyUsages); - return setCryptoKey(key); - } - checkCryptoKey(key, keyUsage) { - super.checkCryptoKey(key, keyUsage); - const internalKey = getCryptoKey(key); - if (!(internalKey instanceof RsaPrivateKey2 || internalKey instanceof RsaPublicKey2)) { - throw new TypeError("key: Is not RSA CryptoKey"); - } - } - }; - RsaPssProvider2 = class extends RsaPssProvider { - constructor() { - super(...arguments); - this.hashAlgorithms = [ - "SHA-1", - "SHA-256", - "SHA-384", - "SHA-512", - "shake128", - "shake256", - "SHA3-256", - "SHA3-384", - "SHA3-512" - ]; - } - async onGenerateKey(algorithm, extractable, keyUsages) { - const keys = await RsaCrypto.generateKey({ - ...algorithm, - name: this.name - }, extractable, keyUsages); - return { - privateKey: setCryptoKey(keys.privateKey), - publicKey: setCryptoKey(keys.publicKey) - }; - } - async onSign(algorithm, key, data) { - return RsaCrypto.sign(algorithm, getCryptoKey(key), new Uint8Array(data)); - } - async onVerify(algorithm, key, signature, data) { - return RsaCrypto.verify(algorithm, getCryptoKey(key), new Uint8Array(signature), new Uint8Array(data)); - } - async onExportKey(format2, key) { - return RsaCrypto.exportKey(format2, getCryptoKey(key)); - } - async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { - const key = await RsaCrypto.importKey(format2, keyData, { ...algorithm, name: this.name }, extractable, keyUsages); - return setCryptoKey(key); - } - checkCryptoKey(key, keyUsage) { - super.checkCryptoKey(key, keyUsage); - const internalKey = getCryptoKey(key); - if (!(internalKey instanceof RsaPrivateKey2 || internalKey instanceof RsaPublicKey2)) { - throw new TypeError("key: Is not RSA CryptoKey"); - } - } - }; - ShaCrypto = class { - static size(algorithm) { - switch (algorithm.name.toUpperCase()) { - case "SHA-1": - return 160; - case "SHA-256": - case "SHA3-256": - return 256; - case "SHA-384": - case "SHA3-384": - return 384; - case "SHA-512": - case "SHA3-512": - return 512; - default: - throw new Error("Unrecognized name"); - } - } - static getAlgorithmName(algorithm) { - switch (algorithm.name.toUpperCase()) { - case "SHA-1": - return "sha1"; - case "SHA-256": - return "sha256"; - case "SHA-384": - return "sha384"; - case "SHA-512": - return "sha512"; - case "SHA3-256": - return "sha3-256"; - case "SHA3-384": - return "sha3-384"; - case "SHA3-512": - return "sha3-512"; - default: - throw new Error("Unrecognized name"); - } - } - static digest(algorithm, data) { - const hashAlg = this.getAlgorithmName(algorithm); - const hash = import_crypto.default.createHash(hashAlg).update(Buffer.from(data)).digest(); - return new Uint8Array(hash).buffer; - } - }; - RsaOaepProvider2 = class extends RsaOaepProvider { - async onGenerateKey(algorithm, extractable, keyUsages) { - const keys = await RsaCrypto.generateKey({ - ...algorithm, - name: this.name - }, extractable, keyUsages); - return { - privateKey: setCryptoKey(keys.privateKey), - publicKey: setCryptoKey(keys.publicKey) - }; - } - async onEncrypt(algorithm, key, data) { - const internalKey = getCryptoKey(key); - const dataView = new Uint8Array(data); - const keySize = Math.ceil(internalKey.algorithm.modulusLength >> 3); - const hashSize = ShaCrypto.size(internalKey.algorithm.hash) >> 3; - const dataLength = dataView.byteLength; - const psLength = keySize - dataLength - 2 * hashSize - 2; - if (dataLength > keySize - 2 * hashSize - 2) { - throw new Error("Data too large"); - } - const message = new Uint8Array(keySize); - const seed = message.subarray(1, hashSize + 1); - const dataBlock = message.subarray(hashSize + 1); - dataBlock.set(dataView, hashSize + psLength + 1); - const labelHash = import_crypto.default.createHash(internalKey.algorithm.hash.name.replace("-", "")).update(import_pvtsutils5.BufferSourceConverter.toUint8Array(algorithm.label || new Uint8Array(0))).digest(); - dataBlock.set(labelHash, 0); - dataBlock[hashSize + psLength] = 1; - import_crypto.default.randomFillSync(seed); - const dataBlockMask = this.mgf1(internalKey.algorithm.hash, seed, dataBlock.length); - for (let i = 0; i < dataBlock.length; i++) { - dataBlock[i] ^= dataBlockMask[i]; - } - const seedMask = this.mgf1(internalKey.algorithm.hash, dataBlock, seed.length); - for (let i = 0; i < seed.length; i++) { - seed[i] ^= seedMask[i]; - } - if (!internalKey.pem) { - internalKey.pem = `-----BEGIN PUBLIC KEY----- -${internalKey.data.toString("base64")} ------END PUBLIC KEY-----`; - } - const pkcs0 = import_crypto.default.publicEncrypt({ - key: internalKey.pem, - padding: import_crypto.default.constants.RSA_NO_PADDING - }, Buffer.from(message)); - return new Uint8Array(pkcs0).buffer; - } - async onDecrypt(algorithm, key, data) { - const internalKey = getCryptoKey(key); - const keySize = Math.ceil(internalKey.algorithm.modulusLength >> 3); - const hashSize = ShaCrypto.size(internalKey.algorithm.hash) >> 3; - const dataLength = data.byteLength; - if (dataLength !== keySize) { - throw new Error("Bad data"); - } - if (!internalKey.pem) { - internalKey.pem = `-----BEGIN PRIVATE KEY----- -${internalKey.data.toString("base64")} ------END PRIVATE KEY-----`; - } - let pkcs0 = import_crypto.default.privateDecrypt({ - key: internalKey.pem, - padding: import_crypto.default.constants.RSA_NO_PADDING - }, Buffer.from(data)); - const z = pkcs0[0]; - const seed = pkcs0.subarray(1, hashSize + 1); - const dataBlock = pkcs0.subarray(hashSize + 1); - if (z !== 0) { - throw new Error("Decryption failed"); - } - const seedMask = this.mgf1(internalKey.algorithm.hash, dataBlock, seed.length); - for (let i = 0; i < seed.length; i++) { - seed[i] ^= seedMask[i]; - } - const dataBlockMask = this.mgf1(internalKey.algorithm.hash, seed, dataBlock.length); - for (let i = 0; i < dataBlock.length; i++) { - dataBlock[i] ^= dataBlockMask[i]; - } - const labelHash = import_crypto.default.createHash(internalKey.algorithm.hash.name.replace("-", "")).update(import_pvtsutils5.BufferSourceConverter.toUint8Array(algorithm.label || new Uint8Array(0))).digest(); - for (let i = 0; i < hashSize; i++) { - if (labelHash[i] !== dataBlock[i]) { - throw new Error("Decryption failed"); - } - } - let psEnd = hashSize; - for (; psEnd < dataBlock.length; psEnd++) { - const psz = dataBlock[psEnd]; - if (psz === 1) { - break; - } - if (psz !== 0) { - throw new Error("Decryption failed"); - } - } - if (psEnd === dataBlock.length) { - throw new Error("Decryption failed"); - } - pkcs0 = dataBlock.subarray(psEnd + 1); - return new Uint8Array(pkcs0).buffer; - } - async onExportKey(format2, key) { - return RsaCrypto.exportKey(format2, getCryptoKey(key)); - } - async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { - const key = await RsaCrypto.importKey(format2, keyData, { ...algorithm, name: this.name }, extractable, keyUsages); - return setCryptoKey(key); - } - checkCryptoKey(key, keyUsage) { - super.checkCryptoKey(key, keyUsage); - const internalKey = getCryptoKey(key); - if (!(internalKey instanceof RsaPrivateKey2 || internalKey instanceof RsaPublicKey2)) { - throw new TypeError("key: Is not RSA CryptoKey"); - } - } - mgf1(algorithm, seed, length = 0) { - const hashSize = ShaCrypto.size(algorithm) >> 3; - const mask = new Uint8Array(length); - const counter = new Uint8Array(4); - const chunks = Math.ceil(length / hashSize); - for (let i = 0; i < chunks; i++) { - counter[0] = i >>> 24; - counter[1] = i >>> 16 & 255; - counter[2] = i >>> 8 & 255; - counter[3] = i & 255; - const submask = mask.subarray(i * hashSize); - let chunk = import_crypto.default.createHash(algorithm.name.replace("-", "")).update(seed).update(counter).digest(); - if (chunk.length > submask.length) { - chunk = chunk.subarray(0, submask.length); - } - submask.set(chunk); - } - return mask; - } - }; - RsaEsProvider = class extends ProviderCrypto { - constructor() { - super(...arguments); - this.name = "RSAES-PKCS1-v1_5"; - this.usages = { - publicKey: ["encrypt", "wrapKey"], - privateKey: ["decrypt", "unwrapKey"] - }; - } - async onGenerateKey(algorithm, extractable, keyUsages) { - const keys = await RsaCrypto.generateKey({ - ...algorithm, - name: this.name - }, extractable, keyUsages); - return { - privateKey: setCryptoKey(keys.privateKey), - publicKey: setCryptoKey(keys.publicKey) - }; - } - checkGenerateKeyParams(algorithm) { - this.checkRequiredProperty(algorithm, "publicExponent"); - if (!(algorithm.publicExponent && algorithm.publicExponent instanceof Uint8Array)) { - throw new TypeError("publicExponent: Missing or not a Uint8Array"); - } - const publicExponent = import_pvtsutils6.Convert.ToBase64(algorithm.publicExponent); - if (!(publicExponent === "Aw==" || publicExponent === "AQAB")) { - throw new TypeError("publicExponent: Must be [3] or [1,0,1]"); - } - this.checkRequiredProperty(algorithm, "modulusLength"); - switch (algorithm.modulusLength) { - case 1024: - case 2048: - case 4096: - break; - default: - throw new TypeError("modulusLength: Must be 1024, 2048, or 4096"); - } - } - async onEncrypt(algorithm, key, data) { - const options = this.toCryptoOptions(key); - const enc = crypto.publicEncrypt(options, new Uint8Array(data)); - return new Uint8Array(enc).buffer; - } - async onDecrypt(algorithm, key, data) { - const options = this.toCryptoOptions(key); - const dec = crypto.privateDecrypt(options, new Uint8Array(data)); - return new Uint8Array(dec).buffer; - } - async onExportKey(format2, key) { - return RsaCrypto.exportKey(format2, getCryptoKey(key)); - } - async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { - const key = await RsaCrypto.importKey(format2, keyData, { ...algorithm, name: this.name }, extractable, keyUsages); - return setCryptoKey(key); - } - checkCryptoKey(key, keyUsage) { - super.checkCryptoKey(key, keyUsage); - const internalKey = getCryptoKey(key); - if (!(internalKey instanceof RsaPrivateKey2 || internalKey instanceof RsaPublicKey2)) { - throw new TypeError("key: Is not RSA CryptoKey"); - } - } - toCryptoOptions(key) { - const type = key.type.toUpperCase(); - return { - key: `-----BEGIN ${type} KEY----- -${getCryptoKey(key).data.toString("base64")} ------END ${type} KEY-----`, - padding: crypto.constants.RSA_PKCS1_PADDING - }; - } - }; - namedOIDs = { - "1.2.840.10045.3.1.7": "P-256", - "P-256": "1.2.840.10045.3.1.7", - "1.3.132.0.34": "P-384", - "P-384": "1.3.132.0.34", - "1.3.132.0.35": "P-521", - "P-521": "1.3.132.0.35", - "1.3.132.0.10": "K-256", - "K-256": "1.3.132.0.10", - "brainpoolP160r1": "1.3.36.3.3.2.8.1.1.1", - "1.3.36.3.3.2.8.1.1.1": "brainpoolP160r1", - "brainpoolP160t1": "1.3.36.3.3.2.8.1.1.2", - "1.3.36.3.3.2.8.1.1.2": "brainpoolP160t1", - "brainpoolP192r1": "1.3.36.3.3.2.8.1.1.3", - "1.3.36.3.3.2.8.1.1.3": "brainpoolP192r1", - "brainpoolP192t1": "1.3.36.3.3.2.8.1.1.4", - "1.3.36.3.3.2.8.1.1.4": "brainpoolP192t1", - "brainpoolP224r1": "1.3.36.3.3.2.8.1.1.5", - "1.3.36.3.3.2.8.1.1.5": "brainpoolP224r1", - "brainpoolP224t1": "1.3.36.3.3.2.8.1.1.6", - "1.3.36.3.3.2.8.1.1.6": "brainpoolP224t1", - "brainpoolP256r1": "1.3.36.3.3.2.8.1.1.7", - "1.3.36.3.3.2.8.1.1.7": "brainpoolP256r1", - "brainpoolP256t1": "1.3.36.3.3.2.8.1.1.8", - "1.3.36.3.3.2.8.1.1.8": "brainpoolP256t1", - "brainpoolP320r1": "1.3.36.3.3.2.8.1.1.9", - "1.3.36.3.3.2.8.1.1.9": "brainpoolP320r1", - "brainpoolP320t1": "1.3.36.3.3.2.8.1.1.10", - "1.3.36.3.3.2.8.1.1.10": "brainpoolP320t1", - "brainpoolP384r1": "1.3.36.3.3.2.8.1.1.11", - "1.3.36.3.3.2.8.1.1.11": "brainpoolP384r1", - "brainpoolP384t1": "1.3.36.3.3.2.8.1.1.12", - "1.3.36.3.3.2.8.1.1.12": "brainpoolP384t1", - "brainpoolP512r1": "1.3.36.3.3.2.8.1.1.13", - "1.3.36.3.3.2.8.1.1.13": "brainpoolP512r1", - "brainpoolP512t1": "1.3.36.3.3.2.8.1.1.14", - "1.3.36.3.3.2.8.1.1.14": "brainpoolP512t1" - }; - EcPrivateKey2 = class extends AsymmetricKey { - constructor() { - super(...arguments); - this.type = "private"; - } - getKey() { - const keyInfo = AsnParser.parse(this.data, index$1.PrivateKeyInfo); - return AsnParser.parse(keyInfo.privateKey, index$1.EcPrivateKey); - } - toJSON() { - const key = this.getKey(); - const json = { - kty: "EC", - crv: this.algorithm.namedCurve, - key_ops: this.usages, - ext: this.extractable - }; - return Object.assign(json, JsonSerializer.toJSON(key)); - } - fromJSON(json) { - if (!json.crv) { - throw new OperationError(`Cannot get named curve from JWK. Property 'crv' is required`); - } - const keyInfo = new index$1.PrivateKeyInfo(); - keyInfo.privateKeyAlgorithm.algorithm = "1.2.840.10045.2.1"; - keyInfo.privateKeyAlgorithm.parameters = AsnSerializer.serialize(new index$1.ObjectIdentifier(getOidByNamedCurve$1(json.crv))); - const key = JsonParser.fromJSON(json, { targetSchema: index$1.EcPrivateKey }); - keyInfo.privateKey = AsnSerializer.serialize(key); - this.data = Buffer.from(AsnSerializer.serialize(keyInfo)); - return this; - } - }; - EcPublicKey3 = class extends AsymmetricKey { - constructor() { - super(...arguments); - this.type = "public"; - } - getKey() { - const keyInfo = AsnParser.parse(this.data, index$1.PublicKeyInfo); - return new index$1.EcPublicKey(keyInfo.publicKey); - } - toJSON() { - const key = this.getKey(); - const json = { - kty: "EC", - crv: this.algorithm.namedCurve, - key_ops: this.usages, - ext: this.extractable - }; - return Object.assign(json, JsonSerializer.toJSON(key)); - } - fromJSON(json) { - if (!json.crv) { - throw new OperationError(`Cannot get named curve from JWK. Property 'crv' is required`); - } - const key = JsonParser.fromJSON(json, { targetSchema: index$1.EcPublicKey }); - const keyInfo = new index$1.PublicKeyInfo(); - keyInfo.publicKeyAlgorithm.algorithm = "1.2.840.10045.2.1"; - keyInfo.publicKeyAlgorithm.parameters = AsnSerializer.serialize(new index$1.ObjectIdentifier(getOidByNamedCurve$1(json.crv))); - keyInfo.publicKey = AsnSerializer.toASN(key).valueHex; - this.data = Buffer.from(AsnSerializer.serialize(keyInfo)); - return this; - } - }; - Sha1Provider = class extends ProviderCrypto { - constructor() { - super(...arguments); - this.name = "SHA-1"; - this.usages = []; - } - async onDigest(algorithm, data) { - return ShaCrypto.digest(algorithm, data); - } - }; - Sha256Provider = class extends ProviderCrypto { - constructor() { - super(...arguments); - this.name = "SHA-256"; - this.usages = []; - } - async onDigest(algorithm, data) { - return ShaCrypto.digest(algorithm, data); - } - }; - Sha384Provider = class extends ProviderCrypto { - constructor() { - super(...arguments); - this.name = "SHA-384"; - this.usages = []; - } - async onDigest(algorithm, data) { - return ShaCrypto.digest(algorithm, data); - } - }; - Sha512Provider = class extends ProviderCrypto { - constructor() { - super(...arguments); - this.name = "SHA-512"; - this.usages = []; - } - async onDigest(algorithm, data) { - return ShaCrypto.digest(algorithm, data); - } - }; - Sha3256Provider = class extends ProviderCrypto { - constructor() { - super(...arguments); - this.name = "SHA3-256"; - this.usages = []; - } - async onDigest(algorithm, data) { - return ShaCrypto.digest(algorithm, data); - } - }; - Sha3384Provider = class extends ProviderCrypto { - constructor() { - super(...arguments); - this.name = "SHA3-384"; - this.usages = []; - } - async onDigest(algorithm, data) { - return ShaCrypto.digest(algorithm, data); - } - }; - Sha3512Provider = class extends ProviderCrypto { - constructor() { - super(...arguments); - this.name = "SHA3-512"; - this.usages = []; - } - async onDigest(algorithm, data) { - return ShaCrypto.digest(algorithm, data); - } - }; - EcCrypto = class { - static async generateKey(algorithm, extractable, keyUsages) { - const privateKey = new EcPrivateKey2(); - privateKey.algorithm = algorithm; - privateKey.extractable = extractable; - privateKey.usages = keyUsages.filter((usage) => this.privateKeyUsages.indexOf(usage) !== -1); - const publicKey = new EcPublicKey3(); - publicKey.algorithm = algorithm; - publicKey.extractable = true; - publicKey.usages = keyUsages.filter((usage) => this.publicKeyUsages.indexOf(usage) !== -1); - const keys = import_crypto.default.generateKeyPairSync("ec", { - namedCurve: this.getOpenSSLNamedCurve(algorithm.namedCurve), - publicKeyEncoding: { - format: "der", - type: "spki" - }, - privateKeyEncoding: { - format: "der", - type: "pkcs8" - } - }); - privateKey.data = keys.privateKey; - publicKey.data = keys.publicKey; - const res = { - privateKey, - publicKey - }; - return res; - } - static async sign(algorithm, key, data) { - const cryptoAlg = ShaCrypto.getAlgorithmName(algorithm.hash); - const signer = import_crypto.default.createSign(cryptoAlg); - signer.update(Buffer.from(data)); - if (!key.pem) { - key.pem = `-----BEGIN PRIVATE KEY----- -${key.data.toString("base64")} ------END PRIVATE KEY-----`; - } - const options = { - key: key.pem - }; - const signature = signer.sign(options); - const ecSignature = AsnParser.parse(signature, index$1.EcDsaSignature); - const signatureRaw = EcUtils.encodeSignature(ecSignature, EcCurves.get(key.algorithm.namedCurve).size); - return signatureRaw.buffer; - } - static async verify(algorithm, key, signature, data) { - const cryptoAlg = ShaCrypto.getAlgorithmName(algorithm.hash); - const signer = import_crypto.default.createVerify(cryptoAlg); - signer.update(Buffer.from(data)); - if (!key.pem) { - key.pem = `-----BEGIN PUBLIC KEY----- -${key.data.toString("base64")} ------END PUBLIC KEY-----`; - } - const options = { - key: key.pem - }; - const ecSignature = new index$1.EcDsaSignature(); - const namedCurve = EcCurves.get(key.algorithm.namedCurve); - const signaturePoint = EcUtils.decodeSignature(signature, namedCurve.size); - ecSignature.r = import_pvtsutils6.BufferSourceConverter.toArrayBuffer(signaturePoint.r); - ecSignature.s = import_pvtsutils6.BufferSourceConverter.toArrayBuffer(signaturePoint.s); - const ecSignatureRaw = Buffer.from(AsnSerializer.serialize(ecSignature)); - const ok = signer.verify(options, ecSignatureRaw); - return ok; - } - static async deriveBits(algorithm, baseKey, length) { - const cryptoAlg = this.getOpenSSLNamedCurve(baseKey.algorithm.namedCurve); - const ecdh = import_crypto.default.createECDH(cryptoAlg); - const asnPrivateKey = AsnParser.parse(baseKey.data, index$1.PrivateKeyInfo); - const asnEcPrivateKey = AsnParser.parse(asnPrivateKey.privateKey, index$1.EcPrivateKey); - ecdh.setPrivateKey(Buffer.from(asnEcPrivateKey.privateKey)); - const asnPublicKey = AsnParser.parse(algorithm.public.data, index$1.PublicKeyInfo); - const bits = ecdh.computeSecret(Buffer.from(asnPublicKey.publicKey)); - if (length === null) { - return bits; - } - return new Uint8Array(bits).buffer.slice(0, length >> 3); - } - static async exportKey(format2, key) { - switch (format2.toLowerCase()) { - case "jwk": - return JsonSerializer.toJSON(key); - case "pkcs8": - case "spki": - return new Uint8Array(key.data).buffer; - case "raw": { - const publicKeyInfo = AsnParser.parse(key.data, index$1.PublicKeyInfo); - return publicKeyInfo.publicKey; - } - default: - throw new OperationError("format: Must be 'jwk', 'raw', pkcs8' or 'spki'"); - } - } - static async importKey(format2, keyData, algorithm, extractable, keyUsages) { - switch (format2.toLowerCase()) { - case "jwk": { - const jwk = keyData; - if (jwk.d) { - const asnKey = JsonParser.fromJSON(keyData, { targetSchema: index$1.EcPrivateKey }); - return this.importPrivateKey(asnKey, algorithm, extractable, keyUsages); - } else { - const asnKey = JsonParser.fromJSON(keyData, { targetSchema: index$1.EcPublicKey }); - return this.importPublicKey(asnKey, algorithm, extractable, keyUsages); - } - } - case "raw": { - const asnKey = new index$1.EcPublicKey(keyData); - return this.importPublicKey(asnKey, algorithm, extractable, keyUsages); - } - case "spki": { - const keyInfo = AsnParser.parse(new Uint8Array(keyData), index$1.PublicKeyInfo); - const asnKey = new index$1.EcPublicKey(keyInfo.publicKey); - this.assertKeyParameters(keyInfo.publicKeyAlgorithm.parameters, algorithm.namedCurve); - return this.importPublicKey(asnKey, algorithm, extractable, keyUsages); - } - case "pkcs8": { - const keyInfo = AsnParser.parse(new Uint8Array(keyData), index$1.PrivateKeyInfo); - const asnKey = AsnParser.parse(keyInfo.privateKey, index$1.EcPrivateKey); - this.assertKeyParameters(keyInfo.privateKeyAlgorithm.parameters, algorithm.namedCurve); - return this.importPrivateKey(asnKey, algorithm, extractable, keyUsages); - } - default: - throw new OperationError("format: Must be 'jwk', 'raw', 'pkcs8' or 'spki'"); - } - } - static assertKeyParameters(parameters, namedCurve) { - if (!parameters) { - throw new CryptoError("Key info doesn't have required parameters"); - } - let namedCurveIdentifier = ""; - try { - namedCurveIdentifier = AsnParser.parse(parameters, index$1.ObjectIdentifier).value; - } catch (e) { - throw new CryptoError("Cannot read key info parameters"); - } - if (getOidByNamedCurve$1(namedCurve) !== namedCurveIdentifier) { - throw new CryptoError("Key info parameter doesn't match to named curve"); - } - } - static async importPrivateKey(asnKey, algorithm, extractable, keyUsages) { - const keyInfo = new index$1.PrivateKeyInfo(); - keyInfo.privateKeyAlgorithm.algorithm = "1.2.840.10045.2.1"; - keyInfo.privateKeyAlgorithm.parameters = AsnSerializer.serialize(new index$1.ObjectIdentifier(getOidByNamedCurve$1(algorithm.namedCurve))); - keyInfo.privateKey = AsnSerializer.serialize(asnKey); - const key = new EcPrivateKey2(); - key.data = Buffer.from(AsnSerializer.serialize(keyInfo)); - key.algorithm = Object.assign({}, algorithm); - key.extractable = extractable; - key.usages = keyUsages; - return key; - } - static async importPublicKey(asnKey, algorithm, extractable, keyUsages) { - const keyInfo = new index$1.PublicKeyInfo(); - keyInfo.publicKeyAlgorithm.algorithm = "1.2.840.10045.2.1"; - const namedCurve = getOidByNamedCurve$1(algorithm.namedCurve); - keyInfo.publicKeyAlgorithm.parameters = AsnSerializer.serialize(new index$1.ObjectIdentifier(namedCurve)); - keyInfo.publicKey = asnKey.value; - const key = new EcPublicKey3(); - key.data = Buffer.from(AsnSerializer.serialize(keyInfo)); - key.algorithm = Object.assign({}, algorithm); - key.extractable = extractable; - key.usages = keyUsages; - return key; - } - static getOpenSSLNamedCurve(curve) { - switch (curve.toUpperCase()) { - case "P-256": - return "prime256v1"; - case "K-256": - return "secp256k1"; - case "P-384": - return "secp384r1"; - case "P-521": - return "secp521r1"; - default: - return curve; - } - } - }; - EcCrypto.publicKeyUsages = ["verify"]; - EcCrypto.privateKeyUsages = ["sign", "deriveKey", "deriveBits"]; - EcdsaProvider2 = class extends EcdsaProvider { - constructor() { - super(...arguments); - this.namedCurves = EcCurves.names; - this.hashAlgorithms = [ - "SHA-1", - "SHA-256", - "SHA-384", - "SHA-512", - "shake128", - "shake256", - "SHA3-256", - "SHA3-384", - "SHA3-512" - ]; - } - async onGenerateKey(algorithm, extractable, keyUsages) { - const keys = await EcCrypto.generateKey({ - ...algorithm, - name: this.name - }, extractable, keyUsages); - return { - privateKey: setCryptoKey(keys.privateKey), - publicKey: setCryptoKey(keys.publicKey) - }; - } - async onSign(algorithm, key, data) { - return EcCrypto.sign(algorithm, getCryptoKey(key), new Uint8Array(data)); - } - async onVerify(algorithm, key, signature, data) { - return EcCrypto.verify(algorithm, getCryptoKey(key), new Uint8Array(signature), new Uint8Array(data)); - } - async onExportKey(format2, key) { - return EcCrypto.exportKey(format2, getCryptoKey(key)); - } - async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { - const key = await EcCrypto.importKey(format2, keyData, { ...algorithm, name: this.name }, extractable, keyUsages); - return setCryptoKey(key); - } - checkCryptoKey(key, keyUsage) { - super.checkCryptoKey(key, keyUsage); - const internalKey = getCryptoKey(key); - if (!(internalKey instanceof EcPrivateKey2 || internalKey instanceof EcPublicKey3)) { - throw new TypeError("key: Is not EC CryptoKey"); - } - } - }; - EcdhProvider2 = class extends EcdhProvider { - constructor() { - super(...arguments); - this.namedCurves = EcCurves.names; - } - async onGenerateKey(algorithm, extractable, keyUsages) { - const keys = await EcCrypto.generateKey({ - ...algorithm, - name: this.name - }, extractable, keyUsages); - return { - privateKey: setCryptoKey(keys.privateKey), - publicKey: setCryptoKey(keys.publicKey) - }; - } - async onExportKey(format2, key) { - return EcCrypto.exportKey(format2, getCryptoKey(key)); - } - async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { - const key = await EcCrypto.importKey(format2, keyData, { ...algorithm, name: this.name }, extractable, keyUsages); - return setCryptoKey(key); - } - checkCryptoKey(key, keyUsage) { - super.checkCryptoKey(key, keyUsage); - const internalKey = getCryptoKey(key); - if (!(internalKey instanceof EcPrivateKey2 || internalKey instanceof EcPublicKey3)) { - throw new TypeError("key: Is not EC CryptoKey"); - } - } - async onDeriveBits(algorithm, baseKey, length) { - const bits = await EcCrypto.deriveBits({ ...algorithm, public: getCryptoKey(algorithm.public) }, getCryptoKey(baseKey), length); - return bits; - } - }; - edOIDs = { - [index$1.idEd448]: "Ed448", - "ed448": index$1.idEd448, - [index$1.idX448]: "X448", - "x448": index$1.idX448, - [index$1.idEd25519]: "Ed25519", - "ed25519": index$1.idEd25519, - [index$1.idX25519]: "X25519", - "x25519": index$1.idX25519 - }; - EdPrivateKey3 = class extends AsymmetricKey { - constructor() { - super(...arguments); - this.type = "private"; - } - getKey() { - const keyInfo = AsnParser.parse(this.data, index$1.PrivateKeyInfo); - return AsnParser.parse(keyInfo.privateKey, index$1.CurvePrivateKey); - } - toJSON() { - const key = this.getKey(); - const json = { - kty: "OKP", - crv: this.algorithm.namedCurve, - key_ops: this.usages, - ext: this.extractable - }; - return Object.assign(json, JsonSerializer.toJSON(key)); - } - fromJSON(json) { - if (!json.crv) { - throw new OperationError(`Cannot get named curve from JWK. Property 'crv' is required`); - } - const keyInfo = new index$1.PrivateKeyInfo(); - keyInfo.privateKeyAlgorithm.algorithm = getOidByNamedCurve(json.crv); - const key = JsonParser.fromJSON(json, { targetSchema: index$1.CurvePrivateKey }); - keyInfo.privateKey = AsnSerializer.serialize(key); - this.data = Buffer.from(AsnSerializer.serialize(keyInfo)); - return this; - } - }; - EdPublicKey3 = class extends AsymmetricKey { - constructor() { - super(...arguments); - this.type = "public"; - } - getKey() { - const keyInfo = AsnParser.parse(this.data, index$1.PublicKeyInfo); - return keyInfo.publicKey; - } - toJSON() { - const key = this.getKey(); - const json = { - kty: "OKP", - crv: this.algorithm.namedCurve, - key_ops: this.usages, - ext: this.extractable - }; - return Object.assign(json, { - x: import_pvtsutils6.Convert.ToBase64Url(key) - }); - } - fromJSON(json) { - if (!json.crv) { - throw new OperationError(`Cannot get named curve from JWK. Property 'crv' is required`); - } - if (!json.x) { - throw new OperationError(`Cannot get property from JWK. Property 'x' is required`); - } - const keyInfo = new index$1.PublicKeyInfo(); - keyInfo.publicKeyAlgorithm.algorithm = getOidByNamedCurve(json.crv); - keyInfo.publicKey = import_pvtsutils6.Convert.FromBase64Url(json.x); - this.data = Buffer.from(AsnSerializer.serialize(keyInfo)); - return this; - } - }; - EdCrypto = class { - static async generateKey(algorithm, extractable, keyUsages) { - const privateKey = new EdPrivateKey3(); - privateKey.algorithm = algorithm; - privateKey.extractable = extractable; - privateKey.usages = keyUsages.filter((usage) => this.privateKeyUsages.indexOf(usage) !== -1); - const publicKey = new EdPublicKey3(); - publicKey.algorithm = algorithm; - publicKey.extractable = true; - publicKey.usages = keyUsages.filter((usage) => this.publicKeyUsages.indexOf(usage) !== -1); - const type = algorithm.namedCurve.toLowerCase(); - const keys = import_crypto.default.generateKeyPairSync(type, { - publicKeyEncoding: { - format: "der", - type: "spki" - }, - privateKeyEncoding: { - format: "der", - type: "pkcs8" - } - }); - privateKey.data = keys.privateKey; - publicKey.data = keys.publicKey; - const res = { - privateKey, - publicKey - }; - return res; - } - static async sign(algorithm, key, data) { - if (!key.pem) { - key.pem = `-----BEGIN PRIVATE KEY----- -${key.data.toString("base64")} ------END PRIVATE KEY-----`; - } - const options = { - key: key.pem - }; - const signature = import_crypto.default.sign(null, Buffer.from(data), options); - return import_pvtsutils5.BufferSourceConverter.toArrayBuffer(signature); - } - static async verify(algorithm, key, signature, data) { - if (!key.pem) { - key.pem = `-----BEGIN PUBLIC KEY----- -${key.data.toString("base64")} ------END PUBLIC KEY-----`; - } - const options = { - key: key.pem - }; - const ok = import_crypto.default.verify(null, Buffer.from(data), options, Buffer.from(signature)); - return ok; - } - static async deriveBits(algorithm, baseKey, length) { - const publicKey = import_crypto.default.createPublicKey({ - key: algorithm.public.data, - format: "der", - type: "spki" - }); - const privateKey = import_crypto.default.createPrivateKey({ - key: baseKey.data, - format: "der", - type: "pkcs8" - }); - const bits = import_crypto.default.diffieHellman({ - publicKey, - privateKey - }); - return new Uint8Array(bits).buffer.slice(0, length >> 3); - } - static async exportKey(format2, key) { - switch (format2.toLowerCase()) { - case "jwk": - return JsonSerializer.toJSON(key); - case "pkcs8": - case "spki": - return new Uint8Array(key.data).buffer; - case "raw": { - const publicKeyInfo = AsnParser.parse(key.data, index$1.PublicKeyInfo); - return publicKeyInfo.publicKey; - } - default: - throw new OperationError("format: Must be 'jwk', 'raw', pkcs8' or 'spki'"); - } - } - static async importKey(format2, keyData, algorithm, extractable, keyUsages) { - switch (format2.toLowerCase()) { - case "jwk": { - const jwk = keyData; - if (jwk.d) { - const asnKey = JsonParser.fromJSON(keyData, { targetSchema: index$1.CurvePrivateKey }); - return this.importPrivateKey(asnKey, algorithm, extractable, keyUsages); - } else { - if (!jwk.x) { - throw new TypeError("keyData: Cannot get required 'x' filed"); - } - return this.importPublicKey(import_pvtsutils6.Convert.FromBase64Url(jwk.x), algorithm, extractable, keyUsages); - } - } - case "raw": { - return this.importPublicKey(keyData, algorithm, extractable, keyUsages); - } - case "spki": { - const keyInfo = AsnParser.parse(new Uint8Array(keyData), index$1.PublicKeyInfo); - return this.importPublicKey(keyInfo.publicKey, algorithm, extractable, keyUsages); - } - case "pkcs8": { - const keyInfo = AsnParser.parse(new Uint8Array(keyData), index$1.PrivateKeyInfo); - const asnKey = AsnParser.parse(keyInfo.privateKey, index$1.CurvePrivateKey); - return this.importPrivateKey(asnKey, algorithm, extractable, keyUsages); - } - default: - throw new OperationError("format: Must be 'jwk', 'raw', 'pkcs8' or 'spki'"); - } - } - static importPrivateKey(asnKey, algorithm, extractable, keyUsages) { - const key = new EdPrivateKey3(); - key.fromJSON({ - crv: algorithm.namedCurve, - d: import_pvtsutils6.Convert.ToBase64Url(asnKey.d) - }); - key.algorithm = Object.assign({}, algorithm); - key.extractable = extractable; - key.usages = keyUsages; - return key; - } - static async importPublicKey(asnKey, algorithm, extractable, keyUsages) { - const key = new EdPublicKey3(); - key.fromJSON({ - crv: algorithm.namedCurve, - x: import_pvtsutils6.Convert.ToBase64Url(asnKey) - }); - key.algorithm = Object.assign({}, algorithm); - key.extractable = extractable; - key.usages = keyUsages; - return key; - } - }; - EdCrypto.publicKeyUsages = ["verify"]; - EdCrypto.privateKeyUsages = ["sign", "deriveKey", "deriveBits"]; - EdDsaProvider2 = class extends EdDsaProvider { - async onGenerateKey(algorithm, extractable, keyUsages) { - const keys = await EdCrypto.generateKey({ - name: this.name, - namedCurve: algorithm.namedCurve.replace(/^ed/i, "Ed") - }, extractable, keyUsages); - return { - privateKey: setCryptoKey(keys.privateKey), - publicKey: setCryptoKey(keys.publicKey) - }; - } - async onSign(algorithm, key, data) { - return EdCrypto.sign(algorithm, getCryptoKey(key), new Uint8Array(data)); - } - async onVerify(algorithm, key, signature, data) { - return EdCrypto.verify(algorithm, getCryptoKey(key), new Uint8Array(signature), new Uint8Array(data)); - } - async onExportKey(format2, key) { - return EdCrypto.exportKey(format2, getCryptoKey(key)); - } - async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { - const key = await EdCrypto.importKey(format2, keyData, { ...algorithm, name: this.name }, extractable, keyUsages); - return setCryptoKey(key); - } - }; - EcdhEsProvider2 = class extends EcdhEsProvider { - async onGenerateKey(algorithm, extractable, keyUsages) { - const keys = await EdCrypto.generateKey({ - name: this.name, - namedCurve: algorithm.namedCurve.toUpperCase() - }, extractable, keyUsages); - return { - privateKey: setCryptoKey(keys.privateKey), - publicKey: setCryptoKey(keys.publicKey) - }; - } - async onDeriveBits(algorithm, baseKey, length) { - const bits = await EdCrypto.deriveBits({ ...algorithm, public: getCryptoKey(algorithm.public) }, getCryptoKey(baseKey), length); - return bits; - } - async onExportKey(format2, key) { - return EdCrypto.exportKey(format2, getCryptoKey(key)); - } - async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { - const key = await EdCrypto.importKey(format2, keyData, { ...algorithm, name: this.name }, extractable, keyUsages); - return setCryptoKey(key); - } - }; - PbkdfCryptoKey = class extends CryptoKey2 { - }; - Pbkdf2Provider2 = class extends Pbkdf2Provider { - async onDeriveBits(algorithm, baseKey, length) { - return new Promise((resolve, reject) => { - const salt = import_pvtsutils5.BufferSourceConverter.toArrayBuffer(algorithm.salt); - const hash = algorithm.hash.name.replace("-", ""); - import_crypto.default.pbkdf2(getCryptoKey(baseKey).data, Buffer.from(salt), algorithm.iterations, length >> 3, hash, (err, derivedBits) => { - if (err) { - reject(err); - } else { - resolve(new Uint8Array(derivedBits).buffer); - } - }); - }); - } - async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { - if (format2 === "raw") { - const key = new PbkdfCryptoKey(); - key.data = Buffer.from(keyData); - key.algorithm = { name: this.name }; - key.extractable = false; - key.usages = keyUsages; - return setCryptoKey(key); - } - throw new OperationError("format: Must be 'raw'"); - } - checkCryptoKey(key, keyUsage) { - super.checkCryptoKey(key, keyUsage); - if (!(getCryptoKey(key) instanceof PbkdfCryptoKey)) { - throw new TypeError("key: Is not PBKDF CryptoKey"); - } - } - }; - HmacCryptoKey = class extends CryptoKey2 { - get alg() { - const hash = this.algorithm.hash.name.toUpperCase(); - return `HS${hash.replace("SHA-", "")}`; - } - set alg(value) { - } - }; - __decorate([ - JsonProp({ name: "k", converter: JsonBase64UrlConverter }) - ], HmacCryptoKey.prototype, "data", void 0); - HmacProvider2 = class extends HmacProvider { - async onGenerateKey(algorithm, extractable, keyUsages) { - const length = (algorithm.length || this.getDefaultLength(algorithm.hash.name)) >> 3 << 3; - const key = new HmacCryptoKey(); - key.algorithm = { - ...algorithm, - length, - name: this.name - }; - key.extractable = extractable; - key.usages = keyUsages; - key.data = import_crypto.default.randomBytes(length >> 3); - return setCryptoKey(key); - } - async onSign(algorithm, key, data) { - const cryptoAlg = ShaCrypto.getAlgorithmName(key.algorithm.hash); - const hmac = import_crypto.default.createHmac(cryptoAlg, getCryptoKey(key).data).update(Buffer.from(data)).digest(); - return new Uint8Array(hmac).buffer; - } - async onVerify(algorithm, key, signature, data) { - const cryptoAlg = ShaCrypto.getAlgorithmName(key.algorithm.hash); - const hmac = import_crypto.default.createHmac(cryptoAlg, getCryptoKey(key).data).update(Buffer.from(data)).digest(); - return hmac.compare(Buffer.from(signature)) === 0; - } - async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { - let key; - switch (format2.toLowerCase()) { - case "jwk": - key = JsonParser.fromJSON(keyData, { targetSchema: HmacCryptoKey }); - break; - case "raw": - key = new HmacCryptoKey(); - key.data = Buffer.from(keyData); - break; - default: - throw new OperationError("format: Must be 'jwk' or 'raw'"); - } - key.algorithm = { - hash: { name: algorithm.hash.name }, - name: this.name, - length: key.data.length << 3 - }; - key.extractable = extractable; - key.usages = keyUsages; - return setCryptoKey(key); - } - async onExportKey(format2, key) { - switch (format2.toLowerCase()) { - case "jwk": - return JsonSerializer.toJSON(getCryptoKey(key)); - case "raw": - return new Uint8Array(getCryptoKey(key).data).buffer; - default: - throw new OperationError("format: Must be 'jwk' or 'raw'"); - } - } - checkCryptoKey(key, keyUsage) { - super.checkCryptoKey(key, keyUsage); - if (!(getCryptoKey(key) instanceof HmacCryptoKey)) { - throw new TypeError("key: Is not HMAC CryptoKey"); - } - } - }; - HkdfCryptoKey = class extends CryptoKey2 { - }; - HkdfProvider2 = class extends HkdfProvider { - async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { - if (format2.toLowerCase() !== "raw") { - throw new OperationError("Operation not supported"); - } - const key = new HkdfCryptoKey(); - key.data = Buffer.from(keyData); - key.algorithm = { name: this.name }; - key.extractable = extractable; - key.usages = keyUsages; - return setCryptoKey(key); - } - async onDeriveBits(params, baseKey, length) { - const hash = params.hash.name.replace("-", ""); - const hashLength = import_crypto.default.createHash(hash).digest().length; - const byteLength = length / 8; - const info = import_pvtsutils5.BufferSourceConverter.toUint8Array(params.info); - const PRK = import_crypto.default.createHmac(hash, import_pvtsutils5.BufferSourceConverter.toUint8Array(params.salt)).update(import_pvtsutils5.BufferSourceConverter.toUint8Array(getCryptoKey(baseKey).data)).digest(); - const blocks = [Buffer.alloc(0)]; - const blockCount = Math.ceil(byteLength / hashLength) + 1; - for (let i = 1; i < blockCount; ++i) { - blocks.push(import_crypto.default.createHmac(hash, PRK).update(Buffer.concat([blocks[i - 1], info, Buffer.from([i])])).digest()); - } - return Buffer.concat(blocks).slice(0, byteLength); - } - checkCryptoKey(key, keyUsage) { - super.checkCryptoKey(key, keyUsage); - if (!(getCryptoKey(key) instanceof HkdfCryptoKey)) { - throw new TypeError("key: Is not HKDF CryptoKey"); - } - } - }; - ShakeCrypto = class { - static digest(algorithm, data) { - const hash = import_crypto.default.createHash(algorithm.name.toLowerCase(), { outputLength: algorithm.length }).update(Buffer.from(data)).digest(); - return new Uint8Array(hash).buffer; - } - }; - Shake128Provider2 = class extends Shake128Provider { - async onDigest(algorithm, data) { - return ShakeCrypto.digest(algorithm, data); - } - }; - Shake256Provider2 = class extends Shake256Provider { - async onDigest(algorithm, data) { - return ShakeCrypto.digest(algorithm, data); - } - }; - SubtleCrypto2 = class extends SubtleCrypto { - constructor() { - var _a2; - super(); - this.providers.set(new AesCbcProvider2()); - this.providers.set(new AesCtrProvider2()); - this.providers.set(new AesGcmProvider2()); - this.providers.set(new AesCmacProvider2()); - this.providers.set(new AesKwProvider2()); - this.providers.set(new AesEcbProvider2()); - const ciphers = crypto.getCiphers(); - if (ciphers.includes("des-cbc")) { - this.providers.set(new DesCbcProvider()); - } - this.providers.set(new DesEde3CbcProvider()); - this.providers.set(new RsaSsaProvider2()); - this.providers.set(new RsaPssProvider2()); - this.providers.set(new RsaOaepProvider2()); - this.providers.set(new RsaEsProvider()); - this.providers.set(new EcdsaProvider2()); - this.providers.set(new EcdhProvider2()); - this.providers.set(new Sha1Provider()); - this.providers.set(new Sha256Provider()); - this.providers.set(new Sha384Provider()); - this.providers.set(new Sha512Provider()); - this.providers.set(new Pbkdf2Provider2()); - this.providers.set(new HmacProvider2()); - this.providers.set(new HkdfProvider2()); - const nodeMajorVersion = (_a2 = /^v(\d+)/.exec(process2.version)) === null || _a2 === void 0 ? void 0 : _a2[1]; - if (nodeMajorVersion && parseInt(nodeMajorVersion, 10) >= 12) { - this.providers.set(new Shake128Provider2()); - this.providers.set(new Shake256Provider2()); - } - const hashes = crypto.getHashes(); - if (hashes.includes("sha3-256")) { - this.providers.set(new Sha3256Provider()); - } - if (hashes.includes("sha3-384")) { - this.providers.set(new Sha3384Provider()); - } - if (hashes.includes("sha3-512")) { - this.providers.set(new Sha3512Provider()); - } - if (nodeMajorVersion && parseInt(nodeMajorVersion, 10) >= 14) { - this.providers.set(new EdDsaProvider2()); - this.providers.set(new EcdhEsProvider2()); - } - } - }; - Crypto2 = class extends Crypto { - constructor() { - super(...arguments); - this.subtle = new SubtleCrypto2(); - } - getRandomValues(array) { - if (!ArrayBuffer.isView(array)) { - throw new TypeError("Failed to execute 'getRandomValues' on 'Crypto': parameter 1 is not of type 'ArrayBufferView'"); - } - const buffer = Buffer.from(array.buffer, array.byteOffset, array.byteLength); - import_crypto.default.randomFillSync(buffer); - return array; - } - }; - } - }); - - // ../application/source/math/random.mjs - var random_exports = {}; - __export(random_exports, { - random: () => random - }); - function random(min, max) { - if (min === void 0) { - min = 0; - } - if (max === void 0) { - max = MAX; - } - if (max < min) { - throw new Error("max must be greater than min"); - } - return Math.round(create(min, max)); - } - function create(min, max) { - let crypt; - let globalReference2 = getGlobal(); - crypt = globalReference2?.["crypto"] || globalReference2?.["msCrypto"] || globalReference2?.["crypto"] || void 0; - if (typeof crypt === "undefined") { - throw new Error("missing crypt"); - } - let rval = 0; - const range = max - min; - if (range < 2) { - throw new Error("the distance is too small to create a random number."); - } - const bitsNeeded = Math.ceil(Math.log2(range)); - if (bitsNeeded > 53) { - throw new Error("we cannot generate numbers larger than 53 bits."); - } - const bytesNeeded = Math.ceil(bitsNeeded / 8); - const mask = Math.pow(2, bitsNeeded) - 1; - const byteArray = new Uint8Array(bytesNeeded); - crypt.getRandomValues(byteArray); - let p = (bytesNeeded - 1) * 8; - for (var i = 0; i < bytesNeeded; i++) { - rval += byteArray[i] * Math.pow(2, p); - p -= 8; - } - rval = rval & mask; - if (rval >= range) { - return create(min, max); - } - if (rval < min) { - rval += min; - } - return rval; - } - var MAX; - var init_random = __esm({ - "../application/source/math/random.mjs"() { - init_global(); - MAX = 1e9; - Math.log2 = Math.log2 || function(n) { - return Math.log(n) / Math.log(2); - }; - } - }); - - // ../application/source/types/randomid.mjs - var randomid_exports = {}; - __export(randomid_exports, { - RandomID: () => RandomID - }); - var internalCounter2, RandomID; - var init_randomid = __esm({ - "../application/source/types/randomid.mjs"() { - init_random(); - init_global(); - init_id(); - internalCounter2 = 0; - RandomID = class extends ID { - /** - * create new object - */ - constructor() { - super(); - internalCounter2 += 1; - this.id = getGlobal().btoa(random(1, 1e4)).replace(/=/g, "").replace(/^[0-9]+/, "X") + internalCounter2; - } - }; - } - }); - - // ../application/source/types/uuid.mjs - var uuid_exports = {}; - __export(uuid_exports, { - UUID: () => UUID - }); - function createWithRandom() { - return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) { - const r = random(0, 65e3) * 16 | 0; - const v = c === "x" ? r : r & 3 | 8; - return v.toString(16)[0]; - }); - } - function createWithCrypto() { - const crypt = getGlobalObject("crypto"); - if (!isObject(crypt)) - return; - if (typeof crypt?.["randomUUID"]) - return; - return crypt.randomUUID(); - } - var UUID; - var init_uuid = __esm({ - "../application/source/types/uuid.mjs"() { - init_constants(); - init_random(); - init_is(); - init_base(); - init_global(); - UUID = class extends Base { - /** - * - */ - constructor() { - super(); - let uuid = createWithCrypto(); - if (uuid === void 0) { - uuid = createWithRandom(); - } - if (uuid === void 0) { - throw new Error("unsupported"); - } - this[internalSymbol] = { - value: uuid - }; - } - /** - * - * @return {string} - */ - toString() { - return this[internalSymbol]["value"]; - } - }; - } - }); - - // test/web/prepare.js - if (typeof window === "object") { - (function() { - let sayswho = function() { - var ua = navigator.userAgent, tem, M = ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || []; - if (/trident/i.test(M[1])) { - tem = /\brv[ :]+(\d+)/g.exec(ua) || []; - return "IE " + (tem[1] || ""); - } - if (M[1] === "Chrome") { - tem = ua.match(/\b(OPR|Edge)\/(\d+)/); - if (tem != null) - return tem.slice(1).join(" ").replace("OPR", "Opera"); - } - M = M[2] ? [M[1], M[2]] : [navigator.appName, navigator.appVersion, "-?"]; - if ((tem = ua.match(/version\/(\d+)/i)) != null) - M.splice(1, 1, tem[1]); - return M.join(" "); - }(); - let element = document.querySelector("h1"); - element.innerHTML += " " + sayswho; - })(); - } - - // node_modules/.pnpm/chai@4.3.7/node_modules/chai/index.mjs - var import_index = __toESM(require_chai2(), 1); - var expect = import_index.default.expect; - var version = import_index.default.version; - var Assertion = import_index.default.Assertion; - var AssertionError = import_index.default.AssertionError; - var util = import_index.default.util; - var config = import_index.default.config; - var use = import_index.default.use; - var should = import_index.default.should; - var assert = import_index.default.assert; - var core = import_index.default.core; - var chai_default = import_index.default; - - // ../application/source/types/version.mjs - init_base(); - init_constants(); - var Version = class extends Base { - /** - * - * @param major - * @param minor - * @param patch - * @throws {Error} major is not a number - * @throws {Error} minor is not a number - * @throws {Error} patch is not a number - */ - constructor(major, minor, patch) { - super(); - if (typeof major === "string" && minor === void 0 && patch === void 0) { - let parts = major.toString().split("."); - major = parseInt(parts[0] || 0); - minor = parseInt(parts[1] || 0); - patch = parseInt(parts[2] || 0); - } - if (major === void 0) { - throw new Error("major version is undefined"); - } - if (minor === void 0) { - minor = 0; - } - if (patch === void 0) { - patch = 0; - } - this.major = parseInt(major); - this.minor = parseInt(minor); - this.patch = parseInt(patch); - if (isNaN(this.major)) { - throw new Error("major is not a number"); - } - if (isNaN(this.minor)) { - throw new Error("minor is not a number"); - } - if (isNaN(this.patch)) { - throw new Error("patch is not a number"); - } - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/types/version"); - } - /** - * - * @returns {string} - */ - toString() { - return `${this.major}.${this.minor}.${this.patch}`; - } - /** - * returns 0 if equal, -1 if the object version is less and 1 if greater - * than the compared version - * - * @param {string|Version} version Version to compare - * @returns {number} - */ - compareTo(version3) { - if (version3 instanceof Version) { - version3 = version3.toString(); - } - if (typeof version3 !== "string") { - throw new Error("type exception"); - } - if (version3 === this.toString()) { - return 0; - } - let a2 = [this.major, this.minor, this.patch]; - let b = version3.split("."); - let len = Math.max(a2.length, b.length); - for (let i = 0; i < len; i += 1) { - if (a2[i] && !b[i] && parseInt(a2[i]) > 0 || parseInt(a2[i]) > parseInt(b[i])) { - return 1; - } else if (b[i] && !a2[i] && parseInt(b[i]) > 0 || parseInt(a2[i]) < parseInt(b[i])) { - return -1; - } - } - return 0; - } - }; - var monsterVersion; - function getMonsterVersion() { - if (monsterVersion instanceof Version) { - return monsterVersion; - } - monsterVersion = new Version("3.35.4"); - return monsterVersion; - } - - // test/cases/monster.mjs - describe("Monster", function() { - describe(".getMonsterVersion()", function() { - let monsterVersion2; - monsterVersion2 = new Version("3.35.4"); - let m = getMonsterVersion(); - it("should " + monsterVersion2 + " is " + m, function() { - expect(m.compareTo(monsterVersion2)).is.equal(0); - }); - }); - }); - - // ../application/source/logging/handler.mjs - init_base(); - init_validate(); - - // ../application/source/logging/logentry.mjs - init_base(); - init_validate(); - var LogEntry = class extends Base { - /** - * - * @param {Integer} loglevel - * @param {...*} args - */ - constructor(loglevel, ...args) { - super(); - validateInteger(loglevel); - this.loglevel = loglevel; - this.arguments = args; - } - /** - * - * @returns {integerr} - */ - getLogLevel() { - return this.loglevel; - } - /** - * - * @returns {array} - */ - getArguments() { - return this.arguments; - } - }; - - // ../application/source/logging/handler.mjs - var Handler = class extends Base { - constructor() { - super(); - this.loglevel = OFF; - } - /** - * This is the central log function. this method must be - * overwritten by derived handlers with their own logic. - * - * ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF (ALL = 0xff;OFF = 0x00; - * - * @param {LogEntry} entry - * @returns {boolean} - */ - log(entry) { - validateInstance(entry, LogEntry); - if (this.loglevel < entry.getLogLevel()) { - return false; - } - return true; - } - /** - * set loglevel - * - * @param {integer} loglevel - * @returns {Handler} - * @since 1.5.0 - */ - setLogLevel(loglevel) { - validateInteger(loglevel); - this.loglevel = loglevel; - return this; - } - /** - * get loglevel - * - * @returns {integer} - * @since 1.5.0 - */ - getLogLevel() { - return this.loglevel; - } - /** - * Set log level to All - * - * @returns {Handler} - * @since 1.5.0 - */ - setAll() { - this.setLogLevel(ALL); - return this; - } - /** - * Set log level to Trace - * - * @returns {Handler} - * @since 1.5.0 - */ - setTrace() { - this.setLogLevel(TRACE); - return this; - } - /** - * Set log level to Debug - * - * @returns {Handler} - * @since 1.5.0 - */ - setDebug() { - this.setLogLevel(DEBUG); - return this; - } - /** - * Set log level to Info - * - * @returns {Handler} - * @since 1.5.0 - */ - setInfo() { - this.setLogLevel(INFO); - return this; - } - /** - * Set log level to Warn - * - * @returns {undefined} - * @since 1.5.0 - */ - setWarn() { - this.setLogLevel(WARN); - return this; - } - /** - * Set log level to Error - * - * @returns {Handler} - * @since 1.5.0 - */ - setError() { - this.setLogLevel(ERROR); - return this; - } - /** - * Set log level to Fatal - * - * @returns {Handler} - * @since 1.5.0 - */ - setFatal() { - this.setLogLevel(FATAL); - return this; - } - /** - * Set log level to Off - * - * @returns {Handler} - * @since 1.5.0 - */ - setOff() { - this.setLogLevel(OFF); - return this; - } - }; - - // ../application/source/logging/logger.mjs - init_base(); - init_validate(); - var ALL = 255; - var TRACE = 64; - var DEBUG = 32; - var INFO = 16; - var WARN = 8; - var ERROR = 4; - var FATAL = 2; - var OFF = 0; - var Logger = class extends Base { - /** - * - */ - constructor() { - super(); - this.handler = /* @__PURE__ */ new Set(); - } - /** - * - * @param {Handler} handler - * @returns {Logger} - * @throws {Error} the handler must be an instance of Handler - */ - addHandler(handler) { - validateObject(handler); - if (!(handler instanceof Handler)) { - throw new Error("the handler must be an instance of Handler"); - } - this.handler.add(handler); - return this; - } - /** - * - * @param {Handler} handler - * @returns {Logger} - * @throws {Error} the handler must be an instance of Handler - */ - removeHandler(handler) { - validateObject(handler); - if (!(handler instanceof Handler)) { - throw new Error("the handler must be an instance of Handler"); - } - this.handler.delete(handler); - return this; - } - /** - * log Trace message - * - * ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF (ALL = 0xff;OFF = 0x00; - * - * @param {*} arguments - * @returns {Logger} - * @since 1.5.0 - */ - logTrace(...args) { - if (typeof args !== "object" || args[0] === null) { - throw new Error("the first argument must be an object"); - } - triggerLog.apply(this, [TRACE, ...args]); - return this; - } - /** - * log Debug message - * - * ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF (ALL = 0xff;OFF = 0x00; - * - * @param {*} arguments - * @returns {Logger} - * @since 1.5.0 - */ - logDebug(...args) { - if (typeof args !== "object" || args[0] === null) { - throw new Error("the first argument must be an object"); - } - triggerLog.apply(this, [DEBUG, ...args]); - return this; - } - /** - * log Info message - * - * ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF (ALL = 0xff;OFF = 0x00; - * - * - * @param {*} arguments - * @returns {Logger} - * @since 1.5.0 - */ - logInfo(...args) { - if (typeof args !== "object" || args[0] === null) { - throw new Error("the first argument must be an object"); - } - triggerLog.apply(this, [INFO, ...args]); - return this; - } - /** - * log Warn message - * - * ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF (ALL = 0xff;OFF = 0x00; - * - * @param {*} arguments - * @returns {Logger} - * @since 1.5.0 - */ - logWarn(...args) { - if (typeof args !== "object" || args[0] === null) { - throw new Error("the first argument must be an object"); - } - triggerLog.apply(this, [WARN, ...args]); - return this; - } - /** - * log Error message - * - * ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF (ALL = 0xff;OFF = 0x00; - * - * @param {*} arguments - * @returns {Logger} - * @since 1.5.0 - */ - logError(...args) { - if (typeof args !== "object" || args[0] === null) { - throw new Error("the first argument must be an object"); - } - triggerLog.apply(this, [ERROR, ...args]); - return this; - } - /** - * log Fatal message - * - * ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF (ALL = 0xff;OFF = 0x00; - * - * @param {*} arguments - * @returns {Logger} - * @since 1.5.0 - */ - logFatal(...args) { - if (typeof args !== "object" || args[0] === null) { - throw new Error("the first argument must be an object"); - } - triggerLog.apply(this, [FATAL, ...args]); - return this; - } - /** - * Labels - * - * @param {integer} level - * @returns {string} - */ - getLabel(level) { - validateInteger(level); - if (level === ALL) - return "ALL"; - if (level === TRACE) - return "TRACE"; - if (level === DEBUG) - return "DEBUG"; - if (level === INFO) - return "INFO"; - if (level === WARN) - return "WARN"; - if (level === ERROR) - return "ERROR"; - if (level === FATAL) - return "FATAL"; - if (level === OFF) - return "OFF"; - return "unknown"; - } - /** - * Level - * - * @param {string} label - * @returns {integer} - */ - getLevel(label) { - validateString(label); - if (label === "ALL") - return ALL; - if (label === "TRACE") - return TRACE; - if (label === "DEBUG") - return DEBUG; - if (label === "INFO") - return INFO; - if (label === "WARN") - return WARN; - if (label === "ERROR") - return ERROR; - if (label === "FATAL") - return FATAL; - if (label === "OFF") - return OFF; - return 0; - } - }; - function triggerLog(loglevel, ...args) { - var logger = this; - for (let handler of logger.handler) { - handler.log(new LogEntry(loglevel, args)); - } - return logger; - } - - // test/cases/logging/logger.mjs - describe("Logging", function() { - describe("new Logger", function() { - it("should return instanceof Logger", function() { - expect(new Logger()).to.instanceOf(Logger); - }); - }); - describe("Logger.logTrace()", function() { - it("should return instanceof Logger", function() { - expect(new Logger().logTrace("test")).to.instanceOf(Logger); - }); - }); - describe("Logger.logDebug()", function() { - it("should return instanceof Logger", function() { - expect(new Logger().logDebug("test")).to.instanceOf(Logger); - }); - }); - describe("Logger.logInfo()", function() { - it("should return instanceof Logger", function() { - expect(new Logger().logInfo("test")).to.instanceOf(Logger); - }); - }); - describe("Logger.logWarn()", function() { - it("should return instanceof Logger", function() { - expect(new Logger().logWarn("test")).to.instanceOf(Logger); - }); - }); - describe("Logger.logError()", function() { - it("should return instanceof Logger", function() { - expect(new Logger().logError("test")).to.instanceOf(Logger); - }); - }); - describe("Logger.logFatal()", function() { - it("should return instanceof Logger", function() { - expect(new Logger().logFatal("test")).to.instanceOf(Logger); - }); - }); - describe("Logger.getLevel()", function() { - [ - ["ALL", ALL], - ["TRACE", TRACE], - ["DEBUG", DEBUG], - ["INFO", INFO], - ["WARN", WARN], - ["ERROR", ERROR], - ["FATAL", FATAL], - ["OFF", OFF] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - it(a2 + " should return " + b, function() { - expect(new Logger().getLevel(a2)).to.be.equals(b); - }); - }); - }); - describe("Logger.getLabel()", function() { - [ - ["ALL", ALL], - ["TRACE", TRACE], - ["DEBUG", DEBUG], - ["INFO", INFO], - ["WARN", WARN], - ["ERROR", ERROR], - ["FATAL", FATAL], - ["OFF", OFF] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - it(a2 + " should return " + b, function() { - expect(new Logger().getLabel(b)).to.be.equals(a2); - }); - }); - }); - }); - - // test/cases/logging/logentry.mjs - describe("Log", function() { - describe("new Log", function() { - it("should return instanceof Log", function() { - expect(new LogEntry(1, "a", "b", "c")).to.instanceOf(LogEntry); - }); - }); - describe("Log.loglevel", function() { - let log; - beforeEach(function() { - log = new LogEntry(1, false, "test", 99, { a: true }); - }); - it("should return loglevel 1", function() { - expect(log.getLogLevel()).to.be.equal(1); - }); - it("should return arguments", function() { - expect(log.getArguments()).to.have.deep.members([false, "test", 99, { a: true }]); - }); - }); - }); - - // ../application/source/logging/handler/console.mjs - init_global(); - var ConsoleHandler = class extends Handler { - constructor() { - super(); - } - /** - * This is the central log function. this method must be - * overwritten by derived handlers with their own logic. - * - * ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF (ALL = 0xff;OFF = 0x00; - * - * @param {LogEntry} entry - * @returns {boolean} - */ - log(entry) { - if (super.log(entry)) { - let console2 = getGlobalObject("console"); - if (!console2) - return false; - if (!console2.error) - console2.error = console2.log; - if (!console2.warn) - console2.warn = console2.log; - switch (entry.getLogLevel()) { - case TRACE: - case DEBUG: - case INFO: - console2.log(entry.toString()); - break; - case FATAL: - case ERROR: - console2.error(entry.toString()); - break; - case WARN: - console2.warn(entry.toString()); - break; - default: - console2.log(entry.toString()); - break; - } - return true; - } - return false; - } - }; - - // test/cases/logging/handler/console.mjs - describe("Logging", function() { - describe("ConsoleHandler", function() { - it("should create ConsoleHandler", function() { - expect(new ConsoleHandler()).to.be.instanceof(ConsoleHandler); - }); - it("should log to console", function() { - expect(new ConsoleHandler().setAll().log(new LogEntry(FATAL, [1, true, "fatal"]))).to.be.true; - }); - it("should log to console", function() { - expect(new ConsoleHandler().setAll().log(new LogEntry(TRACE, [1, true, "trace"]))).to.be.true; - }); - it("should log to console", function() { - expect(new ConsoleHandler().setAll().log(new LogEntry(WARN, [1, true, "warn"]))).to.be.true; - }); - it("should log to console", function() { - expect(new ConsoleHandler().setAll().log(new LogEntry(DEBUG, [1, true, "debug"]))).to.be.true; - }); - it("should log to console", function() { - expect(new ConsoleHandler().setAll().log(new LogEntry(ERROR, [1, true, "error"]))).to.be.true; - }); - it("should log to console", function() { - expect(new ConsoleHandler().setAll().log(new LogEntry(INFO, [1, true, "info"]))).to.be.true; - }); - }); - }); - - // test/cases/logging/handler.mjs - describe("Logging", function() { - describe("Handler.setLogLevel().getLogLevel()", function() { - [ - [ALL], - [TRACE], - [DEBUG], - [INFO], - [WARN], - [ERROR], - [FATAL], - [OFF] - ].forEach(function(data) { - let a2 = data.shift(); - it("the function should return the set value " + a2, function() { - expect(new Handler().setLogLevel(a2).getLogLevel()).to.be.equal(a2); - }); - }); - }); - describe("Handler.log()", function() { - it("should return instanceof Handler", function() { - expect(new Handler().log(new LogEntry(0, "test"))).to.be.true; - }); - }); - describe("Handler.log()", function() { - let handler; - class TestHandler extends Handler { - log(entry) { - super.log(entry); - } - } - beforeEach(function() { - let handler2 = new TestHandler(); - }); - it("should return instanceof Handler", function() { - expect(new Handler().log(new LogEntry(0, "test"))).to.be.true; - }); - }); - describe(".log() with loglevel", function() { - let TestHandler; - before(() => { - TestHandler = class extends Handler { - constructor() { - super(); - this.calls = 0; - } - log(loglevel) { - if (super.log(loglevel) === true) { - this.calls++; - return true; - } - return false; - } - }; - }); - [ - // ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF (ALL = 0xff;OFF = 0x00; - [ALL, 6], - [TRACE, 6], - [DEBUG, 5], - [INFO, 4], - [WARN, 3], - [ERROR, 2], - [FATAL, 1], - [OFF, 0] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - it("is.log(" + a2 + ") should log " + b, function() { - let handler = new TestHandler().setLogLevel(a2); - handler.log(new LogEntry(TRACE)); - handler.log(new LogEntry(DEBUG)); - handler.log(new LogEntry(INFO)); - handler.log(new LogEntry(WARN)); - handler.log(new LogEntry(ERROR)); - handler.log(new LogEntry(FATAL)); - expect(handler.calls).is.equal(b); - }); - }); - }); - describe("Handler.setLogLevel()", function() { - it("should return instanceof Handler", function() { - expect(new Handler().setLogLevel(ALL)).to.instanceOf(Handler); - }); - }); - describe("Handler.getLogLevel()", function() { - it("new logger should be 0", function() { - expect(new Handler().getLogLevel()).to.be.equal(OFF); - }); - }); - describe("Handler.setAll()", function() { - it(" should instanceof Handler", function() { - expect(new Handler().setAll()).to.instanceOf(Handler); - }); - }); - describe("Handler.setTrace()", function() { - it("new logger should instanceof Handler", function() { - expect(new Handler().setTrace()).to.instanceOf(Handler); - }); - }); - describe("Handler.setDebug()", function() { - it(" should instanceof Handler", function() { - expect(new Handler().setDebug()).to.instanceOf(Handler); - }); - }); - describe("Handler.setInfo()", function() { - it("should return instanceof Handler", function() { - expect(new Handler().setInfo()).to.instanceOf(Handler); - }); - }); - describe("Handler.setWarn()", function() { - it(" should instanceof Handler", function() { - expect(new Handler().setWarn()).to.instanceOf(Handler); - }); - }); - describe("Handler.setError()", function() { - it("should return instanceof Handler", function() { - expect(new Handler().setError()).to.instanceOf(Handler); - }); - }); - describe("Handler.setFatal()", function() { - it("should return instanceof Handler", function() { - expect(new Handler().setFatal()).to.instanceOf(Handler); - }); - }); - describe("Handler.setOff()", function() { - it("should return instanceof Handler", function() { - expect(new Handler().setOff()).to.instanceOf(Handler); - }); - }); - }); - - // test/cases/text/formatter.mjs - init_formatter(); - describe("Formatter", function() { - describe("examples", function() { - it("rfc example should run", function() { - expect(new Formatter({ - a: { - b: { - c: "Hello" - }, - d: "World", - e: 1 - } - }).format("${a.b.c} ${a.d | toupper}!")).to.be.equal("Hello WORLD!"); - }); - it("doc example should run", function() { - expect(new Formatter({ - a: { - b: { - c: "Hello" - }, - d: "world" - } - }).format("${a.b.c} ${a.d | ucfirst}!")).to.be.equal("Hello World!"); - }); - }); - describe("set marker()", function() { - [ - ["#a#", "#", void 0, "test"], - ["{a}", "{", "}", "test"], - ["i18n{a}", "i18n{", "}", "test"] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - let c = data.shift(); - let d = data.shift(); - it("format " + a2 + " with marker " + b + " and " + c + " should return " + b, function() { - expect( - new Formatter({ - a: "test" - }).setMarker(b, c).format(a2) - ).to.equal(d); - }); - }); - }); - describe("examples()", function() { - [ - ["${a | tojson}", '{"b":{"c":"Hello"},"d":"World","e":1}'], - ["click ${a.d} times", "click World times"], - [" ${a.b.c} ", " Hello "], - [" ${a.b.c}", " Hello"], - ["${a.b.c} ", "Hello "], - ["${a.b.c}", "Hello"], - ["${a.b.c}${a.b.c}", "HelloHello"], - ["${a.b.c} ${a.b.c}", "Hello Hello"], - ["${a.b.c} ${a.b.c} ", "Hello Hello "], - [" ${a.b.c} ${a.b.c} ", " Hello Hello "], - [" ${a.b.c} ${a.d} ", " Hello World "], - [" ${a.b.c} ${a.b.c | toupper | length | tostring} ", " Hello 5 "] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - it("format " + a2 + " should return " + b, function() { - let obj = { - a: { - b: { - c: "Hello" - }, - d: "World", - e: 1 - } - }; - expect(new Formatter(obj).format(a2)).is.equal(b); - }); - }); - }); - describe("Marker in marker", function() { - let text = "${mykey${subkey}}"; - let expected = "1"; - it("format " + text + " should " + expected, function() { - let obj = { - mykey2: "1", - subkey: "2" - }; - expect(new Formatter(obj).format(text)).is.equal(expected); - }); - }); - describe("setParameterChars()", function() { - it("setParameterChars() should return Instance", function() { - expect(new Formatter({}).setParameterChars("a", "b")).is.instanceof(Formatter); - }); - }); - describe("with callbacks", function() { - it("add callback", function() { - const formatter = new Formatter({ - x: "1" - }, { - callbacks: { - my: (value) => { - return "!" + value + "!"; - } - } - }); - expect(formatter.format("${x | call:my}")).is.equal("!1!"); - }); - }); - describe("Marker in marker with parameter", function() { - let text = "${mykey::mykey=${subkey}}"; - let expected = "2"; - it("format " + text + " should " + expected, function() { - let obj = { - subkey: "2" - }; - expect(new Formatter(obj).format(text)).is.equal(expected); - }); - }); - describe("exceptions", function() { - [ - ["${a.b.x}", TypeError], - ["${a.b.d | toupper | length}", TypeError], - ["${a.b.d}", TypeError], - // a.b.d return undefined by pathfinder - ["${a.b.d | tolower}", TypeError], - // a.b.d return undefined by pathfinder - ["${a | }", Error] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - it("format " + a2 + " should throw " + typeof b, function() { - expect( - () => { - new Formatter({ - a: { - b: { - c: "test", - d: 4 - } - } - }).format(a2); - } - ).to.throw(b); - }); - }); - }); - describe("Formatter", () => { - it("should format a basic string with object values", () => { - const formatter = new Formatter({ name: "John", age: 30 }); - const result = formatter.format("My name is ${name} and I am ${age | tostring} years old."); - expect(result).to.equal("My name is John and I am 30 years old."); - }); - it("should format a string with nested markers", () => { - const text = "${mykey${subkey}}"; - const obj = { mykey2: "1", subkey: "2" }; - const formatter = new Formatter(obj); - expect(formatter.format(text)).to.equal("1"); - }); - it("should format a string with custom markers", () => { - const formatter = new Formatter({ name: "John", age: 30 }); - formatter.setMarker("[", "]"); - const result = formatter.format("My name is [name] and I am [age | tostring] years old."); - expect(result).to.equal("My name is John and I am 30 years old."); - }); - it("should format a string using callback", () => { - const formatter = new Formatter({ x: "1" }, { - callbacks: { - quote: (value) => { - return '"' + value + '"'; - } - } - }); - expect(formatter.format("${x | call:quote}")).to.equal('"1"'); - }); - it("should format a string with parameters", () => { - const obj = { - a: { - b: { - c: "Hello" - }, - d: "world" - } - }; - const formatter = new Formatter(obj); - const result = formatter.format("${a.b.c} ${a.d | ucfirst}!"); - expect(result).to.equal("Hello World!"); - }); - it("should throw a too deep nesting error", () => { - const formatter = new Formatter({ name: "John" }); - const nestedText = "${name${name${name${name${name${name${name${name${name${name${name${name${name${name${name${name${name${name${name}}}}}}}}}}}}}}}}}}"; - expect(() => formatter.format(nestedText)).to.throw("syntax error in formatter template"); - }); - it("should throw a too deep nesting error", () => { - const inputObj = { - mykey: "${mykey}" - }; - const formatter = new Formatter(inputObj); - const text = "${mykey}"; - let formattedText = text; - for (let i = 0; i < 21; i++) { - formattedText = "${" + formattedText + "}"; - } - expect(() => formatter.format(formattedText)).to.throw("too deep nesting"); - }); - }); - }); - - // ../application/source/text/util.mjs - function generateRangeComparisonExpression(expression, valueName, options = {}) { - const { urlEncode = false, andOp = "&&", orOp = "||", eqOp = "==", geOp = ">=", leOp = "<=" } = options; - const ranges = expression.split(","); - let comparison = ""; - for (let i = 0; i < ranges.length; i++) { - const range = ranges[i].trim(); - if (range === "") { - throw new Error(`Invalid range '${range}'`); - } else if (range.includes("-")) { - const [start, end] = range.split("-").map((s) => s === "" ? null : parseFloat(s)); - if (start !== null && isNaN(start) || end !== null && isNaN(end)) { - throw new Error(`Invalid value in range '${range}'`); - } - if (start !== null && end !== null && start > end) { - throw new Error(`Invalid range '${range}'`); - } - const compStart = start !== null ? `${valueName}${urlEncode ? encodeURIComponent(geOp) : geOp}${start}` : ""; - const compEnd = end !== null ? `${valueName}${urlEncode ? encodeURIComponent(leOp) : leOp}${end}` : ""; - const compRange = `${compStart}${compStart && compEnd ? ` ${andOp} ` : ""}${compEnd}`; - comparison += ranges.length > 1 ? `(${compRange})` : compRange; - } else { - const value = parseFloat(range); - if (isNaN(value)) { - throw new Error(`Invalid value '${range}'`); - } - const compValue = `${valueName}${urlEncode ? encodeURIComponent(eqOp) : eqOp}${value}`; - comparison += ranges.length > 1 ? `(${compValue})` : compValue; - } - if (i < ranges.length - 1) { - comparison += ` ${orOp} `; - } - } - return comparison; - } - - // test/cases/text/util.mjs - describe("generateRangeComparisonExpression", () => { - it("should generate correct comparison expression for single values", () => { - const expression = "1,3,5"; - const valueName = "x"; - const result = generateRangeComparisonExpression(expression, valueName); - expect(result).to.equal("(x==1) || (x==3) || (x==5)"); - }); - it("should generate correct comparison expression for ranges", () => { - const expression = "1-3,6-8"; - const valueName = "x"; - const result = generateRangeComparisonExpression(expression, valueName); - expect(result).to.equal("(x>=1 && x<=3) || (x>=6 && x<=8)"); - }); - it("should generate correct comparison expression for mixed ranges and single values", () => { - const expression = "1-3,5,7-9"; - const valueName = "x"; - const result = generateRangeComparisonExpression(expression, valueName); - expect(result).to.equal("(x>=1 && x<=3) || (x==5) || (x>=7 && x<=9)"); - }); - it("should throw an error for invalid range", () => { - const expression = "1-3,5-4"; - const valueName = "x"; - expect(() => generateRangeComparisonExpression(expression, valueName)).to.throw(`Invalid range '5-4'`); - }); - it("should throw an error for invalid value", () => { - const expression = "1-3,a"; - const valueName = "x"; - expect(() => generateRangeComparisonExpression(expression, valueName)).to.throw("Invalid value"); - }); - it("should generate correct comparison expression with custom operators", () => { - const expression = "1-3,5"; - const valueName = "x"; - const options = { - andOp: "AND", - orOp: "OR", - eqOp: "===", - geOp: ">=", - leOp: "<=" - }; - const result = generateRangeComparisonExpression(expression, valueName, options); - expect(result).to.equal("(x>=1 AND x<=3) OR (x===5)"); - }); - it("should generate correct comparison expression with urlEncode option", () => { - const testCases = [ - { - expression: "1,3,5", - valueName: "x", - expected: "(x%3D%3D1) || (x%3D%3D3) || (x%3D%3D5)" - }, - { - expression: "-10", - valueName: "x", - expected: "x%3C%3D10" - }, - { - expression: "10-", - valueName: "x", - expected: "x%3E%3D10" - }, - { - expression: "1-3,6-8", - valueName: "y", - expected: "(y%3E%3D1 && y%3C%3D3) || (y%3E%3D6 && y%3C%3D8)" - }, - { - expression: "1-3,5,7-9", - valueName: "z", - expected: "(z%3E%3D1 && z%3C%3D3) || (z%3D%3D5) || (z%3E%3D7 && z%3C%3D9)" - } - ]; - testCases.forEach(({ expression, valueName, expected }) => { - const result = generateRangeComparisonExpression(expression, valueName, { urlEncode: true }); - expect(result).to.equal(expected); - }); - }); - it("should generate correct comparison expression for open-ended ranges with urlEncode option", () => { - const testCases = [ - { - expression: "10-", - valueName: "x", - expected: "x%3E%3D10" - }, - { - expression: "-10", - valueName: "y", - expected: "y%3C%3D10" - } - ]; - testCases.forEach(({ expression, valueName, expected }) => { - const result = generateRangeComparisonExpression(expression, valueName, { urlEncode: true }); - expect(result).to.equal(expected); - }); - }); - }); - - // test/cases/dom/slotted-nodes.mjs - init_slotted(); - describe("getSlottedNodes", () => { - it("should return an empty Set if there is no ShadowRoot", () => { - expect(getSlottedNodes).is.a("function"); - }); - }); - - // ../application/source/dom/resource/link/stylesheet.mjs - init_extend(); - - // ../application/source/dom/resource/link.mjs - init_extend(); - init_constants2(); - init_resource(); - init_constants(); - var Link = class extends Resource { - /** - * @property {string} as {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-as} - * @property {string} crossOrigin=anonymous {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-crossorigin} - * @property {boolean} disabled - * @property {string} href {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-href} - * @property {string} hreflang {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-hreflang} - * @property {string} imagesizes {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-imagesizes} - * @property {string} imagesrcset {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-imagesrcset} - * @property {string} integrity {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-integrity} - * @property {string} media {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-media} - * @property {string} prefetch {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-prefetch} - * @property {string} referrerpolicy {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-referrerpolicy} - * @property {string} rel {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-rel} - * @property {string} type {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-type} - * @property {string} sizes {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-sizes} - * @property {string} nonce {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-nonce} - */ - get defaults() { - return extend({}, super.defaults, { - as: void 0, - crossOrigin: "anonymous", - disabled: void 0, - href: void 0, - hreflang: void 0, - imagesizes: void 0, - imagesrcset: void 0, - integrity: void 0, - media: void 0, - prefetch: void 0, - referrerpolicy: void 0, - rel: void 0, - sizes: void 0, - type: void 0, - nonce: void 0 - }); - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/dom/resource/link"); - } - /** - * - * @return {Monster.DOM.Resource.Link} - */ - create() { - createElement.call(this); - return this; - } - /** - * @return {string} - */ - static getURLAttribute() { - return ATTRIBUTE_HREF; - } - }; - function createElement() { - const self2 = this; - const document2 = self2.getOption(KEY_DOCUMENT); - self2[referenceSymbol] = document2.createElement(TAG_LINK); - for (let key of [ - "as", - "crossOrigin", - "disabled", - "href", - "hreflang", - "imagesizes", - "imagesrcset", - "integrity", - "media", - "prefetch", - "referrerpolicy", - "sizes", - "rel", - "type", - ATTRIBUTE_HREF, - ATTRIBUTE_ID, - ATTRIBUTE_CLASS, - ATTRIBUTE_TITLE, - ATTRIBUTE_NONCE - ]) { - if (self2.getOption(key) !== void 0) { - self2[referenceSymbol][key] = self2.getOption(key); - } - } - return self2; - } - - // ../application/source/dom/resource/link/stylesheet.mjs - init_constants(); - var Stylesheet = class extends Link { - /** - * @property {string} rel {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-rel} - */ - get defaults() { - return extend({}, super.defaults, { - rel: "stylesheet" - }); - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/dom/resource/link/stylesheet"); - } - }; - - // test/cases/dom/resource/link/stylesheet.mjs - init_dataurl(); - init_id(); - - // test/util/chai-dom.mjs - function chaiDom(chai2, utils) { - let flag = utils.flag, elToString = function(el) { - let desc; - if (isNodeList(el)) { - if (el.length === 0) - return "empty NodeList"; - desc = Array.prototype.slice.call(el, 0, 5).map(elToString).join(", "); - return el.length > 5 ? desc + "... (+" + (el.length - 5) + " more)" : desc; - } - if (!isHTMLElement(el)) { - return String(el); - } - desc = el.tagName.toLowerCase(); - if (el.id) { - desc += "#" + el.id; - } - if (el.className) { - desc += "." + String(el.className).replace(/\s+/g, "."); - } - Array.prototype.forEach.call(el.attributes, function(attr) { - if (attr.name !== "class" && attr.name !== "id") { - desc += "[" + attr.name + (attr.value ? '="' + attr.value + '"]' : "]"); - } - }); - return desc; - }, attrAssert = function(name, val) { - var el = flag(this, "object"), actual = el.getAttribute(name); - if (!flag(this, "negate") || void 0 === val) { - this.assert( - !!el.attributes[name], - "expected " + elToString(el) + " to have an attribute #{exp}", - "expected " + elToString(el) + " not to have an attribute #{exp}", - name - ); - } - if (void 0 !== val) { - this.assert( - val === actual, - "expected " + elToString(el) + " to have an attribute " + utils.inspect(name) + " with the value #{exp}, but the value was #{act}", - "expected " + elToString(el) + " not to have an attribute " + utils.inspect(name) + " with the value #{act}", - val, - actual - ); - } - flag(this, "object", actual); - }, isHTMLElement = function(el) { - return el.nodeType === 1; - }, isNodeList = function(obj) { - return Object.prototype.toString.call(obj) === "[object NodeList]"; - }; - utils.elToString = elToString; - chai2.Assertion.addMethod("attr", attrAssert); - chai2.Assertion.addMethod("attribute", attrAssert); - chai2.Assertion.addMethod("class", function(className) { - var el = flag(this, "object"); - this.assert( - el.classList.contains(className), - "expected " + elToString(el) + " to have class #{exp}", - "expected " + elToString(el) + " not to have class #{exp}", - className - ); - }); - chai2.Assertion.addMethod("id", function(id) { - var el = flag(this, "object"); - this.assert( - el.id == id, - "expected " + elToString(el) + " to have id #{exp}", - "expected " + elToString(el) + " not to have id #{exp}", - id - ); - }); - chai2.Assertion.addMethod("html", function(html) { - var el = flag(this, "object"), actual = flag(this, "object").innerHTML; - if (flag(this, "contains")) { - this.assert( - actual.indexOf(html) >= 0, - "expected #{act} to contain HTML #{exp}", - "expected #{act} not to contain HTML #{exp}", - html, - actual - ); - } else { - this.assert( - actual === html, - "expected " + elToString(el) + " to have HTML #{exp}, but the HTML was #{act}", - "expected " + elToString(el) + " not to have HTML #{exp}", - html, - actual - ); - } - }); - chai2.Assertion.addChainableMethod("trimmed", null, function() { - flag(this, "trim-text", true); - }); - chai2.Assertion.addMethod("text", function(text) { - var obj = flag(this, "object"), contains = flag(this, "contains"), trim = flag(this, "trim-text"), actual, result; - if (isNodeList(obj)) { - actual = Array.prototype.map.call(obj, function(el) { - return trim ? el.textContent.trim() : el.textContent; - }); - if (Array.isArray(text)) { - result = contains ? text[flag(this, "negate") ? "some" : "every"](function(t) { - return Array.prototype.some.call(obj, function(el) { - return (trim ? el.textContent.trim() : el.textContent) === t; - }); - }) : utils.eql(actual, text); - actual = actual.join(); - text = text.join(); - } else { - actual = actual.join(""); - result = contains ? actual.indexOf(text) >= 0 : actual === text; - } - } else { - actual = trim ? obj.textContent.trim() : obj.textContent; - result = contains ? actual.indexOf(text) >= 0 : actual === text; - } - var objDesc = elToString(obj), textMsg = trim ? "trimmed text" : "text"; - if (contains) { - this.assert( - result, - "expected " + objDesc + " to contain #{exp}, but the " + textMsg + " was #{act}", - "expected " + objDesc + " not to contain #{exp}, but the " + textMsg + " was #{act}", - text, - actual - ); - } else { - this.assert( - result, - "expected " + objDesc + " to have " + textMsg + " #{exp}, but the " + textMsg + " was #{act}", - "expected " + objDesc + " not to have " + textMsg + " #{exp}", - text, - actual - ); - } - }); - chai2.Assertion.addMethod("value", function(value) { - var el = flag(this, "object"), actual = flag(this, "object").value; - this.assert( - flag(this, "object").value === value, - "expected " + elToString(el) + " to have value #{exp}, but the value was #{act}", - "expected " + elToString(el) + " not to have value #{exp}", - value, - actual - ); - }); - chai2.Assertion.overwriteProperty("exist", function(_super) { - return function() { - var obj = flag(this, "object"); - if (isNodeList(obj)) { - this.assert( - obj.length > 0, - "expected an empty NodeList to have nodes", - "expected " + elToString(obj) + " to not exist" - ); - } else { - _super.apply(this, arguments); - } - }; - }); - chai2.Assertion.overwriteProperty("empty", function(_super) { - return function() { - var obj = flag(this, "object"); - if (isHTMLElement(obj)) { - this.assert( - obj.children.length === 0, - "expected " + elToString(obj) + " to be empty", - "expected " + elToString(obj) + " to not be empty" - ); - } else if (isNodeList(obj)) { - this.assert( - obj.length === 0, - "expected " + elToString(obj) + " to be empty", - "expected " + elToString(obj) + " to not be empty" - ); - } else { - _super.apply(this, arguments); - } - }; - }); - chai2.Assertion.overwriteChainableMethod( - "length", - function(_super) { - return function(length) { - var obj = flag(this, "object"); - if (isNodeList(obj) || isHTMLElement(obj)) { - var actualLength = obj.children ? obj.children.length : obj.length; - this.assert( - actualLength === length, - "expected " + elToString(obj) + " to have #{exp} children but it had #{act} children", - "expected " + elToString(obj) + " to not have #{exp} children", - length, - actualLength - ); - } else { - _super.apply(this, arguments); - } - }; - }, - function(_super) { - return function() { - _super.call(this); - }; - } - ); - chai2.Assertion.overwriteMethod("match", function(_super) { - return function(selector) { - var obj = flag(this, "object"); - if (isHTMLElement(obj)) { - this.assert( - obj.matches(selector), - "expected " + elToString(obj) + " to match #{exp}", - "expected " + elToString(obj) + " to not match #{exp}", - selector - ); - } else if (isNodeList(obj)) { - this.assert( - !!obj.length && Array.prototype.every.call(obj, function(el) { - return el.matches(selector); - }), - "expected " + elToString(obj) + " to match #{exp}", - "expected " + elToString(obj) + " to not match #{exp}", - selector - ); - } else { - _super.apply(this, arguments); - } - }; - }); - chai2.Assertion.overwriteChainableMethod( - "contain", - function(_super) { - return function(subitem) { - var obj = flag(this, "object"); - if (isHTMLElement(obj)) { - if (typeof subitem === "string") { - this.assert( - !!obj.querySelector(subitem), - "expected " + elToString(obj) + " to contain #{exp}", - "expected " + elToString(obj) + " to not contain #{exp}", - subitem - ); - } else { - this.assert( - obj.contains(subitem), - "expected " + elToString(obj) + " to contain " + elToString(subitem), - "expected " + elToString(obj) + " to not contain " + elToString(subitem) - ); - } - } else { - _super.apply(this, arguments); - } - }; - }, - function(_super) { - return function() { - _super.call(this); - }; - } - ); - chai2.Assertion.addMethod("descendant", function(subitem) { - var obj = flag(this, "object"), actual = subitem; - if (typeof subitem === "string") { - actual = obj.querySelector(subitem); - this.assert( - !!actual, - "expected " + elToString(obj) + " to have descendant #{exp}", - "expected " + elToString(obj) + " to not have descendant #{exp}", - subitem - ); - } else { - this.assert( - obj.contains(subitem), - "expected " + elToString(obj) + " to contain " + elToString(subitem), - "expected " + elToString(obj) + " to not contain " + elToString(subitem) - ); - } - flag(this, "object", actual); - }); - chai2.Assertion.addMethod("descendants", function(selector) { - var obj = flag(this, "object"), actual = obj.querySelectorAll(selector); - this.assert( - !!actual.length, - "expected " + elToString(obj) + " to have descendants #{exp}", - "expected " + elToString(obj) + " to not have descendants #{exp}", - selector - ); - flag(this, "object", actual); - }); - chai2.Assertion.addProperty("displayed", function() { - var el = flag(this, "object"), actual = document.body.contains(el) ? window.getComputedStyle(el).display : el.style.display; - this.assert( - actual !== "none", - "expected " + elToString(el) + " to be displayed, but it was not", - "expected " + elToString(el) + " to not be displayed, but it was as " + actual, - actual - ); - }); - chai2.Assertion.addProperty("visible", function() { - var el = flag(this, "object"), actual = document.body.contains(el) ? window.getComputedStyle(el).visibility : el.style.visibility; - this.assert( - actual !== "hidden" && actual !== "collapse", - "expected " + elToString(el) + " to be visible, but it was " + (actual === "hidden" ? "hidden" : "collapsed"), - "expected " + elToString(el) + " to not be visible, but it was", - actual - ); - }); - } - - // test/util/cleanupdom.mjs - var addedNodes; - var mutationobserver; - function init() { - addedNodes = []; - mutationobserver = new MutationObserver(function(mutations) { - mutations.forEach(function(mutation) { - if (mutation.type === "childList" && mutation.removedNodes) { - mutation.addedNodes.forEach((n) => { - if (n instanceof HTMLElement) { - addedNodes.push(n); - } - }); - } - }); - }); - } - function initMutationObserverForTesting() { - if (mutationobserver === void 0) { - init(); - } - mutationobserver.observe(document.querySelector("head"), { childList: true }); - } - function cleanupDOMFromTesting() { - mutationobserver.disconnect(); - for (const n of addedNodes) { - n.remove(); - } - } - - // test/util/jsdom.mjs - init_extend(); - init_global(); - var isBrowser = new Function("try {return this===window;}catch(e){ return false;}"); - var isNode = new Function("try {return this===global;}catch(e){return false;}"); - var JSDOMExport = null; - function initJSDOM(options) { - if (typeof window === "object" && window["DOMParser"]) - return Promise.resolve(); - const g = getGlobal(); - options = extend({}, { - pretendToBeVisual: true, - contentType: "text/html", - includeNodeLocations: true, - storageQuota: 1e7, - runScripts: "dangerously", - resources: "usable" - }, options || {}); - return import("jsdom").then(({ JSDOM }) => { - JSDOMExport = JSDOM; - const { window: window2 } = new JSDOM(`<html> -<head> -</head> -<body> -<div id="mocks"></div> -</body>`, options); - g["window"] = window2; - return new Promise( - (resolve) => window2.addEventListener("load", () => { - [ - "self", - "HTMLCollection", - "NodeList", - "ElementInternals", - "HTMLDocument", - "HTMLFormElement", - "HTMLInputElement", - "HTMLSelectElement", - "HTMLTextAreaElement", - "document", - "Document", - "Node", - "ShadowRoot", - "EventTarget", - "Event", - "CustomEvent", - "Element", - "HTMLElement", - "HTMLDivElement", - "customElements", - "DocumentFragment", - "DOMParser", - "KeyboardEvent", - "CSSStyleSheet", - "HTMLScriptElement", - "MutationObserver", - "HTMLTemplateElement", - "XMLSerializer", - "NodeFilter", - "navigator", - "InputEvent", - "Blob", - "CustomEvent" - ].forEach((key) => { - g[key] = window2[key]; - }); - resolve(); - }) - ); - }); - } - - // test/cases/dom/resource/link/stylesheet.mjs - var expect2 = chai_default.expect; - chai_default.use(chaiDom); - describe("Stylesheet", function() { - before(function(done) { - initJSDOM({ - runScripts: "dangerously", - resources: "usable" - }).then(() => { - done(); - }).catch((e) => done(e)); - }); - beforeEach(() => { - initMutationObserverForTesting(); - }); - afterEach(() => { - cleanupDOMFromTesting(); - }); - describe("Stylesheet()", function() { - it("connect().available()", function(done) { - const stylesheet = new Stylesheet({ - href: new DataUrl("", "text/css").toString() - }); - stylesheet.connect().available().then(() => { - const id = stylesheet.getOption("id"); - done(); - }).catch((e) => done(e)); - }); - }); - describe("External Stylesheet", () => { - let id = new ID("Stylesheet").toString(); - let stylesheet, url = "https://monsterjs.org/assets/empty.css?" + id; - beforeEach(() => { - stylesheet = new Stylesheet({ - href: url, - id - }); - }); - it("append and remove Stylesheet ", (done) => { - expect2(stylesheet.isConnected()).to.be.false; - stylesheet.connect().available().then(() => { - expect2(stylesheet.isConnected()).to.be.true; - expect2(document.querySelector('[href="' + url + '"]')).to.exist; - document.getElementById(id).remove(); - expect2(stylesheet.isConnected()).to.be.false; - expect2(document.querySelector('[href="' + url + '"]')).not.to.exist; - stylesheet.connect().available().then(() => { - expect2(stylesheet.isConnected()).to.be.true; - expect2(document.querySelector('[href="' + url + '"]')).to.exist; - document.getElementById(id).remove(); - expect2(document.querySelector('[href="' + url + '"]')).not.to.exist; - expect2(stylesheet.isConnected()).to.be.false; - done(); - }).catch((e) => done(e)); - }).catch((e) => done(e)); - }); - }); - }); - - // ../application/source/dom/resource/data.mjs - init_constants(); - init_extend(); - init_global(); - init_constants2(); - init_resource(); - init_constants(); - var Data = class extends Resource { - /** - * @property {string} mode=cors https://developer.mozilla.org/en-US/docs/Web/API/fetch - * @property {string} credentials=same-origin https://developer.mozilla.org/en-US/docs/Web/API/fetch - * @property {string} type=application/json {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-type} - */ - get defaults() { - return extend({}, super.defaults, { - mode: "cors", - credentials: "same-origin", - type: "application/json" - }); - } - /** - * - * @return {Monster.DOM.Resource.Data} - */ - create() { - createElement2.call(this); - return this; - } - /** - * This method appends the HTMLElement to the specified document - * - * throws {Error} target not found - * @return {Monster.DOM.Resource} - */ - connect() { - if (!(this[referenceSymbol] instanceof HTMLElement)) { - this.create(); - } - appendToDocument2.call(this); - return this; - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/dom/resource/data"); - } - /** - * @return {string} - */ - static getURLAttribute() { - return ATTRIBUTE_SRC; - } - }; - function createElement2() { - const self2 = this; - const document2 = self2.getOption(KEY_DOCUMENT); - self2[referenceSymbol] = document2.createElement(TAG_SCRIPT); - for (let key of [ATTRIBUTE_TYPE, ATTRIBUTE_ID, ATTRIBUTE_CLASS, ATTRIBUTE_TITLE]) { - if (self2.getOption(key) !== void 0) { - self2[referenceSymbol][key] = self2.getOption(key); - } - } - return self2; - } - function appendToDocument2() { - const self2 = this; - const targetNode = document.querySelector(self2.getOption(KEY_QUERY, "head")); - if (!(targetNode instanceof HTMLElement)) { - throw new Error("target not found"); - } - targetNode.appendChild(self2[referenceSymbol]); - getGlobalFunction("fetch")(self2.getOption(ATTRIBUTE_SRC), { - method: "GET", - // *GET, POST, PUT, DELETE, etc. - mode: self2.getOption("mode", "cors"), - // no-cors, *cors, same-origin - cache: "no-cache", - // *default, no-cache, reload, force-cache, only-if-cached - credentials: self2.getOption("credentials", "same-origin"), - // include, *same-origin, omit - headers: { - Accept: self2.getOption("type", "application/json") - }, - redirect: "follow", - // manual, *follow, error - referrerPolicy: "no-referrer" - // no-referrer, - }).then((response) => { - return response.text(); - }).then((text) => { - const textNode = document.createTextNode(text); - self2[referenceSymbol].appendChild(textNode); - self2[internalStateSymbol].getSubject()["loaded"] = true; - }).catch((e) => { - self2[internalStateSymbol].setSubject({ - loaded: true, - error: e.toString() - }); - targetNode.setAttribute(ATTRIBUTE_ERRORMESSAGE, e.toString()); - }); - return self2; - } - - // test/cases/dom/resource/data.mjs - init_dataurl(); - init_id(); - var expect3 = chai_default.expect; - chai_default.use(chaiDom); - describe("Data", function() { - let fetchReference2, returnStatus, mutationobserver2, addedNodes2 = []; - before(function(done) { - initJSDOM().then(() => { - done(); - }); - }); - beforeEach(() => { - initMutationObserverForTesting(); - returnStatus = 200; - fetchReference2 = globalThis["fetch"]; - globalThis["fetch"] = function(url, options) { - if (!url) - throw new Error("missing url"); - return new Promise((resolve, reject) => { - resolve({ - text: function() { - return JSON.stringify({ - a: "test" - }); - }, - status: returnStatus - }); - }); - }; - }); - afterEach(() => { - globalThis["fetch"] = fetchReference2; - cleanupDOMFromTesting(); - }); - describe("Data()", function() { - it("setEventTypes()", function(done) { - const data = new Data({ - src: new DataUrl("", "text/javascript").toString() - }); - data.connect().available().then(() => { - done(); - }).catch((e) => done(e)); - }); - }); - describe("External Data", () => { - let id = new ID("data").toString(); - let server, data, url = "https://monsterjs.org/assets/empty.js?" + id; - beforeEach(() => { - data = new Data({ - src: url, - id - }); - }); - it("data is not connected", () => { - expect3(data.isConnected()).to.be.false; - }); - it("connect and check availability", (done) => { - data.connect().available().then(() => { - expect3(data.isConnected(), "isConnected 1").to.be.true; - expect3(document.querySelector('[type="application/json"]'), "exists 1").to.exist; - const e = document.getElementById(id).parentElement; - document.getElementById(id).remove(); - expect3(data.isConnected(), "isConnected 2").to.be.false; - expect3(document.querySelector('[type="application/json"]'), "exists 2").not.to.exist; - data.connect().available().then(() => { - expect3(data.isConnected(), "isConnected 3").to.be.true; - expect3(document.querySelector('[type="application/json"]'), "exists 3").to.exist; - document.getElementById(id).remove(); - expect3(document.querySelector('[type="application/json"]'), "exists 4").not.to.exist; - expect3(data.isConnected(), "isConnected 4").to.be.false; - done(); - }).catch((e2) => done(e2)); - }).catch((e) => done(e)); - }); - }); - }); - - // test/cases/dom/resource/link.mjs - init_dataurl(); - init_id(); - var expect4 = chai_default.expect; - chai_default.use(chaiDom); - describe("Link", function() { - before(function(done) { - initJSDOM().then(() => { - done(); - }); - }); - beforeEach(() => { - initMutationObserverForTesting(); - }); - afterEach(() => { - cleanupDOMFromTesting(); - }); - describe("Link()", function() { - this.timeout(5e3); - it("connect().available()", function(done) { - const link = new Link({ - href: new DataUrl("", "text/css").toString(), - rel: "stylesheet" - }); - link.connect().available().then(() => { - done(); - }).catch((e) => done(e)); - }); - }); - describe("External Link", () => { - this.timeout(5e3); - let id = new ID("link").toString(); - let link, url = "https://monsterjs.org/assets/empty.css?" + id; - beforeEach(() => { - link = new Link({ - href: url, - id, - rel: "stylesheet" - }); - }); - it("append and remove Link ", (done) => { - expect4(link.isConnected()).to.be.false; - link.connect().available().then(() => { - expect4(link.isConnected()).to.be.true; - expect4(document.querySelector('[href="' + url + '"]')).to.exist; - document.getElementById(id).remove(); - expect4(link.isConnected()).to.be.false; - expect4(document.querySelector('[href="' + url + '"]')).not.to.exist; - link.connect().available().then(() => { - expect4(link.isConnected()).to.be.true; - expect4(document.querySelector('[href="' + url + '"]')).to.exist; - document.getElementById(id).remove(); - expect4(document.querySelector('[href="' + url + '"]')).not.to.exist; - expect4(link.isConnected()).to.be.false; - done(); - }).catch((e) => done(e)); - }).catch((e) => done(e)); - }); - }); - }); - - // ../application/source/dom/resource/script.mjs - init_extend(); - init_constants2(); - init_resource(); - init_constants(); - var Script = class extends Resource { - /** - * @property {boolean} async=true {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-async} - * @property {string} crossOrigin=anonymous {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-crossorigin} - * @property {boolean} defer=false {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-defer} - * @property {string} integrity {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-integrity} - * @property {boolean} nomodule {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-nomodule} - * @property {string} nonce {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-nonce} - * @property {string} referrerpolicy {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-referrerpolicy} - * @property {string} type {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-type} - */ - get defaults() { - return extend({}, super.defaults, { - async: true, - crossOrigin: "anonymous", - defer: false, - integrity: void 0, - nomodule: false, - nonce: void 0, - referrerpolicy: void 0, - type: "text/javascript" - }); - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/dom/resource/script"); - } - /** - * - * @return {Monster.DOM.Resource.Script} - */ - create() { - createElement3.call(this); - return this; - } - /** - * @return {string} - */ - static getURLAttribute() { - return ATTRIBUTE_SRC; - } - }; - function createElement3() { - const self2 = this; - const document2 = self2.getOption(KEY_DOCUMENT); - self2[referenceSymbol] = document2.createElement(TAG_SCRIPT); - for (let key of [ - "crossOrigin", - "defer", - "async", - "integrity", - "nomodule", - ATTRIBUTE_NONCE, - "referrerpolicy", - ATTRIBUTE_TYPE, - ATTRIBUTE_SRC, - ATTRIBUTE_ID, - ATTRIBUTE_CLASS, - ATTRIBUTE_TITLE - ]) { - if (self2.getOption(key) !== void 0) { - self2[referenceSymbol][key] = self2.getOption(key); - } - } - return self2; - } - - // test/cases/dom/resource/script.mjs - init_dataurl(); - init_id(); - var expect5 = chai_default.expect; - chai_default.use(chaiDom); - describe("Script", function() { - before(function(done) { - initJSDOM().then(() => { - done(); - }); - }); - beforeEach(() => { - initMutationObserverForTesting(); - }); - afterEach(() => { - cleanupDOMFromTesting(); - }); - describe("Script()", function() { - it("setEventTypes()", function(done) { - const script = new Script({ - src: new DataUrl("", "text/javascript").toString(), - async: true, - crossOrigin: "anonymous", - defer: false, - integrity: void 0, - nomodule: false, - nonce: void 0, - referrerpolicy: void 0, - type: "text/javascript" - }); - script.connect().available().then(() => { - const id = script.getOption("id"); - done(); - }).catch((e) => done(e)); - }); - }); - describe("External JS", () => { - let id = new ID("script").toString(); - let server, script, url = "https://monsterjs.org/assets/empty.js?" + id; - beforeEach(() => { - script = new Script({ - src: url, - async: true, - crossOrigin: "anonymous", - defer: false, - integrity: void 0, - nomodule: false, - nonce: void 0, - referrerpolicy: void 0, - type: "text/javascript", - id - }); - }); - it("append and remove script ", (done) => { - expect5(script.isConnected()).to.be.false; - script.connect().available().then(() => { - expect5(script.isConnected()).to.be.true; - expect5(document.querySelector('[src="' + url + '"]')).to.exist; - document.getElementById(id).remove(); - expect5(script.isConnected()).to.be.false; - expect5(document.querySelector('[src="' + url + '"]')).not.to.exist; - script.connect().available().then(() => { - expect5(script.isConnected()).to.be.true; - expect5(document.querySelector('[src="' + url + '"]')).to.exist; - document.getElementById(id).remove(); - expect5(document.querySelector('[src="' + url + '"]')).not.to.exist; - expect5(script.isConnected()).to.be.false; - done(); - }).catch((e) => done(e)); - }).catch((e) => done(e)); - }); - }); - }); - - // test/cases/dom/updater.mjs - init_updater(); - init_id(); - init_observer(); - init_proxyobserver(); - var expect6 = chai_default.expect; - chai_default.use(chaiDom); - var html1 = ` - <template id="current"> - <li data-monster-replace="path:current | tojson"></li> - </template> - <div id="test1"> - <ul data-monster-insert="current path:a.b"> - </ul> - </div> - <div id="test2"> - <ul data-monster-insert="current path:a.b | doit"> - </ul> - </div> - <div id="test3"> - <div data-monster-attributes="class path:a.b"> - <input data-monster-attributes="value path:a.c" id="input1"> - <input data-monster-attributes="checked path:a.checkbox" type="checkbox" name="checkbox" id="checkbox"> - <input data-monster-attributes="value path:a.text" type="text" name="text" id="text"> - <input data-monster-attributes="checked path:a.radio" type="radio" name="radio" value="r1" id="radio"> - <input type="radio" name="radio" value="r2" id="r2"> - <input type="radio" name="radio" value="rx" id="rx"> - - <select data-monster-attributes="value path:a.select" name="select" id="select"> - <option value="other-value">value1</option> - <option>value2</option> - </select> - - <select data-monster-attributes="value path:a.multiselect" name="multiselect" multiple id="multiselect"> - <option>value1</option> - <option>value2</option> - <option>value3</option> - <option>value4</option> - <option value="other-value5">value5</option> - </select> - - <textarea name="textarea" id="textarea" data-monster-attributes="value path:a.textarea"></textarea> - - </div> - </div> - -`; - var html2 = ` - <div id="test1"> - <div data-monster-replace="path:text | tolower"></div> - <div data-monster-replace="path:text | call:myformatter"></div> - <div data-monster-replace="static:hello\\ "></div> - </div> -`; - var html3 = ` - - <template id="myinnerid"> - <span data-monster-replace="path:myinnerid | tojson"></span> - </template> - - <template id="myid"> - <p data-monster-insert="myinnerid path:a.b"></p> - </template> - - <div id="test1"> - <div data-monster-insert="myid path:a.b"></div> - </div> - -`; - var html4 = ` - <div> - <form id="form1"> - <input type="checkbox" value="checked" name="checkbox" data-monster-bind="path:state"> - <input type="text" name="text"> - <input type="radio" name="radio" value="r1" id="r1" data-monster-bind="path:radio"> - <input type="radio" name="radio" value="r2" id="r2" data-monster-bind="path:radio"> - <input type="radio" name="radio" value="rx" id="rx" data-comment="not called because no bind attribute"> - <input type="button" name="button"> - - <select name="select1" id="select1" data-monster-bind="path:select"> - <option>value1</option> - <option>value2</option> - </select> - - <select name="select2" multiple id="select2" data-monster-bind="path:multiselect"> - <option>value1</option> - <option>value2</option> - <option>value3</option> - <option>value4</option> - <option>value5</option> - </select> - - <textarea name="textarea" id="textarea" data-monster-bind="path:textarea"> - - </textarea> - - </form> - </div> - -`; - describe("DOM", function() { - before(function(done) { - initJSDOM().then(() => { - done(); - }); - }); - beforeEach(() => { - let mocks = document.getElementById("mocks"); - mocks.innerHTML = html1; - }); - afterEach(() => { - let mocks = document.getElementById("mocks"); - mocks.innerHTML = ""; - }); - describe("Updater()", function() { - describe("test Getter && Setter", function() { - it("setEventTypes()", function() { - let element = document.getElementById("test1"); - expect6(new Updater(element).setEventTypes(["touch"])).to.be.instanceof(Updater); - }); - it("getSubject()", function() { - let element = document.getElementById("test1"); - let subject = { a: 1 }; - expect6(new Updater(element, subject).getSubject().a).to.be.equal(1); - }); - }); - describe("test control methods", function() { - it("enableEventProcessing()", function() { - let element = document.getElementById("test1"); - expect6(new Updater(element).enableEventProcessing()).to.be.instanceof(Updater); - }); - it("disableEventProcessing()", function() { - let element = document.getElementById("test1"); - expect6(new Updater(element).disableEventProcessing()).to.be.instanceof(Updater); - }); - }); - describe("test Errors", function() { - it("should throw value is not an instance of HTMLElement Error", function() { - expect6(() => new Updater()).to.throw(TypeError); - }); - it("should throw value is wrong", function() { - let element = document.getElementById("test1"); - expect6(() => new Updater(element, null)).to.throw(TypeError); - }); - it("should throw Error: the value is not iterable", function(done) { - let element = document.getElementById("test1"); - let u = new Updater( - element, - { - a: { - x: [] - } - } - ); - u.run().then(() => { - done(new Error("should never called!")); - }).catch((e) => { - expect6(e).is.instanceOf(Error); - expect6(e + "").to.be.equal("Error: the value is not iterable"); - done(); - }); - }); - }); - }); - describe("Updater()", function() { - describe("new Updater", function() { - it("should return document object", function() { - let element = document.getElementById("test1"); - let d = new Updater( - element, - {} - ); - expect6(typeof d).is.equal("object"); - }); - }); - }); - describe("Updater()", function() { - describe("Repeat", function() { - it("should build 6 li elements", function(done) { - let element = document.getElementById("test1"); - let d = new Updater( - element, - { - a: { - b: [ - { i: "0" }, - { i: "1" }, - { i: "2" }, - { i: "3" }, - { i: "4" }, - { i: "5" } - ] - } - } - ); - d.run().then(() => { - expect6(typeof d).is.equal("object"); - for (let i = 0; i < 6; i++) { - expect6(element).contain.html('<li data-monster-replace="path:a.b.' + i + ' | tojson" data-monster-insert-reference="current-' + i + '">{"i":"' + i + '"}</li>'); - } - done(); - }).catch( - (e) => { - done(new Error(e)); - } - ); - }); - }); - }); - describe("Updater()", function() { - beforeEach(() => { - let mocks = document.getElementById("mocks"); - mocks.innerHTML = html4; - }); - describe("Eventhandling", function() { - let updater, form1, proxyobserver; - beforeEach(() => { - proxyobserver = new ProxyObserver({}); - updater = new Updater(document.getElementById("form1"), proxyobserver); - form1 = document.getElementById("form1"); - }); - it("should handle checkbox click events", function(done) { - updater.enableEventProcessing(); - let subject = updater.getSubject(); - expect6(subject).is.equal(proxyobserver.getSubject()); - let expected = ["checked", void 0, "checked"]; - proxyobserver.attachObserver(new Observer(function() { - let e = expected.shift(); - if (e === void 0 && expected.length === 0) - done(new Error("to many calls")); - if (this.getSubject()["state"] !== e) - done(new Error(this.getSubject()["state"] + " should " + e)); - if (expected.length === 0) { - done(); - } else { - setTimeout(() => { - form1.querySelector("[name=checkbox]").click(); - }, 10); - } - })); - setTimeout(() => { - form1.querySelector("[name=checkbox]").click(); - }, 10); - }); - it("should handle radio click events 1", function(done) { - updater.enableEventProcessing(); - let subject = updater.getSubject(); - expect6(subject).is.equal(proxyobserver.getSubject()); - let expected = ["r1", "r2", "r1"]; - let clickTargets = ["r2", "r1"]; - proxyobserver.attachObserver(new Observer(function() { - let e = expected.shift(); - if (e === void 0 && expected.length === 0) - done(new Error("to many calls")); - let v = this.getSubject()["radio"]; - if (v !== e) - done(new Error(v + " should " + e)); - if (expected.length === 0) { - done(); - } else { - setTimeout(() => { - document.getElementById(clickTargets.shift()).click(); - }, 10); - } - })); - setTimeout(() => { - document.getElementById("r1").click(); - }, 10); - setTimeout(() => { - document.getElementById("rx").click(); - }, 20); - }); - it("should handle select click events 2", function(done) { - let selectElement = document.getElementById("select1"); - updater.enableEventProcessing(); - let subject = updater.getSubject(); - expect6(subject).is.equal(proxyobserver.getSubject()); - let expected = ["value2", "value1", "value2"]; - proxyobserver.attachObserver(new Observer(function() { - let e = expected.shift(); - if (e === void 0 && expected.length === 0) - done(new Error("to many calls")); - let v = this.getSubject()["select"]; - if (v !== e) - done(new Error(v + " should " + e)); - if (expected.length === 0) { - done(); - } else { - setTimeout(() => { - selectElement.selectedIndex = selectElement.selectedIndex === 1 ? 0 : 1; - selectElement.click(); - }, 10); - } - })); - setTimeout(() => { - selectElement.selectedIndex = 1; - selectElement.click(); - }, 20); - }); - it("should handle textarea events", function(done) { - let textareaElement = document.getElementById("textarea"); - updater.enableEventProcessing(); - let subject = updater.getSubject(); - expect6(subject).is.equal(proxyobserver.getSubject()); - let expected = ["testX", "lorem ipsum", ""]; - let testValues = ["lorem ipsum", ""]; - proxyobserver.attachObserver(new Observer(function() { - let e = expected.shift(); - if (e === void 0 && expected.length === 0) - done(new Error("to many calls")); - let v = this.getSubject()["textarea"]; - if (JSON.stringify(v) !== JSON.stringify(e)) - done(new Error(JSON.stringify(v) + " should " + JSON.stringify(e))); - if (expected.length === 0) { - done(); - } else { - setTimeout(() => { - textareaElement.value = testValues.shift(); - textareaElement.click(); - }, 10); - } - })); - setTimeout(() => { - textareaElement.value = "testX"; - textareaElement.click(); - }, 20); - }); - it("should handle multiple select events", function(done) { - let selectElement = document.getElementById("select2"); - updater.enableEventProcessing(); - let subject = updater.getSubject(); - expect6(subject).is.equal(proxyobserver.getSubject()); - let expected = [ - ["value1"], - ["value2", "value3", "value4"], - ["value1", "value4"] - ]; - let testSelections = [ - [false, true, true, true], - [true, false, false, true] - ]; - proxyobserver.attachObserver(new Observer(function() { - let e = expected.shift(); - if (e === void 0 && expected.length === 0) - done(new Error("to many calls")); - let v = this.getSubject()["multiselect"]; - if (JSON.stringify(v) !== JSON.stringify(e)) - done(new Error(JSON.stringify(v) + " should " + JSON.stringify(e))); - if (expected.length === 0) { - done(); - } else { - setTimeout(() => { - let v2 = testSelections.shift(); - selectElement.options[0].selected = v2[0]; - selectElement.options[1].selected = v2[1]; - selectElement.options[2].selected = v2[2]; - selectElement.options[3].selected = v2[3]; - selectElement.click(); - }, 10); - } - })); - setTimeout(() => { - selectElement.options[0].selected = true; - selectElement.options[1].selected = false; - selectElement.options[2].selected = false; - selectElement.options[3].selected = false; - selectElement.click(); - }, 20); - }); - }); - }); - describe("Updater()", function() { - beforeEach(() => { - let mocks = document.getElementById("mocks"); - mocks.innerHTML = html2; - }); - describe("Replace", function() { - it("should add lower hello and HELLOyes!", function(done) { - let element = document.getElementById("test1"); - let d = new Updater( - element, - { - text: "HALLO" - } - ); - d.setCallback("myformatter", function(a2) { - return a2 + "yes!"; - }); - setTimeout(() => { - d.run().then(() => { - expect6(typeof d).is.equal("object"); - expect6(element).contain.html('<div data-monster-replace="path:text | tolower">hallo</div>'); - expect6(element).contain.html('<div data-monster-replace="path:text | call:myformatter">HALLOyes!</div>'); - expect6(element).contain.html('<div data-monster-replace="static:hello\\ ">hello </div>'); - return done(); - }).catch( - (e) => { - done(new Error(e)); - } - ); - }, 100); - }); - }); - }); - describe("Updater()", function() { - beforeEach(() => { - let mocks = document.getElementById("mocks"); - mocks.innerHTML = html3; - }); - describe("Replace", function() { - it("should ", function(done) { - let element = document.getElementById("test1"); - let d = new Updater( - element, - { - a: { - b: [ - { i: "0" } - ] - } - } - ); - d.run().then(() => { - expect6(typeof d).is.equal("object"); - expect6(element).contain.html('<div data-monster-insert="myid path:a.b">'); - expect6(element).contain.html('<p data-monster-insert="myinnerid path:a.b" data-monster-insert-reference="myid-0">'); - expect6(element).contain.html('<span data-monster-replace="path:a.b.0 | tojson" data-monster-insert-reference="myinnerid-0">{"i":"0"}</span>'); - done(); - }).catch( - (e) => { - done(new Error(e)); - } - ); - }); - }); - }); - describe("Updater()", function() { - describe("Attributes", function() { - it("should change attributes", function(done) { - let element = document.getElementById("test3"); - let text = document.getElementById("text"); - expect6(text.value).to.be.equal(""); - let radio = document.getElementById("radio"); - expect6(radio.checked).to.be.false; - let checkbox = document.getElementById("checkbox"); - expect6(checkbox.checked).to.be.false; - let select = document.getElementById("select"); - expect6(select.selectedIndex).to.be.equal(0); - let multiselect = document.getElementById("multiselect"); - expect6(multiselect.selectedIndex).to.be.equal(-1); - let textarea = document.getElementById("textarea"); - expect6(textarea.value).to.be.equal(""); - let d = new Updater( - element, - { - a: { - b: "div-class", - c: "hello", - text: "hello", - radio: "true", - textarea: "test", - multiselect: ["value3", "value4", "other-value5"], - select: "value2", - checkbox: "true" - } - } - ); - d.run().then(() => { - expect6(element).contain.html('<div data-monster-attributes="class path:a.b" class="div-class">'); - expect6(element).contain.html('<input data-monster-attributes="value path:a.c" id="input1" value="hello">'); - expect6(element).contain.html('<textarea name="textarea" id="textarea" data-monster-attributes="value path:a.textarea" value="test">'); - expect6(element).contain.html('<input data-monster-attributes="checked path:a.radio" type="radio" name="radio" value="r1" id="radio" checked="true">'); - expect6(text.value, "text control").to.be.equal(d.getSubject()["a"]["c"]); - expect6(radio.checked, "radio control").to.be.equal(true); - expect6(textarea.value, "textarea control").to.be.equal(d.getSubject()["a"]["textarea"]); - expect6(select.selectedIndex, "select control").to.be.equal(1); - let multiselectSelectedOptions = []; - for (const [index, obj] of Object.entries(multiselect.selectedOptions)) { - multiselectSelectedOptions.push(obj.value); - } - expect6(JSON.stringify(multiselectSelectedOptions), "multiselect control").to.be.equal(JSON.stringify(d.getSubject()["a"]["multiselect"])); - expect6(checkbox.checked, "checkbox control").to.be.true; - done(); - }).catch( - (e) => { - done(new Error(e)); - } - ); - }); - }); - }); - describe("Get Attribute Pipe", function() { - let id, mocks; - beforeEach(() => { - mocks = document.getElementById("mocks"); - id = new ID("monster"); - mocks.innerHTML = ` <div id="` + id + `" - data-monster-replace="path:a | if:value:\\ "></div>`; - }); - afterEach(() => { - mocks.innerHTML = ""; - }); - it("should include space", function() { - const div = document.getElementById(id.toString()); - const pipe = div.getAttribute("data-monster-replace"); - expect6(pipe.length).to.be.equal(20); - }); - }); - describe("manuel update", function() { - let id, mocks; - beforeEach(() => { - mocks = document.getElementById("mocks"); - id = new ID("monster").toString(); - mocks.innerHTML = `<input id="` + id + `"data-monster-bind="path:myvalue">`; - }); - afterEach(() => { - mocks.innerHTML = ""; - }); - it("should get value", function() { - document.getElementById(id).value = "hello"; - const updater = new Updater(mocks); - const subject = updater.getSubject(); - expect6(subject).to.not.have.property("myvalue"); - updater.retrieve(); - expect6(subject).to.have.property("myvalue"); - }); - }); - describe("Updater() 20220107", function() { - beforeEach(() => { - let mocks = document.getElementById("mocks"); - mocks.innerHTML = ` - - <div id="container"> - <div data-monster-replace="path:content"></div> - </div> - - - `; - }); - describe("Bugfix #112", function() { - it("should add ", function(done) { - let containerElement = document.getElementById("container"); - let newElement = document.createElement("div"); - newElement.innerHTML = "yeah! <b>Test</b>!"; - const containerHTML = containerElement.innerHTML; - const newHTML = newElement.innerHTML; - let d = new Updater( - containerElement, - { - content: newElement - } - ); - setTimeout(() => { - d.run().then(() => { - try { - expect6(containerElement).contain.html("<div>yeah! <b>Test</b>!</div>"); - } catch (e) { - return done(e); - } - done(); - }); - }, 100); - }); - }); - }); - }); - - // test/cases/dom/customcontrol.mjs - init_constants2(); - init_util(); - var expect7 = chai_default.expect; - chai_default.use(chaiDom); - var html12 = ` - <div id="test1"> - </div> -`; - describe("DOM", function() { - let CustomControl2, registerCustomElement2, TestComponent, document2, jsdomFlag; - describe("CustomControl()", function() { - before(function(done) { - initJSDOM().then(() => { - jsdomFlag = navigator.userAgent.includes("jsdom"); - Promise.resolve().then(() => (init_customelement(), customelement_exports)).then((m) => { - registerCustomElement2 = m["registerCustomElement"]; - Promise.resolve().then(() => (init_customcontrol(), customcontrol_exports)).then((m2) => { - document2 = getDocument(); - try { - CustomControl2 = m2["CustomControl"]; - TestComponent = class extends CustomControl2 { - static getTag() { - return "monster-customcontrol"; - } - }; - registerCustomElement2(TestComponent); - done(); - } catch (e) { - done(e); - } - }); - }); - }); - }); - beforeEach(() => { - let mocks = document2.getElementById("mocks"); - mocks.innerHTML = html12; - }); - afterEach(() => { - let mocks = document2.getElementById("mocks"); - mocks.innerHTML = ""; - }); - describe("create", function() { - it("should return custom-element object", function() { - let d = new TestComponent(); - expect7(typeof d).is.equal("object"); - }); - }); - describe("connect empty element", function() { - it("document should contain monster-customcontrol", function() { - let d = document2.createElement("monster-customcontrol"); - document2.getElementById("test1").appendChild(d); - expect7(document2.getElementsByTagName("monster-customcontrol").length).is.equal(1); - expect7(document2.getElementById("test1")).contain.html("<monster-customcontrol></monster-customcontrol>"); - }); - }); - describe("Options change", function() { - it("delegatesFocus should change from true to false", function() { - let element = document2.createElement("monster-customcontrol"); - expect7(element.getOption("delegatesFocus")).to.be.true; - element.setAttribute(ATTRIBUTE_OPTIONS, JSON.stringify({ delegatesFocus: false })); - expect7(element.getOption("delegatesFocus")).to.be.false; - }); - }); - describe("Test ElementInternals", function() { - let form; - beforeEach(() => { - form = document2.createElement("form"); - }); - it("formAssociated", function() { - let d = document2.createElement("monster-customcontrol"); - form.appendChild(d); - expect7(d.constructor.formAssociated).to.be.true; - }); - it("form", function() { - let d = document2.createElement("monster-customcontrol"); - form.appendChild(d); - if (jsdomFlag) { - expect7(() => d.form).to.throw(Error); - } else { - expect7(d.form).to.be.instanceof(HTMLFormElement); - } - }); - it("value getter", function() { - let d = document2.createElement("monster-customcontrol"); - form.appendChild(d); - expect7(() => d.value).to.throw(Error); - }); - it("value setter", function() { - let d = document2.createElement("monster-customcontrol"); - form.appendChild(d); - expect7(() => d.value = 4).to.throw(Error); - }); - it("setFormValue", function() { - let d = document2.createElement("monster-customcontrol"); - form.appendChild(d); - if (jsdomFlag) { - expect7(() => d.setFormValue()).to.throw(Error); - } else { - } - }); - it("name getter", function() { - let d = document2.createElement("monster-customcontrol"); - form.appendChild(d); - expect7(d.name).to.be.null; - }); - it("type getter", function() { - let d = document2.createElement("monster-customcontrol"); - form.appendChild(d); - expect7(d.type).to.be.equal("monster-customcontrol"); - }); - it("validity getter", function() { - let d = document2.createElement("monster-customcontrol"); - form.appendChild(d); - if (jsdomFlag) { - expect7(() => d.validity).to.throw(Error); - } else { - } - }); - it("validationMessage getter", function() { - let d = document2.createElement("monster-customcontrol"); - form.appendChild(d); - if (jsdomFlag) { - expect7(() => d.validity).to.throw(Error); - } else { - } - }); - it("willValidate getter", function() { - let d = document2.createElement("monster-customcontrol"); - form.appendChild(d); - if (jsdomFlag) { - expect7(() => d.willValidate).to.throw(Error); - } else { - } - }); - it("checkValidity()", function() { - let d = document2.createElement("monster-customcontrol"); - form.appendChild(d); - if (jsdomFlag) { - expect7(() => d.checkValidity()).to.throw(Error); - } else { - } - }); - it("reportValidity()", function() { - let d = document2.createElement("monster-customcontrol"); - form.appendChild(d); - if (jsdomFlag) { - expect7(() => d.reportValidity()).to.throw(Error); - } else { - } - }); - it("setValidity()", function() { - let d = document2.createElement("monster-customcontrol"); - form.appendChild(d); - if (jsdomFlag) { - expect7(() => d.setValidity()).to.throw(Error); - } else { - expect7(d.setValidity({ "valueMissing": true }, "my message")).to.be.undefined; - } - }); - }); - }); - }); - - // test/cases/dom/locale.mjs - init_locale(); - init_locale2(); - describe("Attributes", function() { - before(function(done) { - initJSDOM().then(() => { - done(); - }); - }); - describe("getLocaleOfDocument", function() { - [ - ["de"], - ["sl-IT-nedis"], - ["en-GB"] - ].forEach(function(data) { - let a2 = data.shift(); - it("return language " + a2, function() { - let html = document.getElementsByTagName("html"); - let node = html.item(0); - node.setAttribute("lang", a2); - expect(getLocaleOfDocument().toString()).to.be.equal(a2); - }); - }); - }); - it("return language en", function() { - let html = document.getElementsByTagName("html"); - let node = html.item(0); - let lang = node.getAttribute("lang"); - node.removeAttribute("lang"); - const locale = getLocaleOfDocument(); - expect(locale).to.be.instanceOf(Locale); - expect(locale.localeString).to.be.equal(navigator.language); - node.setAttribute("lang", lang); - }); - }); - - // test/cases/dom/theme.mjs - init_util(); - init_theme(); - describe("Theme", function() { - before(function(done) { - initJSDOM().then(() => { - done(); - }); - }); - describe("new Theme()", function() { - it("should return Theme object", function() { - expect(new Theme("my-theme")).is.a.instanceOf(Theme); - }); - it("should return Theme-Name", function() { - expect(new Theme("my-theme").getName()).is.equal("my-theme"); - }); - it("should throw Error because empty argument", function() { - expect(() => new Theme()).to.throw(TypeError); - }); - it("should throw Error because no string argument", function() { - expect(() => new Theme(2)).to.throw(TypeError); - }); - }); - describe("getDocumentTheme()", function() { - it("should return Theme object", function() { - expect(getDocumentTheme()).is.a.instanceOf(Theme); - }); - it("should return Default Theme name", function() { - expect(getDocumentTheme().getName()).is.equal("monster"); - }); - }); - describe("getDocumentTheme()", function() { - beforeEach(() => { - document.querySelector("html").setAttribute("data-monster-theme-name", "testtheme"); - }); - afterEach(() => { - document.querySelector("html").removeAttribute("data-monster-theme-name"); - }); - it("should return testtheme Theme name", function() { - expect(getDocumentTheme().getName()).is.equal("testtheme"); - }); - }); - }); - - // test/cases/dom/resource.mjs - var Resource2; - var DerivedResource; - describe("Resource", function() { - before(function(done) { - initJSDOM().then(() => { - Promise.resolve().then(() => (init_resource(), resource_exports)).then((m) => { - Resource2 = m["Resource"]; - DerivedResource = class extends Resource2 { - constructor() { - super({ - "data-url": "http://example.com" - }); - } - static getURLAttribute() { - return "data-url"; - } - }; - done(); - }); - }); - }); - describe("DerivedResource", function() { - it("should instanceof Resource", function() { - expect(new DerivedResource()).to.be.an.instanceof(Resource2); - }); - }); - }); - - // ../application/source/dom/resourcemanager.mjs - init_extend(); - init_base(); - init_global(); - - // ../application/source/types/internal.mjs - init_constants(); - init_extend(); - init_pathfinder(); - init_dataurl(); - init_is(); - init_observer(); - init_proxyobserver(); - init_validate(); - init_is(); - var propertyName = "internalDefaults"; - function equipWithInternal() { - const self2 = this; - validateObject(self2); - if (!hasGetter(self2, propertyName)) { - Object.defineProperty(self2, propertyName, { - get: function() { - return {}; - } - }); - } - const defaults = extend({}, self2[propertyName] || {}); - self2[internalSymbol] = new ProxyObserver(defaults); - self2["attachInternalObserver"] = (observer) => { - self2[internalSymbol].attachObserver(observer); - return self2; - }; - self2["detachInternalObserver"] = (observer) => { - self2[internalSymbol].detachObserver(observer); - return self2; - }; - self2["containsInternalObserver"] = (observer) => { - return self2[internalSymbol].containsObserver(observer); - }; - self2["setInternal"] = (path, value) => { - new Pathfinder(self2[internalSymbol].getSubject()).setVia(path, value); - return self2; - }; - self2["setInternals"] = (options) => { - if (isString(options)) { - options = parseOptionsJSON2(options); - } - extend(self2[internalSymbol].getSubject(), defaults, options); - return self2; - }; - self2["getInternal"] = (path, defaultValue) => { - let value; - try { - value = new Pathfinder(self2[internalSymbol].getRealSubject()).getVia(path); - } catch (e) { - } - if (value === void 0) - return defaultValue; - return value; - }; - } - function hasGetter(obj, prop) { - while (isObject(obj)) { - if (Object.getOwnPropertyDescriptor(obj, prop)?.["get"]) { - return true; - } - obj = Object.getPrototypeOf(obj); - } - return false; - } - function parseOptionsJSON2(data) { - let obj = {}; - if (!isString(data)) { - return obj; - } - try { - let dataUrl = parseDataURL(data); - data = dataUrl.content; - } catch (e) { - } - try { - obj = JSON.parse(data); - } catch (e) { - throw e; - } - return validateObject(obj); - } - - // ../application/source/dom/resourcemanager.mjs - init_is(); - init_constants2(); - init_resource(); - var ResourceManager = class extends Base { - /** - * - * @param {Object} options - * throw {Error} unsupported document type - */ - constructor(options) { - super(options); - equipWithInternal.call(this); - if (!(this.getOption("document") instanceof Document)) { - throw new Error("unsupported document type"); - } - } - /** - * @deprecated since 3.15.0 use getInternal instead - * @property {string} baseurl - */ - getOption(key) { - return this.getInternal(key); - } - /** - * @property {string} baseurl - */ - getBaseURL() { - this.getOption("document")?.baseURL; - } - /** - * @property {string} baseurl - * @deprecated since 3.15.0 use internalDefaults instead - */ - get defaults() { - return this.internalDefaults; - } - /** - * - * @property {HTMLDocument} document=document Document - * @property {Object} resources - * @property {Array} resources.scripts=[] array with {@link Monster.DOM.Resource.Script} objects - * @property {Array} resources.stylesheets=[] array with {@link Monster.DOM.Resource.Link.Stylesheet} objects - * @property {Array} resources.data=[] array with {@link Monster.DOM.Resource.Data} objects - */ - get internalDefaults() { - return Object.assign( - {}, - { - document: getGlobalObject("document"), - resources: { - scripts: [], - stylesheets: [], - data: [] - } - } - ); - } - /** - * Append Tags to DOM - * - * @return {Monster.DOM.ResourceManager} - * @throws {Error} unsupported resource definition - */ - connect() { - runResourceMethod.call(this, "connect"); - return this; - } - /** - * Check if available - * - * @return {Promise} - * @throws {Error} unsupported resource definition - */ - available() { - return Promise.all(runResourceMethod.call(this, "available")); - } - /** - * Add a script - * - * @param {string|URL} url - * @param [Object|undefined} options - * @return {Monster.DOM.ResourceManager} - * @see Monster.DOM.Resource.Script - */ - addScript(url, options) { - return addResource.call(this, "scripts", url, options); - } - /** - * Add Stylesheet - * - * @param {string|URL} url - * @param [Object|undefined} options - * @return {Monster.DOM.ResourceManager} - * @see Monster.DOM.Resource.Link.Stylesheet - */ - addStylesheet(url, options) { - return addResource.call(this, "stylesheets", url, options); - } - /** - * Add Data Tag - * - * @param {string|URL} url - * @param [Object|undefined} options - * @return {Monster.DOM.ResourceManager} - * @see Monster.DOM.Resource.Data - */ - addData(url, options) { - return addResource.call(this, "data", url, options); - } - }; - function runResourceMethod(method) { - const self2 = this; - const result = []; - for (const type of ["scripts", "stylesheets", "data"]) { - const resources = self2.getOption(`resources.${type}`); - if (!isArray(resources)) { - continue; - } - for (const resource of resources) { - if (!(resource instanceof Resource)) { - throw new Error("unsupported resource definition"); - } - result.push(resource[method]()); - } - } - return result; - } - function addResource(type, url, options) { - const self2 = this; - if (url instanceof URL) { - url = url.toString(); - } - options = options || {}; - let resource; - switch (type) { - case "scripts": - resource = new Script(extend({}, options, { [ATTRIBUTE_SRC]: url })); - break; - case "stylesheets": - resource = new Stylesheet(extend({}, options, { [ATTRIBUTE_HREF]: url })); - break; - case "data": - resource = new Data(extend({}, options, { [ATTRIBUTE_SRC]: url })); - break; - default: - throw new Error(`unsupported type ${type}`); - } - self2.getOption("resources")?.[type].push(resource); - return self2; - } - - // test/cases/dom/resourcemanager.mjs - describe("ResourceManager", function() { - let fetchReference2, returnStatus; - before(function(done) { - initJSDOM().then(() => { - done(); - }).catch((e) => done(e)); - }); - afterEach(() => { - globalThis["fetch"] = fetchReference2; - cleanupDOMFromTesting(); - }); - beforeEach(() => { - initMutationObserverForTesting(); - returnStatus = 200; - fetchReference2 = globalThis["fetch"]; - globalThis["fetch"] = function(url, options) { - if (!url) - throw new Error("missing url"); - return new Promise((resolve, reject) => { - resolve({ - text: function() { - return JSON.stringify({ - a: "test" - }); - }, - status: returnStatus - }); - }); - }; - }); - describe("new", function() { - it("new ResourceManager() should return ResourceManager object", function() { - let d = new ResourceManager(); - expect(d).to.be.instanceOf(ResourceManager); - }); - }); - describe("load resources", function() { - let manager; - beforeEach(() => { - manager = new ResourceManager(); - }); - it("add script should instance of ResourceManager", function() { - expect(manager.addScript("/example.js")).to.be.instanceOf(ResourceManager); - }); - it("add style should instance of ResourceManager", function() { - expect(manager.addStylesheet("/style.js")).to.be.instanceOf(ResourceManager); - }); - it("add data should instance of ResourceManager", function() { - expect(manager.addData("/data.json")).to.be.instanceOf(ResourceManager); - }); - describe("connect resources", function() { - it("add script and connect should instance of ResourceManager", function() { - expect(manager.addScript("/example.js").connect()).to.be.instanceOf(ResourceManager); - }); - it("add style and connect should instance of ResourceManager", function() { - expect(manager.addStylesheet("/style.js").connect()).to.be.instanceOf(ResourceManager); - }); - it("add data and connect should instance of ResourceManager", function() { - expect(manager.addData("/data.json").connect()).to.be.instanceOf(ResourceManager); - }); - }); - describe("check availability resources", function() { - it("add script and check availability should return Promise", function() { - expect(manager.addScript("/example.js").available()).to.be.instanceOf(Promise); - }); - it("add style and check availability should should return Promise", function() { - expect(manager.addStylesheet("/style.js").available()).to.be.instanceOf(Promise); - }); - it("add data and check availability should should return Promise", function() { - expect(manager.addData("/data.json").available()).to.be.instanceOf(Promise); - }); - }); - describe("check availability example.json", function() { - it("add data and check content", function(done) { - manager.addData("https://example.com/example.json").connect().available().then((r) => { - expect(document.querySelector("html").outerHTML).contains('>{"a":"test"}<\/script></head>'); - done(); - }).catch((e) => done(e)); - }); - }); - }); - }); - - // test/cases/dom/util.mjs - init_util(); - init_util(); - describe("DOM", function() { - before(async function() { - initJSDOM(); - }); - describe("getDocument()", function() { - it("should return document object", function() { - let d = getDocument(); - expect(typeof d).is.equal("object"); - }); - }); - describe("getWindow()", function() { - it("should return document object", function() { - let d = getWindow(); - expect(typeof d).is.equal("object"); - }); - }); - describe("getDocumentFragmentFromString()", function() { - [ - ["<div></div>"], - ["<div><div>2</div></div>"], - ["<div><div>2</div>", "<div><div>2</div></div>"] - // test invalid html - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - if (!b) - b = a2; - it("should return documentFragment object " + a2, function() { - let fragment = getDocumentFragmentFromString(a2); - expect(fragment).to.be.instanceOf(DocumentFragment); - var div = document.createElement("div"); - div.appendChild(fragment.cloneNode(true)); - expect(div.innerHTML).to.be.equal(b); - }); - }); - }); - describe("getContainingDocument", () => { - let jsDomDocument; - beforeEach(() => { - jsDomDocument = getDocument(); - }); - it("should throw an error when called with an invalid argument", () => { - expect(() => getContainingDocument(null)).to.throw("Invalid argument. Expected an HTMLElement."); - }); - it("should return the correct containing document for an element in the main document", () => { - const element = jsDomDocument.createElement("div"); - const containingDocument = getContainingDocument(element); - expect(containingDocument).to.null; - }); - it("should return the correct containing document for an element inside a shadow root", () => { - const host = jsDomDocument.createElement("div"); - const shadowRoot = host.attachShadow({ mode: "open" }); - const element = jsDomDocument.createElement("span"); - shadowRoot.appendChild(element); - const containingDocument = getContainingDocument(element); - expect(containingDocument).to.not.null; - }); - it("should return the correct containing document for an element inside a nested shadow root", () => { - const outerHost = jsDomDocument.createElement("div"); - const outerShadowRoot = outerHost.attachShadow({ mode: "open" }); - const innerHost = jsDomDocument.createElement("div"); - outerShadowRoot.appendChild(innerHost); - const innerShadowRoot = innerHost.attachShadow({ mode: "open" }); - const element = jsDomDocument.createElement("span"); - innerShadowRoot.appendChild(element); - const containingDocument = getContainingDocument(element); - expect(containingDocument).to.not.null; - }); - it("should return null when the element is not attached to any document", () => { - const detachedElement = jsDomDocument.createElement("div"); - detachedElement.remove(); - const containingDocument = getContainingDocument(detachedElement); - expect(containingDocument).to.be.null; - }); - }); - }); - - // test/cases/dom/find.mjs - init_util(); - function setupTestEnvironment() { - class TestComponent extends HTMLElement { - constructor() { - super(); - this.attachShadow({ mode: "open" }); - } - } - if (!customElements.get("test-component")) { - customElements.define("test-component", TestComponent); - } - } - function cleanupTestEnvironment() { - let mocks = document.getElementById("mocks"); - mocks.innerHTML = ""; - } - describe("findElementWithIdUpwards", () => { - before((done) => { - initJSDOM().then(() => { - setupTestEnvironment(); - done(); - }); - }); - after(() => { - cleanupTestEnvironment(); - }); - beforeEach(() => { - let mocks = document.getElementById("mocks"); - mocks.innerHTML = ` - <div id="container"> - <div id="parent"> - <div id="child"></div> - </div> - </div>`; - const shadowHost = document.createElement("div"); - document.body.appendChild(shadowHost); - const shadowRoot = shadowHost.attachShadow({ mode: "open" }); - const innerElement = document.createElement("div"); - innerElement.id = "inner"; - shadowRoot.appendChild(innerElement); - }); - it("should find the element with the target ID in the normal DOM", () => { - const child = document.getElementById("child"); - const result = findElementWithIdUpwards(child, "parent"); - expect(result).to.equal(document.getElementById("parent")); - }); - it("should find the element with the target ID in the shadow DOM", () => { - const innerElement = document.querySelector("div[shadowroot] > div"); - const result = findElementWithIdUpwards(innerElement, "inner"); - expect(result).to.equal(innerElement); - }); - it("should return null if the element with the target ID is not found", () => { - const child = document.getElementById("child"); - const result = findElementWithIdUpwards(child, "nonexistent"); - expect(result).to.be.null; - }); - }); - - // ../application/source/dom/dimension.mjs - init_util(); - init_validate(); - var CURRENT_DEVICE_DPI = function() { - let i = 0; - for (i = 56; i < 2e3; i++) { - if (getWindow().matchMedia(`(max-resolution: ${i}dpi)`).matches === true) { - return i; - } - } - return i; - }; - function getDeviceDPI() { - if (typeof CURRENT_DEVICE_DPI === "function") { - CURRENT_DEVICE_DPI = CURRENT_DEVICE_DPI(); - } - return getWindow().devicePixelRatio * CURRENT_DEVICE_DPI; - } - function convertToPixels(value, parentElement = document.documentElement, fontSizeElement = document.documentElement) { - validateString(value); - const regex = /^(-?[\d.]+)(.*)$/; - const matchResult = value.match(regex); - if (!matchResult) { - throw new Error(`Invalid value format: ${value}`); - } - const [, num, unit] = matchResult; - const number = parseFloat(num); - const dpi = getDeviceDPI(); - if (unit === "px") { - return number; - } else if (unit === "em") { - const fontSize = parseFloat(window.getComputedStyle(fontSizeElement).fontSize); - return number * fontSize; - } else if (unit === "rem") { - const rootFontSize = parseFloat(window.getComputedStyle(parentElement).fontSize); - return number * rootFontSize; - } else if (unit === "%") { - const parentWidth = parseFloat(window.getComputedStyle(parentElement).width); - return number * parentWidth / 100; - } else if (unit === "in") { - return number * dpi; - } else if (unit === "cm") { - return number * dpi / 2.54; - } else if (unit === "mm") { - return number * dpi / 25.4; - } else if (unit === "pt") { - return number * dpi / 72; - } else if (unit === "pc") { - return number * dpi / 6; - } else { - throw new Error(`Unsupported unit: ${unit}`); - } - } - - // test/cases/dom/dimension.mjs - init_util(); - init_global(); - - // ../application/source/util/runtime.mjs - var ENV_AWS_LAMBDA = "aws-lambda"; - var ENV_GOOGLE_FUNCTIONS = "google-functions"; - var ENV_ELECTRON = "electron"; - var ENV_NODE = "node"; - var ENV_BROWSER = "browser"; - var ENV_WEB_WORKER = "web-worker"; - var ENV_DENO = "deno"; - var ENV_UNKNOWN = "unknown"; - function detectRuntimeEnvironment() { - if (typeof process !== "undefined" && process.env != null && process.env.AWS_LAMBDA_FUNCTION_NAME) { - return ENV_AWS_LAMBDA; - } - if (typeof process !== "undefined" && process.env != null && process.env.FUNCTION_NAME) { - return ENV_GOOGLE_FUNCTIONS; - } - if (typeof process !== "undefined" && process.versions != null && process.versions.node != null) { - if (process.versions.electron != null) { - return ENV_ELECTRON; - } - return ENV_NODE; - } - if (typeof window !== "undefined" && typeof window.document !== "undefined" && typeof navigator !== "undefined" && typeof navigator.userAgent === "string") { - if (typeof self === "object" && typeof importScripts === "function") { - return ENV_WEB_WORKER; - } - return ENV_BROWSER; - } - if (typeof Deno !== "undefined") { - return ENV_DENO; - } - return ENV_UNKNOWN; - } - - // test/cases/dom/dimension.mjs - function getMockWindow(dpi) { - if (detectRuntimeEnvironment() === "browser") { - return getWindow(); - } - const dom = new JSDOMExport("", { - pretendToBeVisual: true, - resources: "usable" - }); - dom.window.matchMedia = (query) => { - const dpiRegex = /\(max-resolution: (\d+)dpi\)/; - const match = query.match(dpiRegex); - if (match) { - const maxDpi = parseInt(match[1], 10); - return { matches: dpi <= maxDpi }; - } - return { matches: false }; - }; - return dom.window; - } - describe("dimension", () => { - let currentEnvironment; - before(function(done) { - initJSDOM().then(() => { - done(); - }); - }); - beforeEach(() => { - const testDpi = 96; - const testWindow = getMockWindow(testDpi); - getGlobal().window = testWindow; - }); - afterEach(() => { - delete getGlobal().window; - }); - describe("convertToPixels", () => { - it("should correctly convert px values", () => { - const result = convertToPixels("100px"); - expect(result).to.equal(100); - }); - it("should throw an error when the input value has an invalid format", () => { - const invalidValue = "invalid_value"; - const errorFn = () => { - convertToPixels(invalidValue); - }; - expect(errorFn).to.throw(Error, `Invalid value format: ${invalidValue}`); - }); - it("should handle negative values correctly", () => { - const negativeValue = "-10px"; - const expectedResult = -10; - const result = convertToPixels(negativeValue); - expect(result).to.equal(expectedResult); - }); - it("should correctly convert em values", () => { - const testElement = document.createElement("div"); - testElement.style.fontSize = "16px"; - document.body.appendChild(testElement); - const result = convertToPixels("2em", testElement, testElement); - expect(result).to.equal(32); - document.body.removeChild(testElement); - }); - it("should correctly convert rem values", () => { - const testElement = document.createElement("div"); - testElement.style.fontSize = "16px"; - document.documentElement.appendChild(testElement); - const result = convertToPixels("2rem", testElement); - expect(result).to.equal(32); - document.documentElement.removeChild(testElement); - }); - it("should correctly convert percentage values", () => { - const testElement = document.createElement("div"); - testElement.style.width = "500px"; - document.body.appendChild(testElement); - const result = convertToPixels("50%", testElement); - expect(result).to.equal(250); - document.body.removeChild(testElement); - }); - it("should throw an error for unsupported units", () => { - expect(() => convertToPixels("10unsupportedUnit")).to.throw("Unsupported unit: unsupportedUnit"); - }); - }); - describe("getDeviceDPI", () => { - it("should return the correct device DPI", () => { - const testDpi = 96; - const testWindow = getMockWindow(testDpi); - getGlobal().window = testWindow; - const deviceDpi = getDeviceDPI(); - expect(deviceDpi).to.equal(testDpi * testWindow.devicePixelRatio); - delete getGlobal().window; - }); - it("should cache the result and return the same value", () => { - const testDpi = 96; - const testWindow = getMockWindow(testDpi); - getGlobal().window = testWindow; - const deviceDpi1 = getDeviceDPI(); - const deviceDpi2 = getDeviceDPI(); - expect(deviceDpi1).to.equal(deviceDpi2); - delete getGlobal().window; - }); - }); - }); - - // test/cases/dom/customelement.mjs - init_constants(); - init_constants2(); - init_util(); - init_proxyobserver(); - init_updater(); - var expect8 = chai_default.expect; - chai_default.use(chaiDom); - var html13 = ` - <div id="test1"> - </div> -`; - var html22 = ` - <input data-monster-bind="path:a" id="test2" data-monster-attributes="value path:a"> -`; - var updaterSymbolKey = "@schukai/monster/dom/custom-element@@options-updater-link"; - var updaterSymbolSymbol = Symbol.for(updaterSymbolKey); - describe("DOM", function() { - let CustomElement2, registerCustomElement2, TestComponent, document2, TestComponent2, assignUpdaterToElement; - describe("assignUpdaterToElement", function() { - before(function(done) { - initJSDOM().then(() => { - Promise.resolve().then(() => (init_customelement(), customelement_exports)).then((m) => { - try { - CustomElement2 = m["CustomElement"]; - assignUpdaterToElement = function(elements, object) { - return addObjectWithUpdaterToElement.call(this, elements, updaterSymbolSymbol, object); - }; - document2 = getDocument(); - done(); - } catch (e) { - done(e); - } - }); - }); - }); - beforeEach(() => { - let mocks = document2.getElementById("mocks"); - mocks.innerHTML = html22; - }); - afterEach(() => { - let mocks = document2.getElementById("mocks"); - mocks.innerHTML = ""; - }); - it("should assign an updater to an element", function(done) { - let element = document2.getElementById("test2"); - expect8(document2.getElementById("mocks").innerHTML).to.equal(html22); - const a2 = { a: 1 }; - const b = { b: 2 }; - const ap = new ProxyObserver(a2); - const bp = new ProxyObserver(b); - const x = ap.getSubject(); - const y = bp.getSubject(); - const set = /* @__PURE__ */ new Set(); - set.add(element); - assignUpdaterToElement.call(element, set, ap); - assignUpdaterToElement.call(element, set, bp); - expect8(JSON.stringify(x)).to.equal('{"a":1}'); - expect8(JSON.stringify(y)).to.equal('{"b":2}'); - const sy = updaterSymbolSymbol; - let v = element.getAttribute("data-monster-objectlink"); - expect8(v).to.equal("Symbol(" + updaterSymbolKey + ")"); - const updater = element[sy]; - for (const v2 of updater) { - for (const u of v2) { - u.run().then(() => { - u.enableEventProcessing(); - }); - } - } - expect8(updater).to.be.an.instanceof(Set); - expect8(updater).to.be.a("Set"); - x.a = 3; - bp.getSubject().b = 4; - setTimeout(() => { - let mockHTML = document2.getElementById("mocks"); - expect8(mockHTML.querySelector("#test2")).to.have.value("3"); - expect8(mockHTML.querySelector("#test2")).to.have.attribute("data-monster-objectlink", "Symbol(" + updaterSymbolKey + ")"); - expect8(element.value).to.equal("3"); - expect8(JSON.stringify(ap.getRealSubject())).to.equal('{"a":3}'); - expect8(JSON.stringify(bp.getRealSubject())).to.equal('{"b":4}'); - done(); - }, 10); - }); - }); - describe("CustomElement()", function() { - before(function(done) { - initJSDOM().then(() => { - Promise.resolve().then(() => (init_customelement(), customelement_exports)).then((m) => { - try { - CustomElement2 = m["CustomElement"]; - registerCustomElement2 = m["registerCustomElement"]; - TestComponent = class extends CustomElement2 { - static getTag() { - return "monster-testclass"; - } - }; - registerCustomElement2(TestComponent); - TestComponent2 = class extends CustomElement2 { - static getTag() { - return "monster-testclass2"; - } - /** - * - * @return {Object} - */ - get defaults() { - return Object.assign({}, super.defaults, { - demotest: void 0, - templates: { - main: '<h1></h1><article><p>test</p><div id="container"></div></article>' - } - }); - } - }; - registerCustomElement2(TestComponent2); - document2 = getDocument(); - done(); - } catch (e) { - done(e); - } - }); - }); - }); - beforeEach(() => { - let mocks = document2.getElementById("mocks"); - mocks.innerHTML = html13; - }); - afterEach(() => { - let mocks = document2.getElementById("mocks"); - mocks.innerHTML = ""; - }); - describe("CustomElement() with Config", function() { - it("should read config from tag", function() { - let mocks = document2.getElementById("mocks"); - mocks.innerHTML = ` - - <script id="config1" type="application/json"> - { - "demotest":1425 - } - <\/script> - - <monster-testclass2 id="thisisatest" data-monster-options-selector="#config1"> - </monster-testclass2> - `; - let monster = document2.getElementById("thisisatest"); - expect8(monster.getOption("demotest")).is.eql(1425); - }); - }); - describe("create", function() { - it("should return custom-element object", function() { - let d = new TestComponent(); - expect8(typeof d).is.equal("object"); - }); - }); - describe("connect empty element", function() { - it("document should contain monster-testclass", function() { - let d = document2.createElement("monster-testclass"); - document2.getElementById("test1").appendChild(d); - expect8(document2.getElementsByTagName("monster-testclass").length).is.equal(1); - expect8(document2.getElementById("test1")).contain.html("<monster-testclass></monster-testclass>"); - }); - }); - describe("connect element with html", function() { - it("document should contain monster-testclass2", function(done) { - let d = document2.createElement("monster-testclass2"); - document2.getElementById("test1").appendChild(d); - setTimeout(function() { - try { - expect8(document2.getElementsByTagName("monster-testclass2").length).is.equal(1); - expect8(document2.getElementsByTagName("monster-testclass2").item(0).shadowRoot.innerHTML).is.equal('<h1></h1><article><p>test</p><div id="container"></div></article>'); - expect8(document2.getElementById("test1")).contain.html('<monster-testclass2 data-monster-objectlink="Symbol(' + updaterSymbolKey + ')"></monster-testclass2>'); - return done(); - } catch (e) { - done(e); - } - }, 10); - }); - }); - describe("Options change", function() { - it("delegatesFocus should change from true to false", function() { - let element = document2.createElement("monster-testclass"); - const o = element[internalSymbol].realSubject; - expect8(Object.is(element[internalSymbol].realSubject, o)).to.be.true; - expect8(element[internalSymbol].realSubject.options.delegatesFocus).to.be.true; - expect8(element[internalSymbol].subject.options.delegatesFocus).to.be.true; - expect8(element.getOption("delegatesFocus")).to.be.true; - expect8(Object.is(element[internalSymbol].realSubject, o)).to.be.true; - element.setAttribute(ATTRIBUTE_OPTIONS, JSON.stringify({ delegatesFocus: false })); - expect8(Object.is(element[internalSymbol].realSubject, o)).to.be.true; - expect8(element.getOption("delegatesFocus")).to.be.false; - expect8(element[internalSymbol].realSubject.options.delegatesFocus).to.be.false; - expect8(Object.is(element[internalSymbol].realSubject, o)).to.be.true; - }); - }); - describe("setOptions()", function() { - [ - ["shadowMode", "x1"], - ["templates.main", "x2"], - // is explicitly set to undefined - ["delegatesFocus", "x4"] - ].forEach(function(data) { - let key = data.shift(); - let newValue = data.shift(); - let text = key + " should return " + newValue; - if (newValue !== void 0) { - text = key + " was not set, therefore default " + newValue; - } - it(text, function() { - let d = document2.createElement("monster-testclass"); - expect8(d.getOption(key)).to.be.not.equal(newValue); - let x = d.setOption(key, newValue); - expect8(d.getOption(key)).to.be.equal(newValue); - }); - }); - }); - describe("getOptions()", function() { - [ - ["shadowMode", "open"], - ["templates.main", void 0], - // is explicitly set to undefined - ["delegatesFocus", true], - ["x.y.z", true, true], - // x.y.z isnt set, defaultValue is used - ["x", true, true] - // x isnt set, defaultValue is used - ].forEach(function(data) { - let key = data.shift(); - let value = data.shift(); - let defaultValue = data.shift(); - let text = key + " should return " + value; - if (defaultValue !== void 0) { - text = key + " was not set, therefore default " + defaultValue; - } - it(text, function() { - let d = document2.createElement("monster-testclass"); - let x = d.getOption(key, defaultValue); - expect8(x).to.be.equal(value); - }); - }); - }); - describe("Assign CSSStyle as Array with wrong type", function() { - const htmlTAG = "monster-testclass-x1"; - let mocks, TestComponentX1; - beforeEach(() => { - mocks = document2.getElementById("mocks"); - mocks.innerHTML = html13; - TestComponentX1 = class extends CustomElement2 { - static getTag() { - return htmlTAG; - } - static getCSSStyleSheet() { - return [true]; - } - /** - * @return {Object} - */ - get defaults() { - return Object.assign({}, super.defaults, { - templates: { - main: "<h1>test</h1>" - } - }); - } - }; - registerCustomElement2(TestComponentX1); - }); - it(htmlTAG + " should throw Exception", function(done) { - let d = document2.createElement(htmlTAG); - let div = document2.getElementById("test1"); - div.append(d); - expect8(div).contain.html('data-monster-error="TypeError: value is not an instance of CSSStyleSheet"'); - done(); - }); - }); - describe("Assign CSSStyle as Array and CSSStylesheet", function() { - const htmlTAG = "monster-testclass-x113-2"; - let mocks, TestComponentX113X2; - beforeEach(() => { - mocks = document2.getElementById("mocks"); - mocks.innerHTML = html13; - TestComponentX113X2 = class extends CustomElement2 { - static getTag() { - return htmlTAG; - } - /** - * @return {Object} - */ - get defaults() { - return Object.assign({}, super.defaults, { - templates: { main: "<h1>test</h1>" } - }); - } - static getCSSStyleSheet() { - const s = new CSSStyleSheet(); - s.insertRule("a { color : red}"); - return [s]; - } - }; - registerCustomElement2(TestComponentX113X2); - }); - it(htmlTAG + " should throw Exception 2", function(done) { - let d = document2.createElement(htmlTAG); - let div = document2.getElementById("test1"); - div.append(d); - expect8(d.shadowRoot.innerHTML).is.eq("<h1>test</h1>"); - done(); - }); - }); - describe("Assign CSSStyle as Array and CSS as string", function() { - const htmlTAG = "monster-testclass-x113-21"; - let mocks, TestComponentX113X22; - beforeEach(() => { - mocks = document2.getElementById("mocks"); - mocks.innerHTML = html13; - TestComponentX113X22 = class extends CustomElement2 { - static getTag() { - return htmlTAG; - } - /** - * @return {Object} - */ - get defaults() { - return Object.assign({}, super.defaults, { - templates: { main: "<h1>test</h1>" } - }); - } - static getCSSStyleSheet() { - return "a { color:red }"; - } - }; - registerCustomElement2(TestComponentX113X22); - }); - it(htmlTAG + " should eq <style>a { color:red }</style><h1>test</h1>", function(done) { - let d = document2.createElement(htmlTAG); - let div = document2.getElementById("test1"); - div.append(d); - expect8(d.shadowRoot.innerHTML).is.eq("<style>a { color:red }</style><h1>test</h1>"); - done(); - }); - }); - describe("Assign CSSStyle as Array and CSS as string", function() { - const htmlTAG = "monster-testclass-x113-22"; - let mocks, TestComponentX113X223; - beforeEach(() => { - mocks = document2.getElementById("mocks"); - mocks.innerHTML = html13; - TestComponentX113X223 = class extends CustomElement2 { - static getTag() { - return htmlTAG; - } - /** - * @return {Object} - */ - get defaults() { - return Object.assign({}, super.defaults, { - templates: { main: "<h1>test</h1>" } - }); - } - static getCSSStyleSheet() { - return ["a { color:red }"]; - } - }; - registerCustomElement2(TestComponentX113X223); - }); - it(htmlTAG + " should eq <style>a { color:red }</style><h1>test</h1>", function(done) { - let d = document2.createElement(htmlTAG); - let div = document2.getElementById("test1"); - div.append(d); - expect8(d.shadowRoot.innerHTML).is.eq("<style>a { color:red }</style><h1>test</h1>"); - done(); - }); - }); - describe("hasNode()", function() { - let mocks; - beforeEach(() => { - mocks = document2.getElementById("mocks"); - mocks.innerHTML = html13; - }); - it("hasNode monster-testclass should return ...", function() { - let d = document2.createElement("monster-testclass"); - let p1 = document2.createElement("p"); - let t1 = document2.createTextNode("test1"); - p1.appendChild(t1); - let p = document2.createElement("div"); - let t = document2.createTextNode("test"); - p.appendChild(p1); - p.appendChild(t); - d.appendChild(p); - let div = document2.getElementById("test1"); - div.append(d); - let n1 = document2.createElement("p"); - expect8(d.hasNode(n1)).to.be.false; - expect8(d.hasNode(t)).to.be.true; - expect8(d.hasNode(p)).to.be.true; - expect8(d.hasNode(p1)).to.be.true; - expect8(d.hasNode(t1)).to.be.true; - }); - it("hasNode monster-testclass2 should return ...", function() { - let d = document2.createElement("monster-testclass2"); - let p1 = document2.createElement("p"); - let t1 = document2.createTextNode("test1"); - p1.appendChild(t1); - let p = document2.createElement("div"); - let t = document2.createTextNode("test"); - p.appendChild(p1); - p.appendChild(t); - let div = document2.getElementById("test1"); - div.append(d); - let a2 = d.shadowRoot.getElementById("container"); - d.shadowRoot.getElementById("container").appendChild(p); - let n1 = document2.createElement("p"); - expect8(d.hasNode(n1)).to.be.false; - expect8(d.hasNode(t)).to.be.true; - expect8(d.hasNode(p)).to.be.true; - expect8(d.hasNode(p1)).to.be.true; - expect8(d.hasNode(t1)).to.be.true; - }); - }); - }); - }); - - // test/cases/dom/attributes.mjs - init_attributes(); - var html14; - var html23; - var html32; - describe("Attributes", function() { - before(function(done) { - html14 = `<div id="test1"></div>`; - html23 = `<div id="test1"> - <div id="sub1"> - <div id="sub2"> - <div id="sub3"> - <div id="sub4"> - <div id="sub5"></div> - </div> - </div> - </div> - </div> -</div> -`; - html32 = `<div data-monster-role="test1"> - <div data-monster-role="sub1" id="a1" class="sub1"> - <div data-monster-role="sub2" id="a2" class="sub2"> - <div data-monster-role="sub3" id="a3" class="sub3"> - <div data-monster-role="sub4" id="a4" class="sub4"> - <div data-monster-role="sub5" id="a5" class="sub5"></div> - </div> - </div> - </div> - </div> -</div> -`; - initJSDOM().then(() => { - done(); - }).catch((e) => done(e)); - }); - describe("ObjectLink", function() { - const symbol2 = Symbol("mytest"); - beforeEach(() => { - let mocks = document.getElementById("mocks"); - mocks.innerHTML = html14; - }); - afterEach(() => { - let mocks = document.getElementById("mocks"); - mocks.innerHTML = ""; - }); - it("should handle object-links", function() { - let obj = { a: 1 }; - let element = document.getElementById("test1"); - expect(hasObjectLink(element, symbol2)).to.be.false; - addToObjectLink(element, symbol2, obj); - expect(hasObjectLink(element, symbol2)).to.be.true; - let o = getLinkedObjects(element, symbol2).next(); - expect(o.value).to.equal(obj); - removeObjectLink(element, symbol2); - expect(hasObjectLink(element, symbol2)).to.be.false; - expect(() => getLinkedObjects(element, symbol2)).to.throw(Error); - }); - }); - describe("findClosestObjectLink()", function() { - const symbol2 = Symbol("mytest"); - beforeEach(() => { - let mocks = document.getElementById("mocks"); - mocks.innerHTML = html23; - }); - afterEach(() => { - let mocks = document.getElementById("mocks"); - mocks.innerHTML = ""; - }); - it("should return objectlink", function() { - let sub4 = document.getElementById("sub4"); - let sub2 = document.getElementById("sub2"); - let obj = {}; - expect(hasObjectLink(sub2, symbol2)).to.be.false; - addToObjectLink(sub2, symbol2, obj); - expect(hasObjectLink(sub2, symbol2)).to.be.true; - let element = findClosestObjectLink(sub4); - expect(element).is.instanceOf(HTMLDivElement); - expect(element.getAttribute("id")).to.be.equal("sub2"); - }); - }); - describe("Attributes", function() { - beforeEach(() => { - let mocks = document.getElementById("mocks"); - mocks.innerHTML = html32; - }); - afterEach(() => { - let mocks = document.getElementById("mocks"); - mocks.innerHTML = ""; - }); - describe("find closest Attributes", function() { - [ - ["a5", "data-monster-role", void 0, "sub5"], - ["a5", "data-monster-role", "sub3", "sub3"], - ["a5", "data-monster-role", "sub1", "sub1"], - ["a4", "data-monster-role", "sub1", "sub1"], - ["a3", "data-monster-role", "sub1", "sub1"], - ["a2", "data-monster-role", void 0, "sub2"], - ["a5", "data-monster-role", "sub5", "sub5"] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - let c = data.shift(); - let d = data.shift(); - it("findClosestByAttribute(" + a2 + ", " + b + "," + c + ") should return " + d, function() { - expect(findClosestByAttribute(document.getElementById(a2), b, c).getAttribute("data-monster-role")).to.be.equal(d); - }); - }); - }); - describe("find closest Element with class", function() { - [ - ["a5", "sub3", "sub3"], - ["a5", "sub1", "sub1"], - ["a4", "sub1", "sub1"], - ["a3", "sub1", "sub1"], - ["a5", "sub5", "sub5"] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - let c = data.shift(); - it("findClosestByClass(" + a2 + ", " + b + ") should return " + c, function() { - expect(findClosestByClass(document.getElementById(a2), b).getAttribute("class")).to.be.equal(c); - }); - }); - }); - }); - describe("Attributes", function() { - beforeEach(() => { - let mocks = document.getElementById("mocks"); - mocks.innerHTML = html14; - }); - afterEach(() => { - let mocks = document.getElementById("mocks"); - mocks.innerHTML = ""; - }); - const atributeKey = "data-test"; - it("toggleAttributeToken(element, key, value)", function() { - let element = document.getElementById("test1"); - expect(element.hasAttribute(atributeKey)).to.be.false; - element.setAttribute(atributeKey, "apple bananna"); - toggleAttributeToken(element, atributeKey, "pinapple"); - expect(element.getAttribute(atributeKey)).to.be.equal("apple bananna pinapple"); - toggleAttributeToken(element, atributeKey, "pinapple"); - expect(element.getAttribute(atributeKey)).to.be.equal("apple bananna"); - }); - it("addAttributeToken(element, key, value)", function() { - let element = document.getElementById("test1"); - expect(element.hasAttribute(atributeKey)).to.be.false; - addAttributeToken(element, atributeKey, "pinapple"); - expect(element.getAttribute(atributeKey)).to.be.equal("pinapple"); - addAttributeToken(element, atributeKey, "bananna"); - expect(element.getAttribute(atributeKey)).to.be.equal("pinapple bananna"); - }); - it("removeAttributeToken(element, key, value)", function() { - let element = document.getElementById("test1"); - element.setAttribute(atributeKey, "apple bananna lemmon"); - removeAttributeToken(element, atributeKey, "pinapple"); - expect(element.getAttribute(atributeKey)).to.be.equal("apple bananna lemmon"); - removeAttributeToken(element, atributeKey, "bananna"); - expect(element.getAttribute(atributeKey)).to.be.equal("apple lemmon"); - }); - it("containsAttributeToken(element, key, value)", function() { - let element = document.getElementById("test1"); - expect(containsAttributeToken(element, atributeKey, "pinapple")).to.be.false; - element.setAttribute(atributeKey, "apple bananna"); - expect(containsAttributeToken(element, atributeKey, "pinapple")).to.be.false; - expect(containsAttributeToken(element, atributeKey, "bananna")).to.be.true; - expect(containsAttributeToken(element, atributeKey, "apple")).to.be.true; - }); - it(" replaceAttributeToken(element, key, value)", function() { - let element = document.getElementById("test1"); - element.setAttribute(atributeKey, "apple bananna tomato"); - replaceAttributeToken(element, atributeKey, "tomato", "lemmon"); - expect(element.getAttribute(atributeKey)).to.be.equal("apple bananna lemmon"); - replaceAttributeToken(element, atributeKey, "bananna", "pear"); - expect(element.getAttribute(atributeKey)).to.be.equal("apple pear lemmon"); - }); - it("clearAttributeTokens(element, key)", function() { - let element = document.getElementById("test1"); - element.setAttribute(atributeKey, "apple bananna"); - clearAttributeTokens(element, atributeKey); - expect(element.getAttribute(atributeKey)).to.be.equal(""); - }); - }); - }); - - // test/cases/dom/events.mjs - init_events(); - describe("Events", function() { - before(async function() { - initJSDOM(); - }); - describe("findTargetElementFromEvent()", function() { - it("find object", function(done) { - let container = document.createElement("div"); - container.setAttribute("data-monster", "hello"); - let div = document.createElement("div"); - container.appendChild(div); - div.addEventListener("click", (event) => { - let e = findTargetElementFromEvent(event, "data-monster"); - expect(e.getAttribute("data-monster")).to.be.equal("hello"); - done(); - }); - setTimeout(() => { - fireEvent(div, "click"); - }, 0); - }); - }); - describe("fireEvent()", function() { - it("should fire a click event", function(done) { - let div = document.createElement("div"); - div.addEventListener("click", () => { - done(); - }); - fireEvent(div, "click"); - }); - it("should fire a touch event", function(done) { - let div = document.createElement("div"); - div.addEventListener("touch", () => { - done(); - }); - fireEvent(div, "touch"); - }); - it("should fire a touch event on collection", function(done) { - let div = document.createElement("div"); - div.addEventListener("touch", () => { - done(); - }); - div.appendChild(document.createElement("div")); - let collection = div.querySelectorAll("div"); - fireEvent(collection, "touch"); - }); - it("should fire a touch event", function(done) { - let div = document.createElement("div"); - div.addEventListener("touch", () => { - done(); - }); - div.appendChild(document.createElement("div")); - let collection = div.querySelectorAll("div"); - fireEvent(collection, "touch"); - }); - it("should throw error", function() { - expect(() => fireEvent({}, "touch")).to.throw(Error); - }); - }); - describe("fireCustomEvent()", function() { - it("should fire a click event", function(done) { - let div = document.createElement("div"); - div.addEventListener("click", () => { - done(); - }); - fireCustomEvent(div, "click"); - }); - it("should fire a touch event", function(done) { - let div = document.createElement("div"); - div.addEventListener("touch", () => { - done(); - }); - fireCustomEvent(div, "touch"); - }); - it("should fire a touch event on collection1", function(done) { - let div = document.createElement("div"); - div.addEventListener("touch", (e) => { - if (e.detail.detail !== "hello world") { - done("error"); - } - done(); - }); - div.appendChild(document.createElement("div")); - let collection = div.querySelectorAll("div"); - fireCustomEvent(collection, "touch", "hello world"); - }); - it("should fire a touch event on collection2", function(done) { - let div = document.createElement("div"); - div.addEventListener("touch", (e) => { - if (e.detail.a !== "hello world") { - done("error"); - } - done(); - }); - div.appendChild(document.createElement("div")); - let collection = div.querySelectorAll("div"); - fireCustomEvent(collection, "touch", { a: "hello world" }); - }); - it("should fire a touch event", function(done) { - let div = document.createElement("div"); - div.addEventListener("touch", () => { - done(); - }); - div.appendChild(document.createElement("div")); - let collection = div.querySelectorAll("div"); - fireCustomEvent(collection, "touch"); - }); - it("should throw error", function() { - expect(() => fireCustomEvent({}, "touch")).to.throw(Error); - }); - }); - }); - - // ../application/source/dom/worker/factory.mjs - init_constants(); - init_base(); - init_global(); - init_is(); - init_validate(); - var Factory = class extends Base { - /** - * - */ - constructor() { - super(); - this[internalSymbol] = { - worker: /* @__PURE__ */ new WeakMap() - }; - } - /** - * Creates a worker from a URL - * - * @param {string|URL} url - * @param {function} messageHandler - * @param {function} errorHandler - * @return {Worker} - */ - createFromURL = function(url, messageHandler, errorHandler) { - if (url instanceof URL) { - url = url.toString(); - } - const workerClass = getGlobalFunction("Worker"); - var worker = new workerClass(validateString(url)); - if (isFunction(messageHandler)) { - worker.onmessage = (event) => { - messageHandler.call(worker, event); - }; - } - if (isFunction(errorHandler)) { - worker.onerror = (event) => { - errorHandler.call(worker, event); - }; - } - return worker; - }; - /** - * Creates a worker from a script - * - * @param {string} content - * @param {function} messageHandler - * @param {function} errorHandler - * @return {Worker} - * @see https://developer.mozilla.org/de/docs/Web/API/URL/createObjectURL - */ - createFromScript = function(content, messageHandler, errorHandler) { - const blobFunction = new getGlobalFunction("Blob"); - const blob = new blobFunction([validateString(content)], { - type: "script/javascript" - }); - const url = getGlobalFunction("URL").createObjectURL(blob); - const worker = this.createFromURL(url, messageHandler, errorHandler); - this[internalSymbol]["worker"].set(worker, url); - return worker; - }; - /** - * Terminate the worker and call revokeObjectURL if necessary. - * - * @param worker - * @return {Monster.DOM.Worker.Factory} - */ - terminate(worker) { - const workerClass = getGlobalFunction("Worker"); - validateInstance(worker, workerClass); - worker.terminate(); - if (this[internalSymbol]["worker"].has(worker)) { - const url = this[internalSymbol]["worker"].get(worker); - URL.revokeObjectURL(url); - } - return this; - } - }; - - // test/cases/dom/worker/factory.mjs - init_global(); - var global2 = getGlobal(); - describe("Worker", function() { - before(function(done) { - if (isNode()) { - Object.defineProperty(global2["URL"], "createObjectURL", { - writable: true, - value: () => { - return "/example.mjs"; - } - }); - global2["Worker"] = class { - terminate() { - } - onerror() { - } - onmessage() { - } - }; - let a2 = typeof global2["Worker"]; - let a1 = typeof Worker; - } - const jsdom = initJSDOM().then(() => { - done(); - }); - }); - describe("Factory", function() { - it("create worker", function() { - const factory = new Factory(); - const worker = factory.createFromScript('console.log("hello world");'); - expect(worker).is.instanceof(Worker); - expect(factory.terminate(worker)).is.instanceof(Factory); - }); - }); - }); - - // test/cases/dom/template.mjs - init_constants2(); - init_template(); - describe("Template", function() { - before(async function() { - initJSDOM(); - }); - beforeEach(() => { - let mocks = document.getElementById("mocks"); - mocks.innerHTML = ` - <template id="mytemplate"></template>`; - }); - afterEach(() => { - let mocks = document.getElementById("mocks"); - mocks.innerHTML = ""; - }); - describe("create HTMLFragment", function() { - [ - ["<div>first</div><div>second</div>"], - ["<div>first</div>"], - ["<div>first</div><p>second</p>"] - ].forEach(function(data) { - let a2 = data.shift(); - it("new Template().getNewDocumentFragmentAsString() should return string", function() { - let template = document.createElement("template"); - template.innerHTML = a2; - let t = new Template(template); - var container = document.createElement("div"); - container.appendChild(t.createDocumentFragment()); - expect(container.innerHTML).to.be.equal(a2); - }); - }); - }); - describe("create instance", function() { - it("new Template() should return document object", function() { - let d = new Template(document.createElement("template")); - expect(d).to.be.instanceOf(Template); - }); - }); - describe(".getTemplateElement()", function() { - it("new Template().getTemplateElement() should return HTMLTemplateElement object", function() { - let d = new Template(document.createElement("template")); - expect(d.getTemplateElement()).to.be.instanceOf(HTMLTemplateElement); - }); - }); - describe(".findDocumentTemplate()", function() { - it("should throw Template not found", function() { - const div = document.createElement("div"); - expect(() => { - findDocumentTemplate("noway", div); - }).to.throws(Error); - }); - }); - describe(".findDocumentTemplate()", function() { - describe("Template", function() { - it("should find template over ownerDocument", function() { - const div = document.createElement("div"); - div.remove(); - let t = findDocumentTemplate("mytemplate", div); - expect(t).is.instanceof(Template); - }); - }); - describe("Thmened Template", function() { - let memAttributeValue; - beforeEach(() => { - let mocks = document.getElementById("mocks"); - mocks.innerHTML = ` - <template id="mytemplate"><p>1</p></template> - <template id="mytemplate-monster"><p>2</p></template> - <template id="mytemplate-testtheme"><p>4</p></template> - <template id="myprefix-mytemplate-monster"><p>3</p></template> - `; - let html = document.querySelector("html"); - if (html.hasAttribute(ATTRIBUTE_THEME_NAME)) { - memAttributeValue = html.getAttribute(ATTRIBUTE_THEME_NAME); - } - }); - afterEach(() => { - let mocks = document.getElementById("mocks"); - mocks.innerHTML = ""; - let html = document.querySelector("html"); - if (html.hasAttribute(ATTRIBUTE_THEME_NAME)) { - html.removeAttribute(ATTRIBUTE_THEME_NAME); - } - if (memAttributeValue) { - html.setAttribute(ATTRIBUTE_THEME_NAME, memAttributeValue); - } - }); - it("should find template over ownerDocument", function() { - let html = document.querySelector("html"); - const div = document.createElement("div"); - div.setAttribute("data-monster-template-prefix", "myprefix"); - div.remove(); - let t1 = findDocumentTemplate("mytemplate", div); - expect(t1).is.instanceof(Template); - expect(t1.createDocumentFragment().textContent).is.equal("3"); - div.removeAttribute("data-monster-template-prefix"); - let t2 = findDocumentTemplate("mytemplate", div); - expect(t2).is.instanceof(Template); - expect(t2.createDocumentFragment().textContent).is.equal("2"); - html.setAttribute(ATTRIBUTE_THEME_NAME, "testtheme"); - let a2 = html.outerHTML; - let t3 = findDocumentTemplate("mytemplate", div); - expect(t3).is.instanceof(Template); - expect(t3.createDocumentFragment().textContent).is.equal("4"); - }); - }); - }); - }); - - // test/cases/dom/ready.mjs - var windowReady2; - var domReady2; - describe("Ready", function() { - before(function(done) { - initJSDOM().then(() => { - Promise.resolve().then(() => (init_ready(), ready_exports)).then((m) => { - domReady2 = m["domReady"]; - windowReady2 = m["windowReady"]; - done(); - }); - }); - }); - describe("domReady", function() { - it("resolve promise", function(done) { - domReady2.then(done).catch((e) => done(e)); - }); - }); - describe("windowReady", function() { - it("resolve promise", function(done) { - windowReady2.then(done).catch((e) => done(e)); - }); - }); - }); - - // ../application/source/dom/focusmanager.mjs - init_extend(); - init_basewithoptions(); - init_global(); - init_is(); - init_stack(); - init_validate(); - init_constants(); - var KEY_DOCUMENT2 = "document"; - var KEY_CONTEXT = "context"; - var stackSymbol = Symbol("stack"); - var FocusManager = class extends BaseWithOptions { - /** - * - * @param {Object|undefined} options - */ - constructor(options) { - super(options); - validateInstance(this.getOption(KEY_DOCUMENT2), HTMLDocument); - this[stackSymbol] = new Stack(); - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/dom/focusmanager"); - } - /** - * @property {HTMLDocument} document the document object into which the node is to be appended - */ - get defaults() { - return extend({}, super.defaults, { - [KEY_DOCUMENT2]: getGlobalObject("document"), - [KEY_CONTEXT]: void 0 - }); - } - /** - * Remembers the current focus on a stack. - * Several focus can be stored. - * - * @return {Monster.DOM.FocusManager} - */ - storeFocus() { - const active = this.getActive(); - if (active instanceof Node) { - this[stackSymbol].push(active); - } - return this; - } - /** - * The last focus on the stack is set again - * - * @return {Monster.DOM.FocusManager} - */ - restoreFocus() { - const last = this[stackSymbol].pop(); - if (last instanceof Node) { - this.focus(last); - } - return this; - } - /** - * - * @param {Node} element - * @param {boolean} preventScroll - * @throws {TypeError} value is not an instance of - * @return {Monster.DOM.FocusManager} - */ - focus(element, preventScroll) { - validateInstance(element, Node); - element.focus({ - preventScroll: preventScroll ?? false - }); - return this; - } - /** - * - * @return {Element} - */ - getActive() { - return this.getOption(KEY_DOCUMENT2).activeElement; - } - /** - * Select all elements that can be focused - * - * @param {string|undefined} query - * @return {array} - * @throws {TypeError} value is not an instance of - */ - getFocusable(query) { - let contextElement = this.getOption(KEY_CONTEXT); - if (contextElement === void 0) { - contextElement = this.getOption(KEY_DOCUMENT2); - } - validateInstance(contextElement, Node); - if (query !== void 0) { - validateString(query); - } - return [ - ...contextElement.querySelectorAll( - 'details, button, input, [tabindex]:not([tabindex="-1"]), select, textarea, a[href], body' - ) - ].filter((element) => { - if (query !== void 0 && !element.matches(query)) { - return false; - } - if (element.hasAttribute("disabled")) - return false; - if (element.getAttribute("aria-hidden") === "true") - return false; - const rect = element.getBoundingClientRect(); - if (rect.width === 0) - return false; - if (rect.height === 0) - return false; - return true; - }); - } - /** - * @param {string} query - * @return {Monster.DOM.FocusManager} - */ - focusNext(query) { - const current = this.getActive(); - const focusable = this.getFocusable(query); - if (!isArray(focusable) || focusable.length === 0) { - return this; - } - if (current instanceof Node) { - let index = focusable.indexOf(current); - if (index > -1) { - this.focus(focusable[index + 1] || focusable[0]); - } else { - this.focus(focusable[0]); - } - } else { - this.focus(focusable[0]); - } - return this; - } - /** - * @param {string} query - * @return {Monster.DOM.FocusManager} - */ - focusPrev(query) { - const current = this.getActive(); - const focusable = this.getFocusable(query); - if (!isArray(focusable) || focusable.length === 0) { - return this; - } - if (current instanceof Node) { - let index = focusable.indexOf(current); - if (index > -1) { - this.focus(focusable[index - 1] || focusable[focusable.length - 1]); - } else { - this.focus(focusable[focusable.length - 1]); - } - } else { - this.focus(focusable[focusable.length - 1]); - } - return this; - } - }; - - // test/cases/dom/focusmanager.mjs - describe("FocusManager", function() { - before(function(done) { - initJSDOM().then(() => { - done(); - }); - }); - beforeEach(() => { - initMutationObserverForTesting(); - }); - afterEach(() => { - cleanupDOMFromTesting(); - document.getElementById("mocks").innerHTML = ""; - }); - describe("new", function() { - it("should instance of FocusManager", function() { - expect(new FocusManager()).is.instanceof(FocusManager); - }); - }); - describe("store and restore", function() { - let manager; - beforeEach(() => { - manager = new FocusManager(); - document.getElementById("mocks").innerHTML = ` - <input class="testit" id="tx1"> - <input class="testit" id="tx2"> - <input class="testit" id="tx3" disabled> - <input class="testit" id="tx4"> - <p class="testit" tabindex="2" id="tx5">hello</p> - <input class="testit" id="tx6" aria-hidden="true"> - <button class="testit" id="tx7"></button> - `; - for (const [, element] of Object.entries(document.querySelectorAll(".testit"))) { - element.getBoundingClientRect = () => ({ - width: 200, - height: 200, - top: 0, - left: 0, - right: 200, - bottom: 200 - }); - } - }); - it("run ist", function() { - manager.focus(document.getElementById("tx1")); - manager.storeFocus(); - const e1 = manager.getActive(); - expect(e1.getAttribute("id"), "error1").to.be.equal("tx1"); - manager.focus(document.getElementById("tx2")); - manager.storeFocus(); - expect(manager.getActive().getAttribute("id"), "error2").to.be.equal("tx2"); - manager.focusNext(); - expect(manager.getActive().getAttribute("id"), "error3").to.be.equal("tx4"); - manager.focusNext(); - expect(manager.getActive().getAttribute("id"), "error4").to.be.equal("tx5"); - manager.restoreFocus(); - expect(manager.getActive().getAttribute("id"), "error5").to.be.equal("tx2"); - manager.restoreFocus(); - expect(manager.getActive().getAttribute("id"), "error6").to.be.equal("tx1"); - manager.restoreFocus(); - expect(manager.getActive().getAttribute("id"), "error7").to.be.equal("tx1"); - }); - }); - describe("returntype", function() { - let focusmanager; - beforeEach(() => { - focusmanager = new FocusManager(); - }); - it("check returns", function() { - expect(focusmanager.getFocusable()).is.instanceof(Array); - expect(focusmanager.getActive()).is.instanceof(HTMLElement); - expect(focusmanager.focusNext()).is.instanceof(FocusManager); - expect(focusmanager.focusPrev()).is.instanceof(FocusManager); - expect(focusmanager.storeFocus()).is.instanceof(FocusManager); - expect(focusmanager.focus(document.body)).is.instanceof(FocusManager); - expect(focusmanager.restoreFocus()).is.instanceof(FocusManager); - }); - }); - }); - - // ../application/source/dom/assembler.mjs - init_base(); - init_global(); - init_proxyobserver(); - init_validate(); - var ATTRIBUTEPREFIX = "data-monster-"; - var Assembler = class extends Base { - /** - * @param {DocumentFragment} fragment - * @throws {TypeError} value is not an instance of - * @throws {TypeError} value is not a function - * @throws {Error} the function is not defined - */ - constructor(fragment) { - super(); - this.attributePrefix = ATTRIBUTEPREFIX; - validateInstance(fragment, getGlobalFunction("DocumentFragment")); - this.fragment = fragment; - } - /** - * - * @param {string} prefix - * @returns {Assembler} - * @throws {TypeError} value is not a string - */ - setAttributePrefix(prefix) { - validateString(prefix); - this.attributePrefix = prefix; - return this; - } - /** - * - * @returns {string} - */ - getAttributePrefix() { - return this.attributePrefix; - } - /** - * - * @param {ProxyObserver|undefined} data - * @return {DocumentFragment} - * @throws {TypeError} value is not an instance of - */ - createDocumentFragment(data) { - if (data === void 0) { - data = new ProxyObserver({}); - } - validateInstance(data, ProxyObserver); - let fragment = this.fragment.cloneNode(true); - return fragment; - } - }; - - // test/cases/dom/assembler.mjs - describe("Assembler", function() { - before(async function() { - initJSDOM(); - }); - describe("createDocumentFragment()", function() { - it("should return <div>One</div><div>Two</div>", function() { - let fragment = document.createRange().createContextualFragment("<div>One</div><div>Two</div>"); - let f = new Assembler(fragment); - let container = document.createElement("div"); - container.appendChild(f.createDocumentFragment().cloneNode(true)); - expect(container.innerHTML).to.be.equal("<div>One</div><div>Two</div>"); - }); - }); - describe("createDocumentFragment()", function() { - it("should return DocumentFragment object", function() { - let d = new Assembler(document.createDocumentFragment()); - expect(d.createDocumentFragment()).to.be.instanceOf(DocumentFragment); - }); - }); - describe("new", function() { - it("new Renderer() should return Assembler object", function() { - let d = new Assembler(document.createDocumentFragment()); - expect(d).to.be.instanceOf(Assembler); - }); - }); - describe("getAttributePrefix()", function() { - it("should return " + ATTRIBUTEPREFIX, function() { - let d = new Assembler(document.createDocumentFragment()); - expect(d.getAttributePrefix()).to.be.equal(ATTRIBUTEPREFIX); - }); - }); - describe("setAttributePrefix().getAttributePrefix()", function() { - it("should return same value", function() { - let d = new Assembler(document.createDocumentFragment()); - expect(d.setAttributePrefix("test01").getAttributePrefix()).to.be.equal("test01"); - }); - }); - }); - - // test/cases/i18n/translations.mjs - init_locale(); - - // ../application/source/i18n/providers/embed.mjs - init_constants(); - init_extend(); - init_util(); - init_is(); - init_validate(); - init_locale(); - init_provider(); - init_translations(); - var Embed = class extends Provider { - /** - * ```html - * <script id="translations" type="application/json"> - * { - * "hello": "Hallo" - * } - * <\/script> - * ``` - * - * - * ```javascript - * new Embed('translations') - * ``` - * - * @param {HTMLElement|string} elementOrId - * @param {Object} options - */ - constructor(elementOrId, options) { - super(options); - if (options === void 0) { - options = {}; - } - if (elementOrId instanceof HTMLElement) { - this.translateElement = elementOrId; - } else { - this.translateElement = getDocument().getElementById(validateString(elementOrId)); - } - this[internalSymbol] = extend({}, super.defaults, this.defaults, validateObject(options)); - } - /** - * Defaults - * - * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API} - */ - get defaults() { - return extend({}, super.defaults); - } - /** - * - * @param {Locale|string} locale - * @return {Promise} - */ - getTranslations(locale) { - if (isString(locale)) { - locale = parseLocale(locale); - } - return new Promise((resolve, reject) => { - if (this.translateElement === null) { - reject(new Error("Text not found")); - return; - } - if (!(this.translateElement instanceof HTMLScriptElement)) { - reject(new Error("Element is not a script tag")); - return; - } - if (this.translateElement.type !== "application/json") { - reject(new Error("Element is not a script tag with type application/json")); - return; - } - let translations = null; - try { - translations = JSON.parse(this.translateElement.innerHTML.trim()); - } catch (e) { - reject(e); - return; - } - if (translations === null) { - reject(new Error("Translations not found or invalid")); - return; - } - const t = new Translations(locale); - t.assignTranslations(translations); - resolve(t); - }); - } - /** - * Initializes the translations for the current document. - * - * `script[data-monster-role=translations]` is searched for and the translations are assigned to the element. - * - * @param element - * @returns {Promise<unknown[]>} - */ - static assignTranslationsToElement(element) { - const d = getDocument(); - if (!(element instanceof HTMLElement)) { - element = d.querySelector("body"); - } - const list = d.querySelectorAll("script[data-monster-role=translations]"); - if (list === null) { - return; - } - const promises = []; - list.forEach((translationElement) => { - const p = new Embed(translationElement); - promises.push(p.assignToElement(void 0, element)); - }); - return Promise.all(promises); - } - }; - - // test/cases/i18n/translations.mjs - init_translations(); - describe("Translations", function() { - describe("Instance and Init", function() { - let translation; - beforeEach(() => { - translation = new Translations(parseLocale("en-GB")); - translation.assignTranslations({ - test1: "abc", - test2: { "other": "xyz" } - }); - }); - it("create instance", function() { - expect(new Translations(parseLocale("en-GB"))).is.instanceof(Translations); - }); - it("init translations", function() { - expect(translation.assignTranslations({ - test1: "abc", - test2: { "other": "xyz" } - })).is.instanceof(Translations); - }); - }); - describe("getText", function() { - let translation; - beforeEach(() => { - translation = new Translations(parseLocale("en-GB")); - translation.assignTranslations({ - test1: "abc", - test2: { "other": "xyz" } - }); - }); - it("create, set and get en-GB", function() { - expect(translation.getText("test1")).is.equal("abc"); - }); - it("create, set and get en-GB with pluralrules", function() { - expect(translation.getText("test2")).is.equal("xyz"); - }); - }); - describe("test initDocumentTranslation ", function() { - let html16 = `<div id="mock-translations"></div> - -<script type="application/json" data-monster-role="translations"> - { - "test1": "abc", - "test2": { - "other": "xyz" - } - } -<\/script> - -<script type="application/json" data-monster-role="translations"> - { - "test1": "xyz", - "test3": { - "other": "xyz" - } - } -<\/script> - -`; - beforeEach(() => { - let mocks = document.getElementById("mocks"); - mocks.innerHTML = html16; - }); - afterEach(() => { - let mocks = document.getElementById("mocks"); - mocks.innerHTML = ""; - }); - before(function(done) { - initJSDOM().then(() => { - done(); - }); - }); - it("Init translations", function(done) { - let elem = document.getElementById("mock-translations"); - Embed.assignTranslationsToElement(elem).then((o) => { - let mocks = document.getElementById("mocks"); - expect(getDocumentTranslations(elem).getText("no-key", "with-default")).is.equal("with-default"); - expect(getDocumentTranslations(elem).getText("test1")).is.equal("xyz"); - done(); - }).catch((e) => { - done(e); - }); - }); - }); - }); - - // test/cases/i18n/locale.mjs - init_locale(); - describe("Locale", function() { - describe("new instance", function() { - [ - // language, region, script, variants, extlang, privateUse - // https://www.rfc-editor.org/rfc/rfc5646.html - ["zh", void 0, "Hant", void 0, void 0, void 0, "zh-Hant"], - // zh-Hant (Chinese written using the Traditional Chinese script) - ["de", "CH", void 0, "1901", void 0, void 0, "de-CH-1901"], - // de-CH-1901 (German as used in Switzerland using the 1901 variant [orthography]) - ["sl", "IT", void 0, "nedis", void 0, void 0, "sl-IT-nedis"], - // sl-IT-nedis (Slovenian as used in Italy, Nadiza dialect) - ["hy", "IT", "Latn", "arevela", void 0, void 0, "hy-Latn-IT-arevela"], - // hy-Latn-IT-arevela (Eastern Armenian written in Latin script, as used in Italy) - ["zh", "CN", "Hans", void 0, void 0, void 0, "zh-Hans-CN"], - // zh-Hans-CN (Chinese written using the Simplified script as used in mainland China) - ["sr", "RS", "Latn", void 0, void 0, void 0, "sr-Latn-RS"] - // sr-Latn-RS (Serbian written using the Latin script as used in Serbia) - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - let c = data.shift(); - let d = data.shift(); - let e = data.shift(); - let f = data.shift(); - let g = data.shift(); - it("new Locale(" + a2 + "," + b + "," + c + "," + d + "," + e + "," + f + ") should return " + g, function() { - expect(new Locale(a2, b, c, d, e, f).toString()).is.equal(g); - }); - }); - }); - describe("parseLocale()", function() { - [ - // language, region, script, variants, extlang, privateUse - // https://www.rfc-editor.org/rfc/rfc5646.html - ["zh", void 0, "Hant", void 0, void 0, void 0, "zh-Hant"], - // zh-Hant (Chinese written using the Traditional Chinese script) - ["de", "CH", void 0, "1901", void 0, void 0, "de-CH-1901"], - // de-CH-1901 (German as used in Switzerland using the 1901 variant [orthography]) - ["sl", "IT", void 0, "nedis", void 0, void 0, "sl-IT-nedis"], - // sl-IT-nedis (Slovenian as used in Italy, Nadiza dialect) - ["hy", "IT", "Latn", "arevela", void 0, void 0, "hy-Latn-IT-arevela"], - // hy-Latn-IT-arevela (Eastern Armenian written in Latin script, as used in Italy) - ["zh", "CN", "Hans", void 0, void 0, void 0, "zh-Hans-CN"], - // zh-Hans-CN (Chinese written using the Simplified script as used in mainland China) - ["sr", "RS", "Latn", void 0, void 0, void 0, "sr-Latn-RS"] - // sr-Latn-RS (Serbian written using the Latin script as used in Serbia) - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - let c = data.shift(); - let d = data.shift(); - let e = data.shift(); - let f = data.shift(); - let g = data.shift(); - it("new Locale(" + a2 + "," + b + "," + c + "," + d + "," + e + "," + f + ") should return " + g, function() { - const locale = parseLocale(g); - expect(locale.localeString).to.be.equal(g); - expect(locale.language).to.be.equal(a2); - expect(locale.region).to.be.equal(b); - expect(locale.script).to.be.equal(c); - expect(locale.variants).to.be.equal(d); - expect(locale.extlang).to.be.equal(e); - expect(locale.privateUse).to.be.equal(f); - expect(new Locale(a2, b, c, d, e, f).toString()).is.equal(g); - }); - }); - }); - }); - - // ../application/source/i18n/formatter.mjs - init_constants(); - init_extend(); - init_formatter(); - init_validate(); - init_translations(); - var internalTranslationSymbol = Symbol("internalTranslation"); - var Formatter2 = class extends Formatter { - /** - * Default values for the markers are `${` and `}` - * - * @param {object} object - * @throws {TypeError} value is not a object - */ - constructor(object, translation, options) { - super(object, options); - this[internalTranslationSymbol] = validateInstance(translation, Translations); - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 3.27.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/i18n/formatter@@instance"); - } - /** - * @property {object} marker - * @property {array} marker.open=["i18n{","${"] - * @property {array} marker.close=["${"] - * @property {object} parameter - * @property {string} parameter.delimiter="::" - * @property {string} parameter.assignment="=" - * @property {object} callbacks - * @property {function} callbacks.i18n=()=>{} - */ - get defaults() { - const self2 = this; - return extend({}, super.defaults, { - callbacks: { - i18n: (value) => { - return self2[internalTranslationSymbol].getText(validateString(value)); - } - }, - marker: { - open: ["i18n{", "${"], - close: ["}"] - } - }); - } - /** - * - * @param {string} text - * @return {string} - * @throws {TypeError} value is not a string - * @throws {Error} too deep nesting - * @throws {Error} key not found - * @throws {Error} the closing marker is missing - */ - format(text) { - validateString(text); - const openMarker = this[internalSymbol]["marker"]["open"]?.[0]; - const closeMarker = this[internalSymbol]["marker"]["close"]?.[0]; - if (text.indexOf(openMarker) === 0) { - text = text.substring(openMarker.length); - if (text.indexOf(closeMarker) === text.length - closeMarker.length) { - text = text.substring(0, text.length - closeMarker.length); - } else { - throw new Error("the closing marker is missing"); - } - } - const parts = validateString(text).split("::"); - const translationKey = parts.shift().trim(); - const parameter = parts.join("::").trim(); - let assembledText = `${openMarker}static:${translationKey} | call:i18n`; - if (parameter.length > 0) { - assembledText += `::${parameter}`; - } - assembledText += closeMarker; - return super.format(assembledText); - } - }; - - // test/cases/i18n/formatter.mjs - init_translations(); - describe("Formatter", function() { - describe("example", function() { - it("should run with marker", function() { - const translations = new Translations("en").assignTranslations({ - thekey: "${animal} has eaten the ${food}!" - }); - const f = new Formatter2({}, translations); - expect(f.format("i18n{thekey::animal=dog::food=cake}")).to.be.equal("dog has eaten the cake!"); - }); - it("should run without marker", function() { - const translations = new Translations("en").assignTranslations({ - thekey: "${animal} has eaten the ${food}!" - }); - expect(new Formatter2({}, translations).format("thekey::animal=dog::food=cake")).to.be.equal("dog has eaten the cake!"); - }); - }); - describe("format", function() { - [ - ["i18n{translationkey::a=3::b=5}", "test is 3 and 5"] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - it("format " + a2 + " should " + b, function() { - const translations = new Translations("de").assignTranslations({ - translationkey: "test is ${a} and ${b}" - }); - expect( - new Formatter2({}, translations).format(a2) - ).to.equal(b); - }); - }); - }); - }); - - // test/cases/i18n/providers/embed.mjs - init_translations(); - init_global(); - var global3 = getGlobal(); - var html15 = ` -<script id="templocale" type="application/json"> -{ - "key": "translation" -} -<\/script> -`; - describe("Translation Provider Embed", function() { - before(function(done) { - initJSDOM().then(() => { - done(); - }); - }); - afterEach(() => { - let mocks = document.getElementById("mocks"); - mocks.innerHTML = ""; - }); - beforeEach(() => { - let mocks = document.getElementById("mocks"); - mocks.innerHTML = html15; - }); - describe("get mock data and create translation", function() { - it("embed", function(done) { - const e = new Embed("templocale"); - let p = e.getTranslations("en"); - expect(p).is.instanceof(Promise); - p.then((r) => { - try { - expect(r).is.instanceof(Translations); - let t = r.getText("key"); - expect(t).is.equal("translation"); - done(); - } catch (e2) { - done(e2); - } - }).catch((e2) => { - done(e2); - }); - }); - }); - }); - - // ../application/source/i18n/providers/fetch.mjs - init_constants(); - init_extend(); - init_formatter(); - init_global(); - init_is(); - init_validate(); - init_locale(); - init_provider(); - init_translations(); - var Fetch = class extends Provider { - /** - * As options the key `fetch` can be passed. This config object is passed to the fetch method as init. - * - * The url may contain placeholders (language, script, region, variants, extlang, privateUse), so you can specify one url for all translations. - * - * ``` - * new Fetch('https://www.example.com/assets/${language}.json') - * ``` - * - * @param {string|URL} url - * @param {Object} options see {@link Monster.I18n.Providers.Fetch#defaults} - * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/fetch} - */ - constructor(url, options) { - super(options); - if (isInstance(url, URL)) { - url = url.toString(); - } - if (options === void 0) { - options = {}; - } - validateString(url); - this.url = url; - this[internalSymbol] = extend({}, super.defaults, this.defaults, validateObject(options)); - } - /** - * Defaults - * - * @property {Object} fetch - * @property {String} fetch.method=GET - * @property {String} fetch.mode=cors - * @property {String} fetch.cache=no-cache - * @property {String} fetch.credentials=omit - * @property {String} fetch.redirect=follow - * @property {String} fetch.referrerPolicy=no-referrer - * - * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API} - */ - get defaults() { - return extend( - { - fetch: { - method: "GET", - // *GET, POST, PUT, DELETE, etc. - mode: "cors", - // no-cors, *cors, same-origin - cache: "no-cache", - // *default, no-cache, reload, force-cache, only-if-cached - credentials: "omit", - // include, *same-origin, omit - redirect: "follow", - // manual, *follow, error - referrerPolicy: "no-referrer" - // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url - } - }, - super.defaults - ); - } - /** - * - * @param {Locale|string} locale - * @return {Promise} - */ - getTranslations(locale) { - if (isString(locale)) { - locale = parseLocale(locale); - } - let formatter = new Formatter(locale.getMap()); - return getGlobalFunction("fetch")(formatter.format(this.url), this.getOption("fetch", {})).then((response) => response.json()).then((data) => { - return new Translations(locale).assignTranslations(data); - }); - } - }; - - // test/cases/i18n/providers/fetch.mjs - init_translations(); - init_global(); - var global4 = getGlobal(); - var fetchReference; - describe("Translation Provider Fetch", function() { - afterEach(() => { - global4["fetch"] = fetchReference; - }); - beforeEach(() => { - fetchReference = global4["fetch"]; - global4["fetch"] = function(url, options) { - return new Promise((resolve, reject) => { - resolve({ - json: function() { - return { - a: "test" - }; - } - }); - }); - }; - }); - describe("fetch mock data and create translation", function() { - it("fetch", function(done) { - let p = new Fetch(new URL("http://example.com")).getTranslations("en"); - expect(p).is.instanceof(Promise); - p.then((r) => { - try { - expect(r).is.instanceof(Translations); - done(); - } catch (e) { - done(e); - } - }).catch((e) => { - done(e); - }); - }); - }); - }); - - // test/cases/i18n/provider.mjs - init_constants2(); - init_attributes(); - init_provider(); - init_translations(); - describe("Provider", function() { - let html16 = ` - <div id="test1"> - </div> -`; - beforeEach(() => { - let mocks = document.getElementById("mocks"); - mocks.innerHTML = html16; - }); - afterEach(() => { - let mocks = document.getElementById("mocks"); - mocks.innerHTML = ""; - }); - before(function(done) { - initJSDOM().then(() => { - done(); - }); - }); - describe("Provider and Dom", function() { - const translationsLinkSymbol2 = Symbol.for("@schukai/monster/i18n/translations@@link"); - it("assignToElement", function(done) { - const element = document.getElementById("test1"); - const p = new Provider(); - const r = p.assignToElement(void 0, element); - r.then((e) => { - const s = element.getAttribute(ATTRIBUTE_OBJECTLINK); - if (s === null) { - done(new Error("Attribute not set")); - return; - } - const i = getLinkedObjects(element, translationsLinkSymbol2); - if (i === null) { - done(new Error("No linked object found")); - return; - } - let counter = 0; - for (let v of i) { - counter++; - } - if (counter !== 1) { - done(new Error("No linked object found")); - return; - } - const docTrans = getDocumentTranslations(element); - expect(docTrans).is.instanceof(Translations); - done(); - }).catch((e) => done(e)); - }); - }); - }); - - // ../application/source/net/webconnect/message.mjs - init_base(); - init_validate(); - var dataSymbol = Symbol("@@data"); - var Message = class extends Base { - /** - * @param {Object} data - * @throws {TypeError} value is not a object - */ - constructor(data) { - super(); - this[dataSymbol] = validateObject(data); - } - /** - * Returns the raw message. - * - * @returns {object} - */ - getData() { - return this[dataSymbol]; - } - /** - * @returns {*} - */ - toJSON() { - return this[dataSymbol]; - } - /** - * @param {string} json - * @returns {Message} - * @throws {TypeError} value is not a string - */ - static fromJSON(json) { - validateString(json); - return new Message(JSON.parse(json)); - } - }; - - // test/cases/net/webconnect/message.mjs - describe("Message", function() { - it("construct withouth parameters should throw", function(done) { - try { - new Message(); - done(new Error("should throw")); - } catch (e) { - done(); - return; - } - }); - it("from json should ", function(done) { - const json = { - "id": "123", - "type": "test", - "data": { - "test": "test" - } - }; - const message = Message.fromJSON(JSON.stringify(json)); - const data = message.getData(); - expect(data.id).to.equal(json.id); - expect(data.type).to.equal(json.type); - expect(data.data).to.deep.equal(json.data); - done(); - }); - it("to json should", function(done) { - const obj = { - "id": "123", - "type": "test", - "data": { - "test": "test" - } - }; - const message = new Message(obj); - const data = JSON.stringify(message); - expect(data).to.equal('{"id":"123","type":"test","data":{"test":"test"}}'); - done(); - }); - }); - - // ../application/source/net/webconnect.mjs - init_constants(); - init_is(); - init_basewithoptions(); - - // ../application/source/types/observablequeue.mjs - init_queue(); - init_constants(); - init_observerlist(); - var ObservableQueue = class extends Queue { - /** - * - */ - constructor() { - super(); - this[internalSymbol] = { - observers: new ObserverList() - }; - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/types/observablequeue"); - } - /** - * Add a new element to the end of the queue. - * - * @param {*} value - * @returns {Queue} - */ - add(value) { - super.add(value); - this.notifyObservers(); - return this; - } - /** - * remove all entries - * - * @returns {Queue} - */ - clear() { - super.clear(); - this.notifyObservers(); - return this; - } - /** - * Attach a new observer - * - * @param {Observer} observer - * @returns {ProxyObserver} - */ - attachObserver(observer) { - this[internalSymbol].observers.attach(observer); - return this; - } - /** - * Detach a observer - * - * @param {Observer} observer - * @returns {ProxyObserver} - */ - detachObserver(observer) { - this[internalSymbol].observers.detach(observer); - return this; - } - /** - * Notify all observer - * - * @returns {Promise} - */ - notifyObservers() { - return this[internalSymbol].observers.notify(this); - } - /** - * @param {Observer} observer - * @returns {boolean} - */ - containsObserver(observer) { - return this[internalSymbol].observers.contains(observer); - } - }; - - // ../application/source/net/webconnect.mjs - var receiveQueueSymbol = Symbol("receiveQueue"); - var sendQueueSymbol = Symbol("sendQueue"); - var connectionSymbol = Symbol("connection"); - var manualCloseSymbol = Symbol("manualClose"); - function connectServer(resolve, reject) { - const self2 = this; - const url = self2.getOption("url"); - if (!url) { - reject("No url defined for webconnect."); - return; - } - let promiseAllredyResolved = false; - let connectionTimeout = self2.getOption("connection.timeout"); - if (!isInteger(connectionTimeout) || connectionTimeout < 100) { - connectionTimeout = 5e3; - } - setTimeout(() => { - if (promiseAllredyResolved) { - return; - } - reject(new Error("Connection timeout")); - }, connectionTimeout); - let reconnectTimeout = self2.getOption("connection.reconnect.timeout"); - if (!isInteger(reconnectTimeout) || reconnectTimeout < 1e3) - reconnectTimeout = 1e3; - let reconnectAttempts = self2.getOption("connection.reconnect.attempts"); - if (!isInteger(reconnectAttempts) || reconnectAttempts < 1) - reconnectAttempts = 1; - let reconnectEnabled = self2.getOption("connection.reconnect.enabled"); - if (reconnectEnabled !== true) - reconnectEnabled = false; - self2[manualCloseSymbol] = false; - self2[connectionSymbol].reconnectCounter++; - if (self2[connectionSymbol].socket && self2[connectionSymbol].socket.readyState < 2) { - self2[connectionSymbol].socket.close(); - } - self2[connectionSymbol].socket = null; - self2[connectionSymbol].socket = new WebSocket(url); - self2[connectionSymbol].socket.onmessage = function(event) { - if (event.data instanceof Blob) { - const reader = new FileReader(); - reader.addEventListener("loadend", function() { - self2[receiveQueueSymbol].add(new Message(reader.result)); - }); - reader.readAsText(new Message(event.data)); - } else { - self2[receiveQueueSymbol].add(Message.fromJSON(event.data)); - } - }; - self2[connectionSymbol].socket.onopen = function() { - self2[connectionSymbol].reconnectCounter = 0; - if (typeof resolve === "function" && !promiseAllredyResolved) { - promiseAllredyResolved = true; - resolve(); - } - }; - self2[connectionSymbol].socket.close = function(event) { - if (self2[manualCloseSymbol]) { - self2[manualCloseSymbol] = false; - return; - } - if (reconnectEnabled && this[connectionSymbol].reconnectCounter < reconnectAttempts) { - setTimeout(() => { - self2.connect(); - }, reconnectTimeout * this[connectionSymbol].reconnectCounter); - } - }; - self2[connectionSymbol].socket.onerror = (error) => { - if (reconnectEnabled && self2[connectionSymbol].reconnectCounter < reconnectAttempts) { - setTimeout(() => { - self2.connect(); - }, reconnectTimeout * this[connectionSymbol].reconnectCounter); - } else { - if (typeof reject === "function" && !promiseAllredyResolved) { - promiseAllredyResolved = true; - reject(error); - } - } - }; - } - var WebConnect = class extends BaseWithOptions { - /** - * - * @param {Object} [options] options contains definitions for the webconnect. - */ - constructor(options) { - if (isString(options)) { - options = { url: options }; - } - super(options); - this[receiveQueueSymbol] = new ObservableQueue(); - this[sendQueueSymbol] = new ObservableQueue(); - this[connectionSymbol] = {}; - this[connectionSymbol].socket = null; - this[connectionSymbol].reconnectCounter = 0; - this[manualCloseSymbol] = false; - } - /** - * - * @returns {Promise} - */ - connect() { - const self2 = this; - return new Promise((resolve, reject) => { - connectServer.call(this, resolve, reject); - }); - } - /** - * @returns {boolean} - */ - isConnected() { - return this[connectionSymbol]?.socket?.readyState === 1; - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/net/webconnect"); - } - /** - * @property {string} url=undefined Defines the resource that you wish to fetch. - * @property {Object} connection - * @property {Object} connection.timeout=5000 Defines the timeout for the connection. - * @property {Number} connection.reconnect.timeout The timeout in milliseconds for the reconnect. - * @property {Number} connection.reconnect.attempts The maximum number of reconnects. - * @property {Bool} connection.reconnect.enabled If the reconnect is enabled. - */ - get defaults() { - return Object.assign({}, super.defaults, { - url: void 0, - connection: { - timeout: 5e3, - reconnect: { - timeout: 1e3, - attempts: 1, - enabled: false - } - } - }); - } - /** - * This method closes the connection. - * - * @param {Number} [code=1000] The close code. - * @param {String} [reason=""] The close reason. - * @returns {Promise} - * @see https://www.rfc-editor.org/rfc/rfc6455.html#section-7.4.1 - */ - close(statusCode, reason) { - if (!isInteger(statusCode) || statusCode < 1e3 || statusCode > 4999) { - statusCode = 1e3; - } - if (!isString(reason)) { - reason = ""; - } - return new Promise((resolve, reject) => { - try { - this[manualCloseSymbol] = true; - if (this[connectionSymbol].socket) { - this[connectionSymbol].socket.close(statusCode, reason); - } - } catch (error) { - reject(error); - } - resolve(); - }); - } - /** - * Polls the receive queue for new messages. - * - * @returns {Message} - */ - poll() { - return this[receiveQueueSymbol].poll(); - } - /** - * Are there any messages in the receive queue? - * - * @returns {boolean} - */ - dataReceived() { - return !this[receiveQueueSymbol].isEmpty(); - } - /** - * Get Message from the receive queue, but do not remove it. - * - * @returns {Object} - */ - peek() { - return this[receiveQueueSymbol].peek(); - } - /** - * Attach a new observer - * - * @param {Observer} observer - * @returns {ProxyObserver} - */ - attachObserver(observer) { - this[receiveQueueSymbol].attachObserver(observer); - return this; - } - /** - * Detach a observer - * - * @param {Observer} observer - * @returns {ProxyObserver} - */ - detachObserver(observer) { - this[receiveQueueSymbol].detachObserver(observer); - return this; - } - /** - * @param {Observer} observer - * @returns {boolean} - */ - containsObserver(observer) { - return this[receiveQueueSymbol].containsObserver(observer); - } - /** - * @param {Message|Object} message - * @return {Promise} - */ - send(message) { - const self2 = this; - return new Promise((resolve, reject) => { - if (self2[connectionSymbol].socket.readyState !== 1) { - reject("the socket is not ready"); - } - self2[connectionSymbol].socket.send(JSON.stringify(message)); - resolve(); - }); - } - }; - - // test/cases/net/webconnect.mjs - init_observer(); - - // test/util/websocket.mjs - init_global(); - function initWebSocket() { - if (typeof window === "object" && window["WebSocket"]) - return Promise.resolve(); - return import("ws").then((ws) => { - getGlobal().WebSocket = class extends ws["WebSocket"] { - constructor(url, protocols) { - super(url, protocols, { - handshakeTimeout: 1e3, - maxPayload: 1024 * 1024 * 1024 - }); - } - }; - }); - } - - // test/cases/net/webconnect.mjs - var testUrl = "wss://ws.postman-echo.com/raw"; - describe("Websocket", function() { - let ds = void 0; - before(function(done) { - initWebSocket().then(() => { - done(); - }).catch((e) => { - done(e); - }); - }); - afterEach(function(done) { - if (ds) { - ds.close(); - } - for (const sym of Object.getOwnPropertySymbols(ds)) { - if (sym.toString() === "Symbol(connection)") { - if (typeof ds[sym]?.socket?.terminate === "function") { - ds[sym]?.socket?.["terminate"](); - } - } - } - done(); - }); - it("should transform data", function(done) { - ds = new WebConnect({ - url: testUrl - }); - ds.connect().then(() => { - ds.attachObserver(new Observer(() => { - done(); - })); - ds.send({ - data: { - message: "Hello World" - } - }); - }).catch((e) => { - done(e); - }); - }); - it("should connect", function(done) { - ds = new WebConnect({ - url: testUrl, - reconnect: { - enabled: false - } - }); - ds.connect().then(() => { - done(); - }).catch((e) => { - done(e); - }); - }); - it("should send message", function(done) { - ds = new WebConnect({ - url: testUrl, - reconnect: { - enabled: false - } - }); - ds.connect().then(() => { - ds.attachObserver(new Observer(() => { - expect(ds.dataReceived()).to.be.true; - try { - const msg = ds.poll(); - expect(msg).to.be.instanceOf(Message); - const data = msg.getData(); - expect(data).to.be.deep.equal({ message: "Hello World" }); - } catch (e) { - done(e); - return; - } - done(); - })); - ds.send({ - message: "Hello World" - }); - }).catch((e) => { - done(e); - }); - }).timeout(1e4); - }); - - // test/cases/types/mediatype.mjs - init_mediatype(); - describe("Dataurl", function() { - [ - ["*/*", "*", "*"], - ["text/*", "text", "*"], - ["*/test", "*", "test"], - ["image/png", "image", "png"], - ["audio/mp3", "audio", "mp3"], - ["video/mpeg", "video", "mpeg"], - ["text/plain", "text", "plain"], - ["text/html", "text", "html"], - ["text/html;charset=US-ASCII", "text", "html"], - ['text/html;charset="US-ASCII"', "text", "html"] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - let c = data.shift(); - it("parseMediaType(" + a2 + ")", function() { - const d = parseMediaType(a2); - expect(d).is.instanceof(MediaType); - expect(d.toString()).to.be.equal(a2); - expect(d.type).to.be.equal(b); - expect(d.subtype).to.be.equal(c); - expect(d.parameter).is.instanceof(Map); - }); - }); - [ - ["video/"], - ["text"], - ["/mp3"], - ["text/html;charsetUS-ASCII"], - ['text/html;charset"US-ASCII"'] - ].forEach(function(data) { - let a2 = data.shift(); - it("" + a2 + " should throw exception", function() { - expect(() => { - parseMediaType(a2); - }).throw(TypeError); - }); - }); - }); - - // test/cases/types/typeof.mjs - init_stack(); - init_typeof(); - describe("typeOf", function() { - describe(".typeOf()", function() { - [ - [true, "boolean"], - [null, "null"], - [void 0, "undefined"], - [Promise.resolve(), "promise"], - [/* @__PURE__ */ new WeakMap(), "weakmap"], - [/* @__PURE__ */ new Map(), "map"], - [NaN, "number"], - [function* () { - }, "generatorfunction"], - [5, "number"], - [function() { - }, "function"], - [/a/, "regexp"], - [/* @__PURE__ */ new Date(), "date"], - [{}, "object"], - [[], "array"], - ["", "string"], - [new Error(), "error"], - [new Stack(), "stack"] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - it("should return " + b + " when the value " + typeOf(a2), function() { - expect(typeOf(a2)).to.be.equal(b); - }); - }); - }); - }); - - // test/cases/types/observerlist.mjs - init_observerlist(); - init_observer(); - describe("ObserverList", function() { - describe(".attach()", function() { - it("should return instanceof ObserverList", function() { - let observerList = new ObserverList(); - let result = observerList.attach(new Observer(() => { - })); - expect(result).to.be.instanceOf(ObserverList); - }); - }); - describe(".detach()", function() { - it("should return instanceof ObserverList", function() { - let observerList = new ObserverList(); - let result = observerList.detach(new Observer(() => { - })); - expect(result).to.be.instanceOf(ObserverList); - }); - }); - describe(".notify()", function() { - const resultValue = "Yes!"; - let o; - let observerList; - beforeEach(() => { - o = new Observer(() => { - return resultValue; - }); - observerList = new ObserverList(); - observerList.attach(o); - }); - it("should instanceof Promise", function() { - expect(observerList.notify({})).to.be.instanceOf(Promise); - }); - it("should return " + resultValue, function(done) { - let obj = {}; - observerList.notify(obj).then((r) => { - expect(r).to.be.an("array").that.includes(resultValue); - done(); - }).catch((e) => { - done(new Error(e)); - }); - }); - }); - describe(".contains()", function() { - let o1 = new Observer(() => { - }); - let o2 = new Observer(() => { - }); - it("should not contain o1 and o2", function() { - let observerList = new ObserverList(); - expect(observerList.contains(o1)).to.be.false; - expect(observerList.contains(o2)).to.be.false; - }); - it("should contain o2 and not o1", function() { - let observerList = new ObserverList(); - observerList.attach(o2); - expect(observerList.contains(o1)).to.be.false; - expect(observerList.contains(o2)).to.be.true; - }); - it("should contain o1 and not o2", function() { - let observerList = new ObserverList(); - observerList.attach(o1); - expect(observerList.contains(o1)).to.be.true; - expect(observerList.contains(o2)).to.be.false; - }); - it("should contain o2 and o1", function() { - let observerList = new ObserverList(); - observerList.attach(o2).attach(o1); - expect(observerList.contains(o1)).to.be.true; - expect(observerList.contains(o2)).to.be.true; - }); - }); - }); - - // test/cases/types/randomid.mjs - describe("RandomID", function() { - class RandomID2 { - } - before(function(done) { - let promises = []; - if (!globalThis["crypto"]) { - promises.push(Promise.resolve().then(() => (init_webcrypto_es(), webcrypto_es_exports)).then((m) => { - globalThis["crypto"] = new m.Crypto(); - return true; - })); - } - promises.push(Promise.resolve().then(() => (init_randomid(), randomid_exports)).then((m) => { - RandomID2 = m.RandomID; - return true; - })); - Promise.all(promises).then(() => { - done(); - }); - }); - describe(".toString()", function() { - let id = new RandomID2(); - let result = id.toString(); - it("should return a string", function() { - expect(result).is.a("string"); - }); - }); - }); - - // test/cases/types/observablequeue.mjs - init_observer(); - describe("ObservableQueue", function() { - describe("Observer", function() { - it("should notify", function(done) { - let queue = new ObservableQueue(); - let o = new Observer((q) => { - done(); - }); - queue.attachObserver(o); - expect(queue.add("a")).to.be.instanceOf(ObservableQueue); - }); - }); - }); - - // test/cases/types/uuid.mjs - describe("UUID", function() { - class UUID2 { - } - before(function(done) { - let promises = []; - if (!globalThis["crypto"]) { - promises.push(Promise.resolve().then(() => (init_webcrypto_es(), webcrypto_es_exports)).then((m) => { - globalThis["crypto"] = new m.Crypto(); - return true; - })); - } - promises.push(Promise.resolve().then(() => (init_uuid(), uuid_exports)).then((m) => { - UUID2 = m.UUID; - return true; - })); - Promise.all(promises).then(() => { - done(); - }); - }); - describe(".toString()", function() { - it("should return a string", function() { - let uuid = new UUID2(); - let result = uuid.toString(); - expect(result).is.a("string"); - expect(result.length).is.equal(36); - }); - it("test format", function(done) { - let uuid = new UUID2(); - let result = uuid.toString(); - const regexExp = /^[A-F\d]{8}-[A-F\d]{4}-4[A-F\d]{3}-[89AB][A-F\d]{3}-[A-F\d]{12}$/i; - for (let i = 0; i < 2e3; i++) { - const u = new UUID2().toString(); - const r = regexExp.test(u); - if (r !== true) { - done("no uuid " + u + " => " + r); - return; - } - } - done(); - }); - }); - }); - - // test/cases/types/observer.mjs - init_observer(); - describe("Observer", function() { - let callback = function() { - }; - let observer = new Observer(callback); - describe(".addTag()", function() { - [ - ["test1"], - ["test2"] - ].forEach(function(data) { - let a2 = data.shift(); - it("addTag(" + a2 + ") should return instanceof Observer", function() { - expect(observer.addTag(a2)).is.instanceOf(Observer); - }); - }); - }); - describe(".removeTag()", function() { - [ - ["test1"], - ["test2"] - ].forEach(function(data) { - let a2 = data.shift(); - it("removeTag(" + a2 + ") should return instanceof Observer", function() { - expect(observer.removeTag(a2)).is.instanceOf(Observer); - }); - }); - }); - describe(".hasTag()", function() { - [ - ["test1", true], - ["test2", true], - ["test3", false], - ["test4", false] - ].forEach(function(data) { - let tempObserver = new Observer(callback); - let a2 = data.shift(); - let b = data.shift(); - it("observer.hastTag(" + a2 + ") should return " + b, function() { - if (b === true) { - tempObserver.addTag(a2); - expect(tempObserver.hasTag(a2)).is.be.true; - } else { - expect(tempObserver.hasTag(a2)).is.be.false; - } - }); - }); - }); - describe(".update()", function() { - let obj = {}; - it("observer.update(" + obj + ") is 136", function(done) { - let tempObserver = new Observer(function(a2, b, c) { - return a2 + b + c; - }, 1, 3, 6); - tempObserver.update(obj).then((a2) => { - expect(a2).is.equal(1 + 3 + 6); - done(); - }); - }); - }); - describe("run function .update() several times", function() { - let obj = {}; - it("observer.update(" + obj + ") is 136", function(done) { - let counter = 0; - let tempObserver = new Observer(function(a2, b, c) { - counter++; - }); - tempObserver.update(obj); - tempObserver.update(obj); - tempObserver.update(obj); - tempObserver.update(obj); - tempObserver.update(obj).then((_) => { - done(); - }); - }); - }); - describe(".getTags()", function() { - [ - [["test1", "test2", "test3", "test4"], 4], - [["test1", "test1", "test3", "test4"], 3], - // double test1 (set is uniqueue) - [["test1", "test1", "test1", "test4"], 2] - // multiple test1 (set is uniqueue) - ].forEach(function(data) { - let tempObserver = new Observer(callback); - let a2 = data.shift(); - let b = data.shift(); - for (let i = 0, max = a2.length; i < max; i++) { - tempObserver.addTag(a2[i]); - } - it("observer.getTags(" + a2 + ") is array", function() { - expect(tempObserver.getTags()).to.be.an("array"); - }); - it("observer.getTags(" + a2 + ") should return " + b + " tags", function() { - expect(tempObserver.getTags().length).is.equal(b); - }); - }); - }); - }); - - // test/cases/types/internal.mjs - init_observer(); - var SomeRandomClass1 = class extends Object { - doit() { - return "done"; - } - }; - var SomeRandomClass2 = class extends Object { - constructor() { - super(); - equipWithInternal.call(this); - } - get defaultInternal() { - return { - test: "test" - }; - } - }; - describe("Base inject with options", function() { - describe("new SomeRandomClass", function() { - it("is instance of SomeRandomClass1", function() { - expect(new SomeRandomClass2()).not.to.be.instanceOf(SomeRandomClass1); - expect(new SomeRandomClass2()).to.be.instanceOf(SomeRandomClass2); - }); - it("is instance of SomeRandomClass2", function() { - expect(new SomeRandomClass1()).to.be.instanceOf(SomeRandomClass1); - expect(new SomeRandomClass1()).not.to.be.instanceOf(SomeRandomClass2); - }); - }); - describe("Extends SomeRandomClass with internals", function() { - it("attach and notify internal observer", function(done) { - const c = new SomeRandomClass2(); - c.attachInternalObserver(new Observer(() => { - done(); - })); - c.setInternal("test", "test"); - }); - it("attach and remove internal observer", function() { - const c = new SomeRandomClass2(); - const observer = new Observer(() => { - }); - expect(c.containsInternalObserver(observer)).to.be.false; - c.attachInternalObserver(observer); - expect(c.containsInternalObserver(observer)).to.be.true; - c.detachInternalObserver(observer); - expect(c.containsInternalObserver(observer)).to.be.false; - }); - it("getInternal and setInternal", function() { - const c = new SomeRandomClass2(); - expect(c.setInternal("test", "yeah")).to.be.instanceOf(SomeRandomClass2); - expect(c.getInternal("test")).to.be.equal("yeah"); - }); - it("deal with default values", function() { - const testClass = class extends Object { - constructor() { - super(); - equipWithInternal.call(this); - } - get internalDefaults() { - return { - test: "xyz" - }; - } - }; - const c = new testClass(); - expect(c.getInternal("test")).to.be.equal("xyz"); - expect(c.getInternal("test2", "abc")).to.be.equal("abc"); - }); - it("deal with defaults from defaults", function() { - const testClass = class extends Object { - constructor() { - super(); - equipWithInternal.call(this); - } - get internalDefaults() { - return { - test: "xyz" - }; - } - }; - const testClass2 = class extends testClass { - constructor() { - super(); - equipWithInternal.call(this); - } - get internalDefaults() { - return Object.assign({}, super.internalDefaults, { - test2: "abc" - }); - } - }; - const c = new testClass2(); - expect(c.getInternal("test")).to.be.equal("xyz"); - expect(c.getInternal("test2")).to.be.equal("abc"); - }); - it("set multiple values", function() { - const c = new SomeRandomClass2(); - expect(c.setInternals({ - test: "yeah", - test2: "yeah2" - })).to.be.instanceOf(SomeRandomClass2); - expect(c.getInternal("test")).to.be.equal("yeah"); - expect(c.getInternal("test2")).to.be.equal("yeah2"); - c.setInternals({ - test2: "yeah2-new", - test3: "yeah3" - }); - expect(c.getInternal("test")).to.be.equal("yeah"); - expect(c.getInternal("test2")).to.be.equal("yeah2-new"); - expect(c.getInternal("test3")).to.be.equal("yeah3"); - }); - }); - }); - - // test/cases/types/tokenlist.mjs - init_tokenlist(); - describe("TokenList", function() { - describe(".toString()", function() { - let tokenList = new TokenList(); - let result = tokenList.toString(); - it("should return a string", function() { - expect(result).to.be.a("string"); - }); - it("set and remove return a string", function() { - expect(result).to.be.a("string"); - }); - }); - describe("init with string iterable", function() { - it("new TokenList(" + typeof a + ") throw TypeError ", function() { - let tokens = ["abc", "def", "ghi"]; - let list = new TokenList(tokens); - expect(list.toString()).is.equal("abc def ghi"); - }); - }); - describe("init with iterable without string values", function() { - it("new TokenList(" + typeof a + ") throw TypeError ", function() { - let tokens = ["abc", 4, "ghi"]; - expect(() => new TokenList(tokens)).to.throw(TypeError); - }); - }); - describe("init values", function() { - [ - // current, expected, typerror - ["test1", "test1", false], - ["test1 test2", "test1 test2", false], - [void 0, "", false], - [null, void 0, true], - [parseInt("a"), void 0, true], - // NaN - [() => { - }, void 0, true], - [2, void 0, true], - [false, void 0, true], - [true, void 0, true], - [4.5, void 0, true], - [{}, void 0, true], - [["1", "2", "3"], "1 2 3", false], - // iterable strings - [[1, 2, 3], void 0, true], - [Symbol("foo"), false, true] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - let c = data.shift(); - if (c === true) { - it("new TokenList(" + typeof a2 + ") throw TypeError ", function() { - expect(() => new TokenList(a2)).to.throw(TypeError); - }); - } else { - it("new TokenList(" + typeof a2 + ") should return " + b, function() { - expect(new TokenList(a2).toString()).is.equal(b); - }); - } - }); - }); - describe("iterator protocol", function() { - let list; - it(".add(second) should return TokenList", function() { - list = new TokenList("start"); - expect(list.getIterator()).to.be.an("object"); - }); - it(".add(second) should return TokenList", function() { - list = new TokenList("start end"); - expect([...list]).to.be.an("array"); - expect([...list]).to.be.an("array").to.include("start").to.include("end"); - }); - }); - describe(".entries()", function() { - let list; - it(".entries() should return Array", function() { - list = new TokenList("start"); - expect(list.entries()).to.be.an("array"); - }); - it(".entries() should return Array", function() { - list = new TokenList("start end").entries(); - expect(list).to.be.an("array").to.include("start").to.include("end"); - }); - }); - describe(".forEach()", function() { - let list; - it(".forEach() should iterate over tokenlist", function() { - list = new TokenList("aaa bbb ccc ddd eee fff"); - let result = ""; - list.forEach((a2) => { - result += "!" + a2 + "!"; - expect(a2).to.be.an("string"); - }); - expect(result).is.equal("!aaa!!bbb!!ccc!!ddd!!eee!!fff!"); - }); - it(".entries() should return Array", function() { - list = new TokenList("start end").entries(); - expect(list).to.be.an("array").to.include("start").to.include("end"); - }); - }); - describe("contains values", function() { - let list; - it("new TokenList(start, middle end) should contain middle", function() { - list = new TokenList("start middle end"); - expect(list.contains("start")).to.be.true; - expect(list.contains("middle")).to.be.true; - expect(list.contains("end")).to.be.true; - expect(list.contains(["end", "start", "middle"])).to.be.true; - }); - it("new TokenList(start, middle end) should not contain xyz", function() { - list = new TokenList("start middle end"); - expect(list.contains("xyz")).to.be.false; - expect(list.contains(["end", "start", "middle", "xyz"])).to.be.false; - }); - it("new TokenList(start, middle end) should not contain undefined null NaN", function() { - list = new TokenList("start middle end"); - expect(list.contains(void 0)).to.be.false; - expect(list.contains(parseInt("a"))).to.be.false; - expect(list.contains(null)).to.be.false; - }); - }); - describe("toggle values", function() { - let list; - it("new TokenList(start middle end).toggle(new-value) should contain new-value", function() { - list = new TokenList("start middle end"); - expect(list.toggle("new-value").toString()).is.equal("start middle end new-value"); - }); - it("new TokenList(start middle end).toggle(middle) should not contain middle", function() { - list = new TokenList("start middle end"); - expect(list.toggle("middle").toString()).is.equal("start end"); - }); - it("new TokenList().toggle() should ...", function() { - expect(new TokenList("abc def ghi").toggle("def xyz").toString()).to.equal("abc ghi xyz"); - }); - it("new TokenList().toggle() should ...", function() { - expect(new TokenList("abc def ghi").toggle(["abc", "xyz"]).toString()).to.equal("def ghi xyz"); - }); - it("new TokenList().toggle() should ...", function() { - expect(new TokenList("abc def ghi").toggle(void 0).toString()).to.equal("abc def ghi"); - }); - }); - describe("manipulate values", function() { - let list; - it('result TokenList("start") should be "start"', function() { - list = new TokenList("start"); - expect(list.toString()).is.equal("start"); - }); - it(".add(second) should return TokenList", function() { - list = new TokenList("start"); - expect(list.add("second")).to.be.an.instanceof(TokenList); - }); - it('.add(second).toString() should return "start second" ', function() { - list = new TokenList("start"); - expect(list.add("second").toString()).is.equal("start second"); - }); - it('.add(second third).toString() should return "start second third" ', function() { - list = new TokenList("start"); - expect(list.add("second third").toString()).is.equal("start second third"); - }); - it('.add([second,third]).toString() should return "start second third" ', function() { - list = new TokenList("start"); - expect(list.add(["second", "third"]).toString()).is.equal("start second third"); - }); - it('.clear().toString() should "" ', function() { - list = new TokenList("start"); - expect(list.add(["second", "third"]).clear().toString()).is.equal(""); - }); - it('new TokenList("start second third end").remove(second) should return TokenList', function() { - list = new TokenList("start second third end"); - expect(list.remove("second")).to.be.an.instanceof(TokenList); - }); - it('new TokenList("start second third end").remove(second).toString() should return "start third end" ', function() { - list = new TokenList("start second third end"); - expect(list.remove("second").toString()).is.equal("start third end"); - }); - it('new TokenList("start second third end").remove(second third).toString() should return "start end" ', function() { - list = new TokenList("start second third end"); - expect(list.remove("second third").toString()).is.equal("start end"); - }); - it('new TokenList("start second third end").remove([second,third]).toString() should return "start end" ', function() { - list = new TokenList("start second third end"); - expect(list.remove(["second", "third"]).toString()).is.equal("start end"); - }); - it('new TokenList("start second third end").replace(second, xyz).toString() should return "start xyz third end" ', function() { - list = new TokenList("start second third end"); - expect(list.replace("second", "xyz")).to.be.instanceOf(TokenList); - expect(list.toString()).is.equal("start xyz third end"); - }); - it('new TokenList("start second third end").replace(end, xyz).toString() should return "start second third xyz" ', function() { - list = new TokenList("start second third end"); - expect(list.replace("end", "xyz")).to.be.instanceOf(TokenList); - expect(list.toString()).is.equal("start second third xyz"); - }); - }); - }); - - // test/cases/types/queue.mjs - init_queue(); - describe("Queue", function() { - let queue; - beforeEach(() => { - queue = new Queue(); - }); - describe("isEmpty()", function() { - it("first it should empty", function() { - expect(queue.isEmpty()).to.be.true; - }); - }); - describe("add sequence peek and poll", function() { - it("result a,a,a,b", function() { - expect(queue.add("a")).to.be.instanceOf(Queue); - expect(queue.isEmpty()).to.be.false; - expect(queue.add("b")).to.be.instanceOf(Queue); - expect(queue.add("c")).to.be.instanceOf(Queue); - expect(queue.peek()).to.be.equal("a"); - expect(queue.peek()).to.be.equal("a"); - expect(queue.poll()).to.be.equal("a"); - expect(queue.peek()).to.be.equal("b"); - expect(queue.isEmpty()).to.be.false; - }); - }); - describe("add and clear", function() { - it("should empty", function() { - expect(queue.isEmpty()).to.be.true; - expect(queue.add("a")).to.be.instanceOf(Queue); - expect(queue.isEmpty()).to.be.false; - expect(queue.clear()).to.be.instanceOf(Queue); - expect(queue.isEmpty()).to.be.true; - }); - }); - }); - - // test/cases/types/stack.mjs - init_stack(); - describe("Stack", function() { - let stack; - beforeEach(() => { - stack = new Stack(); - }); - describe("isEmpty()", function() { - it("first it should empty", function() { - expect(stack.isEmpty()).to.be.true; - }); - }); - describe("add sequence peek and pull", function() { - it("result a,a,a,b", function() { - expect(stack.push("a")).to.be.instanceOf(Stack); - expect(stack.isEmpty()).to.be.false; - expect(stack.push("b")).to.be.instanceOf(Stack); - expect(stack.push("c")).to.be.instanceOf(Stack); - expect(stack.peek()).to.be.equal("c"); - expect(stack.peek()).to.be.equal("c"); - expect(stack.pop()).to.be.equal("c"); - expect(stack.peek()).to.be.equal("b"); - expect(stack.isEmpty()).to.be.false; - }); - }); - describe("add and clear", function() { - it("should empty", function() { - expect(stack.isEmpty()).to.be.true; - expect(stack.push("a")).to.be.instanceOf(Stack); - expect(stack.isEmpty()).to.be.false; - expect(stack.clear()).to.be.instanceOf(Stack); - expect(stack.isEmpty()).to.be.true; - }); - }); - }); - - // ../application/source/types/binary.mjs - init_validate(); - function toBinary(string) { - const codeUnits = new Uint16Array(validateString(string).length); - for (let i = 0; i < codeUnits.length; i++) { - codeUnits[i] = string.charCodeAt(i); - } - const charCodes = new Uint8Array(codeUnits.buffer); - let result = ""; - for (let i = 0; i < charCodes.byteLength; i++) { - result += String.fromCharCode(charCodes[i]); - } - return result; - } - function fromBinary(binary) { - const bytes = new Uint8Array(validateString(binary).length); - for (let i = 0; i < bytes.length; i++) { - bytes[i] = binary.charCodeAt(i); - } - const charCodes = new Uint16Array(bytes.buffer); - let result = ""; - for (let i = 0; i < charCodes.length; i++) { - result += String.fromCharCode(charCodes[i]); - } - return result; - } - - // test/cases/types/binary.mjs - describe("Binary", function() { - [ - ["a", "a\0"], - ["\u2639", "9&"], - ["I\xF1t\xEBrn\xE2ti\xF4n\xE0liz\xE6ti\xF8n", "I\0\xF1\0t\0\xEB\0r\0n\0\xE2\0t\0i\0\xF4\0n\0\xE0\0l\0i\0z\0\xE6\0t\0i\0\xF8\0n\0"] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - it("fromBinary(toBinary(" + a2 + ")) should work", function() { - let r = toBinary(a2); - expect(r).to.be.equal(b); - expect(fromBinary(r)).to.be.equal(a2); - }); - }); - }); - - // test/cases/types/basewithoptions.mjs - init_basewithoptions(); - describe("BaseWithOptions", function() { - describe("new BaseWithOptions", function() { - it("is instance of BaseWithOptions", function() { - expect(new BaseWithOptions()).to.be.instanceOf(BaseWithOptions); - }); - it("is instance of Object", function() { - expect(new BaseWithOptions()).to.be.instanceOf(Object); - }); - it("get option is true", function() { - expect(new BaseWithOptions({ a: true }).getOption("a")).to.be.true; - }); - }); - }); - - // ../application/source/types/regex.mjs - init_validate(); - function escapeString(value) { - return validateString(value).replace(/[|\\{}()[\]^$+*?.]/g, "\\$&").replace(/-/g, "\\x2d"); - } - - // test/cases/types/regex.mjs - describe("escapeString", function() { - before(function(done) { - let promises = []; - promises.push(initJSDOM()); - if (!globalThis["crypto"]) { - promises.push(Promise.resolve().then(() => (init_webcrypto_es(), webcrypto_es_exports)).then((m) => { - globalThis["crypto"] = new m.Crypto(); - return true; - })); - } - Promise.all(promises).then(() => { - done(); - }); - }); - [ - ["test1", "test1"], - ["${", "\\$\\{"], - ["i18n{", "i18n\\{"], - ["//", "//"], - ["\\", "\\\\"] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - it("escapeString(" + a2 + ") should return " + b, function() { - expect(escapeString(a2)).is.equal(b); - }); - }); - }); - - // test/cases/types/proxyobserver.mjs - init_extend(); - init_is(); - init_observer(); - init_proxyobserver(); - describe("ProxyObserver", function() { - describe("create", function() { - it("should return instanceof ProxyObserver", function() { - let o = new ProxyObserver({}); - extend(o.getSubject(), { a: 4 }); - expect(o.getRealSubject()).is.eql({ a: 4 }); - }); - }); - describe("setSubject", function() { - it("should run observer", function(done) { - let o = new ProxyObserver({ a: 1 }); - expect(o.getRealSubject()).is.eql({ a: 1 }); - let counter = 0; - o.attachObserver(new Observer(function() { - if (isObject(this) && this instanceof ProxyObserver) { - counter++; - if (counter === 1) { - done(); - return; - } - done("called for error"); - return; - } - done(new Error("this is not ProxyObserver")); - })); - o.getSubject().c = 4; - expect(o.getRealSubject()).is.eql({ a: 1, c: 4 }); - o.setSubject({ b: 2 }); - expect(o.getRealSubject()).is.eql({ b: 2 }); - o.getSubject().d = 5; - expect(o.getRealSubject()).is.eql({ b: 2, d: 5 }); - }); - }); - describe("create", function() { - it("should return instanceof ProxyObserver", function() { - let o = new ProxyObserver({}); - expect(o).is.instanceOf(ProxyObserver); - }); - }); - describe("proxy objects", function() { - it("Proxy objects should not be recommitted", function() { - let o = new ProxyObserver({ a: { b: true } }); - o.getSubject().a.b = o.getSubject(); - o.getSubject().a.b.a.b = false; - }); - }); - describe("notify observer", function() { - it("should inform observer", function(done) { - let counter = 0; - let o = new Observer(function(a2) { - if (isObject(this) && this instanceof ProxyObserver) { - counter++; - if (counter === 1) { - done(); - } - return; - } - done(new Error("this is not ProxyObserver")); - }, true); - let realSubject = { - a: { - b: { - c: true - }, - d: 5 - } - }; - let p = new ProxyObserver(realSubject); - expect(p).is.instanceOf(ProxyObserver); - expect(p.attachObserver(o)).is.instanceOf(ProxyObserver); - let s = p.getSubject(); - let r = p.getRealSubject(); - s.a.d = false; - s.a.b.d = 2; - }); - }); - describe("Reflect", function() { - it("check Reflect.set() with Subject", function() { - let r; - const obj = new ProxyObserver({}).getSubject(); - [ - "yes!", - void 0, - "no" - ].forEach(function(value) { - expect(() => { - obj["data"] = value; - }).to.not.throw(); - }); - }); - [ - ["that", { that: "checked1" }], - ["that", new Proxy({ that: "checked2" }, {})], - ["that", new ProxyObserver({ that: "checked3" }).getRealSubject()], - ["that", new ProxyObserver({ that: "checked4" }).getSubject()] - ].forEach(function(data) { - let key = data.shift(); - let target = data.shift(); - it("check Reflect.set(" + key + "," + JSON.stringify(target) + ") should writable", function() { - let value; - [ - "1", - void 0, - true, - void 0, - false, - void 0, - void 0 - ].forEach(function(values) { - expect(Reflect.getOwnPropertyDescriptor( - target, - key - )["writable"], "writable for " + value + " should return true").to.be.true; - expect(Reflect.set(target, key, value), "set for " + value + " should return true").to.be.true; - expect(Reflect.getOwnPropertyDescriptor( - target, - key - )["writable"], "writable for " + value + " should return true").to.be.true; - }); - }); - }); - }); - describe("notify observer with changes", function() { - let original, observer, proxy; - before(function() { - original = {}; - proxy = new ProxyObserver(original); - }); - [ - ["a", 4, JSON.stringify({ a: 4 })], - ["b", 9, JSON.stringify({ a: 4, b: 9 })] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - let c = data.shift(); - it("set key " + a2 + " value " + b + " expect " + c, function(done) { - let counter = 0; - observer = new Observer(function() { - counter++; - expect(JSON.stringify(this.getRealSubject())).is.equal(c); - if (counter === 1) { - this.detachObserver(observer); - done(); - } - }); - proxy.attachObserver(observer); - let subject = proxy.getSubject(); - subject[a2] = b; - }); - }); - }); - describe("notify observer ", function() { - it("should return promise", function() { - let proxy = new ProxyObserver({}); - let observer = new Observer(function() { - }); - proxy.attachObserver(observer); - expect(proxy.notifyObservers()).is.instanceOf(Promise); - }); - }); - }); - - // ../application/source/types/node.mjs - init_base(); - init_is(); - - // ../application/source/types/nodelist.mjs - init_is(); - init_validate(); - init_constants(); - var NodeList2 = class extends Set { - /** - * @throws {Error} invalid value type - * @param {NodeList|Node|Array<Node>}values - */ - constructor(values) { - super(); - const self2 = this; - if (values === void 0) - return; - if (isArray(values)) { - values.forEach((value) => self2.add(value)); - } else if (isInstance(values, NodeList2)) { - values.forEach((value) => self2.add(value)); - } else if (isInstance(values, Node2)) { - self2.add(values); - } else { - throw new Error("invalid value type"); - } - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/types/node-list"); - } - /** - * - * @param {Node} node - * @return {Monster.Types.NodeList} - */ - add(node) { - super.add(validateInstance(node, Node2)); - return this; - } - /** - * @param {Node} node - * @returns {NodeList} - */ - remove(node) { - super.delete(validateInstance(node, Node2)); - return this; - } - /** - * @param {Node} node - * @returns {boolean} - */ - has(node) { - return super.has(validateInstance(node, Node2)); - } - /** - * @returns {NodeList} - */ - clear() { - super.clear(); - return this; - } - /** - * @returns {NodeList} - */ - toArray() { - return Array.from(this); - } - /** - * @returns {NodeList} - */ - toJSON() { - return this.toArray(); - } - /** - * @returns {NodeList} - */ - toString() { - let parts = []; - for (const node of this.toArray()) { - parts.push(node.toString()); - } - return parts.join("\n"); - } - get length() { - return super.size; - } - }; - - // ../application/source/types/node.mjs - init_validate(); - init_constants(); - var internalValueSymbol = Symbol("internalData"); - var treeStructureSymbol = Symbol("treeStructure"); - var Node2 = class extends Base { - /** - * @param {*} [value] - */ - constructor(value) { - super(); - this[internalValueSymbol] = value; - this[treeStructureSymbol] = { - parent: null, - childNodes: new NodeList2(), - level: 0 - }; - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/types/node"); - } - /** - * @property {*} - */ - get value() { - return this[internalValueSymbol]; - } - /** - * @property {*} - */ - set value(value) { - this[internalValueSymbol] = value; - } - /** - * @property {Monster.Types.Node|null} - */ - get parent() { - return this[treeStructureSymbol].parent; - } - /** - * @property {integer} - */ - get level() { - return this[treeStructureSymbol].level; - } - /** - * - * @property {NodeList} - */ - get childNodes() { - return this[treeStructureSymbol].childNodes; - } - /** - * - * @property {NodeList} - */ - set childNodes(childNodes) { - this[treeStructureSymbol].childNodes = validateInstance(childNodes, NodeList2); - setChildLevelAndParent.call(this, this, 1); - } - /** - * @return {Monster.Types.Node} - * @param {Node} node - */ - appendChild(node) { - this[treeStructureSymbol].childNodes.add(validateInstance(node, Node2)); - node[treeStructureSymbol].parent = this; - node[treeStructureSymbol].level = this.level + 1; - setChildLevelAndParent.call(this, node, 1); - return this; - } - /** - * @return {Monster.Types.Node} - * @param {Node} node - */ - removeChild(node) { - this[treeStructureSymbol].childNodes.remove(validateInstance(node, Node2)); - node[treeStructureSymbol].parent = null; - node[treeStructureSymbol].level = 0; - setChildLevelAndParent.call(this, node, -1); - return this; - } - /** - * - * @return {boolean} - */ - hasChildNodes() { - return this[treeStructureSymbol].childNodes.length > 0; - } - /** - * @return {Monster.Types.Node} - * @param {Node} node - */ - hasChild(node) { - return this[treeStructureSymbol].childNodes.has(validateInstance(node, Node2)); - } - /** - * @since 1.28.0 - * @return {string} - */ - toString() { - let parts = []; - if (this[internalValueSymbol]) { - let label = this[internalValueSymbol]; - if (!isPrimitive(label)) - label = JSON.stringify(this[internalValueSymbol]); - parts.push(label); - } - if (!this.hasChildNodes()) { - return parts.join("\n"); - } - let count = this.childNodes.length; - let counter = 0; - for (const node of this.childNodes) { - counter++; - const prefix = (count === counter ? "\u2514" : "\u251C").padStart(2 * node.level, " |"); - parts.push(prefix + node.toString()); - } - return parts.join("\n"); - } - }; - function setChildLevelAndParent(node, operand) { - const self2 = this; - if (node !== this) { - node[treeStructureSymbol].parent = this; - } - node[treeStructureSymbol].childNodes.forEach(function(child) { - child[treeStructureSymbol].parent = node; - child[treeStructureSymbol].level = node[treeStructureSymbol].level + operand; - setChildLevelAndParent.call(self2, child, operand); - }); - return this; - } - - // test/cases/types/nodelist.mjs - describe("NodeList", function() { - describe("#constructor", function() { - it("should create an empty NodeList", function() { - let nodeList = new NodeList2(); - expect(nodeList.size).to.equal(0); - }); - it("should create a NodeList from an array", function() { - let nodeList = new NodeList2([ - new Node2("div"), - new Node2("div"), - new Node2("div") - ]); - expect(nodeList.size).to.equal(3); - }); - it("should create a NodeList from a NodeList", function() { - let nodeList = new NodeList2([ - new Node2("div"), - new Node2("div"), - new Node2("div") - ]); - let nodeList2 = new NodeList2(nodeList); - expect(nodeList2.size).to.equal(3); - }); - }); - it("create NodeList", function() { - expect(new NodeList2()).is.instanceof(NodeList2); - }); - it("add Node", function() { - expect(new NodeList2().add(new Node2())).to.be.instanceof(NodeList2); - }); - it("remove Node", function() { - expect(new NodeList2().remove(new Node2())).to.be.instanceof(NodeList2); - }); - it("has unknown Node", function() { - expect(new NodeList2().has(new Node2())).to.be.false; - }); - it("has added Node", function() { - const n = new Node2(); - expect(new NodeList2().add(n).has(n)).to.be.true; - }); - it("toString", function() { - const n = new Node2(); - expect(new NodeList2().add(new Node2("a").appendChild(new Node2("b"))).toString()).to.be.equal("a\n \u2514b"); - }); - it("throw exception", function() { - expect(() => new NodeList2().add(1)).to.throw(Error); - }); - }); - - // test/cases/types/version.mjs - describe("Version", function() { - describe(".compareTo()", function() { - [ - ["1.2.3", "1.2.3", 0], - ["1.2.2", "1.2.3", -1], - ["2", "2.0.0", 0], - ["1.2.4", "1.2.3", 1] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - let c = data.shift(); - it("should return " + c + " when the value " + a2 + " is " + b, function() { - expect(new Version(a2).compareTo(b)).to.be.equal(c); - }); - }); - }); - describe(".toString()", function() { - [ - ["1.1.1", "2.3", 3, "1.2.3"], - ["1.2.4", "1.2.3", 5, "1.1.5"] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - let c = data.shift(); - let d = data.shift(); - it("should return " + d, function() { - expect(new Version(a2, b, c).toString()).to.be.equal(d); - }); - }); - }); - }); - - // ../application/source/types/noderecursiveiterator.mjs - init_constants(); - init_base(); - init_is(); - init_validate(); - var isNodeListSymbol = Symbol("isNodeList"); - var NodeRecursiveIterator = class extends Base { - /** - * @param {Node} [data] - */ - constructor(node) { - super(); - this[isNodeListSymbol] = false; - if (isInstance(node, NodeList2)) { - let children = node; - node = new Node2(); - node.childNodes = children; - this[isNodeListSymbol] = true; - } - this[internalSymbol] = validateInstance(node, Node2); - } - /** - * @private - * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield - */ - [Symbol.iterator] = function* () { - if (this[internalSymbol] === void 0) { - return; - } - if (this[isNodeListSymbol] !== true) { - yield this[internalSymbol]; - } - if (this[internalSymbol].hasChildNodes()) { - let childNodes = this[internalSymbol].childNodes; - for (let node of childNodes) { - yield* new NodeRecursiveIterator(node); - } - } - return; - }; - /** - * @param {function} callback - * @return {Monster.Types.NodeRecursiveIterator} - */ - forEach(callback) { - for (const node of this) { - callback(node); - } - return this; - } - }; - - // test/cases/types/node.mjs - describe("NodeList", function() { - describe("#constructor", function() { - it("should create an empty NodeList", function() { - let nodeList = new NodeList2(); - expect(nodeList.size).to.equal(0); - }); - it("should create a NodeList from an array", function() { - let nodeList = new NodeList2([ - new Node2("div"), - new Node2("div"), - new Node2("div") - ]); - expect(nodeList.size).to.equal(3); - }); - it("should create a NodeList from a NodeList", function() { - let nodeList = new NodeList2([ - new Node2("div"), - new Node2("div"), - new Node2("div") - ]); - let nodeList2 = new NodeList2(nodeList); - expect(nodeList2.size).to.equal(3); - }); - }); - it("create NodeList", function() { - expect(new NodeList2()).is.instanceof(NodeList2); - }); - it("add Node", function() { - expect(new NodeList2().add(new Node2())).to.be.instanceof(NodeList2); - }); - it("remove Node", function() { - expect(new NodeList2().remove(new Node2())).to.be.instanceof(NodeList2); - }); - it("has unknown Node", function() { - expect(new NodeList2().has(new Node2())).to.be.false; - }); - it("has added Node", function() { - const n = new Node2(); - expect(new NodeList2().add(n).has(n)).to.be.true; - }); - it("throw exception", function() { - expect(() => new NodeList2().add(1)).to.throw(Error); - }); - it("check level", function() { - const root = new Node2("root"); - const n1 = new Node2("n1"); - const n2 = new Node2("n2"); - const n3 = new Node2("n3"); - const n4 = new Node2("n4"); - const n11 = new Node2("n11"); - const n12 = new Node2("n12"); - const n13 = new Node2("n13"); - const n21 = new Node2("n21"); - const n22 = new Node2("n22"); - const n23 = new Node2("n23"); - const n41 = new Node2("n41"); - const n42 = new Node2("n42"); - const n411 = new Node2("n411"); - const n412 = new Node2("n412"); - const n413 = new Node2("n413"); - const n4121 = new Node2("n4121"); - root.appendChild(n1).appendChild(n2).appendChild(n3).appendChild(n4); - n1.appendChild(n11).appendChild(n12).appendChild(n13); - n2.appendChild(n21).appendChild(n22).appendChild(n23); - n4.appendChild(n41).appendChild(n42); - n41.appendChild(n411).appendChild(n412).appendChild(n413); - n412.appendChild(n4121); - let iterator = new NodeRecursiveIterator(root); - let result = []; - for (const n of iterator) { - expect(n).to.be.an.instanceof(Node2); - result.push(n.value + ":" + n.level); - } - expect(result).to.deep.equal([ - "root:0", - "n1:1", - "n11:2", - "n12:2", - "n13:2", - "n2:1", - "n21:2", - "n22:2", - "n23:2", - "n3:1", - "n4:1", - "n41:2", - "n411:3", - "n412:3", - "n4121:4", - "n413:3", - "n42:2" - ]); - n4121.appendChild(new Node2("n41211")); - iterator = new NodeRecursiveIterator(root); - result = []; - for (const n of iterator) { - expect(n).to.be.an.instanceof(Node2); - result.push(n.value + ":" + n.level); - } - expect(result).to.deep.equal([ - "root:0", - "n1:1", - "n11:2", - "n12:2", - "n13:2", - "n2:1", - "n21:2", - "n22:2", - "n23:2", - "n3:1", - "n4:1", - "n41:2", - "n411:3", - "n412:3", - "n4121:4", - "n41211:5", - "n413:3", - "n42:2" - ]); - const bb = new Node2("bb"); - bb.appendChild(root); - iterator = new NodeRecursiveIterator(bb); - result = []; - for (const n of iterator) { - expect(n).to.be.an.instanceof(Node2); - result.push(n.value + ":" + n.level); - } - expect(result).to.deep.equal([ - "bb:0", - "root:1", - "n1:2", - "n11:3", - "n12:3", - "n13:3", - "n2:2", - "n21:3", - "n22:3", - "n23:3", - "n3:2", - "n4:2", - "n41:3", - "n411:4", - "n412:4", - "n4121:5", - "n41211:6", - "n413:4", - "n42:3" - ]); - }); - describe("Levels", function() { - it("n2 should level 2", function() { - const n0 = new Node2("abc"); - const n1 = new Node2("def"); - n0.appendChild(n1); - const n2 = new Node2("ghi"); - n1.appendChild(n2); - const n3 = new Node2("jkl"); - n2.appendChild(n3); - expect(n0.level).to.be.equal(0); - expect(n1.level).to.be.equal(1); - expect(n2.level).to.be.equal(2); - expect(n3.level).to.be.equal(3); - }); - }); - describe("toString()", function() { - it("should output empty string", function() { - const node = new Node2(); - expect(node.toString()).is.equal(""); - }); - it("should output string", function() { - const n0 = new Node2("abc"); - const n1 = new Node2("def"); - n0.appendChild(n1); - const n11 = new Node2("ghi"); - n0.appendChild(n11); - const n2 = new Node2("jkl"); - n1.appendChild(n2); - const n3 = new Node2("mno"); - n1.appendChild(n3); - const n4 = new Node2("pqr"); - n2.appendChild(n4); - expect(n2.level).to.be.equal(2); - console.log(n0.toString()); - }); - }); - }); - - // test/cases/types/noderecursiveiterator.mjs - describe("NodeRecursiveIterator", function() { - it("should throw exeption", function() { - expect(() => new NodeRecursiveIterator()).to.throw(Error); - }); - it("should be a function", function() { - expect(NodeRecursiveIterator).to.be.a("function"); - }); - it("should be a constructor", function() { - expect(new NodeRecursiveIterator(new Node2())).to.be.an.instanceof(NodeRecursiveIterator); - }); - it("undefined should not result in undefined node", function() { - const iterator = new NodeRecursiveIterator(new Node2()); - const result = []; - for (const n of iterator) { - expect(n).to.be.an.instanceof(Node2); - result.push(n.value); - } - expect(result).to.deep.equal([void 0]); - }); - it("should iterate", function() { - const node = new Node2("1"); - node.appendChild( - new Node2("2").appendChild(new Node2("2.1")).appendChild(new Node2("2.2")).appendChild(new Node2("2.3")) - ).appendChild(new Node2("3")).appendChild(new Node2("4").appendChild(new Node2("4.1")).appendChild(new Node2("4.2"))); - const iterator = new NodeRecursiveIterator(node); - const result = []; - for (const n of iterator) { - expect(n).to.be.an.instanceof(Node2); - result.push(n.value); - } - expect(result).to.deep.equal(["1", "2", "2.1", "2.2", "2.3", "3", "4", "4.1", "4.2"]); - }); - it("should iterate nodelist", function() { - const nodeList = new NodeList2(); - nodeList.add( - new Node2("2").appendChild(new Node2("2.1")).appendChild(new Node2("2.2")).appendChild(new Node2("2.3")).appendChild(new Node2("3")).appendChild(new Node2("4").appendChild(new Node2("4.1")).appendChild(new Node2("4.2"))) - ); - nodeList.add(new Node2("x")); - const iterator = new NodeRecursiveIterator(nodeList); - const result = []; - for (const n of iterator) { - expect(n).to.be.an.instanceof(Node2); - result.push(n.value); - } - expect(result).to.deep.equal(["2", "2.1", "2.2", "2.3", "3", "4", "4.1", "4.2", "x"]); - }); - }); - - // test/cases/types/global.mjs - init_global(); - describe("Global", function() { - describe("getGlobal", function() { - it("should return global object", function() { - let t = typeof getGlobal(); - expect(t).to.be.equal("object"); - }); - }); - describe("getGlobalFunction", function() { - it("should return global function", function() { - let t = typeof getGlobalFunction("parseInt"); - expect(t).to.be.equal("function"); - }); - }); - describe("getGlobalObject", function() { - it("should return global object", function() { - let t = typeof getGlobalObject("JSON"); - expect(t).to.be.equal("object"); - }); - }); - }); - - // test/cases/types/dataurl.mjs - init_dataurl(); - describe("Dataurl", function() { - [ - [" data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E"], - ["data:text/html;charset=US-ASCII,%3Ch1%3EHello!%3C%2Fh1%3E"], - ["data:,A%20brief%20note", "data:text/plain;charset=US-ASCII,A%20brief%20note"], - ["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD///+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC"], - [" data:,Hello%2C%20World!", "data:text/plain;charset=US-ASCII,Hello%2C%20World!"], - [" data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIBAMAAAA2IaO4AAAAFVBMVEXk5OTn5+ft7e319fX29vb5+fn///++GUmVAAAALUlEQVQIHWNICnYLZnALTgpmMGYIFWYIZTA2ZFAzTTFlSDFVMwVyQhmAwsYMAKDaBy0axX/iAAAAAElFTkSuQmCC "], - [" data:,Hello World!", "data:text/plain;charset=US-ASCII,Hello%20World!"], - ["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIBAMAAAA2IaO4AAAAFVBMVEXk5OTn5+ft7e319fX29vb5+fn///++GUmVAAAALUlEQVQIHWNICnYLZnALTgpmMGYIFWYIZTA2ZFAzTTFlSDFVMwVyQhmAwsYMAKDaBy0axX/iAAAAAElFTkSuQmCC"], - [" data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D"] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - if (b === void 0) - b = a2.trim(); - it("parseDataURL(" + a2 + ")", function() { - expect(parseDataURL(a2).toString()).to.be.equal(b); - }); - }); - [ - ["dataxbase64"], - ["data:HelloWorld"], - ["data:text/html;charset=,%3Ch1%3EHello!%3C%2Fh1%3E"], - ["data:text/html;charset,%3Ch1%3EHello!%3C%2Fh1%3E", "data:base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD///+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC"], - [""], - ["http://wikipedia.org"], - ["base64"], - ["iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD///+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC"] - ].forEach(function(data) { - let a2 = data.shift(); - it("should throw exception parseDataURL(" + a2 + ")", function() { - expect(() => parseDataURL(a2)).throw(TypeError); - }); - }); - }); - - // test/cases/types/validate.mjs - init_validate(); - init_base(); - init_id(); - describe("validate", function() { - describe(".validatePrimitive()", function() { - [ - ["test1", true], - [void 0, true], - [null, true], - [() => { - }, false], - [2, true], - [false, true], - [true, true], - [4.5, true], - [{}, false], - [[1, 2, 3], false], - [Symbol("foo"), true] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - if (b === false) { - it(".validatePrimitive(" + typeof a2 + ") should throw TypeException " + b, function() { - expect(() => validatePrimitive(a2)).to.throw(TypeError); - }); - } else { - it(".validatePrimitive(" + typeof a2 + ") should not throw TypeException " + b, function() { - expect(validatePrimitive(a2)).to.be.equal(a2); - }); - } - }); - }); - describe(".validateInteger()", function() { - [ - ["test1", false], - [void 0, false], - [null, false], - [() => { - }, false], - [2, true], - [false, false], - [true, false], - [4.5, false], - [{}, false], - [[1, 2, 3], false], - [Symbol("foo"), false] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - if (b === false) { - it(".validateInteger(" + typeof a2 + ") should throw TypeException " + b, function() { - expect(() => validateInteger(a2)).to.throw(TypeError); - }); - } else { - it(".validateInteger(" + typeof a2 + ") should not throw TypeException " + b, function() { - expect(validateInteger(a2)).to.be.equal(a2); - }); - } - }); - }); - describe(".validateSymbol()", function() { - [ - ["test1", false], - [void 0, false], - [null, false], - [() => { - }, false], - [2, false], - [false, false], - [true, false], - [4.5, false], - [{}, false], - [[1, 2, 3], false], - [Symbol("foo"), true] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - if (b === false) { - it(".validateSymbol(" + typeof a2 + ") should throw TypeException " + b, function() { - expect(() => validateSymbol(a2)).to.throw(TypeError); - }); - } else { - it(".validateSymbol(" + typeof a2 + ") should not throw TypeException " + b, function() { - expect(validateSymbol(a2)).to.be.equal(a2); - }); - } - }); - }); - describe(".validateIterable()", function() { - [ - ["test1", true], - [void 0, false], - [null, false], - [() => { - }, false], - [2, false], - [false, false], - [true, false], - [4.5, false], - [{}, false], - [[1, 2, 3], true], - [Symbol("foo"), false] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - if (b === false) { - it(".validateIterable(" + typeof a2 + ") should throw TypeException " + b, function() { - expect(() => { - validateIterable(a2); - }).to.throw(TypeError); - ; - }); - } else { - it(".validateIterable(" + typeof a2 + ") should not throw TypeException " + b, function() { - expect(validateIterable(a2)).to.be.equal(a2); - }); - } - }); - }); - describe(".validateBoolean()", function() { - [ - ["test1", false], - [void 0, false], - [null, false], - [() => { - }, false], - [2, false], - [false, true], - [true, true], - [4.5, false], - [{}, false], - [[1, 2, 3], false], - [Symbol("foo"), false] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - if (b === false) { - it(".validateBoolean(" + typeof a2 + ") should throw TypeException " + b, function() { - expect(() => { - validateBoolean(a2); - }).to.throw(TypeError); - }); - } else { - it(".validateBoolean(" + typeof a2 + ") should not throw TypeException " + b, function() { - expect(validateBoolean(a2)).to.be.equal(a2); - }); - } - }); - }); - describe(".validateString()", function() { - [ - ["test1", true], - [void 0, false], - [null, false], - [() => { - }, false], - [2, false], - [false, false], - [true, false], - [4.5, false], - [{}, false], - [[1, 2, 3], false], - [Symbol("foo"), false] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - if (b === false) { - it(".validateString(" + typeof a2 + ") should throw TypeException " + b, function() { - expect(() => { - validateString(a2); - }).to.throw(TypeError); - ; - }); - } else { - it(".validateString(" + typeof a2 + ") should not throw TypeException " + b, function() { - expect(validateString(a2)).to.be.equal(a2); - }); - } - }); - }); - describe(".validateObject()", function() { - [ - ["test1", false], - [void 0, false], - [null, false], - [() => { - }, false], - [2, false], - [false, false], - [true, false], - [4.5, false], - [{}, true], - [[1, 2, 3], false], - [Symbol("foo"), false] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - if (b === false) { - it(".validateObject(" + typeof a2 + ") should throw TypeException " + b, function() { - expect(() => { - validateObject(a2); - }).to.throw(TypeError); - ; - }); - } else { - it(".validateObject(" + typeof a2 + ") should not throw TypeException " + b, function() { - expect(validateObject(a2)).to.be.equal(a2); - }); - } - }); - }); - describe(".validateInstance()", function() { - [ - ["test1", Object], - [void 0, Object], - [null, Object], - [() => { - }, Object], - [2, Object], - [false, Object], - [true, Object], - [4.5, Object], - [{}, Base], - [[1, 2, 3], Object], - [Symbol("foo"), Object] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - it(".validateInstance(" + typeof a2 + ") should throw TypeException ", function() { - expect(() => { - validateInstance(a2, b); - }).to.throw(TypeError); - ; - }); - }); - }); - describe(".validateInstance()", function() { - [ - [{}, Object, true], - [new Base(), Base, true] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - it(".validateInstance(" + typeof a2 + ") should not throw TypeException ", function() { - expect(validateInstance(a2, b)).to.be.equal(a2); - }); - }); - }); - describe(".validateArray()", function() { - [ - ["test1", false], - [void 0, false], - [null, false], - [() => { - }, false], - [2, false], - [false, false], - [true, false], - [4.5, false], - [{}, false], - [[1, 2, 3], true], - [Symbol("foo"), false] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - if (b === false) { - it(".validateArray(" + typeof a2 + ") should throw TypeException " + b, function() { - expect(() => { - validateArray(a2); - }).to.throw(TypeError); - ; - }); - } else { - it(".validateArray(" + typeof a2 + ") should not throw TypeException " + b, function() { - expect(validateArray(a2)).to.be.equal(a2); - }); - } - }); - }); - describe(".validateFunction()", function() { - [ - ["test1", false], - [void 0, false], - [null, false], - [() => { - }, true], - [2, false], - [false, false], - [true, false], - [4.5, false], - [{}, false], - [[1, 2, 3], false], - [Symbol("foo"), false] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - if (b === false) { - it(".validateFunction(" + typeof a2 + ") should throw TypeException " + b, function() { - expect(() => { - validateFunction(a2); - }).to.throw(TypeError); - ; - }); - } else { - it(".validateFunction(" + typeof a2 + ") should not throw TypeException " + b, function() { - expect(validateFunction(a2)).to.be.equal(a2); - }); - } - }); - }); - }); - - // test/cases/types/uniquequeue.mjs - init_uniquequeue(); - describe("UniqueQueue", function() { - let queue; - beforeEach(() => { - queue = new UniqueQueue(); - }); - describe("isEmpty()", function() { - it("first it should empty", function() { - expect(queue.isEmpty()).to.be.true; - }); - }); - describe("add sequence peek and poll", function() { - it("result a,a,a,b", function() { - expect(queue.add({ a: 1 })).to.be.instanceOf(UniqueQueue); - expect(queue.isEmpty()).to.be.false; - expect(queue.add({ a: 2 })).to.be.instanceOf(UniqueQueue); - expect(queue.add({ a: 3 })).to.be.instanceOf(UniqueQueue); - expect(queue.peek()).to.deep.equal({ a: 1 }); - expect(queue.peek()).to.deep.equal({ a: 1 }); - expect(queue.poll()).to.deep.equal({ a: 1 }); - expect(queue.poll()).to.deep.equal({ a: 2 }); - expect(queue.isEmpty()).to.be.false; - expect(queue.peek()).to.deep.equal({ a: 3 }); - expect(queue.poll()).to.deep.equal({ a: 3 }); - expect(queue.isEmpty()).to.be.true; - }); - }); - describe("add and clear", function() { - it("should empty", function() { - expect(queue.isEmpty()).to.be.true; - expect(queue.add({ a: 1 })).to.be.instanceOf(UniqueQueue); - expect(queue.isEmpty()).to.be.false; - expect(queue.clear()).to.be.instanceOf(UniqueQueue); - expect(queue.isEmpty()).to.be.true; - }); - }); - describe("add no object", function() { - it("should throw error", function() { - expect(() => { - queue.add([]); - }).to.throw(TypeError); - expect(() => { - queue.add(1); - }).to.throw(TypeError); - expect(() => { - queue.add(true); - }).to.throw(TypeError); - expect(() => { - queue.add(); - }).to.throw(TypeError); - expect(() => { - queue.add(Symbol("1")); - }).to.throw(TypeError); - expect(() => { - queue.add(function() { - }); - }).to.throw(TypeError); - }); - }); - }); - - // test/cases/types/base.mjs - init_base(); - init_constants(); - var BaseDifferentRealm = class extends Object { - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/types/base"); - } - }; - var Subclass = class extends BaseDifferentRealm { - constructor() { - super(); - } - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/types/subclass"); - } - }; - describe("Base", function() { - describe("new Base", function() { - it("is instance of Base", function() { - expect(new Base()).to.be.instanceOf(Base); - }); - it("is instance of Object", function() { - expect(new Base()).to.be.instanceOf(Object); - }); - }); - describe("instancof", function() { - it("is instance of Base", function() { - expect(new Base()).to.be.instanceOf(Base); - }); - it("subclass instanceof", function() { - if (new Subclass() instanceof Base) { - expect(true).to.be.true; - } else { - expect(false).to.be.true; - } - }); - }); - }); - - // test/cases/types/is.mjs - init_is(); - init_id(); - describe("Is", function() { - before(function(done) { - let promises = []; - if (!globalThis["crypto"]) { - promises.push(Promise.resolve().then(() => (init_webcrypto_es(), webcrypto_es_exports)).then((m) => { - globalThis["crypto"] = new m.Crypto(); - return true; - })); - } - Promise.all(promises).then(() => { - done(); - }); - }); - describe(".isPrimitive()", function() { - [ - ["test1", true], - [void 0, true], - [null, true], - [() => { - }, false], - [2, true], - [parseInt("a"), true], - [false, true], - [true, true], - [4.5, true], - [{}, false], - [[1, 2, 3], false], - [Symbol("foo"), true] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - it("is.isPrimitive(" + typeof a2 + ") should return " + b, function() { - expect(isPrimitive(a2)).is.equal(b); - }); - }); - }); - describe(".isSymbol()", function() { - [ - ["test1", false], - [void 0, false], - [null, false], - [() => { - }, false], - [2, false], - [parseInt("a"), false], - [false, false], - [true, false], - [4.5, false], - [{}, false], - [[1, 2, 3], false], - [Symbol("foo"), true] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - it("is.isSymbol(" + typeof a2 + ") should return " + b, function() { - expect(isSymbol(a2)).is.equal(b); - }); - }); - }); - describe(".isInteger()", function() { - [ - ["test1", false], - [void 0, false], - [null, false], - [() => { - }, false], - [2, true], - [parseInt("a"), false], - [false, false], - [true, false], - [4.5, false], - [{}, false], - [[1, 2, 3], false], - [Symbol("foo"), false] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - it("is.isInteger(" + typeof a2 + ") should return " + b, function() { - expect(isInteger(a2)).is.equal(b); - }); - }); - }); - describe(".isIterable()", function() { - [ - ["test1", true], - [void 0, false], - [null, false], - [() => { - }, false], - [parseInt("a"), false], - [2, false], - [false, false], - [true, false], - [4.5, false], - [{}, false], - [[1, 2, 3], true], - [Symbol("foo"), false] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - it("is.isIterable(" + typeof a2 + ") should return " + b, function() { - expect(isIterable(a2)).is.equal(b); - }); - }); - }); - describe(".isBoolean()", function() { - [ - ["test1", false], - [void 0, false], - [null, false], - [() => { - }, false], - [2, false], - [false, true], - [parseInt("a"), false], - [true, true], - [4.5, false], - [{}, false], - [[1, 2, 3], false], - [Symbol("foo"), false] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - it("is.isBoolean(" + typeof a2 + ") should return " + b, function() { - expect(isBoolean(a2)).is.equal(b); - }); - }); - }); - describe(".isString()", function() { - [ - ["test1", true], - [void 0, false], - [null, false], - [() => { - }, false], - [2, false], - [false, false], - [parseInt("a"), false], - [true, false], - [4.5, false], - [{}, false], - [[1, 2, 3], false], - [Symbol("foo"), false] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - it("is.isString(" + typeof a2 + ") should return " + b, function() { - expect(isString(a2)).is.equal(b); - }); - }); - }); - describe(".isInstance()", function() { - [ - [new ID(), ID, true], - [new ID(), () => { - }, false], - ["test1", void 0, false], - [void 0, void 0, false], - [null, void 0, false], - [() => { - }, void 0, false], - [2, void 0, false], - [false, void 0, false], - [parseInt("a"), void 0, false], - [true, void 0, false], - [4.5, void 0, false], - [{}, void 0, false], - [[1, 2, 3], void 0, false], - [Symbol("foo"), void 0, false] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - let c = data.shift(); - it("is.isInstance(" + JSON.stringify(a2) + ") should return " + typeof b, function() { - expect(isInstance(a2, b)).is.equal(c); - }); - }); - }); - describe(".isObject()", function() { - [ - ["test1", false], - [void 0, false], - [null, false], - [() => { - }, false], - [2, false], - [false, false], - [parseInt("a"), false], - [true, false], - [4.5, false], - [{}, true], - [[1, 2, 3], false], - [Symbol("foo"), false] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - it("is.isObject(" + JSON.stringify(a2) + ") should return " + b, function() { - expect(isObject(a2)).is.equal(b); - }); - }); - }); - describe(".isArray()", function() { - [ - ["test1", false], - [void 0, false], - [null, false], - [() => { - }, false], - [2, false], - [false, false], - [parseInt("a"), false], - [true, false], - [4.5, false], - [{}, false], - [[1, 2, 3], true], - [Symbol("foo"), false] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - it("is.isArray(" + typeof a2 + ") should return " + b, function() { - expect(isArray(a2)).is.equal(b); - }); - }); - }); - describe(".isFunction()", function() { - [ - ["test1", false], - [void 0, false], - [null, false], - [() => { - }, true], - [2, false], - [false, false], - [parseInt("a"), false], - [true, false], - [4.5, false], - [{}, false], - [[1, 2, 3], false], - [Symbol("foo"), false] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - it("is.isFunction(" + typeof a2 + ") should return " + b, function() { - expect(isFunction(a2)).is.equal(b); - }); - }); - }); - }); - - // test/cases/types/id.mjs - init_id(); - describe("ID", function() { - before(function(done) { - let promises = []; - if (!globalThis["crypto"]) { - promises.push(Promise.resolve().then(() => (init_webcrypto_es(), webcrypto_es_exports)).then((m) => { - globalThis["crypto"] = new m.Crypto(); - return true; - })); - } - Promise.all(promises).then(() => { - done(); - }); - }); - describe(".toString()", function() { - let id = new ID(); - let result = id.toString(); - it("should return a string", function() { - expect(result).is.a("string"); - }); - it("should return a string", function() { - expect(new ID("text1425id").toString()).is.equal("text1425id1"); - expect(new ID("text1425id").toString()).is.equal("text1425id2"); - expect(new ID("text1425id").toString()).is.equal("text1425id3"); - }); - }); - }); - - // ../application/source/constraints/isobject.mjs - init_is(); - - // ../application/source/constraints/abstract.mjs - init_base(); - init_constants(); - var AbstractConstraint = class extends Base { - /** - * - */ - constructor() { - super(); - } - /** - * this method must return a promise containing the result of the check. - * - * @param {*} value - * @returns {Promise} - */ - isValid(value) { - return Promise.reject(value); - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/constraints/abstract-constraint"); - } - }; - - // ../application/source/constraints/isobject.mjs - init_constants(); - var IsObject = class extends AbstractConstraint { - /** - * this method return a promise containing the result of the check. - * - * @param {*} value - * @returns {Promise} - */ - isValid(value) { - if (isObject(value)) { - return Promise.resolve(value); - } - return Promise.reject(value); - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/constraint/is-object"); - } - }; - - // test/cases/constraint/isobject.mjs - describe("IsObject", function() { - describe(".isValid()", function() { - let constraint = new IsObject(); - it("should resolve promise", function(done) { - constraint.isValid({}).then((r) => { - expect(r).is.a("object"); - done(); - }).catch((e) => { - done(new Error("should not reached: " + e)); - }); - }); - }); - }); - - // ../application/source/constraints/invalid.mjs - init_constants(); - var Invalid = class extends AbstractConstraint { - /** - * this method return a rejected promise - * - * @param {*} value - * @returns {Promise} - */ - isValid(value) { - return Promise.reject(value); - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/constraints/invalid"); - } - }; - - // test/cases/constraint/invalid.mjs - describe("Invalid", function() { - describe(".isValid()", function() { - let isvalid = new Invalid(); - it("should resolve promise", function(done) { - isvalid.isValid().catch((e) => { - expect(e).to.be.undefined; - done(); - }); - }); - }); - }); - - // ../application/source/constraints/valid.mjs - init_constants(); - var Valid = class extends AbstractConstraint { - /** - * this method return a promise containing the result of the check. - * - * @param {*} value - * @returns {Promise} - */ - isValid(value) { - return Promise.resolve(value); - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/constraints/valid"); - } - }; - - // ../application/source/constraints/abstractoperator.mjs - init_constants(); - var AbstractOperator = class extends AbstractConstraint { - /** - * - * @param {AbstractConstraint} operantA - * @param {AbstractConstraint} operantB - * @throws {TypeError} "parameters must be from type AbstractConstraint" - */ - constructor(operantA, operantB) { - super(); - if (!(operantA instanceof AbstractConstraint && operantB instanceof AbstractConstraint)) { - throw new TypeError("parameters must be from type AbstractConstraint"); - } - this.operantA = operantA; - this.operantB = operantB; - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/constraints/abstract-operator"); - } - }; - - // ../application/source/constraints/andoperator.mjs - init_constants(); - var AndOperator = class extends AbstractOperator { - /** - * this method return a promise containing the result of the check. - * - * @param {*} value - * @returns {Promise} - */ - isValid(value) { - return Promise.all([this.operantA.isValid(value), this.operantB.isValid(value)]); - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/constraints/and-operator"); - } - }; - - // test/cases/constraint/andoperator.mjs - describe("AndOperator", function() { - describe(".isValid()", function() { - [ - [new Valid(), new Valid(), true], - [new Valid(), new Invalid(), false], - [new Invalid(), new Valid(), false], - [new Invalid(), new Invalid(), false] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - let c = data.shift(); - it("constraint.isValid() should return " + c, function(done) { - let constraint = new AndOperator(a2, b); - constraint.isValid().then(() => { - c === true ? done() : done(new Error()); - }).catch(() => { - c === true ? done(new Error()) : done(); - }); - }); - }); - }); - }); - - // ../application/source/constraints/oroperator.mjs - init_constants(); - var OrOperator = class extends AbstractOperator { - /** - * this method return a promise containing the result of the check. - * - * @param {*} value - * @returns {Promise} - */ - isValid(value) { - var self2 = this; - return new Promise(function(resolve, reject) { - let a2; - let b; - self2.operantA.isValid(value).then(function() { - resolve(); - }).catch(function() { - a2 = false; - if (b === false) { - reject(); - } - }); - self2.operantB.isValid(value).then(function() { - resolve(); - }).catch(function() { - b = false; - if (a2 === false) { - reject(); - } - }); - }); - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/constraints/or-operator"); - } - }; - - // test/cases/constraint/oroperator.mjs - describe("OrOperator", function() { - describe(".isValid()", function() { - [ - [new Valid(), new Valid(), true], - [new Valid(), new Invalid(), true], - [new Invalid(), new Valid(), true], - [new Invalid(), new Invalid(), false] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - let c = data.shift(); - it("constraint.isValid() should return " + c, function(done) { - let constraint = new OrOperator(a2, b); - constraint.isValid().then(() => { - c === true ? done() : done(new Error()); - }).catch(() => { - c === true ? done(new Error()) : done(); - }); - }); - }); - }); - }); - - // ../application/source/constraints/isarray.mjs - init_is(); - init_constants(); - var IsArray = class extends AbstractConstraint { - /** - * this method return a promise containing the result of the check. - * - * @param {*} value - * @returns {Promise} - */ - isValid(value) { - if (isArray(value)) { - return Promise.resolve(value); - } - return Promise.reject(value); - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/constraint/is-array"); - } - }; - - // test/cases/constraint/isarray.mjs - describe("IsArray", function() { - describe(".isValid()", function() { - let constraint = new IsArray(); - it("should resolve promise", function(done) { - constraint.isValid([1, 2, 3]).then((r) => { - expect(r).is.a("array"); - done(); - }).catch((e) => { - done(new Error("should not reached: " + e)); - }); - }); - }); - }); - - // test/cases/constraint/abstractoperator.mjs - init_base(); - var AbstractConstraintMock = class extends Base { - constructor() { - super(); - } - isValid(value) { - return Promise.reject(value); - } - }; - describe("AbstractOperator", function() { - it("should throw an error when the constraint is not call with parameter", function(done) { - try { - new AbstractOperator(); - } catch (e) { - done(); - } - }); - it("should throw not an error when the constraint is not call with parameter", function(done) { - try { - const c = new AbstractOperator(new AbstractConstraintMock(), new AbstractConstraintMock()); - } catch (e) { - done(); - } - }); - }); - - // test/cases/constraint/valid.mjs - describe("Valid", function() { - describe(".isValid()", function() { - let constraint = new Valid(); - it("should resolve promise", function(done) { - constraint.isValid({}).then((r) => { - done(); - }).catch((e) => { - done(new Error("should not reached: " + e)); - }); - }); - }); - }); - - // test/cases/util/trimspaces.mjs - init_trimspaces(); - describe("trimSpaces", function() { - [ - // one stroke is escped by the javascript interpreter, the second stroke escapes the stroke - [" value ", "value"], - [" value\\ ", "value\\ "], - ["\\ value\\ ", "\\ value\\ "], - [" value ", "value"], - [" value ", "value"] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - it("trimSpaces(" + JSON.stringify(a2) + ") should return " + JSON.stringify(b), function() { - expect(trimSpaces(a2)).to.be.equal(b); - }); - }); - }); - - // ../application/source/util/deadmansswitch.mjs - init_constants(); - init_base(); - init_is(); - init_validate(); - var DeadMansSwitch = class extends Base { - /** - * Create new dead man's switch - * - * @param {Integer} delay - * @param {function} callback - * @throw {TypeError} the arguments must be either integer or functions - * @throws {TypeError} value is not an integer - */ - constructor(delay, callback) { - super(); - init2.call(this, validateInteger(delay), validateFunction(callback)); - } - /** - * - * @param {Integer|undefined} [delay] - */ - touch(delay) { - if (this[internalSymbol]["isAlreadyRun"] === true) { - throw new Error("has already run"); - } - if (isInteger(delay)) { - this[internalSymbol]["delay"] = delay; - } else if (delay !== void 0) { - throw new Error("unsupported argument"); - } - clearTimeout(this[internalSymbol]["timer"]); - initCallback.call(this); - return this; - } - }; - function initCallback() { - const self2 = this; - self2[internalSymbol]["timer"] = setTimeout(() => { - self2[internalSymbol]["isAlreadyRun"] = true; - self2[internalSymbol]["callback"](); - }, self2[internalSymbol]["delay"]); - } - function init2(delay, callback) { - const self2 = this; - self2[internalSymbol] = { - callback, - delay, - isAlreadyRun: false, - timer: void 0 - }; - initCallback.call(self2); - } - - // test/cases/util/deadmansswitch.mjs - describe("DeadMansSwitch", function() { - describe("run instance", function() { - it("should run", function(done) { - const ms1 = Date.now(); - new DeadMansSwitch(100, () => { - const ms2 = Date.now(); - const diff2 = ms2 - ms1; - if (diff2 < 100) { - done("to short " + diff2); - return; - } - done(); - }); - }); - }); - describe("run instance and touch", function() { - it("should run", function(done) { - const ms1 = Date.now(); - const deadmansswitch = new DeadMansSwitch(100, () => { - const ms2 = Date.now(); - const diff2 = ms2 - ms1; - if (ms1 > ms2) { - done(new Error("timing error")); - return; - } - if (diff2 < 600) { - done(new Error("to short " + diff2)); - return; - } - done(); - }); - setTimeout(() => { - deadmansswitch.touch(); - setTimeout(() => { - deadmansswitch.touch(500); - }, 50); - }, 50); - }); - }); - }); - - // ../application/source/util/freeze.mjs - init_validate(); - function deepFreeze(object) { - validateObject(object); - var propNames = Object.getOwnPropertyNames(object); - for (let name of propNames) { - let value = object[name]; - object[name] = value && typeof value === "object" ? deepFreeze(value) : value; - } - return Object.freeze(object); - } - - // test/cases/util/freeze.mjs - describe("deepFreeze", function() { - describe("deepFreeze an object", function() { - it("should freeze object", function() { - let obj1 = { - a: { - b: { - c: 1 - } - } - }; - let obj2 = { - a: { - b: { - c: 2 - } - } - }; - expect(obj2).to.not.eql(obj1); - obj1.a.b.c = 2; - expect(obj2).to.eql(obj1); - const obj1Freezed = deepFreeze(obj1); - expect(obj2).to.eql(obj1Freezed); - try { - obj1Freezed.a.b.c = 3; - } catch (_) { - } - expect(obj2).to.eql(obj1Freezed); - }); - }); - }); - - // ../application/source/util/comparator.mjs - init_base(); - init_is(); - var Comparator = class extends Base { - /** - * create new comparator - * - * @param {Monster.Util~exampleCallback} [callback] Comparator callback - * @throw {TypeError} unsupported type - * @throw {TypeError} impractical comparison - */ - constructor(callback) { - super(); - if (isFunction(callback)) { - this.compare = callback; - } else if (callback !== void 0) { - throw new TypeError("unsupported type"); - } else { - this.compare = function(a2, b) { - if (typeof a2 !== typeof b) { - throw new TypeError("impractical comparison", "types/comparator.mjs"); - } - if (a2 === b) { - return 0; - } - return a2 < b ? -1 : 1; - }; - } - } - /** - * changes the order of the operators - * - * @return {Comparator} - */ - reverse() { - const original = this.compare; - this.compare = (a2, b) => original(b, a2); - return this; - } - /** - * Checks if two variables are equal. - * - * @param {*} a - * @param {*} b - * - * @return {boolean} - */ - equal(a2, b) { - return this.compare(a2, b) === 0; - } - /** - * Checks if variable `a` is greater than `b` - * - * @param {*} a - * @param {*} b - * - * @return {boolean} - */ - greaterThan(a2, b) { - return this.compare(a2, b) > 0; - } - /** - * Checks if variable `a` is greater than or equal to `b` - * - * @param {*} a - * @param {*} b - * - * @return {boolean} - */ - greaterThanOrEqual(a2, b) { - return this.greaterThan(a2, b) || this.equal(a2, b); - } - /** - * Checks if variable `a` is less than or equal to `b` - * - * @param {*} a - * @param {*} b - * - * @return {boolean} - */ - lessThanOrEqual(a2, b) { - return this.lessThan(a2, b) || this.equal(a2, b); - } - /** - * Checks if variable a is less than b - * - * @param {*} a - * @param {*} b - * - * @return {boolean} - */ - lessThan(a2, b) { - return this.compare(a2, b) < 0; - } - }; - - // test/cases/util/comparator.mjs - describe("Comparator", function() { - describe("create new instance", function() { - it("should return a comparator object", function() { - expect(new Comparator()).to.be.a("object"); - }); - it("should return a comparator object", function() { - expect(new Comparator(function() { - })).to.be.a("object"); - }); - it("should throw TypeError", function() { - expect(() => new Comparator(true)).to.throw(TypeError); - }); - it("should throw TypeError", function() { - expect(() => new Comparator("test")).to.throw(TypeError); - }); - }); - describe("equal()", function() { - [ - ["test1", "test", false], - [5.1, 5, false], - [5.1, 5.1, true], - [true, true, true], - [false, true, false], - [false, false, true], - [-4, -4, true] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - let c = data.shift(); - it("should compare " + a2 + " and " + b + " return " + c, function() { - expect(new Comparator().equal(a2, b)).is.equal(c); - }); - }); - }); - describe("equal()", function() { - [ - ["test1", true], - ["test1", 5], - ["test1", null], - ["test1", parseInt("a")], - [false, 5], - [void 0, null] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - it("should compare " + a2 + " and " + b + " throw TypeError", function() { - expect(() => new Comparator().equal(a2, b)).to.throw(TypeError); - }); - }); - }); - describe("greaterThan()", function() { - [ - ["test1", "test", true], - [5.1, 5, true], - [5.1, 5.1, false], - [true, true, false], - [false, true, false], - [false, false, false], - [-4, -4, false], - [-4, 4, false] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - let c = data.shift(); - it("should compare " + a2 + " and " + b + " return " + c, function() { - expect(new Comparator().greaterThan(a2, b)).is.equal(c); - }); - }); - }); - describe("reverse().greaterThan()", function() { - [ - ["test1", "test", true], - [5.1, 5, true], - [5.1, 5.1, false], - [true, true, false], - [false, true, false], - [false, false, false], - [-4, -4, false], - [-4, 4, false] - ].forEach(function(data) { - let b = data.shift(); - let a2 = data.shift(); - let c = data.shift(); - it("should compare " + a2 + " and " + b + " return " + c, function() { - expect(new Comparator().reverse().greaterThan(a2, b)).is.equal(c); - }); - }); - }); - describe("greaterThanOrEqual()", function() { - [ - ["test1", "test", true], - [5.1, 5, true], - [5.1, 5.1, true], - [true, true, true], - [false, true, false], - [false, false, true], - [-4, -4, true], - [-4, 4, false] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - let c = data.shift(); - it("should compare " + a2 + " and " + b + " return " + c, function() { - expect(new Comparator().greaterThanOrEqual(a2, b)).is.equal(c); - }); - }); - }); - describe("lessThan()", function() { - [ - ["test1", "test", true], - [5.1, 5, true], - [5.1, 5.1, false], - [true, true, false], - [false, true, false], - [false, false, false], - [-4, -4, false], - [-4, 4, false] - ].forEach(function(data) { - let b = data.shift(); - let a2 = data.shift(); - let c = data.shift(); - it("should compare " + a2 + " and " + b + " return " + c, function() { - expect(new Comparator().lessThan(a2, b)).is.equal(c); - }); - }); - }); - describe("documentations", function() { - it("should run ...", function() { - expect(new Comparator().lessThanOrEqual(2, 5)).to.be.true; - expect(new Comparator().greaterThan(4, 2)).to.be.true; - expect(new Comparator().equal(4, 4)).to.be.true; - expect(new Comparator().equal(4, 5)).to.be.false; - }); - it("should run with own function ...", function() { - expect(new Comparator(function(a2, b) { - if (a2.v === b.v) - return 0; - return a2.v < b.v ? -1 : 1; - }).equal({ v: 2 }, { v: 2 })).to.be.true; - }); - }); - describe("lessThanOrEqual()", function() { - [ - ["test1", "test", true], - [5.1, 5, true], - [5.1, 5.1, true], - [true, true, true], - [false, true, false], - [false, false, true], - [-4, -4, true], - [-4, 4, false] - ].forEach(function(data) { - let b = data.shift(); - let a2 = data.shift(); - let c = data.shift(); - it("should compare " + a2 + " and " + b + " return " + c, function() { - expect(new Comparator().lessThanOrEqual(a2, b)).is.equal(c); - }); - }); - }); - }); - - // test/cases/util/clone.mjs - init_clone(); - describe("Clone", function() { - class A { - constructor(b) { - this.b = b; - } - a() { - } - } - class B { - constructor(b) { - this.b = b; - } - a() { - } - getClone() { - return "DONE"; - } - } - describe(".clone(B) with getClone", function() { - it(".clone(B) should object", function() { - let b = new B({ - x: { - y: 1, - d: new A(1), - z: () => { - } - } - }); - let r = clone(b); - expect(b).to.be.instanceOf(B); - expect(r).not.equal(b); - expect(JSON.stringify(r)).equal(JSON.stringify("DONE")); - }); - }); - describe(".clone(A)", function() { - it(".clone(A) should object", function() { - let a2 = new A({ - x: { - y: 1, - d: new A(1), - z: () => { - } - } - }); - let b = clone(a2); - expect(a2).to.be.instanceOf(A); - expect(b).to.be.instanceOf(A); - expect(b).not.equal(a2); - expect(JSON.stringify(a2)).equal(JSON.stringify(b)); - }); - }); - if (typeof DocumentFragment === "object") { - describe(".clone(DocumentFragment)", function() { - it(".clone(DocumentFragment) should same DocumentFragment", function() { - let a2 = document.createDocumentFragment(); - let b = clone(a2); - expect(b).equal(a2); - }); - }); - } - describe(".clone(null)", function() { - it(".clone(null) should null", function() { - let a2 = null; - let b = clone(a2); - expect(b).equal(a2); - expect(b).to.be.null; - expect(a2).to.be.null; - }); - }); - describe(".clone(undefined)", function() { - it(".clone(undefined) should undefined", function() { - let a2 = void 0; - let b = clone(a2); - expect(a2 === b).to.be.true; - expect(typeof b === "undefined").to.be.true; - expect(a2 === void 0).to.be.true; - expect(b === void 0).to.be.true; - }); - }); - describe(".clone(object)", function() { - it(".clone({}) should object", function() { - let a2 = {}; - let b = clone(a2); - expect(typeof b === "object").to.be.true; - }); - it(".clone({x:1}) should object", function() { - let a2 = { x: 1 }; - let b = clone(a2); - expect(a2.x).is.equal(b.x); - }); - }); - describe(".clone(function)", function() { - it(".clone(function) should function", function() { - let a2 = () => { - }; - let b = clone(a2); - expect(typeof b === "function").to.be.true; - }); - }); - describe(".clone()", function() { - [ - ["test1", "string"], - [void 0, "undefined"], - [null, "object"], - // typeof null results in 'object'. https://2ality.com/2013/10/typeof-null.html - [() => { - }, "function"], - [2, "number"], - [false, "boolean"], - [true, "boolean"], - [4.5, "number"], - [{}, "object"], - [[1, 2, 3], "object"], - // array ist auch type object - [Symbol("foo"), "symbol"] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - it(".clone(" + JSON.stringify(a2) + ") should " + b + " ", function() { - let c = clone(a2); - expect(typeof c).is.equal(b); - }); - }); - }); - }); - - // ../application/source/util/processing.mjs - init_constants(); - init_base(); - init_global(); - init_is(); - init_queue(); - init_validate(); - var Callback = class { - /** - * - * @param {function} callback - * @param {int|undefined} time - * @throws {TypeError} value is not a function - * @throws {TypeError} value is not an integer - * @private - */ - constructor(callback, time) { - this[internalSymbol] = { - callback: validateFunction(callback), - time: validateInteger(time ?? 0) - }; - } - /** - * @private - * @param {*} data - * @return {Promise} - */ - run(data) { - const self2 = this; - return new Promise((resolve, reject) => { - getGlobalFunction("setTimeout")(() => { - try { - resolve(self2[internalSymbol].callback(data)); - } catch (e) { - reject(e); - } - }, self2[internalSymbol].time); - }); - } - }; - var Processing = class extends Base { - /** - * Create new Processing - * - * Functions and timeouts can be passed. If a timeout is passed, it applies to all further functions. - * In the example - * - * `timeout1, function1, function2, function3, timeout2, function4` - * - * the timeout1 is valid for the functions 1, 2 and 3 and the timeout2 for the function4. - * - * So the execution time is timeout1+timeout1+timeout1+timeout2 - * - * @param {int} timeout Timeout - * @param {function} callback Callback - * @throw {TypeError} the arguments must be either integer or functions - */ - constructor(...args) { - super(); - this[internalSymbol] = { - queue: new Queue() - }; - let time = 0; - if (typeof args !== "object" || args[0] === null) { - throw new TypeError("the arguments must be either integer or functions"); - } - for (const [, arg] of Object.entries(args)) { - if (isInteger(arg) && arg >= 0) { - time = arg; - } else if (isFunction(arg)) { - this[internalSymbol].queue.add(new Callback(arg, time)); - } else { - throw new TypeError("the arguments must be either integer or functions"); - } - } - } - /** - * Adds a function with the desired timeout - * If no timeout is specified, the timeout of the previous function is used. - * - * @param {function} callback - * @param {int|undefined} time - * @throws {TypeError} value is not a function - * @throws {TypeError} value is not an integer - */ - add(callback, time) { - this[internalSymbol].queue.add(new Callback(callback, time)); - return this; - } - /** - * Executes the defined functions in order. - * - * @param {*} data - * @return {Promise} - */ - run(data) { - const self2 = this; - if (this[internalSymbol].queue.isEmpty()) { - return Promise.resolve(data); - } - return this[internalSymbol].queue.poll().run(data).then((result) => { - return self2.run(result); - }); - } - }; - - // test/cases/util/processing.mjs - describe("Processing", function() { - describe("run instance", function() { - it("should run many function", function(done) { - let counter = 0; - let t = +/* @__PURE__ */ new Date(); - const desiredDelay = 200; - this.timeout(desiredDelay + 100); - new Processing((v) => { - counter++; - return v; - }, (v) => { - counter++; - return v; - }, function(v) { - counter++; - return v; - }, desiredDelay, function(v) { - counter++; - return v; - }).run("test").then((v) => { - try { - expect(counter).to.be.equal(4); - expect(v === "test").to.be.true; - expect(+/* @__PURE__ */ new Date() > t + desiredDelay + 1).to.be.true; - } catch (e) { - return done(e); - } - done(); - }); - }); - it("should run one function", function(done) { - let counter = 0; - new Processing((value) => { - counter++; - return value; - }).run("test").then((v) => { - try { - expect(v === "test").to.be.true; - } catch (e) { - return done(e); - } - done(); - }).catch((e) => done(e)); - }); - it("should run no function", function(done) { - let counter = 0; - new Processing().run("test").then((v) => { - try { - expect(v === "test").to.be.true; - } catch (e) { - return done(e); - } - done(); - }).catch((e) => done(e)); - }); - }); - describe("create new instance", function() { - it("should return a Processing object", function() { - expect(new Processing()).to.be.a("object"); - }); - it("should return a Processing object", function() { - expect(new Processing(function() { - })).to.be.a("object"); - }); - it("should throw TypeError", function() { - expect(() => new Processing(true)).to.throw(TypeError); - }); - it("should throw TypeError", function() { - expect(() => new Processing("test")).to.throw(TypeError); - }); - }); - }); - - // test/cases/data/extend.mjs - init_extend(); - var MockForExtends = class { - constructor() { - } - }; - describe("extend", function() { - [ - [ - '{"thekey":{}}', - {}, - { thekey: new MockForExtends() } - ], - [ - '{"a":{"b":["1","2","3"]}}', - { - a: { - b: [ - "1", - "2", - "3" - ] - } - }, - { - a: { - b: [] - } - } - ], - [ - '{"a":{"b":1,"d":1}}', - { - a: { - b: 1 - } - }, - { - a: { - d: 1 - } - } - ], - [ - '{"a":{"b":1,"d":{"x":["car"],"f":true,"g":[]}}}', - {}, - { - a: { - b: 1, - d: { x: ["car"] } - } - }, - { - a: { - d: { - f: true, - g: [] - } - } - } - ] - ].forEach(function(data) { - let d = data.shift(); - let a2 = data; - it(".extend(" + JSON.stringify(a2) + ") should result in " + d, function() { - let x = extend.apply(this, a2); - expect(JSON.stringify(x)).is.equal(d); - }); - }); - [ - [ - {}, - { - a: { - b: 1, - d: ["car"] - } - }, - { - a: { - d: { - f: true, - g: [] - } - } - } - ], - [ - { - a: {} - }, - { - a: [] - } - ] - ].forEach(function(data) { - let a2 = data; - it(".extend(" + JSON.stringify(a2) + ") should throw Error ", function() { - expect(() => extend.apply(this, a2)).to.throw(Error); - }); - }); - }); - - // test/cases/data/pipe.mjs - init_pipe(); - describe("Pipe", function() { - before(function(done) { - let promises = []; - if (!globalThis["crypto"]) { - promises.push(Promise.resolve().then(() => (init_webcrypto_es(), webcrypto_es_exports)).then((m) => { - globalThis["crypto"] = new m.Crypto(); - return true; - })); - } - Promise.all(promises).then(() => { - done(); - }); - }); - describe("run different pipes", function() { - [ - ["path:b | if:x:\\ ", { a: true }, " "], - // '\\ '.length ↦ 2 - ["path:a | if:x:\\ ", { a: true }, "x"], - ["nop", "abcdefghijklmnop", "abcdefghijklmnop"] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - let c = data.shift(); - it("Pipe.run(" + JSON.stringify(a2) + ").run(" + JSON.stringify(b) + ") should return " + JSON.stringify(c), function() { - let t = new Pipe(a2); - const r = t.run(b); - expect(r).to.be.eql(c); - }); - }); - }); - describe("new Pipe should create new Instance", function() { - it("should return Instance", function() { - expect(new Pipe("")).to.be.instanceOf(Pipe); - }); - it("should return Instance", function() { - expect(new Pipe("index:a|toupper |prefix:a").run({ a: "test" })).to.be.equal("aTEST"); - }); - [ - ["index:a|toupper |prefix:a", { a: "test" }, "aTEST"], - ["path:a.b.c.d | toupper | prefix:Hello\\ ", { - a: { - b: { - c: { - d: "world" - } - } - } - }, "Hello WORLD"], - ["path:a.b.c|index:d|toupper |suffix:x", { a: { b: { c: { d: "test" } } } }, "TESTx"] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - let c = data.shift(); - it("new Pipe(" + JSON.stringify(a2) + ").run(" + JSON.stringify(b) + ") should return " + JSON.stringify(c) + " ", function() { - let t = new Pipe(a2); - expect(t.run(b)).to.be.equal(c); - }); - }); - }); - describe("new Pipe and locale", function() { - let html16 = ` -<div id="mock-translations"></div> -<script type="application/json" data-monster-role="translations"> - { - "51": "xyz", - "52": "abc", - "53": "def" - } -<\/script> -`; - beforeEach((done) => { - let mocks = document.getElementById("mocks"); - mocks.innerHTML = html16; - let elem = document.getElementById("mock-translations"); - Embed.assignTranslationsToElement(elem).then((o) => { - done(); - }).catch((e) => { - done(e); - }); - }); - afterEach(() => { - let mocks = document.getElementById("mocks"); - mocks.innerHTML = ""; - }); - before(function(done) { - initJSDOM().then(() => { - done(); - }); - }); - [ - ["path:status | tostring | i18n", { status: 51 }, "xyz"] - ].forEach(function(data) { - let pipe = data.shift(); - let obj = data.shift(); - let expected = data.shift(); - it("should transform(" + pipe + ").run(" + JSON.stringify(obj) + ") return " + JSON.stringify(expected), function() { - let t = new Pipe(pipe); - expect(t.run(obj)).to.be.equal(expected); - }); - }); - }); - }); - - // ../application/source/data/buildmap.mjs - init_is(); - init_validate(); - init_clone(); - init_pathfinder(); - var PARENT = "^"; - function buildMap(subject, selector, valueTemplate, keyTemplate, filter) { - return assembleParts(subject, selector, filter, function(v, k, m) { - k = build(v, keyTemplate, k); - v = build(v, valueTemplate); - this.set(k, v); - }); - } - function assembleParts(subject, selector, filter, callback) { - const result = /* @__PURE__ */ new Map(); - let map; - if (isFunction(selector)) { - map = selector(subject); - if (!(map instanceof Map)) { - throw new TypeError("the selector callback must return a map"); - } - } else if (isString(selector)) { - map = /* @__PURE__ */ new Map(); - buildFlatMap.call(map, subject, selector); - } else { - throw new TypeError("selector is neither a string nor a function"); - } - if (!(map instanceof Map)) { - return result; - } - map.forEach((v, k, m) => { - if (isFunction(filter)) { - if (filter.call(m, v, k) !== true) - return; - } - callback.call(result, v, k, m); - }); - return result; - } - function buildFlatMap(subject, selector, key, parentMap) { - const result = this; - const currentMap = /* @__PURE__ */ new Map(); - const resultLength = result.size; - if (key === void 0) - key = []; - let parts = selector.split(DELIMITER); - let current = ""; - let currentPath = []; - do { - current = parts.shift(); - currentPath.push(current); - if (current === WILDCARD) { - let finder = new Pathfinder(subject); - let map; - try { - map = finder.getVia(currentPath.join(DELIMITER)); - } catch (e) { - let a2 = e; - map = /* @__PURE__ */ new Map(); - } - for (const [k, o] of map) { - let copyKey = clone(key); - currentPath.map((a2) => { - copyKey.push(a2 === WILDCARD ? k : a2); - }); - let kk = copyKey.join(DELIMITER); - let sub = buildFlatMap.call(result, o, parts.join(DELIMITER), copyKey, o); - if (isObject(sub) && parentMap !== void 0) { - sub[PARENT] = parentMap; - } - currentMap.set(kk, sub); - } - } - } while (parts.length > 0); - if (resultLength === result.size) { - for (const [k, o] of currentMap) { - result.set(k, o); - } - } - return subject; - } - function build(subject, definition, defaultValue) { - if (definition === void 0) - return defaultValue ? defaultValue : subject; - validateString(definition); - const regexp = /(?<placeholder>\${(?<path>[a-z\^A-Z.\-_0-9]*)})/gm; - const array = [...definition.matchAll(regexp)]; - let finder = new Pathfinder(subject); - if (array.length === 0) { - return finder.getVia(definition); - } - array.forEach((a2) => { - let groups = a2?.["groups"]; - let placeholder = groups?.["placeholder"]; - if (placeholder === void 0) - return; - let path = groups?.["path"]; - let v = finder.getVia(path); - if (v === void 0) - v = defaultValue; - definition = definition.replaceAll(placeholder, v); - }); - return definition; - } - - // test/cases/data/buildmap.mjs - describe("buildMap", function() { - let convertMapResult = function(r) { - if (r instanceof Map) { - r = Object.fromEntries(r); - if (r instanceof Array) { - r = r.map((e) => { - return convertMapResult(e); - }); - } else if (typeof r === "object") { - for (const [k, o] of Object.entries(r)) { - r[k] = convertMapResult(o); - } - } - } - return r; - }; - describe("build Map with callback", function() { - it("definition should return map with sub and parent keys", function() { - let obj = { - "data": [ - { - "id": 10, - "name": "Cassandra", - "enrichment": { - variants: [ - { - sku: 1, - label: "XXS", - price: [ - { vk: "12.12 \u20AC" }, - { vk: "12.12 \u20AC" } - ] - }, - { - sku: 2, - label: "XS", - price: [ - { vk: "22.12 \u20AC" }, - { vk: "22.12 \u20AC" } - ] - }, - { - sku: 3, - label: "S", - price: [ - { vk: "32.12 \u20AC" }, - { vk: "32.12 \u20AC" } - ] - }, - { - sku: 4, - label: "L", - price: [ - { vk: "42.12 \u20AC" }, - { vk: "42.12 \u20AC" } - ] - } - ] - } - }, - { - "id": 20, - "name": "Yessey!", - "enrichment": { - variants: [ - { - sku: 1, - label: "XXS", - price: [ - { vk: "12.12 \u20AC" }, - { vk: "12.12 \u20AC" } - ] - }, - { - sku: 2, - label: "XS", - price: [ - { vk: "22.12 \u20AC" }, - { vk: "22.12 \u20AC" } - ] - }, - { - sku: 3, - label: "S", - price: [ - { vk: "32.12 \u20AC" }, - { vk: "32.12 \u20AC" } - ] - }, - { - sku: 4, - label: "L", - price: [ - { vk: "42.12 \u20AC" }, - { vk: "42.12 \u20AC" } - ] - } - ] - } - } - ] - }; - let callback = function(subject) { - let m = /* @__PURE__ */ new Map(); - for (const [i2, b] of Object.entries(subject.data)) { - let key1 = i2; - for (const [j, c] of Object.entries(b.enrichment.variants)) { - let key2 = j; - for (const [k, d] of Object.entries(c.price)) { - let key3 = k; - d.name = b.name; - d.label = c.label; - d.id = [key1, key2, key3].join("."); - m.set(d.id, d); - } - } - } - return m; - }; - let map = buildMap(obj, callback, "${name} ${label}", "${id}"); - let i = convertMapResult(map); - expect(JSON.stringify(i)).to.be.equal('{"0.0.0":"Cassandra XXS","0.0.1":"Cassandra XXS","0.1.0":"Cassandra XS","0.1.1":"Cassandra XS","0.2.0":"Cassandra S","0.2.1":"Cassandra S","0.3.0":"Cassandra L","0.3.1":"Cassandra L","1.0.0":"Yessey! XXS","1.0.1":"Yessey! XXS","1.1.0":"Yessey! XS","1.1.1":"Yessey! XS","1.2.0":"Yessey! S","1.2.1":"Yessey! S","1.3.0":"Yessey! L","1.3.1":"Yessey! L"}'); - }); - }); - describe("build submap with *", function() { - it('definition should return {"10":"Cassandra 10","20":"Yessey! 20"}', function() { - let obj = { - "data": [ - { - "id": 10, - "name": "Cassandra" - }, - { - "id": 20, - "name": "Yessey!" - } - ] - }; - let map = buildMap(obj, "data.*", "${name} ${id}", "${id}"); - let i = convertMapResult(map); - expect(JSON.stringify(i)).to.be.equal('{"10":"Cassandra 10","20":"Yessey! 20"}'); - }); - }); - describe("build submap with **", function() { - it("definition should return Map", function() { - let obj = { - "data": [ - { - "id": 10, - "name": "Cassandra", - "enrichment": { - variants: [ - { - sku: 1, - label: "XXS", - price: [ - { vk: "12.12 \u20AC", id: 1 }, - { vk: "12.12 \u20AC", id: 2 } - ] - }, - { - sku: 2, - label: "XS", - price: [ - { vk: "22.12 \u20AC", id: 3 }, - { vk: "22.12 \u20AC", id: 4 } - ] - }, - { - sku: 3, - label: "S", - price: [ - { vk: "32.12 \u20AC", id: 5 }, - { vk: "32.12 \u20AC", id: 6 } - ] - }, - { - sku: 4, - label: "L", - price: [ - { vk: "42.12 \u20AC", id: 7 }, - { vk: "42.12 \u20AC", id: 8 } - ] - } - ] - } - }, - { - "id": 20, - "name": "Yessey!", - "enrichment": { - variants: [ - { - sku: 1, - label: "XXS", - price: [ - { vk: "12.12 \u20AC", id: 9 }, - { vk: "12.12 \u20AC", id: 10 } - ] - }, - { - sku: 2, - label: "XS", - price: [ - { vk: "22.12 \u20AC", id: 11 }, - { vk: "22.12 \u20AC", id: 12 } - ] - }, - { - sku: 3, - label: "S", - price: [ - { vk: "32.12 \u20AC", id: 13 }, - { vk: "32.12 \u20AC", id: 14 } - ] - }, - { - sku: 4, - label: "L", - price: [ - { vk: "42.12 \u20AC", id: 15 }, - { vk: "42.12 \u20AC", id: 16 }, - { vk: "44.12 \u20AC", id: 17 } - ] - } - ] - } - } - ] - }; - let map = buildMap(obj, "data.*.enrichment.variants.*.price.*", "${vk} ${^.label} ${^.^.name}", "${^.^.sku}"); - let i = convertMapResult(map); - expect(JSON.stringify(i)).to.be.equal('{"data.0.enrichment.variants.0.price.0":"12.12 \u20AC XXS Cassandra","data.0.enrichment.variants.0.price.1":"12.12 \u20AC XXS Cassandra","data.0.enrichment.variants.1.price.0":"22.12 \u20AC XS Cassandra","data.0.enrichment.variants.1.price.1":"22.12 \u20AC XS Cassandra","data.0.enrichment.variants.2.price.0":"32.12 \u20AC S Cassandra","data.0.enrichment.variants.2.price.1":"32.12 \u20AC S Cassandra","data.0.enrichment.variants.3.price.0":"42.12 \u20AC L Cassandra","data.0.enrichment.variants.3.price.1":"42.12 \u20AC L Cassandra","data.1.enrichment.variants.0.price.0":"12.12 \u20AC XXS Yessey!","data.1.enrichment.variants.0.price.1":"12.12 \u20AC XXS Yessey!","data.1.enrichment.variants.1.price.0":"22.12 \u20AC XS Yessey!","data.1.enrichment.variants.1.price.1":"22.12 \u20AC XS Yessey!","data.1.enrichment.variants.2.price.0":"32.12 \u20AC S Yessey!","data.1.enrichment.variants.2.price.1":"32.12 \u20AC S Yessey!","data.1.enrichment.variants.3.price.0":"42.12 \u20AC L Yessey!","data.1.enrichment.variants.3.price.1":"42.12 \u20AC L Yessey!","data.1.enrichment.variants.3.price.2":"44.12 \u20AC L Yessey!"}'); - }); - }); - describe("examplecode", function() { - it("should execute example code", function() { - let obj = { - "data": [ - { - "id": 10, - "name": "Cassandra", - "address": { - "street": "493-4105 Vulputate Street", - "city": "Saumur", - "zip": "52628" - } - }, - { - "id": 20, - "name": "Holly", - "address": { - "street": "1762 Eget Rd.", - "city": "Schwalbach", - "zip": "952340" - } - }, - { - "id": 30, - "name": "Guy", - "address": { - "street": "957-388 Sollicitudin Avenue", - "city": "Panchi\xE0", - "zip": "420729" - } - } - ] - }; - let map; - map = buildMap(obj, "data.*", "${name} (${address.zip} ${address.city})", "id"); - expect(map).to.be.instanceOf(Map); - map = buildMap(obj, "data.*", "${name} (${address.zip} ${address.city})"); - expect(map).to.be.instanceOf(Map); - map = buildMap(obj, "data.*", "${name} (${address.zip} ${address.city})", "id", function(value, key) { - return value["id"] >= 20 ? true : false; - }); - expect(map).to.be.instanceOf(Map); - }); - }); - describe("buildmap()", function() { - let obj1 = { - dataset: { - "10082": { - name: "Test 1", - address: "Here 1" - }, - "10084": { - name: "Test 2", - address: "Here 2" - } - } - }; - it("should return Map Instance.", function() { - expect(buildMap({}, "")).to.be.instanceOf(Map); - }); - [ - [obj1, "dataset.*", "address", '{"dataset.10082":"Here 1","dataset.10084":"Here 2"}'], - [obj1, "x", void 0, "{}"], - [obj1, "dataset.*", "name", '{"dataset.10082":"Test 1","dataset.10084":"Test 2"}'] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - let c = data.shift(); - let d = data.shift(); - it("buildMap(" + JSON.stringify(a2) + "," + JSON.stringify(b) + "," + JSON.stringify(c) + ") should return " + JSON.stringify(d) + " ", function() { - let t = buildMap(a2, b, c); - let m = JSON.stringify(convertMapResult(t)); - expect(m).to.be.equal(d); - }); - }); - }); - }); - - // ../application/source/data/datasource.mjs - init_constants(); - init_constants(); - init_base(); - init_dataurl(); - init_is(); - init_proxyobserver(); - init_validate(); - init_extend(); - init_pathfinder(); - var internalDataSymbol = Symbol.for("@schukai/monster/data/datasource/@@data"); - var Datasource = class extends Base { - /** - * creates a new datasource - * - */ - constructor() { - super(); - this[internalSymbol] = new ProxyObserver({ - options: extend({}, this.defaults) - }); - this[internalDataSymbol] = new ProxyObserver({}); - } - /** - * attach a new observer - * - * @param {Observer} observer - * @returns {Datasource} - */ - attachObserver(observer) { - this[internalDataSymbol].attachObserver(observer); - return this; - } - /** - * detach a observer - * - * @param {Observer} observer - * @returns {Datasource} - */ - detachObserver(observer) { - this[internalDataSymbol].detachObserver(observer); - return this; - } - /** - * @param {Observer} observer - * @returns {boolean} - */ - containsObserver(observer) { - return this[internalDataSymbol].containsObserver(observer); - } - /** - * Derived classes can override and extend this method as follows. - * - * ``` - * get defaults() { - * return Object.assign({}, super.defaults, { - * myValue:true - * }); - * } - * ``` - */ - get defaults() { - return {}; - } - /** - * Set option - * - * @param {string} path - * @param {*} value - * @return {Datasource} - */ - setOption(path, value) { - new Pathfinder(this[internalSymbol].getSubject()["options"]).setVia(path, value); - return this; - } - /** - * @param {string|object} options - * @return {Datasource} - * @throws {Error} the options does not contain a valid json definition - */ - setOptions(options) { - if (isString(options)) { - options = parseOptionsJSON3(options); - } - const self2 = this; - extend(self2[internalSymbol].getSubject()["options"], self2.defaults, options); - return self2; - } - /** - * nested options can be specified by path `a.b.c` - * - * @param {string} path - * @param {*} defaultValue - * @return {*} - */ - getOption(path, defaultValue) { - let value; - try { - value = new Pathfinder(this[internalSymbol].getRealSubject()["options"]).getVia(path); - } catch (e) { - } - if (value === void 0) - return defaultValue; - return value; - } - /** - * @throws {Error} this method must be implemented by derived classes. - * @return {Promise} - */ - read() { - throw new Error("this method must be implemented by derived classes"); - } - /** - * @throws {Error} this method must be implemented by derived classes. - * @return {Promise} - */ - write() { - throw new Error("this method must be implemented by derived classes"); - } - /** - * Returns real object - * - * @return {Object|Array} - */ - get() { - const self2 = this; - return self2[internalDataSymbol].getRealSubject(); - } - /** - * @param {Object|Array} data - * @return {Datasource} - */ - set(data) { - const self2 = this; - self2[internalDataSymbol].setSubject(data); - return self2; - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/data/datasource"); - } - }; - function parseOptionsJSON3(data) { - if (isString(data)) { - try { - let dataUrl = parseDataURL(data); - data = dataUrl.content; - } catch (e) { - } - try { - let obj = JSON.parse(data); - validateObject(obj); - return obj; - } catch (e) { - throw new Error(`the options does not contain a valid json definition (actual: ${data}).`); - } - } - return {}; - } - - // test/cases/data/datasource.mjs - describe("Datasource", function() { - it("should instance of Datasource ", function() { - expect(new Datasource()).to.be.instanceof(Datasource); - }); - describe("Options", function() { - it("setOption should change value", function() { - const datasource = new Datasource(); - expect(datasource.getOption("default")).to.be.undefined; - datasource.setOption("default", true); - expect(datasource.getOption("default")).to.be.true; - }); - it("setOptions should set all values", function() { - const datasource = new Datasource(); - expect(datasource.getOption("default")).to.be.undefined; - datasource.setOptions({ default: true }); - expect(datasource.getOption("default")).to.be.true; - }); - }); - describe("rw", function() { - const datasource = new Datasource(); - it("read should throw exeption", function() { - expect(() => datasource.read()).to.throw(Error); - }); - it("write should throw exeption", function() { - expect(() => datasource.read()).to.throw(Error); - }); - }); - describe("get/set", function() { - const datasource = new Datasource(); - it("get should return undefined", function() { - expect(datasource.get()).to.be.eql({}); - }); - it("write should throw exeption", function() { - expect(datasource.get()).to.be.eql({}); - expect(datasource.set({ a: "myvalue" })).to.be.instanceof(Datasource); - expect(datasource.get()).to.be.eql({ a: "myvalue" }); - }); - }); - }); - - // ../application/source/data/buildtree.mjs - init_is(); - init_extend(); - var parentSymbol = Symbol("parent"); - var rootSymbol = Symbol("root"); - function buildTree(subject, selector, idKey, parentIDKey, options) { - const nodes = /* @__PURE__ */ new Map(); - if (!isObject(options)) { - options = {}; - } - options = extend( - {}, - { - rootReferences: [null, void 0], - filter: void 0 - }, - options - ); - const filter = options?.filter; - let rootReferences = options.rootReferences; - if (!isArray(rootReferences)) { - rootReferences = [rootReferences]; - } - const childMap = assembleParts(subject, selector, filter, function(o, k, m) { - const key = o?.[idKey]; - let ref = o?.[parentIDKey]; - if (rootReferences.indexOf(ref) !== -1) - ref = rootSymbol; - if (key === void 0) { - throw new Error("the object has no value for the specified id"); - } - o[parentSymbol] = ref; - const node = new Node2(o); - this.has(ref) ? this.get(ref).add(node) : this.set(ref, new NodeList2().add(node)); - nodes.set(key, node); - }); - nodes.forEach((node) => { - let id = node?.["value"]?.[idKey]; - if (childMap.has(id)) { - node.childNodes = childMap.get(id); - childMap.delete(id); - } - }); - const list = new NodeList2(); - childMap.forEach((s) => { - if (s instanceof Set) { - s.forEach((n) => { - list.add(n); - }); - } - }); - return list; - } - - // test/cases/data/buildtree.mjs - describe("buildTree", function() { - describe("example", function() { - it("should run example", function() { - const objects = { - dataset: { - "1": { - id: "1", - name: "vehicle", - parent: null - }, - "2": { - id: "2", - name: "car", - parent: "1" - }, - "3": { - id: "3", - name: "truck", - parent: "1" - }, - "4": { - id: "4", - name: "motorcycle", - parent: "1" - }, - "5": { - id: "5", - name: "SUV", - parent: "2" - }, - "6": { - id: "6", - name: "sports car", - parent: "2" - } - } - }; - const nodes = buildTree(objects, "dataset.*", "id", "parent"); - expect(nodes).to.be.instanceOf(NodeList2); - expect(nodes.length).to.equal(1); - expect(nodes.toString()).to.be.equal('{"id":"1","name":"vehicle","parent":null}\n \u251C{"id":"2","name":"car","parent":"1"}\n | \u251C{"id":"5","name":"SUV","parent":"2"}\n | \u2514{"id":"6","name":"sports car","parent":"2"}\n \u251C{"id":"3","name":"truck","parent":"1"}\n \u2514{"id":"4","name":"motorcycle","parent":"1"}'); - }); - }); - describe("buildTree()", function() { - let obj1 = { - dataset: { - "1": { - id: "1", - name: "Test 1", - address: "Here 1", - parent: null - }, - "2": { - id: "2", - name: "Test 2", - address: "Here 2", - parent: "1" - }, - "3": { - id: "3", - name: "Test 3", - address: "Here 3", - parent: "2" - }, - "4": { - id: "4", - name: "Test 4", - address: "Here 4", - parent: "2" - }, - "5": { - id: "5", - name: "Test 5", - address: "Here 5", - parent: "1" - }, - "6": { - id: "6", - name: "Test 6", - address: "Here 6", - parent: "4" - } - } - }; - it("should return Node Instance.", function() { - expect(buildTree({}, "")).to.be.instanceOf(NodeList2); - }); - [ - [obj1, "dataset.*", '{"id":"1","name":"Test 1","address":"Here 1","parent":null}\n \u251C{"id":"2","name":"Test 2","address":"Here 2","parent":"1"}\n | \u251C{"id":"3","name":"Test 3","address":"Here 3","parent":"2"}\n | \u2514{"id":"4","name":"Test 4","address":"Here 4","parent":"2"}\n | | \u2514{"id":"6","name":"Test 6","address":"Here 6","parent":"4"}\n \u2514{"id":"5","name":"Test 5","address":"Here 5","parent":"1"}'], - [obj1, "x", ""], - [obj1, "dataset.*", '{"id":"1","name":"Test 1","address":"Here 1","parent":null}\n \u251C{"id":"2","name":"Test 2","address":"Here 2","parent":"1"}\n | \u251C{"id":"3","name":"Test 3","address":"Here 3","parent":"2"}\n | \u2514{"id":"4","name":"Test 4","address":"Here 4","parent":"2"}\n | | \u2514{"id":"6","name":"Test 6","address":"Here 6","parent":"4"}\n \u2514{"id":"5","name":"Test 5","address":"Here 5","parent":"1"}'] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - let c = data.shift(); - it("buildTree(" + JSON.stringify(a2) + "," + JSON.stringify(b) + ") should return " + JSON.stringify(c) + " ", function() { - let nodelist = buildTree(a2, b, "id", "parent"); - expect(nodelist.toString()).to.be.eql(c); - }); - }); - }); - describe("buildTree() test 2", function() { - let obj1 = { - dataset: { - "1": { - id: "1", - name: "Test 1", - address: "Here 1", - parent: "2" - }, - "2": { - id: "2", - name: "Test 2", - address: "Here 2", - parent: "0" - }, - "3": { - id: "3", - name: "Test 3", - address: "Here 3", - parent: "2" - }, - "4": { - id: "4", - name: "Test 4", - address: "Here 4", - parent: "0" - }, - "5": { - id: "5", - name: "Test 5", - address: "Here 5", - parent: "0" - }, - "6": { - id: "6", - name: "Test 6", - address: "Here 6", - parent: "4" - }, - "7": { - id: "7", - name: "Test 7", - address: "Here 7", - parent: "1" - } - } - }; - it("should return Node Instance.", function() { - expect(buildTree({}, "")).to.be.instanceOf(NodeList2); - }); - [ - [obj1, "dataset.*", '{"id":"2","name":"Test 2","address":"Here 2","parent":"0"}\n \u251C{"id":"1","name":"Test 1","address":"Here 1","parent":"2"}\n | \u2514{"id":"7","name":"Test 7","address":"Here 7","parent":"1"}\n \u2514{"id":"3","name":"Test 3","address":"Here 3","parent":"2"}\n{"id":"4","name":"Test 4","address":"Here 4","parent":"0"}\n \u2514{"id":"6","name":"Test 6","address":"Here 6","parent":"4"}\n{"id":"5","name":"Test 5","address":"Here 5","parent":"0"}'], - [obj1, "x", ""] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - let c = data.shift(); - it("buildTree(" + JSON.stringify(a2) + "," + JSON.stringify(b) + ") should return " + JSON.stringify(c) + " ", function() { - let nodelist = buildTree(a2, b, "id", "parent", { - rootReferences: ["0"] - }); - expect(nodelist.toString()).to.be.equal(c); - }); - }); - }); - }); - - // test/cases/data/transformer.mjs - init_transformer(); - describe("Transformer", function() { - before(function(done) { - let promises = []; - promises.push(initJSDOM()); - if (!globalThis["crypto"]) { - promises.push(Promise.resolve().then(() => (init_webcrypto_es(), webcrypto_es_exports)).then((m) => { - globalThis["crypto"] = new m.Crypto(); - return true; - })); - } - Promise.all(promises).then(() => { - done(); - }); - }); - describe("Transformer.run()", function() { - [ - ["equals:a", "a", true], - ["equals:a", "b", false], - ["equals:3", 3, true], - ["equals:3", 6, false], - ["equals:on", true, true], - ["equals:true", true, true], - ["equals:on", false, false], - ["equals:true", false, false], - ["equals:off", false, true], - ["equals:false", false, true], - ["equals:off", false, true], - ["equals:false", true, false], - ["equals:3", 3, true], - ["equals:3", 6, false], - ["equals:undefined", void 0, true], - ["equals:undefined", 3, false], - ["equals:null", null, true], - ["equals:null", 3, false], - ["equals:3", 6, false], - ["currency", "EUR0", "0,00\xA0\u20AC"], - ["currency:1:2", "EUR14.25", "14,2\xA0\u20AC"], - ["currency", "EUR14.25", "14,25\xA0\u20AC"], - ["datetime", "2023-02-14 14:12:10", "14.2.2023, 14:12:10"], - ["datetime", "2023-02-14 08:02:01", "14.2.2023, 08:02:01"], - ["has-entries", {}, false], - ["has-entries", { a: 4 }, true], - ["has-entries", [], false], - ["has-entries", "", false], - ["has-entries", [1, 2, 3], true], - ["has-entries", [1], true], - ["has-entries", ["1"], true], - ["has-entries", [true], true], - ["contains:x", "asd wxd sdf", true], - ["contains:x", "asd wd sdf", false], - ["contains:b", ["a", "b", "c"], true], - ["contains:x", ["a", "b", "c"], false], - ["isundefined", "a", false], - ["isundefined", null, false], - ["isundefined", void 0, true], - ["isnull", "a", false], - ["isnull", null, true], - ["isset", null, false], - ["isset", void 0, false], - ["isset", "", true], - ["isnumber", "a", false], - ["isnumber", 4, true], - ["isnumber", 4.5, true], - ["isinteger", 4.5, false], - ["isinteger", 4, true], - ["isfloat", 5.6, true], - ["isfloat", 5, false], - ["isobject", 4, false], - ["isobject", {}, true], - ["isarray", [{}], true], - ["isarray", "a", false], - ["not", true, false], - ["not", false, true], - ["map:a=4:b=5:c=6", "a", "4"], - ["date", "2023-02-14", "14.2.2023"], - ["year", "2023-02-14", 2023], - ["month", "2023-02-14", 2], - ["day", "2023-02-14", 14], - ["weekday", "2023-02-14", 2], - ["minutes", "2023-02-14 06:12:21", 12], - ["seconds", "2023-02-14 06:12:21", 21], - ["hours", "2023-02-14 06:12:21", 6], - ["time", "2023-02-14 06:12:21", "06:12:21"], - ["timestamp", "2023-02-14", 16763328e5], - ["concat:a.b.c:test:a.b.d", { a: { b: { c: 4, d: 6 } } }, "4test6"], - ["concat:a.b.c:\\ \\ :a.b.d", { a: { b: { c: 4, d: 6 } } }, "4 6"], - ["concat:a.b.c:,:a.b.d", { a: { b: { c: 4, d: 6 } } }, "4,6"], - ["concat:a.b.c:,:\\ :a.b.d", { a: { b: { c: 4, d: 6 } } }, "4, 6"], - ["??:a", null, "a"], - ["??:a", void 0, "a"], - ["??:a", "true", "true"], - ["??:a", false, false], - [" if:a: ", false, void 0], - // without \\ - [" if:a:\\ ", false, " "], - [" if:a:\\ ", true, "a"], - ["default:yes", null, "yes"], - ["default:yes", void 0, "yes"], - ["default:1:bool", void 0, true], - ["default:on:bool", void 0, true], - ["default:true:bool", void 0, true], - ["default:yes:bool", void 0, true], - ["default:undefined:bool", void 0, false], - ["default:false:bool", void 0, false], - ["default:1:int", void 0, 1], - ["default:1:string", void 0, "1"], - ["first-key", { a: 1, c: 3, b: 2 }, 1], - ["last-key", { a: 1, c: 3, b: 2 }, 3], - ["nth-last-key:0", { a: 1, c: 3, b: 2 }, 3], - ["nth-last-key:1", { a: 1, c: 3, b: 2 }, 2], - ["nth-last-key:2", { a: 1, c: 3, b: 2 }, 1], - ["nth-key:2", { a: 1, b: 2, c: 3 }, 3], - ["nth-key:0", { c: 3, a: 1, b: 2 }, 1], - ["nth-key:2", { a: 1, c: 3, b: 2 }, 3], - ["prefix:Hello\\ ", "test", "Hello test"], - ["tojson", { a: 4 }, '{"a":4}'], - ["prefix:a\\\\: ", "test", "a\\test"], - ["prefix:a\\ ", "test", "a test"], - ["static:abc:a:b:x", "test", "abc:a:b:x"], - ["tolowercase", "A:b:Cse4", "a:b:cse4"], - ["toupper", "A:b:Cse4", "A:B:CSE4"], - ["tostring", 5, "5"], - ["tostring", [1, 2, 3, {}], "1,2,3,[object Object]"], - ["tointeger", "5", 5], - ["trim", " 5 ", "5"], - ["trim", " a", "a"], - ["trim", " ", ""], - ["rawurlencode", "\xFC\xF6\xE4", "%C3%BC%C3%B6%C3%A4"], - ["call:testcallback:4:5:6", "test", "test456"], - ["plain", "t<br>est", "test"], - ["if:a:b", true, "a"], - ["if:a:b", "on", "a"], - ["if:a:b", "true", "a"], - ["if:a:b", "false", "b"], - ["if:a:b", 9, "a"], - ["if:a:b", "", "b"], - ["if:a:b", void 0, "b"], - ["if:a:b", false, "b"], - ["ucfirst", "car", "Car"], - ["ucfirst", "cAr", "CAr"], - ["default:test", "a", "a"], - ["default:test", void 0, "test"], - ["fromjson", "{}", {}], - ["fromjson", '{"a":1}', { a: 1 }], - ["ucwords", "cAr runs", "CAr Runs"], - ["tointeger", "6", 6], - ["length", "test", 4], - ["to-base64", "Hello World!", "SGVsbG8gV29ybGQh"], - ["from-base64", "SGVsbG8gV29ybGQh", "Hello World!"], - ["to-base64", "test", "dGVzdA=="], - ["from-base64", "dGVzdA==", "test"], - ["prefix:a", "test", "atest"], - ["suffix:a", "test", "testa"], - ["index:a", { a: 4 }, 4], - ["index:2", [2, 4, 7], 7], - ["index:x:test", [2, 4, 7], "test"], - ["path:a.b.c", { a: { b: { c: 4 } } }, 4], - ["path:a.b.d", { a: { b: { c: 4 } } }, void 0], - ["index:a", (/* @__PURE__ */ new Map()).set("a", 5), 5], - ["substring:2:4", "abcdefghijklmnop", "cdef"], - ["nop", "abcdefghijklmnop", "abcdefghijklmnop"] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - let c = data.shift(); - it("Transformer.run(" + JSON.stringify(a2) + ").run(" + JSON.stringify(b) + ") should return " + JSON.stringify(c), function() { - let t = new Transformer(a2); - t.setCallback("testcallback", function(a3, b2, c2, d) { - return a3 + b2 + c2 + d; - }); - const r = t.run(b); - expect(r).to.be.eql(c); - }); - }); - }); - describe("Transformer.run() throws Error", function() { - [ - ["tolowercase", []], - ["tolowercase", {}], - ["tolowercase", 4.5], - ["toupper", true], - ["toupper", 5], - ["tointeger", "a"], - ["trim", 5], - ["trim", true], - ["trim", {}], - ["trim", []], - ["rawurlencode", []], - ["if:a:b", {}], - ["ucwords", {}], - ["ucwords", false], - ["ucwords", 4], - ["path:a.b.c", "", 4], - ["tointeger", {}], - ["base64", {}], - ["fromjson", ""], - ["prefix", {}], - ["suffix", {}], - ["index", "test"], - ["xxxxxx", "test"] - // unsupported command - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - it("Transformer.run(" + JSON.stringify(a2) + ").run(" + JSON.stringify(b) + ") should throw Error ", function() { - let t = new Transformer(a2); - expect(() => t.run(b)).to.throw(Error); - }); - }); - }); - describe('new Transformer().run("uniqid")', function() { - it("should return String", function() { - let t = new Transformer("uniqid"); - expect(t.run("")).to.be.a("string"); - }); - }); - describe('new Transformer().run("default:eyJiIjoxfQ==:object")', function() { - it("should return Object", function() { - let t = new Transformer("default:eyJiIjoxfQ==:object"); - expect(t.run(void 0)).to.eql({ b: 1 }); - }); - }); - describe("new Transformer()", function() { - it("should return instanceof Transformer", function() { - expect(new Transformer("")).to.instanceOf(Transformer); - }); - it("should return instanceof Transformer", function() { - expect(new Transformer("suffix:abc")).to.instanceOf(Transformer); - }); - it("false as argument should throw TypeError", function() { - expect(() => { - new Transformer(false); - }).to.throw(TypeError); - }); - it("object as argument should throw TypeError", function() { - expect(() => { - new Transformer({}); - }).to.throw(TypeError); - }); - }); - describe("i18n", function() { - let html16 = ` -<div id="mock-translations"></div> -<script type="application/json" data-monster-role="translations"> - { - "test1": "xyz", - "test3": { - "other": "xyz" - } - } -<\/script> -`; - beforeEach((done) => { - let mocks = document.getElementById("mocks"); - mocks.innerHTML = html16; - let elem = document.getElementById("mock-translations"); - Embed.assignTranslationsToElement(elem).then((o) => { - done(); - }); - }); - afterEach(() => { - let mocks = document.getElementById("mocks"); - mocks.innerHTML = ""; - }); - before(function(done) { - initJSDOM().then(() => { - done(); - }); - }); - [ - ["i18n:test1", "", "xyz"], - ["i18n:", "test1", "xyz"], - // key by value - ["i18n::", "test1", "xyz"], - // key by value no default - ["i18n::eee", "test2", "eee"], - // key by value with default - ["i18n::ddd", "test2", "ddd"] - // key by value and default - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - let c = data.shift(); - it("should transform(" + a2 + ").run(" + b + ") return " + JSON.stringify(c), function() { - const t = new Transformer(a2); - expect(t.run(b)).to.be.eql(c); - }); - }); - }); - }); - - // test/cases/data/pathfinder.mjs - init_pathfinder(); - describe("Pathfinder", function() { - let convertMapResult = function(r) { - if (r instanceof Map) { - r = Object.fromEntries(r); - if (r instanceof Array) { - r = r.map((e) => { - return convertMapResult(e); - }); - } else if (typeof r === "object") { - for (const [k, o] of Object.entries(r)) { - r[k] = convertMapResult(o); - } - } - } - return r; - }; - describe("with Wildcard and Iterations", function() { - let pf, obj; - beforeEach(function() { - obj = { - a: [ - { - b: [ - { - c: "1-1" - }, - { - c: "1-2" - } - ], - d: "!" - }, - { - b: [ - { - c: "2-1" - }, - { - c: "2-2" - } - ], - d: "?" - } - ] - }; - pf = new Pathfinder(obj); - }); - [ - ["a.*.b.*", '{"0":{"0":{"c":"1-1"},"1":{"c":"1-2"}},"1":{"0":{"c":"2-1"},"1":{"c":"2-2"}}}'], - ["a.*.b", '{"0":[{"c":"1-1"},{"c":"1-2"}],"1":[{"c":"2-1"},{"c":"2-2"}]}'], - ["a.1.b", '[{"c":"2-1"},{"c":"2-2"}]'], - ["a.0.b", '[{"c":"1-1"},{"c":"1-2"}]'] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - it(".setVia(" + a2 + ") should result in " + b, function() { - let r = pf.getVia(a2); - let i = convertMapResult(r); - expect(JSON.stringify(i)).is.equal(b); - }); - }); - }); - describe("api tests", function() { - let pathfinder, object; - class A { - get a() { - return 1; - } - } - beforeEach(() => { - object = { - a: { - b: { - c: [ - 4, - "test1", - false, - void 0, - parseInt("a") - ], - d: void 0, - e: false, - f: [ - { - g: false, - h: 3, - i: ["test2"] - } - ], - j: {}, - k: (/* @__PURE__ */ new Map()).set("m", { n: 3 }), - l: (/* @__PURE__ */ new Set()).add({ n: 4 }) - } - }, - b: new A() - }; - pathfinder = new Pathfinder(object); - }); - describe("create new object", function() { - [ - [12], - [void 0], - [null], - ["test"] - ].forEach(function(data) { - let a2 = data.shift(); - let label = typeof a2; - if (a2 === null) - label = "null"; - it(label + " should throw error", function() { - expect(() => { - new Pathfinder(a2); - }).to.throw(Error); - }); - }); - }); - describe(".setVia(x)", function() { - let pf, obj; - beforeEach(function() { - obj = {}; - pf = new Pathfinder(obj); - }); - [ - ["a.b.0.0.c", true, '{"a":{"b":[[{"c":true}]]}}'], - ["a.b.0.c", true, '{"a":{"b":[{"c":true}]}}'], - ["a.b.3.c", true, '{"a":{"b":[null,null,null,{"c":true}]}}'], - ["a.b.c", true, '{"a":{"b":{"c":true}}}'] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - let c = data.shift(); - it(".setVia(" + a2 + ", " + b + ") should result in " + c, function() { - pf.setVia(a2, b); - expect(JSON.stringify(obj)).is.equal(c); - }); - }); - }); - describe(".setVia()", function() { - let a2; - let b; - let c; - beforeEach(function() { - a2 = "a.x"; - b = "true"; - c = "a.y.d"; - }); - it(".setVia(" + a2 + ", " + b + ") should return Pathfinder", function() { - expect(pathfinder.setVia(a2, b)).is.instanceOf(Pathfinder); - }); - it(".setVia(" + a2 + ", " + b + ") should change object", function() { - pathfinder.setVia(a2, b); - expect(JSON.stringify(object)).is.equal('{"a":{"b":{"c":[4,"test1",false,null,null],"e":false,"f":[{"g":false,"h":3,"i":["test2"]}],"j":{},"k":{},"l":{}},"x":"true"},"b":{}}'); - }); - it(".setVia(" + c + ", " + b + ") should change object", function() { - pathfinder.setVia(c, b); - expect(JSON.stringify(object)).is.equal('{"a":{"b":{"c":[4,"test1",false,null,null],"e":false,"f":[{"g":false,"h":3,"i":["test2"]}],"j":{},"k":{},"l":{}},"y":{"d":"true"}},"b":{}}'); - }); - }); - describe(".exists()", function() { - [ - ["a.b.c.1", true], - ["b.a", true], - ["a.b.x", false], - ["a.x", false], - ["a.b.q", false], - ["a.b.c.0", true], - ["a.b.d", true], - ["a.b.f.0.g", true], - ["a.b.f.0.i.0", true], - ["a.b.f.0.i.2", false], - ["a.b.e", true] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - it(".exists(" + a2 + ") should return " + b + " ", function() { - expect(pathfinder.exists(a2)).is.equal(b); - }); - }); - }); - describe(".deleteVia()", function() { - [ - ["a.b.e", '{"a":{"b":{"c":[4,"test1",false,null,null],"f":[{"g":false,"h":3,"i":["test2"]}],"j":{},"k":{},"l":{}}},"b":{}}'], - ["a.b.f", '{"a":{"b":{"c":[4,"test1",false,null,null],"e":false,"j":{},"k":{},"l":{}}},"b":{}}'], - ["a.b.j", '{"a":{"b":{"c":[4,"test1",false,null,null],"e":false,"f":[{"g":false,"h":3,"i":["test2"]}],"k":{},"l":{}}},"b":{}}'] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - it(".deleteVia(" + a2 + ") should return " + b + " ", function() { - pathfinder.deleteVia(a2); - expect(JSON.stringify(object)).is.equal(b); - }); - }); - }); - describe(".getVia()", function() { - describe(".getVia()", function() { - beforeEach(function() { - object = { - a: { - b: { - c: [ - 4, - "test1", - false, - void 0, - parseInt("a") - ], - d: void 0, - e: false, - f: [ - { - g: false, - h: 3, - i: ["test2"] - } - ], - j: {}, - k: (/* @__PURE__ */ new Map()).set("m", { n: 3 }), - l: (/* @__PURE__ */ new Set()).add({ n: 4 }), - o: [ - { p: { q: 1, r: true } }, - { p: { q: 2, r: true } }, - { p: { q: 3, r: true } }, - { p: { q: 4, r: true } }, - { p: { q: 5, r: true } } - ], - s: { - t: { a: 1 }, - u: { a: 2 }, - v: { a: 3 }, - x: { a: 4 } - } - } - } - }; - pathfinder = new Pathfinder(object); - }); - [ - ["a.*", '[["b",{"c":[4,"test1",false,null,null],"e":false,"f":[{"g":false,"h":3,"i":["test2"]}],"j":{},"k":{},"l":{},"o":[{"p":{"q":1,"r":true}},{"p":{"q":2,"r":true}},{"p":{"q":3,"r":true}},{"p":{"q":4,"r":true}},{"p":{"q":5,"r":true}}],"s":{"t":{"a":1},"u":{"a":2},"v":{"a":3},"x":{"a":4}}}]]'], - ["a.b.s.*.a", '[["t",1],["u",2],["v",3],["x",4]]'], - ["a.b.s.*", '[["t",{"a":1}],["u",{"a":2}],["v",{"a":3}],["x",{"a":4}]]'], - ["a.b.o.*.p.q", '[["0",1],["1",2],["2",3],["3",4],["4",5]]'], - ["a.b.o.*.p.r", '[["0",true],["1",true],["2",true],["3",true],["4",true]]'], - ["a.b.o.*.p", '[["0",{"q":1,"r":true}],["1",{"q":2,"r":true}],["2",{"q":3,"r":true}],["3",{"q":4,"r":true}],["4",{"q":5,"r":true}]]'] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - it(".getVia(" + a2 + ") should result " + b, function() { - let r = pathfinder.getVia(a2); - expect(JSON.stringify(Array.from(r))).is.equal(b); - }); - }); - }); - it(".getVia() should result ", function() { - let p = new Pathfinder({ - a: { - x: [ - { c: 1 }, - { c: 2 } - ], - y: true - }, - b: { - x: [ - { c: 1, d: false }, - { c: 2 } - ], - y: true - } - }); - let r = p.getVia("*.x.*.c"); - function mapToObj(map) { - var obj = {}; - map.forEach(function(v, k) { - if (v instanceof Map) { - obj[k] = mapToObj(v); - } else { - obj[k] = v; - } - }); - return obj; - } - expect(JSON.stringify(mapToObj(r))).is.equal('{"a":{"0":1,"1":2},"b":{"0":1,"1":2}}'); - }); - it(".getVia(a.b.l.0.n) with map should return 4 ", function() { - expect(pathfinder.getVia("a.b.l.0.n")).is.equal(4); - }); - [ - ["a.b.k.m.n", 3], - ["a.b.l.0.n", 4], - ["a.x", void 0], - ["a.b.q", void 0], - ["a.b.c.1", "test1"], - ["a.b.c.0", 4], - ["a.b.d", void 0], - ["a.b.f.0.g", false], - ["a.b.f.0.i.0", "test2"], - ["a.b.e", false] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - it(".getVia(" + a2 + ") should return " + b + " ", function() { - expect(pathfinder.getVia(a2)).is.equal(b); - }); - }); - [ - ["a.b.d.e"], - ["a.b.d.x"], - ["a.b.l.e.n"] - ].forEach(function(data) { - let a2 = data.shift(); - it(".getVia(" + a2 + ") should throw Error ", function() { - expect(() => pathfinder.getVia(a2)).to.throw(Error); - }); - }); - }); - }); - }); - - // test/cases/data/diff.mjs - init_diff(); - init_queue(); - describe("Diff", function() { - describe("Diff special cases", function() { - var obj1, obj2; - beforeEach(() => { - obj1 = { - "count": 1, - "reason": null, - "info": "test", - "exchange": [] - }; - obj2 = { - "count": 2, - "reason": null, - "info": void 0, - "exchange": [] - }; - }); - it("Diff value with null ", function() { - let d = diff(obj1, obj2); - expect(JSON.stringify(d)).is.equal('[{"operator":"update","path":["count"],"first":{"value":1,"type":"number"},"second":{"value":2,"type":"number"}},{"operator":"delete","path":["info"],"first":{"value":"test","type":"string"}}]'); - }); - it("Diff identical value with null ", function() { - let d = diff(obj1, obj1); - expect(JSON.stringify(d)).is.equal("[]"); - }); - }); - const date1 = /* @__PURE__ */ new Date(); - const date2 = Date.parse("01 Jan 1970 00:00:00 GMT"); - const date3 = Date.parse("04 Dec 1995 00:12:00 GMT"); - const date4 = Date.parse("04 Dec 1995 00:12:01 GMT"); - const date5 = new Date(Date.parse("04 Dec 1995 00:12:01 GMT")); - const date6 = new Date(Date.parse("04 Dec 1995 00:12:02 GMT")); - [ - [ - {}, - { - a: new Queue() - }, - '[{"operator":"add","path":["a"],"second":{"value":{"data":[]},"type":"object","instance":"Queue"}}]' - ], - [ - { - a: { - b: 1 - }, - c: { - d: 2 - } - }, - { - a: { - e: 3 - }, - f: { - d: 2 - } - }, - '[{"operator":"delete","path":["a","b"],"first":{"value":1,"type":"number"}},{"operator":"add","path":["a","e"],"second":{"value":3,"type":"number"}},{"operator":"delete","path":["c"],"first":{"value":{"d":2},"type":"object","instance":"Object"}},{"operator":"add","path":["f"],"second":{"value":{"d":2},"type":"object","instance":"Object"}}]' - ], - [ - { - a: date1, - c: date4 - }, - { - a: date2, - b: date3 - }, - '[{"operator":"update","path":["a"],"first":{"value":"' + date1.toISOString() + '","type":"object","instance":"Date"},"second":{"value":0,"type":"number"}},{"operator":"delete","path":["c"],"first":{"value":818035921000,"type":"number"}},{"operator":"add","path":["b"],"second":{"value":818035920000,"type":"number"}}]' - ], - [ - { - a: date5 - }, - { - b: date6 - }, - '[{"operator":"delete","path":["a"],"first":{"value":"1995-12-04T00:12:01.000Z","type":"object","instance":"Date"}},{"operator":"add","path":["b"],"second":{"value":"1995-12-04T00:12:02.000Z","type":"object","instance":"Date"}}]' - ], - [ - { - a: date1 - }, - { - a: date1 - }, - "[]" - ], - [ - {}, - { - a: date3 - }, - '[{"operator":"add","path":["a"],"second":{"value":818035920000,"type":"number"}}]' - ], - [ - { - a: date2 - }, - { - a: date3 - }, - '[{"operator":"update","path":["a"],"first":{"value":0,"type":"number"},"second":{"value":818035920000,"type":"number"}}]' - ], - [ - { - a: 1 - }, - { - a: 2 - }, - '[{"operator":"update","path":["a"],"first":{"value":1,"type":"number"},"second":{"value":2,"type":"number"}}]' - ], - [ - { - a: 1 - }, - { - x: 1 - }, - '[{"operator":"delete","path":["a"],"first":{"value":1,"type":"number"}},{"operator":"add","path":["x"],"second":{"value":1,"type":"number"}}]' - ], - [ - { - a: 1 - }, - { - a: 2, - x: 1 - }, - '[{"operator":"update","path":["a"],"first":{"value":1,"type":"number"},"second":{"value":2,"type":"number"}},{"operator":"add","path":["x"],"second":{"value":1,"type":"number"}}]' - ], - [ - { - a: null - }, - {}, - '[{"operator":"delete","path":["a"],"first":{"value":null,"type":"object"}}]' - ], - [ - { - a: null - }, - { - a: null - }, - "[]" - ], - [ - {}, - { - a: null - }, - '[{"operator":"add","path":["a"],"second":{"value":null,"type":"object"}}]' - ], - [ - {}, - { a: void 0 }, - '[{"operator":"add","path":["a"],"second":{"type":"undefined"}}]' - ] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - let c = data.shift(); - it("Diff should result " + c, function() { - let d = diff(a2, b); - expect(JSON.stringify(d)).is.equal(c); - }); - }); - }); - - // ../application/source/data/datasource/server.mjs - init_constants(); - init_is(); - init_pathfinder(); - init_pipe(); - var Server = class extends Datasource { - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/data/datasource/server"); - } - /** - * This prepares the data that comes from the server. - * Should not be called directly. - * - * @private - * @param {Object} payload - * @returns {Object} - */ - transformServerPayload(payload) { - const self2 = this; - payload = doTransform.call(self2, "read", payload); - const dataPath = self2.getOption("read.path"); - if (dataPath) { - payload = new Pathfinder(payload).getVia(dataPath); - } - return payload; - } - /** - * This prepares the data for writing and should not be called directly. - * - * @private - * @param {Object} payload - * @returns {Object} - */ - prepareServerPayload(payload) { - const self2 = this; - payload = doTransform.call(self2, "write", payload); - let sheathingObject = self2.getOption("write.sheathing.object"); - let sheathingPath = self2.getOption("write.sheathing.path"); - if (sheathingObject && sheathingPath) { - const sub = payload; - payload = sheathingObject; - new Pathfinder(payload).setVia(sheathingPath, sub); - } - return payload; - } - }; - function doTransform(type, obj) { - const self2 = this; - let transformation = self2.getOption(`${type}.mapping.transformer`); - if (transformation !== void 0) { - const pipe = new Pipe(transformation); - const callbacks = self2.getOption(`${type}.mapping.callbacks`); - if (isObject(callbacks)) { - for (const key in callbacks) { - if (callbacks.hasOwnProperty(key) && typeof callbacks[key] === "function") { - pipe.setCallback(key, callbacks[key]); - } - } - } - obj = pipe.run(obj); - } - return obj; - } - - // test/cases/data/datasource/server.mjs - describe("Server", function() { - it("should transform data", function() { - let writeCallbackCalled = false; - let readCallbackCalled = false; - const server = new Server({ - write: { - mapping: { - transformer: "call:onWrite", - callbacks: { - onWrite: (data) => { - writeCallbackCalled = true; - return data; - } - } - }, - sheathing: { - object: { - demo: 1, - data: { - xyz: void 0 - } - }, - path: "data.xyz" - } - }, - read: { - mapping: { - transformer: "call:onRead", - callbacks: { - onRead: (data) => { - readCallbackCalled = true; - return data; - } - } - }, - path: "data.xyz" - } - }); - expect(server.transformServerPayload({ demo: 1, data: { xyz: 2 } })).to.deep.equal({ demo: 1, data: { xyz: 2 } }); - expect(server.prepareServerPayload({ demo: 1, data: { xyz: 2 } })).to.deep.equal({ demo: 1, data: { xyz: 2 } }); - }); - }); - - // ../application/source/data/datasource/storage/sessionstorage.mjs - init_constants(); - init_global(); - - // ../application/source/data/datasource/storage.mjs - init_constants(); - init_validate(); - var storageObjectSymbol = Symbol.for("@schukai/monster/data/datasource/storage/@@storageObject"); - var Storage = class extends Datasource { - /** - * - * @param {string} key LocalStorage Key - * @throws {TypeError} value is not a string - */ - constructor(key) { - super(); - this.setOption("key", validateString(key)); - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/data/datasource/storage"); - } - /** - * @property {string} key=undefined LocalStorage Key - */ - get defaults() { - return Object.assign({}, super.defaults, { - key: void 0 - }); - } - /** - * @throws {Error} this method must be implemented by derived classes. - * @return {external:Storage} - * @private - */ - [storageObjectSymbol]() { - throw new Error("this method must be implemented by derived classes"); - } - /** - * @return {Promise} - * @throws {Error} the options does not contain a valid json definition - * @throws {TypeError} value is not a object - * @throws {Error} the data cannot be read - */ - read() { - const self2 = this; - const storage = self2[storageObjectSymbol](); - return new Promise(function(resolve) { - const data = JSON.parse(storage.getItem(self2.getOption("key"))); - self2.set(data ?? {}); - resolve(); - }); - } - /** - * @return {Storage} - * @throws {Error} the data cannot be written - */ - write() { - const self2 = this; - const storage = self2[storageObjectSymbol](); - return new Promise(function(resolve) { - const data = self2.get(); - if (data === void 0) { - storage.removeItem(self2.getOption("key")); - } else { - storage.setItem(self2.getOption("key"), JSON.stringify(data)); - } - resolve(); - }); - } - /** - * @return {Storage} - */ - getClone() { - const self2 = this; - return new Storage(self2[internalSymbol].getRealSubject()["options"].key); - } - }; - - // ../application/source/data/datasource/storage/sessionstorage.mjs - var SessionStorage = class extends Storage { - /** - * @throws {Error} this method must be implemented by derived classes. - * @return {external:sessionStorage} - * @private - */ - [storageObjectSymbol]() { - return getGlobalObject("sessionStorage"); - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/data/datasource/storage/session-storage"); - } - /** - * Create Clone - * - * @return {SessionStorage} - */ - getClone() { - const self2 = this; - return new SessionStorage(self2[internalSymbol].getRealSubject()["options"].key); - } - }; - - // test/util/localstorage.mjs - function createStorage() { - let UNSET = Symbol(); - let s = {}, noopCallback = () => { - }, _itemInsertionCallback = noopCallback; - Object.defineProperty(s, "setItem", { - get: () => { - return (k, v = UNSET) => { - if (v === UNSET) { - throw new TypeError(`Failed to execute 'setItem' on 'Storage': 2 arguments required, but only 1 present.`); - } - k = k + ""; - if (!s.hasOwnProperty(k)) { - _itemInsertionCallback(s.length); - } - s[k] = v + ""; - }; - } - }); - Object.defineProperty(s, "getItem", { - get: () => { - return (k) => { - k = k + ""; - if (s.hasOwnProperty(k)) { - return s[k]; - } else { - return null; - } - }; - } - }); - Object.defineProperty(s, "removeItem", { - get: () => { - return (k) => { - k = k + ""; - if (s.hasOwnProperty(k)) { - delete s[k]; - } - }; - } - }); - Object.defineProperty(s, "clear", { - get: () => { - return () => { - for (let k in s) { - if (s.hasOwnProperty(k)) { - delete s[k]; - } - } - }; - } - }); - Object.defineProperty(s, "length", { - get: () => { - return Object.keys(s).length; - } - }); - Object.defineProperty(s, "key", { - value: (k) => { - let key = Object.keys(s)[k]; - return !key ? null : key; - } - }); - Object.defineProperty(s, "itemInsertionCallback", { - get: () => { - return _itemInsertionCallback; - }, - set: (v) => { - if (!v || typeof v != "function") { - v = noopCallback; - } - _itemInsertionCallback = v; - } - }); - return s; - } - - // test/cases/data/datasource/storage/sessionstorage.mjs - var storageReference; - describe("SessionStorage", function() { - afterEach(() => { - globalThis["sessionStorage"] = storageReference; - }); - beforeEach(function() { - storageReference = globalThis["sessionStorage"]; - globalThis["sessionStorage"] = createStorage(); - }); - it("should instance of SessionStorage ", function() { - expect(new SessionStorage("mykey")).to.be.instanceof(SessionStorage); - }); - describe("rw", function() { - it("read should return object", function(done) { - const ds = new SessionStorage("mykey"); - ds.read().then((data) => { - done(); - }).catch((e) => done(e)); - }); - it("write should ", function(done) { - const ds = new SessionStorage("mykey"); - ds.write().then((data) => { - done(); - }).catch((e) => done(e)); - }); - }); - }); - - // ../application/source/data/datasource/storage/localstorage.mjs - init_constants(); - init_global(); - var LocalStorage = class extends Storage { - /** - * @throws {Error} this method must be implemented by derived classes. - * @return {external:localStorage} - * @private - */ - [storageObjectSymbol]() { - return getGlobalObject("localStorage"); - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/data/datasource/storage/localstorage"); - } - /** - * Create clone - * @return {LocalStorage} - */ - getClone() { - const self2 = this; - return new LocalStorage(self2[internalSymbol].getRealSubject()["options"].key); - } - }; - - // test/cases/data/datasource/storage/localstorage.mjs - var localStorageReference; - describe("LocalStorage", function() { - afterEach(() => { - globalThis["localStorage"] = localStorageReference; - }); - beforeEach(function() { - localStorageReference = globalThis["localStorage"]; - globalThis["localStorage"] = createStorage(); - }); - it("should instance of LocalStorage ", function() { - expect(new LocalStorage("mykey")).to.be.instanceof(LocalStorage); - }); - describe("rw", function() { - it("read should return object", function(done) { - const ds = new LocalStorage("mykey"); - ds.read().then((data) => { - done(); - }).catch((e) => done(e)); - }); - it("write should ", function(done) { - const ds = new LocalStorage("mykey"); - ds.write().then((data) => { - done(); - }).catch((e) => done(e)); - }); - }); - }); - - // ../application/source/data/datasource/dom.mjs - init_constants(); - init_is(); - var DomStorage = class extends Datasource { - /** - * @param {Object} [options] options contains definitions for the datasource. - */ - constructor(options) { - super(); - if (isObject(options)) { - this.setOptions(options); - } - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/data/datasource/storage/dom-storage"); - } - /** - * @property {Object} defaults - * @property {Object} defaults.read - * @property {string} defaults.read.selector - * @property {Object} defaults.write - * @property {string} defaults.write.selector - */ - get defaults() { - return Object.assign({}, super.defaults, { - read: { - selector: void 0 - }, - write: { - selector: void 0 - } - }); - } - /** - * @return {Promise} - * @throws {Error} The read selector is not defined - * @throws {Error} There are no storage element - */ - read() { - const self2 = this; - let selector = self2.getOption("read.selector", void 0); - if (!selector) { - throw new Error("The read selector is not defined"); - } - let storage = document.querySelector(selector); - if (!storage) { - throw new Error("There are no storage element"); - } - return new Promise((resolve, reject) => { - try { - let data = JSON.parse(storage.innerHTML); - self2.set(data); - resolve(data); - } catch (e) { - reject(e); - } - }); - } - /** - * @return {Promise} - * @throws {Error} The write selector is not defined - * @throws {Error} There are no storage element - */ - write() { - const self2 = this; - let selector = self2.getOption("write.selector"); - if (!selector) { - throw new Error("The write selector is not defined"); - } - let storage = document.querySelector(selector); - if (!storage) { - throw new Error("There are no storage element"); - } - return new Promise((resolve, reject) => { - try { - storage.innerHTML = JSON.stringify(self2.get()); - resolve(storage); - } catch (e) { - reject(e); - } - }); - } - }; - - // test/cases/data/datasource/dom.mjs - describe("ServeDomr", function() { - it("should init", function() { - const dom = new DomStorage({}); - expect(dom).to.be.not.null; - }); - }); - - // ../application/source/data/datasource/server/restapi.mjs - init_constants(); - init_is(); - - // ../application/source/data/datasource/server/restapi/writeerror.mjs - init_constants(); - var WriteError = class extends Error { - /** - * - * @param {string} message - * @param {Response} response - */ - constructor(message, response, validation) { - super(message); - this[internalSymbol] = { - response, - validation - }; - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/data/datasource/server/restapi/writeerror"); - } - /** - * @return {Response} - */ - getResponse() { - return this[internalSymbol]["response"]; - } - /** - * @return {Object} - */ - getValidation() { - return this[internalSymbol]["validation"]; - } - }; - - // ../application/source/data/datasource/server/restapi.mjs - var rawDataSymbol = Symbol.for("@schukai/monster/data/datasource/server/restapi/rawdata"); - var RestAPI = class extends Server { - /** - * - * @param {Object} [options] options contains definitions for the datasource. - */ - constructor(options) { - super(); - if (isObject(options)) { - this.setOptions(options); - } - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/data/datasource/server/restapi"); - } - /** - * @property {Object} write={} Options - * @property {Object} write.init={} An options object containing any custom settings that you want to apply to the request. The parameters are identical to those of the {@link https://developer.mozilla.org/en-US/docs/Web/API/Request/Request|Request constructor} - * @property {string} write.init.method=POST - * @property {Object} write.init.headers Object containing any custom headers that you want to apply to the request. - * @property {string} write.responseCallback Callback function to be executed after the request has been completed. - * @property {string} write.acceptedStatus=[200,201] - * @property {string} write.url URL - * @property {Object} write.mapping the mapping is applied before writing. - * @property {String} write.mapping.transformer Transformer to select the appropriate entries - * @property {Monster.Data.Datasource~exampleCallback[]} write.mapping.callback with the help of the callback, the structures can be adjusted before writing. - * @property {Object} write.report - * @property {String} write.report.path Path to validations - * @property {Object} write.sheathing - * @property {Object} write.sheathing.object Object to be wrapped - * @property {string} write.sheathing.path Path to the data - * @property {Object} read={} Options - * @property {Object} read.init={} An options object containing any custom settings that you want to apply to the request. The parameters are identical to those of the {@link https://developer.mozilla.org/en-US/docs/Web/API/Request/Request|Request constructor} - * @property {string} read.init.method=GET - * @property {string} read.acceptedStatus=[200] - * @property {string} read.url URL - * @property {Object} read.mapping the mapping is applied after reading. - * @property {String} read.mapping.transformer Transformer to select the appropriate entries - * @property {Monster.Data.Datasource~exampleCallback[]} read.mapping.callback with the help of the callback, the structures can be adjusted after reading. - */ - get defaults() { - return Object.assign({}, super.defaults, { - write: { - init: { - method: "POST" - }, - responseCallback: void 0, - acceptedStatus: [200, 201], - url: void 0, - mapping: { - transformer: void 0, - callbacks: [] - }, - sheathing: { - object: void 0, - path: void 0 - }, - report: { - path: void 0 - } - }, - read: { - init: { - method: "GET" - }, - responseCallback: void 0, - acceptedStatus: [200], - url: void 0, - mapping: { - transformer: void 0, - callbacks: [] - } - } - }); - } - /** - * @return {Promise} - * @throws {Error} the options does not contain a valid json definition - * @throws {TypeError} value is not a object - * @throws {Error} the data cannot be read - */ - read() { - const self2 = this; - let init3 = self2.getOption("read.init"); - if (!isObject(init3)) - init3 = {}; - if (!init3["method"]) - init3["method"] = "GET"; - let callback = self2.getOption("read.responseCallback"); - if (!callback) - callback = (obj) => { - self2.set(self2.transformServerPayload.call(self2, obj)); - }; - return fetchData.call(this, init3, "read", callback); - } - /** - * @return {Promise} - * @throws {WriteError} the data cannot be written - */ - write() { - const self2 = this; - let init3 = self2.getOption("write.init"); - if (!isObject(init3)) - init3 = {}; - if (typeof init3["headers"] !== "object") { - init3["headers"] = { - "Content-Type": "application/json" - }; - } - if (!init3["method"]) - init3["method"] = "POST"; - let obj = self2.prepareServerPayload(self2.get()); - init3["body"] = JSON.stringify(obj); - let callback = self2.getOption("write.responseCallback"); - return fetchData.call(this, init3, "write", callback); - } - /** - * @return {RestAPI} - */ - getClone() { - const self2 = this; - return new RestAPI( - self2[internalSymbol].getRealSubject()["options"].read, - self2[internalSymbol].getRealSubject()["options"].write - ); - } - }; - function fetchData(init3, key, callback) { - const self2 = this; - let response; - return fetch(self2.getOption(`${key}.url`), init3).then((resp) => { - response = resp; - const acceptedStatus = self2.getOption(`${key}.acceptedStatus`, [200]); - if (acceptedStatus.indexOf(resp.status) === -1) { - throw Error(`the data cannot be ${key} (response ${resp.status})`); - } - return resp.text(); - }).then((body) => { - let obj; - try { - obj = JSON.parse(body); - response[rawDataSymbol] = obj; - } catch (e) { - if (body.length > 100) { - body = `${body.substring(0, 97)}...`; - } - throw new Error(`the response does not contain a valid json (actual: ${body}).`); - } - if (callback && isFunction(callback)) { - callback(obj); - } - return response; - }); - } - - // test/cases/data/datasource/server/restapi.mjs - init_validate(); - describe("RestAPI", function() { - let fetchReference2; - let returnStatus; - afterEach(() => { - globalThis["fetch"] = fetchReference2; - }); - beforeEach(() => { - returnStatus = 200; - fetchReference2 = globalThis["fetch"]; - globalThis["fetch"] = function(options) { - return new Promise((resolve, reject) => { - resolve({ - text: function() { - return new Promise((resolve2, reject2) => { - resolve2(JSON.stringify({ - a: "test" - })); - }); - }, - status: returnStatus - }); - }); - }; - }); - it("should instance of RestAPI ", function() { - expect(new RestAPI("https://monsterjs.org/assets/world.json")).to.be.instanceof(RestAPI); - }); - describe("rw", function() { - it("read should return object", function(done) { - const ds = new RestAPI({ url: "https://monsterjs.org/assets/world.json" }); - ds.read().then((data) => { - validateObject(data); - done(); - }).catch((e) => done(e)); - }); - it("write should ", function(done) { - const ds = new RestAPI( - { - read: { - url: "https://monsterjs.org/assets/world.json" - }, - write: { - url: "https://monsterjs.org/assets/world.json", - acceptedStatus: [99] - } - } - ); - ds.write().then((data) => { - done("should not be here"); - }).catch((e) => done()); - }); - }); - describe("rw with errors", function() { - it("read should throw exception", function(done) { - returnStatus = 400; - const ds = new RestAPI({ url: "https://monsterjs.org/assets/world.json" }); - ds.read().then((data) => { - done("should not run."); - }).catch((e) => done()); - }); - it("write should ", function(done) { - returnStatus = 400; - const ds = new RestAPI({ url: "https://monsterjs.org/assets/world.json" }, { url: "https://monsterjs.org/assets/world.json" }); - ds.write().then((data) => { - validateObject(data); - done("error"); - }).catch((e) => done()); - }); - }); - }); - - // ../application/source/data/datasource/server/webconnect.mjs - init_constants(); - init_is(); - var webConnectSymbol = Symbol("connection"); - var WebConnect2 = class extends Server { - /** - * - * @param {Object} [options] options contains definitions for the datasource. - */ - constructor(options) { - super(); - const self2 = this; - if (isString(options)) { - options = { url: options }; - } - if (!isObject(options)) - options = {}; - this.setOptions(options); - this[webConnectSymbol] = new WebConnect({ - url: self2.getOption("url"), - connection: { - timeout: self2.getOption("connection.timeout"), - reconnect: { - timeout: self2.getOption("connection.reconnect.timeout"), - attempts: self2.getOption("connection.reconnect.attempts"), - enabled: self2.getOption("connection.reconnect.enabled") - } - } - }); - } - /** - * - * @returns {Promise} - */ - connect() { - return this[webConnectSymbol].connect(); - } - /** - * @returns {boolean} - */ - isConnected() { - return this[webConnectSymbol].isConnected(); - } - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/data/datasource/server/webconnect"); - } - /** - * @property {string} url=undefined Defines the resource that you wish to fetch. - * @property {Object} connection - * @property {Object} connection.timeout=5000 Defines the timeout for the connection. - * @property {Number} connection.reconnect.timeout The timeout in milliseconds for the reconnect. - * @property {Number} connection.reconnect.attempts The maximum number of reconnects. - * @property {Bool} connection.reconnect.enabled If the reconnect is enabled. - * @property {Object} write={} Options - * @property {Object} write.mapping the mapping is applied before writing. - * @property {String} write.mapping.transformer Transformer to select the appropriate entries - * @property {Monster.Data.Datasource~exampleCallback[]} write.mapping.callback with the help of the callback, the structures can be adjusted before writing. - * @property {Object} write.sheathing - * @property {Object} write.sheathing.object Object to be wrapped - * @property {string} write.sheathing.path Path to the data - * @property {Object} read={} Options - * @property {String} read.path Path to data - * @property {Object} read.mapping the mapping is applied after reading. - * @property {String} read.mapping.transformer Transformer to select the appropriate entries - * @property {Monster.Data.Datasource~exampleCallback[]} read.mapping.callback with the help of the callback, the structures can be adjusted after reading. - */ - get defaults() { - return Object.assign({}, super.defaults, { - url: void 0, - write: { - mapping: { - transformer: void 0, - callbacks: {} - }, - sheathing: { - object: void 0, - path: void 0 - } - }, - read: { - mapping: { - transformer: void 0, - callbacks: {} - }, - path: void 0 - }, - connection: { - timeout: 5e3, - reconnect: { - timeout: 1e3, - attempts: 1, - enabled: false - } - } - }); - } - /** - * This method closes the connection. - * - * @returns {Promise} - */ - close() { - return this[webConnectSymbol].close(); - } - /** - * @return {Promise} - */ - read() { - const self2 = this; - return new Promise((resolve, reject) => { - while (this[webConnectSymbol].dataReceived() === true) { - let obj = this[webConnectSymbol].poll(); - if (!isObject(obj)) { - reject(new Error("The received data is not an object.")); - return; - } - if (!(obj instanceof Message)) { - reject(new Error("The received data is not a Message.")); - return; - } - obj = obj.getData(); - obj = self2.transformServerPayload.call(self2, obj); - self2.set(obj); - } - resolve(self2.get()); - }); - } - /** - * @return {Promise} - */ - write() { - const self2 = this; - let obj = self2.prepareServerPayload(self2.get()); - return self2[webConnectSymbol].send(obj); - } - /** - * @return {RestAPI} - */ - getClone() { - const self2 = this; - return new WebConnect2(self2[internalSymbol].getRealSubject()["options"]); - } - }; - - // test/cases/data/datasource/server/websocket.mjs - var testUrl2 = "wss://ws.postman-echo.com/raw"; - describe("Websocket", function() { - let ds = void 0; - before(function(done) { - initWebSocket().then(() => { - done(); - }).catch((e) => { - done(e); - }); - }); - afterEach(function(done) { - if (ds) { - ds.close(); - } - for (const sym of Object.getOwnPropertySymbols(ds)) { - if (sym.toString() === "Symbol(connection)") { - const connection = ds[sym]; - for (const sym2 of Object.getOwnPropertySymbols(connection)) { - if (sym2.toString() === "Symbol(connection)") { - const socket = connection[sym2]?.socket; - if (socket) { - if (typeof socket?.terminate === "function") { - socket?.["terminate"](); - } - } - } - } - } - } - done(); - }); - it("should get clone", function() { - ds = new WebConnect2(testUrl2); - const clone2 = ds.getClone(); - expect(clone2).to.be.an.instanceof(WebConnect2); - }); - it("should transform data", function(done) { - let writeCallbackCalled = false; - let readCallbackCalled = false; - ds = new WebConnect2({ - url: testUrl2, - write: { - mapping: { - transformer: "call:onWrite", - callbacks: { - onWrite: (data) => { - writeCallbackCalled = true; - return data; - } - } - }, - sheathing: { - object: { - demo: 1, - data: { - xyz: void 0 - } - }, - path: "data.xyz" - } - }, - read: { - mapping: { - transformer: "call:onRead", - callbacks: { - onRead: (data) => { - readCallbackCalled = true; - return data; - } - } - }, - path: "data.xyz" - } - }); - ds.connect().then(() => { - ds.set({ - envelop: { - message: "Hello World" - } - }); - ds.write().then(() => { - ds.set({}); - expect(ds.get()).to.be.deep.equal({}); - setTimeout(() => { - ds.read().then(() => { - expect(ds.get()).to.be.deep.equal({ envelop: { message: "Hello World" } }); - expect(writeCallbackCalled).to.be.true; - expect(readCallbackCalled).to.be.true; - done(); - }).catch((e) => { - done(e); - }); - }, 200); - }).catch((err) => { - done(new Error(err)); - }); - }).catch((e) => { - done(e); - }); - }); - it("should connect", function(done) { - ds = new WebConnect2({ - url: testUrl2, - reconnect: { - enabled: false - } - }); - ds.connect().then(() => { - done(); - }).catch((e) => { - done(e); - }); - }); - it("should send message", function(done) { - ds = new WebConnect2({ - url: testUrl2, - reconnect: { - enabled: false - } - }); - ds.connect().then(() => { - ds.set({ - envelop: { - message: "Hello World" - } - }); - ds.write().then(() => { - ds.set({}); - expect(ds.get()).to.be.deep.equal({}); - setTimeout(() => { - ds.read().then(() => { - expect(ds.get()).to.be.deep.equal({ envelop: { message: "Hello World" } }); - done(); - }).catch((e) => { - done(e); - }); - }, 500); - }).catch((err) => { - done(new Error(err)); - }); - }).catch((e) => { - done(e); - }); - }).timeout(1e4); - }); - - // test/cases/math/random.mjs - describe("Math", function() { - let random2 = () => { - }; - before(function(done) { - let promises = []; - if (!globalThis["crypto"]) { - promises.push(Promise.resolve().then(() => (init_webcrypto_es(), webcrypto_es_exports)).then((m) => { - globalThis["crypto"] = new m.Crypto(); - return true; - })); - } - promises.push(Promise.resolve().then(() => (init_random(), random_exports)).then((m) => { - random2 = m.random; - return true; - })); - Promise.all(promises).then(() => { - done(); - }); - }); - describe(".random()", function() { - it("a greater b should throw error ", function() { - expect(() => random2(10, 2)).to.throw(Error); - }); - it(" should return a number ", function() { - let r = random2(); - expect(r).that.is.a("number"); - }); - it(" should return a number ", function() { - expect(() => random2(5, 6)).to.throw(Error); - }); - it(" should throw Error we cannot generate numbers larger than 53 bits.", function() { - expect(() => random2(-999999999, 1e20)).to.throw(Error); - }); - it(" should throw Error we cannot generate numbers larger than 53 bits.", function() { - [ - [1, 100], - [500, 600], - [100, 1e3] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - let r = random2(a2, b); - it(r + " should return value between " + a2 + " " + b, function() { - expect(r >= a2).to.be.true; - expect(r <= b).to.be.true; - }); - }); - [ - [1, 100], - [500, 600], - [100, 1e3] - ].forEach(function(data) { - let a2 = data.shift(); - let b = data.shift(); - let sum = 0; - const rounds = 500; - for (let i = 0, max = rounds; i < max; i++) { - sum += random2(a2, b); - } - let avg = sum / rounds; - it(avg + " should between " + a2 + " " + b, function() { - expect(avg > a2).to.be.true; - expect(avg < b).to.be.true; - }); - }); - }); - }); - }); -})(); -/** - * @private - * @type {symbol} - * @memberOf Monster - * @license AGPLv3 - * @since 1.24.0 - */ -/** - * @private - * @type {symbol} - * @memberOf Monster - * @license AGPLv3 - * @since 1.25.0 - */ -/** - * This is the base class from which the most classes are derived. - * - * This class has besides a `toString` which returns the json representation of the object - * also a functionality to check if an object is an instance of a class. - * - * Therefor the class has a static method ` [Symbol.hasInstance](that)` which returns true if the object - * is an instance of the class. - * - * @see [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/hasInstance](developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/hasInstance) - * - * Derived classes should implement a static getter `instanceSymbol` which returns a unique symbol. - * - * ```javascript - * static get [instanceSymbol]() { - * return Symbol.for("@schukai/monster/types/base"); - * } - * ``` - * - * The class was formerly called Object. - * - * @license AGPLv3 - * @since 1.5.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - */ -/** - * With this function you can check if a value is iterable. - * - * This method is used in the library to have consistent names. - * - * You can call the method via the monster namespace `Monster.Types.isPrimitive()`. - * - * @externalExample ../../example/types/is-1.mjs - * @param {*} value - * @returns {boolean} - * @license AGPLv3 - * @since 1.2.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - */ -/** - * Checks whether the value passed is a primitive (string, number, boolean, NaN, undefined, null or symbol) - * - * This method is used in the library to have consistent names. - * - * @externalExample ../../example/types/is-2.mjs - * @param {*} value - * @returns {boolean} - * @license AGPLv3 - * @since 1.0.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - */ -/** - * Checks whether the value passed is a symbol - * - * This method is used in the library to have consistent names. - * - * @externalExample ../../example/types/is-3.mjs - * @param {*} value - * @returns {boolean} - * @license AGPLv3 - * @since 1.9.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - */ -/** - * Checks whether the value passed is a boolean. - * - * This method is used in the library to have consistent names. - * - * @externalExample ../../example/types/is-4.mjs - * @param {*} value - * @returns {boolean} - * @license AGPLv3 - * @since 1.0.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - */ -/** - * Checks whether the value passed is a string - * - * This method is used in the library to have consistent names. - * - * @externalExample ../../example/types/is-5.mjs - * @param {*} value - * @returns {boolean} - * @license AGPLv3 - * @since 1.0.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - */ -/** - * Checks whether the value passed is a object - * - * This method is used in the library to have consistent names. - * - * @externalExample ../../example/types/is-6.mjs - * @param {*} value - * @returns {boolean} - * @license AGPLv3 - * @since 1.0.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - */ -/** - * Checks whether the value passed is a object and instance of instance. - * - * This method is used in the library to have consistent names. - * - * @externalExample ../../example/types/is-7.mjs - * @param {*} value - * @param {*} instance - * @returns {boolean} - * @license AGPLv3 - * @since 1.5.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - */ -/** - * Checks whether the value passed is a array - * - * This method is used in the library to have consistent names. - * - * @externalExample ../../example/types/is-8.mjs - * @param {*} value - * @returns {boolean} - * @license AGPLv3 - * @since 1.0.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - * @see https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray - */ -/** - * Checks whether the value passed is a function - * - * This method is used in the library to have consistent names. - * - * @externalExample ../../example/types/is-9.mjs - * @param {*} value - * @returns {boolean} - * @license AGPLv3 - * @since 1.0.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - */ -/** - * Checks whether the value passed is an integer. - * - * This method is used in the library to have consistent names. - * - * @externalExample ../../example/types/is-10.mjs - * @param {*} value - * @returns {boolean} - * @license AGPLv3 - * @since 1.4.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - */ -/** - * This method checks if the type matches the primitive type. this function is identical to isPrimitive() except that a TypeError is thrown. - * - * ``` - * <script type="module"> - * import {validateIterable} from '@schukai/monster/source/types/validate.mjs'; - * console.log(validateIterable('2')) // ↦ TypeError - * console.log(validateIterable([])) // ↦ value - * <\/script> - * ``` - * - * @param {*} value - * @return {*} - * @license AGPLv3 - * @since 1.2.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - * @throws {TypeError} value is not a primitive - * @see {@link isPrimitive} - * @see {@link Monster.Types.isPrimitive} - * @see {@link Monster.Types#isPrimitive} - */ -/** - * This method checks if the type matches the primitive type. this function is identical to isPrimitive() except that a TypeError is thrown. - * - * ``` - * <script type="module"> - * import {validatePrimitive} from '@schukai/monster/source/types/validate.mjs'; - * console.log(validatePrimitive('2')) // ↦ value - * console.log(validatePrimitive([])) // ↦ TypeError - * <\/script> - * ``` - * - * @param {*} value - * @return {*} - * @license AGPLv3 - * @since 1.0.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - * @throws {TypeError} value is not a primitive - * @see {@link isPrimitive} - * @see {@link Monster.Types.isPrimitive} - * @see {@link Monster.Types#isPrimitive} - */ -/** - * This method checks if the type matches the boolean type. this function is identical to isBoolean() except that a TypeError is thrown. - * - * ``` - * <script type="module"> - * import {validateBoolean} from '@schukai/monster/source/types/validate.mjs'; - * console.log(validateBoolean(false)) // ↦ value - * console.log(validateBoolean('2')) // ↦ TypeError - * console.log(validateBoolean([])) // ↦ TypeError - * <\/script> - * ``` - * - * @param {*} value - * @return {*} - * @license AGPLv3 - * @since 1.0.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - - * @throws {TypeError} value is not primitive - */ -/** - * This method checks if the type matches the string type. this function is identical to isString() except that a TypeError is thrown. - * - * ``` - * <script type="module"> - * import {validateString} from '@schukai/monster/source/types/validate.mjs'; - * console.log(validateString('2')) // ↦ value - * console.log(validateString([])) // ↦ TypeError - * <\/script> - * ``` - * - * @param {*} value - * @return {*} - * @license AGPLv3 - * @since 1.0.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - * @throws {TypeError} value is not a string - */ -/** - * This method checks if the type matches the object type. this function is identical to isObject() except that a TypeError is thrown. - * - * ``` - * <script type="module"> - * import {validateObject} from '@schukai/monster/source/types/validate.mjs'; - * console.log(validateObject({})) // ↦ value - * console.log(validateObject('2')) // ↦ TypeError - * console.log(validateObject([])) // ↦ TypeError - * <\/script> - * ``` - * - * @param {*} value - * @return {*} - * @license AGPLv3 - * @since 1.0.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - * @throws {TypeError} value is not a object - */ -/** - * This method checks if the type matches the object instance. - * - * ``` - * <script type="module"> - * import {validateInstance} from '@schukai/monster/source/types/validate.mjs'; - * console.log(validateInstance({}, Object)) // ↦ value - * console.log(validateInstance('2', Object)) // ↦ TypeError - * console.log(validateInstance([], Object)) // ↦ TypeError - * <\/script> - * ``` - * - * @param {*} value - * @return {*} - * @license AGPLv3 - * @since 1.5.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - * @throws {TypeError} value is not an instance of - */ -/** - * This method checks if the type matches the array type. this function is identical to isArray() except that a TypeError is thrown. - * - * ``` - * <script type="module"> - * import {validateArray} from '@schukai/monster/source/types/validate.mjs'; - * console.log(validateArray('2')) // ↦ TypeError - * console.log(validateArray([])) // ↦ value - * <\/script> - * ``` - * - * @param {*} value - * @return {*} - * @license AGPLv3 - * @since 1.0.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - * @throws {TypeError} value is not an array - */ -/** - * This method checks if the type matches the symbol type. this function is identical to isSymbol() except that a TypeError is thrown. - * - * ``` - * <script type="module"> - * import {validateSymbol} from '@schukai/monster/source/types/validate.mjs'; - * console.log(validateSymbol('2')) // ↦ TypeError - * console.log(validateSymbol()) // ↦ value - * <\/script> - * ``` - * - * @param {*} value - * @return {*} - * @license AGPLv3 - * @since 1.9.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - * @throws {TypeError} value is not an symbol - */ -/** - * This method checks if the type matches the function type. this function is identical to isFunction() except that a TypeError is thrown. - * - * ``` - * <script type="module"> - * import {validateFunction} from '@schukai/monster/source/types/validate.mjs'; - * console.log(validateFunction(()=>{})) // ↦ value - * console.log(validateFunction('2')) // ↦ TypeError - * console.log(validateFunction([])) // ↦ TypeError - * <\/script> - * ``` - * - * @param {*} value - * @return {*} - * @license AGPLv3 - * @since 1.0.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - * @throws {TypeError} value is not a function - */ -/** - * This method checks if the type is an integer. this function is identical to isInteger() except that a TypeError is thrown. - * - * ``` - * <script type="module"> - * import {validateFunction} from '@schukai/monster/source/types/validate.mjs'; - * console.log(validateInteger(true)) // ↦ TypeError - * console.log(validateInteger('2')) // ↦ TypeError - * console.log(validateInteger(2)) // ↦ value - * <\/script> - * ``` - * - * @param {*} value - * @return {*} - * @license AGPLv3 - * @since 1.4.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - * @throws {TypeError} value is not an integer - */ -/** - * Return globalThis - * - * If globalThis is not available, it will be polyfilled - * - * @license AGPLv3 - * @since 1.6.0 - * @memberOf Monster.Types - * @returns {objec} globalThis - */ -/** - * Return global object or throw Error - * - * You can call the method via the monster namespace `Monster.Types.getGlobalObject()`. - * - * ``` - * <script type="module"> - * import {Monster} from '@schukai/monster/source/monster.mjs'; - * Monster.Types.getGlobalObject('document') - * // ↦ { } - * <\/script> - * ``` - * - * Alternatively, you can also integrate this function individually. - * - * ``` - * <script type="module"> - * import {getGlobalObject} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.30.0/dist/modules/types/global.mjs'; - * getGlobalObject('document') - * // ↦ { } - * <\/script> - * ``` - * - * @license AGPLv3 - * @since 1.6.0 - * @memberOf Monster.Types - * @param {string} name - * @returns {objec} - * @throws {Error} the object is not defined - * @throws {TypeError} value is not a object - * @throws {TypeError} value is not a string - */ -/** - * Return global function or throw Error - * - * You can call the method via the monster namespace `Monster.Types.getGlobalFunction()`. - * - * ``` - * <script type="module"> - * import {Monster} from '@schukai/monster/source/monster.mjs'; - * console.log(Monster.Types.getGlobalFunction('parseInt')) // ↦ f parseInt() { } - * <\/script> - * ``` - * - * Alternatively, you can also integrate this function individually. - * - * ``` - * <script type="module"> - * import {getGlobalFunction} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.30.0/dist/modules/types/global.mjs'; - * console.log(getGlobalFunction('parseInt')) // ↦ f parseInt() { } - * <\/script> - * ``` - * - * @license AGPLv3 - * @since 1.6.0 - * @memberOf Monster.Types - * @param {string} name - * @return {objec} - * @throws {TypeError} value is not a function - * @throws {Error} the function is not defined - * @throws {TypeError} value is not a string - */ -/** - * The built-in typeof method is known to have some historical weaknesses. This function tries to provide a better and more accurate result. - * - * @externalExample ../../example/types/typeof.mjs - * @param {*} value - * @return {string} - * @license AGPLv3 - * @since 1.7.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - * @throws {TypeError} value is not a primitive - */ -/** - * Extend copies all enumerable own properties from one or - * more source objects to a target object. It returns the modified target object. - * - * @param {object} target - * @param {object} - * @return {object} - * @license AGPLv3 - * @since 1.10.0 - * @copyright schukai GmbH - * @memberOf Monster.Data - * @throws {Error} unsupported argument - * @throws {Error} type mismatch - * @throws {Error} unsupported argument - */ -/** - * With this function, objects can be cloned. - * The entire object tree is run through. - * - * Proxy, Element, HTMLDocument and DocumentFragment instances are not cloned. - * Global objects such as windows are also not cloned, - * - * If an object has a method `getClone()`, this method is used to create the clone. - * - * @param {*} obj object to be cloned - * @returns {*} - * @license AGPLv3 - * @since 1.0.0 - * @memberOf Monster.Util - * @copyright schukai GmbH - * @throws {Error} unable to clone obj! its type isn't supported. - */ -/** - * The Locale class is a base class for the language classes. - * - * RFC - * - * ``` - * A Language-Tag consists of: - * langtag ; generated tag - * -or- private-use ; a private use tag - * - * langtag = (language - * ["-" script] - * ["-" region] - * *("-" variant) - * *("-" extension) - * ["-" privateuse]) - * - * language = "en", "ale", or a registered value - * - * script = "Latn", "Cyrl", "Hant" ISO 15924 codes - * - * region = "US", "CS", "FR" ISO 3166 codes - * "419", "019", or UN M.49 codes - * - * variant = "rozaj", "nedis", "1996", multiple subtags can be used in a tag - * - * extension = single letter followed by additional subtags; more than one extension - * may be used in a language tag - * - * private-use = "x-" followed by additional subtags, as many as are required - * Note that these can start a tag or appear at the end (but not - * in the middle) - * ``` - * - * @license AGPLv3 - * @since 1.13.0 - * @copyright schukai GmbH - * @memberOf Monster.I18n - * @see https://datatracker.ietf.org/doc/html/rfc3066 - */ -/** - * Parse local according to rfc4646 standard - * - * Limitations: The regex cannot handle multiple variants or private. - * - * You can call the method via this function individually: - * - * ```javascript - * import {createLocale} from '@schukai/monster/source/i18n/locale.mjs'; - * createLocale() - * ``` - * - * RFC - * - * ``` - * The syntax of the language tag in ABNF [RFC4234] is: - * - * Language-Tag = langtag - * / privateuse ; private use tag - * / grandfathered ; grandfathered registrations - * - * langtag = (language - * ["-" script] - * ["-" region] - * *("-" variant) - * *("-" extension) - * ["-" privateuse]) - * - * language = (2*3ALPHA [ extlang ]) ; shortest ISO 639 code - * / 4ALPHA ; reserved for future use - * / 5*8ALPHA ; registered language subtag - * - * extlang = *3("-" 3ALPHA) ; reserved for future use - * - * script = 4ALPHA ; ISO 15924 code - * - * region = 2ALPHA ; ISO 3166 code - * / 3DIGIT ; UN M.49 code - * - * variant = 5*8alphanum ; registered variants - * / (DIGIT 3alphanum) - * - * extension = singleton 1*("-" (2*8alphanum)) - * - * singleton = %x41-57 / %x59-5A / %x61-77 / %x79-7A / DIGIT - * ; "a"-"w" / "y"-"z" / "A"-"W" / "Y"-"Z" / "0"-"9" - * ; Single letters: x/X is reserved for private use - * - * privateuse = ("x"/"X") 1*("-" (1*8alphanum)) - * - * grandfathered = 1*3ALPHA 1*2("-" (2*8alphanum)) - * ; grandfathered registration - * ; Note: i is the only singleton - * ; that starts a grandfathered tag - * - * alphanum = (ALPHA / DIGIT) ; letters and numbers - * - * Figure 1: Language Tag ABNF - * ``` - * - * @param {string} locale - * @returns {Locale} - * @license AGPLv3 - * @since 1.14.0 - * @copyright schukai GmbH - * @memberOf Monster.I18n - * @throws {TypeError} value is not a string - * @throws {Error} unsupported locale - */ -/** - * This method fetches the document object - * - * In nodejs this functionality can be performed with [jsdom](https://www.npmjs.com/package/jsdom). - * - * ``` - * import {JSDOM} from "jsdom" - * if (typeof window !== "object") { - * const {window} = new JSDOM('', { - * url: 'http://example.com/', - * pretendToBeVisual: true - * }); - * - * [ - * 'self', - * 'document', - * 'Document', - * 'Node', - * 'Element', - * 'HTMLElement', - * 'DocumentFragment', - * 'DOMParser', - * 'XMLSerializer', - * 'NodeFilter', - * 'InputEvent', - * 'CustomEvent' - * ].forEach(key => (getGlobal()[key] = window[key])); - * } - * ``` - * - * @returns {object} - * @license AGPLv3 - * @since 1.6.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM - * @throws {Error} not supported environment - */ -/** - * This method fetches the window object - * - * In nodejs this functionality can be performed with [jsdom](https://www.npmjs.com/package/jsdom). - * - * ``` - * import {JSDOM} from "jsdom" - * if (typeof window !== "object") { - * const {window} = new JSDOM('', { - * url: 'http://example.com/', - * pretendToBeVisual: true - * }); - * - * getGlobal()['window']=window; - * - * [ - * 'self', - * 'document', - * 'Document', - * 'Node', - * 'Element', - * 'HTMLElement', - * 'DocumentFragment', - * 'DOMParser', - * 'XMLSerializer', - * 'NodeFilter', - * 'InputEvent', - * 'CustomEvent' - * ].forEach(key => (getGlobal()[key] = window[key])); - * } - * ``` - * - * @returns {object} - * @license AGPLv3 - * @since 1.6.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM - * @throws {Error} not supported environment - */ -/** - * This method fetches the document object - * - * In nodejs this functionality can be performed with [jsdom](https://www.npmjs.com/package/jsdom). - * - * ``` - * import {JSDOM} from "jsdom" - * if (typeof window !== "object") { - * const {window} = new JSDOM('', { - * url: 'http://example.com/', - * pretendToBeVisual: true - * }); - * - * [ - * 'self', - * 'document', - * 'Document', - * 'Node', - * 'Element', - * 'HTMLElement', - * 'DocumentFragment', - * 'DOMParser', - * 'XMLSerializer', - * 'NodeFilter', - * 'InputEvent', - * 'CustomEvent' - * ].forEach(key => (getGlobal()[key] = window[key])); - * } - * ``` - * - * @returns {DocumentFragment} - * @license AGPLv3 - * @since 1.6.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM - * @throws {Error} not supported environment - * @throws {TypeError} value is not a string - */ -/** - * Recursively searches upwards from a given element to find an ancestor element - * with a specified ID, considering both normal DOM and shadow DOM. - * - * @param {HTMLElement|ShadowRoot} element - The starting element or shadow root to search from. - * @param {string} targetId - The ID of the target element to find. - * @returns {HTMLElement|null} - The ancestor element with the specified ID, or null if not found. - * @memberOf Monster.DOM - * @since 3.29.0 - * @license AGPLv3 - * @copyright schukai GmbH - */ -/** - * With this function you can read the language version set by the document. - * For this the attribute `lang` in the html tag is read. If no attribute is set, `en` is used as default. - * Alternatively, the language version of the browser is used. - * - * ```html - * <html lang="en"> - * ``` - * - * You can call the function via `getLocaleOfDocument()`. - * - * @license AGPLv3 - * @since 1.13.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM - * @throws {TypeError} value is not a string - * @throws {Error} unsupported locale - * @summary Tries to determine the locale used - */ -/** - * With the id class, sequences of ids can be created. for this purpose, an internal counter is incremented for each prefix. - * thus, the first id with the prefix `myid` will be `myid1` and the second id `myid2`. - * The ids are the same for every call, for example on a web page. - * - * So the ids can also be used for navigation. you just have to take care that the order stays the same. - * - * As of version 1.6.0 there is the new RandomID. this ID class is continuous from now on. - * - * @license AGPLv3 - * @since 1.0.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - * @summary Automatic generation of ids - */ -/** - * A `TokenList` allows you to manage tokens (individual character strings such as css classes in an attribute string). - * - * The `TokenList` offers various functions to manipulate values. For example, you can add, remove or replace a class in a CSS list. - * - * This class implements the [iteration protocol](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols). - * - * @externalExample ../../example/types/tokenlist-1.mjs - * @license AGPLv3 - * @since 1.2.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - */ -/** - * @memberOf Monster.DOM - * @license AGPLv3 - * @since 1.8.0 - * @type {string} - */ -/** - * This is the name of the attribute to pass options to a control - * - * @memberOf Monster.DOM - * @license AGPLv3 - * @since 1.8.0 - * @type {string} - */ -/** - * This is the name of the attribute to pass options to a control - * - * @memberOf Monster.DOM - * @license AGPLv3 - * @since 1.30.0 - * @type {string} - */ -/** - * @memberOf Monster.DOM - * @type {string} - * @license AGPLv3 - * @since 1.8.0 - */ -/** - * @memberOf Monster.DOM - * @type {string} - * @license AGPLv3 - * @since 1.27.1 - */ -/** - * @memberOf Monster.DOM - * @type {string} - * @license AGPLv3 - * @since 1.9.0 - */ -/** - * @memberOf Monster.DOM - * @type {string} - * @license AGPLv3 - * @since 1.27.0 - */ -/** - * @memberOf Monster.DOM - * @type {string} - * @license AGPLv3 - * @since 1.14.0 - */ -/** - * @memberOf Monster.DOM - * @type {string} - * @license AGPLv3 - * @since 1.24.0 - */ -/** - * @memberOf Monster.DOM - * @type {symbol} - * @license AGPLv3 - * @since 1.24.0 - */ -/** - * @memberOf Monster.DOM - * @type {string} - * @license AGPLv3 - * @since 1.25.0 - */ -/** - * Get the closest object link of a node - * - * if a node is specified without a object link, a recursive search upwards is performed until the corresponding - * object link is found, or undefined is returned. - * - * @param {HTMLElement} element - * @return {HTMLElement|undefined} - * @license AGPLv3 - * @since 1.10.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM - * @throws {TypeError} value is not an instance of HTMLElement - */ -/** - * Adds a class attribute to an element. - * - * @license AGPLv3 - * @since 1.9.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM - * @param {HTMLElement} element - * @param {Symbol} symbol - * @param {Object} object - * @return {boolean} - */ -/** - * Removes an object from an element - * - * @license AGPLv3 - * @since 1.9.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM - * @param {HTMLElement} element - * @param {Symbol} symbol - * @return {boolean} - */ -/** - * Checks if an element has an object link - * - * @license AGPLv3 - * @since 1.9.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM - * @param {HTMLElement} element - * @param {Symbol} symbol - * @return {boolean} - */ -/** - * The ObjectLink can be used to attach objects to HTMLElements. The elements are kept in a set under a unique - * symbol and can be read via an iterator {@see {@link getLinkedObjects}}. - * - * In addition, elements with an objectLink receive the attribute `data-monster-objectlink`. - * - * With the method {@see {@link addToObjectLink}} the objects can be added. - * - * @license AGPLv3 - * @since 1.9.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM - * @param {HTMLElement} element - * @param {Symbol} symbol - * @return {Iterator} - * @throws {Error} there is no object link for symbol - */ -/** - * With this method tokens in an attribute can be switched on or off. For example, classes can be switched on and off in the elements class attribute. - * - * Tokens are always separated by a space. - * - * @license AGPLv3 - * @since 1.9.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM - * @param {HTMLElement} element - * @param {string} key - * @param {string} token - * @return {HTMLElement} - */ -/** - * This method can be used to add a token to an attribute. Tokens are always separated by a space. - * - * @license AGPLv3 - * @since 1.9.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM - * @param {HTMLElement} element - * @param {string} key - * @param {string} token - * @return {HTMLElement} - */ -/** - * This function can be used to remove tokens from an attribute. - * - * Tokens are always separated by a space. - * - * @license AGPLv3 - * @since 1.9.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM - * @param {HTMLElement} element - * @param {string} key - * @param {string} token - * @return {HTMLElement} - */ -/** - * This method can be used to determine whether an attribute has a token. - * - * Tokens are always separated by a space. - * - * @license AGPLv3 - * @since 1.9.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM - * @param {HTMLElement} element - * @param {string} key - * @param {string} token - * @return {boolean} - */ -/** - * Tokens are always separated by a space. - * - * @license AGPLv3 - * @since 1.9.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM - * @param {HTMLElement} element - * @param {string} key - * @param {string} from - * @param {string} to - * @return {HTMLElement} - */ -/** - * Tokens are always separated by a space. - * - * @license AGPLv3 - * @since 1.9.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM - * @param {HTMLElement} element - * @param {string} key - * @return {HTMLElement} - */ -/** - * This function searches, starting from an `HTMLElemement`, for the next element that has a certain attribute. - * - * ```html - * <div data-my-attribute="2" id="2"> - * <div id="1"></div> - * </div> - * ``` - * - * ```javascript - * // if no value is specified (undefined), then only the attribute is checked. - * findClosestByAttribute(document.getElementById('1'),'data-my-attribute'); // ↦ node with id 2 - * findClosestByAttribute(document.getElementById('2'),'data-my-attribute'); // ↦ node with id 2 - * - * // if a value is specified, for example an empty string, then the name and the value are checked. - * findClosestByAttribute(document.getElementById('1'),'data-my-attribute', ''); // ↦ undefined - * findClosestByAttribute(document.getElementById('1'),'data-my-attribute', '2'); // ↦ node with id 2 - * ``` - * - * @license AGPLv3 - * @since 1.14.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM - * @param {HTMLElement} element - * @param {string} key - * @param {string|undefined} value - * @return {HTMLElement|undefined} - * @summary find closest node - */ -/** - * This function searches, starting from an `HTMLElemement`, for the next element that has a certain attribute. - * - * ```html - * <div class="myclass" id="2"> - * <div id="1"></div> - * </div> - * ``` - * - * ```javascript - * // if no value is specified (undefined), then only the attribute is checked. - * findClosestByClass(document.getElementById('1'),'myclass'); // ↦ node with id 2 - * findClosestByClass(document.getElementById('2'),'myclass'); // ↦ node with id 2 - * ``` - * - * ``` - * <script type="module"> - * import {findClosestByClass} from '@schukai/monster/source/dom/attributes.mjs'; - * findClosestByClass(); - * <\/script> - * ``` - * - * @license AGPLv3 - * @since 1.27.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM - * @param {HTMLElement} element - * @param {string} className - * @return {HTMLElement|undefined} - * @summary find closest node - */ -/** - * You can call the method via the monster namespace `new Monster.Types.Queue()`. - * - * @license AGPLv3 - * @since 1.4.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - */ -/** - * Pathfinder is a class to find a path to an object. - * - * With the help of the pathfinder, values can be read and written from an object construct. - * - * ``` - * new Pathfinder({ - * a: { - * b: { - * f: [ - * { - * g: false, - * } - * ], - * } - * } - * }).getVia("a.b.f.0.g"); // ↦ false - * ``` - * - * if a value is not present or has the wrong type, a corresponding exception is thrown. - * - * ``` - * new Pathfinder({}).getVia("a.b.f.0.g"); // ↦ Error - * ``` - * - * The `Pathfinder.exists()` method can be used to check whether access to the path is possible. - * - * ``` - * new Pathfinder({}).exists("a.b.f.0.g"); // ↦ false - * ``` - * - * pathfinder can also be used to build object structures. to do this, the `Pathfinder.setVia()` method must be used. - * - * ``` - * obj = {}; - * new Pathfinder(obj).setVia('a.b.0.c', true); // ↦ {a:{b:[{c:true}]}} - * ``` - * - * @externalExample ../../example/data/pathfinder-1.mjs - * @externalExample ../../example/data/pathfinder-2.mjs - * @license AGPLv3 - * @since 1.4.0 - * @copyright schukai GmbH - * @memberOf Monster.Data - */ -/** - * - * @param {object} subject - * @param {string} path - * @returns {void} - * @throws {TypeError} unsupported type - * @throws {TypeError} unsupported type - * @throws {Error} the journey is not at its end - * @throws {Error} unsupported action for this data type - * @license AGPLv3 - * @since 1.6.0 - * @private - */ -/** - * This is the base class with options from which some monster classes are derived. - * - * This class is actually only used as a base class. - * - * Classes that require the possibility of options can be derived directly from this class. - * Derived classes almost always override the `defaul` getter with their own values. - * - * @externalExample ../../example/types/basewithoptions.mjs - * @license AGPLv3 - * @since 1.13.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - * @deprecated since 3.15.0 use {@link Monster.Types.Base} with {@link Monster.Types.equipWithInternal} instead. - */ -/** - * @memberOf Monster.I18n - * @type {symbol} - * @license AGPLv3 - * @since 3.9.0 - * @private - */ -/** - * A provider makes a translation object available. - * - * @license AGPLv3 - * @since 1.13.0 - * @copyright schukai GmbH - * @memberOf Monster.I18n - * @see {@link https://datatracker.ietf.org/doc/html/rfc3066} - */ -/** - * With this class you can manage translations and access the keys. - * - * @externalExample ../../example/i18n/translations.mjs - * @license AGPLv3 - * @since 1.13.0 - * @copyright schukai GmbH - * @memberOf Monster.I18n - * @see https://datatracker.ietf.org/doc/html/rfc3066 - */ -/** - * The transformer class is a swiss army knife for manipulating values. especially in combination with the pipe, processing chains can be built up. - * - * A simple example is the conversion of all characters to lowercase. for this purpose the command `tolower` must be used. - * - * ``` - * let t = new Transformer('tolower').run('ABC'); // ↦ abc - * ``` - * - * @see {@link https://monsterjs.org/en/doc/#transformer|Monster Docs} - * - * @externalExample ../../example/data/transformer.mjs - * @license AGPLv3 - * @since 1.5.0 - * @copyright schukai GmbH - * @memberOf Monster.Data - */ -/** - * The pipe class makes it possible to combine several processing steps. - * - * A pipe consists of commands whose input and output are connected with the pipe symbol `|`. - * - * With the Pipe, processing steps can be combined. Here, the value of an object is accessed via the pathfinder (path command). - * the word is then converted to uppercase letters and a prefix Hello is added. the two backslash safe the space char. - * - * @externalExample ../../example/data/pipe.mjs - * @license AGPLv3 - * @since 1.5.0 - * @copyright schukai GmbH - * @memberOf Monster.Data - */ -/** - * Messages can be formatted with the formatter. To do this, an object with the values must be passed to the formatter. The message can then contain placeholders. - * - * Look at the example below. The placeholders use the logic of Pipe. - * - * ## Marker in marker - * - * Markers can be nested. Here, the inner marker is resolved first `${subkey} ↦ 1 = ${mykey2}` and then the outer marker `${mykey2}`. - * - * ``` - * const text = '${mykey${subkey}}'; - * let obj = { - * mykey2: "1", - * subkey: "2" - * }; - * - * new Formatter(obj).format(text); - * // ↦ 1 - * ``` - * - * ## Callbacks - * - * The values in a formatter can be adjusted via the commands of the `Transformer` or the`Pipe`. - * There is also the possibility to use callbacks. - * - * const formatter = new Formatter({x: '1'}, { - * callbacks: { - * quote: (value) => { - * return '"' + value + '"' - * } - * } - * }); - * - * formatter.format('${x | call:quote}')) - * // ↦ "1" - * - * ## Marker with parameter - * - * A string can also bring its own values. These must then be separated from the key by a separator `::`. - * The values themselves must be specified in key/value pairs. The key must be separated from the value by a separator `=`. - * - * When using a pipe, you must pay attention to the separators. - * - * @example - * - * import {Formatter} from '@schukai/monster/source/text/formatter.mjs'; - * - * new Formatter({ - * a: { - * b: { - * c: "Hello" - * }, - * d: "world", - * } - * }).format("${a.b.c} ${a.d | ucfirst}!"); // with pipe - * - * // ↦ Hello World! - * - * @license AGPLv3 - * @since 1.12.0 - * @copyright schukai GmbH - * @memberOf Monster.Text - */ -/** - * @private - * @license AGPLv3 - * @since 1.12.0 - * @param text - * @return {string} - */ -/** - * @private - * @param {String|undefined} query - * @param {String|undefined|null} name name of the slot (if the parameter is undefined, all slots are searched, if the parameter has the value null, all slots without a name are searched. if a string is specified, the slots with this name are searched.) - * @return {*} - * @this CustomElement - * @license AGPLv3 - * @since 3.33.0 - * @throws {Error} query must be a string - */ -/** - * @private - * @param {String|undefined} query - * @param {String|undefined|null} name name of the slot (if the parameter is undefined, all slots are searched, if the parameter has the value null, all slots without a name are searched. if a string is specified, the slots with this name are searched.) - * @return {*} - * @this CustomElement - * @license AGPLv3 - * @since 1.23.0 - * @throws {Error} query must be a string - */ -/** - * A queue is a list of items that are processed one after another (first in, first out). - * - * With a queue you can add items to the end of the list `Queue.add()` and remove items from the beginning of the list `Queue.pop()`. - * - * With `Queue.peek()` you can get the first item without removing it from the list. - * - * You can create the instance via `new Queue()`. - * - * @externalExample ../../example/types/queue.mjs - * @license AGPLv3 - * @since 1.4.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - * @summary A Queue (Fifo) - */ -/** - * An UniqueQueue is a queue that contains items only once. - * - * @license AGPLv3 - * @since 1.4.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - * @summary A queue for unique values - */ -/** - * An observer manages a callback function - * - * The update method is called with the subject object as this pointer. For this reason the callback should not - * be an arrow function, because it gets this pointer of its own context. - * - * ```js - * new Observer(()=>{ - * // this is not subject - * }) - * - * new Observer(function() { - * // this is subject - * }) - * ``` - * - * Additional arguments can be passed to the callback. To do this, simply specify them. - * - * ```js - * Observer(function(a, b, c) { - * console.log(a, b, c); // ↦ "a", 2, true - * }, "a", 2, true) - * ``` - * - * The callback function must have as many parameters as arguments are given. - * - * @externalExample ../../example/types/observer.mjs - * @license AGPLv3 - * @since 1.0.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - */ -/** - * With the help of the ObserverList class, observer can be managed. - * - * @license AGPLv3 - * @since 1.0.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - */ -/** - * An observer manages a callback function - * - * With the ProxyObserver you can attach observer for observation. - * With each change at the object to be observed an update takes place. - * - * This also applies to nested objects. - * - * @externalExample ../../example/types/proxyobserver.mjs - * @license AGPLv3 - * @since 1.0.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - */ -/** - * This class is the base class for all resources to be loaded. - * - * @license AGPLv3 - * @since 1.25.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM - * @summary A Resource class - */ -/** - * You can create an object via the monster namespace `new Monster.Types.MediaType()`. - * - * @license AGPLv3 - * @since 1.8.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - */ -/** - * @private - * @license AGPLv3 - * @since 1.18.0 - * @param {String} parameter - * @return {Monster.Types.Parameter[]|undefined} - * @memberOf Monster.Types - */ -/** - * You can create an object via the monster namespace `new Monster.Types.DataUrl()`. - * - * @license AGPLv3 - * @since 1.8.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs - * @see https://datatracker.ietf.org/doc/html/rfc2397 - */ -/** - * With the diff function you can perform the change of one object to another. The result shows the changes of the second object to the first object. - * - * The operator `add` means that something has been added to the second object. `delete` means that something has been deleted from the second object compared to the first object. - * - * @externalExample ../../example/data/diff.mjs - * @param {*} first - * @param {*} second - * @return {array} - * @license AGPLv3 - * @since 1.6.0 - * @copyright schukai GmbH - * @memberOf Monster.Data - */ -/** - * This special trim function allows to trim spaces that have been protected by a special escape character. - * - * ``` - * <script type="module"> - * import {trimSpaces} from '@schukai/monster/source/util/trimspaces.mjs'; - * trimSpaces(' hello \\ ') - * <\/script> - * ``` - * - * Hint: One stroke is escaped by the javascript interpreter, the second stroke escapes the stroke. - * - * ```text - * a\ b ↦ a b - * a\\ b ↦ a\ b - * ``` - * - * @license AGPLv3 - * @since 1.24.0 - * @memberOf Monster.Util - * @copyright schukai GmbH - * @param {string} value - * @return {string} - * @throws {TypeError} value is not a string - */ -/** - * The function sends an event - * - * @param {HTMLElement|HTMLCollection|NodeList} element - * @param {string} type - * @return {void} - * @license AGPLv3 - * @since 1.10.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM - * @throws {TypeError} value is not an instance of HTMLElement or HTMLCollection - * @summary Construct and send and event - */ -/** - * You can call the function via the monster namespace `new Monster.DOM.fireCustomEvent()`. - * - * @param {HTMLElement|HTMLCollection|NodeList} element - * @param {string} type - * @return {void} - * @license AGPLv3 - * @since 1.29.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM - * @throws {TypeError} value is not an instance of HTMLElement or HTMLCollection - * @summary Construct and send and event - */ -/** - * This function gets the path `Event.composedPath()` from an event and tries to find the next element - * up the tree `element.closest()` with the attribute and value. If no value, or a value that is undefined or null, - * is specified, only the attribute is searched. - * - * @license AGPLv3 - * @since 1.14.0 - * @param {Event} event - * @param {string} attributeName - * @param {string|null|undefined} attributeValue - * @throws {Error} unsupported event - * @memberOf Monster.DOM - * @throws {TypeError} value is not a string - * @throws {TypeError} value is not an instance of HTMLElement - * @summary Help function to find the appropriate control - */ -/** - * The Theme class provides the functionality for the theme. - * - * @externalExample ../../example/dom/theme.mjs - * @license AGPLv3 - * @since 1.7.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM - * @summary A theme class - */ -/** - * The theming used in the document can be defined via the html-tag. - * The theming is specified via the attribute `data-monster-theme-name`. - * - * As name for a theme all characters are valid, which are also allowed for a HTMLElement-ID. - * - * ``` - * <html data-monster-theme-name="my-theme"> - * ``` - * - * the default theme name is `monster`. - * - * @return {Theme} - * @memberOf Monster.DOM - * @license AGPLv3 - * @since 1.7.0 - */ -/** - * The template class provides methods for creating templates. - * - * @license AGPLv3 - * @since 1.6.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM - * @summary A template class - */ -/** - * This method loads a template with the given ID and returns it. - * - * To do this, it first reads the theme of the document and looks for the `data-monster-theme-name` attribute in the HTML tag. - * - * ``` - * <html data-monster-theme-name="my-theme"> - * ``` - * - * If no theme was specified, the default theme is `monster`. - * - * Now it is looked if there is a template with the given ID and theme `id-theme` and if yes it is returned. - * If there is no template a search for a template with the given ID `id` is done. If this is also not found, an error is thrown. - * - * You can call the method via the monster namespace `Monster.DOM.findDocumentTemplate()`. - * - * ``` - * <script type="module"> - * import {findTemplate} from '@schukai/monster/source/dom/template.mjs'; - * findDocumentTemplate() - * <\/script> - * ``` - * - * @example - * - * import { findDocumentTemplate } from "https://cdn.jsdelivr.net/npm/@schukai/monster@latest/source/dom/template.mjs"; - * - * const template = document.createElement("template"); - * template.id = "myTemplate"; - * template.innerHTML = "<p>my default template</p>"; - * document.body.appendChild(template); - * - * const themedTemplate = document.createElement("template"); - * themedTemplate.id = "myTemplate-myTheme"; - * themedTemplate.innerHTML = "<p>my themed template</p>"; - * document.body.appendChild(themedTemplate); - * - * // loads the temple and since no theme is set the default template - * const template1 = findDocumentTemplate("myTemplate"); - * console.log(template1.createDocumentFragment()); - * // ↦ '<p>my default template</p>' - * - * // now we set our own theme - * document - * .querySelector("html") - * .setAttribute("data-monster-theme-name", "myTheme"); - * - * // now we don't get the default template, - * // but the template with the theme in the id - * const template2 = findDocumentTemplate("myTemplate"); - * console.log(template2.createDocumentFragment()); - * // ↦ '<p>my themed template</p>' - * - * @param {string} id - * @param {Node} currentNode - * @return {Monster.DOM.Template} - * @license AGPLv3 - * @since 1.7.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM - * @throws {Error} template id not found. - * @throws {TypeError} value is not a string - */ -/** - * The updater class connects an object with the dom. In this way, structures and contents in the DOM can be programmatically adapted via attributes. - * - * For example, to include a string from an object, the attribute `data-monster-replace` can be used. - * a further explanation can be found under {@tutorial dom-based-templating-implementation}. - * - * Changes to attributes are made only when the direct values are changed. If you want to assign changes to other values - * as well, you have to insert the attribute `data-monster-select-this`. This should be done with care, as it can reduce performance. - * - * @externalExample ../../example/dom/updater.mjs - * @license AGPLv3 - * @since 1.8.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM - * @throws {Error} the value is not iterable - * @throws {Error} pipes are not allowed when cloning a node. - * @throws {Error} no template was found with the specified key. - * @throws {Error} the maximum depth for the recursion is reached. - * @throws {TypeError} value is not a object - * @throws {TypeError} value is not an instance of HTMLElement - * @summary The updater class connects an object with the dom - */ -/** - * @private - * @license AGPLv3 - * @since 1.9.0 - * @return {function - * @this Updater - */ -/** - * @license AGPLv3 - * @since 1.27.0 - * @return void - * @private - */ -/** - * @private - * @license AGPLv3 - * @since 1.8.0 - * @param {object} change - * @return {void} - */ -/** - * @private - * @license AGPLv3 - * @since 1.8.0 - * @param {object} change - * @return {void} - * @throws {Error} the value is not iterable - * @throws {Error} pipes are not allowed when cloning a node. - * @throws {Error} no template was found with the specified key. - * @throws {Error} the maximum depth for the recursion is reached. - * @this Updater - */ -/** - * - * @private - * @license AGPLv3 - * @since 1.8.0 - * @param {HTMLElement} container - * @param {string} key - * @param {string} ref - * @param {string} path - * @throws {Error} no template was found with the specified key. - */ -/** - * @private - * @license AGPLv3 - * @since 1.10.0 - * @param {HTMLElement} node - * @param {string} key - * @param {string} path - * @return {void} - */ -/** - * @private - * @license AGPLv3 - * @since 1.8.0 - * @param {object} change - * @return {void} - * @this Updater - */ -/** - * @private - * @license AGPLv3 - * @since 1.8.0 - * @param {HTMLElement} container - * @param {array} parts - * @param {object} subject - * @return {void} - */ -/** - * @private - * @license AGPLv3 - * @since 1.8.0 - * @param {string} path - * @param {object} change - * @return {void} - */ -/** - * @param {NodeList|HTMLElement|Set<HTMLElement>} elements - * @param {Symbol} symbol - * @param {object} object - * @return {Promise[]} - * @license AGPLv3 - * @since 1.23.0 - * @memberOf Monster.DOM - * @throws {TypeError} elements is not an instance of NodeList, HTMLElement or Set - * @throws {TypeError} the context of the function is not an instance of HTMLElement - * @throws {TypeError} symbol must be an instance of Symbol - */ -/** - * To define a new HTML element we need the power of CustomElement - * - * IMPORTANT: after defining a `CustomElement`, the `registerCustomElement` method must be called - * with the new class name. only then will the tag defined via the `getTag` method be made known to the DOM. - * - * <img src="./images/customelement-class.png"> - * - * You can create the object via the function `document.createElement()`. - * - * - * ## Interaction - * - * <img src="./images/customelement-sequencediagram.png"> - * - * ## Styling - * - * For optimal display of custom-elements the pseudo-class :defined can be used. - * - * To prevent the custom elements from being displayed and flickering until the control is registered, it is recommended to create a css directive. - * - * In the simplest case, you can simply hide the control. - * - * ``` - * <style> - * - * my-custom-element:not(:defined) { - * display: none; - * } - * - * my-custom-element:defined { - * display: flex; - * } - * - * </style> - * ``` - * - * Alternatively you can also display a loader - * - * ``` - * my-custom-element:not(:defined) { - * display: flex; - * box-shadow: 0 4px 10px 0 rgba(33, 33, 33, 0.15); - * border-radius: 4px; - * height: 200px; - * position: relative; - * overflow: hidden; - * } - * - * my-custom-element:not(:defined)::before { - * content: ''; - * display: block; - * position: absolute; - * left: -150px; - * top: 0; - * height: 100%; - * width: 150px; - * background: linear-gradient(to right, transparent 0%, #E8E8E8 50%, transparent 100%); - * animation: load 1s cubic-bezier(0.4, 0.0, 0.2, 1) infinite; - * } - * - * @keyframes load { - * from { - * left: -150px; - * } - * to { - * left: 100%; - * } - * } - * - * my-custom-element:defined { - * display: flex; - * } - * ``` - * - * @externalExample ../../example/dom/theme.mjs - * @see https://github.com/WICG/webcomponents - * @see https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements - * @license AGPLv3 - * @since 1.7.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM - * @extends external:HTMLElement - * @summary A base class for HTML5 customcontrols - */ -/** - * @license AGPLv3 - * @since 1.15.0 - * @private - * @this CustomElement - */ -/** - * @private - * @return {CustomElement} - * @memberOf Monster.DOM - * @this CustomElement - * @license AGPLv3 - * @since 1.16.0 - * @throws {TypeError} value is not an instance of - */ -/** - * @private - * @return {CustomElement} - * @throws {Error} html is not set. - * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow - * @memberOf Monster.DOM - * @license AGPLv3 - * @since 1.8.0 - */ -/** - * This method registers a new element. The string returned by `CustomElement.getTag()` is used as the tag. - * - * @param {CustomElement} element - * @return {void} - * @license AGPLv3 - * @since 1.7.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM - * @throws {DOMException} Failed to execute 'define' on 'CustomElementRegistry': is not a valid custom element name - */ -/** - * To define a new HTML control we need the power of CustomElement - * - * IMPORTANT: after defining a `CustomElement`, the `registerCustomElement` method must be called - * with the new class name. only then will the tag defined via the `getTag` method be made known to the DOM. - * - * <img src="./images/customcontrol-class.png"> - * - * This control uses `attachInternals()` to integrate the control into a form. - * If the target environment does not support this method, the [polyfill](https://www.npmjs.com/package/element-internals-polyfill ) can be used. - * - * You can create the object via the function `document.createElement()`. - * - * @startuml customcontrol-class.png - * skinparam monochrome true - * skinparam shadowing false - * HTMLElement <|-- CustomElement - * CustomElement <|-- CustomControl - * @enduml - * - * @summary A base class for customcontrols based on CustomElement - * @see {@link https://www.npmjs.com/package/element-internals-polyfill} - * @see {@link https://github.com/WICG/webcomponents} - * @see {@link https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements} - * @license AGPLv3 - * @since 1.14.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM - */ -/** - * This variable is a promise that is fulfilled as soon as the dom is available. - * - * The DOMContentLoaded event is fired when the original HTML document is fully loaded and parsed - * without waiting for stylesheets, images, and subframes to finish loading. - * - * document.readyState changes to interactive - * window's DOMContentLoaded event gets fired - * document.readyState changes to complete - * window's load event gets fired load - * - * @license AGPLv3 - * @since 1.31.0 - * @memberOf Monster.DOM - * @summary variable to check if dom is ready - * @type {Promise} - * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/DOMContentLoaded_event - * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState - */ -/** - * This variable is a promise that is fulfilled as soon as the windows is available. - * - * The load event fires when the entire page is loaded, including all dependent resources such as stylesheets, - * assets, and images. Unlike DOMContentLoaded, which fires as soon as the DOM of the page is loaded, - * without waiting for the resources to finish loading. - * - * @license AGPLv3 - * @since 1.31.0 - * @memberOf Monster.DOM - * @summary variable to check if window is ready - * @type {Promise} - * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event - * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState - */ -/** - * this function uses crypt and returns a random number. - * - * @param {number} min starting value of the definition set (default is 0) - * @param {number} max end value of the definition set (default is 1000000000) - * @returns {number} - * @memberOf Monster.Math - * @throws {Error} missing crypt - * @throws {Error} we cannot generate numbers larger than 53 bits. - * @throws {Error} the distance is too small to create a random number. - - * @license AGPLv3 - * @since 1.0.0 - * @copyright schukai GmbH - */ -/** - * The `RandomID` class provides a unique ID for an item. - * - * @license AGPLv3 - * @since 1.6.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - * @summary class to generate random numbers - */ -/** - * The UUID class makes it possible to get a unique UUID for an object. - * - * @license AGPLv3 - * @since 1.25.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - * @throws {Error} unsupported - */ -/** - * The version object contains a semantic version number - * - * @externalExample ../../example/types/version-1.mjs - * @license AGPLv3 - * @since 1.0.0 - * @author schukai GmbH - * @copyright schukai GmbH - * @memberOf Monster.Types - * @summary The version object contains a sematic version number - */ -/** - * Version of monster - * - * @externalExample ../../example/types/version-2.mjs - * @returns {Monster.Types.Version} - * @license AGPLv3 - * @since 1.0.0 - * @copyright schukai GmbH - * @author schukai GmbH - * @memberOf Monster - */ -/** - * A log entry for the logger - * - * @license AGPLv3 - * @since 1.5.0 - * @copyright schukai GmbH - * @memberOf Monster.Logging - */ -/** - * The log handler is the interface between the log entries and the log listeners. - * - * @license AGPLv3 - * @since 1.5.0 - * @copyright schukai GmbH - * @memberOf Monster.Logging - */ -/** - * The logger is a class that takes care of logging. - * - * @license AGPLv3 - * @since 1.5.0 - * @copyright schukai GmbH - * @memberOf Monster.Logging - */ -/** - * You can create an object of the class simply by using the namespace `new Monster.Logging.Handler.ConsoleHandler()`. - * - * @license AGPLv3 - * @since 1.5.0 - * @copyright schukai GmbH - * @memberOf Monster.Logging.Handler - */ -/** - * This class is used by the resource manager to embed external resources. - * - * @license AGPLv3 - * @since 1.25.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM.Resource - * @summary A Resource class - * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link - */ -/** - * This class is used by the resource manager to embed data. - * - * @license AGPLv3 - * @since 1.25.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM.Resource - * @summary A Data Resource class - */ -/** - * This class is used by the resource manager to embed scripts. - * - * @license AGPLv3 - * @since 1.25.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM.Resource - * @summary A Resource class - */ -/** - * This function extends the given object with the following methods: - * - * - attachInternalObserver - * - detachInternalObserver - * - containsInternalObserver - * - setInternal - * - setInternals - * - getInternal - * - * @license AGPLv3 - * @since 3.15.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - */ -/** - * The ResourceManager is a singleton that manages all resources. - * - * @license AGPLv3 - * @since 1.25.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM - * @summary A Resource class - */ -/** - * Converts a CSS value to pixels. - * - * As Example: - * - * ```js - * convertToPixels('1em') // returns the current font size in pixels - * convertToPixels('1rem') // returns the current root font size in pixels - * convertToPixels('1px') // returns 1 - * convertToPixels('100%') // returns the current width of the parent element in pixels - * ``` - * - * Following units are supported: - * - px - * - em - * - rem - * - % - * - * @param {string} value - * @param {HTMLElement} [parentElement=document.documentElement] - * @param {HTMLElement} [fontSizeElement=document.documentElement] - * @returns {number} - * @license AGPLv3 - * @since 3.34.0 - * @copyright schukai GmbH - * @throws {Error} Unsupported unit - * @memberOf Monster.DOM - * @throws {Error} Invalid value format - */ -/** - * A factory for creating worker instances. - * - * @license AGPLv3 - * @since 1.25.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM.Worker - * @summary A small factory to create worker - */ -/** - * With the focus manager the focus can be stored in a document, recalled and moved. - * - * @license AGPLv3 - * @since 1.25.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM - * @throws {Error} unsupported locale - * @summary Handle the focus - */ -/** - * Assembler class - * - * @license AGPLv3 - * @since 1.6.0 - * @copyright schukai GmbH - * @memberOf Monster.DOM - * @summary Allows you to build an html fragment - */ -/** - * The Embed provider retrieves a JSON file from the given Script Tag. - * - * @externalExample ../../../example/i18n/providers/embed.mjs - * @license AGPLv3 - * @since 1.13.0 - * @copyright schukai GmbH - * @memberOf Monster.I18n.Providers - * @see {@link https://datatracker.ietf.org/doc/html/rfc3066} - * @tutorial i18n-locale-and-formatter - */ -/** - * The Formatter extends the Text.Formatter with the possibility to replace the key by a translation. - * - * @externalExample ../../example/i18n/formatter.mjs - * @license AGPLv3 - * @since 1.26.0 - * @copyright schukai GmbH - * @memberOf Monster.I18n - */ -/** - * The fetch provider retrieves a JSON file from the given URL and returns a translation object. - * - * @externalExample ../../../example/i18n/providers/fetch.mjs - * @license AGPLv3 - * @since 1.13.0 - * @copyright schukai GmbH - * @memberOf Monster.I18n.Providers - * @see {@link https://datatracker.ietf.org/doc/html/rfc3066} - * @tutorial i18n-locale-and-formatter - */ -/** - * This class represents a WebSocket message. - * - * @license AGPLv3 - * @since 3.4.0 - * @copyright schukai GmbH - * @memberOf Monster.Net.WebSocket - * @summary The Message class encapsulates a WebSocket message. - */ -/** - * An observable queue is a list of items that are processed one after another (first in, first out). - * - * `Queue.add()` and `Queue.clear()` notify all observers. - * - * @externalExample ../../example/types/queue.mjs - * @license AGPLv3 - * @since 3.3.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - * @summary An observable Queue (Fifo) - */ -/** - * The RestAPI is a class that enables a REST API server. - * - * @externalExample ../../example/net/webconnect.mjs - * @license AGPLv3 - * @since 3.1.0 - * @copyright schukai GmbH - * @memberOf Monster.Net - * @summary The LocalStorage class encapsulates the access to data objects. - */ -/** - * You can call the function via the monster namespace `Monster.Types.toBinary()`. - * - * @param {String} binary - * @return {String} - * @throws {TypeError} value is not a string - * @memberOf Monster.Types - * @license AGPLv3 - * @since 1.18.0 - */ -/** - * You can call the function via the monster namespace `Monster.Types.fromBinary()`. - * - * @param {String} binary - * @return {String} - * @throws {TypeError} value is not a string - * @memberOf Monster.Types - * @license AGPLv3 - * @since 1.18.0 - */ -/** - * This function prefixes all special characters that may appear in a regex with a slash. - * - * @param {string} value - * @return {string} - * @license AGPLv3 - * @since 1.26.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - * @throws {TypeError} value is not a string - */ -/** - * You can create the instance via the monster namespace `new Monster.Types.NodeList()`. - * - * @license AGPLv3 - * @since 1.26.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - * @summary A NodeList class - */ -/** - * You can create the instance via the monster namespace `new Monster.Types.Node()`. - * - * @license AGPLv3 - * @since 1.26.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - * @summary A Node Class - * @see https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Iteration_protocols - */ -/** - * You can create the instance via the monster namespace `new Monster.Types.NodeRecursiveIterator()`. - * - * @externalExample ../../example/types/noderecursiveiterator.mjs - * @license AGPLv3 - * @since 1.26.0 - * @copyright schukai GmbH - * @memberOf Monster.Types - * @summary An iterator to run recursively through a tree of nodes - */ -/** - * Constraints are used to define conditions that must be met by the value of a variable. - * - * The uniform API of the constraints allows chains to be formed. - * - * The abstract constraint defines the api for all constraints. mainly the method isValid() is defined. - * - * Derived classes must implement the method isValid(). - * - * @license AGPLv3 - * @since 1.3.0 - * @copyright schukai GmbH - * @memberOf Monster.Constraints - * @summary The abstract constraint - */ -/** - * Constraints are used to define conditions that must be met by the value of a variable. - * - * The uniform API of the constraints allows chains to be formed. - * - * @externalExample ../../example/constraints/isobject.mjs - * @license AGPLv3 - * @since 1.3.0 - * @copyright schukai GmbH - * @memberOf Monster.Constraints - * @summary A constraint to check if a value is an object - */ -/** - * Constraints are used to define conditions that must be met by the value of a variable. - * - * The uniform API of the constraints allows chains to be formed. - * - * The invalid constraint allows an always invalid query to be performed. this constraint is mainly intended for testing. - * - * @externalExample ../../example/constraints/invalid.mjs - * @license AGPLv3 - * @since 1.3.0 - * @copyright schukai GmbH - * @memberOf Monster.Constraints - * @summary A constraint that always invalid - */ -/** - * Constraints are used to define conditions that must be met by the value of a variable. - * - * The uniform API of the constraints allows chains to be formed. - * - * The valid constraint allows an always valid query to be performed. this constraint is mainly intended for testing. - * - * @externalExample ../../example/constraints/valid.mjs - * @license AGPLv3 - * @since 1.3.0 - * @copyright schukai GmbH - * @memberOf Monster.Constraints - * @summary A constraint that always valid - */ -/** - * Constraints are used to define conditions that must be met by the value of a variable. - * - * The uniform API of the constraints allows chains to be formed. - * - * Operators allow you to link constraints together. for example, you can check whether a value is - * an object or an array. each operator has two operands that are linked together. - * - * @license AGPLv3 - * @since 1.3.0 - * @copyright schukai GmbH - * @memberOf Monster.Constraints - * @summary The abstract operator constraint - */ -/** - * Constraints are used to define conditions that must be met by the value of a variable. - * - * The uniform API of the constraints allows chains to be formed. - * - * The AndOperator is used to link several constraints. The constraint is fulfilled if all constraints of the operators are fulfilled. - * - * @externalExample ../../example/constraints/andoperator.mjs - * @license AGPLv3 - * @since 1.3.0 - * @copyright schukai GmbH - * @memberOf Monster.Constraints - * @summary A and operator constraint - */ -/** - * Constraints are used to define conditions that must be met by the value of a variable. - * - * The uniform API of the constraints allows chains to be formed. - * - * The OrOperator is used to link several constraints. The constraint is fulfilled if one of the constraints is fulfilled. - * - * @externalExample ../../example/constraints/oroperator.mjs - * @license AGPLv3 - * @since 1.3.0 - * @copyright schukai GmbH - * @memberOf Monster.Constraints - * @summary A or operator - */ -/** - * Constraints are used to define conditions that must be met by the value of a variable. - * - * The uniform API of the constraints allows chains to be formed. - * - * @externalExample ../../example/constraints/isarray.mjs - * @license AGPLv3 - * @since 1.3.0 - * @copyright schukai GmbH - * @memberOf Monster.Constraints - * @summary A constraint to check if a value is an array - */ -/** - * The dead man's switch allows to set a timer which can be reset again and again within a defined period of time. - * - * @externalExample ../../example/util/deadmansswitch.mjs - * @copyright schukai GmbH - * @license AGPLv3 - * @since 1.29.0 - * @memberOf Monster.Util - * @summary Class to be able to execute function chains - */ -/** - * Deep freeze a object - * - * @param {object} object object to be freeze - * @license AGPLv3 - * @since 1.0.0 - * @returns {object} - * @memberOf Monster.Util - * @copyright schukai GmbH - * @throws {TypeError} value is not a object - */ -/** - * The comparator allows a comparison function to be abstracted. - * - * The following are some examples of the application of the class. - * - * ``` - * new Comparator().lessThanOrEqual(2, 5) // ↦ true - * new Comparator().greaterThan(4, 2) // ↦ true - * new Comparator().equal(4, 4) // ↦ true - * new Comparator().equal(4, 5) // ↦ false - * ``` - * - * You can also pass your own comparison function, and thus define the comparison function. - * - * ``` - * new Comparator(function (a, b) { - * if (a.v === b.v) return 0; - * return a.v < b.v ? -1 : 1; - * }).equal({v: 2}, {v: 2}); // ↦ true - * ``` - * - * @externalExample ../../example/util/comparator.mjs - * @license AGPLv3 - * @since 1.3.0 - * @memberOf Monster.Util - */ -/** - * This class allows to execute several functions in order. - * - * Functions and timeouts can be passed. If a timeout is passed, it applies to all further functions. - * In the example - * - * `timeout1, function1, function2, function3, timeout2, function4` - * - * the timeout1 is valid for the functions 1, 2 and 3 and the timeout2 for the function4. - * - * So the execution time is timeout1+timeout1+timeout1+timeout2 - * - * The result of `run()` is a promise. - * - * @externalExample ../../example/util/processing.mjs - * @copyright schukai GmbH - * @license AGPLv3 - * @since 1.21.0 - * @memberOf Monster.Util - * @summary Class to be able to execute function chains - */ -/** - * Alternatively to a string selector a callback can be specified. this must return a map. - * - * @example - * import {buildMap} from '@schukai/monster/source/data/buildmap.mjs'; - * - * let obj = { - * "data": [ - * { - * "id": 10, - * "name": "Cassandra", - * "enrichment": { - * variants: [ - * { - * sku: 1, label: "XXS", price: [ - * {vk: '12.12 €'}, - * {vk: '12.12 €'} - * ] - * }, - * { - * sku: 2, label: "XS", price: [ - * {vk: '22.12 €'}, - * {vk: '22.12 €'} - * ] - * }, - * { - * sku: 3, label: "S", price: [ - * {vk: '32.12 €'}, - * {vk: '32.12 €'} - * ] - * }, - * { - * sku: 4, label: "L", price: [ - * {vk: '42.12 €'}, - * {vk: '42.12 €'} - * ] - * } - * ] - * - * } - * }, - * { - * "id": 20, - * "name": "Yessey!", - * "enrichment": { - * variants: [ - * { - * sku: 1, label: "XXS", price: [ - * {vk: '12.12 €'}, - * {vk: '12.12 €'} - * ] - * }, - * { - * sku: 2, label: "XS", price: [ - * {vk: '22.12 €'}, - * {vk: '22.12 €'} - * ] - * }, - * { - * sku: 3, label: "S", price: [ - * {vk: '32.12 €'}, - * {vk: '32.12 €'} - * ] - * }, - * { - * sku: 4, label: "L", price: [ - * {vk: '42.12 €'}, - * {vk: '42.12 €'} - * ] - * } - * ] - * - * } - * } - * ] - * }; - * - * let callback = function (subject) { - * let m = new Map; - * - * for (const [i, b] of Object.entries(subject.data)) { - * - * let key1 = i; - * - * for (const [j, c] of Object.entries(b.enrichment.variants)) { - * let key2 = j; - * - * for (const [k, d] of Object.entries(c.price)) { - * - * let key3 = k; - * - * d.name = b.name; - * d.label = c.label; - * d.id = [key1, key2, key3].join('.'); - * - * m.set(d.id, d); - * } - * - * } - * } - * return m; - * } - * - * let map = buildMap(obj, callback, '${name} ${vk}', '${id}') - * - * // ↦ Map(3) { - * // "0.0.0":"Cassandra 12.12 €", - * // "0.0.1":"Cassandra 12.12 €", - * // "0.1.0":"Cassandra 22.12 €", - * // "0.1.1":"Cassandra 22.12 €", - * // "0.2.0":"Cassandra 32.12 €", - * // "0.2.1":"Cassandra 32.12 €", - * // "0.3.0":"Cassandra 42.12 €", - * // "0.3.1":"Cassandra 42.12 €", - * // "1.0.0":"Yessey! 12.12 €", - * // "1.0.1":"Yessey! 12.12 €", - * // "1.1.0":"Yessey! 22.12 €", - * // "1.1.1":"Yessey! 22.12 €", - * // "1.2.0":"Yessey! 32.12 €", - * // "1.2.1":"Yessey! 32.12 €", - * // "1.3.0":"Yessey! 42.12 €", - * // "1.3.1":"Yessey! 42.12 €" - * // } - * - * @callback Monster.Data~exampleSelectorCallback - * @param {*} subject subject - * @return Map - * @license AGPLv3 - * @since 1.17.0 - * @memberOf Monster.Data - * @see {@link Monster.Data.buildMap} - */ -/** - * @private - * @type {symbol} - * @memberOf Monster.Data - * @license AGPLv3 - * @since 1.24.0 - */ -/** - * The datasource class is the basis for dealing with different data sources. - * It provides a unified interface for accessing data - * @externalExample ../../example/data/datasource.mjs - * @license AGPLv3 - * @since 1.22.0 - * @copyright schukai GmbH - * @memberOf Monster.Data - * @summary The datasource class encapsulates the access to data objects. - */ -/** - * Creates a tree structure from a given subject using a selector and specified ID and parent ID keys. - * - * The buildTree function is a powerful tool for creating tree-like data structures from plain JavaScript - * objects. It takes in four required parameters: the subject object that you want to turn into a tree, a - * selector that identifies which parts of the subject to use when building the tree, and two keys - * (idKey and parentIDKey) that specify which properties in the subject represent the unique identifiers - * and parent-child relationships between nodes in the tree. - * - * Optionally, you can also pass in an options object to further configure the behavior of the function, - * such as specifying which values should be treated as roots of the tree, or providing a custom filter - * function to only include certain nodes in the final output. - * - * The buildTree function works by first using the assembleParts helper function to extract the relevant - * parts of the subject based on the selector, and then iterates over the resulting map to create Node - * objects and organize them into parent-child relationships based on the values of the idKey and parentIDKey properties. - * - * The resulting NodeList represents the tree structure, with each Node object containing the original - * object data as well as additional metadata about its position in the tree. You can then use the childNodes - * property of each Node to access its children, or the parent property to access its parent. - * - * Overall, the buildTree function is a flexible and powerful way to transform flat data into hierarchical - * structures, and can be especially useful in scenarios such as displaying folder structures or - * visualizing complex data relationships. - * - * Let's say you have an array of data objects representing a file system directory structure, and you want - * to turn it into a tree-like structure where each node represents a folder or file, and child nodes - * represent the contents of the folder: - * - * ```javascript - * const fileSystem = [ - * { id: 'folder1', name: 'Folder 1', type: 'folder', parent: null }, - * { id: 'file1', name: 'File 1', type: 'file', parent: 'folder1' }, - * { id: 'file2', name: 'File 2', type: 'file', parent: 'folder1' }, - * { id: 'subfolder1', name: 'Subfolder 1', type: 'folder', parent: 'folder1' }, - * { id: 'file3', name: 'File 3', type: 'file', parent: 'subfolder1' }, - * { id: 'file4', name: 'File 4', type: 'file', parent: 'subfolder1' }, - * { id: 'subfolder2', name: 'Subfolder 2', type: 'folder', parent: 'folder1' }, - * { id: 'file5', name: 'File 5', type: 'file', parent: 'subfolder2' }, - * { id: 'file6', name: 'File 6', type: 'file', parent: 'subfolder2' }, - * { id: 'folder2', name: 'Folder 2', type: 'folder', parent: null }, - * { id: 'file7', name: 'File 7', type: 'file', parent: 'folder2' }, - * { id: 'file8', name: 'File 8', type: 'file', parent: 'folder2' }, - * { id: 'subfolder3', name: 'Subfolder 3', type: 'folder', parent: 'folder2' }, - * { id: 'file9', name: 'File 9', type: 'file', parent: 'subfolder3' }, - * { id: 'file10', name: 'File 10', type: 'file', parent: 'subfolder3' }, - * ]; - * - * const tree = buildTree(fileSystem, 'id', 'id', 'parent', { rootReferences: [null] }); - * - * console.log(tree.toString()); - * ``` - * - * The buildTree function takes in the array of data objects, as well as some configuration options specifying - * the keys to use for identifying nodes and their parent-child relationships. In this example, we use the id - * key to identify nodes, and the parent key to specify the parent of each node. - * - * The resulting tree object is a nested tree structure, where each node is an object representing a file or - * folder, and has child nodes representing its contents. The toString method of the tree object - * can be used to print out the tree in a readable format: - * - * ```markdown - * - Folder 1 - * - File 1 - * - File 2 - * - Subfolder 1 - * - File 3 - * - File 4 - * - Subfolder 2 - * - File 5 - * - File 6 - * - Folder 2 - * - File 7 - * - File 8 - * - Subfolder 3 - * - File 9 - * - File 10 - * ``` - * - * @memberof Monster.Data - * - * @param {*} subject - The object or array to build the tree from. - * @param {string|Monster.Data~exampleSelectorCallback} selector - Either a string to specify a property of each object to use as a selector, or a selector function to generate a map of objects. - * @param {string} idKey - The property key to use as the unique ID of each node. - * @param {string} parentIDKey - The property key to use as the parent ID of each node. - * @param {object} [options] - Additional options to modify the function behavior. - * @param {Array<*>} [options.rootReferences=[null, undefined]] - An array of values to treat as root references when creating the tree. - * @param {function} [options.filter] - A filter function to apply to each node. - * - * @return {*} The resulting tree structure as a NodeList. - * - * @throws {TypeError} selector is neither a string nor a function. - * @throws {TypeError} the selector callback must return a map. - * @throws {Error} the object has no value for the specified id. - * - * @license AGPLv3 - * - * @since 1.26.0 - */ -/** - * Base class for all server datasources - * - * @license AGPLv3 - * @since 3.4.0 - * @copyright schukai GmbH - * @memberOf Monster.Data.Datasource - * @summary The Server class encapsulates the access to a server datasource - */ -/** - * The class represents a record. - * - * @license AGPLv3 - * @since 1.22.0 - * @copyright schukai GmbH - * @memberOf Monster.Data.Datasource - * @summary The Storage class encapsulates the access to data objects over WebStorageAPI. - */ -/** - * The SessionStorage class provides a data source that uses the SessionStorage API on the client. - * - * @license AGPLv3 - * @since 1.22.0 - * @copyright schukai GmbH - * @memberOf Monster.Data.Datasource.Storage - * @summary The LocalStorage class encapsulates the access to data objects. - */ -/** - * The LocalStorage Datasource provides a data store in the browser localStorage. - * - * @license AGPLv3 - * @since 1.22.0 - * @copyright schukai GmbH - * @memberOf Monster.Data.Datasource.Storage - * @summary The LocalStorage class encapsulates the access to data objects. - */ -/** - * The DomStorage is a class that stores data in memory. - * - * @license AGPLv3 - * @copyright schukai GmbH - * @memberOf Monster.Data.Datasource - */ -/** - * Error message for API requests with extension of request and validation. - * - * @license AGPLv3 - * @since 1.24.0 - * @copyright schukai GmbH - * @memberOf Monster.Data.Datasource.Server.RestAPI - * @summary the error is thrown by the rest api in case of error - */ -/** - * @type {symbol} - * @memberOf Monster - * @license AGPLv3 - * @since 3.12.0 - */ -/** - * The RestAPI is a class that enables a REST API server. - * - * @externalExample ../../../../example/data/datasource/server/restapi.mjs - * @license AGPLv3 - * @since 1.22.0 - * @copyright schukai GmbH - * @memberOf Monster.Data.Datasource.Server - * @summary The RestAPI is a class that binds a REST API server. - */ -/** - * The RestAPI is a class that enables a REST API server. - * - * @externalExample ../../../../example/data/datasource/server/webconnect.mjs - * @license AGPLv3 - * @since 3.1.0 - * @copyright schukai GmbH - * @memberOf Monster.Data.Datasource.Server - * @summary The LocalStorage class encapsulates the access to data objects. - */ -/*! Bundled license information: - -assertion-error/index.js: - (*! - * assertion-error - * Copyright(c) 2013 Jake Luer <jake@qualiancy.com> - * MIT Licensed - *) - (*! - * Return a function that will copy properties from - * one object to another excluding any originally - * listed. Returned function will create a new `{}`. - * - * @param {String} excluded properties ... - * @return {Function} - *) - (*! - * Primary Exports - *) - (*! - * Inherit from Error.prototype - *) - (*! - * Statically set name - *) - (*! - * Ensure correct constructor - *) - -chai/lib/chai/utils/flag.js: - (*! - * Chai - flag utility - * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> - * MIT Licensed - *) - -chai/lib/chai/utils/test.js: - (*! - * Chai - test utility - * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> - * MIT Licensed - *) - (*! - * Module dependencies - *) - -chai/lib/chai/utils/expectTypes.js: - (*! - * Chai - expectTypes utility - * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> - * MIT Licensed - *) - -chai/lib/chai/utils/getActual.js: - (*! - * Chai - getActual utility - * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> - * MIT Licensed - *) - -chai/lib/chai/utils/objDisplay.js: - (*! - * Chai - flag utility - * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> - * MIT Licensed - *) - (*! - * Module dependencies - *) - -chai/lib/chai/utils/getMessage.js: - (*! - * Chai - message composition utility - * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> - * MIT Licensed - *) - (*! - * Module dependencies - *) - -chai/lib/chai/utils/transferFlags.js: - (*! - * Chai - transferFlags utility - * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> - * MIT Licensed - *) - -deep-eql/index.js: - (*! - * deep-eql - * Copyright(c) 2013 Jake Luer <jake@alogicalparadox.com> - * MIT Licensed - *) - (*! - * Check to see if the MemoizeMap has recorded a result of the two operands - * - * @param {Mixed} leftHandOperand - * @param {Mixed} rightHandOperand - * @param {MemoizeMap} memoizeMap - * @returns {Boolean|null} result - *) - (*! - * Set the result of the equality into the MemoizeMap - * - * @param {Mixed} leftHandOperand - * @param {Mixed} rightHandOperand - * @param {MemoizeMap} memoizeMap - * @param {Boolean} result - *) - (*! - * Primary Export - *) - (*! - * The main logic of the `deepEqual` function. - * - * @param {Mixed} leftHandOperand - * @param {Mixed} rightHandOperand - * @param {Object} [options] (optional) Additional options - * @param {Array} [options.comparator] (optional) Override default algorithm, determining custom equality. - * @param {Array} [options.memoize] (optional) Provide a custom memoization object which will cache the results of - complex objects for a speed boost. By passing `false` you can disable memoization, but this will cause circular - references to blow the stack. - * @return {Boolean} equal match - *) - (*! - * Compare two Regular Expressions for equality. - * - * @param {RegExp} leftHandOperand - * @param {RegExp} rightHandOperand - * @return {Boolean} result - *) - (*! - * Compare two Sets/Maps for equality. Faster than other equality functions. - * - * @param {Set} leftHandOperand - * @param {Set} rightHandOperand - * @param {Object} [options] (Optional) - * @return {Boolean} result - *) - (*! - * Simple equality for flat iterable objects such as Arrays, TypedArrays or Node.js buffers. - * - * @param {Iterable} leftHandOperand - * @param {Iterable} rightHandOperand - * @param {Object} [options] (Optional) - * @return {Boolean} result - *) - (*! - * Simple equality for generator objects such as those returned by generator functions. - * - * @param {Iterable} leftHandOperand - * @param {Iterable} rightHandOperand - * @param {Object} [options] (Optional) - * @return {Boolean} result - *) - (*! - * Determine if the given object has an @@iterator function. - * - * @param {Object} target - * @return {Boolean} `true` if the object has an @@iterator function. - *) - (*! - * Gets all iterator entries from the given Object. If the Object has no @@iterator function, returns an empty array. - * This will consume the iterator - which could have side effects depending on the @@iterator implementation. - * - * @param {Object} target - * @returns {Array} an array of entries from the @@iterator function - *) - (*! - * Gets all entries from a Generator. This will consume the generator - which could have side effects. - * - * @param {Generator} target - * @returns {Array} an array of entries from the Generator. - *) - (*! - * Gets all own and inherited enumerable keys from a target. - * - * @param {Object} target - * @returns {Array} an array of own and inherited enumerable keys from the target. - *) - (*! - * Determines if two objects have matching values, given a set of keys. Defers to deepEqual for the equality check of - * each key. If any value of the given key is not equal, the function will return false (early). - * - * @param {Mixed} leftHandOperand - * @param {Mixed} rightHandOperand - * @param {Array} keys An array of keys to compare the values of leftHandOperand and rightHandOperand against - * @param {Object} [options] (Optional) - * @return {Boolean} result - *) - (*! - * Recursively check the equality of two Objects. Once basic sameness has been established it will defer to `deepEqual` - * for each enumerable key in the object. - * - * @param {Mixed} leftHandOperand - * @param {Mixed} rightHandOperand - * @param {Object} [options] (Optional) - * @return {Boolean} result - *) - (*! - * Returns true if the argument is a primitive. - * - * This intentionally returns true for all objects that can be compared by reference, - * including functions and symbols. - * - * @param {Mixed} value - * @return {Boolean} result - *) - -chai/lib/chai/utils/isProxyEnabled.js: - (*! - * Chai - isProxyEnabled helper - * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> - * MIT Licensed - *) - -chai/lib/chai/utils/addProperty.js: - (*! - * Chai - addProperty utility - * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> - * MIT Licensed - *) - -chai/lib/chai/utils/addLengthGuard.js: - (*! - * Chai - addLengthGuard utility - * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> - * MIT Licensed - *) - -chai/lib/chai/utils/getProperties.js: - (*! - * Chai - getProperties utility - * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> - * MIT Licensed - *) - -chai/lib/chai/utils/proxify.js: - (*! - * Chai - proxify utility - * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> - * MIT Licensed - *) - -chai/lib/chai/utils/addMethod.js: - (*! - * Chai - addMethod utility - * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> - * MIT Licensed - *) - -chai/lib/chai/utils/overwriteProperty.js: - (*! - * Chai - overwriteProperty utility - * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> - * MIT Licensed - *) - -chai/lib/chai/utils/overwriteMethod.js: - (*! - * Chai - overwriteMethod utility - * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> - * MIT Licensed - *) - -chai/lib/chai/utils/addChainableMethod.js: - (*! - * Chai - addChainingMethod utility - * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> - * MIT Licensed - *) - (*! - * Module dependencies - *) - (*! - * Module variables - *) - -chai/lib/chai/utils/overwriteChainableMethod.js: - (*! - * Chai - overwriteChainableMethod utility - * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> - * MIT Licensed - *) - -chai/lib/chai/utils/compareByInspect.js: - (*! - * Chai - compareByInspect utility - * Copyright(c) 2011-2016 Jake Luer <jake@alogicalparadox.com> - * MIT Licensed - *) - (*! - * Module dependencies - *) - -chai/lib/chai/utils/getOwnEnumerablePropertySymbols.js: - (*! - * Chai - getOwnEnumerablePropertySymbols utility - * Copyright(c) 2011-2016 Jake Luer <jake@alogicalparadox.com> - * MIT Licensed - *) - -chai/lib/chai/utils/getOwnEnumerableProperties.js: - (*! - * Chai - getOwnEnumerableProperties utility - * Copyright(c) 2011-2016 Jake Luer <jake@alogicalparadox.com> - * MIT Licensed - *) - (*! - * Module dependencies - *) - -chai/lib/chai/utils/isNaN.js: - (*! - * Chai - isNaN utility - * Copyright(c) 2012-2015 Sakthipriyan Vairamani <thechargingvolcano@gmail.com> - * MIT Licensed - *) - -chai/lib/chai/utils/index.js: - (*! - * chai - * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com> - * MIT Licensed - *) - (*! - * Dependencies that are used for multiple exports are required here only once - *) - (*! - * test utility - *) - (*! - * type utility - *) - (*! - * expectTypes utility - *) - (*! - * message utility - *) - (*! - * actual utility - *) - (*! - * Inspect util - *) - (*! - * Object Display util - *) - (*! - * Flag utility - *) - (*! - * Flag transferring utility - *) - (*! - * Deep equal utility - *) - (*! - * Deep path info - *) - (*! - * Check if a property exists - *) - (*! - * Function name - *) - (*! - * add Property - *) - (*! - * add Method - *) - (*! - * overwrite Property - *) - (*! - * overwrite Method - *) - (*! - * Add a chainable method - *) - (*! - * Overwrite chainable method - *) - (*! - * Compare by inspect method - *) - (*! - * Get own enumerable property symbols method - *) - (*! - * Get own enumerable properties method - *) - (*! - * Checks error against a given set of criteria - *) - (*! - * Proxify util - *) - (*! - * addLengthGuard util - *) - (*! - * isProxyEnabled helper - *) - (*! - * isNaN method - *) - (*! - * getOperator method - *) - -chai/lib/chai/assertion.js: - (*! - * chai - * http://chaijs.com - * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com> - * MIT Licensed - *) - (*! - * Module dependencies. - *) - (*! - * Module export. - *) - (*! - * Assertion Constructor - * - * Creates object for chaining. - * - * `Assertion` objects contain metadata in the form of flags. Three flags can - * be assigned during instantiation by passing arguments to this constructor: - * - * - `object`: This flag contains the target of the assertion. For example, in - * the assertion `expect(numKittens).to.equal(7);`, the `object` flag will - * contain `numKittens` so that the `equal` assertion can reference it when - * needed. - * - * - `message`: This flag contains an optional custom error message to be - * prepended to the error message that's generated by the assertion when it - * fails. - * - * - `ssfi`: This flag stands for "start stack function indicator". It - * contains a function reference that serves as the starting point for - * removing frames from the stack trace of the error that's created by the - * assertion when it fails. The goal is to provide a cleaner stack trace to - * end users by removing Chai's internal functions. Note that it only works - * in environments that support `Error.captureStackTrace`, and only when - * `Chai.config.includeStack` hasn't been set to `false`. - * - * - `lockSsfi`: This flag controls whether or not the given `ssfi` flag - * should retain its current value, even as assertions are chained off of - * this object. This is usually set to `true` when creating a new assertion - * from within another assertion. It's also temporarily set to `true` before - * an overwritten assertion gets called by the overwriting assertion. - * - * @param {Mixed} obj target of the assertion - * @param {String} msg (optional) custom error message - * @param {Function} ssfi (optional) starting point for removing stack frames - * @param {Boolean} lockSsfi (optional) whether or not the ssfi flag is locked - * @api private - *) - (*! - * ### ._obj - * - * Quick reference to stored `actual` value for plugin developers. - * - * @api private - *) - -chai/lib/chai/core/assertions.js: - (*! - * chai - * http://chaijs.com - * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com> - * MIT Licensed - *) - -chai/lib/chai/interface/expect.js: - (*! - * chai - * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com> - * MIT Licensed - *) - -chai/lib/chai/interface/should.js: - (*! - * chai - * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com> - * MIT Licensed - *) - -chai/lib/chai/interface/assert.js: - (*! - * chai - * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com> - * MIT Licensed - *) - (*! - * Chai dependencies. - *) - (*! - * Module export. - *) - (*! - * ### .ifError(object) - * - * Asserts if value is not a false value, and throws if it is a true value. - * This is added to allow for chai to be a drop-in replacement for Node's - * assert class. - * - * var err = new Error('I am a custom error'); - * assert.ifError(err); // Rethrows err! - * - * @name ifError - * @param {Object} object - * @namespace Assert - * @api public - *) - (*! - * Aliases. - *) - -chai/lib/chai.js: - (*! - * chai - * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com> - * MIT Licensed - *) - (*! - * Chai version - *) - (*! - * Assertion Error - *) - (*! - * Utils for plugins (not exported) - *) - (*! - * Utility Functions - *) - (*! - * Configuration - *) - (*! - * Primary `Assertion` prototype - *) - (*! - * Core Assertions - *) - (*! - * Expect interface - *) - (*! - * Should interface - *) - (*! - * Assert interface - *) - -pvtsutils/build/index.js: - (*! - * MIT License - * - * Copyright (c) 2017-2022 Peculiar Ventures, LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - *) - -pvutils/build/utils.es.js: - (*! - Copyright (c) Peculiar Ventures, LLC - *) - -asn1js/build/index.es.js: - (*! - * Copyright (c) 2014, GMO GlobalSign - * Copyright (c) 2015-2022, Peculiar Ventures - * All rights reserved. - * - * Author 2014-2019, Yury Strozhevsky - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * * Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - *) - -webcrypto-core/build/webcrypto-core.es.js: - (*! - Copyright (c) Peculiar Ventures, LLC - *) - -@peculiar/webcrypto/build/webcrypto.es.js: - (*! - Copyright (c) Peculiar Ventures, LLC - *) -*/ -//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2Fzc2VydGlvbi1lcnJvckAxLjEuMC9ub2RlX21vZHVsZXMvYXNzZXJ0aW9uLWVycm9yL2luZGV4LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9wYXRodmFsQDEuMS4xL25vZGVfbW9kdWxlcy9wYXRodmFsL2luZGV4LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9jaGFpQDQuMy43L25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL3V0aWxzL2ZsYWcuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2NoYWlANC4zLjcvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvdGVzdC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vdHlwZS1kZXRlY3RANC4wLjgvbm9kZV9tb2R1bGVzL3R5cGUtZGV0ZWN0L3R5cGUtZGV0ZWN0LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9jaGFpQDQuMy43L25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL3V0aWxzL2V4cGVjdFR5cGVzLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9jaGFpQDQuMy43L25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL3V0aWxzL2dldEFjdHVhbC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vZ2V0LWZ1bmMtbmFtZUAyLjAuMC9ub2RlX21vZHVsZXMvZ2V0LWZ1bmMtbmFtZS9pbmRleC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vbG91cGVAMi4zLjYvbm9kZV9tb2R1bGVzL2xvdXBlL2xvdXBlLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9jaGFpQDQuMy43L25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL2NvbmZpZy5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vY2hhaUA0LjMuNy9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy9pbnNwZWN0LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9jaGFpQDQuMy43L25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL3V0aWxzL29iakRpc3BsYXkuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2NoYWlANC4zLjcvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvZ2V0TWVzc2FnZS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vY2hhaUA0LjMuNy9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy90cmFuc2ZlckZsYWdzLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9kZWVwLWVxbEA0LjEuMy9ub2RlX21vZHVsZXMvZGVlcC1lcWwvaW5kZXguanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2NoYWlANC4zLjcvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvaXNQcm94eUVuYWJsZWQuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2NoYWlANC4zLjcvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvYWRkUHJvcGVydHkuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2NoYWlANC4zLjcvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvYWRkTGVuZ3RoR3VhcmQuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2NoYWlANC4zLjcvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvZ2V0UHJvcGVydGllcy5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vY2hhaUA0LjMuNy9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy9wcm94aWZ5LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9jaGFpQDQuMy43L25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL3V0aWxzL2FkZE1ldGhvZC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vY2hhaUA0LjMuNy9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy9vdmVyd3JpdGVQcm9wZXJ0eS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vY2hhaUA0LjMuNy9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy9vdmVyd3JpdGVNZXRob2QuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2NoYWlANC4zLjcvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvYWRkQ2hhaW5hYmxlTWV0aG9kLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9jaGFpQDQuMy43L25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL3V0aWxzL292ZXJ3cml0ZUNoYWluYWJsZU1ldGhvZC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vY2hhaUA0LjMuNy9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy9jb21wYXJlQnlJbnNwZWN0LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9jaGFpQDQuMy43L25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL3V0aWxzL2dldE93bkVudW1lcmFibGVQcm9wZXJ0eVN5bWJvbHMuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2NoYWlANC4zLjcvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvZ2V0T3duRW51bWVyYWJsZVByb3BlcnRpZXMuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2NoZWNrLWVycm9yQDEuMC4yL25vZGVfbW9kdWxlcy9jaGVjay1lcnJvci9pbmRleC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vY2hhaUA0LjMuNy9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy9pc05hTi5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vY2hhaUA0LjMuNy9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy9nZXRPcGVyYXRvci5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vY2hhaUA0LjMuNy9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy9pbmRleC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vY2hhaUA0LjMuNy9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS9hc3NlcnRpb24uanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2NoYWlANC4zLjcvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvY29yZS9hc3NlcnRpb25zLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9jaGFpQDQuMy43L25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL2ludGVyZmFjZS9leHBlY3QuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2NoYWlANC4zLjcvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvaW50ZXJmYWNlL3Nob3VsZC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vY2hhaUA0LjMuNy9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS9pbnRlcmZhY2UvYXNzZXJ0LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9jaGFpQDQuMy43L25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9jaGFpQDQuMy43L25vZGVfbW9kdWxlcy9jaGFpL2luZGV4LmpzIiwgIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9jb25zdGFudHMubWpzIiwgIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS90eXBlcy9iYXNlLm1qcyIsICIuLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdHlwZXMvaXMubWpzIiwgIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS90eXBlcy92YWxpZGF0ZS5tanMiLCAiLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL2dsb2JhbC5tanMiLCAiLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL3R5cGVvZi5tanMiLCAiLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2RhdGEvZXh0ZW5kLm1qcyIsICIuLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdXRpbC9jbG9uZS5tanMiLCAiLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2kxOG4vbG9jYWxlLm1qcyIsICIuLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvZG9tL3V0aWwubWpzIiwgIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9kb20vbG9jYWxlLm1qcyIsICIuLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdHlwZXMvaWQubWpzIiwgIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS90eXBlcy90b2tlbmxpc3QubWpzIiwgIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9kb20vY29uc3RhbnRzLm1qcyIsICIuLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvZG9tL2F0dHJpYnV0ZXMubWpzIiwgIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS90eXBlcy9zdGFjay5tanMiLCAiLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2RhdGEvcGF0aGZpbmRlci5tanMiLCAiLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL2Jhc2V3aXRob3B0aW9ucy5tanMiLCAiLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2kxOG4vcHJvdmlkZXIubWpzIiwgIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9pMThuL3RyYW5zbGF0aW9ucy5tanMiLCAiLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2RhdGEvdHJhbnNmb3JtZXIubWpzIiwgIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9kYXRhL3BpcGUubWpzIiwgIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS90ZXh0L2Zvcm1hdHRlci5tanMiLCAiLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2RvbS9zbG90dGVkLm1qcyIsICIuLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdHlwZXMvcXVldWUubWpzIiwgIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS90eXBlcy91bmlxdWVxdWV1ZS5tanMiLCAiLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL29ic2VydmVyLm1qcyIsICIuLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdHlwZXMvb2JzZXJ2ZXJsaXN0Lm1qcyIsICIuLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdHlwZXMvcHJveHlvYnNlcnZlci5tanMiLCAiLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2RvbS9yZXNvdXJjZS5tanMiLCAiLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL21lZGlhdHlwZS5tanMiLCAiLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL2RhdGF1cmwubWpzIiwgIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9kYXRhL2RpZmYubWpzIiwgIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS91dGlsL3RyaW1zcGFjZXMubWpzIiwgIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9kb20vZXZlbnRzLm1qcyIsICIuLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvZG9tL3RoZW1lLm1qcyIsICIuLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvZG9tL3RlbXBsYXRlLm1qcyIsICIuLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvZG9tL3VwZGF0ZXIubWpzIiwgIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9kb20vY3VzdG9tZWxlbWVudC5tanMiLCAiLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2RvbS9jdXN0b21jb250cm9sLm1qcyIsICIuLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvZG9tL3JlYWR5Lm1qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vcHZ0c3V0aWxzQDEuMy4yL25vZGVfbW9kdWxlcy9wdnRzdXRpbHMvYnVpbGQvaW5kZXguanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3B2dXRpbHNAMS4xLjMvbm9kZV9tb2R1bGVzL3B2dXRpbHMvYnVpbGQvdXRpbHMuZXMuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FzbjFqc0AzLjAuNS9ub2RlX21vZHVsZXMvYXNuMWpzL2J1aWxkL2luZGV4LmVzLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AcGVjdWxpYXIrYXNuMS1zY2hlbWFAMi4zLjYvbm9kZV9tb2R1bGVzL0BwZWN1bGlhci9hc24xLXNjaGVtYS9idWlsZC9lczIwMTUvZW51bXMuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BwZWN1bGlhcithc24xLXNjaGVtYUAyLjMuNi9ub2RlX21vZHVsZXMvQHBlY3VsaWFyL2FzbjEtc2NoZW1hL2J1aWxkL2VzMjAxNS90eXBlcy9iaXRfc3RyaW5nLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AcGVjdWxpYXIrYXNuMS1zY2hlbWFAMi4zLjYvbm9kZV9tb2R1bGVzL0BwZWN1bGlhci9hc24xLXNjaGVtYS9idWlsZC9lczIwMTUvdHlwZXMvb2N0ZXRfc3RyaW5nLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AcGVjdWxpYXIrYXNuMS1zY2hlbWFAMi4zLjYvbm9kZV9tb2R1bGVzL0BwZWN1bGlhci9hc24xLXNjaGVtYS9idWlsZC9lczIwMTUvdHlwZXMvaW5kZXguanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BwZWN1bGlhcithc24xLXNjaGVtYUAyLjMuNi9ub2RlX21vZHVsZXMvQHBlY3VsaWFyL2FzbjEtc2NoZW1hL2J1aWxkL2VzMjAxNS9jb252ZXJ0ZXJzLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AcGVjdWxpYXIrYXNuMS1zY2hlbWFAMi4zLjYvbm9kZV9tb2R1bGVzL0BwZWN1bGlhci9hc24xLXNjaGVtYS9idWlsZC9lczIwMTUvaGVscGVyLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AcGVjdWxpYXIrYXNuMS1zY2hlbWFAMi4zLjYvbm9kZV9tb2R1bGVzL0BwZWN1bGlhci9hc24xLXNjaGVtYS9idWlsZC9lczIwMTUvc2NoZW1hLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AcGVjdWxpYXIrYXNuMS1zY2hlbWFAMi4zLjYvbm9kZV9tb2R1bGVzL0BwZWN1bGlhci9hc24xLXNjaGVtYS9idWlsZC9lczIwMTUvc3RvcmFnZS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHBlY3VsaWFyK2FzbjEtc2NoZW1hQDIuMy42L25vZGVfbW9kdWxlcy9AcGVjdWxpYXIvYXNuMS1zY2hlbWEvYnVpbGQvZXMyMDE1L2RlY29yYXRvcnMuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BwZWN1bGlhcithc24xLXNjaGVtYUAyLjMuNi9ub2RlX21vZHVsZXMvQHBlY3VsaWFyL2FzbjEtc2NoZW1hL2J1aWxkL2VzMjAxNS9lcnJvcnMvc2NoZW1hX3ZhbGlkYXRpb24uanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BwZWN1bGlhcithc24xLXNjaGVtYUAyLjMuNi9ub2RlX21vZHVsZXMvQHBlY3VsaWFyL2FzbjEtc2NoZW1hL2J1aWxkL2VzMjAxNS9lcnJvcnMvaW5kZXguanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BwZWN1bGlhcithc24xLXNjaGVtYUAyLjMuNi9ub2RlX21vZHVsZXMvQHBlY3VsaWFyL2FzbjEtc2NoZW1hL2J1aWxkL2VzMjAxNS9wYXJzZXIuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BwZWN1bGlhcithc24xLXNjaGVtYUAyLjMuNi9ub2RlX21vZHVsZXMvQHBlY3VsaWFyL2FzbjEtc2NoZW1hL2J1aWxkL2VzMjAxNS9zZXJpYWxpemVyLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AcGVjdWxpYXIrYXNuMS1zY2hlbWFAMi4zLjYvbm9kZV9tb2R1bGVzL0BwZWN1bGlhci9hc24xLXNjaGVtYS9idWlsZC9lczIwMTUvb2JqZWN0cy5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHBlY3VsaWFyK2FzbjEtc2NoZW1hQDIuMy42L25vZGVfbW9kdWxlcy9AcGVjdWxpYXIvYXNuMS1zY2hlbWEvYnVpbGQvZXMyMDE1L2NvbnZlcnQuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BwZWN1bGlhcithc24xLXNjaGVtYUAyLjMuNi9ub2RlX21vZHVsZXMvQHBlY3VsaWFyL2FzbjEtc2NoZW1hL2J1aWxkL2VzMjAxNS9pbmRleC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vdHNsaWJAMi41LjAvbm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHBlY3VsaWFyK2pzb24tc2NoZW1hQDEuMS4xMi9ub2RlX21vZHVsZXMvQHBlY3VsaWFyL2pzb24tc2NoZW1hL2J1aWxkL2luZGV4LmVzLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS93ZWJjcnlwdG8tY29yZUAxLjcuNy9ub2RlX21vZHVsZXMvd2ViY3J5cHRvLWNvcmUvYnVpbGQvd2ViY3J5cHRvLWNvcmUuZXMuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BwZWN1bGlhcit3ZWJjcnlwdG9AMS40LjMvbm9kZV9tb2R1bGVzL0BwZWN1bGlhci93ZWJjcnlwdG8vYnVpbGQvd2ViY3J5cHRvLmVzLmpzIiwgIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9tYXRoL3JhbmRvbS5tanMiLCAiLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL3JhbmRvbWlkLm1qcyIsICIuLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdHlwZXMvdXVpZC5tanMiLCAicHJlcGFyZS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vY2hhaUA0LjMuNy9ub2RlX21vZHVsZXMvY2hhaS9pbmRleC5tanMiLCAiLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL3ZlcnNpb24ubWpzIiwgIi4uL2Nhc2VzL21vbnN0ZXIubWpzIiwgIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9sb2dnaW5nL2hhbmRsZXIubWpzIiwgIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9sb2dnaW5nL2xvZ2VudHJ5Lm1qcyIsICIuLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvbG9nZ2luZy9sb2dnZXIubWpzIiwgIi4uL2Nhc2VzL2xvZ2dpbmcvbG9nZ2VyLm1qcyIsICIuLi9jYXNlcy9sb2dnaW5nL2xvZ2VudHJ5Lm1qcyIsICIuLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvbG9nZ2luZy9oYW5kbGVyL2NvbnNvbGUubWpzIiwgIi4uL2Nhc2VzL2xvZ2dpbmcvaGFuZGxlci9jb25zb2xlLm1qcyIsICIuLi9jYXNlcy9sb2dnaW5nL2hhbmRsZXIubWpzIiwgIi4uL2Nhc2VzL3RleHQvZm9ybWF0dGVyLm1qcyIsICIuLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdGV4dC91dGlsLm1qcyIsICIuLi9jYXNlcy90ZXh0L3V0aWwubWpzIiwgIi4uL2Nhc2VzL2RvbS9zbG90dGVkLW5vZGVzLm1qcyIsICIuLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvZG9tL3Jlc291cmNlL2xpbmsvc3R5bGVzaGVldC5tanMiLCAiLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2RvbS9yZXNvdXJjZS9saW5rLm1qcyIsICIuLi9jYXNlcy9kb20vcmVzb3VyY2UvbGluay9zdHlsZXNoZWV0Lm1qcyIsICIuLi91dGlsL2NoYWktZG9tLm1qcyIsICIuLi91dGlsL2NsZWFudXBkb20ubWpzIiwgIi4uL3V0aWwvanNkb20ubWpzIiwgIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9kb20vcmVzb3VyY2UvZGF0YS5tanMiLCAiLi4vY2FzZXMvZG9tL3Jlc291cmNlL2RhdGEubWpzIiwgIi4uL2Nhc2VzL2RvbS9yZXNvdXJjZS9saW5rLm1qcyIsICIuLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvZG9tL3Jlc291cmNlL3NjcmlwdC5tanMiLCAiLi4vY2FzZXMvZG9tL3Jlc291cmNlL3NjcmlwdC5tanMiLCAiLi4vY2FzZXMvZG9tL3VwZGF0ZXIubWpzIiwgIi4uL2Nhc2VzL2RvbS9jdXN0b21jb250cm9sLm1qcyIsICIuLi9jYXNlcy9kb20vbG9jYWxlLm1qcyIsICIuLi9jYXNlcy9kb20vdGhlbWUubWpzIiwgIi4uL2Nhc2VzL2RvbS9yZXNvdXJjZS5tanMiLCAiLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2RvbS9yZXNvdXJjZW1hbmFnZXIubWpzIiwgIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS90eXBlcy9pbnRlcm5hbC5tanMiLCAiLi4vY2FzZXMvZG9tL3Jlc291cmNlbWFuYWdlci5tanMiLCAiLi4vY2FzZXMvZG9tL3V0aWwubWpzIiwgIi4uL2Nhc2VzL2RvbS9maW5kLm1qcyIsICIuLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvZG9tL2RpbWVuc2lvbi5tanMiLCAiLi4vY2FzZXMvZG9tL2RpbWVuc2lvbi5tanMiLCAiLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3V0aWwvcnVudGltZS5tanMiLCAiLi4vY2FzZXMvZG9tL2N1c3RvbWVsZW1lbnQubWpzIiwgIi4uL2Nhc2VzL2RvbS9hdHRyaWJ1dGVzLm1qcyIsICIuLi9jYXNlcy9kb20vZXZlbnRzLm1qcyIsICIuLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvZG9tL3dvcmtlci9mYWN0b3J5Lm1qcyIsICIuLi9jYXNlcy9kb20vd29ya2VyL2ZhY3RvcnkubWpzIiwgIi4uL2Nhc2VzL2RvbS90ZW1wbGF0ZS5tanMiLCAiLi4vY2FzZXMvZG9tL3JlYWR5Lm1qcyIsICIuLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvZG9tL2ZvY3VzbWFuYWdlci5tanMiLCAiLi4vY2FzZXMvZG9tL2ZvY3VzbWFuYWdlci5tanMiLCAiLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2RvbS9hc3NlbWJsZXIubWpzIiwgIi4uL2Nhc2VzL2RvbS9hc3NlbWJsZXIubWpzIiwgIi4uL2Nhc2VzL2kxOG4vdHJhbnNsYXRpb25zLm1qcyIsICIuLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvaTE4bi9wcm92aWRlcnMvZW1iZWQubWpzIiwgIi4uL2Nhc2VzL2kxOG4vbG9jYWxlLm1qcyIsICIuLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvaTE4bi9mb3JtYXR0ZXIubWpzIiwgIi4uL2Nhc2VzL2kxOG4vZm9ybWF0dGVyLm1qcyIsICIuLi9jYXNlcy9pMThuL3Byb3ZpZGVycy9lbWJlZC5tanMiLCAiLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2kxOG4vcHJvdmlkZXJzL2ZldGNoLm1qcyIsICIuLi9jYXNlcy9pMThuL3Byb3ZpZGVycy9mZXRjaC5tanMiLCAiLi4vY2FzZXMvaTE4bi9wcm92aWRlci5tanMiLCAiLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL25ldC93ZWJjb25uZWN0L21lc3NhZ2UubWpzIiwgIi4uL2Nhc2VzL25ldC93ZWJjb25uZWN0L21lc3NhZ2UubWpzIiwgIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9uZXQvd2ViY29ubmVjdC5tanMiLCAiLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL29ic2VydmFibGVxdWV1ZS5tanMiLCAiLi4vY2FzZXMvbmV0L3dlYmNvbm5lY3QubWpzIiwgIi4uL3V0aWwvd2Vic29ja2V0Lm1qcyIsICIuLi9jYXNlcy90eXBlcy9tZWRpYXR5cGUubWpzIiwgIi4uL2Nhc2VzL3R5cGVzL3R5cGVvZi5tanMiLCAiLi4vY2FzZXMvdHlwZXMvb2JzZXJ2ZXJsaXN0Lm1qcyIsICIuLi9jYXNlcy90eXBlcy9yYW5kb21pZC5tanMiLCAiLi4vY2FzZXMvdHlwZXMvb2JzZXJ2YWJsZXF1ZXVlLm1qcyIsICIuLi9jYXNlcy90eXBlcy91dWlkLm1qcyIsICIuLi9jYXNlcy90eXBlcy9vYnNlcnZlci5tanMiLCAiLi4vY2FzZXMvdHlwZXMvaW50ZXJuYWwubWpzIiwgIi4uL2Nhc2VzL3R5cGVzL3Rva2VubGlzdC5tanMiLCAiLi4vY2FzZXMvdHlwZXMvcXVldWUubWpzIiwgIi4uL2Nhc2VzL3R5cGVzL3N0YWNrLm1qcyIsICIuLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdHlwZXMvYmluYXJ5Lm1qcyIsICIuLi9jYXNlcy90eXBlcy9iaW5hcnkubWpzIiwgIi4uL2Nhc2VzL3R5cGVzL2Jhc2V3aXRob3B0aW9ucy5tanMiLCAiLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL3JlZ2V4Lm1qcyIsICIuLi9jYXNlcy90eXBlcy9yZWdleC5tanMiLCAiLi4vY2FzZXMvdHlwZXMvcHJveHlvYnNlcnZlci5tanMiLCAiLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL25vZGUubWpzIiwgIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS90eXBlcy9ub2RlbGlzdC5tanMiLCAiLi4vY2FzZXMvdHlwZXMvbm9kZWxpc3QubWpzIiwgIi4uL2Nhc2VzL3R5cGVzL3ZlcnNpb24ubWpzIiwgIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS90eXBlcy9ub2RlcmVjdXJzaXZlaXRlcmF0b3IubWpzIiwgIi4uL2Nhc2VzL3R5cGVzL25vZGUubWpzIiwgIi4uL2Nhc2VzL3R5cGVzL25vZGVyZWN1cnNpdmVpdGVyYXRvci5tanMiLCAiLi4vY2FzZXMvdHlwZXMvZ2xvYmFsLm1qcyIsICIuLi9jYXNlcy90eXBlcy9kYXRhdXJsLm1qcyIsICIuLi9jYXNlcy90eXBlcy92YWxpZGF0ZS5tanMiLCAiLi4vY2FzZXMvdHlwZXMvdW5pcXVlcXVldWUubWpzIiwgIi4uL2Nhc2VzL3R5cGVzL2Jhc2UubWpzIiwgIi4uL2Nhc2VzL3R5cGVzL2lzLm1qcyIsICIuLi9jYXNlcy90eXBlcy9pZC5tanMiLCAiLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2NvbnN0cmFpbnRzL2lzb2JqZWN0Lm1qcyIsICIuLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvY29uc3RyYWludHMvYWJzdHJhY3QubWpzIiwgIi4uL2Nhc2VzL2NvbnN0cmFpbnQvaXNvYmplY3QubWpzIiwgIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9jb25zdHJhaW50cy9pbnZhbGlkLm1qcyIsICIuLi9jYXNlcy9jb25zdHJhaW50L2ludmFsaWQubWpzIiwgIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9jb25zdHJhaW50cy92YWxpZC5tanMiLCAiLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2NvbnN0cmFpbnRzL2Fic3RyYWN0b3BlcmF0b3IubWpzIiwgIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9jb25zdHJhaW50cy9hbmRvcGVyYXRvci5tanMiLCAiLi4vY2FzZXMvY29uc3RyYWludC9hbmRvcGVyYXRvci5tanMiLCAiLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2NvbnN0cmFpbnRzL29yb3BlcmF0b3IubWpzIiwgIi4uL2Nhc2VzL2NvbnN0cmFpbnQvb3JvcGVyYXRvci5tanMiLCAiLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2NvbnN0cmFpbnRzL2lzYXJyYXkubWpzIiwgIi4uL2Nhc2VzL2NvbnN0cmFpbnQvaXNhcnJheS5tanMiLCAiLi4vY2FzZXMvY29uc3RyYWludC9hYnN0cmFjdG9wZXJhdG9yLm1qcyIsICIuLi9jYXNlcy9jb25zdHJhaW50L3ZhbGlkLm1qcyIsICIuLi9jYXNlcy91dGlsL3RyaW1zcGFjZXMubWpzIiwgIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS91dGlsL2RlYWRtYW5zc3dpdGNoLm1qcyIsICIuLi9jYXNlcy91dGlsL2RlYWRtYW5zc3dpdGNoLm1qcyIsICIuLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdXRpbC9mcmVlemUubWpzIiwgIi4uL2Nhc2VzL3V0aWwvZnJlZXplLm1qcyIsICIuLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdXRpbC9jb21wYXJhdG9yLm1qcyIsICIuLi9jYXNlcy91dGlsL2NvbXBhcmF0b3IubWpzIiwgIi4uL2Nhc2VzL3V0aWwvY2xvbmUubWpzIiwgIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS91dGlsL3Byb2Nlc3NpbmcubWpzIiwgIi4uL2Nhc2VzL3V0aWwvcHJvY2Vzc2luZy5tanMiLCAiLi4vY2FzZXMvZGF0YS9leHRlbmQubWpzIiwgIi4uL2Nhc2VzL2RhdGEvcGlwZS5tanMiLCAiLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2RhdGEvYnVpbGRtYXAubWpzIiwgIi4uL2Nhc2VzL2RhdGEvYnVpbGRtYXAubWpzIiwgIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9kYXRhL2RhdGFzb3VyY2UubWpzIiwgIi4uL2Nhc2VzL2RhdGEvZGF0YXNvdXJjZS5tanMiLCAiLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2RhdGEvYnVpbGR0cmVlLm1qcyIsICIuLi9jYXNlcy9kYXRhL2J1aWxkdHJlZS5tanMiLCAiLi4vY2FzZXMvZGF0YS90cmFuc2Zvcm1lci5tanMiLCAiLi4vY2FzZXMvZGF0YS9wYXRoZmluZGVyLm1qcyIsICIuLi9jYXNlcy9kYXRhL2RpZmYubWpzIiwgIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9kYXRhL2RhdGFzb3VyY2Uvc2VydmVyLm1qcyIsICIuLi9jYXNlcy9kYXRhL2RhdGFzb3VyY2Uvc2VydmVyLm1qcyIsICIuLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvZGF0YS9kYXRhc291cmNlL3N0b3JhZ2Uvc2Vzc2lvbnN0b3JhZ2UubWpzIiwgIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9kYXRhL2RhdGFzb3VyY2Uvc3RvcmFnZS5tanMiLCAiLi4vdXRpbC9sb2NhbHN0b3JhZ2UubWpzIiwgIi4uL2Nhc2VzL2RhdGEvZGF0YXNvdXJjZS9zdG9yYWdlL3Nlc3Npb25zdG9yYWdlLm1qcyIsICIuLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvZGF0YS9kYXRhc291cmNlL3N0b3JhZ2UvbG9jYWxzdG9yYWdlLm1qcyIsICIuLi9jYXNlcy9kYXRhL2RhdGFzb3VyY2Uvc3RvcmFnZS9sb2NhbHN0b3JhZ2UubWpzIiwgIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9kYXRhL2RhdGFzb3VyY2UvZG9tLm1qcyIsICIuLi9jYXNlcy9kYXRhL2RhdGFzb3VyY2UvZG9tLm1qcyIsICIuLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvZGF0YS9kYXRhc291cmNlL3NlcnZlci9yZXN0YXBpLm1qcyIsICIuLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvZGF0YS9kYXRhc291cmNlL3NlcnZlci9yZXN0YXBpL3dyaXRlZXJyb3IubWpzIiwgIi4uL2Nhc2VzL2RhdGEvZGF0YXNvdXJjZS9zZXJ2ZXIvcmVzdGFwaS5tanMiLCAiLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2RhdGEvZGF0YXNvdXJjZS9zZXJ2ZXIvd2ViY29ubmVjdC5tanMiLCAiLi4vY2FzZXMvZGF0YS9kYXRhc291cmNlL3NlcnZlci93ZWJzb2NrZXQubWpzIiwgIi4uL2Nhc2VzL21hdGgvcmFuZG9tLm1qcyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyohXG4gKiBhc3NlcnRpb24tZXJyb3JcbiAqIENvcHlyaWdodChjKSAyMDEzIEpha2UgTHVlciA8amFrZUBxdWFsaWFuY3kuY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyohXG4gKiBSZXR1cm4gYSBmdW5jdGlvbiB0aGF0IHdpbGwgY29weSBwcm9wZXJ0aWVzIGZyb21cbiAqIG9uZSBvYmplY3QgdG8gYW5vdGhlciBleGNsdWRpbmcgYW55IG9yaWdpbmFsbHlcbiAqIGxpc3RlZC4gUmV0dXJuZWQgZnVuY3Rpb24gd2lsbCBjcmVhdGUgYSBuZXcgYHt9YC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXhjbHVkZWQgcHJvcGVydGllcyAuLi5cbiAqIEByZXR1cm4ge0Z1bmN0aW9ufVxuICovXG5cbmZ1bmN0aW9uIGV4Y2x1ZGUgKCkge1xuICB2YXIgZXhjbHVkZXMgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG5cbiAgZnVuY3Rpb24gZXhjbHVkZVByb3BzIChyZXMsIG9iaikge1xuICAgIE9iamVjdC5rZXlzKG9iaikuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICBpZiAoIX5leGNsdWRlcy5pbmRleE9mKGtleSkpIHJlc1trZXldID0gb2JqW2tleV07XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gZnVuY3Rpb24gZXh0ZW5kRXhjbHVkZSAoKSB7XG4gICAgdmFyIGFyZ3MgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cylcbiAgICAgICwgaSA9IDBcbiAgICAgICwgcmVzID0ge307XG5cbiAgICBmb3IgKDsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHtcbiAgICAgIGV4Y2x1ZGVQcm9wcyhyZXMsIGFyZ3NbaV0pO1xuICAgIH1cblxuICAgIHJldHVybiByZXM7XG4gIH07XG59O1xuXG4vKiFcbiAqIFByaW1hcnkgRXhwb3J0c1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gQXNzZXJ0aW9uRXJyb3I7XG5cbi8qKlxuICogIyMjIEFzc2VydGlvbkVycm9yXG4gKlxuICogQW4gZXh0ZW5zaW9uIG9mIHRoZSBKYXZhU2NyaXB0IGBFcnJvcmAgY29uc3RydWN0b3IgZm9yXG4gKiBhc3NlcnRpb24gYW5kIHZhbGlkYXRpb24gc2NlbmFyaW9zLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gKiBAcGFyYW0ge09iamVjdH0gcHJvcGVydGllcyB0byBpbmNsdWRlIChvcHRpb25hbClcbiAqIEBwYXJhbSB7Y2FsbGVlfSBzdGFydCBzdGFjayBmdW5jdGlvbiAob3B0aW9uYWwpXG4gKi9cblxuZnVuY3Rpb24gQXNzZXJ0aW9uRXJyb3IgKG1lc3NhZ2UsIF9wcm9wcywgc3NmKSB7XG4gIHZhciBleHRlbmQgPSBleGNsdWRlKCduYW1lJywgJ21lc3NhZ2UnLCAnc3RhY2snLCAnY29uc3RydWN0b3InLCAndG9KU09OJylcbiAgICAsIHByb3BzID0gZXh0ZW5kKF9wcm9wcyB8fCB7fSk7XG5cbiAgLy8gZGVmYXVsdCB2YWx1ZXNcbiAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZSB8fCAnVW5zcGVjaWZpZWQgQXNzZXJ0aW9uRXJyb3InO1xuICB0aGlzLnNob3dEaWZmID0gZmFsc2U7XG5cbiAgLy8gY29weSBmcm9tIHByb3BlcnRpZXNcbiAgZm9yICh2YXIga2V5IGluIHByb3BzKSB7XG4gICAgdGhpc1trZXldID0gcHJvcHNba2V5XTtcbiAgfVxuXG4gIC8vIGNhcHR1cmUgc3RhY2sgdHJhY2VcbiAgc3NmID0gc3NmIHx8IEFzc2VydGlvbkVycm9yO1xuICBpZiAoRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UpIHtcbiAgICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSh0aGlzLCBzc2YpO1xuICB9IGVsc2Uge1xuICAgIHRyeSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoKTtcbiAgICB9IGNhdGNoKGUpIHtcbiAgICAgIHRoaXMuc3RhY2sgPSBlLnN0YWNrO1xuICAgIH1cbiAgfVxufVxuXG4vKiFcbiAqIEluaGVyaXQgZnJvbSBFcnJvci5wcm90b3R5cGVcbiAqL1xuXG5Bc3NlcnRpb25FcnJvci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEVycm9yLnByb3RvdHlwZSk7XG5cbi8qIVxuICogU3RhdGljYWxseSBzZXQgbmFtZVxuICovXG5cbkFzc2VydGlvbkVycm9yLnByb3RvdHlwZS5uYW1lID0gJ0Fzc2VydGlvbkVycm9yJztcblxuLyohXG4gKiBFbnN1cmUgY29ycmVjdCBjb25zdHJ1Y3RvclxuICovXG5cbkFzc2VydGlvbkVycm9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IEFzc2VydGlvbkVycm9yO1xuXG4vKipcbiAqIEFsbG93IGVycm9ycyB0byBiZSBjb252ZXJ0ZWQgdG8gSlNPTiBmb3Igc3RhdGljIHRyYW5zZmVyLlxuICpcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gaW5jbHVkZSBzdGFjayAoZGVmYXVsdDogYHRydWVgKVxuICogQHJldHVybiB7T2JqZWN0fSBvYmplY3QgdGhhdCBjYW4gYmUgYEpTT04uc3RyaW5naWZ5YFxuICovXG5cbkFzc2VydGlvbkVycm9yLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiAoc3RhY2spIHtcbiAgdmFyIGV4dGVuZCA9IGV4Y2x1ZGUoJ2NvbnN0cnVjdG9yJywgJ3RvSlNPTicsICdzdGFjaycpXG4gICAgLCBwcm9wcyA9IGV4dGVuZCh7IG5hbWU6IHRoaXMubmFtZSB9LCB0aGlzKTtcblxuICAvLyBpbmNsdWRlIHN0YWNrIGlmIGV4aXN0cyBhbmQgbm90IHR1cm5lZCBvZmZcbiAgaWYgKGZhbHNlICE9PSBzdGFjayAmJiB0aGlzLnN0YWNrKSB7XG4gICAgcHJvcHMuc3RhY2sgPSB0aGlzLnN0YWNrO1xuICB9XG5cbiAgcmV0dXJuIHByb3BzO1xufTtcbiIsICIndXNlIHN0cmljdCc7XG5cbi8qICFcbiAqIENoYWkgLSBwYXRodmFsIHV0aWxpdHlcbiAqIENvcHlyaWdodChjKSAyMDEyLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBAc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9sb2dpY2FscGFyYWRveC9maWx0clxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyoqXG4gKiAjIyMgLmhhc1Byb3BlcnR5KG9iamVjdCwgbmFtZSlcbiAqXG4gKiBUaGlzIGFsbG93cyBjaGVja2luZyB3aGV0aGVyIGFuIG9iamVjdCBoYXMgb3duXG4gKiBvciBpbmhlcml0ZWQgZnJvbSBwcm90b3R5cGUgY2hhaW4gbmFtZWQgcHJvcGVydHkuXG4gKlxuICogQmFzaWNhbGx5IGRvZXMgdGhlIHNhbWUgdGhpbmcgYXMgdGhlIGBpbmBcbiAqIG9wZXJhdG9yIGJ1dCB3b3JrcyBwcm9wZXJseSB3aXRoIG51bGwvdW5kZWZpbmVkIHZhbHVlc1xuICogYW5kIG90aGVyIHByaW1pdGl2ZXMuXG4gKlxuICogICAgIHZhciBvYmogPSB7XG4gKiAgICAgICAgIGFycjogWydhJywgJ2InLCAnYyddXG4gKiAgICAgICAsIHN0cjogJ0hlbGxvJ1xuICogICAgIH1cbiAqXG4gKiBUaGUgZm9sbG93aW5nIHdvdWxkIGJlIHRoZSByZXN1bHRzLlxuICpcbiAqICAgICBoYXNQcm9wZXJ0eShvYmosICdzdHInKTsgIC8vIHRydWVcbiAqICAgICBoYXNQcm9wZXJ0eShvYmosICdjb25zdHJ1Y3RvcicpOyAgLy8gdHJ1ZVxuICogICAgIGhhc1Byb3BlcnR5KG9iaiwgJ2JhcicpOyAgLy8gZmFsc2VcbiAqXG4gKiAgICAgaGFzUHJvcGVydHkob2JqLnN0ciwgJ2xlbmd0aCcpOyAvLyB0cnVlXG4gKiAgICAgaGFzUHJvcGVydHkob2JqLnN0ciwgMSk7ICAvLyB0cnVlXG4gKiAgICAgaGFzUHJvcGVydHkob2JqLnN0ciwgNSk7ICAvLyBmYWxzZVxuICpcbiAqICAgICBoYXNQcm9wZXJ0eShvYmouYXJyLCAnbGVuZ3RoJyk7ICAvLyB0cnVlXG4gKiAgICAgaGFzUHJvcGVydHkob2JqLmFyciwgMik7ICAvLyB0cnVlXG4gKiAgICAgaGFzUHJvcGVydHkob2JqLmFyciwgMyk7ICAvLyBmYWxzZVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAqIEBwYXJhbSB7U3RyaW5nfFN5bWJvbH0gbmFtZVxuICogQHJldHVybnMge0Jvb2xlYW59IHdoZXRoZXIgaXQgZXhpc3RzXG4gKiBAbmFtZXNwYWNlIFV0aWxzXG4gKiBAbmFtZSBoYXNQcm9wZXJ0eVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBoYXNQcm9wZXJ0eShvYmosIG5hbWUpIHtcbiAgaWYgKHR5cGVvZiBvYmogPT09ICd1bmRlZmluZWQnIHx8IG9iaiA9PT0gbnVsbCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIFRoZSBgaW5gIG9wZXJhdG9yIGRvZXMgbm90IHdvcmsgd2l0aCBwcmltaXRpdmVzLlxuICByZXR1cm4gbmFtZSBpbiBPYmplY3Qob2JqKTtcbn1cblxuLyogIVxuICogIyMgcGFyc2VQYXRoKHBhdGgpXG4gKlxuICogSGVscGVyIGZ1bmN0aW9uIHVzZWQgdG8gcGFyc2Ugc3RyaW5nIG9iamVjdFxuICogcGF0aHMuIFVzZSBpbiBjb25qdW5jdGlvbiB3aXRoIGBpbnRlcm5hbEdldFBhdGhWYWx1ZWAuXG4gKlxuICogICAgICB2YXIgcGFyc2VkID0gcGFyc2VQYXRoKCdteW9iamVjdC5wcm9wZXJ0eS5zdWJwcm9wJyk7XG4gKlxuICogIyMjIFBhdGhzOlxuICpcbiAqICogQ2FuIGJlIGluZmluaXRlbHkgZGVlcCBhbmQgbmVzdGVkLlxuICogKiBBcnJheXMgYXJlIGFsc28gdmFsaWQgdXNpbmcgdGhlIGZvcm1hbCBgbXlvYmplY3QuZG9jdW1lbnRbM10ucHJvcGVydHlgLlxuICogKiBMaXRlcmFsIGRvdHMgYW5kIGJyYWNrZXRzIChub3QgZGVsaW1pdGVyKSBtdXN0IGJlIGJhY2tzbGFzaC1lc2NhcGVkLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBwYXRoXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBwYXJzZWRcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHBhcnNlUGF0aChwYXRoKSB7XG4gIHZhciBzdHIgPSBwYXRoLnJlcGxhY2UoLyhbXlxcXFxdKVxcWy9nLCAnJDEuWycpO1xuICB2YXIgcGFydHMgPSBzdHIubWF0Y2goLyhcXFxcXFwufFteLl0rPykrL2cpO1xuICByZXR1cm4gcGFydHMubWFwKGZ1bmN0aW9uIG1hcE1hdGNoZXModmFsdWUpIHtcbiAgICBpZiAoXG4gICAgICB2YWx1ZSA9PT0gJ2NvbnN0cnVjdG9yJyB8fFxuICAgICAgdmFsdWUgPT09ICdfX3Byb3RvX18nIHx8XG4gICAgICB2YWx1ZSA9PT0gJ3Byb3RvdHlwZSdcbiAgICApIHtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgdmFyIHJlZ2V4cCA9IC9eXFxbKFxcZCspXFxdJC87XG4gICAgdmFyIG1BcnIgPSByZWdleHAuZXhlYyh2YWx1ZSk7XG4gICAgdmFyIHBhcnNlZCA9IG51bGw7XG4gICAgaWYgKG1BcnIpIHtcbiAgICAgIHBhcnNlZCA9IHsgaTogcGFyc2VGbG9hdChtQXJyWzFdKSB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBwYXJzZWQgPSB7IHA6IHZhbHVlLnJlcGxhY2UoL1xcXFwoWy5bXFxdXSkvZywgJyQxJykgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gcGFyc2VkO1xuICB9KTtcbn1cblxuLyogIVxuICogIyMgaW50ZXJuYWxHZXRQYXRoVmFsdWUob2JqLCBwYXJzZWRbLCBwYXRoRGVwdGhdKVxuICpcbiAqIEhlbHBlciBjb21wYW5pb24gZnVuY3Rpb24gZm9yIGAucGFyc2VQYXRoYCB0aGF0IHJldHVybnNcbiAqIHRoZSB2YWx1ZSBsb2NhdGVkIGF0IHRoZSBwYXJzZWQgYWRkcmVzcy5cbiAqXG4gKiAgICAgIHZhciB2YWx1ZSA9IGdldFBhdGhWYWx1ZShvYmosIHBhcnNlZCk7XG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCB0byBzZWFyY2ggYWdhaW5zdFxuICogQHBhcmFtIHtPYmplY3R9IHBhcnNlZCBkZWZpbml0aW9uIGZyb20gYHBhcnNlUGF0aGAuXG4gKiBAcGFyYW0ge051bWJlcn0gZGVwdGggKG5lc3RpbmcgbGV2ZWwpIG9mIHRoZSBwcm9wZXJ0eSB3ZSB3YW50IHRvIHJldHJpZXZlXG4gKiBAcmV0dXJucyB7T2JqZWN0fFVuZGVmaW5lZH0gdmFsdWVcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGludGVybmFsR2V0UGF0aFZhbHVlKG9iaiwgcGFyc2VkLCBwYXRoRGVwdGgpIHtcbiAgdmFyIHRlbXBvcmFyeVZhbHVlID0gb2JqO1xuICB2YXIgcmVzID0gbnVsbDtcbiAgcGF0aERlcHRoID0gdHlwZW9mIHBhdGhEZXB0aCA9PT0gJ3VuZGVmaW5lZCcgPyBwYXJzZWQubGVuZ3RoIDogcGF0aERlcHRoO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcGF0aERlcHRoOyBpKyspIHtcbiAgICB2YXIgcGFydCA9IHBhcnNlZFtpXTtcbiAgICBpZiAodGVtcG9yYXJ5VmFsdWUpIHtcbiAgICAgIGlmICh0eXBlb2YgcGFydC5wID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICB0ZW1wb3JhcnlWYWx1ZSA9IHRlbXBvcmFyeVZhbHVlW3BhcnQuaV07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0ZW1wb3JhcnlWYWx1ZSA9IHRlbXBvcmFyeVZhbHVlW3BhcnQucF07XG4gICAgICB9XG5cbiAgICAgIGlmIChpID09PSBwYXRoRGVwdGggLSAxKSB7XG4gICAgICAgIHJlcyA9IHRlbXBvcmFyeVZhbHVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXM7XG59XG5cbi8qICFcbiAqICMjIGludGVybmFsU2V0UGF0aFZhbHVlKG9iaiwgdmFsdWUsIHBhcnNlZClcbiAqXG4gKiBDb21wYW5pb24gZnVuY3Rpb24gZm9yIGBwYXJzZVBhdGhgIHRoYXQgc2V0c1xuICogdGhlIHZhbHVlIGxvY2F0ZWQgYXQgYSBwYXJzZWQgYWRkcmVzcy5cbiAqXG4gKiAgaW50ZXJuYWxTZXRQYXRoVmFsdWUob2JqLCAndmFsdWUnLCBwYXJzZWQpO1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgdG8gc2VhcmNoIGFuZCBkZWZpbmUgb25cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgdG8gdXNlIHVwb24gc2V0XG4gKiBAcGFyYW0ge09iamVjdH0gcGFyc2VkIGRlZmluaXRpb24gZnJvbSBgcGFyc2VQYXRoYFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gaW50ZXJuYWxTZXRQYXRoVmFsdWUob2JqLCB2YWwsIHBhcnNlZCkge1xuICB2YXIgdGVtcE9iaiA9IG9iajtcbiAgdmFyIHBhdGhEZXB0aCA9IHBhcnNlZC5sZW5ndGg7XG4gIHZhciBwYXJ0ID0gbnVsbDtcbiAgLy8gSGVyZSB3ZSBpdGVyYXRlIHRocm91Z2ggZXZlcnkgcGFydCBvZiB0aGUgcGF0aFxuICBmb3IgKHZhciBpID0gMDsgaSA8IHBhdGhEZXB0aDsgaSsrKSB7XG4gICAgdmFyIHByb3BOYW1lID0gbnVsbDtcbiAgICB2YXIgcHJvcFZhbCA9IG51bGw7XG4gICAgcGFydCA9IHBhcnNlZFtpXTtcblxuICAgIC8vIElmIGl0J3MgdGhlIGxhc3QgcGFydCBvZiB0aGUgcGF0aCwgd2Ugc2V0IHRoZSAncHJvcE5hbWUnIHZhbHVlIHdpdGggdGhlIHByb3BlcnR5IG5hbWVcbiAgICBpZiAoaSA9PT0gcGF0aERlcHRoIC0gMSkge1xuICAgICAgcHJvcE5hbWUgPSB0eXBlb2YgcGFydC5wID09PSAndW5kZWZpbmVkJyA/IHBhcnQuaSA6IHBhcnQucDtcbiAgICAgIC8vIE5vdyB3ZSBzZXQgdGhlIHByb3BlcnR5IHdpdGggdGhlIG5hbWUgaGVsZCBieSAncHJvcE5hbWUnIG9uIG9iamVjdCB3aXRoIHRoZSBkZXNpcmVkIHZhbFxuICAgICAgdGVtcE9ialtwcm9wTmFtZV0gPSB2YWw7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgcGFydC5wICE9PSAndW5kZWZpbmVkJyAmJiB0ZW1wT2JqW3BhcnQucF0pIHtcbiAgICAgIHRlbXBPYmogPSB0ZW1wT2JqW3BhcnQucF07XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgcGFydC5pICE9PSAndW5kZWZpbmVkJyAmJiB0ZW1wT2JqW3BhcnQuaV0pIHtcbiAgICAgIHRlbXBPYmogPSB0ZW1wT2JqW3BhcnQuaV07XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIElmIHRoZSBvYmogZG9lc24ndCBoYXZlIHRoZSBwcm9wZXJ0eSB3ZSBjcmVhdGUgb25lIHdpdGggdGhhdCBuYW1lIHRvIGRlZmluZSBpdFxuICAgICAgdmFyIG5leHQgPSBwYXJzZWRbaSArIDFdO1xuICAgICAgLy8gSGVyZSB3ZSBzZXQgdGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IHdoaWNoIHdpbGwgYmUgZGVmaW5lZFxuICAgICAgcHJvcE5hbWUgPSB0eXBlb2YgcGFydC5wID09PSAndW5kZWZpbmVkJyA/IHBhcnQuaSA6IHBhcnQucDtcbiAgICAgIC8vIEhlcmUgd2UgZGVjaWRlIGlmIHRoaXMgcHJvcGVydHkgd2lsbCBiZSBhbiBhcnJheSBvciBhIG5ldyBvYmplY3RcbiAgICAgIHByb3BWYWwgPSB0eXBlb2YgbmV4dC5wID09PSAndW5kZWZpbmVkJyA/IFtdIDoge307XG4gICAgICB0ZW1wT2JqW3Byb3BOYW1lXSA9IHByb3BWYWw7XG4gICAgICB0ZW1wT2JqID0gdGVtcE9ialtwcm9wTmFtZV07XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogIyMjIC5nZXRQYXRoSW5mbyhvYmplY3QsIHBhdGgpXG4gKlxuICogVGhpcyBhbGxvd3MgdGhlIHJldHJpZXZhbCBvZiBwcm9wZXJ0eSBpbmZvIGluIGFuXG4gKiBvYmplY3QgZ2l2ZW4gYSBzdHJpbmcgcGF0aC5cbiAqXG4gKiBUaGUgcGF0aCBpbmZvIGNvbnNpc3RzIG9mIGFuIG9iamVjdCB3aXRoIHRoZVxuICogZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gKlxuICogKiBwYXJlbnQgLSBUaGUgcGFyZW50IG9iamVjdCBvZiB0aGUgcHJvcGVydHkgcmVmZXJlbmNlZCBieSBgcGF0aGBcbiAqICogbmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBmaW5hbCBwcm9wZXJ0eSwgYSBudW1iZXIgaWYgaXQgd2FzIGFuIGFycmF5IGluZGV4ZXJcbiAqICogdmFsdWUgLSBUaGUgdmFsdWUgb2YgdGhlIHByb3BlcnR5LCBpZiBpdCBleGlzdHMsIG90aGVyd2lzZSBgdW5kZWZpbmVkYFxuICogKiBleGlzdHMgLSBXaGV0aGVyIHRoZSBwcm9wZXJ0eSBleGlzdHMgb3Igbm90XG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICogQHBhcmFtIHtTdHJpbmd9IHBhdGhcbiAqIEByZXR1cm5zIHtPYmplY3R9IGluZm9cbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBuYW1lIGdldFBhdGhJbmZvXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGdldFBhdGhJbmZvKG9iaiwgcGF0aCkge1xuICB2YXIgcGFyc2VkID0gcGFyc2VQYXRoKHBhdGgpO1xuICB2YXIgbGFzdCA9IHBhcnNlZFtwYXJzZWQubGVuZ3RoIC0gMV07XG4gIHZhciBpbmZvID0ge1xuICAgIHBhcmVudDpcbiAgICAgIHBhcnNlZC5sZW5ndGggPiAxID9cbiAgICAgICAgaW50ZXJuYWxHZXRQYXRoVmFsdWUob2JqLCBwYXJzZWQsIHBhcnNlZC5sZW5ndGggLSAxKSA6XG4gICAgICAgIG9iaixcbiAgICBuYW1lOiBsYXN0LnAgfHwgbGFzdC5pLFxuICAgIHZhbHVlOiBpbnRlcm5hbEdldFBhdGhWYWx1ZShvYmosIHBhcnNlZCksXG4gIH07XG4gIGluZm8uZXhpc3RzID0gaGFzUHJvcGVydHkoaW5mby5wYXJlbnQsIGluZm8ubmFtZSk7XG5cbiAgcmV0dXJuIGluZm87XG59XG5cbi8qKlxuICogIyMjIC5nZXRQYXRoVmFsdWUob2JqZWN0LCBwYXRoKVxuICpcbiAqIFRoaXMgYWxsb3dzIHRoZSByZXRyaWV2YWwgb2YgdmFsdWVzIGluIGFuXG4gKiBvYmplY3QgZ2l2ZW4gYSBzdHJpbmcgcGF0aC5cbiAqXG4gKiAgICAgdmFyIG9iaiA9IHtcbiAqICAgICAgICAgcHJvcDE6IHtcbiAqICAgICAgICAgICAgIGFycjogWydhJywgJ2InLCAnYyddXG4gKiAgICAgICAgICAgLCBzdHI6ICdIZWxsbydcbiAqICAgICAgICAgfVxuICogICAgICAgLCBwcm9wMjoge1xuICogICAgICAgICAgICAgYXJyOiBbIHsgbmVzdGVkOiAnVW5pdmVyc2UnIH0gXVxuICogICAgICAgICAgICwgc3RyOiAnSGVsbG8gYWdhaW4hJ1xuICogICAgICAgICB9XG4gKiAgICAgfVxuICpcbiAqIFRoZSBmb2xsb3dpbmcgd291bGQgYmUgdGhlIHJlc3VsdHMuXG4gKlxuICogICAgIGdldFBhdGhWYWx1ZShvYmosICdwcm9wMS5zdHInKTsgLy8gSGVsbG9cbiAqICAgICBnZXRQYXRoVmFsdWUob2JqLCAncHJvcDEuYXR0WzJdJyk7IC8vIGJcbiAqICAgICBnZXRQYXRoVmFsdWUob2JqLCAncHJvcDIuYXJyWzBdLm5lc3RlZCcpOyAvLyBVbml2ZXJzZVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAqIEBwYXJhbSB7U3RyaW5nfSBwYXRoXG4gKiBAcmV0dXJucyB7T2JqZWN0fSB2YWx1ZSBvciBgdW5kZWZpbmVkYFxuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQG5hbWUgZ2V0UGF0aFZhbHVlXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGdldFBhdGhWYWx1ZShvYmosIHBhdGgpIHtcbiAgdmFyIGluZm8gPSBnZXRQYXRoSW5mbyhvYmosIHBhdGgpO1xuICByZXR1cm4gaW5mby52YWx1ZTtcbn1cblxuLyoqXG4gKiAjIyMgLnNldFBhdGhWYWx1ZShvYmplY3QsIHBhdGgsIHZhbHVlKVxuICpcbiAqIERlZmluZSB0aGUgdmFsdWUgaW4gYW4gb2JqZWN0IGF0IGEgZ2l2ZW4gc3RyaW5nIHBhdGguXG4gKlxuICogYGBganNcbiAqIHZhciBvYmogPSB7XG4gKiAgICAgcHJvcDE6IHtcbiAqICAgICAgICAgYXJyOiBbJ2EnLCAnYicsICdjJ11cbiAqICAgICAgICwgc3RyOiAnSGVsbG8nXG4gKiAgICAgfVxuICogICAsIHByb3AyOiB7XG4gKiAgICAgICAgIGFycjogWyB7IG5lc3RlZDogJ1VuaXZlcnNlJyB9IF1cbiAqICAgICAgICwgc3RyOiAnSGVsbG8gYWdhaW4hJ1xuICogICAgIH1cbiAqIH07XG4gKiBgYGBcbiAqXG4gKiBUaGUgZm9sbG93aW5nIHdvdWxkIGJlIGFjY2VwdGFibGUuXG4gKlxuICogYGBganNcbiAqIHZhciBwcm9wZXJ0aWVzID0gcmVxdWlyZSgndGVhLXByb3BlcnRpZXMnKTtcbiAqIHByb3BlcnRpZXMuc2V0KG9iaiwgJ3Byb3AxLnN0cicsICdIZWxsbyBVbml2ZXJzZSEnKTtcbiAqIHByb3BlcnRpZXMuc2V0KG9iaiwgJ3Byb3AxLmFyclsyXScsICdCJyk7XG4gKiBwcm9wZXJ0aWVzLnNldChvYmosICdwcm9wMi5hcnJbMF0ubmVzdGVkLnZhbHVlJywgeyBoZWxsbzogJ3VuaXZlcnNlJyB9KTtcbiAqIGBgYFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAqIEBwYXJhbSB7U3RyaW5nfSBwYXRoXG4gKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gc2V0UGF0aFZhbHVlKG9iaiwgcGF0aCwgdmFsKSB7XG4gIHZhciBwYXJzZWQgPSBwYXJzZVBhdGgocGF0aCk7XG4gIGludGVybmFsU2V0UGF0aFZhbHVlKG9iaiwgdmFsLCBwYXJzZWQpO1xuICByZXR1cm4gb2JqO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgaGFzUHJvcGVydHk6IGhhc1Byb3BlcnR5LFxuICBnZXRQYXRoSW5mbzogZ2V0UGF0aEluZm8sXG4gIGdldFBhdGhWYWx1ZTogZ2V0UGF0aFZhbHVlLFxuICBzZXRQYXRoVmFsdWU6IHNldFBhdGhWYWx1ZSxcbn07XG4iLCAiLyohXG4gKiBDaGFpIC0gZmxhZyB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyoqXG4gKiAjIyMgLmZsYWcob2JqZWN0LCBrZXksIFt2YWx1ZV0pXG4gKlxuICogR2V0IG9yIHNldCBhIGZsYWcgdmFsdWUgb24gYW4gb2JqZWN0LiBJZiBhXG4gKiB2YWx1ZSBpcyBwcm92aWRlZCBpdCB3aWxsIGJlIHNldCwgZWxzZSBpdCB3aWxsXG4gKiByZXR1cm4gdGhlIGN1cnJlbnRseSBzZXQgdmFsdWUgb3IgYHVuZGVmaW5lZGAgaWZcbiAqIHRoZSB2YWx1ZSBpcyBub3Qgc2V0LlxuICpcbiAqICAgICB1dGlscy5mbGFnKHRoaXMsICdmb28nLCAnYmFyJyk7IC8vIHNldHRlclxuICogICAgIHV0aWxzLmZsYWcodGhpcywgJ2ZvbycpOyAvLyBnZXR0ZXIsIHJldHVybnMgYGJhcmBcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IGNvbnN0cnVjdGVkIEFzc2VydGlvblxuICogQHBhcmFtIHtTdHJpbmd9IGtleVxuICogQHBhcmFtIHtNaXhlZH0gdmFsdWUgKG9wdGlvbmFsKVxuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQG5hbWUgZmxhZ1xuICogQGFwaSBwcml2YXRlXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBmbGFnKG9iaiwga2V5LCB2YWx1ZSkge1xuICB2YXIgZmxhZ3MgPSBvYmouX19mbGFncyB8fCAob2JqLl9fZmxhZ3MgPSBPYmplY3QuY3JlYXRlKG51bGwpKTtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDMpIHtcbiAgICBmbGFnc1trZXldID0gdmFsdWU7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGZsYWdzW2tleV07XG4gIH1cbn07XG4iLCAiLyohXG4gKiBDaGFpIC0gdGVzdCB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyohXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzXG4gKi9cblxudmFyIGZsYWcgPSByZXF1aXJlKCcuL2ZsYWcnKTtcblxuLyoqXG4gKiAjIyMgLnRlc3Qob2JqZWN0LCBleHByZXNzaW9uKVxuICpcbiAqIFRlc3QgYW5kIG9iamVjdCBmb3IgZXhwcmVzc2lvbi5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IChjb25zdHJ1Y3RlZCBBc3NlcnRpb24pXG4gKiBAcGFyYW0ge0FyZ3VtZW50c30gY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLmFzc2VydCBhcmd1bWVudHNcbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBuYW1lIHRlc3RcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHRlc3Qob2JqLCBhcmdzKSB7XG4gIHZhciBuZWdhdGUgPSBmbGFnKG9iaiwgJ25lZ2F0ZScpXG4gICAgLCBleHByID0gYXJnc1swXTtcbiAgcmV0dXJuIG5lZ2F0ZSA/ICFleHByIDogZXhwcjtcbn07XG4iLCAiKGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcblx0dHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnID8gbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KCkgOlxuXHR0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQgPyBkZWZpbmUoZmFjdG9yeSkgOlxuXHQoZ2xvYmFsLnR5cGVEZXRlY3QgPSBmYWN0b3J5KCkpO1xufSh0aGlzLCAoZnVuY3Rpb24gKCkgeyAndXNlIHN0cmljdCc7XG5cbi8qICFcbiAqIHR5cGUtZGV0ZWN0XG4gKiBDb3B5cmlnaHQoYykgMjAxMyBqYWtlIGx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG52YXIgcHJvbWlzZUV4aXN0cyA9IHR5cGVvZiBQcm9taXNlID09PSAnZnVuY3Rpb24nO1xuXG4vKiBlc2xpbnQtZGlzYWJsZSBuby11bmRlZiAqL1xudmFyIGdsb2JhbE9iamVjdCA9IHR5cGVvZiBzZWxmID09PSAnb2JqZWN0JyA/IHNlbGYgOiBnbG9iYWw7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgaWQtYmxhY2tsaXN0XG5cbnZhciBzeW1ib2xFeGlzdHMgPSB0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJztcbnZhciBtYXBFeGlzdHMgPSB0eXBlb2YgTWFwICE9PSAndW5kZWZpbmVkJztcbnZhciBzZXRFeGlzdHMgPSB0eXBlb2YgU2V0ICE9PSAndW5kZWZpbmVkJztcbnZhciB3ZWFrTWFwRXhpc3RzID0gdHlwZW9mIFdlYWtNYXAgIT09ICd1bmRlZmluZWQnO1xudmFyIHdlYWtTZXRFeGlzdHMgPSB0eXBlb2YgV2Vha1NldCAhPT0gJ3VuZGVmaW5lZCc7XG52YXIgZGF0YVZpZXdFeGlzdHMgPSB0eXBlb2YgRGF0YVZpZXcgIT09ICd1bmRlZmluZWQnO1xudmFyIHN5bWJvbEl0ZXJhdG9yRXhpc3RzID0gc3ltYm9sRXhpc3RzICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgIT09ICd1bmRlZmluZWQnO1xudmFyIHN5bWJvbFRvU3RyaW5nVGFnRXhpc3RzID0gc3ltYm9sRXhpc3RzICYmIHR5cGVvZiBTeW1ib2wudG9TdHJpbmdUYWcgIT09ICd1bmRlZmluZWQnO1xudmFyIHNldEVudHJpZXNFeGlzdHMgPSBzZXRFeGlzdHMgJiYgdHlwZW9mIFNldC5wcm90b3R5cGUuZW50cmllcyA9PT0gJ2Z1bmN0aW9uJztcbnZhciBtYXBFbnRyaWVzRXhpc3RzID0gbWFwRXhpc3RzICYmIHR5cGVvZiBNYXAucHJvdG90eXBlLmVudHJpZXMgPT09ICdmdW5jdGlvbic7XG52YXIgc2V0SXRlcmF0b3JQcm90b3R5cGUgPSBzZXRFbnRyaWVzRXhpc3RzICYmIE9iamVjdC5nZXRQcm90b3R5cGVPZihuZXcgU2V0KCkuZW50cmllcygpKTtcbnZhciBtYXBJdGVyYXRvclByb3RvdHlwZSA9IG1hcEVudHJpZXNFeGlzdHMgJiYgT2JqZWN0LmdldFByb3RvdHlwZU9mKG5ldyBNYXAoKS5lbnRyaWVzKCkpO1xudmFyIGFycmF5SXRlcmF0b3JFeGlzdHMgPSBzeW1ib2xJdGVyYXRvckV4aXN0cyAmJiB0eXBlb2YgQXJyYXkucHJvdG90eXBlW1N5bWJvbC5pdGVyYXRvcl0gPT09ICdmdW5jdGlvbic7XG52YXIgYXJyYXlJdGVyYXRvclByb3RvdHlwZSA9IGFycmF5SXRlcmF0b3JFeGlzdHMgJiYgT2JqZWN0LmdldFByb3RvdHlwZU9mKFtdW1N5bWJvbC5pdGVyYXRvcl0oKSk7XG52YXIgc3RyaW5nSXRlcmF0b3JFeGlzdHMgPSBzeW1ib2xJdGVyYXRvckV4aXN0cyAmJiB0eXBlb2YgU3RyaW5nLnByb3RvdHlwZVtTeW1ib2wuaXRlcmF0b3JdID09PSAnZnVuY3Rpb24nO1xudmFyIHN0cmluZ0l0ZXJhdG9yUHJvdG90eXBlID0gc3RyaW5nSXRlcmF0b3JFeGlzdHMgJiYgT2JqZWN0LmdldFByb3RvdHlwZU9mKCcnW1N5bWJvbC5pdGVyYXRvcl0oKSk7XG52YXIgdG9TdHJpbmdMZWZ0U2xpY2VMZW5ndGggPSA4O1xudmFyIHRvU3RyaW5nUmlnaHRTbGljZUxlbmd0aCA9IC0xO1xuLyoqXG4gKiAjIyMgdHlwZU9mIChvYmopXG4gKlxuICogVXNlcyBgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZ2AgdG8gZGV0ZXJtaW5lIHRoZSB0eXBlIG9mIGFuIG9iamVjdCxcbiAqIG5vcm1hbGlzaW5nIGJlaGF2aW91ciBhY3Jvc3MgZW5naW5lIHZlcnNpb25zICYgd2VsbCBvcHRpbWlzZWQuXG4gKlxuICogQHBhcmFtIHtNaXhlZH0gb2JqZWN0XG4gKiBAcmV0dXJuIHtTdHJpbmd9IG9iamVjdCB0eXBlXG4gKiBAYXBpIHB1YmxpY1xuICovXG5mdW5jdGlvbiB0eXBlRGV0ZWN0KG9iaikge1xuICAvKiAhIFNwZWVkIG9wdGltaXNhdGlvblxuICAgKiBQcmU6XG4gICAqICAgc3RyaW5nIGxpdGVyYWwgICAgIHggMywwMzksMDM1IG9wcy9zZWMgXHUwMEIxMS42MiUgKDc4IHJ1bnMgc2FtcGxlZClcbiAgICogICBib29sZWFuIGxpdGVyYWwgICAgeCAxLDQyNCwxMzggb3BzL3NlYyBcdTAwQjE0LjU0JSAoNzUgcnVucyBzYW1wbGVkKVxuICAgKiAgIG51bWJlciBsaXRlcmFsICAgICB4IDEsNjUzLDE1MyBvcHMvc2VjIFx1MDBCMTEuOTElICg4MiBydW5zIHNhbXBsZWQpXG4gICAqICAgdW5kZWZpbmVkICAgICAgICAgIHggOSw5NzgsNjYwIG9wcy9zZWMgXHUwMEIxMS45MiUgKDc1IHJ1bnMgc2FtcGxlZClcbiAgICogICBmdW5jdGlvbiAgICAgICAgICAgeCAyLDU1Niw3Njkgb3BzL3NlYyBcdTAwQjExLjczJSAoNzcgcnVucyBzYW1wbGVkKVxuICAgKiBQb3N0OlxuICAgKiAgIHN0cmluZyBsaXRlcmFsICAgICB4IDM4LDU2NCw3OTYgb3BzL3NlYyBcdTAwQjExLjE1JSAoNzkgcnVucyBzYW1wbGVkKVxuICAgKiAgIGJvb2xlYW4gbGl0ZXJhbCAgICB4IDMxLDE0OCw5NDAgb3BzL3NlYyBcdTAwQjExLjEwJSAoNzkgcnVucyBzYW1wbGVkKVxuICAgKiAgIG51bWJlciBsaXRlcmFsICAgICB4IDMyLDY3OSwzMzAgb3BzL3NlYyBcdTAwQjExLjkwJSAoNzggcnVucyBzYW1wbGVkKVxuICAgKiAgIHVuZGVmaW5lZCAgICAgICAgICB4IDMyLDM2MywzNjggb3BzL3NlYyBcdTAwQjExLjA3JSAoODIgcnVucyBzYW1wbGVkKVxuICAgKiAgIGZ1bmN0aW9uICAgICAgICAgICB4IDMxLDI5Niw4NzAgb3BzL3NlYyBcdTAwQjEwLjk2JSAoODMgcnVucyBzYW1wbGVkKVxuICAgKi9cbiAgdmFyIHR5cGVvZk9iaiA9IHR5cGVvZiBvYmo7XG4gIGlmICh0eXBlb2ZPYmogIT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIHR5cGVvZk9iajtcbiAgfVxuXG4gIC8qICEgU3BlZWQgb3B0aW1pc2F0aW9uXG4gICAqIFByZTpcbiAgICogICBudWxsICAgICAgICAgICAgICAgeCAyOCw2NDUsNzY1IG9wcy9zZWMgXHUwMEIxMS4xNyUgKDgyIHJ1bnMgc2FtcGxlZClcbiAgICogUG9zdDpcbiAgICogICBudWxsICAgICAgICAgICAgICAgeCAzNiw0MjgsOTYyIG9wcy9zZWMgXHUwMEIxMS4zNyUgKDg0IHJ1bnMgc2FtcGxlZClcbiAgICovXG4gIGlmIChvYmogPT09IG51bGwpIHtcbiAgICByZXR1cm4gJ251bGwnO1xuICB9XG5cbiAgLyogISBTcGVjIENvbmZvcm1hbmNlXG4gICAqIFRlc3Q6IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwod2luZG93KWBgXG4gICAqICAtIE5vZGUgPT09IFwiW29iamVjdCBnbG9iYWxdXCJcbiAgICogIC0gQ2hyb21lID09PSBcIltvYmplY3QgZ2xvYmFsXVwiXG4gICAqICAtIEZpcmVmb3ggPT09IFwiW29iamVjdCBXaW5kb3ddXCJcbiAgICogIC0gUGhhbnRvbUpTID09PSBcIltvYmplY3QgV2luZG93XVwiXG4gICAqICAtIFNhZmFyaSA9PT0gXCJbb2JqZWN0IFdpbmRvd11cIlxuICAgKiAgLSBJRSAxMSA9PT0gXCJbb2JqZWN0IFdpbmRvd11cIlxuICAgKiAgLSBJRSBFZGdlID09PSBcIltvYmplY3QgV2luZG93XVwiXG4gICAqIFRlc3Q6IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodGhpcylgYFxuICAgKiAgLSBDaHJvbWUgV29ya2VyID09PSBcIltvYmplY3QgZ2xvYmFsXVwiXG4gICAqICAtIEZpcmVmb3ggV29ya2VyID09PSBcIltvYmplY3QgRGVkaWNhdGVkV29ya2VyR2xvYmFsU2NvcGVdXCJcbiAgICogIC0gU2FmYXJpIFdvcmtlciA9PT0gXCJbb2JqZWN0IERlZGljYXRlZFdvcmtlckdsb2JhbFNjb3BlXVwiXG4gICAqICAtIElFIDExIFdvcmtlciA9PT0gXCJbb2JqZWN0IFdvcmtlckdsb2JhbFNjb3BlXVwiXG4gICAqICAtIElFIEVkZ2UgV29ya2VyID09PSBcIltvYmplY3QgV29ya2VyR2xvYmFsU2NvcGVdXCJcbiAgICovXG4gIGlmIChvYmogPT09IGdsb2JhbE9iamVjdCkge1xuICAgIHJldHVybiAnZ2xvYmFsJztcbiAgfVxuXG4gIC8qICEgU3BlZWQgb3B0aW1pc2F0aW9uXG4gICAqIFByZTpcbiAgICogICBhcnJheSBsaXRlcmFsICAgICAgeCAyLDg4OCwzNTIgb3BzL3NlYyBcdTAwQjEwLjY3JSAoODIgcnVucyBzYW1wbGVkKVxuICAgKiBQb3N0OlxuICAgKiAgIGFycmF5IGxpdGVyYWwgICAgICB4IDIyLDQ3OSw2NTAgb3BzL3NlYyBcdTAwQjEwLjk2JSAoODEgcnVucyBzYW1wbGVkKVxuICAgKi9cbiAgaWYgKFxuICAgIEFycmF5LmlzQXJyYXkob2JqKSAmJlxuICAgIChzeW1ib2xUb1N0cmluZ1RhZ0V4aXN0cyA9PT0gZmFsc2UgfHwgIShTeW1ib2wudG9TdHJpbmdUYWcgaW4gb2JqKSlcbiAgKSB7XG4gICAgcmV0dXJuICdBcnJheSc7XG4gIH1cblxuICAvLyBOb3QgY2FjaGluZyBleGlzdGVuY2Ugb2YgYHdpbmRvd2AgYW5kIHJlbGF0ZWQgcHJvcGVydGllcyBkdWUgdG8gcG90ZW50aWFsXG4gIC8vIGZvciBgd2luZG93YCB0byBiZSB1bnNldCBiZWZvcmUgdGVzdHMgaW4gcXVhc2ktYnJvd3NlciBlbnZpcm9ubWVudHMuXG4gIGlmICh0eXBlb2Ygd2luZG93ID09PSAnb2JqZWN0JyAmJiB3aW5kb3cgIT09IG51bGwpIHtcbiAgICAvKiAhIFNwZWMgQ29uZm9ybWFuY2VcbiAgICAgKiAoaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2UvYnJvd3NlcnMuaHRtbCNsb2NhdGlvbilcbiAgICAgKiBXaGF0V0cgSFRNTCQ3LjcuMyAtIFRoZSBgTG9jYXRpb25gIGludGVyZmFjZVxuICAgICAqIFRlc3Q6IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwod2luZG93LmxvY2F0aW9uKWBgXG4gICAgICogIC0gSUUgPD0xMSA9PT0gXCJbb2JqZWN0IE9iamVjdF1cIlxuICAgICAqICAtIElFIEVkZ2UgPD0xMyA9PT0gXCJbb2JqZWN0IE9iamVjdF1cIlxuICAgICAqL1xuICAgIGlmICh0eXBlb2Ygd2luZG93LmxvY2F0aW9uID09PSAnb2JqZWN0JyAmJiBvYmogPT09IHdpbmRvdy5sb2NhdGlvbikge1xuICAgICAgcmV0dXJuICdMb2NhdGlvbic7XG4gICAgfVxuXG4gICAgLyogISBTcGVjIENvbmZvcm1hbmNlXG4gICAgICogKGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvI2RvY3VtZW50KVxuICAgICAqIFdoYXRXRyBIVE1MJDMuMS4xIC0gVGhlIGBEb2N1bWVudGAgb2JqZWN0XG4gICAgICogTm90ZTogTW9zdCBicm93c2VycyBjdXJyZW50bHkgYWRoZXIgdG8gdGhlIFczQyBET00gTGV2ZWwgMiBzcGVjXG4gICAgICogICAgICAgKGh0dHBzOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1IVE1ML2h0bWwuaHRtbCNJRC0yNjgwOTI2OClcbiAgICAgKiAgICAgICB3aGljaCBzdWdnZXN0cyB0aGF0IGJyb3dzZXJzIHNob3VsZCB1c2UgSFRNTFRhYmxlQ2VsbEVsZW1lbnQgZm9yXG4gICAgICogICAgICAgYm90aCBURCBhbmQgVEggZWxlbWVudHMuIFdoYXRXRyBzZXBhcmF0ZXMgdGhlc2UuXG4gICAgICogICAgICAgV2hhdFdHIEhUTUwgc3RhdGVzOlxuICAgICAqICAgICAgICAgPiBGb3IgaGlzdG9yaWNhbCByZWFzb25zLCBXaW5kb3cgb2JqZWN0cyBtdXN0IGFsc28gaGF2ZSBhXG4gICAgICogICAgICAgICA+IHdyaXRhYmxlLCBjb25maWd1cmFibGUsIG5vbi1lbnVtZXJhYmxlIHByb3BlcnR5IG5hbWVkXG4gICAgICogICAgICAgICA+IEhUTUxEb2N1bWVudCB3aG9zZSB2YWx1ZSBpcyB0aGUgRG9jdW1lbnQgaW50ZXJmYWNlIG9iamVjdC5cbiAgICAgKiBUZXN0OiBgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGRvY3VtZW50KWBgXG4gICAgICogIC0gQ2hyb21lID09PSBcIltvYmplY3QgSFRNTERvY3VtZW50XVwiXG4gICAgICogIC0gRmlyZWZveCA9PT0gXCJbb2JqZWN0IEhUTUxEb2N1bWVudF1cIlxuICAgICAqICAtIFNhZmFyaSA9PT0gXCJbb2JqZWN0IEhUTUxEb2N1bWVudF1cIlxuICAgICAqICAtIElFIDw9MTAgPT09IFwiW29iamVjdCBEb2N1bWVudF1cIlxuICAgICAqICAtIElFIDExID09PSBcIltvYmplY3QgSFRNTERvY3VtZW50XVwiXG4gICAgICogIC0gSUUgRWRnZSA8PTEzID09PSBcIltvYmplY3QgSFRNTERvY3VtZW50XVwiXG4gICAgICovXG4gICAgaWYgKHR5cGVvZiB3aW5kb3cuZG9jdW1lbnQgPT09ICdvYmplY3QnICYmIG9iaiA9PT0gd2luZG93LmRvY3VtZW50KSB7XG4gICAgICByZXR1cm4gJ0RvY3VtZW50JztcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHdpbmRvdy5uYXZpZ2F0b3IgPT09ICdvYmplY3QnKSB7XG4gICAgICAvKiAhIFNwZWMgQ29uZm9ybWFuY2VcbiAgICAgICAqIChodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS93ZWJhcHBhcGlzLmh0bWwjbWltZXR5cGVhcnJheSlcbiAgICAgICAqIFdoYXRXRyBIVE1MJDguNi4xLjUgLSBQbHVnaW5zIC0gSW50ZXJmYWNlIE1pbWVUeXBlQXJyYXlcbiAgICAgICAqIFRlc3Q6IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobmF2aWdhdG9yLm1pbWVUeXBlcylgYFxuICAgICAgICogIC0gSUUgPD0xMCA9PT0gXCJbb2JqZWN0IE1TTWltZVR5cGVzQ29sbGVjdGlvbl1cIlxuICAgICAgICovXG4gICAgICBpZiAodHlwZW9mIHdpbmRvdy5uYXZpZ2F0b3IubWltZVR5cGVzID09PSAnb2JqZWN0JyAmJlxuICAgICAgICAgIG9iaiA9PT0gd2luZG93Lm5hdmlnYXRvci5taW1lVHlwZXMpIHtcbiAgICAgICAgcmV0dXJuICdNaW1lVHlwZUFycmF5JztcbiAgICAgIH1cblxuICAgICAgLyogISBTcGVjIENvbmZvcm1hbmNlXG4gICAgICAgKiAoaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvd2ViYXBwYXBpcy5odG1sI3BsdWdpbmFycmF5KVxuICAgICAgICogV2hhdFdHIEhUTUwkOC42LjEuNSAtIFBsdWdpbnMgLSBJbnRlcmZhY2UgUGx1Z2luQXJyYXlcbiAgICAgICAqIFRlc3Q6IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobmF2aWdhdG9yLnBsdWdpbnMpYGBcbiAgICAgICAqICAtIElFIDw9MTAgPT09IFwiW29iamVjdCBNU1BsdWdpbnNDb2xsZWN0aW9uXVwiXG4gICAgICAgKi9cbiAgICAgIGlmICh0eXBlb2Ygd2luZG93Lm5hdmlnYXRvci5wbHVnaW5zID09PSAnb2JqZWN0JyAmJlxuICAgICAgICAgIG9iaiA9PT0gd2luZG93Lm5hdmlnYXRvci5wbHVnaW5zKSB7XG4gICAgICAgIHJldHVybiAnUGx1Z2luQXJyYXknO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICgodHlwZW9mIHdpbmRvdy5IVE1MRWxlbWVudCA9PT0gJ2Z1bmN0aW9uJyB8fFxuICAgICAgICB0eXBlb2Ygd2luZG93LkhUTUxFbGVtZW50ID09PSAnb2JqZWN0JykgJiZcbiAgICAgICAgb2JqIGluc3RhbmNlb2Ygd2luZG93LkhUTUxFbGVtZW50KSB7XG4gICAgICAvKiAhIFNwZWMgQ29uZm9ybWFuY2VcbiAgICAgICogKGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3dlYmFwcGFwaXMuaHRtbCNwbHVnaW5hcnJheSlcbiAgICAgICogV2hhdFdHIEhUTUwkNC40LjQgLSBUaGUgYGJsb2NrcXVvdGVgIGVsZW1lbnQgLSBJbnRlcmZhY2UgYEhUTUxRdW90ZUVsZW1lbnRgXG4gICAgICAqIFRlc3Q6IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYmxvY2txdW90ZScpKWBgXG4gICAgICAqICAtIElFIDw9MTAgPT09IFwiW29iamVjdCBIVE1MQmxvY2tFbGVtZW50XVwiXG4gICAgICAqL1xuICAgICAgaWYgKG9iai50YWdOYW1lID09PSAnQkxPQ0tRVU9URScpIHtcbiAgICAgICAgcmV0dXJuICdIVE1MUXVvdGVFbGVtZW50JztcbiAgICAgIH1cblxuICAgICAgLyogISBTcGVjIENvbmZvcm1hbmNlXG4gICAgICAgKiAoaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy8jaHRtbHRhYmxlZGF0YWNlbGxlbGVtZW50KVxuICAgICAgICogV2hhdFdHIEhUTUwkNC45LjkgLSBUaGUgYHRkYCBlbGVtZW50IC0gSW50ZXJmYWNlIGBIVE1MVGFibGVEYXRhQ2VsbEVsZW1lbnRgXG4gICAgICAgKiBOb3RlOiBNb3N0IGJyb3dzZXJzIGN1cnJlbnRseSBhZGhlciB0byB0aGUgVzNDIERPTSBMZXZlbCAyIHNwZWNcbiAgICAgICAqICAgICAgIChodHRwczovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItSFRNTC9odG1sLmh0bWwjSUQtODI5MTUwNzUpXG4gICAgICAgKiAgICAgICB3aGljaCBzdWdnZXN0cyB0aGF0IGJyb3dzZXJzIHNob3VsZCB1c2UgSFRNTFRhYmxlQ2VsbEVsZW1lbnQgZm9yXG4gICAgICAgKiAgICAgICBib3RoIFREIGFuZCBUSCBlbGVtZW50cy4gV2hhdFdHIHNlcGFyYXRlcyB0aGVzZS5cbiAgICAgICAqIFRlc3Q6IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd0ZCcpKVxuICAgICAgICogIC0gQ2hyb21lID09PSBcIltvYmplY3QgSFRNTFRhYmxlQ2VsbEVsZW1lbnRdXCJcbiAgICAgICAqICAtIEZpcmVmb3ggPT09IFwiW29iamVjdCBIVE1MVGFibGVDZWxsRWxlbWVudF1cIlxuICAgICAgICogIC0gU2FmYXJpID09PSBcIltvYmplY3QgSFRNTFRhYmxlQ2VsbEVsZW1lbnRdXCJcbiAgICAgICAqL1xuICAgICAgaWYgKG9iai50YWdOYW1lID09PSAnVEQnKSB7XG4gICAgICAgIHJldHVybiAnSFRNTFRhYmxlRGF0YUNlbGxFbGVtZW50JztcbiAgICAgIH1cblxuICAgICAgLyogISBTcGVjIENvbmZvcm1hbmNlXG4gICAgICAgKiAoaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy8jaHRtbHRhYmxlaGVhZGVyY2VsbGVsZW1lbnQpXG4gICAgICAgKiBXaGF0V0cgSFRNTCQ0LjkuOSAtIFRoZSBgdGRgIGVsZW1lbnQgLSBJbnRlcmZhY2UgYEhUTUxUYWJsZUhlYWRlckNlbGxFbGVtZW50YFxuICAgICAgICogTm90ZTogTW9zdCBicm93c2VycyBjdXJyZW50bHkgYWRoZXIgdG8gdGhlIFczQyBET00gTGV2ZWwgMiBzcGVjXG4gICAgICAgKiAgICAgICAoaHR0cHM6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUhUTUwvaHRtbC5odG1sI0lELTgyOTE1MDc1KVxuICAgICAgICogICAgICAgd2hpY2ggc3VnZ2VzdHMgdGhhdCBicm93c2VycyBzaG91bGQgdXNlIEhUTUxUYWJsZUNlbGxFbGVtZW50IGZvclxuICAgICAgICogICAgICAgYm90aCBURCBhbmQgVEggZWxlbWVudHMuIFdoYXRXRyBzZXBhcmF0ZXMgdGhlc2UuXG4gICAgICAgKiBUZXN0OiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndGgnKSlcbiAgICAgICAqICAtIENocm9tZSA9PT0gXCJbb2JqZWN0IEhUTUxUYWJsZUNlbGxFbGVtZW50XVwiXG4gICAgICAgKiAgLSBGaXJlZm94ID09PSBcIltvYmplY3QgSFRNTFRhYmxlQ2VsbEVsZW1lbnRdXCJcbiAgICAgICAqICAtIFNhZmFyaSA9PT0gXCJbb2JqZWN0IEhUTUxUYWJsZUNlbGxFbGVtZW50XVwiXG4gICAgICAgKi9cbiAgICAgIGlmIChvYmoudGFnTmFtZSA9PT0gJ1RIJykge1xuICAgICAgICByZXR1cm4gJ0hUTUxUYWJsZUhlYWRlckNlbGxFbGVtZW50JztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKiAhIFNwZWVkIG9wdGltaXNhdGlvblxuICAqIFByZTpcbiAgKiAgIEZsb2F0NjRBcnJheSAgICAgICB4IDYyNSw2NDQgb3BzL3NlYyBcdTAwQjExLjU4JSAoODAgcnVucyBzYW1wbGVkKVxuICAqICAgRmxvYXQzMkFycmF5ICAgICAgIHggMSwyNzksODUyIG9wcy9zZWMgXHUwMEIxMi45MSUgKDc3IHJ1bnMgc2FtcGxlZClcbiAgKiAgIFVpbnQzMkFycmF5ICAgICAgICB4IDEsMTc4LDE4NSBvcHMvc2VjIFx1MDBCMTEuOTUlICg4MyBydW5zIHNhbXBsZWQpXG4gICogICBVaW50MTZBcnJheSAgICAgICAgeCAxLDAwOCwzODAgb3BzL3NlYyBcdTAwQjEyLjI1JSAoODAgcnVucyBzYW1wbGVkKVxuICAqICAgVWludDhBcnJheSAgICAgICAgIHggMSwxMjgsMDQwIG9wcy9zZWMgXHUwMEIxMi4xMSUgKDgxIHJ1bnMgc2FtcGxlZClcbiAgKiAgIEludDMyQXJyYXkgICAgICAgICB4IDEsMTcwLDExOSBvcHMvc2VjIFx1MDBCMTIuODglICg4MCBydW5zIHNhbXBsZWQpXG4gICogICBJbnQxNkFycmF5ICAgICAgICAgeCAxLDE3NiwzNDggb3BzL3NlYyBcdTAwQjE1Ljc5JSAoODYgcnVucyBzYW1wbGVkKVxuICAqICAgSW50OEFycmF5ICAgICAgICAgIHggMSwwNTgsNzA3IG9wcy9zZWMgXHUwMEIxNC45NCUgKDc3IHJ1bnMgc2FtcGxlZClcbiAgKiAgIFVpbnQ4Q2xhbXBlZEFycmF5ICB4IDEsMTEwLDYzMyBvcHMvc2VjIFx1MDBCMTQuMjAlICg4MCBydW5zIHNhbXBsZWQpXG4gICogUG9zdDpcbiAgKiAgIEZsb2F0NjRBcnJheSAgICAgICB4IDcsMTA1LDY3MSBvcHMvc2VjIFx1MDBCMTEzLjQ3JSAoNjQgcnVucyBzYW1wbGVkKVxuICAqICAgRmxvYXQzMkFycmF5ICAgICAgIHggNSw4ODcsOTEyIG9wcy9zZWMgXHUwMEIxMS40NiUgKDgyIHJ1bnMgc2FtcGxlZClcbiAgKiAgIFVpbnQzMkFycmF5ICAgICAgICB4IDYsNDkxLDY2MSBvcHMvc2VjIFx1MDBCMTEuNzYlICg3OSBydW5zIHNhbXBsZWQpXG4gICogICBVaW50MTZBcnJheSAgICAgICAgeCA2LDU1OSw3OTUgb3BzL3NlYyBcdTAwQjExLjY3JSAoODIgcnVucyBzYW1wbGVkKVxuICAqICAgVWludDhBcnJheSAgICAgICAgIHggNiw0NjMsOTY2IG9wcy9zZWMgXHUwMEIxMS40MyUgKDg1IHJ1bnMgc2FtcGxlZClcbiAgKiAgIEludDMyQXJyYXkgICAgICAgICB4IDUsNjQxLDg0MSBvcHMvc2VjIFx1MDBCMTMuNDklICg4MSBydW5zIHNhbXBsZWQpXG4gICogICBJbnQxNkFycmF5ICAgICAgICAgeCA2LDU4Myw1MTEgb3BzL3NlYyBcdTAwQjExLjk4JSAoODAgcnVucyBzYW1wbGVkKVxuICAqICAgSW50OEFycmF5ICAgICAgICAgIHggNiw2MDYsMDc4IG9wcy9zZWMgXHUwMEIxMS43NCUgKDgxIHJ1bnMgc2FtcGxlZClcbiAgKiAgIFVpbnQ4Q2xhbXBlZEFycmF5ICB4IDYsNjAyLDIyNCBvcHMvc2VjIFx1MDBCMTEuNzclICg4MyBydW5zIHNhbXBsZWQpXG4gICovXG4gIHZhciBzdHJpbmdUYWcgPSAoc3ltYm9sVG9TdHJpbmdUYWdFeGlzdHMgJiYgb2JqW1N5bWJvbC50b1N0cmluZ1RhZ10pO1xuICBpZiAodHlwZW9mIHN0cmluZ1RhZyA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gc3RyaW5nVGFnO1xuICB9XG5cbiAgdmFyIG9ialByb3RvdHlwZSA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihvYmopO1xuICAvKiAhIFNwZWVkIG9wdGltaXNhdGlvblxuICAqIFByZTpcbiAgKiAgIHJlZ2V4IGxpdGVyYWwgICAgICB4IDEsNzcyLDM4NSBvcHMvc2VjIFx1MDBCMTEuODUlICg3NyBydW5zIHNhbXBsZWQpXG4gICogICByZWdleCBjb25zdHJ1Y3RvciAgeCAyLDE0Myw2MzQgb3BzL3NlYyBcdTAwQjEyLjQ2JSAoNzggcnVucyBzYW1wbGVkKVxuICAqIFBvc3Q6XG4gICogICByZWdleCBsaXRlcmFsICAgICAgeCAzLDkyOCwwMDkgb3BzL3NlYyBcdTAwQjEwLjY1JSAoNzggcnVucyBzYW1wbGVkKVxuICAqICAgcmVnZXggY29uc3RydWN0b3IgIHggMyw5MzEsMTA4IG9wcy9zZWMgXHUwMEIxMC41OCUgKDg0IHJ1bnMgc2FtcGxlZClcbiAgKi9cbiAgaWYgKG9ialByb3RvdHlwZSA9PT0gUmVnRXhwLnByb3RvdHlwZSkge1xuICAgIHJldHVybiAnUmVnRXhwJztcbiAgfVxuXG4gIC8qICEgU3BlZWQgb3B0aW1pc2F0aW9uXG4gICogUHJlOlxuICAqICAgZGF0ZSAgICAgICAgICAgICAgIHggMiwxMzAsMDc0IG9wcy9zZWMgXHUwMEIxNC40MiUgKDY4IHJ1bnMgc2FtcGxlZClcbiAgKiBQb3N0OlxuICAqICAgZGF0ZSAgICAgICAgICAgICAgIHggMyw5NTMsNzc5IG9wcy9zZWMgXHUwMEIxMS4zNSUgKDc3IHJ1bnMgc2FtcGxlZClcbiAgKi9cbiAgaWYgKG9ialByb3RvdHlwZSA9PT0gRGF0ZS5wcm90b3R5cGUpIHtcbiAgICByZXR1cm4gJ0RhdGUnO1xuICB9XG5cbiAgLyogISBTcGVjIENvbmZvcm1hbmNlXG4gICAqIChodHRwOi8vd3d3LmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wL2luZGV4Lmh0bWwjc2VjLXByb21pc2UucHJvdG90eXBlLUBAdG9zdHJpbmd0YWcpXG4gICAqIEVTNiQyNS40LjUuNCAtIFByb21pc2UucHJvdG90eXBlW0BAdG9TdHJpbmdUYWddIHNob3VsZCBiZSBcIlByb21pc2VcIjpcbiAgICogVGVzdDogYE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChQcm9taXNlLnJlc29sdmUoKSlgYFxuICAgKiAgLSBDaHJvbWUgPD00NyA9PT0gXCJbb2JqZWN0IE9iamVjdF1cIlxuICAgKiAgLSBFZGdlIDw9MjAgPT09IFwiW29iamVjdCBPYmplY3RdXCJcbiAgICogIC0gRmlyZWZveCAyOS1MYXRlc3QgPT09IFwiW29iamVjdCBQcm9taXNlXVwiXG4gICAqICAtIFNhZmFyaSA3LjEtTGF0ZXN0ID09PSBcIltvYmplY3QgUHJvbWlzZV1cIlxuICAgKi9cbiAgaWYgKHByb21pc2VFeGlzdHMgJiYgb2JqUHJvdG90eXBlID09PSBQcm9taXNlLnByb3RvdHlwZSkge1xuICAgIHJldHVybiAnUHJvbWlzZSc7XG4gIH1cblxuICAvKiAhIFNwZWVkIG9wdGltaXNhdGlvblxuICAqIFByZTpcbiAgKiAgIHNldCAgICAgICAgICAgICAgICB4IDIsMjIyLDE4NiBvcHMvc2VjIFx1MDBCMTEuMzElICg4MiBydW5zIHNhbXBsZWQpXG4gICogUG9zdDpcbiAgKiAgIHNldCAgICAgICAgICAgICAgICB4IDQsNTQ1LDg3OSBvcHMvc2VjIFx1MDBCMTEuMTMlICg4MyBydW5zIHNhbXBsZWQpXG4gICovXG4gIGlmIChzZXRFeGlzdHMgJiYgb2JqUHJvdG90eXBlID09PSBTZXQucHJvdG90eXBlKSB7XG4gICAgcmV0dXJuICdTZXQnO1xuICB9XG5cbiAgLyogISBTcGVlZCBvcHRpbWlzYXRpb25cbiAgKiBQcmU6XG4gICogICBtYXAgICAgICAgICAgICAgICAgeCAyLDM5Niw4NDIgb3BzL3NlYyBcdTAwQjExLjU5JSAoODEgcnVucyBzYW1wbGVkKVxuICAqIFBvc3Q6XG4gICogICBtYXAgICAgICAgICAgICAgICAgeCA0LDE4Myw5NDUgb3BzL3NlYyBcdTAwQjE2LjU5JSAoODIgcnVucyBzYW1wbGVkKVxuICAqL1xuICBpZiAobWFwRXhpc3RzICYmIG9ialByb3RvdHlwZSA9PT0gTWFwLnByb3RvdHlwZSkge1xuICAgIHJldHVybiAnTWFwJztcbiAgfVxuXG4gIC8qICEgU3BlZWQgb3B0aW1pc2F0aW9uXG4gICogUHJlOlxuICAqICAgd2Vha3NldCAgICAgICAgICAgIHggMSwzMjMsMjIwIG9wcy9zZWMgXHUwMEIxMi4xNyUgKDc2IHJ1bnMgc2FtcGxlZClcbiAgKiBQb3N0OlxuICAqICAgd2Vha3NldCAgICAgICAgICAgIHggNCwyMzcsNTEwIG9wcy9zZWMgXHUwMEIxMi4wMSUgKDc3IHJ1bnMgc2FtcGxlZClcbiAgKi9cbiAgaWYgKHdlYWtTZXRFeGlzdHMgJiYgb2JqUHJvdG90eXBlID09PSBXZWFrU2V0LnByb3RvdHlwZSkge1xuICAgIHJldHVybiAnV2Vha1NldCc7XG4gIH1cblxuICAvKiAhIFNwZWVkIG9wdGltaXNhdGlvblxuICAqIFByZTpcbiAgKiAgIHdlYWttYXAgICAgICAgICAgICB4IDEsNTAwLDI2MCBvcHMvc2VjIFx1MDBCMTIuMDIlICg3OCBydW5zIHNhbXBsZWQpXG4gICogUG9zdDpcbiAgKiAgIHdlYWttYXAgICAgICAgICAgICB4IDMsODgxLDM4NCBvcHMvc2VjIFx1MDBCMTEuNDUlICg4MiBydW5zIHNhbXBsZWQpXG4gICovXG4gIGlmICh3ZWFrTWFwRXhpc3RzICYmIG9ialByb3RvdHlwZSA9PT0gV2Vha01hcC5wcm90b3R5cGUpIHtcbiAgICByZXR1cm4gJ1dlYWtNYXAnO1xuICB9XG5cbiAgLyogISBTcGVjIENvbmZvcm1hbmNlXG4gICAqIChodHRwOi8vd3d3LmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wL2luZGV4Lmh0bWwjc2VjLWRhdGF2aWV3LnByb3RvdHlwZS1AQHRvc3RyaW5ndGFnKVxuICAgKiBFUzYkMjQuMi40LjIxIC0gRGF0YVZpZXcucHJvdG90eXBlW0BAdG9TdHJpbmdUYWddIHNob3VsZCBiZSBcIkRhdGFWaWV3XCI6XG4gICAqIFRlc3Q6IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobmV3IERhdGFWaWV3KG5ldyBBcnJheUJ1ZmZlcigxKSkpYGBcbiAgICogIC0gRWRnZSA8PTEzID09PSBcIltvYmplY3QgT2JqZWN0XVwiXG4gICAqL1xuICBpZiAoZGF0YVZpZXdFeGlzdHMgJiYgb2JqUHJvdG90eXBlID09PSBEYXRhVmlldy5wcm90b3R5cGUpIHtcbiAgICByZXR1cm4gJ0RhdGFWaWV3JztcbiAgfVxuXG4gIC8qICEgU3BlYyBDb25mb3JtYW5jZVxuICAgKiAoaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC9pbmRleC5odG1sI3NlYy0lbWFwaXRlcmF0b3Jwcm90b3R5cGUlLUBAdG9zdHJpbmd0YWcpXG4gICAqIEVTNiQyMy4xLjUuMi4yIC0gJU1hcEl0ZXJhdG9yUHJvdG90eXBlJVtAQHRvU3RyaW5nVGFnXSBzaG91bGQgYmUgXCJNYXAgSXRlcmF0b3JcIjpcbiAgICogVGVzdDogYE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChuZXcgTWFwKCkuZW50cmllcygpKWBgXG4gICAqICAtIEVkZ2UgPD0xMyA9PT0gXCJbb2JqZWN0IE9iamVjdF1cIlxuICAgKi9cbiAgaWYgKG1hcEV4aXN0cyAmJiBvYmpQcm90b3R5cGUgPT09IG1hcEl0ZXJhdG9yUHJvdG90eXBlKSB7XG4gICAgcmV0dXJuICdNYXAgSXRlcmF0b3InO1xuICB9XG5cbiAgLyogISBTcGVjIENvbmZvcm1hbmNlXG4gICAqIChodHRwOi8vd3d3LmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wL2luZGV4Lmh0bWwjc2VjLSVzZXRpdGVyYXRvcnByb3RvdHlwZSUtQEB0b3N0cmluZ3RhZylcbiAgICogRVM2JDIzLjIuNS4yLjIgLSAlU2V0SXRlcmF0b3JQcm90b3R5cGUlW0BAdG9TdHJpbmdUYWddIHNob3VsZCBiZSBcIlNldCBJdGVyYXRvclwiOlxuICAgKiBUZXN0OiBgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG5ldyBTZXQoKS5lbnRyaWVzKCkpYGBcbiAgICogIC0gRWRnZSA8PTEzID09PSBcIltvYmplY3QgT2JqZWN0XVwiXG4gICAqL1xuICBpZiAoc2V0RXhpc3RzICYmIG9ialByb3RvdHlwZSA9PT0gc2V0SXRlcmF0b3JQcm90b3R5cGUpIHtcbiAgICByZXR1cm4gJ1NldCBJdGVyYXRvcic7XG4gIH1cblxuICAvKiAhIFNwZWMgQ29uZm9ybWFuY2VcbiAgICogKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvaW5kZXguaHRtbCNzZWMtJWFycmF5aXRlcmF0b3Jwcm90b3R5cGUlLUBAdG9zdHJpbmd0YWcpXG4gICAqIEVTNiQyMi4xLjUuMi4yIC0gJUFycmF5SXRlcmF0b3JQcm90b3R5cGUlW0BAdG9TdHJpbmdUYWddIHNob3VsZCBiZSBcIkFycmF5IEl0ZXJhdG9yXCI6XG4gICAqIFRlc3Q6IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoW11bU3ltYm9sLml0ZXJhdG9yXSgpKWBgXG4gICAqICAtIEVkZ2UgPD0xMyA9PT0gXCJbb2JqZWN0IE9iamVjdF1cIlxuICAgKi9cbiAgaWYgKGFycmF5SXRlcmF0b3JFeGlzdHMgJiYgb2JqUHJvdG90eXBlID09PSBhcnJheUl0ZXJhdG9yUHJvdG90eXBlKSB7XG4gICAgcmV0dXJuICdBcnJheSBJdGVyYXRvcic7XG4gIH1cblxuICAvKiAhIFNwZWMgQ29uZm9ybWFuY2VcbiAgICogKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvaW5kZXguaHRtbCNzZWMtJXN0cmluZ2l0ZXJhdG9ycHJvdG90eXBlJS1AQHRvc3RyaW5ndGFnKVxuICAgKiBFUzYkMjEuMS41LjIuMiAtICVTdHJpbmdJdGVyYXRvclByb3RvdHlwZSVbQEB0b1N0cmluZ1RhZ10gc2hvdWxkIGJlIFwiU3RyaW5nIEl0ZXJhdG9yXCI6XG4gICAqIFRlc3Q6IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoJydbU3ltYm9sLml0ZXJhdG9yXSgpKWBgXG4gICAqICAtIEVkZ2UgPD0xMyA9PT0gXCJbb2JqZWN0IE9iamVjdF1cIlxuICAgKi9cbiAgaWYgKHN0cmluZ0l0ZXJhdG9yRXhpc3RzICYmIG9ialByb3RvdHlwZSA9PT0gc3RyaW5nSXRlcmF0b3JQcm90b3R5cGUpIHtcbiAgICByZXR1cm4gJ1N0cmluZyBJdGVyYXRvcic7XG4gIH1cblxuICAvKiAhIFNwZWVkIG9wdGltaXNhdGlvblxuICAqIFByZTpcbiAgKiAgIG9iamVjdCBmcm9tIG51bGwgICB4IDIsNDI0LDMyMCBvcHMvc2VjIFx1MDBCMTEuNjclICg3NiBydW5zIHNhbXBsZWQpXG4gICogUG9zdDpcbiAgKiAgIG9iamVjdCBmcm9tIG51bGwgICB4IDUsODM4LDAwMCBvcHMvc2VjIFx1MDBCMTAuOTklICg4NCBydW5zIHNhbXBsZWQpXG4gICovXG4gIGlmIChvYmpQcm90b3R5cGUgPT09IG51bGwpIHtcbiAgICByZXR1cm4gJ09iamVjdCc7XG4gIH1cblxuICByZXR1cm4gT2JqZWN0XG4gICAgLnByb3RvdHlwZVxuICAgIC50b1N0cmluZ1xuICAgIC5jYWxsKG9iailcbiAgICAuc2xpY2UodG9TdHJpbmdMZWZ0U2xpY2VMZW5ndGgsIHRvU3RyaW5nUmlnaHRTbGljZUxlbmd0aCk7XG59XG5cbnJldHVybiB0eXBlRGV0ZWN0O1xuXG59KSkpO1xuIiwgIi8qIVxuICogQ2hhaSAtIGV4cGVjdFR5cGVzIHV0aWxpdHlcbiAqIENvcHlyaWdodChjKSAyMDEyLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG4vKipcbiAqICMjIyAuZXhwZWN0VHlwZXMob2JqLCB0eXBlcylcbiAqXG4gKiBFbnN1cmVzIHRoYXQgdGhlIG9iamVjdCBiZWluZyB0ZXN0ZWQgYWdhaW5zdCBpcyBvZiBhIHZhbGlkIHR5cGUuXG4gKlxuICogICAgIHV0aWxzLmV4cGVjdFR5cGVzKHRoaXMsIFsnYXJyYXknLCAnb2JqZWN0JywgJ3N0cmluZyddKTtcbiAqXG4gKiBAcGFyYW0ge01peGVkfSBvYmogY29uc3RydWN0ZWQgQXNzZXJ0aW9uXG4gKiBAcGFyYW0ge0FycmF5fSB0eXBlIEEgbGlzdCBvZiBhbGxvd2VkIHR5cGVzIGZvciB0aGlzIGFzc2VydGlvblxuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQG5hbWUgZXhwZWN0VHlwZXNcbiAqIEBhcGkgcHVibGljXG4gKi9cblxudmFyIEFzc2VydGlvbkVycm9yID0gcmVxdWlyZSgnYXNzZXJ0aW9uLWVycm9yJyk7XG52YXIgZmxhZyA9IHJlcXVpcmUoJy4vZmxhZycpO1xudmFyIHR5cGUgPSByZXF1aXJlKCd0eXBlLWRldGVjdCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGV4cGVjdFR5cGVzKG9iaiwgdHlwZXMpIHtcbiAgdmFyIGZsYWdNc2cgPSBmbGFnKG9iaiwgJ21lc3NhZ2UnKTtcbiAgdmFyIHNzZmkgPSBmbGFnKG9iaiwgJ3NzZmknKTtcblxuICBmbGFnTXNnID0gZmxhZ01zZyA/IGZsYWdNc2cgKyAnOiAnIDogJyc7XG5cbiAgb2JqID0gZmxhZyhvYmosICdvYmplY3QnKTtcbiAgdHlwZXMgPSB0eXBlcy5tYXAoZnVuY3Rpb24gKHQpIHsgcmV0dXJuIHQudG9Mb3dlckNhc2UoKTsgfSk7XG4gIHR5cGVzLnNvcnQoKTtcblxuICAvLyBUcmFuc2Zvcm1zIFsnbG9yZW0nLCAnaXBzdW0nXSBpbnRvICdhIGxvcmVtLCBvciBhbiBpcHN1bSdcbiAgdmFyIHN0ciA9IHR5cGVzLm1hcChmdW5jdGlvbiAodCwgaW5kZXgpIHtcbiAgICB2YXIgYXJ0ID0gflsgJ2EnLCAnZScsICdpJywgJ28nLCAndScgXS5pbmRleE9mKHQuY2hhckF0KDApKSA/ICdhbicgOiAnYSc7XG4gICAgdmFyIG9yID0gdHlwZXMubGVuZ3RoID4gMSAmJiBpbmRleCA9PT0gdHlwZXMubGVuZ3RoIC0gMSA/ICdvciAnIDogJyc7XG4gICAgcmV0dXJuIG9yICsgYXJ0ICsgJyAnICsgdDtcbiAgfSkuam9pbignLCAnKTtcblxuICB2YXIgb2JqVHlwZSA9IHR5cGUob2JqKS50b0xvd2VyQ2FzZSgpO1xuXG4gIGlmICghdHlwZXMuc29tZShmdW5jdGlvbiAoZXhwZWN0ZWQpIHsgcmV0dXJuIG9ialR5cGUgPT09IGV4cGVjdGVkOyB9KSkge1xuICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihcbiAgICAgIGZsYWdNc2cgKyAnb2JqZWN0IHRlc3RlZCBtdXN0IGJlICcgKyBzdHIgKyAnLCBidXQgJyArIG9ialR5cGUgKyAnIGdpdmVuJyxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHNzZmlcbiAgICApO1xuICB9XG59O1xuIiwgIi8qIVxuICogQ2hhaSAtIGdldEFjdHVhbCB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyoqXG4gKiAjIyMgLmdldEFjdHVhbChvYmplY3QsIFthY3R1YWxdKVxuICpcbiAqIFJldHVybnMgdGhlIGBhY3R1YWxgIHZhbHVlIGZvciBhbiBBc3NlcnRpb24uXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCAoY29uc3RydWN0ZWQgQXNzZXJ0aW9uKVxuICogQHBhcmFtIHtBcmd1bWVudHN9IGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZS5hc3NlcnQgYXJndW1lbnRzXG4gKiBAbmFtZXNwYWNlIFV0aWxzXG4gKiBAbmFtZSBnZXRBY3R1YWxcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGdldEFjdHVhbChvYmosIGFyZ3MpIHtcbiAgcmV0dXJuIGFyZ3MubGVuZ3RoID4gNCA/IGFyZ3NbNF0gOiBvYmouX29iajtcbn07XG4iLCAiJ3VzZSBzdHJpY3QnO1xuXG4vKiAhXG4gKiBDaGFpIC0gZ2V0RnVuY05hbWUgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNiBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbi8qKlxuICogIyMjIC5nZXRGdW5jTmFtZShjb25zdHJ1Y3RvckZuKVxuICpcbiAqIFJldHVybnMgdGhlIG5hbWUgb2YgYSBmdW5jdGlvbi5cbiAqIFdoZW4gYSBub24tZnVuY3Rpb24gaW5zdGFuY2UgaXMgcGFzc2VkLCByZXR1cm5zIGBudWxsYC5cbiAqIFRoaXMgYWxzbyBpbmNsdWRlcyBhIHBvbHlmaWxsIGZ1bmN0aW9uIGlmIGBhRnVuYy5uYW1lYCBpcyBub3QgZGVmaW5lZC5cbiAqXG4gKiBAbmFtZSBnZXRGdW5jTmFtZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuY3RcbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBhcGkgcHVibGljXG4gKi9cblxudmFyIHRvU3RyaW5nID0gRnVuY3Rpb24ucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIGZ1bmN0aW9uTmFtZU1hdGNoID0gL1xccypmdW5jdGlvbig/Olxcc3xcXHMqXFwvXFwqW14oPzoqXFwvKV0rXFwqXFwvXFxzKikqKFteXFxzXFwoXFwvXSspLztcbmZ1bmN0aW9uIGdldEZ1bmNOYW1lKGFGdW5jKSB7XG4gIGlmICh0eXBlb2YgYUZ1bmMgIT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHZhciBuYW1lID0gJyc7XG4gIGlmICh0eXBlb2YgRnVuY3Rpb24ucHJvdG90eXBlLm5hbWUgPT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBhRnVuYy5uYW1lID09PSAndW5kZWZpbmVkJykge1xuICAgIC8vIEhlcmUgd2UgcnVuIGEgcG9seWZpbGwgaWYgRnVuY3Rpb24gZG9lcyBub3Qgc3VwcG9ydCB0aGUgYG5hbWVgIHByb3BlcnR5IGFuZCBpZiBhRnVuYy5uYW1lIGlzIG5vdCBkZWZpbmVkXG4gICAgdmFyIG1hdGNoID0gdG9TdHJpbmcuY2FsbChhRnVuYykubWF0Y2goZnVuY3Rpb25OYW1lTWF0Y2gpO1xuICAgIGlmIChtYXRjaCkge1xuICAgICAgbmFtZSA9IG1hdGNoWzFdO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBJZiB3ZSd2ZSBnb3QgYSBgbmFtZWAgcHJvcGVydHkgd2UganVzdCB1c2UgaXRcbiAgICBuYW1lID0gYUZ1bmMubmFtZTtcbiAgfVxuXG4gIHJldHVybiBuYW1lO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldEZ1bmNOYW1lO1xuIiwgIihmdW5jdGlvbiAoZ2xvYmFsLCBmYWN0b3J5KSB7XG4gIHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJyA/IGZhY3RvcnkoZXhwb3J0cykgOlxuICB0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQgPyBkZWZpbmUoWydleHBvcnRzJ10sIGZhY3RvcnkpIDpcbiAgKGdsb2JhbCA9IHR5cGVvZiBnbG9iYWxUaGlzICE9PSAndW5kZWZpbmVkJyA/IGdsb2JhbFRoaXMgOiBnbG9iYWwgfHwgc2VsZiwgZmFjdG9yeShnbG9iYWwubG91cGUgPSB7fSkpO1xufSh0aGlzLCAoZnVuY3Rpb24gKGV4cG9ydHMpIHsgJ3VzZSBzdHJpY3QnO1xuXG4gIGZ1bmN0aW9uIF90eXBlb2Yob2JqKSB7XG4gICAgXCJAYmFiZWwvaGVscGVycyAtIHR5cGVvZlwiO1xuXG4gICAgaWYgKHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID09PSBcInN5bWJvbFwiKSB7XG4gICAgICBfdHlwZW9mID0gZnVuY3Rpb24gKG9iaikge1xuICAgICAgICByZXR1cm4gdHlwZW9mIG9iajtcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIF90eXBlb2YgPSBmdW5jdGlvbiAob2JqKSB7XG4gICAgICAgIHJldHVybiBvYmogJiYgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9iai5jb25zdHJ1Y3RvciA9PT0gU3ltYm9sICYmIG9iaiAhPT0gU3ltYm9sLnByb3RvdHlwZSA/IFwic3ltYm9sXCIgOiB0eXBlb2Ygb2JqO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gX3R5cGVvZihvYmopO1xuICB9XG5cbiAgZnVuY3Rpb24gX3NsaWNlZFRvQXJyYXkoYXJyLCBpKSB7XG4gICAgcmV0dXJuIF9hcnJheVdpdGhIb2xlcyhhcnIpIHx8IF9pdGVyYWJsZVRvQXJyYXlMaW1pdChhcnIsIGkpIHx8IF91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheShhcnIsIGkpIHx8IF9ub25JdGVyYWJsZVJlc3QoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIF9hcnJheVdpdGhIb2xlcyhhcnIpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShhcnIpKSByZXR1cm4gYXJyO1xuICB9XG5cbiAgZnVuY3Rpb24gX2l0ZXJhYmxlVG9BcnJheUxpbWl0KGFyciwgaSkge1xuICAgIGlmICh0eXBlb2YgU3ltYm9sID09PSBcInVuZGVmaW5lZFwiIHx8ICEoU3ltYm9sLml0ZXJhdG9yIGluIE9iamVjdChhcnIpKSkgcmV0dXJuO1xuICAgIHZhciBfYXJyID0gW107XG4gICAgdmFyIF9uID0gdHJ1ZTtcbiAgICB2YXIgX2QgPSBmYWxzZTtcbiAgICB2YXIgX2UgPSB1bmRlZmluZWQ7XG5cbiAgICB0cnkge1xuICAgICAgZm9yICh2YXIgX2kgPSBhcnJbU3ltYm9sLml0ZXJhdG9yXSgpLCBfczsgIShfbiA9IChfcyA9IF9pLm5leHQoKSkuZG9uZSk7IF9uID0gdHJ1ZSkge1xuICAgICAgICBfYXJyLnB1c2goX3MudmFsdWUpO1xuXG4gICAgICAgIGlmIChpICYmIF9hcnIubGVuZ3RoID09PSBpKSBicmVhaztcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIF9kID0gdHJ1ZTtcbiAgICAgIF9lID0gZXJyO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0cnkge1xuICAgICAgICBpZiAoIV9uICYmIF9pW1wicmV0dXJuXCJdICE9IG51bGwpIF9pW1wicmV0dXJuXCJdKCk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBpZiAoX2QpIHRocm93IF9lO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBfYXJyO1xuICB9XG5cbiAgZnVuY3Rpb24gX3Vuc3VwcG9ydGVkSXRlcmFibGVUb0FycmF5KG8sIG1pbkxlbikge1xuICAgIGlmICghbykgcmV0dXJuO1xuICAgIGlmICh0eXBlb2YgbyA9PT0gXCJzdHJpbmdcIikgcmV0dXJuIF9hcnJheUxpa2VUb0FycmF5KG8sIG1pbkxlbik7XG4gICAgdmFyIG4gPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobykuc2xpY2UoOCwgLTEpO1xuICAgIGlmIChuID09PSBcIk9iamVjdFwiICYmIG8uY29uc3RydWN0b3IpIG4gPSBvLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgaWYgKG4gPT09IFwiTWFwXCIgfHwgbiA9PT0gXCJTZXRcIikgcmV0dXJuIEFycmF5LmZyb20obyk7XG4gICAgaWYgKG4gPT09IFwiQXJndW1lbnRzXCIgfHwgL14oPzpVaXxJKW50KD86OHwxNnwzMikoPzpDbGFtcGVkKT9BcnJheSQvLnRlc3QobikpIHJldHVybiBfYXJyYXlMaWtlVG9BcnJheShvLCBtaW5MZW4pO1xuICB9XG5cbiAgZnVuY3Rpb24gX2FycmF5TGlrZVRvQXJyYXkoYXJyLCBsZW4pIHtcbiAgICBpZiAobGVuID09IG51bGwgfHwgbGVuID4gYXJyLmxlbmd0aCkgbGVuID0gYXJyLmxlbmd0aDtcblxuICAgIGZvciAodmFyIGkgPSAwLCBhcnIyID0gbmV3IEFycmF5KGxlbik7IGkgPCBsZW47IGkrKykgYXJyMltpXSA9IGFycltpXTtcblxuICAgIHJldHVybiBhcnIyO1xuICB9XG5cbiAgZnVuY3Rpb24gX25vbkl0ZXJhYmxlUmVzdCgpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBhdHRlbXB0IHRvIGRlc3RydWN0dXJlIG5vbi1pdGVyYWJsZSBpbnN0YW5jZS5cXG5JbiBvcmRlciB0byBiZSBpdGVyYWJsZSwgbm9uLWFycmF5IG9iamVjdHMgbXVzdCBoYXZlIGEgW1N5bWJvbC5pdGVyYXRvcl0oKSBtZXRob2QuXCIpO1xuICB9XG5cbiAgdmFyIGFuc2lDb2xvcnMgPSB7XG4gICAgYm9sZDogWycxJywgJzIyJ10sXG4gICAgZGltOiBbJzInLCAnMjInXSxcbiAgICBpdGFsaWM6IFsnMycsICcyMyddLFxuICAgIHVuZGVybGluZTogWyc0JywgJzI0J10sXG4gICAgLy8gNSAmIDYgYXJlIGJsaW5raW5nXG4gICAgaW52ZXJzZTogWyc3JywgJzI3J10sXG4gICAgaGlkZGVuOiBbJzgnLCAnMjgnXSxcbiAgICBzdHJpa2U6IFsnOScsICcyOSddLFxuICAgIC8vIDEwLTIwIGFyZSBmb250c1xuICAgIC8vIDIxLTI5IGFyZSByZXNldHMgZm9yIDEtOVxuICAgIGJsYWNrOiBbJzMwJywgJzM5J10sXG4gICAgcmVkOiBbJzMxJywgJzM5J10sXG4gICAgZ3JlZW46IFsnMzInLCAnMzknXSxcbiAgICB5ZWxsb3c6IFsnMzMnLCAnMzknXSxcbiAgICBibHVlOiBbJzM0JywgJzM5J10sXG4gICAgbWFnZW50YTogWyczNScsICczOSddLFxuICAgIGN5YW46IFsnMzYnLCAnMzknXSxcbiAgICB3aGl0ZTogWyczNycsICczOSddLFxuICAgIGJyaWdodGJsYWNrOiBbJzMwOzEnLCAnMzknXSxcbiAgICBicmlnaHRyZWQ6IFsnMzE7MScsICczOSddLFxuICAgIGJyaWdodGdyZWVuOiBbJzMyOzEnLCAnMzknXSxcbiAgICBicmlnaHR5ZWxsb3c6IFsnMzM7MScsICczOSddLFxuICAgIGJyaWdodGJsdWU6IFsnMzQ7MScsICczOSddLFxuICAgIGJyaWdodG1hZ2VudGE6IFsnMzU7MScsICczOSddLFxuICAgIGJyaWdodGN5YW46IFsnMzY7MScsICczOSddLFxuICAgIGJyaWdodHdoaXRlOiBbJzM3OzEnLCAnMzknXSxcbiAgICBncmV5OiBbJzkwJywgJzM5J11cbiAgfTtcbiAgdmFyIHN0eWxlcyA9IHtcbiAgICBzcGVjaWFsOiAnY3lhbicsXG4gICAgbnVtYmVyOiAneWVsbG93JyxcbiAgICBiaWdpbnQ6ICd5ZWxsb3cnLFxuICAgIGJvb2xlYW46ICd5ZWxsb3cnLFxuICAgIHVuZGVmaW5lZDogJ2dyZXknLFxuICAgIG51bGw6ICdib2xkJyxcbiAgICBzdHJpbmc6ICdncmVlbicsXG4gICAgc3ltYm9sOiAnZ3JlZW4nLFxuICAgIGRhdGU6ICdtYWdlbnRhJyxcbiAgICByZWdleHA6ICdyZWQnXG4gIH07XG4gIHZhciB0cnVuY2F0b3IgPSAnXHUyMDI2JztcblxuICBmdW5jdGlvbiBjb2xvcmlzZSh2YWx1ZSwgc3R5bGVUeXBlKSB7XG4gICAgdmFyIGNvbG9yID0gYW5zaUNvbG9yc1tzdHlsZXNbc3R5bGVUeXBlXV0gfHwgYW5zaUNvbG9yc1tzdHlsZVR5cGVdO1xuXG4gICAgaWYgKCFjb2xvcikge1xuICAgICAgcmV0dXJuIFN0cmluZyh2YWx1ZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIFwiXFx4MUJbXCIuY29uY2F0KGNvbG9yWzBdLCBcIm1cIikuY29uY2F0KFN0cmluZyh2YWx1ZSksIFwiXFx4MUJbXCIpLmNvbmNhdChjb2xvclsxXSwgXCJtXCIpO1xuICB9XG5cbiAgZnVuY3Rpb24gbm9ybWFsaXNlT3B0aW9ucygpIHtcbiAgICB2YXIgX3JlZiA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDoge30sXG4gICAgICAgIF9yZWYkc2hvd0hpZGRlbiA9IF9yZWYuc2hvd0hpZGRlbixcbiAgICAgICAgc2hvd0hpZGRlbiA9IF9yZWYkc2hvd0hpZGRlbiA9PT0gdm9pZCAwID8gZmFsc2UgOiBfcmVmJHNob3dIaWRkZW4sXG4gICAgICAgIF9yZWYkZGVwdGggPSBfcmVmLmRlcHRoLFxuICAgICAgICBkZXB0aCA9IF9yZWYkZGVwdGggPT09IHZvaWQgMCA/IDIgOiBfcmVmJGRlcHRoLFxuICAgICAgICBfcmVmJGNvbG9ycyA9IF9yZWYuY29sb3JzLFxuICAgICAgICBjb2xvcnMgPSBfcmVmJGNvbG9ycyA9PT0gdm9pZCAwID8gZmFsc2UgOiBfcmVmJGNvbG9ycyxcbiAgICAgICAgX3JlZiRjdXN0b21JbnNwZWN0ID0gX3JlZi5jdXN0b21JbnNwZWN0LFxuICAgICAgICBjdXN0b21JbnNwZWN0ID0gX3JlZiRjdXN0b21JbnNwZWN0ID09PSB2b2lkIDAgPyB0cnVlIDogX3JlZiRjdXN0b21JbnNwZWN0LFxuICAgICAgICBfcmVmJHNob3dQcm94eSA9IF9yZWYuc2hvd1Byb3h5LFxuICAgICAgICBzaG93UHJveHkgPSBfcmVmJHNob3dQcm94eSA9PT0gdm9pZCAwID8gZmFsc2UgOiBfcmVmJHNob3dQcm94eSxcbiAgICAgICAgX3JlZiRtYXhBcnJheUxlbmd0aCA9IF9yZWYubWF4QXJyYXlMZW5ndGgsXG4gICAgICAgIG1heEFycmF5TGVuZ3RoID0gX3JlZiRtYXhBcnJheUxlbmd0aCA9PT0gdm9pZCAwID8gSW5maW5pdHkgOiBfcmVmJG1heEFycmF5TGVuZ3RoLFxuICAgICAgICBfcmVmJGJyZWFrTGVuZ3RoID0gX3JlZi5icmVha0xlbmd0aCxcbiAgICAgICAgYnJlYWtMZW5ndGggPSBfcmVmJGJyZWFrTGVuZ3RoID09PSB2b2lkIDAgPyBJbmZpbml0eSA6IF9yZWYkYnJlYWtMZW5ndGgsXG4gICAgICAgIF9yZWYkc2VlbiA9IF9yZWYuc2VlbixcbiAgICAgICAgc2VlbiA9IF9yZWYkc2VlbiA9PT0gdm9pZCAwID8gW10gOiBfcmVmJHNlZW4sXG4gICAgICAgIF9yZWYkdHJ1bmNhdGUgPSBfcmVmLnRydW5jYXRlLFxuICAgICAgICB0cnVuY2F0ZSA9IF9yZWYkdHJ1bmNhdGUgPT09IHZvaWQgMCA/IEluZmluaXR5IDogX3JlZiR0cnVuY2F0ZSxcbiAgICAgICAgX3JlZiRzdHlsaXplID0gX3JlZi5zdHlsaXplLFxuICAgICAgICBzdHlsaXplID0gX3JlZiRzdHlsaXplID09PSB2b2lkIDAgPyBTdHJpbmcgOiBfcmVmJHN0eWxpemU7XG5cbiAgICB2YXIgb3B0aW9ucyA9IHtcbiAgICAgIHNob3dIaWRkZW46IEJvb2xlYW4oc2hvd0hpZGRlbiksXG4gICAgICBkZXB0aDogTnVtYmVyKGRlcHRoKSxcbiAgICAgIGNvbG9yczogQm9vbGVhbihjb2xvcnMpLFxuICAgICAgY3VzdG9tSW5zcGVjdDogQm9vbGVhbihjdXN0b21JbnNwZWN0KSxcbiAgICAgIHNob3dQcm94eTogQm9vbGVhbihzaG93UHJveHkpLFxuICAgICAgbWF4QXJyYXlMZW5ndGg6IE51bWJlcihtYXhBcnJheUxlbmd0aCksXG4gICAgICBicmVha0xlbmd0aDogTnVtYmVyKGJyZWFrTGVuZ3RoKSxcbiAgICAgIHRydW5jYXRlOiBOdW1iZXIodHJ1bmNhdGUpLFxuICAgICAgc2Vlbjogc2VlbixcbiAgICAgIHN0eWxpemU6IHN0eWxpemVcbiAgICB9O1xuXG4gICAgaWYgKG9wdGlvbnMuY29sb3JzKSB7XG4gICAgICBvcHRpb25zLnN0eWxpemUgPSBjb2xvcmlzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3B0aW9ucztcbiAgfVxuICBmdW5jdGlvbiB0cnVuY2F0ZShzdHJpbmcsIGxlbmd0aCkge1xuICAgIHZhciB0YWlsID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiB0cnVuY2F0b3I7XG4gICAgc3RyaW5nID0gU3RyaW5nKHN0cmluZyk7XG4gICAgdmFyIHRhaWxMZW5ndGggPSB0YWlsLmxlbmd0aDtcbiAgICB2YXIgc3RyaW5nTGVuZ3RoID0gc3RyaW5nLmxlbmd0aDtcblxuICAgIGlmICh0YWlsTGVuZ3RoID4gbGVuZ3RoICYmIHN0cmluZ0xlbmd0aCA+IHRhaWxMZW5ndGgpIHtcbiAgICAgIHJldHVybiB0YWlsO1xuICAgIH1cblxuICAgIGlmIChzdHJpbmdMZW5ndGggPiBsZW5ndGggJiYgc3RyaW5nTGVuZ3RoID4gdGFpbExlbmd0aCkge1xuICAgICAgcmV0dXJuIFwiXCIuY29uY2F0KHN0cmluZy5zbGljZSgwLCBsZW5ndGggLSB0YWlsTGVuZ3RoKSkuY29uY2F0KHRhaWwpO1xuICAgIH1cblxuICAgIHJldHVybiBzdHJpbmc7XG4gIH0gLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNvbXBsZXhpdHlcblxuICBmdW5jdGlvbiBpbnNwZWN0TGlzdChsaXN0LCBvcHRpb25zLCBpbnNwZWN0SXRlbSkge1xuICAgIHZhciBzZXBhcmF0b3IgPSBhcmd1bWVudHMubGVuZ3RoID4gMyAmJiBhcmd1bWVudHNbM10gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1szXSA6ICcsICc7XG4gICAgaW5zcGVjdEl0ZW0gPSBpbnNwZWN0SXRlbSB8fCBvcHRpb25zLmluc3BlY3Q7XG4gICAgdmFyIHNpemUgPSBsaXN0Lmxlbmd0aDtcbiAgICBpZiAoc2l6ZSA9PT0gMCkgcmV0dXJuICcnO1xuICAgIHZhciBvcmlnaW5hbExlbmd0aCA9IG9wdGlvbnMudHJ1bmNhdGU7XG4gICAgdmFyIG91dHB1dCA9ICcnO1xuICAgIHZhciBwZWVrID0gJyc7XG4gICAgdmFyIHRydW5jYXRlZCA9ICcnO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzaXplOyBpICs9IDEpIHtcbiAgICAgIHZhciBsYXN0ID0gaSArIDEgPT09IGxpc3QubGVuZ3RoO1xuICAgICAgdmFyIHNlY29uZFRvTGFzdCA9IGkgKyAyID09PSBsaXN0Lmxlbmd0aDtcbiAgICAgIHRydW5jYXRlZCA9IFwiXCIuY29uY2F0KHRydW5jYXRvciwgXCIoXCIpLmNvbmNhdChsaXN0Lmxlbmd0aCAtIGksIFwiKVwiKTtcbiAgICAgIHZhciB2YWx1ZSA9IGxpc3RbaV07IC8vIElmIHRoZXJlIGlzIG1vcmUgdGhhbiBvbmUgcmVtYWluaW5nIHdlIG5lZWQgdG8gYWNjb3VudCBmb3IgYSBzZXBhcmF0b3Igb2YgYCwgYFxuXG4gICAgICBvcHRpb25zLnRydW5jYXRlID0gb3JpZ2luYWxMZW5ndGggLSBvdXRwdXQubGVuZ3RoIC0gKGxhc3QgPyAwIDogc2VwYXJhdG9yLmxlbmd0aCk7XG4gICAgICB2YXIgc3RyaW5nID0gcGVlayB8fCBpbnNwZWN0SXRlbSh2YWx1ZSwgb3B0aW9ucykgKyAobGFzdCA/ICcnIDogc2VwYXJhdG9yKTtcbiAgICAgIHZhciBuZXh0TGVuZ3RoID0gb3V0cHV0Lmxlbmd0aCArIHN0cmluZy5sZW5ndGg7XG4gICAgICB2YXIgdHJ1bmNhdGVkTGVuZ3RoID0gbmV4dExlbmd0aCArIHRydW5jYXRlZC5sZW5ndGg7IC8vIElmIHRoaXMgaXMgdGhlIGxhc3QgZWxlbWVudCwgYW5kIGFkZGluZyBpdCB3b3VsZFxuICAgICAgLy8gdGFrZSB1cyBvdmVyIGxlbmd0aCwgYnV0IGFkZGluZyB0aGUgdHJ1bmNhdG9yIHdvdWxkbid0IC0gdGhlbiBicmVhayBub3dcblxuICAgICAgaWYgKGxhc3QgJiYgbmV4dExlbmd0aCA+IG9yaWdpbmFsTGVuZ3RoICYmIG91dHB1dC5sZW5ndGggKyB0cnVuY2F0ZWQubGVuZ3RoIDw9IG9yaWdpbmFsTGVuZ3RoKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfSAvLyBJZiB0aGlzIGlzbid0IHRoZSBsYXN0IG9yIHNlY29uZCB0byBsYXN0IGVsZW1lbnQgdG8gc2NhbixcbiAgICAgIC8vIGJ1dCB0aGUgc3RyaW5nIGlzIGFscmVhZHkgb3ZlciBsZW5ndGggdGhlbiBicmVhayBoZXJlXG5cblxuICAgICAgaWYgKCFsYXN0ICYmICFzZWNvbmRUb0xhc3QgJiYgdHJ1bmNhdGVkTGVuZ3RoID4gb3JpZ2luYWxMZW5ndGgpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9IC8vIFBlZWsgYXQgdGhlIG5leHQgc3RyaW5nIHRvIGRldGVybWluZSBpZiB3ZSBzaG91bGRcbiAgICAgIC8vIGJyZWFrIGVhcmx5IGJlZm9yZSBhZGRpbmcgdGhpcyBpdGVtIHRvIHRoZSBvdXRwdXRcblxuXG4gICAgICBwZWVrID0gbGFzdCA/ICcnIDogaW5zcGVjdEl0ZW0obGlzdFtpICsgMV0sIG9wdGlvbnMpICsgKHNlY29uZFRvTGFzdCA/ICcnIDogc2VwYXJhdG9yKTsgLy8gSWYgd2UgaGF2ZSBvbmUgZWxlbWVudCBsZWZ0LCBidXQgdGhpcyBlbGVtZW50IGFuZFxuICAgICAgLy8gdGhlIG5leHQgdGFrZXMgb3ZlciBsZW5ndGgsIHRoZSBicmVhayBlYXJseVxuXG4gICAgICBpZiAoIWxhc3QgJiYgc2Vjb25kVG9MYXN0ICYmIHRydW5jYXRlZExlbmd0aCA+IG9yaWdpbmFsTGVuZ3RoICYmIG5leHRMZW5ndGggKyBwZWVrLmxlbmd0aCA+IG9yaWdpbmFsTGVuZ3RoKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBvdXRwdXQgKz0gc3RyaW5nOyAvLyBJZiB0aGUgbmV4dCBlbGVtZW50IHRha2VzIHVzIHRvIGxlbmd0aCAtXG4gICAgICAvLyBidXQgdGhlcmUgYXJlIG1vcmUgYWZ0ZXIgdGhhdCwgdGhlbiB3ZSBzaG91bGQgdHJ1bmNhdGUgbm93XG5cbiAgICAgIGlmICghbGFzdCAmJiAhc2Vjb25kVG9MYXN0ICYmIG5leHRMZW5ndGggKyBwZWVrLmxlbmd0aCA+PSBvcmlnaW5hbExlbmd0aCkge1xuICAgICAgICB0cnVuY2F0ZWQgPSBcIlwiLmNvbmNhdCh0cnVuY2F0b3IsIFwiKFwiKS5jb25jYXQobGlzdC5sZW5ndGggLSBpIC0gMSwgXCIpXCIpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgdHJ1bmNhdGVkID0gJyc7XG4gICAgfVxuXG4gICAgcmV0dXJuIFwiXCIuY29uY2F0KG91dHB1dCkuY29uY2F0KHRydW5jYXRlZCk7XG4gIH1cblxuICBmdW5jdGlvbiBxdW90ZUNvbXBsZXhLZXkoa2V5KSB7XG4gICAgaWYgKGtleS5tYXRjaCgvXlthLXpBLVpfXVthLXpBLVpfMC05XSokLykpIHtcbiAgICAgIHJldHVybiBrZXk7XG4gICAgfVxuXG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGtleSkucmVwbGFjZSgvJy9nLCBcIlxcXFwnXCIpLnJlcGxhY2UoL1xcXFxcIi9nLCAnXCInKS5yZXBsYWNlKC8oXlwifFwiJCkvZywgXCInXCIpO1xuICB9XG5cbiAgZnVuY3Rpb24gaW5zcGVjdFByb3BlcnR5KF9yZWYyLCBvcHRpb25zKSB7XG4gICAgdmFyIF9yZWYzID0gX3NsaWNlZFRvQXJyYXkoX3JlZjIsIDIpLFxuICAgICAgICBrZXkgPSBfcmVmM1swXSxcbiAgICAgICAgdmFsdWUgPSBfcmVmM1sxXTtcblxuICAgIG9wdGlvbnMudHJ1bmNhdGUgLT0gMjtcblxuICAgIGlmICh0eXBlb2Yga2V5ID09PSAnc3RyaW5nJykge1xuICAgICAga2V5ID0gcXVvdGVDb21wbGV4S2V5KGtleSk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2Yga2V5ICE9PSAnbnVtYmVyJykge1xuICAgICAga2V5ID0gXCJbXCIuY29uY2F0KG9wdGlvbnMuaW5zcGVjdChrZXksIG9wdGlvbnMpLCBcIl1cIik7XG4gICAgfVxuXG4gICAgb3B0aW9ucy50cnVuY2F0ZSAtPSBrZXkubGVuZ3RoO1xuICAgIHZhbHVlID0gb3B0aW9ucy5pbnNwZWN0KHZhbHVlLCBvcHRpb25zKTtcbiAgICByZXR1cm4gXCJcIi5jb25jYXQoa2V5LCBcIjogXCIpLmNvbmNhdCh2YWx1ZSk7XG4gIH1cblxuICBmdW5jdGlvbiBpbnNwZWN0QXJyYXkoYXJyYXksIG9wdGlvbnMpIHtcbiAgICAvLyBPYmplY3Qua2V5cyB3aWxsIGFsd2F5cyBvdXRwdXQgdGhlIEFycmF5IGluZGljZXMgZmlyc3QsIHNvIHdlIGNhbiBzbGljZSBieVxuICAgIC8vIGBhcnJheS5sZW5ndGhgIHRvIGdldCBub24taW5kZXggcHJvcGVydGllc1xuICAgIHZhciBub25JbmRleFByb3BlcnRpZXMgPSBPYmplY3Qua2V5cyhhcnJheSkuc2xpY2UoYXJyYXkubGVuZ3RoKTtcbiAgICBpZiAoIWFycmF5Lmxlbmd0aCAmJiAhbm9uSW5kZXhQcm9wZXJ0aWVzLmxlbmd0aCkgcmV0dXJuICdbXSc7XG4gICAgb3B0aW9ucy50cnVuY2F0ZSAtPSA0O1xuICAgIHZhciBsaXN0Q29udGVudHMgPSBpbnNwZWN0TGlzdChhcnJheSwgb3B0aW9ucyk7XG4gICAgb3B0aW9ucy50cnVuY2F0ZSAtPSBsaXN0Q29udGVudHMubGVuZ3RoO1xuICAgIHZhciBwcm9wZXJ0eUNvbnRlbnRzID0gJyc7XG5cbiAgICBpZiAobm9uSW5kZXhQcm9wZXJ0aWVzLmxlbmd0aCkge1xuICAgICAgcHJvcGVydHlDb250ZW50cyA9IGluc3BlY3RMaXN0KG5vbkluZGV4UHJvcGVydGllcy5tYXAoZnVuY3Rpb24gKGtleSkge1xuICAgICAgICByZXR1cm4gW2tleSwgYXJyYXlba2V5XV07XG4gICAgICB9KSwgb3B0aW9ucywgaW5zcGVjdFByb3BlcnR5KTtcbiAgICB9XG5cbiAgICByZXR1cm4gXCJbIFwiLmNvbmNhdChsaXN0Q29udGVudHMpLmNvbmNhdChwcm9wZXJ0eUNvbnRlbnRzID8gXCIsIFwiLmNvbmNhdChwcm9wZXJ0eUNvbnRlbnRzKSA6ICcnLCBcIiBdXCIpO1xuICB9XG5cbiAgLyogIVxuICAgKiBDaGFpIC0gZ2V0RnVuY05hbWUgdXRpbGl0eVxuICAgKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE2IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICAgKiBNSVQgTGljZW5zZWRcbiAgICovXG5cbiAgLyoqXG4gICAqICMjIyAuZ2V0RnVuY05hbWUoY29uc3RydWN0b3JGbilcbiAgICpcbiAgICogUmV0dXJucyB0aGUgbmFtZSBvZiBhIGZ1bmN0aW9uLlxuICAgKiBXaGVuIGEgbm9uLWZ1bmN0aW9uIGluc3RhbmNlIGlzIHBhc3NlZCwgcmV0dXJucyBgbnVsbGAuXG4gICAqIFRoaXMgYWxzbyBpbmNsdWRlcyBhIHBvbHlmaWxsIGZ1bmN0aW9uIGlmIGBhRnVuYy5uYW1lYCBpcyBub3QgZGVmaW5lZC5cbiAgICpcbiAgICogQG5hbWUgZ2V0RnVuY05hbWVcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuY3RcbiAgICogQG5hbWVzcGFjZSBVdGlsc1xuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICB2YXIgdG9TdHJpbmcgPSBGdW5jdGlvbi5wcm90b3R5cGUudG9TdHJpbmc7XG4gIHZhciBmdW5jdGlvbk5hbWVNYXRjaCA9IC9cXHMqZnVuY3Rpb24oPzpcXHN8XFxzKlxcL1xcKlteKD86KlxcLyldK1xcKlxcL1xccyopKihbXlxcc1xcKFxcL10rKS87XG4gIGZ1bmN0aW9uIGdldEZ1bmNOYW1lKGFGdW5jKSB7XG4gICAgaWYgKHR5cGVvZiBhRnVuYyAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgdmFyIG5hbWUgPSAnJztcbiAgICBpZiAodHlwZW9mIEZ1bmN0aW9uLnByb3RvdHlwZS5uYW1lID09PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgYUZ1bmMubmFtZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIC8vIEhlcmUgd2UgcnVuIGEgcG9seWZpbGwgaWYgRnVuY3Rpb24gZG9lcyBub3Qgc3VwcG9ydCB0aGUgYG5hbWVgIHByb3BlcnR5IGFuZCBpZiBhRnVuYy5uYW1lIGlzIG5vdCBkZWZpbmVkXG4gICAgICB2YXIgbWF0Y2ggPSB0b1N0cmluZy5jYWxsKGFGdW5jKS5tYXRjaChmdW5jdGlvbk5hbWVNYXRjaCk7XG4gICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgbmFtZSA9IG1hdGNoWzFdO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBJZiB3ZSd2ZSBnb3QgYSBgbmFtZWAgcHJvcGVydHkgd2UganVzdCB1c2UgaXRcbiAgICAgIG5hbWUgPSBhRnVuYy5uYW1lO1xuICAgIH1cblxuICAgIHJldHVybiBuYW1lO1xuICB9XG5cbiAgdmFyIGdldEZ1bmNOYW1lXzEgPSBnZXRGdW5jTmFtZTtcblxuICB2YXIgZ2V0QXJyYXlOYW1lID0gZnVuY3Rpb24gZ2V0QXJyYXlOYW1lKGFycmF5KSB7XG4gICAgLy8gV2UgbmVlZCB0byBzcGVjaWFsIGNhc2UgTm9kZS5qcycgQnVmZmVycywgd2hpY2ggcmVwb3J0IHRvIGJlIFVpbnQ4QXJyYXlcbiAgICBpZiAodHlwZW9mIEJ1ZmZlciA9PT0gJ2Z1bmN0aW9uJyAmJiBhcnJheSBpbnN0YW5jZW9mIEJ1ZmZlcikge1xuICAgICAgcmV0dXJuICdCdWZmZXInO1xuICAgIH1cblxuICAgIGlmIChhcnJheVtTeW1ib2wudG9TdHJpbmdUYWddKSB7XG4gICAgICByZXR1cm4gYXJyYXlbU3ltYm9sLnRvU3RyaW5nVGFnXTtcbiAgICB9XG5cbiAgICByZXR1cm4gZ2V0RnVuY05hbWVfMShhcnJheS5jb25zdHJ1Y3Rvcik7XG4gIH07XG5cbiAgZnVuY3Rpb24gaW5zcGVjdFR5cGVkQXJyYXkoYXJyYXksIG9wdGlvbnMpIHtcbiAgICB2YXIgbmFtZSA9IGdldEFycmF5TmFtZShhcnJheSk7XG4gICAgb3B0aW9ucy50cnVuY2F0ZSAtPSBuYW1lLmxlbmd0aCArIDQ7IC8vIE9iamVjdC5rZXlzIHdpbGwgYWx3YXlzIG91dHB1dCB0aGUgQXJyYXkgaW5kaWNlcyBmaXJzdCwgc28gd2UgY2FuIHNsaWNlIGJ5XG4gICAgLy8gYGFycmF5Lmxlbmd0aGAgdG8gZ2V0IG5vbi1pbmRleCBwcm9wZXJ0aWVzXG5cbiAgICB2YXIgbm9uSW5kZXhQcm9wZXJ0aWVzID0gT2JqZWN0LmtleXMoYXJyYXkpLnNsaWNlKGFycmF5Lmxlbmd0aCk7XG4gICAgaWYgKCFhcnJheS5sZW5ndGggJiYgIW5vbkluZGV4UHJvcGVydGllcy5sZW5ndGgpIHJldHVybiBcIlwiLmNvbmNhdChuYW1lLCBcIltdXCIpOyAvLyBBcyB3ZSBrbm93IFR5cGVkQXJyYXlzIG9ubHkgY29udGFpbiBVbnNpZ25lZCBJbnRlZ2Vycywgd2UgY2FuIHNraXAgaW5zcGVjdGluZyBlYWNoIG9uZSBhbmQgc2ltcGx5XG4gICAgLy8gc3R5bGlzZSB0aGUgdG9TdHJpbmcoKSB2YWx1ZSBvZiB0aGVtXG5cbiAgICB2YXIgb3V0cHV0ID0gJyc7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgc3RyaW5nID0gXCJcIi5jb25jYXQob3B0aW9ucy5zdHlsaXplKHRydW5jYXRlKGFycmF5W2ldLCBvcHRpb25zLnRydW5jYXRlKSwgJ251bWJlcicpKS5jb25jYXQoaSA9PT0gYXJyYXkubGVuZ3RoIC0gMSA/ICcnIDogJywgJyk7XG4gICAgICBvcHRpb25zLnRydW5jYXRlIC09IHN0cmluZy5sZW5ndGg7XG5cbiAgICAgIGlmIChhcnJheVtpXSAhPT0gYXJyYXkubGVuZ3RoICYmIG9wdGlvbnMudHJ1bmNhdGUgPD0gMykge1xuICAgICAgICBvdXRwdXQgKz0gXCJcIi5jb25jYXQodHJ1bmNhdG9yLCBcIihcIikuY29uY2F0KGFycmF5Lmxlbmd0aCAtIGFycmF5W2ldICsgMSwgXCIpXCIpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgb3V0cHV0ICs9IHN0cmluZztcbiAgICB9XG5cbiAgICB2YXIgcHJvcGVydHlDb250ZW50cyA9ICcnO1xuXG4gICAgaWYgKG5vbkluZGV4UHJvcGVydGllcy5sZW5ndGgpIHtcbiAgICAgIHByb3BlcnR5Q29udGVudHMgPSBpbnNwZWN0TGlzdChub25JbmRleFByb3BlcnRpZXMubWFwKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgcmV0dXJuIFtrZXksIGFycmF5W2tleV1dO1xuICAgICAgfSksIG9wdGlvbnMsIGluc3BlY3RQcm9wZXJ0eSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIFwiXCIuY29uY2F0KG5hbWUsIFwiWyBcIikuY29uY2F0KG91dHB1dCkuY29uY2F0KHByb3BlcnR5Q29udGVudHMgPyBcIiwgXCIuY29uY2F0KHByb3BlcnR5Q29udGVudHMpIDogJycsIFwiIF1cIik7XG4gIH1cblxuICBmdW5jdGlvbiBpbnNwZWN0RGF0ZShkYXRlT2JqZWN0LCBvcHRpb25zKSB7XG4gICAgdmFyIHN0cmluZ1JlcHJlc2VudGF0aW9uID0gZGF0ZU9iamVjdC50b0pTT04oKTtcblxuICAgIGlmIChzdHJpbmdSZXByZXNlbnRhdGlvbiA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuICdJbnZhbGlkIERhdGUnO1xuICAgIH1cblxuICAgIHZhciBzcGxpdCA9IHN0cmluZ1JlcHJlc2VudGF0aW9uLnNwbGl0KCdUJyk7XG4gICAgdmFyIGRhdGUgPSBzcGxpdFswXTsgLy8gSWYgd2UgbmVlZCB0byAtIHRydW5jYXRlIHRoZSB0aW1lIHBvcnRpb24sIGJ1dCBuZXZlciB0aGUgZGF0ZVxuXG4gICAgcmV0dXJuIG9wdGlvbnMuc3R5bGl6ZShcIlwiLmNvbmNhdChkYXRlLCBcIlRcIikuY29uY2F0KHRydW5jYXRlKHNwbGl0WzFdLCBvcHRpb25zLnRydW5jYXRlIC0gZGF0ZS5sZW5ndGggLSAxKSksICdkYXRlJyk7XG4gIH1cblxuICBmdW5jdGlvbiBpbnNwZWN0RnVuY3Rpb24oZnVuYywgb3B0aW9ucykge1xuICAgIHZhciBuYW1lID0gZ2V0RnVuY05hbWVfMShmdW5jKTtcblxuICAgIGlmICghbmFtZSkge1xuICAgICAgcmV0dXJuIG9wdGlvbnMuc3R5bGl6ZSgnW0Z1bmN0aW9uXScsICdzcGVjaWFsJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG9wdGlvbnMuc3R5bGl6ZShcIltGdW5jdGlvbiBcIi5jb25jYXQodHJ1bmNhdGUobmFtZSwgb3B0aW9ucy50cnVuY2F0ZSAtIDExKSwgXCJdXCIpLCAnc3BlY2lhbCcpO1xuICB9XG5cbiAgZnVuY3Rpb24gaW5zcGVjdE1hcEVudHJ5KF9yZWYsIG9wdGlvbnMpIHtcbiAgICB2YXIgX3JlZjIgPSBfc2xpY2VkVG9BcnJheShfcmVmLCAyKSxcbiAgICAgICAga2V5ID0gX3JlZjJbMF0sXG4gICAgICAgIHZhbHVlID0gX3JlZjJbMV07XG5cbiAgICBvcHRpb25zLnRydW5jYXRlIC09IDQ7XG4gICAga2V5ID0gb3B0aW9ucy5pbnNwZWN0KGtleSwgb3B0aW9ucyk7XG4gICAgb3B0aW9ucy50cnVuY2F0ZSAtPSBrZXkubGVuZ3RoO1xuICAgIHZhbHVlID0gb3B0aW9ucy5pbnNwZWN0KHZhbHVlLCBvcHRpb25zKTtcbiAgICByZXR1cm4gXCJcIi5jb25jYXQoa2V5LCBcIiA9PiBcIikuY29uY2F0KHZhbHVlKTtcbiAgfSAvLyBJRTExIGRvZXNuJ3Qgc3VwcG9ydCBgbWFwLmVudHJpZXMoKWBcblxuXG4gIGZ1bmN0aW9uIG1hcFRvRW50cmllcyhtYXApIHtcbiAgICB2YXIgZW50cmllcyA9IFtdO1xuICAgIG1hcC5mb3JFYWNoKGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG4gICAgICBlbnRyaWVzLnB1c2goW2tleSwgdmFsdWVdKTtcbiAgICB9KTtcbiAgICByZXR1cm4gZW50cmllcztcbiAgfVxuXG4gIGZ1bmN0aW9uIGluc3BlY3RNYXAobWFwLCBvcHRpb25zKSB7XG4gICAgdmFyIHNpemUgPSBtYXAuc2l6ZSAtIDE7XG5cbiAgICBpZiAoc2l6ZSA8PSAwKSB7XG4gICAgICByZXR1cm4gJ01hcHt9JztcbiAgICB9XG5cbiAgICBvcHRpb25zLnRydW5jYXRlIC09IDc7XG4gICAgcmV0dXJuIFwiTWFweyBcIi5jb25jYXQoaW5zcGVjdExpc3QobWFwVG9FbnRyaWVzKG1hcCksIG9wdGlvbnMsIGluc3BlY3RNYXBFbnRyeSksIFwiIH1cIik7XG4gIH1cblxuICB2YXIgaXNOYU4gPSBOdW1iZXIuaXNOYU4gfHwgZnVuY3Rpb24gKGkpIHtcbiAgICByZXR1cm4gaSAhPT0gaTtcbiAgfTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1zZWxmLWNvbXBhcmVcblxuXG4gIGZ1bmN0aW9uIGluc3BlY3ROdW1iZXIobnVtYmVyLCBvcHRpb25zKSB7XG4gICAgaWYgKGlzTmFOKG51bWJlcikpIHtcbiAgICAgIHJldHVybiBvcHRpb25zLnN0eWxpemUoJ05hTicsICdudW1iZXInKTtcbiAgICB9XG5cbiAgICBpZiAobnVtYmVyID09PSBJbmZpbml0eSkge1xuICAgICAgcmV0dXJuIG9wdGlvbnMuc3R5bGl6ZSgnSW5maW5pdHknLCAnbnVtYmVyJyk7XG4gICAgfVxuXG4gICAgaWYgKG51bWJlciA9PT0gLUluZmluaXR5KSB7XG4gICAgICByZXR1cm4gb3B0aW9ucy5zdHlsaXplKCctSW5maW5pdHknLCAnbnVtYmVyJyk7XG4gICAgfVxuXG4gICAgaWYgKG51bWJlciA9PT0gMCkge1xuICAgICAgcmV0dXJuIG9wdGlvbnMuc3R5bGl6ZSgxIC8gbnVtYmVyID09PSBJbmZpbml0eSA/ICcrMCcgOiAnLTAnLCAnbnVtYmVyJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG9wdGlvbnMuc3R5bGl6ZSh0cnVuY2F0ZShudW1iZXIsIG9wdGlvbnMudHJ1bmNhdGUpLCAnbnVtYmVyJyk7XG4gIH1cblxuICBmdW5jdGlvbiBpbnNwZWN0QmlnSW50KG51bWJlciwgb3B0aW9ucykge1xuICAgIHZhciBudW1zID0gdHJ1bmNhdGUobnVtYmVyLnRvU3RyaW5nKCksIG9wdGlvbnMudHJ1bmNhdGUgLSAxKTtcbiAgICBpZiAobnVtcyAhPT0gdHJ1bmNhdG9yKSBudW1zICs9ICduJztcbiAgICByZXR1cm4gb3B0aW9ucy5zdHlsaXplKG51bXMsICdiaWdpbnQnKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGluc3BlY3RSZWdFeHAodmFsdWUsIG9wdGlvbnMpIHtcbiAgICB2YXIgZmxhZ3MgPSB2YWx1ZS50b1N0cmluZygpLnNwbGl0KCcvJylbMl07XG4gICAgdmFyIHNvdXJjZUxlbmd0aCA9IG9wdGlvbnMudHJ1bmNhdGUgLSAoMiArIGZsYWdzLmxlbmd0aCk7XG4gICAgdmFyIHNvdXJjZSA9IHZhbHVlLnNvdXJjZTtcbiAgICByZXR1cm4gb3B0aW9ucy5zdHlsaXplKFwiL1wiLmNvbmNhdCh0cnVuY2F0ZShzb3VyY2UsIHNvdXJjZUxlbmd0aCksIFwiL1wiKS5jb25jYXQoZmxhZ3MpLCAncmVnZXhwJyk7XG4gIH1cblxuICBmdW5jdGlvbiBhcnJheUZyb21TZXQoc2V0KSB7XG4gICAgdmFyIHZhbHVlcyA9IFtdO1xuICAgIHNldC5mb3JFYWNoKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgdmFsdWVzLnB1c2godmFsdWUpO1xuICAgIH0pO1xuICAgIHJldHVybiB2YWx1ZXM7XG4gIH1cblxuICBmdW5jdGlvbiBpbnNwZWN0U2V0KHNldCwgb3B0aW9ucykge1xuICAgIGlmIChzZXQuc2l6ZSA9PT0gMCkgcmV0dXJuICdTZXR7fSc7XG4gICAgb3B0aW9ucy50cnVuY2F0ZSAtPSA3O1xuICAgIHJldHVybiBcIlNldHsgXCIuY29uY2F0KGluc3BlY3RMaXN0KGFycmF5RnJvbVNldChzZXQpLCBvcHRpb25zKSwgXCIgfVwiKTtcbiAgfVxuXG4gIHZhciBzdHJpbmdFc2NhcGVDaGFycyA9IG5ldyBSZWdFeHAoXCJbJ1xcXFx1MDAwMC1cXFxcdTAwMWZcXFxcdTAwN2YtXFxcXHUwMDlmXFxcXHUwMGFkXFxcXHUwNjAwLVxcXFx1MDYwNFxcXFx1MDcwZlxcXFx1MTdiNFxcXFx1MTdiNVwiICsgXCJcXFxcdTIwMGMtXFxcXHUyMDBmXFxcXHUyMDI4LVxcXFx1MjAyZlxcXFx1MjA2MC1cXFxcdTIwNmZcXFxcdWZlZmZcXFxcdWZmZjAtXFxcXHVmZmZmXVwiLCAnZycpO1xuICB2YXIgZXNjYXBlQ2hhcmFjdGVycyA9IHtcbiAgICAnXFxiJzogJ1xcXFxiJyxcbiAgICAnXFx0JzogJ1xcXFx0JyxcbiAgICAnXFxuJzogJ1xcXFxuJyxcbiAgICAnXFxmJzogJ1xcXFxmJyxcbiAgICAnXFxyJzogJ1xcXFxyJyxcbiAgICBcIidcIjogXCJcXFxcJ1wiLFxuICAgICdcXFxcJzogJ1xcXFxcXFxcJ1xuICB9O1xuICB2YXIgaGV4ID0gMTY7XG4gIHZhciB1bmljb2RlTGVuZ3RoID0gNDtcblxuICBmdW5jdGlvbiBlc2NhcGUoY2hhcikge1xuICAgIHJldHVybiBlc2NhcGVDaGFyYWN0ZXJzW2NoYXJdIHx8IFwiXFxcXHVcIi5jb25jYXQoXCIwMDAwXCIuY29uY2F0KGNoYXIuY2hhckNvZGVBdCgwKS50b1N0cmluZyhoZXgpKS5zbGljZSgtdW5pY29kZUxlbmd0aCkpO1xuICB9XG5cbiAgZnVuY3Rpb24gaW5zcGVjdFN0cmluZyhzdHJpbmcsIG9wdGlvbnMpIHtcbiAgICBpZiAoc3RyaW5nRXNjYXBlQ2hhcnMudGVzdChzdHJpbmcpKSB7XG4gICAgICBzdHJpbmcgPSBzdHJpbmcucmVwbGFjZShzdHJpbmdFc2NhcGVDaGFycywgZXNjYXBlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3B0aW9ucy5zdHlsaXplKFwiJ1wiLmNvbmNhdCh0cnVuY2F0ZShzdHJpbmcsIG9wdGlvbnMudHJ1bmNhdGUgLSAyKSwgXCInXCIpLCAnc3RyaW5nJyk7XG4gIH1cblxuICBmdW5jdGlvbiBpbnNwZWN0U3ltYm9sKHZhbHVlKSB7XG4gICAgaWYgKCdkZXNjcmlwdGlvbicgaW4gU3ltYm9sLnByb3RvdHlwZSkge1xuICAgICAgcmV0dXJuIHZhbHVlLmRlc2NyaXB0aW9uID8gXCJTeW1ib2woXCIuY29uY2F0KHZhbHVlLmRlc2NyaXB0aW9uLCBcIilcIikgOiAnU3ltYm9sKCknO1xuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZS50b1N0cmluZygpO1xuICB9XG5cbiAgdmFyIGdldFByb21pc2VWYWx1ZSA9IGZ1bmN0aW9uIGdldFByb21pc2VWYWx1ZSgpIHtcbiAgICByZXR1cm4gJ1Byb21pc2V7XHUyMDI2fSc7XG4gIH07XG5cbiAgdHJ5IHtcbiAgICB2YXIgX3Byb2Nlc3MkYmluZGluZyA9IHByb2Nlc3MuYmluZGluZygndXRpbCcpLFxuICAgICAgICBnZXRQcm9taXNlRGV0YWlscyA9IF9wcm9jZXNzJGJpbmRpbmcuZ2V0UHJvbWlzZURldGFpbHMsXG4gICAgICAgIGtQZW5kaW5nID0gX3Byb2Nlc3MkYmluZGluZy5rUGVuZGluZyxcbiAgICAgICAga1JlamVjdGVkID0gX3Byb2Nlc3MkYmluZGluZy5rUmVqZWN0ZWQ7XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShnZXRQcm9taXNlRGV0YWlscyhQcm9taXNlLnJlc29sdmUoKSkpKSB7XG4gICAgICBnZXRQcm9taXNlVmFsdWUgPSBmdW5jdGlvbiBnZXRQcm9taXNlVmFsdWUodmFsdWUsIG9wdGlvbnMpIHtcbiAgICAgICAgdmFyIF9nZXRQcm9taXNlRGV0YWlscyA9IGdldFByb21pc2VEZXRhaWxzKHZhbHVlKSxcbiAgICAgICAgICAgIF9nZXRQcm9taXNlRGV0YWlsczIgPSBfc2xpY2VkVG9BcnJheShfZ2V0UHJvbWlzZURldGFpbHMsIDIpLFxuICAgICAgICAgICAgc3RhdGUgPSBfZ2V0UHJvbWlzZURldGFpbHMyWzBdLFxuICAgICAgICAgICAgaW5uZXJWYWx1ZSA9IF9nZXRQcm9taXNlRGV0YWlsczJbMV07XG5cbiAgICAgICAgaWYgKHN0YXRlID09PSBrUGVuZGluZykge1xuICAgICAgICAgIHJldHVybiAnUHJvbWlzZXs8cGVuZGluZz59JztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBcIlByb21pc2VcIi5jb25jYXQoc3RhdGUgPT09IGtSZWplY3RlZCA/ICchJyA6ICcnLCBcIntcIikuY29uY2F0KG9wdGlvbnMuaW5zcGVjdChpbm5lclZhbHVlLCBvcHRpb25zKSwgXCJ9XCIpO1xuICAgICAgfTtcbiAgICB9XG4gIH0gY2F0Y2ggKG5vdE5vZGUpIHtcbiAgICAvKiBpZ25vcmUgKi9cbiAgfVxuXG4gIHZhciBpbnNwZWN0UHJvbWlzZSA9IGdldFByb21pc2VWYWx1ZTtcblxuICBmdW5jdGlvbiBpbnNwZWN0T2JqZWN0KG9iamVjdCwgb3B0aW9ucykge1xuICAgIHZhciBwcm9wZXJ0aWVzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMob2JqZWN0KTtcbiAgICB2YXIgc3ltYm9scyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPyBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKG9iamVjdCkgOiBbXTtcblxuICAgIGlmIChwcm9wZXJ0aWVzLmxlbmd0aCA9PT0gMCAmJiBzeW1ib2xzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuICd7fSc7XG4gICAgfVxuXG4gICAgb3B0aW9ucy50cnVuY2F0ZSAtPSA0O1xuICAgIG9wdGlvbnMuc2VlbiA9IG9wdGlvbnMuc2VlbiB8fCBbXTtcblxuICAgIGlmIChvcHRpb25zLnNlZW4uaW5kZXhPZihvYmplY3QpID49IDApIHtcbiAgICAgIHJldHVybiAnW0NpcmN1bGFyXSc7XG4gICAgfVxuXG4gICAgb3B0aW9ucy5zZWVuLnB1c2gob2JqZWN0KTtcbiAgICB2YXIgcHJvcGVydHlDb250ZW50cyA9IGluc3BlY3RMaXN0KHByb3BlcnRpZXMubWFwKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgIHJldHVybiBba2V5LCBvYmplY3Rba2V5XV07XG4gICAgfSksIG9wdGlvbnMsIGluc3BlY3RQcm9wZXJ0eSk7XG4gICAgdmFyIHN5bWJvbENvbnRlbnRzID0gaW5zcGVjdExpc3Qoc3ltYm9scy5tYXAoZnVuY3Rpb24gKGtleSkge1xuICAgICAgcmV0dXJuIFtrZXksIG9iamVjdFtrZXldXTtcbiAgICB9KSwgb3B0aW9ucywgaW5zcGVjdFByb3BlcnR5KTtcbiAgICBvcHRpb25zLnNlZW4ucG9wKCk7XG4gICAgdmFyIHNlcCA9ICcnO1xuXG4gICAgaWYgKHByb3BlcnR5Q29udGVudHMgJiYgc3ltYm9sQ29udGVudHMpIHtcbiAgICAgIHNlcCA9ICcsICc7XG4gICAgfVxuXG4gICAgcmV0dXJuIFwieyBcIi5jb25jYXQocHJvcGVydHlDb250ZW50cykuY29uY2F0KHNlcCkuY29uY2F0KHN5bWJvbENvbnRlbnRzLCBcIiB9XCIpO1xuICB9XG5cbiAgdmFyIHRvU3RyaW5nVGFnID0gdHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvU3RyaW5nVGFnID8gU3ltYm9sLnRvU3RyaW5nVGFnIDogZmFsc2U7XG4gIGZ1bmN0aW9uIGluc3BlY3RDbGFzcyh2YWx1ZSwgb3B0aW9ucykge1xuICAgIHZhciBuYW1lID0gJyc7XG5cbiAgICBpZiAodG9TdHJpbmdUYWcgJiYgdG9TdHJpbmdUYWcgaW4gdmFsdWUpIHtcbiAgICAgIG5hbWUgPSB2YWx1ZVt0b1N0cmluZ1RhZ107XG4gICAgfVxuXG4gICAgbmFtZSA9IG5hbWUgfHwgZ2V0RnVuY05hbWVfMSh2YWx1ZS5jb25zdHJ1Y3Rvcik7IC8vIEJhYmVsIHRyYW5zZm9ybXMgYW5vbnltb3VzIGNsYXNzZXMgdG8gdGhlIG5hbWUgYF9jbGFzc2BcblxuICAgIGlmICghbmFtZSB8fCBuYW1lID09PSAnX2NsYXNzJykge1xuICAgICAgbmFtZSA9ICc8QW5vbnltb3VzIENsYXNzPic7XG4gICAgfVxuXG4gICAgb3B0aW9ucy50cnVuY2F0ZSAtPSBuYW1lLmxlbmd0aDtcbiAgICByZXR1cm4gXCJcIi5jb25jYXQobmFtZSkuY29uY2F0KGluc3BlY3RPYmplY3QodmFsdWUsIG9wdGlvbnMpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGluc3BlY3RBcmd1bWVudHMoYXJncywgb3B0aW9ucykge1xuICAgIGlmIChhcmdzLmxlbmd0aCA9PT0gMCkgcmV0dXJuICdBcmd1bWVudHNbXSc7XG4gICAgb3B0aW9ucy50cnVuY2F0ZSAtPSAxMztcbiAgICByZXR1cm4gXCJBcmd1bWVudHNbIFwiLmNvbmNhdChpbnNwZWN0TGlzdChhcmdzLCBvcHRpb25zKSwgXCIgXVwiKTtcbiAgfVxuXG4gIHZhciBlcnJvcktleXMgPSBbJ3N0YWNrJywgJ2xpbmUnLCAnY29sdW1uJywgJ25hbWUnLCAnbWVzc2FnZScsICdmaWxlTmFtZScsICdsaW5lTnVtYmVyJywgJ2NvbHVtbk51bWJlcicsICdudW1iZXInLCAnZGVzY3JpcHRpb24nXTtcbiAgZnVuY3Rpb24gaW5zcGVjdE9iamVjdCQxKGVycm9yLCBvcHRpb25zKSB7XG4gICAgdmFyIHByb3BlcnRpZXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhlcnJvcikuZmlsdGVyKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgIHJldHVybiBlcnJvcktleXMuaW5kZXhPZihrZXkpID09PSAtMTtcbiAgICB9KTtcbiAgICB2YXIgbmFtZSA9IGVycm9yLm5hbWU7XG4gICAgb3B0aW9ucy50cnVuY2F0ZSAtPSBuYW1lLmxlbmd0aDtcbiAgICB2YXIgbWVzc2FnZSA9ICcnO1xuXG4gICAgaWYgKHR5cGVvZiBlcnJvci5tZXNzYWdlID09PSAnc3RyaW5nJykge1xuICAgICAgbWVzc2FnZSA9IHRydW5jYXRlKGVycm9yLm1lc3NhZ2UsIG9wdGlvbnMudHJ1bmNhdGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBwcm9wZXJ0aWVzLnVuc2hpZnQoJ21lc3NhZ2UnKTtcbiAgICB9XG5cbiAgICBtZXNzYWdlID0gbWVzc2FnZSA/IFwiOiBcIi5jb25jYXQobWVzc2FnZSkgOiAnJztcbiAgICBvcHRpb25zLnRydW5jYXRlIC09IG1lc3NhZ2UubGVuZ3RoICsgNTtcbiAgICB2YXIgcHJvcGVydHlDb250ZW50cyA9IGluc3BlY3RMaXN0KHByb3BlcnRpZXMubWFwKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgIHJldHVybiBba2V5LCBlcnJvcltrZXldXTtcbiAgICB9KSwgb3B0aW9ucywgaW5zcGVjdFByb3BlcnR5KTtcbiAgICByZXR1cm4gXCJcIi5jb25jYXQobmFtZSkuY29uY2F0KG1lc3NhZ2UpLmNvbmNhdChwcm9wZXJ0eUNvbnRlbnRzID8gXCIgeyBcIi5jb25jYXQocHJvcGVydHlDb250ZW50cywgXCIgfVwiKSA6ICcnKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGluc3BlY3RBdHRyaWJ1dGUoX3JlZiwgb3B0aW9ucykge1xuICAgIHZhciBfcmVmMiA9IF9zbGljZWRUb0FycmF5KF9yZWYsIDIpLFxuICAgICAgICBrZXkgPSBfcmVmMlswXSxcbiAgICAgICAgdmFsdWUgPSBfcmVmMlsxXTtcblxuICAgIG9wdGlvbnMudHJ1bmNhdGUgLT0gMztcblxuICAgIGlmICghdmFsdWUpIHtcbiAgICAgIHJldHVybiBcIlwiLmNvbmNhdChvcHRpb25zLnN0eWxpemUoa2V5LCAneWVsbG93JykpO1xuICAgIH1cblxuICAgIHJldHVybiBcIlwiLmNvbmNhdChvcHRpb25zLnN0eWxpemUoa2V5LCAneWVsbG93JyksIFwiPVwiKS5jb25jYXQob3B0aW9ucy5zdHlsaXplKFwiXFxcIlwiLmNvbmNhdCh2YWx1ZSwgXCJcXFwiXCIpLCAnc3RyaW5nJykpO1xuICB9XG4gIGZ1bmN0aW9uIGluc3BlY3RIVE1MQ29sbGVjdGlvbihjb2xsZWN0aW9uLCBvcHRpb25zKSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVzZS1iZWZvcmUtZGVmaW5lXG4gICAgcmV0dXJuIGluc3BlY3RMaXN0KGNvbGxlY3Rpb24sIG9wdGlvbnMsIGluc3BlY3RIVE1MLCAnXFxuJyk7XG4gIH1cbiAgZnVuY3Rpb24gaW5zcGVjdEhUTUwoZWxlbWVudCwgb3B0aW9ucykge1xuICAgIHZhciBwcm9wZXJ0aWVzID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVOYW1lcygpO1xuICAgIHZhciBuYW1lID0gZWxlbWVudC50YWdOYW1lLnRvTG93ZXJDYXNlKCk7XG4gICAgdmFyIGhlYWQgPSBvcHRpb25zLnN0eWxpemUoXCI8XCIuY29uY2F0KG5hbWUpLCAnc3BlY2lhbCcpO1xuICAgIHZhciBoZWFkQ2xvc2UgPSBvcHRpb25zLnN0eWxpemUoXCI+XCIsICdzcGVjaWFsJyk7XG4gICAgdmFyIHRhaWwgPSBvcHRpb25zLnN0eWxpemUoXCI8L1wiLmNvbmNhdChuYW1lLCBcIj5cIiksICdzcGVjaWFsJyk7XG4gICAgb3B0aW9ucy50cnVuY2F0ZSAtPSBuYW1lLmxlbmd0aCAqIDIgKyA1O1xuICAgIHZhciBwcm9wZXJ0eUNvbnRlbnRzID0gJyc7XG5cbiAgICBpZiAocHJvcGVydGllcy5sZW5ndGggPiAwKSB7XG4gICAgICBwcm9wZXJ0eUNvbnRlbnRzICs9ICcgJztcbiAgICAgIHByb3BlcnR5Q29udGVudHMgKz0gaW5zcGVjdExpc3QocHJvcGVydGllcy5tYXAoZnVuY3Rpb24gKGtleSkge1xuICAgICAgICByZXR1cm4gW2tleSwgZWxlbWVudC5nZXRBdHRyaWJ1dGUoa2V5KV07XG4gICAgICB9KSwgb3B0aW9ucywgaW5zcGVjdEF0dHJpYnV0ZSwgJyAnKTtcbiAgICB9XG5cbiAgICBvcHRpb25zLnRydW5jYXRlIC09IHByb3BlcnR5Q29udGVudHMubGVuZ3RoO1xuICAgIHZhciB0cnVuY2F0ZSA9IG9wdGlvbnMudHJ1bmNhdGU7XG4gICAgdmFyIGNoaWxkcmVuID0gaW5zcGVjdEhUTUxDb2xsZWN0aW9uKGVsZW1lbnQuY2hpbGRyZW4sIG9wdGlvbnMpO1xuXG4gICAgaWYgKGNoaWxkcmVuICYmIGNoaWxkcmVuLmxlbmd0aCA+IHRydW5jYXRlKSB7XG4gICAgICBjaGlsZHJlbiA9IFwiXCIuY29uY2F0KHRydW5jYXRvciwgXCIoXCIpLmNvbmNhdChlbGVtZW50LmNoaWxkcmVuLmxlbmd0aCwgXCIpXCIpO1xuICAgIH1cblxuICAgIHJldHVybiBcIlwiLmNvbmNhdChoZWFkKS5jb25jYXQocHJvcGVydHlDb250ZW50cykuY29uY2F0KGhlYWRDbG9zZSkuY29uY2F0KGNoaWxkcmVuKS5jb25jYXQodGFpbCk7XG4gIH1cblxuICB2YXIgc3ltYm9sc1N1cHBvcnRlZCA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIFN5bWJvbC5mb3IgPT09ICdmdW5jdGlvbic7XG4gIHZhciBjaGFpSW5zcGVjdCA9IHN5bWJvbHNTdXBwb3J0ZWQgPyBTeW1ib2wuZm9yKCdjaGFpL2luc3BlY3QnKSA6ICdAQGNoYWkvaW5zcGVjdCc7XG4gIHZhciBub2RlSW5zcGVjdCA9IGZhbHNlO1xuXG4gIHRyeSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGdsb2JhbC1yZXF1aXJlXG4gICAgdmFyIG5vZGVVdGlsID0gcmVxdWlyZSgndXRpbCcpO1xuXG4gICAgbm9kZUluc3BlY3QgPSBub2RlVXRpbC5pbnNwZWN0ID8gbm9kZVV0aWwuaW5zcGVjdC5jdXN0b20gOiBmYWxzZTtcbiAgfSBjYXRjaCAobm9Ob2RlSW5zcGVjdCkge1xuICAgIG5vZGVJbnNwZWN0ID0gZmFsc2U7XG4gIH1cblxuICBmdW5jdGlvbiBGYWtlTWFwKCkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBwcmVmZXItdGVtcGxhdGVcbiAgICB0aGlzLmtleSA9ICdjaGFpL2xvdXBlX18nICsgTWF0aC5yYW5kb20oKSArIERhdGUubm93KCk7XG4gIH1cblxuICBGYWtlTWFwLnByb3RvdHlwZSA9IHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgb2JqZWN0LXNob3J0aGFuZFxuICAgIGdldDogZnVuY3Rpb24gZ2V0KGtleSkge1xuICAgICAgcmV0dXJuIGtleVt0aGlzLmtleV07XG4gICAgfSxcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgb2JqZWN0LXNob3J0aGFuZFxuICAgIGhhczogZnVuY3Rpb24gaGFzKGtleSkge1xuICAgICAgcmV0dXJuIHRoaXMua2V5IGluIGtleTtcbiAgICB9LFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBvYmplY3Qtc2hvcnRoYW5kXG4gICAgc2V0OiBmdW5jdGlvbiBzZXQoa2V5LCB2YWx1ZSkge1xuICAgICAgaWYgKE9iamVjdC5pc0V4dGVuc2libGUoa2V5KSkge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoa2V5LCB0aGlzLmtleSwge1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBvYmplY3Qtc2hvcnRoYW5kXG4gICAgICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG4gIHZhciBjb25zdHJ1Y3Rvck1hcCA9IG5ldyAodHlwZW9mIFdlYWtNYXAgPT09ICdmdW5jdGlvbicgPyBXZWFrTWFwIDogRmFrZU1hcCkoKTtcbiAgdmFyIHN0cmluZ1RhZ01hcCA9IHt9O1xuICB2YXIgYmFzZVR5cGVzTWFwID0ge1xuICAgIHVuZGVmaW5lZDogZnVuY3Rpb24gdW5kZWZpbmVkJDEodmFsdWUsIG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiBvcHRpb25zLnN0eWxpemUoJ3VuZGVmaW5lZCcsICd1bmRlZmluZWQnKTtcbiAgICB9LFxuICAgIG51bGw6IGZ1bmN0aW9uIF9udWxsKHZhbHVlLCBvcHRpb25zKSB7XG4gICAgICByZXR1cm4gb3B0aW9ucy5zdHlsaXplKG51bGwsICdudWxsJyk7XG4gICAgfSxcbiAgICBib29sZWFuOiBmdW5jdGlvbiBib29sZWFuKHZhbHVlLCBvcHRpb25zKSB7XG4gICAgICByZXR1cm4gb3B0aW9ucy5zdHlsaXplKHZhbHVlLCAnYm9vbGVhbicpO1xuICAgIH0sXG4gICAgQm9vbGVhbjogZnVuY3Rpb24gQm9vbGVhbih2YWx1ZSwgb3B0aW9ucykge1xuICAgICAgcmV0dXJuIG9wdGlvbnMuc3R5bGl6ZSh2YWx1ZSwgJ2Jvb2xlYW4nKTtcbiAgICB9LFxuICAgIG51bWJlcjogaW5zcGVjdE51bWJlcixcbiAgICBOdW1iZXI6IGluc3BlY3ROdW1iZXIsXG4gICAgYmlnaW50OiBpbnNwZWN0QmlnSW50LFxuICAgIEJpZ0ludDogaW5zcGVjdEJpZ0ludCxcbiAgICBzdHJpbmc6IGluc3BlY3RTdHJpbmcsXG4gICAgU3RyaW5nOiBpbnNwZWN0U3RyaW5nLFxuICAgIGZ1bmN0aW9uOiBpbnNwZWN0RnVuY3Rpb24sXG4gICAgRnVuY3Rpb246IGluc3BlY3RGdW5jdGlvbixcbiAgICBzeW1ib2w6IGluc3BlY3RTeW1ib2wsXG4gICAgLy8gQSBTeW1ib2wgcG9seWZpbGwgd2lsbCByZXR1cm4gYFN5bWJvbGAgbm90IGBzeW1ib2xgIGZyb20gdHlwZWRldGVjdFxuICAgIFN5bWJvbDogaW5zcGVjdFN5bWJvbCxcbiAgICBBcnJheTogaW5zcGVjdEFycmF5LFxuICAgIERhdGU6IGluc3BlY3REYXRlLFxuICAgIE1hcDogaW5zcGVjdE1hcCxcbiAgICBTZXQ6IGluc3BlY3RTZXQsXG4gICAgUmVnRXhwOiBpbnNwZWN0UmVnRXhwLFxuICAgIFByb21pc2U6IGluc3BlY3RQcm9taXNlLFxuICAgIC8vIFdlYWtTZXQsIFdlYWtNYXAgYXJlIHRvdGFsbHkgb3BhcXVlIHRvIHVzXG4gICAgV2Vha1NldDogZnVuY3Rpb24gV2Vha1NldCh2YWx1ZSwgb3B0aW9ucykge1xuICAgICAgcmV0dXJuIG9wdGlvbnMuc3R5bGl6ZSgnV2Vha1NldHtcdTIwMjZ9JywgJ3NwZWNpYWwnKTtcbiAgICB9LFxuICAgIFdlYWtNYXA6IGZ1bmN0aW9uIFdlYWtNYXAodmFsdWUsIG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiBvcHRpb25zLnN0eWxpemUoJ1dlYWtNYXB7XHUyMDI2fScsICdzcGVjaWFsJyk7XG4gICAgfSxcbiAgICBBcmd1bWVudHM6IGluc3BlY3RBcmd1bWVudHMsXG4gICAgSW50OEFycmF5OiBpbnNwZWN0VHlwZWRBcnJheSxcbiAgICBVaW50OEFycmF5OiBpbnNwZWN0VHlwZWRBcnJheSxcbiAgICBVaW50OENsYW1wZWRBcnJheTogaW5zcGVjdFR5cGVkQXJyYXksXG4gICAgSW50MTZBcnJheTogaW5zcGVjdFR5cGVkQXJyYXksXG4gICAgVWludDE2QXJyYXk6IGluc3BlY3RUeXBlZEFycmF5LFxuICAgIEludDMyQXJyYXk6IGluc3BlY3RUeXBlZEFycmF5LFxuICAgIFVpbnQzMkFycmF5OiBpbnNwZWN0VHlwZWRBcnJheSxcbiAgICBGbG9hdDMyQXJyYXk6IGluc3BlY3RUeXBlZEFycmF5LFxuICAgIEZsb2F0NjRBcnJheTogaW5zcGVjdFR5cGVkQXJyYXksXG4gICAgR2VuZXJhdG9yOiBmdW5jdGlvbiBHZW5lcmF0b3IoKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfSxcbiAgICBEYXRhVmlldzogZnVuY3Rpb24gRGF0YVZpZXcoKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfSxcbiAgICBBcnJheUJ1ZmZlcjogZnVuY3Rpb24gQXJyYXlCdWZmZXIoKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfSxcbiAgICBFcnJvcjogaW5zcGVjdE9iamVjdCQxLFxuICAgIEhUTUxDb2xsZWN0aW9uOiBpbnNwZWN0SFRNTENvbGxlY3Rpb24sXG4gICAgTm9kZUxpc3Q6IGluc3BlY3RIVE1MQ29sbGVjdGlvblxuICB9OyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29tcGxleGl0eVxuXG4gIHZhciBpbnNwZWN0Q3VzdG9tID0gZnVuY3Rpb24gaW5zcGVjdEN1c3RvbSh2YWx1ZSwgb3B0aW9ucywgdHlwZSkge1xuICAgIGlmIChjaGFpSW5zcGVjdCBpbiB2YWx1ZSAmJiB0eXBlb2YgdmFsdWVbY2hhaUluc3BlY3RdID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gdmFsdWVbY2hhaUluc3BlY3RdKG9wdGlvbnMpO1xuICAgIH1cblxuICAgIGlmIChub2RlSW5zcGVjdCAmJiBub2RlSW5zcGVjdCBpbiB2YWx1ZSAmJiB0eXBlb2YgdmFsdWVbbm9kZUluc3BlY3RdID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gdmFsdWVbbm9kZUluc3BlY3RdKG9wdGlvbnMuZGVwdGgsIG9wdGlvbnMpO1xuICAgIH1cblxuICAgIGlmICgnaW5zcGVjdCcgaW4gdmFsdWUgJiYgdHlwZW9mIHZhbHVlLmluc3BlY3QgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybiB2YWx1ZS5pbnNwZWN0KG9wdGlvbnMuZGVwdGgsIG9wdGlvbnMpO1xuICAgIH1cblxuICAgIGlmICgnY29uc3RydWN0b3InIGluIHZhbHVlICYmIGNvbnN0cnVjdG9yTWFwLmhhcyh2YWx1ZS5jb25zdHJ1Y3RvcikpIHtcbiAgICAgIHJldHVybiBjb25zdHJ1Y3Rvck1hcC5nZXQodmFsdWUuY29uc3RydWN0b3IpKHZhbHVlLCBvcHRpb25zKTtcbiAgICB9XG5cbiAgICBpZiAoc3RyaW5nVGFnTWFwW3R5cGVdKSB7XG4gICAgICByZXR1cm4gc3RyaW5nVGFnTWFwW3R5cGVdKHZhbHVlLCBvcHRpb25zKTtcbiAgICB9XG5cbiAgICByZXR1cm4gJyc7XG4gIH07XG5cbiAgdmFyIHRvU3RyaW5nJDEgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nOyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29tcGxleGl0eVxuXG4gIGZ1bmN0aW9uIGluc3BlY3QodmFsdWUsIG9wdGlvbnMpIHtcbiAgICBvcHRpb25zID0gbm9ybWFsaXNlT3B0aW9ucyhvcHRpb25zKTtcbiAgICBvcHRpb25zLmluc3BlY3QgPSBpbnNwZWN0O1xuICAgIHZhciBfb3B0aW9ucyA9IG9wdGlvbnMsXG4gICAgICAgIGN1c3RvbUluc3BlY3QgPSBfb3B0aW9ucy5jdXN0b21JbnNwZWN0O1xuICAgIHZhciB0eXBlID0gdmFsdWUgPT09IG51bGwgPyAnbnVsbCcgOiBfdHlwZW9mKHZhbHVlKTtcblxuICAgIGlmICh0eXBlID09PSAnb2JqZWN0Jykge1xuICAgICAgdHlwZSA9IHRvU3RyaW5nJDEuY2FsbCh2YWx1ZSkuc2xpY2UoOCwgLTEpO1xuICAgIH0gLy8gSWYgaXQgaXMgYSBiYXNlIHZhbHVlIHRoYXQgd2UgYWxyZWFkeSBzdXBwb3J0LCB0aGVuIHVzZSBMb3VwZSdzIGluc3BlY3RvclxuXG5cbiAgICBpZiAoYmFzZVR5cGVzTWFwW3R5cGVdKSB7XG4gICAgICByZXR1cm4gYmFzZVR5cGVzTWFwW3R5cGVdKHZhbHVlLCBvcHRpb25zKTtcbiAgICB9IC8vIElmIGBvcHRpb25zLmN1c3RvbUluc3BlY3RgIGlzIHNldCB0byB0cnVlIHRoZW4gdHJ5IHRvIHVzZSB0aGUgY3VzdG9tIGluc3BlY3RvclxuXG5cbiAgICBpZiAoY3VzdG9tSW5zcGVjdCAmJiB2YWx1ZSkge1xuICAgICAgdmFyIG91dHB1dCA9IGluc3BlY3RDdXN0b20odmFsdWUsIG9wdGlvbnMsIHR5cGUpO1xuXG4gICAgICBpZiAob3V0cHV0KSB7XG4gICAgICAgIGlmICh0eXBlb2Ygb3V0cHV0ID09PSAnc3RyaW5nJykgcmV0dXJuIG91dHB1dDtcbiAgICAgICAgcmV0dXJuIGluc3BlY3Qob3V0cHV0LCBvcHRpb25zKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgcHJvdG8gPSB2YWx1ZSA/IE9iamVjdC5nZXRQcm90b3R5cGVPZih2YWx1ZSkgOiBmYWxzZTsgLy8gSWYgaXQncyBhIHBsYWluIE9iamVjdCB0aGVuIHVzZSBMb3VwZSdzIGluc3BlY3RvclxuXG4gICAgaWYgKHByb3RvID09PSBPYmplY3QucHJvdG90eXBlIHx8IHByb3RvID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gaW5zcGVjdE9iamVjdCh2YWx1ZSwgb3B0aW9ucyk7XG4gICAgfSAvLyBTcGVjaWZpY2FsbHkgYWNjb3VudCBmb3IgSFRNTEVsZW1lbnRzXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVmXG5cblxuICAgIGlmICh2YWx1ZSAmJiB0eXBlb2YgSFRNTEVsZW1lbnQgPT09ICdmdW5jdGlvbicgJiYgdmFsdWUgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgcmV0dXJuIGluc3BlY3RIVE1MKHZhbHVlLCBvcHRpb25zKTtcbiAgICB9XG5cbiAgICBpZiAoJ2NvbnN0cnVjdG9yJyBpbiB2YWx1ZSkge1xuICAgICAgLy8gSWYgaXQgaXMgYSBjbGFzcywgaW5zcGVjdCBpdCBsaWtlIGFuIG9iamVjdCBidXQgYWRkIHRoZSBjb25zdHJ1Y3RvciBuYW1lXG4gICAgICBpZiAodmFsdWUuY29uc3RydWN0b3IgIT09IE9iamVjdCkge1xuICAgICAgICByZXR1cm4gaW5zcGVjdENsYXNzKHZhbHVlLCBvcHRpb25zKTtcbiAgICAgIH0gLy8gSWYgaXQgaXMgYW4gb2JqZWN0IHdpdGggYW4gYW5vbnltb3VzIHByb3RvdHlwZSwgZGlzcGxheSBpdCBhcyBhbiBvYmplY3QuXG5cblxuICAgICAgcmV0dXJuIGluc3BlY3RPYmplY3QodmFsdWUsIG9wdGlvbnMpO1xuICAgIH0gLy8gbGFzdCBjaGFuY2UgdG8gY2hlY2sgaWYgaXQncyBhbiBvYmplY3RcblxuXG4gICAgaWYgKHZhbHVlID09PSBPYmplY3QodmFsdWUpKSB7XG4gICAgICByZXR1cm4gaW5zcGVjdE9iamVjdCh2YWx1ZSwgb3B0aW9ucyk7XG4gICAgfSAvLyBXZSBoYXZlIHJ1biBvdXQgb2Ygb3B0aW9ucyEgSnVzdCBzdHJpbmdpZnkgdGhlIHZhbHVlXG5cblxuICAgIHJldHVybiBvcHRpb25zLnN0eWxpemUoU3RyaW5nKHZhbHVlKSwgdHlwZSk7XG4gIH1cbiAgZnVuY3Rpb24gcmVnaXN0ZXJDb25zdHJ1Y3Rvcihjb25zdHJ1Y3RvciwgaW5zcGVjdG9yKSB7XG4gICAgaWYgKGNvbnN0cnVjdG9yTWFwLmhhcyhjb25zdHJ1Y3RvcikpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBjb25zdHJ1Y3Rvck1hcC5zZXQoY29uc3RydWN0b3IsIGluc3BlY3Rvcik7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgZnVuY3Rpb24gcmVnaXN0ZXJTdHJpbmdUYWcoc3RyaW5nVGFnLCBpbnNwZWN0b3IpIHtcbiAgICBpZiAoc3RyaW5nVGFnIGluIHN0cmluZ1RhZ01hcCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHN0cmluZ1RhZ01hcFtzdHJpbmdUYWddID0gaW5zcGVjdG9yO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHZhciBjdXN0b20gPSBjaGFpSW5zcGVjdDtcblxuICBleHBvcnRzLmN1c3RvbSA9IGN1c3RvbTtcbiAgZXhwb3J0cy5kZWZhdWx0ID0gaW5zcGVjdDtcbiAgZXhwb3J0cy5pbnNwZWN0ID0gaW5zcGVjdDtcbiAgZXhwb3J0cy5yZWdpc3RlckNvbnN0cnVjdG9yID0gcmVnaXN0ZXJDb25zdHJ1Y3RvcjtcbiAgZXhwb3J0cy5yZWdpc3RlclN0cmluZ1RhZyA9IHJlZ2lzdGVyU3RyaW5nVGFnO1xuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHsgdmFsdWU6IHRydWUgfSk7XG5cbn0pKSk7XG4iLCAibW9kdWxlLmV4cG9ydHMgPSB7XG5cbiAgLyoqXG4gICAqICMjIyBjb25maWcuaW5jbHVkZVN0YWNrXG4gICAqXG4gICAqIFVzZXIgY29uZmlndXJhYmxlIHByb3BlcnR5LCBpbmZsdWVuY2VzIHdoZXRoZXIgc3RhY2sgdHJhY2VcbiAgICogaXMgaW5jbHVkZWQgaW4gQXNzZXJ0aW9uIGVycm9yIG1lc3NhZ2UuIERlZmF1bHQgb2YgZmFsc2VcbiAgICogc3VwcHJlc3NlcyBzdGFjayB0cmFjZSBpbiB0aGUgZXJyb3IgbWVzc2FnZS5cbiAgICpcbiAgICogICAgIGNoYWkuY29uZmlnLmluY2x1ZGVTdGFjayA9IHRydWU7ICAvLyBlbmFibGUgc3RhY2sgb24gZXJyb3JcbiAgICpcbiAgICogQHBhcmFtIHtCb29sZWFufVxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBpbmNsdWRlU3RhY2s6IGZhbHNlLFxuXG4gIC8qKlxuICAgKiAjIyMgY29uZmlnLnNob3dEaWZmXG4gICAqXG4gICAqIFVzZXIgY29uZmlndXJhYmxlIHByb3BlcnR5LCBpbmZsdWVuY2VzIHdoZXRoZXIgb3Igbm90XG4gICAqIHRoZSBgc2hvd0RpZmZgIGZsYWcgc2hvdWxkIGJlIGluY2x1ZGVkIGluIHRoZSB0aHJvd25cbiAgICogQXNzZXJ0aW9uRXJyb3JzLiBgZmFsc2VgIHdpbGwgYWx3YXlzIGJlIGBmYWxzZWA7IGB0cnVlYFxuICAgKiB3aWxsIGJlIHRydWUgd2hlbiB0aGUgYXNzZXJ0aW9uIGhhcyByZXF1ZXN0ZWQgYSBkaWZmXG4gICAqIGJlIHNob3duLlxuICAgKlxuICAgKiBAcGFyYW0ge0Jvb2xlYW59XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIHNob3dEaWZmOiB0cnVlLFxuXG4gIC8qKlxuICAgKiAjIyMgY29uZmlnLnRydW5jYXRlVGhyZXNob2xkXG4gICAqXG4gICAqIFVzZXIgY29uZmlndXJhYmxlIHByb3BlcnR5LCBzZXRzIGxlbmd0aCB0aHJlc2hvbGQgZm9yIGFjdHVhbCBhbmRcbiAgICogZXhwZWN0ZWQgdmFsdWVzIGluIGFzc2VydGlvbiBlcnJvcnMuIElmIHRoaXMgdGhyZXNob2xkIGlzIGV4Y2VlZGVkLCBmb3JcbiAgICogZXhhbXBsZSBmb3IgbGFyZ2UgZGF0YSBzdHJ1Y3R1cmVzLCB0aGUgdmFsdWUgaXMgcmVwbGFjZWQgd2l0aCBzb21ldGhpbmdcbiAgICogbGlrZSBgWyBBcnJheSgzKSBdYCBvciBgeyBPYmplY3QgKHByb3AxLCBwcm9wMikgfWAuXG4gICAqXG4gICAqIFNldCBpdCB0byB6ZXJvIGlmIHlvdSB3YW50IHRvIGRpc2FibGUgdHJ1bmNhdGluZyBhbHRvZ2V0aGVyLlxuICAgKlxuICAgKiBUaGlzIGlzIGVzcGVjaWFsbHkgdXNlcmZ1bCB3aGVuIGRvaW5nIGFzc2VydGlvbnMgb24gYXJyYXlzOiBoYXZpbmcgdGhpc1xuICAgKiBzZXQgdG8gYSByZWFzb25hYmxlIGxhcmdlIHZhbHVlIG1ha2VzIHRoZSBmYWlsdXJlIG1lc3NhZ2VzIHJlYWRpbHlcbiAgICogaW5zcGVjdGFibGUuXG4gICAqXG4gICAqICAgICBjaGFpLmNvbmZpZy50cnVuY2F0ZVRocmVzaG9sZCA9IDA7ICAvLyBkaXNhYmxlIHRydW5jYXRpbmdcbiAgICpcbiAgICogQHBhcmFtIHtOdW1iZXJ9XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIHRydW5jYXRlVGhyZXNob2xkOiA0MCxcblxuICAvKipcbiAgICogIyMjIGNvbmZpZy51c2VQcm94eVxuICAgKlxuICAgKiBVc2VyIGNvbmZpZ3VyYWJsZSBwcm9wZXJ0eSwgZGVmaW5lcyBpZiBjaGFpIHdpbGwgdXNlIGEgUHJveHkgdG8gdGhyb3dcbiAgICogYW4gZXJyb3Igd2hlbiBhIG5vbi1leGlzdGVudCBwcm9wZXJ0eSBpcyByZWFkLCB3aGljaCBwcm90ZWN0cyB1c2Vyc1xuICAgKiBmcm9tIHR5cG9zIHdoZW4gdXNpbmcgcHJvcGVydHktYmFzZWQgYXNzZXJ0aW9ucy5cbiAgICpcbiAgICogU2V0IGl0IHRvIGZhbHNlIGlmIHlvdSB3YW50IHRvIGRpc2FibGUgdGhpcyBmZWF0dXJlLlxuICAgKlxuICAgKiAgICAgY2hhaS5jb25maWcudXNlUHJveHkgPSBmYWxzZTsgIC8vIGRpc2FibGUgdXNlIG9mIFByb3h5XG4gICAqXG4gICAqIFRoaXMgZmVhdHVyZSBpcyBhdXRvbWF0aWNhbGx5IGRpc2FibGVkIHJlZ2FyZGxlc3Mgb2YgdGhpcyBjb25maWcgdmFsdWVcbiAgICogaW4gZW52aXJvbm1lbnRzIHRoYXQgZG9uJ3Qgc3VwcG9ydCBwcm94aWVzLlxuICAgKlxuICAgKiBAcGFyYW0ge0Jvb2xlYW59XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIHVzZVByb3h5OiB0cnVlLFxuXG4gIC8qKlxuICAgKiAjIyMgY29uZmlnLnByb3h5RXhjbHVkZWRLZXlzXG4gICAqXG4gICAqIFVzZXIgY29uZmlndXJhYmxlIHByb3BlcnR5LCBkZWZpbmVzIHdoaWNoIHByb3BlcnRpZXMgc2hvdWxkIGJlIGlnbm9yZWRcbiAgICogaW5zdGVhZCBvZiB0aHJvd2luZyBhbiBlcnJvciBpZiB0aGV5IGRvIG5vdCBleGlzdCBvbiB0aGUgYXNzZXJ0aW9uLlxuICAgKiBUaGlzIGlzIG9ubHkgYXBwbGllZCBpZiB0aGUgZW52aXJvbm1lbnQgQ2hhaSBpcyBydW5uaW5nIGluIHN1cHBvcnRzIHByb3hpZXMgYW5kXG4gICAqIGlmIHRoZSBgdXNlUHJveHlgIGNvbmZpZ3VyYXRpb24gc2V0dGluZyBpcyBlbmFibGVkLlxuICAgKiBCeSBkZWZhdWx0LCBgdGhlbmAgYW5kIGBpbnNwZWN0YCB3aWxsIG5vdCB0aHJvdyBhbiBlcnJvciBpZiB0aGV5IGRvIG5vdCBleGlzdCBvbiB0aGVcbiAgICogYXNzZXJ0aW9uIG9iamVjdCBiZWNhdXNlIHRoZSBgLmluc3BlY3RgIHByb3BlcnR5IGlzIHJlYWQgYnkgYHV0aWwuaW5zcGVjdGAgKGZvciBleGFtcGxlLCB3aGVuXG4gICAqIHVzaW5nIGBjb25zb2xlLmxvZ2Agb24gdGhlIGFzc2VydGlvbiBvYmplY3QpIGFuZCBgLnRoZW5gIGlzIG5lY2Vzc2FyeSBmb3IgcHJvbWlzZSB0eXBlLWNoZWNraW5nLlxuICAgKlxuICAgKiAgICAgLy8gQnkgZGVmYXVsdCB0aGVzZSBrZXlzIHdpbGwgbm90IHRocm93IGFuIGVycm9yIGlmIHRoZXkgZG8gbm90IGV4aXN0IG9uIHRoZSBhc3NlcnRpb24gb2JqZWN0XG4gICAqICAgICBjaGFpLmNvbmZpZy5wcm94eUV4Y2x1ZGVkS2V5cyA9IFsndGhlbicsICdpbnNwZWN0J107XG4gICAqXG4gICAqIEBwYXJhbSB7QXJyYXl9XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIHByb3h5RXhjbHVkZWRLZXlzOiBbJ3RoZW4nLCAnY2F0Y2gnLCAnaW5zcGVjdCcsICd0b0pTT04nXVxufTtcbiIsICIvLyBUaGlzIGlzIChhbG1vc3QpIGRpcmVjdGx5IGZyb20gTm9kZS5qcyB1dGlsc1xuLy8gaHR0cHM6Ly9naXRodWIuY29tL2pveWVudC9ub2RlL2Jsb2IvZjhjMzM1ZDBjYWY0N2YxNmQzMTQxM2Y4OWFhMjhlZGEzODc4ZTNhYS9saWIvdXRpbC5qc1xuXG52YXIgZ2V0TmFtZSA9IHJlcXVpcmUoJ2dldC1mdW5jLW5hbWUnKTtcbnZhciBsb3VwZSA9IHJlcXVpcmUoJ2xvdXBlJyk7XG52YXIgY29uZmlnID0gcmVxdWlyZSgnLi4vY29uZmlnJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gaW5zcGVjdDtcblxuLyoqXG4gKiAjIyMgLmluc3BlY3Qob2JqLCBbc2hvd0hpZGRlbl0sIFtkZXB0aF0sIFtjb2xvcnNdKVxuICpcbiAqIEVjaG9lcyB0aGUgdmFsdWUgb2YgYSB2YWx1ZS4gVHJpZXMgdG8gcHJpbnQgdGhlIHZhbHVlIG91dFxuICogaW4gdGhlIGJlc3Qgd2F5IHBvc3NpYmxlIGdpdmVuIHRoZSBkaWZmZXJlbnQgdHlwZXMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iaiBUaGUgb2JqZWN0IHRvIHByaW50IG91dC5cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gc2hvd0hpZGRlbiBGbGFnIHRoYXQgc2hvd3MgaGlkZGVuIChub3QgZW51bWVyYWJsZSlcbiAqICAgIHByb3BlcnRpZXMgb2Ygb2JqZWN0cy4gRGVmYXVsdCBpcyBmYWxzZS5cbiAqIEBwYXJhbSB7TnVtYmVyfSBkZXB0aCBEZXB0aCBpbiB3aGljaCB0byBkZXNjZW5kIGluIG9iamVjdC4gRGVmYXVsdCBpcyAyLlxuICogQHBhcmFtIHtCb29sZWFufSBjb2xvcnMgRmxhZyB0byB0dXJuIG9uIEFOU0kgZXNjYXBlIGNvZGVzIHRvIGNvbG9yIHRoZVxuICogICAgb3V0cHV0LiBEZWZhdWx0IGlzIGZhbHNlIChubyBjb2xvcmluZykuXG4gKiBAbmFtZXNwYWNlIFV0aWxzXG4gKiBAbmFtZSBpbnNwZWN0XG4gKi9cbmZ1bmN0aW9uIGluc3BlY3Qob2JqLCBzaG93SGlkZGVuLCBkZXB0aCwgY29sb3JzKSB7XG4gIHZhciBvcHRpb25zID0ge1xuICAgIGNvbG9yczogY29sb3JzLFxuICAgIGRlcHRoOiAodHlwZW9mIGRlcHRoID09PSAndW5kZWZpbmVkJyA/IDIgOiBkZXB0aCksXG4gICAgc2hvd0hpZGRlbjogc2hvd0hpZGRlbixcbiAgICB0cnVuY2F0ZTogY29uZmlnLnRydW5jYXRlVGhyZXNob2xkID8gY29uZmlnLnRydW5jYXRlVGhyZXNob2xkIDogSW5maW5pdHksXG4gIH07XG4gIHJldHVybiBsb3VwZS5pbnNwZWN0KG9iaiwgb3B0aW9ucyk7XG59XG4iLCAiLyohXG4gKiBDaGFpIC0gZmxhZyB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyohXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzXG4gKi9cblxudmFyIGluc3BlY3QgPSByZXF1aXJlKCcuL2luc3BlY3QnKTtcbnZhciBjb25maWcgPSByZXF1aXJlKCcuLi9jb25maWcnKTtcblxuLyoqXG4gKiAjIyMgLm9iakRpc3BsYXkob2JqZWN0KVxuICpcbiAqIERldGVybWluZXMgaWYgYW4gb2JqZWN0IG9yIGFuIGFycmF5IG1hdGNoZXNcbiAqIGNyaXRlcmlhIHRvIGJlIGluc3BlY3RlZCBpbi1saW5lIGZvciBlcnJvclxuICogbWVzc2FnZXMgb3Igc2hvdWxkIGJlIHRydW5jYXRlZC5cbiAqXG4gKiBAcGFyYW0ge01peGVkfSBqYXZhc2NyaXB0IG9iamVjdCB0byBpbnNwZWN0XG4gKiBAbmFtZSBvYmpEaXNwbGF5XG4gKiBAbmFtZXNwYWNlIFV0aWxzXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gb2JqRGlzcGxheShvYmopIHtcbiAgdmFyIHN0ciA9IGluc3BlY3Qob2JqKVxuICAgICwgdHlwZSA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmopO1xuXG4gIGlmIChjb25maWcudHJ1bmNhdGVUaHJlc2hvbGQgJiYgc3RyLmxlbmd0aCA+PSBjb25maWcudHJ1bmNhdGVUaHJlc2hvbGQpIHtcbiAgICBpZiAodHlwZSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJykge1xuICAgICAgcmV0dXJuICFvYmoubmFtZSB8fCBvYmoubmFtZSA9PT0gJydcbiAgICAgICAgPyAnW0Z1bmN0aW9uXSdcbiAgICAgICAgOiAnW0Z1bmN0aW9uOiAnICsgb2JqLm5hbWUgKyAnXSc7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnW29iamVjdCBBcnJheV0nKSB7XG4gICAgICByZXR1cm4gJ1sgQXJyYXkoJyArIG9iai5sZW5ndGggKyAnKSBdJztcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdbb2JqZWN0IE9iamVjdF0nKSB7XG4gICAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKG9iailcbiAgICAgICAgLCBrc3RyID0ga2V5cy5sZW5ndGggPiAyXG4gICAgICAgICAgPyBrZXlzLnNwbGljZSgwLCAyKS5qb2luKCcsICcpICsgJywgLi4uJ1xuICAgICAgICAgIDoga2V5cy5qb2luKCcsICcpO1xuICAgICAgcmV0dXJuICd7IE9iamVjdCAoJyArIGtzdHIgKyAnKSB9JztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHN0cjtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHN0cjtcbiAgfVxufTtcbiIsICIvKiFcbiAqIENoYWkgLSBtZXNzYWdlIGNvbXBvc2l0aW9uIHV0aWxpdHlcbiAqIENvcHlyaWdodChjKSAyMDEyLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG4vKiFcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXNcbiAqL1xuXG52YXIgZmxhZyA9IHJlcXVpcmUoJy4vZmxhZycpXG4gICwgZ2V0QWN0dWFsID0gcmVxdWlyZSgnLi9nZXRBY3R1YWwnKVxuICAsIG9iakRpc3BsYXkgPSByZXF1aXJlKCcuL29iakRpc3BsYXknKTtcblxuLyoqXG4gKiAjIyMgLmdldE1lc3NhZ2Uob2JqZWN0LCBtZXNzYWdlLCBuZWdhdGVNZXNzYWdlKVxuICpcbiAqIENvbnN0cnVjdCB0aGUgZXJyb3IgbWVzc2FnZSBiYXNlZCBvbiBmbGFnc1xuICogYW5kIHRlbXBsYXRlIHRhZ3MuIFRlbXBsYXRlIHRhZ3Mgd2lsbCByZXR1cm5cbiAqIGEgc3RyaW5naWZpZWQgaW5zcGVjdGlvbiBvZiB0aGUgb2JqZWN0IHJlZmVyZW5jZWQuXG4gKlxuICogTWVzc2FnZSB0ZW1wbGF0ZSB0YWdzOlxuICogLSBgI3t0aGlzfWAgY3VycmVudCBhc3NlcnRlZCBvYmplY3RcbiAqIC0gYCN7YWN0fWAgYWN0dWFsIHZhbHVlXG4gKiAtIGAje2V4cH1gIGV4cGVjdGVkIHZhbHVlXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCAoY29uc3RydWN0ZWQgQXNzZXJ0aW9uKVxuICogQHBhcmFtIHtBcmd1bWVudHN9IGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZS5hc3NlcnQgYXJndW1lbnRzXG4gKiBAbmFtZXNwYWNlIFV0aWxzXG4gKiBAbmFtZSBnZXRNZXNzYWdlXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZ2V0TWVzc2FnZShvYmosIGFyZ3MpIHtcbiAgdmFyIG5lZ2F0ZSA9IGZsYWcob2JqLCAnbmVnYXRlJylcbiAgICAsIHZhbCA9IGZsYWcob2JqLCAnb2JqZWN0JylcbiAgICAsIGV4cGVjdGVkID0gYXJnc1szXVxuICAgICwgYWN0dWFsID0gZ2V0QWN0dWFsKG9iaiwgYXJncylcbiAgICAsIG1zZyA9IG5lZ2F0ZSA/IGFyZ3NbMl0gOiBhcmdzWzFdXG4gICAgLCBmbGFnTXNnID0gZmxhZyhvYmosICdtZXNzYWdlJyk7XG5cbiAgaWYodHlwZW9mIG1zZyA9PT0gXCJmdW5jdGlvblwiKSBtc2cgPSBtc2coKTtcbiAgbXNnID0gbXNnIHx8ICcnO1xuICBtc2cgPSBtc2dcbiAgICAucmVwbGFjZSgvI1xce3RoaXNcXH0vZywgZnVuY3Rpb24gKCkgeyByZXR1cm4gb2JqRGlzcGxheSh2YWwpOyB9KVxuICAgIC5yZXBsYWNlKC8jXFx7YWN0XFx9L2csIGZ1bmN0aW9uICgpIHsgcmV0dXJuIG9iakRpc3BsYXkoYWN0dWFsKTsgfSlcbiAgICAucmVwbGFjZSgvI1xce2V4cFxcfS9nLCBmdW5jdGlvbiAoKSB7IHJldHVybiBvYmpEaXNwbGF5KGV4cGVjdGVkKTsgfSk7XG5cbiAgcmV0dXJuIGZsYWdNc2cgPyBmbGFnTXNnICsgJzogJyArIG1zZyA6IG1zZztcbn07XG4iLCAiLyohXG4gKiBDaGFpIC0gdHJhbnNmZXJGbGFncyB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyoqXG4gKiAjIyMgLnRyYW5zZmVyRmxhZ3MoYXNzZXJ0aW9uLCBvYmplY3QsIGluY2x1ZGVBbGwgPSB0cnVlKVxuICpcbiAqIFRyYW5zZmVyIGFsbCB0aGUgZmxhZ3MgZm9yIGBhc3NlcnRpb25gIHRvIGBvYmplY3RgLiBJZlxuICogYGluY2x1ZGVBbGxgIGlzIHNldCB0byBgZmFsc2VgLCB0aGVuIHRoZSBiYXNlIENoYWlcbiAqIGFzc2VydGlvbiBmbGFncyAobmFtZWx5IGBvYmplY3RgLCBgc3NmaWAsIGBsb2NrU3NmaWAsXG4gKiBhbmQgYG1lc3NhZ2VgKSB3aWxsIG5vdCBiZSB0cmFuc2ZlcnJlZC5cbiAqXG4gKlxuICogICAgIHZhciBuZXdBc3NlcnRpb24gPSBuZXcgQXNzZXJ0aW9uKCk7XG4gKiAgICAgdXRpbHMudHJhbnNmZXJGbGFncyhhc3NlcnRpb24sIG5ld0Fzc2VydGlvbik7XG4gKlxuICogICAgIHZhciBhbm90aGVyQXNzZXJ0aW9uID0gbmV3IEFzc2VydGlvbihteU9iaik7XG4gKiAgICAgdXRpbHMudHJhbnNmZXJGbGFncyhhc3NlcnRpb24sIGFub3RoZXJBc3NlcnRpb24sIGZhbHNlKTtcbiAqXG4gKiBAcGFyYW0ge0Fzc2VydGlvbn0gYXNzZXJ0aW9uIHRoZSBhc3NlcnRpb24gdG8gdHJhbnNmZXIgdGhlIGZsYWdzIGZyb21cbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgdGhlIG9iamVjdCB0byB0cmFuc2ZlciB0aGUgZmxhZ3MgdG87IHVzdWFsbHkgYSBuZXcgYXNzZXJ0aW9uXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGluY2x1ZGVBbGxcbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBuYW1lIHRyYW5zZmVyRmxhZ3NcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gdHJhbnNmZXJGbGFncyhhc3NlcnRpb24sIG9iamVjdCwgaW5jbHVkZUFsbCkge1xuICB2YXIgZmxhZ3MgPSBhc3NlcnRpb24uX19mbGFncyB8fCAoYXNzZXJ0aW9uLl9fZmxhZ3MgPSBPYmplY3QuY3JlYXRlKG51bGwpKTtcblxuICBpZiAoIW9iamVjdC5fX2ZsYWdzKSB7XG4gICAgb2JqZWN0Ll9fZmxhZ3MgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICB9XG5cbiAgaW5jbHVkZUFsbCA9IGFyZ3VtZW50cy5sZW5ndGggPT09IDMgPyBpbmNsdWRlQWxsIDogdHJ1ZTtcblxuICBmb3IgKHZhciBmbGFnIGluIGZsYWdzKSB7XG4gICAgaWYgKGluY2x1ZGVBbGwgfHxcbiAgICAgICAgKGZsYWcgIT09ICdvYmplY3QnICYmIGZsYWcgIT09ICdzc2ZpJyAmJiBmbGFnICE9PSAnbG9ja1NzZmknICYmIGZsYWcgIT0gJ21lc3NhZ2UnKSkge1xuICAgICAgb2JqZWN0Ll9fZmxhZ3NbZmxhZ10gPSBmbGFnc1tmbGFnXTtcbiAgICB9XG4gIH1cbn07XG4iLCAiJ3VzZSBzdHJpY3QnO1xuLyogZ2xvYmFscyBTeW1ib2w6IGZhbHNlLCBVaW50OEFycmF5OiBmYWxzZSwgV2Vha01hcDogZmFsc2UgKi9cbi8qIVxuICogZGVlcC1lcWxcbiAqIENvcHlyaWdodChjKSAyMDEzIEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxudmFyIHR5cGUgPSByZXF1aXJlKCd0eXBlLWRldGVjdCcpO1xuZnVuY3Rpb24gRmFrZU1hcCgpIHtcbiAgdGhpcy5fa2V5ID0gJ2NoYWkvZGVlcC1lcWxfXycgKyBNYXRoLnJhbmRvbSgpICsgRGF0ZS5ub3coKTtcbn1cblxuRmFrZU1hcC5wcm90b3R5cGUgPSB7XG4gIGdldDogZnVuY3Rpb24gZ2V0KGtleSkge1xuICAgIHJldHVybiBrZXlbdGhpcy5fa2V5XTtcbiAgfSxcbiAgc2V0OiBmdW5jdGlvbiBzZXQoa2V5LCB2YWx1ZSkge1xuICAgIGlmIChPYmplY3QuaXNFeHRlbnNpYmxlKGtleSkpIHtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShrZXksIHRoaXMuX2tleSwge1xuICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfSxcbn07XG5cbnZhciBNZW1vaXplTWFwID0gdHlwZW9mIFdlYWtNYXAgPT09ICdmdW5jdGlvbicgPyBXZWFrTWFwIDogRmFrZU1hcDtcbi8qIVxuICogQ2hlY2sgdG8gc2VlIGlmIHRoZSBNZW1vaXplTWFwIGhhcyByZWNvcmRlZCBhIHJlc3VsdCBvZiB0aGUgdHdvIG9wZXJhbmRzXG4gKlxuICogQHBhcmFtIHtNaXhlZH0gbGVmdEhhbmRPcGVyYW5kXG4gKiBAcGFyYW0ge01peGVkfSByaWdodEhhbmRPcGVyYW5kXG4gKiBAcGFyYW0ge01lbW9pemVNYXB9IG1lbW9pemVNYXBcbiAqIEByZXR1cm5zIHtCb29sZWFufG51bGx9IHJlc3VsdFxuKi9cbmZ1bmN0aW9uIG1lbW9pemVDb21wYXJlKGxlZnRIYW5kT3BlcmFuZCwgcmlnaHRIYW5kT3BlcmFuZCwgbWVtb2l6ZU1hcCkge1xuICAvLyBUZWNobmljYWxseSwgV2Vha01hcCBrZXlzIGNhbiAqb25seSogYmUgb2JqZWN0cywgbm90IHByaW1pdGl2ZXMuXG4gIGlmICghbWVtb2l6ZU1hcCB8fCBpc1ByaW1pdGl2ZShsZWZ0SGFuZE9wZXJhbmQpIHx8IGlzUHJpbWl0aXZlKHJpZ2h0SGFuZE9wZXJhbmQpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgdmFyIGxlZnRIYW5kTWFwID0gbWVtb2l6ZU1hcC5nZXQobGVmdEhhbmRPcGVyYW5kKTtcbiAgaWYgKGxlZnRIYW5kTWFwKSB7XG4gICAgdmFyIHJlc3VsdCA9IGxlZnRIYW5kTWFwLmdldChyaWdodEhhbmRPcGVyYW5kKTtcbiAgICBpZiAodHlwZW9mIHJlc3VsdCA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cblxuLyohXG4gKiBTZXQgdGhlIHJlc3VsdCBvZiB0aGUgZXF1YWxpdHkgaW50byB0aGUgTWVtb2l6ZU1hcFxuICpcbiAqIEBwYXJhbSB7TWl4ZWR9IGxlZnRIYW5kT3BlcmFuZFxuICogQHBhcmFtIHtNaXhlZH0gcmlnaHRIYW5kT3BlcmFuZFxuICogQHBhcmFtIHtNZW1vaXplTWFwfSBtZW1vaXplTWFwXG4gKiBAcGFyYW0ge0Jvb2xlYW59IHJlc3VsdFxuKi9cbmZ1bmN0aW9uIG1lbW9pemVTZXQobGVmdEhhbmRPcGVyYW5kLCByaWdodEhhbmRPcGVyYW5kLCBtZW1vaXplTWFwLCByZXN1bHQpIHtcbiAgLy8gVGVjaG5pY2FsbHksIFdlYWtNYXAga2V5cyBjYW4gKm9ubHkqIGJlIG9iamVjdHMsIG5vdCBwcmltaXRpdmVzLlxuICBpZiAoIW1lbW9pemVNYXAgfHwgaXNQcmltaXRpdmUobGVmdEhhbmRPcGVyYW5kKSB8fCBpc1ByaW1pdGl2ZShyaWdodEhhbmRPcGVyYW5kKSkge1xuICAgIHJldHVybjtcbiAgfVxuICB2YXIgbGVmdEhhbmRNYXAgPSBtZW1vaXplTWFwLmdldChsZWZ0SGFuZE9wZXJhbmQpO1xuICBpZiAobGVmdEhhbmRNYXApIHtcbiAgICBsZWZ0SGFuZE1hcC5zZXQocmlnaHRIYW5kT3BlcmFuZCwgcmVzdWx0KTtcbiAgfSBlbHNlIHtcbiAgICBsZWZ0SGFuZE1hcCA9IG5ldyBNZW1vaXplTWFwKCk7XG4gICAgbGVmdEhhbmRNYXAuc2V0KHJpZ2h0SGFuZE9wZXJhbmQsIHJlc3VsdCk7XG4gICAgbWVtb2l6ZU1hcC5zZXQobGVmdEhhbmRPcGVyYW5kLCBsZWZ0SGFuZE1hcCk7XG4gIH1cbn1cblxuLyohXG4gKiBQcmltYXJ5IEV4cG9ydFxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZGVlcEVxdWFsO1xubW9kdWxlLmV4cG9ydHMuTWVtb2l6ZU1hcCA9IE1lbW9pemVNYXA7XG5cbi8qKlxuICogQXNzZXJ0IGRlZXBseSBuZXN0ZWQgc2FtZVZhbHVlIGVxdWFsaXR5IGJldHdlZW4gdHdvIG9iamVjdHMgb2YgYW55IHR5cGUuXG4gKlxuICogQHBhcmFtIHtNaXhlZH0gbGVmdEhhbmRPcGVyYW5kXG4gKiBAcGFyYW0ge01peGVkfSByaWdodEhhbmRPcGVyYW5kXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIChvcHRpb25hbCkgQWRkaXRpb25hbCBvcHRpb25zXG4gKiBAcGFyYW0ge0FycmF5fSBbb3B0aW9ucy5jb21wYXJhdG9yXSAob3B0aW9uYWwpIE92ZXJyaWRlIGRlZmF1bHQgYWxnb3JpdGhtLCBkZXRlcm1pbmluZyBjdXN0b20gZXF1YWxpdHkuXG4gKiBAcGFyYW0ge0FycmF5fSBbb3B0aW9ucy5tZW1vaXplXSAob3B0aW9uYWwpIFByb3ZpZGUgYSBjdXN0b20gbWVtb2l6YXRpb24gb2JqZWN0IHdoaWNoIHdpbGwgY2FjaGUgdGhlIHJlc3VsdHMgb2ZcbiAgICBjb21wbGV4IG9iamVjdHMgZm9yIGEgc3BlZWQgYm9vc3QuIEJ5IHBhc3NpbmcgYGZhbHNlYCB5b3UgY2FuIGRpc2FibGUgbWVtb2l6YXRpb24sIGJ1dCB0aGlzIHdpbGwgY2F1c2UgY2lyY3VsYXJcbiAgICByZWZlcmVuY2VzIHRvIGJsb3cgdGhlIHN0YWNrLlxuICogQHJldHVybiB7Qm9vbGVhbn0gZXF1YWwgbWF0Y2hcbiAqL1xuZnVuY3Rpb24gZGVlcEVxdWFsKGxlZnRIYW5kT3BlcmFuZCwgcmlnaHRIYW5kT3BlcmFuZCwgb3B0aW9ucykge1xuICAvLyBJZiB3ZSBoYXZlIGEgY29tcGFyYXRvciwgd2UgY2FuJ3QgYXNzdW1lIGFueXRoaW5nOyBzbyBiYWlsIHRvIGl0cyBjaGVjayBmaXJzdC5cbiAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5jb21wYXJhdG9yKSB7XG4gICAgcmV0dXJuIGV4dGVuc2l2ZURlZXBFcXVhbChsZWZ0SGFuZE9wZXJhbmQsIHJpZ2h0SGFuZE9wZXJhbmQsIG9wdGlvbnMpO1xuICB9XG5cbiAgdmFyIHNpbXBsZVJlc3VsdCA9IHNpbXBsZUVxdWFsKGxlZnRIYW5kT3BlcmFuZCwgcmlnaHRIYW5kT3BlcmFuZCk7XG4gIGlmIChzaW1wbGVSZXN1bHQgIT09IG51bGwpIHtcbiAgICByZXR1cm4gc2ltcGxlUmVzdWx0O1xuICB9XG5cbiAgLy8gRGVlcGVyIGNvbXBhcmlzb25zIGFyZSBwdXNoZWQgdGhyb3VnaCB0byBhIGxhcmdlciBmdW5jdGlvblxuICByZXR1cm4gZXh0ZW5zaXZlRGVlcEVxdWFsKGxlZnRIYW5kT3BlcmFuZCwgcmlnaHRIYW5kT3BlcmFuZCwgb3B0aW9ucyk7XG59XG5cbi8qKlxuICogTWFueSBjb21wYXJpc29ucyBjYW4gYmUgY2FuY2VsZWQgb3V0IGVhcmx5IHZpYSBzaW1wbGUgZXF1YWxpdHkgb3IgcHJpbWl0aXZlIGNoZWNrcy5cbiAqIEBwYXJhbSB7TWl4ZWR9IGxlZnRIYW5kT3BlcmFuZFxuICogQHBhcmFtIHtNaXhlZH0gcmlnaHRIYW5kT3BlcmFuZFxuICogQHJldHVybiB7Qm9vbGVhbnxudWxsfSBlcXVhbCBtYXRjaFxuICovXG5mdW5jdGlvbiBzaW1wbGVFcXVhbChsZWZ0SGFuZE9wZXJhbmQsIHJpZ2h0SGFuZE9wZXJhbmQpIHtcbiAgLy8gRXF1YWwgcmVmZXJlbmNlcyAoZXhjZXB0IGZvciBOdW1iZXJzKSBjYW4gYmUgcmV0dXJuZWQgZWFybHlcbiAgaWYgKGxlZnRIYW5kT3BlcmFuZCA9PT0gcmlnaHRIYW5kT3BlcmFuZCkge1xuICAgIC8vIEhhbmRsZSArLTAgY2FzZXNcbiAgICByZXR1cm4gbGVmdEhhbmRPcGVyYW5kICE9PSAwIHx8IDEgLyBsZWZ0SGFuZE9wZXJhbmQgPT09IDEgLyByaWdodEhhbmRPcGVyYW5kO1xuICB9XG5cbiAgLy8gaGFuZGxlIE5hTiBjYXNlc1xuICBpZiAoXG4gICAgbGVmdEhhbmRPcGVyYW5kICE9PSBsZWZ0SGFuZE9wZXJhbmQgJiYgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1zZWxmLWNvbXBhcmVcbiAgICByaWdodEhhbmRPcGVyYW5kICE9PSByaWdodEhhbmRPcGVyYW5kIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gICkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLy8gQW55dGhpbmcgdGhhdCBpcyBub3QgYW4gJ29iamVjdCcsIGkuZS4gc3ltYm9scywgZnVuY3Rpb25zLCBib29sZWFucywgbnVtYmVycyxcbiAgLy8gc3RyaW5ncywgYW5kIHVuZGVmaW5lZCwgY2FuIGJlIGNvbXBhcmVkIGJ5IHJlZmVyZW5jZS5cbiAgaWYgKGlzUHJpbWl0aXZlKGxlZnRIYW5kT3BlcmFuZCkgfHwgaXNQcmltaXRpdmUocmlnaHRIYW5kT3BlcmFuZCkpIHtcbiAgICAvLyBFYXN5IG91dCBiL2MgaXQgd291bGQgaGF2ZSBwYXNzZWQgdGhlIGZpcnN0IGVxdWFsaXR5IGNoZWNrXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiBudWxsO1xufVxuXG4vKiFcbiAqIFRoZSBtYWluIGxvZ2ljIG9mIHRoZSBgZGVlcEVxdWFsYCBmdW5jdGlvbi5cbiAqXG4gKiBAcGFyYW0ge01peGVkfSBsZWZ0SGFuZE9wZXJhbmRcbiAqIEBwYXJhbSB7TWl4ZWR9IHJpZ2h0SGFuZE9wZXJhbmRcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc10gKG9wdGlvbmFsKSBBZGRpdGlvbmFsIG9wdGlvbnNcbiAqIEBwYXJhbSB7QXJyYXl9IFtvcHRpb25zLmNvbXBhcmF0b3JdIChvcHRpb25hbCkgT3ZlcnJpZGUgZGVmYXVsdCBhbGdvcml0aG0sIGRldGVybWluaW5nIGN1c3RvbSBlcXVhbGl0eS5cbiAqIEBwYXJhbSB7QXJyYXl9IFtvcHRpb25zLm1lbW9pemVdIChvcHRpb25hbCkgUHJvdmlkZSBhIGN1c3RvbSBtZW1vaXphdGlvbiBvYmplY3Qgd2hpY2ggd2lsbCBjYWNoZSB0aGUgcmVzdWx0cyBvZlxuICAgIGNvbXBsZXggb2JqZWN0cyBmb3IgYSBzcGVlZCBib29zdC4gQnkgcGFzc2luZyBgZmFsc2VgIHlvdSBjYW4gZGlzYWJsZSBtZW1vaXphdGlvbiwgYnV0IHRoaXMgd2lsbCBjYXVzZSBjaXJjdWxhclxuICAgIHJlZmVyZW5jZXMgdG8gYmxvdyB0aGUgc3RhY2suXG4gKiBAcmV0dXJuIHtCb29sZWFufSBlcXVhbCBtYXRjaFxuKi9cbmZ1bmN0aW9uIGV4dGVuc2l2ZURlZXBFcXVhbChsZWZ0SGFuZE9wZXJhbmQsIHJpZ2h0SGFuZE9wZXJhbmQsIG9wdGlvbnMpIHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIG9wdGlvbnMubWVtb2l6ZSA9IG9wdGlvbnMubWVtb2l6ZSA9PT0gZmFsc2UgPyBmYWxzZSA6IG9wdGlvbnMubWVtb2l6ZSB8fCBuZXcgTWVtb2l6ZU1hcCgpO1xuICB2YXIgY29tcGFyYXRvciA9IG9wdGlvbnMgJiYgb3B0aW9ucy5jb21wYXJhdG9yO1xuXG4gIC8vIENoZWNrIGlmIGEgbWVtb2l6ZWQgcmVzdWx0IGV4aXN0cy5cbiAgdmFyIG1lbW9pemVSZXN1bHRMZWZ0ID0gbWVtb2l6ZUNvbXBhcmUobGVmdEhhbmRPcGVyYW5kLCByaWdodEhhbmRPcGVyYW5kLCBvcHRpb25zLm1lbW9pemUpO1xuICBpZiAobWVtb2l6ZVJlc3VsdExlZnQgIT09IG51bGwpIHtcbiAgICByZXR1cm4gbWVtb2l6ZVJlc3VsdExlZnQ7XG4gIH1cbiAgdmFyIG1lbW9pemVSZXN1bHRSaWdodCA9IG1lbW9pemVDb21wYXJlKHJpZ2h0SGFuZE9wZXJhbmQsIGxlZnRIYW5kT3BlcmFuZCwgb3B0aW9ucy5tZW1vaXplKTtcbiAgaWYgKG1lbW9pemVSZXN1bHRSaWdodCAhPT0gbnVsbCkge1xuICAgIHJldHVybiBtZW1vaXplUmVzdWx0UmlnaHQ7XG4gIH1cblxuICAvLyBJZiBhIGNvbXBhcmF0b3IgaXMgcHJlc2VudCwgdXNlIGl0LlxuICBpZiAoY29tcGFyYXRvcikge1xuICAgIHZhciBjb21wYXJhdG9yUmVzdWx0ID0gY29tcGFyYXRvcihsZWZ0SGFuZE9wZXJhbmQsIHJpZ2h0SGFuZE9wZXJhbmQpO1xuICAgIC8vIENvbXBhcmF0b3JzIG1heSByZXR1cm4gbnVsbCwgaW4gd2hpY2ggY2FzZSB3ZSB3YW50IHRvIGdvIGJhY2sgdG8gZGVmYXVsdCBiZWhhdmlvci5cbiAgICBpZiAoY29tcGFyYXRvclJlc3VsdCA9PT0gZmFsc2UgfHwgY29tcGFyYXRvclJlc3VsdCA9PT0gdHJ1ZSkge1xuICAgICAgbWVtb2l6ZVNldChsZWZ0SGFuZE9wZXJhbmQsIHJpZ2h0SGFuZE9wZXJhbmQsIG9wdGlvbnMubWVtb2l6ZSwgY29tcGFyYXRvclJlc3VsdCk7XG4gICAgICByZXR1cm4gY29tcGFyYXRvclJlc3VsdDtcbiAgICB9XG4gICAgLy8gVG8gYWxsb3cgY29tcGFyYXRvcnMgdG8gb3ZlcnJpZGUgKmFueSogYmVoYXZpb3IsIHdlIHJhbiB0aGVtIGZpcnN0LiBTaW5jZSBpdCBkaWRuJ3QgZGVjaWRlXG4gICAgLy8gd2hhdCB0byBkbywgd2UgbmVlZCB0byBtYWtlIHN1cmUgdG8gcmV0dXJuIHRoZSBiYXNpYyB0ZXN0cyBmaXJzdCBiZWZvcmUgd2UgbW92ZSBvbi5cbiAgICB2YXIgc2ltcGxlUmVzdWx0ID0gc2ltcGxlRXF1YWwobGVmdEhhbmRPcGVyYW5kLCByaWdodEhhbmRPcGVyYW5kKTtcbiAgICBpZiAoc2ltcGxlUmVzdWx0ICE9PSBudWxsKSB7XG4gICAgICAvLyBEb24ndCBtZW1vaXplIHRoaXMsIGl0IHRha2VzIGxvbmdlciB0byBzZXQvcmV0cmlldmUgdGhhbiB0byBqdXN0IGNvbXBhcmUuXG4gICAgICByZXR1cm4gc2ltcGxlUmVzdWx0O1xuICAgIH1cbiAgfVxuXG4gIHZhciBsZWZ0SGFuZFR5cGUgPSB0eXBlKGxlZnRIYW5kT3BlcmFuZCk7XG4gIGlmIChsZWZ0SGFuZFR5cGUgIT09IHR5cGUocmlnaHRIYW5kT3BlcmFuZCkpIHtcbiAgICBtZW1vaXplU2V0KGxlZnRIYW5kT3BlcmFuZCwgcmlnaHRIYW5kT3BlcmFuZCwgb3B0aW9ucy5tZW1vaXplLCBmYWxzZSk7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLy8gVGVtcG9yYXJpbHkgc2V0IHRoZSBvcGVyYW5kcyBpbiB0aGUgbWVtb2l6ZSBvYmplY3QgdG8gcHJldmVudCBibG93aW5nIHRoZSBzdGFja1xuICBtZW1vaXplU2V0KGxlZnRIYW5kT3BlcmFuZCwgcmlnaHRIYW5kT3BlcmFuZCwgb3B0aW9ucy5tZW1vaXplLCB0cnVlKTtcblxuICB2YXIgcmVzdWx0ID0gZXh0ZW5zaXZlRGVlcEVxdWFsQnlUeXBlKGxlZnRIYW5kT3BlcmFuZCwgcmlnaHRIYW5kT3BlcmFuZCwgbGVmdEhhbmRUeXBlLCBvcHRpb25zKTtcbiAgbWVtb2l6ZVNldChsZWZ0SGFuZE9wZXJhbmQsIHJpZ2h0SGFuZE9wZXJhbmQsIG9wdGlvbnMubWVtb2l6ZSwgcmVzdWx0KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gZXh0ZW5zaXZlRGVlcEVxdWFsQnlUeXBlKGxlZnRIYW5kT3BlcmFuZCwgcmlnaHRIYW5kT3BlcmFuZCwgbGVmdEhhbmRUeXBlLCBvcHRpb25zKSB7XG4gIHN3aXRjaCAobGVmdEhhbmRUeXBlKSB7XG4gICAgY2FzZSAnU3RyaW5nJzpcbiAgICBjYXNlICdOdW1iZXInOlxuICAgIGNhc2UgJ0Jvb2xlYW4nOlxuICAgIGNhc2UgJ0RhdGUnOlxuICAgICAgLy8gSWYgdGhlc2UgdHlwZXMgYXJlIHRoZWlyIGluc3RhbmNlIHR5cGVzIChlLmcuIGBuZXcgTnVtYmVyYCkgdGhlbiByZS1kZWVwRXF1YWwgYWdhaW5zdCB0aGVpciB2YWx1ZXNcbiAgICAgIHJldHVybiBkZWVwRXF1YWwobGVmdEhhbmRPcGVyYW5kLnZhbHVlT2YoKSwgcmlnaHRIYW5kT3BlcmFuZC52YWx1ZU9mKCkpO1xuICAgIGNhc2UgJ1Byb21pc2UnOlxuICAgIGNhc2UgJ1N5bWJvbCc6XG4gICAgY2FzZSAnZnVuY3Rpb24nOlxuICAgIGNhc2UgJ1dlYWtNYXAnOlxuICAgIGNhc2UgJ1dlYWtTZXQnOlxuICAgICAgcmV0dXJuIGxlZnRIYW5kT3BlcmFuZCA9PT0gcmlnaHRIYW5kT3BlcmFuZDtcbiAgICBjYXNlICdFcnJvcic6XG4gICAgICByZXR1cm4ga2V5c0VxdWFsKGxlZnRIYW5kT3BlcmFuZCwgcmlnaHRIYW5kT3BlcmFuZCwgWyAnbmFtZScsICdtZXNzYWdlJywgJ2NvZGUnIF0sIG9wdGlvbnMpO1xuICAgIGNhc2UgJ0FyZ3VtZW50cyc6XG4gICAgY2FzZSAnSW50OEFycmF5JzpcbiAgICBjYXNlICdVaW50OEFycmF5JzpcbiAgICBjYXNlICdVaW50OENsYW1wZWRBcnJheSc6XG4gICAgY2FzZSAnSW50MTZBcnJheSc6XG4gICAgY2FzZSAnVWludDE2QXJyYXknOlxuICAgIGNhc2UgJ0ludDMyQXJyYXknOlxuICAgIGNhc2UgJ1VpbnQzMkFycmF5JzpcbiAgICBjYXNlICdGbG9hdDMyQXJyYXknOlxuICAgIGNhc2UgJ0Zsb2F0NjRBcnJheSc6XG4gICAgY2FzZSAnQXJyYXknOlxuICAgICAgcmV0dXJuIGl0ZXJhYmxlRXF1YWwobGVmdEhhbmRPcGVyYW5kLCByaWdodEhhbmRPcGVyYW5kLCBvcHRpb25zKTtcbiAgICBjYXNlICdSZWdFeHAnOlxuICAgICAgcmV0dXJuIHJlZ2V4cEVxdWFsKGxlZnRIYW5kT3BlcmFuZCwgcmlnaHRIYW5kT3BlcmFuZCk7XG4gICAgY2FzZSAnR2VuZXJhdG9yJzpcbiAgICAgIHJldHVybiBnZW5lcmF0b3JFcXVhbChsZWZ0SGFuZE9wZXJhbmQsIHJpZ2h0SGFuZE9wZXJhbmQsIG9wdGlvbnMpO1xuICAgIGNhc2UgJ0RhdGFWaWV3JzpcbiAgICAgIHJldHVybiBpdGVyYWJsZUVxdWFsKG5ldyBVaW50OEFycmF5KGxlZnRIYW5kT3BlcmFuZC5idWZmZXIpLCBuZXcgVWludDhBcnJheShyaWdodEhhbmRPcGVyYW5kLmJ1ZmZlciksIG9wdGlvbnMpO1xuICAgIGNhc2UgJ0FycmF5QnVmZmVyJzpcbiAgICAgIHJldHVybiBpdGVyYWJsZUVxdWFsKG5ldyBVaW50OEFycmF5KGxlZnRIYW5kT3BlcmFuZCksIG5ldyBVaW50OEFycmF5KHJpZ2h0SGFuZE9wZXJhbmQpLCBvcHRpb25zKTtcbiAgICBjYXNlICdTZXQnOlxuICAgICAgcmV0dXJuIGVudHJpZXNFcXVhbChsZWZ0SGFuZE9wZXJhbmQsIHJpZ2h0SGFuZE9wZXJhbmQsIG9wdGlvbnMpO1xuICAgIGNhc2UgJ01hcCc6XG4gICAgICByZXR1cm4gZW50cmllc0VxdWFsKGxlZnRIYW5kT3BlcmFuZCwgcmlnaHRIYW5kT3BlcmFuZCwgb3B0aW9ucyk7XG4gICAgY2FzZSAnVGVtcG9yYWwuUGxhaW5EYXRlJzpcbiAgICBjYXNlICdUZW1wb3JhbC5QbGFpblRpbWUnOlxuICAgIGNhc2UgJ1RlbXBvcmFsLlBsYWluRGF0ZVRpbWUnOlxuICAgIGNhc2UgJ1RlbXBvcmFsLkluc3RhbnQnOlxuICAgIGNhc2UgJ1RlbXBvcmFsLlpvbmVkRGF0ZVRpbWUnOlxuICAgIGNhc2UgJ1RlbXBvcmFsLlBsYWluWWVhck1vbnRoJzpcbiAgICBjYXNlICdUZW1wb3JhbC5QbGFpbk1vbnRoRGF5JzpcbiAgICAgIHJldHVybiBsZWZ0SGFuZE9wZXJhbmQuZXF1YWxzKHJpZ2h0SGFuZE9wZXJhbmQpO1xuICAgIGNhc2UgJ1RlbXBvcmFsLkR1cmF0aW9uJzpcbiAgICAgIHJldHVybiBsZWZ0SGFuZE9wZXJhbmQudG90YWwoJ25hbm9zZWNvbmRzJykgPT09IHJpZ2h0SGFuZE9wZXJhbmQudG90YWwoJ25hbm9zZWNvbmRzJyk7XG4gICAgY2FzZSAnVGVtcG9yYWwuVGltZVpvbmUnOlxuICAgIGNhc2UgJ1RlbXBvcmFsLkNhbGVuZGFyJzpcbiAgICAgIHJldHVybiBsZWZ0SGFuZE9wZXJhbmQudG9TdHJpbmcoKSA9PT0gcmlnaHRIYW5kT3BlcmFuZC50b1N0cmluZygpO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gb2JqZWN0RXF1YWwobGVmdEhhbmRPcGVyYW5kLCByaWdodEhhbmRPcGVyYW5kLCBvcHRpb25zKTtcbiAgfVxufVxuXG4vKiFcbiAqIENvbXBhcmUgdHdvIFJlZ3VsYXIgRXhwcmVzc2lvbnMgZm9yIGVxdWFsaXR5LlxuICpcbiAqIEBwYXJhbSB7UmVnRXhwfSBsZWZ0SGFuZE9wZXJhbmRcbiAqIEBwYXJhbSB7UmVnRXhwfSByaWdodEhhbmRPcGVyYW5kXG4gKiBAcmV0dXJuIHtCb29sZWFufSByZXN1bHRcbiAqL1xuXG5mdW5jdGlvbiByZWdleHBFcXVhbChsZWZ0SGFuZE9wZXJhbmQsIHJpZ2h0SGFuZE9wZXJhbmQpIHtcbiAgcmV0dXJuIGxlZnRIYW5kT3BlcmFuZC50b1N0cmluZygpID09PSByaWdodEhhbmRPcGVyYW5kLnRvU3RyaW5nKCk7XG59XG5cbi8qIVxuICogQ29tcGFyZSB0d28gU2V0cy9NYXBzIGZvciBlcXVhbGl0eS4gRmFzdGVyIHRoYW4gb3RoZXIgZXF1YWxpdHkgZnVuY3Rpb25zLlxuICpcbiAqIEBwYXJhbSB7U2V0fSBsZWZ0SGFuZE9wZXJhbmRcbiAqIEBwYXJhbSB7U2V0fSByaWdodEhhbmRPcGVyYW5kXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIChPcHRpb25hbClcbiAqIEByZXR1cm4ge0Jvb2xlYW59IHJlc3VsdFxuICovXG5cbmZ1bmN0aW9uIGVudHJpZXNFcXVhbChsZWZ0SGFuZE9wZXJhbmQsIHJpZ2h0SGFuZE9wZXJhbmQsIG9wdGlvbnMpIHtcbiAgLy8gSUUxMSBkb2Vzbid0IHN1cHBvcnQgU2V0I2VudHJpZXMgb3IgU2V0I0BAaXRlcmF0b3IsIHNvIHdlIG5lZWQgbWFudWFsbHkgcG9wdWxhdGUgdXNpbmcgU2V0I2ZvckVhY2hcbiAgaWYgKGxlZnRIYW5kT3BlcmFuZC5zaXplICE9PSByaWdodEhhbmRPcGVyYW5kLnNpemUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKGxlZnRIYW5kT3BlcmFuZC5zaXplID09PSAwKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgdmFyIGxlZnRIYW5kSXRlbXMgPSBbXTtcbiAgdmFyIHJpZ2h0SGFuZEl0ZW1zID0gW107XG4gIGxlZnRIYW5kT3BlcmFuZC5mb3JFYWNoKGZ1bmN0aW9uIGdhdGhlckVudHJpZXMoa2V5LCB2YWx1ZSkge1xuICAgIGxlZnRIYW5kSXRlbXMucHVzaChbIGtleSwgdmFsdWUgXSk7XG4gIH0pO1xuICByaWdodEhhbmRPcGVyYW5kLmZvckVhY2goZnVuY3Rpb24gZ2F0aGVyRW50cmllcyhrZXksIHZhbHVlKSB7XG4gICAgcmlnaHRIYW5kSXRlbXMucHVzaChbIGtleSwgdmFsdWUgXSk7XG4gIH0pO1xuICByZXR1cm4gaXRlcmFibGVFcXVhbChsZWZ0SGFuZEl0ZW1zLnNvcnQoKSwgcmlnaHRIYW5kSXRlbXMuc29ydCgpLCBvcHRpb25zKTtcbn1cblxuLyohXG4gKiBTaW1wbGUgZXF1YWxpdHkgZm9yIGZsYXQgaXRlcmFibGUgb2JqZWN0cyBzdWNoIGFzIEFycmF5cywgVHlwZWRBcnJheXMgb3IgTm9kZS5qcyBidWZmZXJzLlxuICpcbiAqIEBwYXJhbSB7SXRlcmFibGV9IGxlZnRIYW5kT3BlcmFuZFxuICogQHBhcmFtIHtJdGVyYWJsZX0gcmlnaHRIYW5kT3BlcmFuZFxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXSAoT3B0aW9uYWwpXG4gKiBAcmV0dXJuIHtCb29sZWFufSByZXN1bHRcbiAqL1xuXG5mdW5jdGlvbiBpdGVyYWJsZUVxdWFsKGxlZnRIYW5kT3BlcmFuZCwgcmlnaHRIYW5kT3BlcmFuZCwgb3B0aW9ucykge1xuICB2YXIgbGVuZ3RoID0gbGVmdEhhbmRPcGVyYW5kLmxlbmd0aDtcbiAgaWYgKGxlbmd0aCAhPT0gcmlnaHRIYW5kT3BlcmFuZC5sZW5ndGgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKGxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHZhciBpbmRleCA9IC0xO1xuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIGlmIChkZWVwRXF1YWwobGVmdEhhbmRPcGVyYW5kW2luZGV4XSwgcmlnaHRIYW5kT3BlcmFuZFtpbmRleF0sIG9wdGlvbnMpID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyohXG4gKiBTaW1wbGUgZXF1YWxpdHkgZm9yIGdlbmVyYXRvciBvYmplY3RzIHN1Y2ggYXMgdGhvc2UgcmV0dXJuZWQgYnkgZ2VuZXJhdG9yIGZ1bmN0aW9ucy5cbiAqXG4gKiBAcGFyYW0ge0l0ZXJhYmxlfSBsZWZ0SGFuZE9wZXJhbmRcbiAqIEBwYXJhbSB7SXRlcmFibGV9IHJpZ2h0SGFuZE9wZXJhbmRcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc10gKE9wdGlvbmFsKVxuICogQHJldHVybiB7Qm9vbGVhbn0gcmVzdWx0XG4gKi9cblxuZnVuY3Rpb24gZ2VuZXJhdG9yRXF1YWwobGVmdEhhbmRPcGVyYW5kLCByaWdodEhhbmRPcGVyYW5kLCBvcHRpb25zKSB7XG4gIHJldHVybiBpdGVyYWJsZUVxdWFsKGdldEdlbmVyYXRvckVudHJpZXMobGVmdEhhbmRPcGVyYW5kKSwgZ2V0R2VuZXJhdG9yRW50cmllcyhyaWdodEhhbmRPcGVyYW5kKSwgb3B0aW9ucyk7XG59XG5cbi8qIVxuICogRGV0ZXJtaW5lIGlmIHRoZSBnaXZlbiBvYmplY3QgaGFzIGFuIEBAaXRlcmF0b3IgZnVuY3Rpb24uXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHRhcmdldFxuICogQHJldHVybiB7Qm9vbGVhbn0gYHRydWVgIGlmIHRoZSBvYmplY3QgaGFzIGFuIEBAaXRlcmF0b3IgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGhhc0l0ZXJhdG9yRnVuY3Rpb24odGFyZ2V0KSB7XG4gIHJldHVybiB0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJlxuICAgIHR5cGVvZiB0YXJnZXQgPT09ICdvYmplY3QnICYmXG4gICAgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICB0eXBlb2YgdGFyZ2V0W1N5bWJvbC5pdGVyYXRvcl0gPT09ICdmdW5jdGlvbic7XG59XG5cbi8qIVxuICogR2V0cyBhbGwgaXRlcmF0b3IgZW50cmllcyBmcm9tIHRoZSBnaXZlbiBPYmplY3QuIElmIHRoZSBPYmplY3QgaGFzIG5vIEBAaXRlcmF0b3IgZnVuY3Rpb24sIHJldHVybnMgYW4gZW1wdHkgYXJyYXkuXG4gKiBUaGlzIHdpbGwgY29uc3VtZSB0aGUgaXRlcmF0b3IgLSB3aGljaCBjb3VsZCBoYXZlIHNpZGUgZWZmZWN0cyBkZXBlbmRpbmcgb24gdGhlIEBAaXRlcmF0b3IgaW1wbGVtZW50YXRpb24uXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHRhcmdldFxuICogQHJldHVybnMge0FycmF5fSBhbiBhcnJheSBvZiBlbnRyaWVzIGZyb20gdGhlIEBAaXRlcmF0b3IgZnVuY3Rpb25cbiAqL1xuZnVuY3Rpb24gZ2V0SXRlcmF0b3JFbnRyaWVzKHRhcmdldCkge1xuICBpZiAoaGFzSXRlcmF0b3JGdW5jdGlvbih0YXJnZXQpKSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBnZXRHZW5lcmF0b3JFbnRyaWVzKHRhcmdldFtTeW1ib2wuaXRlcmF0b3JdKCkpO1xuICAgIH0gY2F0Y2ggKGl0ZXJhdG9yRXJyb3IpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIFtdO1xufVxuXG4vKiFcbiAqIEdldHMgYWxsIGVudHJpZXMgZnJvbSBhIEdlbmVyYXRvci4gVGhpcyB3aWxsIGNvbnN1bWUgdGhlIGdlbmVyYXRvciAtIHdoaWNoIGNvdWxkIGhhdmUgc2lkZSBlZmZlY3RzLlxuICpcbiAqIEBwYXJhbSB7R2VuZXJhdG9yfSB0YXJnZXRcbiAqIEByZXR1cm5zIHtBcnJheX0gYW4gYXJyYXkgb2YgZW50cmllcyBmcm9tIHRoZSBHZW5lcmF0b3IuXG4gKi9cbmZ1bmN0aW9uIGdldEdlbmVyYXRvckVudHJpZXMoZ2VuZXJhdG9yKSB7XG4gIHZhciBnZW5lcmF0b3JSZXN1bHQgPSBnZW5lcmF0b3IubmV4dCgpO1xuICB2YXIgYWNjdW11bGF0b3IgPSBbIGdlbmVyYXRvclJlc3VsdC52YWx1ZSBdO1xuICB3aGlsZSAoZ2VuZXJhdG9yUmVzdWx0LmRvbmUgPT09IGZhbHNlKSB7XG4gICAgZ2VuZXJhdG9yUmVzdWx0ID0gZ2VuZXJhdG9yLm5leHQoKTtcbiAgICBhY2N1bXVsYXRvci5wdXNoKGdlbmVyYXRvclJlc3VsdC52YWx1ZSk7XG4gIH1cbiAgcmV0dXJuIGFjY3VtdWxhdG9yO1xufVxuXG4vKiFcbiAqIEdldHMgYWxsIG93biBhbmQgaW5oZXJpdGVkIGVudW1lcmFibGUga2V5cyBmcm9tIGEgdGFyZ2V0LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB0YXJnZXRcbiAqIEByZXR1cm5zIHtBcnJheX0gYW4gYXJyYXkgb2Ygb3duIGFuZCBpbmhlcml0ZWQgZW51bWVyYWJsZSBrZXlzIGZyb20gdGhlIHRhcmdldC5cbiAqL1xuZnVuY3Rpb24gZ2V0RW51bWVyYWJsZUtleXModGFyZ2V0KSB7XG4gIHZhciBrZXlzID0gW107XG4gIGZvciAodmFyIGtleSBpbiB0YXJnZXQpIHtcbiAgICBrZXlzLnB1c2goa2V5KTtcbiAgfVxuICByZXR1cm4ga2V5cztcbn1cblxuZnVuY3Rpb24gZ2V0RW51bWVyYWJsZVN5bWJvbHModGFyZ2V0KSB7XG4gIHZhciBrZXlzID0gW107XG4gIHZhciBhbGxLZXlzID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyh0YXJnZXQpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFsbEtleXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICB2YXIga2V5ID0gYWxsS2V5c1tpXTtcbiAgICBpZiAoT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIGtleSkuZW51bWVyYWJsZSkge1xuICAgICAga2V5cy5wdXNoKGtleSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBrZXlzO1xufVxuXG4vKiFcbiAqIERldGVybWluZXMgaWYgdHdvIG9iamVjdHMgaGF2ZSBtYXRjaGluZyB2YWx1ZXMsIGdpdmVuIGEgc2V0IG9mIGtleXMuIERlZmVycyB0byBkZWVwRXF1YWwgZm9yIHRoZSBlcXVhbGl0eSBjaGVjayBvZlxuICogZWFjaCBrZXkuIElmIGFueSB2YWx1ZSBvZiB0aGUgZ2l2ZW4ga2V5IGlzIG5vdCBlcXVhbCwgdGhlIGZ1bmN0aW9uIHdpbGwgcmV0dXJuIGZhbHNlIChlYXJseSkuXG4gKlxuICogQHBhcmFtIHtNaXhlZH0gbGVmdEhhbmRPcGVyYW5kXG4gKiBAcGFyYW0ge01peGVkfSByaWdodEhhbmRPcGVyYW5kXG4gKiBAcGFyYW0ge0FycmF5fSBrZXlzIEFuIGFycmF5IG9mIGtleXMgdG8gY29tcGFyZSB0aGUgdmFsdWVzIG9mIGxlZnRIYW5kT3BlcmFuZCBhbmQgcmlnaHRIYW5kT3BlcmFuZCBhZ2FpbnN0XG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIChPcHRpb25hbClcbiAqIEByZXR1cm4ge0Jvb2xlYW59IHJlc3VsdFxuICovXG5mdW5jdGlvbiBrZXlzRXF1YWwobGVmdEhhbmRPcGVyYW5kLCByaWdodEhhbmRPcGVyYW5kLCBrZXlzLCBvcHRpb25zKSB7XG4gIHZhciBsZW5ndGggPSBrZXlzLmxlbmd0aDtcbiAgaWYgKGxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICBpZiAoZGVlcEVxdWFsKGxlZnRIYW5kT3BlcmFuZFtrZXlzW2ldXSwgcmlnaHRIYW5kT3BlcmFuZFtrZXlzW2ldXSwgb3B0aW9ucykgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG4vKiFcbiAqIFJlY3Vyc2l2ZWx5IGNoZWNrIHRoZSBlcXVhbGl0eSBvZiB0d28gT2JqZWN0cy4gT25jZSBiYXNpYyBzYW1lbmVzcyBoYXMgYmVlbiBlc3RhYmxpc2hlZCBpdCB3aWxsIGRlZmVyIHRvIGBkZWVwRXF1YWxgXG4gKiBmb3IgZWFjaCBlbnVtZXJhYmxlIGtleSBpbiB0aGUgb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7TWl4ZWR9IGxlZnRIYW5kT3BlcmFuZFxuICogQHBhcmFtIHtNaXhlZH0gcmlnaHRIYW5kT3BlcmFuZFxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXSAoT3B0aW9uYWwpXG4gKiBAcmV0dXJuIHtCb29sZWFufSByZXN1bHRcbiAqL1xuZnVuY3Rpb24gb2JqZWN0RXF1YWwobGVmdEhhbmRPcGVyYW5kLCByaWdodEhhbmRPcGVyYW5kLCBvcHRpb25zKSB7XG4gIHZhciBsZWZ0SGFuZEtleXMgPSBnZXRFbnVtZXJhYmxlS2V5cyhsZWZ0SGFuZE9wZXJhbmQpO1xuICB2YXIgcmlnaHRIYW5kS2V5cyA9IGdldEVudW1lcmFibGVLZXlzKHJpZ2h0SGFuZE9wZXJhbmQpO1xuICB2YXIgbGVmdEhhbmRTeW1ib2xzID0gZ2V0RW51bWVyYWJsZVN5bWJvbHMobGVmdEhhbmRPcGVyYW5kKTtcbiAgdmFyIHJpZ2h0SGFuZFN5bWJvbHMgPSBnZXRFbnVtZXJhYmxlU3ltYm9scyhyaWdodEhhbmRPcGVyYW5kKTtcbiAgbGVmdEhhbmRLZXlzID0gbGVmdEhhbmRLZXlzLmNvbmNhdChsZWZ0SGFuZFN5bWJvbHMpO1xuICByaWdodEhhbmRLZXlzID0gcmlnaHRIYW5kS2V5cy5jb25jYXQocmlnaHRIYW5kU3ltYm9scyk7XG5cbiAgaWYgKGxlZnRIYW5kS2V5cy5sZW5ndGggJiYgbGVmdEhhbmRLZXlzLmxlbmd0aCA9PT0gcmlnaHRIYW5kS2V5cy5sZW5ndGgpIHtcbiAgICBpZiAoaXRlcmFibGVFcXVhbChtYXBTeW1ib2xzKGxlZnRIYW5kS2V5cykuc29ydCgpLCBtYXBTeW1ib2xzKHJpZ2h0SGFuZEtleXMpLnNvcnQoKSkgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiBrZXlzRXF1YWwobGVmdEhhbmRPcGVyYW5kLCByaWdodEhhbmRPcGVyYW5kLCBsZWZ0SGFuZEtleXMsIG9wdGlvbnMpO1xuICB9XG5cbiAgdmFyIGxlZnRIYW5kRW50cmllcyA9IGdldEl0ZXJhdG9yRW50cmllcyhsZWZ0SGFuZE9wZXJhbmQpO1xuICB2YXIgcmlnaHRIYW5kRW50cmllcyA9IGdldEl0ZXJhdG9yRW50cmllcyhyaWdodEhhbmRPcGVyYW5kKTtcbiAgaWYgKGxlZnRIYW5kRW50cmllcy5sZW5ndGggJiYgbGVmdEhhbmRFbnRyaWVzLmxlbmd0aCA9PT0gcmlnaHRIYW5kRW50cmllcy5sZW5ndGgpIHtcbiAgICBsZWZ0SGFuZEVudHJpZXMuc29ydCgpO1xuICAgIHJpZ2h0SGFuZEVudHJpZXMuc29ydCgpO1xuICAgIHJldHVybiBpdGVyYWJsZUVxdWFsKGxlZnRIYW5kRW50cmllcywgcmlnaHRIYW5kRW50cmllcywgb3B0aW9ucyk7XG4gIH1cblxuICBpZiAobGVmdEhhbmRLZXlzLmxlbmd0aCA9PT0gMCAmJlxuICAgICAgbGVmdEhhbmRFbnRyaWVzLmxlbmd0aCA9PT0gMCAmJlxuICAgICAgcmlnaHRIYW5kS2V5cy5sZW5ndGggPT09IDAgJiZcbiAgICAgIHJpZ2h0SGFuZEVudHJpZXMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qIVxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBhcmd1bWVudCBpcyBhIHByaW1pdGl2ZS5cbiAqXG4gKiBUaGlzIGludGVudGlvbmFsbHkgcmV0dXJucyB0cnVlIGZvciBhbGwgb2JqZWN0cyB0aGF0IGNhbiBiZSBjb21wYXJlZCBieSByZWZlcmVuY2UsXG4gKiBpbmNsdWRpbmcgZnVuY3Rpb25zIGFuZCBzeW1ib2xzLlxuICpcbiAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gKiBAcmV0dXJuIHtCb29sZWFufSByZXN1bHRcbiAqL1xuZnVuY3Rpb24gaXNQcmltaXRpdmUodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlID09PSBudWxsIHx8IHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCc7XG59XG5cbmZ1bmN0aW9uIG1hcFN5bWJvbHMoYXJyKSB7XG4gIHJldHVybiBhcnIubWFwKGZ1bmN0aW9uIG1hcFN5bWJvbChlbnRyeSkge1xuICAgIGlmICh0eXBlb2YgZW50cnkgPT09ICdzeW1ib2wnKSB7XG4gICAgICByZXR1cm4gZW50cnkudG9TdHJpbmcoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZW50cnk7XG4gIH0pO1xufVxuIiwgInZhciBjb25maWcgPSByZXF1aXJlKCcuLi9jb25maWcnKTtcblxuLyohXG4gKiBDaGFpIC0gaXNQcm94eUVuYWJsZWQgaGVscGVyXG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyoqXG4gKiAjIyMgLmlzUHJveHlFbmFibGVkKClcbiAqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdG8gY2hlY2sgaWYgQ2hhaSdzIHByb3h5IHByb3RlY3Rpb24gZmVhdHVyZSBpcyBlbmFibGVkLiBJZlxuICogcHJveGllcyBhcmUgdW5zdXBwb3J0ZWQgb3IgZGlzYWJsZWQgdmlhIHRoZSB1c2VyJ3MgQ2hhaSBjb25maWcsIHRoZW4gcmV0dXJuXG4gKiBmYWxzZS4gT3RoZXJ3aXNlLCByZXR1cm4gdHJ1ZS5cbiAqXG4gKiBAbmFtZXNwYWNlIFV0aWxzXG4gKiBAbmFtZSBpc1Byb3h5RW5hYmxlZFxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNQcm94eUVuYWJsZWQoKSB7XG4gIHJldHVybiBjb25maWcudXNlUHJveHkgJiZcbiAgICB0eXBlb2YgUHJveHkgIT09ICd1bmRlZmluZWQnICYmXG4gICAgdHlwZW9mIFJlZmxlY3QgIT09ICd1bmRlZmluZWQnO1xufTtcbiIsICIvKiFcbiAqIENoYWkgLSBhZGRQcm9wZXJ0eSB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxudmFyIGNoYWkgPSByZXF1aXJlKCcuLi8uLi9jaGFpJyk7XG52YXIgZmxhZyA9IHJlcXVpcmUoJy4vZmxhZycpO1xudmFyIGlzUHJveHlFbmFibGVkID0gcmVxdWlyZSgnLi9pc1Byb3h5RW5hYmxlZCcpO1xudmFyIHRyYW5zZmVyRmxhZ3MgPSByZXF1aXJlKCcuL3RyYW5zZmVyRmxhZ3MnKTtcblxuLyoqXG4gKiAjIyMgLmFkZFByb3BlcnR5KGN0eCwgbmFtZSwgZ2V0dGVyKVxuICpcbiAqIEFkZHMgYSBwcm9wZXJ0eSB0byB0aGUgcHJvdG90eXBlIG9mIGFuIG9iamVjdC5cbiAqXG4gKiAgICAgdXRpbHMuYWRkUHJvcGVydHkoY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLCAnZm9vJywgZnVuY3Rpb24gKCkge1xuICogICAgICAgdmFyIG9iaiA9IHV0aWxzLmZsYWcodGhpcywgJ29iamVjdCcpO1xuICogICAgICAgbmV3IGNoYWkuQXNzZXJ0aW9uKG9iaikudG8uYmUuaW5zdGFuY2VvZihGb28pO1xuICogICAgIH0pO1xuICpcbiAqIENhbiBhbHNvIGJlIGFjY2Vzc2VkIGRpcmVjdGx5IGZyb20gYGNoYWkuQXNzZXJ0aW9uYC5cbiAqXG4gKiAgICAgY2hhaS5Bc3NlcnRpb24uYWRkUHJvcGVydHkoJ2ZvbycsIGZuKTtcbiAqXG4gKiBUaGVuIGNhbiBiZSB1c2VkIGFzIGFueSBvdGhlciBhc3NlcnRpb24uXG4gKlxuICogICAgIGV4cGVjdChteUZvbykudG8uYmUuZm9vO1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjdHggb2JqZWN0IHRvIHdoaWNoIHRoZSBwcm9wZXJ0eSBpcyBhZGRlZFxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgb2YgcHJvcGVydHkgdG8gYWRkXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBnZXR0ZXIgZnVuY3Rpb24gdG8gYmUgdXNlZCBmb3IgbmFtZVxuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQG5hbWUgYWRkUHJvcGVydHlcbiAqIEBhcGkgcHVibGljXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBhZGRQcm9wZXJ0eShjdHgsIG5hbWUsIGdldHRlcikge1xuICBnZXR0ZXIgPSBnZXR0ZXIgPT09IHVuZGVmaW5lZCA/IGZ1bmN0aW9uICgpIHt9IDogZ2V0dGVyO1xuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjdHgsIG5hbWUsXG4gICAgeyBnZXQ6IGZ1bmN0aW9uIHByb3BlcnR5R2V0dGVyKCkge1xuICAgICAgICAvLyBTZXR0aW5nIHRoZSBgc3NmaWAgZmxhZyB0byBgcHJvcGVydHlHZXR0ZXJgIGNhdXNlcyB0aGlzIGZ1bmN0aW9uIHRvXG4gICAgICAgIC8vIGJlIHRoZSBzdGFydGluZyBwb2ludCBmb3IgcmVtb3ZpbmcgaW1wbGVtZW50YXRpb24gZnJhbWVzIGZyb20gdGhlXG4gICAgICAgIC8vIHN0YWNrIHRyYWNlIG9mIGEgZmFpbGVkIGFzc2VydGlvbi5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gSG93ZXZlciwgd2Ugb25seSB3YW50IHRvIHVzZSB0aGlzIGZ1bmN0aW9uIGFzIHRoZSBzdGFydGluZyBwb2ludCBpZlxuICAgICAgICAvLyB0aGUgYGxvY2tTc2ZpYCBmbGFnIGlzbid0IHNldCBhbmQgcHJveHkgcHJvdGVjdGlvbiBpcyBkaXNhYmxlZC5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gSWYgdGhlIGBsb2NrU3NmaWAgZmxhZyBpcyBzZXQsIHRoZW4gZWl0aGVyIHRoaXMgYXNzZXJ0aW9uIGhhcyBiZWVuXG4gICAgICAgIC8vIG92ZXJ3cml0dGVuIGJ5IGFub3RoZXIgYXNzZXJ0aW9uLCBvciB0aGlzIGFzc2VydGlvbiBpcyBiZWluZyBpbnZva2VkXG4gICAgICAgIC8vIGZyb20gaW5zaWRlIG9mIGFub3RoZXIgYXNzZXJ0aW9uLiBJbiB0aGUgZmlyc3QgY2FzZSwgdGhlIGBzc2ZpYCBmbGFnXG4gICAgICAgIC8vIGhhcyBhbHJlYWR5IGJlZW4gc2V0IGJ5IHRoZSBvdmVyd3JpdGluZyBhc3NlcnRpb24uIEluIHRoZSBzZWNvbmRcbiAgICAgICAgLy8gY2FzZSwgdGhlIGBzc2ZpYCBmbGFnIGhhcyBhbHJlYWR5IGJlZW4gc2V0IGJ5IHRoZSBvdXRlciBhc3NlcnRpb24uXG4gICAgICAgIC8vXG4gICAgICAgIC8vIElmIHByb3h5IHByb3RlY3Rpb24gaXMgZW5hYmxlZCwgdGhlbiB0aGUgYHNzZmlgIGZsYWcgaGFzIGFscmVhZHkgYmVlblxuICAgICAgICAvLyBzZXQgYnkgdGhlIHByb3h5IGdldHRlci5cbiAgICAgICAgaWYgKCFpc1Byb3h5RW5hYmxlZCgpICYmICFmbGFnKHRoaXMsICdsb2NrU3NmaScpKSB7XG4gICAgICAgICAgZmxhZyh0aGlzLCAnc3NmaScsIHByb3BlcnR5R2V0dGVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciByZXN1bHQgPSBnZXR0ZXIuY2FsbCh0aGlzKTtcbiAgICAgICAgaWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKVxuICAgICAgICAgIHJldHVybiByZXN1bHQ7XG5cbiAgICAgICAgdmFyIG5ld0Fzc2VydGlvbiA9IG5ldyBjaGFpLkFzc2VydGlvbigpO1xuICAgICAgICB0cmFuc2ZlckZsYWdzKHRoaXMsIG5ld0Fzc2VydGlvbik7XG4gICAgICAgIHJldHVybiBuZXdBc3NlcnRpb247XG4gICAgICB9XG4gICAgLCBjb25maWd1cmFibGU6IHRydWVcbiAgfSk7XG59O1xuIiwgInZhciBmbkxlbmd0aERlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGZ1bmN0aW9uICgpIHt9LCAnbGVuZ3RoJyk7XG5cbi8qIVxuICogQ2hhaSAtIGFkZExlbmd0aEd1YXJkIHV0aWxpdHlcbiAqIENvcHlyaWdodChjKSAyMDEyLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG4vKipcbiAqICMjIyAuYWRkTGVuZ3RoR3VhcmQoZm4sIGFzc2VydGlvbk5hbWUsIGlzQ2hhaW5hYmxlKVxuICpcbiAqIERlZmluZSBgbGVuZ3RoYCBhcyBhIGdldHRlciBvbiB0aGUgZ2l2ZW4gdW5pbnZva2VkIG1ldGhvZCBhc3NlcnRpb24uIFRoZVxuICogZ2V0dGVyIGFjdHMgYXMgYSBndWFyZCBhZ2FpbnN0IGNoYWluaW5nIGBsZW5ndGhgIGRpcmVjdGx5IG9mZiBvZiBhbiB1bmludm9rZWRcbiAqIG1ldGhvZCBhc3NlcnRpb24sIHdoaWNoIGlzIGEgcHJvYmxlbSBiZWNhdXNlIGl0IHJlZmVyZW5jZXMgYGZ1bmN0aW9uYCdzXG4gKiBidWlsdC1pbiBgbGVuZ3RoYCBwcm9wZXJ0eSBpbnN0ZWFkIG9mIENoYWkncyBgbGVuZ3RoYCBhc3NlcnRpb24uIFdoZW4gdGhlXG4gKiBnZXR0ZXIgY2F0Y2hlcyB0aGUgdXNlciBtYWtpbmcgdGhpcyBtaXN0YWtlLCBpdCB0aHJvd3MgYW4gZXJyb3Igd2l0aCBhXG4gKiBoZWxwZnVsIG1lc3NhZ2UuXG4gKlxuICogVGhlcmUgYXJlIHR3byB3YXlzIGluIHdoaWNoIHRoaXMgbWlzdGFrZSBjYW4gYmUgbWFkZS4gVGhlIGZpcnN0IHdheSBpcyBieVxuICogY2hhaW5pbmcgdGhlIGBsZW5ndGhgIGFzc2VydGlvbiBkaXJlY3RseSBvZmYgb2YgYW4gdW5pbnZva2VkIGNoYWluYWJsZVxuICogbWV0aG9kLiBJbiB0aGlzIGNhc2UsIENoYWkgc3VnZ2VzdHMgdGhhdCB0aGUgdXNlciB1c2UgYGxlbmd0aE9mYCBpbnN0ZWFkLiBUaGVcbiAqIHNlY29uZCB3YXkgaXMgYnkgY2hhaW5pbmcgdGhlIGBsZW5ndGhgIGFzc2VydGlvbiBkaXJlY3RseSBvZmYgb2YgYW4gdW5pbnZva2VkXG4gKiBub24tY2hhaW5hYmxlIG1ldGhvZC4gTm9uLWNoYWluYWJsZSBtZXRob2RzIG11c3QgYmUgaW52b2tlZCBwcmlvciB0b1xuICogY2hhaW5pbmcuIEluIHRoaXMgY2FzZSwgQ2hhaSBzdWdnZXN0cyB0aGF0IHRoZSB1c2VyIGNvbnN1bHQgdGhlIGRvY3MgZm9yIHRoZVxuICogZ2l2ZW4gYXNzZXJ0aW9uLlxuICpcbiAqIElmIHRoZSBgbGVuZ3RoYCBwcm9wZXJ0eSBvZiBmdW5jdGlvbnMgaXMgdW5jb25maWd1cmFibGUsIHRoZW4gcmV0dXJuIGBmbmBcbiAqIHdpdGhvdXQgbW9kaWZpY2F0aW9uLlxuICpcbiAqIE5vdGUgdGhhdCBpbiBFUzYsIHRoZSBmdW5jdGlvbidzIGBsZW5ndGhgIHByb3BlcnR5IGlzIGNvbmZpZ3VyYWJsZSwgc28gb25jZVxuICogc3VwcG9ydCBmb3IgbGVnYWN5IGVudmlyb25tZW50cyBpcyBkcm9wcGVkLCBDaGFpJ3MgYGxlbmd0aGAgcHJvcGVydHkgY2FuXG4gKiByZXBsYWNlIHRoZSBidWlsdC1pbiBmdW5jdGlvbidzIGBsZW5ndGhgIHByb3BlcnR5LCBhbmQgdGhpcyBsZW5ndGggZ3VhcmQgd2lsbFxuICogbm8gbG9uZ2VyIGJlIG5lY2Vzc2FyeS4gSW4gdGhlIG1lYW4gdGltZSwgbWFpbnRhaW5pbmcgY29uc2lzdGVuY3kgYWNyb3NzIGFsbFxuICogZW52aXJvbm1lbnRzIGlzIHRoZSBwcmlvcml0eS5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHBhcmFtIHtTdHJpbmd9IGFzc2VydGlvbk5hbWVcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gaXNDaGFpbmFibGVcbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBuYW1lIGFkZExlbmd0aEd1YXJkXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBhZGRMZW5ndGhHdWFyZCAoZm4sIGFzc2VydGlvbk5hbWUsIGlzQ2hhaW5hYmxlKSB7XG4gIGlmICghZm5MZW5ndGhEZXNjLmNvbmZpZ3VyYWJsZSkgcmV0dXJuIGZuO1xuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShmbiwgJ2xlbmd0aCcsIHtcbiAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmIChpc0NoYWluYWJsZSkge1xuICAgICAgICB0aHJvdyBFcnJvcignSW52YWxpZCBDaGFpIHByb3BlcnR5OiAnICsgYXNzZXJ0aW9uTmFtZSArICcubGVuZ3RoLiBEdWUnICtcbiAgICAgICAgICAnIHRvIGEgY29tcGF0aWJpbGl0eSBpc3N1ZSwgXCJsZW5ndGhcIiBjYW5ub3QgZGlyZWN0bHkgZm9sbG93IFwiJyArXG4gICAgICAgICAgYXNzZXJ0aW9uTmFtZSArICdcIi4gVXNlIFwiJyArIGFzc2VydGlvbk5hbWUgKyAnLmxlbmd0aE9mXCIgaW5zdGVhZC4nKTtcbiAgICAgIH1cblxuICAgICAgdGhyb3cgRXJyb3IoJ0ludmFsaWQgQ2hhaSBwcm9wZXJ0eTogJyArIGFzc2VydGlvbk5hbWUgKyAnLmxlbmd0aC4gU2VlJyArXG4gICAgICAgICcgZG9jcyBmb3IgcHJvcGVyIHVzYWdlIG9mIFwiJyArIGFzc2VydGlvbk5hbWUgKyAnXCIuJyk7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gZm47XG59O1xuIiwgIi8qIVxuICogQ2hhaSAtIGdldFByb3BlcnRpZXMgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbi8qKlxuICogIyMjIC5nZXRQcm9wZXJ0aWVzKG9iamVjdClcbiAqXG4gKiBUaGlzIGFsbG93cyB0aGUgcmV0cmlldmFsIG9mIHByb3BlcnR5IG5hbWVzIG9mIGFuIG9iamVjdCwgZW51bWVyYWJsZSBvciBub3QsXG4gKiBpbmhlcml0ZWQgb3Igbm90LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAqIEByZXR1cm5zIHtBcnJheX1cbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBuYW1lIGdldFByb3BlcnRpZXNcbiAqIEBhcGkgcHVibGljXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBnZXRQcm9wZXJ0aWVzKG9iamVjdCkge1xuICB2YXIgcmVzdWx0ID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMob2JqZWN0KTtcblxuICBmdW5jdGlvbiBhZGRQcm9wZXJ0eShwcm9wZXJ0eSkge1xuICAgIGlmIChyZXN1bHQuaW5kZXhPZihwcm9wZXJ0eSkgPT09IC0xKSB7XG4gICAgICByZXN1bHQucHVzaChwcm9wZXJ0eSk7XG4gICAgfVxuICB9XG5cbiAgdmFyIHByb3RvID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKG9iamVjdCk7XG4gIHdoaWxlIChwcm90byAhPT0gbnVsbCkge1xuICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHByb3RvKS5mb3JFYWNoKGFkZFByb3BlcnR5KTtcbiAgICBwcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihwcm90byk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufTtcbiIsICJ2YXIgY29uZmlnID0gcmVxdWlyZSgnLi4vY29uZmlnJyk7XG52YXIgZmxhZyA9IHJlcXVpcmUoJy4vZmxhZycpO1xudmFyIGdldFByb3BlcnRpZXMgPSByZXF1aXJlKCcuL2dldFByb3BlcnRpZXMnKTtcbnZhciBpc1Byb3h5RW5hYmxlZCA9IHJlcXVpcmUoJy4vaXNQcm94eUVuYWJsZWQnKTtcblxuLyohXG4gKiBDaGFpIC0gcHJveGlmeSB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyoqXG4gKiAjIyMgLnByb3hpZnkob2JqZWN0KVxuICpcbiAqIFJldHVybiBhIHByb3h5IG9mIGdpdmVuIG9iamVjdCB0aGF0IHRocm93cyBhbiBlcnJvciB3aGVuIGEgbm9uLWV4aXN0ZW50XG4gKiBwcm9wZXJ0eSBpcyByZWFkLiBCeSBkZWZhdWx0LCB0aGUgcm9vdCBjYXVzZSBpcyBhc3N1bWVkIHRvIGJlIGEgbWlzc3BlbGxlZFxuICogcHJvcGVydHksIGFuZCB0aHVzIGFuIGF0dGVtcHQgaXMgbWFkZSB0byBvZmZlciBhIHJlYXNvbmFibGUgc3VnZ2VzdGlvbiBmcm9tXG4gKiB0aGUgbGlzdCBvZiBleGlzdGluZyBwcm9wZXJ0aWVzLiBIb3dldmVyLCBpZiBhIG5vbkNoYWluYWJsZU1ldGhvZE5hbWUgaXNcbiAqIHByb3ZpZGVkLCB0aGVuIHRoZSByb290IGNhdXNlIGlzIGluc3RlYWQgYSBmYWlsdXJlIHRvIGludm9rZSBhIG5vbi1jaGFpbmFibGVcbiAqIG1ldGhvZCBwcmlvciB0byByZWFkaW5nIHRoZSBub24tZXhpc3RlbnQgcHJvcGVydHkuXG4gKlxuICogSWYgcHJveGllcyBhcmUgdW5zdXBwb3J0ZWQgb3IgZGlzYWJsZWQgdmlhIHRoZSB1c2VyJ3MgQ2hhaSBjb25maWcsIHRoZW5cbiAqIHJldHVybiBvYmplY3Qgd2l0aG91dCBtb2RpZmljYXRpb24uXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICogQHBhcmFtIHtTdHJpbmd9IG5vbkNoYWluYWJsZU1ldGhvZE5hbWVcbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBuYW1lIHByb3hpZnlcbiAqL1xuXG52YXIgYnVpbHRpbnMgPSBbJ19fZmxhZ3MnLCAnX19tZXRob2RzJywgJ19vYmonLCAnYXNzZXJ0J107XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcHJveGlmeShvYmosIG5vbkNoYWluYWJsZU1ldGhvZE5hbWUpIHtcbiAgaWYgKCFpc1Byb3h5RW5hYmxlZCgpKSByZXR1cm4gb2JqO1xuXG4gIHJldHVybiBuZXcgUHJveHkob2JqLCB7XG4gICAgZ2V0OiBmdW5jdGlvbiBwcm94eUdldHRlcih0YXJnZXQsIHByb3BlcnR5KSB7XG4gICAgICAvLyBUaGlzIGNoZWNrIGlzIGhlcmUgYmVjYXVzZSB3ZSBzaG91bGQgbm90IHRocm93IGVycm9ycyBvbiBTeW1ib2wgcHJvcGVydGllc1xuICAgICAgLy8gc3VjaCBhcyBgU3ltYm9sLnRvU3RyaW5nVGFnYC5cbiAgICAgIC8vIFRoZSB2YWx1ZXMgZm9yIHdoaWNoIGFuIGVycm9yIHNob3VsZCBiZSB0aHJvd24gY2FuIGJlIGNvbmZpZ3VyZWQgdXNpbmdcbiAgICAgIC8vIHRoZSBgY29uZmlnLnByb3h5RXhjbHVkZWRLZXlzYCBzZXR0aW5nLlxuICAgICAgaWYgKHR5cGVvZiBwcm9wZXJ0eSA9PT0gJ3N0cmluZycgJiZcbiAgICAgICAgICBjb25maWcucHJveHlFeGNsdWRlZEtleXMuaW5kZXhPZihwcm9wZXJ0eSkgPT09IC0xICYmXG4gICAgICAgICAgIVJlZmxlY3QuaGFzKHRhcmdldCwgcHJvcGVydHkpKSB7XG4gICAgICAgIC8vIFNwZWNpYWwgbWVzc2FnZSBmb3IgaW52YWxpZCBwcm9wZXJ0eSBhY2Nlc3Mgb2Ygbm9uLWNoYWluYWJsZSBtZXRob2RzLlxuICAgICAgICBpZiAobm9uQ2hhaW5hYmxlTWV0aG9kTmFtZSkge1xuICAgICAgICAgIHRocm93IEVycm9yKCdJbnZhbGlkIENoYWkgcHJvcGVydHk6ICcgKyBub25DaGFpbmFibGVNZXRob2ROYW1lICsgJy4nICtcbiAgICAgICAgICAgIHByb3BlcnR5ICsgJy4gU2VlIGRvY3MgZm9yIHByb3BlciB1c2FnZSBvZiBcIicgK1xuICAgICAgICAgICAgbm9uQ2hhaW5hYmxlTWV0aG9kTmFtZSArICdcIi4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIElmIHRoZSBwcm9wZXJ0eSBpcyByZWFzb25hYmx5IGNsb3NlIHRvIGFuIGV4aXN0aW5nIENoYWkgcHJvcGVydHksXG4gICAgICAgIC8vIHN1Z2dlc3QgdGhhdCBwcm9wZXJ0eSB0byB0aGUgdXNlci4gT25seSBzdWdnZXN0IHByb3BlcnRpZXMgd2l0aCBhXG4gICAgICAgIC8vIGRpc3RhbmNlIGxlc3MgdGhhbiA0LlxuICAgICAgICB2YXIgc3VnZ2VzdGlvbiA9IG51bGw7XG4gICAgICAgIHZhciBzdWdnZXN0aW9uRGlzdGFuY2UgPSA0O1xuICAgICAgICBnZXRQcm9wZXJ0aWVzKHRhcmdldCkuZm9yRWFjaChmdW5jdGlvbihwcm9wKSB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkocHJvcCkgJiZcbiAgICAgICAgICAgIGJ1aWx0aW5zLmluZGV4T2YocHJvcCkgPT09IC0xXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICB2YXIgZGlzdCA9IHN0cmluZ0Rpc3RhbmNlQ2FwcGVkKFxuICAgICAgICAgICAgICBwcm9wZXJ0eSxcbiAgICAgICAgICAgICAgcHJvcCxcbiAgICAgICAgICAgICAgc3VnZ2VzdGlvbkRpc3RhbmNlXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKGRpc3QgPCBzdWdnZXN0aW9uRGlzdGFuY2UpIHtcbiAgICAgICAgICAgICAgc3VnZ2VzdGlvbiA9IHByb3A7XG4gICAgICAgICAgICAgIHN1Z2dlc3Rpb25EaXN0YW5jZSA9IGRpc3Q7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoc3VnZ2VzdGlvbiAhPT0gbnVsbCkge1xuICAgICAgICAgIHRocm93IEVycm9yKCdJbnZhbGlkIENoYWkgcHJvcGVydHk6ICcgKyBwcm9wZXJ0eSArXG4gICAgICAgICAgICAnLiBEaWQgeW91IG1lYW4gXCInICsgc3VnZ2VzdGlvbiArICdcIj8nKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBFcnJvcignSW52YWxpZCBDaGFpIHByb3BlcnR5OiAnICsgcHJvcGVydHkpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFVzZSB0aGlzIHByb3h5IGdldHRlciBhcyB0aGUgc3RhcnRpbmcgcG9pbnQgZm9yIHJlbW92aW5nIGltcGxlbWVudGF0aW9uXG4gICAgICAvLyBmcmFtZXMgZnJvbSB0aGUgc3RhY2sgdHJhY2Ugb2YgYSBmYWlsZWQgYXNzZXJ0aW9uLiBGb3IgcHJvcGVydHlcbiAgICAgIC8vIGFzc2VydGlvbnMsIHRoaXMgcHJldmVudHMgdGhlIHByb3h5IGdldHRlciBmcm9tIHNob3dpbmcgdXAgaW4gdGhlIHN0YWNrXG4gICAgICAvLyB0cmFjZSBzaW5jZSBpdCdzIGludm9rZWQgYmVmb3JlIHRoZSBwcm9wZXJ0eSBnZXR0ZXIuIEZvciBtZXRob2QgYW5kXG4gICAgICAvLyBjaGFpbmFibGUgbWV0aG9kIGFzc2VydGlvbnMsIHRoaXMgZmxhZyB3aWxsIGVuZCB1cCBnZXR0aW5nIGNoYW5nZWQgdG9cbiAgICAgIC8vIHRoZSBtZXRob2Qgd3JhcHBlciwgd2hpY2ggaXMgZ29vZCBzaW5jZSB0aGlzIGZyYW1lIHdpbGwgbm8gbG9uZ2VyIGJlIGluXG4gICAgICAvLyB0aGUgc3RhY2sgb25jZSB0aGUgbWV0aG9kIGlzIGludm9rZWQuIE5vdGUgdGhhdCBDaGFpIGJ1aWx0aW4gYXNzZXJ0aW9uXG4gICAgICAvLyBwcm9wZXJ0aWVzIHN1Y2ggYXMgYF9fZmxhZ3NgIGFyZSBza2lwcGVkIHNpbmNlIHRoaXMgaXMgb25seSBtZWFudCB0b1xuICAgICAgLy8gY2FwdHVyZSB0aGUgc3RhcnRpbmcgcG9pbnQgb2YgYW4gYXNzZXJ0aW9uLiBUaGlzIHN0ZXAgaXMgYWxzbyBza2lwcGVkXG4gICAgICAvLyBpZiB0aGUgYGxvY2tTc2ZpYCBmbGFnIGlzIHNldCwgdGh1cyBpbmRpY2F0aW5nIHRoYXQgdGhpcyBhc3NlcnRpb24gaXNcbiAgICAgIC8vIGJlaW5nIGNhbGxlZCBmcm9tIHdpdGhpbiBhbm90aGVyIGFzc2VydGlvbi4gSW4gdGhhdCBjYXNlLCB0aGUgYHNzZmlgXG4gICAgICAvLyBmbGFnIGlzIGFscmVhZHkgc2V0IHRvIHRoZSBvdXRlciBhc3NlcnRpb24ncyBzdGFydGluZyBwb2ludC5cbiAgICAgIGlmIChidWlsdGlucy5pbmRleE9mKHByb3BlcnR5KSA9PT0gLTEgJiYgIWZsYWcodGFyZ2V0LCAnbG9ja1NzZmknKSkge1xuICAgICAgICBmbGFnKHRhcmdldCwgJ3NzZmknLCBwcm94eUdldHRlcik7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBSZWZsZWN0LmdldCh0YXJnZXQsIHByb3BlcnR5KTtcbiAgICB9XG4gIH0pO1xufTtcblxuLyoqXG4gKiAjIHN0cmluZ0Rpc3RhbmNlQ2FwcGVkKHN0ckEsIHN0ckIsIGNhcClcbiAqIFJldHVybiB0aGUgTGV2ZW5zaHRlaW4gZGlzdGFuY2UgYmV0d2VlbiB0d28gc3RyaW5ncywgYnV0IG5vIG1vcmUgdGhhbiBjYXAuXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyQVxuICogQHBhcmFtIHtzdHJpbmd9IHN0ckJcbiAqIEBwYXJhbSB7bnVtYmVyfSBudW1iZXJcbiAqIEByZXR1cm4ge251bWJlcn0gbWluKHN0cmluZyBkaXN0YW5jZSBiZXR3ZWVuIHN0ckEgYW5kIHN0ckIsIGNhcClcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHN0cmluZ0Rpc3RhbmNlQ2FwcGVkKHN0ckEsIHN0ckIsIGNhcCkge1xuICBpZiAoTWF0aC5hYnMoc3RyQS5sZW5ndGggLSBzdHJCLmxlbmd0aCkgPj0gY2FwKSB7XG4gICAgcmV0dXJuIGNhcDtcbiAgfVxuXG4gIHZhciBtZW1vID0gW107XG4gIC8vIGBtZW1vYCBpcyBhIHR3by1kaW1lbnNpb25hbCBhcnJheSBjb250YWluaW5nIGRpc3RhbmNlcy5cbiAgLy8gbWVtb1tpXVtqXSBpcyB0aGUgZGlzdGFuY2UgYmV0d2VlbiBzdHJBLnNsaWNlKDAsIGkpIGFuZFxuICAvLyBzdHJCLnNsaWNlKDAsIGopLlxuICBmb3IgKHZhciBpID0gMDsgaSA8PSBzdHJBLmxlbmd0aDsgaSsrKSB7XG4gICAgbWVtb1tpXSA9IEFycmF5KHN0ckIubGVuZ3RoICsgMSkuZmlsbCgwKTtcbiAgICBtZW1vW2ldWzBdID0gaTtcbiAgfVxuICBmb3IgKHZhciBqID0gMDsgaiA8IHN0ckIubGVuZ3RoOyBqKyspIHtcbiAgICBtZW1vWzBdW2pdID0gajtcbiAgfVxuXG4gIGZvciAodmFyIGkgPSAxOyBpIDw9IHN0ckEubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgY2ggPSBzdHJBLmNoYXJDb2RlQXQoaSAtIDEpO1xuICAgIGZvciAodmFyIGogPSAxOyBqIDw9IHN0ckIubGVuZ3RoOyBqKyspIHtcbiAgICAgIGlmIChNYXRoLmFicyhpIC0gaikgPj0gY2FwKSB7XG4gICAgICAgIG1lbW9baV1bal0gPSBjYXA7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgbWVtb1tpXVtqXSA9IE1hdGgubWluKFxuICAgICAgICBtZW1vW2kgLSAxXVtqXSArIDEsXG4gICAgICAgIG1lbW9baV1baiAtIDFdICsgMSxcbiAgICAgICAgbWVtb1tpIC0gMV1baiAtIDFdICtcbiAgICAgICAgICAoY2ggPT09IHN0ckIuY2hhckNvZGVBdChqIC0gMSkgPyAwIDogMSlcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG1lbW9bc3RyQS5sZW5ndGhdW3N0ckIubGVuZ3RoXTtcbn1cbiIsICIvKiFcbiAqIENoYWkgLSBhZGRNZXRob2QgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbnZhciBhZGRMZW5ndGhHdWFyZCA9IHJlcXVpcmUoJy4vYWRkTGVuZ3RoR3VhcmQnKTtcbnZhciBjaGFpID0gcmVxdWlyZSgnLi4vLi4vY2hhaScpO1xudmFyIGZsYWcgPSByZXF1aXJlKCcuL2ZsYWcnKTtcbnZhciBwcm94aWZ5ID0gcmVxdWlyZSgnLi9wcm94aWZ5Jyk7XG52YXIgdHJhbnNmZXJGbGFncyA9IHJlcXVpcmUoJy4vdHJhbnNmZXJGbGFncycpO1xuXG4vKipcbiAqICMjIyAuYWRkTWV0aG9kKGN0eCwgbmFtZSwgbWV0aG9kKVxuICpcbiAqIEFkZHMgYSBtZXRob2QgdG8gdGhlIHByb3RvdHlwZSBvZiBhbiBvYmplY3QuXG4gKlxuICogICAgIHV0aWxzLmFkZE1ldGhvZChjaGFpLkFzc2VydGlvbi5wcm90b3R5cGUsICdmb28nLCBmdW5jdGlvbiAoc3RyKSB7XG4gKiAgICAgICB2YXIgb2JqID0gdXRpbHMuZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gKiAgICAgICBuZXcgY2hhaS5Bc3NlcnRpb24ob2JqKS50by5iZS5lcXVhbChzdHIpO1xuICogICAgIH0pO1xuICpcbiAqIENhbiBhbHNvIGJlIGFjY2Vzc2VkIGRpcmVjdGx5IGZyb20gYGNoYWkuQXNzZXJ0aW9uYC5cbiAqXG4gKiAgICAgY2hhaS5Bc3NlcnRpb24uYWRkTWV0aG9kKCdmb28nLCBmbik7XG4gKlxuICogVGhlbiBjYW4gYmUgdXNlZCBhcyBhbnkgb3RoZXIgYXNzZXJ0aW9uLlxuICpcbiAqICAgICBleHBlY3QoZm9vU3RyKS50by5iZS5mb28oJ2JhcicpO1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjdHggb2JqZWN0IHRvIHdoaWNoIHRoZSBtZXRob2QgaXMgYWRkZWRcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIG9mIG1ldGhvZCB0byBhZGRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IG1ldGhvZCBmdW5jdGlvbiB0byBiZSB1c2VkIGZvciBuYW1lXG4gKiBAbmFtZXNwYWNlIFV0aWxzXG4gKiBAbmFtZSBhZGRNZXRob2RcbiAqIEBhcGkgcHVibGljXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBhZGRNZXRob2QoY3R4LCBuYW1lLCBtZXRob2QpIHtcbiAgdmFyIG1ldGhvZFdyYXBwZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgLy8gU2V0dGluZyB0aGUgYHNzZmlgIGZsYWcgdG8gYG1ldGhvZFdyYXBwZXJgIGNhdXNlcyB0aGlzIGZ1bmN0aW9uIHRvIGJlIHRoZVxuICAgIC8vIHN0YXJ0aW5nIHBvaW50IGZvciByZW1vdmluZyBpbXBsZW1lbnRhdGlvbiBmcmFtZXMgZnJvbSB0aGUgc3RhY2sgdHJhY2Ugb2ZcbiAgICAvLyBhIGZhaWxlZCBhc3NlcnRpb24uXG4gICAgLy9cbiAgICAvLyBIb3dldmVyLCB3ZSBvbmx5IHdhbnQgdG8gdXNlIHRoaXMgZnVuY3Rpb24gYXMgdGhlIHN0YXJ0aW5nIHBvaW50IGlmIHRoZVxuICAgIC8vIGBsb2NrU3NmaWAgZmxhZyBpc24ndCBzZXQuXG4gICAgLy9cbiAgICAvLyBJZiB0aGUgYGxvY2tTc2ZpYCBmbGFnIGlzIHNldCwgdGhlbiBlaXRoZXIgdGhpcyBhc3NlcnRpb24gaGFzIGJlZW5cbiAgICAvLyBvdmVyd3JpdHRlbiBieSBhbm90aGVyIGFzc2VydGlvbiwgb3IgdGhpcyBhc3NlcnRpb24gaXMgYmVpbmcgaW52b2tlZCBmcm9tXG4gICAgLy8gaW5zaWRlIG9mIGFub3RoZXIgYXNzZXJ0aW9uLiBJbiB0aGUgZmlyc3QgY2FzZSwgdGhlIGBzc2ZpYCBmbGFnIGhhc1xuICAgIC8vIGFscmVhZHkgYmVlbiBzZXQgYnkgdGhlIG92ZXJ3cml0aW5nIGFzc2VydGlvbi4gSW4gdGhlIHNlY29uZCBjYXNlLCB0aGVcbiAgICAvLyBgc3NmaWAgZmxhZyBoYXMgYWxyZWFkeSBiZWVuIHNldCBieSB0aGUgb3V0ZXIgYXNzZXJ0aW9uLlxuICAgIGlmICghZmxhZyh0aGlzLCAnbG9ja1NzZmknKSkge1xuICAgICAgZmxhZyh0aGlzLCAnc3NmaScsIG1ldGhvZFdyYXBwZXIpO1xuICAgIH1cblxuICAgIHZhciByZXN1bHQgPSBtZXRob2QuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQpXG4gICAgICByZXR1cm4gcmVzdWx0O1xuXG4gICAgdmFyIG5ld0Fzc2VydGlvbiA9IG5ldyBjaGFpLkFzc2VydGlvbigpO1xuICAgIHRyYW5zZmVyRmxhZ3ModGhpcywgbmV3QXNzZXJ0aW9uKTtcbiAgICByZXR1cm4gbmV3QXNzZXJ0aW9uO1xuICB9O1xuXG4gIGFkZExlbmd0aEd1YXJkKG1ldGhvZFdyYXBwZXIsIG5hbWUsIGZhbHNlKTtcbiAgY3R4W25hbWVdID0gcHJveGlmeShtZXRob2RXcmFwcGVyLCBuYW1lKTtcbn07XG4iLCAiLyohXG4gKiBDaGFpIC0gb3ZlcndyaXRlUHJvcGVydHkgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbnZhciBjaGFpID0gcmVxdWlyZSgnLi4vLi4vY2hhaScpO1xudmFyIGZsYWcgPSByZXF1aXJlKCcuL2ZsYWcnKTtcbnZhciBpc1Byb3h5RW5hYmxlZCA9IHJlcXVpcmUoJy4vaXNQcm94eUVuYWJsZWQnKTtcbnZhciB0cmFuc2ZlckZsYWdzID0gcmVxdWlyZSgnLi90cmFuc2ZlckZsYWdzJyk7XG5cbi8qKlxuICogIyMjIC5vdmVyd3JpdGVQcm9wZXJ0eShjdHgsIG5hbWUsIGZuKVxuICpcbiAqIE92ZXJ3cml0ZXMgYW4gYWxyZWFkeSBleGlzdGluZyBwcm9wZXJ0eSBnZXR0ZXIgYW5kIHByb3ZpZGVzXG4gKiBhY2Nlc3MgdG8gcHJldmlvdXMgdmFsdWUuIE11c3QgcmV0dXJuIGZ1bmN0aW9uIHRvIHVzZSBhcyBnZXR0ZXIuXG4gKlxuICogICAgIHV0aWxzLm92ZXJ3cml0ZVByb3BlcnR5KGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZSwgJ29rJywgZnVuY3Rpb24gKF9zdXBlcikge1xuICogICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAqICAgICAgICAgdmFyIG9iaiA9IHV0aWxzLmZsYWcodGhpcywgJ29iamVjdCcpO1xuICogICAgICAgICBpZiAob2JqIGluc3RhbmNlb2YgRm9vKSB7XG4gKiAgICAgICAgICAgbmV3IGNoYWkuQXNzZXJ0aW9uKG9iai5uYW1lKS50by5lcXVhbCgnYmFyJyk7XG4gKiAgICAgICAgIH0gZWxzZSB7XG4gKiAgICAgICAgICAgX3N1cGVyLmNhbGwodGhpcyk7XG4gKiAgICAgICAgIH1cbiAqICAgICAgIH1cbiAqICAgICB9KTtcbiAqXG4gKlxuICogQ2FuIGFsc28gYmUgYWNjZXNzZWQgZGlyZWN0bHkgZnJvbSBgY2hhaS5Bc3NlcnRpb25gLlxuICpcbiAqICAgICBjaGFpLkFzc2VydGlvbi5vdmVyd3JpdGVQcm9wZXJ0eSgnZm9vJywgZm4pO1xuICpcbiAqIFRoZW4gY2FuIGJlIHVzZWQgYXMgYW55IG90aGVyIGFzc2VydGlvbi5cbiAqXG4gKiAgICAgZXhwZWN0KG15Rm9vKS50by5iZS5vaztcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY3R4IG9iamVjdCB3aG9zZSBwcm9wZXJ0eSBpcyB0byBiZSBvdmVyd3JpdHRlblxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgb2YgcHJvcGVydHkgdG8gb3ZlcndyaXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBnZXR0ZXIgZnVuY3Rpb24gdGhhdCByZXR1cm5zIGEgZ2V0dGVyIGZ1bmN0aW9uIHRvIGJlIHVzZWQgZm9yIG5hbWVcbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBuYW1lIG92ZXJ3cml0ZVByb3BlcnR5XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gb3ZlcndyaXRlUHJvcGVydHkoY3R4LCBuYW1lLCBnZXR0ZXIpIHtcbiAgdmFyIF9nZXQgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGN0eCwgbmFtZSlcbiAgICAsIF9zdXBlciA9IGZ1bmN0aW9uICgpIHt9O1xuXG4gIGlmIChfZ2V0ICYmICdmdW5jdGlvbicgPT09IHR5cGVvZiBfZ2V0LmdldClcbiAgICBfc3VwZXIgPSBfZ2V0LmdldFxuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjdHgsIG5hbWUsXG4gICAgeyBnZXQ6IGZ1bmN0aW9uIG92ZXJ3cml0aW5nUHJvcGVydHlHZXR0ZXIoKSB7XG4gICAgICAgIC8vIFNldHRpbmcgdGhlIGBzc2ZpYCBmbGFnIHRvIGBvdmVyd3JpdGluZ1Byb3BlcnR5R2V0dGVyYCBjYXVzZXMgdGhpc1xuICAgICAgICAvLyBmdW5jdGlvbiB0byBiZSB0aGUgc3RhcnRpbmcgcG9pbnQgZm9yIHJlbW92aW5nIGltcGxlbWVudGF0aW9uIGZyYW1lc1xuICAgICAgICAvLyBmcm9tIHRoZSBzdGFjayB0cmFjZSBvZiBhIGZhaWxlZCBhc3NlcnRpb24uXG4gICAgICAgIC8vXG4gICAgICAgIC8vIEhvd2V2ZXIsIHdlIG9ubHkgd2FudCB0byB1c2UgdGhpcyBmdW5jdGlvbiBhcyB0aGUgc3RhcnRpbmcgcG9pbnQgaWZcbiAgICAgICAgLy8gdGhlIGBsb2NrU3NmaWAgZmxhZyBpc24ndCBzZXQgYW5kIHByb3h5IHByb3RlY3Rpb24gaXMgZGlzYWJsZWQuXG4gICAgICAgIC8vXG4gICAgICAgIC8vIElmIHRoZSBgbG9ja1NzZmlgIGZsYWcgaXMgc2V0LCB0aGVuIGVpdGhlciB0aGlzIGFzc2VydGlvbiBoYXMgYmVlblxuICAgICAgICAvLyBvdmVyd3JpdHRlbiBieSBhbm90aGVyIGFzc2VydGlvbiwgb3IgdGhpcyBhc3NlcnRpb24gaXMgYmVpbmcgaW52b2tlZFxuICAgICAgICAvLyBmcm9tIGluc2lkZSBvZiBhbm90aGVyIGFzc2VydGlvbi4gSW4gdGhlIGZpcnN0IGNhc2UsIHRoZSBgc3NmaWAgZmxhZ1xuICAgICAgICAvLyBoYXMgYWxyZWFkeSBiZWVuIHNldCBieSB0aGUgb3ZlcndyaXRpbmcgYXNzZXJ0aW9uLiBJbiB0aGUgc2Vjb25kXG4gICAgICAgIC8vIGNhc2UsIHRoZSBgc3NmaWAgZmxhZyBoYXMgYWxyZWFkeSBiZWVuIHNldCBieSB0aGUgb3V0ZXIgYXNzZXJ0aW9uLlxuICAgICAgICAvL1xuICAgICAgICAvLyBJZiBwcm94eSBwcm90ZWN0aW9uIGlzIGVuYWJsZWQsIHRoZW4gdGhlIGBzc2ZpYCBmbGFnIGhhcyBhbHJlYWR5IGJlZW5cbiAgICAgICAgLy8gc2V0IGJ5IHRoZSBwcm94eSBnZXR0ZXIuXG4gICAgICAgIGlmICghaXNQcm94eUVuYWJsZWQoKSAmJiAhZmxhZyh0aGlzLCAnbG9ja1NzZmknKSkge1xuICAgICAgICAgIGZsYWcodGhpcywgJ3NzZmknLCBvdmVyd3JpdGluZ1Byb3BlcnR5R2V0dGVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldHRpbmcgdGhlIGBsb2NrU3NmaWAgZmxhZyB0byBgdHJ1ZWAgcHJldmVudHMgdGhlIG92ZXJ3cml0dGVuXG4gICAgICAgIC8vIGFzc2VydGlvbiBmcm9tIGNoYW5naW5nIHRoZSBgc3NmaWAgZmxhZy4gQnkgdGhpcyBwb2ludCwgdGhlIGBzc2ZpYFxuICAgICAgICAvLyBmbGFnIGlzIGFscmVhZHkgc2V0IHRvIHRoZSBjb3JyZWN0IHN0YXJ0aW5nIHBvaW50IGZvciB0aGlzIGFzc2VydGlvbi5cbiAgICAgICAgdmFyIG9yaWdMb2NrU3NmaSA9IGZsYWcodGhpcywgJ2xvY2tTc2ZpJyk7XG4gICAgICAgIGZsYWcodGhpcywgJ2xvY2tTc2ZpJywgdHJ1ZSk7XG4gICAgICAgIHZhciByZXN1bHQgPSBnZXR0ZXIoX3N1cGVyKS5jYWxsKHRoaXMpO1xuICAgICAgICBmbGFnKHRoaXMsICdsb2NrU3NmaScsIG9yaWdMb2NrU3NmaSk7XG5cbiAgICAgICAgaWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBuZXdBc3NlcnRpb24gPSBuZXcgY2hhaS5Bc3NlcnRpb24oKTtcbiAgICAgICAgdHJhbnNmZXJGbGFncyh0aGlzLCBuZXdBc3NlcnRpb24pO1xuICAgICAgICByZXR1cm4gbmV3QXNzZXJ0aW9uO1xuICAgICAgfVxuICAgICwgY29uZmlndXJhYmxlOiB0cnVlXG4gIH0pO1xufTtcbiIsICIvKiFcbiAqIENoYWkgLSBvdmVyd3JpdGVNZXRob2QgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbnZhciBhZGRMZW5ndGhHdWFyZCA9IHJlcXVpcmUoJy4vYWRkTGVuZ3RoR3VhcmQnKTtcbnZhciBjaGFpID0gcmVxdWlyZSgnLi4vLi4vY2hhaScpO1xudmFyIGZsYWcgPSByZXF1aXJlKCcuL2ZsYWcnKTtcbnZhciBwcm94aWZ5ID0gcmVxdWlyZSgnLi9wcm94aWZ5Jyk7XG52YXIgdHJhbnNmZXJGbGFncyA9IHJlcXVpcmUoJy4vdHJhbnNmZXJGbGFncycpO1xuXG4vKipcbiAqICMjIyAub3ZlcndyaXRlTWV0aG9kKGN0eCwgbmFtZSwgZm4pXG4gKlxuICogT3ZlcndyaXRlcyBhbiBhbHJlYWR5IGV4aXN0aW5nIG1ldGhvZCBhbmQgcHJvdmlkZXNcbiAqIGFjY2VzcyB0byBwcmV2aW91cyBmdW5jdGlvbi4gTXVzdCByZXR1cm4gZnVuY3Rpb25cbiAqIHRvIGJlIHVzZWQgZm9yIG5hbWUuXG4gKlxuICogICAgIHV0aWxzLm92ZXJ3cml0ZU1ldGhvZChjaGFpLkFzc2VydGlvbi5wcm90b3R5cGUsICdlcXVhbCcsIGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAqICAgICAgIHJldHVybiBmdW5jdGlvbiAoc3RyKSB7XG4gKiAgICAgICAgIHZhciBvYmogPSB1dGlscy5mbGFnKHRoaXMsICdvYmplY3QnKTtcbiAqICAgICAgICAgaWYgKG9iaiBpbnN0YW5jZW9mIEZvbykge1xuICogICAgICAgICAgIG5ldyBjaGFpLkFzc2VydGlvbihvYmoudmFsdWUpLnRvLmVxdWFsKHN0cik7XG4gKiAgICAgICAgIH0gZWxzZSB7XG4gKiAgICAgICAgICAgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gKiAgICAgICAgIH1cbiAqICAgICAgIH1cbiAqICAgICB9KTtcbiAqXG4gKiBDYW4gYWxzbyBiZSBhY2Nlc3NlZCBkaXJlY3RseSBmcm9tIGBjaGFpLkFzc2VydGlvbmAuXG4gKlxuICogICAgIGNoYWkuQXNzZXJ0aW9uLm92ZXJ3cml0ZU1ldGhvZCgnZm9vJywgZm4pO1xuICpcbiAqIFRoZW4gY2FuIGJlIHVzZWQgYXMgYW55IG90aGVyIGFzc2VydGlvbi5cbiAqXG4gKiAgICAgZXhwZWN0KG15Rm9vKS50by5lcXVhbCgnYmFyJyk7XG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGN0eCBvYmplY3Qgd2hvc2UgbWV0aG9kIGlzIHRvIGJlIG92ZXJ3cml0dGVuXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBvZiBtZXRob2QgdG8gb3ZlcndyaXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBtZXRob2QgZnVuY3Rpb24gdGhhdCByZXR1cm5zIGEgZnVuY3Rpb24gdG8gYmUgdXNlZCBmb3IgbmFtZVxuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQG5hbWUgb3ZlcndyaXRlTWV0aG9kXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gb3ZlcndyaXRlTWV0aG9kKGN0eCwgbmFtZSwgbWV0aG9kKSB7XG4gIHZhciBfbWV0aG9kID0gY3R4W25hbWVdXG4gICAgLCBfc3VwZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IobmFtZSArICcgaXMgbm90IGEgZnVuY3Rpb24nKTtcbiAgICB9O1xuXG4gIGlmIChfbWV0aG9kICYmICdmdW5jdGlvbicgPT09IHR5cGVvZiBfbWV0aG9kKVxuICAgIF9zdXBlciA9IF9tZXRob2Q7XG5cbiAgdmFyIG92ZXJ3cml0aW5nTWV0aG9kV3JhcHBlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAvLyBTZXR0aW5nIHRoZSBgc3NmaWAgZmxhZyB0byBgb3ZlcndyaXRpbmdNZXRob2RXcmFwcGVyYCBjYXVzZXMgdGhpc1xuICAgIC8vIGZ1bmN0aW9uIHRvIGJlIHRoZSBzdGFydGluZyBwb2ludCBmb3IgcmVtb3ZpbmcgaW1wbGVtZW50YXRpb24gZnJhbWVzIGZyb21cbiAgICAvLyB0aGUgc3RhY2sgdHJhY2Ugb2YgYSBmYWlsZWQgYXNzZXJ0aW9uLlxuICAgIC8vXG4gICAgLy8gSG93ZXZlciwgd2Ugb25seSB3YW50IHRvIHVzZSB0aGlzIGZ1bmN0aW9uIGFzIHRoZSBzdGFydGluZyBwb2ludCBpZiB0aGVcbiAgICAvLyBgbG9ja1NzZmlgIGZsYWcgaXNuJ3Qgc2V0LlxuICAgIC8vXG4gICAgLy8gSWYgdGhlIGBsb2NrU3NmaWAgZmxhZyBpcyBzZXQsIHRoZW4gZWl0aGVyIHRoaXMgYXNzZXJ0aW9uIGhhcyBiZWVuXG4gICAgLy8gb3ZlcndyaXR0ZW4gYnkgYW5vdGhlciBhc3NlcnRpb24sIG9yIHRoaXMgYXNzZXJ0aW9uIGlzIGJlaW5nIGludm9rZWQgZnJvbVxuICAgIC8vIGluc2lkZSBvZiBhbm90aGVyIGFzc2VydGlvbi4gSW4gdGhlIGZpcnN0IGNhc2UsIHRoZSBgc3NmaWAgZmxhZyBoYXNcbiAgICAvLyBhbHJlYWR5IGJlZW4gc2V0IGJ5IHRoZSBvdmVyd3JpdGluZyBhc3NlcnRpb24uIEluIHRoZSBzZWNvbmQgY2FzZSwgdGhlXG4gICAgLy8gYHNzZmlgIGZsYWcgaGFzIGFscmVhZHkgYmVlbiBzZXQgYnkgdGhlIG91dGVyIGFzc2VydGlvbi5cbiAgICBpZiAoIWZsYWcodGhpcywgJ2xvY2tTc2ZpJykpIHtcbiAgICAgIGZsYWcodGhpcywgJ3NzZmknLCBvdmVyd3JpdGluZ01ldGhvZFdyYXBwZXIpO1xuICAgIH1cblxuICAgIC8vIFNldHRpbmcgdGhlIGBsb2NrU3NmaWAgZmxhZyB0byBgdHJ1ZWAgcHJldmVudHMgdGhlIG92ZXJ3cml0dGVuIGFzc2VydGlvblxuICAgIC8vIGZyb20gY2hhbmdpbmcgdGhlIGBzc2ZpYCBmbGFnLiBCeSB0aGlzIHBvaW50LCB0aGUgYHNzZmlgIGZsYWcgaXMgYWxyZWFkeVxuICAgIC8vIHNldCB0byB0aGUgY29ycmVjdCBzdGFydGluZyBwb2ludCBmb3IgdGhpcyBhc3NlcnRpb24uXG4gICAgdmFyIG9yaWdMb2NrU3NmaSA9IGZsYWcodGhpcywgJ2xvY2tTc2ZpJyk7XG4gICAgZmxhZyh0aGlzLCAnbG9ja1NzZmknLCB0cnVlKTtcbiAgICB2YXIgcmVzdWx0ID0gbWV0aG9kKF9zdXBlcikuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICBmbGFnKHRoaXMsICdsb2NrU3NmaScsIG9yaWdMb2NrU3NmaSk7XG5cbiAgICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgdmFyIG5ld0Fzc2VydGlvbiA9IG5ldyBjaGFpLkFzc2VydGlvbigpO1xuICAgIHRyYW5zZmVyRmxhZ3ModGhpcywgbmV3QXNzZXJ0aW9uKTtcbiAgICByZXR1cm4gbmV3QXNzZXJ0aW9uO1xuICB9XG5cbiAgYWRkTGVuZ3RoR3VhcmQob3ZlcndyaXRpbmdNZXRob2RXcmFwcGVyLCBuYW1lLCBmYWxzZSk7XG4gIGN0eFtuYW1lXSA9IHByb3hpZnkob3ZlcndyaXRpbmdNZXRob2RXcmFwcGVyLCBuYW1lKTtcbn07XG4iLCAiLyohXG4gKiBDaGFpIC0gYWRkQ2hhaW5pbmdNZXRob2QgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbi8qIVxuICogTW9kdWxlIGRlcGVuZGVuY2llc1xuICovXG5cbnZhciBhZGRMZW5ndGhHdWFyZCA9IHJlcXVpcmUoJy4vYWRkTGVuZ3RoR3VhcmQnKTtcbnZhciBjaGFpID0gcmVxdWlyZSgnLi4vLi4vY2hhaScpO1xudmFyIGZsYWcgPSByZXF1aXJlKCcuL2ZsYWcnKTtcbnZhciBwcm94aWZ5ID0gcmVxdWlyZSgnLi9wcm94aWZ5Jyk7XG52YXIgdHJhbnNmZXJGbGFncyA9IHJlcXVpcmUoJy4vdHJhbnNmZXJGbGFncycpO1xuXG4vKiFcbiAqIE1vZHVsZSB2YXJpYWJsZXNcbiAqL1xuXG4vLyBDaGVjayB3aGV0aGVyIGBPYmplY3Quc2V0UHJvdG90eXBlT2ZgIGlzIHN1cHBvcnRlZFxudmFyIGNhblNldFByb3RvdHlwZSA9IHR5cGVvZiBPYmplY3Quc2V0UHJvdG90eXBlT2YgPT09ICdmdW5jdGlvbic7XG5cbi8vIFdpdGhvdXQgYE9iamVjdC5zZXRQcm90b3R5cGVPZmAgc3VwcG9ydCwgdGhpcyBtb2R1bGUgd2lsbCBuZWVkIHRvIGFkZCBwcm9wZXJ0aWVzIHRvIGEgZnVuY3Rpb24uXG4vLyBIb3dldmVyLCBzb21lIG9mIGZ1bmN0aW9ucycgb3duIHByb3BzIGFyZSBub3QgY29uZmlndXJhYmxlIGFuZCBzaG91bGQgYmUgc2tpcHBlZC5cbnZhciB0ZXN0Rm4gPSBmdW5jdGlvbigpIHt9O1xudmFyIGV4Y2x1ZGVOYW1lcyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHRlc3RGbikuZmlsdGVyKGZ1bmN0aW9uKG5hbWUpIHtcbiAgdmFyIHByb3BEZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0ZXN0Rm4sIG5hbWUpO1xuXG4gIC8vIE5vdGU6IFBoYW50b21KUyAxLnggaW5jbHVkZXMgYGNhbGxlZWAgYXMgb25lIG9mIGB0ZXN0Rm5gJ3Mgb3duIHByb3BlcnRpZXMsXG4gIC8vIGJ1dCB0aGVuIHJldHVybnMgYHVuZGVmaW5lZGAgYXMgdGhlIHByb3BlcnR5IGRlc2NyaXB0b3IgZm9yIGBjYWxsZWVgLiBBcyBhXG4gIC8vIHdvcmthcm91bmQsIHdlIHBlcmZvcm0gYW4gb3RoZXJ3aXNlIHVubmVjZXNzYXJ5IHR5cGUtY2hlY2sgZm9yIGBwcm9wRGVzY2AsXG4gIC8vIGFuZCB0aGVuIGZpbHRlciBpdCBvdXQgaWYgaXQncyBub3QgYW4gb2JqZWN0IGFzIGl0IHNob3VsZCBiZS5cbiAgaWYgKHR5cGVvZiBwcm9wRGVzYyAhPT0gJ29iamVjdCcpXG4gICAgcmV0dXJuIHRydWU7XG5cbiAgcmV0dXJuICFwcm9wRGVzYy5jb25maWd1cmFibGU7XG59KTtcblxuLy8gQ2FjaGUgYEZ1bmN0aW9uYCBwcm9wZXJ0aWVzXG52YXIgY2FsbCAgPSBGdW5jdGlvbi5wcm90b3R5cGUuY2FsbCxcbiAgICBhcHBseSA9IEZ1bmN0aW9uLnByb3RvdHlwZS5hcHBseTtcblxuLyoqXG4gKiAjIyMgLmFkZENoYWluYWJsZU1ldGhvZChjdHgsIG5hbWUsIG1ldGhvZCwgY2hhaW5pbmdCZWhhdmlvcilcbiAqXG4gKiBBZGRzIGEgbWV0aG9kIHRvIGFuIG9iamVjdCwgc3VjaCB0aGF0IHRoZSBtZXRob2QgY2FuIGFsc28gYmUgY2hhaW5lZC5cbiAqXG4gKiAgICAgdXRpbHMuYWRkQ2hhaW5hYmxlTWV0aG9kKGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZSwgJ2ZvbycsIGZ1bmN0aW9uIChzdHIpIHtcbiAqICAgICAgIHZhciBvYmogPSB1dGlscy5mbGFnKHRoaXMsICdvYmplY3QnKTtcbiAqICAgICAgIG5ldyBjaGFpLkFzc2VydGlvbihvYmopLnRvLmJlLmVxdWFsKHN0cik7XG4gKiAgICAgfSk7XG4gKlxuICogQ2FuIGFsc28gYmUgYWNjZXNzZWQgZGlyZWN0bHkgZnJvbSBgY2hhaS5Bc3NlcnRpb25gLlxuICpcbiAqICAgICBjaGFpLkFzc2VydGlvbi5hZGRDaGFpbmFibGVNZXRob2QoJ2ZvbycsIGZuLCBjaGFpbmluZ0JlaGF2aW9yKTtcbiAqXG4gKiBUaGUgcmVzdWx0IGNhbiB0aGVuIGJlIHVzZWQgYXMgYm90aCBhIG1ldGhvZCBhc3NlcnRpb24sIGV4ZWN1dGluZyBib3RoIGBtZXRob2RgIGFuZFxuICogYGNoYWluaW5nQmVoYXZpb3JgLCBvciBhcyBhIGxhbmd1YWdlIGNoYWluLCB3aGljaCBvbmx5IGV4ZWN1dGVzIGBjaGFpbmluZ0JlaGF2aW9yYC5cbiAqXG4gKiAgICAgZXhwZWN0KGZvb1N0cikudG8uYmUuZm9vKCdiYXInKTtcbiAqICAgICBleHBlY3QoZm9vU3RyKS50by5iZS5mb28uZXF1YWwoJ2ZvbycpO1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjdHggb2JqZWN0IHRvIHdoaWNoIHRoZSBtZXRob2QgaXMgYWRkZWRcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIG9mIG1ldGhvZCB0byBhZGRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IG1ldGhvZCBmdW5jdGlvbiB0byBiZSB1c2VkIGZvciBgbmFtZWAsIHdoZW4gY2FsbGVkXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjaGFpbmluZ0JlaGF2aW9yIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCBldmVyeSB0aW1lIHRoZSBwcm9wZXJ0eSBpcyBhY2Nlc3NlZFxuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQG5hbWUgYWRkQ2hhaW5hYmxlTWV0aG9kXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gYWRkQ2hhaW5hYmxlTWV0aG9kKGN0eCwgbmFtZSwgbWV0aG9kLCBjaGFpbmluZ0JlaGF2aW9yKSB7XG4gIGlmICh0eXBlb2YgY2hhaW5pbmdCZWhhdmlvciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIGNoYWluaW5nQmVoYXZpb3IgPSBmdW5jdGlvbiAoKSB7IH07XG4gIH1cblxuICB2YXIgY2hhaW5hYmxlQmVoYXZpb3IgPSB7XG4gICAgICBtZXRob2Q6IG1ldGhvZFxuICAgICwgY2hhaW5pbmdCZWhhdmlvcjogY2hhaW5pbmdCZWhhdmlvclxuICB9O1xuXG4gIC8vIHNhdmUgdGhlIG1ldGhvZHMgc28gd2UgY2FuIG92ZXJ3cml0ZSB0aGVtIGxhdGVyLCBpZiB3ZSBuZWVkIHRvLlxuICBpZiAoIWN0eC5fX21ldGhvZHMpIHtcbiAgICBjdHguX19tZXRob2RzID0ge307XG4gIH1cbiAgY3R4Ll9fbWV0aG9kc1tuYW1lXSA9IGNoYWluYWJsZUJlaGF2aW9yO1xuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjdHgsIG5hbWUsXG4gICAgeyBnZXQ6IGZ1bmN0aW9uIGNoYWluYWJsZU1ldGhvZEdldHRlcigpIHtcbiAgICAgICAgY2hhaW5hYmxlQmVoYXZpb3IuY2hhaW5pbmdCZWhhdmlvci5jYWxsKHRoaXMpO1xuXG4gICAgICAgIHZhciBjaGFpbmFibGVNZXRob2RXcmFwcGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIC8vIFNldHRpbmcgdGhlIGBzc2ZpYCBmbGFnIHRvIGBjaGFpbmFibGVNZXRob2RXcmFwcGVyYCBjYXVzZXMgdGhpc1xuICAgICAgICAgIC8vIGZ1bmN0aW9uIHRvIGJlIHRoZSBzdGFydGluZyBwb2ludCBmb3IgcmVtb3ZpbmcgaW1wbGVtZW50YXRpb25cbiAgICAgICAgICAvLyBmcmFtZXMgZnJvbSB0aGUgc3RhY2sgdHJhY2Ugb2YgYSBmYWlsZWQgYXNzZXJ0aW9uLlxuICAgICAgICAgIC8vXG4gICAgICAgICAgLy8gSG93ZXZlciwgd2Ugb25seSB3YW50IHRvIHVzZSB0aGlzIGZ1bmN0aW9uIGFzIHRoZSBzdGFydGluZyBwb2ludCBpZlxuICAgICAgICAgIC8vIHRoZSBgbG9ja1NzZmlgIGZsYWcgaXNuJ3Qgc2V0LlxuICAgICAgICAgIC8vXG4gICAgICAgICAgLy8gSWYgdGhlIGBsb2NrU3NmaWAgZmxhZyBpcyBzZXQsIHRoZW4gdGhpcyBhc3NlcnRpb24gaXMgYmVpbmdcbiAgICAgICAgICAvLyBpbnZva2VkIGZyb20gaW5zaWRlIG9mIGFub3RoZXIgYXNzZXJ0aW9uLiBJbiB0aGlzIGNhc2UsIHRoZSBgc3NmaWBcbiAgICAgICAgICAvLyBmbGFnIGhhcyBhbHJlYWR5IGJlZW4gc2V0IGJ5IHRoZSBvdXRlciBhc3NlcnRpb24uXG4gICAgICAgICAgLy9cbiAgICAgICAgICAvLyBOb3RlIHRoYXQgb3ZlcndyaXRpbmcgYSBjaGFpbmFibGUgbWV0aG9kIG1lcmVseSByZXBsYWNlcyB0aGUgc2F2ZWRcbiAgICAgICAgICAvLyBtZXRob2RzIGluIGBjdHguX19tZXRob2RzYCBpbnN0ZWFkIG9mIGNvbXBsZXRlbHkgcmVwbGFjaW5nIHRoZVxuICAgICAgICAgIC8vIG92ZXJ3cml0dGVuIGFzc2VydGlvbi4gVGhlcmVmb3JlLCBhbiBvdmVyd3JpdGluZyBhc3NlcnRpb24gd29uJ3RcbiAgICAgICAgICAvLyBzZXQgdGhlIGBzc2ZpYCBvciBgbG9ja1NzZmlgIGZsYWdzLlxuICAgICAgICAgIGlmICghZmxhZyh0aGlzLCAnbG9ja1NzZmknKSkge1xuICAgICAgICAgICAgZmxhZyh0aGlzLCAnc3NmaScsIGNoYWluYWJsZU1ldGhvZFdyYXBwZXIpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHZhciByZXN1bHQgPSBjaGFpbmFibGVCZWhhdmlvci5tZXRob2QuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdmFyIG5ld0Fzc2VydGlvbiA9IG5ldyBjaGFpLkFzc2VydGlvbigpO1xuICAgICAgICAgIHRyYW5zZmVyRmxhZ3ModGhpcywgbmV3QXNzZXJ0aW9uKTtcbiAgICAgICAgICByZXR1cm4gbmV3QXNzZXJ0aW9uO1xuICAgICAgICB9O1xuXG4gICAgICAgIGFkZExlbmd0aEd1YXJkKGNoYWluYWJsZU1ldGhvZFdyYXBwZXIsIG5hbWUsIHRydWUpO1xuXG4gICAgICAgIC8vIFVzZSBgT2JqZWN0LnNldFByb3RvdHlwZU9mYCBpZiBhdmFpbGFibGVcbiAgICAgICAgaWYgKGNhblNldFByb3RvdHlwZSkge1xuICAgICAgICAgIC8vIEluaGVyaXQgYWxsIHByb3BlcnRpZXMgZnJvbSB0aGUgb2JqZWN0IGJ5IHJlcGxhY2luZyB0aGUgYEZ1bmN0aW9uYCBwcm90b3R5cGVcbiAgICAgICAgICB2YXIgcHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSh0aGlzKTtcbiAgICAgICAgICAvLyBSZXN0b3JlIHRoZSBgY2FsbGAgYW5kIGBhcHBseWAgbWV0aG9kcyBmcm9tIGBGdW5jdGlvbmBcbiAgICAgICAgICBwcm90b3R5cGUuY2FsbCA9IGNhbGw7XG4gICAgICAgICAgcHJvdG90eXBlLmFwcGx5ID0gYXBwbHk7XG4gICAgICAgICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKGNoYWluYWJsZU1ldGhvZFdyYXBwZXIsIHByb3RvdHlwZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gT3RoZXJ3aXNlLCByZWRlZmluZSBhbGwgcHJvcGVydGllcyAoc2xvdyEpXG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHZhciBhc3NlcnRlck5hbWVzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoY3R4KTtcbiAgICAgICAgICBhc3NlcnRlck5hbWVzLmZvckVhY2goZnVuY3Rpb24gKGFzc2VydGVyTmFtZSkge1xuICAgICAgICAgICAgaWYgKGV4Y2x1ZGVOYW1lcy5pbmRleE9mKGFzc2VydGVyTmFtZSkgIT09IC0xKSB7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIHBkID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihjdHgsIGFzc2VydGVyTmFtZSk7XG4gICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY2hhaW5hYmxlTWV0aG9kV3JhcHBlciwgYXNzZXJ0ZXJOYW1lLCBwZCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICB0cmFuc2ZlckZsYWdzKHRoaXMsIGNoYWluYWJsZU1ldGhvZFdyYXBwZXIpO1xuICAgICAgICByZXR1cm4gcHJveGlmeShjaGFpbmFibGVNZXRob2RXcmFwcGVyKTtcbiAgICAgIH1cbiAgICAsIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICB9KTtcbn07XG4iLCAiLyohXG4gKiBDaGFpIC0gb3ZlcndyaXRlQ2hhaW5hYmxlTWV0aG9kIHV0aWxpdHlcbiAqIENvcHlyaWdodChjKSAyMDEyLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG52YXIgY2hhaSA9IHJlcXVpcmUoJy4uLy4uL2NoYWknKTtcbnZhciB0cmFuc2ZlckZsYWdzID0gcmVxdWlyZSgnLi90cmFuc2ZlckZsYWdzJyk7XG5cbi8qKlxuICogIyMjIC5vdmVyd3JpdGVDaGFpbmFibGVNZXRob2QoY3R4LCBuYW1lLCBtZXRob2QsIGNoYWluaW5nQmVoYXZpb3IpXG4gKlxuICogT3ZlcndyaXRlcyBhbiBhbHJlYWR5IGV4aXN0aW5nIGNoYWluYWJsZSBtZXRob2RcbiAqIGFuZCBwcm92aWRlcyBhY2Nlc3MgdG8gdGhlIHByZXZpb3VzIGZ1bmN0aW9uIG9yXG4gKiBwcm9wZXJ0eS4gIE11c3QgcmV0dXJuIGZ1bmN0aW9ucyB0byBiZSB1c2VkIGZvclxuICogbmFtZS5cbiAqXG4gKiAgICAgdXRpbHMub3ZlcndyaXRlQ2hhaW5hYmxlTWV0aG9kKGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZSwgJ2xlbmd0aE9mJyxcbiAqICAgICAgIGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAqICAgICAgIH1cbiAqICAgICAsIGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAqICAgICAgIH1cbiAqICAgICApO1xuICpcbiAqIENhbiBhbHNvIGJlIGFjY2Vzc2VkIGRpcmVjdGx5IGZyb20gYGNoYWkuQXNzZXJ0aW9uYC5cbiAqXG4gKiAgICAgY2hhaS5Bc3NlcnRpb24ub3ZlcndyaXRlQ2hhaW5hYmxlTWV0aG9kKCdmb28nLCBmbiwgZm4pO1xuICpcbiAqIFRoZW4gY2FuIGJlIHVzZWQgYXMgYW55IG90aGVyIGFzc2VydGlvbi5cbiAqXG4gKiAgICAgZXhwZWN0KG15Rm9vKS50by5oYXZlLmxlbmd0aE9mKDMpO1xuICogICAgIGV4cGVjdChteUZvbykudG8uaGF2ZS5sZW5ndGhPZi5hYm92ZSgzKTtcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY3R4IG9iamVjdCB3aG9zZSBtZXRob2QgLyBwcm9wZXJ0eSBpcyB0byBiZSBvdmVyd3JpdHRlblxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgb2YgbWV0aG9kIC8gcHJvcGVydHkgdG8gb3ZlcndyaXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBtZXRob2QgZnVuY3Rpb24gdGhhdCByZXR1cm5zIGEgZnVuY3Rpb24gdG8gYmUgdXNlZCBmb3IgbmFtZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2hhaW5pbmdCZWhhdmlvciBmdW5jdGlvbiB0aGF0IHJldHVybnMgYSBmdW5jdGlvbiB0byBiZSB1c2VkIGZvciBwcm9wZXJ0eVxuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQG5hbWUgb3ZlcndyaXRlQ2hhaW5hYmxlTWV0aG9kXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gb3ZlcndyaXRlQ2hhaW5hYmxlTWV0aG9kKGN0eCwgbmFtZSwgbWV0aG9kLCBjaGFpbmluZ0JlaGF2aW9yKSB7XG4gIHZhciBjaGFpbmFibGVCZWhhdmlvciA9IGN0eC5fX21ldGhvZHNbbmFtZV07XG5cbiAgdmFyIF9jaGFpbmluZ0JlaGF2aW9yID0gY2hhaW5hYmxlQmVoYXZpb3IuY2hhaW5pbmdCZWhhdmlvcjtcbiAgY2hhaW5hYmxlQmVoYXZpb3IuY2hhaW5pbmdCZWhhdmlvciA9IGZ1bmN0aW9uIG92ZXJ3cml0aW5nQ2hhaW5hYmxlTWV0aG9kR2V0dGVyKCkge1xuICAgIHZhciByZXN1bHQgPSBjaGFpbmluZ0JlaGF2aW9yKF9jaGFpbmluZ0JlaGF2aW9yKS5jYWxsKHRoaXMpO1xuICAgIGlmIChyZXN1bHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICB2YXIgbmV3QXNzZXJ0aW9uID0gbmV3IGNoYWkuQXNzZXJ0aW9uKCk7XG4gICAgdHJhbnNmZXJGbGFncyh0aGlzLCBuZXdBc3NlcnRpb24pO1xuICAgIHJldHVybiBuZXdBc3NlcnRpb247XG4gIH07XG5cbiAgdmFyIF9tZXRob2QgPSBjaGFpbmFibGVCZWhhdmlvci5tZXRob2Q7XG4gIGNoYWluYWJsZUJlaGF2aW9yLm1ldGhvZCA9IGZ1bmN0aW9uIG92ZXJ3cml0aW5nQ2hhaW5hYmxlTWV0aG9kV3JhcHBlcigpIHtcbiAgICB2YXIgcmVzdWx0ID0gbWV0aG9kKF9tZXRob2QpLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgaWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIHZhciBuZXdBc3NlcnRpb24gPSBuZXcgY2hhaS5Bc3NlcnRpb24oKTtcbiAgICB0cmFuc2ZlckZsYWdzKHRoaXMsIG5ld0Fzc2VydGlvbik7XG4gICAgcmV0dXJuIG5ld0Fzc2VydGlvbjtcbiAgfTtcbn07XG4iLCAiLyohXG4gKiBDaGFpIC0gY29tcGFyZUJ5SW5zcGVjdCB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMS0yMDE2IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyohXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzXG4gKi9cblxudmFyIGluc3BlY3QgPSByZXF1aXJlKCcuL2luc3BlY3QnKTtcblxuLyoqXG4gKiAjIyMgLmNvbXBhcmVCeUluc3BlY3QobWl4ZWQsIG1peGVkKVxuICpcbiAqIFRvIGJlIHVzZWQgYXMgYSBjb21wYXJlRnVuY3Rpb24gd2l0aCBBcnJheS5wcm90b3R5cGUuc29ydC4gQ29tcGFyZXMgZWxlbWVudHNcbiAqIHVzaW5nIGluc3BlY3QgaW5zdGVhZCBvZiBkZWZhdWx0IGJlaGF2aW9yIG9mIHVzaW5nIHRvU3RyaW5nIHNvIHRoYXQgU3ltYm9sc1xuICogYW5kIG9iamVjdHMgd2l0aCBpcnJlZ3VsYXIvbWlzc2luZyB0b1N0cmluZyBjYW4gc3RpbGwgYmUgc29ydGVkIHdpdGhvdXQgYVxuICogVHlwZUVycm9yLlxuICpcbiAqIEBwYXJhbSB7TWl4ZWR9IGZpcnN0IGVsZW1lbnQgdG8gY29tcGFyZVxuICogQHBhcmFtIHtNaXhlZH0gc2Vjb25kIGVsZW1lbnQgdG8gY29tcGFyZVxuICogQHJldHVybnMge051bWJlcn0gLTEgaWYgJ2EnIHNob3VsZCBjb21lIGJlZm9yZSAnYic7IG90aGVyd2lzZSAxXG4gKiBAbmFtZSBjb21wYXJlQnlJbnNwZWN0XG4gKiBAbmFtZXNwYWNlIFV0aWxzXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gY29tcGFyZUJ5SW5zcGVjdChhLCBiKSB7XG4gIHJldHVybiBpbnNwZWN0KGEpIDwgaW5zcGVjdChiKSA/IC0xIDogMTtcbn07XG4iLCAiLyohXG4gKiBDaGFpIC0gZ2V0T3duRW51bWVyYWJsZVByb3BlcnR5U3ltYm9scyB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMS0yMDE2IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyoqXG4gKiAjIyMgLmdldE93bkVudW1lcmFibGVQcm9wZXJ0eVN5bWJvbHMob2JqZWN0KVxuICpcbiAqIFRoaXMgYWxsb3dzIHRoZSByZXRyaWV2YWwgb2YgZGlyZWN0bHktb3duZWQgZW51bWVyYWJsZSBwcm9wZXJ0eSBzeW1ib2xzIG9mIGFuXG4gKiBvYmplY3QuIFRoaXMgZnVuY3Rpb24gaXMgbmVjZXNzYXJ5IGJlY2F1c2UgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9sc1xuICogcmV0dXJucyBib3RoIGVudW1lcmFibGUgYW5kIG5vbi1lbnVtZXJhYmxlIHByb3BlcnR5IHN5bWJvbHMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICogQHJldHVybnMge0FycmF5fVxuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQG5hbWUgZ2V0T3duRW51bWVyYWJsZVByb3BlcnR5U3ltYm9sc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGdldE93bkVudW1lcmFibGVQcm9wZXJ0eVN5bWJvbHMob2JqKSB7XG4gIGlmICh0eXBlb2YgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyAhPT0gJ2Z1bmN0aW9uJykgcmV0dXJuIFtdO1xuXG4gIHJldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKG9iaikuZmlsdGVyKGZ1bmN0aW9uIChzeW0pIHtcbiAgICByZXR1cm4gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihvYmosIHN5bSkuZW51bWVyYWJsZTtcbiAgfSk7XG59O1xuIiwgIi8qIVxuICogQ2hhaSAtIGdldE93bkVudW1lcmFibGVQcm9wZXJ0aWVzIHV0aWxpdHlcbiAqIENvcHlyaWdodChjKSAyMDExLTIwMTYgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG4vKiFcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXNcbiAqL1xuXG52YXIgZ2V0T3duRW51bWVyYWJsZVByb3BlcnR5U3ltYm9scyA9IHJlcXVpcmUoJy4vZ2V0T3duRW51bWVyYWJsZVByb3BlcnR5U3ltYm9scycpO1xuXG4vKipcbiAqICMjIyAuZ2V0T3duRW51bWVyYWJsZVByb3BlcnRpZXMob2JqZWN0KVxuICpcbiAqIFRoaXMgYWxsb3dzIHRoZSByZXRyaWV2YWwgb2YgZGlyZWN0bHktb3duZWQgZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBhbmRcbiAqIHN5bWJvbHMgb2YgYW4gb2JqZWN0LiBUaGlzIGZ1bmN0aW9uIGlzIG5lY2Vzc2FyeSBiZWNhdXNlIE9iamVjdC5rZXlzIG9ubHlcbiAqIHJldHVybnMgZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcywgbm90IGVudW1lcmFibGUgcHJvcGVydHkgc3ltYm9scy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gKiBAcmV0dXJucyB7QXJyYXl9XG4gKiBAbmFtZXNwYWNlIFV0aWxzXG4gKiBAbmFtZSBnZXRPd25FbnVtZXJhYmxlUHJvcGVydGllc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGdldE93bkVudW1lcmFibGVQcm9wZXJ0aWVzKG9iaikge1xuICByZXR1cm4gT2JqZWN0LmtleXMob2JqKS5jb25jYXQoZ2V0T3duRW51bWVyYWJsZVByb3BlcnR5U3ltYm9scyhvYmopKTtcbn07XG4iLCAiJ3VzZSBzdHJpY3QnO1xuXG4vKiAhXG4gKiBDaGFpIC0gY2hlY2tFcnJvciB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE2IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyoqXG4gKiAjIyMgLmNoZWNrRXJyb3JcbiAqXG4gKiBDaGVja3MgdGhhdCBhbiBlcnJvciBjb25mb3JtcyB0byBhIGdpdmVuIHNldCBvZiBjcml0ZXJpYSBhbmQvb3IgcmV0cmlldmVzIGluZm9ybWF0aW9uIGFib3V0IGl0LlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuLyoqXG4gKiAjIyMgLmNvbXBhdGlibGVJbnN0YW5jZSh0aHJvd24sIGVycm9yTGlrZSlcbiAqXG4gKiBDaGVja3MgaWYgdHdvIGluc3RhbmNlcyBhcmUgY29tcGF0aWJsZSAoc3RyaWN0IGVxdWFsKS5cbiAqIFJldHVybnMgZmFsc2UgaWYgZXJyb3JMaWtlIGlzIG5vdCBhbiBpbnN0YW5jZSBvZiBFcnJvciwgYmVjYXVzZSBpbnN0YW5jZXNcbiAqIGNhbiBvbmx5IGJlIGNvbXBhdGlibGUgaWYgdGhleSdyZSBib3RoIGVycm9yIGluc3RhbmNlcy5cbiAqXG4gKiBAbmFtZSBjb21wYXRpYmxlSW5zdGFuY2VcbiAqIEBwYXJhbSB7RXJyb3J9IHRocm93biBlcnJvclxuICogQHBhcmFtIHtFcnJvcnxFcnJvckNvbnN0cnVjdG9yfSBlcnJvckxpa2Ugb2JqZWN0IHRvIGNvbXBhcmUgYWdhaW5zdFxuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBjb21wYXRpYmxlSW5zdGFuY2UodGhyb3duLCBlcnJvckxpa2UpIHtcbiAgcmV0dXJuIGVycm9yTGlrZSBpbnN0YW5jZW9mIEVycm9yICYmIHRocm93biA9PT0gZXJyb3JMaWtlO1xufVxuXG4vKipcbiAqICMjIyAuY29tcGF0aWJsZUNvbnN0cnVjdG9yKHRocm93biwgZXJyb3JMaWtlKVxuICpcbiAqIENoZWNrcyBpZiB0d28gY29uc3RydWN0b3JzIGFyZSBjb21wYXRpYmxlLlxuICogVGhpcyBmdW5jdGlvbiBjYW4gcmVjZWl2ZSBlaXRoZXIgYW4gZXJyb3IgY29uc3RydWN0b3Igb3JcbiAqIGFuIGVycm9yIGluc3RhbmNlIGFzIHRoZSBgZXJyb3JMaWtlYCBhcmd1bWVudC5cbiAqIENvbnN0cnVjdG9ycyBhcmUgY29tcGF0aWJsZSBpZiB0aGV5J3JlIHRoZSBzYW1lIG9yIGlmIG9uZSBpc1xuICogYW4gaW5zdGFuY2Ugb2YgYW5vdGhlci5cbiAqXG4gKiBAbmFtZSBjb21wYXRpYmxlQ29uc3RydWN0b3JcbiAqIEBwYXJhbSB7RXJyb3J9IHRocm93biBlcnJvclxuICogQHBhcmFtIHtFcnJvcnxFcnJvckNvbnN0cnVjdG9yfSBlcnJvckxpa2Ugb2JqZWN0IHRvIGNvbXBhcmUgYWdhaW5zdFxuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBjb21wYXRpYmxlQ29uc3RydWN0b3IodGhyb3duLCBlcnJvckxpa2UpIHtcbiAgaWYgKGVycm9yTGlrZSBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgLy8gSWYgYGVycm9yTGlrZWAgaXMgYW4gaW5zdGFuY2Ugb2YgYW55IGVycm9yIHdlIGNvbXBhcmUgdGhlaXIgY29uc3RydWN0b3JzXG4gICAgcmV0dXJuIHRocm93bi5jb25zdHJ1Y3RvciA9PT0gZXJyb3JMaWtlLmNvbnN0cnVjdG9yIHx8IHRocm93biBpbnN0YW5jZW9mIGVycm9yTGlrZS5jb25zdHJ1Y3RvcjtcbiAgfSBlbHNlIGlmIChlcnJvckxpa2UucHJvdG90eXBlIGluc3RhbmNlb2YgRXJyb3IgfHwgZXJyb3JMaWtlID09PSBFcnJvcikge1xuICAgIC8vIElmIGBlcnJvckxpa2VgIGlzIGEgY29uc3RydWN0b3IgdGhhdCBpbmhlcml0cyBmcm9tIEVycm9yLCB3ZSBjb21wYXJlIGB0aHJvd25gIHRvIGBlcnJvckxpa2VgIGRpcmVjdGx5XG4gICAgcmV0dXJuIHRocm93bi5jb25zdHJ1Y3RvciA9PT0gZXJyb3JMaWtlIHx8IHRocm93biBpbnN0YW5jZW9mIGVycm9yTGlrZTtcbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuLyoqXG4gKiAjIyMgLmNvbXBhdGlibGVNZXNzYWdlKHRocm93biwgZXJyTWF0Y2hlcilcbiAqXG4gKiBDaGVja3MgaWYgYW4gZXJyb3IncyBtZXNzYWdlIGlzIGNvbXBhdGlibGUgd2l0aCBhIG1hdGNoZXIgKFN0cmluZyBvciBSZWdFeHApLlxuICogSWYgdGhlIG1lc3NhZ2UgY29udGFpbnMgdGhlIFN0cmluZyBvciBwYXNzZXMgdGhlIFJlZ0V4cCB0ZXN0LFxuICogaXQgaXMgY29uc2lkZXJlZCBjb21wYXRpYmxlLlxuICpcbiAqIEBuYW1lIGNvbXBhdGlibGVNZXNzYWdlXG4gKiBAcGFyYW0ge0Vycm9yfSB0aHJvd24gZXJyb3JcbiAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXJyTWF0Y2hlciB0byBsb29rIGZvciBpbnRvIHRoZSBtZXNzYWdlXG4gKiBAbmFtZXNwYWNlIFV0aWxzXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGNvbXBhdGlibGVNZXNzYWdlKHRocm93biwgZXJyTWF0Y2hlcikge1xuICB2YXIgY29tcGFyaXNvblN0cmluZyA9IHR5cGVvZiB0aHJvd24gPT09ICdzdHJpbmcnID8gdGhyb3duIDogdGhyb3duLm1lc3NhZ2U7XG4gIGlmIChlcnJNYXRjaGVyIGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgcmV0dXJuIGVyck1hdGNoZXIudGVzdChjb21wYXJpc29uU3RyaW5nKTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgZXJyTWF0Y2hlciA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gY29tcGFyaXNvblN0cmluZy5pbmRleE9mKGVyck1hdGNoZXIpICE9PSAtMTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1tYWdpYy1udW1iZXJzXG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogIyMjIC5nZXRGdW5jdGlvbk5hbWUoY29uc3RydWN0b3JGbilcbiAqXG4gKiBSZXR1cm5zIHRoZSBuYW1lIG9mIGEgZnVuY3Rpb24uXG4gKiBUaGlzIGFsc28gaW5jbHVkZXMgYSBwb2x5ZmlsbCBmdW5jdGlvbiBpZiBgY29uc3RydWN0b3JGbi5uYW1lYCBpcyBub3QgZGVmaW5lZC5cbiAqXG4gKiBAbmFtZSBnZXRGdW5jdGlvbk5hbWVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNvbnN0cnVjdG9yRm5cbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbnZhciBmdW5jdGlvbk5hbWVNYXRjaCA9IC9cXHMqZnVuY3Rpb24oPzpcXHN8XFxzKlxcL1xcKlteKD86KlxcLyldK1xcKlxcL1xccyopKihbXlxcKFxcL10rKS87XG5mdW5jdGlvbiBnZXRGdW5jdGlvbk5hbWUoY29uc3RydWN0b3JGbikge1xuICB2YXIgbmFtZSA9ICcnO1xuICBpZiAodHlwZW9mIGNvbnN0cnVjdG9yRm4ubmFtZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAvLyBIZXJlIHdlIHJ1biBhIHBvbHlmaWxsIGlmIGNvbnN0cnVjdG9yRm4ubmFtZSBpcyBub3QgZGVmaW5lZFxuICAgIHZhciBtYXRjaCA9IFN0cmluZyhjb25zdHJ1Y3RvckZuKS5tYXRjaChmdW5jdGlvbk5hbWVNYXRjaCk7XG4gICAgaWYgKG1hdGNoKSB7XG4gICAgICBuYW1lID0gbWF0Y2hbMV07XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIG5hbWUgPSBjb25zdHJ1Y3RvckZuLm5hbWU7XG4gIH1cblxuICByZXR1cm4gbmFtZTtcbn1cblxuLyoqXG4gKiAjIyMgLmdldENvbnN0cnVjdG9yTmFtZShlcnJvckxpa2UpXG4gKlxuICogR2V0cyB0aGUgY29uc3RydWN0b3IgbmFtZSBmb3IgYW4gRXJyb3IgaW5zdGFuY2Ugb3IgY29uc3RydWN0b3IgaXRzZWxmLlxuICpcbiAqIEBuYW1lIGdldENvbnN0cnVjdG9yTmFtZVxuICogQHBhcmFtIHtFcnJvcnxFcnJvckNvbnN0cnVjdG9yfSBlcnJvckxpa2VcbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gZ2V0Q29uc3RydWN0b3JOYW1lKGVycm9yTGlrZSkge1xuICB2YXIgY29uc3RydWN0b3JOYW1lID0gZXJyb3JMaWtlO1xuICBpZiAoZXJyb3JMaWtlIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICBjb25zdHJ1Y3Rvck5hbWUgPSBnZXRGdW5jdGlvbk5hbWUoZXJyb3JMaWtlLmNvbnN0cnVjdG9yKTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgZXJyb3JMaWtlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgLy8gSWYgYGVycmAgaXMgbm90IGFuIGluc3RhbmNlIG9mIEVycm9yIGl0IGlzIGFuIGVycm9yIGNvbnN0cnVjdG9yIGl0c2VsZiBvciBhbm90aGVyIGZ1bmN0aW9uLlxuICAgIC8vIElmIHdlJ3ZlIGdvdCBhIGNvbW1vbiBmdW5jdGlvbiB3ZSBnZXQgaXRzIG5hbWUsIG90aGVyd2lzZSB3ZSBtYXkgbmVlZCB0byBjcmVhdGUgYSBuZXcgaW5zdGFuY2VcbiAgICAvLyBvZiB0aGUgZXJyb3IganVzdCBpbiBjYXNlIGl0J3MgYSBwb29ybHktY29uc3RydWN0ZWQgZXJyb3IuIFBsZWFzZSBzZWUgY2hhaWpzL2NoYWkvaXNzdWVzLzQ1IHRvIGtub3cgbW9yZS5cbiAgICBjb25zdHJ1Y3Rvck5hbWUgPSBnZXRGdW5jdGlvbk5hbWUoZXJyb3JMaWtlKS50cmltKCkgfHxcbiAgICAgICAgZ2V0RnVuY3Rpb25OYW1lKG5ldyBlcnJvckxpa2UoKSk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbmV3LWNhcFxuICB9XG5cbiAgcmV0dXJuIGNvbnN0cnVjdG9yTmFtZTtcbn1cblxuLyoqXG4gKiAjIyMgLmdldE1lc3NhZ2UoZXJyb3JMaWtlKVxuICpcbiAqIEdldHMgdGhlIGVycm9yIG1lc3NhZ2UgZnJvbSBhbiBlcnJvci5cbiAqIElmIGBlcnJgIGlzIGEgU3RyaW5nIGl0c2VsZiwgd2UgcmV0dXJuIGl0LlxuICogSWYgdGhlIGVycm9yIGhhcyBubyBtZXNzYWdlLCB3ZSByZXR1cm4gYW4gZW1wdHkgc3RyaW5nLlxuICpcbiAqIEBuYW1lIGdldE1lc3NhZ2VcbiAqIEBwYXJhbSB7RXJyb3J8U3RyaW5nfSBlcnJvckxpa2VcbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gZ2V0TWVzc2FnZShlcnJvckxpa2UpIHtcbiAgdmFyIG1zZyA9ICcnO1xuICBpZiAoZXJyb3JMaWtlICYmIGVycm9yTGlrZS5tZXNzYWdlKSB7XG4gICAgbXNnID0gZXJyb3JMaWtlLm1lc3NhZ2U7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGVycm9yTGlrZSA9PT0gJ3N0cmluZycpIHtcbiAgICBtc2cgPSBlcnJvckxpa2U7XG4gIH1cblxuICByZXR1cm4gbXNnO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgY29tcGF0aWJsZUluc3RhbmNlOiBjb21wYXRpYmxlSW5zdGFuY2UsXG4gIGNvbXBhdGlibGVDb25zdHJ1Y3RvcjogY29tcGF0aWJsZUNvbnN0cnVjdG9yLFxuICBjb21wYXRpYmxlTWVzc2FnZTogY29tcGF0aWJsZU1lc3NhZ2UsXG4gIGdldE1lc3NhZ2U6IGdldE1lc3NhZ2UsXG4gIGdldENvbnN0cnVjdG9yTmFtZTogZ2V0Q29uc3RydWN0b3JOYW1lLFxufTtcbiIsICIvKiFcbiAqIENoYWkgLSBpc05hTiB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE1IFNha3RoaXByaXlhbiBWYWlyYW1hbmkgPHRoZWNoYXJnaW5ndm9sY2Fub0BnbWFpbC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG4vKipcbiAqICMjIyAuaXNOYU4odmFsdWUpXG4gKlxuICogQ2hlY2tzIGlmIHRoZSBnaXZlbiB2YWx1ZSBpcyBOYU4gb3Igbm90LlxuICpcbiAqICAgICB1dGlscy5pc05hTihOYU4pOyAvLyB0cnVlXG4gKlxuICogQHBhcmFtIHtWYWx1ZX0gVGhlIHZhbHVlIHdoaWNoIGhhcyB0byBiZSBjaGVja2VkIGlmIGl0IGlzIE5hTlxuICogQG5hbWUgaXNOYU5cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGlzTmFOKHZhbHVlKSB7XG4gIC8vIFJlZmVyIGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1pc25hbi1udW1iZXJcbiAgLy8gc2VjdGlvbidzIE5PVEUuXG4gIHJldHVybiB2YWx1ZSAhPT0gdmFsdWU7XG59XG5cbi8vIElmIEVDTUFTY3JpcHQgNidzIE51bWJlci5pc05hTiBpcyBwcmVzZW50LCBwcmVmZXIgdGhhdC5cbm1vZHVsZS5leHBvcnRzID0gTnVtYmVyLmlzTmFOIHx8IGlzTmFOO1xuIiwgInZhciB0eXBlID0gcmVxdWlyZSgndHlwZS1kZXRlY3QnKTtcblxudmFyIGZsYWcgPSByZXF1aXJlKCcuL2ZsYWcnKTtcblxuZnVuY3Rpb24gaXNPYmplY3RUeXBlKG9iaikge1xuICB2YXIgb2JqZWN0VHlwZSA9IHR5cGUob2JqKTtcbiAgdmFyIG9iamVjdFR5cGVzID0gWydBcnJheScsICdPYmplY3QnLCAnZnVuY3Rpb24nXTtcblxuICByZXR1cm4gb2JqZWN0VHlwZXMuaW5kZXhPZihvYmplY3RUeXBlKSAhPT0gLTE7XG59XG5cbi8qKlxuICogIyMjIC5nZXRPcGVyYXRvcihtZXNzYWdlKVxuICpcbiAqIEV4dHJhY3QgdGhlIG9wZXJhdG9yIGZyb20gZXJyb3IgbWVzc2FnZS5cbiAqIE9wZXJhdG9yIGRlZmluZWQgaXMgYmFzZWQgb24gYmVsb3cgbGlua1xuICogaHR0cHM6Ly9ub2RlanMub3JnL2FwaS9hc3NlcnQuaHRtbCNhc3NlcnRfYXNzZXJ0LlxuICpcbiAqIFJldHVybnMgdGhlIGBvcGVyYXRvcmAgb3IgYHVuZGVmaW5lZGAgdmFsdWUgZm9yIGFuIEFzc2VydGlvbi5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IChjb25zdHJ1Y3RlZCBBc3NlcnRpb24pXG4gKiBAcGFyYW0ge0FyZ3VtZW50c30gY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLmFzc2VydCBhcmd1bWVudHNcbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBuYW1lIGdldE9wZXJhdG9yXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZ2V0T3BlcmF0b3Iob2JqLCBhcmdzKSB7XG4gIHZhciBvcGVyYXRvciA9IGZsYWcob2JqLCAnb3BlcmF0b3InKTtcbiAgdmFyIG5lZ2F0ZSA9IGZsYWcob2JqLCAnbmVnYXRlJyk7XG4gIHZhciBleHBlY3RlZCA9IGFyZ3NbM107XG4gIHZhciBtc2cgPSBuZWdhdGUgPyBhcmdzWzJdIDogYXJnc1sxXTtcblxuICBpZiAob3BlcmF0b3IpIHtcbiAgICByZXR1cm4gb3BlcmF0b3I7XG4gIH1cblxuICBpZiAodHlwZW9mIG1zZyA9PT0gJ2Z1bmN0aW9uJykgbXNnID0gbXNnKCk7XG5cbiAgbXNnID0gbXNnIHx8ICcnO1xuICBpZiAoIW1zZykge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBpZiAoL1xcc2hhdmVcXHMvLnRlc3QobXNnKSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICB2YXIgaXNPYmplY3QgPSBpc09iamVjdFR5cGUoZXhwZWN0ZWQpO1xuICBpZiAoL1xcc25vdFxccy8udGVzdChtc2cpKSB7XG4gICAgcmV0dXJuIGlzT2JqZWN0ID8gJ25vdERlZXBTdHJpY3RFcXVhbCcgOiAnbm90U3RyaWN0RXF1YWwnO1xuICB9XG5cbiAgcmV0dXJuIGlzT2JqZWN0ID8gJ2RlZXBTdHJpY3RFcXVhbCcgOiAnc3RyaWN0RXF1YWwnO1xufTtcbiIsICIvKiFcbiAqIGNoYWlcbiAqIENvcHlyaWdodChjKSAyMDExIEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyohXG4gKiBEZXBlbmRlbmNpZXMgdGhhdCBhcmUgdXNlZCBmb3IgbXVsdGlwbGUgZXhwb3J0cyBhcmUgcmVxdWlyZWQgaGVyZSBvbmx5IG9uY2VcbiAqL1xuXG52YXIgcGF0aHZhbCA9IHJlcXVpcmUoJ3BhdGh2YWwnKTtcblxuLyohXG4gKiB0ZXN0IHV0aWxpdHlcbiAqL1xuXG5leHBvcnRzLnRlc3QgPSByZXF1aXJlKCcuL3Rlc3QnKTtcblxuLyohXG4gKiB0eXBlIHV0aWxpdHlcbiAqL1xuXG5leHBvcnRzLnR5cGUgPSByZXF1aXJlKCd0eXBlLWRldGVjdCcpO1xuXG4vKiFcbiAqIGV4cGVjdFR5cGVzIHV0aWxpdHlcbiAqL1xuZXhwb3J0cy5leHBlY3RUeXBlcyA9IHJlcXVpcmUoJy4vZXhwZWN0VHlwZXMnKTtcblxuLyohXG4gKiBtZXNzYWdlIHV0aWxpdHlcbiAqL1xuXG5leHBvcnRzLmdldE1lc3NhZ2UgPSByZXF1aXJlKCcuL2dldE1lc3NhZ2UnKTtcblxuLyohXG4gKiBhY3R1YWwgdXRpbGl0eVxuICovXG5cbmV4cG9ydHMuZ2V0QWN0dWFsID0gcmVxdWlyZSgnLi9nZXRBY3R1YWwnKTtcblxuLyohXG4gKiBJbnNwZWN0IHV0aWxcbiAqL1xuXG5leHBvcnRzLmluc3BlY3QgPSByZXF1aXJlKCcuL2luc3BlY3QnKTtcblxuLyohXG4gKiBPYmplY3QgRGlzcGxheSB1dGlsXG4gKi9cblxuZXhwb3J0cy5vYmpEaXNwbGF5ID0gcmVxdWlyZSgnLi9vYmpEaXNwbGF5Jyk7XG5cbi8qIVxuICogRmxhZyB1dGlsaXR5XG4gKi9cblxuZXhwb3J0cy5mbGFnID0gcmVxdWlyZSgnLi9mbGFnJyk7XG5cbi8qIVxuICogRmxhZyB0cmFuc2ZlcnJpbmcgdXRpbGl0eVxuICovXG5cbmV4cG9ydHMudHJhbnNmZXJGbGFncyA9IHJlcXVpcmUoJy4vdHJhbnNmZXJGbGFncycpO1xuXG4vKiFcbiAqIERlZXAgZXF1YWwgdXRpbGl0eVxuICovXG5cbmV4cG9ydHMuZXFsID0gcmVxdWlyZSgnZGVlcC1lcWwnKTtcblxuLyohXG4gKiBEZWVwIHBhdGggaW5mb1xuICovXG5cbmV4cG9ydHMuZ2V0UGF0aEluZm8gPSBwYXRodmFsLmdldFBhdGhJbmZvO1xuXG4vKiFcbiAqIENoZWNrIGlmIGEgcHJvcGVydHkgZXhpc3RzXG4gKi9cblxuZXhwb3J0cy5oYXNQcm9wZXJ0eSA9IHBhdGh2YWwuaGFzUHJvcGVydHk7XG5cbi8qIVxuICogRnVuY3Rpb24gbmFtZVxuICovXG5cbmV4cG9ydHMuZ2V0TmFtZSA9IHJlcXVpcmUoJ2dldC1mdW5jLW5hbWUnKTtcblxuLyohXG4gKiBhZGQgUHJvcGVydHlcbiAqL1xuXG5leHBvcnRzLmFkZFByb3BlcnR5ID0gcmVxdWlyZSgnLi9hZGRQcm9wZXJ0eScpO1xuXG4vKiFcbiAqIGFkZCBNZXRob2RcbiAqL1xuXG5leHBvcnRzLmFkZE1ldGhvZCA9IHJlcXVpcmUoJy4vYWRkTWV0aG9kJyk7XG5cbi8qIVxuICogb3ZlcndyaXRlIFByb3BlcnR5XG4gKi9cblxuZXhwb3J0cy5vdmVyd3JpdGVQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vb3ZlcndyaXRlUHJvcGVydHknKTtcblxuLyohXG4gKiBvdmVyd3JpdGUgTWV0aG9kXG4gKi9cblxuZXhwb3J0cy5vdmVyd3JpdGVNZXRob2QgPSByZXF1aXJlKCcuL292ZXJ3cml0ZU1ldGhvZCcpO1xuXG4vKiFcbiAqIEFkZCBhIGNoYWluYWJsZSBtZXRob2RcbiAqL1xuXG5leHBvcnRzLmFkZENoYWluYWJsZU1ldGhvZCA9IHJlcXVpcmUoJy4vYWRkQ2hhaW5hYmxlTWV0aG9kJyk7XG5cbi8qIVxuICogT3ZlcndyaXRlIGNoYWluYWJsZSBtZXRob2RcbiAqL1xuXG5leHBvcnRzLm92ZXJ3cml0ZUNoYWluYWJsZU1ldGhvZCA9IHJlcXVpcmUoJy4vb3ZlcndyaXRlQ2hhaW5hYmxlTWV0aG9kJyk7XG5cbi8qIVxuICogQ29tcGFyZSBieSBpbnNwZWN0IG1ldGhvZFxuICovXG5cbmV4cG9ydHMuY29tcGFyZUJ5SW5zcGVjdCA9IHJlcXVpcmUoJy4vY29tcGFyZUJ5SW5zcGVjdCcpO1xuXG4vKiFcbiAqIEdldCBvd24gZW51bWVyYWJsZSBwcm9wZXJ0eSBzeW1ib2xzIG1ldGhvZFxuICovXG5cbmV4cG9ydHMuZ2V0T3duRW51bWVyYWJsZVByb3BlcnR5U3ltYm9scyA9IHJlcXVpcmUoJy4vZ2V0T3duRW51bWVyYWJsZVByb3BlcnR5U3ltYm9scycpO1xuXG4vKiFcbiAqIEdldCBvd24gZW51bWVyYWJsZSBwcm9wZXJ0aWVzIG1ldGhvZFxuICovXG5cbmV4cG9ydHMuZ2V0T3duRW51bWVyYWJsZVByb3BlcnRpZXMgPSByZXF1aXJlKCcuL2dldE93bkVudW1lcmFibGVQcm9wZXJ0aWVzJyk7XG5cbi8qIVxuICogQ2hlY2tzIGVycm9yIGFnYWluc3QgYSBnaXZlbiBzZXQgb2YgY3JpdGVyaWFcbiAqL1xuXG5leHBvcnRzLmNoZWNrRXJyb3IgPSByZXF1aXJlKCdjaGVjay1lcnJvcicpO1xuXG4vKiFcbiAqIFByb3hpZnkgdXRpbFxuICovXG5cbmV4cG9ydHMucHJveGlmeSA9IHJlcXVpcmUoJy4vcHJveGlmeScpO1xuXG4vKiFcbiAqIGFkZExlbmd0aEd1YXJkIHV0aWxcbiAqL1xuXG5leHBvcnRzLmFkZExlbmd0aEd1YXJkID0gcmVxdWlyZSgnLi9hZGRMZW5ndGhHdWFyZCcpO1xuXG4vKiFcbiAqIGlzUHJveHlFbmFibGVkIGhlbHBlclxuICovXG5cbmV4cG9ydHMuaXNQcm94eUVuYWJsZWQgPSByZXF1aXJlKCcuL2lzUHJveHlFbmFibGVkJyk7XG5cbi8qIVxuICogaXNOYU4gbWV0aG9kXG4gKi9cblxuZXhwb3J0cy5pc05hTiA9IHJlcXVpcmUoJy4vaXNOYU4nKTtcblxuLyohXG4gKiBnZXRPcGVyYXRvciBtZXRob2RcbiAqL1xuXG5leHBvcnRzLmdldE9wZXJhdG9yID0gcmVxdWlyZSgnLi9nZXRPcGVyYXRvcicpOyIsICIvKiFcbiAqIGNoYWlcbiAqIGh0dHA6Ly9jaGFpanMuY29tXG4gKiBDb3B5cmlnaHQoYykgMjAxMS0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxudmFyIGNvbmZpZyA9IHJlcXVpcmUoJy4vY29uZmlnJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKF9jaGFpLCB1dGlsKSB7XG4gIC8qIVxuICAgKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICAgKi9cblxuICB2YXIgQXNzZXJ0aW9uRXJyb3IgPSBfY2hhaS5Bc3NlcnRpb25FcnJvclxuICAgICwgZmxhZyA9IHV0aWwuZmxhZztcblxuICAvKiFcbiAgICogTW9kdWxlIGV4cG9ydC5cbiAgICovXG5cbiAgX2NoYWkuQXNzZXJ0aW9uID0gQXNzZXJ0aW9uO1xuXG4gIC8qIVxuICAgKiBBc3NlcnRpb24gQ29uc3RydWN0b3JcbiAgICpcbiAgICogQ3JlYXRlcyBvYmplY3QgZm9yIGNoYWluaW5nLlxuICAgKlxuICAgKiBgQXNzZXJ0aW9uYCBvYmplY3RzIGNvbnRhaW4gbWV0YWRhdGEgaW4gdGhlIGZvcm0gb2YgZmxhZ3MuIFRocmVlIGZsYWdzIGNhblxuICAgKiBiZSBhc3NpZ25lZCBkdXJpbmcgaW5zdGFudGlhdGlvbiBieSBwYXNzaW5nIGFyZ3VtZW50cyB0byB0aGlzIGNvbnN0cnVjdG9yOlxuICAgKlxuICAgKiAtIGBvYmplY3RgOiBUaGlzIGZsYWcgY29udGFpbnMgdGhlIHRhcmdldCBvZiB0aGUgYXNzZXJ0aW9uLiBGb3IgZXhhbXBsZSwgaW5cbiAgICogICB0aGUgYXNzZXJ0aW9uIGBleHBlY3QobnVtS2l0dGVucykudG8uZXF1YWwoNyk7YCwgdGhlIGBvYmplY3RgIGZsYWcgd2lsbFxuICAgKiAgIGNvbnRhaW4gYG51bUtpdHRlbnNgIHNvIHRoYXQgdGhlIGBlcXVhbGAgYXNzZXJ0aW9uIGNhbiByZWZlcmVuY2UgaXQgd2hlblxuICAgKiAgIG5lZWRlZC5cbiAgICpcbiAgICogLSBgbWVzc2FnZWA6IFRoaXMgZmxhZyBjb250YWlucyBhbiBvcHRpb25hbCBjdXN0b20gZXJyb3IgbWVzc2FnZSB0byBiZVxuICAgKiAgIHByZXBlbmRlZCB0byB0aGUgZXJyb3IgbWVzc2FnZSB0aGF0J3MgZ2VuZXJhdGVkIGJ5IHRoZSBhc3NlcnRpb24gd2hlbiBpdFxuICAgKiAgIGZhaWxzLlxuICAgKlxuICAgKiAtIGBzc2ZpYDogVGhpcyBmbGFnIHN0YW5kcyBmb3IgXCJzdGFydCBzdGFjayBmdW5jdGlvbiBpbmRpY2F0b3JcIi4gSXRcbiAgICogICBjb250YWlucyBhIGZ1bmN0aW9uIHJlZmVyZW5jZSB0aGF0IHNlcnZlcyBhcyB0aGUgc3RhcnRpbmcgcG9pbnQgZm9yXG4gICAqICAgcmVtb3ZpbmcgZnJhbWVzIGZyb20gdGhlIHN0YWNrIHRyYWNlIG9mIHRoZSBlcnJvciB0aGF0J3MgY3JlYXRlZCBieSB0aGVcbiAgICogICBhc3NlcnRpb24gd2hlbiBpdCBmYWlscy4gVGhlIGdvYWwgaXMgdG8gcHJvdmlkZSBhIGNsZWFuZXIgc3RhY2sgdHJhY2UgdG9cbiAgICogICBlbmQgdXNlcnMgYnkgcmVtb3ZpbmcgQ2hhaSdzIGludGVybmFsIGZ1bmN0aW9ucy4gTm90ZSB0aGF0IGl0IG9ubHkgd29ya3NcbiAgICogICBpbiBlbnZpcm9ubWVudHMgdGhhdCBzdXBwb3J0IGBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZWAsIGFuZCBvbmx5IHdoZW5cbiAgICogICBgQ2hhaS5jb25maWcuaW5jbHVkZVN0YWNrYCBoYXNuJ3QgYmVlbiBzZXQgdG8gYGZhbHNlYC5cbiAgICpcbiAgICogLSBgbG9ja1NzZmlgOiBUaGlzIGZsYWcgY29udHJvbHMgd2hldGhlciBvciBub3QgdGhlIGdpdmVuIGBzc2ZpYCBmbGFnXG4gICAqICAgc2hvdWxkIHJldGFpbiBpdHMgY3VycmVudCB2YWx1ZSwgZXZlbiBhcyBhc3NlcnRpb25zIGFyZSBjaGFpbmVkIG9mZiBvZlxuICAgKiAgIHRoaXMgb2JqZWN0LiBUaGlzIGlzIHVzdWFsbHkgc2V0IHRvIGB0cnVlYCB3aGVuIGNyZWF0aW5nIGEgbmV3IGFzc2VydGlvblxuICAgKiAgIGZyb20gd2l0aGluIGFub3RoZXIgYXNzZXJ0aW9uLiBJdCdzIGFsc28gdGVtcG9yYXJpbHkgc2V0IHRvIGB0cnVlYCBiZWZvcmVcbiAgICogICBhbiBvdmVyd3JpdHRlbiBhc3NlcnRpb24gZ2V0cyBjYWxsZWQgYnkgdGhlIG92ZXJ3cml0aW5nIGFzc2VydGlvbi5cbiAgICpcbiAgICogQHBhcmFtIHtNaXhlZH0gb2JqIHRhcmdldCBvZiB0aGUgYXNzZXJ0aW9uXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtc2cgKG9wdGlvbmFsKSBjdXN0b20gZXJyb3IgbWVzc2FnZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBzc2ZpIChvcHRpb25hbCkgc3RhcnRpbmcgcG9pbnQgZm9yIHJlbW92aW5nIHN0YWNrIGZyYW1lc1xuICAgKiBAcGFyYW0ge0Jvb2xlYW59IGxvY2tTc2ZpIChvcHRpb25hbCkgd2hldGhlciBvciBub3QgdGhlIHNzZmkgZmxhZyBpcyBsb2NrZWRcbiAgICogQGFwaSBwcml2YXRlXG4gICAqL1xuXG4gIGZ1bmN0aW9uIEFzc2VydGlvbiAob2JqLCBtc2csIHNzZmksIGxvY2tTc2ZpKSB7XG4gICAgZmxhZyh0aGlzLCAnc3NmaScsIHNzZmkgfHwgQXNzZXJ0aW9uKTtcbiAgICBmbGFnKHRoaXMsICdsb2NrU3NmaScsIGxvY2tTc2ZpKTtcbiAgICBmbGFnKHRoaXMsICdvYmplY3QnLCBvYmopO1xuICAgIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuXG4gICAgcmV0dXJuIHV0aWwucHJveGlmeSh0aGlzKTtcbiAgfVxuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShBc3NlcnRpb24sICdpbmNsdWRlU3RhY2snLCB7XG4gICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnNvbGUud2FybignQXNzZXJ0aW9uLmluY2x1ZGVTdGFjayBpcyBkZXByZWNhdGVkLCB1c2UgY2hhaS5jb25maWcuaW5jbHVkZVN0YWNrIGluc3RlYWQuJyk7XG4gICAgICByZXR1cm4gY29uZmlnLmluY2x1ZGVTdGFjaztcbiAgICB9LFxuICAgIHNldDogZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIGNvbnNvbGUud2FybignQXNzZXJ0aW9uLmluY2x1ZGVTdGFjayBpcyBkZXByZWNhdGVkLCB1c2UgY2hhaS5jb25maWcuaW5jbHVkZVN0YWNrIGluc3RlYWQuJyk7XG4gICAgICBjb25maWcuaW5jbHVkZVN0YWNrID0gdmFsdWU7XG4gICAgfVxuICB9KTtcblxuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQXNzZXJ0aW9uLCAnc2hvd0RpZmYnLCB7XG4gICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnNvbGUud2FybignQXNzZXJ0aW9uLnNob3dEaWZmIGlzIGRlcHJlY2F0ZWQsIHVzZSBjaGFpLmNvbmZpZy5zaG93RGlmZiBpbnN0ZWFkLicpO1xuICAgICAgcmV0dXJuIGNvbmZpZy5zaG93RGlmZjtcbiAgICB9LFxuICAgIHNldDogZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIGNvbnNvbGUud2FybignQXNzZXJ0aW9uLnNob3dEaWZmIGlzIGRlcHJlY2F0ZWQsIHVzZSBjaGFpLmNvbmZpZy5zaG93RGlmZiBpbnN0ZWFkLicpO1xuICAgICAgY29uZmlnLnNob3dEaWZmID0gdmFsdWU7XG4gICAgfVxuICB9KTtcblxuICBBc3NlcnRpb24uYWRkUHJvcGVydHkgPSBmdW5jdGlvbiAobmFtZSwgZm4pIHtcbiAgICB1dGlsLmFkZFByb3BlcnR5KHRoaXMucHJvdG90eXBlLCBuYW1lLCBmbik7XG4gIH07XG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCA9IGZ1bmN0aW9uIChuYW1lLCBmbikge1xuICAgIHV0aWwuYWRkTWV0aG9kKHRoaXMucHJvdG90eXBlLCBuYW1lLCBmbik7XG4gIH07XG5cbiAgQXNzZXJ0aW9uLmFkZENoYWluYWJsZU1ldGhvZCA9IGZ1bmN0aW9uIChuYW1lLCBmbiwgY2hhaW5pbmdCZWhhdmlvcikge1xuICAgIHV0aWwuYWRkQ2hhaW5hYmxlTWV0aG9kKHRoaXMucHJvdG90eXBlLCBuYW1lLCBmbiwgY2hhaW5pbmdCZWhhdmlvcik7XG4gIH07XG5cbiAgQXNzZXJ0aW9uLm92ZXJ3cml0ZVByb3BlcnR5ID0gZnVuY3Rpb24gKG5hbWUsIGZuKSB7XG4gICAgdXRpbC5vdmVyd3JpdGVQcm9wZXJ0eSh0aGlzLnByb3RvdHlwZSwgbmFtZSwgZm4pO1xuICB9O1xuXG4gIEFzc2VydGlvbi5vdmVyd3JpdGVNZXRob2QgPSBmdW5jdGlvbiAobmFtZSwgZm4pIHtcbiAgICB1dGlsLm92ZXJ3cml0ZU1ldGhvZCh0aGlzLnByb3RvdHlwZSwgbmFtZSwgZm4pO1xuICB9O1xuXG4gIEFzc2VydGlvbi5vdmVyd3JpdGVDaGFpbmFibGVNZXRob2QgPSBmdW5jdGlvbiAobmFtZSwgZm4sIGNoYWluaW5nQmVoYXZpb3IpIHtcbiAgICB1dGlsLm92ZXJ3cml0ZUNoYWluYWJsZU1ldGhvZCh0aGlzLnByb3RvdHlwZSwgbmFtZSwgZm4sIGNoYWluaW5nQmVoYXZpb3IpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmFzc2VydChleHByZXNzaW9uLCBtZXNzYWdlLCBuZWdhdGVNZXNzYWdlLCBleHBlY3RlZCwgYWN0dWFsLCBzaG93RGlmZilcbiAgICpcbiAgICogRXhlY3V0ZXMgYW4gZXhwcmVzc2lvbiBhbmQgY2hlY2sgZXhwZWN0YXRpb25zLiBUaHJvd3MgQXNzZXJ0aW9uRXJyb3IgZm9yIHJlcG9ydGluZyBpZiB0ZXN0IGRvZXNuJ3QgcGFzcy5cbiAgICpcbiAgICogQG5hbWUgYXNzZXJ0XG4gICAqIEBwYXJhbSB7UGhpbG9zb3BoaWNhbH0gZXhwcmVzc2lvbiB0byBiZSB0ZXN0ZWRcbiAgICogQHBhcmFtIHtTdHJpbmd8RnVuY3Rpb259IG1lc3NhZ2Ugb3IgZnVuY3Rpb24gdGhhdCByZXR1cm5zIG1lc3NhZ2UgdG8gZGlzcGxheSBpZiBleHByZXNzaW9uIGZhaWxzXG4gICAqIEBwYXJhbSB7U3RyaW5nfEZ1bmN0aW9ufSBuZWdhdGVkTWVzc2FnZSBvciBmdW5jdGlvbiB0aGF0IHJldHVybnMgbmVnYXRlZE1lc3NhZ2UgdG8gZGlzcGxheSBpZiBuZWdhdGVkIGV4cHJlc3Npb24gZmFpbHNcbiAgICogQHBhcmFtIHtNaXhlZH0gZXhwZWN0ZWQgdmFsdWUgKHJlbWVtYmVyIHRvIGNoZWNrIGZvciBuZWdhdGlvbilcbiAgICogQHBhcmFtIHtNaXhlZH0gYWN0dWFsIChvcHRpb25hbCkgd2lsbCBkZWZhdWx0IHRvIGB0aGlzLm9iamBcbiAgICogQHBhcmFtIHtCb29sZWFufSBzaG93RGlmZiAob3B0aW9uYWwpIHdoZW4gc2V0IHRvIGB0cnVlYCwgYXNzZXJ0IHdpbGwgZGlzcGxheSBhIGRpZmYgaW4gYWRkaXRpb24gdG8gdGhlIG1lc3NhZ2UgaWYgZXhwcmVzc2lvbiBmYWlsc1xuICAgKiBAYXBpIHByaXZhdGVcbiAgICovXG5cbiAgQXNzZXJ0aW9uLnByb3RvdHlwZS5hc3NlcnQgPSBmdW5jdGlvbiAoZXhwciwgbXNnLCBuZWdhdGVNc2csIGV4cGVjdGVkLCBfYWN0dWFsLCBzaG93RGlmZikge1xuICAgIHZhciBvayA9IHV0aWwudGVzdCh0aGlzLCBhcmd1bWVudHMpO1xuICAgIGlmIChmYWxzZSAhPT0gc2hvd0RpZmYpIHNob3dEaWZmID0gdHJ1ZTtcbiAgICBpZiAodW5kZWZpbmVkID09PSBleHBlY3RlZCAmJiB1bmRlZmluZWQgPT09IF9hY3R1YWwpIHNob3dEaWZmID0gZmFsc2U7XG4gICAgaWYgKHRydWUgIT09IGNvbmZpZy5zaG93RGlmZikgc2hvd0RpZmYgPSBmYWxzZTtcblxuICAgIGlmICghb2spIHtcbiAgICAgIG1zZyA9IHV0aWwuZ2V0TWVzc2FnZSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgdmFyIGFjdHVhbCA9IHV0aWwuZ2V0QWN0dWFsKHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB2YXIgYXNzZXJ0aW9uRXJyb3JPYmplY3RQcm9wZXJ0aWVzID0ge1xuICAgICAgICAgIGFjdHVhbDogYWN0dWFsXG4gICAgICAgICwgZXhwZWN0ZWQ6IGV4cGVjdGVkXG4gICAgICAgICwgc2hvd0RpZmY6IHNob3dEaWZmXG4gICAgICB9O1xuXG4gICAgICB2YXIgb3BlcmF0b3IgPSB1dGlsLmdldE9wZXJhdG9yKHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICBpZiAob3BlcmF0b3IpIHtcbiAgICAgICAgYXNzZXJ0aW9uRXJyb3JPYmplY3RQcm9wZXJ0aWVzLm9wZXJhdG9yID0gb3BlcmF0b3I7XG4gICAgICB9XG5cbiAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihcbiAgICAgICAgbXNnLFxuICAgICAgICBhc3NlcnRpb25FcnJvck9iamVjdFByb3BlcnRpZXMsXG4gICAgICAgIChjb25maWcuaW5jbHVkZVN0YWNrKSA/IHRoaXMuYXNzZXJ0IDogZmxhZyh0aGlzLCAnc3NmaScpKTtcbiAgICB9XG4gIH07XG5cbiAgLyohXG4gICAqICMjIyAuX29ialxuICAgKlxuICAgKiBRdWljayByZWZlcmVuY2UgdG8gc3RvcmVkIGBhY3R1YWxgIHZhbHVlIGZvciBwbHVnaW4gZGV2ZWxvcGVycy5cbiAgICpcbiAgICogQGFwaSBwcml2YXRlXG4gICAqL1xuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShBc3NlcnRpb24ucHJvdG90eXBlLCAnX29iaicsXG4gICAgeyBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIGZsYWcodGhpcywgJ29iamVjdCcpO1xuICAgICAgfVxuICAgICwgc2V0OiBmdW5jdGlvbiAodmFsKSB7XG4gICAgICAgIGZsYWcodGhpcywgJ29iamVjdCcsIHZhbCk7XG4gICAgICB9XG4gIH0pO1xufTtcbiIsICIvKiFcbiAqIGNoYWlcbiAqIGh0dHA6Ly9jaGFpanMuY29tXG4gKiBDb3B5cmlnaHQoYykgMjAxMS0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoY2hhaSwgXykge1xuICB2YXIgQXNzZXJ0aW9uID0gY2hhaS5Bc3NlcnRpb25cbiAgICAsIEFzc2VydGlvbkVycm9yID0gY2hhaS5Bc3NlcnRpb25FcnJvclxuICAgICwgZmxhZyA9IF8uZmxhZztcblxuICAvKipcbiAgICogIyMjIExhbmd1YWdlIENoYWluc1xuICAgKlxuICAgKiBUaGUgZm9sbG93aW5nIGFyZSBwcm92aWRlZCBhcyBjaGFpbmFibGUgZ2V0dGVycyB0byBpbXByb3ZlIHRoZSByZWFkYWJpbGl0eVxuICAgKiBvZiB5b3VyIGFzc2VydGlvbnMuXG4gICAqXG4gICAqICoqQ2hhaW5zKipcbiAgICpcbiAgICogLSB0b1xuICAgKiAtIGJlXG4gICAqIC0gYmVlblxuICAgKiAtIGlzXG4gICAqIC0gdGhhdFxuICAgKiAtIHdoaWNoXG4gICAqIC0gYW5kXG4gICAqIC0gaGFzXG4gICAqIC0gaGF2ZVxuICAgKiAtIHdpdGhcbiAgICogLSBhdFxuICAgKiAtIG9mXG4gICAqIC0gc2FtZVxuICAgKiAtIGJ1dFxuICAgKiAtIGRvZXNcbiAgICogLSBzdGlsbFxuICAgKiAtIGFsc29cbiAgICpcbiAgICogQG5hbWUgbGFuZ3VhZ2UgY2hhaW5zXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIFsgJ3RvJywgJ2JlJywgJ2JlZW4nLCAnaXMnXG4gICwgJ2FuZCcsICdoYXMnLCAnaGF2ZScsICd3aXRoJ1xuICAsICd0aGF0JywgJ3doaWNoJywgJ2F0JywgJ29mJ1xuICAsICdzYW1lJywgJ2J1dCcsICdkb2VzJywgJ3N0aWxsJywgXCJhbHNvXCIgXS5mb3JFYWNoKGZ1bmN0aW9uIChjaGFpbikge1xuICAgIEFzc2VydGlvbi5hZGRQcm9wZXJ0eShjaGFpbik7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiAjIyMgLm5vdFxuICAgKlxuICAgKiBOZWdhdGVzIGFsbCBhc3NlcnRpb25zIHRoYXQgZm9sbG93IGluIHRoZSBjaGFpbi5cbiAgICpcbiAgICogICAgIGV4cGVjdChmdW5jdGlvbiAoKSB7fSkudG8ubm90LnRocm93KCk7XG4gICAqICAgICBleHBlY3Qoe2E6IDF9KS50by5ub3QuaGF2ZS5wcm9wZXJ0eSgnYicpO1xuICAgKiAgICAgZXhwZWN0KFsxLCAyXSkudG8uYmUuYW4oJ2FycmF5JykudGhhdC5kb2VzLm5vdC5pbmNsdWRlKDMpO1xuICAgKlxuICAgKiBKdXN0IGJlY2F1c2UgeW91IGNhbiBuZWdhdGUgYW55IGFzc2VydGlvbiB3aXRoIGAubm90YCBkb2Vzbid0IG1lYW4geW91XG4gICAqIHNob3VsZC4gV2l0aCBncmVhdCBwb3dlciBjb21lcyBncmVhdCByZXNwb25zaWJpbGl0eS4gSXQncyBvZnRlbiBiZXN0IHRvXG4gICAqIGFzc2VydCB0aGF0IHRoZSBvbmUgZXhwZWN0ZWQgb3V0cHV0IHdhcyBwcm9kdWNlZCwgcmF0aGVyIHRoYW4gYXNzZXJ0aW5nXG4gICAqIHRoYXQgb25lIG9mIGNvdW50bGVzcyB1bmV4cGVjdGVkIG91dHB1dHMgd2Fzbid0IHByb2R1Y2VkLiBTZWUgaW5kaXZpZHVhbFxuICAgKiBhc3NlcnRpb25zIGZvciBzcGVjaWZpYyBndWlkYW5jZS5cbiAgICpcbiAgICogICAgIGV4cGVjdCgyKS50by5lcXVhbCgyKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCgyKS50by5ub3QuZXF1YWwoMSk7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBAbmFtZSBub3RcbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgQXNzZXJ0aW9uLmFkZFByb3BlcnR5KCdub3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgZmxhZyh0aGlzLCAnbmVnYXRlJywgdHJ1ZSk7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiAjIyMgLmRlZXBcbiAgICpcbiAgICogQ2F1c2VzIGFsbCBgLmVxdWFsYCwgYC5pbmNsdWRlYCwgYC5tZW1iZXJzYCwgYC5rZXlzYCwgYW5kIGAucHJvcGVydHlgXG4gICAqIGFzc2VydGlvbnMgdGhhdCBmb2xsb3cgaW4gdGhlIGNoYWluIHRvIHVzZSBkZWVwIGVxdWFsaXR5IGluc3RlYWQgb2Ygc3RyaWN0XG4gICAqIChgPT09YCkgZXF1YWxpdHkuIFNlZSB0aGUgYGRlZXAtZXFsYCBwcm9qZWN0IHBhZ2UgZm9yIGluZm8gb24gdGhlIGRlZXBcbiAgICogZXF1YWxpdHkgYWxnb3JpdGhtOiBodHRwczovL2dpdGh1Yi5jb20vY2hhaWpzL2RlZXAtZXFsLlxuICAgKlxuICAgKiAgICAgLy8gVGFyZ2V0IG9iamVjdCBkZWVwbHkgKGJ1dCBub3Qgc3RyaWN0bHkpIGVxdWFscyBge2E6IDF9YFxuICAgKiAgICAgZXhwZWN0KHthOiAxfSkudG8uZGVlcC5lcXVhbCh7YTogMX0pO1xuICAgKiAgICAgZXhwZWN0KHthOiAxfSkudG8ubm90LmVxdWFsKHthOiAxfSk7XG4gICAqXG4gICAqICAgICAvLyBUYXJnZXQgYXJyYXkgZGVlcGx5IChidXQgbm90IHN0cmljdGx5KSBpbmNsdWRlcyBge2E6IDF9YFxuICAgKiAgICAgZXhwZWN0KFt7YTogMX1dKS50by5kZWVwLmluY2x1ZGUoe2E6IDF9KTtcbiAgICogICAgIGV4cGVjdChbe2E6IDF9XSkudG8ubm90LmluY2x1ZGUoe2E6IDF9KTtcbiAgICpcbiAgICogICAgIC8vIFRhcmdldCBvYmplY3QgZGVlcGx5IChidXQgbm90IHN0cmljdGx5KSBpbmNsdWRlcyBgeDoge2E6IDF9YFxuICAgKiAgICAgZXhwZWN0KHt4OiB7YTogMX19KS50by5kZWVwLmluY2x1ZGUoe3g6IHthOiAxfX0pO1xuICAgKiAgICAgZXhwZWN0KHt4OiB7YTogMX19KS50by5ub3QuaW5jbHVkZSh7eDoge2E6IDF9fSk7XG4gICAqXG4gICAqICAgICAvLyBUYXJnZXQgYXJyYXkgZGVlcGx5IChidXQgbm90IHN0cmljdGx5KSBoYXMgbWVtYmVyIGB7YTogMX1gXG4gICAqICAgICBleHBlY3QoW3thOiAxfV0pLnRvLmhhdmUuZGVlcC5tZW1iZXJzKFt7YTogMX1dKTtcbiAgICogICAgIGV4cGVjdChbe2E6IDF9XSkudG8ubm90LmhhdmUubWVtYmVycyhbe2E6IDF9XSk7XG4gICAqXG4gICAqICAgICAvLyBUYXJnZXQgc2V0IGRlZXBseSAoYnV0IG5vdCBzdHJpY3RseSkgaGFzIGtleSBge2E6IDF9YFxuICAgKiAgICAgZXhwZWN0KG5ldyBTZXQoW3thOiAxfV0pKS50by5oYXZlLmRlZXAua2V5cyhbe2E6IDF9XSk7XG4gICAqICAgICBleHBlY3QobmV3IFNldChbe2E6IDF9XSkpLnRvLm5vdC5oYXZlLmtleXMoW3thOiAxfV0pO1xuICAgKlxuICAgKiAgICAgLy8gVGFyZ2V0IG9iamVjdCBkZWVwbHkgKGJ1dCBub3Qgc3RyaWN0bHkpIGhhcyBwcm9wZXJ0eSBgeDoge2E6IDF9YFxuICAgKiAgICAgZXhwZWN0KHt4OiB7YTogMX19KS50by5oYXZlLmRlZXAucHJvcGVydHkoJ3gnLCB7YTogMX0pO1xuICAgKiAgICAgZXhwZWN0KHt4OiB7YTogMX19KS50by5ub3QuaGF2ZS5wcm9wZXJ0eSgneCcsIHthOiAxfSk7XG4gICAqXG4gICAqIEBuYW1lIGRlZXBcbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgQXNzZXJ0aW9uLmFkZFByb3BlcnR5KCdkZWVwJywgZnVuY3Rpb24gKCkge1xuICAgIGZsYWcodGhpcywgJ2RlZXAnLCB0cnVlKTtcbiAgfSk7XG5cbiAgLyoqXG4gICAqICMjIyAubmVzdGVkXG4gICAqXG4gICAqIEVuYWJsZXMgZG90LSBhbmQgYnJhY2tldC1ub3RhdGlvbiBpbiBhbGwgYC5wcm9wZXJ0eWAgYW5kIGAuaW5jbHVkZWBcbiAgICogYXNzZXJ0aW9ucyB0aGF0IGZvbGxvdyBpbiB0aGUgY2hhaW4uXG4gICAqXG4gICAqICAgICBleHBlY3Qoe2E6IHtiOiBbJ3gnLCAneSddfX0pLnRvLmhhdmUubmVzdGVkLnByb3BlcnR5KCdhLmJbMV0nKTtcbiAgICogICAgIGV4cGVjdCh7YToge2I6IFsneCcsICd5J119fSkudG8ubmVzdGVkLmluY2x1ZGUoeydhLmJbMV0nOiAneSd9KTtcbiAgICpcbiAgICogSWYgYC5gIG9yIGBbXWAgYXJlIHBhcnQgb2YgYW4gYWN0dWFsIHByb3BlcnR5IG5hbWUsIHRoZXkgY2FuIGJlIGVzY2FwZWQgYnlcbiAgICogYWRkaW5nIHR3byBiYWNrc2xhc2hlcyBiZWZvcmUgdGhlbS5cbiAgICpcbiAgICogICAgIGV4cGVjdCh7Jy5hJzogeydbYl0nOiAneCd9fSkudG8uaGF2ZS5uZXN0ZWQucHJvcGVydHkoJ1xcXFwuYS5cXFxcW2JcXFxcXScpO1xuICAgKiAgICAgZXhwZWN0KHsnLmEnOiB7J1tiXSc6ICd4J319KS50by5uZXN0ZWQuaW5jbHVkZSh7J1xcXFwuYS5cXFxcW2JcXFxcXSc6ICd4J30pO1xuICAgKlxuICAgKiBgLm5lc3RlZGAgY2Fubm90IGJlIGNvbWJpbmVkIHdpdGggYC5vd25gLlxuICAgKlxuICAgKiBAbmFtZSBuZXN0ZWRcbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgQXNzZXJ0aW9uLmFkZFByb3BlcnR5KCduZXN0ZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgZmxhZyh0aGlzLCAnbmVzdGVkJywgdHJ1ZSk7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiAjIyMgLm93blxuICAgKlxuICAgKiBDYXVzZXMgYWxsIGAucHJvcGVydHlgIGFuZCBgLmluY2x1ZGVgIGFzc2VydGlvbnMgdGhhdCBmb2xsb3cgaW4gdGhlIGNoYWluXG4gICAqIHRvIGlnbm9yZSBpbmhlcml0ZWQgcHJvcGVydGllcy5cbiAgICpcbiAgICogICAgIE9iamVjdC5wcm90b3R5cGUuYiA9IDI7XG4gICAqXG4gICAqICAgICBleHBlY3Qoe2E6IDF9KS50by5oYXZlLm93bi5wcm9wZXJ0eSgnYScpO1xuICAgKiAgICAgZXhwZWN0KHthOiAxfSkudG8uaGF2ZS5wcm9wZXJ0eSgnYicpO1xuICAgKiAgICAgZXhwZWN0KHthOiAxfSkudG8ubm90LmhhdmUub3duLnByb3BlcnR5KCdiJyk7XG4gICAqXG4gICAqICAgICBleHBlY3Qoe2E6IDF9KS50by5vd24uaW5jbHVkZSh7YTogMX0pO1xuICAgKiAgICAgZXhwZWN0KHthOiAxfSkudG8uaW5jbHVkZSh7YjogMn0pLmJ1dC5ub3Qub3duLmluY2x1ZGUoe2I6IDJ9KTtcbiAgICpcbiAgICogYC5vd25gIGNhbm5vdCBiZSBjb21iaW5lZCB3aXRoIGAubmVzdGVkYC5cbiAgICpcbiAgICogQG5hbWUgb3duXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgnb3duJywgZnVuY3Rpb24gKCkge1xuICAgIGZsYWcodGhpcywgJ293bicsIHRydWUpO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC5vcmRlcmVkXG4gICAqXG4gICAqIENhdXNlcyBhbGwgYC5tZW1iZXJzYCBhc3NlcnRpb25zIHRoYXQgZm9sbG93IGluIHRoZSBjaGFpbiB0byByZXF1aXJlIHRoYXRcbiAgICogbWVtYmVycyBiZSBpbiB0aGUgc2FtZSBvcmRlci5cbiAgICpcbiAgICogICAgIGV4cGVjdChbMSwgMl0pLnRvLmhhdmUub3JkZXJlZC5tZW1iZXJzKFsxLCAyXSlcbiAgICogICAgICAgLmJ1dC5ub3QuaGF2ZS5vcmRlcmVkLm1lbWJlcnMoWzIsIDFdKTtcbiAgICpcbiAgICogV2hlbiBgLmluY2x1ZGVgIGFuZCBgLm9yZGVyZWRgIGFyZSBjb21iaW5lZCwgdGhlIG9yZGVyaW5nIGJlZ2lucyBhdCB0aGVcbiAgICogc3RhcnQgb2YgYm90aCBhcnJheXMuXG4gICAqXG4gICAqICAgICBleHBlY3QoWzEsIDIsIDNdKS50by5pbmNsdWRlLm9yZGVyZWQubWVtYmVycyhbMSwgMl0pXG4gICAqICAgICAgIC5idXQubm90LmluY2x1ZGUub3JkZXJlZC5tZW1iZXJzKFsyLCAzXSk7XG4gICAqXG4gICAqIEBuYW1lIG9yZGVyZWRcbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgQXNzZXJ0aW9uLmFkZFByb3BlcnR5KCdvcmRlcmVkJywgZnVuY3Rpb24gKCkge1xuICAgIGZsYWcodGhpcywgJ29yZGVyZWQnLCB0cnVlKTtcbiAgfSk7XG5cbiAgLyoqXG4gICAqICMjIyAuYW55XG4gICAqXG4gICAqIENhdXNlcyBhbGwgYC5rZXlzYCBhc3NlcnRpb25zIHRoYXQgZm9sbG93IGluIHRoZSBjaGFpbiB0byBvbmx5IHJlcXVpcmUgdGhhdFxuICAgKiB0aGUgdGFyZ2V0IGhhdmUgYXQgbGVhc3Qgb25lIG9mIHRoZSBnaXZlbiBrZXlzLiBUaGlzIGlzIHRoZSBvcHBvc2l0ZSBvZlxuICAgKiBgLmFsbGAsIHdoaWNoIHJlcXVpcmVzIHRoYXQgdGhlIHRhcmdldCBoYXZlIGFsbCBvZiB0aGUgZ2l2ZW4ga2V5cy5cbiAgICpcbiAgICogICAgIGV4cGVjdCh7YTogMSwgYjogMn0pLnRvLm5vdC5oYXZlLmFueS5rZXlzKCdjJywgJ2QnKTtcbiAgICpcbiAgICogU2VlIHRoZSBgLmtleXNgIGRvYyBmb3IgZ3VpZGFuY2Ugb24gd2hlbiB0byB1c2UgYC5hbnlgIG9yIGAuYWxsYC5cbiAgICpcbiAgICogQG5hbWUgYW55XG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgnYW55JywgZnVuY3Rpb24gKCkge1xuICAgIGZsYWcodGhpcywgJ2FueScsIHRydWUpO1xuICAgIGZsYWcodGhpcywgJ2FsbCcsIGZhbHNlKTtcbiAgfSk7XG5cbiAgLyoqXG4gICAqICMjIyAuYWxsXG4gICAqXG4gICAqIENhdXNlcyBhbGwgYC5rZXlzYCBhc3NlcnRpb25zIHRoYXQgZm9sbG93IGluIHRoZSBjaGFpbiB0byByZXF1aXJlIHRoYXQgdGhlXG4gICAqIHRhcmdldCBoYXZlIGFsbCBvZiB0aGUgZ2l2ZW4ga2V5cy4gVGhpcyBpcyB0aGUgb3Bwb3NpdGUgb2YgYC5hbnlgLCB3aGljaFxuICAgKiBvbmx5IHJlcXVpcmVzIHRoYXQgdGhlIHRhcmdldCBoYXZlIGF0IGxlYXN0IG9uZSBvZiB0aGUgZ2l2ZW4ga2V5cy5cbiAgICpcbiAgICogICAgIGV4cGVjdCh7YTogMSwgYjogMn0pLnRvLmhhdmUuYWxsLmtleXMoJ2EnLCAnYicpO1xuICAgKlxuICAgKiBOb3RlIHRoYXQgYC5hbGxgIGlzIHVzZWQgYnkgZGVmYXVsdCB3aGVuIG5laXRoZXIgYC5hbGxgIG5vciBgLmFueWAgYXJlXG4gICAqIGFkZGVkIGVhcmxpZXIgaW4gdGhlIGNoYWluLiBIb3dldmVyLCBpdCdzIG9mdGVuIGJlc3QgdG8gYWRkIGAuYWxsYCBhbnl3YXlcbiAgICogYmVjYXVzZSBpdCBpbXByb3ZlcyByZWFkYWJpbGl0eS5cbiAgICpcbiAgICogU2VlIHRoZSBgLmtleXNgIGRvYyBmb3IgZ3VpZGFuY2Ugb24gd2hlbiB0byB1c2UgYC5hbnlgIG9yIGAuYWxsYC5cbiAgICpcbiAgICogQG5hbWUgYWxsXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgnYWxsJywgZnVuY3Rpb24gKCkge1xuICAgIGZsYWcodGhpcywgJ2FsbCcsIHRydWUpO1xuICAgIGZsYWcodGhpcywgJ2FueScsIGZhbHNlKTtcbiAgfSk7XG5cbiAgLyoqXG4gICAqICMjIyAuYSh0eXBlWywgbXNnXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQncyB0eXBlIGlzIGVxdWFsIHRvIHRoZSBnaXZlbiBzdHJpbmcgYHR5cGVgLiBUeXBlc1xuICAgKiBhcmUgY2FzZSBpbnNlbnNpdGl2ZS4gU2VlIHRoZSBgdHlwZS1kZXRlY3RgIHByb2plY3QgcGFnZSBmb3IgaW5mbyBvbiB0aGVcbiAgICogdHlwZSBkZXRlY3Rpb24gYWxnb3JpdGhtOiBodHRwczovL2dpdGh1Yi5jb20vY2hhaWpzL3R5cGUtZGV0ZWN0LlxuICAgKlxuICAgKiAgICAgZXhwZWN0KCdmb28nKS50by5iZS5hKCdzdHJpbmcnKTtcbiAgICogICAgIGV4cGVjdCh7YTogMX0pLnRvLmJlLmFuKCdvYmplY3QnKTtcbiAgICogICAgIGV4cGVjdChudWxsKS50by5iZS5hKCdudWxsJyk7XG4gICAqICAgICBleHBlY3QodW5kZWZpbmVkKS50by5iZS5hbigndW5kZWZpbmVkJyk7XG4gICAqICAgICBleHBlY3QobmV3IEVycm9yKS50by5iZS5hbignZXJyb3InKTtcbiAgICogICAgIGV4cGVjdChQcm9taXNlLnJlc29sdmUoKSkudG8uYmUuYSgncHJvbWlzZScpO1xuICAgKiAgICAgZXhwZWN0KG5ldyBGbG9hdDMyQXJyYXkpLnRvLmJlLmEoJ2Zsb2F0MzJhcnJheScpO1xuICAgKiAgICAgZXhwZWN0KFN5bWJvbCgpKS50by5iZS5hKCdzeW1ib2wnKTtcbiAgICpcbiAgICogYC5hYCBzdXBwb3J0cyBvYmplY3RzIHRoYXQgaGF2ZSBhIGN1c3RvbSB0eXBlIHNldCB2aWEgYFN5bWJvbC50b1N0cmluZ1RhZ2AuXG4gICAqXG4gICAqICAgICB2YXIgbXlPYmogPSB7XG4gICAqICAgICAgIFtTeW1ib2wudG9TdHJpbmdUYWddOiAnbXlDdXN0b21UeXBlJ1xuICAgKiAgICAgfTtcbiAgICpcbiAgICogICAgIGV4cGVjdChteU9iaikudG8uYmUuYSgnbXlDdXN0b21UeXBlJykuYnV0Lm5vdC5hbignb2JqZWN0Jyk7XG4gICAqXG4gICAqIEl0J3Mgb2Z0ZW4gYmVzdCB0byB1c2UgYC5hYCB0byBjaGVjayBhIHRhcmdldCdzIHR5cGUgYmVmb3JlIG1ha2luZyBtb3JlXG4gICAqIGFzc2VydGlvbnMgb24gdGhlIHNhbWUgdGFyZ2V0LiBUaGF0IHdheSwgeW91IGF2b2lkIHVuZXhwZWN0ZWQgYmVoYXZpb3IgZnJvbVxuICAgKiBhbnkgYXNzZXJ0aW9uIHRoYXQgZG9lcyBkaWZmZXJlbnQgdGhpbmdzIGJhc2VkIG9uIHRoZSB0YXJnZXQncyB0eXBlLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KFsxLCAyLCAzXSkudG8uYmUuYW4oJ2FycmF5JykudGhhdC5pbmNsdWRlcygyKTtcbiAgICogICAgIGV4cGVjdChbXSkudG8uYmUuYW4oJ2FycmF5JykudGhhdC5pcy5lbXB0eTtcbiAgICpcbiAgICogQWRkIGAubm90YCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byBuZWdhdGUgYC5hYC4gSG93ZXZlciwgaXQncyBvZnRlbiBiZXN0IHRvXG4gICAqIGFzc2VydCB0aGF0IHRoZSB0YXJnZXQgaXMgdGhlIGV4cGVjdGVkIHR5cGUsIHJhdGhlciB0aGFuIGFzc2VydGluZyB0aGF0IGl0XG4gICAqIGlzbid0IG9uZSBvZiBtYW55IHVuZXhwZWN0ZWQgdHlwZXMuXG4gICAqXG4gICAqICAgICBleHBlY3QoJ2ZvbycpLnRvLmJlLmEoJ3N0cmluZycpOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KCdmb28nKS50by5ub3QuYmUuYW4oJ2FycmF5Jyk7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBgLmFgIGFjY2VwdHMgYW4gb3B0aW9uYWwgYG1zZ2AgYXJndW1lbnQgd2hpY2ggaXMgYSBjdXN0b20gZXJyb3IgbWVzc2FnZSB0b1xuICAgKiBzaG93IHdoZW4gdGhlIGFzc2VydGlvbiBmYWlscy4gVGhlIG1lc3NhZ2UgY2FuIGFsc28gYmUgZ2l2ZW4gYXMgdGhlIHNlY29uZFxuICAgKiBhcmd1bWVudCB0byBgZXhwZWN0YC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgxKS50by5iZS5hKCdzdHJpbmcnLCAnbm9vbyB3aHkgZmFpbD8/Jyk7XG4gICAqICAgICBleHBlY3QoMSwgJ25vb28gd2h5IGZhaWw/PycpLnRvLmJlLmEoJ3N0cmluZycpO1xuICAgKlxuICAgKiBgLmFgIGNhbiBhbHNvIGJlIHVzZWQgYXMgYSBsYW5ndWFnZSBjaGFpbiB0byBpbXByb3ZlIHRoZSByZWFkYWJpbGl0eSBvZlxuICAgKiB5b3VyIGFzc2VydGlvbnMuXG4gICAqXG4gICAqICAgICBleHBlY3Qoe2I6IDJ9KS50by5oYXZlLmEucHJvcGVydHkoJ2InKTtcbiAgICpcbiAgICogVGhlIGFsaWFzIGAuYW5gIGNhbiBiZSB1c2VkIGludGVyY2hhbmdlYWJseSB3aXRoIGAuYWAuXG4gICAqXG4gICAqIEBuYW1lIGFcbiAgICogQGFsaWFzIGFuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtc2cgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBhbiAodHlwZSwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gICAgdHlwZSA9IHR5cGUudG9Mb3dlckNhc2UoKTtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0JylcbiAgICAgICwgYXJ0aWNsZSA9IH5bICdhJywgJ2UnLCAnaScsICdvJywgJ3UnIF0uaW5kZXhPZih0eXBlLmNoYXJBdCgwKSkgPyAnYW4gJyA6ICdhICc7XG5cbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgdHlwZSA9PT0gXy50eXBlKG9iaikudG9Mb3dlckNhc2UoKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSAnICsgYXJ0aWNsZSArIHR5cGVcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gbm90IHRvIGJlICcgKyBhcnRpY2xlICsgdHlwZVxuICAgICk7XG4gIH1cblxuICBBc3NlcnRpb24uYWRkQ2hhaW5hYmxlTWV0aG9kKCdhbicsIGFuKTtcbiAgQXNzZXJ0aW9uLmFkZENoYWluYWJsZU1ldGhvZCgnYScsIGFuKTtcblxuICAvKipcbiAgICogIyMjIC5pbmNsdWRlKHZhbFssIG1zZ10pXG4gICAqXG4gICAqIFdoZW4gdGhlIHRhcmdldCBpcyBhIHN0cmluZywgYC5pbmNsdWRlYCBhc3NlcnRzIHRoYXQgdGhlIGdpdmVuIHN0cmluZyBgdmFsYFxuICAgKiBpcyBhIHN1YnN0cmluZyBvZiB0aGUgdGFyZ2V0LlxuICAgKlxuICAgKiAgICAgZXhwZWN0KCdmb29iYXInKS50by5pbmNsdWRlKCdmb28nKTtcbiAgICpcbiAgICogV2hlbiB0aGUgdGFyZ2V0IGlzIGFuIGFycmF5LCBgLmluY2x1ZGVgIGFzc2VydHMgdGhhdCB0aGUgZ2l2ZW4gYHZhbGAgaXMgYVxuICAgKiBtZW1iZXIgb2YgdGhlIHRhcmdldC5cbiAgICpcbiAgICogICAgIGV4cGVjdChbMSwgMiwgM10pLnRvLmluY2x1ZGUoMik7XG4gICAqXG4gICAqIFdoZW4gdGhlIHRhcmdldCBpcyBhbiBvYmplY3QsIGAuaW5jbHVkZWAgYXNzZXJ0cyB0aGF0IHRoZSBnaXZlbiBvYmplY3RcbiAgICogYHZhbGAncyBwcm9wZXJ0aWVzIGFyZSBhIHN1YnNldCBvZiB0aGUgdGFyZ2V0J3MgcHJvcGVydGllcy5cbiAgICpcbiAgICogICAgIGV4cGVjdCh7YTogMSwgYjogMiwgYzogM30pLnRvLmluY2x1ZGUoe2E6IDEsIGI6IDJ9KTtcbiAgICpcbiAgICogV2hlbiB0aGUgdGFyZ2V0IGlzIGEgU2V0IG9yIFdlYWtTZXQsIGAuaW5jbHVkZWAgYXNzZXJ0cyB0aGF0IHRoZSBnaXZlbiBgdmFsYCBpcyBhXG4gICAqIG1lbWJlciBvZiB0aGUgdGFyZ2V0LiBTYW1lVmFsdWVaZXJvIGVxdWFsaXR5IGFsZ29yaXRobSBpcyB1c2VkLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KG5ldyBTZXQoWzEsIDJdKSkudG8uaW5jbHVkZSgyKTtcbiAgICpcbiAgICogV2hlbiB0aGUgdGFyZ2V0IGlzIGEgTWFwLCBgLmluY2x1ZGVgIGFzc2VydHMgdGhhdCB0aGUgZ2l2ZW4gYHZhbGAgaXMgb25lIG9mXG4gICAqIHRoZSB2YWx1ZXMgb2YgdGhlIHRhcmdldC4gU2FtZVZhbHVlWmVybyBlcXVhbGl0eSBhbGdvcml0aG0gaXMgdXNlZC5cbiAgICpcbiAgICogICAgIGV4cGVjdChuZXcgTWFwKFtbJ2EnLCAxXSwgWydiJywgMl1dKSkudG8uaW5jbHVkZSgyKTtcbiAgICpcbiAgICogQmVjYXVzZSBgLmluY2x1ZGVgIGRvZXMgZGlmZmVyZW50IHRoaW5ncyBiYXNlZCBvbiB0aGUgdGFyZ2V0J3MgdHlwZSwgaXQnc1xuICAgKiBpbXBvcnRhbnQgdG8gY2hlY2sgdGhlIHRhcmdldCdzIHR5cGUgYmVmb3JlIHVzaW5nIGAuaW5jbHVkZWAuIFNlZSB0aGUgYC5hYFxuICAgKiBkb2MgZm9yIGluZm8gb24gdGVzdGluZyBhIHRhcmdldCdzIHR5cGUuXG4gICAqXG4gICAqICAgICBleHBlY3QoWzEsIDIsIDNdKS50by5iZS5hbignYXJyYXknKS50aGF0LmluY2x1ZGVzKDIpO1xuICAgKlxuICAgKiBCeSBkZWZhdWx0LCBzdHJpY3QgKGA9PT1gKSBlcXVhbGl0eSBpcyB1c2VkIHRvIGNvbXBhcmUgYXJyYXkgbWVtYmVycyBhbmRcbiAgICogb2JqZWN0IHByb3BlcnRpZXMuIEFkZCBgLmRlZXBgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIHVzZSBkZWVwIGVxdWFsaXR5XG4gICAqIGluc3RlYWQgKFdlYWtTZXQgdGFyZ2V0cyBhcmUgbm90IHN1cHBvcnRlZCkuIFNlZSB0aGUgYGRlZXAtZXFsYCBwcm9qZWN0XG4gICAqIHBhZ2UgZm9yIGluZm8gb24gdGhlIGRlZXAgZXF1YWxpdHkgYWxnb3JpdGhtOiBodHRwczovL2dpdGh1Yi5jb20vY2hhaWpzL2RlZXAtZXFsLlxuICAgKlxuICAgKiAgICAgLy8gVGFyZ2V0IGFycmF5IGRlZXBseSAoYnV0IG5vdCBzdHJpY3RseSkgaW5jbHVkZXMgYHthOiAxfWBcbiAgICogICAgIGV4cGVjdChbe2E6IDF9XSkudG8uZGVlcC5pbmNsdWRlKHthOiAxfSk7XG4gICAqICAgICBleHBlY3QoW3thOiAxfV0pLnRvLm5vdC5pbmNsdWRlKHthOiAxfSk7XG4gICAqXG4gICAqICAgICAvLyBUYXJnZXQgb2JqZWN0IGRlZXBseSAoYnV0IG5vdCBzdHJpY3RseSkgaW5jbHVkZXMgYHg6IHthOiAxfWBcbiAgICogICAgIGV4cGVjdCh7eDoge2E6IDF9fSkudG8uZGVlcC5pbmNsdWRlKHt4OiB7YTogMX19KTtcbiAgICogICAgIGV4cGVjdCh7eDoge2E6IDF9fSkudG8ubm90LmluY2x1ZGUoe3g6IHthOiAxfX0pO1xuICAgKlxuICAgKiBCeSBkZWZhdWx0LCBhbGwgb2YgdGhlIHRhcmdldCdzIHByb3BlcnRpZXMgYXJlIHNlYXJjaGVkIHdoZW4gd29ya2luZyB3aXRoXG4gICAqIG9iamVjdHMuIFRoaXMgaW5jbHVkZXMgcHJvcGVydGllcyB0aGF0IGFyZSBpbmhlcml0ZWQgYW5kL29yIG5vbi1lbnVtZXJhYmxlLlxuICAgKiBBZGQgYC5vd25gIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIGV4Y2x1ZGUgdGhlIHRhcmdldCdzIGluaGVyaXRlZFxuICAgKiBwcm9wZXJ0aWVzIGZyb20gdGhlIHNlYXJjaC5cbiAgICpcbiAgICogICAgIE9iamVjdC5wcm90b3R5cGUuYiA9IDI7XG4gICAqXG4gICAqICAgICBleHBlY3Qoe2E6IDF9KS50by5vd24uaW5jbHVkZSh7YTogMX0pO1xuICAgKiAgICAgZXhwZWN0KHthOiAxfSkudG8uaW5jbHVkZSh7YjogMn0pLmJ1dC5ub3Qub3duLmluY2x1ZGUoe2I6IDJ9KTtcbiAgICpcbiAgICogTm90ZSB0aGF0IGEgdGFyZ2V0IG9iamVjdCBpcyBhbHdheXMgb25seSBzZWFyY2hlZCBmb3IgYHZhbGAncyBvd25cbiAgICogZW51bWVyYWJsZSBwcm9wZXJ0aWVzLlxuICAgKlxuICAgKiBgLmRlZXBgIGFuZCBgLm93bmAgY2FuIGJlIGNvbWJpbmVkLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KHthOiB7YjogMn19KS50by5kZWVwLm93bi5pbmNsdWRlKHthOiB7YjogMn19KTtcbiAgICpcbiAgICogQWRkIGAubmVzdGVkYCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byBlbmFibGUgZG90LSBhbmQgYnJhY2tldC1ub3RhdGlvbiB3aGVuXG4gICAqIHJlZmVyZW5jaW5nIG5lc3RlZCBwcm9wZXJ0aWVzLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KHthOiB7YjogWyd4JywgJ3knXX19KS50by5uZXN0ZWQuaW5jbHVkZSh7J2EuYlsxXSc6ICd5J30pO1xuICAgKlxuICAgKiBJZiBgLmAgb3IgYFtdYCBhcmUgcGFydCBvZiBhbiBhY3R1YWwgcHJvcGVydHkgbmFtZSwgdGhleSBjYW4gYmUgZXNjYXBlZCBieVxuICAgKiBhZGRpbmcgdHdvIGJhY2tzbGFzaGVzIGJlZm9yZSB0aGVtLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KHsnLmEnOiB7J1tiXSc6IDJ9fSkudG8ubmVzdGVkLmluY2x1ZGUoeydcXFxcLmEuXFxcXFtiXFxcXF0nOiAyfSk7XG4gICAqXG4gICAqIGAuZGVlcGAgYW5kIGAubmVzdGVkYCBjYW4gYmUgY29tYmluZWQuXG4gICAqXG4gICAqICAgICBleHBlY3Qoe2E6IHtiOiBbe2M6IDN9XX19KS50by5kZWVwLm5lc3RlZC5pbmNsdWRlKHsnYS5iWzBdJzoge2M6IDN9fSk7XG4gICAqXG4gICAqIGAub3duYCBhbmQgYC5uZXN0ZWRgIGNhbm5vdCBiZSBjb21iaW5lZC5cbiAgICpcbiAgICogQWRkIGAubm90YCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byBuZWdhdGUgYC5pbmNsdWRlYC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgnZm9vYmFyJykudG8ubm90LmluY2x1ZGUoJ3RhY28nKTtcbiAgICogICAgIGV4cGVjdChbMSwgMiwgM10pLnRvLm5vdC5pbmNsdWRlKDQpO1xuICAgKlxuICAgKiBIb3dldmVyLCBpdCdzIGRhbmdlcm91cyB0byBuZWdhdGUgYC5pbmNsdWRlYCB3aGVuIHRoZSB0YXJnZXQgaXMgYW4gb2JqZWN0LlxuICAgKiBUaGUgcHJvYmxlbSBpcyB0aGF0IGl0IGNyZWF0ZXMgdW5jZXJ0YWluIGV4cGVjdGF0aW9ucyBieSBhc3NlcnRpbmcgdGhhdCB0aGVcbiAgICogdGFyZ2V0IG9iamVjdCBkb2Vzbid0IGhhdmUgYWxsIG9mIGB2YWxgJ3Mga2V5L3ZhbHVlIHBhaXJzIGJ1dCBtYXkgb3IgbWF5XG4gICAqIG5vdCBoYXZlIHNvbWUgb2YgdGhlbS4gSXQncyBvZnRlbiBiZXN0IHRvIGlkZW50aWZ5IHRoZSBleGFjdCBvdXRwdXQgdGhhdCdzXG4gICAqIGV4cGVjdGVkLCBhbmQgdGhlbiB3cml0ZSBhbiBhc3NlcnRpb24gdGhhdCBvbmx5IGFjY2VwdHMgdGhhdCBleGFjdCBvdXRwdXQuXG4gICAqXG4gICAqIFdoZW4gdGhlIHRhcmdldCBvYmplY3QgaXNuJ3QgZXZlbiBleHBlY3RlZCB0byBoYXZlIGB2YWxgJ3Mga2V5cywgaXQnc1xuICAgKiBvZnRlbiBiZXN0IHRvIGFzc2VydCBleGFjdGx5IHRoYXQuXG4gICAqXG4gICAqICAgICBleHBlY3Qoe2M6IDN9KS50by5ub3QuaGF2ZS5hbnkua2V5cygnYScsICdiJyk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3Qoe2M6IDN9KS50by5ub3QuaW5jbHVkZSh7YTogMSwgYjogMn0pOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogV2hlbiB0aGUgdGFyZ2V0IG9iamVjdCBpcyBleHBlY3RlZCB0byBoYXZlIGB2YWxgJ3Mga2V5cywgaXQncyBvZnRlbiBiZXN0IHRvXG4gICAqIGFzc2VydCB0aGF0IGVhY2ggb2YgdGhlIHByb3BlcnRpZXMgaGFzIGl0cyBleHBlY3RlZCB2YWx1ZSwgcmF0aGVyIHRoYW5cbiAgICogYXNzZXJ0aW5nIHRoYXQgZWFjaCBwcm9wZXJ0eSBkb2Vzbid0IGhhdmUgb25lIG9mIG1hbnkgdW5leHBlY3RlZCB2YWx1ZXMuXG4gICAqXG4gICAqICAgICBleHBlY3Qoe2E6IDMsIGI6IDR9KS50by5pbmNsdWRlKHthOiAzLCBiOiA0fSk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3Qoe2E6IDMsIGI6IDR9KS50by5ub3QuaW5jbHVkZSh7YTogMSwgYjogMn0pOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogYC5pbmNsdWRlYCBhY2NlcHRzIGFuIG9wdGlvbmFsIGBtc2dgIGFyZ3VtZW50IHdoaWNoIGlzIGEgY3VzdG9tIGVycm9yXG4gICAqIG1lc3NhZ2UgdG8gc2hvdyB3aGVuIHRoZSBhc3NlcnRpb24gZmFpbHMuIFRoZSBtZXNzYWdlIGNhbiBhbHNvIGJlIGdpdmVuIGFzXG4gICAqIHRoZSBzZWNvbmQgYXJndW1lbnQgdG8gYGV4cGVjdGAuXG4gICAqXG4gICAqICAgICBleHBlY3QoWzEsIDIsIDNdKS50by5pbmNsdWRlKDQsICdub29vIHdoeSBmYWlsPz8nKTtcbiAgICogICAgIGV4cGVjdChbMSwgMiwgM10sICdub29vIHdoeSBmYWlsPz8nKS50by5pbmNsdWRlKDQpO1xuICAgKlxuICAgKiBgLmluY2x1ZGVgIGNhbiBhbHNvIGJlIHVzZWQgYXMgYSBsYW5ndWFnZSBjaGFpbiwgY2F1c2luZyBhbGwgYC5tZW1iZXJzYCBhbmRcbiAgICogYC5rZXlzYCBhc3NlcnRpb25zIHRoYXQgZm9sbG93IGluIHRoZSBjaGFpbiB0byByZXF1aXJlIHRoZSB0YXJnZXQgdG8gYmUgYVxuICAgKiBzdXBlcnNldCBvZiB0aGUgZXhwZWN0ZWQgc2V0LCByYXRoZXIgdGhhbiBhbiBpZGVudGljYWwgc2V0LiBOb3RlIHRoYXRcbiAgICogYC5tZW1iZXJzYCBpZ25vcmVzIGR1cGxpY2F0ZXMgaW4gdGhlIHN1YnNldCB3aGVuIGAuaW5jbHVkZWAgaXMgYWRkZWQuXG4gICAqXG4gICAqICAgICAvLyBUYXJnZXQgb2JqZWN0J3Mga2V5cyBhcmUgYSBzdXBlcnNldCBvZiBbJ2EnLCAnYiddIGJ1dCBub3QgaWRlbnRpY2FsXG4gICAqICAgICBleHBlY3Qoe2E6IDEsIGI6IDIsIGM6IDN9KS50by5pbmNsdWRlLmFsbC5rZXlzKCdhJywgJ2InKTtcbiAgICogICAgIGV4cGVjdCh7YTogMSwgYjogMiwgYzogM30pLnRvLm5vdC5oYXZlLmFsbC5rZXlzKCdhJywgJ2InKTtcbiAgICpcbiAgICogICAgIC8vIFRhcmdldCBhcnJheSBpcyBhIHN1cGVyc2V0IG9mIFsxLCAyXSBidXQgbm90IGlkZW50aWNhbFxuICAgKiAgICAgZXhwZWN0KFsxLCAyLCAzXSkudG8uaW5jbHVkZS5tZW1iZXJzKFsxLCAyXSk7XG4gICAqICAgICBleHBlY3QoWzEsIDIsIDNdKS50by5ub3QuaGF2ZS5tZW1iZXJzKFsxLCAyXSk7XG4gICAqXG4gICAqICAgICAvLyBEdXBsaWNhdGVzIGluIHRoZSBzdWJzZXQgYXJlIGlnbm9yZWRcbiAgICogICAgIGV4cGVjdChbMSwgMiwgM10pLnRvLmluY2x1ZGUubWVtYmVycyhbMSwgMiwgMiwgMl0pO1xuICAgKlxuICAgKiBOb3RlIHRoYXQgYWRkaW5nIGAuYW55YCBlYXJsaWVyIGluIHRoZSBjaGFpbiBjYXVzZXMgdGhlIGAua2V5c2AgYXNzZXJ0aW9uXG4gICAqIHRvIGlnbm9yZSBgLmluY2x1ZGVgLlxuICAgKlxuICAgKiAgICAgLy8gQm90aCBhc3NlcnRpb25zIGFyZSBpZGVudGljYWxcbiAgICogICAgIGV4cGVjdCh7YTogMX0pLnRvLmluY2x1ZGUuYW55LmtleXMoJ2EnLCAnYicpO1xuICAgKiAgICAgZXhwZWN0KHthOiAxfSkudG8uaGF2ZS5hbnkua2V5cygnYScsICdiJyk7XG4gICAqXG4gICAqIFRoZSBhbGlhc2VzIGAuaW5jbHVkZXNgLCBgLmNvbnRhaW5gLCBhbmQgYC5jb250YWluc2AgY2FuIGJlIHVzZWRcbiAgICogaW50ZXJjaGFuZ2VhYmx5IHdpdGggYC5pbmNsdWRlYC5cbiAgICpcbiAgICogQG5hbWUgaW5jbHVkZVxuICAgKiBAYWxpYXMgY29udGFpblxuICAgKiBAYWxpYXMgaW5jbHVkZXNcbiAgICogQGFsaWFzIGNvbnRhaW5zXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbXNnIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gU2FtZVZhbHVlWmVybyhhLCBiKSB7XG4gICAgcmV0dXJuIChfLmlzTmFOKGEpICYmIF8uaXNOYU4oYikpIHx8IGEgPT09IGI7XG4gIH1cblxuICBmdW5jdGlvbiBpbmNsdWRlQ2hhaW5pbmdCZWhhdmlvciAoKSB7XG4gICAgZmxhZyh0aGlzLCAnY29udGFpbnMnLCB0cnVlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGluY2x1ZGUgKHZhbCwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG5cbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0JylcbiAgICAgICwgb2JqVHlwZSA9IF8udHlwZShvYmopLnRvTG93ZXJDYXNlKClcbiAgICAgICwgZmxhZ01zZyA9IGZsYWcodGhpcywgJ21lc3NhZ2UnKVxuICAgICAgLCBuZWdhdGUgPSBmbGFnKHRoaXMsICduZWdhdGUnKVxuICAgICAgLCBzc2ZpID0gZmxhZyh0aGlzLCAnc3NmaScpXG4gICAgICAsIGlzRGVlcCA9IGZsYWcodGhpcywgJ2RlZXAnKVxuICAgICAgLCBkZXNjcmlwdG9yID0gaXNEZWVwID8gJ2RlZXAgJyA6ICcnO1xuXG4gICAgZmxhZ01zZyA9IGZsYWdNc2cgPyBmbGFnTXNnICsgJzogJyA6ICcnO1xuXG4gICAgdmFyIGluY2x1ZGVkID0gZmFsc2U7XG5cbiAgICBzd2l0Y2ggKG9ialR5cGUpIHtcbiAgICAgIGNhc2UgJ3N0cmluZyc6XG4gICAgICAgIGluY2x1ZGVkID0gb2JqLmluZGV4T2YodmFsKSAhPT0gLTE7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICd3ZWFrc2V0JzpcbiAgICAgICAgaWYgKGlzRGVlcCkge1xuICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihcbiAgICAgICAgICAgIGZsYWdNc2cgKyAndW5hYmxlIHRvIHVzZSAuZGVlcC5pbmNsdWRlIHdpdGggV2Vha1NldCcsXG4gICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICBzc2ZpXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGluY2x1ZGVkID0gb2JqLmhhcyh2YWwpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnbWFwJzpcbiAgICAgICAgdmFyIGlzRXFsID0gaXNEZWVwID8gXy5lcWwgOiBTYW1lVmFsdWVaZXJvO1xuICAgICAgICBvYmouZm9yRWFjaChmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgIGluY2x1ZGVkID0gaW5jbHVkZWQgfHwgaXNFcWwoaXRlbSwgdmFsKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdzZXQnOlxuICAgICAgICBpZiAoaXNEZWVwKSB7XG4gICAgICAgICAgb2JqLmZvckVhY2goZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgICAgIGluY2x1ZGVkID0gaW5jbHVkZWQgfHwgXy5lcWwoaXRlbSwgdmFsKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpbmNsdWRlZCA9IG9iai5oYXModmFsKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnYXJyYXknOlxuICAgICAgICBpZiAoaXNEZWVwKSB7XG4gICAgICAgICAgaW5jbHVkZWQgPSBvYmouc29tZShmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgICAgcmV0dXJuIF8uZXFsKGl0ZW0sIHZhbCk7XG4gICAgICAgICAgfSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpbmNsdWRlZCA9IG9iai5pbmRleE9mKHZhbCkgIT09IC0xO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICAvLyBUaGlzIGJsb2NrIGlzIGZvciBhc3NlcnRpbmcgYSBzdWJzZXQgb2YgcHJvcGVydGllcyBpbiBhbiBvYmplY3QuXG4gICAgICAgIC8vIGBfLmV4cGVjdFR5cGVzYCBpc24ndCB1c2VkIGhlcmUgYmVjYXVzZSBgLmluY2x1ZGVgIHNob3VsZCB3b3JrIHdpdGhcbiAgICAgICAgLy8gb2JqZWN0cyB3aXRoIGEgY3VzdG9tIGBAQHRvU3RyaW5nVGFnYC5cbiAgICAgICAgaWYgKHZhbCAhPT0gT2JqZWN0KHZhbCkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoXG4gICAgICAgICAgICBmbGFnTXNnICsgJ3RoZSBnaXZlbiBjb21iaW5hdGlvbiBvZiBhcmd1bWVudHMgKCdcbiAgICAgICAgICAgICsgb2JqVHlwZSArICcgYW5kICdcbiAgICAgICAgICAgICsgXy50eXBlKHZhbCkudG9Mb3dlckNhc2UoKSArICcpJ1xuICAgICAgICAgICAgKyAnIGlzIGludmFsaWQgZm9yIHRoaXMgYXNzZXJ0aW9uLiAnXG4gICAgICAgICAgICArICdZb3UgY2FuIHVzZSBhbiBhcnJheSwgYSBtYXAsIGFuIG9iamVjdCwgYSBzZXQsIGEgc3RyaW5nLCAnXG4gICAgICAgICAgICArICdvciBhIHdlYWtzZXQgaW5zdGVhZCBvZiBhICdcbiAgICAgICAgICAgICsgXy50eXBlKHZhbCkudG9Mb3dlckNhc2UoKSxcbiAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHNzZmlcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHByb3BzID0gT2JqZWN0LmtleXModmFsKVxuICAgICAgICAgICwgZmlyc3RFcnIgPSBudWxsXG4gICAgICAgICAgLCBudW1FcnJzID0gMDtcblxuICAgICAgICBwcm9wcy5mb3JFYWNoKGZ1bmN0aW9uIChwcm9wKSB7XG4gICAgICAgICAgdmFyIHByb3BBc3NlcnRpb24gPSBuZXcgQXNzZXJ0aW9uKG9iaik7XG4gICAgICAgICAgXy50cmFuc2ZlckZsYWdzKHRoaXMsIHByb3BBc3NlcnRpb24sIHRydWUpO1xuICAgICAgICAgIGZsYWcocHJvcEFzc2VydGlvbiwgJ2xvY2tTc2ZpJywgdHJ1ZSk7XG5cbiAgICAgICAgICBpZiAoIW5lZ2F0ZSB8fCBwcm9wcy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgIHByb3BBc3NlcnRpb24ucHJvcGVydHkocHJvcCwgdmFsW3Byb3BdKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgcHJvcEFzc2VydGlvbi5wcm9wZXJ0eShwcm9wLCB2YWxbcHJvcF0pO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgaWYgKCFfLmNoZWNrRXJyb3IuY29tcGF0aWJsZUNvbnN0cnVjdG9yKGVyciwgQXNzZXJ0aW9uRXJyb3IpKSB7XG4gICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChmaXJzdEVyciA9PT0gbnVsbCkgZmlyc3RFcnIgPSBlcnI7XG4gICAgICAgICAgICBudW1FcnJzKys7XG4gICAgICAgICAgfVxuICAgICAgICB9LCB0aGlzKTtcblxuICAgICAgICAvLyBXaGVuIHZhbGlkYXRpbmcgLm5vdC5pbmNsdWRlIHdpdGggbXVsdGlwbGUgcHJvcGVydGllcywgd2Ugb25seSB3YW50XG4gICAgICAgIC8vIHRvIHRocm93IGFuIGFzc2VydGlvbiBlcnJvciBpZiBhbGwgb2YgdGhlIHByb3BlcnRpZXMgYXJlIGluY2x1ZGVkLFxuICAgICAgICAvLyBpbiB3aGljaCBjYXNlIHdlIHRocm93IHRoZSBmaXJzdCBwcm9wZXJ0eSBhc3NlcnRpb24gZXJyb3IgdGhhdCB3ZVxuICAgICAgICAvLyBlbmNvdW50ZXJlZC5cbiAgICAgICAgaWYgKG5lZ2F0ZSAmJiBwcm9wcy5sZW5ndGggPiAxICYmIG51bUVycnMgPT09IHByb3BzLmxlbmd0aCkge1xuICAgICAgICAgIHRocm93IGZpcnN0RXJyO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBBc3NlcnQgaW5jbHVzaW9uIGluIGNvbGxlY3Rpb24gb3Igc3Vic3RyaW5nIGluIGEgc3RyaW5nLlxuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgaW5jbHVkZWRcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gJyArIGRlc2NyaXB0b3IgKyAnaW5jbHVkZSAnICsgXy5pbnNwZWN0KHZhbClcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90ICcgKyBkZXNjcmlwdG9yICsgJ2luY2x1ZGUgJyArIF8uaW5zcGVjdCh2YWwpKTtcbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRDaGFpbmFibGVNZXRob2QoJ2luY2x1ZGUnLCBpbmNsdWRlLCBpbmNsdWRlQ2hhaW5pbmdCZWhhdmlvcik7XG4gIEFzc2VydGlvbi5hZGRDaGFpbmFibGVNZXRob2QoJ2NvbnRhaW4nLCBpbmNsdWRlLCBpbmNsdWRlQ2hhaW5pbmdCZWhhdmlvcik7XG4gIEFzc2VydGlvbi5hZGRDaGFpbmFibGVNZXRob2QoJ2NvbnRhaW5zJywgaW5jbHVkZSwgaW5jbHVkZUNoYWluaW5nQmVoYXZpb3IpO1xuICBBc3NlcnRpb24uYWRkQ2hhaW5hYmxlTWV0aG9kKCdpbmNsdWRlcycsIGluY2x1ZGUsIGluY2x1ZGVDaGFpbmluZ0JlaGF2aW9yKTtcblxuICAvKipcbiAgICogIyMjIC5va1xuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBhIHRydXRoeSB2YWx1ZSAoY29uc2lkZXJlZCBgdHJ1ZWAgaW4gYm9vbGVhbiBjb250ZXh0KS5cbiAgICogSG93ZXZlciwgaXQncyBvZnRlbiBiZXN0IHRvIGFzc2VydCB0aGF0IHRoZSB0YXJnZXQgaXMgc3RyaWN0bHkgKGA9PT1gKSBvclxuICAgKiBkZWVwbHkgZXF1YWwgdG8gaXRzIGV4cGVjdGVkIHZhbHVlLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KDEpLnRvLmVxdWFsKDEpOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KDEpLnRvLmJlLm9rOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogICAgIGV4cGVjdCh0cnVlKS50by5iZS50cnVlOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KHRydWUpLnRvLmJlLm9rOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogQWRkIGAubm90YCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byBuZWdhdGUgYC5va2AuXG4gICAqXG4gICAqICAgICBleHBlY3QoMCkudG8uZXF1YWwoMCk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoMCkudG8ubm90LmJlLm9rOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogICAgIGV4cGVjdChmYWxzZSkudG8uYmUuZmFsc2U7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoZmFsc2UpLnRvLm5vdC5iZS5vazsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqICAgICBleHBlY3QobnVsbCkudG8uYmUubnVsbDsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdChudWxsKS50by5ub3QuYmUub2s7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiAgICAgZXhwZWN0KHVuZGVmaW5lZCkudG8uYmUudW5kZWZpbmVkOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KHVuZGVmaW5lZCkudG8ubm90LmJlLm9rOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogQSBjdXN0b20gZXJyb3IgbWVzc2FnZSBjYW4gYmUgZ2l2ZW4gYXMgdGhlIHNlY29uZCBhcmd1bWVudCB0byBgZXhwZWN0YC5cbiAgICpcbiAgICogICAgIGV4cGVjdChmYWxzZSwgJ25vb28gd2h5IGZhaWw/PycpLnRvLmJlLm9rO1xuICAgKlxuICAgKiBAbmFtZSBva1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBBc3NlcnRpb24uYWRkUHJvcGVydHkoJ29rJywgZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSB0cnV0aHknXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIGZhbHN5Jyk7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiAjIyMgLnRydWVcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaXMgc3RyaWN0bHkgKGA9PT1gKSBlcXVhbCB0byBgdHJ1ZWAuXG4gICAqXG4gICAqICAgICBleHBlY3QodHJ1ZSkudG8uYmUudHJ1ZTtcbiAgICpcbiAgICogQWRkIGAubm90YCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byBuZWdhdGUgYC50cnVlYC4gSG93ZXZlciwgaXQncyBvZnRlbiBiZXN0XG4gICAqIHRvIGFzc2VydCB0aGF0IHRoZSB0YXJnZXQgaXMgZXF1YWwgdG8gaXRzIGV4cGVjdGVkIHZhbHVlLCByYXRoZXIgdGhhbiBub3RcbiAgICogZXF1YWwgdG8gYHRydWVgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KGZhbHNlKS50by5iZS5mYWxzZTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdChmYWxzZSkudG8ubm90LmJlLnRydWU7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiAgICAgZXhwZWN0KDEpLnRvLmVxdWFsKDEpOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KDEpLnRvLm5vdC5iZS50cnVlOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogQSBjdXN0b20gZXJyb3IgbWVzc2FnZSBjYW4gYmUgZ2l2ZW4gYXMgdGhlIHNlY29uZCBhcmd1bWVudCB0byBgZXhwZWN0YC5cbiAgICpcbiAgICogICAgIGV4cGVjdChmYWxzZSwgJ25vb28gd2h5IGZhaWw/PycpLnRvLmJlLnRydWU7XG4gICAqXG4gICAqIEBuYW1lIHRydWVcbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgQXNzZXJ0aW9uLmFkZFByb3BlcnR5KCd0cnVlJywgZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICB0cnVlID09PSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSB0cnVlJ1xuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBmYWxzZSdcbiAgICAgICwgZmxhZyh0aGlzLCAnbmVnYXRlJykgPyBmYWxzZSA6IHRydWVcbiAgICApO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC5mYWxzZVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBzdHJpY3RseSAoYD09PWApIGVxdWFsIHRvIGBmYWxzZWAuXG4gICAqXG4gICAqICAgICBleHBlY3QoZmFsc2UpLnRvLmJlLmZhbHNlO1xuICAgKlxuICAgKiBBZGQgYC5ub3RgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIG5lZ2F0ZSBgLmZhbHNlYC4gSG93ZXZlciwgaXQncyBvZnRlblxuICAgKiBiZXN0IHRvIGFzc2VydCB0aGF0IHRoZSB0YXJnZXQgaXMgZXF1YWwgdG8gaXRzIGV4cGVjdGVkIHZhbHVlLCByYXRoZXIgdGhhblxuICAgKiBub3QgZXF1YWwgdG8gYGZhbHNlYC5cbiAgICpcbiAgICogICAgIGV4cGVjdCh0cnVlKS50by5iZS50cnVlOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KHRydWUpLnRvLm5vdC5iZS5mYWxzZTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqICAgICBleHBlY3QoMSkudG8uZXF1YWwoMSk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoMSkudG8ubm90LmJlLmZhbHNlOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogQSBjdXN0b20gZXJyb3IgbWVzc2FnZSBjYW4gYmUgZ2l2ZW4gYXMgdGhlIHNlY29uZCBhcmd1bWVudCB0byBgZXhwZWN0YC5cbiAgICpcbiAgICogICAgIGV4cGVjdCh0cnVlLCAnbm9vbyB3aHkgZmFpbD8/JykudG8uYmUuZmFsc2U7XG4gICAqXG4gICAqIEBuYW1lIGZhbHNlXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgnZmFsc2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICAgIGZhbHNlID09PSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBmYWxzZSdcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgdHJ1ZSdcbiAgICAgICwgZmxhZyh0aGlzLCAnbmVnYXRlJykgPyB0cnVlIDogZmFsc2VcbiAgICApO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC5udWxsXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIHN0cmljdGx5IChgPT09YCkgZXF1YWwgdG8gYG51bGxgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KG51bGwpLnRvLmJlLm51bGw7XG4gICAqXG4gICAqIEFkZCBgLm5vdGAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gbmVnYXRlIGAubnVsbGAuIEhvd2V2ZXIsIGl0J3Mgb2Z0ZW4gYmVzdFxuICAgKiB0byBhc3NlcnQgdGhhdCB0aGUgdGFyZ2V0IGlzIGVxdWFsIHRvIGl0cyBleHBlY3RlZCB2YWx1ZSwgcmF0aGVyIHRoYW4gbm90XG4gICAqIGVxdWFsIHRvIGBudWxsYC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgxKS50by5lcXVhbCgxKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCgxKS50by5ub3QuYmUubnVsbDsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqIEEgY3VzdG9tIGVycm9yIG1lc3NhZ2UgY2FuIGJlIGdpdmVuIGFzIHRoZSBzZWNvbmQgYXJndW1lbnQgdG8gYGV4cGVjdGAuXG4gICAqXG4gICAqICAgICBleHBlY3QoNDIsICdub29vIHdoeSBmYWlsPz8nKS50by5iZS5udWxsO1xuICAgKlxuICAgKiBAbmFtZSBudWxsXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgnbnVsbCcsIGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgbnVsbCA9PT0gZmxhZyh0aGlzLCAnb2JqZWN0JylcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgbnVsbCdcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gbm90IHRvIGJlIG51bGwnXG4gICAgKTtcbiAgfSk7XG5cbiAgLyoqXG4gICAqICMjIyAudW5kZWZpbmVkXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIHN0cmljdGx5IChgPT09YCkgZXF1YWwgdG8gYHVuZGVmaW5lZGAuXG4gICAqXG4gICAqICAgICBleHBlY3QodW5kZWZpbmVkKS50by5iZS51bmRlZmluZWQ7XG4gICAqXG4gICAqIEFkZCBgLm5vdGAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gbmVnYXRlIGAudW5kZWZpbmVkYC4gSG93ZXZlciwgaXQncyBvZnRlblxuICAgKiBiZXN0IHRvIGFzc2VydCB0aGF0IHRoZSB0YXJnZXQgaXMgZXF1YWwgdG8gaXRzIGV4cGVjdGVkIHZhbHVlLCByYXRoZXIgdGhhblxuICAgKiBub3QgZXF1YWwgdG8gYHVuZGVmaW5lZGAuXG4gICAqXG4gICAqICAgICBleHBlY3QoMSkudG8uZXF1YWwoMSk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoMSkudG8ubm90LmJlLnVuZGVmaW5lZDsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqIEEgY3VzdG9tIGVycm9yIG1lc3NhZ2UgY2FuIGJlIGdpdmVuIGFzIHRoZSBzZWNvbmQgYXJndW1lbnQgdG8gYGV4cGVjdGAuXG4gICAqXG4gICAqICAgICBleHBlY3QoNDIsICdub29vIHdoeSBmYWlsPz8nKS50by5iZS51bmRlZmluZWQ7XG4gICAqXG4gICAqIEBuYW1lIHVuZGVmaW5lZFxuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBBc3NlcnRpb24uYWRkUHJvcGVydHkoJ3VuZGVmaW5lZCcsIGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgdW5kZWZpbmVkID09PSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSB1bmRlZmluZWQnXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IG5vdCB0byBiZSB1bmRlZmluZWQnXG4gICAgKTtcbiAgfSk7XG5cbiAgLyoqXG4gICAqICMjIyAuTmFOXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGV4YWN0bHkgYE5hTmAuXG4gICAqXG4gICAqICAgICBleHBlY3QoTmFOKS50by5iZS5OYU47XG4gICAqXG4gICAqIEFkZCBgLm5vdGAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gbmVnYXRlIGAuTmFOYC4gSG93ZXZlciwgaXQncyBvZnRlbiBiZXN0XG4gICAqIHRvIGFzc2VydCB0aGF0IHRoZSB0YXJnZXQgaXMgZXF1YWwgdG8gaXRzIGV4cGVjdGVkIHZhbHVlLCByYXRoZXIgdGhhbiBub3RcbiAgICogZXF1YWwgdG8gYE5hTmAuXG4gICAqXG4gICAqICAgICBleHBlY3QoJ2ZvbycpLnRvLmVxdWFsKCdmb28nKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCgnZm9vJykudG8ubm90LmJlLk5hTjsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqIEEgY3VzdG9tIGVycm9yIG1lc3NhZ2UgY2FuIGJlIGdpdmVuIGFzIHRoZSBzZWNvbmQgYXJndW1lbnQgdG8gYGV4cGVjdGAuXG4gICAqXG4gICAqICAgICBleHBlY3QoNDIsICdub29vIHdoeSBmYWlsPz8nKS50by5iZS5OYU47XG4gICAqXG4gICAqIEBuYW1lIE5hTlxuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBBc3NlcnRpb24uYWRkUHJvcGVydHkoJ05hTicsIGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgXy5pc05hTihmbGFnKHRoaXMsICdvYmplY3QnKSlcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBOYU4nXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gbm90IHRvIGJlIE5hTidcbiAgICApO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC5leGlzdFxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBub3Qgc3RyaWN0bHkgKGA9PT1gKSBlcXVhbCB0byBlaXRoZXIgYG51bGxgIG9yXG4gICAqIGB1bmRlZmluZWRgLiBIb3dldmVyLCBpdCdzIG9mdGVuIGJlc3QgdG8gYXNzZXJ0IHRoYXQgdGhlIHRhcmdldCBpcyBlcXVhbCB0b1xuICAgKiBpdHMgZXhwZWN0ZWQgdmFsdWUuXG4gICAqXG4gICAqICAgICBleHBlY3QoMSkudG8uZXF1YWwoMSk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoMSkudG8uZXhpc3Q7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiAgICAgZXhwZWN0KDApLnRvLmVxdWFsKDApOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KDApLnRvLmV4aXN0OyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogQWRkIGAubm90YCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byBuZWdhdGUgYC5leGlzdGAuXG4gICAqXG4gICAqICAgICBleHBlY3QobnVsbCkudG8uYmUubnVsbDsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdChudWxsKS50by5ub3QuZXhpc3Q7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiAgICAgZXhwZWN0KHVuZGVmaW5lZCkudG8uYmUudW5kZWZpbmVkOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KHVuZGVmaW5lZCkudG8ubm90LmV4aXN0OyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogQSBjdXN0b20gZXJyb3IgbWVzc2FnZSBjYW4gYmUgZ2l2ZW4gYXMgdGhlIHNlY29uZCBhcmd1bWVudCB0byBgZXhwZWN0YC5cbiAgICpcbiAgICogICAgIGV4cGVjdChudWxsLCAnbm9vbyB3aHkgZmFpbD8/JykudG8uZXhpc3Q7XG4gICAqXG4gICAqIFRoZSBhbGlhcyBgLmV4aXN0c2AgY2FuIGJlIHVzZWQgaW50ZXJjaGFuZ2VhYmx5IHdpdGggYC5leGlzdGAuXG4gICAqXG4gICAqIEBuYW1lIGV4aXN0XG4gICAqIEBhbGlhcyBleGlzdHNcbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gYXNzZXJ0RXhpc3QgKCkge1xuICAgIHZhciB2YWwgPSBmbGFnKHRoaXMsICdvYmplY3QnKTtcbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgdmFsICE9PSBudWxsICYmIHZhbCAhPT0gdW5kZWZpbmVkXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGV4aXN0J1xuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgZXhpc3QnXG4gICAgKTtcbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgnZXhpc3QnLCBhc3NlcnRFeGlzdCk7XG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgnZXhpc3RzJywgYXNzZXJ0RXhpc3QpO1xuXG4gIC8qKlxuICAgKiAjIyMgLmVtcHR5XG4gICAqXG4gICAqIFdoZW4gdGhlIHRhcmdldCBpcyBhIHN0cmluZyBvciBhcnJheSwgYC5lbXB0eWAgYXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQnc1xuICAgKiBgbGVuZ3RoYCBwcm9wZXJ0eSBpcyBzdHJpY3RseSAoYD09PWApIGVxdWFsIHRvIGAwYC5cbiAgICpcbiAgICogICAgIGV4cGVjdChbXSkudG8uYmUuZW1wdHk7XG4gICAqICAgICBleHBlY3QoJycpLnRvLmJlLmVtcHR5O1xuICAgKlxuICAgKiBXaGVuIHRoZSB0YXJnZXQgaXMgYSBtYXAgb3Igc2V0LCBgLmVtcHR5YCBhc3NlcnRzIHRoYXQgdGhlIHRhcmdldCdzIGBzaXplYFxuICAgKiBwcm9wZXJ0eSBpcyBzdHJpY3RseSBlcXVhbCB0byBgMGAuXG4gICAqXG4gICAqICAgICBleHBlY3QobmV3IFNldCgpKS50by5iZS5lbXB0eTtcbiAgICogICAgIGV4cGVjdChuZXcgTWFwKCkpLnRvLmJlLmVtcHR5O1xuICAgKlxuICAgKiBXaGVuIHRoZSB0YXJnZXQgaXMgYSBub24tZnVuY3Rpb24gb2JqZWN0LCBgLmVtcHR5YCBhc3NlcnRzIHRoYXQgdGhlIHRhcmdldFxuICAgKiBkb2Vzbid0IGhhdmUgYW55IG93biBlbnVtZXJhYmxlIHByb3BlcnRpZXMuIFByb3BlcnRpZXMgd2l0aCBTeW1ib2wtYmFzZWRcbiAgICoga2V5cyBhcmUgZXhjbHVkZWQgZnJvbSB0aGUgY291bnQuXG4gICAqXG4gICAqICAgICBleHBlY3Qoe30pLnRvLmJlLmVtcHR5O1xuICAgKlxuICAgKiBCZWNhdXNlIGAuZW1wdHlgIGRvZXMgZGlmZmVyZW50IHRoaW5ncyBiYXNlZCBvbiB0aGUgdGFyZ2V0J3MgdHlwZSwgaXQnc1xuICAgKiBpbXBvcnRhbnQgdG8gY2hlY2sgdGhlIHRhcmdldCdzIHR5cGUgYmVmb3JlIHVzaW5nIGAuZW1wdHlgLiBTZWUgdGhlIGAuYWBcbiAgICogZG9jIGZvciBpbmZvIG9uIHRlc3RpbmcgYSB0YXJnZXQncyB0eXBlLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KFtdKS50by5iZS5hbignYXJyYXknKS50aGF0LmlzLmVtcHR5O1xuICAgKlxuICAgKiBBZGQgYC5ub3RgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIG5lZ2F0ZSBgLmVtcHR5YC4gSG93ZXZlciwgaXQncyBvZnRlblxuICAgKiBiZXN0IHRvIGFzc2VydCB0aGF0IHRoZSB0YXJnZXQgY29udGFpbnMgaXRzIGV4cGVjdGVkIG51bWJlciBvZiB2YWx1ZXMsXG4gICAqIHJhdGhlciB0aGFuIGFzc2VydGluZyB0aGF0IGl0J3Mgbm90IGVtcHR5LlxuICAgKlxuICAgKiAgICAgZXhwZWN0KFsxLCAyLCAzXSkudG8uaGF2ZS5sZW5ndGhPZigzKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdChbMSwgMiwgM10pLnRvLm5vdC5iZS5lbXB0eTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqICAgICBleHBlY3QobmV3IFNldChbMSwgMiwgM10pKS50by5oYXZlLnByb3BlcnR5KCdzaXplJywgMyk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QobmV3IFNldChbMSwgMiwgM10pKS50by5ub3QuYmUuZW1wdHk7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiAgICAgZXhwZWN0KE9iamVjdC5rZXlzKHthOiAxfSkpLnRvLmhhdmUubGVuZ3RoT2YoMSk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3Qoe2E6IDF9KS50by5ub3QuYmUuZW1wdHk7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBBIGN1c3RvbSBlcnJvciBtZXNzYWdlIGNhbiBiZSBnaXZlbiBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50IHRvIGBleHBlY3RgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KFsxLCAyLCAzXSwgJ25vb28gd2h5IGZhaWw/PycpLnRvLmJlLmVtcHR5O1xuICAgKlxuICAgKiBAbmFtZSBlbXB0eVxuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBBc3NlcnRpb24uYWRkUHJvcGVydHkoJ2VtcHR5JywgZnVuY3Rpb24gKCkge1xuICAgIHZhciB2YWwgPSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCBzc2ZpID0gZmxhZyh0aGlzLCAnc3NmaScpXG4gICAgICAsIGZsYWdNc2cgPSBmbGFnKHRoaXMsICdtZXNzYWdlJylcbiAgICAgICwgaXRlbXNDb3VudDtcblxuICAgIGZsYWdNc2cgPSBmbGFnTXNnID8gZmxhZ01zZyArICc6ICcgOiAnJztcblxuICAgIHN3aXRjaCAoXy50eXBlKHZhbCkudG9Mb3dlckNhc2UoKSkge1xuICAgICAgY2FzZSAnYXJyYXknOlxuICAgICAgY2FzZSAnc3RyaW5nJzpcbiAgICAgICAgaXRlbXNDb3VudCA9IHZhbC5sZW5ndGg7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbWFwJzpcbiAgICAgIGNhc2UgJ3NldCc6XG4gICAgICAgIGl0ZW1zQ291bnQgPSB2YWwuc2l6ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICd3ZWFrbWFwJzpcbiAgICAgIGNhc2UgJ3dlYWtzZXQnOlxuICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoXG4gICAgICAgICAgZmxhZ01zZyArICcuZW1wdHkgd2FzIHBhc3NlZCBhIHdlYWsgY29sbGVjdGlvbicsXG4gICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgIHNzZmlcbiAgICAgICAgKTtcbiAgICAgIGNhc2UgJ2Z1bmN0aW9uJzpcbiAgICAgICAgdmFyIG1zZyA9IGZsYWdNc2cgKyAnLmVtcHR5IHdhcyBwYXNzZWQgYSBmdW5jdGlvbiAnICsgXy5nZXROYW1lKHZhbCk7XG4gICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihtc2cudHJpbSgpLCB1bmRlZmluZWQsIHNzZmkpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKHZhbCAhPT0gT2JqZWN0KHZhbCkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoXG4gICAgICAgICAgICBmbGFnTXNnICsgJy5lbXB0eSB3YXMgcGFzc2VkIG5vbi1zdHJpbmcgcHJpbWl0aXZlICcgKyBfLmluc3BlY3QodmFsKSxcbiAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHNzZmlcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGl0ZW1zQ291bnQgPSBPYmplY3Qua2V5cyh2YWwpLmxlbmd0aDtcbiAgICB9XG5cbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgMCA9PT0gaXRlbXNDb3VudFxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBlbXB0eSdcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gbm90IHRvIGJlIGVtcHR5J1xuICAgICk7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiAjIyMgLmFyZ3VtZW50c1xuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBhbiBgYXJndW1lbnRzYCBvYmplY3QuXG4gICAqXG4gICAqICAgICBmdW5jdGlvbiB0ZXN0ICgpIHtcbiAgICogICAgICAgZXhwZWN0KGFyZ3VtZW50cykudG8uYmUuYXJndW1lbnRzO1xuICAgKiAgICAgfVxuICAgKlxuICAgKiAgICAgdGVzdCgpO1xuICAgKlxuICAgKiBBZGQgYC5ub3RgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIG5lZ2F0ZSBgLmFyZ3VtZW50c2AuIEhvd2V2ZXIsIGl0J3Mgb2Z0ZW5cbiAgICogYmVzdCB0byBhc3NlcnQgd2hpY2ggdHlwZSB0aGUgdGFyZ2V0IGlzIGV4cGVjdGVkIHRvIGJlLCByYXRoZXIgdGhhblxuICAgKiBhc3NlcnRpbmcgdGhhdCBpdFx1MjAxOXMgbm90IGFuIGBhcmd1bWVudHNgIG9iamVjdC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgnZm9vJykudG8uYmUuYSgnc3RyaW5nJyk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoJ2ZvbycpLnRvLm5vdC5iZS5hcmd1bWVudHM7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBBIGN1c3RvbSBlcnJvciBtZXNzYWdlIGNhbiBiZSBnaXZlbiBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50IHRvIGBleHBlY3RgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KHt9LCAnbm9vbyB3aHkgZmFpbD8/JykudG8uYmUuYXJndW1lbnRzO1xuICAgKlxuICAgKiBUaGUgYWxpYXMgYC5Bcmd1bWVudHNgIGNhbiBiZSB1c2VkIGludGVyY2hhbmdlYWJseSB3aXRoIGAuYXJndW1lbnRzYC5cbiAgICpcbiAgICogQG5hbWUgYXJndW1lbnRzXG4gICAqIEBhbGlhcyBBcmd1bWVudHNcbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gY2hlY2tBcmd1bWVudHMgKCkge1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCB0eXBlID0gXy50eXBlKG9iaik7XG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICdBcmd1bWVudHMnID09PSB0eXBlXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIGFyZ3VtZW50cyBidXQgZ290ICcgKyB0eXBlXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBiZSBhcmd1bWVudHMnXG4gICAgKTtcbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgnYXJndW1lbnRzJywgY2hlY2tBcmd1bWVudHMpO1xuICBBc3NlcnRpb24uYWRkUHJvcGVydHkoJ0FyZ3VtZW50cycsIGNoZWNrQXJndW1lbnRzKTtcblxuICAvKipcbiAgICogIyMjIC5lcXVhbCh2YWxbLCBtc2ddKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBzdHJpY3RseSAoYD09PWApIGVxdWFsIHRvIHRoZSBnaXZlbiBgdmFsYC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgxKS50by5lcXVhbCgxKTtcbiAgICogICAgIGV4cGVjdCgnZm9vJykudG8uZXF1YWwoJ2ZvbycpO1xuICAgKlxuICAgKiBBZGQgYC5kZWVwYCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byB1c2UgZGVlcCBlcXVhbGl0eSBpbnN0ZWFkLiBTZWUgdGhlXG4gICAqIGBkZWVwLWVxbGAgcHJvamVjdCBwYWdlIGZvciBpbmZvIG9uIHRoZSBkZWVwIGVxdWFsaXR5IGFsZ29yaXRobTpcbiAgICogaHR0cHM6Ly9naXRodWIuY29tL2NoYWlqcy9kZWVwLWVxbC5cbiAgICpcbiAgICogICAgIC8vIFRhcmdldCBvYmplY3QgZGVlcGx5IChidXQgbm90IHN0cmljdGx5KSBlcXVhbHMgYHthOiAxfWBcbiAgICogICAgIGV4cGVjdCh7YTogMX0pLnRvLmRlZXAuZXF1YWwoe2E6IDF9KTtcbiAgICogICAgIGV4cGVjdCh7YTogMX0pLnRvLm5vdC5lcXVhbCh7YTogMX0pO1xuICAgKlxuICAgKiAgICAgLy8gVGFyZ2V0IGFycmF5IGRlZXBseSAoYnV0IG5vdCBzdHJpY3RseSkgZXF1YWxzIGBbMSwgMl1gXG4gICAqICAgICBleHBlY3QoWzEsIDJdKS50by5kZWVwLmVxdWFsKFsxLCAyXSk7XG4gICAqICAgICBleHBlY3QoWzEsIDJdKS50by5ub3QuZXF1YWwoWzEsIDJdKTtcbiAgICpcbiAgICogQWRkIGAubm90YCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byBuZWdhdGUgYC5lcXVhbGAuIEhvd2V2ZXIsIGl0J3Mgb2Z0ZW5cbiAgICogYmVzdCB0byBhc3NlcnQgdGhhdCB0aGUgdGFyZ2V0IGlzIGVxdWFsIHRvIGl0cyBleHBlY3RlZCB2YWx1ZSwgcmF0aGVyIHRoYW5cbiAgICogbm90IGVxdWFsIHRvIG9uZSBvZiBjb3VudGxlc3MgdW5leHBlY3RlZCB2YWx1ZXMuXG4gICAqXG4gICAqICAgICBleHBlY3QoMSkudG8uZXF1YWwoMSk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoMSkudG8ubm90LmVxdWFsKDIpOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogYC5lcXVhbGAgYWNjZXB0cyBhbiBvcHRpb25hbCBgbXNnYCBhcmd1bWVudCB3aGljaCBpcyBhIGN1c3RvbSBlcnJvciBtZXNzYWdlXG4gICAqIHRvIHNob3cgd2hlbiB0aGUgYXNzZXJ0aW9uIGZhaWxzLiBUaGUgbWVzc2FnZSBjYW4gYWxzbyBiZSBnaXZlbiBhcyB0aGVcbiAgICogc2Vjb25kIGFyZ3VtZW50IHRvIGBleHBlY3RgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KDEpLnRvLmVxdWFsKDIsICdub29vIHdoeSBmYWlsPz8nKTtcbiAgICogICAgIGV4cGVjdCgxLCAnbm9vbyB3aHkgZmFpbD8/JykudG8uZXF1YWwoMik7XG4gICAqXG4gICAqIFRoZSBhbGlhc2VzIGAuZXF1YWxzYCBhbmQgYGVxYCBjYW4gYmUgdXNlZCBpbnRlcmNoYW5nZWFibHkgd2l0aCBgLmVxdWFsYC5cbiAgICpcbiAgICogQG5hbWUgZXF1YWxcbiAgICogQGFsaWFzIGVxdWFsc1xuICAgKiBAYWxpYXMgZXFcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtc2cgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBhc3NlcnRFcXVhbCAodmFsLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gICAgaWYgKGZsYWcodGhpcywgJ2RlZXAnKSkge1xuICAgICAgdmFyIHByZXZMb2NrU3NmaSA9IGZsYWcodGhpcywgJ2xvY2tTc2ZpJyk7XG4gICAgICBmbGFnKHRoaXMsICdsb2NrU3NmaScsIHRydWUpO1xuICAgICAgdGhpcy5lcWwodmFsKTtcbiAgICAgIGZsYWcodGhpcywgJ2xvY2tTc2ZpJywgcHJldkxvY2tTc2ZpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgdmFsID09PSBvYmpcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBlcXVhbCAje2V4cH0nXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGVxdWFsICN7ZXhwfSdcbiAgICAgICAgLCB2YWxcbiAgICAgICAgLCB0aGlzLl9vYmpcbiAgICAgICAgLCB0cnVlXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2VxdWFsJywgYXNzZXJ0RXF1YWwpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdlcXVhbHMnLCBhc3NlcnRFcXVhbCk7XG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2VxJywgYXNzZXJ0RXF1YWwpO1xuXG4gIC8qKlxuICAgKiAjIyMgLmVxbChvYmpbLCBtc2ddKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBkZWVwbHkgZXF1YWwgdG8gdGhlIGdpdmVuIGBvYmpgLiBTZWUgdGhlXG4gICAqIGBkZWVwLWVxbGAgcHJvamVjdCBwYWdlIGZvciBpbmZvIG9uIHRoZSBkZWVwIGVxdWFsaXR5IGFsZ29yaXRobTpcbiAgICogaHR0cHM6Ly9naXRodWIuY29tL2NoYWlqcy9kZWVwLWVxbC5cbiAgICpcbiAgICogICAgIC8vIFRhcmdldCBvYmplY3QgaXMgZGVlcGx5IChidXQgbm90IHN0cmljdGx5KSBlcXVhbCB0byB7YTogMX1cbiAgICogICAgIGV4cGVjdCh7YTogMX0pLnRvLmVxbCh7YTogMX0pLmJ1dC5ub3QuZXF1YWwoe2E6IDF9KTtcbiAgICpcbiAgICogICAgIC8vIFRhcmdldCBhcnJheSBpcyBkZWVwbHkgKGJ1dCBub3Qgc3RyaWN0bHkpIGVxdWFsIHRvIFsxLCAyXVxuICAgKiAgICAgZXhwZWN0KFsxLCAyXSkudG8uZXFsKFsxLCAyXSkuYnV0Lm5vdC5lcXVhbChbMSwgMl0pO1xuICAgKlxuICAgKiBBZGQgYC5ub3RgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIG5lZ2F0ZSBgLmVxbGAuIEhvd2V2ZXIsIGl0J3Mgb2Z0ZW4gYmVzdFxuICAgKiB0byBhc3NlcnQgdGhhdCB0aGUgdGFyZ2V0IGlzIGRlZXBseSBlcXVhbCB0byBpdHMgZXhwZWN0ZWQgdmFsdWUsIHJhdGhlclxuICAgKiB0aGFuIG5vdCBkZWVwbHkgZXF1YWwgdG8gb25lIG9mIGNvdW50bGVzcyB1bmV4cGVjdGVkIHZhbHVlcy5cbiAgICpcbiAgICogICAgIGV4cGVjdCh7YTogMX0pLnRvLmVxbCh7YTogMX0pOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KHthOiAxfSkudG8ubm90LmVxbCh7YjogMn0pOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogYC5lcWxgIGFjY2VwdHMgYW4gb3B0aW9uYWwgYG1zZ2AgYXJndW1lbnQgd2hpY2ggaXMgYSBjdXN0b20gZXJyb3IgbWVzc2FnZVxuICAgKiB0byBzaG93IHdoZW4gdGhlIGFzc2VydGlvbiBmYWlscy4gVGhlIG1lc3NhZ2UgY2FuIGFsc28gYmUgZ2l2ZW4gYXMgdGhlXG4gICAqIHNlY29uZCBhcmd1bWVudCB0byBgZXhwZWN0YC5cbiAgICpcbiAgICogICAgIGV4cGVjdCh7YTogMX0pLnRvLmVxbCh7YjogMn0sICdub29vIHdoeSBmYWlsPz8nKTtcbiAgICogICAgIGV4cGVjdCh7YTogMX0sICdub29vIHdoeSBmYWlsPz8nKS50by5lcWwoe2I6IDJ9KTtcbiAgICpcbiAgICogVGhlIGFsaWFzIGAuZXFsc2AgY2FuIGJlIHVzZWQgaW50ZXJjaGFuZ2VhYmx5IHdpdGggYC5lcWxgLlxuICAgKlxuICAgKiBUaGUgYC5kZWVwLmVxdWFsYCBhc3NlcnRpb24gaXMgYWxtb3N0IGlkZW50aWNhbCB0byBgLmVxbGAgYnV0IHdpdGggb25lXG4gICAqIGRpZmZlcmVuY2U6IGAuZGVlcC5lcXVhbGAgY2F1c2VzIGRlZXAgZXF1YWxpdHkgY29tcGFyaXNvbnMgdG8gYWxzbyBiZSB1c2VkXG4gICAqIGZvciBhbnkgb3RoZXIgYXNzZXJ0aW9ucyB0aGF0IGZvbGxvdyBpbiB0aGUgY2hhaW4uXG4gICAqXG4gICAqIEBuYW1lIGVxbFxuICAgKiBAYWxpYXMgZXFsc1xuICAgKiBAcGFyYW0ge01peGVkfSBvYmpcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1zZyBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGFzc2VydEVxbChvYmosIG1zZykge1xuICAgIGlmIChtc2cpIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICBfLmVxbChvYmosIGZsYWcodGhpcywgJ29iamVjdCcpKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBkZWVwbHkgZXF1YWwgI3tleHB9J1xuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgZGVlcGx5IGVxdWFsICN7ZXhwfSdcbiAgICAgICwgb2JqXG4gICAgICAsIHRoaXMuX29ialxuICAgICAgLCB0cnVlXG4gICAgKTtcbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2VxbCcsIGFzc2VydEVxbCk7XG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2VxbHMnLCBhc3NlcnRFcWwpO1xuXG4gIC8qKlxuICAgKiAjIyMgLmFib3ZlKG5bLCBtc2ddKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBhIG51bWJlciBvciBhIGRhdGUgZ3JlYXRlciB0aGFuIHRoZSBnaXZlbiBudW1iZXIgb3IgZGF0ZSBgbmAgcmVzcGVjdGl2ZWx5LlxuICAgKiBIb3dldmVyLCBpdCdzIG9mdGVuIGJlc3QgdG8gYXNzZXJ0IHRoYXQgdGhlIHRhcmdldCBpcyBlcXVhbCB0byBpdHMgZXhwZWN0ZWRcbiAgICogdmFsdWUuXG4gICAqXG4gICAqICAgICBleHBlY3QoMikudG8uZXF1YWwoMik7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoMikudG8uYmUuYWJvdmUoMSk7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBBZGQgYC5sZW5ndGhPZmAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gYXNzZXJ0IHRoYXQgdGhlIHRhcmdldCdzIGBsZW5ndGhgXG4gICAqIG9yIGBzaXplYCBpcyBncmVhdGVyIHRoYW4gdGhlIGdpdmVuIG51bWJlciBgbmAuXG4gICAqXG4gICAqICAgICBleHBlY3QoJ2ZvbycpLnRvLmhhdmUubGVuZ3RoT2YoMyk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoJ2ZvbycpLnRvLmhhdmUubGVuZ3RoT2YuYWJvdmUoMik7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiAgICAgZXhwZWN0KFsxLCAyLCAzXSkudG8uaGF2ZS5sZW5ndGhPZigzKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdChbMSwgMiwgM10pLnRvLmhhdmUubGVuZ3RoT2YuYWJvdmUoMik7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBBZGQgYC5ub3RgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIG5lZ2F0ZSBgLmFib3ZlYC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgyKS50by5lcXVhbCgyKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCgxKS50by5ub3QuYmUuYWJvdmUoMik7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBgLmFib3ZlYCBhY2NlcHRzIGFuIG9wdGlvbmFsIGBtc2dgIGFyZ3VtZW50IHdoaWNoIGlzIGEgY3VzdG9tIGVycm9yIG1lc3NhZ2VcbiAgICogdG8gc2hvdyB3aGVuIHRoZSBhc3NlcnRpb24gZmFpbHMuIFRoZSBtZXNzYWdlIGNhbiBhbHNvIGJlIGdpdmVuIGFzIHRoZVxuICAgKiBzZWNvbmQgYXJndW1lbnQgdG8gYGV4cGVjdGAuXG4gICAqXG4gICAqICAgICBleHBlY3QoMSkudG8uYmUuYWJvdmUoMiwgJ25vb28gd2h5IGZhaWw/PycpO1xuICAgKiAgICAgZXhwZWN0KDEsICdub29vIHdoeSBmYWlsPz8nKS50by5iZS5hYm92ZSgyKTtcbiAgICpcbiAgICogVGhlIGFsaWFzZXMgYC5ndGAgYW5kIGAuZ3JlYXRlclRoYW5gIGNhbiBiZSB1c2VkIGludGVyY2hhbmdlYWJseSB3aXRoXG4gICAqIGAuYWJvdmVgLlxuICAgKlxuICAgKiBAbmFtZSBhYm92ZVxuICAgKiBAYWxpYXMgZ3RcbiAgICogQGFsaWFzIGdyZWF0ZXJUaGFuXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtc2cgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBhc3NlcnRBYm92ZSAobiwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAsIGRvTGVuZ3RoID0gZmxhZyh0aGlzLCAnZG9MZW5ndGgnKVxuICAgICAgLCBmbGFnTXNnID0gZmxhZyh0aGlzLCAnbWVzc2FnZScpXG4gICAgICAsIG1zZ1ByZWZpeCA9ICgoZmxhZ01zZykgPyBmbGFnTXNnICsgJzogJyA6ICcnKVxuICAgICAgLCBzc2ZpID0gZmxhZyh0aGlzLCAnc3NmaScpXG4gICAgICAsIG9ialR5cGUgPSBfLnR5cGUob2JqKS50b0xvd2VyQ2FzZSgpXG4gICAgICAsIG5UeXBlID0gXy50eXBlKG4pLnRvTG93ZXJDYXNlKClcbiAgICAgICwgZXJyb3JNZXNzYWdlXG4gICAgICAsIHNob3VsZFRocm93ID0gdHJ1ZTtcblxuICAgIGlmIChkb0xlbmd0aCAmJiBvYmpUeXBlICE9PSAnbWFwJyAmJiBvYmpUeXBlICE9PSAnc2V0Jykge1xuICAgICAgbmV3IEFzc2VydGlvbihvYmosIGZsYWdNc2csIHNzZmksIHRydWUpLnRvLmhhdmUucHJvcGVydHkoJ2xlbmd0aCcpO1xuICAgIH1cblxuICAgIGlmICghZG9MZW5ndGggJiYgKG9ialR5cGUgPT09ICdkYXRlJyAmJiBuVHlwZSAhPT0gJ2RhdGUnKSkge1xuICAgICAgZXJyb3JNZXNzYWdlID0gbXNnUHJlZml4ICsgJ3RoZSBhcmd1bWVudCB0byBhYm92ZSBtdXN0IGJlIGEgZGF0ZSc7XG4gICAgfSBlbHNlIGlmIChuVHlwZSAhPT0gJ251bWJlcicgJiYgKGRvTGVuZ3RoIHx8IG9ialR5cGUgPT09ICdudW1iZXInKSkge1xuICAgICAgZXJyb3JNZXNzYWdlID0gbXNnUHJlZml4ICsgJ3RoZSBhcmd1bWVudCB0byBhYm92ZSBtdXN0IGJlIGEgbnVtYmVyJztcbiAgICB9IGVsc2UgaWYgKCFkb0xlbmd0aCAmJiAob2JqVHlwZSAhPT0gJ2RhdGUnICYmIG9ialR5cGUgIT09ICdudW1iZXInKSkge1xuICAgICAgdmFyIHByaW50T2JqID0gKG9ialR5cGUgPT09ICdzdHJpbmcnKSA/IFwiJ1wiICsgb2JqICsgXCInXCIgOiBvYmo7XG4gICAgICBlcnJvck1lc3NhZ2UgPSBtc2dQcmVmaXggKyAnZXhwZWN0ZWQgJyArIHByaW50T2JqICsgJyB0byBiZSBhIG51bWJlciBvciBhIGRhdGUnO1xuICAgIH0gZWxzZSB7XG4gICAgICBzaG91bGRUaHJvdyA9IGZhbHNlO1xuICAgIH1cblxuICAgIGlmIChzaG91bGRUaHJvdykge1xuICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKGVycm9yTWVzc2FnZSwgdW5kZWZpbmVkLCBzc2ZpKTtcbiAgICB9XG5cbiAgICBpZiAoZG9MZW5ndGgpIHtcbiAgICAgIHZhciBkZXNjcmlwdG9yID0gJ2xlbmd0aCdcbiAgICAgICAgLCBpdGVtc0NvdW50O1xuICAgICAgaWYgKG9ialR5cGUgPT09ICdtYXAnIHx8IG9ialR5cGUgPT09ICdzZXQnKSB7XG4gICAgICAgIGRlc2NyaXB0b3IgPSAnc2l6ZSc7XG4gICAgICAgIGl0ZW1zQ291bnQgPSBvYmouc2l6ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGl0ZW1zQ291bnQgPSBvYmoubGVuZ3RoO1xuICAgICAgfVxuICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgaXRlbXNDb3VudCA+IG5cbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBoYXZlIGEgJyArIGRlc2NyaXB0b3IgKyAnIGFib3ZlICN7ZXhwfSBidXQgZ290ICN7YWN0fSdcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgaGF2ZSBhICcgKyBkZXNjcmlwdG9yICsgJyBhYm92ZSAje2V4cH0nXG4gICAgICAgICwgblxuICAgICAgICAsIGl0ZW1zQ291bnRcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgIG9iaiA+IG5cbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBhYm92ZSAje2V4cH0nXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgYXQgbW9zdCAje2V4cH0nXG4gICAgICAgICwgblxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdhYm92ZScsIGFzc2VydEFib3ZlKTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnZ3QnLCBhc3NlcnRBYm92ZSk7XG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2dyZWF0ZXJUaGFuJywgYXNzZXJ0QWJvdmUpO1xuXG4gIC8qKlxuICAgKiAjIyMgLmxlYXN0KG5bLCBtc2ddKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBhIG51bWJlciBvciBhIGRhdGUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBnaXZlblxuICAgKiBudW1iZXIgb3IgZGF0ZSBgbmAgcmVzcGVjdGl2ZWx5LiBIb3dldmVyLCBpdCdzIG9mdGVuIGJlc3QgdG8gYXNzZXJ0IHRoYXQgdGhlIHRhcmdldCBpcyBlcXVhbCB0b1xuICAgKiBpdHMgZXhwZWN0ZWQgdmFsdWUuXG4gICAqXG4gICAqICAgICBleHBlY3QoMikudG8uZXF1YWwoMik7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoMikudG8uYmUuYXQubGVhc3QoMSk7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KDIpLnRvLmJlLmF0LmxlYXN0KDIpOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogQWRkIGAubGVuZ3RoT2ZgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIGFzc2VydCB0aGF0IHRoZSB0YXJnZXQncyBgbGVuZ3RoYFxuICAgKiBvciBgc2l6ZWAgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBnaXZlbiBudW1iZXIgYG5gLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KCdmb28nKS50by5oYXZlLmxlbmd0aE9mKDMpOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KCdmb28nKS50by5oYXZlLmxlbmd0aE9mLmF0LmxlYXN0KDIpOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogICAgIGV4cGVjdChbMSwgMiwgM10pLnRvLmhhdmUubGVuZ3RoT2YoMyk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoWzEsIDIsIDNdKS50by5oYXZlLmxlbmd0aE9mLmF0LmxlYXN0KDIpOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogQWRkIGAubm90YCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byBuZWdhdGUgYC5sZWFzdGAuXG4gICAqXG4gICAqICAgICBleHBlY3QoMSkudG8uZXF1YWwoMSk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoMSkudG8ubm90LmJlLmF0LmxlYXN0KDIpOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogYC5sZWFzdGAgYWNjZXB0cyBhbiBvcHRpb25hbCBgbXNnYCBhcmd1bWVudCB3aGljaCBpcyBhIGN1c3RvbSBlcnJvciBtZXNzYWdlXG4gICAqIHRvIHNob3cgd2hlbiB0aGUgYXNzZXJ0aW9uIGZhaWxzLiBUaGUgbWVzc2FnZSBjYW4gYWxzbyBiZSBnaXZlbiBhcyB0aGVcbiAgICogc2Vjb25kIGFyZ3VtZW50IHRvIGBleHBlY3RgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KDEpLnRvLmJlLmF0LmxlYXN0KDIsICdub29vIHdoeSBmYWlsPz8nKTtcbiAgICogICAgIGV4cGVjdCgxLCAnbm9vbyB3aHkgZmFpbD8/JykudG8uYmUuYXQubGVhc3QoMik7XG4gICAqXG4gICAqIFRoZSBhbGlhc2VzIGAuZ3RlYCBhbmQgYC5ncmVhdGVyVGhhbk9yRXF1YWxgIGNhbiBiZSB1c2VkIGludGVyY2hhbmdlYWJseSB3aXRoXG4gICAqIGAubGVhc3RgLlxuICAgKlxuICAgKiBAbmFtZSBsZWFzdFxuICAgKiBAYWxpYXMgZ3RlXG4gICAqIEBhbGlhcyBncmVhdGVyVGhhbk9yRXF1YWxcbiAgICogQHBhcmFtIHtOdW1iZXJ9IG5cbiAgICogQHBhcmFtIHtTdHJpbmd9IG1zZyBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGFzc2VydExlYXN0IChuLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0JylcbiAgICAgICwgZG9MZW5ndGggPSBmbGFnKHRoaXMsICdkb0xlbmd0aCcpXG4gICAgICAsIGZsYWdNc2cgPSBmbGFnKHRoaXMsICdtZXNzYWdlJylcbiAgICAgICwgbXNnUHJlZml4ID0gKChmbGFnTXNnKSA/IGZsYWdNc2cgKyAnOiAnIDogJycpXG4gICAgICAsIHNzZmkgPSBmbGFnKHRoaXMsICdzc2ZpJylcbiAgICAgICwgb2JqVHlwZSA9IF8udHlwZShvYmopLnRvTG93ZXJDYXNlKClcbiAgICAgICwgblR5cGUgPSBfLnR5cGUobikudG9Mb3dlckNhc2UoKVxuICAgICAgLCBlcnJvck1lc3NhZ2VcbiAgICAgICwgc2hvdWxkVGhyb3cgPSB0cnVlO1xuXG4gICAgaWYgKGRvTGVuZ3RoICYmIG9ialR5cGUgIT09ICdtYXAnICYmIG9ialR5cGUgIT09ICdzZXQnKSB7XG4gICAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgZmxhZ01zZywgc3NmaSwgdHJ1ZSkudG8uaGF2ZS5wcm9wZXJ0eSgnbGVuZ3RoJyk7XG4gICAgfVxuXG4gICAgaWYgKCFkb0xlbmd0aCAmJiAob2JqVHlwZSA9PT0gJ2RhdGUnICYmIG5UeXBlICE9PSAnZGF0ZScpKSB7XG4gICAgICBlcnJvck1lc3NhZ2UgPSBtc2dQcmVmaXggKyAndGhlIGFyZ3VtZW50IHRvIGxlYXN0IG11c3QgYmUgYSBkYXRlJztcbiAgICB9IGVsc2UgaWYgKG5UeXBlICE9PSAnbnVtYmVyJyAmJiAoZG9MZW5ndGggfHwgb2JqVHlwZSA9PT0gJ251bWJlcicpKSB7XG4gICAgICBlcnJvck1lc3NhZ2UgPSBtc2dQcmVmaXggKyAndGhlIGFyZ3VtZW50IHRvIGxlYXN0IG11c3QgYmUgYSBudW1iZXInO1xuICAgIH0gZWxzZSBpZiAoIWRvTGVuZ3RoICYmIChvYmpUeXBlICE9PSAnZGF0ZScgJiYgb2JqVHlwZSAhPT0gJ251bWJlcicpKSB7XG4gICAgICB2YXIgcHJpbnRPYmogPSAob2JqVHlwZSA9PT0gJ3N0cmluZycpID8gXCInXCIgKyBvYmogKyBcIidcIiA6IG9iajtcbiAgICAgIGVycm9yTWVzc2FnZSA9IG1zZ1ByZWZpeCArICdleHBlY3RlZCAnICsgcHJpbnRPYmogKyAnIHRvIGJlIGEgbnVtYmVyIG9yIGEgZGF0ZSc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNob3VsZFRocm93ID0gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKHNob3VsZFRocm93KSB7XG4gICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZXJyb3JNZXNzYWdlLCB1bmRlZmluZWQsIHNzZmkpO1xuICAgIH1cblxuICAgIGlmIChkb0xlbmd0aCkge1xuICAgICAgdmFyIGRlc2NyaXB0b3IgPSAnbGVuZ3RoJ1xuICAgICAgICAsIGl0ZW1zQ291bnQ7XG4gICAgICBpZiAob2JqVHlwZSA9PT0gJ21hcCcgfHwgb2JqVHlwZSA9PT0gJ3NldCcpIHtcbiAgICAgICAgZGVzY3JpcHRvciA9ICdzaXplJztcbiAgICAgICAgaXRlbXNDb3VudCA9IG9iai5zaXplO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaXRlbXNDb3VudCA9IG9iai5sZW5ndGg7XG4gICAgICB9XG4gICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICBpdGVtc0NvdW50ID49IG5cbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBoYXZlIGEgJyArIGRlc2NyaXB0b3IgKyAnIGF0IGxlYXN0ICN7ZXhwfSBidXQgZ290ICN7YWN0fSdcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBoYXZlIGEgJyArIGRlc2NyaXB0b3IgKyAnIGJlbG93ICN7ZXhwfSdcbiAgICAgICAgLCBuXG4gICAgICAgICwgaXRlbXNDb3VudFxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgb2JqID49IG5cbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBhdCBsZWFzdCAje2V4cH0nXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgYmVsb3cgI3tleHB9J1xuICAgICAgICAsIG5cbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnbGVhc3QnLCBhc3NlcnRMZWFzdCk7XG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2d0ZScsIGFzc2VydExlYXN0KTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnZ3JlYXRlclRoYW5PckVxdWFsJywgYXNzZXJ0TGVhc3QpO1xuXG4gIC8qKlxuICAgKiAjIyMgLmJlbG93KG5bLCBtc2ddKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBhIG51bWJlciBvciBhIGRhdGUgbGVzcyB0aGFuIHRoZSBnaXZlbiBudW1iZXIgb3IgZGF0ZSBgbmAgcmVzcGVjdGl2ZWx5LlxuICAgKiBIb3dldmVyLCBpdCdzIG9mdGVuIGJlc3QgdG8gYXNzZXJ0IHRoYXQgdGhlIHRhcmdldCBpcyBlcXVhbCB0byBpdHMgZXhwZWN0ZWRcbiAgICogdmFsdWUuXG4gICAqXG4gICAqICAgICBleHBlY3QoMSkudG8uZXF1YWwoMSk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoMSkudG8uYmUuYmVsb3coMik7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBBZGQgYC5sZW5ndGhPZmAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gYXNzZXJ0IHRoYXQgdGhlIHRhcmdldCdzIGBsZW5ndGhgXG4gICAqIG9yIGBzaXplYCBpcyBsZXNzIHRoYW4gdGhlIGdpdmVuIG51bWJlciBgbmAuXG4gICAqXG4gICAqICAgICBleHBlY3QoJ2ZvbycpLnRvLmhhdmUubGVuZ3RoT2YoMyk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoJ2ZvbycpLnRvLmhhdmUubGVuZ3RoT2YuYmVsb3coNCk7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiAgICAgZXhwZWN0KFsxLCAyLCAzXSkudG8uaGF2ZS5sZW5ndGgoMyk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoWzEsIDIsIDNdKS50by5oYXZlLmxlbmd0aE9mLmJlbG93KDQpOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogQWRkIGAubm90YCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byBuZWdhdGUgYC5iZWxvd2AuXG4gICAqXG4gICAqICAgICBleHBlY3QoMikudG8uZXF1YWwoMik7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoMikudG8ubm90LmJlLmJlbG93KDEpOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogYC5iZWxvd2AgYWNjZXB0cyBhbiBvcHRpb25hbCBgbXNnYCBhcmd1bWVudCB3aGljaCBpcyBhIGN1c3RvbSBlcnJvciBtZXNzYWdlXG4gICAqIHRvIHNob3cgd2hlbiB0aGUgYXNzZXJ0aW9uIGZhaWxzLiBUaGUgbWVzc2FnZSBjYW4gYWxzbyBiZSBnaXZlbiBhcyB0aGVcbiAgICogc2Vjb25kIGFyZ3VtZW50IHRvIGBleHBlY3RgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KDIpLnRvLmJlLmJlbG93KDEsICdub29vIHdoeSBmYWlsPz8nKTtcbiAgICogICAgIGV4cGVjdCgyLCAnbm9vbyB3aHkgZmFpbD8/JykudG8uYmUuYmVsb3coMSk7XG4gICAqXG4gICAqIFRoZSBhbGlhc2VzIGAubHRgIGFuZCBgLmxlc3NUaGFuYCBjYW4gYmUgdXNlZCBpbnRlcmNoYW5nZWFibHkgd2l0aFxuICAgKiBgLmJlbG93YC5cbiAgICpcbiAgICogQG5hbWUgYmVsb3dcbiAgICogQGFsaWFzIGx0XG4gICAqIEBhbGlhcyBsZXNzVGhhblxuICAgKiBAcGFyYW0ge051bWJlcn0gblxuICAgKiBAcGFyYW0ge1N0cmluZ30gbXNnIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gYXNzZXJ0QmVsb3cgKG4sIG1zZykge1xuICAgIGlmIChtc2cpIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCBkb0xlbmd0aCA9IGZsYWcodGhpcywgJ2RvTGVuZ3RoJylcbiAgICAgICwgZmxhZ01zZyA9IGZsYWcodGhpcywgJ21lc3NhZ2UnKVxuICAgICAgLCBtc2dQcmVmaXggPSAoKGZsYWdNc2cpID8gZmxhZ01zZyArICc6ICcgOiAnJylcbiAgICAgICwgc3NmaSA9IGZsYWcodGhpcywgJ3NzZmknKVxuICAgICAgLCBvYmpUeXBlID0gXy50eXBlKG9iaikudG9Mb3dlckNhc2UoKVxuICAgICAgLCBuVHlwZSA9IF8udHlwZShuKS50b0xvd2VyQ2FzZSgpXG4gICAgICAsIGVycm9yTWVzc2FnZVxuICAgICAgLCBzaG91bGRUaHJvdyA9IHRydWU7XG5cbiAgICBpZiAoZG9MZW5ndGggJiYgb2JqVHlwZSAhPT0gJ21hcCcgJiYgb2JqVHlwZSAhPT0gJ3NldCcpIHtcbiAgICAgIG5ldyBBc3NlcnRpb24ob2JqLCBmbGFnTXNnLCBzc2ZpLCB0cnVlKS50by5oYXZlLnByb3BlcnR5KCdsZW5ndGgnKTtcbiAgICB9XG5cbiAgICBpZiAoIWRvTGVuZ3RoICYmIChvYmpUeXBlID09PSAnZGF0ZScgJiYgblR5cGUgIT09ICdkYXRlJykpIHtcbiAgICAgIGVycm9yTWVzc2FnZSA9IG1zZ1ByZWZpeCArICd0aGUgYXJndW1lbnQgdG8gYmVsb3cgbXVzdCBiZSBhIGRhdGUnO1xuICAgIH0gZWxzZSBpZiAoblR5cGUgIT09ICdudW1iZXInICYmIChkb0xlbmd0aCB8fCBvYmpUeXBlID09PSAnbnVtYmVyJykpIHtcbiAgICAgIGVycm9yTWVzc2FnZSA9IG1zZ1ByZWZpeCArICd0aGUgYXJndW1lbnQgdG8gYmVsb3cgbXVzdCBiZSBhIG51bWJlcic7XG4gICAgfSBlbHNlIGlmICghZG9MZW5ndGggJiYgKG9ialR5cGUgIT09ICdkYXRlJyAmJiBvYmpUeXBlICE9PSAnbnVtYmVyJykpIHtcbiAgICAgIHZhciBwcmludE9iaiA9IChvYmpUeXBlID09PSAnc3RyaW5nJykgPyBcIidcIiArIG9iaiArIFwiJ1wiIDogb2JqO1xuICAgICAgZXJyb3JNZXNzYWdlID0gbXNnUHJlZml4ICsgJ2V4cGVjdGVkICcgKyBwcmludE9iaiArICcgdG8gYmUgYSBudW1iZXIgb3IgYSBkYXRlJztcbiAgICB9IGVsc2Uge1xuICAgICAgc2hvdWxkVGhyb3cgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoc2hvdWxkVGhyb3cpIHtcbiAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihlcnJvck1lc3NhZ2UsIHVuZGVmaW5lZCwgc3NmaSk7XG4gICAgfVxuXG4gICAgaWYgKGRvTGVuZ3RoKSB7XG4gICAgICB2YXIgZGVzY3JpcHRvciA9ICdsZW5ndGgnXG4gICAgICAgICwgaXRlbXNDb3VudDtcbiAgICAgIGlmIChvYmpUeXBlID09PSAnbWFwJyB8fCBvYmpUeXBlID09PSAnc2V0Jykge1xuICAgICAgICBkZXNjcmlwdG9yID0gJ3NpemUnO1xuICAgICAgICBpdGVtc0NvdW50ID0gb2JqLnNpemU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpdGVtc0NvdW50ID0gb2JqLmxlbmd0aDtcbiAgICAgIH1cbiAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgIGl0ZW1zQ291bnQgPCBuXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gaGF2ZSBhICcgKyBkZXNjcmlwdG9yICsgJyBiZWxvdyAje2V4cH0gYnV0IGdvdCAje2FjdH0nXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGhhdmUgYSAnICsgZGVzY3JpcHRvciArICcgYmVsb3cgI3tleHB9J1xuICAgICAgICAsIG5cbiAgICAgICAgLCBpdGVtc0NvdW50XG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICBvYmogPCBuXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgYmVsb3cgI3tleHB9J1xuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIGF0IGxlYXN0ICN7ZXhwfSdcbiAgICAgICAgLCBuXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2JlbG93JywgYXNzZXJ0QmVsb3cpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdsdCcsIGFzc2VydEJlbG93KTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnbGVzc1RoYW4nLCBhc3NlcnRCZWxvdyk7XG5cbiAgLyoqXG4gICAqICMjIyAubW9zdChuWywgbXNnXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaXMgYSBudW1iZXIgb3IgYSBkYXRlIGxlc3MgdGhhbiBvciBlcXVhbCB0byB0aGUgZ2l2ZW4gbnVtYmVyXG4gICAqIG9yIGRhdGUgYG5gIHJlc3BlY3RpdmVseS4gSG93ZXZlciwgaXQncyBvZnRlbiBiZXN0IHRvIGFzc2VydCB0aGF0IHRoZSB0YXJnZXQgaXMgZXF1YWwgdG8gaXRzXG4gICAqIGV4cGVjdGVkIHZhbHVlLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KDEpLnRvLmVxdWFsKDEpOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KDEpLnRvLmJlLmF0Lm1vc3QoMik7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KDEpLnRvLmJlLmF0Lm1vc3QoMSk7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBBZGQgYC5sZW5ndGhPZmAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gYXNzZXJ0IHRoYXQgdGhlIHRhcmdldCdzIGBsZW5ndGhgXG4gICAqIG9yIGBzaXplYCBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gdGhlIGdpdmVuIG51bWJlciBgbmAuXG4gICAqXG4gICAqICAgICBleHBlY3QoJ2ZvbycpLnRvLmhhdmUubGVuZ3RoT2YoMyk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoJ2ZvbycpLnRvLmhhdmUubGVuZ3RoT2YuYXQubW9zdCg0KTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqICAgICBleHBlY3QoWzEsIDIsIDNdKS50by5oYXZlLmxlbmd0aE9mKDMpOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KFsxLCAyLCAzXSkudG8uaGF2ZS5sZW5ndGhPZi5hdC5tb3N0KDQpOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogQWRkIGAubm90YCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byBuZWdhdGUgYC5tb3N0YC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgyKS50by5lcXVhbCgyKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCgyKS50by5ub3QuYmUuYXQubW9zdCgxKTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqIGAubW9zdGAgYWNjZXB0cyBhbiBvcHRpb25hbCBgbXNnYCBhcmd1bWVudCB3aGljaCBpcyBhIGN1c3RvbSBlcnJvciBtZXNzYWdlXG4gICAqIHRvIHNob3cgd2hlbiB0aGUgYXNzZXJ0aW9uIGZhaWxzLiBUaGUgbWVzc2FnZSBjYW4gYWxzbyBiZSBnaXZlbiBhcyB0aGVcbiAgICogc2Vjb25kIGFyZ3VtZW50IHRvIGBleHBlY3RgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KDIpLnRvLmJlLmF0Lm1vc3QoMSwgJ25vb28gd2h5IGZhaWw/PycpO1xuICAgKiAgICAgZXhwZWN0KDIsICdub29vIHdoeSBmYWlsPz8nKS50by5iZS5hdC5tb3N0KDEpO1xuICAgKlxuICAgKiBUaGUgYWxpYXNlcyBgLmx0ZWAgYW5kIGAubGVzc1RoYW5PckVxdWFsYCBjYW4gYmUgdXNlZCBpbnRlcmNoYW5nZWFibHkgd2l0aFxuICAgKiBgLm1vc3RgLlxuICAgKlxuICAgKiBAbmFtZSBtb3N0XG4gICAqIEBhbGlhcyBsdGVcbiAgICogQGFsaWFzIGxlc3NUaGFuT3JFcXVhbFxuICAgKiBAcGFyYW0ge051bWJlcn0gblxuICAgKiBAcGFyYW0ge1N0cmluZ30gbXNnIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gYXNzZXJ0TW9zdCAobiwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAsIGRvTGVuZ3RoID0gZmxhZyh0aGlzLCAnZG9MZW5ndGgnKVxuICAgICAgLCBmbGFnTXNnID0gZmxhZyh0aGlzLCAnbWVzc2FnZScpXG4gICAgICAsIG1zZ1ByZWZpeCA9ICgoZmxhZ01zZykgPyBmbGFnTXNnICsgJzogJyA6ICcnKVxuICAgICAgLCBzc2ZpID0gZmxhZyh0aGlzLCAnc3NmaScpXG4gICAgICAsIG9ialR5cGUgPSBfLnR5cGUob2JqKS50b0xvd2VyQ2FzZSgpXG4gICAgICAsIG5UeXBlID0gXy50eXBlKG4pLnRvTG93ZXJDYXNlKClcbiAgICAgICwgZXJyb3JNZXNzYWdlXG4gICAgICAsIHNob3VsZFRocm93ID0gdHJ1ZTtcblxuICAgIGlmIChkb0xlbmd0aCAmJiBvYmpUeXBlICE9PSAnbWFwJyAmJiBvYmpUeXBlICE9PSAnc2V0Jykge1xuICAgICAgbmV3IEFzc2VydGlvbihvYmosIGZsYWdNc2csIHNzZmksIHRydWUpLnRvLmhhdmUucHJvcGVydHkoJ2xlbmd0aCcpO1xuICAgIH1cblxuICAgIGlmICghZG9MZW5ndGggJiYgKG9ialR5cGUgPT09ICdkYXRlJyAmJiBuVHlwZSAhPT0gJ2RhdGUnKSkge1xuICAgICAgZXJyb3JNZXNzYWdlID0gbXNnUHJlZml4ICsgJ3RoZSBhcmd1bWVudCB0byBtb3N0IG11c3QgYmUgYSBkYXRlJztcbiAgICB9IGVsc2UgaWYgKG5UeXBlICE9PSAnbnVtYmVyJyAmJiAoZG9MZW5ndGggfHwgb2JqVHlwZSA9PT0gJ251bWJlcicpKSB7XG4gICAgICBlcnJvck1lc3NhZ2UgPSBtc2dQcmVmaXggKyAndGhlIGFyZ3VtZW50IHRvIG1vc3QgbXVzdCBiZSBhIG51bWJlcic7XG4gICAgfSBlbHNlIGlmICghZG9MZW5ndGggJiYgKG9ialR5cGUgIT09ICdkYXRlJyAmJiBvYmpUeXBlICE9PSAnbnVtYmVyJykpIHtcbiAgICAgIHZhciBwcmludE9iaiA9IChvYmpUeXBlID09PSAnc3RyaW5nJykgPyBcIidcIiArIG9iaiArIFwiJ1wiIDogb2JqO1xuICAgICAgZXJyb3JNZXNzYWdlID0gbXNnUHJlZml4ICsgJ2V4cGVjdGVkICcgKyBwcmludE9iaiArICcgdG8gYmUgYSBudW1iZXIgb3IgYSBkYXRlJztcbiAgICB9IGVsc2Uge1xuICAgICAgc2hvdWxkVGhyb3cgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoc2hvdWxkVGhyb3cpIHtcbiAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihlcnJvck1lc3NhZ2UsIHVuZGVmaW5lZCwgc3NmaSk7XG4gICAgfVxuXG4gICAgaWYgKGRvTGVuZ3RoKSB7XG4gICAgICB2YXIgZGVzY3JpcHRvciA9ICdsZW5ndGgnXG4gICAgICAgICwgaXRlbXNDb3VudDtcbiAgICAgIGlmIChvYmpUeXBlID09PSAnbWFwJyB8fCBvYmpUeXBlID09PSAnc2V0Jykge1xuICAgICAgICBkZXNjcmlwdG9yID0gJ3NpemUnO1xuICAgICAgICBpdGVtc0NvdW50ID0gb2JqLnNpemU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpdGVtc0NvdW50ID0gb2JqLmxlbmd0aDtcbiAgICAgIH1cbiAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgIGl0ZW1zQ291bnQgPD0gblxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGhhdmUgYSAnICsgZGVzY3JpcHRvciArICcgYXQgbW9zdCAje2V4cH0gYnV0IGdvdCAje2FjdH0nXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gaGF2ZSBhICcgKyBkZXNjcmlwdG9yICsgJyBhYm92ZSAje2V4cH0nXG4gICAgICAgICwgblxuICAgICAgICAsIGl0ZW1zQ291bnRcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgIG9iaiA8PSBuXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgYXQgbW9zdCAje2V4cH0nXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgYWJvdmUgI3tleHB9J1xuICAgICAgICAsIG5cbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnbW9zdCcsIGFzc2VydE1vc3QpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdsdGUnLCBhc3NlcnRNb3N0KTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnbGVzc1RoYW5PckVxdWFsJywgYXNzZXJ0TW9zdCk7XG5cbiAgLyoqXG4gICAqICMjIyAud2l0aGluKHN0YXJ0LCBmaW5pc2hbLCBtc2ddKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBhIG51bWJlciBvciBhIGRhdGUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBnaXZlblxuICAgKiBudW1iZXIgb3IgZGF0ZSBgc3RhcnRgLCBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHRoZSBnaXZlbiBudW1iZXIgb3IgZGF0ZSBgZmluaXNoYCByZXNwZWN0aXZlbHkuXG4gICAqIEhvd2V2ZXIsIGl0J3Mgb2Z0ZW4gYmVzdCB0byBhc3NlcnQgdGhhdCB0aGUgdGFyZ2V0IGlzIGVxdWFsIHRvIGl0cyBleHBlY3RlZFxuICAgKiB2YWx1ZS5cbiAgICpcbiAgICogICAgIGV4cGVjdCgyKS50by5lcXVhbCgyKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCgyKS50by5iZS53aXRoaW4oMSwgMyk7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KDIpLnRvLmJlLndpdGhpbigyLCAzKTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoMikudG8uYmUud2l0aGluKDEsIDIpOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogQWRkIGAubGVuZ3RoT2ZgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIGFzc2VydCB0aGF0IHRoZSB0YXJnZXQncyBgbGVuZ3RoYFxuICAgKiBvciBgc2l6ZWAgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBnaXZlbiBudW1iZXIgYHN0YXJ0YCwgYW5kIGxlc3NcbiAgICogdGhhbiBvciBlcXVhbCB0byB0aGUgZ2l2ZW4gbnVtYmVyIGBmaW5pc2hgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KCdmb28nKS50by5oYXZlLmxlbmd0aE9mKDMpOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KCdmb28nKS50by5oYXZlLmxlbmd0aE9mLndpdGhpbigyLCA0KTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqICAgICBleHBlY3QoWzEsIDIsIDNdKS50by5oYXZlLmxlbmd0aE9mKDMpOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KFsxLCAyLCAzXSkudG8uaGF2ZS5sZW5ndGhPZi53aXRoaW4oMiwgNCk7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBBZGQgYC5ub3RgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIG5lZ2F0ZSBgLndpdGhpbmAuXG4gICAqXG4gICAqICAgICBleHBlY3QoMSkudG8uZXF1YWwoMSk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoMSkudG8ubm90LmJlLndpdGhpbigyLCA0KTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqIGAud2l0aGluYCBhY2NlcHRzIGFuIG9wdGlvbmFsIGBtc2dgIGFyZ3VtZW50IHdoaWNoIGlzIGEgY3VzdG9tIGVycm9yXG4gICAqIG1lc3NhZ2UgdG8gc2hvdyB3aGVuIHRoZSBhc3NlcnRpb24gZmFpbHMuIFRoZSBtZXNzYWdlIGNhbiBhbHNvIGJlIGdpdmVuIGFzXG4gICAqIHRoZSBzZWNvbmQgYXJndW1lbnQgdG8gYGV4cGVjdGAuXG4gICAqXG4gICAqICAgICBleHBlY3QoNCkudG8uYmUud2l0aGluKDEsIDMsICdub29vIHdoeSBmYWlsPz8nKTtcbiAgICogICAgIGV4cGVjdCg0LCAnbm9vbyB3aHkgZmFpbD8/JykudG8uYmUud2l0aGluKDEsIDMpO1xuICAgKlxuICAgKiBAbmFtZSB3aXRoaW5cbiAgICogQHBhcmFtIHtOdW1iZXJ9IHN0YXJ0IGxvd2VyIGJvdW5kIGluY2x1c2l2ZVxuICAgKiBAcGFyYW0ge051bWJlcn0gZmluaXNoIHVwcGVyIGJvdW5kIGluY2x1c2l2ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbXNnIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnd2l0aGluJywgZnVuY3Rpb24gKHN0YXJ0LCBmaW5pc2gsIG1zZykge1xuICAgIGlmIChtc2cpIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCBkb0xlbmd0aCA9IGZsYWcodGhpcywgJ2RvTGVuZ3RoJylcbiAgICAgICwgZmxhZ01zZyA9IGZsYWcodGhpcywgJ21lc3NhZ2UnKVxuICAgICAgLCBtc2dQcmVmaXggPSAoKGZsYWdNc2cpID8gZmxhZ01zZyArICc6ICcgOiAnJylcbiAgICAgICwgc3NmaSA9IGZsYWcodGhpcywgJ3NzZmknKVxuICAgICAgLCBvYmpUeXBlID0gXy50eXBlKG9iaikudG9Mb3dlckNhc2UoKVxuICAgICAgLCBzdGFydFR5cGUgPSBfLnR5cGUoc3RhcnQpLnRvTG93ZXJDYXNlKClcbiAgICAgICwgZmluaXNoVHlwZSA9IF8udHlwZShmaW5pc2gpLnRvTG93ZXJDYXNlKClcbiAgICAgICwgZXJyb3JNZXNzYWdlXG4gICAgICAsIHNob3VsZFRocm93ID0gdHJ1ZVxuICAgICAgLCByYW5nZSA9IChzdGFydFR5cGUgPT09ICdkYXRlJyAmJiBmaW5pc2hUeXBlID09PSAnZGF0ZScpXG4gICAgICAgICAgPyBzdGFydC50b0lTT1N0cmluZygpICsgJy4uJyArIGZpbmlzaC50b0lTT1N0cmluZygpXG4gICAgICAgICAgOiBzdGFydCArICcuLicgKyBmaW5pc2g7XG5cbiAgICBpZiAoZG9MZW5ndGggJiYgb2JqVHlwZSAhPT0gJ21hcCcgJiYgb2JqVHlwZSAhPT0gJ3NldCcpIHtcbiAgICAgIG5ldyBBc3NlcnRpb24ob2JqLCBmbGFnTXNnLCBzc2ZpLCB0cnVlKS50by5oYXZlLnByb3BlcnR5KCdsZW5ndGgnKTtcbiAgICB9XG5cbiAgICBpZiAoIWRvTGVuZ3RoICYmIChvYmpUeXBlID09PSAnZGF0ZScgJiYgKHN0YXJ0VHlwZSAhPT0gJ2RhdGUnIHx8IGZpbmlzaFR5cGUgIT09ICdkYXRlJykpKSB7XG4gICAgICBlcnJvck1lc3NhZ2UgPSBtc2dQcmVmaXggKyAndGhlIGFyZ3VtZW50cyB0byB3aXRoaW4gbXVzdCBiZSBkYXRlcyc7XG4gICAgfSBlbHNlIGlmICgoc3RhcnRUeXBlICE9PSAnbnVtYmVyJyB8fCBmaW5pc2hUeXBlICE9PSAnbnVtYmVyJykgJiYgKGRvTGVuZ3RoIHx8IG9ialR5cGUgPT09ICdudW1iZXInKSkge1xuICAgICAgZXJyb3JNZXNzYWdlID0gbXNnUHJlZml4ICsgJ3RoZSBhcmd1bWVudHMgdG8gd2l0aGluIG11c3QgYmUgbnVtYmVycyc7XG4gICAgfSBlbHNlIGlmICghZG9MZW5ndGggJiYgKG9ialR5cGUgIT09ICdkYXRlJyAmJiBvYmpUeXBlICE9PSAnbnVtYmVyJykpIHtcbiAgICAgIHZhciBwcmludE9iaiA9IChvYmpUeXBlID09PSAnc3RyaW5nJykgPyBcIidcIiArIG9iaiArIFwiJ1wiIDogb2JqO1xuICAgICAgZXJyb3JNZXNzYWdlID0gbXNnUHJlZml4ICsgJ2V4cGVjdGVkICcgKyBwcmludE9iaiArICcgdG8gYmUgYSBudW1iZXIgb3IgYSBkYXRlJztcbiAgICB9IGVsc2Uge1xuICAgICAgc2hvdWxkVGhyb3cgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoc2hvdWxkVGhyb3cpIHtcbiAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihlcnJvck1lc3NhZ2UsIHVuZGVmaW5lZCwgc3NmaSk7XG4gICAgfVxuXG4gICAgaWYgKGRvTGVuZ3RoKSB7XG4gICAgICB2YXIgZGVzY3JpcHRvciA9ICdsZW5ndGgnXG4gICAgICAgICwgaXRlbXNDb3VudDtcbiAgICAgIGlmIChvYmpUeXBlID09PSAnbWFwJyB8fCBvYmpUeXBlID09PSAnc2V0Jykge1xuICAgICAgICBkZXNjcmlwdG9yID0gJ3NpemUnO1xuICAgICAgICBpdGVtc0NvdW50ID0gb2JqLnNpemU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpdGVtc0NvdW50ID0gb2JqLmxlbmd0aDtcbiAgICAgIH1cbiAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgIGl0ZW1zQ291bnQgPj0gc3RhcnQgJiYgaXRlbXNDb3VudCA8PSBmaW5pc2hcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBoYXZlIGEgJyArIGRlc2NyaXB0b3IgKyAnIHdpdGhpbiAnICsgcmFuZ2VcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgaGF2ZSBhICcgKyBkZXNjcmlwdG9yICsgJyB3aXRoaW4gJyArIHJhbmdlXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICBvYmogPj0gc3RhcnQgJiYgb2JqIDw9IGZpbmlzaFxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIHdpdGhpbiAnICsgcmFuZ2VcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgYmUgd2l0aGluICcgKyByYW5nZVxuICAgICAgKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8qKlxuICAgKiAjIyMgLmluc3RhbmNlb2YoY29uc3RydWN0b3JbLCBtc2ddKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBhbiBpbnN0YW5jZSBvZiB0aGUgZ2l2ZW4gYGNvbnN0cnVjdG9yYC5cbiAgICpcbiAgICogICAgIGZ1bmN0aW9uIENhdCAoKSB7IH1cbiAgICpcbiAgICogICAgIGV4cGVjdChuZXcgQ2F0KCkpLnRvLmJlLmFuLmluc3RhbmNlb2YoQ2F0KTtcbiAgICogICAgIGV4cGVjdChbMSwgMl0pLnRvLmJlLmFuLmluc3RhbmNlb2YoQXJyYXkpO1xuICAgKlxuICAgKiBBZGQgYC5ub3RgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIG5lZ2F0ZSBgLmluc3RhbmNlb2ZgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KHthOiAxfSkudG8ubm90LmJlLmFuLmluc3RhbmNlb2YoQXJyYXkpO1xuICAgKlxuICAgKiBgLmluc3RhbmNlb2ZgIGFjY2VwdHMgYW4gb3B0aW9uYWwgYG1zZ2AgYXJndW1lbnQgd2hpY2ggaXMgYSBjdXN0b20gZXJyb3JcbiAgICogbWVzc2FnZSB0byBzaG93IHdoZW4gdGhlIGFzc2VydGlvbiBmYWlscy4gVGhlIG1lc3NhZ2UgY2FuIGFsc28gYmUgZ2l2ZW4gYXNcbiAgICogdGhlIHNlY29uZCBhcmd1bWVudCB0byBgZXhwZWN0YC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgxKS50by5iZS5hbi5pbnN0YW5jZW9mKEFycmF5LCAnbm9vbyB3aHkgZmFpbD8/Jyk7XG4gICAqICAgICBleHBlY3QoMSwgJ25vb28gd2h5IGZhaWw/PycpLnRvLmJlLmFuLmluc3RhbmNlb2YoQXJyYXkpO1xuICAgKlxuICAgKiBEdWUgdG8gbGltaXRhdGlvbnMgaW4gRVM1LCBgLmluc3RhbmNlb2ZgIG1heSBub3QgYWx3YXlzIHdvcmsgYXMgZXhwZWN0ZWRcbiAgICogd2hlbiB1c2luZyBhIHRyYW5zcGlsZXIgc3VjaCBhcyBCYWJlbCBvciBUeXBlU2NyaXB0LiBJbiBwYXJ0aWN1bGFyLCBpdCBtYXlcbiAgICogcHJvZHVjZSB1bmV4cGVjdGVkIHJlc3VsdHMgd2hlbiBzdWJjbGFzc2luZyBidWlsdC1pbiBvYmplY3Qgc3VjaCBhc1xuICAgKiBgQXJyYXlgLCBgRXJyb3JgLCBhbmQgYE1hcGAuIFNlZSB5b3VyIHRyYW5zcGlsZXIncyBkb2NzIGZvciBkZXRhaWxzOlxuICAgKlxuICAgKiAtIChbQmFiZWxdKGh0dHBzOi8vYmFiZWxqcy5pby9kb2NzL3VzYWdlL2NhdmVhdHMvI2NsYXNzZXMpKVxuICAgKiAtIChbVHlwZVNjcmlwdF0oaHR0cHM6Ly9naXRodWIuY29tL01pY3Jvc29mdC9UeXBlU2NyaXB0L3dpa2kvQnJlYWtpbmctQ2hhbmdlcyNleHRlbmRpbmctYnVpbHQtaW5zLWxpa2UtZXJyb3ItYXJyYXktYW5kLW1hcC1tYXktbm8tbG9uZ2VyLXdvcmspKVxuICAgKlxuICAgKiBUaGUgYWxpYXMgYC5pbnN0YW5jZU9mYCBjYW4gYmUgdXNlZCBpbnRlcmNoYW5nZWFibHkgd2l0aCBgLmluc3RhbmNlb2ZgLlxuICAgKlxuICAgKiBAbmFtZSBpbnN0YW5jZW9mXG4gICAqIEBwYXJhbSB7Q29uc3RydWN0b3J9IGNvbnN0cnVjdG9yXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtc2cgX29wdGlvbmFsX1xuICAgKiBAYWxpYXMgaW5zdGFuY2VPZlxuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBhc3NlcnRJbnN0YW5jZU9mIChjb25zdHJ1Y3RvciwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG5cbiAgICB2YXIgdGFyZ2V0ID0gZmxhZyh0aGlzLCAnb2JqZWN0JylcbiAgICB2YXIgc3NmaSA9IGZsYWcodGhpcywgJ3NzZmknKTtcbiAgICB2YXIgZmxhZ01zZyA9IGZsYWcodGhpcywgJ21lc3NhZ2UnKTtcblxuICAgIHRyeSB7XG4gICAgICB2YXIgaXNJbnN0YW5jZU9mID0gdGFyZ2V0IGluc3RhbmNlb2YgY29uc3RydWN0b3I7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBpZiAoZXJyIGluc3RhbmNlb2YgVHlwZUVycm9yKSB7XG4gICAgICAgIGZsYWdNc2cgPSBmbGFnTXNnID8gZmxhZ01zZyArICc6ICcgOiAnJztcbiAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKFxuICAgICAgICAgIGZsYWdNc2cgKyAnVGhlIGluc3RhbmNlb2YgYXNzZXJ0aW9uIG5lZWRzIGEgY29uc3RydWN0b3IgYnV0ICdcbiAgICAgICAgICAgICsgXy50eXBlKGNvbnN0cnVjdG9yKSArICcgd2FzIGdpdmVuLicsXG4gICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgIHNzZmlcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHRocm93IGVycjtcbiAgICB9XG5cbiAgICB2YXIgbmFtZSA9IF8uZ2V0TmFtZShjb25zdHJ1Y3Rvcik7XG4gICAgaWYgKG5hbWUgPT09IG51bGwpIHtcbiAgICAgIG5hbWUgPSAnYW4gdW5uYW1lZCBjb25zdHJ1Y3Rvcic7XG4gICAgfVxuXG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICAgIGlzSW5zdGFuY2VPZlxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBhbiBpbnN0YW5jZSBvZiAnICsgbmFtZVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgYmUgYW4gaW5zdGFuY2Ugb2YgJyArIG5hbWVcbiAgICApO1xuICB9O1xuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2luc3RhbmNlb2YnLCBhc3NlcnRJbnN0YW5jZU9mKTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnaW5zdGFuY2VPZicsIGFzc2VydEluc3RhbmNlT2YpO1xuXG4gIC8qKlxuICAgKiAjIyMgLnByb3BlcnR5KG5hbWVbLCB2YWxbLCBtc2ddXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaGFzIGEgcHJvcGVydHkgd2l0aCB0aGUgZ2l2ZW4ga2V5IGBuYW1lYC5cbiAgICpcbiAgICogICAgIGV4cGVjdCh7YTogMX0pLnRvLmhhdmUucHJvcGVydHkoJ2EnKTtcbiAgICpcbiAgICogV2hlbiBgdmFsYCBpcyBwcm92aWRlZCwgYC5wcm9wZXJ0eWAgYWxzbyBhc3NlcnRzIHRoYXQgdGhlIHByb3BlcnR5J3MgdmFsdWVcbiAgICogaXMgZXF1YWwgdG8gdGhlIGdpdmVuIGB2YWxgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KHthOiAxfSkudG8uaGF2ZS5wcm9wZXJ0eSgnYScsIDEpO1xuICAgKlxuICAgKiBCeSBkZWZhdWx0LCBzdHJpY3QgKGA9PT1gKSBlcXVhbGl0eSBpcyB1c2VkLiBBZGQgYC5kZWVwYCBlYXJsaWVyIGluIHRoZVxuICAgKiBjaGFpbiB0byB1c2UgZGVlcCBlcXVhbGl0eSBpbnN0ZWFkLiBTZWUgdGhlIGBkZWVwLWVxbGAgcHJvamVjdCBwYWdlIGZvclxuICAgKiBpbmZvIG9uIHRoZSBkZWVwIGVxdWFsaXR5IGFsZ29yaXRobTogaHR0cHM6Ly9naXRodWIuY29tL2NoYWlqcy9kZWVwLWVxbC5cbiAgICpcbiAgICogICAgIC8vIFRhcmdldCBvYmplY3QgZGVlcGx5IChidXQgbm90IHN0cmljdGx5KSBoYXMgcHJvcGVydHkgYHg6IHthOiAxfWBcbiAgICogICAgIGV4cGVjdCh7eDoge2E6IDF9fSkudG8uaGF2ZS5kZWVwLnByb3BlcnR5KCd4Jywge2E6IDF9KTtcbiAgICogICAgIGV4cGVjdCh7eDoge2E6IDF9fSkudG8ubm90LmhhdmUucHJvcGVydHkoJ3gnLCB7YTogMX0pO1xuICAgKlxuICAgKiBUaGUgdGFyZ2V0J3MgZW51bWVyYWJsZSBhbmQgbm9uLWVudW1lcmFibGUgcHJvcGVydGllcyBhcmUgYWx3YXlzIGluY2x1ZGVkXG4gICAqIGluIHRoZSBzZWFyY2guIEJ5IGRlZmF1bHQsIGJvdGggb3duIGFuZCBpbmhlcml0ZWQgcHJvcGVydGllcyBhcmUgaW5jbHVkZWQuXG4gICAqIEFkZCBgLm93bmAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gZXhjbHVkZSBpbmhlcml0ZWQgcHJvcGVydGllcyBmcm9tIHRoZVxuICAgKiBzZWFyY2guXG4gICAqXG4gICAqICAgICBPYmplY3QucHJvdG90eXBlLmIgPSAyO1xuICAgKlxuICAgKiAgICAgZXhwZWN0KHthOiAxfSkudG8uaGF2ZS5vd24ucHJvcGVydHkoJ2EnKTtcbiAgICogICAgIGV4cGVjdCh7YTogMX0pLnRvLmhhdmUub3duLnByb3BlcnR5KCdhJywgMSk7XG4gICAqICAgICBleHBlY3Qoe2E6IDF9KS50by5oYXZlLnByb3BlcnR5KCdiJyk7XG4gICAqICAgICBleHBlY3Qoe2E6IDF9KS50by5ub3QuaGF2ZS5vd24ucHJvcGVydHkoJ2InKTtcbiAgICpcbiAgICogYC5kZWVwYCBhbmQgYC5vd25gIGNhbiBiZSBjb21iaW5lZC5cbiAgICpcbiAgICogICAgIGV4cGVjdCh7eDoge2E6IDF9fSkudG8uaGF2ZS5kZWVwLm93bi5wcm9wZXJ0eSgneCcsIHthOiAxfSk7XG4gICAqXG4gICAqIEFkZCBgLm5lc3RlZGAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gZW5hYmxlIGRvdC0gYW5kIGJyYWNrZXQtbm90YXRpb24gd2hlblxuICAgKiByZWZlcmVuY2luZyBuZXN0ZWQgcHJvcGVydGllcy5cbiAgICpcbiAgICogICAgIGV4cGVjdCh7YToge2I6IFsneCcsICd5J119fSkudG8uaGF2ZS5uZXN0ZWQucHJvcGVydHkoJ2EuYlsxXScpO1xuICAgKiAgICAgZXhwZWN0KHthOiB7YjogWyd4JywgJ3knXX19KS50by5oYXZlLm5lc3RlZC5wcm9wZXJ0eSgnYS5iWzFdJywgJ3knKTtcbiAgICpcbiAgICogSWYgYC5gIG9yIGBbXWAgYXJlIHBhcnQgb2YgYW4gYWN0dWFsIHByb3BlcnR5IG5hbWUsIHRoZXkgY2FuIGJlIGVzY2FwZWQgYnlcbiAgICogYWRkaW5nIHR3byBiYWNrc2xhc2hlcyBiZWZvcmUgdGhlbS5cbiAgICpcbiAgICogICAgIGV4cGVjdCh7Jy5hJzogeydbYl0nOiAneCd9fSkudG8uaGF2ZS5uZXN0ZWQucHJvcGVydHkoJ1xcXFwuYS5cXFxcW2JcXFxcXScpO1xuICAgKlxuICAgKiBgLmRlZXBgIGFuZCBgLm5lc3RlZGAgY2FuIGJlIGNvbWJpbmVkLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KHthOiB7YjogW3tjOiAzfV19fSlcbiAgICogICAgICAgLnRvLmhhdmUuZGVlcC5uZXN0ZWQucHJvcGVydHkoJ2EuYlswXScsIHtjOiAzfSk7XG4gICAqXG4gICAqIGAub3duYCBhbmQgYC5uZXN0ZWRgIGNhbm5vdCBiZSBjb21iaW5lZC5cbiAgICpcbiAgICogQWRkIGAubm90YCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byBuZWdhdGUgYC5wcm9wZXJ0eWAuXG4gICAqXG4gICAqICAgICBleHBlY3Qoe2E6IDF9KS50by5ub3QuaGF2ZS5wcm9wZXJ0eSgnYicpO1xuICAgKlxuICAgKiBIb3dldmVyLCBpdCdzIGRhbmdlcm91cyB0byBuZWdhdGUgYC5wcm9wZXJ0eWAgd2hlbiBwcm92aWRpbmcgYHZhbGAuIFRoZVxuICAgKiBwcm9ibGVtIGlzIHRoYXQgaXQgY3JlYXRlcyB1bmNlcnRhaW4gZXhwZWN0YXRpb25zIGJ5IGFzc2VydGluZyB0aGF0IHRoZVxuICAgKiB0YXJnZXQgZWl0aGVyIGRvZXNuJ3QgaGF2ZSBhIHByb3BlcnR5IHdpdGggdGhlIGdpdmVuIGtleSBgbmFtZWAsIG9yIHRoYXQgaXRcbiAgICogZG9lcyBoYXZlIGEgcHJvcGVydHkgd2l0aCB0aGUgZ2l2ZW4ga2V5IGBuYW1lYCBidXQgaXRzIHZhbHVlIGlzbid0IGVxdWFsIHRvXG4gICAqIHRoZSBnaXZlbiBgdmFsYC4gSXQncyBvZnRlbiBiZXN0IHRvIGlkZW50aWZ5IHRoZSBleGFjdCBvdXRwdXQgdGhhdCdzXG4gICAqIGV4cGVjdGVkLCBhbmQgdGhlbiB3cml0ZSBhbiBhc3NlcnRpb24gdGhhdCBvbmx5IGFjY2VwdHMgdGhhdCBleGFjdCBvdXRwdXQuXG4gICAqXG4gICAqIFdoZW4gdGhlIHRhcmdldCBpc24ndCBleHBlY3RlZCB0byBoYXZlIGEgcHJvcGVydHkgd2l0aCB0aGUgZ2l2ZW4ga2V5XG4gICAqIGBuYW1lYCwgaXQncyBvZnRlbiBiZXN0IHRvIGFzc2VydCBleGFjdGx5IHRoYXQuXG4gICAqXG4gICAqICAgICBleHBlY3Qoe2I6IDJ9KS50by5ub3QuaGF2ZS5wcm9wZXJ0eSgnYScpOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KHtiOiAyfSkudG8ubm90LmhhdmUucHJvcGVydHkoJ2EnLCAxKTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqIFdoZW4gdGhlIHRhcmdldCBpcyBleHBlY3RlZCB0byBoYXZlIGEgcHJvcGVydHkgd2l0aCB0aGUgZ2l2ZW4ga2V5IGBuYW1lYCxcbiAgICogaXQncyBvZnRlbiBiZXN0IHRvIGFzc2VydCB0aGF0IHRoZSBwcm9wZXJ0eSBoYXMgaXRzIGV4cGVjdGVkIHZhbHVlLCByYXRoZXJcbiAgICogdGhhbiBhc3NlcnRpbmcgdGhhdCBpdCBkb2Vzbid0IGhhdmUgb25lIG9mIG1hbnkgdW5leHBlY3RlZCB2YWx1ZXMuXG4gICAqXG4gICAqICAgICBleHBlY3Qoe2E6IDN9KS50by5oYXZlLnByb3BlcnR5KCdhJywgMyk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3Qoe2E6IDN9KS50by5ub3QuaGF2ZS5wcm9wZXJ0eSgnYScsIDEpOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogYC5wcm9wZXJ0eWAgY2hhbmdlcyB0aGUgdGFyZ2V0IG9mIGFueSBhc3NlcnRpb25zIHRoYXQgZm9sbG93IGluIHRoZSBjaGFpblxuICAgKiB0byBiZSB0aGUgdmFsdWUgb2YgdGhlIHByb3BlcnR5IGZyb20gdGhlIG9yaWdpbmFsIHRhcmdldCBvYmplY3QuXG4gICAqXG4gICAqICAgICBleHBlY3Qoe2E6IDF9KS50by5oYXZlLnByb3BlcnR5KCdhJykudGhhdC5pcy5hKCdudW1iZXInKTtcbiAgICpcbiAgICogYC5wcm9wZXJ0eWAgYWNjZXB0cyBhbiBvcHRpb25hbCBgbXNnYCBhcmd1bWVudCB3aGljaCBpcyBhIGN1c3RvbSBlcnJvclxuICAgKiBtZXNzYWdlIHRvIHNob3cgd2hlbiB0aGUgYXNzZXJ0aW9uIGZhaWxzLiBUaGUgbWVzc2FnZSBjYW4gYWxzbyBiZSBnaXZlbiBhc1xuICAgKiB0aGUgc2Vjb25kIGFyZ3VtZW50IHRvIGBleHBlY3RgLiBXaGVuIG5vdCBwcm92aWRpbmcgYHZhbGAsIG9ubHkgdXNlIHRoZVxuICAgKiBzZWNvbmQgZm9ybS5cbiAgICpcbiAgICogICAgIC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3Qoe2E6IDF9KS50by5oYXZlLnByb3BlcnR5KCdhJywgMiwgJ25vb28gd2h5IGZhaWw/PycpO1xuICAgKiAgICAgZXhwZWN0KHthOiAxfSwgJ25vb28gd2h5IGZhaWw/PycpLnRvLmhhdmUucHJvcGVydHkoJ2EnLCAyKTtcbiAgICogICAgIGV4cGVjdCh7YTogMX0sICdub29vIHdoeSBmYWlsPz8nKS50by5oYXZlLnByb3BlcnR5KCdiJyk7XG4gICAqXG4gICAqICAgICAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCh7YTogMX0pLnRvLmhhdmUucHJvcGVydHkoJ2InLCB1bmRlZmluZWQsICdub29vIHdoeSBmYWlsPz8nKTtcbiAgICpcbiAgICogVGhlIGFib3ZlIGFzc2VydGlvbiBpc24ndCB0aGUgc2FtZSB0aGluZyBhcyBub3QgcHJvdmlkaW5nIGB2YWxgLiBJbnN0ZWFkLFxuICAgKiBpdCdzIGFzc2VydGluZyB0aGF0IHRoZSB0YXJnZXQgb2JqZWN0IGhhcyBhIGBiYCBwcm9wZXJ0eSB0aGF0J3MgZXF1YWwgdG9cbiAgICogYHVuZGVmaW5lZGAuXG4gICAqXG4gICAqIFRoZSBhc3NlcnRpb25zIGAub3duUHJvcGVydHlgIGFuZCBgLmhhdmVPd25Qcm9wZXJ0eWAgY2FuIGJlIHVzZWRcbiAgICogaW50ZXJjaGFuZ2VhYmx5IHdpdGggYC5vd24ucHJvcGVydHlgLlxuICAgKlxuICAgKiBAbmFtZSBwcm9wZXJ0eVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxuICAgKiBAcGFyYW0ge01peGVkfSB2YWwgKG9wdGlvbmFsKVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbXNnIF9vcHRpb25hbF9cbiAgICogQHJldHVybnMgdmFsdWUgb2YgcHJvcGVydHkgZm9yIGNoYWluaW5nXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGFzc2VydFByb3BlcnR5IChuYW1lLCB2YWwsIG1zZykge1xuICAgIGlmIChtc2cpIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuXG4gICAgdmFyIGlzTmVzdGVkID0gZmxhZyh0aGlzLCAnbmVzdGVkJylcbiAgICAgICwgaXNPd24gPSBmbGFnKHRoaXMsICdvd24nKVxuICAgICAgLCBmbGFnTXNnID0gZmxhZyh0aGlzLCAnbWVzc2FnZScpXG4gICAgICAsIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAsIHNzZmkgPSBmbGFnKHRoaXMsICdzc2ZpJylcbiAgICAgICwgbmFtZVR5cGUgPSB0eXBlb2YgbmFtZTtcblxuICAgIGZsYWdNc2cgPSBmbGFnTXNnID8gZmxhZ01zZyArICc6ICcgOiAnJztcblxuICAgIGlmIChpc05lc3RlZCkge1xuICAgICAgaWYgKG5hbWVUeXBlICE9PSAnc3RyaW5nJykge1xuICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoXG4gICAgICAgICAgZmxhZ01zZyArICd0aGUgYXJndW1lbnQgdG8gcHJvcGVydHkgbXVzdCBiZSBhIHN0cmluZyB3aGVuIHVzaW5nIG5lc3RlZCBzeW50YXgnLFxuICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICBzc2ZpXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChuYW1lVHlwZSAhPT0gJ3N0cmluZycgJiYgbmFtZVR5cGUgIT09ICdudW1iZXInICYmIG5hbWVUeXBlICE9PSAnc3ltYm9sJykge1xuICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoXG4gICAgICAgICAgZmxhZ01zZyArICd0aGUgYXJndW1lbnQgdG8gcHJvcGVydHkgbXVzdCBiZSBhIHN0cmluZywgbnVtYmVyLCBvciBzeW1ib2wnLFxuICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICBzc2ZpXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGlzTmVzdGVkICYmIGlzT3duKSB7XG4gICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoXG4gICAgICAgIGZsYWdNc2cgKyAnVGhlIFwibmVzdGVkXCIgYW5kIFwib3duXCIgZmxhZ3MgY2Fubm90IGJlIGNvbWJpbmVkLicsXG4gICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgc3NmaVxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAob2JqID09PSBudWxsIHx8IG9iaiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoXG4gICAgICAgIGZsYWdNc2cgKyAnVGFyZ2V0IGNhbm5vdCBiZSBudWxsIG9yIHVuZGVmaW5lZC4nLFxuICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgIHNzZmlcbiAgICAgICk7XG4gICAgfVxuXG4gICAgdmFyIGlzRGVlcCA9IGZsYWcodGhpcywgJ2RlZXAnKVxuICAgICAgLCBuZWdhdGUgPSBmbGFnKHRoaXMsICduZWdhdGUnKVxuICAgICAgLCBwYXRoSW5mbyA9IGlzTmVzdGVkID8gXy5nZXRQYXRoSW5mbyhvYmosIG5hbWUpIDogbnVsbFxuICAgICAgLCB2YWx1ZSA9IGlzTmVzdGVkID8gcGF0aEluZm8udmFsdWUgOiBvYmpbbmFtZV07XG5cbiAgICB2YXIgZGVzY3JpcHRvciA9ICcnO1xuICAgIGlmIChpc0RlZXApIGRlc2NyaXB0b3IgKz0gJ2RlZXAgJztcbiAgICBpZiAoaXNPd24pIGRlc2NyaXB0b3IgKz0gJ293biAnO1xuICAgIGlmIChpc05lc3RlZCkgZGVzY3JpcHRvciArPSAnbmVzdGVkICc7XG4gICAgZGVzY3JpcHRvciArPSAncHJvcGVydHkgJztcblxuICAgIHZhciBoYXNQcm9wZXJ0eTtcbiAgICBpZiAoaXNPd24pIGhhc1Byb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgbmFtZSk7XG4gICAgZWxzZSBpZiAoaXNOZXN0ZWQpIGhhc1Byb3BlcnR5ID0gcGF0aEluZm8uZXhpc3RzO1xuICAgIGVsc2UgaGFzUHJvcGVydHkgPSBfLmhhc1Byb3BlcnR5KG9iaiwgbmFtZSk7XG5cbiAgICAvLyBXaGVuIHBlcmZvcm1pbmcgYSBuZWdhdGVkIGFzc2VydGlvbiBmb3IgYm90aCBuYW1lIGFuZCB2YWwsIG1lcmVseSBoYXZpbmdcbiAgICAvLyBhIHByb3BlcnR5IHdpdGggdGhlIGdpdmVuIG5hbWUgaXNuJ3QgZW5vdWdoIHRvIGNhdXNlIHRoZSBhc3NlcnRpb24gdG9cbiAgICAvLyBmYWlsLiBJdCBtdXN0IGJvdGggaGF2ZSBhIHByb3BlcnR5IHdpdGggdGhlIGdpdmVuIG5hbWUsIGFuZCB0aGUgdmFsdWUgb2ZcbiAgICAvLyB0aGF0IHByb3BlcnR5IG11c3QgZXF1YWwgdGhlIGdpdmVuIHZhbC4gVGhlcmVmb3JlLCBza2lwIHRoaXMgYXNzZXJ0aW9uIGluXG4gICAgLy8gZmF2b3Igb2YgdGhlIG5leHQuXG4gICAgaWYgKCFuZWdhdGUgfHwgYXJndW1lbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgaGFzUHJvcGVydHlcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBoYXZlICcgKyBkZXNjcmlwdG9yICsgXy5pbnNwZWN0KG5hbWUpXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGhhdmUgJyArIGRlc2NyaXB0b3IgKyBfLmluc3BlY3QobmFtZSkpO1xuICAgIH1cblxuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgaGFzUHJvcGVydHkgJiYgKGlzRGVlcCA/IF8uZXFsKHZhbCwgdmFsdWUpIDogdmFsID09PSB2YWx1ZSlcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBoYXZlICcgKyBkZXNjcmlwdG9yICsgXy5pbnNwZWN0KG5hbWUpICsgJyBvZiAje2V4cH0sIGJ1dCBnb3QgI3thY3R9J1xuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBoYXZlICcgKyBkZXNjcmlwdG9yICsgXy5pbnNwZWN0KG5hbWUpICsgJyBvZiAje2FjdH0nXG4gICAgICAgICwgdmFsXG4gICAgICAgICwgdmFsdWVcbiAgICAgICk7XG4gICAgfVxuXG4gICAgZmxhZyh0aGlzLCAnb2JqZWN0JywgdmFsdWUpO1xuICB9XG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgncHJvcGVydHknLCBhc3NlcnRQcm9wZXJ0eSk7XG5cbiAgZnVuY3Rpb24gYXNzZXJ0T3duUHJvcGVydHkgKG5hbWUsIHZhbHVlLCBtc2cpIHtcbiAgICBmbGFnKHRoaXMsICdvd24nLCB0cnVlKTtcbiAgICBhc3NlcnRQcm9wZXJ0eS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnb3duUHJvcGVydHknLCBhc3NlcnRPd25Qcm9wZXJ0eSk7XG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2hhdmVPd25Qcm9wZXJ0eScsIGFzc2VydE93blByb3BlcnR5KTtcblxuICAvKipcbiAgICogIyMjIC5vd25Qcm9wZXJ0eURlc2NyaXB0b3IobmFtZVssIGRlc2NyaXB0b3JbLCBtc2ddXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaGFzIGl0cyBvd24gcHJvcGVydHkgZGVzY3JpcHRvciB3aXRoIHRoZSBnaXZlbiBrZXlcbiAgICogYG5hbWVgLiBFbnVtZXJhYmxlIGFuZCBub24tZW51bWVyYWJsZSBwcm9wZXJ0aWVzIGFyZSBpbmNsdWRlZCBpbiB0aGVcbiAgICogc2VhcmNoLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KHthOiAxfSkudG8uaGF2ZS5vd25Qcm9wZXJ0eURlc2NyaXB0b3IoJ2EnKTtcbiAgICpcbiAgICogV2hlbiBgZGVzY3JpcHRvcmAgaXMgcHJvdmlkZWQsIGAub3duUHJvcGVydHlEZXNjcmlwdG9yYCBhbHNvIGFzc2VydHMgdGhhdFxuICAgKiB0aGUgcHJvcGVydHkncyBkZXNjcmlwdG9yIGlzIGRlZXBseSBlcXVhbCB0byB0aGUgZ2l2ZW4gYGRlc2NyaXB0b3JgLiBTZWVcbiAgICogdGhlIGBkZWVwLWVxbGAgcHJvamVjdCBwYWdlIGZvciBpbmZvIG9uIHRoZSBkZWVwIGVxdWFsaXR5IGFsZ29yaXRobTpcbiAgICogaHR0cHM6Ly9naXRodWIuY29tL2NoYWlqcy9kZWVwLWVxbC5cbiAgICpcbiAgICogICAgIGV4cGVjdCh7YTogMX0pLnRvLmhhdmUub3duUHJvcGVydHlEZXNjcmlwdG9yKCdhJywge1xuICAgKiAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAqICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAqICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgKiAgICAgICB2YWx1ZTogMSxcbiAgICogICAgIH0pO1xuICAgKlxuICAgKiBBZGQgYC5ub3RgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIG5lZ2F0ZSBgLm93blByb3BlcnR5RGVzY3JpcHRvcmAuXG4gICAqXG4gICAqICAgICBleHBlY3Qoe2E6IDF9KS50by5ub3QuaGF2ZS5vd25Qcm9wZXJ0eURlc2NyaXB0b3IoJ2InKTtcbiAgICpcbiAgICogSG93ZXZlciwgaXQncyBkYW5nZXJvdXMgdG8gbmVnYXRlIGAub3duUHJvcGVydHlEZXNjcmlwdG9yYCB3aGVuIHByb3ZpZGluZ1xuICAgKiBhIGBkZXNjcmlwdG9yYC4gVGhlIHByb2JsZW0gaXMgdGhhdCBpdCBjcmVhdGVzIHVuY2VydGFpbiBleHBlY3RhdGlvbnMgYnlcbiAgICogYXNzZXJ0aW5nIHRoYXQgdGhlIHRhcmdldCBlaXRoZXIgZG9lc24ndCBoYXZlIGEgcHJvcGVydHkgZGVzY3JpcHRvciB3aXRoXG4gICAqIHRoZSBnaXZlbiBrZXkgYG5hbWVgLCBvciB0aGF0IGl0IGRvZXMgaGF2ZSBhIHByb3BlcnR5IGRlc2NyaXB0b3Igd2l0aCB0aGVcbiAgICogZ2l2ZW4ga2V5IGBuYW1lYCBidXQgaXRcdTIwMTlzIG5vdCBkZWVwbHkgZXF1YWwgdG8gdGhlIGdpdmVuIGBkZXNjcmlwdG9yYC4gSXQnc1xuICAgKiBvZnRlbiBiZXN0IHRvIGlkZW50aWZ5IHRoZSBleGFjdCBvdXRwdXQgdGhhdCdzIGV4cGVjdGVkLCBhbmQgdGhlbiB3cml0ZSBhblxuICAgKiBhc3NlcnRpb24gdGhhdCBvbmx5IGFjY2VwdHMgdGhhdCBleGFjdCBvdXRwdXQuXG4gICAqXG4gICAqIFdoZW4gdGhlIHRhcmdldCBpc24ndCBleHBlY3RlZCB0byBoYXZlIGEgcHJvcGVydHkgZGVzY3JpcHRvciB3aXRoIHRoZSBnaXZlblxuICAgKiBrZXkgYG5hbWVgLCBpdCdzIG9mdGVuIGJlc3QgdG8gYXNzZXJ0IGV4YWN0bHkgdGhhdC5cbiAgICpcbiAgICogICAgIC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3Qoe2I6IDJ9KS50by5ub3QuaGF2ZS5vd25Qcm9wZXJ0eURlc2NyaXB0b3IoJ2EnKTtcbiAgICpcbiAgICogICAgIC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KHtiOiAyfSkudG8ubm90LmhhdmUub3duUHJvcGVydHlEZXNjcmlwdG9yKCdhJywge1xuICAgKiAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAqICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAqICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgKiAgICAgICB2YWx1ZTogMSxcbiAgICogICAgIH0pO1xuICAgKlxuICAgKiBXaGVuIHRoZSB0YXJnZXQgaXMgZXhwZWN0ZWQgdG8gaGF2ZSBhIHByb3BlcnR5IGRlc2NyaXB0b3Igd2l0aCB0aGUgZ2l2ZW5cbiAgICoga2V5IGBuYW1lYCwgaXQncyBvZnRlbiBiZXN0IHRvIGFzc2VydCB0aGF0IHRoZSBwcm9wZXJ0eSBoYXMgaXRzIGV4cGVjdGVkXG4gICAqIGRlc2NyaXB0b3IsIHJhdGhlciB0aGFuIGFzc2VydGluZyB0aGF0IGl0IGRvZXNuJ3QgaGF2ZSBvbmUgb2YgbWFueVxuICAgKiB1bmV4cGVjdGVkIGRlc2NyaXB0b3JzLlxuICAgKlxuICAgKiAgICAgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCh7YTogM30pLnRvLmhhdmUub3duUHJvcGVydHlEZXNjcmlwdG9yKCdhJywge1xuICAgKiAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAqICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAqICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgKiAgICAgICB2YWx1ZTogMyxcbiAgICogICAgIH0pO1xuICAgKlxuICAgKiAgICAgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3Qoe2E6IDN9KS50by5ub3QuaGF2ZS5vd25Qcm9wZXJ0eURlc2NyaXB0b3IoJ2EnLCB7XG4gICAqICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICogICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICogICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAqICAgICAgIHZhbHVlOiAxLFxuICAgKiAgICAgfSk7XG4gICAqXG4gICAqIGAub3duUHJvcGVydHlEZXNjcmlwdG9yYCBjaGFuZ2VzIHRoZSB0YXJnZXQgb2YgYW55IGFzc2VydGlvbnMgdGhhdCBmb2xsb3dcbiAgICogaW4gdGhlIGNoYWluIHRvIGJlIHRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkgZGVzY3JpcHRvciBmcm9tIHRoZSBvcmlnaW5hbFxuICAgKiB0YXJnZXQgb2JqZWN0LlxuICAgKlxuICAgKiAgICAgZXhwZWN0KHthOiAxfSkudG8uaGF2ZS5vd25Qcm9wZXJ0eURlc2NyaXB0b3IoJ2EnKVxuICAgKiAgICAgICAudGhhdC5oYXMucHJvcGVydHkoJ2VudW1lcmFibGUnLCB0cnVlKTtcbiAgICpcbiAgICogYC5vd25Qcm9wZXJ0eURlc2NyaXB0b3JgIGFjY2VwdHMgYW4gb3B0aW9uYWwgYG1zZ2AgYXJndW1lbnQgd2hpY2ggaXMgYVxuICAgKiBjdXN0b20gZXJyb3IgbWVzc2FnZSB0byBzaG93IHdoZW4gdGhlIGFzc2VydGlvbiBmYWlscy4gVGhlIG1lc3NhZ2UgY2FuIGFsc29cbiAgICogYmUgZ2l2ZW4gYXMgdGhlIHNlY29uZCBhcmd1bWVudCB0byBgZXhwZWN0YC4gV2hlbiBub3QgcHJvdmlkaW5nXG4gICAqIGBkZXNjcmlwdG9yYCwgb25seSB1c2UgdGhlIHNlY29uZCBmb3JtLlxuICAgKlxuICAgKiAgICAgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCh7YTogMX0pLnRvLmhhdmUub3duUHJvcGVydHlEZXNjcmlwdG9yKCdhJywge1xuICAgKiAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAqICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAqICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgKiAgICAgICB2YWx1ZTogMixcbiAgICogICAgIH0sICdub29vIHdoeSBmYWlsPz8nKTtcbiAgICpcbiAgICogICAgIC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3Qoe2E6IDF9LCAnbm9vbyB3aHkgZmFpbD8/JykudG8uaGF2ZS5vd25Qcm9wZXJ0eURlc2NyaXB0b3IoJ2EnLCB7XG4gICAqICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICogICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICogICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAqICAgICAgIHZhbHVlOiAyLFxuICAgKiAgICAgfSk7XG4gICAqXG4gICAqICAgICAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KHthOiAxfSwgJ25vb28gd2h5IGZhaWw/PycpLnRvLmhhdmUub3duUHJvcGVydHlEZXNjcmlwdG9yKCdiJyk7XG4gICAqXG4gICAqICAgICAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCh7YTogMX0pXG4gICAqICAgICAgIC50by5oYXZlLm93blByb3BlcnR5RGVzY3JpcHRvcignYicsIHVuZGVmaW5lZCwgJ25vb28gd2h5IGZhaWw/PycpO1xuICAgKlxuICAgKiBUaGUgYWJvdmUgYXNzZXJ0aW9uIGlzbid0IHRoZSBzYW1lIHRoaW5nIGFzIG5vdCBwcm92aWRpbmcgYGRlc2NyaXB0b3JgLlxuICAgKiBJbnN0ZWFkLCBpdCdzIGFzc2VydGluZyB0aGF0IHRoZSB0YXJnZXQgb2JqZWN0IGhhcyBhIGBiYCBwcm9wZXJ0eVxuICAgKiBkZXNjcmlwdG9yIHRoYXQncyBkZWVwbHkgZXF1YWwgdG8gYHVuZGVmaW5lZGAuXG4gICAqXG4gICAqIFRoZSBhbGlhcyBgLmhhdmVPd25Qcm9wZXJ0eURlc2NyaXB0b3JgIGNhbiBiZSB1c2VkIGludGVyY2hhbmdlYWJseSB3aXRoXG4gICAqIGAub3duUHJvcGVydHlEZXNjcmlwdG9yYC5cbiAgICpcbiAgICogQG5hbWUgb3duUHJvcGVydHlEZXNjcmlwdG9yXG4gICAqIEBhbGlhcyBoYXZlT3duUHJvcGVydHlEZXNjcmlwdG9yXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBkZXNjcmlwdG9yIF9vcHRpb25hbF9cbiAgICogQHBhcmFtIHtTdHJpbmd9IG1zZyBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGFzc2VydE93blByb3BlcnR5RGVzY3JpcHRvciAobmFtZSwgZGVzY3JpcHRvciwgbXNnKSB7XG4gICAgaWYgKHR5cGVvZiBkZXNjcmlwdG9yID09PSAnc3RyaW5nJykge1xuICAgICAgbXNnID0gZGVzY3JpcHRvcjtcbiAgICAgIGRlc2NyaXB0b3IgPSBudWxsO1xuICAgIH1cbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gICAgdmFyIGFjdHVhbERlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKE9iamVjdChvYmopLCBuYW1lKTtcbiAgICBpZiAoYWN0dWFsRGVzY3JpcHRvciAmJiBkZXNjcmlwdG9yKSB7XG4gICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICBfLmVxbChkZXNjcmlwdG9yLCBhY3R1YWxEZXNjcmlwdG9yKVxuICAgICAgICAsICdleHBlY3RlZCB0aGUgb3duIHByb3BlcnR5IGRlc2NyaXB0b3IgZm9yICcgKyBfLmluc3BlY3QobmFtZSkgKyAnIG9uICN7dGhpc30gdG8gbWF0Y2ggJyArIF8uaW5zcGVjdChkZXNjcmlwdG9yKSArICcsIGdvdCAnICsgXy5pbnNwZWN0KGFjdHVhbERlc2NyaXB0b3IpXG4gICAgICAgICwgJ2V4cGVjdGVkIHRoZSBvd24gcHJvcGVydHkgZGVzY3JpcHRvciBmb3IgJyArIF8uaW5zcGVjdChuYW1lKSArICcgb24gI3t0aGlzfSB0byBub3QgbWF0Y2ggJyArIF8uaW5zcGVjdChkZXNjcmlwdG9yKVxuICAgICAgICAsIGRlc2NyaXB0b3JcbiAgICAgICAgLCBhY3R1YWxEZXNjcmlwdG9yXG4gICAgICAgICwgdHJ1ZVxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgYWN0dWFsRGVzY3JpcHRvclxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGhhdmUgYW4gb3duIHByb3BlcnR5IGRlc2NyaXB0b3IgZm9yICcgKyBfLmluc3BlY3QobmFtZSlcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgaGF2ZSBhbiBvd24gcHJvcGVydHkgZGVzY3JpcHRvciBmb3IgJyArIF8uaW5zcGVjdChuYW1lKVxuICAgICAgKTtcbiAgICB9XG4gICAgZmxhZyh0aGlzLCAnb2JqZWN0JywgYWN0dWFsRGVzY3JpcHRvcik7XG4gIH1cblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdvd25Qcm9wZXJ0eURlc2NyaXB0b3InLCBhc3NlcnRPd25Qcm9wZXJ0eURlc2NyaXB0b3IpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdoYXZlT3duUHJvcGVydHlEZXNjcmlwdG9yJywgYXNzZXJ0T3duUHJvcGVydHlEZXNjcmlwdG9yKTtcblxuICAvKipcbiAgICogIyMjIC5sZW5ndGhPZihuWywgbXNnXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQncyBgbGVuZ3RoYCBvciBgc2l6ZWAgaXMgZXF1YWwgdG8gdGhlIGdpdmVuIG51bWJlclxuICAgKiBgbmAuXG4gICAqXG4gICAqICAgICBleHBlY3QoWzEsIDIsIDNdKS50by5oYXZlLmxlbmd0aE9mKDMpO1xuICAgKiAgICAgZXhwZWN0KCdmb28nKS50by5oYXZlLmxlbmd0aE9mKDMpO1xuICAgKiAgICAgZXhwZWN0KG5ldyBTZXQoWzEsIDIsIDNdKSkudG8uaGF2ZS5sZW5ndGhPZigzKTtcbiAgICogICAgIGV4cGVjdChuZXcgTWFwKFtbJ2EnLCAxXSwgWydiJywgMl0sIFsnYycsIDNdXSkpLnRvLmhhdmUubGVuZ3RoT2YoMyk7XG4gICAqXG4gICAqIEFkZCBgLm5vdGAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gbmVnYXRlIGAubGVuZ3RoT2ZgLiBIb3dldmVyLCBpdCdzIG9mdGVuXG4gICAqIGJlc3QgdG8gYXNzZXJ0IHRoYXQgdGhlIHRhcmdldCdzIGBsZW5ndGhgIHByb3BlcnR5IGlzIGVxdWFsIHRvIGl0cyBleHBlY3RlZFxuICAgKiB2YWx1ZSwgcmF0aGVyIHRoYW4gbm90IGVxdWFsIHRvIG9uZSBvZiBtYW55IHVuZXhwZWN0ZWQgdmFsdWVzLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KCdmb28nKS50by5oYXZlLmxlbmd0aE9mKDMpOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KCdmb28nKS50by5ub3QuaGF2ZS5sZW5ndGhPZig0KTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqIGAubGVuZ3RoT2ZgIGFjY2VwdHMgYW4gb3B0aW9uYWwgYG1zZ2AgYXJndW1lbnQgd2hpY2ggaXMgYSBjdXN0b20gZXJyb3JcbiAgICogbWVzc2FnZSB0byBzaG93IHdoZW4gdGhlIGFzc2VydGlvbiBmYWlscy4gVGhlIG1lc3NhZ2UgY2FuIGFsc28gYmUgZ2l2ZW4gYXNcbiAgICogdGhlIHNlY29uZCBhcmd1bWVudCB0byBgZXhwZWN0YC5cbiAgICpcbiAgICogICAgIGV4cGVjdChbMSwgMiwgM10pLnRvLmhhdmUubGVuZ3RoT2YoMiwgJ25vb28gd2h5IGZhaWw/PycpO1xuICAgKiAgICAgZXhwZWN0KFsxLCAyLCAzXSwgJ25vb28gd2h5IGZhaWw/PycpLnRvLmhhdmUubGVuZ3RoT2YoMik7XG4gICAqXG4gICAqIGAubGVuZ3RoT2ZgIGNhbiBhbHNvIGJlIHVzZWQgYXMgYSBsYW5ndWFnZSBjaGFpbiwgY2F1c2luZyBhbGwgYC5hYm92ZWAsXG4gICAqIGAuYmVsb3dgLCBgLmxlYXN0YCwgYC5tb3N0YCwgYW5kIGAud2l0aGluYCBhc3NlcnRpb25zIHRoYXQgZm9sbG93IGluIHRoZVxuICAgKiBjaGFpbiB0byB1c2UgdGhlIHRhcmdldCdzIGBsZW5ndGhgIHByb3BlcnR5IGFzIHRoZSB0YXJnZXQuIEhvd2V2ZXIsIGl0J3NcbiAgICogb2Z0ZW4gYmVzdCB0byBhc3NlcnQgdGhhdCB0aGUgdGFyZ2V0J3MgYGxlbmd0aGAgcHJvcGVydHkgaXMgZXF1YWwgdG8gaXRzXG4gICAqIGV4cGVjdGVkIGxlbmd0aCwgcmF0aGVyIHRoYW4gYXNzZXJ0aW5nIHRoYXQgaXRzIGBsZW5ndGhgIHByb3BlcnR5IGZhbGxzXG4gICAqIHdpdGhpbiBzb21lIHJhbmdlIG9mIHZhbHVlcy5cbiAgICpcbiAgICogICAgIC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoWzEsIDIsIDNdKS50by5oYXZlLmxlbmd0aE9mKDMpO1xuICAgKlxuICAgKiAgICAgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoWzEsIDIsIDNdKS50by5oYXZlLmxlbmd0aE9mLmFib3ZlKDIpO1xuICAgKiAgICAgZXhwZWN0KFsxLCAyLCAzXSkudG8uaGF2ZS5sZW5ndGhPZi5iZWxvdyg0KTtcbiAgICogICAgIGV4cGVjdChbMSwgMiwgM10pLnRvLmhhdmUubGVuZ3RoT2YuYXQubGVhc3QoMyk7XG4gICAqICAgICBleHBlY3QoWzEsIDIsIDNdKS50by5oYXZlLmxlbmd0aE9mLmF0Lm1vc3QoMyk7XG4gICAqICAgICBleHBlY3QoWzEsIDIsIDNdKS50by5oYXZlLmxlbmd0aE9mLndpdGhpbigyLDQpO1xuICAgKlxuICAgKiBEdWUgdG8gYSBjb21wYXRpYmlsaXR5IGlzc3VlLCB0aGUgYWxpYXMgYC5sZW5ndGhgIGNhbid0IGJlIGNoYWluZWQgZGlyZWN0bHlcbiAgICogb2ZmIG9mIGFuIHVuaW52b2tlZCBtZXRob2Qgc3VjaCBhcyBgLmFgLiBUaGVyZWZvcmUsIGAubGVuZ3RoYCBjYW4ndCBiZSB1c2VkXG4gICAqIGludGVyY2hhbmdlYWJseSB3aXRoIGAubGVuZ3RoT2ZgIGluIGV2ZXJ5IHNpdHVhdGlvbi4gSXQncyByZWNvbW1lbmRlZCB0b1xuICAgKiBhbHdheXMgdXNlIGAubGVuZ3RoT2ZgIGluc3RlYWQgb2YgYC5sZW5ndGhgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KFsxLCAyLCAzXSkudG8uaGF2ZS5hLmxlbmd0aCgzKTsgLy8gaW5jb21wYXRpYmxlOyB0aHJvd3MgZXJyb3JcbiAgICogICAgIGV4cGVjdChbMSwgMiwgM10pLnRvLmhhdmUuYS5sZW5ndGhPZigzKTsgIC8vIHBhc3NlcyBhcyBleHBlY3RlZFxuICAgKlxuICAgKiBAbmFtZSBsZW5ndGhPZlxuICAgKiBAYWxpYXMgbGVuZ3RoXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtc2cgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBhc3NlcnRMZW5ndGhDaGFpbiAoKSB7XG4gICAgZmxhZyh0aGlzLCAnZG9MZW5ndGgnLCB0cnVlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGFzc2VydExlbmd0aCAobiwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAsIG9ialR5cGUgPSBfLnR5cGUob2JqKS50b0xvd2VyQ2FzZSgpXG4gICAgICAsIGZsYWdNc2cgPSBmbGFnKHRoaXMsICdtZXNzYWdlJylcbiAgICAgICwgc3NmaSA9IGZsYWcodGhpcywgJ3NzZmknKVxuICAgICAgLCBkZXNjcmlwdG9yID0gJ2xlbmd0aCdcbiAgICAgICwgaXRlbXNDb3VudDtcblxuICAgIHN3aXRjaCAob2JqVHlwZSkge1xuICAgICAgY2FzZSAnbWFwJzpcbiAgICAgIGNhc2UgJ3NldCc6XG4gICAgICAgIGRlc2NyaXB0b3IgPSAnc2l6ZSc7XG4gICAgICAgIGl0ZW1zQ291bnQgPSBvYmouc2l6ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgZmxhZ01zZywgc3NmaSwgdHJ1ZSkudG8uaGF2ZS5wcm9wZXJ0eSgnbGVuZ3RoJyk7XG4gICAgICAgIGl0ZW1zQ291bnQgPSBvYmoubGVuZ3RoO1xuICAgIH1cblxuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICBpdGVtc0NvdW50ID09IG5cbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gaGF2ZSBhICcgKyBkZXNjcmlwdG9yICsgJyBvZiAje2V4cH0gYnV0IGdvdCAje2FjdH0nXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBoYXZlIGEgJyArIGRlc2NyaXB0b3IgKyAnIG9mICN7YWN0fSdcbiAgICAgICwgblxuICAgICAgLCBpdGVtc0NvdW50XG4gICAgKTtcbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRDaGFpbmFibGVNZXRob2QoJ2xlbmd0aCcsIGFzc2VydExlbmd0aCwgYXNzZXJ0TGVuZ3RoQ2hhaW4pO1xuICBBc3NlcnRpb24uYWRkQ2hhaW5hYmxlTWV0aG9kKCdsZW5ndGhPZicsIGFzc2VydExlbmd0aCwgYXNzZXJ0TGVuZ3RoQ2hhaW4pO1xuXG4gIC8qKlxuICAgKiAjIyMgLm1hdGNoKHJlWywgbXNnXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgbWF0Y2hlcyB0aGUgZ2l2ZW4gcmVndWxhciBleHByZXNzaW9uIGByZWAuXG4gICAqXG4gICAqICAgICBleHBlY3QoJ2Zvb2JhcicpLnRvLm1hdGNoKC9eZm9vLyk7XG4gICAqXG4gICAqIEFkZCBgLm5vdGAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gbmVnYXRlIGAubWF0Y2hgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KCdmb29iYXInKS50by5ub3QubWF0Y2goL3RhY28vKTtcbiAgICpcbiAgICogYC5tYXRjaGAgYWNjZXB0cyBhbiBvcHRpb25hbCBgbXNnYCBhcmd1bWVudCB3aGljaCBpcyBhIGN1c3RvbSBlcnJvciBtZXNzYWdlXG4gICAqIHRvIHNob3cgd2hlbiB0aGUgYXNzZXJ0aW9uIGZhaWxzLiBUaGUgbWVzc2FnZSBjYW4gYWxzbyBiZSBnaXZlbiBhcyB0aGVcbiAgICogc2Vjb25kIGFyZ3VtZW50IHRvIGBleHBlY3RgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KCdmb29iYXInKS50by5tYXRjaCgvdGFjby8sICdub29vIHdoeSBmYWlsPz8nKTtcbiAgICogICAgIGV4cGVjdCgnZm9vYmFyJywgJ25vb28gd2h5IGZhaWw/PycpLnRvLm1hdGNoKC90YWNvLyk7XG4gICAqXG4gICAqIFRoZSBhbGlhcyBgLm1hdGNoZXNgIGNhbiBiZSB1c2VkIGludGVyY2hhbmdlYWJseSB3aXRoIGAubWF0Y2hgLlxuICAgKlxuICAgKiBAbmFtZSBtYXRjaFxuICAgKiBAYWxpYXMgbWF0Y2hlc1xuICAgKiBAcGFyYW0ge1JlZ0V4cH0gcmVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1zZyBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuICBmdW5jdGlvbiBhc3NlcnRNYXRjaChyZSwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpO1xuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICByZS5leGVjKG9iailcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbWF0Y2ggJyArIHJlXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IG5vdCB0byBtYXRjaCAnICsgcmVcbiAgICApO1xuICB9XG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnbWF0Y2gnLCBhc3NlcnRNYXRjaCk7XG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ21hdGNoZXMnLCBhc3NlcnRNYXRjaCk7XG5cbiAgLyoqXG4gICAqICMjIyAuc3RyaW5nKHN0clssIG1zZ10pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IHN0cmluZyBjb250YWlucyB0aGUgZ2l2ZW4gc3Vic3RyaW5nIGBzdHJgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KCdmb29iYXInKS50by5oYXZlLnN0cmluZygnYmFyJyk7XG4gICAqXG4gICAqIEFkZCBgLm5vdGAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gbmVnYXRlIGAuc3RyaW5nYC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgnZm9vYmFyJykudG8ubm90LmhhdmUuc3RyaW5nKCd0YWNvJyk7XG4gICAqXG4gICAqIGAuc3RyaW5nYCBhY2NlcHRzIGFuIG9wdGlvbmFsIGBtc2dgIGFyZ3VtZW50IHdoaWNoIGlzIGEgY3VzdG9tIGVycm9yXG4gICAqIG1lc3NhZ2UgdG8gc2hvdyB3aGVuIHRoZSBhc3NlcnRpb24gZmFpbHMuIFRoZSBtZXNzYWdlIGNhbiBhbHNvIGJlIGdpdmVuIGFzXG4gICAqIHRoZSBzZWNvbmQgYXJndW1lbnQgdG8gYGV4cGVjdGAuXG4gICAqXG4gICAqICAgICBleHBlY3QoJ2Zvb2JhcicpLnRvLmhhdmUuc3RyaW5nKCd0YWNvJywgJ25vb28gd2h5IGZhaWw/PycpO1xuICAgKiAgICAgZXhwZWN0KCdmb29iYXInLCAnbm9vbyB3aHkgZmFpbD8/JykudG8uaGF2ZS5zdHJpbmcoJ3RhY28nKTtcbiAgICpcbiAgICogQG5hbWUgc3RyaW5nXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1zZyBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ3N0cmluZycsIGZ1bmN0aW9uIChzdHIsIG1zZykge1xuICAgIGlmIChtc2cpIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCBmbGFnTXNnID0gZmxhZyh0aGlzLCAnbWVzc2FnZScpXG4gICAgICAsIHNzZmkgPSBmbGFnKHRoaXMsICdzc2ZpJyk7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIGZsYWdNc2csIHNzZmksIHRydWUpLmlzLmEoJ3N0cmluZycpO1xuXG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICAgIH5vYmouaW5kZXhPZihzdHIpXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGNvbnRhaW4gJyArIF8uaW5zcGVjdChzdHIpXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBjb250YWluICcgKyBfLmluc3BlY3Qoc3RyKVxuICAgICk7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiAjIyMgLmtleXMoa2V5MVssIGtleTJbLCAuLi5dXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgb2JqZWN0LCBhcnJheSwgbWFwLCBvciBzZXQgaGFzIHRoZSBnaXZlbiBrZXlzLiBPbmx5XG4gICAqIHRoZSB0YXJnZXQncyBvd24gaW5oZXJpdGVkIHByb3BlcnRpZXMgYXJlIGluY2x1ZGVkIGluIHRoZSBzZWFyY2guXG4gICAqXG4gICAqIFdoZW4gdGhlIHRhcmdldCBpcyBhbiBvYmplY3Qgb3IgYXJyYXksIGtleXMgY2FuIGJlIHByb3ZpZGVkIGFzIG9uZSBvciBtb3JlXG4gICAqIHN0cmluZyBhcmd1bWVudHMsIGEgc2luZ2xlIGFycmF5IGFyZ3VtZW50LCBvciBhIHNpbmdsZSBvYmplY3QgYXJndW1lbnQuIEluXG4gICAqIHRoZSBsYXR0ZXIgY2FzZSwgb25seSB0aGUga2V5cyBpbiB0aGUgZ2l2ZW4gb2JqZWN0IG1hdHRlcjsgdGhlIHZhbHVlcyBhcmVcbiAgICogaWdub3JlZC5cbiAgICpcbiAgICogICAgIGV4cGVjdCh7YTogMSwgYjogMn0pLnRvLmhhdmUuYWxsLmtleXMoJ2EnLCAnYicpO1xuICAgKiAgICAgZXhwZWN0KFsneCcsICd5J10pLnRvLmhhdmUuYWxsLmtleXMoMCwgMSk7XG4gICAqXG4gICAqICAgICBleHBlY3Qoe2E6IDEsIGI6IDJ9KS50by5oYXZlLmFsbC5rZXlzKFsnYScsICdiJ10pO1xuICAgKiAgICAgZXhwZWN0KFsneCcsICd5J10pLnRvLmhhdmUuYWxsLmtleXMoWzAsIDFdKTtcbiAgICpcbiAgICogICAgIGV4cGVjdCh7YTogMSwgYjogMn0pLnRvLmhhdmUuYWxsLmtleXMoe2E6IDQsIGI6IDV9KTsgLy8gaWdub3JlIDQgYW5kIDVcbiAgICogICAgIGV4cGVjdChbJ3gnLCAneSddKS50by5oYXZlLmFsbC5rZXlzKHswOiA0LCAxOiA1fSk7IC8vIGlnbm9yZSA0IGFuZCA1XG4gICAqXG4gICAqIFdoZW4gdGhlIHRhcmdldCBpcyBhIG1hcCBvciBzZXQsIGVhY2gga2V5IG11c3QgYmUgcHJvdmlkZWQgYXMgYSBzZXBhcmF0ZVxuICAgKiBhcmd1bWVudC5cbiAgICpcbiAgICogICAgIGV4cGVjdChuZXcgTWFwKFtbJ2EnLCAxXSwgWydiJywgMl1dKSkudG8uaGF2ZS5hbGwua2V5cygnYScsICdiJyk7XG4gICAqICAgICBleHBlY3QobmV3IFNldChbJ2EnLCAnYiddKSkudG8uaGF2ZS5hbGwua2V5cygnYScsICdiJyk7XG4gICAqXG4gICAqIEJlY2F1c2UgYC5rZXlzYCBkb2VzIGRpZmZlcmVudCB0aGluZ3MgYmFzZWQgb24gdGhlIHRhcmdldCdzIHR5cGUsIGl0J3NcbiAgICogaW1wb3J0YW50IHRvIGNoZWNrIHRoZSB0YXJnZXQncyB0eXBlIGJlZm9yZSB1c2luZyBgLmtleXNgLiBTZWUgdGhlIGAuYWAgZG9jXG4gICAqIGZvciBpbmZvIG9uIHRlc3RpbmcgYSB0YXJnZXQncyB0eXBlLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KHthOiAxLCBiOiAyfSkudG8uYmUuYW4oJ29iamVjdCcpLnRoYXQuaGFzLmFsbC5rZXlzKCdhJywgJ2InKTtcbiAgICpcbiAgICogQnkgZGVmYXVsdCwgc3RyaWN0IChgPT09YCkgZXF1YWxpdHkgaXMgdXNlZCB0byBjb21wYXJlIGtleXMgb2YgbWFwcyBhbmRcbiAgICogc2V0cy4gQWRkIGAuZGVlcGAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gdXNlIGRlZXAgZXF1YWxpdHkgaW5zdGVhZC4gU2VlXG4gICAqIHRoZSBgZGVlcC1lcWxgIHByb2plY3QgcGFnZSBmb3IgaW5mbyBvbiB0aGUgZGVlcCBlcXVhbGl0eSBhbGdvcml0aG06XG4gICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFpanMvZGVlcC1lcWwuXG4gICAqXG4gICAqICAgICAvLyBUYXJnZXQgc2V0IGRlZXBseSAoYnV0IG5vdCBzdHJpY3RseSkgaGFzIGtleSBge2E6IDF9YFxuICAgKiAgICAgZXhwZWN0KG5ldyBTZXQoW3thOiAxfV0pKS50by5oYXZlLmFsbC5kZWVwLmtleXMoW3thOiAxfV0pO1xuICAgKiAgICAgZXhwZWN0KG5ldyBTZXQoW3thOiAxfV0pKS50by5ub3QuaGF2ZS5hbGwua2V5cyhbe2E6IDF9XSk7XG4gICAqXG4gICAqIEJ5IGRlZmF1bHQsIHRoZSB0YXJnZXQgbXVzdCBoYXZlIGFsbCBvZiB0aGUgZ2l2ZW4ga2V5cyBhbmQgbm8gbW9yZS4gQWRkXG4gICAqIGAuYW55YCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byBvbmx5IHJlcXVpcmUgdGhhdCB0aGUgdGFyZ2V0IGhhdmUgYXQgbGVhc3RcbiAgICogb25lIG9mIHRoZSBnaXZlbiBrZXlzLiBBbHNvLCBhZGQgYC5ub3RgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIG5lZ2F0ZVxuICAgKiBgLmtleXNgLiBJdCdzIG9mdGVuIGJlc3QgdG8gYWRkIGAuYW55YCB3aGVuIG5lZ2F0aW5nIGAua2V5c2AsIGFuZCB0byB1c2VcbiAgICogYC5hbGxgIHdoZW4gYXNzZXJ0aW5nIGAua2V5c2Agd2l0aG91dCBuZWdhdGlvbi5cbiAgICpcbiAgICogV2hlbiBuZWdhdGluZyBgLmtleXNgLCBgLmFueWAgaXMgcHJlZmVycmVkIGJlY2F1c2UgYC5ub3QuYW55LmtleXNgIGFzc2VydHNcbiAgICogZXhhY3RseSB3aGF0J3MgZXhwZWN0ZWQgb2YgdGhlIG91dHB1dCwgd2hlcmVhcyBgLm5vdC5hbGwua2V5c2AgY3JlYXRlc1xuICAgKiB1bmNlcnRhaW4gZXhwZWN0YXRpb25zLlxuICAgKlxuICAgKiAgICAgLy8gUmVjb21tZW5kZWQ7IGFzc2VydHMgdGhhdCB0YXJnZXQgZG9lc24ndCBoYXZlIGFueSBvZiB0aGUgZ2l2ZW4ga2V5c1xuICAgKiAgICAgZXhwZWN0KHthOiAxLCBiOiAyfSkudG8ubm90LmhhdmUuYW55LmtleXMoJ2MnLCAnZCcpO1xuICAgKlxuICAgKiAgICAgLy8gTm90IHJlY29tbWVuZGVkOyBhc3NlcnRzIHRoYXQgdGFyZ2V0IGRvZXNuJ3QgaGF2ZSBhbGwgb2YgdGhlIGdpdmVuXG4gICAqICAgICAvLyBrZXlzIGJ1dCBtYXkgb3IgbWF5IG5vdCBoYXZlIHNvbWUgb2YgdGhlbVxuICAgKiAgICAgZXhwZWN0KHthOiAxLCBiOiAyfSkudG8ubm90LmhhdmUuYWxsLmtleXMoJ2MnLCAnZCcpO1xuICAgKlxuICAgKiBXaGVuIGFzc2VydGluZyBgLmtleXNgIHdpdGhvdXQgbmVnYXRpb24sIGAuYWxsYCBpcyBwcmVmZXJyZWQgYmVjYXVzZVxuICAgKiBgLmFsbC5rZXlzYCBhc3NlcnRzIGV4YWN0bHkgd2hhdCdzIGV4cGVjdGVkIG9mIHRoZSBvdXRwdXQsIHdoZXJlYXNcbiAgICogYC5hbnkua2V5c2AgY3JlYXRlcyB1bmNlcnRhaW4gZXhwZWN0YXRpb25zLlxuICAgKlxuICAgKiAgICAgLy8gUmVjb21tZW5kZWQ7IGFzc2VydHMgdGhhdCB0YXJnZXQgaGFzIGFsbCB0aGUgZ2l2ZW4ga2V5c1xuICAgKiAgICAgZXhwZWN0KHthOiAxLCBiOiAyfSkudG8uaGF2ZS5hbGwua2V5cygnYScsICdiJyk7XG4gICAqXG4gICAqICAgICAvLyBOb3QgcmVjb21tZW5kZWQ7IGFzc2VydHMgdGhhdCB0YXJnZXQgaGFzIGF0IGxlYXN0IG9uZSBvZiB0aGUgZ2l2ZW5cbiAgICogICAgIC8vIGtleXMgYnV0IG1heSBvciBtYXkgbm90IGhhdmUgbW9yZSBvZiB0aGVtXG4gICAqICAgICBleHBlY3Qoe2E6IDEsIGI6IDJ9KS50by5oYXZlLmFueS5rZXlzKCdhJywgJ2InKTtcbiAgICpcbiAgICogTm90ZSB0aGF0IGAuYWxsYCBpcyB1c2VkIGJ5IGRlZmF1bHQgd2hlbiBuZWl0aGVyIGAuYWxsYCBub3IgYC5hbnlgIGFwcGVhclxuICAgKiBlYXJsaWVyIGluIHRoZSBjaGFpbi4gSG93ZXZlciwgaXQncyBvZnRlbiBiZXN0IHRvIGFkZCBgLmFsbGAgYW55d2F5IGJlY2F1c2VcbiAgICogaXQgaW1wcm92ZXMgcmVhZGFiaWxpdHkuXG4gICAqXG4gICAqICAgICAvLyBCb3RoIGFzc2VydGlvbnMgYXJlIGlkZW50aWNhbFxuICAgKiAgICAgZXhwZWN0KHthOiAxLCBiOiAyfSkudG8uaGF2ZS5hbGwua2V5cygnYScsICdiJyk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3Qoe2E6IDEsIGI6IDJ9KS50by5oYXZlLmtleXMoJ2EnLCAnYicpOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogQWRkIGAuaW5jbHVkZWAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gcmVxdWlyZSB0aGF0IHRoZSB0YXJnZXQncyBrZXlzIGJlIGFcbiAgICogc3VwZXJzZXQgb2YgdGhlIGV4cGVjdGVkIGtleXMsIHJhdGhlciB0aGFuIGlkZW50aWNhbCBzZXRzLlxuICAgKlxuICAgKiAgICAgLy8gVGFyZ2V0IG9iamVjdCdzIGtleXMgYXJlIGEgc3VwZXJzZXQgb2YgWydhJywgJ2InXSBidXQgbm90IGlkZW50aWNhbFxuICAgKiAgICAgZXhwZWN0KHthOiAxLCBiOiAyLCBjOiAzfSkudG8uaW5jbHVkZS5hbGwua2V5cygnYScsICdiJyk7XG4gICAqICAgICBleHBlY3Qoe2E6IDEsIGI6IDIsIGM6IDN9KS50by5ub3QuaGF2ZS5hbGwua2V5cygnYScsICdiJyk7XG4gICAqXG4gICAqIEhvd2V2ZXIsIGlmIGAuYW55YCBhbmQgYC5pbmNsdWRlYCBhcmUgY29tYmluZWQsIG9ubHkgdGhlIGAuYW55YCB0YWtlc1xuICAgKiBlZmZlY3QuIFRoZSBgLmluY2x1ZGVgIGlzIGlnbm9yZWQgaW4gdGhpcyBjYXNlLlxuICAgKlxuICAgKiAgICAgLy8gQm90aCBhc3NlcnRpb25zIGFyZSBpZGVudGljYWxcbiAgICogICAgIGV4cGVjdCh7YTogMX0pLnRvLmhhdmUuYW55LmtleXMoJ2EnLCAnYicpO1xuICAgKiAgICAgZXhwZWN0KHthOiAxfSkudG8uaW5jbHVkZS5hbnkua2V5cygnYScsICdiJyk7XG4gICAqXG4gICAqIEEgY3VzdG9tIGVycm9yIG1lc3NhZ2UgY2FuIGJlIGdpdmVuIGFzIHRoZSBzZWNvbmQgYXJndW1lbnQgdG8gYGV4cGVjdGAuXG4gICAqXG4gICAqICAgICBleHBlY3Qoe2E6IDF9LCAnbm9vbyB3aHkgZmFpbD8/JykudG8uaGF2ZS5rZXkoJ2InKTtcbiAgICpcbiAgICogVGhlIGFsaWFzIGAua2V5YCBjYW4gYmUgdXNlZCBpbnRlcmNoYW5nZWFibHkgd2l0aCBgLmtleXNgLlxuICAgKlxuICAgKiBAbmFtZSBrZXlzXG4gICAqIEBhbGlhcyBrZXlcbiAgICogQHBhcmFtIHsuLi5TdHJpbmd8QXJyYXl8T2JqZWN0fSBrZXlzXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGFzc2VydEtleXMgKGtleXMpIHtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0JylcbiAgICAgICwgb2JqVHlwZSA9IF8udHlwZShvYmopXG4gICAgICAsIGtleXNUeXBlID0gXy50eXBlKGtleXMpXG4gICAgICAsIHNzZmkgPSBmbGFnKHRoaXMsICdzc2ZpJylcbiAgICAgICwgaXNEZWVwID0gZmxhZyh0aGlzLCAnZGVlcCcpXG4gICAgICAsIHN0clxuICAgICAgLCBkZWVwU3RyID0gJydcbiAgICAgICwgYWN0dWFsXG4gICAgICAsIG9rID0gdHJ1ZVxuICAgICAgLCBmbGFnTXNnID0gZmxhZyh0aGlzLCAnbWVzc2FnZScpO1xuXG4gICAgZmxhZ01zZyA9IGZsYWdNc2cgPyBmbGFnTXNnICsgJzogJyA6ICcnO1xuICAgIHZhciBtaXhlZEFyZ3NNc2cgPSBmbGFnTXNnICsgJ3doZW4gdGVzdGluZyBrZXlzIGFnYWluc3QgYW4gb2JqZWN0IG9yIGFuIGFycmF5IHlvdSBtdXN0IGdpdmUgYSBzaW5nbGUgQXJyYXl8T2JqZWN0fFN0cmluZyBhcmd1bWVudCBvciBtdWx0aXBsZSBTdHJpbmcgYXJndW1lbnRzJztcblxuICAgIGlmIChvYmpUeXBlID09PSAnTWFwJyB8fCBvYmpUeXBlID09PSAnU2V0Jykge1xuICAgICAgZGVlcFN0ciA9IGlzRGVlcCA/ICdkZWVwbHkgJyA6ICcnO1xuICAgICAgYWN0dWFsID0gW107XG5cbiAgICAgIC8vIE1hcCBhbmQgU2V0ICcua2V5cycgYXJlbid0IHN1cHBvcnRlZCBpbiBJRSAxMS4gVGhlcmVmb3JlLCB1c2UgLmZvckVhY2guXG4gICAgICBvYmouZm9yRWFjaChmdW5jdGlvbiAodmFsLCBrZXkpIHsgYWN0dWFsLnB1c2goa2V5KSB9KTtcblxuICAgICAgaWYgKGtleXNUeXBlICE9PSAnQXJyYXknKSB7XG4gICAgICAgIGtleXMgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBhY3R1YWwgPSBfLmdldE93bkVudW1lcmFibGVQcm9wZXJ0aWVzKG9iaik7XG5cbiAgICAgIHN3aXRjaCAoa2V5c1R5cGUpIHtcbiAgICAgICAgY2FzZSAnQXJyYXknOlxuICAgICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKG1peGVkQXJnc01zZywgdW5kZWZpbmVkLCBzc2ZpKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ09iamVjdCc6XG4gICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IobWl4ZWRBcmdzTXNnLCB1bmRlZmluZWQsIHNzZmkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBrZXlzID0gT2JqZWN0LmtleXMoa2V5cyk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAga2V5cyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG4gICAgICB9XG5cbiAgICAgIC8vIE9ubHkgc3RyaW5naWZ5IG5vbi1TeW1ib2xzIGJlY2F1c2UgU3ltYm9scyB3b3VsZCBiZWNvbWUgXCJTeW1ib2woKVwiXG4gICAgICBrZXlzID0ga2V5cy5tYXAoZnVuY3Rpb24gKHZhbCkge1xuICAgICAgICByZXR1cm4gdHlwZW9mIHZhbCA9PT0gJ3N5bWJvbCcgPyB2YWwgOiBTdHJpbmcodmFsKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICgha2V5cy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihmbGFnTXNnICsgJ2tleXMgcmVxdWlyZWQnLCB1bmRlZmluZWQsIHNzZmkpO1xuICAgIH1cblxuICAgIHZhciBsZW4gPSBrZXlzLmxlbmd0aFxuICAgICAgLCBhbnkgPSBmbGFnKHRoaXMsICdhbnknKVxuICAgICAgLCBhbGwgPSBmbGFnKHRoaXMsICdhbGwnKVxuICAgICAgLCBleHBlY3RlZCA9IGtleXM7XG5cbiAgICBpZiAoIWFueSAmJiAhYWxsKSB7XG4gICAgICBhbGwgPSB0cnVlO1xuICAgIH1cblxuICAgIC8vIEhhcyBhbnlcbiAgICBpZiAoYW55KSB7XG4gICAgICBvayA9IGV4cGVjdGVkLnNvbWUoZnVuY3Rpb24oZXhwZWN0ZWRLZXkpIHtcbiAgICAgICAgcmV0dXJuIGFjdHVhbC5zb21lKGZ1bmN0aW9uKGFjdHVhbEtleSkge1xuICAgICAgICAgIGlmIChpc0RlZXApIHtcbiAgICAgICAgICAgIHJldHVybiBfLmVxbChleHBlY3RlZEtleSwgYWN0dWFsS2V5KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGV4cGVjdGVkS2V5ID09PSBhY3R1YWxLZXk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIEhhcyBhbGxcbiAgICBpZiAoYWxsKSB7XG4gICAgICBvayA9IGV4cGVjdGVkLmV2ZXJ5KGZ1bmN0aW9uKGV4cGVjdGVkS2V5KSB7XG4gICAgICAgIHJldHVybiBhY3R1YWwuc29tZShmdW5jdGlvbihhY3R1YWxLZXkpIHtcbiAgICAgICAgICBpZiAoaXNEZWVwKSB7XG4gICAgICAgICAgICByZXR1cm4gXy5lcWwoZXhwZWN0ZWRLZXksIGFjdHVhbEtleSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBleHBlY3RlZEtleSA9PT0gYWN0dWFsS2V5O1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgaWYgKCFmbGFnKHRoaXMsICdjb250YWlucycpKSB7XG4gICAgICAgIG9rID0gb2sgJiYga2V5cy5sZW5ndGggPT0gYWN0dWFsLmxlbmd0aDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBLZXkgc3RyaW5nXG4gICAgaWYgKGxlbiA+IDEpIHtcbiAgICAgIGtleXMgPSBrZXlzLm1hcChmdW5jdGlvbihrZXkpIHtcbiAgICAgICAgcmV0dXJuIF8uaW5zcGVjdChrZXkpO1xuICAgICAgfSk7XG4gICAgICB2YXIgbGFzdCA9IGtleXMucG9wKCk7XG4gICAgICBpZiAoYWxsKSB7XG4gICAgICAgIHN0ciA9IGtleXMuam9pbignLCAnKSArICcsIGFuZCAnICsgbGFzdDtcbiAgICAgIH1cbiAgICAgIGlmIChhbnkpIHtcbiAgICAgICAgc3RyID0ga2V5cy5qb2luKCcsICcpICsgJywgb3IgJyArIGxhc3Q7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0ciA9IF8uaW5zcGVjdChrZXlzWzBdKTtcbiAgICB9XG5cbiAgICAvLyBGb3JtXG4gICAgc3RyID0gKGxlbiA+IDEgPyAna2V5cyAnIDogJ2tleSAnKSArIHN0cjtcblxuICAgIC8vIEhhdmUgLyBpbmNsdWRlXG4gICAgc3RyID0gKGZsYWcodGhpcywgJ2NvbnRhaW5zJykgPyAnY29udGFpbiAnIDogJ2hhdmUgJykgKyBzdHI7XG5cbiAgICAvLyBBc3NlcnRpb25cbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgb2tcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gJyArIGRlZXBTdHIgKyBzdHJcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90ICcgKyBkZWVwU3RyICsgc3RyXG4gICAgICAsIGV4cGVjdGVkLnNsaWNlKDApLnNvcnQoXy5jb21wYXJlQnlJbnNwZWN0KVxuICAgICAgLCBhY3R1YWwuc29ydChfLmNvbXBhcmVCeUluc3BlY3QpXG4gICAgICAsIHRydWVcbiAgICApO1xuICB9XG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgna2V5cycsIGFzc2VydEtleXMpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdrZXknLCBhc3NlcnRLZXlzKTtcblxuICAvKipcbiAgICogIyMjIC50aHJvdyhbZXJyb3JMaWtlXSwgW2Vyck1zZ01hdGNoZXJdLCBbbXNnXSlcbiAgICpcbiAgICogV2hlbiBubyBhcmd1bWVudHMgYXJlIHByb3ZpZGVkLCBgLnRocm93YCBpbnZva2VzIHRoZSB0YXJnZXQgZnVuY3Rpb24gYW5kXG4gICAqIGFzc2VydHMgdGhhdCBhbiBlcnJvciBpcyB0aHJvd24uXG4gICAqXG4gICAqICAgICB2YXIgYmFkRm4gPSBmdW5jdGlvbiAoKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ0lsbGVnYWwgc2FsbW9uIScpOyB9O1xuICAgKlxuICAgKiAgICAgZXhwZWN0KGJhZEZuKS50by50aHJvdygpO1xuICAgKlxuICAgKiBXaGVuIG9uZSBhcmd1bWVudCBpcyBwcm92aWRlZCwgYW5kIGl0J3MgYW4gZXJyb3IgY29uc3RydWN0b3IsIGAudGhyb3dgXG4gICAqIGludm9rZXMgdGhlIHRhcmdldCBmdW5jdGlvbiBhbmQgYXNzZXJ0cyB0aGF0IGFuIGVycm9yIGlzIHRocm93biB0aGF0J3MgYW5cbiAgICogaW5zdGFuY2Ugb2YgdGhhdCBlcnJvciBjb25zdHJ1Y3Rvci5cbiAgICpcbiAgICogICAgIHZhciBiYWRGbiA9IGZ1bmN0aW9uICgpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignSWxsZWdhbCBzYWxtb24hJyk7IH07XG4gICAqXG4gICAqICAgICBleHBlY3QoYmFkRm4pLnRvLnRocm93KFR5cGVFcnJvcik7XG4gICAqXG4gICAqIFdoZW4gb25lIGFyZ3VtZW50IGlzIHByb3ZpZGVkLCBhbmQgaXQncyBhbiBlcnJvciBpbnN0YW5jZSwgYC50aHJvd2AgaW52b2tlc1xuICAgKiB0aGUgdGFyZ2V0IGZ1bmN0aW9uIGFuZCBhc3NlcnRzIHRoYXQgYW4gZXJyb3IgaXMgdGhyb3duIHRoYXQncyBzdHJpY3RseVxuICAgKiAoYD09PWApIGVxdWFsIHRvIHRoYXQgZXJyb3IgaW5zdGFuY2UuXG4gICAqXG4gICAqICAgICB2YXIgZXJyID0gbmV3IFR5cGVFcnJvcignSWxsZWdhbCBzYWxtb24hJyk7XG4gICAqICAgICB2YXIgYmFkRm4gPSBmdW5jdGlvbiAoKSB7IHRocm93IGVycjsgfTtcbiAgICpcbiAgICogICAgIGV4cGVjdChiYWRGbikudG8udGhyb3coZXJyKTtcbiAgICpcbiAgICogV2hlbiBvbmUgYXJndW1lbnQgaXMgcHJvdmlkZWQsIGFuZCBpdCdzIGEgc3RyaW5nLCBgLnRocm93YCBpbnZva2VzIHRoZVxuICAgKiB0YXJnZXQgZnVuY3Rpb24gYW5kIGFzc2VydHMgdGhhdCBhbiBlcnJvciBpcyB0aHJvd24gd2l0aCBhIG1lc3NhZ2UgdGhhdFxuICAgKiBjb250YWlucyB0aGF0IHN0cmluZy5cbiAgICpcbiAgICogICAgIHZhciBiYWRGbiA9IGZ1bmN0aW9uICgpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignSWxsZWdhbCBzYWxtb24hJyk7IH07XG4gICAqXG4gICAqICAgICBleHBlY3QoYmFkRm4pLnRvLnRocm93KCdzYWxtb24nKTtcbiAgICpcbiAgICogV2hlbiBvbmUgYXJndW1lbnQgaXMgcHJvdmlkZWQsIGFuZCBpdCdzIGEgcmVndWxhciBleHByZXNzaW9uLCBgLnRocm93YFxuICAgKiBpbnZva2VzIHRoZSB0YXJnZXQgZnVuY3Rpb24gYW5kIGFzc2VydHMgdGhhdCBhbiBlcnJvciBpcyB0aHJvd24gd2l0aCBhXG4gICAqIG1lc3NhZ2UgdGhhdCBtYXRjaGVzIHRoYXQgcmVndWxhciBleHByZXNzaW9uLlxuICAgKlxuICAgKiAgICAgdmFyIGJhZEZuID0gZnVuY3Rpb24gKCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbGxlZ2FsIHNhbG1vbiEnKTsgfTtcbiAgICpcbiAgICogICAgIGV4cGVjdChiYWRGbikudG8udGhyb3coL3NhbG1vbi8pO1xuICAgKlxuICAgKiBXaGVuIHR3byBhcmd1bWVudHMgYXJlIHByb3ZpZGVkLCBhbmQgdGhlIGZpcnN0IGlzIGFuIGVycm9yIGluc3RhbmNlIG9yXG4gICAqIGNvbnN0cnVjdG9yLCBhbmQgdGhlIHNlY29uZCBpcyBhIHN0cmluZyBvciByZWd1bGFyIGV4cHJlc3Npb24sIGAudGhyb3dgXG4gICAqIGludm9rZXMgdGhlIGZ1bmN0aW9uIGFuZCBhc3NlcnRzIHRoYXQgYW4gZXJyb3IgaXMgdGhyb3duIHRoYXQgZnVsZmlsbHMgYm90aFxuICAgKiBjb25kaXRpb25zIGFzIGRlc2NyaWJlZCBhYm92ZS5cbiAgICpcbiAgICogICAgIHZhciBlcnIgPSBuZXcgVHlwZUVycm9yKCdJbGxlZ2FsIHNhbG1vbiEnKTtcbiAgICogICAgIHZhciBiYWRGbiA9IGZ1bmN0aW9uICgpIHsgdGhyb3cgZXJyOyB9O1xuICAgKlxuICAgKiAgICAgZXhwZWN0KGJhZEZuKS50by50aHJvdyhUeXBlRXJyb3IsICdzYWxtb24nKTtcbiAgICogICAgIGV4cGVjdChiYWRGbikudG8udGhyb3coVHlwZUVycm9yLCAvc2FsbW9uLyk7XG4gICAqICAgICBleHBlY3QoYmFkRm4pLnRvLnRocm93KGVyciwgJ3NhbG1vbicpO1xuICAgKiAgICAgZXhwZWN0KGJhZEZuKS50by50aHJvdyhlcnIsIC9zYWxtb24vKTtcbiAgICpcbiAgICogQWRkIGAubm90YCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byBuZWdhdGUgYC50aHJvd2AuXG4gICAqXG4gICAqICAgICB2YXIgZ29vZEZuID0gZnVuY3Rpb24gKCkge307XG4gICAqXG4gICAqICAgICBleHBlY3QoZ29vZEZuKS50by5ub3QudGhyb3coKTtcbiAgICpcbiAgICogSG93ZXZlciwgaXQncyBkYW5nZXJvdXMgdG8gbmVnYXRlIGAudGhyb3dgIHdoZW4gcHJvdmlkaW5nIGFueSBhcmd1bWVudHMuXG4gICAqIFRoZSBwcm9ibGVtIGlzIHRoYXQgaXQgY3JlYXRlcyB1bmNlcnRhaW4gZXhwZWN0YXRpb25zIGJ5IGFzc2VydGluZyB0aGF0IHRoZVxuICAgKiB0YXJnZXQgZWl0aGVyIGRvZXNuJ3QgdGhyb3cgYW4gZXJyb3IsIG9yIHRoYXQgaXQgdGhyb3dzIGFuIGVycm9yIGJ1dCBvZiBhXG4gICAqIGRpZmZlcmVudCB0eXBlIHRoYW4gdGhlIGdpdmVuIHR5cGUsIG9yIHRoYXQgaXQgdGhyb3dzIGFuIGVycm9yIG9mIHRoZSBnaXZlblxuICAgKiB0eXBlIGJ1dCB3aXRoIGEgbWVzc2FnZSB0aGF0IGRvZXNuJ3QgaW5jbHVkZSB0aGUgZ2l2ZW4gc3RyaW5nLiBJdCdzIG9mdGVuXG4gICAqIGJlc3QgdG8gaWRlbnRpZnkgdGhlIGV4YWN0IG91dHB1dCB0aGF0J3MgZXhwZWN0ZWQsIGFuZCB0aGVuIHdyaXRlIGFuXG4gICAqIGFzc2VydGlvbiB0aGF0IG9ubHkgYWNjZXB0cyB0aGF0IGV4YWN0IG91dHB1dC5cbiAgICpcbiAgICogV2hlbiB0aGUgdGFyZ2V0IGlzbid0IGV4cGVjdGVkIHRvIHRocm93IGFuIGVycm9yLCBpdCdzIG9mdGVuIGJlc3QgdG8gYXNzZXJ0XG4gICAqIGV4YWN0bHkgdGhhdC5cbiAgICpcbiAgICogICAgIHZhciBnb29kRm4gPSBmdW5jdGlvbiAoKSB7fTtcbiAgICpcbiAgICogICAgIGV4cGVjdChnb29kRm4pLnRvLm5vdC50aHJvdygpOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KGdvb2RGbikudG8ubm90LnRocm93KFJlZmVyZW5jZUVycm9yLCAneCcpOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogV2hlbiB0aGUgdGFyZ2V0IGlzIGV4cGVjdGVkIHRvIHRocm93IGFuIGVycm9yLCBpdCdzIG9mdGVuIGJlc3QgdG8gYXNzZXJ0XG4gICAqIHRoYXQgdGhlIGVycm9yIGlzIG9mIGl0cyBleHBlY3RlZCB0eXBlLCBhbmQgaGFzIGEgbWVzc2FnZSB0aGF0IGluY2x1ZGVzIGFuXG4gICAqIGV4cGVjdGVkIHN0cmluZywgcmF0aGVyIHRoYW4gYXNzZXJ0aW5nIHRoYXQgaXQgZG9lc24ndCBoYXZlIG9uZSBvZiBtYW55XG4gICAqIHVuZXhwZWN0ZWQgdHlwZXMsIGFuZCBkb2Vzbid0IGhhdmUgYSBtZXNzYWdlIHRoYXQgaW5jbHVkZXMgc29tZSBzdHJpbmcuXG4gICAqXG4gICAqICAgICB2YXIgYmFkRm4gPSBmdW5jdGlvbiAoKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ0lsbGVnYWwgc2FsbW9uIScpOyB9O1xuICAgKlxuICAgKiAgICAgZXhwZWN0KGJhZEZuKS50by50aHJvdyhUeXBlRXJyb3IsICdzYWxtb24nKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdChiYWRGbikudG8ubm90LnRocm93KFJlZmVyZW5jZUVycm9yLCAneCcpOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogYC50aHJvd2AgY2hhbmdlcyB0aGUgdGFyZ2V0IG9mIGFueSBhc3NlcnRpb25zIHRoYXQgZm9sbG93IGluIHRoZSBjaGFpbiB0b1xuICAgKiBiZSB0aGUgZXJyb3Igb2JqZWN0IHRoYXQncyB0aHJvd24uXG4gICAqXG4gICAqICAgICB2YXIgZXJyID0gbmV3IFR5cGVFcnJvcignSWxsZWdhbCBzYWxtb24hJyk7XG4gICAqICAgICBlcnIuY29kZSA9IDQyO1xuICAgKiAgICAgdmFyIGJhZEZuID0gZnVuY3Rpb24gKCkgeyB0aHJvdyBlcnI7IH07XG4gICAqXG4gICAqICAgICBleHBlY3QoYmFkRm4pLnRvLnRocm93KFR5cGVFcnJvcikud2l0aC5wcm9wZXJ0eSgnY29kZScsIDQyKTtcbiAgICpcbiAgICogYC50aHJvd2AgYWNjZXB0cyBhbiBvcHRpb25hbCBgbXNnYCBhcmd1bWVudCB3aGljaCBpcyBhIGN1c3RvbSBlcnJvciBtZXNzYWdlXG4gICAqIHRvIHNob3cgd2hlbiB0aGUgYXNzZXJ0aW9uIGZhaWxzLiBUaGUgbWVzc2FnZSBjYW4gYWxzbyBiZSBnaXZlbiBhcyB0aGVcbiAgICogc2Vjb25kIGFyZ3VtZW50IHRvIGBleHBlY3RgLiBXaGVuIG5vdCBwcm92aWRpbmcgdHdvIGFyZ3VtZW50cywgYWx3YXlzIHVzZVxuICAgKiB0aGUgc2Vjb25kIGZvcm0uXG4gICAqXG4gICAqICAgICB2YXIgZ29vZEZuID0gZnVuY3Rpb24gKCkge307XG4gICAqXG4gICAqICAgICBleHBlY3QoZ29vZEZuKS50by50aHJvdyhUeXBlRXJyb3IsICd4JywgJ25vb28gd2h5IGZhaWw/PycpO1xuICAgKiAgICAgZXhwZWN0KGdvb2RGbiwgJ25vb28gd2h5IGZhaWw/PycpLnRvLnRocm93KCk7XG4gICAqXG4gICAqIER1ZSB0byBsaW1pdGF0aW9ucyBpbiBFUzUsIGAudGhyb3dgIG1heSBub3QgYWx3YXlzIHdvcmsgYXMgZXhwZWN0ZWQgd2hlblxuICAgKiB1c2luZyBhIHRyYW5zcGlsZXIgc3VjaCBhcyBCYWJlbCBvciBUeXBlU2NyaXB0LiBJbiBwYXJ0aWN1bGFyLCBpdCBtYXlcbiAgICogcHJvZHVjZSB1bmV4cGVjdGVkIHJlc3VsdHMgd2hlbiBzdWJjbGFzc2luZyB0aGUgYnVpbHQtaW4gYEVycm9yYCBvYmplY3QgYW5kXG4gICAqIHRoZW4gcGFzc2luZyB0aGUgc3ViY2xhc3NlZCBjb25zdHJ1Y3RvciB0byBgLnRocm93YC4gU2VlIHlvdXIgdHJhbnNwaWxlcidzXG4gICAqIGRvY3MgZm9yIGRldGFpbHM6XG4gICAqXG4gICAqIC0gKFtCYWJlbF0oaHR0cHM6Ly9iYWJlbGpzLmlvL2RvY3MvdXNhZ2UvY2F2ZWF0cy8jY2xhc3NlcykpXG4gICAqIC0gKFtUeXBlU2NyaXB0XShodHRwczovL2dpdGh1Yi5jb20vTWljcm9zb2Z0L1R5cGVTY3JpcHQvd2lraS9CcmVha2luZy1DaGFuZ2VzI2V4dGVuZGluZy1idWlsdC1pbnMtbGlrZS1lcnJvci1hcnJheS1hbmQtbWFwLW1heS1uby1sb25nZXItd29yaykpXG4gICAqXG4gICAqIEJld2FyZSBvZiBzb21lIGNvbW1vbiBtaXN0YWtlcyB3aGVuIHVzaW5nIHRoZSBgdGhyb3dgIGFzc2VydGlvbi4gT25lIGNvbW1vblxuICAgKiBtaXN0YWtlIGlzIHRvIGFjY2lkZW50YWxseSBpbnZva2UgdGhlIGZ1bmN0aW9uIHlvdXJzZWxmIGluc3RlYWQgb2YgbGV0dGluZ1xuICAgKiB0aGUgYHRocm93YCBhc3NlcnRpb24gaW52b2tlIHRoZSBmdW5jdGlvbiBmb3IgeW91LiBGb3IgZXhhbXBsZSwgd2hlblxuICAgKiB0ZXN0aW5nIGlmIGEgZnVuY3Rpb24gbmFtZWQgYGZuYCB0aHJvd3MsIHByb3ZpZGUgYGZuYCBpbnN0ZWFkIG9mIGBmbigpYCBhc1xuICAgKiB0aGUgdGFyZ2V0IGZvciB0aGUgYXNzZXJ0aW9uLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KGZuKS50by50aHJvdygpOyAgICAgLy8gR29vZCEgVGVzdHMgYGZuYCBhcyBkZXNpcmVkXG4gICAqICAgICBleHBlY3QoZm4oKSkudG8udGhyb3coKTsgICAvLyBCYWQhIFRlc3RzIHJlc3VsdCBvZiBgZm4oKWAsIG5vdCBgZm5gXG4gICAqXG4gICAqIElmIHlvdSBuZWVkIHRvIGFzc2VydCB0aGF0IHlvdXIgZnVuY3Rpb24gYGZuYCB0aHJvd3Mgd2hlbiBwYXNzZWQgY2VydGFpblxuICAgKiBhcmd1bWVudHMsIHRoZW4gd3JhcCBhIGNhbGwgdG8gYGZuYCBpbnNpZGUgb2YgYW5vdGhlciBmdW5jdGlvbi5cbiAgICpcbiAgICogICAgIGV4cGVjdChmdW5jdGlvbiAoKSB7IGZuKDQyKTsgfSkudG8udGhyb3coKTsgIC8vIEZ1bmN0aW9uIGV4cHJlc3Npb25cbiAgICogICAgIGV4cGVjdCgoKSA9PiBmbig0MikpLnRvLnRocm93KCk7ICAgICAgICAgICAgIC8vIEVTNiBhcnJvdyBmdW5jdGlvblxuICAgKlxuICAgKiBBbm90aGVyIGNvbW1vbiBtaXN0YWtlIGlzIHRvIHByb3ZpZGUgYW4gb2JqZWN0IG1ldGhvZCAob3IgYW55IHN0YW5kLWFsb25lXG4gICAqIGZ1bmN0aW9uIHRoYXQgcmVsaWVzIG9uIGB0aGlzYCkgYXMgdGhlIHRhcmdldCBvZiB0aGUgYXNzZXJ0aW9uLiBEb2luZyBzbyBpc1xuICAgKiBwcm9ibGVtYXRpYyBiZWNhdXNlIHRoZSBgdGhpc2AgY29udGV4dCB3aWxsIGJlIGxvc3Qgd2hlbiB0aGUgZnVuY3Rpb24gaXNcbiAgICogaW52b2tlZCBieSBgLnRocm93YDsgdGhlcmUncyBubyB3YXkgZm9yIGl0IHRvIGtub3cgd2hhdCBgdGhpc2AgaXMgc3VwcG9zZWRcbiAgICogdG8gYmUuIFRoZXJlIGFyZSB0d28gd2F5cyBhcm91bmQgdGhpcyBwcm9ibGVtLiBPbmUgc29sdXRpb24gaXMgdG8gd3JhcCB0aGVcbiAgICogbWV0aG9kIG9yIGZ1bmN0aW9uIGNhbGwgaW5zaWRlIG9mIGFub3RoZXIgZnVuY3Rpb24uIEFub3RoZXIgc29sdXRpb24gaXMgdG9cbiAgICogdXNlIGBiaW5kYC5cbiAgICpcbiAgICogICAgIGV4cGVjdChmdW5jdGlvbiAoKSB7IGNhdC5tZW93KCk7IH0pLnRvLnRocm93KCk7ICAvLyBGdW5jdGlvbiBleHByZXNzaW9uXG4gICAqICAgICBleHBlY3QoKCkgPT4gY2F0Lm1lb3coKSkudG8udGhyb3coKTsgICAgICAgICAgICAgLy8gRVM2IGFycm93IGZ1bmN0aW9uXG4gICAqICAgICBleHBlY3QoY2F0Lm1lb3cuYmluZChjYXQpKS50by50aHJvdygpOyAgICAgICAgICAgLy8gQmluZFxuICAgKlxuICAgKiBGaW5hbGx5LCBpdCdzIHdvcnRoIG1lbnRpb25pbmcgdGhhdCBpdCdzIGEgYmVzdCBwcmFjdGljZSBpbiBKYXZhU2NyaXB0IHRvXG4gICAqIG9ubHkgdGhyb3cgYEVycm9yYCBhbmQgZGVyaXZhdGl2ZXMgb2YgYEVycm9yYCBzdWNoIGFzIGBSZWZlcmVuY2VFcnJvcmAsXG4gICAqIGBUeXBlRXJyb3JgLCBhbmQgdXNlci1kZWZpbmVkIG9iamVjdHMgdGhhdCBleHRlbmQgYEVycm9yYC4gTm8gb3RoZXIgdHlwZSBvZlxuICAgKiB2YWx1ZSB3aWxsIGdlbmVyYXRlIGEgc3RhY2sgdHJhY2Ugd2hlbiBpbml0aWFsaXplZC4gV2l0aCB0aGF0IHNhaWQsIHRoZVxuICAgKiBgdGhyb3dgIGFzc2VydGlvbiBkb2VzIHRlY2huaWNhbGx5IHN1cHBvcnQgYW55IHR5cGUgb2YgdmFsdWUgYmVpbmcgdGhyb3duLFxuICAgKiBub3QganVzdCBgRXJyb3JgIGFuZCBpdHMgZGVyaXZhdGl2ZXMuXG4gICAqXG4gICAqIFRoZSBhbGlhc2VzIGAudGhyb3dzYCBhbmQgYC5UaHJvd2AgY2FuIGJlIHVzZWQgaW50ZXJjaGFuZ2VhYmx5IHdpdGhcbiAgICogYC50aHJvd2AuXG4gICAqXG4gICAqIEBuYW1lIHRocm93XG4gICAqIEBhbGlhcyB0aHJvd3NcbiAgICogQGFsaWFzIFRocm93XG4gICAqIEBwYXJhbSB7RXJyb3J8RXJyb3JDb25zdHJ1Y3Rvcn0gZXJyb3JMaWtlXG4gICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXJyTXNnTWF0Y2hlciBlcnJvciBtZXNzYWdlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtc2cgX29wdGlvbmFsX1xuICAgKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0Vycm9yI0Vycm9yX3R5cGVzXG4gICAqIEByZXR1cm5zIGVycm9yIGZvciBjaGFpbmluZyAobnVsbCBpZiBubyBlcnJvcilcbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gYXNzZXJ0VGhyb3dzIChlcnJvckxpa2UsIGVyck1zZ01hdGNoZXIsIG1zZykge1xuICAgIGlmIChtc2cpIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCBzc2ZpID0gZmxhZyh0aGlzLCAnc3NmaScpXG4gICAgICAsIGZsYWdNc2cgPSBmbGFnKHRoaXMsICdtZXNzYWdlJylcbiAgICAgICwgbmVnYXRlID0gZmxhZyh0aGlzLCAnbmVnYXRlJykgfHwgZmFsc2U7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIGZsYWdNc2csIHNzZmksIHRydWUpLmlzLmEoJ2Z1bmN0aW9uJyk7XG5cbiAgICBpZiAoZXJyb3JMaWtlIGluc3RhbmNlb2YgUmVnRXhwIHx8IHR5cGVvZiBlcnJvckxpa2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICBlcnJNc2dNYXRjaGVyID0gZXJyb3JMaWtlO1xuICAgICAgZXJyb3JMaWtlID0gbnVsbDtcbiAgICB9XG5cbiAgICB2YXIgY2F1Z2h0RXJyO1xuICAgIHRyeSB7XG4gICAgICBvYmooKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGNhdWdodEVyciA9IGVycjtcbiAgICB9XG5cbiAgICAvLyBJZiB3ZSBoYXZlIHRoZSBuZWdhdGUgZmxhZyBlbmFibGVkIGFuZCBhdCBsZWFzdCBvbmUgdmFsaWQgYXJndW1lbnQgaXQgbWVhbnMgd2UgZG8gZXhwZWN0IGFuIGVycm9yXG4gICAgLy8gYnV0IHdlIHdhbnQgaXQgdG8gbWF0Y2ggYSBnaXZlbiBzZXQgb2YgY3JpdGVyaWFcbiAgICB2YXIgZXZlcnlBcmdJc1VuZGVmaW5lZCA9IGVycm9yTGlrZSA9PT0gdW5kZWZpbmVkICYmIGVyck1zZ01hdGNoZXIgPT09IHVuZGVmaW5lZDtcblxuICAgIC8vIElmIHdlJ3ZlIGdvdCB0aGUgbmVnYXRlIGZsYWcgZW5hYmxlZCBhbmQgYm90aCBhcmdzLCB3ZSBzaG91bGQgb25seSBmYWlsIGlmIGJvdGggYXJlbid0IGNvbXBhdGlibGVcbiAgICAvLyBTZWUgSXNzdWUgIzU1MSBhbmQgUFIgIzY4M0BHaXRIdWJcbiAgICB2YXIgZXZlcnlBcmdJc0RlZmluZWQgPSBCb29sZWFuKGVycm9yTGlrZSAmJiBlcnJNc2dNYXRjaGVyKTtcbiAgICB2YXIgZXJyb3JMaWtlRmFpbCA9IGZhbHNlO1xuICAgIHZhciBlcnJNc2dNYXRjaGVyRmFpbCA9IGZhbHNlO1xuXG4gICAgLy8gQ2hlY2tpbmcgaWYgZXJyb3Igd2FzIHRocm93blxuICAgIGlmIChldmVyeUFyZ0lzVW5kZWZpbmVkIHx8ICFldmVyeUFyZ0lzVW5kZWZpbmVkICYmICFuZWdhdGUpIHtcbiAgICAgIC8vIFdlIG5lZWQgdGhpcyB0byBkaXNwbGF5IHJlc3VsdHMgY29ycmVjdGx5IGFjY29yZGluZyB0byB0aGVpciB0eXBlc1xuICAgICAgdmFyIGVycm9yTGlrZVN0cmluZyA9ICdhbiBlcnJvcic7XG4gICAgICBpZiAoZXJyb3JMaWtlIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgZXJyb3JMaWtlU3RyaW5nID0gJyN7ZXhwfSc7XG4gICAgICB9IGVsc2UgaWYgKGVycm9yTGlrZSkge1xuICAgICAgICBlcnJvckxpa2VTdHJpbmcgPSBfLmNoZWNrRXJyb3IuZ2V0Q29uc3RydWN0b3JOYW1lKGVycm9yTGlrZSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgIGNhdWdodEVyclxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIHRocm93ICcgKyBlcnJvckxpa2VTdHJpbmdcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgdGhyb3cgYW4gZXJyb3IgYnV0ICN7YWN0fSB3YXMgdGhyb3duJ1xuICAgICAgICAsIGVycm9yTGlrZSAmJiBlcnJvckxpa2UudG9TdHJpbmcoKVxuICAgICAgICAsIChjYXVnaHRFcnIgaW5zdGFuY2VvZiBFcnJvciA/XG4gICAgICAgICAgICBjYXVnaHRFcnIudG9TdHJpbmcoKSA6ICh0eXBlb2YgY2F1Z2h0RXJyID09PSAnc3RyaW5nJyA/IGNhdWdodEVyciA6IGNhdWdodEVyciAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXy5jaGVja0Vycm9yLmdldENvbnN0cnVjdG9yTmFtZShjYXVnaHRFcnIpKSlcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKGVycm9yTGlrZSAmJiBjYXVnaHRFcnIpIHtcbiAgICAgIC8vIFdlIHNob3VsZCBjb21wYXJlIGluc3RhbmNlcyBvbmx5IGlmIGBlcnJvckxpa2VgIGlzIGFuIGluc3RhbmNlIG9mIGBFcnJvcmBcbiAgICAgIGlmIChlcnJvckxpa2UgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICB2YXIgaXNDb21wYXRpYmxlSW5zdGFuY2UgPSBfLmNoZWNrRXJyb3IuY29tcGF0aWJsZUluc3RhbmNlKGNhdWdodEVyciwgZXJyb3JMaWtlKTtcblxuICAgICAgICBpZiAoaXNDb21wYXRpYmxlSW5zdGFuY2UgPT09IG5lZ2F0ZSkge1xuICAgICAgICAgIC8vIFRoZXNlIGNoZWNrcyB3ZXJlIGNyZWF0ZWQgdG8gZW5zdXJlIHdlIHdvbid0IGZhaWwgdG9vIHNvb24gd2hlbiB3ZSd2ZSBnb3QgYm90aCBhcmdzIGFuZCBhIG5lZ2F0ZVxuICAgICAgICAgIC8vIFNlZSBJc3N1ZSAjNTUxIGFuZCBQUiAjNjgzQEdpdEh1YlxuICAgICAgICAgIGlmIChldmVyeUFyZ0lzRGVmaW5lZCAmJiBuZWdhdGUpIHtcbiAgICAgICAgICAgIGVycm9yTGlrZUZhaWwgPSB0cnVlO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICAgICAgICBuZWdhdGVcbiAgICAgICAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byB0aHJvdyAje2V4cH0gYnV0ICN7YWN0fSB3YXMgdGhyb3duJ1xuICAgICAgICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCB0aHJvdyAje2V4cH0nICsgKGNhdWdodEVyciAmJiAhbmVnYXRlID8gJyBidXQgI3thY3R9IHdhcyB0aHJvd24nIDogJycpXG4gICAgICAgICAgICAgICwgZXJyb3JMaWtlLnRvU3RyaW5nKClcbiAgICAgICAgICAgICAgLCBjYXVnaHRFcnIudG9TdHJpbmcoKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdmFyIGlzQ29tcGF0aWJsZUNvbnN0cnVjdG9yID0gXy5jaGVja0Vycm9yLmNvbXBhdGlibGVDb25zdHJ1Y3RvcihjYXVnaHRFcnIsIGVycm9yTGlrZSk7XG4gICAgICBpZiAoaXNDb21wYXRpYmxlQ29uc3RydWN0b3IgPT09IG5lZ2F0ZSkge1xuICAgICAgICBpZiAoZXZlcnlBcmdJc0RlZmluZWQgJiYgbmVnYXRlKSB7XG4gICAgICAgICAgICBlcnJvckxpa2VGYWlsID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICAgICAgbmVnYXRlXG4gICAgICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIHRocm93ICN7ZXhwfSBidXQgI3thY3R9IHdhcyB0aHJvd24nXG4gICAgICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCB0aHJvdyAje2V4cH0nICsgKGNhdWdodEVyciA/ICcgYnV0ICN7YWN0fSB3YXMgdGhyb3duJyA6ICcnKVxuICAgICAgICAgICAgLCAoZXJyb3JMaWtlIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvckxpa2UudG9TdHJpbmcoKSA6IGVycm9yTGlrZSAmJiBfLmNoZWNrRXJyb3IuZ2V0Q29uc3RydWN0b3JOYW1lKGVycm9yTGlrZSkpXG4gICAgICAgICAgICAsIChjYXVnaHRFcnIgaW5zdGFuY2VvZiBFcnJvciA/IGNhdWdodEVyci50b1N0cmluZygpIDogY2F1Z2h0RXJyICYmIF8uY2hlY2tFcnJvci5nZXRDb25zdHJ1Y3Rvck5hbWUoY2F1Z2h0RXJyKSlcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNhdWdodEVyciAmJiBlcnJNc2dNYXRjaGVyICE9PSB1bmRlZmluZWQgJiYgZXJyTXNnTWF0Y2hlciAhPT0gbnVsbCkge1xuICAgICAgLy8gSGVyZSB3ZSBjaGVjayBjb21wYXRpYmxlIG1lc3NhZ2VzXG4gICAgICB2YXIgcGxhY2Vob2xkZXIgPSAnaW5jbHVkaW5nJztcbiAgICAgIGlmIChlcnJNc2dNYXRjaGVyIGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICAgIHBsYWNlaG9sZGVyID0gJ21hdGNoaW5nJ1xuICAgICAgfVxuXG4gICAgICB2YXIgaXNDb21wYXRpYmxlTWVzc2FnZSA9IF8uY2hlY2tFcnJvci5jb21wYXRpYmxlTWVzc2FnZShjYXVnaHRFcnIsIGVyck1zZ01hdGNoZXIpO1xuICAgICAgaWYgKGlzQ29tcGF0aWJsZU1lc3NhZ2UgPT09IG5lZ2F0ZSkge1xuICAgICAgICBpZiAoZXZlcnlBcmdJc0RlZmluZWQgJiYgbmVnYXRlKSB7XG4gICAgICAgICAgICBlcnJNc2dNYXRjaGVyRmFpbCA9IHRydWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgICBuZWdhdGVcbiAgICAgICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gdGhyb3cgZXJyb3IgJyArIHBsYWNlaG9sZGVyICsgJyAje2V4cH0gYnV0IGdvdCAje2FjdH0nXG4gICAgICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIHRocm93IGVycm9yIG5vdCAnICsgcGxhY2Vob2xkZXIgKyAnICN7ZXhwfSdcbiAgICAgICAgICAgICwgIGVyck1zZ01hdGNoZXJcbiAgICAgICAgICAgICwgIF8uY2hlY2tFcnJvci5nZXRNZXNzYWdlKGNhdWdodEVycilcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gSWYgYm90aCBhc3NlcnRpb25zIGZhaWxlZCBhbmQgYm90aCBzaG91bGQndmUgbWF0Y2hlZCB3ZSB0aHJvdyBhbiBlcnJvclxuICAgIGlmIChlcnJvckxpa2VGYWlsICYmIGVyck1zZ01hdGNoZXJGYWlsKSB7XG4gICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgbmVnYXRlXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gdGhyb3cgI3tleHB9IGJ1dCAje2FjdH0gd2FzIHRocm93bidcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgdGhyb3cgI3tleHB9JyArIChjYXVnaHRFcnIgPyAnIGJ1dCAje2FjdH0gd2FzIHRocm93bicgOiAnJylcbiAgICAgICAgLCAoZXJyb3JMaWtlIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvckxpa2UudG9TdHJpbmcoKSA6IGVycm9yTGlrZSAmJiBfLmNoZWNrRXJyb3IuZ2V0Q29uc3RydWN0b3JOYW1lKGVycm9yTGlrZSkpXG4gICAgICAgICwgKGNhdWdodEVyciBpbnN0YW5jZW9mIEVycm9yID8gY2F1Z2h0RXJyLnRvU3RyaW5nKCkgOiBjYXVnaHRFcnIgJiYgXy5jaGVja0Vycm9yLmdldENvbnN0cnVjdG9yTmFtZShjYXVnaHRFcnIpKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICBmbGFnKHRoaXMsICdvYmplY3QnLCBjYXVnaHRFcnIpO1xuICB9O1xuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ3Rocm93JywgYXNzZXJ0VGhyb3dzKTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgndGhyb3dzJywgYXNzZXJ0VGhyb3dzKTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnVGhyb3cnLCBhc3NlcnRUaHJvd3MpO1xuXG4gIC8qKlxuICAgKiAjIyMgLnJlc3BvbmRUbyhtZXRob2RbLCBtc2ddKVxuICAgKlxuICAgKiBXaGVuIHRoZSB0YXJnZXQgaXMgYSBub24tZnVuY3Rpb24gb2JqZWN0LCBgLnJlc3BvbmRUb2AgYXNzZXJ0cyB0aGF0IHRoZVxuICAgKiB0YXJnZXQgaGFzIGEgbWV0aG9kIHdpdGggdGhlIGdpdmVuIG5hbWUgYG1ldGhvZGAuIFRoZSBtZXRob2QgY2FuIGJlIG93biBvclxuICAgKiBpbmhlcml0ZWQsIGFuZCBpdCBjYW4gYmUgZW51bWVyYWJsZSBvciBub24tZW51bWVyYWJsZS5cbiAgICpcbiAgICogICAgIGZ1bmN0aW9uIENhdCAoKSB7fVxuICAgKiAgICAgQ2F0LnByb3RvdHlwZS5tZW93ID0gZnVuY3Rpb24gKCkge307XG4gICAqXG4gICAqICAgICBleHBlY3QobmV3IENhdCgpKS50by5yZXNwb25kVG8oJ21lb3cnKTtcbiAgICpcbiAgICogV2hlbiB0aGUgdGFyZ2V0IGlzIGEgZnVuY3Rpb24sIGAucmVzcG9uZFRvYCBhc3NlcnRzIHRoYXQgdGhlIHRhcmdldCdzXG4gICAqIGBwcm90b3R5cGVgIHByb3BlcnR5IGhhcyBhIG1ldGhvZCB3aXRoIHRoZSBnaXZlbiBuYW1lIGBtZXRob2RgLiBBZ2FpbiwgdGhlXG4gICAqIG1ldGhvZCBjYW4gYmUgb3duIG9yIGluaGVyaXRlZCwgYW5kIGl0IGNhbiBiZSBlbnVtZXJhYmxlIG9yIG5vbi1lbnVtZXJhYmxlLlxuICAgKlxuICAgKiAgICAgZnVuY3Rpb24gQ2F0ICgpIHt9XG4gICAqICAgICBDYXQucHJvdG90eXBlLm1lb3cgPSBmdW5jdGlvbiAoKSB7fTtcbiAgICpcbiAgICogICAgIGV4cGVjdChDYXQpLnRvLnJlc3BvbmRUbygnbWVvdycpO1xuICAgKlxuICAgKiBBZGQgYC5pdHNlbGZgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIGZvcmNlIGAucmVzcG9uZFRvYCB0byB0cmVhdCB0aGVcbiAgICogdGFyZ2V0IGFzIGEgbm9uLWZ1bmN0aW9uIG9iamVjdCwgZXZlbiBpZiBpdCdzIGEgZnVuY3Rpb24uIFRodXMsIGl0IGFzc2VydHNcbiAgICogdGhhdCB0aGUgdGFyZ2V0IGhhcyBhIG1ldGhvZCB3aXRoIHRoZSBnaXZlbiBuYW1lIGBtZXRob2RgLCByYXRoZXIgdGhhblxuICAgKiBhc3NlcnRpbmcgdGhhdCB0aGUgdGFyZ2V0J3MgYHByb3RvdHlwZWAgcHJvcGVydHkgaGFzIGEgbWV0aG9kIHdpdGggdGhlXG4gICAqIGdpdmVuIG5hbWUgYG1ldGhvZGAuXG4gICAqXG4gICAqICAgICBmdW5jdGlvbiBDYXQgKCkge31cbiAgICogICAgIENhdC5wcm90b3R5cGUubWVvdyA9IGZ1bmN0aW9uICgpIHt9O1xuICAgKiAgICAgQ2F0Lmhpc3MgPSBmdW5jdGlvbiAoKSB7fTtcbiAgICpcbiAgICogICAgIGV4cGVjdChDYXQpLml0c2VsZi50by5yZXNwb25kVG8oJ2hpc3MnKS5idXQubm90LnJlc3BvbmRUbygnbWVvdycpO1xuICAgKlxuICAgKiBXaGVuIG5vdCBhZGRpbmcgYC5pdHNlbGZgLCBpdCdzIGltcG9ydGFudCB0byBjaGVjayB0aGUgdGFyZ2V0J3MgdHlwZSBiZWZvcmVcbiAgICogdXNpbmcgYC5yZXNwb25kVG9gLiBTZWUgdGhlIGAuYWAgZG9jIGZvciBpbmZvIG9uIGNoZWNraW5nIGEgdGFyZ2V0J3MgdHlwZS5cbiAgICpcbiAgICogICAgIGZ1bmN0aW9uIENhdCAoKSB7fVxuICAgKiAgICAgQ2F0LnByb3RvdHlwZS5tZW93ID0gZnVuY3Rpb24gKCkge307XG4gICAqXG4gICAqICAgICBleHBlY3QobmV3IENhdCgpKS50by5iZS5hbignb2JqZWN0JykudGhhdC5yZXNwb25kc1RvKCdtZW93Jyk7XG4gICAqXG4gICAqIEFkZCBgLm5vdGAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gbmVnYXRlIGAucmVzcG9uZFRvYC5cbiAgICpcbiAgICogICAgIGZ1bmN0aW9uIERvZyAoKSB7fVxuICAgKiAgICAgRG9nLnByb3RvdHlwZS5iYXJrID0gZnVuY3Rpb24gKCkge307XG4gICAqXG4gICAqICAgICBleHBlY3QobmV3IERvZygpKS50by5ub3QucmVzcG9uZFRvKCdtZW93Jyk7XG4gICAqXG4gICAqIGAucmVzcG9uZFRvYCBhY2NlcHRzIGFuIG9wdGlvbmFsIGBtc2dgIGFyZ3VtZW50IHdoaWNoIGlzIGEgY3VzdG9tIGVycm9yXG4gICAqIG1lc3NhZ2UgdG8gc2hvdyB3aGVuIHRoZSBhc3NlcnRpb24gZmFpbHMuIFRoZSBtZXNzYWdlIGNhbiBhbHNvIGJlIGdpdmVuIGFzXG4gICAqIHRoZSBzZWNvbmQgYXJndW1lbnQgdG8gYGV4cGVjdGAuXG4gICAqXG4gICAqICAgICBleHBlY3Qoe30pLnRvLnJlc3BvbmRUbygnbWVvdycsICdub29vIHdoeSBmYWlsPz8nKTtcbiAgICogICAgIGV4cGVjdCh7fSwgJ25vb28gd2h5IGZhaWw/PycpLnRvLnJlc3BvbmRUbygnbWVvdycpO1xuICAgKlxuICAgKiBUaGUgYWxpYXMgYC5yZXNwb25kc1RvYCBjYW4gYmUgdXNlZCBpbnRlcmNoYW5nZWFibHkgd2l0aCBgLnJlc3BvbmRUb2AuXG4gICAqXG4gICAqIEBuYW1lIHJlc3BvbmRUb1xuICAgKiBAYWxpYXMgcmVzcG9uZHNUb1xuICAgKiBAcGFyYW0ge1N0cmluZ30gbWV0aG9kXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtc2cgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiByZXNwb25kVG8gKG1ldGhvZCwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAsIGl0c2VsZiA9IGZsYWcodGhpcywgJ2l0c2VsZicpXG4gICAgICAsIGNvbnRleHQgPSAoJ2Z1bmN0aW9uJyA9PT0gdHlwZW9mIG9iaiAmJiAhaXRzZWxmKVxuICAgICAgICA/IG9iai5wcm90b3R5cGVbbWV0aG9kXVxuICAgICAgICA6IG9ialttZXRob2RdO1xuXG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICdmdW5jdGlvbicgPT09IHR5cGVvZiBjb250ZXh0XG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIHJlc3BvbmQgdG8gJyArIF8uaW5zcGVjdChtZXRob2QpXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCByZXNwb25kIHRvICcgKyBfLmluc3BlY3QobWV0aG9kKVxuICAgICk7XG4gIH1cblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdyZXNwb25kVG8nLCByZXNwb25kVG8pO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdyZXNwb25kc1RvJywgcmVzcG9uZFRvKTtcblxuICAvKipcbiAgICogIyMjIC5pdHNlbGZcbiAgICpcbiAgICogRm9yY2VzIGFsbCBgLnJlc3BvbmRUb2AgYXNzZXJ0aW9ucyB0aGF0IGZvbGxvdyBpbiB0aGUgY2hhaW4gdG8gYmVoYXZlIGFzIGlmXG4gICAqIHRoZSB0YXJnZXQgaXMgYSBub24tZnVuY3Rpb24gb2JqZWN0LCBldmVuIGlmIGl0J3MgYSBmdW5jdGlvbi4gVGh1cywgaXRcbiAgICogY2F1c2VzIGAucmVzcG9uZFRvYCB0byBhc3NlcnQgdGhhdCB0aGUgdGFyZ2V0IGhhcyBhIG1ldGhvZCB3aXRoIHRoZSBnaXZlblxuICAgKiBuYW1lLCByYXRoZXIgdGhhbiBhc3NlcnRpbmcgdGhhdCB0aGUgdGFyZ2V0J3MgYHByb3RvdHlwZWAgcHJvcGVydHkgaGFzIGFcbiAgICogbWV0aG9kIHdpdGggdGhlIGdpdmVuIG5hbWUuXG4gICAqXG4gICAqICAgICBmdW5jdGlvbiBDYXQgKCkge31cbiAgICogICAgIENhdC5wcm90b3R5cGUubWVvdyA9IGZ1bmN0aW9uICgpIHt9O1xuICAgKiAgICAgQ2F0Lmhpc3MgPSBmdW5jdGlvbiAoKSB7fTtcbiAgICpcbiAgICogICAgIGV4cGVjdChDYXQpLml0c2VsZi50by5yZXNwb25kVG8oJ2hpc3MnKS5idXQubm90LnJlc3BvbmRUbygnbWVvdycpO1xuICAgKlxuICAgKiBAbmFtZSBpdHNlbGZcbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgQXNzZXJ0aW9uLmFkZFByb3BlcnR5KCdpdHNlbGYnLCBmdW5jdGlvbiAoKSB7XG4gICAgZmxhZyh0aGlzLCAnaXRzZWxmJywgdHJ1ZSk7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiAjIyMgLnNhdGlzZnkobWF0Y2hlclssIG1zZ10pXG4gICAqXG4gICAqIEludm9rZXMgdGhlIGdpdmVuIGBtYXRjaGVyYCBmdW5jdGlvbiB3aXRoIHRoZSB0YXJnZXQgYmVpbmcgcGFzc2VkIGFzIHRoZVxuICAgKiBmaXJzdCBhcmd1bWVudCwgYW5kIGFzc2VydHMgdGhhdCB0aGUgdmFsdWUgcmV0dXJuZWQgaXMgdHJ1dGh5LlxuICAgKlxuICAgKiAgICAgZXhwZWN0KDEpLnRvLnNhdGlzZnkoZnVuY3Rpb24obnVtKSB7XG4gICAqICAgICAgIHJldHVybiBudW0gPiAwO1xuICAgKiAgICAgfSk7XG4gICAqXG4gICAqIEFkZCBgLm5vdGAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gbmVnYXRlIGAuc2F0aXNmeWAuXG4gICAqXG4gICAqICAgICBleHBlY3QoMSkudG8ubm90LnNhdGlzZnkoZnVuY3Rpb24obnVtKSB7XG4gICAqICAgICAgIHJldHVybiBudW0gPiAyO1xuICAgKiAgICAgfSk7XG4gICAqXG4gICAqIGAuc2F0aXNmeWAgYWNjZXB0cyBhbiBvcHRpb25hbCBgbXNnYCBhcmd1bWVudCB3aGljaCBpcyBhIGN1c3RvbSBlcnJvclxuICAgKiBtZXNzYWdlIHRvIHNob3cgd2hlbiB0aGUgYXNzZXJ0aW9uIGZhaWxzLiBUaGUgbWVzc2FnZSBjYW4gYWxzbyBiZSBnaXZlbiBhc1xuICAgKiB0aGUgc2Vjb25kIGFyZ3VtZW50IHRvIGBleHBlY3RgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KDEpLnRvLnNhdGlzZnkoZnVuY3Rpb24obnVtKSB7XG4gICAqICAgICAgIHJldHVybiBudW0gPiAyO1xuICAgKiAgICAgfSwgJ25vb28gd2h5IGZhaWw/PycpO1xuICAgKlxuICAgKiAgICAgZXhwZWN0KDEsICdub29vIHdoeSBmYWlsPz8nKS50by5zYXRpc2Z5KGZ1bmN0aW9uKG51bSkge1xuICAgKiAgICAgICByZXR1cm4gbnVtID4gMjtcbiAgICogICAgIH0pO1xuICAgKlxuICAgKiBUaGUgYWxpYXMgYC5zYXRpc2ZpZXNgIGNhbiBiZSB1c2VkIGludGVyY2hhbmdlYWJseSB3aXRoIGAuc2F0aXNmeWAuXG4gICAqXG4gICAqIEBuYW1lIHNhdGlzZnlcbiAgICogQGFsaWFzIHNhdGlzZmllc1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBtYXRjaGVyXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtc2cgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBzYXRpc2Z5IChtYXRjaGVyLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gICAgdmFyIHJlc3VsdCA9IG1hdGNoZXIob2JqKTtcbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgcmVzdWx0XG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIHNhdGlzZnkgJyArIF8ub2JqRGlzcGxheShtYXRjaGVyKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3Qgc2F0aXNmeScgKyBfLm9iakRpc3BsYXkobWF0Y2hlcilcbiAgICAgICwgZmxhZyh0aGlzLCAnbmVnYXRlJykgPyBmYWxzZSA6IHRydWVcbiAgICAgICwgcmVzdWx0XG4gICAgKTtcbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ3NhdGlzZnknLCBzYXRpc2Z5KTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnc2F0aXNmaWVzJywgc2F0aXNmeSk7XG5cbiAgLyoqXG4gICAqICMjIyAuY2xvc2VUbyhleHBlY3RlZCwgZGVsdGFbLCBtc2ddKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBhIG51bWJlciB0aGF0J3Mgd2l0aGluIGEgZ2l2ZW4gKy8tIGBkZWx0YWAgcmFuZ2VcbiAgICogb2YgdGhlIGdpdmVuIG51bWJlciBgZXhwZWN0ZWRgLiBIb3dldmVyLCBpdCdzIG9mdGVuIGJlc3QgdG8gYXNzZXJ0IHRoYXQgdGhlXG4gICAqIHRhcmdldCBpcyBlcXVhbCB0byBpdHMgZXhwZWN0ZWQgdmFsdWUuXG4gICAqXG4gICAqICAgICAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KDEuNSkudG8uZXF1YWwoMS41KTtcbiAgICpcbiAgICogICAgIC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KDEuNSkudG8uYmUuY2xvc2VUbygxLCAwLjUpO1xuICAgKiAgICAgZXhwZWN0KDEuNSkudG8uYmUuY2xvc2VUbygyLCAwLjUpO1xuICAgKiAgICAgZXhwZWN0KDEuNSkudG8uYmUuY2xvc2VUbygxLCAxKTtcbiAgICpcbiAgICogQWRkIGAubm90YCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byBuZWdhdGUgYC5jbG9zZVRvYC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgxLjUpLnRvLmVxdWFsKDEuNSk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoMS41KS50by5ub3QuYmUuY2xvc2VUbygzLCAxKTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqIGAuY2xvc2VUb2AgYWNjZXB0cyBhbiBvcHRpb25hbCBgbXNnYCBhcmd1bWVudCB3aGljaCBpcyBhIGN1c3RvbSBlcnJvclxuICAgKiBtZXNzYWdlIHRvIHNob3cgd2hlbiB0aGUgYXNzZXJ0aW9uIGZhaWxzLiBUaGUgbWVzc2FnZSBjYW4gYWxzbyBiZSBnaXZlbiBhc1xuICAgKiB0aGUgc2Vjb25kIGFyZ3VtZW50IHRvIGBleHBlY3RgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KDEuNSkudG8uYmUuY2xvc2VUbygzLCAxLCAnbm9vbyB3aHkgZmFpbD8/Jyk7XG4gICAqICAgICBleHBlY3QoMS41LCAnbm9vbyB3aHkgZmFpbD8/JykudG8uYmUuY2xvc2VUbygzLCAxKTtcbiAgICpcbiAgICogVGhlIGFsaWFzIGAuYXBwcm94aW1hdGVseWAgY2FuIGJlIHVzZWQgaW50ZXJjaGFuZ2VhYmx5IHdpdGggYC5jbG9zZVRvYC5cbiAgICpcbiAgICogQG5hbWUgY2xvc2VUb1xuICAgKiBAYWxpYXMgYXBwcm94aW1hdGVseVxuICAgKiBAcGFyYW0ge051bWJlcn0gZXhwZWN0ZWRcbiAgICogQHBhcmFtIHtOdW1iZXJ9IGRlbHRhXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtc2cgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBjbG9zZVRvKGV4cGVjdGVkLCBkZWx0YSwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAsIGZsYWdNc2cgPSBmbGFnKHRoaXMsICdtZXNzYWdlJylcbiAgICAgICwgc3NmaSA9IGZsYWcodGhpcywgJ3NzZmknKTtcblxuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBmbGFnTXNnLCBzc2ZpLCB0cnVlKS5pcy5hKCdudW1iZXInKTtcbiAgICBpZiAodHlwZW9mIGV4cGVjdGVkICE9PSAnbnVtYmVyJyB8fCB0eXBlb2YgZGVsdGEgIT09ICdudW1iZXInKSB7XG4gICAgICBmbGFnTXNnID0gZmxhZ01zZyA/IGZsYWdNc2cgKyAnOiAnIDogJyc7XG4gICAgICB2YXIgZGVsdGFNZXNzYWdlID0gZGVsdGEgPT09IHVuZGVmaW5lZCA/IFwiLCBhbmQgYSBkZWx0YSBpcyByZXF1aXJlZFwiIDogXCJcIjtcbiAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihcbiAgICAgICAgICBmbGFnTXNnICsgJ3RoZSBhcmd1bWVudHMgdG8gY2xvc2VUbyBvciBhcHByb3hpbWF0ZWx5IG11c3QgYmUgbnVtYmVycycgKyBkZWx0YU1lc3NhZ2UsXG4gICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgIHNzZmlcbiAgICAgICk7XG4gICAgfVxuXG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICAgIE1hdGguYWJzKG9iaiAtIGV4cGVjdGVkKSA8PSBkZWx0YVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBjbG9zZSB0byAnICsgZXhwZWN0ZWQgKyAnICsvLSAnICsgZGVsdGFcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gbm90IHRvIGJlIGNsb3NlIHRvICcgKyBleHBlY3RlZCArICcgKy8tICcgKyBkZWx0YVxuICAgICk7XG4gIH1cblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdjbG9zZVRvJywgY2xvc2VUbyk7XG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2FwcHJveGltYXRlbHknLCBjbG9zZVRvKTtcblxuICAvLyBOb3RlOiBEdXBsaWNhdGVzIGFyZSBpZ25vcmVkIGlmIHRlc3RpbmcgZm9yIGluY2x1c2lvbiBpbnN0ZWFkIG9mIHNhbWVuZXNzLlxuICBmdW5jdGlvbiBpc1N1YnNldE9mKHN1YnNldCwgc3VwZXJzZXQsIGNtcCwgY29udGFpbnMsIG9yZGVyZWQpIHtcbiAgICBpZiAoIWNvbnRhaW5zKSB7XG4gICAgICBpZiAoc3Vic2V0Lmxlbmd0aCAhPT0gc3VwZXJzZXQubGVuZ3RoKSByZXR1cm4gZmFsc2U7XG4gICAgICBzdXBlcnNldCA9IHN1cGVyc2V0LnNsaWNlKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN1YnNldC5ldmVyeShmdW5jdGlvbihlbGVtLCBpZHgpIHtcbiAgICAgIGlmIChvcmRlcmVkKSByZXR1cm4gY21wID8gY21wKGVsZW0sIHN1cGVyc2V0W2lkeF0pIDogZWxlbSA9PT0gc3VwZXJzZXRbaWR4XTtcblxuICAgICAgaWYgKCFjbXApIHtcbiAgICAgICAgdmFyIG1hdGNoSWR4ID0gc3VwZXJzZXQuaW5kZXhPZihlbGVtKTtcbiAgICAgICAgaWYgKG1hdGNoSWR4ID09PSAtMSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgIC8vIFJlbW92ZSBtYXRjaCBmcm9tIHN1cGVyc2V0IHNvIG5vdCBjb3VudGVkIHR3aWNlIGlmIGR1cGxpY2F0ZSBpbiBzdWJzZXQuXG4gICAgICAgIGlmICghY29udGFpbnMpIHN1cGVyc2V0LnNwbGljZShtYXRjaElkeCwgMSk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gc3VwZXJzZXQuc29tZShmdW5jdGlvbihlbGVtMiwgbWF0Y2hJZHgpIHtcbiAgICAgICAgaWYgKCFjbXAoZWxlbSwgZWxlbTIpKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgLy8gUmVtb3ZlIG1hdGNoIGZyb20gc3VwZXJzZXQgc28gbm90IGNvdW50ZWQgdHdpY2UgaWYgZHVwbGljYXRlIGluIHN1YnNldC5cbiAgICAgICAgaWYgKCFjb250YWlucykgc3VwZXJzZXQuc3BsaWNlKG1hdGNoSWR4LCAxKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiAjIyMgLm1lbWJlcnMoc2V0WywgbXNnXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgYXJyYXkgaGFzIHRoZSBzYW1lIG1lbWJlcnMgYXMgdGhlIGdpdmVuIGFycmF5XG4gICAqIGBzZXRgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KFsxLCAyLCAzXSkudG8uaGF2ZS5tZW1iZXJzKFsyLCAxLCAzXSk7XG4gICAqICAgICBleHBlY3QoWzEsIDIsIDJdKS50by5oYXZlLm1lbWJlcnMoWzIsIDEsIDJdKTtcbiAgICpcbiAgICogQnkgZGVmYXVsdCwgbWVtYmVycyBhcmUgY29tcGFyZWQgdXNpbmcgc3RyaWN0IChgPT09YCkgZXF1YWxpdHkuIEFkZCBgLmRlZXBgXG4gICAqIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIHVzZSBkZWVwIGVxdWFsaXR5IGluc3RlYWQuIFNlZSB0aGUgYGRlZXAtZXFsYFxuICAgKiBwcm9qZWN0IHBhZ2UgZm9yIGluZm8gb24gdGhlIGRlZXAgZXF1YWxpdHkgYWxnb3JpdGhtOlxuICAgKiBodHRwczovL2dpdGh1Yi5jb20vY2hhaWpzL2RlZXAtZXFsLlxuICAgKlxuICAgKiAgICAgLy8gVGFyZ2V0IGFycmF5IGRlZXBseSAoYnV0IG5vdCBzdHJpY3RseSkgaGFzIG1lbWJlciBge2E6IDF9YFxuICAgKiAgICAgZXhwZWN0KFt7YTogMX1dKS50by5oYXZlLmRlZXAubWVtYmVycyhbe2E6IDF9XSk7XG4gICAqICAgICBleHBlY3QoW3thOiAxfV0pLnRvLm5vdC5oYXZlLm1lbWJlcnMoW3thOiAxfV0pO1xuICAgKlxuICAgKiBCeSBkZWZhdWx0LCBvcmRlciBkb2Vzbid0IG1hdHRlci4gQWRkIGAub3JkZXJlZGAgZWFybGllciBpbiB0aGUgY2hhaW4gdG9cbiAgICogcmVxdWlyZSB0aGF0IG1lbWJlcnMgYXBwZWFyIGluIHRoZSBzYW1lIG9yZGVyLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KFsxLCAyLCAzXSkudG8uaGF2ZS5vcmRlcmVkLm1lbWJlcnMoWzEsIDIsIDNdKTtcbiAgICogICAgIGV4cGVjdChbMSwgMiwgM10pLnRvLmhhdmUubWVtYmVycyhbMiwgMSwgM10pXG4gICAqICAgICAgIC5idXQubm90Lm9yZGVyZWQubWVtYmVycyhbMiwgMSwgM10pO1xuICAgKlxuICAgKiBCeSBkZWZhdWx0LCBib3RoIGFycmF5cyBtdXN0IGJlIHRoZSBzYW1lIHNpemUuIEFkZCBgLmluY2x1ZGVgIGVhcmxpZXIgaW5cbiAgICogdGhlIGNoYWluIHRvIHJlcXVpcmUgdGhhdCB0aGUgdGFyZ2V0J3MgbWVtYmVycyBiZSBhIHN1cGVyc2V0IG9mIHRoZVxuICAgKiBleHBlY3RlZCBtZW1iZXJzLiBOb3RlIHRoYXQgZHVwbGljYXRlcyBhcmUgaWdub3JlZCBpbiB0aGUgc3Vic2V0IHdoZW5cbiAgICogYC5pbmNsdWRlYCBpcyBhZGRlZC5cbiAgICpcbiAgICogICAgIC8vIFRhcmdldCBhcnJheSBpcyBhIHN1cGVyc2V0IG9mIFsxLCAyXSBidXQgbm90IGlkZW50aWNhbFxuICAgKiAgICAgZXhwZWN0KFsxLCAyLCAzXSkudG8uaW5jbHVkZS5tZW1iZXJzKFsxLCAyXSk7XG4gICAqICAgICBleHBlY3QoWzEsIDIsIDNdKS50by5ub3QuaGF2ZS5tZW1iZXJzKFsxLCAyXSk7XG4gICAqXG4gICAqICAgICAvLyBEdXBsaWNhdGVzIGluIHRoZSBzdWJzZXQgYXJlIGlnbm9yZWRcbiAgICogICAgIGV4cGVjdChbMSwgMiwgM10pLnRvLmluY2x1ZGUubWVtYmVycyhbMSwgMiwgMiwgMl0pO1xuICAgKlxuICAgKiBgLmRlZXBgLCBgLm9yZGVyZWRgLCBhbmQgYC5pbmNsdWRlYCBjYW4gYWxsIGJlIGNvbWJpbmVkLiBIb3dldmVyLCBpZlxuICAgKiBgLmluY2x1ZGVgIGFuZCBgLm9yZGVyZWRgIGFyZSBjb21iaW5lZCwgdGhlIG9yZGVyaW5nIGJlZ2lucyBhdCB0aGUgc3RhcnQgb2ZcbiAgICogYm90aCBhcnJheXMuXG4gICAqXG4gICAqICAgICBleHBlY3QoW3thOiAxfSwge2I6IDJ9LCB7YzogM31dKVxuICAgKiAgICAgICAudG8uaW5jbHVkZS5kZWVwLm9yZGVyZWQubWVtYmVycyhbe2E6IDF9LCB7YjogMn1dKVxuICAgKiAgICAgICAuYnV0Lm5vdC5pbmNsdWRlLmRlZXAub3JkZXJlZC5tZW1iZXJzKFt7YjogMn0sIHtjOiAzfV0pO1xuICAgKlxuICAgKiBBZGQgYC5ub3RgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIG5lZ2F0ZSBgLm1lbWJlcnNgLiBIb3dldmVyLCBpdCdzXG4gICAqIGRhbmdlcm91cyB0byBkbyBzby4gVGhlIHByb2JsZW0gaXMgdGhhdCBpdCBjcmVhdGVzIHVuY2VydGFpbiBleHBlY3RhdGlvbnNcbiAgICogYnkgYXNzZXJ0aW5nIHRoYXQgdGhlIHRhcmdldCBhcnJheSBkb2Vzbid0IGhhdmUgYWxsIG9mIHRoZSBzYW1lIG1lbWJlcnMgYXNcbiAgICogdGhlIGdpdmVuIGFycmF5IGBzZXRgIGJ1dCBtYXkgb3IgbWF5IG5vdCBoYXZlIHNvbWUgb2YgdGhlbS4gSXQncyBvZnRlbiBiZXN0XG4gICAqIHRvIGlkZW50aWZ5IHRoZSBleGFjdCBvdXRwdXQgdGhhdCdzIGV4cGVjdGVkLCBhbmQgdGhlbiB3cml0ZSBhbiBhc3NlcnRpb25cbiAgICogdGhhdCBvbmx5IGFjY2VwdHMgdGhhdCBleGFjdCBvdXRwdXQuXG4gICAqXG4gICAqICAgICBleHBlY3QoWzEsIDJdKS50by5ub3QuaW5jbHVkZSgzKS5hbmQubm90LmluY2x1ZGUoNCk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoWzEsIDJdKS50by5ub3QuaGF2ZS5tZW1iZXJzKFszLCA0XSk7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBgLm1lbWJlcnNgIGFjY2VwdHMgYW4gb3B0aW9uYWwgYG1zZ2AgYXJndW1lbnQgd2hpY2ggaXMgYSBjdXN0b20gZXJyb3JcbiAgICogbWVzc2FnZSB0byBzaG93IHdoZW4gdGhlIGFzc2VydGlvbiBmYWlscy4gVGhlIG1lc3NhZ2UgY2FuIGFsc28gYmUgZ2l2ZW4gYXNcbiAgICogdGhlIHNlY29uZCBhcmd1bWVudCB0byBgZXhwZWN0YC5cbiAgICpcbiAgICogICAgIGV4cGVjdChbMSwgMl0pLnRvLmhhdmUubWVtYmVycyhbMSwgMiwgM10sICdub29vIHdoeSBmYWlsPz8nKTtcbiAgICogICAgIGV4cGVjdChbMSwgMl0sICdub29vIHdoeSBmYWlsPz8nKS50by5oYXZlLm1lbWJlcnMoWzEsIDIsIDNdKTtcbiAgICpcbiAgICogQG5hbWUgbWVtYmVyc1xuICAgKiBAcGFyYW0ge0FycmF5fSBzZXRcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1zZyBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ21lbWJlcnMnLCBmdW5jdGlvbiAoc3Vic2V0LCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0JylcbiAgICAgICwgZmxhZ01zZyA9IGZsYWcodGhpcywgJ21lc3NhZ2UnKVxuICAgICAgLCBzc2ZpID0gZmxhZyh0aGlzLCAnc3NmaScpO1xuXG4gICAgbmV3IEFzc2VydGlvbihvYmosIGZsYWdNc2csIHNzZmksIHRydWUpLnRvLmJlLmFuKCdhcnJheScpO1xuICAgIG5ldyBBc3NlcnRpb24oc3Vic2V0LCBmbGFnTXNnLCBzc2ZpLCB0cnVlKS50by5iZS5hbignYXJyYXknKTtcblxuICAgIHZhciBjb250YWlucyA9IGZsYWcodGhpcywgJ2NvbnRhaW5zJyk7XG4gICAgdmFyIG9yZGVyZWQgPSBmbGFnKHRoaXMsICdvcmRlcmVkJyk7XG5cbiAgICB2YXIgc3ViamVjdCwgZmFpbE1zZywgZmFpbE5lZ2F0ZU1zZztcblxuICAgIGlmIChjb250YWlucykge1xuICAgICAgc3ViamVjdCA9IG9yZGVyZWQgPyAnYW4gb3JkZXJlZCBzdXBlcnNldCcgOiAnYSBzdXBlcnNldCc7XG4gICAgICBmYWlsTXNnID0gJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgJyArIHN1YmplY3QgKyAnIG9mICN7ZXhwfSc7XG4gICAgICBmYWlsTmVnYXRlTXNnID0gJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGJlICcgKyBzdWJqZWN0ICsgJyBvZiAje2V4cH0nO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdWJqZWN0ID0gb3JkZXJlZCA/ICdvcmRlcmVkIG1lbWJlcnMnIDogJ21lbWJlcnMnO1xuICAgICAgZmFpbE1zZyA9ICdleHBlY3RlZCAje3RoaXN9IHRvIGhhdmUgdGhlIHNhbWUgJyArIHN1YmplY3QgKyAnIGFzICN7ZXhwfSc7XG4gICAgICBmYWlsTmVnYXRlTXNnID0gJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGhhdmUgdGhlIHNhbWUgJyArIHN1YmplY3QgKyAnIGFzICN7ZXhwfSc7XG4gICAgfVxuXG4gICAgdmFyIGNtcCA9IGZsYWcodGhpcywgJ2RlZXAnKSA/IF8uZXFsIDogdW5kZWZpbmVkO1xuXG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICAgIGlzU3Vic2V0T2Yoc3Vic2V0LCBvYmosIGNtcCwgY29udGFpbnMsIG9yZGVyZWQpXG4gICAgICAsIGZhaWxNc2dcbiAgICAgICwgZmFpbE5lZ2F0ZU1zZ1xuICAgICAgLCBzdWJzZXRcbiAgICAgICwgb2JqXG4gICAgICAsIHRydWVcbiAgICApO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC5vbmVPZihsaXN0WywgbXNnXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaXMgYSBtZW1iZXIgb2YgdGhlIGdpdmVuIGFycmF5IGBsaXN0YC4gSG93ZXZlcixcbiAgICogaXQncyBvZnRlbiBiZXN0IHRvIGFzc2VydCB0aGF0IHRoZSB0YXJnZXQgaXMgZXF1YWwgdG8gaXRzIGV4cGVjdGVkIHZhbHVlLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KDEpLnRvLmVxdWFsKDEpOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KDEpLnRvLmJlLm9uZU9mKFsxLCAyLCAzXSk7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBDb21wYXJpc29ucyBhcmUgcGVyZm9ybWVkIHVzaW5nIHN0cmljdCAoYD09PWApIGVxdWFsaXR5LlxuICAgKlxuICAgKiBBZGQgYC5ub3RgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIG5lZ2F0ZSBgLm9uZU9mYC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgxKS50by5lcXVhbCgxKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCgxKS50by5ub3QuYmUub25lT2YoWzIsIDMsIDRdKTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqIEl0IGNhbiBhbHNvIGJlIGNoYWluZWQgd2l0aCBgLmNvbnRhaW5gIG9yIGAuaW5jbHVkZWAsIHdoaWNoIHdpbGwgd29yayB3aXRoXG4gICAqIGJvdGggYXJyYXlzIGFuZCBzdHJpbmdzOlxuICAgKlxuICAgKiAgICAgZXhwZWN0KCdUb2RheSBpcyBzdW5ueScpLnRvLmNvbnRhaW4ub25lT2YoWydzdW5ueScsICdjbG91ZHknXSlcbiAgICogICAgIGV4cGVjdCgnVG9kYXkgaXMgcmFpbnknKS50by5ub3QuY29udGFpbi5vbmVPZihbJ3N1bm55JywgJ2Nsb3VkeSddKVxuICAgKiAgICAgZXhwZWN0KFsxLDIsM10pLnRvLmNvbnRhaW4ub25lT2YoWzMsNCw1XSlcbiAgICogICAgIGV4cGVjdChbMSwyLDNdKS50by5ub3QuY29udGFpbi5vbmVPZihbNCw1LDZdKVxuICAgKlxuICAgKiBgLm9uZU9mYCBhY2NlcHRzIGFuIG9wdGlvbmFsIGBtc2dgIGFyZ3VtZW50IHdoaWNoIGlzIGEgY3VzdG9tIGVycm9yIG1lc3NhZ2VcbiAgICogdG8gc2hvdyB3aGVuIHRoZSBhc3NlcnRpb24gZmFpbHMuIFRoZSBtZXNzYWdlIGNhbiBhbHNvIGJlIGdpdmVuIGFzIHRoZVxuICAgKiBzZWNvbmQgYXJndW1lbnQgdG8gYGV4cGVjdGAuXG4gICAqXG4gICAqICAgICBleHBlY3QoMSkudG8uYmUub25lT2YoWzIsIDMsIDRdLCAnbm9vbyB3aHkgZmFpbD8/Jyk7XG4gICAqICAgICBleHBlY3QoMSwgJ25vb28gd2h5IGZhaWw/PycpLnRvLmJlLm9uZU9mKFsyLCAzLCA0XSk7XG4gICAqXG4gICAqIEBuYW1lIG9uZU9mXG4gICAqIEBwYXJhbSB7QXJyYXk8Kj59IGxpc3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1zZyBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGZ1bmN0aW9uIG9uZU9mIChsaXN0LCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgZXhwZWN0ZWQgPSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCBmbGFnTXNnID0gZmxhZyh0aGlzLCAnbWVzc2FnZScpXG4gICAgICAsIHNzZmkgPSBmbGFnKHRoaXMsICdzc2ZpJylcbiAgICAgICwgY29udGFpbnMgPSBmbGFnKHRoaXMsICdjb250YWlucycpXG4gICAgICAsIGlzRGVlcCA9IGZsYWcodGhpcywgJ2RlZXAnKTtcbiAgICBuZXcgQXNzZXJ0aW9uKGxpc3QsIGZsYWdNc2csIHNzZmksIHRydWUpLnRvLmJlLmFuKCdhcnJheScpO1xuXG4gICAgaWYgKGNvbnRhaW5zKSB7XG4gICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgbGlzdC5zb21lKGZ1bmN0aW9uKHBvc3NpYmlsaXR5KSB7IHJldHVybiBleHBlY3RlZC5pbmRleE9mKHBvc3NpYmlsaXR5KSA+IC0xIH0pXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gY29udGFpbiBvbmUgb2YgI3tleHB9J1xuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBjb250YWluIG9uZSBvZiAje2V4cH0nXG4gICAgICAgICwgbGlzdFxuICAgICAgICAsIGV4cGVjdGVkXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoaXNEZWVwKSB7XG4gICAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgIGxpc3Quc29tZShmdW5jdGlvbihwb3NzaWJpbGl0eSkgeyByZXR1cm4gXy5lcWwoZXhwZWN0ZWQsIHBvc3NpYmlsaXR5KSB9KVxuICAgICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gZGVlcGx5IGVxdWFsIG9uZSBvZiAje2V4cH0nXG4gICAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBkZWVwbHkgZXF1YWwgb25lIG9mICN7ZXhwfSdcbiAgICAgICAgICAsIGxpc3RcbiAgICAgICAgICAsIGV4cGVjdGVkXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICBsaXN0LmluZGV4T2YoZXhwZWN0ZWQpID4gLTFcbiAgICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIG9uZSBvZiAje2V4cH0nXG4gICAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgYmUgb25lIG9mICN7ZXhwfSdcbiAgICAgICAgICAsIGxpc3RcbiAgICAgICAgICAsIGV4cGVjdGVkXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnb25lT2YnLCBvbmVPZik7XG5cbiAgLyoqXG4gICAqICMjIyAuY2hhbmdlKHN1YmplY3RbLCBwcm9wWywgbXNnXV0pXG4gICAqXG4gICAqIFdoZW4gb25lIGFyZ3VtZW50IGlzIHByb3ZpZGVkLCBgLmNoYW5nZWAgYXNzZXJ0cyB0aGF0IHRoZSBnaXZlbiBmdW5jdGlvblxuICAgKiBgc3ViamVjdGAgcmV0dXJucyBhIGRpZmZlcmVudCB2YWx1ZSB3aGVuIGl0J3MgaW52b2tlZCBiZWZvcmUgdGhlIHRhcmdldFxuICAgKiBmdW5jdGlvbiBjb21wYXJlZCB0byB3aGVuIGl0J3MgaW52b2tlZCBhZnRlcndhcmQuIEhvd2V2ZXIsIGl0J3Mgb2Z0ZW4gYmVzdFxuICAgKiB0byBhc3NlcnQgdGhhdCBgc3ViamVjdGAgaXMgZXF1YWwgdG8gaXRzIGV4cGVjdGVkIHZhbHVlLlxuICAgKlxuICAgKiAgICAgdmFyIGRvdHMgPSAnJ1xuICAgKiAgICAgICAsIGFkZERvdCA9IGZ1bmN0aW9uICgpIHsgZG90cyArPSAnLic7IH1cbiAgICogICAgICAgLCBnZXREb3RzID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gZG90czsgfTtcbiAgICpcbiAgICogICAgIC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoZ2V0RG90cygpKS50by5lcXVhbCgnJyk7XG4gICAqICAgICBhZGREb3QoKTtcbiAgICogICAgIGV4cGVjdChnZXREb3RzKCkpLnRvLmVxdWFsKCcuJyk7XG4gICAqXG4gICAqICAgICAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdChhZGREb3QpLnRvLmNoYW5nZShnZXREb3RzKTtcbiAgICpcbiAgICogV2hlbiB0d28gYXJndW1lbnRzIGFyZSBwcm92aWRlZCwgYC5jaGFuZ2VgIGFzc2VydHMgdGhhdCB0aGUgdmFsdWUgb2YgdGhlXG4gICAqIGdpdmVuIG9iamVjdCBgc3ViamVjdGAncyBgcHJvcGAgcHJvcGVydHkgaXMgZGlmZmVyZW50IGJlZm9yZSBpbnZva2luZyB0aGVcbiAgICogdGFyZ2V0IGZ1bmN0aW9uIGNvbXBhcmVkIHRvIGFmdGVyd2FyZC5cbiAgICpcbiAgICogICAgIHZhciBteU9iaiA9IHtkb3RzOiAnJ31cbiAgICogICAgICAgLCBhZGREb3QgPSBmdW5jdGlvbiAoKSB7IG15T2JqLmRvdHMgKz0gJy4nOyB9O1xuICAgKlxuICAgKiAgICAgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdChteU9iaikudG8uaGF2ZS5wcm9wZXJ0eSgnZG90cycsICcnKTtcbiAgICogICAgIGFkZERvdCgpO1xuICAgKiAgICAgZXhwZWN0KG15T2JqKS50by5oYXZlLnByb3BlcnR5KCdkb3RzJywgJy4nKTtcbiAgICpcbiAgICogICAgIC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KGFkZERvdCkudG8uY2hhbmdlKG15T2JqLCAnZG90cycpO1xuICAgKlxuICAgKiBTdHJpY3QgKGA9PT1gKSBlcXVhbGl0eSBpcyB1c2VkIHRvIGNvbXBhcmUgYmVmb3JlIGFuZCBhZnRlciB2YWx1ZXMuXG4gICAqXG4gICAqIEFkZCBgLm5vdGAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gbmVnYXRlIGAuY2hhbmdlYC5cbiAgICpcbiAgICogICAgIHZhciBkb3RzID0gJydcbiAgICogICAgICAgLCBub29wID0gZnVuY3Rpb24gKCkge31cbiAgICogICAgICAgLCBnZXREb3RzID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gZG90czsgfTtcbiAgICpcbiAgICogICAgIGV4cGVjdChub29wKS50by5ub3QuY2hhbmdlKGdldERvdHMpO1xuICAgKlxuICAgKiAgICAgdmFyIG15T2JqID0ge2RvdHM6ICcnfVxuICAgKiAgICAgICAsIG5vb3AgPSBmdW5jdGlvbiAoKSB7fTtcbiAgICpcbiAgICogICAgIGV4cGVjdChub29wKS50by5ub3QuY2hhbmdlKG15T2JqLCAnZG90cycpO1xuICAgKlxuICAgKiBgLmNoYW5nZWAgYWNjZXB0cyBhbiBvcHRpb25hbCBgbXNnYCBhcmd1bWVudCB3aGljaCBpcyBhIGN1c3RvbSBlcnJvclxuICAgKiBtZXNzYWdlIHRvIHNob3cgd2hlbiB0aGUgYXNzZXJ0aW9uIGZhaWxzLiBUaGUgbWVzc2FnZSBjYW4gYWxzbyBiZSBnaXZlbiBhc1xuICAgKiB0aGUgc2Vjb25kIGFyZ3VtZW50IHRvIGBleHBlY3RgLiBXaGVuIG5vdCBwcm92aWRpbmcgdHdvIGFyZ3VtZW50cywgYWx3YXlzXG4gICAqIHVzZSB0aGUgc2Vjb25kIGZvcm0uXG4gICAqXG4gICAqICAgICB2YXIgbXlPYmogPSB7ZG90czogJyd9XG4gICAqICAgICAgICwgYWRkRG90ID0gZnVuY3Rpb24gKCkgeyBteU9iai5kb3RzICs9ICcuJzsgfTtcbiAgICpcbiAgICogICAgIGV4cGVjdChhZGREb3QpLnRvLm5vdC5jaGFuZ2UobXlPYmosICdkb3RzJywgJ25vb28gd2h5IGZhaWw/PycpO1xuICAgKlxuICAgKiAgICAgdmFyIGRvdHMgPSAnJ1xuICAgKiAgICAgICAsIGFkZERvdCA9IGZ1bmN0aW9uICgpIHsgZG90cyArPSAnLic7IH1cbiAgICogICAgICAgLCBnZXREb3RzID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gZG90czsgfTtcbiAgICpcbiAgICogICAgIGV4cGVjdChhZGREb3QsICdub29vIHdoeSBmYWlsPz8nKS50by5ub3QuY2hhbmdlKGdldERvdHMpO1xuICAgKlxuICAgKiBgLmNoYW5nZWAgYWxzbyBjYXVzZXMgYWxsIGAuYnlgIGFzc2VydGlvbnMgdGhhdCBmb2xsb3cgaW4gdGhlIGNoYWluIHRvXG4gICAqIGFzc2VydCBob3cgbXVjaCBhIG51bWVyaWMgc3ViamVjdCB3YXMgaW5jcmVhc2VkIG9yIGRlY3JlYXNlZCBieS4gSG93ZXZlcixcbiAgICogaXQncyBkYW5nZXJvdXMgdG8gdXNlIGAuY2hhbmdlLmJ5YC4gVGhlIHByb2JsZW0gaXMgdGhhdCBpdCBjcmVhdGVzXG4gICAqIHVuY2VydGFpbiBleHBlY3RhdGlvbnMgYnkgYXNzZXJ0aW5nIHRoYXQgdGhlIHN1YmplY3QgZWl0aGVyIGluY3JlYXNlcyBieVxuICAgKiB0aGUgZ2l2ZW4gZGVsdGEsIG9yIHRoYXQgaXQgZGVjcmVhc2VzIGJ5IHRoZSBnaXZlbiBkZWx0YS4gSXQncyBvZnRlbiBiZXN0XG4gICAqIHRvIGlkZW50aWZ5IHRoZSBleGFjdCBvdXRwdXQgdGhhdCdzIGV4cGVjdGVkLCBhbmQgdGhlbiB3cml0ZSBhbiBhc3NlcnRpb25cbiAgICogdGhhdCBvbmx5IGFjY2VwdHMgdGhhdCBleGFjdCBvdXRwdXQuXG4gICAqXG4gICAqICAgICB2YXIgbXlPYmogPSB7dmFsOiAxfVxuICAgKiAgICAgICAsIGFkZFR3byA9IGZ1bmN0aW9uICgpIHsgbXlPYmoudmFsICs9IDI7IH1cbiAgICogICAgICAgLCBzdWJ0cmFjdFR3byA9IGZ1bmN0aW9uICgpIHsgbXlPYmoudmFsIC09IDI7IH07XG4gICAqXG4gICAqICAgICBleHBlY3QoYWRkVHdvKS50by5pbmNyZWFzZShteU9iaiwgJ3ZhbCcpLmJ5KDIpOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KGFkZFR3bykudG8uY2hhbmdlKG15T2JqLCAndmFsJykuYnkoMik7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiAgICAgZXhwZWN0KHN1YnRyYWN0VHdvKS50by5kZWNyZWFzZShteU9iaiwgJ3ZhbCcpLmJ5KDIpOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KHN1YnRyYWN0VHdvKS50by5jaGFuZ2UobXlPYmosICd2YWwnKS5ieSgyKTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqIFRoZSBhbGlhcyBgLmNoYW5nZXNgIGNhbiBiZSB1c2VkIGludGVyY2hhbmdlYWJseSB3aXRoIGAuY2hhbmdlYC5cbiAgICpcbiAgICogQG5hbWUgY2hhbmdlXG4gICAqIEBhbGlhcyBjaGFuZ2VzXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBzdWJqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wIG5hbWUgX29wdGlvbmFsX1xuICAgKiBAcGFyYW0ge1N0cmluZ30gbXNnIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gYXNzZXJ0Q2hhbmdlcyAoc3ViamVjdCwgcHJvcCwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gICAgdmFyIGZuID0gZmxhZyh0aGlzLCAnb2JqZWN0JylcbiAgICAgICwgZmxhZ01zZyA9IGZsYWcodGhpcywgJ21lc3NhZ2UnKVxuICAgICAgLCBzc2ZpID0gZmxhZyh0aGlzLCAnc3NmaScpO1xuICAgIG5ldyBBc3NlcnRpb24oZm4sIGZsYWdNc2csIHNzZmksIHRydWUpLmlzLmEoJ2Z1bmN0aW9uJyk7XG5cbiAgICB2YXIgaW5pdGlhbDtcbiAgICBpZiAoIXByb3ApIHtcbiAgICAgIG5ldyBBc3NlcnRpb24oc3ViamVjdCwgZmxhZ01zZywgc3NmaSwgdHJ1ZSkuaXMuYSgnZnVuY3Rpb24nKTtcbiAgICAgIGluaXRpYWwgPSBzdWJqZWN0KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5ldyBBc3NlcnRpb24oc3ViamVjdCwgZmxhZ01zZywgc3NmaSwgdHJ1ZSkudG8uaGF2ZS5wcm9wZXJ0eShwcm9wKTtcbiAgICAgIGluaXRpYWwgPSBzdWJqZWN0W3Byb3BdO1xuICAgIH1cblxuICAgIGZuKCk7XG5cbiAgICB2YXIgZmluYWwgPSBwcm9wID09PSB1bmRlZmluZWQgfHwgcHJvcCA9PT0gbnVsbCA/IHN1YmplY3QoKSA6IHN1YmplY3RbcHJvcF07XG4gICAgdmFyIG1zZ09iaiA9IHByb3AgPT09IHVuZGVmaW5lZCB8fCBwcm9wID09PSBudWxsID8gaW5pdGlhbCA6ICcuJyArIHByb3A7XG5cbiAgICAvLyBUaGlzIGdldHMgZmxhZ2dlZCBiZWNhdXNlIG9mIHRoZSAuYnkoZGVsdGEpIGFzc2VydGlvblxuICAgIGZsYWcodGhpcywgJ2RlbHRhTXNnT2JqJywgbXNnT2JqKTtcbiAgICBmbGFnKHRoaXMsICdpbml0aWFsRGVsdGFWYWx1ZScsIGluaXRpYWwpO1xuICAgIGZsYWcodGhpcywgJ2ZpbmFsRGVsdGFWYWx1ZScsIGZpbmFsKTtcbiAgICBmbGFnKHRoaXMsICdkZWx0YUJlaGF2aW9yJywgJ2NoYW5nZScpO1xuICAgIGZsYWcodGhpcywgJ3JlYWxEZWx0YScsIGZpbmFsICE9PSBpbml0aWFsKTtcblxuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgaW5pdGlhbCAhPT0gZmluYWxcbiAgICAgICwgJ2V4cGVjdGVkICcgKyBtc2dPYmogKyAnIHRvIGNoYW5nZSdcbiAgICAgICwgJ2V4cGVjdGVkICcgKyBtc2dPYmogKyAnIHRvIG5vdCBjaGFuZ2UnXG4gICAgKTtcbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2NoYW5nZScsIGFzc2VydENoYW5nZXMpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdjaGFuZ2VzJywgYXNzZXJ0Q2hhbmdlcyk7XG5cbiAgLyoqXG4gICAqICMjIyAuaW5jcmVhc2Uoc3ViamVjdFssIHByb3BbLCBtc2ddXSlcbiAgICpcbiAgICogV2hlbiBvbmUgYXJndW1lbnQgaXMgcHJvdmlkZWQsIGAuaW5jcmVhc2VgIGFzc2VydHMgdGhhdCB0aGUgZ2l2ZW4gZnVuY3Rpb25cbiAgICogYHN1YmplY3RgIHJldHVybnMgYSBncmVhdGVyIG51bWJlciB3aGVuIGl0J3MgaW52b2tlZCBhZnRlciBpbnZva2luZyB0aGVcbiAgICogdGFyZ2V0IGZ1bmN0aW9uIGNvbXBhcmVkIHRvIHdoZW4gaXQncyBpbnZva2VkIGJlZm9yZWhhbmQuIGAuaW5jcmVhc2VgIGFsc29cbiAgICogY2F1c2VzIGFsbCBgLmJ5YCBhc3NlcnRpb25zIHRoYXQgZm9sbG93IGluIHRoZSBjaGFpbiB0byBhc3NlcnQgaG93IG11Y2hcbiAgICogZ3JlYXRlciBvZiBhIG51bWJlciBpcyByZXR1cm5lZC4gSXQncyBvZnRlbiBiZXN0IHRvIGFzc2VydCB0aGF0IHRoZSByZXR1cm5cbiAgICogdmFsdWUgaW5jcmVhc2VkIGJ5IHRoZSBleHBlY3RlZCBhbW91bnQsIHJhdGhlciB0aGFuIGFzc2VydGluZyBpdCBpbmNyZWFzZWRcbiAgICogYnkgYW55IGFtb3VudC5cbiAgICpcbiAgICogICAgIHZhciB2YWwgPSAxXG4gICAqICAgICAgICwgYWRkVHdvID0gZnVuY3Rpb24gKCkgeyB2YWwgKz0gMjsgfVxuICAgKiAgICAgICAsIGdldFZhbCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHZhbDsgfTtcbiAgICpcbiAgICogICAgIGV4cGVjdChhZGRUd28pLnRvLmluY3JlYXNlKGdldFZhbCkuYnkoMik7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoYWRkVHdvKS50by5pbmNyZWFzZShnZXRWYWwpOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogV2hlbiB0d28gYXJndW1lbnRzIGFyZSBwcm92aWRlZCwgYC5pbmNyZWFzZWAgYXNzZXJ0cyB0aGF0IHRoZSB2YWx1ZSBvZiB0aGVcbiAgICogZ2l2ZW4gb2JqZWN0IGBzdWJqZWN0YCdzIGBwcm9wYCBwcm9wZXJ0eSBpcyBncmVhdGVyIGFmdGVyIGludm9raW5nIHRoZVxuICAgKiB0YXJnZXQgZnVuY3Rpb24gY29tcGFyZWQgdG8gYmVmb3JlaGFuZC5cbiAgICpcbiAgICogICAgIHZhciBteU9iaiA9IHt2YWw6IDF9XG4gICAqICAgICAgICwgYWRkVHdvID0gZnVuY3Rpb24gKCkgeyBteU9iai52YWwgKz0gMjsgfTtcbiAgICpcbiAgICogICAgIGV4cGVjdChhZGRUd28pLnRvLmluY3JlYXNlKG15T2JqLCAndmFsJykuYnkoMik7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoYWRkVHdvKS50by5pbmNyZWFzZShteU9iaiwgJ3ZhbCcpOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogQWRkIGAubm90YCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byBuZWdhdGUgYC5pbmNyZWFzZWAuIEhvd2V2ZXIsIGl0J3NcbiAgICogZGFuZ2Vyb3VzIHRvIGRvIHNvLiBUaGUgcHJvYmxlbSBpcyB0aGF0IGl0IGNyZWF0ZXMgdW5jZXJ0YWluIGV4cGVjdGF0aW9uc1xuICAgKiBieSBhc3NlcnRpbmcgdGhhdCB0aGUgc3ViamVjdCBlaXRoZXIgZGVjcmVhc2VzLCBvciB0aGF0IGl0IHN0YXlzIHRoZSBzYW1lLlxuICAgKiBJdCdzIG9mdGVuIGJlc3QgdG8gaWRlbnRpZnkgdGhlIGV4YWN0IG91dHB1dCB0aGF0J3MgZXhwZWN0ZWQsIGFuZCB0aGVuXG4gICAqIHdyaXRlIGFuIGFzc2VydGlvbiB0aGF0IG9ubHkgYWNjZXB0cyB0aGF0IGV4YWN0IG91dHB1dC5cbiAgICpcbiAgICogV2hlbiB0aGUgc3ViamVjdCBpcyBleHBlY3RlZCB0byBkZWNyZWFzZSwgaXQncyBvZnRlbiBiZXN0IHRvIGFzc2VydCB0aGF0IGl0XG4gICAqIGRlY3JlYXNlZCBieSB0aGUgZXhwZWN0ZWQgYW1vdW50LlxuICAgKlxuICAgKiAgICAgdmFyIG15T2JqID0ge3ZhbDogMX1cbiAgICogICAgICAgLCBzdWJ0cmFjdFR3byA9IGZ1bmN0aW9uICgpIHsgbXlPYmoudmFsIC09IDI7IH07XG4gICAqXG4gICAqICAgICBleHBlY3Qoc3VidHJhY3RUd28pLnRvLmRlY3JlYXNlKG15T2JqLCAndmFsJykuYnkoMik7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3Qoc3VidHJhY3RUd28pLnRvLm5vdC5pbmNyZWFzZShteU9iaiwgJ3ZhbCcpOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogV2hlbiB0aGUgc3ViamVjdCBpcyBleHBlY3RlZCB0byBzdGF5IHRoZSBzYW1lLCBpdCdzIG9mdGVuIGJlc3QgdG8gYXNzZXJ0XG4gICAqIGV4YWN0bHkgdGhhdC5cbiAgICpcbiAgICogICAgIHZhciBteU9iaiA9IHt2YWw6IDF9XG4gICAqICAgICAgICwgbm9vcCA9IGZ1bmN0aW9uICgpIHt9O1xuICAgKlxuICAgKiAgICAgZXhwZWN0KG5vb3ApLnRvLm5vdC5jaGFuZ2UobXlPYmosICd2YWwnKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdChub29wKS50by5ub3QuaW5jcmVhc2UobXlPYmosICd2YWwnKTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqIGAuaW5jcmVhc2VgIGFjY2VwdHMgYW4gb3B0aW9uYWwgYG1zZ2AgYXJndW1lbnQgd2hpY2ggaXMgYSBjdXN0b20gZXJyb3JcbiAgICogbWVzc2FnZSB0byBzaG93IHdoZW4gdGhlIGFzc2VydGlvbiBmYWlscy4gVGhlIG1lc3NhZ2UgY2FuIGFsc28gYmUgZ2l2ZW4gYXNcbiAgICogdGhlIHNlY29uZCBhcmd1bWVudCB0byBgZXhwZWN0YC4gV2hlbiBub3QgcHJvdmlkaW5nIHR3byBhcmd1bWVudHMsIGFsd2F5c1xuICAgKiB1c2UgdGhlIHNlY29uZCBmb3JtLlxuICAgKlxuICAgKiAgICAgdmFyIG15T2JqID0ge3ZhbDogMX1cbiAgICogICAgICAgLCBub29wID0gZnVuY3Rpb24gKCkge307XG4gICAqXG4gICAqICAgICBleHBlY3Qobm9vcCkudG8uaW5jcmVhc2UobXlPYmosICd2YWwnLCAnbm9vbyB3aHkgZmFpbD8/Jyk7XG4gICAqXG4gICAqICAgICB2YXIgdmFsID0gMVxuICAgKiAgICAgICAsIG5vb3AgPSBmdW5jdGlvbiAoKSB7fVxuICAgKiAgICAgICAsIGdldFZhbCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHZhbDsgfTtcbiAgICpcbiAgICogICAgIGV4cGVjdChub29wLCAnbm9vbyB3aHkgZmFpbD8/JykudG8uaW5jcmVhc2UoZ2V0VmFsKTtcbiAgICpcbiAgICogVGhlIGFsaWFzIGAuaW5jcmVhc2VzYCBjYW4gYmUgdXNlZCBpbnRlcmNoYW5nZWFibHkgd2l0aCBgLmluY3JlYXNlYC5cbiAgICpcbiAgICogQG5hbWUgaW5jcmVhc2VcbiAgICogQGFsaWFzIGluY3JlYXNlc1xuICAgKiBAcGFyYW0ge1N0cmluZ3xGdW5jdGlvbn0gc3ViamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcCBuYW1lIF9vcHRpb25hbF9cbiAgICogQHBhcmFtIHtTdHJpbmd9IG1zZyBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGFzc2VydEluY3JlYXNlcyAoc3ViamVjdCwgcHJvcCwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gICAgdmFyIGZuID0gZmxhZyh0aGlzLCAnb2JqZWN0JylcbiAgICAgICwgZmxhZ01zZyA9IGZsYWcodGhpcywgJ21lc3NhZ2UnKVxuICAgICAgLCBzc2ZpID0gZmxhZyh0aGlzLCAnc3NmaScpO1xuICAgIG5ldyBBc3NlcnRpb24oZm4sIGZsYWdNc2csIHNzZmksIHRydWUpLmlzLmEoJ2Z1bmN0aW9uJyk7XG5cbiAgICB2YXIgaW5pdGlhbDtcbiAgICBpZiAoIXByb3ApIHtcbiAgICAgIG5ldyBBc3NlcnRpb24oc3ViamVjdCwgZmxhZ01zZywgc3NmaSwgdHJ1ZSkuaXMuYSgnZnVuY3Rpb24nKTtcbiAgICAgIGluaXRpYWwgPSBzdWJqZWN0KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5ldyBBc3NlcnRpb24oc3ViamVjdCwgZmxhZ01zZywgc3NmaSwgdHJ1ZSkudG8uaGF2ZS5wcm9wZXJ0eShwcm9wKTtcbiAgICAgIGluaXRpYWwgPSBzdWJqZWN0W3Byb3BdO1xuICAgIH1cblxuICAgIC8vIE1ha2Ugc3VyZSB0aGF0IHRoZSB0YXJnZXQgaXMgYSBudW1iZXJcbiAgICBuZXcgQXNzZXJ0aW9uKGluaXRpYWwsIGZsYWdNc2csIHNzZmksIHRydWUpLmlzLmEoJ251bWJlcicpO1xuXG4gICAgZm4oKTtcblxuICAgIHZhciBmaW5hbCA9IHByb3AgPT09IHVuZGVmaW5lZCB8fCBwcm9wID09PSBudWxsID8gc3ViamVjdCgpIDogc3ViamVjdFtwcm9wXTtcbiAgICB2YXIgbXNnT2JqID0gcHJvcCA9PT0gdW5kZWZpbmVkIHx8IHByb3AgPT09IG51bGwgPyBpbml0aWFsIDogJy4nICsgcHJvcDtcblxuICAgIGZsYWcodGhpcywgJ2RlbHRhTXNnT2JqJywgbXNnT2JqKTtcbiAgICBmbGFnKHRoaXMsICdpbml0aWFsRGVsdGFWYWx1ZScsIGluaXRpYWwpO1xuICAgIGZsYWcodGhpcywgJ2ZpbmFsRGVsdGFWYWx1ZScsIGZpbmFsKTtcbiAgICBmbGFnKHRoaXMsICdkZWx0YUJlaGF2aW9yJywgJ2luY3JlYXNlJyk7XG4gICAgZmxhZyh0aGlzLCAncmVhbERlbHRhJywgZmluYWwgLSBpbml0aWFsKTtcblxuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgZmluYWwgLSBpbml0aWFsID4gMFxuICAgICAgLCAnZXhwZWN0ZWQgJyArIG1zZ09iaiArICcgdG8gaW5jcmVhc2UnXG4gICAgICAsICdleHBlY3RlZCAnICsgbXNnT2JqICsgJyB0byBub3QgaW5jcmVhc2UnXG4gICAgKTtcbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2luY3JlYXNlJywgYXNzZXJ0SW5jcmVhc2VzKTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnaW5jcmVhc2VzJywgYXNzZXJ0SW5jcmVhc2VzKTtcblxuICAvKipcbiAgICogIyMjIC5kZWNyZWFzZShzdWJqZWN0WywgcHJvcFssIG1zZ11dKVxuICAgKlxuICAgKiBXaGVuIG9uZSBhcmd1bWVudCBpcyBwcm92aWRlZCwgYC5kZWNyZWFzZWAgYXNzZXJ0cyB0aGF0IHRoZSBnaXZlbiBmdW5jdGlvblxuICAgKiBgc3ViamVjdGAgcmV0dXJucyBhIGxlc3NlciBudW1iZXIgd2hlbiBpdCdzIGludm9rZWQgYWZ0ZXIgaW52b2tpbmcgdGhlXG4gICAqIHRhcmdldCBmdW5jdGlvbiBjb21wYXJlZCB0byB3aGVuIGl0J3MgaW52b2tlZCBiZWZvcmVoYW5kLiBgLmRlY3JlYXNlYCBhbHNvXG4gICAqIGNhdXNlcyBhbGwgYC5ieWAgYXNzZXJ0aW9ucyB0aGF0IGZvbGxvdyBpbiB0aGUgY2hhaW4gdG8gYXNzZXJ0IGhvdyBtdWNoXG4gICAqIGxlc3NlciBvZiBhIG51bWJlciBpcyByZXR1cm5lZC4gSXQncyBvZnRlbiBiZXN0IHRvIGFzc2VydCB0aGF0IHRoZSByZXR1cm5cbiAgICogdmFsdWUgZGVjcmVhc2VkIGJ5IHRoZSBleHBlY3RlZCBhbW91bnQsIHJhdGhlciB0aGFuIGFzc2VydGluZyBpdCBkZWNyZWFzZWRcbiAgICogYnkgYW55IGFtb3VudC5cbiAgICpcbiAgICogICAgIHZhciB2YWwgPSAxXG4gICAqICAgICAgICwgc3VidHJhY3RUd28gPSBmdW5jdGlvbiAoKSB7IHZhbCAtPSAyOyB9XG4gICAqICAgICAgICwgZ2V0VmFsID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdmFsOyB9O1xuICAgKlxuICAgKiAgICAgZXhwZWN0KHN1YnRyYWN0VHdvKS50by5kZWNyZWFzZShnZXRWYWwpLmJ5KDIpOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KHN1YnRyYWN0VHdvKS50by5kZWNyZWFzZShnZXRWYWwpOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogV2hlbiB0d28gYXJndW1lbnRzIGFyZSBwcm92aWRlZCwgYC5kZWNyZWFzZWAgYXNzZXJ0cyB0aGF0IHRoZSB2YWx1ZSBvZiB0aGVcbiAgICogZ2l2ZW4gb2JqZWN0IGBzdWJqZWN0YCdzIGBwcm9wYCBwcm9wZXJ0eSBpcyBsZXNzZXIgYWZ0ZXIgaW52b2tpbmcgdGhlXG4gICAqIHRhcmdldCBmdW5jdGlvbiBjb21wYXJlZCB0byBiZWZvcmVoYW5kLlxuICAgKlxuICAgKiAgICAgdmFyIG15T2JqID0ge3ZhbDogMX1cbiAgICogICAgICAgLCBzdWJ0cmFjdFR3byA9IGZ1bmN0aW9uICgpIHsgbXlPYmoudmFsIC09IDI7IH07XG4gICAqXG4gICAqICAgICBleHBlY3Qoc3VidHJhY3RUd28pLnRvLmRlY3JlYXNlKG15T2JqLCAndmFsJykuYnkoMik7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3Qoc3VidHJhY3RUd28pLnRvLmRlY3JlYXNlKG15T2JqLCAndmFsJyk7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBBZGQgYC5ub3RgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIG5lZ2F0ZSBgLmRlY3JlYXNlYC4gSG93ZXZlciwgaXQnc1xuICAgKiBkYW5nZXJvdXMgdG8gZG8gc28uIFRoZSBwcm9ibGVtIGlzIHRoYXQgaXQgY3JlYXRlcyB1bmNlcnRhaW4gZXhwZWN0YXRpb25zXG4gICAqIGJ5IGFzc2VydGluZyB0aGF0IHRoZSBzdWJqZWN0IGVpdGhlciBpbmNyZWFzZXMsIG9yIHRoYXQgaXQgc3RheXMgdGhlIHNhbWUuXG4gICAqIEl0J3Mgb2Z0ZW4gYmVzdCB0byBpZGVudGlmeSB0aGUgZXhhY3Qgb3V0cHV0IHRoYXQncyBleHBlY3RlZCwgYW5kIHRoZW5cbiAgICogd3JpdGUgYW4gYXNzZXJ0aW9uIHRoYXQgb25seSBhY2NlcHRzIHRoYXQgZXhhY3Qgb3V0cHV0LlxuICAgKlxuICAgKiBXaGVuIHRoZSBzdWJqZWN0IGlzIGV4cGVjdGVkIHRvIGluY3JlYXNlLCBpdCdzIG9mdGVuIGJlc3QgdG8gYXNzZXJ0IHRoYXQgaXRcbiAgICogaW5jcmVhc2VkIGJ5IHRoZSBleHBlY3RlZCBhbW91bnQuXG4gICAqXG4gICAqICAgICB2YXIgbXlPYmogPSB7dmFsOiAxfVxuICAgKiAgICAgICAsIGFkZFR3byA9IGZ1bmN0aW9uICgpIHsgbXlPYmoudmFsICs9IDI7IH07XG4gICAqXG4gICAqICAgICBleHBlY3QoYWRkVHdvKS50by5pbmNyZWFzZShteU9iaiwgJ3ZhbCcpLmJ5KDIpOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KGFkZFR3bykudG8ubm90LmRlY3JlYXNlKG15T2JqLCAndmFsJyk7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBXaGVuIHRoZSBzdWJqZWN0IGlzIGV4cGVjdGVkIHRvIHN0YXkgdGhlIHNhbWUsIGl0J3Mgb2Z0ZW4gYmVzdCB0byBhc3NlcnRcbiAgICogZXhhY3RseSB0aGF0LlxuICAgKlxuICAgKiAgICAgdmFyIG15T2JqID0ge3ZhbDogMX1cbiAgICogICAgICAgLCBub29wID0gZnVuY3Rpb24gKCkge307XG4gICAqXG4gICAqICAgICBleHBlY3Qobm9vcCkudG8ubm90LmNoYW5nZShteU9iaiwgJ3ZhbCcpOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KG5vb3ApLnRvLm5vdC5kZWNyZWFzZShteU9iaiwgJ3ZhbCcpOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogYC5kZWNyZWFzZWAgYWNjZXB0cyBhbiBvcHRpb25hbCBgbXNnYCBhcmd1bWVudCB3aGljaCBpcyBhIGN1c3RvbSBlcnJvclxuICAgKiBtZXNzYWdlIHRvIHNob3cgd2hlbiB0aGUgYXNzZXJ0aW9uIGZhaWxzLiBUaGUgbWVzc2FnZSBjYW4gYWxzbyBiZSBnaXZlbiBhc1xuICAgKiB0aGUgc2Vjb25kIGFyZ3VtZW50IHRvIGBleHBlY3RgLiBXaGVuIG5vdCBwcm92aWRpbmcgdHdvIGFyZ3VtZW50cywgYWx3YXlzXG4gICAqIHVzZSB0aGUgc2Vjb25kIGZvcm0uXG4gICAqXG4gICAqICAgICB2YXIgbXlPYmogPSB7dmFsOiAxfVxuICAgKiAgICAgICAsIG5vb3AgPSBmdW5jdGlvbiAoKSB7fTtcbiAgICpcbiAgICogICAgIGV4cGVjdChub29wKS50by5kZWNyZWFzZShteU9iaiwgJ3ZhbCcsICdub29vIHdoeSBmYWlsPz8nKTtcbiAgICpcbiAgICogICAgIHZhciB2YWwgPSAxXG4gICAqICAgICAgICwgbm9vcCA9IGZ1bmN0aW9uICgpIHt9XG4gICAqICAgICAgICwgZ2V0VmFsID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdmFsOyB9O1xuICAgKlxuICAgKiAgICAgZXhwZWN0KG5vb3AsICdub29vIHdoeSBmYWlsPz8nKS50by5kZWNyZWFzZShnZXRWYWwpO1xuICAgKlxuICAgKiBUaGUgYWxpYXMgYC5kZWNyZWFzZXNgIGNhbiBiZSB1c2VkIGludGVyY2hhbmdlYWJseSB3aXRoIGAuZGVjcmVhc2VgLlxuICAgKlxuICAgKiBAbmFtZSBkZWNyZWFzZVxuICAgKiBAYWxpYXMgZGVjcmVhc2VzXG4gICAqIEBwYXJhbSB7U3RyaW5nfEZ1bmN0aW9ufSBzdWJqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wIG5hbWUgX29wdGlvbmFsX1xuICAgKiBAcGFyYW0ge1N0cmluZ30gbXNnIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gYXNzZXJ0RGVjcmVhc2VzIChzdWJqZWN0LCBwcm9wLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgZm4gPSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCBmbGFnTXNnID0gZmxhZyh0aGlzLCAnbWVzc2FnZScpXG4gICAgICAsIHNzZmkgPSBmbGFnKHRoaXMsICdzc2ZpJyk7XG4gICAgbmV3IEFzc2VydGlvbihmbiwgZmxhZ01zZywgc3NmaSwgdHJ1ZSkuaXMuYSgnZnVuY3Rpb24nKTtcblxuICAgIHZhciBpbml0aWFsO1xuICAgIGlmICghcHJvcCkge1xuICAgICAgbmV3IEFzc2VydGlvbihzdWJqZWN0LCBmbGFnTXNnLCBzc2ZpLCB0cnVlKS5pcy5hKCdmdW5jdGlvbicpO1xuICAgICAgaW5pdGlhbCA9IHN1YmplY3QoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbmV3IEFzc2VydGlvbihzdWJqZWN0LCBmbGFnTXNnLCBzc2ZpLCB0cnVlKS50by5oYXZlLnByb3BlcnR5KHByb3ApO1xuICAgICAgaW5pdGlhbCA9IHN1YmplY3RbcHJvcF07XG4gICAgfVxuXG4gICAgLy8gTWFrZSBzdXJlIHRoYXQgdGhlIHRhcmdldCBpcyBhIG51bWJlclxuICAgIG5ldyBBc3NlcnRpb24oaW5pdGlhbCwgZmxhZ01zZywgc3NmaSwgdHJ1ZSkuaXMuYSgnbnVtYmVyJyk7XG5cbiAgICBmbigpO1xuXG4gICAgdmFyIGZpbmFsID0gcHJvcCA9PT0gdW5kZWZpbmVkIHx8IHByb3AgPT09IG51bGwgPyBzdWJqZWN0KCkgOiBzdWJqZWN0W3Byb3BdO1xuICAgIHZhciBtc2dPYmogPSBwcm9wID09PSB1bmRlZmluZWQgfHwgcHJvcCA9PT0gbnVsbCA/IGluaXRpYWwgOiAnLicgKyBwcm9wO1xuXG4gICAgZmxhZyh0aGlzLCAnZGVsdGFNc2dPYmonLCBtc2dPYmopO1xuICAgIGZsYWcodGhpcywgJ2luaXRpYWxEZWx0YVZhbHVlJywgaW5pdGlhbCk7XG4gICAgZmxhZyh0aGlzLCAnZmluYWxEZWx0YVZhbHVlJywgZmluYWwpO1xuICAgIGZsYWcodGhpcywgJ2RlbHRhQmVoYXZpb3InLCAnZGVjcmVhc2UnKTtcbiAgICBmbGFnKHRoaXMsICdyZWFsRGVsdGEnLCBpbml0aWFsIC0gZmluYWwpO1xuXG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICBmaW5hbCAtIGluaXRpYWwgPCAwXG4gICAgICAsICdleHBlY3RlZCAnICsgbXNnT2JqICsgJyB0byBkZWNyZWFzZSdcbiAgICAgICwgJ2V4cGVjdGVkICcgKyBtc2dPYmogKyAnIHRvIG5vdCBkZWNyZWFzZSdcbiAgICApO1xuICB9XG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnZGVjcmVhc2UnLCBhc3NlcnREZWNyZWFzZXMpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdkZWNyZWFzZXMnLCBhc3NlcnREZWNyZWFzZXMpO1xuXG4gIC8qKlxuICAgKiAjIyMgLmJ5KGRlbHRhWywgbXNnXSlcbiAgICpcbiAgICogV2hlbiBmb2xsb3dpbmcgYW4gYC5pbmNyZWFzZWAgYXNzZXJ0aW9uIGluIHRoZSBjaGFpbiwgYC5ieWAgYXNzZXJ0cyB0aGF0XG4gICAqIHRoZSBzdWJqZWN0IG9mIHRoZSBgLmluY3JlYXNlYCBhc3NlcnRpb24gaW5jcmVhc2VkIGJ5IHRoZSBnaXZlbiBgZGVsdGFgLlxuICAgKlxuICAgKiAgICAgdmFyIG15T2JqID0ge3ZhbDogMX1cbiAgICogICAgICAgLCBhZGRUd28gPSBmdW5jdGlvbiAoKSB7IG15T2JqLnZhbCArPSAyOyB9O1xuICAgKlxuICAgKiAgICAgZXhwZWN0KGFkZFR3bykudG8uaW5jcmVhc2UobXlPYmosICd2YWwnKS5ieSgyKTtcbiAgICpcbiAgICogV2hlbiBmb2xsb3dpbmcgYSBgLmRlY3JlYXNlYCBhc3NlcnRpb24gaW4gdGhlIGNoYWluLCBgLmJ5YCBhc3NlcnRzIHRoYXQgdGhlXG4gICAqIHN1YmplY3Qgb2YgdGhlIGAuZGVjcmVhc2VgIGFzc2VydGlvbiBkZWNyZWFzZWQgYnkgdGhlIGdpdmVuIGBkZWx0YWAuXG4gICAqXG4gICAqICAgICB2YXIgbXlPYmogPSB7dmFsOiAxfVxuICAgKiAgICAgICAsIHN1YnRyYWN0VHdvID0gZnVuY3Rpb24gKCkgeyBteU9iai52YWwgLT0gMjsgfTtcbiAgICpcbiAgICogICAgIGV4cGVjdChzdWJ0cmFjdFR3bykudG8uZGVjcmVhc2UobXlPYmosICd2YWwnKS5ieSgyKTtcbiAgICpcbiAgICogV2hlbiBmb2xsb3dpbmcgYSBgLmNoYW5nZWAgYXNzZXJ0aW9uIGluIHRoZSBjaGFpbiwgYC5ieWAgYXNzZXJ0cyB0aGF0IHRoZVxuICAgKiBzdWJqZWN0IG9mIHRoZSBgLmNoYW5nZWAgYXNzZXJ0aW9uIGVpdGhlciBpbmNyZWFzZWQgb3IgZGVjcmVhc2VkIGJ5IHRoZVxuICAgKiBnaXZlbiBgZGVsdGFgLiBIb3dldmVyLCBpdCdzIGRhbmdlcm91cyB0byB1c2UgYC5jaGFuZ2UuYnlgLiBUaGUgcHJvYmxlbSBpc1xuICAgKiB0aGF0IGl0IGNyZWF0ZXMgdW5jZXJ0YWluIGV4cGVjdGF0aW9ucy4gSXQncyBvZnRlbiBiZXN0IHRvIGlkZW50aWZ5IHRoZVxuICAgKiBleGFjdCBvdXRwdXQgdGhhdCdzIGV4cGVjdGVkLCBhbmQgdGhlbiB3cml0ZSBhbiBhc3NlcnRpb24gdGhhdCBvbmx5IGFjY2VwdHNcbiAgICogdGhhdCBleGFjdCBvdXRwdXQuXG4gICAqXG4gICAqICAgICB2YXIgbXlPYmogPSB7dmFsOiAxfVxuICAgKiAgICAgICAsIGFkZFR3byA9IGZ1bmN0aW9uICgpIHsgbXlPYmoudmFsICs9IDI7IH1cbiAgICogICAgICAgLCBzdWJ0cmFjdFR3byA9IGZ1bmN0aW9uICgpIHsgbXlPYmoudmFsIC09IDI7IH07XG4gICAqXG4gICAqICAgICBleHBlY3QoYWRkVHdvKS50by5pbmNyZWFzZShteU9iaiwgJ3ZhbCcpLmJ5KDIpOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KGFkZFR3bykudG8uY2hhbmdlKG15T2JqLCAndmFsJykuYnkoMik7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiAgICAgZXhwZWN0KHN1YnRyYWN0VHdvKS50by5kZWNyZWFzZShteU9iaiwgJ3ZhbCcpLmJ5KDIpOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KHN1YnRyYWN0VHdvKS50by5jaGFuZ2UobXlPYmosICd2YWwnKS5ieSgyKTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqIEFkZCBgLm5vdGAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gbmVnYXRlIGAuYnlgLiBIb3dldmVyLCBpdCdzIG9mdGVuIGJlc3RcbiAgICogdG8gYXNzZXJ0IHRoYXQgdGhlIHN1YmplY3QgY2hhbmdlZCBieSBpdHMgZXhwZWN0ZWQgZGVsdGEsIHJhdGhlciB0aGFuXG4gICAqIGFzc2VydGluZyB0aGF0IGl0IGRpZG4ndCBjaGFuZ2UgYnkgb25lIG9mIGNvdW50bGVzcyB1bmV4cGVjdGVkIGRlbHRhcy5cbiAgICpcbiAgICogICAgIHZhciBteU9iaiA9IHt2YWw6IDF9XG4gICAqICAgICAgICwgYWRkVHdvID0gZnVuY3Rpb24gKCkgeyBteU9iai52YWwgKz0gMjsgfTtcbiAgICpcbiAgICogICAgIC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoYWRkVHdvKS50by5pbmNyZWFzZShteU9iaiwgJ3ZhbCcpLmJ5KDIpO1xuICAgKlxuICAgKiAgICAgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoYWRkVHdvKS50by5pbmNyZWFzZShteU9iaiwgJ3ZhbCcpLmJ1dC5ub3QuYnkoMyk7XG4gICAqXG4gICAqIGAuYnlgIGFjY2VwdHMgYW4gb3B0aW9uYWwgYG1zZ2AgYXJndW1lbnQgd2hpY2ggaXMgYSBjdXN0b20gZXJyb3IgbWVzc2FnZSB0b1xuICAgKiBzaG93IHdoZW4gdGhlIGFzc2VydGlvbiBmYWlscy4gVGhlIG1lc3NhZ2UgY2FuIGFsc28gYmUgZ2l2ZW4gYXMgdGhlIHNlY29uZFxuICAgKiBhcmd1bWVudCB0byBgZXhwZWN0YC5cbiAgICpcbiAgICogICAgIHZhciBteU9iaiA9IHt2YWw6IDF9XG4gICAqICAgICAgICwgYWRkVHdvID0gZnVuY3Rpb24gKCkgeyBteU9iai52YWwgKz0gMjsgfTtcbiAgICpcbiAgICogICAgIGV4cGVjdChhZGRUd28pLnRvLmluY3JlYXNlKG15T2JqLCAndmFsJykuYnkoMywgJ25vb28gd2h5IGZhaWw/PycpO1xuICAgKiAgICAgZXhwZWN0KGFkZFR3bywgJ25vb28gd2h5IGZhaWw/PycpLnRvLmluY3JlYXNlKG15T2JqLCAndmFsJykuYnkoMyk7XG4gICAqXG4gICAqIEBuYW1lIGJ5XG4gICAqIEBwYXJhbSB7TnVtYmVyfSBkZWx0YVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbXNnIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gYXNzZXJ0RGVsdGEoZGVsdGEsIG1zZykge1xuICAgIGlmIChtc2cpIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuXG4gICAgdmFyIG1zZ09iaiA9IGZsYWcodGhpcywgJ2RlbHRhTXNnT2JqJyk7XG4gICAgdmFyIGluaXRpYWwgPSBmbGFnKHRoaXMsICdpbml0aWFsRGVsdGFWYWx1ZScpO1xuICAgIHZhciBmaW5hbCA9IGZsYWcodGhpcywgJ2ZpbmFsRGVsdGFWYWx1ZScpO1xuICAgIHZhciBiZWhhdmlvciA9IGZsYWcodGhpcywgJ2RlbHRhQmVoYXZpb3InKTtcbiAgICB2YXIgcmVhbERlbHRhID0gZmxhZyh0aGlzLCAncmVhbERlbHRhJyk7XG5cbiAgICB2YXIgZXhwcmVzc2lvbjtcbiAgICBpZiAoYmVoYXZpb3IgPT09ICdjaGFuZ2UnKSB7XG4gICAgICBleHByZXNzaW9uID0gTWF0aC5hYnMoZmluYWwgLSBpbml0aWFsKSA9PT0gTWF0aC5hYnMoZGVsdGEpO1xuICAgIH0gZWxzZSB7XG4gICAgICBleHByZXNzaW9uID0gcmVhbERlbHRhID09PSBNYXRoLmFicyhkZWx0YSk7XG4gICAgfVxuXG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICBleHByZXNzaW9uXG4gICAgICAsICdleHBlY3RlZCAnICsgbXNnT2JqICsgJyB0byAnICsgYmVoYXZpb3IgKyAnIGJ5ICcgKyBkZWx0YVxuICAgICAgLCAnZXhwZWN0ZWQgJyArIG1zZ09iaiArICcgdG8gbm90ICcgKyBiZWhhdmlvciArICcgYnkgJyArIGRlbHRhXG4gICAgKTtcbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2J5JywgYXNzZXJ0RGVsdGEpO1xuXG4gIC8qKlxuICAgKiAjIyMgLmV4dGVuc2libGVcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaXMgZXh0ZW5zaWJsZSwgd2hpY2ggbWVhbnMgdGhhdCBuZXcgcHJvcGVydGllcyBjYW5cbiAgICogYmUgYWRkZWQgdG8gaXQuIFByaW1pdGl2ZXMgYXJlIG5ldmVyIGV4dGVuc2libGUuXG4gICAqXG4gICAqICAgICBleHBlY3Qoe2E6IDF9KS50by5iZS5leHRlbnNpYmxlO1xuICAgKlxuICAgKiBBZGQgYC5ub3RgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIG5lZ2F0ZSBgLmV4dGVuc2libGVgLlxuICAgKlxuICAgKiAgICAgdmFyIG5vbkV4dGVuc2libGVPYmplY3QgPSBPYmplY3QucHJldmVudEV4dGVuc2lvbnMoe30pXG4gICAqICAgICAgICwgc2VhbGVkT2JqZWN0ID0gT2JqZWN0LnNlYWwoe30pXG4gICAqICAgICAgICwgZnJvemVuT2JqZWN0ID0gT2JqZWN0LmZyZWV6ZSh7fSk7XG4gICAqXG4gICAqICAgICBleHBlY3Qobm9uRXh0ZW5zaWJsZU9iamVjdCkudG8ubm90LmJlLmV4dGVuc2libGU7XG4gICAqICAgICBleHBlY3Qoc2VhbGVkT2JqZWN0KS50by5ub3QuYmUuZXh0ZW5zaWJsZTtcbiAgICogICAgIGV4cGVjdChmcm96ZW5PYmplY3QpLnRvLm5vdC5iZS5leHRlbnNpYmxlO1xuICAgKiAgICAgZXhwZWN0KDEpLnRvLm5vdC5iZS5leHRlbnNpYmxlO1xuICAgKlxuICAgKiBBIGN1c3RvbSBlcnJvciBtZXNzYWdlIGNhbiBiZSBnaXZlbiBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50IHRvIGBleHBlY3RgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KDEsICdub29vIHdoeSBmYWlsPz8nKS50by5iZS5leHRlbnNpYmxlO1xuICAgKlxuICAgKiBAbmFtZSBleHRlbnNpYmxlXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgnZXh0ZW5zaWJsZScsIGZ1bmN0aW9uKCkge1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKTtcblxuICAgIC8vIEluIEVTNSwgaWYgdGhlIGFyZ3VtZW50IHRvIHRoaXMgbWV0aG9kIGlzIGEgcHJpbWl0aXZlLCB0aGVuIGl0IHdpbGwgY2F1c2UgYSBUeXBlRXJyb3IuXG4gICAgLy8gSW4gRVM2LCBhIG5vbi1vYmplY3QgYXJndW1lbnQgd2lsbCBiZSB0cmVhdGVkIGFzIGlmIGl0IHdhcyBhIG5vbi1leHRlbnNpYmxlIG9yZGluYXJ5IG9iamVjdCwgc2ltcGx5IHJldHVybiBmYWxzZS5cbiAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9PYmplY3QvaXNFeHRlbnNpYmxlXG4gICAgLy8gVGhlIGZvbGxvd2luZyBwcm92aWRlcyBFUzYgYmVoYXZpb3IgZm9yIEVTNSBlbnZpcm9ubWVudHMuXG5cbiAgICB2YXIgaXNFeHRlbnNpYmxlID0gb2JqID09PSBPYmplY3Qob2JqKSAmJiBPYmplY3QuaXNFeHRlbnNpYmxlKG9iaik7XG5cbiAgICB0aGlzLmFzc2VydChcbiAgICAgIGlzRXh0ZW5zaWJsZVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBleHRlbnNpYmxlJ1xuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgYmUgZXh0ZW5zaWJsZSdcbiAgICApO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC5zZWFsZWRcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaXMgc2VhbGVkLCB3aGljaCBtZWFucyB0aGF0IG5ldyBwcm9wZXJ0aWVzIGNhbid0IGJlXG4gICAqIGFkZGVkIHRvIGl0LCBhbmQgaXRzIGV4aXN0aW5nIHByb3BlcnRpZXMgY2FuJ3QgYmUgcmVjb25maWd1cmVkIG9yIGRlbGV0ZWQuXG4gICAqIEhvd2V2ZXIsIGl0J3MgcG9zc2libGUgdGhhdCBpdHMgZXhpc3RpbmcgcHJvcGVydGllcyBjYW4gc3RpbGwgYmUgcmVhc3NpZ25lZFxuICAgKiB0byBkaWZmZXJlbnQgdmFsdWVzLiBQcmltaXRpdmVzIGFyZSBhbHdheXMgc2VhbGVkLlxuICAgKlxuICAgKiAgICAgdmFyIHNlYWxlZE9iamVjdCA9IE9iamVjdC5zZWFsKHt9KTtcbiAgICogICAgIHZhciBmcm96ZW5PYmplY3QgPSBPYmplY3QuZnJlZXplKHt9KTtcbiAgICpcbiAgICogICAgIGV4cGVjdChzZWFsZWRPYmplY3QpLnRvLmJlLnNlYWxlZDtcbiAgICogICAgIGV4cGVjdChmcm96ZW5PYmplY3QpLnRvLmJlLnNlYWxlZDtcbiAgICogICAgIGV4cGVjdCgxKS50by5iZS5zZWFsZWQ7XG4gICAqXG4gICAqIEFkZCBgLm5vdGAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gbmVnYXRlIGAuc2VhbGVkYC5cbiAgICpcbiAgICogICAgIGV4cGVjdCh7YTogMX0pLnRvLm5vdC5iZS5zZWFsZWQ7XG4gICAqXG4gICAqIEEgY3VzdG9tIGVycm9yIG1lc3NhZ2UgY2FuIGJlIGdpdmVuIGFzIHRoZSBzZWNvbmQgYXJndW1lbnQgdG8gYGV4cGVjdGAuXG4gICAqXG4gICAqICAgICBleHBlY3Qoe2E6IDF9LCAnbm9vbyB3aHkgZmFpbD8/JykudG8uYmUuc2VhbGVkO1xuICAgKlxuICAgKiBAbmFtZSBzZWFsZWRcbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgQXNzZXJ0aW9uLmFkZFByb3BlcnR5KCdzZWFsZWQnLCBmdW5jdGlvbigpIHtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG5cbiAgICAvLyBJbiBFUzUsIGlmIHRoZSBhcmd1bWVudCB0byB0aGlzIG1ldGhvZCBpcyBhIHByaW1pdGl2ZSwgdGhlbiBpdCB3aWxsIGNhdXNlIGEgVHlwZUVycm9yLlxuICAgIC8vIEluIEVTNiwgYSBub24tb2JqZWN0IGFyZ3VtZW50IHdpbGwgYmUgdHJlYXRlZCBhcyBpZiBpdCB3YXMgYSBzZWFsZWQgb3JkaW5hcnkgb2JqZWN0LCBzaW1wbHkgcmV0dXJuIHRydWUuXG4gICAgLy8gU2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL09iamVjdC9pc1NlYWxlZFxuICAgIC8vIFRoZSBmb2xsb3dpbmcgcHJvdmlkZXMgRVM2IGJlaGF2aW9yIGZvciBFUzUgZW52aXJvbm1lbnRzLlxuXG4gICAgdmFyIGlzU2VhbGVkID0gb2JqID09PSBPYmplY3Qob2JqKSA/IE9iamVjdC5pc1NlYWxlZChvYmopIDogdHJ1ZTtcblxuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgaXNTZWFsZWRcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgc2VhbGVkJ1xuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgYmUgc2VhbGVkJ1xuICAgICk7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiAjIyMgLmZyb3plblxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBmcm96ZW4sIHdoaWNoIG1lYW5zIHRoYXQgbmV3IHByb3BlcnRpZXMgY2FuJ3QgYmVcbiAgICogYWRkZWQgdG8gaXQsIGFuZCBpdHMgZXhpc3RpbmcgcHJvcGVydGllcyBjYW4ndCBiZSByZWFzc2lnbmVkIHRvIGRpZmZlcmVudFxuICAgKiB2YWx1ZXMsIHJlY29uZmlndXJlZCwgb3IgZGVsZXRlZC4gUHJpbWl0aXZlcyBhcmUgYWx3YXlzIGZyb3plbi5cbiAgICpcbiAgICogICAgIHZhciBmcm96ZW5PYmplY3QgPSBPYmplY3QuZnJlZXplKHt9KTtcbiAgICpcbiAgICogICAgIGV4cGVjdChmcm96ZW5PYmplY3QpLnRvLmJlLmZyb3plbjtcbiAgICogICAgIGV4cGVjdCgxKS50by5iZS5mcm96ZW47XG4gICAqXG4gICAqIEFkZCBgLm5vdGAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gbmVnYXRlIGAuZnJvemVuYC5cbiAgICpcbiAgICogICAgIGV4cGVjdCh7YTogMX0pLnRvLm5vdC5iZS5mcm96ZW47XG4gICAqXG4gICAqIEEgY3VzdG9tIGVycm9yIG1lc3NhZ2UgY2FuIGJlIGdpdmVuIGFzIHRoZSBzZWNvbmQgYXJndW1lbnQgdG8gYGV4cGVjdGAuXG4gICAqXG4gICAqICAgICBleHBlY3Qoe2E6IDF9LCAnbm9vbyB3aHkgZmFpbD8/JykudG8uYmUuZnJvemVuO1xuICAgKlxuICAgKiBAbmFtZSBmcm96ZW5cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgQXNzZXJ0aW9uLmFkZFByb3BlcnR5KCdmcm96ZW4nLCBmdW5jdGlvbigpIHtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG5cbiAgICAvLyBJbiBFUzUsIGlmIHRoZSBhcmd1bWVudCB0byB0aGlzIG1ldGhvZCBpcyBhIHByaW1pdGl2ZSwgdGhlbiBpdCB3aWxsIGNhdXNlIGEgVHlwZUVycm9yLlxuICAgIC8vIEluIEVTNiwgYSBub24tb2JqZWN0IGFyZ3VtZW50IHdpbGwgYmUgdHJlYXRlZCBhcyBpZiBpdCB3YXMgYSBmcm96ZW4gb3JkaW5hcnkgb2JqZWN0LCBzaW1wbHkgcmV0dXJuIHRydWUuXG4gICAgLy8gU2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL09iamVjdC9pc0Zyb3plblxuICAgIC8vIFRoZSBmb2xsb3dpbmcgcHJvdmlkZXMgRVM2IGJlaGF2aW9yIGZvciBFUzUgZW52aXJvbm1lbnRzLlxuXG4gICAgdmFyIGlzRnJvemVuID0gb2JqID09PSBPYmplY3Qob2JqKSA/IE9iamVjdC5pc0Zyb3plbihvYmopIDogdHJ1ZTtcblxuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgaXNGcm96ZW5cbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgZnJvemVuJ1xuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgYmUgZnJvemVuJ1xuICAgICk7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiAjIyMgLmZpbml0ZVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBhIG51bWJlciwgYW5kIGlzbid0IGBOYU5gIG9yIHBvc2l0aXZlL25lZ2F0aXZlXG4gICAqIGBJbmZpbml0eWAuXG4gICAqXG4gICAqICAgICBleHBlY3QoMSkudG8uYmUuZmluaXRlO1xuICAgKlxuICAgKiBBZGQgYC5ub3RgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIG5lZ2F0ZSBgLmZpbml0ZWAuIEhvd2V2ZXIsIGl0J3NcbiAgICogZGFuZ2Vyb3VzIHRvIGRvIHNvLiBUaGUgcHJvYmxlbSBpcyB0aGF0IGl0IGNyZWF0ZXMgdW5jZXJ0YWluIGV4cGVjdGF0aW9uc1xuICAgKiBieSBhc3NlcnRpbmcgdGhhdCB0aGUgc3ViamVjdCBlaXRoZXIgaXNuJ3QgYSBudW1iZXIsIG9yIHRoYXQgaXQncyBgTmFOYCwgb3JcbiAgICogdGhhdCBpdCdzIHBvc2l0aXZlIGBJbmZpbml0eWAsIG9yIHRoYXQgaXQncyBuZWdhdGl2ZSBgSW5maW5pdHlgLiBJdCdzIG9mdGVuXG4gICAqIGJlc3QgdG8gaWRlbnRpZnkgdGhlIGV4YWN0IG91dHB1dCB0aGF0J3MgZXhwZWN0ZWQsIGFuZCB0aGVuIHdyaXRlIGFuXG4gICAqIGFzc2VydGlvbiB0aGF0IG9ubHkgYWNjZXB0cyB0aGF0IGV4YWN0IG91dHB1dC5cbiAgICpcbiAgICogV2hlbiB0aGUgdGFyZ2V0IGlzbid0IGV4cGVjdGVkIHRvIGJlIGEgbnVtYmVyLCBpdCdzIG9mdGVuIGJlc3QgdG8gYXNzZXJ0XG4gICAqIHRoYXQgaXQncyB0aGUgZXhwZWN0ZWQgdHlwZSwgcmF0aGVyIHRoYW4gYXNzZXJ0aW5nIHRoYXQgaXQgaXNuJ3Qgb25lIG9mXG4gICAqIG1hbnkgdW5leHBlY3RlZCB0eXBlcy5cbiAgICpcbiAgICogICAgIGV4cGVjdCgnZm9vJykudG8uYmUuYSgnc3RyaW5nJyk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoJ2ZvbycpLnRvLm5vdC5iZS5maW5pdGU7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBXaGVuIHRoZSB0YXJnZXQgaXMgZXhwZWN0ZWQgdG8gYmUgYE5hTmAsIGl0J3Mgb2Z0ZW4gYmVzdCB0byBhc3NlcnQgZXhhY3RseVxuICAgKiB0aGF0LlxuICAgKlxuICAgKiAgICAgZXhwZWN0KE5hTikudG8uYmUuTmFOOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KE5hTikudG8ubm90LmJlLmZpbml0ZTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqIFdoZW4gdGhlIHRhcmdldCBpcyBleHBlY3RlZCB0byBiZSBwb3NpdGl2ZSBpbmZpbml0eSwgaXQncyBvZnRlbiBiZXN0IHRvXG4gICAqIGFzc2VydCBleGFjdGx5IHRoYXQuXG4gICAqXG4gICAqICAgICBleHBlY3QoSW5maW5pdHkpLnRvLmVxdWFsKEluZmluaXR5KTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdChJbmZpbml0eSkudG8ubm90LmJlLmZpbml0ZTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqIFdoZW4gdGhlIHRhcmdldCBpcyBleHBlY3RlZCB0byBiZSBuZWdhdGl2ZSBpbmZpbml0eSwgaXQncyBvZnRlbiBiZXN0IHRvXG4gICAqIGFzc2VydCBleGFjdGx5IHRoYXQuXG4gICAqXG4gICAqICAgICBleHBlY3QoLUluZmluaXR5KS50by5lcXVhbCgtSW5maW5pdHkpOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KC1JbmZpbml0eSkudG8ubm90LmJlLmZpbml0ZTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqIEEgY3VzdG9tIGVycm9yIG1lc3NhZ2UgY2FuIGJlIGdpdmVuIGFzIHRoZSBzZWNvbmQgYXJndW1lbnQgdG8gYGV4cGVjdGAuXG4gICAqXG4gICAqICAgICBleHBlY3QoJ2ZvbycsICdub29vIHdoeSBmYWlsPz8nKS50by5iZS5maW5pdGU7XG4gICAqXG4gICAqIEBuYW1lIGZpbml0ZVxuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBBc3NlcnRpb24uYWRkUHJvcGVydHkoJ2Zpbml0ZScsIGZ1bmN0aW9uKG1zZykge1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKTtcblxuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICB0eXBlb2Ygb2JqID09PSAnbnVtYmVyJyAmJiBpc0Zpbml0ZShvYmopXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIGEgZmluaXRlIG51bWJlcidcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGJlIGEgZmluaXRlIG51bWJlcidcbiAgICApO1xuICB9KTtcbn07XG4iLCAiLyohXG4gKiBjaGFpXG4gKiBDb3B5cmlnaHQoYykgMjAxMS0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoY2hhaSwgdXRpbCkge1xuICBjaGFpLmV4cGVjdCA9IGZ1bmN0aW9uICh2YWwsIG1lc3NhZ2UpIHtcbiAgICByZXR1cm4gbmV3IGNoYWkuQXNzZXJ0aW9uKHZhbCwgbWVzc2FnZSk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuZmFpbChbbWVzc2FnZV0pXG4gICAqICMjIyAuZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBbbWVzc2FnZV0sIFtvcGVyYXRvcl0pXG4gICAqXG4gICAqIFRocm93IGEgZmFpbHVyZS5cbiAgICpcbiAgICogICAgIGV4cGVjdC5mYWlsKCk7XG4gICAqICAgICBleHBlY3QuZmFpbChcImN1c3RvbSBlcnJvciBtZXNzYWdlXCIpO1xuICAgKiAgICAgZXhwZWN0LmZhaWwoMSwgMik7XG4gICAqICAgICBleHBlY3QuZmFpbCgxLCAyLCBcImN1c3RvbSBlcnJvciBtZXNzYWdlXCIpO1xuICAgKiAgICAgZXhwZWN0LmZhaWwoMSwgMiwgXCJjdXN0b20gZXJyb3IgbWVzc2FnZVwiLCBcIj5cIik7XG4gICAqICAgICBleHBlY3QuZmFpbCgxLCAyLCB1bmRlZmluZWQsIFwiPlwiKTtcbiAgICpcbiAgICogQG5hbWUgZmFpbFxuICAgKiBAcGFyYW0ge01peGVkfSBhY3R1YWxcbiAgICogQHBhcmFtIHtNaXhlZH0gZXhwZWN0ZWRcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQHBhcmFtIHtTdHJpbmd9IG9wZXJhdG9yXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGNoYWkuZXhwZWN0LmZhaWwgPSBmdW5jdGlvbiAoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgb3BlcmF0b3IpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgbWVzc2FnZSA9IGFjdHVhbDtcbiAgICAgICAgYWN0dWFsID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIG1lc3NhZ2UgPSBtZXNzYWdlIHx8ICdleHBlY3QuZmFpbCgpJztcbiAgICB0aHJvdyBuZXcgY2hhaS5Bc3NlcnRpb25FcnJvcihtZXNzYWdlLCB7XG4gICAgICAgIGFjdHVhbDogYWN0dWFsXG4gICAgICAsIGV4cGVjdGVkOiBleHBlY3RlZFxuICAgICAgLCBvcGVyYXRvcjogb3BlcmF0b3JcbiAgICB9LCBjaGFpLmV4cGVjdC5mYWlsKTtcbiAgfTtcbn07XG4iLCAiLyohXG4gKiBjaGFpXG4gKiBDb3B5cmlnaHQoYykgMjAxMS0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoY2hhaSwgdXRpbCkge1xuICB2YXIgQXNzZXJ0aW9uID0gY2hhaS5Bc3NlcnRpb247XG5cbiAgZnVuY3Rpb24gbG9hZFNob3VsZCAoKSB7XG4gICAgLy8gZXhwbGljaXRseSBkZWZpbmUgdGhpcyBtZXRob2QgYXMgZnVuY3Rpb24gYXMgdG8gaGF2ZSBpdCdzIG5hbWUgdG8gaW5jbHVkZSBhcyBgc3NmaWBcbiAgICBmdW5jdGlvbiBzaG91bGRHZXR0ZXIoKSB7XG4gICAgICBpZiAodGhpcyBpbnN0YW5jZW9mIFN0cmluZ1xuICAgICAgICAgIHx8IHRoaXMgaW5zdGFuY2VvZiBOdW1iZXJcbiAgICAgICAgICB8fCB0aGlzIGluc3RhbmNlb2YgQm9vbGVhblxuICAgICAgICAgIHx8IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgdGhpcyBpbnN0YW5jZW9mIFN5bWJvbFxuICAgICAgICAgIHx8IHR5cGVvZiBCaWdJbnQgPT09ICdmdW5jdGlvbicgJiYgdGhpcyBpbnN0YW5jZW9mIEJpZ0ludCkge1xuICAgICAgICByZXR1cm4gbmV3IEFzc2VydGlvbih0aGlzLnZhbHVlT2YoKSwgbnVsbCwgc2hvdWxkR2V0dGVyKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBuZXcgQXNzZXJ0aW9uKHRoaXMsIG51bGwsIHNob3VsZEdldHRlcik7XG4gICAgfVxuICAgIGZ1bmN0aW9uIHNob3VsZFNldHRlcih2YWx1ZSkge1xuICAgICAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFpanMvY2hhaS9pc3N1ZXMvODY6IHRoaXMgbWFrZXNcbiAgICAgIC8vIGB3aGF0ZXZlci5zaG91bGQgPSBzb21lVmFsdWVgIGFjdHVhbGx5IHNldCBgc29tZVZhbHVlYCwgd2hpY2ggaXNcbiAgICAgIC8vIGVzcGVjaWFsbHkgdXNlZnVsIGZvciBgZ2xvYmFsLnNob3VsZCA9IHJlcXVpcmUoJ2NoYWknKS5zaG91bGQoKWAuXG4gICAgICAvL1xuICAgICAgLy8gTm90ZSB0aGF0IHdlIGhhdmUgdG8gdXNlIFtbRGVmaW5lUHJvcGVydHldXSBpbnN0ZWFkIG9mIFtbUHV0XV1cbiAgICAgIC8vIHNpbmNlIG90aGVyd2lzZSB3ZSB3b3VsZCB0cmlnZ2VyIHRoaXMgdmVyeSBzZXR0ZXIhXG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3Nob3VsZCcsIHtcbiAgICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlXG4gICAgICB9KTtcbiAgICB9XG4gICAgLy8gbW9kaWZ5IE9iamVjdC5wcm90b3R5cGUgdG8gaGF2ZSBgc2hvdWxkYFxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShPYmplY3QucHJvdG90eXBlLCAnc2hvdWxkJywge1xuICAgICAgc2V0OiBzaG91bGRTZXR0ZXJcbiAgICAgICwgZ2V0OiBzaG91bGRHZXR0ZXJcbiAgICAgICwgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG5cbiAgICB2YXIgc2hvdWxkID0ge307XG5cbiAgICAvKipcbiAgICAgKiAjIyMgLmZhaWwoW21lc3NhZ2VdKVxuICAgICAqICMjIyAuZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBbbWVzc2FnZV0sIFtvcGVyYXRvcl0pXG4gICAgICpcbiAgICAgKiBUaHJvdyBhIGZhaWx1cmUuXG4gICAgICpcbiAgICAgKiAgICAgc2hvdWxkLmZhaWwoKTtcbiAgICAgKiAgICAgc2hvdWxkLmZhaWwoXCJjdXN0b20gZXJyb3IgbWVzc2FnZVwiKTtcbiAgICAgKiAgICAgc2hvdWxkLmZhaWwoMSwgMik7XG4gICAgICogICAgIHNob3VsZC5mYWlsKDEsIDIsIFwiY3VzdG9tIGVycm9yIG1lc3NhZ2VcIik7XG4gICAgICogICAgIHNob3VsZC5mYWlsKDEsIDIsIFwiY3VzdG9tIGVycm9yIG1lc3NhZ2VcIiwgXCI+XCIpO1xuICAgICAqICAgICBzaG91bGQuZmFpbCgxLCAyLCB1bmRlZmluZWQsIFwiPlwiKTtcbiAgICAgKlxuICAgICAqXG4gICAgICogQG5hbWUgZmFpbFxuICAgICAqIEBwYXJhbSB7TWl4ZWR9IGFjdHVhbFxuICAgICAqIEBwYXJhbSB7TWl4ZWR9IGV4cGVjdGVkXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gb3BlcmF0b3JcbiAgICAgKiBAbmFtZXNwYWNlIEJERFxuICAgICAqIEBhcGkgcHVibGljXG4gICAgICovXG5cbiAgICBzaG91bGQuZmFpbCA9IGZ1bmN0aW9uIChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCBvcGVyYXRvcikge1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAyKSB7XG4gICAgICAgICAgbWVzc2FnZSA9IGFjdHVhbDtcbiAgICAgICAgICBhY3R1YWwgPSB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIG1lc3NhZ2UgPSBtZXNzYWdlIHx8ICdzaG91bGQuZmFpbCgpJztcbiAgICAgIHRocm93IG5ldyBjaGFpLkFzc2VydGlvbkVycm9yKG1lc3NhZ2UsIHtcbiAgICAgICAgICBhY3R1YWw6IGFjdHVhbFxuICAgICAgICAsIGV4cGVjdGVkOiBleHBlY3RlZFxuICAgICAgICAsIG9wZXJhdG9yOiBvcGVyYXRvclxuICAgICAgfSwgc2hvdWxkLmZhaWwpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiAjIyMgLmVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIFttZXNzYWdlXSlcbiAgICAgKlxuICAgICAqIEFzc2VydHMgbm9uLXN0cmljdCBlcXVhbGl0eSAoYD09YCkgb2YgYGFjdHVhbGAgYW5kIGBleHBlY3RlZGAuXG4gICAgICpcbiAgICAgKiAgICAgc2hvdWxkLmVxdWFsKDMsICczJywgJz09IGNvZXJjZXMgdmFsdWVzIHRvIHN0cmluZ3MnKTtcbiAgICAgKlxuICAgICAqIEBuYW1lIGVxdWFsXG4gICAgICogQHBhcmFtIHtNaXhlZH0gYWN0dWFsXG4gICAgICogQHBhcmFtIHtNaXhlZH0gZXhwZWN0ZWRcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgICAqIEBuYW1lc3BhY2UgU2hvdWxkXG4gICAgICogQGFwaSBwdWJsaWNcbiAgICAgKi9cblxuICAgIHNob3VsZC5lcXVhbCA9IGZ1bmN0aW9uICh2YWwxLCB2YWwyLCBtc2cpIHtcbiAgICAgIG5ldyBBc3NlcnRpb24odmFsMSwgbXNnKS50by5lcXVhbCh2YWwyKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogIyMjIC50aHJvdyhmdW5jdGlvbiwgW2NvbnN0cnVjdG9yL3N0cmluZy9yZWdleHBdLCBbc3RyaW5nL3JlZ2V4cF0sIFttZXNzYWdlXSlcbiAgICAgKlxuICAgICAqIEFzc2VydHMgdGhhdCBgZnVuY3Rpb25gIHdpbGwgdGhyb3cgYW4gZXJyb3IgdGhhdCBpcyBhbiBpbnN0YW5jZSBvZlxuICAgICAqIGBjb25zdHJ1Y3RvcmAsIG9yIGFsdGVybmF0ZWx5IHRoYXQgaXQgd2lsbCB0aHJvdyBhbiBlcnJvciB3aXRoIG1lc3NhZ2VcbiAgICAgKiBtYXRjaGluZyBgcmVnZXhwYC5cbiAgICAgKlxuICAgICAqICAgICBzaG91bGQudGhyb3coZm4sICdmdW5jdGlvbiB0aHJvd3MgYSByZWZlcmVuY2UgZXJyb3InKTtcbiAgICAgKiAgICAgc2hvdWxkLnRocm93KGZuLCAvZnVuY3Rpb24gdGhyb3dzIGEgcmVmZXJlbmNlIGVycm9yLyk7XG4gICAgICogICAgIHNob3VsZC50aHJvdyhmbiwgUmVmZXJlbmNlRXJyb3IpO1xuICAgICAqICAgICBzaG91bGQudGhyb3coZm4sIFJlZmVyZW5jZUVycm9yLCAnZnVuY3Rpb24gdGhyb3dzIGEgcmVmZXJlbmNlIGVycm9yJyk7XG4gICAgICogICAgIHNob3VsZC50aHJvdyhmbiwgUmVmZXJlbmNlRXJyb3IsIC9mdW5jdGlvbiB0aHJvd3MgYSByZWZlcmVuY2UgZXJyb3IvKTtcbiAgICAgKlxuICAgICAqIEBuYW1lIHRocm93XG4gICAgICogQGFsaWFzIFRocm93XG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Vycm9yQ29uc3RydWN0b3J9IGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtSZWdFeHB9IHJlZ2V4cFxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAgICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9FcnJvciNFcnJvcl90eXBlc1xuICAgICAqIEBuYW1lc3BhY2UgU2hvdWxkXG4gICAgICogQGFwaSBwdWJsaWNcbiAgICAgKi9cblxuICAgIHNob3VsZC5UaHJvdyA9IGZ1bmN0aW9uIChmbiwgZXJydCwgZXJycywgbXNnKSB7XG4gICAgICBuZXcgQXNzZXJ0aW9uKGZuLCBtc2cpLnRvLlRocm93KGVycnQsIGVycnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiAjIyMgLmV4aXN0XG4gICAgICpcbiAgICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBuZWl0aGVyIGBudWxsYCBub3IgYHVuZGVmaW5lZGAuXG4gICAgICpcbiAgICAgKiAgICAgdmFyIGZvbyA9ICdoaSc7XG4gICAgICpcbiAgICAgKiAgICAgc2hvdWxkLmV4aXN0KGZvbywgJ2ZvbyBleGlzdHMnKTtcbiAgICAgKlxuICAgICAqIEBuYW1lIGV4aXN0XG4gICAgICogQG5hbWVzcGFjZSBTaG91bGRcbiAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAqL1xuXG4gICAgc2hvdWxkLmV4aXN0ID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS50by5leGlzdDtcbiAgICB9XG5cbiAgICAvLyBuZWdhdGlvblxuICAgIHNob3VsZC5ub3QgPSB7fVxuXG4gICAgLyoqXG4gICAgICogIyMjIC5ub3QuZXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgW21lc3NhZ2VdKVxuICAgICAqXG4gICAgICogQXNzZXJ0cyBub24tc3RyaWN0IGluZXF1YWxpdHkgKGAhPWApIG9mIGBhY3R1YWxgIGFuZCBgZXhwZWN0ZWRgLlxuICAgICAqXG4gICAgICogICAgIHNob3VsZC5ub3QuZXF1YWwoMywgNCwgJ3RoZXNlIG51bWJlcnMgYXJlIG5vdCBlcXVhbCcpO1xuICAgICAqXG4gICAgICogQG5hbWUgbm90LmVxdWFsXG4gICAgICogQHBhcmFtIHtNaXhlZH0gYWN0dWFsXG4gICAgICogQHBhcmFtIHtNaXhlZH0gZXhwZWN0ZWRcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgICAqIEBuYW1lc3BhY2UgU2hvdWxkXG4gICAgICogQGFwaSBwdWJsaWNcbiAgICAgKi9cblxuICAgIHNob3VsZC5ub3QuZXF1YWwgPSBmdW5jdGlvbiAodmFsMSwgdmFsMiwgbXNnKSB7XG4gICAgICBuZXcgQXNzZXJ0aW9uKHZhbDEsIG1zZykudG8ubm90LmVxdWFsKHZhbDIpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiAjIyMgLnRocm93KGZ1bmN0aW9uLCBbY29uc3RydWN0b3IvcmVnZXhwXSwgW21lc3NhZ2VdKVxuICAgICAqXG4gICAgICogQXNzZXJ0cyB0aGF0IGBmdW5jdGlvbmAgd2lsbCBfbm90XyB0aHJvdyBhbiBlcnJvciB0aGF0IGlzIGFuIGluc3RhbmNlIG9mXG4gICAgICogYGNvbnN0cnVjdG9yYCwgb3IgYWx0ZXJuYXRlbHkgdGhhdCBpdCB3aWxsIG5vdCB0aHJvdyBhbiBlcnJvciB3aXRoIG1lc3NhZ2VcbiAgICAgKiBtYXRjaGluZyBgcmVnZXhwYC5cbiAgICAgKlxuICAgICAqICAgICBzaG91bGQubm90LnRocm93KGZuLCBFcnJvciwgJ2Z1bmN0aW9uIGRvZXMgbm90IHRocm93Jyk7XG4gICAgICpcbiAgICAgKiBAbmFtZSBub3QudGhyb3dcbiAgICAgKiBAYWxpYXMgbm90LlRocm93XG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Vycm9yQ29uc3RydWN0b3J9IGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtSZWdFeHB9IHJlZ2V4cFxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAgICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9FcnJvciNFcnJvcl90eXBlc1xuICAgICAqIEBuYW1lc3BhY2UgU2hvdWxkXG4gICAgICogQGFwaSBwdWJsaWNcbiAgICAgKi9cblxuICAgIHNob3VsZC5ub3QuVGhyb3cgPSBmdW5jdGlvbiAoZm4sIGVycnQsIGVycnMsIG1zZykge1xuICAgICAgbmV3IEFzc2VydGlvbihmbiwgbXNnKS50by5ub3QuVGhyb3coZXJydCwgZXJycyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqICMjIyAubm90LmV4aXN0XG4gICAgICpcbiAgICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBuZWl0aGVyIGBudWxsYCBub3IgYHVuZGVmaW5lZGAuXG4gICAgICpcbiAgICAgKiAgICAgdmFyIGJhciA9IG51bGw7XG4gICAgICpcbiAgICAgKiAgICAgc2hvdWxkLm5vdC5leGlzdChiYXIsICdiYXIgZG9lcyBub3QgZXhpc3QnKTtcbiAgICAgKlxuICAgICAqIEBuYW1lIG5vdC5leGlzdFxuICAgICAqIEBuYW1lc3BhY2UgU2hvdWxkXG4gICAgICogQGFwaSBwdWJsaWNcbiAgICAgKi9cblxuICAgIHNob3VsZC5ub3QuZXhpc3QgPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2cpLnRvLm5vdC5leGlzdDtcbiAgICB9XG5cbiAgICBzaG91bGRbJ3Rocm93J10gPSBzaG91bGRbJ1Rocm93J107XG4gICAgc2hvdWxkLm5vdFsndGhyb3cnXSA9IHNob3VsZC5ub3RbJ1Rocm93J107XG5cbiAgICByZXR1cm4gc2hvdWxkO1xuICB9O1xuXG4gIGNoYWkuc2hvdWxkID0gbG9hZFNob3VsZDtcbiAgY2hhaS5TaG91bGQgPSBsb2FkU2hvdWxkO1xufTtcbiIsICIvKiFcbiAqIGNoYWlcbiAqIENvcHlyaWdodChjKSAyMDExLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChjaGFpLCB1dGlsKSB7XG4gIC8qIVxuICAgKiBDaGFpIGRlcGVuZGVuY2llcy5cbiAgICovXG5cbiAgdmFyIEFzc2VydGlvbiA9IGNoYWkuQXNzZXJ0aW9uXG4gICAgLCBmbGFnID0gdXRpbC5mbGFnO1xuXG4gIC8qIVxuICAgKiBNb2R1bGUgZXhwb3J0LlxuICAgKi9cblxuICAvKipcbiAgICogIyMjIGFzc2VydChleHByZXNzaW9uLCBtZXNzYWdlKVxuICAgKlxuICAgKiBXcml0ZSB5b3VyIG93biB0ZXN0IGV4cHJlc3Npb25zLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0KCdmb28nICE9PSAnYmFyJywgJ2ZvbyBpcyBub3QgYmFyJyk7XG4gICAqICAgICBhc3NlcnQoQXJyYXkuaXNBcnJheShbXSksICdlbXB0eSBhcnJheXMgYXJlIGFycmF5cycpO1xuICAgKlxuICAgKiBAcGFyYW0ge01peGVkfSBleHByZXNzaW9uIHRvIHRlc3QgZm9yIHRydXRoaW5lc3NcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgdG8gZGlzcGxheSBvbiBlcnJvclxuICAgKiBAbmFtZSBhc3NlcnRcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgdmFyIGFzc2VydCA9IGNoYWkuYXNzZXJ0ID0gZnVuY3Rpb24gKGV4cHJlc3MsIGVycm1zZykge1xuICAgIHZhciB0ZXN0ID0gbmV3IEFzc2VydGlvbihudWxsLCBudWxsLCBjaGFpLmFzc2VydCwgdHJ1ZSk7XG4gICAgdGVzdC5hc3NlcnQoXG4gICAgICAgIGV4cHJlc3NcbiAgICAgICwgZXJybXNnXG4gICAgICAsICdbIG5lZ2F0aW9uIG1lc3NhZ2UgdW5hdmFpbGFibGUgXSdcbiAgICApO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmZhaWwoW21lc3NhZ2VdKVxuICAgKiAjIyMgLmZhaWwoYWN0dWFsLCBleHBlY3RlZCwgW21lc3NhZ2VdLCBbb3BlcmF0b3JdKVxuICAgKlxuICAgKiBUaHJvdyBhIGZhaWx1cmUuIE5vZGUuanMgYGFzc2VydGAgbW9kdWxlLWNvbXBhdGlibGUuXG4gICAqXG4gICAqICAgICBhc3NlcnQuZmFpbCgpO1xuICAgKiAgICAgYXNzZXJ0LmZhaWwoXCJjdXN0b20gZXJyb3IgbWVzc2FnZVwiKTtcbiAgICogICAgIGFzc2VydC5mYWlsKDEsIDIpO1xuICAgKiAgICAgYXNzZXJ0LmZhaWwoMSwgMiwgXCJjdXN0b20gZXJyb3IgbWVzc2FnZVwiKTtcbiAgICogICAgIGFzc2VydC5mYWlsKDEsIDIsIFwiY3VzdG9tIGVycm9yIG1lc3NhZ2VcIiwgXCI+XCIpO1xuICAgKiAgICAgYXNzZXJ0LmZhaWwoMSwgMiwgdW5kZWZpbmVkLCBcIj5cIik7XG4gICAqXG4gICAqIEBuYW1lIGZhaWxcbiAgICogQHBhcmFtIHtNaXhlZH0gYWN0dWFsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IGV4cGVjdGVkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBvcGVyYXRvclxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuZmFpbCA9IGZ1bmN0aW9uIChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCBvcGVyYXRvcikge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMikge1xuICAgICAgICAvLyBDb21wbHkgd2l0aCBOb2RlJ3MgZmFpbChbbWVzc2FnZV0pIGludGVyZmFjZVxuXG4gICAgICAgIG1lc3NhZ2UgPSBhY3R1YWw7XG4gICAgICAgIGFjdHVhbCA9IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBtZXNzYWdlID0gbWVzc2FnZSB8fCAnYXNzZXJ0LmZhaWwoKSc7XG4gICAgdGhyb3cgbmV3IGNoYWkuQXNzZXJ0aW9uRXJyb3IobWVzc2FnZSwge1xuICAgICAgICBhY3R1YWw6IGFjdHVhbFxuICAgICAgLCBleHBlY3RlZDogZXhwZWN0ZWRcbiAgICAgICwgb3BlcmF0b3I6IG9wZXJhdG9yXG4gICAgfSwgYXNzZXJ0LmZhaWwpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzT2sob2JqZWN0LCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBpcyB0cnV0aHkuXG4gICAqXG4gICAqICAgICBhc3NlcnQuaXNPaygnZXZlcnl0aGluZycsICdldmVyeXRoaW5nIGlzIG9rJyk7XG4gICAqICAgICBhc3NlcnQuaXNPayhmYWxzZSwgJ3RoaXMgd2lsbCBmYWlsJyk7XG4gICAqXG4gICAqIEBuYW1lIGlzT2tcbiAgICogQGFsaWFzIG9rXG4gICAqIEBwYXJhbSB7TWl4ZWR9IG9iamVjdCB0byB0ZXN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc09rID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZywgYXNzZXJ0LmlzT2ssIHRydWUpLmlzLm9rO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzTm90T2sob2JqZWN0LCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBpcyBmYWxzeS5cbiAgICpcbiAgICogICAgIGFzc2VydC5pc05vdE9rKCdldmVyeXRoaW5nJywgJ3RoaXMgd2lsbCBmYWlsJyk7XG4gICAqICAgICBhc3NlcnQuaXNOb3RPayhmYWxzZSwgJ3RoaXMgd2lsbCBwYXNzJyk7XG4gICAqXG4gICAqIEBuYW1lIGlzTm90T2tcbiAgICogQGFsaWFzIG5vdE9rXG4gICAqIEBwYXJhbSB7TWl4ZWR9IG9iamVjdCB0byB0ZXN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc05vdE9rID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZywgYXNzZXJ0LmlzTm90T2ssIHRydWUpLmlzLm5vdC5vaztcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5lcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgbm9uLXN0cmljdCBlcXVhbGl0eSAoYD09YCkgb2YgYGFjdHVhbGAgYW5kIGBleHBlY3RlZGAuXG4gICAqXG4gICAqICAgICBhc3NlcnQuZXF1YWwoMywgJzMnLCAnPT0gY29lcmNlcyB2YWx1ZXMgdG8gc3RyaW5ncycpO1xuICAgKlxuICAgKiBAbmFtZSBlcXVhbFxuICAgKiBAcGFyYW0ge01peGVkfSBhY3R1YWxcbiAgICogQHBhcmFtIHtNaXhlZH0gZXhwZWN0ZWRcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmVxdWFsID0gZnVuY3Rpb24gKGFjdCwgZXhwLCBtc2cpIHtcbiAgICB2YXIgdGVzdCA9IG5ldyBBc3NlcnRpb24oYWN0LCBtc2csIGFzc2VydC5lcXVhbCwgdHJ1ZSk7XG5cbiAgICB0ZXN0LmFzc2VydChcbiAgICAgICAgZXhwID09IGZsYWcodGVzdCwgJ29iamVjdCcpXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGVxdWFsICN7ZXhwfSdcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGVxdWFsICN7YWN0fSdcbiAgICAgICwgZXhwXG4gICAgICAsIGFjdFxuICAgICAgLCB0cnVlXG4gICAgKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5ub3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgbm9uLXN0cmljdCBpbmVxdWFsaXR5IChgIT1gKSBvZiBgYWN0dWFsYCBhbmQgYGV4cGVjdGVkYC5cbiAgICpcbiAgICogICAgIGFzc2VydC5ub3RFcXVhbCgzLCA0LCAndGhlc2UgbnVtYmVycyBhcmUgbm90IGVxdWFsJyk7XG4gICAqXG4gICAqIEBuYW1lIG5vdEVxdWFsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IGFjdHVhbFxuICAgKiBAcGFyYW0ge01peGVkfSBleHBlY3RlZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubm90RXF1YWwgPSBmdW5jdGlvbiAoYWN0LCBleHAsIG1zZykge1xuICAgIHZhciB0ZXN0ID0gbmV3IEFzc2VydGlvbihhY3QsIG1zZywgYXNzZXJ0Lm5vdEVxdWFsLCB0cnVlKTtcblxuICAgIHRlc3QuYXNzZXJ0KFxuICAgICAgICBleHAgIT0gZmxhZyh0ZXN0LCAnb2JqZWN0JylcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGVxdWFsICN7ZXhwfSdcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gZXF1YWwgI3thY3R9J1xuICAgICAgLCBleHBcbiAgICAgICwgYWN0XG4gICAgICAsIHRydWVcbiAgICApO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLnN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyBzdHJpY3QgZXF1YWxpdHkgKGA9PT1gKSBvZiBgYWN0dWFsYCBhbmQgYGV4cGVjdGVkYC5cbiAgICpcbiAgICogICAgIGFzc2VydC5zdHJpY3RFcXVhbCh0cnVlLCB0cnVlLCAndGhlc2UgYm9vbGVhbnMgYXJlIHN0cmljdGx5IGVxdWFsJyk7XG4gICAqXG4gICAqIEBuYW1lIHN0cmljdEVxdWFsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IGFjdHVhbFxuICAgKiBAcGFyYW0ge01peGVkfSBleHBlY3RlZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuc3RyaWN0RXF1YWwgPSBmdW5jdGlvbiAoYWN0LCBleHAsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oYWN0LCBtc2csIGFzc2VydC5zdHJpY3RFcXVhbCwgdHJ1ZSkudG8uZXF1YWwoZXhwKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5ub3RTdHJpY3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgc3RyaWN0IGluZXF1YWxpdHkgKGAhPT1gKSBvZiBgYWN0dWFsYCBhbmQgYGV4cGVjdGVkYC5cbiAgICpcbiAgICogICAgIGFzc2VydC5ub3RTdHJpY3RFcXVhbCgzLCAnMycsICdubyBjb2VyY2lvbiBmb3Igc3RyaWN0IGVxdWFsaXR5Jyk7XG4gICAqXG4gICAqIEBuYW1lIG5vdFN0cmljdEVxdWFsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IGFjdHVhbFxuICAgKiBAcGFyYW0ge01peGVkfSBleHBlY3RlZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubm90U3RyaWN0RXF1YWwgPSBmdW5jdGlvbiAoYWN0LCBleHAsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oYWN0LCBtc2csIGFzc2VydC5ub3RTdHJpY3RFcXVhbCwgdHJ1ZSkudG8ubm90LmVxdWFsKGV4cCk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuZGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBhY3R1YWxgIGlzIGRlZXBseSBlcXVhbCB0byBgZXhwZWN0ZWRgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmRlZXBFcXVhbCh7IHRlYTogJ2dyZWVuJyB9LCB7IHRlYTogJ2dyZWVuJyB9KTtcbiAgICpcbiAgICogQG5hbWUgZGVlcEVxdWFsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IGFjdHVhbFxuICAgKiBAcGFyYW0ge01peGVkfSBleHBlY3RlZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAYWxpYXMgZGVlcFN0cmljdEVxdWFsXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5kZWVwRXF1YWwgPSBhc3NlcnQuZGVlcFN0cmljdEVxdWFsID0gZnVuY3Rpb24gKGFjdCwgZXhwLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKGFjdCwgbXNnLCBhc3NlcnQuZGVlcEVxdWFsLCB0cnVlKS50by5lcWwoZXhwKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5ub3REZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnQgdGhhdCBgYWN0dWFsYCBpcyBub3QgZGVlcGx5IGVxdWFsIHRvIGBleHBlY3RlZGAuXG4gICAqXG4gICAqICAgICBhc3NlcnQubm90RGVlcEVxdWFsKHsgdGVhOiAnZ3JlZW4nIH0sIHsgdGVhOiAnamFzbWluZScgfSk7XG4gICAqXG4gICAqIEBuYW1lIG5vdERlZXBFcXVhbFxuICAgKiBAcGFyYW0ge01peGVkfSBhY3R1YWxcbiAgICogQHBhcmFtIHtNaXhlZH0gZXhwZWN0ZWRcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm5vdERlZXBFcXVhbCA9IGZ1bmN0aW9uIChhY3QsIGV4cCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihhY3QsIG1zZywgYXNzZXJ0Lm5vdERlZXBFcXVhbCwgdHJ1ZSkudG8ubm90LmVxbChleHApO1xuICB9O1xuXG4gICAvKipcbiAgICogIyMjIC5pc0Fib3ZlKHZhbHVlVG9DaGVjaywgdmFsdWVUb0JlQWJvdmUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyBgdmFsdWVUb0NoZWNrYCBpcyBzdHJpY3RseSBncmVhdGVyIHRoYW4gKD4pIGB2YWx1ZVRvQmVBYm92ZWAuXG4gICAqXG4gICAqICAgICBhc3NlcnQuaXNBYm92ZSg1LCAyLCAnNSBpcyBzdHJpY3RseSBncmVhdGVyIHRoYW4gMicpO1xuICAgKlxuICAgKiBAbmFtZSBpc0Fib3ZlXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlVG9DaGVja1xuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVRvQmVBYm92ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNBYm92ZSA9IGZ1bmN0aW9uICh2YWwsIGFidiwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZywgYXNzZXJ0LmlzQWJvdmUsIHRydWUpLnRvLmJlLmFib3ZlKGFidik7XG4gIH07XG5cbiAgIC8qKlxuICAgKiAjIyMgLmlzQXRMZWFzdCh2YWx1ZVRvQ2hlY2ssIHZhbHVlVG9CZUF0TGVhc3QsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyBgdmFsdWVUb0NoZWNrYCBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gKD49KSBgdmFsdWVUb0JlQXRMZWFzdGAuXG4gICAqXG4gICAqICAgICBhc3NlcnQuaXNBdExlYXN0KDUsIDIsICc1IGlzIGdyZWF0ZXIgb3IgZXF1YWwgdG8gMicpO1xuICAgKiAgICAgYXNzZXJ0LmlzQXRMZWFzdCgzLCAzLCAnMyBpcyBncmVhdGVyIG9yIGVxdWFsIHRvIDMnKTtcbiAgICpcbiAgICogQG5hbWUgaXNBdExlYXN0XG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlVG9DaGVja1xuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVRvQmVBdExlYXN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc0F0TGVhc3QgPSBmdW5jdGlvbiAodmFsLCBhdGxzdCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZywgYXNzZXJ0LmlzQXRMZWFzdCwgdHJ1ZSkudG8uYmUubGVhc3QoYXRsc3QpO1xuICB9O1xuXG4gICAvKipcbiAgICogIyMjIC5pc0JlbG93KHZhbHVlVG9DaGVjaywgdmFsdWVUb0JlQmVsb3csIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyBgdmFsdWVUb0NoZWNrYCBpcyBzdHJpY3RseSBsZXNzIHRoYW4gKDwpIGB2YWx1ZVRvQmVCZWxvd2AuXG4gICAqXG4gICAqICAgICBhc3NlcnQuaXNCZWxvdygzLCA2LCAnMyBpcyBzdHJpY3RseSBsZXNzIHRoYW4gNicpO1xuICAgKlxuICAgKiBAbmFtZSBpc0JlbG93XG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlVG9DaGVja1xuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVRvQmVCZWxvd1xuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNCZWxvdyA9IGZ1bmN0aW9uICh2YWwsIGJsdywgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZywgYXNzZXJ0LmlzQmVsb3csIHRydWUpLnRvLmJlLmJlbG93KGJsdyk7XG4gIH07XG5cbiAgIC8qKlxuICAgKiAjIyMgLmlzQXRNb3N0KHZhbHVlVG9DaGVjaywgdmFsdWVUb0JlQXRNb3N0LCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgYHZhbHVlVG9DaGVja2AgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICg8PSkgYHZhbHVlVG9CZUF0TW9zdGAuXG4gICAqXG4gICAqICAgICBhc3NlcnQuaXNBdE1vc3QoMywgNiwgJzMgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIDYnKTtcbiAgICogICAgIGFzc2VydC5pc0F0TW9zdCg0LCA0LCAnNCBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gNCcpO1xuICAgKlxuICAgKiBAbmFtZSBpc0F0TW9zdFxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVRvQ2hlY2tcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVUb0JlQXRNb3N0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc0F0TW9zdCA9IGZ1bmN0aW9uICh2YWwsIGF0bXN0LCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnLCBhc3NlcnQuaXNBdE1vc3QsIHRydWUpLnRvLmJlLm1vc3QoYXRtc3QpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzVHJ1ZSh2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyB0cnVlLlxuICAgKlxuICAgKiAgICAgdmFyIHRlYVNlcnZlZCA9IHRydWU7XG4gICAqICAgICBhc3NlcnQuaXNUcnVlKHRlYVNlcnZlZCwgJ3RoZSB0ZWEgaGFzIGJlZW4gc2VydmVkJyk7XG4gICAqXG4gICAqIEBuYW1lIGlzVHJ1ZVxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNUcnVlID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZywgYXNzZXJ0LmlzVHJ1ZSwgdHJ1ZSkuaXNbJ3RydWUnXTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc05vdFRydWUodmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgbm90IHRydWUuXG4gICAqXG4gICAqICAgICB2YXIgdGVhID0gJ3Rhc3R5IGNoYWknO1xuICAgKiAgICAgYXNzZXJ0LmlzTm90VHJ1ZSh0ZWEsICdncmVhdCwgdGltZSBmb3IgdGVhIScpO1xuICAgKlxuICAgKiBAbmFtZSBpc05vdFRydWVcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzTm90VHJ1ZSA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2csIGFzc2VydC5pc05vdFRydWUsIHRydWUpLnRvLm5vdC5lcXVhbCh0cnVlKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc0ZhbHNlKHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGlzIGZhbHNlLlxuICAgKlxuICAgKiAgICAgdmFyIHRlYVNlcnZlZCA9IGZhbHNlO1xuICAgKiAgICAgYXNzZXJ0LmlzRmFsc2UodGVhU2VydmVkLCAnbm8gdGVhIHlldD8gaG1tLi4uJyk7XG4gICAqXG4gICAqIEBuYW1lIGlzRmFsc2VcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzRmFsc2UgPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnLCBhc3NlcnQuaXNGYWxzZSwgdHJ1ZSkuaXNbJ2ZhbHNlJ107XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNOb3RGYWxzZSh2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyBub3QgZmFsc2UuXG4gICAqXG4gICAqICAgICB2YXIgdGVhID0gJ3Rhc3R5IGNoYWknO1xuICAgKiAgICAgYXNzZXJ0LmlzTm90RmFsc2UodGVhLCAnZ3JlYXQsIHRpbWUgZm9yIHRlYSEnKTtcbiAgICpcbiAgICogQG5hbWUgaXNOb3RGYWxzZVxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNOb3RGYWxzZSA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2csIGFzc2VydC5pc05vdEZhbHNlLCB0cnVlKS50by5ub3QuZXF1YWwoZmFsc2UpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzTnVsbCh2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyBudWxsLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmlzTnVsbChlcnIsICd0aGVyZSB3YXMgbm8gZXJyb3InKTtcbiAgICpcbiAgICogQG5hbWUgaXNOdWxsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc051bGwgPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnLCBhc3NlcnQuaXNOdWxsLCB0cnVlKS50by5lcXVhbChudWxsKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc05vdE51bGwodmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgbm90IG51bGwuXG4gICAqXG4gICAqICAgICB2YXIgdGVhID0gJ3Rhc3R5IGNoYWknO1xuICAgKiAgICAgYXNzZXJ0LmlzTm90TnVsbCh0ZWEsICdncmVhdCwgdGltZSBmb3IgdGVhIScpO1xuICAgKlxuICAgKiBAbmFtZSBpc05vdE51bGxcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzTm90TnVsbCA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2csIGFzc2VydC5pc05vdE51bGwsIHRydWUpLnRvLm5vdC5lcXVhbChudWxsKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc05hTlxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdmFsdWUgaXMgTmFOLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmlzTmFOKE5hTiwgJ05hTiBpcyBOYU4nKTtcbiAgICpcbiAgICogQG5hbWUgaXNOYU5cbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzTmFOID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZywgYXNzZXJ0LmlzTmFOLCB0cnVlKS50by5iZS5OYU47XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNOb3ROYU5cbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHZhbHVlIGlzIG5vdCBOYU4uXG4gICAqXG4gICAqICAgICBhc3NlcnQuaXNOb3ROYU4oNCwgJzQgaXMgbm90IE5hTicpO1xuICAgKlxuICAgKiBAbmFtZSBpc05vdE5hTlxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cbiAgYXNzZXJ0LmlzTm90TmFOID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZywgYXNzZXJ0LmlzTm90TmFOLCB0cnVlKS5ub3QudG8uYmUuTmFOO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmV4aXN0c1xuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBuZWl0aGVyIGBudWxsYCBub3IgYHVuZGVmaW5lZGAuXG4gICAqXG4gICAqICAgICB2YXIgZm9vID0gJ2hpJztcbiAgICpcbiAgICogICAgIGFzc2VydC5leGlzdHMoZm9vLCAnZm9vIGlzIG5laXRoZXIgYG51bGxgIG5vciBgdW5kZWZpbmVkYCcpO1xuICAgKlxuICAgKiBAbmFtZSBleGlzdHNcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmV4aXN0cyA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2csIGFzc2VydC5leGlzdHMsIHRydWUpLnRvLmV4aXN0O1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm5vdEV4aXN0c1xuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBlaXRoZXIgYG51bGxgIG9yIGB1bmRlZmluZWRgLlxuICAgKlxuICAgKiAgICAgdmFyIGJhciA9IG51bGxcbiAgICogICAgICAgLCBiYXo7XG4gICAqXG4gICAqICAgICBhc3NlcnQubm90RXhpc3RzKGJhcik7XG4gICAqICAgICBhc3NlcnQubm90RXhpc3RzKGJheiwgJ2JheiBpcyBlaXRoZXIgbnVsbCBvciB1bmRlZmluZWQnKTtcbiAgICpcbiAgICogQG5hbWUgbm90RXhpc3RzXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5ub3RFeGlzdHMgPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnLCBhc3NlcnQubm90RXhpc3RzLCB0cnVlKS50by5ub3QuZXhpc3Q7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNVbmRlZmluZWQodmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgYHVuZGVmaW5lZGAuXG4gICAqXG4gICAqICAgICB2YXIgdGVhO1xuICAgKiAgICAgYXNzZXJ0LmlzVW5kZWZpbmVkKHRlYSwgJ25vIHRlYSBkZWZpbmVkJyk7XG4gICAqXG4gICAqIEBuYW1lIGlzVW5kZWZpbmVkXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc1VuZGVmaW5lZCA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2csIGFzc2VydC5pc1VuZGVmaW5lZCwgdHJ1ZSkudG8uZXF1YWwodW5kZWZpbmVkKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc0RlZmluZWQodmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgbm90IGB1bmRlZmluZWRgLlxuICAgKlxuICAgKiAgICAgdmFyIHRlYSA9ICdjdXAgb2YgY2hhaSc7XG4gICAqICAgICBhc3NlcnQuaXNEZWZpbmVkKHRlYSwgJ3RlYSBoYXMgYmVlbiBkZWZpbmVkJyk7XG4gICAqXG4gICAqIEBuYW1lIGlzRGVmaW5lZFxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNEZWZpbmVkID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZywgYXNzZXJ0LmlzRGVmaW5lZCwgdHJ1ZSkudG8ubm90LmVxdWFsKHVuZGVmaW5lZCk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNGdW5jdGlvbih2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyBhIGZ1bmN0aW9uLlxuICAgKlxuICAgKiAgICAgZnVuY3Rpb24gc2VydmVUZWEoKSB7IHJldHVybiAnY3VwIG9mIHRlYSc7IH07XG4gICAqICAgICBhc3NlcnQuaXNGdW5jdGlvbihzZXJ2ZVRlYSwgJ2dyZWF0LCB3ZSBjYW4gaGF2ZSB0ZWEgbm93Jyk7XG4gICAqXG4gICAqIEBuYW1lIGlzRnVuY3Rpb25cbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzRnVuY3Rpb24gPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnLCBhc3NlcnQuaXNGdW5jdGlvbiwgdHJ1ZSkudG8uYmUuYSgnZnVuY3Rpb24nKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc05vdEZ1bmN0aW9uKHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGlzIF9ub3RfIGEgZnVuY3Rpb24uXG4gICAqXG4gICAqICAgICB2YXIgc2VydmVUZWEgPSBbICdoZWF0JywgJ3BvdXInLCAnc2lwJyBdO1xuICAgKiAgICAgYXNzZXJ0LmlzTm90RnVuY3Rpb24oc2VydmVUZWEsICdncmVhdCwgd2UgaGF2ZSBsaXN0ZWQgdGhlIHN0ZXBzJyk7XG4gICAqXG4gICAqIEBuYW1lIGlzTm90RnVuY3Rpb25cbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzTm90RnVuY3Rpb24gPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnLCBhc3NlcnQuaXNOb3RGdW5jdGlvbiwgdHJ1ZSkudG8ubm90LmJlLmEoJ2Z1bmN0aW9uJyk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNPYmplY3QodmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgYW4gb2JqZWN0IG9mIHR5cGUgJ09iamVjdCcgKGFzIHJldmVhbGVkIGJ5IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nYCkuXG4gICAqIF9UaGUgYXNzZXJ0aW9uIGRvZXMgbm90IG1hdGNoIHN1YmNsYXNzZWQgb2JqZWN0cy5fXG4gICAqXG4gICAqICAgICB2YXIgc2VsZWN0aW9uID0geyBuYW1lOiAnQ2hhaScsIHNlcnZlOiAnd2l0aCBzcGljZXMnIH07XG4gICAqICAgICBhc3NlcnQuaXNPYmplY3Qoc2VsZWN0aW9uLCAndGVhIHNlbGVjdGlvbiBpcyBhbiBvYmplY3QnKTtcbiAgICpcbiAgICogQG5hbWUgaXNPYmplY3RcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzT2JqZWN0ID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZywgYXNzZXJ0LmlzT2JqZWN0LCB0cnVlKS50by5iZS5hKCdvYmplY3QnKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc05vdE9iamVjdCh2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyBfbm90XyBhbiBvYmplY3Qgb2YgdHlwZSAnT2JqZWN0JyAoYXMgcmV2ZWFsZWQgYnkgYE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmdgKS5cbiAgICpcbiAgICogICAgIHZhciBzZWxlY3Rpb24gPSAnY2hhaSdcbiAgICogICAgIGFzc2VydC5pc05vdE9iamVjdChzZWxlY3Rpb24sICd0ZWEgc2VsZWN0aW9uIGlzIG5vdCBhbiBvYmplY3QnKTtcbiAgICogICAgIGFzc2VydC5pc05vdE9iamVjdChudWxsLCAnbnVsbCBpcyBub3QgYW4gb2JqZWN0Jyk7XG4gICAqXG4gICAqIEBuYW1lIGlzTm90T2JqZWN0XG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc05vdE9iamVjdCA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2csIGFzc2VydC5pc05vdE9iamVjdCwgdHJ1ZSkudG8ubm90LmJlLmEoJ29iamVjdCcpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzQXJyYXkodmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgYW4gYXJyYXkuXG4gICAqXG4gICAqICAgICB2YXIgbWVudSA9IFsgJ2dyZWVuJywgJ2NoYWknLCAnb29sb25nJyBdO1xuICAgKiAgICAgYXNzZXJ0LmlzQXJyYXkobWVudSwgJ3doYXQga2luZCBvZiB0ZWEgZG8gd2Ugd2FudD8nKTtcbiAgICpcbiAgICogQG5hbWUgaXNBcnJheVxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNBcnJheSA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2csIGFzc2VydC5pc0FycmF5LCB0cnVlKS50by5iZS5hbignYXJyYXknKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc05vdEFycmF5KHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGlzIF9ub3RfIGFuIGFycmF5LlxuICAgKlxuICAgKiAgICAgdmFyIG1lbnUgPSAnZ3JlZW58Y2hhaXxvb2xvbmcnO1xuICAgKiAgICAgYXNzZXJ0LmlzTm90QXJyYXkobWVudSwgJ3doYXQga2luZCBvZiB0ZWEgZG8gd2Ugd2FudD8nKTtcbiAgICpcbiAgICogQG5hbWUgaXNOb3RBcnJheVxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNOb3RBcnJheSA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2csIGFzc2VydC5pc05vdEFycmF5LCB0cnVlKS50by5ub3QuYmUuYW4oJ2FycmF5Jyk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNTdHJpbmcodmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgYSBzdHJpbmcuXG4gICAqXG4gICAqICAgICB2YXIgdGVhT3JkZXIgPSAnY2hhaSc7XG4gICAqICAgICBhc3NlcnQuaXNTdHJpbmcodGVhT3JkZXIsICdvcmRlciBwbGFjZWQnKTtcbiAgICpcbiAgICogQG5hbWUgaXNTdHJpbmdcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzU3RyaW5nID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZywgYXNzZXJ0LmlzU3RyaW5nLCB0cnVlKS50by5iZS5hKCdzdHJpbmcnKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc05vdFN0cmluZyh2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyBfbm90XyBhIHN0cmluZy5cbiAgICpcbiAgICogICAgIHZhciB0ZWFPcmRlciA9IDQ7XG4gICAqICAgICBhc3NlcnQuaXNOb3RTdHJpbmcodGVhT3JkZXIsICdvcmRlciBwbGFjZWQnKTtcbiAgICpcbiAgICogQG5hbWUgaXNOb3RTdHJpbmdcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzTm90U3RyaW5nID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZywgYXNzZXJ0LmlzTm90U3RyaW5nLCB0cnVlKS50by5ub3QuYmUuYSgnc3RyaW5nJyk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNOdW1iZXIodmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgYSBudW1iZXIuXG4gICAqXG4gICAqICAgICB2YXIgY3VwcyA9IDI7XG4gICAqICAgICBhc3NlcnQuaXNOdW1iZXIoY3VwcywgJ2hvdyBtYW55IGN1cHMnKTtcbiAgICpcbiAgICogQG5hbWUgaXNOdW1iZXJcbiAgICogQHBhcmFtIHtOdW1iZXJ9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc051bWJlciA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2csIGFzc2VydC5pc051bWJlciwgdHJ1ZSkudG8uYmUuYSgnbnVtYmVyJyk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNOb3ROdW1iZXIodmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgX25vdF8gYSBudW1iZXIuXG4gICAqXG4gICAqICAgICB2YXIgY3VwcyA9ICcyIGN1cHMgcGxlYXNlJztcbiAgICogICAgIGFzc2VydC5pc05vdE51bWJlcihjdXBzLCAnaG93IG1hbnkgY3VwcycpO1xuICAgKlxuICAgKiBAbmFtZSBpc05vdE51bWJlclxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNOb3ROdW1iZXIgPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnLCBhc3NlcnQuaXNOb3ROdW1iZXIsIHRydWUpLnRvLm5vdC5iZS5hKCdudW1iZXInKTtcbiAgfTtcblxuICAgLyoqXG4gICAqICMjIyAuaXNGaW5pdGUodmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgYSBmaW5pdGUgbnVtYmVyLiBVbmxpa2UgYC5pc051bWJlcmAsIHRoaXMgd2lsbCBmYWlsIGZvciBgTmFOYCBhbmQgYEluZmluaXR5YC5cbiAgICpcbiAgICogICAgIHZhciBjdXBzID0gMjtcbiAgICogICAgIGFzc2VydC5pc0Zpbml0ZShjdXBzLCAnaG93IG1hbnkgY3VwcycpO1xuICAgKlxuICAgKiAgICAgYXNzZXJ0LmlzRmluaXRlKE5hTik7IC8vIHRocm93c1xuICAgKlxuICAgKiBAbmFtZSBpc0Zpbml0ZVxuICAgKiBAcGFyYW0ge051bWJlcn0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzRmluaXRlID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZywgYXNzZXJ0LmlzRmluaXRlLCB0cnVlKS50by5iZS5maW5pdGU7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNCb29sZWFuKHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGlzIGEgYm9vbGVhbi5cbiAgICpcbiAgICogICAgIHZhciB0ZWFSZWFkeSA9IHRydWVcbiAgICogICAgICAgLCB0ZWFTZXJ2ZWQgPSBmYWxzZTtcbiAgICpcbiAgICogICAgIGFzc2VydC5pc0Jvb2xlYW4odGVhUmVhZHksICdpcyB0aGUgdGVhIHJlYWR5Jyk7XG4gICAqICAgICBhc3NlcnQuaXNCb29sZWFuKHRlYVNlcnZlZCwgJ2hhcyB0ZWEgYmVlbiBzZXJ2ZWQnKTtcbiAgICpcbiAgICogQG5hbWUgaXNCb29sZWFuXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc0Jvb2xlYW4gPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnLCBhc3NlcnQuaXNCb29sZWFuLCB0cnVlKS50by5iZS5hKCdib29sZWFuJyk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNOb3RCb29sZWFuKHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGlzIF9ub3RfIGEgYm9vbGVhbi5cbiAgICpcbiAgICogICAgIHZhciB0ZWFSZWFkeSA9ICd5ZXAnXG4gICAqICAgICAgICwgdGVhU2VydmVkID0gJ25vcGUnO1xuICAgKlxuICAgKiAgICAgYXNzZXJ0LmlzTm90Qm9vbGVhbih0ZWFSZWFkeSwgJ2lzIHRoZSB0ZWEgcmVhZHknKTtcbiAgICogICAgIGFzc2VydC5pc05vdEJvb2xlYW4odGVhU2VydmVkLCAnaGFzIHRlYSBiZWVuIHNlcnZlZCcpO1xuICAgKlxuICAgKiBAbmFtZSBpc05vdEJvb2xlYW5cbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzTm90Qm9vbGVhbiA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2csIGFzc2VydC5pc05vdEJvb2xlYW4sIHRydWUpLnRvLm5vdC5iZS5hKCdib29sZWFuJyk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAudHlwZU9mKHZhbHVlLCBuYW1lLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgJ3MgdHlwZSBpcyBgbmFtZWAsIGFzIGRldGVybWluZWQgYnlcbiAgICogYE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmdgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LnR5cGVPZih7IHRlYTogJ2NoYWknIH0sICdvYmplY3QnLCAnd2UgaGF2ZSBhbiBvYmplY3QnKTtcbiAgICogICAgIGFzc2VydC50eXBlT2YoWydjaGFpJywgJ2phc21pbmUnXSwgJ2FycmF5JywgJ3dlIGhhdmUgYW4gYXJyYXknKTtcbiAgICogICAgIGFzc2VydC50eXBlT2YoJ3RlYScsICdzdHJpbmcnLCAnd2UgaGF2ZSBhIHN0cmluZycpO1xuICAgKiAgICAgYXNzZXJ0LnR5cGVPZigvdGVhLywgJ3JlZ2V4cCcsICd3ZSBoYXZlIGEgcmVndWxhciBleHByZXNzaW9uJyk7XG4gICAqICAgICBhc3NlcnQudHlwZU9mKG51bGwsICdudWxsJywgJ3dlIGhhdmUgYSBudWxsJyk7XG4gICAqICAgICBhc3NlcnQudHlwZU9mKHVuZGVmaW5lZCwgJ3VuZGVmaW5lZCcsICd3ZSBoYXZlIGFuIHVuZGVmaW5lZCcpO1xuICAgKlxuICAgKiBAbmFtZSB0eXBlT2ZcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LnR5cGVPZiA9IGZ1bmN0aW9uICh2YWwsIHR5cGUsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2csIGFzc2VydC50eXBlT2YsIHRydWUpLnRvLmJlLmEodHlwZSk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAubm90VHlwZU9mKHZhbHVlLCBuYW1lLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgJ3MgdHlwZSBpcyBfbm90XyBgbmFtZWAsIGFzIGRldGVybWluZWQgYnlcbiAgICogYE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmdgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm5vdFR5cGVPZigndGVhJywgJ251bWJlcicsICdzdHJpbmdzIGFyZSBub3QgbnVtYmVycycpO1xuICAgKlxuICAgKiBAbmFtZSBub3RUeXBlT2ZcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IHR5cGVvZiBuYW1lXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5ub3RUeXBlT2YgPSBmdW5jdGlvbiAodmFsLCB0eXBlLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnLCBhc3NlcnQubm90VHlwZU9mLCB0cnVlKS50by5ub3QuYmUuYSh0eXBlKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pbnN0YW5jZU9mKG9iamVjdCwgY29uc3RydWN0b3IsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgYW4gaW5zdGFuY2Ugb2YgYGNvbnN0cnVjdG9yYC5cbiAgICpcbiAgICogICAgIHZhciBUZWEgPSBmdW5jdGlvbiAobmFtZSkgeyB0aGlzLm5hbWUgPSBuYW1lOyB9XG4gICAqICAgICAgICwgY2hhaSA9IG5ldyBUZWEoJ2NoYWknKTtcbiAgICpcbiAgICogICAgIGFzc2VydC5pbnN0YW5jZU9mKGNoYWksIFRlYSwgJ2NoYWkgaXMgYW4gaW5zdGFuY2Ugb2YgdGVhJyk7XG4gICAqXG4gICAqIEBuYW1lIGluc3RhbmNlT2ZcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge0NvbnN0cnVjdG9yfSBjb25zdHJ1Y3RvclxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaW5zdGFuY2VPZiA9IGZ1bmN0aW9uICh2YWwsIHR5cGUsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2csIGFzc2VydC5pbnN0YW5jZU9mLCB0cnVlKS50by5iZS5pbnN0YW5jZU9mKHR5cGUpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm5vdEluc3RhbmNlT2Yob2JqZWN0LCBjb25zdHJ1Y3RvciwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIGB2YWx1ZWAgaXMgbm90IGFuIGluc3RhbmNlIG9mIGBjb25zdHJ1Y3RvcmAuXG4gICAqXG4gICAqICAgICB2YXIgVGVhID0gZnVuY3Rpb24gKG5hbWUpIHsgdGhpcy5uYW1lID0gbmFtZTsgfVxuICAgKiAgICAgICAsIGNoYWkgPSBuZXcgU3RyaW5nKCdjaGFpJyk7XG4gICAqXG4gICAqICAgICBhc3NlcnQubm90SW5zdGFuY2VPZihjaGFpLCBUZWEsICdjaGFpIGlzIG5vdCBhbiBpbnN0YW5jZSBvZiB0ZWEnKTtcbiAgICpcbiAgICogQG5hbWUgbm90SW5zdGFuY2VPZlxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7Q29uc3RydWN0b3J9IGNvbnN0cnVjdG9yXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5ub3RJbnN0YW5jZU9mID0gZnVuY3Rpb24gKHZhbCwgdHlwZSwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZywgYXNzZXJ0Lm5vdEluc3RhbmNlT2YsIHRydWUpXG4gICAgICAudG8ubm90LmJlLmluc3RhbmNlT2YodHlwZSk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaW5jbHVkZShoYXlzdGFjaywgbmVlZGxlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgaGF5c3RhY2tgIGluY2x1ZGVzIGBuZWVkbGVgLiBDYW4gYmUgdXNlZCB0byBhc3NlcnQgdGhlXG4gICAqIGluY2x1c2lvbiBvZiBhIHZhbHVlIGluIGFuIGFycmF5LCBhIHN1YnN0cmluZyBpbiBhIHN0cmluZywgb3IgYSBzdWJzZXQgb2ZcbiAgICogcHJvcGVydGllcyBpbiBhbiBvYmplY3QuXG4gICAqXG4gICAqICAgICBhc3NlcnQuaW5jbHVkZShbMSwyLDNdLCAyLCAnYXJyYXkgY29udGFpbnMgdmFsdWUnKTtcbiAgICogICAgIGFzc2VydC5pbmNsdWRlKCdmb29iYXInLCAnZm9vJywgJ3N0cmluZyBjb250YWlucyBzdWJzdHJpbmcnKTtcbiAgICogICAgIGFzc2VydC5pbmNsdWRlKHsgZm9vOiAnYmFyJywgaGVsbG86ICd1bml2ZXJzZScgfSwgeyBmb286ICdiYXInIH0sICdvYmplY3QgY29udGFpbnMgcHJvcGVydHknKTtcbiAgICpcbiAgICogU3RyaWN0IGVxdWFsaXR5ICg9PT0pIGlzIHVzZWQuIFdoZW4gYXNzZXJ0aW5nIHRoZSBpbmNsdXNpb24gb2YgYSB2YWx1ZSBpblxuICAgKiBhbiBhcnJheSwgdGhlIGFycmF5IGlzIHNlYXJjaGVkIGZvciBhbiBlbGVtZW50IHRoYXQncyBzdHJpY3RseSBlcXVhbCB0byB0aGVcbiAgICogZ2l2ZW4gdmFsdWUuIFdoZW4gYXNzZXJ0aW5nIGEgc3Vic2V0IG9mIHByb3BlcnRpZXMgaW4gYW4gb2JqZWN0LCB0aGUgb2JqZWN0XG4gICAqIGlzIHNlYXJjaGVkIGZvciB0aGUgZ2l2ZW4gcHJvcGVydHkga2V5cywgY2hlY2tpbmcgdGhhdCBlYWNoIG9uZSBpcyBwcmVzZW50XG4gICAqIGFuZCBzdHJpY3RseSBlcXVhbCB0byB0aGUgZ2l2ZW4gcHJvcGVydHkgdmFsdWUuIEZvciBpbnN0YW5jZTpcbiAgICpcbiAgICogICAgIHZhciBvYmoxID0ge2E6IDF9XG4gICAqICAgICAgICwgb2JqMiA9IHtiOiAyfTtcbiAgICogICAgIGFzc2VydC5pbmNsdWRlKFtvYmoxLCBvYmoyXSwgb2JqMSk7XG4gICAqICAgICBhc3NlcnQuaW5jbHVkZSh7Zm9vOiBvYmoxLCBiYXI6IG9iajJ9LCB7Zm9vOiBvYmoxfSk7XG4gICAqICAgICBhc3NlcnQuaW5jbHVkZSh7Zm9vOiBvYmoxLCBiYXI6IG9iajJ9LCB7Zm9vOiBvYmoxLCBiYXI6IG9iajJ9KTtcbiAgICpcbiAgICogQG5hbWUgaW5jbHVkZVxuICAgKiBAcGFyYW0ge0FycmF5fFN0cmluZ30gaGF5c3RhY2tcbiAgICogQHBhcmFtIHtNaXhlZH0gbmVlZGxlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pbmNsdWRlID0gZnVuY3Rpb24gKGV4cCwgaW5jLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKGV4cCwgbXNnLCBhc3NlcnQuaW5jbHVkZSwgdHJ1ZSkuaW5jbHVkZShpbmMpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm5vdEluY2x1ZGUoaGF5c3RhY2ssIG5lZWRsZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYGhheXN0YWNrYCBkb2VzIG5vdCBpbmNsdWRlIGBuZWVkbGVgLiBDYW4gYmUgdXNlZCB0byBhc3NlcnRcbiAgICogdGhlIGFic2VuY2Ugb2YgYSB2YWx1ZSBpbiBhbiBhcnJheSwgYSBzdWJzdHJpbmcgaW4gYSBzdHJpbmcsIG9yIGEgc3Vic2V0IG9mXG4gICAqIHByb3BlcnRpZXMgaW4gYW4gb2JqZWN0LlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm5vdEluY2x1ZGUoWzEsMiwzXSwgNCwgXCJhcnJheSBkb2Vzbid0IGNvbnRhaW4gdmFsdWVcIik7XG4gICAqICAgICBhc3NlcnQubm90SW5jbHVkZSgnZm9vYmFyJywgJ2JheicsIFwic3RyaW5nIGRvZXNuJ3QgY29udGFpbiBzdWJzdHJpbmdcIik7XG4gICAqICAgICBhc3NlcnQubm90SW5jbHVkZSh7IGZvbzogJ2JhcicsIGhlbGxvOiAndW5pdmVyc2UnIH0sIHsgZm9vOiAnYmF6JyB9LCAnb2JqZWN0IGRvZXNuJ3QgY29udGFpbiBwcm9wZXJ0eScpO1xuICAgKlxuICAgKiBTdHJpY3QgZXF1YWxpdHkgKD09PSkgaXMgdXNlZC4gV2hlbiBhc3NlcnRpbmcgdGhlIGFic2VuY2Ugb2YgYSB2YWx1ZSBpbiBhblxuICAgKiBhcnJheSwgdGhlIGFycmF5IGlzIHNlYXJjaGVkIHRvIGNvbmZpcm0gdGhlIGFic2VuY2Ugb2YgYW4gZWxlbWVudCB0aGF0J3NcbiAgICogc3RyaWN0bHkgZXF1YWwgdG8gdGhlIGdpdmVuIHZhbHVlLiBXaGVuIGFzc2VydGluZyBhIHN1YnNldCBvZiBwcm9wZXJ0aWVzIGluXG4gICAqIGFuIG9iamVjdCwgdGhlIG9iamVjdCBpcyBzZWFyY2hlZCB0byBjb25maXJtIHRoYXQgYXQgbGVhc3Qgb25lIG9mIHRoZSBnaXZlblxuICAgKiBwcm9wZXJ0eSBrZXlzIGlzIGVpdGhlciBub3QgcHJlc2VudCBvciBub3Qgc3RyaWN0bHkgZXF1YWwgdG8gdGhlIGdpdmVuXG4gICAqIHByb3BlcnR5IHZhbHVlLiBGb3IgaW5zdGFuY2U6XG4gICAqXG4gICAqICAgICB2YXIgb2JqMSA9IHthOiAxfVxuICAgKiAgICAgICAsIG9iajIgPSB7YjogMn07XG4gICAqICAgICBhc3NlcnQubm90SW5jbHVkZShbb2JqMSwgb2JqMl0sIHthOiAxfSk7XG4gICAqICAgICBhc3NlcnQubm90SW5jbHVkZSh7Zm9vOiBvYmoxLCBiYXI6IG9iajJ9LCB7Zm9vOiB7YTogMX19KTtcbiAgICogICAgIGFzc2VydC5ub3RJbmNsdWRlKHtmb286IG9iajEsIGJhcjogb2JqMn0sIHtmb286IG9iajEsIGJhcjoge2I6IDJ9fSk7XG4gICAqXG4gICAqIEBuYW1lIG5vdEluY2x1ZGVcbiAgICogQHBhcmFtIHtBcnJheXxTdHJpbmd9IGhheXN0YWNrXG4gICAqIEBwYXJhbSB7TWl4ZWR9IG5lZWRsZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubm90SW5jbHVkZSA9IGZ1bmN0aW9uIChleHAsIGluYywgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihleHAsIG1zZywgYXNzZXJ0Lm5vdEluY2x1ZGUsIHRydWUpLm5vdC5pbmNsdWRlKGluYyk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuZGVlcEluY2x1ZGUoaGF5c3RhY2ssIG5lZWRsZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYGhheXN0YWNrYCBpbmNsdWRlcyBgbmVlZGxlYC4gQ2FuIGJlIHVzZWQgdG8gYXNzZXJ0IHRoZVxuICAgKiBpbmNsdXNpb24gb2YgYSB2YWx1ZSBpbiBhbiBhcnJheSBvciBhIHN1YnNldCBvZiBwcm9wZXJ0aWVzIGluIGFuIG9iamVjdC5cbiAgICogRGVlcCBlcXVhbGl0eSBpcyB1c2VkLlxuICAgKlxuICAgKiAgICAgdmFyIG9iajEgPSB7YTogMX1cbiAgICogICAgICAgLCBvYmoyID0ge2I6IDJ9O1xuICAgKiAgICAgYXNzZXJ0LmRlZXBJbmNsdWRlKFtvYmoxLCBvYmoyXSwge2E6IDF9KTtcbiAgICogICAgIGFzc2VydC5kZWVwSW5jbHVkZSh7Zm9vOiBvYmoxLCBiYXI6IG9iajJ9LCB7Zm9vOiB7YTogMX19KTtcbiAgICogICAgIGFzc2VydC5kZWVwSW5jbHVkZSh7Zm9vOiBvYmoxLCBiYXI6IG9iajJ9LCB7Zm9vOiB7YTogMX0sIGJhcjoge2I6IDJ9fSk7XG4gICAqXG4gICAqIEBuYW1lIGRlZXBJbmNsdWRlXG4gICAqIEBwYXJhbSB7QXJyYXl8U3RyaW5nfSBoYXlzdGFja1xuICAgKiBAcGFyYW0ge01peGVkfSBuZWVkbGVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmRlZXBJbmNsdWRlID0gZnVuY3Rpb24gKGV4cCwgaW5jLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKGV4cCwgbXNnLCBhc3NlcnQuZGVlcEluY2x1ZGUsIHRydWUpLmRlZXAuaW5jbHVkZShpbmMpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm5vdERlZXBJbmNsdWRlKGhheXN0YWNrLCBuZWVkbGUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBoYXlzdGFja2AgZG9lcyBub3QgaW5jbHVkZSBgbmVlZGxlYC4gQ2FuIGJlIHVzZWQgdG8gYXNzZXJ0XG4gICAqIHRoZSBhYnNlbmNlIG9mIGEgdmFsdWUgaW4gYW4gYXJyYXkgb3IgYSBzdWJzZXQgb2YgcHJvcGVydGllcyBpbiBhbiBvYmplY3QuXG4gICAqIERlZXAgZXF1YWxpdHkgaXMgdXNlZC5cbiAgICpcbiAgICogICAgIHZhciBvYmoxID0ge2E6IDF9XG4gICAqICAgICAgICwgb2JqMiA9IHtiOiAyfTtcbiAgICogICAgIGFzc2VydC5ub3REZWVwSW5jbHVkZShbb2JqMSwgb2JqMl0sIHthOiA5fSk7XG4gICAqICAgICBhc3NlcnQubm90RGVlcEluY2x1ZGUoe2Zvbzogb2JqMSwgYmFyOiBvYmoyfSwge2Zvbzoge2E6IDl9fSk7XG4gICAqICAgICBhc3NlcnQubm90RGVlcEluY2x1ZGUoe2Zvbzogb2JqMSwgYmFyOiBvYmoyfSwge2Zvbzoge2E6IDF9LCBiYXI6IHtiOiA5fX0pO1xuICAgKlxuICAgKiBAbmFtZSBub3REZWVwSW5jbHVkZVxuICAgKiBAcGFyYW0ge0FycmF5fFN0cmluZ30gaGF5c3RhY2tcbiAgICogQHBhcmFtIHtNaXhlZH0gbmVlZGxlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5ub3REZWVwSW5jbHVkZSA9IGZ1bmN0aW9uIChleHAsIGluYywgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihleHAsIG1zZywgYXNzZXJ0Lm5vdERlZXBJbmNsdWRlLCB0cnVlKS5ub3QuZGVlcC5pbmNsdWRlKGluYyk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAubmVzdGVkSW5jbHVkZShoYXlzdGFjaywgbmVlZGxlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCAnaGF5c3RhY2snIGluY2x1ZGVzICduZWVkbGUnLlxuICAgKiBDYW4gYmUgdXNlZCB0byBhc3NlcnQgdGhlIGluY2x1c2lvbiBvZiBhIHN1YnNldCBvZiBwcm9wZXJ0aWVzIGluIGFuXG4gICAqIG9iamVjdC5cbiAgICogRW5hYmxlcyB0aGUgdXNlIG9mIGRvdC0gYW5kIGJyYWNrZXQtbm90YXRpb24gZm9yIHJlZmVyZW5jaW5nIG5lc3RlZFxuICAgKiBwcm9wZXJ0aWVzLlxuICAgKiAnW10nIGFuZCAnLicgaW4gcHJvcGVydHkgbmFtZXMgY2FuIGJlIGVzY2FwZWQgdXNpbmcgZG91YmxlIGJhY2tzbGFzaGVzLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm5lc3RlZEluY2x1ZGUoeycuYSc6IHsnYic6ICd4J319LCB7J1xcXFwuYS5bYl0nOiAneCd9KTtcbiAgICogICAgIGFzc2VydC5uZXN0ZWRJbmNsdWRlKHsnYSc6IHsnW2JdJzogJ3gnfX0sIHsnYS5cXFxcW2JcXFxcXSc6ICd4J30pO1xuICAgKlxuICAgKiBAbmFtZSBuZXN0ZWRJbmNsdWRlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBoYXlzdGFja1xuICAgKiBAcGFyYW0ge09iamVjdH0gbmVlZGxlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5uZXN0ZWRJbmNsdWRlID0gZnVuY3Rpb24gKGV4cCwgaW5jLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKGV4cCwgbXNnLCBhc3NlcnQubmVzdGVkSW5jbHVkZSwgdHJ1ZSkubmVzdGVkLmluY2x1ZGUoaW5jKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5ub3ROZXN0ZWRJbmNsdWRlKGhheXN0YWNrLCBuZWVkbGUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0ICdoYXlzdGFjaycgZG9lcyBub3QgaW5jbHVkZSAnbmVlZGxlJy5cbiAgICogQ2FuIGJlIHVzZWQgdG8gYXNzZXJ0IHRoZSBhYnNlbmNlIG9mIGEgc3Vic2V0IG9mIHByb3BlcnRpZXMgaW4gYW5cbiAgICogb2JqZWN0LlxuICAgKiBFbmFibGVzIHRoZSB1c2Ugb2YgZG90LSBhbmQgYnJhY2tldC1ub3RhdGlvbiBmb3IgcmVmZXJlbmNpbmcgbmVzdGVkXG4gICAqIHByb3BlcnRpZXMuXG4gICAqICdbXScgYW5kICcuJyBpbiBwcm9wZXJ0eSBuYW1lcyBjYW4gYmUgZXNjYXBlZCB1c2luZyBkb3VibGUgYmFja3NsYXNoZXMuXG4gICAqXG4gICAqICAgICBhc3NlcnQubm90TmVzdGVkSW5jbHVkZSh7Jy5hJzogeydiJzogJ3gnfX0sIHsnXFxcXC5hLmInOiAneSd9KTtcbiAgICogICAgIGFzc2VydC5ub3ROZXN0ZWRJbmNsdWRlKHsnYSc6IHsnW2JdJzogJ3gnfX0sIHsnYS5cXFxcW2JcXFxcXSc6ICd5J30pO1xuICAgKlxuICAgKiBAbmFtZSBub3ROZXN0ZWRJbmNsdWRlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBoYXlzdGFja1xuICAgKiBAcGFyYW0ge09iamVjdH0gbmVlZGxlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5ub3ROZXN0ZWRJbmNsdWRlID0gZnVuY3Rpb24gKGV4cCwgaW5jLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKGV4cCwgbXNnLCBhc3NlcnQubm90TmVzdGVkSW5jbHVkZSwgdHJ1ZSlcbiAgICAgIC5ub3QubmVzdGVkLmluY2x1ZGUoaW5jKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5kZWVwTmVzdGVkSW5jbHVkZShoYXlzdGFjaywgbmVlZGxlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCAnaGF5c3RhY2snIGluY2x1ZGVzICduZWVkbGUnLlxuICAgKiBDYW4gYmUgdXNlZCB0byBhc3NlcnQgdGhlIGluY2x1c2lvbiBvZiBhIHN1YnNldCBvZiBwcm9wZXJ0aWVzIGluIGFuXG4gICAqIG9iamVjdCB3aGlsZSBjaGVja2luZyBmb3IgZGVlcCBlcXVhbGl0eS5cbiAgICogRW5hYmxlcyB0aGUgdXNlIG9mIGRvdC0gYW5kIGJyYWNrZXQtbm90YXRpb24gZm9yIHJlZmVyZW5jaW5nIG5lc3RlZFxuICAgKiBwcm9wZXJ0aWVzLlxuICAgKiAnW10nIGFuZCAnLicgaW4gcHJvcGVydHkgbmFtZXMgY2FuIGJlIGVzY2FwZWQgdXNpbmcgZG91YmxlIGJhY2tzbGFzaGVzLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmRlZXBOZXN0ZWRJbmNsdWRlKHthOiB7YjogW3t4OiAxfV19fSwgeydhLmJbMF0nOiB7eDogMX19KTtcbiAgICogICAgIGFzc2VydC5kZWVwTmVzdGVkSW5jbHVkZSh7Jy5hJzogeydbYl0nOiB7eDogMX19fSwgeydcXFxcLmEuXFxcXFtiXFxcXF0nOiB7eDogMX19KTtcbiAgICpcbiAgICogQG5hbWUgZGVlcE5lc3RlZEluY2x1ZGVcbiAgICogQHBhcmFtIHtPYmplY3R9IGhheXN0YWNrXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBuZWVkbGVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmRlZXBOZXN0ZWRJbmNsdWRlID0gZnVuY3Rpb24oZXhwLCBpbmMsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oZXhwLCBtc2csIGFzc2VydC5kZWVwTmVzdGVkSW5jbHVkZSwgdHJ1ZSlcbiAgICAgIC5kZWVwLm5lc3RlZC5pbmNsdWRlKGluYyk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAubm90RGVlcE5lc3RlZEluY2x1ZGUoaGF5c3RhY2ssIG5lZWRsZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgJ2hheXN0YWNrJyBkb2VzIG5vdCBpbmNsdWRlICduZWVkbGUnLlxuICAgKiBDYW4gYmUgdXNlZCB0byBhc3NlcnQgdGhlIGFic2VuY2Ugb2YgYSBzdWJzZXQgb2YgcHJvcGVydGllcyBpbiBhblxuICAgKiBvYmplY3Qgd2hpbGUgY2hlY2tpbmcgZm9yIGRlZXAgZXF1YWxpdHkuXG4gICAqIEVuYWJsZXMgdGhlIHVzZSBvZiBkb3QtIGFuZCBicmFja2V0LW5vdGF0aW9uIGZvciByZWZlcmVuY2luZyBuZXN0ZWRcbiAgICogcHJvcGVydGllcy5cbiAgICogJ1tdJyBhbmQgJy4nIGluIHByb3BlcnR5IG5hbWVzIGNhbiBiZSBlc2NhcGVkIHVzaW5nIGRvdWJsZSBiYWNrc2xhc2hlcy5cbiAgICpcbiAgICogICAgIGFzc2VydC5ub3REZWVwTmVzdGVkSW5jbHVkZSh7YToge2I6IFt7eDogMX1dfX0sIHsnYS5iWzBdJzoge3k6IDF9fSlcbiAgICogICAgIGFzc2VydC5ub3REZWVwTmVzdGVkSW5jbHVkZSh7Jy5hJzogeydbYl0nOiB7eDogMX19fSwgeydcXFxcLmEuXFxcXFtiXFxcXF0nOiB7eTogMn19KTtcbiAgICpcbiAgICogQG5hbWUgbm90RGVlcE5lc3RlZEluY2x1ZGVcbiAgICogQHBhcmFtIHtPYmplY3R9IGhheXN0YWNrXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBuZWVkbGVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm5vdERlZXBOZXN0ZWRJbmNsdWRlID0gZnVuY3Rpb24oZXhwLCBpbmMsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oZXhwLCBtc2csIGFzc2VydC5ub3REZWVwTmVzdGVkSW5jbHVkZSwgdHJ1ZSlcbiAgICAgIC5ub3QuZGVlcC5uZXN0ZWQuaW5jbHVkZShpbmMpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm93bkluY2x1ZGUoaGF5c3RhY2ssIG5lZWRsZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgJ2hheXN0YWNrJyBpbmNsdWRlcyAnbmVlZGxlJy5cbiAgICogQ2FuIGJlIHVzZWQgdG8gYXNzZXJ0IHRoZSBpbmNsdXNpb24gb2YgYSBzdWJzZXQgb2YgcHJvcGVydGllcyBpbiBhblxuICAgKiBvYmplY3Qgd2hpbGUgaWdub3JpbmcgaW5oZXJpdGVkIHByb3BlcnRpZXMuXG4gICAqXG4gICAqICAgICBhc3NlcnQub3duSW5jbHVkZSh7IGE6IDEgfSwgeyBhOiAxIH0pO1xuICAgKlxuICAgKiBAbmFtZSBvd25JbmNsdWRlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBoYXlzdGFja1xuICAgKiBAcGFyYW0ge09iamVjdH0gbmVlZGxlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5vd25JbmNsdWRlID0gZnVuY3Rpb24oZXhwLCBpbmMsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oZXhwLCBtc2csIGFzc2VydC5vd25JbmNsdWRlLCB0cnVlKS5vd24uaW5jbHVkZShpbmMpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm5vdE93bkluY2x1ZGUoaGF5c3RhY2ssIG5lZWRsZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgJ2hheXN0YWNrJyBpbmNsdWRlcyAnbmVlZGxlJy5cbiAgICogQ2FuIGJlIHVzZWQgdG8gYXNzZXJ0IHRoZSBhYnNlbmNlIG9mIGEgc3Vic2V0IG9mIHByb3BlcnRpZXMgaW4gYW5cbiAgICogb2JqZWN0IHdoaWxlIGlnbm9yaW5nIGluaGVyaXRlZCBwcm9wZXJ0aWVzLlxuICAgKlxuICAgKiAgICAgT2JqZWN0LnByb3RvdHlwZS5iID0gMjtcbiAgICpcbiAgICogICAgIGFzc2VydC5ub3RPd25JbmNsdWRlKHsgYTogMSB9LCB7IGI6IDIgfSk7XG4gICAqXG4gICAqIEBuYW1lIG5vdE93bkluY2x1ZGVcbiAgICogQHBhcmFtIHtPYmplY3R9IGhheXN0YWNrXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBuZWVkbGVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm5vdE93bkluY2x1ZGUgPSBmdW5jdGlvbihleHAsIGluYywgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihleHAsIG1zZywgYXNzZXJ0Lm5vdE93bkluY2x1ZGUsIHRydWUpLm5vdC5vd24uaW5jbHVkZShpbmMpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmRlZXBPd25JbmNsdWRlKGhheXN0YWNrLCBuZWVkbGUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0ICdoYXlzdGFjaycgaW5jbHVkZXMgJ25lZWRsZScuXG4gICAqIENhbiBiZSB1c2VkIHRvIGFzc2VydCB0aGUgaW5jbHVzaW9uIG9mIGEgc3Vic2V0IG9mIHByb3BlcnRpZXMgaW4gYW5cbiAgICogb2JqZWN0IHdoaWxlIGlnbm9yaW5nIGluaGVyaXRlZCBwcm9wZXJ0aWVzIGFuZCBjaGVja2luZyBmb3IgZGVlcCBlcXVhbGl0eS5cbiAgICpcbiAgICogICAgICBhc3NlcnQuZGVlcE93bkluY2x1ZGUoe2E6IHtiOiAyfX0sIHthOiB7YjogMn19KTtcbiAgICpcbiAgICogQG5hbWUgZGVlcE93bkluY2x1ZGVcbiAgICogQHBhcmFtIHtPYmplY3R9IGhheXN0YWNrXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBuZWVkbGVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmRlZXBPd25JbmNsdWRlID0gZnVuY3Rpb24oZXhwLCBpbmMsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oZXhwLCBtc2csIGFzc2VydC5kZWVwT3duSW5jbHVkZSwgdHJ1ZSlcbiAgICAgIC5kZWVwLm93bi5pbmNsdWRlKGluYyk7XG4gIH07XG5cbiAgIC8qKlxuICAgKiAjIyMgLm5vdERlZXBPd25JbmNsdWRlKGhheXN0YWNrLCBuZWVkbGUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0ICdoYXlzdGFjaycgaW5jbHVkZXMgJ25lZWRsZScuXG4gICAqIENhbiBiZSB1c2VkIHRvIGFzc2VydCB0aGUgYWJzZW5jZSBvZiBhIHN1YnNldCBvZiBwcm9wZXJ0aWVzIGluIGFuXG4gICAqIG9iamVjdCB3aGlsZSBpZ25vcmluZyBpbmhlcml0ZWQgcHJvcGVydGllcyBhbmQgY2hlY2tpbmcgZm9yIGRlZXAgZXF1YWxpdHkuXG4gICAqXG4gICAqICAgICAgYXNzZXJ0Lm5vdERlZXBPd25JbmNsdWRlKHthOiB7YjogMn19LCB7YToge2M6IDN9fSk7XG4gICAqXG4gICAqIEBuYW1lIG5vdERlZXBPd25JbmNsdWRlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBoYXlzdGFja1xuICAgKiBAcGFyYW0ge09iamVjdH0gbmVlZGxlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5ub3REZWVwT3duSW5jbHVkZSA9IGZ1bmN0aW9uKGV4cCwgaW5jLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKGV4cCwgbXNnLCBhc3NlcnQubm90RGVlcE93bkluY2x1ZGUsIHRydWUpXG4gICAgICAubm90LmRlZXAub3duLmluY2x1ZGUoaW5jKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5tYXRjaCh2YWx1ZSwgcmVnZXhwLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIG1hdGNoZXMgdGhlIHJlZ3VsYXIgZXhwcmVzc2lvbiBgcmVnZXhwYC5cbiAgICpcbiAgICogICAgIGFzc2VydC5tYXRjaCgnZm9vYmFyJywgL15mb28vLCAncmVnZXhwIG1hdGNoZXMnKTtcbiAgICpcbiAgICogQG5hbWUgbWF0Y2hcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtSZWdFeHB9IHJlZ2V4cFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubWF0Y2ggPSBmdW5jdGlvbiAoZXhwLCByZSwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihleHAsIG1zZywgYXNzZXJ0Lm1hdGNoLCB0cnVlKS50by5tYXRjaChyZSk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAubm90TWF0Y2godmFsdWUsIHJlZ2V4cCwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBkb2VzIG5vdCBtYXRjaCB0aGUgcmVndWxhciBleHByZXNzaW9uIGByZWdleHBgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm5vdE1hdGNoKCdmb29iYXInLCAvXmZvby8sICdyZWdleHAgZG9lcyBub3QgbWF0Y2gnKTtcbiAgICpcbiAgICogQG5hbWUgbm90TWF0Y2hcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtSZWdFeHB9IHJlZ2V4cFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubm90TWF0Y2ggPSBmdW5jdGlvbiAoZXhwLCByZSwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihleHAsIG1zZywgYXNzZXJ0Lm5vdE1hdGNoLCB0cnVlKS50by5ub3QubWF0Y2gocmUpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLnByb3BlcnR5KG9iamVjdCwgcHJvcGVydHksIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGhhcyBhIGRpcmVjdCBvciBpbmhlcml0ZWQgcHJvcGVydHkgbmFtZWQgYnlcbiAgICogYHByb3BlcnR5YC5cbiAgICpcbiAgICogICAgIGFzc2VydC5wcm9wZXJ0eSh7IHRlYTogeyBncmVlbjogJ21hdGNoYScgfX0sICd0ZWEnKTtcbiAgICogICAgIGFzc2VydC5wcm9wZXJ0eSh7IHRlYTogeyBncmVlbjogJ21hdGNoYScgfX0sICd0b1N0cmluZycpO1xuICAgKlxuICAgKiBAbmFtZSBwcm9wZXJ0eVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQucHJvcGVydHkgPSBmdW5jdGlvbiAob2JqLCBwcm9wLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnLCBhc3NlcnQucHJvcGVydHksIHRydWUpLnRvLmhhdmUucHJvcGVydHkocHJvcCk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAubm90UHJvcGVydHkob2JqZWN0LCBwcm9wZXJ0eSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgZG9lcyBfbm90XyBoYXZlIGEgZGlyZWN0IG9yIGluaGVyaXRlZCBwcm9wZXJ0eSBuYW1lZFxuICAgKiBieSBgcHJvcGVydHlgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm5vdFByb3BlcnR5KHsgdGVhOiB7IGdyZWVuOiAnbWF0Y2hhJyB9fSwgJ2NvZmZlZScpO1xuICAgKlxuICAgKiBAbmFtZSBub3RQcm9wZXJ0eVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubm90UHJvcGVydHkgPSBmdW5jdGlvbiAob2JqLCBwcm9wLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnLCBhc3NlcnQubm90UHJvcGVydHksIHRydWUpXG4gICAgICAudG8ubm90LmhhdmUucHJvcGVydHkocHJvcCk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAucHJvcGVydHlWYWwob2JqZWN0LCBwcm9wZXJ0eSwgdmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGhhcyBhIGRpcmVjdCBvciBpbmhlcml0ZWQgcHJvcGVydHkgbmFtZWQgYnlcbiAgICogYHByb3BlcnR5YCB3aXRoIGEgdmFsdWUgZ2l2ZW4gYnkgYHZhbHVlYC4gVXNlcyBhIHN0cmljdCBlcXVhbGl0eSBjaGVja1xuICAgKiAoPT09KS5cbiAgICpcbiAgICogICAgIGFzc2VydC5wcm9wZXJ0eVZhbCh7IHRlYTogJ2lzIGdvb2QnIH0sICd0ZWEnLCAnaXMgZ29vZCcpO1xuICAgKlxuICAgKiBAbmFtZSBwcm9wZXJ0eVZhbFxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eVxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQucHJvcGVydHlWYWwgPSBmdW5jdGlvbiAob2JqLCBwcm9wLCB2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2csIGFzc2VydC5wcm9wZXJ0eVZhbCwgdHJ1ZSlcbiAgICAgIC50by5oYXZlLnByb3BlcnR5KHByb3AsIHZhbCk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAubm90UHJvcGVydHlWYWwob2JqZWN0LCBwcm9wZXJ0eSwgdmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGRvZXMgX25vdF8gaGF2ZSBhIGRpcmVjdCBvciBpbmhlcml0ZWQgcHJvcGVydHkgbmFtZWRcbiAgICogYnkgYHByb3BlcnR5YCB3aXRoIHZhbHVlIGdpdmVuIGJ5IGB2YWx1ZWAuIFVzZXMgYSBzdHJpY3QgZXF1YWxpdHkgY2hlY2tcbiAgICogKD09PSkuXG4gICAqXG4gICAqICAgICBhc3NlcnQubm90UHJvcGVydHlWYWwoeyB0ZWE6ICdpcyBnb29kJyB9LCAndGVhJywgJ2lzIGJhZCcpO1xuICAgKiAgICAgYXNzZXJ0Lm5vdFByb3BlcnR5VmFsKHsgdGVhOiAnaXMgZ29vZCcgfSwgJ2NvZmZlZScsICdpcyBnb29kJyk7XG4gICAqXG4gICAqIEBuYW1lIG5vdFByb3BlcnR5VmFsXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5XG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5ub3RQcm9wZXJ0eVZhbCA9IGZ1bmN0aW9uIChvYmosIHByb3AsIHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZywgYXNzZXJ0Lm5vdFByb3BlcnR5VmFsLCB0cnVlKVxuICAgICAgLnRvLm5vdC5oYXZlLnByb3BlcnR5KHByb3AsIHZhbCk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuZGVlcFByb3BlcnR5VmFsKG9iamVjdCwgcHJvcGVydHksIHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBoYXMgYSBkaXJlY3Qgb3IgaW5oZXJpdGVkIHByb3BlcnR5IG5hbWVkIGJ5XG4gICAqIGBwcm9wZXJ0eWAgd2l0aCBhIHZhbHVlIGdpdmVuIGJ5IGB2YWx1ZWAuIFVzZXMgYSBkZWVwIGVxdWFsaXR5IGNoZWNrLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmRlZXBQcm9wZXJ0eVZhbCh7IHRlYTogeyBncmVlbjogJ21hdGNoYScgfSB9LCAndGVhJywgeyBncmVlbjogJ21hdGNoYScgfSk7XG4gICAqXG4gICAqIEBuYW1lIGRlZXBQcm9wZXJ0eVZhbFxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eVxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuZGVlcFByb3BlcnR5VmFsID0gZnVuY3Rpb24gKG9iaiwgcHJvcCwgdmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnLCBhc3NlcnQuZGVlcFByb3BlcnR5VmFsLCB0cnVlKVxuICAgICAgLnRvLmhhdmUuZGVlcC5wcm9wZXJ0eShwcm9wLCB2YWwpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm5vdERlZXBQcm9wZXJ0eVZhbChvYmplY3QsIHByb3BlcnR5LCB2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgZG9lcyBfbm90XyBoYXZlIGEgZGlyZWN0IG9yIGluaGVyaXRlZCBwcm9wZXJ0eSBuYW1lZFxuICAgKiBieSBgcHJvcGVydHlgIHdpdGggdmFsdWUgZ2l2ZW4gYnkgYHZhbHVlYC4gVXNlcyBhIGRlZXAgZXF1YWxpdHkgY2hlY2suXG4gICAqXG4gICAqICAgICBhc3NlcnQubm90RGVlcFByb3BlcnR5VmFsKHsgdGVhOiB7IGdyZWVuOiAnbWF0Y2hhJyB9IH0sICd0ZWEnLCB7IGJsYWNrOiAnbWF0Y2hhJyB9KTtcbiAgICogICAgIGFzc2VydC5ub3REZWVwUHJvcGVydHlWYWwoeyB0ZWE6IHsgZ3JlZW46ICdtYXRjaGEnIH0gfSwgJ3RlYScsIHsgZ3JlZW46ICdvb2xvbmcnIH0pO1xuICAgKiAgICAgYXNzZXJ0Lm5vdERlZXBQcm9wZXJ0eVZhbCh7IHRlYTogeyBncmVlbjogJ21hdGNoYScgfSB9LCAnY29mZmVlJywgeyBncmVlbjogJ21hdGNoYScgfSk7XG4gICAqXG4gICAqIEBuYW1lIG5vdERlZXBQcm9wZXJ0eVZhbFxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eVxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubm90RGVlcFByb3BlcnR5VmFsID0gZnVuY3Rpb24gKG9iaiwgcHJvcCwgdmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnLCBhc3NlcnQubm90RGVlcFByb3BlcnR5VmFsLCB0cnVlKVxuICAgICAgLnRvLm5vdC5oYXZlLmRlZXAucHJvcGVydHkocHJvcCwgdmFsKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5vd25Qcm9wZXJ0eShvYmplY3QsIHByb3BlcnR5LCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBoYXMgYSBkaXJlY3QgcHJvcGVydHkgbmFtZWQgYnkgYHByb3BlcnR5YC4gSW5oZXJpdGVkXG4gICAqIHByb3BlcnRpZXMgYXJlbid0IGNoZWNrZWQuXG4gICAqXG4gICAqICAgICBhc3NlcnQub3duUHJvcGVydHkoeyB0ZWE6IHsgZ3JlZW46ICdtYXRjaGEnIH19LCAndGVhJyk7XG4gICAqXG4gICAqIEBuYW1lIG93blByb3BlcnR5XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5vd25Qcm9wZXJ0eSA9IGZ1bmN0aW9uIChvYmosIHByb3AsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2csIGFzc2VydC5vd25Qcm9wZXJ0eSwgdHJ1ZSlcbiAgICAgIC50by5oYXZlLm93bi5wcm9wZXJ0eShwcm9wKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5ub3RPd25Qcm9wZXJ0eShvYmplY3QsIHByb3BlcnR5LCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBkb2VzIF9ub3RfIGhhdmUgYSBkaXJlY3QgcHJvcGVydHkgbmFtZWQgYnlcbiAgICogYHByb3BlcnR5YC4gSW5oZXJpdGVkIHByb3BlcnRpZXMgYXJlbid0IGNoZWNrZWQuXG4gICAqXG4gICAqICAgICBhc3NlcnQubm90T3duUHJvcGVydHkoeyB0ZWE6IHsgZ3JlZW46ICdtYXRjaGEnIH19LCAnY29mZmVlJyk7XG4gICAqICAgICBhc3NlcnQubm90T3duUHJvcGVydHkoe30sICd0b1N0cmluZycpO1xuICAgKlxuICAgKiBAbmFtZSBub3RPd25Qcm9wZXJ0eVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubm90T3duUHJvcGVydHkgPSBmdW5jdGlvbiAob2JqLCBwcm9wLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnLCBhc3NlcnQubm90T3duUHJvcGVydHksIHRydWUpXG4gICAgICAudG8ubm90LmhhdmUub3duLnByb3BlcnR5KHByb3ApO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm93blByb3BlcnR5VmFsKG9iamVjdCwgcHJvcGVydHksIHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBoYXMgYSBkaXJlY3QgcHJvcGVydHkgbmFtZWQgYnkgYHByb3BlcnR5YCBhbmQgYSB2YWx1ZVxuICAgKiBlcXVhbCB0byB0aGUgcHJvdmlkZWQgYHZhbHVlYC4gVXNlcyBhIHN0cmljdCBlcXVhbGl0eSBjaGVjayAoPT09KS5cbiAgICogSW5oZXJpdGVkIHByb3BlcnRpZXMgYXJlbid0IGNoZWNrZWQuXG4gICAqXG4gICAqICAgICBhc3NlcnQub3duUHJvcGVydHlWYWwoeyBjb2ZmZWU6ICdpcyBnb29kJ30sICdjb2ZmZWUnLCAnaXMgZ29vZCcpO1xuICAgKlxuICAgKiBAbmFtZSBvd25Qcm9wZXJ0eVZhbFxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eVxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQub3duUHJvcGVydHlWYWwgPSBmdW5jdGlvbiAob2JqLCBwcm9wLCB2YWx1ZSwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZywgYXNzZXJ0Lm93blByb3BlcnR5VmFsLCB0cnVlKVxuICAgICAgLnRvLmhhdmUub3duLnByb3BlcnR5KHByb3AsIHZhbHVlKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5ub3RPd25Qcm9wZXJ0eVZhbChvYmplY3QsIHByb3BlcnR5LCB2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgZG9lcyBfbm90XyBoYXZlIGEgZGlyZWN0IHByb3BlcnR5IG5hbWVkIGJ5IGBwcm9wZXJ0eWBcbiAgICogd2l0aCBhIHZhbHVlIGVxdWFsIHRvIHRoZSBwcm92aWRlZCBgdmFsdWVgLiBVc2VzIGEgc3RyaWN0IGVxdWFsaXR5IGNoZWNrXG4gICAqICg9PT0pLiBJbmhlcml0ZWQgcHJvcGVydGllcyBhcmVuJ3QgY2hlY2tlZC5cbiAgICpcbiAgICogICAgIGFzc2VydC5ub3RPd25Qcm9wZXJ0eVZhbCh7IHRlYTogJ2lzIGJldHRlcid9LCAndGVhJywgJ2lzIHdvcnNlJyk7XG4gICAqICAgICBhc3NlcnQubm90T3duUHJvcGVydHlWYWwoe30sICd0b1N0cmluZycsIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcpO1xuICAgKlxuICAgKiBAbmFtZSBub3RPd25Qcm9wZXJ0eVZhbFxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eVxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubm90T3duUHJvcGVydHlWYWwgPSBmdW5jdGlvbiAob2JqLCBwcm9wLCB2YWx1ZSwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZywgYXNzZXJ0Lm5vdE93blByb3BlcnR5VmFsLCB0cnVlKVxuICAgICAgLnRvLm5vdC5oYXZlLm93bi5wcm9wZXJ0eShwcm9wLCB2YWx1ZSk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuZGVlcE93blByb3BlcnR5VmFsKG9iamVjdCwgcHJvcGVydHksIHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBoYXMgYSBkaXJlY3QgcHJvcGVydHkgbmFtZWQgYnkgYHByb3BlcnR5YCBhbmQgYSB2YWx1ZVxuICAgKiBlcXVhbCB0byB0aGUgcHJvdmlkZWQgYHZhbHVlYC4gVXNlcyBhIGRlZXAgZXF1YWxpdHkgY2hlY2suIEluaGVyaXRlZFxuICAgKiBwcm9wZXJ0aWVzIGFyZW4ndCBjaGVja2VkLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmRlZXBPd25Qcm9wZXJ0eVZhbCh7IHRlYTogeyBncmVlbjogJ21hdGNoYScgfSB9LCAndGVhJywgeyBncmVlbjogJ21hdGNoYScgfSk7XG4gICAqXG4gICAqIEBuYW1lIGRlZXBPd25Qcm9wZXJ0eVZhbFxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eVxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuZGVlcE93blByb3BlcnR5VmFsID0gZnVuY3Rpb24gKG9iaiwgcHJvcCwgdmFsdWUsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2csIGFzc2VydC5kZWVwT3duUHJvcGVydHlWYWwsIHRydWUpXG4gICAgICAudG8uaGF2ZS5kZWVwLm93bi5wcm9wZXJ0eShwcm9wLCB2YWx1ZSk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAubm90RGVlcE93blByb3BlcnR5VmFsKG9iamVjdCwgcHJvcGVydHksIHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBkb2VzIF9ub3RfIGhhdmUgYSBkaXJlY3QgcHJvcGVydHkgbmFtZWQgYnkgYHByb3BlcnR5YFxuICAgKiB3aXRoIGEgdmFsdWUgZXF1YWwgdG8gdGhlIHByb3ZpZGVkIGB2YWx1ZWAuIFVzZXMgYSBkZWVwIGVxdWFsaXR5IGNoZWNrLlxuICAgKiBJbmhlcml0ZWQgcHJvcGVydGllcyBhcmVuJ3QgY2hlY2tlZC5cbiAgICpcbiAgICogICAgIGFzc2VydC5ub3REZWVwT3duUHJvcGVydHlWYWwoeyB0ZWE6IHsgZ3JlZW46ICdtYXRjaGEnIH0gfSwgJ3RlYScsIHsgYmxhY2s6ICdtYXRjaGEnIH0pO1xuICAgKiAgICAgYXNzZXJ0Lm5vdERlZXBPd25Qcm9wZXJ0eVZhbCh7IHRlYTogeyBncmVlbjogJ21hdGNoYScgfSB9LCAndGVhJywgeyBncmVlbjogJ29vbG9uZycgfSk7XG4gICAqICAgICBhc3NlcnQubm90RGVlcE93blByb3BlcnR5VmFsKHsgdGVhOiB7IGdyZWVuOiAnbWF0Y2hhJyB9IH0sICdjb2ZmZWUnLCB7IGdyZWVuOiAnbWF0Y2hhJyB9KTtcbiAgICogICAgIGFzc2VydC5ub3REZWVwT3duUHJvcGVydHlWYWwoe30sICd0b1N0cmluZycsIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcpO1xuICAgKlxuICAgKiBAbmFtZSBub3REZWVwT3duUHJvcGVydHlWYWxcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHlcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm5vdERlZXBPd25Qcm9wZXJ0eVZhbCA9IGZ1bmN0aW9uIChvYmosIHByb3AsIHZhbHVlLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnLCBhc3NlcnQubm90RGVlcE93blByb3BlcnR5VmFsLCB0cnVlKVxuICAgICAgLnRvLm5vdC5oYXZlLmRlZXAub3duLnByb3BlcnR5KHByb3AsIHZhbHVlKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5uZXN0ZWRQcm9wZXJ0eShvYmplY3QsIHByb3BlcnR5LCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBoYXMgYSBkaXJlY3Qgb3IgaW5oZXJpdGVkIHByb3BlcnR5IG5hbWVkIGJ5XG4gICAqIGBwcm9wZXJ0eWAsIHdoaWNoIGNhbiBiZSBhIHN0cmluZyB1c2luZyBkb3QtIGFuZCBicmFja2V0LW5vdGF0aW9uIGZvclxuICAgKiBuZXN0ZWQgcmVmZXJlbmNlLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm5lc3RlZFByb3BlcnR5KHsgdGVhOiB7IGdyZWVuOiAnbWF0Y2hhJyB9fSwgJ3RlYS5ncmVlbicpO1xuICAgKlxuICAgKiBAbmFtZSBuZXN0ZWRQcm9wZXJ0eVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubmVzdGVkUHJvcGVydHkgPSBmdW5jdGlvbiAob2JqLCBwcm9wLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnLCBhc3NlcnQubmVzdGVkUHJvcGVydHksIHRydWUpXG4gICAgICAudG8uaGF2ZS5uZXN0ZWQucHJvcGVydHkocHJvcCk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAubm90TmVzdGVkUHJvcGVydHkob2JqZWN0LCBwcm9wZXJ0eSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgZG9lcyBfbm90XyBoYXZlIGEgcHJvcGVydHkgbmFtZWQgYnkgYHByb3BlcnR5YCwgd2hpY2hcbiAgICogY2FuIGJlIGEgc3RyaW5nIHVzaW5nIGRvdC0gYW5kIGJyYWNrZXQtbm90YXRpb24gZm9yIG5lc3RlZCByZWZlcmVuY2UuIFRoZVxuICAgKiBwcm9wZXJ0eSBjYW5ub3QgZXhpc3Qgb24gdGhlIG9iamVjdCBub3IgYW55d2hlcmUgaW4gaXRzIHByb3RvdHlwZSBjaGFpbi5cbiAgICpcbiAgICogICAgIGFzc2VydC5ub3ROZXN0ZWRQcm9wZXJ0eSh7IHRlYTogeyBncmVlbjogJ21hdGNoYScgfX0sICd0ZWEub29sb25nJyk7XG4gICAqXG4gICAqIEBuYW1lIG5vdE5lc3RlZFByb3BlcnR5XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5ub3ROZXN0ZWRQcm9wZXJ0eSA9IGZ1bmN0aW9uIChvYmosIHByb3AsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2csIGFzc2VydC5ub3ROZXN0ZWRQcm9wZXJ0eSwgdHJ1ZSlcbiAgICAgIC50by5ub3QuaGF2ZS5uZXN0ZWQucHJvcGVydHkocHJvcCk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAubmVzdGVkUHJvcGVydHlWYWwob2JqZWN0LCBwcm9wZXJ0eSwgdmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGhhcyBhIHByb3BlcnR5IG5hbWVkIGJ5IGBwcm9wZXJ0eWAgd2l0aCB2YWx1ZSBnaXZlblxuICAgKiBieSBgdmFsdWVgLiBgcHJvcGVydHlgIGNhbiB1c2UgZG90LSBhbmQgYnJhY2tldC1ub3RhdGlvbiBmb3IgbmVzdGVkXG4gICAqIHJlZmVyZW5jZS4gVXNlcyBhIHN0cmljdCBlcXVhbGl0eSBjaGVjayAoPT09KS5cbiAgICpcbiAgICogICAgIGFzc2VydC5uZXN0ZWRQcm9wZXJ0eVZhbCh7IHRlYTogeyBncmVlbjogJ21hdGNoYScgfX0sICd0ZWEuZ3JlZW4nLCAnbWF0Y2hhJyk7XG4gICAqXG4gICAqIEBuYW1lIG5lc3RlZFByb3BlcnR5VmFsXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5XG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5uZXN0ZWRQcm9wZXJ0eVZhbCA9IGZ1bmN0aW9uIChvYmosIHByb3AsIHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZywgYXNzZXJ0Lm5lc3RlZFByb3BlcnR5VmFsLCB0cnVlKVxuICAgICAgLnRvLmhhdmUubmVzdGVkLnByb3BlcnR5KHByb3AsIHZhbCk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAubm90TmVzdGVkUHJvcGVydHlWYWwob2JqZWN0LCBwcm9wZXJ0eSwgdmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGRvZXMgX25vdF8gaGF2ZSBhIHByb3BlcnR5IG5hbWVkIGJ5IGBwcm9wZXJ0eWAgd2l0aFxuICAgKiB2YWx1ZSBnaXZlbiBieSBgdmFsdWVgLiBgcHJvcGVydHlgIGNhbiB1c2UgZG90LSBhbmQgYnJhY2tldC1ub3RhdGlvbiBmb3JcbiAgICogbmVzdGVkIHJlZmVyZW5jZS4gVXNlcyBhIHN0cmljdCBlcXVhbGl0eSBjaGVjayAoPT09KS5cbiAgICpcbiAgICogICAgIGFzc2VydC5ub3ROZXN0ZWRQcm9wZXJ0eVZhbCh7IHRlYTogeyBncmVlbjogJ21hdGNoYScgfX0sICd0ZWEuZ3JlZW4nLCAna29uYWNoYScpO1xuICAgKiAgICAgYXNzZXJ0Lm5vdE5lc3RlZFByb3BlcnR5VmFsKHsgdGVhOiB7IGdyZWVuOiAnbWF0Y2hhJyB9fSwgJ2NvZmZlZS5ncmVlbicsICdtYXRjaGEnKTtcbiAgICpcbiAgICogQG5hbWUgbm90TmVzdGVkUHJvcGVydHlWYWxcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHlcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm5vdE5lc3RlZFByb3BlcnR5VmFsID0gZnVuY3Rpb24gKG9iaiwgcHJvcCwgdmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnLCBhc3NlcnQubm90TmVzdGVkUHJvcGVydHlWYWwsIHRydWUpXG4gICAgICAudG8ubm90LmhhdmUubmVzdGVkLnByb3BlcnR5KHByb3AsIHZhbCk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuZGVlcE5lc3RlZFByb3BlcnR5VmFsKG9iamVjdCwgcHJvcGVydHksIHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBoYXMgYSBwcm9wZXJ0eSBuYW1lZCBieSBgcHJvcGVydHlgIHdpdGggYSB2YWx1ZSBnaXZlblxuICAgKiBieSBgdmFsdWVgLiBgcHJvcGVydHlgIGNhbiB1c2UgZG90LSBhbmQgYnJhY2tldC1ub3RhdGlvbiBmb3IgbmVzdGVkXG4gICAqIHJlZmVyZW5jZS4gVXNlcyBhIGRlZXAgZXF1YWxpdHkgY2hlY2suXG4gICAqXG4gICAqICAgICBhc3NlcnQuZGVlcE5lc3RlZFByb3BlcnR5VmFsKHsgdGVhOiB7IGdyZWVuOiB7IG1hdGNoYTogJ3l1bScgfSB9IH0sICd0ZWEuZ3JlZW4nLCB7IG1hdGNoYTogJ3l1bScgfSk7XG4gICAqXG4gICAqIEBuYW1lIGRlZXBOZXN0ZWRQcm9wZXJ0eVZhbFxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eVxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuZGVlcE5lc3RlZFByb3BlcnR5VmFsID0gZnVuY3Rpb24gKG9iaiwgcHJvcCwgdmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnLCBhc3NlcnQuZGVlcE5lc3RlZFByb3BlcnR5VmFsLCB0cnVlKVxuICAgICAgLnRvLmhhdmUuZGVlcC5uZXN0ZWQucHJvcGVydHkocHJvcCwgdmFsKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5ub3REZWVwTmVzdGVkUHJvcGVydHlWYWwob2JqZWN0LCBwcm9wZXJ0eSwgdmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGRvZXMgX25vdF8gaGF2ZSBhIHByb3BlcnR5IG5hbWVkIGJ5IGBwcm9wZXJ0eWAgd2l0aFxuICAgKiB2YWx1ZSBnaXZlbiBieSBgdmFsdWVgLiBgcHJvcGVydHlgIGNhbiB1c2UgZG90LSBhbmQgYnJhY2tldC1ub3RhdGlvbiBmb3JcbiAgICogbmVzdGVkIHJlZmVyZW5jZS4gVXNlcyBhIGRlZXAgZXF1YWxpdHkgY2hlY2suXG4gICAqXG4gICAqICAgICBhc3NlcnQubm90RGVlcE5lc3RlZFByb3BlcnR5VmFsKHsgdGVhOiB7IGdyZWVuOiB7IG1hdGNoYTogJ3l1bScgfSB9IH0sICd0ZWEuZ3JlZW4nLCB7IG9vbG9uZzogJ3l1bScgfSk7XG4gICAqICAgICBhc3NlcnQubm90RGVlcE5lc3RlZFByb3BlcnR5VmFsKHsgdGVhOiB7IGdyZWVuOiB7IG1hdGNoYTogJ3l1bScgfSB9IH0sICd0ZWEuZ3JlZW4nLCB7IG1hdGNoYTogJ3l1Y2snIH0pO1xuICAgKiAgICAgYXNzZXJ0Lm5vdERlZXBOZXN0ZWRQcm9wZXJ0eVZhbCh7IHRlYTogeyBncmVlbjogeyBtYXRjaGE6ICd5dW0nIH0gfSB9LCAndGVhLmJsYWNrJywgeyBtYXRjaGE6ICd5dW0nIH0pO1xuICAgKlxuICAgKiBAbmFtZSBub3REZWVwTmVzdGVkUHJvcGVydHlWYWxcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHlcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm5vdERlZXBOZXN0ZWRQcm9wZXJ0eVZhbCA9IGZ1bmN0aW9uIChvYmosIHByb3AsIHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZywgYXNzZXJ0Lm5vdERlZXBOZXN0ZWRQcm9wZXJ0eVZhbCwgdHJ1ZSlcbiAgICAgIC50by5ub3QuaGF2ZS5kZWVwLm5lc3RlZC5wcm9wZXJ0eShwcm9wLCB2YWwpO1xuICB9XG5cbiAgLyoqXG4gICAqICMjIyAubGVuZ3RoT2Yob2JqZWN0LCBsZW5ndGgsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGhhcyBhIGBsZW5ndGhgIG9yIGBzaXplYCB3aXRoIHRoZSBleHBlY3RlZCB2YWx1ZS5cbiAgICpcbiAgICogICAgIGFzc2VydC5sZW5ndGhPZihbMSwyLDNdLCAzLCAnYXJyYXkgaGFzIGxlbmd0aCBvZiAzJyk7XG4gICAqICAgICBhc3NlcnQubGVuZ3RoT2YoJ2Zvb2JhcicsIDYsICdzdHJpbmcgaGFzIGxlbmd0aCBvZiA2Jyk7XG4gICAqICAgICBhc3NlcnQubGVuZ3RoT2YobmV3IFNldChbMSwyLDNdKSwgMywgJ3NldCBoYXMgc2l6ZSBvZiAzJyk7XG4gICAqICAgICBhc3NlcnQubGVuZ3RoT2YobmV3IE1hcChbWydhJywxXSxbJ2InLDJdLFsnYycsM11dKSwgMywgJ21hcCBoYXMgc2l6ZSBvZiAzJyk7XG4gICAqXG4gICAqIEBuYW1lIGxlbmd0aE9mXG4gICAqIEBwYXJhbSB7TWl4ZWR9IG9iamVjdFxuICAgKiBAcGFyYW0ge051bWJlcn0gbGVuZ3RoXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5sZW5ndGhPZiA9IGZ1bmN0aW9uIChleHAsIGxlbiwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihleHAsIG1zZywgYXNzZXJ0Lmxlbmd0aE9mLCB0cnVlKS50by5oYXZlLmxlbmd0aE9mKGxlbik7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaGFzQW55S2V5cyhvYmplY3QsIFtrZXlzXSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgaGFzIGF0IGxlYXN0IG9uZSBvZiB0aGUgYGtleXNgIHByb3ZpZGVkLlxuICAgKiBZb3UgY2FuIGFsc28gcHJvdmlkZSBhIHNpbmdsZSBvYmplY3QgaW5zdGVhZCBvZiBhIGBrZXlzYCBhcnJheSBhbmQgaXRzIGtleXNcbiAgICogd2lsbCBiZSB1c2VkIGFzIHRoZSBleHBlY3RlZCBzZXQgb2Yga2V5cy5cbiAgICpcbiAgICogICAgIGFzc2VydC5oYXNBbnlLZXlzKHtmb286IDEsIGJhcjogMiwgYmF6OiAzfSwgWydmb28nLCAnaURvbnRFeGlzdCcsICdiYXonXSk7XG4gICAqICAgICBhc3NlcnQuaGFzQW55S2V5cyh7Zm9vOiAxLCBiYXI6IDIsIGJhejogM30sIHtmb286IDMwLCBpRG9udEV4aXN0OiA5OSwgYmF6OiAxMzM3fSk7XG4gICAqICAgICBhc3NlcnQuaGFzQW55S2V5cyhuZXcgTWFwKFtbe2ZvbzogMX0sICdiYXInXSwgWydrZXknLCAndmFsdWUnXV0pLCBbe2ZvbzogMX0sICdrZXknXSk7XG4gICAqICAgICBhc3NlcnQuaGFzQW55S2V5cyhuZXcgU2V0KFt7Zm9vOiAnYmFyJ30sICdhbm90aGVyS2V5J10pLCBbe2ZvbzogJ2Jhcid9LCAnYW5vdGhlcktleSddKTtcbiAgICpcbiAgICogQG5hbWUgaGFzQW55S2V5c1xuICAgKiBAcGFyYW0ge01peGVkfSBvYmplY3RcbiAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGtleXNcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lmhhc0FueUtleXMgPSBmdW5jdGlvbiAob2JqLCBrZXlzLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnLCBhc3NlcnQuaGFzQW55S2V5cywgdHJ1ZSkudG8uaGF2ZS5hbnkua2V5cyhrZXlzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiAjIyMgLmhhc0FsbEtleXMob2JqZWN0LCBba2V5c10sIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGhhcyBhbGwgYW5kIG9ubHkgYWxsIG9mIHRoZSBga2V5c2AgcHJvdmlkZWQuXG4gICAqIFlvdSBjYW4gYWxzbyBwcm92aWRlIGEgc2luZ2xlIG9iamVjdCBpbnN0ZWFkIG9mIGEgYGtleXNgIGFycmF5IGFuZCBpdHMga2V5c1xuICAgKiB3aWxsIGJlIHVzZWQgYXMgdGhlIGV4cGVjdGVkIHNldCBvZiBrZXlzLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lmhhc0FsbEtleXMoe2ZvbzogMSwgYmFyOiAyLCBiYXo6IDN9LCBbJ2ZvbycsICdiYXInLCAnYmF6J10pO1xuICAgKiAgICAgYXNzZXJ0Lmhhc0FsbEtleXMoe2ZvbzogMSwgYmFyOiAyLCBiYXo6IDN9LCB7Zm9vOiAzMCwgYmFyOiA5OSwgYmF6OiAxMzM3XSk7XG4gICAqICAgICBhc3NlcnQuaGFzQWxsS2V5cyhuZXcgTWFwKFtbe2ZvbzogMX0sICdiYXInXSwgWydrZXknLCAndmFsdWUnXV0pLCBbe2ZvbzogMX0sICdrZXknXSk7XG4gICAqICAgICBhc3NlcnQuaGFzQWxsS2V5cyhuZXcgU2V0KFt7Zm9vOiAnYmFyJ30sICdhbm90aGVyS2V5J10sIFt7Zm9vOiAnYmFyJ30sICdhbm90aGVyS2V5J10pO1xuICAgKlxuICAgKiBAbmFtZSBoYXNBbGxLZXlzXG4gICAqIEBwYXJhbSB7TWl4ZWR9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ1tdfSBrZXlzXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5oYXNBbGxLZXlzID0gZnVuY3Rpb24gKG9iaiwga2V5cywgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZywgYXNzZXJ0Lmhhc0FsbEtleXMsIHRydWUpLnRvLmhhdmUuYWxsLmtleXMoa2V5cyk7XG4gIH1cblxuICAvKipcbiAgICogIyMjIC5jb250YWluc0FsbEtleXMob2JqZWN0LCBba2V5c10sIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGhhcyBhbGwgb2YgdGhlIGBrZXlzYCBwcm92aWRlZCBidXQgbWF5IGhhdmUgbW9yZSBrZXlzIG5vdCBsaXN0ZWQuXG4gICAqIFlvdSBjYW4gYWxzbyBwcm92aWRlIGEgc2luZ2xlIG9iamVjdCBpbnN0ZWFkIG9mIGEgYGtleXNgIGFycmF5IGFuZCBpdHMga2V5c1xuICAgKiB3aWxsIGJlIHVzZWQgYXMgdGhlIGV4cGVjdGVkIHNldCBvZiBrZXlzLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmNvbnRhaW5zQWxsS2V5cyh7Zm9vOiAxLCBiYXI6IDIsIGJhejogM30sIFsnZm9vJywgJ2JheiddKTtcbiAgICogICAgIGFzc2VydC5jb250YWluc0FsbEtleXMoe2ZvbzogMSwgYmFyOiAyLCBiYXo6IDN9LCBbJ2ZvbycsICdiYXInLCAnYmF6J10pO1xuICAgKiAgICAgYXNzZXJ0LmNvbnRhaW5zQWxsS2V5cyh7Zm9vOiAxLCBiYXI6IDIsIGJhejogM30sIHtmb286IDMwLCBiYXo6IDEzMzd9KTtcbiAgICogICAgIGFzc2VydC5jb250YWluc0FsbEtleXMoe2ZvbzogMSwgYmFyOiAyLCBiYXo6IDN9LCB7Zm9vOiAzMCwgYmFyOiA5OSwgYmF6OiAxMzM3fSk7XG4gICAqICAgICBhc3NlcnQuY29udGFpbnNBbGxLZXlzKG5ldyBNYXAoW1t7Zm9vOiAxfSwgJ2JhciddLCBbJ2tleScsICd2YWx1ZSddXSksIFt7Zm9vOiAxfV0pO1xuICAgKiAgICAgYXNzZXJ0LmNvbnRhaW5zQWxsS2V5cyhuZXcgTWFwKFtbe2ZvbzogMX0sICdiYXInXSwgWydrZXknLCAndmFsdWUnXV0pLCBbe2ZvbzogMX0sICdrZXknXSk7XG4gICAqICAgICBhc3NlcnQuY29udGFpbnNBbGxLZXlzKG5ldyBTZXQoW3tmb286ICdiYXInfSwgJ2Fub3RoZXJLZXknXSwgW3tmb286ICdiYXInfV0pO1xuICAgKiAgICAgYXNzZXJ0LmNvbnRhaW5zQWxsS2V5cyhuZXcgU2V0KFt7Zm9vOiAnYmFyJ30sICdhbm90aGVyS2V5J10sIFt7Zm9vOiAnYmFyJ30sICdhbm90aGVyS2V5J10pO1xuICAgKlxuICAgKiBAbmFtZSBjb250YWluc0FsbEtleXNcbiAgICogQHBhcmFtIHtNaXhlZH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nW119IGtleXNcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmNvbnRhaW5zQWxsS2V5cyA9IGZ1bmN0aW9uIChvYmosIGtleXMsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2csIGFzc2VydC5jb250YWluc0FsbEtleXMsIHRydWUpXG4gICAgICAudG8uY29udGFpbi5hbGwua2V5cyhrZXlzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiAjIyMgLmRvZXNOb3RIYXZlQW55S2V5cyhvYmplY3QsIFtrZXlzXSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgaGFzIG5vbmUgb2YgdGhlIGBrZXlzYCBwcm92aWRlZC5cbiAgICogWW91IGNhbiBhbHNvIHByb3ZpZGUgYSBzaW5nbGUgb2JqZWN0IGluc3RlYWQgb2YgYSBga2V5c2AgYXJyYXkgYW5kIGl0cyBrZXlzXG4gICAqIHdpbGwgYmUgdXNlZCBhcyB0aGUgZXhwZWN0ZWQgc2V0IG9mIGtleXMuXG4gICAqXG4gICAqICAgICBhc3NlcnQuZG9lc05vdEhhdmVBbnlLZXlzKHtmb286IDEsIGJhcjogMiwgYmF6OiAzfSwgWydvbmUnLCAndHdvJywgJ2V4YW1wbGUnXSk7XG4gICAqICAgICBhc3NlcnQuZG9lc05vdEhhdmVBbnlLZXlzKHtmb286IDEsIGJhcjogMiwgYmF6OiAzfSwge29uZTogMSwgdHdvOiAyLCBleGFtcGxlOiAnZm9vJ30pO1xuICAgKiAgICAgYXNzZXJ0LmRvZXNOb3RIYXZlQW55S2V5cyhuZXcgTWFwKFtbe2ZvbzogMX0sICdiYXInXSwgWydrZXknLCAndmFsdWUnXV0pLCBbe29uZTogJ3R3byd9LCAnZXhhbXBsZSddKTtcbiAgICogICAgIGFzc2VydC5kb2VzTm90SGF2ZUFueUtleXMobmV3IFNldChbe2ZvbzogJ2Jhcid9LCAnYW5vdGhlcktleSddLCBbe29uZTogJ3R3byd9LCAnZXhhbXBsZSddKTtcbiAgICpcbiAgICogQG5hbWUgZG9lc05vdEhhdmVBbnlLZXlzXG4gICAqIEBwYXJhbSB7TWl4ZWR9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ1tdfSBrZXlzXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5kb2VzTm90SGF2ZUFueUtleXMgPSBmdW5jdGlvbiAob2JqLCBrZXlzLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnLCBhc3NlcnQuZG9lc05vdEhhdmVBbnlLZXlzLCB0cnVlKVxuICAgICAgLnRvLm5vdC5oYXZlLmFueS5rZXlzKGtleXMpO1xuICB9XG5cbiAgLyoqXG4gICAqICMjIyAuZG9lc05vdEhhdmVBbGxLZXlzKG9iamVjdCwgW2tleXNdLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBkb2VzIG5vdCBoYXZlIGF0IGxlYXN0IG9uZSBvZiB0aGUgYGtleXNgIHByb3ZpZGVkLlxuICAgKiBZb3UgY2FuIGFsc28gcHJvdmlkZSBhIHNpbmdsZSBvYmplY3QgaW5zdGVhZCBvZiBhIGBrZXlzYCBhcnJheSBhbmQgaXRzIGtleXNcbiAgICogd2lsbCBiZSB1c2VkIGFzIHRoZSBleHBlY3RlZCBzZXQgb2Yga2V5cy5cbiAgICpcbiAgICogICAgIGFzc2VydC5kb2VzTm90SGF2ZUFsbEtleXMoe2ZvbzogMSwgYmFyOiAyLCBiYXo6IDN9LCBbJ29uZScsICd0d28nLCAnZXhhbXBsZSddKTtcbiAgICogICAgIGFzc2VydC5kb2VzTm90SGF2ZUFsbEtleXMoe2ZvbzogMSwgYmFyOiAyLCBiYXo6IDN9LCB7b25lOiAxLCB0d286IDIsIGV4YW1wbGU6ICdmb28nfSk7XG4gICAqICAgICBhc3NlcnQuZG9lc05vdEhhdmVBbGxLZXlzKG5ldyBNYXAoW1t7Zm9vOiAxfSwgJ2JhciddLCBbJ2tleScsICd2YWx1ZSddXSksIFt7b25lOiAndHdvJ30sICdleGFtcGxlJ10pO1xuICAgKiAgICAgYXNzZXJ0LmRvZXNOb3RIYXZlQWxsS2V5cyhuZXcgU2V0KFt7Zm9vOiAnYmFyJ30sICdhbm90aGVyS2V5J10sIFt7b25lOiAndHdvJ30sICdleGFtcGxlJ10pO1xuICAgKlxuICAgKiBAbmFtZSBkb2VzTm90SGF2ZUFsbEtleXNcbiAgICogQHBhcmFtIHtNaXhlZH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nW119IGtleXNcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmRvZXNOb3RIYXZlQWxsS2V5cyA9IGZ1bmN0aW9uIChvYmosIGtleXMsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2csIGFzc2VydC5kb2VzTm90SGF2ZUFsbEtleXMsIHRydWUpXG4gICAgICAudG8ubm90LmhhdmUuYWxsLmtleXMoa2V5cyk7XG4gIH1cblxuICAvKipcbiAgICogIyMjIC5oYXNBbnlEZWVwS2V5cyhvYmplY3QsIFtrZXlzXSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgaGFzIGF0IGxlYXN0IG9uZSBvZiB0aGUgYGtleXNgIHByb3ZpZGVkLlxuICAgKiBTaW5jZSBTZXRzIGFuZCBNYXBzIGNhbiBoYXZlIG9iamVjdHMgYXMga2V5cyB5b3UgY2FuIHVzZSB0aGlzIGFzc2VydGlvbiB0byBwZXJmb3JtXG4gICAqIGEgZGVlcCBjb21wYXJpc29uLlxuICAgKiBZb3UgY2FuIGFsc28gcHJvdmlkZSBhIHNpbmdsZSBvYmplY3QgaW5zdGVhZCBvZiBhIGBrZXlzYCBhcnJheSBhbmQgaXRzIGtleXNcbiAgICogd2lsbCBiZSB1c2VkIGFzIHRoZSBleHBlY3RlZCBzZXQgb2Yga2V5cy5cbiAgICpcbiAgICogICAgIGFzc2VydC5oYXNBbnlEZWVwS2V5cyhuZXcgTWFwKFtbe29uZTogJ29uZSd9LCAndmFsdWVPbmUnXSwgWzEsIDJdXSksIHtvbmU6ICdvbmUnfSk7XG4gICAqICAgICBhc3NlcnQuaGFzQW55RGVlcEtleXMobmV3IE1hcChbW3tvbmU6ICdvbmUnfSwgJ3ZhbHVlT25lJ10sIFsxLCAyXV0pLCBbe29uZTogJ29uZSd9LCB7dHdvOiAndHdvJ31dKTtcbiAgICogICAgIGFzc2VydC5oYXNBbnlEZWVwS2V5cyhuZXcgTWFwKFtbe29uZTogJ29uZSd9LCAndmFsdWVPbmUnXSwgW3t0d286ICd0d28nfSwgJ3ZhbHVlVHdvJ11dKSwgW3tvbmU6ICdvbmUnfSwge3R3bzogJ3R3byd9XSk7XG4gICAqICAgICBhc3NlcnQuaGFzQW55RGVlcEtleXMobmV3IFNldChbe29uZTogJ29uZSd9LCB7dHdvOiAndHdvJ31dKSwge29uZTogJ29uZSd9KTtcbiAgICogICAgIGFzc2VydC5oYXNBbnlEZWVwS2V5cyhuZXcgU2V0KFt7b25lOiAnb25lJ30sIHt0d286ICd0d28nfV0pLCBbe29uZTogJ29uZSd9LCB7dGhyZWU6ICd0aHJlZSd9XSk7XG4gICAqICAgICBhc3NlcnQuaGFzQW55RGVlcEtleXMobmV3IFNldChbe29uZTogJ29uZSd9LCB7dHdvOiAndHdvJ31dKSwgW3tvbmU6ICdvbmUnfSwge3R3bzogJ3R3byd9XSk7XG4gICAqXG4gICAqIEBuYW1lIGhhc0FueURlZXBLZXlzXG4gICAqIEBwYXJhbSB7TWl4ZWR9IG9iamVjdFxuICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0ga2V5c1xuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaGFzQW55RGVlcEtleXMgPSBmdW5jdGlvbiAob2JqLCBrZXlzLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnLCBhc3NlcnQuaGFzQW55RGVlcEtleXMsIHRydWUpXG4gICAgICAudG8uaGF2ZS5hbnkuZGVlcC5rZXlzKGtleXMpO1xuICB9XG5cbiAvKipcbiAgICogIyMjIC5oYXNBbGxEZWVwS2V5cyhvYmplY3QsIFtrZXlzXSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgaGFzIGFsbCBhbmQgb25seSBhbGwgb2YgdGhlIGBrZXlzYCBwcm92aWRlZC5cbiAgICogU2luY2UgU2V0cyBhbmQgTWFwcyBjYW4gaGF2ZSBvYmplY3RzIGFzIGtleXMgeW91IGNhbiB1c2UgdGhpcyBhc3NlcnRpb24gdG8gcGVyZm9ybVxuICAgKiBhIGRlZXAgY29tcGFyaXNvbi5cbiAgICogWW91IGNhbiBhbHNvIHByb3ZpZGUgYSBzaW5nbGUgb2JqZWN0IGluc3RlYWQgb2YgYSBga2V5c2AgYXJyYXkgYW5kIGl0cyBrZXlzXG4gICAqIHdpbGwgYmUgdXNlZCBhcyB0aGUgZXhwZWN0ZWQgc2V0IG9mIGtleXMuXG4gICAqXG4gICAqICAgICBhc3NlcnQuaGFzQWxsRGVlcEtleXMobmV3IE1hcChbW3tvbmU6ICdvbmUnfSwgJ3ZhbHVlT25lJ11dKSwge29uZTogJ29uZSd9KTtcbiAgICogICAgIGFzc2VydC5oYXNBbGxEZWVwS2V5cyhuZXcgTWFwKFtbe29uZTogJ29uZSd9LCAndmFsdWVPbmUnXSwgW3t0d286ICd0d28nfSwgJ3ZhbHVlVHdvJ11dKSwgW3tvbmU6ICdvbmUnfSwge3R3bzogJ3R3byd9XSk7XG4gICAqICAgICBhc3NlcnQuaGFzQWxsRGVlcEtleXMobmV3IFNldChbe29uZTogJ29uZSd9XSksIHtvbmU6ICdvbmUnfSk7XG4gICAqICAgICBhc3NlcnQuaGFzQWxsRGVlcEtleXMobmV3IFNldChbe29uZTogJ29uZSd9LCB7dHdvOiAndHdvJ31dKSwgW3tvbmU6ICdvbmUnfSwge3R3bzogJ3R3byd9XSk7XG4gICAqXG4gICAqIEBuYW1lIGhhc0FsbERlZXBLZXlzXG4gICAqIEBwYXJhbSB7TWl4ZWR9IG9iamVjdFxuICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0ga2V5c1xuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaGFzQWxsRGVlcEtleXMgPSBmdW5jdGlvbiAob2JqLCBrZXlzLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnLCBhc3NlcnQuaGFzQWxsRGVlcEtleXMsIHRydWUpXG4gICAgICAudG8uaGF2ZS5hbGwuZGVlcC5rZXlzKGtleXMpO1xuICB9XG5cbiAvKipcbiAgICogIyMjIC5jb250YWluc0FsbERlZXBLZXlzKG9iamVjdCwgW2tleXNdLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBjb250YWlucyBhbGwgb2YgdGhlIGBrZXlzYCBwcm92aWRlZC5cbiAgICogU2luY2UgU2V0cyBhbmQgTWFwcyBjYW4gaGF2ZSBvYmplY3RzIGFzIGtleXMgeW91IGNhbiB1c2UgdGhpcyBhc3NlcnRpb24gdG8gcGVyZm9ybVxuICAgKiBhIGRlZXAgY29tcGFyaXNvbi5cbiAgICogWW91IGNhbiBhbHNvIHByb3ZpZGUgYSBzaW5nbGUgb2JqZWN0IGluc3RlYWQgb2YgYSBga2V5c2AgYXJyYXkgYW5kIGl0cyBrZXlzXG4gICAqIHdpbGwgYmUgdXNlZCBhcyB0aGUgZXhwZWN0ZWQgc2V0IG9mIGtleXMuXG4gICAqXG4gICAqICAgICBhc3NlcnQuY29udGFpbnNBbGxEZWVwS2V5cyhuZXcgTWFwKFtbe29uZTogJ29uZSd9LCAndmFsdWVPbmUnXSwgWzEsIDJdXSksIHtvbmU6ICdvbmUnfSk7XG4gICAqICAgICBhc3NlcnQuY29udGFpbnNBbGxEZWVwS2V5cyhuZXcgTWFwKFtbe29uZTogJ29uZSd9LCAndmFsdWVPbmUnXSwgW3t0d286ICd0d28nfSwgJ3ZhbHVlVHdvJ11dKSwgW3tvbmU6ICdvbmUnfSwge3R3bzogJ3R3byd9XSk7XG4gICAqICAgICBhc3NlcnQuY29udGFpbnNBbGxEZWVwS2V5cyhuZXcgU2V0KFt7b25lOiAnb25lJ30sIHt0d286ICd0d28nfV0pLCB7b25lOiAnb25lJ30pO1xuICAgKiAgICAgYXNzZXJ0LmNvbnRhaW5zQWxsRGVlcEtleXMobmV3IFNldChbe29uZTogJ29uZSd9LCB7dHdvOiAndHdvJ31dKSwgW3tvbmU6ICdvbmUnfSwge3R3bzogJ3R3byd9XSk7XG4gICAqXG4gICAqIEBuYW1lIGNvbnRhaW5zQWxsRGVlcEtleXNcbiAgICogQHBhcmFtIHtNaXhlZH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBrZXlzXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5jb250YWluc0FsbERlZXBLZXlzID0gZnVuY3Rpb24gKG9iaiwga2V5cywgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZywgYXNzZXJ0LmNvbnRhaW5zQWxsRGVlcEtleXMsIHRydWUpXG4gICAgICAudG8uY29udGFpbi5hbGwuZGVlcC5rZXlzKGtleXMpO1xuICB9XG5cbiAvKipcbiAgICogIyMjIC5kb2VzTm90SGF2ZUFueURlZXBLZXlzKG9iamVjdCwgW2tleXNdLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBoYXMgbm9uZSBvZiB0aGUgYGtleXNgIHByb3ZpZGVkLlxuICAgKiBTaW5jZSBTZXRzIGFuZCBNYXBzIGNhbiBoYXZlIG9iamVjdHMgYXMga2V5cyB5b3UgY2FuIHVzZSB0aGlzIGFzc2VydGlvbiB0byBwZXJmb3JtXG4gICAqIGEgZGVlcCBjb21wYXJpc29uLlxuICAgKiBZb3UgY2FuIGFsc28gcHJvdmlkZSBhIHNpbmdsZSBvYmplY3QgaW5zdGVhZCBvZiBhIGBrZXlzYCBhcnJheSBhbmQgaXRzIGtleXNcbiAgICogd2lsbCBiZSB1c2VkIGFzIHRoZSBleHBlY3RlZCBzZXQgb2Yga2V5cy5cbiAgICpcbiAgICogICAgIGFzc2VydC5kb2VzTm90SGF2ZUFueURlZXBLZXlzKG5ldyBNYXAoW1t7b25lOiAnb25lJ30sICd2YWx1ZU9uZSddLCBbMSwgMl1dKSwge3RoaXNEb2VzTm90OiAnZXhpc3QnfSk7XG4gICAqICAgICBhc3NlcnQuZG9lc05vdEhhdmVBbnlEZWVwS2V5cyhuZXcgTWFwKFtbe29uZTogJ29uZSd9LCAndmFsdWVPbmUnXSwgW3t0d286ICd0d28nfSwgJ3ZhbHVlVHdvJ11dKSwgW3t0d2VudHk6ICd0d2VudHknfSwge2ZpZnR5OiAnZmlmdHknfV0pO1xuICAgKiAgICAgYXNzZXJ0LmRvZXNOb3RIYXZlQW55RGVlcEtleXMobmV3IFNldChbe29uZTogJ29uZSd9LCB7dHdvOiAndHdvJ31dKSwge3R3ZW50eTogJ3R3ZW50eSd9KTtcbiAgICogICAgIGFzc2VydC5kb2VzTm90SGF2ZUFueURlZXBLZXlzKG5ldyBTZXQoW3tvbmU6ICdvbmUnfSwge3R3bzogJ3R3byd9XSksIFt7dHdlbnR5OiAndHdlbnR5J30sIHtmaWZ0eTogJ2ZpZnR5J31dKTtcbiAgICpcbiAgICogQG5hbWUgZG9lc05vdEhhdmVBbnlEZWVwS2V5c1xuICAgKiBAcGFyYW0ge01peGVkfSBvYmplY3RcbiAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGtleXNcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmRvZXNOb3RIYXZlQW55RGVlcEtleXMgPSBmdW5jdGlvbiAob2JqLCBrZXlzLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnLCBhc3NlcnQuZG9lc05vdEhhdmVBbnlEZWVwS2V5cywgdHJ1ZSlcbiAgICAgIC50by5ub3QuaGF2ZS5hbnkuZGVlcC5rZXlzKGtleXMpO1xuICB9XG5cbiAvKipcbiAgICogIyMjIC5kb2VzTm90SGF2ZUFsbERlZXBLZXlzKG9iamVjdCwgW2tleXNdLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBkb2VzIG5vdCBoYXZlIGF0IGxlYXN0IG9uZSBvZiB0aGUgYGtleXNgIHByb3ZpZGVkLlxuICAgKiBTaW5jZSBTZXRzIGFuZCBNYXBzIGNhbiBoYXZlIG9iamVjdHMgYXMga2V5cyB5b3UgY2FuIHVzZSB0aGlzIGFzc2VydGlvbiB0byBwZXJmb3JtXG4gICAqIGEgZGVlcCBjb21wYXJpc29uLlxuICAgKiBZb3UgY2FuIGFsc28gcHJvdmlkZSBhIHNpbmdsZSBvYmplY3QgaW5zdGVhZCBvZiBhIGBrZXlzYCBhcnJheSBhbmQgaXRzIGtleXNcbiAgICogd2lsbCBiZSB1c2VkIGFzIHRoZSBleHBlY3RlZCBzZXQgb2Yga2V5cy5cbiAgICpcbiAgICogICAgIGFzc2VydC5kb2VzTm90SGF2ZUFsbERlZXBLZXlzKG5ldyBNYXAoW1t7b25lOiAnb25lJ30sICd2YWx1ZU9uZSddLCBbMSwgMl1dKSwge3RoaXNEb2VzTm90OiAnZXhpc3QnfSk7XG4gICAqICAgICBhc3NlcnQuZG9lc05vdEhhdmVBbGxEZWVwS2V5cyhuZXcgTWFwKFtbe29uZTogJ29uZSd9LCAndmFsdWVPbmUnXSwgW3t0d286ICd0d28nfSwgJ3ZhbHVlVHdvJ11dKSwgW3t0d2VudHk6ICd0d2VudHknfSwge29uZTogJ29uZSd9XSk7XG4gICAqICAgICBhc3NlcnQuZG9lc05vdEhhdmVBbGxEZWVwS2V5cyhuZXcgU2V0KFt7b25lOiAnb25lJ30sIHt0d286ICd0d28nfV0pLCB7dHdlbnR5OiAndHdlbnR5J30pO1xuICAgKiAgICAgYXNzZXJ0LmRvZXNOb3RIYXZlQWxsRGVlcEtleXMobmV3IFNldChbe29uZTogJ29uZSd9LCB7dHdvOiAndHdvJ31dKSwgW3tvbmU6ICdvbmUnfSwge2ZpZnR5OiAnZmlmdHknfV0pO1xuICAgKlxuICAgKiBAbmFtZSBkb2VzTm90SGF2ZUFsbERlZXBLZXlzXG4gICAqIEBwYXJhbSB7TWl4ZWR9IG9iamVjdFxuICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0ga2V5c1xuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuZG9lc05vdEhhdmVBbGxEZWVwS2V5cyA9IGZ1bmN0aW9uIChvYmosIGtleXMsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2csIGFzc2VydC5kb2VzTm90SGF2ZUFsbERlZXBLZXlzLCB0cnVlKVxuICAgICAgLnRvLm5vdC5oYXZlLmFsbC5kZWVwLmtleXMoa2V5cyk7XG4gIH1cblxuIC8qKlxuICAgKiAjIyMgLnRocm93cyhmbiwgW2Vycm9yTGlrZS9zdHJpbmcvcmVnZXhwXSwgW3N0cmluZy9yZWdleHBdLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIElmIGBlcnJvckxpa2VgIGlzIGFuIGBFcnJvcmAgY29uc3RydWN0b3IsIGFzc2VydHMgdGhhdCBgZm5gIHdpbGwgdGhyb3cgYW4gZXJyb3IgdGhhdCBpcyBhblxuICAgKiBpbnN0YW5jZSBvZiBgZXJyb3JMaWtlYC5cbiAgICogSWYgYGVycm9yTGlrZWAgaXMgYW4gYEVycm9yYCBpbnN0YW5jZSwgYXNzZXJ0cyB0aGF0IHRoZSBlcnJvciB0aHJvd24gaXMgdGhlIHNhbWVcbiAgICogaW5zdGFuY2UgYXMgYGVycm9yTGlrZWAuXG4gICAqIElmIGBlcnJNc2dNYXRjaGVyYCBpcyBwcm92aWRlZCwgaXQgYWxzbyBhc3NlcnRzIHRoYXQgdGhlIGVycm9yIHRocm93biB3aWxsIGhhdmUgYVxuICAgKiBtZXNzYWdlIG1hdGNoaW5nIGBlcnJNc2dNYXRjaGVyYC5cbiAgICpcbiAgICogICAgIGFzc2VydC50aHJvd3MoZm4sICdFcnJvciB0aHJvd24gbXVzdCBoYXZlIHRoaXMgbXNnJyk7XG4gICAqICAgICBhc3NlcnQudGhyb3dzKGZuLCAvRXJyb3IgdGhyb3duIG11c3QgaGF2ZSBhIG1zZyB0aGF0IG1hdGNoZXMgdGhpcy8pO1xuICAgKiAgICAgYXNzZXJ0LnRocm93cyhmbiwgUmVmZXJlbmNlRXJyb3IpO1xuICAgKiAgICAgYXNzZXJ0LnRocm93cyhmbiwgZXJyb3JJbnN0YW5jZSk7XG4gICAqICAgICBhc3NlcnQudGhyb3dzKGZuLCBSZWZlcmVuY2VFcnJvciwgJ0Vycm9yIHRocm93biBtdXN0IGJlIGEgUmVmZXJlbmNlRXJyb3IgYW5kIGhhdmUgdGhpcyBtc2cnKTtcbiAgICogICAgIGFzc2VydC50aHJvd3MoZm4sIGVycm9ySW5zdGFuY2UsICdFcnJvciB0aHJvd24gbXVzdCBiZSB0aGUgc2FtZSBlcnJvckluc3RhbmNlIGFuZCBoYXZlIHRoaXMgbXNnJyk7XG4gICAqICAgICBhc3NlcnQudGhyb3dzKGZuLCBSZWZlcmVuY2VFcnJvciwgL0Vycm9yIHRocm93biBtdXN0IGJlIGEgUmVmZXJlbmNlRXJyb3IgYW5kIG1hdGNoIHRoaXMvKTtcbiAgICogICAgIGFzc2VydC50aHJvd3MoZm4sIGVycm9ySW5zdGFuY2UsIC9FcnJvciB0aHJvd24gbXVzdCBiZSB0aGUgc2FtZSBlcnJvckluc3RhbmNlIGFuZCBtYXRjaCB0aGlzLyk7XG4gICAqXG4gICAqIEBuYW1lIHRocm93c1xuICAgKiBAYWxpYXMgdGhyb3dcbiAgICogQGFsaWFzIFRocm93XG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gICAqIEBwYXJhbSB7RXJyb3JDb25zdHJ1Y3RvcnxFcnJvcn0gZXJyb3JMaWtlXG4gICAqIEBwYXJhbSB7UmVnRXhwfFN0cmluZ30gZXJyTXNnTWF0Y2hlclxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0Vycm9yI0Vycm9yX3R5cGVzXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC50aHJvd3MgPSBmdW5jdGlvbiAoZm4sIGVycm9yTGlrZSwgZXJyTXNnTWF0Y2hlciwgbXNnKSB7XG4gICAgaWYgKCdzdHJpbmcnID09PSB0eXBlb2YgZXJyb3JMaWtlIHx8IGVycm9yTGlrZSBpbnN0YW5jZW9mIFJlZ0V4cCkge1xuICAgICAgZXJyTXNnTWF0Y2hlciA9IGVycm9yTGlrZTtcbiAgICAgIGVycm9yTGlrZSA9IG51bGw7XG4gICAgfVxuXG4gICAgdmFyIGFzc2VydEVyciA9IG5ldyBBc3NlcnRpb24oZm4sIG1zZywgYXNzZXJ0LnRocm93cywgdHJ1ZSlcbiAgICAgIC50by50aHJvdyhlcnJvckxpa2UsIGVyck1zZ01hdGNoZXIpO1xuICAgIHJldHVybiBmbGFnKGFzc2VydEVyciwgJ29iamVjdCcpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmRvZXNOb3RUaHJvdyhmbiwgW2Vycm9yTGlrZS9zdHJpbmcvcmVnZXhwXSwgW3N0cmluZy9yZWdleHBdLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIElmIGBlcnJvckxpa2VgIGlzIGFuIGBFcnJvcmAgY29uc3RydWN0b3IsIGFzc2VydHMgdGhhdCBgZm5gIHdpbGwgX25vdF8gdGhyb3cgYW4gZXJyb3IgdGhhdCBpcyBhblxuICAgKiBpbnN0YW5jZSBvZiBgZXJyb3JMaWtlYC5cbiAgICogSWYgYGVycm9yTGlrZWAgaXMgYW4gYEVycm9yYCBpbnN0YW5jZSwgYXNzZXJ0cyB0aGF0IHRoZSBlcnJvciB0aHJvd24gaXMgX25vdF8gdGhlIHNhbWVcbiAgICogaW5zdGFuY2UgYXMgYGVycm9yTGlrZWAuXG4gICAqIElmIGBlcnJNc2dNYXRjaGVyYCBpcyBwcm92aWRlZCwgaXQgYWxzbyBhc3NlcnRzIHRoYXQgdGhlIGVycm9yIHRocm93biB3aWxsIF9ub3RfIGhhdmUgYVxuICAgKiBtZXNzYWdlIG1hdGNoaW5nIGBlcnJNc2dNYXRjaGVyYC5cbiAgICpcbiAgICogICAgIGFzc2VydC5kb2VzTm90VGhyb3coZm4sICdBbnkgRXJyb3IgdGhyb3duIG11c3Qgbm90IGhhdmUgdGhpcyBtZXNzYWdlJyk7XG4gICAqICAgICBhc3NlcnQuZG9lc05vdFRocm93KGZuLCAvQW55IEVycm9yIHRocm93biBtdXN0IG5vdCBtYXRjaCB0aGlzLyk7XG4gICAqICAgICBhc3NlcnQuZG9lc05vdFRocm93KGZuLCBFcnJvcik7XG4gICAqICAgICBhc3NlcnQuZG9lc05vdFRocm93KGZuLCBlcnJvckluc3RhbmNlKTtcbiAgICogICAgIGFzc2VydC5kb2VzTm90VGhyb3coZm4sIEVycm9yLCAnRXJyb3IgbXVzdCBub3QgaGF2ZSB0aGlzIG1lc3NhZ2UnKTtcbiAgICogICAgIGFzc2VydC5kb2VzTm90VGhyb3coZm4sIGVycm9ySW5zdGFuY2UsICdFcnJvciBtdXN0IG5vdCBoYXZlIHRoaXMgbWVzc2FnZScpO1xuICAgKiAgICAgYXNzZXJ0LmRvZXNOb3RUaHJvdyhmbiwgRXJyb3IsIC9FcnJvciBtdXN0IG5vdCBtYXRjaCB0aGlzLyk7XG4gICAqICAgICBhc3NlcnQuZG9lc05vdFRocm93KGZuLCBlcnJvckluc3RhbmNlLCAvRXJyb3IgbXVzdCBub3QgbWF0Y2ggdGhpcy8pO1xuICAgKlxuICAgKiBAbmFtZSBkb2VzTm90VGhyb3dcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAgICogQHBhcmFtIHtFcnJvckNvbnN0cnVjdG9yfSBlcnJvckxpa2VcbiAgICogQHBhcmFtIHtSZWdFeHB8U3RyaW5nfSBlcnJNc2dNYXRjaGVyXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4vSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvRXJyb3IjRXJyb3JfdHlwZXNcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmRvZXNOb3RUaHJvdyA9IGZ1bmN0aW9uIChmbiwgZXJyb3JMaWtlLCBlcnJNc2dNYXRjaGVyLCBtc2cpIHtcbiAgICBpZiAoJ3N0cmluZycgPT09IHR5cGVvZiBlcnJvckxpa2UgfHwgZXJyb3JMaWtlIGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICBlcnJNc2dNYXRjaGVyID0gZXJyb3JMaWtlO1xuICAgICAgZXJyb3JMaWtlID0gbnVsbDtcbiAgICB9XG5cbiAgICBuZXcgQXNzZXJ0aW9uKGZuLCBtc2csIGFzc2VydC5kb2VzTm90VGhyb3csIHRydWUpXG4gICAgICAudG8ubm90LnRocm93KGVycm9yTGlrZSwgZXJyTXNnTWF0Y2hlcik7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAub3BlcmF0b3IodmFsMSwgb3BlcmF0b3IsIHZhbDIsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQ29tcGFyZXMgdHdvIHZhbHVlcyB1c2luZyBgb3BlcmF0b3JgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm9wZXJhdG9yKDEsICc8JywgMiwgJ2V2ZXJ5dGhpbmcgaXMgb2snKTtcbiAgICogICAgIGFzc2VydC5vcGVyYXRvcigxLCAnPicsIDIsICd0aGlzIHdpbGwgZmFpbCcpO1xuICAgKlxuICAgKiBAbmFtZSBvcGVyYXRvclxuICAgKiBAcGFyYW0ge01peGVkfSB2YWwxXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBvcGVyYXRvclxuICAgKiBAcGFyYW0ge01peGVkfSB2YWwyXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5vcGVyYXRvciA9IGZ1bmN0aW9uICh2YWwsIG9wZXJhdG9yLCB2YWwyLCBtc2cpIHtcbiAgICB2YXIgb2s7XG4gICAgc3dpdGNoKG9wZXJhdG9yKSB7XG4gICAgICBjYXNlICc9PSc6XG4gICAgICAgIG9rID0gdmFsID09IHZhbDI7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnPT09JzpcbiAgICAgICAgb2sgPSB2YWwgPT09IHZhbDI7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnPic6XG4gICAgICAgIG9rID0gdmFsID4gdmFsMjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICc+PSc6XG4gICAgICAgIG9rID0gdmFsID49IHZhbDI7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnPCc6XG4gICAgICAgIG9rID0gdmFsIDwgdmFsMjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICc8PSc6XG4gICAgICAgIG9rID0gdmFsIDw9IHZhbDI7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnIT0nOlxuICAgICAgICBvayA9IHZhbCAhPSB2YWwyO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJyE9PSc6XG4gICAgICAgIG9rID0gdmFsICE9PSB2YWwyO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIG1zZyA9IG1zZyA/IG1zZyArICc6ICcgOiBtc2c7XG4gICAgICAgIHRocm93IG5ldyBjaGFpLkFzc2VydGlvbkVycm9yKFxuICAgICAgICAgIG1zZyArICdJbnZhbGlkIG9wZXJhdG9yIFwiJyArIG9wZXJhdG9yICsgJ1wiJyxcbiAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgYXNzZXJ0Lm9wZXJhdG9yXG4gICAgICAgICk7XG4gICAgfVxuICAgIHZhciB0ZXN0ID0gbmV3IEFzc2VydGlvbihvaywgbXNnLCBhc3NlcnQub3BlcmF0b3IsIHRydWUpO1xuICAgIHRlc3QuYXNzZXJ0KFxuICAgICAgICB0cnVlID09PSBmbGFnKHRlc3QsICdvYmplY3QnKVxuICAgICAgLCAnZXhwZWN0ZWQgJyArIHV0aWwuaW5zcGVjdCh2YWwpICsgJyB0byBiZSAnICsgb3BlcmF0b3IgKyAnICcgKyB1dGlsLmluc3BlY3QodmFsMilcbiAgICAgICwgJ2V4cGVjdGVkICcgKyB1dGlsLmluc3BlY3QodmFsKSArICcgdG8gbm90IGJlICcgKyBvcGVyYXRvciArICcgJyArIHV0aWwuaW5zcGVjdCh2YWwyKSApO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmNsb3NlVG8oYWN0dWFsLCBleHBlY3RlZCwgZGVsdGEsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaXMgZXF1YWwgYGV4cGVjdGVkYCwgdG8gd2l0aGluIGEgKy8tIGBkZWx0YWAgcmFuZ2UuXG4gICAqXG4gICAqICAgICBhc3NlcnQuY2xvc2VUbygxLjUsIDEsIDAuNSwgJ251bWJlcnMgYXJlIGNsb3NlJyk7XG4gICAqXG4gICAqIEBuYW1lIGNsb3NlVG9cbiAgICogQHBhcmFtIHtOdW1iZXJ9IGFjdHVhbFxuICAgKiBAcGFyYW0ge051bWJlcn0gZXhwZWN0ZWRcbiAgICogQHBhcmFtIHtOdW1iZXJ9IGRlbHRhXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5jbG9zZVRvID0gZnVuY3Rpb24gKGFjdCwgZXhwLCBkZWx0YSwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihhY3QsIG1zZywgYXNzZXJ0LmNsb3NlVG8sIHRydWUpLnRvLmJlLmNsb3NlVG8oZXhwLCBkZWx0YSk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuYXBwcm94aW1hdGVseShhY3R1YWwsIGV4cGVjdGVkLCBkZWx0YSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBlcXVhbCBgZXhwZWN0ZWRgLCB0byB3aXRoaW4gYSArLy0gYGRlbHRhYCByYW5nZS5cbiAgICpcbiAgICogICAgIGFzc2VydC5hcHByb3hpbWF0ZWx5KDEuNSwgMSwgMC41LCAnbnVtYmVycyBhcmUgY2xvc2UnKTtcbiAgICpcbiAgICogQG5hbWUgYXBwcm94aW1hdGVseVxuICAgKiBAcGFyYW0ge051bWJlcn0gYWN0dWFsXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBleHBlY3RlZFxuICAgKiBAcGFyYW0ge051bWJlcn0gZGVsdGFcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmFwcHJveGltYXRlbHkgPSBmdW5jdGlvbiAoYWN0LCBleHAsIGRlbHRhLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKGFjdCwgbXNnLCBhc3NlcnQuYXBwcm94aW1hdGVseSwgdHJ1ZSlcbiAgICAgIC50by5iZS5hcHByb3hpbWF0ZWx5KGV4cCwgZGVsdGEpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLnNhbWVNZW1iZXJzKHNldDEsIHNldDIsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBzZXQxYCBhbmQgYHNldDJgIGhhdmUgdGhlIHNhbWUgbWVtYmVycyBpbiBhbnkgb3JkZXIuIFVzZXMgYVxuICAgKiBzdHJpY3QgZXF1YWxpdHkgY2hlY2sgKD09PSkuXG4gICAqXG4gICAqICAgICBhc3NlcnQuc2FtZU1lbWJlcnMoWyAxLCAyLCAzIF0sIFsgMiwgMSwgMyBdLCAnc2FtZSBtZW1iZXJzJyk7XG4gICAqXG4gICAqIEBuYW1lIHNhbWVNZW1iZXJzXG4gICAqIEBwYXJhbSB7QXJyYXl9IHNldDFcbiAgICogQHBhcmFtIHtBcnJheX0gc2V0MlxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuc2FtZU1lbWJlcnMgPSBmdW5jdGlvbiAoc2V0MSwgc2V0MiwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihzZXQxLCBtc2csIGFzc2VydC5zYW1lTWVtYmVycywgdHJ1ZSlcbiAgICAgIC50by5oYXZlLnNhbWUubWVtYmVycyhzZXQyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiAjIyMgLm5vdFNhbWVNZW1iZXJzKHNldDEsIHNldDIsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBzZXQxYCBhbmQgYHNldDJgIGRvbid0IGhhdmUgdGhlIHNhbWUgbWVtYmVycyBpbiBhbnkgb3JkZXIuXG4gICAqIFVzZXMgYSBzdHJpY3QgZXF1YWxpdHkgY2hlY2sgKD09PSkuXG4gICAqXG4gICAqICAgICBhc3NlcnQubm90U2FtZU1lbWJlcnMoWyAxLCAyLCAzIF0sIFsgNSwgMSwgMyBdLCAnbm90IHNhbWUgbWVtYmVycycpO1xuICAgKlxuICAgKiBAbmFtZSBub3RTYW1lTWVtYmVyc1xuICAgKiBAcGFyYW0ge0FycmF5fSBzZXQxXG4gICAqIEBwYXJhbSB7QXJyYXl9IHNldDJcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm5vdFNhbWVNZW1iZXJzID0gZnVuY3Rpb24gKHNldDEsIHNldDIsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oc2V0MSwgbXNnLCBhc3NlcnQubm90U2FtZU1lbWJlcnMsIHRydWUpXG4gICAgICAudG8ubm90LmhhdmUuc2FtZS5tZW1iZXJzKHNldDIpO1xuICB9XG5cbiAgLyoqXG4gICAqICMjIyAuc2FtZURlZXBNZW1iZXJzKHNldDEsIHNldDIsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBzZXQxYCBhbmQgYHNldDJgIGhhdmUgdGhlIHNhbWUgbWVtYmVycyBpbiBhbnkgb3JkZXIuIFVzZXMgYVxuICAgKiBkZWVwIGVxdWFsaXR5IGNoZWNrLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LnNhbWVEZWVwTWVtYmVycyhbIHsgYTogMSB9LCB7IGI6IDIgfSwgeyBjOiAzIH0gXSwgW3sgYjogMiB9LCB7IGE6IDEgfSwgeyBjOiAzIH1dLCAnc2FtZSBkZWVwIG1lbWJlcnMnKTtcbiAgICpcbiAgICogQG5hbWUgc2FtZURlZXBNZW1iZXJzXG4gICAqIEBwYXJhbSB7QXJyYXl9IHNldDFcbiAgICogQHBhcmFtIHtBcnJheX0gc2V0MlxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuc2FtZURlZXBNZW1iZXJzID0gZnVuY3Rpb24gKHNldDEsIHNldDIsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oc2V0MSwgbXNnLCBhc3NlcnQuc2FtZURlZXBNZW1iZXJzLCB0cnVlKVxuICAgICAgLnRvLmhhdmUuc2FtZS5kZWVwLm1lbWJlcnMoc2V0Mik7XG4gIH1cblxuICAvKipcbiAgICogIyMjIC5ub3RTYW1lRGVlcE1lbWJlcnMoc2V0MSwgc2V0MiwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHNldDFgIGFuZCBgc2V0MmAgZG9uJ3QgaGF2ZSB0aGUgc2FtZSBtZW1iZXJzIGluIGFueSBvcmRlci5cbiAgICogVXNlcyBhIGRlZXAgZXF1YWxpdHkgY2hlY2suXG4gICAqXG4gICAqICAgICBhc3NlcnQubm90U2FtZURlZXBNZW1iZXJzKFsgeyBhOiAxIH0sIHsgYjogMiB9LCB7IGM6IDMgfSBdLCBbeyBiOiAyIH0sIHsgYTogMSB9LCB7IGY6IDUgfV0sICdub3Qgc2FtZSBkZWVwIG1lbWJlcnMnKTtcbiAgICpcbiAgICogQG5hbWUgbm90U2FtZURlZXBNZW1iZXJzXG4gICAqIEBwYXJhbSB7QXJyYXl9IHNldDFcbiAgICogQHBhcmFtIHtBcnJheX0gc2V0MlxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubm90U2FtZURlZXBNZW1iZXJzID0gZnVuY3Rpb24gKHNldDEsIHNldDIsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oc2V0MSwgbXNnLCBhc3NlcnQubm90U2FtZURlZXBNZW1iZXJzLCB0cnVlKVxuICAgICAgLnRvLm5vdC5oYXZlLnNhbWUuZGVlcC5tZW1iZXJzKHNldDIpO1xuICB9XG5cbiAgLyoqXG4gICAqICMjIyAuc2FtZU9yZGVyZWRNZW1iZXJzKHNldDEsIHNldDIsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBzZXQxYCBhbmQgYHNldDJgIGhhdmUgdGhlIHNhbWUgbWVtYmVycyBpbiB0aGUgc2FtZSBvcmRlci5cbiAgICogVXNlcyBhIHN0cmljdCBlcXVhbGl0eSBjaGVjayAoPT09KS5cbiAgICpcbiAgICogICAgIGFzc2VydC5zYW1lT3JkZXJlZE1lbWJlcnMoWyAxLCAyLCAzIF0sIFsgMSwgMiwgMyBdLCAnc2FtZSBvcmRlcmVkIG1lbWJlcnMnKTtcbiAgICpcbiAgICogQG5hbWUgc2FtZU9yZGVyZWRNZW1iZXJzXG4gICAqIEBwYXJhbSB7QXJyYXl9IHNldDFcbiAgICogQHBhcmFtIHtBcnJheX0gc2V0MlxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuc2FtZU9yZGVyZWRNZW1iZXJzID0gZnVuY3Rpb24gKHNldDEsIHNldDIsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oc2V0MSwgbXNnLCBhc3NlcnQuc2FtZU9yZGVyZWRNZW1iZXJzLCB0cnVlKVxuICAgICAgLnRvLmhhdmUuc2FtZS5vcmRlcmVkLm1lbWJlcnMoc2V0Mik7XG4gIH1cblxuICAvKipcbiAgICogIyMjIC5ub3RTYW1lT3JkZXJlZE1lbWJlcnMoc2V0MSwgc2V0MiwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHNldDFgIGFuZCBgc2V0MmAgZG9uJ3QgaGF2ZSB0aGUgc2FtZSBtZW1iZXJzIGluIHRoZSBzYW1lXG4gICAqIG9yZGVyLiBVc2VzIGEgc3RyaWN0IGVxdWFsaXR5IGNoZWNrICg9PT0pLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm5vdFNhbWVPcmRlcmVkTWVtYmVycyhbIDEsIDIsIDMgXSwgWyAyLCAxLCAzIF0sICdub3Qgc2FtZSBvcmRlcmVkIG1lbWJlcnMnKTtcbiAgICpcbiAgICogQG5hbWUgbm90U2FtZU9yZGVyZWRNZW1iZXJzXG4gICAqIEBwYXJhbSB7QXJyYXl9IHNldDFcbiAgICogQHBhcmFtIHtBcnJheX0gc2V0MlxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubm90U2FtZU9yZGVyZWRNZW1iZXJzID0gZnVuY3Rpb24gKHNldDEsIHNldDIsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oc2V0MSwgbXNnLCBhc3NlcnQubm90U2FtZU9yZGVyZWRNZW1iZXJzLCB0cnVlKVxuICAgICAgLnRvLm5vdC5oYXZlLnNhbWUub3JkZXJlZC5tZW1iZXJzKHNldDIpO1xuICB9XG5cbiAgLyoqXG4gICAqICMjIyAuc2FtZURlZXBPcmRlcmVkTWVtYmVycyhzZXQxLCBzZXQyLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgc2V0MWAgYW5kIGBzZXQyYCBoYXZlIHRoZSBzYW1lIG1lbWJlcnMgaW4gdGhlIHNhbWUgb3JkZXIuXG4gICAqIFVzZXMgYSBkZWVwIGVxdWFsaXR5IGNoZWNrLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LnNhbWVEZWVwT3JkZXJlZE1lbWJlcnMoWyB7IGE6IDEgfSwgeyBiOiAyIH0sIHsgYzogMyB9IF0sIFsgeyBhOiAxIH0sIHsgYjogMiB9LCB7IGM6IDMgfSBdLCAnc2FtZSBkZWVwIG9yZGVyZWQgbWVtYmVycycpO1xuICAgKlxuICAgKiBAbmFtZSBzYW1lRGVlcE9yZGVyZWRNZW1iZXJzXG4gICAqIEBwYXJhbSB7QXJyYXl9IHNldDFcbiAgICogQHBhcmFtIHtBcnJheX0gc2V0MlxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuc2FtZURlZXBPcmRlcmVkTWVtYmVycyA9IGZ1bmN0aW9uIChzZXQxLCBzZXQyLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHNldDEsIG1zZywgYXNzZXJ0LnNhbWVEZWVwT3JkZXJlZE1lbWJlcnMsIHRydWUpXG4gICAgICAudG8uaGF2ZS5zYW1lLmRlZXAub3JkZXJlZC5tZW1iZXJzKHNldDIpO1xuICB9XG5cbiAgLyoqXG4gICAqICMjIyAubm90U2FtZURlZXBPcmRlcmVkTWVtYmVycyhzZXQxLCBzZXQyLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgc2V0MWAgYW5kIGBzZXQyYCBkb24ndCBoYXZlIHRoZSBzYW1lIG1lbWJlcnMgaW4gdGhlIHNhbWVcbiAgICogb3JkZXIuIFVzZXMgYSBkZWVwIGVxdWFsaXR5IGNoZWNrLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm5vdFNhbWVEZWVwT3JkZXJlZE1lbWJlcnMoWyB7IGE6IDEgfSwgeyBiOiAyIH0sIHsgYzogMyB9IF0sIFsgeyBhOiAxIH0sIHsgYjogMiB9LCB7IHo6IDUgfSBdLCAnbm90IHNhbWUgZGVlcCBvcmRlcmVkIG1lbWJlcnMnKTtcbiAgICogICAgIGFzc2VydC5ub3RTYW1lRGVlcE9yZGVyZWRNZW1iZXJzKFsgeyBhOiAxIH0sIHsgYjogMiB9LCB7IGM6IDMgfSBdLCBbIHsgYjogMiB9LCB7IGE6IDEgfSwgeyBjOiAzIH0gXSwgJ25vdCBzYW1lIGRlZXAgb3JkZXJlZCBtZW1iZXJzJyk7XG4gICAqXG4gICAqIEBuYW1lIG5vdFNhbWVEZWVwT3JkZXJlZE1lbWJlcnNcbiAgICogQHBhcmFtIHtBcnJheX0gc2V0MVxuICAgKiBAcGFyYW0ge0FycmF5fSBzZXQyXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5ub3RTYW1lRGVlcE9yZGVyZWRNZW1iZXJzID0gZnVuY3Rpb24gKHNldDEsIHNldDIsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oc2V0MSwgbXNnLCBhc3NlcnQubm90U2FtZURlZXBPcmRlcmVkTWVtYmVycywgdHJ1ZSlcbiAgICAgIC50by5ub3QuaGF2ZS5zYW1lLmRlZXAub3JkZXJlZC5tZW1iZXJzKHNldDIpO1xuICB9XG5cbiAgLyoqXG4gICAqICMjIyAuaW5jbHVkZU1lbWJlcnMoc3VwZXJzZXQsIHN1YnNldCwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHN1YnNldGAgaXMgaW5jbHVkZWQgaW4gYHN1cGVyc2V0YCBpbiBhbnkgb3JkZXIuIFVzZXMgYVxuICAgKiBzdHJpY3QgZXF1YWxpdHkgY2hlY2sgKD09PSkuIER1cGxpY2F0ZXMgYXJlIGlnbm9yZWQuXG4gICAqXG4gICAqICAgICBhc3NlcnQuaW5jbHVkZU1lbWJlcnMoWyAxLCAyLCAzIF0sIFsgMiwgMSwgMiBdLCAnaW5jbHVkZSBtZW1iZXJzJyk7XG4gICAqXG4gICAqIEBuYW1lIGluY2x1ZGVNZW1iZXJzXG4gICAqIEBwYXJhbSB7QXJyYXl9IHN1cGVyc2V0XG4gICAqIEBwYXJhbSB7QXJyYXl9IHN1YnNldFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaW5jbHVkZU1lbWJlcnMgPSBmdW5jdGlvbiAoc3VwZXJzZXQsIHN1YnNldCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihzdXBlcnNldCwgbXNnLCBhc3NlcnQuaW5jbHVkZU1lbWJlcnMsIHRydWUpXG4gICAgICAudG8uaW5jbHVkZS5tZW1iZXJzKHN1YnNldCk7XG4gIH1cblxuICAvKipcbiAgICogIyMjIC5ub3RJbmNsdWRlTWVtYmVycyhzdXBlcnNldCwgc3Vic2V0LCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgc3Vic2V0YCBpc24ndCBpbmNsdWRlZCBpbiBgc3VwZXJzZXRgIGluIGFueSBvcmRlci4gVXNlcyBhXG4gICAqIHN0cmljdCBlcXVhbGl0eSBjaGVjayAoPT09KS4gRHVwbGljYXRlcyBhcmUgaWdub3JlZC5cbiAgICpcbiAgICogICAgIGFzc2VydC5ub3RJbmNsdWRlTWVtYmVycyhbIDEsIDIsIDMgXSwgWyA1LCAxIF0sICdub3QgaW5jbHVkZSBtZW1iZXJzJyk7XG4gICAqXG4gICAqIEBuYW1lIG5vdEluY2x1ZGVNZW1iZXJzXG4gICAqIEBwYXJhbSB7QXJyYXl9IHN1cGVyc2V0XG4gICAqIEBwYXJhbSB7QXJyYXl9IHN1YnNldFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubm90SW5jbHVkZU1lbWJlcnMgPSBmdW5jdGlvbiAoc3VwZXJzZXQsIHN1YnNldCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihzdXBlcnNldCwgbXNnLCBhc3NlcnQubm90SW5jbHVkZU1lbWJlcnMsIHRydWUpXG4gICAgICAudG8ubm90LmluY2x1ZGUubWVtYmVycyhzdWJzZXQpO1xuICB9XG5cbiAgLyoqXG4gICAqICMjIyAuaW5jbHVkZURlZXBNZW1iZXJzKHN1cGVyc2V0LCBzdWJzZXQsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBzdWJzZXRgIGlzIGluY2x1ZGVkIGluIGBzdXBlcnNldGAgaW4gYW55IG9yZGVyLiBVc2VzIGEgZGVlcFxuICAgKiBlcXVhbGl0eSBjaGVjay4gRHVwbGljYXRlcyBhcmUgaWdub3JlZC5cbiAgICpcbiAgICogICAgIGFzc2VydC5pbmNsdWRlRGVlcE1lbWJlcnMoWyB7IGE6IDEgfSwgeyBiOiAyIH0sIHsgYzogMyB9IF0sIFsgeyBiOiAyIH0sIHsgYTogMSB9LCB7IGI6IDIgfSBdLCAnaW5jbHVkZSBkZWVwIG1lbWJlcnMnKTtcbiAgICpcbiAgICogQG5hbWUgaW5jbHVkZURlZXBNZW1iZXJzXG4gICAqIEBwYXJhbSB7QXJyYXl9IHN1cGVyc2V0XG4gICAqIEBwYXJhbSB7QXJyYXl9IHN1YnNldFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaW5jbHVkZURlZXBNZW1iZXJzID0gZnVuY3Rpb24gKHN1cGVyc2V0LCBzdWJzZXQsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oc3VwZXJzZXQsIG1zZywgYXNzZXJ0LmluY2x1ZGVEZWVwTWVtYmVycywgdHJ1ZSlcbiAgICAgIC50by5pbmNsdWRlLmRlZXAubWVtYmVycyhzdWJzZXQpO1xuICB9XG5cbiAgLyoqXG4gICAqICMjIyAubm90SW5jbHVkZURlZXBNZW1iZXJzKHN1cGVyc2V0LCBzdWJzZXQsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBzdWJzZXRgIGlzbid0IGluY2x1ZGVkIGluIGBzdXBlcnNldGAgaW4gYW55IG9yZGVyLiBVc2VzIGFcbiAgICogZGVlcCBlcXVhbGl0eSBjaGVjay4gRHVwbGljYXRlcyBhcmUgaWdub3JlZC5cbiAgICpcbiAgICogICAgIGFzc2VydC5ub3RJbmNsdWRlRGVlcE1lbWJlcnMoWyB7IGE6IDEgfSwgeyBiOiAyIH0sIHsgYzogMyB9IF0sIFsgeyBiOiAyIH0sIHsgZjogNSB9IF0sICdub3QgaW5jbHVkZSBkZWVwIG1lbWJlcnMnKTtcbiAgICpcbiAgICogQG5hbWUgbm90SW5jbHVkZURlZXBNZW1iZXJzXG4gICAqIEBwYXJhbSB7QXJyYXl9IHN1cGVyc2V0XG4gICAqIEBwYXJhbSB7QXJyYXl9IHN1YnNldFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubm90SW5jbHVkZURlZXBNZW1iZXJzID0gZnVuY3Rpb24gKHN1cGVyc2V0LCBzdWJzZXQsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oc3VwZXJzZXQsIG1zZywgYXNzZXJ0Lm5vdEluY2x1ZGVEZWVwTWVtYmVycywgdHJ1ZSlcbiAgICAgIC50by5ub3QuaW5jbHVkZS5kZWVwLm1lbWJlcnMoc3Vic2V0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiAjIyMgLmluY2x1ZGVPcmRlcmVkTWVtYmVycyhzdXBlcnNldCwgc3Vic2V0LCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgc3Vic2V0YCBpcyBpbmNsdWRlZCBpbiBgc3VwZXJzZXRgIGluIHRoZSBzYW1lIG9yZGVyXG4gICAqIGJlZ2lubmluZyB3aXRoIHRoZSBmaXJzdCBlbGVtZW50IGluIGBzdXBlcnNldGAuIFVzZXMgYSBzdHJpY3QgZXF1YWxpdHlcbiAgICogY2hlY2sgKD09PSkuXG4gICAqXG4gICAqICAgICBhc3NlcnQuaW5jbHVkZU9yZGVyZWRNZW1iZXJzKFsgMSwgMiwgMyBdLCBbIDEsIDIgXSwgJ2luY2x1ZGUgb3JkZXJlZCBtZW1iZXJzJyk7XG4gICAqXG4gICAqIEBuYW1lIGluY2x1ZGVPcmRlcmVkTWVtYmVyc1xuICAgKiBAcGFyYW0ge0FycmF5fSBzdXBlcnNldFxuICAgKiBAcGFyYW0ge0FycmF5fSBzdWJzZXRcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmluY2x1ZGVPcmRlcmVkTWVtYmVycyA9IGZ1bmN0aW9uIChzdXBlcnNldCwgc3Vic2V0LCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHN1cGVyc2V0LCBtc2csIGFzc2VydC5pbmNsdWRlT3JkZXJlZE1lbWJlcnMsIHRydWUpXG4gICAgICAudG8uaW5jbHVkZS5vcmRlcmVkLm1lbWJlcnMoc3Vic2V0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiAjIyMgLm5vdEluY2x1ZGVPcmRlcmVkTWVtYmVycyhzdXBlcnNldCwgc3Vic2V0LCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgc3Vic2V0YCBpc24ndCBpbmNsdWRlZCBpbiBgc3VwZXJzZXRgIGluIHRoZSBzYW1lIG9yZGVyXG4gICAqIGJlZ2lubmluZyB3aXRoIHRoZSBmaXJzdCBlbGVtZW50IGluIGBzdXBlcnNldGAuIFVzZXMgYSBzdHJpY3QgZXF1YWxpdHlcbiAgICogY2hlY2sgKD09PSkuXG4gICAqXG4gICAqICAgICBhc3NlcnQubm90SW5jbHVkZU9yZGVyZWRNZW1iZXJzKFsgMSwgMiwgMyBdLCBbIDIsIDEgXSwgJ25vdCBpbmNsdWRlIG9yZGVyZWQgbWVtYmVycycpO1xuICAgKiAgICAgYXNzZXJ0Lm5vdEluY2x1ZGVPcmRlcmVkTWVtYmVycyhbIDEsIDIsIDMgXSwgWyAyLCAzIF0sICdub3QgaW5jbHVkZSBvcmRlcmVkIG1lbWJlcnMnKTtcbiAgICpcbiAgICogQG5hbWUgbm90SW5jbHVkZU9yZGVyZWRNZW1iZXJzXG4gICAqIEBwYXJhbSB7QXJyYXl9IHN1cGVyc2V0XG4gICAqIEBwYXJhbSB7QXJyYXl9IHN1YnNldFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubm90SW5jbHVkZU9yZGVyZWRNZW1iZXJzID0gZnVuY3Rpb24gKHN1cGVyc2V0LCBzdWJzZXQsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oc3VwZXJzZXQsIG1zZywgYXNzZXJ0Lm5vdEluY2x1ZGVPcmRlcmVkTWVtYmVycywgdHJ1ZSlcbiAgICAgIC50by5ub3QuaW5jbHVkZS5vcmRlcmVkLm1lbWJlcnMoc3Vic2V0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiAjIyMgLmluY2x1ZGVEZWVwT3JkZXJlZE1lbWJlcnMoc3VwZXJzZXQsIHN1YnNldCwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHN1YnNldGAgaXMgaW5jbHVkZWQgaW4gYHN1cGVyc2V0YCBpbiB0aGUgc2FtZSBvcmRlclxuICAgKiBiZWdpbm5pbmcgd2l0aCB0aGUgZmlyc3QgZWxlbWVudCBpbiBgc3VwZXJzZXRgLiBVc2VzIGEgZGVlcCBlcXVhbGl0eVxuICAgKiBjaGVjay5cbiAgICpcbiAgICogICAgIGFzc2VydC5pbmNsdWRlRGVlcE9yZGVyZWRNZW1iZXJzKFsgeyBhOiAxIH0sIHsgYjogMiB9LCB7IGM6IDMgfSBdLCBbIHsgYTogMSB9LCB7IGI6IDIgfSBdLCAnaW5jbHVkZSBkZWVwIG9yZGVyZWQgbWVtYmVycycpO1xuICAgKlxuICAgKiBAbmFtZSBpbmNsdWRlRGVlcE9yZGVyZWRNZW1iZXJzXG4gICAqIEBwYXJhbSB7QXJyYXl9IHN1cGVyc2V0XG4gICAqIEBwYXJhbSB7QXJyYXl9IHN1YnNldFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaW5jbHVkZURlZXBPcmRlcmVkTWVtYmVycyA9IGZ1bmN0aW9uIChzdXBlcnNldCwgc3Vic2V0LCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHN1cGVyc2V0LCBtc2csIGFzc2VydC5pbmNsdWRlRGVlcE9yZGVyZWRNZW1iZXJzLCB0cnVlKVxuICAgICAgLnRvLmluY2x1ZGUuZGVlcC5vcmRlcmVkLm1lbWJlcnMoc3Vic2V0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiAjIyMgLm5vdEluY2x1ZGVEZWVwT3JkZXJlZE1lbWJlcnMoc3VwZXJzZXQsIHN1YnNldCwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHN1YnNldGAgaXNuJ3QgaW5jbHVkZWQgaW4gYHN1cGVyc2V0YCBpbiB0aGUgc2FtZSBvcmRlclxuICAgKiBiZWdpbm5pbmcgd2l0aCB0aGUgZmlyc3QgZWxlbWVudCBpbiBgc3VwZXJzZXRgLiBVc2VzIGEgZGVlcCBlcXVhbGl0eVxuICAgKiBjaGVjay5cbiAgICpcbiAgICogICAgIGFzc2VydC5ub3RJbmNsdWRlRGVlcE9yZGVyZWRNZW1iZXJzKFsgeyBhOiAxIH0sIHsgYjogMiB9LCB7IGM6IDMgfSBdLCBbIHsgYTogMSB9LCB7IGY6IDUgfSBdLCAnbm90IGluY2x1ZGUgZGVlcCBvcmRlcmVkIG1lbWJlcnMnKTtcbiAgICogICAgIGFzc2VydC5ub3RJbmNsdWRlRGVlcE9yZGVyZWRNZW1iZXJzKFsgeyBhOiAxIH0sIHsgYjogMiB9LCB7IGM6IDMgfSBdLCBbIHsgYjogMiB9LCB7IGE6IDEgfSBdLCAnbm90IGluY2x1ZGUgZGVlcCBvcmRlcmVkIG1lbWJlcnMnKTtcbiAgICogICAgIGFzc2VydC5ub3RJbmNsdWRlRGVlcE9yZGVyZWRNZW1iZXJzKFsgeyBhOiAxIH0sIHsgYjogMiB9LCB7IGM6IDMgfSBdLCBbIHsgYjogMiB9LCB7IGM6IDMgfSBdLCAnbm90IGluY2x1ZGUgZGVlcCBvcmRlcmVkIG1lbWJlcnMnKTtcbiAgICpcbiAgICogQG5hbWUgbm90SW5jbHVkZURlZXBPcmRlcmVkTWVtYmVyc1xuICAgKiBAcGFyYW0ge0FycmF5fSBzdXBlcnNldFxuICAgKiBAcGFyYW0ge0FycmF5fSBzdWJzZXRcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm5vdEluY2x1ZGVEZWVwT3JkZXJlZE1lbWJlcnMgPSBmdW5jdGlvbiAoc3VwZXJzZXQsIHN1YnNldCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihzdXBlcnNldCwgbXNnLCBhc3NlcnQubm90SW5jbHVkZURlZXBPcmRlcmVkTWVtYmVycywgdHJ1ZSlcbiAgICAgIC50by5ub3QuaW5jbHVkZS5kZWVwLm9yZGVyZWQubWVtYmVycyhzdWJzZXQpO1xuICB9XG5cbiAgLyoqXG4gICAqICMjIyAub25lT2YoaW5MaXN0LCBsaXN0LCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBub24tb2JqZWN0LCBub24tYXJyYXkgdmFsdWUgYGluTGlzdGAgYXBwZWFycyBpbiB0aGUgZmxhdCBhcnJheSBgbGlzdGAuXG4gICAqXG4gICAqICAgICBhc3NlcnQub25lT2YoMSwgWyAyLCAxIF0sICdOb3QgZm91bmQgaW4gbGlzdCcpO1xuICAgKlxuICAgKiBAbmFtZSBvbmVPZlxuICAgKiBAcGFyYW0geyp9IGluTGlzdFxuICAgKiBAcGFyYW0ge0FycmF5PCo+fSBsaXN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5vbmVPZiA9IGZ1bmN0aW9uIChpbkxpc3QsIGxpc3QsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oaW5MaXN0LCBtc2csIGFzc2VydC5vbmVPZiwgdHJ1ZSkudG8uYmUub25lT2YobGlzdCk7XG4gIH1cblxuICAvKipcbiAgICogIyMjIC5jaGFuZ2VzKGZ1bmN0aW9uLCBvYmplY3QsIHByb3BlcnR5LCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBhIGZ1bmN0aW9uIGNoYW5nZXMgdGhlIHZhbHVlIG9mIGEgcHJvcGVydHkuXG4gICAqXG4gICAqICAgICB2YXIgb2JqID0geyB2YWw6IDEwIH07XG4gICAqICAgICB2YXIgZm4gPSBmdW5jdGlvbigpIHsgb2JqLnZhbCA9IDIyIH07XG4gICAqICAgICBhc3NlcnQuY2hhbmdlcyhmbiwgb2JqLCAndmFsJyk7XG4gICAqXG4gICAqIEBuYW1lIGNoYW5nZXNcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gbW9kaWZpZXIgZnVuY3Rpb25cbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBvciBnZXR0ZXIgZnVuY3Rpb25cbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5IG5hbWUgX29wdGlvbmFsX1xuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5jaGFuZ2VzID0gZnVuY3Rpb24gKGZuLCBvYmosIHByb3AsIG1zZykge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAzICYmIHR5cGVvZiBvYmogPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIG1zZyA9IHByb3A7XG4gICAgICBwcm9wID0gbnVsbDtcbiAgICB9XG5cbiAgICBuZXcgQXNzZXJ0aW9uKGZuLCBtc2csIGFzc2VydC5jaGFuZ2VzLCB0cnVlKS50by5jaGFuZ2Uob2JqLCBwcm9wKTtcbiAgfVxuXG4gICAvKipcbiAgICogIyMjIC5jaGFuZ2VzQnkoZnVuY3Rpb24sIG9iamVjdCwgcHJvcGVydHksIGRlbHRhLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBhIGZ1bmN0aW9uIGNoYW5nZXMgdGhlIHZhbHVlIG9mIGEgcHJvcGVydHkgYnkgYW4gYW1vdW50IChkZWx0YSkuXG4gICAqXG4gICAqICAgICB2YXIgb2JqID0geyB2YWw6IDEwIH07XG4gICAqICAgICB2YXIgZm4gPSBmdW5jdGlvbigpIHsgb2JqLnZhbCArPSAyIH07XG4gICAqICAgICBhc3NlcnQuY2hhbmdlc0J5KGZuLCBvYmosICd2YWwnLCAyKTtcbiAgICpcbiAgICogQG5hbWUgY2hhbmdlc0J5XG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IG1vZGlmaWVyIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3Qgb3IgZ2V0dGVyIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eSBuYW1lIF9vcHRpb25hbF9cbiAgICogQHBhcmFtIHtOdW1iZXJ9IGNoYW5nZSBhbW91bnQgKGRlbHRhKVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5jaGFuZ2VzQnkgPSBmdW5jdGlvbiAoZm4sIG9iaiwgcHJvcCwgZGVsdGEsIG1zZykge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSA0ICYmIHR5cGVvZiBvYmogPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHZhciB0bXBNc2cgPSBkZWx0YTtcbiAgICAgIGRlbHRhID0gcHJvcDtcbiAgICAgIG1zZyA9IHRtcE1zZztcbiAgICB9IGVsc2UgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDMpIHtcbiAgICAgIGRlbHRhID0gcHJvcDtcbiAgICAgIHByb3AgPSBudWxsO1xuICAgIH1cblxuICAgIG5ldyBBc3NlcnRpb24oZm4sIG1zZywgYXNzZXJ0LmNoYW5nZXNCeSwgdHJ1ZSlcbiAgICAgIC50by5jaGFuZ2Uob2JqLCBwcm9wKS5ieShkZWx0YSk7XG4gIH1cblxuICAgLyoqXG4gICAqICMjIyAuZG9lc05vdENoYW5nZShmdW5jdGlvbiwgb2JqZWN0LCBwcm9wZXJ0eSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYSBmdW5jdGlvbiBkb2VzIG5vdCBjaGFuZ2UgdGhlIHZhbHVlIG9mIGEgcHJvcGVydHkuXG4gICAqXG4gICAqICAgICB2YXIgb2JqID0geyB2YWw6IDEwIH07XG4gICAqICAgICB2YXIgZm4gPSBmdW5jdGlvbigpIHsgY29uc29sZS5sb2coJ2ZvbycpOyB9O1xuICAgKiAgICAgYXNzZXJ0LmRvZXNOb3RDaGFuZ2UoZm4sIG9iaiwgJ3ZhbCcpO1xuICAgKlxuICAgKiBAbmFtZSBkb2VzTm90Q2hhbmdlXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IG1vZGlmaWVyIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3Qgb3IgZ2V0dGVyIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eSBuYW1lIF9vcHRpb25hbF9cbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuZG9lc05vdENoYW5nZSA9IGZ1bmN0aW9uIChmbiwgb2JqLCBwcm9wLCBtc2cpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMyAmJiB0eXBlb2Ygb2JqID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBtc2cgPSBwcm9wO1xuICAgICAgcHJvcCA9IG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBBc3NlcnRpb24oZm4sIG1zZywgYXNzZXJ0LmRvZXNOb3RDaGFuZ2UsIHRydWUpXG4gICAgICAudG8ubm90LmNoYW5nZShvYmosIHByb3ApO1xuICB9XG5cbiAgLyoqXG4gICAqICMjIyAuY2hhbmdlc0J1dE5vdEJ5KGZ1bmN0aW9uLCBvYmplY3QsIHByb3BlcnR5LCBkZWx0YSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYSBmdW5jdGlvbiBkb2VzIG5vdCBjaGFuZ2UgdGhlIHZhbHVlIG9mIGEgcHJvcGVydHkgb3Igb2YgYSBmdW5jdGlvbidzIHJldHVybiB2YWx1ZSBieSBhbiBhbW91bnQgKGRlbHRhKVxuICAgKlxuICAgKiAgICAgdmFyIG9iaiA9IHsgdmFsOiAxMCB9O1xuICAgKiAgICAgdmFyIGZuID0gZnVuY3Rpb24oKSB7IG9iai52YWwgKz0gMTAgfTtcbiAgICogICAgIGFzc2VydC5jaGFuZ2VzQnV0Tm90QnkoZm4sIG9iaiwgJ3ZhbCcsIDUpO1xuICAgKlxuICAgKiBAbmFtZSBjaGFuZ2VzQnV0Tm90QnlcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gbW9kaWZpZXIgZnVuY3Rpb25cbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBvciBnZXR0ZXIgZnVuY3Rpb25cbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5IG5hbWUgX29wdGlvbmFsX1xuICAgKiBAcGFyYW0ge051bWJlcn0gY2hhbmdlIGFtb3VudCAoZGVsdGEpXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmNoYW5nZXNCdXROb3RCeSA9IGZ1bmN0aW9uIChmbiwgb2JqLCBwcm9wLCBkZWx0YSwgbXNnKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDQgJiYgdHlwZW9mIG9iaiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdmFyIHRtcE1zZyA9IGRlbHRhO1xuICAgICAgZGVsdGEgPSBwcm9wO1xuICAgICAgbXNnID0gdG1wTXNnO1xuICAgIH0gZWxzZSBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMykge1xuICAgICAgZGVsdGEgPSBwcm9wO1xuICAgICAgcHJvcCA9IG51bGw7XG4gICAgfVxuXG4gICAgbmV3IEFzc2VydGlvbihmbiwgbXNnLCBhc3NlcnQuY2hhbmdlc0J1dE5vdEJ5LCB0cnVlKVxuICAgICAgLnRvLmNoYW5nZShvYmosIHByb3ApLmJ1dC5ub3QuYnkoZGVsdGEpO1xuICB9XG5cbiAgLyoqXG4gICAqICMjIyAuaW5jcmVhc2VzKGZ1bmN0aW9uLCBvYmplY3QsIHByb3BlcnR5LCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBhIGZ1bmN0aW9uIGluY3JlYXNlcyBhIG51bWVyaWMgb2JqZWN0IHByb3BlcnR5LlxuICAgKlxuICAgKiAgICAgdmFyIG9iaiA9IHsgdmFsOiAxMCB9O1xuICAgKiAgICAgdmFyIGZuID0gZnVuY3Rpb24oKSB7IG9iai52YWwgPSAxMyB9O1xuICAgKiAgICAgYXNzZXJ0LmluY3JlYXNlcyhmbiwgb2JqLCAndmFsJyk7XG4gICAqXG4gICAqIEBuYW1lIGluY3JlYXNlc1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBtb2RpZmllciBmdW5jdGlvblxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IG9yIGdldHRlciBmdW5jdGlvblxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHkgbmFtZSBfb3B0aW9uYWxfXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmluY3JlYXNlcyA9IGZ1bmN0aW9uIChmbiwgb2JqLCBwcm9wLCBtc2cpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMyAmJiB0eXBlb2Ygb2JqID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBtc2cgPSBwcm9wO1xuICAgICAgcHJvcCA9IG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBBc3NlcnRpb24oZm4sIG1zZywgYXNzZXJ0LmluY3JlYXNlcywgdHJ1ZSlcbiAgICAgIC50by5pbmNyZWFzZShvYmosIHByb3ApO1xuICB9XG5cbiAgLyoqXG4gICAqICMjIyAuaW5jcmVhc2VzQnkoZnVuY3Rpb24sIG9iamVjdCwgcHJvcGVydHksIGRlbHRhLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBhIGZ1bmN0aW9uIGluY3JlYXNlcyBhIG51bWVyaWMgb2JqZWN0IHByb3BlcnR5IG9yIGEgZnVuY3Rpb24ncyByZXR1cm4gdmFsdWUgYnkgYW4gYW1vdW50IChkZWx0YSkuXG4gICAqXG4gICAqICAgICB2YXIgb2JqID0geyB2YWw6IDEwIH07XG4gICAqICAgICB2YXIgZm4gPSBmdW5jdGlvbigpIHsgb2JqLnZhbCArPSAxMCB9O1xuICAgKiAgICAgYXNzZXJ0LmluY3JlYXNlc0J5KGZuLCBvYmosICd2YWwnLCAxMCk7XG4gICAqXG4gICAqIEBuYW1lIGluY3JlYXNlc0J5XG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IG1vZGlmaWVyIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3Qgb3IgZ2V0dGVyIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eSBuYW1lIF9vcHRpb25hbF9cbiAgICogQHBhcmFtIHtOdW1iZXJ9IGNoYW5nZSBhbW91bnQgKGRlbHRhKVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pbmNyZWFzZXNCeSA9IGZ1bmN0aW9uIChmbiwgb2JqLCBwcm9wLCBkZWx0YSwgbXNnKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDQgJiYgdHlwZW9mIG9iaiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdmFyIHRtcE1zZyA9IGRlbHRhO1xuICAgICAgZGVsdGEgPSBwcm9wO1xuICAgICAgbXNnID0gdG1wTXNnO1xuICAgIH0gZWxzZSBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMykge1xuICAgICAgZGVsdGEgPSBwcm9wO1xuICAgICAgcHJvcCA9IG51bGw7XG4gICAgfVxuXG4gICAgbmV3IEFzc2VydGlvbihmbiwgbXNnLCBhc3NlcnQuaW5jcmVhc2VzQnksIHRydWUpXG4gICAgICAudG8uaW5jcmVhc2Uob2JqLCBwcm9wKS5ieShkZWx0YSk7XG4gIH1cblxuICAvKipcbiAgICogIyMjIC5kb2VzTm90SW5jcmVhc2UoZnVuY3Rpb24sIG9iamVjdCwgcHJvcGVydHksIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGEgZnVuY3Rpb24gZG9lcyBub3QgaW5jcmVhc2UgYSBudW1lcmljIG9iamVjdCBwcm9wZXJ0eS5cbiAgICpcbiAgICogICAgIHZhciBvYmogPSB7IHZhbDogMTAgfTtcbiAgICogICAgIHZhciBmbiA9IGZ1bmN0aW9uKCkgeyBvYmoudmFsID0gOCB9O1xuICAgKiAgICAgYXNzZXJ0LmRvZXNOb3RJbmNyZWFzZShmbiwgb2JqLCAndmFsJyk7XG4gICAqXG4gICAqIEBuYW1lIGRvZXNOb3RJbmNyZWFzZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBtb2RpZmllciBmdW5jdGlvblxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IG9yIGdldHRlciBmdW5jdGlvblxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHkgbmFtZSBfb3B0aW9uYWxfXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmRvZXNOb3RJbmNyZWFzZSA9IGZ1bmN0aW9uIChmbiwgb2JqLCBwcm9wLCBtc2cpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMyAmJiB0eXBlb2Ygb2JqID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBtc2cgPSBwcm9wO1xuICAgICAgcHJvcCA9IG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBBc3NlcnRpb24oZm4sIG1zZywgYXNzZXJ0LmRvZXNOb3RJbmNyZWFzZSwgdHJ1ZSlcbiAgICAgIC50by5ub3QuaW5jcmVhc2Uob2JqLCBwcm9wKTtcbiAgfVxuXG4gIC8qKlxuICAgKiAjIyMgLmluY3JlYXNlc0J1dE5vdEJ5KGZ1bmN0aW9uLCBvYmplY3QsIHByb3BlcnR5LCBkZWx0YSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYSBmdW5jdGlvbiBkb2VzIG5vdCBpbmNyZWFzZSBhIG51bWVyaWMgb2JqZWN0IHByb3BlcnR5IG9yIGZ1bmN0aW9uJ3MgcmV0dXJuIHZhbHVlIGJ5IGFuIGFtb3VudCAoZGVsdGEpLlxuICAgKlxuICAgKiAgICAgdmFyIG9iaiA9IHsgdmFsOiAxMCB9O1xuICAgKiAgICAgdmFyIGZuID0gZnVuY3Rpb24oKSB7IG9iai52YWwgPSAxNSB9O1xuICAgKiAgICAgYXNzZXJ0LmluY3JlYXNlc0J1dE5vdEJ5KGZuLCBvYmosICd2YWwnLCAxMCk7XG4gICAqXG4gICAqIEBuYW1lIGluY3JlYXNlc0J1dE5vdEJ5XG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IG1vZGlmaWVyIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3Qgb3IgZ2V0dGVyIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eSBuYW1lIF9vcHRpb25hbF9cbiAgICogQHBhcmFtIHtOdW1iZXJ9IGNoYW5nZSBhbW91bnQgKGRlbHRhKVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pbmNyZWFzZXNCdXROb3RCeSA9IGZ1bmN0aW9uIChmbiwgb2JqLCBwcm9wLCBkZWx0YSwgbXNnKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDQgJiYgdHlwZW9mIG9iaiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdmFyIHRtcE1zZyA9IGRlbHRhO1xuICAgICAgZGVsdGEgPSBwcm9wO1xuICAgICAgbXNnID0gdG1wTXNnO1xuICAgIH0gZWxzZSBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMykge1xuICAgICAgZGVsdGEgPSBwcm9wO1xuICAgICAgcHJvcCA9IG51bGw7XG4gICAgfVxuXG4gICAgbmV3IEFzc2VydGlvbihmbiwgbXNnLCBhc3NlcnQuaW5jcmVhc2VzQnV0Tm90QnksIHRydWUpXG4gICAgICAudG8uaW5jcmVhc2Uob2JqLCBwcm9wKS5idXQubm90LmJ5KGRlbHRhKTtcbiAgfVxuXG4gIC8qKlxuICAgKiAjIyMgLmRlY3JlYXNlcyhmdW5jdGlvbiwgb2JqZWN0LCBwcm9wZXJ0eSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYSBmdW5jdGlvbiBkZWNyZWFzZXMgYSBudW1lcmljIG9iamVjdCBwcm9wZXJ0eS5cbiAgICpcbiAgICogICAgIHZhciBvYmogPSB7IHZhbDogMTAgfTtcbiAgICogICAgIHZhciBmbiA9IGZ1bmN0aW9uKCkgeyBvYmoudmFsID0gNSB9O1xuICAgKiAgICAgYXNzZXJ0LmRlY3JlYXNlcyhmbiwgb2JqLCAndmFsJyk7XG4gICAqXG4gICAqIEBuYW1lIGRlY3JlYXNlc1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBtb2RpZmllciBmdW5jdGlvblxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IG9yIGdldHRlciBmdW5jdGlvblxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHkgbmFtZSBfb3B0aW9uYWxfXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmRlY3JlYXNlcyA9IGZ1bmN0aW9uIChmbiwgb2JqLCBwcm9wLCBtc2cpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMyAmJiB0eXBlb2Ygb2JqID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBtc2cgPSBwcm9wO1xuICAgICAgcHJvcCA9IG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBBc3NlcnRpb24oZm4sIG1zZywgYXNzZXJ0LmRlY3JlYXNlcywgdHJ1ZSlcbiAgICAgIC50by5kZWNyZWFzZShvYmosIHByb3ApO1xuICB9XG5cbiAgLyoqXG4gICAqICMjIyAuZGVjcmVhc2VzQnkoZnVuY3Rpb24sIG9iamVjdCwgcHJvcGVydHksIGRlbHRhLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBhIGZ1bmN0aW9uIGRlY3JlYXNlcyBhIG51bWVyaWMgb2JqZWN0IHByb3BlcnR5IG9yIGEgZnVuY3Rpb24ncyByZXR1cm4gdmFsdWUgYnkgYW4gYW1vdW50IChkZWx0YSlcbiAgICpcbiAgICogICAgIHZhciBvYmogPSB7IHZhbDogMTAgfTtcbiAgICogICAgIHZhciBmbiA9IGZ1bmN0aW9uKCkgeyBvYmoudmFsIC09IDUgfTtcbiAgICogICAgIGFzc2VydC5kZWNyZWFzZXNCeShmbiwgb2JqLCAndmFsJywgNSk7XG4gICAqXG4gICAqIEBuYW1lIGRlY3JlYXNlc0J5XG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IG1vZGlmaWVyIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3Qgb3IgZ2V0dGVyIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eSBuYW1lIF9vcHRpb25hbF9cbiAgICogQHBhcmFtIHtOdW1iZXJ9IGNoYW5nZSBhbW91bnQgKGRlbHRhKVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5kZWNyZWFzZXNCeSA9IGZ1bmN0aW9uIChmbiwgb2JqLCBwcm9wLCBkZWx0YSwgbXNnKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDQgJiYgdHlwZW9mIG9iaiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdmFyIHRtcE1zZyA9IGRlbHRhO1xuICAgICAgZGVsdGEgPSBwcm9wO1xuICAgICAgbXNnID0gdG1wTXNnO1xuICAgIH0gZWxzZSBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMykge1xuICAgICAgZGVsdGEgPSBwcm9wO1xuICAgICAgcHJvcCA9IG51bGw7XG4gICAgfVxuXG4gICAgbmV3IEFzc2VydGlvbihmbiwgbXNnLCBhc3NlcnQuZGVjcmVhc2VzQnksIHRydWUpXG4gICAgICAudG8uZGVjcmVhc2Uob2JqLCBwcm9wKS5ieShkZWx0YSk7XG4gIH1cblxuICAvKipcbiAgICogIyMjIC5kb2VzTm90RGVjcmVhc2UoZnVuY3Rpb24sIG9iamVjdCwgcHJvcGVydHksIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGEgZnVuY3Rpb24gZG9lcyBub3QgZGVjcmVhc2VzIGEgbnVtZXJpYyBvYmplY3QgcHJvcGVydHkuXG4gICAqXG4gICAqICAgICB2YXIgb2JqID0geyB2YWw6IDEwIH07XG4gICAqICAgICB2YXIgZm4gPSBmdW5jdGlvbigpIHsgb2JqLnZhbCA9IDE1IH07XG4gICAqICAgICBhc3NlcnQuZG9lc05vdERlY3JlYXNlKGZuLCBvYmosICd2YWwnKTtcbiAgICpcbiAgICogQG5hbWUgZG9lc05vdERlY3JlYXNlXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IG1vZGlmaWVyIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3Qgb3IgZ2V0dGVyIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eSBuYW1lIF9vcHRpb25hbF9cbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuZG9lc05vdERlY3JlYXNlID0gZnVuY3Rpb24gKGZuLCBvYmosIHByb3AsIG1zZykge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAzICYmIHR5cGVvZiBvYmogPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIG1zZyA9IHByb3A7XG4gICAgICBwcm9wID0gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IEFzc2VydGlvbihmbiwgbXNnLCBhc3NlcnQuZG9lc05vdERlY3JlYXNlLCB0cnVlKVxuICAgICAgLnRvLm5vdC5kZWNyZWFzZShvYmosIHByb3ApO1xuICB9XG5cbiAgLyoqXG4gICAqICMjIyAuZG9lc05vdERlY3JlYXNlQnkoZnVuY3Rpb24sIG9iamVjdCwgcHJvcGVydHksIGRlbHRhLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBhIGZ1bmN0aW9uIGRvZXMgbm90IGRlY3JlYXNlcyBhIG51bWVyaWMgb2JqZWN0IHByb3BlcnR5IG9yIGEgZnVuY3Rpb24ncyByZXR1cm4gdmFsdWUgYnkgYW4gYW1vdW50IChkZWx0YSlcbiAgICpcbiAgICogICAgIHZhciBvYmogPSB7IHZhbDogMTAgfTtcbiAgICogICAgIHZhciBmbiA9IGZ1bmN0aW9uKCkgeyBvYmoudmFsID0gNSB9O1xuICAgKiAgICAgYXNzZXJ0LmRvZXNOb3REZWNyZWFzZUJ5KGZuLCBvYmosICd2YWwnLCAxKTtcbiAgICpcbiAgICogQG5hbWUgZG9lc05vdERlY3JlYXNlQnlcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gbW9kaWZpZXIgZnVuY3Rpb25cbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBvciBnZXR0ZXIgZnVuY3Rpb25cbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5IG5hbWUgX29wdGlvbmFsX1xuICAgKiBAcGFyYW0ge051bWJlcn0gY2hhbmdlIGFtb3VudCAoZGVsdGEpXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmRvZXNOb3REZWNyZWFzZUJ5ID0gZnVuY3Rpb24gKGZuLCBvYmosIHByb3AsIGRlbHRhLCBtc2cpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gNCAmJiB0eXBlb2Ygb2JqID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB2YXIgdG1wTXNnID0gZGVsdGE7XG4gICAgICBkZWx0YSA9IHByb3A7XG4gICAgICBtc2cgPSB0bXBNc2c7XG4gICAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAzKSB7XG4gICAgICBkZWx0YSA9IHByb3A7XG4gICAgICBwcm9wID0gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IEFzc2VydGlvbihmbiwgbXNnLCBhc3NlcnQuZG9lc05vdERlY3JlYXNlQnksIHRydWUpXG4gICAgICAudG8ubm90LmRlY3JlYXNlKG9iaiwgcHJvcCkuYnkoZGVsdGEpO1xuICB9XG5cbiAgLyoqXG4gICAqICMjIyAuZGVjcmVhc2VzQnV0Tm90QnkoZnVuY3Rpb24sIG9iamVjdCwgcHJvcGVydHksIGRlbHRhLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBhIGZ1bmN0aW9uIGRvZXMgbm90IGRlY3JlYXNlcyBhIG51bWVyaWMgb2JqZWN0IHByb3BlcnR5IG9yIGEgZnVuY3Rpb24ncyByZXR1cm4gdmFsdWUgYnkgYW4gYW1vdW50IChkZWx0YSlcbiAgICpcbiAgICogICAgIHZhciBvYmogPSB7IHZhbDogMTAgfTtcbiAgICogICAgIHZhciBmbiA9IGZ1bmN0aW9uKCkgeyBvYmoudmFsID0gNSB9O1xuICAgKiAgICAgYXNzZXJ0LmRlY3JlYXNlc0J1dE5vdEJ5KGZuLCBvYmosICd2YWwnLCAxKTtcbiAgICpcbiAgICogQG5hbWUgZGVjcmVhc2VzQnV0Tm90QnlcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gbW9kaWZpZXIgZnVuY3Rpb25cbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBvciBnZXR0ZXIgZnVuY3Rpb25cbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5IG5hbWUgX29wdGlvbmFsX1xuICAgKiBAcGFyYW0ge051bWJlcn0gY2hhbmdlIGFtb3VudCAoZGVsdGEpXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmRlY3JlYXNlc0J1dE5vdEJ5ID0gZnVuY3Rpb24gKGZuLCBvYmosIHByb3AsIGRlbHRhLCBtc2cpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gNCAmJiB0eXBlb2Ygb2JqID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB2YXIgdG1wTXNnID0gZGVsdGE7XG4gICAgICBkZWx0YSA9IHByb3A7XG4gICAgICBtc2cgPSB0bXBNc2c7XG4gICAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAzKSB7XG4gICAgICBkZWx0YSA9IHByb3A7XG4gICAgICBwcm9wID0gbnVsbDtcbiAgICB9XG5cbiAgICBuZXcgQXNzZXJ0aW9uKGZuLCBtc2csIGFzc2VydC5kZWNyZWFzZXNCdXROb3RCeSwgdHJ1ZSlcbiAgICAgIC50by5kZWNyZWFzZShvYmosIHByb3ApLmJ1dC5ub3QuYnkoZGVsdGEpO1xuICB9XG5cbiAgLyohXG4gICAqICMjIyAuaWZFcnJvcihvYmplY3QpXG4gICAqXG4gICAqIEFzc2VydHMgaWYgdmFsdWUgaXMgbm90IGEgZmFsc2UgdmFsdWUsIGFuZCB0aHJvd3MgaWYgaXQgaXMgYSB0cnVlIHZhbHVlLlxuICAgKiBUaGlzIGlzIGFkZGVkIHRvIGFsbG93IGZvciBjaGFpIHRvIGJlIGEgZHJvcC1pbiByZXBsYWNlbWVudCBmb3IgTm9kZSdzXG4gICAqIGFzc2VydCBjbGFzcy5cbiAgICpcbiAgICogICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ0kgYW0gYSBjdXN0b20gZXJyb3InKTtcbiAgICogICAgIGFzc2VydC5pZkVycm9yKGVycik7IC8vIFJldGhyb3dzIGVyciFcbiAgICpcbiAgICogQG5hbWUgaWZFcnJvclxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pZkVycm9yID0gZnVuY3Rpb24gKHZhbCkge1xuICAgIGlmICh2YWwpIHtcbiAgICAgIHRocm93KHZhbCk7XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzRXh0ZW5zaWJsZShvYmplY3QpXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBpcyBleHRlbnNpYmxlIChjYW4gaGF2ZSBuZXcgcHJvcGVydGllcyBhZGRlZCB0byBpdCkuXG4gICAqXG4gICAqICAgICBhc3NlcnQuaXNFeHRlbnNpYmxlKHt9KTtcbiAgICpcbiAgICogQG5hbWUgaXNFeHRlbnNpYmxlXG4gICAqIEBhbGlhcyBleHRlbnNpYmxlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNFeHRlbnNpYmxlID0gZnVuY3Rpb24gKG9iaiwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZywgYXNzZXJ0LmlzRXh0ZW5zaWJsZSwgdHJ1ZSkudG8uYmUuZXh0ZW5zaWJsZTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc05vdEV4dGVuc2libGUob2JqZWN0KVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgaXMgX25vdF8gZXh0ZW5zaWJsZS5cbiAgICpcbiAgICogICAgIHZhciBub25FeHRlbnNpYmxlT2JqZWN0ID0gT2JqZWN0LnByZXZlbnRFeHRlbnNpb25zKHt9KTtcbiAgICogICAgIHZhciBzZWFsZWRPYmplY3QgPSBPYmplY3Quc2VhbCh7fSk7XG4gICAqICAgICB2YXIgZnJvemVuT2JqZWN0ID0gT2JqZWN0LmZyZWV6ZSh7fSk7XG4gICAqXG4gICAqICAgICBhc3NlcnQuaXNOb3RFeHRlbnNpYmxlKG5vbkV4dGVuc2libGVPYmplY3QpO1xuICAgKiAgICAgYXNzZXJ0LmlzTm90RXh0ZW5zaWJsZShzZWFsZWRPYmplY3QpO1xuICAgKiAgICAgYXNzZXJ0LmlzTm90RXh0ZW5zaWJsZShmcm96ZW5PYmplY3QpO1xuICAgKlxuICAgKiBAbmFtZSBpc05vdEV4dGVuc2libGVcbiAgICogQGFsaWFzIG5vdEV4dGVuc2libGVcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc05vdEV4dGVuc2libGUgPSBmdW5jdGlvbiAob2JqLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnLCBhc3NlcnQuaXNOb3RFeHRlbnNpYmxlLCB0cnVlKS50by5ub3QuYmUuZXh0ZW5zaWJsZTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc1NlYWxlZChvYmplY3QpXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBpcyBzZWFsZWQgKGNhbm5vdCBoYXZlIG5ldyBwcm9wZXJ0aWVzIGFkZGVkIHRvIGl0XG4gICAqIGFuZCBpdHMgZXhpc3RpbmcgcHJvcGVydGllcyBjYW5ub3QgYmUgcmVtb3ZlZCkuXG4gICAqXG4gICAqICAgICB2YXIgc2VhbGVkT2JqZWN0ID0gT2JqZWN0LnNlYWwoe30pO1xuICAgKiAgICAgdmFyIGZyb3plbk9iamVjdCA9IE9iamVjdC5zZWFsKHt9KTtcbiAgICpcbiAgICogICAgIGFzc2VydC5pc1NlYWxlZChzZWFsZWRPYmplY3QpO1xuICAgKiAgICAgYXNzZXJ0LmlzU2VhbGVkKGZyb3plbk9iamVjdCk7XG4gICAqXG4gICAqIEBuYW1lIGlzU2VhbGVkXG4gICAqIEBhbGlhcyBzZWFsZWRcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc1NlYWxlZCA9IGZ1bmN0aW9uIChvYmosIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2csIGFzc2VydC5pc1NlYWxlZCwgdHJ1ZSkudG8uYmUuc2VhbGVkO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzTm90U2VhbGVkKG9iamVjdClcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGlzIF9ub3RfIHNlYWxlZC5cbiAgICpcbiAgICogICAgIGFzc2VydC5pc05vdFNlYWxlZCh7fSk7XG4gICAqXG4gICAqIEBuYW1lIGlzTm90U2VhbGVkXG4gICAqIEBhbGlhcyBub3RTZWFsZWRcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc05vdFNlYWxlZCA9IGZ1bmN0aW9uIChvYmosIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2csIGFzc2VydC5pc05vdFNlYWxlZCwgdHJ1ZSkudG8ubm90LmJlLnNlYWxlZDtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc0Zyb3plbihvYmplY3QpXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBpcyBmcm96ZW4gKGNhbm5vdCBoYXZlIG5ldyBwcm9wZXJ0aWVzIGFkZGVkIHRvIGl0XG4gICAqIGFuZCBpdHMgZXhpc3RpbmcgcHJvcGVydGllcyBjYW5ub3QgYmUgbW9kaWZpZWQpLlxuICAgKlxuICAgKiAgICAgdmFyIGZyb3plbk9iamVjdCA9IE9iamVjdC5mcmVlemUoe30pO1xuICAgKiAgICAgYXNzZXJ0LmZyb3plbihmcm96ZW5PYmplY3QpO1xuICAgKlxuICAgKiBAbmFtZSBpc0Zyb3plblxuICAgKiBAYWxpYXMgZnJvemVuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNGcm96ZW4gPSBmdW5jdGlvbiAob2JqLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnLCBhc3NlcnQuaXNGcm96ZW4sIHRydWUpLnRvLmJlLmZyb3plbjtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc05vdEZyb3plbihvYmplY3QpXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBpcyBfbm90XyBmcm96ZW4uXG4gICAqXG4gICAqICAgICBhc3NlcnQuaXNOb3RGcm96ZW4oe30pO1xuICAgKlxuICAgKiBAbmFtZSBpc05vdEZyb3plblxuICAgKiBAYWxpYXMgbm90RnJvemVuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNOb3RGcm96ZW4gPSBmdW5jdGlvbiAob2JqLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnLCBhc3NlcnQuaXNOb3RGcm96ZW4sIHRydWUpLnRvLm5vdC5iZS5mcm96ZW47XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNFbXB0eSh0YXJnZXQpXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGRvZXMgbm90IGNvbnRhaW4gYW55IHZhbHVlcy5cbiAgICogRm9yIGFycmF5cyBhbmQgc3RyaW5ncywgaXQgY2hlY2tzIHRoZSBgbGVuZ3RoYCBwcm9wZXJ0eS5cbiAgICogRm9yIGBNYXBgIGFuZCBgU2V0YCBpbnN0YW5jZXMsIGl0IGNoZWNrcyB0aGUgYHNpemVgIHByb3BlcnR5LlxuICAgKiBGb3Igbm9uLWZ1bmN0aW9uIG9iamVjdHMsIGl0IGdldHMgdGhlIGNvdW50IG9mIG93blxuICAgKiBlbnVtZXJhYmxlIHN0cmluZyBrZXlzLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmlzRW1wdHkoW10pO1xuICAgKiAgICAgYXNzZXJ0LmlzRW1wdHkoJycpO1xuICAgKiAgICAgYXNzZXJ0LmlzRW1wdHkobmV3IE1hcCk7XG4gICAqICAgICBhc3NlcnQuaXNFbXB0eSh7fSk7XG4gICAqXG4gICAqIEBuYW1lIGlzRW1wdHlcbiAgICogQGFsaWFzIGVtcHR5XG4gICAqIEBwYXJhbSB7T2JqZWN0fEFycmF5fFN0cmluZ3xNYXB8U2V0fSB0YXJnZXRcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNFbXB0eSA9IGZ1bmN0aW9uKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZywgYXNzZXJ0LmlzRW1wdHksIHRydWUpLnRvLmJlLmVtcHR5O1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzTm90RW1wdHkodGFyZ2V0KVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBjb250YWlucyB2YWx1ZXMuXG4gICAqIEZvciBhcnJheXMgYW5kIHN0cmluZ3MsIGl0IGNoZWNrcyB0aGUgYGxlbmd0aGAgcHJvcGVydHkuXG4gICAqIEZvciBgTWFwYCBhbmQgYFNldGAgaW5zdGFuY2VzLCBpdCBjaGVja3MgdGhlIGBzaXplYCBwcm9wZXJ0eS5cbiAgICogRm9yIG5vbi1mdW5jdGlvbiBvYmplY3RzLCBpdCBnZXRzIHRoZSBjb3VudCBvZiBvd25cbiAgICogZW51bWVyYWJsZSBzdHJpbmcga2V5cy5cbiAgICpcbiAgICogICAgIGFzc2VydC5pc05vdEVtcHR5KFsxLCAyXSk7XG4gICAqICAgICBhc3NlcnQuaXNOb3RFbXB0eSgnMzQnKTtcbiAgICogICAgIGFzc2VydC5pc05vdEVtcHR5KG5ldyBTZXQoWzUsIDZdKSk7XG4gICAqICAgICBhc3NlcnQuaXNOb3RFbXB0eSh7IGtleTogNyB9KTtcbiAgICpcbiAgICogQG5hbWUgaXNOb3RFbXB0eVxuICAgKiBAYWxpYXMgbm90RW1wdHlcbiAgICogQHBhcmFtIHtPYmplY3R8QXJyYXl8U3RyaW5nfE1hcHxTZXR9IHRhcmdldFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc05vdEVtcHR5ID0gZnVuY3Rpb24odmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnLCBhc3NlcnQuaXNOb3RFbXB0eSwgdHJ1ZSkudG8ubm90LmJlLmVtcHR5O1xuICB9O1xuXG4gIC8qIVxuICAgKiBBbGlhc2VzLlxuICAgKi9cblxuICAoZnVuY3Rpb24gYWxpYXMobmFtZSwgYXMpe1xuICAgIGFzc2VydFthc10gPSBhc3NlcnRbbmFtZV07XG4gICAgcmV0dXJuIGFsaWFzO1xuICB9KVxuICAoJ2lzT2snLCAnb2snKVxuICAoJ2lzTm90T2snLCAnbm90T2snKVxuICAoJ3Rocm93cycsICd0aHJvdycpXG4gICgndGhyb3dzJywgJ1Rocm93JylcbiAgKCdpc0V4dGVuc2libGUnLCAnZXh0ZW5zaWJsZScpXG4gICgnaXNOb3RFeHRlbnNpYmxlJywgJ25vdEV4dGVuc2libGUnKVxuICAoJ2lzU2VhbGVkJywgJ3NlYWxlZCcpXG4gICgnaXNOb3RTZWFsZWQnLCAnbm90U2VhbGVkJylcbiAgKCdpc0Zyb3plbicsICdmcm96ZW4nKVxuICAoJ2lzTm90RnJvemVuJywgJ25vdEZyb3plbicpXG4gICgnaXNFbXB0eScsICdlbXB0eScpXG4gICgnaXNOb3RFbXB0eScsICdub3RFbXB0eScpO1xufTtcbiIsICIvKiFcbiAqIGNoYWlcbiAqIENvcHlyaWdodChjKSAyMDExLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG52YXIgdXNlZCA9IFtdO1xuXG4vKiFcbiAqIENoYWkgdmVyc2lvblxuICovXG5cbmV4cG9ydHMudmVyc2lvbiA9ICc0LjMuMyc7XG5cbi8qIVxuICogQXNzZXJ0aW9uIEVycm9yXG4gKi9cblxuZXhwb3J0cy5Bc3NlcnRpb25FcnJvciA9IHJlcXVpcmUoJ2Fzc2VydGlvbi1lcnJvcicpO1xuXG4vKiFcbiAqIFV0aWxzIGZvciBwbHVnaW5zIChub3QgZXhwb3J0ZWQpXG4gKi9cblxudmFyIHV0aWwgPSByZXF1aXJlKCcuL2NoYWkvdXRpbHMnKTtcblxuLyoqXG4gKiAjIC51c2UoZnVuY3Rpb24pXG4gKlxuICogUHJvdmlkZXMgYSB3YXkgdG8gZXh0ZW5kIHRoZSBpbnRlcm5hbHMgb2YgQ2hhaS5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufVxuICogQHJldHVybnMge3RoaXN9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLnVzZSA9IGZ1bmN0aW9uIChmbikge1xuICBpZiAoIX51c2VkLmluZGV4T2YoZm4pKSB7XG4gICAgZm4oZXhwb3J0cywgdXRpbCk7XG4gICAgdXNlZC5wdXNoKGZuKTtcbiAgfVxuXG4gIHJldHVybiBleHBvcnRzO1xufTtcblxuLyohXG4gKiBVdGlsaXR5IEZ1bmN0aW9uc1xuICovXG5cbmV4cG9ydHMudXRpbCA9IHV0aWw7XG5cbi8qIVxuICogQ29uZmlndXJhdGlvblxuICovXG5cbnZhciBjb25maWcgPSByZXF1aXJlKCcuL2NoYWkvY29uZmlnJyk7XG5leHBvcnRzLmNvbmZpZyA9IGNvbmZpZztcblxuLyohXG4gKiBQcmltYXJ5IGBBc3NlcnRpb25gIHByb3RvdHlwZVxuICovXG5cbnZhciBhc3NlcnRpb24gPSByZXF1aXJlKCcuL2NoYWkvYXNzZXJ0aW9uJyk7XG5leHBvcnRzLnVzZShhc3NlcnRpb24pO1xuXG4vKiFcbiAqIENvcmUgQXNzZXJ0aW9uc1xuICovXG5cbnZhciBjb3JlID0gcmVxdWlyZSgnLi9jaGFpL2NvcmUvYXNzZXJ0aW9ucycpO1xuZXhwb3J0cy51c2UoY29yZSk7XG5cbi8qIVxuICogRXhwZWN0IGludGVyZmFjZVxuICovXG5cbnZhciBleHBlY3QgPSByZXF1aXJlKCcuL2NoYWkvaW50ZXJmYWNlL2V4cGVjdCcpO1xuZXhwb3J0cy51c2UoZXhwZWN0KTtcblxuLyohXG4gKiBTaG91bGQgaW50ZXJmYWNlXG4gKi9cblxudmFyIHNob3VsZCA9IHJlcXVpcmUoJy4vY2hhaS9pbnRlcmZhY2Uvc2hvdWxkJyk7XG5leHBvcnRzLnVzZShzaG91bGQpO1xuXG4vKiFcbiAqIEFzc2VydCBpbnRlcmZhY2VcbiAqL1xuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnLi9jaGFpL2ludGVyZmFjZS9hc3NlcnQnKTtcbmV4cG9ydHMudXNlKGFzc2VydCk7XG4iLCAibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2xpYi9jaGFpJyk7XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgMjAyMyBzY2h1a2FpIEdtYkhcbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBR1BMLTMuMFxuICovXG5cbi8qKlxuICogUHJvcGVydHktS2V5c1xuICogQGF1dGhvciBzY2h1a2FpIEdtYkhcbiAqL1xuXG5leHBvcnQgeyBpbnRlcm5hbFN5bWJvbCwgaW50ZXJuYWxTdGF0ZVN5bWJvbCwgaW5zdGFuY2VTeW1ib2wgfTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHR5cGUge3N5bWJvbH1cbiAqIEBtZW1iZXJPZiBNb25zdGVyXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI0LjBcbiAqL1xuY29uc3QgaW50ZXJuYWxTeW1ib2wgPSBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci9pbnRlcm5hbFwiKTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHR5cGUge3N5bWJvbH1cbiAqIEBtZW1iZXJPZiBNb25zdGVyXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI1LjBcbiAqL1xuY29uc3QgaW50ZXJuYWxTdGF0ZVN5bWJvbCA9IFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL3N0YXRlXCIpO1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAdHlwZSB7c3ltYm9sfVxuICovXG5jb25zdCBpbnN0YW5jZVN5bWJvbCA9IFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL2luc3RhbmNlXCIpO1xuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgaW5zdGFuY2VTeW1ib2wgfSBmcm9tIFwiLi4vY29uc3RhbnRzLm1qc1wiO1xuXG5leHBvcnQgeyBCYXNlIH07XG5cbi8qKlxuICogVGhpcyBpcyB0aGUgYmFzZSBjbGFzcyBmcm9tIHdoaWNoIHRoZSBtb3N0IGNsYXNzZXMgYXJlIGRlcml2ZWQuXG4gKlxuICogVGhpcyBjbGFzcyBoYXMgYmVzaWRlcyBhIGB0b1N0cmluZ2Agd2hpY2ggcmV0dXJucyB0aGUganNvbiByZXByZXNlbnRhdGlvbiBvZiB0aGUgb2JqZWN0XG4gKiBhbHNvIGEgZnVuY3Rpb25hbGl0eSB0byBjaGVjayBpZiBhbiBvYmplY3QgaXMgYW4gaW5zdGFuY2Ugb2YgYSBjbGFzcy5cbiAqXG4gKiBUaGVyZWZvciB0aGUgY2xhc3MgaGFzIGEgc3RhdGljIG1ldGhvZCBgIFtTeW1ib2wuaGFzSW5zdGFuY2VdKHRoYXQpYCB3aGljaCByZXR1cm5zIHRydWUgaWYgdGhlIG9iamVjdFxuICogaXMgYW4gaW5zdGFuY2Ugb2YgdGhlIGNsYXNzLlxuICpcbiAqIEBzZWUgW2h0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL1N5bWJvbC9oYXNJbnN0YW5jZV0oZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL1N5bWJvbC9oYXNJbnN0YW5jZSlcbiAqXG4gKiBEZXJpdmVkIGNsYXNzZXMgc2hvdWxkIGltcGxlbWVudCBhIHN0YXRpYyBnZXR0ZXIgYGluc3RhbmNlU3ltYm9sYCB3aGljaCByZXR1cm5zIGEgdW5pcXVlIHN5bWJvbC5cbiAqXG4gKiBgYGBqYXZhc2NyaXB0XG4gKiBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gKiAgICByZXR1cm4gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvdHlwZXMvYmFzZVwiKTtcbiAqIH1cbiAqIGBgYFxuICpcbiAqIFRoZSBjbGFzcyB3YXMgZm9ybWVybHkgY2FsbGVkIE9iamVjdC5cbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjUuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKi9cbmNsYXNzIEJhc2UgZXh0ZW5kcyBPYmplY3Qge1xuICAgIC8qKlxuICAgICAqXG4gICAgICogQHJldHVybnMge3N0cmluZ31cbiAgICAgKi9cbiAgICB0b1N0cmluZygpIHtcbiAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHRoaXMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgYGluc3RhbmNlb2ZgIG9wZXJhdG9yLlxuICAgICAqIEByZXR1cm5zIHtzeW1ib2x9XG4gICAgICogQHNpbmNlIDIuMS4wXG4gICAgICovXG4gICAgc3RhdGljIGdldCBbaW5zdGFuY2VTeW1ib2xdKCkge1xuICAgICAgICByZXR1cm4gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvdHlwZXMvYmFzZVwiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGBpbnN0YW5jZW9mYCBvcGVyYXRvci5cbiAgICAgKiBAcGFyYW0gdGhhdFxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgICAqIEBzaW5jZSAyLjEuMFxuICAgICAqL1xuICAgIHN0YXRpYyBbU3ltYm9sLmhhc0luc3RhbmNlXSh0aGF0KSB7XG4gICAgICAgIGlmICh0aGF0ID09PSB1bmRlZmluZWQgfHwgdGhhdCA9PT0gbnVsbCB8fCAodHlwZW9mIHRoYXQgIT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHRoYXQgIT09IFwiZnVuY3Rpb25cIikpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHRoYXRDbGFzcyA9IE9iamVjdC5nZXRQcm90b3R5cGVPZih0aGF0KTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgdGhhdENsYXNzID09PSB1bmRlZmluZWQgfHxcbiAgICAgICAgICAgIHRoYXRDbGFzcyA9PT0gbnVsbCB8fFxuICAgICAgICAgICAgKHR5cGVvZiB0aGF0Q2xhc3MgIT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHRoYXRDbGFzcyAhPT0gXCJmdW5jdGlvblwiKVxuICAgICAgICApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjaGVja0luc3RhbmNlU3ltYm9sLmFwcGx5KHRoaXMsIFt0aGF0Q2xhc3NdKSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICAvLyB0aGlzIGNhbGwgdGhlIHN0YXRpYyBtZXRob2Qgb2YgdGhlIHN1cGVyIGNsYXNzLCBpZiB0aGVyZSBpcyBvbmVcbiAgICAgICAgcmV0dXJuIHN1cGVyW1N5bWJvbC5oYXNJbnN0YW5jZV0odGhhdCk7XG4gICAgfVxufVxuXG4vKipcbiAqIHRoaXMgZnVuY3Rpb24gY2hlY2tzIGlmIHRoZSBjbGFzcyBoYXMgYSBzdGF0aWMgZ2V0dGVyIGBpbnN0YW5jZVN5bWJvbGAgYW5kIGlmIHRoZSB2YWx1ZSBvZiB0aGlzIGdldHRlciBpcyBlcXVhbCB0byB0aGVcbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIG9ialxuICogQHJldHVybnMge2Jvb2xlYW58YW55fGJvb2xlYW59XG4gKiBAc2luY2UgMi4xLjBcbiAqL1xuZnVuY3Rpb24gY2hlY2tJbnN0YW5jZVN5bWJvbChvYmopIHtcbiAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eShpbnN0YW5jZVN5bWJvbCkgPT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBjb25zdCBwcm90byA9IG9iaj8uY29uc3RydWN0b3I7XG4gICAgaWYgKHByb3RvID09PSB1bmRlZmluZWQgfHwgcHJvdG8gPT09IG51bGwgfHwgKHR5cGVvZiBwcm90byAhPT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgcHJvdG8gIT09IFwiZnVuY3Rpb25cIikpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmIChwcm90by5oYXNPd25Qcm9wZXJ0eShpbnN0YW5jZVN5bWJvbCkgIT09IHRydWUpIHtcbiAgICAgICAgcmV0dXJuIGNoZWNrSW5zdGFuY2VTeW1ib2wuYXBwbHkodGhpcywgW29iai5fX3Byb3RvX19dKTtcbiAgICB9XG5cbiAgICBjb25zdCBzeW1ib2wgPSBwcm90b1tpbnN0YW5jZVN5bWJvbF07XG4gICAgaWYgKHN5bWJvbCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmIChvYmouX19wcm90b19fKSB7XG4gICAgICAgICAgICByZXR1cm4gY2hlY2tJbnN0YW5jZVN5bWJvbChvYmouX19wcm90b19fKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzeW1ib2wgPT09IHRoaXNbaW5zdGFuY2VTeW1ib2xdKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiBjaGVja0luc3RhbmNlU3ltYm9sLmFwcGx5KHRoaXMsIFtvYmouX19wcm90b19fXSk7XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5leHBvcnQgeyBpc0l0ZXJhYmxlLCBpc1ByaW1pdGl2ZSwgaXNTeW1ib2wsIGlzQm9vbGVhbiwgaXNTdHJpbmcsIGlzT2JqZWN0LCBpc0luc3RhbmNlLCBpc0FycmF5LCBpc0Z1bmN0aW9uLCBpc0ludGVnZXIgfTtcblxuLyoqXG4gKiBXaXRoIHRoaXMgZnVuY3Rpb24geW91IGNhbiBjaGVjayBpZiBhIHZhbHVlIGlzIGl0ZXJhYmxlLlxuICpcbiAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgaW4gdGhlIGxpYnJhcnkgdG8gaGF2ZSBjb25zaXN0ZW50IG5hbWVzLlxuICpcbiAqIFlvdSBjYW4gY2FsbCB0aGUgbWV0aG9kIHZpYSB0aGUgbW9uc3RlciBuYW1lc3BhY2UgYE1vbnN0ZXIuVHlwZXMuaXNQcmltaXRpdmUoKWAuXG4gKlxuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL3R5cGVzL2lzLTEubWpzXG4gKiBAcGFyYW0geyp9IHZhbHVlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMi4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcbiAqL1xuZnVuY3Rpb24gaXNJdGVyYWJsZSh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKHZhbHVlID09PSBudWxsKSByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuIHR5cGVvZiB2YWx1ZT8uW1N5bWJvbC5pdGVyYXRvcl0gPT09IFwiZnVuY3Rpb25cIjtcbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciB0aGUgdmFsdWUgcGFzc2VkIGlzIGEgcHJpbWl0aXZlIChzdHJpbmcsIG51bWJlciwgYm9vbGVhbiwgTmFOLCB1bmRlZmluZWQsIG51bGwgb3Igc3ltYm9sKVxuICpcbiAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgaW4gdGhlIGxpYnJhcnkgdG8gaGF2ZSBjb25zaXN0ZW50IG5hbWVzLlxuICpcbiAqIEBleHRlcm5hbEV4YW1wbGUgLi4vLi4vZXhhbXBsZS90eXBlcy9pcy0yLm1qc1xuICogQHBhcmFtIHsqfSB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjAuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKi9cbmZ1bmN0aW9uIGlzUHJpbWl0aXZlKHZhbHVlKSB7XG4gICAgdmFyIHR5cGU7XG5cbiAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCB8fCB2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICB0eXBlID0gdHlwZW9mIHZhbHVlO1xuXG4gICAgaWYgKHR5cGUgPT09IFwic3RyaW5nXCIgfHwgdHlwZSA9PT0gXCJudW1iZXJcIiB8fCB0eXBlID09PSBcImJvb2xlYW5cIiB8fCB0eXBlID09PSBcInN5bWJvbFwiKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciB0aGUgdmFsdWUgcGFzc2VkIGlzIGEgc3ltYm9sXG4gKlxuICogVGhpcyBtZXRob2QgaXMgdXNlZCBpbiB0aGUgbGlicmFyeSB0byBoYXZlIGNvbnNpc3RlbnQgbmFtZXMuXG4gKlxuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL3R5cGVzL2lzLTMubWpzXG4gKiBAcGFyYW0geyp9IHZhbHVlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuOS4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcbiAqL1xuZnVuY3Rpb24gaXNTeW1ib2wodmFsdWUpIHtcbiAgICByZXR1cm4gXCJzeW1ib2xcIiA9PT0gdHlwZW9mIHZhbHVlID8gdHJ1ZSA6IGZhbHNlO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIHRoZSB2YWx1ZSBwYXNzZWQgaXMgYSBib29sZWFuLlxuICpcbiAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgaW4gdGhlIGxpYnJhcnkgdG8gaGF2ZSBjb25zaXN0ZW50IG5hbWVzLlxuICpcbiAqIEBleHRlcm5hbEV4YW1wbGUgLi4vLi4vZXhhbXBsZS90eXBlcy9pcy00Lm1qc1xuICogQHBhcmFtIHsqfSB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjAuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKi9cbmZ1bmN0aW9uIGlzQm9vbGVhbih2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSA9PT0gdHJ1ZSB8fCB2YWx1ZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIHRoZSB2YWx1ZSBwYXNzZWQgaXMgYSBzdHJpbmdcbiAqXG4gKiBUaGlzIG1ldGhvZCBpcyB1c2VkIGluIHRoZSBsaWJyYXJ5IHRvIGhhdmUgY29uc2lzdGVudCBuYW1lcy5cbiAqXG4gKiBAZXh0ZXJuYWxFeGFtcGxlIC4uLy4uL2V4YW1wbGUvdHlwZXMvaXMtNS5tanNcbiAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4wLjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UeXBlc1xuICovXG5mdW5jdGlvbiBpc1N0cmluZyh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHR5cGVvZiB2YWx1ZSAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIHRoZSB2YWx1ZSBwYXNzZWQgaXMgYSBvYmplY3RcbiAqXG4gKiBUaGlzIG1ldGhvZCBpcyB1c2VkIGluIHRoZSBsaWJyYXJ5IHRvIGhhdmUgY29uc2lzdGVudCBuYW1lcy5cbiAqXG4gKiBAZXh0ZXJuYWxFeGFtcGxlIC4uLy4uL2V4YW1wbGUvdHlwZXMvaXMtNi5tanNcbiAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4wLjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UeXBlc1xuICovXG5mdW5jdGlvbiBpc09iamVjdCh2YWx1ZSkge1xuICAgIGlmIChpc0FycmF5KHZhbHVlKSkgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChpc1ByaW1pdGl2ZSh2YWx1ZSkpIHJldHVybiBmYWxzZTtcblxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIHRoZSB2YWx1ZSBwYXNzZWQgaXMgYSBvYmplY3QgYW5kIGluc3RhbmNlIG9mIGluc3RhbmNlLlxuICpcbiAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgaW4gdGhlIGxpYnJhcnkgdG8gaGF2ZSBjb25zaXN0ZW50IG5hbWVzLlxuICpcbiAqIEBleHRlcm5hbEV4YW1wbGUgLi4vLi4vZXhhbXBsZS90eXBlcy9pcy03Lm1qc1xuICogQHBhcmFtIHsqfSB2YWx1ZVxuICogQHBhcmFtIHsqfSBpbnN0YW5jZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjUuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKi9cbmZ1bmN0aW9uIGlzSW5zdGFuY2UodmFsdWUsIGluc3RhbmNlKSB7XG4gICAgaWYgKCFpc09iamVjdCh2YWx1ZSkpIHJldHVybiBmYWxzZTtcbiAgICBpZiAoIWlzRnVuY3Rpb24oaW5zdGFuY2UpKSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKCFpbnN0YW5jZS5oYXNPd25Qcm9wZXJ0eShcInByb3RvdHlwZVwiKSkgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIGluc3RhbmNlID8gdHJ1ZSA6IGZhbHNlO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIHRoZSB2YWx1ZSBwYXNzZWQgaXMgYSBhcnJheVxuICpcbiAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgaW4gdGhlIGxpYnJhcnkgdG8gaGF2ZSBjb25zaXN0ZW50IG5hbWVzLlxuICpcbiAqIEBleHRlcm5hbEV4YW1wbGUgLi4vLi4vZXhhbXBsZS90eXBlcy9pcy04Lm1qc1xuICogQHBhcmFtIHsqfSB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjAuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2RlL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0FycmF5L2lzQXJyYXlcbiAqL1xuZnVuY3Rpb24gaXNBcnJheSh2YWx1ZSkge1xuICAgIHJldHVybiBBcnJheS5pc0FycmF5KHZhbHVlKTtcbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciB0aGUgdmFsdWUgcGFzc2VkIGlzIGEgZnVuY3Rpb25cbiAqXG4gKiBUaGlzIG1ldGhvZCBpcyB1c2VkIGluIHRoZSBsaWJyYXJ5IHRvIGhhdmUgY29uc2lzdGVudCBuYW1lcy5cbiAqXG4gKiBAZXh0ZXJuYWxFeGFtcGxlIC4uLy4uL2V4YW1wbGUvdHlwZXMvaXMtOS5tanNcbiAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4wLjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UeXBlc1xuICovXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKHZhbHVlKSB7XG4gICAgaWYgKGlzQXJyYXkodmFsdWUpKSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKGlzUHJpbWl0aXZlKHZhbHVlKSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciB0aGUgdmFsdWUgcGFzc2VkIGlzIGFuIGludGVnZXIuXG4gKlxuICogVGhpcyBtZXRob2QgaXMgdXNlZCBpbiB0aGUgbGlicmFyeSB0byBoYXZlIGNvbnNpc3RlbnQgbmFtZXMuXG4gKlxuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL3R5cGVzL2lzLTEwLm1qc1xuICogQHBhcmFtIHsqfSB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjQuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKi9cbmZ1bmN0aW9uIGlzSW50ZWdlcih2YWx1ZSkge1xuICAgIHJldHVybiBOdW1iZXIuaXNJbnRlZ2VyKHZhbHVlKTtcbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7XG4gICAgaXNBcnJheSxcbiAgICBpc0Jvb2xlYW4sXG4gICAgaXNGdW5jdGlvbixcbiAgICBpc0luc3RhbmNlLFxuICAgIGlzSW50ZWdlcixcbiAgICBpc0l0ZXJhYmxlLFxuICAgIGlzT2JqZWN0LFxuICAgIGlzUHJpbWl0aXZlLFxuICAgIGlzU3RyaW5nLFxuICAgIGlzU3ltYm9sLFxufSBmcm9tIFwiLi9pcy5tanNcIjtcblxuZXhwb3J0IHtcbiAgICB2YWxpZGF0ZUl0ZXJhYmxlLFxuICAgIHZhbGlkYXRlUHJpbWl0aXZlLFxuICAgIHZhbGlkYXRlQm9vbGVhbixcbiAgICB2YWxpZGF0ZVN0cmluZyxcbiAgICB2YWxpZGF0ZU9iamVjdCxcbiAgICB2YWxpZGF0ZUluc3RhbmNlLFxuICAgIHZhbGlkYXRlQXJyYXksXG4gICAgdmFsaWRhdGVTeW1ib2wsXG4gICAgdmFsaWRhdGVGdW5jdGlvbixcbiAgICB2YWxpZGF0ZUludGVnZXIsXG59O1xuXG4vKipcbiAqIFRoaXMgbWV0aG9kIGNoZWNrcyBpZiB0aGUgdHlwZSBtYXRjaGVzIHRoZSBwcmltaXRpdmUgdHlwZS4gdGhpcyBmdW5jdGlvbiBpcyBpZGVudGljYWwgdG8gaXNQcmltaXRpdmUoKSBleGNlcHQgdGhhdCBhIFR5cGVFcnJvciBpcyB0aHJvd24uXG4gKlxuICogYGBgXG4gKiA8c2NyaXB0IHR5cGU9XCJtb2R1bGVcIj5cbiAqIGltcG9ydCB7dmFsaWRhdGVJdGVyYWJsZX0gZnJvbSAnQHNjaHVrYWkvbW9uc3Rlci9zb3VyY2UvdHlwZXMvdmFsaWRhdGUubWpzJztcbiAqIGNvbnNvbGUubG9nKHZhbGlkYXRlSXRlcmFibGUoJzInKSkgIC8vIFx1MjFBNiBUeXBlRXJyb3JcbiAqIGNvbnNvbGUubG9nKHZhbGlkYXRlSXRlcmFibGUoW10pKSAgLy8gXHUyMUE2IHZhbHVlXG4gKiA8L3NjcmlwdD5cbiAqIGBgYFxuICpcbiAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAqIEByZXR1cm4geyp9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjIuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIHByaW1pdGl2ZVxuICogQHNlZSB7QGxpbmsgaXNQcmltaXRpdmV9XG4gKiBAc2VlIHtAbGluayBNb25zdGVyLlR5cGVzLmlzUHJpbWl0aXZlfVxuICogQHNlZSB7QGxpbmsgTW9uc3Rlci5UeXBlcyNpc1ByaW1pdGl2ZX1cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVJdGVyYWJsZSh2YWx1ZSkge1xuICAgIGlmICghaXNJdGVyYWJsZSh2YWx1ZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInZhbHVlIGlzIG5vdCBpdGVyYWJsZVwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xufVxuXG4vKipcbiAqIFRoaXMgbWV0aG9kIGNoZWNrcyBpZiB0aGUgdHlwZSBtYXRjaGVzIHRoZSBwcmltaXRpdmUgdHlwZS4gdGhpcyBmdW5jdGlvbiBpcyBpZGVudGljYWwgdG8gaXNQcmltaXRpdmUoKSBleGNlcHQgdGhhdCBhIFR5cGVFcnJvciBpcyB0aHJvd24uXG4gKlxuICogYGBgXG4gKiA8c2NyaXB0IHR5cGU9XCJtb2R1bGVcIj5cbiAqIGltcG9ydCB7dmFsaWRhdGVQcmltaXRpdmV9IGZyb20gJ0BzY2h1a2FpL21vbnN0ZXIvc291cmNlL3R5cGVzL3ZhbGlkYXRlLm1qcyc7XG4gKiBjb25zb2xlLmxvZyh2YWxpZGF0ZVByaW1pdGl2ZSgnMicpKSAgLy8gXHUyMUE2IHZhbHVlXG4gKiBjb25zb2xlLmxvZyh2YWxpZGF0ZVByaW1pdGl2ZShbXSkpICAvLyBcdTIxQTYgVHlwZUVycm9yXG4gKiA8L3NjcmlwdD5cbiAqIGBgYFxuICpcbiAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAqIEByZXR1cm4geyp9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjAuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIHByaW1pdGl2ZVxuICogQHNlZSB7QGxpbmsgaXNQcmltaXRpdmV9XG4gKiBAc2VlIHtAbGluayBNb25zdGVyLlR5cGVzLmlzUHJpbWl0aXZlfVxuICogQHNlZSB7QGxpbmsgTW9uc3Rlci5UeXBlcyNpc1ByaW1pdGl2ZX1cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVQcmltaXRpdmUodmFsdWUpIHtcbiAgICBpZiAoIWlzUHJpbWl0aXZlKHZhbHVlKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwidmFsdWUgaXMgbm90IGEgcHJpbWl0aXZlXCIpO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWU7XG59XG5cbi8qKlxuICogVGhpcyBtZXRob2QgY2hlY2tzIGlmIHRoZSB0eXBlIG1hdGNoZXMgdGhlIGJvb2xlYW4gdHlwZS4gdGhpcyBmdW5jdGlvbiBpcyBpZGVudGljYWwgdG8gaXNCb29sZWFuKCkgZXhjZXB0IHRoYXQgYSBUeXBlRXJyb3IgaXMgdGhyb3duLlxuICpcbiAqIGBgYFxuICogPHNjcmlwdCB0eXBlPVwibW9kdWxlXCI+XG4gKiBpbXBvcnQge3ZhbGlkYXRlQm9vbGVhbn0gZnJvbSAnQHNjaHVrYWkvbW9uc3Rlci9zb3VyY2UvdHlwZXMvdmFsaWRhdGUubWpzJztcbiAqIGNvbnNvbGUubG9nKHZhbGlkYXRlQm9vbGVhbihmYWxzZSkpICAvLyBcdTIxQTYgdmFsdWVcbiAqIGNvbnNvbGUubG9nKHZhbGlkYXRlQm9vbGVhbignMicpKSAgLy8gXHUyMUE2IFR5cGVFcnJvclxuICogY29uc29sZS5sb2codmFsaWRhdGVCb29sZWFuKFtdKSkgIC8vIFx1MjFBNiBUeXBlRXJyb3JcbiAqIDwvc2NyaXB0PlxuICogYGBgXG4gKlxuICogQHBhcmFtIHsqfSB2YWx1ZVxuICogQHJldHVybiB7Kn1cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMC4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcblxuICogQHRocm93cyB7VHlwZUVycm9yfSAgdmFsdWUgaXMgbm90IHByaW1pdGl2ZVxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZUJvb2xlYW4odmFsdWUpIHtcbiAgICBpZiAoIWlzQm9vbGVhbih2YWx1ZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInZhbHVlIGlzIG5vdCBhIGJvb2xlYW5cIik7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZTtcbn1cblxuLyoqXG4gKiBUaGlzIG1ldGhvZCBjaGVja3MgaWYgdGhlIHR5cGUgbWF0Y2hlcyB0aGUgc3RyaW5nIHR5cGUuIHRoaXMgZnVuY3Rpb24gaXMgaWRlbnRpY2FsIHRvIGlzU3RyaW5nKCkgZXhjZXB0IHRoYXQgYSBUeXBlRXJyb3IgaXMgdGhyb3duLlxuICpcbiAqIGBgYFxuICogPHNjcmlwdCB0eXBlPVwibW9kdWxlXCI+XG4gKiBpbXBvcnQge3ZhbGlkYXRlU3RyaW5nfSBmcm9tICdAc2NodWthaS9tb25zdGVyL3NvdXJjZS90eXBlcy92YWxpZGF0ZS5tanMnO1xuICogY29uc29sZS5sb2codmFsaWRhdGVTdHJpbmcoJzInKSkgIC8vIFx1MjFBNiB2YWx1ZVxuICogY29uc29sZS5sb2codmFsaWRhdGVTdHJpbmcoW10pKSAgLy8gXHUyMUE2IFR5cGVFcnJvclxuICogPC9zY3JpcHQ+XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0geyp9IHZhbHVlXG4gKiBAcmV0dXJuIHsqfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4wLjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UeXBlc1xuICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYSBzdHJpbmdcbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVTdHJpbmcodmFsdWUpIHtcbiAgICBpZiAoIWlzU3RyaW5nKHZhbHVlKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwidmFsdWUgaXMgbm90IGEgc3RyaW5nXCIpO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWU7XG59XG5cbi8qKlxuICogVGhpcyBtZXRob2QgY2hlY2tzIGlmIHRoZSB0eXBlIG1hdGNoZXMgdGhlIG9iamVjdCB0eXBlLiB0aGlzIGZ1bmN0aW9uIGlzIGlkZW50aWNhbCB0byBpc09iamVjdCgpIGV4Y2VwdCB0aGF0IGEgVHlwZUVycm9yIGlzIHRocm93bi5cbiAqXG4gKiBgYGBcbiAqIDxzY3JpcHQgdHlwZT1cIm1vZHVsZVwiPlxuICogaW1wb3J0IHt2YWxpZGF0ZU9iamVjdH0gZnJvbSAnQHNjaHVrYWkvbW9uc3Rlci9zb3VyY2UvdHlwZXMvdmFsaWRhdGUubWpzJztcbiAqIGNvbnNvbGUubG9nKHZhbGlkYXRlT2JqZWN0KHt9KSkgIC8vIFx1MjFBNiB2YWx1ZVxuICogY29uc29sZS5sb2codmFsaWRhdGVPYmplY3QoJzInKSkgIC8vIFx1MjFBNiBUeXBlRXJyb3JcbiAqIGNvbnNvbGUubG9nKHZhbGlkYXRlT2JqZWN0KFtdKSkgIC8vIFx1MjFBNiBUeXBlRXJyb3JcbiAqIDwvc2NyaXB0PlxuICogYGBgXG4gKlxuICogQHBhcmFtIHsqfSB2YWx1ZVxuICogQHJldHVybiB7Kn1cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMC4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgb2JqZWN0XG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlT2JqZWN0KHZhbHVlKSB7XG4gICAgaWYgKCFpc09iamVjdCh2YWx1ZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInZhbHVlIGlzIG5vdCBhIG9iamVjdFwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xufVxuXG4vKipcbiAqIFRoaXMgbWV0aG9kIGNoZWNrcyBpZiB0aGUgdHlwZSBtYXRjaGVzIHRoZSBvYmplY3QgaW5zdGFuY2UuXG4gKlxuICogYGBgXG4gKiA8c2NyaXB0IHR5cGU9XCJtb2R1bGVcIj5cbiAqIGltcG9ydCB7dmFsaWRhdGVJbnN0YW5jZX0gZnJvbSAnQHNjaHVrYWkvbW9uc3Rlci9zb3VyY2UvdHlwZXMvdmFsaWRhdGUubWpzJztcbiAqIGNvbnNvbGUubG9nKHZhbGlkYXRlSW5zdGFuY2Uoe30sIE9iamVjdCkpIC8vIFx1MjFBNiB2YWx1ZVxuICogY29uc29sZS5sb2codmFsaWRhdGVJbnN0YW5jZSgnMicsIE9iamVjdCkpIC8vIFx1MjFBNiBUeXBlRXJyb3JcbiAqIGNvbnNvbGUubG9nKHZhbGlkYXRlSW5zdGFuY2UoW10sIE9iamVjdCkpIC8vIFx1MjFBNiBUeXBlRXJyb3JcbiAqIDwvc2NyaXB0PlxuICogYGBgXG4gKlxuICogQHBhcmFtIHsqfSB2YWx1ZVxuICogQHJldHVybiB7Kn1cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuNS4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGFuIGluc3RhbmNlIG9mXG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlSW5zdGFuY2UodmFsdWUsIGluc3RhbmNlKSB7XG4gICAgaWYgKCFpc0luc3RhbmNlKHZhbHVlLCBpbnN0YW5jZSkpIHtcbiAgICAgICAgbGV0IG4gPSBcIlwiO1xuICAgICAgICBpZiAoaXNPYmplY3QoaW5zdGFuY2UpIHx8IGlzRnVuY3Rpb24oaW5zdGFuY2UpKSB7XG4gICAgICAgICAgICBuID0gaW5zdGFuY2U/LltcIm5hbWVcIl07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobikge1xuICAgICAgICAgICAgbiA9IGAgJHtufWA7XG4gICAgICAgIH1cblxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGB2YWx1ZSBpcyBub3QgYW4gaW5zdGFuY2Ugb2Yke259YCk7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZTtcbn1cblxuLyoqXG4gKiBUaGlzIG1ldGhvZCBjaGVja3MgaWYgdGhlIHR5cGUgbWF0Y2hlcyB0aGUgYXJyYXkgdHlwZS4gdGhpcyBmdW5jdGlvbiBpcyBpZGVudGljYWwgdG8gaXNBcnJheSgpIGV4Y2VwdCB0aGF0IGEgVHlwZUVycm9yIGlzIHRocm93bi5cbiAqXG4gKiBgYGBcbiAqIDxzY3JpcHQgdHlwZT1cIm1vZHVsZVwiPlxuICogaW1wb3J0IHt2YWxpZGF0ZUFycmF5fSBmcm9tICdAc2NodWthaS9tb25zdGVyL3NvdXJjZS90eXBlcy92YWxpZGF0ZS5tanMnO1xuICogY29uc29sZS5sb2codmFsaWRhdGVBcnJheSgnMicpKSAgLy8gXHUyMUE2IFR5cGVFcnJvclxuICogY29uc29sZS5sb2codmFsaWRhdGVBcnJheShbXSkpICAvLyBcdTIxQTYgdmFsdWVcbiAqIDwvc2NyaXB0PlxuICogYGBgXG4gKlxuICogQHBhcmFtIHsqfSB2YWx1ZVxuICogQHJldHVybiB7Kn1cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMC4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGFuIGFycmF5XG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlQXJyYXkodmFsdWUpIHtcbiAgICBpZiAoIWlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJ2YWx1ZSBpcyBub3QgYW4gYXJyYXlcIik7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZTtcbn1cblxuLyoqXG4gKiBUaGlzIG1ldGhvZCBjaGVja3MgaWYgdGhlIHR5cGUgbWF0Y2hlcyB0aGUgc3ltYm9sIHR5cGUuIHRoaXMgZnVuY3Rpb24gaXMgaWRlbnRpY2FsIHRvIGlzU3ltYm9sKCkgZXhjZXB0IHRoYXQgYSBUeXBlRXJyb3IgaXMgdGhyb3duLlxuICpcbiAqIGBgYFxuICogPHNjcmlwdCB0eXBlPVwibW9kdWxlXCI+XG4gKiBpbXBvcnQge3ZhbGlkYXRlU3ltYm9sfSBmcm9tICdAc2NodWthaS9tb25zdGVyL3NvdXJjZS90eXBlcy92YWxpZGF0ZS5tanMnO1xuICogY29uc29sZS5sb2codmFsaWRhdGVTeW1ib2woJzInKSkgIC8vIFx1MjFBNiBUeXBlRXJyb3JcbiAqIGNvbnNvbGUubG9nKHZhbGlkYXRlU3ltYm9sKCkpICAvLyBcdTIxQTYgdmFsdWVcbiAqIDwvc2NyaXB0PlxuICogYGBgXG4gKlxuICogQHBhcmFtIHsqfSB2YWx1ZVxuICogQHJldHVybiB7Kn1cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuOS4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGFuIHN5bWJvbFxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZVN5bWJvbCh2YWx1ZSkge1xuICAgIGlmICghaXNTeW1ib2wodmFsdWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJ2YWx1ZSBpcyBub3QgYW4gc3ltYm9sXCIpO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWU7XG59XG5cbi8qKlxuICogVGhpcyBtZXRob2QgY2hlY2tzIGlmIHRoZSB0eXBlIG1hdGNoZXMgdGhlIGZ1bmN0aW9uIHR5cGUuIHRoaXMgZnVuY3Rpb24gaXMgaWRlbnRpY2FsIHRvIGlzRnVuY3Rpb24oKSBleGNlcHQgdGhhdCBhIFR5cGVFcnJvciBpcyB0aHJvd24uXG4gKlxuICogYGBgXG4gKiA8c2NyaXB0IHR5cGU9XCJtb2R1bGVcIj5cbiAqIGltcG9ydCB7dmFsaWRhdGVGdW5jdGlvbn0gZnJvbSAnQHNjaHVrYWkvbW9uc3Rlci9zb3VyY2UvdHlwZXMvdmFsaWRhdGUubWpzJztcbiAqIGNvbnNvbGUubG9nKHZhbGlkYXRlRnVuY3Rpb24oKCk9Pnt9KSkgLy8gXHUyMUE2IHZhbHVlXG4gKiBjb25zb2xlLmxvZyh2YWxpZGF0ZUZ1bmN0aW9uKCcyJykpICAvLyBcdTIxQTYgVHlwZUVycm9yXG4gKiBjb25zb2xlLmxvZyh2YWxpZGF0ZUZ1bmN0aW9uKFtdKSkgIC8vIFx1MjFBNiBUeXBlRXJyb3JcbiAqIDwvc2NyaXB0PlxuICogYGBgXG4gKlxuICogQHBhcmFtIHsqfSB2YWx1ZVxuICogQHJldHVybiB7Kn1cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMC4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgZnVuY3Rpb25cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVGdW5jdGlvbih2YWx1ZSkge1xuICAgIGlmICghaXNGdW5jdGlvbih2YWx1ZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInZhbHVlIGlzIG5vdCBhIGZ1bmN0aW9uXCIpO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWU7XG59XG5cbi8qKlxuICogVGhpcyBtZXRob2QgY2hlY2tzIGlmIHRoZSB0eXBlIGlzIGFuIGludGVnZXIuIHRoaXMgZnVuY3Rpb24gaXMgaWRlbnRpY2FsIHRvIGlzSW50ZWdlcigpIGV4Y2VwdCB0aGF0IGEgVHlwZUVycm9yIGlzIHRocm93bi5cbiAqXG4gKiBgYGBcbiAqIDxzY3JpcHQgdHlwZT1cIm1vZHVsZVwiPlxuICogaW1wb3J0IHt2YWxpZGF0ZUZ1bmN0aW9ufSBmcm9tICdAc2NodWthaS9tb25zdGVyL3NvdXJjZS90eXBlcy92YWxpZGF0ZS5tanMnO1xuICogY29uc29sZS5sb2codmFsaWRhdGVJbnRlZ2VyKHRydWUpKSAvLyBcdTIxQTYgVHlwZUVycm9yXG4gKiBjb25zb2xlLmxvZyh2YWxpZGF0ZUludGVnZXIoJzInKSkgIC8vIFx1MjFBNiBUeXBlRXJyb3JcbiAqIGNvbnNvbGUubG9nKHZhbGlkYXRlSW50ZWdlcigyKSkgIC8vIFx1MjFBNiB2YWx1ZVxuICogPC9zY3JpcHQ+XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0geyp9IHZhbHVlXG4gKiBAcmV0dXJuIHsqfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS40LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UeXBlc1xuICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYW4gaW50ZWdlclxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZUludGVnZXIodmFsdWUpIHtcbiAgICBpZiAoIWlzSW50ZWdlcih2YWx1ZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInZhbHVlIGlzIG5vdCBhbiBpbnRlZ2VyXCIpO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWU7XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyB2YWxpZGF0ZUZ1bmN0aW9uLCB2YWxpZGF0ZU9iamVjdCwgdmFsaWRhdGVTdHJpbmcgfSBmcm9tIFwiLi92YWxpZGF0ZS5tanNcIjtcblxuZXhwb3J0IHsgZ2V0R2xvYmFsLCBnZXRHbG9iYWxPYmplY3QsIGdldEdsb2JhbEZ1bmN0aW9uIH07XG5cbi8qKlxuICogQHR5cGUge29iamVjfVxuICogQHByaXZhdGVcbiAqL1xubGV0IGdsb2JhbFJlZmVyZW5jZTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHRocm93cyB7RXJyb3J9IHVuc3VwcG9ydGVkIGVudmlyb25tZW50LlxuICovXG4oZnVuY3Rpb24gKCkge1xuICAgIGlmICh0eXBlb2YgZ2xvYmFsVGhpcyA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICBnbG9iYWxSZWZlcmVuY2UgPSBnbG9iYWxUaGlzO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgIGdsb2JhbFJlZmVyZW5jZSA9IHNlbGY7XG4gICAgICAgIHJldHVybjtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgZ2xvYmFsUmVmZXJlbmNlID0gd2luZG93O1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KE9iamVjdC5wcm90b3R5cGUsIFwiX19tb25zdGVyX19cIiwge1xuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9LFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgfSk7XG5cbiAgICBpZiAodHlwZW9mIF9fbW9uc3Rlcl9fID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgIF9fbW9uc3Rlcl9fLmdsb2JhbFRoaXMgPSBfX21vbnN0ZXJfXztcbiAgICAgICAgZGVsZXRlIE9iamVjdC5wcm90b3R5cGUuX19tb25zdGVyX187XG5cbiAgICAgICAgZ2xvYmFsUmVmZXJlbmNlID0gZ2xvYmFsVGhpcztcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICAgIGdsb2JhbFJlZmVyZW5jZSA9IEZ1bmN0aW9uKFwicmV0dXJuIHRoaXNcIikoKTtcbiAgICB9IGNhdGNoIChlKSB7fVxuXG4gICAgdGhyb3cgbmV3IEVycm9yKFwidW5zdXBwb3J0ZWQgZW52aXJvbm1lbnQuXCIpO1xufSkoKTtcblxuLyoqXG4gKiBSZXR1cm4gZ2xvYmFsVGhpc1xuICpcbiAqIElmIGdsb2JhbFRoaXMgaXMgbm90IGF2YWlsYWJsZSwgaXQgd2lsbCBiZSBwb2x5ZmlsbGVkXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS42LjBcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKiBAcmV0dXJucyB7b2JqZWN9IGdsb2JhbFRoaXNcbiAqL1xuZnVuY3Rpb24gZ2V0R2xvYmFsKCkge1xuICAgIHJldHVybiBnbG9iYWxSZWZlcmVuY2U7XG59XG5cbi8qKlxuICogUmV0dXJuIGdsb2JhbCBvYmplY3Qgb3IgdGhyb3cgRXJyb3JcbiAqXG4gKiBZb3UgY2FuIGNhbGwgdGhlIG1ldGhvZCB2aWEgdGhlIG1vbnN0ZXIgbmFtZXNwYWNlIGBNb25zdGVyLlR5cGVzLmdldEdsb2JhbE9iamVjdCgpYC5cbiAqXG4gKiBgYGBcbiAqIDxzY3JpcHQgdHlwZT1cIm1vZHVsZVwiPlxuICogaW1wb3J0IHtNb25zdGVyfSBmcm9tICdAc2NodWthaS9tb25zdGVyL3NvdXJjZS9tb25zdGVyLm1qcyc7XG4gKiBNb25zdGVyLlR5cGVzLmdldEdsb2JhbE9iamVjdCgnZG9jdW1lbnQnKVxuICogLy8gXHUyMUE2IHsgfVxuICogPC9zY3JpcHQ+XG4gKiBgYGBcbiAqXG4gKiBBbHRlcm5hdGl2ZWx5LCB5b3UgY2FuIGFsc28gaW50ZWdyYXRlIHRoaXMgZnVuY3Rpb24gaW5kaXZpZHVhbGx5LlxuICpcbiAqIGBgYFxuICogPHNjcmlwdCB0eXBlPVwibW9kdWxlXCI+XG4gKiBpbXBvcnQge2dldEdsb2JhbE9iamVjdH0gZnJvbSAnaHR0cHM6Ly9jZG4uanNkZWxpdnIubmV0L25wbS9Ac2NodWthaS9tb25zdGVyQDEuMzAuMC9kaXN0L21vZHVsZXMvdHlwZXMvZ2xvYmFsLm1qcyc7XG4gKiBnZXRHbG9iYWxPYmplY3QoJ2RvY3VtZW50JylcbiAqIC8vIFx1MjFBNiB7IH1cbiAqIDwvc2NyaXB0PlxuICogYGBgXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS42LjBcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuICogQHJldHVybnMge29iamVjfVxuICogQHRocm93cyB7RXJyb3J9IHRoZSBvYmplY3QgaXMgbm90IGRlZmluZWRcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgb2JqZWN0XG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIHN0cmluZ1xuICovXG5mdW5jdGlvbiBnZXRHbG9iYWxPYmplY3QobmFtZSkge1xuICAgIHZhbGlkYXRlU3RyaW5nKG5hbWUpO1xuICAgIGxldCBvID0gZ2xvYmFsUmVmZXJlbmNlPy5bbmFtZV07XG4gICAgaWYgKHR5cGVvZiBvID09PSBcInVuZGVmaW5lZFwiKSB0aHJvdyBuZXcgRXJyb3IoYHRoZSBvYmplY3QgJHtuYW1lfSBpcyBub3QgZGVmaW5lZGApO1xuICAgIHZhbGlkYXRlT2JqZWN0KG8pO1xuICAgIHJldHVybiBvO1xufVxuXG4vKipcbiAqIFJldHVybiBnbG9iYWwgZnVuY3Rpb24gb3IgdGhyb3cgRXJyb3JcbiAqXG4gKiBZb3UgY2FuIGNhbGwgdGhlIG1ldGhvZCB2aWEgdGhlIG1vbnN0ZXIgbmFtZXNwYWNlIGBNb25zdGVyLlR5cGVzLmdldEdsb2JhbEZ1bmN0aW9uKClgLlxuICpcbiAqIGBgYFxuICogPHNjcmlwdCB0eXBlPVwibW9kdWxlXCI+XG4gKiBpbXBvcnQge01vbnN0ZXJ9IGZyb20gJ0BzY2h1a2FpL21vbnN0ZXIvc291cmNlL21vbnN0ZXIubWpzJztcbiAqIGNvbnNvbGUubG9nKE1vbnN0ZXIuVHlwZXMuZ2V0R2xvYmFsRnVuY3Rpb24oJ3BhcnNlSW50JykpIC8vIFx1MjFBNiBmIHBhcnNlSW50KCkgeyB9XG4gKiA8L3NjcmlwdD5cbiAqIGBgYFxuICpcbiAqIEFsdGVybmF0aXZlbHksIHlvdSBjYW4gYWxzbyBpbnRlZ3JhdGUgdGhpcyBmdW5jdGlvbiBpbmRpdmlkdWFsbHkuXG4gKlxuICogYGBgXG4gKiA8c2NyaXB0IHR5cGU9XCJtb2R1bGVcIj5cbiAqIGltcG9ydCB7Z2V0R2xvYmFsRnVuY3Rpb259IGZyb20gJ2h0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9ucG0vQHNjaHVrYWkvbW9uc3RlckAxLjMwLjAvZGlzdC9tb2R1bGVzL3R5cGVzL2dsb2JhbC5tanMnO1xuICogY29uc29sZS5sb2coZ2V0R2xvYmFsRnVuY3Rpb24oJ3BhcnNlSW50JykpIC8vIFx1MjFBNiBmIHBhcnNlSW50KCkgeyB9XG4gKiA8L3NjcmlwdD5cbiAqIGBgYFxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuNi4wXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UeXBlc1xuICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAqIEByZXR1cm4ge29iamVjfVxuICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYSBmdW5jdGlvblxuICogQHRocm93cyB7RXJyb3J9IHRoZSBmdW5jdGlvbiBpcyBub3QgZGVmaW5lZFxuICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYSBzdHJpbmdcbiAqL1xuZnVuY3Rpb24gZ2V0R2xvYmFsRnVuY3Rpb24obmFtZSkge1xuICAgIHZhbGlkYXRlU3RyaW5nKG5hbWUpO1xuICAgIGxldCBmID0gZ2xvYmFsUmVmZXJlbmNlPy5bbmFtZV07XG4gICAgaWYgKHR5cGVvZiBmID09PSBcInVuZGVmaW5lZFwiKSB0aHJvdyBuZXcgRXJyb3IoYHRoZSBmdW5jdGlvbiAke25hbWV9IGlzIG5vdCBkZWZpbmVkYCk7XG4gICAgdmFsaWRhdGVGdW5jdGlvbihmKTtcbiAgICByZXR1cm4gZjtcbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmV4cG9ydCB7IHR5cGVPZiB9O1xuXG4vKipcbiAqIFRoZSBidWlsdC1pbiB0eXBlb2YgbWV0aG9kIGlzIGtub3duIHRvIGhhdmUgc29tZSBoaXN0b3JpY2FsIHdlYWtuZXNzZXMuIFRoaXMgZnVuY3Rpb24gdHJpZXMgdG8gcHJvdmlkZSBhIGJldHRlciBhbmQgbW9yZSBhY2N1cmF0ZSByZXN1bHQuXG4gKlxuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL3R5cGVzL3R5cGVvZi5tanNcbiAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAqIEByZXR1cm4ge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuNy4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgcHJpbWl0aXZlXG4gKi9cbmZ1bmN0aW9uIHR5cGVPZih2YWx1ZSkge1xuICAgIGxldCB0eXBlID0ge30udG9TdHJpbmcuY2FsbCh2YWx1ZSkubWF0Y2goL1xccyhbYS16QS1aXSspLylbMV07XG4gICAgaWYgKFwiT2JqZWN0XCIgPT09IHR5cGUpIHtcbiAgICAgICAgY29uc3QgbmFtZSA9IHZhbHVlLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgIGlmIChuYW1lKSB7XG4gICAgICAgICAgICByZXR1cm4gbmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVzdWx0cyA9IC9eKGNsYXNzfGZ1bmN0aW9uKVxccysoXFx3KykvLmV4ZWModmFsdWUuY29uc3RydWN0b3IudG9TdHJpbmcoKSk7XG4gICAgICAgIHR5cGUgPSByZXN1bHRzICYmIHJlc3VsdHMubGVuZ3RoID4gMiA/IHJlc3VsdHNbMl0gOiBcIlwiO1xuICAgIH1cblxuICAgIHJldHVybiB0eXBlLnRvTG93ZXJDYXNlKCk7XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBpc0FycmF5LCBpc09iamVjdCB9IGZyb20gXCIuLi90eXBlcy9pcy5tanNcIjtcbmltcG9ydCB7IHR5cGVPZiB9IGZyb20gXCIuLi90eXBlcy90eXBlb2YubWpzXCI7XG5cbmV4cG9ydCB7IGV4dGVuZCB9O1xuXG4vKipcbiAqIEV4dGVuZCBjb3BpZXMgYWxsIGVudW1lcmFibGUgb3duIHByb3BlcnRpZXMgZnJvbSBvbmUgb3JcbiAqIG1vcmUgc291cmNlIG9iamVjdHMgdG8gYSB0YXJnZXQgb2JqZWN0LiBJdCByZXR1cm5zIHRoZSBtb2RpZmllZCB0YXJnZXQgb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSB0YXJnZXRcbiAqIEBwYXJhbSB7b2JqZWN0fVxuICogQHJldHVybiB7b2JqZWN0fVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4xMC4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRGF0YVxuICogQHRocm93cyB7RXJyb3J9IHVuc3VwcG9ydGVkIGFyZ3VtZW50XG4gKiBAdGhyb3dzIHtFcnJvcn0gdHlwZSBtaXNtYXRjaFxuICogQHRocm93cyB7RXJyb3J9IHVuc3VwcG9ydGVkIGFyZ3VtZW50XG4gKi9cbmZ1bmN0aW9uIGV4dGVuZCguLi5hcmdzKSB7XG4gICAgbGV0IG87XG4gICAgbGV0IGk7XG5cbiAgICBpZiAodHlwZW9mIGFyZ3MgIT09IFwib2JqZWN0XCIgfHwgYXJnc1swXSA9PT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuc3VwcG9ydGVkIGFyZ3VtZW50ICR7SlNPTi5zdHJpbmdpZnkoYXJnc1swXSl9YCk7XG4gICAgfVxuXG4gICAgZm9yIChpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgbGV0IGEgPSBhcmdzW2ldO1xuXG4gICAgICAgIGlmICghKGlzT2JqZWN0KGEpIHx8IGlzQXJyYXkoYSkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuc3VwcG9ydGVkIGFyZ3VtZW50ICR7SlNPTi5zdHJpbmdpZnkoYSl9YCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBvID0gYTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChsZXQgayBpbiBhKSB7XG4gICAgICAgICAgICBsZXQgdiA9IGE/LltrXTtcblxuICAgICAgICAgICAgaWYgKHYgPT09IG8/LltrXSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoKGlzT2JqZWN0KHYpICYmIHR5cGVPZih2KSA9PT0gXCJvYmplY3RcIikgfHwgaXNBcnJheSh2KSkge1xuICAgICAgICAgICAgICAgIGlmIChvW2tdID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzQXJyYXkodikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9ba10gPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9ba10gPSB7fTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlT2Yob1trXSkgIT09IHR5cGVPZih2KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGB0eXBlIG1pc21hdGNoOiAke0pTT04uc3RyaW5naWZ5KG9ba10pfSgke3R5cGVPZihvW2tdKX0pICE9ICR7SlNPTi5zdHJpbmdpZnkodil9KCR7dHlwZU9mKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICl9KWAsXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgb1trXSA9IGV4dGVuZChvW2tdLCB2KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgb1trXSA9IHY7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbztcbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGdldEdsb2JhbCB9IGZyb20gXCIuLi90eXBlcy9nbG9iYWwubWpzXCI7XG5pbXBvcnQgeyBpc0FycmF5LCBpc0Z1bmN0aW9uLCBpc09iamVjdCwgaXNQcmltaXRpdmUgfSBmcm9tIFwiLi4vdHlwZXMvaXMubWpzXCI7XG5pbXBvcnQgeyB0eXBlT2YgfSBmcm9tIFwiLi4vdHlwZXMvdHlwZW9mLm1qc1wiO1xuaW1wb3J0IHsgdmFsaWRhdGVPYmplY3QgfSBmcm9tIFwiLi4vdHlwZXMvdmFsaWRhdGUubWpzXCI7XG5cbmV4cG9ydCB7IGNsb25lIH07XG5cbi8qKlxuICogV2l0aCB0aGlzIGZ1bmN0aW9uLCBvYmplY3RzIGNhbiBiZSBjbG9uZWQuXG4gKiBUaGUgZW50aXJlIG9iamVjdCB0cmVlIGlzIHJ1biB0aHJvdWdoLlxuICpcbiAqIFByb3h5LCBFbGVtZW50LCBIVE1MRG9jdW1lbnQgYW5kIERvY3VtZW50RnJhZ21lbnQgaW5zdGFuY2VzIGFyZSBub3QgY2xvbmVkLlxuICogR2xvYmFsIG9iamVjdHMgc3VjaCBhcyB3aW5kb3dzIGFyZSBhbHNvIG5vdCBjbG9uZWQsXG4gKlxuICogSWYgYW4gb2JqZWN0IGhhcyBhIG1ldGhvZCBgZ2V0Q2xvbmUoKWAsIHRoaXMgbWV0aG9kIGlzIHVzZWQgdG8gY3JlYXRlIHRoZSBjbG9uZS5cbiAqXG4gKiBAcGFyYW0geyp9IG9iaiBvYmplY3QgdG8gYmUgY2xvbmVkXG4gKiBAcmV0dXJucyB7Kn1cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMC4wXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5VdGlsXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQHRocm93cyB7RXJyb3J9IHVuYWJsZSB0byBjbG9uZSBvYmohIGl0cyB0eXBlIGlzbid0IHN1cHBvcnRlZC5cbiAqL1xuZnVuY3Rpb24gY2xvbmUob2JqKSB7XG4gICAgLy8gdHlwZW9mIG51bGwgcmVzdWx0cyBpbiAnb2JqZWN0Jy4gIGh0dHBzOi8vMmFsaXR5LmNvbS8yMDEzLzEwL3R5cGVvZi1udWxsLmh0bWxcbiAgICBpZiAobnVsbCA9PT0gb2JqKSB7XG4gICAgICAgIHJldHVybiBvYmo7XG4gICAgfVxuXG4gICAgLy8gSGFuZGxlIHRoZSB0d28gc2ltcGxlIHR5cGVzLCBudWxsIGFuZCB1bmRlZmluZWRcbiAgICBpZiAoaXNQcmltaXRpdmUob2JqKSkge1xuICAgICAgICByZXR1cm4gb2JqO1xuICAgIH1cblxuICAgIC8vIEhhbmRsZSB0aGUgdHdvIHNpbXBsZSB0eXBlcywgbnVsbCBhbmQgdW5kZWZpbmVkXG4gICAgaWYgKGlzRnVuY3Rpb24ob2JqKSkge1xuICAgICAgICByZXR1cm4gb2JqO1xuICAgIH1cblxuICAgIC8vIEhhbmRsZSBBcnJheVxuICAgIGlmIChpc0FycmF5KG9iaikpIHtcbiAgICAgICAgbGV0IGNvcHkgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IG9iai5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgY29weVtpXSA9IGNsb25lKG9ialtpXSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gY29weTtcbiAgICB9XG5cbiAgICBpZiAoaXNPYmplY3Qob2JqKSkge1xuICAgICAgICAvLyBIYW5kbGUgRGF0ZVxuICAgICAgICBpZiAob2JqIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgICAgICAgbGV0IGNvcHkgPSBuZXcgRGF0ZSgpO1xuICAgICAgICAgICAgY29weS5zZXRUaW1lKG9iai5nZXRUaW1lKCkpO1xuICAgICAgICAgICAgcmV0dXJuIGNvcHk7XG4gICAgICAgIH1cblxuICAgICAgICAvKiogRG8gbm90IGNsb25lIERPTSBub2RlcyAqL1xuICAgICAgICBpZiAodHlwZW9mIEVsZW1lbnQgIT09IFwidW5kZWZpbmVkXCIgJiYgb2JqIGluc3RhbmNlb2YgRWxlbWVudCkgcmV0dXJuIG9iajtcbiAgICAgICAgaWYgKHR5cGVvZiBIVE1MRG9jdW1lbnQgIT09IFwidW5kZWZpbmVkXCIgJiYgb2JqIGluc3RhbmNlb2YgSFRNTERvY3VtZW50KSByZXR1cm4gb2JqO1xuICAgICAgICBpZiAodHlwZW9mIERvY3VtZW50RnJhZ21lbnQgIT09IFwidW5kZWZpbmVkXCIgJiYgb2JqIGluc3RhbmNlb2YgRG9jdW1lbnRGcmFnbWVudCkgcmV0dXJuIG9iajtcblxuICAgICAgICAvKiogRG8gbm90IGNsb25lIGdsb2JhbCBvYmplY3RzICovXG4gICAgICAgIGlmIChvYmogPT09IGdldEdsb2JhbCgpKSByZXR1cm4gb2JqO1xuICAgICAgICBpZiAodHlwZW9mIGdsb2JhbENvbnRleHQgIT09IFwidW5kZWZpbmVkXCIgJiYgb2JqID09PSBnbG9iYWxDb250ZXh0KSByZXR1cm4gb2JqO1xuICAgICAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiAmJiBvYmogPT09IHdpbmRvdykgcmV0dXJuIG9iajtcbiAgICAgICAgaWYgKHR5cGVvZiBkb2N1bWVudCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBvYmogPT09IGRvY3VtZW50KSByZXR1cm4gb2JqO1xuICAgICAgICBpZiAodHlwZW9mIG5hdmlnYXRvciAhPT0gXCJ1bmRlZmluZWRcIiAmJiBvYmogPT09IG5hdmlnYXRvcikgcmV0dXJuIG9iajtcbiAgICAgICAgaWYgKHR5cGVvZiBKU09OICE9PSBcInVuZGVmaW5lZFwiICYmIG9iaiA9PT0gSlNPTikgcmV0dXJuIG9iajtcblxuICAgICAgICAvLyBIYW5kbGUgUHJveHktT2JqZWN0XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyB0cnkvY2F0Y2ggYmVjYXVzZSBwb3NzaWJsZTogVHlwZUVycm9yOiBGdW5jdGlvbiBoYXMgbm9uLW9iamVjdCBwcm90b3R5cGUgJ3VuZGVmaW5lZCcgaW4gaW5zdGFuY2VvZiBjaGVja1xuICAgICAgICAgICAgaWYgKG9iaiBpbnN0YW5jZW9mIFByb3h5KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9iajtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZSkge31cblxuICAgICAgICByZXR1cm4gY2xvbmVPYmplY3Qob2JqKTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1bmFibGUgdG8gY2xvbmUgb2JqISBpdHMgdHlwZSBpc24ndCBzdXBwb3J0ZWQuXCIpO1xufVxuXG4vKipcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gb2JqXG4gKiBAcmV0dXJucyB7b2JqZWN0fVxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gY2xvbmVPYmplY3Qob2JqKSB7XG4gICAgdmFsaWRhdGVPYmplY3Qob2JqKTtcblxuICAgIGNvbnN0IGZrdCA9IG9iaj8uW1wiY29uc3RydWN0b3JcIl07XG5cbiAgICAvKiogT2JqZWN0IGhhcyBjbG9uZSBtZXRob2QgKi9cbiAgICBpZiAodHlwZU9mKGZrdCkgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICBjb25zdCBwcm90b3R5cGUgPSBma3Q/LnByb3RvdHlwZTtcbiAgICAgICAgaWYgKHR5cGVvZiBwcm90b3R5cGUgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICAgIGlmIChwcm90b3R5cGUuaGFzT3duUHJvcGVydHkoXCJnZXRDbG9uZVwiKSAmJiB0eXBlT2Yob2JqLmdldENsb25lKSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9iai5nZXRDbG9uZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgbGV0IGNvcHkgPSB7fTtcbiAgICBpZiAodHlwZW9mIG9iai5jb25zdHJ1Y3RvciA9PT0gXCJmdW5jdGlvblwiICYmIHR5cGVvZiBvYmouY29uc3RydWN0b3IuY2FsbCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGNvcHkgPSBuZXcgb2JqLmNvbnN0cnVjdG9yKCk7XG4gICAgfVxuXG4gICAgZm9yIChsZXQga2V5IGluIG9iaikge1xuICAgICAgICBpZiAoIW9iai5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc1ByaW1pdGl2ZShvYmpba2V5XSkpIHtcbiAgICAgICAgICAgIGNvcHlba2V5XSA9IG9ialtrZXldO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBjb3B5W2tleV0gPSBjbG9uZShvYmpba2V5XSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvcHk7XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBpbnN0YW5jZVN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQgeyBCYXNlIH0gZnJvbSBcIi4uL3R5cGVzL2Jhc2UubWpzXCI7XG5pbXBvcnQgeyB2YWxpZGF0ZVN0cmluZyB9IGZyb20gXCIuLi90eXBlcy92YWxpZGF0ZS5tanNcIjtcbmltcG9ydCB7IGNsb25lIH0gZnJvbSBcIi4uL3V0aWwvY2xvbmUubWpzXCI7XG5cbmV4cG9ydCB7IExvY2FsZSwgcGFyc2VMb2NhbGUgfTtcblxuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5JMThuXG4gKiBAdHlwZSB7c3ltYm9sfVxuICovXG5jb25zdCBwcm9wZXJ0aWVzU3ltYm9sID0gU3ltYm9sKFwicHJvcGVydGllc1wiKTtcblxuLyoqXG4gKiBAdHlwZSB7c3ltYm9sfVxuICogQG1lbWJlck9mIE1vbnN0ZXIuSTE4blxuICovXG5jb25zdCBsb2NhbGVTdHJpbmdTeW1ib2wgPSBTeW1ib2woXCJsb2NhbGVTdHJpbmdcIik7XG5cbi8qKlxuICogVGhlIExvY2FsZSBjbGFzcyBpcyBhIGJhc2UgY2xhc3MgZm9yIHRoZSBsYW5ndWFnZSBjbGFzc2VzLlxuICpcbiAqIFJGQ1xuICpcbiAqIGBgYFxuICogQSBMYW5ndWFnZS1UYWcgY29uc2lzdHMgb2Y6XG4gKiBsYW5ndGFnICAgICAgICAgICAgICAgICAgICAgICAgICAgOyBnZW5lcmF0ZWQgdGFnXG4gKiAgICAgICAgICAgLW9yLSBwcml2YXRlLXVzZSAgICAgICAgOyBhIHByaXZhdGUgdXNlIHRhZ1xuICpcbiAqIGxhbmd0YWcgICAgICAgPSAobGFuZ3VhZ2VcbiAqICAgICAgICAgICAgICAgICAgICBbXCItXCIgc2NyaXB0XVxuICogICAgICAgICAgICAgICAgICAgIFtcIi1cIiByZWdpb25dXG4gKiAgICAgICAgICAgICAgICAgICAgKihcIi1cIiB2YXJpYW50KVxuICogICAgICAgICAgICAgICAgICAgICooXCItXCIgZXh0ZW5zaW9uKVxuICogICAgICAgICAgICAgICAgICAgIFtcIi1cIiBwcml2YXRldXNlXSlcbiAqXG4gKiBsYW5ndWFnZSAgICAgID0gXCJlblwiLCBcImFsZVwiLCBvciBhIHJlZ2lzdGVyZWQgdmFsdWVcbiAqXG4gKiBzY3JpcHQgICAgICAgID0gXCJMYXRuXCIsIFwiQ3lybFwiLCBcIkhhbnRcIiBJU08gMTU5MjQgY29kZXNcbiAqXG4gKiByZWdpb24gICAgICAgID0gXCJVU1wiLCBcIkNTXCIsIFwiRlJcIiBJU08gMzE2NiBjb2Rlc1xuICogICAgICAgICAgICAgICAgIFwiNDE5XCIsIFwiMDE5XCIsICBvciBVTiBNLjQ5IGNvZGVzXG4gKlxuICogdmFyaWFudCAgICAgICA9IFwicm96YWpcIiwgXCJuZWRpc1wiLCBcIjE5OTZcIiwgbXVsdGlwbGUgc3VidGFncyBjYW4gYmUgdXNlZCBpbiBhIHRhZ1xuICpcbiAqIGV4dGVuc2lvbiAgICAgPSBzaW5nbGUgbGV0dGVyIGZvbGxvd2VkIGJ5IGFkZGl0aW9uYWwgc3VidGFnczsgbW9yZSB0aGFuIG9uZSBleHRlbnNpb25cbiAqICAgICAgICAgICAgICAgICBtYXkgYmUgdXNlZCBpbiBhIGxhbmd1YWdlIHRhZ1xuICpcbiAqIHByaXZhdGUtdXNlICAgPSBcIngtXCIgZm9sbG93ZWQgYnkgYWRkaXRpb25hbCBzdWJ0YWdzLCBhcyBtYW55IGFzIGFyZSByZXF1aXJlZFxuICogICAgICAgICAgICAgICAgIE5vdGUgdGhhdCB0aGVzZSBjYW4gc3RhcnQgYSB0YWcgb3IgYXBwZWFyIGF0IHRoZSBlbmQgKGJ1dCBub3RcbiAqICAgICAgICAgICAgICAgICBpbiB0aGUgbWlkZGxlKVxuICogYGBgXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4xMy4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuSTE4blxuICogQHNlZSBodHRwczovL2RhdGF0cmFja2VyLmlldGYub3JnL2RvYy9odG1sL3JmYzMwNjZcbiAqL1xuY2xhc3MgTG9jYWxlIGV4dGVuZHMgQmFzZSB7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGxhbmd1YWdlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtyZWdpb25dXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzY3JpcHRdXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFt2YXJpYW50c11cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW2V4dGxhbmddXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtwcml2YXRlVXNlXVxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSB1bnN1cHBvcnRlZCBsb2NhbGVcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihsYW5ndWFnZSwgcmVnaW9uLCBzY3JpcHQsIHZhcmlhbnRzLCBleHRsYW5nLCBwcml2YXRlVXNlKSB7XG4gICAgICAgIHN1cGVyKCk7XG5cbiAgICAgICAgdGhpc1twcm9wZXJ0aWVzU3ltYm9sXSA9IHtcbiAgICAgICAgICAgIGxhbmd1YWdlOiBsYW5ndWFnZSA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogdmFsaWRhdGVTdHJpbmcobGFuZ3VhZ2UpLFxuICAgICAgICAgICAgc2NyaXB0OiBzY3JpcHQgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IHZhbGlkYXRlU3RyaW5nKHNjcmlwdCksXG4gICAgICAgICAgICByZWdpb246IHJlZ2lvbiA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogdmFsaWRhdGVTdHJpbmcocmVnaW9uKSxcbiAgICAgICAgICAgIHZhcmlhbnRzOiB2YXJpYW50cyA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogdmFsaWRhdGVTdHJpbmcodmFyaWFudHMpLFxuICAgICAgICAgICAgZXh0bGFuZzogZXh0bGFuZyA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogdmFsaWRhdGVTdHJpbmcoZXh0bGFuZyksXG4gICAgICAgICAgICBwcml2YXRlVXNlOiBwcml2YXRlVXNlID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiB2YWxpZGF0ZVN0cmluZyhwcml2YXRlVXNlKSxcbiAgICAgICAgfTtcblxuICAgICAgICBsZXQgcyA9IFtdO1xuICAgICAgICBpZiAobGFuZ3VhZ2UgIT09IHVuZGVmaW5lZCkgcy5wdXNoKGxhbmd1YWdlKTtcbiAgICAgICAgaWYgKHNjcmlwdCAhPT0gdW5kZWZpbmVkKSBzLnB1c2goc2NyaXB0KTtcbiAgICAgICAgaWYgKHJlZ2lvbiAhPT0gdW5kZWZpbmVkKSBzLnB1c2gocmVnaW9uKTtcbiAgICAgICAgaWYgKHZhcmlhbnRzICE9PSB1bmRlZmluZWQpIHMucHVzaCh2YXJpYW50cyk7XG4gICAgICAgIGlmIChleHRsYW5nICE9PSB1bmRlZmluZWQpIHMucHVzaChleHRsYW5nKTtcbiAgICAgICAgaWYgKHByaXZhdGVVc2UgIT09IHVuZGVmaW5lZCkgcy5wdXNoKHByaXZhdGVVc2UpO1xuXG4gICAgICAgIGlmIChzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidW5zdXBwb3J0ZWQgbG9jYWxlXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpc1tsb2NhbGVTdHJpbmdTeW1ib2xdID0gcy5qb2luKFwiLVwiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGBpbnN0YW5jZW9mYCBvcGVyYXRvci5cbiAgICAgKiBAcmV0dXJucyB7c3ltYm9sfVxuICAgICAqIEBzaW5jZSAzLjI3LjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci9pMThuL2xvY2FsZUBAaW5zdGFuY2VcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7c3RyaW5nfVxuICAgICAqL1xuICAgIGdldCBsb2NhbGVTdHJpbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzW2xvY2FsZVN0cmluZ1N5bWJvbF07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7c3RyaW5nfHVuZGVmaW5lZH1cbiAgICAgKi9cbiAgICBnZXQgbGFuZ3VhZ2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzW3Byb3BlcnRpZXNTeW1ib2xdLmxhbmd1YWdlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge3N0cmluZ3x1bmRlZmluZWR9XG4gICAgICovXG4gICAgZ2V0IHJlZ2lvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbcHJvcGVydGllc1N5bWJvbF0ucmVnaW9uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge3N0cmluZ3x1bmRlZmluZWR9XG4gICAgICovXG4gICAgZ2V0IHNjcmlwdCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbcHJvcGVydGllc1N5bWJvbF0uc2NyaXB0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge3N0cmluZ3x1bmRlZmluZWR9XG4gICAgICovXG4gICAgZ2V0IHZhcmlhbnRzKCkge1xuICAgICAgICByZXR1cm4gdGhpc1twcm9wZXJ0aWVzU3ltYm9sXS52YXJpYW50cztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtzdHJpbmd8dW5kZWZpbmVkfVxuICAgICAqL1xuICAgIGdldCBleHRsYW5nKCkge1xuICAgICAgICByZXR1cm4gdGhpc1twcm9wZXJ0aWVzU3ltYm9sXS5leHRsYW5nO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge3N0cmluZ3x1bmRlZmluZWR9XG4gICAgICovXG4gICAgZ2V0IHByaXZhdGVVc2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzW3Byb3BlcnRpZXNTeW1ib2xdLnByaXZhdGVWYWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAgICovXG4gICAgdG9TdHJpbmcoKSB7XG4gICAgICAgIHJldHVybiBgJHt0aGlzLmxvY2FsZVN0cmluZ31gO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBzdHJ1Y3R1cmUgaGFzIHRoZSBmb2xsb3dpbmc6IGxhbmd1YWdlLCBzY3JpcHQsIHJlZ2lvbiwgdmFyaWFudHMsIGV4dGxhbmcsIHByaXZhdGVVc2VcbiAgICAgKlxuICAgICAqIEByZXR1cm4ge01vbnN0ZXIuSTE4bi5Mb2NhbGVNYXB9XG4gICAgICovXG4gICAgZ2V0TWFwKCkge1xuICAgICAgICByZXR1cm4gY2xvbmUodGhpc1twcm9wZXJ0aWVzU3ltYm9sXSk7XG4gICAgfVxufVxuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IExvY2FsZU1hcFxuICogQHByb3BlcnR5IHtzdHJpbmd9IGxhbmd1YWdlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gc2NyaXB0XG4gKiBAcHJvcGVydHkge3N0cmluZ30gcmVnaW9uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gdmFyaWFudHNcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBleHRsYW5nXG4gKiBAcHJvcGVydHkge3N0cmluZ30gcHJpdmF0ZVVzZVxuICogQG1lbWJlck9mIE1vbnN0ZXIuSTE4blxuICovXG5cbi8qKlxuICogUGFyc2UgbG9jYWwgYWNjb3JkaW5nIHRvIHJmYzQ2NDYgc3RhbmRhcmRcbiAqXG4gKiBMaW1pdGF0aW9uczogVGhlIHJlZ2V4IGNhbm5vdCBoYW5kbGUgbXVsdGlwbGUgdmFyaWFudHMgb3IgcHJpdmF0ZS5cbiAqXG4gKiBZb3UgY2FuIGNhbGwgdGhlIG1ldGhvZCB2aWEgdGhpcyBmdW5jdGlvbiBpbmRpdmlkdWFsbHk6XG4gKlxuICogYGBgamF2YXNjcmlwdFxuICogaW1wb3J0IHtjcmVhdGVMb2NhbGV9IGZyb20gJ0BzY2h1a2FpL21vbnN0ZXIvc291cmNlL2kxOG4vbG9jYWxlLm1qcyc7XG4gKiBjcmVhdGVMb2NhbGUoKVxuICogYGBgXG4gKlxuICogUkZDXG4gKlxuICogYGBgXG4gKiAgIFRoZSBzeW50YXggb2YgdGhlIGxhbmd1YWdlIHRhZyBpbiBBQk5GIFtSRkM0MjM0XSBpczpcbiAqXG4gKiAgIExhbmd1YWdlLVRhZyAgPSBsYW5ndGFnXG4gKiAgICAgICAgICAgICAgICAgLyBwcml2YXRldXNlICAgICAgICAgICAgIDsgcHJpdmF0ZSB1c2UgdGFnXG4gKiAgICAgICAgICAgICAgICAgLyBncmFuZGZhdGhlcmVkICAgICAgICAgIDsgZ3JhbmRmYXRoZXJlZCByZWdpc3RyYXRpb25zXG4gKlxuICogICBsYW5ndGFnICAgICAgID0gKGxhbmd1YWdlXG4gKiAgICAgICAgICAgICAgICAgICAgW1wiLVwiIHNjcmlwdF1cbiAqICAgICAgICAgICAgICAgICAgICBbXCItXCIgcmVnaW9uXVxuICogICAgICAgICAgICAgICAgICAgICooXCItXCIgdmFyaWFudClcbiAqICAgICAgICAgICAgICAgICAgICAqKFwiLVwiIGV4dGVuc2lvbilcbiAqICAgICAgICAgICAgICAgICAgICBbXCItXCIgcHJpdmF0ZXVzZV0pXG4gKlxuICogICBsYW5ndWFnZSAgICAgID0gKDIqM0FMUEhBIFsgZXh0bGFuZyBdKSA7IHNob3J0ZXN0IElTTyA2MzkgY29kZVxuICogICAgICAgICAgICAgICAgIC8gNEFMUEhBICAgICAgICAgICAgICAgICA7IHJlc2VydmVkIGZvciBmdXR1cmUgdXNlXG4gKiAgICAgICAgICAgICAgICAgLyA1KjhBTFBIQSAgICAgICAgICAgICAgIDsgcmVnaXN0ZXJlZCBsYW5ndWFnZSBzdWJ0YWdcbiAqXG4gKiAgIGV4dGxhbmcgICAgICAgPSAqMyhcIi1cIiAzQUxQSEEpICAgICAgICAgOyByZXNlcnZlZCBmb3IgZnV0dXJlIHVzZVxuICpcbiAqICAgc2NyaXB0ICAgICAgICA9IDRBTFBIQSAgICAgICAgICAgICAgICAgOyBJU08gMTU5MjQgY29kZVxuICpcbiAqICAgcmVnaW9uICAgICAgICA9IDJBTFBIQSAgICAgICAgICAgICAgICAgOyBJU08gMzE2NiBjb2RlXG4gKiAgICAgICAgICAgICAgICAgLyAzRElHSVQgICAgICAgICAgICAgICAgIDsgVU4gTS40OSBjb2RlXG4gKlxuICogICB2YXJpYW50ICAgICAgID0gNSo4YWxwaGFudW0gICAgICAgICAgICA7IHJlZ2lzdGVyZWQgdmFyaWFudHNcbiAqICAgICAgICAgICAgICAgICAvIChESUdJVCAzYWxwaGFudW0pXG4gKlxuICogICBleHRlbnNpb24gICAgID0gc2luZ2xldG9uIDEqKFwiLVwiICgyKjhhbHBoYW51bSkpXG4gKlxuICogICBzaW5nbGV0b24gICAgID0gJXg0MS01NyAvICV4NTktNUEgLyAleDYxLTc3IC8gJXg3OS03QSAvIERJR0lUXG4gKiAgICAgICAgICAgICAgICAgOyBcImFcIi1cIndcIiAvIFwieVwiLVwielwiIC8gXCJBXCItXCJXXCIgLyBcIllcIi1cIlpcIiAvIFwiMFwiLVwiOVwiXG4gKiAgICAgICAgICAgICAgICAgOyBTaW5nbGUgbGV0dGVyczogeC9YIGlzIHJlc2VydmVkIGZvciBwcml2YXRlIHVzZVxuICpcbiAqICAgcHJpdmF0ZXVzZSAgICA9IChcInhcIi9cIlhcIikgMSooXCItXCIgKDEqOGFscGhhbnVtKSlcbiAqXG4gKiAgIGdyYW5kZmF0aGVyZWQgPSAxKjNBTFBIQSAxKjIoXCItXCIgKDIqOGFscGhhbnVtKSlcbiAqICAgICAgICAgICAgICAgICAgIDsgZ3JhbmRmYXRoZXJlZCByZWdpc3RyYXRpb25cbiAqICAgICAgICAgICAgICAgICAgIDsgTm90ZTogaSBpcyB0aGUgb25seSBzaW5nbGV0b25cbiAqICAgICAgICAgICAgICAgICAgIDsgdGhhdCBzdGFydHMgYSBncmFuZGZhdGhlcmVkIHRhZ1xuICpcbiAqICAgYWxwaGFudW0gICAgICA9IChBTFBIQSAvIERJR0lUKSAgICAgICA7IGxldHRlcnMgYW5kIG51bWJlcnNcbiAqXG4gKiAgICAgICAgICAgICAgICAgICAgICAgIEZpZ3VyZSAxOiBMYW5ndWFnZSBUYWcgQUJORlxuICogYGBgXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGxvY2FsZVxuICogQHJldHVybnMge0xvY2FsZX1cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMTQuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkkxOG5cbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgc3RyaW5nXG4gKiBAdGhyb3dzIHtFcnJvcn0gdW5zdXBwb3J0ZWQgbG9jYWxlXG4gKi9cbmZ1bmN0aW9uIHBhcnNlTG9jYWxlKGxvY2FsZSkge1xuICAgIGxvY2FsZSA9IHZhbGlkYXRlU3RyaW5nKGxvY2FsZSkucmVwbGFjZSgvXy9nLCBcIi1cIik7XG5cbiAgICBsZXQgbGFuZ3VhZ2U7XG4gICAgbGV0IHJlZ2lvbjtcbiAgICBsZXQgdmFyaWFudHM7XG4gICAgbGV0IHBhcnRzO1xuICAgIGxldCBzY3JpcHQ7XG4gICAgbGV0IGV4dGxhbmc7XG4gICAgbGV0IHJlZ2V4UmVndWxhciA9IFwiKGFydC1sb2piYW58Y2VsLWdhdWxpc2h8bm8tYm9rfG5vLW55bnx6aC1ndW95dXx6aC1oYWtrYXx6aC1taW58emgtbWluLW5hbnx6aC14aWFuZylcIjtcbiAgICBsZXQgcmVnZXhJcnJlZ3VsYXIgPVxuICAgICAgICBcIihlbi1HQi1vZWR8aS1hbWl8aS1ibm58aS1kZWZhdWx0fGktZW5vY2hpYW58aS1oYWt8aS1rbGluZ29ufGktbHV4fGktbWluZ298aS1uYXZham98aS1wd258aS10YW98aS10YXl8aS10c3V8c2duLUJFLUZSfHNnbi1CRS1OTHxzZ24tQ0gtREUpXCI7XG4gICAgbGV0IHJlZ2V4R3JhbmRmYXRoZXJlZCA9IGAoJHtyZWdleElycmVndWxhcn18JHtyZWdleFJlZ3VsYXJ9KWA7XG4gICAgbGV0IHJlZ2V4UHJpdmF0ZVVzZSA9IFwiKHgoLVtBLVphLXowLTldezEsOH0pKylcIjtcbiAgICBsZXQgcmVnZXhTaW5nbGV0b24gPSBcIlswLTlBLVdZLVphLXd5LXpdXCI7XG4gICAgbGV0IHJlZ2V4RXh0ZW5zaW9uID0gYCgke3JlZ2V4U2luZ2xldG9ufSgtW0EtWmEtejAtOV17Miw4fSkrKWA7XG4gICAgbGV0IHJlZ2V4VmFyaWFudCA9IFwiKFtBLVphLXowLTldezUsOH18WzAtOV1bQS1aYS16MC05XXszfSlcIjtcbiAgICBsZXQgcmVnZXhSZWdpb24gPSBcIihbQS1aYS16XXsyfXxbMC05XXszfSlcIjtcbiAgICBsZXQgcmVnZXhTY3JpcHQgPSBcIihbQS1aYS16XXs0fSlcIjtcbiAgICBsZXQgcmVnZXhFeHRsYW5nID0gXCIoW0EtWmEtel17M30oLVtBLVphLXpdezN9KXswLDJ9KVwiO1xuICAgIGxldCByZWdleExhbmd1YWdlID0gYCgoW0EtWmEtel17MiwzfSgtJHtyZWdleEV4dGxhbmd9KT8pfFtBLVphLXpdezR9fFtBLVphLXpdezUsOH0pYDtcbiAgICBsZXQgcmVnZXhMYW5ndGFnID0gYCgke3JlZ2V4TGFuZ3VhZ2V9KC0ke3JlZ2V4U2NyaXB0fSk/KC0ke3JlZ2V4UmVnaW9ufSk/KC0ke3JlZ2V4VmFyaWFudH0pKigtJHtyZWdleEV4dGVuc2lvbn0pKigtJHtyZWdleFByaXZhdGVVc2V9KT8pYDtcbiAgICBsZXQgcmVnZXhMYW5ndWFnZVRhZyA9IGBeKCR7cmVnZXhHcmFuZGZhdGhlcmVkfXwke3JlZ2V4TGFuZ3RhZ318JHtyZWdleFByaXZhdGVVc2V9KSRgO1xuICAgIGxldCByZWdleCA9IG5ldyBSZWdFeHAocmVnZXhMYW5ndWFnZVRhZyk7XG4gICAgbGV0IG1hdGNoO1xuXG4gICAgaWYgKChtYXRjaCA9IHJlZ2V4LmV4ZWMobG9jYWxlKSkgIT09IG51bGwpIHtcbiAgICAgICAgaWYgKG1hdGNoLmluZGV4ID09PSByZWdleC5sYXN0SW5kZXgpIHtcbiAgICAgICAgICAgIHJlZ2V4Lmxhc3RJbmRleCsrO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG1hdGNoID09PSB1bmRlZmluZWQgfHwgbWF0Y2ggPT09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidW5zdXBwb3J0ZWQgbG9jYWxlXCIpO1xuICAgIH1cblxuICAgIGlmIChtYXRjaFs2XSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGxhbmd1YWdlID0gbWF0Y2hbNl07XG5cbiAgICAgICAgcGFydHMgPSBsYW5ndWFnZS5zcGxpdChcIi1cIik7XG4gICAgICAgIGlmIChwYXJ0cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICBsYW5ndWFnZSA9IHBhcnRzWzBdO1xuICAgICAgICAgICAgZXh0bGFuZyA9IHBhcnRzWzFdO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG1hdGNoWzE0XSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJlZ2lvbiA9IG1hdGNoWzE0XTtcbiAgICB9XG5cbiAgICBpZiAobWF0Y2hbMTJdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgc2NyaXB0ID0gbWF0Y2hbMTJdO1xuICAgIH1cblxuICAgIGlmIChtYXRjaFsxNl0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB2YXJpYW50cyA9IG1hdGNoWzE2XTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IExvY2FsZShsYW5ndWFnZSwgcmVnaW9uLCBzY3JpcHQsIHZhcmlhbnRzLCBleHRsYW5nKTtcbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGdldEdsb2JhbCB9IGZyb20gXCIuLi90eXBlcy9nbG9iYWwubWpzXCI7XG5pbXBvcnQgeyB2YWxpZGF0ZVN0cmluZyB9IGZyb20gXCIuLi90eXBlcy92YWxpZGF0ZS5tanNcIjtcblxuZXhwb3J0IHsgZ2V0RG9jdW1lbnQsIGdldFdpbmRvdywgZ2V0RG9jdW1lbnRGcmFnbWVudEZyb21TdHJpbmcsIGZpbmRFbGVtZW50V2l0aElkVXB3YXJkcyxnZXRDb250YWluaW5nRG9jdW1lbnQgfTtcblxuLyoqXG4gKiBUaGlzIG1ldGhvZCBmZXRjaGVzIHRoZSBkb2N1bWVudCBvYmplY3RcbiAqXG4gKiBJbiBub2RlanMgdGhpcyBmdW5jdGlvbmFsaXR5IGNhbiBiZSBwZXJmb3JtZWQgd2l0aCBbanNkb21dKGh0dHBzOi8vd3d3Lm5wbWpzLmNvbS9wYWNrYWdlL2pzZG9tKS5cbiAqXG4gKiBgYGBcbiAqIGltcG9ydCB7SlNET019IGZyb20gXCJqc2RvbVwiXG4gKiBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJvYmplY3RcIikge1xuICogICAgY29uc3Qge3dpbmRvd30gPSBuZXcgSlNET00oJycsIHtcbiAqICAgICAgICB1cmw6ICdodHRwOi8vZXhhbXBsZS5jb20vJyxcbiAqICAgICAgICBwcmV0ZW5kVG9CZVZpc3VhbDogdHJ1ZVxuICogICAgfSk7XG4gKlxuICogICAgW1xuICogICAgICAgICdzZWxmJyxcbiAqICAgICAgICAnZG9jdW1lbnQnLFxuICogICAgICAgICdEb2N1bWVudCcsXG4gKiAgICAgICAgJ05vZGUnLFxuICogICAgICAgICdFbGVtZW50JyxcbiAqICAgICAgICAnSFRNTEVsZW1lbnQnLFxuICogICAgICAgICdEb2N1bWVudEZyYWdtZW50JyxcbiAqICAgICAgICAnRE9NUGFyc2VyJyxcbiAqICAgICAgICAnWE1MU2VyaWFsaXplcicsXG4gKiAgICAgICAgJ05vZGVGaWx0ZXInLFxuICogICAgICAgICdJbnB1dEV2ZW50JyxcbiAqICAgICAgICAnQ3VzdG9tRXZlbnQnXG4gKiAgICBdLmZvckVhY2goa2V5ID0+IChnZXRHbG9iYWwoKVtrZXldID0gd2luZG93W2tleV0pKTtcbiAqIH1cbiAqIGBgYFxuICpcbiAqIEByZXR1cm5zIHtvYmplY3R9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjYuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHRocm93cyB7RXJyb3J9IG5vdCBzdXBwb3J0ZWQgZW52aXJvbm1lbnRcbiAqL1xuZnVuY3Rpb24gZ2V0RG9jdW1lbnQoKSB7XG4gICAgbGV0IGRvY3VtZW50ID0gZ2V0R2xvYmFsKCk/LltcImRvY3VtZW50XCJdO1xuICAgIGlmICh0eXBlb2YgZG9jdW1lbnQgIT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwibm90IHN1cHBvcnRlZCBlbnZpcm9ubWVudFwiKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZG9jdW1lbnQ7XG59XG5cbi8qKlxuICogVGhpcyBtZXRob2QgZmV0Y2hlcyB0aGUgd2luZG93IG9iamVjdFxuICpcbiAqIEluIG5vZGVqcyB0aGlzIGZ1bmN0aW9uYWxpdHkgY2FuIGJlIHBlcmZvcm1lZCB3aXRoIFtqc2RvbV0oaHR0cHM6Ly93d3cubnBtanMuY29tL3BhY2thZ2UvanNkb20pLlxuICpcbiAqIGBgYFxuICogaW1wb3J0IHtKU0RPTX0gZnJvbSBcImpzZG9tXCJcbiAqIGlmICh0eXBlb2Ygd2luZG93ICE9PSBcIm9iamVjdFwiKSB7XG4gKiAgICBjb25zdCB7d2luZG93fSA9IG5ldyBKU0RPTSgnJywge1xuICogICAgICAgIHVybDogJ2h0dHA6Ly9leGFtcGxlLmNvbS8nLFxuICogICAgICAgIHByZXRlbmRUb0JlVmlzdWFsOiB0cnVlXG4gKiAgICB9KTtcbiAqXG4gKiAgICBnZXRHbG9iYWwoKVsnd2luZG93J109d2luZG93O1xuICpcbiAqICAgIFtcbiAqICAgICAgICAnc2VsZicsXG4gKiAgICAgICAgJ2RvY3VtZW50JyxcbiAqICAgICAgICAnRG9jdW1lbnQnLFxuICogICAgICAgICdOb2RlJyxcbiAqICAgICAgICAnRWxlbWVudCcsXG4gKiAgICAgICAgJ0hUTUxFbGVtZW50JyxcbiAqICAgICAgICAnRG9jdW1lbnRGcmFnbWVudCcsXG4gKiAgICAgICAgJ0RPTVBhcnNlcicsXG4gKiAgICAgICAgJ1hNTFNlcmlhbGl6ZXInLFxuICogICAgICAgICdOb2RlRmlsdGVyJyxcbiAqICAgICAgICAnSW5wdXRFdmVudCcsXG4gKiAgICAgICAgJ0N1c3RvbUV2ZW50J1xuICogICAgXS5mb3JFYWNoKGtleSA9PiAoZ2V0R2xvYmFsKClba2V5XSA9IHdpbmRvd1trZXldKSk7XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBAcmV0dXJucyB7b2JqZWN0fVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS42LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0aHJvd3Mge0Vycm9yfSBub3Qgc3VwcG9ydGVkIGVudmlyb25tZW50XG4gKi9cbmZ1bmN0aW9uIGdldFdpbmRvdygpIHtcbiAgICBsZXQgd2luZG93ID0gZ2V0R2xvYmFsKCk/LltcIndpbmRvd1wiXTtcbiAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJvYmplY3RcIikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJub3Qgc3VwcG9ydGVkIGVudmlyb25tZW50XCIpO1xuICAgIH1cblxuICAgIHJldHVybiB3aW5kb3c7XG59XG5cbi8qKlxuICogVGhpcyBtZXRob2QgZmV0Y2hlcyB0aGUgZG9jdW1lbnQgb2JqZWN0XG4gKlxuICogSW4gbm9kZWpzIHRoaXMgZnVuY3Rpb25hbGl0eSBjYW4gYmUgcGVyZm9ybWVkIHdpdGggW2pzZG9tXShodHRwczovL3d3dy5ucG1qcy5jb20vcGFja2FnZS9qc2RvbSkuXG4gKlxuICogYGBgXG4gKiBpbXBvcnQge0pTRE9NfSBmcm9tIFwianNkb21cIlxuICogaWYgKHR5cGVvZiB3aW5kb3cgIT09IFwib2JqZWN0XCIpIHtcbiAqICAgIGNvbnN0IHt3aW5kb3d9ID0gbmV3IEpTRE9NKCcnLCB7XG4gKiAgICAgICAgdXJsOiAnaHR0cDovL2V4YW1wbGUuY29tLycsXG4gKiAgICAgICAgcHJldGVuZFRvQmVWaXN1YWw6IHRydWVcbiAqICAgIH0pO1xuICpcbiAqICAgIFtcbiAqICAgICAgICAnc2VsZicsXG4gKiAgICAgICAgJ2RvY3VtZW50JyxcbiAqICAgICAgICAnRG9jdW1lbnQnLFxuICogICAgICAgICdOb2RlJyxcbiAqICAgICAgICAnRWxlbWVudCcsXG4gKiAgICAgICAgJ0hUTUxFbGVtZW50JyxcbiAqICAgICAgICAnRG9jdW1lbnRGcmFnbWVudCcsXG4gKiAgICAgICAgJ0RPTVBhcnNlcicsXG4gKiAgICAgICAgJ1hNTFNlcmlhbGl6ZXInLFxuICogICAgICAgICdOb2RlRmlsdGVyJyxcbiAqICAgICAgICAnSW5wdXRFdmVudCcsXG4gKiAgICAgICAgJ0N1c3RvbUV2ZW50J1xuICogICAgXS5mb3JFYWNoKGtleSA9PiAoZ2V0R2xvYmFsKClba2V5XSA9IHdpbmRvd1trZXldKSk7XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBAcmV0dXJucyB7RG9jdW1lbnRGcmFnbWVudH1cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuNi4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdGhyb3dzIHtFcnJvcn0gbm90IHN1cHBvcnRlZCBlbnZpcm9ubWVudFxuICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYSBzdHJpbmdcbiAqL1xuZnVuY3Rpb24gZ2V0RG9jdW1lbnRGcmFnbWVudEZyb21TdHJpbmcoaHRtbCkge1xuICAgIHZhbGlkYXRlU3RyaW5nKGh0bWwpO1xuXG4gICAgY29uc3QgZG9jdW1lbnQgPSBnZXREb2N1bWVudCgpO1xuICAgIGNvbnN0IHRlbXBsYXRlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInRlbXBsYXRlXCIpO1xuICAgIHRlbXBsYXRlLmlubmVySFRNTCA9IGh0bWw7XG5cbiAgICByZXR1cm4gdGVtcGxhdGUuY29udGVudDtcbn1cblxuLyoqXG4gKiBSZWN1cnNpdmVseSBzZWFyY2hlcyB1cHdhcmRzIGZyb20gYSBnaXZlbiBlbGVtZW50IHRvIGZpbmQgYW4gYW5jZXN0b3IgZWxlbWVudFxuICogd2l0aCBhIHNwZWNpZmllZCBJRCwgY29uc2lkZXJpbmcgYm90aCBub3JtYWwgRE9NIGFuZCBzaGFkb3cgRE9NLlxuICpcbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR8U2hhZG93Um9vdH0gZWxlbWVudCAtIFRoZSBzdGFydGluZyBlbGVtZW50IG9yIHNoYWRvdyByb290IHRvIHNlYXJjaCBmcm9tLlxuICogQHBhcmFtIHtzdHJpbmd9IHRhcmdldElkIC0gVGhlIElEIG9mIHRoZSB0YXJnZXQgZWxlbWVudCB0byBmaW5kLlxuICogQHJldHVybnMge0hUTUxFbGVtZW50fG51bGx9IC0gVGhlIGFuY2VzdG9yIGVsZW1lbnQgd2l0aCB0aGUgc3BlY2lmaWVkIElELCBvciBudWxsIGlmIG5vdCBmb3VuZC5cbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHNpbmNlIDMuMjkuMFxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICovXG5mdW5jdGlvbiBmaW5kRWxlbWVudFdpdGhJZFVwd2FyZHMoZWxlbWVudCwgdGFyZ2V0SWQpIHtcbiAgICBpZiAoIWVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgdGhlIGN1cnJlbnQgZWxlbWVudCBoYXMgdGhlIHRhcmdldCBJRFxuICAgIGlmIChlbGVtZW50LmlkID09PSB0YXJnZXRJZCkge1xuICAgICAgICByZXR1cm4gZWxlbWVudDtcbiAgICB9XG5cbiAgICAvLyBTZWFyY2ggd2l0aGluIHRoZSBjdXJyZW50IGVsZW1lbnQncyBzaGFkb3cgcm9vdCwgaWYgaXQgZXhpc3RzXG4gICAgaWYgKGVsZW1lbnQuc2hhZG93Um9vdCkge1xuICAgICAgICBjb25zdCB0YXJnZXQgPSBlbGVtZW50LnNoYWRvd1Jvb3QuZ2V0RWxlbWVudEJ5SWQodGFyZ2V0SWQpO1xuICAgICAgICBpZiAodGFyZ2V0KSB7XG4gICAgICAgICAgICByZXR1cm4gdGFyZ2V0O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gSWYgdGhlIGN1cnJlbnQgZWxlbWVudCBpcyB0aGUgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LCBzZWFyY2ggd2l0aGluIHRoZSBtYWluIGRvY3VtZW50XG4gICAgaWYgKGVsZW1lbnQgPT09IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCkge1xuICAgICAgICBjb25zdCB0YXJnZXQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0YXJnZXRJZCk7XG4gICAgICAgIGlmICh0YXJnZXQpIHtcbiAgICAgICAgICAgIHJldHVybiB0YXJnZXQ7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBJZiB0aGUgY3VycmVudCBlbGVtZW50IGlzIGluc2lkZSBhIHNoYWRvdyByb290LCBzZWFyY2ggaXRzIGhvc3QncyBhbmNlc3RvcnNcbiAgICBjb25zdCByb290Tm9kZSA9IGVsZW1lbnQuZ2V0Um9vdE5vZGUoKTtcbiAgICBpZiAocm9vdE5vZGUgJiYgcm9vdE5vZGUgaW5zdGFuY2VvZiBTaGFkb3dSb290KSB7XG4gICAgICAgIHJldHVybiBmaW5kRWxlbWVudFdpdGhJZFVwd2FyZHMocm9vdE5vZGUuaG9zdCwgdGFyZ2V0SWQpO1xuICAgIH1cblxuICAgIC8vIE90aGVyd2lzZSwgc2VhcmNoIHRoZSBjdXJyZW50IGVsZW1lbnQncyBwYXJlbnRcbiAgICByZXR1cm4gZmluZEVsZW1lbnRXaXRoSWRVcHdhcmRzKGVsZW1lbnQucGFyZW50RWxlbWVudCwgdGFyZ2V0SWQpO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gKiBAcmV0dXJucyB7SFRNTEVsZW1lbnR8bnVsbH1cbiAqL1xuZnVuY3Rpb24gdHJhdmVyc2VTaGFkb3dSb290cyhlbGVtZW50KSB7XG4gICAgbGV0IGN1cnJlbnRSb290ID0gZWxlbWVudC5zaGFkb3dSb290O1xuICAgIGxldCBjdXJyZW50UGFyZW50ID0gZWxlbWVudC5wYXJlbnROb2RlO1xuXG4gICAgd2hpbGUgKGN1cnJlbnRQYXJlbnQgJiYgY3VycmVudFBhcmVudC5ub2RlVHlwZSAhPT0gTm9kZS5ET0NVTUVOVF9OT0RFICYmIGN1cnJlbnRQYXJlbnQubm9kZVR5cGUgIT09IE5vZGUuRE9DVU1FTlRfRlJBR01FTlRfTk9ERSkge1xuICAgICAgICBpZiAoY3VycmVudFJvb3QgJiYgY3VycmVudFJvb3QucGFyZW50Tm9kZSkge1xuICAgICAgICAgICAgY3VycmVudFBhcmVudCA9IGN1cnJlbnRSb290LnBhcmVudE5vZGU7XG4gICAgICAgICAgICBjdXJyZW50Um9vdCA9IGN1cnJlbnRQYXJlbnQuc2hhZG93Um9vdDtcbiAgICAgICAgfSBlbHNlIGlmIChjdXJyZW50UGFyZW50LnBhcmVudE5vZGUpIHtcbiAgICAgICAgICAgIGN1cnJlbnRQYXJlbnQgPSBjdXJyZW50UGFyZW50LnBhcmVudE5vZGU7XG4gICAgICAgICAgICBjdXJyZW50Um9vdCA9IG51bGw7XG4gICAgICAgIH0gZWxzZSBpZiAoY3VycmVudFJvb3QgJiYgY3VycmVudFJvb3QuaG9zdCAmJiBjdXJyZW50Um9vdC5ob3N0Lm5vZGVUeXBlID09PSBOb2RlLkRPQ1VNRU5UX05PREUpIHtcbiAgICAgICAgICAgIGN1cnJlbnRQYXJlbnQgPSBjdXJyZW50Um9vdC5ob3N0O1xuICAgICAgICAgICAgY3VycmVudFJvb3QgPSBudWxsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY3VycmVudFBhcmVudCA9IG51bGw7XG4gICAgICAgICAgICBjdXJyZW50Um9vdCA9IG51bGw7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gY3VycmVudFBhcmVudDtcbn1cblxuLyoqXG4gKiBSZWN1cnNpdmVseSBzZWFyY2hlcyB1cHdhcmRzIGZyb20gYSBnaXZlbiBlbGVtZW50IHRvIGZpbmQgYW4gYW5jZXN0b3IgZWxlbWVudFxuICpcbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVsZW1lbnRcbiAqIEByZXR1cm5zIHsqfVxuICogQHRocm93cyB7RXJyb3J9IEludmFsaWQgYXJndW1lbnQuIEV4cGVjdGVkIGFuIEhUTUxFbGVtZW50LlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKi9cbmZ1bmN0aW9uIGdldENvbnRhaW5pbmdEb2N1bWVudChlbGVtZW50KSB7XG4gICAgaWYgKCFlbGVtZW50IHx8ICEoZWxlbWVudCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50IHx8IGVsZW1lbnQgaW5zdGFuY2VvZiBlbGVtZW50Lm93bmVyRG9jdW1lbnQuZGVmYXVsdFZpZXcuSFRNTEVsZW1lbnQpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBhcmd1bWVudC4gRXhwZWN0ZWQgYW4gSFRNTEVsZW1lbnQuJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRyYXZlcnNlU2hhZG93Um9vdHMoZWxlbWVudCkgfHwgbnVsbDtcbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IHBhcnNlTG9jYWxlIH0gZnJvbSBcIi4uL2kxOG4vbG9jYWxlLm1qc1wiO1xuaW1wb3J0IHsgZ2V0RG9jdW1lbnQgfSBmcm9tIFwiLi91dGlsLm1qc1wiO1xuaW1wb3J0IHsgZ2V0R2xvYmFsT2JqZWN0IH0gZnJvbSBcIi4uL3R5cGVzL2dsb2JhbC5tanNcIjtcblxuZXhwb3J0IHsgZ2V0TG9jYWxlT2ZEb2N1bWVudCB9O1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAdHlwZSB7c3RyaW5nfVxuICovXG5jb25zdCBERUZBVUxUX0xBTkdVQUdFID0gXCJlblwiO1xuXG4vKipcbiAqIFdpdGggdGhpcyBmdW5jdGlvbiB5b3UgY2FuIHJlYWQgdGhlIGxhbmd1YWdlIHZlcnNpb24gc2V0IGJ5IHRoZSBkb2N1bWVudC5cbiAqIEZvciB0aGlzIHRoZSBhdHRyaWJ1dGUgYGxhbmdgIGluIHRoZSBodG1sIHRhZyBpcyByZWFkLiBJZiBubyBhdHRyaWJ1dGUgaXMgc2V0LCBgZW5gIGlzIHVzZWQgYXMgZGVmYXVsdC5cbiAqIEFsdGVybmF0aXZlbHksIHRoZSBsYW5ndWFnZSB2ZXJzaW9uIG9mIHRoZSBicm93c2VyIGlzIHVzZWQuXG4gKlxuICogYGBgaHRtbFxuICogPGh0bWwgbGFuZz1cImVuXCI+XG4gKiBgYGBcbiAqXG4gKiBZb3UgY2FuIGNhbGwgdGhlIGZ1bmN0aW9uIHZpYSBgZ2V0TG9jYWxlT2ZEb2N1bWVudCgpYC5cbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjEzLjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgc3RyaW5nXG4gKiBAdGhyb3dzIHtFcnJvcn0gdW5zdXBwb3J0ZWQgbG9jYWxlXG4gKiBAc3VtbWFyeSBUcmllcyB0byBkZXRlcm1pbmUgdGhlIGxvY2FsZSB1c2VkXG4gKi9cbmZ1bmN0aW9uIGdldExvY2FsZU9mRG9jdW1lbnQoKSB7XG4gICAgY29uc3QgZG9jdW1lbnQgPSBnZXREb2N1bWVudCgpO1xuXG4gICAgbGV0IGh0bWwgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiaHRtbFwiKTtcbiAgICBpZiAoaHRtbCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50ICYmIGh0bWwuaGFzQXR0cmlidXRlKFwibGFuZ1wiKSkge1xuICAgICAgICBsZXQgbG9jYWxlID0gaHRtbC5nZXRBdHRyaWJ1dGUoXCJsYW5nXCIpO1xuICAgICAgICBpZiAobG9jYWxlKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IHBhcnNlTG9jYWxlKGxvY2FsZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBsZXQgbmF2aWdhdG9yTGFuZ3VhZ2UgPSBnZXROYXZpZ2F0b3JMYW5ndWFnZSgpO1xuICAgIGlmIChuYXZpZ2F0b3JMYW5ndWFnZSkge1xuICAgICAgICByZXR1cm4gcGFyc2VMb2NhbGUobmF2aWdhdG9yTGFuZ3VhZ2UpO1xuICAgIH1cblxuICAgIHJldHVybiBwYXJzZUxvY2FsZShERUZBVUxUX0xBTkdVQUdFKTtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHJldHVybnMge3N0cmluZ3x1bmRlZmluZWR8Kn1cbiAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL05hdmlnYXRvci9sYW5ndWFnZVxuICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvTmF2aWdhdG9yL2xhbmd1YWdlc1xuICovXG5jb25zdCBnZXROYXZpZ2F0b3JMYW5ndWFnZSA9ICgpID0+IHtcbiAgICBjb25zdCBuYXZpZ2F0b3IgPSBnZXRHbG9iYWxPYmplY3QoXCJuYXZpZ2F0b3JcIik7XG4gICAgaWYgKG5hdmlnYXRvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgaWYgKG5hdmlnYXRvci5oYXNPd25Qcm9wZXJ0eShcImxhbmd1YWdlXCIpKSB7XG4gICAgICAgIGNvbnN0IGxhbmd1YWdlID0gbmF2aWdhdG9yLmxhbmd1YWdlO1xuICAgICAgICBpZiAodHlwZW9mIGxhbmd1YWdlID09PSBcInN0cmluZ1wiICYmIGxhbmd1YWdlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHJldHVybiBsYW5ndWFnZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGxhbmd1YWdlcyA9IG5hdmlnYXRvcj8ubGFuZ3VhZ2VzO1xuICAgIGlmIChBcnJheS5pc0FycmF5KGxhbmd1YWdlcykgJiYgbGFuZ3VhZ2VzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmV0dXJuIGxhbmd1YWdlc1swXTtcbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xufTtcbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IEJhc2UgfSBmcm9tIFwiLi9iYXNlLm1qc1wiO1xuaW1wb3J0IHsgdmFsaWRhdGVTdHJpbmcgfSBmcm9tIFwiLi92YWxpZGF0ZS5tanNcIjtcblxuZXhwb3J0IHsgSUQgfTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHR5cGUge01hcDxzdHJpbmcsIGludGVnZXI+fVxuICovXG5sZXQgaW50ZXJuYWxDb3VudGVyID0gbmV3IE1hcCgpO1xuXG4vKipcbiAqIFdpdGggdGhlIGlkIGNsYXNzLCBzZXF1ZW5jZXMgb2YgaWRzIGNhbiBiZSBjcmVhdGVkLiBmb3IgdGhpcyBwdXJwb3NlLCBhbiBpbnRlcm5hbCBjb3VudGVyIGlzIGluY3JlbWVudGVkIGZvciBlYWNoIHByZWZpeC5cbiAqIHRodXMsIHRoZSBmaXJzdCBpZCB3aXRoIHRoZSBwcmVmaXggYG15aWRgIHdpbGwgYmUgYG15aWQxYCBhbmQgdGhlIHNlY29uZCBpZCBgbXlpZDJgLlxuICogVGhlIGlkcyBhcmUgdGhlIHNhbWUgZm9yIGV2ZXJ5IGNhbGwsIGZvciBleGFtcGxlIG9uIGEgd2ViIHBhZ2UuXG4gKlxuICogU28gdGhlIGlkcyBjYW4gYWxzbyBiZSB1c2VkIGZvciBuYXZpZ2F0aW9uLiB5b3UganVzdCBoYXZlIHRvIHRha2UgY2FyZSB0aGF0IHRoZSBvcmRlciBzdGF5cyB0aGUgc2FtZS5cbiAqXG4gKiBBcyBvZiB2ZXJzaW9uIDEuNi4wIHRoZXJlIGlzIHRoZSBuZXcgUmFuZG9tSUQuIHRoaXMgSUQgY2xhc3MgaXMgY29udGludW91cyBmcm9tIG5vdyBvbi5cbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjAuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKiBAc3VtbWFyeSBBdXRvbWF0aWMgZ2VuZXJhdGlvbiBvZiBpZHNcbiAqL1xuY2xhc3MgSUQgZXh0ZW5kcyBCYXNlIHtcbiAgICAvKipcbiAgICAgKiBjcmVhdGUgbmV3IGlkIHdpdGggcHJlZml4XG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcHJlZml4XG4gICAgICovXG4gICAgY29uc3RydWN0b3IocHJlZml4KSB7XG4gICAgICAgIHN1cGVyKCk7XG5cbiAgICAgICAgaWYgKHByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBwcmVmaXggPSBcImlkXCI7XG4gICAgICAgIH1cblxuICAgICAgICB2YWxpZGF0ZVN0cmluZyhwcmVmaXgpO1xuXG4gICAgICAgIGlmICghaW50ZXJuYWxDb3VudGVyLmhhcyhwcmVmaXgpKSB7XG4gICAgICAgICAgICBpbnRlcm5hbENvdW50ZXIuc2V0KHByZWZpeCwgMSk7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgY291bnQgPSBpbnRlcm5hbENvdW50ZXIuZ2V0KHByZWZpeCk7XG4gICAgICAgIHRoaXMuaWQgPSBwcmVmaXggKyBjb3VudDtcblxuICAgICAgICBpbnRlcm5hbENvdW50ZXIuc2V0KHByZWZpeCwgKytjb3VudCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7c3RyaW5nfVxuICAgICAqL1xuICAgIHRvU3RyaW5nKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5pZDtcbiAgICB9XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBpc0l0ZXJhYmxlLCBpc1N0cmluZyB9IGZyb20gXCIuLi90eXBlcy9pcy5tanNcIjtcbmltcG9ydCB7IHZhbGlkYXRlRnVuY3Rpb24sIHZhbGlkYXRlU3RyaW5nIH0gZnJvbSBcIi4uL3R5cGVzL3ZhbGlkYXRlLm1qc1wiO1xuaW1wb3J0IHsgQmFzZSB9IGZyb20gXCIuL2Jhc2UubWpzXCI7XG5cbmV4cG9ydCB7IFRva2VuTGlzdCB9O1xuXG4vKipcbiAqIEEgYFRva2VuTGlzdGAgYWxsb3dzIHlvdSB0byBtYW5hZ2UgdG9rZW5zIChpbmRpdmlkdWFsIGNoYXJhY3RlciBzdHJpbmdzIHN1Y2ggYXMgY3NzIGNsYXNzZXMgaW4gYW4gYXR0cmlidXRlIHN0cmluZykuXG4gKlxuICogVGhlIGBUb2tlbkxpc3RgIG9mZmVycyB2YXJpb3VzIGZ1bmN0aW9ucyB0byBtYW5pcHVsYXRlIHZhbHVlcy4gRm9yIGV4YW1wbGUsIHlvdSBjYW4gYWRkLCByZW1vdmUgb3IgcmVwbGFjZSBhIGNsYXNzIGluIGEgQ1NTIGxpc3QuXG4gKlxuICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIHRoZSBbaXRlcmF0aW9uIHByb3RvY29sXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9JdGVyYXRpb25fcHJvdG9jb2xzKS5cbiAqXG4gKiBAZXh0ZXJuYWxFeGFtcGxlIC4uLy4uL2V4YW1wbGUvdHlwZXMvdG9rZW5saXN0LTEubWpzXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjIuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKi9cbmNsYXNzIFRva2VuTGlzdCBleHRlbmRzIEJhc2Uge1xuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHthcnJheXxzdHJpbmd8aXRlcmF0YWJsZX0gaW5pdFxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGluaXQpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy50b2tlbnMgPSBuZXcgU2V0KCk7XG5cbiAgICAgICAgaWYgKHR5cGVvZiBpbml0ICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICB0aGlzLmFkZChpbml0KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEl0ZXJhdG9yIHByb3RvY29sXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7U3ltYm9sLml0ZXJhdG9yfVxuICAgICAqL1xuICAgIGdldEl0ZXJhdG9yKCkge1xuICAgICAgICByZXR1cm4gdGhpc1tTeW1ib2wuaXRlcmF0b3JdKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSXRlcmF0b3JcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHt7bmV4dDogKChmdW5jdGlvbigpOiAoe3ZhbHVlOiAqLCBkb25lOiBib29sZWFufSkpfCopfX1cbiAgICAgKi9cbiAgICBbU3ltYm9sLml0ZXJhdG9yXSgpIHtcbiAgICAgICAgLy8gVXNlIGEgbmV3IGluZGV4IGZvciBlYWNoIGl0ZXJhdG9yLiBUaGlzIG1ha2VzIG11bHRpcGxlXG4gICAgICAgIC8vIGl0ZXJhdGlvbnMgb3ZlciB0aGUgaXRlcmFibGUgc2FmZSBmb3Igbm9uLXRyaXZpYWwgY2FzZXMsXG4gICAgICAgIC8vIHN1Y2ggYXMgdXNlIG9mIGJyZWFrIG9yIG5lc3RlZCBsb29waW5nIG92ZXIgdGhlIHNhbWUgaXRlcmFibGUuXG4gICAgICAgIGxldCBpbmRleCA9IDA7XG4gICAgICAgIGxldCBlbnRyaWVzID0gdGhpcy5lbnRyaWVzKCk7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG5leHQ6ICgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoaW5kZXggPCBlbnRyaWVzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4geyB2YWx1ZTogZW50cmllcz8uW2luZGV4KytdLCBkb25lOiBmYWxzZSB9O1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7IGRvbmU6IHRydWUgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdHJ1ZSBpZiBpdCBjb250YWlucyB0b2tlbiwgb3RoZXJ3aXNlIGZhbHNlXG4gICAgICpcbiAgICAgKiBAZXh0ZXJuYWxFeGFtcGxlIC4uLy4uL2V4YW1wbGUvdHlwZXMvdG9rZW5saXN0LTIubWpzXG4gICAgICogQHBhcmFtIHthcnJheXxzdHJpbmd8aXRlcmF0YWJsZX0gdmFsdWVcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBjb250YWlucyh2YWx1ZSkge1xuICAgICAgICBpZiAoaXNTdHJpbmcodmFsdWUpKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnRyaW0oKTtcbiAgICAgICAgICAgIGxldCBjb3VudGVyID0gMDtcbiAgICAgICAgICAgIHZhbHVlLnNwbGl0KFwiIFwiKS5mb3JFYWNoKCh0b2tlbikgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnRva2Vucy5oYXModG9rZW4udHJpbSgpKSA9PT0gZmFsc2UpIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICBjb3VudGVyKys7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBjb3VudGVyID4gMCA/IHRydWUgOiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc0l0ZXJhYmxlKHZhbHVlKSkge1xuICAgICAgICAgICAgbGV0IGNvdW50ZXIgPSAwO1xuICAgICAgICAgICAgZm9yIChsZXQgdG9rZW4gb2YgdmFsdWUpIHtcbiAgICAgICAgICAgICAgICB2YWxpZGF0ZVN0cmluZyh0b2tlbik7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMudG9rZW5zLmhhcyh0b2tlbi50cmltKCkpID09PSBmYWxzZSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIGNvdW50ZXIrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBjb3VudGVyID4gMCA/IHRydWUgOiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBZGQgdG9rZW5zXG4gICAgICpcbiAgICAgKiBAZXh0ZXJuYWxFeGFtcGxlIC4uLy4uL2V4YW1wbGUvdHlwZXMvdG9rZW5saXN0LTMubWpzXG4gICAgICogQHBhcmFtIHthcnJheXxzdHJpbmd8aXRlcmF0YWJsZX0gdmFsdWVcbiAgICAgKiBAcmV0dXJucyB7VG9rZW5MaXN0fVxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdW5zdXBwb3J0ZWQgdmFsdWVcbiAgICAgKi9cbiAgICBhZGQodmFsdWUpIHtcbiAgICAgICAgaWYgKGlzU3RyaW5nKHZhbHVlKSkge1xuICAgICAgICAgICAgdmFsdWUuc3BsaXQoXCIgXCIpLmZvckVhY2goKHRva2VuKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy50b2tlbnMuYWRkKHRva2VuLnRyaW0oKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIGlmIChpc0l0ZXJhYmxlKHZhbHVlKSkge1xuICAgICAgICAgICAgZm9yIChsZXQgdG9rZW4gb2YgdmFsdWUpIHtcbiAgICAgICAgICAgICAgICB2YWxpZGF0ZVN0cmluZyh0b2tlbik7XG4gICAgICAgICAgICAgICAgdGhpcy50b2tlbnMuYWRkKHRva2VuLnRyaW0oKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwidW5zdXBwb3J0ZWQgdmFsdWVcIik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiByZW1vdmUgYWxsIHRva2Vuc1xuICAgICAqXG4gICAgICogQHJldHVybnMge1Rva2VuTGlzdH1cbiAgICAgKi9cbiAgICBjbGVhcigpIHtcbiAgICAgICAgdGhpcy50b2tlbnMuY2xlYXIoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyB0b2tlblxuICAgICAqXG4gICAgICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL3R5cGVzL3Rva2VubGlzdC00Lm1qc1xuICAgICAqIEBwYXJhbSB7YXJyYXl8c3RyaW5nfGl0ZXJhdGFibGV9IHZhbHVlXG4gICAgICogQHJldHVybnMge1Rva2VuTGlzdH1cbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHVuc3VwcG9ydGVkIHZhbHVlXG4gICAgICovXG4gICAgcmVtb3ZlKHZhbHVlKSB7XG4gICAgICAgIGlmIChpc1N0cmluZyh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHZhbHVlLnNwbGl0KFwiIFwiKS5mb3JFYWNoKCh0b2tlbikgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMudG9rZW5zLmRlbGV0ZSh0b2tlbi50cmltKCkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNJdGVyYWJsZSh2YWx1ZSkpIHtcbiAgICAgICAgICAgIGZvciAobGV0IHRva2VuIG9mIHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgdmFsaWRhdGVTdHJpbmcodG9rZW4pO1xuICAgICAgICAgICAgICAgIHRoaXMudG9rZW5zLmRlbGV0ZSh0b2tlbi50cmltKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInVuc3VwcG9ydGVkIHZhbHVlXCIsIFwidHlwZXMvdG9rZW5saXN0Lm1qc1wiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHRoaXMgbWV0aG9kIHJlcGxhY2VzIGEgdG9rZW4gd2l0aCBhIG5ldyB0b2tlbi5cbiAgICAgKlxuICAgICAqIGlmIHRoZSBwYXNzZWQgdG9rZW4gZXhpc3RzLCBpdCBpcyByZXBsYWNlZCB3aXRoIG5ld1Rva2VuIGFuZCBUb2tlbkxpc3QgaXMgcmV0dXJuZWQuXG4gICAgICogaWYgdGhlIHRva2VuIGRvZXMgbm90IGV4aXN0LCBuZXdUb2tlbiBpcyBub3Qgc2V0IGFuZCBUb2tlbkxpc3QgaXMgcmV0dXJuZWQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdG9rZW5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmV3VG9rZW5cbiAgICAgKiBAcmV0dXJucyB7VG9rZW5MaXN0fVxuICAgICAqL1xuICAgIHJlcGxhY2UodG9rZW4sIG5ld1Rva2VuKSB7XG4gICAgICAgIHZhbGlkYXRlU3RyaW5nKHRva2VuKTtcbiAgICAgICAgdmFsaWRhdGVTdHJpbmcobmV3VG9rZW4pO1xuICAgICAgICBpZiAoIXRoaXMuY29udGFpbnModG9rZW4pKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBhID0gQXJyYXkuZnJvbSh0aGlzLnRva2Vucyk7XG4gICAgICAgIGxldCBpID0gYS5pbmRleE9mKHRva2VuKTtcbiAgICAgICAgaWYgKGkgPT09IC0xKSByZXR1cm4gdGhpcztcblxuICAgICAgICBhLnNwbGljZShpLCAxLCBuZXdUb2tlbik7XG4gICAgICAgIHRoaXMudG9rZW5zID0gbmV3IFNldCgpO1xuICAgICAgICB0aGlzLmFkZChhKTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIHRva2VuIGZyb20gc3RyaW5nLiBJZiB0b2tlbiBkb2Vzbid0IGV4aXN0IGl0J3MgYWRkZWQuXG4gICAgICpcbiAgICAgKiBAZXh0ZXJuYWxFeGFtcGxlIC4uLy4uL2V4YW1wbGUvdHlwZXMvdG9rZW5saXN0LTUubWpzXG4gICAgICogQHBhcmFtIHthcnJheXxzdHJpbmd8aXRlcmF0YWJsZX0gdmFsdWVcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHVuc3VwcG9ydGVkIHZhbHVlXG4gICAgICovXG4gICAgdG9nZ2xlKHZhbHVlKSB7XG4gICAgICAgIGlmIChpc1N0cmluZyh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHZhbHVlLnNwbGl0KFwiIFwiKS5mb3JFYWNoKCh0b2tlbikgPT4ge1xuICAgICAgICAgICAgICAgIHRvZ2dsZVZhbHVlLmNhbGwodGhpcywgdG9rZW4pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNJdGVyYWJsZSh2YWx1ZSkpIHtcbiAgICAgICAgICAgIGZvciAobGV0IHRva2VuIG9mIHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgdG9nZ2xlVmFsdWUuY2FsbCh0aGlzLCB0b2tlbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwidW5zdXBwb3J0ZWQgdmFsdWVcIiwgXCJ0eXBlcy90b2tlbmxpc3QubWpzXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogcmV0dXJucyBhbiBhcnJheSB3aXRoIGFsbCB0b2tlbnNcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHthcnJheX1cbiAgICAgKi9cbiAgICBlbnRyaWVzKCkge1xuICAgICAgICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLnRva2Vucyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogZXhlY3V0ZXMgdGhlIHByb3ZpZGVkIGZ1bmN0aW9uIHdpdGggZWFjaCB2YWx1ZSBvZiB0aGUgc2V0XG4gICAgICpcbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBjYWxsYmFja1xuICAgICAqIEByZXR1cm5zIHtUb2tlbkxpc3R9XG4gICAgICovXG4gICAgZm9yRWFjaChjYWxsYmFjaykge1xuICAgICAgICB2YWxpZGF0ZUZ1bmN0aW9uKGNhbGxiYWNrKTtcbiAgICAgICAgdGhpcy50b2tlbnMuZm9yRWFjaChjYWxsYmFjayk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHJldHVybnMgdGhlIGluZGl2aWR1YWwgdG9rZW5zIHNlcGFyYXRlZCBieSBhIGJsYW5rIGNoYXJhY3RlclxuICAgICAqXG4gICAgICogQHJldHVybnMge3N0cmluZ31cbiAgICAgKi9cbiAgICB0b1N0cmluZygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW50cmllcygpLmpvaW4oXCIgXCIpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHRva2VuXG4gKiBAcmV0dXJucyB7dG9nZ2xlVmFsdWV9XG4gKiBAdGhyb3dzIHtFcnJvcn0gbXVzdCBiZSBjYWxsZWQgd2l0aCBUb2tlbkxpc3QuY2FsbFxuICovXG5mdW5jdGlvbiB0b2dnbGVWYWx1ZSh0b2tlbikge1xuICAgIGlmICghKHRoaXMgaW5zdGFuY2VvZiBUb2tlbkxpc3QpKSB0aHJvdyBFcnJvcihcIm11c3QgYmUgY2FsbGVkIHdpdGggVG9rZW5MaXN0LmNhbGxcIik7XG4gICAgdmFsaWRhdGVTdHJpbmcodG9rZW4pO1xuICAgIHRva2VuID0gdG9rZW4udHJpbSgpO1xuICAgIGlmICh0aGlzLmNvbnRhaW5zKHRva2VuKSkge1xuICAgICAgICB0aGlzLnJlbW92ZSh0b2tlbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICB0aGlzLmFkZCh0b2tlbik7XG4gICAgcmV0dXJuIHRoaXM7XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5leHBvcnQge1xuICAgIERFRkFVTFRfVEhFTUUsXG4gICAgQVRUUklCVVRFX1BSRUZJWCxcbiAgICBBVFRSSUJVVEVfT1BUSU9OUyxcbiAgICBBVFRSSUJVVEVfT1BUSU9OU19TRUxFQ1RPUixcbiAgICBBVFRSSUJVVEVfVEhFTUVfUFJFRklYLFxuICAgIEFUVFJJQlVURV9USEVNRV9OQU1FLFxuICAgIEFUVFJJQlVURV9VUERBVEVSX0FUVFJJQlVURVMsXG4gICAgQVRUUklCVVRFX1VQREFURVJfU0VMRUNUX1RISVMsXG4gICAgQVRUUklCVVRFX1VQREFURVJfUkVQTEFDRSxcbiAgICBBVFRSSUJVVEVfVVBEQVRFUl9JTlNFUlQsXG4gICAgQVRUUklCVVRFX1VQREFURVJfSU5TRVJUX1JFRkVSRU5DRSxcbiAgICBBVFRSSUJVVEVfVVBEQVRFUl9SRU1PVkUsXG4gICAgQVRUUklCVVRFX1VQREFURVJfQklORCxcbiAgICBBVFRSSUJVVEVfVEVNUExBVEVfUFJFRklYLFxuICAgIEFUVFJJQlVURV9ST0xFLFxuICAgIEFUVFJJQlVURV9ESVNBQkxFRCxcbiAgICBBVFRSSUJVVEVfVkFMVUUsXG4gICAgQVRUUklCVVRFX09CSkVDVExJTkssXG4gICAgQVRUUklCVVRFX0VSUk9STUVTU0FHRSxcbiAgICBUQUdfU0NSSVBULFxuICAgIFRBR19TVFlMRSxcbiAgICBUQUdfTElOSyxcbiAgICBBVFRSSUJVVEVfSUQsXG4gICAgQVRUUklCVVRFX0NMQVNTLFxuICAgIEFUVFJJQlVURV9USVRMRSxcbiAgICBBVFRSSUJVVEVfU1JDLFxuICAgIEFUVFJJQlVURV9IUkVGLFxuICAgIEFUVFJJQlVURV9UWVBFLFxuICAgIEFUVFJJQlVURV9OT05DRSxcbiAgICBBVFRSSUJVVEVfVFJBTlNMQVRFLFxuICAgIEFUVFJJQlVURV9UQUJJTkRFWCxcbiAgICBBVFRSSUJVVEVfU1BFTExDSEVDSyxcbiAgICBBVFRSSUJVVEVfU0xPVCxcbiAgICBBVFRSSUJVVEVfUEFSVCxcbiAgICBBVFRSSUJVVEVfTEFORyxcbiAgICBBVFRSSUJVVEVfSVRFTVRZUEUsXG4gICAgQVRUUklCVVRFX0lURU1TQ09QRSxcbiAgICBBVFRSSUJVVEVfSVRFTVJFRixcbiAgICBBVFRSSUJVVEVfSVRFTUlELFxuICAgIEFUVFJJQlVURV9JVEVNUFJPUCxcbiAgICBBVFRSSUJVVEVfSVMsXG4gICAgQVRUUklCVVRFX0lOUFVUTU9ERSxcbiAgICBBVFRSSUJVVEVfQUNDRVNTS0VZLFxuICAgIEFUVFJJQlVURV9BVVRPQ0FQSVRBTElaRSxcbiAgICBBVFRSSUJVVEVfQVVUT0ZPQ1VTLFxuICAgIEFUVFJJQlVURV9DT05URU5URURJVEFCTEUsXG4gICAgQVRUUklCVVRFX0RJUixcbiAgICBBVFRSSUJVVEVfRFJBR0dBQkxFLFxuICAgIEFUVFJJQlVURV9FTlRFUktFWUhJTlQsXG4gICAgQVRUUklCVVRFX0VYUE9SVFBBUlRTLFxuICAgIEFUVFJJQlVURV9ISURERU4sXG4gICAgb2JqZWN0VXBkYXRlckxpbmtTeW1ib2wsXG4gICAgY3VzdG9tRWxlbWVudFVwZGF0ZXJMaW5rU3ltYm9sLFxufTtcblxuLyoqXG4gKiBkZWZhdWx0IHRoZW1lXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKi9cbmNvbnN0IERFRkFVTFRfVEhFTUUgPSBcIm1vbnN0ZXJcIjtcblxuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuOC4wXG4gKiBAdHlwZSB7c3RyaW5nfVxuICovXG5jb25zdCBBVFRSSUJVVEVfUFJFRklYID0gXCJkYXRhLW1vbnN0ZXItXCI7XG5cbi8qKlxuICogVGhpcyBpcyB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlIHRvIHBhc3Mgb3B0aW9ucyB0byBhIGNvbnRyb2xcbiAqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuOC4wXG4gKiBAdHlwZSB7c3RyaW5nfVxuICovXG5jb25zdCBBVFRSSUJVVEVfT1BUSU9OUyA9IGAke0FUVFJJQlVURV9QUkVGSVh9b3B0aW9uc2A7XG5cbi8qKlxuICogVGhpcyBpcyB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlIHRvIHBhc3Mgb3B0aW9ucyB0byBhIGNvbnRyb2xcbiAqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMzAuMFxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuY29uc3QgQVRUUklCVVRFX09QVElPTlNfU0VMRUNUT1IgPSBgJHtBVFRSSUJVVEVfUFJFRklYfW9wdGlvbnMtc2VsZWN0b3JgO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuOC4wXG4gKi9cbmNvbnN0IEFUVFJJQlVURV9USEVNRV9QUkVGSVggPSBgJHtBVFRSSUJVVEVfUFJFRklYfXRoZW1lLWA7XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3RyaW5nfVxuICovXG5jb25zdCBBVFRSSUJVVEVfVEhFTUVfTkFNRSA9IGAke0FUVFJJQlVURV9USEVNRV9QUkVGSVh9bmFtZWA7XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS44LjBcbiAqL1xuY29uc3QgQVRUUklCVVRFX1VQREFURVJfQVRUUklCVVRFUyA9IGAke0FUVFJJQlVURV9QUkVGSVh9YXR0cmlidXRlc2A7XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNy4xXG4gKi9cbmNvbnN0IEFUVFJJQlVURV9VUERBVEVSX1NFTEVDVF9USElTID0gYCR7QVRUUklCVVRFX1BSRUZJWH1zZWxlY3QtdGhpc2A7XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS44LjBcbiAqL1xuY29uc3QgQVRUUklCVVRFX1VQREFURVJfUkVQTEFDRSA9IGAke0FUVFJJQlVURV9QUkVGSVh9cmVwbGFjZWA7XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS44LjBcbiAqL1xuY29uc3QgQVRUUklCVVRFX1VQREFURVJfSU5TRVJUID0gYCR7QVRUUklCVVRFX1BSRUZJWH1pbnNlcnRgO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuOC4wXG4gKi9cbmNvbnN0IEFUVFJJQlVURV9VUERBVEVSX0lOU0VSVF9SRUZFUkVOQ0UgPSBgJHtBVFRSSUJVVEVfUFJFRklYfWluc2VydC1yZWZlcmVuY2VgO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuOC4wXG4gKi9cbmNvbnN0IEFUVFJJQlVURV9VUERBVEVSX1JFTU9WRSA9IGAke0FUVFJJQlVURV9QUkVGSVh9cmVtb3ZlYDtcblxuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjkuMFxuICovXG5jb25zdCBBVFRSSUJVVEVfVVBEQVRFUl9CSU5EID0gYCR7QVRUUklCVVRFX1BSRUZJWH1iaW5kYDtcblxuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI3LjBcbiAqL1xuY29uc3QgQVRUUklCVVRFX1RFTVBMQVRFX1BSRUZJWCA9IGAke0FUVFJJQlVURV9QUkVGSVh9dGVtcGxhdGUtcHJlZml4YDtcblxuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjE0LjBcbiAqL1xuY29uc3QgQVRUUklCVVRFX1JPTEUgPSBgJHtBVFRSSUJVVEVfUFJFRklYfXJvbGVgO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjQuMFxuICovXG5jb25zdCBBVFRSSUJVVEVfRElTQUJMRUQgPSBcImRpc2FibGVkXCI7XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNC4wXG4gKi9cbmNvbnN0IEFUVFJJQlVURV9WQUxVRSA9IFwidmFsdWVcIjtcblxuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjkuMFxuICovXG5jb25zdCBBVFRSSUJVVEVfT0JKRUNUTElOSyA9IGAke0FUVFJJQlVURV9QUkVGSVh9b2JqZWN0bGlua2A7XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNC4wXG4gKi9cbmNvbnN0IEFUVFJJQlVURV9FUlJPUk1FU1NBR0UgPSBgJHtBVFRSSUJVVEVfUFJFRklYfWVycm9yYDtcblxuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0eXBlIHtzeW1ib2x9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI0LjBcbiAqL1xuY29uc3Qgb2JqZWN0VXBkYXRlckxpbmtTeW1ib2wgPSBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci9kb20vQEBvYmplY3QtdXBkYXRlci1saW5rXCIpO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N5bWJvbH1cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjQuMFxuICovXG5jb25zdCBjdXN0b21FbGVtZW50VXBkYXRlckxpbmtTeW1ib2wgPSBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci9kb20vY3VzdG9tLWVsZW1lbnRAQG9wdGlvbnMtdXBkYXRlci1saW5rXCIpO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjUuMFxuICovXG5jb25zdCBUQUdfU0NSSVBUID0gXCJzY3JpcHRcIjtcblxuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI1LjBcbiAqL1xuY29uc3QgVEFHX1NUWUxFID0gXCJzdHlsZVwiO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjUuMFxuICovXG5jb25zdCBUQUdfTElOSyA9IFwibGlua1wiO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjUuMFxuICovXG5cbmNvbnN0IEFUVFJJQlVURV9JRCA9IFwiaWRcIjtcblxuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI1LjBcbiAqL1xuXG5jb25zdCBBVFRSSUJVVEVfQ0xBU1MgPSBcImNsYXNzXCI7XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNS4wXG4gKi9cbmNvbnN0IEFUVFJJQlVURV9USVRMRSA9IFwidGl0bGVcIjtcblxuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI1LjBcbiAqL1xuY29uc3QgQVRUUklCVVRFX1NSQyA9IFwic3JjXCI7XG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjUuMFxuICovXG5jb25zdCBBVFRSSUJVVEVfSFJFRiA9IFwiaHJlZlwiO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjUuMFxuICovXG5jb25zdCBBVFRSSUJVVEVfVFlQRSA9IFwidHlwZVwiO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjUuMFxuICovXG5jb25zdCBBVFRSSUJVVEVfTk9OQ0UgPSBcIm5vbmNlXCI7XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNS4wXG4gKi9cbmNvbnN0IEFUVFJJQlVURV9UUkFOU0xBVEUgPSBcInRyYW5zbGF0ZVwiO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjUuMFxuICovXG5jb25zdCBBVFRSSUJVVEVfVEFCSU5ERVggPSBcInRhYmluZGV4XCI7XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNS4wXG4gKi9cbmNvbnN0IEFUVFJJQlVURV9TUEVMTENIRUNLID0gXCJzcGVsbGNoZWNrXCI7XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNS4wXG4gKi9cbmNvbnN0IEFUVFJJQlVURV9TTE9UID0gXCJzbG90XCI7XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNS4wXG4gKi9cbmNvbnN0IEFUVFJJQlVURV9QQVJUID0gXCJwYXJ0XCI7XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNS4wXG4gKi9cbmNvbnN0IEFUVFJJQlVURV9MQU5HID0gXCJsYW5nXCI7XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNS4wXG4gKi9cbmNvbnN0IEFUVFJJQlVURV9JVEVNVFlQRSA9IFwiaXRlbXR5cGVcIjtcblxuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI1LjBcbiAqL1xuY29uc3QgQVRUUklCVVRFX0lURU1TQ09QRSA9IFwiaXRlbXNjb3BlXCI7XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNS4wXG4gKi9cbmNvbnN0IEFUVFJJQlVURV9JVEVNUkVGID0gXCJpdGVtcmVmXCI7XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNS4wXG4gKi9cbmNvbnN0IEFUVFJJQlVURV9JVEVNSUQgPSBcIml0ZW1pZFwiO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjUuMFxuICovXG5jb25zdCBBVFRSSUJVVEVfSVRFTVBST1AgPSBcIml0ZW1wcm9wXCI7XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNS4wXG4gKi9cbmNvbnN0IEFUVFJJQlVURV9JUyA9IFwiaXNcIjtcblxuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI1LjBcbiAqL1xuY29uc3QgQVRUUklCVVRFX0lOUFVUTU9ERSA9IFwiaW5wdXRtb2RlXCI7XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNS4wXG4gKi9cbmNvbnN0IEFUVFJJQlVURV9BQ0NFU1NLRVkgPSBcImFjY2Vzc2tleVwiO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjUuMFxuICovXG5jb25zdCBBVFRSSUJVVEVfQVVUT0NBUElUQUxJWkUgPSBcImF1dG9jYXBpdGFsaXplXCI7XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNS4wXG4gKi9cbmNvbnN0IEFUVFJJQlVURV9BVVRPRk9DVVMgPSBcImF1dG9mb2N1c1wiO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjUuMFxuICovXG5jb25zdCBBVFRSSUJVVEVfQ09OVEVOVEVESVRBQkxFID0gXCJjb250ZW50ZWRpdGFibGVcIjtcblxuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI1LjBcbiAqL1xuY29uc3QgQVRUUklCVVRFX0RJUiA9IFwiZGlyXCI7XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNS4wXG4gKi9cbmNvbnN0IEFUVFJJQlVURV9EUkFHR0FCTEUgPSBcImRyYWdnYWJsZVwiO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjUuMFxuICovXG5jb25zdCBBVFRSSUJVVEVfRU5URVJLRVlISU5UID0gXCJlbnRlcmtleWhpbnRcIjtcbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNS4wXG4gKi9cbmNvbnN0IEFUVFJJQlVURV9FWFBPUlRQQVJUUyA9IFwiZXhwb3J0cGFydHNcIjtcbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNS4wXG4gKi9cbmNvbnN0IEFUVFJJQlVURV9ISURERU4gPSBcImhpZGRlblwiO1xuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgZ2V0R2xvYmFsRnVuY3Rpb24gfSBmcm9tIFwiLi4vdHlwZXMvZ2xvYmFsLm1qc1wiO1xuaW1wb3J0IHsgVG9rZW5MaXN0IH0gZnJvbSBcIi4uL3R5cGVzL3Rva2VubGlzdC5tanNcIjtcbmltcG9ydCB7IHZhbGlkYXRlSW5zdGFuY2UsIHZhbGlkYXRlU3RyaW5nLCB2YWxpZGF0ZVN5bWJvbCB9IGZyb20gXCIuLi90eXBlcy92YWxpZGF0ZS5tanNcIjtcbmltcG9ydCB7IEFUVFJJQlVURV9PQkpFQ1RMSU5LIH0gZnJvbSBcIi4vY29uc3RhbnRzLm1qc1wiO1xuXG5leHBvcnQge1xuICAgIGZpbmRDbG9zZXN0T2JqZWN0TGluayxcbiAgICBhZGRUb09iamVjdExpbmssXG4gICAgcmVtb3ZlT2JqZWN0TGluayxcbiAgICBoYXNPYmplY3RMaW5rLFxuICAgIGdldExpbmtlZE9iamVjdHMsXG4gICAgdG9nZ2xlQXR0cmlidXRlVG9rZW4sXG4gICAgYWRkQXR0cmlidXRlVG9rZW4sXG4gICAgcmVtb3ZlQXR0cmlidXRlVG9rZW4sXG4gICAgY29udGFpbnNBdHRyaWJ1dGVUb2tlbixcbiAgICByZXBsYWNlQXR0cmlidXRlVG9rZW4sXG4gICAgY2xlYXJBdHRyaWJ1dGVUb2tlbnMsXG4gICAgZmluZENsb3Nlc3RCeUF0dHJpYnV0ZSxcbiAgICBmaW5kQ2xvc2VzdEJ5Q2xhc3MsXG59O1xuXG4vKipcbiAqIEdldCB0aGUgY2xvc2VzdCBvYmplY3QgbGluayBvZiBhIG5vZGVcbiAqXG4gKiBpZiBhIG5vZGUgaXMgc3BlY2lmaWVkIHdpdGhvdXQgYSBvYmplY3QgbGluaywgYSByZWN1cnNpdmUgc2VhcmNoIHVwd2FyZHMgaXMgcGVyZm9ybWVkIHVudGlsIHRoZSBjb3JyZXNwb25kaW5nXG4gKiBvYmplY3QgbGluayBpcyBmb3VuZCwgb3IgdW5kZWZpbmVkIGlzIHJldHVybmVkLlxuICpcbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVsZW1lbnRcbiAqIEByZXR1cm4ge0hUTUxFbGVtZW50fHVuZGVmaW5lZH1cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMTAuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgSFRNTEVsZW1lbnRcbiAqL1xuZnVuY3Rpb24gZmluZENsb3Nlc3RPYmplY3RMaW5rKGVsZW1lbnQpIHtcbiAgICByZXR1cm4gZmluZENsb3Nlc3RCeUF0dHJpYnV0ZShlbGVtZW50LCBBVFRSSUJVVEVfT0JKRUNUTElOSyk7XG59XG5cbi8qKlxuICogQWRkcyBhIGNsYXNzIGF0dHJpYnV0ZSB0byBhbiBlbGVtZW50LlxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuOS4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0ge1N5bWJvbH0gc3ltYm9sXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5mdW5jdGlvbiBhZGRUb09iamVjdExpbmsoZWxlbWVudCwgc3ltYm9sLCBvYmplY3QpIHtcbiAgICB2YWxpZGF0ZUluc3RhbmNlKGVsZW1lbnQsIEhUTUxFbGVtZW50KTtcbiAgICB2YWxpZGF0ZVN5bWJvbChzeW1ib2wpO1xuXG4gICAgaWYgKGVsZW1lbnQ/LltzeW1ib2xdID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZWxlbWVudFtzeW1ib2xdID0gbmV3IFNldCgpO1xuICAgIH1cblxuICAgIGFkZEF0dHJpYnV0ZVRva2VuKGVsZW1lbnQsIEFUVFJJQlVURV9PQkpFQ1RMSU5LLCBzeW1ib2wudG9TdHJpbmcoKSk7XG4gICAgZWxlbWVudFtzeW1ib2xdLmFkZChvYmplY3QpO1xuICAgIHJldHVybiBlbGVtZW50O1xufVxuXG4vKipcbiAqIFJlbW92ZXMgYW4gb2JqZWN0IGZyb20gYW4gZWxlbWVudFxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuOS4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0ge1N5bWJvbH0gc3ltYm9sXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5mdW5jdGlvbiByZW1vdmVPYmplY3RMaW5rKGVsZW1lbnQsIHN5bWJvbCkge1xuICAgIHZhbGlkYXRlSW5zdGFuY2UoZWxlbWVudCwgSFRNTEVsZW1lbnQpO1xuICAgIHZhbGlkYXRlU3ltYm9sKHN5bWJvbCk7XG5cbiAgICBpZiAoZWxlbWVudD8uW3N5bWJvbF0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gZWxlbWVudDtcbiAgICB9XG5cbiAgICByZW1vdmVBdHRyaWJ1dGVUb2tlbihlbGVtZW50LCBBVFRSSUJVVEVfT0JKRUNUTElOSywgc3ltYm9sLnRvU3RyaW5nKCkpO1xuICAgIGRlbGV0ZSBlbGVtZW50W3N5bWJvbF07XG4gICAgcmV0dXJuIGVsZW1lbnQ7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIGFuIGVsZW1lbnQgaGFzIGFuIG9iamVjdCBsaW5rXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS45LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7U3ltYm9sfSBzeW1ib2xcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIGhhc09iamVjdExpbmsoZWxlbWVudCwgc3ltYm9sKSB7XG4gICAgdmFsaWRhdGVJbnN0YW5jZShlbGVtZW50LCBIVE1MRWxlbWVudCk7XG4gICAgdmFsaWRhdGVTeW1ib2woc3ltYm9sKTtcblxuICAgIGlmIChlbGVtZW50Py5bc3ltYm9sXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gY29udGFpbnNBdHRyaWJ1dGVUb2tlbihlbGVtZW50LCBBVFRSSUJVVEVfT0JKRUNUTElOSywgc3ltYm9sLnRvU3RyaW5nKCkpO1xufVxuXG4vKipcbiAqIFRoZSBPYmplY3RMaW5rIGNhbiBiZSB1c2VkIHRvIGF0dGFjaCBvYmplY3RzIHRvIEhUTUxFbGVtZW50cy4gVGhlIGVsZW1lbnRzIGFyZSBrZXB0IGluIGEgc2V0IHVuZGVyIGEgdW5pcXVlXG4gKiBzeW1ib2wgYW5kIGNhbiBiZSByZWFkIHZpYSBhbiBpdGVyYXRvciB7QHNlZSB7QGxpbmsgZ2V0TGlua2VkT2JqZWN0c319LlxuICpcbiAqIEluIGFkZGl0aW9uLCBlbGVtZW50cyB3aXRoIGFuIG9iamVjdExpbmsgcmVjZWl2ZSB0aGUgYXR0cmlidXRlIGBkYXRhLW1vbnN0ZXItb2JqZWN0bGlua2AuXG4gKlxuICogV2l0aCB0aGUgbWV0aG9kICB7QHNlZSB7QGxpbmsgYWRkVG9PYmplY3RMaW5rfX0gdGhlIG9iamVjdHMgY2FuIGJlIGFkZGVkLlxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuOS4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0ge1N5bWJvbH0gc3ltYm9sXG4gKiBAcmV0dXJuIHtJdGVyYXRvcn1cbiAqIEB0aHJvd3Mge0Vycm9yfSB0aGVyZSBpcyBubyBvYmplY3QgbGluayBmb3Igc3ltYm9sXG4gKi9cbmZ1bmN0aW9uIGdldExpbmtlZE9iamVjdHMoZWxlbWVudCwgc3ltYm9sKSB7XG4gICAgdmFsaWRhdGVJbnN0YW5jZShlbGVtZW50LCBIVE1MRWxlbWVudCk7XG4gICAgdmFsaWRhdGVTeW1ib2woc3ltYm9sKTtcblxuICAgIGlmIChlbGVtZW50Py5bc3ltYm9sXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgdGhlcmUgaXMgbm8gb2JqZWN0IGxpbmsgZm9yICR7c3ltYm9sLnRvU3RyaW5nKCl9YCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGVsZW1lbnQ/LltzeW1ib2xdW1N5bWJvbC5pdGVyYXRvcl0oKTtcbn1cblxuLyoqXG4gKiBXaXRoIHRoaXMgbWV0aG9kIHRva2VucyBpbiBhbiBhdHRyaWJ1dGUgY2FuIGJlIHN3aXRjaGVkIG9uIG9yIG9mZi4gRm9yIGV4YW1wbGUsIGNsYXNzZXMgY2FuIGJlIHN3aXRjaGVkIG9uIGFuZCBvZmYgaW4gdGhlIGVsZW1lbnRzIGNsYXNzIGF0dHJpYnV0ZS5cbiAqXG4gKiBUb2tlbnMgYXJlIGFsd2F5cyBzZXBhcmF0ZWQgYnkgYSBzcGFjZS5cbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjkuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHtzdHJpbmd9IGtleVxuICogQHBhcmFtIHtzdHJpbmd9IHRva2VuXG4gKiBAcmV0dXJuIHtIVE1MRWxlbWVudH1cbiAqL1xuZnVuY3Rpb24gdG9nZ2xlQXR0cmlidXRlVG9rZW4oZWxlbWVudCwga2V5LCB0b2tlbikge1xuICAgIHZhbGlkYXRlSW5zdGFuY2UoZWxlbWVudCwgSFRNTEVsZW1lbnQpO1xuICAgIHZhbGlkYXRlU3RyaW5nKHRva2VuKTtcbiAgICB2YWxpZGF0ZVN0cmluZyhrZXkpO1xuXG4gICAgaWYgKCFlbGVtZW50Lmhhc0F0dHJpYnV0ZShrZXkpKSB7XG4gICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKGtleSwgdG9rZW4pO1xuICAgICAgICByZXR1cm4gZWxlbWVudDtcbiAgICB9XG5cbiAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShrZXksIG5ldyBUb2tlbkxpc3QoZWxlbWVudC5nZXRBdHRyaWJ1dGUoa2V5KSkudG9nZ2xlKHRva2VuKS50b1N0cmluZygpKTtcblxuICAgIHJldHVybiBlbGVtZW50O1xufVxuXG4vKipcbiAqIFRoaXMgbWV0aG9kIGNhbiBiZSB1c2VkIHRvIGFkZCBhIHRva2VuIHRvIGFuIGF0dHJpYnV0ZS4gVG9rZW5zIGFyZSBhbHdheXMgc2VwYXJhdGVkIGJ5IGEgc3BhY2UuXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS45LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXlcbiAqIEBwYXJhbSB7c3RyaW5nfSB0b2tlblxuICogQHJldHVybiB7SFRNTEVsZW1lbnR9XG4gKi9cbmZ1bmN0aW9uIGFkZEF0dHJpYnV0ZVRva2VuKGVsZW1lbnQsIGtleSwgdG9rZW4pIHtcbiAgICB2YWxpZGF0ZUluc3RhbmNlKGVsZW1lbnQsIEhUTUxFbGVtZW50KTtcbiAgICB2YWxpZGF0ZVN0cmluZyh0b2tlbik7XG4gICAgdmFsaWRhdGVTdHJpbmcoa2V5KTtcblxuICAgIGlmICghZWxlbWVudC5oYXNBdHRyaWJ1dGUoa2V5KSkge1xuICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShrZXksIHRva2VuKTtcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgfVxuXG4gICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoa2V5LCBuZXcgVG9rZW5MaXN0KGVsZW1lbnQuZ2V0QXR0cmlidXRlKGtleSkpLmFkZCh0b2tlbikudG9TdHJpbmcoKSk7XG5cbiAgICByZXR1cm4gZWxlbWVudDtcbn1cblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSB1c2VkIHRvIHJlbW92ZSB0b2tlbnMgZnJvbSBhbiBhdHRyaWJ1dGUuXG4gKlxuICogVG9rZW5zIGFyZSBhbHdheXMgc2VwYXJhdGVkIGJ5IGEgc3BhY2UuXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS45LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXlcbiAqIEBwYXJhbSB7c3RyaW5nfSB0b2tlblxuICogQHJldHVybiB7SFRNTEVsZW1lbnR9XG4gKi9cbmZ1bmN0aW9uIHJlbW92ZUF0dHJpYnV0ZVRva2VuKGVsZW1lbnQsIGtleSwgdG9rZW4pIHtcbiAgICB2YWxpZGF0ZUluc3RhbmNlKGVsZW1lbnQsIEhUTUxFbGVtZW50KTtcbiAgICB2YWxpZGF0ZVN0cmluZyh0b2tlbik7XG4gICAgdmFsaWRhdGVTdHJpbmcoa2V5KTtcblxuICAgIGlmICghZWxlbWVudC5oYXNBdHRyaWJ1dGUoa2V5KSkge1xuICAgICAgICByZXR1cm4gZWxlbWVudDtcbiAgICB9XG5cbiAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShrZXksIG5ldyBUb2tlbkxpc3QoZWxlbWVudC5nZXRBdHRyaWJ1dGUoa2V5KSkucmVtb3ZlKHRva2VuKS50b1N0cmluZygpKTtcblxuICAgIHJldHVybiBlbGVtZW50O1xufVxuXG4vKipcbiAqIFRoaXMgbWV0aG9kIGNhbiBiZSB1c2VkIHRvIGRldGVybWluZSB3aGV0aGVyIGFuIGF0dHJpYnV0ZSBoYXMgYSB0b2tlbi5cbiAqXG4gKiBUb2tlbnMgYXJlIGFsd2F5cyBzZXBhcmF0ZWQgYnkgYSBzcGFjZS5cbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjkuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHtzdHJpbmd9IGtleVxuICogQHBhcmFtIHtzdHJpbmd9IHRva2VuXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5mdW5jdGlvbiBjb250YWluc0F0dHJpYnV0ZVRva2VuKGVsZW1lbnQsIGtleSwgdG9rZW4pIHtcbiAgICB2YWxpZGF0ZUluc3RhbmNlKGVsZW1lbnQsIEhUTUxFbGVtZW50KTtcbiAgICB2YWxpZGF0ZVN0cmluZyh0b2tlbik7XG4gICAgdmFsaWRhdGVTdHJpbmcoa2V5KTtcblxuICAgIGlmICghZWxlbWVudC5oYXNBdHRyaWJ1dGUoa2V5KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBUb2tlbkxpc3QoZWxlbWVudC5nZXRBdHRyaWJ1dGUoa2V5KSkuY29udGFpbnModG9rZW4pO1xufVxuXG4vKipcbiAqIFRva2VucyBhcmUgYWx3YXlzIHNlcGFyYXRlZCBieSBhIHNwYWNlLlxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuOS4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5XG4gKiBAcGFyYW0ge3N0cmluZ30gZnJvbVxuICogQHBhcmFtIHtzdHJpbmd9IHRvXG4gKiBAcmV0dXJuIHtIVE1MRWxlbWVudH1cbiAqL1xuZnVuY3Rpb24gcmVwbGFjZUF0dHJpYnV0ZVRva2VuKGVsZW1lbnQsIGtleSwgZnJvbSwgdG8pIHtcbiAgICB2YWxpZGF0ZUluc3RhbmNlKGVsZW1lbnQsIEhUTUxFbGVtZW50KTtcbiAgICB2YWxpZGF0ZVN0cmluZyhmcm9tKTtcbiAgICB2YWxpZGF0ZVN0cmluZyh0byk7XG4gICAgdmFsaWRhdGVTdHJpbmcoa2V5KTtcblxuICAgIGlmICghZWxlbWVudC5oYXNBdHRyaWJ1dGUoa2V5KSkge1xuICAgICAgICByZXR1cm4gZWxlbWVudDtcbiAgICB9XG5cbiAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShrZXksIG5ldyBUb2tlbkxpc3QoZWxlbWVudC5nZXRBdHRyaWJ1dGUoa2V5KSkucmVwbGFjZShmcm9tLCB0bykudG9TdHJpbmcoKSk7XG5cbiAgICByZXR1cm4gZWxlbWVudDtcbn1cblxuLyoqXG4gKiBUb2tlbnMgYXJlIGFsd2F5cyBzZXBhcmF0ZWQgYnkgYSBzcGFjZS5cbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjkuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHtzdHJpbmd9IGtleVxuICogQHJldHVybiB7SFRNTEVsZW1lbnR9XG4gKi9cbmZ1bmN0aW9uIGNsZWFyQXR0cmlidXRlVG9rZW5zKGVsZW1lbnQsIGtleSkge1xuICAgIHZhbGlkYXRlSW5zdGFuY2UoZWxlbWVudCwgSFRNTEVsZW1lbnQpO1xuICAgIHZhbGlkYXRlU3RyaW5nKGtleSk7XG5cbiAgICBpZiAoIWVsZW1lbnQuaGFzQXR0cmlidXRlKGtleSkpIHtcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgfVxuXG4gICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoa2V5LCBcIlwiKTtcblxuICAgIHJldHVybiBlbGVtZW50O1xufVxuXG4vKipcbiAqIFRoaXMgZnVuY3Rpb24gc2VhcmNoZXMsIHN0YXJ0aW5nIGZyb20gYW4gYEhUTUxFbGVtZW1lbnRgLCBmb3IgdGhlIG5leHQgZWxlbWVudCB0aGF0IGhhcyBhIGNlcnRhaW4gYXR0cmlidXRlLlxuICpcbiAqIGBgYGh0bWxcbiAqIDxkaXYgZGF0YS1teS1hdHRyaWJ1dGU9XCIyXCIgaWQ9XCIyXCI+XG4gKiAgICAgPGRpdiBpZD1cIjFcIj48L2Rpdj5cbiAqIDwvZGl2PlxuICogYGBgXG4gKlxuICogYGBgamF2YXNjcmlwdFxuICogLy8gaWYgbm8gdmFsdWUgaXMgc3BlY2lmaWVkICh1bmRlZmluZWQpLCB0aGVuIG9ubHkgdGhlIGF0dHJpYnV0ZSBpcyBjaGVja2VkLlxuICogZmluZENsb3Nlc3RCeUF0dHJpYnV0ZShkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnMScpLCdkYXRhLW15LWF0dHJpYnV0ZScpOyAvLyBcdTIxQTYgbm9kZSB3aXRoIGlkIDJcbiAqIGZpbmRDbG9zZXN0QnlBdHRyaWJ1dGUoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJzInKSwnZGF0YS1teS1hdHRyaWJ1dGUnKTsgLy8gXHUyMUE2IG5vZGUgd2l0aCBpZCAyXG4gKlxuICogLy8gaWYgYSB2YWx1ZSBpcyBzcGVjaWZpZWQsIGZvciBleGFtcGxlIGFuIGVtcHR5IHN0cmluZywgdGhlbiB0aGUgbmFtZSBhbmQgdGhlIHZhbHVlIGFyZSBjaGVja2VkLlxuICogZmluZENsb3Nlc3RCeUF0dHJpYnV0ZShkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnMScpLCdkYXRhLW15LWF0dHJpYnV0ZScsICcnKTsgIC8vIFx1MjFBNiB1bmRlZmluZWRcbiAqIGZpbmRDbG9zZXN0QnlBdHRyaWJ1dGUoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJzEnKSwnZGF0YS1teS1hdHRyaWJ1dGUnLCAnMicpOyAvLyBcdTIxQTYgbm9kZSB3aXRoIGlkIDJcbiAqIGBgYFxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMTQuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHtzdHJpbmd9IGtleVxuICogQHBhcmFtIHtzdHJpbmd8dW5kZWZpbmVkfSB2YWx1ZVxuICogQHJldHVybiB7SFRNTEVsZW1lbnR8dW5kZWZpbmVkfVxuICogQHN1bW1hcnkgZmluZCBjbG9zZXN0IG5vZGVcbiAqL1xuZnVuY3Rpb24gZmluZENsb3Nlc3RCeUF0dHJpYnV0ZShlbGVtZW50LCBrZXksIHZhbHVlKSB7XG4gICAgdmFsaWRhdGVJbnN0YW5jZShlbGVtZW50LCBnZXRHbG9iYWxGdW5jdGlvbihcIkhUTUxFbGVtZW50XCIpKTtcblxuICAgIGlmIChlbGVtZW50Lmhhc0F0dHJpYnV0ZShrZXkpKSB7XG4gICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gZWxlbWVudDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlbGVtZW50LmdldEF0dHJpYnV0ZShrZXkpID09PSB2YWx1ZSkge1xuICAgICAgICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBsZXQgc2VsZWN0b3IgPSB2YWxpZGF0ZVN0cmluZyhrZXkpO1xuICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSBzZWxlY3RvciArPSBgPSR7dmFsaWRhdGVTdHJpbmcodmFsdWUpfWA7XG4gICAgbGV0IHJlc3VsdCA9IGVsZW1lbnQuY2xvc2VzdChgWyR7c2VsZWN0b3J9XWApO1xuICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFRoaXMgZnVuY3Rpb24gc2VhcmNoZXMsIHN0YXJ0aW5nIGZyb20gYW4gYEhUTUxFbGVtZW1lbnRgLCBmb3IgdGhlIG5leHQgZWxlbWVudCB0aGF0IGhhcyBhIGNlcnRhaW4gYXR0cmlidXRlLlxuICpcbiAqIGBgYGh0bWxcbiAqIDxkaXYgY2xhc3M9XCJteWNsYXNzXCIgaWQ9XCIyXCI+XG4gKiAgICAgPGRpdiBpZD1cIjFcIj48L2Rpdj5cbiAqIDwvZGl2PlxuICogYGBgXG4gKlxuICogYGBgamF2YXNjcmlwdFxuICogLy8gaWYgbm8gdmFsdWUgaXMgc3BlY2lmaWVkICh1bmRlZmluZWQpLCB0aGVuIG9ubHkgdGhlIGF0dHJpYnV0ZSBpcyBjaGVja2VkLlxuICogZmluZENsb3Nlc3RCeUNsYXNzKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCcxJyksJ215Y2xhc3MnKTsgLy8gXHUyMUE2IG5vZGUgd2l0aCBpZCAyXG4gKiBmaW5kQ2xvc2VzdEJ5Q2xhc3MoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJzInKSwnbXljbGFzcycpOyAvLyBcdTIxQTYgbm9kZSB3aXRoIGlkIDJcbiAqIGBgYFxuICpcbiAqIGBgYFxuICogPHNjcmlwdCB0eXBlPVwibW9kdWxlXCI+XG4gKiBpbXBvcnQge2ZpbmRDbG9zZXN0QnlDbGFzc30gZnJvbSAnQHNjaHVrYWkvbW9uc3Rlci9zb3VyY2UvZG9tL2F0dHJpYnV0ZXMubWpzJztcbiAqIGZpbmRDbG9zZXN0QnlDbGFzcygpO1xuICogPC9zY3JpcHQ+XG4gKiBgYGBcbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI3LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBjbGFzc05hbWVcbiAqIEByZXR1cm4ge0hUTUxFbGVtZW50fHVuZGVmaW5lZH1cbiAqIEBzdW1tYXJ5IGZpbmQgY2xvc2VzdCBub2RlXG4gKi9cbmZ1bmN0aW9uIGZpbmRDbG9zZXN0QnlDbGFzcyhlbGVtZW50LCBjbGFzc05hbWUpIHtcbiAgICB2YWxpZGF0ZUluc3RhbmNlKGVsZW1lbnQsIGdldEdsb2JhbEZ1bmN0aW9uKFwiSFRNTEVsZW1lbnRcIikpO1xuXG4gICAgaWYgKGVsZW1lbnQ/LmNsYXNzTGlzdD8uY29udGFpbnModmFsaWRhdGVTdHJpbmcoY2xhc3NOYW1lKSkpIHtcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgfVxuXG4gICAgbGV0IHJlc3VsdCA9IGVsZW1lbnQuY2xvc2VzdChgLiR7Y2xhc3NOYW1lfWApO1xuICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIHJldHVybiB1bmRlZmluZWQ7XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBCYXNlIH0gZnJvbSBcIi4vYmFzZS5tanNcIjtcbmltcG9ydCB7IGluc3RhbmNlU3ltYm9sIH0gZnJvbSBcIi4uL2NvbnN0YW50cy5tanNcIjtcbmV4cG9ydCB7IFN0YWNrIH07XG5cbi8qKlxuICogWW91IGNhbiBjYWxsIHRoZSBtZXRob2QgdmlhIHRoZSBtb25zdGVyIG5hbWVzcGFjZSBgbmV3IE1vbnN0ZXIuVHlwZXMuUXVldWUoKWAuXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS40LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UeXBlc1xuICovXG5jbGFzcyBTdGFjayBleHRlbmRzIEJhc2Uge1xuICAgIC8qKlxuICAgICAqXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMuZGF0YSA9IFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgYGluc3RhbmNlb2ZgIG9wZXJhdG9yLlxuICAgICAqIEByZXR1cm5zIHtzeW1ib2x9XG4gICAgICogQHNpbmNlIDIuMS4wXG4gICAgICovXG4gICAgc3RhdGljIGdldCBbaW5zdGFuY2VTeW1ib2xdKCkge1xuICAgICAgICByZXR1cm4gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvdHlwZXMvc3RhY2tcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBpc0VtcHR5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5kYXRhLmxlbmd0aCA9PT0gMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBsb29rcyBhdCB0aGUgb2JqZWN0IGF0IHRoZSB0b3Agb2YgdGhpcyBzdGFjayB3aXRob3V0IHJlbW92aW5nIGl0IGZyb20gdGhlIHN0YWNrLlxuICAgICAqXG4gICAgICogQHJldHVybiB7Kn1cbiAgICAgKi9cbiAgICBwZWVrKCkge1xuICAgICAgICBpZiAodGhpcy5pc0VtcHR5KCkpIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcy5kYXRhPy5bdGhpcy5kYXRhLmxlbmd0aCAtIDFdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHB1c2hlcyBhbiBpdGVtIG9udG8gdGhlIHRvcCBvZiB0aGlzIHN0YWNrLlxuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZVxuICAgICAqIEByZXR1cm5zIHtRdWV1ZX1cbiAgICAgKi9cbiAgICBwdXNoKHZhbHVlKSB7XG4gICAgICAgIHRoaXMuZGF0YS5wdXNoKHZhbHVlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogcmVtb3ZlIGFsbCBlbnRyaWVzXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7UXVldWV9XG4gICAgICovXG4gICAgY2xlYXIoKSB7XG4gICAgICAgIHRoaXMuZGF0YSA9IFtdO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiByZW1vdmVzIHRoZSBvYmplY3QgYXQgdGhlIHRvcCBvZiB0aGlzIHN0YWNrIGFuZCByZXR1cm5zXG4gICAgICogdGhhdCBvYmplY3QgYXMgdGhlIHZhbHVlIG9mIHRoaXMgZnVuY3Rpb24uIGlzIHRoZSBzdGFjayBlbXB0eVxuICAgICAqIHRoZSByZXR1cm4gdmFsdWUgaXMgdW5kZWZpbmVkLlxuICAgICAqXG4gICAgICogQHJldHVybiB7Kn1cbiAgICAgKi9cbiAgICBwb3AoKSB7XG4gICAgICAgIGlmICh0aGlzLmlzRW1wdHkoKSkge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5kYXRhLnBvcCgpO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IEJhc2UgfSBmcm9tIFwiLi4vdHlwZXMvYmFzZS5tanNcIjtcbmltcG9ydCB7IGlzQXJyYXksIGlzSW50ZWdlciwgaXNPYmplY3QsIGlzUHJpbWl0aXZlLCBpc1N0cmluZyB9IGZyb20gXCIuLi90eXBlcy9pcy5tanNcIjtcbmltcG9ydCB7IFN0YWNrIH0gZnJvbSBcIi4uL3R5cGVzL3N0YWNrLm1qc1wiO1xuaW1wb3J0IHsgdmFsaWRhdGVJbnRlZ2VyLCB2YWxpZGF0ZUJvb2xlYW4sIHZhbGlkYXRlU3RyaW5nIH0gZnJvbSBcIi4uL3R5cGVzL3ZhbGlkYXRlLm1qc1wiO1xuXG5leHBvcnQgeyBQYXRoZmluZGVyLCBERUxJTUlURVIsIFdJTERDQVJEIH07XG5cbi8qKlxuICogcGF0aCBzZXBhcmF0b3JcbiAqXG4gKiBAcHJpdmF0ZVxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuY29uc3QgREVMSU1JVEVSID0gXCIuXCI7XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEB0eXBlIHtzdHJpbmd9XG4gKi9cbmNvbnN0IFdJTERDQVJEID0gXCIqXCI7XG5cbi8qKlxuICogUGF0aGZpbmRlciBpcyBhIGNsYXNzIHRvIGZpbmQgYSBwYXRoIHRvIGFuIG9iamVjdC5cbiAqXG4gKiBXaXRoIHRoZSBoZWxwIG9mIHRoZSBwYXRoZmluZGVyLCB2YWx1ZXMgY2FuIGJlIHJlYWQgYW5kIHdyaXR0ZW4gZnJvbSBhbiBvYmplY3QgY29uc3RydWN0LlxuICpcbiAqIGBgYFxuICogbmV3IFBhdGhmaW5kZXIoe1xuICogYToge1xuICogICAgIGI6IHtcbiAqICAgICAgICAgZjogW1xuICogICAgICAgICAgICAge1xuICogICAgICAgICAgICAgICAgIGc6IGZhbHNlLFxuICogICAgICAgICAgICAgfVxuICogICAgICAgICBdLFxuICogICAgIH1cbiAqIH1cbiAqIH0pLmdldFZpYShcImEuYi5mLjAuZ1wiKTsgLy8gXHUyMUE2IGZhbHNlXG4gKiBgYGBcbiAqXG4gKiBpZiBhIHZhbHVlIGlzIG5vdCBwcmVzZW50IG9yIGhhcyB0aGUgd3JvbmcgdHlwZSwgYSBjb3JyZXNwb25kaW5nIGV4Y2VwdGlvbiBpcyB0aHJvd24uXG4gKlxuICogYGBgXG4gKiBuZXcgUGF0aGZpbmRlcih7fSkuZ2V0VmlhKFwiYS5iLmYuMC5nXCIpOyAvLyBcdTIxQTYgRXJyb3JcbiAqIGBgYFxuICpcbiAqIFRoZSBgUGF0aGZpbmRlci5leGlzdHMoKWAgbWV0aG9kIGNhbiBiZSB1c2VkIHRvIGNoZWNrIHdoZXRoZXIgYWNjZXNzIHRvIHRoZSBwYXRoIGlzIHBvc3NpYmxlLlxuICpcbiAqIGBgYFxuICogbmV3IFBhdGhmaW5kZXIoe30pLmV4aXN0cyhcImEuYi5mLjAuZ1wiKTsgLy8gXHUyMUE2IGZhbHNlXG4gKiBgYGBcbiAqXG4gKiBwYXRoZmluZGVyIGNhbiBhbHNvIGJlIHVzZWQgdG8gYnVpbGQgb2JqZWN0IHN0cnVjdHVyZXMuIHRvIGRvIHRoaXMsIHRoZSBgUGF0aGZpbmRlci5zZXRWaWEoKWAgbWV0aG9kIG11c3QgYmUgdXNlZC5cbiAqXG4gKiBgYGBcbiAqIG9iaiA9IHt9O1xuICogbmV3IFBhdGhmaW5kZXIob2JqKS5zZXRWaWEoJ2EuYi4wLmMnLCB0cnVlKTsgLy8gXHUyMUE2IHthOntiOlt7Yzp0cnVlfV19fVxuICogYGBgXG4gKlxuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL2RhdGEvcGF0aGZpbmRlci0xLm1qc1xuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL2RhdGEvcGF0aGZpbmRlci0yLm1qc1xuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS40LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5EYXRhXG4gKi9cbmNsYXNzIFBhdGhmaW5kZXIgZXh0ZW5kcyBCYXNlIHtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2FycmF5fG9iamVjdHxNYXB8U2V0fSB2YWx1ZVxuICAgICAqIEBzaW5jZSAxLjQuMFxuICAgICAqIEB0aHJvd3MgIHtFcnJvcn0gdGhlIHBhcmFtZXRlciBtdXN0IG5vdCBiZSBhIHNpbXBsZSB0eXBlXG4gICAgICoqL1xuICAgIGNvbnN0cnVjdG9yKG9iamVjdCkge1xuICAgICAgICBzdXBlcigpO1xuXG4gICAgICAgIGlmIChpc1ByaW1pdGl2ZShvYmplY3QpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0aGUgcGFyYW1ldGVyIG11c3Qgbm90IGJlIGEgc2ltcGxlIHR5cGVcIik7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLm9iamVjdCA9IG9iamVjdDtcbiAgICAgICAgdGhpcy53aWxkQ2FyZCA9IFdJTERDQVJEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHNldCB3aWxkY2FyZFxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHdpbGRjYXJkXG4gICAgICogQHJldHVybiB7UGF0aGZpbmRlcn1cbiAgICAgKiBAc2luY2UgMS43LjBcbiAgICAgKi9cbiAgICBzZXRXaWxkQ2FyZCh3aWxkY2FyZCkge1xuICAgICAgICB2YWxpZGF0ZVN0cmluZyh3aWxkY2FyZCk7XG4gICAgICAgIHRoaXMud2lsZENhcmQgPSB3aWxkY2FyZDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xhcnJheX0gcGF0aFxuICAgICAqIEBzaW5jZSAxLjQuMFxuICAgICAqIEByZXR1cm5zIHsqfVxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdW5zdXBwb3J0ZWQgdHlwZVxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSB0aGUgam91cm5leSBpcyBub3QgYXQgaXRzIGVuZFxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgc3RyaW5nXG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYW4gaW50ZWdlclxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSB1bnN1cHBvcnRlZCBhY3Rpb24gZm9yIHRoaXMgZGF0YSB0eXBlXG4gICAgICovXG4gICAgZ2V0VmlhKHBhdGgpIHtcbiAgICAgICAgcmV0dXJuIGdldFZhbHVlVmlhUGF0aC5jYWxsKHRoaXMsIHRoaXMub2JqZWN0LCBwYXRoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfGFycmF5fSBwYXRoXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZVxuICAgICAqIEByZXR1cm5zIHtQYXRoZmluZGVyfVxuICAgICAqIEBzaW5jZSAxLjQuMFxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdW5zdXBwb3J0ZWQgdHlwZVxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgc3RyaW5nXG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYW4gaW50ZWdlclxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSB1bnN1cHBvcnRlZCBhY3Rpb24gZm9yIHRoaXMgZGF0YSB0eXBlXG4gICAgICovXG4gICAgc2V0VmlhKHBhdGgsIHZhbHVlKSB7XG4gICAgICAgIHNldFZhbHVlVmlhUGF0aC5jYWxsKHRoaXMsIHRoaXMub2JqZWN0LCBwYXRoLCB2YWx1ZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERlbGV0ZSBWaWEgUGF0aFxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd8YXJyYXl9IHBhdGhcbiAgICAgKiBAcmV0dXJucyB7UGF0aGZpbmRlcn1cbiAgICAgKiBAc2luY2UgMS42LjBcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHVuc3VwcG9ydGVkIHR5cGVcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIHN0cmluZ1xuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGFuIGludGVnZXJcbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gdW5zdXBwb3J0ZWQgYWN0aW9uIGZvciB0aGlzIGRhdGEgdHlwZVxuICAgICAqL1xuICAgIGRlbGV0ZVZpYShwYXRoKSB7XG4gICAgICAgIGRlbGV0ZVZhbHVlVmlhUGF0aC5jYWxsKHRoaXMsIHRoaXMub2JqZWN0LCBwYXRoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xhcnJheX0gcGF0aFxuICAgICAqIEByZXR1cm4ge2Jvb2x9XG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSB1bnN1cHBvcnRlZCB0eXBlXG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYSBzdHJpbmdcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhbiBpbnRlZ2VyXG4gICAgICogQHNpbmNlIDEuNC4wXG4gICAgICovXG4gICAgZXhpc3RzKHBhdGgpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGdldFZhbHVlVmlhUGF0aC5jYWxsKHRoaXMsIHRoaXMub2JqZWN0LCBwYXRoLCB0cnVlKTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9IGNhdGNoIChlKSB7fVxuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG59XG5cbi8qKlxuICpcbiAqIEBwYXJhbSB7Kn0gc3ViamVjdFxuICogQHBhcmFtIHtzdHJpbmd8YXJyYXl9IHBhdGhcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gY2hlY2tcbiAqIEByZXR1cm4ge01hcH1cbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdW5zdXBwb3J0ZWQgdHlwZVxuICogQHRocm93cyB7RXJyb3J9IHRoZSBqb3VybmV5IGlzIG5vdCBhdCBpdHMgZW5kXG4gKiBAdGhyb3dzIHtFcnJvcn0gdW5zdXBwb3J0ZWQgYWN0aW9uIGZvciB0aGlzIGRhdGEgdHlwZVxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gaXRlcmF0ZShzdWJqZWN0LCBwYXRoLCBjaGVjaykge1xuICAgIGlmIChjaGVjayA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNoZWNrID0gZmFsc2U7XG4gICAgfVxuICAgIHZhbGlkYXRlQm9vbGVhbihjaGVjayk7XG5cbiAgICBjb25zdCByZXN1bHQgPSBuZXcgTWFwKCk7XG5cbiAgICBpZiAoaXNBcnJheShwYXRoKSkge1xuICAgICAgICBwYXRoID0gcGF0aC5qb2luKERFTElNSVRFUik7XG4gICAgfVxuXG4gICAgaWYgKGlzT2JqZWN0KHN1YmplY3QpIHx8IGlzQXJyYXkoc3ViamVjdCkpIHtcbiAgICAgICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoc3ViamVjdCkpIHtcbiAgICAgICAgICAgIHJlc3VsdC5zZXQoa2V5LCBnZXRWYWx1ZVZpYVBhdGguY2FsbCh0aGlzLCB2YWx1ZSwgcGF0aCwgY2hlY2spKTtcbiAgICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAgIGxldCBrZXkgPSBwYXRoLnNwbGl0KERFTElNSVRFUikuc2hpZnQoKTtcbiAgICAgICAgcmVzdWx0LnNldChrZXksIGdldFZhbHVlVmlhUGF0aC5jYWxsKHRoaXMsIHN1YmplY3QsIHBhdGgsIGNoZWNrKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKlxuICogQHBhcmFtIHsqfSBzdWJqZWN0XG4gKiBAcGFyYW0gW3N0cmluZ3xhcnJheX0gcGF0aFxuICogQHBhcmFtIFtib29sZWFufSBjaGVja1xuICogQHJldHVybnMgeyp9XG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHVuc3VwcG9ydGVkIHR5cGVcbiAqIEB0aHJvd3Mge0Vycm9yfSB0aGUgam91cm5leSBpcyBub3QgYXQgaXRzIGVuZFxuICogQHRocm93cyB7RXJyb3J9IHVuc3VwcG9ydGVkIGFjdGlvbiBmb3IgdGhpcyBkYXRhIHR5cGVcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGdldFZhbHVlVmlhUGF0aChzdWJqZWN0LCBwYXRoLCBjaGVjaykge1xuICAgIGlmIChjaGVjayA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNoZWNrID0gZmFsc2U7XG4gICAgfVxuICAgIHZhbGlkYXRlQm9vbGVhbihjaGVjayk7XG5cbiAgICBpZiAoIShpc0FycmF5KHBhdGgpIHx8IGlzU3RyaW5nKHBhdGgpKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0eXBlIGVycm9yOiBwYXRoIG11c3QgYmUgYSBzdHJpbmcgb3IgYW4gYXJyYXlcIik7XG4gICAgfVxuXG4gICAgbGV0IHBhcnRzO1xuICAgIGlmIChpc1N0cmluZyhwYXRoKSkge1xuICAgICAgICBpZiAocGF0aCA9PT0gXCJcIikge1xuICAgICAgICAgICAgcmV0dXJuIHN1YmplY3Q7XG4gICAgICAgIH1cblxuICAgICAgICBwYXJ0cyA9IHBhdGguc3BsaXQoREVMSU1JVEVSKTtcbiAgICB9XG5cbiAgICBsZXQgY3VycmVudCA9IHBhcnRzLnNoaWZ0KCk7XG5cbiAgICBpZiAoY3VycmVudCA9PT0gdGhpcy53aWxkQ2FyZCkge1xuICAgICAgICByZXR1cm4gaXRlcmF0ZS5jYWxsKHRoaXMsIHN1YmplY3QsIHBhcnRzLmpvaW4oREVMSU1JVEVSKSwgY2hlY2spO1xuICAgIH1cblxuICAgIGlmIChpc09iamVjdChzdWJqZWN0KSB8fCBpc0FycmF5KHN1YmplY3QpKSB7XG4gICAgICAgIGxldCBhbmNob3I7XG4gICAgICAgIGlmIChzdWJqZWN0IGluc3RhbmNlb2YgTWFwIHx8IHN1YmplY3QgaW5zdGFuY2VvZiBXZWFrTWFwKSB7XG4gICAgICAgICAgICBhbmNob3IgPSBzdWJqZWN0LmdldChjdXJyZW50KTtcbiAgICAgICAgfSBlbHNlIGlmIChzdWJqZWN0IGluc3RhbmNlb2YgU2V0IHx8IHN1YmplY3QgaW5zdGFuY2VvZiBXZWFrU2V0KSB7XG4gICAgICAgICAgICBjdXJyZW50ID0gcGFyc2VJbnQoY3VycmVudCk7XG4gICAgICAgICAgICB2YWxpZGF0ZUludGVnZXIoY3VycmVudCk7XG4gICAgICAgICAgICBhbmNob3IgPSBbLi4uc3ViamVjdF0/LltjdXJyZW50XTtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgV2Vha1JlZiA9PT0gXCJmdW5jdGlvblwiICYmIHN1YmplY3QgaW5zdGFuY2VvZiBXZWFrUmVmKSB7XG4gICAgICAgICAgICB0aHJvdyBFcnJvcihcInVuc3VwcG9ydGVkIGFjdGlvbiBmb3IgdGhpcyBkYXRhIHR5cGVcIik7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNBcnJheShzdWJqZWN0KSkge1xuICAgICAgICAgICAgY3VycmVudCA9IHBhcnNlSW50KGN1cnJlbnQpO1xuICAgICAgICAgICAgdmFsaWRhdGVJbnRlZ2VyKGN1cnJlbnQpO1xuICAgICAgICAgICAgYW5jaG9yID0gc3ViamVjdD8uW2N1cnJlbnRdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYW5jaG9yID0gc3ViamVjdD8uW2N1cnJlbnRdO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzT2JqZWN0KGFuY2hvcikgfHwgaXNBcnJheShhbmNob3IpKSB7XG4gICAgICAgICAgICByZXR1cm4gZ2V0VmFsdWVWaWFQYXRoLmNhbGwodGhpcywgYW5jaG9yLCBwYXJ0cy5qb2luKERFTElNSVRFUiksIGNoZWNrKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXJ0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aHJvdyBFcnJvcihgdGhlIGpvdXJuZXkgaXMgbm90IGF0IGl0cyBlbmQgKCR7cGFydHMuam9pbihERUxJTUlURVIpfSlgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjaGVjayA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgY29uc3QgZGVzY3JpcHRvciA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoT2JqZWN0LmdldFByb3RvdHlwZU9mKHN1YmplY3QpLCBjdXJyZW50KTtcblxuICAgICAgICAgICAgaWYgKCFzdWJqZWN0Lmhhc093blByb3BlcnR5KGN1cnJlbnQpICYmIGRlc2NyaXB0b3IgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHRocm93IEVycm9yKFwidW5rbm93biB2YWx1ZVwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhbmNob3I7XG4gICAgfVxuXG4gICAgdGhyb3cgVHlwZUVycm9yKGB1bnN1cHBvcnRlZCB0eXBlICR7dHlwZW9mIHN1YmplY3R9YCk7XG59XG5cbi8qKlxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBzdWJqZWN0XG4gKiBAcGFyYW0ge3N0cmluZ3xhcnJheX0gcGF0aFxuICogQHBhcmFtIHsqfSB2YWx1ZVxuICogQHJldHVybnMge3ZvaWR9XG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHVuc3VwcG9ydGVkIHR5cGVcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdW5zdXBwb3J0ZWQgdHlwZVxuICogQHRocm93cyB7RXJyb3J9IHRoZSBqb3VybmV5IGlzIG5vdCBhdCBpdHMgZW5kXG4gKiBAdGhyb3dzIHtFcnJvcn0gdW5zdXBwb3J0ZWQgYWN0aW9uIGZvciB0aGlzIGRhdGEgdHlwZVxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gc2V0VmFsdWVWaWFQYXRoKHN1YmplY3QsIHBhdGgsIHZhbHVlKSB7XG4gICAgaWYgKCEoaXNBcnJheShwYXRoKSB8fCBpc1N0cmluZyhwYXRoKSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidHlwZSBlcnJvcjogcGF0aCBtdXN0IGJlIGEgc3RyaW5nIG9yIGFuIGFycmF5XCIpO1xuICAgIH1cblxuICAgIGxldCBwYXJ0cztcbiAgICBpZiAoaXNBcnJheShwYXRoKSkge1xuICAgICAgICBpZiAocGF0aC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBzdWJqZWN0O1xuICAgICAgICB9XG5cbiAgICAgICAgcGFydHMgPSBwYXRoO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHBhcnRzID0gcGF0aC5zcGxpdChERUxJTUlURVIpO1xuICAgIH1cblxuICAgIGxldCBsYXN0ID0gcGFydHMucG9wKCk7XG4gICAgbGV0IHN1YnBhdGggPSBwYXJ0cy5qb2luKERFTElNSVRFUik7XG5cbiAgICBsZXQgc3RhY2sgPSBuZXcgU3RhY2soKTtcbiAgICBsZXQgY3VycmVudCA9IHN1YnBhdGg7XG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGdldFZhbHVlVmlhUGF0aC5jYWxsKHRoaXMsIHN1YmplY3QsIGN1cnJlbnQsIHRydWUpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHt9XG5cbiAgICAgICAgc3RhY2sucHVzaChjdXJyZW50KTtcbiAgICAgICAgcGFydHMucG9wKCk7XG4gICAgICAgIGN1cnJlbnQgPSBwYXJ0cy5qb2luKERFTElNSVRFUik7XG5cbiAgICAgICAgaWYgKGN1cnJlbnQgPT09IFwiXCIpIGJyZWFrO1xuICAgIH1cblxuICAgIHdoaWxlICghc3RhY2suaXNFbXB0eSgpKSB7XG4gICAgICAgIGN1cnJlbnQgPSBzdGFjay5wb3AoKTtcbiAgICAgICAgbGV0IG9iaiA9IHt9O1xuXG4gICAgICAgIGlmICghc3RhY2suaXNFbXB0eSgpKSB7XG4gICAgICAgICAgICBsZXQgbiA9IHN0YWNrLnBlZWsoKS5zcGxpdChERUxJTUlURVIpLnBvcCgpO1xuICAgICAgICAgICAgaWYgKGlzSW50ZWdlcihwYXJzZUludChuKSkpIHtcbiAgICAgICAgICAgICAgICBvYmogPSBbXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHNldFZhbHVlVmlhUGF0aC5jYWxsKHRoaXMsIHN1YmplY3QsIGN1cnJlbnQsIG9iaik7XG4gICAgfVxuXG4gICAgbGV0IGFuY2hvciA9IGdldFZhbHVlVmlhUGF0aC5jYWxsKHRoaXMsIHN1YmplY3QsIHN1YnBhdGgpO1xuXG4gICAgaWYgKCEoaXNPYmplY3Qoc3ViamVjdCkgfHwgaXNBcnJheShzdWJqZWN0KSkpIHtcbiAgICAgICAgdGhyb3cgVHlwZUVycm9yKGB1bnN1cHBvcnRlZCB0eXBlOiAke3R5cGVvZiBzdWJqZWN0fWApO1xuICAgIH1cblxuICAgIGlmIChhbmNob3IgaW5zdGFuY2VvZiBNYXAgfHwgYW5jaG9yIGluc3RhbmNlb2YgV2Vha01hcCkge1xuICAgICAgICBhbmNob3Iuc2V0KGxhc3QsIHZhbHVlKTtcbiAgICB9IGVsc2UgaWYgKGFuY2hvciBpbnN0YW5jZW9mIFNldCB8fCBhbmNob3IgaW5zdGFuY2VvZiBXZWFrU2V0KSB7XG4gICAgICAgIGFuY2hvci5hcHBlbmQodmFsdWUpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIFdlYWtSZWYgPT09IFwiZnVuY3Rpb25cIiAmJiBhbmNob3IgaW5zdGFuY2VvZiBXZWFrUmVmKSB7XG4gICAgICAgIHRocm93IEVycm9yKFwidW5zdXBwb3J0ZWQgYWN0aW9uIGZvciB0aGlzIGRhdGEgdHlwZVwiKTtcbiAgICB9IGVsc2UgaWYgKGlzQXJyYXkoYW5jaG9yKSkge1xuICAgICAgICBsYXN0ID0gcGFyc2VJbnQobGFzdCk7XG4gICAgICAgIHZhbGlkYXRlSW50ZWdlcihsYXN0KTtcbiAgICAgICAgYXNzaWduUHJvcGVydHkoYW5jaG9yLCBsYXN0LCB2YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgYXNzaWduUHJvcGVydHkoYW5jaG9yLCBsYXN0LCB2YWx1ZSk7XG4gICAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge29iamVjdH0gb2JqZWN0XG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5XG4gKiBAcGFyYW0geyp9IHZhbHVlXG4gKi9cbmZ1bmN0aW9uIGFzc2lnblByb3BlcnR5KG9iamVjdCwga2V5LCB2YWx1ZSkge1xuICAgIGlmICghb2JqZWN0Lmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgb2JqZWN0W2tleV0gPSB2YWx1ZTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGRlbGV0ZSBvYmplY3Rba2V5XTtcbiAgICB9XG5cbiAgICBvYmplY3Rba2V5XSA9IHZhbHVlO1xufVxuXG4vKipcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gc3ViamVjdFxuICogQHBhcmFtIHtzdHJpbmd9IHBhdGhcbiAqIEByZXR1cm5zIHt2b2lkfVxuICogQHRocm93cyB7VHlwZUVycm9yfSB1bnN1cHBvcnRlZCB0eXBlXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHVuc3VwcG9ydGVkIHR5cGVcbiAqIEB0aHJvd3Mge0Vycm9yfSB0aGUgam91cm5leSBpcyBub3QgYXQgaXRzIGVuZFxuICogQHRocm93cyB7RXJyb3J9IHVuc3VwcG9ydGVkIGFjdGlvbiBmb3IgdGhpcyBkYXRhIHR5cGVcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuNi4wXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBkZWxldGVWYWx1ZVZpYVBhdGgoc3ViamVjdCwgcGF0aCkge1xuICAgIGlmICghKGlzQXJyYXkocGF0aCkgfHwgaXNTdHJpbmcocGF0aCkpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcInR5cGUgZXJyb3I6IHBhdGggbXVzdCBiZSBhIHN0cmluZyBvciBhbiBhcnJheVwiKTtcbiAgICB9XG5cbiAgICBsZXQgcGFydHM7XG4gICAgaWYgKGlzQXJyYXkocGF0aCkpIHtcbiAgICAgICAgaWYgKHBhdGgubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gc3ViamVjdDtcbiAgICAgICAgfVxuXG4gICAgICAgIHBhcnRzID0gcGF0aDtcbiAgICB9IGVsc2Uge1xuICAgICAgICBwYXJ0cyA9IHBhdGguc3BsaXQoREVMSU1JVEVSKTtcbiAgICB9XG5cbiAgICBsZXQgbGFzdCA9IHBhcnRzLnBvcCgpO1xuICAgIGNvbnN0IHN1YnBhdGggPSBwYXJ0cy5qb2luKERFTElNSVRFUik7XG5cbiAgICBjb25zdCBhbmNob3IgPSBnZXRWYWx1ZVZpYVBhdGguY2FsbCh0aGlzLCBzdWJqZWN0LCBzdWJwYXRoKTtcblxuICAgIGlmIChhbmNob3IgaW5zdGFuY2VvZiBNYXApIHtcbiAgICAgICAgYW5jaG9yLmRlbGV0ZShsYXN0KTtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgICBhbmNob3IgaW5zdGFuY2VvZiBTZXQgfHxcbiAgICAgICAgYW5jaG9yIGluc3RhbmNlb2YgV2Vha01hcCB8fFxuICAgICAgICBhbmNob3IgaW5zdGFuY2VvZiBXZWFrU2V0IHx8XG4gICAgICAgICh0eXBlb2YgV2Vha1JlZiA9PT0gXCJmdW5jdGlvblwiICYmIGFuY2hvciBpbnN0YW5jZW9mIFdlYWtSZWYpXG4gICAgKSB7XG4gICAgICAgIHRocm93IEVycm9yKFwidW5zdXBwb3J0ZWQgYWN0aW9uIGZvciB0aGlzIGRhdGEgdHlwZVwiKTtcbiAgICB9IGVsc2UgaWYgKGlzQXJyYXkoYW5jaG9yKSkge1xuICAgICAgICBsYXN0ID0gcGFyc2VJbnQobGFzdCk7XG4gICAgICAgIHZhbGlkYXRlSW50ZWdlcihsYXN0KTtcbiAgICAgICAgZGVsZXRlIGFuY2hvcltsYXN0XTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBkZWxldGUgYW5jaG9yW2xhc3RdO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGludGVybmFsU3ltYm9sIH0gZnJvbSBcIi4uL2NvbnN0YW50cy5tanNcIjtcbmltcG9ydCB7IGV4dGVuZCB9IGZyb20gXCIuLi9kYXRhL2V4dGVuZC5tanNcIjtcbmltcG9ydCB7IFBhdGhmaW5kZXIgfSBmcm9tIFwiLi4vZGF0YS9wYXRoZmluZGVyLm1qc1wiO1xuaW1wb3J0IHsgQmFzZSB9IGZyb20gXCIuL2Jhc2UubWpzXCI7XG5pbXBvcnQgeyB2YWxpZGF0ZU9iamVjdCB9IGZyb20gXCIuL3ZhbGlkYXRlLm1qc1wiO1xuXG5leHBvcnQgeyBCYXNlV2l0aE9wdGlvbnMgfTtcblxuLyoqXG4gKiBUaGlzIGlzIHRoZSBiYXNlIGNsYXNzIHdpdGggb3B0aW9ucyBmcm9tIHdoaWNoIHNvbWUgbW9uc3RlciBjbGFzc2VzIGFyZSBkZXJpdmVkLlxuICpcbiAqIFRoaXMgY2xhc3MgaXMgYWN0dWFsbHkgb25seSB1c2VkIGFzIGEgYmFzZSBjbGFzcy5cbiAqXG4gKiBDbGFzc2VzIHRoYXQgcmVxdWlyZSB0aGUgcG9zc2liaWxpdHkgb2Ygb3B0aW9ucyBjYW4gYmUgZGVyaXZlZCBkaXJlY3RseSBmcm9tIHRoaXMgY2xhc3MuXG4gKiBEZXJpdmVkIGNsYXNzZXMgYWxtb3N0IGFsd2F5cyBvdmVycmlkZSB0aGUgYGRlZmF1bGAgZ2V0dGVyIHdpdGggdGhlaXIgb3duIHZhbHVlcy5cbiAqXG4gKiBAZXh0ZXJuYWxFeGFtcGxlIC4uLy4uL2V4YW1wbGUvdHlwZXMvYmFzZXdpdGhvcHRpb25zLm1qc1xuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4xMy4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcbiAqIEBkZXByZWNhdGVkIHNpbmNlIDMuMTUuMCB1c2Uge0BsaW5rIE1vbnN0ZXIuVHlwZXMuQmFzZX0gd2l0aCB7QGxpbmsgTW9uc3Rlci5UeXBlcy5lcXVpcFdpdGhJbnRlcm5hbH0gaW5zdGVhZC5cbiAqL1xuY2xhc3MgQmFzZVdpdGhPcHRpb25zIGV4dGVuZHMgQmFzZSB7XG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gb3B0aW9uc1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgc3VwZXIoKTtcblxuICAgICAgICBpZiAob3B0aW9ucyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBvcHRpb25zID0ge307XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzW2ludGVybmFsU3ltYm9sXSA9IGV4dGVuZCh7fSwgdGhpcy5kZWZhdWx0cywgdmFsaWRhdGVPYmplY3Qob3B0aW9ucykpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgZ2V0dGVyIHByb3ZpZGVzIHRoZSBvcHRpb25zLiBEZXJpdmVkIGNsYXNzZXMgb3ZlcndyaXRlXG4gICAgICogdGhpcyBnZXR0ZXIgd2l0aCB0aGVpciBvd24gdmFsdWVzLiBJdCBpcyBnb29kIGthcm1hIHRvIGFsd2F5cyBpbmNsdWRlXG4gICAgICogdGhlIHZhbHVlcyBmcm9tIHRoZSBwYXJlbnQgY2xhc3MuXG4gICAgICpcbiAgICAgKiBgYGBqYXZhc2NyaXB0XG4gICAgICogZ2V0IGRlZmF1bHRzKCkge1xuICAgICAqICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3VwZXIuZGVmYXVsdHMsIHtcbiAgICAgKiAgICAgICAgIG15a2V5OiB0cnVlXG4gICAgICogICAgIH0pO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQHJldHVybiB7b2JqZWN0fVxuICAgICAqL1xuICAgIGdldCBkZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIG5lc3RlZCBvcHRpb25zIGNhbiBiZSBzcGVjaWZpZWQgYnkgcGF0aCBgYS5iLmNgXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcGF0aFxuICAgICAqIEBwYXJhbSB7Kn0gZGVmYXVsdFZhbHVlXG4gICAgICogQHJldHVybiB7Kn1cbiAgICAgKiBAc2luY2UgMS4xMC4wXG4gICAgICovXG4gICAgZ2V0T3B0aW9uKHBhdGgsIGRlZmF1bHRWYWx1ZSkge1xuICAgICAgICBsZXQgdmFsdWU7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHZhbHVlID0gbmV3IFBhdGhmaW5kZXIodGhpc1tpbnRlcm5hbFN5bWJvbF0pLmdldFZpYShwYXRoKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge31cblxuICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkgcmV0dXJuIGRlZmF1bHRWYWx1ZTtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGluc3RhbmNlU3ltYm9sIH0gZnJvbSBcIi4uL2NvbnN0YW50cy5tanNcIjtcbmltcG9ydCB7IGhhc09iamVjdExpbmssIGdldExpbmtlZE9iamVjdHMsIGFkZFRvT2JqZWN0TGluayB9IGZyb20gXCIuLi9kb20vYXR0cmlidXRlcy5tanNcIjtcbmltcG9ydCB7IGdldExvY2FsZU9mRG9jdW1lbnQgfSBmcm9tIFwiLi4vZG9tL2xvY2FsZS5tanNcIjtcbmltcG9ydCB7IEJhc2VXaXRoT3B0aW9ucyB9IGZyb20gXCIuLi90eXBlcy9iYXNld2l0aG9wdGlvbnMubWpzXCI7XG5pbXBvcnQgeyBMb2NhbGUgfSBmcm9tIFwiLi9sb2NhbGUubWpzXCI7XG5pbXBvcnQgeyBUcmFuc2xhdGlvbnMgfSBmcm9tIFwiLi90cmFuc2xhdGlvbnMubWpzXCI7XG5cbmV4cG9ydCB7IFByb3ZpZGVyLCB0cmFuc2xhdGlvbnNMaW5rU3ltYm9sIH07XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuSTE4blxuICogQHR5cGUge3N5bWJvbH1cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDMuOS4wXG4gKiBAcHJpdmF0ZVxuICovXG5jb25zdCB0cmFuc2xhdGlvbnNMaW5rU3ltYm9sID0gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvaTE4bi90cmFuc2xhdGlvbnNAQGxpbmtcIik7XG5cbi8qKlxuICogQSBwcm92aWRlciBtYWtlcyBhIHRyYW5zbGF0aW9uIG9iamVjdCBhdmFpbGFibGUuXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4xMy4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuSTE4blxuICogQHNlZSB7QGxpbmsgaHR0cHM6Ly9kYXRhdHJhY2tlci5pZXRmLm9yZy9kb2MvaHRtbC9yZmMzMDY2fVxuICovXG5jbGFzcyBQcm92aWRlciBleHRlbmRzIEJhc2VXaXRoT3B0aW9ucyB7XG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMy4yNy4wXG4gICAgICovXG4gICAgc3RhdGljIGdldCBbaW5zdGFuY2VTeW1ib2xdKCkge1xuICAgICAgICByZXR1cm4gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvaTE4bi9wcm92aWRlckBAaW5zdGFuY2VcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtMb2NhbGV8c3RyaW5nfSBsb2NhbGVcbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgICAqL1xuICAgIGdldFRyYW5zbGF0aW9ucyhsb2NhbGUpIHtcbiAgICAgICAgaWYgKGxvY2FsZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBsb2NhbGUgPSBnZXRMb2NhbGVPZkRvY3VtZW50KCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKG5ldyBUcmFuc2xhdGlvbnMobG9jYWxlKSk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0xvY2FsZXxzdHJpbmd9IGxvY2FsZVxuICAgICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVsZW1lbnRcbiAgICAgKiBAcmV0dXJuIHtQcm92aWRlcn1cbiAgICAgKi9cbiAgICBhc3NpZ25Ub0VsZW1lbnQobG9jYWxlLCBlbGVtZW50KSB7XG4gICAgICAgIGlmIChsb2NhbGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgbG9jYWxlID0gZ2V0TG9jYWxlT2ZEb2N1bWVudCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCEobG9jYWxlIGluc3RhbmNlb2YgTG9jYWxlKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTG9jYWxlIGlzIG5vdCBhbiBpbnN0YW5jZSBvZiBMb2NhbGVcIik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIShlbGVtZW50IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKSB7XG4gICAgICAgICAgICBlbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcImJvZHlcIik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIShlbGVtZW50IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJFbGVtZW50IGlzIG5vdCBhbiBIVE1MRWxlbWVudFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzLmdldFRyYW5zbGF0aW9ucyhsb2NhbGUpLnRoZW4oKG9iaikgPT4ge1xuICAgICAgICAgICAgbGV0IHRyYW5zbGF0aW9ucyA9IG51bGw7XG4gICAgICAgICAgICBpZiAoaGFzT2JqZWN0TGluayhlbGVtZW50LCB0cmFuc2xhdGlvbnNMaW5rU3ltYm9sKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9iamVjdHMgPSBnZXRMaW5rZWRPYmplY3RzKGVsZW1lbnQsIHRyYW5zbGF0aW9uc0xpbmtTeW1ib2wpO1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgbyBvZiBvYmplY3RzKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChvIGluc3RhbmNlb2YgVHJhbnNsYXRpb25zKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2xhdGlvbnMgPSBvO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoISh0cmFuc2xhdGlvbnMgaW5zdGFuY2VvZiBUcmFuc2xhdGlvbnMpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIk9iamVjdCBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgVHJhbnNsYXRpb25zXCIpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRyYW5zbGF0aW9ucy5hc3NpZ25UcmFuc2xhdGlvbnMob2JqKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYWRkVG9PYmplY3RMaW5rKGVsZW1lbnQsIHRyYW5zbGF0aW9uc0xpbmtTeW1ib2wsIG9iaik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBvYmo7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGluc3RhbmNlU3ltYm9sIH0gZnJvbSBcIi4uL2NvbnN0YW50cy5tanNcIjtcbmltcG9ydCB7IGdldExpbmtlZE9iamVjdHMsIGhhc09iamVjdExpbmsgfSBmcm9tIFwiLi4vZG9tL2F0dHJpYnV0ZXMubWpzXCI7XG5pbXBvcnQgeyBBVFRSSUJVVEVfT0JKRUNUTElOSyB9IGZyb20gXCIuLi9kb20vY29uc3RhbnRzLm1qc1wiO1xuaW1wb3J0IHsgZ2V0RG9jdW1lbnQgfSBmcm9tIFwiLi4vZG9tL3V0aWwubWpzXCI7XG5pbXBvcnQgeyBCYXNlIH0gZnJvbSBcIi4uL3R5cGVzL2Jhc2UubWpzXCI7XG5pbXBvcnQgeyBpc09iamVjdCwgaXNTdHJpbmcgfSBmcm9tIFwiLi4vdHlwZXMvaXMubWpzXCI7XG5pbXBvcnQgeyB2YWxpZGF0ZUludGVnZXIsIHZhbGlkYXRlT2JqZWN0LCB2YWxpZGF0ZVN0cmluZyB9IGZyb20gXCIuLi90eXBlcy92YWxpZGF0ZS5tanNcIjtcbmltcG9ydCB7IExvY2FsZSwgcGFyc2VMb2NhbGUgfSBmcm9tIFwiLi9sb2NhbGUubWpzXCI7XG5pbXBvcnQgeyB0cmFuc2xhdGlvbnNMaW5rU3ltYm9sIH0gZnJvbSBcIi4vcHJvdmlkZXIubWpzXCI7XG5cbmV4cG9ydCB7IFRyYW5zbGF0aW9ucywgZ2V0RG9jdW1lbnRUcmFuc2xhdGlvbnMgfTtcblxuLyoqXG4gKiBXaXRoIHRoaXMgY2xhc3MgeW91IGNhbiBtYW5hZ2UgdHJhbnNsYXRpb25zIGFuZCBhY2Nlc3MgdGhlIGtleXMuXG4gKlxuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL2kxOG4vdHJhbnNsYXRpb25zLm1qc1xuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4xMy4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuSTE4blxuICogQHNlZSBodHRwczovL2RhdGF0cmFja2VyLmlldGYub3JnL2RvYy9odG1sL3JmYzMwNjZcbiAqL1xuY2xhc3MgVHJhbnNsYXRpb25zIGV4dGVuZHMgQmFzZSB7XG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0xvY2FsZX0gbG9jYWxlXG4gICAgICovXG4gICAgY29uc3RydWN0b3IobG9jYWxlKSB7XG4gICAgICAgIHN1cGVyKCk7XG5cbiAgICAgICAgaWYgKGxvY2FsZSBpbnN0YW5jZW9mIExvY2FsZSkge1xuICAgICAgICAgICAgdGhpcy5sb2NhbGUgPSBsb2NhbGU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmxvY2FsZSA9IHBhcnNlTG9jYWxlKHZhbGlkYXRlU3RyaW5nKGxvY2FsZSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zdG9yYWdlID0gbmV3IE1hcCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgYGluc3RhbmNlb2ZgIG9wZXJhdG9yLlxuICAgICAqIEByZXR1cm5zIHtzeW1ib2x9XG4gICAgICogQHNpbmNlIDMuMjcuMFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgW2luc3RhbmNlU3ltYm9sXSgpIHtcbiAgICAgICAgcmV0dXJuIFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL2kxOG4vdHJhbnNsYXRpb25zQEBpbnN0YW5jZVwiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaGVzIGEgdGV4dCB1c2luZyB0aGUgc3BlY2lmaWVkIGtleS5cbiAgICAgKiBJZiBubyBzdWl0YWJsZSBrZXkgaXMgZm91bmQsIGBkZWZhdWx0VGV4dGAgaXMgdGFrZW4uXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5XG4gICAgICogQHBhcmFtIHtzdHJpbmd8dW5kZWZpbmVkfSBkZWZhdWx0VGV4dFxuICAgICAqIEByZXR1cm4ge3N0cmluZ31cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0ga2V5IG5vdCBmb3VuZFxuICAgICAqL1xuICAgIGdldFRleHQoa2V5LCBkZWZhdWx0VGV4dCkge1xuICAgICAgICBpZiAoIXRoaXMuc3RvcmFnZS5oYXMoa2V5KSkge1xuICAgICAgICAgICAgaWYgKGRlZmF1bHRUZXh0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGtleSAke2tleX0gbm90IGZvdW5kYCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB2YWxpZGF0ZVN0cmluZyhkZWZhdWx0VGV4dCk7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgciA9IHRoaXMuc3RvcmFnZS5nZXQoa2V5KTtcbiAgICAgICAgaWYgKGlzT2JqZWN0KHIpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRQbHVyYWxSdWxlVGV4dChrZXksIFwib3RoZXJcIiwgZGVmYXVsdFRleHQpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuc3RvcmFnZS5nZXQoa2V5KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIG51bWJlciBgY291bnRgIGNhbiBiZSBwYXNzZWQgdG8gdGhpcyBtZXRob2QuIEluIGFkZGl0aW9uIHRvIGEgbnVtYmVyLCBvbmUgb2YgdGhlIGtleXdvcmRzIGNhbiBhbHNvIGJlIHBhc3NlZCBkaXJlY3RseS5cbiAgICAgKiBcInplcm9cIiwgXCJvbmVcIiwgXCJ0d29cIiwgXCJmZXdcIiwgXCJtYW55XCIgYW5kIFwib3RoZXJcIi4gUmVtZW1iZXI6IG5vdCBldmVyeSBsYW5ndWFnZSBoYXMgYWxsIHJ1bGVzLlxuICAgICAqXG4gICAgICogVGhlIGFwcHJvcHJpYXRlIHRleHQgZm9yIHRoaXMgbnVtYmVyIGlzIHRoZW4gc2VsZWN0ZWQuIElmIG5vIHN1aXRhYmxlIGtleSBpcyBmb3VuZCwgYGRlZmF1bHRUZXh0YCBpcyB0YWtlbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXlcbiAgICAgKiBAcGFyYW0ge2ludGVnZXJ8Y291bnR9IGNvdW50XG4gICAgICogQHBhcmFtIHtzdHJpbmd8dW5kZWZpbmVkfSBkZWZhdWx0VGV4dFxuICAgICAqIEByZXR1cm4ge3N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRQbHVyYWxSdWxlVGV4dChrZXksIGNvdW50LCBkZWZhdWx0VGV4dCkge1xuICAgICAgICBpZiAoIXRoaXMuc3RvcmFnZS5oYXMoa2V5KSkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbGlkYXRlU3RyaW5nKGRlZmF1bHRUZXh0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCByID0gdmFsaWRhdGVPYmplY3QodGhpcy5zdG9yYWdlLmdldChrZXkpKTtcblxuICAgICAgICBsZXQga2V5d29yZDtcbiAgICAgICAgaWYgKGlzU3RyaW5nKGNvdW50KSkge1xuICAgICAgICAgICAga2V5d29yZCA9IGNvdW50LnRvTG9jYWxlU3RyaW5nKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb3VudCA9IHZhbGlkYXRlSW50ZWdlcihjb3VudCk7XG4gICAgICAgICAgICBpZiAoY291bnQgPT09IDApIHtcbiAgICAgICAgICAgICAgICAvLyBzcGVjaWFsIGhhbmRsaW5nIGZvciB6ZXJvIGNvdW50XG4gICAgICAgICAgICAgICAgaWYgKHIuaGFzT3duUHJvcGVydHkoXCJ6ZXJvXCIpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWxpZGF0ZVN0cmluZyhyW1wiemVyb1wiXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBrZXl3b3JkID0gbmV3IEludGwuUGx1cmFsUnVsZXModGhpcy5sb2NhbGUudG9TdHJpbmcoKSkuc2VsZWN0KHZhbGlkYXRlSW50ZWdlcihjb3VudCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHIuaGFzT3duUHJvcGVydHkoa2V5d29yZCkpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWxpZGF0ZVN0cmluZyhyW2tleXdvcmRdKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEBkZXByZWNhdGVkIHNpbmNlIDIwMjMtMDMtMTRcbiAgICAgICAgLy8gREVGQVVMVF9LRVkgaXMgdW5kZWZpbmVkXG4gICAgICAgIC8vIGlmIChyLmhhc093blByb3BlcnR5KERFRkFVTFRfS0VZKSkge1xuICAgICAgICAvLyAgICAgcmV0dXJuIHZhbGlkYXRlU3RyaW5nKHJbREVGQVVMVF9LRVldKTtcbiAgICAgICAgLy8gfVxuXG4gICAgICAgIHJldHVybiB2YWxpZGF0ZVN0cmluZyhkZWZhdWx0VGV4dCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IGEgdGV4dCBmb3IgYSBrZXlcbiAgICAgKlxuICAgICAqIGBgYFxuICAgICAqIHRyYW5zbGF0aW9ucy5zZXRUZXh0KFwidGV4dDFcIiwgXCJNYWtlIG15IGRheSFcIik7XG4gICAgICogLy8gcGx1cmFsIHJ1bGVzXG4gICAgICogdHJhbnNsYXRpb25zLnNldFRleHQoXCJ0ZXh0NlwiLCB7XG4gICAgICogICAgIFwiemVyb1wiOiBcIlRoZXJlIGFyZSBubyBmaWxlcyBvbiBEaXNrLlwiLFxuICAgICAqICAgICBcIm9uZVwiOiBcIlRoZXJlIGlzIG9uZSBmaWxlIG9uIERpc2suXCIsXG4gICAgICogICAgIFwib3RoZXJcIjogXCJUaGVyZSBhcmUgZmlsZXMgb24gRGlzay5cIlxuICAgICAqICAgICBcImRlZmF1bHRcIjogXCJUaGVyZSBhcmUgZmlsZXMgb24gRGlzay5cIlxuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfG9iamVjdH0gdGV4dFxuICAgICAqIEByZXR1cm4ge1RyYW5zbGF0aW9uc31cbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIHN0cmluZyBvciBvYmplY3RcbiAgICAgKi9cbiAgICBzZXRUZXh0KGtleSwgdGV4dCkge1xuICAgICAgICBpZiAoaXNTdHJpbmcodGV4dCkgfHwgaXNPYmplY3QodGV4dCkpIHtcbiAgICAgICAgICAgIHRoaXMuc3RvcmFnZS5zZXQodmFsaWRhdGVTdHJpbmcoa2V5KSwgdGV4dCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJ2YWx1ZSBpcyBub3QgYSBzdHJpbmcgb3Igb2JqZWN0XCIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGNhbiBiZSB1c2VkIHRvIHRyYW5zZmVyIG92ZXJsYXlzIGZyb20gYW4gb2JqZWN0LiBUaGUga2V5cyBhcmUgdHJhbnNmZXJyZWQsIGFuZCB0aGUgdmFsdWVzIGFyZSBlbnRlcmVkXG4gICAgICogYXMgdGV4dC5cbiAgICAgKlxuICAgICAqIFRoZSB2YWx1ZXMgY2FuIGVpdGhlciBiZSBjaGFyYWN0ZXIgc3RyaW5ncyBvciwgaW4gdGhlIGNhc2Ugb2YgdGV4dHMgd2l0aCBwbHVyYWwgZm9ybXMsIG9iamVjdHMuIFRoZSBwbHVyYWwgZm9ybXNcbiAgICAgKiBtdXN0IGJlIHN0b3JlZCBhcyB0ZXh0IHZpYSBhIHN0YW5kYXJkIGtleSBcInplcm9cIiwgXCJvbmVcIiwgXCJ0d29cIiwgXCJmZXdcIiwgXCJtYW55XCIgYW5kIFwib3RoZXJcIi5cbiAgICAgKlxuICAgICAqIEFkZGl0aW9uYWxseSwgdGhlIGtleSBkZWZhdWx0IGNhbiBiZSBzcGVjaWZpZWQsIHdoaWNoIHdpbGwgYmUgdXNlZCBpZiBubyBvdGhlciBrZXkgZml0cy5cbiAgICAgKlxuICAgICAqIEluIHNvbWUgbGFuZ3VhZ2VzLCBsaWtlIGZvciBleGFtcGxlIGluIEdlcm1hbiwgdGhlcmUgaXMgbm8gb3duIG1vcmUgbnVtYmVyIGF0IHRoZSB2YWx1ZSAwLiBJbiB0aGVzZSBsYW5ndWFnZXMsXG4gICAgICogdGhlIGZ1bmN0aW9uIGFwcGxpZXMgYWRkaXRpb25hbGx5IHplcm8uXG4gICAgICpcbiAgICAgKiBgYGBcbiAgICAgKiB0cmFuc2xhdGlvbnMuYXNzaWduVHJhbnNsYXRpb25zKHtcbiAgICAgKiAgIFwidGV4dDFcIjogXCJNYWtlIG15IGRheSFcIixcbiAgICAgKiAgIFwidGV4dDJcIjogXCJJJ2xsIGJlIGJhY2shXCIsXG4gICAgICogICBcInRleHQ2XCI6IHtcbiAgICAgKiAgICAgXCJ6ZXJvXCI6IFwiVGhlcmUgYXJlIG5vIGZpbGVzIG9uIERpc2suXCIsXG4gICAgICogICAgIFwib25lXCI6IFwiVGhlcmUgaXMgb25lIGZpbGUgb24gRGlzay5cIixcbiAgICAgKiAgICAgXCJvdGhlclwiOiBcIlRoZXJlIGFyZSBmaWxlcyBvbiBEaXNrLlwiXG4gICAgICogICAgIFwiZGVmYXVsdFwiOiBcIlRoZXJlIGFyZSBmaWxlcyBvbiBEaXNrLlwiXG4gICAgICogfSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gdHJhbnNsYXRpb25zXG4gICAgICogQHJldHVybiB7VHJhbnNsYXRpb25zfVxuICAgICAqL1xuICAgIGFzc2lnblRyYW5zbGF0aW9ucyh0cmFuc2xhdGlvbnMpIHtcbiAgICAgICAgdmFsaWRhdGVPYmplY3QodHJhbnNsYXRpb25zKTtcblxuICAgICAgICBpZiAodHJhbnNsYXRpb25zIGluc3RhbmNlb2YgVHJhbnNsYXRpb25zKSB7XG4gICAgICAgICAgICB0cmFuc2xhdGlvbnMuc3RvcmFnZS5mb3JFYWNoKCh2LCBrKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRUZXh0KGssIHYpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoY29uc3QgW2ssIHZdIG9mIE9iamVjdC5lbnRyaWVzKHRyYW5zbGF0aW9ucykpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0VGV4dChrLCB2KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSB0cmFuc2xhdGlvbnMgZm9yIHRoZSBjdXJyZW50IGRvY3VtZW50LlxuICpcbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR8dW5kZWZpbmVkfSBbZWxlbWVudF0gLSBFbGVtZW50IHRvIHNlYXJjaCBmb3IgdHJhbnNsYXRpb25zLiBEZWZhdWx0OiBlbGVtZW50IHdpdGggb2JqZWN0bGluayBAc2NodWthaS9tb25zdGVyL2kxOG4vdHJhbnNsYXRpb25zQEBsaW5rLlxuICogQHJldHVybnMge1RyYW5zbGF0aW9uc31cbiAqIEB0aHJvd3Mge0Vycm9yfSBFbGVtZW50IGlzIG5vdCBhbiBIVE1MRWxlbWVudC5cbiAqIEB0aHJvd3Mge0Vycm9yfSBDYW5ub3QgZmluZCBlbGVtZW50IHdpdGggdHJhbnNsYXRpb25zLiBBZGQgYSB0cmFuc2xhdGlvbnMgb2JqZWN0IHRvIHRoZSBkb2N1bWVudC5cbiAqIEB0aHJvd3Mge0Vycm9yfSBUaGlzIGVsZW1lbnQgaGFzIG5vIHRyYW5zbGF0aW9ucy5cbiAqIEB0aHJvd3Mge0Vycm9yfSBNaXNzaW5nIHRyYW5zbGF0aW9ucy5cbiAqIEBtZW1iZXJPZiBNb25zdGVyLkkxOG5cbiAqL1xuZnVuY3Rpb24gZ2V0RG9jdW1lbnRUcmFuc2xhdGlvbnMoZWxlbWVudCkge1xuICAgIGNvbnN0IGQgPSBnZXREb2N1bWVudCgpO1xuXG4gICAgaWYgKCEoZWxlbWVudCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSkge1xuICAgICAgICBlbGVtZW50ID0gZC5xdWVyeVNlbGVjdG9yKGBbJHtBVFRSSUJVVEVfT0JKRUNUTElOS31+PVwiJHt0cmFuc2xhdGlvbnNMaW5rU3ltYm9sLnRvU3RyaW5nKCl9XCJdYCk7XG4gICAgICAgIGlmIChlbGVtZW50ID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBlbGVtZW50IHdpdGggdHJhbnNsYXRpb25zLiBBZGQgYSB0cmFuc2xhdGlvbnMgb2JqZWN0IHRvIHRoZSBkb2N1bWVudC5cIik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIShlbGVtZW50IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkVsZW1lbnQgaXMgbm90IGFuIEhUTUxFbGVtZW50LlwiKTtcbiAgICB9XG5cbiAgICBpZiAoIWhhc09iamVjdExpbmsoZWxlbWVudCwgdHJhbnNsYXRpb25zTGlua1N5bWJvbCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBlbGVtZW50IGhhcyBubyB0cmFuc2xhdGlvbnMuXCIpO1xuICAgIH1cblxuICAgIGxldCBvYmogPSBnZXRMaW5rZWRPYmplY3RzKGVsZW1lbnQsIHRyYW5zbGF0aW9uc0xpbmtTeW1ib2wpO1xuXG4gICAgZm9yIChjb25zdCB0IG9mIG9iaikge1xuICAgICAgICBpZiAodCBpbnN0YW5jZW9mIFRyYW5zbGF0aW9ucykge1xuICAgICAgICAgICAgcmV0dXJuIHQ7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIHRyYW5zbGF0aW9ucy5cIik7XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBnZXRMb2NhbGVPZkRvY3VtZW50IH0gZnJvbSBcIi4uL2RvbS9sb2NhbGUubWpzXCI7XG5pbXBvcnQgeyBCYXNlIH0gZnJvbSBcIi4uL3R5cGVzL2Jhc2UubWpzXCI7XG5pbXBvcnQgeyBnZXRHbG9iYWwsIGdldEdsb2JhbE9iamVjdCB9IGZyb20gXCIuLi90eXBlcy9nbG9iYWwubWpzXCI7XG5pbXBvcnQgeyBJRCB9IGZyb20gXCIuLi90eXBlcy9pZC5tanNcIjtcbmltcG9ydCB7IGlzQXJyYXksIGlzT2JqZWN0LCBpc1N0cmluZywgaXNQcmltaXRpdmUgfSBmcm9tIFwiLi4vdHlwZXMvaXMubWpzXCI7XG5pbXBvcnQgeyBnZXREb2N1bWVudFRyYW5zbGF0aW9ucywgVHJhbnNsYXRpb25zIH0gZnJvbSBcIi4uL2kxOG4vdHJhbnNsYXRpb25zLm1qc1wiO1xuaW1wb3J0IHtcbiAgICB2YWxpZGF0ZUZ1bmN0aW9uLFxuICAgIHZhbGlkYXRlSW50ZWdlcixcbiAgICB2YWxpZGF0ZU9iamVjdCxcbiAgICB2YWxpZGF0ZVByaW1pdGl2ZSxcbiAgICB2YWxpZGF0ZVN0cmluZyxcbiAgICB2YWxpZGF0ZUJvb2xlYW4sXG59IGZyb20gXCIuLi90eXBlcy92YWxpZGF0ZS5tanNcIjtcbmltcG9ydCB7IGNsb25lIH0gZnJvbSBcIi4uL3V0aWwvY2xvbmUubWpzXCI7XG5pbXBvcnQgeyBQYXRoZmluZGVyIH0gZnJvbSBcIi4vcGF0aGZpbmRlci5tanNcIjtcblxuZXhwb3J0IHsgVHJhbnNmb3JtZXIgfTtcblxuLyoqXG4gKiBUaGUgdHJhbnNmb3JtZXIgY2xhc3MgaXMgYSBzd2lzcyBhcm15IGtuaWZlIGZvciBtYW5pcHVsYXRpbmcgdmFsdWVzLiBlc3BlY2lhbGx5IGluIGNvbWJpbmF0aW9uIHdpdGggdGhlIHBpcGUsIHByb2Nlc3NpbmcgY2hhaW5zIGNhbiBiZSBidWlsdCB1cC5cbiAqXG4gKiBBIHNpbXBsZSBleGFtcGxlIGlzIHRoZSBjb252ZXJzaW9uIG9mIGFsbCBjaGFyYWN0ZXJzIHRvIGxvd2VyY2FzZS4gZm9yIHRoaXMgcHVycG9zZSB0aGUgY29tbWFuZCBgdG9sb3dlcmAgbXVzdCBiZSB1c2VkLlxuICpcbiAqIGBgYFxuICogbGV0IHQgPSBuZXcgVHJhbnNmb3JtZXIoJ3RvbG93ZXInKS5ydW4oJ0FCQycpOyAvLyBcdTIxQTYgYWJjXG4gKiBgYGBcbiAqXG4gKiBAc2VlIHtAbGluayBodHRwczovL21vbnN0ZXJqcy5vcmcvZW4vZG9jLyN0cmFuc2Zvcm1lcnxNb25zdGVyIERvY3N9XG4gKlxuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL2RhdGEvdHJhbnNmb3JtZXIubWpzXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjUuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRhdGFcbiAqL1xuY2xhc3MgVHJhbnNmb3JtZXIgZXh0ZW5kcyBCYXNlIHtcbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBkZWZpbml0aW9uXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoZGVmaW5pdGlvbikge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLmFyZ3MgPSBkaXNhc3NlbWJsZShkZWZpbml0aW9uKTtcbiAgICAgICAgdGhpcy5jb21tYW5kID0gdGhpcy5hcmdzLnNoaWZ0KCk7XG4gICAgICAgIHRoaXMuY2FsbGJhY2tzID0gbmV3IE1hcCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBjYWxsYmFja1xuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBjb250ZXh0XG4gICAgICogQHJldHVybnMge1RyYW5zZm9ybWVyfVxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgc3RyaW5nXG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYSBmdW5jdGlvblxuICAgICAqL1xuICAgIHNldENhbGxiYWNrKG5hbWUsIGNhbGxiYWNrLCBjb250ZXh0KSB7XG4gICAgICAgIHZhbGlkYXRlU3RyaW5nKG5hbWUpO1xuICAgICAgICB2YWxpZGF0ZUZ1bmN0aW9uKGNhbGxiYWNrKTtcblxuICAgICAgICBpZiAoY29udGV4dCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB2YWxpZGF0ZU9iamVjdChjb250ZXh0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY2FsbGJhY2tzLnNldChuYW1lLCB7XG4gICAgICAgICAgICBjYWxsYmFjazogY2FsbGJhY2ssXG4gICAgICAgICAgICBjb250ZXh0OiBjb250ZXh0LFxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAgICAgKiBAcmV0dXJucyB7Kn1cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gdW5rbm93biBjb21tYW5kXG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSB1bnN1cHBvcnRlZCB0eXBlXG4gICAgICogQHRocm93cyB7RXJyb3J9IHR5cGUgbm90IHN1cHBvcnRlZFxuICAgICAqL1xuICAgIHJ1bih2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdHJhbnNmb3JtLmFwcGx5KHRoaXMsIFt2YWx1ZV0pO1xuICAgIH1cbn1cblxuLyoqXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGNvbW1hbmRcbiAqIEByZXR1cm5zIHthcnJheX1cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGRpc2Fzc2VtYmxlKGNvbW1hbmQpIHtcbiAgICB2YWxpZGF0ZVN0cmluZyhjb21tYW5kKTtcblxuICAgIGxldCBwbGFjZWhvbGRlciA9IG5ldyBNYXAoKTtcbiAgICBjb25zdCByZWdleCA9IC8oKD88cGF0dGVybj5cXFxcKD88Y2hhcj4uKSl7MX0pL2dpbTtcblxuICAgIC8vIFRoZSBzZXBhcmF0b3IgZm9yIGFyZ3MgbXVzdCBiZSBlc2NhcGVkXG4gICAgLy8gdW5kZWZpbmVkIHN0cmluZyB3aGljaCBzaG91bGQgbm90IG9jY3VyIG5vcm1hbGx5IGFuZCBpcyBhbHNvIG5vdCBhIHJlZ2V4XG4gICAgbGV0IHJlc3VsdCA9IGNvbW1hbmQubWF0Y2hBbGwocmVnZXgpO1xuXG4gICAgZm9yIChsZXQgbSBvZiByZXN1bHQpIHtcbiAgICAgICAgbGV0IGcgPSBtPy5bXCJncm91cHNcIl07XG4gICAgICAgIGlmICghaXNPYmplY3QoZykpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHAgPSBnPy5bXCJwYXR0ZXJuXCJdO1xuICAgICAgICBsZXQgYyA9IGc/LltcImNoYXJcIl07XG5cbiAgICAgICAgaWYgKHAgJiYgYykge1xuICAgICAgICAgICAgbGV0IHIgPSBgX18ke25ldyBJRCgpLnRvU3RyaW5nKCl9X19gO1xuICAgICAgICAgICAgcGxhY2Vob2xkZXIuc2V0KHIsIGMpO1xuICAgICAgICAgICAgY29tbWFuZCA9IGNvbW1hbmQucmVwbGFjZShwLCByKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBsZXQgcGFydHMgPSBjb21tYW5kLnNwbGl0KFwiOlwiKTtcblxuICAgIHBhcnRzID0gcGFydHMubWFwKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICBsZXQgdiA9IHZhbHVlLnRyaW0oKTtcbiAgICAgICAgZm9yIChsZXQgayBvZiBwbGFjZWhvbGRlcikge1xuICAgICAgICAgICAgdiA9IHYucmVwbGFjZShrWzBdLCBrWzFdKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdjtcbiAgICB9KTtcblxuICAgIHJldHVybiBwYXJ0cztcbn1cblxuLyoqXG4gKiB0cmllcyB0byBtYWtlIGEgc3RyaW5nIG91dCBvZiB2YWx1ZSBhbmQgaWYgdGhpcyBzdWNjZWVkcyB0byByZXR1cm4gaXQgYmFja1xuICpcbiAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAqIEByZXR1cm5zIHtzdHJpbmd9XG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBjb252ZXJ0VG9TdHJpbmcodmFsdWUpIHtcbiAgICBpZiAoaXNPYmplY3QodmFsdWUpICYmIHZhbHVlLmhhc093blByb3BlcnR5KFwidG9TdHJpbmdcIikpIHtcbiAgICAgICAgdmFsdWUgPSB2YWx1ZS50b1N0cmluZygpO1xuICAgIH1cblxuICAgIHZhbGlkYXRlU3RyaW5nKHZhbHVlKTtcbiAgICByZXR1cm4gdmFsdWU7XG59XG5cbi8qKlxuICpcbiAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAqIEByZXR1cm5zIHsqfVxuICogQHByaXZhdGVcbiAqIEB0aHJvd3Mge0Vycm9yfSB1bmtub3duIGNvbW1hbmRcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdW5zdXBwb3J0ZWQgdHlwZVxuICogQHRocm93cyB7RXJyb3J9IHR5cGUgbm90IHN1cHBvcnRlZFxuICogQHRocm93cyB7RXJyb3J9IG1pc3Npbmcga2V5IHBhcmFtZXRlclxuICovXG5mdW5jdGlvbiB0cmFuc2Zvcm0odmFsdWUpIHtcbiAgICBjb25zdCBjb25zb2xlID0gZ2V0R2xvYmFsT2JqZWN0KFwiY29uc29sZVwiKTtcblxuICAgIGxldCBhcmdzID0gY2xvbmUodGhpcy5hcmdzKTtcbiAgICBsZXQga2V5O1xuICAgIGxldCBkZWZhdWx0VmFsdWU7XG5cbiAgICBsZXQgdHJhbnNsYXRpb25zO1xuICAgIGxldCBkYXRlO1xuICAgIGxldCBsb2NhbGU7XG4gICAgbGV0IHRpbWVzdGFtcDtcbiAgICBsZXQgbWFwO1xuICAgIGxldCBrZXlWYWx1ZTtcblxuICAgIHN3aXRjaCAodGhpcy5jb21tYW5kKSB7XG4gICAgICAgIGNhc2UgXCJzdGF0aWNcIjpcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmFyZ3Muam9pbihcIjpcIik7XG5cbiAgICAgICAgY2FzZSBcInRvbG93ZXJcIjpcbiAgICAgICAgY2FzZSBcInN0cnRvbG93ZXJcIjpcbiAgICAgICAgY2FzZSBcInRvbG93ZXJjYXNlXCI6XG4gICAgICAgICAgICB2YWxpZGF0ZVN0cmluZyh2YWx1ZSk7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWUudG9Mb3dlckNhc2UoKTtcblxuICAgICAgICBjYXNlIFwiY29udGFpbnNcIjpcbiAgICAgICAgICAgIGlmIChpc1N0cmluZyh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWUuaW5jbHVkZXMoYXJnc1swXSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZS5pbmNsdWRlcyhhcmdzWzBdKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGlzT2JqZWN0KHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZS5oYXNPd25Qcm9wZXJ0eShhcmdzWzBdKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgIGNhc2UgXCJoYXMtZW50cmllc1wiOlxuICAgICAgICBjYXNlIFwiaGFzZW50cmllc1wiOlxuICAgICAgICAgICAgaWYgKGlzT2JqZWN0KHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBPYmplY3Qua2V5cyh2YWx1ZSkubGVuZ3RoID4gMDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlLmxlbmd0aCA+IDA7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcblxuICAgICAgICBjYXNlIFwiaXN1bmRlZmluZWRcIjpcbiAgICAgICAgY2FzZSBcImlzLXVuZGVmaW5lZFwiOlxuICAgICAgICAgICAgcmV0dXJuIHZhbHVlID09PSB1bmRlZmluZWQ7XG5cbiAgICAgICAgY2FzZSBcImlzbnVsbFwiOlxuICAgICAgICBjYXNlIFwiaXMtbnVsbFwiOlxuICAgICAgICAgICAgcmV0dXJuIHZhbHVlID09PSBudWxsO1xuXG4gICAgICAgIGNhc2UgXCJpc3NldFwiOlxuICAgICAgICBjYXNlIFwiaXMtc2V0XCI6XG4gICAgICAgICAgICByZXR1cm4gdmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbDtcblxuICAgICAgICBjYXNlIFwiaXNudW1iZXJcIjpcbiAgICAgICAgY2FzZSBcImlzLW51bWJlclwiOlxuICAgICAgICAgICAgcmV0dXJuIGlzUHJpbWl0aXZlKHZhbHVlKSAmJiAhaXNOYU4odmFsdWUpO1xuXG4gICAgICAgIGNhc2UgXCJpc2ludGVnZXJcIjpcbiAgICAgICAgY2FzZSBcImlzLWludGVnZXJcIjpcbiAgICAgICAgICAgIHJldHVybiBpc1ByaW1pdGl2ZSh2YWx1ZSkgJiYgIWlzTmFOKHZhbHVlKSAmJiB2YWx1ZSAlIDEgPT09IDA7XG5cbiAgICAgICAgY2FzZSBcImlzZmxvYXRcIjpcbiAgICAgICAgY2FzZSBcImlzLWZsb2F0XCI6XG4gICAgICAgICAgICByZXR1cm4gaXNQcmltaXRpdmUodmFsdWUpICYmICFpc05hTih2YWx1ZSkgJiYgdmFsdWUgJSAxICE9PSAwO1xuXG4gICAgICAgIGNhc2UgXCJpc29iamVjdFwiOlxuICAgICAgICBjYXNlIFwiaXMtb2JqZWN0XCI6XG4gICAgICAgICAgICByZXR1cm4gaXNPYmplY3QodmFsdWUpO1xuXG4gICAgICAgIGNhc2UgXCJpc2FycmF5XCI6XG4gICAgICAgIGNhc2UgXCJpcy1hcnJheVwiOlxuICAgICAgICAgICAgcmV0dXJuIEFycmF5LmlzQXJyYXkodmFsdWUpO1xuXG4gICAgICAgIGNhc2UgXCJub3RcIjpcbiAgICAgICAgICAgIHZhbGlkYXRlQm9vbGVhbih2YWx1ZSk7XG4gICAgICAgICAgICByZXR1cm4gIXZhbHVlO1xuXG4gICAgICAgIGNhc2UgXCJ0b3VwcGVyXCI6XG4gICAgICAgIGNhc2UgXCJzdHJ0b3VwcGVyXCI6XG4gICAgICAgIGNhc2UgXCJ0b3VwcGVyY2FzZVwiOlxuICAgICAgICAgICAgdmFsaWRhdGVTdHJpbmcodmFsdWUpO1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlLnRvVXBwZXJDYXNlKCk7XG5cbiAgICAgICAgY2FzZSBcInRvc3RyaW5nXCI6XG4gICAgICAgICAgICByZXR1cm4gYCR7dmFsdWV9YDtcblxuICAgICAgICBjYXNlIFwidG9pbnRlZ2VyXCI6XG4gICAgICAgICAgICBsZXQgbiA9IHBhcnNlSW50KHZhbHVlKTtcbiAgICAgICAgICAgIHZhbGlkYXRlSW50ZWdlcihuKTtcbiAgICAgICAgICAgIHJldHVybiBuO1xuXG4gICAgICAgIGNhc2UgXCJ0by1qc29uXCI6XG4gICAgICAgIGNhc2UgXCJ0b2pzb25cIjpcbiAgICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh2YWx1ZSk7XG5cbiAgICAgICAgY2FzZSBcImZyb20tanNvblwiOlxuICAgICAgICBjYXNlIFwiZnJvbWpzb25cIjpcbiAgICAgICAgICAgIHJldHVybiBKU09OLnBhcnNlKHZhbHVlKTtcblxuICAgICAgICBjYXNlIFwidHJpbVwiOlxuICAgICAgICAgICAgdmFsaWRhdGVTdHJpbmcodmFsdWUpO1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlLnRyaW0oKTtcblxuICAgICAgICBjYXNlIFwicmF3dXJsZW5jb2RlXCI6XG4gICAgICAgICAgICB2YWxpZGF0ZVN0cmluZyh2YWx1ZSk7XG4gICAgICAgICAgICByZXR1cm4gZW5jb2RlVVJJQ29tcG9uZW50KHZhbHVlKVxuICAgICAgICAgICAgICAgIC5yZXBsYWNlKC8hL2csIFwiJTIxXCIpXG4gICAgICAgICAgICAgICAgLnJlcGxhY2UoLycvZywgXCIlMjdcIilcbiAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFwoL2csIFwiJTI4XCIpXG4gICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xcKS9nLCBcIiUyOVwiKVxuICAgICAgICAgICAgICAgIC5yZXBsYWNlKC9cXCovZywgXCIlMkFcIik7XG5cbiAgICAgICAgY2FzZSBcImNhbGxcIjpcbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogY2FsbGJhY2stZGVmaW5pdGlvblxuICAgICAgICAgICAgICogZnVuY3Rpb24gY2FsbGJhY2sodmFsdWUsIC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAqICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgICogfVxuICAgICAgICAgICAgICovXG5cbiAgICAgICAgICAgIGxldCBjYWxsYmFjaztcbiAgICAgICAgICAgIGxldCBjYWxsYmFja05hbWUgPSBhcmdzLnNoaWZ0KCk7XG4gICAgICAgICAgICBsZXQgY29udGV4dCA9IGdldEdsb2JhbCgpO1xuXG4gICAgICAgICAgICBpZiAoaXNPYmplY3QodmFsdWUpICYmIHZhbHVlLmhhc093blByb3BlcnR5KGNhbGxiYWNrTmFtZSkpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayA9IHZhbHVlW2NhbGxiYWNrTmFtZV07XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuY2FsbGJhY2tzLmhhcyhjYWxsYmFja05hbWUpKSB7XG4gICAgICAgICAgICAgICAgbGV0IHMgPSB0aGlzLmNhbGxiYWNrcy5nZXQoY2FsbGJhY2tOYW1lKTtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayA9IHM/LltcImNhbGxiYWNrXCJdO1xuICAgICAgICAgICAgICAgIGNvbnRleHQgPSBzPy5bXCJjb250ZXh0XCJdO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2Ygd2luZG93ID09PSBcIm9iamVjdFwiICYmIHdpbmRvdy5oYXNPd25Qcm9wZXJ0eShjYWxsYmFja05hbWUpKSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2sgPSB3aW5kb3dbY2FsbGJhY2tOYW1lXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhbGlkYXRlRnVuY3Rpb24oY2FsbGJhY2spO1xuXG4gICAgICAgICAgICBhcmdzLnVuc2hpZnQodmFsdWUpO1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmNhbGwoY29udGV4dCwgLi4uYXJncyk7XG5cbiAgICAgICAgY2FzZSBcInBsYWluXCI6XG4gICAgICAgIGNhc2UgXCJwbGFpbnRleHRcIjpcbiAgICAgICAgICAgIHZhbGlkYXRlU3RyaW5nKHZhbHVlKTtcbiAgICAgICAgICAgIGxldCBkb2MgPSBuZXcgRE9NUGFyc2VyKCkucGFyc2VGcm9tU3RyaW5nKHZhbHVlLCBcInRleHQvaHRtbFwiKTtcbiAgICAgICAgICAgIHJldHVybiBkb2MuYm9keS50ZXh0Q29udGVudCB8fCBcIlwiO1xuXG4gICAgICAgIGNhc2UgXCJpZlwiOlxuICAgICAgICBjYXNlIFwiP1wiOlxuICAgICAgICAgICAgdmFsaWRhdGVQcmltaXRpdmUodmFsdWUpO1xuXG4gICAgICAgICAgICBsZXQgdHJ1ZVN0YXRlbWVudCA9IGFyZ3Muc2hpZnQoKSB8fCB1bmRlZmluZWQ7XG4gICAgICAgICAgICBsZXQgZmFsc2VTdGF0ZW1lbnQgPSBhcmdzLnNoaWZ0KCkgfHwgdW5kZWZpbmVkO1xuXG4gICAgICAgICAgICBpZiAodHJ1ZVN0YXRlbWVudCA9PT0gXCJ2YWx1ZVwiKSB7XG4gICAgICAgICAgICAgICAgdHJ1ZVN0YXRlbWVudCA9IHZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRydWVTdGF0ZW1lbnQgPT09IFwiXFxcXHZhbHVlXCIpIHtcbiAgICAgICAgICAgICAgICB0cnVlU3RhdGVtZW50ID0gXCJ2YWx1ZVwiO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodHJ1ZVN0YXRlbWVudCA9PT0gXCJcXFxcdW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgICAgICB0cnVlU3RhdGVtZW50ID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodHJ1ZVN0YXRlbWVudCA9PT0gXCJcXFxcbnVsbFwiKSB7XG4gICAgICAgICAgICAgICAgdHJ1ZVN0YXRlbWVudCA9IG51bGw7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChmYWxzZVN0YXRlbWVudCA9PT0gXCJ2YWx1ZVwiKSB7XG4gICAgICAgICAgICAgICAgZmFsc2VTdGF0ZW1lbnQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChmYWxzZVN0YXRlbWVudCA9PT0gXCJcXFxcdmFsdWVcIikge1xuICAgICAgICAgICAgICAgIGZhbHNlU3RhdGVtZW50ID0gXCJ2YWx1ZVwiO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoZmFsc2VTdGF0ZW1lbnQgPT09IFwiXFxcXHVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICAgICAgZmFsc2VTdGF0ZW1lbnQgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChmYWxzZVN0YXRlbWVudCA9PT0gXCJcXFxcbnVsbFwiKSB7XG4gICAgICAgICAgICAgICAgZmFsc2VTdGF0ZW1lbnQgPSBudWxsO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgY29uZGl0aW9uID1cbiAgICAgICAgICAgICAgICAodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gXCJcIiAmJiB2YWx1ZSAhPT0gXCJvZmZcIiAmJiB2YWx1ZSAhPT0gXCJmYWxzZVwiICYmIHZhbHVlICE9PSBmYWxzZSkgfHxcbiAgICAgICAgICAgICAgICB2YWx1ZSA9PT0gXCJvblwiIHx8XG4gICAgICAgICAgICAgICAgdmFsdWUgPT09IFwidHJ1ZVwiIHx8XG4gICAgICAgICAgICAgICAgdmFsdWUgPT09IHRydWU7XG4gICAgICAgICAgICByZXR1cm4gY29uZGl0aW9uID8gdHJ1ZVN0YXRlbWVudCA6IGZhbHNlU3RhdGVtZW50O1xuXG4gICAgICAgIGNhc2UgXCJ1Y2ZpcnN0XCI6XG4gICAgICAgICAgICB2YWxpZGF0ZVN0cmluZyh2YWx1ZSk7XG5cbiAgICAgICAgICAgIGxldCBmaXJzdGNoYXIgPSB2YWx1ZS5jaGFyQXQoMCkudG9VcHBlckNhc2UoKTtcbiAgICAgICAgICAgIHJldHVybiBmaXJzdGNoYXIgKyB2YWx1ZS5zdWJzdHIoMSk7XG4gICAgICAgIGNhc2UgXCJ1Y3dvcmRzXCI6XG4gICAgICAgICAgICB2YWxpZGF0ZVN0cmluZyh2YWx1ZSk7XG5cbiAgICAgICAgICAgIHJldHVybiB2YWx1ZS5yZXBsYWNlKC9eKFthLXpcXHUwMEUwLVxcdTAwRkNdKXxcXHMrKFthLXpcXHUwMEUwLVxcdTAwRkNdKS9nLCBmdW5jdGlvbiAodikge1xuICAgICAgICAgICAgICAgIHJldHVybiB2LnRvVXBwZXJDYXNlKCk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICBjYXNlIFwiY291bnRcIjpcbiAgICAgICAgY2FzZSBcImxlbmd0aFwiOlxuICAgICAgICAgICAgaWYgKChpc1N0cmluZyh2YWx1ZSkgfHwgaXNPYmplY3QodmFsdWUpIHx8IGlzQXJyYXkodmFsdWUpKSAmJiB2YWx1ZS5oYXNPd25Qcm9wZXJ0eShcImxlbmd0aFwiKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZS5sZW5ndGg7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYHVuc3VwcG9ydGVkIHR5cGUgJHt0eXBlb2YgdmFsdWV9YCk7XG5cbiAgICAgICAgY2FzZSBcInRvLWJhc2U2NFwiOlxuICAgICAgICBjYXNlIFwiYnRvYVwiOlxuICAgICAgICBjYXNlIFwiYmFzZTY0XCI6XG4gICAgICAgICAgICByZXR1cm4gYnRvYShjb252ZXJ0VG9TdHJpbmcodmFsdWUpKTtcblxuICAgICAgICBjYXNlIFwiYXRvYlwiOlxuICAgICAgICBjYXNlIFwiZnJvbS1iYXNlNjRcIjpcbiAgICAgICAgICAgIHJldHVybiBhdG9iKGNvbnZlcnRUb1N0cmluZyh2YWx1ZSkpO1xuXG4gICAgICAgIGNhc2UgXCJlbXB0eVwiOlxuICAgICAgICAgICAgcmV0dXJuIFwiXCI7XG5cbiAgICAgICAgY2FzZSBcInVuZGVmaW5lZFwiOlxuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgICAgICBjYXNlIFwiZGVidWdcIjpcbiAgICAgICAgICAgIGlmIChpc09iamVjdChjb25zb2xlKSkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKHZhbHVlKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuXG4gICAgICAgIGNhc2UgXCJwcmVmaXhcIjpcbiAgICAgICAgICAgIHZhbGlkYXRlU3RyaW5nKHZhbHVlKTtcbiAgICAgICAgICAgIGxldCBwcmVmaXggPSBhcmdzPy5bMF07XG4gICAgICAgICAgICByZXR1cm4gcHJlZml4ICsgdmFsdWU7XG5cbiAgICAgICAgY2FzZSBcInN1ZmZpeFwiOlxuICAgICAgICAgICAgdmFsaWRhdGVTdHJpbmcodmFsdWUpO1xuICAgICAgICAgICAgbGV0IHN1ZmZpeCA9IGFyZ3M/LlswXTtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZSArIHN1ZmZpeDtcblxuICAgICAgICBjYXNlIFwidW5pcWlkXCI6XG4gICAgICAgICAgICByZXR1cm4gbmV3IElEKCkudG9TdHJpbmcoKTtcblxuICAgICAgICBjYXNlIFwiZmlyc3Qta2V5XCI6XG4gICAgICAgIGNhc2UgXCJsYXN0LWtleVwiOlxuICAgICAgICBjYXNlIFwibnRoLWxhc3Qta2V5XCI6XG4gICAgICAgIGNhc2UgXCJudGgta2V5XCI6XG4gICAgICAgICAgICBpZiAoIWlzT2JqZWN0KHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInR5cGUgbm90IHN1cHBvcnRlZFwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKHZhbHVlKS5zb3J0KCk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmNvbW1hbmQgPT09IFwiZmlyc3Qta2V5XCIpIHtcbiAgICAgICAgICAgICAgICBrZXkgPSAwO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLmNvbW1hbmQgPT09IFwibGFzdC1rZXlcIikge1xuICAgICAgICAgICAgICAgIGtleSA9IGtleXMubGVuZ3RoIC0gMTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAga2V5ID0gdmFsaWRhdGVJbnRlZ2VyKHBhcnNlSW50KGFyZ3Muc2hpZnQoKSkpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuY29tbWFuZCA9PT0gXCJudGgtbGFzdC1rZXlcIikge1xuICAgICAgICAgICAgICAgICAgICBrZXkgPSBrZXlzLmxlbmd0aCAtIGtleSAtIDE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBkZWZhdWx0VmFsdWUgPSBhcmdzLnNoaWZ0KCkgfHwgXCJcIjtcblxuICAgICAgICAgICAgbGV0IHVzZUtleSA9IGtleXM/LltrZXldO1xuXG4gICAgICAgICAgICBpZiAodmFsdWU/Llt1c2VLZXldKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlPy5bdXNlS2V5XTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTtcblxuICAgICAgICBjYXNlIFwia2V5XCI6XG4gICAgICAgIGNhc2UgXCJwcm9wZXJ0eVwiOlxuICAgICAgICBjYXNlIFwiaW5kZXhcIjpcbiAgICAgICAgICAgIGtleSA9IGFyZ3Muc2hpZnQoKSB8fCB1bmRlZmluZWQ7XG5cbiAgICAgICAgICAgIGlmIChrZXkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIm1pc3Npbmcga2V5IHBhcmFtZXRlclwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZGVmYXVsdFZhbHVlID0gYXJncy5zaGlmdCgpIHx8IHVuZGVmaW5lZDtcblxuICAgICAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgTWFwKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF2YWx1ZS5oYXMoa2V5KSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGVmYXVsdFZhbHVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWUuZ2V0KGtleSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChpc09iamVjdCh2YWx1ZSkgfHwgaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICBpZiAodmFsdWU/LltrZXldKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZT8uW2tleV07XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidHlwZSBub3Qgc3VwcG9ydGVkXCIpO1xuXG4gICAgICAgIGNhc2UgXCJwYXRoLWV4aXN0c1wiOlxuICAgICAgICAgICAga2V5ID0gYXJncy5zaGlmdCgpO1xuICAgICAgICAgICAgaWYgKGtleSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwibWlzc2luZyBrZXkgcGFyYW1ldGVyXCIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gbmV3IFBhdGhmaW5kZXIodmFsdWUpLmV4aXN0cyhrZXkpO1xuXG4gICAgICAgIGNhc2UgXCJjb25jYXRcIjpcbiAgICAgICAgICAgIGxldCBwZjIgPSBuZXcgUGF0aGZpbmRlcih2YWx1ZSk7XG4gICAgICAgICAgICBsZXQgY29uY2F0ID0gXCJcIjtcbiAgICAgICAgICAgIHdoaWxlIChhcmdzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBrZXkgPSBhcmdzLnNoaWZ0KCk7XG4gICAgICAgICAgICAgICAgaWYgKGtleSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIm1pc3Npbmcga2V5IHBhcmFtZXRlclwiKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBhZGQgZW1wdHkgc3RyaW5nc1xuICAgICAgICAgICAgICAgIGlmIChpc1N0cmluZyhrZXkpICYmIGtleS50cmltKCkgPT09IFwiXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uY2F0ICs9IGtleTtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKCFwZjIuZXhpc3RzKGtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uY2F0ICs9IGtleTtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxldCB2ID0gcGYyLmdldFZpYShrZXkpO1xuICAgICAgICAgICAgICAgIGlmICghaXNQcmltaXRpdmUodikpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidmFsdWUgaXMgbm90IHByaW1pdGl2ZVwiKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25jYXQgKz0gdjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGNvbmNhdDtcbiAgICAgICAgY2FzZSBcInBhdGhcIjpcbiAgICAgICAgICAgIGtleSA9IGFyZ3Muc2hpZnQoKTtcbiAgICAgICAgICAgIGlmIChrZXkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIm1pc3Npbmcga2V5IHBhcmFtZXRlclwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGV0IHBmID0gbmV3IFBhdGhmaW5kZXIodmFsdWUpO1xuXG4gICAgICAgICAgICBpZiAoIXBmLmV4aXN0cyhrZXkpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHBmLmdldFZpYShrZXkpO1xuXG4gICAgICAgIGNhc2UgXCJzdWJzdHJpbmdcIjpcbiAgICAgICAgICAgIHZhbGlkYXRlU3RyaW5nKHZhbHVlKTtcblxuICAgICAgICAgICAgbGV0IHN0YXJ0ID0gcGFyc2VJbnQoYXJnc1swXSkgfHwgMDtcbiAgICAgICAgICAgIGxldCBlbmQgPSAocGFyc2VJbnQoYXJnc1sxXSkgfHwgMCkgKyBzdGFydDtcblxuICAgICAgICAgICAgcmV0dXJuIHZhbHVlLnN1YnN0cmluZyhzdGFydCwgZW5kKTtcblxuICAgICAgICBjYXNlIFwibm9wXCI6XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG5cbiAgICAgICAgY2FzZSBcIj8/XCI6XG4gICAgICAgIGNhc2UgXCJkZWZhdWx0XCI6XG4gICAgICAgICAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZGVmYXVsdFZhbHVlID0gYXJncy5zaGlmdCgpO1xuICAgICAgICAgICAgbGV0IGRlZmF1bHRUeXBlID0gYXJncy5zaGlmdCgpO1xuICAgICAgICAgICAgaWYgKGRlZmF1bHRUeXBlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBkZWZhdWx0VHlwZSA9IFwic3RyaW5nXCI7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHN3aXRjaCAoZGVmYXVsdFR5cGUpIHtcbiAgICAgICAgICAgICAgICBjYXNlIFwiaW50XCI6XG4gICAgICAgICAgICAgICAgY2FzZSBcImludGVnZXJcIjpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlSW50KGRlZmF1bHRWYWx1ZSk7XG4gICAgICAgICAgICAgICAgY2FzZSBcImZsb2F0XCI6XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZUZsb2F0KGRlZmF1bHRWYWx1ZSk7XG4gICAgICAgICAgICAgICAgY2FzZSBcInVuZGVmaW5lZFwiOlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJib29sXCI6XG4gICAgICAgICAgICAgICAgY2FzZSBcImJvb2xlYW5cIjpcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlID0gZGVmYXVsdFZhbHVlLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgICAgICAgICAoZGVmYXVsdFZhbHVlICE9PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlICE9PSBcIlwiICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlICE9PSBcIm9mZlwiICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlICE9PSBcImZhbHNlXCIgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0VmFsdWUgIT09IFwiZmFsc2VcIikgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRWYWx1ZSA9PT0gXCJvblwiIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0VmFsdWUgPT09IFwidHJ1ZVwiIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0VmFsdWUgPT09IFwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgY2FzZSBcInN0cmluZ1wiOlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYCR7ZGVmYXVsdFZhbHVlfWA7XG4gICAgICAgICAgICAgICAgY2FzZSBcIm9iamVjdFwiOlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gSlNPTi5wYXJzZShhdG9iKGRlZmF1bHRWYWx1ZSkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0eXBlIG5vdCBzdXBwb3J0ZWRcIik7XG5cbiAgICAgICAgY2FzZSBcIm1hcFwiOlxuICAgICAgICAgICAgbWFwID0gbmV3IE1hcCgpO1xuICAgICAgICAgICAgd2hpbGUgKGFyZ3MubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGtleVZhbHVlID0gYXJncy5zaGlmdCgpO1xuICAgICAgICAgICAgICAgIGlmIChrZXlWYWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIm1pc3Npbmcga2V5IHBhcmFtZXRlclwiKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBrZXlWYWx1ZSA9IGtleVZhbHVlLnNwbGl0KFwiPVwiKTtcbiAgICAgICAgICAgICAgICBtYXAuc2V0KGtleVZhbHVlWzBdLCBrZXlWYWx1ZVsxXSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBtYXAuZ2V0KHZhbHVlKTtcblxuICAgICAgICBjYXNlIFwiZXF1YWxzXCI6XG4gICAgICAgICAgICBpZiAoYXJncy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJtaXNzaW5nIHZhbHVlIHBhcmFtZXRlclwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFsaWRhdGVQcmltaXRpdmUodmFsdWUpO1xuXG4gICAgICAgICAgICBjb25zdCBlcXVhbHNWYWx1ZSA9IGFyZ3Muc2hpZnQoKTtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBUaGUgaGlzdG9yeSBvZiBcdTIwMUN0eXBlb2YgbnVsbFx1MjAxRFxuICAgICAgICAgICAgICogaHR0cHM6Ly8yYWxpdHkuY29tLzIwMTMvMTAvdHlwZW9mLW51bGwuaHRtbFxuICAgICAgICAgICAgICogSW4gSmF2YVNjcmlwdCwgdHlwZW9mIG51bGwgaXMgJ29iamVjdCcsIHdoaWNoIGluY29ycmVjdGx5IHN1Z2dlc3RzXG4gICAgICAgICAgICAgKiB0aGF0IG51bGwgaXMgYW4gb2JqZWN0LlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBpZiAodmFsdWUgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXF1YWxzVmFsdWUgPT09IFwibnVsbFwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHR5cGVPZlZhbHVlID0gdHlwZW9mIHZhbHVlO1xuXG4gICAgICAgICAgICBzd2l0Y2ggKHR5cGVPZlZhbHVlKSB7XG4gICAgICAgICAgICAgICAgY2FzZSBcInN0cmluZ1wiOlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWUgPT09IGVxdWFsc1ZhbHVlO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlID09PSBwYXJzZUZsb2F0KGVxdWFsc1ZhbHVlKTtcbiAgICAgICAgICAgICAgICBjYXNlIFwiYm9vbGVhblwiOlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWUgPT09IChlcXVhbHNWYWx1ZSA9PT0gXCJ0cnVlXCIgfHwgZXF1YWxzVmFsdWUgPT09IFwib25cIik7XG4gICAgICAgICAgICAgICAgY2FzZSBcInVuZGVmaW5lZFwiOlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZXF1YWxzVmFsdWUgPT09IFwidW5kZWZpbmVkXCI7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidHlwZSBub3Qgc3VwcG9ydGVkXCIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIGNhc2UgXCJtb25leVwiOlxuICAgICAgICBjYXNlIFwiY3VycmVuY3lcIjpcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgbG9jYWxlID0gZ2V0TG9jYWxlT2ZEb2N1bWVudCgpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgdW5zdXBwb3J0ZWQgbG9jYWxlIG9yIG1pc3NpbmcgZm9ybWF0ICgke2UubWVzc2FnZX0pYCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbmN5ID0gdmFsdWUuc3Vic3RyaW5nKDAsIDMpO1xuICAgICAgICAgICAgaWYgKCFjdXJyZW5jeSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIm1pc3NpbmcgY3VycmVuY3kgcGFyYW1ldGVyXCIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBtYXhpbXVtRnJhY3Rpb25EaWdpdHMgPSBhcmdzPy5bMF0gfHwgMjtcbiAgICAgICAgICAgIGNvbnN0IHJvdW5kaW5nSW5jcmVtZW50ID0gYXJncz8uWzFdIHx8IDU7XG5cbiAgICAgICAgICAgIGNvbnN0IG5mID0gbmV3IEludGwuTnVtYmVyRm9ybWF0KGxvY2FsZSwge1xuICAgICAgICAgICAgICAgIHN0eWxlOiBcImN1cnJlbmN5XCIsXG4gICAgICAgICAgICAgICAgY3VycmVuY3k6IGN1cnJlbmN5LFxuICAgICAgICAgICAgICAgIG1heGltdW1GcmFjdGlvbkRpZ2l0czogbWF4aW11bUZyYWN0aW9uRGlnaXRzLFxuICAgICAgICAgICAgICAgIHJvdW5kaW5nSW5jcmVtZW50OiByb3VuZGluZ0luY3JlbWVudCxcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICByZXR1cm4gbmYuZm9ybWF0KHZhbHVlLnN1YnN0cmluZygzKSk7XG5cbiAgICAgICAgY2FzZSBcInRpbWVzdGFtcFwiOlxuICAgICAgICAgICAgZGF0ZSA9IG5ldyBEYXRlKHZhbHVlKTtcbiAgICAgICAgICAgIHRpbWVzdGFtcCA9IGRhdGUuZ2V0VGltZSgpO1xuICAgICAgICAgICAgaWYgKGlzTmFOKHRpbWVzdGFtcCkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJpbnZhbGlkIGRhdGVcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGltZXN0YW1wO1xuXG4gICAgICAgIGNhc2UgXCJ0aW1lXCI6XG4gICAgICAgICAgICBkYXRlID0gbmV3IERhdGUodmFsdWUpO1xuICAgICAgICAgICAgaWYgKGlzTmFOKGRhdGUuZ2V0VGltZSgpKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImludmFsaWQgZGF0ZVwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBsb2NhbGUgPSBnZXRMb2NhbGVPZkRvY3VtZW50KCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRhdGUudG9Mb2NhbGVUaW1lU3RyaW5nKGxvY2FsZSk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnN1cHBvcnRlZCBsb2NhbGUgb3IgbWlzc2luZyBmb3JtYXQgKCR7ZS5tZXNzYWdlfSlgKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICBjYXNlIFwiZGF0ZXRpbWVcIjpcbiAgICAgICAgICAgIGRhdGUgPSBuZXcgRGF0ZSh2YWx1ZSk7XG4gICAgICAgICAgICBpZiAoaXNOYU4oZGF0ZS5nZXRUaW1lKCkpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiaW52YWxpZCBkYXRlXCIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGxvY2FsZSA9IGdldExvY2FsZU9mRG9jdW1lbnQoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZGF0ZS50b0xvY2FsZVN0cmluZyhsb2NhbGUpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgdW5zdXBwb3J0ZWQgbG9jYWxlIG9yIG1pc3NpbmcgZm9ybWF0ICgke2UubWVzc2FnZX0pYCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgY2FzZSBcImRhdGVcIjpcbiAgICAgICAgICAgIGRhdGUgPSBuZXcgRGF0ZSh2YWx1ZSk7XG4gICAgICAgICAgICBpZiAoaXNOYU4oZGF0ZS5nZXRUaW1lKCkpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiaW52YWxpZCBkYXRlXCIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGxvY2FsZSA9IGdldExvY2FsZU9mRG9jdW1lbnQoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZGF0ZS50b0xvY2FsZURhdGVTdHJpbmcobG9jYWxlKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuc3VwcG9ydGVkIGxvY2FsZSBvciBtaXNzaW5nIGZvcm1hdCAoJHtlLm1lc3NhZ2V9KWApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIGNhc2UgXCJ5ZWFyXCI6XG4gICAgICAgICAgICBkYXRlID0gbmV3IERhdGUodmFsdWUpO1xuICAgICAgICAgICAgaWYgKGlzTmFOKGRhdGUuZ2V0VGltZSgpKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImludmFsaWQgZGF0ZVwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGRhdGUuZ2V0RnVsbFllYXIoKTtcblxuICAgICAgICBjYXNlIFwibW9udGhcIjpcbiAgICAgICAgICAgIGRhdGUgPSBuZXcgRGF0ZSh2YWx1ZSk7XG4gICAgICAgICAgICBpZiAoaXNOYU4oZGF0ZS5nZXRUaW1lKCkpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiaW52YWxpZCBkYXRlXCIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gZGF0ZS5nZXRNb250aCgpICsgMTtcblxuICAgICAgICBjYXNlIFwiZGF5XCI6XG4gICAgICAgICAgICBkYXRlID0gbmV3IERhdGUodmFsdWUpO1xuICAgICAgICAgICAgaWYgKGlzTmFOKGRhdGUuZ2V0VGltZSgpKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImludmFsaWQgZGF0ZVwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGRhdGUuZ2V0RGF0ZSgpO1xuXG4gICAgICAgIGNhc2UgXCJ3ZWVrZGF5XCI6XG4gICAgICAgICAgICBkYXRlID0gbmV3IERhdGUodmFsdWUpO1xuICAgICAgICAgICAgaWYgKGlzTmFOKGRhdGUuZ2V0VGltZSgpKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImludmFsaWQgZGF0ZVwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGRhdGUuZ2V0RGF5KCk7XG5cbiAgICAgICAgY2FzZSBcImhvdXJcIjpcbiAgICAgICAgY2FzZSBcImhvdXJzXCI6XG4gICAgICAgICAgICBkYXRlID0gbmV3IERhdGUodmFsdWUpO1xuICAgICAgICAgICAgaWYgKGlzTmFOKGRhdGUuZ2V0VGltZSgpKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImludmFsaWQgZGF0ZVwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGRhdGUuZ2V0SG91cnMoKTtcblxuICAgICAgICBjYXNlIFwibWludXRlXCI6XG4gICAgICAgIGNhc2UgXCJtaW51dGVzXCI6XG4gICAgICAgICAgICBkYXRlID0gbmV3IERhdGUodmFsdWUpO1xuICAgICAgICAgICAgaWYgKGlzTmFOKGRhdGUuZ2V0VGltZSgpKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImludmFsaWQgZGF0ZVwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGRhdGUuZ2V0TWludXRlcygpO1xuXG4gICAgICAgIGNhc2UgXCJzZWNvbmRcIjpcbiAgICAgICAgY2FzZSBcInNlY29uZHNcIjpcbiAgICAgICAgICAgIGRhdGUgPSBuZXcgRGF0ZSh2YWx1ZSk7XG4gICAgICAgICAgICBpZiAoaXNOYU4oZGF0ZS5nZXRUaW1lKCkpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiaW52YWxpZCBkYXRlXCIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gZGF0ZS5nZXRTZWNvbmRzKCk7XG5cbiAgICAgICAgY2FzZSBcImkxOG5cIjpcbiAgICAgICAgY2FzZSBcInRyYW5zbGF0aW9uXCI6XG4gICAgICAgICAgICB0cmFuc2xhdGlvbnMgPSBnZXREb2N1bWVudFRyYW5zbGF0aW9ucygpO1xuICAgICAgICAgICAgaWYgKCEodHJhbnNsYXRpb25zIGluc3RhbmNlb2YgVHJhbnNsYXRpb25zKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIm1pc3NpbmcgdHJhbnNsYXRpb25zXCIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBrZXkgPSBhcmdzLnNoaWZ0KCkgfHwgdW5kZWZpbmVkO1xuICAgICAgICAgICAgaWYgKGtleSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAga2V5ID0gdmFsdWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGRlZmF1bHRWYWx1ZSA9IGFyZ3Muc2hpZnQoKSB8fCB1bmRlZmluZWQ7XG4gICAgICAgICAgICByZXR1cm4gdHJhbnNsYXRpb25zLmdldFRleHQoa2V5LCBkZWZhdWx0VmFsdWUpO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVua25vd24gY29tbWFuZCAke3RoaXMuY29tbWFuZH1gKTtcbiAgICB9XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBCYXNlIH0gZnJvbSBcIi4uL3R5cGVzL2Jhc2UubWpzXCI7XG5pbXBvcnQgeyB2YWxpZGF0ZVN0cmluZyB9IGZyb20gXCIuLi90eXBlcy92YWxpZGF0ZS5tanNcIjtcbmltcG9ydCB7IFRyYW5zZm9ybWVyIH0gZnJvbSBcIi4vdHJhbnNmb3JtZXIubWpzXCI7XG5cbmV4cG9ydCB7IFBpcGUgfTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuY29uc3QgREVMSU1JVEVSID0gXCJ8XCI7XG5cbi8qKlxuICogVGhlIHBpcGUgY2xhc3MgbWFrZXMgaXQgcG9zc2libGUgdG8gY29tYmluZSBzZXZlcmFsIHByb2Nlc3Npbmcgc3RlcHMuXG4gKlxuICogQSBwaXBlIGNvbnNpc3RzIG9mIGNvbW1hbmRzIHdob3NlIGlucHV0IGFuZCBvdXRwdXQgYXJlIGNvbm5lY3RlZCB3aXRoIHRoZSBwaXBlIHN5bWJvbCBgfGAuXG4gKlxuICogV2l0aCB0aGUgUGlwZSwgcHJvY2Vzc2luZyBzdGVwcyBjYW4gYmUgY29tYmluZWQuIEhlcmUsIHRoZSB2YWx1ZSBvZiBhbiBvYmplY3QgaXMgYWNjZXNzZWQgdmlhIHRoZSBwYXRoZmluZGVyIChwYXRoIGNvbW1hbmQpLlxuICogdGhlIHdvcmQgaXMgdGhlbiBjb252ZXJ0ZWQgdG8gdXBwZXJjYXNlIGxldHRlcnMgYW5kIGEgcHJlZml4IEhlbGxvIGlzIGFkZGVkLiB0aGUgdHdvIGJhY2tzbGFzaCBzYWZlIHRoZSBzcGFjZSBjaGFyLlxuICpcbiAqIEBleHRlcm5hbEV4YW1wbGUgIC4uLy4uL2V4YW1wbGUvZGF0YS9waXBlLm1qc1xuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS41LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5EYXRhXG4gKi9cbmNsYXNzIFBpcGUgZXh0ZW5kcyBCYXNlIHtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcGlwZSBhIHBpcGUgY29uc2lzdHMgb2YgY29tbWFuZHMgd2hvc2UgaW5wdXQgYW5kIG91dHB1dCBhcmUgY29ubmVjdGVkIHdpdGggdGhlIHBpcGUgc3ltYm9sIGB8YC5cbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9XG4gICAgICovXG4gICAgY29uc3RydWN0b3IocGlwZSkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB2YWxpZGF0ZVN0cmluZyhwaXBlKTtcblxuICAgICAgICB0aGlzLnBpcGUgPSBwaXBlLnNwbGl0KERFTElNSVRFUikubWFwKCh2KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFRyYW5zZm9ybWVyKHYpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGNhbGxiYWNrXG4gICAgICogQHBhcmFtIHtvYmplY3R9IGNvbnRleHRcbiAgICAgKiBAcmV0dXJucyB7VHJhbnNmb3JtZXJ9XG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYSBzdHJpbmdcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIGZ1bmN0aW9uXG4gICAgICovXG4gICAgc2V0Q2FsbGJhY2sobmFtZSwgY2FsbGJhY2ssIGNvbnRleHQpIHtcbiAgICAgICAgZm9yIChjb25zdCBbLCB0XSBvZiBPYmplY3QuZW50cmllcyh0aGlzLnBpcGUpKSB7XG4gICAgICAgICAgICB0LnNldENhbGxiYWNrKG5hbWUsIGNhbGxiYWNrLCBjb250ZXh0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHJ1biBhIHBpcGVcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAgICAgKiBAcmV0dXJucyB7Kn1cbiAgICAgKi9cbiAgICBydW4odmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGlwZS5yZWR1Y2UoKGFjY3VtdWxhdG9yLCB0cmFuc2Zvcm1lciwgY3VycmVudEluZGV4LCBhcnJheSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRyYW5zZm9ybWVyLnJ1bihhY2N1bXVsYXRvcik7XG4gICAgICAgIH0sIHZhbHVlKTtcbiAgICB9XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBpbnRlcm5hbFN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQgeyBleHRlbmQgfSBmcm9tIFwiLi4vZGF0YS9leHRlbmQubWpzXCI7XG5pbXBvcnQgeyBQaXBlIH0gZnJvbSBcIi4uL2RhdGEvcGlwZS5tanNcIjtcblxuaW1wb3J0IHsgQmFzZVdpdGhPcHRpb25zIH0gZnJvbSBcIi4uL3R5cGVzL2Jhc2V3aXRob3B0aW9ucy5tanNcIjtcbmltcG9ydCB7IGlzT2JqZWN0LCBpc1N0cmluZyB9IGZyb20gXCIuLi90eXBlcy9pcy5tanNcIjtcbmltcG9ydCB7IHZhbGlkYXRlQXJyYXksIHZhbGlkYXRlU3RyaW5nIH0gZnJvbSBcIi4uL3R5cGVzL3ZhbGlkYXRlLm1qc1wiO1xuXG5leHBvcnQgeyBGb3JtYXR0ZXIgfTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHR5cGUge3N5bWJvbH1cbiAqL1xuY29uc3QgaW50ZXJuYWxPYmplY3RTeW1ib2wgPSBTeW1ib2woXCJpbnRlcm5hbE9iamVjdFwiKTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHR5cGUge3N5bWJvbH1cbiAqL1xuY29uc3Qgd2F0Y2hkb2dTeW1ib2wgPSBTeW1ib2woXCJ3YXRjaGRvZ1wiKTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHR5cGUge3N5bWJvbH1cbiAqL1xuY29uc3QgbWFya2VyT3BlbkluZGV4U3ltYm9sID0gU3ltYm9sKFwibWFya2VyT3BlbkluZGV4XCIpO1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAdHlwZSB7c3ltYm9sfVxuICovXG5jb25zdCBtYXJrZXJDbG9zZUluZGV4U3ltYm9sID0gU3ltYm9sKFwibWFya2VyY2xvc2VJbmRleFwiKTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHR5cGUge3N5bWJvbH1cbiAqL1xuY29uc3Qgd29ya2luZ0RhdGFTeW1ib2wgPSBTeW1ib2woXCJ3b3JraW5nRGF0YVwiKTtcblxuLyoqXG4gKiBNZXNzYWdlcyBjYW4gYmUgZm9ybWF0dGVkIHdpdGggdGhlIGZvcm1hdHRlci4gVG8gZG8gdGhpcywgYW4gb2JqZWN0IHdpdGggdGhlIHZhbHVlcyBtdXN0IGJlIHBhc3NlZCB0byB0aGUgZm9ybWF0dGVyLiBUaGUgbWVzc2FnZSBjYW4gdGhlbiBjb250YWluIHBsYWNlaG9sZGVycy5cbiAqXG4gKiBMb29rIGF0IHRoZSBleGFtcGxlIGJlbG93LiBUaGUgcGxhY2Vob2xkZXJzIHVzZSB0aGUgbG9naWMgb2YgUGlwZS5cbiAqXG4gKiAjIyBNYXJrZXIgaW4gbWFya2VyXG4gKlxuICogTWFya2VycyBjYW4gYmUgbmVzdGVkLiBIZXJlLCB0aGUgaW5uZXIgbWFya2VyIGlzIHJlc29sdmVkIGZpcnN0IGAke3N1YmtleX0gXHUyMUE2IDEgPSAke215a2V5Mn1gIGFuZCB0aGVuIHRoZSBvdXRlciBtYXJrZXIgYCR7bXlrZXkyfWAuXG4gKlxuICogYGBgXG4gKiBjb25zdCB0ZXh0ID0gJyR7bXlrZXkke3N1YmtleX19JztcbiAqIGxldCBvYmogPSB7XG4gKiAgbXlrZXkyOiBcIjFcIixcbiAqICBzdWJrZXk6IFwiMlwiXG4gKiB9O1xuICpcbiAqIG5ldyBGb3JtYXR0ZXIob2JqKS5mb3JtYXQodGV4dCk7XG4gKiAvLyBcdTIxQTYgMVxuICogYGBgXG4gKlxuICogIyMgQ2FsbGJhY2tzXG4gKlxuICogVGhlIHZhbHVlcyBpbiBhIGZvcm1hdHRlciBjYW4gYmUgYWRqdXN0ZWQgdmlhIHRoZSBjb21tYW5kcyBvZiB0aGUgYFRyYW5zZm9ybWVyYCBvciB0aGVgUGlwZWAuXG4gKiBUaGVyZSBpcyBhbHNvIHRoZSBwb3NzaWJpbGl0eSB0byB1c2UgY2FsbGJhY2tzLlxuICpcbiAqIGNvbnN0IGZvcm1hdHRlciA9IG5ldyBGb3JtYXR0ZXIoe3g6ICcxJ30sIHtcbiAqICAgICAgICAgICAgICAgIGNhbGxiYWNrczoge1xuICogICAgICAgICAgICAgICAgICAgIHF1b3RlOiAodmFsdWUpID0+IHtcbiAqICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICdcIicgKyB2YWx1ZSArICdcIidcbiAqICAgICAgICAgICAgICAgICAgICB9XG4gKiAgICAgICAgICAgICAgICB9XG4gKiAgICAgICAgICAgIH0pO1xuICpcbiAqIGZvcm1hdHRlci5mb3JtYXQoJyR7eCB8IGNhbGw6cXVvdGV9JykpXG4gKiAvLyBcdTIxQTYgXCIxXCJcbiAqXG4gKiAjIyBNYXJrZXIgd2l0aCBwYXJhbWV0ZXJcbiAqXG4gKiBBIHN0cmluZyBjYW4gYWxzbyBicmluZyBpdHMgb3duIHZhbHVlcy4gVGhlc2UgbXVzdCB0aGVuIGJlIHNlcGFyYXRlZCBmcm9tIHRoZSBrZXkgYnkgYSBzZXBhcmF0b3IgYDo6YC5cbiAqIFRoZSB2YWx1ZXMgdGhlbXNlbHZlcyBtdXN0IGJlIHNwZWNpZmllZCBpbiBrZXkvdmFsdWUgcGFpcnMuIFRoZSBrZXkgbXVzdCBiZSBzZXBhcmF0ZWQgZnJvbSB0aGUgdmFsdWUgYnkgYSBzZXBhcmF0b3IgYD1gLlxuICpcbiAqIFdoZW4gdXNpbmcgYSBwaXBlLCB5b3UgbXVzdCBwYXkgYXR0ZW50aW9uIHRvIHRoZSBzZXBhcmF0b3JzLlxuICpcbiAqIEBleGFtcGxlXG4gKlxuICogaW1wb3J0IHtGb3JtYXR0ZXJ9IGZyb20gJ0BzY2h1a2FpL21vbnN0ZXIvc291cmNlL3RleHQvZm9ybWF0dGVyLm1qcyc7XG4gKlxuICogbmV3IEZvcm1hdHRlcih7XG4gKiAgICAgICBhOiB7XG4gKiAgICAgICAgICAgYjoge1xuICogICAgICAgICAgICAgICBjOiBcIkhlbGxvXCJcbiAqICAgICAgICAgICB9LFxuICogICAgICAgICAgIGQ6IFwid29ybGRcIixcbiAqICAgICAgIH1cbiAqICAgfSkuZm9ybWF0KFwiJHthLmIuY30gJHthLmQgfCB1Y2ZpcnN0fSFcIik7IC8vIHdpdGggcGlwZVxuICpcbiAqIC8vIFx1MjFBNiBIZWxsbyBXb3JsZCFcbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjEyLjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UZXh0XG4gKi9cbmNsYXNzIEZvcm1hdHRlciBleHRlbmRzIEJhc2VXaXRoT3B0aW9ucyB7XG4gICAgLyoqXG4gICAgICogRGVmYXVsdCB2YWx1ZXMgZm9yIHRoZSBtYXJrZXJzIGFyZSBgJHtgIGFuZCBgfWBcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBvYmplY3RcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIG9iamVjdFxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKG9iamVjdCwgb3B0aW9ucykge1xuICAgICAgICBzdXBlcihvcHRpb25zKTtcbiAgICAgICAgdGhpc1tpbnRlcm5hbE9iamVjdFN5bWJvbF0gPSBvYmplY3QgfHwge307XG4gICAgICAgIHRoaXNbbWFya2VyT3BlbkluZGV4U3ltYm9sXSA9IDA7XG4gICAgICAgIHRoaXNbbWFya2VyQ2xvc2VJbmRleFN5bWJvbF0gPSAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwcm9wZXJ0eSB7b2JqZWN0fSBtYXJrZXJcbiAgICAgKiBAcHJvcGVydHkge2FycmF5fSBtYXJrZXIub3Blbj1bXCIke1wiXVxuICAgICAqIEBwcm9wZXJ0eSB7YXJyYXl9IG1hcmtlci5jbG9zZT1bXCIke1wiXVxuICAgICAqIEBwcm9wZXJ0eSB7b2JqZWN0fSBwYXJhbWV0ZXJcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gcGFyYW1ldGVyLmRlbGltaXRlcj1cIjo6XCJcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gcGFyYW1ldGVyLmFzc2lnbm1lbnQ9XCI9XCJcbiAgICAgKiBAcHJvcGVydHkge29iamVjdH0gY2FsbGJhY2tzPXt9XG4gICAgICovXG4gICAgZ2V0IGRlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gZXh0ZW5kKHt9LCBzdXBlci5kZWZhdWx0cywge1xuICAgICAgICAgICAgbWFya2VyOiB7XG4gICAgICAgICAgICAgICAgb3BlbjogW1wiJHtcIl0sXG4gICAgICAgICAgICAgICAgY2xvc2U6IFtcIn1cIl0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcGFyYW1ldGVyOiB7XG4gICAgICAgICAgICAgICAgZGVsaW1pdGVyOiBcIjo6XCIsXG4gICAgICAgICAgICAgICAgYXNzaWdubWVudDogXCI9XCIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY2FsbGJhY2tzOiB7fSxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IG5ldyBQYXJhbWV0ZXIgQ2hhcmFjdGVyXG4gICAgICpcbiAgICAgKiBEZWZhdWx0IHZhbHVlcyBmb3IgdGhlIGNoYXJzIGFyZSBgOjpgIGFuZCBgPWBcbiAgICAgKlxuICAgICAqIGBgYFxuICAgICAqIGZvcm1hdHRlci5zZXRQYXJhbWV0ZXJDaGFycygnIycpO1xuICAgICAqIGZvcm1hdHRlci5zZXRQYXJhbWV0ZXJDaGFycygnWycsJ10nKTtcbiAgICAgKiBmb3JtYXR0ZXIuc2V0UGFyYW1ldGVyQ2hhcnMoJ2kxOG57JywnfScpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGRlbGltaXRlclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBhc3NpZ25tZW50XG4gICAgICogQHJldHVybiB7Rm9ybWF0dGVyfVxuICAgICAqIEBzaW5jZSAxLjI0LjBcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIHN0cmluZ1xuICAgICAqL1xuICAgIHNldFBhcmFtZXRlckNoYXJzKGRlbGltaXRlciwgYXNzaWdubWVudCkge1xuICAgICAgICBpZiAoZGVsaW1pdGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXNbaW50ZXJuYWxTeW1ib2xdW1wicGFyYW1ldGVyXCJdW1wiZGVsaW1pdGVyXCJdID0gdmFsaWRhdGVTdHJpbmcoZGVsaW1pdGVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChhc3NpZ25tZW50ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXNbaW50ZXJuYWxTeW1ib2xdW1wicGFyYW1ldGVyXCJdW1wiYXNzaWdubWVudFwiXSA9IHZhbGlkYXRlU3RyaW5nKGFzc2lnbm1lbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IG5ldyBNYXJrZXJcbiAgICAgKlxuICAgICAqIERlZmF1bHQgdmFsdWVzIGZvciB0aGUgbWFya2VycyBhcmUgYCR7YCBhbmQgYH1gXG4gICAgICpcbiAgICAgKiBgYGBcbiAgICAgKiBmb3JtYXR0ZXIuc2V0TWFya2VyKCcjJyk7IC8vIG9wZW4gYW5kIGNsb3NlIGFyZSBib3RoICNcbiAgICAgKiBmb3JtYXR0ZXIuc2V0TWFya2VyKCdbJywnXScpO1xuICAgICAqIGZvcm1hdHRlci5zZXRNYXJrZXIoJ2kxOG57JywnfScpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQHBhcmFtIHthcnJheXxzdHJpbmd9IG9wZW5cbiAgICAgKiBAcGFyYW0ge2FycmF5fHN0cmluZ3x1bmRlZmluZWR9IGNsb3NlXG4gICAgICogQHJldHVybiB7Rm9ybWF0dGVyfVxuICAgICAqIEBzaW5jZSAxLjEyLjBcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIHN0cmluZ1xuICAgICAqL1xuICAgIHNldE1hcmtlcihvcGVuLCBjbG9zZSkge1xuICAgICAgICBpZiAoY2xvc2UgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgY2xvc2UgPSBvcGVuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzU3RyaW5nKG9wZW4pKSBvcGVuID0gW29wZW5dO1xuICAgICAgICBpZiAoaXNTdHJpbmcoY2xvc2UpKSBjbG9zZSA9IFtjbG9zZV07XG5cbiAgICAgICAgdGhpc1tpbnRlcm5hbFN5bWJvbF1bXCJtYXJrZXJcIl1bXCJvcGVuXCJdID0gdmFsaWRhdGVBcnJheShvcGVuKTtcbiAgICAgICAgdGhpc1tpbnRlcm5hbFN5bWJvbF1bXCJtYXJrZXJcIl1bXCJjbG9zZVwiXSA9IHZhbGlkYXRlQXJyYXkoY2xvc2UpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0XG4gICAgICogQHJldHVybiB7c3RyaW5nfVxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgc3RyaW5nXG4gICAgICogQHRocm93cyB7RXJyb3J9IHRvbyBkZWVwIG5lc3RpbmdcbiAgICAgKi9cbiAgICBmb3JtYXQodGV4dCkge1xuICAgICAgICB0aGlzW3dhdGNoZG9nU3ltYm9sXSA9IDA7XG4gICAgICAgIHRoaXNbbWFya2VyT3BlbkluZGV4U3ltYm9sXSA9IDA7XG4gICAgICAgIHRoaXNbbWFya2VyQ2xvc2VJbmRleFN5bWJvbF0gPSAwO1xuICAgICAgICB0aGlzW3dvcmtpbmdEYXRhU3ltYm9sXSA9IHt9O1xuICAgICAgICByZXR1cm4gZm9ybWF0LmNhbGwodGhpcywgdGV4dCk7XG4gICAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcmV0dXJuIHtzdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIGZvcm1hdCh0ZXh0KSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICBzZWxmW3dhdGNoZG9nU3ltYm9sXSsrO1xuICAgIGlmICh0aGlzW3dhdGNoZG9nU3ltYm9sXSA+IDIwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcInRvbyBkZWVwIG5lc3RpbmdcIik7XG4gICAgfVxuXG4gICAgbGV0IG9wZW5NYXJrZXIgPSBzZWxmW2ludGVybmFsU3ltYm9sXVtcIm1hcmtlclwiXVtcIm9wZW5cIl0/Llt0aGlzW21hcmtlck9wZW5JbmRleFN5bWJvbF1dO1xuICAgIGxldCBjbG9zZU1hcmtlciA9IHNlbGZbaW50ZXJuYWxTeW1ib2xdW1wibWFya2VyXCJdW1wiY2xvc2VcIl0/Llt0aGlzW21hcmtlckNsb3NlSW5kZXhTeW1ib2xdXTtcblxuICAgIC8vIGNvbnRhaW5zIG5vIHBsYWNlaG9sZGVyc1xuICAgIGlmICh0ZXh0LmluZGV4T2Yob3Blbk1hcmtlcikgPT09IC0xIHx8IHRleHQuaW5kZXhPZihjbG9zZU1hcmtlcikgPT09IC0xKSB7XG4gICAgICAgIHJldHVybiB0ZXh0O1xuICAgIH1cblxuICAgIGxldCByZXN1bHQgPSB0b2tlbml6ZS5jYWxsKHRoaXMsIHZhbGlkYXRlU3RyaW5nKHRleHQpLCBvcGVuTWFya2VyLCBjbG9zZU1hcmtlcik7XG5cbiAgICBpZiAoc2VsZltpbnRlcm5hbFN5bWJvbF1bXCJtYXJrZXJcIl1bXCJvcGVuXCJdPy5bdGhpc1ttYXJrZXJPcGVuSW5kZXhTeW1ib2xdICsgMV0pIHtcbiAgICAgICAgdGhpc1ttYXJrZXJPcGVuSW5kZXhTeW1ib2xdKys7XG4gICAgfVxuXG4gICAgaWYgKHNlbGZbaW50ZXJuYWxTeW1ib2xdW1wibWFya2VyXCJdW1wiY2xvc2VcIl0/Llt0aGlzW21hcmtlckNsb3NlSW5kZXhTeW1ib2xdICsgMV0pIHtcbiAgICAgICAgdGhpc1ttYXJrZXJDbG9zZUluZGV4U3ltYm9sXSsrO1xuICAgIH1cblxuICAgIHJlc3VsdCA9IGZvcm1hdC5jYWxsKHNlbGYsIHJlc3VsdCk7XG5cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjEyLjBcbiAqIEBwYXJhbSB0ZXh0XG4gKiBAcmV0dXJuIHtzdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIHRva2VuaXplKHRleHQsIG9wZW5NYXJrZXIsIGNsb3NlTWFya2VyKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICBsZXQgZm9ybWF0dGVkID0gW107XG5cbiAgICBjb25zdCBwYXJhbWV0ZXJBc3NpZ25tZW50ID0gc2VsZltpbnRlcm5hbFN5bWJvbF1bXCJwYXJhbWV0ZXJcIl1bXCJhc3NpZ25tZW50XCJdO1xuICAgIGNvbnN0IHBhcmFtZXRlckRlbGltaXRlciA9IHNlbGZbaW50ZXJuYWxTeW1ib2xdW1wicGFyYW1ldGVyXCJdW1wiZGVsaW1pdGVyXCJdO1xuICAgIGNvbnN0IGNhbGxiYWNrcyA9IHNlbGZbaW50ZXJuYWxTeW1ib2xdW1wiY2FsbGJhY2tzXCJdO1xuXG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgbGV0IHN0YXJ0SW5kZXggPSB0ZXh0LmluZGV4T2Yob3Blbk1hcmtlcik7XG4gICAgICAgIC8vIG5vIG1hcmtlclxuICAgICAgICBpZiAoc3RhcnRJbmRleCA9PT0gLTEpIHtcbiAgICAgICAgICAgIGZvcm1hdHRlZC5wdXNoKHRleHQpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH0gZWxzZSBpZiAoc3RhcnRJbmRleCA+IDApIHtcbiAgICAgICAgICAgIGZvcm1hdHRlZC5wdXNoKHRleHQuc3Vic3RyaW5nKDAsIHN0YXJ0SW5kZXgpKTtcbiAgICAgICAgICAgIHRleHQgPSB0ZXh0LnN1YnN0cmluZyhzdGFydEluZGV4KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBlbmRJbmRleCA9IHRleHQuc3Vic3RyaW5nKG9wZW5NYXJrZXIubGVuZ3RoKS5pbmRleE9mKGNsb3NlTWFya2VyKTtcbiAgICAgICAgaWYgKGVuZEluZGV4ICE9PSAtMSkgZW5kSW5kZXggKz0gb3Blbk1hcmtlci5sZW5ndGg7XG4gICAgICAgIGxldCBpbnNpZGVTdGFydEluZGV4ID0gdGV4dC5zdWJzdHJpbmcob3Blbk1hcmtlci5sZW5ndGgpLmluZGV4T2Yob3Blbk1hcmtlcik7XG4gICAgICAgIGlmIChpbnNpZGVTdGFydEluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgaW5zaWRlU3RhcnRJbmRleCArPSBvcGVuTWFya2VyLmxlbmd0aDtcbiAgICAgICAgICAgIGlmIChpbnNpZGVTdGFydEluZGV4IDwgZW5kSW5kZXgpIHtcbiAgICAgICAgICAgICAgICBsZXQgcmVzdWx0ID0gdG9rZW5pemUuY2FsbChzZWxmLCB0ZXh0LnN1YnN0cmluZyhpbnNpZGVTdGFydEluZGV4KSwgb3Blbk1hcmtlciwgY2xvc2VNYXJrZXIpO1xuICAgICAgICAgICAgICAgIHRleHQgPSB0ZXh0LnN1YnN0cmluZygwLCBpbnNpZGVTdGFydEluZGV4KSArIHJlc3VsdDtcbiAgICAgICAgICAgICAgICBlbmRJbmRleCA9IHRleHQuc3Vic3RyaW5nKG9wZW5NYXJrZXIubGVuZ3RoKS5pbmRleE9mKGNsb3NlTWFya2VyKTtcbiAgICAgICAgICAgICAgICBpZiAoZW5kSW5kZXggIT09IC0xKSBlbmRJbmRleCArPSBvcGVuTWFya2VyLmxlbmd0aDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlbmRJbmRleCA9PT0gLTEpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInN5bnRheCBlcnJvciBpbiBmb3JtYXR0ZXIgdGVtcGxhdGVcIik7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQga2V5ID0gdGV4dC5zdWJzdHJpbmcob3Blbk1hcmtlci5sZW5ndGgsIGVuZEluZGV4KTtcbiAgICAgICAgbGV0IHBhcnRzID0ga2V5LnNwbGl0KHBhcmFtZXRlckRlbGltaXRlcik7XG4gICAgICAgIGxldCBjdXJyZW50UGlwZSA9IHBhcnRzLnNoaWZ0KCk7XG5cbiAgICAgICAgc2VsZlt3b3JraW5nRGF0YVN5bWJvbF0gPSBleHRlbmQoe30sIHNlbGZbaW50ZXJuYWxPYmplY3RTeW1ib2xdLCBzZWxmW3dvcmtpbmdEYXRhU3ltYm9sXSk7XG5cbiAgICAgICAgZm9yIChjb25zdCBrdiBvZiBwYXJ0cykge1xuICAgICAgICAgICAgY29uc3QgW2ssIHZdID0ga3Yuc3BsaXQocGFyYW1ldGVyQXNzaWdubWVudCk7XG4gICAgICAgICAgICBzZWxmW3dvcmtpbmdEYXRhU3ltYm9sXVtrXSA9IHY7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB0MSA9IGtleS5zcGxpdChcInxcIikuc2hpZnQoKS50cmltKCk7IC8vIHBpcGUgc3ltYm9sXG4gICAgICAgIGNvbnN0IHQyID0gdDEuc3BsaXQoXCI6OlwiKS5zaGlmdCgpLnRyaW0oKTsgLy8ga2V5IHZhbHVlIGRlbGltaXRlclxuICAgICAgICBjb25zdCB0MyA9IHQyLnNwbGl0KFwiLlwiKS5zaGlmdCgpLnRyaW0oKTsgLy8gcGF0aCBkZWxpbWl0ZXJcbiAgICAgICAgbGV0IHByZWZpeCA9IHNlbGZbd29ya2luZ0RhdGFTeW1ib2xdPy5bdDNdID8gXCJwYXRoOlwiIDogXCJzdGF0aWM6XCI7XG5cbiAgICAgICAgbGV0IGNvbW1hbmQgPSBcIlwiO1xuICAgICAgICBpZiAocHJlZml4ICYmIGtleS5pbmRleE9mKHByZWZpeCkgIT09IDAgJiYga2V5LmluZGV4T2YoXCJwYXRoOlwiKSAhPT0gMCAmJiBrZXkuaW5kZXhPZihcInN0YXRpYzpcIikgIT09IDApIHtcbiAgICAgICAgICAgIGNvbW1hbmQgPSBwcmVmaXg7XG4gICAgICAgIH1cblxuICAgICAgICBjb21tYW5kICs9IGN1cnJlbnRQaXBlO1xuXG4gICAgICAgIGNvbnN0IHBpcGUgPSBuZXcgUGlwZShjb21tYW5kKTtcblxuICAgICAgICBpZiAoaXNPYmplY3QoY2FsbGJhY2tzKSkge1xuICAgICAgICAgICAgZm9yIChjb25zdCBbbmFtZSwgY2FsbGJhY2tdIG9mIE9iamVjdC5lbnRyaWVzKGNhbGxiYWNrcykpIHtcbiAgICAgICAgICAgICAgICBwaXBlLnNldENhbGxiYWNrKG5hbWUsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGZvcm1hdHRlZC5wdXNoKHZhbGlkYXRlU3RyaW5nKHBpcGUucnVuKHNlbGZbd29ya2luZ0RhdGFTeW1ib2xdKSkpO1xuXG4gICAgICAgIHRleHQgPSB0ZXh0LnN1YnN0cmluZyhlbmRJbmRleCArIGNsb3NlTWFya2VyLmxlbmd0aCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZvcm1hdHRlZC5qb2luKFwiXCIpO1xufVxuIiwgImltcG9ydCB7IGlzU3RyaW5nIH0gZnJvbSBcIi4uL3R5cGVzL2lzLm1qc1wiO1xuaW1wb3J0IHsgdmFsaWRhdGVTdHJpbmcgfSBmcm9tIFwiLi4vdHlwZXMvdmFsaWRhdGUubWpzXCI7XG5cbmV4cG9ydCB7IGdldFNsb3R0ZWRFbGVtZW50cywgZ2V0U2xvdHRlZE5vZGVzIH07XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7U3RyaW5nfHVuZGVmaW5lZH0gcXVlcnlcbiAqIEBwYXJhbSB7U3RyaW5nfHVuZGVmaW5lZHxudWxsfSBuYW1lIG5hbWUgb2YgdGhlIHNsb3QgKGlmIHRoZSBwYXJhbWV0ZXIgaXMgdW5kZWZpbmVkLCBhbGwgc2xvdHMgYXJlIHNlYXJjaGVkLCBpZiB0aGUgcGFyYW1ldGVyIGhhcyB0aGUgdmFsdWUgbnVsbCwgYWxsIHNsb3RzIHdpdGhvdXQgYSBuYW1lIGFyZSBzZWFyY2hlZC4gaWYgYSBzdHJpbmcgaXMgc3BlY2lmaWVkLCB0aGUgc2xvdHMgd2l0aCB0aGlzIG5hbWUgYXJlIHNlYXJjaGVkLilcbiAqIEByZXR1cm4geyp9XG4gKiBAdGhpcyBDdXN0b21FbGVtZW50XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAzLjMzLjBcbiAqIEB0aHJvd3Mge0Vycm9yfSBxdWVyeSBtdXN0IGJlIGEgc3RyaW5nXG4gKi9cbmZ1bmN0aW9uIGdldFNsb3R0ZWROb2RlcyhxdWVyeSwgbmFtZSkge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIGNvbnN0IHJlc3VsdCA9IG5ldyBTZXQoKTtcblxuICAgIGlmICghc2VsZi5zaGFkb3dSb290KSB7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgbGV0IHNlbGVjdG9yID0gXCJzbG90XCI7XG4gICAgaWYgKG5hbWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAobmFtZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgc2VsZWN0b3IgKz0gXCI6bm90KFtuYW1lXSlcIjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNlbGVjdG9yICs9IGBbbmFtZT0ke3ZhbGlkYXRlU3RyaW5nKG5hbWUpfV1gO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY29uc3Qgc2xvdHMgPSBzZWxmLnNoYWRvd1Jvb3QucXVlcnlTZWxlY3RvckFsbChzZWxlY3Rvcik7XG5cbiAgICBmb3IgKGNvbnN0IFssIHNsb3RdIG9mIE9iamVjdC5lbnRyaWVzKHNsb3RzKSkge1xuICAgICAgICBzbG90LmFzc2lnbmVkTm9kZXMoKS5mb3JFYWNoKGZ1bmN0aW9uIChub2RlKSB7XG4gICAgICAgICAgICBpZiAobm9kZSA9PT0gbnVsbCB8fCBub2RlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChpc1N0cmluZyhxdWVyeSkpIHtcbiAgICAgICAgICAgICAgICBub2RlLnF1ZXJ5U2VsZWN0b3JBbGwocXVlcnkpLmZvckVhY2goZnVuY3Rpb24gKG4pIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmFkZChuKTtcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIGlmIChub2RlLm1hdGNoZXMocXVlcnkpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hZGQobm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChxdWVyeSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwicXVlcnkgbXVzdCBiZSBhIHN0cmluZ1wiKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0LmFkZChub2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtTdHJpbmd8dW5kZWZpbmVkfSBxdWVyeVxuICogQHBhcmFtIHtTdHJpbmd8dW5kZWZpbmVkfG51bGx9IG5hbWUgbmFtZSBvZiB0aGUgc2xvdCAoaWYgdGhlIHBhcmFtZXRlciBpcyB1bmRlZmluZWQsIGFsbCBzbG90cyBhcmUgc2VhcmNoZWQsIGlmIHRoZSBwYXJhbWV0ZXIgaGFzIHRoZSB2YWx1ZSBudWxsLCBhbGwgc2xvdHMgd2l0aG91dCBhIG5hbWUgYXJlIHNlYXJjaGVkLiBpZiBhIHN0cmluZyBpcyBzcGVjaWZpZWQsIHRoZSBzbG90cyB3aXRoIHRoaXMgbmFtZSBhcmUgc2VhcmNoZWQuKVxuICogQHJldHVybiB7Kn1cbiAqIEB0aGlzIEN1c3RvbUVsZW1lbnRcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjMuMFxuICogQHRocm93cyB7RXJyb3J9IHF1ZXJ5IG11c3QgYmUgYSBzdHJpbmdcbiAqL1xuZnVuY3Rpb24gZ2V0U2xvdHRlZEVsZW1lbnRzKHF1ZXJ5LCBuYW1lKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgY29uc3QgcmVzdWx0ID0gbmV3IFNldCgpO1xuXG4gICAgaWYgKCEoc2VsZi5zaGFkb3dSb290IGluc3RhbmNlb2YgU2hhZG93Um9vdCkpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICBsZXQgc2VsZWN0b3IgPSBcInNsb3RcIjtcbiAgICBpZiAobmFtZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmIChuYW1lID09PSBudWxsKSB7XG4gICAgICAgICAgICBzZWxlY3RvciArPSBcIjpub3QoW25hbWVdKVwiO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2VsZWN0b3IgKz0gYFtuYW1lPSR7dmFsaWRhdGVTdHJpbmcobmFtZSl9XWA7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBzbG90cyA9IHNlbGYuc2hhZG93Um9vdC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKTtcblxuICAgIGZvciAoY29uc3QgWywgc2xvdF0gb2YgT2JqZWN0LmVudHJpZXMoc2xvdHMpKSB7XG4gICAgICAgIHNsb3QuYXNzaWduZWRFbGVtZW50cygpLmZvckVhY2goZnVuY3Rpb24gKG5vZGUpIHtcbiAgICAgICAgICAgIGlmICghKG5vZGUgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpIHJldHVybjtcblxuICAgICAgICAgICAgaWYgKGlzU3RyaW5nKHF1ZXJ5KSkge1xuICAgICAgICAgICAgICAgIG5vZGUucXVlcnlTZWxlY3RvckFsbChxdWVyeSkuZm9yRWFjaChmdW5jdGlvbiAobikge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQuYWRkKG4pO1xuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgaWYgKG5vZGUubWF0Y2hlcyhxdWVyeSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmFkZChub2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHF1ZXJ5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJxdWVyeSBtdXN0IGJlIGEgc3RyaW5nXCIpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXN1bHQuYWRkKG5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgQmFzZSB9IGZyb20gXCIuL2Jhc2UubWpzXCI7XG5pbXBvcnQgeyBpbnN0YW5jZVN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5cbmV4cG9ydCB7IFF1ZXVlIH07XG5cbi8qKlxuICogQSBxdWV1ZSBpcyBhIGxpc3Qgb2YgaXRlbXMgdGhhdCBhcmUgcHJvY2Vzc2VkIG9uZSBhZnRlciBhbm90aGVyIChmaXJzdCBpbiwgZmlyc3Qgb3V0KS5cbiAqXG4gKiBXaXRoIGEgcXVldWUgeW91IGNhbiBhZGQgaXRlbXMgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdCBgUXVldWUuYWRkKClgIGFuZCByZW1vdmUgaXRlbXMgZnJvbSB0aGUgYmVnaW5uaW5nIG9mIHRoZSBsaXN0IGBRdWV1ZS5wb3AoKWAuXG4gKlxuICogV2l0aCBgUXVldWUucGVlaygpYCB5b3UgY2FuIGdldCB0aGUgZmlyc3QgaXRlbSB3aXRob3V0IHJlbW92aW5nIGl0IGZyb20gdGhlIGxpc3QuXG4gKlxuICogWW91IGNhbiBjcmVhdGUgdGhlIGluc3RhbmNlIHZpYSBgbmV3IFF1ZXVlKClgLlxuICpcbiAqIEBleHRlcm5hbEV4YW1wbGUgLi4vLi4vZXhhbXBsZS90eXBlcy9xdWV1ZS5tanNcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuNC4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcbiAqIEBzdW1tYXJ5IEEgUXVldWUgKEZpZm8pXG4gKi9cbmNsYXNzIFF1ZXVlIGV4dGVuZHMgQmFzZSB7XG4gICAgLyoqXG4gICAgICpcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5kYXRhID0gW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMi4xLjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci90eXBlcy9xdWV1ZVwiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgICAqL1xuICAgIGlzRW1wdHkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmRhdGEubGVuZ3RoID09PSAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlYWQgdGhlIGVsZW1lbnQgYXQgdGhlIGZyb250IG9mIHRoZSBxdWV1ZSB3aXRob3V0IHJlbW92aW5nIGl0LlxuICAgICAqXG4gICAgICogQHJldHVybiB7Kn1cbiAgICAgKi9cbiAgICBwZWVrKCkge1xuICAgICAgICBpZiAodGhpcy5pc0VtcHR5KCkpIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcy5kYXRhWzBdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZCBhIG5ldyBlbGVtZW50IHRvIHRoZSBlbmQgb2YgdGhlIHF1ZXVlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZVxuICAgICAqIEByZXR1cm5zIHtRdWV1ZX1cbiAgICAgKi9cbiAgICBhZGQodmFsdWUpIHtcbiAgICAgICAgdGhpcy5kYXRhLnB1c2godmFsdWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiByZW1vdmUgYWxsIGVudHJpZXNcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtRdWV1ZX1cbiAgICAgKi9cbiAgICBjbGVhcigpIHtcbiAgICAgICAgdGhpcy5kYXRhID0gW107XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZSB0aGUgZWxlbWVudCBhdCB0aGUgZnJvbnQgb2YgdGhlIHF1ZXVlXG4gICAgICogSWYgdGhlIHF1ZXVlIGlzIGVtcHR5LCByZXR1cm4gdW5kZWZpbmVkLlxuICAgICAqXG4gICAgICogQHJldHVybiB7Kn1cbiAgICAgKi9cbiAgICBwb2xsKCkge1xuICAgICAgICBpZiAodGhpcy5pc0VtcHR5KCkpIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuZGF0YS5zaGlmdCgpO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IFF1ZXVlIH0gZnJvbSBcIi4vcXVldWUubWpzXCI7XG5pbXBvcnQgeyBpbnRlcm5hbFN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQgeyB2YWxpZGF0ZU9iamVjdCB9IGZyb20gXCIuL3ZhbGlkYXRlLm1qc1wiO1xuXG5leHBvcnQgeyBVbmlxdWVRdWV1ZSB9O1xuXG4vKipcbiAqIEFuIFVuaXF1ZVF1ZXVlIGlzIGEgcXVldWUgdGhhdCBjb250YWlucyBpdGVtcyBvbmx5IG9uY2UuXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS40LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UeXBlc1xuICogQHN1bW1hcnkgQSBxdWV1ZSBmb3IgdW5pcXVlIHZhbHVlc1xuICovXG5jbGFzcyBVbmlxdWVRdWV1ZSBleHRlbmRzIFF1ZXVlIHtcbiAgICAvKipcbiAgICAgKlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzW2ludGVybmFsU3ltYm9sXSA9IHtcbiAgICAgICAgICAgIHVuaXF1ZTogbmV3IFdlYWtTZXQoKSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSBuZXcgZWxlbWVudCB0byB0aGUgZW5kIG9mIHRoZSBxdWV1ZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSB2YWx1ZVxuICAgICAqIEByZXR1cm5zIHtRdWV1ZX1cbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIG9iamVjdFxuICAgICAqL1xuICAgIGFkZCh2YWx1ZSkge1xuICAgICAgICB2YWxpZGF0ZU9iamVjdCh2YWx1ZSk7XG5cbiAgICAgICAgaWYgKCF0aGlzW2ludGVybmFsU3ltYm9sXS51bmlxdWUuaGFzKHZhbHVlKSkge1xuICAgICAgICAgICAgdGhpc1tpbnRlcm5hbFN5bWJvbF0udW5pcXVlLmFkZCh2YWx1ZSk7XG4gICAgICAgICAgICBzdXBlci5hZGQodmFsdWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogcmVtb3ZlIGFsbCBlbnRyaWVzXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7UXVldWV9XG4gICAgICovXG4gICAgY2xlYXIoKSB7XG4gICAgICAgIHN1cGVyLmNsZWFyKCk7XG4gICAgICAgIHRoaXNbaW50ZXJuYWxTeW1ib2xdLnVuaXF1ZSA9IG5ldyBXZWFrU2V0KCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZSB0aGUgZWxlbWVudCBhdCB0aGUgZnJvbnQgb2YgdGhlIHF1ZXVlXG4gICAgICogSWYgdGhlIHF1ZXVlIGlzIGVtcHR5LCByZXR1cm4gdW5kZWZpbmVkLlxuICAgICAqXG4gICAgICogQHJldHVybiB7b2JqZWN0fVxuICAgICAqL1xuICAgIHBvbGwoKSB7XG4gICAgICAgIGlmICh0aGlzLmlzRW1wdHkoKSkge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICBsZXQgdmFsdWUgPSB0aGlzLmRhdGEuc2hpZnQoKTtcbiAgICAgICAgdGhpc1tpbnRlcm5hbFN5bWJvbF0udW5pcXVlLmRlbGV0ZSh2YWx1ZSk7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBCYXNlIH0gZnJvbSBcIi4vYmFzZS5tanNcIjtcbmltcG9ydCB7IGlzT2JqZWN0IH0gZnJvbSBcIi4vaXMubWpzXCI7XG5pbXBvcnQgeyBUb2tlbkxpc3QgfSBmcm9tIFwiLi90b2tlbmxpc3QubWpzXCI7XG5pbXBvcnQgeyBVbmlxdWVRdWV1ZSB9IGZyb20gXCIuL3VuaXF1ZXF1ZXVlLm1qc1wiO1xuaW1wb3J0IHsgaW5zdGFuY2VTeW1ib2wgfSBmcm9tIFwiLi4vY29uc3RhbnRzLm1qc1wiO1xuZXhwb3J0IHsgT2JzZXJ2ZXIgfTtcblxuLyoqXG4gKiBBbiBvYnNlcnZlciBtYW5hZ2VzIGEgY2FsbGJhY2sgZnVuY3Rpb25cbiAqXG4gKiBUaGUgdXBkYXRlIG1ldGhvZCBpcyBjYWxsZWQgd2l0aCB0aGUgc3ViamVjdCBvYmplY3QgYXMgdGhpcyBwb2ludGVyLiBGb3IgdGhpcyByZWFzb24gdGhlIGNhbGxiYWNrIHNob3VsZCBub3RcbiAqIGJlIGFuIGFycm93IGZ1bmN0aW9uLCBiZWNhdXNlIGl0IGdldHMgdGhpcyBwb2ludGVyIG9mIGl0cyBvd24gY29udGV4dC5cbiAqXG4gKiBgYGBqc1xuICogbmV3IE9ic2VydmVyKCgpPT57XG4gKiAgICAgLy8gdGhpcyBpcyBub3Qgc3ViamVjdFxuICogfSlcbiAqXG4gKiBuZXcgT2JzZXJ2ZXIoZnVuY3Rpb24oKSB7XG4gKiAgICAgLy8gdGhpcyBpcyBzdWJqZWN0XG4gKiB9KVxuICogYGBgXG4gKlxuICogQWRkaXRpb25hbCBhcmd1bWVudHMgY2FuIGJlIHBhc3NlZCB0byB0aGUgY2FsbGJhY2suIFRvIGRvIHRoaXMsIHNpbXBseSBzcGVjaWZ5IHRoZW0uXG4gKlxuICogYGBganNcbiAqIE9ic2VydmVyKGZ1bmN0aW9uKGEsIGIsIGMpIHtcbiAqICAgICBjb25zb2xlLmxvZyhhLCBiLCBjKTsgLy8gXHUyMUE2IFwiYVwiLCAyLCB0cnVlXG4gKiB9LCBcImFcIiwgMiwgdHJ1ZSlcbiAqIGBgYFxuICpcbiAqIFRoZSBjYWxsYmFjayBmdW5jdGlvbiBtdXN0IGhhdmUgYXMgbWFueSBwYXJhbWV0ZXJzIGFzIGFyZ3VtZW50cyBhcmUgZ2l2ZW4uXG4gKlxuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL3R5cGVzL29ic2VydmVyLm1qc1xuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4wLjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UeXBlc1xuICovXG5jbGFzcyBPYnNlcnZlciBleHRlbmRzIEJhc2Uge1xuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2tcbiAgICAgKiBAcGFyYW0geyp9IGFyZ3NcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihjYWxsYmFjaywgLi4uYXJncykge1xuICAgICAgICBzdXBlcigpO1xuXG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwib2JzZXJ2ZXIgY2FsbGJhY2sgbXVzdCBiZSBhIGZ1bmN0aW9uXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgICAgICB0aGlzLmFyZ3VtZW50cyA9IGFyZ3M7XG4gICAgICAgIHRoaXMudGFncyA9IG5ldyBUb2tlbkxpc3QoKTtcbiAgICAgICAgdGhpcy5xdWV1ZSA9IG5ldyBVbmlxdWVRdWV1ZSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgYGluc3RhbmNlb2ZgIG9wZXJhdG9yLlxuICAgICAqIEByZXR1cm5zIHtzeW1ib2x9XG4gICAgICogQHNpbmNlIDIuMS4wXG4gICAgICovXG4gICAgc3RhdGljIGdldCBbaW5zdGFuY2VTeW1ib2xdKCkge1xuICAgICAgICByZXR1cm4gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvdHlwZXMvb2JzZXJ2ZXJcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdGFnXG4gICAgICogQHJldHVybnMge09ic2VydmVyfVxuICAgICAqL1xuICAgIGFkZFRhZyh0YWcpIHtcbiAgICAgICAgdGhpcy50YWdzLmFkZCh0YWcpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0YWdcbiAgICAgKiBAcmV0dXJucyB7T2JzZXJ2ZXJ9XG4gICAgICovXG4gICAgcmVtb3ZlVGFnKHRhZykge1xuICAgICAgICB0aGlzLnRhZ3MucmVtb3ZlKHRhZyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHJldHVybnMge0FycmF5fVxuICAgICAqL1xuICAgIGdldFRhZ3MoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRhZ3MuZW50cmllcygpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHRhZ1xuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgICAqL1xuICAgIGhhc1RhZyh0YWcpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudGFncy5jb250YWlucyh0YWcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtvYmplY3R9IHN1YmplY3RcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZX1cbiAgICAgKi9cbiAgICB1cGRhdGUoc3ViamVjdCkge1xuICAgICAgICBsZXQgc2VsZiA9IHRoaXM7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgICAgIGlmICghaXNPYmplY3Qoc3ViamVjdCkpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoXCJzdWJqZWN0IG11c3QgYmUgYW4gb2JqZWN0XCIpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgc2VsZi5xdWV1ZS5hZGQoc3ViamVjdCk7XG5cbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHRoZSBxdWV1ZSBhbmQgdGhlIHNldHRpbWVvdXQgZW5zdXJlIHRoYXQgYW4gb2JqZWN0IGlzIG5vdFxuICAgICAgICAgICAgICAgICAgICAvLyBpbmZvcm1lZCBvZiB0aGUgc2FtZSBjaGFuZ2UgbW9yZSB0aGFuIG9uY2UuXG4gICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLnF1ZXVlLmlzRW1wdHkoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgbGV0IHMgPSBzZWxmLnF1ZXVlLnBvbGwoKTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHJlc3VsdCA9IHNlbGYuY2FsbGJhY2suYXBwbHkocywgc2VsZi5hcmd1bWVudHMpO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChpc09iamVjdChyZXN1bHQpICYmIHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC50aGVuKHJlc29sdmUpLmNhdGNoKHJlamVjdCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSwgMCk7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IEJhc2UgfSBmcm9tIFwiLi9iYXNlLm1qc1wiO1xuaW1wb3J0IHsgT2JzZXJ2ZXIgfSBmcm9tIFwiLi9vYnNlcnZlci5tanNcIjtcbmltcG9ydCB7IHZhbGlkYXRlSW5zdGFuY2UgfSBmcm9tIFwiLi92YWxpZGF0ZS5tanNcIjtcblxuZXhwb3J0IHsgT2JzZXJ2ZXJMaXN0IH07XG5cbi8qKlxuICogV2l0aCB0aGUgaGVscCBvZiB0aGUgT2JzZXJ2ZXJMaXN0IGNsYXNzLCBvYnNlcnZlciBjYW4gYmUgbWFuYWdlZC5cbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjAuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKi9cbmNsYXNzIE9ic2VydmVyTGlzdCBleHRlbmRzIEJhc2Uge1xuICAgIC8qKlxuICAgICAqXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMub2JzZXJ2ZXJzID0gW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge09ic2VydmVyfSBvYnNlcnZlclxuICAgICAqIEByZXR1cm4ge09ic2VydmVyTGlzdH1cbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhbiBpbnN0YW5jZSBvZiBPYnNlcnZlclxuICAgICAqL1xuICAgIGF0dGFjaChvYnNlcnZlcikge1xuICAgICAgICB2YWxpZGF0ZUluc3RhbmNlKG9ic2VydmVyLCBPYnNlcnZlcik7XG5cbiAgICAgICAgdGhpcy5vYnNlcnZlcnMucHVzaChvYnNlcnZlcik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYnNlcnZlcn0gb2JzZXJ2ZXJcbiAgICAgKiBAcmV0dXJuIHtPYnNlcnZlckxpc3R9XG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgT2JzZXJ2ZXJcbiAgICAgKi9cbiAgICBkZXRhY2gob2JzZXJ2ZXIpIHtcbiAgICAgICAgdmFsaWRhdGVJbnN0YW5jZShvYnNlcnZlciwgT2JzZXJ2ZXIpO1xuXG4gICAgICAgIHZhciBpID0gMDtcbiAgICAgICAgdmFyIGwgPSB0aGlzLm9ic2VydmVycy5sZW5ndGg7XG4gICAgICAgIGZvciAoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5vYnNlcnZlcnNbaV0gPT09IG9ic2VydmVyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vYnNlcnZlcnMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge09ic2VydmVyfSBvYnNlcnZlclxuICAgICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgT2JzZXJ2ZXJcbiAgICAgKi9cbiAgICBjb250YWlucyhvYnNlcnZlcikge1xuICAgICAgICB2YWxpZGF0ZUluc3RhbmNlKG9ic2VydmVyLCBPYnNlcnZlcik7XG4gICAgICAgIHZhciBpID0gMDtcbiAgICAgICAgdmFyIGwgPSB0aGlzLm9ic2VydmVycy5sZW5ndGg7XG4gICAgICAgIGZvciAoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5vYnNlcnZlcnNbaV0gPT09IG9ic2VydmVyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHN1YmplY3RcbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgICAqL1xuICAgIG5vdGlmeShzdWJqZWN0KSB7XG4gICAgICAgIGxldCBwb21pc2VzID0gW107XG5cbiAgICAgICAgbGV0IGkgPSAwO1xuICAgICAgICBsZXQgbCA9IHRoaXMub2JzZXJ2ZXJzLmxlbmd0aDtcbiAgICAgICAgZm9yICg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICAgIHBvbWlzZXMucHVzaCh0aGlzLm9ic2VydmVyc1tpXS51cGRhdGUoc3ViamVjdCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHBvbWlzZXMpO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IEJhc2UgfSBmcm9tIFwiLi9iYXNlLm1qc1wiO1xuaW1wb3J0IHsgaXNBcnJheSwgaXNPYmplY3QsIGlzUHJpbWl0aXZlIH0gZnJvbSBcIi4vaXMubWpzXCI7XG5pbXBvcnQgeyBPYnNlcnZlciB9IGZyb20gXCIuL29ic2VydmVyLm1qc1wiO1xuaW1wb3J0IHsgT2JzZXJ2ZXJMaXN0IH0gZnJvbSBcIi4vb2JzZXJ2ZXJsaXN0Lm1qc1wiO1xuaW1wb3J0IHsgdmFsaWRhdGVPYmplY3QgfSBmcm9tIFwiLi92YWxpZGF0ZS5tanNcIjtcbmltcG9ydCB7IGV4dGVuZCB9IGZyb20gXCIuLi9kYXRhL2V4dGVuZC5tanNcIjtcbmltcG9ydCB7IGluc3RhbmNlU3ltYm9sIH0gZnJvbSBcIi4uL2NvbnN0YW50cy5tanNcIjtcbmV4cG9ydCB7IFByb3h5T2JzZXJ2ZXIgfTtcblxuLyoqXG4gKiBBbiBvYnNlcnZlciBtYW5hZ2VzIGEgY2FsbGJhY2sgZnVuY3Rpb25cbiAqXG4gKiBXaXRoIHRoZSBQcm94eU9ic2VydmVyIHlvdSBjYW4gYXR0YWNoIG9ic2VydmVyIGZvciBvYnNlcnZhdGlvbi5cbiAqIFdpdGggZWFjaCBjaGFuZ2UgYXQgdGhlIG9iamVjdCB0byBiZSBvYnNlcnZlZCBhbiB1cGRhdGUgdGFrZXMgcGxhY2UuXG4gKlxuICogVGhpcyBhbHNvIGFwcGxpZXMgdG8gbmVzdGVkIG9iamVjdHMuXG4gKlxuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL3R5cGVzL3Byb3h5b2JzZXJ2ZXIubWpzXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjAuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKi9cbmNsYXNzIFByb3h5T2JzZXJ2ZXIgZXh0ZW5kcyBCYXNlIHtcbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBvYmplY3RcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIG9iamVjdFxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKG9iamVjdCkge1xuICAgICAgICBzdXBlcigpO1xuXG4gICAgICAgIHRoaXMucmVhbFN1YmplY3QgPSB2YWxpZGF0ZU9iamVjdChvYmplY3QpO1xuICAgICAgICB0aGlzLnN1YmplY3QgPSBuZXcgUHJveHkob2JqZWN0LCBnZXRIYW5kbGVyLmNhbGwodGhpcykpO1xuXG4gICAgICAgIHRoaXMub2JqZWN0TWFwID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgdGhpcy5vYmplY3RNYXAuc2V0KHRoaXMucmVhbFN1YmplY3QsIHRoaXMuc3ViamVjdCk7XG5cbiAgICAgICAgdGhpcy5wcm94eU1hcCA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIHRoaXMucHJveHlNYXAuc2V0KHRoaXMuc3ViamVjdCwgdGhpcy5yZWFsU3ViamVjdCk7XG5cbiAgICAgICAgdGhpcy5vYnNlcnZlcnMgPSBuZXcgT2JzZXJ2ZXJMaXN0KCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMi4xLjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci90eXBlcy9wcm94eS1vYnNlcnZlclwiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHJlYWwgb2JqZWN0XG4gICAgICpcbiAgICAgKiBDaGFuZ2VzIHRvIHRoaXMgb2JqZWN0IGFyZSBub3Qgbm90aWNlZCBieSB0aGUgb2JzZXJ2ZXJzLCBzbyB5b3UgY2FuIG1ha2UgYSBsYXJnZSBudW1iZXIgb2YgY2hhbmdlcyBhbmQgaW5mb3JtIHRoZSBvYnNlcnZlcnMgbGF0ZXIuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7b2JqZWN0fVxuICAgICAqL1xuICAgIGdldFN1YmplY3QoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN1YmplY3Q7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHNpbmNlIDEuMjQuMFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAgICAgKiBAcmV0dXJuIHtNb25zdGVyLlR5cGVzLlByb3h5T2JzZXJ2ZXJ9XG4gICAgICovXG4gICAgc2V0U3ViamVjdChvYmopIHtcbiAgICAgICAgbGV0IGk7XG4gICAgICAgIGxldCBrID0gT2JqZWN0LmtleXModGhpcy5zdWJqZWN0KTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGsubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnN1YmplY3Rba1tpXV07XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnN1YmplY3QgPSBleHRlbmQodGhpcy5zdWJqZWN0LCBvYmopO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBnZXQgdGhlIHByb3hpZWQgb2JqZWN0XG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7b2JqZWN0fVxuICAgICAqL1xuICAgIGdldFJlYWxTdWJqZWN0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5yZWFsU3ViamVjdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBhdHRhY2ggYSBuZXcgb2JzZXJ2ZXJcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7T2JzZXJ2ZXJ9IG9ic2VydmVyXG4gICAgICogQHJldHVybnMge1Byb3h5T2JzZXJ2ZXJ9XG4gICAgICovXG4gICAgYXR0YWNoT2JzZXJ2ZXIob2JzZXJ2ZXIpIHtcbiAgICAgICAgdGhpcy5vYnNlcnZlcnMuYXR0YWNoKG9ic2VydmVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogZGV0YWNoIGEgb2JzZXJ2ZXJcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7T2JzZXJ2ZXJ9IG9ic2VydmVyXG4gICAgICogQHJldHVybnMge1Byb3h5T2JzZXJ2ZXJ9XG4gICAgICovXG4gICAgZGV0YWNoT2JzZXJ2ZXIob2JzZXJ2ZXIpIHtcbiAgICAgICAgdGhpcy5vYnNlcnZlcnMuZGV0YWNoKG9ic2VydmVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogbm90aWZ5IGFsbCBvYnNlcnZlclxuICAgICAqXG4gICAgICogQHJldHVybnMge1Byb21pc2V9XG4gICAgICovXG4gICAgbm90aWZ5T2JzZXJ2ZXJzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5vYnNlcnZlcnMubm90aWZ5KHRoaXMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7T2JzZXJ2ZXJ9IG9ic2VydmVyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAgICovXG4gICAgY29udGFpbnNPYnNlcnZlcihvYnNlcnZlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5vYnNlcnZlcnMuY29udGFpbnMob2JzZXJ2ZXIpO1xuICAgIH1cbn1cblxuLyoqXG4gKlxuICogQHJldHVybnMge3tkZWZpbmVQcm9wZXJ0eTogKGZ1bmN0aW9uKCo9LCAqPSwgKj0pOiAqKSwgc2V0UHJvdG90eXBlT2Y6IChmdW5jdGlvbigqLCAqPSk6IGJvb2xlYW4pLCBzZXQ6IChmdW5jdGlvbigqLCAqLCAqLCAqKTogYm9vbGVhbiksIGdldDogKChmdW5jdGlvbigqPSwgKj0sICo9KTogKHVuZGVmaW5lZCkpfCopLCBkZWxldGVQcm9wZXJ0eTogKChmdW5jdGlvbigqLCAqKTogKGJvb2xlYW4pKXwqKX19XG4gKiBAcHJpdmF0ZVxuICogQHNlZSB7QGxpbmsgaHR0cHM6Ly9naXRsYWIuc2NodWthaS5jb20vLS9zbmlwcGV0cy80OX1cbiAqL1xuZnVuY3Rpb24gZ2V0SGFuZGxlcigpIHtcbiAgICBjb25zdCBwcm94eSA9IHRoaXM7XG5cbiAgICAvLyBodHRwczovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzkuMC8jc2VjLXByb3h5LW9iamVjdC1pbnRlcm5hbC1tZXRob2RzLWFuZC1pbnRlcm5hbC1zbG90c1xuICAgIGNvbnN0IGhhbmRsZXIgPSB7XG4gICAgICAgIC8vIGh0dHBzOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvOS4wLyNzZWMtcHJveHktb2JqZWN0LWludGVybmFsLW1ldGhvZHMtYW5kLWludGVybmFsLXNsb3RzLWdldC1wLXJlY2VpdmVyXG4gICAgICAgIGdldDogZnVuY3Rpb24gKHRhcmdldCwga2V5LCByZWNlaXZlcikge1xuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBSZWZsZWN0LmdldCh0YXJnZXQsIGtleSwgcmVjZWl2ZXIpO1xuXG4gICAgICAgICAgICBpZiAodHlwZW9mIGtleSA9PT0gXCJzeW1ib2xcIikge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGlzUHJpbWl0aXZlKHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gc2V0IHZhbHVlIGFzIHByb3h5IGlmIG9iamVjdCBvciBhcnJheVxuICAgICAgICAgICAgaWYgKGlzQXJyYXkodmFsdWUpIHx8IGlzT2JqZWN0KHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIGlmIChwcm94eS5vYmplY3RNYXAuaGFzKHZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcHJveHkub2JqZWN0TWFwLmdldCh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwcm94eS5wcm94eU1hcC5oYXModmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBsZXQgcCA9IG5ldyBQcm94eSh2YWx1ZSwgaGFuZGxlcik7XG4gICAgICAgICAgICAgICAgICAgIHByb3h5Lm9iamVjdE1hcC5zZXQodmFsdWUsIHApO1xuICAgICAgICAgICAgICAgICAgICBwcm94eS5wcm94eU1hcC5zZXQocCwgdmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfSxcblxuICAgICAgICAvLyBodHRwczovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzkuMC8jc2VjLXByb3h5LW9iamVjdC1pbnRlcm5hbC1tZXRob2RzLWFuZC1pbnRlcm5hbC1zbG90cy1zZXQtcC12LXJlY2VpdmVyXG4gICAgICAgIHNldDogZnVuY3Rpb24gKHRhcmdldCwga2V5LCB2YWx1ZSwgcmVjZWl2ZXIpIHtcbiAgICAgICAgICAgIGlmIChwcm94eS5wcm94eU1hcC5oYXModmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBwcm94eS5wcm94eU1hcC5nZXQodmFsdWUpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAocHJveHkucHJveHlNYXAuaGFzKHRhcmdldCkpIHtcbiAgICAgICAgICAgICAgICB0YXJnZXQgPSBwcm94eS5wcm94eU1hcC5nZXQodGFyZ2V0KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGV0IGN1cnJlbnQgPSBSZWZsZWN0LmdldCh0YXJnZXQsIGtleSwgcmVjZWl2ZXIpO1xuICAgICAgICAgICAgaWYgKHByb3h5LnByb3h5TWFwLmhhcyhjdXJyZW50KSkge1xuICAgICAgICAgICAgICAgIGN1cnJlbnQgPSBwcm94eS5wcm94eU1hcC5nZXQoY3VycmVudCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChjdXJyZW50ID09PSB2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgcmVzdWx0O1xuICAgICAgICAgICAgbGV0IGRlc2NyaXB0b3IgPSBSZWZsZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIGtleSk7XG5cbiAgICAgICAgICAgIGlmIChkZXNjcmlwdG9yID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBkZXNjcmlwdG9yID0ge1xuICAgICAgICAgICAgICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGRlc2NyaXB0b3JbXCJ2YWx1ZVwiXSA9IHZhbHVlO1xuICAgICAgICAgICAgcmVzdWx0ID0gUmVmbGVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgZGVzY3JpcHRvcik7XG5cbiAgICAgICAgICAgIGlmICh0eXBlb2Yga2V5ICE9PSBcInN5bWJvbFwiKSB7XG4gICAgICAgICAgICAgICAgcHJveHkub2JzZXJ2ZXJzLm5vdGlmeShwcm94eSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH0sXG5cbiAgICAgICAgLy8gaHR0cHM6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy85LjAvI3NlYy1wcm94eS1vYmplY3QtaW50ZXJuYWwtbWV0aG9kcy1hbmQtaW50ZXJuYWwtc2xvdHMtZGVsZXRlLXBcbiAgICAgICAgZGVsZXRlUHJvcGVydHk6IGZ1bmN0aW9uICh0YXJnZXQsIGtleSkge1xuICAgICAgICAgICAgaWYgKGtleSBpbiB0YXJnZXQpIHtcbiAgICAgICAgICAgICAgICBkZWxldGUgdGFyZ2V0W2tleV07XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGtleSAhPT0gXCJzeW1ib2xcIikge1xuICAgICAgICAgICAgICAgICAgICBwcm94eS5vYnNlcnZlcnMubm90aWZ5KHByb3h5KTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfSxcblxuICAgICAgICAvLyBodHRwczovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzkuMC8jc2VjLXByb3h5LW9iamVjdC1pbnRlcm5hbC1tZXRob2RzLWFuZC1pbnRlcm5hbC1zbG90cy1kZWZpbmVvd25wcm9wZXJ0eS1wLWRlc2NcbiAgICAgICAgZGVmaW5lUHJvcGVydHk6IGZ1bmN0aW9uICh0YXJnZXQsIGtleSwgZGVzY3JpcHRvcikge1xuICAgICAgICAgICAgbGV0IHJlc3VsdCA9IFJlZmxlY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIGRlc2NyaXB0b3IpO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBrZXkgIT09IFwic3ltYm9sXCIpIHtcbiAgICAgICAgICAgICAgICBwcm94eS5vYnNlcnZlcnMubm90aWZ5KHByb3h5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH0sXG5cbiAgICAgICAgLy8gaHR0cHM6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy85LjAvI3NlYy1wcm94eS1vYmplY3QtaW50ZXJuYWwtbWV0aG9kcy1hbmQtaW50ZXJuYWwtc2xvdHMtc2V0cHJvdG90eXBlb2YtdlxuICAgICAgICBzZXRQcm90b3R5cGVPZjogZnVuY3Rpb24gKHRhcmdldCwga2V5KSB7XG4gICAgICAgICAgICBsZXQgcmVzdWx0ID0gUmVmbGVjdC5zZXRQcm90b3R5cGVPZihvYmplY3QxLCBrZXkpO1xuXG4gICAgICAgICAgICBpZiAodHlwZW9mIGtleSAhPT0gXCJzeW1ib2xcIikge1xuICAgICAgICAgICAgICAgIHByb3h5Lm9ic2VydmVycy5ub3RpZnkocHJveHkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9LFxuICAgIH07XG5cbiAgICByZXR1cm4gaGFuZGxlcjtcbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGludGVybmFsU3RhdGVTeW1ib2wsIGludGVybmFsU3ltYm9sIH0gZnJvbSBcIi4uL2NvbnN0YW50cy5tanNcIjtcbmltcG9ydCB7IGV4dGVuZCB9IGZyb20gXCIuLi9kYXRhL2V4dGVuZC5tanNcIjtcbmltcG9ydCB7IEJhc2VXaXRoT3B0aW9ucyB9IGZyb20gXCIuLi90eXBlcy9iYXNld2l0aG9wdGlvbnMubWpzXCI7XG5pbXBvcnQgeyBnZXRHbG9iYWxPYmplY3QgfSBmcm9tIFwiLi4vdHlwZXMvZ2xvYmFsLm1qc1wiO1xuaW1wb3J0IHsgSUQgfSBmcm9tIFwiLi4vdHlwZXMvaWQubWpzXCI7XG5pbXBvcnQgeyBpc1N0cmluZyB9IGZyb20gXCIuLi90eXBlcy9pcy5tanNcIjtcbmltcG9ydCB7IE9ic2VydmVyIH0gZnJvbSBcIi4uL3R5cGVzL29ic2VydmVyLm1qc1wiO1xuaW1wb3J0IHsgUHJveHlPYnNlcnZlciB9IGZyb20gXCIuLi90eXBlcy9wcm94eW9ic2VydmVyLm1qc1wiO1xuaW1wb3J0IHsgQVRUUklCVVRFX0NMQVNTLCBBVFRSSUJVVEVfSUQsIEFUVFJJQlVURV9USVRMRSB9IGZyb20gXCIuL2NvbnN0YW50cy5tanNcIjtcbmltcG9ydCB7IGluc3RhbmNlU3ltYm9sIH0gZnJvbSBcIi4uL2NvbnN0YW50cy5tanNcIjtcblxuZXhwb3J0IHsgUmVzb3VyY2UsIEtFWV9ET0NVTUVOVCwgS0VZX1FVRVJZLCByZWZlcmVuY2VTeW1ib2wgfTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuY29uc3QgS0VZX0RPQ1VNRU5UID0gXCJkb2N1bWVudFwiO1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAdHlwZSB7c3RyaW5nfVxuICovXG5jb25zdCBLRVlfUVVFUlkgPSBcInF1ZXJ5XCI7XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEB0eXBlIHtzdHJpbmd9XG4gKi9cbmNvbnN0IEtFWV9USU1FT1VUID0gXCJ0aW1lb3V0XCI7XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEB0eXBlIHtzeW1ib2x9XG4gKi9cbmNvbnN0IHJlZmVyZW5jZVN5bWJvbCA9IFN5bWJvbChcInJlZmVyZW5jZVwiKTtcblxuLyoqXG4gKiBUaGlzIGNsYXNzIGlzIHRoZSBiYXNlIGNsYXNzIGZvciBhbGwgcmVzb3VyY2VzIHRvIGJlIGxvYWRlZC5cbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI1LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEBzdW1tYXJ5IEEgUmVzb3VyY2UgY2xhc3NcbiAqL1xuY2xhc3MgUmVzb3VyY2UgZXh0ZW5kcyBCYXNlV2l0aE9wdGlvbnMge1xuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYmplY3R8dW5kZWZpbmVkfSBvcHRpb25zXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgICAgICBzdXBlcihvcHRpb25zKTtcblxuICAgICAgICBsZXQgdXJpID0gdGhpcy5nZXRPcHRpb24odGhpcy5jb25zdHJ1Y3Rvci5nZXRVUkxBdHRyaWJ1dGUoKSk7XG5cbiAgICAgICAgaWYgKHVyaSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJtaXNzaW5nIHNvdXJjZVwiKTtcbiAgICAgICAgfSBlbHNlIGlmICh1cmkgaW5zdGFuY2VvZiBVUkwpIHtcbiAgICAgICAgICAgIHVyaSA9IHVyaS50b1N0cmluZygpO1xuICAgICAgICB9IGVsc2UgaWYgKCFpc1N0cmluZyh1cmkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1bnN1cHBvcnRlZCB1cmwgdHlwZVwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXNbaW50ZXJuYWxTeW1ib2xdW3RoaXMuY29uc3RydWN0b3IuZ2V0VVJMQXR0cmlidXRlKCldID0gdXJpO1xuICAgICAgICB0aGlzW2ludGVybmFsU3RhdGVTeW1ib2xdID0gbmV3IFByb3h5T2JzZXJ2ZXIoe1xuICAgICAgICAgICAgbG9hZGVkOiBmYWxzZSxcbiAgICAgICAgICAgIGVycm9yOiB1bmRlZmluZWQsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXNbcmVmZXJlbmNlU3ltYm9sXSA9IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgICAqL1xuICAgIGlzQ29ubmVjdGVkKCkge1xuICAgICAgICBpZiAodGhpc1tyZWZlcmVuY2VTeW1ib2xdIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzW3JlZmVyZW5jZVN5bWJvbF0uaXNDb25uZWN0ZWQ7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgb3ZlcnJpZGRlbiBieSB0aGUgc3BlY2lhbCBjbGFzc2VzIGFuZCBjcmVhdGVzIHRoZSBET00gb2JqZWN0LlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGFsc28gY2FsbGVkIGltcGxpY2l0bHksIGlmIG5vdCB5ZXQgZG9uZSBleHBsaWNpdGx5LCBieSBjYWxsaW5nIGBjb25uZWN0KClgLlxuICAgICAqXG4gICAgICogQHRocm93cyB7RXJyb3J9IHRoaXMgbWV0aG9kIG11c3QgYmUgaW1wbGVtZW50ZWQgYnkgZGVyaXZlZCBjbGFzc2VzXG4gICAgICogQHJldHVybiB7TW9uc3Rlci5ET00uUmVzb3VyY2V9XG4gICAgICovXG4gICAgY3JlYXRlKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0aGlzIG1ldGhvZCBtdXN0IGJlIGltcGxlbWVudGVkIGJ5IGRlcml2ZWQgY2xhc3Nlc1wiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBhcHBlbmRzIHRoZSBIVE1MRWxlbWVudCB0byB0aGUgc3BlY2lmaWVkIGRvY3VtZW50LlxuICAgICAqIElmIHRoZSBlbGVtZW50IGhhcyBub3QgeWV0IGJlZW4gY3JlYXRlZCwgYGNyZWF0ZSgpYCBpcyBjYWxsZWQgaW1wbGljaXRseS5cbiAgICAgKlxuICAgICAqIHRocm93cyB7RXJyb3J9IHRhcmdldCBub3QgZm91bmRcbiAgICAgKiBAcmV0dXJuIHtNb25zdGVyLkRPTS5SZXNvdXJjZX1cbiAgICAgKi9cbiAgICBjb25uZWN0KCkge1xuICAgICAgICBpZiAoISh0aGlzW3JlZmVyZW5jZVN5bWJvbF0gaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpIHtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRlKCk7XG4gICAgICAgIH1cblxuICAgICAgICBhcHBlbmRUb0RvY3VtZW50LmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwcm9wZXJ0eSB7RG9jdW1lbnR9IGRvY3VtZW50IHRoZSBkb2N1bWVudCBvYmplY3QgaW50byB3aGljaCB0aGUgbm9kZSBpcyB0byBiZSBhcHBlbmRlZFxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBzcmMvaHJlZiB1cmwgdG8gdGhlIGNvcnJlc3BvbmRpbmcgcmVzb3VyY2VcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gcXVlcnkgZGVmaW5lcyB0aGUgbG9jYXRpb24gd2hlcmUgdGhlIHJlc291cmNlIGlzIHRvIGJlIGhvb2tlZCBpbnRvIHRoZSBkb20uXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd9IGlkIGVsZW1lbnQgYXR0cmlidXRlIGlkXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd9IHRpdGxlIGVsZW1lbnQgYXR0cmlidXRlIHRpdGxlXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd9IGNsYXNzIGVsZW1lbnQgYXR0cmlidXRlIGNsYXNzXG4gICAgICogQHByb3BlcnR5IHtpbnR9IHRpbWVvdXQgdGltZW91dFxuICAgICAqL1xuICAgIGdldCBkZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIGV4dGVuZCh7fSwgc3VwZXIuZGVmYXVsdHMsIHtcbiAgICAgICAgICAgIFt0aGlzLmNvbnN0cnVjdG9yLmdldFVSTEF0dHJpYnV0ZSgpXTogdW5kZWZpbmVkLFxuICAgICAgICAgICAgW0tFWV9ET0NVTUVOVF06IGdldEdsb2JhbE9iamVjdChcImRvY3VtZW50XCIpLFxuICAgICAgICAgICAgW0tFWV9RVUVSWV06IFwiaGVhZFwiLFxuICAgICAgICAgICAgW0tFWV9USU1FT1VUXTogMTAwMDAsXG4gICAgICAgICAgICBbQVRUUklCVVRFX0lEXTogbmV3IElEKFwicmVzb3VyY2VcIikudG9TdHJpbmcoKSxcbiAgICAgICAgICAgIFtBVFRSSUJVVEVfQ0xBU1NdOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBbQVRUUklCVVRFX1RJVExFXTogdW5kZWZpbmVkLFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBXaXRoIGBhdmFpbGFibGUoKWAgeW91IGNhbiBjaGVjayBpZiBhIHJlc291cmNlIGlzIGF2YWlsYWJsZS5cbiAgICAgKiBUaGlzIGlzIHRoZSBjYXNlIHdoZW4gdGhlIHRhZyBpcyBpbmNsdWRlZCBhbmQgdGhlIHJlc291cmNlIGlzIGxvYWRlZC5cbiAgICAgKlxuICAgICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAgICovXG4gICAgYXZhaWxhYmxlKCkge1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICAgICAgaWYgKCEoc2VsZltyZWZlcmVuY2VTeW1ib2xdIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXCJubyBlbGVtZW50XCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFzZWxmLmlzQ29ubmVjdGVkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChcImVsZW1lbnQgbm90IGNvbm5lY3RlZFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzZWxmW2ludGVybmFsU3RhdGVTeW1ib2xdLmdldFN1YmplY3QoKVtcImxvYWRlZFwiXSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgaWYgKHNlbGZbaW50ZXJuYWxTdGF0ZVN5bWJvbF0uZ2V0U3ViamVjdCgpW1wiZXJyb3JcIl0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChzZWxmW2ludGVybmFsU3RhdGVTeW1ib2xdLmdldFN1YmplY3QoKVtcImVycm9yXCJdKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgICAgIGNvbnN0IHRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICByZWplY3QoXCJ0aW1lb3V0XCIpO1xuICAgICAgICAgICAgfSwgc2VsZi5nZXRPcHRpb24oXCJ0aW1lb3V0XCIpKTtcblxuICAgICAgICAgICAgY29uc3Qgb2JzZXJ2ZXIgPSBuZXcgT2JzZXJ2ZXIoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgICAgICAgICAgICBzZWxmW2ludGVybmFsU3RhdGVTeW1ib2xdLmRldGFjaE9ic2VydmVyKG9ic2VydmVyKTtcbiAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgc2VsZltpbnRlcm5hbFN0YXRlU3ltYm9sXS5hdHRhY2hPYnNlcnZlcihvYnNlcnZlcik7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge3N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0VVJMQXR0cmlidXRlKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0aGlzIG1ldGhvZCBtdXN0IGJlIGltcGxlbWVudGVkIGJ5IGRlcml2ZWQgY2xhc3Nlc1wiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtzeW1ib2x9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBbaW5zdGFuY2VTeW1ib2xdKCkge1xuICAgICAgICByZXR1cm4gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvZG9tL3Jlc291cmNlXCIpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHJldHVybiB7UHJvbWlzZX1cbiAqIHRocm93cyB7RXJyb3J9IHRhcmdldCBub3QgZm91bmRcbiAqL1xuZnVuY3Rpb24gYXBwZW5kVG9Eb2N1bWVudCgpIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgIGNvbnN0IHRhcmdldE5vZGUgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHNlbGYuZ2V0T3B0aW9uKEtFWV9RVUVSWSwgXCJoZWFkXCIpKTtcbiAgICBpZiAoISh0YXJnZXROb2RlIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcInRhcmdldCBub3QgZm91bmRcIik7XG4gICAgfVxuXG4gICAgYWRkRXZlbnRzLmNhbGwoc2VsZik7XG4gICAgdGFyZ2V0Tm9kZS5hcHBlbmRDaGlsZChzZWxmW3JlZmVyZW5jZVN5bWJvbF0pO1xuXG4gICAgcmV0dXJuIHNlbGY7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEByZXR1cm4ge2FkZEV2ZW50c31cbiAqL1xuZnVuY3Rpb24gYWRkRXZlbnRzKCkge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgY29uc3Qgb25FcnJvciA9ICgpID0+IHtcbiAgICAgICAgc2VsZltyZWZlcmVuY2VTeW1ib2xdLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJlcnJvclwiLCBvbkVycm9yKTtcbiAgICAgICAgc2VsZltyZWZlcmVuY2VTeW1ib2xdLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJsb2FkXCIsIG9uTG9hZCk7XG5cbiAgICAgICAgc2VsZltpbnRlcm5hbFN0YXRlU3ltYm9sXS5zZXRTdWJqZWN0KHtcbiAgICAgICAgICAgIGxvYWRlZDogdHJ1ZSxcbiAgICAgICAgICAgIGVycm9yOiBgJHtzZWxmW3JlZmVyZW5jZVN5bWJvbF1bc2VsZi5jb25zdHJ1Y3Rvci5nZXRVUkxBdHRyaWJ1dGUoKV19IGlzIG5vdCBhdmFpbGFibGVgLFxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm47XG4gICAgfTtcblxuICAgIGNvbnN0IG9uTG9hZCA9ICgpID0+IHtcbiAgICAgICAgc2VsZltyZWZlcmVuY2VTeW1ib2xdLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJlcnJvclwiLCBvbkVycm9yKTtcbiAgICAgICAgc2VsZltyZWZlcmVuY2VTeW1ib2xdLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJsb2FkXCIsIG9uTG9hZCk7XG4gICAgICAgIHNlbGZbaW50ZXJuYWxTdGF0ZVN5bWJvbF0uZ2V0U3ViamVjdCgpW1wibG9hZGVkXCJdID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH07XG5cbiAgICBzZWxmW3JlZmVyZW5jZVN5bWJvbF0uYWRkRXZlbnRMaXN0ZW5lcihcImxvYWRcIiwgb25Mb2FkLCBmYWxzZSk7XG4gICAgc2VsZltyZWZlcmVuY2VTeW1ib2xdLmFkZEV2ZW50TGlzdGVuZXIoXCJlcnJvclwiLCBvbkVycm9yLCBmYWxzZSk7XG5cbiAgICByZXR1cm4gc2VsZjtcbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IEJhc2UgfSBmcm9tIFwiLi9iYXNlLm1qc1wiO1xuaW1wb3J0IHsgaXNTdHJpbmcgfSBmcm9tIFwiLi9pcy5tanNcIjtcbmltcG9ydCB7IHZhbGlkYXRlQXJyYXksIHZhbGlkYXRlU3RyaW5nIH0gZnJvbSBcIi4vdmFsaWRhdGUubWpzXCI7XG5pbXBvcnQgeyBpbnN0YW5jZVN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5leHBvcnQgeyBNZWRpYVR5cGUsIHBhcnNlTWVkaWFUeXBlIH07XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEB0eXBlIHtzeW1ib2x9XG4gKi9cbmNvbnN0IGludGVybmFsID0gU3ltYm9sKFwiaW50ZXJuYWxcIik7XG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gUGFyYW1ldGVyXG4gKiBAcHJvcGVydHkge3N0cmluZ30ga2V5XG4gKiBAcHJvcGVydHkge3N0cmluZ30gdmFsdWVcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKi9cblxuLyoqXG4gKiBZb3UgY2FuIGNyZWF0ZSBhbiBvYmplY3QgdmlhIHRoZSBtb25zdGVyIG5hbWVzcGFjZSBgbmV3IE1vbnN0ZXIuVHlwZXMuTWVkaWFUeXBlKClgLlxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuOC4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcbiAqL1xuY2xhc3MgTWVkaWFUeXBlIGV4dGVuZHMgQmFzZSB7XG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gdHlwZVxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBzdWJ0eXBlXG4gICAgICogQHBhcmFtIHtNb25zdGVyLlR5cGVzLlBhcmFtZXRlcltdfSBwYXJhbWV0ZXJcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0eXBlLCBzdWJ0eXBlLCBwYXJhbWV0ZXIpIHtcbiAgICAgICAgc3VwZXIoKTtcblxuICAgICAgICB0aGlzW2ludGVybmFsXSA9IHtcbiAgICAgICAgICAgIHR5cGU6IHZhbGlkYXRlU3RyaW5nKHR5cGUpLnRvTG93ZXJDYXNlKCksXG4gICAgICAgICAgICBzdWJ0eXBlOiB2YWxpZGF0ZVN0cmluZyhzdWJ0eXBlKS50b0xvd2VyQ2FzZSgpLFxuICAgICAgICAgICAgcGFyYW1ldGVyOiBbXSxcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAocGFyYW1ldGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXNbaW50ZXJuYWxdW1wicGFyYW1ldGVyXCJdID0gdmFsaWRhdGVBcnJheShwYXJhbWV0ZXIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMi4xLjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci90eXBlcy9tZWRpYS10eXBlXCIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbaW50ZXJuYWxdLnR5cGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldCBzdWJ0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpc1tpbnRlcm5hbF0uc3VidHlwZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtNb25zdGVyLlR5cGVzLlBhcmFtZXRlcltdfVxuICAgICAqL1xuICAgIGdldCBwYXJhbWV0ZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzW2ludGVybmFsXS5wYXJhbWV0ZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKlxuICAgICAqIEByZXR1cm4ge01hcH1cbiAgICAgKi9cbiAgICBnZXQgcGFyYW1ldGVyKCkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBuZXcgTWFwKCk7XG5cbiAgICAgICAgdGhpc1tpbnRlcm5hbF1bXCJwYXJhbWV0ZXJcIl0uZm9yRWFjaCgocCkgPT4ge1xuICAgICAgICAgICAgbGV0IHZhbHVlID0gcC52YWx1ZTtcblxuICAgICAgICAgICAgLy8gaW50ZXJuYWxseSBzcGVjaWFsIHZhbHVlcyBhcmUgcGFydGx5IHN0b3JlZCB3aXRoIHF1b3RlcywgdGhpcyBmdW5jdGlvbiByZW1vdmVzIHRoZW0uXG4gICAgICAgICAgICBpZiAodmFsdWUuc3RhcnRzV2l0aCgnXCInKSAmJiB2YWx1ZS5lbmRzV2l0aCgnXCInKSkge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gdmFsdWUuc3Vic3RyaW5nKDEsIHZhbHVlLmxlbmd0aCAtIDEpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXN1bHQuc2V0KHAua2V5LCB2YWx1ZSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAgICovXG4gICAgdG9TdHJpbmcoKSB7XG4gICAgICAgIGxldCBwYXJhbWV0ZXIgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgYSBvZiB0aGlzW2ludGVybmFsXS5wYXJhbWV0ZXIpIHtcbiAgICAgICAgICAgIHBhcmFtZXRlci5wdXNoKGAke2Eua2V5fT0ke2EudmFsdWV9YCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYCR7dGhpc1tpbnRlcm5hbF0udHlwZX0vJHt0aGlzW2ludGVybmFsXS5zdWJ0eXBlfSR7XG4gICAgICAgICAgICBwYXJhbWV0ZXIubGVuZ3RoID4gMCA/IGA7JHtwYXJhbWV0ZXIuam9pbihcIjtcIil9YCA6IFwiXCJcbiAgICAgICAgfWA7XG4gICAgfVxufVxuXG4vKipcbiAqIFlvdSBjYW4gY2FsbCB0aGUgZnVuY3Rpb24gdmlhIHRoZSBtb25zdGVyIG5hbWVzcGFjZSBgTW9uc3Rlci5UeXBlcy5wYXJzZU1lZGlhVHlwZSgpYC5cbiAqXG4gKiBgYGBcbiAqIDxzY3JpcHQgdHlwZT1cIm1vZHVsZVwiPlxuICogaW1wb3J0IHtNb25zdGVyfSBmcm9tICdAc2NodWthaS9tb25zdGVyL3NvdXJjZS9tb25zdGVyLm1qcyc7XG4gKiBjb25zb2xlLmxvZyhNb25zdGVyLlR5cGVzLnBhcnNlTWVkaWFUeXBlKCkpXG4gKiA8L3NjcmlwdD5cbiAqIGBgYFxuICpcbiAqIEFsdGVybmF0aXZlbHksIHlvdSBjYW4gYWxzbyBpbnRlZ3JhdGUgdGhpcyBmdW5jdGlvbiBpbmRpdmlkdWFsbHkuXG4gKlxuICogYGBgXG4gKiA8c2NyaXB0IHR5cGU9XCJtb2R1bGVcIj5cbiAqIGltcG9ydCB7cGFyc2VNZWRpYVR5cGV9IGZyb20gJ0BzY2h1a2FpL21vbnN0ZXIvc291cmNlL3R5cGVzL2RhdGF1cmwubWpzJztcbiAqIGNvbnNvbGUubG9nKHBhcnNlTWVkaWFUeXBlKCkpXG4gKiA8L3NjcmlwdD5cbiAqIGBgYFxuICpcbiAqIFNwZWNpZmljYXRpb246XG4gKlxuICogYGBgXG4gKiBkYXRhdXJsICAgIDo9IFwiZGF0YTpcIiBbIG1lZGlhdHlwZSBdIFsgXCI7YmFzZTY0XCIgXSBcIixcIiBkYXRhXG4gKiBtZWRpYXR5cGUgIDo9IFsgdHlwZSBcIi9cIiBzdWJ0eXBlIF0gKiggXCI7XCIgcGFyYW1ldGVyIClcbiAqIGRhdGEgICAgICAgOj0gKnVybGNoYXJcbiAqIHBhcmFtZXRlciAgOj0gYXR0cmlidXRlIFwiPVwiIHZhbHVlXG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbWVkaWF0eXBlXG4gKiBAcmV0dXJuIHtNb25zdGVyLlR5cGVzLk1lZGlhVHlwZX1cbiAqIEBzZWUgaHR0cHM6Ly9kYXRhdHJhY2tlci5pZXRmLm9yZy9kb2MvaHRtbC9yZmMyMDQ1I3NlY3Rpb24tNS4xXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHRoZSBtaW1ldHlwZSBjYW4gbm90IGJlIHBhcnNlZFxuICogQHRocm93cyB7VHlwZUVycm9yfSBibGFuayB2YWx1ZSBpcyBub3QgYWxsb3dlZFxuICogQHRocm93cyB7VHlwZUVycm9yfSBtYWxmb3JtZWQgZGF0YSB1cmxcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKi9cbmZ1bmN0aW9uIHBhcnNlTWVkaWFUeXBlKG1lZGlhdHlwZSkge1xuICAgIGNvbnN0IHJlZ2V4ID1cbiAgICAgICAgLyg/PHR5cGU+W0EtWmEtel0rfFxcKilcXC8oPzxzdWJ0eXBlPihbYS16QS1aMC05LlxcK19cXC1dKyl8XFwqfCkoPzxwYXJhbWV0ZXI+XFxzKjtcXHMqKFthLXpBLVowLTldKylcXHMqKD1cXHMqKFwiP1tBLVphLXowLTlfXFwtXStcIj8pKT8pKi9nO1xuICAgIGNvbnN0IHJlc3VsdCA9IHJlZ2V4LmV4ZWModmFsaWRhdGVTdHJpbmcobWVkaWF0eXBlKSk7XG5cbiAgICBjb25zdCBncm91cHMgPSByZXN1bHQ/LltcImdyb3Vwc1wiXTtcbiAgICBpZiAoZ3JvdXBzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInRoZSBtaW1ldHlwZSBjYW4gbm90IGJlIHBhcnNlZFwiKTtcbiAgICB9XG5cbiAgICBjb25zdCB0eXBlID0gZ3JvdXBzPy5bXCJ0eXBlXCJdO1xuICAgIGNvbnN0IHN1YnR5cGUgPSBncm91cHM/LltcInN1YnR5cGVcIl07XG4gICAgY29uc3QgcGFyYW1ldGVyID0gZ3JvdXBzPy5bXCJwYXJhbWV0ZXJcIl07XG5cbiAgICBpZiAoc3VidHlwZSA9PT0gXCJcIiB8fCB0eXBlID09PSBcIlwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJibGFuayB2YWx1ZSBpcyBub3QgYWxsb3dlZFwiKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IE1lZGlhVHlwZSh0eXBlLCBzdWJ0eXBlLCBwYXJzZVBhcmFtZXRlcihwYXJhbWV0ZXIpKTtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4xOC4wXG4gKiBAcGFyYW0ge1N0cmluZ30gcGFyYW1ldGVyXG4gKiBAcmV0dXJuIHtNb25zdGVyLlR5cGVzLlBhcmFtZXRlcltdfHVuZGVmaW5lZH1cbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKi9cbmZ1bmN0aW9uIHBhcnNlUGFyYW1ldGVyKHBhcmFtZXRlcikge1xuICAgIGlmICghaXNTdHJpbmcocGFyYW1ldGVyKSkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGxldCByZXN1bHQgPSBbXTtcblxuICAgIHBhcmFtZXRlci5zcGxpdChcIjtcIikuZm9yRWFjaCgoZW50cnkpID0+IHtcbiAgICAgICAgZW50cnkgPSBlbnRyeS50cmltKCk7XG4gICAgICAgIGlmIChlbnRyeSA9PT0gXCJcIikge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qga3YgPSBlbnRyeS5zcGxpdChcIj1cIik7XG5cbiAgICAgICAgbGV0IGtleSA9IHZhbGlkYXRlU3RyaW5nKGt2Py5bMF0pLnRyaW0oKTtcbiAgICAgICAgbGV0IHZhbHVlID0gdmFsaWRhdGVTdHJpbmcoa3Y/LlsxXSkudHJpbSgpO1xuXG4gICAgICAgIC8vIGlmIHZhbHVlcyBhcmUgcXVvdGVkLCB0aGV5IHJlbWFpbiBzbyBpbnRlcm5hbGx5XG4gICAgICAgIHJlc3VsdC5wdXNoKHtcbiAgICAgICAgICAgIGtleToga2V5LFxuICAgICAgICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIHJldHVybiByZXN1bHQ7XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBCYXNlIH0gZnJvbSBcIi4vYmFzZS5tanNcIjtcbmltcG9ydCB7IGlzU3RyaW5nIH0gZnJvbSBcIi4vaXMubWpzXCI7XG5pbXBvcnQgeyBNZWRpYVR5cGUsIHBhcnNlTWVkaWFUeXBlIH0gZnJvbSBcIi4vbWVkaWF0eXBlLm1qc1wiO1xuaW1wb3J0IHsgdmFsaWRhdGVCb29sZWFuLCB2YWxpZGF0ZUluc3RhbmNlLCB2YWxpZGF0ZVN0cmluZyB9IGZyb20gXCIuL3ZhbGlkYXRlLm1qc1wiO1xuaW1wb3J0IHsgaW5zdGFuY2VTeW1ib2wgfSBmcm9tIFwiLi4vY29uc3RhbnRzLm1qc1wiO1xuZXhwb3J0IHsgRGF0YVVybCwgcGFyc2VEYXRhVVJMIH07XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEB0eXBlIHtzeW1ib2x9XG4gKi9cbmNvbnN0IGludGVybmFsID0gU3ltYm9sKFwiaW50ZXJuYWxcIik7XG5cbi8qKlxuICogWW91IGNhbiBjcmVhdGUgYW4gb2JqZWN0IHZpYSB0aGUgbW9uc3RlciBuYW1lc3BhY2UgYG5ldyBNb25zdGVyLlR5cGVzLkRhdGFVcmwoKWAuXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS44LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UeXBlc1xuICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVFRQL0Jhc2ljc19vZl9IVFRQL0RhdGFfVVJJc1xuICogQHNlZSBodHRwczovL2RhdGF0cmFja2VyLmlldGYub3JnL2RvYy9odG1sL3JmYzIzOTdcbiAqL1xuY2xhc3MgRGF0YVVybCBleHRlbmRzIEJhc2Uge1xuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGNvbnRlbnRcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xNb25zdGVyLlR5cGVzLk1lZGlhVHlwZX0gbWVkaWF0eXBlXG4gICAgICogQHBhcmFtIHtib29sZWFufSBiYXNlNjQ9dHJ1ZVxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGNvbnRlbnQsIG1lZGlhdHlwZSwgYmFzZTY0KSB7XG4gICAgICAgIHN1cGVyKCk7XG5cbiAgICAgICAgaWYgKGlzU3RyaW5nKG1lZGlhdHlwZSkpIHtcbiAgICAgICAgICAgIG1lZGlhdHlwZSA9IHBhcnNlTWVkaWFUeXBlKG1lZGlhdHlwZSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzW2ludGVybmFsXSA9IHtcbiAgICAgICAgICAgIGNvbnRlbnQ6IHZhbGlkYXRlU3RyaW5nKGNvbnRlbnQpLFxuICAgICAgICAgICAgbWVkaWF0eXBlOiB2YWxpZGF0ZUluc3RhbmNlKG1lZGlhdHlwZSwgTWVkaWFUeXBlKSxcbiAgICAgICAgICAgIGJhc2U2NDogdmFsaWRhdGVCb29sZWFuKGJhc2U2NCA9PT0gdW5kZWZpbmVkID8gdHJ1ZSA6IGJhc2U2NCksXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMi4xLjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci90eXBlcy9kYXRhLXVybFwiKTtcbiAgICB9XG5cbiAgICBnZXQgY29udGVudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbaW50ZXJuYWxdLmJhc2U2NCA/IGF0b2IodGhpc1tpbnRlcm5hbF0uY29udGVudCkgOiB0aGlzW2ludGVybmFsXS5jb250ZW50O1xuICAgIH1cblxuICAgIGdldCBtZWRpYXR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzW2ludGVybmFsXS5tZWRpYXR5cGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAgICogQHNlZSBodHRwczovL2RhdGF0cmFja2VyLmlldGYub3JnL2RvYy9odG1sL3JmYzIzOTdcbiAgICAgKi9cbiAgICB0b1N0cmluZygpIHtcbiAgICAgICAgbGV0IGNvbnRlbnQgPSB0aGlzW2ludGVybmFsXS5jb250ZW50O1xuXG4gICAgICAgIGlmICh0aGlzW2ludGVybmFsXS5iYXNlNjQgPT09IHRydWUpIHtcbiAgICAgICAgICAgIGNvbnRlbnQgPSBgO2Jhc2U2NCwke2NvbnRlbnR9YDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnRlbnQgPSBgLCR7ZW5jb2RlVVJJQ29tcG9uZW50KGNvbnRlbnQpfWA7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYGRhdGE6JHt0aGlzW2ludGVybmFsXS5tZWRpYXR5cGUudG9TdHJpbmcoKX0ke2NvbnRlbnR9YDtcbiAgICB9XG59XG5cbi8qKlxuICogWW91IGNhbiBjYWxsIHRoZSBmdW5jdGlvbiB2aWEgdGhlIG1vbnN0ZXIgbmFtZXNwYWNlIGBNb25zdGVyLlR5cGVzLnBhcnNlRGF0YVVSTCgpYC5cbiAqXG4gKiBTcGVjaWZpY2F0aW9uOlxuICpcbiAqIGBgYFxuICogZGF0YXVybCAgICA6PSBcImRhdGE6XCIgWyBtZWRpYXR5cGUgXSBbIFwiO2Jhc2U2NFwiIF0gXCIsXCIgZGF0YVxuICogbWVkaWF0eXBlICA6PSBbIHR5cGUgXCIvXCIgc3VidHlwZSBdICooIFwiO1wiIHBhcmFtZXRlciApXG4gKiBkYXRhICAgICAgIDo9ICp1cmxjaGFyXG4gKiBwYXJhbWV0ZXIgIDo9IGF0dHJpYnV0ZSBcIj1cIiB2YWx1ZVxuICogYGBgXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGRhdGF1cmxcbiAqIEByZXR1cm4ge01vbnN0ZXIuVHlwZXMuRGF0YVVybH1cbiAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRUUC9CYXNpY3Nfb2ZfSFRUUC9EYXRhX1VSSXNcbiAqIEBzZWUgaHR0cHM6Ly9kYXRhdHJhY2tlci5pZXRmLm9yZy9kb2MvaHRtbC9yZmMyMzk3XG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IGluY29ycmVjdCBvciBtaXNzaW5nIGRhdGEgcHJvdG9jb2xcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gbWFsZm9ybWVkIGRhdGEgdXJsXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UeXBlc1xuICovXG5mdW5jdGlvbiBwYXJzZURhdGFVUkwoZGF0YXVybCkge1xuICAgIHZhbGlkYXRlU3RyaW5nKGRhdGF1cmwpO1xuXG4gICAgZGF0YXVybCA9IGRhdGF1cmwudHJpbSgpO1xuXG4gICAgaWYgKGRhdGF1cmwuc3Vic3RyaW5nKDAsIDUpICE9PSBcImRhdGE6XCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImluY29ycmVjdCBvciBtaXNzaW5nIGRhdGEgcHJvdG9jb2xcIik7XG4gICAgfVxuXG4gICAgZGF0YXVybCA9IGRhdGF1cmwuc3Vic3RyaW5nKDUpO1xuXG4gICAgbGV0IHAgPSBkYXRhdXJsLmluZGV4T2YoXCIsXCIpO1xuICAgIGlmIChwID09PSAtMSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwibWFsZm9ybWVkIGRhdGEgdXJsXCIpO1xuICAgIH1cblxuICAgIGxldCBjb250ZW50ID0gZGF0YXVybC5zdWJzdHJpbmcocCArIDEpO1xuICAgIGxldCBtZWRpYXR5cGVBbmRCYXNlNjQgPSBkYXRhdXJsLnN1YnN0cmluZygwLCBwKS50cmltKCk7XG4gICAgbGV0IG1lZGlhdHlwZSA9IFwidGV4dC9wbGFpbjtjaGFyc2V0PVVTLUFTQ0lJXCI7XG4gICAgbGV0IGJhc2U2NEZsYWcgPSBmYWxzZTtcblxuICAgIGlmIChtZWRpYXR5cGVBbmRCYXNlNjQgIT09IFwiXCIpIHtcbiAgICAgICAgbWVkaWF0eXBlID0gbWVkaWF0eXBlQW5kQmFzZTY0O1xuICAgICAgICBpZiAobWVkaWF0eXBlQW5kQmFzZTY0LmVuZHNXaXRoKFwiYmFzZTY0XCIpKSB7XG4gICAgICAgICAgICBsZXQgaSA9IG1lZGlhdHlwZUFuZEJhc2U2NC5sYXN0SW5kZXhPZihcIjtcIik7XG4gICAgICAgICAgICBtZWRpYXR5cGUgPSBtZWRpYXR5cGVBbmRCYXNlNjQuc3Vic3RyaW5nKDAsIGkpO1xuICAgICAgICAgICAgYmFzZTY0RmxhZyA9IHRydWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb250ZW50ID0gZGVjb2RlVVJJQ29tcG9uZW50KGNvbnRlbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgbWVkaWF0eXBlID0gcGFyc2VNZWRpYVR5cGUobWVkaWF0eXBlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBjb250ZW50ID0gZGVjb2RlVVJJQ29tcG9uZW50KGNvbnRlbnQpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgRGF0YVVybChjb250ZW50LCBtZWRpYXR5cGUsIGJhc2U2NEZsYWcpO1xufVxuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgaXNBcnJheSwgaXNPYmplY3QgfSBmcm9tIFwiLi4vdHlwZXMvaXMubWpzXCI7XG5pbXBvcnQgeyB0eXBlT2YgfSBmcm9tIFwiLi4vdHlwZXMvdHlwZW9mLm1qc1wiO1xuXG5leHBvcnQgeyBkaWZmIH07XG5cbi8qKlxuICogV2l0aCB0aGUgZGlmZiBmdW5jdGlvbiB5b3UgY2FuIHBlcmZvcm0gdGhlIGNoYW5nZSBvZiBvbmUgb2JqZWN0IHRvIGFub3RoZXIuIFRoZSByZXN1bHQgc2hvd3MgdGhlIGNoYW5nZXMgb2YgdGhlIHNlY29uZCBvYmplY3QgdG8gdGhlIGZpcnN0IG9iamVjdC5cbiAqXG4gKiBUaGUgb3BlcmF0b3IgYGFkZGAgbWVhbnMgdGhhdCBzb21ldGhpbmcgaGFzIGJlZW4gYWRkZWQgdG8gdGhlIHNlY29uZCBvYmplY3QuIGBkZWxldGVgIG1lYW5zIHRoYXQgc29tZXRoaW5nIGhhcyBiZWVuIGRlbGV0ZWQgZnJvbSB0aGUgc2Vjb25kIG9iamVjdCBjb21wYXJlZCB0byB0aGUgZmlyc3Qgb2JqZWN0LlxuICpcbiAqIEBleHRlcm5hbEV4YW1wbGUgLi4vLi4vZXhhbXBsZS9kYXRhL2RpZmYubWpzXG4gKiBAcGFyYW0geyp9IGZpcnN0XG4gKiBAcGFyYW0geyp9IHNlY29uZFxuICogQHJldHVybiB7YXJyYXl9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjYuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRhdGFcbiAqL1xuZnVuY3Rpb24gZGlmZihmaXJzdCwgc2Vjb25kKSB7XG4gICAgcmV0dXJuIGRvRGlmZihmaXJzdCwgc2Vjb25kKTtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIGFcbiAqIEBwYXJhbSBiXG4gKiBAcGFyYW0gdHlwZVxuICogQHJldHVybiB7U2V0PHN0cmluZz58U2V0PG51bWJlcj59XG4gKi9cbmZ1bmN0aW9uIGdldEtleXMoYSwgYiwgdHlwZSkge1xuICAgIGlmIChpc0FycmF5KHR5cGUpKSB7XG4gICAgICAgIGNvbnN0IGtleXMgPSBhLmxlbmd0aCA+IGIubGVuZ3RoID8gbmV3IEFycmF5KGEubGVuZ3RoKSA6IG5ldyBBcnJheShiLmxlbmd0aCk7XG4gICAgICAgIGtleXMuZmlsbCgwKTtcbiAgICAgICAgcmV0dXJuIG5ldyBTZXQoa2V5cy5tYXAoKF8sIGkpID0+IGkpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFNldChPYmplY3Qua2V5cyhhKS5jb25jYXQoT2JqZWN0LmtleXMoYikpKTtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIGFcbiAqIEBwYXJhbSBiXG4gKiBAcGFyYW0gcGF0aFxuICogQHBhcmFtIGRpZmZcbiAqIEByZXR1cm4ge2FycmF5fVxuICovXG5mdW5jdGlvbiBkb0RpZmYoYSwgYiwgcGF0aCwgZGlmZikge1xuICAgIGxldCB0eXBlQSA9IHR5cGVPZihhKTtcbiAgICBsZXQgdHlwZUIgPSB0eXBlT2YoYik7XG5cbiAgICBjb25zdCBjdXJyUGF0aCA9IHBhdGggfHwgW107XG4gICAgY29uc3QgY3VyckRpZmYgPSBkaWZmIHx8IFtdO1xuXG4gICAgaWYgKHR5cGVBID09PSB0eXBlQiAmJiAodHlwZUEgPT09IFwib2JqZWN0XCIgfHwgdHlwZUEgPT09IFwiYXJyYXlcIikpIHtcbiAgICAgICAgZ2V0S2V5cyhhLCBiLCB0eXBlQSkuZm9yRWFjaCgodikgPT4ge1xuICAgICAgICAgICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYSwgdikpIHtcbiAgICAgICAgICAgICAgICBjdXJyRGlmZi5wdXNoKGJ1aWxkUmVzdWx0KGFbdl0sIGJbdl0sIFwiYWRkXCIsIGN1cnJQYXRoLmNvbmNhdCh2KSkpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHYpKSB7XG4gICAgICAgICAgICAgICAgY3VyckRpZmYucHVzaChidWlsZFJlc3VsdChhW3ZdLCBiW3ZdLCBcImRlbGV0ZVwiLCBjdXJyUGF0aC5jb25jYXQodikpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZG9EaWZmKGFbdl0sIGJbdl0sIGN1cnJQYXRoLmNvbmNhdCh2KSwgY3VyckRpZmYpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBvID0gZ2V0T3BlcmF0b3IoYSwgYiwgdHlwZUEsIHR5cGVCKTtcbiAgICAgICAgaWYgKG8gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgY3VyckRpZmYucHVzaChidWlsZFJlc3VsdChhLCBiLCBvLCBwYXRoKSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gY3VyckRpZmY7XG59XG5cbi8qKlxuICpcbiAqIEBwYXJhbSB7Kn0gYVxuICogQHBhcmFtIHsqfSBiXG4gKiBAcGFyYW0ge3N0cmluZ30gb3BlcmF0b3JcbiAqIEBwYXJhbSB7YXJyYXl9IHBhdGhcbiAqIEByZXR1cm4ge3twYXRoOiBhcnJheSwgb3BlcmF0b3I6IHN0cmluZ319XG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBidWlsZFJlc3VsdChhLCBiLCBvcGVyYXRvciwgcGF0aCkge1xuICAgIGNvbnN0IHJlc3VsdCA9IHtcbiAgICAgICAgb3BlcmF0b3IsXG4gICAgICAgIHBhdGgsXG4gICAgfTtcblxuICAgIGlmIChvcGVyYXRvciAhPT0gXCJhZGRcIikge1xuICAgICAgICByZXN1bHQuZmlyc3QgPSB7XG4gICAgICAgICAgICB2YWx1ZTogYSxcbiAgICAgICAgICAgIHR5cGU6IHR5cGVvZiBhLFxuICAgICAgICB9O1xuXG4gICAgICAgIGlmIChpc09iamVjdChhKSkge1xuICAgICAgICAgICAgY29uc3QgbmFtZSA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihhKT8uY29uc3RydWN0b3I/Lm5hbWU7XG4gICAgICAgICAgICBpZiAobmFtZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0LmZpcnN0Lmluc3RhbmNlID0gbmFtZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmIChvcGVyYXRvciA9PT0gXCJhZGRcIiB8fCBvcGVyYXRvciA9PT0gXCJ1cGRhdGVcIikge1xuICAgICAgICByZXN1bHQuc2Vjb25kID0ge1xuICAgICAgICAgICAgdmFsdWU6IGIsXG4gICAgICAgICAgICB0eXBlOiB0eXBlb2YgYixcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAoaXNPYmplY3QoYikpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hbWUgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YoYik/LmNvbnN0cnVjdG9yPy5uYW1lO1xuICAgICAgICAgICAgaWYgKG5hbWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHJlc3VsdC5zZWNvbmQuaW5zdGFuY2UgPSBuYW1lO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSBhXG4gKiBAcGFyYW0geyp9IGJcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIGlzTm90RXF1YWwoYSwgYikge1xuICAgIGlmICh0eXBlb2YgYSAhPT0gdHlwZW9mIGIpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgaWYgKGEgaW5zdGFuY2VvZiBEYXRlICYmIGIgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICAgIHJldHVybiBhLmdldFRpbWUoKSAhPT0gYi5nZXRUaW1lKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGEgIT09IGI7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gYVxuICogQHBhcmFtIHsqfSBiXG4gKiBAcmV0dXJuIHtzdHJpbmd8dW5kZWZpbmVkfVxuICovXG5mdW5jdGlvbiBnZXRPcGVyYXRvcihhLCBiKSB7XG4gICAgLyoqXG4gICAgICogQHR5cGUge3N0cmluZ3x1bmRlZmluZWR9XG4gICAgICovXG4gICAgbGV0IG9wZXJhdG9yO1xuXG4gICAgLyoqXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBsZXQgdHlwZUEgPSB0eXBlb2YgYTtcblxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgbGV0IHR5cGVCID0gdHlwZW9mIGI7XG5cbiAgICBpZiAodHlwZUEgPT09IFwidW5kZWZpbmVkXCIgJiYgdHlwZUIgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgb3BlcmF0b3IgPSBcImFkZFwiO1xuICAgIH0gZWxzZSBpZiAodHlwZUEgIT09IFwidW5kZWZpbmVkXCIgJiYgdHlwZUIgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgb3BlcmF0b3IgPSBcImRlbGV0ZVwiO1xuICAgIH0gZWxzZSBpZiAoaXNOb3RFcXVhbChhLCBiKSkge1xuICAgICAgICBvcGVyYXRvciA9IFwidXBkYXRlXCI7XG4gICAgfVxuXG4gICAgcmV0dXJuIG9wZXJhdG9yO1xufVxuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgSUQgfSBmcm9tIFwiLi4vdHlwZXMvaWQubWpzXCI7XG5pbXBvcnQgeyBpc09iamVjdCB9IGZyb20gXCIuLi90eXBlcy9pcy5tanNcIjtcbmltcG9ydCB7IHZhbGlkYXRlU3RyaW5nIH0gZnJvbSBcIi4uL3R5cGVzL3ZhbGlkYXRlLm1qc1wiO1xuXG5leHBvcnQgeyB0cmltU3BhY2VzIH07XG5cbi8qKlxuICogVGhpcyBzcGVjaWFsIHRyaW0gZnVuY3Rpb24gYWxsb3dzIHRvIHRyaW0gc3BhY2VzIHRoYXQgaGF2ZSBiZWVuIHByb3RlY3RlZCBieSBhIHNwZWNpYWwgZXNjYXBlIGNoYXJhY3Rlci5cbiAqXG4gKiBgYGBcbiAqIDxzY3JpcHQgdHlwZT1cIm1vZHVsZVwiPlxuICogaW1wb3J0IHt0cmltU3BhY2VzfSBmcm9tICdAc2NodWthaS9tb25zdGVyL3NvdXJjZS91dGlsL3RyaW1zcGFjZXMubWpzJztcbiAqIHRyaW1TcGFjZXMoJyBoZWxsbyBcXFxcICcpXG4gKiA8L3NjcmlwdD5cbiAqIGBgYFxuICpcbiAqIEhpbnQ6IE9uZSBzdHJva2UgaXMgZXNjYXBlZCBieSB0aGUgamF2YXNjcmlwdCBpbnRlcnByZXRlciwgdGhlIHNlY29uZCBzdHJva2UgZXNjYXBlcyB0aGUgc3Ryb2tlLlxuICpcbiAqIGBgYHRleHRcbiAqIGFcXCBiICBcdTIxQTYgYSBiXG4gKiBhXFxcXCBiIFx1MjFBNiBhXFwgYlxuICogYGBgXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNC4wXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5VdGlsXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlXG4gKiBAcmV0dXJuIHtzdHJpbmd9XG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIHN0cmluZ1xuICovXG5mdW5jdGlvbiB0cmltU3BhY2VzKHZhbHVlKSB7XG4gICAgdmFsaWRhdGVTdHJpbmcodmFsdWUpO1xuXG4gICAgbGV0IHBsYWNlaG9sZGVyID0gbmV3IE1hcCgpO1xuICAgIGNvbnN0IHJlZ2V4ID0gLygoPzxwYXR0ZXJuPlxcXFwoPzxjaGFyPi4pKXsxfSkvZ2ltO1xuXG4gICAgLy8gVGhlIHNlcGFyYXRvciBmb3IgYXJncyBtdXN0IGJlIGVzY2FwZWRcbiAgICAvLyB1bmRlZmluZWQgc3RyaW5nIHdoaWNoIHNob3VsZCBub3Qgb2NjdXIgbm9ybWFsbHkgYW5kIGlzIGFsc28gbm90IGEgcmVnZXhcbiAgICBsZXQgcmVzdWx0ID0gdmFsdWUubWF0Y2hBbGwocmVnZXgpO1xuXG4gICAgZm9yIChsZXQgbSBvZiByZXN1bHQpIHtcbiAgICAgICAgbGV0IGcgPSBtPy5bXCJncm91cHNcIl07XG4gICAgICAgIGlmICghaXNPYmplY3QoZykpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHAgPSBnPy5bXCJwYXR0ZXJuXCJdO1xuICAgICAgICBsZXQgYyA9IGc/LltcImNoYXJcIl07XG5cbiAgICAgICAgaWYgKHAgJiYgYykge1xuICAgICAgICAgICAgbGV0IHIgPSBgX18ke25ldyBJRCgpLnRvU3RyaW5nKCl9X19gO1xuICAgICAgICAgICAgcGxhY2Vob2xkZXIuc2V0KHIsIGMpO1xuICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKHAsIHIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdmFsdWUgPSB2YWx1ZS50cmltKCk7XG4gICAgcGxhY2Vob2xkZXIuZm9yRWFjaCgodiwgaykgPT4ge1xuICAgICAgICB2YWx1ZSA9IHZhbHVlLnJlcGxhY2UoaywgYFxcXFwke3Z9YCk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gdmFsdWU7XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBpc0FycmF5LCBpc09iamVjdCB9IGZyb20gXCIuLi90eXBlcy9pcy5tanNcIjtcbmltcG9ydCB7IHZhbGlkYXRlSW5zdGFuY2UsIHZhbGlkYXRlU3RyaW5nIH0gZnJvbSBcIi4uL3R5cGVzL3ZhbGlkYXRlLm1qc1wiO1xuaW1wb3J0IHsgZ2V0RG9jdW1lbnQgfSBmcm9tIFwiLi91dGlsLm1qc1wiO1xuXG5leHBvcnQgeyBmaXJlRXZlbnQsIGZpcmVDdXN0b21FdmVudCwgZmluZFRhcmdldEVsZW1lbnRGcm9tRXZlbnQgfTtcblxuLyoqXG4gKiBUaGUgZnVuY3Rpb24gc2VuZHMgYW4gZXZlbnRcbiAqXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fEhUTUxDb2xsZWN0aW9ufE5vZGVMaXN0fSBlbGVtZW50XG4gKiBAcGFyYW0ge3N0cmluZ30gdHlwZVxuICogQHJldHVybiB7dm9pZH1cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMTAuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgSFRNTEVsZW1lbnQgb3IgSFRNTENvbGxlY3Rpb25cbiAqIEBzdW1tYXJ5IENvbnN0cnVjdCBhbmQgc2VuZCBhbmQgZXZlbnRcbiAqL1xuZnVuY3Rpb24gZmlyZUV2ZW50KGVsZW1lbnQsIHR5cGUpIHtcbiAgICBjb25zdCBkb2N1bWVudCA9IGdldERvY3VtZW50KCk7XG5cbiAgICBpZiAoZWxlbWVudCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSB7XG4gICAgICAgIGlmICh0eXBlID09PSBcImNsaWNrXCIpIHtcbiAgICAgICAgICAgIGVsZW1lbnQuY2xpY2soKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FdmVudC9FdmVudFxuICAgICAgICBsZXQgZXZlbnQgPSBuZXcgRXZlbnQodmFsaWRhdGVTdHJpbmcodHlwZSksIHtcbiAgICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgICBjYW5jZWxhYmxlOiB0cnVlLFxuICAgICAgICAgICAgY29tcG9zZWQ6IHRydWUsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGVsZW1lbnQuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgfSBlbHNlIGlmIChlbGVtZW50IGluc3RhbmNlb2YgSFRNTENvbGxlY3Rpb24gfHwgZWxlbWVudCBpbnN0YW5jZW9mIE5vZGVMaXN0KSB7XG4gICAgICAgIGZvciAobGV0IGUgb2YgZWxlbWVudCkge1xuICAgICAgICAgICAgZmlyZUV2ZW50KGUsIHR5cGUpO1xuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInZhbHVlIGlzIG5vdCBhbiBpbnN0YW5jZSBvZiBIVE1MRWxlbWVudCBvciBIVE1MQ29sbGVjdGlvblwiKTtcbiAgICB9XG59XG5cbi8qKlxuICogWW91IGNhbiBjYWxsIHRoZSBmdW5jdGlvbiB2aWEgdGhlIG1vbnN0ZXIgbmFtZXNwYWNlIGBuZXcgTW9uc3Rlci5ET00uZmlyZUN1c3RvbUV2ZW50KClgLlxuICpcbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR8SFRNTENvbGxlY3Rpb258Tm9kZUxpc3R9IGVsZW1lbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlXG4gKiBAcmV0dXJuIHt2b2lkfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yOS4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhbiBpbnN0YW5jZSBvZiBIVE1MRWxlbWVudCBvciBIVE1MQ29sbGVjdGlvblxuICogQHN1bW1hcnkgQ29uc3RydWN0IGFuZCBzZW5kIGFuZCBldmVudFxuICovXG5mdW5jdGlvbiBmaXJlQ3VzdG9tRXZlbnQoZWxlbWVudCwgdHlwZSwgZGV0YWlsKSB7XG4gICAgY29uc3QgZG9jdW1lbnQgPSBnZXREb2N1bWVudCgpO1xuXG4gICAgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICBpZiAoIWlzT2JqZWN0KGRldGFpbCkpIHtcbiAgICAgICAgICAgIGRldGFpbCA9IHsgZGV0YWlsIH07XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgZXZlbnQgPSBuZXcgQ3VzdG9tRXZlbnQodmFsaWRhdGVTdHJpbmcodHlwZSksIHtcbiAgICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgICBjYW5jZWxhYmxlOiB0cnVlLFxuICAgICAgICAgICAgY29tcG9zZWQ6IHRydWUsXG4gICAgICAgICAgICBkZXRhaWwsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGVsZW1lbnQuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgfSBlbHNlIGlmIChlbGVtZW50IGluc3RhbmNlb2YgSFRNTENvbGxlY3Rpb24gfHwgZWxlbWVudCBpbnN0YW5jZW9mIE5vZGVMaXN0KSB7XG4gICAgICAgIGZvciAobGV0IGUgb2YgZWxlbWVudCkge1xuICAgICAgICAgICAgZmlyZUN1c3RvbUV2ZW50KGUsIHR5cGUsIGRldGFpbCk7XG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwidmFsdWUgaXMgbm90IGFuIGluc3RhbmNlIG9mIEhUTUxFbGVtZW50IG9yIEhUTUxDb2xsZWN0aW9uXCIpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGdldHMgdGhlIHBhdGggYEV2ZW50LmNvbXBvc2VkUGF0aCgpYCBmcm9tIGFuIGV2ZW50IGFuZCB0cmllcyB0byBmaW5kIHRoZSBuZXh0IGVsZW1lbnRcbiAqIHVwIHRoZSB0cmVlIGBlbGVtZW50LmNsb3Nlc3QoKWAgd2l0aCB0aGUgYXR0cmlidXRlIGFuZCB2YWx1ZS4gSWYgbm8gdmFsdWUsIG9yIGEgdmFsdWUgdGhhdCBpcyB1bmRlZmluZWQgb3IgbnVsbCxcbiAqIGlzIHNwZWNpZmllZCwgb25seSB0aGUgYXR0cmlidXRlIGlzIHNlYXJjaGVkLlxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMTQuMFxuICogQHBhcmFtIHtFdmVudH0gZXZlbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBhdHRyaWJ1dGVOYW1lXG4gKiBAcGFyYW0ge3N0cmluZ3xudWxsfHVuZGVmaW5lZH0gYXR0cmlidXRlVmFsdWVcbiAqIEB0aHJvd3Mge0Vycm9yfSB1bnN1cHBvcnRlZCBldmVudFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIHN0cmluZ1xuICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgSFRNTEVsZW1lbnRcbiAqIEBzdW1tYXJ5IEhlbHAgZnVuY3Rpb24gdG8gZmluZCB0aGUgYXBwcm9wcmlhdGUgY29udHJvbFxuICovXG5mdW5jdGlvbiBmaW5kVGFyZ2V0RWxlbWVudEZyb21FdmVudChldmVudCwgYXR0cmlidXRlTmFtZSwgYXR0cmlidXRlVmFsdWUpIHtcbiAgICB2YWxpZGF0ZUluc3RhbmNlKGV2ZW50LCBFdmVudCk7XG5cbiAgICBpZiAodHlwZW9mIGV2ZW50LmNvbXBvc2VkUGF0aCAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcInVuc3VwcG9ydGVkIGV2ZW50XCIpO1xuICAgIH1cblxuICAgIGNvbnN0IHBhdGggPSBldmVudC5jb21wb3NlZFBhdGgoKTtcblxuICAgIC8vIGNsb3Nlc3QgY2Fubm90IGJlIHVzZWQgaGVyZSwgYmVjYXVzZSBjbG9zZXN0IGlzIG5vdCBjb3JyZWN0IGZvciBzbG90dGVkIGVsZW1lbnRzXG4gICAgaWYgKGlzQXJyYXkocGF0aCkpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwYXRoLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBvID0gcGF0aFtpXTtcblxuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIG8gaW5zdGFuY2VvZiBIVE1MRWxlbWVudCAmJlxuICAgICAgICAgICAgICAgIG8uaGFzQXR0cmlidXRlKGF0dHJpYnV0ZU5hbWUpICYmXG4gICAgICAgICAgICAgICAgKGF0dHJpYnV0ZVZhbHVlID09PSB1bmRlZmluZWQgfHwgby5nZXRBdHRyaWJ1dGUoYXR0cmlidXRlTmFtZSkgPT09IGF0dHJpYnV0ZVZhbHVlKVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG87XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xufVxuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgQmFzZSB9IGZyb20gXCIuLi90eXBlcy9iYXNlLm1qc1wiO1xuaW1wb3J0IHsgZ2V0R2xvYmFsT2JqZWN0IH0gZnJvbSBcIi4uL3R5cGVzL2dsb2JhbC5tanNcIjtcbmltcG9ydCB7IHZhbGlkYXRlU3RyaW5nIH0gZnJvbSBcIi4uL3R5cGVzL3ZhbGlkYXRlLm1qc1wiO1xuaW1wb3J0IHsgQVRUUklCVVRFX1RIRU1FX05BTUUsIERFRkFVTFRfVEhFTUUgfSBmcm9tIFwiLi9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQgeyBpbnN0YW5jZVN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5leHBvcnQgeyBUaGVtZSwgZ2V0RG9jdW1lbnRUaGVtZSB9O1xuXG4vKipcbiAqIFRoZSBUaGVtZSBjbGFzcyBwcm92aWRlcyB0aGUgZnVuY3Rpb25hbGl0eSBmb3IgdGhlIHRoZW1lLlxuICpcbiAqIEBleHRlcm5hbEV4YW1wbGUgLi4vLi4vZXhhbXBsZS9kb20vdGhlbWUubWpzXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjcuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHN1bW1hcnkgQSB0aGVtZSBjbGFzc1xuICovXG5jbGFzcyBUaGVtZSBleHRlbmRzIEJhc2Uge1xuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIG5hbWVcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIHN0cmluZ1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKG5hbWUpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdmFsaWRhdGVTdHJpbmcobmFtZSk7XG4gICAgICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMi4xLjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci9kb20vdGhlbWVcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgICAqL1xuICAgIGdldE5hbWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm5hbWU7XG4gICAgfVxufVxuXG4vKipcbiAqIFRoZSB0aGVtaW5nIHVzZWQgaW4gdGhlIGRvY3VtZW50IGNhbiBiZSBkZWZpbmVkIHZpYSB0aGUgaHRtbC10YWcuXG4gKiBUaGUgdGhlbWluZyBpcyBzcGVjaWZpZWQgdmlhIHRoZSBhdHRyaWJ1dGUgYGRhdGEtbW9uc3Rlci10aGVtZS1uYW1lYC5cbiAqXG4gKiBBcyBuYW1lIGZvciBhIHRoZW1lIGFsbCBjaGFyYWN0ZXJzIGFyZSB2YWxpZCwgd2hpY2ggYXJlIGFsc28gYWxsb3dlZCBmb3IgYSBIVE1MRWxlbWVudC1JRC5cbiAqXG4gKiBgYGBcbiAqIDxodG1sIGRhdGEtbW9uc3Rlci10aGVtZS1uYW1lPVwibXktdGhlbWVcIj5cbiAqIGBgYFxuICpcbiAqIHRoZSBkZWZhdWx0IHRoZW1lIG5hbWUgaXMgYG1vbnN0ZXJgLlxuICpcbiAqIEByZXR1cm4ge1RoZW1lfVxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjcuMFxuICovXG5mdW5jdGlvbiBnZXREb2N1bWVudFRoZW1lKCkge1xuICAgIGxldCBkb2N1bWVudCA9IGdldEdsb2JhbE9iamVjdChcImRvY3VtZW50XCIpO1xuICAgIGxldCBuYW1lID0gREVGQVVMVF9USEVNRTtcblxuICAgIGxldCBlbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcImh0bWxcIik7XG4gICAgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICBsZXQgdGhlbWUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZShBVFRSSUJVVEVfVEhFTUVfTkFNRSk7XG4gICAgICAgIGlmICh0aGVtZSkge1xuICAgICAgICAgICAgbmFtZSA9IHRoZW1lO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBUaGVtZShuYW1lKTtcbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IEJhc2UgfSBmcm9tIFwiLi4vdHlwZXMvYmFzZS5tanNcIjtcbmltcG9ydCB7IGdldEdsb2JhbEZ1bmN0aW9uLCBnZXRHbG9iYWxPYmplY3QgfSBmcm9tIFwiLi4vdHlwZXMvZ2xvYmFsLm1qc1wiO1xuaW1wb3J0IHsgdmFsaWRhdGVJbnN0YW5jZSwgdmFsaWRhdGVTdHJpbmcgfSBmcm9tIFwiLi4vdHlwZXMvdmFsaWRhdGUubWpzXCI7XG5pbXBvcnQgeyBBVFRSSUJVVEVfVEVNUExBVEVfUFJFRklYIH0gZnJvbSBcIi4vY29uc3RhbnRzLm1qc1wiO1xuaW1wb3J0IHsgZ2V0RG9jdW1lbnRUaGVtZSB9IGZyb20gXCIuL3RoZW1lLm1qc1wiO1xuaW1wb3J0IHsgaW5zdGFuY2VTeW1ib2wgfSBmcm9tIFwiLi4vY29uc3RhbnRzLm1qc1wiO1xuZXhwb3J0IHsgVGVtcGxhdGUgfTtcblxuLyoqXG4gKiBUaGUgdGVtcGxhdGUgY2xhc3MgcHJvdmlkZXMgbWV0aG9kcyBmb3IgY3JlYXRpbmcgdGVtcGxhdGVzLlxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuNi4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAc3VtbWFyeSBBIHRlbXBsYXRlIGNsYXNzXG4gKi9cbmNsYXNzIFRlbXBsYXRlIGV4dGVuZHMgQmFzZSB7XG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0hUTUxUZW1wbGF0ZUVsZW1lbnR9IHRlbXBsYXRlXG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYW4gaW5zdGFuY2Ugb2ZcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIGZ1bmN0aW9uXG4gICAgICogQHRocm93cyB7RXJyb3J9IHRoZSBmdW5jdGlvbiBpcyBub3QgZGVmaW5lZFxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRlbXBsYXRlKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIGNvbnN0IEhUTUxUZW1wbGF0ZUVsZW1lbnQgPSBnZXRHbG9iYWxGdW5jdGlvbihcIkhUTUxUZW1wbGF0ZUVsZW1lbnRcIik7XG4gICAgICAgIHZhbGlkYXRlSW5zdGFuY2UodGVtcGxhdGUsIEhUTUxUZW1wbGF0ZUVsZW1lbnQpO1xuICAgICAgICB0aGlzLnRlbXBsYXRlID0gdGVtcGxhdGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMi4xLjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci9kb20vcmVzb3VyY2UvdGVtcGxhdGVcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7SFRNTFRlbXBsYXRlRWxlbWVudH1cbiAgICAgKi9cbiAgICBnZXRUZW1wbGF0ZUVsZW1lbnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRlbXBsYXRlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHJldHVybiB7RG9jdW1lbnRGcmFnbWVudH1cbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhbiBpbnN0YW5jZSBvZlxuICAgICAqL1xuICAgIGNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRlbXBsYXRlLmNvbnRlbnQuY2xvbmVOb2RlKHRydWUpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBUaGlzIG1ldGhvZCBsb2FkcyBhIHRlbXBsYXRlIHdpdGggdGhlIGdpdmVuIElEIGFuZCByZXR1cm5zIGl0LlxuICpcbiAqIFRvIGRvIHRoaXMsIGl0IGZpcnN0IHJlYWRzIHRoZSB0aGVtZSBvZiB0aGUgZG9jdW1lbnQgYW5kIGxvb2tzIGZvciB0aGUgYGRhdGEtbW9uc3Rlci10aGVtZS1uYW1lYCBhdHRyaWJ1dGUgaW4gdGhlIEhUTUwgdGFnLlxuICpcbiAqIGBgYFxuICogPGh0bWwgZGF0YS1tb25zdGVyLXRoZW1lLW5hbWU9XCJteS10aGVtZVwiPlxuICogYGBgXG4gKlxuICogSWYgbm8gdGhlbWUgd2FzIHNwZWNpZmllZCwgdGhlIGRlZmF1bHQgdGhlbWUgaXMgYG1vbnN0ZXJgLlxuICpcbiAqIE5vdyBpdCBpcyBsb29rZWQgaWYgdGhlcmUgaXMgYSB0ZW1wbGF0ZSB3aXRoIHRoZSBnaXZlbiBJRCBhbmQgdGhlbWUgYGlkLXRoZW1lYCBhbmQgaWYgeWVzIGl0IGlzIHJldHVybmVkLlxuICogSWYgdGhlcmUgaXMgbm8gdGVtcGxhdGUgYSBzZWFyY2ggZm9yIGEgdGVtcGxhdGUgd2l0aCB0aGUgZ2l2ZW4gSUQgYGlkYCBpcyBkb25lLiBJZiB0aGlzIGlzIGFsc28gbm90IGZvdW5kLCBhbiBlcnJvciBpcyB0aHJvd24uXG4gKlxuICogWW91IGNhbiBjYWxsIHRoZSBtZXRob2QgdmlhIHRoZSBtb25zdGVyIG5hbWVzcGFjZSBgTW9uc3Rlci5ET00uZmluZERvY3VtZW50VGVtcGxhdGUoKWAuXG4gKlxuICogYGBgXG4gKiA8c2NyaXB0IHR5cGU9XCJtb2R1bGVcIj5cbiAqIGltcG9ydCB7ZmluZFRlbXBsYXRlfSBmcm9tICdAc2NodWthaS9tb25zdGVyL3NvdXJjZS9kb20vdGVtcGxhdGUubWpzJztcbiAqIGZpbmREb2N1bWVudFRlbXBsYXRlKClcbiAqIDwvc2NyaXB0PlxuICogYGBgXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiBpbXBvcnQgeyBmaW5kRG9jdW1lbnRUZW1wbGF0ZSB9IGZyb20gXCJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL0BzY2h1a2FpL21vbnN0ZXJAbGF0ZXN0L3NvdXJjZS9kb20vdGVtcGxhdGUubWpzXCI7XG4gKlxuICogY29uc3QgdGVtcGxhdGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwidGVtcGxhdGVcIik7XG4gKiB0ZW1wbGF0ZS5pZCA9IFwibXlUZW1wbGF0ZVwiO1xuICogdGVtcGxhdGUuaW5uZXJIVE1MID0gXCI8cD5teSBkZWZhdWx0IHRlbXBsYXRlPC9wPlwiO1xuICogZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCh0ZW1wbGF0ZSk7XG4gKlxuICogY29uc3QgdGhlbWVkVGVtcGxhdGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwidGVtcGxhdGVcIik7XG4gKiB0aGVtZWRUZW1wbGF0ZS5pZCA9IFwibXlUZW1wbGF0ZS1teVRoZW1lXCI7XG4gKiB0aGVtZWRUZW1wbGF0ZS5pbm5lckhUTUwgPSBcIjxwPm15IHRoZW1lZCB0ZW1wbGF0ZTwvcD5cIjtcbiAqIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodGhlbWVkVGVtcGxhdGUpO1xuICpcbiAqIC8vIGxvYWRzIHRoZSB0ZW1wbGUgYW5kIHNpbmNlIG5vIHRoZW1lIGlzIHNldCB0aGUgZGVmYXVsdCB0ZW1wbGF0ZVxuICogY29uc3QgdGVtcGxhdGUxID0gZmluZERvY3VtZW50VGVtcGxhdGUoXCJteVRlbXBsYXRlXCIpO1xuICogY29uc29sZS5sb2codGVtcGxhdGUxLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKSk7XG4gKiAvLyBcdTIxQTYgJzxwPm15IGRlZmF1bHQgdGVtcGxhdGU8L3A+J1xuICpcbiAqIC8vIG5vdyB3ZSBzZXQgb3VyIG93biB0aGVtZVxuICogZG9jdW1lbnRcbiAqIC5xdWVyeVNlbGVjdG9yKFwiaHRtbFwiKVxuICogLnNldEF0dHJpYnV0ZShcImRhdGEtbW9uc3Rlci10aGVtZS1uYW1lXCIsIFwibXlUaGVtZVwiKTtcbiAqXG4gKiAvLyBub3cgd2UgZG9uJ3QgZ2V0IHRoZSBkZWZhdWx0IHRlbXBsYXRlLFxuICogLy8gYnV0IHRoZSB0ZW1wbGF0ZSB3aXRoIHRoZSB0aGVtZSBpbiB0aGUgaWRcbiAqIGNvbnN0IHRlbXBsYXRlMiA9IGZpbmREb2N1bWVudFRlbXBsYXRlKFwibXlUZW1wbGF0ZVwiKTtcbiAqIGNvbnNvbGUubG9nKHRlbXBsYXRlMi5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCkpO1xuICogLy8gXHUyMUE2ICc8cD5teSB0aGVtZWQgdGVtcGxhdGU8L3A+J1xuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBpZFxuICogQHBhcmFtIHtOb2RlfSBjdXJyZW50Tm9kZVxuICogQHJldHVybiB7TW9uc3Rlci5ET00uVGVtcGxhdGV9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjcuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHRocm93cyB7RXJyb3J9IHRlbXBsYXRlIGlkIG5vdCBmb3VuZC5cbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgc3RyaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaW5kRG9jdW1lbnRUZW1wbGF0ZShpZCwgY3VycmVudE5vZGUpIHtcbiAgICB2YWxpZGF0ZVN0cmluZyhpZCk7XG5cbiAgICBjb25zdCBkb2N1bWVudCA9IGdldEdsb2JhbE9iamVjdChcImRvY3VtZW50XCIpO1xuICAgIGNvbnN0IEhUTUxUZW1wbGF0ZUVsZW1lbnQgPSBnZXRHbG9iYWxGdW5jdGlvbihcIkhUTUxUZW1wbGF0ZUVsZW1lbnRcIik7XG4gICAgY29uc3QgRG9jdW1lbnRGcmFnbWVudCA9IGdldEdsb2JhbEZ1bmN0aW9uKFwiRG9jdW1lbnRGcmFnbWVudFwiKTtcbiAgICBjb25zdCBEb2N1bWVudCA9IGdldEdsb2JhbEZ1bmN0aW9uKFwiRG9jdW1lbnRcIik7XG5cbiAgICBsZXQgcHJlZml4SUQ7XG5cbiAgICBpZiAoIShjdXJyZW50Tm9kZSBpbnN0YW5jZW9mIERvY3VtZW50IHx8IGN1cnJlbnROb2RlIGluc3RhbmNlb2YgRG9jdW1lbnRGcmFnbWVudCkpIHtcbiAgICAgICAgaWYgKGN1cnJlbnROb2RlIGluc3RhbmNlb2YgTm9kZSkge1xuICAgICAgICAgICAgaWYgKGN1cnJlbnROb2RlLmhhc0F0dHJpYnV0ZShBVFRSSUJVVEVfVEVNUExBVEVfUFJFRklYKSkge1xuICAgICAgICAgICAgICAgIHByZWZpeElEID0gY3VycmVudE5vZGUuZ2V0QXR0cmlidXRlKEFUVFJJQlVURV9URU1QTEFURV9QUkVGSVgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjdXJyZW50Tm9kZSA9IGN1cnJlbnROb2RlLmdldFJvb3ROb2RlKCk7XG5cbiAgICAgICAgICAgIGlmICghKGN1cnJlbnROb2RlIGluc3RhbmNlb2YgRG9jdW1lbnQgfHwgY3VycmVudE5vZGUgaW5zdGFuY2VvZiBEb2N1bWVudEZyYWdtZW50KSkge1xuICAgICAgICAgICAgICAgIGN1cnJlbnROb2RlID0gY3VycmVudE5vZGUub3duZXJEb2N1bWVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghKGN1cnJlbnROb2RlIGluc3RhbmNlb2YgRG9jdW1lbnQgfHwgY3VycmVudE5vZGUgaW5zdGFuY2VvZiBEb2N1bWVudEZyYWdtZW50KSkge1xuICAgICAgICAgICAgY3VycmVudE5vZGUgPSBkb2N1bWVudDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGxldCB0ZW1wbGF0ZTtcbiAgICBsZXQgdGhlbWUgPSBnZXREb2N1bWVudFRoZW1lKCk7XG5cbiAgICBpZiAocHJlZml4SUQpIHtcbiAgICAgICAgbGV0IHRoZW1lZFByZWZpeElEID0gYCR7cHJlZml4SUR9LSR7aWR9LSR7dGhlbWUuZ2V0TmFtZSgpfWA7XG5cbiAgICAgICAgLy8gY3VycmVudCArIHRoZW1lZFByZWZpeElEXG4gICAgICAgIHRlbXBsYXRlID0gY3VycmVudE5vZGUuZ2V0RWxlbWVudEJ5SWQodGhlbWVkUHJlZml4SUQpO1xuICAgICAgICBpZiAodGVtcGxhdGUgaW5zdGFuY2VvZiBIVE1MVGVtcGxhdGVFbGVtZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFRlbXBsYXRlKHRlbXBsYXRlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGRvY3VtZW50ICsgdGhlbWVkUHJlZml4SURcbiAgICAgICAgdGVtcGxhdGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGVtZWRQcmVmaXhJRCk7XG4gICAgICAgIGlmICh0ZW1wbGF0ZSBpbnN0YW5jZW9mIEhUTUxUZW1wbGF0ZUVsZW1lbnQpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgVGVtcGxhdGUodGVtcGxhdGUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbGV0IHRoZW1lZElEID0gYCR7aWR9LSR7dGhlbWUuZ2V0TmFtZSgpfWA7XG5cbiAgICAvLyBjdXJyZW50ICsgdGhlbWVkSURcbiAgICB0ZW1wbGF0ZSA9IGN1cnJlbnROb2RlLmdldEVsZW1lbnRCeUlkKHRoZW1lZElEKTtcbiAgICBpZiAodGVtcGxhdGUgaW5zdGFuY2VvZiBIVE1MVGVtcGxhdGVFbGVtZW50KSB7XG4gICAgICAgIHJldHVybiBuZXcgVGVtcGxhdGUodGVtcGxhdGUpO1xuICAgIH1cblxuICAgIC8vIGRvY3VtZW50ICsgdGhlbWVkSURcbiAgICB0ZW1wbGF0ZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRoZW1lZElEKTtcbiAgICBpZiAodGVtcGxhdGUgaW5zdGFuY2VvZiBIVE1MVGVtcGxhdGVFbGVtZW50KSB7XG4gICAgICAgIHJldHVybiBuZXcgVGVtcGxhdGUodGVtcGxhdGUpO1xuICAgIH1cblxuICAgIC8vIGN1cnJlbnQgKyBJRFxuICAgIHRlbXBsYXRlID0gY3VycmVudE5vZGUuZ2V0RWxlbWVudEJ5SWQoaWQpO1xuICAgIGlmICh0ZW1wbGF0ZSBpbnN0YW5jZW9mIEhUTUxUZW1wbGF0ZUVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUZW1wbGF0ZSh0ZW1wbGF0ZSk7XG4gICAgfVxuXG4gICAgLy8gZG9jdW1lbnQgKyBJRFxuICAgIHRlbXBsYXRlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpO1xuICAgIGlmICh0ZW1wbGF0ZSBpbnN0YW5jZW9mIEhUTUxUZW1wbGF0ZUVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUZW1wbGF0ZSh0ZW1wbGF0ZSk7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IEVycm9yKGB0ZW1wbGF0ZSAke2lkfSBub3QgZm91bmQuYCk7XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBpbnRlcm5hbFN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQgeyBkaWZmIH0gZnJvbSBcIi4uL2RhdGEvZGlmZi5tanNcIjtcbmltcG9ydCB7IFBhdGhmaW5kZXIgfSBmcm9tIFwiLi4vZGF0YS9wYXRoZmluZGVyLm1qc1wiO1xuaW1wb3J0IHsgUGlwZSB9IGZyb20gXCIuLi9kYXRhL3BpcGUubWpzXCI7XG5pbXBvcnQge1xuICAgIEFUVFJJQlVURV9FUlJPUk1FU1NBR0UsXG4gICAgQVRUUklCVVRFX1VQREFURVJfQVRUUklCVVRFUyxcbiAgICBBVFRSSUJVVEVfVVBEQVRFUl9CSU5ELFxuICAgIEFUVFJJQlVURV9VUERBVEVSX0lOU0VSVCxcbiAgICBBVFRSSUJVVEVfVVBEQVRFUl9JTlNFUlRfUkVGRVJFTkNFLFxuICAgIEFUVFJJQlVURV9VUERBVEVSX1JFTU9WRSxcbiAgICBBVFRSSUJVVEVfVVBEQVRFUl9SRVBMQUNFLFxuICAgIEFUVFJJQlVURV9VUERBVEVSX1NFTEVDVF9USElTLFxufSBmcm9tIFwiLi4vZG9tL2NvbnN0YW50cy5tanNcIjtcblxuaW1wb3J0IHsgQmFzZSB9IGZyb20gXCIuLi90eXBlcy9iYXNlLm1qc1wiO1xuaW1wb3J0IHsgaXNBcnJheSwgaXNJbnN0YW5jZSwgaXNJdGVyYWJsZSB9IGZyb20gXCIuLi90eXBlcy9pcy5tanNcIjtcbmltcG9ydCB7IE9ic2VydmVyIH0gZnJvbSBcIi4uL3R5cGVzL29ic2VydmVyLm1qc1wiO1xuaW1wb3J0IHsgUHJveHlPYnNlcnZlciB9IGZyb20gXCIuLi90eXBlcy9wcm94eW9ic2VydmVyLm1qc1wiO1xuaW1wb3J0IHsgdmFsaWRhdGVBcnJheSwgdmFsaWRhdGVJbnN0YW5jZSB9IGZyb20gXCIuLi90eXBlcy92YWxpZGF0ZS5tanNcIjtcbmltcG9ydCB7IGNsb25lIH0gZnJvbSBcIi4uL3V0aWwvY2xvbmUubWpzXCI7XG5pbXBvcnQgeyB0cmltU3BhY2VzIH0gZnJvbSBcIi4uL3V0aWwvdHJpbXNwYWNlcy5tanNcIjtcbmltcG9ydCB7IGFkZFRvT2JqZWN0TGluayB9IGZyb20gXCIuL2F0dHJpYnV0ZXMubWpzXCI7XG5pbXBvcnQgeyBmaW5kVGFyZ2V0RWxlbWVudEZyb21FdmVudCB9IGZyb20gXCIuL2V2ZW50cy5tanNcIjtcbmltcG9ydCB7IGZpbmREb2N1bWVudFRlbXBsYXRlIH0gZnJvbSBcIi4vdGVtcGxhdGUubWpzXCI7XG5cbmV4cG9ydCB7IFVwZGF0ZXIsIGFkZE9iamVjdFdpdGhVcGRhdGVyVG9FbGVtZW50IH07XG5cbi8qKlxuICogVGhlIHVwZGF0ZXIgY2xhc3MgY29ubmVjdHMgYW4gb2JqZWN0IHdpdGggdGhlIGRvbS4gSW4gdGhpcyB3YXksIHN0cnVjdHVyZXMgYW5kIGNvbnRlbnRzIGluIHRoZSBET00gY2FuIGJlIHByb2dyYW1tYXRpY2FsbHkgYWRhcHRlZCB2aWEgYXR0cmlidXRlcy5cbiAqXG4gKiBGb3IgZXhhbXBsZSwgdG8gaW5jbHVkZSBhIHN0cmluZyBmcm9tIGFuIG9iamVjdCwgdGhlIGF0dHJpYnV0ZSBgZGF0YS1tb25zdGVyLXJlcGxhY2VgIGNhbiBiZSB1c2VkLlxuICogYSBmdXJ0aGVyIGV4cGxhbmF0aW9uIGNhbiBiZSBmb3VuZCB1bmRlciB7QHR1dG9yaWFsIGRvbS1iYXNlZC10ZW1wbGF0aW5nLWltcGxlbWVudGF0aW9ufS5cbiAqXG4gKiBDaGFuZ2VzIHRvIGF0dHJpYnV0ZXMgYXJlIG1hZGUgb25seSB3aGVuIHRoZSBkaXJlY3QgdmFsdWVzIGFyZSBjaGFuZ2VkLiBJZiB5b3Ugd2FudCB0byBhc3NpZ24gY2hhbmdlcyB0byBvdGhlciB2YWx1ZXNcbiAqIGFzIHdlbGwsIHlvdSBoYXZlIHRvIGluc2VydCB0aGUgYXR0cmlidXRlIGBkYXRhLW1vbnN0ZXItc2VsZWN0LXRoaXNgLiBUaGlzIHNob3VsZCBiZSBkb25lIHdpdGggY2FyZSwgYXMgaXQgY2FuIHJlZHVjZSBwZXJmb3JtYW5jZS5cbiAqXG4gKiBAZXh0ZXJuYWxFeGFtcGxlIC4uLy4uL2V4YW1wbGUvZG9tL3VwZGF0ZXIubWpzXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjguMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHRocm93cyB7RXJyb3J9IHRoZSB2YWx1ZSBpcyBub3QgaXRlcmFibGVcbiAqIEB0aHJvd3Mge0Vycm9yfSBwaXBlcyBhcmUgbm90IGFsbG93ZWQgd2hlbiBjbG9uaW5nIGEgbm9kZS5cbiAqIEB0aHJvd3Mge0Vycm9yfSBubyB0ZW1wbGF0ZSB3YXMgZm91bmQgd2l0aCB0aGUgc3BlY2lmaWVkIGtleS5cbiAqIEB0aHJvd3Mge0Vycm9yfSB0aGUgbWF4aW11bSBkZXB0aCBmb3IgdGhlIHJlY3Vyc2lvbiBpcyByZWFjaGVkLlxuICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYSBvYmplY3RcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGFuIGluc3RhbmNlIG9mIEhUTUxFbGVtZW50XG4gKiBAc3VtbWFyeSBUaGUgdXBkYXRlciBjbGFzcyBjb25uZWN0cyBhbiBvYmplY3Qgd2l0aCB0aGUgZG9tXG4gKi9cbmNsYXNzIFVwZGF0ZXIgZXh0ZW5kcyBCYXNlIHtcbiAgICAvKipcbiAgICAgKiBAc2luY2UgMS44LjBcbiAgICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gICAgICogQHBhcmFtIHtvYmplY3R8UHJveHlPYnNlcnZlcnx1bmRlZmluZWR9IHN1YmplY3RcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIG9iamVjdFxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGFuIGluc3RhbmNlIG9mIEhUTUxFbGVtZW50XG4gICAgICogQHNlZSB7QGxpbmsgTW9uc3Rlci5ET00uZmluZERvY3VtZW50VGVtcGxhdGV9XG4gICAgICovXG4gICAgY29uc3RydWN0b3IoZWxlbWVudCwgc3ViamVjdCkge1xuICAgICAgICBzdXBlcigpO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAdHlwZSB7SFRNTEVsZW1lbnR9XG4gICAgICAgICAqL1xuICAgICAgICBpZiAoc3ViamVjdCA9PT0gdW5kZWZpbmVkKSBzdWJqZWN0ID0ge307XG4gICAgICAgIGlmICghaXNJbnN0YW5jZShzdWJqZWN0LCBQcm94eU9ic2VydmVyKSkge1xuICAgICAgICAgICAgc3ViamVjdCA9IG5ldyBQcm94eU9ic2VydmVyKHN1YmplY3QpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpc1tpbnRlcm5hbFN5bWJvbF0gPSB7XG4gICAgICAgICAgICBlbGVtZW50OiB2YWxpZGF0ZUluc3RhbmNlKGVsZW1lbnQsIEhUTUxFbGVtZW50KSxcbiAgICAgICAgICAgIGxhc3Q6IHt9LFxuICAgICAgICAgICAgY2FsbGJhY2tzOiBuZXcgTWFwKCksXG4gICAgICAgICAgICBldmVudFR5cGVzOiBbXCJrZXl1cFwiLCBcImNsaWNrXCIsIFwiY2hhbmdlXCIsIFwiZHJvcFwiLCBcInRvdWNoZW5kXCIsIFwiaW5wdXRcIl0sXG4gICAgICAgICAgICBzdWJqZWN0OiBzdWJqZWN0LFxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXNbaW50ZXJuYWxTeW1ib2xdLmNhbGxiYWNrcy5zZXQoXCJjaGVja3N0YXRlXCIsIGdldENoZWNrU3RhdGVDYWxsYmFjay5jYWxsKHRoaXMpKTtcblxuICAgICAgICB0aGlzW2ludGVybmFsU3ltYm9sXS5zdWJqZWN0LmF0dGFjaE9ic2VydmVyKFxuICAgICAgICAgICAgbmV3IE9ic2VydmVyKCgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBzID0gdGhpc1tpbnRlcm5hbFN5bWJvbF0uc3ViamVjdC5nZXRSZWFsU3ViamVjdCgpO1xuXG4gICAgICAgICAgICAgICAgY29uc3QgZGlmZlJlc3VsdCA9IGRpZmYodGhpc1tpbnRlcm5hbFN5bWJvbF0ubGFzdCwgcyk7XG4gICAgICAgICAgICAgICAgdGhpc1tpbnRlcm5hbFN5bWJvbF0ubGFzdCA9IGNsb25lKHMpO1xuXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBbLCBjaGFuZ2VdIG9mIE9iamVjdC5lbnRyaWVzKGRpZmZSZXN1bHQpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlbW92ZUVsZW1lbnQuY2FsbCh0aGlzLCBjaGFuZ2UpO1xuICAgICAgICAgICAgICAgICAgICBpbnNlcnRFbGVtZW50LmNhbGwodGhpcywgY2hhbmdlKTtcbiAgICAgICAgICAgICAgICAgICAgdXBkYXRlQ29udGVudC5jYWxsKHRoaXMsIGNoYW5nZSk7XG4gICAgICAgICAgICAgICAgICAgIHVwZGF0ZUF0dHJpYnV0ZXMuY2FsbCh0aGlzLCBjaGFuZ2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERlZmF1bHRzOiAna2V5dXAnLCAnY2xpY2snLCAnY2hhbmdlJywgJ2Ryb3AnLCAndG91Y2hlbmQnXG4gICAgICpcbiAgICAgKiBAc2VlIHtAbGluayBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9kZS9kb2NzL1dlYi9FdmVudHN9XG4gICAgICogQHNpbmNlIDEuOS4wXG4gICAgICogQHBhcmFtIHtBcnJheX0gdHlwZXNcbiAgICAgKiBAcmV0dXJuIHtVcGRhdGVyfVxuICAgICAqL1xuICAgIHNldEV2ZW50VHlwZXModHlwZXMpIHtcbiAgICAgICAgdGhpc1tpbnRlcm5hbFN5bWJvbF0uZXZlbnRUeXBlcyA9IHZhbGlkYXRlQXJyYXkodHlwZXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBXaXRoIHRoaXMgbWV0aG9kLCB0aGUgZXZlbnRsaXN0ZW5lcnMgYXJlIGhvb2tlZCBpbiBhbmQgdGhlIG1hZ2ljIGJlZ2lucy5cbiAgICAgKlxuICAgICAqIGBgYFxuICAgICAqIHVwZGF0ZXIucnVuKCkudGhlbigoKSA9PiB7XG4gICAgICogICB1cGRhdGVyLmVuYWJsZUV2ZW50UHJvY2Vzc2luZygpO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQHNpbmNlIDEuOS4wXG4gICAgICogQHJldHVybiB7VXBkYXRlcn1cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gdGhlIGJpbmQgYXJndW1lbnQgbXVzdCBzdGFydCBhcyBhIHZhbHVlIHdpdGggYSBwYXRoXG4gICAgICovXG4gICAgZW5hYmxlRXZlbnRQcm9jZXNzaW5nKCkge1xuICAgICAgICB0aGlzLmRpc2FibGVFdmVudFByb2Nlc3NpbmcoKTtcblxuICAgICAgICBmb3IgKGNvbnN0IHR5cGUgb2YgdGhpc1tpbnRlcm5hbFN5bWJvbF0uZXZlbnRUeXBlcykge1xuICAgICAgICAgICAgLy8gQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRXZlbnRUYXJnZXQvYWRkRXZlbnRMaXN0ZW5lclxuICAgICAgICAgICAgdGhpc1tpbnRlcm5hbFN5bWJvbF0uZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKHR5cGUsIGdldENvbnRyb2xFdmVudEhhbmRsZXIuY2FsbCh0aGlzKSwge1xuICAgICAgICAgICAgICAgIGNhcHR1cmU6IHRydWUsXG4gICAgICAgICAgICAgICAgcGFzc2l2ZTogdHJ1ZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgdHVybnMgb2ZmIHRoZSBtYWdpYyBvciB3aG8gbG92ZXMgaXQgbW9yZSBwcm9mYW5lIGl0IHJlbW92ZXMgdGhlIGV2ZW50TGlzdGVuZXIuXG4gICAgICpcbiAgICAgKiBAc2luY2UgMS45LjBcbiAgICAgKiBAcmV0dXJuIHtVcGRhdGVyfVxuICAgICAqL1xuICAgIGRpc2FibGVFdmVudFByb2Nlc3NpbmcoKSB7XG4gICAgICAgIGZvciAoY29uc3QgdHlwZSBvZiB0aGlzW2ludGVybmFsU3ltYm9sXS5ldmVudFR5cGVzKSB7XG4gICAgICAgICAgICB0aGlzW2ludGVybmFsU3ltYm9sXS5lbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIodHlwZSwgZ2V0Q29udHJvbEV2ZW50SGFuZGxlci5jYWxsKHRoaXMpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBydW4gbWV0aG9kIG11c3QgYmUgY2FsbGVkIGZvciB0aGUgdXBkYXRlIHRvIHN0YXJ0IHdvcmtpbmcuXG4gICAgICogVGhlIG1ldGhvZCBlbnN1cmVzIHRoYXQgY2hhbmdlcyBhcmUgZGV0ZWN0ZWQuXG4gICAgICpcbiAgICAgKiBgYGBcbiAgICAgKiB1cGRhdGVyLnJ1bigpLnRoZW4oKCkgPT4ge1xuICAgICAqICAgdXBkYXRlci5lbmFibGVFdmVudFByb2Nlc3NpbmcoKTtcbiAgICAgKiB9KTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEBzdW1tYXJ5IExldCB0aGUgbWFnaWMgYmVnaW5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgICAqL1xuICAgIHJ1bigpIHtcbiAgICAgICAgLy8gdGhlIGtleSBfX2luaXRfX2hhcyBubyBmdXJ0aGVyIG1lYW5pbmcgYW5kIGlzIG9ubHlcbiAgICAgICAgLy8gdXNlZCB0byBjcmVhdGUgdGhlIGRpZmYgZm9yIGVtcHR5IG9iamVjdHMuXG4gICAgICAgIHRoaXNbaW50ZXJuYWxTeW1ib2xdLmxhc3QgPSB7IF9faW5pdF9fOiB0cnVlIH07XG4gICAgICAgIHJldHVybiB0aGlzW2ludGVybmFsU3ltYm9sXS5zdWJqZWN0Lm5vdGlmeU9ic2VydmVycygpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIHZhbHVlcyBvZiBib3VuZCBlbGVtZW50cyBhbmQgY2hhbmdlcyB0aGVtIGluIHN1YmplY3RcbiAgICAgKlxuICAgICAqIEBzaW5jZSAxLjI3LjBcbiAgICAgKiBAcmV0dXJuIHtNb25zdGVyLkRPTS5VcGRhdGVyfVxuICAgICAqL1xuICAgIHJldHJpZXZlKCkge1xuICAgICAgICByZXRyaWV2ZUZyb21CaW5kaW5ncy5jYWxsKHRoaXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJZiB5b3UgaGF2ZSBwYXNzZWQgYSBQcm94eU9ic2VydmVyIGluIHRoZSBjb25zdHJ1Y3RvciwgeW91IHdpbGwgZ2V0IHRoZSBvYmplY3QgdGhhdCB0aGUgUHJveHlPYnNlcnZlciBtYW5hZ2VzIGhlcmUuXG4gICAgICogSG93ZXZlciwgaWYgeW91IHBhc3NlZCBhIHNpbXBsZSBvYmplY3QsIGhlcmUgeW91IHdpbGwgZ2V0IGEgcHJveHkgZm9yIHRoYXQgb2JqZWN0LlxuICAgICAqXG4gICAgICogRm9yIGNoYW5nZXMgdGhlIFByb3h5T2JzZXJ2ZXIgbXVzdCBiZSB1c2VkLlxuICAgICAqXG4gICAgICogQHNpbmNlIDEuOC4wXG4gICAgICogQHJldHVybiB7UHJveHl9XG4gICAgICovXG4gICAgZ2V0U3ViamVjdCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbaW50ZXJuYWxTeW1ib2xdLnN1YmplY3QuZ2V0U3ViamVjdCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGNhbiBiZSB1c2VkIHRvIHJlZ2lzdGVyIGNvbW1hbmRzIHRoYXQgY2FuIGJlIGNhbGxlZCB2aWEgY2FsbDogaW5zdHJ1Y3Rpb24uXG4gICAgICogVGhpcyBjYW4gYmUgdXNlZCB0byBwcm92aWRlIGEgcGlwZSB3aXRoIGl0cyBvd24gZnVuY3Rpb25hbGl0eS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2tcbiAgICAgKiBAcmV0dXJucyB7VHJhbnNmb3JtZXJ9XG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYSBzdHJpbmdcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIGZ1bmN0aW9uXG4gICAgICovXG4gICAgc2V0Q2FsbGJhY2sobmFtZSwgY2FsbGJhY2spIHtcbiAgICAgICAgdGhpc1tpbnRlcm5hbFN5bWJvbF0uY2FsbGJhY2tzLnNldChuYW1lLCBjYWxsYmFjayk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS45LjBcbiAqIEByZXR1cm4ge2Z1bmN0aW9uXG4gKiBAdGhpcyBVcGRhdGVyXG4gKi9cbmZ1bmN0aW9uIGdldENoZWNrU3RhdGVDYWxsYmFjaygpIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgIHJldHVybiBmdW5jdGlvbiAoY3VycmVudCkge1xuICAgICAgICAvLyB0aGlzIGlzIGEgcmVmZXJlbmNlIHRvIHRoZSBjdXJyZW50IG9iamVjdCAodGhlcmVmb3JlIG5vIGFycmF5IGZ1bmN0aW9uIGhlcmUpXG4gICAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCkge1xuICAgICAgICAgICAgaWYgKFtcInJhZGlvXCIsIFwiY2hlY2tib3hcIl0uaW5kZXhPZih0aGlzLnR5cGUpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBgJHt0aGlzLnZhbHVlfWAgPT09IGAke2N1cnJlbnR9YCA/IFwidHJ1ZVwiIDogdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMgaW5zdGFuY2VvZiBIVE1MT3B0aW9uRWxlbWVudCkge1xuICAgICAgICAgICAgaWYgKGlzQXJyYXkoY3VycmVudCkgJiYgY3VycmVudC5pbmRleE9mKHRoaXMudmFsdWUpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBcInRydWVcIjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgIH07XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuY29uc3Qgc3ltYm9sID0gU3ltYm9sKFwiQHNjaHVrYWkvbW9uc3Rlci91cGRhdGVyQEBFdmVudEhhbmRsZXJcIik7XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEByZXR1cm4ge2Z1bmN0aW9ufVxuICogQHRoaXMgVXBkYXRlclxuICogQHRocm93cyB7RXJyb3J9IHRoZSBiaW5kIGFyZ3VtZW50IG11c3Qgc3RhcnQgYXMgYSB2YWx1ZSB3aXRoIGEgcGF0aFxuICovXG5mdW5jdGlvbiBnZXRDb250cm9sRXZlbnRIYW5kbGVyKCkge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgaWYgKHNlbGZbc3ltYm9sXSkge1xuICAgICAgICByZXR1cm4gc2VsZltzeW1ib2xdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSB0aGUgYmluZCBhcmd1bWVudCBtdXN0IHN0YXJ0IGFzIGEgdmFsdWUgd2l0aCBhIHBhdGguXG4gICAgICogQHRocm93cyB7RXJyb3J9IHVuc3VwcG9ydGVkIG9iamVjdFxuICAgICAqIEBwYXJhbSB7RXZlbnR9IGV2ZW50XG4gICAgICovXG4gICAgc2VsZltzeW1ib2xdID0gKGV2ZW50KSA9PiB7XG4gICAgICAgIGNvbnN0IGVsZW1lbnQgPSBmaW5kVGFyZ2V0RWxlbWVudEZyb21FdmVudChldmVudCwgQVRUUklCVVRFX1VQREFURVJfQklORCk7XG5cbiAgICAgICAgaWYgKGVsZW1lbnQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0cmlldmVBbmRTZXRWYWx1ZS5jYWxsKHNlbGYsIGVsZW1lbnQpO1xuICAgIH07XG5cbiAgICByZXR1cm4gc2VsZltzeW1ib2xdO1xufVxuXG4vKipcbiAqIEB0aHJvd3Mge0Vycm9yfSB0aGUgYmluZCBhcmd1bWVudCBtdXN0IHN0YXJ0IGFzIGEgdmFsdWUgd2l0aCBhIHBhdGhcbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVsZW1lbnRcbiAqIEByZXR1cm4gdm9pZFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiByZXRyaWV2ZUFuZFNldFZhbHVlKGVsZW1lbnQpIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgIGNvbnN0IHBhdGhmaW5kZXIgPSBuZXcgUGF0aGZpbmRlcihzZWxmW2ludGVybmFsU3ltYm9sXS5zdWJqZWN0LmdldFN1YmplY3QoKSk7XG5cbiAgICBsZXQgcGF0aCA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKEFUVFJJQlVURV9VUERBVEVSX0JJTkQpO1xuICAgIGlmIChwYXRoID09PSBudWxsKSB0aHJvdyBuZXcgRXJyb3IoXCJ0aGUgYmluZCBhcmd1bWVudCBtdXN0IHN0YXJ0IGFzIGEgdmFsdWUgd2l0aCBhIHBhdGhcIik7XG5cbiAgICBpZiAocGF0aC5pbmRleE9mKFwicGF0aDpcIikgIT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidGhlIGJpbmQgYXJndW1lbnQgbXVzdCBzdGFydCBhcyBhIHZhbHVlIHdpdGggYSBwYXRoXCIpO1xuICAgIH1cblxuICAgIHBhdGggPSBwYXRoLnN1YnN0cmluZyg1KTtcblxuICAgIGxldCB2YWx1ZTtcblxuICAgIGlmIChlbGVtZW50IGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCkge1xuICAgICAgICBzd2l0Y2ggKGVsZW1lbnQudHlwZSkge1xuICAgICAgICAgICAgY2FzZSBcImNoZWNrYm94XCI6XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBlbGVtZW50LmNoZWNrZWQgPyBlbGVtZW50LnZhbHVlIDogdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IGVsZW1lbnQudmFsdWU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MVGV4dEFyZWFFbGVtZW50KSB7XG4gICAgICAgIHZhbHVlID0gZWxlbWVudC52YWx1ZTtcbiAgICB9IGVsc2UgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MU2VsZWN0RWxlbWVudCkge1xuICAgICAgICBzd2l0Y2ggKGVsZW1lbnQudHlwZSkge1xuICAgICAgICAgICAgY2FzZSBcInNlbGVjdC1vbmVcIjpcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IGVsZW1lbnQudmFsdWU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwic2VsZWN0LW11bHRpcGxlXCI6XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBlbGVtZW50LnZhbHVlO1xuXG4gICAgICAgICAgICAgICAgbGV0IG9wdGlvbnMgPSBlbGVtZW50Py5zZWxlY3RlZE9wdGlvbnM7XG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMgPT09IHVuZGVmaW5lZCkgb3B0aW9ucyA9IGVsZW1lbnQucXVlcnlTZWxlY3RvckFsbChcIjpzY29wZSBvcHRpb246Y2hlY2tlZFwiKTtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IEFycmF5LmZyb20ob3B0aW9ucykubWFwKCh7IHZhbHVlIH0pID0+IHZhbHVlKTtcblxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gdmFsdWVzIGZyb20gY3VzdG9tZWxlbWVudHNcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgICAoZWxlbWVudD8uY29uc3RydWN0b3I/LnByb3RvdHlwZSAmJlxuICAgICAgICAgICAgISFPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGVsZW1lbnQuY29uc3RydWN0b3IucHJvdG90eXBlLCBcInZhbHVlXCIpPy5bXCJnZXRcIl0pIHx8XG4gICAgICAgIGVsZW1lbnQuaGFzT3duUHJvcGVydHkoXCJ2YWx1ZVwiKVxuICAgICkge1xuICAgICAgICB2YWx1ZSA9IGVsZW1lbnQ/LltcInZhbHVlXCJdO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcInVuc3VwcG9ydGVkIG9iamVjdFwiKTtcbiAgICB9XG5cbiAgICBjb25zdCBjb3B5ID0gY2xvbmUoc2VsZltpbnRlcm5hbFN5bWJvbF0uc3ViamVjdC5nZXRSZWFsU3ViamVjdCgpKTtcbiAgICBjb25zdCBwZiA9IG5ldyBQYXRoZmluZGVyKGNvcHkpO1xuICAgIHBmLnNldFZpYShwYXRoLCB2YWx1ZSk7XG5cbiAgICBjb25zdCBkaWZmUmVzdWx0ID0gZGlmZihjb3B5LCBzZWxmW2ludGVybmFsU3ltYm9sXS5zdWJqZWN0LmdldFJlYWxTdWJqZWN0KCkpO1xuXG4gICAgaWYgKGRpZmZSZXN1bHQubGVuZ3RoID4gMCkge1xuICAgICAgICBwYXRoZmluZGVyLnNldFZpYShwYXRoLCB2YWx1ZSk7XG4gICAgfVxufVxuXG4vKipcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjcuMFxuICogQHJldHVybiB2b2lkXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiByZXRyaWV2ZUZyb21CaW5kaW5ncygpIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgIGlmIChzZWxmW2ludGVybmFsU3ltYm9sXS5lbGVtZW50Lm1hdGNoZXMoYFske0FUVFJJQlVURV9VUERBVEVSX0JJTkR9XWApKSB7XG4gICAgICAgIHJldHJpZXZlQW5kU2V0VmFsdWUuY2FsbChzZWxmLCBzZWxmW2ludGVybmFsU3ltYm9sXS5lbGVtZW50KTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IFssIGVsZW1lbnRdIG9mIHNlbGZbaW50ZXJuYWxTeW1ib2xdLmVsZW1lbnQucXVlcnlTZWxlY3RvckFsbChgWyR7QVRUUklCVVRFX1VQREFURVJfQklORH1dYCkuZW50cmllcygpKSB7XG4gICAgICAgIHJldHJpZXZlQW5kU2V0VmFsdWUuY2FsbChzZWxmLCBlbGVtZW50KTtcbiAgICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuOC4wXG4gKiBAcGFyYW0ge29iamVjdH0gY2hhbmdlXG4gKiBAcmV0dXJuIHt2b2lkfVxuICovXG5mdW5jdGlvbiByZW1vdmVFbGVtZW50KGNoYW5nZSkge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgZm9yIChjb25zdCBbLCBlbGVtZW50XSBvZiBzZWxmW2ludGVybmFsU3ltYm9sXS5lbGVtZW50XG4gICAgICAgIC5xdWVyeVNlbGVjdG9yQWxsKGA6c2NvcGUgWyR7QVRUUklCVVRFX1VQREFURVJfUkVNT1ZFfV1gKVxuICAgICAgICAuZW50cmllcygpKSB7XG4gICAgICAgIGVsZW1lbnQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChlbGVtZW50KTtcbiAgICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuOC4wXG4gKiBAcGFyYW0ge29iamVjdH0gY2hhbmdlXG4gKiBAcmV0dXJuIHt2b2lkfVxuICogQHRocm93cyB7RXJyb3J9IHRoZSB2YWx1ZSBpcyBub3QgaXRlcmFibGVcbiAqIEB0aHJvd3Mge0Vycm9yfSBwaXBlcyBhcmUgbm90IGFsbG93ZWQgd2hlbiBjbG9uaW5nIGEgbm9kZS5cbiAqIEB0aHJvd3Mge0Vycm9yfSBubyB0ZW1wbGF0ZSB3YXMgZm91bmQgd2l0aCB0aGUgc3BlY2lmaWVkIGtleS5cbiAqIEB0aHJvd3Mge0Vycm9yfSB0aGUgbWF4aW11bSBkZXB0aCBmb3IgdGhlIHJlY3Vyc2lvbiBpcyByZWFjaGVkLlxuICogQHRoaXMgVXBkYXRlclxuICovXG5mdW5jdGlvbiBpbnNlcnRFbGVtZW50KGNoYW5nZSkge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIGNvbnN0IHN1YmplY3QgPSBzZWxmW2ludGVybmFsU3ltYm9sXS5zdWJqZWN0LmdldFJlYWxTdWJqZWN0KCk7XG5cbiAgICBsZXQgbWVtID0gbmV3IFdlYWtTZXQoKTtcbiAgICBsZXQgd2QgPSAwO1xuXG4gICAgY29uc3QgY29udGFpbmVyID0gc2VsZltpbnRlcm5hbFN5bWJvbF0uZWxlbWVudDtcblxuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIGxldCBmb3VuZCA9IGZhbHNlO1xuICAgICAgICB3ZCsrO1xuXG4gICAgICAgIGxldCBwID0gY2xvbmUoY2hhbmdlPy5bXCJwYXRoXCJdKTtcbiAgICAgICAgaWYgKCFpc0FycmF5KHApKSByZXR1cm4gc2VsZjtcblxuICAgICAgICB3aGlsZSAocC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBjb25zdCBjdXJyZW50ID0gcC5qb2luKFwiLlwiKTtcblxuICAgICAgICAgICAgbGV0IGl0ZXJhdG9yID0gbmV3IFNldCgpO1xuICAgICAgICAgICAgY29uc3QgcXVlcnkgPSBgWyR7QVRUUklCVVRFX1VQREFURVJfSU5TRVJUfSo9XCJwYXRoOiR7Y3VycmVudH1cIl1gO1xuXG4gICAgICAgICAgICBjb25zdCBlID0gY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwocXVlcnkpO1xuXG4gICAgICAgICAgICBpZiAoZS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgaXRlcmF0b3IgPSBuZXcgU2V0KFsuLi5lXSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChjb250YWluZXIubWF0Y2hlcyhxdWVyeSkpIHtcbiAgICAgICAgICAgICAgICBpdGVyYXRvci5hZGQoY29udGFpbmVyKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZm9yIChjb25zdCBbLCBjb250YWluZXJFbGVtZW50XSBvZiBpdGVyYXRvci5lbnRyaWVzKCkpIHtcbiAgICAgICAgICAgICAgICBpZiAobWVtLmhhcyhjb250YWluZXJFbGVtZW50KSkgY29udGludWU7XG4gICAgICAgICAgICAgICAgbWVtLmFkZChjb250YWluZXJFbGVtZW50KTtcblxuICAgICAgICAgICAgICAgIGZvdW5kID0gdHJ1ZTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IGF0dHJpYnV0ZXMgPSBjb250YWluZXJFbGVtZW50LmdldEF0dHJpYnV0ZShBVFRSSUJVVEVfVVBEQVRFUl9JTlNFUlQpO1xuICAgICAgICAgICAgICAgIGlmIChhdHRyaWJ1dGVzID09PSBudWxsKSBjb250aW51ZTtcblxuICAgICAgICAgICAgICAgIGxldCBkZWYgPSB0cmltU3BhY2VzKGF0dHJpYnV0ZXMpO1xuICAgICAgICAgICAgICAgIGxldCBpID0gZGVmLmluZGV4T2YoXCIgXCIpO1xuICAgICAgICAgICAgICAgIGxldCBrZXkgPSB0cmltU3BhY2VzKGRlZi5zdWJzdHIoMCwgaSkpO1xuICAgICAgICAgICAgICAgIGxldCByZWZQcmVmaXggPSBgJHtrZXl9LWA7XG4gICAgICAgICAgICAgICAgbGV0IGNtZCA9IHRyaW1TcGFjZXMoZGVmLnN1YnN0cihpKSk7XG5cbiAgICAgICAgICAgICAgICAvLyB0aGlzIGNhc2UgaXMgYWN0dWFsbHkgZXhjbHVkZWQgYnkgdGhlIHF1ZXJ5IGJ1dCBpcyBuZXZlcnRoZWxlc3MgY2hlY2tlZCBhZ2FpbiBoZXJlXG4gICAgICAgICAgICAgICAgaWYgKGNtZC5pbmRleE9mKFwifFwiKSA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwicGlwZXMgYXJlIG5vdCBhbGxvd2VkIHdoZW4gY2xvbmluZyBhIG5vZGUuXCIpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGxldCBwaXBlID0gbmV3IFBpcGUoY21kKTtcbiAgICAgICAgICAgICAgICBzZWxmW2ludGVybmFsU3ltYm9sXS5jYWxsYmFja3MuZm9yRWFjaCgoZiwgbikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBwaXBlLnNldENhbGxiYWNrKG4sIGYpO1xuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgbGV0IHZhbHVlO1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRhaW5lckVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKEFUVFJJQlVURV9FUlJPUk1FU1NBR0UpO1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHBpcGUucnVuKHN1YmplY3QpO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyRWxlbWVudC5zZXRBdHRyaWJ1dGUoQVRUUklCVVRFX0VSUk9STUVTU0FHRSwgZS5tZXNzYWdlKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBsZXQgZGF0YVBhdGggPSBjbWQuc3BsaXQoXCI6XCIpLnBvcCgpO1xuXG4gICAgICAgICAgICAgICAgbGV0IGluc2VydFBvaW50O1xuICAgICAgICAgICAgICAgIGlmIChjb250YWluZXJFbGVtZW50Lmhhc0NoaWxkTm9kZXMoKSkge1xuICAgICAgICAgICAgICAgICAgICBpbnNlcnRQb2ludCA9IGNvbnRhaW5lckVsZW1lbnQubGFzdENoaWxkO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICghaXNJdGVyYWJsZSh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidGhlIHZhbHVlIGlzIG5vdCBpdGVyYWJsZVwiKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBsZXQgYXZhaWxhYmxlID0gbmV3IFNldCgpO1xuXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBbaSwgb2JqXSBvZiBPYmplY3QuZW50cmllcyh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHJlZiA9IHJlZlByZWZpeCArIGk7XG4gICAgICAgICAgICAgICAgICAgIGxldCBjdXJyZW50UGF0aCA9IGAke2RhdGFQYXRofS4ke2l9YDtcblxuICAgICAgICAgICAgICAgICAgICBhdmFpbGFibGUuYWRkKHJlZik7XG4gICAgICAgICAgICAgICAgICAgIGxldCByZWZFbGVtZW50ID0gY29udGFpbmVyRWxlbWVudC5xdWVyeVNlbGVjdG9yKGBbJHtBVFRSSUJVVEVfVVBEQVRFUl9JTlNFUlRfUkVGRVJFTkNFfT1cIiR7cmVmfVwiXWApO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZWZFbGVtZW50IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGluc2VydFBvaW50ID0gcmVmRWxlbWVudDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgYXBwZW5kTmV3RG9jdW1lbnRGcmFnbWVudChjb250YWluZXJFbGVtZW50LCBrZXksIHJlZiwgY3VycmVudFBhdGgpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGxldCBub2RlcyA9IGNvbnRhaW5lckVsZW1lbnQucXVlcnlTZWxlY3RvckFsbChcbiAgICAgICAgICAgICAgICAgICAgYFske0FUVFJJQlVURV9VUERBVEVSX0lOU0VSVF9SRUZFUkVOQ0V9Kj1cIiR7cmVmUHJlZml4fVwiXWAsXG4gICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgWywgbm9kZV0gb2YgT2JqZWN0LmVudHJpZXMobm9kZXMpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghYXZhaWxhYmxlLmhhcyhub2RlLmdldEF0dHJpYnV0ZShBVFRSSUJVVEVfVVBEQVRFUl9JTlNFUlRfUkVGRVJFTkNFKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyRWxlbWVudC5yZW1vdmVDaGlsZChub2RlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250YWluZXJFbGVtZW50LnNldEF0dHJpYnV0ZShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVRUUklCVVRFX0VSUk9STUVTU0FHRSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYCR7Y29udGFpbmVyRWxlbWVudC5nZXRBdHRyaWJ1dGUoQVRUUklCVVRFX0VSUk9STUVTU0FHRSl9LCAke2UubWVzc2FnZX1gLnRyaW0oKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBwLnBvcCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGZvdW5kID09PSBmYWxzZSkgYnJlYWs7XG4gICAgICAgIGlmICh3ZCsrID4gMjAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0aGUgbWF4aW11bSBkZXB0aCBmb3IgdGhlIHJlY3Vyc2lvbiBpcyByZWFjaGVkLlwiKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLyoqXG4gKlxuICogQHByaXZhdGVcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuOC4wXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBjb250YWluZXJcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXlcbiAqIEBwYXJhbSB7c3RyaW5nfSByZWZcbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoXG4gKiBAdGhyb3dzIHtFcnJvcn0gbm8gdGVtcGxhdGUgd2FzIGZvdW5kIHdpdGggdGhlIHNwZWNpZmllZCBrZXkuXG4gKi9cbmZ1bmN0aW9uIGFwcGVuZE5ld0RvY3VtZW50RnJhZ21lbnQoY29udGFpbmVyLCBrZXksIHJlZiwgcGF0aCkge1xuICAgIGxldCB0ZW1wbGF0ZSA9IGZpbmREb2N1bWVudFRlbXBsYXRlKGtleSwgY29udGFpbmVyKTtcblxuICAgIGxldCBub2RlcyA9IHRlbXBsYXRlLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcbiAgICBmb3IgKGNvbnN0IFssIG5vZGVdIG9mIE9iamVjdC5lbnRyaWVzKG5vZGVzLmNoaWxkTm9kZXMpKSB7XG4gICAgICAgIGlmIChub2RlIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgICAgIGFwcGx5UmVjdXJzaXZlKG5vZGUsIGtleSwgcGF0aCk7XG4gICAgICAgICAgICBub2RlLnNldEF0dHJpYnV0ZShBVFRSSUJVVEVfVVBEQVRFUl9JTlNFUlRfUkVGRVJFTkNFLCByZWYpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKG5vZGUpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4xMC4wXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBub2RlXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5XG4gKiBAcGFyYW0ge3N0cmluZ30gcGF0aFxuICogQHJldHVybiB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gYXBwbHlSZWN1cnNpdmUobm9kZSwga2V5LCBwYXRoKSB7XG4gICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICBpZiAobm9kZS5oYXNBdHRyaWJ1dGUoQVRUUklCVVRFX1VQREFURVJfUkVQTEFDRSkpIHtcbiAgICAgICAgICAgIGxldCB2YWx1ZSA9IG5vZGUuZ2V0QXR0cmlidXRlKEFUVFJJQlVURV9VUERBVEVSX1JFUExBQ0UpO1xuICAgICAgICAgICAgbm9kZS5zZXRBdHRyaWJ1dGUoQVRUUklCVVRFX1VQREFURVJfUkVQTEFDRSwgdmFsdWUucmVwbGFjZUFsbChgcGF0aDoke2tleX1gLCBgcGF0aDoke3BhdGh9YCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG5vZGUuaGFzQXR0cmlidXRlKEFUVFJJQlVURV9VUERBVEVSX0FUVFJJQlVURVMpKSB7XG4gICAgICAgICAgICBsZXQgdmFsdWUgPSBub2RlLmdldEF0dHJpYnV0ZShBVFRSSUJVVEVfVVBEQVRFUl9BVFRSSUJVVEVTKTtcbiAgICAgICAgICAgIG5vZGUuc2V0QXR0cmlidXRlKEFUVFJJQlVURV9VUERBVEVSX0FUVFJJQlVURVMsIHZhbHVlLnJlcGxhY2VBbGwoYHBhdGg6JHtrZXl9YCwgYHBhdGg6JHtwYXRofWApKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoY29uc3QgWywgY2hpbGRdIG9mIE9iamVjdC5lbnRyaWVzKG5vZGUuY2hpbGROb2RlcykpIHtcbiAgICAgICAgICAgIGFwcGx5UmVjdXJzaXZlKGNoaWxkLCBrZXksIHBhdGgpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjguMFxuICogQHBhcmFtIHtvYmplY3R9IGNoYW5nZVxuICogQHJldHVybiB7dm9pZH1cbiAqIEB0aGlzIFVwZGF0ZXJcbiAqL1xuZnVuY3Rpb24gdXBkYXRlQ29udGVudChjaGFuZ2UpIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICBjb25zdCBzdWJqZWN0ID0gc2VsZltpbnRlcm5hbFN5bWJvbF0uc3ViamVjdC5nZXRSZWFsU3ViamVjdCgpO1xuXG4gICAgbGV0IHAgPSBjbG9uZShjaGFuZ2U/LltcInBhdGhcIl0pO1xuICAgIHJ1blVwZGF0ZUNvbnRlbnQuY2FsbCh0aGlzLCB0aGlzW2ludGVybmFsU3ltYm9sXS5lbGVtZW50LCBwLCBzdWJqZWN0KTtcblxuICAgIGNvbnN0IHNsb3RzID0gdGhpc1tpbnRlcm5hbFN5bWJvbF0uZWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKFwic2xvdFwiKTtcbiAgICBpZiAoc2xvdHMubGVuZ3RoID4gMCkge1xuICAgICAgICBmb3IgKGNvbnN0IFssIHNsb3RdIG9mIE9iamVjdC5lbnRyaWVzKHNsb3RzKSkge1xuICAgICAgICAgICAgZm9yIChjb25zdCBbLCBlbGVtZW50XSBvZiBPYmplY3QuZW50cmllcyhzbG90LmFzc2lnbmVkTm9kZXMoKSkpIHtcbiAgICAgICAgICAgICAgICBydW5VcGRhdGVDb250ZW50LmNhbGwodGhpcywgZWxlbWVudCwgcCwgc3ViamVjdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuOC4wXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBjb250YWluZXJcbiAqIEBwYXJhbSB7YXJyYXl9IHBhcnRzXG4gKiBAcGFyYW0ge29iamVjdH0gc3ViamVjdFxuICogQHJldHVybiB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gcnVuVXBkYXRlQ29udGVudChjb250YWluZXIsIHBhcnRzLCBzdWJqZWN0KSB7XG4gICAgaWYgKCFpc0FycmF5KHBhcnRzKSkgcmV0dXJuO1xuICAgIGlmICghKGNvbnRhaW5lciBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSkgcmV0dXJuO1xuICAgIHBhcnRzID0gY2xvbmUocGFydHMpO1xuXG4gICAgbGV0IG1lbSA9IG5ldyBXZWFrU2V0KCk7XG5cbiAgICB3aGlsZSAocGFydHMubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zdCBjdXJyZW50ID0gcGFydHMuam9pbihcIi5cIik7XG4gICAgICAgIHBhcnRzLnBvcCgpO1xuXG4gICAgICAgIC8vIFVuZm9ydHVuYXRlbHksIHN0YXRpYyBkYXRhIGlzIGFsd2F5cyBjaGFuZ2VkIGFzIHdlbGwsIHNpbmNlIGl0IGlzIG5vdCBwb3NzaWJsZSB0byByZWFjdCB0byBjaGFuZ2VzIGhlcmUuXG4gICAgICAgIGNvbnN0IHF1ZXJ5ID0gYFske0FUVFJJQlVURV9VUERBVEVSX1JFUExBQ0V9Xj1cInBhdGg6JHtjdXJyZW50fVwiXSwgWyR7QVRUUklCVVRFX1VQREFURVJfUkVQTEFDRX1ePVwic3RhdGljOlwiXSwgWyR7QVRUUklCVVRFX1VQREFURVJfUkVQTEFDRX1ePVwiaTE4bjpcIl1gO1xuICAgICAgICBjb25zdCBlID0gY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoYCR7cXVlcnl9YCk7XG5cbiAgICAgICAgY29uc3QgaXRlcmF0b3IgPSBuZXcgU2V0KFsuLi5lXSk7XG5cbiAgICAgICAgaWYgKGNvbnRhaW5lci5tYXRjaGVzKHF1ZXJ5KSkge1xuICAgICAgICAgICAgaXRlcmF0b3IuYWRkKGNvbnRhaW5lcik7XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICogQHR5cGUge0hUTUxFbGVtZW50fVxuICAgICAgICAgKi9cbiAgICAgICAgZm9yIChjb25zdCBbZWxlbWVudF0gb2YgaXRlcmF0b3IuZW50cmllcygpKSB7XG4gICAgICAgICAgICBpZiAobWVtLmhhcyhlbGVtZW50KSkgcmV0dXJuO1xuICAgICAgICAgICAgbWVtLmFkZChlbGVtZW50KTtcblxuICAgICAgICAgICAgY29uc3QgYXR0cmlidXRlcyA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKEFUVFJJQlVURV9VUERBVEVSX1JFUExBQ0UpO1xuICAgICAgICAgICAgbGV0IGNtZCA9IHRyaW1TcGFjZXMoYXR0cmlidXRlcyk7XG5cbiAgICAgICAgICAgIGxldCBwaXBlID0gbmV3IFBpcGUoY21kKTtcbiAgICAgICAgICAgIHRoaXNbaW50ZXJuYWxTeW1ib2xdLmNhbGxiYWNrcy5mb3JFYWNoKChmLCBuKSA9PiB7XG4gICAgICAgICAgICAgICAgcGlwZS5zZXRDYWxsYmFjayhuLCBmKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBsZXQgdmFsdWU7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKEFUVFJJQlVURV9FUlJPUk1FU1NBR0UpO1xuICAgICAgICAgICAgICAgIHZhbHVlID0gcGlwZS5ydW4oc3ViamVjdCk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoQVRUUklCVVRFX0VSUk9STUVTU0FHRSwgZS5tZXNzYWdlKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICB3aGlsZSAoZWxlbWVudC5maXJzdENoaWxkKSB7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQucmVtb3ZlQ2hpbGQoZWxlbWVudC5maXJzdENoaWxkKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50LmFwcGVuZENoaWxkKHZhbHVlKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKFxuICAgICAgICAgICAgICAgICAgICAgICAgQVRUUklCVVRFX0VSUk9STUVTU0FHRSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGAke2VsZW1lbnQuZ2V0QXR0cmlidXRlKEFUVFJJQlVURV9FUlJPUk1FU1NBR0UpfSwgJHtlLm1lc3NhZ2V9YC50cmltKCksXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBlbGVtZW50LmlubmVySFRNTCA9IHZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjguMFxuICogQHBhcmFtIHtzdHJpbmd9IHBhdGhcbiAqIEBwYXJhbSB7b2JqZWN0fSBjaGFuZ2VcbiAqIEByZXR1cm4ge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIHVwZGF0ZUF0dHJpYnV0ZXMoY2hhbmdlKSB7XG4gICAgY29uc3Qgc3ViamVjdCA9IHRoaXNbaW50ZXJuYWxTeW1ib2xdLnN1YmplY3QuZ2V0UmVhbFN1YmplY3QoKTtcbiAgICBsZXQgcCA9IGNsb25lKGNoYW5nZT8uW1wicGF0aFwiXSk7XG4gICAgcnVuVXBkYXRlQXR0cmlidXRlcy5jYWxsKHRoaXMsIHRoaXNbaW50ZXJuYWxTeW1ib2xdLmVsZW1lbnQsIHAsIHN1YmplY3QpO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBjb250YWluZXJcbiAqIEBwYXJhbSB7YXJyYXl9IHBhcnRzXG4gKiBAcGFyYW0ge29iamVjdH0gc3ViamVjdFxuICogQHJldHVybiB7dm9pZH1cbiAqIEB0aGlzIFVwZGF0ZXJcbiAqL1xuZnVuY3Rpb24gcnVuVXBkYXRlQXR0cmlidXRlcyhjb250YWluZXIsIHBhcnRzLCBzdWJqZWN0KSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICBpZiAoIWlzQXJyYXkocGFydHMpKSByZXR1cm47XG4gICAgcGFydHMgPSBjbG9uZShwYXJ0cyk7XG5cbiAgICBsZXQgbWVtID0gbmV3IFdlYWtTZXQoKTtcblxuICAgIHdoaWxlIChwYXJ0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnQgPSBwYXJ0cy5qb2luKFwiLlwiKTtcbiAgICAgICAgcGFydHMucG9wKCk7XG5cbiAgICAgICAgbGV0IGl0ZXJhdG9yID0gbmV3IFNldCgpO1xuXG4gICAgICAgIGNvbnN0IHF1ZXJ5ID0gYFske0FUVFJJQlVURV9VUERBVEVSX1NFTEVDVF9USElTfV1bJHtBVFRSSUJVVEVfVVBEQVRFUl9BVFRSSUJVVEVTfV0sIFske0FUVFJJQlVURV9VUERBVEVSX0FUVFJJQlVURVN9Kj1cInBhdGg6JHtjdXJyZW50fVwiXSwgWyR7QVRUUklCVVRFX1VQREFURVJfQVRUUklCVVRFU31ePVwic3RhdGljOlwiXSwgWyR7QVRUUklCVVRFX1VQREFURVJfQVRUUklCVVRFU31ePVwiaTE4bjpcIl1gO1xuXG4gICAgICAgIGNvbnN0IGUgPSBjb250YWluZXIucXVlcnlTZWxlY3RvckFsbChxdWVyeSk7XG5cbiAgICAgICAgaWYgKGUubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgaXRlcmF0b3IgPSBuZXcgU2V0KFsuLi5lXSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29udGFpbmVyLm1hdGNoZXMocXVlcnkpKSB7XG4gICAgICAgICAgICBpdGVyYXRvci5hZGQoY29udGFpbmVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoY29uc3QgW2VsZW1lbnRdIG9mIGl0ZXJhdG9yLmVudHJpZXMoKSkge1xuICAgICAgICAgICAgaWYgKG1lbS5oYXMoZWxlbWVudCkpIHJldHVybjtcbiAgICAgICAgICAgIG1lbS5hZGQoZWxlbWVudCk7XG5cbiAgICAgICAgICAgIC8vIHRoaXMgY2FzZSBvY2N1cnMgd2hlbiB0aGUgQVRUUklCVVRFX1VQREFURVJfU0VMRUNUX1RISVMgYXR0cmlidXRlIGlzIHNldFxuICAgICAgICAgICAgaWYgKCFlbGVtZW50Lmhhc0F0dHJpYnV0ZShBVFRSSUJVVEVfVVBEQVRFUl9BVFRSSUJVVEVTKSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBhdHRyaWJ1dGVzID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoQVRUUklCVVRFX1VQREFURVJfQVRUUklCVVRFUyk7XG5cbiAgICAgICAgICAgIGZvciAobGV0IFssIGRlZl0gb2YgT2JqZWN0LmVudHJpZXMoYXR0cmlidXRlcy5zcGxpdChcIixcIikpKSB7XG4gICAgICAgICAgICAgICAgZGVmID0gdHJpbVNwYWNlcyhkZWYpO1xuICAgICAgICAgICAgICAgIGxldCBpID0gZGVmLmluZGV4T2YoXCIgXCIpO1xuICAgICAgICAgICAgICAgIGxldCBuYW1lID0gdHJpbVNwYWNlcyhkZWYuc3Vic3RyKDAsIGkpKTtcbiAgICAgICAgICAgICAgICBsZXQgY21kID0gdHJpbVNwYWNlcyhkZWYuc3Vic3RyKGkpKTtcblxuICAgICAgICAgICAgICAgIGxldCBwaXBlID0gbmV3IFBpcGUoY21kKTtcblxuICAgICAgICAgICAgICAgIHNlbGZbaW50ZXJuYWxTeW1ib2xdLmNhbGxiYWNrcy5mb3JFYWNoKChmLCBuKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHBpcGUuc2V0Q2FsbGJhY2sobiwgZiwgZWxlbWVudCk7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICBsZXQgdmFsdWU7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoQVRUUklCVVRFX0VSUk9STUVTU0FHRSk7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gcGlwZS5ydW4oc3ViamVjdCk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShBVFRSSUJVVEVfRVJST1JNRVNTQUdFLCBlLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKG5hbWUpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZWxlbWVudC5nZXRBdHRyaWJ1dGUobmFtZSkgIT09IHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKG5hbWUsIHZhbHVlKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBoYW5kbGVJbnB1dENvbnRyb2xBdHRyaWJ1dGVVcGRhdGUuY2FsbCh0aGlzLCBlbGVtZW50LCBuYW1lLCB2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR8Kn0gZWxlbWVudFxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcnx1bmRlZmluZWR9IHZhbHVlXG4gKiBAcmV0dXJuIHt2b2lkfVxuICogQHRoaXMgVXBkYXRlclxuICovXG5cbmZ1bmN0aW9uIGhhbmRsZUlucHV0Q29udHJvbEF0dHJpYnV0ZVVwZGF0ZShlbGVtZW50LCBuYW1lLCB2YWx1ZSkge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MU2VsZWN0RWxlbWVudCkge1xuICAgICAgICBzd2l0Y2ggKGVsZW1lbnQudHlwZSkge1xuICAgICAgICAgICAgY2FzZSBcInNlbGVjdC1tdWx0aXBsZVwiOlxuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW2luZGV4LCBvcHRdIG9mIE9iamVjdC5lbnRyaWVzKGVsZW1lbnQub3B0aW9ucykpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlLmluZGV4T2Yob3B0LnZhbHVlKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdC5zZWxlY3RlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcHQuc2VsZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcInNlbGVjdC1vbmVcIjpcbiAgICAgICAgICAgICAgICAvLyBPbmx5IG9uZSB2YWx1ZSBtYXkgYmUgc2VsZWN0ZWRcblxuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW2luZGV4LCBvcHRdIG9mIE9iamVjdC5lbnRyaWVzKGVsZW1lbnQub3B0aW9ucykpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wdC52YWx1ZSA9PT0gdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuc2VsZWN0ZWRJbmRleCA9IGluZGV4O1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZWxlbWVudCBpbnN0YW5jZW9mIEhUTUxJbnB1dEVsZW1lbnQpIHtcbiAgICAgICAgc3dpdGNoIChlbGVtZW50LnR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgXCJyYWRpb1wiOlxuICAgICAgICAgICAgICAgIGlmIChuYW1lID09PSBcImNoZWNrZWRcIikge1xuICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5jaGVja2VkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuY2hlY2tlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgIGNhc2UgXCJjaGVja2JveFwiOlxuICAgICAgICAgICAgICAgIGlmIChuYW1lID09PSBcImNoZWNrZWRcIikge1xuICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5jaGVja2VkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuY2hlY2tlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwidGV4dFwiOlxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBpZiAobmFtZSA9PT0gXCJ2YWx1ZVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQudmFsdWUgPSB2YWx1ZSA9PT0gdW5kZWZpbmVkID8gXCJcIiA6IHZhbHVlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfSBlbHNlIGlmIChlbGVtZW50IGluc3RhbmNlb2YgSFRNTFRleHRBcmVhRWxlbWVudCkge1xuICAgICAgICBpZiAobmFtZSA9PT0gXCJ2YWx1ZVwiKSB7XG4gICAgICAgICAgICBlbGVtZW50LnZhbHVlID0gdmFsdWUgPT09IHVuZGVmaW5lZCA/IFwiXCIgOiB2YWx1ZTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLyoqXG4gKiBAcGFyYW0ge05vZGVMaXN0fEhUTUxFbGVtZW50fFNldDxIVE1MRWxlbWVudD59IGVsZW1lbnRzXG4gKiBAcGFyYW0ge1N5bWJvbH0gc3ltYm9sXG4gKiBAcGFyYW0ge29iamVjdH0gb2JqZWN0XG4gKiBAcmV0dXJuIHtQcm9taXNlW119XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjIzLjBcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHRocm93cyB7VHlwZUVycm9yfSBlbGVtZW50cyBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgTm9kZUxpc3QsIEhUTUxFbGVtZW50IG9yIFNldFxuICogQHRocm93cyB7VHlwZUVycm9yfSB0aGUgY29udGV4dCBvZiB0aGUgZnVuY3Rpb24gaXMgbm90IGFuIGluc3RhbmNlIG9mIEhUTUxFbGVtZW50XG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHN5bWJvbCBtdXN0IGJlIGFuIGluc3RhbmNlIG9mIFN5bWJvbFxuICovXG5mdW5jdGlvbiBhZGRPYmplY3RXaXRoVXBkYXRlclRvRWxlbWVudChlbGVtZW50cywgc3ltYm9sLCBvYmplY3QpIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICBpZiAoIShzZWxmIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJ0aGUgY29udGV4dCBvZiB0aGlzIGZ1bmN0aW9uIG11c3QgYmUgYW4gaW5zdGFuY2Ugb2YgSFRNTEVsZW1lbnRcIik7XG4gICAgfVxuXG4gICAgaWYgKCEodHlwZW9mIHN5bWJvbCA9PT0gXCJzeW1ib2xcIikpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInN5bWJvbCBtdXN0IGJlIGFuIGluc3RhbmNlIG9mIFN5bWJvbFwiKTtcbiAgICB9XG5cbiAgICBjb25zdCB1cGRhdGVycyA9IG5ldyBTZXQoKTtcblxuICAgIGlmIChlbGVtZW50cyBpbnN0YW5jZW9mIE5vZGVMaXN0KSB7XG4gICAgICAgIGVsZW1lbnRzID0gbmV3IFNldChbLi4uZWxlbWVudHNdKTtcbiAgICB9IGVsc2UgaWYgKGVsZW1lbnRzIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgZWxlbWVudHMgPSBuZXcgU2V0KFtlbGVtZW50c10pO1xuICAgIH0gZWxzZSBpZiAoZWxlbWVudHMgaW5zdGFuY2VvZiBTZXQpIHtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBlbGVtZW50cyBpcyBub3QgYSB2YWxpZCB0eXBlLiAoYWN0dWFsOiAke3R5cGVvZiBlbGVtZW50c30pYCk7XG4gICAgfVxuXG4gICAgbGV0IHJlc3VsdCA9IFtdO1xuXG4gICAgZWxlbWVudHMuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgICBpZiAoIShlbGVtZW50IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKSByZXR1cm47XG4gICAgICAgIGlmIChlbGVtZW50IGluc3RhbmNlb2YgSFRNTFRlbXBsYXRlRWxlbWVudCkgcmV0dXJuO1xuXG4gICAgICAgIGNvbnN0IHUgPSBuZXcgVXBkYXRlcihlbGVtZW50LCBvYmplY3QpO1xuICAgICAgICB1cGRhdGVycy5hZGQodSk7XG5cbiAgICAgICAgcmVzdWx0LnB1c2goXG4gICAgICAgICAgICB1LnJ1bigpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiB1LmVuYWJsZUV2ZW50UHJvY2Vzc2luZygpO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpZiAodXBkYXRlcnMuc2l6ZSA+IDApIHtcbiAgICAgICAgYWRkVG9PYmplY3RMaW5rKHNlbGYsIHN5bWJvbCwgdXBkYXRlcnMpO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBpbnRlcm5hbFN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQgeyBleHRlbmQgfSBmcm9tIFwiLi4vZGF0YS9leHRlbmQubWpzXCI7XG5pbXBvcnQgeyBQYXRoZmluZGVyIH0gZnJvbSBcIi4uL2RhdGEvcGF0aGZpbmRlci5tanNcIjtcbmltcG9ydCB7IEZvcm1hdHRlciB9IGZyb20gXCIuLi90ZXh0L2Zvcm1hdHRlci5tanNcIjtcblxuaW1wb3J0IHsgcGFyc2VEYXRhVVJMIH0gZnJvbSBcIi4uL3R5cGVzL2RhdGF1cmwubWpzXCI7XG5pbXBvcnQgeyBnZXRHbG9iYWxPYmplY3QgfSBmcm9tIFwiLi4vdHlwZXMvZ2xvYmFsLm1qc1wiO1xuaW1wb3J0IHsgaXNBcnJheSwgaXNGdW5jdGlvbiwgaXNJdGVyYWJsZSwgaXNPYmplY3QsIGlzU3RyaW5nIH0gZnJvbSBcIi4uL3R5cGVzL2lzLm1qc1wiO1xuaW1wb3J0IHsgT2JzZXJ2ZXIgfSBmcm9tIFwiLi4vdHlwZXMvb2JzZXJ2ZXIubWpzXCI7XG5pbXBvcnQgeyBQcm94eU9ic2VydmVyIH0gZnJvbSBcIi4uL3R5cGVzL3Byb3h5b2JzZXJ2ZXIubWpzXCI7XG5pbXBvcnQgeyB2YWxpZGF0ZUZ1bmN0aW9uLCB2YWxpZGF0ZUluc3RhbmNlLCB2YWxpZGF0ZU9iamVjdCwgdmFsaWRhdGVTdHJpbmcgfSBmcm9tIFwiLi4vdHlwZXMvdmFsaWRhdGUubWpzXCI7XG5pbXBvcnQgeyBjbG9uZSB9IGZyb20gXCIuLi91dGlsL2Nsb25lLm1qc1wiO1xuaW1wb3J0IHsgYWRkQXR0cmlidXRlVG9rZW4sIGdldExpbmtlZE9iamVjdHMsIGhhc09iamVjdExpbmsgfSBmcm9tIFwiLi9hdHRyaWJ1dGVzLm1qc1wiO1xuaW1wb3J0IHtcbiAgICBBVFRSSUJVVEVfRElTQUJMRUQsXG4gICAgQVRUUklCVVRFX0VSUk9STUVTU0FHRSxcbiAgICBBVFRSSUJVVEVfT1BUSU9OUyxcbiAgICBBVFRSSUJVVEVfT1BUSU9OU19TRUxFQ1RPUixcbiAgICBjdXN0b21FbGVtZW50VXBkYXRlckxpbmtTeW1ib2wsXG59IGZyb20gXCIuL2NvbnN0YW50cy5tanNcIjtcbmltcG9ydCB7IGZpbmREb2N1bWVudFRlbXBsYXRlLCBUZW1wbGF0ZSB9IGZyb20gXCIuL3RlbXBsYXRlLm1qc1wiO1xuaW1wb3J0IHsgYWRkT2JqZWN0V2l0aFVwZGF0ZXJUb0VsZW1lbnQgfSBmcm9tIFwiLi91cGRhdGVyLm1qc1wiO1xuaW1wb3J0IHsgaW5zdGFuY2VTeW1ib2wgfSBmcm9tIFwiLi4vY29uc3RhbnRzLm1qc1wiO1xuaW1wb3J0IHsgZ2V0RG9jdW1lbnRUcmFuc2xhdGlvbnMsIFRyYW5zbGF0aW9ucyB9IGZyb20gXCIuLi9pMThuL3RyYW5zbGF0aW9ucy5tanNcIjtcbmltcG9ydCB7IGdldFNsb3R0ZWRFbGVtZW50cyB9IGZyb20gXCIuL3Nsb3R0ZWQubWpzXCI7XG5cbmV4cG9ydCB7XG4gICAgQ3VzdG9tRWxlbWVudCxcbiAgICBpbml0TWV0aG9kU3ltYm9sLFxuICAgIGFzc2VtYmxlTWV0aG9kU3ltYm9sLFxuICAgIGF0dHJpYnV0ZU9ic2VydmVyU3ltYm9sLFxuICAgIHJlZ2lzdGVyQ3VzdG9tRWxlbWVudCxcbiAgICBnZXRTbG90dGVkRWxlbWVudHMsXG59O1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N5bWJvbH1cbiAqL1xuY29uc3QgaW5pdE1ldGhvZFN5bWJvbCA9IFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL2RvbS9AQGluaXRNZXRob2RTeW1ib2xcIik7XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3ltYm9sfVxuICovXG5jb25zdCBhc3NlbWJsZU1ldGhvZFN5bWJvbCA9IFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL2RvbS9AQGFzc2VtYmxlTWV0aG9kU3ltYm9sXCIpO1xuXG4vKipcbiAqIHRoaXMgc3ltYm9sIGhvbGRzIHRoZSBhdHRyaWJ1dGUgb2JzZXJ2ZXIgY2FsbGJhY2tzLiBUaGUga2V5IGlzIHRoZSBhdHRyaWJ1dGUgbmFtZS5cbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N5bWJvbH1cbiAqL1xuY29uc3QgYXR0cmlidXRlT2JzZXJ2ZXJTeW1ib2wgPSBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci9kb20vQEBhdHRyaWJ1dGVPYnNlcnZlclwiKTtcblxuLyoqXG4gKiBIVE1MRWxlbWVudFxuICogQGV4dGVybmFsIEhUTUxFbGVtZW50XG4gKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9IVE1MRWxlbWVudFxuICpcbiAqIEBzdGFydHVtbCBjdXN0b21lbGVtZW50LXNlcXVlbmNlZGlhZ3JhbS5wbmdcbiAqIHNraW5wYXJhbSBtb25vY2hyb21lIHRydWVcbiAqIHNraW5wYXJhbSBzaGFkb3dpbmcgZmFsc2VcbiAqXG4gKiBhdXRvbnVtYmVyXG4gKlxuICogU2NyaXB0IC0+IERPTTogZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ215LWVsZW1lbnQnKVxuICogRE9NIC0+IEN1c3RvbUVsZW1lbnQ6IGNvbnN0cnVjdG9yKClcbiAqIEN1c3RvbUVsZW1lbnQgLT4gQ3VzdG9tRWxlbWVudDogW2luaXRNZXRob2RTeW1ib2xdKClcbiAqXG4gKiBDdXN0b21FbGVtZW50IC0tPiBET006IEVsZW1lbnRcbiAqIERPTSAtLT4gU2NyaXB0IDogZWxlbWVudFxuICpcbiAqXG4gKiBTY3JpcHQgLT4gRE9NOiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdib2R5JykuYXBwZW5kKGVsZW1lbnQpXG4gKlxuICogRE9NIC0+IEN1c3RvbUVsZW1lbnQgOiBjb25uZWN0ZWRDYWxsYmFjaygpXG4gKlxuICogbm90ZSByaWdodCBDdXN0b21FbGVtZW50OiBpcyBvbmx5IGNhbGxlZCBhdFxcbnRoZSBmaXJzdCBjb25uZWN0aW9uXG4gKiBDdXN0b21FbGVtZW50IC0+IEN1c3RvbUVsZW1lbnQgOiBbYXNzZW1ibGVNZXRob2RTeW1ib2xdKClcbiAqXG4gKiAuLi4gLi4uXG4gKlxuICogYXV0b251bWJlclxuICpcbiAqIFNjcmlwdCAtPiBET006IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ21vbnN0ZXItY29uZmlybS1idXR0b24nKS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGVsZW1lbnQpXG4gKiBET00gLT4gQ3VzdG9tRWxlbWVudDogZGlzY29ubmVjdGVkQ2FsbGJhY2soKVxuICpcbiAqXG4gKiBAZW5kdW1sXG4gKlxuICogQHN0YXJ0dW1sIGN1c3RvbWVsZW1lbnQtY2xhc3MucG5nXG4gKiBza2lucGFyYW0gbW9ub2Nocm9tZSB0cnVlXG4gKiBza2lucGFyYW0gc2hhZG93aW5nIGZhbHNlXG4gKiBIVE1MRWxlbWVudCA8fC0tIEN1c3RvbUVsZW1lbnRcbiAqIEBlbmR1bWxcbiAqL1xuXG4vKipcbiAqIFRvIGRlZmluZSBhIG5ldyBIVE1MIGVsZW1lbnQgd2UgbmVlZCB0aGUgcG93ZXIgb2YgQ3VzdG9tRWxlbWVudFxuICpcbiAqIElNUE9SVEFOVDogYWZ0ZXIgZGVmaW5pbmcgYSBgQ3VzdG9tRWxlbWVudGAsIHRoZSBgcmVnaXN0ZXJDdXN0b21FbGVtZW50YCBtZXRob2QgbXVzdCBiZSBjYWxsZWRcbiAqIHdpdGggdGhlIG5ldyBjbGFzcyBuYW1lLiBvbmx5IHRoZW4gd2lsbCB0aGUgdGFnIGRlZmluZWQgdmlhIHRoZSBgZ2V0VGFnYCBtZXRob2QgYmUgbWFkZSBrbm93biB0byB0aGUgRE9NLlxuICpcbiAqIDxpbWcgc3JjPVwiLi9pbWFnZXMvY3VzdG9tZWxlbWVudC1jbGFzcy5wbmdcIj5cbiAqXG4gKiBZb3UgY2FuIGNyZWF0ZSB0aGUgb2JqZWN0IHZpYSB0aGUgZnVuY3Rpb24gYGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoKWAuXG4gKlxuICpcbiAqICMjIEludGVyYWN0aW9uXG4gKlxuICogPGltZyBzcmM9XCIuL2ltYWdlcy9jdXN0b21lbGVtZW50LXNlcXVlbmNlZGlhZ3JhbS5wbmdcIj5cbiAqXG4gKiAjIyBTdHlsaW5nXG4gKlxuICogRm9yIG9wdGltYWwgZGlzcGxheSBvZiBjdXN0b20tZWxlbWVudHMgdGhlIHBzZXVkby1jbGFzcyA6ZGVmaW5lZCBjYW4gYmUgdXNlZC5cbiAqXG4gKiBUbyBwcmV2ZW50IHRoZSBjdXN0b20gZWxlbWVudHMgZnJvbSBiZWluZyBkaXNwbGF5ZWQgYW5kIGZsaWNrZXJpbmcgdW50aWwgdGhlIGNvbnRyb2wgaXMgcmVnaXN0ZXJlZCwgaXQgaXMgcmVjb21tZW5kZWQgdG8gY3JlYXRlIGEgY3NzIGRpcmVjdGl2ZS5cbiAqXG4gKiBJbiB0aGUgc2ltcGxlc3QgY2FzZSwgeW91IGNhbiBzaW1wbHkgaGlkZSB0aGUgY29udHJvbC5cbiAqXG4gKiBgYGBcbiAqIDxzdHlsZT5cbiAqXG4gKiBteS1jdXN0b20tZWxlbWVudDpub3QoOmRlZmluZWQpIHtcbiAqICAgICBkaXNwbGF5OiBub25lO1xuICogfVxuICpcbiAqIG15LWN1c3RvbS1lbGVtZW50OmRlZmluZWQge1xuICogICAgIGRpc3BsYXk6IGZsZXg7XG4gKiB9XG4gKlxuICogPC9zdHlsZT5cbiAqIGBgYFxuICpcbiAqIEFsdGVybmF0aXZlbHkgeW91IGNhbiBhbHNvIGRpc3BsYXkgYSBsb2FkZXJcbiAqXG4gKiBgYGBcbiAqIG15LWN1c3RvbS1lbGVtZW50Om5vdCg6ZGVmaW5lZCkge1xuICogICAgICAgICAgICBkaXNwbGF5OiBmbGV4O1xuICogICAgICAgICAgICBib3gtc2hhZG93OiAwIDRweCAxMHB4IDAgcmdiYSgzMywgMzMsIDMzLCAwLjE1KTtcbiAqICAgICAgICAgICAgYm9yZGVyLXJhZGl1czogNHB4O1xuICogICAgICAgICAgICBoZWlnaHQ6IDIwMHB4O1xuICogICAgICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gKiAgICAgICAgICAgIG92ZXJmbG93OiBoaWRkZW47XG4gKiAgICAgICAgfVxuICpcbiAqIG15LWN1c3RvbS1lbGVtZW50Om5vdCg6ZGVmaW5lZCk6OmJlZm9yZSB7XG4gKiAgICAgICAgICAgIGNvbnRlbnQ6ICcnO1xuICogICAgICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAqICAgICAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICogICAgICAgICAgICBsZWZ0OiAtMTUwcHg7XG4gKiAgICAgICAgICAgIHRvcDogMDtcbiAqICAgICAgICAgICAgaGVpZ2h0OiAxMDAlO1xuICogICAgICAgICAgICB3aWR0aDogMTUwcHg7XG4gKiAgICAgICAgICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCh0byByaWdodCwgdHJhbnNwYXJlbnQgMCUsICNFOEU4RTggNTAlLCB0cmFuc3BhcmVudCAxMDAlKTtcbiAqICAgICAgICAgICAgYW5pbWF0aW9uOiBsb2FkIDFzIGN1YmljLWJlemllcigwLjQsIDAuMCwgMC4yLCAxKSBpbmZpbml0ZTtcbiAqICAgICAgICB9XG4gKlxuICogQGtleWZyYW1lcyBsb2FkIHtcbiAqICAgICAgICAgICAgZnJvbSB7XG4gKiAgICAgICAgICAgICAgICBsZWZ0OiAtMTUwcHg7XG4gKiAgICAgICAgICAgIH1cbiAqICAgICAgICAgICAgdG8gICB7XG4gKiAgICAgICAgICAgICAgICBsZWZ0OiAxMDAlO1xuICogICAgICAgICAgICB9XG4gKiAgICAgICAgfVxuICpcbiAqIG15LWN1c3RvbS1lbGVtZW50OmRlZmluZWQge1xuICogICAgICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gKiAgICAgICB9XG4gKiBgYGBcbiAqXG4gKiBAZXh0ZXJuYWxFeGFtcGxlIC4uLy4uL2V4YW1wbGUvZG9tL3RoZW1lLm1qc1xuICogQHNlZSBodHRwczovL2dpdGh1Yi5jb20vV0lDRy93ZWJjb21wb25lbnRzXG4gKiBAc2VlIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL2N1c3RvbS1lbGVtZW50cy5odG1sI2N1c3RvbS1lbGVtZW50c1xuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS43LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEBleHRlbmRzIGV4dGVybmFsOkhUTUxFbGVtZW50XG4gKiBAc3VtbWFyeSBBIGJhc2UgY2xhc3MgZm9yIEhUTUw1IGN1c3RvbWNvbnRyb2xzXG4gKi9cbmNsYXNzIEN1c3RvbUVsZW1lbnQgZXh0ZW5kcyBIVE1MRWxlbWVudCB7XG4gICAgLyoqXG4gICAgICogQSBuZXcgb2JqZWN0IGlzIGNyZWF0ZWQuIEZpcnN0IHRoZSBgaW5pdE9wdGlvbnNgIG1ldGhvZCBpcyBjYWxsZWQuIEhlcmUgdGhlXG4gICAgICogb3B0aW9ucyBjYW4gYmUgZGVmaW5lZCBpbiBkZXJpdmVkIGNsYXNzZXMuIFN1YnNlcXVlbnRseSwgdGhlIHNoYWRvd1Jvb3QgaXMgaW5pdGlhbGl6ZWQuXG4gICAgICpcbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gdGhlIG9wdGlvbnMgYXR0cmlidXRlIGRvZXMgbm90IGNvbnRhaW4gYSB2YWxpZCBqc29uIGRlZmluaXRpb24uXG4gICAgICogQHNpbmNlIDEuNy4wXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXNbaW50ZXJuYWxTeW1ib2xdID0gbmV3IFByb3h5T2JzZXJ2ZXIoe1xuICAgICAgICAgICAgb3B0aW9uczogZXh0ZW5kKHt9LCB0aGlzLmRlZmF1bHRzKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXNbYXR0cmlidXRlT2JzZXJ2ZXJTeW1ib2xdID0ge307XG4gICAgICAgIGluaXRPcHRpb25PYnNlcnZlci5jYWxsKHRoaXMpO1xuICAgICAgICB0aGlzW2luaXRNZXRob2RTeW1ib2xdKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMi4xLjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci9kb20vY3VzdG9tLWVsZW1lbnRcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgZGV0ZXJtaW5lcyB3aGljaCBhdHRyaWJ1dGVzIGFyZSB0byBiZSBtb25pdG9yZWQgYnkgYGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjaygpYC5cbiAgICAgKlxuICAgICAqIEByZXR1cm4ge3N0cmluZ1tdfVxuICAgICAqIEBzaW5jZSAxLjE1LjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IG9ic2VydmVkQXR0cmlidXRlcygpIHtcbiAgICAgICAgcmV0dXJuIFtBVFRSSUJVVEVfT1BUSU9OUywgQVRUUklCVVRFX0RJU0FCTEVEXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZXJpdmVkIGNsYXNzZXMgY2FuIG92ZXJyaWRlIGFuZCBleHRlbmQgdGhpcyBtZXRob2QgYXMgZm9sbG93cy5cbiAgICAgKlxuICAgICAqIGBgYFxuICAgICAqIGdldCBkZWZhdWx0cygpIHtcbiAgICAgKiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3VwZXIuZGVmYXVsdHMsIHtcbiAgICAgKiAgICAgICAgbXlWYWx1ZTp0cnVlXG4gICAgICogICAgfSk7XG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogVG8gc2V0IHRoZSBvcHRpb25zIHZpYSB0aGUgaHRtbCB0YWcgdGhlIGF0dHJpYnV0ZSBkYXRhLW1vbnN0ZXItb3B0aW9ucyBtdXN0IGJlIHNldC5cbiAgICAgKiBBcyB2YWx1ZSBhIEpTT04gb2JqZWN0IHdpdGggdGhlIGRlc2lyZWQgdmFsdWVzIG11c3QgYmUgZGVmaW5lZC5cbiAgICAgKlxuICAgICAqIFNpbmNlIDEuMTguMCB0aGUgSlNPTiBjYW4gYmUgc3BlY2lmaWVkIGFzIGEgRGF0YVVSSS5cbiAgICAgKlxuICAgICAqIGBgYFxuICAgICAqIG5ldyBNb25zdGVyLlR5cGVzLkRhdGFVcmwoYnRvYShKU09OLnN0cmluZ2lmeSh7XG4gICAgICogICAgICAgIHNoYWRvd01vZGU6ICdvcGVuJyxcbiAgICAgKiAgICAgICAgZGVsZWdhdGVzRm9jdXM6IHRydWUsXG4gICAgICogICAgICAgIHRlbXBsYXRlczoge1xuICAgICAqICAgICAgICAgICAgbWFpbjogdW5kZWZpbmVkXG4gICAgICogICAgICAgIH1cbiAgICAgKiAgICB9KSksJ2FwcGxpY2F0aW9uL2pzb24nLHRydWUpLnRvU3RyaW5nKClcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFRoZSBhdHRyaWJ1dGUgZGF0YS1tb25zdGVyLW9wdGlvbnMtc2VsZWN0b3IgY2FuIGJlIHVzZWQgdG8gYWNjZXNzIGEgc2NyaXB0IHRhZyB0aGF0IGNvbnRhaW5zIGFkZGl0aW9uYWwgY29uZmlndXJhdGlvbi5cbiAgICAgKlxuICAgICAqIEFzIHZhbHVlIGEgc2VsZWN0b3IgbXVzdCBiZSBzcGVjaWZpZWQsIHdoaWNoIGJlbG9uZ3MgdG8gYSBzY3JpcHQgdGFnIGFuZCBjb250YWlucyB0aGUgY29uZmlndXJhdGlvbiBhcyBqc29uLlxuICAgICAqXG4gICAgICogYGBgXG4gICAgICogPHNjcmlwdCBpZD1cImlkLWZvci10aGlzLWNvbmZpZ1wiIHR5cGU9XCJhcHBsaWNhdGlvbi9qc29uXCI+XG4gICAgICogICAge1xuICAgICAqICAgICAgICBcImNvbmZpZy1rZXlcIjogXCJjb25maWctdmFsdWVcIlxuICAgICAqICAgIH1cbiAgICAgKiA8L3NjcmlwdD5cbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFRoZSBpbmRpdmlkdWFsIGNvbmZpZ3VyYXRpb24gdmFsdWVzIGNhbiBiZSBmb3VuZCBpbiB0aGUgdGFibGUuXG4gICAgICpcbiAgICAgKiBAcHJvcGVydHkge2Jvb2xlYW59IGRpc2FibGVkPWZhbHNlIE9iamVjdCBUaGUgQm9vbGVhbiBkaXNhYmxlZCBhdHRyaWJ1dGUsIHdoZW4gcHJlc2VudCwgbWFrZXMgdGhlIGVsZW1lbnQgbm90IG11dGFibGUsIGZvY3VzYWJsZSwgb3IgZXZlbiBzdWJtaXR0ZWQgd2l0aCB0aGUgZm9ybS5cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gc2hhZG93TW9kZT1vcGVuIGBvcGVuYCBFbGVtZW50cyBvZiB0aGUgc2hhZG93IHJvb3QgYXJlIGFjY2Vzc2libGUgZnJvbSBKYXZhU2NyaXB0IG91dHNpZGUgdGhlIHJvb3QsIGZvciBleGFtcGxlIHVzaW5nLiBgY2xvc2VgIERlbmllcyBhY2Nlc3MgdG8gdGhlIG5vZGUocykgb2YgYSBjbG9zZWQgc2hhZG93IHJvb3QgZnJvbSBKYXZhU2NyaXB0IG91dHNpZGUgaXRcbiAgICAgKiBAcHJvcGVydHkge0Jvb2xlYW59IGRlbGVnYXRlc0ZvY3VzPXRydWUgQSBib29sZWFuIHRoYXQsIHdoZW4gc2V0IHRvIHRydWUsIHNwZWNpZmllcyBiZWhhdmlvciB0aGF0IG1pdGlnYXRlcyBjdXN0b20gZWxlbWVudCBpc3N1ZXMgYXJvdW5kIGZvY3VzYWJpbGl0eS4gV2hlbiBhIG5vbi1mb2N1c2FibGUgcGFydCBvZiB0aGUgc2hhZG93IERPTSBpcyBjbGlja2VkLCB0aGUgZmlyc3QgZm9jdXNhYmxlIHBhcnQgaXMgZ2l2ZW4gZm9jdXMsIGFuZCB0aGUgc2hhZG93IGhvc3QgaXMgZ2l2ZW4gYW55IGF2YWlsYWJsZSA6Zm9jdXMgc3R5bGluZy5cbiAgICAgKiBAcHJvcGVydHkge09iamVjdH0gdGVtcGxhdGVzIFRlbXBsYXRlc1xuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB0ZW1wbGF0ZXMubWFpbj11bmRlZmluZWQgTWFpbiB0ZW1wbGF0ZVxuICAgICAqIEBwcm9wZXJ0eSB7T2JqZWN0fSB0ZW1wbGF0ZU1hcHBpbmcgVGVtcGxhdGUgbWFwcGluZ1xuICAgICAqXG4gICAgICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRWxlbWVudC9hdHRhY2hTaGFkb3dcbiAgICAgKiBAc2luY2UgMS44LjBcbiAgICAgKi9cbiAgICBnZXQgZGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBBVFRSSUJVVEVfRElTQUJMRUQ6IHRoaXMuZ2V0QXR0cmlidXRlKEFUVFJJQlVURV9ESVNBQkxFRCksXG4gICAgICAgICAgICBzaGFkb3dNb2RlOiBcIm9wZW5cIixcbiAgICAgICAgICAgIGRlbGVnYXRlc0ZvY3VzOiB0cnVlLFxuICAgICAgICAgICAgdGVtcGxhdGVzOiB7XG4gICAgICAgICAgICAgICAgbWFpbjogdW5kZWZpbmVkLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRlbXBsYXRlTWFwcGluZzoge30sXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgdXBkYXRlcyB0aGUgbGFiZWxzIG9mIHRoZSBlbGVtZW50LlxuICAgICAqIFRoZSBsYWJlbHMgYXJlIGRlZmluZWQgaW4gdGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIFRoZSBrZXkgb2YgdGhlIGxhYmVsIGlzIHVzZWQgdG8gcmV0cmlldmUgdGhlIHRyYW5zbGF0aW9uIGZyb20gdGhlIGRvY3VtZW50LlxuICAgICAqIElmIHRoZSB0cmFuc2xhdGlvbiBpcyBkaWZmZXJlbnQgZnJvbSB0aGUgbGFiZWwsIHRoZSBsYWJlbCBpcyB1cGRhdGVkLlxuICAgICAqXG4gICAgICogQmVmb3JlIHlvdSBjYW4gdXNlIHRoaXMgbWV0aG9kLCB5b3UgbXVzdCBoYXZlIGxvYWRlZCB0aGUgdHJhbnNsYXRpb25zLlxuICAgICAqXG4gICAgICogQHJldHVybnMge01vbnN0ZXIuRE9NLkN1c3RvbUVsZW1lbnR9XG4gICAgICogQHRocm93cyB7RXJyb3J9ICBDYW5ub3QgZmluZCBlbGVtZW50IHdpdGggdHJhbnNsYXRpb25zLiBBZGQgYSB0cmFuc2xhdGlvbnMgb2JqZWN0IHRvIHRoZSBkb2N1bWVudC5cbiAgICAgKi9cbiAgICB1cGRhdGVJMThuKCkge1xuICAgICAgICBjb25zdCB0cmFuc2xhdGlvbnMgPSBnZXREb2N1bWVudFRyYW5zbGF0aW9ucygpO1xuICAgICAgICBpZiAoIXRyYW5zbGF0aW9ucykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgbGFiZWxzID0gdGhpcy5nZXRPcHRpb24oXCJsYWJlbHNcIik7XG4gICAgICAgIGlmICghKGlzT2JqZWN0KGxhYmVscykgfHwgaXNJdGVyYWJsZShsYWJlbHMpKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBsYWJlbHMpIHtcbiAgICAgICAgICAgIGNvbnN0IGRlZiA9IGxhYmVsc1trZXldO1xuXG4gICAgICAgICAgICBpZiAoaXNTdHJpbmcoZGVmKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRleHQgPSB0cmFuc2xhdGlvbnMuZ2V0VGV4dChrZXksIGRlZik7XG4gICAgICAgICAgICAgICAgaWYgKHRleHQgIT09IGRlZikge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldE9wdGlvbihgbGFiZWxzLiR7a2V5fWAsIHRleHQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNPYmplY3QoZGVmKSkge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgayBpbiBkZWYpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZCA9IGRlZltrXTtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCB0ZXh0ID0gdHJhbnNsYXRpb25zLmdldFBsdXJhbFJ1bGVUZXh0KGtleSwgaywgZCk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghaXNTdHJpbmcodGV4dCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgbGFiZWxzIGRlZmluaXRpb25cIik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHRleHQgIT09IGQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0T3B0aW9uKGBsYWJlbHMuJHtrZXl9LiR7a31gLCB0ZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBsYWJlbHMgZGVmaW5pdGlvblwiKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGVyZSBpcyBubyBjaGVjayBvbiB0aGUgbmFtZSBieSB0aGlzIGNsYXNzLiB0aGUgZGV2ZWxvcGVyIGlzIHJlc3BvbnNpYmxlIGZvciBhc3NpZ25pbmcgYW4gYXBwcm9wcmlhdGUgdGFnLlxuICAgICAqIGlmIHRoZSBuYW1lIGlzIG5vdCB2YWxpZCwgcmVnaXN0ZXJDdXN0b21FbGVtZW50KCkgd2lsbCBpc3N1ZSBhbiBlcnJvclxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2UvY3VzdG9tLWVsZW1lbnRzLmh0bWwjdmFsaWQtY3VzdG9tLWVsZW1lbnQtbmFtZVxuICAgICAqIEByZXR1cm4ge3N0cmluZ31cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gdGhlIG1ldGhvZCBnZXRUYWcgbXVzdCBiZSBvdmVyd3JpdHRlbiBieSB0aGUgZGVyaXZlZCBjbGFzcy5cbiAgICAgKiBAc2luY2UgMS43LjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0VGFnKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0aGUgbWV0aG9kIGdldFRhZyBtdXN0IGJlIG92ZXJ3cml0dGVuIGJ5IHRoZSBkZXJpdmVkIGNsYXNzLlwiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBdCB0aGlzIHBvaW50IGEgYENTU1N0eWxlU2hlZXRgIG9iamVjdCBjYW4gYmUgcmV0dXJuZWQuIElmIHRoZSBlbnZpcm9ubWVudCBkb2VzIG5vdFxuICAgICAqIHN1cHBvcnQgYSBjb25zdHJ1Y3RvciwgdGhlbiBhbiBvYmplY3QgY2FuIGFsc28gYmUgYnVpbHQgdXNpbmcgdGhlIGZvbGxvd2luZyBkZXRvdXIuXG4gICAgICpcbiAgICAgKiBJZiBgdW5kZWZpbmVkYCBpcyByZXR1cm5lZCB0aGVuIHRoZSBzaGFkb3dSb290IGRvZXMgbm90IGdldCBhIHN0eWxlc2hlZXQuXG4gICAgICpcbiAgICAgKiBgYGBcbiAgICAgKiBjb25zdCBkb2MgPSBkb2N1bWVudC5pbXBsZW1lbnRhdGlvbi5jcmVhdGVIVE1MRG9jdW1lbnQoJ3RpdGxlJyk7XG4gICAgICpcbiAgICAgKiBsZXQgc3R5bGUgPSBkb2MuY3JlYXRlRWxlbWVudChcInN0eWxlXCIpO1xuICAgICAqIHN0eWxlLmlubmVySFRNTD1cInB7Y29sb3I6cmVkO31cIjtcbiAgICAgKlxuICAgICAqIC8vIFdlYktpdCBIYWNrXG4gICAgICogc3R5bGUuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoXCJcIikpO1xuICAgICAqIC8vIEFkZCB0aGUgPHN0eWxlPiBlbGVtZW50IHRvIHRoZSBwYWdlXG4gICAgICogZG9jLmhlYWQuYXBwZW5kQ2hpbGQoc3R5bGUpO1xuICAgICAqIHJldHVybiBkb2Muc3R5bGVTaGVldHNbMF07XG4gICAgICogO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQHJldHVybiB7Q1NTU3R5bGVTaGVldHxDU1NTdHlsZVNoZWV0W118c3RyaW5nfHVuZGVmaW5lZH1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0Q1NTU3R5bGVTaGVldCgpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBhdHRhY2ggYSBuZXcgb2JzZXJ2ZXJcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7T2JzZXJ2ZXJ9IG9ic2VydmVyXG4gICAgICogQHJldHVybnMge0N1c3RvbUVsZW1lbnR9XG4gICAgICovXG4gICAgYXR0YWNoT2JzZXJ2ZXIob2JzZXJ2ZXIpIHtcbiAgICAgICAgdGhpc1tpbnRlcm5hbFN5bWJvbF0uYXR0YWNoT2JzZXJ2ZXIob2JzZXJ2ZXIpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBkZXRhY2ggYSBvYnNlcnZlclxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYnNlcnZlcn0gb2JzZXJ2ZXJcbiAgICAgKiBAcmV0dXJucyB7Q3VzdG9tRWxlbWVudH1cbiAgICAgKi9cbiAgICBkZXRhY2hPYnNlcnZlcihvYnNlcnZlcikge1xuICAgICAgICB0aGlzW2ludGVybmFsU3ltYm9sXS5kZXRhY2hPYnNlcnZlcihvYnNlcnZlcik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7T2JzZXJ2ZXJ9IG9ic2VydmVyXG4gICAgICogQHJldHVybnMge1Byb3h5T2JzZXJ2ZXJ9XG4gICAgICovXG4gICAgY29udGFpbnNPYnNlcnZlcihvYnNlcnZlcikge1xuICAgICAgICByZXR1cm4gdGhpc1tpbnRlcm5hbFN5bWJvbF0uY29udGFpbnNPYnNlcnZlcihvYnNlcnZlcik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogbmVzdGVkIG9wdGlvbnMgY2FuIGJlIHNwZWNpZmllZCBieSBwYXRoIGBhLmIuY2BcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoXG4gICAgICogQHBhcmFtIHsqfSBkZWZhdWx0VmFsdWVcbiAgICAgKiBAcmV0dXJuIHsqfVxuICAgICAqIEBzaW5jZSAxLjEwLjBcbiAgICAgKi9cbiAgICBnZXRPcHRpb24ocGF0aCwgZGVmYXVsdFZhbHVlKSB7XG4gICAgICAgIGxldCB2YWx1ZTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdmFsdWUgPSBuZXcgUGF0aGZpbmRlcih0aGlzW2ludGVybmFsU3ltYm9sXS5nZXRSZWFsU3ViamVjdCgpW1wib3B0aW9uc1wiXSkuZ2V0VmlhKHBhdGgpO1xuICAgICAgICB9IGNhdGNoIChlKSB7fVxuXG4gICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSByZXR1cm4gZGVmYXVsdFZhbHVlO1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IG9wdGlvbiBhbmQgaW5mb3JtIGVsZW1lbnRzXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcGF0aFxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAgICAgKiBAcmV0dXJuIHtDdXN0b21FbGVtZW50fVxuICAgICAqIEBzaW5jZSAxLjE0LjBcbiAgICAgKi9cbiAgICBzZXRPcHRpb24ocGF0aCwgdmFsdWUpIHtcbiAgICAgICAgbmV3IFBhdGhmaW5kZXIodGhpc1tpbnRlcm5hbFN5bWJvbF0uZ2V0U3ViamVjdCgpW1wib3B0aW9uc1wiXSkuc2V0VmlhKHBhdGgsIHZhbHVlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHNpbmNlIDEuMTUuMFxuICAgICAqIEBwYXJhbSB7c3RyaW5nfG9iamVjdH0gb3B0aW9uc1xuICAgICAqIEByZXR1cm4ge0N1c3RvbUVsZW1lbnR9XG4gICAgICovXG4gICAgc2V0T3B0aW9ucyhvcHRpb25zKSB7XG4gICAgICAgIGlmIChpc1N0cmluZyhvcHRpb25zKSkge1xuICAgICAgICAgICAgb3B0aW9ucyA9IHBhcnNlT3B0aW9uc0pTT04uY2FsbCh0aGlzLCBvcHRpb25zKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgICAgICBleHRlbmQoc2VsZltpbnRlcm5hbFN5bWJvbF0uZ2V0U3ViamVjdCgpW1wib3B0aW9uc1wiXSwgc2VsZi5kZWZhdWx0cywgb3B0aW9ucyk7XG5cbiAgICAgICAgcmV0dXJuIHNlbGY7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSXMgY2FsbGVkIG9uY2UgdmlhIHRoZSBjb25zdHJ1Y3RvclxuICAgICAqXG4gICAgICogQHJldHVybiB7Q3VzdG9tRWxlbWVudH1cbiAgICAgKiBAc2luY2UgMS44LjBcbiAgICAgKi9cbiAgICBbaW5pdE1ldGhvZFN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIElzIGNhbGxlZCBvbmNlIHdoZW4gdGhlIG9iamVjdCBpcyBpbmNsdWRlZCBpbiB0aGUgRE9NIGZvciB0aGUgZmlyc3QgdGltZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm4ge0N1c3RvbUVsZW1lbnR9XG4gICAgICogQHNpbmNlIDEuOC4wXG4gICAgICovXG4gICAgW2Fzc2VtYmxlTWV0aG9kU3ltYm9sXSgpIHtcbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgICAgIGxldCBlbGVtZW50cztcbiAgICAgICAgbGV0IG5vZGVMaXN0O1xuXG4gICAgICAgIGNvbnN0IEF0dHJpYnV0ZU9wdGlvbnMgPSBnZXRPcHRpb25zRnJvbUF0dHJpYnV0ZXMuY2FsbChzZWxmKTtcbiAgICAgICAgaWYgKGlzT2JqZWN0KEF0dHJpYnV0ZU9wdGlvbnMpICYmIE9iamVjdC5rZXlzKEF0dHJpYnV0ZU9wdGlvbnMpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHNlbGYuc2V0T3B0aW9ucyhBdHRyaWJ1dGVPcHRpb25zKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IFNjcmlwdE9wdGlvbnMgPSBnZXRPcHRpb25zRnJvbVNjcmlwdFRhZy5jYWxsKHNlbGYpO1xuICAgICAgICBpZiAoaXNPYmplY3QoU2NyaXB0T3B0aW9ucykgJiYgT2JqZWN0LmtleXMoU2NyaXB0T3B0aW9ucykubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgc2VsZi5zZXRPcHRpb25zKFNjcmlwdE9wdGlvbnMpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNlbGYuZ2V0T3B0aW9uKFwic2hhZG93TW9kZVwiLCBmYWxzZSkgIT09IGZhbHNlKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGluaXRTaGFkb3dSb290LmNhbGwoc2VsZik7XG4gICAgICAgICAgICAgICAgZWxlbWVudHMgPSBzZWxmLnNoYWRvd1Jvb3QuY2hpbGROb2RlcztcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHt9XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaW5pdENTU1N0eWxlc2hlZXQuY2FsbCh0aGlzKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBhZGRBdHRyaWJ1dGVUb2tlbihzZWxmLCBBVFRSSUJVVEVfRVJST1JNRVNTQUdFLCBlLnRvU3RyaW5nKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCEoZWxlbWVudHMgaW5zdGFuY2VvZiBOb2RlTGlzdCkpIHtcbiAgICAgICAgICAgIGlmICghKGVsZW1lbnRzIGluc3RhbmNlb2YgTm9kZUxpc3QpKSB7XG4gICAgICAgICAgICAgICAgaW5pdEh0bWxDb250ZW50LmNhbGwodGhpcyk7XG4gICAgICAgICAgICAgICAgZWxlbWVudHMgPSB0aGlzLmNoaWxkTm9kZXM7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbm9kZUxpc3QgPSBuZXcgU2V0KFsuLi5lbGVtZW50cywgLi4uZ2V0U2xvdHRlZEVsZW1lbnRzLmNhbGwoc2VsZildKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgbm9kZUxpc3QgPSBlbGVtZW50cztcbiAgICAgICAgfVxuXG4gICAgICAgIGFkZE9iamVjdFdpdGhVcGRhdGVyVG9FbGVtZW50LmNhbGwoXG4gICAgICAgICAgICBzZWxmLFxuICAgICAgICAgICAgbm9kZUxpc3QsXG4gICAgICAgICAgICBjdXN0b21FbGVtZW50VXBkYXRlckxpbmtTeW1ib2wsXG4gICAgICAgICAgICBjbG9uZShzZWxmW2ludGVybmFsU3ltYm9sXS5nZXRSZWFsU3ViamVjdCgpW1wib3B0aW9uc1wiXSksXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiBzZWxmO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbGxlZCBldmVyeSB0aW1lIHRoZSBlbGVtZW50IGlzIGluc2VydGVkIGludG8gdGhlIERPTS4gVXNlZnVsIGZvciBydW5uaW5nIHNldHVwIGNvZGUsIHN1Y2ggYXNcbiAgICAgKiBmZXRjaGluZyByZXNvdXJjZXMgb3IgcmVuZGVyaW5nLiBHZW5lcmFsbHksIHlvdSBzaG91bGQgdHJ5IHRvIGRlbGF5IHdvcmsgdW50aWwgdGhpcyB0aW1lLlxuICAgICAqXG4gICAgICogQHJldHVybiB7dm9pZH1cbiAgICAgKiBAc2luY2UgMS43LjBcbiAgICAgKi9cbiAgICBjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICAgICAgbGV0IHNlbGYgPSB0aGlzO1xuICAgICAgICBpZiAoIWhhc09iamVjdExpbmsoc2VsZiwgY3VzdG9tRWxlbWVudFVwZGF0ZXJMaW5rU3ltYm9sKSkge1xuICAgICAgICAgICAgc2VsZlthc3NlbWJsZU1ldGhvZFN5bWJvbF0oKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbGxlZCBldmVyeSB0aW1lIHRoZSBlbGVtZW50IGlzIHJlbW92ZWQgZnJvbSB0aGUgRE9NLiBVc2VmdWwgZm9yIHJ1bm5pbmcgY2xlYW4gdXAgY29kZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm4ge3ZvaWR9XG4gICAgICogQHNpbmNlIDEuNy4wXG4gICAgICovXG4gICAgZGlzY29ubmVjdGVkQ2FsbGJhY2soKSB7fVxuXG4gICAgLyoqXG4gICAgICogVGhlIGN1c3RvbSBlbGVtZW50IGhhcyBiZWVuIG1vdmVkIGludG8gYSBuZXcgZG9jdW1lbnQgKGUuZy4gc29tZW9uZSBjYWxsZWQgZG9jdW1lbnQuYWRvcHROb2RlKGVsKSkuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgICAqIEBzaW5jZSAxLjcuMFxuICAgICAqL1xuICAgIGFkb3B0ZWRDYWxsYmFjaygpIHt9XG5cbiAgICAvKipcbiAgICAgKiBDYWxsZWQgd2hlbiBhbiBvYnNlcnZlZCBhdHRyaWJ1dGUgaGFzIGJlZW4gYWRkZWQsIHJlbW92ZWQsIHVwZGF0ZWQsIG9yIHJlcGxhY2VkLiBBbHNvIGNhbGxlZCBmb3IgaW5pdGlhbFxuICAgICAqIHZhbHVlcyB3aGVuIGFuIGVsZW1lbnQgaXMgY3JlYXRlZCBieSB0aGUgcGFyc2VyLCBvciB1cGdyYWRlZC4gTm90ZTogb25seSBhdHRyaWJ1dGVzIGxpc3RlZCBpbiB0aGUgb2JzZXJ2ZWRBdHRyaWJ1dGVzXG4gICAgICogcHJvcGVydHkgd2lsbCByZWNlaXZlIHRoaXMgY2FsbGJhY2suXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gYXR0ck5hbWVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gb2xkVmFsXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5ld1ZhbFxuICAgICAqIEByZXR1cm4ge3ZvaWR9XG4gICAgICogQHNpbmNlIDEuMTUuMFxuICAgICAqL1xuICAgIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhhdHRyTmFtZSwgb2xkVmFsLCBuZXdWYWwpIHtcbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICAgICAgY29uc3QgY2FsbGJhY2sgPSBzZWxmW2F0dHJpYnV0ZU9ic2VydmVyU3ltYm9sXT8uW2F0dHJOYW1lXTtcblxuICAgICAgICBpZiAoaXNGdW5jdGlvbihjYWxsYmFjaykpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrLmNhbGwoc2VsZiwgbmV3VmFsLCBvbGRWYWwpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge05vZGV9IG5vZGVcbiAgICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGFuIGluc3RhbmNlIG9mXG4gICAgICogQHNpbmNlIDEuMTkuMFxuICAgICAqL1xuICAgIGhhc05vZGUobm9kZSkge1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgICAgICBpZiAoY29udGFpbkNoaWxkTm9kZS5jYWxsKHNlbGYsIHZhbGlkYXRlSW5zdGFuY2Uobm9kZSwgTm9kZSkpKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghKHNlbGYuc2hhZG93Um9vdCBpbnN0YW5jZW9mIFNoYWRvd1Jvb3QpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gY29udGFpbkNoaWxkTm9kZS5jYWxsKHNlbGYuc2hhZG93Um9vdCwgbm9kZSk7XG4gICAgfVxufVxuXG4vKipcbiAqIEB0aGlzIEN1c3RvbUVsZW1lbnRcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge05vZGV9IG5vZGVcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIGNvbnRhaW5DaGlsZE5vZGUobm9kZSkge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgaWYgKHNlbGYuY29udGFpbnMobm9kZSkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBbLCBlXSBvZiBPYmplY3QuZW50cmllcyhzZWxmLmNoaWxkTm9kZXMpKSB7XG4gICAgICAgIGlmIChlLmNvbnRhaW5zKG5vZGUpKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnRhaW5DaGlsZE5vZGUuY2FsbChlLCBub2RlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4xNS4wXG4gKiBAcHJpdmF0ZVxuICogQHRoaXMgQ3VzdG9tRWxlbWVudFxuICovXG5mdW5jdGlvbiBpbml0T3B0aW9uT2JzZXJ2ZXIoKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICBsZXQgbGFzdERpc2FibGVkVmFsdWUgPSB1bmRlZmluZWQ7XG4gICAgc2VsZi5hdHRhY2hPYnNlcnZlcihcbiAgICAgICAgbmV3IE9ic2VydmVyKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IGZsYWcgPSBzZWxmLmdldE9wdGlvbihcImRpc2FibGVkXCIpO1xuXG4gICAgICAgICAgICBpZiAoZmxhZyA9PT0gbGFzdERpc2FibGVkVmFsdWUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxhc3REaXNhYmxlZFZhbHVlID0gZmxhZztcblxuICAgICAgICAgICAgaWYgKCEoc2VsZi5zaGFkb3dSb290IGluc3RhbmNlb2YgU2hhZG93Um9vdCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHF1ZXJ5ID1cbiAgICAgICAgICAgICAgICBcImJ1dHRvbiwgY29tbWFuZCwgZmllbGRzZXQsIGtleWdlbiwgb3B0Z3JvdXAsIG9wdGlvbiwgc2VsZWN0LCB0ZXh0YXJlYSwgaW5wdXQsIFtkYXRhLW1vbnN0ZXItb2JqZWN0bGlua11cIjtcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnRzID0gc2VsZi5zaGFkb3dSb290LnF1ZXJ5U2VsZWN0b3JBbGwocXVlcnkpO1xuXG4gICAgICAgICAgICBsZXQgbm9kZUxpc3Q7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIG5vZGVMaXN0ID0gbmV3IFNldChbLi4uZWxlbWVudHMsIC4uLmdldFNsb3R0ZWRFbGVtZW50cy5jYWxsKHNlbGYsIHF1ZXJ5KV0pO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIG5vZGVMaXN0ID0gZWxlbWVudHM7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiBbLi4ubm9kZUxpc3RdKSB7XG4gICAgICAgICAgICAgICAgaWYgKGZsYWcgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoQVRUUklCVVRFX0RJU0FCTEVELCBcIlwiKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnJlbW92ZUF0dHJpYnV0ZShBVFRSSUJVVEVfRElTQUJMRUQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSksXG4gICAgKTtcblxuICAgIHNlbGYuYXR0YWNoT2JzZXJ2ZXIoXG4gICAgICAgIG5ldyBPYnNlcnZlcihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAvLyBub3QgaW5pdGlhbGlzZWRcbiAgICAgICAgICAgIGlmICghaGFzT2JqZWN0TGluayhzZWxmLCBjdXN0b21FbGVtZW50VXBkYXRlckxpbmtTeW1ib2wpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gaW5mb3JtIGV2ZXJ5IGVsZW1lbnRcbiAgICAgICAgICAgIGNvbnN0IHVwZGF0ZXJzID0gZ2V0TGlua2VkT2JqZWN0cyhzZWxmLCBjdXN0b21FbGVtZW50VXBkYXRlckxpbmtTeW1ib2wpO1xuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGxpc3Qgb2YgdXBkYXRlcnMpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHVwZGF0ZXIgb2YgbGlzdCkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgZCA9IGNsb25lKHNlbGZbaW50ZXJuYWxTeW1ib2xdLmdldFJlYWxTdWJqZWN0KClbXCJvcHRpb25zXCJdKTtcbiAgICAgICAgICAgICAgICAgICAgT2JqZWN0LmFzc2lnbih1cGRhdGVyLmdldFN1YmplY3QoKSwgZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KSxcbiAgICApO1xuXG4gICAgLy8gZGlzYWJsZWRcbiAgICBzZWxmW2F0dHJpYnV0ZU9ic2VydmVyU3ltYm9sXVtBVFRSSUJVVEVfRElTQUJMRURdID0gKCkgPT4ge1xuICAgICAgICBpZiAoc2VsZi5oYXNBdHRyaWJ1dGUoQVRUUklCVVRFX0RJU0FCTEVEKSkge1xuICAgICAgICAgICAgc2VsZi5zZXRPcHRpb24oQVRUUklCVVRFX0RJU0FCTEVELCB0cnVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNlbGYuc2V0T3B0aW9uKEFUVFJJQlVURV9ESVNBQkxFRCwgdW5kZWZpbmVkKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICAvLyBkYXRhLW1vbnN0ZXItb3B0aW9uc1xuICAgIHNlbGZbYXR0cmlidXRlT2JzZXJ2ZXJTeW1ib2xdW0FUVFJJQlVURV9PUFRJT05TXSA9ICgpID0+IHtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IGdldE9wdGlvbnNGcm9tQXR0cmlidXRlcy5jYWxsKHNlbGYpO1xuICAgICAgICBpZiAoaXNPYmplY3Qob3B0aW9ucykgJiYgT2JqZWN0LmtleXMob3B0aW9ucykubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgc2VsZi5zZXRPcHRpb25zKG9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIC8vIGRhdGEtbW9uc3Rlci1vcHRpb25zLXNlbGVjdG9yXG4gICAgc2VsZlthdHRyaWJ1dGVPYnNlcnZlclN5bWJvbF1bQVRUUklCVVRFX09QVElPTlNfU0VMRUNUT1JdID0gKCkgPT4ge1xuICAgICAgICBjb25zdCBvcHRpb25zID0gZ2V0T3B0aW9uc0Zyb21TY3JpcHRUYWcuY2FsbChzZWxmKTtcbiAgICAgICAgaWYgKGlzT2JqZWN0KG9wdGlvbnMpICYmIE9iamVjdC5rZXlzKG9wdGlvbnMpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHNlbGYuc2V0T3B0aW9ucyhvcHRpb25zKTtcbiAgICAgICAgfVxuICAgIH07XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEByZXR1cm4ge29iamVjdH1cbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgb2JqZWN0XG4gKi9cbmZ1bmN0aW9uIGdldE9wdGlvbnNGcm9tU2NyaXB0VGFnKCkge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgaWYgKCFzZWxmLmhhc0F0dHJpYnV0ZShBVFRSSUJVVEVfT1BUSU9OU19TRUxFQ1RPUikpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cblxuICAgIGNvbnN0IG5vZGUgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHNlbGYuZ2V0QXR0cmlidXRlKEFUVFJJQlVURV9PUFRJT05TX1NFTEVDVE9SKSk7XG4gICAgaWYgKCEobm9kZSBpbnN0YW5jZW9mIEhUTUxTY3JpcHRFbGVtZW50KSkge1xuICAgICAgICBhZGRBdHRyaWJ1dGVUb2tlbihcbiAgICAgICAgICAgIHNlbGYsXG4gICAgICAgICAgICBBVFRSSUJVVEVfRVJST1JNRVNTQUdFLFxuICAgICAgICAgICAgYHRoZSBzZWxlY3RvciAke0FUVFJJQlVURV9PUFRJT05TX1NFTEVDVE9SfSBmb3Igb3B0aW9ucyB3YXMgc3BlY2lmaWVkICgke3NlbGYuZ2V0QXR0cmlidXRlKFxuICAgICAgICAgICAgICAgIEFUVFJJQlVURV9PUFRJT05TX1NFTEVDVE9SLFxuICAgICAgICAgICAgKX0pIGJ1dCBub3QgZm91bmQuYCxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cblxuICAgIGxldCBvYmogPSB7fTtcblxuICAgIHRyeSB7XG4gICAgICAgIG9iaiA9IHBhcnNlT3B0aW9uc0pTT04uY2FsbCh0aGlzLCBub2RlLnRleHRDb250ZW50LnRyaW0oKSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBhZGRBdHRyaWJ1dGVUb2tlbihcbiAgICAgICAgICAgIHNlbGYsXG4gICAgICAgICAgICBBVFRSSUJVVEVfRVJST1JNRVNTQUdFLFxuICAgICAgICAgICAgYHdoZW4gYW5hbHl6aW5nIHRoZSBjb25maWd1cmF0aW9uIGZyb20gdGhlIHNjcmlwdCB0YWcgdGhlcmUgd2FzIGFuIGVycm9yLiAke2V9YCxcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gb2JqO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcmV0dXJuIHtvYmplY3R9XG4gKi9cbmZ1bmN0aW9uIGdldE9wdGlvbnNGcm9tQXR0cmlidXRlcygpIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgIGlmICh0aGlzLmhhc0F0dHJpYnV0ZShBVFRSSUJVVEVfT1BUSU9OUykpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiBwYXJzZU9wdGlvbnNKU09OLmNhbGwoc2VsZiwgdGhpcy5nZXRBdHRyaWJ1dGUoQVRUUklCVVRFX09QVElPTlMpKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgYWRkQXR0cmlidXRlVG9rZW4oXG4gICAgICAgICAgICAgICAgc2VsZixcbiAgICAgICAgICAgICAgICBBVFRSSUJVVEVfRVJST1JNRVNTQUdFLFxuICAgICAgICAgICAgICAgIGB0aGUgb3B0aW9ucyBhdHRyaWJ1dGUgJHtBVFRSSUJVVEVfT1BUSU9OU30gZG9lcyBub3QgY29udGFpbiBhIHZhbGlkIGpzb24gZGVmaW5pdGlvbiAoYWN0dWFsOiAke3RoaXMuZ2V0QXR0cmlidXRlKFxuICAgICAgICAgICAgICAgICAgICBBVFRSSUJVVEVfT1BUSU9OUyxcbiAgICAgICAgICAgICAgICApfSkuJHtlfWAsXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHt9O1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0gZGF0YVxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBwYXJzZU9wdGlvbnNKU09OKGRhdGEpIHtcbiAgICBsZXQgb2JqID0ge307XG5cbiAgICBpZiAoIWlzU3RyaW5nKGRhdGEpKSB7XG4gICAgICAgIHJldHVybiBvYmo7XG4gICAgfVxuXG4gICAgLy8gdGhlIGNvbmZpZ3VyYXRpb24gY2FuIGJlIHNwZWNpZmllZCBhcyBhIGRhdGEgdXJsLlxuICAgIHRyeSB7XG4gICAgICAgIGxldCBkYXRhVXJsID0gcGFyc2VEYXRhVVJMKGRhdGEpO1xuICAgICAgICBkYXRhID0gZGF0YVVybC5jb250ZW50O1xuICAgIH0gY2F0Y2ggKGUpIHt9XG5cbiAgICB0cnkge1xuICAgICAgICBvYmogPSBKU09OLnBhcnNlKGRhdGEpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgdGhyb3cgZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsaWRhdGVPYmplY3Qob2JqKTtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHJldHVybiB7aW5pdEh0bWxDb250ZW50fVxuICovXG5mdW5jdGlvbiBpbml0SHRtbENvbnRlbnQoKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgbGV0IHRlbXBsYXRlID0gZmluZERvY3VtZW50VGVtcGxhdGUodGhpcy5jb25zdHJ1Y3Rvci5nZXRUYWcoKSk7XG4gICAgICAgIHRoaXMuYXBwZW5kQ2hpbGQodGVtcGxhdGUuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGxldCBodG1sID0gdGhpcy5nZXRPcHRpb24oXCJ0ZW1wbGF0ZXMubWFpblwiLCBcIlwiKTtcbiAgICAgICAgaWYgKGlzU3RyaW5nKGh0bWwpICYmIGh0bWwubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uc3QgbWFwcGluZyA9IHRoaXMuZ2V0T3B0aW9uKFwidGVtcGxhdGVNYXBwaW5nXCIsIHt9KTtcbiAgICAgICAgICAgIGlmIChpc09iamVjdChtYXBwaW5nKSkge1xuICAgICAgICAgICAgICAgIGh0bWwgPSBuZXcgRm9ybWF0dGVyKG1hcHBpbmcpLmZvcm1hdChodG1sKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuaW5uZXJIVE1MID0gaHRtbDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcmV0dXJuIHtDdXN0b21FbGVtZW50fVxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdGhpcyBDdXN0b21FbGVtZW50XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjE2LjBcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGFuIGluc3RhbmNlIG9mXG4gKi9cbmZ1bmN0aW9uIGluaXRDU1NTdHlsZXNoZWV0KCkge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgaWYgKCEodGhpcy5zaGFkb3dSb290IGluc3RhbmNlb2YgU2hhZG93Um9vdCkpIHtcbiAgICAgICAgcmV0dXJuIHNlbGY7XG4gICAgfVxuXG4gICAgY29uc3Qgc3R5bGVTaGVldCA9IHRoaXMuY29uc3RydWN0b3IuZ2V0Q1NTU3R5bGVTaGVldCgpO1xuXG4gICAgaWYgKHN0eWxlU2hlZXQgaW5zdGFuY2VvZiBDU1NTdHlsZVNoZWV0KSB7XG4gICAgICAgIGlmIChzdHlsZVNoZWV0LmNzc1J1bGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuc2hhZG93Um9vdC5hZG9wdGVkU3R5bGVTaGVldHMgPSBbc3R5bGVTaGVldF07XG4gICAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGlzQXJyYXkoc3R5bGVTaGVldCkpIHtcbiAgICAgICAgY29uc3QgYXNzaWduID0gW107XG4gICAgICAgIGZvciAobGV0IHMgb2Ygc3R5bGVTaGVldCkge1xuICAgICAgICAgICAgaWYgKGlzU3RyaW5nKHMpKSB7XG4gICAgICAgICAgICAgICAgbGV0IHRyaW1lZFN0eWxlU2hlZXQgPSBzLnRyaW0oKTtcbiAgICAgICAgICAgICAgICBpZiAodHJpbWVkU3R5bGVTaGVldCAhPT0gXCJcIikge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHlsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzdHlsZVwiKTtcbiAgICAgICAgICAgICAgICAgICAgc3R5bGUuaW5uZXJIVE1MID0gdHJpbWVkU3R5bGVTaGVldDtcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5zaGFkb3dSb290LnByZXBlbmQoc3R5bGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFsaWRhdGVJbnN0YW5jZShzLCBDU1NTdHlsZVNoZWV0KTtcblxuICAgICAgICAgICAgaWYgKHMuY3NzUnVsZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGFzc2lnbi5wdXNoKHMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGFzc2lnbi5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aGlzLnNoYWRvd1Jvb3QuYWRvcHRlZFN0eWxlU2hlZXRzID0gYXNzaWduO1xuICAgICAgICB9XG4gICAgfSBlbHNlIGlmIChpc1N0cmluZyhzdHlsZVNoZWV0KSkge1xuICAgICAgICBsZXQgdHJpbWVkU3R5bGVTaGVldCA9IHN0eWxlU2hlZXQudHJpbSgpO1xuICAgICAgICBpZiAodHJpbWVkU3R5bGVTaGVldCAhPT0gXCJcIikge1xuICAgICAgICAgICAgY29uc3Qgc3R5bGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3R5bGVcIik7XG4gICAgICAgICAgICBzdHlsZS5pbm5lckhUTUwgPSBzdHlsZVNoZWV0O1xuICAgICAgICAgICAgc2VsZi5zaGFkb3dSb290LnByZXBlbmQoc3R5bGUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHNlbGY7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEByZXR1cm4ge0N1c3RvbUVsZW1lbnR9XG4gKiBAdGhyb3dzIHtFcnJvcn0gaHRtbCBpcyBub3Qgc2V0LlxuICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRWxlbWVudC9hdHRhY2hTaGFkb3dcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS44LjBcbiAqL1xuZnVuY3Rpb24gaW5pdFNoYWRvd1Jvb3QoKSB7XG4gICAgbGV0IHRlbXBsYXRlO1xuICAgIGxldCBodG1sO1xuXG4gICAgdHJ5IHtcbiAgICAgICAgdGVtcGxhdGUgPSBmaW5kRG9jdW1lbnRUZW1wbGF0ZSh0aGlzLmNvbnN0cnVjdG9yLmdldFRhZygpKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGh0bWwgPSB0aGlzLmdldE9wdGlvbihcInRlbXBsYXRlcy5tYWluXCIsIFwiXCIpO1xuICAgICAgICBpZiAoIWlzU3RyaW5nKGh0bWwpIHx8IGh0bWwgPT09IHVuZGVmaW5lZCB8fCBodG1sID09PSBcIlwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJodG1sIGlzIG5vdCBzZXQuXCIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5hdHRhY2hTaGFkb3coe1xuICAgICAgICBtb2RlOiB0aGlzLmdldE9wdGlvbihcInNoYWRvd01vZGVcIiwgXCJvcGVuXCIpLFxuICAgICAgICBkZWxlZ2F0ZXNGb2N1czogdGhpcy5nZXRPcHRpb24oXCJkZWxlZ2F0ZXNGb2N1c1wiLCB0cnVlKSxcbiAgICB9KTtcblxuICAgIGlmICh0ZW1wbGF0ZSBpbnN0YW5jZW9mIFRlbXBsYXRlKSB7XG4gICAgICAgIHRoaXMuc2hhZG93Um9vdC5hcHBlbmRDaGlsZCh0ZW1wbGF0ZS5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBjb25zdCBtYXBwaW5nID0gdGhpcy5nZXRPcHRpb24oXCJ0ZW1wbGF0ZU1hcHBpbmdcIiwge30pO1xuICAgIGlmIChpc09iamVjdChtYXBwaW5nKSkge1xuICAgICAgICBodG1sID0gbmV3IEZvcm1hdHRlcihtYXBwaW5nKS5mb3JtYXQoaHRtbCk7XG4gICAgfVxuXG4gICAgdGhpcy5zaGFkb3dSb290LmlubmVySFRNTCA9IGh0bWw7XG4gICAgcmV0dXJuIHRoaXM7XG59XG5cbi8qKlxuICogVGhpcyBtZXRob2QgcmVnaXN0ZXJzIGEgbmV3IGVsZW1lbnQuIFRoZSBzdHJpbmcgcmV0dXJuZWQgYnkgYEN1c3RvbUVsZW1lbnQuZ2V0VGFnKClgIGlzIHVzZWQgYXMgdGhlIHRhZy5cbiAqXG4gKiBAcGFyYW0ge0N1c3RvbUVsZW1lbnR9IGVsZW1lbnRcbiAqIEByZXR1cm4ge3ZvaWR9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjcuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHRocm93cyB7RE9NRXhjZXB0aW9ufSBGYWlsZWQgdG8gZXhlY3V0ZSAnZGVmaW5lJyBvbiAnQ3VzdG9tRWxlbWVudFJlZ2lzdHJ5JzogaXMgbm90IGEgdmFsaWQgY3VzdG9tIGVsZW1lbnQgbmFtZVxuICovXG5mdW5jdGlvbiByZWdpc3RlckN1c3RvbUVsZW1lbnQoZWxlbWVudCkge1xuICAgIHZhbGlkYXRlRnVuY3Rpb24oZWxlbWVudCk7XG4gICAgY29uc3QgY3VzdG9tRWxlbWVudHMgPSBnZXRHbG9iYWxPYmplY3QoXCJjdXN0b21FbGVtZW50c1wiKTtcbiAgICBpZiAoY3VzdG9tRWxlbWVudHMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJjdXN0b21FbGVtZW50cyBpcyBub3Qgc3VwcG9ydGVkLlwiKTtcbiAgICB9XG5cbiAgICBpZiAoY3VzdG9tRWxlbWVudHMuZ2V0KGVsZW1lbnQuZ2V0VGFnKCkpICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGN1c3RvbUVsZW1lbnRzLmRlZmluZShlbGVtZW50LmdldFRhZygpLCBlbGVtZW50KTtcbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGV4dGVuZCB9IGZyb20gXCIuLi9kYXRhL2V4dGVuZC5tanNcIjtcbmltcG9ydCB7IEFUVFJJQlVURV9WQUxVRSB9IGZyb20gXCIuL2NvbnN0YW50cy5tanNcIjtcbmltcG9ydCB7IEN1c3RvbUVsZW1lbnQsIGF0dHJpYnV0ZU9ic2VydmVyU3ltYm9sIH0gZnJvbSBcIi4vY3VzdG9tZWxlbWVudC5tanNcIjtcbmltcG9ydCB7IGluc3RhbmNlU3ltYm9sIH0gZnJvbSBcIi4uL2NvbnN0YW50cy5tanNcIjtcbmV4cG9ydCB7IEN1c3RvbUNvbnRyb2wgfTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHR5cGUge3N5bWJvbH1cbiAqL1xuY29uc3QgYXR0YWNoZWRJbnRlcm5hbFN5bWJvbCA9IFN5bWJvbChcImF0dGFjaGVkSW50ZXJuYWxcIik7XG5cbi8qKlxuICogVG8gZGVmaW5lIGEgbmV3IEhUTUwgY29udHJvbCB3ZSBuZWVkIHRoZSBwb3dlciBvZiBDdXN0b21FbGVtZW50XG4gKlxuICogSU1QT1JUQU5UOiBhZnRlciBkZWZpbmluZyBhIGBDdXN0b21FbGVtZW50YCwgdGhlIGByZWdpc3RlckN1c3RvbUVsZW1lbnRgIG1ldGhvZCBtdXN0IGJlIGNhbGxlZFxuICogd2l0aCB0aGUgbmV3IGNsYXNzIG5hbWUuIG9ubHkgdGhlbiB3aWxsIHRoZSB0YWcgZGVmaW5lZCB2aWEgdGhlIGBnZXRUYWdgIG1ldGhvZCBiZSBtYWRlIGtub3duIHRvIHRoZSBET00uXG4gKlxuICogPGltZyBzcmM9XCIuL2ltYWdlcy9jdXN0b21jb250cm9sLWNsYXNzLnBuZ1wiPlxuICpcbiAqIFRoaXMgY29udHJvbCB1c2VzIGBhdHRhY2hJbnRlcm5hbHMoKWAgdG8gaW50ZWdyYXRlIHRoZSBjb250cm9sIGludG8gYSBmb3JtLlxuICogSWYgdGhlIHRhcmdldCBlbnZpcm9ubWVudCBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgbWV0aG9kLCB0aGUgW3BvbHlmaWxsXShodHRwczovL3d3dy5ucG1qcy5jb20vcGFja2FnZS9lbGVtZW50LWludGVybmFscy1wb2x5ZmlsbCApIGNhbiBiZSB1c2VkLlxuICpcbiAqIFlvdSBjYW4gY3JlYXRlIHRoZSBvYmplY3QgdmlhIHRoZSBmdW5jdGlvbiBgZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgpYC5cbiAqXG4gKiBAc3RhcnR1bWwgY3VzdG9tY29udHJvbC1jbGFzcy5wbmdcbiAqIHNraW5wYXJhbSBtb25vY2hyb21lIHRydWVcbiAqIHNraW5wYXJhbSBzaGFkb3dpbmcgZmFsc2VcbiAqIEhUTUxFbGVtZW50IDx8LS0gQ3VzdG9tRWxlbWVudFxuICogQ3VzdG9tRWxlbWVudCA8fC0tIEN1c3RvbUNvbnRyb2xcbiAqIEBlbmR1bWxcbiAqXG4gKiBAc3VtbWFyeSBBIGJhc2UgY2xhc3MgZm9yIGN1c3RvbWNvbnRyb2xzIGJhc2VkIG9uIEN1c3RvbUVsZW1lbnRcbiAqIEBzZWUge0BsaW5rIGh0dHBzOi8vd3d3Lm5wbWpzLmNvbS9wYWNrYWdlL2VsZW1lbnQtaW50ZXJuYWxzLXBvbHlmaWxsfVxuICogQHNlZSB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL1dJQ0cvd2ViY29tcG9uZW50c31cbiAqIEBzZWUge0BsaW5rIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL2N1c3RvbS1lbGVtZW50cy5odG1sI2N1c3RvbS1lbGVtZW50c31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMTQuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICovXG5jbGFzcyBDdXN0b21Db250cm9sIGV4dGVuZHMgQ3VzdG9tRWxlbWVudCB7XG4gICAgLyoqXG4gICAgICogSU1QT1JUQU5UOiBDdXN0b21Db250cm9scyBpbnN0YW5jZXMgYXJlIG5vdCBjcmVhdGVkIHZpYSB0aGUgY29uc3RydWN0b3IsIGJ1dCBlaXRoZXIgdmlhIGEgdGFnIGluIHRoZSBIVE1MIG9yIHZpYSA8Y29kZT5kb2N1bWVudC5jcmVhdGVFbGVtZW50KCk8L2NvZGU+LlxuICAgICAqXG4gICAgICogQHRocm93cyB7RXJyb3J9IHRoZSBFbGVtZW50SW50ZXJuYWxzIGlzIG5vdCBzdXBwb3J0ZWQgYW5kIGEgcG9seWZpbGwgaXMgbmVjZXNzYXJ5XG4gICAgICogQHN1bW1hcnkgY3JlYXRlIG5ldyBJbnN0YW5jZVxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuXG4gICAgICAgIGlmICh0eXBlb2YgdGhpc1tcImF0dGFjaEludGVybmFsc1wiXSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIGN1cnJlbnRseSBvbmx5IHN1cHBvcnRlZCBieSBjaHJvbWVcbiAgICAgICAgICAgICAqIEBwcm9wZXJ0eSB7T2JqZWN0fVxuICAgICAgICAgICAgICogQHByaXZhdGVcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgdGhpc1thdHRhY2hlZEludGVybmFsU3ltYm9sXSA9IHRoaXMuYXR0YWNoSW50ZXJuYWxzKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpbml0T2JzZXJ2ZXIuY2FsbCh0aGlzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGBpbnN0YW5jZW9mYCBvcGVyYXRvci5cbiAgICAgKiBAcmV0dXJucyB7c3ltYm9sfVxuICAgICAqIEBzaW5jZSAyLjEuMFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgW2luc3RhbmNlU3ltYm9sXSgpIHtcbiAgICAgICAgcmV0dXJuIFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL2RvbS9jdXN0b20tY29udHJvbFwiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBkZXRlcm1pbmVzIHdoaWNoIGF0dHJpYnV0ZXMgYXJlIHRvIGJlIG1vbml0b3JlZCBieSBgYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKClgLlxuICAgICAqXG4gICAgICogQHJldHVybiB7c3RyaW5nW119XG4gICAgICogQHNpbmNlIDEuMTUuMFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgb2JzZXJ2ZWRBdHRyaWJ1dGVzKCkge1xuICAgICAgICBjb25zdCBsaXN0ID0gc3VwZXIub2JzZXJ2ZWRBdHRyaWJ1dGVzO1xuICAgICAgICBsaXN0LnB1c2goQVRUUklCVVRFX1ZBTFVFKTtcbiAgICAgICAgcmV0dXJuIGxpc3Q7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAc2VlIHtAbGluayBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvSFRNTEVsZW1lbnQvYXR0YWNoSW50ZXJuYWxzfVxuICAgICAqIEBzaW5jZSAxLjE0LjBcbiAgICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgZm9ybUFzc29jaWF0ZWQoKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERlcml2ZWQgY2xhc3NlcyBjYW4gb3ZlcnJpZGUgYW5kIGV4dGVuZCB0aGlzIG1ldGhvZCBhcyBmb2xsb3dzLlxuICAgICAqXG4gICAgICogYGBgXG4gICAgICogZ2V0IGRlZmF1bHRzKCkge1xuICAgICAqICAgIHJldHVybiBleHRlbmRze30sIHN1cGVyLmRlZmF1bHRzLCB7XG4gICAgICogICAgICAgIG15VmFsdWU6dHJ1ZVxuICAgICAqICAgIH0pO1xuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEBzZWUge0BsaW5rIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL2N1c3RvbS1lbGVtZW50cy5odG1sI2N1c3RvbS1lbGVtZW50cy1mYWNlLWV4YW1wbGV9XG4gICAgICogQHNlZSB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0hUTUxFbGVtZW50L2F0dGFjaEludGVybmFsc31cbiAgICAgKiBAcmV0dXJuIHtvYmplY3R9XG4gICAgICogQHNpbmNlIDEuMTQuMFxuICAgICAqL1xuICAgIGdldCBkZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIGV4dGVuZCh7fSwgc3VwZXIuZGVmYXVsdHMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE11c3QgYmUgb3ZlcnJpZGRlbiBieSBhIGRlcml2ZWQgY2xhc3MgYW5kIHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGNvbnRyb2wuXG4gICAgICpcbiAgICAgKiBUaGlzIGlzIGEgbWV0aG9kIG9mIFtpbnRlcm5hbCBhcGldKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FbGVtZW50SW50ZXJuYWxzKVxuICAgICAqXG4gICAgICogQHNpbmNlIDEuMTQuMFxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSB0aGUgdmFsdWUgZ2V0dGVyIG11c3QgYmUgb3ZlcndyaXR0ZW4gYnkgdGhlIGRlcml2ZWQgY2xhc3NcbiAgICAgKi9cbiAgICBnZXQgdmFsdWUoKSB7XG4gICAgICAgIHRocm93IEVycm9yKFwidGhlIHZhbHVlIGdldHRlciBtdXN0IGJlIG92ZXJ3cml0dGVuIGJ5IHRoZSBkZXJpdmVkIGNsYXNzXCIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE11c3QgYmUgb3ZlcnJpZGRlbiBieSBhIGRlcml2ZWQgY2xhc3MgYW5kIHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGNvbnRyb2wuXG4gICAgICpcbiAgICAgKiBUaGlzIGlzIGEgbWV0aG9kIG9mIFtpbnRlcm5hbCBhcGldKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FbGVtZW50SW50ZXJuYWxzKVxuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZVxuICAgICAqIEBzaW5jZSAxLjE0LjBcbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gdGhlIHZhbHVlIHNldHRlciBtdXN0IGJlIG92ZXJ3cml0dGVuIGJ5IHRoZSBkZXJpdmVkIGNsYXNzXG4gICAgICovXG4gICAgc2V0IHZhbHVlKHZhbHVlKSB7XG4gICAgICAgIHRocm93IEVycm9yKFwidGhlIHZhbHVlIHNldHRlciBtdXN0IGJlIG92ZXJ3cml0dGVuIGJ5IHRoZSBkZXJpdmVkIGNsYXNzXCIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgaXMgYSBtZXRob2Qgb2YgW2ludGVybmFsIGFwaV0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0VsZW1lbnRJbnRlcm5hbHMpXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtOb2RlTGlzdH1cbiAgICAgKiBAc2luY2UgMS4xNC4wXG4gICAgICogQHNlZSB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0VsZW1lbnRJbnRlcm5hbHMvbGFiZWxzfVxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSB0aGUgRWxlbWVudEludGVybmFscyBpcyBub3Qgc3VwcG9ydGVkIGFuZCBhIHBvbHlmaWxsIGlzIG5lY2Vzc2FyeVxuICAgICAqL1xuICAgIGdldCBsYWJlbHMoKSB7XG4gICAgICAgIHJldHVybiBnZXRJbnRlcm5hbC5jYWxsKHRoaXMpPy5sYWJlbHM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBpcyBhIG1ldGhvZCBvZiBbaW50ZXJuYWwgYXBpXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRWxlbWVudEludGVybmFscylcbiAgICAgKlxuICAgICAqIEByZXR1cm4ge3N0cmluZ3xudWxsfVxuICAgICAqL1xuICAgIGdldCBuYW1lKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoXCJuYW1lXCIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgaXMgYSBtZXRob2Qgb2YgW2ludGVybmFsIGFwaV0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0VsZW1lbnRJbnRlcm5hbHMpXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLmdldFRhZygpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgaXMgYSBtZXRob2Qgb2YgW2ludGVybmFsIGFwaV0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0VsZW1lbnRJbnRlcm5hbHMpXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtWYWxpZGl0eVN0YXRlfVxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSB0aGUgRWxlbWVudEludGVybmFscyBpcyBub3Qgc3VwcG9ydGVkIGFuZCBhIHBvbHlmaWxsIGlzIG5lY2Vzc2FyeVxuICAgICAqIEBzZWUge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9WYWxpZGl0eVN0YXRlfVxuICAgICAqIEBzZWUge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS92YWxpZGl0eX1cbiAgICAgKi9cbiAgICBnZXQgdmFsaWRpdHkoKSB7XG4gICAgICAgIHJldHVybiBnZXRJbnRlcm5hbC5jYWxsKHRoaXMpPy52YWxpZGl0eTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGlzIGEgbWV0aG9kIG9mIFtpbnRlcm5hbCBhcGldKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FbGVtZW50SW50ZXJuYWxzKVxuICAgICAqXG4gICAgICogQHJldHVybiB7c3RyaW5nfVxuICAgICAqIEBzaW5jZSAxLjE0LjBcbiAgICAgKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FbGVtZW50SW50ZXJuYWxzL3ZhbGlkYXRpb25NZXNzYWdlXG4gICAgICogQHRocm93cyB7RXJyb3J9IHRoZSBFbGVtZW50SW50ZXJuYWxzIGlzIG5vdCBzdXBwb3J0ZWQgYW5kIGEgcG9seWZpbGwgaXMgbmVjZXNzYXJ5XG4gICAgICovXG4gICAgZ2V0IHZhbGlkYXRpb25NZXNzYWdlKCkge1xuICAgICAgICByZXR1cm4gZ2V0SW50ZXJuYWwuY2FsbCh0aGlzKT8udmFsaWRhdGlvbk1lc3NhZ2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBpcyBhIG1ldGhvZCBvZiBbaW50ZXJuYWwgYXBpXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRWxlbWVudEludGVybmFscylcbiAgICAgKlxuICAgICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAgICogQHNpbmNlIDEuMTQuMFxuICAgICAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0VsZW1lbnRJbnRlcm5hbHMvd2lsbFZhbGlkYXRlXG4gICAgICogQHRocm93cyB7RXJyb3J9IHRoZSBFbGVtZW50SW50ZXJuYWxzIGlzIG5vdCBzdXBwb3J0ZWQgYW5kIGEgcG9seWZpbGwgaXMgbmVjZXNzYXJ5XG4gICAgICovXG4gICAgZ2V0IHdpbGxWYWxpZGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIGdldEludGVybmFsLmNhbGwodGhpcyk/LndpbGxWYWxpZGF0ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGlzIGEgbWV0aG9kIG9mIFtpbnRlcm5hbCBhcGldKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FbGVtZW50SW50ZXJuYWxzKVxuICAgICAqXG4gICAgICogQHJldHVybiB7Q3VzdG9tU3RhdGVTZXR9XG4gICAgICogQHNpbmNlIDEuMTQuMFxuICAgICAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0VsZW1lbnRJbnRlcm5hbHMvc3RhdGVzXG4gICAgICogQHRocm93cyB7RXJyb3J9IHRoZSBFbGVtZW50SW50ZXJuYWxzIGlzIG5vdCBzdXBwb3J0ZWQgYW5kIGEgcG9seWZpbGwgaXMgbmVjZXNzYXJ5XG4gICAgICovXG4gICAgZ2V0IHN0YXRlcygpIHtcbiAgICAgICAgcmV0dXJuIGdldEludGVybmFsLmNhbGwodGhpcyk/LnN0YXRlcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGlzIGEgbWV0aG9kIG9mIFtpbnRlcm5hbCBhcGldKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FbGVtZW50SW50ZXJuYWxzKVxuICAgICAqXG4gICAgICogQHJldHVybiB7SFRNTEZvbnRFbGVtZW50fG51bGx9XG4gICAgICogQHNpbmNlIDEuMTQuMFxuICAgICAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0VsZW1lbnRJbnRlcm5hbHMvZm9ybVxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSB0aGUgRWxlbWVudEludGVybmFscyBpcyBub3Qgc3VwcG9ydGVkIGFuZCBhIHBvbHlmaWxsIGlzIG5lY2Vzc2FyeVxuICAgICAqL1xuICAgIGdldCBmb3JtKCkge1xuICAgICAgICByZXR1cm4gZ2V0SW50ZXJuYWwuY2FsbCh0aGlzKT8uZm9ybTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGlzIGEgbWV0aG9kIG9mIFtpbnRlcm5hbCBhcGldKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FbGVtZW50SW50ZXJuYWxzKVxuICAgICAqXG4gICAgICogYGBgXG4gICAgICogLy8gVXNlIHRoZSBjb250cm9sJ3MgbmFtZSBhcyB0aGUgYmFzZSBuYW1lIGZvciBzdWJtaXR0ZWQgZGF0YVxuICAgICAqIGNvbnN0IG4gPSB0aGlzLmdldEF0dHJpYnV0ZSgnbmFtZScpO1xuICAgICAqIGNvbnN0IGVudHJpZXMgPSBuZXcgRm9ybURhdGEoKTtcbiAgICAgKiBlbnRyaWVzLmFwcGVuZChuICsgJy1maXJzdC1uYW1lJywgdGhpcy5maXJzdE5hbWVfKTtcbiAgICAgKiBlbnRyaWVzLmFwcGVuZChuICsgJy1sYXN0LW5hbWUnLCB0aGlzLmxhc3ROYW1lXyk7XG4gICAgICogdGhpcy5zZXRGb3JtVmFsdWUoZW50cmllcyk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0ZpbGV8c3RyaW5nfEZvcm1EYXRhfSB2YWx1ZVxuICAgICAqIEBwYXJhbSB7RmlsZXxzdHJpbmd8Rm9ybURhdGF9IHN0YXRlXG4gICAgICogQHNpbmNlIDEuMTQuMFxuICAgICAqIEByZXR1cm4ge3VuZGVmaW5lZH1cbiAgICAgKiBAdGhyb3dzIHtET01FeGNlcHRpb259IE5vdFN1cHBvcnRlZEVycm9yXG4gICAgICogQHRocm93cyB7RXJyb3J9IHRoZSBFbGVtZW50SW50ZXJuYWxzIGlzIG5vdCBzdXBwb3J0ZWQgYW5kIGEgcG9seWZpbGwgaXMgbmVjZXNzYXJ5XG4gICAgICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRWxlbWVudEludGVybmFscy9zZXRGb3JtVmFsdWVcbiAgICAgKi9cbiAgICBzZXRGb3JtVmFsdWUodmFsdWUsIHN0YXRlKSB7XG4gICAgICAgIGdldEludGVybmFsLmNhbGwodGhpcykuc2V0Rm9ybVZhbHVlKHZhbHVlLCBzdGF0ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gZmxhZ3NcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3x1bmRlZmluZWR9IG1lc3NhZ2VcbiAgICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBhbmNob3JcbiAgICAgKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FbGVtZW50SW50ZXJuYWxzL3NldFZhbGlkaXR5XG4gICAgICogQHNpbmNlIDEuMTQuMFxuICAgICAqIEByZXR1cm4ge3VuZGVmaW5lZH1cbiAgICAgKiBAdGhyb3dzIHtET01FeGNlcHRpb259IE5vdFN1cHBvcnRlZEVycm9yXG4gICAgICogQHRocm93cyB7RXJyb3J9IHRoZSBFbGVtZW50SW50ZXJuYWxzIGlzIG5vdCBzdXBwb3J0ZWQgYW5kIGEgcG9seWZpbGwgaXMgbmVjZXNzYXJ5XG4gICAgICovXG4gICAgc2V0VmFsaWRpdHkoZmxhZ3MsIG1lc3NhZ2UsIGFuY2hvcikge1xuICAgICAgICBnZXRJbnRlcm5hbC5jYWxsKHRoaXMpLnNldFZhbGlkaXR5KGZsYWdzLCBtZXNzYWdlLCBhbmNob3IpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgaXMgYSBtZXRob2Qgb2YgW2ludGVybmFsIGFwaV0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0VsZW1lbnRJbnRlcm5hbHMpXG4gICAgICpcbiAgICAgKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FbGVtZW50SW50ZXJuYWxzL2NoZWNrVmFsaWRpdHlcbiAgICAgKiBAc2luY2UgMS4xNC4wXG4gICAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICAgKiBAdGhyb3dzIHtET01FeGNlcHRpb259IE5vdFN1cHBvcnRlZEVycm9yXG4gICAgICogQHRocm93cyB7RXJyb3J9IHRoZSBFbGVtZW50SW50ZXJuYWxzIGlzIG5vdCBzdXBwb3J0ZWQgYW5kIGEgcG9seWZpbGwgaXMgbmVjZXNzYXJ5XG4gICAgICovXG4gICAgY2hlY2tWYWxpZGl0eSgpIHtcbiAgICAgICAgcmV0dXJuIGdldEludGVybmFsLmNhbGwodGhpcyk/LmNoZWNrVmFsaWRpdHkoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGlzIGEgbWV0aG9kIG9mIFtpbnRlcm5hbCBhcGldKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FbGVtZW50SW50ZXJuYWxzKVxuICAgICAqXG4gICAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICAgKiBAc2luY2UgMS4xNC4wXG4gICAgICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRWxlbWVudEludGVybmFscy9yZXBvcnRWYWxpZGl0eVxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSB0aGUgRWxlbWVudEludGVybmFscyBpcyBub3Qgc3VwcG9ydGVkIGFuZCBhIHBvbHlmaWxsIGlzIG5lY2Vzc2FyeVxuICAgICAqIEB0aHJvd3Mge0RPTUV4Y2VwdGlvbn0gTm90U3VwcG9ydGVkRXJyb3JcbiAgICAgKi9cbiAgICByZXBvcnRWYWxpZGl0eSgpIHtcbiAgICAgICAgcmV0dXJuIGdldEludGVybmFsLmNhbGwodGhpcyk/LnJlcG9ydFZhbGlkaXR5KCk7XG4gICAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcmV0dXJuIHtvYmplY3R9XG4gKiBAdGhyb3dzIHtFcnJvcn0gdGhlIEVsZW1lbnRJbnRlcm5hbHMgaXMgbm90IHN1cHBvcnRlZCBhbmQgYSBwb2x5ZmlsbCBpcyBuZWNlc3NhcnlcbiAqIEB0aGlzIEN1c3RvbUNvbnRyb2xcbiAqL1xuZnVuY3Rpb24gZ2V0SW50ZXJuYWwoKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICBpZiAoIShhdHRhY2hlZEludGVybmFsU3ltYm9sIGluIHRoaXMpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkVsZW1lbnRJbnRlcm5hbHMgaXMgbm90IHN1cHBvcnRlZCBhbmQgYSBwb2x5ZmlsbCBpcyBuZWNlc3NhcnlcIik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXNbYXR0YWNoZWRJbnRlcm5hbFN5bWJvbF07XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEByZXR1cm4ge29iamVjdH1cbiAqIEB0aGlzIEN1c3RvbUNvbnRyb2xcbiAqL1xuZnVuY3Rpb24gaW5pdE9ic2VydmVyKCkge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgLy8gdmFsdWVcbiAgICBzZWxmW2F0dHJpYnV0ZU9ic2VydmVyU3ltYm9sXVtcInZhbHVlXCJdID0gKCkgPT4ge1xuICAgICAgICBzZWxmLnNldE9wdGlvbihcInZhbHVlXCIsIHNlbGYuZ2V0QXR0cmlidXRlKFwidmFsdWVcIikpO1xuICAgIH07XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBnZXREb2N1bWVudCwgZ2V0V2luZG93IH0gZnJvbSBcIi4vdXRpbC5tanNcIjtcblxuZXhwb3J0IHsgZG9tUmVhZHksIHdpbmRvd1JlYWR5IH07XG5cbi8qKlxuICogVGhpcyB2YXJpYWJsZSBpcyBhIHByb21pc2UgdGhhdCBpcyBmdWxmaWxsZWQgYXMgc29vbiBhcyB0aGUgZG9tIGlzIGF2YWlsYWJsZS5cbiAqXG4gKiBUaGUgRE9NQ29udGVudExvYWRlZCBldmVudCBpcyBmaXJlZCB3aGVuIHRoZSBvcmlnaW5hbCBIVE1MIGRvY3VtZW50IGlzIGZ1bGx5IGxvYWRlZCBhbmQgcGFyc2VkXG4gKiB3aXRob3V0IHdhaXRpbmcgZm9yIHN0eWxlc2hlZXRzLCBpbWFnZXMsIGFuZCBzdWJmcmFtZXMgdG8gZmluaXNoIGxvYWRpbmcuXG4gKlxuICogZG9jdW1lbnQucmVhZHlTdGF0ZSBjaGFuZ2VzIHRvIGludGVyYWN0aXZlXG4gKiB3aW5kb3cncyBET01Db250ZW50TG9hZGVkIGV2ZW50IGdldHMgZmlyZWRcbiAqIGRvY3VtZW50LnJlYWR5U3RhdGUgY2hhbmdlcyB0byBjb21wbGV0ZVxuICogd2luZG93J3MgbG9hZCBldmVudCBnZXRzIGZpcmVkIGxvYWRcbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjMxLjBcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHN1bW1hcnkgdmFyaWFibGUgdG8gY2hlY2sgaWYgZG9tIGlzIHJlYWR5XG4gKiBAdHlwZSB7UHJvbWlzZX1cbiAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0RvY3VtZW50L0RPTUNvbnRlbnRMb2FkZWRfZXZlbnRcbiAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0RvY3VtZW50L3JlYWR5U3RhdGVcbiAqL1xuY29uc3QgZG9tUmVhZHkgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgIGNvbnN0IGRvY3VtZW50ID0gZ2V0RG9jdW1lbnQoKTtcblxuICAgIGlmIChkb2N1bWVudC5yZWFkeVN0YXRlID09PSBcImxvYWRpbmdcIikge1xuICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwiRE9NQ29udGVudExvYWRlZFwiLCByZXNvbHZlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXNvbHZlKCk7XG4gICAgfVxufSk7XG5cbi8qKlxuICogVGhpcyB2YXJpYWJsZSBpcyBhIHByb21pc2UgdGhhdCBpcyBmdWxmaWxsZWQgYXMgc29vbiBhcyB0aGUgd2luZG93cyBpcyBhdmFpbGFibGUuXG4gKlxuICogVGhlIGxvYWQgZXZlbnQgZmlyZXMgd2hlbiB0aGUgZW50aXJlIHBhZ2UgaXMgbG9hZGVkLCBpbmNsdWRpbmcgYWxsIGRlcGVuZGVudCByZXNvdXJjZXMgc3VjaCBhcyBzdHlsZXNoZWV0cyxcbiAqIGFzc2V0cywgYW5kIGltYWdlcy4gVW5saWtlIERPTUNvbnRlbnRMb2FkZWQsIHdoaWNoIGZpcmVzIGFzIHNvb24gYXMgdGhlIERPTSBvZiB0aGUgcGFnZSBpcyBsb2FkZWQsXG4gKiB3aXRob3V0IHdhaXRpbmcgZm9yIHRoZSByZXNvdXJjZXMgdG8gZmluaXNoIGxvYWRpbmcuXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4zMS4wXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEBzdW1tYXJ5IHZhcmlhYmxlIHRvIGNoZWNrIGlmIHdpbmRvdyBpcyByZWFkeVxuICogQHR5cGUge1Byb21pc2V9XG4gKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9XaW5kb3cvbG9hZF9ldmVudFxuICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRG9jdW1lbnQvcmVhZHlTdGF0ZVxuICovXG5jb25zdCB3aW5kb3dSZWFkeSA9IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgY29uc3QgZG9jdW1lbnQgPSBnZXREb2N1bWVudCgpO1xuICAgIGNvbnN0IHdpbmRvdyA9IGdldFdpbmRvdygpO1xuXG4gICAgaWYgKGRvY3VtZW50LnJlYWR5U3RhdGUgPT09IFwiY29tcGxldGVcIikge1xuICAgICAgICByZXNvbHZlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJsb2FkXCIsIHJlc29sdmUpO1xuICAgIH1cbn0pO1xuIiwgIi8qIVxuICogTUlUIExpY2Vuc2VcbiAqIFxuICogQ29weXJpZ2h0IChjKSAyMDE3LTIwMjIgUGVjdWxpYXIgVmVudHVyZXMsIExMQ1xuICogXG4gKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4gKiBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG4gKiBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXG4gKiB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXG4gKiBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbiAqIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4gKiBcbiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluIGFsbFxuICogY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbiAqIFxuICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbiAqIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbiAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG4gKiBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRVxuICogU09GVFdBUkUuXG4gKiBcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHsgdmFsdWU6IHRydWUgfSk7XG5cbmNvbnN0IEFSUkFZX0JVRkZFUl9OQU1FID0gXCJbb2JqZWN0IEFycmF5QnVmZmVyXVwiO1xyXG5jbGFzcyBCdWZmZXJTb3VyY2VDb252ZXJ0ZXIge1xyXG4gICAgc3RhdGljIGlzQXJyYXlCdWZmZXIoZGF0YSkge1xyXG4gICAgICAgIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoZGF0YSkgPT09IEFSUkFZX0JVRkZFUl9OQU1FO1xyXG4gICAgfVxyXG4gICAgc3RhdGljIHRvQXJyYXlCdWZmZXIoZGF0YSkge1xyXG4gICAgICAgIGlmICh0aGlzLmlzQXJyYXlCdWZmZXIoZGF0YSkpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGRhdGE7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChkYXRhLmJ5dGVMZW5ndGggPT09IGRhdGEuYnVmZmVyLmJ5dGVMZW5ndGgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGRhdGEuYnVmZmVyO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcy50b1VpbnQ4QXJyYXkoZGF0YSkuc2xpY2UoKS5idWZmZXI7XHJcbiAgICB9XHJcbiAgICBzdGF0aWMgdG9VaW50OEFycmF5KGRhdGEpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy50b1ZpZXcoZGF0YSwgVWludDhBcnJheSk7XHJcbiAgICB9XHJcbiAgICBzdGF0aWMgdG9WaWV3KGRhdGEsIHR5cGUpIHtcclxuICAgICAgICBpZiAoZGF0YS5jb25zdHJ1Y3RvciA9PT0gdHlwZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gZGF0YTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHRoaXMuaXNBcnJheUJ1ZmZlcihkYXRhKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gbmV3IHR5cGUoZGF0YSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLmlzQXJyYXlCdWZmZXJWaWV3KGRhdGEpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgdHlwZShkYXRhLmJ1ZmZlciwgZGF0YS5ieXRlT2Zmc2V0LCBkYXRhLmJ5dGVMZW5ndGgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiVGhlIHByb3ZpZGVkIHZhbHVlIGlzIG5vdCBvZiB0eXBlICcoQXJyYXlCdWZmZXIgb3IgQXJyYXlCdWZmZXJWaWV3KSdcIik7XHJcbiAgICB9XHJcbiAgICBzdGF0aWMgaXNCdWZmZXJTb3VyY2UoZGF0YSkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmlzQXJyYXlCdWZmZXJWaWV3KGRhdGEpXHJcbiAgICAgICAgICAgIHx8IHRoaXMuaXNBcnJheUJ1ZmZlcihkYXRhKTtcclxuICAgIH1cclxuICAgIHN0YXRpYyBpc0FycmF5QnVmZmVyVmlldyhkYXRhKSB7XHJcbiAgICAgICAgcmV0dXJuIEFycmF5QnVmZmVyLmlzVmlldyhkYXRhKVxyXG4gICAgICAgICAgICB8fCAoZGF0YSAmJiB0aGlzLmlzQXJyYXlCdWZmZXIoZGF0YS5idWZmZXIpKTtcclxuICAgIH1cclxuICAgIHN0YXRpYyBpc0VxdWFsKGEsIGIpIHtcclxuICAgICAgICBjb25zdCBhVmlldyA9IEJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b1VpbnQ4QXJyYXkoYSk7XHJcbiAgICAgICAgY29uc3QgYlZpZXcgPSBCdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9VaW50OEFycmF5KGIpO1xyXG4gICAgICAgIGlmIChhVmlldy5sZW5ndGggIT09IGJWaWV3LmJ5dGVMZW5ndGgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFWaWV3Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmIChhVmlld1tpXSAhPT0gYlZpZXdbaV0pIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuICAgIHN0YXRpYyBjb25jYXQoLi4uYXJncykge1xyXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KGFyZ3NbMF0pKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlcnMgPSBhcmdzWzBdO1xyXG4gICAgICAgICAgICBsZXQgc2l6ZSA9IDA7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgYnVmZmVyIG9mIGJ1ZmZlcnMpIHtcclxuICAgICAgICAgICAgICAgIHNpemUgKz0gYnVmZmVyLmJ5dGVMZW5ndGg7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY29uc3QgcmVzID0gbmV3IFVpbnQ4QXJyYXkoc2l6ZSk7XHJcbiAgICAgICAgICAgIGxldCBvZmZzZXQgPSAwO1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGJ1ZmZlciBvZiBidWZmZXJzKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCB2aWV3ID0gdGhpcy50b1VpbnQ4QXJyYXkoYnVmZmVyKTtcclxuICAgICAgICAgICAgICAgIHJlcy5zZXQodmlldywgb2Zmc2V0KTtcclxuICAgICAgICAgICAgICAgIG9mZnNldCArPSB2aWV3Lmxlbmd0aDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoYXJnc1sxXSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudG9WaWV3KHJlcywgYXJnc1sxXSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHJlcy5idWZmZXI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb25jYXQoYXJncyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XG5cbmNsYXNzIFV0ZjhDb252ZXJ0ZXIge1xyXG4gICAgc3RhdGljIGZyb21TdHJpbmcodGV4dCkge1xyXG4gICAgICAgIGNvbnN0IHMgPSB1bmVzY2FwZShlbmNvZGVVUklDb21wb25lbnQodGV4dCkpO1xyXG4gICAgICAgIGNvbnN0IHVpbnRBcnJheSA9IG5ldyBVaW50OEFycmF5KHMubGVuZ3RoKTtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgdWludEFycmF5W2ldID0gcy5jaGFyQ29kZUF0KGkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdWludEFycmF5LmJ1ZmZlcjtcclxuICAgIH1cclxuICAgIHN0YXRpYyB0b1N0cmluZyhidWZmZXIpIHtcclxuICAgICAgICBjb25zdCBidWYgPSBCdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9VaW50OEFycmF5KGJ1ZmZlcik7XHJcbiAgICAgICAgbGV0IGVuY29kZWRTdHJpbmcgPSBcIlwiO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYnVmLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGVuY29kZWRTdHJpbmcgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBkZWNvZGVkU3RyaW5nID0gZGVjb2RlVVJJQ29tcG9uZW50KGVzY2FwZShlbmNvZGVkU3RyaW5nKSk7XHJcbiAgICAgICAgcmV0dXJuIGRlY29kZWRTdHJpbmc7XHJcbiAgICB9XHJcbn1cclxuY2xhc3MgVXRmMTZDb252ZXJ0ZXIge1xyXG4gICAgc3RhdGljIHRvU3RyaW5nKGJ1ZmZlciwgbGl0dGxlRW5kaWFuID0gZmFsc2UpIHtcclxuICAgICAgICBjb25zdCBhcnJheUJ1ZmZlciA9IEJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b0FycmF5QnVmZmVyKGJ1ZmZlcik7XHJcbiAgICAgICAgY29uc3QgZGF0YVZpZXcgPSBuZXcgRGF0YVZpZXcoYXJyYXlCdWZmZXIpO1xyXG4gICAgICAgIGxldCByZXMgPSBcIlwiO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXJyYXlCdWZmZXIuYnl0ZUxlbmd0aDsgaSArPSAyKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGNvZGUgPSBkYXRhVmlldy5nZXRVaW50MTYoaSwgbGl0dGxlRW5kaWFuKTtcclxuICAgICAgICAgICAgcmVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoY29kZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiByZXM7XHJcbiAgICB9XHJcbiAgICBzdGF0aWMgZnJvbVN0cmluZyh0ZXh0LCBsaXR0bGVFbmRpYW4gPSBmYWxzZSkge1xyXG4gICAgICAgIGNvbnN0IHJlcyA9IG5ldyBBcnJheUJ1ZmZlcih0ZXh0Lmxlbmd0aCAqIDIpO1xyXG4gICAgICAgIGNvbnN0IGRhdGFWaWV3ID0gbmV3IERhdGFWaWV3KHJlcyk7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0ZXh0Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGRhdGFWaWV3LnNldFVpbnQxNihpICogMiwgdGV4dC5jaGFyQ29kZUF0KGkpLCBsaXR0bGVFbmRpYW4pO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcmVzO1xyXG4gICAgfVxyXG59XHJcbmNsYXNzIENvbnZlcnQge1xyXG4gICAgc3RhdGljIGlzSGV4KGRhdGEpIHtcclxuICAgICAgICByZXR1cm4gdHlwZW9mIGRhdGEgPT09IFwic3RyaW5nXCJcclxuICAgICAgICAgICAgJiYgL15bYS16MC05XSskL2kudGVzdChkYXRhKTtcclxuICAgIH1cclxuICAgIHN0YXRpYyBpc0Jhc2U2NChkYXRhKSB7XHJcbiAgICAgICAgcmV0dXJuIHR5cGVvZiBkYXRhID09PSBcInN0cmluZ1wiXHJcbiAgICAgICAgICAgICYmIC9eKD86W0EtWmEtejAtOSsvXXs0fSkqKD86W0EtWmEtejAtOSsvXXsyfT09fFtBLVphLXowLTkrL117M309KT8kLy50ZXN0KGRhdGEpO1xyXG4gICAgfVxyXG4gICAgc3RhdGljIGlzQmFzZTY0VXJsKGRhdGEpIHtcclxuICAgICAgICByZXR1cm4gdHlwZW9mIGRhdGEgPT09IFwic3RyaW5nXCJcclxuICAgICAgICAgICAgJiYgL15bYS16QS1aMC05LV9dKyQvaS50ZXN0KGRhdGEpO1xyXG4gICAgfVxyXG4gICAgc3RhdGljIFRvU3RyaW5nKGJ1ZmZlciwgZW5jID0gXCJ1dGY4XCIpIHtcclxuICAgICAgICBjb25zdCBidWYgPSBCdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9VaW50OEFycmF5KGJ1ZmZlcik7XHJcbiAgICAgICAgc3dpdGNoIChlbmMudG9Mb3dlckNhc2UoKSkge1xyXG4gICAgICAgICAgICBjYXNlIFwidXRmOFwiOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuVG9VdGY4U3RyaW5nKGJ1Zik7XHJcbiAgICAgICAgICAgIGNhc2UgXCJiaW5hcnlcIjpcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLlRvQmluYXJ5KGJ1Zik7XHJcbiAgICAgICAgICAgIGNhc2UgXCJoZXhcIjpcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLlRvSGV4KGJ1Zik7XHJcbiAgICAgICAgICAgIGNhc2UgXCJiYXNlNjRcIjpcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLlRvQmFzZTY0KGJ1Zik7XHJcbiAgICAgICAgICAgIGNhc2UgXCJiYXNlNjR1cmxcIjpcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLlRvQmFzZTY0VXJsKGJ1Zik7XHJcbiAgICAgICAgICAgIGNhc2UgXCJ1dGYxNmxlXCI6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gVXRmMTZDb252ZXJ0ZXIudG9TdHJpbmcoYnVmLCB0cnVlKTtcclxuICAgICAgICAgICAgY2FzZSBcInV0ZjE2XCI6XHJcbiAgICAgICAgICAgIGNhc2UgXCJ1dGYxNmJlXCI6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gVXRmMTZDb252ZXJ0ZXIudG9TdHJpbmcoYnVmKTtcclxuICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biB0eXBlIG9mIGVuY29kaW5nICcke2VuY30nYCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgc3RhdGljIEZyb21TdHJpbmcoc3RyLCBlbmMgPSBcInV0ZjhcIikge1xyXG4gICAgICAgIGlmICghc3RyKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgQXJyYXlCdWZmZXIoMCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHN3aXRjaCAoZW5jLnRvTG93ZXJDYXNlKCkpIHtcclxuICAgICAgICAgICAgY2FzZSBcInV0ZjhcIjpcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLkZyb21VdGY4U3RyaW5nKHN0cik7XHJcbiAgICAgICAgICAgIGNhc2UgXCJiaW5hcnlcIjpcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLkZyb21CaW5hcnkoc3RyKTtcclxuICAgICAgICAgICAgY2FzZSBcImhleFwiOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuRnJvbUhleChzdHIpO1xyXG4gICAgICAgICAgICBjYXNlIFwiYmFzZTY0XCI6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5Gcm9tQmFzZTY0KHN0cik7XHJcbiAgICAgICAgICAgIGNhc2UgXCJiYXNlNjR1cmxcIjpcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLkZyb21CYXNlNjRVcmwoc3RyKTtcclxuICAgICAgICAgICAgY2FzZSBcInV0ZjE2bGVcIjpcclxuICAgICAgICAgICAgICAgIHJldHVybiBVdGYxNkNvbnZlcnRlci5mcm9tU3RyaW5nKHN0ciwgdHJ1ZSk7XHJcbiAgICAgICAgICAgIGNhc2UgXCJ1dGYxNlwiOlxyXG4gICAgICAgICAgICBjYXNlIFwidXRmMTZiZVwiOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFV0ZjE2Q29udmVydGVyLmZyb21TdHJpbmcoc3RyKTtcclxuICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biB0eXBlIG9mIGVuY29kaW5nICcke2VuY30nYCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgc3RhdGljIFRvQmFzZTY0KGJ1ZmZlcikge1xyXG4gICAgICAgIGNvbnN0IGJ1ZiA9IEJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b1VpbnQ4QXJyYXkoYnVmZmVyKTtcclxuICAgICAgICBpZiAodHlwZW9mIGJ0b2EgIT09IFwidW5kZWZpbmVkXCIpIHtcclxuICAgICAgICAgICAgY29uc3QgYmluYXJ5ID0gdGhpcy5Ub1N0cmluZyhidWYsIFwiYmluYXJ5XCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gYnRvYShiaW5hcnkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGJ1ZikudG9TdHJpbmcoXCJiYXNlNjRcIik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgc3RhdGljIEZyb21CYXNlNjQoYmFzZTY0KSB7XHJcbiAgICAgICAgY29uc3QgZm9ybWF0dGVkID0gdGhpcy5mb3JtYXRTdHJpbmcoYmFzZTY0KTtcclxuICAgICAgICBpZiAoIWZvcm1hdHRlZCkge1xyXG4gICAgICAgICAgICByZXR1cm4gbmV3IEFycmF5QnVmZmVyKDApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIUNvbnZlcnQuaXNCYXNlNjQoZm9ybWF0dGVkKSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQXJndW1lbnQgJ2Jhc2U2NFRleHQnIGlzIG5vdCBCYXNlNjQgZW5jb2RlZFwiKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHR5cGVvZiBhdG9iICE9PSBcInVuZGVmaW5lZFwiKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLkZyb21CaW5hcnkoYXRvYihmb3JtYXR0ZWQpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShCdWZmZXIuZnJvbShmb3JtYXR0ZWQsIFwiYmFzZTY0XCIpKS5idWZmZXI7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgc3RhdGljIEZyb21CYXNlNjRVcmwoYmFzZTY0dXJsKSB7XHJcbiAgICAgICAgY29uc3QgZm9ybWF0dGVkID0gdGhpcy5mb3JtYXRTdHJpbmcoYmFzZTY0dXJsKTtcclxuICAgICAgICBpZiAoIWZvcm1hdHRlZCkge1xyXG4gICAgICAgICAgICByZXR1cm4gbmV3IEFycmF5QnVmZmVyKDApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIUNvbnZlcnQuaXNCYXNlNjRVcmwoZm9ybWF0dGVkKSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQXJndW1lbnQgJ2Jhc2U2NHVybCcgaXMgbm90IEJhc2U2NFVybCBlbmNvZGVkXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcy5Gcm9tQmFzZTY0KHRoaXMuQmFzZTY0UGFkZGluZyhmb3JtYXR0ZWQucmVwbGFjZSgvXFwtL2csIFwiK1wiKS5yZXBsYWNlKC9cXF8vZywgXCIvXCIpKSk7XHJcbiAgICB9XHJcbiAgICBzdGF0aWMgVG9CYXNlNjRVcmwoZGF0YSkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLlRvQmFzZTY0KGRhdGEpLnJlcGxhY2UoL1xcKy9nLCBcIi1cIikucmVwbGFjZSgvXFwvL2csIFwiX1wiKS5yZXBsYWNlKC9cXD0vZywgXCJcIik7XHJcbiAgICB9XHJcbiAgICBzdGF0aWMgRnJvbVV0ZjhTdHJpbmcodGV4dCwgZW5jb2RpbmcgPSBDb252ZXJ0LkRFRkFVTFRfVVRGOF9FTkNPRElORykge1xyXG4gICAgICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcclxuICAgICAgICAgICAgY2FzZSBcImFzY2lpXCI6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5Gcm9tQmluYXJ5KHRleHQpO1xyXG4gICAgICAgICAgICBjYXNlIFwidXRmOFwiOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFV0ZjhDb252ZXJ0ZXIuZnJvbVN0cmluZyh0ZXh0KTtcclxuICAgICAgICAgICAgY2FzZSBcInV0ZjE2XCI6XHJcbiAgICAgICAgICAgIGNhc2UgXCJ1dGYxNmJlXCI6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gVXRmMTZDb252ZXJ0ZXIuZnJvbVN0cmluZyh0ZXh0KTtcclxuICAgICAgICAgICAgY2FzZSBcInV0ZjE2bGVcIjpcclxuICAgICAgICAgICAgY2FzZSBcInVzYzJcIjpcclxuICAgICAgICAgICAgICAgIHJldHVybiBVdGYxNkNvbnZlcnRlci5mcm9tU3RyaW5nKHRleHQsIHRydWUpO1xyXG4gICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIHR5cGUgb2YgZW5jb2RpbmcgJyR7ZW5jb2Rpbmd9J2ApO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHN0YXRpYyBUb1V0ZjhTdHJpbmcoYnVmZmVyLCBlbmNvZGluZyA9IENvbnZlcnQuREVGQVVMVF9VVEY4X0VOQ09ESU5HKSB7XHJcbiAgICAgICAgc3dpdGNoIChlbmNvZGluZykge1xyXG4gICAgICAgICAgICBjYXNlIFwiYXNjaWlcIjpcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLlRvQmluYXJ5KGJ1ZmZlcik7XHJcbiAgICAgICAgICAgIGNhc2UgXCJ1dGY4XCI6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gVXRmOENvbnZlcnRlci50b1N0cmluZyhidWZmZXIpO1xyXG4gICAgICAgICAgICBjYXNlIFwidXRmMTZcIjpcclxuICAgICAgICAgICAgY2FzZSBcInV0ZjE2YmVcIjpcclxuICAgICAgICAgICAgICAgIHJldHVybiBVdGYxNkNvbnZlcnRlci50b1N0cmluZyhidWZmZXIpO1xyXG4gICAgICAgICAgICBjYXNlIFwidXRmMTZsZVwiOlxyXG4gICAgICAgICAgICBjYXNlIFwidXNjMlwiOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFV0ZjE2Q29udmVydGVyLnRvU3RyaW5nKGJ1ZmZlciwgdHJ1ZSk7XHJcbiAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gdHlwZSBvZiBlbmNvZGluZyAnJHtlbmNvZGluZ30nYCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgc3RhdGljIEZyb21CaW5hcnkodGV4dCkge1xyXG4gICAgICAgIGNvbnN0IHN0cmluZ0xlbmd0aCA9IHRleHQubGVuZ3RoO1xyXG4gICAgICAgIGNvbnN0IHJlc3VsdFZpZXcgPSBuZXcgVWludDhBcnJheShzdHJpbmdMZW5ndGgpO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3RyaW5nTGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgcmVzdWx0Vmlld1tpXSA9IHRleHQuY2hhckNvZGVBdChpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdFZpZXcuYnVmZmVyO1xyXG4gICAgfVxyXG4gICAgc3RhdGljIFRvQmluYXJ5KGJ1ZmZlcikge1xyXG4gICAgICAgIGNvbnN0IGJ1ZiA9IEJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b1VpbnQ4QXJyYXkoYnVmZmVyKTtcclxuICAgICAgICBsZXQgcmVzID0gXCJcIjtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJ1Zi5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICByZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcmVzO1xyXG4gICAgfVxyXG4gICAgc3RhdGljIFRvSGV4KGJ1ZmZlcikge1xyXG4gICAgICAgIGNvbnN0IGJ1ZiA9IEJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b1VpbnQ4QXJyYXkoYnVmZmVyKTtcclxuICAgICAgICBjb25zdCBzcGxpdHRlciA9IFwiXCI7XHJcbiAgICAgICAgY29uc3QgcmVzID0gW107XHJcbiAgICAgICAgY29uc3QgbGVuID0gYnVmLmxlbmd0aDtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGNoYXIgPSBidWZbaV0udG9TdHJpbmcoMTYpLnBhZFN0YXJ0KDIsIFwiMFwiKTtcclxuICAgICAgICAgICAgcmVzLnB1c2goY2hhcik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiByZXMuam9pbihzcGxpdHRlcik7XHJcbiAgICB9XHJcbiAgICBzdGF0aWMgRnJvbUhleChoZXhTdHJpbmcpIHtcclxuICAgICAgICBsZXQgZm9ybWF0dGVkID0gdGhpcy5mb3JtYXRTdHJpbmcoaGV4U3RyaW5nKTtcclxuICAgICAgICBpZiAoIWZvcm1hdHRlZCkge1xyXG4gICAgICAgICAgICByZXR1cm4gbmV3IEFycmF5QnVmZmVyKDApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIUNvbnZlcnQuaXNIZXgoZm9ybWF0dGVkKSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQXJndW1lbnQgJ2hleFN0cmluZycgaXMgbm90IEhFWCBlbmNvZGVkXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoZm9ybWF0dGVkLmxlbmd0aCAlIDIpIHtcclxuICAgICAgICAgICAgZm9ybWF0dGVkID0gYDAke2Zvcm1hdHRlZH1gO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCByZXMgPSBuZXcgVWludDhBcnJheShmb3JtYXR0ZWQubGVuZ3RoIC8gMik7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBmb3JtYXR0ZWQubGVuZ3RoOyBpID0gaSArIDIpIHtcclxuICAgICAgICAgICAgY29uc3QgYyA9IGZvcm1hdHRlZC5zbGljZShpLCBpICsgMik7XHJcbiAgICAgICAgICAgIHJlc1tpIC8gMl0gPSBwYXJzZUludChjLCAxNik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiByZXMuYnVmZmVyO1xyXG4gICAgfVxyXG4gICAgc3RhdGljIFRvVXRmMTZTdHJpbmcoYnVmZmVyLCBsaXR0bGVFbmRpYW4gPSBmYWxzZSkge1xyXG4gICAgICAgIHJldHVybiBVdGYxNkNvbnZlcnRlci50b1N0cmluZyhidWZmZXIsIGxpdHRsZUVuZGlhbik7XHJcbiAgICB9XHJcbiAgICBzdGF0aWMgRnJvbVV0ZjE2U3RyaW5nKHRleHQsIGxpdHRsZUVuZGlhbiA9IGZhbHNlKSB7XHJcbiAgICAgICAgcmV0dXJuIFV0ZjE2Q29udmVydGVyLmZyb21TdHJpbmcodGV4dCwgbGl0dGxlRW5kaWFuKTtcclxuICAgIH1cclxuICAgIHN0YXRpYyBCYXNlNjRQYWRkaW5nKGJhc2U2NCkge1xyXG4gICAgICAgIGNvbnN0IHBhZENvdW50ID0gNCAtIChiYXNlNjQubGVuZ3RoICUgNCk7XHJcbiAgICAgICAgaWYgKHBhZENvdW50IDwgNCkge1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhZENvdW50OyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGJhc2U2NCArPSBcIj1cIjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gYmFzZTY0O1xyXG4gICAgfVxyXG4gICAgc3RhdGljIGZvcm1hdFN0cmluZyhkYXRhKSB7XHJcbiAgICAgICAgcmV0dXJuIChkYXRhID09PSBudWxsIHx8IGRhdGEgPT09IHZvaWQgMCA/IHZvaWQgMCA6IGRhdGEucmVwbGFjZSgvW1xcblxcclxcdCBdL2csIFwiXCIpKSB8fCBcIlwiO1xyXG4gICAgfVxyXG59XHJcbkNvbnZlcnQuREVGQVVMVF9VVEY4X0VOQ09ESU5HID0gXCJ1dGY4XCI7XG5cbmZ1bmN0aW9uIGFzc2lnbih0YXJnZXQsIC4uLnNvdXJjZXMpIHtcclxuICAgIGNvbnN0IHJlcyA9IGFyZ3VtZW50c1swXTtcclxuICAgIGZvciAobGV0IGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgY29uc3Qgb2JqID0gYXJndW1lbnRzW2ldO1xyXG4gICAgICAgIGZvciAoY29uc3QgcHJvcCBpbiBvYmopIHtcclxuICAgICAgICAgICAgcmVzW3Byb3BdID0gb2JqW3Byb3BdO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiByZXM7XHJcbn1cclxuZnVuY3Rpb24gY29tYmluZSguLi5idWYpIHtcclxuICAgIGNvbnN0IHRvdGFsQnl0ZUxlbmd0aCA9IGJ1Zi5tYXAoKGl0ZW0pID0+IGl0ZW0uYnl0ZUxlbmd0aCkucmVkdWNlKChwcmV2LCBjdXIpID0+IHByZXYgKyBjdXIpO1xyXG4gICAgY29uc3QgcmVzID0gbmV3IFVpbnQ4QXJyYXkodG90YWxCeXRlTGVuZ3RoKTtcclxuICAgIGxldCBjdXJyZW50UG9zID0gMDtcclxuICAgIGJ1Zi5tYXAoKGl0ZW0pID0+IG5ldyBVaW50OEFycmF5KGl0ZW0pKS5mb3JFYWNoKChhcnIpID0+IHtcclxuICAgICAgICBmb3IgKGNvbnN0IGl0ZW0yIG9mIGFycikge1xyXG4gICAgICAgICAgICByZXNbY3VycmVudFBvcysrXSA9IGl0ZW0yO1xyXG4gICAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIHJlcy5idWZmZXI7XHJcbn1cclxuZnVuY3Rpb24gaXNFcXVhbChieXRlczEsIGJ5dGVzMikge1xyXG4gICAgaWYgKCEoYnl0ZXMxICYmIGJ5dGVzMikpIHtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgICBpZiAoYnl0ZXMxLmJ5dGVMZW5ndGggIT09IGJ5dGVzMi5ieXRlTGVuZ3RoKSB7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gICAgY29uc3QgYjEgPSBuZXcgVWludDhBcnJheShieXRlczEpO1xyXG4gICAgY29uc3QgYjIgPSBuZXcgVWludDhBcnJheShieXRlczIpO1xyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBieXRlczEuYnl0ZUxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgaWYgKGIxW2ldICE9PSBiMltpXSkge1xyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRydWU7XHJcbn1cblxuZXhwb3J0cy5CdWZmZXJTb3VyY2VDb252ZXJ0ZXIgPSBCdWZmZXJTb3VyY2VDb252ZXJ0ZXI7XG5leHBvcnRzLkNvbnZlcnQgPSBDb252ZXJ0O1xuZXhwb3J0cy5hc3NpZ24gPSBhc3NpZ247XG5leHBvcnRzLmNvbWJpbmUgPSBjb21iaW5lO1xuZXhwb3J0cy5pc0VxdWFsID0gaXNFcXVhbDtcbiIsICIvKiFcbiBDb3B5cmlnaHQgKGMpIFBlY3VsaWFyIFZlbnR1cmVzLCBMTENcbiovXG5cbmZ1bmN0aW9uIGdldFVUQ0RhdGUoZGF0ZSkge1xyXG4gICAgcmV0dXJuIG5ldyBEYXRlKGRhdGUuZ2V0VGltZSgpICsgKGRhdGUuZ2V0VGltZXpvbmVPZmZzZXQoKSAqIDYwMDAwKSk7XHJcbn1cclxuZnVuY3Rpb24gZ2V0UGFyYW1ldGVyc1ZhbHVlKHBhcmFtZXRlcnMsIG5hbWUsIGRlZmF1bHRWYWx1ZSkge1xyXG4gICAgdmFyIF9hO1xyXG4gICAgaWYgKChwYXJhbWV0ZXJzIGluc3RhbmNlb2YgT2JqZWN0KSA9PT0gZmFsc2UpIHtcclxuICAgICAgICByZXR1cm4gZGVmYXVsdFZhbHVlO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIChfYSA9IHBhcmFtZXRlcnNbbmFtZV0pICE9PSBudWxsICYmIF9hICE9PSB2b2lkIDAgPyBfYSA6IGRlZmF1bHRWYWx1ZTtcclxufVxyXG5mdW5jdGlvbiBidWZmZXJUb0hleENvZGVzKGlucHV0QnVmZmVyLCBpbnB1dE9mZnNldCA9IDAsIGlucHV0TGVuZ3RoID0gKGlucHV0QnVmZmVyLmJ5dGVMZW5ndGggLSBpbnB1dE9mZnNldCksIGluc2VydFNwYWNlID0gZmFsc2UpIHtcclxuICAgIGxldCByZXN1bHQgPSBcIlwiO1xyXG4gICAgZm9yIChjb25zdCBpdGVtIG9mIChuZXcgVWludDhBcnJheShpbnB1dEJ1ZmZlciwgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoKSkpIHtcclxuICAgICAgICBjb25zdCBzdHIgPSBpdGVtLnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpO1xyXG4gICAgICAgIGlmIChzdHIubGVuZ3RoID09PSAxKSB7XHJcbiAgICAgICAgICAgIHJlc3VsdCArPSBcIjBcIjtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmVzdWx0ICs9IHN0cjtcclxuICAgICAgICBpZiAoaW5zZXJ0U3BhY2UpIHtcclxuICAgICAgICAgICAgcmVzdWx0ICs9IFwiIFwiO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiByZXN1bHQudHJpbSgpO1xyXG59XHJcbmZ1bmN0aW9uIGNoZWNrQnVmZmVyUGFyYW1zKGJhc2VCbG9jaywgaW5wdXRCdWZmZXIsIGlucHV0T2Zmc2V0LCBpbnB1dExlbmd0aCkge1xyXG4gICAgaWYgKCEoaW5wdXRCdWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikpIHtcclxuICAgICAgICBiYXNlQmxvY2suZXJyb3IgPSBcIldyb25nIHBhcmFtZXRlcjogaW5wdXRCdWZmZXIgbXVzdCBiZSBcXFwiQXJyYXlCdWZmZXJcXFwiXCI7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gICAgaWYgKCFpbnB1dEJ1ZmZlci5ieXRlTGVuZ3RoKSB7XHJcbiAgICAgICAgYmFzZUJsb2NrLmVycm9yID0gXCJXcm9uZyBwYXJhbWV0ZXI6IGlucHV0QnVmZmVyIGhhcyB6ZXJvIGxlbmd0aFwiO1xyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIGlmIChpbnB1dE9mZnNldCA8IDApIHtcclxuICAgICAgICBiYXNlQmxvY2suZXJyb3IgPSBcIldyb25nIHBhcmFtZXRlcjogaW5wdXRPZmZzZXQgbGVzcyB0aGFuIHplcm9cIjtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgICBpZiAoaW5wdXRMZW5ndGggPCAwKSB7XHJcbiAgICAgICAgYmFzZUJsb2NrLmVycm9yID0gXCJXcm9uZyBwYXJhbWV0ZXI6IGlucHV0TGVuZ3RoIGxlc3MgdGhhbiB6ZXJvXCI7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gICAgaWYgKChpbnB1dEJ1ZmZlci5ieXRlTGVuZ3RoIC0gaW5wdXRPZmZzZXQgLSBpbnB1dExlbmd0aCkgPCAwKSB7XHJcbiAgICAgICAgYmFzZUJsb2NrLmVycm9yID0gXCJFbmQgb2YgaW5wdXQgcmVhY2hlZCBiZWZvcmUgbWVzc2FnZSB3YXMgZnVsbHkgZGVjb2RlZCAoaW5jb25zaXN0ZW50IG9mZnNldCBhbmQgbGVuZ3RoIHZhbHVlcylcIjtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdHJ1ZTtcclxufVxyXG5mdW5jdGlvbiB1dGlsRnJvbUJhc2UoaW5wdXRCdWZmZXIsIGlucHV0QmFzZSkge1xyXG4gICAgbGV0IHJlc3VsdCA9IDA7XHJcbiAgICBpZiAoaW5wdXRCdWZmZXIubGVuZ3RoID09PSAxKSB7XHJcbiAgICAgICAgcmV0dXJuIGlucHV0QnVmZmVyWzBdO1xyXG4gICAgfVxyXG4gICAgZm9yIChsZXQgaSA9IChpbnB1dEJ1ZmZlci5sZW5ndGggLSAxKTsgaSA+PSAwOyBpLS0pIHtcclxuICAgICAgICByZXN1bHQgKz0gaW5wdXRCdWZmZXJbKGlucHV0QnVmZmVyLmxlbmd0aCAtIDEpIC0gaV0gKiBNYXRoLnBvdygyLCBpbnB1dEJhc2UgKiBpKTtcclxuICAgIH1cclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn1cclxuZnVuY3Rpb24gdXRpbFRvQmFzZSh2YWx1ZSwgYmFzZSwgcmVzZXJ2ZWQgPSAoLTEpKSB7XHJcbiAgICBjb25zdCBpbnRlcm5hbFJlc2VydmVkID0gcmVzZXJ2ZWQ7XHJcbiAgICBsZXQgaW50ZXJuYWxWYWx1ZSA9IHZhbHVlO1xyXG4gICAgbGV0IHJlc3VsdCA9IDA7XHJcbiAgICBsZXQgYmlnZ2VzdCA9IE1hdGgucG93KDIsIGJhc2UpO1xyXG4gICAgZm9yIChsZXQgaSA9IDE7IGkgPCA4OyBpKyspIHtcclxuICAgICAgICBpZiAodmFsdWUgPCBiaWdnZXN0KSB7XHJcbiAgICAgICAgICAgIGxldCByZXRCdWY7XHJcbiAgICAgICAgICAgIGlmIChpbnRlcm5hbFJlc2VydmVkIDwgMCkge1xyXG4gICAgICAgICAgICAgICAgcmV0QnVmID0gbmV3IEFycmF5QnVmZmVyKGkpO1xyXG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gaTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGlmIChpbnRlcm5hbFJlc2VydmVkIDwgaSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAobmV3IEFycmF5QnVmZmVyKDApKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldEJ1ZiA9IG5ldyBBcnJheUJ1ZmZlcihpbnRlcm5hbFJlc2VydmVkKTtcclxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGludGVybmFsUmVzZXJ2ZWQ7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY29uc3QgcmV0VmlldyA9IG5ldyBVaW50OEFycmF5KHJldEJ1Zik7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGogPSAoaSAtIDEpOyBqID49IDA7IGotLSkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgYmFzaXMgPSBNYXRoLnBvdygyLCBqICogYmFzZSk7XHJcbiAgICAgICAgICAgICAgICByZXRWaWV3W3Jlc3VsdCAtIGogLSAxXSA9IE1hdGguZmxvb3IoaW50ZXJuYWxWYWx1ZSAvIGJhc2lzKTtcclxuICAgICAgICAgICAgICAgIGludGVybmFsVmFsdWUgLT0gKHJldFZpZXdbcmVzdWx0IC0gaiAtIDFdKSAqIGJhc2lzO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiByZXRCdWY7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGJpZ2dlc3QgKj0gTWF0aC5wb3coMiwgYmFzZSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbmV3IEFycmF5QnVmZmVyKDApO1xyXG59XHJcbmZ1bmN0aW9uIHV0aWxDb25jYXRCdWYoLi4uYnVmZmVycykge1xyXG4gICAgbGV0IG91dHB1dExlbmd0aCA9IDA7XHJcbiAgICBsZXQgcHJldkxlbmd0aCA9IDA7XHJcbiAgICBmb3IgKGNvbnN0IGJ1ZmZlciBvZiBidWZmZXJzKSB7XHJcbiAgICAgICAgb3V0cHV0TGVuZ3RoICs9IGJ1ZmZlci5ieXRlTGVuZ3RoO1xyXG4gICAgfVxyXG4gICAgY29uc3QgcmV0QnVmID0gbmV3IEFycmF5QnVmZmVyKG91dHB1dExlbmd0aCk7XHJcbiAgICBjb25zdCByZXRWaWV3ID0gbmV3IFVpbnQ4QXJyYXkocmV0QnVmKTtcclxuICAgIGZvciAoY29uc3QgYnVmZmVyIG9mIGJ1ZmZlcnMpIHtcclxuICAgICAgICByZXRWaWV3LnNldChuZXcgVWludDhBcnJheShidWZmZXIpLCBwcmV2TGVuZ3RoKTtcclxuICAgICAgICBwcmV2TGVuZ3RoICs9IGJ1ZmZlci5ieXRlTGVuZ3RoO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHJldEJ1ZjtcclxufVxyXG5mdW5jdGlvbiB1dGlsQ29uY2F0VmlldyguLi52aWV3cykge1xyXG4gICAgbGV0IG91dHB1dExlbmd0aCA9IDA7XHJcbiAgICBsZXQgcHJldkxlbmd0aCA9IDA7XHJcbiAgICBmb3IgKGNvbnN0IHZpZXcgb2Ygdmlld3MpIHtcclxuICAgICAgICBvdXRwdXRMZW5ndGggKz0gdmlldy5sZW5ndGg7XHJcbiAgICB9XHJcbiAgICBjb25zdCByZXRCdWYgPSBuZXcgQXJyYXlCdWZmZXIob3V0cHV0TGVuZ3RoKTtcclxuICAgIGNvbnN0IHJldFZpZXcgPSBuZXcgVWludDhBcnJheShyZXRCdWYpO1xyXG4gICAgZm9yIChjb25zdCB2aWV3IG9mIHZpZXdzKSB7XHJcbiAgICAgICAgcmV0Vmlldy5zZXQodmlldywgcHJldkxlbmd0aCk7XHJcbiAgICAgICAgcHJldkxlbmd0aCArPSB2aWV3Lmxlbmd0aDtcclxuICAgIH1cclxuICAgIHJldHVybiByZXRWaWV3O1xyXG59XHJcbmZ1bmN0aW9uIHV0aWxEZWNvZGVUQygpIHtcclxuICAgIGNvbnN0IGJ1ZiA9IG5ldyBVaW50OEFycmF5KHRoaXMudmFsdWVIZXgpO1xyXG4gICAgaWYgKHRoaXMudmFsdWVIZXguYnl0ZUxlbmd0aCA+PSAyKSB7XHJcbiAgICAgICAgY29uc3QgY29uZGl0aW9uMSA9IChidWZbMF0gPT09IDB4RkYpICYmIChidWZbMV0gJiAweDgwKTtcclxuICAgICAgICBjb25zdCBjb25kaXRpb24yID0gKGJ1ZlswXSA9PT0gMHgwMCkgJiYgKChidWZbMV0gJiAweDgwKSA9PT0gMHgwMCk7XHJcbiAgICAgICAgaWYgKGNvbmRpdGlvbjEgfHwgY29uZGl0aW9uMikge1xyXG4gICAgICAgICAgICB0aGlzLndhcm5pbmdzLnB1c2goXCJOZWVkbGVzc2x5IGxvbmcgZm9ybWF0XCIpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGNvbnN0IGJpZ0ludEJ1ZmZlciA9IG5ldyBBcnJheUJ1ZmZlcih0aGlzLnZhbHVlSGV4LmJ5dGVMZW5ndGgpO1xyXG4gICAgY29uc3QgYmlnSW50VmlldyA9IG5ldyBVaW50OEFycmF5KGJpZ0ludEJ1ZmZlcik7XHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMudmFsdWVIZXguYnl0ZUxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgYmlnSW50Vmlld1tpXSA9IDA7XHJcbiAgICB9XHJcbiAgICBiaWdJbnRWaWV3WzBdID0gKGJ1ZlswXSAmIDB4ODApO1xyXG4gICAgY29uc3QgYmlnSW50ID0gdXRpbEZyb21CYXNlKGJpZ0ludFZpZXcsIDgpO1xyXG4gICAgY29uc3Qgc21hbGxJbnRCdWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIodGhpcy52YWx1ZUhleC5ieXRlTGVuZ3RoKTtcclxuICAgIGNvbnN0IHNtYWxsSW50VmlldyA9IG5ldyBVaW50OEFycmF5KHNtYWxsSW50QnVmZmVyKTtcclxuICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy52YWx1ZUhleC5ieXRlTGVuZ3RoOyBqKyspIHtcclxuICAgICAgICBzbWFsbEludFZpZXdbal0gPSBidWZbal07XHJcbiAgICB9XHJcbiAgICBzbWFsbEludFZpZXdbMF0gJj0gMHg3RjtcclxuICAgIGNvbnN0IHNtYWxsSW50ID0gdXRpbEZyb21CYXNlKHNtYWxsSW50VmlldywgOCk7XHJcbiAgICByZXR1cm4gKHNtYWxsSW50IC0gYmlnSW50KTtcclxufVxyXG5mdW5jdGlvbiB1dGlsRW5jb2RlVEModmFsdWUpIHtcclxuICAgIGNvbnN0IG1vZFZhbHVlID0gKHZhbHVlIDwgMCkgPyAodmFsdWUgKiAoLTEpKSA6IHZhbHVlO1xyXG4gICAgbGV0IGJpZ0ludCA9IDEyODtcclxuICAgIGZvciAobGV0IGkgPSAxOyBpIDwgODsgaSsrKSB7XHJcbiAgICAgICAgaWYgKG1vZFZhbHVlIDw9IGJpZ0ludCkge1xyXG4gICAgICAgICAgICBpZiAodmFsdWUgPCAwKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBzbWFsbEludCA9IGJpZ0ludCAtIG1vZFZhbHVlO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcmV0QnVmID0gdXRpbFRvQmFzZShzbWFsbEludCwgOCwgaSk7XHJcbiAgICAgICAgICAgICAgICBjb25zdCByZXRWaWV3ID0gbmV3IFVpbnQ4QXJyYXkocmV0QnVmKTtcclxuICAgICAgICAgICAgICAgIHJldFZpZXdbMF0gfD0gMHg4MDtcclxuICAgICAgICAgICAgICAgIHJldHVybiByZXRCdWY7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgbGV0IHJldEJ1ZiA9IHV0aWxUb0Jhc2UobW9kVmFsdWUsIDgsIGkpO1xyXG4gICAgICAgICAgICBsZXQgcmV0VmlldyA9IG5ldyBVaW50OEFycmF5KHJldEJ1Zik7XHJcbiAgICAgICAgICAgIGlmIChyZXRWaWV3WzBdICYgMHg4MCkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgdGVtcEJ1ZiA9IHJldEJ1Zi5zbGljZSgwKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHRlbXBWaWV3ID0gbmV3IFVpbnQ4QXJyYXkodGVtcEJ1Zik7XHJcbiAgICAgICAgICAgICAgICByZXRCdWYgPSBuZXcgQXJyYXlCdWZmZXIocmV0QnVmLmJ5dGVMZW5ndGggKyAxKTtcclxuICAgICAgICAgICAgICAgIHJldFZpZXcgPSBuZXcgVWludDhBcnJheShyZXRCdWYpO1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCB0ZW1wQnVmLmJ5dGVMZW5ndGg7IGsrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldFZpZXdbayArIDFdID0gdGVtcFZpZXdba107XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXRWaWV3WzBdID0gMHgwMDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gcmV0QnVmO1xyXG4gICAgICAgIH1cclxuICAgICAgICBiaWdJbnQgKj0gTWF0aC5wb3coMiwgOCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gKG5ldyBBcnJheUJ1ZmZlcigwKSk7XHJcbn1cclxuZnVuY3Rpb24gaXNFcXVhbEJ1ZmZlcihpbnB1dEJ1ZmZlcjEsIGlucHV0QnVmZmVyMikge1xyXG4gICAgaWYgKGlucHV0QnVmZmVyMS5ieXRlTGVuZ3RoICE9PSBpbnB1dEJ1ZmZlcjIuYnl0ZUxlbmd0aCkge1xyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIGNvbnN0IHZpZXcxID0gbmV3IFVpbnQ4QXJyYXkoaW5wdXRCdWZmZXIxKTtcclxuICAgIGNvbnN0IHZpZXcyID0gbmV3IFVpbnQ4QXJyYXkoaW5wdXRCdWZmZXIyKTtcclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdmlldzEubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBpZiAodmlldzFbaV0gIT09IHZpZXcyW2ldKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdHJ1ZTtcclxufVxyXG5mdW5jdGlvbiBwYWROdW1iZXIoaW5wdXROdW1iZXIsIGZ1bGxMZW5ndGgpIHtcclxuICAgIGNvbnN0IHN0ciA9IGlucHV0TnVtYmVyLnRvU3RyaW5nKDEwKTtcclxuICAgIGlmIChmdWxsTGVuZ3RoIDwgc3RyLmxlbmd0aCkge1xyXG4gICAgICAgIHJldHVybiBcIlwiO1xyXG4gICAgfVxyXG4gICAgY29uc3QgZGlmID0gZnVsbExlbmd0aCAtIHN0ci5sZW5ndGg7XHJcbiAgICBjb25zdCBwYWRkaW5nID0gbmV3IEFycmF5KGRpZik7XHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRpZjsgaSsrKSB7XHJcbiAgICAgICAgcGFkZGluZ1tpXSA9IFwiMFwiO1xyXG4gICAgfVxyXG4gICAgY29uc3QgcGFkZGluZ1N0cmluZyA9IHBhZGRpbmcuam9pbihcIlwiKTtcclxuICAgIHJldHVybiBwYWRkaW5nU3RyaW5nLmNvbmNhdChzdHIpO1xyXG59XHJcbmNvbnN0IGJhc2U2NFRlbXBsYXRlID0gXCJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvPVwiO1xyXG5jb25zdCBiYXNlNjRVcmxUZW1wbGF0ZSA9IFwiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODktXz1cIjtcclxuZnVuY3Rpb24gdG9CYXNlNjQoaW5wdXQsIHVzZVVybFRlbXBsYXRlID0gZmFsc2UsIHNraXBQYWRkaW5nID0gZmFsc2UsIHNraXBMZWFkaW5nWmVyb3MgPSBmYWxzZSkge1xyXG4gICAgbGV0IGkgPSAwO1xyXG4gICAgbGV0IGZsYWcxID0gMDtcclxuICAgIGxldCBmbGFnMiA9IDA7XHJcbiAgICBsZXQgb3V0cHV0ID0gXCJcIjtcclxuICAgIGNvbnN0IHRlbXBsYXRlID0gKHVzZVVybFRlbXBsYXRlKSA/IGJhc2U2NFVybFRlbXBsYXRlIDogYmFzZTY0VGVtcGxhdGU7XHJcbiAgICBpZiAoc2tpcExlYWRpbmdaZXJvcykge1xyXG4gICAgICAgIGxldCBub25aZXJvUG9zaXRpb24gPSAwO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXQubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgaWYgKGlucHV0LmNoYXJDb2RlQXQoaSkgIT09IDApIHtcclxuICAgICAgICAgICAgICAgIG5vblplcm9Qb3NpdGlvbiA9IGk7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBpbnB1dCA9IGlucHV0LnNsaWNlKG5vblplcm9Qb3NpdGlvbik7XHJcbiAgICB9XHJcbiAgICB3aGlsZSAoaSA8IGlucHV0Lmxlbmd0aCkge1xyXG4gICAgICAgIGNvbnN0IGNocjEgPSBpbnB1dC5jaGFyQ29kZUF0KGkrKyk7XHJcbiAgICAgICAgaWYgKGkgPj0gaW5wdXQubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIGZsYWcxID0gMTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgY2hyMiA9IGlucHV0LmNoYXJDb2RlQXQoaSsrKTtcclxuICAgICAgICBpZiAoaSA+PSBpbnB1dC5sZW5ndGgpIHtcclxuICAgICAgICAgICAgZmxhZzIgPSAxO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBjaHIzID0gaW5wdXQuY2hhckNvZGVBdChpKyspO1xyXG4gICAgICAgIGNvbnN0IGVuYzEgPSBjaHIxID4+IDI7XHJcbiAgICAgICAgY29uc3QgZW5jMiA9ICgoY2hyMSAmIDB4MDMpIDw8IDQpIHwgKGNocjIgPj4gNCk7XHJcbiAgICAgICAgbGV0IGVuYzMgPSAoKGNocjIgJiAweDBGKSA8PCAyKSB8IChjaHIzID4+IDYpO1xyXG4gICAgICAgIGxldCBlbmM0ID0gY2hyMyAmIDB4M0Y7XHJcbiAgICAgICAgaWYgKGZsYWcxID09PSAxKSB7XHJcbiAgICAgICAgICAgIGVuYzMgPSBlbmM0ID0gNjQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBpZiAoZmxhZzIgPT09IDEpIHtcclxuICAgICAgICAgICAgICAgIGVuYzQgPSA2NDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoc2tpcFBhZGRpbmcpIHtcclxuICAgICAgICAgICAgaWYgKGVuYzMgPT09IDY0KSB7XHJcbiAgICAgICAgICAgICAgICBvdXRwdXQgKz0gYCR7dGVtcGxhdGUuY2hhckF0KGVuYzEpfSR7dGVtcGxhdGUuY2hhckF0KGVuYzIpfWA7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZW5jNCA9PT0gNjQpIHtcclxuICAgICAgICAgICAgICAgICAgICBvdXRwdXQgKz0gYCR7dGVtcGxhdGUuY2hhckF0KGVuYzEpfSR7dGVtcGxhdGUuY2hhckF0KGVuYzIpfSR7dGVtcGxhdGUuY2hhckF0KGVuYzMpfWA7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBvdXRwdXQgKz0gYCR7dGVtcGxhdGUuY2hhckF0KGVuYzEpfSR7dGVtcGxhdGUuY2hhckF0KGVuYzIpfSR7dGVtcGxhdGUuY2hhckF0KGVuYzMpfSR7dGVtcGxhdGUuY2hhckF0KGVuYzQpfWA7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIG91dHB1dCArPSBgJHt0ZW1wbGF0ZS5jaGFyQXQoZW5jMSl9JHt0ZW1wbGF0ZS5jaGFyQXQoZW5jMil9JHt0ZW1wbGF0ZS5jaGFyQXQoZW5jMyl9JHt0ZW1wbGF0ZS5jaGFyQXQoZW5jNCl9YDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gb3V0cHV0O1xyXG59XHJcbmZ1bmN0aW9uIGZyb21CYXNlNjQoaW5wdXQsIHVzZVVybFRlbXBsYXRlID0gZmFsc2UsIGN1dFRhaWxaZXJvcyA9IGZhbHNlKSB7XHJcbiAgICBjb25zdCB0ZW1wbGF0ZSA9ICh1c2VVcmxUZW1wbGF0ZSkgPyBiYXNlNjRVcmxUZW1wbGF0ZSA6IGJhc2U2NFRlbXBsYXRlO1xyXG4gICAgZnVuY3Rpb24gaW5kZXhPZih0b1NlYXJjaCkge1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgNjQ7IGkrKykge1xyXG4gICAgICAgICAgICBpZiAodGVtcGxhdGUuY2hhckF0KGkpID09PSB0b1NlYXJjaClcclxuICAgICAgICAgICAgICAgIHJldHVybiBpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gNjQ7XHJcbiAgICB9XHJcbiAgICBmdW5jdGlvbiB0ZXN0KGluY29taW5nKSB7XHJcbiAgICAgICAgcmV0dXJuICgoaW5jb21pbmcgPT09IDY0KSA/IDB4MDAgOiBpbmNvbWluZyk7XHJcbiAgICB9XHJcbiAgICBsZXQgaSA9IDA7XHJcbiAgICBsZXQgb3V0cHV0ID0gXCJcIjtcclxuICAgIHdoaWxlIChpIDwgaW5wdXQubGVuZ3RoKSB7XHJcbiAgICAgICAgY29uc3QgZW5jMSA9IGluZGV4T2YoaW5wdXQuY2hhckF0KGkrKykpO1xyXG4gICAgICAgIGNvbnN0IGVuYzIgPSAoaSA+PSBpbnB1dC5sZW5ndGgpID8gMHgwMCA6IGluZGV4T2YoaW5wdXQuY2hhckF0KGkrKykpO1xyXG4gICAgICAgIGNvbnN0IGVuYzMgPSAoaSA+PSBpbnB1dC5sZW5ndGgpID8gMHgwMCA6IGluZGV4T2YoaW5wdXQuY2hhckF0KGkrKykpO1xyXG4gICAgICAgIGNvbnN0IGVuYzQgPSAoaSA+PSBpbnB1dC5sZW5ndGgpID8gMHgwMCA6IGluZGV4T2YoaW5wdXQuY2hhckF0KGkrKykpO1xyXG4gICAgICAgIGNvbnN0IGNocjEgPSAodGVzdChlbmMxKSA8PCAyKSB8ICh0ZXN0KGVuYzIpID4+IDQpO1xyXG4gICAgICAgIGNvbnN0IGNocjIgPSAoKHRlc3QoZW5jMikgJiAweDBGKSA8PCA0KSB8ICh0ZXN0KGVuYzMpID4+IDIpO1xyXG4gICAgICAgIGNvbnN0IGNocjMgPSAoKHRlc3QoZW5jMykgJiAweDAzKSA8PCA2KSB8IHRlc3QoZW5jNCk7XHJcbiAgICAgICAgb3V0cHV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoY2hyMSk7XHJcbiAgICAgICAgaWYgKGVuYzMgIT09IDY0KSB7XHJcbiAgICAgICAgICAgIG91dHB1dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGNocjIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoZW5jNCAhPT0gNjQpIHtcclxuICAgICAgICAgICAgb3V0cHV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoY2hyMyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKGN1dFRhaWxaZXJvcykge1xyXG4gICAgICAgIGNvbnN0IG91dHB1dExlbmd0aCA9IG91dHB1dC5sZW5ndGg7XHJcbiAgICAgICAgbGV0IG5vblplcm9TdGFydCA9ICgtMSk7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IChvdXRwdXRMZW5ndGggLSAxKTsgaSA+PSAwOyBpLS0pIHtcclxuICAgICAgICAgICAgaWYgKG91dHB1dC5jaGFyQ29kZUF0KGkpICE9PSAwKSB7XHJcbiAgICAgICAgICAgICAgICBub25aZXJvU3RhcnQgPSBpO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKG5vblplcm9TdGFydCAhPT0gKC0xKSkge1xyXG4gICAgICAgICAgICBvdXRwdXQgPSBvdXRwdXQuc2xpY2UoMCwgbm9uWmVyb1N0YXJ0ICsgMSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBvdXRwdXQgPSBcIlwiO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBvdXRwdXQ7XHJcbn1cclxuZnVuY3Rpb24gYXJyYXlCdWZmZXJUb1N0cmluZyhidWZmZXIpIHtcclxuICAgIGxldCByZXN1bHRTdHJpbmcgPSBcIlwiO1xyXG4gICAgY29uc3QgdmlldyA9IG5ldyBVaW50OEFycmF5KGJ1ZmZlcik7XHJcbiAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2Ygdmlldykge1xyXG4gICAgICAgIHJlc3VsdFN0cmluZyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGVsZW1lbnQpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHJlc3VsdFN0cmluZztcclxufVxyXG5mdW5jdGlvbiBzdHJpbmdUb0FycmF5QnVmZmVyKHN0cikge1xyXG4gICAgY29uc3Qgc3RyaW5nTGVuZ3RoID0gc3RyLmxlbmd0aDtcclxuICAgIGNvbnN0IHJlc3VsdEJ1ZmZlciA9IG5ldyBBcnJheUJ1ZmZlcihzdHJpbmdMZW5ndGgpO1xyXG4gICAgY29uc3QgcmVzdWx0VmlldyA9IG5ldyBVaW50OEFycmF5KHJlc3VsdEJ1ZmZlcik7XHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHN0cmluZ0xlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgcmVzdWx0Vmlld1tpXSA9IHN0ci5jaGFyQ29kZUF0KGkpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHJlc3VsdEJ1ZmZlcjtcclxufVxyXG5jb25zdCBsb2cyID0gTWF0aC5sb2coMik7XHJcbmZ1bmN0aW9uIG5lYXJlc3RQb3dlck9mMihsZW5ndGgpIHtcclxuICAgIGNvbnN0IGJhc2UgPSAoTWF0aC5sb2cobGVuZ3RoKSAvIGxvZzIpO1xyXG4gICAgY29uc3QgZmxvb3IgPSBNYXRoLmZsb29yKGJhc2UpO1xyXG4gICAgY29uc3Qgcm91bmQgPSBNYXRoLnJvdW5kKGJhc2UpO1xyXG4gICAgcmV0dXJuICgoZmxvb3IgPT09IHJvdW5kKSA/IGZsb29yIDogcm91bmQpO1xyXG59XHJcbmZ1bmN0aW9uIGNsZWFyUHJvcHMob2JqZWN0LCBwcm9wc0FycmF5KSB7XHJcbiAgICBmb3IgKGNvbnN0IHByb3Agb2YgcHJvcHNBcnJheSkge1xyXG4gICAgICAgIGRlbGV0ZSBvYmplY3RbcHJvcF07XHJcbiAgICB9XHJcbn1cblxuZXhwb3J0IHsgYXJyYXlCdWZmZXJUb1N0cmluZywgYnVmZmVyVG9IZXhDb2RlcywgY2hlY2tCdWZmZXJQYXJhbXMsIGNsZWFyUHJvcHMsIGZyb21CYXNlNjQsIGdldFBhcmFtZXRlcnNWYWx1ZSwgZ2V0VVRDRGF0ZSwgaXNFcXVhbEJ1ZmZlciwgbmVhcmVzdFBvd2VyT2YyLCBwYWROdW1iZXIsIHN0cmluZ1RvQXJyYXlCdWZmZXIsIHRvQmFzZTY0LCB1dGlsQ29uY2F0QnVmLCB1dGlsQ29uY2F0VmlldywgdXRpbERlY29kZVRDLCB1dGlsRW5jb2RlVEMsIHV0aWxGcm9tQmFzZSwgdXRpbFRvQmFzZSB9O1xuIiwgIi8qIVxuICogQ29weXJpZ2h0IChjKSAyMDE0LCBHTU8gR2xvYmFsU2lnblxuICogQ29weXJpZ2h0IChjKSAyMDE1LTIwMjIsIFBlY3VsaWFyIFZlbnR1cmVzXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICogXG4gKiBBdXRob3IgMjAxNC0yMDE5LCBZdXJ5IFN0cm96aGV2c2t5XG4gKiBcbiAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dCBtb2RpZmljYXRpb24sXG4gKiBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4gKiBcbiAqICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4gKiAgIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuICogXG4gKiAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuICogICBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3JcbiAqICAgb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cbiAqIFxuICogKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBjb3B5cmlnaHQgaG9sZGVyIG5vciB0aGUgbmFtZXMgb2YgaXRzXG4gKiAgIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tXG4gKiAgIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4gKiBcbiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiIEFORFxuICogQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRURcbiAqIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkVcbiAqIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SXG4gKiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVNcbiAqIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUztcbiAqIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTlxuICogQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlRcbiAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTXG4gKiBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqIFxuICovXG5cbmltcG9ydCAqIGFzIHB2dHN1dGlscyBmcm9tICdwdnRzdXRpbHMnO1xuaW1wb3J0ICogYXMgcHZ1dGlscyBmcm9tICdwdnV0aWxzJztcblxuZnVuY3Rpb24gYXNzZXJ0QmlnSW50KCkge1xyXG4gICAgaWYgKHR5cGVvZiBCaWdJbnQgPT09IFwidW5kZWZpbmVkXCIpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJCaWdJbnQgaXMgbm90IGRlZmluZWQuIFlvdXIgZW52aXJvbm1lbnQgZG9lc24ndCBpbXBsZW1lbnQgQmlnSW50LlwiKTtcclxuICAgIH1cclxufVxyXG5mdW5jdGlvbiBjb25jYXQoYnVmZmVycykge1xyXG4gICAgbGV0IG91dHB1dExlbmd0aCA9IDA7XHJcbiAgICBsZXQgcHJldkxlbmd0aCA9IDA7XHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJ1ZmZlcnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBjb25zdCBidWZmZXIgPSBidWZmZXJzW2ldO1xyXG4gICAgICAgIG91dHB1dExlbmd0aCArPSBidWZmZXIuYnl0ZUxlbmd0aDtcclxuICAgIH1cclxuICAgIGNvbnN0IHJldFZpZXcgPSBuZXcgVWludDhBcnJheShvdXRwdXRMZW5ndGgpO1xyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBidWZmZXJzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgY29uc3QgYnVmZmVyID0gYnVmZmVyc1tpXTtcclxuICAgICAgICByZXRWaWV3LnNldChuZXcgVWludDhBcnJheShidWZmZXIpLCBwcmV2TGVuZ3RoKTtcclxuICAgICAgICBwcmV2TGVuZ3RoICs9IGJ1ZmZlci5ieXRlTGVuZ3RoO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHJldFZpZXcuYnVmZmVyO1xyXG59XHJcbmZ1bmN0aW9uIGNoZWNrQnVmZmVyUGFyYW1zKGJhc2VCbG9jaywgaW5wdXRCdWZmZXIsIGlucHV0T2Zmc2V0LCBpbnB1dExlbmd0aCkge1xyXG4gICAgaWYgKCEoaW5wdXRCdWZmZXIgaW5zdGFuY2VvZiBVaW50OEFycmF5KSkge1xyXG4gICAgICAgIGJhc2VCbG9jay5lcnJvciA9IFwiV3JvbmcgcGFyYW1ldGVyOiBpbnB1dEJ1ZmZlciBtdXN0IGJlICdVaW50OEFycmF5J1wiO1xyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIGlmICghaW5wdXRCdWZmZXIuYnl0ZUxlbmd0aCkge1xyXG4gICAgICAgIGJhc2VCbG9jay5lcnJvciA9IFwiV3JvbmcgcGFyYW1ldGVyOiBpbnB1dEJ1ZmZlciBoYXMgemVybyBsZW5ndGhcIjtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgICBpZiAoaW5wdXRPZmZzZXQgPCAwKSB7XHJcbiAgICAgICAgYmFzZUJsb2NrLmVycm9yID0gXCJXcm9uZyBwYXJhbWV0ZXI6IGlucHV0T2Zmc2V0IGxlc3MgdGhhbiB6ZXJvXCI7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gICAgaWYgKGlucHV0TGVuZ3RoIDwgMCkge1xyXG4gICAgICAgIGJhc2VCbG9jay5lcnJvciA9IFwiV3JvbmcgcGFyYW1ldGVyOiBpbnB1dExlbmd0aCBsZXNzIHRoYW4gemVyb1wiO1xyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIGlmICgoaW5wdXRCdWZmZXIuYnl0ZUxlbmd0aCAtIGlucHV0T2Zmc2V0IC0gaW5wdXRMZW5ndGgpIDwgMCkge1xyXG4gICAgICAgIGJhc2VCbG9jay5lcnJvciA9IFwiRW5kIG9mIGlucHV0IHJlYWNoZWQgYmVmb3JlIG1lc3NhZ2Ugd2FzIGZ1bGx5IGRlY29kZWQgKGluY29uc2lzdGVudCBvZmZzZXQgYW5kIGxlbmd0aCB2YWx1ZXMpXCI7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRydWU7XHJcbn1cblxuY2xhc3MgVmlld1dyaXRlciB7XHJcbiAgICBjb25zdHJ1Y3RvcigpIHtcclxuICAgICAgICB0aGlzLml0ZW1zID0gW107XHJcbiAgICB9XHJcbiAgICB3cml0ZShidWYpIHtcclxuICAgICAgICB0aGlzLml0ZW1zLnB1c2goYnVmKTtcclxuICAgIH1cclxuICAgIGZpbmFsKCkge1xyXG4gICAgICAgIHJldHVybiBjb25jYXQodGhpcy5pdGVtcyk7XHJcbiAgICB9XHJcbn1cblxuY29uc3QgcG93ZXJzMiA9IFtuZXcgVWludDhBcnJheShbMV0pXTtcclxuY29uc3QgZGlnaXRzU3RyaW5nID0gXCIwMTIzNDU2Nzg5XCI7XHJcbmNvbnN0IE5BTUUgPSBcIm5hbWVcIjtcclxuY29uc3QgVkFMVUVfSEVYX1ZJRVcgPSBcInZhbHVlSGV4Vmlld1wiO1xyXG5jb25zdCBJU19IRVhfT05MWSA9IFwiaXNIZXhPbmx5XCI7XHJcbmNvbnN0IElEX0JMT0NLID0gXCJpZEJsb2NrXCI7XHJcbmNvbnN0IFRBR19DTEFTUyA9IFwidGFnQ2xhc3NcIjtcclxuY29uc3QgVEFHX05VTUJFUiA9IFwidGFnTnVtYmVyXCI7XHJcbmNvbnN0IElTX0NPTlNUUlVDVEVEID0gXCJpc0NvbnN0cnVjdGVkXCI7XHJcbmNvbnN0IEZST01fQkVSID0gXCJmcm9tQkVSXCI7XHJcbmNvbnN0IFRPX0JFUiA9IFwidG9CRVJcIjtcclxuY29uc3QgTE9DQUwgPSBcImxvY2FsXCI7XHJcbmNvbnN0IEVNUFRZX1NUUklORyA9IFwiXCI7XHJcbmNvbnN0IEVNUFRZX0JVRkZFUiA9IG5ldyBBcnJheUJ1ZmZlcigwKTtcclxuY29uc3QgRU1QVFlfVklFVyA9IG5ldyBVaW50OEFycmF5KDApO1xyXG5jb25zdCBFTkRfT0ZfQ09OVEVOVF9OQU1FID0gXCJFbmRPZkNvbnRlbnRcIjtcclxuY29uc3QgT0NURVRfU1RSSU5HX05BTUUgPSBcIk9DVEVUIFNUUklOR1wiO1xyXG5jb25zdCBCSVRfU1RSSU5HX05BTUUgPSBcIkJJVCBTVFJJTkdcIjtcblxuZnVuY3Rpb24gSGV4QmxvY2soQmFzZUNsYXNzKSB7XHJcbiAgICB2YXIgX2E7XHJcbiAgICByZXR1cm4gX2EgPSBjbGFzcyBTb21lIGV4dGVuZHMgQmFzZUNsYXNzIHtcclxuICAgICAgICAgICAgY29uc3RydWN0b3IoLi4uYXJncykge1xyXG4gICAgICAgICAgICAgICAgdmFyIF9hO1xyXG4gICAgICAgICAgICAgICAgc3VwZXIoLi4uYXJncyk7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBwYXJhbXMgPSBhcmdzWzBdIHx8IHt9O1xyXG4gICAgICAgICAgICAgICAgdGhpcy5pc0hleE9ubHkgPSAoX2EgPSBwYXJhbXMuaXNIZXhPbmx5KSAhPT0gbnVsbCAmJiBfYSAhPT0gdm9pZCAwID8gX2EgOiBmYWxzZTtcclxuICAgICAgICAgICAgICAgIHRoaXMudmFsdWVIZXhWaWV3ID0gcGFyYW1zLnZhbHVlSGV4ID8gcHZ0c3V0aWxzLkJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b1VpbnQ4QXJyYXkocGFyYW1zLnZhbHVlSGV4KSA6IEVNUFRZX1ZJRVc7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZ2V0IHZhbHVlSGV4KCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudmFsdWVIZXhWaWV3LnNsaWNlKCkuYnVmZmVyO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHNldCB2YWx1ZUhleCh2YWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy52YWx1ZUhleFZpZXcgPSBuZXcgVWludDhBcnJheSh2YWx1ZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZnJvbUJFUihpbnB1dEJ1ZmZlciwgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCB2aWV3ID0gaW5wdXRCdWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlciA/IG5ldyBVaW50OEFycmF5KGlucHV0QnVmZmVyKSA6IGlucHV0QnVmZmVyO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFjaGVja0J1ZmZlclBhcmFtcyh0aGlzLCB2aWV3LCBpbnB1dE9mZnNldCwgaW5wdXRMZW5ndGgpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgY29uc3QgZW5kTGVuZ3RoID0gaW5wdXRPZmZzZXQgKyBpbnB1dExlbmd0aDtcclxuICAgICAgICAgICAgICAgIHRoaXMudmFsdWVIZXhWaWV3ID0gdmlldy5zdWJhcnJheShpbnB1dE9mZnNldCwgZW5kTGVuZ3RoKTtcclxuICAgICAgICAgICAgICAgIGlmICghdGhpcy52YWx1ZUhleFZpZXcubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy53YXJuaW5ncy5wdXNoKFwiWmVybyBidWZmZXIgbGVuZ3RoXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dE9mZnNldDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHRoaXMuYmxvY2tMZW5ndGggPSBpbnB1dExlbmd0aDtcclxuICAgICAgICAgICAgICAgIHJldHVybiBlbmRMZW5ndGg7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdG9CRVIoc2l6ZU9ubHkgPSBmYWxzZSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmlzSGV4T25seSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXJyb3IgPSBcIkZsYWcgJ2lzSGV4T25seScgaXMgbm90IHNldCwgYWJvcnRcIjtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gRU1QVFlfQlVGRkVSO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKHNpemVPbmx5KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBBcnJheUJ1ZmZlcih0aGlzLnZhbHVlSGV4Vmlldy5ieXRlTGVuZ3RoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldHVybiAodGhpcy52YWx1ZUhleFZpZXcuYnl0ZUxlbmd0aCA9PT0gdGhpcy52YWx1ZUhleFZpZXcuYnVmZmVyLmJ5dGVMZW5ndGgpXHJcbiAgICAgICAgICAgICAgICAgICAgPyB0aGlzLnZhbHVlSGV4Vmlldy5idWZmZXJcclxuICAgICAgICAgICAgICAgICAgICA6IHRoaXMudmFsdWVIZXhWaWV3LnNsaWNlKCkuYnVmZmVyO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRvSlNPTigpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgLi4uc3VwZXIudG9KU09OKCksXHJcbiAgICAgICAgICAgICAgICAgICAgaXNIZXhPbmx5OiB0aGlzLmlzSGV4T25seSxcclxuICAgICAgICAgICAgICAgICAgICB2YWx1ZUhleDogcHZ0c3V0aWxzLkNvbnZlcnQuVG9IZXgodGhpcy52YWx1ZUhleFZpZXcpLFxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgX2EuTkFNRSA9IFwiaGV4QmxvY2tcIixcclxuICAgICAgICBfYTtcclxufVxuXG5jbGFzcyBMb2NhbEJhc2VCbG9jayB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7IGJsb2NrTGVuZ3RoID0gMCwgZXJyb3IgPSBFTVBUWV9TVFJJTkcsIHdhcm5pbmdzID0gW10sIHZhbHVlQmVmb3JlRGVjb2RlID0gRU1QVFlfVklFVywgfSA9IHt9KSB7XHJcbiAgICAgICAgdGhpcy5ibG9ja0xlbmd0aCA9IGJsb2NrTGVuZ3RoO1xyXG4gICAgICAgIHRoaXMuZXJyb3IgPSBlcnJvcjtcclxuICAgICAgICB0aGlzLndhcm5pbmdzID0gd2FybmluZ3M7XHJcbiAgICAgICAgdGhpcy52YWx1ZUJlZm9yZURlY29kZVZpZXcgPSBwdnRzdXRpbHMuQnVmZmVyU291cmNlQ29udmVydGVyLnRvVWludDhBcnJheSh2YWx1ZUJlZm9yZURlY29kZSk7XHJcbiAgICB9XHJcbiAgICBzdGF0aWMgYmxvY2tOYW1lKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLk5BTUU7XHJcbiAgICB9XHJcbiAgICBnZXQgdmFsdWVCZWZvcmVEZWNvZGUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWVCZWZvcmVEZWNvZGVWaWV3LnNsaWNlKCkuYnVmZmVyO1xyXG4gICAgfVxyXG4gICAgc2V0IHZhbHVlQmVmb3JlRGVjb2RlKHZhbHVlKSB7XHJcbiAgICAgICAgdGhpcy52YWx1ZUJlZm9yZURlY29kZVZpZXcgPSBuZXcgVWludDhBcnJheSh2YWx1ZSk7XHJcbiAgICB9XHJcbiAgICB0b0pTT04oKSB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgYmxvY2tOYW1lOiB0aGlzLmNvbnN0cnVjdG9yLk5BTUUsXHJcbiAgICAgICAgICAgIGJsb2NrTGVuZ3RoOiB0aGlzLmJsb2NrTGVuZ3RoLFxyXG4gICAgICAgICAgICBlcnJvcjogdGhpcy5lcnJvcixcclxuICAgICAgICAgICAgd2FybmluZ3M6IHRoaXMud2FybmluZ3MsXHJcbiAgICAgICAgICAgIHZhbHVlQmVmb3JlRGVjb2RlOiBwdnRzdXRpbHMuQ29udmVydC5Ub0hleCh0aGlzLnZhbHVlQmVmb3JlRGVjb2RlVmlldyksXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxufVxyXG5Mb2NhbEJhc2VCbG9jay5OQU1FID0gXCJiYXNlQmxvY2tcIjtcblxuY2xhc3MgVmFsdWVCbG9jayBleHRlbmRzIExvY2FsQmFzZUJsb2NrIHtcclxuICAgIGZyb21CRVIoaW5wdXRCdWZmZXIsIGlucHV0T2Zmc2V0LCBpbnB1dExlbmd0aCkge1xyXG4gICAgICAgIHRocm93IFR5cGVFcnJvcihcIlVzZXIgbmVlZCB0byBtYWtlIGEgc3BlY2lmaWMgZnVuY3Rpb24gaW4gYSBjbGFzcyB3aGljaCBleHRlbmRzICdWYWx1ZUJsb2NrJ1wiKTtcclxuICAgIH1cclxuICAgIHRvQkVSKHNpemVPbmx5LCB3cml0ZXIpIHtcclxuICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJVc2VyIG5lZWQgdG8gbWFrZSBhIHNwZWNpZmljIGZ1bmN0aW9uIGluIGEgY2xhc3Mgd2hpY2ggZXh0ZW5kcyAnVmFsdWVCbG9jaydcIik7XHJcbiAgICB9XHJcbn1cclxuVmFsdWVCbG9jay5OQU1FID0gXCJ2YWx1ZUJsb2NrXCI7XG5cbmNsYXNzIExvY2FsSWRlbnRpZmljYXRpb25CbG9jayBleHRlbmRzIEhleEJsb2NrKExvY2FsQmFzZUJsb2NrKSB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7IGlkQmxvY2sgPSB7fSwgfSA9IHt9KSB7XHJcbiAgICAgICAgdmFyIF9hLCBfYiwgX2MsIF9kO1xyXG4gICAgICAgIHN1cGVyKCk7XHJcbiAgICAgICAgaWYgKGlkQmxvY2spIHtcclxuICAgICAgICAgICAgdGhpcy5pc0hleE9ubHkgPSAoX2EgPSBpZEJsb2NrLmlzSGV4T25seSkgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogZmFsc2U7XHJcbiAgICAgICAgICAgIHRoaXMudmFsdWVIZXhWaWV3ID0gaWRCbG9jay52YWx1ZUhleCA/IHB2dHN1dGlscy5CdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9VaW50OEFycmF5KGlkQmxvY2sudmFsdWVIZXgpIDogRU1QVFlfVklFVztcclxuICAgICAgICAgICAgdGhpcy50YWdDbGFzcyA9IChfYiA9IGlkQmxvY2sudGFnQ2xhc3MpICE9PSBudWxsICYmIF9iICE9PSB2b2lkIDAgPyBfYiA6IC0xO1xyXG4gICAgICAgICAgICB0aGlzLnRhZ051bWJlciA9IChfYyA9IGlkQmxvY2sudGFnTnVtYmVyKSAhPT0gbnVsbCAmJiBfYyAhPT0gdm9pZCAwID8gX2MgOiAtMTtcclxuICAgICAgICAgICAgdGhpcy5pc0NvbnN0cnVjdGVkID0gKF9kID0gaWRCbG9jay5pc0NvbnN0cnVjdGVkKSAhPT0gbnVsbCAmJiBfZCAhPT0gdm9pZCAwID8gX2QgOiBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMudGFnQ2xhc3MgPSAtMTtcclxuICAgICAgICAgICAgdGhpcy50YWdOdW1iZXIgPSAtMTtcclxuICAgICAgICAgICAgdGhpcy5pc0NvbnN0cnVjdGVkID0gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgdG9CRVIoc2l6ZU9ubHkgPSBmYWxzZSkge1xyXG4gICAgICAgIGxldCBmaXJzdE9jdGV0ID0gMDtcclxuICAgICAgICBzd2l0Y2ggKHRoaXMudGFnQ2xhc3MpIHtcclxuICAgICAgICAgICAgY2FzZSAxOlxyXG4gICAgICAgICAgICAgICAgZmlyc3RPY3RldCB8PSAweDAwO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgMjpcclxuICAgICAgICAgICAgICAgIGZpcnN0T2N0ZXQgfD0gMHg0MDtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlIDM6XHJcbiAgICAgICAgICAgICAgICBmaXJzdE9jdGV0IHw9IDB4ODA7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgY2FzZSA0OlxyXG4gICAgICAgICAgICAgICAgZmlyc3RPY3RldCB8PSAweEMwO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9yID0gXCJVbmtub3duIHRhZyBjbGFzc1wiO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIEVNUFRZX0JVRkZFUjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHRoaXMuaXNDb25zdHJ1Y3RlZClcclxuICAgICAgICAgICAgZmlyc3RPY3RldCB8PSAweDIwO1xyXG4gICAgICAgIGlmICh0aGlzLnRhZ051bWJlciA8IDMxICYmICF0aGlzLmlzSGV4T25seSkge1xyXG4gICAgICAgICAgICBjb25zdCByZXRWaWV3ID0gbmV3IFVpbnQ4QXJyYXkoMSk7XHJcbiAgICAgICAgICAgIGlmICghc2l6ZU9ubHkpIHtcclxuICAgICAgICAgICAgICAgIGxldCBudW1iZXIgPSB0aGlzLnRhZ051bWJlcjtcclxuICAgICAgICAgICAgICAgIG51bWJlciAmPSAweDFGO1xyXG4gICAgICAgICAgICAgICAgZmlyc3RPY3RldCB8PSBudW1iZXI7XHJcbiAgICAgICAgICAgICAgICByZXRWaWV3WzBdID0gZmlyc3RPY3RldDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gcmV0Vmlldy5idWZmZXI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghdGhpcy5pc0hleE9ubHkpIHtcclxuICAgICAgICAgICAgY29uc3QgZW5jb2RlZEJ1ZiA9IHB2dXRpbHMudXRpbFRvQmFzZSh0aGlzLnRhZ051bWJlciwgNyk7XHJcbiAgICAgICAgICAgIGNvbnN0IGVuY29kZWRWaWV3ID0gbmV3IFVpbnQ4QXJyYXkoZW5jb2RlZEJ1Zik7XHJcbiAgICAgICAgICAgIGNvbnN0IHNpemUgPSBlbmNvZGVkQnVmLmJ5dGVMZW5ndGg7XHJcbiAgICAgICAgICAgIGNvbnN0IHJldFZpZXcgPSBuZXcgVWludDhBcnJheShzaXplICsgMSk7XHJcbiAgICAgICAgICAgIHJldFZpZXdbMF0gPSAoZmlyc3RPY3RldCB8IDB4MUYpO1xyXG4gICAgICAgICAgICBpZiAoIXNpemVPbmx5KSB7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IChzaXplIC0gMSk7IGkrKylcclxuICAgICAgICAgICAgICAgICAgICByZXRWaWV3W2kgKyAxXSA9IGVuY29kZWRWaWV3W2ldIHwgMHg4MDtcclxuICAgICAgICAgICAgICAgIHJldFZpZXdbc2l6ZV0gPSBlbmNvZGVkVmlld1tzaXplIC0gMV07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHJldFZpZXcuYnVmZmVyO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCByZXRWaWV3ID0gbmV3IFVpbnQ4QXJyYXkodGhpcy52YWx1ZUhleFZpZXcuYnl0ZUxlbmd0aCArIDEpO1xyXG4gICAgICAgIHJldFZpZXdbMF0gPSAoZmlyc3RPY3RldCB8IDB4MUYpO1xyXG4gICAgICAgIGlmICghc2l6ZU9ubHkpIHtcclxuICAgICAgICAgICAgY29uc3QgY3VyVmlldyA9IHRoaXMudmFsdWVIZXhWaWV3O1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IChjdXJWaWV3Lmxlbmd0aCAtIDEpOyBpKyspXHJcbiAgICAgICAgICAgICAgICByZXRWaWV3W2kgKyAxXSA9IGN1clZpZXdbaV0gfCAweDgwO1xyXG4gICAgICAgICAgICByZXRWaWV3W3RoaXMudmFsdWVIZXhWaWV3LmJ5dGVMZW5ndGhdID0gY3VyVmlld1tjdXJWaWV3Lmxlbmd0aCAtIDFdO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcmV0Vmlldy5idWZmZXI7XHJcbiAgICB9XHJcbiAgICBmcm9tQkVSKGlucHV0QnVmZmVyLCBpbnB1dE9mZnNldCwgaW5wdXRMZW5ndGgpIHtcclxuICAgICAgICBjb25zdCBpbnB1dFZpZXcgPSBwdnRzdXRpbHMuQnVmZmVyU291cmNlQ29udmVydGVyLnRvVWludDhBcnJheShpbnB1dEJ1ZmZlcik7XHJcbiAgICAgICAgaWYgKCFjaGVja0J1ZmZlclBhcmFtcyh0aGlzLCBpbnB1dFZpZXcsIGlucHV0T2Zmc2V0LCBpbnB1dExlbmd0aCkpIHtcclxuICAgICAgICAgICAgcmV0dXJuIC0xO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBpbnRCdWZmZXIgPSBpbnB1dFZpZXcuc3ViYXJyYXkoaW5wdXRPZmZzZXQsIGlucHV0T2Zmc2V0ICsgaW5wdXRMZW5ndGgpO1xyXG4gICAgICAgIGlmIChpbnRCdWZmZXIubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZXJyb3IgPSBcIlplcm8gYnVmZmVyIGxlbmd0aFwiO1xyXG4gICAgICAgICAgICByZXR1cm4gLTE7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IHRhZ0NsYXNzTWFzayA9IGludEJ1ZmZlclswXSAmIDB4QzA7XHJcbiAgICAgICAgc3dpdGNoICh0YWdDbGFzc01hc2spIHtcclxuICAgICAgICAgICAgY2FzZSAweDAwOlxyXG4gICAgICAgICAgICAgICAgdGhpcy50YWdDbGFzcyA9ICgxKTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlIDB4NDA6XHJcbiAgICAgICAgICAgICAgICB0aGlzLnRhZ0NsYXNzID0gKDIpO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgMHg4MDpcclxuICAgICAgICAgICAgICAgIHRoaXMudGFnQ2xhc3MgPSAoMyk7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgY2FzZSAweEMwOlxyXG4gICAgICAgICAgICAgICAgdGhpcy50YWdDbGFzcyA9ICg0KTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgdGhpcy5lcnJvciA9IFwiVW5rbm93biB0YWcgY2xhc3NcIjtcclxuICAgICAgICAgICAgICAgIHJldHVybiAtMTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5pc0NvbnN0cnVjdGVkID0gKGludEJ1ZmZlclswXSAmIDB4MjApID09PSAweDIwO1xyXG4gICAgICAgIHRoaXMuaXNIZXhPbmx5ID0gZmFsc2U7XHJcbiAgICAgICAgY29uc3QgdGFnTnVtYmVyTWFzayA9IGludEJ1ZmZlclswXSAmIDB4MUY7XHJcbiAgICAgICAgaWYgKHRhZ051bWJlck1hc2sgIT09IDB4MUYpIHtcclxuICAgICAgICAgICAgdGhpcy50YWdOdW1iZXIgPSAodGFnTnVtYmVyTWFzayk7XHJcbiAgICAgICAgICAgIHRoaXMuYmxvY2tMZW5ndGggPSAxO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgbGV0IGNvdW50ID0gMTtcclxuICAgICAgICAgICAgbGV0IGludFRhZ051bWJlckJ1ZmZlciA9IHRoaXMudmFsdWVIZXhWaWV3ID0gbmV3IFVpbnQ4QXJyYXkoMjU1KTtcclxuICAgICAgICAgICAgbGV0IHRhZ051bWJlckJ1ZmZlck1heExlbmd0aCA9IDI1NTtcclxuICAgICAgICAgICAgd2hpbGUgKGludEJ1ZmZlcltjb3VudF0gJiAweDgwKSB7XHJcbiAgICAgICAgICAgICAgICBpbnRUYWdOdW1iZXJCdWZmZXJbY291bnQgLSAxXSA9IGludEJ1ZmZlcltjb3VudF0gJiAweDdGO1xyXG4gICAgICAgICAgICAgICAgY291bnQrKztcclxuICAgICAgICAgICAgICAgIGlmIChjb3VudCA+PSBpbnRCdWZmZXIubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lcnJvciA9IFwiRW5kIG9mIGlucHV0IHJlYWNoZWQgYmVmb3JlIG1lc3NhZ2Ugd2FzIGZ1bGx5IGRlY29kZWRcIjtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoY291bnQgPT09IHRhZ051bWJlckJ1ZmZlck1heExlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRhZ051bWJlckJ1ZmZlck1heExlbmd0aCArPSAyNTU7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdGVtcEJ1ZmZlclZpZXcgPSBuZXcgVWludDhBcnJheSh0YWdOdW1iZXJCdWZmZXJNYXhMZW5ndGgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW50VGFnTnVtYmVyQnVmZmVyLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZW1wQnVmZmVyVmlld1tpXSA9IGludFRhZ051bWJlckJ1ZmZlcltpXTtcclxuICAgICAgICAgICAgICAgICAgICBpbnRUYWdOdW1iZXJCdWZmZXIgPSB0aGlzLnZhbHVlSGV4VmlldyA9IG5ldyBVaW50OEFycmF5KHRhZ051bWJlckJ1ZmZlck1heExlbmd0aCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5ibG9ja0xlbmd0aCA9IChjb3VudCArIDEpO1xyXG4gICAgICAgICAgICBpbnRUYWdOdW1iZXJCdWZmZXJbY291bnQgLSAxXSA9IGludEJ1ZmZlcltjb3VudF0gJiAweDdGO1xyXG4gICAgICAgICAgICBjb25zdCB0ZW1wQnVmZmVyVmlldyA9IG5ldyBVaW50OEFycmF5KGNvdW50KTtcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKVxyXG4gICAgICAgICAgICAgICAgdGVtcEJ1ZmZlclZpZXdbaV0gPSBpbnRUYWdOdW1iZXJCdWZmZXJbaV07XHJcbiAgICAgICAgICAgIGludFRhZ051bWJlckJ1ZmZlciA9IHRoaXMudmFsdWVIZXhWaWV3ID0gbmV3IFVpbnQ4QXJyYXkoY291bnQpO1xyXG4gICAgICAgICAgICBpbnRUYWdOdW1iZXJCdWZmZXIuc2V0KHRlbXBCdWZmZXJWaWV3KTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuYmxvY2tMZW5ndGggPD0gOSlcclxuICAgICAgICAgICAgICAgIHRoaXMudGFnTnVtYmVyID0gcHZ1dGlscy51dGlsRnJvbUJhc2UoaW50VGFnTnVtYmVyQnVmZmVyLCA3KTtcclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmlzSGV4T25seSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB0aGlzLndhcm5pbmdzLnB1c2goXCJUYWcgdG9vIGxvbmcsIHJlcHJlc2VudGVkIGFzIGhleC1jb2RlZFwiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoKCh0aGlzLnRhZ0NsYXNzID09PSAxKSkgJiZcclxuICAgICAgICAgICAgKHRoaXMuaXNDb25zdHJ1Y3RlZCkpIHtcclxuICAgICAgICAgICAgc3dpdGNoICh0aGlzLnRhZ051bWJlcikge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAxOlxyXG4gICAgICAgICAgICAgICAgY2FzZSAyOlxyXG4gICAgICAgICAgICAgICAgY2FzZSA1OlxyXG4gICAgICAgICAgICAgICAgY2FzZSA2OlxyXG4gICAgICAgICAgICAgICAgY2FzZSA5OlxyXG4gICAgICAgICAgICAgICAgY2FzZSAxMzpcclxuICAgICAgICAgICAgICAgIGNhc2UgMTQ6XHJcbiAgICAgICAgICAgICAgICBjYXNlIDIzOlxyXG4gICAgICAgICAgICAgICAgY2FzZSAyNDpcclxuICAgICAgICAgICAgICAgIGNhc2UgMzE6XHJcbiAgICAgICAgICAgICAgICBjYXNlIDMyOlxyXG4gICAgICAgICAgICAgICAgY2FzZSAzMzpcclxuICAgICAgICAgICAgICAgIGNhc2UgMzQ6XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lcnJvciA9IFwiQ29uc3RydWN0ZWQgZW5jb2RpbmcgdXNlZCBmb3IgcHJpbWl0aXZlIHR5cGVcIjtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIChpbnB1dE9mZnNldCArIHRoaXMuYmxvY2tMZW5ndGgpO1xyXG4gICAgfVxyXG4gICAgdG9KU09OKCkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIC4uLnN1cGVyLnRvSlNPTigpLFxyXG4gICAgICAgICAgICB0YWdDbGFzczogdGhpcy50YWdDbGFzcyxcclxuICAgICAgICAgICAgdGFnTnVtYmVyOiB0aGlzLnRhZ051bWJlcixcclxuICAgICAgICAgICAgaXNDb25zdHJ1Y3RlZDogdGhpcy5pc0NvbnN0cnVjdGVkLFxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbn1cclxuTG9jYWxJZGVudGlmaWNhdGlvbkJsb2NrLk5BTUUgPSBcImlkZW50aWZpY2F0aW9uQmxvY2tcIjtcblxuY2xhc3MgTG9jYWxMZW5ndGhCbG9jayBleHRlbmRzIExvY2FsQmFzZUJsb2NrIHtcclxuICAgIGNvbnN0cnVjdG9yKHsgbGVuQmxvY2sgPSB7fSwgfSA9IHt9KSB7XHJcbiAgICAgICAgdmFyIF9hLCBfYiwgX2M7XHJcbiAgICAgICAgc3VwZXIoKTtcclxuICAgICAgICB0aGlzLmlzSW5kZWZpbml0ZUZvcm0gPSAoX2EgPSBsZW5CbG9jay5pc0luZGVmaW5pdGVGb3JtKSAhPT0gbnVsbCAmJiBfYSAhPT0gdm9pZCAwID8gX2EgOiBmYWxzZTtcclxuICAgICAgICB0aGlzLmxvbmdGb3JtVXNlZCA9IChfYiA9IGxlbkJsb2NrLmxvbmdGb3JtVXNlZCkgIT09IG51bGwgJiYgX2IgIT09IHZvaWQgMCA/IF9iIDogZmFsc2U7XHJcbiAgICAgICAgdGhpcy5sZW5ndGggPSAoX2MgPSBsZW5CbG9jay5sZW5ndGgpICE9PSBudWxsICYmIF9jICE9PSB2b2lkIDAgPyBfYyA6IDA7XHJcbiAgICB9XHJcbiAgICBmcm9tQkVSKGlucHV0QnVmZmVyLCBpbnB1dE9mZnNldCwgaW5wdXRMZW5ndGgpIHtcclxuICAgICAgICBjb25zdCB2aWV3ID0gcHZ0c3V0aWxzLkJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b1VpbnQ4QXJyYXkoaW5wdXRCdWZmZXIpO1xyXG4gICAgICAgIGlmICghY2hlY2tCdWZmZXJQYXJhbXModGhpcywgdmlldywgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gLTE7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IGludEJ1ZmZlciA9IHZpZXcuc3ViYXJyYXkoaW5wdXRPZmZzZXQsIGlucHV0T2Zmc2V0ICsgaW5wdXRMZW5ndGgpO1xyXG4gICAgICAgIGlmIChpbnRCdWZmZXIubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZXJyb3IgPSBcIlplcm8gYnVmZmVyIGxlbmd0aFwiO1xyXG4gICAgICAgICAgICByZXR1cm4gLTE7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChpbnRCdWZmZXJbMF0gPT09IDB4RkYpIHtcclxuICAgICAgICAgICAgdGhpcy5lcnJvciA9IFwiTGVuZ3RoIGJsb2NrIDB4RkYgaXMgcmVzZXJ2ZWQgYnkgc3RhbmRhcmRcIjtcclxuICAgICAgICAgICAgcmV0dXJuIC0xO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmlzSW5kZWZpbml0ZUZvcm0gPSBpbnRCdWZmZXJbMF0gPT09IDB4ODA7XHJcbiAgICAgICAgaWYgKHRoaXMuaXNJbmRlZmluaXRlRm9ybSkge1xyXG4gICAgICAgICAgICB0aGlzLmJsb2NrTGVuZ3RoID0gMTtcclxuICAgICAgICAgICAgcmV0dXJuIChpbnB1dE9mZnNldCArIHRoaXMuYmxvY2tMZW5ndGgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmxvbmdGb3JtVXNlZCA9ICEhKGludEJ1ZmZlclswXSAmIDB4ODApO1xyXG4gICAgICAgIGlmICh0aGlzLmxvbmdGb3JtVXNlZCA9PT0gZmFsc2UpIHtcclxuICAgICAgICAgICAgdGhpcy5sZW5ndGggPSAoaW50QnVmZmVyWzBdKTtcclxuICAgICAgICAgICAgdGhpcy5ibG9ja0xlbmd0aCA9IDE7XHJcbiAgICAgICAgICAgIHJldHVybiAoaW5wdXRPZmZzZXQgKyB0aGlzLmJsb2NrTGVuZ3RoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgY291bnQgPSBpbnRCdWZmZXJbMF0gJiAweDdGO1xyXG4gICAgICAgIGlmIChjb3VudCA+IDgpIHtcclxuICAgICAgICAgICAgdGhpcy5lcnJvciA9IFwiVG9vIGJpZyBpbnRlZ2VyXCI7XHJcbiAgICAgICAgICAgIHJldHVybiAtMTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKChjb3VudCArIDEpID4gaW50QnVmZmVyLmxlbmd0aCkge1xyXG4gICAgICAgICAgICB0aGlzLmVycm9yID0gXCJFbmQgb2YgaW5wdXQgcmVhY2hlZCBiZWZvcmUgbWVzc2FnZSB3YXMgZnVsbHkgZGVjb2RlZFwiO1xyXG4gICAgICAgICAgICByZXR1cm4gLTE7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IGxlbk9mZnNldCA9IGlucHV0T2Zmc2V0ICsgMTtcclxuICAgICAgICBjb25zdCBsZW5ndGhCdWZmZXJWaWV3ID0gdmlldy5zdWJhcnJheShsZW5PZmZzZXQsIGxlbk9mZnNldCArIGNvdW50KTtcclxuICAgICAgICBpZiAobGVuZ3RoQnVmZmVyVmlld1tjb3VudCAtIDFdID09PSAweDAwKVxyXG4gICAgICAgICAgICB0aGlzLndhcm5pbmdzLnB1c2goXCJOZWVkbGVzc2x5IGxvbmcgZW5jb2RlZCBsZW5ndGhcIik7XHJcbiAgICAgICAgdGhpcy5sZW5ndGggPSBwdnV0aWxzLnV0aWxGcm9tQmFzZShsZW5ndGhCdWZmZXJWaWV3LCA4KTtcclxuICAgICAgICBpZiAodGhpcy5sb25nRm9ybVVzZWQgJiYgKHRoaXMubGVuZ3RoIDw9IDEyNykpXHJcbiAgICAgICAgICAgIHRoaXMud2FybmluZ3MucHVzaChcIlVubmVjZXNzYXJ5IHVzYWdlIG9mIGxvbmcgbGVuZ3RoIGZvcm1cIik7XHJcbiAgICAgICAgdGhpcy5ibG9ja0xlbmd0aCA9IGNvdW50ICsgMTtcclxuICAgICAgICByZXR1cm4gKGlucHV0T2Zmc2V0ICsgdGhpcy5ibG9ja0xlbmd0aCk7XHJcbiAgICB9XHJcbiAgICB0b0JFUihzaXplT25seSA9IGZhbHNlKSB7XHJcbiAgICAgICAgbGV0IHJldEJ1ZjtcclxuICAgICAgICBsZXQgcmV0VmlldztcclxuICAgICAgICBpZiAodGhpcy5sZW5ndGggPiAxMjcpXHJcbiAgICAgICAgICAgIHRoaXMubG9uZ0Zvcm1Vc2VkID0gdHJ1ZTtcclxuICAgICAgICBpZiAodGhpcy5pc0luZGVmaW5pdGVGb3JtKSB7XHJcbiAgICAgICAgICAgIHJldEJ1ZiA9IG5ldyBBcnJheUJ1ZmZlcigxKTtcclxuICAgICAgICAgICAgaWYgKHNpemVPbmx5ID09PSBmYWxzZSkge1xyXG4gICAgICAgICAgICAgICAgcmV0VmlldyA9IG5ldyBVaW50OEFycmF5KHJldEJ1Zik7XHJcbiAgICAgICAgICAgICAgICByZXRWaWV3WzBdID0gMHg4MDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gcmV0QnVmO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5sb25nRm9ybVVzZWQpIHtcclxuICAgICAgICAgICAgY29uc3QgZW5jb2RlZEJ1ZiA9IHB2dXRpbHMudXRpbFRvQmFzZSh0aGlzLmxlbmd0aCwgOCk7XHJcbiAgICAgICAgICAgIGlmIChlbmNvZGVkQnVmLmJ5dGVMZW5ndGggPiAxMjcpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZXJyb3IgPSBcIlRvbyBiaWcgbGVuZ3RoXCI7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gKEVNUFRZX0JVRkZFUik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0QnVmID0gbmV3IEFycmF5QnVmZmVyKGVuY29kZWRCdWYuYnl0ZUxlbmd0aCArIDEpO1xyXG4gICAgICAgICAgICBpZiAoc2l6ZU9ubHkpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcmV0QnVmO1xyXG4gICAgICAgICAgICBjb25zdCBlbmNvZGVkVmlldyA9IG5ldyBVaW50OEFycmF5KGVuY29kZWRCdWYpO1xyXG4gICAgICAgICAgICByZXRWaWV3ID0gbmV3IFVpbnQ4QXJyYXkocmV0QnVmKTtcclxuICAgICAgICAgICAgcmV0Vmlld1swXSA9IGVuY29kZWRCdWYuYnl0ZUxlbmd0aCB8IDB4ODA7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZW5jb2RlZEJ1Zi5ieXRlTGVuZ3RoOyBpKyspXHJcbiAgICAgICAgICAgICAgICByZXRWaWV3W2kgKyAxXSA9IGVuY29kZWRWaWV3W2ldO1xyXG4gICAgICAgICAgICByZXR1cm4gcmV0QnVmO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXRCdWYgPSBuZXcgQXJyYXlCdWZmZXIoMSk7XHJcbiAgICAgICAgaWYgKHNpemVPbmx5ID09PSBmYWxzZSkge1xyXG4gICAgICAgICAgICByZXRWaWV3ID0gbmV3IFVpbnQ4QXJyYXkocmV0QnVmKTtcclxuICAgICAgICAgICAgcmV0Vmlld1swXSA9IHRoaXMubGVuZ3RoO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcmV0QnVmO1xyXG4gICAgfVxyXG4gICAgdG9KU09OKCkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIC4uLnN1cGVyLnRvSlNPTigpLFxyXG4gICAgICAgICAgICBpc0luZGVmaW5pdGVGb3JtOiB0aGlzLmlzSW5kZWZpbml0ZUZvcm0sXHJcbiAgICAgICAgICAgIGxvbmdGb3JtVXNlZDogdGhpcy5sb25nRm9ybVVzZWQsXHJcbiAgICAgICAgICAgIGxlbmd0aDogdGhpcy5sZW5ndGgsXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxufVxyXG5Mb2NhbExlbmd0aEJsb2NrLk5BTUUgPSBcImxlbmd0aEJsb2NrXCI7XG5cbmNvbnN0IHR5cGVTdG9yZSA9IHt9O1xuXG5jbGFzcyBCYXNlQmxvY2sgZXh0ZW5kcyBMb2NhbEJhc2VCbG9jayB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7IG5hbWUgPSBFTVBUWV9TVFJJTkcsIG9wdGlvbmFsID0gZmFsc2UsIHByaW1pdGl2ZVNjaGVtYSwgLi4ucGFyYW1ldGVycyB9ID0ge30sIHZhbHVlQmxvY2tUeXBlKSB7XHJcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XHJcbiAgICAgICAgdGhpcy5uYW1lID0gbmFtZTtcclxuICAgICAgICB0aGlzLm9wdGlvbmFsID0gb3B0aW9uYWw7XHJcbiAgICAgICAgaWYgKHByaW1pdGl2ZVNjaGVtYSkge1xyXG4gICAgICAgICAgICB0aGlzLnByaW1pdGl2ZVNjaGVtYSA9IHByaW1pdGl2ZVNjaGVtYTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrID0gbmV3IExvY2FsSWRlbnRpZmljYXRpb25CbG9jayhwYXJhbWV0ZXJzKTtcclxuICAgICAgICB0aGlzLmxlbkJsb2NrID0gbmV3IExvY2FsTGVuZ3RoQmxvY2socGFyYW1ldGVycyk7XHJcbiAgICAgICAgdGhpcy52YWx1ZUJsb2NrID0gdmFsdWVCbG9ja1R5cGUgPyBuZXcgdmFsdWVCbG9ja1R5cGUocGFyYW1ldGVycykgOiBuZXcgVmFsdWVCbG9jayhwYXJhbWV0ZXJzKTtcclxuICAgIH1cclxuICAgIGZyb21CRVIoaW5wdXRCdWZmZXIsIGlucHV0T2Zmc2V0LCBpbnB1dExlbmd0aCkge1xyXG4gICAgICAgIGNvbnN0IHJlc3VsdE9mZnNldCA9IHRoaXMudmFsdWVCbG9jay5mcm9tQkVSKGlucHV0QnVmZmVyLCBpbnB1dE9mZnNldCwgKHRoaXMubGVuQmxvY2suaXNJbmRlZmluaXRlRm9ybSkgPyBpbnB1dExlbmd0aCA6IHRoaXMubGVuQmxvY2subGVuZ3RoKTtcclxuICAgICAgICBpZiAocmVzdWx0T2Zmc2V0ID09PSAtMSkge1xyXG4gICAgICAgICAgICB0aGlzLmVycm9yID0gdGhpcy52YWx1ZUJsb2NrLmVycm9yO1xyXG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0T2Zmc2V0O1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIXRoaXMuaWRCbG9jay5lcnJvci5sZW5ndGgpXHJcbiAgICAgICAgICAgIHRoaXMuYmxvY2tMZW5ndGggKz0gdGhpcy5pZEJsb2NrLmJsb2NrTGVuZ3RoO1xyXG4gICAgICAgIGlmICghdGhpcy5sZW5CbG9jay5lcnJvci5sZW5ndGgpXHJcbiAgICAgICAgICAgIHRoaXMuYmxvY2tMZW5ndGggKz0gdGhpcy5sZW5CbG9jay5ibG9ja0xlbmd0aDtcclxuICAgICAgICBpZiAoIXRoaXMudmFsdWVCbG9jay5lcnJvci5sZW5ndGgpXHJcbiAgICAgICAgICAgIHRoaXMuYmxvY2tMZW5ndGggKz0gdGhpcy52YWx1ZUJsb2NrLmJsb2NrTGVuZ3RoO1xyXG4gICAgICAgIHJldHVybiByZXN1bHRPZmZzZXQ7XHJcbiAgICB9XHJcbiAgICB0b0JFUihzaXplT25seSwgd3JpdGVyKSB7XHJcbiAgICAgICAgY29uc3QgX3dyaXRlciA9IHdyaXRlciB8fCBuZXcgVmlld1dyaXRlcigpO1xyXG4gICAgICAgIGlmICghd3JpdGVyKSB7XHJcbiAgICAgICAgICAgIHByZXBhcmVJbmRlZmluaXRlRm9ybSh0aGlzKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgaWRCbG9ja0J1ZiA9IHRoaXMuaWRCbG9jay50b0JFUihzaXplT25seSk7XHJcbiAgICAgICAgX3dyaXRlci53cml0ZShpZEJsb2NrQnVmKTtcclxuICAgICAgICBpZiAodGhpcy5sZW5CbG9jay5pc0luZGVmaW5pdGVGb3JtKSB7XHJcbiAgICAgICAgICAgIF93cml0ZXIud3JpdGUobmV3IFVpbnQ4QXJyYXkoWzB4ODBdKS5idWZmZXIpO1xyXG4gICAgICAgICAgICB0aGlzLnZhbHVlQmxvY2sudG9CRVIoc2l6ZU9ubHksIF93cml0ZXIpO1xyXG4gICAgICAgICAgICBfd3JpdGVyLndyaXRlKG5ldyBBcnJheUJ1ZmZlcigyKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBjb25zdCB2YWx1ZUJsb2NrQnVmID0gdGhpcy52YWx1ZUJsb2NrLnRvQkVSKHNpemVPbmx5KTtcclxuICAgICAgICAgICAgdGhpcy5sZW5CbG9jay5sZW5ndGggPSB2YWx1ZUJsb2NrQnVmLmJ5dGVMZW5ndGg7XHJcbiAgICAgICAgICAgIGNvbnN0IGxlbkJsb2NrQnVmID0gdGhpcy5sZW5CbG9jay50b0JFUihzaXplT25seSk7XHJcbiAgICAgICAgICAgIF93cml0ZXIud3JpdGUobGVuQmxvY2tCdWYpO1xyXG4gICAgICAgICAgICBfd3JpdGVyLndyaXRlKHZhbHVlQmxvY2tCdWYpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIXdyaXRlcikge1xyXG4gICAgICAgICAgICByZXR1cm4gX3dyaXRlci5maW5hbCgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gRU1QVFlfQlVGRkVSO1xyXG4gICAgfVxyXG4gICAgdG9KU09OKCkge1xyXG4gICAgICAgIGNvbnN0IG9iamVjdCA9IHtcclxuICAgICAgICAgICAgLi4uc3VwZXIudG9KU09OKCksXHJcbiAgICAgICAgICAgIGlkQmxvY2s6IHRoaXMuaWRCbG9jay50b0pTT04oKSxcclxuICAgICAgICAgICAgbGVuQmxvY2s6IHRoaXMubGVuQmxvY2sudG9KU09OKCksXHJcbiAgICAgICAgICAgIHZhbHVlQmxvY2s6IHRoaXMudmFsdWVCbG9jay50b0pTT04oKSxcclxuICAgICAgICAgICAgbmFtZTogdGhpcy5uYW1lLFxyXG4gICAgICAgICAgICBvcHRpb25hbDogdGhpcy5vcHRpb25hbCxcclxuICAgICAgICB9O1xyXG4gICAgICAgIGlmICh0aGlzLnByaW1pdGl2ZVNjaGVtYSlcclxuICAgICAgICAgICAgb2JqZWN0LnByaW1pdGl2ZVNjaGVtYSA9IHRoaXMucHJpbWl0aXZlU2NoZW1hLnRvSlNPTigpO1xyXG4gICAgICAgIHJldHVybiBvYmplY3Q7XHJcbiAgICB9XHJcbiAgICB0b1N0cmluZyhlbmNvZGluZyA9IFwiYXNjaWlcIikge1xyXG4gICAgICAgIGlmIChlbmNvZGluZyA9PT0gXCJhc2NpaVwiKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm9uQXNjaWlFbmNvZGluZygpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcHZ0c3V0aWxzLkNvbnZlcnQuVG9IZXgodGhpcy50b0JFUigpKTtcclxuICAgIH1cclxuICAgIG9uQXNjaWlFbmNvZGluZygpIHtcclxuICAgICAgICByZXR1cm4gYCR7dGhpcy5jb25zdHJ1Y3Rvci5OQU1FfSA6ICR7cHZ0c3V0aWxzLkNvbnZlcnQuVG9IZXgodGhpcy52YWx1ZUJsb2NrLnZhbHVlQmVmb3JlRGVjb2RlVmlldyl9YDtcclxuICAgIH1cclxuICAgIGlzRXF1YWwob3RoZXIpIHtcclxuICAgICAgICBpZiAodGhpcyA9PT0gb3RoZXIpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghKG90aGVyIGluc3RhbmNlb2YgdGhpcy5jb25zdHJ1Y3RvcikpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCB0aGlzUmF3ID0gdGhpcy50b0JFUigpO1xyXG4gICAgICAgIGNvbnN0IG90aGVyUmF3ID0gb3RoZXIudG9CRVIoKTtcclxuICAgICAgICByZXR1cm4gcHZ1dGlscy5pc0VxdWFsQnVmZmVyKHRoaXNSYXcsIG90aGVyUmF3KTtcclxuICAgIH1cclxufVxyXG5CYXNlQmxvY2suTkFNRSA9IFwiQmFzZUJsb2NrXCI7XHJcbmZ1bmN0aW9uIHByZXBhcmVJbmRlZmluaXRlRm9ybShiYXNlQmxvY2spIHtcclxuICAgIGlmIChiYXNlQmxvY2sgaW5zdGFuY2VvZiB0eXBlU3RvcmUuQ29uc3RydWN0ZWQpIHtcclxuICAgICAgICBmb3IgKGNvbnN0IHZhbHVlIG9mIGJhc2VCbG9jay52YWx1ZUJsb2NrLnZhbHVlKSB7XHJcbiAgICAgICAgICAgIGlmIChwcmVwYXJlSW5kZWZpbml0ZUZvcm0odmFsdWUpKSB7XHJcbiAgICAgICAgICAgICAgICBiYXNlQmxvY2subGVuQmxvY2suaXNJbmRlZmluaXRlRm9ybSA9IHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gISFiYXNlQmxvY2subGVuQmxvY2suaXNJbmRlZmluaXRlRm9ybTtcclxufVxuXG5jbGFzcyBCYXNlU3RyaW5nQmxvY2sgZXh0ZW5kcyBCYXNlQmxvY2sge1xyXG4gICAgY29uc3RydWN0b3IoeyB2YWx1ZSA9IEVNUFRZX1NUUklORywgLi4ucGFyYW1ldGVycyB9ID0ge30sIHN0cmluZ1ZhbHVlQmxvY2tUeXBlKSB7XHJcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycywgc3RyaW5nVmFsdWVCbG9ja1R5cGUpO1xyXG4gICAgICAgIGlmICh2YWx1ZSkge1xyXG4gICAgICAgICAgICB0aGlzLmZyb21TdHJpbmcodmFsdWUpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGdldFZhbHVlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlQmxvY2sudmFsdWU7XHJcbiAgICB9XHJcbiAgICBzZXRWYWx1ZSh2YWx1ZSkge1xyXG4gICAgICAgIHRoaXMudmFsdWVCbG9jay52YWx1ZSA9IHZhbHVlO1xyXG4gICAgfVxyXG4gICAgZnJvbUJFUihpbnB1dEJ1ZmZlciwgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoKSB7XHJcbiAgICAgICAgY29uc3QgcmVzdWx0T2Zmc2V0ID0gdGhpcy52YWx1ZUJsb2NrLmZyb21CRVIoaW5wdXRCdWZmZXIsIGlucHV0T2Zmc2V0LCAodGhpcy5sZW5CbG9jay5pc0luZGVmaW5pdGVGb3JtKSA/IGlucHV0TGVuZ3RoIDogdGhpcy5sZW5CbG9jay5sZW5ndGgpO1xyXG4gICAgICAgIGlmIChyZXN1bHRPZmZzZXQgPT09IC0xKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZXJyb3IgPSB0aGlzLnZhbHVlQmxvY2suZXJyb3I7XHJcbiAgICAgICAgICAgIHJldHVybiByZXN1bHRPZmZzZXQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuZnJvbUJ1ZmZlcih0aGlzLnZhbHVlQmxvY2sudmFsdWVIZXhWaWV3KTtcclxuICAgICAgICBpZiAoIXRoaXMuaWRCbG9jay5lcnJvci5sZW5ndGgpXHJcbiAgICAgICAgICAgIHRoaXMuYmxvY2tMZW5ndGggKz0gdGhpcy5pZEJsb2NrLmJsb2NrTGVuZ3RoO1xyXG4gICAgICAgIGlmICghdGhpcy5sZW5CbG9jay5lcnJvci5sZW5ndGgpXHJcbiAgICAgICAgICAgIHRoaXMuYmxvY2tMZW5ndGggKz0gdGhpcy5sZW5CbG9jay5ibG9ja0xlbmd0aDtcclxuICAgICAgICBpZiAoIXRoaXMudmFsdWVCbG9jay5lcnJvci5sZW5ndGgpXHJcbiAgICAgICAgICAgIHRoaXMuYmxvY2tMZW5ndGggKz0gdGhpcy52YWx1ZUJsb2NrLmJsb2NrTGVuZ3RoO1xyXG4gICAgICAgIHJldHVybiByZXN1bHRPZmZzZXQ7XHJcbiAgICB9XHJcbiAgICBvbkFzY2lpRW5jb2RpbmcoKSB7XHJcbiAgICAgICAgcmV0dXJuIGAke3RoaXMuY29uc3RydWN0b3IuTkFNRX0gOiAnJHt0aGlzLnZhbHVlQmxvY2sudmFsdWV9J2A7XHJcbiAgICB9XHJcbn1cclxuQmFzZVN0cmluZ0Jsb2NrLk5BTUUgPSBcIkJhc2VTdHJpbmdCbG9ja1wiO1xuXG5jbGFzcyBMb2NhbFByaW1pdGl2ZVZhbHVlQmxvY2sgZXh0ZW5kcyBIZXhCbG9jayhWYWx1ZUJsb2NrKSB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7IGlzSGV4T25seSA9IHRydWUsIC4uLnBhcmFtZXRlcnMgfSA9IHt9KSB7XHJcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XHJcbiAgICAgICAgdGhpcy5pc0hleE9ubHkgPSBpc0hleE9ubHk7XHJcbiAgICB9XHJcbn1cclxuTG9jYWxQcmltaXRpdmVWYWx1ZUJsb2NrLk5BTUUgPSBcIlByaW1pdGl2ZVZhbHVlQmxvY2tcIjtcblxudmFyIF9hJHc7XHJcbmNsYXNzIFByaW1pdGl2ZSBleHRlbmRzIEJhc2VCbG9jayB7XHJcbiAgICBjb25zdHJ1Y3RvcihwYXJhbWV0ZXJzID0ge30pIHtcclxuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzLCBMb2NhbFByaW1pdGl2ZVZhbHVlQmxvY2spO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay5pc0NvbnN0cnVjdGVkID0gZmFsc2U7XHJcbiAgICB9XHJcbn1cclxuX2EkdyA9IFByaW1pdGl2ZTtcclxuKCgpID0+IHtcclxuICAgIHR5cGVTdG9yZS5QcmltaXRpdmUgPSBfYSR3O1xyXG59KSgpO1xyXG5QcmltaXRpdmUuTkFNRSA9IFwiUFJJTUlUSVZFXCI7XG5cbmZ1bmN0aW9uIGxvY2FsQ2hhbmdlVHlwZShpbnB1dE9iamVjdCwgbmV3VHlwZSkge1xyXG4gICAgaWYgKGlucHV0T2JqZWN0IGluc3RhbmNlb2YgbmV3VHlwZSkge1xyXG4gICAgICAgIHJldHVybiBpbnB1dE9iamVjdDtcclxuICAgIH1cclxuICAgIGNvbnN0IG5ld09iamVjdCA9IG5ldyBuZXdUeXBlKCk7XHJcbiAgICBuZXdPYmplY3QuaWRCbG9jayA9IGlucHV0T2JqZWN0LmlkQmxvY2s7XHJcbiAgICBuZXdPYmplY3QubGVuQmxvY2sgPSBpbnB1dE9iamVjdC5sZW5CbG9jaztcclxuICAgIG5ld09iamVjdC53YXJuaW5ncyA9IGlucHV0T2JqZWN0Lndhcm5pbmdzO1xyXG4gICAgbmV3T2JqZWN0LnZhbHVlQmVmb3JlRGVjb2RlVmlldyA9IGlucHV0T2JqZWN0LnZhbHVlQmVmb3JlRGVjb2RlVmlldztcclxuICAgIHJldHVybiBuZXdPYmplY3Q7XHJcbn1cclxuZnVuY3Rpb24gbG9jYWxGcm9tQkVSKGlucHV0QnVmZmVyLCBpbnB1dE9mZnNldCA9IDAsIGlucHV0TGVuZ3RoID0gaW5wdXRCdWZmZXIubGVuZ3RoKSB7XHJcbiAgICBjb25zdCBpbmNvbWluZ09mZnNldCA9IGlucHV0T2Zmc2V0O1xyXG4gICAgbGV0IHJldHVybk9iamVjdCA9IG5ldyBCYXNlQmxvY2soe30sIFZhbHVlQmxvY2spO1xyXG4gICAgY29uc3QgYmFzZUJsb2NrID0gbmV3IExvY2FsQmFzZUJsb2NrKCk7XHJcbiAgICBpZiAoIWNoZWNrQnVmZmVyUGFyYW1zKGJhc2VCbG9jaywgaW5wdXRCdWZmZXIsIGlucHV0T2Zmc2V0LCBpbnB1dExlbmd0aCkpIHtcclxuICAgICAgICByZXR1cm5PYmplY3QuZXJyb3IgPSBiYXNlQmxvY2suZXJyb3I7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgb2Zmc2V0OiAtMSxcclxuICAgICAgICAgICAgcmVzdWx0OiByZXR1cm5PYmplY3RcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG4gICAgY29uc3QgaW50QnVmZmVyID0gaW5wdXRCdWZmZXIuc3ViYXJyYXkoaW5wdXRPZmZzZXQsIGlucHV0T2Zmc2V0ICsgaW5wdXRMZW5ndGgpO1xyXG4gICAgaWYgKCFpbnRCdWZmZXIubGVuZ3RoKSB7XHJcbiAgICAgICAgcmV0dXJuT2JqZWN0LmVycm9yID0gXCJaZXJvIGJ1ZmZlciBsZW5ndGhcIjtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBvZmZzZXQ6IC0xLFxyXG4gICAgICAgICAgICByZXN1bHQ6IHJldHVybk9iamVjdFxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbiAgICBsZXQgcmVzdWx0T2Zmc2V0ID0gcmV0dXJuT2JqZWN0LmlkQmxvY2suZnJvbUJFUihpbnB1dEJ1ZmZlciwgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoKTtcclxuICAgIGlmIChyZXR1cm5PYmplY3QuaWRCbG9jay53YXJuaW5ncy5sZW5ndGgpIHtcclxuICAgICAgICByZXR1cm5PYmplY3Qud2FybmluZ3MuY29uY2F0KHJldHVybk9iamVjdC5pZEJsb2NrLndhcm5pbmdzKTtcclxuICAgIH1cclxuICAgIGlmIChyZXN1bHRPZmZzZXQgPT09IC0xKSB7XHJcbiAgICAgICAgcmV0dXJuT2JqZWN0LmVycm9yID0gcmV0dXJuT2JqZWN0LmlkQmxvY2suZXJyb3I7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgb2Zmc2V0OiAtMSxcclxuICAgICAgICAgICAgcmVzdWx0OiByZXR1cm5PYmplY3RcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG4gICAgaW5wdXRPZmZzZXQgPSByZXN1bHRPZmZzZXQ7XHJcbiAgICBpbnB1dExlbmd0aCAtPSByZXR1cm5PYmplY3QuaWRCbG9jay5ibG9ja0xlbmd0aDtcclxuICAgIHJlc3VsdE9mZnNldCA9IHJldHVybk9iamVjdC5sZW5CbG9jay5mcm9tQkVSKGlucHV0QnVmZmVyLCBpbnB1dE9mZnNldCwgaW5wdXRMZW5ndGgpO1xyXG4gICAgaWYgKHJldHVybk9iamVjdC5sZW5CbG9jay53YXJuaW5ncy5sZW5ndGgpIHtcclxuICAgICAgICByZXR1cm5PYmplY3Qud2FybmluZ3MuY29uY2F0KHJldHVybk9iamVjdC5sZW5CbG9jay53YXJuaW5ncyk7XHJcbiAgICB9XHJcbiAgICBpZiAocmVzdWx0T2Zmc2V0ID09PSAtMSkge1xyXG4gICAgICAgIHJldHVybk9iamVjdC5lcnJvciA9IHJldHVybk9iamVjdC5sZW5CbG9jay5lcnJvcjtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBvZmZzZXQ6IC0xLFxyXG4gICAgICAgICAgICByZXN1bHQ6IHJldHVybk9iamVjdFxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbiAgICBpbnB1dE9mZnNldCA9IHJlc3VsdE9mZnNldDtcclxuICAgIGlucHV0TGVuZ3RoIC09IHJldHVybk9iamVjdC5sZW5CbG9jay5ibG9ja0xlbmd0aDtcclxuICAgIGlmICghcmV0dXJuT2JqZWN0LmlkQmxvY2suaXNDb25zdHJ1Y3RlZCAmJlxyXG4gICAgICAgIHJldHVybk9iamVjdC5sZW5CbG9jay5pc0luZGVmaW5pdGVGb3JtKSB7XHJcbiAgICAgICAgcmV0dXJuT2JqZWN0LmVycm9yID0gXCJJbmRlZmluaXRlIGxlbmd0aCBmb3JtIHVzZWQgZm9yIHByaW1pdGl2ZSBlbmNvZGluZyBmb3JtXCI7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgb2Zmc2V0OiAtMSxcclxuICAgICAgICAgICAgcmVzdWx0OiByZXR1cm5PYmplY3RcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG4gICAgbGV0IG5ld0FTTjFUeXBlID0gQmFzZUJsb2NrO1xyXG4gICAgc3dpdGNoIChyZXR1cm5PYmplY3QuaWRCbG9jay50YWdDbGFzcykge1xyXG4gICAgICAgIGNhc2UgMTpcclxuICAgICAgICAgICAgaWYgKChyZXR1cm5PYmplY3QuaWRCbG9jay50YWdOdW1iZXIgPj0gMzcpICYmXHJcbiAgICAgICAgICAgICAgICAocmV0dXJuT2JqZWN0LmlkQmxvY2suaXNIZXhPbmx5ID09PSBmYWxzZSkpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybk9iamVjdC5lcnJvciA9IFwiVU5JVkVSU0FMIDM3IGFuZCB1cHBlciB0YWdzIGFyZSByZXNlcnZlZCBieSBBU04uMSBzdGFuZGFyZFwiO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICBvZmZzZXQ6IC0xLFxyXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdDogcmV0dXJuT2JqZWN0XHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHN3aXRjaCAocmV0dXJuT2JqZWN0LmlkQmxvY2sudGFnTnVtYmVyKSB7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDA6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKChyZXR1cm5PYmplY3QuaWRCbG9jay5pc0NvbnN0cnVjdGVkKSAmJlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAocmV0dXJuT2JqZWN0LmxlbkJsb2NrLmxlbmd0aCA+IDApKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybk9iamVjdC5lcnJvciA9IFwiVHlwZSBbVU5JVkVSU0FMIDBdIGlzIHJlc2VydmVkXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQ6IC0xLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0OiByZXR1cm5PYmplY3RcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgbmV3QVNOMVR5cGUgPSB0eXBlU3RvcmUuRW5kT2ZDb250ZW50O1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAxOlxyXG4gICAgICAgICAgICAgICAgICAgIG5ld0FTTjFUeXBlID0gdHlwZVN0b3JlLkJvb2xlYW47XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDI6XHJcbiAgICAgICAgICAgICAgICAgICAgbmV3QVNOMVR5cGUgPSB0eXBlU3RvcmUuSW50ZWdlcjtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgMzpcclxuICAgICAgICAgICAgICAgICAgICBuZXdBU04xVHlwZSA9IHR5cGVTdG9yZS5CaXRTdHJpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDQ6XHJcbiAgICAgICAgICAgICAgICAgICAgbmV3QVNOMVR5cGUgPSB0eXBlU3RvcmUuT2N0ZXRTdHJpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDU6XHJcbiAgICAgICAgICAgICAgICAgICAgbmV3QVNOMVR5cGUgPSB0eXBlU3RvcmUuTnVsbDtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgNjpcclxuICAgICAgICAgICAgICAgICAgICBuZXdBU04xVHlwZSA9IHR5cGVTdG9yZS5PYmplY3RJZGVudGlmaWVyO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAxMDpcclxuICAgICAgICAgICAgICAgICAgICBuZXdBU04xVHlwZSA9IHR5cGVTdG9yZS5FbnVtZXJhdGVkO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAxMjpcclxuICAgICAgICAgICAgICAgICAgICBuZXdBU04xVHlwZSA9IHR5cGVTdG9yZS5VdGY4U3RyaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAxMzpcclxuICAgICAgICAgICAgICAgICAgICBuZXdBU04xVHlwZSA9IHR5cGVTdG9yZS5SZWxhdGl2ZU9iamVjdElkZW50aWZpZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDE0OlxyXG4gICAgICAgICAgICAgICAgICAgIG5ld0FTTjFUeXBlID0gdHlwZVN0b3JlLlRJTUU7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDE1OlxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybk9iamVjdC5lcnJvciA9IFwiW1VOSVZFUlNBTCAxNV0gaXMgcmVzZXJ2ZWQgYnkgQVNOLjEgc3RhbmRhcmRcIjtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQ6IC0xLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQ6IHJldHVybk9iamVjdFxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICBjYXNlIDE2OlxyXG4gICAgICAgICAgICAgICAgICAgIG5ld0FTTjFUeXBlID0gdHlwZVN0b3JlLlNlcXVlbmNlO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAxNzpcclxuICAgICAgICAgICAgICAgICAgICBuZXdBU04xVHlwZSA9IHR5cGVTdG9yZS5TZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDE4OlxyXG4gICAgICAgICAgICAgICAgICAgIG5ld0FTTjFUeXBlID0gdHlwZVN0b3JlLk51bWVyaWNTdHJpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDE5OlxyXG4gICAgICAgICAgICAgICAgICAgIG5ld0FTTjFUeXBlID0gdHlwZVN0b3JlLlByaW50YWJsZVN0cmluZztcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgMjA6XHJcbiAgICAgICAgICAgICAgICAgICAgbmV3QVNOMVR5cGUgPSB0eXBlU3RvcmUuVGVsZXRleFN0cmluZztcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgMjE6XHJcbiAgICAgICAgICAgICAgICAgICAgbmV3QVNOMVR5cGUgPSB0eXBlU3RvcmUuVmlkZW90ZXhTdHJpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDIyOlxyXG4gICAgICAgICAgICAgICAgICAgIG5ld0FTTjFUeXBlID0gdHlwZVN0b3JlLklBNVN0cmluZztcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgMjM6XHJcbiAgICAgICAgICAgICAgICAgICAgbmV3QVNOMVR5cGUgPSB0eXBlU3RvcmUuVVRDVGltZTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgMjQ6XHJcbiAgICAgICAgICAgICAgICAgICAgbmV3QVNOMVR5cGUgPSB0eXBlU3RvcmUuR2VuZXJhbGl6ZWRUaW1lO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAyNTpcclxuICAgICAgICAgICAgICAgICAgICBuZXdBU04xVHlwZSA9IHR5cGVTdG9yZS5HcmFwaGljU3RyaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAyNjpcclxuICAgICAgICAgICAgICAgICAgICBuZXdBU04xVHlwZSA9IHR5cGVTdG9yZS5WaXNpYmxlU3RyaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAyNzpcclxuICAgICAgICAgICAgICAgICAgICBuZXdBU04xVHlwZSA9IHR5cGVTdG9yZS5HZW5lcmFsU3RyaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAyODpcclxuICAgICAgICAgICAgICAgICAgICBuZXdBU04xVHlwZSA9IHR5cGVTdG9yZS5Vbml2ZXJzYWxTdHJpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDI5OlxyXG4gICAgICAgICAgICAgICAgICAgIG5ld0FTTjFUeXBlID0gdHlwZVN0b3JlLkNoYXJhY3RlclN0cmluZztcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgMzA6XHJcbiAgICAgICAgICAgICAgICAgICAgbmV3QVNOMVR5cGUgPSB0eXBlU3RvcmUuQm1wU3RyaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAzMTpcclxuICAgICAgICAgICAgICAgICAgICBuZXdBU04xVHlwZSA9IHR5cGVTdG9yZS5EQVRFO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAzMjpcclxuICAgICAgICAgICAgICAgICAgICBuZXdBU04xVHlwZSA9IHR5cGVTdG9yZS5UaW1lT2ZEYXk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDMzOlxyXG4gICAgICAgICAgICAgICAgICAgIG5ld0FTTjFUeXBlID0gdHlwZVN0b3JlLkRhdGVUaW1lO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAzNDpcclxuICAgICAgICAgICAgICAgICAgICBuZXdBU04xVHlwZSA9IHR5cGVTdG9yZS5EdXJhdGlvbjtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXdPYmplY3QgPSByZXR1cm5PYmplY3QuaWRCbG9jay5pc0NvbnN0cnVjdGVkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgID8gbmV3IHR5cGVTdG9yZS5Db25zdHJ1Y3RlZCgpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDogbmV3IHR5cGVTdG9yZS5QcmltaXRpdmUoKTtcclxuICAgICAgICAgICAgICAgICAgICBuZXdPYmplY3QuaWRCbG9jayA9IHJldHVybk9iamVjdC5pZEJsb2NrO1xyXG4gICAgICAgICAgICAgICAgICAgIG5ld09iamVjdC5sZW5CbG9jayA9IHJldHVybk9iamVjdC5sZW5CbG9jaztcclxuICAgICAgICAgICAgICAgICAgICBuZXdPYmplY3Qud2FybmluZ3MgPSByZXR1cm5PYmplY3Qud2FybmluZ3M7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuT2JqZWN0ID0gbmV3T2JqZWN0O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIGNhc2UgMjpcclxuICAgICAgICBjYXNlIDM6XHJcbiAgICAgICAgY2FzZSA0OlxyXG4gICAgICAgIGRlZmF1bHQ6IHtcclxuICAgICAgICAgICAgbmV3QVNOMVR5cGUgPSByZXR1cm5PYmplY3QuaWRCbG9jay5pc0NvbnN0cnVjdGVkXHJcbiAgICAgICAgICAgICAgICA/IHR5cGVTdG9yZS5Db25zdHJ1Y3RlZFxyXG4gICAgICAgICAgICAgICAgOiB0eXBlU3RvcmUuUHJpbWl0aXZlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybk9iamVjdCA9IGxvY2FsQ2hhbmdlVHlwZShyZXR1cm5PYmplY3QsIG5ld0FTTjFUeXBlKTtcclxuICAgIHJlc3VsdE9mZnNldCA9IHJldHVybk9iamVjdC5mcm9tQkVSKGlucHV0QnVmZmVyLCBpbnB1dE9mZnNldCwgcmV0dXJuT2JqZWN0LmxlbkJsb2NrLmlzSW5kZWZpbml0ZUZvcm0gPyBpbnB1dExlbmd0aCA6IHJldHVybk9iamVjdC5sZW5CbG9jay5sZW5ndGgpO1xyXG4gICAgcmV0dXJuT2JqZWN0LnZhbHVlQmVmb3JlRGVjb2RlVmlldyA9IGlucHV0QnVmZmVyLnN1YmFycmF5KGluY29taW5nT2Zmc2V0LCBpbmNvbWluZ09mZnNldCArIHJldHVybk9iamVjdC5ibG9ja0xlbmd0aCk7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIG9mZnNldDogcmVzdWx0T2Zmc2V0LFxyXG4gICAgICAgIHJlc3VsdDogcmV0dXJuT2JqZWN0XHJcbiAgICB9O1xyXG59XHJcbmZ1bmN0aW9uIGZyb21CRVIoaW5wdXRCdWZmZXIpIHtcclxuICAgIGlmICghaW5wdXRCdWZmZXIuYnl0ZUxlbmd0aCkge1xyXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IG5ldyBCYXNlQmxvY2soe30sIFZhbHVlQmxvY2spO1xyXG4gICAgICAgIHJlc3VsdC5lcnJvciA9IFwiSW5wdXQgYnVmZmVyIGhhcyB6ZXJvIGxlbmd0aFwiO1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIG9mZnNldDogLTEsXHJcbiAgICAgICAgICAgIHJlc3VsdFxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbG9jYWxGcm9tQkVSKHB2dHN1dGlscy5CdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9VaW50OEFycmF5KGlucHV0QnVmZmVyKS5zbGljZSgpLCAwLCBpbnB1dEJ1ZmZlci5ieXRlTGVuZ3RoKTtcclxufVxuXG5mdW5jdGlvbiBjaGVja0xlbihpbmRlZmluaXRlTGVuZ3RoLCBsZW5ndGgpIHtcclxuICAgIGlmIChpbmRlZmluaXRlTGVuZ3RoKSB7XHJcbiAgICAgICAgcmV0dXJuIDE7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbGVuZ3RoO1xyXG59XHJcbmNsYXNzIExvY2FsQ29uc3RydWN0ZWRWYWx1ZUJsb2NrIGV4dGVuZHMgVmFsdWVCbG9jayB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7IHZhbHVlID0gW10sIGlzSW5kZWZpbml0ZUZvcm0gPSBmYWxzZSwgLi4ucGFyYW1ldGVycyB9ID0ge30pIHtcclxuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcclxuICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XHJcbiAgICAgICAgdGhpcy5pc0luZGVmaW5pdGVGb3JtID0gaXNJbmRlZmluaXRlRm9ybTtcclxuICAgIH1cclxuICAgIGZyb21CRVIoaW5wdXRCdWZmZXIsIGlucHV0T2Zmc2V0LCBpbnB1dExlbmd0aCkge1xyXG4gICAgICAgIGNvbnN0IHZpZXcgPSBwdnRzdXRpbHMuQnVmZmVyU291cmNlQ29udmVydGVyLnRvVWludDhBcnJheShpbnB1dEJ1ZmZlcik7XHJcbiAgICAgICAgaWYgKCFjaGVja0J1ZmZlclBhcmFtcyh0aGlzLCB2aWV3LCBpbnB1dE9mZnNldCwgaW5wdXRMZW5ndGgpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiAtMTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy52YWx1ZUJlZm9yZURlY29kZVZpZXcgPSB2aWV3LnN1YmFycmF5KGlucHV0T2Zmc2V0LCBpbnB1dE9mZnNldCArIGlucHV0TGVuZ3RoKTtcclxuICAgICAgICBpZiAodGhpcy52YWx1ZUJlZm9yZURlY29kZVZpZXcubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgICAgIHRoaXMud2FybmluZ3MucHVzaChcIlplcm8gYnVmZmVyIGxlbmd0aFwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIGlucHV0T2Zmc2V0O1xyXG4gICAgICAgIH1cclxuICAgICAgICBsZXQgY3VycmVudE9mZnNldCA9IGlucHV0T2Zmc2V0O1xyXG4gICAgICAgIHdoaWxlIChjaGVja0xlbih0aGlzLmlzSW5kZWZpbml0ZUZvcm0sIGlucHV0TGVuZ3RoKSA+IDApIHtcclxuICAgICAgICAgICAgY29uc3QgcmV0dXJuT2JqZWN0ID0gbG9jYWxGcm9tQkVSKHZpZXcsIGN1cnJlbnRPZmZzZXQsIGlucHV0TGVuZ3RoKTtcclxuICAgICAgICAgICAgaWYgKHJldHVybk9iamVjdC5vZmZzZXQgPT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9yID0gcmV0dXJuT2JqZWN0LnJlc3VsdC5lcnJvcjtcclxuICAgICAgICAgICAgICAgIHRoaXMud2FybmluZ3MuY29uY2F0KHJldHVybk9iamVjdC5yZXN1bHQud2FybmluZ3MpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIC0xO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGN1cnJlbnRPZmZzZXQgPSByZXR1cm5PYmplY3Qub2Zmc2V0O1xyXG4gICAgICAgICAgICB0aGlzLmJsb2NrTGVuZ3RoICs9IHJldHVybk9iamVjdC5yZXN1bHQuYmxvY2tMZW5ndGg7XHJcbiAgICAgICAgICAgIGlucHV0TGVuZ3RoIC09IHJldHVybk9iamVjdC5yZXN1bHQuYmxvY2tMZW5ndGg7XHJcbiAgICAgICAgICAgIHRoaXMudmFsdWUucHVzaChyZXR1cm5PYmplY3QucmVzdWx0KTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuaXNJbmRlZmluaXRlRm9ybSAmJiByZXR1cm5PYmplY3QucmVzdWx0LmNvbnN0cnVjdG9yLk5BTUUgPT09IEVORF9PRl9DT05URU5UX05BTUUpIHtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLmlzSW5kZWZpbml0ZUZvcm0pIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMudmFsdWVbdGhpcy52YWx1ZS5sZW5ndGggLSAxXS5jb25zdHJ1Y3Rvci5OQU1FID09PSBFTkRfT0ZfQ09OVEVOVF9OQU1FKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnZhbHVlLnBvcCgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy53YXJuaW5ncy5wdXNoKFwiTm8gRW5kT2ZDb250ZW50IGJsb2NrIGVuY29kZWRcIik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGN1cnJlbnRPZmZzZXQ7XHJcbiAgICB9XHJcbiAgICB0b0JFUihzaXplT25seSwgd3JpdGVyKSB7XHJcbiAgICAgICAgY29uc3QgX3dyaXRlciA9IHdyaXRlciB8fCBuZXcgVmlld1dyaXRlcigpO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy52YWx1ZS5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICB0aGlzLnZhbHVlW2ldLnRvQkVSKHNpemVPbmx5LCBfd3JpdGVyKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCF3cml0ZXIpIHtcclxuICAgICAgICAgICAgcmV0dXJuIF93cml0ZXIuZmluYWwoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIEVNUFRZX0JVRkZFUjtcclxuICAgIH1cclxuICAgIHRvSlNPTigpIHtcclxuICAgICAgICBjb25zdCBvYmplY3QgPSB7XHJcbiAgICAgICAgICAgIC4uLnN1cGVyLnRvSlNPTigpLFxyXG4gICAgICAgICAgICBpc0luZGVmaW5pdGVGb3JtOiB0aGlzLmlzSW5kZWZpbml0ZUZvcm0sXHJcbiAgICAgICAgICAgIHZhbHVlOiBbXSxcclxuICAgICAgICB9O1xyXG4gICAgICAgIGZvciAoY29uc3QgdmFsdWUgb2YgdGhpcy52YWx1ZSkge1xyXG4gICAgICAgICAgICBvYmplY3QudmFsdWUucHVzaCh2YWx1ZS50b0pTT04oKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBvYmplY3Q7XHJcbiAgICB9XHJcbn1cclxuTG9jYWxDb25zdHJ1Y3RlZFZhbHVlQmxvY2suTkFNRSA9IFwiQ29uc3RydWN0ZWRWYWx1ZUJsb2NrXCI7XG5cbnZhciBfYSR2O1xyXG5jbGFzcyBDb25zdHJ1Y3RlZCBleHRlbmRzIEJhc2VCbG9jayB7XHJcbiAgICBjb25zdHJ1Y3RvcihwYXJhbWV0ZXJzID0ge30pIHtcclxuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzLCBMb2NhbENvbnN0cnVjdGVkVmFsdWVCbG9jayk7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLmlzQ29uc3RydWN0ZWQgPSB0cnVlO1xyXG4gICAgfVxyXG4gICAgZnJvbUJFUihpbnB1dEJ1ZmZlciwgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoKSB7XHJcbiAgICAgICAgdGhpcy52YWx1ZUJsb2NrLmlzSW5kZWZpbml0ZUZvcm0gPSB0aGlzLmxlbkJsb2NrLmlzSW5kZWZpbml0ZUZvcm07XHJcbiAgICAgICAgY29uc3QgcmVzdWx0T2Zmc2V0ID0gdGhpcy52YWx1ZUJsb2NrLmZyb21CRVIoaW5wdXRCdWZmZXIsIGlucHV0T2Zmc2V0LCAodGhpcy5sZW5CbG9jay5pc0luZGVmaW5pdGVGb3JtKSA/IGlucHV0TGVuZ3RoIDogdGhpcy5sZW5CbG9jay5sZW5ndGgpO1xyXG4gICAgICAgIGlmIChyZXN1bHRPZmZzZXQgPT09IC0xKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZXJyb3IgPSB0aGlzLnZhbHVlQmxvY2suZXJyb3I7XHJcbiAgICAgICAgICAgIHJldHVybiByZXN1bHRPZmZzZXQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghdGhpcy5pZEJsb2NrLmVycm9yLmxlbmd0aClcclxuICAgICAgICAgICAgdGhpcy5ibG9ja0xlbmd0aCArPSB0aGlzLmlkQmxvY2suYmxvY2tMZW5ndGg7XHJcbiAgICAgICAgaWYgKCF0aGlzLmxlbkJsb2NrLmVycm9yLmxlbmd0aClcclxuICAgICAgICAgICAgdGhpcy5ibG9ja0xlbmd0aCArPSB0aGlzLmxlbkJsb2NrLmJsb2NrTGVuZ3RoO1xyXG4gICAgICAgIGlmICghdGhpcy52YWx1ZUJsb2NrLmVycm9yLmxlbmd0aClcclxuICAgICAgICAgICAgdGhpcy5ibG9ja0xlbmd0aCArPSB0aGlzLnZhbHVlQmxvY2suYmxvY2tMZW5ndGg7XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdE9mZnNldDtcclxuICAgIH1cclxuICAgIG9uQXNjaWlFbmNvZGluZygpIHtcclxuICAgICAgICBjb25zdCB2YWx1ZXMgPSBbXTtcclxuICAgICAgICBmb3IgKGNvbnN0IHZhbHVlIG9mIHRoaXMudmFsdWVCbG9jay52YWx1ZSkge1xyXG4gICAgICAgICAgICB2YWx1ZXMucHVzaCh2YWx1ZS50b1N0cmluZyhcImFzY2lpXCIpLnNwbGl0KFwiXFxuXCIpLm1hcChvID0+IGAgICR7b31gKS5qb2luKFwiXFxuXCIpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgYmxvY2tOYW1lID0gdGhpcy5pZEJsb2NrLnRhZ0NsYXNzID09PSAzXHJcbiAgICAgICAgICAgID8gYFske3RoaXMuaWRCbG9jay50YWdOdW1iZXJ9XWBcclxuICAgICAgICAgICAgOiB0aGlzLmNvbnN0cnVjdG9yLk5BTUU7XHJcbiAgICAgICAgcmV0dXJuIHZhbHVlcy5sZW5ndGhcclxuICAgICAgICAgICAgPyBgJHtibG9ja05hbWV9IDpcXG4ke3ZhbHVlcy5qb2luKFwiXFxuXCIpfWBcclxuICAgICAgICAgICAgOiBgJHtibG9ja05hbWV9IDpgO1xyXG4gICAgfVxyXG59XHJcbl9hJHYgPSBDb25zdHJ1Y3RlZDtcclxuKCgpID0+IHtcclxuICAgIHR5cGVTdG9yZS5Db25zdHJ1Y3RlZCA9IF9hJHY7XHJcbn0pKCk7XHJcbkNvbnN0cnVjdGVkLk5BTUUgPSBcIkNPTlNUUlVDVEVEXCI7XG5cbmNsYXNzIExvY2FsRW5kT2ZDb250ZW50VmFsdWVCbG9jayBleHRlbmRzIFZhbHVlQmxvY2sge1xyXG4gICAgZnJvbUJFUihpbnB1dEJ1ZmZlciwgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoKSB7XHJcbiAgICAgICAgcmV0dXJuIGlucHV0T2Zmc2V0O1xyXG4gICAgfVxyXG4gICAgdG9CRVIoc2l6ZU9ubHkpIHtcclxuICAgICAgICByZXR1cm4gRU1QVFlfQlVGRkVSO1xyXG4gICAgfVxyXG59XHJcbkxvY2FsRW5kT2ZDb250ZW50VmFsdWVCbG9jay5vdmVycmlkZSA9IFwiRW5kT2ZDb250ZW50VmFsdWVCbG9ja1wiO1xuXG52YXIgX2EkdTtcclxuY2xhc3MgRW5kT2ZDb250ZW50IGV4dGVuZHMgQmFzZUJsb2NrIHtcclxuICAgIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMgPSB7fSkge1xyXG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMsIExvY2FsRW5kT2ZDb250ZW50VmFsdWVCbG9jayk7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ0NsYXNzID0gMTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnTnVtYmVyID0gMDtcclxuICAgIH1cclxufVxyXG5fYSR1ID0gRW5kT2ZDb250ZW50O1xyXG4oKCkgPT4ge1xyXG4gICAgdHlwZVN0b3JlLkVuZE9mQ29udGVudCA9IF9hJHU7XHJcbn0pKCk7XHJcbkVuZE9mQ29udGVudC5OQU1FID0gRU5EX09GX0NPTlRFTlRfTkFNRTtcblxudmFyIF9hJHQ7XHJcbmNsYXNzIE51bGwgZXh0ZW5kcyBCYXNlQmxvY2sge1xyXG4gICAgY29uc3RydWN0b3IocGFyYW1ldGVycyA9IHt9KSB7XHJcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycywgVmFsdWVCbG9jayk7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ0NsYXNzID0gMTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnTnVtYmVyID0gNTtcclxuICAgIH1cclxuICAgIGZyb21CRVIoaW5wdXRCdWZmZXIsIGlucHV0T2Zmc2V0LCBpbnB1dExlbmd0aCkge1xyXG4gICAgICAgIGlmICh0aGlzLmxlbkJsb2NrLmxlbmd0aCA+IDApXHJcbiAgICAgICAgICAgIHRoaXMud2FybmluZ3MucHVzaChcIk5vbi16ZXJvIGxlbmd0aCBvZiB2YWx1ZSBibG9jayBmb3IgTnVsbCB0eXBlXCIpO1xyXG4gICAgICAgIGlmICghdGhpcy5pZEJsb2NrLmVycm9yLmxlbmd0aClcclxuICAgICAgICAgICAgdGhpcy5ibG9ja0xlbmd0aCArPSB0aGlzLmlkQmxvY2suYmxvY2tMZW5ndGg7XHJcbiAgICAgICAgaWYgKCF0aGlzLmxlbkJsb2NrLmVycm9yLmxlbmd0aClcclxuICAgICAgICAgICAgdGhpcy5ibG9ja0xlbmd0aCArPSB0aGlzLmxlbkJsb2NrLmJsb2NrTGVuZ3RoO1xyXG4gICAgICAgIHRoaXMuYmxvY2tMZW5ndGggKz0gaW5wdXRMZW5ndGg7XHJcbiAgICAgICAgaWYgKChpbnB1dE9mZnNldCArIGlucHV0TGVuZ3RoKSA+IGlucHV0QnVmZmVyLmJ5dGVMZW5ndGgpIHtcclxuICAgICAgICAgICAgdGhpcy5lcnJvciA9IFwiRW5kIG9mIGlucHV0IHJlYWNoZWQgYmVmb3JlIG1lc3NhZ2Ugd2FzIGZ1bGx5IGRlY29kZWQgKGluY29uc2lzdGVudCBvZmZzZXQgYW5kIGxlbmd0aCB2YWx1ZXMpXCI7XHJcbiAgICAgICAgICAgIHJldHVybiAtMTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIChpbnB1dE9mZnNldCArIGlucHV0TGVuZ3RoKTtcclxuICAgIH1cclxuICAgIHRvQkVSKHNpemVPbmx5LCB3cml0ZXIpIHtcclxuICAgICAgICBjb25zdCByZXRCdWYgPSBuZXcgQXJyYXlCdWZmZXIoMik7XHJcbiAgICAgICAgaWYgKCFzaXplT25seSkge1xyXG4gICAgICAgICAgICBjb25zdCByZXRWaWV3ID0gbmV3IFVpbnQ4QXJyYXkocmV0QnVmKTtcclxuICAgICAgICAgICAgcmV0Vmlld1swXSA9IDB4MDU7XHJcbiAgICAgICAgICAgIHJldFZpZXdbMV0gPSAweDAwO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAod3JpdGVyKSB7XHJcbiAgICAgICAgICAgIHdyaXRlci53cml0ZShyZXRCdWYpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcmV0QnVmO1xyXG4gICAgfVxyXG4gICAgb25Bc2NpaUVuY29kaW5nKCkge1xyXG4gICAgICAgIHJldHVybiBgJHt0aGlzLmNvbnN0cnVjdG9yLk5BTUV9YDtcclxuICAgIH1cclxufVxyXG5fYSR0ID0gTnVsbDtcclxuKCgpID0+IHtcclxuICAgIHR5cGVTdG9yZS5OdWxsID0gX2EkdDtcclxufSkoKTtcclxuTnVsbC5OQU1FID0gXCJOVUxMXCI7XG5cbmNsYXNzIExvY2FsQm9vbGVhblZhbHVlQmxvY2sgZXh0ZW5kcyBIZXhCbG9jayhWYWx1ZUJsb2NrKSB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7IHZhbHVlLCAuLi5wYXJhbWV0ZXJzIH0gPSB7fSkge1xyXG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xyXG4gICAgICAgIGlmIChwYXJhbWV0ZXJzLnZhbHVlSGV4KSB7XHJcbiAgICAgICAgICAgIHRoaXMudmFsdWVIZXhWaWV3ID0gcHZ0c3V0aWxzLkJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b1VpbnQ4QXJyYXkocGFyYW1ldGVycy52YWx1ZUhleCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLnZhbHVlSGV4VmlldyA9IG5ldyBVaW50OEFycmF5KDEpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodmFsdWUpIHtcclxuICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGdldCB2YWx1ZSgpIHtcclxuICAgICAgICBmb3IgKGNvbnN0IG9jdGV0IG9mIHRoaXMudmFsdWVIZXhWaWV3KSB7XHJcbiAgICAgICAgICAgIGlmIChvY3RldCA+IDApIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIHNldCB2YWx1ZSh2YWx1ZSkge1xyXG4gICAgICAgIHRoaXMudmFsdWVIZXhWaWV3WzBdID0gdmFsdWUgPyAweEZGIDogMHgwMDtcclxuICAgIH1cclxuICAgIGZyb21CRVIoaW5wdXRCdWZmZXIsIGlucHV0T2Zmc2V0LCBpbnB1dExlbmd0aCkge1xyXG4gICAgICAgIGNvbnN0IGlucHV0VmlldyA9IHB2dHN1dGlscy5CdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9VaW50OEFycmF5KGlucHV0QnVmZmVyKTtcclxuICAgICAgICBpZiAoIWNoZWNrQnVmZmVyUGFyYW1zKHRoaXMsIGlucHV0VmlldywgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gLTE7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMudmFsdWVIZXhWaWV3ID0gaW5wdXRWaWV3LnN1YmFycmF5KGlucHV0T2Zmc2V0LCBpbnB1dE9mZnNldCArIGlucHV0TGVuZ3RoKTtcclxuICAgICAgICBpZiAoaW5wdXRMZW5ndGggPiAxKVxyXG4gICAgICAgICAgICB0aGlzLndhcm5pbmdzLnB1c2goXCJCb29sZWFuIHZhbHVlIGVuY29kZWQgaW4gbW9yZSB0aGVuIDEgb2N0ZXRcIik7XHJcbiAgICAgICAgdGhpcy5pc0hleE9ubHkgPSB0cnVlO1xyXG4gICAgICAgIHB2dXRpbHMudXRpbERlY29kZVRDLmNhbGwodGhpcyk7XHJcbiAgICAgICAgdGhpcy5ibG9ja0xlbmd0aCA9IGlucHV0TGVuZ3RoO1xyXG4gICAgICAgIHJldHVybiAoaW5wdXRPZmZzZXQgKyBpbnB1dExlbmd0aCk7XHJcbiAgICB9XHJcbiAgICB0b0JFUigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZUhleFZpZXcuc2xpY2UoKTtcclxuICAgIH1cclxuICAgIHRvSlNPTigpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAuLi5zdXBlci50b0pTT04oKSxcclxuICAgICAgICAgICAgdmFsdWU6IHRoaXMudmFsdWUsXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxufVxyXG5Mb2NhbEJvb2xlYW5WYWx1ZUJsb2NrLk5BTUUgPSBcIkJvb2xlYW5WYWx1ZUJsb2NrXCI7XG5cbnZhciBfYSRzO1xyXG5jbGFzcyBCb29sZWFuIGV4dGVuZHMgQmFzZUJsb2NrIHtcclxuICAgIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMgPSB7fSkge1xyXG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMsIExvY2FsQm9vbGVhblZhbHVlQmxvY2spO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdDbGFzcyA9IDE7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ051bWJlciA9IDE7XHJcbiAgICB9XHJcbiAgICBnZXRWYWx1ZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZUJsb2NrLnZhbHVlO1xyXG4gICAgfVxyXG4gICAgc2V0VmFsdWUodmFsdWUpIHtcclxuICAgICAgICB0aGlzLnZhbHVlQmxvY2sudmFsdWUgPSB2YWx1ZTtcclxuICAgIH1cclxuICAgIG9uQXNjaWlFbmNvZGluZygpIHtcclxuICAgICAgICByZXR1cm4gYCR7dGhpcy5jb25zdHJ1Y3Rvci5OQU1FfSA6ICR7dGhpcy5nZXRWYWx1ZX1gO1xyXG4gICAgfVxyXG59XHJcbl9hJHMgPSBCb29sZWFuO1xyXG4oKCkgPT4ge1xyXG4gICAgdHlwZVN0b3JlLkJvb2xlYW4gPSBfYSRzO1xyXG59KSgpO1xyXG5Cb29sZWFuLk5BTUUgPSBcIkJPT0xFQU5cIjtcblxuY2xhc3MgTG9jYWxPY3RldFN0cmluZ1ZhbHVlQmxvY2sgZXh0ZW5kcyBIZXhCbG9jayhMb2NhbENvbnN0cnVjdGVkVmFsdWVCbG9jaykge1xyXG4gICAgY29uc3RydWN0b3IoeyBpc0NvbnN0cnVjdGVkID0gZmFsc2UsIC4uLnBhcmFtZXRlcnMgfSA9IHt9KSB7XHJcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XHJcbiAgICAgICAgdGhpcy5pc0NvbnN0cnVjdGVkID0gaXNDb25zdHJ1Y3RlZDtcclxuICAgIH1cclxuICAgIGZyb21CRVIoaW5wdXRCdWZmZXIsIGlucHV0T2Zmc2V0LCBpbnB1dExlbmd0aCkge1xyXG4gICAgICAgIGxldCByZXN1bHRPZmZzZXQgPSAwO1xyXG4gICAgICAgIGlmICh0aGlzLmlzQ29uc3RydWN0ZWQpIHtcclxuICAgICAgICAgICAgdGhpcy5pc0hleE9ubHkgPSBmYWxzZTtcclxuICAgICAgICAgICAgcmVzdWx0T2Zmc2V0ID0gTG9jYWxDb25zdHJ1Y3RlZFZhbHVlQmxvY2sucHJvdG90eXBlLmZyb21CRVIuY2FsbCh0aGlzLCBpbnB1dEJ1ZmZlciwgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoKTtcclxuICAgICAgICAgICAgaWYgKHJlc3VsdE9mZnNldCA9PT0gLTEpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0T2Zmc2V0O1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMudmFsdWUubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRCbG9ja05hbWUgPSB0aGlzLnZhbHVlW2ldLmNvbnN0cnVjdG9yLk5BTUU7XHJcbiAgICAgICAgICAgICAgICBpZiAoY3VycmVudEJsb2NrTmFtZSA9PT0gRU5EX09GX0NPTlRFTlRfTkFNRSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzSW5kZWZpbml0ZUZvcm0pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVycm9yID0gXCJFbmRPZkNvbnRlbnQgaXMgdW5leHBlY3RlZCwgT0NURVQgU1RSSU5HIG1heSBjb25zaXN0cyBvZiBPQ1RFVCBTVFJJTkdzIG9ubHlcIjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChjdXJyZW50QmxvY2tOYW1lICE9PSBPQ1RFVF9TVFJJTkdfTkFNRSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXJyb3IgPSBcIk9DVEVUIFNUUklORyBtYXkgY29uc2lzdHMgb2YgT0NURVQgU1RSSU5HcyBvbmx5XCI7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLmlzSGV4T25seSA9IHRydWU7XHJcbiAgICAgICAgICAgIHJlc3VsdE9mZnNldCA9IHN1cGVyLmZyb21CRVIoaW5wdXRCdWZmZXIsIGlucHV0T2Zmc2V0LCBpbnB1dExlbmd0aCk7XHJcbiAgICAgICAgICAgIHRoaXMuYmxvY2tMZW5ndGggPSBpbnB1dExlbmd0aDtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdE9mZnNldDtcclxuICAgIH1cclxuICAgIHRvQkVSKHNpemVPbmx5LCB3cml0ZXIpIHtcclxuICAgICAgICBpZiAodGhpcy5pc0NvbnN0cnVjdGVkKVxyXG4gICAgICAgICAgICByZXR1cm4gTG9jYWxDb25zdHJ1Y3RlZFZhbHVlQmxvY2sucHJvdG90eXBlLnRvQkVSLmNhbGwodGhpcywgc2l6ZU9ubHksIHdyaXRlcik7XHJcbiAgICAgICAgcmV0dXJuIHNpemVPbmx5XHJcbiAgICAgICAgICAgID8gbmV3IEFycmF5QnVmZmVyKHRoaXMudmFsdWVIZXhWaWV3LmJ5dGVMZW5ndGgpXHJcbiAgICAgICAgICAgIDogdGhpcy52YWx1ZUhleFZpZXcuc2xpY2UoKS5idWZmZXI7XHJcbiAgICB9XHJcbiAgICB0b0pTT04oKSB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgLi4uc3VwZXIudG9KU09OKCksXHJcbiAgICAgICAgICAgIGlzQ29uc3RydWN0ZWQ6IHRoaXMuaXNDb25zdHJ1Y3RlZCxcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG59XHJcbkxvY2FsT2N0ZXRTdHJpbmdWYWx1ZUJsb2NrLk5BTUUgPSBcIk9jdGV0U3RyaW5nVmFsdWVCbG9ja1wiO1xuXG52YXIgX2EkcjtcclxuY2xhc3MgT2N0ZXRTdHJpbmcgZXh0ZW5kcyBCYXNlQmxvY2sge1xyXG4gICAgY29uc3RydWN0b3IoeyBpZEJsb2NrID0ge30sIGxlbkJsb2NrID0ge30sIC4uLnBhcmFtZXRlcnMgfSA9IHt9KSB7XHJcbiAgICAgICAgdmFyIF9iLCBfYztcclxuICAgICAgICAoX2IgPSBwYXJhbWV0ZXJzLmlzQ29uc3RydWN0ZWQpICE9PSBudWxsICYmIF9iICE9PSB2b2lkIDAgPyBfYiA6IChwYXJhbWV0ZXJzLmlzQ29uc3RydWN0ZWQgPSAhISgoX2MgPSBwYXJhbWV0ZXJzLnZhbHVlKSA9PT0gbnVsbCB8fCBfYyA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2MubGVuZ3RoKSk7XHJcbiAgICAgICAgc3VwZXIoe1xyXG4gICAgICAgICAgICBpZEJsb2NrOiB7XHJcbiAgICAgICAgICAgICAgICBpc0NvbnN0cnVjdGVkOiBwYXJhbWV0ZXJzLmlzQ29uc3RydWN0ZWQsXHJcbiAgICAgICAgICAgICAgICAuLi5pZEJsb2NrLFxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBsZW5CbG9jazoge1xyXG4gICAgICAgICAgICAgICAgLi4ubGVuQmxvY2ssXHJcbiAgICAgICAgICAgICAgICBpc0luZGVmaW5pdGVGb3JtOiAhIXBhcmFtZXRlcnMuaXNJbmRlZmluaXRlRm9ybSxcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgLi4ucGFyYW1ldGVycyxcclxuICAgICAgICB9LCBMb2NhbE9jdGV0U3RyaW5nVmFsdWVCbG9jayk7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ0NsYXNzID0gMTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnTnVtYmVyID0gNDtcclxuICAgIH1cclxuICAgIGZyb21CRVIoaW5wdXRCdWZmZXIsIGlucHV0T2Zmc2V0LCBpbnB1dExlbmd0aCkge1xyXG4gICAgICAgIHRoaXMudmFsdWVCbG9jay5pc0NvbnN0cnVjdGVkID0gdGhpcy5pZEJsb2NrLmlzQ29uc3RydWN0ZWQ7XHJcbiAgICAgICAgdGhpcy52YWx1ZUJsb2NrLmlzSW5kZWZpbml0ZUZvcm0gPSB0aGlzLmxlbkJsb2NrLmlzSW5kZWZpbml0ZUZvcm07XHJcbiAgICAgICAgaWYgKGlucHV0TGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmlkQmxvY2suZXJyb3IubGVuZ3RoID09PSAwKVxyXG4gICAgICAgICAgICAgICAgdGhpcy5ibG9ja0xlbmd0aCArPSB0aGlzLmlkQmxvY2suYmxvY2tMZW5ndGg7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmxlbkJsb2NrLmVycm9yLmxlbmd0aCA9PT0gMClcclxuICAgICAgICAgICAgICAgIHRoaXMuYmxvY2tMZW5ndGggKz0gdGhpcy5sZW5CbG9jay5ibG9ja0xlbmd0aDtcclxuICAgICAgICAgICAgcmV0dXJuIGlucHV0T2Zmc2V0O1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIXRoaXMudmFsdWVCbG9jay5pc0NvbnN0cnVjdGVkKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHZpZXcgPSBpbnB1dEJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyID8gbmV3IFVpbnQ4QXJyYXkoaW5wdXRCdWZmZXIpIDogaW5wdXRCdWZmZXI7XHJcbiAgICAgICAgICAgIGNvbnN0IGJ1ZiA9IHZpZXcuc3ViYXJyYXkoaW5wdXRPZmZzZXQsIGlucHV0T2Zmc2V0ICsgaW5wdXRMZW5ndGgpO1xyXG4gICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGJ1Zi5ieXRlTGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYXNuID0gbG9jYWxGcm9tQkVSKGJ1ZiwgMCwgYnVmLmJ5dGVMZW5ndGgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChhc24ub2Zmc2V0ICE9PSAtMSAmJiBhc24ub2Zmc2V0ID09PSBpbnB1dExlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZhbHVlQmxvY2sudmFsdWUgPSBbYXNuLnJlc3VsdF07XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHN1cGVyLmZyb21CRVIoaW5wdXRCdWZmZXIsIGlucHV0T2Zmc2V0LCBpbnB1dExlbmd0aCk7XHJcbiAgICB9XHJcbiAgICBvbkFzY2lpRW5jb2RpbmcoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMudmFsdWVCbG9jay5pc0NvbnN0cnVjdGVkIHx8ICh0aGlzLnZhbHVlQmxvY2sudmFsdWUgJiYgdGhpcy52YWx1ZUJsb2NrLnZhbHVlLmxlbmd0aCkpIHtcclxuICAgICAgICAgICAgcmV0dXJuIENvbnN0cnVjdGVkLnByb3RvdHlwZS5vbkFzY2lpRW5jb2RpbmcuY2FsbCh0aGlzKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGAke3RoaXMuY29uc3RydWN0b3IuTkFNRX0gOiAke3B2dHN1dGlscy5Db252ZXJ0LlRvSGV4KHRoaXMudmFsdWVCbG9jay52YWx1ZUhleFZpZXcpfWA7XHJcbiAgICB9XHJcbiAgICBnZXRWYWx1ZSgpIHtcclxuICAgICAgICBpZiAoIXRoaXMuaWRCbG9jay5pc0NvbnN0cnVjdGVkKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnZhbHVlQmxvY2sudmFsdWVIZXhWaWV3LnNsaWNlKCkuYnVmZmVyO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBhcnJheSA9IFtdO1xyXG4gICAgICAgIGZvciAoY29uc3QgY29udGVudCBvZiB0aGlzLnZhbHVlQmxvY2sudmFsdWUpIHtcclxuICAgICAgICAgICAgaWYgKGNvbnRlbnQgaW5zdGFuY2VvZiBPY3RldFN0cmluZykge1xyXG4gICAgICAgICAgICAgICAgYXJyYXkucHVzaChjb250ZW50LnZhbHVlQmxvY2sudmFsdWVIZXhWaWV3KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcHZ0c3V0aWxzLkJ1ZmZlclNvdXJjZUNvbnZlcnRlci5jb25jYXQoYXJyYXkpO1xyXG4gICAgfVxyXG59XHJcbl9hJHIgPSBPY3RldFN0cmluZztcclxuKCgpID0+IHtcclxuICAgIHR5cGVTdG9yZS5PY3RldFN0cmluZyA9IF9hJHI7XHJcbn0pKCk7XHJcbk9jdGV0U3RyaW5nLk5BTUUgPSBPQ1RFVF9TVFJJTkdfTkFNRTtcblxuY2xhc3MgTG9jYWxCaXRTdHJpbmdWYWx1ZUJsb2NrIGV4dGVuZHMgSGV4QmxvY2soTG9jYWxDb25zdHJ1Y3RlZFZhbHVlQmxvY2spIHtcclxuICAgIGNvbnN0cnVjdG9yKHsgdW51c2VkQml0cyA9IDAsIGlzQ29uc3RydWN0ZWQgPSBmYWxzZSwgLi4ucGFyYW1ldGVycyB9ID0ge30pIHtcclxuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcclxuICAgICAgICB0aGlzLnVudXNlZEJpdHMgPSB1bnVzZWRCaXRzO1xyXG4gICAgICAgIHRoaXMuaXNDb25zdHJ1Y3RlZCA9IGlzQ29uc3RydWN0ZWQ7XHJcbiAgICAgICAgdGhpcy5ibG9ja0xlbmd0aCA9IHRoaXMudmFsdWVIZXhWaWV3LmJ5dGVMZW5ndGg7XHJcbiAgICB9XHJcbiAgICBmcm9tQkVSKGlucHV0QnVmZmVyLCBpbnB1dE9mZnNldCwgaW5wdXRMZW5ndGgpIHtcclxuICAgICAgICBpZiAoIWlucHV0TGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBpbnB1dE9mZnNldDtcclxuICAgICAgICB9XHJcbiAgICAgICAgbGV0IHJlc3VsdE9mZnNldCA9IC0xO1xyXG4gICAgICAgIGlmICh0aGlzLmlzQ29uc3RydWN0ZWQpIHtcclxuICAgICAgICAgICAgcmVzdWx0T2Zmc2V0ID0gTG9jYWxDb25zdHJ1Y3RlZFZhbHVlQmxvY2sucHJvdG90eXBlLmZyb21CRVIuY2FsbCh0aGlzLCBpbnB1dEJ1ZmZlciwgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoKTtcclxuICAgICAgICAgICAgaWYgKHJlc3VsdE9mZnNldCA9PT0gLTEpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0T2Zmc2V0O1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHZhbHVlIG9mIHRoaXMudmFsdWUpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRCbG9ja05hbWUgPSB2YWx1ZS5jb25zdHJ1Y3Rvci5OQU1FO1xyXG4gICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRCbG9ja05hbWUgPT09IEVORF9PRl9DT05URU5UX05BTUUpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5pc0luZGVmaW5pdGVGb3JtKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lcnJvciA9IFwiRW5kT2ZDb250ZW50IGlzIHVuZXhwZWN0ZWQsIEJJVCBTVFJJTkcgbWF5IGNvbnNpc3RzIG9mIEJJVCBTVFJJTkdzIG9ubHlcIjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChjdXJyZW50QmxvY2tOYW1lICE9PSBCSVRfU1RSSU5HX05BTUUpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmVycm9yID0gXCJCSVQgU1RSSU5HIG1heSBjb25zaXN0cyBvZiBCSVQgU1RSSU5HcyBvbmx5XCI7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWVCbG9jayA9IHZhbHVlLnZhbHVlQmxvY2s7XHJcbiAgICAgICAgICAgICAgICBpZiAoKHRoaXMudW51c2VkQml0cyA+IDApICYmICh2YWx1ZUJsb2NrLnVudXNlZEJpdHMgPiAwKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXJyb3IgPSBcIlVzaW5nIG9mIFxcXCJ1bnVzZWQgYml0c1xcXCIgaW5zaWRlIGNvbnN0cnVjdGl2ZSBCSVQgU1RSSU5HIGFsbG93ZWQgZm9yIGxlYXN0IG9uZSBvbmx5XCI7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdGhpcy51bnVzZWRCaXRzID0gdmFsdWVCbG9jay51bnVzZWRCaXRzO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiByZXN1bHRPZmZzZXQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IGlucHV0VmlldyA9IHB2dHN1dGlscy5CdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9VaW50OEFycmF5KGlucHV0QnVmZmVyKTtcclxuICAgICAgICBpZiAoIWNoZWNrQnVmZmVyUGFyYW1zKHRoaXMsIGlucHV0VmlldywgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gLTE7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IGludEJ1ZmZlciA9IGlucHV0Vmlldy5zdWJhcnJheShpbnB1dE9mZnNldCwgaW5wdXRPZmZzZXQgKyBpbnB1dExlbmd0aCk7XHJcbiAgICAgICAgdGhpcy51bnVzZWRCaXRzID0gaW50QnVmZmVyWzBdO1xyXG4gICAgICAgIGlmICh0aGlzLnVudXNlZEJpdHMgPiA3KSB7XHJcbiAgICAgICAgICAgIHRoaXMuZXJyb3IgPSBcIlVudXNlZCBiaXRzIGZvciBCaXRTdHJpbmcgbXVzdCBiZSBpbiByYW5nZSAwLTdcIjtcclxuICAgICAgICAgICAgcmV0dXJuIC0xO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIXRoaXMudW51c2VkQml0cykge1xyXG4gICAgICAgICAgICBjb25zdCBidWYgPSBpbnRCdWZmZXIuc3ViYXJyYXkoMSk7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoYnVmLmJ5dGVMZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBhc24gPSBsb2NhbEZyb21CRVIoYnVmLCAwLCBidWYuYnl0ZUxlbmd0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGFzbi5vZmZzZXQgIT09IC0xICYmIGFzbi5vZmZzZXQgPT09IChpbnB1dExlbmd0aCAtIDEpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudmFsdWUgPSBbYXNuLnJlc3VsdF07XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy52YWx1ZUhleFZpZXcgPSBpbnRCdWZmZXIuc3ViYXJyYXkoMSk7XHJcbiAgICAgICAgdGhpcy5ibG9ja0xlbmd0aCA9IGludEJ1ZmZlci5sZW5ndGg7XHJcbiAgICAgICAgcmV0dXJuIChpbnB1dE9mZnNldCArIGlucHV0TGVuZ3RoKTtcclxuICAgIH1cclxuICAgIHRvQkVSKHNpemVPbmx5LCB3cml0ZXIpIHtcclxuICAgICAgICBpZiAodGhpcy5pc0NvbnN0cnVjdGVkKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBMb2NhbENvbnN0cnVjdGVkVmFsdWVCbG9jay5wcm90b3R5cGUudG9CRVIuY2FsbCh0aGlzLCBzaXplT25seSwgd3JpdGVyKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHNpemVPbmx5KSB7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgQXJyYXlCdWZmZXIodGhpcy52YWx1ZUhleFZpZXcuYnl0ZUxlbmd0aCArIDEpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIXRoaXMudmFsdWVIZXhWaWV3LmJ5dGVMZW5ndGgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIEVNUFRZX0JVRkZFUjtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgcmV0VmlldyA9IG5ldyBVaW50OEFycmF5KHRoaXMudmFsdWVIZXhWaWV3Lmxlbmd0aCArIDEpO1xyXG4gICAgICAgIHJldFZpZXdbMF0gPSB0aGlzLnVudXNlZEJpdHM7XHJcbiAgICAgICAgcmV0Vmlldy5zZXQodGhpcy52YWx1ZUhleFZpZXcsIDEpO1xyXG4gICAgICAgIHJldHVybiByZXRWaWV3LmJ1ZmZlcjtcclxuICAgIH1cclxuICAgIHRvSlNPTigpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAuLi5zdXBlci50b0pTT04oKSxcclxuICAgICAgICAgICAgdW51c2VkQml0czogdGhpcy51bnVzZWRCaXRzLFxyXG4gICAgICAgICAgICBpc0NvbnN0cnVjdGVkOiB0aGlzLmlzQ29uc3RydWN0ZWQsXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxufVxyXG5Mb2NhbEJpdFN0cmluZ1ZhbHVlQmxvY2suTkFNRSA9IFwiQml0U3RyaW5nVmFsdWVCbG9ja1wiO1xuXG52YXIgX2EkcTtcclxuY2xhc3MgQml0U3RyaW5nIGV4dGVuZHMgQmFzZUJsb2NrIHtcclxuICAgIGNvbnN0cnVjdG9yKHsgaWRCbG9jayA9IHt9LCBsZW5CbG9jayA9IHt9LCAuLi5wYXJhbWV0ZXJzIH0gPSB7fSkge1xyXG4gICAgICAgIHZhciBfYiwgX2M7XHJcbiAgICAgICAgKF9iID0gcGFyYW1ldGVycy5pc0NvbnN0cnVjdGVkKSAhPT0gbnVsbCAmJiBfYiAhPT0gdm9pZCAwID8gX2IgOiAocGFyYW1ldGVycy5pc0NvbnN0cnVjdGVkID0gISEoKF9jID0gcGFyYW1ldGVycy52YWx1ZSkgPT09IG51bGwgfHwgX2MgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9jLmxlbmd0aCkpO1xyXG4gICAgICAgIHN1cGVyKHtcclxuICAgICAgICAgICAgaWRCbG9jazoge1xyXG4gICAgICAgICAgICAgICAgaXNDb25zdHJ1Y3RlZDogcGFyYW1ldGVycy5pc0NvbnN0cnVjdGVkLFxyXG4gICAgICAgICAgICAgICAgLi4uaWRCbG9jayxcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgbGVuQmxvY2s6IHtcclxuICAgICAgICAgICAgICAgIC4uLmxlbkJsb2NrLFxyXG4gICAgICAgICAgICAgICAgaXNJbmRlZmluaXRlRm9ybTogISFwYXJhbWV0ZXJzLmlzSW5kZWZpbml0ZUZvcm0sXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIC4uLnBhcmFtZXRlcnMsXHJcbiAgICAgICAgfSwgTG9jYWxCaXRTdHJpbmdWYWx1ZUJsb2NrKTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnQ2xhc3MgPSAxO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdOdW1iZXIgPSAzO1xyXG4gICAgfVxyXG4gICAgZnJvbUJFUihpbnB1dEJ1ZmZlciwgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoKSB7XHJcbiAgICAgICAgdGhpcy52YWx1ZUJsb2NrLmlzQ29uc3RydWN0ZWQgPSB0aGlzLmlkQmxvY2suaXNDb25zdHJ1Y3RlZDtcclxuICAgICAgICB0aGlzLnZhbHVlQmxvY2suaXNJbmRlZmluaXRlRm9ybSA9IHRoaXMubGVuQmxvY2suaXNJbmRlZmluaXRlRm9ybTtcclxuICAgICAgICByZXR1cm4gc3VwZXIuZnJvbUJFUihpbnB1dEJ1ZmZlciwgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoKTtcclxuICAgIH1cclxuICAgIG9uQXNjaWlFbmNvZGluZygpIHtcclxuICAgICAgICBpZiAodGhpcy52YWx1ZUJsb2NrLmlzQ29uc3RydWN0ZWQgfHwgKHRoaXMudmFsdWVCbG9jay52YWx1ZSAmJiB0aGlzLnZhbHVlQmxvY2sudmFsdWUubGVuZ3RoKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gQ29uc3RydWN0ZWQucHJvdG90eXBlLm9uQXNjaWlFbmNvZGluZy5jYWxsKHRoaXMpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgY29uc3QgYml0cyA9IFtdO1xyXG4gICAgICAgICAgICBjb25zdCB2YWx1ZUhleCA9IHRoaXMudmFsdWVCbG9jay52YWx1ZUhleFZpZXc7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgYnl0ZSBvZiB2YWx1ZUhleCkge1xyXG4gICAgICAgICAgICAgICAgYml0cy5wdXNoKGJ5dGUudG9TdHJpbmcoMikucGFkU3RhcnQoOCwgXCIwXCIpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjb25zdCBiaXRzU3RyID0gYml0cy5qb2luKFwiXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gYCR7dGhpcy5jb25zdHJ1Y3Rvci5OQU1FfSA6ICR7Yml0c1N0ci5zdWJzdHJpbmcoMCwgYml0c1N0ci5sZW5ndGggLSB0aGlzLnZhbHVlQmxvY2sudW51c2VkQml0cyl9YDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuX2EkcSA9IEJpdFN0cmluZztcclxuKCgpID0+IHtcclxuICAgIHR5cGVTdG9yZS5CaXRTdHJpbmcgPSBfYSRxO1xyXG59KSgpO1xyXG5CaXRTdHJpbmcuTkFNRSA9IEJJVF9TVFJJTkdfTkFNRTtcblxudmFyIF9hJHA7XHJcbmZ1bmN0aW9uIHZpZXdBZGQoZmlyc3QsIHNlY29uZCkge1xyXG4gICAgY29uc3QgYyA9IG5ldyBVaW50OEFycmF5KFswXSk7XHJcbiAgICBjb25zdCBmaXJzdFZpZXcgPSBuZXcgVWludDhBcnJheShmaXJzdCk7XHJcbiAgICBjb25zdCBzZWNvbmRWaWV3ID0gbmV3IFVpbnQ4QXJyYXkoc2Vjb25kKTtcclxuICAgIGxldCBmaXJzdFZpZXdDb3B5ID0gZmlyc3RWaWV3LnNsaWNlKDApO1xyXG4gICAgY29uc3QgZmlyc3RWaWV3Q29weUxlbmd0aCA9IGZpcnN0Vmlld0NvcHkubGVuZ3RoIC0gMTtcclxuICAgIGNvbnN0IHNlY29uZFZpZXdDb3B5ID0gc2Vjb25kVmlldy5zbGljZSgwKTtcclxuICAgIGNvbnN0IHNlY29uZFZpZXdDb3B5TGVuZ3RoID0gc2Vjb25kVmlld0NvcHkubGVuZ3RoIC0gMTtcclxuICAgIGxldCB2YWx1ZSA9IDA7XHJcbiAgICBjb25zdCBtYXggPSAoc2Vjb25kVmlld0NvcHlMZW5ndGggPCBmaXJzdFZpZXdDb3B5TGVuZ3RoKSA/IGZpcnN0Vmlld0NvcHlMZW5ndGggOiBzZWNvbmRWaWV3Q29weUxlbmd0aDtcclxuICAgIGxldCBjb3VudGVyID0gMDtcclxuICAgIGZvciAobGV0IGkgPSBtYXg7IGkgPj0gMDsgaS0tLCBjb3VudGVyKyspIHtcclxuICAgICAgICBzd2l0Y2ggKHRydWUpIHtcclxuICAgICAgICAgICAgY2FzZSAoY291bnRlciA8IHNlY29uZFZpZXdDb3B5Lmxlbmd0aCk6XHJcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IGZpcnN0Vmlld0NvcHlbZmlyc3RWaWV3Q29weUxlbmd0aCAtIGNvdW50ZXJdICsgc2Vjb25kVmlld0NvcHlbc2Vjb25kVmlld0NvcHlMZW5ndGggLSBjb3VudGVyXSArIGNbMF07XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgIHZhbHVlID0gZmlyc3RWaWV3Q29weVtmaXJzdFZpZXdDb3B5TGVuZ3RoIC0gY291bnRlcl0gKyBjWzBdO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjWzBdID0gdmFsdWUgLyAxMDtcclxuICAgICAgICBzd2l0Y2ggKHRydWUpIHtcclxuICAgICAgICAgICAgY2FzZSAoY291bnRlciA+PSBmaXJzdFZpZXdDb3B5Lmxlbmd0aCk6XHJcbiAgICAgICAgICAgICAgICBmaXJzdFZpZXdDb3B5ID0gcHZ1dGlscy51dGlsQ29uY2F0VmlldyhuZXcgVWludDhBcnJheShbdmFsdWUgJSAxMF0pLCBmaXJzdFZpZXdDb3B5KTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgZmlyc3RWaWV3Q29weVtmaXJzdFZpZXdDb3B5TGVuZ3RoIC0gY291bnRlcl0gPSB2YWx1ZSAlIDEwO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGlmIChjWzBdID4gMClcclxuICAgICAgICBmaXJzdFZpZXdDb3B5ID0gcHZ1dGlscy51dGlsQ29uY2F0VmlldyhjLCBmaXJzdFZpZXdDb3B5KTtcclxuICAgIHJldHVybiBmaXJzdFZpZXdDb3B5O1xyXG59XHJcbmZ1bmN0aW9uIHBvd2VyMihuKSB7XHJcbiAgICBpZiAobiA+PSBwb3dlcnMyLmxlbmd0aCkge1xyXG4gICAgICAgIGZvciAobGV0IHAgPSBwb3dlcnMyLmxlbmd0aDsgcCA8PSBuOyBwKyspIHtcclxuICAgICAgICAgICAgY29uc3QgYyA9IG5ldyBVaW50OEFycmF5KFswXSk7XHJcbiAgICAgICAgICAgIGxldCBkaWdpdHMgPSAocG93ZXJzMltwIC0gMV0pLnNsaWNlKDApO1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gKGRpZ2l0cy5sZW5ndGggLSAxKTsgaSA+PSAwOyBpLS0pIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG5ld1ZhbHVlID0gbmV3IFVpbnQ4QXJyYXkoWyhkaWdpdHNbaV0gPDwgMSkgKyBjWzBdXSk7XHJcbiAgICAgICAgICAgICAgICBjWzBdID0gbmV3VmFsdWVbMF0gLyAxMDtcclxuICAgICAgICAgICAgICAgIGRpZ2l0c1tpXSA9IG5ld1ZhbHVlWzBdICUgMTA7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGNbMF0gPiAwKVxyXG4gICAgICAgICAgICAgICAgZGlnaXRzID0gcHZ1dGlscy51dGlsQ29uY2F0VmlldyhjLCBkaWdpdHMpO1xyXG4gICAgICAgICAgICBwb3dlcnMyLnB1c2goZGlnaXRzKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcG93ZXJzMltuXTtcclxufVxyXG5mdW5jdGlvbiB2aWV3U3ViKGZpcnN0LCBzZWNvbmQpIHtcclxuICAgIGxldCBiID0gMDtcclxuICAgIGNvbnN0IGZpcnN0VmlldyA9IG5ldyBVaW50OEFycmF5KGZpcnN0KTtcclxuICAgIGNvbnN0IHNlY29uZFZpZXcgPSBuZXcgVWludDhBcnJheShzZWNvbmQpO1xyXG4gICAgY29uc3QgZmlyc3RWaWV3Q29weSA9IGZpcnN0Vmlldy5zbGljZSgwKTtcclxuICAgIGNvbnN0IGZpcnN0Vmlld0NvcHlMZW5ndGggPSBmaXJzdFZpZXdDb3B5Lmxlbmd0aCAtIDE7XHJcbiAgICBjb25zdCBzZWNvbmRWaWV3Q29weSA9IHNlY29uZFZpZXcuc2xpY2UoMCk7XHJcbiAgICBjb25zdCBzZWNvbmRWaWV3Q29weUxlbmd0aCA9IHNlY29uZFZpZXdDb3B5Lmxlbmd0aCAtIDE7XHJcbiAgICBsZXQgdmFsdWU7XHJcbiAgICBsZXQgY291bnRlciA9IDA7XHJcbiAgICBmb3IgKGxldCBpID0gc2Vjb25kVmlld0NvcHlMZW5ndGg7IGkgPj0gMDsgaS0tLCBjb3VudGVyKyspIHtcclxuICAgICAgICB2YWx1ZSA9IGZpcnN0Vmlld0NvcHlbZmlyc3RWaWV3Q29weUxlbmd0aCAtIGNvdW50ZXJdIC0gc2Vjb25kVmlld0NvcHlbc2Vjb25kVmlld0NvcHlMZW5ndGggLSBjb3VudGVyXSAtIGI7XHJcbiAgICAgICAgc3dpdGNoICh0cnVlKSB7XHJcbiAgICAgICAgICAgIGNhc2UgKHZhbHVlIDwgMCk6XHJcbiAgICAgICAgICAgICAgICBiID0gMTtcclxuICAgICAgICAgICAgICAgIGZpcnN0Vmlld0NvcHlbZmlyc3RWaWV3Q29weUxlbmd0aCAtIGNvdW50ZXJdID0gdmFsdWUgKyAxMDtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgYiA9IDA7XHJcbiAgICAgICAgICAgICAgICBmaXJzdFZpZXdDb3B5W2ZpcnN0Vmlld0NvcHlMZW5ndGggLSBjb3VudGVyXSA9IHZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGlmIChiID4gMCkge1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAoZmlyc3RWaWV3Q29weUxlbmd0aCAtIHNlY29uZFZpZXdDb3B5TGVuZ3RoICsgMSk7IGkgPj0gMDsgaS0tLCBjb3VudGVyKyspIHtcclxuICAgICAgICAgICAgdmFsdWUgPSBmaXJzdFZpZXdDb3B5W2ZpcnN0Vmlld0NvcHlMZW5ndGggLSBjb3VudGVyXSAtIGI7XHJcbiAgICAgICAgICAgIGlmICh2YWx1ZSA8IDApIHtcclxuICAgICAgICAgICAgICAgIGIgPSAxO1xyXG4gICAgICAgICAgICAgICAgZmlyc3RWaWV3Q29weVtmaXJzdFZpZXdDb3B5TGVuZ3RoIC0gY291bnRlcl0gPSB2YWx1ZSArIDEwO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgYiA9IDA7XHJcbiAgICAgICAgICAgICAgICBmaXJzdFZpZXdDb3B5W2ZpcnN0Vmlld0NvcHlMZW5ndGggLSBjb3VudGVyXSA9IHZhbHVlO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZmlyc3RWaWV3Q29weS5zbGljZSgpO1xyXG59XHJcbmNsYXNzIExvY2FsSW50ZWdlclZhbHVlQmxvY2sgZXh0ZW5kcyBIZXhCbG9jayhWYWx1ZUJsb2NrKSB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7IHZhbHVlLCAuLi5wYXJhbWV0ZXJzIH0gPSB7fSkge1xyXG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xyXG4gICAgICAgIHRoaXMuX3ZhbHVlRGVjID0gMDtcclxuICAgICAgICBpZiAocGFyYW1ldGVycy52YWx1ZUhleCkge1xyXG4gICAgICAgICAgICB0aGlzLnNldFZhbHVlSGV4KCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIHRoaXMudmFsdWVEZWMgPSB2YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBzZXRWYWx1ZUhleCgpIHtcclxuICAgICAgICBpZiAodGhpcy52YWx1ZUhleFZpZXcubGVuZ3RoID49IDQpIHtcclxuICAgICAgICAgICAgdGhpcy53YXJuaW5ncy5wdXNoKFwiVG9vIGJpZyBJbnRlZ2VyIGZvciBkZWNvZGluZywgaGV4IG9ubHlcIik7XHJcbiAgICAgICAgICAgIHRoaXMuaXNIZXhPbmx5ID0gdHJ1ZTtcclxuICAgICAgICAgICAgdGhpcy5fdmFsdWVEZWMgPSAwO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5pc0hleE9ubHkgPSBmYWxzZTtcclxuICAgICAgICAgICAgaWYgKHRoaXMudmFsdWVIZXhWaWV3Lmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3ZhbHVlRGVjID0gcHZ1dGlscy51dGlsRGVjb2RlVEMuY2FsbCh0aGlzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHNldCB2YWx1ZURlYyh2KSB7XHJcbiAgICAgICAgdGhpcy5fdmFsdWVEZWMgPSB2O1xyXG4gICAgICAgIHRoaXMuaXNIZXhPbmx5ID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy52YWx1ZUhleFZpZXcgPSBuZXcgVWludDhBcnJheShwdnV0aWxzLnV0aWxFbmNvZGVUQyh2KSk7XHJcbiAgICB9XHJcbiAgICBnZXQgdmFsdWVEZWMoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlRGVjO1xyXG4gICAgfVxyXG4gICAgZnJvbURFUihpbnB1dEJ1ZmZlciwgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoLCBleHBlY3RlZExlbmd0aCA9IDApIHtcclxuICAgICAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmZyb21CRVIoaW5wdXRCdWZmZXIsIGlucHV0T2Zmc2V0LCBpbnB1dExlbmd0aCk7XHJcbiAgICAgICAgaWYgKG9mZnNldCA9PT0gLTEpXHJcbiAgICAgICAgICAgIHJldHVybiBvZmZzZXQ7XHJcbiAgICAgICAgY29uc3QgdmlldyA9IHRoaXMudmFsdWVIZXhWaWV3O1xyXG4gICAgICAgIGlmICgodmlld1swXSA9PT0gMHgwMCkgJiYgKCh2aWV3WzFdICYgMHg4MCkgIT09IDApKSB7XHJcbiAgICAgICAgICAgIHRoaXMudmFsdWVIZXhWaWV3ID0gdmlldy5zdWJhcnJheSgxKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGlmIChleHBlY3RlZExlbmd0aCAhPT0gMCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHZpZXcubGVuZ3RoIDwgZXhwZWN0ZWRMZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoKGV4cGVjdGVkTGVuZ3RoIC0gdmlldy5sZW5ndGgpID4gMSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWRMZW5ndGggPSB2aWV3Lmxlbmd0aCArIDE7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy52YWx1ZUhleFZpZXcgPSB2aWV3LnN1YmFycmF5KGV4cGVjdGVkTGVuZ3RoIC0gdmlldy5sZW5ndGgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBvZmZzZXQ7XHJcbiAgICB9XHJcbiAgICB0b0RFUihzaXplT25seSA9IGZhbHNlKSB7XHJcbiAgICAgICAgY29uc3QgdmlldyA9IHRoaXMudmFsdWVIZXhWaWV3O1xyXG4gICAgICAgIHN3aXRjaCAodHJ1ZSkge1xyXG4gICAgICAgICAgICBjYXNlICgodmlld1swXSAmIDB4ODApICE9PSAwKTpcclxuICAgICAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCB1cGRhdGVkVmlldyA9IG5ldyBVaW50OEFycmF5KHRoaXMudmFsdWVIZXhWaWV3Lmxlbmd0aCArIDEpO1xyXG4gICAgICAgICAgICAgICAgICAgIHVwZGF0ZWRWaWV3WzBdID0gMHgwMDtcclxuICAgICAgICAgICAgICAgICAgICB1cGRhdGVkVmlldy5zZXQodmlldywgMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy52YWx1ZUhleFZpZXcgPSB1cGRhdGVkVmlldztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlICgodmlld1swXSA9PT0gMHgwMCkgJiYgKCh2aWV3WzFdICYgMHg4MCkgPT09IDApKTpcclxuICAgICAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnZhbHVlSGV4VmlldyA9IHRoaXMudmFsdWVIZXhWaWV3LnN1YmFycmF5KDEpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0aGlzLnRvQkVSKHNpemVPbmx5KTtcclxuICAgIH1cclxuICAgIGZyb21CRVIoaW5wdXRCdWZmZXIsIGlucHV0T2Zmc2V0LCBpbnB1dExlbmd0aCkge1xyXG4gICAgICAgIGNvbnN0IHJlc3VsdE9mZnNldCA9IHN1cGVyLmZyb21CRVIoaW5wdXRCdWZmZXIsIGlucHV0T2Zmc2V0LCBpbnB1dExlbmd0aCk7XHJcbiAgICAgICAgaWYgKHJlc3VsdE9mZnNldCA9PT0gLTEpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdE9mZnNldDtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5zZXRWYWx1ZUhleCgpO1xyXG4gICAgICAgIHJldHVybiByZXN1bHRPZmZzZXQ7XHJcbiAgICB9XHJcbiAgICB0b0JFUihzaXplT25seSkge1xyXG4gICAgICAgIHJldHVybiBzaXplT25seVxyXG4gICAgICAgICAgICA/IG5ldyBBcnJheUJ1ZmZlcih0aGlzLnZhbHVlSGV4Vmlldy5sZW5ndGgpXHJcbiAgICAgICAgICAgIDogdGhpcy52YWx1ZUhleFZpZXcuc2xpY2UoKS5idWZmZXI7XHJcbiAgICB9XHJcbiAgICB0b0pTT04oKSB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgLi4uc3VwZXIudG9KU09OKCksXHJcbiAgICAgICAgICAgIHZhbHVlRGVjOiB0aGlzLnZhbHVlRGVjLFxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbiAgICB0b1N0cmluZygpIHtcclxuICAgICAgICBjb25zdCBmaXJzdEJpdCA9ICh0aGlzLnZhbHVlSGV4Vmlldy5sZW5ndGggKiA4KSAtIDE7XHJcbiAgICAgICAgbGV0IGRpZ2l0cyA9IG5ldyBVaW50OEFycmF5KCh0aGlzLnZhbHVlSGV4Vmlldy5sZW5ndGggKiA4KSAvIDMpO1xyXG4gICAgICAgIGxldCBiaXROdW1iZXIgPSAwO1xyXG4gICAgICAgIGxldCBjdXJyZW50Qnl0ZTtcclxuICAgICAgICBjb25zdCBhc24xVmlldyA9IHRoaXMudmFsdWVIZXhWaWV3O1xyXG4gICAgICAgIGxldCByZXN1bHQgPSBcIlwiO1xyXG4gICAgICAgIGxldCBmbGFnID0gZmFsc2U7XHJcbiAgICAgICAgZm9yIChsZXQgYnl0ZU51bWJlciA9IChhc24xVmlldy5ieXRlTGVuZ3RoIC0gMSk7IGJ5dGVOdW1iZXIgPj0gMDsgYnl0ZU51bWJlci0tKSB7XHJcbiAgICAgICAgICAgIGN1cnJlbnRCeXRlID0gYXNuMVZpZXdbYnl0ZU51bWJlcl07XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgODsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoKGN1cnJlbnRCeXRlICYgMSkgPT09IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGJpdE51bWJlcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIGZpcnN0Qml0OlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlnaXRzID0gdmlld1N1Yihwb3dlcjIoYml0TnVtYmVyKSwgZGlnaXRzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IFwiLVwiO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaWdpdHMgPSB2aWV3QWRkKGRpZ2l0cywgcG93ZXIyKGJpdE51bWJlcikpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGJpdE51bWJlcisrO1xyXG4gICAgICAgICAgICAgICAgY3VycmVudEJ5dGUgPj49IDE7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkaWdpdHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgaWYgKGRpZ2l0c1tpXSlcclxuICAgICAgICAgICAgICAgIGZsYWcgPSB0cnVlO1xyXG4gICAgICAgICAgICBpZiAoZmxhZylcclxuICAgICAgICAgICAgICAgIHJlc3VsdCArPSBkaWdpdHNTdHJpbmcuY2hhckF0KGRpZ2l0c1tpXSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChmbGFnID09PSBmYWxzZSlcclxuICAgICAgICAgICAgcmVzdWx0ICs9IGRpZ2l0c1N0cmluZy5jaGFyQXQoMCk7XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH1cclxufVxyXG5fYSRwID0gTG9jYWxJbnRlZ2VyVmFsdWVCbG9jaztcclxuTG9jYWxJbnRlZ2VyVmFsdWVCbG9jay5OQU1FID0gXCJJbnRlZ2VyVmFsdWVCbG9ja1wiO1xyXG4oKCkgPT4ge1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KF9hJHAucHJvdG90eXBlLCBcInZhbHVlSGV4XCIsIHtcclxuICAgICAgICBzZXQ6IGZ1bmN0aW9uICh2KSB7XHJcbiAgICAgICAgICAgIHRoaXMudmFsdWVIZXhWaWV3ID0gbmV3IFVpbnQ4QXJyYXkodik7XHJcbiAgICAgICAgICAgIHRoaXMuc2V0VmFsdWVIZXgoKTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy52YWx1ZUhleFZpZXcuc2xpY2UoKS5idWZmZXI7XHJcbiAgICAgICAgfSxcclxuICAgIH0pO1xyXG59KSgpO1xuXG52YXIgX2EkbztcclxuY2xhc3MgSW50ZWdlciBleHRlbmRzIEJhc2VCbG9jayB7XHJcbiAgICBjb25zdHJ1Y3RvcihwYXJhbWV0ZXJzID0ge30pIHtcclxuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzLCBMb2NhbEludGVnZXJWYWx1ZUJsb2NrKTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnQ2xhc3MgPSAxO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdOdW1iZXIgPSAyO1xyXG4gICAgfVxyXG4gICAgdG9CaWdJbnQoKSB7XHJcbiAgICAgICAgYXNzZXJ0QmlnSW50KCk7XHJcbiAgICAgICAgcmV0dXJuIEJpZ0ludCh0aGlzLnZhbHVlQmxvY2sudG9TdHJpbmcoKSk7XHJcbiAgICB9XHJcbiAgICBzdGF0aWMgZnJvbUJpZ0ludCh2YWx1ZSkge1xyXG4gICAgICAgIGFzc2VydEJpZ0ludCgpO1xyXG4gICAgICAgIGNvbnN0IGJpZ0ludFZhbHVlID0gQmlnSW50KHZhbHVlKTtcclxuICAgICAgICBjb25zdCB3cml0ZXIgPSBuZXcgVmlld1dyaXRlcigpO1xyXG4gICAgICAgIGNvbnN0IGhleCA9IGJpZ0ludFZhbHVlLnRvU3RyaW5nKDE2KS5yZXBsYWNlKC9eLS8sIFwiXCIpO1xyXG4gICAgICAgIGNvbnN0IHZpZXcgPSBuZXcgVWludDhBcnJheShwdnRzdXRpbHMuQ29udmVydC5Gcm9tSGV4KGhleCkpO1xyXG4gICAgICAgIGlmIChiaWdJbnRWYWx1ZSA8IDApIHtcclxuICAgICAgICAgICAgY29uc3QgZmlyc3QgPSBuZXcgVWludDhBcnJheSh2aWV3Lmxlbmd0aCArICh2aWV3WzBdICYgMHg4MCA/IDEgOiAwKSk7XHJcbiAgICAgICAgICAgIGZpcnN0WzBdIHw9IDB4ODA7XHJcbiAgICAgICAgICAgIGNvbnN0IGZpcnN0SW50ID0gQmlnSW50KGAweCR7cHZ0c3V0aWxzLkNvbnZlcnQuVG9IZXgoZmlyc3QpfWApO1xyXG4gICAgICAgICAgICBjb25zdCBzZWNvbmRJbnQgPSBmaXJzdEludCArIGJpZ0ludFZhbHVlO1xyXG4gICAgICAgICAgICBjb25zdCBzZWNvbmQgPSBwdnRzdXRpbHMuQnVmZmVyU291cmNlQ29udmVydGVyLnRvVWludDhBcnJheShwdnRzdXRpbHMuQ29udmVydC5Gcm9tSGV4KHNlY29uZEludC50b1N0cmluZygxNikpKTtcclxuICAgICAgICAgICAgc2Vjb25kWzBdIHw9IDB4ODA7XHJcbiAgICAgICAgICAgIHdyaXRlci53cml0ZShzZWNvbmQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgaWYgKHZpZXdbMF0gJiAweDgwKSB7XHJcbiAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUobmV3IFVpbnQ4QXJyYXkoWzBdKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgd3JpdGVyLndyaXRlKHZpZXcpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCByZXMgPSBuZXcgSW50ZWdlcih7XHJcbiAgICAgICAgICAgIHZhbHVlSGV4OiB3cml0ZXIuZmluYWwoKSxcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gcmVzO1xyXG4gICAgfVxyXG4gICAgY29udmVydFRvREVSKCkge1xyXG4gICAgICAgIGNvbnN0IGludGVnZXIgPSBuZXcgSW50ZWdlcih7IHZhbHVlSGV4OiB0aGlzLnZhbHVlQmxvY2sudmFsdWVIZXhWaWV3IH0pO1xyXG4gICAgICAgIGludGVnZXIudmFsdWVCbG9jay50b0RFUigpO1xyXG4gICAgICAgIHJldHVybiBpbnRlZ2VyO1xyXG4gICAgfVxyXG4gICAgY29udmVydEZyb21ERVIoKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBJbnRlZ2VyKHtcclxuICAgICAgICAgICAgdmFsdWVIZXg6IHRoaXMudmFsdWVCbG9jay52YWx1ZUhleFZpZXdbMF0gPT09IDBcclxuICAgICAgICAgICAgICAgID8gdGhpcy52YWx1ZUJsb2NrLnZhbHVlSGV4Vmlldy5zdWJhcnJheSgxKVxyXG4gICAgICAgICAgICAgICAgOiB0aGlzLnZhbHVlQmxvY2sudmFsdWVIZXhWaWV3LFxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgb25Bc2NpaUVuY29kaW5nKCkge1xyXG4gICAgICAgIHJldHVybiBgJHt0aGlzLmNvbnN0cnVjdG9yLk5BTUV9IDogJHt0aGlzLnZhbHVlQmxvY2sudG9TdHJpbmcoKX1gO1xyXG4gICAgfVxyXG59XHJcbl9hJG8gPSBJbnRlZ2VyO1xyXG4oKCkgPT4ge1xyXG4gICAgdHlwZVN0b3JlLkludGVnZXIgPSBfYSRvO1xyXG59KSgpO1xyXG5JbnRlZ2VyLk5BTUUgPSBcIklOVEVHRVJcIjtcblxudmFyIF9hJG47XHJcbmNsYXNzIEVudW1lcmF0ZWQgZXh0ZW5kcyBJbnRlZ2VyIHtcclxuICAgIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMgPSB7fSkge1xyXG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdDbGFzcyA9IDE7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ051bWJlciA9IDEwO1xyXG4gICAgfVxyXG59XHJcbl9hJG4gPSBFbnVtZXJhdGVkO1xyXG4oKCkgPT4ge1xyXG4gICAgdHlwZVN0b3JlLkVudW1lcmF0ZWQgPSBfYSRuO1xyXG59KSgpO1xyXG5FbnVtZXJhdGVkLk5BTUUgPSBcIkVOVU1FUkFURURcIjtcblxuY2xhc3MgTG9jYWxTaWRWYWx1ZUJsb2NrIGV4dGVuZHMgSGV4QmxvY2soVmFsdWVCbG9jaykge1xyXG4gICAgY29uc3RydWN0b3IoeyB2YWx1ZURlYyA9IC0xLCBpc0ZpcnN0U2lkID0gZmFsc2UsIC4uLnBhcmFtZXRlcnMgfSA9IHt9KSB7XHJcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XHJcbiAgICAgICAgdGhpcy52YWx1ZURlYyA9IHZhbHVlRGVjO1xyXG4gICAgICAgIHRoaXMuaXNGaXJzdFNpZCA9IGlzRmlyc3RTaWQ7XHJcbiAgICB9XHJcbiAgICBmcm9tQkVSKGlucHV0QnVmZmVyLCBpbnB1dE9mZnNldCwgaW5wdXRMZW5ndGgpIHtcclxuICAgICAgICBpZiAoIWlucHV0TGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBpbnB1dE9mZnNldDtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgaW5wdXRWaWV3ID0gcHZ0c3V0aWxzLkJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b1VpbnQ4QXJyYXkoaW5wdXRCdWZmZXIpO1xyXG4gICAgICAgIGlmICghY2hlY2tCdWZmZXJQYXJhbXModGhpcywgaW5wdXRWaWV3LCBpbnB1dE9mZnNldCwgaW5wdXRMZW5ndGgpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiAtMTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgaW50QnVmZmVyID0gaW5wdXRWaWV3LnN1YmFycmF5KGlucHV0T2Zmc2V0LCBpbnB1dE9mZnNldCArIGlucHV0TGVuZ3RoKTtcclxuICAgICAgICB0aGlzLnZhbHVlSGV4VmlldyA9IG5ldyBVaW50OEFycmF5KGlucHV0TGVuZ3RoKTtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGlucHV0TGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgdGhpcy52YWx1ZUhleFZpZXdbaV0gPSBpbnRCdWZmZXJbaV0gJiAweDdGO1xyXG4gICAgICAgICAgICB0aGlzLmJsb2NrTGVuZ3RoKys7XHJcbiAgICAgICAgICAgIGlmICgoaW50QnVmZmVyW2ldICYgMHg4MCkgPT09IDB4MDApXHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgdGVtcFZpZXcgPSBuZXcgVWludDhBcnJheSh0aGlzLmJsb2NrTGVuZ3RoKTtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuYmxvY2tMZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICB0ZW1wVmlld1tpXSA9IHRoaXMudmFsdWVIZXhWaWV3W2ldO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnZhbHVlSGV4VmlldyA9IHRlbXBWaWV3O1xyXG4gICAgICAgIGlmICgoaW50QnVmZmVyW3RoaXMuYmxvY2tMZW5ndGggLSAxXSAmIDB4ODApICE9PSAweDAwKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZXJyb3IgPSBcIkVuZCBvZiBpbnB1dCByZWFjaGVkIGJlZm9yZSBtZXNzYWdlIHdhcyBmdWxseSBkZWNvZGVkXCI7XHJcbiAgICAgICAgICAgIHJldHVybiAtMTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHRoaXMudmFsdWVIZXhWaWV3WzBdID09PSAweDAwKVxyXG4gICAgICAgICAgICB0aGlzLndhcm5pbmdzLnB1c2goXCJOZWVkbGVzc2x5IGxvbmcgZm9ybWF0IG9mIFNJRCBlbmNvZGluZ1wiKTtcclxuICAgICAgICBpZiAodGhpcy5ibG9ja0xlbmd0aCA8PSA4KVxyXG4gICAgICAgICAgICB0aGlzLnZhbHVlRGVjID0gcHZ1dGlscy51dGlsRnJvbUJhc2UodGhpcy52YWx1ZUhleFZpZXcsIDcpO1xyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLmlzSGV4T25seSA9IHRydWU7XHJcbiAgICAgICAgICAgIHRoaXMud2FybmluZ3MucHVzaChcIlRvbyBiaWcgU0lEIGZvciBkZWNvZGluZywgaGV4IG9ubHlcIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiAoaW5wdXRPZmZzZXQgKyB0aGlzLmJsb2NrTGVuZ3RoKTtcclxuICAgIH1cclxuICAgIHNldCB2YWx1ZUJpZ0ludCh2YWx1ZSkge1xyXG4gICAgICAgIGFzc2VydEJpZ0ludCgpO1xyXG4gICAgICAgIGxldCBiaXRzID0gQmlnSW50KHZhbHVlKS50b1N0cmluZygyKTtcclxuICAgICAgICB3aGlsZSAoYml0cy5sZW5ndGggJSA3KSB7XHJcbiAgICAgICAgICAgIGJpdHMgPSBcIjBcIiArIGJpdHM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IGJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoYml0cy5sZW5ndGggLyA3KTtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJ5dGVzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGJ5dGVzW2ldID0gcGFyc2VJbnQoYml0cy5zbGljZShpICogNywgaSAqIDcgKyA3KSwgMikgKyAoaSArIDEgPCBieXRlcy5sZW5ndGggPyAweDgwIDogMCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuZnJvbUJFUihieXRlcy5idWZmZXIsIDAsIGJ5dGVzLmxlbmd0aCk7XHJcbiAgICB9XHJcbiAgICB0b0JFUihzaXplT25seSkge1xyXG4gICAgICAgIGlmICh0aGlzLmlzSGV4T25seSkge1xyXG4gICAgICAgICAgICBpZiAoc2l6ZU9ubHkpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gKG5ldyBBcnJheUJ1ZmZlcih0aGlzLnZhbHVlSGV4Vmlldy5ieXRlTGVuZ3RoKSk7XHJcbiAgICAgICAgICAgIGNvbnN0IGN1clZpZXcgPSB0aGlzLnZhbHVlSGV4VmlldztcclxuICAgICAgICAgICAgY29uc3QgcmV0VmlldyA9IG5ldyBVaW50OEFycmF5KHRoaXMuYmxvY2tMZW5ndGgpO1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8ICh0aGlzLmJsb2NrTGVuZ3RoIC0gMSk7IGkrKylcclxuICAgICAgICAgICAgICAgIHJldFZpZXdbaV0gPSBjdXJWaWV3W2ldIHwgMHg4MDtcclxuICAgICAgICAgICAgcmV0Vmlld1t0aGlzLmJsb2NrTGVuZ3RoIC0gMV0gPSBjdXJWaWV3W3RoaXMuYmxvY2tMZW5ndGggLSAxXTtcclxuICAgICAgICAgICAgcmV0dXJuIHJldFZpZXcuYnVmZmVyO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBlbmNvZGVkQnVmID0gcHZ1dGlscy51dGlsVG9CYXNlKHRoaXMudmFsdWVEZWMsIDcpO1xyXG4gICAgICAgIGlmIChlbmNvZGVkQnVmLmJ5dGVMZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgdGhpcy5lcnJvciA9IFwiRXJyb3IgZHVyaW5nIGVuY29kaW5nIFNJRCB2YWx1ZVwiO1xyXG4gICAgICAgICAgICByZXR1cm4gRU1QVFlfQlVGRkVSO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCByZXRWaWV3ID0gbmV3IFVpbnQ4QXJyYXkoZW5jb2RlZEJ1Zi5ieXRlTGVuZ3RoKTtcclxuICAgICAgICBpZiAoIXNpemVPbmx5KSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGVuY29kZWRWaWV3ID0gbmV3IFVpbnQ4QXJyYXkoZW5jb2RlZEJ1Zik7XHJcbiAgICAgICAgICAgIGNvbnN0IGxlbiA9IGVuY29kZWRCdWYuYnl0ZUxlbmd0aCAtIDE7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspXHJcbiAgICAgICAgICAgICAgICByZXRWaWV3W2ldID0gZW5jb2RlZFZpZXdbaV0gfCAweDgwO1xyXG4gICAgICAgICAgICByZXRWaWV3W2xlbl0gPSBlbmNvZGVkVmlld1tsZW5dO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcmV0VmlldztcclxuICAgIH1cclxuICAgIHRvU3RyaW5nKCkge1xyXG4gICAgICAgIGxldCByZXN1bHQgPSBcIlwiO1xyXG4gICAgICAgIGlmICh0aGlzLmlzSGV4T25seSlcclxuICAgICAgICAgICAgcmVzdWx0ID0gcHZ0c3V0aWxzLkNvbnZlcnQuVG9IZXgodGhpcy52YWx1ZUhleFZpZXcpO1xyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5pc0ZpcnN0U2lkKSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgc2lkVmFsdWUgPSB0aGlzLnZhbHVlRGVjO1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMudmFsdWVEZWMgPD0gMzkpXHJcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gXCIwLlwiO1xyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMudmFsdWVEZWMgPD0gNzkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gXCIxLlwiO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzaWRWYWx1ZSAtPSA0MDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IFwiMi5cIjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2lkVmFsdWUgLT0gODA7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmVzdWx0ICs9IHNpZFZhbHVlLnRvU3RyaW5nKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gdGhpcy52YWx1ZURlYy50b1N0cmluZygpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgfVxyXG4gICAgdG9KU09OKCkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIC4uLnN1cGVyLnRvSlNPTigpLFxyXG4gICAgICAgICAgICB2YWx1ZURlYzogdGhpcy52YWx1ZURlYyxcclxuICAgICAgICAgICAgaXNGaXJzdFNpZDogdGhpcy5pc0ZpcnN0U2lkLFxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbn1cclxuTG9jYWxTaWRWYWx1ZUJsb2NrLk5BTUUgPSBcInNpZEJsb2NrXCI7XG5cbmNsYXNzIExvY2FsT2JqZWN0SWRlbnRpZmllclZhbHVlQmxvY2sgZXh0ZW5kcyBWYWx1ZUJsb2NrIHtcclxuICAgIGNvbnN0cnVjdG9yKHsgdmFsdWUgPSBFTVBUWV9TVFJJTkcsIC4uLnBhcmFtZXRlcnMgfSA9IHt9KSB7XHJcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XHJcbiAgICAgICAgdGhpcy52YWx1ZSA9IFtdO1xyXG4gICAgICAgIGlmICh2YWx1ZSkge1xyXG4gICAgICAgICAgICB0aGlzLmZyb21TdHJpbmcodmFsdWUpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGZyb21CRVIoaW5wdXRCdWZmZXIsIGlucHV0T2Zmc2V0LCBpbnB1dExlbmd0aCkge1xyXG4gICAgICAgIGxldCByZXN1bHRPZmZzZXQgPSBpbnB1dE9mZnNldDtcclxuICAgICAgICB3aGlsZSAoaW5wdXRMZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHNpZEJsb2NrID0gbmV3IExvY2FsU2lkVmFsdWVCbG9jaygpO1xyXG4gICAgICAgICAgICByZXN1bHRPZmZzZXQgPSBzaWRCbG9jay5mcm9tQkVSKGlucHV0QnVmZmVyLCByZXN1bHRPZmZzZXQsIGlucHV0TGVuZ3RoKTtcclxuICAgICAgICAgICAgaWYgKHJlc3VsdE9mZnNldCA9PT0gLTEpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuYmxvY2tMZW5ndGggPSAwO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5lcnJvciA9IHNpZEJsb2NrLmVycm9yO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdE9mZnNldDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAodGhpcy52YWx1ZS5sZW5ndGggPT09IDApXHJcbiAgICAgICAgICAgICAgICBzaWRCbG9jay5pc0ZpcnN0U2lkID0gdHJ1ZTtcclxuICAgICAgICAgICAgdGhpcy5ibG9ja0xlbmd0aCArPSBzaWRCbG9jay5ibG9ja0xlbmd0aDtcclxuICAgICAgICAgICAgaW5wdXRMZW5ndGggLT0gc2lkQmxvY2suYmxvY2tMZW5ndGg7XHJcbiAgICAgICAgICAgIHRoaXMudmFsdWUucHVzaChzaWRCbG9jayk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiByZXN1bHRPZmZzZXQ7XHJcbiAgICB9XHJcbiAgICB0b0JFUihzaXplT25seSkge1xyXG4gICAgICAgIGNvbnN0IHJldEJ1ZmZlcnMgPSBbXTtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMudmFsdWUubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgY29uc3QgdmFsdWVCdWYgPSB0aGlzLnZhbHVlW2ldLnRvQkVSKHNpemVPbmx5KTtcclxuICAgICAgICAgICAgaWYgKHZhbHVlQnVmLmJ5dGVMZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZXJyb3IgPSB0aGlzLnZhbHVlW2ldLmVycm9yO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIEVNUFRZX0JVRkZFUjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXRCdWZmZXJzLnB1c2godmFsdWVCdWYpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gY29uY2F0KHJldEJ1ZmZlcnMpO1xyXG4gICAgfVxyXG4gICAgZnJvbVN0cmluZyhzdHJpbmcpIHtcclxuICAgICAgICB0aGlzLnZhbHVlID0gW107XHJcbiAgICAgICAgbGV0IHBvczEgPSAwO1xyXG4gICAgICAgIGxldCBwb3MyID0gMDtcclxuICAgICAgICBsZXQgc2lkID0gXCJcIjtcclxuICAgICAgICBsZXQgZmxhZyA9IGZhbHNlO1xyXG4gICAgICAgIGRvIHtcclxuICAgICAgICAgICAgcG9zMiA9IHN0cmluZy5pbmRleE9mKFwiLlwiLCBwb3MxKTtcclxuICAgICAgICAgICAgaWYgKHBvczIgPT09IC0xKVxyXG4gICAgICAgICAgICAgICAgc2lkID0gc3RyaW5nLnN1YnN0cmluZyhwb3MxKTtcclxuICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgc2lkID0gc3RyaW5nLnN1YnN0cmluZyhwb3MxLCBwb3MyKTtcclxuICAgICAgICAgICAgcG9zMSA9IHBvczIgKyAxO1xyXG4gICAgICAgICAgICBpZiAoZmxhZykge1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgc2lkQmxvY2sgPSB0aGlzLnZhbHVlWzBdO1xyXG4gICAgICAgICAgICAgICAgbGV0IHBsdXMgPSAwO1xyXG4gICAgICAgICAgICAgICAgc3dpdGNoIChzaWRCbG9jay52YWx1ZURlYykge1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAxOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwbHVzID0gNDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMjpcclxuICAgICAgICAgICAgICAgICAgICAgICAgcGx1cyA9IDgwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZhbHVlID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGNvbnN0IHBhcnNlZFNJRCA9IHBhcnNlSW50KHNpZCwgMTApO1xyXG4gICAgICAgICAgICAgICAgaWYgKGlzTmFOKHBhcnNlZFNJRCkpXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgc2lkQmxvY2sudmFsdWVEZWMgPSBwYXJzZWRTSUQgKyBwbHVzO1xyXG4gICAgICAgICAgICAgICAgZmxhZyA9IGZhbHNlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgc2lkQmxvY2sgPSBuZXcgTG9jYWxTaWRWYWx1ZUJsb2NrKCk7XHJcbiAgICAgICAgICAgICAgICBpZiAoc2lkID4gTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIpIHtcclxuICAgICAgICAgICAgICAgICAgICBhc3NlcnRCaWdJbnQoKTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaWRWYWx1ZSA9IEJpZ0ludChzaWQpO1xyXG4gICAgICAgICAgICAgICAgICAgIHNpZEJsb2NrLnZhbHVlQmlnSW50ID0gc2lkVmFsdWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBzaWRCbG9jay52YWx1ZURlYyA9IHBhcnNlSW50KHNpZCwgMTApO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpc05hTihzaWRCbG9jay52YWx1ZURlYykpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmICghdGhpcy52YWx1ZS5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgICAgICBzaWRCbG9jay5pc0ZpcnN0U2lkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICBmbGFnID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHRoaXMudmFsdWUucHVzaChzaWRCbG9jayk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IHdoaWxlIChwb3MyICE9PSAtMSk7XHJcbiAgICB9XHJcbiAgICB0b1N0cmluZygpIHtcclxuICAgICAgICBsZXQgcmVzdWx0ID0gXCJcIjtcclxuICAgICAgICBsZXQgaXNIZXhPbmx5ID0gZmFsc2U7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnZhbHVlLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlzSGV4T25seSA9IHRoaXMudmFsdWVbaV0uaXNIZXhPbmx5O1xyXG4gICAgICAgICAgICBsZXQgc2lkU3RyID0gdGhpcy52YWx1ZVtpXS50b1N0cmluZygpO1xyXG4gICAgICAgICAgICBpZiAoaSAhPT0gMClcclxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGAke3Jlc3VsdH0uYDtcclxuICAgICAgICAgICAgaWYgKGlzSGV4T25seSkge1xyXG4gICAgICAgICAgICAgICAgc2lkU3RyID0gYHske3NpZFN0cn19YDtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnZhbHVlW2ldLmlzRmlyc3RTaWQpXHJcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gYDIueyR7c2lkU3RyfSAtIDgwfWA7XHJcbiAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ICs9IHNpZFN0cjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICByZXN1bHQgKz0gc2lkU3RyO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgfVxyXG4gICAgdG9KU09OKCkge1xyXG4gICAgICAgIGNvbnN0IG9iamVjdCA9IHtcclxuICAgICAgICAgICAgLi4uc3VwZXIudG9KU09OKCksXHJcbiAgICAgICAgICAgIHZhbHVlOiB0aGlzLnRvU3RyaW5nKCksXHJcbiAgICAgICAgICAgIHNpZEFycmF5OiBbXSxcclxuICAgICAgICB9O1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy52YWx1ZS5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBvYmplY3Quc2lkQXJyYXkucHVzaCh0aGlzLnZhbHVlW2ldLnRvSlNPTigpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIG9iamVjdDtcclxuICAgIH1cclxufVxyXG5Mb2NhbE9iamVjdElkZW50aWZpZXJWYWx1ZUJsb2NrLk5BTUUgPSBcIk9iamVjdElkZW50aWZpZXJWYWx1ZUJsb2NrXCI7XG5cbnZhciBfYSRtO1xyXG5jbGFzcyBPYmplY3RJZGVudGlmaWVyIGV4dGVuZHMgQmFzZUJsb2NrIHtcclxuICAgIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMgPSB7fSkge1xyXG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMsIExvY2FsT2JqZWN0SWRlbnRpZmllclZhbHVlQmxvY2spO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdDbGFzcyA9IDE7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ051bWJlciA9IDY7XHJcbiAgICB9XHJcbiAgICBnZXRWYWx1ZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZUJsb2NrLnRvU3RyaW5nKCk7XHJcbiAgICB9XHJcbiAgICBzZXRWYWx1ZSh2YWx1ZSkge1xyXG4gICAgICAgIHRoaXMudmFsdWVCbG9jay5mcm9tU3RyaW5nKHZhbHVlKTtcclxuICAgIH1cclxuICAgIG9uQXNjaWlFbmNvZGluZygpIHtcclxuICAgICAgICByZXR1cm4gYCR7dGhpcy5jb25zdHJ1Y3Rvci5OQU1FfSA6ICR7dGhpcy52YWx1ZUJsb2NrLnRvU3RyaW5nKCkgfHwgXCJlbXB0eVwifWA7XHJcbiAgICB9XHJcbiAgICB0b0pTT04oKSB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgLi4uc3VwZXIudG9KU09OKCksXHJcbiAgICAgICAgICAgIHZhbHVlOiB0aGlzLmdldFZhbHVlKCksXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxufVxyXG5fYSRtID0gT2JqZWN0SWRlbnRpZmllcjtcclxuKCgpID0+IHtcclxuICAgIHR5cGVTdG9yZS5PYmplY3RJZGVudGlmaWVyID0gX2EkbTtcclxufSkoKTtcclxuT2JqZWN0SWRlbnRpZmllci5OQU1FID0gXCJPQkpFQ1QgSURFTlRJRklFUlwiO1xuXG5jbGFzcyBMb2NhbFJlbGF0aXZlU2lkVmFsdWVCbG9jayBleHRlbmRzIEhleEJsb2NrKExvY2FsQmFzZUJsb2NrKSB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7IHZhbHVlRGVjID0gMCwgLi4ucGFyYW1ldGVycyB9ID0ge30pIHtcclxuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcclxuICAgICAgICB0aGlzLnZhbHVlRGVjID0gdmFsdWVEZWM7XHJcbiAgICB9XHJcbiAgICBmcm9tQkVSKGlucHV0QnVmZmVyLCBpbnB1dE9mZnNldCwgaW5wdXRMZW5ndGgpIHtcclxuICAgICAgICBpZiAoaW5wdXRMZW5ndGggPT09IDApXHJcbiAgICAgICAgICAgIHJldHVybiBpbnB1dE9mZnNldDtcclxuICAgICAgICBjb25zdCBpbnB1dFZpZXcgPSBwdnRzdXRpbHMuQnVmZmVyU291cmNlQ29udmVydGVyLnRvVWludDhBcnJheShpbnB1dEJ1ZmZlcik7XHJcbiAgICAgICAgaWYgKCFjaGVja0J1ZmZlclBhcmFtcyh0aGlzLCBpbnB1dFZpZXcsIGlucHV0T2Zmc2V0LCBpbnB1dExlbmd0aCkpXHJcbiAgICAgICAgICAgIHJldHVybiAtMTtcclxuICAgICAgICBjb25zdCBpbnRCdWZmZXIgPSBpbnB1dFZpZXcuc3ViYXJyYXkoaW5wdXRPZmZzZXQsIGlucHV0T2Zmc2V0ICsgaW5wdXRMZW5ndGgpO1xyXG4gICAgICAgIHRoaXMudmFsdWVIZXhWaWV3ID0gbmV3IFVpbnQ4QXJyYXkoaW5wdXRMZW5ndGgpO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXRMZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICB0aGlzLnZhbHVlSGV4Vmlld1tpXSA9IGludEJ1ZmZlcltpXSAmIDB4N0Y7XHJcbiAgICAgICAgICAgIHRoaXMuYmxvY2tMZW5ndGgrKztcclxuICAgICAgICAgICAgaWYgKChpbnRCdWZmZXJbaV0gJiAweDgwKSA9PT0gMHgwMClcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCB0ZW1wVmlldyA9IG5ldyBVaW50OEFycmF5KHRoaXMuYmxvY2tMZW5ndGgpO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5ibG9ja0xlbmd0aDsgaSsrKVxyXG4gICAgICAgICAgICB0ZW1wVmlld1tpXSA9IHRoaXMudmFsdWVIZXhWaWV3W2ldO1xyXG4gICAgICAgIHRoaXMudmFsdWVIZXhWaWV3ID0gdGVtcFZpZXc7XHJcbiAgICAgICAgaWYgKChpbnRCdWZmZXJbdGhpcy5ibG9ja0xlbmd0aCAtIDFdICYgMHg4MCkgIT09IDB4MDApIHtcclxuICAgICAgICAgICAgdGhpcy5lcnJvciA9IFwiRW5kIG9mIGlucHV0IHJlYWNoZWQgYmVmb3JlIG1lc3NhZ2Ugd2FzIGZ1bGx5IGRlY29kZWRcIjtcclxuICAgICAgICAgICAgcmV0dXJuIC0xO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy52YWx1ZUhleFZpZXdbMF0gPT09IDB4MDApXHJcbiAgICAgICAgICAgIHRoaXMud2FybmluZ3MucHVzaChcIk5lZWRsZXNzbHkgbG9uZyBmb3JtYXQgb2YgU0lEIGVuY29kaW5nXCIpO1xyXG4gICAgICAgIGlmICh0aGlzLmJsb2NrTGVuZ3RoIDw9IDgpXHJcbiAgICAgICAgICAgIHRoaXMudmFsdWVEZWMgPSBwdnV0aWxzLnV0aWxGcm9tQmFzZSh0aGlzLnZhbHVlSGV4VmlldywgNyk7XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuaXNIZXhPbmx5ID0gdHJ1ZTtcclxuICAgICAgICAgICAgdGhpcy53YXJuaW5ncy5wdXNoKFwiVG9vIGJpZyBTSUQgZm9yIGRlY29kaW5nLCBoZXggb25seVwiKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIChpbnB1dE9mZnNldCArIHRoaXMuYmxvY2tMZW5ndGgpO1xyXG4gICAgfVxyXG4gICAgdG9CRVIoc2l6ZU9ubHkpIHtcclxuICAgICAgICBpZiAodGhpcy5pc0hleE9ubHkpIHtcclxuICAgICAgICAgICAgaWYgKHNpemVPbmx5KVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIChuZXcgQXJyYXlCdWZmZXIodGhpcy52YWx1ZUhleFZpZXcuYnl0ZUxlbmd0aCkpO1xyXG4gICAgICAgICAgICBjb25zdCBjdXJWaWV3ID0gdGhpcy52YWx1ZUhleFZpZXc7XHJcbiAgICAgICAgICAgIGNvbnN0IHJldFZpZXcgPSBuZXcgVWludDhBcnJheSh0aGlzLmJsb2NrTGVuZ3RoKTtcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCAodGhpcy5ibG9ja0xlbmd0aCAtIDEpOyBpKyspXHJcbiAgICAgICAgICAgICAgICByZXRWaWV3W2ldID0gY3VyVmlld1tpXSB8IDB4ODA7XHJcbiAgICAgICAgICAgIHJldFZpZXdbdGhpcy5ibG9ja0xlbmd0aCAtIDFdID0gY3VyVmlld1t0aGlzLmJsb2NrTGVuZ3RoIC0gMV07XHJcbiAgICAgICAgICAgIHJldHVybiByZXRWaWV3LmJ1ZmZlcjtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgZW5jb2RlZEJ1ZiA9IHB2dXRpbHMudXRpbFRvQmFzZSh0aGlzLnZhbHVlRGVjLCA3KTtcclxuICAgICAgICBpZiAoZW5jb2RlZEJ1Zi5ieXRlTGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZXJyb3IgPSBcIkVycm9yIGR1cmluZyBlbmNvZGluZyBTSUQgdmFsdWVcIjtcclxuICAgICAgICAgICAgcmV0dXJuIEVNUFRZX0JVRkZFUjtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgcmV0VmlldyA9IG5ldyBVaW50OEFycmF5KGVuY29kZWRCdWYuYnl0ZUxlbmd0aCk7XHJcbiAgICAgICAgaWYgKCFzaXplT25seSkge1xyXG4gICAgICAgICAgICBjb25zdCBlbmNvZGVkVmlldyA9IG5ldyBVaW50OEFycmF5KGVuY29kZWRCdWYpO1xyXG4gICAgICAgICAgICBjb25zdCBsZW4gPSBlbmNvZGVkQnVmLmJ5dGVMZW5ndGggLSAxO1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbjsgaSsrKVxyXG4gICAgICAgICAgICAgICAgcmV0Vmlld1tpXSA9IGVuY29kZWRWaWV3W2ldIHwgMHg4MDtcclxuICAgICAgICAgICAgcmV0Vmlld1tsZW5dID0gZW5jb2RlZFZpZXdbbGVuXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJldFZpZXcuYnVmZmVyO1xyXG4gICAgfVxyXG4gICAgdG9TdHJpbmcoKSB7XHJcbiAgICAgICAgbGV0IHJlc3VsdCA9IFwiXCI7XHJcbiAgICAgICAgaWYgKHRoaXMuaXNIZXhPbmx5KVxyXG4gICAgICAgICAgICByZXN1bHQgPSBwdnRzdXRpbHMuQ29udmVydC5Ub0hleCh0aGlzLnZhbHVlSGV4Vmlldyk7XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHJlc3VsdCA9IHRoaXMudmFsdWVEZWMudG9TdHJpbmcoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH1cclxuICAgIHRvSlNPTigpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAuLi5zdXBlci50b0pTT04oKSxcclxuICAgICAgICAgICAgdmFsdWVEZWM6IHRoaXMudmFsdWVEZWMsXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxufVxyXG5Mb2NhbFJlbGF0aXZlU2lkVmFsdWVCbG9jay5OQU1FID0gXCJyZWxhdGl2ZVNpZEJsb2NrXCI7XG5cbmNsYXNzIExvY2FsUmVsYXRpdmVPYmplY3RJZGVudGlmaWVyVmFsdWVCbG9jayBleHRlbmRzIFZhbHVlQmxvY2sge1xyXG4gICAgY29uc3RydWN0b3IoeyB2YWx1ZSA9IEVNUFRZX1NUUklORywgLi4ucGFyYW1ldGVycyB9ID0ge30pIHtcclxuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcclxuICAgICAgICB0aGlzLnZhbHVlID0gW107XHJcbiAgICAgICAgaWYgKHZhbHVlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZnJvbVN0cmluZyh2YWx1ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZnJvbUJFUihpbnB1dEJ1ZmZlciwgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoKSB7XHJcbiAgICAgICAgbGV0IHJlc3VsdE9mZnNldCA9IGlucHV0T2Zmc2V0O1xyXG4gICAgICAgIHdoaWxlIChpbnB1dExlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgY29uc3Qgc2lkQmxvY2sgPSBuZXcgTG9jYWxSZWxhdGl2ZVNpZFZhbHVlQmxvY2soKTtcclxuICAgICAgICAgICAgcmVzdWx0T2Zmc2V0ID0gc2lkQmxvY2suZnJvbUJFUihpbnB1dEJ1ZmZlciwgcmVzdWx0T2Zmc2V0LCBpbnB1dExlbmd0aCk7XHJcbiAgICAgICAgICAgIGlmIChyZXN1bHRPZmZzZXQgPT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmJsb2NrTGVuZ3RoID0gMDtcclxuICAgICAgICAgICAgICAgIHRoaXMuZXJyb3IgPSBzaWRCbG9jay5lcnJvcjtcclxuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHRPZmZzZXQ7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5ibG9ja0xlbmd0aCArPSBzaWRCbG9jay5ibG9ja0xlbmd0aDtcclxuICAgICAgICAgICAgaW5wdXRMZW5ndGggLT0gc2lkQmxvY2suYmxvY2tMZW5ndGg7XHJcbiAgICAgICAgICAgIHRoaXMudmFsdWUucHVzaChzaWRCbG9jayk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiByZXN1bHRPZmZzZXQ7XHJcbiAgICB9XHJcbiAgICB0b0JFUihzaXplT25seSwgd3JpdGVyKSB7XHJcbiAgICAgICAgY29uc3QgcmV0QnVmZmVycyA9IFtdO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy52YWx1ZS5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBjb25zdCB2YWx1ZUJ1ZiA9IHRoaXMudmFsdWVbaV0udG9CRVIoc2l6ZU9ubHkpO1xyXG4gICAgICAgICAgICBpZiAodmFsdWVCdWYuYnl0ZUxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5lcnJvciA9IHRoaXMudmFsdWVbaV0uZXJyb3I7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gRU1QVFlfQlVGRkVSO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldEJ1ZmZlcnMucHVzaCh2YWx1ZUJ1Zik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBjb25jYXQocmV0QnVmZmVycyk7XHJcbiAgICB9XHJcbiAgICBmcm9tU3RyaW5nKHN0cmluZykge1xyXG4gICAgICAgIHRoaXMudmFsdWUgPSBbXTtcclxuICAgICAgICBsZXQgcG9zMSA9IDA7XHJcbiAgICAgICAgbGV0IHBvczIgPSAwO1xyXG4gICAgICAgIGxldCBzaWQgPSBcIlwiO1xyXG4gICAgICAgIGRvIHtcclxuICAgICAgICAgICAgcG9zMiA9IHN0cmluZy5pbmRleE9mKFwiLlwiLCBwb3MxKTtcclxuICAgICAgICAgICAgaWYgKHBvczIgPT09IC0xKVxyXG4gICAgICAgICAgICAgICAgc2lkID0gc3RyaW5nLnN1YnN0cmluZyhwb3MxKTtcclxuICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgc2lkID0gc3RyaW5nLnN1YnN0cmluZyhwb3MxLCBwb3MyKTtcclxuICAgICAgICAgICAgcG9zMSA9IHBvczIgKyAxO1xyXG4gICAgICAgICAgICBjb25zdCBzaWRCbG9jayA9IG5ldyBMb2NhbFJlbGF0aXZlU2lkVmFsdWVCbG9jaygpO1xyXG4gICAgICAgICAgICBzaWRCbG9jay52YWx1ZURlYyA9IHBhcnNlSW50KHNpZCwgMTApO1xyXG4gICAgICAgICAgICBpZiAoaXNOYU4oc2lkQmxvY2sudmFsdWVEZWMpKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgIHRoaXMudmFsdWUucHVzaChzaWRCbG9jayk7XHJcbiAgICAgICAgfSB3aGlsZSAocG9zMiAhPT0gLTEpO1xyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG4gICAgdG9TdHJpbmcoKSB7XHJcbiAgICAgICAgbGV0IHJlc3VsdCA9IFwiXCI7XHJcbiAgICAgICAgbGV0IGlzSGV4T25seSA9IGZhbHNlO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy52YWx1ZS5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBpc0hleE9ubHkgPSB0aGlzLnZhbHVlW2ldLmlzSGV4T25seTtcclxuICAgICAgICAgICAgbGV0IHNpZFN0ciA9IHRoaXMudmFsdWVbaV0udG9TdHJpbmcoKTtcclxuICAgICAgICAgICAgaWYgKGkgIT09IDApXHJcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBgJHtyZXN1bHR9LmA7XHJcbiAgICAgICAgICAgIGlmIChpc0hleE9ubHkpIHtcclxuICAgICAgICAgICAgICAgIHNpZFN0ciA9IGB7JHtzaWRTdHJ9fWA7XHJcbiAgICAgICAgICAgICAgICByZXN1bHQgKz0gc2lkU3RyO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgIHJlc3VsdCArPSBzaWRTdHI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICB9XHJcbiAgICB0b0pTT04oKSB7XHJcbiAgICAgICAgY29uc3Qgb2JqZWN0ID0ge1xyXG4gICAgICAgICAgICAuLi5zdXBlci50b0pTT04oKSxcclxuICAgICAgICAgICAgdmFsdWU6IHRoaXMudG9TdHJpbmcoKSxcclxuICAgICAgICAgICAgc2lkQXJyYXk6IFtdLFxyXG4gICAgICAgIH07XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnZhbHVlLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgICAgICBvYmplY3Quc2lkQXJyYXkucHVzaCh0aGlzLnZhbHVlW2ldLnRvSlNPTigpKTtcclxuICAgICAgICByZXR1cm4gb2JqZWN0O1xyXG4gICAgfVxyXG59XHJcbkxvY2FsUmVsYXRpdmVPYmplY3RJZGVudGlmaWVyVmFsdWVCbG9jay5OQU1FID0gXCJSZWxhdGl2ZU9iamVjdElkZW50aWZpZXJWYWx1ZUJsb2NrXCI7XG5cbnZhciBfYSRsO1xyXG5jbGFzcyBSZWxhdGl2ZU9iamVjdElkZW50aWZpZXIgZXh0ZW5kcyBCYXNlQmxvY2sge1xyXG4gICAgY29uc3RydWN0b3IocGFyYW1ldGVycyA9IHt9KSB7XHJcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycywgTG9jYWxSZWxhdGl2ZU9iamVjdElkZW50aWZpZXJWYWx1ZUJsb2NrKTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnQ2xhc3MgPSAxO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdOdW1iZXIgPSAxMztcclxuICAgIH1cclxuICAgIGdldFZhbHVlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlQmxvY2sudG9TdHJpbmcoKTtcclxuICAgIH1cclxuICAgIHNldFZhbHVlKHZhbHVlKSB7XHJcbiAgICAgICAgdGhpcy52YWx1ZUJsb2NrLmZyb21TdHJpbmcodmFsdWUpO1xyXG4gICAgfVxyXG4gICAgb25Bc2NpaUVuY29kaW5nKCkge1xyXG4gICAgICAgIHJldHVybiBgJHt0aGlzLmNvbnN0cnVjdG9yLk5BTUV9IDogJHt0aGlzLnZhbHVlQmxvY2sudG9TdHJpbmcoKSB8fCBcImVtcHR5XCJ9YDtcclxuICAgIH1cclxuICAgIHRvSlNPTigpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAuLi5zdXBlci50b0pTT04oKSxcclxuICAgICAgICAgICAgdmFsdWU6IHRoaXMuZ2V0VmFsdWUoKSxcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG59XHJcbl9hJGwgPSBSZWxhdGl2ZU9iamVjdElkZW50aWZpZXI7XHJcbigoKSA9PiB7XHJcbiAgICB0eXBlU3RvcmUuUmVsYXRpdmVPYmplY3RJZGVudGlmaWVyID0gX2EkbDtcclxufSkoKTtcclxuUmVsYXRpdmVPYmplY3RJZGVudGlmaWVyLk5BTUUgPSBcIlJlbGF0aXZlT2JqZWN0SWRlbnRpZmllclwiO1xuXG52YXIgX2EkaztcclxuY2xhc3MgU2VxdWVuY2UgZXh0ZW5kcyBDb25zdHJ1Y3RlZCB7XHJcbiAgICBjb25zdHJ1Y3RvcihwYXJhbWV0ZXJzID0ge30pIHtcclxuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnQ2xhc3MgPSAxO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdOdW1iZXIgPSAxNjtcclxuICAgIH1cclxufVxyXG5fYSRrID0gU2VxdWVuY2U7XHJcbigoKSA9PiB7XHJcbiAgICB0eXBlU3RvcmUuU2VxdWVuY2UgPSBfYSRrO1xyXG59KSgpO1xyXG5TZXF1ZW5jZS5OQU1FID0gXCJTRVFVRU5DRVwiO1xuXG52YXIgX2EkajtcclxuY2xhc3MgU2V0IGV4dGVuZHMgQ29uc3RydWN0ZWQge1xyXG4gICAgY29uc3RydWN0b3IocGFyYW1ldGVycyA9IHt9KSB7XHJcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ0NsYXNzID0gMTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnTnVtYmVyID0gMTc7XHJcbiAgICB9XHJcbn1cclxuX2EkaiA9IFNldDtcclxuKCgpID0+IHtcclxuICAgIHR5cGVTdG9yZS5TZXQgPSBfYSRqO1xyXG59KSgpO1xyXG5TZXQuTkFNRSA9IFwiU0VUXCI7XG5cbmNsYXNzIExvY2FsU3RyaW5nVmFsdWVCbG9jayBleHRlbmRzIEhleEJsb2NrKFZhbHVlQmxvY2spIHtcclxuICAgIGNvbnN0cnVjdG9yKHsgLi4ucGFyYW1ldGVycyB9ID0ge30pIHtcclxuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcclxuICAgICAgICB0aGlzLmlzSGV4T25seSA9IHRydWU7XHJcbiAgICAgICAgdGhpcy52YWx1ZSA9IEVNUFRZX1NUUklORztcclxuICAgIH1cclxuICAgIHRvSlNPTigpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAuLi5zdXBlci50b0pTT04oKSxcclxuICAgICAgICAgICAgdmFsdWU6IHRoaXMudmFsdWUsXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxufVxyXG5Mb2NhbFN0cmluZ1ZhbHVlQmxvY2suTkFNRSA9IFwiU3RyaW5nVmFsdWVCbG9ja1wiO1xuXG5jbGFzcyBMb2NhbFNpbXBsZVN0cmluZ1ZhbHVlQmxvY2sgZXh0ZW5kcyBMb2NhbFN0cmluZ1ZhbHVlQmxvY2sge1xyXG59XHJcbkxvY2FsU2ltcGxlU3RyaW5nVmFsdWVCbG9jay5OQU1FID0gXCJTaW1wbGVTdHJpbmdWYWx1ZUJsb2NrXCI7XG5cbmNsYXNzIExvY2FsU2ltcGxlU3RyaW5nQmxvY2sgZXh0ZW5kcyBCYXNlU3RyaW5nQmxvY2sge1xyXG4gICAgY29uc3RydWN0b3IoeyAuLi5wYXJhbWV0ZXJzIH0gPSB7fSkge1xyXG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMsIExvY2FsU2ltcGxlU3RyaW5nVmFsdWVCbG9jayk7XHJcbiAgICB9XHJcbiAgICBmcm9tQnVmZmVyKGlucHV0QnVmZmVyKSB7XHJcbiAgICAgICAgdGhpcy52YWx1ZUJsb2NrLnZhbHVlID0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBwdnRzdXRpbHMuQnVmZmVyU291cmNlQ29udmVydGVyLnRvVWludDhBcnJheShpbnB1dEJ1ZmZlcikpO1xyXG4gICAgfVxyXG4gICAgZnJvbVN0cmluZyhpbnB1dFN0cmluZykge1xyXG4gICAgICAgIGNvbnN0IHN0ckxlbiA9IGlucHV0U3RyaW5nLmxlbmd0aDtcclxuICAgICAgICBjb25zdCB2aWV3ID0gdGhpcy52YWx1ZUJsb2NrLnZhbHVlSGV4VmlldyA9IG5ldyBVaW50OEFycmF5KHN0ckxlbik7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzdHJMZW47IGkrKylcclxuICAgICAgICAgICAgdmlld1tpXSA9IGlucHV0U3RyaW5nLmNoYXJDb2RlQXQoaSk7XHJcbiAgICAgICAgdGhpcy52YWx1ZUJsb2NrLnZhbHVlID0gaW5wdXRTdHJpbmc7XHJcbiAgICB9XHJcbn1cclxuTG9jYWxTaW1wbGVTdHJpbmdCbG9jay5OQU1FID0gXCJTSU1QTEUgU1RSSU5HXCI7XG5cbmNsYXNzIExvY2FsVXRmOFN0cmluZ1ZhbHVlQmxvY2sgZXh0ZW5kcyBMb2NhbFNpbXBsZVN0cmluZ0Jsb2NrIHtcclxuICAgIGZyb21CdWZmZXIoaW5wdXRCdWZmZXIpIHtcclxuICAgICAgICB0aGlzLnZhbHVlQmxvY2sudmFsdWVIZXhWaWV3ID0gcHZ0c3V0aWxzLkJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b1VpbnQ4QXJyYXkoaW5wdXRCdWZmZXIpO1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIHRoaXMudmFsdWVCbG9jay52YWx1ZSA9IHB2dHN1dGlscy5Db252ZXJ0LlRvVXRmOFN0cmluZyhpbnB1dEJ1ZmZlcik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhdGNoIChleCkge1xyXG4gICAgICAgICAgICB0aGlzLndhcm5pbmdzLnB1c2goYEVycm9yIGR1cmluZyBcImRlY29kZVVSSUNvbXBvbmVudFwiOiAke2V4fSwgdXNpbmcgcmF3IHN0cmluZ2ApO1xyXG4gICAgICAgICAgICB0aGlzLnZhbHVlQmxvY2sudmFsdWUgPSBwdnRzdXRpbHMuQ29udmVydC5Ub0JpbmFyeShpbnB1dEJ1ZmZlcik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZnJvbVN0cmluZyhpbnB1dFN0cmluZykge1xyXG4gICAgICAgIHRoaXMudmFsdWVCbG9jay52YWx1ZUhleFZpZXcgPSBuZXcgVWludDhBcnJheShwdnRzdXRpbHMuQ29udmVydC5Gcm9tVXRmOFN0cmluZyhpbnB1dFN0cmluZykpO1xyXG4gICAgICAgIHRoaXMudmFsdWVCbG9jay52YWx1ZSA9IGlucHV0U3RyaW5nO1xyXG4gICAgfVxyXG59XHJcbkxvY2FsVXRmOFN0cmluZ1ZhbHVlQmxvY2suTkFNRSA9IFwiVXRmOFN0cmluZ1ZhbHVlQmxvY2tcIjtcblxudmFyIF9hJGk7XHJcbmNsYXNzIFV0ZjhTdHJpbmcgZXh0ZW5kcyBMb2NhbFV0ZjhTdHJpbmdWYWx1ZUJsb2NrIHtcclxuICAgIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMgPSB7fSkge1xyXG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdDbGFzcyA9IDE7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ051bWJlciA9IDEyO1xyXG4gICAgfVxyXG59XHJcbl9hJGkgPSBVdGY4U3RyaW5nO1xyXG4oKCkgPT4ge1xyXG4gICAgdHlwZVN0b3JlLlV0ZjhTdHJpbmcgPSBfYSRpO1xyXG59KSgpO1xyXG5VdGY4U3RyaW5nLk5BTUUgPSBcIlVURjhTdHJpbmdcIjtcblxuY2xhc3MgTG9jYWxCbXBTdHJpbmdWYWx1ZUJsb2NrIGV4dGVuZHMgTG9jYWxTaW1wbGVTdHJpbmdCbG9jayB7XHJcbiAgICBmcm9tQnVmZmVyKGlucHV0QnVmZmVyKSB7XHJcbiAgICAgICAgdGhpcy52YWx1ZUJsb2NrLnZhbHVlID0gcHZ0c3V0aWxzLkNvbnZlcnQuVG9VdGYxNlN0cmluZyhpbnB1dEJ1ZmZlcik7XHJcbiAgICAgICAgdGhpcy52YWx1ZUJsb2NrLnZhbHVlSGV4VmlldyA9IHB2dHN1dGlscy5CdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9VaW50OEFycmF5KGlucHV0QnVmZmVyKTtcclxuICAgIH1cclxuICAgIGZyb21TdHJpbmcoaW5wdXRTdHJpbmcpIHtcclxuICAgICAgICB0aGlzLnZhbHVlQmxvY2sudmFsdWUgPSBpbnB1dFN0cmluZztcclxuICAgICAgICB0aGlzLnZhbHVlQmxvY2sudmFsdWVIZXhWaWV3ID0gbmV3IFVpbnQ4QXJyYXkocHZ0c3V0aWxzLkNvbnZlcnQuRnJvbVV0ZjE2U3RyaW5nKGlucHV0U3RyaW5nKSk7XHJcbiAgICB9XHJcbn1cclxuTG9jYWxCbXBTdHJpbmdWYWx1ZUJsb2NrLk5BTUUgPSBcIkJtcFN0cmluZ1ZhbHVlQmxvY2tcIjtcblxudmFyIF9hJGg7XHJcbmNsYXNzIEJtcFN0cmluZyBleHRlbmRzIExvY2FsQm1wU3RyaW5nVmFsdWVCbG9jayB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7IC4uLnBhcmFtZXRlcnMgfSA9IHt9KSB7XHJcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ0NsYXNzID0gMTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnTnVtYmVyID0gMzA7XHJcbiAgICB9XHJcbn1cclxuX2EkaCA9IEJtcFN0cmluZztcclxuKCgpID0+IHtcclxuICAgIHR5cGVTdG9yZS5CbXBTdHJpbmcgPSBfYSRoO1xyXG59KSgpO1xyXG5CbXBTdHJpbmcuTkFNRSA9IFwiQk1QU3RyaW5nXCI7XG5cbmNsYXNzIExvY2FsVW5pdmVyc2FsU3RyaW5nVmFsdWVCbG9jayBleHRlbmRzIExvY2FsU2ltcGxlU3RyaW5nQmxvY2sge1xyXG4gICAgZnJvbUJ1ZmZlcihpbnB1dEJ1ZmZlcikge1xyXG4gICAgICAgIGNvbnN0IGNvcHlCdWZmZXIgPSBBcnJheUJ1ZmZlci5pc1ZpZXcoaW5wdXRCdWZmZXIpID8gaW5wdXRCdWZmZXIuc2xpY2UoKS5idWZmZXIgOiBpbnB1dEJ1ZmZlci5zbGljZSgwKTtcclxuICAgICAgICBjb25zdCB2YWx1ZVZpZXcgPSBuZXcgVWludDhBcnJheShjb3B5QnVmZmVyKTtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHZhbHVlVmlldy5sZW5ndGg7IGkgKz0gNCkge1xyXG4gICAgICAgICAgICB2YWx1ZVZpZXdbaV0gPSB2YWx1ZVZpZXdbaSArIDNdO1xyXG4gICAgICAgICAgICB2YWx1ZVZpZXdbaSArIDFdID0gdmFsdWVWaWV3W2kgKyAyXTtcclxuICAgICAgICAgICAgdmFsdWVWaWV3W2kgKyAyXSA9IDB4MDA7XHJcbiAgICAgICAgICAgIHZhbHVlVmlld1tpICsgM10gPSAweDAwO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnZhbHVlQmxvY2sudmFsdWUgPSBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIG5ldyBVaW50MzJBcnJheShjb3B5QnVmZmVyKSk7XHJcbiAgICB9XHJcbiAgICBmcm9tU3RyaW5nKGlucHV0U3RyaW5nKSB7XHJcbiAgICAgICAgY29uc3Qgc3RyTGVuZ3RoID0gaW5wdXRTdHJpbmcubGVuZ3RoO1xyXG4gICAgICAgIGNvbnN0IHZhbHVlSGV4VmlldyA9IHRoaXMudmFsdWVCbG9jay52YWx1ZUhleFZpZXcgPSBuZXcgVWludDhBcnJheShzdHJMZW5ndGggKiA0KTtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHN0ckxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGNvZGVCdWYgPSBwdnV0aWxzLnV0aWxUb0Jhc2UoaW5wdXRTdHJpbmcuY2hhckNvZGVBdChpKSwgOCk7XHJcbiAgICAgICAgICAgIGNvbnN0IGNvZGVWaWV3ID0gbmV3IFVpbnQ4QXJyYXkoY29kZUJ1Zik7XHJcbiAgICAgICAgICAgIGlmIChjb2RlVmlldy5sZW5ndGggPiA0KVxyXG4gICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgIGNvbnN0IGRpZiA9IDQgLSBjb2RlVmlldy5sZW5ndGg7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGogPSAoY29kZVZpZXcubGVuZ3RoIC0gMSk7IGogPj0gMDsgai0tKVxyXG4gICAgICAgICAgICAgICAgdmFsdWVIZXhWaWV3W2kgKiA0ICsgaiArIGRpZl0gPSBjb2RlVmlld1tqXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy52YWx1ZUJsb2NrLnZhbHVlID0gaW5wdXRTdHJpbmc7XHJcbiAgICB9XHJcbn1cclxuTG9jYWxVbml2ZXJzYWxTdHJpbmdWYWx1ZUJsb2NrLk5BTUUgPSBcIlVuaXZlcnNhbFN0cmluZ1ZhbHVlQmxvY2tcIjtcblxudmFyIF9hJGc7XHJcbmNsYXNzIFVuaXZlcnNhbFN0cmluZyBleHRlbmRzIExvY2FsVW5pdmVyc2FsU3RyaW5nVmFsdWVCbG9jayB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7IC4uLnBhcmFtZXRlcnMgfSA9IHt9KSB7XHJcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ0NsYXNzID0gMTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnTnVtYmVyID0gMjg7XHJcbiAgICB9XHJcbn1cclxuX2EkZyA9IFVuaXZlcnNhbFN0cmluZztcclxuKCgpID0+IHtcclxuICAgIHR5cGVTdG9yZS5Vbml2ZXJzYWxTdHJpbmcgPSBfYSRnO1xyXG59KSgpO1xyXG5Vbml2ZXJzYWxTdHJpbmcuTkFNRSA9IFwiVW5pdmVyc2FsU3RyaW5nXCI7XG5cbnZhciBfYSRmO1xyXG5jbGFzcyBOdW1lcmljU3RyaW5nIGV4dGVuZHMgTG9jYWxTaW1wbGVTdHJpbmdCbG9jayB7XHJcbiAgICBjb25zdHJ1Y3RvcihwYXJhbWV0ZXJzID0ge30pIHtcclxuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnQ2xhc3MgPSAxO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdOdW1iZXIgPSAxODtcclxuICAgIH1cclxufVxyXG5fYSRmID0gTnVtZXJpY1N0cmluZztcclxuKCgpID0+IHtcclxuICAgIHR5cGVTdG9yZS5OdW1lcmljU3RyaW5nID0gX2EkZjtcclxufSkoKTtcclxuTnVtZXJpY1N0cmluZy5OQU1FID0gXCJOdW1lcmljU3RyaW5nXCI7XG5cbnZhciBfYSRlO1xyXG5jbGFzcyBQcmludGFibGVTdHJpbmcgZXh0ZW5kcyBMb2NhbFNpbXBsZVN0cmluZ0Jsb2NrIHtcclxuICAgIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMgPSB7fSkge1xyXG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdDbGFzcyA9IDE7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ051bWJlciA9IDE5O1xyXG4gICAgfVxyXG59XHJcbl9hJGUgPSBQcmludGFibGVTdHJpbmc7XHJcbigoKSA9PiB7XHJcbiAgICB0eXBlU3RvcmUuUHJpbnRhYmxlU3RyaW5nID0gX2EkZTtcclxufSkoKTtcclxuUHJpbnRhYmxlU3RyaW5nLk5BTUUgPSBcIlByaW50YWJsZVN0cmluZ1wiO1xuXG52YXIgX2EkZDtcclxuY2xhc3MgVGVsZXRleFN0cmluZyBleHRlbmRzIExvY2FsU2ltcGxlU3RyaW5nQmxvY2sge1xyXG4gICAgY29uc3RydWN0b3IocGFyYW1ldGVycyA9IHt9KSB7XHJcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ0NsYXNzID0gMTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnTnVtYmVyID0gMjA7XHJcbiAgICB9XHJcbn1cclxuX2EkZCA9IFRlbGV0ZXhTdHJpbmc7XHJcbigoKSA9PiB7XHJcbiAgICB0eXBlU3RvcmUuVGVsZXRleFN0cmluZyA9IF9hJGQ7XHJcbn0pKCk7XHJcblRlbGV0ZXhTdHJpbmcuTkFNRSA9IFwiVGVsZXRleFN0cmluZ1wiO1xuXG52YXIgX2EkYztcclxuY2xhc3MgVmlkZW90ZXhTdHJpbmcgZXh0ZW5kcyBMb2NhbFNpbXBsZVN0cmluZ0Jsb2NrIHtcclxuICAgIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMgPSB7fSkge1xyXG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdDbGFzcyA9IDE7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ051bWJlciA9IDIxO1xyXG4gICAgfVxyXG59XHJcbl9hJGMgPSBWaWRlb3RleFN0cmluZztcclxuKCgpID0+IHtcclxuICAgIHR5cGVTdG9yZS5WaWRlb3RleFN0cmluZyA9IF9hJGM7XHJcbn0pKCk7XHJcblZpZGVvdGV4U3RyaW5nLk5BTUUgPSBcIlZpZGVvdGV4U3RyaW5nXCI7XG5cbnZhciBfYSRiO1xyXG5jbGFzcyBJQTVTdHJpbmcgZXh0ZW5kcyBMb2NhbFNpbXBsZVN0cmluZ0Jsb2NrIHtcclxuICAgIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMgPSB7fSkge1xyXG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdDbGFzcyA9IDE7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ051bWJlciA9IDIyO1xyXG4gICAgfVxyXG59XHJcbl9hJGIgPSBJQTVTdHJpbmc7XHJcbigoKSA9PiB7XHJcbiAgICB0eXBlU3RvcmUuSUE1U3RyaW5nID0gX2EkYjtcclxufSkoKTtcclxuSUE1U3RyaW5nLk5BTUUgPSBcIklBNVN0cmluZ1wiO1xuXG52YXIgX2EkYTtcclxuY2xhc3MgR3JhcGhpY1N0cmluZyBleHRlbmRzIExvY2FsU2ltcGxlU3RyaW5nQmxvY2sge1xyXG4gICAgY29uc3RydWN0b3IocGFyYW1ldGVycyA9IHt9KSB7XHJcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ0NsYXNzID0gMTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnTnVtYmVyID0gMjU7XHJcbiAgICB9XHJcbn1cclxuX2EkYSA9IEdyYXBoaWNTdHJpbmc7XHJcbigoKSA9PiB7XHJcbiAgICB0eXBlU3RvcmUuR3JhcGhpY1N0cmluZyA9IF9hJGE7XHJcbn0pKCk7XHJcbkdyYXBoaWNTdHJpbmcuTkFNRSA9IFwiR3JhcGhpY1N0cmluZ1wiO1xuXG52YXIgX2EkOTtcclxuY2xhc3MgVmlzaWJsZVN0cmluZyBleHRlbmRzIExvY2FsU2ltcGxlU3RyaW5nQmxvY2sge1xyXG4gICAgY29uc3RydWN0b3IocGFyYW1ldGVycyA9IHt9KSB7XHJcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ0NsYXNzID0gMTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnTnVtYmVyID0gMjY7XHJcbiAgICB9XHJcbn1cclxuX2EkOSA9IFZpc2libGVTdHJpbmc7XHJcbigoKSA9PiB7XHJcbiAgICB0eXBlU3RvcmUuVmlzaWJsZVN0cmluZyA9IF9hJDk7XHJcbn0pKCk7XHJcblZpc2libGVTdHJpbmcuTkFNRSA9IFwiVmlzaWJsZVN0cmluZ1wiO1xuXG52YXIgX2EkODtcclxuY2xhc3MgR2VuZXJhbFN0cmluZyBleHRlbmRzIExvY2FsU2ltcGxlU3RyaW5nQmxvY2sge1xyXG4gICAgY29uc3RydWN0b3IocGFyYW1ldGVycyA9IHt9KSB7XHJcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ0NsYXNzID0gMTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnTnVtYmVyID0gMjc7XHJcbiAgICB9XHJcbn1cclxuX2EkOCA9IEdlbmVyYWxTdHJpbmc7XHJcbigoKSA9PiB7XHJcbiAgICB0eXBlU3RvcmUuR2VuZXJhbFN0cmluZyA9IF9hJDg7XHJcbn0pKCk7XHJcbkdlbmVyYWxTdHJpbmcuTkFNRSA9IFwiR2VuZXJhbFN0cmluZ1wiO1xuXG52YXIgX2EkNztcclxuY2xhc3MgQ2hhcmFjdGVyU3RyaW5nIGV4dGVuZHMgTG9jYWxTaW1wbGVTdHJpbmdCbG9jayB7XHJcbiAgICBjb25zdHJ1Y3RvcihwYXJhbWV0ZXJzID0ge30pIHtcclxuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnQ2xhc3MgPSAxO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdOdW1iZXIgPSAyOTtcclxuICAgIH1cclxufVxyXG5fYSQ3ID0gQ2hhcmFjdGVyU3RyaW5nO1xyXG4oKCkgPT4ge1xyXG4gICAgdHlwZVN0b3JlLkNoYXJhY3RlclN0cmluZyA9IF9hJDc7XHJcbn0pKCk7XHJcbkNoYXJhY3RlclN0cmluZy5OQU1FID0gXCJDaGFyYWN0ZXJTdHJpbmdcIjtcblxudmFyIF9hJDY7XHJcbmNsYXNzIFVUQ1RpbWUgZXh0ZW5kcyBWaXNpYmxlU3RyaW5nIHtcclxuICAgIGNvbnN0cnVjdG9yKHsgdmFsdWUsIHZhbHVlRGF0ZSwgLi4ucGFyYW1ldGVycyB9ID0ge30pIHtcclxuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcclxuICAgICAgICB0aGlzLnllYXIgPSAwO1xyXG4gICAgICAgIHRoaXMubW9udGggPSAwO1xyXG4gICAgICAgIHRoaXMuZGF5ID0gMDtcclxuICAgICAgICB0aGlzLmhvdXIgPSAwO1xyXG4gICAgICAgIHRoaXMubWludXRlID0gMDtcclxuICAgICAgICB0aGlzLnNlY29uZCA9IDA7XHJcbiAgICAgICAgaWYgKHZhbHVlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZnJvbVN0cmluZyh2YWx1ZSk7XHJcbiAgICAgICAgICAgIHRoaXMudmFsdWVCbG9jay52YWx1ZUhleFZpZXcgPSBuZXcgVWludDhBcnJheSh2YWx1ZS5sZW5ndGgpO1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHZhbHVlLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgICAgICAgICAgdGhpcy52YWx1ZUJsb2NrLnZhbHVlSGV4Vmlld1tpXSA9IHZhbHVlLmNoYXJDb2RlQXQoaSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh2YWx1ZURhdGUpIHtcclxuICAgICAgICAgICAgdGhpcy5mcm9tRGF0ZSh2YWx1ZURhdGUpO1xyXG4gICAgICAgICAgICB0aGlzLnZhbHVlQmxvY2sudmFsdWVIZXhWaWV3ID0gbmV3IFVpbnQ4QXJyYXkodGhpcy50b0J1ZmZlcigpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ0NsYXNzID0gMTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnTnVtYmVyID0gMjM7XHJcbiAgICB9XHJcbiAgICBmcm9tQnVmZmVyKGlucHV0QnVmZmVyKSB7XHJcbiAgICAgICAgdGhpcy5mcm9tU3RyaW5nKFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCwgcHZ0c3V0aWxzLkJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b1VpbnQ4QXJyYXkoaW5wdXRCdWZmZXIpKSk7XHJcbiAgICB9XHJcbiAgICB0b0J1ZmZlcigpIHtcclxuICAgICAgICBjb25zdCBzdHIgPSB0aGlzLnRvU3RyaW5nKCk7XHJcbiAgICAgICAgY29uc3QgYnVmZmVyID0gbmV3IEFycmF5QnVmZmVyKHN0ci5sZW5ndGgpO1xyXG4gICAgICAgIGNvbnN0IHZpZXcgPSBuZXcgVWludDhBcnJheShidWZmZXIpO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgICAgICB2aWV3W2ldID0gc3RyLmNoYXJDb2RlQXQoaSk7XHJcbiAgICAgICAgcmV0dXJuIGJ1ZmZlcjtcclxuICAgIH1cclxuICAgIGZyb21EYXRlKGlucHV0RGF0ZSkge1xyXG4gICAgICAgIHRoaXMueWVhciA9IGlucHV0RGF0ZS5nZXRVVENGdWxsWWVhcigpO1xyXG4gICAgICAgIHRoaXMubW9udGggPSBpbnB1dERhdGUuZ2V0VVRDTW9udGgoKSArIDE7XHJcbiAgICAgICAgdGhpcy5kYXkgPSBpbnB1dERhdGUuZ2V0VVRDRGF0ZSgpO1xyXG4gICAgICAgIHRoaXMuaG91ciA9IGlucHV0RGF0ZS5nZXRVVENIb3VycygpO1xyXG4gICAgICAgIHRoaXMubWludXRlID0gaW5wdXREYXRlLmdldFVUQ01pbnV0ZXMoKTtcclxuICAgICAgICB0aGlzLnNlY29uZCA9IGlucHV0RGF0ZS5nZXRVVENTZWNvbmRzKCk7XHJcbiAgICB9XHJcbiAgICB0b0RhdGUoKSB7XHJcbiAgICAgICAgcmV0dXJuIChuZXcgRGF0ZShEYXRlLlVUQyh0aGlzLnllYXIsIHRoaXMubW9udGggLSAxLCB0aGlzLmRheSwgdGhpcy5ob3VyLCB0aGlzLm1pbnV0ZSwgdGhpcy5zZWNvbmQpKSk7XHJcbiAgICB9XHJcbiAgICBmcm9tU3RyaW5nKGlucHV0U3RyaW5nKSB7XHJcbiAgICAgICAgY29uc3QgcGFyc2VyID0gLyhcXGR7Mn0pKFxcZHsyfSkoXFxkezJ9KShcXGR7Mn0pKFxcZHsyfSkoXFxkezJ9KVovaWc7XHJcbiAgICAgICAgY29uc3QgcGFyc2VyQXJyYXkgPSBwYXJzZXIuZXhlYyhpbnB1dFN0cmluZyk7XHJcbiAgICAgICAgaWYgKHBhcnNlckFycmF5ID09PSBudWxsKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZXJyb3IgPSBcIldyb25nIGlucHV0IHN0cmluZyBmb3IgY29udmVyc2lvblwiO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IHllYXIgPSBwYXJzZUludChwYXJzZXJBcnJheVsxXSwgMTApO1xyXG4gICAgICAgIGlmICh5ZWFyID49IDUwKVxyXG4gICAgICAgICAgICB0aGlzLnllYXIgPSAxOTAwICsgeWVhcjtcclxuICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgIHRoaXMueWVhciA9IDIwMDAgKyB5ZWFyO1xyXG4gICAgICAgIHRoaXMubW9udGggPSBwYXJzZUludChwYXJzZXJBcnJheVsyXSwgMTApO1xyXG4gICAgICAgIHRoaXMuZGF5ID0gcGFyc2VJbnQocGFyc2VyQXJyYXlbM10sIDEwKTtcclxuICAgICAgICB0aGlzLmhvdXIgPSBwYXJzZUludChwYXJzZXJBcnJheVs0XSwgMTApO1xyXG4gICAgICAgIHRoaXMubWludXRlID0gcGFyc2VJbnQocGFyc2VyQXJyYXlbNV0sIDEwKTtcclxuICAgICAgICB0aGlzLnNlY29uZCA9IHBhcnNlSW50KHBhcnNlckFycmF5WzZdLCAxMCk7XHJcbiAgICB9XHJcbiAgICB0b1N0cmluZyhlbmNvZGluZyA9IFwiaXNvXCIpIHtcclxuICAgICAgICBpZiAoZW5jb2RpbmcgPT09IFwiaXNvXCIpIHtcclxuICAgICAgICAgICAgY29uc3Qgb3V0cHV0QXJyYXkgPSBuZXcgQXJyYXkoNyk7XHJcbiAgICAgICAgICAgIG91dHB1dEFycmF5WzBdID0gcHZ1dGlscy5wYWROdW1iZXIoKCh0aGlzLnllYXIgPCAyMDAwKSA/ICh0aGlzLnllYXIgLSAxOTAwKSA6ICh0aGlzLnllYXIgLSAyMDAwKSksIDIpO1xyXG4gICAgICAgICAgICBvdXRwdXRBcnJheVsxXSA9IHB2dXRpbHMucGFkTnVtYmVyKHRoaXMubW9udGgsIDIpO1xyXG4gICAgICAgICAgICBvdXRwdXRBcnJheVsyXSA9IHB2dXRpbHMucGFkTnVtYmVyKHRoaXMuZGF5LCAyKTtcclxuICAgICAgICAgICAgb3V0cHV0QXJyYXlbM10gPSBwdnV0aWxzLnBhZE51bWJlcih0aGlzLmhvdXIsIDIpO1xyXG4gICAgICAgICAgICBvdXRwdXRBcnJheVs0XSA9IHB2dXRpbHMucGFkTnVtYmVyKHRoaXMubWludXRlLCAyKTtcclxuICAgICAgICAgICAgb3V0cHV0QXJyYXlbNV0gPSBwdnV0aWxzLnBhZE51bWJlcih0aGlzLnNlY29uZCwgMik7XHJcbiAgICAgICAgICAgIG91dHB1dEFycmF5WzZdID0gXCJaXCI7XHJcbiAgICAgICAgICAgIHJldHVybiBvdXRwdXRBcnJheS5qb2luKFwiXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gc3VwZXIudG9TdHJpbmcoZW5jb2RpbmcpO1xyXG4gICAgfVxyXG4gICAgb25Bc2NpaUVuY29kaW5nKCkge1xyXG4gICAgICAgIHJldHVybiBgJHt0aGlzLmNvbnN0cnVjdG9yLk5BTUV9IDogJHt0aGlzLnRvRGF0ZSgpLnRvSVNPU3RyaW5nKCl9YDtcclxuICAgIH1cclxuICAgIHRvSlNPTigpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAuLi5zdXBlci50b0pTT04oKSxcclxuICAgICAgICAgICAgeWVhcjogdGhpcy55ZWFyLFxyXG4gICAgICAgICAgICBtb250aDogdGhpcy5tb250aCxcclxuICAgICAgICAgICAgZGF5OiB0aGlzLmRheSxcclxuICAgICAgICAgICAgaG91cjogdGhpcy5ob3VyLFxyXG4gICAgICAgICAgICBtaW51dGU6IHRoaXMubWludXRlLFxyXG4gICAgICAgICAgICBzZWNvbmQ6IHRoaXMuc2Vjb25kLFxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbn1cclxuX2EkNiA9IFVUQ1RpbWU7XHJcbigoKSA9PiB7XHJcbiAgICB0eXBlU3RvcmUuVVRDVGltZSA9IF9hJDY7XHJcbn0pKCk7XHJcblVUQ1RpbWUuTkFNRSA9IFwiVVRDVGltZVwiO1xuXG52YXIgX2EkNTtcclxuY2xhc3MgR2VuZXJhbGl6ZWRUaW1lIGV4dGVuZHMgVVRDVGltZSB7XHJcbiAgICBjb25zdHJ1Y3RvcihwYXJhbWV0ZXJzID0ge30pIHtcclxuICAgICAgICB2YXIgX2I7XHJcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XHJcbiAgICAgICAgKF9iID0gdGhpcy5taWxsaXNlY29uZCkgIT09IG51bGwgJiYgX2IgIT09IHZvaWQgMCA/IF9iIDogKHRoaXMubWlsbGlzZWNvbmQgPSAwKTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnQ2xhc3MgPSAxO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdOdW1iZXIgPSAyNDtcclxuICAgIH1cclxuICAgIGZyb21EYXRlKGlucHV0RGF0ZSkge1xyXG4gICAgICAgIHN1cGVyLmZyb21EYXRlKGlucHV0RGF0ZSk7XHJcbiAgICAgICAgdGhpcy5taWxsaXNlY29uZCA9IGlucHV0RGF0ZS5nZXRVVENNaWxsaXNlY29uZHMoKTtcclxuICAgIH1cclxuICAgIHRvRGF0ZSgpIHtcclxuICAgICAgICByZXR1cm4gKG5ldyBEYXRlKERhdGUuVVRDKHRoaXMueWVhciwgdGhpcy5tb250aCAtIDEsIHRoaXMuZGF5LCB0aGlzLmhvdXIsIHRoaXMubWludXRlLCB0aGlzLnNlY29uZCwgdGhpcy5taWxsaXNlY29uZCkpKTtcclxuICAgIH1cclxuICAgIGZyb21TdHJpbmcoaW5wdXRTdHJpbmcpIHtcclxuICAgICAgICBsZXQgaXNVVEMgPSBmYWxzZTtcclxuICAgICAgICBsZXQgdGltZVN0cmluZyA9IFwiXCI7XHJcbiAgICAgICAgbGV0IGRhdGVUaW1lU3RyaW5nID0gXCJcIjtcclxuICAgICAgICBsZXQgZnJhY3Rpb25QYXJ0ID0gMDtcclxuICAgICAgICBsZXQgcGFyc2VyO1xyXG4gICAgICAgIGxldCBob3VyRGlmZmVyZW5jZSA9IDA7XHJcbiAgICAgICAgbGV0IG1pbnV0ZURpZmZlcmVuY2UgPSAwO1xyXG4gICAgICAgIGlmIChpbnB1dFN0cmluZ1tpbnB1dFN0cmluZy5sZW5ndGggLSAxXSA9PT0gXCJaXCIpIHtcclxuICAgICAgICAgICAgdGltZVN0cmluZyA9IGlucHV0U3RyaW5nLnN1YnN0cmluZygwLCBpbnB1dFN0cmluZy5sZW5ndGggLSAxKTtcclxuICAgICAgICAgICAgaXNVVEMgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgY29uc3QgbnVtYmVyID0gbmV3IE51bWJlcihpbnB1dFN0cmluZ1tpbnB1dFN0cmluZy5sZW5ndGggLSAxXSk7XHJcbiAgICAgICAgICAgIGlmIChpc05hTihudW1iZXIudmFsdWVPZigpKSlcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIldyb25nIGlucHV0IHN0cmluZyBmb3IgY29udmVyc2lvblwiKTtcclxuICAgICAgICAgICAgdGltZVN0cmluZyA9IGlucHV0U3RyaW5nO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoaXNVVEMpIHtcclxuICAgICAgICAgICAgaWYgKHRpbWVTdHJpbmcuaW5kZXhPZihcIitcIikgIT09IC0xKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiV3JvbmcgaW5wdXQgc3RyaW5nIGZvciBjb252ZXJzaW9uXCIpO1xyXG4gICAgICAgICAgICBpZiAodGltZVN0cmluZy5pbmRleE9mKFwiLVwiKSAhPT0gLTEpXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJXcm9uZyBpbnB1dCBzdHJpbmcgZm9yIGNvbnZlcnNpb25cIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBsZXQgbXVsdGlwbGllciA9IDE7XHJcbiAgICAgICAgICAgIGxldCBkaWZmZXJlbmNlUG9zaXRpb24gPSB0aW1lU3RyaW5nLmluZGV4T2YoXCIrXCIpO1xyXG4gICAgICAgICAgICBsZXQgZGlmZmVyZW5jZVN0cmluZyA9IFwiXCI7XHJcbiAgICAgICAgICAgIGlmIChkaWZmZXJlbmNlUG9zaXRpb24gPT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICBkaWZmZXJlbmNlUG9zaXRpb24gPSB0aW1lU3RyaW5nLmluZGV4T2YoXCItXCIpO1xyXG4gICAgICAgICAgICAgICAgbXVsdGlwbGllciA9IC0xO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChkaWZmZXJlbmNlUG9zaXRpb24gIT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICBkaWZmZXJlbmNlU3RyaW5nID0gdGltZVN0cmluZy5zdWJzdHJpbmcoZGlmZmVyZW5jZVBvc2l0aW9uICsgMSk7XHJcbiAgICAgICAgICAgICAgICB0aW1lU3RyaW5nID0gdGltZVN0cmluZy5zdWJzdHJpbmcoMCwgZGlmZmVyZW5jZVBvc2l0aW9uKTtcclxuICAgICAgICAgICAgICAgIGlmICgoZGlmZmVyZW5jZVN0cmluZy5sZW5ndGggIT09IDIpICYmIChkaWZmZXJlbmNlU3RyaW5nLmxlbmd0aCAhPT0gNCkpXHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiV3JvbmcgaW5wdXQgc3RyaW5nIGZvciBjb252ZXJzaW9uXCIpO1xyXG4gICAgICAgICAgICAgICAgbGV0IG51bWJlciA9IHBhcnNlSW50KGRpZmZlcmVuY2VTdHJpbmcuc3Vic3RyaW5nKDAsIDIpLCAxMCk7XHJcbiAgICAgICAgICAgICAgICBpZiAoaXNOYU4obnVtYmVyLnZhbHVlT2YoKSkpXHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiV3JvbmcgaW5wdXQgc3RyaW5nIGZvciBjb252ZXJzaW9uXCIpO1xyXG4gICAgICAgICAgICAgICAgaG91ckRpZmZlcmVuY2UgPSBtdWx0aXBsaWVyICogbnVtYmVyO1xyXG4gICAgICAgICAgICAgICAgaWYgKGRpZmZlcmVuY2VTdHJpbmcubGVuZ3RoID09PSA0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbnVtYmVyID0gcGFyc2VJbnQoZGlmZmVyZW5jZVN0cmluZy5zdWJzdHJpbmcoMiwgNCksIDEwKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoaXNOYU4obnVtYmVyLnZhbHVlT2YoKSkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIldyb25nIGlucHV0IHN0cmluZyBmb3IgY29udmVyc2lvblwiKTtcclxuICAgICAgICAgICAgICAgICAgICBtaW51dGVEaWZmZXJlbmNlID0gbXVsdGlwbGllciAqIG51bWJlcjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBsZXQgZnJhY3Rpb25Qb2ludFBvc2l0aW9uID0gdGltZVN0cmluZy5pbmRleE9mKFwiLlwiKTtcclxuICAgICAgICBpZiAoZnJhY3Rpb25Qb2ludFBvc2l0aW9uID09PSAtMSlcclxuICAgICAgICAgICAgZnJhY3Rpb25Qb2ludFBvc2l0aW9uID0gdGltZVN0cmluZy5pbmRleE9mKFwiLFwiKTtcclxuICAgICAgICBpZiAoZnJhY3Rpb25Qb2ludFBvc2l0aW9uICE9PSAtMSkge1xyXG4gICAgICAgICAgICBjb25zdCBmcmFjdGlvblBhcnRDaGVjayA9IG5ldyBOdW1iZXIoYDAke3RpbWVTdHJpbmcuc3Vic3RyaW5nKGZyYWN0aW9uUG9pbnRQb3NpdGlvbil9YCk7XHJcbiAgICAgICAgICAgIGlmIChpc05hTihmcmFjdGlvblBhcnRDaGVjay52YWx1ZU9mKCkpKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiV3JvbmcgaW5wdXQgc3RyaW5nIGZvciBjb252ZXJzaW9uXCIpO1xyXG4gICAgICAgICAgICBmcmFjdGlvblBhcnQgPSBmcmFjdGlvblBhcnRDaGVjay52YWx1ZU9mKCk7XHJcbiAgICAgICAgICAgIGRhdGVUaW1lU3RyaW5nID0gdGltZVN0cmluZy5zdWJzdHJpbmcoMCwgZnJhY3Rpb25Qb2ludFBvc2l0aW9uKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICBkYXRlVGltZVN0cmluZyA9IHRpbWVTdHJpbmc7XHJcbiAgICAgICAgc3dpdGNoICh0cnVlKSB7XHJcbiAgICAgICAgICAgIGNhc2UgKGRhdGVUaW1lU3RyaW5nLmxlbmd0aCA9PT0gOCk6XHJcbiAgICAgICAgICAgICAgICBwYXJzZXIgPSAvKFxcZHs0fSkoXFxkezJ9KShcXGR7Mn0pL2lnO1xyXG4gICAgICAgICAgICAgICAgaWYgKGZyYWN0aW9uUG9pbnRQb3NpdGlvbiAhPT0gLTEpXHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiV3JvbmcgaW5wdXQgc3RyaW5nIGZvciBjb252ZXJzaW9uXCIpO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgKGRhdGVUaW1lU3RyaW5nLmxlbmd0aCA9PT0gMTApOlxyXG4gICAgICAgICAgICAgICAgcGFyc2VyID0gLyhcXGR7NH0pKFxcZHsyfSkoXFxkezJ9KShcXGR7Mn0pL2lnO1xyXG4gICAgICAgICAgICAgICAgaWYgKGZyYWN0aW9uUG9pbnRQb3NpdGlvbiAhPT0gLTEpIHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgZnJhY3Rpb25SZXN1bHQgPSA2MCAqIGZyYWN0aW9uUGFydDtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLm1pbnV0ZSA9IE1hdGguZmxvb3IoZnJhY3Rpb25SZXN1bHQpO1xyXG4gICAgICAgICAgICAgICAgICAgIGZyYWN0aW9uUmVzdWx0ID0gNjAgKiAoZnJhY3Rpb25SZXN1bHQgLSB0aGlzLm1pbnV0ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZWNvbmQgPSBNYXRoLmZsb29yKGZyYWN0aW9uUmVzdWx0KTtcclxuICAgICAgICAgICAgICAgICAgICBmcmFjdGlvblJlc3VsdCA9IDEwMDAgKiAoZnJhY3Rpb25SZXN1bHQgLSB0aGlzLnNlY29uZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5taWxsaXNlY29uZCA9IE1hdGguZmxvb3IoZnJhY3Rpb25SZXN1bHQpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgKGRhdGVUaW1lU3RyaW5nLmxlbmd0aCA9PT0gMTIpOlxyXG4gICAgICAgICAgICAgICAgcGFyc2VyID0gLyhcXGR7NH0pKFxcZHsyfSkoXFxkezJ9KShcXGR7Mn0pKFxcZHsyfSkvaWc7XHJcbiAgICAgICAgICAgICAgICBpZiAoZnJhY3Rpb25Qb2ludFBvc2l0aW9uICE9PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBmcmFjdGlvblJlc3VsdCA9IDYwICogZnJhY3Rpb25QYXJ0O1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vjb25kID0gTWF0aC5mbG9vcihmcmFjdGlvblJlc3VsdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgZnJhY3Rpb25SZXN1bHQgPSAxMDAwICogKGZyYWN0aW9uUmVzdWx0IC0gdGhpcy5zZWNvbmQpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWlsbGlzZWNvbmQgPSBNYXRoLmZsb29yKGZyYWN0aW9uUmVzdWx0KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlIChkYXRlVGltZVN0cmluZy5sZW5ndGggPT09IDE0KTpcclxuICAgICAgICAgICAgICAgIHBhcnNlciA9IC8oXFxkezR9KShcXGR7Mn0pKFxcZHsyfSkoXFxkezJ9KShcXGR7Mn0pKFxcZHsyfSkvaWc7XHJcbiAgICAgICAgICAgICAgICBpZiAoZnJhY3Rpb25Qb2ludFBvc2l0aW9uICE9PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGZyYWN0aW9uUmVzdWx0ID0gMTAwMCAqIGZyYWN0aW9uUGFydDtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLm1pbGxpc2Vjb25kID0gTWF0aC5mbG9vcihmcmFjdGlvblJlc3VsdCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIldyb25nIGlucHV0IHN0cmluZyBmb3IgY29udmVyc2lvblwiKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgcGFyc2VyQXJyYXkgPSBwYXJzZXIuZXhlYyhkYXRlVGltZVN0cmluZyk7XHJcbiAgICAgICAgaWYgKHBhcnNlckFycmF5ID09PSBudWxsKVxyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJXcm9uZyBpbnB1dCBzdHJpbmcgZm9yIGNvbnZlcnNpb25cIik7XHJcbiAgICAgICAgZm9yIChsZXQgaiA9IDE7IGogPCBwYXJzZXJBcnJheS5sZW5ndGg7IGorKykge1xyXG4gICAgICAgICAgICBzd2l0Y2ggKGopIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgMTpcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnllYXIgPSBwYXJzZUludChwYXJzZXJBcnJheVtqXSwgMTApO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAyOlxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubW9udGggPSBwYXJzZUludChwYXJzZXJBcnJheVtqXSwgMTApO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAzOlxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGF5ID0gcGFyc2VJbnQocGFyc2VyQXJyYXlbal0sIDEwKTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgNDpcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmhvdXIgPSBwYXJzZUludChwYXJzZXJBcnJheVtqXSwgMTApICsgaG91ckRpZmZlcmVuY2U7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDU6XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5taW51dGUgPSBwYXJzZUludChwYXJzZXJBcnJheVtqXSwgMTApICsgbWludXRlRGlmZmVyZW5jZTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgNjpcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNlY29uZCA9IHBhcnNlSW50KHBhcnNlckFycmF5W2pdLCAxMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIldyb25nIGlucHV0IHN0cmluZyBmb3IgY29udmVyc2lvblwiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoaXNVVEMgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHRlbXBEYXRlID0gbmV3IERhdGUodGhpcy55ZWFyLCB0aGlzLm1vbnRoLCB0aGlzLmRheSwgdGhpcy5ob3VyLCB0aGlzLm1pbnV0ZSwgdGhpcy5zZWNvbmQsIHRoaXMubWlsbGlzZWNvbmQpO1xyXG4gICAgICAgICAgICB0aGlzLnllYXIgPSB0ZW1wRGF0ZS5nZXRVVENGdWxsWWVhcigpO1xyXG4gICAgICAgICAgICB0aGlzLm1vbnRoID0gdGVtcERhdGUuZ2V0VVRDTW9udGgoKTtcclxuICAgICAgICAgICAgdGhpcy5kYXkgPSB0ZW1wRGF0ZS5nZXRVVENEYXkoKTtcclxuICAgICAgICAgICAgdGhpcy5ob3VyID0gdGVtcERhdGUuZ2V0VVRDSG91cnMoKTtcclxuICAgICAgICAgICAgdGhpcy5taW51dGUgPSB0ZW1wRGF0ZS5nZXRVVENNaW51dGVzKCk7XHJcbiAgICAgICAgICAgIHRoaXMuc2Vjb25kID0gdGVtcERhdGUuZ2V0VVRDU2Vjb25kcygpO1xyXG4gICAgICAgICAgICB0aGlzLm1pbGxpc2Vjb25kID0gdGVtcERhdGUuZ2V0VVRDTWlsbGlzZWNvbmRzKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgdG9TdHJpbmcoZW5jb2RpbmcgPSBcImlzb1wiKSB7XHJcbiAgICAgICAgaWYgKGVuY29kaW5nID09PSBcImlzb1wiKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IG91dHB1dEFycmF5ID0gW107XHJcbiAgICAgICAgICAgIG91dHB1dEFycmF5LnB1c2gocHZ1dGlscy5wYWROdW1iZXIodGhpcy55ZWFyLCA0KSk7XHJcbiAgICAgICAgICAgIG91dHB1dEFycmF5LnB1c2gocHZ1dGlscy5wYWROdW1iZXIodGhpcy5tb250aCwgMikpO1xyXG4gICAgICAgICAgICBvdXRwdXRBcnJheS5wdXNoKHB2dXRpbHMucGFkTnVtYmVyKHRoaXMuZGF5LCAyKSk7XHJcbiAgICAgICAgICAgIG91dHB1dEFycmF5LnB1c2gocHZ1dGlscy5wYWROdW1iZXIodGhpcy5ob3VyLCAyKSk7XHJcbiAgICAgICAgICAgIG91dHB1dEFycmF5LnB1c2gocHZ1dGlscy5wYWROdW1iZXIodGhpcy5taW51dGUsIDIpKTtcclxuICAgICAgICAgICAgb3V0cHV0QXJyYXkucHVzaChwdnV0aWxzLnBhZE51bWJlcih0aGlzLnNlY29uZCwgMikpO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5taWxsaXNlY29uZCAhPT0gMCkge1xyXG4gICAgICAgICAgICAgICAgb3V0cHV0QXJyYXkucHVzaChcIi5cIik7XHJcbiAgICAgICAgICAgICAgICBvdXRwdXRBcnJheS5wdXNoKHB2dXRpbHMucGFkTnVtYmVyKHRoaXMubWlsbGlzZWNvbmQsIDMpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBvdXRwdXRBcnJheS5wdXNoKFwiWlwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIG91dHB1dEFycmF5LmpvaW4oXCJcIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBzdXBlci50b1N0cmluZyhlbmNvZGluZyk7XHJcbiAgICB9XHJcbiAgICB0b0pTT04oKSB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgLi4uc3VwZXIudG9KU09OKCksXHJcbiAgICAgICAgICAgIG1pbGxpc2Vjb25kOiB0aGlzLm1pbGxpc2Vjb25kLFxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbn1cclxuX2EkNSA9IEdlbmVyYWxpemVkVGltZTtcclxuKCgpID0+IHtcclxuICAgIHR5cGVTdG9yZS5HZW5lcmFsaXplZFRpbWUgPSBfYSQ1O1xyXG59KSgpO1xyXG5HZW5lcmFsaXplZFRpbWUuTkFNRSA9IFwiR2VuZXJhbGl6ZWRUaW1lXCI7XG5cbnZhciBfYSQ0O1xyXG5jbGFzcyBEQVRFIGV4dGVuZHMgVXRmOFN0cmluZyB7XHJcbiAgICBjb25zdHJ1Y3RvcihwYXJhbWV0ZXJzID0ge30pIHtcclxuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnQ2xhc3MgPSAxO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdOdW1iZXIgPSAzMTtcclxuICAgIH1cclxufVxyXG5fYSQ0ID0gREFURTtcclxuKCgpID0+IHtcclxuICAgIHR5cGVTdG9yZS5EQVRFID0gX2EkNDtcclxufSkoKTtcclxuREFURS5OQU1FID0gXCJEQVRFXCI7XG5cbnZhciBfYSQzO1xyXG5jbGFzcyBUaW1lT2ZEYXkgZXh0ZW5kcyBVdGY4U3RyaW5nIHtcclxuICAgIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMgPSB7fSkge1xyXG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdDbGFzcyA9IDE7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ051bWJlciA9IDMyO1xyXG4gICAgfVxyXG59XHJcbl9hJDMgPSBUaW1lT2ZEYXk7XHJcbigoKSA9PiB7XHJcbiAgICB0eXBlU3RvcmUuVGltZU9mRGF5ID0gX2EkMztcclxufSkoKTtcclxuVGltZU9mRGF5Lk5BTUUgPSBcIlRpbWVPZkRheVwiO1xuXG52YXIgX2EkMjtcclxuY2xhc3MgRGF0ZVRpbWUgZXh0ZW5kcyBVdGY4U3RyaW5nIHtcclxuICAgIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMgPSB7fSkge1xyXG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdDbGFzcyA9IDE7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ051bWJlciA9IDMzO1xyXG4gICAgfVxyXG59XHJcbl9hJDIgPSBEYXRlVGltZTtcclxuKCgpID0+IHtcclxuICAgIHR5cGVTdG9yZS5EYXRlVGltZSA9IF9hJDI7XHJcbn0pKCk7XHJcbkRhdGVUaW1lLk5BTUUgPSBcIkRhdGVUaW1lXCI7XG5cbnZhciBfYSQxO1xyXG5jbGFzcyBEdXJhdGlvbiBleHRlbmRzIFV0ZjhTdHJpbmcge1xyXG4gICAgY29uc3RydWN0b3IocGFyYW1ldGVycyA9IHt9KSB7XHJcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ0NsYXNzID0gMTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnTnVtYmVyID0gMzQ7XHJcbiAgICB9XHJcbn1cclxuX2EkMSA9IER1cmF0aW9uO1xyXG4oKCkgPT4ge1xyXG4gICAgdHlwZVN0b3JlLkR1cmF0aW9uID0gX2EkMTtcclxufSkoKTtcclxuRHVyYXRpb24uTkFNRSA9IFwiRHVyYXRpb25cIjtcblxudmFyIF9hO1xyXG5jbGFzcyBUSU1FIGV4dGVuZHMgVXRmOFN0cmluZyB7XHJcbiAgICBjb25zdHJ1Y3RvcihwYXJhbWV0ZXJzID0ge30pIHtcclxuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnQ2xhc3MgPSAxO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdOdW1iZXIgPSAxNDtcclxuICAgIH1cclxufVxyXG5fYSA9IFRJTUU7XHJcbigoKSA9PiB7XHJcbiAgICB0eXBlU3RvcmUuVElNRSA9IF9hO1xyXG59KSgpO1xyXG5USU1FLk5BTUUgPSBcIlRJTUVcIjtcblxuY2xhc3MgQW55IHtcclxuICAgIGNvbnN0cnVjdG9yKHsgbmFtZSA9IEVNUFRZX1NUUklORywgb3B0aW9uYWwgPSBmYWxzZSwgfSA9IHt9KSB7XHJcbiAgICAgICAgdGhpcy5uYW1lID0gbmFtZTtcclxuICAgICAgICB0aGlzLm9wdGlvbmFsID0gb3B0aW9uYWw7XHJcbiAgICB9XHJcbn1cblxuY2xhc3MgQ2hvaWNlIGV4dGVuZHMgQW55IHtcclxuICAgIGNvbnN0cnVjdG9yKHsgdmFsdWUgPSBbXSwgLi4ucGFyYW1ldGVycyB9ID0ge30pIHtcclxuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcclxuICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XHJcbiAgICB9XHJcbn1cblxuY2xhc3MgUmVwZWF0ZWQgZXh0ZW5kcyBBbnkge1xyXG4gICAgY29uc3RydWN0b3IoeyB2YWx1ZSA9IG5ldyBBbnkoKSwgbG9jYWwgPSBmYWxzZSwgLi4ucGFyYW1ldGVycyB9ID0ge30pIHtcclxuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcclxuICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XHJcbiAgICAgICAgdGhpcy5sb2NhbCA9IGxvY2FsO1xyXG4gICAgfVxyXG59XG5cbmNsYXNzIFJhd0RhdGEge1xyXG4gICAgY29uc3RydWN0b3IoeyBkYXRhID0gRU1QVFlfVklFVyB9ID0ge30pIHtcclxuICAgICAgICB0aGlzLmRhdGFWaWV3ID0gcHZ0c3V0aWxzLkJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b1VpbnQ4QXJyYXkoZGF0YSk7XHJcbiAgICB9XHJcbiAgICBnZXQgZGF0YSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5kYXRhVmlldy5zbGljZSgpLmJ1ZmZlcjtcclxuICAgIH1cclxuICAgIHNldCBkYXRhKHZhbHVlKSB7XHJcbiAgICAgICAgdGhpcy5kYXRhVmlldyA9IHB2dHN1dGlscy5CdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9VaW50OEFycmF5KHZhbHVlKTtcclxuICAgIH1cclxuICAgIGZyb21CRVIoaW5wdXRCdWZmZXIsIGlucHV0T2Zmc2V0LCBpbnB1dExlbmd0aCkge1xyXG4gICAgICAgIGNvbnN0IGVuZExlbmd0aCA9IGlucHV0T2Zmc2V0ICsgaW5wdXRMZW5ndGg7XHJcbiAgICAgICAgdGhpcy5kYXRhVmlldyA9IHB2dHN1dGlscy5CdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9VaW50OEFycmF5KGlucHV0QnVmZmVyKS5zdWJhcnJheShpbnB1dE9mZnNldCwgZW5kTGVuZ3RoKTtcclxuICAgICAgICByZXR1cm4gZW5kTGVuZ3RoO1xyXG4gICAgfVxyXG4gICAgdG9CRVIoc2l6ZU9ubHkpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5kYXRhVmlldy5zbGljZSgpLmJ1ZmZlcjtcclxuICAgIH1cclxufVxuXG5mdW5jdGlvbiBjb21wYXJlU2NoZW1hKHJvb3QsIGlucHV0RGF0YSwgaW5wdXRTY2hlbWEpIHtcclxuICAgIGlmIChpbnB1dFNjaGVtYSBpbnN0YW5jZW9mIENob2ljZSkge1xyXG4gICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgaW5wdXRTY2hlbWEudmFsdWUubGVuZ3RoOyBqKyspIHtcclxuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gY29tcGFyZVNjaGVtYShyb290LCBpbnB1dERhdGEsIGlucHV0U2NoZW1hLnZhbHVlW2pdKTtcclxuICAgICAgICAgICAgaWYgKHJlc3VsdC52ZXJpZmllZCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICB2ZXJpZmllZDogdHJ1ZSxcclxuICAgICAgICAgICAgICAgICAgICByZXN1bHQ6IHJvb3RcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAge1xyXG4gICAgICAgICAgICBjb25zdCBfcmVzdWx0ID0ge1xyXG4gICAgICAgICAgICAgICAgdmVyaWZpZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgcmVzdWx0OiB7XHJcbiAgICAgICAgICAgICAgICAgICAgZXJyb3I6IFwiV3JvbmcgdmFsdWVzIGZvciBDaG9pY2UgdHlwZVwiXHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBpZiAoaW5wdXRTY2hlbWEuaGFzT3duUHJvcGVydHkoTkFNRSkpXHJcbiAgICAgICAgICAgICAgICBfcmVzdWx0Lm5hbWUgPSBpbnB1dFNjaGVtYS5uYW1lO1xyXG4gICAgICAgICAgICByZXR1cm4gX3Jlc3VsdDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAoaW5wdXRTY2hlbWEgaW5zdGFuY2VvZiBBbnkpIHtcclxuICAgICAgICBpZiAoaW5wdXRTY2hlbWEuaGFzT3duUHJvcGVydHkoTkFNRSkpXHJcbiAgICAgICAgICAgIHJvb3RbaW5wdXRTY2hlbWEubmFtZV0gPSBpbnB1dERhdGE7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgdmVyaWZpZWQ6IHRydWUsXHJcbiAgICAgICAgICAgIHJlc3VsdDogcm9vdFxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbiAgICBpZiAoKHJvb3QgaW5zdGFuY2VvZiBPYmplY3QpID09PSBmYWxzZSkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIHZlcmlmaWVkOiBmYWxzZSxcclxuICAgICAgICAgICAgcmVzdWx0OiB7IGVycm9yOiBcIldyb25nIHJvb3Qgb2JqZWN0XCIgfVxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbiAgICBpZiAoKGlucHV0RGF0YSBpbnN0YW5jZW9mIE9iamVjdCkgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgdmVyaWZpZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICByZXN1bHQ6IHsgZXJyb3I6IFwiV3JvbmcgQVNOLjEgZGF0YVwiIH1cclxuICAgICAgICB9O1xyXG4gICAgfVxyXG4gICAgaWYgKChpbnB1dFNjaGVtYSBpbnN0YW5jZW9mIE9iamVjdCkgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgdmVyaWZpZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICByZXN1bHQ6IHsgZXJyb3I6IFwiV3JvbmcgQVNOLjEgc2NoZW1hXCIgfVxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbiAgICBpZiAoKElEX0JMT0NLIGluIGlucHV0U2NoZW1hKSA9PT0gZmFsc2UpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICB2ZXJpZmllZDogZmFsc2UsXHJcbiAgICAgICAgICAgIHJlc3VsdDogeyBlcnJvcjogXCJXcm9uZyBBU04uMSBzY2hlbWFcIiB9XHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuICAgIGlmICgoRlJPTV9CRVIgaW4gaW5wdXRTY2hlbWEuaWRCbG9jaykgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgdmVyaWZpZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICByZXN1bHQ6IHsgZXJyb3I6IFwiV3JvbmcgQVNOLjEgc2NoZW1hXCIgfVxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbiAgICBpZiAoKFRPX0JFUiBpbiBpbnB1dFNjaGVtYS5pZEJsb2NrKSA9PT0gZmFsc2UpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICB2ZXJpZmllZDogZmFsc2UsXHJcbiAgICAgICAgICAgIHJlc3VsdDogeyBlcnJvcjogXCJXcm9uZyBBU04uMSBzY2hlbWFcIiB9XHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuICAgIGNvbnN0IGVuY29kZWRJZCA9IGlucHV0U2NoZW1hLmlkQmxvY2sudG9CRVIoZmFsc2UpO1xyXG4gICAgaWYgKGVuY29kZWRJZC5ieXRlTGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgdmVyaWZpZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICByZXN1bHQ6IHsgZXJyb3I6IFwiRXJyb3IgZW5jb2RpbmcgaWRCbG9jayBmb3IgQVNOLjEgc2NoZW1hXCIgfVxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbiAgICBjb25zdCBkZWNvZGVkT2Zmc2V0ID0gaW5wdXRTY2hlbWEuaWRCbG9jay5mcm9tQkVSKGVuY29kZWRJZCwgMCwgZW5jb2RlZElkLmJ5dGVMZW5ndGgpO1xyXG4gICAgaWYgKGRlY29kZWRPZmZzZXQgPT09IC0xKSB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgdmVyaWZpZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICByZXN1bHQ6IHsgZXJyb3I6IFwiRXJyb3IgZGVjb2RpbmcgaWRCbG9jayBmb3IgQVNOLjEgc2NoZW1hXCIgfVxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbiAgICBpZiAoaW5wdXRTY2hlbWEuaWRCbG9jay5oYXNPd25Qcm9wZXJ0eShUQUdfQ0xBU1MpID09PSBmYWxzZSkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIHZlcmlmaWVkOiBmYWxzZSxcclxuICAgICAgICAgICAgcmVzdWx0OiB7IGVycm9yOiBcIldyb25nIEFTTi4xIHNjaGVtYVwiIH1cclxuICAgICAgICB9O1xyXG4gICAgfVxyXG4gICAgaWYgKGlucHV0U2NoZW1hLmlkQmxvY2sudGFnQ2xhc3MgIT09IGlucHV0RGF0YS5pZEJsb2NrLnRhZ0NsYXNzKSB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgdmVyaWZpZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICByZXN1bHQ6IHJvb3RcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG4gICAgaWYgKGlucHV0U2NoZW1hLmlkQmxvY2suaGFzT3duUHJvcGVydHkoVEFHX05VTUJFUikgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgdmVyaWZpZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICByZXN1bHQ6IHsgZXJyb3I6IFwiV3JvbmcgQVNOLjEgc2NoZW1hXCIgfVxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbiAgICBpZiAoaW5wdXRTY2hlbWEuaWRCbG9jay50YWdOdW1iZXIgIT09IGlucHV0RGF0YS5pZEJsb2NrLnRhZ051bWJlcikge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIHZlcmlmaWVkOiBmYWxzZSxcclxuICAgICAgICAgICAgcmVzdWx0OiByb290XHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuICAgIGlmIChpbnB1dFNjaGVtYS5pZEJsb2NrLmhhc093blByb3BlcnR5KElTX0NPTlNUUlVDVEVEKSA9PT0gZmFsc2UpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICB2ZXJpZmllZDogZmFsc2UsXHJcbiAgICAgICAgICAgIHJlc3VsdDogeyBlcnJvcjogXCJXcm9uZyBBU04uMSBzY2hlbWFcIiB9XHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuICAgIGlmIChpbnB1dFNjaGVtYS5pZEJsb2NrLmlzQ29uc3RydWN0ZWQgIT09IGlucHV0RGF0YS5pZEJsb2NrLmlzQ29uc3RydWN0ZWQpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICB2ZXJpZmllZDogZmFsc2UsXHJcbiAgICAgICAgICAgIHJlc3VsdDogcm9vdFxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbiAgICBpZiAoIShJU19IRVhfT05MWSBpbiBpbnB1dFNjaGVtYS5pZEJsb2NrKSkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIHZlcmlmaWVkOiBmYWxzZSxcclxuICAgICAgICAgICAgcmVzdWx0OiB7IGVycm9yOiBcIldyb25nIEFTTi4xIHNjaGVtYVwiIH1cclxuICAgICAgICB9O1xyXG4gICAgfVxyXG4gICAgaWYgKGlucHV0U2NoZW1hLmlkQmxvY2suaXNIZXhPbmx5ICE9PSBpbnB1dERhdGEuaWRCbG9jay5pc0hleE9ubHkpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICB2ZXJpZmllZDogZmFsc2UsXHJcbiAgICAgICAgICAgIHJlc3VsdDogcm9vdFxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbiAgICBpZiAoaW5wdXRTY2hlbWEuaWRCbG9jay5pc0hleE9ubHkpIHtcclxuICAgICAgICBpZiAoKFZBTFVFX0hFWF9WSUVXIGluIGlucHV0U2NoZW1hLmlkQmxvY2spID09PSBmYWxzZSkge1xyXG4gICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgdmVyaWZpZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgcmVzdWx0OiB7IGVycm9yOiBcIldyb25nIEFTTi4xIHNjaGVtYVwiIH1cclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3Qgc2NoZW1hVmlldyA9IGlucHV0U2NoZW1hLmlkQmxvY2sudmFsdWVIZXhWaWV3O1xyXG4gICAgICAgIGNvbnN0IGFzbjFWaWV3ID0gaW5wdXREYXRhLmlkQmxvY2sudmFsdWVIZXhWaWV3O1xyXG4gICAgICAgIGlmIChzY2hlbWFWaWV3Lmxlbmd0aCAhPT0gYXNuMVZpZXcubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICB2ZXJpZmllZDogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICByZXN1bHQ6IHJvb3RcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzY2hlbWFWaWV3Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmIChzY2hlbWFWaWV3W2ldICE9PSBhc24xVmlld1sxXSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICB2ZXJpZmllZDogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0OiByb290XHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKGlucHV0U2NoZW1hLm5hbWUpIHtcclxuICAgICAgICBpbnB1dFNjaGVtYS5uYW1lID0gaW5wdXRTY2hlbWEubmFtZS5yZXBsYWNlKC9eXFxzK3xcXHMrJC9nLCBFTVBUWV9TVFJJTkcpO1xyXG4gICAgICAgIGlmIChpbnB1dFNjaGVtYS5uYW1lKVxyXG4gICAgICAgICAgICByb290W2lucHV0U2NoZW1hLm5hbWVdID0gaW5wdXREYXRhO1xyXG4gICAgfVxyXG4gICAgaWYgKGlucHV0U2NoZW1hIGluc3RhbmNlb2YgdHlwZVN0b3JlLkNvbnN0cnVjdGVkKSB7XHJcbiAgICAgICAgbGV0IGFkbWlzc2lvbiA9IDA7XHJcbiAgICAgICAgbGV0IHJlc3VsdCA9IHtcclxuICAgICAgICAgICAgdmVyaWZpZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICByZXN1bHQ6IHtcclxuICAgICAgICAgICAgICAgIGVycm9yOiBcIlVua25vd24gZXJyb3JcIixcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgbGV0IG1heExlbmd0aCA9IGlucHV0U2NoZW1hLnZhbHVlQmxvY2sudmFsdWUubGVuZ3RoO1xyXG4gICAgICAgIGlmIChtYXhMZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgIGlmIChpbnB1dFNjaGVtYS52YWx1ZUJsb2NrLnZhbHVlWzBdIGluc3RhbmNlb2YgUmVwZWF0ZWQpIHtcclxuICAgICAgICAgICAgICAgIG1heExlbmd0aCA9IGlucHV0RGF0YS52YWx1ZUJsb2NrLnZhbHVlLmxlbmd0aDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAobWF4TGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICB2ZXJpZmllZDogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIHJlc3VsdDogcm9vdFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoKGlucHV0RGF0YS52YWx1ZUJsb2NrLnZhbHVlLmxlbmd0aCA9PT0gMCkgJiZcclxuICAgICAgICAgICAgKGlucHV0U2NoZW1hLnZhbHVlQmxvY2sudmFsdWUubGVuZ3RoICE9PSAwKSkge1xyXG4gICAgICAgICAgICBsZXQgX29wdGlvbmFsID0gdHJ1ZTtcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbnB1dFNjaGVtYS52YWx1ZUJsb2NrLnZhbHVlLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgICAgICAgICAgX29wdGlvbmFsID0gX29wdGlvbmFsICYmIChpbnB1dFNjaGVtYS52YWx1ZUJsb2NrLnZhbHVlW2ldLm9wdGlvbmFsIHx8IGZhbHNlKTtcclxuICAgICAgICAgICAgaWYgKF9vcHRpb25hbCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICB2ZXJpZmllZDogdHJ1ZSxcclxuICAgICAgICAgICAgICAgICAgICByZXN1bHQ6IHJvb3RcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGlucHV0U2NoZW1hLm5hbWUpIHtcclxuICAgICAgICAgICAgICAgIGlucHV0U2NoZW1hLm5hbWUgPSBpbnB1dFNjaGVtYS5uYW1lLnJlcGxhY2UoL15cXHMrfFxccyskL2csIEVNUFRZX1NUUklORyk7XHJcbiAgICAgICAgICAgICAgICBpZiAoaW5wdXRTY2hlbWEubmFtZSlcclxuICAgICAgICAgICAgICAgICAgICBkZWxldGUgcm9vdFtpbnB1dFNjaGVtYS5uYW1lXTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByb290LmVycm9yID0gXCJJbmNvbnNpc3RlbnQgb2JqZWN0IGxlbmd0aFwiO1xyXG4gICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgdmVyaWZpZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgcmVzdWx0OiByb290XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbWF4TGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgaWYgKChpIC0gYWRtaXNzaW9uKSA+PSBpbnB1dERhdGEudmFsdWVCbG9jay52YWx1ZS5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgIGlmIChpbnB1dFNjaGVtYS52YWx1ZUJsb2NrLnZhbHVlW2ldLm9wdGlvbmFsID09PSBmYWxzZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9yZXN1bHQgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZlcmlmaWVkOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0OiByb290XHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICByb290LmVycm9yID0gXCJJbmNvbnNpc3RlbnQgbGVuZ3RoIGJldHdlZW4gQVNOLjEgZGF0YSBhbmQgc2NoZW1hXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlucHV0U2NoZW1hLm5hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRTY2hlbWEubmFtZSA9IGlucHV0U2NoZW1hLm5hbWUucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgRU1QVFlfU1RSSU5HKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlucHV0U2NoZW1hLm5hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSByb290W2lucHV0U2NoZW1hLm5hbWVdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3Jlc3VsdC5uYW1lID0gaW5wdXRTY2hlbWEubmFtZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3Jlc3VsdDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGlmIChpbnB1dFNjaGVtYS52YWx1ZUJsb2NrLnZhbHVlWzBdIGluc3RhbmNlb2YgUmVwZWF0ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBjb21wYXJlU2NoZW1hKHJvb3QsIGlucHV0RGF0YS52YWx1ZUJsb2NrLnZhbHVlW2ldLCBpbnB1dFNjaGVtYS52YWx1ZUJsb2NrLnZhbHVlWzBdLnZhbHVlKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0LnZlcmlmaWVkID09PSBmYWxzZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5wdXRTY2hlbWEudmFsdWVCbG9jay52YWx1ZVswXS5vcHRpb25hbClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkbWlzc2lvbisrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbnB1dFNjaGVtYS5uYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRTY2hlbWEubmFtZSA9IGlucHV0U2NoZW1hLm5hbWUucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgRU1QVFlfU1RSSU5HKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5wdXRTY2hlbWEubmFtZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHJvb3RbaW5wdXRTY2hlbWEubmFtZV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICgoTkFNRSBpbiBpbnB1dFNjaGVtYS52YWx1ZUJsb2NrLnZhbHVlWzBdKSAmJiAoaW5wdXRTY2hlbWEudmFsdWVCbG9jay52YWx1ZVswXS5uYW1lLmxlbmd0aCA+IDApKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBhcnJheVJvb3QgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChMT0NBTCBpbiBpbnB1dFNjaGVtYS52YWx1ZUJsb2NrLnZhbHVlWzBdKSAmJiAoaW5wdXRTY2hlbWEudmFsdWVCbG9jay52YWx1ZVswXS5sb2NhbCkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJheVJvb3QgPSBpbnB1dERhdGE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5Um9vdCA9IHJvb3Q7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgYXJyYXlSb290W2lucHV0U2NoZW1hLnZhbHVlQmxvY2sudmFsdWVbMF0ubmFtZV0gPT09IFwidW5kZWZpbmVkXCIpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJheVJvb3RbaW5wdXRTY2hlbWEudmFsdWVCbG9jay52YWx1ZVswXS5uYW1lXSA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhcnJheVJvb3RbaW5wdXRTY2hlbWEudmFsdWVCbG9jay52YWx1ZVswXS5uYW1lXS5wdXNoKGlucHV0RGF0YS52YWx1ZUJsb2NrLnZhbHVlW2ldKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBjb21wYXJlU2NoZW1hKHJvb3QsIGlucHV0RGF0YS52YWx1ZUJsb2NrLnZhbHVlW2kgLSBhZG1pc3Npb25dLCBpbnB1dFNjaGVtYS52YWx1ZUJsb2NrLnZhbHVlW2ldKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0LnZlcmlmaWVkID09PSBmYWxzZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5wdXRTY2hlbWEudmFsdWVCbG9jay52YWx1ZVtpXS5vcHRpb25hbClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkbWlzc2lvbisrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbnB1dFNjaGVtYS5uYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRTY2hlbWEubmFtZSA9IGlucHV0U2NoZW1hLm5hbWUucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgRU1QVFlfU1RSSU5HKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5wdXRTY2hlbWEubmFtZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHJvb3RbaW5wdXRTY2hlbWEubmFtZV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChyZXN1bHQudmVyaWZpZWQgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IF9yZXN1bHQgPSB7XHJcbiAgICAgICAgICAgICAgICB2ZXJpZmllZDogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICByZXN1bHQ6IHJvb3RcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgaWYgKGlucHV0U2NoZW1hLm5hbWUpIHtcclxuICAgICAgICAgICAgICAgIGlucHV0U2NoZW1hLm5hbWUgPSBpbnB1dFNjaGVtYS5uYW1lLnJlcGxhY2UoL15cXHMrfFxccyskL2csIEVNUFRZX1NUUklORyk7XHJcbiAgICAgICAgICAgICAgICBpZiAoaW5wdXRTY2hlbWEubmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSByb290W2lucHV0U2NoZW1hLm5hbWVdO1xyXG4gICAgICAgICAgICAgICAgICAgIF9yZXN1bHQubmFtZSA9IGlucHV0U2NoZW1hLm5hbWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIF9yZXN1bHQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIHZlcmlmaWVkOiB0cnVlLFxyXG4gICAgICAgICAgICByZXN1bHQ6IHJvb3RcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG4gICAgaWYgKGlucHV0U2NoZW1hLnByaW1pdGl2ZVNjaGVtYSAmJlxyXG4gICAgICAgIChWQUxVRV9IRVhfVklFVyBpbiBpbnB1dERhdGEudmFsdWVCbG9jaykpIHtcclxuICAgICAgICBjb25zdCBhc24xID0gbG9jYWxGcm9tQkVSKGlucHV0RGF0YS52YWx1ZUJsb2NrLnZhbHVlSGV4Vmlldyk7XHJcbiAgICAgICAgaWYgKGFzbjEub2Zmc2V0ID09PSAtMSkge1xyXG4gICAgICAgICAgICBjb25zdCBfcmVzdWx0ID0ge1xyXG4gICAgICAgICAgICAgICAgdmVyaWZpZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgcmVzdWx0OiBhc24xLnJlc3VsdFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBpZiAoaW5wdXRTY2hlbWEubmFtZSkge1xyXG4gICAgICAgICAgICAgICAgaW5wdXRTY2hlbWEubmFtZSA9IGlucHV0U2NoZW1hLm5hbWUucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgRU1QVFlfU1RSSU5HKTtcclxuICAgICAgICAgICAgICAgIGlmIChpbnB1dFNjaGVtYS5uYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHJvb3RbaW5wdXRTY2hlbWEubmFtZV07XHJcbiAgICAgICAgICAgICAgICAgICAgX3Jlc3VsdC5uYW1lID0gaW5wdXRTY2hlbWEubmFtZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gX3Jlc3VsdDtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGNvbXBhcmVTY2hlbWEocm9vdCwgYXNuMS5yZXN1bHQsIGlucHV0U2NoZW1hLnByaW1pdGl2ZVNjaGVtYSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIHZlcmlmaWVkOiB0cnVlLFxyXG4gICAgICAgIHJlc3VsdDogcm9vdFxyXG4gICAgfTtcclxufVxyXG5mdW5jdGlvbiB2ZXJpZnlTY2hlbWEoaW5wdXRCdWZmZXIsIGlucHV0U2NoZW1hKSB7XHJcbiAgICBpZiAoKGlucHV0U2NoZW1hIGluc3RhbmNlb2YgT2JqZWN0KSA9PT0gZmFsc2UpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICB2ZXJpZmllZDogZmFsc2UsXHJcbiAgICAgICAgICAgIHJlc3VsdDogeyBlcnJvcjogXCJXcm9uZyBBU04uMSBzY2hlbWEgdHlwZVwiIH1cclxuICAgICAgICB9O1xyXG4gICAgfVxyXG4gICAgY29uc3QgYXNuMSA9IGxvY2FsRnJvbUJFUihwdnRzdXRpbHMuQnVmZmVyU291cmNlQ29udmVydGVyLnRvVWludDhBcnJheShpbnB1dEJ1ZmZlcikpO1xyXG4gICAgaWYgKGFzbjEub2Zmc2V0ID09PSAtMSkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIHZlcmlmaWVkOiBmYWxzZSxcclxuICAgICAgICAgICAgcmVzdWx0OiBhc24xLnJlc3VsdFxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbiAgICByZXR1cm4gY29tcGFyZVNjaGVtYShhc24xLnJlc3VsdCwgYXNuMS5yZXN1bHQsIGlucHV0U2NoZW1hKTtcclxufVxuXG5leHBvcnQgeyBBbnksIEJhc2VCbG9jaywgQmFzZVN0cmluZ0Jsb2NrLCBCaXRTdHJpbmcsIEJtcFN0cmluZywgQm9vbGVhbiwgQ2hhcmFjdGVyU3RyaW5nLCBDaG9pY2UsIENvbnN0cnVjdGVkLCBEQVRFLCBEYXRlVGltZSwgRHVyYXRpb24sIEVuZE9mQ29udGVudCwgRW51bWVyYXRlZCwgR2VuZXJhbFN0cmluZywgR2VuZXJhbGl6ZWRUaW1lLCBHcmFwaGljU3RyaW5nLCBIZXhCbG9jaywgSUE1U3RyaW5nLCBJbnRlZ2VyLCBOdWxsLCBOdW1lcmljU3RyaW5nLCBPYmplY3RJZGVudGlmaWVyLCBPY3RldFN0cmluZywgUHJpbWl0aXZlLCBQcmludGFibGVTdHJpbmcsIFJhd0RhdGEsIFJlbGF0aXZlT2JqZWN0SWRlbnRpZmllciwgUmVwZWF0ZWQsIFNlcXVlbmNlLCBTZXQsIFRJTUUsIFRlbGV0ZXhTdHJpbmcsIFRpbWVPZkRheSwgVVRDVGltZSwgVW5pdmVyc2FsU3RyaW5nLCBVdGY4U3RyaW5nLCBWYWx1ZUJsb2NrLCBWaWRlb3RleFN0cmluZywgVmlld1dyaXRlciwgVmlzaWJsZVN0cmluZywgY29tcGFyZVNjaGVtYSwgZnJvbUJFUiwgdmVyaWZ5U2NoZW1hIH07XG4iLCAiZXhwb3J0IHZhciBBc25UeXBlVHlwZXM7XG4oZnVuY3Rpb24gKEFzblR5cGVUeXBlcykge1xuICAgIEFzblR5cGVUeXBlc1tBc25UeXBlVHlwZXNbXCJTZXF1ZW5jZVwiXSA9IDBdID0gXCJTZXF1ZW5jZVwiO1xuICAgIEFzblR5cGVUeXBlc1tBc25UeXBlVHlwZXNbXCJTZXRcIl0gPSAxXSA9IFwiU2V0XCI7XG4gICAgQXNuVHlwZVR5cGVzW0FzblR5cGVUeXBlc1tcIkNob2ljZVwiXSA9IDJdID0gXCJDaG9pY2VcIjtcbn0pKEFzblR5cGVUeXBlcyB8fCAoQXNuVHlwZVR5cGVzID0ge30pKTtcbmV4cG9ydCB2YXIgQXNuUHJvcFR5cGVzO1xuKGZ1bmN0aW9uIChBc25Qcm9wVHlwZXMpIHtcbiAgICBBc25Qcm9wVHlwZXNbQXNuUHJvcFR5cGVzW1wiQW55XCJdID0gMV0gPSBcIkFueVwiO1xuICAgIEFzblByb3BUeXBlc1tBc25Qcm9wVHlwZXNbXCJCb29sZWFuXCJdID0gMl0gPSBcIkJvb2xlYW5cIjtcbiAgICBBc25Qcm9wVHlwZXNbQXNuUHJvcFR5cGVzW1wiT2N0ZXRTdHJpbmdcIl0gPSAzXSA9IFwiT2N0ZXRTdHJpbmdcIjtcbiAgICBBc25Qcm9wVHlwZXNbQXNuUHJvcFR5cGVzW1wiQml0U3RyaW5nXCJdID0gNF0gPSBcIkJpdFN0cmluZ1wiO1xuICAgIEFzblByb3BUeXBlc1tBc25Qcm9wVHlwZXNbXCJJbnRlZ2VyXCJdID0gNV0gPSBcIkludGVnZXJcIjtcbiAgICBBc25Qcm9wVHlwZXNbQXNuUHJvcFR5cGVzW1wiRW51bWVyYXRlZFwiXSA9IDZdID0gXCJFbnVtZXJhdGVkXCI7XG4gICAgQXNuUHJvcFR5cGVzW0FzblByb3BUeXBlc1tcIk9iamVjdElkZW50aWZpZXJcIl0gPSA3XSA9IFwiT2JqZWN0SWRlbnRpZmllclwiO1xuICAgIEFzblByb3BUeXBlc1tBc25Qcm9wVHlwZXNbXCJVdGY4U3RyaW5nXCJdID0gOF0gPSBcIlV0ZjhTdHJpbmdcIjtcbiAgICBBc25Qcm9wVHlwZXNbQXNuUHJvcFR5cGVzW1wiQm1wU3RyaW5nXCJdID0gOV0gPSBcIkJtcFN0cmluZ1wiO1xuICAgIEFzblByb3BUeXBlc1tBc25Qcm9wVHlwZXNbXCJVbml2ZXJzYWxTdHJpbmdcIl0gPSAxMF0gPSBcIlVuaXZlcnNhbFN0cmluZ1wiO1xuICAgIEFzblByb3BUeXBlc1tBc25Qcm9wVHlwZXNbXCJOdW1lcmljU3RyaW5nXCJdID0gMTFdID0gXCJOdW1lcmljU3RyaW5nXCI7XG4gICAgQXNuUHJvcFR5cGVzW0FzblByb3BUeXBlc1tcIlByaW50YWJsZVN0cmluZ1wiXSA9IDEyXSA9IFwiUHJpbnRhYmxlU3RyaW5nXCI7XG4gICAgQXNuUHJvcFR5cGVzW0FzblByb3BUeXBlc1tcIlRlbGV0ZXhTdHJpbmdcIl0gPSAxM10gPSBcIlRlbGV0ZXhTdHJpbmdcIjtcbiAgICBBc25Qcm9wVHlwZXNbQXNuUHJvcFR5cGVzW1wiVmlkZW90ZXhTdHJpbmdcIl0gPSAxNF0gPSBcIlZpZGVvdGV4U3RyaW5nXCI7XG4gICAgQXNuUHJvcFR5cGVzW0FzblByb3BUeXBlc1tcIklBNVN0cmluZ1wiXSA9IDE1XSA9IFwiSUE1U3RyaW5nXCI7XG4gICAgQXNuUHJvcFR5cGVzW0FzblByb3BUeXBlc1tcIkdyYXBoaWNTdHJpbmdcIl0gPSAxNl0gPSBcIkdyYXBoaWNTdHJpbmdcIjtcbiAgICBBc25Qcm9wVHlwZXNbQXNuUHJvcFR5cGVzW1wiVmlzaWJsZVN0cmluZ1wiXSA9IDE3XSA9IFwiVmlzaWJsZVN0cmluZ1wiO1xuICAgIEFzblByb3BUeXBlc1tBc25Qcm9wVHlwZXNbXCJHZW5lcmFsU3RyaW5nXCJdID0gMThdID0gXCJHZW5lcmFsU3RyaW5nXCI7XG4gICAgQXNuUHJvcFR5cGVzW0FzblByb3BUeXBlc1tcIkNoYXJhY3RlclN0cmluZ1wiXSA9IDE5XSA9IFwiQ2hhcmFjdGVyU3RyaW5nXCI7XG4gICAgQXNuUHJvcFR5cGVzW0FzblByb3BUeXBlc1tcIlVUQ1RpbWVcIl0gPSAyMF0gPSBcIlVUQ1RpbWVcIjtcbiAgICBBc25Qcm9wVHlwZXNbQXNuUHJvcFR5cGVzW1wiR2VuZXJhbGl6ZWRUaW1lXCJdID0gMjFdID0gXCJHZW5lcmFsaXplZFRpbWVcIjtcbiAgICBBc25Qcm9wVHlwZXNbQXNuUHJvcFR5cGVzW1wiREFURVwiXSA9IDIyXSA9IFwiREFURVwiO1xuICAgIEFzblByb3BUeXBlc1tBc25Qcm9wVHlwZXNbXCJUaW1lT2ZEYXlcIl0gPSAyM10gPSBcIlRpbWVPZkRheVwiO1xuICAgIEFzblByb3BUeXBlc1tBc25Qcm9wVHlwZXNbXCJEYXRlVGltZVwiXSA9IDI0XSA9IFwiRGF0ZVRpbWVcIjtcbiAgICBBc25Qcm9wVHlwZXNbQXNuUHJvcFR5cGVzW1wiRHVyYXRpb25cIl0gPSAyNV0gPSBcIkR1cmF0aW9uXCI7XG4gICAgQXNuUHJvcFR5cGVzW0FzblByb3BUeXBlc1tcIlRJTUVcIl0gPSAyNl0gPSBcIlRJTUVcIjtcbiAgICBBc25Qcm9wVHlwZXNbQXNuUHJvcFR5cGVzW1wiTnVsbFwiXSA9IDI3XSA9IFwiTnVsbFwiO1xufSkoQXNuUHJvcFR5cGVzIHx8IChBc25Qcm9wVHlwZXMgPSB7fSkpO1xuIiwgImltcG9ydCAqIGFzIGFzbjFqcyBmcm9tIFwiYXNuMWpzXCI7XG5pbXBvcnQgeyBCdWZmZXJTb3VyY2VDb252ZXJ0ZXIgfSBmcm9tIFwicHZ0c3V0aWxzXCI7XG5leHBvcnQgY2xhc3MgQml0U3RyaW5nIHtcbiAgICBjb25zdHJ1Y3RvcihwYXJhbXMsIHVudXNlZEJpdHMgPSAwKSB7XG4gICAgICAgIHRoaXMudW51c2VkQml0cyA9IDA7XG4gICAgICAgIHRoaXMudmFsdWUgPSBuZXcgQXJyYXlCdWZmZXIoMCk7XG4gICAgICAgIGlmIChwYXJhbXMpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgcGFyYW1zID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5mcm9tTnVtYmVyKHBhcmFtcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChCdWZmZXJTb3VyY2VDb252ZXJ0ZXIuaXNCdWZmZXJTb3VyY2UocGFyYW1zKSkge1xuICAgICAgICAgICAgICAgIHRoaXMudW51c2VkQml0cyA9IHVudXNlZEJpdHM7XG4gICAgICAgICAgICAgICAgdGhpcy52YWx1ZSA9IEJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b0FycmF5QnVmZmVyKHBhcmFtcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJVbnN1cHBvcnRlZCB0eXBlIG9mICdwYXJhbXMnIGFyZ3VtZW50IGZvciBCaXRTdHJpbmdcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgZnJvbUFTTihhc24pIHtcbiAgICAgICAgaWYgKCEoYXNuIGluc3RhbmNlb2YgYXNuMWpzLkJpdFN0cmluZykpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJBcmd1bWVudCAnYXNuJyBpcyBub3QgaW5zdGFuY2Ugb2YgQVNOLjEgQml0U3RyaW5nXCIpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudW51c2VkQml0cyA9IGFzbi52YWx1ZUJsb2NrLnVudXNlZEJpdHM7XG4gICAgICAgIHRoaXMudmFsdWUgPSBhc24udmFsdWVCbG9jay52YWx1ZUhleDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHRvQVNOKCkge1xuICAgICAgICByZXR1cm4gbmV3IGFzbjFqcy5CaXRTdHJpbmcoeyB1bnVzZWRCaXRzOiB0aGlzLnVudXNlZEJpdHMsIHZhbHVlSGV4OiB0aGlzLnZhbHVlIH0pO1xuICAgIH1cbiAgICB0b1NjaGVtYShuYW1lKSB7XG4gICAgICAgIHJldHVybiBuZXcgYXNuMWpzLkJpdFN0cmluZyh7IG5hbWUgfSk7XG4gICAgfVxuICAgIHRvTnVtYmVyKCkge1xuICAgICAgICBsZXQgcmVzID0gXCJcIjtcbiAgICAgICAgY29uc3QgdWludEFycmF5ID0gbmV3IFVpbnQ4QXJyYXkodGhpcy52YWx1ZSk7XG4gICAgICAgIGZvciAoY29uc3Qgb2N0ZXQgb2YgdWludEFycmF5KSB7XG4gICAgICAgICAgICByZXMgKz0gb2N0ZXQudG9TdHJpbmcoMikucGFkU3RhcnQoOCwgXCIwXCIpO1xuICAgICAgICB9XG4gICAgICAgIHJlcyA9IHJlcy5zcGxpdChcIlwiKS5yZXZlcnNlKCkuam9pbihcIlwiKTtcbiAgICAgICAgaWYgKHRoaXMudW51c2VkQml0cykge1xuICAgICAgICAgICAgcmVzID0gcmVzLnNsaWNlKHRoaXMudW51c2VkQml0cykucGFkU3RhcnQodGhpcy51bnVzZWRCaXRzLCBcIjBcIik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBhcnNlSW50KHJlcywgMik7XG4gICAgfVxuICAgIGZyb21OdW1iZXIodmFsdWUpIHtcbiAgICAgICAgbGV0IGJpdHMgPSB2YWx1ZS50b1N0cmluZygyKTtcbiAgICAgICAgY29uc3Qgb2N0ZXRTaXplID0gKGJpdHMubGVuZ3RoICsgNykgPj4gMztcbiAgICAgICAgdGhpcy51bnVzZWRCaXRzID0gKG9jdGV0U2l6ZSA8PCAzKSAtIGJpdHMubGVuZ3RoO1xuICAgICAgICBjb25zdCBvY3RldHMgPSBuZXcgVWludDhBcnJheShvY3RldFNpemUpO1xuICAgICAgICBiaXRzID0gYml0cy5wYWRTdGFydChvY3RldFNpemUgPDwgMywgXCIwXCIpLnNwbGl0KFwiXCIpLnJldmVyc2UoKS5qb2luKFwiXCIpO1xuICAgICAgICBsZXQgaW5kZXggPSAwO1xuICAgICAgICB3aGlsZSAoaW5kZXggPCBvY3RldFNpemUpIHtcbiAgICAgICAgICAgIG9jdGV0c1tpbmRleF0gPSBwYXJzZUludChiaXRzLnNsaWNlKGluZGV4IDw8IDMsIChpbmRleCA8PCAzKSArIDgpLCAyKTtcbiAgICAgICAgICAgIGluZGV4Kys7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy52YWx1ZSA9IG9jdGV0cy5idWZmZXI7XG4gICAgfVxufVxuIiwgImltcG9ydCAqIGFzIGFzbjFqcyBmcm9tIFwiYXNuMWpzXCI7XG5pbXBvcnQgeyBCdWZmZXJTb3VyY2VDb252ZXJ0ZXIgfSBmcm9tIFwicHZ0c3V0aWxzXCI7XG5leHBvcnQgY2xhc3MgT2N0ZXRTdHJpbmcge1xuICAgIGNvbnN0cnVjdG9yKHBhcmFtKSB7XG4gICAgICAgIGlmICh0eXBlb2YgcGFyYW0gPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgIHRoaXMuYnVmZmVyID0gbmV3IEFycmF5QnVmZmVyKHBhcmFtKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmIChCdWZmZXJTb3VyY2VDb252ZXJ0ZXIuaXNCdWZmZXJTb3VyY2UocGFyYW0pKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5idWZmZXIgPSBCdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9BcnJheUJ1ZmZlcihwYXJhbSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChBcnJheS5pc0FycmF5KHBhcmFtKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuYnVmZmVyID0gbmV3IFVpbnQ4QXJyYXkocGFyYW0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5idWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIoMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IGJ5dGVMZW5ndGgoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoO1xuICAgIH1cbiAgICBnZXQgYnl0ZU9mZnNldCgpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIGZyb21BU04oYXNuKSB7XG4gICAgICAgIGlmICghKGFzbiBpbnN0YW5jZW9mIGFzbjFqcy5PY3RldFN0cmluZykpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJBcmd1bWVudCAnYXNuJyBpcyBub3QgaW5zdGFuY2Ugb2YgQVNOLjEgT2N0ZXRTdHJpbmdcIik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5idWZmZXIgPSBhc24udmFsdWVCbG9jay52YWx1ZUhleDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHRvQVNOKCkge1xuICAgICAgICByZXR1cm4gbmV3IGFzbjFqcy5PY3RldFN0cmluZyh7IHZhbHVlSGV4OiB0aGlzLmJ1ZmZlciB9KTtcbiAgICB9XG4gICAgdG9TY2hlbWEobmFtZSkge1xuICAgICAgICByZXR1cm4gbmV3IGFzbjFqcy5PY3RldFN0cmluZyh7IG5hbWUgfSk7XG4gICAgfVxufVxuIiwgImV4cG9ydCAqIGZyb20gXCIuL2JpdF9zdHJpbmdcIjtcbmV4cG9ydCAqIGZyb20gXCIuL29jdGV0X3N0cmluZ1wiO1xuIiwgImltcG9ydCAqIGFzIGFzbjFqcyBmcm9tIFwiYXNuMWpzXCI7XG5pbXBvcnQgeyBBc25Qcm9wVHlwZXMgfSBmcm9tIFwiLi9lbnVtc1wiO1xuaW1wb3J0IHsgT2N0ZXRTdHJpbmcgfSBmcm9tIFwiLi90eXBlcy9pbmRleFwiO1xuZXhwb3J0IGNvbnN0IEFzbkFueUNvbnZlcnRlciA9IHtcbiAgICBmcm9tQVNOOiAodmFsdWUpID0+IHZhbHVlIGluc3RhbmNlb2YgYXNuMWpzLk51bGwgPyBudWxsIDogdmFsdWUudmFsdWVCZWZvcmVEZWNvZGVWaWV3LFxuICAgIHRvQVNOOiAodmFsdWUpID0+IHtcbiAgICAgICAgaWYgKHZhbHVlID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IGFzbjFqcy5OdWxsKCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc2NoZW1hID0gYXNuMWpzLmZyb21CRVIodmFsdWUpO1xuICAgICAgICBpZiAoc2NoZW1hLnJlc3VsdC5lcnJvcikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKHNjaGVtYS5yZXN1bHQuZXJyb3IpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzY2hlbWEucmVzdWx0O1xuICAgIH0sXG59O1xuZXhwb3J0IGNvbnN0IEFzbkludGVnZXJDb252ZXJ0ZXIgPSB7XG4gICAgZnJvbUFTTjogKHZhbHVlKSA9PiB2YWx1ZS52YWx1ZUJsb2NrLnZhbHVlSGV4Vmlldy5ieXRlTGVuZ3RoID49IDRcbiAgICAgICAgPyB2YWx1ZS52YWx1ZUJsb2NrLnRvU3RyaW5nKClcbiAgICAgICAgOiB2YWx1ZS52YWx1ZUJsb2NrLnZhbHVlRGVjLFxuICAgIHRvQVNOOiAodmFsdWUpID0+IG5ldyBhc24xanMuSW50ZWdlcih7IHZhbHVlOiArdmFsdWUgfSksXG59O1xuZXhwb3J0IGNvbnN0IEFzbkVudW1lcmF0ZWRDb252ZXJ0ZXIgPSB7XG4gICAgZnJvbUFTTjogKHZhbHVlKSA9PiB2YWx1ZS52YWx1ZUJsb2NrLnZhbHVlRGVjLFxuICAgIHRvQVNOOiAodmFsdWUpID0+IG5ldyBhc24xanMuRW51bWVyYXRlZCh7IHZhbHVlIH0pLFxufTtcbmV4cG9ydCBjb25zdCBBc25JbnRlZ2VyQXJyYXlCdWZmZXJDb252ZXJ0ZXIgPSB7XG4gICAgZnJvbUFTTjogKHZhbHVlKSA9PiB2YWx1ZS52YWx1ZUJsb2NrLnZhbHVlSGV4VmlldyxcbiAgICB0b0FTTjogKHZhbHVlKSA9PiBuZXcgYXNuMWpzLkludGVnZXIoeyB2YWx1ZUhleDogdmFsdWUgfSksXG59O1xuZXhwb3J0IGNvbnN0IEFzbkludGVnZXJCaWdJbnRDb252ZXJ0ZXIgPSB7XG4gICAgZnJvbUFTTjogKHZhbHVlKSA9PiB2YWx1ZS50b0JpZ0ludCgpLFxuICAgIHRvQVNOOiAodmFsdWUpID0+IGFzbjFqcy5JbnRlZ2VyLmZyb21CaWdJbnQodmFsdWUpLFxufTtcbmV4cG9ydCBjb25zdCBBc25CaXRTdHJpbmdDb252ZXJ0ZXIgPSB7XG4gICAgZnJvbUFTTjogKHZhbHVlKSA9PiB2YWx1ZS52YWx1ZUJsb2NrLnZhbHVlSGV4VmlldyxcbiAgICB0b0FTTjogKHZhbHVlKSA9PiBuZXcgYXNuMWpzLkJpdFN0cmluZyh7IHZhbHVlSGV4OiB2YWx1ZSB9KSxcbn07XG5leHBvcnQgY29uc3QgQXNuT2JqZWN0SWRlbnRpZmllckNvbnZlcnRlciA9IHtcbiAgICBmcm9tQVNOOiAodmFsdWUpID0+IHZhbHVlLnZhbHVlQmxvY2sudG9TdHJpbmcoKSxcbiAgICB0b0FTTjogKHZhbHVlKSA9PiBuZXcgYXNuMWpzLk9iamVjdElkZW50aWZpZXIoeyB2YWx1ZSB9KSxcbn07XG5leHBvcnQgY29uc3QgQXNuQm9vbGVhbkNvbnZlcnRlciA9IHtcbiAgICBmcm9tQVNOOiAodmFsdWUpID0+IHZhbHVlLnZhbHVlQmxvY2sudmFsdWUsXG4gICAgdG9BU046ICh2YWx1ZSkgPT4gbmV3IGFzbjFqcy5Cb29sZWFuKHsgdmFsdWUgfSksXG59O1xuZXhwb3J0IGNvbnN0IEFzbk9jdGV0U3RyaW5nQ29udmVydGVyID0ge1xuICAgIGZyb21BU046ICh2YWx1ZSkgPT4gdmFsdWUudmFsdWVCbG9jay52YWx1ZUhleFZpZXcsXG4gICAgdG9BU046ICh2YWx1ZSkgPT4gbmV3IGFzbjFqcy5PY3RldFN0cmluZyh7IHZhbHVlSGV4OiB2YWx1ZSB9KSxcbn07XG5leHBvcnQgY29uc3QgQXNuQ29uc3RydWN0ZWRPY3RldFN0cmluZ0NvbnZlcnRlciA9IHtcbiAgICBmcm9tQVNOOiAodmFsdWUpID0+IG5ldyBPY3RldFN0cmluZyh2YWx1ZS5nZXRWYWx1ZSgpKSxcbiAgICB0b0FTTjogKHZhbHVlKSA9PiB2YWx1ZS50b0FTTigpLFxufTtcbmZ1bmN0aW9uIGNyZWF0ZVN0cmluZ0NvbnZlcnRlcihBc24xVHlwZSkge1xuICAgIHJldHVybiB7XG4gICAgICAgIGZyb21BU046ICh2YWx1ZSkgPT4gdmFsdWUudmFsdWVCbG9jay52YWx1ZSxcbiAgICAgICAgdG9BU046ICh2YWx1ZSkgPT4gbmV3IEFzbjFUeXBlKHsgdmFsdWUgfSksXG4gICAgfTtcbn1cbmV4cG9ydCBjb25zdCBBc25VdGY4U3RyaW5nQ29udmVydGVyID0gY3JlYXRlU3RyaW5nQ29udmVydGVyKGFzbjFqcy5VdGY4U3RyaW5nKTtcbmV4cG9ydCBjb25zdCBBc25CbXBTdHJpbmdDb252ZXJ0ZXIgPSBjcmVhdGVTdHJpbmdDb252ZXJ0ZXIoYXNuMWpzLkJtcFN0cmluZyk7XG5leHBvcnQgY29uc3QgQXNuVW5pdmVyc2FsU3RyaW5nQ29udmVydGVyID0gY3JlYXRlU3RyaW5nQ29udmVydGVyKGFzbjFqcy5Vbml2ZXJzYWxTdHJpbmcpO1xuZXhwb3J0IGNvbnN0IEFzbk51bWVyaWNTdHJpbmdDb252ZXJ0ZXIgPSBjcmVhdGVTdHJpbmdDb252ZXJ0ZXIoYXNuMWpzLk51bWVyaWNTdHJpbmcpO1xuZXhwb3J0IGNvbnN0IEFzblByaW50YWJsZVN0cmluZ0NvbnZlcnRlciA9IGNyZWF0ZVN0cmluZ0NvbnZlcnRlcihhc24xanMuUHJpbnRhYmxlU3RyaW5nKTtcbmV4cG9ydCBjb25zdCBBc25UZWxldGV4U3RyaW5nQ29udmVydGVyID0gY3JlYXRlU3RyaW5nQ29udmVydGVyKGFzbjFqcy5UZWxldGV4U3RyaW5nKTtcbmV4cG9ydCBjb25zdCBBc25WaWRlb3RleFN0cmluZ0NvbnZlcnRlciA9IGNyZWF0ZVN0cmluZ0NvbnZlcnRlcihhc24xanMuVmlkZW90ZXhTdHJpbmcpO1xuZXhwb3J0IGNvbnN0IEFzbklBNVN0cmluZ0NvbnZlcnRlciA9IGNyZWF0ZVN0cmluZ0NvbnZlcnRlcihhc24xanMuSUE1U3RyaW5nKTtcbmV4cG9ydCBjb25zdCBBc25HcmFwaGljU3RyaW5nQ29udmVydGVyID0gY3JlYXRlU3RyaW5nQ29udmVydGVyKGFzbjFqcy5HcmFwaGljU3RyaW5nKTtcbmV4cG9ydCBjb25zdCBBc25WaXNpYmxlU3RyaW5nQ29udmVydGVyID0gY3JlYXRlU3RyaW5nQ29udmVydGVyKGFzbjFqcy5WaXNpYmxlU3RyaW5nKTtcbmV4cG9ydCBjb25zdCBBc25HZW5lcmFsU3RyaW5nQ29udmVydGVyID0gY3JlYXRlU3RyaW5nQ29udmVydGVyKGFzbjFqcy5HZW5lcmFsU3RyaW5nKTtcbmV4cG9ydCBjb25zdCBBc25DaGFyYWN0ZXJTdHJpbmdDb252ZXJ0ZXIgPSBjcmVhdGVTdHJpbmdDb252ZXJ0ZXIoYXNuMWpzLkNoYXJhY3RlclN0cmluZyk7XG5leHBvcnQgY29uc3QgQXNuVVRDVGltZUNvbnZlcnRlciA9IHtcbiAgICBmcm9tQVNOOiAodmFsdWUpID0+IHZhbHVlLnRvRGF0ZSgpLFxuICAgIHRvQVNOOiAodmFsdWUpID0+IG5ldyBhc24xanMuVVRDVGltZSh7IHZhbHVlRGF0ZTogdmFsdWUgfSksXG59O1xuZXhwb3J0IGNvbnN0IEFzbkdlbmVyYWxpemVkVGltZUNvbnZlcnRlciA9IHtcbiAgICBmcm9tQVNOOiAodmFsdWUpID0+IHZhbHVlLnRvRGF0ZSgpLFxuICAgIHRvQVNOOiAodmFsdWUpID0+IG5ldyBhc24xanMuR2VuZXJhbGl6ZWRUaW1lKHsgdmFsdWVEYXRlOiB2YWx1ZSB9KSxcbn07XG5leHBvcnQgY29uc3QgQXNuTnVsbENvbnZlcnRlciA9IHtcbiAgICBmcm9tQVNOOiAoKSA9PiBudWxsLFxuICAgIHRvQVNOOiAoKSA9PiB7XG4gICAgICAgIHJldHVybiBuZXcgYXNuMWpzLk51bGwoKTtcbiAgICB9LFxufTtcbmV4cG9ydCBmdW5jdGlvbiBkZWZhdWx0Q29udmVydGVyKHR5cGUpIHtcbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgY2FzZSBBc25Qcm9wVHlwZXMuQW55OlxuICAgICAgICAgICAgcmV0dXJuIEFzbkFueUNvbnZlcnRlcjtcbiAgICAgICAgY2FzZSBBc25Qcm9wVHlwZXMuQml0U3RyaW5nOlxuICAgICAgICAgICAgcmV0dXJuIEFzbkJpdFN0cmluZ0NvbnZlcnRlcjtcbiAgICAgICAgY2FzZSBBc25Qcm9wVHlwZXMuQm1wU3RyaW5nOlxuICAgICAgICAgICAgcmV0dXJuIEFzbkJtcFN0cmluZ0NvbnZlcnRlcjtcbiAgICAgICAgY2FzZSBBc25Qcm9wVHlwZXMuQm9vbGVhbjpcbiAgICAgICAgICAgIHJldHVybiBBc25Cb29sZWFuQ29udmVydGVyO1xuICAgICAgICBjYXNlIEFzblByb3BUeXBlcy5DaGFyYWN0ZXJTdHJpbmc6XG4gICAgICAgICAgICByZXR1cm4gQXNuQ2hhcmFjdGVyU3RyaW5nQ29udmVydGVyO1xuICAgICAgICBjYXNlIEFzblByb3BUeXBlcy5FbnVtZXJhdGVkOlxuICAgICAgICAgICAgcmV0dXJuIEFzbkVudW1lcmF0ZWRDb252ZXJ0ZXI7XG4gICAgICAgIGNhc2UgQXNuUHJvcFR5cGVzLkdlbmVyYWxTdHJpbmc6XG4gICAgICAgICAgICByZXR1cm4gQXNuR2VuZXJhbFN0cmluZ0NvbnZlcnRlcjtcbiAgICAgICAgY2FzZSBBc25Qcm9wVHlwZXMuR2VuZXJhbGl6ZWRUaW1lOlxuICAgICAgICAgICAgcmV0dXJuIEFzbkdlbmVyYWxpemVkVGltZUNvbnZlcnRlcjtcbiAgICAgICAgY2FzZSBBc25Qcm9wVHlwZXMuR3JhcGhpY1N0cmluZzpcbiAgICAgICAgICAgIHJldHVybiBBc25HcmFwaGljU3RyaW5nQ29udmVydGVyO1xuICAgICAgICBjYXNlIEFzblByb3BUeXBlcy5JQTVTdHJpbmc6XG4gICAgICAgICAgICByZXR1cm4gQXNuSUE1U3RyaW5nQ29udmVydGVyO1xuICAgICAgICBjYXNlIEFzblByb3BUeXBlcy5JbnRlZ2VyOlxuICAgICAgICAgICAgcmV0dXJuIEFzbkludGVnZXJDb252ZXJ0ZXI7XG4gICAgICAgIGNhc2UgQXNuUHJvcFR5cGVzLk51bGw6XG4gICAgICAgICAgICByZXR1cm4gQXNuTnVsbENvbnZlcnRlcjtcbiAgICAgICAgY2FzZSBBc25Qcm9wVHlwZXMuTnVtZXJpY1N0cmluZzpcbiAgICAgICAgICAgIHJldHVybiBBc25OdW1lcmljU3RyaW5nQ29udmVydGVyO1xuICAgICAgICBjYXNlIEFzblByb3BUeXBlcy5PYmplY3RJZGVudGlmaWVyOlxuICAgICAgICAgICAgcmV0dXJuIEFzbk9iamVjdElkZW50aWZpZXJDb252ZXJ0ZXI7XG4gICAgICAgIGNhc2UgQXNuUHJvcFR5cGVzLk9jdGV0U3RyaW5nOlxuICAgICAgICAgICAgcmV0dXJuIEFzbk9jdGV0U3RyaW5nQ29udmVydGVyO1xuICAgICAgICBjYXNlIEFzblByb3BUeXBlcy5QcmludGFibGVTdHJpbmc6XG4gICAgICAgICAgICByZXR1cm4gQXNuUHJpbnRhYmxlU3RyaW5nQ29udmVydGVyO1xuICAgICAgICBjYXNlIEFzblByb3BUeXBlcy5UZWxldGV4U3RyaW5nOlxuICAgICAgICAgICAgcmV0dXJuIEFzblRlbGV0ZXhTdHJpbmdDb252ZXJ0ZXI7XG4gICAgICAgIGNhc2UgQXNuUHJvcFR5cGVzLlVUQ1RpbWU6XG4gICAgICAgICAgICByZXR1cm4gQXNuVVRDVGltZUNvbnZlcnRlcjtcbiAgICAgICAgY2FzZSBBc25Qcm9wVHlwZXMuVW5pdmVyc2FsU3RyaW5nOlxuICAgICAgICAgICAgcmV0dXJuIEFzblVuaXZlcnNhbFN0cmluZ0NvbnZlcnRlcjtcbiAgICAgICAgY2FzZSBBc25Qcm9wVHlwZXMuVXRmOFN0cmluZzpcbiAgICAgICAgICAgIHJldHVybiBBc25VdGY4U3RyaW5nQ29udmVydGVyO1xuICAgICAgICBjYXNlIEFzblByb3BUeXBlcy5WaWRlb3RleFN0cmluZzpcbiAgICAgICAgICAgIHJldHVybiBBc25WaWRlb3RleFN0cmluZ0NvbnZlcnRlcjtcbiAgICAgICAgY2FzZSBBc25Qcm9wVHlwZXMuVmlzaWJsZVN0cmluZzpcbiAgICAgICAgICAgIHJldHVybiBBc25WaXNpYmxlU3RyaW5nQ29udmVydGVyO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxufVxuIiwgImV4cG9ydCBmdW5jdGlvbiBpc0NvbnZlcnRpYmxlKHRhcmdldCkge1xuICAgIGlmICh0eXBlb2YgdGFyZ2V0ID09PSBcImZ1bmN0aW9uXCIgJiYgdGFyZ2V0LnByb3RvdHlwZSkge1xuICAgICAgICBpZiAodGFyZ2V0LnByb3RvdHlwZS50b0FTTiAmJiB0YXJnZXQucHJvdG90eXBlLmZyb21BU04pIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGlzQ29udmVydGlibGUodGFyZ2V0LnByb3RvdHlwZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJldHVybiAhISh0YXJnZXQgJiYgdHlwZW9mIHRhcmdldCA9PT0gXCJvYmplY3RcIiAmJiBcInRvQVNOXCIgaW4gdGFyZ2V0ICYmIFwiZnJvbUFTTlwiIGluIHRhcmdldCk7XG4gICAgfVxufVxuZXhwb3J0IGZ1bmN0aW9uIGlzVHlwZU9mQXJyYXkodGFyZ2V0KSB7XG4gICAgdmFyIF9hO1xuICAgIGlmICh0YXJnZXQpIHtcbiAgICAgICAgY29uc3QgcHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YodGFyZ2V0KTtcbiAgICAgICAgaWYgKCgoX2EgPSBwcm90byA9PT0gbnVsbCB8fCBwcm90byA9PT0gdm9pZCAwID8gdm9pZCAwIDogcHJvdG8ucHJvdG90eXBlKSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2EuY29uc3RydWN0b3IpID09PSBBcnJheSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGlzVHlwZU9mQXJyYXkocHJvdG8pO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5leHBvcnQgZnVuY3Rpb24gaXNBcnJheUVxdWFsKGJ5dGVzMSwgYnl0ZXMyKSB7XG4gICAgaWYgKCEoYnl0ZXMxICYmIGJ5dGVzMikpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoYnl0ZXMxLmJ5dGVMZW5ndGggIT09IGJ5dGVzMi5ieXRlTGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgY29uc3QgYjEgPSBuZXcgVWludDhBcnJheShieXRlczEpO1xuICAgIGNvbnN0IGIyID0gbmV3IFVpbnQ4QXJyYXkoYnl0ZXMyKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJ5dGVzMS5ieXRlTGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGIxW2ldICE9PSBiMltpXSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuIiwgImltcG9ydCAqIGFzIGFzbjFqcyBmcm9tIFwiYXNuMWpzXCI7XG5pbXBvcnQgeyBBc25Qcm9wVHlwZXMsIEFzblR5cGVUeXBlcyB9IGZyb20gXCIuL2VudW1zXCI7XG5pbXBvcnQgeyBpc0NvbnZlcnRpYmxlIH0gZnJvbSBcIi4vaGVscGVyXCI7XG5leHBvcnQgY2xhc3MgQXNuU2NoZW1hU3RvcmFnZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMuaXRlbXMgPSBuZXcgV2Vha01hcCgpO1xuICAgIH1cbiAgICBoYXModGFyZ2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLml0ZW1zLmhhcyh0YXJnZXQpO1xuICAgIH1cbiAgICBnZXQodGFyZ2V0LCBjaGVja1NjaGVtYSA9IGZhbHNlKSB7XG4gICAgICAgIGNvbnN0IHNjaGVtYSA9IHRoaXMuaXRlbXMuZ2V0KHRhcmdldCk7XG4gICAgICAgIGlmICghc2NoZW1hKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBnZXQgc2NoZW1hIGZvciAnJHt0YXJnZXQucHJvdG90eXBlLmNvbnN0cnVjdG9yLm5hbWV9JyB0YXJnZXRgKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY2hlY2tTY2hlbWEgJiYgIXNjaGVtYS5zY2hlbWEpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgU2NoZW1hICcke3RhcmdldC5wcm90b3R5cGUuY29uc3RydWN0b3IubmFtZX0nIGRvZXNuJ3QgY29udGFpbiBBU04uMSBzY2hlbWEuIENhbGwgJ0FzblNjaGVtYVN0b3JhZ2UuY2FjaGUnLmApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzY2hlbWE7XG4gICAgfVxuICAgIGNhY2hlKHRhcmdldCkge1xuICAgICAgICBjb25zdCBzY2hlbWEgPSB0aGlzLmdldCh0YXJnZXQpO1xuICAgICAgICBpZiAoIXNjaGVtYS5zY2hlbWEpIHtcbiAgICAgICAgICAgIHNjaGVtYS5zY2hlbWEgPSB0aGlzLmNyZWF0ZSh0YXJnZXQsIHRydWUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGNyZWF0ZURlZmF1bHQodGFyZ2V0KSB7XG4gICAgICAgIGNvbnN0IHNjaGVtYSA9IHtcbiAgICAgICAgICAgIHR5cGU6IEFzblR5cGVUeXBlcy5TZXF1ZW5jZSxcbiAgICAgICAgICAgIGl0ZW1zOiB7fSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgcGFyZW50U2NoZW1hID0gdGhpcy5maW5kUGFyZW50U2NoZW1hKHRhcmdldCk7XG4gICAgICAgIGlmIChwYXJlbnRTY2hlbWEpIHtcbiAgICAgICAgICAgIE9iamVjdC5hc3NpZ24oc2NoZW1hLCBwYXJlbnRTY2hlbWEpO1xuICAgICAgICAgICAgc2NoZW1hLml0ZW1zID0gT2JqZWN0LmFzc2lnbih7fSwgc2NoZW1hLml0ZW1zLCBwYXJlbnRTY2hlbWEuaXRlbXMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzY2hlbWE7XG4gICAgfVxuICAgIGNyZWF0ZSh0YXJnZXQsIHVzZU5hbWVzKSB7XG4gICAgICAgIGNvbnN0IHNjaGVtYSA9IHRoaXMuaXRlbXMuZ2V0KHRhcmdldCkgfHwgdGhpcy5jcmVhdGVEZWZhdWx0KHRhcmdldCk7XG4gICAgICAgIGNvbnN0IGFzbjFWYWx1ZSA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBzY2hlbWEuaXRlbXMpIHtcbiAgICAgICAgICAgIGNvbnN0IGl0ZW0gPSBzY2hlbWEuaXRlbXNba2V5XTtcbiAgICAgICAgICAgIGNvbnN0IG5hbWUgPSB1c2VOYW1lcyA/IGtleSA6IFwiXCI7XG4gICAgICAgICAgICBsZXQgYXNuMUl0ZW07XG4gICAgICAgICAgICBpZiAodHlwZW9mIChpdGVtLnR5cGUpID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgQXNuMVR5cGVOYW1lID0gQXNuUHJvcFR5cGVzW2l0ZW0udHlwZV07XG4gICAgICAgICAgICAgICAgY29uc3QgQXNuMVR5cGUgPSBhc24xanNbQXNuMVR5cGVOYW1lXTtcbiAgICAgICAgICAgICAgICBpZiAoIUFzbjFUeXBlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IGdldCBBU04xIGNsYXNzIGJ5IG5hbWUgJyR7QXNuMVR5cGVOYW1lfSdgKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYXNuMUl0ZW0gPSBuZXcgQXNuMVR5cGUoeyBuYW1lIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoaXNDb252ZXJ0aWJsZShpdGVtLnR5cGUpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgaW5zdGFuY2UgPSBuZXcgaXRlbS50eXBlKCk7XG4gICAgICAgICAgICAgICAgYXNuMUl0ZW0gPSBpbnN0YW5jZS50b1NjaGVtYShuYW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGl0ZW0ub3B0aW9uYWwpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBpdGVtU2NoZW1hID0gdGhpcy5nZXQoaXRlbS50eXBlKTtcbiAgICAgICAgICAgICAgICBpZiAoaXRlbVNjaGVtYS50eXBlID09PSBBc25UeXBlVHlwZXMuQ2hvaWNlKSB7XG4gICAgICAgICAgICAgICAgICAgIGFzbjFJdGVtID0gbmV3IGFzbjFqcy5BbnkoeyBuYW1lIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYXNuMUl0ZW0gPSB0aGlzLmNyZWF0ZShpdGVtLnR5cGUsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgYXNuMUl0ZW0ubmFtZSA9IG5hbWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYXNuMUl0ZW0gPSBuZXcgYXNuMWpzLkFueSh7IG5hbWUgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBvcHRpb25hbCA9ICEhaXRlbS5vcHRpb25hbCB8fCBpdGVtLmRlZmF1bHRWYWx1ZSAhPT0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgaWYgKGl0ZW0ucmVwZWF0ZWQpIHtcbiAgICAgICAgICAgICAgICBhc24xSXRlbS5uYW1lID0gXCJcIjtcbiAgICAgICAgICAgICAgICBjb25zdCBDb250YWluZXIgPSBpdGVtLnJlcGVhdGVkID09PSBcInNldFwiXG4gICAgICAgICAgICAgICAgICAgID8gYXNuMWpzLlNldFxuICAgICAgICAgICAgICAgICAgICA6IGFzbjFqcy5TZXF1ZW5jZTtcbiAgICAgICAgICAgICAgICBhc24xSXRlbSA9IG5ldyBDb250YWluZXIoe1xuICAgICAgICAgICAgICAgICAgICBuYW1lOiBcIlwiLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogW1xuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IGFzbjFqcy5SZXBlYXRlZCh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogYXNuMUl0ZW0sXG4gICAgICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpdGVtLmNvbnRleHQgIT09IG51bGwgJiYgaXRlbS5jb250ZXh0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBpZiAoaXRlbS5pbXBsaWNpdCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGl0ZW0udHlwZSA9PT0gXCJudW1iZXJcIiB8fCBpc0NvbnZlcnRpYmxlKGl0ZW0udHlwZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IENvbnRhaW5lciA9IGl0ZW0ucmVwZWF0ZWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGFzbjFqcy5Db25zdHJ1Y3RlZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogYXNuMWpzLlByaW1pdGl2ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFzbjFWYWx1ZS5wdXNoKG5ldyBDb250YWluZXIoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uYWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWRCbG9jazoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWdDbGFzczogMyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFnTnVtYmVyOiBpdGVtLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2FjaGUoaXRlbS50eXBlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGlzUmVwZWF0ZWQgPSAhIWl0ZW0ucmVwZWF0ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgdmFsdWUgPSAhaXNSZXBlYXRlZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gdGhpcy5nZXQoaXRlbS50eXBlLCB0cnVlKS5zY2hlbWFcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGFzbjFJdGVtO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBcInZhbHVlQmxvY2tcIiBpbiB2YWx1ZSA/IHZhbHVlLnZhbHVlQmxvY2sudmFsdWUgOiB2YWx1ZS52YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFzbjFWYWx1ZS5wdXNoKG5ldyBhc24xanMuQ29uc3RydWN0ZWQoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICFpc1JlcGVhdGVkID8gbmFtZSA6IFwiXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uYWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWRCbG9jazoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWdDbGFzczogMyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFnTnVtYmVyOiBpdGVtLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGFzbjFWYWx1ZS5wdXNoKG5ldyBhc24xanMuQ29uc3RydWN0ZWQoe1xuICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uYWwsXG4gICAgICAgICAgICAgICAgICAgICAgICBpZEJsb2NrOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFnQ2xhc3M6IDMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFnTnVtYmVyOiBpdGVtLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IFthc24xSXRlbV0sXG4gICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhc24xSXRlbS5vcHRpb25hbCA9IG9wdGlvbmFsO1xuICAgICAgICAgICAgICAgIGFzbjFWYWx1ZS5wdXNoKGFzbjFJdGVtKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBzd2l0Y2ggKHNjaGVtYS50eXBlKSB7XG4gICAgICAgICAgICBjYXNlIEFzblR5cGVUeXBlcy5TZXF1ZW5jZTpcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IGFzbjFqcy5TZXF1ZW5jZSh7IHZhbHVlOiBhc24xVmFsdWUsIG5hbWU6IFwiXCIgfSk7XG4gICAgICAgICAgICBjYXNlIEFzblR5cGVUeXBlcy5TZXQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBhc24xanMuU2V0KHsgdmFsdWU6IGFzbjFWYWx1ZSwgbmFtZTogXCJcIiB9KTtcbiAgICAgICAgICAgIGNhc2UgQXNuVHlwZVR5cGVzLkNob2ljZTpcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IGFzbjFqcy5DaG9pY2UoeyB2YWx1ZTogYXNuMVZhbHVlLCBuYW1lOiBcIlwiIH0pO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIEFTTjEgdHlwZSBpbiB1c2VgKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzZXQodGFyZ2V0LCBzY2hlbWEpIHtcbiAgICAgICAgdGhpcy5pdGVtcy5zZXQodGFyZ2V0LCBzY2hlbWEpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZmluZFBhcmVudFNjaGVtYSh0YXJnZXQpIHtcbiAgICAgICAgY29uc3QgcGFyZW50ID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHRhcmdldCk7XG4gICAgICAgIGlmIChwYXJlbnQpIHtcbiAgICAgICAgICAgIGNvbnN0IHNjaGVtYSA9IHRoaXMuaXRlbXMuZ2V0KHBhcmVudCk7XG4gICAgICAgICAgICByZXR1cm4gc2NoZW1hIHx8IHRoaXMuZmluZFBhcmVudFNjaGVtYShwYXJlbnQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbn1cbiIsICJpbXBvcnQgeyBBc25TY2hlbWFTdG9yYWdlIH0gZnJvbSBcIi4vc2NoZW1hXCI7XG5leHBvcnQgY29uc3Qgc2NoZW1hU3RvcmFnZSA9IG5ldyBBc25TY2hlbWFTdG9yYWdlKCk7XG4iLCAiaW1wb3J0ICogYXMgY29udmVydGVycyBmcm9tIFwiLi9jb252ZXJ0ZXJzXCI7XG5pbXBvcnQgeyBBc25UeXBlVHlwZXMgfSBmcm9tIFwiLi9lbnVtc1wiO1xuaW1wb3J0IHsgc2NoZW1hU3RvcmFnZSB9IGZyb20gXCIuL3N0b3JhZ2VcIjtcbmV4cG9ydCBjb25zdCBBc25UeXBlID0gKG9wdGlvbnMpID0+ICh0YXJnZXQpID0+IHtcbiAgICBsZXQgc2NoZW1hO1xuICAgIGlmICghc2NoZW1hU3RvcmFnZS5oYXModGFyZ2V0KSkge1xuICAgICAgICBzY2hlbWEgPSBzY2hlbWFTdG9yYWdlLmNyZWF0ZURlZmF1bHQodGFyZ2V0KTtcbiAgICAgICAgc2NoZW1hU3RvcmFnZS5zZXQodGFyZ2V0LCBzY2hlbWEpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgc2NoZW1hID0gc2NoZW1hU3RvcmFnZS5nZXQodGFyZ2V0KTtcbiAgICB9XG4gICAgT2JqZWN0LmFzc2lnbihzY2hlbWEsIG9wdGlvbnMpO1xufTtcbmV4cG9ydCBjb25zdCBBc25DaG9pY2VUeXBlID0gKCkgPT4gQXNuVHlwZSh7IHR5cGU6IEFzblR5cGVUeXBlcy5DaG9pY2UgfSk7XG5leHBvcnQgY29uc3QgQXNuU2V0VHlwZSA9IChvcHRpb25zKSA9PiBBc25UeXBlKHsgdHlwZTogQXNuVHlwZVR5cGVzLlNldCwgLi4ub3B0aW9ucyB9KTtcbmV4cG9ydCBjb25zdCBBc25TZXF1ZW5jZVR5cGUgPSAob3B0aW9ucykgPT4gQXNuVHlwZSh7IHR5cGU6IEFzblR5cGVUeXBlcy5TZXF1ZW5jZSwgLi4ub3B0aW9ucyB9KTtcbmV4cG9ydCBjb25zdCBBc25Qcm9wID0gKG9wdGlvbnMpID0+ICh0YXJnZXQsIHByb3BlcnR5S2V5KSA9PiB7XG4gICAgbGV0IHNjaGVtYTtcbiAgICBpZiAoIXNjaGVtYVN0b3JhZ2UuaGFzKHRhcmdldC5jb25zdHJ1Y3RvcikpIHtcbiAgICAgICAgc2NoZW1hID0gc2NoZW1hU3RvcmFnZS5jcmVhdGVEZWZhdWx0KHRhcmdldC5jb25zdHJ1Y3Rvcik7XG4gICAgICAgIHNjaGVtYVN0b3JhZ2Uuc2V0KHRhcmdldC5jb25zdHJ1Y3Rvciwgc2NoZW1hKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHNjaGVtYSA9IHNjaGVtYVN0b3JhZ2UuZ2V0KHRhcmdldC5jb25zdHJ1Y3Rvcik7XG4gICAgfVxuICAgIGNvbnN0IGNvcHlPcHRpb25zID0gT2JqZWN0LmFzc2lnbih7fSwgb3B0aW9ucyk7XG4gICAgaWYgKHR5cGVvZiBjb3B5T3B0aW9ucy50eXBlID09PSBcIm51bWJlclwiICYmICFjb3B5T3B0aW9ucy5jb252ZXJ0ZXIpIHtcbiAgICAgICAgY29uc3QgZGVmYXVsdENvbnZlcnRlciA9IGNvbnZlcnRlcnMuZGVmYXVsdENvbnZlcnRlcihvcHRpb25zLnR5cGUpO1xuICAgICAgICBpZiAoIWRlZmF1bHRDb252ZXJ0ZXIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IGdldCBkZWZhdWx0IGNvbnZlcnRlciBmb3IgcHJvcGVydHkgJyR7cHJvcGVydHlLZXl9JyBvZiAke3RhcmdldC5jb25zdHJ1Y3Rvci5uYW1lfWApO1xuICAgICAgICB9XG4gICAgICAgIGNvcHlPcHRpb25zLmNvbnZlcnRlciA9IGRlZmF1bHRDb252ZXJ0ZXI7XG4gICAgfVxuICAgIHNjaGVtYS5pdGVtc1twcm9wZXJ0eUtleV0gPSBjb3B5T3B0aW9ucztcbn07XG4iLCAiZXhwb3J0IGNsYXNzIEFzblNjaGVtYVZhbGlkYXRpb25FcnJvciBleHRlbmRzIEVycm9yIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5zY2hlbWFzID0gW107XG4gICAgfVxufVxuIiwgImV4cG9ydCAqIGZyb20gXCIuL3NjaGVtYV92YWxpZGF0aW9uXCI7XG4iLCAiaW1wb3J0ICogYXMgYXNuMWpzIGZyb20gXCJhc24xanNcIjtcbmltcG9ydCB7IEFzblByb3BUeXBlcywgQXNuVHlwZVR5cGVzIH0gZnJvbSBcIi4vZW51bXNcIjtcbmltcG9ydCAqIGFzIGNvbnZlcnRlcnMgZnJvbSBcIi4vY29udmVydGVyc1wiO1xuaW1wb3J0IHsgQXNuU2NoZW1hVmFsaWRhdGlvbkVycm9yIH0gZnJvbSBcIi4vZXJyb3JzXCI7XG5pbXBvcnQgeyBpc0NvbnZlcnRpYmxlLCBpc1R5cGVPZkFycmF5IH0gZnJvbSBcIi4vaGVscGVyXCI7XG5pbXBvcnQgeyBzY2hlbWFTdG9yYWdlIH0gZnJvbSBcIi4vc3RvcmFnZVwiO1xuZXhwb3J0IGNsYXNzIEFzblBhcnNlciB7XG4gICAgc3RhdGljIHBhcnNlKGRhdGEsIHRhcmdldCkge1xuICAgICAgICBjb25zdCBhc24xUGFyc2VkID0gYXNuMWpzLmZyb21CRVIoZGF0YSk7XG4gICAgICAgIGlmIChhc24xUGFyc2VkLnJlc3VsdC5lcnJvcikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGFzbjFQYXJzZWQucmVzdWx0LmVycm9yKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCByZXMgPSB0aGlzLmZyb21BU04oYXNuMVBhcnNlZC5yZXN1bHQsIHRhcmdldCk7XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxuICAgIHN0YXRpYyBmcm9tQVNOKGFzbjFTY2hlbWEsIHRhcmdldCkge1xuICAgICAgICB2YXIgX2E7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAoaXNDb252ZXJ0aWJsZSh0YXJnZXQpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBuZXcgdGFyZ2V0KCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlLmZyb21BU04oYXNuMVNjaGVtYSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBzY2hlbWEgPSBzY2hlbWFTdG9yYWdlLmdldCh0YXJnZXQpO1xuICAgICAgICAgICAgc2NoZW1hU3RvcmFnZS5jYWNoZSh0YXJnZXQpO1xuICAgICAgICAgICAgbGV0IHRhcmdldFNjaGVtYSA9IHNjaGVtYS5zY2hlbWE7XG4gICAgICAgICAgICBpZiAoYXNuMVNjaGVtYS5jb25zdHJ1Y3RvciA9PT0gYXNuMWpzLkNvbnN0cnVjdGVkICYmIHNjaGVtYS50eXBlICE9PSBBc25UeXBlVHlwZXMuQ2hvaWNlKSB7XG4gICAgICAgICAgICAgICAgdGFyZ2V0U2NoZW1hID0gbmV3IGFzbjFqcy5Db25zdHJ1Y3RlZCh7XG4gICAgICAgICAgICAgICAgICAgIGlkQmxvY2s6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhZ0NsYXNzOiAzLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGFnTnVtYmVyOiBhc24xU2NoZW1hLmlkQmxvY2sudGFnTnVtYmVyLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogc2NoZW1hLnNjaGVtYS52YWx1ZUJsb2NrLnZhbHVlLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIHNjaGVtYS5pdGVtcykge1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgYXNuMVNjaGVtYVtrZXldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGFzbjFDb21wYXJlZFNjaGVtYSA9IGFzbjFqcy5jb21wYXJlU2NoZW1hKHt9LCBhc24xU2NoZW1hLCB0YXJnZXRTY2hlbWEpO1xuICAgICAgICAgICAgaWYgKCFhc24xQ29tcGFyZWRTY2hlbWEudmVyaWZpZWQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNuU2NoZW1hVmFsaWRhdGlvbkVycm9yKGBEYXRhIGRvZXMgbm90IG1hdGNoIHRvICR7dGFyZ2V0Lm5hbWV9IEFTTjEgc2NoZW1hLiAke2FzbjFDb21wYXJlZFNjaGVtYS5yZXN1bHQuZXJyb3J9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCByZXMgPSBuZXcgdGFyZ2V0KCk7XG4gICAgICAgICAgICBpZiAoaXNUeXBlT2ZBcnJheSh0YXJnZXQpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEoXCJ2YWx1ZVwiIGluIGFzbjFTY2hlbWEudmFsdWVCbG9jayAmJiBBcnJheS5pc0FycmF5KGFzbjFTY2hlbWEudmFsdWVCbG9jay52YWx1ZSkpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IGdldCBpdGVtcyBmcm9tIHRoZSBBU04uMSBwYXJzZWQgdmFsdWUuIEFTTi4xIG9iamVjdCBpcyBub3QgY29uc3RydWN0ZWQuYCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGl0ZW1UeXBlID0gc2NoZW1hLml0ZW1UeXBlO1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgaXRlbVR5cGUgPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY29udmVydGVyID0gY29udmVydGVycy5kZWZhdWx0Q29udmVydGVyKGl0ZW1UeXBlKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFjb252ZXJ0ZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IGdldCBkZWZhdWx0IGNvbnZlcnRlciBmb3IgYXJyYXkgaXRlbSBvZiAke3RhcmdldC5uYW1lfSBBU04xIHNjaGVtYWApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0YXJnZXQuZnJvbShhc24xU2NoZW1hLnZhbHVlQmxvY2sudmFsdWUsIChlbGVtZW50KSA9PiBjb252ZXJ0ZXIuZnJvbUFTTihlbGVtZW50KSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGFyZ2V0LmZyb20oYXNuMVNjaGVtYS52YWx1ZUJsb2NrLnZhbHVlLCAoZWxlbWVudCkgPT4gdGhpcy5mcm9tQVNOKGVsZW1lbnQsIGl0ZW1UeXBlKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gc2NoZW1hLml0ZW1zKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgYXNuMVNjaGVtYVZhbHVlID0gYXNuMUNvbXBhcmVkU2NoZW1hLnJlc3VsdFtrZXldO1xuICAgICAgICAgICAgICAgIGlmICghYXNuMVNjaGVtYVZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBzY2hlbWFJdGVtID0gc2NoZW1hLml0ZW1zW2tleV07XG4gICAgICAgICAgICAgICAgY29uc3Qgc2NoZW1hSXRlbVR5cGUgPSBzY2hlbWFJdGVtLnR5cGU7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBzY2hlbWFJdGVtVHlwZSA9PT0gXCJudW1iZXJcIiB8fCBpc0NvbnZlcnRpYmxlKHNjaGVtYUl0ZW1UeXBlKSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjb252ZXJ0ZXIgPSAoX2EgPSBzY2hlbWFJdGVtLmNvbnZlcnRlcikgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogKGlzQ29udmVydGlibGUoc2NoZW1hSXRlbVR5cGUpXG4gICAgICAgICAgICAgICAgICAgICAgICA/IG5ldyBzY2hlbWFJdGVtVHlwZSgpXG4gICAgICAgICAgICAgICAgICAgICAgICA6IG51bGwpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWNvbnZlcnRlcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ29udmVydGVyIGlzIGVtcHR5XCIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChzY2hlbWFJdGVtLnJlcGVhdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2NoZW1hSXRlbS5pbXBsaWNpdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IENvbnRhaW5lciA9IHNjaGVtYUl0ZW0ucmVwZWF0ZWQgPT09IFwic2VxdWVuY2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGFzbjFqcy5TZXF1ZW5jZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGFzbjFqcy5TZXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3SXRlbSA9IG5ldyBDb250YWluZXIoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdJdGVtLnZhbHVlQmxvY2sgPSBhc24xU2NoZW1hVmFsdWUudmFsdWVCbG9jaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXdJdGVtQXNuID0gYXNuMWpzLmZyb21CRVIobmV3SXRlbS50b0JFUihmYWxzZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXdJdGVtQXNuLm9mZnNldCA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgcGFyc2UgdGhlIGNoaWxkIGl0ZW0uICR7bmV3SXRlbUFzbi5yZXN1bHQuZXJyb3J9YCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKFwidmFsdWVcIiBpbiBuZXdJdGVtQXNuLnJlc3VsdC52YWx1ZUJsb2NrICYmIEFycmF5LmlzQXJyYXkobmV3SXRlbUFzbi5yZXN1bHQudmFsdWVCbG9jay52YWx1ZSkpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBnZXQgaXRlbXMgZnJvbSB0aGUgQVNOLjEgcGFyc2VkIHZhbHVlLiBBU04uMSBvYmplY3QgaXMgbm90IGNvbnN0cnVjdGVkLlwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBuZXdJdGVtQXNuLnJlc3VsdC52YWx1ZUJsb2NrLnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc1trZXldID0gQXJyYXkuZnJvbSh2YWx1ZSwgKGVsZW1lbnQpID0+IGNvbnZlcnRlci5mcm9tQVNOKGVsZW1lbnQpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc1trZXldID0gQXJyYXkuZnJvbShhc24xU2NoZW1hVmFsdWUsIChlbGVtZW50KSA9PiBjb252ZXJ0ZXIuZnJvbUFTTihlbGVtZW50KSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgdmFsdWUgPSBhc24xU2NoZW1hVmFsdWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2NoZW1hSXRlbS5pbXBsaWNpdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBuZXdJdGVtO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0NvbnZlcnRpYmxlKHNjaGVtYUl0ZW1UeXBlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdJdGVtID0gbmV3IHNjaGVtYUl0ZW1UeXBlKCkudG9TY2hlbWEoXCJcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBc24xVHlwZU5hbWUgPSBBc25Qcm9wVHlwZXNbc2NoZW1hSXRlbVR5cGVdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBc24xVHlwZSA9IGFzbjFqc1tBc24xVHlwZU5hbWVdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIUFzbjFUeXBlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBnZXQgJyR7QXNuMVR5cGVOYW1lfScgY2xhc3MgZnJvbSBhc24xanMgbW9kdWxlYCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3SXRlbSA9IG5ldyBBc24xVHlwZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdJdGVtLnZhbHVlQmxvY2sgPSB2YWx1ZS52YWx1ZUJsb2NrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gYXNuMWpzLmZyb21CRVIobmV3SXRlbS50b0JFUihmYWxzZSkpLnJlc3VsdDtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc1trZXldID0gY29udmVydGVyLmZyb21BU04odmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2NoZW1hSXRlbS5yZXBlYXRlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGFzbjFTY2hlbWFWYWx1ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgZ2V0IGxpc3Qgb2YgaXRlbXMgZnJvbSB0aGUgQVNOLjEgcGFyc2VkIHZhbHVlLiBBU04uMSB2YWx1ZSBzaG91bGQgYmUgaXRlcmFibGUuXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzW2tleV0gPSBBcnJheS5mcm9tKGFzbjFTY2hlbWFWYWx1ZSwgKGVsZW1lbnQpID0+IHRoaXMuZnJvbUFTTihlbGVtZW50LCBzY2hlbWFJdGVtVHlwZSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzW2tleV0gPSB0aGlzLmZyb21BU04oYXNuMVNjaGVtYVZhbHVlLCBzY2hlbWFJdGVtVHlwZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVzO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgQXNuU2NoZW1hVmFsaWRhdGlvbkVycm9yKSB7XG4gICAgICAgICAgICAgICAgZXJyb3Iuc2NoZW1hcy5wdXNoKHRhcmdldC5uYW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwgImltcG9ydCAqIGFzIGFzbjFqcyBmcm9tIFwiYXNuMWpzXCI7XG5pbXBvcnQgKiBhcyBjb252ZXJ0ZXJzIGZyb20gXCIuL2NvbnZlcnRlcnNcIjtcbmltcG9ydCB7IEFzblByb3BUeXBlcywgQXNuVHlwZVR5cGVzIH0gZnJvbSBcIi4vZW51bXNcIjtcbmltcG9ydCB7IGlzQ29udmVydGlibGUsIGlzQXJyYXlFcXVhbCB9IGZyb20gXCIuL2hlbHBlclwiO1xuaW1wb3J0IHsgc2NoZW1hU3RvcmFnZSB9IGZyb20gXCIuL3N0b3JhZ2VcIjtcbmV4cG9ydCBjbGFzcyBBc25TZXJpYWxpemVyIHtcbiAgICBzdGF0aWMgc2VyaWFsaXplKG9iaikge1xuICAgICAgICBpZiAob2JqIGluc3RhbmNlb2YgYXNuMWpzLkJhc2VCbG9jaykge1xuICAgICAgICAgICAgcmV0dXJuIG9iai50b0JFUihmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMudG9BU04ob2JqKS50b0JFUihmYWxzZSk7XG4gICAgfVxuICAgIHN0YXRpYyB0b0FTTihvYmopIHtcbiAgICAgICAgaWYgKG9iaiAmJiB0eXBlb2Ygb2JqID09PSBcIm9iamVjdFwiICYmIGlzQ29udmVydGlibGUob2JqKSkge1xuICAgICAgICAgICAgcmV0dXJuIG9iai50b0FTTigpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghKG9iaiAmJiB0eXBlb2Ygb2JqID09PSBcIm9iamVjdFwiKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlBhcmFtZXRlciAxIHNob3VsZCBiZSB0eXBlIG9mIE9iamVjdC5cIik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdGFyZ2V0ID0gb2JqLmNvbnN0cnVjdG9yO1xuICAgICAgICBjb25zdCBzY2hlbWEgPSBzY2hlbWFTdG9yYWdlLmdldCh0YXJnZXQpO1xuICAgICAgICBzY2hlbWFTdG9yYWdlLmNhY2hlKHRhcmdldCk7XG4gICAgICAgIGxldCBhc24xVmFsdWUgPSBbXTtcbiAgICAgICAgaWYgKHNjaGVtYS5pdGVtVHlwZSkge1xuICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iaikpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUGFyYW1ldGVyIDEgc2hvdWxkIGJlIHR5cGUgb2YgQXJyYXkuXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHR5cGVvZiBzY2hlbWEuaXRlbVR5cGUgPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjb252ZXJ0ZXIgPSBjb252ZXJ0ZXJzLmRlZmF1bHRDb252ZXJ0ZXIoc2NoZW1hLml0ZW1UeXBlKTtcbiAgICAgICAgICAgICAgICBpZiAoIWNvbnZlcnRlcikge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBnZXQgZGVmYXVsdCBjb252ZXJ0ZXIgZm9yIGFycmF5IGl0ZW0gb2YgJHt0YXJnZXQubmFtZX0gQVNOMSBzY2hlbWFgKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYXNuMVZhbHVlID0gb2JqLm1hcCgobykgPT4gY29udmVydGVyLnRvQVNOKG8pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGFzbjFWYWx1ZSA9IG9iai5tYXAoKG8pID0+IHRoaXMudG9Bc25JdGVtKHsgdHlwZTogc2NoZW1hLml0ZW1UeXBlIH0sIFwiW11cIiwgdGFyZ2V0LCBvKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBzY2hlbWEuaXRlbXMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzY2hlbWFJdGVtID0gc2NoZW1hLml0ZW1zW2tleV07XG4gICAgICAgICAgICAgICAgY29uc3Qgb2JqUHJvcCA9IG9ialtrZXldO1xuICAgICAgICAgICAgICAgIGlmIChvYmpQcm9wID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgfHwgc2NoZW1hSXRlbS5kZWZhdWx0VmFsdWUgPT09IG9ialByb3BcbiAgICAgICAgICAgICAgICAgICAgfHwgKHR5cGVvZiBzY2hlbWFJdGVtLmRlZmF1bHRWYWx1ZSA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2Ygb2JqUHJvcCA9PT0gXCJvYmplY3RcIlxuICAgICAgICAgICAgICAgICAgICAgICAgJiYgaXNBcnJheUVxdWFsKHRoaXMuc2VyaWFsaXplKHNjaGVtYUl0ZW0uZGVmYXVsdFZhbHVlKSwgdGhpcy5zZXJpYWxpemUob2JqUHJvcCkpKSkge1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgYXNuMUl0ZW0gPSBBc25TZXJpYWxpemVyLnRvQXNuSXRlbShzY2hlbWFJdGVtLCBrZXksIHRhcmdldCwgb2JqUHJvcCk7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBzY2hlbWFJdGVtLmNvbnRleHQgPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNjaGVtYUl0ZW0uaW1wbGljaXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghc2NoZW1hSXRlbS5yZXBlYXRlZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmICh0eXBlb2Ygc2NoZW1hSXRlbS50eXBlID09PSBcIm51bWJlclwiIHx8IGlzQ29udmVydGlibGUoc2NoZW1hSXRlbS50eXBlKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHt9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlLnZhbHVlSGV4ID0gYXNuMUl0ZW0gaW5zdGFuY2VvZiBhc24xanMuTnVsbCA/IGFzbjFJdGVtLnZhbHVlQmVmb3JlRGVjb2RlVmlldyA6IGFzbjFJdGVtLnZhbHVlQmxvY2sudG9CRVIoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc24xVmFsdWUucHVzaChuZXcgYXNuMWpzLlByaW1pdGl2ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbmFsOiBzY2hlbWFJdGVtLm9wdGlvbmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZEJsb2NrOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWdDbGFzczogMyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhZ051bWJlcjogc2NoZW1hSXRlbS5jb250ZXh0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc24xVmFsdWUucHVzaChuZXcgYXNuMWpzLkNvbnN0cnVjdGVkKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uYWw6IHNjaGVtYUl0ZW0ub3B0aW9uYWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkQmxvY2s6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhZ0NsYXNzOiAzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFnTnVtYmVyOiBzY2hlbWFJdGVtLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiBhc24xSXRlbS52YWx1ZUJsb2NrLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFzbjFWYWx1ZS5wdXNoKG5ldyBhc24xanMuQ29uc3RydWN0ZWQoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbmFsOiBzY2hlbWFJdGVtLm9wdGlvbmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkQmxvY2s6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFnQ2xhc3M6IDMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhZ051bWJlcjogc2NoZW1hSXRlbS5jb250ZXh0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IFthc24xSXRlbV0sXG4gICAgICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoc2NoZW1hSXRlbS5yZXBlYXRlZCkge1xuICAgICAgICAgICAgICAgICAgICBhc24xVmFsdWUgPSBhc24xVmFsdWUuY29uY2F0KGFzbjFJdGVtKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGFzbjFWYWx1ZS5wdXNoKGFzbjFJdGVtKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGFzblNjaGVtYTtcbiAgICAgICAgc3dpdGNoIChzY2hlbWEudHlwZSkge1xuICAgICAgICAgICAgY2FzZSBBc25UeXBlVHlwZXMuU2VxdWVuY2U6XG4gICAgICAgICAgICAgICAgYXNuU2NoZW1hID0gbmV3IGFzbjFqcy5TZXF1ZW5jZSh7IHZhbHVlOiBhc24xVmFsdWUgfSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEFzblR5cGVUeXBlcy5TZXQ6XG4gICAgICAgICAgICAgICAgYXNuU2NoZW1hID0gbmV3IGFzbjFqcy5TZXQoeyB2YWx1ZTogYXNuMVZhbHVlIH0pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBBc25UeXBlVHlwZXMuQ2hvaWNlOlxuICAgICAgICAgICAgICAgIGlmICghYXNuMVZhbHVlWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgU2NoZW1hICcke3RhcmdldC5uYW1lfScgaGFzIHdyb25nIGRhdGEuIENob2ljZSBjYW5ub3QgYmUgZW1wdHkuYCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGFzblNjaGVtYSA9IGFzbjFWYWx1ZVswXTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYXNuU2NoZW1hO1xuICAgIH1cbiAgICBzdGF0aWMgdG9Bc25JdGVtKHNjaGVtYUl0ZW0sIGtleSwgdGFyZ2V0LCBvYmpQcm9wKSB7XG4gICAgICAgIGxldCBhc24xSXRlbTtcbiAgICAgICAgaWYgKHR5cGVvZiAoc2NoZW1hSXRlbS50eXBlKSA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgY29uc3QgY29udmVydGVyID0gc2NoZW1hSXRlbS5jb252ZXJ0ZXI7XG4gICAgICAgICAgICBpZiAoIWNvbnZlcnRlcikge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgUHJvcGVydHkgJyR7a2V5fScgZG9lc24ndCBoYXZlIGNvbnZlcnRlciBmb3IgdHlwZSAke0FzblByb3BUeXBlc1tzY2hlbWFJdGVtLnR5cGVdfSBpbiBzY2hlbWEgJyR7dGFyZ2V0Lm5hbWV9J2ApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHNjaGVtYUl0ZW0ucmVwZWF0ZWQpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqUHJvcCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlBhcmFtZXRlciAnb2JqUHJvcCcgc2hvdWxkIGJlIHR5cGUgb2YgQXJyYXkuXCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBpdGVtcyA9IEFycmF5LmZyb20ob2JqUHJvcCwgKGVsZW1lbnQpID0+IGNvbnZlcnRlci50b0FTTihlbGVtZW50KSk7XG4gICAgICAgICAgICAgICAgY29uc3QgQ29udGFpbmVyID0gc2NoZW1hSXRlbS5yZXBlYXRlZCA9PT0gXCJzZXF1ZW5jZVwiXG4gICAgICAgICAgICAgICAgICAgID8gYXNuMWpzLlNlcXVlbmNlXG4gICAgICAgICAgICAgICAgICAgIDogYXNuMWpzLlNldDtcbiAgICAgICAgICAgICAgICBhc24xSXRlbSA9IG5ldyBDb250YWluZXIoe1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogaXRlbXMsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhc24xSXRlbSA9IGNvbnZlcnRlci50b0FTTihvYmpQcm9wKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmIChzY2hlbWFJdGVtLnJlcGVhdGVkKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9ialByb3ApKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQYXJhbWV0ZXIgJ29ialByb3AnIHNob3VsZCBiZSB0eXBlIG9mIEFycmF5LlwiKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgaXRlbXMgPSBBcnJheS5mcm9tKG9ialByb3AsIChlbGVtZW50KSA9PiB0aGlzLnRvQVNOKGVsZW1lbnQpKTtcbiAgICAgICAgICAgICAgICBjb25zdCBDb250YWluZXIgPSBzY2hlbWFJdGVtLnJlcGVhdGVkID09PSBcInNlcXVlbmNlXCJcbiAgICAgICAgICAgICAgICAgICAgPyBhc24xanMuU2VxdWVuY2VcbiAgICAgICAgICAgICAgICAgICAgOiBhc24xanMuU2V0O1xuICAgICAgICAgICAgICAgIGFzbjFJdGVtID0gbmV3IENvbnRhaW5lcih7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiBpdGVtcyxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGFzbjFJdGVtID0gdGhpcy50b0FTTihvYmpQcm9wKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYXNuMUl0ZW07XG4gICAgfVxufVxuIiwgImV4cG9ydCBjbGFzcyBBc25BcnJheSBleHRlbmRzIEFycmF5IHtcbiAgICBjb25zdHJ1Y3RvcihpdGVtcyA9IFtdKSB7XG4gICAgICAgIGlmICh0eXBlb2YgaXRlbXMgPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgIHN1cGVyKGl0ZW1zKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHN1cGVyKCk7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgaXRlbXMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnB1c2goaXRlbSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCAiaW1wb3J0ICogYXMgYXNuMWpzIGZyb20gXCJhc24xanNcIjtcbmltcG9ydCB7IEJ1ZmZlclNvdXJjZUNvbnZlcnRlciB9IGZyb20gXCJwdnRzdXRpbHNcIjtcbmltcG9ydCB7IEFzblBhcnNlciB9IGZyb20gXCIuL3BhcnNlclwiO1xuaW1wb3J0IHsgQXNuU2VyaWFsaXplciB9IGZyb20gXCIuL3NlcmlhbGl6ZXJcIjtcbmV4cG9ydCBjbGFzcyBBc25Db252ZXJ0IHtcbiAgICBzdGF0aWMgc2VyaWFsaXplKG9iaikge1xuICAgICAgICByZXR1cm4gQXNuU2VyaWFsaXplci5zZXJpYWxpemUob2JqKTtcbiAgICB9XG4gICAgc3RhdGljIHBhcnNlKGRhdGEsIHRhcmdldCkge1xuICAgICAgICByZXR1cm4gQXNuUGFyc2VyLnBhcnNlKGRhdGEsIHRhcmdldCk7XG4gICAgfVxuICAgIHN0YXRpYyB0b1N0cmluZyhkYXRhKSB7XG4gICAgICAgIGNvbnN0IGJ1ZiA9IEJ1ZmZlclNvdXJjZUNvbnZlcnRlci5pc0J1ZmZlclNvdXJjZShkYXRhKVxuICAgICAgICAgICAgPyBCdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9BcnJheUJ1ZmZlcihkYXRhKVxuICAgICAgICAgICAgOiBBc25Db252ZXJ0LnNlcmlhbGl6ZShkYXRhKTtcbiAgICAgICAgY29uc3QgYXNuID0gYXNuMWpzLmZyb21CRVIoYnVmKTtcbiAgICAgICAgaWYgKGFzbi5vZmZzZXQgPT09IC0xKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBkZWNvZGUgQVNOLjEgZGF0YS4gJHthc24ucmVzdWx0LmVycm9yfWApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhc24ucmVzdWx0LnRvU3RyaW5nKCk7XG4gICAgfVxufVxuIiwgImV4cG9ydCAqIGZyb20gXCIuL2NvbnZlcnRlcnNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3R5cGVzL2luZGV4XCI7XG5leHBvcnQgeyBBc25Qcm9wLCBBc25UeXBlLCBBc25DaG9pY2VUeXBlLCBBc25TZXF1ZW5jZVR5cGUsIEFzblNldFR5cGUgfSBmcm9tIFwiLi9kZWNvcmF0b3JzXCI7XG5leHBvcnQgeyBBc25UeXBlVHlwZXMsIEFzblByb3BUeXBlcyB9IGZyb20gXCIuL2VudW1zXCI7XG5leHBvcnQgeyBBc25QYXJzZXIgfSBmcm9tIFwiLi9wYXJzZXJcIjtcbmV4cG9ydCB7IEFzblNlcmlhbGl6ZXIgfSBmcm9tIFwiLi9zZXJpYWxpemVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9lcnJvcnNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL29iamVjdHNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NvbnZlcnRcIjtcbiIsICIvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcbkNvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLlxyXG5cclxuUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kL29yIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IgYW55XHJcbnB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZC5cclxuXHJcblRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEhcclxuUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZXHJcbkFORCBGSVRORVNTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIERJUkVDVCxcclxuSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NXHJcbkxPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SXHJcbk9USEVSIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1JcclxuUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS5cclxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi9cclxuLyogZ2xvYmFsIFJlZmxlY3QsIFByb21pc2UgKi9cclxuXHJcbnZhciBleHRlbmRTdGF0aWNzID0gZnVuY3Rpb24oZCwgYikge1xyXG4gICAgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHRlbmRzKGQsIGIpIHtcclxuICAgIGlmICh0eXBlb2YgYiAhPT0gXCJmdW5jdGlvblwiICYmIGIgIT09IG51bGwpXHJcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNsYXNzIGV4dGVuZHMgdmFsdWUgXCIgKyBTdHJpbmcoYikgKyBcIiBpcyBub3QgYSBjb25zdHJ1Y3RvciBvciBudWxsXCIpO1xyXG4gICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG59XHJcblxyXG5leHBvcnQgdmFyIF9fYXNzaWduID0gZnVuY3Rpb24oKSB7XHJcbiAgICBfX2Fzc2lnbiA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gX19hc3NpZ24odCkge1xyXG4gICAgICAgIGZvciAodmFyIHMsIGkgPSAxLCBuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IG47IGkrKykge1xyXG4gICAgICAgICAgICBzID0gYXJndW1lbnRzW2ldO1xyXG4gICAgICAgICAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkpIHRbcF0gPSBzW3BdO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdDtcclxuICAgIH1cclxuICAgIHJldHVybiBfX2Fzc2lnbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZXN0KHMsIGUpIHtcclxuICAgIHZhciB0ID0ge307XHJcbiAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkgJiYgZS5pbmRleE9mKHApIDwgMClcclxuICAgICAgICB0W3BdID0gc1twXTtcclxuICAgIGlmIChzICE9IG51bGwgJiYgdHlwZW9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPT09IFwiZnVuY3Rpb25cIilcclxuICAgICAgICBmb3IgKHZhciBpID0gMCwgcCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMocyk7IGkgPCBwLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmIChlLmluZGV4T2YocFtpXSkgPCAwICYmIE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChzLCBwW2ldKSlcclxuICAgICAgICAgICAgICAgIHRbcFtpXV0gPSBzW3BbaV1dO1xyXG4gICAgICAgIH1cclxuICAgIHJldHVybiB0O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYykge1xyXG4gICAgdmFyIGMgPSBhcmd1bWVudHMubGVuZ3RoLCByID0gYyA8IDMgPyB0YXJnZXQgOiBkZXNjID09PSBudWxsID8gZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBrZXkpIDogZGVzYywgZDtcclxuICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5kZWNvcmF0ZSA9PT0gXCJmdW5jdGlvblwiKSByID0gUmVmbGVjdC5kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYyk7XHJcbiAgICBlbHNlIGZvciAodmFyIGkgPSBkZWNvcmF0b3JzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSBpZiAoZCA9IGRlY29yYXRvcnNbaV0pIHIgPSAoYyA8IDMgPyBkKHIpIDogYyA+IDMgPyBkKHRhcmdldCwga2V5LCByKSA6IGQodGFyZ2V0LCBrZXkpKSB8fCByO1xyXG4gICAgcmV0dXJuIGMgPiAzICYmIHIgJiYgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCByKSwgcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcGFyYW0ocGFyYW1JbmRleCwgZGVjb3JhdG9yKSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwga2V5KSB7IGRlY29yYXRvcih0YXJnZXQsIGtleSwgcGFyYW1JbmRleCk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXNEZWNvcmF0ZShjdG9yLCBkZXNjcmlwdG9ySW4sIGRlY29yYXRvcnMsIGNvbnRleHRJbiwgaW5pdGlhbGl6ZXJzLCBleHRyYUluaXRpYWxpemVycykge1xyXG4gICAgZnVuY3Rpb24gYWNjZXB0KGYpIHsgaWYgKGYgIT09IHZvaWQgMCAmJiB0eXBlb2YgZiAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRnVuY3Rpb24gZXhwZWN0ZWRcIik7IHJldHVybiBmOyB9XHJcbiAgICB2YXIga2luZCA9IGNvbnRleHRJbi5raW5kLCBrZXkgPSBraW5kID09PSBcImdldHRlclwiID8gXCJnZXRcIiA6IGtpbmQgPT09IFwic2V0dGVyXCIgPyBcInNldFwiIDogXCJ2YWx1ZVwiO1xyXG4gICAgdmFyIHRhcmdldCA9ICFkZXNjcmlwdG9ySW4gJiYgY3RvciA/IGNvbnRleHRJbltcInN0YXRpY1wiXSA/IGN0b3IgOiBjdG9yLnByb3RvdHlwZSA6IG51bGw7XHJcbiAgICB2YXIgZGVzY3JpcHRvciA9IGRlc2NyaXB0b3JJbiB8fCAodGFyZ2V0ID8gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIGNvbnRleHRJbi5uYW1lKSA6IHt9KTtcclxuICAgIHZhciBfLCBkb25lID0gZmFsc2U7XHJcbiAgICBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xyXG4gICAgICAgIHZhciBjb250ZXh0ID0ge307XHJcbiAgICAgICAgZm9yICh2YXIgcCBpbiBjb250ZXh0SW4pIGNvbnRleHRbcF0gPSBwID09PSBcImFjY2Vzc1wiID8ge30gOiBjb250ZXh0SW5bcF07XHJcbiAgICAgICAgZm9yICh2YXIgcCBpbiBjb250ZXh0SW4uYWNjZXNzKSBjb250ZXh0LmFjY2Vzc1twXSA9IGNvbnRleHRJbi5hY2Nlc3NbcF07XHJcbiAgICAgICAgY29udGV4dC5hZGRJbml0aWFsaXplciA9IGZ1bmN0aW9uIChmKSB7IGlmIChkb25lKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGFkZCBpbml0aWFsaXplcnMgYWZ0ZXIgZGVjb3JhdGlvbiBoYXMgY29tcGxldGVkXCIpOyBleHRyYUluaXRpYWxpemVycy5wdXNoKGFjY2VwdChmIHx8IG51bGwpKTsgfTtcclxuICAgICAgICB2YXIgcmVzdWx0ID0gKDAsIGRlY29yYXRvcnNbaV0pKGtpbmQgPT09IFwiYWNjZXNzb3JcIiA/IHsgZ2V0OiBkZXNjcmlwdG9yLmdldCwgc2V0OiBkZXNjcmlwdG9yLnNldCB9IDogZGVzY3JpcHRvcltrZXldLCBjb250ZXh0KTtcclxuICAgICAgICBpZiAoa2luZCA9PT0gXCJhY2Nlc3NvclwiKSB7XHJcbiAgICAgICAgICAgIGlmIChyZXN1bHQgPT09IHZvaWQgMCkgY29udGludWU7XHJcbiAgICAgICAgICAgIGlmIChyZXN1bHQgPT09IG51bGwgfHwgdHlwZW9mIHJlc3VsdCAhPT0gXCJvYmplY3RcIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9iamVjdCBleHBlY3RlZFwiKTtcclxuICAgICAgICAgICAgaWYgKF8gPSBhY2NlcHQocmVzdWx0LmdldCkpIGRlc2NyaXB0b3IuZ2V0ID0gXztcclxuICAgICAgICAgICAgaWYgKF8gPSBhY2NlcHQocmVzdWx0LnNldCkpIGRlc2NyaXB0b3Iuc2V0ID0gXztcclxuICAgICAgICAgICAgaWYgKF8gPSBhY2NlcHQocmVzdWx0LmluaXQpKSBpbml0aWFsaXplcnMucHVzaChfKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoXyA9IGFjY2VwdChyZXN1bHQpKSB7XHJcbiAgICAgICAgICAgIGlmIChraW5kID09PSBcImZpZWxkXCIpIGluaXRpYWxpemVycy5wdXNoKF8pO1xyXG4gICAgICAgICAgICBlbHNlIGRlc2NyaXB0b3Jba2V5XSA9IF87XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKHRhcmdldCkgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgY29udGV4dEluLm5hbWUsIGRlc2NyaXB0b3IpO1xyXG4gICAgZG9uZSA9IHRydWU7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19ydW5Jbml0aWFsaXplcnModGhpc0FyZywgaW5pdGlhbGl6ZXJzLCB2YWx1ZSkge1xyXG4gICAgdmFyIHVzZVZhbHVlID0gYXJndW1lbnRzLmxlbmd0aCA+IDI7XHJcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGluaXRpYWxpemVycy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIHZhbHVlID0gdXNlVmFsdWUgPyBpbml0aWFsaXplcnNbaV0uY2FsbCh0aGlzQXJnLCB2YWx1ZSkgOiBpbml0aWFsaXplcnNbaV0uY2FsbCh0aGlzQXJnKTtcclxuICAgIH1cclxuICAgIHJldHVybiB1c2VWYWx1ZSA/IHZhbHVlIDogdm9pZCAwO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcHJvcEtleSh4KSB7XHJcbiAgICByZXR1cm4gdHlwZW9mIHggPT09IFwic3ltYm9sXCIgPyB4IDogXCJcIi5jb25jYXQoeCk7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19zZXRGdW5jdGlvbk5hbWUoZiwgbmFtZSwgcHJlZml4KSB7XHJcbiAgICBpZiAodHlwZW9mIG5hbWUgPT09IFwic3ltYm9sXCIpIG5hbWUgPSBuYW1lLmRlc2NyaXB0aW9uID8gXCJbXCIuY29uY2F0KG5hbWUuZGVzY3JpcHRpb24sIFwiXVwiKSA6IFwiXCI7XHJcbiAgICByZXR1cm4gT2JqZWN0LmRlZmluZVByb3BlcnR5KGYsIFwibmFtZVwiLCB7IGNvbmZpZ3VyYWJsZTogdHJ1ZSwgdmFsdWU6IHByZWZpeCA/IFwiXCIuY29uY2F0KHByZWZpeCwgXCIgXCIsIG5hbWUpIDogbmFtZSB9KTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX21ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKSB7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QubWV0YWRhdGEgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIFJlZmxlY3QubWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdGVyKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikge1xyXG4gICAgZnVuY3Rpb24gYWRvcHQodmFsdWUpIHsgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgUCA/IHZhbHVlIDogbmV3IFAoZnVuY3Rpb24gKHJlc29sdmUpIHsgcmVzb2x2ZSh2YWx1ZSk7IH0pOyB9XHJcbiAgICByZXR1cm4gbmV3IChQIHx8IChQID0gUHJvbWlzZSkpKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gcmVqZWN0ZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3JbXCJ0aHJvd1wiXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gc3RlcChyZXN1bHQpIHsgcmVzdWx0LmRvbmUgPyByZXNvbHZlKHJlc3VsdC52YWx1ZSkgOiBhZG9wdChyZXN1bHQudmFsdWUpLnRoZW4oZnVsZmlsbGVkLCByZWplY3RlZCk7IH1cclxuICAgICAgICBzdGVwKChnZW5lcmF0b3IgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSkpLm5leHQoKSk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZ2VuZXJhdG9yKHRoaXNBcmcsIGJvZHkpIHtcclxuICAgIHZhciBfID0geyBsYWJlbDogMCwgc2VudDogZnVuY3Rpb24oKSB7IGlmICh0WzBdICYgMSkgdGhyb3cgdFsxXTsgcmV0dXJuIHRbMV07IH0sIHRyeXM6IFtdLCBvcHM6IFtdIH0sIGYsIHksIHQsIGc7XHJcbiAgICByZXR1cm4gZyA9IHsgbmV4dDogdmVyYigwKSwgXCJ0aHJvd1wiOiB2ZXJiKDEpLCBcInJldHVyblwiOiB2ZXJiKDIpIH0sIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiAoZ1tTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzOyB9KSwgZztcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyByZXR1cm4gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIHN0ZXAoW24sIHZdKTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc3RlcChvcCkge1xyXG4gICAgICAgIGlmIChmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiR2VuZXJhdG9yIGlzIGFscmVhZHkgZXhlY3V0aW5nLlwiKTtcclxuICAgICAgICB3aGlsZSAoZyAmJiAoZyA9IDAsIG9wWzBdICYmIChfID0gMCkpLCBfKSB0cnkge1xyXG4gICAgICAgICAgICBpZiAoZiA9IDEsIHkgJiYgKHQgPSBvcFswXSAmIDIgPyB5W1wicmV0dXJuXCJdIDogb3BbMF0gPyB5W1widGhyb3dcIl0gfHwgKCh0ID0geVtcInJldHVyblwiXSkgJiYgdC5jYWxsKHkpLCAwKSA6IHkubmV4dCkgJiYgISh0ID0gdC5jYWxsKHksIG9wWzFdKSkuZG9uZSkgcmV0dXJuIHQ7XHJcbiAgICAgICAgICAgIGlmICh5ID0gMCwgdCkgb3AgPSBbb3BbMF0gJiAyLCB0LnZhbHVlXTtcclxuICAgICAgICAgICAgc3dpdGNoIChvcFswXSkge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAwOiBjYXNlIDE6IHQgPSBvcDsgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDQ6IF8ubGFiZWwrKzsgcmV0dXJuIHsgdmFsdWU6IG9wWzFdLCBkb25lOiBmYWxzZSB9O1xyXG4gICAgICAgICAgICAgICAgY2FzZSA1OiBfLmxhYmVsKys7IHkgPSBvcFsxXTsgb3AgPSBbMF07IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA3OiBvcCA9IF8ub3BzLnBvcCgpOyBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoISh0ID0gXy50cnlzLCB0ID0gdC5sZW5ndGggPiAwICYmIHRbdC5sZW5ndGggLSAxXSkgJiYgKG9wWzBdID09PSA2IHx8IG9wWzBdID09PSAyKSkgeyBfID0gMDsgY29udGludWU7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDMgJiYgKCF0IHx8IChvcFsxXSA+IHRbMF0gJiYgb3BbMV0gPCB0WzNdKSkpIHsgXy5sYWJlbCA9IG9wWzFdOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gNiAmJiBfLmxhYmVsIDwgdFsxXSkgeyBfLmxhYmVsID0gdFsxXTsgdCA9IG9wOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0ICYmIF8ubGFiZWwgPCB0WzJdKSB7IF8ubGFiZWwgPSB0WzJdOyBfLm9wcy5wdXNoKG9wKTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodFsyXSkgXy5vcHMucG9wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBvcCA9IGJvZHkuY2FsbCh0aGlzQXJnLCBfKTtcclxuICAgICAgICB9IGNhdGNoIChlKSB7IG9wID0gWzYsIGVdOyB5ID0gMDsgfSBmaW5hbGx5IHsgZiA9IHQgPSAwOyB9XHJcbiAgICAgICAgaWYgKG9wWzBdICYgNSkgdGhyb3cgb3BbMV07IHJldHVybiB7IHZhbHVlOiBvcFswXSA/IG9wWzFdIDogdm9pZCAwLCBkb25lOiB0cnVlIH07XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCB2YXIgX19jcmVhdGVCaW5kaW5nID0gT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xyXG4gICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcclxuICAgIHZhciBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihtLCBrKTtcclxuICAgIGlmICghZGVzYyB8fCAoXCJnZXRcIiBpbiBkZXNjID8gIW0uX19lc01vZHVsZSA6IGRlc2Mud3JpdGFibGUgfHwgZGVzYy5jb25maWd1cmFibGUpKSB7XHJcbiAgICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcclxuICAgIH1cclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgZGVzYyk7XHJcbn0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XHJcbiAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xyXG4gICAgb1trMl0gPSBtW2tdO1xyXG59KTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2V4cG9ydFN0YXIobSwgbykge1xyXG4gICAgZm9yICh2YXIgcCBpbiBtKSBpZiAocCAhPT0gXCJkZWZhdWx0XCIgJiYgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvLCBwKSkgX19jcmVhdGVCaW5kaW5nKG8sIG0sIHApO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX192YWx1ZXMobykge1xyXG4gICAgdmFyIHMgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgU3ltYm9sLml0ZXJhdG9yLCBtID0gcyAmJiBvW3NdLCBpID0gMDtcclxuICAgIGlmIChtKSByZXR1cm4gbS5jYWxsKG8pO1xyXG4gICAgaWYgKG8gJiYgdHlwZW9mIG8ubGVuZ3RoID09PSBcIm51bWJlclwiKSByZXR1cm4ge1xyXG4gICAgICAgIG5leHQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKG8gJiYgaSA+PSBvLmxlbmd0aCkgbyA9IHZvaWQgMDtcclxuICAgICAgICAgICAgcmV0dXJuIHsgdmFsdWU6IG8gJiYgb1tpKytdLCBkb25lOiAhbyB9O1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKHMgPyBcIk9iamVjdCBpcyBub3QgaXRlcmFibGUuXCIgOiBcIlN5bWJvbC5pdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3JlYWQobywgbikge1xyXG4gICAgdmFyIG0gPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb1tTeW1ib2wuaXRlcmF0b3JdO1xyXG4gICAgaWYgKCFtKSByZXR1cm4gbztcclxuICAgIHZhciBpID0gbS5jYWxsKG8pLCByLCBhciA9IFtdLCBlO1xyXG4gICAgdHJ5IHtcclxuICAgICAgICB3aGlsZSAoKG4gPT09IHZvaWQgMCB8fCBuLS0gPiAwKSAmJiAhKHIgPSBpLm5leHQoKSkuZG9uZSkgYXIucHVzaChyLnZhbHVlKTtcclxuICAgIH1cclxuICAgIGNhdGNoIChlcnJvcikgeyBlID0geyBlcnJvcjogZXJyb3IgfTsgfVxyXG4gICAgZmluYWxseSB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKHIgJiYgIXIuZG9uZSAmJiAobSA9IGlbXCJyZXR1cm5cIl0pKSBtLmNhbGwoaSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZpbmFsbHkgeyBpZiAoZSkgdGhyb3cgZS5lcnJvcjsgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGFyO1xyXG59XHJcblxyXG4vKiogQGRlcHJlY2F0ZWQgKi9cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkKCkge1xyXG4gICAgZm9yICh2YXIgYXIgPSBbXSwgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgYXIgPSBhci5jb25jYXQoX19yZWFkKGFyZ3VtZW50c1tpXSkpO1xyXG4gICAgcmV0dXJuIGFyO1xyXG59XHJcblxyXG4vKiogQGRlcHJlY2F0ZWQgKi9cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkQXJyYXlzKCkge1xyXG4gICAgZm9yICh2YXIgcyA9IDAsIGkgPSAwLCBpbCA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBpbDsgaSsrKSBzICs9IGFyZ3VtZW50c1tpXS5sZW5ndGg7XHJcbiAgICBmb3IgKHZhciByID0gQXJyYXkocyksIGsgPSAwLCBpID0gMDsgaSA8IGlsOyBpKyspXHJcbiAgICAgICAgZm9yICh2YXIgYSA9IGFyZ3VtZW50c1tpXSwgaiA9IDAsIGpsID0gYS5sZW5ndGg7IGogPCBqbDsgaisrLCBrKyspXHJcbiAgICAgICAgICAgIHJba10gPSBhW2pdO1xyXG4gICAgcmV0dXJuIHI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZEFycmF5KHRvLCBmcm9tLCBwYWNrKSB7XHJcbiAgICBpZiAocGFjayB8fCBhcmd1bWVudHMubGVuZ3RoID09PSAyKSBmb3IgKHZhciBpID0gMCwgbCA9IGZyb20ubGVuZ3RoLCBhcjsgaSA8IGw7IGkrKykge1xyXG4gICAgICAgIGlmIChhciB8fCAhKGkgaW4gZnJvbSkpIHtcclxuICAgICAgICAgICAgaWYgKCFhcikgYXIgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChmcm9tLCAwLCBpKTtcclxuICAgICAgICAgICAgYXJbaV0gPSBmcm9tW2ldO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiB0by5jb25jYXQoYXIgfHwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoZnJvbSkpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdCh2KSB7XHJcbiAgICByZXR1cm4gdGhpcyBpbnN0YW5jZW9mIF9fYXdhaXQgPyAodGhpcy52ID0gdiwgdGhpcykgOiBuZXcgX19hd2FpdCh2KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNHZW5lcmF0b3IodGhpc0FyZywgX2FyZ3VtZW50cywgZ2VuZXJhdG9yKSB7XHJcbiAgICBpZiAoIVN5bWJvbC5hc3luY0l0ZXJhdG9yKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgdmFyIGcgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSksIGksIHEgPSBbXTtcclxuICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyBpZiAoZ1tuXSkgaVtuXSA9IGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAoYSwgYikgeyBxLnB1c2goW24sIHYsIGEsIGJdKSA+IDEgfHwgcmVzdW1lKG4sIHYpOyB9KTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gcmVzdW1lKG4sIHYpIHsgdHJ5IHsgc3RlcChnW25dKHYpKTsgfSBjYXRjaCAoZSkgeyBzZXR0bGUocVswXVszXSwgZSk7IH0gfVxyXG4gICAgZnVuY3Rpb24gc3RlcChyKSB7IHIudmFsdWUgaW5zdGFuY2VvZiBfX2F3YWl0ID8gUHJvbWlzZS5yZXNvbHZlKHIudmFsdWUudikudGhlbihmdWxmaWxsLCByZWplY3QpIDogc2V0dGxlKHFbMF1bMl0sIHIpOyB9XHJcbiAgICBmdW5jdGlvbiBmdWxmaWxsKHZhbHVlKSB7IHJlc3VtZShcIm5leHRcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiByZWplY3QodmFsdWUpIHsgcmVzdW1lKFwidGhyb3dcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiBzZXR0bGUoZiwgdikgeyBpZiAoZih2KSwgcS5zaGlmdCgpLCBxLmxlbmd0aCkgcmVzdW1lKHFbMF1bMF0sIHFbMF1bMV0pOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jRGVsZWdhdG9yKG8pIHtcclxuICAgIHZhciBpLCBwO1xyXG4gICAgcmV0dXJuIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiLCBmdW5jdGlvbiAoZSkgeyB0aHJvdyBlOyB9KSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobiwgZikgeyBpW25dID0gb1tuXSA/IGZ1bmN0aW9uICh2KSB7IHJldHVybiAocCA9ICFwKSA/IHsgdmFsdWU6IF9fYXdhaXQob1tuXSh2KSksIGRvbmU6IGZhbHNlIH0gOiBmID8gZih2KSA6IHY7IH0gOiBmOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jVmFsdWVzKG8pIHtcclxuICAgIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICB2YXIgbSA9IG9bU3ltYm9sLmFzeW5jSXRlcmF0b3JdLCBpO1xyXG4gICAgcmV0dXJuIG0gPyBtLmNhbGwobykgOiAobyA9IHR5cGVvZiBfX3ZhbHVlcyA9PT0gXCJmdW5jdGlvblwiID8gX192YWx1ZXMobykgOiBvW1N5bWJvbC5pdGVyYXRvcl0oKSwgaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGkpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IGlbbl0gPSBvW25dICYmIGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7IHYgPSBvW25dKHYpLCBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCB2LmRvbmUsIHYudmFsdWUpOyB9KTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgZCwgdikgeyBQcm9taXNlLnJlc29sdmUodikudGhlbihmdW5jdGlvbih2KSB7IHJlc29sdmUoeyB2YWx1ZTogdiwgZG9uZTogZCB9KTsgfSwgcmVqZWN0KTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19tYWtlVGVtcGxhdGVPYmplY3QoY29va2VkLCByYXcpIHtcclxuICAgIGlmIChPYmplY3QuZGVmaW5lUHJvcGVydHkpIHsgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvb2tlZCwgXCJyYXdcIiwgeyB2YWx1ZTogcmF3IH0pOyB9IGVsc2UgeyBjb29rZWQucmF3ID0gcmF3OyB9XHJcbiAgICByZXR1cm4gY29va2VkO1xyXG59O1xyXG5cclxudmFyIF9fc2V0TW9kdWxlRGVmYXVsdCA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgdikge1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIFwiZGVmYXVsdFwiLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2IH0pO1xyXG59KSA6IGZ1bmN0aW9uKG8sIHYpIHtcclxuICAgIG9bXCJkZWZhdWx0XCJdID0gdjtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydFN0YXIobW9kKSB7XHJcbiAgICBpZiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSByZXR1cm4gbW9kO1xyXG4gICAgdmFyIHJlc3VsdCA9IHt9O1xyXG4gICAgaWYgKG1vZCAhPSBudWxsKSBmb3IgKHZhciBrIGluIG1vZCkgaWYgKGsgIT09IFwiZGVmYXVsdFwiICYmIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChtb2QsIGspKSBfX2NyZWF0ZUJpbmRpbmcocmVzdWx0LCBtb2QsIGspO1xyXG4gICAgX19zZXRNb2R1bGVEZWZhdWx0KHJlc3VsdCwgbW9kKTtcclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydERlZmF1bHQobW9kKSB7XHJcbiAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IGRlZmF1bHQ6IG1vZCB9O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZEdldChyZWNlaXZlciwgc3RhdGUsIGtpbmQsIGYpIHtcclxuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIGdldHRlclwiKTtcclxuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xyXG4gICAgcmV0dXJuIGtpbmQgPT09IFwibVwiID8gZiA6IGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyKSA6IGYgPyBmLnZhbHVlIDogc3RhdGUuZ2V0KHJlY2VpdmVyKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fY2xhc3NQcml2YXRlRmllbGRTZXQocmVjZWl2ZXIsIHN0YXRlLCB2YWx1ZSwga2luZCwgZikge1xyXG4gICAgaWYgKGtpbmQgPT09IFwibVwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBtZXRob2QgaXMgbm90IHdyaXRhYmxlXCIpO1xyXG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xyXG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3Qgd3JpdGUgcHJpdmF0ZSBtZW1iZXIgdG8gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcclxuICAgIHJldHVybiAoa2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIsIHZhbHVlKSA6IGYgPyBmLnZhbHVlID0gdmFsdWUgOiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSksIHZhbHVlO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZEluKHN0YXRlLCByZWNlaXZlcikge1xyXG4gICAgaWYgKHJlY2VpdmVyID09PSBudWxsIHx8ICh0eXBlb2YgcmVjZWl2ZXIgIT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHJlY2VpdmVyICE9PSBcImZ1bmN0aW9uXCIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHVzZSAnaW4nIG9wZXJhdG9yIG9uIG5vbi1vYmplY3RcIik7XHJcbiAgICByZXR1cm4gdHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciA9PT0gc3RhdGUgOiBzdGF0ZS5oYXMocmVjZWl2ZXIpO1xyXG59XHJcbiIsICIvKipcbiAqIENvcHlyaWdodCAoYykgMjAyMCwgUGVjdWxpYXIgVmVudHVyZXMsIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKi9cblxuY2xhc3MgSnNvbkVycm9yIGV4dGVuZHMgRXJyb3Ige1xyXG4gICAgY29uc3RydWN0b3IobWVzc2FnZSwgaW5uZXJFcnJvcikge1xyXG4gICAgICAgIHN1cGVyKGlubmVyRXJyb3JcclxuICAgICAgICAgICAgPyBgJHttZXNzYWdlfS4gU2VlIHRoZSBpbm5lciBleGNlcHRpb24gZm9yIG1vcmUgZGV0YWlscy5gXHJcbiAgICAgICAgICAgIDogbWVzc2FnZSk7XHJcbiAgICAgICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZTtcclxuICAgICAgICB0aGlzLmlubmVyRXJyb3IgPSBpbm5lckVycm9yO1xyXG4gICAgfVxyXG59XG5cbmNsYXNzIFRyYW5zZm9ybUVycm9yIGV4dGVuZHMgSnNvbkVycm9yIHtcclxuICAgIGNvbnN0cnVjdG9yKHNjaGVtYSwgbWVzc2FnZSwgaW5uZXJFcnJvcikge1xyXG4gICAgICAgIHN1cGVyKG1lc3NhZ2UsIGlubmVyRXJyb3IpO1xyXG4gICAgICAgIHRoaXMuc2NoZW1hID0gc2NoZW1hO1xyXG4gICAgfVxyXG59XG5cbmNsYXNzIFBhcnNlckVycm9yIGV4dGVuZHMgVHJhbnNmb3JtRXJyb3Ige1xyXG4gICAgY29uc3RydWN0b3Ioc2NoZW1hLCBtZXNzYWdlLCBpbm5lckVycm9yKSB7XHJcbiAgICAgICAgc3VwZXIoc2NoZW1hLCBgSlNPTiBkb2Vzbid0IG1hdGNoIHRvICcke3NjaGVtYS50YXJnZXQubmFtZX0nIHNjaGVtYS4gJHttZXNzYWdlfWAsIGlubmVyRXJyb3IpO1xyXG4gICAgfVxyXG59XG5cbmNsYXNzIFZhbGlkYXRpb25FcnJvciBleHRlbmRzIEpzb25FcnJvciB7XHJcbn1cblxuY2xhc3MgU2VyaWFsaXplckVycm9yIGV4dGVuZHMgSnNvbkVycm9yIHtcclxuICAgIGNvbnN0cnVjdG9yKHNjaGVtYU5hbWUsIG1lc3NhZ2UsIGlubmVyRXJyb3IpIHtcclxuICAgICAgICBzdXBlcihgQ2Fubm90IHNlcmlhbGl6ZSBieSAnJHtzY2hlbWFOYW1lfScgc2NoZW1hLiAke21lc3NhZ2V9YCwgaW5uZXJFcnJvcik7XHJcbiAgICAgICAgdGhpcy5zY2hlbWFOYW1lID0gc2NoZW1hTmFtZTtcclxuICAgIH1cclxufVxuXG5jbGFzcyBLZXlFcnJvciBleHRlbmRzIFBhcnNlckVycm9yIHtcclxuICAgIGNvbnN0cnVjdG9yKHNjaGVtYSwga2V5cywgZXJyb3JzID0ge30pIHtcclxuICAgICAgICBzdXBlcihzY2hlbWEsIFwiU29tZSBrZXlzIGRvZXNuJ3QgbWF0Y2ggdG8gc2NoZW1hXCIpO1xyXG4gICAgICAgIHRoaXMua2V5cyA9IGtleXM7XHJcbiAgICAgICAgdGhpcy5lcnJvcnMgPSBlcnJvcnM7XHJcbiAgICB9XHJcbn1cblxudmFyIEpzb25Qcm9wVHlwZXM7XHJcbihmdW5jdGlvbiAoSnNvblByb3BUeXBlcykge1xyXG4gICAgSnNvblByb3BUeXBlc1tKc29uUHJvcFR5cGVzW1wiQW55XCJdID0gMF0gPSBcIkFueVwiO1xyXG4gICAgSnNvblByb3BUeXBlc1tKc29uUHJvcFR5cGVzW1wiQm9vbGVhblwiXSA9IDFdID0gXCJCb29sZWFuXCI7XHJcbiAgICBKc29uUHJvcFR5cGVzW0pzb25Qcm9wVHlwZXNbXCJOdW1iZXJcIl0gPSAyXSA9IFwiTnVtYmVyXCI7XHJcbiAgICBKc29uUHJvcFR5cGVzW0pzb25Qcm9wVHlwZXNbXCJTdHJpbmdcIl0gPSAzXSA9IFwiU3RyaW5nXCI7XHJcbn0pKEpzb25Qcm9wVHlwZXMgfHwgKEpzb25Qcm9wVHlwZXMgPSB7fSkpO1xuXG5mdW5jdGlvbiBjaGVja1R5cGUodmFsdWUsIHR5cGUpIHtcclxuICAgIHN3aXRjaCAodHlwZSkge1xyXG4gICAgICAgIGNhc2UgSnNvblByb3BUeXBlcy5Cb29sZWFuOlxyXG4gICAgICAgICAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcImJvb2xlYW5cIjtcclxuICAgICAgICBjYXNlIEpzb25Qcm9wVHlwZXMuTnVtYmVyOlxyXG4gICAgICAgICAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcIm51bWJlclwiO1xyXG4gICAgICAgIGNhc2UgSnNvblByb3BUeXBlcy5TdHJpbmc6XHJcbiAgICAgICAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCI7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdHJ1ZTtcclxufVxyXG5mdW5jdGlvbiB0aHJvd0lmVHlwZUlzV3JvbmcodmFsdWUsIHR5cGUpIHtcclxuICAgIGlmICghY2hlY2tUeXBlKHZhbHVlLCB0eXBlKSkge1xyXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYFZhbHVlIG11c3QgYmUgJHtKc29uUHJvcFR5cGVzW3R5cGVdfWApO1xyXG4gICAgfVxyXG59XHJcbmZ1bmN0aW9uIGlzQ29udmVydGlibGUodGFyZ2V0KSB7XHJcbiAgICBpZiAodGFyZ2V0ICYmIHRhcmdldC5wcm90b3R5cGUpIHtcclxuICAgICAgICBpZiAodGFyZ2V0LnByb3RvdHlwZS50b0pTT04gJiYgdGFyZ2V0LnByb3RvdHlwZS5mcm9tSlNPTikge1xyXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiBpc0NvbnZlcnRpYmxlKHRhcmdldC5wcm90b3R5cGUpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIHJldHVybiAhISh0YXJnZXQgJiYgdGFyZ2V0LnRvSlNPTiAmJiB0YXJnZXQuZnJvbUpTT04pO1xyXG4gICAgfVxyXG59XG5cbmNsYXNzIEpzb25TY2hlbWFTdG9yYWdlIHtcclxuICAgIGNvbnN0cnVjdG9yKCkge1xyXG4gICAgICAgIHRoaXMuaXRlbXMgPSBuZXcgTWFwKCk7XHJcbiAgICB9XHJcbiAgICBoYXModGFyZ2V0KSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaXRlbXMuaGFzKHRhcmdldCkgfHwgISF0aGlzLmZpbmRQYXJlbnRTY2hlbWEodGFyZ2V0KTtcclxuICAgIH1cclxuICAgIGdldCh0YXJnZXQpIHtcclxuICAgICAgICBjb25zdCBzY2hlbWEgPSB0aGlzLml0ZW1zLmdldCh0YXJnZXQpIHx8IHRoaXMuZmluZFBhcmVudFNjaGVtYSh0YXJnZXQpO1xyXG4gICAgICAgIGlmICghc2NoZW1hKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBnZXQgc2NoZW1hIGZvciBjdXJyZW50IHRhcmdldFwiKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHNjaGVtYTtcclxuICAgIH1cclxuICAgIGNyZWF0ZSh0YXJnZXQpIHtcclxuICAgICAgICBjb25zdCBzY2hlbWEgPSB7IG5hbWVzOiB7fSB9O1xyXG4gICAgICAgIGNvbnN0IHBhcmVudFNjaGVtYSA9IHRoaXMuZmluZFBhcmVudFNjaGVtYSh0YXJnZXQpO1xyXG4gICAgICAgIGlmIChwYXJlbnRTY2hlbWEpIHtcclxuICAgICAgICAgICAgT2JqZWN0LmFzc2lnbihzY2hlbWEsIHBhcmVudFNjaGVtYSk7XHJcbiAgICAgICAgICAgIHNjaGVtYS5uYW1lcyA9IHt9O1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IG5hbWUgaW4gcGFyZW50U2NoZW1hLm5hbWVzKSB7XHJcbiAgICAgICAgICAgICAgICBzY2hlbWEubmFtZXNbbmFtZV0gPSBPYmplY3QuYXNzaWduKHt9LCBwYXJlbnRTY2hlbWEubmFtZXNbbmFtZV0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHNjaGVtYS50YXJnZXQgPSB0YXJnZXQ7XHJcbiAgICAgICAgcmV0dXJuIHNjaGVtYTtcclxuICAgIH1cclxuICAgIHNldCh0YXJnZXQsIHNjaGVtYSkge1xyXG4gICAgICAgIHRoaXMuaXRlbXMuc2V0KHRhcmdldCwgc2NoZW1hKTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuICAgIGZpbmRQYXJlbnRTY2hlbWEodGFyZ2V0KSB7XHJcbiAgICAgICAgY29uc3QgcGFyZW50ID0gdGFyZ2V0Ll9fcHJvdG9fXztcclxuICAgICAgICBpZiAocGFyZW50KSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHNjaGVtYSA9IHRoaXMuaXRlbXMuZ2V0KHBhcmVudCk7XHJcbiAgICAgICAgICAgIHJldHVybiBzY2hlbWEgfHwgdGhpcy5maW5kUGFyZW50U2NoZW1hKHBhcmVudCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG59XG5cbmNvbnN0IERFRkFVTFRfU0NIRU1BID0gXCJkZWZhdWx0XCI7XHJcbmNvbnN0IHNjaGVtYVN0b3JhZ2UgPSBuZXcgSnNvblNjaGVtYVN0b3JhZ2UoKTtcblxuY2xhc3MgUGF0dGVyblZhbGlkYXRpb24ge1xyXG4gICAgY29uc3RydWN0b3IocGF0dGVybikge1xyXG4gICAgICAgIHRoaXMucGF0dGVybiA9IG5ldyBSZWdFeHAocGF0dGVybik7XHJcbiAgICB9XHJcbiAgICB2YWxpZGF0ZSh2YWx1ZSkge1xyXG4gICAgICAgIGNvbnN0IHBhdHRlcm4gPSBuZXcgUmVnRXhwKHRoaXMucGF0dGVybi5zb3VyY2UsIHRoaXMucGF0dGVybi5mbGFncyk7XHJcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJzdHJpbmdcIikge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKFwiSW5jb21pbmcgdmFsdWUgbXVzdCBiZSBzdHJpbmdcIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghcGF0dGVybi5leGVjKHZhbHVlKSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKGBWYWx1ZSBkb2Vzbid0IG1hdGNoIHRvIHBhdHRlcm4gJyR7cGF0dGVybi50b1N0cmluZygpfSdgKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cblxuY2xhc3MgSW5jbHVzaXZlVmFsaWRhdGlvbiB7XHJcbiAgICBjb25zdHJ1Y3RvcihtaW4gPSBOdW1iZXIuTUlOX1ZBTFVFLCBtYXggPSBOdW1iZXIuTUFYX1ZBTFVFKSB7XHJcbiAgICAgICAgdGhpcy5taW4gPSBtaW47XHJcbiAgICAgICAgdGhpcy5tYXggPSBtYXg7XHJcbiAgICB9XHJcbiAgICB2YWxpZGF0ZSh2YWx1ZSkge1xyXG4gICAgICAgIHRocm93SWZUeXBlSXNXcm9uZyh2YWx1ZSwgSnNvblByb3BUeXBlcy5OdW1iZXIpO1xyXG4gICAgICAgIGlmICghKHRoaXMubWluIDw9IHZhbHVlICYmIHZhbHVlIDw9IHRoaXMubWF4KSkge1xyXG4gICAgICAgICAgICBjb25zdCBtaW4gPSB0aGlzLm1pbiA9PT0gTnVtYmVyLk1JTl9WQUxVRSA/IFwiTUlOXCIgOiB0aGlzLm1pbjtcclxuICAgICAgICAgICAgY29uc3QgbWF4ID0gdGhpcy5tYXggPT09IE51bWJlci5NQVhfVkFMVUUgPyBcIk1BWFwiIDogdGhpcy5tYXg7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoYFZhbHVlIGRvZXNuJ3QgbWF0Y2ggdG8gZGlhcGFzb24gWyR7bWlufSwke21heH1dYCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XG5cbmNsYXNzIEV4Y2x1c2l2ZVZhbGlkYXRpb24ge1xyXG4gICAgY29uc3RydWN0b3IobWluID0gTnVtYmVyLk1JTl9WQUxVRSwgbWF4ID0gTnVtYmVyLk1BWF9WQUxVRSkge1xyXG4gICAgICAgIHRoaXMubWluID0gbWluO1xyXG4gICAgICAgIHRoaXMubWF4ID0gbWF4O1xyXG4gICAgfVxyXG4gICAgdmFsaWRhdGUodmFsdWUpIHtcclxuICAgICAgICB0aHJvd0lmVHlwZUlzV3JvbmcodmFsdWUsIEpzb25Qcm9wVHlwZXMuTnVtYmVyKTtcclxuICAgICAgICBpZiAoISh0aGlzLm1pbiA8IHZhbHVlICYmIHZhbHVlIDwgdGhpcy5tYXgpKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IG1pbiA9IHRoaXMubWluID09PSBOdW1iZXIuTUlOX1ZBTFVFID8gXCJNSU5cIiA6IHRoaXMubWluO1xyXG4gICAgICAgICAgICBjb25zdCBtYXggPSB0aGlzLm1heCA9PT0gTnVtYmVyLk1BWF9WQUxVRSA/IFwiTUFYXCIgOiB0aGlzLm1heDtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihgVmFsdWUgZG9lc24ndCBtYXRjaCB0byBkaWFwYXNvbiAoJHttaW59LCR7bWF4fSlgKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cblxuY2xhc3MgTGVuZ3RoVmFsaWRhdGlvbiB7XHJcbiAgICBjb25zdHJ1Y3RvcihsZW5ndGgsIG1pbkxlbmd0aCwgbWF4TGVuZ3RoKSB7XHJcbiAgICAgICAgdGhpcy5sZW5ndGggPSBsZW5ndGg7XHJcbiAgICAgICAgdGhpcy5taW5MZW5ndGggPSBtaW5MZW5ndGg7XHJcbiAgICAgICAgdGhpcy5tYXhMZW5ndGggPSBtYXhMZW5ndGg7XHJcbiAgICB9XHJcbiAgICB2YWxpZGF0ZSh2YWx1ZSkge1xyXG4gICAgICAgIGlmICh0aGlzLmxlbmd0aCAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIGlmICh2YWx1ZS5sZW5ndGggIT09IHRoaXMubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKGBWYWx1ZSBsZW5ndGggbXVzdCBiZSBleGFjdGx5ICR7dGhpcy5sZW5ndGh9LmApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHRoaXMubWluTGVuZ3RoICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgaWYgKHZhbHVlLmxlbmd0aCA8IHRoaXMubWluTGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKGBWYWx1ZSBsZW5ndGggbXVzdCBiZSBtb3JlIHRoYW4gJHt0aGlzLm1pbkxlbmd0aH0uYCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHRoaXMubWF4TGVuZ3RoICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgaWYgKHZhbHVlLmxlbmd0aCA+IHRoaXMubWF4TGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKGBWYWx1ZSBsZW5ndGggbXVzdCBiZSBsZXNzIHRoYW4gJHt0aGlzLm1heExlbmd0aH0uYCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cblxuY2xhc3MgRW51bWVyYXRpb25WYWxpZGF0aW9uIHtcclxuICAgIGNvbnN0cnVjdG9yKGVudW1lcmF0aW9uKSB7XHJcbiAgICAgICAgdGhpcy5lbnVtZXJhdGlvbiA9IGVudW1lcmF0aW9uO1xyXG4gICAgfVxyXG4gICAgdmFsaWRhdGUodmFsdWUpIHtcclxuICAgICAgICB0aHJvd0lmVHlwZUlzV3JvbmcodmFsdWUsIEpzb25Qcm9wVHlwZXMuU3RyaW5nKTtcclxuICAgICAgICBpZiAoIXRoaXMuZW51bWVyYXRpb24uaW5jbHVkZXModmFsdWUpKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoYFZhbHVlIG11c3QgYmUgb25lIG9mICR7dGhpcy5lbnVtZXJhdGlvbi5tYXAoKHYpID0+IGAnJHt2fSdgKS5qb2luKFwiLCBcIil9YCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XG5cbmNsYXNzIEpzb25UcmFuc2Zvcm0ge1xyXG4gICAgc3RhdGljIGNoZWNrVmFsdWVzKGRhdGEsIHNjaGVtYUl0ZW0pIHtcclxuICAgICAgICBjb25zdCB2YWx1ZXMgPSBBcnJheS5pc0FycmF5KGRhdGEpID8gZGF0YSA6IFtkYXRhXTtcclxuICAgICAgICBmb3IgKGNvbnN0IHZhbHVlIG9mIHZhbHVlcykge1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHZhbGlkYXRpb24gb2Ygc2NoZW1hSXRlbS52YWxpZGF0aW9ucykge1xyXG4gICAgICAgICAgICAgICAgaWYgKHZhbGlkYXRpb24gaW5zdGFuY2VvZiBMZW5ndGhWYWxpZGF0aW9uICYmIHNjaGVtYUl0ZW0ucmVwZWF0ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uLnZhbGlkYXRlKGRhdGEpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGlvbi52YWxpZGF0ZSh2YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBzdGF0aWMgY2hlY2tUeXBlcyh2YWx1ZSwgc2NoZW1hSXRlbSkge1xyXG4gICAgICAgIGlmIChzY2hlbWFJdGVtLnJlcGVhdGVkICYmICFBcnJheS5pc0FycmF5KHZhbHVlKSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiVmFsdWUgbXVzdCBiZSBBcnJheVwiKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHR5cGVvZiBzY2hlbWFJdGVtLnR5cGUgPT09IFwibnVtYmVyXCIpIHtcclxuICAgICAgICAgICAgY29uc3QgdmFsdWVzID0gQXJyYXkuaXNBcnJheSh2YWx1ZSkgPyB2YWx1ZSA6IFt2YWx1ZV07XHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgdiBvZiB2YWx1ZXMpIHtcclxuICAgICAgICAgICAgICAgIHRocm93SWZUeXBlSXNXcm9uZyh2LCBzY2hlbWFJdGVtLnR5cGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgc3RhdGljIGdldFNjaGVtYUJ5TmFtZShzY2hlbWEsIG5hbWUgPSBERUZBVUxUX1NDSEVNQSkge1xyXG4gICAgICAgIHJldHVybiB7IC4uLnNjaGVtYS5uYW1lc1tERUZBVUxUX1NDSEVNQV0sIC4uLnNjaGVtYS5uYW1lc1tuYW1lXSB9O1xyXG4gICAgfVxyXG59XG5cbmNsYXNzIEpzb25TZXJpYWxpemVyIGV4dGVuZHMgSnNvblRyYW5zZm9ybSB7XHJcbiAgICBzdGF0aWMgc2VyaWFsaXplKG9iaiwgb3B0aW9ucywgcmVwbGFjZXIsIHNwYWNlKSB7XHJcbiAgICAgICAgY29uc3QganNvbiA9IHRoaXMudG9KU09OKG9iaiwgb3B0aW9ucyk7XHJcbiAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGpzb24sIHJlcGxhY2VyLCBzcGFjZSk7XHJcbiAgICB9XHJcbiAgICBzdGF0aWMgdG9KU09OKG9iaiwgb3B0aW9ucyA9IHt9KSB7XHJcbiAgICAgICAgbGV0IHJlcztcclxuICAgICAgICBsZXQgdGFyZ2V0U2NoZW1hID0gb3B0aW9ucy50YXJnZXRTY2hlbWE7XHJcbiAgICAgICAgY29uc3Qgc2NoZW1hTmFtZSA9IG9wdGlvbnMuc2NoZW1hTmFtZSB8fCBERUZBVUxUX1NDSEVNQTtcclxuICAgICAgICBpZiAoaXNDb252ZXJ0aWJsZShvYmopKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBvYmoudG9KU09OKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KG9iaikpIHtcclxuICAgICAgICAgICAgcmVzID0gW107XHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBvYmopIHtcclxuICAgICAgICAgICAgICAgIHJlcy5wdXNoKHRoaXMudG9KU09OKGl0ZW0sIG9wdGlvbnMpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqID09PSBcIm9iamVjdFwiKSB7XHJcbiAgICAgICAgICAgIGlmICh0YXJnZXRTY2hlbWEgJiYgIXNjaGVtYVN0b3JhZ2UuaGFzKHRhcmdldFNjaGVtYSkpIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBKc29uRXJyb3IoXCJDYW5ub3QgZ2V0IHNjaGVtYSBmb3IgYHRhcmdldFNjaGVtYWAgcGFyYW1cIik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGFyZ2V0U2NoZW1hID0gKHRhcmdldFNjaGVtYSB8fCBvYmouY29uc3RydWN0b3IpO1xyXG4gICAgICAgICAgICBpZiAoc2NoZW1hU3RvcmFnZS5oYXModGFyZ2V0U2NoZW1hKSkge1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgc2NoZW1hID0gc2NoZW1hU3RvcmFnZS5nZXQodGFyZ2V0U2NoZW1hKTtcclxuICAgICAgICAgICAgICAgIHJlcyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbmFtZWRTY2hlbWEgPSB0aGlzLmdldFNjaGVtYUJ5TmFtZShzY2hlbWEsIHNjaGVtYU5hbWUpO1xyXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gbmFtZWRTY2hlbWEpIHtcclxuICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpdGVtID0gbmFtZWRTY2hlbWFba2V5XTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2JqSXRlbSA9IG9ialtrZXldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgdmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoaXRlbS5vcHRpb25hbCAmJiBvYmpJdGVtID09PSB1bmRlZmluZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCAoaXRlbS5kZWZhdWx0VmFsdWUgIT09IHVuZGVmaW5lZCAmJiBvYmpJdGVtID09PSBpdGVtLmRlZmF1bHRWYWx1ZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghaXRlbS5vcHRpb25hbCAmJiBvYmpJdGVtID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTZXJpYWxpemVyRXJyb3IodGFyZ2V0U2NoZW1hLm5hbWUsIGBQcm9wZXJ0eSAnJHtrZXl9JyBpcyByZXF1aXJlZC5gKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGl0ZW0udHlwZSA9PT0gXCJudW1iZXJcIikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGl0ZW0uY29udmVydGVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGl0ZW0ucmVwZWF0ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBvYmpJdGVtLm1hcCgoZWwpID0+IGl0ZW0uY29udmVydGVyLnRvSlNPTihlbCwgb2JqKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGl0ZW0uY29udmVydGVyLnRvSlNPTihvYmpJdGVtLCBvYmopO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gb2JqSXRlbTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpdGVtLnJlcGVhdGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBvYmpJdGVtLm1hcCgoZWwpID0+IHRoaXMudG9KU09OKGVsLCB7IHNjaGVtYU5hbWUgfSkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSB0aGlzLnRvSlNPTihvYmpJdGVtLCB7IHNjaGVtYU5hbWUgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jaGVja1R5cGVzKHZhbHVlLCBpdGVtKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jaGVja1ZhbHVlcyh2YWx1ZSwgaXRlbSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc1tpdGVtLm5hbWUgfHwga2V5XSA9IHZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIFNlcmlhbGl6ZXJFcnJvcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTZXJpYWxpemVyRXJyb3Ioc2NoZW1hLnRhcmdldC5uYW1lLCBgUHJvcGVydHkgJyR7a2V5fScgaXMgd3JvbmcuICR7ZS5tZXNzYWdlfWAsIGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmVzID0ge307XHJcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBvYmopIHtcclxuICAgICAgICAgICAgICAgICAgICByZXNba2V5XSA9IHRoaXMudG9KU09OKG9ialtrZXldLCB7IHNjaGVtYU5hbWUgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHJlcyA9IG9iajtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJlcztcclxuICAgIH1cclxufVxuXG5jbGFzcyBKc29uUGFyc2VyIGV4dGVuZHMgSnNvblRyYW5zZm9ybSB7XHJcbiAgICBzdGF0aWMgcGFyc2UoZGF0YSwgb3B0aW9ucykge1xyXG4gICAgICAgIGNvbnN0IG9iaiA9IEpTT04ucGFyc2UoZGF0YSk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZnJvbUpTT04ob2JqLCBvcHRpb25zKTtcclxuICAgIH1cclxuICAgIHN0YXRpYyBmcm9tSlNPTih0YXJnZXQsIG9wdGlvbnMpIHtcclxuICAgICAgICBjb25zdCB0YXJnZXRTY2hlbWEgPSBvcHRpb25zLnRhcmdldFNjaGVtYTtcclxuICAgICAgICBjb25zdCBzY2hlbWFOYW1lID0gb3B0aW9ucy5zY2hlbWFOYW1lIHx8IERFRkFVTFRfU0NIRU1BO1xyXG4gICAgICAgIGNvbnN0IG9iaiA9IG5ldyB0YXJnZXRTY2hlbWEoKTtcclxuICAgICAgICBpZiAoaXNDb252ZXJ0aWJsZShvYmopKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBvYmouZnJvbUpTT04odGFyZ2V0KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3Qgc2NoZW1hID0gc2NoZW1hU3RvcmFnZS5nZXQodGFyZ2V0U2NoZW1hKTtcclxuICAgICAgICBjb25zdCBuYW1lZFNjaGVtYSA9IHRoaXMuZ2V0U2NoZW1hQnlOYW1lKHNjaGVtYSwgc2NoZW1hTmFtZSk7XHJcbiAgICAgICAgY29uc3Qga2V5RXJyb3JzID0ge307XHJcbiAgICAgICAgaWYgKG9wdGlvbnMuc3RyaWN0UHJvcGVydHkgJiYgIUFycmF5LmlzQXJyYXkodGFyZ2V0KSkge1xyXG4gICAgICAgICAgICBKc29uUGFyc2VyLmNoZWNrU3RyaWN0UHJvcGVydHkodGFyZ2V0LCBuYW1lZFNjaGVtYSwgc2NoZW1hKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gbmFtZWRTY2hlbWEpIHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGl0ZW0gPSBuYW1lZFNjaGVtYVtrZXldO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbmFtZSA9IGl0ZW0ubmFtZSB8fCBrZXk7XHJcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHRhcmdldFtuYW1lXTtcclxuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkICYmIChpdGVtLm9wdGlvbmFsIHx8IGl0ZW0uZGVmYXVsdFZhbHVlICE9PSB1bmRlZmluZWQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoIWl0ZW0ub3B0aW9uYWwgJiYgdmFsdWUgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZXJFcnJvcihzY2hlbWEsIGBQcm9wZXJ0eSAnJHtuYW1lfScgaXMgcmVxdWlyZWQuYCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNoZWNrVHlwZXModmFsdWUsIGl0ZW0pO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jaGVja1ZhbHVlcyh2YWx1ZSwgaXRlbSk7XHJcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIChpdGVtLnR5cGUpID09PSBcIm51bWJlclwiKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGl0ZW0uY29udmVydGVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpdGVtLnJlcGVhdGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmpba2V5XSA9IHZhbHVlLm1hcCgoZWwpID0+IGl0ZW0uY29udmVydGVyLmZyb21KU09OKGVsLCBvYmopKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ialtrZXldID0gaXRlbS5jb252ZXJ0ZXIuZnJvbUpTT04odmFsdWUsIG9iaik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9ialtrZXldID0gdmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3T3B0aW9ucyA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLi4ub3B0aW9ucyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0U2NoZW1hOiBpdGVtLnR5cGUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjaGVtYU5hbWUsXHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoaXRlbS5yZXBlYXRlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvYmpba2V5XSA9IHZhbHVlLm1hcCgoZWwpID0+IHRoaXMuZnJvbUpTT04oZWwsIG5ld09wdGlvbnMpKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9ialtrZXldID0gdGhpcy5mcm9tSlNPTih2YWx1ZSwgbmV3T3B0aW9ucyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIShlIGluc3RhbmNlb2YgUGFyc2VyRXJyb3IpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZSA9IG5ldyBQYXJzZXJFcnJvcihzY2hlbWEsIGBQcm9wZXJ0eSAnJHtrZXl9JyBpcyB3cm9uZy4gJHtlLm1lc3NhZ2V9YCwgZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5zdHJpY3RBbGxLZXlzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAga2V5RXJyb3JzW2tleV0gPSBlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoa2V5RXJyb3JzKTtcclxuICAgICAgICBpZiAoa2V5cy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEtleUVycm9yKHNjaGVtYSwga2V5cywga2V5RXJyb3JzKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIG9iajtcclxuICAgIH1cclxuICAgIHN0YXRpYyBjaGVja1N0cmljdFByb3BlcnR5KHRhcmdldCwgbmFtZWRTY2hlbWEsIHNjaGVtYSkge1xyXG4gICAgICAgIGNvbnN0IGpzb25Qcm9wcyA9IE9iamVjdC5rZXlzKHRhcmdldCk7XHJcbiAgICAgICAgY29uc3Qgc2NoZW1hUHJvcHMgPSBPYmplY3Qua2V5cyhuYW1lZFNjaGVtYSk7XHJcbiAgICAgICAgY29uc3Qga2V5cyA9IFtdO1xyXG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIGpzb25Qcm9wcykge1xyXG4gICAgICAgICAgICBpZiAoc2NoZW1hUHJvcHMuaW5kZXhPZihrZXkpID09PSAtMSkge1xyXG4gICAgICAgICAgICAgICAga2V5cy5wdXNoKGtleSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGtleXMubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBLZXlFcnJvcihzY2hlbWEsIGtleXMpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxuXG5mdW5jdGlvbiBnZXRWYWxpZGF0aW9ucyhpdGVtKSB7XHJcbiAgICBjb25zdCB2YWxpZGF0aW9ucyA9IFtdO1xyXG4gICAgaWYgKGl0ZW0ucGF0dGVybikge1xyXG4gICAgICAgIHZhbGlkYXRpb25zLnB1c2gobmV3IFBhdHRlcm5WYWxpZGF0aW9uKGl0ZW0ucGF0dGVybikpO1xyXG4gICAgfVxyXG4gICAgaWYgKGl0ZW0udHlwZSA9PT0gSnNvblByb3BUeXBlcy5OdW1iZXIgfHwgaXRlbS50eXBlID09PSBKc29uUHJvcFR5cGVzLkFueSkge1xyXG4gICAgICAgIGlmIChpdGVtLm1pbkluY2x1c2l2ZSAhPT0gdW5kZWZpbmVkIHx8IGl0ZW0ubWF4SW5jbHVzaXZlICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgdmFsaWRhdGlvbnMucHVzaChuZXcgSW5jbHVzaXZlVmFsaWRhdGlvbihpdGVtLm1pbkluY2x1c2l2ZSwgaXRlbS5tYXhJbmNsdXNpdmUpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGl0ZW0ubWluRXhjbHVzaXZlICE9PSB1bmRlZmluZWQgfHwgaXRlbS5tYXhFeGNsdXNpdmUgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICB2YWxpZGF0aW9ucy5wdXNoKG5ldyBFeGNsdXNpdmVWYWxpZGF0aW9uKGl0ZW0ubWluRXhjbHVzaXZlLCBpdGVtLm1heEV4Y2x1c2l2ZSkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoaXRlbS5lbnVtZXJhdGlvbiAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIHZhbGlkYXRpb25zLnB1c2gobmV3IEVudW1lcmF0aW9uVmFsaWRhdGlvbihpdGVtLmVudW1lcmF0aW9uKSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKGl0ZW0udHlwZSA9PT0gSnNvblByb3BUeXBlcy5TdHJpbmcgfHwgaXRlbS5yZXBlYXRlZCB8fCBpdGVtLnR5cGUgPT09IEpzb25Qcm9wVHlwZXMuQW55KSB7XHJcbiAgICAgICAgaWYgKGl0ZW0ubGVuZ3RoICE9PSB1bmRlZmluZWQgfHwgaXRlbS5taW5MZW5ndGggIT09IHVuZGVmaW5lZCB8fCBpdGVtLm1heExlbmd0aCAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIHZhbGlkYXRpb25zLnB1c2gobmV3IExlbmd0aFZhbGlkYXRpb24oaXRlbS5sZW5ndGgsIGl0ZW0ubWluTGVuZ3RoLCBpdGVtLm1heExlbmd0aCkpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiB2YWxpZGF0aW9ucztcclxufVxyXG5jb25zdCBKc29uUHJvcCA9IChvcHRpb25zID0ge30pID0+ICh0YXJnZXQsIHByb3BlcnR5S2V5KSA9PiB7XHJcbiAgICBjb25zdCBlcnJvck1lc3NhZ2UgPSBgQ2Fubm90IHNldCB0eXBlIGZvciAke3Byb3BlcnR5S2V5fSBwcm9wZXJ0eSBvZiAke3RhcmdldC5jb25zdHJ1Y3Rvci5uYW1lfSBzY2hlbWFgO1xyXG4gICAgbGV0IHNjaGVtYTtcclxuICAgIGlmICghc2NoZW1hU3RvcmFnZS5oYXModGFyZ2V0LmNvbnN0cnVjdG9yKSkge1xyXG4gICAgICAgIHNjaGVtYSA9IHNjaGVtYVN0b3JhZ2UuY3JlYXRlKHRhcmdldC5jb25zdHJ1Y3Rvcik7XHJcbiAgICAgICAgc2NoZW1hU3RvcmFnZS5zZXQodGFyZ2V0LmNvbnN0cnVjdG9yLCBzY2hlbWEpO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgc2NoZW1hID0gc2NoZW1hU3RvcmFnZS5nZXQodGFyZ2V0LmNvbnN0cnVjdG9yKTtcclxuICAgICAgICBpZiAoc2NoZW1hLnRhcmdldCAhPT0gdGFyZ2V0LmNvbnN0cnVjdG9yKSB7XHJcbiAgICAgICAgICAgIHNjaGVtYSA9IHNjaGVtYVN0b3JhZ2UuY3JlYXRlKHRhcmdldC5jb25zdHJ1Y3Rvcik7XHJcbiAgICAgICAgICAgIHNjaGVtYVN0b3JhZ2Uuc2V0KHRhcmdldC5jb25zdHJ1Y3Rvciwgc2NoZW1hKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBjb25zdCBkZWZhdWx0U2NoZW1hID0ge1xyXG4gICAgICAgIHR5cGU6IEpzb25Qcm9wVHlwZXMuQW55LFxyXG4gICAgICAgIHZhbGlkYXRpb25zOiBbXSxcclxuICAgIH07XHJcbiAgICBjb25zdCBjb3B5T3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oZGVmYXVsdFNjaGVtYSwgb3B0aW9ucyk7XHJcbiAgICBjb3B5T3B0aW9ucy52YWxpZGF0aW9ucyA9IGdldFZhbGlkYXRpb25zKGNvcHlPcHRpb25zKTtcclxuICAgIGlmICh0eXBlb2YgY29weU9wdGlvbnMudHlwZSAhPT0gXCJudW1iZXJcIikge1xyXG4gICAgICAgIGlmICghc2NoZW1hU3RvcmFnZS5oYXMoY29weU9wdGlvbnMudHlwZSkgJiYgIWlzQ29udmVydGlibGUoY29weU9wdGlvbnMudHlwZSkpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2Vycm9yTWVzc2FnZX0uIEFzc2lnbmluZyB0eXBlIGRvZXNuJ3QgaGF2ZSBzY2hlbWEuYCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgbGV0IHNjaGVtYU5hbWVzO1xyXG4gICAgaWYgKEFycmF5LmlzQXJyYXkob3B0aW9ucy5zY2hlbWEpKSB7XHJcbiAgICAgICAgc2NoZW1hTmFtZXMgPSBvcHRpb25zLnNjaGVtYTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIHNjaGVtYU5hbWVzID0gW29wdGlvbnMuc2NoZW1hIHx8IERFRkFVTFRfU0NIRU1BXTtcclxuICAgIH1cclxuICAgIGZvciAoY29uc3Qgc2NoZW1hTmFtZSBvZiBzY2hlbWFOYW1lcykge1xyXG4gICAgICAgIGlmICghc2NoZW1hLm5hbWVzW3NjaGVtYU5hbWVdKSB7XHJcbiAgICAgICAgICAgIHNjaGVtYS5uYW1lc1tzY2hlbWFOYW1lXSA9IHt9O1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBuYW1lZFNjaGVtYSA9IHNjaGVtYS5uYW1lc1tzY2hlbWFOYW1lXTtcclxuICAgICAgICBuYW1lZFNjaGVtYVtwcm9wZXJ0eUtleV0gPSBjb3B5T3B0aW9ucztcclxuICAgIH1cclxufTtcblxuZXhwb3J0IHsgSnNvbkVycm9yLCBKc29uUGFyc2VyLCBKc29uUHJvcCwgSnNvblByb3BUeXBlcywgSnNvblNlcmlhbGl6ZXIsIEtleUVycm9yLCBQYXJzZXJFcnJvciwgU2VyaWFsaXplckVycm9yLCBUcmFuc2Zvcm1FcnJvciwgVmFsaWRhdGlvbkVycm9yIH07XG4iLCAiLyohXG4gQ29weXJpZ2h0IChjKSBQZWN1bGlhciBWZW50dXJlcywgTExDXG4qL1xuXG5pbXBvcnQgeyBDb252ZXJ0LCBCdWZmZXJTb3VyY2VDb252ZXJ0ZXIsIGNvbWJpbmUgfSBmcm9tICdwdnRzdXRpbHMnO1xuZXhwb3J0IHsgQnVmZmVyU291cmNlQ29udmVydGVyIH0gZnJvbSAncHZ0c3V0aWxzJztcbmltcG9ydCB7IEFzblByb3AsIEFzblByb3BUeXBlcywgQXNuVHlwZSwgQXNuVHlwZVR5cGVzLCBBc25JbnRlZ2VyQ29udmVydGVyLCBBc25TZXJpYWxpemVyLCBBc25Db252ZXJ0IH0gZnJvbSAnQHBlY3VsaWFyL2FzbjEtc2NoZW1hJztcbmltcG9ydCB7IF9fZGVjb3JhdGUgfSBmcm9tICd0c2xpYic7XG5pbXBvcnQgeyBKc29uUHJvcCwgSnNvblByb3BUeXBlcyB9IGZyb20gJ0BwZWN1bGlhci9qc29uLXNjaGVtYSc7XG5pbXBvcnQgKiBhcyBhc24xIGZyb20gJ2FzbjFqcyc7XG5cbmNsYXNzIENyeXB0b0Vycm9yIGV4dGVuZHMgRXJyb3Ige1xufVxuXG5jbGFzcyBBbGdvcml0aG1FcnJvciBleHRlbmRzIENyeXB0b0Vycm9yIHtcbn1cblxuY2xhc3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FcnJvciBleHRlbmRzIENyeXB0b0Vycm9yIHtcbiAgICBjb25zdHJ1Y3RvcihtZXRob2ROYW1lKSB7XG4gICAgICAgIHN1cGVyKGBVbnN1cHBvcnRlZCBvcGVyYXRpb246ICR7bWV0aG9kTmFtZSA/IGAke21ldGhvZE5hbWV9YCA6IFwiXCJ9YCk7XG4gICAgfVxufVxuXG5jbGFzcyBPcGVyYXRpb25FcnJvciBleHRlbmRzIENyeXB0b0Vycm9yIHtcbn1cblxuY2xhc3MgUmVxdWlyZWRQcm9wZXJ0eUVycm9yIGV4dGVuZHMgQ3J5cHRvRXJyb3Ige1xuICAgIGNvbnN0cnVjdG9yKHByb3BOYW1lKSB7XG4gICAgICAgIHN1cGVyKGAke3Byb3BOYW1lfTogTWlzc2luZyByZXF1aXJlZCBwcm9wZXJ0eWApO1xuICAgIH1cbn1cblxuY2xhc3MgUGVtQ29udmVydGVyIHtcbiAgICBzdGF0aWMgdG9BcnJheUJ1ZmZlcihwZW0pIHtcbiAgICAgICAgY29uc3QgYmFzZTY0ID0gcGVtXG4gICAgICAgICAgICAucmVwbGFjZSgvLXs1fShCRUdJTnxFTkQpIC4qLXs1fS9nLCBcIlwiKVxuICAgICAgICAgICAgLnJlcGxhY2UoXCJcXHJcIiwgXCJcIilcbiAgICAgICAgICAgIC5yZXBsYWNlKFwiXFxuXCIsIFwiXCIpO1xuICAgICAgICByZXR1cm4gQ29udmVydC5Gcm9tQmFzZTY0KGJhc2U2NCk7XG4gICAgfVxuICAgIHN0YXRpYyB0b1VpbnQ4QXJyYXkocGVtKSB7XG4gICAgICAgIGNvbnN0IGJ5dGVzID0gdGhpcy50b0FycmF5QnVmZmVyKHBlbSk7XG4gICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShieXRlcyk7XG4gICAgfVxuICAgIHN0YXRpYyBmcm9tQnVmZmVyU291cmNlKGJ1ZmZlciwgdGFnKSB7XG4gICAgICAgIGNvbnN0IGJhc2U2NCA9IENvbnZlcnQuVG9CYXNlNjQoYnVmZmVyKTtcbiAgICAgICAgbGV0IHNsaWNlZDtcbiAgICAgICAgbGV0IG9mZnNldCA9IDA7XG4gICAgICAgIGNvbnN0IHJvd3MgPSBbXTtcbiAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgIHNsaWNlZCA9IGJhc2U2NC5zbGljZShvZmZzZXQsIG9mZnNldCA9IG9mZnNldCArIDY0KTtcbiAgICAgICAgICAgIGlmIChzbGljZWQubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgcm93cy5wdXNoKHNsaWNlZCk7XG4gICAgICAgICAgICAgICAgaWYgKHNsaWNlZC5sZW5ndGggPCA2NCkge1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCB1cHBlckNhc2VUYWcgPSB0YWcudG9VcHBlckNhc2UoKTtcbiAgICAgICAgcmV0dXJuIGAtLS0tLUJFR0lOICR7dXBwZXJDYXNlVGFnfS0tLS0tXFxuJHtyb3dzLmpvaW4oXCJcXG5cIil9XFxuLS0tLS1FTkQgJHt1cHBlckNhc2VUYWd9LS0tLS1gO1xuICAgIH1cbiAgICBzdGF0aWMgaXNQRU0oZGF0YSkge1xuICAgICAgICByZXR1cm4gLy0tLS0tQkVHSU4gListLS0tLVtBLVphLXowLTkrXFwvXFwrXFw9XFxzXFxuXSstLS0tLUVORCAuKy0tLS0tL2kudGVzdChkYXRhKTtcbiAgICB9XG4gICAgc3RhdGljIGdldFRhZ05hbWUocGVtKSB7XG4gICAgICAgIGlmICghdGhpcy5pc1BFTShwZW0pKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJCYWQgcGFyYW1ldGVyLiBJbmNvbWluZyBkYXRhIGlzIG5vdCByaWdodCBQRU1cIik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVzID0gLy0tLS0tQkVHSU4gKC4rKS0tLS0tLy5leGVjKHBlbSk7XG4gICAgICAgIGlmICghcmVzKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgZ2V0IHRhZyBmcm9tIFBFTVwiKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzWzFdO1xuICAgIH1cbiAgICBzdGF0aWMgaGFzVGFnTmFtZShwZW0sIHRhZ05hbWUpIHtcbiAgICAgICAgY29uc3QgdGFnID0gdGhpcy5nZXRUYWdOYW1lKHBlbSk7XG4gICAgICAgIHJldHVybiB0YWdOYW1lLnRvTG93ZXJDYXNlKCkgPT09IHRhZy50b0xvd2VyQ2FzZSgpO1xuICAgIH1cbiAgICBzdGF0aWMgaXNDZXJ0aWZpY2F0ZShwZW0pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFzVGFnTmFtZShwZW0sIFwiY2VydGlmaWNhdGVcIik7XG4gICAgfVxuICAgIHN0YXRpYyBpc0NlcnRpZmljYXRlUmVxdWVzdChwZW0pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFzVGFnTmFtZShwZW0sIFwiY2VydGlmaWNhdGUgcmVxdWVzdFwiKTtcbiAgICB9XG4gICAgc3RhdGljIGlzQ1JMKHBlbSkge1xuICAgICAgICByZXR1cm4gdGhpcy5oYXNUYWdOYW1lKHBlbSwgXCJ4NTA5IGNybFwiKTtcbiAgICB9XG4gICAgc3RhdGljIGlzUHVibGljS2V5KHBlbSkge1xuICAgICAgICByZXR1cm4gdGhpcy5oYXNUYWdOYW1lKHBlbSwgXCJwdWJsaWMga2V5XCIpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gaXNKV0soZGF0YSkge1xuICAgIHJldHVybiB0eXBlb2YgZGF0YSA9PT0gXCJvYmplY3RcIiAmJiBcImt0eVwiIGluIGRhdGE7XG59XG5cbmNsYXNzIFByb3ZpZGVyQ3J5cHRvIHtcbiAgICBhc3luYyBkaWdlc3QoLi4uYXJncykge1xuICAgICAgICB0aGlzLmNoZWNrRGlnZXN0LmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICByZXR1cm4gdGhpcy5vbkRpZ2VzdC5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9XG4gICAgY2hlY2tEaWdlc3QoYWxnb3JpdGhtLCBkYXRhKSB7XG4gICAgICAgIHRoaXMuY2hlY2tBbGdvcml0aG1OYW1lKGFsZ29yaXRobSk7XG4gICAgfVxuICAgIGFzeW5jIG9uRGlnZXN0KGFsZ29yaXRobSwgZGF0YSkge1xuICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FcnJvcihcImRpZ2VzdFwiKTtcbiAgICB9XG4gICAgYXN5bmMgZ2VuZXJhdGVLZXkoLi4uYXJncykge1xuICAgICAgICB0aGlzLmNoZWNrR2VuZXJhdGVLZXkuYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgIHJldHVybiB0aGlzLm9uR2VuZXJhdGVLZXkuYXBwbHkodGhpcywgYXJncyk7XG4gICAgfVxuICAgIGNoZWNrR2VuZXJhdGVLZXkoYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzLCAuLi5hcmdzKSB7XG4gICAgICAgIHRoaXMuY2hlY2tBbGdvcml0aG1OYW1lKGFsZ29yaXRobSk7XG4gICAgICAgIHRoaXMuY2hlY2tHZW5lcmF0ZUtleVBhcmFtcyhhbGdvcml0aG0pO1xuICAgICAgICBpZiAoIShrZXlVc2FnZXMgJiYga2V5VXNhZ2VzLmxlbmd0aCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYFVzYWdlcyBjYW5ub3QgYmUgZW1wdHkgd2hlbiBjcmVhdGluZyBhIGtleS5gKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgYWxsb3dlZFVzYWdlcztcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodGhpcy51c2FnZXMpKSB7XG4gICAgICAgICAgICBhbGxvd2VkVXNhZ2VzID0gdGhpcy51c2FnZXM7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBhbGxvd2VkVXNhZ2VzID0gdGhpcy51c2FnZXMucHJpdmF0ZUtleS5jb25jYXQodGhpcy51c2FnZXMucHVibGljS2V5KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNoZWNrS2V5VXNhZ2VzKGtleVVzYWdlcywgYWxsb3dlZFVzYWdlcyk7XG4gICAgfVxuICAgIGNoZWNrR2VuZXJhdGVLZXlQYXJhbXMoYWxnb3JpdGhtKSB7XG4gICAgfVxuICAgIGFzeW5jIG9uR2VuZXJhdGVLZXkoYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzLCAuLi5hcmdzKSB7XG4gICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkVycm9yKFwiZ2VuZXJhdGVLZXlcIik7XG4gICAgfVxuICAgIGFzeW5jIHNpZ24oLi4uYXJncykge1xuICAgICAgICB0aGlzLmNoZWNrU2lnbi5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgcmV0dXJuIHRoaXMub25TaWduLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH1cbiAgICBjaGVja1NpZ24oYWxnb3JpdGhtLCBrZXksIGRhdGEsIC4uLmFyZ3MpIHtcbiAgICAgICAgdGhpcy5jaGVja0FsZ29yaXRobU5hbWUoYWxnb3JpdGhtKTtcbiAgICAgICAgdGhpcy5jaGVja0FsZ29yaXRobVBhcmFtcyhhbGdvcml0aG0pO1xuICAgICAgICB0aGlzLmNoZWNrQ3J5cHRvS2V5KGtleSwgXCJzaWduXCIpO1xuICAgIH1cbiAgICBhc3luYyBvblNpZ24oYWxnb3JpdGhtLCBrZXksIGRhdGEsIC4uLmFyZ3MpIHtcbiAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXJyb3IoXCJzaWduXCIpO1xuICAgIH1cbiAgICBhc3luYyB2ZXJpZnkoLi4uYXJncykge1xuICAgICAgICB0aGlzLmNoZWNrVmVyaWZ5LmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICByZXR1cm4gdGhpcy5vblZlcmlmeS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9XG4gICAgY2hlY2tWZXJpZnkoYWxnb3JpdGhtLCBrZXksIHNpZ25hdHVyZSwgZGF0YSwgLi4uYXJncykge1xuICAgICAgICB0aGlzLmNoZWNrQWxnb3JpdGhtTmFtZShhbGdvcml0aG0pO1xuICAgICAgICB0aGlzLmNoZWNrQWxnb3JpdGhtUGFyYW1zKGFsZ29yaXRobSk7XG4gICAgICAgIHRoaXMuY2hlY2tDcnlwdG9LZXkoa2V5LCBcInZlcmlmeVwiKTtcbiAgICB9XG4gICAgYXN5bmMgb25WZXJpZnkoYWxnb3JpdGhtLCBrZXksIHNpZ25hdHVyZSwgZGF0YSwgLi4uYXJncykge1xuICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FcnJvcihcInZlcmlmeVwiKTtcbiAgICB9XG4gICAgYXN5bmMgZW5jcnlwdCguLi5hcmdzKSB7XG4gICAgICAgIHRoaXMuY2hlY2tFbmNyeXB0LmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICByZXR1cm4gdGhpcy5vbkVuY3J5cHQuYXBwbHkodGhpcywgYXJncyk7XG4gICAgfVxuICAgIGNoZWNrRW5jcnlwdChhbGdvcml0aG0sIGtleSwgZGF0YSwgb3B0aW9ucyA9IHt9LCAuLi5hcmdzKSB7XG4gICAgICAgIHRoaXMuY2hlY2tBbGdvcml0aG1OYW1lKGFsZ29yaXRobSk7XG4gICAgICAgIHRoaXMuY2hlY2tBbGdvcml0aG1QYXJhbXMoYWxnb3JpdGhtKTtcbiAgICAgICAgdGhpcy5jaGVja0NyeXB0b0tleShrZXksIG9wdGlvbnMua2V5VXNhZ2UgPyBcImVuY3J5cHRcIiA6IHZvaWQgMCk7XG4gICAgfVxuICAgIGFzeW5jIG9uRW5jcnlwdChhbGdvcml0aG0sIGtleSwgZGF0YSwgLi4uYXJncykge1xuICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FcnJvcihcImVuY3J5cHRcIik7XG4gICAgfVxuICAgIGFzeW5jIGRlY3J5cHQoLi4uYXJncykge1xuICAgICAgICB0aGlzLmNoZWNrRGVjcnlwdC5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgcmV0dXJuIHRoaXMub25EZWNyeXB0LmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH1cbiAgICBjaGVja0RlY3J5cHQoYWxnb3JpdGhtLCBrZXksIGRhdGEsIG9wdGlvbnMgPSB7fSwgLi4uYXJncykge1xuICAgICAgICB0aGlzLmNoZWNrQWxnb3JpdGhtTmFtZShhbGdvcml0aG0pO1xuICAgICAgICB0aGlzLmNoZWNrQWxnb3JpdGhtUGFyYW1zKGFsZ29yaXRobSk7XG4gICAgICAgIHRoaXMuY2hlY2tDcnlwdG9LZXkoa2V5LCBvcHRpb25zLmtleVVzYWdlID8gXCJkZWNyeXB0XCIgOiB2b2lkIDApO1xuICAgIH1cbiAgICBhc3luYyBvbkRlY3J5cHQoYWxnb3JpdGhtLCBrZXksIGRhdGEsIC4uLmFyZ3MpIHtcbiAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXJyb3IoXCJkZWNyeXB0XCIpO1xuICAgIH1cbiAgICBhc3luYyBkZXJpdmVCaXRzKC4uLmFyZ3MpIHtcbiAgICAgICAgdGhpcy5jaGVja0Rlcml2ZUJpdHMuYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgIHJldHVybiB0aGlzLm9uRGVyaXZlQml0cy5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9XG4gICAgY2hlY2tEZXJpdmVCaXRzKGFsZ29yaXRobSwgYmFzZUtleSwgbGVuZ3RoLCBvcHRpb25zID0ge30sIC4uLmFyZ3MpIHtcbiAgICAgICAgdGhpcy5jaGVja0FsZ29yaXRobU5hbWUoYWxnb3JpdGhtKTtcbiAgICAgICAgdGhpcy5jaGVja0FsZ29yaXRobVBhcmFtcyhhbGdvcml0aG0pO1xuICAgICAgICB0aGlzLmNoZWNrQ3J5cHRvS2V5KGJhc2VLZXksIG9wdGlvbnMua2V5VXNhZ2UgPyBcImRlcml2ZUJpdHNcIiA6IHZvaWQgMCk7XG4gICAgICAgIGlmIChsZW5ndGggJSA4ICE9PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgT3BlcmF0aW9uRXJyb3IoXCJsZW5ndGg6IElzIG5vdCBtdWx0aXBsZSBvZiA4XCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFzeW5jIG9uRGVyaXZlQml0cyhhbGdvcml0aG0sIGJhc2VLZXksIGxlbmd0aCwgLi4uYXJncykge1xuICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FcnJvcihcImRlcml2ZUJpdHNcIik7XG4gICAgfVxuICAgIGFzeW5jIGV4cG9ydEtleSguLi5hcmdzKSB7XG4gICAgICAgIHRoaXMuY2hlY2tFeHBvcnRLZXkuYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgIHJldHVybiB0aGlzLm9uRXhwb3J0S2V5LmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH1cbiAgICBjaGVja0V4cG9ydEtleShmb3JtYXQsIGtleSwgLi4uYXJncykge1xuICAgICAgICB0aGlzLmNoZWNrS2V5Rm9ybWF0KGZvcm1hdCk7XG4gICAgICAgIHRoaXMuY2hlY2tDcnlwdG9LZXkoa2V5KTtcbiAgICAgICAgaWYgKCFrZXkuZXh0cmFjdGFibGUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBDcnlwdG9FcnJvcihcImtleTogSXMgbm90IGV4dHJhY3RhYmxlXCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFzeW5jIG9uRXhwb3J0S2V5KGZvcm1hdCwga2V5LCAuLi5hcmdzKSB7XG4gICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkVycm9yKFwiZXhwb3J0S2V5XCIpO1xuICAgIH1cbiAgICBhc3luYyBpbXBvcnRLZXkoLi4uYXJncykge1xuICAgICAgICB0aGlzLmNoZWNrSW1wb3J0S2V5LmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICByZXR1cm4gdGhpcy5vbkltcG9ydEtleS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9XG4gICAgY2hlY2tJbXBvcnRLZXkoZm9ybWF0LCBrZXlEYXRhLCBhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMsIC4uLmFyZ3MpIHtcbiAgICAgICAgdGhpcy5jaGVja0tleUZvcm1hdChmb3JtYXQpO1xuICAgICAgICB0aGlzLmNoZWNrS2V5RGF0YShmb3JtYXQsIGtleURhdGEpO1xuICAgICAgICB0aGlzLmNoZWNrQWxnb3JpdGhtTmFtZShhbGdvcml0aG0pO1xuICAgICAgICB0aGlzLmNoZWNrSW1wb3J0UGFyYW1zKGFsZ29yaXRobSk7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHRoaXMudXNhZ2VzKSkge1xuICAgICAgICAgICAgdGhpcy5jaGVja0tleVVzYWdlcyhrZXlVc2FnZXMsIHRoaXMudXNhZ2VzKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhc3luYyBvbkltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcywgLi4uYXJncykge1xuICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FcnJvcihcImltcG9ydEtleVwiKTtcbiAgICB9XG4gICAgY2hlY2tBbGdvcml0aG1OYW1lKGFsZ29yaXRobSkge1xuICAgICAgICBpZiAoYWxnb3JpdGhtLm5hbWUudG9Mb3dlckNhc2UoKSAhPT0gdGhpcy5uYW1lLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBBbGdvcml0aG1FcnJvcihcIlVucmVjb2duaXplZCBuYW1lXCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGNoZWNrQWxnb3JpdGhtUGFyYW1zKGFsZ29yaXRobSkge1xuICAgIH1cbiAgICBjaGVja0Rlcml2ZWRLZXlQYXJhbXMoYWxnb3JpdGhtKSB7XG4gICAgfVxuICAgIGNoZWNrS2V5VXNhZ2VzKHVzYWdlcywgYWxsb3dlZCkge1xuICAgICAgICBmb3IgKGNvbnN0IHVzYWdlIG9mIHVzYWdlcykge1xuICAgICAgICAgICAgaWYgKGFsbG93ZWQuaW5kZXhPZih1c2FnZSkgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjcmVhdGUgYSBrZXkgdXNpbmcgdGhlIHNwZWNpZmllZCBrZXkgdXNhZ2VzXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIGNoZWNrQ3J5cHRvS2V5KGtleSwga2V5VXNhZ2UpIHtcbiAgICAgICAgdGhpcy5jaGVja0FsZ29yaXRobU5hbWUoa2V5LmFsZ29yaXRobSk7XG4gICAgICAgIGlmIChrZXlVc2FnZSAmJiBrZXkudXNhZ2VzLmluZGV4T2Yoa2V5VXNhZ2UpID09PSAtMSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IENyeXB0b0Vycm9yKGBrZXkgZG9lcyBub3QgbWF0Y2ggdGhhdCBvZiBvcGVyYXRpb25gKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjaGVja1JlcXVpcmVkUHJvcGVydHkoZGF0YSwgcHJvcE5hbWUpIHtcbiAgICAgICAgaWYgKCEocHJvcE5hbWUgaW4gZGF0YSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBSZXF1aXJlZFByb3BlcnR5RXJyb3IocHJvcE5hbWUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGNoZWNrSGFzaEFsZ29yaXRobShhbGdvcml0aG0sIGhhc2hBbGdvcml0aG1zKSB7XG4gICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBoYXNoQWxnb3JpdGhtcykge1xuICAgICAgICAgICAgaWYgKGl0ZW0udG9Mb3dlckNhc2UoKSA9PT0gYWxnb3JpdGhtLm5hbWUudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBuZXcgT3BlcmF0aW9uRXJyb3IoYGhhc2g6IE11c3QgYmUgb25lIG9mICR7aGFzaEFsZ29yaXRobXMuam9pbihcIiwgXCIpfWApO1xuICAgIH1cbiAgICBjaGVja0ltcG9ydFBhcmFtcyhhbGdvcml0aG0pIHtcbiAgICB9XG4gICAgY2hlY2tLZXlGb3JtYXQoZm9ybWF0KSB7XG4gICAgICAgIHN3aXRjaCAoZm9ybWF0KSB7XG4gICAgICAgICAgICBjYXNlIFwicmF3XCI6XG4gICAgICAgICAgICBjYXNlIFwicGtjczhcIjpcbiAgICAgICAgICAgIGNhc2UgXCJzcGtpXCI6XG4gICAgICAgICAgICBjYXNlIFwiandrXCI6XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJmb3JtYXQ6IElzIGludmFsaWQgdmFsdWUuIE11c3QgYmUgJ2p3aycsICdyYXcnLCAnc3BraScsIG9yICdwa2NzOCdcIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY2hlY2tLZXlEYXRhKGZvcm1hdCwga2V5RGF0YSkge1xuICAgICAgICBpZiAoIWtleURhdGEpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJrZXlEYXRhOiBDYW5ub3QgYmUgZW1wdHkgb24gZW1wdHkgb24ga2V5IGltcG9ydGluZ1wiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZm9ybWF0ID09PSBcImp3a1wiKSB7XG4gICAgICAgICAgICBpZiAoIWlzSldLKGtleURhdGEpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImtleURhdGE6IElzIG5vdCBKc29uV2ViVG9rZW5cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoIUJ1ZmZlclNvdXJjZUNvbnZlcnRlci5pc0J1ZmZlclNvdXJjZShrZXlEYXRhKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImtleURhdGE6IElzIG5vdCBBcnJheUJ1ZmZlclZpZXcgb3IgQXJyYXlCdWZmZXJcIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcHJlcGFyZURhdGEoZGF0YSkge1xuICAgICAgICByZXR1cm4gQnVmZmVyU291cmNlQ29udmVydGVyLnRvQXJyYXlCdWZmZXIoZGF0YSk7XG4gICAgfVxufVxuXG5jbGFzcyBBZXNQcm92aWRlciBleHRlbmRzIFByb3ZpZGVyQ3J5cHRvIHtcbiAgICBjaGVja0dlbmVyYXRlS2V5UGFyYW1zKGFsZ29yaXRobSkge1xuICAgICAgICB0aGlzLmNoZWNrUmVxdWlyZWRQcm9wZXJ0eShhbGdvcml0aG0sIFwibGVuZ3RoXCIpO1xuICAgICAgICBpZiAodHlwZW9mIGFsZ29yaXRobS5sZW5ndGggIT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJsZW5ndGg6IElzIG5vdCBvZiB0eXBlIE51bWJlclwiKTtcbiAgICAgICAgfVxuICAgICAgICBzd2l0Y2ggKGFsZ29yaXRobS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNhc2UgMTI4OlxuICAgICAgICAgICAgY2FzZSAxOTI6XG4gICAgICAgICAgICBjYXNlIDI1NjpcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImxlbmd0aDogTXVzdCBiZSAxMjgsIDE5Miwgb3IgMjU2XCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGNoZWNrRGVyaXZlZEtleVBhcmFtcyhhbGdvcml0aG0pIHtcbiAgICAgICAgdGhpcy5jaGVja0dlbmVyYXRlS2V5UGFyYW1zKGFsZ29yaXRobSk7XG4gICAgfVxufVxuXG5jbGFzcyBBZXNDYmNQcm92aWRlciBleHRlbmRzIEFlc1Byb3ZpZGVyIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJBRVMtQ0JDXCI7XG4gICAgICAgIHRoaXMudXNhZ2VzID0gW1wiZW5jcnlwdFwiLCBcImRlY3J5cHRcIiwgXCJ3cmFwS2V5XCIsIFwidW53cmFwS2V5XCJdO1xuICAgIH1cbiAgICBjaGVja0FsZ29yaXRobVBhcmFtcyhhbGdvcml0aG0pIHtcbiAgICAgICAgdGhpcy5jaGVja1JlcXVpcmVkUHJvcGVydHkoYWxnb3JpdGhtLCBcIml2XCIpO1xuICAgICAgICBpZiAoIShhbGdvcml0aG0uaXYgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlciB8fCBBcnJheUJ1ZmZlci5pc1ZpZXcoYWxnb3JpdGhtLml2KSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJpdjogSXMgbm90IG9mIHR5cGUgJyhBcnJheUJ1ZmZlciBvciBBcnJheUJ1ZmZlclZpZXcpJ1wiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYWxnb3JpdGhtLml2LmJ5dGVMZW5ndGggIT09IDE2KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiaXY6IE11c3QgaGF2ZSBsZW5ndGggMTYgYnl0ZXNcIik7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmNsYXNzIEFlc0NtYWNQcm92aWRlciBleHRlbmRzIEFlc1Byb3ZpZGVyIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJBRVMtQ01BQ1wiO1xuICAgICAgICB0aGlzLnVzYWdlcyA9IFtcInNpZ25cIiwgXCJ2ZXJpZnlcIl07XG4gICAgfVxuICAgIGNoZWNrQWxnb3JpdGhtUGFyYW1zKGFsZ29yaXRobSkge1xuICAgICAgICB0aGlzLmNoZWNrUmVxdWlyZWRQcm9wZXJ0eShhbGdvcml0aG0sIFwibGVuZ3RoXCIpO1xuICAgICAgICBpZiAodHlwZW9mIGFsZ29yaXRobS5sZW5ndGggIT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJsZW5ndGg6IElzIG5vdCBhIE51bWJlclwiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYWxnb3JpdGhtLmxlbmd0aCA8IDEpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBPcGVyYXRpb25FcnJvcihcImxlbmd0aDogTXVzdCBiZSBtb3JlIHRoYW4gMFwiKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuY2xhc3MgQWVzQ3RyUHJvdmlkZXIgZXh0ZW5kcyBBZXNQcm92aWRlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQUVTLUNUUlwiO1xuICAgICAgICB0aGlzLnVzYWdlcyA9IFtcImVuY3J5cHRcIiwgXCJkZWNyeXB0XCIsIFwid3JhcEtleVwiLCBcInVud3JhcEtleVwiXTtcbiAgICB9XG4gICAgY2hlY2tBbGdvcml0aG1QYXJhbXMoYWxnb3JpdGhtKSB7XG4gICAgICAgIHRoaXMuY2hlY2tSZXF1aXJlZFByb3BlcnR5KGFsZ29yaXRobSwgXCJjb3VudGVyXCIpO1xuICAgICAgICBpZiAoIShhbGdvcml0aG0uY291bnRlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyIHx8IEFycmF5QnVmZmVyLmlzVmlldyhhbGdvcml0aG0uY291bnRlcikpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiY291bnRlcjogSXMgbm90IG9mIHR5cGUgJyhBcnJheUJ1ZmZlciBvciBBcnJheUJ1ZmZlclZpZXcpJ1wiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYWxnb3JpdGhtLmNvdW50ZXIuYnl0ZUxlbmd0aCAhPT0gMTYpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJpdjogTXVzdCBoYXZlIGxlbmd0aCAxNiBieXRlc1wiKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNoZWNrUmVxdWlyZWRQcm9wZXJ0eShhbGdvcml0aG0sIFwibGVuZ3RoXCIpO1xuICAgICAgICBpZiAodHlwZW9mIGFsZ29yaXRobS5sZW5ndGggIT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJsZW5ndGg6IElzIG5vdCBhIE51bWJlclwiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYWxnb3JpdGhtLmxlbmd0aCA8IDEpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBPcGVyYXRpb25FcnJvcihcImxlbmd0aDogTXVzdCBiZSBtb3JlIHRoYW4gMFwiKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuY2xhc3MgQWVzRWNiUHJvdmlkZXIgZXh0ZW5kcyBBZXNQcm92aWRlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQUVTLUVDQlwiO1xuICAgICAgICB0aGlzLnVzYWdlcyA9IFtcImVuY3J5cHRcIiwgXCJkZWNyeXB0XCIsIFwid3JhcEtleVwiLCBcInVud3JhcEtleVwiXTtcbiAgICB9XG59XG5cbmNsYXNzIEFlc0djbVByb3ZpZGVyIGV4dGVuZHMgQWVzUHJvdmlkZXIge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkFFUy1HQ01cIjtcbiAgICAgICAgdGhpcy51c2FnZXMgPSBbXCJlbmNyeXB0XCIsIFwiZGVjcnlwdFwiLCBcIndyYXBLZXlcIiwgXCJ1bndyYXBLZXlcIl07XG4gICAgfVxuICAgIGNoZWNrQWxnb3JpdGhtUGFyYW1zKGFsZ29yaXRobSkge1xuICAgICAgICB0aGlzLmNoZWNrUmVxdWlyZWRQcm9wZXJ0eShhbGdvcml0aG0sIFwiaXZcIik7XG4gICAgICAgIGlmICghKGFsZ29yaXRobS5pdiBpbnN0YW5jZW9mIEFycmF5QnVmZmVyIHx8IEFycmF5QnVmZmVyLmlzVmlldyhhbGdvcml0aG0uaXYpKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIml2OiBJcyBub3Qgb2YgdHlwZSAnKEFycmF5QnVmZmVyIG9yIEFycmF5QnVmZmVyVmlldyknXCIpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChhbGdvcml0aG0uaXYuYnl0ZUxlbmd0aCA8IDEpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBPcGVyYXRpb25FcnJvcihcIml2OiBNdXN0IGhhdmUgbGVuZ3RoIG1vcmUgdGhhbiAwIGFuZCBsZXNzIHRoYW4gMl42NCAtIDFcIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEoXCJ0YWdMZW5ndGhcIiBpbiBhbGdvcml0aG0pKSB7XG4gICAgICAgICAgICBhbGdvcml0aG0udGFnTGVuZ3RoID0gMTI4O1xuICAgICAgICB9XG4gICAgICAgIHN3aXRjaCAoYWxnb3JpdGhtLnRhZ0xlbmd0aCkge1xuICAgICAgICAgICAgY2FzZSAzMjpcbiAgICAgICAgICAgIGNhc2UgNjQ6XG4gICAgICAgICAgICBjYXNlIDk2OlxuICAgICAgICAgICAgY2FzZSAxMDQ6XG4gICAgICAgICAgICBjYXNlIDExMjpcbiAgICAgICAgICAgIGNhc2UgMTIwOlxuICAgICAgICAgICAgY2FzZSAxMjg6XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBPcGVyYXRpb25FcnJvcihcInRhZ0xlbmd0aDogTXVzdCBiZSBvbmUgb2YgMzIsIDY0LCA5NiwgMTA0LCAxMTIsIDEyMCBvciAxMjhcIik7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmNsYXNzIEFlc0t3UHJvdmlkZXIgZXh0ZW5kcyBBZXNQcm92aWRlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQUVTLUtXXCI7XG4gICAgICAgIHRoaXMudXNhZ2VzID0gW1wid3JhcEtleVwiLCBcInVud3JhcEtleVwiXTtcbiAgICB9XG59XG5cbmNsYXNzIERlc1Byb3ZpZGVyIGV4dGVuZHMgUHJvdmlkZXJDcnlwdG8ge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLnVzYWdlcyA9IFtcImVuY3J5cHRcIiwgXCJkZWNyeXB0XCIsIFwid3JhcEtleVwiLCBcInVud3JhcEtleVwiXTtcbiAgICB9XG4gICAgY2hlY2tBbGdvcml0aG1QYXJhbXMoYWxnb3JpdGhtKSB7XG4gICAgICAgIGlmICh0aGlzLml2U2l6ZSkge1xuICAgICAgICAgICAgdGhpcy5jaGVja1JlcXVpcmVkUHJvcGVydHkoYWxnb3JpdGhtLCBcIml2XCIpO1xuICAgICAgICAgICAgaWYgKCEoYWxnb3JpdGhtLml2IGluc3RhbmNlb2YgQXJyYXlCdWZmZXIgfHwgQXJyYXlCdWZmZXIuaXNWaWV3KGFsZ29yaXRobS5pdikpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIml2OiBJcyBub3Qgb2YgdHlwZSAnKEFycmF5QnVmZmVyIG9yIEFycmF5QnVmZmVyVmlldyknXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGFsZ29yaXRobS5pdi5ieXRlTGVuZ3RoICE9PSB0aGlzLml2U2l6ZSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYGl2OiBNdXN0IGhhdmUgbGVuZ3RoICR7dGhpcy5pdlNpemV9IGJ5dGVzYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgY2hlY2tHZW5lcmF0ZUtleVBhcmFtcyhhbGdvcml0aG0pIHtcbiAgICAgICAgdGhpcy5jaGVja1JlcXVpcmVkUHJvcGVydHkoYWxnb3JpdGhtLCBcImxlbmd0aFwiKTtcbiAgICAgICAgaWYgKHR5cGVvZiBhbGdvcml0aG0ubGVuZ3RoICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwibGVuZ3RoOiBJcyBub3Qgb2YgdHlwZSBOdW1iZXJcIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGFsZ29yaXRobS5sZW5ndGggIT09IHRoaXMua2V5U2l6ZUJpdHMpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBPcGVyYXRpb25FcnJvcihgYWxnb3JpdGhtLmxlbmd0aDogTXVzdCBiZSAke3RoaXMua2V5U2l6ZUJpdHN9YCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY2hlY2tEZXJpdmVkS2V5UGFyYW1zKGFsZ29yaXRobSkge1xuICAgICAgICB0aGlzLmNoZWNrR2VuZXJhdGVLZXlQYXJhbXMoYWxnb3JpdGhtKTtcbiAgICB9XG59XG5cbmNsYXNzIFJzYVByb3ZpZGVyIGV4dGVuZHMgUHJvdmlkZXJDcnlwdG8ge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLmhhc2hBbGdvcml0aG1zID0gW1wiU0hBLTFcIiwgXCJTSEEtMjU2XCIsIFwiU0hBLTM4NFwiLCBcIlNIQS01MTJcIl07XG4gICAgfVxuICAgIGNoZWNrR2VuZXJhdGVLZXlQYXJhbXMoYWxnb3JpdGhtKSB7XG4gICAgICAgIHRoaXMuY2hlY2tSZXF1aXJlZFByb3BlcnR5KGFsZ29yaXRobSwgXCJoYXNoXCIpO1xuICAgICAgICB0aGlzLmNoZWNrSGFzaEFsZ29yaXRobShhbGdvcml0aG0uaGFzaCwgdGhpcy5oYXNoQWxnb3JpdGhtcyk7XG4gICAgICAgIHRoaXMuY2hlY2tSZXF1aXJlZFByb3BlcnR5KGFsZ29yaXRobSwgXCJwdWJsaWNFeHBvbmVudFwiKTtcbiAgICAgICAgaWYgKCEoYWxnb3JpdGhtLnB1YmxpY0V4cG9uZW50ICYmIGFsZ29yaXRobS5wdWJsaWNFeHBvbmVudCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwicHVibGljRXhwb25lbnQ6IE1pc3Npbmcgb3Igbm90IGEgVWludDhBcnJheVwiKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwdWJsaWNFeHBvbmVudCA9IENvbnZlcnQuVG9CYXNlNjQoYWxnb3JpdGhtLnB1YmxpY0V4cG9uZW50KTtcbiAgICAgICAgaWYgKCEocHVibGljRXhwb25lbnQgPT09IFwiQXc9PVwiIHx8IHB1YmxpY0V4cG9uZW50ID09PSBcIkFRQUJcIikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJwdWJsaWNFeHBvbmVudDogTXVzdCBiZSBbM10gb3IgWzEsMCwxXVwiKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNoZWNrUmVxdWlyZWRQcm9wZXJ0eShhbGdvcml0aG0sIFwibW9kdWx1c0xlbmd0aFwiKTtcbiAgICAgICAgaWYgKGFsZ29yaXRobS5tb2R1bHVzTGVuZ3RoICUgOFxuICAgICAgICAgICAgfHwgYWxnb3JpdGhtLm1vZHVsdXNMZW5ndGggPCAyNTZcbiAgICAgICAgICAgIHx8IGFsZ29yaXRobS5tb2R1bHVzTGVuZ3RoID4gMTYzODQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJUaGUgbW9kdWx1cyBsZW5ndGggbXVzdCBiZSBhIG11bHRpcGxlIG9mIDggYml0cyBhbmQgPj0gMjU2IGFuZCA8PSAxNjM4NFwiKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjaGVja0ltcG9ydFBhcmFtcyhhbGdvcml0aG0pIHtcbiAgICAgICAgdGhpcy5jaGVja1JlcXVpcmVkUHJvcGVydHkoYWxnb3JpdGhtLCBcImhhc2hcIik7XG4gICAgICAgIHRoaXMuY2hlY2tIYXNoQWxnb3JpdGhtKGFsZ29yaXRobS5oYXNoLCB0aGlzLmhhc2hBbGdvcml0aG1zKTtcbiAgICB9XG59XG5cbmNsYXNzIFJzYVNzYVByb3ZpZGVyIGV4dGVuZHMgUnNhUHJvdmlkZXIge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlJTQVNTQS1QS0NTMS12MV81XCI7XG4gICAgICAgIHRoaXMudXNhZ2VzID0ge1xuICAgICAgICAgICAgcHJpdmF0ZUtleTogW1wic2lnblwiXSxcbiAgICAgICAgICAgIHB1YmxpY0tleTogW1widmVyaWZ5XCJdLFxuICAgICAgICB9O1xuICAgIH1cbn1cblxuY2xhc3MgUnNhUHNzUHJvdmlkZXIgZXh0ZW5kcyBSc2FQcm92aWRlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUlNBLVBTU1wiO1xuICAgICAgICB0aGlzLnVzYWdlcyA9IHtcbiAgICAgICAgICAgIHByaXZhdGVLZXk6IFtcInNpZ25cIl0sXG4gICAgICAgICAgICBwdWJsaWNLZXk6IFtcInZlcmlmeVwiXSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgY2hlY2tBbGdvcml0aG1QYXJhbXMoYWxnb3JpdGhtKSB7XG4gICAgICAgIHRoaXMuY2hlY2tSZXF1aXJlZFByb3BlcnR5KGFsZ29yaXRobSwgXCJzYWx0TGVuZ3RoXCIpO1xuICAgICAgICBpZiAodHlwZW9mIGFsZ29yaXRobS5zYWx0TGVuZ3RoICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwic2FsdExlbmd0aDogSXMgbm90IGEgTnVtYmVyXCIpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChhbGdvcml0aG0uc2FsdExlbmd0aCA8IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwic2FsdExlbmd0aDogTXVzdCBiZSBwb3NpdGl2ZSBudW1iZXJcIik7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmNsYXNzIFJzYU9hZXBQcm92aWRlciBleHRlbmRzIFJzYVByb3ZpZGVyIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJSU0EtT0FFUFwiO1xuICAgICAgICB0aGlzLnVzYWdlcyA9IHtcbiAgICAgICAgICAgIHByaXZhdGVLZXk6IFtcImRlY3J5cHRcIiwgXCJ1bndyYXBLZXlcIl0sXG4gICAgICAgICAgICBwdWJsaWNLZXk6IFtcImVuY3J5cHRcIiwgXCJ3cmFwS2V5XCJdLFxuICAgICAgICB9O1xuICAgIH1cbiAgICBjaGVja0FsZ29yaXRobVBhcmFtcyhhbGdvcml0aG0pIHtcbiAgICAgICAgaWYgKGFsZ29yaXRobS5sYWJlbFxuICAgICAgICAgICAgJiYgIShhbGdvcml0aG0ubGFiZWwgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlciB8fCBBcnJheUJ1ZmZlci5pc1ZpZXcoYWxnb3JpdGhtLmxhYmVsKSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJsYWJlbDogSXMgbm90IG9mIHR5cGUgJyhBcnJheUJ1ZmZlciBvciBBcnJheUJ1ZmZlclZpZXcpJ1wiKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuY2xhc3MgRWxsaXB0aWNQcm92aWRlciBleHRlbmRzIFByb3ZpZGVyQ3J5cHRvIHtcbiAgICBjaGVja0dlbmVyYXRlS2V5UGFyYW1zKGFsZ29yaXRobSkge1xuICAgICAgICB0aGlzLmNoZWNrUmVxdWlyZWRQcm9wZXJ0eShhbGdvcml0aG0sIFwibmFtZWRDdXJ2ZVwiKTtcbiAgICAgICAgdGhpcy5jaGVja05hbWVkQ3VydmUoYWxnb3JpdGhtLm5hbWVkQ3VydmUpO1xuICAgIH1cbiAgICBjaGVja05hbWVkQ3VydmUobmFtZWRDdXJ2ZSkge1xuICAgICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgdGhpcy5uYW1lZEN1cnZlcykge1xuICAgICAgICAgICAgaWYgKGl0ZW0udG9Mb3dlckNhc2UoKSA9PT0gbmFtZWRDdXJ2ZS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRocm93IG5ldyBPcGVyYXRpb25FcnJvcihgbmFtZWRDdXJ2ZTogTXVzdCBiZSBvbmUgb2YgJHt0aGlzLm5hbWVkQ3VydmVzLmpvaW4oXCIsIFwiKX1gKTtcbiAgICB9XG59XG5cbmNsYXNzIEVjZHNhUHJvdmlkZXIgZXh0ZW5kcyBFbGxpcHRpY1Byb3ZpZGVyIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJFQ0RTQVwiO1xuICAgICAgICB0aGlzLmhhc2hBbGdvcml0aG1zID0gW1wiU0hBLTFcIiwgXCJTSEEtMjU2XCIsIFwiU0hBLTM4NFwiLCBcIlNIQS01MTJcIl07XG4gICAgICAgIHRoaXMudXNhZ2VzID0ge1xuICAgICAgICAgICAgcHJpdmF0ZUtleTogW1wic2lnblwiXSxcbiAgICAgICAgICAgIHB1YmxpY0tleTogW1widmVyaWZ5XCJdLFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLm5hbWVkQ3VydmVzID0gW1wiUC0yNTZcIiwgXCJQLTM4NFwiLCBcIlAtNTIxXCIsIFwiSy0yNTZcIl07XG4gICAgfVxuICAgIGNoZWNrQWxnb3JpdGhtUGFyYW1zKGFsZ29yaXRobSkge1xuICAgICAgICB0aGlzLmNoZWNrUmVxdWlyZWRQcm9wZXJ0eShhbGdvcml0aG0sIFwiaGFzaFwiKTtcbiAgICAgICAgdGhpcy5jaGVja0hhc2hBbGdvcml0aG0oYWxnb3JpdGhtLmhhc2gsIHRoaXMuaGFzaEFsZ29yaXRobXMpO1xuICAgIH1cbn1cblxuY29uc3QgS0VZX1RZUEVTID0gW1wic2VjcmV0XCIsIFwicHJpdmF0ZVwiLCBcInB1YmxpY1wiXTtcbmNsYXNzIENyeXB0b0tleSB7XG4gICAgc3RhdGljIGNyZWF0ZShhbGdvcml0aG0sIHR5cGUsIGV4dHJhY3RhYmxlLCB1c2FnZXMpIHtcbiAgICAgICAgY29uc3Qga2V5ID0gbmV3IHRoaXMoKTtcbiAgICAgICAga2V5LmFsZ29yaXRobSA9IGFsZ29yaXRobTtcbiAgICAgICAga2V5LnR5cGUgPSB0eXBlO1xuICAgICAgICBrZXkuZXh0cmFjdGFibGUgPSBleHRyYWN0YWJsZTtcbiAgICAgICAga2V5LnVzYWdlcyA9IHVzYWdlcztcbiAgICAgICAgcmV0dXJuIGtleTtcbiAgICB9XG4gICAgc3RhdGljIGlzS2V5VHlwZShkYXRhKSB7XG4gICAgICAgIHJldHVybiBLRVlfVFlQRVMuaW5kZXhPZihkYXRhKSAhPT0gLTE7XG4gICAgfVxuICAgIGdldCBbU3ltYm9sLnRvU3RyaW5nVGFnXSgpIHtcbiAgICAgICAgcmV0dXJuIFwiQ3J5cHRvS2V5XCI7XG4gICAgfVxufVxuXG5jbGFzcyBFY2RoUHJvdmlkZXIgZXh0ZW5kcyBFbGxpcHRpY1Byb3ZpZGVyIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJFQ0RIXCI7XG4gICAgICAgIHRoaXMudXNhZ2VzID0ge1xuICAgICAgICAgICAgcHJpdmF0ZUtleTogW1wiZGVyaXZlQml0c1wiLCBcImRlcml2ZUtleVwiXSxcbiAgICAgICAgICAgIHB1YmxpY0tleTogW10sXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMubmFtZWRDdXJ2ZXMgPSBbXCJQLTI1NlwiLCBcIlAtMzg0XCIsIFwiUC01MjFcIiwgXCJLLTI1NlwiXTtcbiAgICB9XG4gICAgY2hlY2tBbGdvcml0aG1QYXJhbXMoYWxnb3JpdGhtKSB7XG4gICAgICAgIHRoaXMuY2hlY2tSZXF1aXJlZFByb3BlcnR5KGFsZ29yaXRobSwgXCJwdWJsaWNcIik7XG4gICAgICAgIGlmICghKGFsZ29yaXRobS5wdWJsaWMgaW5zdGFuY2VvZiBDcnlwdG9LZXkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwicHVibGljOiBJcyBub3QgYSBDcnlwdG9LZXlcIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGFsZ29yaXRobS5wdWJsaWMudHlwZSAhPT0gXCJwdWJsaWNcIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IE9wZXJhdGlvbkVycm9yKFwicHVibGljOiBJcyBub3QgYSBwdWJsaWMga2V5XCIpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChhbGdvcml0aG0ucHVibGljLmFsZ29yaXRobS5uYW1lICE9PSB0aGlzLm5hbWUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBPcGVyYXRpb25FcnJvcihgcHVibGljOiBJcyBub3QgJHt0aGlzLm5hbWV9IGtleWApO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5jbGFzcyBFY2RoRXNQcm92aWRlciBleHRlbmRzIEVjZGhQcm92aWRlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRUNESC1FU1wiO1xuICAgICAgICB0aGlzLm5hbWVkQ3VydmVzID0gW1wiWDI1NTE5XCIsIFwiWDQ0OFwiXTtcbiAgICB9XG59XG5cbmNsYXNzIEVkRHNhUHJvdmlkZXIgZXh0ZW5kcyBFbGxpcHRpY1Byb3ZpZGVyIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJFZERTQVwiO1xuICAgICAgICB0aGlzLnVzYWdlcyA9IHtcbiAgICAgICAgICAgIHByaXZhdGVLZXk6IFtcInNpZ25cIl0sXG4gICAgICAgICAgICBwdWJsaWNLZXk6IFtcInZlcmlmeVwiXSxcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5uYW1lZEN1cnZlcyA9IFtcIkVkMjU1MTlcIiwgXCJFZDQ0OFwiXTtcbiAgICB9XG59XG5cbmxldCBPYmplY3RJZGVudGlmaWVyID0gY2xhc3MgT2JqZWN0SWRlbnRpZmllciB7XG4gICAgY29uc3RydWN0b3IodmFsdWUpIHtcbiAgICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG59O1xuX19kZWNvcmF0ZShbXG4gICAgQXNuUHJvcCh7IHR5cGU6IEFzblByb3BUeXBlcy5PYmplY3RJZGVudGlmaWVyIH0pXG5dLCBPYmplY3RJZGVudGlmaWVyLnByb3RvdHlwZSwgXCJ2YWx1ZVwiLCB2b2lkIDApO1xuT2JqZWN0SWRlbnRpZmllciA9IF9fZGVjb3JhdGUoW1xuICAgIEFzblR5cGUoeyB0eXBlOiBBc25UeXBlVHlwZXMuQ2hvaWNlIH0pXG5dLCBPYmplY3RJZGVudGlmaWVyKTtcblxuY2xhc3MgQWxnb3JpdGhtSWRlbnRpZmllciB7XG4gICAgY29uc3RydWN0b3IocGFyYW1zKSB7XG4gICAgICAgIE9iamVjdC5hc3NpZ24odGhpcywgcGFyYW1zKTtcbiAgICB9XG59XG5fX2RlY29yYXRlKFtcbiAgICBBc25Qcm9wKHtcbiAgICAgICAgdHlwZTogQXNuUHJvcFR5cGVzLk9iamVjdElkZW50aWZpZXIsXG4gICAgfSlcbl0sIEFsZ29yaXRobUlkZW50aWZpZXIucHJvdG90eXBlLCBcImFsZ29yaXRobVwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgQXNuUHJvcCh7XG4gICAgICAgIHR5cGU6IEFzblByb3BUeXBlcy5BbnksXG4gICAgICAgIG9wdGlvbmFsOiB0cnVlLFxuICAgIH0pXG5dLCBBbGdvcml0aG1JZGVudGlmaWVyLnByb3RvdHlwZSwgXCJwYXJhbWV0ZXJzXCIsIHZvaWQgMCk7XG5cbmNsYXNzIFByaXZhdGVLZXlJbmZvIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy52ZXJzaW9uID0gMDtcbiAgICAgICAgdGhpcy5wcml2YXRlS2V5QWxnb3JpdGhtID0gbmV3IEFsZ29yaXRobUlkZW50aWZpZXIoKTtcbiAgICAgICAgdGhpcy5wcml2YXRlS2V5ID0gbmV3IEFycmF5QnVmZmVyKDApO1xuICAgIH1cbn1cbl9fZGVjb3JhdGUoW1xuICAgIEFzblByb3AoeyB0eXBlOiBBc25Qcm9wVHlwZXMuSW50ZWdlciB9KVxuXSwgUHJpdmF0ZUtleUluZm8ucHJvdG90eXBlLCBcInZlcnNpb25cIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIEFzblByb3AoeyB0eXBlOiBBbGdvcml0aG1JZGVudGlmaWVyIH0pXG5dLCBQcml2YXRlS2V5SW5mby5wcm90b3R5cGUsIFwicHJpdmF0ZUtleUFsZ29yaXRobVwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgQXNuUHJvcCh7IHR5cGU6IEFzblByb3BUeXBlcy5PY3RldFN0cmluZyB9KVxuXSwgUHJpdmF0ZUtleUluZm8ucHJvdG90eXBlLCBcInByaXZhdGVLZXlcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIEFzblByb3AoeyB0eXBlOiBBc25Qcm9wVHlwZXMuQW55LCBvcHRpb25hbDogdHJ1ZSB9KVxuXSwgUHJpdmF0ZUtleUluZm8ucHJvdG90eXBlLCBcImF0dHJpYnV0ZXNcIiwgdm9pZCAwKTtcblxuY2xhc3MgUHVibGljS2V5SW5mbyB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMucHVibGljS2V5QWxnb3JpdGhtID0gbmV3IEFsZ29yaXRobUlkZW50aWZpZXIoKTtcbiAgICAgICAgdGhpcy5wdWJsaWNLZXkgPSBuZXcgQXJyYXlCdWZmZXIoMCk7XG4gICAgfVxufVxuX19kZWNvcmF0ZShbXG4gICAgQXNuUHJvcCh7IHR5cGU6IEFsZ29yaXRobUlkZW50aWZpZXIgfSlcbl0sIFB1YmxpY0tleUluZm8ucHJvdG90eXBlLCBcInB1YmxpY0tleUFsZ29yaXRobVwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgQXNuUHJvcCh7IHR5cGU6IEFzblByb3BUeXBlcy5CaXRTdHJpbmcgfSlcbl0sIFB1YmxpY0tleUluZm8ucHJvdG90eXBlLCBcInB1YmxpY0tleVwiLCB2b2lkIDApO1xuXG5jb25zdCBKc29uQmFzZTY0VXJsQXJyYXlCdWZmZXJDb252ZXJ0ZXIgPSB7XG4gICAgZnJvbUpTT046ICh2YWx1ZSkgPT4gQ29udmVydC5Gcm9tQmFzZTY0VXJsKHZhbHVlKSxcbiAgICB0b0pTT046ICh2YWx1ZSkgPT4gQ29udmVydC5Ub0Jhc2U2NFVybChuZXcgVWludDhBcnJheSh2YWx1ZSkpLFxufTtcblxuY29uc3QgQXNuSW50ZWdlckFycmF5QnVmZmVyQ29udmVydGVyID0ge1xuICAgIGZyb21BU046ICh2YWx1ZSkgPT4ge1xuICAgICAgICBjb25zdCB2YWx1ZUhleCA9IHZhbHVlLnZhbHVlQmxvY2sudmFsdWVIZXg7XG4gICAgICAgIHJldHVybiAhKG5ldyBVaW50OEFycmF5KHZhbHVlSGV4KVswXSlcbiAgICAgICAgICAgID8gdmFsdWUudmFsdWVCbG9jay52YWx1ZUhleC5zbGljZSgxKVxuICAgICAgICAgICAgOiB2YWx1ZS52YWx1ZUJsb2NrLnZhbHVlSGV4O1xuICAgIH0sXG4gICAgdG9BU046ICh2YWx1ZSkgPT4ge1xuICAgICAgICBjb25zdCB2YWx1ZUhleCA9IG5ldyBVaW50OEFycmF5KHZhbHVlKVswXSA+IDEyN1xuICAgICAgICAgICAgPyBjb21iaW5lKG5ldyBVaW50OEFycmF5KFswXSkuYnVmZmVyLCB2YWx1ZSlcbiAgICAgICAgICAgIDogdmFsdWU7XG4gICAgICAgIHJldHVybiBuZXcgYXNuMS5JbnRlZ2VyKHsgdmFsdWVIZXggfSk7XG4gICAgfSxcbn07XG5cbnZhciBpbmRleCQzID0gLyojX19QVVJFX18qL09iamVjdC5mcmVlemUoe1xuICBfX3Byb3RvX186IG51bGwsXG4gIEFzbkludGVnZXJBcnJheUJ1ZmZlckNvbnZlcnRlcjogQXNuSW50ZWdlckFycmF5QnVmZmVyQ29udmVydGVyLFxuICBKc29uQmFzZTY0VXJsQXJyYXlCdWZmZXJDb252ZXJ0ZXI6IEpzb25CYXNlNjRVcmxBcnJheUJ1ZmZlckNvbnZlcnRlclxufSk7XG5cbmNsYXNzIFJzYVByaXZhdGVLZXkge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnZlcnNpb24gPSAwO1xuICAgICAgICB0aGlzLm1vZHVsdXMgPSBuZXcgQXJyYXlCdWZmZXIoMCk7XG4gICAgICAgIHRoaXMucHVibGljRXhwb25lbnQgPSBuZXcgQXJyYXlCdWZmZXIoMCk7XG4gICAgICAgIHRoaXMucHJpdmF0ZUV4cG9uZW50ID0gbmV3IEFycmF5QnVmZmVyKDApO1xuICAgICAgICB0aGlzLnByaW1lMSA9IG5ldyBBcnJheUJ1ZmZlcigwKTtcbiAgICAgICAgdGhpcy5wcmltZTIgPSBuZXcgQXJyYXlCdWZmZXIoMCk7XG4gICAgICAgIHRoaXMuZXhwb25lbnQxID0gbmV3IEFycmF5QnVmZmVyKDApO1xuICAgICAgICB0aGlzLmV4cG9uZW50MiA9IG5ldyBBcnJheUJ1ZmZlcigwKTtcbiAgICAgICAgdGhpcy5jb2VmZmljaWVudCA9IG5ldyBBcnJheUJ1ZmZlcigwKTtcbiAgICB9XG59XG5fX2RlY29yYXRlKFtcbiAgICBBc25Qcm9wKHsgdHlwZTogQXNuUHJvcFR5cGVzLkludGVnZXIsIGNvbnZlcnRlcjogQXNuSW50ZWdlckNvbnZlcnRlciB9KVxuXSwgUnNhUHJpdmF0ZUtleS5wcm90b3R5cGUsIFwidmVyc2lvblwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgQXNuUHJvcCh7IHR5cGU6IEFzblByb3BUeXBlcy5JbnRlZ2VyLCBjb252ZXJ0ZXI6IEFzbkludGVnZXJBcnJheUJ1ZmZlckNvbnZlcnRlciB9KSxcbiAgICBKc29uUHJvcCh7IG5hbWU6IFwiblwiLCBjb252ZXJ0ZXI6IEpzb25CYXNlNjRVcmxBcnJheUJ1ZmZlckNvbnZlcnRlciB9KVxuXSwgUnNhUHJpdmF0ZUtleS5wcm90b3R5cGUsIFwibW9kdWx1c1wiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgQXNuUHJvcCh7IHR5cGU6IEFzblByb3BUeXBlcy5JbnRlZ2VyLCBjb252ZXJ0ZXI6IEFzbkludGVnZXJBcnJheUJ1ZmZlckNvbnZlcnRlciB9KSxcbiAgICBKc29uUHJvcCh7IG5hbWU6IFwiZVwiLCBjb252ZXJ0ZXI6IEpzb25CYXNlNjRVcmxBcnJheUJ1ZmZlckNvbnZlcnRlciB9KVxuXSwgUnNhUHJpdmF0ZUtleS5wcm90b3R5cGUsIFwicHVibGljRXhwb25lbnRcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIEFzblByb3AoeyB0eXBlOiBBc25Qcm9wVHlwZXMuSW50ZWdlciwgY29udmVydGVyOiBBc25JbnRlZ2VyQXJyYXlCdWZmZXJDb252ZXJ0ZXIgfSksXG4gICAgSnNvblByb3AoeyBuYW1lOiBcImRcIiwgY29udmVydGVyOiBKc29uQmFzZTY0VXJsQXJyYXlCdWZmZXJDb252ZXJ0ZXIgfSlcbl0sIFJzYVByaXZhdGVLZXkucHJvdG90eXBlLCBcInByaXZhdGVFeHBvbmVudFwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgQXNuUHJvcCh7IHR5cGU6IEFzblByb3BUeXBlcy5JbnRlZ2VyLCBjb252ZXJ0ZXI6IEFzbkludGVnZXJBcnJheUJ1ZmZlckNvbnZlcnRlciB9KSxcbiAgICBKc29uUHJvcCh7IG5hbWU6IFwicFwiLCBjb252ZXJ0ZXI6IEpzb25CYXNlNjRVcmxBcnJheUJ1ZmZlckNvbnZlcnRlciB9KVxuXSwgUnNhUHJpdmF0ZUtleS5wcm90b3R5cGUsIFwicHJpbWUxXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBBc25Qcm9wKHsgdHlwZTogQXNuUHJvcFR5cGVzLkludGVnZXIsIGNvbnZlcnRlcjogQXNuSW50ZWdlckFycmF5QnVmZmVyQ29udmVydGVyIH0pLFxuICAgIEpzb25Qcm9wKHsgbmFtZTogXCJxXCIsIGNvbnZlcnRlcjogSnNvbkJhc2U2NFVybEFycmF5QnVmZmVyQ29udmVydGVyIH0pXG5dLCBSc2FQcml2YXRlS2V5LnByb3RvdHlwZSwgXCJwcmltZTJcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIEFzblByb3AoeyB0eXBlOiBBc25Qcm9wVHlwZXMuSW50ZWdlciwgY29udmVydGVyOiBBc25JbnRlZ2VyQXJyYXlCdWZmZXJDb252ZXJ0ZXIgfSksXG4gICAgSnNvblByb3AoeyBuYW1lOiBcImRwXCIsIGNvbnZlcnRlcjogSnNvbkJhc2U2NFVybEFycmF5QnVmZmVyQ29udmVydGVyIH0pXG5dLCBSc2FQcml2YXRlS2V5LnByb3RvdHlwZSwgXCJleHBvbmVudDFcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIEFzblByb3AoeyB0eXBlOiBBc25Qcm9wVHlwZXMuSW50ZWdlciwgY29udmVydGVyOiBBc25JbnRlZ2VyQXJyYXlCdWZmZXJDb252ZXJ0ZXIgfSksXG4gICAgSnNvblByb3AoeyBuYW1lOiBcImRxXCIsIGNvbnZlcnRlcjogSnNvbkJhc2U2NFVybEFycmF5QnVmZmVyQ29udmVydGVyIH0pXG5dLCBSc2FQcml2YXRlS2V5LnByb3RvdHlwZSwgXCJleHBvbmVudDJcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIEFzblByb3AoeyB0eXBlOiBBc25Qcm9wVHlwZXMuSW50ZWdlciwgY29udmVydGVyOiBBc25JbnRlZ2VyQXJyYXlCdWZmZXJDb252ZXJ0ZXIgfSksXG4gICAgSnNvblByb3AoeyBuYW1lOiBcInFpXCIsIGNvbnZlcnRlcjogSnNvbkJhc2U2NFVybEFycmF5QnVmZmVyQ29udmVydGVyIH0pXG5dLCBSc2FQcml2YXRlS2V5LnByb3RvdHlwZSwgXCJjb2VmZmljaWVudFwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgQXNuUHJvcCh7IHR5cGU6IEFzblByb3BUeXBlcy5BbnksIG9wdGlvbmFsOiB0cnVlIH0pXG5dLCBSc2FQcml2YXRlS2V5LnByb3RvdHlwZSwgXCJvdGhlclByaW1lSW5mb3NcIiwgdm9pZCAwKTtcblxuY2xhc3MgUnNhUHVibGljS2V5IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5tb2R1bHVzID0gbmV3IEFycmF5QnVmZmVyKDApO1xuICAgICAgICB0aGlzLnB1YmxpY0V4cG9uZW50ID0gbmV3IEFycmF5QnVmZmVyKDApO1xuICAgIH1cbn1cbl9fZGVjb3JhdGUoW1xuICAgIEFzblByb3AoeyB0eXBlOiBBc25Qcm9wVHlwZXMuSW50ZWdlciwgY29udmVydGVyOiBBc25JbnRlZ2VyQXJyYXlCdWZmZXJDb252ZXJ0ZXIgfSksXG4gICAgSnNvblByb3AoeyBuYW1lOiBcIm5cIiwgY29udmVydGVyOiBKc29uQmFzZTY0VXJsQXJyYXlCdWZmZXJDb252ZXJ0ZXIgfSlcbl0sIFJzYVB1YmxpY0tleS5wcm90b3R5cGUsIFwibW9kdWx1c1wiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgQXNuUHJvcCh7IHR5cGU6IEFzblByb3BUeXBlcy5JbnRlZ2VyLCBjb252ZXJ0ZXI6IEFzbkludGVnZXJBcnJheUJ1ZmZlckNvbnZlcnRlciB9KSxcbiAgICBKc29uUHJvcCh7IG5hbWU6IFwiZVwiLCBjb252ZXJ0ZXI6IEpzb25CYXNlNjRVcmxBcnJheUJ1ZmZlckNvbnZlcnRlciB9KVxuXSwgUnNhUHVibGljS2V5LnByb3RvdHlwZSwgXCJwdWJsaWNFeHBvbmVudFwiLCB2b2lkIDApO1xuXG5sZXQgRWNQdWJsaWNLZXkgPSBjbGFzcyBFY1B1YmxpY0tleSB7XG4gICAgY29uc3RydWN0b3IodmFsdWUpIHtcbiAgICAgICAgdGhpcy52YWx1ZSA9IG5ldyBBcnJheUJ1ZmZlcigwKTtcbiAgICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgdG9KU09OKCkge1xuICAgICAgICBsZXQgYnl0ZXMgPSBuZXcgVWludDhBcnJheSh0aGlzLnZhbHVlKTtcbiAgICAgICAgaWYgKGJ5dGVzWzBdICE9PSAweDA0KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQ3J5cHRvRXJyb3IoXCJXcm9uZyBFQ1BvaW50LiBDdXJyZW50IHZlcnNpb24gc3VwcG9ydHMgb25seSBVbmNvbXByZXNzZWQgKDB4MDQpIHBvaW50XCIpO1xuICAgICAgICB9XG4gICAgICAgIGJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkodGhpcy52YWx1ZS5zbGljZSgxKSk7XG4gICAgICAgIGNvbnN0IHNpemUgPSBieXRlcy5sZW5ndGggLyAyO1xuICAgICAgICBjb25zdCBvZmZzZXQgPSAwO1xuICAgICAgICBjb25zdCBqc29uID0ge1xuICAgICAgICAgICAgeDogQ29udmVydC5Ub0Jhc2U2NFVybChieXRlcy5idWZmZXIuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyBzaXplKSksXG4gICAgICAgICAgICB5OiBDb252ZXJ0LlRvQmFzZTY0VXJsKGJ5dGVzLmJ1ZmZlci5zbGljZShvZmZzZXQgKyBzaXplLCBvZmZzZXQgKyBzaXplICsgc2l6ZSkpLFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ganNvbjtcbiAgICB9XG4gICAgZnJvbUpTT04oanNvbikge1xuICAgICAgICBpZiAoIShcInhcIiBpbiBqc29uKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwieDogTWlzc2luZyByZXF1aXJlZCBwcm9wZXJ0eVwiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIShcInlcIiBpbiBqc29uKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwieTogTWlzc2luZyByZXF1aXJlZCBwcm9wZXJ0eVwiKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB4ID0gQ29udmVydC5Gcm9tQmFzZTY0VXJsKGpzb24ueCk7XG4gICAgICAgIGNvbnN0IHkgPSBDb252ZXJ0LkZyb21CYXNlNjRVcmwoanNvbi55KTtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBjb21iaW5lKG5ldyBVaW50OEFycmF5KFsweDA0XSkuYnVmZmVyLCB4LCB5KTtcbiAgICAgICAgdGhpcy52YWx1ZSA9IG5ldyBVaW50OEFycmF5KHZhbHVlKS5idWZmZXI7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn07XG5fX2RlY29yYXRlKFtcbiAgICBBc25Qcm9wKHsgdHlwZTogQXNuUHJvcFR5cGVzLk9jdGV0U3RyaW5nIH0pXG5dLCBFY1B1YmxpY0tleS5wcm90b3R5cGUsIFwidmFsdWVcIiwgdm9pZCAwKTtcbkVjUHVibGljS2V5ID0gX19kZWNvcmF0ZShbXG4gICAgQXNuVHlwZSh7IHR5cGU6IEFzblR5cGVUeXBlcy5DaG9pY2UgfSlcbl0sIEVjUHVibGljS2V5KTtcblxuY2xhc3MgRWNQcml2YXRlS2V5IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy52ZXJzaW9uID0gMTtcbiAgICAgICAgdGhpcy5wcml2YXRlS2V5ID0gbmV3IEFycmF5QnVmZmVyKDApO1xuICAgIH1cbiAgICBmcm9tSlNPTihqc29uKSB7XG4gICAgICAgIGlmICghKFwiZFwiIGluIGpzb24pKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJkOiBNaXNzaW5nIHJlcXVpcmVkIHByb3BlcnR5XCIpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucHJpdmF0ZUtleSA9IENvbnZlcnQuRnJvbUJhc2U2NFVybChqc29uLmQpO1xuICAgICAgICBpZiAoXCJ4XCIgaW4ganNvbikge1xuICAgICAgICAgICAgY29uc3QgcHVibGljS2V5ID0gbmV3IEVjUHVibGljS2V5KCk7XG4gICAgICAgICAgICBwdWJsaWNLZXkuZnJvbUpTT04oanNvbik7XG4gICAgICAgICAgICBjb25zdCBhc24gPSBBc25TZXJpYWxpemVyLnRvQVNOKHB1YmxpY0tleSk7XG4gICAgICAgICAgICBpZiAoXCJ2YWx1ZUhleFwiIGluIGFzbi52YWx1ZUJsb2NrKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wdWJsaWNLZXkgPSBhc24udmFsdWVCbG9jay52YWx1ZUhleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgdG9KU09OKCkge1xuICAgICAgICBjb25zdCBqd2sgPSB7fTtcbiAgICAgICAgandrLmQgPSBDb252ZXJ0LlRvQmFzZTY0VXJsKHRoaXMucHJpdmF0ZUtleSk7XG4gICAgICAgIGlmICh0aGlzLnB1YmxpY0tleSkge1xuICAgICAgICAgICAgT2JqZWN0LmFzc2lnbihqd2ssIG5ldyBFY1B1YmxpY0tleSh0aGlzLnB1YmxpY0tleSkudG9KU09OKCkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBqd2s7XG4gICAgfVxufVxuX19kZWNvcmF0ZShbXG4gICAgQXNuUHJvcCh7IHR5cGU6IEFzblByb3BUeXBlcy5JbnRlZ2VyLCBjb252ZXJ0ZXI6IEFzbkludGVnZXJDb252ZXJ0ZXIgfSlcbl0sIEVjUHJpdmF0ZUtleS5wcm90b3R5cGUsIFwidmVyc2lvblwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgQXNuUHJvcCh7IHR5cGU6IEFzblByb3BUeXBlcy5PY3RldFN0cmluZyB9KVxuXSwgRWNQcml2YXRlS2V5LnByb3RvdHlwZSwgXCJwcml2YXRlS2V5XCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBBc25Qcm9wKHsgY29udGV4dDogMCwgdHlwZTogQXNuUHJvcFR5cGVzLkFueSwgb3B0aW9uYWw6IHRydWUgfSlcbl0sIEVjUHJpdmF0ZUtleS5wcm90b3R5cGUsIFwicGFyYW1ldGVyc1wiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgQXNuUHJvcCh7IGNvbnRleHQ6IDEsIHR5cGU6IEFzblByb3BUeXBlcy5CaXRTdHJpbmcsIG9wdGlvbmFsOiB0cnVlIH0pXG5dLCBFY1ByaXZhdGVLZXkucHJvdG90eXBlLCBcInB1YmxpY0tleVwiLCB2b2lkIDApO1xuXG5jb25zdCBBc25JbnRlZ2VyV2l0aG91dFBhZGRpbmdDb252ZXJ0ZXIgPSB7XG4gICAgZnJvbUFTTjogKHZhbHVlKSA9PiB7XG4gICAgICAgIGNvbnN0IGJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkodmFsdWUudmFsdWVCbG9jay52YWx1ZUhleCk7XG4gICAgICAgIHJldHVybiAoYnl0ZXNbMF0gPT09IDApXG4gICAgICAgICAgICA/IGJ5dGVzLmJ1ZmZlci5zbGljZSgxKVxuICAgICAgICAgICAgOiBieXRlcy5idWZmZXI7XG4gICAgfSxcbiAgICB0b0FTTjogKHZhbHVlKSA9PiB7XG4gICAgICAgIGNvbnN0IGJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkodmFsdWUpO1xuICAgICAgICBpZiAoYnl0ZXNbMF0gPiAxMjcpIHtcbiAgICAgICAgICAgIGNvbnN0IG5ld1ZhbHVlID0gbmV3IFVpbnQ4QXJyYXkoYnl0ZXMubGVuZ3RoICsgMSk7XG4gICAgICAgICAgICBuZXdWYWx1ZS5zZXQoYnl0ZXMsIDEpO1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBhc24xLkludGVnZXIoeyB2YWx1ZUhleDogbmV3VmFsdWUuYnVmZmVyIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgYXNuMS5JbnRlZ2VyKHsgdmFsdWVIZXg6IHZhbHVlIH0pO1xuICAgIH0sXG59O1xuXG52YXIgaW5kZXgkMiA9IC8qI19fUFVSRV9fKi9PYmplY3QuZnJlZXplKHtcbiAgX19wcm90b19fOiBudWxsLFxuICBBc25JbnRlZ2VyV2l0aG91dFBhZGRpbmdDb252ZXJ0ZXI6IEFzbkludGVnZXJXaXRob3V0UGFkZGluZ0NvbnZlcnRlclxufSk7XG5cbmNsYXNzIEVjVXRpbHMge1xuICAgIHN0YXRpYyBkZWNvZGVQb2ludChkYXRhLCBwb2ludFNpemUpIHtcbiAgICAgICAgY29uc3QgdmlldyA9IEJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b1VpbnQ4QXJyYXkoZGF0YSk7XG4gICAgICAgIGlmICgodmlldy5sZW5ndGggPT09IDApIHx8ICh2aWV3WzBdICE9PSA0KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiT25seSB1bmNvbXByZXNzZWQgcG9pbnQgZm9ybWF0IHN1cHBvcnRlZFwiKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBuID0gKHZpZXcubGVuZ3RoIC0gMSkgLyAyO1xuICAgICAgICBpZiAobiAhPT0gKE1hdGguY2VpbChwb2ludFNpemUgLyA4KSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlBvaW50IGRvZXMgbm90IG1hdGNoIGZpZWxkIHNpemVcIik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgeGIgPSB2aWV3LnNsaWNlKDEsIG4gKyAxKTtcbiAgICAgICAgY29uc3QgeWIgPSB2aWV3LnNsaWNlKG4gKyAxLCBuICsgMSArIG4pO1xuICAgICAgICByZXR1cm4geyB4OiB4YiwgeTogeWIgfTtcbiAgICB9XG4gICAgc3RhdGljIGVuY29kZVBvaW50KHBvaW50LCBwb2ludFNpemUpIHtcbiAgICAgICAgY29uc3Qgc2l6ZSA9IE1hdGguY2VpbChwb2ludFNpemUgLyA4KTtcbiAgICAgICAgaWYgKHBvaW50LnguYnl0ZUxlbmd0aCAhPT0gc2l6ZSB8fCBwb2ludC55LmJ5dGVMZW5ndGggIT09IHNpemUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlgsWSBjb29yZGluYXRlcyBkb24ndCBtYXRjaCBwb2ludCBzaXplIGNyaXRlcmlhXCIpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHggPSBCdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9VaW50OEFycmF5KHBvaW50LngpO1xuICAgICAgICBjb25zdCB5ID0gQnVmZmVyU291cmNlQ29udmVydGVyLnRvVWludDhBcnJheShwb2ludC55KTtcbiAgICAgICAgY29uc3QgcmVzID0gbmV3IFVpbnQ4QXJyYXkoc2l6ZSAqIDIgKyAxKTtcbiAgICAgICAgcmVzWzBdID0gNDtcbiAgICAgICAgcmVzLnNldCh4LCAxKTtcbiAgICAgICAgcmVzLnNldCh5LCBzaXplICsgMSk7XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxuICAgIHN0YXRpYyBnZXRTaXplKHBvaW50U2l6ZSkge1xuICAgICAgICByZXR1cm4gTWF0aC5jZWlsKHBvaW50U2l6ZSAvIDgpO1xuICAgIH1cbiAgICBzdGF0aWMgZW5jb2RlU2lnbmF0dXJlKHNpZ25hdHVyZSwgcG9pbnRTaXplKSB7XG4gICAgICAgIGNvbnN0IHNpemUgPSB0aGlzLmdldFNpemUocG9pbnRTaXplKTtcbiAgICAgICAgY29uc3QgciA9IEJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b1VpbnQ4QXJyYXkoc2lnbmF0dXJlLnIpO1xuICAgICAgICBjb25zdCBzID0gQnVmZmVyU291cmNlQ29udmVydGVyLnRvVWludDhBcnJheShzaWduYXR1cmUucyk7XG4gICAgICAgIGNvbnN0IHJlcyA9IG5ldyBVaW50OEFycmF5KHNpemUgKiAyKTtcbiAgICAgICAgcmVzLnNldCh0aGlzLnBhZFN0YXJ0KHIsIHNpemUpKTtcbiAgICAgICAgcmVzLnNldCh0aGlzLnBhZFN0YXJ0KHMsIHNpemUpLCBzaXplKTtcbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG4gICAgc3RhdGljIGRlY29kZVNpZ25hdHVyZShkYXRhLCBwb2ludFNpemUpIHtcbiAgICAgICAgY29uc3Qgc2l6ZSA9IHRoaXMuZ2V0U2l6ZShwb2ludFNpemUpO1xuICAgICAgICBjb25zdCB2aWV3ID0gQnVmZmVyU291cmNlQ29udmVydGVyLnRvVWludDhBcnJheShkYXRhKTtcbiAgICAgICAgaWYgKHZpZXcubGVuZ3RoICE9PSAoc2l6ZSAqIDIpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbmNvcnJlY3Qgc2l6ZSBvZiB0aGUgc2lnbmF0dXJlXCIpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHIgPSB2aWV3LnNsaWNlKDAsIHNpemUpO1xuICAgICAgICBjb25zdCBzID0gdmlldy5zbGljZShzaXplKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHI6IHRoaXMudHJpbVN0YXJ0KHIpLFxuICAgICAgICAgICAgczogdGhpcy50cmltU3RhcnQocyksXG4gICAgICAgIH07XG4gICAgfVxuICAgIHN0YXRpYyB0cmltU3RhcnQoZGF0YSkge1xuICAgICAgICBsZXQgaSA9IDA7XG4gICAgICAgIHdoaWxlICgoaSA8IGRhdGEubGVuZ3RoIC0gMSkgJiYgKGRhdGFbaV0gPT09IDApKSB7XG4gICAgICAgICAgICBpKys7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGkgPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBkYXRhO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkYXRhLnNsaWNlKGksIGRhdGEubGVuZ3RoKTtcbiAgICB9XG4gICAgc3RhdGljIHBhZFN0YXJ0KGRhdGEsIHNpemUpIHtcbiAgICAgICAgaWYgKHNpemUgPT09IGRhdGEubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gZGF0YTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCByZXMgPSBuZXcgVWludDhBcnJheShzaXplKTtcbiAgICAgICAgcmVzLnNldChkYXRhLCBzaXplIC0gZGF0YS5sZW5ndGgpO1xuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cbn1cblxuY2xhc3MgRWNEc2FTaWduYXR1cmUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnIgPSBuZXcgQXJyYXlCdWZmZXIoMCk7XG4gICAgICAgIHRoaXMucyA9IG5ldyBBcnJheUJ1ZmZlcigwKTtcbiAgICB9XG4gICAgc3RhdGljIGZyb21XZWJDcnlwdG9TaWduYXR1cmUodmFsdWUpIHtcbiAgICAgICAgY29uc3QgcG9pbnRTaXplID0gdmFsdWUuYnl0ZUxlbmd0aCAvIDI7XG4gICAgICAgIGNvbnN0IHBvaW50ID0gRWNVdGlscy5kZWNvZGVTaWduYXR1cmUodmFsdWUsIHBvaW50U2l6ZSAqIDgpO1xuICAgICAgICBjb25zdCBlY1NpZ25hdHVyZSA9IG5ldyBFY0RzYVNpZ25hdHVyZSgpO1xuICAgICAgICBlY1NpZ25hdHVyZS5yID0gQnVmZmVyU291cmNlQ29udmVydGVyLnRvQXJyYXlCdWZmZXIocG9pbnQucik7XG4gICAgICAgIGVjU2lnbmF0dXJlLnMgPSBCdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9BcnJheUJ1ZmZlcihwb2ludC5zKTtcbiAgICAgICAgcmV0dXJuIGVjU2lnbmF0dXJlO1xuICAgIH1cbiAgICB0b1dlYkNyeXB0b1NpZ25hdHVyZShwb2ludFNpemUpIHtcbiAgICAgICAgcG9pbnRTaXplICE9PSBudWxsICYmIHBvaW50U2l6ZSAhPT0gdm9pZCAwID8gcG9pbnRTaXplIDogKHBvaW50U2l6ZSA9IE1hdGgubWF4KHRoaXMuci5ieXRlTGVuZ3RoLCB0aGlzLnMuYnl0ZUxlbmd0aCkgKiA4KTtcbiAgICAgICAgY29uc3Qgc2lnbmF0dXJlID0gRWNVdGlscy5lbmNvZGVTaWduYXR1cmUodGhpcywgcG9pbnRTaXplKTtcbiAgICAgICAgcmV0dXJuIHNpZ25hdHVyZS5idWZmZXI7XG4gICAgfVxufVxuX19kZWNvcmF0ZShbXG4gICAgQXNuUHJvcCh7IHR5cGU6IEFzblByb3BUeXBlcy5JbnRlZ2VyLCBjb252ZXJ0ZXI6IEFzbkludGVnZXJXaXRob3V0UGFkZGluZ0NvbnZlcnRlciB9KVxuXSwgRWNEc2FTaWduYXR1cmUucHJvdG90eXBlLCBcInJcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIEFzblByb3AoeyB0eXBlOiBBc25Qcm9wVHlwZXMuSW50ZWdlciwgY29udmVydGVyOiBBc25JbnRlZ2VyV2l0aG91dFBhZGRpbmdDb252ZXJ0ZXIgfSlcbl0sIEVjRHNhU2lnbmF0dXJlLnByb3RvdHlwZSwgXCJzXCIsIHZvaWQgMCk7XG5cbmNsYXNzIE9uZUFzeW1tZXRyaWNLZXkgZXh0ZW5kcyBQcml2YXRlS2V5SW5mbyB7XG59XG5fX2RlY29yYXRlKFtcbiAgICBBc25Qcm9wKHsgY29udGV4dDogMSwgaW1wbGljaXQ6IHRydWUsIHR5cGU6IEFzblByb3BUeXBlcy5CaXRTdHJpbmcsIG9wdGlvbmFsOiB0cnVlIH0pXG5dLCBPbmVBc3ltbWV0cmljS2V5LnByb3RvdHlwZSwgXCJwdWJsaWNLZXlcIiwgdm9pZCAwKTtcblxubGV0IEVkUHJpdmF0ZUtleSA9IGNsYXNzIEVkUHJpdmF0ZUtleSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMudmFsdWUgPSBuZXcgQXJyYXlCdWZmZXIoMCk7XG4gICAgfVxuICAgIGZyb21KU09OKGpzb24pIHtcbiAgICAgICAgaWYgKCFqc29uLmQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImQ6IE1pc3NpbmcgcmVxdWlyZWQgcHJvcGVydHlcIik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy52YWx1ZSA9IENvbnZlcnQuRnJvbUJhc2U2NFVybChqc29uLmQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgdG9KU09OKCkge1xuICAgICAgICBjb25zdCBqd2sgPSB7XG4gICAgICAgICAgICBkOiBDb252ZXJ0LlRvQmFzZTY0VXJsKHRoaXMudmFsdWUpLFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gandrO1xuICAgIH1cbn07XG5fX2RlY29yYXRlKFtcbiAgICBBc25Qcm9wKHsgdHlwZTogQXNuUHJvcFR5cGVzLk9jdGV0U3RyaW5nIH0pXG5dLCBFZFByaXZhdGVLZXkucHJvdG90eXBlLCBcInZhbHVlXCIsIHZvaWQgMCk7XG5FZFByaXZhdGVLZXkgPSBfX2RlY29yYXRlKFtcbiAgICBBc25UeXBlKHsgdHlwZTogQXNuVHlwZVR5cGVzLkNob2ljZSB9KVxuXSwgRWRQcml2YXRlS2V5KTtcblxubGV0IEVkUHVibGljS2V5ID0gY2xhc3MgRWRQdWJsaWNLZXkge1xuICAgIGNvbnN0cnVjdG9yKHZhbHVlKSB7XG4gICAgICAgIHRoaXMudmFsdWUgPSBuZXcgQXJyYXlCdWZmZXIoMCk7XG4gICAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHRvSlNPTigpIHtcbiAgICAgICAgY29uc3QganNvbiA9IHtcbiAgICAgICAgICAgIHg6IENvbnZlcnQuVG9CYXNlNjRVcmwodGhpcy52YWx1ZSksXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBqc29uO1xuICAgIH1cbiAgICBmcm9tSlNPTihqc29uKSB7XG4gICAgICAgIGlmICghKFwieFwiIGluIGpzb24pKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ4OiBNaXNzaW5nIHJlcXVpcmVkIHByb3BlcnR5XCIpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudmFsdWUgPSBDb252ZXJ0LkZyb21CYXNlNjRVcmwoanNvbi54KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufTtcbl9fZGVjb3JhdGUoW1xuICAgIEFzblByb3AoeyB0eXBlOiBBc25Qcm9wVHlwZXMuQml0U3RyaW5nIH0pXG5dLCBFZFB1YmxpY0tleS5wcm90b3R5cGUsIFwidmFsdWVcIiwgdm9pZCAwKTtcbkVkUHVibGljS2V5ID0gX19kZWNvcmF0ZShbXG4gICAgQXNuVHlwZSh7IHR5cGU6IEFzblR5cGVUeXBlcy5DaG9pY2UgfSlcbl0sIEVkUHVibGljS2V5KTtcblxubGV0IEN1cnZlUHJpdmF0ZUtleSA9IGNsYXNzIEN1cnZlUHJpdmF0ZUtleSB7XG59O1xuX19kZWNvcmF0ZShbXG4gICAgQXNuUHJvcCh7IHR5cGU6IEFzblByb3BUeXBlcy5PY3RldFN0cmluZyB9KSxcbiAgICBKc29uUHJvcCh7IHR5cGU6IEpzb25Qcm9wVHlwZXMuU3RyaW5nLCBjb252ZXJ0ZXI6IEpzb25CYXNlNjRVcmxBcnJheUJ1ZmZlckNvbnZlcnRlciB9KVxuXSwgQ3VydmVQcml2YXRlS2V5LnByb3RvdHlwZSwgXCJkXCIsIHZvaWQgMCk7XG5DdXJ2ZVByaXZhdGVLZXkgPSBfX2RlY29yYXRlKFtcbiAgICBBc25UeXBlKHsgdHlwZTogQXNuVHlwZVR5cGVzLkNob2ljZSB9KVxuXSwgQ3VydmVQcml2YXRlS2V5KTtcblxuY29uc3QgaWRTZWNwMjU2cjEgPSBcIjEuMi44NDAuMTAwNDUuMy4xLjdcIjtcbmNvbnN0IGlkRWxsaXB0aWNDdXJ2ZSA9IFwiMS4zLjEzMi4wXCI7XG5jb25zdCBpZFNlY3AzODRyMSA9IGAke2lkRWxsaXB0aWNDdXJ2ZX0uMzRgO1xuY29uc3QgaWRTZWNwNTIxcjEgPSBgJHtpZEVsbGlwdGljQ3VydmV9LjM1YDtcbmNvbnN0IGlkU2VjcDI1NmsxID0gYCR7aWRFbGxpcHRpY0N1cnZlfS4xMGA7XG5jb25zdCBpZFZlcnNpb25PbmUgPSBcIjEuMy4zNi4zLjMuMi44LjEuMVwiO1xuY29uc3QgaWRCcmFpbnBvb2xQMTYwcjEgPSBgJHtpZFZlcnNpb25PbmV9LjFgO1xuY29uc3QgaWRCcmFpbnBvb2xQMTYwdDEgPSBgJHtpZFZlcnNpb25PbmV9LjJgO1xuY29uc3QgaWRCcmFpbnBvb2xQMTkycjEgPSBgJHtpZFZlcnNpb25PbmV9LjNgO1xuY29uc3QgaWRCcmFpbnBvb2xQMTkydDEgPSBgJHtpZFZlcnNpb25PbmV9LjRgO1xuY29uc3QgaWRCcmFpbnBvb2xQMjI0cjEgPSBgJHtpZFZlcnNpb25PbmV9LjVgO1xuY29uc3QgaWRCcmFpbnBvb2xQMjI0dDEgPSBgJHtpZFZlcnNpb25PbmV9LjZgO1xuY29uc3QgaWRCcmFpbnBvb2xQMjU2cjEgPSBgJHtpZFZlcnNpb25PbmV9LjdgO1xuY29uc3QgaWRCcmFpbnBvb2xQMjU2dDEgPSBgJHtpZFZlcnNpb25PbmV9LjhgO1xuY29uc3QgaWRCcmFpbnBvb2xQMzIwcjEgPSBgJHtpZFZlcnNpb25PbmV9LjlgO1xuY29uc3QgaWRCcmFpbnBvb2xQMzIwdDEgPSBgJHtpZFZlcnNpb25PbmV9LjEwYDtcbmNvbnN0IGlkQnJhaW5wb29sUDM4NHIxID0gYCR7aWRWZXJzaW9uT25lfS4xMWA7XG5jb25zdCBpZEJyYWlucG9vbFAzODR0MSA9IGAke2lkVmVyc2lvbk9uZX0uMTJgO1xuY29uc3QgaWRCcmFpbnBvb2xQNTEycjEgPSBgJHtpZFZlcnNpb25PbmV9LjEzYDtcbmNvbnN0IGlkQnJhaW5wb29sUDUxMnQxID0gYCR7aWRWZXJzaW9uT25lfS4xNGA7XG5jb25zdCBpZFgyNTUxOSA9IFwiMS4zLjEwMS4xMTBcIjtcbmNvbnN0IGlkWDQ0OCA9IFwiMS4zLjEwMS4xMTFcIjtcbmNvbnN0IGlkRWQyNTUxOSA9IFwiMS4zLjEwMS4xMTJcIjtcbmNvbnN0IGlkRWQ0NDggPSBcIjEuMy4xMDEuMTEzXCI7XG5cbnZhciBpbmRleCQxID0gLyojX19QVVJFX18qL09iamVjdC5mcmVlemUoe1xuICBfX3Byb3RvX186IG51bGwsXG4gIEFsZ29yaXRobUlkZW50aWZpZXI6IEFsZ29yaXRobUlkZW50aWZpZXIsXG4gIGdldCBDdXJ2ZVByaXZhdGVLZXkgKCkgeyByZXR1cm4gQ3VydmVQcml2YXRlS2V5OyB9LFxuICBFY0RzYVNpZ25hdHVyZTogRWNEc2FTaWduYXR1cmUsXG4gIEVjUHJpdmF0ZUtleTogRWNQcml2YXRlS2V5LFxuICBnZXQgRWNQdWJsaWNLZXkgKCkgeyByZXR1cm4gRWNQdWJsaWNLZXk7IH0sXG4gIGdldCBFZFByaXZhdGVLZXkgKCkgeyByZXR1cm4gRWRQcml2YXRlS2V5OyB9LFxuICBnZXQgRWRQdWJsaWNLZXkgKCkgeyByZXR1cm4gRWRQdWJsaWNLZXk7IH0sXG4gIGdldCBPYmplY3RJZGVudGlmaWVyICgpIHsgcmV0dXJuIE9iamVjdElkZW50aWZpZXI7IH0sXG4gIE9uZUFzeW1tZXRyaWNLZXk6IE9uZUFzeW1tZXRyaWNLZXksXG4gIFByaXZhdGVLZXlJbmZvOiBQcml2YXRlS2V5SW5mbyxcbiAgUHVibGljS2V5SW5mbzogUHVibGljS2V5SW5mbyxcbiAgUnNhUHJpdmF0ZUtleTogUnNhUHJpdmF0ZUtleSxcbiAgUnNhUHVibGljS2V5OiBSc2FQdWJsaWNLZXksXG4gIGNvbnZlcnRlcnM6IGluZGV4JDIsXG4gIGlkQnJhaW5wb29sUDE2MHIxOiBpZEJyYWlucG9vbFAxNjByMSxcbiAgaWRCcmFpbnBvb2xQMTYwdDE6IGlkQnJhaW5wb29sUDE2MHQxLFxuICBpZEJyYWlucG9vbFAxOTJyMTogaWRCcmFpbnBvb2xQMTkycjEsXG4gIGlkQnJhaW5wb29sUDE5MnQxOiBpZEJyYWlucG9vbFAxOTJ0MSxcbiAgaWRCcmFpbnBvb2xQMjI0cjE6IGlkQnJhaW5wb29sUDIyNHIxLFxuICBpZEJyYWlucG9vbFAyMjR0MTogaWRCcmFpbnBvb2xQMjI0dDEsXG4gIGlkQnJhaW5wb29sUDI1NnIxOiBpZEJyYWlucG9vbFAyNTZyMSxcbiAgaWRCcmFpbnBvb2xQMjU2dDE6IGlkQnJhaW5wb29sUDI1NnQxLFxuICBpZEJyYWlucG9vbFAzMjByMTogaWRCcmFpbnBvb2xQMzIwcjEsXG4gIGlkQnJhaW5wb29sUDMyMHQxOiBpZEJyYWlucG9vbFAzMjB0MSxcbiAgaWRCcmFpbnBvb2xQMzg0cjE6IGlkQnJhaW5wb29sUDM4NHIxLFxuICBpZEJyYWlucG9vbFAzODR0MTogaWRCcmFpbnBvb2xQMzg0dDEsXG4gIGlkQnJhaW5wb29sUDUxMnIxOiBpZEJyYWlucG9vbFA1MTJyMSxcbiAgaWRCcmFpbnBvb2xQNTEydDE6IGlkQnJhaW5wb29sUDUxMnQxLFxuICBpZEVkMjU1MTk6IGlkRWQyNTUxOSxcbiAgaWRFZDQ0ODogaWRFZDQ0OCxcbiAgaWRFbGxpcHRpY0N1cnZlOiBpZEVsbGlwdGljQ3VydmUsXG4gIGlkU2VjcDI1NmsxOiBpZFNlY3AyNTZrMSxcbiAgaWRTZWNwMjU2cjE6IGlkU2VjcDI1NnIxLFxuICBpZFNlY3AzODRyMTogaWRTZWNwMzg0cjEsXG4gIGlkU2VjcDUyMXIxOiBpZFNlY3A1MjFyMSxcbiAgaWRWZXJzaW9uT25lOiBpZFZlcnNpb25PbmUsXG4gIGlkWDI1NTE5OiBpZFgyNTUxOSxcbiAgaWRYNDQ4OiBpZFg0NDhcbn0pO1xuXG5jbGFzcyBFY0N1cnZlcyB7XG4gICAgY29uc3RydWN0b3IoKSB7IH1cbiAgICBzdGF0aWMgcmVnaXN0ZXIoaXRlbSkge1xuICAgICAgICBjb25zdCBvaWQgPSBuZXcgT2JqZWN0SWRlbnRpZmllcigpO1xuICAgICAgICBvaWQudmFsdWUgPSBpdGVtLmlkO1xuICAgICAgICBjb25zdCByYXcgPSBBc25Db252ZXJ0LnNlcmlhbGl6ZShvaWQpO1xuICAgICAgICB0aGlzLml0ZW1zLnB1c2goe1xuICAgICAgICAgICAgLi4uaXRlbSxcbiAgICAgICAgICAgIHJhdyxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubmFtZXMucHVzaChpdGVtLm5hbWUpO1xuICAgIH1cbiAgICBzdGF0aWMgZmluZChuYW1lT3JJZCkge1xuICAgICAgICBuYW1lT3JJZCA9IG5hbWVPcklkLnRvVXBwZXJDYXNlKCk7XG4gICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiB0aGlzLml0ZW1zKSB7XG4gICAgICAgICAgICBpZiAoaXRlbS5uYW1lLnRvVXBwZXJDYXNlKCkgPT09IG5hbWVPcklkIHx8IGl0ZW0uaWQudG9VcHBlckNhc2UoKSA9PT0gbmFtZU9ySWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaXRlbTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgc3RhdGljIGdldChuYW1lT3JJZCkge1xuICAgICAgICBjb25zdCByZXMgPSB0aGlzLmZpbmQobmFtZU9ySWQpO1xuICAgICAgICBpZiAoIXJlcykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBFQyBuYW1lZCBjdXJ2ZSAnJHtuYW1lT3JJZH0nYCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG59XG5FY0N1cnZlcy5pdGVtcyA9IFtdO1xuRWNDdXJ2ZXMubmFtZXMgPSBbXTtcbkVjQ3VydmVzLnJlZ2lzdGVyKHsgbmFtZTogXCJQLTI1NlwiLCBpZDogaWRTZWNwMjU2cjEsIHNpemU6IDI1NiB9KTtcbkVjQ3VydmVzLnJlZ2lzdGVyKHsgbmFtZTogXCJQLTM4NFwiLCBpZDogaWRTZWNwMzg0cjEsIHNpemU6IDM4NCB9KTtcbkVjQ3VydmVzLnJlZ2lzdGVyKHsgbmFtZTogXCJQLTUyMVwiLCBpZDogaWRTZWNwNTIxcjEsIHNpemU6IDUyMSB9KTtcbkVjQ3VydmVzLnJlZ2lzdGVyKHsgbmFtZTogXCJLLTI1NlwiLCBpZDogaWRTZWNwMjU2azEsIHNpemU6IDI1NiB9KTtcbkVjQ3VydmVzLnJlZ2lzdGVyKHsgbmFtZTogXCJicmFpbnBvb2xQMTYwcjFcIiwgaWQ6IGlkQnJhaW5wb29sUDE2MHIxLCBzaXplOiAxNjAgfSk7XG5FY0N1cnZlcy5yZWdpc3Rlcih7IG5hbWU6IFwiYnJhaW5wb29sUDE2MHQxXCIsIGlkOiBpZEJyYWlucG9vbFAxNjB0MSwgc2l6ZTogMTYwIH0pO1xuRWNDdXJ2ZXMucmVnaXN0ZXIoeyBuYW1lOiBcImJyYWlucG9vbFAxOTJyMVwiLCBpZDogaWRCcmFpbnBvb2xQMTkycjEsIHNpemU6IDE5MiB9KTtcbkVjQ3VydmVzLnJlZ2lzdGVyKHsgbmFtZTogXCJicmFpbnBvb2xQMTkydDFcIiwgaWQ6IGlkQnJhaW5wb29sUDE5MnQxLCBzaXplOiAxOTIgfSk7XG5FY0N1cnZlcy5yZWdpc3Rlcih7IG5hbWU6IFwiYnJhaW5wb29sUDIyNHIxXCIsIGlkOiBpZEJyYWlucG9vbFAyMjRyMSwgc2l6ZTogMjI0IH0pO1xuRWNDdXJ2ZXMucmVnaXN0ZXIoeyBuYW1lOiBcImJyYWlucG9vbFAyMjR0MVwiLCBpZDogaWRCcmFpbnBvb2xQMjI0dDEsIHNpemU6IDIyNCB9KTtcbkVjQ3VydmVzLnJlZ2lzdGVyKHsgbmFtZTogXCJicmFpbnBvb2xQMjU2cjFcIiwgaWQ6IGlkQnJhaW5wb29sUDI1NnIxLCBzaXplOiAyNTYgfSk7XG5FY0N1cnZlcy5yZWdpc3Rlcih7IG5hbWU6IFwiYnJhaW5wb29sUDI1NnQxXCIsIGlkOiBpZEJyYWlucG9vbFAyNTZ0MSwgc2l6ZTogMjU2IH0pO1xuRWNDdXJ2ZXMucmVnaXN0ZXIoeyBuYW1lOiBcImJyYWlucG9vbFAzMjByMVwiLCBpZDogaWRCcmFpbnBvb2xQMzIwcjEsIHNpemU6IDMyMCB9KTtcbkVjQ3VydmVzLnJlZ2lzdGVyKHsgbmFtZTogXCJicmFpbnBvb2xQMzIwdDFcIiwgaWQ6IGlkQnJhaW5wb29sUDMyMHQxLCBzaXplOiAzMjAgfSk7XG5FY0N1cnZlcy5yZWdpc3Rlcih7IG5hbWU6IFwiYnJhaW5wb29sUDM4NHIxXCIsIGlkOiBpZEJyYWlucG9vbFAzODRyMSwgc2l6ZTogMzg0IH0pO1xuRWNDdXJ2ZXMucmVnaXN0ZXIoeyBuYW1lOiBcImJyYWlucG9vbFAzODR0MVwiLCBpZDogaWRCcmFpbnBvb2xQMzg0dDEsIHNpemU6IDM4NCB9KTtcbkVjQ3VydmVzLnJlZ2lzdGVyKHsgbmFtZTogXCJicmFpbnBvb2xQNTEycjFcIiwgaWQ6IGlkQnJhaW5wb29sUDUxMnIxLCBzaXplOiA1MTIgfSk7XG5FY0N1cnZlcy5yZWdpc3Rlcih7IG5hbWU6IFwiYnJhaW5wb29sUDUxMnQxXCIsIGlkOiBpZEJyYWlucG9vbFA1MTJ0MSwgc2l6ZTogNTEyIH0pO1xuXG5jbGFzcyBIbWFjUHJvdmlkZXIgZXh0ZW5kcyBQcm92aWRlckNyeXB0byB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiSE1BQ1wiO1xuICAgICAgICB0aGlzLmhhc2hBbGdvcml0aG1zID0gW1wiU0hBLTFcIiwgXCJTSEEtMjU2XCIsIFwiU0hBLTM4NFwiLCBcIlNIQS01MTJcIl07XG4gICAgICAgIHRoaXMudXNhZ2VzID0gW1wic2lnblwiLCBcInZlcmlmeVwiXTtcbiAgICB9XG4gICAgZ2V0RGVmYXVsdExlbmd0aChhbGdOYW1lKSB7XG4gICAgICAgIHN3aXRjaCAoYWxnTmFtZS50b1VwcGVyQ2FzZSgpKSB7XG4gICAgICAgICAgICBjYXNlIFwiU0hBLTFcIjpcbiAgICAgICAgICAgIGNhc2UgXCJTSEEtMjU2XCI6XG4gICAgICAgICAgICBjYXNlIFwiU0hBLTM4NFwiOlxuICAgICAgICAgICAgY2FzZSBcIlNIQS01MTJcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gNTEyO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gYWxnb3JpdGhtIG5hbWUgJyR7YWxnTmFtZX0nYCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY2hlY2tHZW5lcmF0ZUtleVBhcmFtcyhhbGdvcml0aG0pIHtcbiAgICAgICAgdGhpcy5jaGVja1JlcXVpcmVkUHJvcGVydHkoYWxnb3JpdGhtLCBcImhhc2hcIik7XG4gICAgICAgIHRoaXMuY2hlY2tIYXNoQWxnb3JpdGhtKGFsZ29yaXRobS5oYXNoLCB0aGlzLmhhc2hBbGdvcml0aG1zKTtcbiAgICAgICAgaWYgKFwibGVuZ3RoXCIgaW4gYWxnb3JpdGhtKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGFsZ29yaXRobS5sZW5ndGggIT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwibGVuZ3RoOiBJcyBub3QgYSBOdW1iZXJcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoYWxnb3JpdGhtLmxlbmd0aCA8IDEpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcImxlbmd0aDogTnVtYmVyIGlzIG91dCBvZiByYW5nZVwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBjaGVja0ltcG9ydFBhcmFtcyhhbGdvcml0aG0pIHtcbiAgICAgICAgdGhpcy5jaGVja1JlcXVpcmVkUHJvcGVydHkoYWxnb3JpdGhtLCBcImhhc2hcIik7XG4gICAgICAgIHRoaXMuY2hlY2tIYXNoQWxnb3JpdGhtKGFsZ29yaXRobS5oYXNoLCB0aGlzLmhhc2hBbGdvcml0aG1zKTtcbiAgICB9XG59XG5cbmNsYXNzIFBia2RmMlByb3ZpZGVyIGV4dGVuZHMgUHJvdmlkZXJDcnlwdG8ge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlBCS0RGMlwiO1xuICAgICAgICB0aGlzLmhhc2hBbGdvcml0aG1zID0gW1wiU0hBLTFcIiwgXCJTSEEtMjU2XCIsIFwiU0hBLTM4NFwiLCBcIlNIQS01MTJcIl07XG4gICAgICAgIHRoaXMudXNhZ2VzID0gW1wiZGVyaXZlQml0c1wiLCBcImRlcml2ZUtleVwiXTtcbiAgICB9XG4gICAgY2hlY2tBbGdvcml0aG1QYXJhbXMoYWxnb3JpdGhtKSB7XG4gICAgICAgIHRoaXMuY2hlY2tSZXF1aXJlZFByb3BlcnR5KGFsZ29yaXRobSwgXCJoYXNoXCIpO1xuICAgICAgICB0aGlzLmNoZWNrSGFzaEFsZ29yaXRobShhbGdvcml0aG0uaGFzaCwgdGhpcy5oYXNoQWxnb3JpdGhtcyk7XG4gICAgICAgIHRoaXMuY2hlY2tSZXF1aXJlZFByb3BlcnR5KGFsZ29yaXRobSwgXCJzYWx0XCIpO1xuICAgICAgICBpZiAoIShhbGdvcml0aG0uc2FsdCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyIHx8IEFycmF5QnVmZmVyLmlzVmlldyhhbGdvcml0aG0uc2FsdCkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwic2FsdDogSXMgbm90IG9mIHR5cGUgJyhBcnJheUJ1ZmZlciBvciBBcnJheUJ1ZmZlclZpZXcpJ1wiKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNoZWNrUmVxdWlyZWRQcm9wZXJ0eShhbGdvcml0aG0sIFwiaXRlcmF0aW9uc1wiKTtcbiAgICAgICAgaWYgKHR5cGVvZiBhbGdvcml0aG0uaXRlcmF0aW9ucyAhPT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIml0ZXJhdGlvbnM6IElzIG5vdCBhIE51bWJlclwiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYWxnb3JpdGhtLml0ZXJhdGlvbnMgPCAxKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiaXRlcmF0aW9uczogSXMgbGVzcyB0aGFuIDFcIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY2hlY2tJbXBvcnRLZXkoZm9ybWF0LCBrZXlEYXRhLCBhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMsIC4uLmFyZ3MpIHtcbiAgICAgICAgc3VwZXIuY2hlY2tJbXBvcnRLZXkoZm9ybWF0LCBrZXlEYXRhLCBhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpO1xuICAgICAgICBpZiAoZXh0cmFjdGFibGUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcImV4dHJhY3RhYmxlOiBNdXN0IGJlICdmYWxzZSdcIik7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmNsYXNzIEhrZGZQcm92aWRlciBleHRlbmRzIFByb3ZpZGVyQ3J5cHRvIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJIS0RGXCI7XG4gICAgICAgIHRoaXMuaGFzaEFsZ29yaXRobXMgPSBbXCJTSEEtMVwiLCBcIlNIQS0yNTZcIiwgXCJTSEEtMzg0XCIsIFwiU0hBLTUxMlwiXTtcbiAgICAgICAgdGhpcy51c2FnZXMgPSBbXCJkZXJpdmVLZXlcIiwgXCJkZXJpdmVCaXRzXCJdO1xuICAgIH1cbiAgICBjaGVja0FsZ29yaXRobVBhcmFtcyhhbGdvcml0aG0pIHtcbiAgICAgICAgdGhpcy5jaGVja1JlcXVpcmVkUHJvcGVydHkoYWxnb3JpdGhtLCBcImhhc2hcIik7XG4gICAgICAgIHRoaXMuY2hlY2tIYXNoQWxnb3JpdGhtKGFsZ29yaXRobS5oYXNoLCB0aGlzLmhhc2hBbGdvcml0aG1zKTtcbiAgICAgICAgdGhpcy5jaGVja1JlcXVpcmVkUHJvcGVydHkoYWxnb3JpdGhtLCBcInNhbHRcIik7XG4gICAgICAgIGlmICghQnVmZmVyU291cmNlQ29udmVydGVyLmlzQnVmZmVyU291cmNlKGFsZ29yaXRobS5zYWx0KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInNhbHQ6IElzIG5vdCBvZiB0eXBlICcoQXJyYXlCdWZmZXIgb3IgQXJyYXlCdWZmZXJWaWV3KSdcIik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jaGVja1JlcXVpcmVkUHJvcGVydHkoYWxnb3JpdGhtLCBcImluZm9cIik7XG4gICAgICAgIGlmICghQnVmZmVyU291cmNlQ29udmVydGVyLmlzQnVmZmVyU291cmNlKGFsZ29yaXRobS5pbmZvKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInNhbHQ6IElzIG5vdCBvZiB0eXBlICcoQXJyYXlCdWZmZXIgb3IgQXJyYXlCdWZmZXJWaWV3KSdcIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY2hlY2tJbXBvcnRLZXkoZm9ybWF0LCBrZXlEYXRhLCBhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMsIC4uLmFyZ3MpIHtcbiAgICAgICAgc3VwZXIuY2hlY2tJbXBvcnRLZXkoZm9ybWF0LCBrZXlEYXRhLCBhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpO1xuICAgICAgICBpZiAoZXh0cmFjdGFibGUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcImV4dHJhY3RhYmxlOiBNdXN0IGJlICdmYWxzZSdcIik7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmNsYXNzIFNoYWtlUHJvdmlkZXIgZXh0ZW5kcyBQcm92aWRlckNyeXB0byB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMudXNhZ2VzID0gW107XG4gICAgICAgIHRoaXMuZGVmYXVsdExlbmd0aCA9IDA7XG4gICAgfVxuICAgIGRpZ2VzdCguLi5hcmdzKSB7XG4gICAgICAgIGFyZ3NbMF0gPSB7IGxlbmd0aDogdGhpcy5kZWZhdWx0TGVuZ3RoLCAuLi5hcmdzWzBdIH07XG4gICAgICAgIHJldHVybiBzdXBlci5kaWdlc3QuYXBwbHkodGhpcywgYXJncyk7XG4gICAgfVxuICAgIGNoZWNrRGlnZXN0KGFsZ29yaXRobSwgZGF0YSkge1xuICAgICAgICBzdXBlci5jaGVja0RpZ2VzdChhbGdvcml0aG0sIGRhdGEpO1xuICAgICAgICBjb25zdCBsZW5ndGggPSBhbGdvcml0aG0ubGVuZ3RoIHx8IDA7XG4gICAgICAgIGlmICh0eXBlb2YgbGVuZ3RoICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwibGVuZ3RoOiBJcyBub3QgYSBOdW1iZXJcIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGxlbmd0aCA8IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJsZW5ndGg6IElzIG5lZ2F0aXZlXCIpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5jbGFzcyBTaGFrZTEyOFByb3ZpZGVyIGV4dGVuZHMgU2hha2VQcm92aWRlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwic2hha2UxMjhcIjtcbiAgICAgICAgdGhpcy5kZWZhdWx0TGVuZ3RoID0gMTY7XG4gICAgfVxufVxuXG5jbGFzcyBTaGFrZTI1NlByb3ZpZGVyIGV4dGVuZHMgU2hha2VQcm92aWRlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwic2hha2UyNTZcIjtcbiAgICAgICAgdGhpcy5kZWZhdWx0TGVuZ3RoID0gMzI7XG4gICAgfVxufVxuXG5jbGFzcyBDcnlwdG8ge1xuICAgIGdldCBbU3ltYm9sLnRvU3RyaW5nVGFnXSgpIHtcbiAgICAgICAgcmV0dXJuIFwiQ3J5cHRvXCI7XG4gICAgfVxuICAgIHJhbmRvbVVVSUQoKSB7XG4gICAgICAgIGNvbnN0IGIgPSB0aGlzLmdldFJhbmRvbVZhbHVlcyhuZXcgVWludDhBcnJheSgxNikpO1xuICAgICAgICBiWzZdID0gKGJbNl0gJiAweDBmKSB8IDB4NDA7XG4gICAgICAgIGJbOF0gPSAoYls4XSAmIDB4M2YpIHwgMHg4MDtcbiAgICAgICAgY29uc3QgdXVpZCA9IENvbnZlcnQuVG9IZXgoYikudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgcmV0dXJuIGAke3V1aWQuc3Vic3RyaW5nKDAsIDgpfS0ke3V1aWQuc3Vic3RyaW5nKDgsIDEyKX0tJHt1dWlkLnN1YnN0cmluZygxMiwgMTYpfS0ke3V1aWQuc3Vic3RyaW5nKDE2LCAyMCl9LSR7dXVpZC5zdWJzdHJpbmcoMjApfWA7XG4gICAgfVxufVxuXG5jbGFzcyBQcm92aWRlclN0b3JhZ2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLml0ZW1zID0ge307XG4gICAgfVxuICAgIGdldChhbGdvcml0aG1OYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLml0ZW1zW2FsZ29yaXRobU5hbWUudG9Mb3dlckNhc2UoKV0gfHwgbnVsbDtcbiAgICB9XG4gICAgc2V0KHByb3ZpZGVyKSB7XG4gICAgICAgIHRoaXMuaXRlbXNbcHJvdmlkZXIubmFtZS50b0xvd2VyQ2FzZSgpXSA9IHByb3ZpZGVyO1xuICAgIH1cbiAgICByZW1vdmVBdChhbGdvcml0aG1OYW1lKSB7XG4gICAgICAgIGNvbnN0IHByb3ZpZGVyID0gdGhpcy5nZXQoYWxnb3JpdGhtTmFtZS50b0xvd2VyQ2FzZSgpKTtcbiAgICAgICAgaWYgKHByb3ZpZGVyKSB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5pdGVtc1thbGdvcml0aG1OYW1lXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcHJvdmlkZXI7XG4gICAgfVxuICAgIGhhcyhuYW1lKSB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuZ2V0KG5hbWUpO1xuICAgIH1cbiAgICBnZXQgbGVuZ3RoKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmtleXModGhpcy5pdGVtcykubGVuZ3RoO1xuICAgIH1cbiAgICBnZXQgYWxnb3JpdGhtcygpIHtcbiAgICAgICAgY29uc3QgYWxnb3JpdGhtcyA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiB0aGlzLml0ZW1zKSB7XG4gICAgICAgICAgICBjb25zdCBwcm92aWRlciA9IHRoaXMuaXRlbXNba2V5XTtcbiAgICAgICAgICAgIGFsZ29yaXRobXMucHVzaChwcm92aWRlci5uYW1lKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYWxnb3JpdGhtcy5zb3J0KCk7XG4gICAgfVxufVxuXG5jbGFzcyBTdWJ0bGVDcnlwdG8ge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnByb3ZpZGVycyA9IG5ldyBQcm92aWRlclN0b3JhZ2UoKTtcbiAgICB9XG4gICAgc3RhdGljIGlzSGFzaGVkQWxnb3JpdGhtKGRhdGEpIHtcbiAgICAgICAgcmV0dXJuIGRhdGFcbiAgICAgICAgICAgICYmIHR5cGVvZiBkYXRhID09PSBcIm9iamVjdFwiXG4gICAgICAgICAgICAmJiBcIm5hbWVcIiBpbiBkYXRhXG4gICAgICAgICAgICAmJiBcImhhc2hcIiBpbiBkYXRhXG4gICAgICAgICAgICA/IHRydWVcbiAgICAgICAgICAgIDogZmFsc2U7XG4gICAgfVxuICAgIGdldCBbU3ltYm9sLnRvU3RyaW5nVGFnXSgpIHtcbiAgICAgICAgcmV0dXJuIFwiU3VidGxlQ3J5cHRvXCI7XG4gICAgfVxuICAgIGFzeW5jIGRpZ2VzdCguLi5hcmdzKSB7XG4gICAgICAgIHRoaXMuY2hlY2tSZXF1aXJlZEFyZ3VtZW50cyhhcmdzLCAyLCBcImRpZ2VzdFwiKTtcbiAgICAgICAgY29uc3QgW2FsZ29yaXRobSwgZGF0YSwgLi4ucGFyYW1zXSA9IGFyZ3M7XG4gICAgICAgIGNvbnN0IHByZXBhcmVkQWxnb3JpdGhtID0gdGhpcy5wcmVwYXJlQWxnb3JpdGhtKGFsZ29yaXRobSk7XG4gICAgICAgIGNvbnN0IHByZXBhcmVkRGF0YSA9IEJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b0FycmF5QnVmZmVyKGRhdGEpO1xuICAgICAgICBjb25zdCBwcm92aWRlciA9IHRoaXMuZ2V0UHJvdmlkZXIocHJlcGFyZWRBbGdvcml0aG0ubmFtZSk7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHByb3ZpZGVyLmRpZ2VzdChwcmVwYXJlZEFsZ29yaXRobSwgcHJlcGFyZWREYXRhLCAuLi5wYXJhbXMpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgICBhc3luYyBnZW5lcmF0ZUtleSguLi5hcmdzKSB7XG4gICAgICAgIHRoaXMuY2hlY2tSZXF1aXJlZEFyZ3VtZW50cyhhcmdzLCAzLCBcImdlbmVyYXRlS2V5XCIpO1xuICAgICAgICBjb25zdCBbYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzLCAuLi5wYXJhbXNdID0gYXJncztcbiAgICAgICAgY29uc3QgcHJlcGFyZWRBbGdvcml0aG0gPSB0aGlzLnByZXBhcmVBbGdvcml0aG0oYWxnb3JpdGhtKTtcbiAgICAgICAgY29uc3QgcHJvdmlkZXIgPSB0aGlzLmdldFByb3ZpZGVyKHByZXBhcmVkQWxnb3JpdGhtLm5hbWUpO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwcm92aWRlci5nZW5lcmF0ZUtleSh7IC4uLnByZXBhcmVkQWxnb3JpdGhtLCBuYW1lOiBwcm92aWRlci5uYW1lIH0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMsIC4uLnBhcmFtcyk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICAgIGFzeW5jIHNpZ24oLi4uYXJncykge1xuICAgICAgICB0aGlzLmNoZWNrUmVxdWlyZWRBcmd1bWVudHMoYXJncywgMywgXCJzaWduXCIpO1xuICAgICAgICBjb25zdCBbYWxnb3JpdGhtLCBrZXksIGRhdGEsIC4uLnBhcmFtc10gPSBhcmdzO1xuICAgICAgICB0aGlzLmNoZWNrQ3J5cHRvS2V5KGtleSk7XG4gICAgICAgIGNvbnN0IHByZXBhcmVkQWxnb3JpdGhtID0gdGhpcy5wcmVwYXJlQWxnb3JpdGhtKGFsZ29yaXRobSk7XG4gICAgICAgIGNvbnN0IHByZXBhcmVkRGF0YSA9IEJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b0FycmF5QnVmZmVyKGRhdGEpO1xuICAgICAgICBjb25zdCBwcm92aWRlciA9IHRoaXMuZ2V0UHJvdmlkZXIocHJlcGFyZWRBbGdvcml0aG0ubmFtZSk7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHByb3ZpZGVyLnNpZ24oeyAuLi5wcmVwYXJlZEFsZ29yaXRobSwgbmFtZTogcHJvdmlkZXIubmFtZSB9LCBrZXksIHByZXBhcmVkRGF0YSwgLi4ucGFyYW1zKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgYXN5bmMgdmVyaWZ5KC4uLmFyZ3MpIHtcbiAgICAgICAgdGhpcy5jaGVja1JlcXVpcmVkQXJndW1lbnRzKGFyZ3MsIDQsIFwidmVyaWZ5XCIpO1xuICAgICAgICBjb25zdCBbYWxnb3JpdGhtLCBrZXksIHNpZ25hdHVyZSwgZGF0YSwgLi4ucGFyYW1zXSA9IGFyZ3M7XG4gICAgICAgIHRoaXMuY2hlY2tDcnlwdG9LZXkoa2V5KTtcbiAgICAgICAgY29uc3QgcHJlcGFyZWRBbGdvcml0aG0gPSB0aGlzLnByZXBhcmVBbGdvcml0aG0oYWxnb3JpdGhtKTtcbiAgICAgICAgY29uc3QgcHJlcGFyZWREYXRhID0gQnVmZmVyU291cmNlQ29udmVydGVyLnRvQXJyYXlCdWZmZXIoZGF0YSk7XG4gICAgICAgIGNvbnN0IHByZXBhcmVkU2lnbmF0dXJlID0gQnVmZmVyU291cmNlQ29udmVydGVyLnRvQXJyYXlCdWZmZXIoc2lnbmF0dXJlKTtcbiAgICAgICAgY29uc3QgcHJvdmlkZXIgPSB0aGlzLmdldFByb3ZpZGVyKHByZXBhcmVkQWxnb3JpdGhtLm5hbWUpO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwcm92aWRlci52ZXJpZnkoeyAuLi5wcmVwYXJlZEFsZ29yaXRobSwgbmFtZTogcHJvdmlkZXIubmFtZSB9LCBrZXksIHByZXBhcmVkU2lnbmF0dXJlLCBwcmVwYXJlZERhdGEsIC4uLnBhcmFtcyk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICAgIGFzeW5jIGVuY3J5cHQoLi4uYXJncykge1xuICAgICAgICB0aGlzLmNoZWNrUmVxdWlyZWRBcmd1bWVudHMoYXJncywgMywgXCJlbmNyeXB0XCIpO1xuICAgICAgICBjb25zdCBbYWxnb3JpdGhtLCBrZXksIGRhdGEsIC4uLnBhcmFtc10gPSBhcmdzO1xuICAgICAgICB0aGlzLmNoZWNrQ3J5cHRvS2V5KGtleSk7XG4gICAgICAgIGNvbnN0IHByZXBhcmVkQWxnb3JpdGhtID0gdGhpcy5wcmVwYXJlQWxnb3JpdGhtKGFsZ29yaXRobSk7XG4gICAgICAgIGNvbnN0IHByZXBhcmVkRGF0YSA9IEJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b0FycmF5QnVmZmVyKGRhdGEpO1xuICAgICAgICBjb25zdCBwcm92aWRlciA9IHRoaXMuZ2V0UHJvdmlkZXIocHJlcGFyZWRBbGdvcml0aG0ubmFtZSk7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHByb3ZpZGVyLmVuY3J5cHQoeyAuLi5wcmVwYXJlZEFsZ29yaXRobSwgbmFtZTogcHJvdmlkZXIubmFtZSB9LCBrZXksIHByZXBhcmVkRGF0YSwgeyBrZXlVc2FnZTogdHJ1ZSB9LCAuLi5wYXJhbXMpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgICBhc3luYyBkZWNyeXB0KC4uLmFyZ3MpIHtcbiAgICAgICAgdGhpcy5jaGVja1JlcXVpcmVkQXJndW1lbnRzKGFyZ3MsIDMsIFwiZGVjcnlwdFwiKTtcbiAgICAgICAgY29uc3QgW2FsZ29yaXRobSwga2V5LCBkYXRhLCAuLi5wYXJhbXNdID0gYXJncztcbiAgICAgICAgdGhpcy5jaGVja0NyeXB0b0tleShrZXkpO1xuICAgICAgICBjb25zdCBwcmVwYXJlZEFsZ29yaXRobSA9IHRoaXMucHJlcGFyZUFsZ29yaXRobShhbGdvcml0aG0pO1xuICAgICAgICBjb25zdCBwcmVwYXJlZERhdGEgPSBCdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9BcnJheUJ1ZmZlcihkYXRhKTtcbiAgICAgICAgY29uc3QgcHJvdmlkZXIgPSB0aGlzLmdldFByb3ZpZGVyKHByZXBhcmVkQWxnb3JpdGhtLm5hbWUpO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwcm92aWRlci5kZWNyeXB0KHsgLi4ucHJlcGFyZWRBbGdvcml0aG0sIG5hbWU6IHByb3ZpZGVyLm5hbWUgfSwga2V5LCBwcmVwYXJlZERhdGEsIHsga2V5VXNhZ2U6IHRydWUgfSwgLi4ucGFyYW1zKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgYXN5bmMgZGVyaXZlQml0cyguLi5hcmdzKSB7XG4gICAgICAgIHRoaXMuY2hlY2tSZXF1aXJlZEFyZ3VtZW50cyhhcmdzLCAzLCBcImRlcml2ZUJpdHNcIik7XG4gICAgICAgIGNvbnN0IFthbGdvcml0aG0sIGJhc2VLZXksIGxlbmd0aCwgLi4ucGFyYW1zXSA9IGFyZ3M7XG4gICAgICAgIHRoaXMuY2hlY2tDcnlwdG9LZXkoYmFzZUtleSk7XG4gICAgICAgIGNvbnN0IHByZXBhcmVkQWxnb3JpdGhtID0gdGhpcy5wcmVwYXJlQWxnb3JpdGhtKGFsZ29yaXRobSk7XG4gICAgICAgIGNvbnN0IHByb3ZpZGVyID0gdGhpcy5nZXRQcm92aWRlcihwcmVwYXJlZEFsZ29yaXRobS5uYW1lKTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcHJvdmlkZXIuZGVyaXZlQml0cyh7IC4uLnByZXBhcmVkQWxnb3JpdGhtLCBuYW1lOiBwcm92aWRlci5uYW1lIH0sIGJhc2VLZXksIGxlbmd0aCwgeyBrZXlVc2FnZTogdHJ1ZSB9LCAuLi5wYXJhbXMpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgICBhc3luYyBkZXJpdmVLZXkoLi4uYXJncykge1xuICAgICAgICB0aGlzLmNoZWNrUmVxdWlyZWRBcmd1bWVudHMoYXJncywgNSwgXCJkZXJpdmVLZXlcIik7XG4gICAgICAgIGNvbnN0IFthbGdvcml0aG0sIGJhc2VLZXksIGRlcml2ZWRLZXlUeXBlLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzLCAuLi5wYXJhbXNdID0gYXJncztcbiAgICAgICAgY29uc3QgcHJlcGFyZWREZXJpdmVkS2V5VHlwZSA9IHRoaXMucHJlcGFyZUFsZ29yaXRobShkZXJpdmVkS2V5VHlwZSk7XG4gICAgICAgIGNvbnN0IGltcG9ydFByb3ZpZGVyID0gdGhpcy5nZXRQcm92aWRlcihwcmVwYXJlZERlcml2ZWRLZXlUeXBlLm5hbWUpO1xuICAgICAgICBpbXBvcnRQcm92aWRlci5jaGVja0Rlcml2ZWRLZXlQYXJhbXMocHJlcGFyZWREZXJpdmVkS2V5VHlwZSk7XG4gICAgICAgIGNvbnN0IHByZXBhcmVkQWxnb3JpdGhtID0gdGhpcy5wcmVwYXJlQWxnb3JpdGhtKGFsZ29yaXRobSk7XG4gICAgICAgIGNvbnN0IHByb3ZpZGVyID0gdGhpcy5nZXRQcm92aWRlcihwcmVwYXJlZEFsZ29yaXRobS5uYW1lKTtcbiAgICAgICAgcHJvdmlkZXIuY2hlY2tDcnlwdG9LZXkoYmFzZUtleSwgXCJkZXJpdmVLZXlcIik7XG4gICAgICAgIGNvbnN0IGRlcml2ZWRCaXRzID0gYXdhaXQgcHJvdmlkZXIuZGVyaXZlQml0cyh7IC4uLnByZXBhcmVkQWxnb3JpdGhtLCBuYW1lOiBwcm92aWRlci5uYW1lIH0sIGJhc2VLZXksIGRlcml2ZWRLZXlUeXBlLmxlbmd0aCB8fCA1MTIsIHsga2V5VXNhZ2U6IGZhbHNlIH0sIC4uLnBhcmFtcyk7XG4gICAgICAgIHJldHVybiB0aGlzLmltcG9ydEtleShcInJhd1wiLCBkZXJpdmVkQml0cywgZGVyaXZlZEtleVR5cGUsIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMsIC4uLnBhcmFtcyk7XG4gICAgfVxuICAgIGFzeW5jIGV4cG9ydEtleSguLi5hcmdzKSB7XG4gICAgICAgIHRoaXMuY2hlY2tSZXF1aXJlZEFyZ3VtZW50cyhhcmdzLCAyLCBcImV4cG9ydEtleVwiKTtcbiAgICAgICAgY29uc3QgW2Zvcm1hdCwga2V5LCAuLi5wYXJhbXNdID0gYXJncztcbiAgICAgICAgdGhpcy5jaGVja0NyeXB0b0tleShrZXkpO1xuICAgICAgICBjb25zdCBwcm92aWRlciA9IHRoaXMuZ2V0UHJvdmlkZXIoa2V5LmFsZ29yaXRobS5uYW1lKTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcHJvdmlkZXIuZXhwb3J0S2V5KGZvcm1hdCwga2V5LCAuLi5wYXJhbXMpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgICBhc3luYyBpbXBvcnRLZXkoLi4uYXJncykge1xuICAgICAgICB0aGlzLmNoZWNrUmVxdWlyZWRBcmd1bWVudHMoYXJncywgNSwgXCJpbXBvcnRLZXlcIik7XG4gICAgICAgIGNvbnN0IFtmb3JtYXQsIGtleURhdGEsIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcywgLi4ucGFyYW1zXSA9IGFyZ3M7XG4gICAgICAgIGNvbnN0IHByZXBhcmVkQWxnb3JpdGhtID0gdGhpcy5wcmVwYXJlQWxnb3JpdGhtKGFsZ29yaXRobSk7XG4gICAgICAgIGNvbnN0IHByb3ZpZGVyID0gdGhpcy5nZXRQcm92aWRlcihwcmVwYXJlZEFsZ29yaXRobS5uYW1lKTtcbiAgICAgICAgaWYgKFtcInBrY3M4XCIsIFwic3BraVwiLCBcInJhd1wiXS5pbmRleE9mKGZvcm1hdCkgIT09IC0xKSB7XG4gICAgICAgICAgICBjb25zdCBwcmVwYXJlZERhdGEgPSBCdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9BcnJheUJ1ZmZlcihrZXlEYXRhKTtcbiAgICAgICAgICAgIHJldHVybiBwcm92aWRlci5pbXBvcnRLZXkoZm9ybWF0LCBwcmVwYXJlZERhdGEsIHsgLi4ucHJlcGFyZWRBbGdvcml0aG0sIG5hbWU6IHByb3ZpZGVyLm5hbWUgfSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcywgLi4ucGFyYW1zKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmICgha2V5RGF0YS5rdHkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwia2V5RGF0YTogSXMgbm90IEpTT05cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHByb3ZpZGVyLmltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIHsgLi4ucHJlcGFyZWRBbGdvcml0aG0sIG5hbWU6IHByb3ZpZGVyLm5hbWUgfSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcywgLi4ucGFyYW1zKTtcbiAgICB9XG4gICAgYXN5bmMgd3JhcEtleShmb3JtYXQsIGtleSwgd3JhcHBpbmdLZXksIHdyYXBBbGdvcml0aG0sIC4uLmFyZ3MpIHtcbiAgICAgICAgbGV0IGtleURhdGEgPSBhd2FpdCB0aGlzLmV4cG9ydEtleShmb3JtYXQsIGtleSwgLi4uYXJncyk7XG4gICAgICAgIGlmIChmb3JtYXQgPT09IFwiandrXCIpIHtcbiAgICAgICAgICAgIGNvbnN0IGpzb24gPSBKU09OLnN0cmluZ2lmeShrZXlEYXRhKTtcbiAgICAgICAgICAgIGtleURhdGEgPSBDb252ZXJ0LkZyb21VdGY4U3RyaW5nKGpzb24pO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHByZXBhcmVkQWxnb3JpdGhtID0gdGhpcy5wcmVwYXJlQWxnb3JpdGhtKHdyYXBBbGdvcml0aG0pO1xuICAgICAgICBjb25zdCBwcmVwYXJlZERhdGEgPSBCdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9BcnJheUJ1ZmZlcihrZXlEYXRhKTtcbiAgICAgICAgY29uc3QgcHJvdmlkZXIgPSB0aGlzLmdldFByb3ZpZGVyKHByZXBhcmVkQWxnb3JpdGhtLm5hbWUpO1xuICAgICAgICByZXR1cm4gcHJvdmlkZXIuZW5jcnlwdCh7IC4uLnByZXBhcmVkQWxnb3JpdGhtLCBuYW1lOiBwcm92aWRlci5uYW1lIH0sIHdyYXBwaW5nS2V5LCBwcmVwYXJlZERhdGEsIHsga2V5VXNhZ2U6IGZhbHNlIH0sIC4uLmFyZ3MpO1xuICAgIH1cbiAgICBhc3luYyB1bndyYXBLZXkoZm9ybWF0LCB3cmFwcGVkS2V5LCB1bndyYXBwaW5nS2V5LCB1bndyYXBBbGdvcml0aG0sIHVud3JhcHBlZEtleUFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcywgLi4uYXJncykge1xuICAgICAgICBjb25zdCBwcmVwYXJlZEFsZ29yaXRobSA9IHRoaXMucHJlcGFyZUFsZ29yaXRobSh1bndyYXBBbGdvcml0aG0pO1xuICAgICAgICBjb25zdCBwcmVwYXJlZERhdGEgPSBCdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9BcnJheUJ1ZmZlcih3cmFwcGVkS2V5KTtcbiAgICAgICAgY29uc3QgcHJvdmlkZXIgPSB0aGlzLmdldFByb3ZpZGVyKHByZXBhcmVkQWxnb3JpdGhtLm5hbWUpO1xuICAgICAgICBsZXQga2V5RGF0YSA9IGF3YWl0IHByb3ZpZGVyLmRlY3J5cHQoeyAuLi5wcmVwYXJlZEFsZ29yaXRobSwgbmFtZTogcHJvdmlkZXIubmFtZSB9LCB1bndyYXBwaW5nS2V5LCBwcmVwYXJlZERhdGEsIHsga2V5VXNhZ2U6IGZhbHNlIH0sIC4uLmFyZ3MpO1xuICAgICAgICBpZiAoZm9ybWF0ID09PSBcImp3a1wiKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGtleURhdGEgPSBKU09OLnBhcnNlKENvbnZlcnQuVG9VdGY4U3RyaW5nKGtleURhdGEpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgVHlwZUVycm9yKFwid3JhcHBlZEtleTogSXMgbm90IGEgSlNPTlwiKTtcbiAgICAgICAgICAgICAgICBlcnJvci5pbnRlcm5hbCA9IGU7XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuaW1wb3J0S2V5KGZvcm1hdCwga2V5RGF0YSwgdW53cmFwcGVkS2V5QWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzLCAuLi5hcmdzKTtcbiAgICB9XG4gICAgY2hlY2tSZXF1aXJlZEFyZ3VtZW50cyhhcmdzLCBzaXplLCBtZXRob2ROYW1lKSB7XG4gICAgICAgIGlmIChhcmdzLmxlbmd0aCA8IHNpemUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYEZhaWxlZCB0byBleGVjdXRlICcke21ldGhvZE5hbWV9JyBvbiAnU3VidGxlQ3J5cHRvJzogJHtzaXplfSBhcmd1bWVudHMgcmVxdWlyZWQsIGJ1dCBvbmx5ICR7YXJncy5sZW5ndGh9IHByZXNlbnRgKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBwcmVwYXJlQWxnb3JpdGhtKGFsZ29yaXRobSkge1xuICAgICAgICBpZiAodHlwZW9mIGFsZ29yaXRobSA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBuYW1lOiBhbGdvcml0aG0sXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGlmIChTdWJ0bGVDcnlwdG8uaXNIYXNoZWRBbGdvcml0aG0oYWxnb3JpdGhtKSkge1xuICAgICAgICAgICAgY29uc3QgcHJlcGFyZWRBbGdvcml0aG0gPSB7IC4uLmFsZ29yaXRobSB9O1xuICAgICAgICAgICAgcHJlcGFyZWRBbGdvcml0aG0uaGFzaCA9IHRoaXMucHJlcGFyZUFsZ29yaXRobShhbGdvcml0aG0uaGFzaCk7XG4gICAgICAgICAgICByZXR1cm4gcHJlcGFyZWRBbGdvcml0aG07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgLi4uYWxnb3JpdGhtIH07XG4gICAgfVxuICAgIGdldFByb3ZpZGVyKG5hbWUpIHtcbiAgICAgICAgY29uc3QgcHJvdmlkZXIgPSB0aGlzLnByb3ZpZGVycy5nZXQobmFtZSk7XG4gICAgICAgIGlmICghcHJvdmlkZXIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBBbGdvcml0aG1FcnJvcihcIlVucmVjb2duaXplZCBuYW1lXCIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwcm92aWRlcjtcbiAgICB9XG4gICAgY2hlY2tDcnlwdG9LZXkoa2V5KSB7XG4gICAgICAgIGlmICghKGtleSBpbnN0YW5jZW9mIENyeXB0b0tleSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYEtleSBpcyBub3Qgb2YgdHlwZSAnQ3J5cHRvS2V5J2ApO1xuICAgICAgICB9XG4gICAgfVxufVxuXG52YXIgaW5kZXggPSAvKiNfX1BVUkVfXyovT2JqZWN0LmZyZWV6ZSh7XG4gIF9fcHJvdG9fXzogbnVsbCxcbiAgY29udmVydGVyczogaW5kZXgkM1xufSk7XG5cbmNvbnN0IFJFUVVJUkVEX0ZJRUxEUyA9IFtcImNydlwiLCBcImVcIiwgXCJrXCIsIFwia3R5XCIsIFwiblwiLCBcInhcIiwgXCJ5XCJdO1xuY2xhc3MgSndrVXRpbHMge1xuICAgIHN0YXRpYyBhc3luYyB0aHVtYnByaW50KGhhc2gsIGp3aywgY3J5cHRvKSB7XG4gICAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLmZvcm1hdChqd2ssIHRydWUpO1xuICAgICAgICByZXR1cm4gY3J5cHRvLnN1YnRsZS5kaWdlc3QoaGFzaCwgQ29udmVydC5Gcm9tQmluYXJ5KEpTT04uc3RyaW5naWZ5KGRhdGEpKSk7XG4gICAgfVxuICAgIHN0YXRpYyBmb3JtYXQoandrLCByZW1vdmUgPSBmYWxzZSkge1xuICAgICAgICBsZXQgcmVzID0gT2JqZWN0LmVudHJpZXMoandrKTtcbiAgICAgICAgaWYgKHJlbW92ZSkge1xuICAgICAgICAgICAgcmVzID0gcmVzLmZpbHRlcihvID0+IFJFUVVJUkVEX0ZJRUxEUy5pbmNsdWRlcyhvWzBdKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzID0gcmVzLnNvcnQoKFtrZXlBXSwgW2tleUJdKSA9PiBrZXlBID4ga2V5QiA/IDEgOiBrZXlBIDwga2V5QiA/IC0xIDogMCk7XG4gICAgICAgIHJldHVybiBPYmplY3QuZnJvbUVudHJpZXMocmVzKTtcbiAgICB9XG59XG5cbmV4cG9ydCB7IEFlc0NiY1Byb3ZpZGVyLCBBZXNDbWFjUHJvdmlkZXIsIEFlc0N0clByb3ZpZGVyLCBBZXNFY2JQcm92aWRlciwgQWVzR2NtUHJvdmlkZXIsIEFlc0t3UHJvdmlkZXIsIEFlc1Byb3ZpZGVyLCBBbGdvcml0aG1FcnJvciwgQ3J5cHRvLCBDcnlwdG9FcnJvciwgQ3J5cHRvS2V5LCBEZXNQcm92aWRlciwgRWNDdXJ2ZXMsIEVjVXRpbHMsIEVjZGhFc1Byb3ZpZGVyLCBFY2RoUHJvdmlkZXIsIEVjZHNhUHJvdmlkZXIsIEVkRHNhUHJvdmlkZXIsIEVsbGlwdGljUHJvdmlkZXIsIEhrZGZQcm92aWRlciwgSG1hY1Byb3ZpZGVyLCBKd2tVdGlscywgT3BlcmF0aW9uRXJyb3IsIFBia2RmMlByb3ZpZGVyLCBQZW1Db252ZXJ0ZXIsIFByb3ZpZGVyQ3J5cHRvLCBQcm92aWRlclN0b3JhZ2UsIFJlcXVpcmVkUHJvcGVydHlFcnJvciwgUnNhT2FlcFByb3ZpZGVyLCBSc2FQcm92aWRlciwgUnNhUHNzUHJvdmlkZXIsIFJzYVNzYVByb3ZpZGVyLCBTaGFrZTEyOFByb3ZpZGVyLCBTaGFrZTI1NlByb3ZpZGVyLCBTaGFrZVByb3ZpZGVyLCBTdWJ0bGVDcnlwdG8sIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXJyb3IsIGluZGV4JDEgYXMgYXNuMSwgaXNKV0ssIGluZGV4IGFzIGpzb24gfTtcbiIsICIvKiFcbiBDb3B5cmlnaHQgKGMpIFBlY3VsaWFyIFZlbnR1cmVzLCBMTENcbiovXG5cbmltcG9ydCAqIGFzIGNvcmUgZnJvbSAnd2ViY3J5cHRvLWNvcmUnO1xuaW1wb3J0IHsgQnVmZmVyU291cmNlQ29udmVydGVyIGFzIEJ1ZmZlclNvdXJjZUNvbnZlcnRlciQxIH0gZnJvbSAnd2ViY3J5cHRvLWNvcmUnO1xuZXhwb3J0IHsgQ3J5cHRvS2V5IH0gZnJvbSAnd2ViY3J5cHRvLWNvcmUnO1xuaW1wb3J0ICogYXMgY3J5cHRvIGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgY3J5cHRvX19kZWZhdWx0IGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgKiBhcyBwcm9jZXNzIGZyb20gJ3Byb2Nlc3MnO1xuaW1wb3J0IHsgX19kZWNvcmF0ZSB9IGZyb20gJ3RzbGliJztcbmltcG9ydCB7IEpzb25Qcm9wLCBKc29uUHJvcFR5cGVzLCBKc29uU2VyaWFsaXplciwgSnNvblBhcnNlciB9IGZyb20gJ0BwZWN1bGlhci9qc29uLXNjaGVtYSc7XG5pbXBvcnQgeyBDb252ZXJ0LCBCdWZmZXJTb3VyY2VDb252ZXJ0ZXIgfSBmcm9tICdwdnRzdXRpbHMnO1xuaW1wb3J0IHsgQXNuUGFyc2VyLCBBc25TZXJpYWxpemVyIH0gZnJvbSAnQHBlY3VsaWFyL2FzbjEtc2NoZW1hJztcblxuY29uc3QgSnNvbkJhc2U2NFVybENvbnZlcnRlciA9IHtcbiAgICBmcm9tSlNPTjogKHZhbHVlKSA9PiBCdWZmZXIuZnJvbShDb252ZXJ0LkZyb21CYXNlNjRVcmwodmFsdWUpKSxcbiAgICB0b0pTT046ICh2YWx1ZSkgPT4gQ29udmVydC5Ub0Jhc2U2NFVybCh2YWx1ZSksXG59O1xuXG5jbGFzcyBDcnlwdG9LZXkgZXh0ZW5kcyBjb3JlLkNyeXB0b0tleSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuZGF0YSA9IEJ1ZmZlci5hbGxvYygwKTtcbiAgICAgICAgdGhpcy5hbGdvcml0aG0gPSB7IG5hbWU6IFwiXCIgfTtcbiAgICAgICAgdGhpcy5leHRyYWN0YWJsZSA9IGZhbHNlO1xuICAgICAgICB0aGlzLnR5cGUgPSBcInNlY3JldFwiO1xuICAgICAgICB0aGlzLnVzYWdlcyA9IFtdO1xuICAgICAgICB0aGlzLmt0eSA9IFwib2N0XCI7XG4gICAgICAgIHRoaXMuYWxnID0gXCJcIjtcbiAgICB9XG59XG5fX2RlY29yYXRlKFtcbiAgICBKc29uUHJvcCh7IG5hbWU6IFwiZXh0XCIsIHR5cGU6IEpzb25Qcm9wVHlwZXMuQm9vbGVhbiwgb3B0aW9uYWw6IHRydWUgfSlcbl0sIENyeXB0b0tleS5wcm90b3R5cGUsIFwiZXh0cmFjdGFibGVcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIEpzb25Qcm9wKHsgbmFtZTogXCJrZXlfb3BzXCIsIHR5cGU6IEpzb25Qcm9wVHlwZXMuU3RyaW5nLCByZXBlYXRlZDogdHJ1ZSwgb3B0aW9uYWw6IHRydWUgfSlcbl0sIENyeXB0b0tleS5wcm90b3R5cGUsIFwidXNhZ2VzXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBKc29uUHJvcCh7IHR5cGU6IEpzb25Qcm9wVHlwZXMuU3RyaW5nIH0pXG5dLCBDcnlwdG9LZXkucHJvdG90eXBlLCBcImt0eVwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgSnNvblByb3AoeyB0eXBlOiBKc29uUHJvcFR5cGVzLlN0cmluZywgb3B0aW9uYWw6IHRydWUgfSlcbl0sIENyeXB0b0tleS5wcm90b3R5cGUsIFwiYWxnXCIsIHZvaWQgMCk7XG5cbmNsYXNzIFN5bW1ldHJpY0tleSBleHRlbmRzIENyeXB0b0tleSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMua3R5ID0gXCJvY3RcIjtcbiAgICAgICAgdGhpcy50eXBlID0gXCJzZWNyZXRcIjtcbiAgICB9XG59XG5cbmNsYXNzIEFzeW1tZXRyaWNLZXkgZXh0ZW5kcyBDcnlwdG9LZXkge1xufVxuXG5jbGFzcyBBZXNDcnlwdG9LZXkgZXh0ZW5kcyBTeW1tZXRyaWNLZXkge1xuICAgIGdldCBhbGcoKSB7XG4gICAgICAgIHN3aXRjaCAodGhpcy5hbGdvcml0aG0ubmFtZS50b1VwcGVyQ2FzZSgpKSB7XG4gICAgICAgICAgICBjYXNlIFwiQUVTLUNCQ1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgQSR7dGhpcy5hbGdvcml0aG0ubGVuZ3RofUNCQ2A7XG4gICAgICAgICAgICBjYXNlIFwiQUVTLUNUUlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgQSR7dGhpcy5hbGdvcml0aG0ubGVuZ3RofUNUUmA7XG4gICAgICAgICAgICBjYXNlIFwiQUVTLUdDTVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgQSR7dGhpcy5hbGdvcml0aG0ubGVuZ3RofUdDTWA7XG4gICAgICAgICAgICBjYXNlIFwiQUVTLUtXXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBBJHt0aGlzLmFsZ29yaXRobS5sZW5ndGh9S1dgO1xuICAgICAgICAgICAgY2FzZSBcIkFFUy1DTUFDXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBBJHt0aGlzLmFsZ29yaXRobS5sZW5ndGh9Q01BQ2A7XG4gICAgICAgICAgICBjYXNlIFwiQUVTLUVDQlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgQSR7dGhpcy5hbGdvcml0aG0ubGVuZ3RofUVDQmA7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBjb3JlLkFsZ29yaXRobUVycm9yKFwiVW5zdXBwb3J0ZWQgYWxnb3JpdGhtIG5hbWVcIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc2V0IGFsZyh2YWx1ZSkge1xuICAgIH1cbn1cbl9fZGVjb3JhdGUoW1xuICAgIEpzb25Qcm9wKHsgbmFtZTogXCJrXCIsIGNvbnZlcnRlcjogSnNvbkJhc2U2NFVybENvbnZlcnRlciB9KVxuXSwgQWVzQ3J5cHRvS2V5LnByb3RvdHlwZSwgXCJkYXRhXCIsIHZvaWQgMCk7XG5cbmNsYXNzIEFlc0NyeXB0byB7XG4gICAgc3RhdGljIGFzeW5jIGdlbmVyYXRlS2V5KGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCBrZXkgPSBuZXcgQWVzQ3J5cHRvS2V5KCk7XG4gICAgICAgIGtleS5hbGdvcml0aG0gPSBhbGdvcml0aG07XG4gICAgICAgIGtleS5leHRyYWN0YWJsZSA9IGV4dHJhY3RhYmxlO1xuICAgICAgICBrZXkudXNhZ2VzID0ga2V5VXNhZ2VzO1xuICAgICAgICBrZXkuZGF0YSA9IGNyeXB0b19fZGVmYXVsdC5yYW5kb21CeXRlcyhhbGdvcml0aG0ubGVuZ3RoID4+IDMpO1xuICAgICAgICByZXR1cm4ga2V5O1xuICAgIH1cbiAgICBzdGF0aWMgYXN5bmMgZXhwb3J0S2V5KGZvcm1hdCwga2V5KSB7XG4gICAgICAgIGlmICghKGtleSBpbnN0YW5jZW9mIEFlc0NyeXB0b0tleSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImtleTogSXMgbm90IEFlc0NyeXB0b0tleVwiKTtcbiAgICAgICAgfVxuICAgICAgICBzd2l0Y2ggKGZvcm1hdC50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgICAgICBjYXNlIFwiandrXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIEpzb25TZXJpYWxpemVyLnRvSlNPTihrZXkpO1xuICAgICAgICAgICAgY2FzZSBcInJhd1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShrZXkuZGF0YSkuYnVmZmVyO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgY29yZS5PcGVyYXRpb25FcnJvcihcImZvcm1hdDogTXVzdCBiZSAnandrJyBvciAncmF3J1wiKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzdGF0aWMgYXN5bmMgaW1wb3J0S2V5KGZvcm1hdCwga2V5RGF0YSwgYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKSB7XG4gICAgICAgIGxldCBrZXk7XG4gICAgICAgIHN3aXRjaCAoZm9ybWF0LnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICAgIGNhc2UgXCJqd2tcIjpcbiAgICAgICAgICAgICAgICBrZXkgPSBKc29uUGFyc2VyLmZyb21KU09OKGtleURhdGEsIHsgdGFyZ2V0U2NoZW1hOiBBZXNDcnlwdG9LZXkgfSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwicmF3XCI6XG4gICAgICAgICAgICAgICAga2V5ID0gbmV3IEFlc0NyeXB0b0tleSgpO1xuICAgICAgICAgICAgICAgIGtleS5kYXRhID0gQnVmZmVyLmZyb20oa2V5RGF0YSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBjb3JlLk9wZXJhdGlvbkVycm9yKFwiZm9ybWF0OiBNdXN0IGJlICdqd2snIG9yICdyYXcnXCIpO1xuICAgICAgICB9XG4gICAgICAgIGtleS5hbGdvcml0aG0gPSBhbGdvcml0aG07XG4gICAgICAgIGtleS5hbGdvcml0aG0ubGVuZ3RoID0ga2V5LmRhdGEubGVuZ3RoIDw8IDM7XG4gICAgICAgIGtleS5leHRyYWN0YWJsZSA9IGV4dHJhY3RhYmxlO1xuICAgICAgICBrZXkudXNhZ2VzID0ga2V5VXNhZ2VzO1xuICAgICAgICBzd2l0Y2ggKGtleS5hbGdvcml0aG0ubGVuZ3RoKSB7XG4gICAgICAgICAgICBjYXNlIDEyODpcbiAgICAgICAgICAgIGNhc2UgMTkyOlxuICAgICAgICAgICAgY2FzZSAyNTY6XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBjb3JlLk9wZXJhdGlvbkVycm9yKFwia2V5RGF0YTogSXMgd3Jvbmcga2V5IGxlbmd0aFwiKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ga2V5O1xuICAgIH1cbiAgICBzdGF0aWMgYXN5bmMgZW5jcnlwdChhbGdvcml0aG0sIGtleSwgZGF0YSkge1xuICAgICAgICBzd2l0Y2ggKGFsZ29yaXRobS5uYW1lLnRvVXBwZXJDYXNlKCkpIHtcbiAgICAgICAgICAgIGNhc2UgXCJBRVMtQ0JDXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW5jcnlwdEFlc0NCQyhhbGdvcml0aG0sIGtleSwgQnVmZmVyLmZyb20oZGF0YSkpO1xuICAgICAgICAgICAgY2FzZSBcIkFFUy1DVFJcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lbmNyeXB0QWVzQ1RSKGFsZ29yaXRobSwga2V5LCBCdWZmZXIuZnJvbShkYXRhKSk7XG4gICAgICAgICAgICBjYXNlIFwiQUVTLUdDTVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVuY3J5cHRBZXNHQ00oYWxnb3JpdGhtLCBrZXksIEJ1ZmZlci5mcm9tKGRhdGEpKTtcbiAgICAgICAgICAgIGNhc2UgXCJBRVMtS1dcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lbmNyeXB0QWVzS1coYWxnb3JpdGhtLCBrZXksIEJ1ZmZlci5mcm9tKGRhdGEpKTtcbiAgICAgICAgICAgIGNhc2UgXCJBRVMtRUNCXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW5jcnlwdEFlc0VDQihhbGdvcml0aG0sIGtleSwgQnVmZmVyLmZyb20oZGF0YSkpO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgY29yZS5PcGVyYXRpb25FcnJvcihcImFsZ29yaXRobTogSXMgbm90IHJlY29nbml6ZWRcIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIGFzeW5jIGRlY3J5cHQoYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgaWYgKCEoa2V5IGluc3RhbmNlb2YgQWVzQ3J5cHRvS2V5KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwia2V5OiBJcyBub3QgQWVzQ3J5cHRvS2V5XCIpO1xuICAgICAgICB9XG4gICAgICAgIHN3aXRjaCAoYWxnb3JpdGhtLm5hbWUudG9VcHBlckNhc2UoKSkge1xuICAgICAgICAgICAgY2FzZSBcIkFFUy1DQkNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5kZWNyeXB0QWVzQ0JDKGFsZ29yaXRobSwga2V5LCBCdWZmZXIuZnJvbShkYXRhKSk7XG4gICAgICAgICAgICBjYXNlIFwiQUVTLUNUUlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmRlY3J5cHRBZXNDVFIoYWxnb3JpdGhtLCBrZXksIEJ1ZmZlci5mcm9tKGRhdGEpKTtcbiAgICAgICAgICAgIGNhc2UgXCJBRVMtR0NNXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGVjcnlwdEFlc0dDTShhbGdvcml0aG0sIGtleSwgQnVmZmVyLmZyb20oZGF0YSkpO1xuICAgICAgICAgICAgY2FzZSBcIkFFUy1LV1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmRlY3J5cHRBZXNLVyhhbGdvcml0aG0sIGtleSwgQnVmZmVyLmZyb20oZGF0YSkpO1xuICAgICAgICAgICAgY2FzZSBcIkFFUy1FQ0JcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5kZWNyeXB0QWVzRUNCKGFsZ29yaXRobSwga2V5LCBCdWZmZXIuZnJvbShkYXRhKSk7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBjb3JlLk9wZXJhdGlvbkVycm9yKFwiYWxnb3JpdGhtOiBJcyBub3QgcmVjb2duaXplZFwiKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzdGF0aWMgYXN5bmMgZW5jcnlwdEFlc0NCQyhhbGdvcml0aG0sIGtleSwgZGF0YSkge1xuICAgICAgICBjb25zdCBjaXBoZXIgPSBjcnlwdG9fX2RlZmF1bHQuY3JlYXRlQ2lwaGVyaXYoYGFlcy0ke2tleS5hbGdvcml0aG0ubGVuZ3RofS1jYmNgLCBrZXkuZGF0YSwgbmV3IFVpbnQ4QXJyYXkoYWxnb3JpdGhtLml2KSk7XG4gICAgICAgIGxldCBlbmMgPSBjaXBoZXIudXBkYXRlKGRhdGEpO1xuICAgICAgICBlbmMgPSBCdWZmZXIuY29uY2F0KFtlbmMsIGNpcGhlci5maW5hbCgpXSk7XG4gICAgICAgIGNvbnN0IHJlcyA9IG5ldyBVaW50OEFycmF5KGVuYykuYnVmZmVyO1xuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cbiAgICBzdGF0aWMgYXN5bmMgZGVjcnlwdEFlc0NCQyhhbGdvcml0aG0sIGtleSwgZGF0YSkge1xuICAgICAgICBjb25zdCBkZWNpcGhlciA9IGNyeXB0b19fZGVmYXVsdC5jcmVhdGVEZWNpcGhlcml2KGBhZXMtJHtrZXkuYWxnb3JpdGhtLmxlbmd0aH0tY2JjYCwga2V5LmRhdGEsIG5ldyBVaW50OEFycmF5KGFsZ29yaXRobS5pdikpO1xuICAgICAgICBsZXQgZGVjID0gZGVjaXBoZXIudXBkYXRlKGRhdGEpO1xuICAgICAgICBkZWMgPSBCdWZmZXIuY29uY2F0KFtkZWMsIGRlY2lwaGVyLmZpbmFsKCldKTtcbiAgICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGRlYykuYnVmZmVyO1xuICAgIH1cbiAgICBzdGF0aWMgYXN5bmMgZW5jcnlwdEFlc0NUUihhbGdvcml0aG0sIGtleSwgZGF0YSkge1xuICAgICAgICBjb25zdCBjaXBoZXIgPSBjcnlwdG9fX2RlZmF1bHQuY3JlYXRlQ2lwaGVyaXYoYGFlcy0ke2tleS5hbGdvcml0aG0ubGVuZ3RofS1jdHJgLCBrZXkuZGF0YSwgQnVmZmVyLmZyb20oYWxnb3JpdGhtLmNvdW50ZXIpKTtcbiAgICAgICAgbGV0IGVuYyA9IGNpcGhlci51cGRhdGUoZGF0YSk7XG4gICAgICAgIGVuYyA9IEJ1ZmZlci5jb25jYXQoW2VuYywgY2lwaGVyLmZpbmFsKCldKTtcbiAgICAgICAgY29uc3QgcmVzID0gbmV3IFVpbnQ4QXJyYXkoZW5jKS5idWZmZXI7XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxuICAgIHN0YXRpYyBhc3luYyBkZWNyeXB0QWVzQ1RSKGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIGNvbnN0IGRlY2lwaGVyID0gY3J5cHRvX19kZWZhdWx0LmNyZWF0ZURlY2lwaGVyaXYoYGFlcy0ke2tleS5hbGdvcml0aG0ubGVuZ3RofS1jdHJgLCBrZXkuZGF0YSwgbmV3IFVpbnQ4QXJyYXkoYWxnb3JpdGhtLmNvdW50ZXIpKTtcbiAgICAgICAgbGV0IGRlYyA9IGRlY2lwaGVyLnVwZGF0ZShkYXRhKTtcbiAgICAgICAgZGVjID0gQnVmZmVyLmNvbmNhdChbZGVjLCBkZWNpcGhlci5maW5hbCgpXSk7XG4gICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShkZWMpLmJ1ZmZlcjtcbiAgICB9XG4gICAgc3RhdGljIGFzeW5jIGVuY3J5cHRBZXNHQ00oYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgY29uc3QgY2lwaGVyID0gY3J5cHRvX19kZWZhdWx0LmNyZWF0ZUNpcGhlcml2KGBhZXMtJHtrZXkuYWxnb3JpdGhtLmxlbmd0aH0tZ2NtYCwga2V5LmRhdGEsIEJ1ZmZlci5mcm9tKGFsZ29yaXRobS5pdiksIHtcbiAgICAgICAgICAgIGF1dGhUYWdMZW5ndGg6IChhbGdvcml0aG0udGFnTGVuZ3RoIHx8IDEyOCkgPj4gMyxcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChhbGdvcml0aG0uYWRkaXRpb25hbERhdGEpIHtcbiAgICAgICAgICAgIGNpcGhlci5zZXRBQUQoQnVmZmVyLmZyb20oYWxnb3JpdGhtLmFkZGl0aW9uYWxEYXRhKSk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGVuYyA9IGNpcGhlci51cGRhdGUoZGF0YSk7XG4gICAgICAgIGVuYyA9IEJ1ZmZlci5jb25jYXQoW2VuYywgY2lwaGVyLmZpbmFsKCksIGNpcGhlci5nZXRBdXRoVGFnKCldKTtcbiAgICAgICAgY29uc3QgcmVzID0gbmV3IFVpbnQ4QXJyYXkoZW5jKS5idWZmZXI7XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxuICAgIHN0YXRpYyBhc3luYyBkZWNyeXB0QWVzR0NNKGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIGNvbnN0IGRlY2lwaGVyID0gY3J5cHRvX19kZWZhdWx0LmNyZWF0ZURlY2lwaGVyaXYoYGFlcy0ke2tleS5hbGdvcml0aG0ubGVuZ3RofS1nY21gLCBrZXkuZGF0YSwgbmV3IFVpbnQ4QXJyYXkoYWxnb3JpdGhtLml2KSk7XG4gICAgICAgIGNvbnN0IHRhZ0xlbmd0aCA9IChhbGdvcml0aG0udGFnTGVuZ3RoIHx8IDEyOCkgPj4gMztcbiAgICAgICAgY29uc3QgZW5jID0gZGF0YS5zbGljZSgwLCBkYXRhLmxlbmd0aCAtIHRhZ0xlbmd0aCk7XG4gICAgICAgIGNvbnN0IHRhZyA9IGRhdGEuc2xpY2UoZGF0YS5sZW5ndGggLSB0YWdMZW5ndGgpO1xuICAgICAgICBpZiAoYWxnb3JpdGhtLmFkZGl0aW9uYWxEYXRhKSB7XG4gICAgICAgICAgICBkZWNpcGhlci5zZXRBQUQoQnVmZmVyLmZyb20oYWxnb3JpdGhtLmFkZGl0aW9uYWxEYXRhKSk7XG4gICAgICAgIH1cbiAgICAgICAgZGVjaXBoZXIuc2V0QXV0aFRhZyh0YWcpO1xuICAgICAgICBsZXQgZGVjID0gZGVjaXBoZXIudXBkYXRlKGVuYyk7XG4gICAgICAgIGRlYyA9IEJ1ZmZlci5jb25jYXQoW2RlYywgZGVjaXBoZXIuZmluYWwoKV0pO1xuICAgICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoZGVjKS5idWZmZXI7XG4gICAgfVxuICAgIHN0YXRpYyBhc3luYyBlbmNyeXB0QWVzS1coYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgY29uc3QgY2lwaGVyID0gY3J5cHRvX19kZWZhdWx0LmNyZWF0ZUNpcGhlcml2KGBpZC1hZXMke2tleS5hbGdvcml0aG0ubGVuZ3RofS13cmFwYCwga2V5LmRhdGEsIHRoaXMuQUVTX0tXX0lWKTtcbiAgICAgICAgbGV0IGVuYyA9IGNpcGhlci51cGRhdGUoZGF0YSk7XG4gICAgICAgIGVuYyA9IEJ1ZmZlci5jb25jYXQoW2VuYywgY2lwaGVyLmZpbmFsKCldKTtcbiAgICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGVuYykuYnVmZmVyO1xuICAgIH1cbiAgICBzdGF0aWMgYXN5bmMgZGVjcnlwdEFlc0tXKGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIGNvbnN0IGRlY2lwaGVyID0gY3J5cHRvX19kZWZhdWx0LmNyZWF0ZURlY2lwaGVyaXYoYGlkLWFlcyR7a2V5LmFsZ29yaXRobS5sZW5ndGh9LXdyYXBgLCBrZXkuZGF0YSwgdGhpcy5BRVNfS1dfSVYpO1xuICAgICAgICBsZXQgZGVjID0gZGVjaXBoZXIudXBkYXRlKGRhdGEpO1xuICAgICAgICBkZWMgPSBCdWZmZXIuY29uY2F0KFtkZWMsIGRlY2lwaGVyLmZpbmFsKCldKTtcbiAgICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGRlYykuYnVmZmVyO1xuICAgIH1cbiAgICBzdGF0aWMgYXN5bmMgZW5jcnlwdEFlc0VDQihhbGdvcml0aG0sIGtleSwgZGF0YSkge1xuICAgICAgICBjb25zdCBjaXBoZXIgPSBjcnlwdG9fX2RlZmF1bHQuY3JlYXRlQ2lwaGVyaXYoYGFlcy0ke2tleS5hbGdvcml0aG0ubGVuZ3RofS1lY2JgLCBrZXkuZGF0YSwgbmV3IFVpbnQ4QXJyYXkoMCkpO1xuICAgICAgICBsZXQgZW5jID0gY2lwaGVyLnVwZGF0ZShkYXRhKTtcbiAgICAgICAgZW5jID0gQnVmZmVyLmNvbmNhdChbZW5jLCBjaXBoZXIuZmluYWwoKV0pO1xuICAgICAgICBjb25zdCByZXMgPSBuZXcgVWludDhBcnJheShlbmMpLmJ1ZmZlcjtcbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG4gICAgc3RhdGljIGFzeW5jIGRlY3J5cHRBZXNFQ0IoYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgY29uc3QgZGVjaXBoZXIgPSBjcnlwdG9fX2RlZmF1bHQuY3JlYXRlRGVjaXBoZXJpdihgYWVzLSR7a2V5LmFsZ29yaXRobS5sZW5ndGh9LWVjYmAsIGtleS5kYXRhLCBuZXcgVWludDhBcnJheSgwKSk7XG4gICAgICAgIGxldCBkZWMgPSBkZWNpcGhlci51cGRhdGUoZGF0YSk7XG4gICAgICAgIGRlYyA9IEJ1ZmZlci5jb25jYXQoW2RlYywgZGVjaXBoZXIuZmluYWwoKV0pO1xuICAgICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoZGVjKS5idWZmZXI7XG4gICAgfVxufVxuQWVzQ3J5cHRvLkFFU19LV19JViA9IEJ1ZmZlci5mcm9tKFwiQTZBNkE2QTZBNkE2QTZBNlwiLCBcImhleFwiKTtcblxuY29uc3Qga2V5U3RvcmFnZSA9IG5ldyBXZWFrTWFwKCk7XG5mdW5jdGlvbiBnZXRDcnlwdG9LZXkoa2V5KSB7XG4gICAgY29uc3QgcmVzID0ga2V5U3RvcmFnZS5nZXQoa2V5KTtcbiAgICBpZiAoIXJlcykge1xuICAgICAgICB0aHJvdyBuZXcgY29yZS5PcGVyYXRpb25FcnJvcihcIkNhbm5vdCBnZXQgQ3J5cHRvS2V5IGZyb20gc2VjdXJlIHN0b3JhZ2VcIik7XG4gICAgfVxuICAgIHJldHVybiByZXM7XG59XG5mdW5jdGlvbiBzZXRDcnlwdG9LZXkodmFsdWUpIHtcbiAgICBjb25zdCBrZXkgPSBjb3JlLkNyeXB0b0tleS5jcmVhdGUodmFsdWUuYWxnb3JpdGhtLCB2YWx1ZS50eXBlLCB2YWx1ZS5leHRyYWN0YWJsZSwgdmFsdWUudXNhZ2VzKTtcbiAgICBPYmplY3QuZnJlZXplKGtleSk7XG4gICAga2V5U3RvcmFnZS5zZXQoa2V5LCB2YWx1ZSk7XG4gICAgcmV0dXJuIGtleTtcbn1cblxuY2xhc3MgQWVzQ2JjUHJvdmlkZXIgZXh0ZW5kcyBjb3JlLkFlc0NiY1Byb3ZpZGVyIHtcbiAgICBhc3luYyBvbkdlbmVyYXRlS2V5KGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCBrZXkgPSBhd2FpdCBBZXNDcnlwdG8uZ2VuZXJhdGVLZXkoe1xuICAgICAgICAgICAgbmFtZTogdGhpcy5uYW1lLFxuICAgICAgICAgICAgbGVuZ3RoOiBhbGdvcml0aG0ubGVuZ3RoLFxuICAgICAgICB9LCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgcmV0dXJuIHNldENyeXB0b0tleShrZXkpO1xuICAgIH1cbiAgICBhc3luYyBvbkVuY3J5cHQoYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgcmV0dXJuIEFlc0NyeXB0by5lbmNyeXB0KGFsZ29yaXRobSwgZ2V0Q3J5cHRvS2V5KGtleSksIG5ldyBVaW50OEFycmF5KGRhdGEpKTtcbiAgICB9XG4gICAgYXN5bmMgb25EZWNyeXB0KGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIHJldHVybiBBZXNDcnlwdG8uZGVjcnlwdChhbGdvcml0aG0sIGdldENyeXB0b0tleShrZXkpLCBuZXcgVWludDhBcnJheShkYXRhKSk7XG4gICAgfVxuICAgIGFzeW5jIG9uRXhwb3J0S2V5KGZvcm1hdCwga2V5KSB7XG4gICAgICAgIHJldHVybiBBZXNDcnlwdG8uZXhwb3J0S2V5KGZvcm1hdCwgZ2V0Q3J5cHRvS2V5KGtleSkpO1xuICAgIH1cbiAgICBhc3luYyBvbkltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCBrZXkgPSBhd2FpdCBBZXNDcnlwdG8uaW1wb3J0S2V5KGZvcm1hdCwga2V5RGF0YSwgeyBuYW1lOiBhbGdvcml0aG0ubmFtZSB9LCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgcmV0dXJuIHNldENyeXB0b0tleShrZXkpO1xuICAgIH1cbiAgICBjaGVja0NyeXB0b0tleShrZXksIGtleVVzYWdlKSB7XG4gICAgICAgIHN1cGVyLmNoZWNrQ3J5cHRvS2V5KGtleSwga2V5VXNhZ2UpO1xuICAgICAgICBpZiAoIShnZXRDcnlwdG9LZXkoa2V5KSBpbnN0YW5jZW9mIEFlc0NyeXB0b0tleSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJrZXk6IElzIG5vdCBhIEFlc0NyeXB0b0tleVwiKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuY29uc3QgemVybyA9IEJ1ZmZlci5mcm9tKFswLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwXSk7XG5jb25zdCByYiA9IEJ1ZmZlci5mcm9tKFswLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAxMzVdKTtcbmNvbnN0IGJsb2NrU2l6ZSA9IDE2O1xuZnVuY3Rpb24gYml0U2hpZnRMZWZ0KGJ1ZmZlcikge1xuICAgIGNvbnN0IHNoaWZ0ZWQgPSBCdWZmZXIuYWxsb2MoYnVmZmVyLmxlbmd0aCk7XG4gICAgY29uc3QgbGFzdCA9IGJ1ZmZlci5sZW5ndGggLSAxO1xuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBsYXN0OyBpbmRleCsrKSB7XG4gICAgICAgIHNoaWZ0ZWRbaW5kZXhdID0gYnVmZmVyW2luZGV4XSA8PCAxO1xuICAgICAgICBpZiAoYnVmZmVyW2luZGV4ICsgMV0gJiAweDgwKSB7XG4gICAgICAgICAgICBzaGlmdGVkW2luZGV4XSArPSAweDAxO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNoaWZ0ZWRbbGFzdF0gPSBidWZmZXJbbGFzdF0gPDwgMTtcbiAgICByZXR1cm4gc2hpZnRlZDtcbn1cbmZ1bmN0aW9uIHhvcihhLCBiKSB7XG4gICAgY29uc3QgbGVuZ3RoID0gTWF0aC5taW4oYS5sZW5ndGgsIGIubGVuZ3RoKTtcbiAgICBjb25zdCBvdXRwdXQgPSBCdWZmZXIuYWxsb2MobGVuZ3RoKTtcbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgIG91dHB1dFtpbmRleF0gPSBhW2luZGV4XSBeIGJbaW5kZXhdO1xuICAgIH1cbiAgICByZXR1cm4gb3V0cHV0O1xufVxuZnVuY3Rpb24gYWVzKGtleSwgbWVzc2FnZSkge1xuICAgIGNvbnN0IGNpcGhlciA9IGNyeXB0by5jcmVhdGVDaXBoZXJpdihgYWVzJHtrZXkubGVuZ3RoIDw8IDN9YCwga2V5LCB6ZXJvKTtcbiAgICBjb25zdCByZXN1bHQgPSBjaXBoZXIudXBkYXRlKG1lc3NhZ2UpO1xuICAgIGNpcGhlci5maW5hbCgpO1xuICAgIHJldHVybiByZXN1bHQ7XG59XG5mdW5jdGlvbiBnZXRNZXNzYWdlQmxvY2sobWVzc2FnZSwgYmxvY2tJbmRleCkge1xuICAgIGNvbnN0IGJsb2NrID0gQnVmZmVyLmFsbG9jKGJsb2NrU2l6ZSk7XG4gICAgY29uc3Qgc3RhcnQgPSBibG9ja0luZGV4ICogYmxvY2tTaXplO1xuICAgIGNvbnN0IGVuZCA9IHN0YXJ0ICsgYmxvY2tTaXplO1xuICAgIG1lc3NhZ2UuY29weShibG9jaywgMCwgc3RhcnQsIGVuZCk7XG4gICAgcmV0dXJuIGJsb2NrO1xufVxuZnVuY3Rpb24gZ2V0UGFkZGVkTWVzc2FnZUJsb2NrKG1lc3NhZ2UsIGJsb2NrSW5kZXgpIHtcbiAgICBjb25zdCBibG9jayA9IEJ1ZmZlci5hbGxvYyhibG9ja1NpemUpO1xuICAgIGNvbnN0IHN0YXJ0ID0gYmxvY2tJbmRleCAqIGJsb2NrU2l6ZTtcbiAgICBjb25zdCBlbmQgPSBtZXNzYWdlLmxlbmd0aDtcbiAgICBibG9jay5maWxsKDApO1xuICAgIG1lc3NhZ2UuY29weShibG9jaywgMCwgc3RhcnQsIGVuZCk7XG4gICAgYmxvY2tbZW5kIC0gc3RhcnRdID0gMHg4MDtcbiAgICByZXR1cm4gYmxvY2s7XG59XG5mdW5jdGlvbiBnZW5lcmF0ZVN1YmtleXMoa2V5KSB7XG4gICAgY29uc3QgbCA9IGFlcyhrZXksIHplcm8pO1xuICAgIGxldCBzdWJrZXkxID0gYml0U2hpZnRMZWZ0KGwpO1xuICAgIGlmIChsWzBdICYgMHg4MCkge1xuICAgICAgICBzdWJrZXkxID0geG9yKHN1YmtleTEsIHJiKTtcbiAgICB9XG4gICAgbGV0IHN1YmtleTIgPSBiaXRTaGlmdExlZnQoc3Via2V5MSk7XG4gICAgaWYgKHN1YmtleTFbMF0gJiAweDgwKSB7XG4gICAgICAgIHN1YmtleTIgPSB4b3Ioc3Via2V5MiwgcmIpO1xuICAgIH1cbiAgICByZXR1cm4geyBzdWJrZXkxLCBzdWJrZXkyIH07XG59XG5mdW5jdGlvbiBhZXNDbWFjKGtleSwgbWVzc2FnZSkge1xuICAgIGNvbnN0IHN1YmtleXMgPSBnZW5lcmF0ZVN1YmtleXMoa2V5KTtcbiAgICBsZXQgYmxvY2tDb3VudCA9IE1hdGguY2VpbChtZXNzYWdlLmxlbmd0aCAvIGJsb2NrU2l6ZSk7XG4gICAgbGV0IGxhc3RCbG9ja0NvbXBsZXRlRmxhZztcbiAgICBsZXQgbGFzdEJsb2NrO1xuICAgIGlmIChibG9ja0NvdW50ID09PSAwKSB7XG4gICAgICAgIGJsb2NrQ291bnQgPSAxO1xuICAgICAgICBsYXN0QmxvY2tDb21wbGV0ZUZsYWcgPSBmYWxzZTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGxhc3RCbG9ja0NvbXBsZXRlRmxhZyA9IChtZXNzYWdlLmxlbmd0aCAlIGJsb2NrU2l6ZSA9PT0gMCk7XG4gICAgfVxuICAgIGNvbnN0IGxhc3RCbG9ja0luZGV4ID0gYmxvY2tDb3VudCAtIDE7XG4gICAgaWYgKGxhc3RCbG9ja0NvbXBsZXRlRmxhZykge1xuICAgICAgICBsYXN0QmxvY2sgPSB4b3IoZ2V0TWVzc2FnZUJsb2NrKG1lc3NhZ2UsIGxhc3RCbG9ja0luZGV4KSwgc3Via2V5cy5zdWJrZXkxKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGxhc3RCbG9jayA9IHhvcihnZXRQYWRkZWRNZXNzYWdlQmxvY2sobWVzc2FnZSwgbGFzdEJsb2NrSW5kZXgpLCBzdWJrZXlzLnN1YmtleTIpO1xuICAgIH1cbiAgICBsZXQgeCA9IHplcm87XG4gICAgbGV0IHk7XG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGxhc3RCbG9ja0luZGV4OyBpbmRleCsrKSB7XG4gICAgICAgIHkgPSB4b3IoeCwgZ2V0TWVzc2FnZUJsb2NrKG1lc3NhZ2UsIGluZGV4KSk7XG4gICAgICAgIHggPSBhZXMoa2V5LCB5KTtcbiAgICB9XG4gICAgeSA9IHhvcihsYXN0QmxvY2ssIHgpO1xuICAgIHJldHVybiBhZXMoa2V5LCB5KTtcbn1cbmNsYXNzIEFlc0NtYWNQcm92aWRlciBleHRlbmRzIGNvcmUuQWVzQ21hY1Byb3ZpZGVyIHtcbiAgICBhc3luYyBvbkdlbmVyYXRlS2V5KGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCBrZXkgPSBhd2FpdCBBZXNDcnlwdG8uZ2VuZXJhdGVLZXkoe1xuICAgICAgICAgICAgbmFtZTogdGhpcy5uYW1lLFxuICAgICAgICAgICAgbGVuZ3RoOiBhbGdvcml0aG0ubGVuZ3RoLFxuICAgICAgICB9LCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgcmV0dXJuIHNldENyeXB0b0tleShrZXkpO1xuICAgIH1cbiAgICBhc3luYyBvblNpZ24oYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYWVzQ21hYyhnZXRDcnlwdG9LZXkoa2V5KS5kYXRhLCBCdWZmZXIuZnJvbShkYXRhKSk7XG4gICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShyZXN1bHQpLmJ1ZmZlcjtcbiAgICB9XG4gICAgYXN5bmMgb25WZXJpZnkoYWxnb3JpdGhtLCBrZXksIHNpZ25hdHVyZSwgZGF0YSkge1xuICAgICAgICBjb25zdCBzaWduYXR1cmUyID0gYXdhaXQgdGhpcy5zaWduKGFsZ29yaXRobSwga2V5LCBkYXRhKTtcbiAgICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKHNpZ25hdHVyZSkuY29tcGFyZShCdWZmZXIuZnJvbShzaWduYXR1cmUyKSkgPT09IDA7XG4gICAgfVxuICAgIGFzeW5jIG9uRXhwb3J0S2V5KGZvcm1hdCwga2V5KSB7XG4gICAgICAgIHJldHVybiBBZXNDcnlwdG8uZXhwb3J0S2V5KGZvcm1hdCwgZ2V0Q3J5cHRvS2V5KGtleSkpO1xuICAgIH1cbiAgICBhc3luYyBvbkltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBBZXNDcnlwdG8uaW1wb3J0S2V5KGZvcm1hdCwga2V5RGF0YSwgeyBuYW1lOiBhbGdvcml0aG0ubmFtZSB9LCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgcmV0dXJuIHNldENyeXB0b0tleShyZXMpO1xuICAgIH1cbiAgICBjaGVja0NyeXB0b0tleShrZXksIGtleVVzYWdlKSB7XG4gICAgICAgIHN1cGVyLmNoZWNrQ3J5cHRvS2V5KGtleSwga2V5VXNhZ2UpO1xuICAgICAgICBpZiAoIShnZXRDcnlwdG9LZXkoa2V5KSBpbnN0YW5jZW9mIEFlc0NyeXB0b0tleSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJrZXk6IElzIG5vdCBhIEFlc0NyeXB0b0tleVwiKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuY2xhc3MgQWVzQ3RyUHJvdmlkZXIgZXh0ZW5kcyBjb3JlLkFlc0N0clByb3ZpZGVyIHtcbiAgICBhc3luYyBvbkdlbmVyYXRlS2V5KGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCBrZXkgPSBhd2FpdCBBZXNDcnlwdG8uZ2VuZXJhdGVLZXkoe1xuICAgICAgICAgICAgbmFtZTogdGhpcy5uYW1lLFxuICAgICAgICAgICAgbGVuZ3RoOiBhbGdvcml0aG0ubGVuZ3RoLFxuICAgICAgICB9LCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgcmV0dXJuIHNldENyeXB0b0tleShrZXkpO1xuICAgIH1cbiAgICBhc3luYyBvbkVuY3J5cHQoYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgcmV0dXJuIEFlc0NyeXB0by5lbmNyeXB0KGFsZ29yaXRobSwgZ2V0Q3J5cHRvS2V5KGtleSksIG5ldyBVaW50OEFycmF5KGRhdGEpKTtcbiAgICB9XG4gICAgYXN5bmMgb25EZWNyeXB0KGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIHJldHVybiBBZXNDcnlwdG8uZGVjcnlwdChhbGdvcml0aG0sIGdldENyeXB0b0tleShrZXkpLCBuZXcgVWludDhBcnJheShkYXRhKSk7XG4gICAgfVxuICAgIGFzeW5jIG9uRXhwb3J0S2V5KGZvcm1hdCwga2V5KSB7XG4gICAgICAgIHJldHVybiBBZXNDcnlwdG8uZXhwb3J0S2V5KGZvcm1hdCwgZ2V0Q3J5cHRvS2V5KGtleSkpO1xuICAgIH1cbiAgICBhc3luYyBvbkltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBBZXNDcnlwdG8uaW1wb3J0S2V5KGZvcm1hdCwga2V5RGF0YSwgeyBuYW1lOiBhbGdvcml0aG0ubmFtZSB9LCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgcmV0dXJuIHNldENyeXB0b0tleShyZXMpO1xuICAgIH1cbiAgICBjaGVja0NyeXB0b0tleShrZXksIGtleVVzYWdlKSB7XG4gICAgICAgIHN1cGVyLmNoZWNrQ3J5cHRvS2V5KGtleSwga2V5VXNhZ2UpO1xuICAgICAgICBpZiAoIShnZXRDcnlwdG9LZXkoa2V5KSBpbnN0YW5jZW9mIEFlc0NyeXB0b0tleSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJrZXk6IElzIG5vdCBhIEFlc0NyeXB0b0tleVwiKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuY2xhc3MgQWVzR2NtUHJvdmlkZXIgZXh0ZW5kcyBjb3JlLkFlc0djbVByb3ZpZGVyIHtcbiAgICBhc3luYyBvbkdlbmVyYXRlS2V5KGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCBrZXkgPSBhd2FpdCBBZXNDcnlwdG8uZ2VuZXJhdGVLZXkoe1xuICAgICAgICAgICAgbmFtZTogdGhpcy5uYW1lLFxuICAgICAgICAgICAgbGVuZ3RoOiBhbGdvcml0aG0ubGVuZ3RoLFxuICAgICAgICB9LCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgcmV0dXJuIHNldENyeXB0b0tleShrZXkpO1xuICAgIH1cbiAgICBhc3luYyBvbkVuY3J5cHQoYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgcmV0dXJuIEFlc0NyeXB0by5lbmNyeXB0KGFsZ29yaXRobSwgZ2V0Q3J5cHRvS2V5KGtleSksIG5ldyBVaW50OEFycmF5KGRhdGEpKTtcbiAgICB9XG4gICAgYXN5bmMgb25EZWNyeXB0KGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIHJldHVybiBBZXNDcnlwdG8uZGVjcnlwdChhbGdvcml0aG0sIGdldENyeXB0b0tleShrZXkpLCBuZXcgVWludDhBcnJheShkYXRhKSk7XG4gICAgfVxuICAgIGFzeW5jIG9uRXhwb3J0S2V5KGZvcm1hdCwga2V5KSB7XG4gICAgICAgIHJldHVybiBBZXNDcnlwdG8uZXhwb3J0S2V5KGZvcm1hdCwgZ2V0Q3J5cHRvS2V5KGtleSkpO1xuICAgIH1cbiAgICBhc3luYyBvbkltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBBZXNDcnlwdG8uaW1wb3J0S2V5KGZvcm1hdCwga2V5RGF0YSwgeyBuYW1lOiBhbGdvcml0aG0ubmFtZSB9LCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgcmV0dXJuIHNldENyeXB0b0tleShyZXMpO1xuICAgIH1cbiAgICBjaGVja0NyeXB0b0tleShrZXksIGtleVVzYWdlKSB7XG4gICAgICAgIHN1cGVyLmNoZWNrQ3J5cHRvS2V5KGtleSwga2V5VXNhZ2UpO1xuICAgICAgICBpZiAoIShnZXRDcnlwdG9LZXkoa2V5KSBpbnN0YW5jZW9mIEFlc0NyeXB0b0tleSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJrZXk6IElzIG5vdCBhIEFlc0NyeXB0b0tleVwiKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuY2xhc3MgQWVzS3dQcm92aWRlciBleHRlbmRzIGNvcmUuQWVzS3dQcm92aWRlciB7XG4gICAgYXN5bmMgb25HZW5lcmF0ZUtleShhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgQWVzQ3J5cHRvLmdlbmVyYXRlS2V5KHtcbiAgICAgICAgICAgIG5hbWU6IHRoaXMubmFtZSxcbiAgICAgICAgICAgIGxlbmd0aDogYWxnb3JpdGhtLmxlbmd0aCxcbiAgICAgICAgfSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcyk7XG4gICAgICAgIHJldHVybiBzZXRDcnlwdG9LZXkocmVzKTtcbiAgICB9XG4gICAgYXN5bmMgb25FeHBvcnRLZXkoZm9ybWF0LCBrZXkpIHtcbiAgICAgICAgcmV0dXJuIEFlc0NyeXB0by5leHBvcnRLZXkoZm9ybWF0LCBnZXRDcnlwdG9LZXkoa2V5KSk7XG4gICAgfVxuICAgIGFzeW5jIG9uSW1wb3J0S2V5KGZvcm1hdCwga2V5RGF0YSwgYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKSB7XG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IEFlc0NyeXB0by5pbXBvcnRLZXkoZm9ybWF0LCBrZXlEYXRhLCB7IG5hbWU6IGFsZ29yaXRobS5uYW1lIH0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpO1xuICAgICAgICByZXR1cm4gc2V0Q3J5cHRvS2V5KHJlcyk7XG4gICAgfVxuICAgIGFzeW5jIG9uRW5jcnlwdChhbGdvcml0aG0sIGtleSwgZGF0YSkge1xuICAgICAgICByZXR1cm4gQWVzQ3J5cHRvLmVuY3J5cHQoYWxnb3JpdGhtLCBnZXRDcnlwdG9LZXkoa2V5KSwgbmV3IFVpbnQ4QXJyYXkoZGF0YSkpO1xuICAgIH1cbiAgICBhc3luYyBvbkRlY3J5cHQoYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgcmV0dXJuIEFlc0NyeXB0by5kZWNyeXB0KGFsZ29yaXRobSwgZ2V0Q3J5cHRvS2V5KGtleSksIG5ldyBVaW50OEFycmF5KGRhdGEpKTtcbiAgICB9XG4gICAgY2hlY2tDcnlwdG9LZXkoa2V5LCBrZXlVc2FnZSkge1xuICAgICAgICBzdXBlci5jaGVja0NyeXB0b0tleShrZXksIGtleVVzYWdlKTtcbiAgICAgICAgaWYgKCEoZ2V0Q3J5cHRvS2V5KGtleSkgaW5zdGFuY2VvZiBBZXNDcnlwdG9LZXkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwia2V5OiBJcyBub3QgYSBBZXNDcnlwdG9LZXlcIik7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmNsYXNzIEFlc0VjYlByb3ZpZGVyIGV4dGVuZHMgY29yZS5BZXNFY2JQcm92aWRlciB7XG4gICAgYXN5bmMgb25HZW5lcmF0ZUtleShhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgY29uc3Qga2V5ID0gYXdhaXQgQWVzQ3J5cHRvLmdlbmVyYXRlS2V5KHtcbiAgICAgICAgICAgIG5hbWU6IHRoaXMubmFtZSxcbiAgICAgICAgICAgIGxlbmd0aDogYWxnb3JpdGhtLmxlbmd0aCxcbiAgICAgICAgfSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcyk7XG4gICAgICAgIHJldHVybiBzZXRDcnlwdG9LZXkoa2V5KTtcbiAgICB9XG4gICAgYXN5bmMgb25FbmNyeXB0KGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIHJldHVybiBBZXNDcnlwdG8uZW5jcnlwdChhbGdvcml0aG0sIGdldENyeXB0b0tleShrZXkpLCBuZXcgVWludDhBcnJheShkYXRhKSk7XG4gICAgfVxuICAgIGFzeW5jIG9uRGVjcnlwdChhbGdvcml0aG0sIGtleSwgZGF0YSkge1xuICAgICAgICByZXR1cm4gQWVzQ3J5cHRvLmRlY3J5cHQoYWxnb3JpdGhtLCBnZXRDcnlwdG9LZXkoa2V5KSwgbmV3IFVpbnQ4QXJyYXkoZGF0YSkpO1xuICAgIH1cbiAgICBhc3luYyBvbkV4cG9ydEtleShmb3JtYXQsIGtleSkge1xuICAgICAgICByZXR1cm4gQWVzQ3J5cHRvLmV4cG9ydEtleShmb3JtYXQsIGdldENyeXB0b0tleShrZXkpKTtcbiAgICB9XG4gICAgYXN5bmMgb25JbXBvcnRLZXkoZm9ybWF0LCBrZXlEYXRhLCBhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgQWVzQ3J5cHRvLmltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIHsgbmFtZTogYWxnb3JpdGhtLm5hbWUgfSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcyk7XG4gICAgICAgIHJldHVybiBzZXRDcnlwdG9LZXkocmVzKTtcbiAgICB9XG4gICAgY2hlY2tDcnlwdG9LZXkoa2V5LCBrZXlVc2FnZSkge1xuICAgICAgICBzdXBlci5jaGVja0NyeXB0b0tleShrZXksIGtleVVzYWdlKTtcbiAgICAgICAgaWYgKCEoZ2V0Q3J5cHRvS2V5KGtleSkgaW5zdGFuY2VvZiBBZXNDcnlwdG9LZXkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwia2V5OiBJcyBub3QgYSBBZXNDcnlwdG9LZXlcIik7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmNsYXNzIERlc0NyeXB0b0tleSBleHRlbmRzIFN5bW1ldHJpY0tleSB7XG4gICAgZ2V0IGFsZygpIHtcbiAgICAgICAgc3dpdGNoICh0aGlzLmFsZ29yaXRobS5uYW1lLnRvVXBwZXJDYXNlKCkpIHtcbiAgICAgICAgICAgIGNhc2UgXCJERVMtQ0JDXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBERVMtQ0JDYDtcbiAgICAgICAgICAgIGNhc2UgXCJERVMtRURFMy1DQkNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYDNERVMtQ0JDYDtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IGNvcmUuQWxnb3JpdGhtRXJyb3IoXCJVbnN1cHBvcnRlZCBhbGdvcml0aG0gbmFtZVwiKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzZXQgYWxnKHZhbHVlKSB7XG4gICAgfVxufVxuX19kZWNvcmF0ZShbXG4gICAgSnNvblByb3AoeyBuYW1lOiBcImtcIiwgY29udmVydGVyOiBKc29uQmFzZTY0VXJsQ29udmVydGVyIH0pXG5dLCBEZXNDcnlwdG9LZXkucHJvdG90eXBlLCBcImRhdGFcIiwgdm9pZCAwKTtcblxuY2xhc3MgRGVzQ3J5cHRvIHtcbiAgICBzdGF0aWMgYXN5bmMgZ2VuZXJhdGVLZXkoYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IG5ldyBEZXNDcnlwdG9LZXkoKTtcbiAgICAgICAga2V5LmFsZ29yaXRobSA9IGFsZ29yaXRobTtcbiAgICAgICAga2V5LmV4dHJhY3RhYmxlID0gZXh0cmFjdGFibGU7XG4gICAgICAgIGtleS51c2FnZXMgPSBrZXlVc2FnZXM7XG4gICAgICAgIGtleS5kYXRhID0gY3J5cHRvX19kZWZhdWx0LnJhbmRvbUJ5dGVzKGFsZ29yaXRobS5sZW5ndGggPj4gMyk7XG4gICAgICAgIHJldHVybiBrZXk7XG4gICAgfVxuICAgIHN0YXRpYyBhc3luYyBleHBvcnRLZXkoZm9ybWF0LCBrZXkpIHtcbiAgICAgICAgc3dpdGNoIChmb3JtYXQudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgY2FzZSBcImp3a1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBKc29uU2VyaWFsaXplci50b0pTT04oa2V5KTtcbiAgICAgICAgICAgIGNhc2UgXCJyYXdcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoa2V5LmRhdGEpLmJ1ZmZlcjtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IGNvcmUuT3BlcmF0aW9uRXJyb3IoXCJmb3JtYXQ6IE11c3QgYmUgJ2p3aycgb3IgJ3JhdydcIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIGFzeW5jIGltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBsZXQga2V5O1xuICAgICAgICBzd2l0Y2ggKGZvcm1hdC50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgICAgICBjYXNlIFwiandrXCI6XG4gICAgICAgICAgICAgICAga2V5ID0gSnNvblBhcnNlci5mcm9tSlNPTihrZXlEYXRhLCB7IHRhcmdldFNjaGVtYTogRGVzQ3J5cHRvS2V5IH0pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcInJhd1wiOlxuICAgICAgICAgICAgICAgIGtleSA9IG5ldyBEZXNDcnlwdG9LZXkoKTtcbiAgICAgICAgICAgICAgICBrZXkuZGF0YSA9IEJ1ZmZlci5mcm9tKGtleURhdGEpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgY29yZS5PcGVyYXRpb25FcnJvcihcImZvcm1hdDogTXVzdCBiZSAnandrJyBvciAncmF3J1wiKTtcbiAgICAgICAgfVxuICAgICAgICBrZXkuYWxnb3JpdGhtID0gYWxnb3JpdGhtO1xuICAgICAgICBrZXkuZXh0cmFjdGFibGUgPSBleHRyYWN0YWJsZTtcbiAgICAgICAga2V5LnVzYWdlcyA9IGtleVVzYWdlcztcbiAgICAgICAgcmV0dXJuIGtleTtcbiAgICB9XG4gICAgc3RhdGljIGFzeW5jIGVuY3J5cHQoYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgc3dpdGNoIChhbGdvcml0aG0ubmFtZS50b1VwcGVyQ2FzZSgpKSB7XG4gICAgICAgICAgICBjYXNlIFwiREVTLUNCQ1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVuY3J5cHREZXNDQkMoYWxnb3JpdGhtLCBrZXksIEJ1ZmZlci5mcm9tKGRhdGEpKTtcbiAgICAgICAgICAgIGNhc2UgXCJERVMtRURFMy1DQkNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lbmNyeXB0RGVzRURFM0NCQyhhbGdvcml0aG0sIGtleSwgQnVmZmVyLmZyb20oZGF0YSkpO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgY29yZS5PcGVyYXRpb25FcnJvcihcImFsZ29yaXRobTogSXMgbm90IHJlY29nbml6ZWRcIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIGFzeW5jIGRlY3J5cHQoYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgaWYgKCEoa2V5IGluc3RhbmNlb2YgRGVzQ3J5cHRvS2V5KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwia2V5OiBJcyBub3QgRGVzQ3J5cHRvS2V5XCIpO1xuICAgICAgICB9XG4gICAgICAgIHN3aXRjaCAoYWxnb3JpdGhtLm5hbWUudG9VcHBlckNhc2UoKSkge1xuICAgICAgICAgICAgY2FzZSBcIkRFUy1DQkNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5kZWNyeXB0RGVzQ0JDKGFsZ29yaXRobSwga2V5LCBCdWZmZXIuZnJvbShkYXRhKSk7XG4gICAgICAgICAgICBjYXNlIFwiREVTLUVERTMtQ0JDXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGVjcnlwdERlc0VERTNDQkMoYWxnb3JpdGhtLCBrZXksIEJ1ZmZlci5mcm9tKGRhdGEpKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IGNvcmUuT3BlcmF0aW9uRXJyb3IoXCJhbGdvcml0aG06IElzIG5vdCByZWNvZ25pemVkXCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHN0YXRpYyBhc3luYyBlbmNyeXB0RGVzQ0JDKGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIGNvbnN0IGNpcGhlciA9IGNyeXB0b19fZGVmYXVsdC5jcmVhdGVDaXBoZXJpdihgZGVzLWNiY2AsIGtleS5kYXRhLCBuZXcgVWludDhBcnJheShhbGdvcml0aG0uaXYpKTtcbiAgICAgICAgbGV0IGVuYyA9IGNpcGhlci51cGRhdGUoZGF0YSk7XG4gICAgICAgIGVuYyA9IEJ1ZmZlci5jb25jYXQoW2VuYywgY2lwaGVyLmZpbmFsKCldKTtcbiAgICAgICAgY29uc3QgcmVzID0gbmV3IFVpbnQ4QXJyYXkoZW5jKS5idWZmZXI7XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxuICAgIHN0YXRpYyBhc3luYyBkZWNyeXB0RGVzQ0JDKGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIGNvbnN0IGRlY2lwaGVyID0gY3J5cHRvX19kZWZhdWx0LmNyZWF0ZURlY2lwaGVyaXYoYGRlcy1jYmNgLCBrZXkuZGF0YSwgbmV3IFVpbnQ4QXJyYXkoYWxnb3JpdGhtLml2KSk7XG4gICAgICAgIGxldCBkZWMgPSBkZWNpcGhlci51cGRhdGUoZGF0YSk7XG4gICAgICAgIGRlYyA9IEJ1ZmZlci5jb25jYXQoW2RlYywgZGVjaXBoZXIuZmluYWwoKV0pO1xuICAgICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoZGVjKS5idWZmZXI7XG4gICAgfVxuICAgIHN0YXRpYyBhc3luYyBlbmNyeXB0RGVzRURFM0NCQyhhbGdvcml0aG0sIGtleSwgZGF0YSkge1xuICAgICAgICBjb25zdCBjaXBoZXIgPSBjcnlwdG9fX2RlZmF1bHQuY3JlYXRlQ2lwaGVyaXYoYGRlcy1lZGUzLWNiY2AsIGtleS5kYXRhLCBCdWZmZXIuZnJvbShhbGdvcml0aG0uaXYpKTtcbiAgICAgICAgbGV0IGVuYyA9IGNpcGhlci51cGRhdGUoZGF0YSk7XG4gICAgICAgIGVuYyA9IEJ1ZmZlci5jb25jYXQoW2VuYywgY2lwaGVyLmZpbmFsKCldKTtcbiAgICAgICAgY29uc3QgcmVzID0gbmV3IFVpbnQ4QXJyYXkoZW5jKS5idWZmZXI7XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxuICAgIHN0YXRpYyBhc3luYyBkZWNyeXB0RGVzRURFM0NCQyhhbGdvcml0aG0sIGtleSwgZGF0YSkge1xuICAgICAgICBjb25zdCBkZWNpcGhlciA9IGNyeXB0b19fZGVmYXVsdC5jcmVhdGVEZWNpcGhlcml2KGBkZXMtZWRlMy1jYmNgLCBrZXkuZGF0YSwgbmV3IFVpbnQ4QXJyYXkoYWxnb3JpdGhtLml2KSk7XG4gICAgICAgIGxldCBkZWMgPSBkZWNpcGhlci51cGRhdGUoZGF0YSk7XG4gICAgICAgIGRlYyA9IEJ1ZmZlci5jb25jYXQoW2RlYywgZGVjaXBoZXIuZmluYWwoKV0pO1xuICAgICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoZGVjKS5idWZmZXI7XG4gICAgfVxufVxuXG5jbGFzcyBEZXNDYmNQcm92aWRlciBleHRlbmRzIGNvcmUuRGVzUHJvdmlkZXIge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLmtleVNpemVCaXRzID0gNjQ7XG4gICAgICAgIHRoaXMuaXZTaXplID0gODtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJERVMtQ0JDXCI7XG4gICAgfVxuICAgIGFzeW5jIG9uR2VuZXJhdGVLZXkoYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IGF3YWl0IERlc0NyeXB0by5nZW5lcmF0ZUtleSh7XG4gICAgICAgICAgICBuYW1lOiB0aGlzLm5hbWUsXG4gICAgICAgICAgICBsZW5ndGg6IHRoaXMua2V5U2l6ZUJpdHMsXG4gICAgICAgIH0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpO1xuICAgICAgICByZXR1cm4gc2V0Q3J5cHRvS2V5KGtleSk7XG4gICAgfVxuICAgIGFzeW5jIG9uRW5jcnlwdChhbGdvcml0aG0sIGtleSwgZGF0YSkge1xuICAgICAgICByZXR1cm4gRGVzQ3J5cHRvLmVuY3J5cHQoYWxnb3JpdGhtLCBnZXRDcnlwdG9LZXkoa2V5KSwgbmV3IFVpbnQ4QXJyYXkoZGF0YSkpO1xuICAgIH1cbiAgICBhc3luYyBvbkRlY3J5cHQoYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgcmV0dXJuIERlc0NyeXB0by5kZWNyeXB0KGFsZ29yaXRobSwgZ2V0Q3J5cHRvS2V5KGtleSksIG5ldyBVaW50OEFycmF5KGRhdGEpKTtcbiAgICB9XG4gICAgYXN5bmMgb25FeHBvcnRLZXkoZm9ybWF0LCBrZXkpIHtcbiAgICAgICAgcmV0dXJuIERlc0NyeXB0by5leHBvcnRLZXkoZm9ybWF0LCBnZXRDcnlwdG9LZXkoa2V5KSk7XG4gICAgfVxuICAgIGFzeW5jIG9uSW1wb3J0S2V5KGZvcm1hdCwga2V5RGF0YSwgYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IGF3YWl0IERlc0NyeXB0by5pbXBvcnRLZXkoZm9ybWF0LCBrZXlEYXRhLCB7IG5hbWU6IHRoaXMubmFtZSwgbGVuZ3RoOiB0aGlzLmtleVNpemVCaXRzIH0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpO1xuICAgICAgICBpZiAoa2V5LmRhdGEubGVuZ3RoICE9PSAodGhpcy5rZXlTaXplQml0cyA+PiAzKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IGNvcmUuT3BlcmF0aW9uRXJyb3IoXCJrZXlEYXRhOiBXcm9uZyBrZXkgc2l6ZVwiKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc2V0Q3J5cHRvS2V5KGtleSk7XG4gICAgfVxuICAgIGNoZWNrQ3J5cHRvS2V5KGtleSwga2V5VXNhZ2UpIHtcbiAgICAgICAgc3VwZXIuY2hlY2tDcnlwdG9LZXkoa2V5LCBrZXlVc2FnZSk7XG4gICAgICAgIGlmICghKGdldENyeXB0b0tleShrZXkpIGluc3RhbmNlb2YgRGVzQ3J5cHRvS2V5KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImtleTogSXMgbm90IGEgRGVzQ3J5cHRvS2V5XCIpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5jbGFzcyBEZXNFZGUzQ2JjUHJvdmlkZXIgZXh0ZW5kcyBjb3JlLkRlc1Byb3ZpZGVyIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5rZXlTaXplQml0cyA9IDE5MjtcbiAgICAgICAgdGhpcy5pdlNpemUgPSA4O1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkRFUy1FREUzLUNCQ1wiO1xuICAgIH1cbiAgICBhc3luYyBvbkdlbmVyYXRlS2V5KGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCBrZXkgPSBhd2FpdCBEZXNDcnlwdG8uZ2VuZXJhdGVLZXkoe1xuICAgICAgICAgICAgbmFtZTogdGhpcy5uYW1lLFxuICAgICAgICAgICAgbGVuZ3RoOiB0aGlzLmtleVNpemVCaXRzLFxuICAgICAgICB9LCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgcmV0dXJuIHNldENyeXB0b0tleShrZXkpO1xuICAgIH1cbiAgICBhc3luYyBvbkVuY3J5cHQoYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgcmV0dXJuIERlc0NyeXB0by5lbmNyeXB0KGFsZ29yaXRobSwgZ2V0Q3J5cHRvS2V5KGtleSksIG5ldyBVaW50OEFycmF5KGRhdGEpKTtcbiAgICB9XG4gICAgYXN5bmMgb25EZWNyeXB0KGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIHJldHVybiBEZXNDcnlwdG8uZGVjcnlwdChhbGdvcml0aG0sIGdldENyeXB0b0tleShrZXkpLCBuZXcgVWludDhBcnJheShkYXRhKSk7XG4gICAgfVxuICAgIGFzeW5jIG9uRXhwb3J0S2V5KGZvcm1hdCwga2V5KSB7XG4gICAgICAgIHJldHVybiBEZXNDcnlwdG8uZXhwb3J0S2V5KGZvcm1hdCwgZ2V0Q3J5cHRvS2V5KGtleSkpO1xuICAgIH1cbiAgICBhc3luYyBvbkltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCBrZXkgPSBhd2FpdCBEZXNDcnlwdG8uaW1wb3J0S2V5KGZvcm1hdCwga2V5RGF0YSwgeyBuYW1lOiB0aGlzLm5hbWUsIGxlbmd0aDogdGhpcy5rZXlTaXplQml0cyB9LCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgaWYgKGtleS5kYXRhLmxlbmd0aCAhPT0gKHRoaXMua2V5U2l6ZUJpdHMgPj4gMykpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBjb3JlLk9wZXJhdGlvbkVycm9yKFwia2V5RGF0YTogV3Jvbmcga2V5IHNpemVcIik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNldENyeXB0b0tleShrZXkpO1xuICAgIH1cbiAgICBjaGVja0NyeXB0b0tleShrZXksIGtleVVzYWdlKSB7XG4gICAgICAgIHN1cGVyLmNoZWNrQ3J5cHRvS2V5KGtleSwga2V5VXNhZ2UpO1xuICAgICAgICBpZiAoIShnZXRDcnlwdG9LZXkoa2V5KSBpbnN0YW5jZW9mIERlc0NyeXB0b0tleSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJrZXk6IElzIG5vdCBhIERlc0NyeXB0b0tleVwiKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZnVuY3Rpb24gZ2V0SndrQWxnb3JpdGhtKGFsZ29yaXRobSkge1xuICAgIHN3aXRjaCAoYWxnb3JpdGhtLm5hbWUudG9VcHBlckNhc2UoKSkge1xuICAgICAgICBjYXNlIFwiUlNBLU9BRVBcIjoge1xuICAgICAgICAgICAgY29uc3QgbWRTaXplID0gLyhcXGQrKSQvLmV4ZWMoYWxnb3JpdGhtLmhhc2gubmFtZSlbMV07XG4gICAgICAgICAgICByZXR1cm4gYFJTQS1PQUVQJHttZFNpemUgIT09IFwiMVwiID8gYC0ke21kU2l6ZX1gIDogXCJcIn1gO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgXCJSU0FTU0EtUEtDUzEtVjFfNVwiOlxuICAgICAgICAgICAgcmV0dXJuIGBSUyR7LyhcXGQrKSQvLmV4ZWMoYWxnb3JpdGhtLmhhc2gubmFtZSlbMV19YDtcbiAgICAgICAgY2FzZSBcIlJTQS1QU1NcIjpcbiAgICAgICAgICAgIHJldHVybiBgUFMkey8oXFxkKykkLy5leGVjKGFsZ29yaXRobS5oYXNoLm5hbWUpWzFdfWA7XG4gICAgICAgIGNhc2UgXCJSU0EtUEtDUzFcIjpcbiAgICAgICAgICAgIHJldHVybiBgUlMxYDtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHRocm93IG5ldyBjb3JlLk9wZXJhdGlvbkVycm9yKFwiYWxnb3JpdGhtOiBJcyBub3QgcmVjb2duaXplZFwiKTtcbiAgICB9XG59XG5cbmNsYXNzIFJzYVByaXZhdGVLZXkgZXh0ZW5kcyBBc3ltbWV0cmljS2V5IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy50eXBlID0gXCJwcml2YXRlXCI7XG4gICAgfVxuICAgIGdldEtleSgpIHtcbiAgICAgICAgY29uc3Qga2V5SW5mbyA9IEFzblBhcnNlci5wYXJzZSh0aGlzLmRhdGEsIGNvcmUuYXNuMS5Qcml2YXRlS2V5SW5mbyk7XG4gICAgICAgIHJldHVybiBBc25QYXJzZXIucGFyc2Uoa2V5SW5mby5wcml2YXRlS2V5LCBjb3JlLmFzbjEuUnNhUHJpdmF0ZUtleSk7XG4gICAgfVxuICAgIHRvSlNPTigpIHtcbiAgICAgICAgY29uc3Qga2V5ID0gdGhpcy5nZXRLZXkoKTtcbiAgICAgICAgY29uc3QganNvbiA9IHtcbiAgICAgICAgICAgIGt0eTogXCJSU0FcIixcbiAgICAgICAgICAgIGFsZzogZ2V0SndrQWxnb3JpdGhtKHRoaXMuYWxnb3JpdGhtKSxcbiAgICAgICAgICAgIGtleV9vcHM6IHRoaXMudXNhZ2VzLFxuICAgICAgICAgICAgZXh0OiB0aGlzLmV4dHJhY3RhYmxlLFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihqc29uLCBKc29uU2VyaWFsaXplci50b0pTT04oa2V5KSk7XG4gICAgfVxuICAgIGZyb21KU09OKGpzb24pIHtcbiAgICAgICAgY29uc3Qga2V5ID0gSnNvblBhcnNlci5mcm9tSlNPTihqc29uLCB7IHRhcmdldFNjaGVtYTogY29yZS5hc24xLlJzYVByaXZhdGVLZXkgfSk7XG4gICAgICAgIGNvbnN0IGtleUluZm8gPSBuZXcgY29yZS5hc24xLlByaXZhdGVLZXlJbmZvKCk7XG4gICAgICAgIGtleUluZm8ucHJpdmF0ZUtleUFsZ29yaXRobS5hbGdvcml0aG0gPSBcIjEuMi44NDAuMTEzNTQ5LjEuMS4xXCI7XG4gICAgICAgIGtleUluZm8ucHJpdmF0ZUtleUFsZ29yaXRobS5wYXJhbWV0ZXJzID0gbnVsbDtcbiAgICAgICAga2V5SW5mby5wcml2YXRlS2V5ID0gQXNuU2VyaWFsaXplci5zZXJpYWxpemUoa2V5KTtcbiAgICAgICAgdGhpcy5kYXRhID0gQnVmZmVyLmZyb20oQXNuU2VyaWFsaXplci5zZXJpYWxpemUoa2V5SW5mbykpO1xuICAgIH1cbn1cblxuY2xhc3MgUnNhUHVibGljS2V5IGV4dGVuZHMgQXN5bW1ldHJpY0tleSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMudHlwZSA9IFwicHVibGljXCI7XG4gICAgfVxuICAgIGdldEtleSgpIHtcbiAgICAgICAgY29uc3Qga2V5SW5mbyA9IEFzblBhcnNlci5wYXJzZSh0aGlzLmRhdGEsIGNvcmUuYXNuMS5QdWJsaWNLZXlJbmZvKTtcbiAgICAgICAgcmV0dXJuIEFzblBhcnNlci5wYXJzZShrZXlJbmZvLnB1YmxpY0tleSwgY29yZS5hc24xLlJzYVB1YmxpY0tleSk7XG4gICAgfVxuICAgIHRvSlNPTigpIHtcbiAgICAgICAgY29uc3Qga2V5ID0gdGhpcy5nZXRLZXkoKTtcbiAgICAgICAgY29uc3QganNvbiA9IHtcbiAgICAgICAgICAgIGt0eTogXCJSU0FcIixcbiAgICAgICAgICAgIGFsZzogZ2V0SndrQWxnb3JpdGhtKHRoaXMuYWxnb3JpdGhtKSxcbiAgICAgICAgICAgIGtleV9vcHM6IHRoaXMudXNhZ2VzLFxuICAgICAgICAgICAgZXh0OiB0aGlzLmV4dHJhY3RhYmxlLFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihqc29uLCBKc29uU2VyaWFsaXplci50b0pTT04oa2V5KSk7XG4gICAgfVxuICAgIGZyb21KU09OKGpzb24pIHtcbiAgICAgICAgY29uc3Qga2V5ID0gSnNvblBhcnNlci5mcm9tSlNPTihqc29uLCB7IHRhcmdldFNjaGVtYTogY29yZS5hc24xLlJzYVB1YmxpY0tleSB9KTtcbiAgICAgICAgY29uc3Qga2V5SW5mbyA9IG5ldyBjb3JlLmFzbjEuUHVibGljS2V5SW5mbygpO1xuICAgICAgICBrZXlJbmZvLnB1YmxpY0tleUFsZ29yaXRobS5hbGdvcml0aG0gPSBcIjEuMi44NDAuMTEzNTQ5LjEuMS4xXCI7XG4gICAgICAgIGtleUluZm8ucHVibGljS2V5QWxnb3JpdGhtLnBhcmFtZXRlcnMgPSBudWxsO1xuICAgICAgICBrZXlJbmZvLnB1YmxpY0tleSA9IEFzblNlcmlhbGl6ZXIuc2VyaWFsaXplKGtleSk7XG4gICAgICAgIHRoaXMuZGF0YSA9IEJ1ZmZlci5mcm9tKEFzblNlcmlhbGl6ZXIuc2VyaWFsaXplKGtleUluZm8pKTtcbiAgICB9XG59XG5cbmNsYXNzIFJzYUNyeXB0byB7XG4gICAgc3RhdGljIGFzeW5jIGdlbmVyYXRlS2V5KGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCBwcml2YXRlS2V5ID0gbmV3IFJzYVByaXZhdGVLZXkoKTtcbiAgICAgICAgcHJpdmF0ZUtleS5hbGdvcml0aG0gPSBhbGdvcml0aG07XG4gICAgICAgIHByaXZhdGVLZXkuZXh0cmFjdGFibGUgPSBleHRyYWN0YWJsZTtcbiAgICAgICAgcHJpdmF0ZUtleS51c2FnZXMgPSBrZXlVc2FnZXMuZmlsdGVyKCh1c2FnZSkgPT4gdGhpcy5wcml2YXRlS2V5VXNhZ2VzLmluZGV4T2YodXNhZ2UpICE9PSAtMSk7XG4gICAgICAgIGNvbnN0IHB1YmxpY0tleSA9IG5ldyBSc2FQdWJsaWNLZXkoKTtcbiAgICAgICAgcHVibGljS2V5LmFsZ29yaXRobSA9IGFsZ29yaXRobTtcbiAgICAgICAgcHVibGljS2V5LmV4dHJhY3RhYmxlID0gdHJ1ZTtcbiAgICAgICAgcHVibGljS2V5LnVzYWdlcyA9IGtleVVzYWdlcy5maWx0ZXIoKHVzYWdlKSA9PiB0aGlzLnB1YmxpY0tleVVzYWdlcy5pbmRleE9mKHVzYWdlKSAhPT0gLTEpO1xuICAgICAgICBjb25zdCBwdWJsaWNFeHBvbmVudCA9IEJ1ZmZlci5jb25jYXQoW1xuICAgICAgICAgICAgQnVmZmVyLmFsbG9jKDQgLSBhbGdvcml0aG0ucHVibGljRXhwb25lbnQuYnl0ZUxlbmd0aCwgMCksXG4gICAgICAgICAgICBCdWZmZXIuZnJvbShhbGdvcml0aG0ucHVibGljRXhwb25lbnQpLFxuICAgICAgICBdKS5yZWFkSW50MzJCRSgwKTtcbiAgICAgICAgY29uc3Qga2V5cyA9IGNyeXB0b19fZGVmYXVsdC5nZW5lcmF0ZUtleVBhaXJTeW5jKFwicnNhXCIsIHtcbiAgICAgICAgICAgIG1vZHVsdXNMZW5ndGg6IGFsZ29yaXRobS5tb2R1bHVzTGVuZ3RoLFxuICAgICAgICAgICAgcHVibGljRXhwb25lbnQsXG4gICAgICAgICAgICBwdWJsaWNLZXlFbmNvZGluZzoge1xuICAgICAgICAgICAgICAgIGZvcm1hdDogXCJkZXJcIixcbiAgICAgICAgICAgICAgICB0eXBlOiBcInNwa2lcIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBwcml2YXRlS2V5RW5jb2Rpbmc6IHtcbiAgICAgICAgICAgICAgICBmb3JtYXQ6IFwiZGVyXCIsXG4gICAgICAgICAgICAgICAgdHlwZTogXCJwa2NzOFwiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIHByaXZhdGVLZXkuZGF0YSA9IGtleXMucHJpdmF0ZUtleTtcbiAgICAgICAgcHVibGljS2V5LmRhdGEgPSBrZXlzLnB1YmxpY0tleTtcbiAgICAgICAgY29uc3QgcmVzID0ge1xuICAgICAgICAgICAgcHJpdmF0ZUtleSxcbiAgICAgICAgICAgIHB1YmxpY0tleSxcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG4gICAgc3RhdGljIGFzeW5jIGV4cG9ydEtleShmb3JtYXQsIGtleSkge1xuICAgICAgICBzd2l0Y2ggKGZvcm1hdC50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgICAgICBjYXNlIFwiandrXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIEpzb25TZXJpYWxpemVyLnRvSlNPTihrZXkpO1xuICAgICAgICAgICAgY2FzZSBcInBrY3M4XCI6XG4gICAgICAgICAgICBjYXNlIFwic3BraVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShrZXkuZGF0YSkuYnVmZmVyO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgY29yZS5PcGVyYXRpb25FcnJvcihcImZvcm1hdDogTXVzdCBiZSAnandrJywgJ3BrY3M4JyBvciAnc3BraSdcIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIGFzeW5jIGltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBzd2l0Y2ggKGZvcm1hdC50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgICAgICBjYXNlIFwiandrXCI6IHtcbiAgICAgICAgICAgICAgICBjb25zdCBqd2sgPSBrZXlEYXRhO1xuICAgICAgICAgICAgICAgIGlmIChqd2suZCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhc25LZXkgPSBKc29uUGFyc2VyLmZyb21KU09OKGtleURhdGEsIHsgdGFyZ2V0U2NoZW1hOiBjb3JlLmFzbjEuUnNhUHJpdmF0ZUtleSB9KTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW1wb3J0UHJpdmF0ZUtleShhc25LZXksIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhc25LZXkgPSBKc29uUGFyc2VyLmZyb21KU09OKGtleURhdGEsIHsgdGFyZ2V0U2NoZW1hOiBjb3JlLmFzbjEuUnNhUHVibGljS2V5IH0pO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5pbXBvcnRQdWJsaWNLZXkoYXNuS2V5LCBhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJzcGtpXCI6IHtcbiAgICAgICAgICAgICAgICBjb25zdCBrZXlJbmZvID0gQXNuUGFyc2VyLnBhcnNlKG5ldyBVaW50OEFycmF5KGtleURhdGEpLCBjb3JlLmFzbjEuUHVibGljS2V5SW5mbyk7XG4gICAgICAgICAgICAgICAgY29uc3QgYXNuS2V5ID0gQXNuUGFyc2VyLnBhcnNlKGtleUluZm8ucHVibGljS2V5LCBjb3JlLmFzbjEuUnNhUHVibGljS2V5KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5pbXBvcnRQdWJsaWNLZXkoYXNuS2V5LCBhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInBrY3M4XCI6IHtcbiAgICAgICAgICAgICAgICBjb25zdCBrZXlJbmZvID0gQXNuUGFyc2VyLnBhcnNlKG5ldyBVaW50OEFycmF5KGtleURhdGEpLCBjb3JlLmFzbjEuUHJpdmF0ZUtleUluZm8pO1xuICAgICAgICAgICAgICAgIGNvbnN0IGFzbktleSA9IEFzblBhcnNlci5wYXJzZShrZXlJbmZvLnByaXZhdGVLZXksIGNvcmUuYXNuMS5Sc2FQcml2YXRlS2V5KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5pbXBvcnRQcml2YXRlS2V5KGFzbktleSwgYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IGNvcmUuT3BlcmF0aW9uRXJyb3IoXCJmb3JtYXQ6IE11c3QgYmUgJ2p3aycsICdwa2NzOCcgb3IgJ3Nwa2knXCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHN0YXRpYyBhc3luYyBzaWduKGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIHN3aXRjaCAoYWxnb3JpdGhtLm5hbWUudG9VcHBlckNhc2UoKSkge1xuICAgICAgICAgICAgY2FzZSBcIlJTQS1QU1NcIjpcbiAgICAgICAgICAgIGNhc2UgXCJSU0FTU0EtUEtDUzEtVjFfNVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnNpZ25Sc2EoYWxnb3JpdGhtLCBrZXksIGRhdGEpO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgY29yZS5PcGVyYXRpb25FcnJvcihcImFsZ29yaXRobTogSXMgbm90IHJlY29nbml6ZWRcIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIGFzeW5jIHZlcmlmeShhbGdvcml0aG0sIGtleSwgc2lnbmF0dXJlLCBkYXRhKSB7XG4gICAgICAgIHN3aXRjaCAoYWxnb3JpdGhtLm5hbWUudG9VcHBlckNhc2UoKSkge1xuICAgICAgICAgICAgY2FzZSBcIlJTQS1QU1NcIjpcbiAgICAgICAgICAgIGNhc2UgXCJSU0FTU0EtUEtDUzEtVjFfNVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnZlcmlmeVNTQShhbGdvcml0aG0sIGtleSwgZGF0YSwgc2lnbmF0dXJlKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IGNvcmUuT3BlcmF0aW9uRXJyb3IoXCJhbGdvcml0aG06IElzIG5vdCByZWNvZ25pemVkXCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHN0YXRpYyBhc3luYyBlbmNyeXB0KGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIHN3aXRjaCAoYWxnb3JpdGhtLm5hbWUudG9VcHBlckNhc2UoKSkge1xuICAgICAgICAgICAgY2FzZSBcIlJTQS1PQUVQXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW5jcnlwdE9BRVAoYWxnb3JpdGhtLCBrZXksIGRhdGEpO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgY29yZS5PcGVyYXRpb25FcnJvcihcImFsZ29yaXRobTogSXMgbm90IHJlY29nbml6ZWRcIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIGFzeW5jIGRlY3J5cHQoYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgc3dpdGNoIChhbGdvcml0aG0ubmFtZS50b1VwcGVyQ2FzZSgpKSB7XG4gICAgICAgICAgICBjYXNlIFwiUlNBLU9BRVBcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5kZWNyeXB0T0FFUChhbGdvcml0aG0sIGtleSwgZGF0YSk7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBjb3JlLk9wZXJhdGlvbkVycm9yKFwiYWxnb3JpdGhtOiBJcyBub3QgcmVjb2duaXplZFwiKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzdGF0aWMgaW1wb3J0UHJpdmF0ZUtleShhc25LZXksIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCBrZXlJbmZvID0gbmV3IGNvcmUuYXNuMS5Qcml2YXRlS2V5SW5mbygpO1xuICAgICAgICBrZXlJbmZvLnByaXZhdGVLZXlBbGdvcml0aG0uYWxnb3JpdGhtID0gXCIxLjIuODQwLjExMzU0OS4xLjEuMVwiO1xuICAgICAgICBrZXlJbmZvLnByaXZhdGVLZXlBbGdvcml0aG0ucGFyYW1ldGVycyA9IG51bGw7XG4gICAgICAgIGtleUluZm8ucHJpdmF0ZUtleSA9IEFzblNlcmlhbGl6ZXIuc2VyaWFsaXplKGFzbktleSk7XG4gICAgICAgIGNvbnN0IGtleSA9IG5ldyBSc2FQcml2YXRlS2V5KCk7XG4gICAgICAgIGtleS5kYXRhID0gQnVmZmVyLmZyb20oQXNuU2VyaWFsaXplci5zZXJpYWxpemUoa2V5SW5mbykpO1xuICAgICAgICBrZXkuYWxnb3JpdGhtID0gT2JqZWN0LmFzc2lnbih7fSwgYWxnb3JpdGhtKTtcbiAgICAgICAga2V5LmFsZ29yaXRobS5wdWJsaWNFeHBvbmVudCA9IG5ldyBVaW50OEFycmF5KGFzbktleS5wdWJsaWNFeHBvbmVudCk7XG4gICAgICAgIGtleS5hbGdvcml0aG0ubW9kdWx1c0xlbmd0aCA9IGFzbktleS5tb2R1bHVzLmJ5dGVMZW5ndGggPDwgMztcbiAgICAgICAga2V5LmV4dHJhY3RhYmxlID0gZXh0cmFjdGFibGU7XG4gICAgICAgIGtleS51c2FnZXMgPSBrZXlVc2FnZXM7XG4gICAgICAgIHJldHVybiBrZXk7XG4gICAgfVxuICAgIHN0YXRpYyBpbXBvcnRQdWJsaWNLZXkoYXNuS2V5LCBhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgY29uc3Qga2V5SW5mbyA9IG5ldyBjb3JlLmFzbjEuUHVibGljS2V5SW5mbygpO1xuICAgICAgICBrZXlJbmZvLnB1YmxpY0tleUFsZ29yaXRobS5hbGdvcml0aG0gPSBcIjEuMi44NDAuMTEzNTQ5LjEuMS4xXCI7XG4gICAgICAgIGtleUluZm8ucHVibGljS2V5QWxnb3JpdGhtLnBhcmFtZXRlcnMgPSBudWxsO1xuICAgICAgICBrZXlJbmZvLnB1YmxpY0tleSA9IEFzblNlcmlhbGl6ZXIuc2VyaWFsaXplKGFzbktleSk7XG4gICAgICAgIGNvbnN0IGtleSA9IG5ldyBSc2FQdWJsaWNLZXkoKTtcbiAgICAgICAga2V5LmRhdGEgPSBCdWZmZXIuZnJvbShBc25TZXJpYWxpemVyLnNlcmlhbGl6ZShrZXlJbmZvKSk7XG4gICAgICAgIGtleS5hbGdvcml0aG0gPSBPYmplY3QuYXNzaWduKHt9LCBhbGdvcml0aG0pO1xuICAgICAgICBrZXkuYWxnb3JpdGhtLnB1YmxpY0V4cG9uZW50ID0gbmV3IFVpbnQ4QXJyYXkoYXNuS2V5LnB1YmxpY0V4cG9uZW50KTtcbiAgICAgICAga2V5LmFsZ29yaXRobS5tb2R1bHVzTGVuZ3RoID0gYXNuS2V5Lm1vZHVsdXMuYnl0ZUxlbmd0aCA8PCAzO1xuICAgICAgICBrZXkuZXh0cmFjdGFibGUgPSBleHRyYWN0YWJsZTtcbiAgICAgICAga2V5LnVzYWdlcyA9IGtleVVzYWdlcztcbiAgICAgICAgcmV0dXJuIGtleTtcbiAgICB9XG4gICAgc3RhdGljIGdldENyeXB0b0FsZ29yaXRobShhbGcpIHtcbiAgICAgICAgc3dpdGNoIChhbGcuaGFzaC5uYW1lLnRvVXBwZXJDYXNlKCkpIHtcbiAgICAgICAgICAgIGNhc2UgXCJTSEEtMVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIlJTQS1TSEExXCI7XG4gICAgICAgICAgICBjYXNlIFwiU0hBLTI1NlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIlJTQS1TSEEyNTZcIjtcbiAgICAgICAgICAgIGNhc2UgXCJTSEEtMzg0XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiUlNBLVNIQTM4NFwiO1xuICAgICAgICAgICAgY2FzZSBcIlNIQS01MTJcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJSU0EtU0hBNTEyXCI7XG4gICAgICAgICAgICBjYXNlIFwiU0hBMy0yNTZcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJSU0EtU0hBMy0yNTZcIjtcbiAgICAgICAgICAgIGNhc2UgXCJTSEEzLTM4NFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIlJTQS1TSEEzLTM4NFwiO1xuICAgICAgICAgICAgY2FzZSBcIlNIQTMtNTEyXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiUlNBLVNIQTMtNTEyXCI7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBjb3JlLk9wZXJhdGlvbkVycm9yKFwiYWxnb3JpdGhtLmhhc2g6IElzIG5vdCByZWNvZ25pemVkXCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHN0YXRpYyBzaWduUnNhKGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIGNvbnN0IGNyeXB0b0FsZyA9IHRoaXMuZ2V0Q3J5cHRvQWxnb3JpdGhtKGtleS5hbGdvcml0aG0pO1xuICAgICAgICBjb25zdCBzaWduZXIgPSBjcnlwdG9fX2RlZmF1bHQuY3JlYXRlU2lnbihjcnlwdG9BbGcpO1xuICAgICAgICBzaWduZXIudXBkYXRlKEJ1ZmZlci5mcm9tKGRhdGEpKTtcbiAgICAgICAgaWYgKCFrZXkucGVtKSB7XG4gICAgICAgICAgICBrZXkucGVtID0gYC0tLS0tQkVHSU4gUFJJVkFURSBLRVktLS0tLVxcbiR7a2V5LmRhdGEudG9TdHJpbmcoXCJiYXNlNjRcIil9XFxuLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLWA7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgIGtleToga2V5LnBlbSxcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKGFsZ29yaXRobS5uYW1lLnRvVXBwZXJDYXNlKCkgPT09IFwiUlNBLVBTU1wiKSB7XG4gICAgICAgICAgICBvcHRpb25zLnBhZGRpbmcgPSBjcnlwdG9fX2RlZmF1bHQuY29uc3RhbnRzLlJTQV9QS0NTMV9QU1NfUEFERElORztcbiAgICAgICAgICAgIG9wdGlvbnMuc2FsdExlbmd0aCA9IGFsZ29yaXRobS5zYWx0TGVuZ3RoO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IHNpZ25lci5zaWduKG9wdGlvbnMpO1xuICAgICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoc2lnbmF0dXJlKS5idWZmZXI7XG4gICAgfVxuICAgIHN0YXRpYyB2ZXJpZnlTU0EoYWxnb3JpdGhtLCBrZXksIGRhdGEsIHNpZ25hdHVyZSkge1xuICAgICAgICBjb25zdCBjcnlwdG9BbGcgPSB0aGlzLmdldENyeXB0b0FsZ29yaXRobShrZXkuYWxnb3JpdGhtKTtcbiAgICAgICAgY29uc3Qgc2lnbmVyID0gY3J5cHRvX19kZWZhdWx0LmNyZWF0ZVZlcmlmeShjcnlwdG9BbGcpO1xuICAgICAgICBzaWduZXIudXBkYXRlKEJ1ZmZlci5mcm9tKGRhdGEpKTtcbiAgICAgICAgaWYgKCFrZXkucGVtKSB7XG4gICAgICAgICAgICBrZXkucGVtID0gYC0tLS0tQkVHSU4gUFVCTElDIEtFWS0tLS0tXFxuJHtrZXkuZGF0YS50b1N0cmluZyhcImJhc2U2NFwiKX1cXG4tLS0tLUVORCBQVUJMSUMgS0VZLS0tLS1gO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICBrZXk6IGtleS5wZW0sXG4gICAgICAgIH07XG4gICAgICAgIGlmIChhbGdvcml0aG0ubmFtZS50b1VwcGVyQ2FzZSgpID09PSBcIlJTQS1QU1NcIikge1xuICAgICAgICAgICAgb3B0aW9ucy5wYWRkaW5nID0gY3J5cHRvX19kZWZhdWx0LmNvbnN0YW50cy5SU0FfUEtDUzFfUFNTX1BBRERJTkc7XG4gICAgICAgICAgICBvcHRpb25zLnNhbHRMZW5ndGggPSBhbGdvcml0aG0uc2FsdExlbmd0aDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBvayA9IHNpZ25lci52ZXJpZnkob3B0aW9ucywgc2lnbmF0dXJlKTtcbiAgICAgICAgcmV0dXJuIG9rO1xuICAgIH1cbiAgICBzdGF0aWMgZW5jcnlwdE9BRVAoYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgIGtleTogYC0tLS0tQkVHSU4gUFVCTElDIEtFWS0tLS0tXFxuJHtrZXkuZGF0YS50b1N0cmluZyhcImJhc2U2NFwiKX1cXG4tLS0tLUVORCBQVUJMSUMgS0VZLS0tLS1gLFxuICAgICAgICAgICAgcGFkZGluZzogY3J5cHRvX19kZWZhdWx0LmNvbnN0YW50cy5SU0FfUEtDUzFfT0FFUF9QQURESU5HLFxuICAgICAgICB9O1xuICAgICAgICBpZiAoYWxnb3JpdGhtLmxhYmVsKSA7XG4gICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShjcnlwdG9fX2RlZmF1bHQucHVibGljRW5jcnlwdChvcHRpb25zLCBkYXRhKSkuYnVmZmVyO1xuICAgIH1cbiAgICBzdGF0aWMgZGVjcnlwdE9BRVAoYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgIGtleTogYC0tLS0tQkVHSU4gUFJJVkFURSBLRVktLS0tLVxcbiR7a2V5LmRhdGEudG9TdHJpbmcoXCJiYXNlNjRcIil9XFxuLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLWAsXG4gICAgICAgICAgICBwYWRkaW5nOiBjcnlwdG9fX2RlZmF1bHQuY29uc3RhbnRzLlJTQV9QS0NTMV9PQUVQX1BBRERJTkcsXG4gICAgICAgIH07XG4gICAgICAgIGlmIChhbGdvcml0aG0ubGFiZWwpIDtcbiAgICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGNyeXB0b19fZGVmYXVsdC5wcml2YXRlRGVjcnlwdChvcHRpb25zLCBkYXRhKSkuYnVmZmVyO1xuICAgIH1cbn1cblJzYUNyeXB0by5wdWJsaWNLZXlVc2FnZXMgPSBbXCJ2ZXJpZnlcIiwgXCJlbmNyeXB0XCIsIFwid3JhcEtleVwiXTtcblJzYUNyeXB0by5wcml2YXRlS2V5VXNhZ2VzID0gW1wic2lnblwiLCBcImRlY3J5cHRcIiwgXCJ1bndyYXBLZXlcIl07XG5cbmNsYXNzIFJzYVNzYVByb3ZpZGVyIGV4dGVuZHMgY29yZS5Sc2FTc2FQcm92aWRlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuaGFzaEFsZ29yaXRobXMgPSBbXG4gICAgICAgICAgICBcIlNIQS0xXCIsIFwiU0hBLTI1NlwiLCBcIlNIQS0zODRcIiwgXCJTSEEtNTEyXCIsXG4gICAgICAgICAgICBcInNoYWtlMTI4XCIsIFwic2hha2UyNTZcIixcbiAgICAgICAgICAgIFwiU0hBMy0yNTZcIiwgXCJTSEEzLTM4NFwiLCBcIlNIQTMtNTEyXCJcbiAgICAgICAgXTtcbiAgICB9XG4gICAgYXN5bmMgb25HZW5lcmF0ZUtleShhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgY29uc3Qga2V5cyA9IGF3YWl0IFJzYUNyeXB0by5nZW5lcmF0ZUtleSh7XG4gICAgICAgICAgICAuLi5hbGdvcml0aG0sXG4gICAgICAgICAgICBuYW1lOiB0aGlzLm5hbWUsXG4gICAgICAgIH0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcHJpdmF0ZUtleTogc2V0Q3J5cHRvS2V5KGtleXMucHJpdmF0ZUtleSksXG4gICAgICAgICAgICBwdWJsaWNLZXk6IHNldENyeXB0b0tleShrZXlzLnB1YmxpY0tleSksXG4gICAgICAgIH07XG4gICAgfVxuICAgIGFzeW5jIG9uU2lnbihhbGdvcml0aG0sIGtleSwgZGF0YSkge1xuICAgICAgICByZXR1cm4gUnNhQ3J5cHRvLnNpZ24oYWxnb3JpdGhtLCBnZXRDcnlwdG9LZXkoa2V5KSwgbmV3IFVpbnQ4QXJyYXkoZGF0YSkpO1xuICAgIH1cbiAgICBhc3luYyBvblZlcmlmeShhbGdvcml0aG0sIGtleSwgc2lnbmF0dXJlLCBkYXRhKSB7XG4gICAgICAgIHJldHVybiBSc2FDcnlwdG8udmVyaWZ5KGFsZ29yaXRobSwgZ2V0Q3J5cHRvS2V5KGtleSksIG5ldyBVaW50OEFycmF5KHNpZ25hdHVyZSksIG5ldyBVaW50OEFycmF5KGRhdGEpKTtcbiAgICB9XG4gICAgYXN5bmMgb25FeHBvcnRLZXkoZm9ybWF0LCBrZXkpIHtcbiAgICAgICAgcmV0dXJuIFJzYUNyeXB0by5leHBvcnRLZXkoZm9ybWF0LCBnZXRDcnlwdG9LZXkoa2V5KSk7XG4gICAgfVxuICAgIGFzeW5jIG9uSW1wb3J0S2V5KGZvcm1hdCwga2V5RGF0YSwgYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IGF3YWl0IFJzYUNyeXB0by5pbXBvcnRLZXkoZm9ybWF0LCBrZXlEYXRhLCB7IC4uLmFsZ29yaXRobSwgbmFtZTogdGhpcy5uYW1lIH0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpO1xuICAgICAgICByZXR1cm4gc2V0Q3J5cHRvS2V5KGtleSk7XG4gICAgfVxuICAgIGNoZWNrQ3J5cHRvS2V5KGtleSwga2V5VXNhZ2UpIHtcbiAgICAgICAgc3VwZXIuY2hlY2tDcnlwdG9LZXkoa2V5LCBrZXlVc2FnZSk7XG4gICAgICAgIGNvbnN0IGludGVybmFsS2V5ID0gZ2V0Q3J5cHRvS2V5KGtleSk7XG4gICAgICAgIGlmICghKGludGVybmFsS2V5IGluc3RhbmNlb2YgUnNhUHJpdmF0ZUtleSB8fCBpbnRlcm5hbEtleSBpbnN0YW5jZW9mIFJzYVB1YmxpY0tleSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJrZXk6IElzIG5vdCBSU0EgQ3J5cHRvS2V5XCIpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5jbGFzcyBSc2FQc3NQcm92aWRlciBleHRlbmRzIGNvcmUuUnNhUHNzUHJvdmlkZXIge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLmhhc2hBbGdvcml0aG1zID0gW1xuICAgICAgICAgICAgXCJTSEEtMVwiLCBcIlNIQS0yNTZcIiwgXCJTSEEtMzg0XCIsIFwiU0hBLTUxMlwiLFxuICAgICAgICAgICAgXCJzaGFrZTEyOFwiLCBcInNoYWtlMjU2XCIsXG4gICAgICAgICAgICBcIlNIQTMtMjU2XCIsIFwiU0hBMy0zODRcIiwgXCJTSEEzLTUxMlwiXG4gICAgICAgIF07XG4gICAgfVxuICAgIGFzeW5jIG9uR2VuZXJhdGVLZXkoYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKSB7XG4gICAgICAgIGNvbnN0IGtleXMgPSBhd2FpdCBSc2FDcnlwdG8uZ2VuZXJhdGVLZXkoe1xuICAgICAgICAgICAgLi4uYWxnb3JpdGhtLFxuICAgICAgICAgICAgbmFtZTogdGhpcy5uYW1lLFxuICAgICAgICB9LCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHByaXZhdGVLZXk6IHNldENyeXB0b0tleShrZXlzLnByaXZhdGVLZXkpLFxuICAgICAgICAgICAgcHVibGljS2V5OiBzZXRDcnlwdG9LZXkoa2V5cy5wdWJsaWNLZXkpLFxuICAgICAgICB9O1xuICAgIH1cbiAgICBhc3luYyBvblNpZ24oYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgcmV0dXJuIFJzYUNyeXB0by5zaWduKGFsZ29yaXRobSwgZ2V0Q3J5cHRvS2V5KGtleSksIG5ldyBVaW50OEFycmF5KGRhdGEpKTtcbiAgICB9XG4gICAgYXN5bmMgb25WZXJpZnkoYWxnb3JpdGhtLCBrZXksIHNpZ25hdHVyZSwgZGF0YSkge1xuICAgICAgICByZXR1cm4gUnNhQ3J5cHRvLnZlcmlmeShhbGdvcml0aG0sIGdldENyeXB0b0tleShrZXkpLCBuZXcgVWludDhBcnJheShzaWduYXR1cmUpLCBuZXcgVWludDhBcnJheShkYXRhKSk7XG4gICAgfVxuICAgIGFzeW5jIG9uRXhwb3J0S2V5KGZvcm1hdCwga2V5KSB7XG4gICAgICAgIHJldHVybiBSc2FDcnlwdG8uZXhwb3J0S2V5KGZvcm1hdCwgZ2V0Q3J5cHRvS2V5KGtleSkpO1xuICAgIH1cbiAgICBhc3luYyBvbkltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCBrZXkgPSBhd2FpdCBSc2FDcnlwdG8uaW1wb3J0S2V5KGZvcm1hdCwga2V5RGF0YSwgeyAuLi5hbGdvcml0aG0sIG5hbWU6IHRoaXMubmFtZSB9LCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgcmV0dXJuIHNldENyeXB0b0tleShrZXkpO1xuICAgIH1cbiAgICBjaGVja0NyeXB0b0tleShrZXksIGtleVVzYWdlKSB7XG4gICAgICAgIHN1cGVyLmNoZWNrQ3J5cHRvS2V5KGtleSwga2V5VXNhZ2UpO1xuICAgICAgICBjb25zdCBpbnRlcm5hbEtleSA9IGdldENyeXB0b0tleShrZXkpO1xuICAgICAgICBpZiAoIShpbnRlcm5hbEtleSBpbnN0YW5jZW9mIFJzYVByaXZhdGVLZXkgfHwgaW50ZXJuYWxLZXkgaW5zdGFuY2VvZiBSc2FQdWJsaWNLZXkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwia2V5OiBJcyBub3QgUlNBIENyeXB0b0tleVwiKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuY2xhc3MgU2hhQ3J5cHRvIHtcbiAgICBzdGF0aWMgc2l6ZShhbGdvcml0aG0pIHtcbiAgICAgICAgc3dpdGNoIChhbGdvcml0aG0ubmFtZS50b1VwcGVyQ2FzZSgpKSB7XG4gICAgICAgICAgICBjYXNlIFwiU0hBLTFcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gMTYwO1xuICAgICAgICAgICAgY2FzZSBcIlNIQS0yNTZcIjpcbiAgICAgICAgICAgIGNhc2UgXCJTSEEzLTI1NlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiAyNTY7XG4gICAgICAgICAgICBjYXNlIFwiU0hBLTM4NFwiOlxuICAgICAgICAgICAgY2FzZSBcIlNIQTMtMzg0XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIDM4NDtcbiAgICAgICAgICAgIGNhc2UgXCJTSEEtNTEyXCI6XG4gICAgICAgICAgICBjYXNlIFwiU0hBMy01MTJcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gNTEyO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbnJlY29nbml6ZWQgbmFtZVwiKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzdGF0aWMgZ2V0QWxnb3JpdGhtTmFtZShhbGdvcml0aG0pIHtcbiAgICAgICAgc3dpdGNoIChhbGdvcml0aG0ubmFtZS50b1VwcGVyQ2FzZSgpKSB7XG4gICAgICAgICAgICBjYXNlIFwiU0hBLTFcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJzaGExXCI7XG4gICAgICAgICAgICBjYXNlIFwiU0hBLTI1NlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcInNoYTI1NlwiO1xuICAgICAgICAgICAgY2FzZSBcIlNIQS0zODRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJzaGEzODRcIjtcbiAgICAgICAgICAgIGNhc2UgXCJTSEEtNTEyXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwic2hhNTEyXCI7XG4gICAgICAgICAgICBjYXNlIFwiU0hBMy0yNTZcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJzaGEzLTI1NlwiO1xuICAgICAgICAgICAgY2FzZSBcIlNIQTMtMzg0XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwic2hhMy0zODRcIjtcbiAgICAgICAgICAgIGNhc2UgXCJTSEEzLTUxMlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcInNoYTMtNTEyXCI7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlVucmVjb2duaXplZCBuYW1lXCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHN0YXRpYyBkaWdlc3QoYWxnb3JpdGhtLCBkYXRhKSB7XG4gICAgICAgIGNvbnN0IGhhc2hBbGcgPSB0aGlzLmdldEFsZ29yaXRobU5hbWUoYWxnb3JpdGhtKTtcbiAgICAgICAgY29uc3QgaGFzaCA9IGNyeXB0b19fZGVmYXVsdC5jcmVhdGVIYXNoKGhhc2hBbGcpXG4gICAgICAgICAgICAudXBkYXRlKEJ1ZmZlci5mcm9tKGRhdGEpKS5kaWdlc3QoKTtcbiAgICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGhhc2gpLmJ1ZmZlcjtcbiAgICB9XG59XG5cbmNsYXNzIFJzYU9hZXBQcm92aWRlciBleHRlbmRzIGNvcmUuUnNhT2FlcFByb3ZpZGVyIHtcbiAgICBhc3luYyBvbkdlbmVyYXRlS2V5KGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCBrZXlzID0gYXdhaXQgUnNhQ3J5cHRvLmdlbmVyYXRlS2V5KHtcbiAgICAgICAgICAgIC4uLmFsZ29yaXRobSxcbiAgICAgICAgICAgIG5hbWU6IHRoaXMubmFtZSxcbiAgICAgICAgfSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcyk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBwcml2YXRlS2V5OiBzZXRDcnlwdG9LZXkoa2V5cy5wcml2YXRlS2V5KSxcbiAgICAgICAgICAgIHB1YmxpY0tleTogc2V0Q3J5cHRvS2V5KGtleXMucHVibGljS2V5KSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgYXN5bmMgb25FbmNyeXB0KGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIGNvbnN0IGludGVybmFsS2V5ID0gZ2V0Q3J5cHRvS2V5KGtleSk7XG4gICAgICAgIGNvbnN0IGRhdGFWaWV3ID0gbmV3IFVpbnQ4QXJyYXkoZGF0YSk7XG4gICAgICAgIGNvbnN0IGtleVNpemUgPSBNYXRoLmNlaWwoaW50ZXJuYWxLZXkuYWxnb3JpdGhtLm1vZHVsdXNMZW5ndGggPj4gMyk7XG4gICAgICAgIGNvbnN0IGhhc2hTaXplID0gU2hhQ3J5cHRvLnNpemUoaW50ZXJuYWxLZXkuYWxnb3JpdGhtLmhhc2gpID4+IDM7XG4gICAgICAgIGNvbnN0IGRhdGFMZW5ndGggPSBkYXRhVmlldy5ieXRlTGVuZ3RoO1xuICAgICAgICBjb25zdCBwc0xlbmd0aCA9IGtleVNpemUgLSBkYXRhTGVuZ3RoIC0gMiAqIGhhc2hTaXplIC0gMjtcbiAgICAgICAgaWYgKGRhdGFMZW5ndGggPiBrZXlTaXplIC0gMiAqIGhhc2hTaXplIC0gMikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRGF0YSB0b28gbGFyZ2VcIik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbWVzc2FnZSA9IG5ldyBVaW50OEFycmF5KGtleVNpemUpO1xuICAgICAgICBjb25zdCBzZWVkID0gbWVzc2FnZS5zdWJhcnJheSgxLCBoYXNoU2l6ZSArIDEpO1xuICAgICAgICBjb25zdCBkYXRhQmxvY2sgPSBtZXNzYWdlLnN1YmFycmF5KGhhc2hTaXplICsgMSk7XG4gICAgICAgIGRhdGFCbG9jay5zZXQoZGF0YVZpZXcsIGhhc2hTaXplICsgcHNMZW5ndGggKyAxKTtcbiAgICAgICAgY29uc3QgbGFiZWxIYXNoID0gY3J5cHRvX19kZWZhdWx0LmNyZWF0ZUhhc2goaW50ZXJuYWxLZXkuYWxnb3JpdGhtLmhhc2gubmFtZS5yZXBsYWNlKFwiLVwiLCBcIlwiKSlcbiAgICAgICAgICAgIC51cGRhdGUoY29yZS5CdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9VaW50OEFycmF5KGFsZ29yaXRobS5sYWJlbCB8fCBuZXcgVWludDhBcnJheSgwKSkpXG4gICAgICAgICAgICAuZGlnZXN0KCk7XG4gICAgICAgIGRhdGFCbG9jay5zZXQobGFiZWxIYXNoLCAwKTtcbiAgICAgICAgZGF0YUJsb2NrW2hhc2hTaXplICsgcHNMZW5ndGhdID0gMTtcbiAgICAgICAgY3J5cHRvX19kZWZhdWx0LnJhbmRvbUZpbGxTeW5jKHNlZWQpO1xuICAgICAgICBjb25zdCBkYXRhQmxvY2tNYXNrID0gdGhpcy5tZ2YxKGludGVybmFsS2V5LmFsZ29yaXRobS5oYXNoLCBzZWVkLCBkYXRhQmxvY2subGVuZ3RoKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkYXRhQmxvY2subGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGRhdGFCbG9ja1tpXSBePSBkYXRhQmxvY2tNYXNrW2ldO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHNlZWRNYXNrID0gdGhpcy5tZ2YxKGludGVybmFsS2V5LmFsZ29yaXRobS5oYXNoLCBkYXRhQmxvY2ssIHNlZWQubGVuZ3RoKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBzZWVkW2ldIF49IHNlZWRNYXNrW2ldO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaW50ZXJuYWxLZXkucGVtKSB7XG4gICAgICAgICAgICBpbnRlcm5hbEtleS5wZW0gPSBgLS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS1cXG4ke2ludGVybmFsS2V5LmRhdGEudG9TdHJpbmcoXCJiYXNlNjRcIil9XFxuLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tYDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwa2NzMCA9IGNyeXB0b19fZGVmYXVsdC5wdWJsaWNFbmNyeXB0KHtcbiAgICAgICAgICAgIGtleTogaW50ZXJuYWxLZXkucGVtLFxuICAgICAgICAgICAgcGFkZGluZzogY3J5cHRvX19kZWZhdWx0LmNvbnN0YW50cy5SU0FfTk9fUEFERElORyxcbiAgICAgICAgfSwgQnVmZmVyLmZyb20obWVzc2FnZSkpO1xuICAgICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkocGtjczApLmJ1ZmZlcjtcbiAgICB9XG4gICAgYXN5bmMgb25EZWNyeXB0KGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIGNvbnN0IGludGVybmFsS2V5ID0gZ2V0Q3J5cHRvS2V5KGtleSk7XG4gICAgICAgIGNvbnN0IGtleVNpemUgPSBNYXRoLmNlaWwoaW50ZXJuYWxLZXkuYWxnb3JpdGhtLm1vZHVsdXNMZW5ndGggPj4gMyk7XG4gICAgICAgIGNvbnN0IGhhc2hTaXplID0gU2hhQ3J5cHRvLnNpemUoaW50ZXJuYWxLZXkuYWxnb3JpdGhtLmhhc2gpID4+IDM7XG4gICAgICAgIGNvbnN0IGRhdGFMZW5ndGggPSBkYXRhLmJ5dGVMZW5ndGg7XG4gICAgICAgIGlmIChkYXRhTGVuZ3RoICE9PSBrZXlTaXplKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJCYWQgZGF0YVwiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWludGVybmFsS2V5LnBlbSkge1xuICAgICAgICAgICAgaW50ZXJuYWxLZXkucGVtID0gYC0tLS0tQkVHSU4gUFJJVkFURSBLRVktLS0tLVxcbiR7aW50ZXJuYWxLZXkuZGF0YS50b1N0cmluZyhcImJhc2U2NFwiKX1cXG4tLS0tLUVORCBQUklWQVRFIEtFWS0tLS0tYDtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcGtjczAgPSBjcnlwdG9fX2RlZmF1bHQucHJpdmF0ZURlY3J5cHQoe1xuICAgICAgICAgICAga2V5OiBpbnRlcm5hbEtleS5wZW0sXG4gICAgICAgICAgICBwYWRkaW5nOiBjcnlwdG9fX2RlZmF1bHQuY29uc3RhbnRzLlJTQV9OT19QQURESU5HLFxuICAgICAgICB9LCBCdWZmZXIuZnJvbShkYXRhKSk7XG4gICAgICAgIGNvbnN0IHogPSBwa2NzMFswXTtcbiAgICAgICAgY29uc3Qgc2VlZCA9IHBrY3MwLnN1YmFycmF5KDEsIGhhc2hTaXplICsgMSk7XG4gICAgICAgIGNvbnN0IGRhdGFCbG9jayA9IHBrY3MwLnN1YmFycmF5KGhhc2hTaXplICsgMSk7XG4gICAgICAgIGlmICh6ICE9PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJEZWNyeXB0aW9uIGZhaWxlZFwiKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzZWVkTWFzayA9IHRoaXMubWdmMShpbnRlcm5hbEtleS5hbGdvcml0aG0uaGFzaCwgZGF0YUJsb2NrLCBzZWVkLmxlbmd0aCk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VlZC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgc2VlZFtpXSBePSBzZWVkTWFza1tpXTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBkYXRhQmxvY2tNYXNrID0gdGhpcy5tZ2YxKGludGVybmFsS2V5LmFsZ29yaXRobS5oYXNoLCBzZWVkLCBkYXRhQmxvY2subGVuZ3RoKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkYXRhQmxvY2subGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGRhdGFCbG9ja1tpXSBePSBkYXRhQmxvY2tNYXNrW2ldO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGxhYmVsSGFzaCA9IGNyeXB0b19fZGVmYXVsdC5jcmVhdGVIYXNoKGludGVybmFsS2V5LmFsZ29yaXRobS5oYXNoLm5hbWUucmVwbGFjZShcIi1cIiwgXCJcIikpXG4gICAgICAgICAgICAudXBkYXRlKGNvcmUuQnVmZmVyU291cmNlQ29udmVydGVyLnRvVWludDhBcnJheShhbGdvcml0aG0ubGFiZWwgfHwgbmV3IFVpbnQ4QXJyYXkoMCkpKVxuICAgICAgICAgICAgLmRpZ2VzdCgpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGhhc2hTaXplOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChsYWJlbEhhc2hbaV0gIT09IGRhdGFCbG9ja1tpXSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkRlY3J5cHRpb24gZmFpbGVkXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxldCBwc0VuZCA9IGhhc2hTaXplO1xuICAgICAgICBmb3IgKDsgcHNFbmQgPCBkYXRhQmxvY2subGVuZ3RoOyBwc0VuZCsrKSB7XG4gICAgICAgICAgICBjb25zdCBwc3ogPSBkYXRhQmxvY2tbcHNFbmRdO1xuICAgICAgICAgICAgaWYgKHBzeiA9PT0gMSkge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHBzeiAhPT0gMCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkRlY3J5cHRpb24gZmFpbGVkXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChwc0VuZCA9PT0gZGF0YUJsb2NrLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRGVjcnlwdGlvbiBmYWlsZWRcIik7XG4gICAgICAgIH1cbiAgICAgICAgcGtjczAgPSBkYXRhQmxvY2suc3ViYXJyYXkocHNFbmQgKyAxKTtcbiAgICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KHBrY3MwKS5idWZmZXI7XG4gICAgfVxuICAgIGFzeW5jIG9uRXhwb3J0S2V5KGZvcm1hdCwga2V5KSB7XG4gICAgICAgIHJldHVybiBSc2FDcnlwdG8uZXhwb3J0S2V5KGZvcm1hdCwgZ2V0Q3J5cHRvS2V5KGtleSkpO1xuICAgIH1cbiAgICBhc3luYyBvbkltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCBrZXkgPSBhd2FpdCBSc2FDcnlwdG8uaW1wb3J0S2V5KGZvcm1hdCwga2V5RGF0YSwgeyAuLi5hbGdvcml0aG0sIG5hbWU6IHRoaXMubmFtZSB9LCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgcmV0dXJuIHNldENyeXB0b0tleShrZXkpO1xuICAgIH1cbiAgICBjaGVja0NyeXB0b0tleShrZXksIGtleVVzYWdlKSB7XG4gICAgICAgIHN1cGVyLmNoZWNrQ3J5cHRvS2V5KGtleSwga2V5VXNhZ2UpO1xuICAgICAgICBjb25zdCBpbnRlcm5hbEtleSA9IGdldENyeXB0b0tleShrZXkpO1xuICAgICAgICBpZiAoIShpbnRlcm5hbEtleSBpbnN0YW5jZW9mIFJzYVByaXZhdGVLZXkgfHwgaW50ZXJuYWxLZXkgaW5zdGFuY2VvZiBSc2FQdWJsaWNLZXkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwia2V5OiBJcyBub3QgUlNBIENyeXB0b0tleVwiKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBtZ2YxKGFsZ29yaXRobSwgc2VlZCwgbGVuZ3RoID0gMCkge1xuICAgICAgICBjb25zdCBoYXNoU2l6ZSA9IFNoYUNyeXB0by5zaXplKGFsZ29yaXRobSkgPj4gMztcbiAgICAgICAgY29uc3QgbWFzayA9IG5ldyBVaW50OEFycmF5KGxlbmd0aCk7XG4gICAgICAgIGNvbnN0IGNvdW50ZXIgPSBuZXcgVWludDhBcnJheSg0KTtcbiAgICAgICAgY29uc3QgY2h1bmtzID0gTWF0aC5jZWlsKGxlbmd0aCAvIGhhc2hTaXplKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaHVua3M7IGkrKykge1xuICAgICAgICAgICAgY291bnRlclswXSA9IGkgPj4+IDI0O1xuICAgICAgICAgICAgY291bnRlclsxXSA9IChpID4+PiAxNikgJiAyNTU7XG4gICAgICAgICAgICBjb3VudGVyWzJdID0gKGkgPj4+IDgpICYgMjU1O1xuICAgICAgICAgICAgY291bnRlclszXSA9IGkgJiAyNTU7XG4gICAgICAgICAgICBjb25zdCBzdWJtYXNrID0gbWFzay5zdWJhcnJheShpICogaGFzaFNpemUpO1xuICAgICAgICAgICAgbGV0IGNodW5rID0gY3J5cHRvX19kZWZhdWx0LmNyZWF0ZUhhc2goYWxnb3JpdGhtLm5hbWUucmVwbGFjZShcIi1cIiwgXCJcIikpXG4gICAgICAgICAgICAgICAgLnVwZGF0ZShzZWVkKVxuICAgICAgICAgICAgICAgIC51cGRhdGUoY291bnRlcilcbiAgICAgICAgICAgICAgICAuZGlnZXN0KCk7XG4gICAgICAgICAgICBpZiAoY2h1bmsubGVuZ3RoID4gc3VibWFzay5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBjaHVuayA9IGNodW5rLnN1YmFycmF5KDAsIHN1Ym1hc2subGVuZ3RoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN1Ym1hc2suc2V0KGNodW5rKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWFzaztcbiAgICB9XG59XG5cbmNsYXNzIFJzYUVzUHJvdmlkZXIgZXh0ZW5kcyBjb3JlLlByb3ZpZGVyQ3J5cHRvIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJSU0FFUy1QS0NTMS12MV81XCI7XG4gICAgICAgIHRoaXMudXNhZ2VzID0ge1xuICAgICAgICAgICAgcHVibGljS2V5OiBbXCJlbmNyeXB0XCIsIFwid3JhcEtleVwiXSxcbiAgICAgICAgICAgIHByaXZhdGVLZXk6IFtcImRlY3J5cHRcIiwgXCJ1bndyYXBLZXlcIl0sXG4gICAgICAgIH07XG4gICAgfVxuICAgIGFzeW5jIG9uR2VuZXJhdGVLZXkoYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKSB7XG4gICAgICAgIGNvbnN0IGtleXMgPSBhd2FpdCBSc2FDcnlwdG8uZ2VuZXJhdGVLZXkoe1xuICAgICAgICAgICAgLi4uYWxnb3JpdGhtLFxuICAgICAgICAgICAgbmFtZTogdGhpcy5uYW1lLFxuICAgICAgICB9LCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHByaXZhdGVLZXk6IHNldENyeXB0b0tleShrZXlzLnByaXZhdGVLZXkpLFxuICAgICAgICAgICAgcHVibGljS2V5OiBzZXRDcnlwdG9LZXkoa2V5cy5wdWJsaWNLZXkpLFxuICAgICAgICB9O1xuICAgIH1cbiAgICBjaGVja0dlbmVyYXRlS2V5UGFyYW1zKGFsZ29yaXRobSkge1xuICAgICAgICB0aGlzLmNoZWNrUmVxdWlyZWRQcm9wZXJ0eShhbGdvcml0aG0sIFwicHVibGljRXhwb25lbnRcIik7XG4gICAgICAgIGlmICghKGFsZ29yaXRobS5wdWJsaWNFeHBvbmVudCAmJiBhbGdvcml0aG0ucHVibGljRXhwb25lbnQgaW5zdGFuY2VvZiBVaW50OEFycmF5KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInB1YmxpY0V4cG9uZW50OiBNaXNzaW5nIG9yIG5vdCBhIFVpbnQ4QXJyYXlcIik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcHVibGljRXhwb25lbnQgPSBDb252ZXJ0LlRvQmFzZTY0KGFsZ29yaXRobS5wdWJsaWNFeHBvbmVudCk7XG4gICAgICAgIGlmICghKHB1YmxpY0V4cG9uZW50ID09PSBcIkF3PT1cIiB8fCBwdWJsaWNFeHBvbmVudCA9PT0gXCJBUUFCXCIpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwicHVibGljRXhwb25lbnQ6IE11c3QgYmUgWzNdIG9yIFsxLDAsMV1cIik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jaGVja1JlcXVpcmVkUHJvcGVydHkoYWxnb3JpdGhtLCBcIm1vZHVsdXNMZW5ndGhcIik7XG4gICAgICAgIHN3aXRjaCAoYWxnb3JpdGhtLm1vZHVsdXNMZW5ndGgpIHtcbiAgICAgICAgICAgIGNhc2UgMTAyNDpcbiAgICAgICAgICAgIGNhc2UgMjA0ODpcbiAgICAgICAgICAgIGNhc2UgNDA5NjpcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIm1vZHVsdXNMZW5ndGg6IE11c3QgYmUgMTAyNCwgMjA0OCwgb3IgNDA5NlwiKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhc3luYyBvbkVuY3J5cHQoYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMudG9DcnlwdG9PcHRpb25zKGtleSk7XG4gICAgICAgIGNvbnN0IGVuYyA9IGNyeXB0by5wdWJsaWNFbmNyeXB0KG9wdGlvbnMsIG5ldyBVaW50OEFycmF5KGRhdGEpKTtcbiAgICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGVuYykuYnVmZmVyO1xuICAgIH1cbiAgICBhc3luYyBvbkRlY3J5cHQoYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMudG9DcnlwdG9PcHRpb25zKGtleSk7XG4gICAgICAgIGNvbnN0IGRlYyA9IGNyeXB0by5wcml2YXRlRGVjcnlwdChvcHRpb25zLCBuZXcgVWludDhBcnJheShkYXRhKSk7XG4gICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShkZWMpLmJ1ZmZlcjtcbiAgICB9XG4gICAgYXN5bmMgb25FeHBvcnRLZXkoZm9ybWF0LCBrZXkpIHtcbiAgICAgICAgcmV0dXJuIFJzYUNyeXB0by5leHBvcnRLZXkoZm9ybWF0LCBnZXRDcnlwdG9LZXkoa2V5KSk7XG4gICAgfVxuICAgIGFzeW5jIG9uSW1wb3J0S2V5KGZvcm1hdCwga2V5RGF0YSwgYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IGF3YWl0IFJzYUNyeXB0by5pbXBvcnRLZXkoZm9ybWF0LCBrZXlEYXRhLCB7IC4uLmFsZ29yaXRobSwgbmFtZTogdGhpcy5uYW1lIH0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpO1xuICAgICAgICByZXR1cm4gc2V0Q3J5cHRvS2V5KGtleSk7XG4gICAgfVxuICAgIGNoZWNrQ3J5cHRvS2V5KGtleSwga2V5VXNhZ2UpIHtcbiAgICAgICAgc3VwZXIuY2hlY2tDcnlwdG9LZXkoa2V5LCBrZXlVc2FnZSk7XG4gICAgICAgIGNvbnN0IGludGVybmFsS2V5ID0gZ2V0Q3J5cHRvS2V5KGtleSk7XG4gICAgICAgIGlmICghKGludGVybmFsS2V5IGluc3RhbmNlb2YgUnNhUHJpdmF0ZUtleSB8fCBpbnRlcm5hbEtleSBpbnN0YW5jZW9mIFJzYVB1YmxpY0tleSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJrZXk6IElzIG5vdCBSU0EgQ3J5cHRvS2V5XCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHRvQ3J5cHRvT3B0aW9ucyhrZXkpIHtcbiAgICAgICAgY29uc3QgdHlwZSA9IGtleS50eXBlLnRvVXBwZXJDYXNlKCk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBrZXk6IGAtLS0tLUJFR0lOICR7dHlwZX0gS0VZLS0tLS1cXG4ke2dldENyeXB0b0tleShrZXkpLmRhdGEudG9TdHJpbmcoXCJiYXNlNjRcIil9XFxuLS0tLS1FTkQgJHt0eXBlfSBLRVktLS0tLWAsXG4gICAgICAgICAgICBwYWRkaW5nOiBjcnlwdG8uY29uc3RhbnRzLlJTQV9QS0NTMV9QQURESU5HLFxuICAgICAgICB9O1xuICAgIH1cbn1cblxuY29uc3QgbmFtZWRPSURzID0ge1xuICAgIFwiMS4yLjg0MC4xMDA0NS4zLjEuN1wiOiBcIlAtMjU2XCIsXG4gICAgXCJQLTI1NlwiOiBcIjEuMi44NDAuMTAwNDUuMy4xLjdcIixcbiAgICBcIjEuMy4xMzIuMC4zNFwiOiBcIlAtMzg0XCIsXG4gICAgXCJQLTM4NFwiOiBcIjEuMy4xMzIuMC4zNFwiLFxuICAgIFwiMS4zLjEzMi4wLjM1XCI6IFwiUC01MjFcIixcbiAgICBcIlAtNTIxXCI6IFwiMS4zLjEzMi4wLjM1XCIsXG4gICAgXCIxLjMuMTMyLjAuMTBcIjogXCJLLTI1NlwiLFxuICAgIFwiSy0yNTZcIjogXCIxLjMuMTMyLjAuMTBcIixcbiAgICBcImJyYWlucG9vbFAxNjByMVwiOiBcIjEuMy4zNi4zLjMuMi44LjEuMS4xXCIsXG4gICAgXCIxLjMuMzYuMy4zLjIuOC4xLjEuMVwiOiBcImJyYWlucG9vbFAxNjByMVwiLFxuICAgIFwiYnJhaW5wb29sUDE2MHQxXCI6IFwiMS4zLjM2LjMuMy4yLjguMS4xLjJcIixcbiAgICBcIjEuMy4zNi4zLjMuMi44LjEuMS4yXCI6IFwiYnJhaW5wb29sUDE2MHQxXCIsXG4gICAgXCJicmFpbnBvb2xQMTkycjFcIjogXCIxLjMuMzYuMy4zLjIuOC4xLjEuM1wiLFxuICAgIFwiMS4zLjM2LjMuMy4yLjguMS4xLjNcIjogXCJicmFpbnBvb2xQMTkycjFcIixcbiAgICBcImJyYWlucG9vbFAxOTJ0MVwiOiBcIjEuMy4zNi4zLjMuMi44LjEuMS40XCIsXG4gICAgXCIxLjMuMzYuMy4zLjIuOC4xLjEuNFwiOiBcImJyYWlucG9vbFAxOTJ0MVwiLFxuICAgIFwiYnJhaW5wb29sUDIyNHIxXCI6IFwiMS4zLjM2LjMuMy4yLjguMS4xLjVcIixcbiAgICBcIjEuMy4zNi4zLjMuMi44LjEuMS41XCI6IFwiYnJhaW5wb29sUDIyNHIxXCIsXG4gICAgXCJicmFpbnBvb2xQMjI0dDFcIjogXCIxLjMuMzYuMy4zLjIuOC4xLjEuNlwiLFxuICAgIFwiMS4zLjM2LjMuMy4yLjguMS4xLjZcIjogXCJicmFpbnBvb2xQMjI0dDFcIixcbiAgICBcImJyYWlucG9vbFAyNTZyMVwiOiBcIjEuMy4zNi4zLjMuMi44LjEuMS43XCIsXG4gICAgXCIxLjMuMzYuMy4zLjIuOC4xLjEuN1wiOiBcImJyYWlucG9vbFAyNTZyMVwiLFxuICAgIFwiYnJhaW5wb29sUDI1NnQxXCI6IFwiMS4zLjM2LjMuMy4yLjguMS4xLjhcIixcbiAgICBcIjEuMy4zNi4zLjMuMi44LjEuMS44XCI6IFwiYnJhaW5wb29sUDI1NnQxXCIsXG4gICAgXCJicmFpbnBvb2xQMzIwcjFcIjogXCIxLjMuMzYuMy4zLjIuOC4xLjEuOVwiLFxuICAgIFwiMS4zLjM2LjMuMy4yLjguMS4xLjlcIjogXCJicmFpbnBvb2xQMzIwcjFcIixcbiAgICBcImJyYWlucG9vbFAzMjB0MVwiOiBcIjEuMy4zNi4zLjMuMi44LjEuMS4xMFwiLFxuICAgIFwiMS4zLjM2LjMuMy4yLjguMS4xLjEwXCI6IFwiYnJhaW5wb29sUDMyMHQxXCIsXG4gICAgXCJicmFpbnBvb2xQMzg0cjFcIjogXCIxLjMuMzYuMy4zLjIuOC4xLjEuMTFcIixcbiAgICBcIjEuMy4zNi4zLjMuMi44LjEuMS4xMVwiOiBcImJyYWlucG9vbFAzODRyMVwiLFxuICAgIFwiYnJhaW5wb29sUDM4NHQxXCI6IFwiMS4zLjM2LjMuMy4yLjguMS4xLjEyXCIsXG4gICAgXCIxLjMuMzYuMy4zLjIuOC4xLjEuMTJcIjogXCJicmFpbnBvb2xQMzg0dDFcIixcbiAgICBcImJyYWlucG9vbFA1MTJyMVwiOiBcIjEuMy4zNi4zLjMuMi44LjEuMS4xM1wiLFxuICAgIFwiMS4zLjM2LjMuMy4yLjguMS4xLjEzXCI6IFwiYnJhaW5wb29sUDUxMnIxXCIsXG4gICAgXCJicmFpbnBvb2xQNTEydDFcIjogXCIxLjMuMzYuMy4zLjIuOC4xLjEuMTRcIixcbiAgICBcIjEuMy4zNi4zLjMuMi44LjEuMS4xNFwiOiBcImJyYWlucG9vbFA1MTJ0MVwiLFxufTtcbmZ1bmN0aW9uIGdldE9pZEJ5TmFtZWRDdXJ2ZSQxKG5hbWVkQ3VydmUpIHtcbiAgICBjb25zdCBvaWQgPSBuYW1lZE9JRHNbbmFtZWRDdXJ2ZV07XG4gICAgaWYgKCFvaWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IGNvcmUuT3BlcmF0aW9uRXJyb3IoYENhbm5vdCBjb252ZXJ0IFdlYkNyeXB0byBuYW1lZCBjdXJ2ZSAnJHtuYW1lZEN1cnZlfScgdG8gT0lEYCk7XG4gICAgfVxuICAgIHJldHVybiBvaWQ7XG59XG5cbmNsYXNzIEVjUHJpdmF0ZUtleSBleHRlbmRzIEFzeW1tZXRyaWNLZXkge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLnR5cGUgPSBcInByaXZhdGVcIjtcbiAgICB9XG4gICAgZ2V0S2V5KCkge1xuICAgICAgICBjb25zdCBrZXlJbmZvID0gQXNuUGFyc2VyLnBhcnNlKHRoaXMuZGF0YSwgY29yZS5hc24xLlByaXZhdGVLZXlJbmZvKTtcbiAgICAgICAgcmV0dXJuIEFzblBhcnNlci5wYXJzZShrZXlJbmZvLnByaXZhdGVLZXksIGNvcmUuYXNuMS5FY1ByaXZhdGVLZXkpO1xuICAgIH1cbiAgICB0b0pTT04oKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IHRoaXMuZ2V0S2V5KCk7XG4gICAgICAgIGNvbnN0IGpzb24gPSB7XG4gICAgICAgICAgICBrdHk6IFwiRUNcIixcbiAgICAgICAgICAgIGNydjogdGhpcy5hbGdvcml0aG0ubmFtZWRDdXJ2ZSxcbiAgICAgICAgICAgIGtleV9vcHM6IHRoaXMudXNhZ2VzLFxuICAgICAgICAgICAgZXh0OiB0aGlzLmV4dHJhY3RhYmxlLFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihqc29uLCBKc29uU2VyaWFsaXplci50b0pTT04oa2V5KSk7XG4gICAgfVxuICAgIGZyb21KU09OKGpzb24pIHtcbiAgICAgICAgaWYgKCFqc29uLmNydikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IGNvcmUuT3BlcmF0aW9uRXJyb3IoYENhbm5vdCBnZXQgbmFtZWQgY3VydmUgZnJvbSBKV0suIFByb3BlcnR5ICdjcnYnIGlzIHJlcXVpcmVkYCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qga2V5SW5mbyA9IG5ldyBjb3JlLmFzbjEuUHJpdmF0ZUtleUluZm8oKTtcbiAgICAgICAga2V5SW5mby5wcml2YXRlS2V5QWxnb3JpdGhtLmFsZ29yaXRobSA9IFwiMS4yLjg0MC4xMDA0NS4yLjFcIjtcbiAgICAgICAga2V5SW5mby5wcml2YXRlS2V5QWxnb3JpdGhtLnBhcmFtZXRlcnMgPSBBc25TZXJpYWxpemVyLnNlcmlhbGl6ZShuZXcgY29yZS5hc24xLk9iamVjdElkZW50aWZpZXIoZ2V0T2lkQnlOYW1lZEN1cnZlJDEoanNvbi5jcnYpKSk7XG4gICAgICAgIGNvbnN0IGtleSA9IEpzb25QYXJzZXIuZnJvbUpTT04oanNvbiwgeyB0YXJnZXRTY2hlbWE6IGNvcmUuYXNuMS5FY1ByaXZhdGVLZXkgfSk7XG4gICAgICAgIGtleUluZm8ucHJpdmF0ZUtleSA9IEFzblNlcmlhbGl6ZXIuc2VyaWFsaXplKGtleSk7XG4gICAgICAgIHRoaXMuZGF0YSA9IEJ1ZmZlci5mcm9tKEFzblNlcmlhbGl6ZXIuc2VyaWFsaXplKGtleUluZm8pKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuXG5jbGFzcyBFY1B1YmxpY0tleSBleHRlbmRzIEFzeW1tZXRyaWNLZXkge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLnR5cGUgPSBcInB1YmxpY1wiO1xuICAgIH1cbiAgICBnZXRLZXkoKSB7XG4gICAgICAgIGNvbnN0IGtleUluZm8gPSBBc25QYXJzZXIucGFyc2UodGhpcy5kYXRhLCBjb3JlLmFzbjEuUHVibGljS2V5SW5mbyk7XG4gICAgICAgIHJldHVybiBuZXcgY29yZS5hc24xLkVjUHVibGljS2V5KGtleUluZm8ucHVibGljS2V5KTtcbiAgICB9XG4gICAgdG9KU09OKCkge1xuICAgICAgICBjb25zdCBrZXkgPSB0aGlzLmdldEtleSgpO1xuICAgICAgICBjb25zdCBqc29uID0ge1xuICAgICAgICAgICAga3R5OiBcIkVDXCIsXG4gICAgICAgICAgICBjcnY6IHRoaXMuYWxnb3JpdGhtLm5hbWVkQ3VydmUsXG4gICAgICAgICAgICBrZXlfb3BzOiB0aGlzLnVzYWdlcyxcbiAgICAgICAgICAgIGV4dDogdGhpcy5leHRyYWN0YWJsZSxcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oanNvbiwgSnNvblNlcmlhbGl6ZXIudG9KU09OKGtleSkpO1xuICAgIH1cbiAgICBmcm9tSlNPTihqc29uKSB7XG4gICAgICAgIGlmICghanNvbi5jcnYpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBjb3JlLk9wZXJhdGlvbkVycm9yKGBDYW5ub3QgZ2V0IG5hbWVkIGN1cnZlIGZyb20gSldLLiBQcm9wZXJ0eSAnY3J2JyBpcyByZXF1aXJlZGApO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGtleSA9IEpzb25QYXJzZXIuZnJvbUpTT04oanNvbiwgeyB0YXJnZXRTY2hlbWE6IGNvcmUuYXNuMS5FY1B1YmxpY0tleSB9KTtcbiAgICAgICAgY29uc3Qga2V5SW5mbyA9IG5ldyBjb3JlLmFzbjEuUHVibGljS2V5SW5mbygpO1xuICAgICAgICBrZXlJbmZvLnB1YmxpY0tleUFsZ29yaXRobS5hbGdvcml0aG0gPSBcIjEuMi44NDAuMTAwNDUuMi4xXCI7XG4gICAgICAgIGtleUluZm8ucHVibGljS2V5QWxnb3JpdGhtLnBhcmFtZXRlcnMgPSBBc25TZXJpYWxpemVyLnNlcmlhbGl6ZShuZXcgY29yZS5hc24xLk9iamVjdElkZW50aWZpZXIoZ2V0T2lkQnlOYW1lZEN1cnZlJDEoanNvbi5jcnYpKSk7XG4gICAgICAgIGtleUluZm8ucHVibGljS2V5ID0gQXNuU2VyaWFsaXplci50b0FTTihrZXkpLnZhbHVlSGV4O1xuICAgICAgICB0aGlzLmRhdGEgPSBCdWZmZXIuZnJvbShBc25TZXJpYWxpemVyLnNlcmlhbGl6ZShrZXlJbmZvKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cblxuY2xhc3MgU2hhMVByb3ZpZGVyIGV4dGVuZHMgY29yZS5Qcm92aWRlckNyeXB0byB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiU0hBLTFcIjtcbiAgICAgICAgdGhpcy51c2FnZXMgPSBbXTtcbiAgICB9XG4gICAgYXN5bmMgb25EaWdlc3QoYWxnb3JpdGhtLCBkYXRhKSB7XG4gICAgICAgIHJldHVybiBTaGFDcnlwdG8uZGlnZXN0KGFsZ29yaXRobSwgZGF0YSk7XG4gICAgfVxufVxuXG5jbGFzcyBTaGEyNTZQcm92aWRlciBleHRlbmRzIGNvcmUuUHJvdmlkZXJDcnlwdG8ge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlNIQS0yNTZcIjtcbiAgICAgICAgdGhpcy51c2FnZXMgPSBbXTtcbiAgICB9XG4gICAgYXN5bmMgb25EaWdlc3QoYWxnb3JpdGhtLCBkYXRhKSB7XG4gICAgICAgIHJldHVybiBTaGFDcnlwdG8uZGlnZXN0KGFsZ29yaXRobSwgZGF0YSk7XG4gICAgfVxufVxuXG5jbGFzcyBTaGEzODRQcm92aWRlciBleHRlbmRzIGNvcmUuUHJvdmlkZXJDcnlwdG8ge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlNIQS0zODRcIjtcbiAgICAgICAgdGhpcy51c2FnZXMgPSBbXTtcbiAgICB9XG4gICAgYXN5bmMgb25EaWdlc3QoYWxnb3JpdGhtLCBkYXRhKSB7XG4gICAgICAgIHJldHVybiBTaGFDcnlwdG8uZGlnZXN0KGFsZ29yaXRobSwgZGF0YSk7XG4gICAgfVxufVxuXG5jbGFzcyBTaGE1MTJQcm92aWRlciBleHRlbmRzIGNvcmUuUHJvdmlkZXJDcnlwdG8ge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlNIQS01MTJcIjtcbiAgICAgICAgdGhpcy51c2FnZXMgPSBbXTtcbiAgICB9XG4gICAgYXN5bmMgb25EaWdlc3QoYWxnb3JpdGhtLCBkYXRhKSB7XG4gICAgICAgIHJldHVybiBTaGFDcnlwdG8uZGlnZXN0KGFsZ29yaXRobSwgZGF0YSk7XG4gICAgfVxufVxuXG5jbGFzcyBTaGEzMjU2UHJvdmlkZXIgZXh0ZW5kcyBjb3JlLlByb3ZpZGVyQ3J5cHRvIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJTSEEzLTI1NlwiO1xuICAgICAgICB0aGlzLnVzYWdlcyA9IFtdO1xuICAgIH1cbiAgICBhc3luYyBvbkRpZ2VzdChhbGdvcml0aG0sIGRhdGEpIHtcbiAgICAgICAgcmV0dXJuIFNoYUNyeXB0by5kaWdlc3QoYWxnb3JpdGhtLCBkYXRhKTtcbiAgICB9XG59XG5cbmNsYXNzIFNoYTMzODRQcm92aWRlciBleHRlbmRzIGNvcmUuUHJvdmlkZXJDcnlwdG8ge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlNIQTMtMzg0XCI7XG4gICAgICAgIHRoaXMudXNhZ2VzID0gW107XG4gICAgfVxuICAgIGFzeW5jIG9uRGlnZXN0KGFsZ29yaXRobSwgZGF0YSkge1xuICAgICAgICByZXR1cm4gU2hhQ3J5cHRvLmRpZ2VzdChhbGdvcml0aG0sIGRhdGEpO1xuICAgIH1cbn1cblxuY2xhc3MgU2hhMzUxMlByb3ZpZGVyIGV4dGVuZHMgY29yZS5Qcm92aWRlckNyeXB0byB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiU0hBMy01MTJcIjtcbiAgICAgICAgdGhpcy51c2FnZXMgPSBbXTtcbiAgICB9XG4gICAgYXN5bmMgb25EaWdlc3QoYWxnb3JpdGhtLCBkYXRhKSB7XG4gICAgICAgIHJldHVybiBTaGFDcnlwdG8uZGlnZXN0KGFsZ29yaXRobSwgZGF0YSk7XG4gICAgfVxufVxuXG5jbGFzcyBFY0NyeXB0byB7XG4gICAgc3RhdGljIGFzeW5jIGdlbmVyYXRlS2V5KGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCBwcml2YXRlS2V5ID0gbmV3IEVjUHJpdmF0ZUtleSgpO1xuICAgICAgICBwcml2YXRlS2V5LmFsZ29yaXRobSA9IGFsZ29yaXRobTtcbiAgICAgICAgcHJpdmF0ZUtleS5leHRyYWN0YWJsZSA9IGV4dHJhY3RhYmxlO1xuICAgICAgICBwcml2YXRlS2V5LnVzYWdlcyA9IGtleVVzYWdlcy5maWx0ZXIoKHVzYWdlKSA9PiB0aGlzLnByaXZhdGVLZXlVc2FnZXMuaW5kZXhPZih1c2FnZSkgIT09IC0xKTtcbiAgICAgICAgY29uc3QgcHVibGljS2V5ID0gbmV3IEVjUHVibGljS2V5KCk7XG4gICAgICAgIHB1YmxpY0tleS5hbGdvcml0aG0gPSBhbGdvcml0aG07XG4gICAgICAgIHB1YmxpY0tleS5leHRyYWN0YWJsZSA9IHRydWU7XG4gICAgICAgIHB1YmxpY0tleS51c2FnZXMgPSBrZXlVc2FnZXMuZmlsdGVyKCh1c2FnZSkgPT4gdGhpcy5wdWJsaWNLZXlVc2FnZXMuaW5kZXhPZih1c2FnZSkgIT09IC0xKTtcbiAgICAgICAgY29uc3Qga2V5cyA9IGNyeXB0b19fZGVmYXVsdC5nZW5lcmF0ZUtleVBhaXJTeW5jKFwiZWNcIiwge1xuICAgICAgICAgICAgbmFtZWRDdXJ2ZTogdGhpcy5nZXRPcGVuU1NMTmFtZWRDdXJ2ZShhbGdvcml0aG0ubmFtZWRDdXJ2ZSksXG4gICAgICAgICAgICBwdWJsaWNLZXlFbmNvZGluZzoge1xuICAgICAgICAgICAgICAgIGZvcm1hdDogXCJkZXJcIixcbiAgICAgICAgICAgICAgICB0eXBlOiBcInNwa2lcIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBwcml2YXRlS2V5RW5jb2Rpbmc6IHtcbiAgICAgICAgICAgICAgICBmb3JtYXQ6IFwiZGVyXCIsXG4gICAgICAgICAgICAgICAgdHlwZTogXCJwa2NzOFwiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIHByaXZhdGVLZXkuZGF0YSA9IGtleXMucHJpdmF0ZUtleTtcbiAgICAgICAgcHVibGljS2V5LmRhdGEgPSBrZXlzLnB1YmxpY0tleTtcbiAgICAgICAgY29uc3QgcmVzID0ge1xuICAgICAgICAgICAgcHJpdmF0ZUtleSxcbiAgICAgICAgICAgIHB1YmxpY0tleSxcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG4gICAgc3RhdGljIGFzeW5jIHNpZ24oYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgY29uc3QgY3J5cHRvQWxnID0gU2hhQ3J5cHRvLmdldEFsZ29yaXRobU5hbWUoYWxnb3JpdGhtLmhhc2gpO1xuICAgICAgICBjb25zdCBzaWduZXIgPSBjcnlwdG9fX2RlZmF1bHQuY3JlYXRlU2lnbihjcnlwdG9BbGcpO1xuICAgICAgICBzaWduZXIudXBkYXRlKEJ1ZmZlci5mcm9tKGRhdGEpKTtcbiAgICAgICAgaWYgKCFrZXkucGVtKSB7XG4gICAgICAgICAgICBrZXkucGVtID0gYC0tLS0tQkVHSU4gUFJJVkFURSBLRVktLS0tLVxcbiR7a2V5LmRhdGEudG9TdHJpbmcoXCJiYXNlNjRcIil9XFxuLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLWA7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgIGtleToga2V5LnBlbSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgc2lnbmF0dXJlID0gc2lnbmVyLnNpZ24ob3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IGVjU2lnbmF0dXJlID0gQXNuUGFyc2VyLnBhcnNlKHNpZ25hdHVyZSwgY29yZS5hc24xLkVjRHNhU2lnbmF0dXJlKTtcbiAgICAgICAgY29uc3Qgc2lnbmF0dXJlUmF3ID0gY29yZS5FY1V0aWxzLmVuY29kZVNpZ25hdHVyZShlY1NpZ25hdHVyZSwgY29yZS5FY0N1cnZlcy5nZXQoa2V5LmFsZ29yaXRobS5uYW1lZEN1cnZlKS5zaXplKTtcbiAgICAgICAgcmV0dXJuIHNpZ25hdHVyZVJhdy5idWZmZXI7XG4gICAgfVxuICAgIHN0YXRpYyBhc3luYyB2ZXJpZnkoYWxnb3JpdGhtLCBrZXksIHNpZ25hdHVyZSwgZGF0YSkge1xuICAgICAgICBjb25zdCBjcnlwdG9BbGcgPSBTaGFDcnlwdG8uZ2V0QWxnb3JpdGhtTmFtZShhbGdvcml0aG0uaGFzaCk7XG4gICAgICAgIGNvbnN0IHNpZ25lciA9IGNyeXB0b19fZGVmYXVsdC5jcmVhdGVWZXJpZnkoY3J5cHRvQWxnKTtcbiAgICAgICAgc2lnbmVyLnVwZGF0ZShCdWZmZXIuZnJvbShkYXRhKSk7XG4gICAgICAgIGlmICgha2V5LnBlbSkge1xuICAgICAgICAgICAga2V5LnBlbSA9IGAtLS0tLUJFR0lOIFBVQkxJQyBLRVktLS0tLVxcbiR7a2V5LmRhdGEudG9TdHJpbmcoXCJiYXNlNjRcIil9XFxuLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tYDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAga2V5OiBrZXkucGVtLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBlY1NpZ25hdHVyZSA9IG5ldyBjb3JlLmFzbjEuRWNEc2FTaWduYXR1cmUoKTtcbiAgICAgICAgY29uc3QgbmFtZWRDdXJ2ZSA9IGNvcmUuRWNDdXJ2ZXMuZ2V0KGtleS5hbGdvcml0aG0ubmFtZWRDdXJ2ZSk7XG4gICAgICAgIGNvbnN0IHNpZ25hdHVyZVBvaW50ID0gY29yZS5FY1V0aWxzLmRlY29kZVNpZ25hdHVyZShzaWduYXR1cmUsIG5hbWVkQ3VydmUuc2l6ZSk7XG4gICAgICAgIGVjU2lnbmF0dXJlLnIgPSBCdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9BcnJheUJ1ZmZlcihzaWduYXR1cmVQb2ludC5yKTtcbiAgICAgICAgZWNTaWduYXR1cmUucyA9IEJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b0FycmF5QnVmZmVyKHNpZ25hdHVyZVBvaW50LnMpO1xuICAgICAgICBjb25zdCBlY1NpZ25hdHVyZVJhdyA9IEJ1ZmZlci5mcm9tKEFzblNlcmlhbGl6ZXIuc2VyaWFsaXplKGVjU2lnbmF0dXJlKSk7XG4gICAgICAgIGNvbnN0IG9rID0gc2lnbmVyLnZlcmlmeShvcHRpb25zLCBlY1NpZ25hdHVyZVJhdyk7XG4gICAgICAgIHJldHVybiBvaztcbiAgICB9XG4gICAgc3RhdGljIGFzeW5jIGRlcml2ZUJpdHMoYWxnb3JpdGhtLCBiYXNlS2V5LCBsZW5ndGgpIHtcbiAgICAgICAgY29uc3QgY3J5cHRvQWxnID0gdGhpcy5nZXRPcGVuU1NMTmFtZWRDdXJ2ZShiYXNlS2V5LmFsZ29yaXRobS5uYW1lZEN1cnZlKTtcbiAgICAgICAgY29uc3QgZWNkaCA9IGNyeXB0b19fZGVmYXVsdC5jcmVhdGVFQ0RIKGNyeXB0b0FsZyk7XG4gICAgICAgIGNvbnN0IGFzblByaXZhdGVLZXkgPSBBc25QYXJzZXIucGFyc2UoYmFzZUtleS5kYXRhLCBjb3JlLmFzbjEuUHJpdmF0ZUtleUluZm8pO1xuICAgICAgICBjb25zdCBhc25FY1ByaXZhdGVLZXkgPSBBc25QYXJzZXIucGFyc2UoYXNuUHJpdmF0ZUtleS5wcml2YXRlS2V5LCBjb3JlLmFzbjEuRWNQcml2YXRlS2V5KTtcbiAgICAgICAgZWNkaC5zZXRQcml2YXRlS2V5KEJ1ZmZlci5mcm9tKGFzbkVjUHJpdmF0ZUtleS5wcml2YXRlS2V5KSk7XG4gICAgICAgIGNvbnN0IGFzblB1YmxpY0tleSA9IEFzblBhcnNlci5wYXJzZShhbGdvcml0aG0ucHVibGljLmRhdGEsIGNvcmUuYXNuMS5QdWJsaWNLZXlJbmZvKTtcbiAgICAgICAgY29uc3QgYml0cyA9IGVjZGguY29tcHV0ZVNlY3JldChCdWZmZXIuZnJvbShhc25QdWJsaWNLZXkucHVibGljS2V5KSk7XG4gICAgICAgIGlmIChsZW5ndGggPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBiaXRzO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShiaXRzKS5idWZmZXIuc2xpY2UoMCwgbGVuZ3RoID4+IDMpO1xuICAgIH1cbiAgICBzdGF0aWMgYXN5bmMgZXhwb3J0S2V5KGZvcm1hdCwga2V5KSB7XG4gICAgICAgIHN3aXRjaCAoZm9ybWF0LnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICAgIGNhc2UgXCJqd2tcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gSnNvblNlcmlhbGl6ZXIudG9KU09OKGtleSk7XG4gICAgICAgICAgICBjYXNlIFwicGtjczhcIjpcbiAgICAgICAgICAgIGNhc2UgXCJzcGtpXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGtleS5kYXRhKS5idWZmZXI7XG4gICAgICAgICAgICBjYXNlIFwicmF3XCI6IHtcbiAgICAgICAgICAgICAgICBjb25zdCBwdWJsaWNLZXlJbmZvID0gQXNuUGFyc2VyLnBhcnNlKGtleS5kYXRhLCBjb3JlLmFzbjEuUHVibGljS2V5SW5mbyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHB1YmxpY0tleUluZm8ucHVibGljS2V5O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgY29yZS5PcGVyYXRpb25FcnJvcihcImZvcm1hdDogTXVzdCBiZSAnandrJywgJ3JhdycsIHBrY3M4JyBvciAnc3BraSdcIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIGFzeW5jIGltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBzd2l0Y2ggKGZvcm1hdC50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgICAgICBjYXNlIFwiandrXCI6IHtcbiAgICAgICAgICAgICAgICBjb25zdCBqd2sgPSBrZXlEYXRhO1xuICAgICAgICAgICAgICAgIGlmIChqd2suZCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhc25LZXkgPSBKc29uUGFyc2VyLmZyb21KU09OKGtleURhdGEsIHsgdGFyZ2V0U2NoZW1hOiBjb3JlLmFzbjEuRWNQcml2YXRlS2V5IH0pO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5pbXBvcnRQcml2YXRlS2V5KGFzbktleSwgYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFzbktleSA9IEpzb25QYXJzZXIuZnJvbUpTT04oa2V5RGF0YSwgeyB0YXJnZXRTY2hlbWE6IGNvcmUuYXNuMS5FY1B1YmxpY0tleSB9KTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW1wb3J0UHVibGljS2V5KGFzbktleSwgYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwicmF3XCI6IHtcbiAgICAgICAgICAgICAgICBjb25zdCBhc25LZXkgPSBuZXcgY29yZS5hc24xLkVjUHVibGljS2V5KGtleURhdGEpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmltcG9ydFB1YmxpY0tleShhc25LZXksIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwic3BraVwiOiB7XG4gICAgICAgICAgICAgICAgY29uc3Qga2V5SW5mbyA9IEFzblBhcnNlci5wYXJzZShuZXcgVWludDhBcnJheShrZXlEYXRhKSwgY29yZS5hc24xLlB1YmxpY0tleUluZm8pO1xuICAgICAgICAgICAgICAgIGNvbnN0IGFzbktleSA9IG5ldyBjb3JlLmFzbjEuRWNQdWJsaWNLZXkoa2V5SW5mby5wdWJsaWNLZXkpO1xuICAgICAgICAgICAgICAgIHRoaXMuYXNzZXJ0S2V5UGFyYW1ldGVycyhrZXlJbmZvLnB1YmxpY0tleUFsZ29yaXRobS5wYXJhbWV0ZXJzLCBhbGdvcml0aG0ubmFtZWRDdXJ2ZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW1wb3J0UHVibGljS2V5KGFzbktleSwgYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJwa2NzOFwiOiB7XG4gICAgICAgICAgICAgICAgY29uc3Qga2V5SW5mbyA9IEFzblBhcnNlci5wYXJzZShuZXcgVWludDhBcnJheShrZXlEYXRhKSwgY29yZS5hc24xLlByaXZhdGVLZXlJbmZvKTtcbiAgICAgICAgICAgICAgICBjb25zdCBhc25LZXkgPSBBc25QYXJzZXIucGFyc2Uoa2V5SW5mby5wcml2YXRlS2V5LCBjb3JlLmFzbjEuRWNQcml2YXRlS2V5KTtcbiAgICAgICAgICAgICAgICB0aGlzLmFzc2VydEtleVBhcmFtZXRlcnMoa2V5SW5mby5wcml2YXRlS2V5QWxnb3JpdGhtLnBhcmFtZXRlcnMsIGFsZ29yaXRobS5uYW1lZEN1cnZlKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5pbXBvcnRQcml2YXRlS2V5KGFzbktleSwgYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IGNvcmUuT3BlcmF0aW9uRXJyb3IoXCJmb3JtYXQ6IE11c3QgYmUgJ2p3aycsICdyYXcnLCAncGtjczgnIG9yICdzcGtpJ1wiKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzdGF0aWMgYXNzZXJ0S2V5UGFyYW1ldGVycyhwYXJhbWV0ZXJzLCBuYW1lZEN1cnZlKSB7XG4gICAgICAgIGlmICghcGFyYW1ldGVycykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IGNvcmUuQ3J5cHRvRXJyb3IoXCJLZXkgaW5mbyBkb2Vzbid0IGhhdmUgcmVxdWlyZWQgcGFyYW1ldGVyc1wiKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgbmFtZWRDdXJ2ZUlkZW50aWZpZXIgPSBcIlwiO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbmFtZWRDdXJ2ZUlkZW50aWZpZXIgPSBBc25QYXJzZXIucGFyc2UocGFyYW1ldGVycywgY29yZS5hc24xLk9iamVjdElkZW50aWZpZXIpLnZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgY29yZS5DcnlwdG9FcnJvcihcIkNhbm5vdCByZWFkIGtleSBpbmZvIHBhcmFtZXRlcnNcIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGdldE9pZEJ5TmFtZWRDdXJ2ZSQxKG5hbWVkQ3VydmUpICE9PSBuYW1lZEN1cnZlSWRlbnRpZmllcikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IGNvcmUuQ3J5cHRvRXJyb3IoXCJLZXkgaW5mbyBwYXJhbWV0ZXIgZG9lc24ndCBtYXRjaCB0byBuYW1lZCBjdXJ2ZVwiKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzdGF0aWMgYXN5bmMgaW1wb3J0UHJpdmF0ZUtleShhc25LZXksIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCBrZXlJbmZvID0gbmV3IGNvcmUuYXNuMS5Qcml2YXRlS2V5SW5mbygpO1xuICAgICAgICBrZXlJbmZvLnByaXZhdGVLZXlBbGdvcml0aG0uYWxnb3JpdGhtID0gXCIxLjIuODQwLjEwMDQ1LjIuMVwiO1xuICAgICAgICBrZXlJbmZvLnByaXZhdGVLZXlBbGdvcml0aG0ucGFyYW1ldGVycyA9IEFzblNlcmlhbGl6ZXIuc2VyaWFsaXplKG5ldyBjb3JlLmFzbjEuT2JqZWN0SWRlbnRpZmllcihnZXRPaWRCeU5hbWVkQ3VydmUkMShhbGdvcml0aG0ubmFtZWRDdXJ2ZSkpKTtcbiAgICAgICAga2V5SW5mby5wcml2YXRlS2V5ID0gQXNuU2VyaWFsaXplci5zZXJpYWxpemUoYXNuS2V5KTtcbiAgICAgICAgY29uc3Qga2V5ID0gbmV3IEVjUHJpdmF0ZUtleSgpO1xuICAgICAgICBrZXkuZGF0YSA9IEJ1ZmZlci5mcm9tKEFzblNlcmlhbGl6ZXIuc2VyaWFsaXplKGtleUluZm8pKTtcbiAgICAgICAga2V5LmFsZ29yaXRobSA9IE9iamVjdC5hc3NpZ24oe30sIGFsZ29yaXRobSk7XG4gICAgICAgIGtleS5leHRyYWN0YWJsZSA9IGV4dHJhY3RhYmxlO1xuICAgICAgICBrZXkudXNhZ2VzID0ga2V5VXNhZ2VzO1xuICAgICAgICByZXR1cm4ga2V5O1xuICAgIH1cbiAgICBzdGF0aWMgYXN5bmMgaW1wb3J0UHVibGljS2V5KGFzbktleSwgYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKSB7XG4gICAgICAgIGNvbnN0IGtleUluZm8gPSBuZXcgY29yZS5hc24xLlB1YmxpY0tleUluZm8oKTtcbiAgICAgICAga2V5SW5mby5wdWJsaWNLZXlBbGdvcml0aG0uYWxnb3JpdGhtID0gXCIxLjIuODQwLjEwMDQ1LjIuMVwiO1xuICAgICAgICBjb25zdCBuYW1lZEN1cnZlID0gZ2V0T2lkQnlOYW1lZEN1cnZlJDEoYWxnb3JpdGhtLm5hbWVkQ3VydmUpO1xuICAgICAgICBrZXlJbmZvLnB1YmxpY0tleUFsZ29yaXRobS5wYXJhbWV0ZXJzID0gQXNuU2VyaWFsaXplci5zZXJpYWxpemUobmV3IGNvcmUuYXNuMS5PYmplY3RJZGVudGlmaWVyKG5hbWVkQ3VydmUpKTtcbiAgICAgICAga2V5SW5mby5wdWJsaWNLZXkgPSBhc25LZXkudmFsdWU7XG4gICAgICAgIGNvbnN0IGtleSA9IG5ldyBFY1B1YmxpY0tleSgpO1xuICAgICAgICBrZXkuZGF0YSA9IEJ1ZmZlci5mcm9tKEFzblNlcmlhbGl6ZXIuc2VyaWFsaXplKGtleUluZm8pKTtcbiAgICAgICAga2V5LmFsZ29yaXRobSA9IE9iamVjdC5hc3NpZ24oe30sIGFsZ29yaXRobSk7XG4gICAgICAgIGtleS5leHRyYWN0YWJsZSA9IGV4dHJhY3RhYmxlO1xuICAgICAgICBrZXkudXNhZ2VzID0ga2V5VXNhZ2VzO1xuICAgICAgICByZXR1cm4ga2V5O1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0T3BlblNTTE5hbWVkQ3VydmUoY3VydmUpIHtcbiAgICAgICAgc3dpdGNoIChjdXJ2ZS50b1VwcGVyQ2FzZSgpKSB7XG4gICAgICAgICAgICBjYXNlIFwiUC0yNTZcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJwcmltZTI1NnYxXCI7XG4gICAgICAgICAgICBjYXNlIFwiSy0yNTZcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJzZWNwMjU2azFcIjtcbiAgICAgICAgICAgIGNhc2UgXCJQLTM4NFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcInNlY3AzODRyMVwiO1xuICAgICAgICAgICAgY2FzZSBcIlAtNTIxXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwic2VjcDUyMXIxXCI7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBjdXJ2ZTtcbiAgICAgICAgfVxuICAgIH1cbn1cbkVjQ3J5cHRvLnB1YmxpY0tleVVzYWdlcyA9IFtcInZlcmlmeVwiXTtcbkVjQ3J5cHRvLnByaXZhdGVLZXlVc2FnZXMgPSBbXCJzaWduXCIsIFwiZGVyaXZlS2V5XCIsIFwiZGVyaXZlQml0c1wiXTtcblxuY2xhc3MgRWNkc2FQcm92aWRlciBleHRlbmRzIGNvcmUuRWNkc2FQcm92aWRlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZWRDdXJ2ZXMgPSBjb3JlLkVjQ3VydmVzLm5hbWVzO1xuICAgICAgICB0aGlzLmhhc2hBbGdvcml0aG1zID0gW1xuICAgICAgICAgICAgXCJTSEEtMVwiLCBcIlNIQS0yNTZcIiwgXCJTSEEtMzg0XCIsIFwiU0hBLTUxMlwiLFxuICAgICAgICAgICAgXCJzaGFrZTEyOFwiLCBcInNoYWtlMjU2XCIsXG4gICAgICAgICAgICBcIlNIQTMtMjU2XCIsIFwiU0hBMy0zODRcIiwgXCJTSEEzLTUxMlwiXG4gICAgICAgIF07XG4gICAgfVxuICAgIGFzeW5jIG9uR2VuZXJhdGVLZXkoYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKSB7XG4gICAgICAgIGNvbnN0IGtleXMgPSBhd2FpdCBFY0NyeXB0by5nZW5lcmF0ZUtleSh7XG4gICAgICAgICAgICAuLi5hbGdvcml0aG0sXG4gICAgICAgICAgICBuYW1lOiB0aGlzLm5hbWUsXG4gICAgICAgIH0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcHJpdmF0ZUtleTogc2V0Q3J5cHRvS2V5KGtleXMucHJpdmF0ZUtleSksXG4gICAgICAgICAgICBwdWJsaWNLZXk6IHNldENyeXB0b0tleShrZXlzLnB1YmxpY0tleSksXG4gICAgICAgIH07XG4gICAgfVxuICAgIGFzeW5jIG9uU2lnbihhbGdvcml0aG0sIGtleSwgZGF0YSkge1xuICAgICAgICByZXR1cm4gRWNDcnlwdG8uc2lnbihhbGdvcml0aG0sIGdldENyeXB0b0tleShrZXkpLCBuZXcgVWludDhBcnJheShkYXRhKSk7XG4gICAgfVxuICAgIGFzeW5jIG9uVmVyaWZ5KGFsZ29yaXRobSwga2V5LCBzaWduYXR1cmUsIGRhdGEpIHtcbiAgICAgICAgcmV0dXJuIEVjQ3J5cHRvLnZlcmlmeShhbGdvcml0aG0sIGdldENyeXB0b0tleShrZXkpLCBuZXcgVWludDhBcnJheShzaWduYXR1cmUpLCBuZXcgVWludDhBcnJheShkYXRhKSk7XG4gICAgfVxuICAgIGFzeW5jIG9uRXhwb3J0S2V5KGZvcm1hdCwga2V5KSB7XG4gICAgICAgIHJldHVybiBFY0NyeXB0by5leHBvcnRLZXkoZm9ybWF0LCBnZXRDcnlwdG9LZXkoa2V5KSk7XG4gICAgfVxuICAgIGFzeW5jIG9uSW1wb3J0S2V5KGZvcm1hdCwga2V5RGF0YSwgYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IGF3YWl0IEVjQ3J5cHRvLmltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIHsgLi4uYWxnb3JpdGhtLCBuYW1lOiB0aGlzLm5hbWUgfSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcyk7XG4gICAgICAgIHJldHVybiBzZXRDcnlwdG9LZXkoa2V5KTtcbiAgICB9XG4gICAgY2hlY2tDcnlwdG9LZXkoa2V5LCBrZXlVc2FnZSkge1xuICAgICAgICBzdXBlci5jaGVja0NyeXB0b0tleShrZXksIGtleVVzYWdlKTtcbiAgICAgICAgY29uc3QgaW50ZXJuYWxLZXkgPSBnZXRDcnlwdG9LZXkoa2V5KTtcbiAgICAgICAgaWYgKCEoaW50ZXJuYWxLZXkgaW5zdGFuY2VvZiBFY1ByaXZhdGVLZXkgfHwgaW50ZXJuYWxLZXkgaW5zdGFuY2VvZiBFY1B1YmxpY0tleSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJrZXk6IElzIG5vdCBFQyBDcnlwdG9LZXlcIik7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmNsYXNzIEVjZGhQcm92aWRlciBleHRlbmRzIGNvcmUuRWNkaFByb3ZpZGVyIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lZEN1cnZlcyA9IGNvcmUuRWNDdXJ2ZXMubmFtZXM7XG4gICAgfVxuICAgIGFzeW5jIG9uR2VuZXJhdGVLZXkoYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKSB7XG4gICAgICAgIGNvbnN0IGtleXMgPSBhd2FpdCBFY0NyeXB0by5nZW5lcmF0ZUtleSh7XG4gICAgICAgICAgICAuLi5hbGdvcml0aG0sXG4gICAgICAgICAgICBuYW1lOiB0aGlzLm5hbWUsXG4gICAgICAgIH0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcHJpdmF0ZUtleTogc2V0Q3J5cHRvS2V5KGtleXMucHJpdmF0ZUtleSksXG4gICAgICAgICAgICBwdWJsaWNLZXk6IHNldENyeXB0b0tleShrZXlzLnB1YmxpY0tleSksXG4gICAgICAgIH07XG4gICAgfVxuICAgIGFzeW5jIG9uRXhwb3J0S2V5KGZvcm1hdCwga2V5KSB7XG4gICAgICAgIHJldHVybiBFY0NyeXB0by5leHBvcnRLZXkoZm9ybWF0LCBnZXRDcnlwdG9LZXkoa2V5KSk7XG4gICAgfVxuICAgIGFzeW5jIG9uSW1wb3J0S2V5KGZvcm1hdCwga2V5RGF0YSwgYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IGF3YWl0IEVjQ3J5cHRvLmltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIHsgLi4uYWxnb3JpdGhtLCBuYW1lOiB0aGlzLm5hbWUgfSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcyk7XG4gICAgICAgIHJldHVybiBzZXRDcnlwdG9LZXkoa2V5KTtcbiAgICB9XG4gICAgY2hlY2tDcnlwdG9LZXkoa2V5LCBrZXlVc2FnZSkge1xuICAgICAgICBzdXBlci5jaGVja0NyeXB0b0tleShrZXksIGtleVVzYWdlKTtcbiAgICAgICAgY29uc3QgaW50ZXJuYWxLZXkgPSBnZXRDcnlwdG9LZXkoa2V5KTtcbiAgICAgICAgaWYgKCEoaW50ZXJuYWxLZXkgaW5zdGFuY2VvZiBFY1ByaXZhdGVLZXkgfHwgaW50ZXJuYWxLZXkgaW5zdGFuY2VvZiBFY1B1YmxpY0tleSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJrZXk6IElzIG5vdCBFQyBDcnlwdG9LZXlcIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgYXN5bmMgb25EZXJpdmVCaXRzKGFsZ29yaXRobSwgYmFzZUtleSwgbGVuZ3RoKSB7XG4gICAgICAgIGNvbnN0IGJpdHMgPSBhd2FpdCBFY0NyeXB0by5kZXJpdmVCaXRzKHsgLi4uYWxnb3JpdGhtLCBwdWJsaWM6IGdldENyeXB0b0tleShhbGdvcml0aG0ucHVibGljKSB9LCBnZXRDcnlwdG9LZXkoYmFzZUtleSksIGxlbmd0aCk7XG4gICAgICAgIHJldHVybiBiaXRzO1xuICAgIH1cbn1cblxuY29uc3QgZWRPSURzID0ge1xuICAgIFtjb3JlLmFzbjEuaWRFZDQ0OF06IFwiRWQ0NDhcIixcbiAgICBcImVkNDQ4XCI6IGNvcmUuYXNuMS5pZEVkNDQ4LFxuICAgIFtjb3JlLmFzbjEuaWRYNDQ4XTogXCJYNDQ4XCIsXG4gICAgXCJ4NDQ4XCI6IGNvcmUuYXNuMS5pZFg0NDgsXG4gICAgW2NvcmUuYXNuMS5pZEVkMjU1MTldOiBcIkVkMjU1MTlcIixcbiAgICBcImVkMjU1MTlcIjogY29yZS5hc24xLmlkRWQyNTUxOSxcbiAgICBbY29yZS5hc24xLmlkWDI1NTE5XTogXCJYMjU1MTlcIixcbiAgICBcIngyNTUxOVwiOiBjb3JlLmFzbjEuaWRYMjU1MTksXG59O1xuZnVuY3Rpb24gZ2V0T2lkQnlOYW1lZEN1cnZlKG5hbWVkQ3VydmUpIHtcbiAgICBjb25zdCBvaWQgPSBlZE9JRHNbbmFtZWRDdXJ2ZS50b0xvd2VyQ2FzZSgpXTtcbiAgICBpZiAoIW9pZCkge1xuICAgICAgICB0aHJvdyBuZXcgY29yZS5PcGVyYXRpb25FcnJvcihgQ2Fubm90IGNvbnZlcnQgV2ViQ3J5cHRvIG5hbWVkIGN1cnZlICcke25hbWVkQ3VydmV9JyB0byBPSURgKTtcbiAgICB9XG4gICAgcmV0dXJuIG9pZDtcbn1cblxuY2xhc3MgRWRQcml2YXRlS2V5IGV4dGVuZHMgQXN5bW1ldHJpY0tleSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMudHlwZSA9IFwicHJpdmF0ZVwiO1xuICAgIH1cbiAgICBnZXRLZXkoKSB7XG4gICAgICAgIGNvbnN0IGtleUluZm8gPSBBc25QYXJzZXIucGFyc2UodGhpcy5kYXRhLCBjb3JlLmFzbjEuUHJpdmF0ZUtleUluZm8pO1xuICAgICAgICByZXR1cm4gQXNuUGFyc2VyLnBhcnNlKGtleUluZm8ucHJpdmF0ZUtleSwgY29yZS5hc24xLkN1cnZlUHJpdmF0ZUtleSk7XG4gICAgfVxuICAgIHRvSlNPTigpIHtcbiAgICAgICAgY29uc3Qga2V5ID0gdGhpcy5nZXRLZXkoKTtcbiAgICAgICAgY29uc3QganNvbiA9IHtcbiAgICAgICAgICAgIGt0eTogXCJPS1BcIixcbiAgICAgICAgICAgIGNydjogdGhpcy5hbGdvcml0aG0ubmFtZWRDdXJ2ZSxcbiAgICAgICAgICAgIGtleV9vcHM6IHRoaXMudXNhZ2VzLFxuICAgICAgICAgICAgZXh0OiB0aGlzLmV4dHJhY3RhYmxlLFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihqc29uLCBKc29uU2VyaWFsaXplci50b0pTT04oa2V5KSk7XG4gICAgfVxuICAgIGZyb21KU09OKGpzb24pIHtcbiAgICAgICAgaWYgKCFqc29uLmNydikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IGNvcmUuT3BlcmF0aW9uRXJyb3IoYENhbm5vdCBnZXQgbmFtZWQgY3VydmUgZnJvbSBKV0suIFByb3BlcnR5ICdjcnYnIGlzIHJlcXVpcmVkYCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qga2V5SW5mbyA9IG5ldyBjb3JlLmFzbjEuUHJpdmF0ZUtleUluZm8oKTtcbiAgICAgICAga2V5SW5mby5wcml2YXRlS2V5QWxnb3JpdGhtLmFsZ29yaXRobSA9IGdldE9pZEJ5TmFtZWRDdXJ2ZShqc29uLmNydik7XG4gICAgICAgIGNvbnN0IGtleSA9IEpzb25QYXJzZXIuZnJvbUpTT04oanNvbiwgeyB0YXJnZXRTY2hlbWE6IGNvcmUuYXNuMS5DdXJ2ZVByaXZhdGVLZXkgfSk7XG4gICAgICAgIGtleUluZm8ucHJpdmF0ZUtleSA9IEFzblNlcmlhbGl6ZXIuc2VyaWFsaXplKGtleSk7XG4gICAgICAgIHRoaXMuZGF0YSA9IEJ1ZmZlci5mcm9tKEFzblNlcmlhbGl6ZXIuc2VyaWFsaXplKGtleUluZm8pKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuXG5jbGFzcyBFZFB1YmxpY0tleSBleHRlbmRzIEFzeW1tZXRyaWNLZXkge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLnR5cGUgPSBcInB1YmxpY1wiO1xuICAgIH1cbiAgICBnZXRLZXkoKSB7XG4gICAgICAgIGNvbnN0IGtleUluZm8gPSBBc25QYXJzZXIucGFyc2UodGhpcy5kYXRhLCBjb3JlLmFzbjEuUHVibGljS2V5SW5mbyk7XG4gICAgICAgIHJldHVybiBrZXlJbmZvLnB1YmxpY0tleTtcbiAgICB9XG4gICAgdG9KU09OKCkge1xuICAgICAgICBjb25zdCBrZXkgPSB0aGlzLmdldEtleSgpO1xuICAgICAgICBjb25zdCBqc29uID0ge1xuICAgICAgICAgICAga3R5OiBcIk9LUFwiLFxuICAgICAgICAgICAgY3J2OiB0aGlzLmFsZ29yaXRobS5uYW1lZEN1cnZlLFxuICAgICAgICAgICAga2V5X29wczogdGhpcy51c2FnZXMsXG4gICAgICAgICAgICBleHQ6IHRoaXMuZXh0cmFjdGFibGUsXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKGpzb24sIHtcbiAgICAgICAgICAgIHg6IENvbnZlcnQuVG9CYXNlNjRVcmwoa2V5KVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZnJvbUpTT04oanNvbikge1xuICAgICAgICBpZiAoIWpzb24uY3J2KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgY29yZS5PcGVyYXRpb25FcnJvcihgQ2Fubm90IGdldCBuYW1lZCBjdXJ2ZSBmcm9tIEpXSy4gUHJvcGVydHkgJ2NydicgaXMgcmVxdWlyZWRgKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWpzb24ueCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IGNvcmUuT3BlcmF0aW9uRXJyb3IoYENhbm5vdCBnZXQgcHJvcGVydHkgZnJvbSBKV0suIFByb3BlcnR5ICd4JyBpcyByZXF1aXJlZGApO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGtleUluZm8gPSBuZXcgY29yZS5hc24xLlB1YmxpY0tleUluZm8oKTtcbiAgICAgICAga2V5SW5mby5wdWJsaWNLZXlBbGdvcml0aG0uYWxnb3JpdGhtID0gZ2V0T2lkQnlOYW1lZEN1cnZlKGpzb24uY3J2KTtcbiAgICAgICAga2V5SW5mby5wdWJsaWNLZXkgPSBDb252ZXJ0LkZyb21CYXNlNjRVcmwoanNvbi54KTtcbiAgICAgICAgdGhpcy5kYXRhID0gQnVmZmVyLmZyb20oQXNuU2VyaWFsaXplci5zZXJpYWxpemUoa2V5SW5mbykpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG5cbmNsYXNzIEVkQ3J5cHRvIHtcbiAgICBzdGF0aWMgYXN5bmMgZ2VuZXJhdGVLZXkoYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKSB7XG4gICAgICAgIGNvbnN0IHByaXZhdGVLZXkgPSBuZXcgRWRQcml2YXRlS2V5KCk7XG4gICAgICAgIHByaXZhdGVLZXkuYWxnb3JpdGhtID0gYWxnb3JpdGhtO1xuICAgICAgICBwcml2YXRlS2V5LmV4dHJhY3RhYmxlID0gZXh0cmFjdGFibGU7XG4gICAgICAgIHByaXZhdGVLZXkudXNhZ2VzID0ga2V5VXNhZ2VzLmZpbHRlcigodXNhZ2UpID0+IHRoaXMucHJpdmF0ZUtleVVzYWdlcy5pbmRleE9mKHVzYWdlKSAhPT0gLTEpO1xuICAgICAgICBjb25zdCBwdWJsaWNLZXkgPSBuZXcgRWRQdWJsaWNLZXkoKTtcbiAgICAgICAgcHVibGljS2V5LmFsZ29yaXRobSA9IGFsZ29yaXRobTtcbiAgICAgICAgcHVibGljS2V5LmV4dHJhY3RhYmxlID0gdHJ1ZTtcbiAgICAgICAgcHVibGljS2V5LnVzYWdlcyA9IGtleVVzYWdlcy5maWx0ZXIoKHVzYWdlKSA9PiB0aGlzLnB1YmxpY0tleVVzYWdlcy5pbmRleE9mKHVzYWdlKSAhPT0gLTEpO1xuICAgICAgICBjb25zdCB0eXBlID0gYWxnb3JpdGhtLm5hbWVkQ3VydmUudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgY29uc3Qga2V5cyA9IGNyeXB0b19fZGVmYXVsdC5nZW5lcmF0ZUtleVBhaXJTeW5jKHR5cGUsIHtcbiAgICAgICAgICAgIHB1YmxpY0tleUVuY29kaW5nOiB7XG4gICAgICAgICAgICAgICAgZm9ybWF0OiBcImRlclwiLFxuICAgICAgICAgICAgICAgIHR5cGU6IFwic3BraVwiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHByaXZhdGVLZXlFbmNvZGluZzoge1xuICAgICAgICAgICAgICAgIGZvcm1hdDogXCJkZXJcIixcbiAgICAgICAgICAgICAgICB0eXBlOiBcInBrY3M4XCIsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgICAgcHJpdmF0ZUtleS5kYXRhID0ga2V5cy5wcml2YXRlS2V5O1xuICAgICAgICBwdWJsaWNLZXkuZGF0YSA9IGtleXMucHVibGljS2V5O1xuICAgICAgICBjb25zdCByZXMgPSB7XG4gICAgICAgICAgICBwcml2YXRlS2V5LFxuICAgICAgICAgICAgcHVibGljS2V5LFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cbiAgICBzdGF0aWMgYXN5bmMgc2lnbihhbGdvcml0aG0sIGtleSwgZGF0YSkge1xuICAgICAgICBpZiAoIWtleS5wZW0pIHtcbiAgICAgICAgICAgIGtleS5wZW0gPSBgLS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tXFxuJHtrZXkuZGF0YS50b1N0cmluZyhcImJhc2U2NFwiKX1cXG4tLS0tLUVORCBQUklWQVRFIEtFWS0tLS0tYDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAga2V5OiBrZXkucGVtLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBzaWduYXR1cmUgPSBjcnlwdG9fX2RlZmF1bHQuc2lnbihudWxsLCBCdWZmZXIuZnJvbShkYXRhKSwgb3B0aW9ucyk7XG4gICAgICAgIHJldHVybiBjb3JlLkJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b0FycmF5QnVmZmVyKHNpZ25hdHVyZSk7XG4gICAgfVxuICAgIHN0YXRpYyBhc3luYyB2ZXJpZnkoYWxnb3JpdGhtLCBrZXksIHNpZ25hdHVyZSwgZGF0YSkge1xuICAgICAgICBpZiAoIWtleS5wZW0pIHtcbiAgICAgICAgICAgIGtleS5wZW0gPSBgLS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS1cXG4ke2tleS5kYXRhLnRvU3RyaW5nKFwiYmFzZTY0XCIpfVxcbi0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLWA7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgIGtleToga2V5LnBlbSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgb2sgPSBjcnlwdG9fX2RlZmF1bHQudmVyaWZ5KG51bGwsIEJ1ZmZlci5mcm9tKGRhdGEpLCBvcHRpb25zLCBCdWZmZXIuZnJvbShzaWduYXR1cmUpKTtcbiAgICAgICAgcmV0dXJuIG9rO1xuICAgIH1cbiAgICBzdGF0aWMgYXN5bmMgZGVyaXZlQml0cyhhbGdvcml0aG0sIGJhc2VLZXksIGxlbmd0aCkge1xuICAgICAgICBjb25zdCBwdWJsaWNLZXkgPSBjcnlwdG9fX2RlZmF1bHQuY3JlYXRlUHVibGljS2V5KHtcbiAgICAgICAgICAgIGtleTogYWxnb3JpdGhtLnB1YmxpYy5kYXRhLFxuICAgICAgICAgICAgZm9ybWF0OiBcImRlclwiLFxuICAgICAgICAgICAgdHlwZTogXCJzcGtpXCIsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBwcml2YXRlS2V5ID0gY3J5cHRvX19kZWZhdWx0LmNyZWF0ZVByaXZhdGVLZXkoe1xuICAgICAgICAgICAga2V5OiBiYXNlS2V5LmRhdGEsXG4gICAgICAgICAgICBmb3JtYXQ6IFwiZGVyXCIsXG4gICAgICAgICAgICB0eXBlOiBcInBrY3M4XCIsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBiaXRzID0gY3J5cHRvX19kZWZhdWx0LmRpZmZpZUhlbGxtYW4oe1xuICAgICAgICAgICAgcHVibGljS2V5LFxuICAgICAgICAgICAgcHJpdmF0ZUtleSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShiaXRzKS5idWZmZXIuc2xpY2UoMCwgbGVuZ3RoID4+IDMpO1xuICAgIH1cbiAgICBzdGF0aWMgYXN5bmMgZXhwb3J0S2V5KGZvcm1hdCwga2V5KSB7XG4gICAgICAgIHN3aXRjaCAoZm9ybWF0LnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICAgIGNhc2UgXCJqd2tcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gSnNvblNlcmlhbGl6ZXIudG9KU09OKGtleSk7XG4gICAgICAgICAgICBjYXNlIFwicGtjczhcIjpcbiAgICAgICAgICAgIGNhc2UgXCJzcGtpXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGtleS5kYXRhKS5idWZmZXI7XG4gICAgICAgICAgICBjYXNlIFwicmF3XCI6IHtcbiAgICAgICAgICAgICAgICBjb25zdCBwdWJsaWNLZXlJbmZvID0gQXNuUGFyc2VyLnBhcnNlKGtleS5kYXRhLCBjb3JlLmFzbjEuUHVibGljS2V5SW5mbyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHB1YmxpY0tleUluZm8ucHVibGljS2V5O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgY29yZS5PcGVyYXRpb25FcnJvcihcImZvcm1hdDogTXVzdCBiZSAnandrJywgJ3JhdycsIHBrY3M4JyBvciAnc3BraSdcIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIGFzeW5jIGltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBzd2l0Y2ggKGZvcm1hdC50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgICAgICBjYXNlIFwiandrXCI6IHtcbiAgICAgICAgICAgICAgICBjb25zdCBqd2sgPSBrZXlEYXRhO1xuICAgICAgICAgICAgICAgIGlmIChqd2suZCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhc25LZXkgPSBKc29uUGFyc2VyLmZyb21KU09OKGtleURhdGEsIHsgdGFyZ2V0U2NoZW1hOiBjb3JlLmFzbjEuQ3VydmVQcml2YXRlS2V5IH0pO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5pbXBvcnRQcml2YXRlS2V5KGFzbktleSwgYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghandrLngpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJrZXlEYXRhOiBDYW5ub3QgZ2V0IHJlcXVpcmVkICd4JyBmaWxlZFwiKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5pbXBvcnRQdWJsaWNLZXkoQ29udmVydC5Gcm9tQmFzZTY0VXJsKGp3ay54KSwgYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwicmF3XCI6IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5pbXBvcnRQdWJsaWNLZXkoa2V5RGF0YSwgYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJzcGtpXCI6IHtcbiAgICAgICAgICAgICAgICBjb25zdCBrZXlJbmZvID0gQXNuUGFyc2VyLnBhcnNlKG5ldyBVaW50OEFycmF5KGtleURhdGEpLCBjb3JlLmFzbjEuUHVibGljS2V5SW5mbyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW1wb3J0UHVibGljS2V5KGtleUluZm8ucHVibGljS2V5LCBhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInBrY3M4XCI6IHtcbiAgICAgICAgICAgICAgICBjb25zdCBrZXlJbmZvID0gQXNuUGFyc2VyLnBhcnNlKG5ldyBVaW50OEFycmF5KGtleURhdGEpLCBjb3JlLmFzbjEuUHJpdmF0ZUtleUluZm8pO1xuICAgICAgICAgICAgICAgIGNvbnN0IGFzbktleSA9IEFzblBhcnNlci5wYXJzZShrZXlJbmZvLnByaXZhdGVLZXksIGNvcmUuYXNuMS5DdXJ2ZVByaXZhdGVLZXkpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmltcG9ydFByaXZhdGVLZXkoYXNuS2V5LCBhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgY29yZS5PcGVyYXRpb25FcnJvcihcImZvcm1hdDogTXVzdCBiZSAnandrJywgJ3JhdycsICdwa2NzOCcgb3IgJ3Nwa2knXCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHN0YXRpYyBpbXBvcnRQcml2YXRlS2V5KGFzbktleSwgYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IG5ldyBFZFByaXZhdGVLZXkoKTtcbiAgICAgICAga2V5LmZyb21KU09OKHtcbiAgICAgICAgICAgIGNydjogYWxnb3JpdGhtLm5hbWVkQ3VydmUsXG4gICAgICAgICAgICBkOiBDb252ZXJ0LlRvQmFzZTY0VXJsKGFzbktleS5kKSxcbiAgICAgICAgfSk7XG4gICAgICAgIGtleS5hbGdvcml0aG0gPSBPYmplY3QuYXNzaWduKHt9LCBhbGdvcml0aG0pO1xuICAgICAgICBrZXkuZXh0cmFjdGFibGUgPSBleHRyYWN0YWJsZTtcbiAgICAgICAga2V5LnVzYWdlcyA9IGtleVVzYWdlcztcbiAgICAgICAgcmV0dXJuIGtleTtcbiAgICB9XG4gICAgc3RhdGljIGFzeW5jIGltcG9ydFB1YmxpY0tleShhc25LZXksIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCBrZXkgPSBuZXcgRWRQdWJsaWNLZXkoKTtcbiAgICAgICAga2V5LmZyb21KU09OKHtcbiAgICAgICAgICAgIGNydjogYWxnb3JpdGhtLm5hbWVkQ3VydmUsXG4gICAgICAgICAgICB4OiBDb252ZXJ0LlRvQmFzZTY0VXJsKGFzbktleSksXG4gICAgICAgIH0pO1xuICAgICAgICBrZXkuYWxnb3JpdGhtID0gT2JqZWN0LmFzc2lnbih7fSwgYWxnb3JpdGhtKTtcbiAgICAgICAga2V5LmV4dHJhY3RhYmxlID0gZXh0cmFjdGFibGU7XG4gICAgICAgIGtleS51c2FnZXMgPSBrZXlVc2FnZXM7XG4gICAgICAgIHJldHVybiBrZXk7XG4gICAgfVxufVxuRWRDcnlwdG8ucHVibGljS2V5VXNhZ2VzID0gW1widmVyaWZ5XCJdO1xuRWRDcnlwdG8ucHJpdmF0ZUtleVVzYWdlcyA9IFtcInNpZ25cIiwgXCJkZXJpdmVLZXlcIiwgXCJkZXJpdmVCaXRzXCJdO1xuXG5jbGFzcyBFZERzYVByb3ZpZGVyIGV4dGVuZHMgY29yZS5FZERzYVByb3ZpZGVyIHtcbiAgICBhc3luYyBvbkdlbmVyYXRlS2V5KGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCBrZXlzID0gYXdhaXQgRWRDcnlwdG8uZ2VuZXJhdGVLZXkoe1xuICAgICAgICAgICAgbmFtZTogdGhpcy5uYW1lLFxuICAgICAgICAgICAgbmFtZWRDdXJ2ZTogYWxnb3JpdGhtLm5hbWVkQ3VydmUucmVwbGFjZSgvXmVkL2ksIFwiRWRcIiksXG4gICAgICAgIH0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcHJpdmF0ZUtleTogc2V0Q3J5cHRvS2V5KGtleXMucHJpdmF0ZUtleSksXG4gICAgICAgICAgICBwdWJsaWNLZXk6IHNldENyeXB0b0tleShrZXlzLnB1YmxpY0tleSksXG4gICAgICAgIH07XG4gICAgfVxuICAgIGFzeW5jIG9uU2lnbihhbGdvcml0aG0sIGtleSwgZGF0YSkge1xuICAgICAgICByZXR1cm4gRWRDcnlwdG8uc2lnbihhbGdvcml0aG0sIGdldENyeXB0b0tleShrZXkpLCBuZXcgVWludDhBcnJheShkYXRhKSk7XG4gICAgfVxuICAgIGFzeW5jIG9uVmVyaWZ5KGFsZ29yaXRobSwga2V5LCBzaWduYXR1cmUsIGRhdGEpIHtcbiAgICAgICAgcmV0dXJuIEVkQ3J5cHRvLnZlcmlmeShhbGdvcml0aG0sIGdldENyeXB0b0tleShrZXkpLCBuZXcgVWludDhBcnJheShzaWduYXR1cmUpLCBuZXcgVWludDhBcnJheShkYXRhKSk7XG4gICAgfVxuICAgIGFzeW5jIG9uRXhwb3J0S2V5KGZvcm1hdCwga2V5KSB7XG4gICAgICAgIHJldHVybiBFZENyeXB0by5leHBvcnRLZXkoZm9ybWF0LCBnZXRDcnlwdG9LZXkoa2V5KSk7XG4gICAgfVxuICAgIGFzeW5jIG9uSW1wb3J0S2V5KGZvcm1hdCwga2V5RGF0YSwgYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IGF3YWl0IEVkQ3J5cHRvLmltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIHsgLi4uYWxnb3JpdGhtLCBuYW1lOiB0aGlzLm5hbWUgfSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcyk7XG4gICAgICAgIHJldHVybiBzZXRDcnlwdG9LZXkoa2V5KTtcbiAgICB9XG59XG5cbmNsYXNzIEVjZGhFc1Byb3ZpZGVyIGV4dGVuZHMgY29yZS5FY2RoRXNQcm92aWRlciB7XG4gICAgYXN5bmMgb25HZW5lcmF0ZUtleShhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgY29uc3Qga2V5cyA9IGF3YWl0IEVkQ3J5cHRvLmdlbmVyYXRlS2V5KHtcbiAgICAgICAgICAgIG5hbWU6IHRoaXMubmFtZSxcbiAgICAgICAgICAgIG5hbWVkQ3VydmU6IGFsZ29yaXRobS5uYW1lZEN1cnZlLnRvVXBwZXJDYXNlKCksXG4gICAgICAgIH0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcHJpdmF0ZUtleTogc2V0Q3J5cHRvS2V5KGtleXMucHJpdmF0ZUtleSksXG4gICAgICAgICAgICBwdWJsaWNLZXk6IHNldENyeXB0b0tleShrZXlzLnB1YmxpY0tleSksXG4gICAgICAgIH07XG4gICAgfVxuICAgIGFzeW5jIG9uRGVyaXZlQml0cyhhbGdvcml0aG0sIGJhc2VLZXksIGxlbmd0aCkge1xuICAgICAgICBjb25zdCBiaXRzID0gYXdhaXQgRWRDcnlwdG8uZGVyaXZlQml0cyh7IC4uLmFsZ29yaXRobSwgcHVibGljOiBnZXRDcnlwdG9LZXkoYWxnb3JpdGhtLnB1YmxpYykgfSwgZ2V0Q3J5cHRvS2V5KGJhc2VLZXkpLCBsZW5ndGgpO1xuICAgICAgICByZXR1cm4gYml0cztcbiAgICB9XG4gICAgYXN5bmMgb25FeHBvcnRLZXkoZm9ybWF0LCBrZXkpIHtcbiAgICAgICAgcmV0dXJuIEVkQ3J5cHRvLmV4cG9ydEtleShmb3JtYXQsIGdldENyeXB0b0tleShrZXkpKTtcbiAgICB9XG4gICAgYXN5bmMgb25JbXBvcnRLZXkoZm9ybWF0LCBrZXlEYXRhLCBhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgY29uc3Qga2V5ID0gYXdhaXQgRWRDcnlwdG8uaW1wb3J0S2V5KGZvcm1hdCwga2V5RGF0YSwgeyAuLi5hbGdvcml0aG0sIG5hbWU6IHRoaXMubmFtZSB9LCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgcmV0dXJuIHNldENyeXB0b0tleShrZXkpO1xuICAgIH1cbn1cblxuY2xhc3MgUGJrZGZDcnlwdG9LZXkgZXh0ZW5kcyBDcnlwdG9LZXkge1xufVxuXG5jbGFzcyBQYmtkZjJQcm92aWRlciBleHRlbmRzIGNvcmUuUGJrZGYyUHJvdmlkZXIge1xuICAgIGFzeW5jIG9uRGVyaXZlQml0cyhhbGdvcml0aG0sIGJhc2VLZXksIGxlbmd0aCkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc2FsdCA9IGNvcmUuQnVmZmVyU291cmNlQ29udmVydGVyLnRvQXJyYXlCdWZmZXIoYWxnb3JpdGhtLnNhbHQpO1xuICAgICAgICAgICAgY29uc3QgaGFzaCA9IGFsZ29yaXRobS5oYXNoLm5hbWUucmVwbGFjZShcIi1cIiwgXCJcIik7XG4gICAgICAgICAgICBjcnlwdG9fX2RlZmF1bHQucGJrZGYyKGdldENyeXB0b0tleShiYXNlS2V5KS5kYXRhLCBCdWZmZXIuZnJvbShzYWx0KSwgYWxnb3JpdGhtLml0ZXJhdGlvbnMsIGxlbmd0aCA+PiAzLCBoYXNoLCAoZXJyLCBkZXJpdmVkQml0cykgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKG5ldyBVaW50OEFycmF5KGRlcml2ZWRCaXRzKS5idWZmZXIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgYXN5bmMgb25JbXBvcnRLZXkoZm9ybWF0LCBrZXlEYXRhLCBhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgaWYgKGZvcm1hdCA9PT0gXCJyYXdcIikge1xuICAgICAgICAgICAgY29uc3Qga2V5ID0gbmV3IFBia2RmQ3J5cHRvS2V5KCk7XG4gICAgICAgICAgICBrZXkuZGF0YSA9IEJ1ZmZlci5mcm9tKGtleURhdGEpO1xuICAgICAgICAgICAga2V5LmFsZ29yaXRobSA9IHsgbmFtZTogdGhpcy5uYW1lIH07XG4gICAgICAgICAgICBrZXkuZXh0cmFjdGFibGUgPSBmYWxzZTtcbiAgICAgICAgICAgIGtleS51c2FnZXMgPSBrZXlVc2FnZXM7XG4gICAgICAgICAgICByZXR1cm4gc2V0Q3J5cHRvS2V5KGtleSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IGNvcmUuT3BlcmF0aW9uRXJyb3IoXCJmb3JtYXQ6IE11c3QgYmUgJ3JhdydcIik7XG4gICAgfVxuICAgIGNoZWNrQ3J5cHRvS2V5KGtleSwga2V5VXNhZ2UpIHtcbiAgICAgICAgc3VwZXIuY2hlY2tDcnlwdG9LZXkoa2V5LCBrZXlVc2FnZSk7XG4gICAgICAgIGlmICghKGdldENyeXB0b0tleShrZXkpIGluc3RhbmNlb2YgUGJrZGZDcnlwdG9LZXkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwia2V5OiBJcyBub3QgUEJLREYgQ3J5cHRvS2V5XCIpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5jbGFzcyBIbWFjQ3J5cHRvS2V5IGV4dGVuZHMgQ3J5cHRvS2V5IHtcbiAgICBnZXQgYWxnKCkge1xuICAgICAgICBjb25zdCBoYXNoID0gdGhpcy5hbGdvcml0aG0uaGFzaC5uYW1lLnRvVXBwZXJDYXNlKCk7XG4gICAgICAgIHJldHVybiBgSFMke2hhc2gucmVwbGFjZShcIlNIQS1cIiwgXCJcIil9YDtcbiAgICB9XG4gICAgc2V0IGFsZyh2YWx1ZSkge1xuICAgIH1cbn1cbl9fZGVjb3JhdGUoW1xuICAgIEpzb25Qcm9wKHsgbmFtZTogXCJrXCIsIGNvbnZlcnRlcjogSnNvbkJhc2U2NFVybENvbnZlcnRlciB9KVxuXSwgSG1hY0NyeXB0b0tleS5wcm90b3R5cGUsIFwiZGF0YVwiLCB2b2lkIDApO1xuXG5jbGFzcyBIbWFjUHJvdmlkZXIgZXh0ZW5kcyBjb3JlLkhtYWNQcm92aWRlciB7XG4gICAgYXN5bmMgb25HZW5lcmF0ZUtleShhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgY29uc3QgbGVuZ3RoID0gKGFsZ29yaXRobS5sZW5ndGggfHwgdGhpcy5nZXREZWZhdWx0TGVuZ3RoKGFsZ29yaXRobS5oYXNoLm5hbWUpKSA+PiAzIDw8IDM7XG4gICAgICAgIGNvbnN0IGtleSA9IG5ldyBIbWFjQ3J5cHRvS2V5KCk7XG4gICAgICAgIGtleS5hbGdvcml0aG0gPSB7XG4gICAgICAgICAgICAuLi5hbGdvcml0aG0sXG4gICAgICAgICAgICBsZW5ndGgsXG4gICAgICAgICAgICBuYW1lOiB0aGlzLm5hbWUsXG4gICAgICAgIH07XG4gICAgICAgIGtleS5leHRyYWN0YWJsZSA9IGV4dHJhY3RhYmxlO1xuICAgICAgICBrZXkudXNhZ2VzID0ga2V5VXNhZ2VzO1xuICAgICAgICBrZXkuZGF0YSA9IGNyeXB0b19fZGVmYXVsdC5yYW5kb21CeXRlcyhsZW5ndGggPj4gMyk7XG4gICAgICAgIHJldHVybiBzZXRDcnlwdG9LZXkoa2V5KTtcbiAgICB9XG4gICAgYXN5bmMgb25TaWduKGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIGNvbnN0IGNyeXB0b0FsZyA9IFNoYUNyeXB0by5nZXRBbGdvcml0aG1OYW1lKGtleS5hbGdvcml0aG0uaGFzaCk7XG4gICAgICAgIGNvbnN0IGhtYWMgPSBjcnlwdG9fX2RlZmF1bHQuY3JlYXRlSG1hYyhjcnlwdG9BbGcsIGdldENyeXB0b0tleShrZXkpLmRhdGEpXG4gICAgICAgICAgICAudXBkYXRlKEJ1ZmZlci5mcm9tKGRhdGEpKS5kaWdlc3QoKTtcbiAgICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGhtYWMpLmJ1ZmZlcjtcbiAgICB9XG4gICAgYXN5bmMgb25WZXJpZnkoYWxnb3JpdGhtLCBrZXksIHNpZ25hdHVyZSwgZGF0YSkge1xuICAgICAgICBjb25zdCBjcnlwdG9BbGcgPSBTaGFDcnlwdG8uZ2V0QWxnb3JpdGhtTmFtZShrZXkuYWxnb3JpdGhtLmhhc2gpO1xuICAgICAgICBjb25zdCBobWFjID0gY3J5cHRvX19kZWZhdWx0LmNyZWF0ZUhtYWMoY3J5cHRvQWxnLCBnZXRDcnlwdG9LZXkoa2V5KS5kYXRhKVxuICAgICAgICAgICAgLnVwZGF0ZShCdWZmZXIuZnJvbShkYXRhKSkuZGlnZXN0KCk7XG4gICAgICAgIHJldHVybiBobWFjLmNvbXBhcmUoQnVmZmVyLmZyb20oc2lnbmF0dXJlKSkgPT09IDA7XG4gICAgfVxuICAgIGFzeW5jIG9uSW1wb3J0S2V5KGZvcm1hdCwga2V5RGF0YSwgYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKSB7XG4gICAgICAgIGxldCBrZXk7XG4gICAgICAgIHN3aXRjaCAoZm9ybWF0LnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICAgIGNhc2UgXCJqd2tcIjpcbiAgICAgICAgICAgICAgICBrZXkgPSBKc29uUGFyc2VyLmZyb21KU09OKGtleURhdGEsIHsgdGFyZ2V0U2NoZW1hOiBIbWFjQ3J5cHRvS2V5IH0pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcInJhd1wiOlxuICAgICAgICAgICAgICAgIGtleSA9IG5ldyBIbWFjQ3J5cHRvS2V5KCk7XG4gICAgICAgICAgICAgICAga2V5LmRhdGEgPSBCdWZmZXIuZnJvbShrZXlEYXRhKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IGNvcmUuT3BlcmF0aW9uRXJyb3IoXCJmb3JtYXQ6IE11c3QgYmUgJ2p3aycgb3IgJ3JhdydcIik7XG4gICAgICAgIH1cbiAgICAgICAga2V5LmFsZ29yaXRobSA9IHtcbiAgICAgICAgICAgIGhhc2g6IHsgbmFtZTogYWxnb3JpdGhtLmhhc2gubmFtZSB9LFxuICAgICAgICAgICAgbmFtZTogdGhpcy5uYW1lLFxuICAgICAgICAgICAgbGVuZ3RoOiBrZXkuZGF0YS5sZW5ndGggPDwgMyxcbiAgICAgICAgfTtcbiAgICAgICAga2V5LmV4dHJhY3RhYmxlID0gZXh0cmFjdGFibGU7XG4gICAgICAgIGtleS51c2FnZXMgPSBrZXlVc2FnZXM7XG4gICAgICAgIHJldHVybiBzZXRDcnlwdG9LZXkoa2V5KTtcbiAgICB9XG4gICAgYXN5bmMgb25FeHBvcnRLZXkoZm9ybWF0LCBrZXkpIHtcbiAgICAgICAgc3dpdGNoIChmb3JtYXQudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgY2FzZSBcImp3a1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBKc29uU2VyaWFsaXplci50b0pTT04oZ2V0Q3J5cHRvS2V5KGtleSkpO1xuICAgICAgICAgICAgY2FzZSBcInJhd1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShnZXRDcnlwdG9LZXkoa2V5KS5kYXRhKS5idWZmZXI7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBjb3JlLk9wZXJhdGlvbkVycm9yKFwiZm9ybWF0OiBNdXN0IGJlICdqd2snIG9yICdyYXcnXCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGNoZWNrQ3J5cHRvS2V5KGtleSwga2V5VXNhZ2UpIHtcbiAgICAgICAgc3VwZXIuY2hlY2tDcnlwdG9LZXkoa2V5LCBrZXlVc2FnZSk7XG4gICAgICAgIGlmICghKGdldENyeXB0b0tleShrZXkpIGluc3RhbmNlb2YgSG1hY0NyeXB0b0tleSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJrZXk6IElzIG5vdCBITUFDIENyeXB0b0tleVwiKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuY2xhc3MgSGtkZkNyeXB0b0tleSBleHRlbmRzIENyeXB0b0tleSB7XG59XG5cbmNsYXNzIEhrZGZQcm92aWRlciBleHRlbmRzIGNvcmUuSGtkZlByb3ZpZGVyIHtcbiAgICBhc3luYyBvbkltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBpZiAoZm9ybWF0LnRvTG93ZXJDYXNlKCkgIT09IFwicmF3XCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBjb3JlLk9wZXJhdGlvbkVycm9yKFwiT3BlcmF0aW9uIG5vdCBzdXBwb3J0ZWRcIik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qga2V5ID0gbmV3IEhrZGZDcnlwdG9LZXkoKTtcbiAgICAgICAga2V5LmRhdGEgPSBCdWZmZXIuZnJvbShrZXlEYXRhKTtcbiAgICAgICAga2V5LmFsZ29yaXRobSA9IHsgbmFtZTogdGhpcy5uYW1lIH07XG4gICAgICAgIGtleS5leHRyYWN0YWJsZSA9IGV4dHJhY3RhYmxlO1xuICAgICAgICBrZXkudXNhZ2VzID0ga2V5VXNhZ2VzO1xuICAgICAgICByZXR1cm4gc2V0Q3J5cHRvS2V5KGtleSk7XG4gICAgfVxuICAgIGFzeW5jIG9uRGVyaXZlQml0cyhwYXJhbXMsIGJhc2VLZXksIGxlbmd0aCkge1xuICAgICAgICBjb25zdCBoYXNoID0gcGFyYW1zLmhhc2gubmFtZS5yZXBsYWNlKFwiLVwiLCBcIlwiKTtcbiAgICAgICAgY29uc3QgaGFzaExlbmd0aCA9IGNyeXB0b19fZGVmYXVsdC5jcmVhdGVIYXNoKGhhc2gpLmRpZ2VzdCgpLmxlbmd0aDtcbiAgICAgICAgY29uc3QgYnl0ZUxlbmd0aCA9IGxlbmd0aCAvIDg7XG4gICAgICAgIGNvbnN0IGluZm8gPSBCdWZmZXJTb3VyY2VDb252ZXJ0ZXIkMS50b1VpbnQ4QXJyYXkocGFyYW1zLmluZm8pO1xuICAgICAgICBjb25zdCBQUksgPSBjcnlwdG9fX2RlZmF1bHQuY3JlYXRlSG1hYyhoYXNoLCBCdWZmZXJTb3VyY2VDb252ZXJ0ZXIkMS50b1VpbnQ4QXJyYXkocGFyYW1zLnNhbHQpKVxuICAgICAgICAgICAgLnVwZGF0ZShCdWZmZXJTb3VyY2VDb252ZXJ0ZXIkMS50b1VpbnQ4QXJyYXkoZ2V0Q3J5cHRvS2V5KGJhc2VLZXkpLmRhdGEpKVxuICAgICAgICAgICAgLmRpZ2VzdCgpO1xuICAgICAgICBjb25zdCBibG9ja3MgPSBbQnVmZmVyLmFsbG9jKDApXTtcbiAgICAgICAgY29uc3QgYmxvY2tDb3VudCA9IE1hdGguY2VpbChieXRlTGVuZ3RoIC8gaGFzaExlbmd0aCkgKyAxO1xuICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IGJsb2NrQ291bnQ7ICsraSkge1xuICAgICAgICAgICAgYmxvY2tzLnB1c2goY3J5cHRvX19kZWZhdWx0LmNyZWF0ZUhtYWMoaGFzaCwgUFJLKVxuICAgICAgICAgICAgICAgIC51cGRhdGUoQnVmZmVyLmNvbmNhdChbYmxvY2tzW2kgLSAxXSwgaW5mbywgQnVmZmVyLmZyb20oW2ldKV0pKVxuICAgICAgICAgICAgICAgIC5kaWdlc3QoKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIEJ1ZmZlci5jb25jYXQoYmxvY2tzKS5zbGljZSgwLCBieXRlTGVuZ3RoKTtcbiAgICB9XG4gICAgY2hlY2tDcnlwdG9LZXkoa2V5LCBrZXlVc2FnZSkge1xuICAgICAgICBzdXBlci5jaGVja0NyeXB0b0tleShrZXksIGtleVVzYWdlKTtcbiAgICAgICAgaWYgKCEoZ2V0Q3J5cHRvS2V5KGtleSkgaW5zdGFuY2VvZiBIa2RmQ3J5cHRvS2V5KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImtleTogSXMgbm90IEhLREYgQ3J5cHRvS2V5XCIpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5jbGFzcyBTaGFrZUNyeXB0byB7XG4gICAgc3RhdGljIGRpZ2VzdChhbGdvcml0aG0sIGRhdGEpIHtcbiAgICAgICAgY29uc3QgaGFzaCA9IGNyeXB0b19fZGVmYXVsdC5jcmVhdGVIYXNoKGFsZ29yaXRobS5uYW1lLnRvTG93ZXJDYXNlKCksIHsgb3V0cHV0TGVuZ3RoOiBhbGdvcml0aG0ubGVuZ3RoIH0pXG4gICAgICAgICAgICAudXBkYXRlKEJ1ZmZlci5mcm9tKGRhdGEpKS5kaWdlc3QoKTtcbiAgICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGhhc2gpLmJ1ZmZlcjtcbiAgICB9XG59XG5cbmNsYXNzIFNoYWtlMTI4UHJvdmlkZXIgZXh0ZW5kcyBjb3JlLlNoYWtlMTI4UHJvdmlkZXIge1xuICAgIGFzeW5jIG9uRGlnZXN0KGFsZ29yaXRobSwgZGF0YSkge1xuICAgICAgICByZXR1cm4gU2hha2VDcnlwdG8uZGlnZXN0KGFsZ29yaXRobSwgZGF0YSk7XG4gICAgfVxufVxuXG5jbGFzcyBTaGFrZTI1NlByb3ZpZGVyIGV4dGVuZHMgY29yZS5TaGFrZTI1NlByb3ZpZGVyIHtcbiAgICBhc3luYyBvbkRpZ2VzdChhbGdvcml0aG0sIGRhdGEpIHtcbiAgICAgICAgcmV0dXJuIFNoYWtlQ3J5cHRvLmRpZ2VzdChhbGdvcml0aG0sIGRhdGEpO1xuICAgIH1cbn1cblxuY2xhc3MgU3VidGxlQ3J5cHRvIGV4dGVuZHMgY29yZS5TdWJ0bGVDcnlwdG8ge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB2YXIgX2E7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMucHJvdmlkZXJzLnNldChuZXcgQWVzQ2JjUHJvdmlkZXIoKSk7XG4gICAgICAgIHRoaXMucHJvdmlkZXJzLnNldChuZXcgQWVzQ3RyUHJvdmlkZXIoKSk7XG4gICAgICAgIHRoaXMucHJvdmlkZXJzLnNldChuZXcgQWVzR2NtUHJvdmlkZXIoKSk7XG4gICAgICAgIHRoaXMucHJvdmlkZXJzLnNldChuZXcgQWVzQ21hY1Byb3ZpZGVyKCkpO1xuICAgICAgICB0aGlzLnByb3ZpZGVycy5zZXQobmV3IEFlc0t3UHJvdmlkZXIoKSk7XG4gICAgICAgIHRoaXMucHJvdmlkZXJzLnNldChuZXcgQWVzRWNiUHJvdmlkZXIoKSk7XG4gICAgICAgIGNvbnN0IGNpcGhlcnMgPSBjcnlwdG8uZ2V0Q2lwaGVycygpO1xuICAgICAgICBpZiAoY2lwaGVycy5pbmNsdWRlcyhcImRlcy1jYmNcIikpIHtcbiAgICAgICAgICAgIHRoaXMucHJvdmlkZXJzLnNldChuZXcgRGVzQ2JjUHJvdmlkZXIoKSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5wcm92aWRlcnMuc2V0KG5ldyBEZXNFZGUzQ2JjUHJvdmlkZXIoKSk7XG4gICAgICAgIHRoaXMucHJvdmlkZXJzLnNldChuZXcgUnNhU3NhUHJvdmlkZXIoKSk7XG4gICAgICAgIHRoaXMucHJvdmlkZXJzLnNldChuZXcgUnNhUHNzUHJvdmlkZXIoKSk7XG4gICAgICAgIHRoaXMucHJvdmlkZXJzLnNldChuZXcgUnNhT2FlcFByb3ZpZGVyKCkpO1xuICAgICAgICB0aGlzLnByb3ZpZGVycy5zZXQobmV3IFJzYUVzUHJvdmlkZXIoKSk7XG4gICAgICAgIHRoaXMucHJvdmlkZXJzLnNldChuZXcgRWNkc2FQcm92aWRlcigpKTtcbiAgICAgICAgdGhpcy5wcm92aWRlcnMuc2V0KG5ldyBFY2RoUHJvdmlkZXIoKSk7XG4gICAgICAgIHRoaXMucHJvdmlkZXJzLnNldChuZXcgU2hhMVByb3ZpZGVyKCkpO1xuICAgICAgICB0aGlzLnByb3ZpZGVycy5zZXQobmV3IFNoYTI1NlByb3ZpZGVyKCkpO1xuICAgICAgICB0aGlzLnByb3ZpZGVycy5zZXQobmV3IFNoYTM4NFByb3ZpZGVyKCkpO1xuICAgICAgICB0aGlzLnByb3ZpZGVycy5zZXQobmV3IFNoYTUxMlByb3ZpZGVyKCkpO1xuICAgICAgICB0aGlzLnByb3ZpZGVycy5zZXQobmV3IFBia2RmMlByb3ZpZGVyKCkpO1xuICAgICAgICB0aGlzLnByb3ZpZGVycy5zZXQobmV3IEhtYWNQcm92aWRlcigpKTtcbiAgICAgICAgdGhpcy5wcm92aWRlcnMuc2V0KG5ldyBIa2RmUHJvdmlkZXIoKSk7XG4gICAgICAgIGNvbnN0IG5vZGVNYWpvclZlcnNpb24gPSAoX2EgPSAvXnYoXFxkKykvLmV4ZWMocHJvY2Vzcy52ZXJzaW9uKSkgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hWzFdO1xuICAgICAgICBpZiAobm9kZU1ham9yVmVyc2lvbiAmJiBwYXJzZUludChub2RlTWFqb3JWZXJzaW9uLCAxMCkgPj0gMTIpIHtcbiAgICAgICAgICAgIHRoaXMucHJvdmlkZXJzLnNldChuZXcgU2hha2UxMjhQcm92aWRlcigpKTtcbiAgICAgICAgICAgIHRoaXMucHJvdmlkZXJzLnNldChuZXcgU2hha2UyNTZQcm92aWRlcigpKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBoYXNoZXMgPSBjcnlwdG8uZ2V0SGFzaGVzKCk7XG4gICAgICAgIGlmIChoYXNoZXMuaW5jbHVkZXMoXCJzaGEzLTI1NlwiKSkge1xuICAgICAgICAgICAgdGhpcy5wcm92aWRlcnMuc2V0KG5ldyBTaGEzMjU2UHJvdmlkZXIoKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGhhc2hlcy5pbmNsdWRlcyhcInNoYTMtMzg0XCIpKSB7XG4gICAgICAgICAgICB0aGlzLnByb3ZpZGVycy5zZXQobmV3IFNoYTMzODRQcm92aWRlcigpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaGFzaGVzLmluY2x1ZGVzKFwic2hhMy01MTJcIikpIHtcbiAgICAgICAgICAgIHRoaXMucHJvdmlkZXJzLnNldChuZXcgU2hhMzUxMlByb3ZpZGVyKCkpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChub2RlTWFqb3JWZXJzaW9uICYmIHBhcnNlSW50KG5vZGVNYWpvclZlcnNpb24sIDEwKSA+PSAxNCkge1xuICAgICAgICAgICAgdGhpcy5wcm92aWRlcnMuc2V0KG5ldyBFZERzYVByb3ZpZGVyKCkpO1xuICAgICAgICAgICAgdGhpcy5wcm92aWRlcnMuc2V0KG5ldyBFY2RoRXNQcm92aWRlcigpKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuY2xhc3MgQ3J5cHRvIGV4dGVuZHMgY29yZS5DcnlwdG8ge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLnN1YnRsZSA9IG5ldyBTdWJ0bGVDcnlwdG8oKTtcbiAgICB9XG4gICAgZ2V0UmFuZG9tVmFsdWVzKGFycmF5KSB7XG4gICAgICAgIGlmICghQXJyYXlCdWZmZXIuaXNWaWV3KGFycmF5KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkZhaWxlZCB0byBleGVjdXRlICdnZXRSYW5kb21WYWx1ZXMnIG9uICdDcnlwdG8nOiBwYXJhbWV0ZXIgMSBpcyBub3Qgb2YgdHlwZSAnQXJyYXlCdWZmZXJWaWV3J1wiKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBidWZmZXIgPSBCdWZmZXIuZnJvbShhcnJheS5idWZmZXIsIGFycmF5LmJ5dGVPZmZzZXQsIGFycmF5LmJ5dGVMZW5ndGgpO1xuICAgICAgICBjcnlwdG9fX2RlZmF1bHQucmFuZG9tRmlsbFN5bmMoYnVmZmVyKTtcbiAgICAgICAgcmV0dXJuIGFycmF5O1xuICAgIH1cbn1cblxuZXhwb3J0IHsgQ3J5cHRvIH07XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBnZXRHbG9iYWwgfSBmcm9tIFwiLi4vdHlwZXMvZ2xvYmFsLm1qc1wiO1xuXG5leHBvcnQgeyByYW5kb20gfTtcblxuLyoqXG4gKiB0aGlzIGZ1bmN0aW9uIHVzZXMgY3J5cHQgYW5kIHJldHVybnMgYSByYW5kb20gbnVtYmVyLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBtaW4gc3RhcnRpbmcgdmFsdWUgb2YgdGhlIGRlZmluaXRpb24gc2V0IChkZWZhdWx0IGlzIDApXG4gKiBAcGFyYW0ge251bWJlcn0gbWF4IGVuZCB2YWx1ZSBvZiB0aGUgZGVmaW5pdGlvbiBzZXQgKGRlZmF1bHQgaXMgMTAwMDAwMDAwMClcbiAqIEByZXR1cm5zIHtudW1iZXJ9XG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5NYXRoXG4gKiBAdGhyb3dzIHtFcnJvcn0gbWlzc2luZyBjcnlwdFxuICogQHRocm93cyB7RXJyb3J9IHdlIGNhbm5vdCBnZW5lcmF0ZSBudW1iZXJzIGxhcmdlciB0aGFuIDUzIGJpdHMuXG4gKiBAdGhyb3dzIHtFcnJvcn0gdGhlIGRpc3RhbmNlIGlzIHRvbyBzbWFsbCB0byBjcmVhdGUgYSByYW5kb20gbnVtYmVyLlxuXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjAuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqL1xuZnVuY3Rpb24gcmFuZG9tKG1pbiwgbWF4KSB7XG4gICAgaWYgKG1pbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIG1pbiA9IDA7XG4gICAgfVxuICAgIGlmIChtYXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBtYXggPSBNQVg7XG4gICAgfVxuXG4gICAgaWYgKG1heCA8IG1pbikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJtYXggbXVzdCBiZSBncmVhdGVyIHRoYW4gbWluXCIpO1xuICAgIH1cblxuICAgIHJldHVybiBNYXRoLnJvdW5kKGNyZWF0ZShtaW4sIG1heCkpO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAdHlwZSB7bnVtYmVyfVxuICovXG52YXIgTUFYID0gMTAwMDAwMDAwMDtcblxuTWF0aC5sb2cyID1cbiAgICBNYXRoLmxvZzIgfHxcbiAgICBmdW5jdGlvbiAobikge1xuICAgICAgICByZXR1cm4gTWF0aC5sb2cobikgLyBNYXRoLmxvZygyKTtcbiAgICB9O1xuXG4vKipcbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gbWluXG4gKiBAcGFyYW0ge251bWJlcn0gbWF4XG4gKiBAcmV0dXJucyB7bnVtYmVyfVxuICogQHByaXZhdGVcbiAqIEB0aHJvd3Mge0Vycm9yfSBtaXNzaW5nIGNyeXB0XG4gKiBAdGhyb3dzIHtFcnJvcn0gd2UgY2Fubm90IGdlbmVyYXRlIG51bWJlcnMgbGFyZ2VyIHRoYW4gNTMgYml0cy5cbiAqIEB0aHJvd3Mge0Vycm9yfSB0aGUgZGlzdGFuY2UgaXMgdG9vIHNtYWxsIHRvIGNyZWF0ZSBhIHJhbmRvbSBudW1iZXIuXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZShtaW4sIG1heCkge1xuICAgIGxldCBjcnlwdDtcbiAgICBsZXQgZ2xvYmFsUmVmZXJlbmNlID0gZ2V0R2xvYmFsKCk7XG5cbiAgICBjcnlwdCA9IGdsb2JhbFJlZmVyZW5jZT8uW1wiY3J5cHRvXCJdIHx8IGdsb2JhbFJlZmVyZW5jZT8uW1wibXNDcnlwdG9cIl0gfHwgZ2xvYmFsUmVmZXJlbmNlPy5bXCJjcnlwdG9cIl0gfHwgdW5kZWZpbmVkO1xuXG4gICAgaWYgKHR5cGVvZiBjcnlwdCA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJtaXNzaW5nIGNyeXB0XCIpO1xuICAgIH1cblxuICAgIGxldCBydmFsID0gMDtcbiAgICBjb25zdCByYW5nZSA9IG1heCAtIG1pbjtcbiAgICBpZiAocmFuZ2UgPCAyKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcInRoZSBkaXN0YW5jZSBpcyB0b28gc21hbGwgdG8gY3JlYXRlIGEgcmFuZG9tIG51bWJlci5cIik7XG4gICAgfVxuXG4gICAgY29uc3QgYml0c05lZWRlZCA9IE1hdGguY2VpbChNYXRoLmxvZzIocmFuZ2UpKTtcbiAgICBpZiAoYml0c05lZWRlZCA+IDUzKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIndlIGNhbm5vdCBnZW5lcmF0ZSBudW1iZXJzIGxhcmdlciB0aGFuIDUzIGJpdHMuXCIpO1xuICAgIH1cbiAgICBjb25zdCBieXRlc05lZWRlZCA9IE1hdGguY2VpbChiaXRzTmVlZGVkIC8gOCk7XG4gICAgY29uc3QgbWFzayA9IE1hdGgucG93KDIsIGJpdHNOZWVkZWQpIC0gMTtcblxuICAgIGNvbnN0IGJ5dGVBcnJheSA9IG5ldyBVaW50OEFycmF5KGJ5dGVzTmVlZGVkKTtcbiAgICBjcnlwdC5nZXRSYW5kb21WYWx1ZXMoYnl0ZUFycmF5KTtcblxuICAgIGxldCBwID0gKGJ5dGVzTmVlZGVkIC0gMSkgKiA4O1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYnl0ZXNOZWVkZWQ7IGkrKykge1xuICAgICAgICBydmFsICs9IGJ5dGVBcnJheVtpXSAqIE1hdGgucG93KDIsIHApO1xuICAgICAgICBwIC09IDg7XG4gICAgfVxuXG4gICAgcnZhbCA9IHJ2YWwgJiBtYXNrO1xuXG4gICAgaWYgKHJ2YWwgPj0gcmFuZ2UpIHtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZShtaW4sIG1heCk7XG4gICAgfVxuXG4gICAgaWYgKHJ2YWwgPCBtaW4pIHtcbiAgICAgICAgcnZhbCArPSBtaW47XG4gICAgfVxuXG4gICAgcmV0dXJuIHJ2YWw7XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyByYW5kb20gfSBmcm9tIFwiLi4vbWF0aC9yYW5kb20ubWpzXCI7XG5pbXBvcnQgeyBnZXRHbG9iYWwgfSBmcm9tIFwiLi9nbG9iYWwubWpzXCI7XG5pbXBvcnQgeyBJRCB9IGZyb20gXCIuL2lkLm1qc1wiO1xuXG5leHBvcnQgeyBSYW5kb21JRCB9O1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAdHlwZSB7bnVtYmVyfVxuICovXG5sZXQgaW50ZXJuYWxDb3VudGVyID0gMDtcblxuLyoqXG4gKiBUaGUgYFJhbmRvbUlEYCBjbGFzcyBwcm92aWRlcyBhIHVuaXF1ZSBJRCBmb3IgYW4gaXRlbS5cbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjYuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKiBAc3VtbWFyeSBjbGFzcyB0byBnZW5lcmF0ZSByYW5kb20gbnVtYmVyc1xuICovXG5jbGFzcyBSYW5kb21JRCBleHRlbmRzIElEIHtcbiAgICAvKipcbiAgICAgKiBjcmVhdGUgbmV3IG9iamVjdFxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuXG4gICAgICAgIGludGVybmFsQ291bnRlciArPSAxO1xuXG4gICAgICAgIHRoaXMuaWQgPVxuICAgICAgICAgICAgZ2V0R2xvYmFsKClcbiAgICAgICAgICAgICAgICAuYnRvYShyYW5kb20oMSwgMTAwMDApKVxuICAgICAgICAgICAgICAgIC5yZXBsYWNlKC89L2csIFwiXCIpXG4gICAgICAgICAgICAgICAgLyoqIE5vIG51bWJlcnMgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgSUQsIGJlY2F1c2Ugb2YgcG9zc2libGUgcHJvYmxlbXMgd2l0aCBET00gKi9cbiAgICAgICAgICAgICAgICAucmVwbGFjZSgvXlswLTldKy8sIFwiWFwiKSArIGludGVybmFsQ291bnRlcjtcbiAgICB9XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBpbnRlcm5hbFN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQgeyByYW5kb20gfSBmcm9tIFwiLi4vbWF0aC9yYW5kb20ubWpzXCI7XG5pbXBvcnQgeyBpc09iamVjdCB9IGZyb20gXCIuLi90eXBlcy9pcy5tanNcIjtcbmltcG9ydCB7IEJhc2UgfSBmcm9tIFwiLi9iYXNlLm1qc1wiO1xuaW1wb3J0IHsgZ2V0R2xvYmFsT2JqZWN0IH0gZnJvbSBcIi4vZ2xvYmFsLm1qc1wiO1xuXG5leHBvcnQgeyBVVUlEIH07XG5cbi8qKlxuICogVGhlIFVVSUQgY2xhc3MgbWFrZXMgaXQgcG9zc2libGUgdG8gZ2V0IGEgdW5pcXVlIFVVSUQgZm9yIGFuIG9iamVjdC5cbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI1LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UeXBlc1xuICogQHRocm93cyB7RXJyb3J9IHVuc3VwcG9ydGVkXG4gKi9cbmNsYXNzIFVVSUQgZXh0ZW5kcyBCYXNlIHtcbiAgICAvKipcbiAgICAgKlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuXG4gICAgICAgIGxldCB1dWlkID0gY3JlYXRlV2l0aENyeXB0bygpO1xuXG4gICAgICAgIGlmICh1dWlkID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHV1aWQgPSBjcmVhdGVXaXRoUmFuZG9tKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodXVpZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1bnN1cHBvcnRlZFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXNbaW50ZXJuYWxTeW1ib2xdID0ge1xuICAgICAgICAgICAgdmFsdWU6IHV1aWQsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAgICovXG4gICAgdG9TdHJpbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzW2ludGVybmFsU3ltYm9sXVtcInZhbHVlXCJdO1xuICAgIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHJldHVybiB7c3RyaW5nfHVuZGVmaW5lZH1cbiAqL1xuZnVuY3Rpb24gY3JlYXRlV2l0aFJhbmRvbSgpIHtcbiAgICByZXR1cm4gXCJ4eHh4eHh4eC14eHh4LTR4eHgteXh4eC14eHh4eHh4eHh4eHhcIi5yZXBsYWNlKC9beHldL2csIGZ1bmN0aW9uIChjKSB7XG4gICAgICAgIGNvbnN0IHIgPSAocmFuZG9tKDAsIDY1MDAwKSAqIDE2KSB8IDA7XG4gICAgICAgIGNvbnN0IHYgPSBjID09PSBcInhcIiA/IHIgOiAociAmIDB4MykgfCAweDg7XG4gICAgICAgIHJldHVybiB2LnRvU3RyaW5nKDE2KVswXTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHJldHVybiB7c3RyaW5nfHVuZGVmaW5lZH1cbiAqL1xuZnVuY3Rpb24gY3JlYXRlV2l0aENyeXB0bygpIHtcbiAgICBjb25zdCBjcnlwdCA9IGdldEdsb2JhbE9iamVjdChcImNyeXB0b1wiKTtcbiAgICBpZiAoIWlzT2JqZWN0KGNyeXB0KSkgcmV0dXJuO1xuICAgIGlmICh0eXBlb2YgY3J5cHQ/LltcInJhbmRvbVVVSURcIl0pIHJldHVybjtcbiAgICByZXR1cm4gY3J5cHQucmFuZG9tVVVJRCgpO1xufVxuIiwgImlmICh0eXBlb2Ygd2luZG93ID09PSAnb2JqZWN0Jykge1xuXG4gICAgKGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBsZXQgc2F5c3dobyA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgdWEgPSBuYXZpZ2F0b3IudXNlckFnZW50LCB0ZW0sXG4gICAgICAgICAgICAgICAgTSA9IHVhLm1hdGNoKC8ob3BlcmF8Y2hyb21lfHNhZmFyaXxmaXJlZm94fG1zaWV8dHJpZGVudCg/PVxcLykpXFwvP1xccyooXFxkKykvaSkgfHwgW107XG4gICAgICAgICAgICBpZiAoL3RyaWRlbnQvaS50ZXN0KE1bMV0pKSB7XG4gICAgICAgICAgICAgICAgdGVtID0gL1xcYnJ2WyA6XSsoXFxkKykvZy5leGVjKHVhKSB8fCBbXTtcbiAgICAgICAgICAgICAgICByZXR1cm4gJ0lFICcgKyAodGVtWzFdIHx8ICcnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChNWzFdID09PSAnQ2hyb21lJykge1xuICAgICAgICAgICAgICAgIHRlbSA9IHVhLm1hdGNoKC9cXGIoT1BSfEVkZ2UpXFwvKFxcZCspLyk7XG4gICAgICAgICAgICAgICAgaWYgKHRlbSAhPSBudWxsKSByZXR1cm4gdGVtLnNsaWNlKDEpLmpvaW4oJyAnKS5yZXBsYWNlKCdPUFInLCAnT3BlcmEnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIE0gPSBNWzJdID8gW01bMV0sIE1bMl1dIDogW25hdmlnYXRvci5hcHBOYW1lLCBuYXZpZ2F0b3IuYXBwVmVyc2lvbiwgJy0/J107XG4gICAgICAgICAgICBpZiAoKHRlbSA9IHVhLm1hdGNoKC92ZXJzaW9uXFwvKFxcZCspL2kpKSAhPSBudWxsKSBNLnNwbGljZSgxLCAxLCB0ZW1bMV0pO1xuICAgICAgICAgICAgcmV0dXJuIE0uam9pbignICcpO1xuICAgICAgICB9KSgpO1xuXG5cbiAgICAgICAgbGV0IGVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdoMScpXG4gICAgICAgIGVsZW1lbnQuaW5uZXJIVE1MICs9IFwiIFwiICsgc2F5c3dobztcblxuICAgIH0pKCk7XG5cblxufVxuIiwgImltcG9ydCBjaGFpIGZyb20gJy4vaW5kZXguanMnO1xuXG5leHBvcnQgY29uc3QgZXhwZWN0ID0gY2hhaS5leHBlY3Q7XG5leHBvcnQgY29uc3QgdmVyc2lvbiA9IGNoYWkudmVyc2lvbjtcbmV4cG9ydCBjb25zdCBBc3NlcnRpb24gPSBjaGFpLkFzc2VydGlvbjtcbmV4cG9ydCBjb25zdCBBc3NlcnRpb25FcnJvciA9IGNoYWkuQXNzZXJ0aW9uRXJyb3I7XG5leHBvcnQgY29uc3QgdXRpbCA9IGNoYWkudXRpbDtcbmV4cG9ydCBjb25zdCBjb25maWcgPSBjaGFpLmNvbmZpZztcbmV4cG9ydCBjb25zdCB1c2UgPSBjaGFpLnVzZTtcbmV4cG9ydCBjb25zdCBzaG91bGQgPSBjaGFpLnNob3VsZDtcbmV4cG9ydCBjb25zdCBhc3NlcnQgPSBjaGFpLmFzc2VydDtcbmV4cG9ydCBjb25zdCBjb3JlID0gY2hhaS5jb3JlO1xuXG5leHBvcnQgZGVmYXVsdCBjaGFpO1xuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgQmFzZSB9IGZyb20gXCIuL2Jhc2UubWpzXCI7XG5pbXBvcnQgeyBpbnN0YW5jZVN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5cbmV4cG9ydCB7IFZlcnNpb24sIGdldE1vbnN0ZXJWZXJzaW9uIH07XG5cbi8qKlxuICogVGhlIHZlcnNpb24gb2JqZWN0IGNvbnRhaW5zIGEgc2VtYW50aWMgdmVyc2lvbiBudW1iZXJcbiAqXG4gKiBAZXh0ZXJuYWxFeGFtcGxlIC4uLy4uL2V4YW1wbGUvdHlwZXMvdmVyc2lvbi0xLm1qc1xuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4wLjBcbiAqIEBhdXRob3Igc2NodWthaSBHbWJIXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcbiAqIEBzdW1tYXJ5IFRoZSB2ZXJzaW9uIG9iamVjdCBjb250YWlucyBhIHNlbWF0aWMgdmVyc2lvbiBudW1iZXJcbiAqL1xuY2xhc3MgVmVyc2lvbiBleHRlbmRzIEJhc2Uge1xuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIG1ham9yXG4gICAgICogQHBhcmFtIG1pbm9yXG4gICAgICogQHBhcmFtIHBhdGNoXG4gICAgICogQHRocm93cyB7RXJyb3J9IG1ham9yIGlzIG5vdCBhIG51bWJlclxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBtaW5vciBpcyBub3QgYSBudW1iZXJcbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gcGF0Y2ggaXMgbm90IGEgbnVtYmVyXG4gICAgICovXG4gICAgY29uc3RydWN0b3IobWFqb3IsIG1pbm9yLCBwYXRjaCkge1xuICAgICAgICBzdXBlcigpO1xuXG4gICAgICAgIGlmICh0eXBlb2YgbWFqb3IgPT09IFwic3RyaW5nXCIgJiYgbWlub3IgPT09IHVuZGVmaW5lZCAmJiBwYXRjaCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBsZXQgcGFydHMgPSBtYWpvci50b1N0cmluZygpLnNwbGl0KFwiLlwiKTtcbiAgICAgICAgICAgIG1ham9yID0gcGFyc2VJbnQocGFydHNbMF0gfHwgMCk7XG4gICAgICAgICAgICBtaW5vciA9IHBhcnNlSW50KHBhcnRzWzFdIHx8IDApO1xuICAgICAgICAgICAgcGF0Y2ggPSBwYXJzZUludChwYXJ0c1syXSB8fCAwKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChtYWpvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJtYWpvciB2ZXJzaW9uIGlzIHVuZGVmaW5lZFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChtaW5vciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBtaW5vciA9IDA7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocGF0Y2ggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcGF0Y2ggPSAwO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5tYWpvciA9IHBhcnNlSW50KG1ham9yKTtcbiAgICAgICAgdGhpcy5taW5vciA9IHBhcnNlSW50KG1pbm9yKTtcbiAgICAgICAgdGhpcy5wYXRjaCA9IHBhcnNlSW50KHBhdGNoKTtcblxuICAgICAgICBpZiAoaXNOYU4odGhpcy5tYWpvcikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIm1ham9yIGlzIG5vdCBhIG51bWJlclwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc05hTih0aGlzLm1pbm9yKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwibWlub3IgaXMgbm90IGEgbnVtYmVyXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzTmFOKHRoaXMucGF0Y2gpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJwYXRjaCBpcyBub3QgYSBudW1iZXJcIik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGBpbnN0YW5jZW9mYCBvcGVyYXRvci5cbiAgICAgKiBAcmV0dXJucyB7c3ltYm9sfVxuICAgICAqIEBzaW5jZSAyLjEuMFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgW2luc3RhbmNlU3ltYm9sXSgpIHtcbiAgICAgICAgcmV0dXJuIFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL3R5cGVzL3ZlcnNpb25cIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgICAqL1xuICAgIHRvU3RyaW5nKCkge1xuICAgICAgICByZXR1cm4gYCR7dGhpcy5tYWpvcn0uJHt0aGlzLm1pbm9yfS4ke3RoaXMucGF0Y2h9YDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiByZXR1cm5zIDAgaWYgZXF1YWwsIC0xIGlmIHRoZSBvYmplY3QgdmVyc2lvbiBpcyBsZXNzIGFuZCAxIGlmIGdyZWF0ZXJcbiAgICAgKiB0aGFuIHRoZSBjb21wYXJlZCB2ZXJzaW9uXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xWZXJzaW9ufSB2ZXJzaW9uIFZlcnNpb24gdG8gY29tcGFyZVxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9XG4gICAgICovXG4gICAgY29tcGFyZVRvKHZlcnNpb24pIHtcbiAgICAgICAgaWYgKHZlcnNpb24gaW5zdGFuY2VvZiBWZXJzaW9uKSB7XG4gICAgICAgICAgICB2ZXJzaW9uID0gdmVyc2lvbi50b1N0cmluZygpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiB2ZXJzaW9uICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0eXBlIGV4Y2VwdGlvblwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh2ZXJzaW9uID09PSB0aGlzLnRvU3RyaW5nKCkpIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGEgPSBbdGhpcy5tYWpvciwgdGhpcy5taW5vciwgdGhpcy5wYXRjaF07XG4gICAgICAgIGxldCBiID0gdmVyc2lvbi5zcGxpdChcIi5cIik7XG4gICAgICAgIGxldCBsZW4gPSBNYXRoLm1heChhLmxlbmd0aCwgYi5sZW5ndGgpO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGlmICgoYVtpXSAmJiAhYltpXSAmJiBwYXJzZUludChhW2ldKSA+IDApIHx8IHBhcnNlSW50KGFbaV0pID4gcGFyc2VJbnQoYltpXSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoKGJbaV0gJiYgIWFbaV0gJiYgcGFyc2VJbnQoYltpXSkgPiAwKSB8fCBwYXJzZUludChhW2ldKSA8IHBhcnNlSW50KGJbaV0pKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxufVxuXG5sZXQgbW9uc3RlclZlcnNpb247XG5cbi8qKlxuICogVmVyc2lvbiBvZiBtb25zdGVyXG4gKlxuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL3R5cGVzL3ZlcnNpb24tMi5tanNcbiAqIEByZXR1cm5zIHtNb25zdGVyLlR5cGVzLlZlcnNpb259XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjAuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBhdXRob3Igc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3RlclxuICovXG5mdW5jdGlvbiBnZXRNb25zdGVyVmVyc2lvbigpIHtcbiAgICBpZiAobW9uc3RlclZlcnNpb24gaW5zdGFuY2VvZiBWZXJzaW9uKSB7XG4gICAgICAgIHJldHVybiBtb25zdGVyVmVyc2lvbjtcbiAgICB9XG5cbiAgICAvKiogZG9uJ3QgdG91Y2gsIHJlcGxhY2VkIGJ5IG1ha2Ugd2l0aCBwYWNrYWdlLmpzb24gdmVyc2lvbiAqL1xuICAgIG1vbnN0ZXJWZXJzaW9uID0gbmV3IFZlcnNpb24oXCIzLjM1LjRcIik7XG5cbiAgICByZXR1cm4gbW9uc3RlclZlcnNpb247XG59XG4iLCAiaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7VmVyc2lvbiwgZ2V0TW9uc3RlclZlcnNpb259IGZyb20gXCIuLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdHlwZXMvdmVyc2lvbi5tanNcIjtcblxuZGVzY3JpYmUoJ01vbnN0ZXInLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBkZXNjcmliZSgnLmdldE1vbnN0ZXJWZXJzaW9uKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCBtb25zdGVyVmVyc2lvblxuXG4gICAgICAgIC8qKiBkb25cdTAwQjR0IHRvdWNoLCByZXBsYWNlZCBieSBtYWtlIHdpdGggcGFja2FnZS5qc29uIHZlcnNpb24gKi9cbiAgICAgICAgbW9uc3RlclZlcnNpb24gPSBuZXcgVmVyc2lvbihcIjMuMzUuNFwiKVxuXG4gICAgICAgIGxldCBtID0gZ2V0TW9uc3RlclZlcnNpb24oKTtcblxuICAgICAgICBpdCgnc2hvdWxkICcgKyBtb25zdGVyVmVyc2lvbiArICcgaXMgJyArIG0sIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChtLmNvbXBhcmVUbyhtb25zdGVyVmVyc2lvbikpLmlzLmVxdWFsKDApO1xuICAgICAgICB9KTtcblxuICAgIH0pO1xuXG59KTtcbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IEJhc2UgfSBmcm9tIFwiLi4vdHlwZXMvYmFzZS5tanNcIjtcbmltcG9ydCB7IHZhbGlkYXRlSW5zdGFuY2UsIHZhbGlkYXRlSW50ZWdlciB9IGZyb20gXCIuLi90eXBlcy92YWxpZGF0ZS5tanNcIjtcbmltcG9ydCB7IExvZ0VudHJ5IH0gZnJvbSBcIi4vbG9nZW50cnkubWpzXCI7XG5pbXBvcnQgeyBBTEwsIERFQlVHLCBFUlJPUiwgRkFUQUwsIElORk8sIE9GRiwgVFJBQ0UsIFdBUk4gfSBmcm9tIFwiLi9sb2dnZXIubWpzXCI7XG5cbmV4cG9ydCB7IEhhbmRsZXIgfTtcblxuLyoqXG4gKiBUaGUgbG9nIGhhbmRsZXIgaXMgdGhlIGludGVyZmFjZSBiZXR3ZWVuIHRoZSBsb2cgZW50cmllcyBhbmQgdGhlIGxvZyBsaXN0ZW5lcnMuXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS41LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5Mb2dnaW5nXG4gKi9cbmNsYXNzIEhhbmRsZXIgZXh0ZW5kcyBCYXNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoKTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogTG9nbGV2ZWxcbiAgICAgICAgICpcbiAgICAgICAgICogQHR5cGUge2ludGVnZXJ9XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmxvZ2xldmVsID0gT0ZGO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgaXMgdGhlIGNlbnRyYWwgbG9nIGZ1bmN0aW9uLiB0aGlzIG1ldGhvZCBtdXN0IGJlXG4gICAgICogb3ZlcndyaXR0ZW4gYnkgZGVyaXZlZCBoYW5kbGVycyB3aXRoIHRoZWlyIG93biBsb2dpYy5cbiAgICAgKlxuICAgICAqIEFMTCA+IFRSQUNFID4gREVCVUcgPiBJTkZPID4gV0FSTiA+IEVSUk9SID4gRkFUQUwgPiBPRkYgIChBTEwgPSAweGZmO09GRiA9IDB4MDA7XG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0xvZ0VudHJ5fSBlbnRyeVxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgICAqL1xuICAgIGxvZyhlbnRyeSkge1xuICAgICAgICB2YWxpZGF0ZUluc3RhbmNlKGVudHJ5LCBMb2dFbnRyeSk7XG5cbiAgICAgICAgaWYgKHRoaXMubG9nbGV2ZWwgPCBlbnRyeS5nZXRMb2dMZXZlbCgpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBzZXQgbG9nbGV2ZWxcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7aW50ZWdlcn0gbG9nbGV2ZWxcbiAgICAgKiBAcmV0dXJucyB7SGFuZGxlcn1cbiAgICAgKiBAc2luY2UgMS41LjBcbiAgICAgKi9cbiAgICBzZXRMb2dMZXZlbChsb2dsZXZlbCkge1xuICAgICAgICB2YWxpZGF0ZUludGVnZXIobG9nbGV2ZWwpO1xuICAgICAgICB0aGlzLmxvZ2xldmVsID0gbG9nbGV2ZWw7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIGdldCBsb2dsZXZlbFxuICAgICAqXG4gICAgICogQHJldHVybnMge2ludGVnZXJ9XG4gICAgICogQHNpbmNlIDEuNS4wXG4gICAgICovXG4gICAgZ2V0TG9nTGV2ZWwoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxvZ2xldmVsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqICBTZXQgbG9nIGxldmVsIHRvIEFsbFxuICAgICAqXG4gICAgICogQHJldHVybnMge0hhbmRsZXJ9XG4gICAgICogQHNpbmNlIDEuNS4wXG4gICAgICovXG4gICAgc2V0QWxsKCkge1xuICAgICAgICB0aGlzLnNldExvZ0xldmVsKEFMTCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldCBsb2cgbGV2ZWwgdG8gVHJhY2VcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtIYW5kbGVyfVxuICAgICAqIEBzaW5jZSAxLjUuMFxuICAgICAqL1xuICAgIHNldFRyYWNlKCkge1xuICAgICAgICB0aGlzLnNldExvZ0xldmVsKFRSQUNFKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IGxvZyBsZXZlbCB0byBEZWJ1Z1xuICAgICAqXG4gICAgICogQHJldHVybnMge0hhbmRsZXJ9XG4gICAgICogQHNpbmNlIDEuNS4wXG4gICAgICovXG4gICAgc2V0RGVidWcoKSB7XG4gICAgICAgIHRoaXMuc2V0TG9nTGV2ZWwoREVCVUcpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgbG9nIGxldmVsIHRvIEluZm9cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtIYW5kbGVyfVxuICAgICAqIEBzaW5jZSAxLjUuMFxuICAgICAqL1xuICAgIHNldEluZm8oKSB7XG4gICAgICAgIHRoaXMuc2V0TG9nTGV2ZWwoSU5GTyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldCBsb2cgbGV2ZWwgdG8gV2FyblxuICAgICAqXG4gICAgICogQHJldHVybnMge3VuZGVmaW5lZH1cbiAgICAgKiBAc2luY2UgMS41LjBcbiAgICAgKi9cbiAgICBzZXRXYXJuKCkge1xuICAgICAgICB0aGlzLnNldExvZ0xldmVsKFdBUk4pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgbG9nIGxldmVsIHRvIEVycm9yXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7SGFuZGxlcn1cbiAgICAgKiBAc2luY2UgMS41LjBcbiAgICAgKi9cbiAgICBzZXRFcnJvcigpIHtcbiAgICAgICAgdGhpcy5zZXRMb2dMZXZlbChFUlJPUik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldCBsb2cgbGV2ZWwgdG8gRmF0YWxcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtIYW5kbGVyfVxuICAgICAqIEBzaW5jZSAxLjUuMFxuICAgICAqL1xuICAgIHNldEZhdGFsKCkge1xuICAgICAgICB0aGlzLnNldExvZ0xldmVsKEZBVEFMKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IGxvZyBsZXZlbCB0byBPZmZcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtIYW5kbGVyfVxuICAgICAqIEBzaW5jZSAxLjUuMFxuICAgICAqL1xuICAgIHNldE9mZigpIHtcbiAgICAgICAgdGhpcy5zZXRMb2dMZXZlbChPRkYpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBCYXNlIH0gZnJvbSBcIi4uL3R5cGVzL2Jhc2UubWpzXCI7XG5pbXBvcnQgeyB2YWxpZGF0ZUludGVnZXIgfSBmcm9tIFwiLi4vdHlwZXMvdmFsaWRhdGUubWpzXCI7XG5cbmV4cG9ydCB7IExvZ0VudHJ5IH07XG5cbi8qKlxuICogQSBsb2cgZW50cnkgZm9yIHRoZSBsb2dnZXJcbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjUuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkxvZ2dpbmdcbiAqL1xuY2xhc3MgTG9nRW50cnkgZXh0ZW5kcyBCYXNlIHtcbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7SW50ZWdlcn0gbG9nbGV2ZWxcbiAgICAgKiBAcGFyYW0gey4uLip9IGFyZ3NcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcihsb2dsZXZlbCwgLi4uYXJncykge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB2YWxpZGF0ZUludGVnZXIobG9nbGV2ZWwpO1xuXG4gICAgICAgIHRoaXMubG9nbGV2ZWwgPSBsb2dsZXZlbDtcbiAgICAgICAgdGhpcy5hcmd1bWVudHMgPSBhcmdzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHJldHVybnMge2ludGVnZXJyfVxuICAgICAqL1xuICAgIGdldExvZ0xldmVsKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5sb2dsZXZlbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHthcnJheX1cbiAgICAgKi9cbiAgICBnZXRBcmd1bWVudHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFyZ3VtZW50cztcbiAgICB9XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBIYW5kbGVyIH0gZnJvbSBcIi4uL2xvZ2dpbmcvaGFuZGxlci5tanNcIjtcbmltcG9ydCB7IExvZ0VudHJ5IH0gZnJvbSBcIi4uL2xvZ2dpbmcvbG9nZW50cnkubWpzXCI7XG5cbmltcG9ydCB7IEJhc2UgfSBmcm9tIFwiLi4vdHlwZXMvYmFzZS5tanNcIjtcbmltcG9ydCB7IHZhbGlkYXRlSW50ZWdlciwgdmFsaWRhdGVPYmplY3QsIHZhbGlkYXRlU3RyaW5nIH0gZnJvbSBcIi4uL3R5cGVzL3ZhbGlkYXRlLm1qc1wiO1xuXG5leHBvcnQgeyBMb2dnZXIsIEFMTCwgVFJBQ0UsIERFQlVHLCBJTkZPLCBXQVJOLCBFUlJPUiwgRkFUQUwsIE9GRiB9O1xuXG4vKipcbiAqIEFMTCA+IFRSQUNFID4gREVCVUcgPiBJTkZPID4gV0FSTiA+IEVSUk9SID4gRkFUQUwgPiBPRkZcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5Mb2dnaW5nXG4gKi9cbmNvbnN0IEFMTCA9IDI1NTtcbi8qKlxuICogQUxMID4gVFJBQ0UgPiBERUJVRyA+IElORk8gPiBXQVJOID4gRVJST1IgPiBGQVRBTCA+IE9GRlxuICogQHR5cGUge251bWJlcn1cbiAqIEBtZW1iZXJPZiBNb25zdGVyLkxvZ2dpbmdcbiAqL1xuY29uc3QgVFJBQ0UgPSA2NDtcbi8qKlxuICogQUxMID4gVFJBQ0UgPiBERUJVRyA+IElORk8gPiBXQVJOID4gRVJST1IgPiBGQVRBTCA+IE9GRlxuICogQHR5cGUge251bWJlcn1cbiAqIEBtZW1iZXJPZiBNb25zdGVyLkxvZ2dpbmdcbiAqL1xuY29uc3QgREVCVUcgPSAzMjtcbi8qKlxuICogQUxMID4gVFJBQ0UgPiBERUJVRyA+IElORk8gPiBXQVJOID4gRVJST1IgPiBGQVRBTCA+IE9GRlxuICogQHR5cGUge251bWJlcn1cbiAqIEBtZW1iZXJPZiBNb25zdGVyLkxvZ2dpbmdcbiAqL1xuY29uc3QgSU5GTyA9IDE2O1xuLyoqXG4gKiBBTEwgPiBUUkFDRSA+IERFQlVHID4gSU5GTyA+IFdBUk4gPiBFUlJPUiA+IEZBVEFMID4gT0ZGXG4gKiBAdHlwZSB7bnVtYmVyfVxuICogQG1lbWJlck9mIE1vbnN0ZXIuTG9nZ2luZ1xuICovXG5jb25zdCBXQVJOID0gODtcbi8qKlxuICogQUxMID4gVFJBQ0UgPiBERUJVRyA+IElORk8gPiBXQVJOID4gRVJST1IgPiBGQVRBTCA+IE9GRlxuICogQHR5cGUge251bWJlcn1cbiAqIEBtZW1iZXJPZiBNb25zdGVyLkxvZ2dpbmdcbiAqL1xuY29uc3QgRVJST1IgPSA0O1xuLyoqXG4gKiBBTEwgPiBUUkFDRSA+IERFQlVHID4gSU5GTyA+IFdBUk4gPiBFUlJPUiA+IEZBVEFMID4gT0ZGXG4gKiBAdHlwZSB7bnVtYmVyfVxuICogQG1lbWJlck9mIE1vbnN0ZXIuTG9nZ2luZ1xuICovXG5jb25zdCBGQVRBTCA9IDI7XG4vKipcbiAqIEFMTCA+IFRSQUNFID4gREVCVUcgPiBJTkZPID4gV0FSTiA+IEVSUk9SID4gRkFUQUwgPiBPRkZcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5Mb2dnaW5nXG4gKi9cbmNvbnN0IE9GRiA9IDA7XG5cbi8qKlxuICogVGhlIGxvZ2dlciBpcyBhIGNsYXNzIHRoYXQgdGFrZXMgY2FyZSBvZiBsb2dnaW5nLlxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuNS4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuTG9nZ2luZ1xuICovXG5jbGFzcyBMb2dnZXIgZXh0ZW5kcyBCYXNlIHtcbiAgICAvKipcbiAgICAgKlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLmhhbmRsZXIgPSBuZXcgU2V0KCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0hhbmRsZXJ9IGhhbmRsZXJcbiAgICAgKiBAcmV0dXJucyB7TG9nZ2VyfVxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSB0aGUgaGFuZGxlciBtdXN0IGJlIGFuIGluc3RhbmNlIG9mIEhhbmRsZXJcbiAgICAgKi9cbiAgICBhZGRIYW5kbGVyKGhhbmRsZXIpIHtcbiAgICAgICAgdmFsaWRhdGVPYmplY3QoaGFuZGxlcik7XG4gICAgICAgIGlmICghKGhhbmRsZXIgaW5zdGFuY2VvZiBIYW5kbGVyKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidGhlIGhhbmRsZXIgbXVzdCBiZSBhbiBpbnN0YW5jZSBvZiBIYW5kbGVyXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5oYW5kbGVyLmFkZChoYW5kbGVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0hhbmRsZXJ9IGhhbmRsZXJcbiAgICAgKiBAcmV0dXJucyB7TG9nZ2VyfVxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSB0aGUgaGFuZGxlciBtdXN0IGJlIGFuIGluc3RhbmNlIG9mIEhhbmRsZXJcbiAgICAgKi9cbiAgICByZW1vdmVIYW5kbGVyKGhhbmRsZXIpIHtcbiAgICAgICAgdmFsaWRhdGVPYmplY3QoaGFuZGxlcik7XG4gICAgICAgIGlmICghKGhhbmRsZXIgaW5zdGFuY2VvZiBIYW5kbGVyKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidGhlIGhhbmRsZXIgbXVzdCBiZSBhbiBpbnN0YW5jZSBvZiBIYW5kbGVyXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5oYW5kbGVyLmRlbGV0ZShoYW5kbGVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogbG9nIFRyYWNlIG1lc3NhZ2VcbiAgICAgKlxuICAgICAqIEFMTCA+IFRSQUNFID4gREVCVUcgPiBJTkZPID4gV0FSTiA+IEVSUk9SID4gRkFUQUwgPiBPRkYgIChBTEwgPSAweGZmO09GRiA9IDB4MDA7XG4gICAgICpcbiAgICAgKiBAcGFyYW0geyp9IGFyZ3VtZW50c1xuICAgICAqIEByZXR1cm5zIHtMb2dnZXJ9XG4gICAgICogQHNpbmNlIDEuNS4wXG4gICAgICovXG4gICAgbG9nVHJhY2UoLi4uYXJncykge1xuICAgICAgICBpZiAodHlwZW9mIGFyZ3MgIT09IFwib2JqZWN0XCIgfHwgYXJnc1swXSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidGhlIGZpcnN0IGFyZ3VtZW50IG11c3QgYmUgYW4gb2JqZWN0XCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgdHJpZ2dlckxvZy5hcHBseSh0aGlzLCBbVFJBQ0UsIC4uLmFyZ3NdKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogbG9nIERlYnVnIG1lc3NhZ2VcbiAgICAgKlxuICAgICAqIEFMTCA+IFRSQUNFID4gREVCVUcgPiBJTkZPID4gV0FSTiA+IEVSUk9SID4gRkFUQUwgPiBPRkYgIChBTEwgPSAweGZmO09GRiA9IDB4MDA7XG4gICAgICpcbiAgICAgKiBAcGFyYW0geyp9IGFyZ3VtZW50c1xuICAgICAqIEByZXR1cm5zIHtMb2dnZXJ9XG4gICAgICogQHNpbmNlIDEuNS4wXG4gICAgICovXG4gICAgbG9nRGVidWcoLi4uYXJncykge1xuICAgICAgICBpZiAodHlwZW9mIGFyZ3MgIT09IFwib2JqZWN0XCIgfHwgYXJnc1swXSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidGhlIGZpcnN0IGFyZ3VtZW50IG11c3QgYmUgYW4gb2JqZWN0XCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgdHJpZ2dlckxvZy5hcHBseSh0aGlzLCBbREVCVUcsIC4uLmFyZ3NdKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogbG9nIEluZm8gbWVzc2FnZVxuICAgICAqXG4gICAgICogQUxMID4gVFJBQ0UgPiBERUJVRyA+IElORk8gPiBXQVJOID4gRVJST1IgPiBGQVRBTCA+IE9GRiAgKEFMTCA9IDB4ZmY7T0ZGID0gMHgwMDtcbiAgICAgKlxuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSBhcmd1bWVudHNcbiAgICAgKiBAcmV0dXJucyB7TG9nZ2VyfVxuICAgICAqIEBzaW5jZSAxLjUuMFxuICAgICAqL1xuICAgIGxvZ0luZm8oLi4uYXJncykge1xuICAgICAgICBpZiAodHlwZW9mIGFyZ3MgIT09IFwib2JqZWN0XCIgfHwgYXJnc1swXSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidGhlIGZpcnN0IGFyZ3VtZW50IG11c3QgYmUgYW4gb2JqZWN0XCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgdHJpZ2dlckxvZy5hcHBseSh0aGlzLCBbSU5GTywgLi4uYXJnc10pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBsb2cgV2FybiBtZXNzYWdlXG4gICAgICpcbiAgICAgKiBBTEwgPiBUUkFDRSA+IERFQlVHID4gSU5GTyA+IFdBUk4gPiBFUlJPUiA+IEZBVEFMID4gT0ZGICAoQUxMID0gMHhmZjtPRkYgPSAweDAwO1xuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSBhcmd1bWVudHNcbiAgICAgKiBAcmV0dXJucyB7TG9nZ2VyfVxuICAgICAqIEBzaW5jZSAxLjUuMFxuICAgICAqL1xuICAgIGxvZ1dhcm4oLi4uYXJncykge1xuICAgICAgICBpZiAodHlwZW9mIGFyZ3MgIT09IFwib2JqZWN0XCIgfHwgYXJnc1swXSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidGhlIGZpcnN0IGFyZ3VtZW50IG11c3QgYmUgYW4gb2JqZWN0XCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgdHJpZ2dlckxvZy5hcHBseSh0aGlzLCBbV0FSTiwgLi4uYXJnc10pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBsb2cgRXJyb3IgbWVzc2FnZVxuICAgICAqXG4gICAgICogQUxMID4gVFJBQ0UgPiBERUJVRyA+IElORk8gPiBXQVJOID4gRVJST1IgPiBGQVRBTCA+IE9GRiAgKEFMTCA9IDB4ZmY7T0ZGID0gMHgwMDtcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Kn0gYXJndW1lbnRzXG4gICAgICogQHJldHVybnMge0xvZ2dlcn1cbiAgICAgKiBAc2luY2UgMS41LjBcbiAgICAgKi9cbiAgICBsb2dFcnJvciguLi5hcmdzKSB7XG4gICAgICAgIGlmICh0eXBlb2YgYXJncyAhPT0gXCJvYmplY3RcIiB8fCBhcmdzWzBdID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0aGUgZmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhbiBvYmplY3RcIik7XG4gICAgICAgIH1cblxuICAgICAgICB0cmlnZ2VyTG9nLmFwcGx5KHRoaXMsIFtFUlJPUiwgLi4uYXJnc10pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBsb2cgRmF0YWwgbWVzc2FnZVxuICAgICAqXG4gICAgICogQUxMID4gVFJBQ0UgPiBERUJVRyA+IElORk8gPiBXQVJOID4gRVJST1IgPiBGQVRBTCA+IE9GRiAgKEFMTCA9IDB4ZmY7T0ZGID0gMHgwMDtcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Kn0gYXJndW1lbnRzXG4gICAgICogQHJldHVybnMge0xvZ2dlcn1cbiAgICAgKiBAc2luY2UgMS41LjBcbiAgICAgKi9cbiAgICBsb2dGYXRhbCguLi5hcmdzKSB7XG4gICAgICAgIGlmICh0eXBlb2YgYXJncyAhPT0gXCJvYmplY3RcIiB8fCBhcmdzWzBdID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0aGUgZmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhbiBvYmplY3RcIik7XG4gICAgICAgIH1cblxuICAgICAgICB0cmlnZ2VyTG9nLmFwcGx5KHRoaXMsIFtGQVRBTCwgLi4uYXJnc10pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBMYWJlbHNcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7aW50ZWdlcn0gbGV2ZWxcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgICAqL1xuICAgIGdldExhYmVsKGxldmVsKSB7XG4gICAgICAgIHZhbGlkYXRlSW50ZWdlcihsZXZlbCk7XG5cbiAgICAgICAgaWYgKGxldmVsID09PSBBTEwpIHJldHVybiBcIkFMTFwiO1xuICAgICAgICBpZiAobGV2ZWwgPT09IFRSQUNFKSByZXR1cm4gXCJUUkFDRVwiO1xuICAgICAgICBpZiAobGV2ZWwgPT09IERFQlVHKSByZXR1cm4gXCJERUJVR1wiO1xuICAgICAgICBpZiAobGV2ZWwgPT09IElORk8pIHJldHVybiBcIklORk9cIjtcbiAgICAgICAgaWYgKGxldmVsID09PSBXQVJOKSByZXR1cm4gXCJXQVJOXCI7XG4gICAgICAgIGlmIChsZXZlbCA9PT0gRVJST1IpIHJldHVybiBcIkVSUk9SXCI7XG4gICAgICAgIGlmIChsZXZlbCA9PT0gRkFUQUwpIHJldHVybiBcIkZBVEFMXCI7XG4gICAgICAgIGlmIChsZXZlbCA9PT0gT0ZGKSByZXR1cm4gXCJPRkZcIjtcblxuICAgICAgICByZXR1cm4gXCJ1bmtub3duXCI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTGV2ZWxcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBsYWJlbFxuICAgICAqIEByZXR1cm5zIHtpbnRlZ2VyfVxuICAgICAqL1xuICAgIGdldExldmVsKGxhYmVsKSB7XG4gICAgICAgIHZhbGlkYXRlU3RyaW5nKGxhYmVsKTtcblxuICAgICAgICBpZiAobGFiZWwgPT09IFwiQUxMXCIpIHJldHVybiBBTEw7XG4gICAgICAgIGlmIChsYWJlbCA9PT0gXCJUUkFDRVwiKSByZXR1cm4gVFJBQ0U7XG4gICAgICAgIGlmIChsYWJlbCA9PT0gXCJERUJVR1wiKSByZXR1cm4gREVCVUc7XG4gICAgICAgIGlmIChsYWJlbCA9PT0gXCJJTkZPXCIpIHJldHVybiBJTkZPO1xuICAgICAgICBpZiAobGFiZWwgPT09IFwiV0FSTlwiKSByZXR1cm4gV0FSTjtcbiAgICAgICAgaWYgKGxhYmVsID09PSBcIkVSUk9SXCIpIHJldHVybiBFUlJPUjtcbiAgICAgICAgaWYgKGxhYmVsID09PSBcIkZBVEFMXCIpIHJldHVybiBGQVRBTDtcbiAgICAgICAgaWYgKGxhYmVsID09PSBcIk9GRlwiKSByZXR1cm4gT0ZGO1xuXG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbn1cblxuLyoqXG4gKiBMb2cgdHJpZ2dlcm5cbiAqXG4gKiBAcGFyYW0ge2ludGVnZXJ9IGxvZ2xldmVsXG4gKiBAcGFyYW0geyp9IGFyZ3NcbiAqIEByZXR1cm5zIHtMb2dnZXJ9XG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiB0cmlnZ2VyTG9nKGxvZ2xldmVsLCAuLi5hcmdzKSB7XG4gICAgdmFyIGxvZ2dlciA9IHRoaXM7XG5cbiAgICBmb3IgKGxldCBoYW5kbGVyIG9mIGxvZ2dlci5oYW5kbGVyKSB7XG4gICAgICAgIGhhbmRsZXIubG9nKG5ldyBMb2dFbnRyeShsb2dsZXZlbCwgYXJncykpO1xuICAgIH1cblxuICAgIHJldHVybiBsb2dnZXI7XG59XG4iLCAiaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7TG9nZ2VyLCBPRkYsIEFMTCwgVFJBQ0UsIERFQlVHLCBJTkZPLCBXQVJOLCBFUlJPUiwgRkFUQUx9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvbG9nZ2luZy9sb2dnZXIubWpzXCI7XG5cblxuZGVzY3JpYmUoJ0xvZ2dpbmcnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBkZXNjcmliZSgnbmV3IExvZ2dlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gaW5zdGFuY2VvZiBMb2dnZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IExvZ2dlcigpKS50by5pbnN0YW5jZU9mKExvZ2dlcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ0xvZ2dlci5sb2dUcmFjZSgpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBpbnN0YW5jZW9mIExvZ2dlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgTG9nZ2VyKCkubG9nVHJhY2UoXCJ0ZXN0XCIpKS50by5pbnN0YW5jZU9mKExvZ2dlcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICAgIFxuICAgIGRlc2NyaWJlKCdMb2dnZXIubG9nRGVidWcoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gaW5zdGFuY2VvZiBMb2dnZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IExvZ2dlcigpLmxvZ0RlYnVnKFwidGVzdFwiKSkudG8uaW5zdGFuY2VPZihMb2dnZXIpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgICBcbiAgICBkZXNjcmliZSgnTG9nZ2VyLmxvZ0luZm8oKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gaW5zdGFuY2VvZiBMb2dnZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IExvZ2dlcigpLmxvZ0luZm8oXCJ0ZXN0XCIpKS50by5pbnN0YW5jZU9mKExvZ2dlcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICAgIFxuICAgIGRlc2NyaWJlKCdMb2dnZXIubG9nV2FybigpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBpbnN0YW5jZW9mIExvZ2dlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgTG9nZ2VyKCkubG9nV2FybihcInRlc3RcIikpLnRvLmluc3RhbmNlT2YoTG9nZ2VyKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gICAgXG4gICAgZGVzY3JpYmUoJ0xvZ2dlci5sb2dFcnJvcigpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBpbnN0YW5jZW9mIExvZ2dlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgTG9nZ2VyKCkubG9nRXJyb3IoXCJ0ZXN0XCIpKS50by5pbnN0YW5jZU9mKExvZ2dlcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICAgIFxuICAgIGRlc2NyaWJlKCdMb2dnZXIubG9nRmF0YWwoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gaW5zdGFuY2VvZiBMb2dnZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IExvZ2dlcigpLmxvZ0ZhdGFsKFwidGVzdFwiKSkudG8uaW5zdGFuY2VPZihMb2dnZXIpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgICBcbiAgICBkZXNjcmliZSgnTG9nZ2VyLmdldExldmVsKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIFtcbiAgICAgICAgICAgIFsnQUxMJywgQUxMXSxcbiAgICAgICAgICAgIFsnVFJBQ0UnLCBUUkFDRV0sXG4gICAgICAgICAgICBbJ0RFQlVHJywgREVCVUddLFxuICAgICAgICAgICAgWydJTkZPJywgSU5GT10sXG4gICAgICAgICAgICBbJ1dBUk4nLCBXQVJOXSxcbiAgICAgICAgICAgIFsnRVJST1InLCBFUlJPUl0sXG4gICAgICAgICAgICBbJ0ZBVEFMJywgRkFUQUxdLFxuICAgICAgICAgICAgWydPRkYnLCBPRkZdLFxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGl0KGEgKyAnIHNob3VsZCByZXR1cm4gJyArIGIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBleHBlY3QobmV3IExvZ2dlcigpLmdldExldmVsKGEpKS50by5iZS5lcXVhbHMoYik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gICAgZGVzY3JpYmUoJ0xvZ2dlci5nZXRMYWJlbCgpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBbXG4gICAgICAgICAgICBbJ0FMTCcsIEFMTF0sXG4gICAgICAgICAgICBbJ1RSQUNFJywgVFJBQ0VdLFxuICAgICAgICAgICAgWydERUJVRycsIERFQlVHXSxcbiAgICAgICAgICAgIFsnSU5GTycsIElORk9dLFxuICAgICAgICAgICAgWydXQVJOJywgV0FSTl0sXG4gICAgICAgICAgICBbJ0VSUk9SJywgRVJST1JdLFxuICAgICAgICAgICAgWydGQVRBTCcsIEZBVEFMXSxcbiAgICAgICAgICAgIFsnT0ZGJywgT0ZGXSxcbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpdChhICsgJyBzaG91bGQgcmV0dXJuICcgKyBiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KG5ldyBMb2dnZXIoKS5nZXRMYWJlbChiKSkudG8uYmUuZXF1YWxzKGEpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xufSk7IiwgImltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge0xvZ0VudHJ5fSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2xvZ2dpbmcvbG9nZW50cnkubWpzXCI7XG5cblxuZGVzY3JpYmUoJ0xvZycsIGZ1bmN0aW9uICgpIHtcblxuICAgIGRlc2NyaWJlKCduZXcgTG9nJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBpbnN0YW5jZW9mIExvZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgTG9nRW50cnkoMSwgJ2EnLCAnYicsICdjJykpLnRvLmluc3RhbmNlT2YoTG9nRW50cnkpO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdMb2cubG9nbGV2ZWwnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgbGV0IGxvZztcblxuICAgICAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxvZyA9IG5ldyBMb2dFbnRyeSgxLCBmYWxzZSwgJ3Rlc3QnLCA5OSwge2E6IHRydWV9KTtcbiAgICAgICAgfSlcblxuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBsb2dsZXZlbCAxJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KGxvZy5nZXRMb2dMZXZlbCgpKS50by5iZS5lcXVhbCgxKVxuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBhcmd1bWVudHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobG9nLmdldEFyZ3VtZW50cygpKS50by5oYXZlLmRlZXAubWVtYmVycyhbZmFsc2UsICd0ZXN0JywgOTksIHthOiB0cnVlfV0pXG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG59KTsiLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBnZXRHbG9iYWxPYmplY3QgfSBmcm9tIFwiLi4vLi4vdHlwZXMvZ2xvYmFsLm1qc1wiO1xuaW1wb3J0IHsgSGFuZGxlciB9IGZyb20gXCIuLi9oYW5kbGVyLm1qc1wiO1xuaW1wb3J0IHsgTG9nRW50cnkgfSBmcm9tIFwiLi4vbG9nZW50cnkubWpzXCI7XG5pbXBvcnQgeyBUUkFDRSwgV0FSTiwgREVCVUcsIEVSUk9SLCBGQVRBTCwgSU5GTyB9IGZyb20gXCIuLi9sb2dnZXIubWpzXCI7XG5cbmV4cG9ydCB7IENvbnNvbGVIYW5kbGVyIH07XG5cbi8qKlxuICogWW91IGNhbiBjcmVhdGUgYW4gb2JqZWN0IG9mIHRoZSBjbGFzcyBzaW1wbHkgYnkgdXNpbmcgdGhlIG5hbWVzcGFjZSBgbmV3IE1vbnN0ZXIuTG9nZ2luZy5IYW5kbGVyLkNvbnNvbGVIYW5kbGVyKClgLlxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuNS4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuTG9nZ2luZy5IYW5kbGVyXG4gKi9cbmNsYXNzIENvbnNvbGVIYW5kbGVyIGV4dGVuZHMgSGFuZGxlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBpcyB0aGUgY2VudHJhbCBsb2cgZnVuY3Rpb24uIHRoaXMgbWV0aG9kIG11c3QgYmVcbiAgICAgKiBvdmVyd3JpdHRlbiBieSBkZXJpdmVkIGhhbmRsZXJzIHdpdGggdGhlaXIgb3duIGxvZ2ljLlxuICAgICAqXG4gICAgICogQUxMID4gVFJBQ0UgPiBERUJVRyA+IElORk8gPiBXQVJOID4gRVJST1IgPiBGQVRBTCA+IE9GRiAgKEFMTCA9IDB4ZmY7T0ZGID0gMHgwMDtcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7TG9nRW50cnl9IGVudHJ5XG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAgICovXG4gICAgbG9nKGVudHJ5KSB7XG4gICAgICAgIGlmIChzdXBlci5sb2coZW50cnkpKSB7XG4gICAgICAgICAgICBsZXQgY29uc29sZSA9IGdldEdsb2JhbE9iamVjdChcImNvbnNvbGVcIik7XG4gICAgICAgICAgICBpZiAoIWNvbnNvbGUpIHJldHVybiBmYWxzZTtcblxuICAgICAgICAgICAgaWYgKCFjb25zb2xlLmVycm9yKSBjb25zb2xlLmVycm9yID0gY29uc29sZS5sb2c7XG4gICAgICAgICAgICBpZiAoIWNvbnNvbGUud2FybikgY29uc29sZS53YXJuID0gY29uc29sZS5sb2c7XG5cbiAgICAgICAgICAgIHN3aXRjaCAoZW50cnkuZ2V0TG9nTGV2ZWwoKSkge1xuICAgICAgICAgICAgICAgIGNhc2UgVFJBQ0U6XG4gICAgICAgICAgICAgICAgY2FzZSBERUJVRzpcbiAgICAgICAgICAgICAgICBjYXNlIElORk86XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGVudHJ5LnRvU3RyaW5nKCkpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIEZBVEFMOlxuICAgICAgICAgICAgICAgIGNhc2UgRVJST1I6XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZW50cnkudG9TdHJpbmcoKSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgV0FSTjpcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKGVudHJ5LnRvU3RyaW5nKCkpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhlbnRyeS50b1N0cmluZygpKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cbiIsICJpbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIjtcbmltcG9ydCB7Q29uc29sZUhhbmRsZXJ9IGZyb20gXCIuLi8uLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvbG9nZ2luZy9oYW5kbGVyL2NvbnNvbGUubWpzXCI7XG5pbXBvcnQge0xvZ0VudHJ5fSBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2xvZ2dpbmcvbG9nZW50cnkubWpzXCI7XG5pbXBvcnQge1RSQUNFLCBXQVJOLCBERUJVRywgRVJST1IsIEZBVEFMLCBJTkZPfSBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2xvZ2dpbmcvbG9nZ2VyLm1qc1wiO1xuXG5kZXNjcmliZSgnTG9nZ2luZycsIGZ1bmN0aW9uICgpIHtcblxuICAgIGRlc2NyaWJlKCdDb25zb2xlSGFuZGxlcicsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBpdCgnc2hvdWxkIGNyZWF0ZSBDb25zb2xlSGFuZGxlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgQ29uc29sZUhhbmRsZXIoKSkudG8uYmUuaW5zdGFuY2VvZihDb25zb2xlSGFuZGxlcilcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBsb2cgdG8gY29uc29sZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgQ29uc29sZUhhbmRsZXIoKS5zZXRBbGwoKS5sb2cobmV3IExvZ0VudHJ5KEZBVEFMLCBbMSwgdHJ1ZSwgJ2ZhdGFsJ10pKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBsb2cgdG8gY29uc29sZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgQ29uc29sZUhhbmRsZXIoKS5zZXRBbGwoKS5sb2cobmV3IExvZ0VudHJ5KFRSQUNFLCBbMSwgdHJ1ZSwgJ3RyYWNlJ10pKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBsb2cgdG8gY29uc29sZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgQ29uc29sZUhhbmRsZXIoKS5zZXRBbGwoKS5sb2cobmV3IExvZ0VudHJ5KFdBUk4sIFsxLCB0cnVlLCAnd2FybiddKSkpLnRvLmJlLnRydWU7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgbG9nIHRvIGNvbnNvbGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IENvbnNvbGVIYW5kbGVyKCkuc2V0QWxsKCkubG9nKG5ldyBMb2dFbnRyeShERUJVRywgWzEsIHRydWUsICdkZWJ1ZyddKSkpLnRvLmJlLnRydWU7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgbG9nIHRvIGNvbnNvbGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IENvbnNvbGVIYW5kbGVyKCkuc2V0QWxsKCkubG9nKG5ldyBMb2dFbnRyeShFUlJPUiwgWzEsIHRydWUsICdlcnJvciddKSkpLnRvLmJlLnRydWU7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgbG9nIHRvIGNvbnNvbGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IENvbnNvbGVIYW5kbGVyKCkuc2V0QWxsKCkubG9nKG5ldyBMb2dFbnRyeShJTkZPLCBbMSwgdHJ1ZSwgJ2luZm8nXSkpKS50by5iZS50cnVlO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuXG59KTsiLCAiaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCI7XG5pbXBvcnQge0FMTCwgVFJBQ0UsIERFQlVHLCBJTkZPLCBXQVJOLCBFUlJPUiwgRkFUQUwsIE9GRn0gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9sb2dnaW5nL2xvZ2dlci5tanNcIjtcbmltcG9ydCB7SGFuZGxlcn0gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9sb2dnaW5nL2hhbmRsZXIubWpzXCI7XG5pbXBvcnQge0xvZ0VudHJ5fSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2xvZ2dpbmcvbG9nZW50cnkubWpzXCI7XG5cbmRlc2NyaWJlKCdMb2dnaW5nJywgZnVuY3Rpb24gKCkge1xuXG4gICAgZGVzY3JpYmUoJ0hhbmRsZXIuc2V0TG9nTGV2ZWwoKS5nZXRMb2dMZXZlbCgpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIFtcbiAgICAgICAgICAgIFtBTExdLCBbVFJBQ0VdLCBbREVCVUddLCBbSU5GT10sIFtXQVJOXSwgW0VSUk9SXSwgW0ZBVEFMXSwgW09GRl0sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpdCgndGhlIGZ1bmN0aW9uIHNob3VsZCByZXR1cm4gdGhlIHNldCB2YWx1ZSAnICsgYSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGV4cGVjdChuZXcgSGFuZGxlcigpLnNldExvZ0xldmVsKGEpLmdldExvZ0xldmVsKCkpLnRvLmJlLmVxdWFsKGEpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG5cbiAgICBkZXNjcmliZSgnSGFuZGxlci5sb2coKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gaW5zdGFuY2VvZiBIYW5kbGVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KG5ldyBIYW5kbGVyKCkubG9nKG5ldyBMb2dFbnRyeSgwLCBcInRlc3RcIikpKS50by5iZS50cnVlO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdIYW5kbGVyLmxvZygpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGxldCBoYW5kbGVyO1xuXG4gICAgICAgIGNsYXNzIFRlc3RIYW5kbGVyIGV4dGVuZHMgSGFuZGxlciB7XG4gICAgICAgICAgICBsb2coZW50cnkpIHtcbiAgICAgICAgICAgICAgICBzdXBlci5sb2coZW50cnkpO1xuXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBoYW5kbGVyID0gbmV3IFRlc3RIYW5kbGVyKCk7XG4gICAgICAgIH0pXG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gaW5zdGFuY2VvZiBIYW5kbGVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KG5ldyBIYW5kbGVyKCkubG9nKG5ldyBMb2dFbnRyeSgwLCBcInRlc3RcIikpKS50by5iZS50cnVlO1xuICAgICAgICB9KTtcblxuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnLmxvZygpIHdpdGggbG9nbGV2ZWwnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgbGV0IFRlc3RIYW5kbGVyO1xuXG4gICAgICAgIGJlZm9yZSgoKSA9PiB7XG4gICAgICAgICAgICBUZXN0SGFuZGxlciA9IGNsYXNzIGV4dGVuZHMgSGFuZGxlciB7XG4gICAgICAgICAgICAgICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgICAgICAgICAgICAgIHN1cGVyKCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2FsbHMgPSAwO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGxvZyhsb2dsZXZlbCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoc3VwZXIubG9nKGxvZ2xldmVsKSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jYWxscysrXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBbIC8vIEFMTCA+IFRSQUNFID4gREVCVUcgPiBJTkZPID4gV0FSTiA+IEVSUk9SID4gRkFUQUwgPiBPRkYgIChBTEwgPSAweGZmO09GRiA9IDB4MDA7XG4gICAgICAgICAgICBbQUxMLCA2XSxcbiAgICAgICAgICAgIFtUUkFDRSwgNl0sXG4gICAgICAgICAgICBbREVCVUcsIDVdLFxuICAgICAgICAgICAgW0lORk8sIDRdLFxuICAgICAgICAgICAgW1dBUk4sIDNdLFxuICAgICAgICAgICAgW0VSUk9SLCAyXSxcbiAgICAgICAgICAgIFtGQVRBTCwgMV0sXG4gICAgICAgICAgICBbT0ZGLCAwXVxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGl0KCdpcy5sb2coJyArIGEgKyAnKSBzaG91bGQgbG9nICcgKyBiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbGV0IGhhbmRsZXIgPSBuZXcgVGVzdEhhbmRsZXIoKS5zZXRMb2dMZXZlbChhKTtcbiAgICAgICAgICAgICAgICBoYW5kbGVyLmxvZyhuZXcgTG9nRW50cnkoVFJBQ0UpKTtcbiAgICAgICAgICAgICAgICBoYW5kbGVyLmxvZyhuZXcgTG9nRW50cnkoREVCVUcpKTtcbiAgICAgICAgICAgICAgICBoYW5kbGVyLmxvZyhuZXcgTG9nRW50cnkoSU5GTykpO1xuICAgICAgICAgICAgICAgIGhhbmRsZXIubG9nKG5ldyBMb2dFbnRyeShXQVJOKSk7XG4gICAgICAgICAgICAgICAgaGFuZGxlci5sb2cobmV3IExvZ0VudHJ5KEVSUk9SKSk7XG4gICAgICAgICAgICAgICAgaGFuZGxlci5sb2cobmV3IExvZ0VudHJ5KEZBVEFMKSk7XG5cbiAgICAgICAgICAgICAgICBleHBlY3QoaGFuZGxlci5jYWxscykuaXMuZXF1YWwoYilcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdIYW5kbGVyLnNldExvZ0xldmVsKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGluc3RhbmNlb2YgSGFuZGxlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgSGFuZGxlcigpLnNldExvZ0xldmVsKEFMTCkpLnRvLmluc3RhbmNlT2YoSGFuZGxlcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ0hhbmRsZXIuZ2V0TG9nTGV2ZWwoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ25ldyBsb2dnZXIgc2hvdWxkIGJlIDAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IEhhbmRsZXIoKS5nZXRMb2dMZXZlbCgpKS50by5iZS5lcXVhbChPRkYpO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdIYW5kbGVyLnNldEFsbCgpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnIHNob3VsZCBpbnN0YW5jZW9mIEhhbmRsZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IEhhbmRsZXIoKS5zZXRBbGwoKSkudG8uaW5zdGFuY2VPZihIYW5kbGVyKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gICAgZGVzY3JpYmUoJ0hhbmRsZXIuc2V0VHJhY2UoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ25ldyBsb2dnZXIgc2hvdWxkIGluc3RhbmNlb2YgSGFuZGxlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgSGFuZGxlcigpLnNldFRyYWNlKCkpLnRvLmluc3RhbmNlT2YoSGFuZGxlcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICAgIGRlc2NyaWJlKCdIYW5kbGVyLnNldERlYnVnKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCcgc2hvdWxkIGluc3RhbmNlb2YgSGFuZGxlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgSGFuZGxlcigpLnNldERlYnVnKCkpLnRvLmluc3RhbmNlT2YoSGFuZGxlcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICAgIGRlc2NyaWJlKCdIYW5kbGVyLnNldEluZm8oKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gaW5zdGFuY2VvZiBIYW5kbGVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KG5ldyBIYW5kbGVyKCkuc2V0SW5mbygpKS50by5pbnN0YW5jZU9mKEhhbmRsZXIpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgICBkZXNjcmliZSgnSGFuZGxlci5zZXRXYXJuKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCcgc2hvdWxkIGluc3RhbmNlb2YgSGFuZGxlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgSGFuZGxlcigpLnNldFdhcm4oKSkudG8uaW5zdGFuY2VPZihIYW5kbGVyKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gICAgZGVzY3JpYmUoJ0hhbmRsZXIuc2V0RXJyb3IoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gaW5zdGFuY2VvZiBIYW5kbGVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KG5ldyBIYW5kbGVyKCkuc2V0RXJyb3IoKSkudG8uaW5zdGFuY2VPZihIYW5kbGVyKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gICAgZGVzY3JpYmUoJ0hhbmRsZXIuc2V0RmF0YWwoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gaW5zdGFuY2VvZiBIYW5kbGVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KG5ldyBIYW5kbGVyKCkuc2V0RmF0YWwoKSkudG8uaW5zdGFuY2VPZihIYW5kbGVyKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gICAgZGVzY3JpYmUoJ0hhbmRsZXIuc2V0T2ZmKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGluc3RhbmNlb2YgSGFuZGxlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgSGFuZGxlcigpLnNldE9mZigpKS50by5pbnN0YW5jZU9mKEhhbmRsZXIpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbn0pOyIsICJpbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuaW1wb3J0IHtGb3JtYXR0ZXJ9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdGV4dC9mb3JtYXR0ZXIubWpzXCI7XG5cblxuZGVzY3JpYmUoJ0Zvcm1hdHRlcicsIGZ1bmN0aW9uICgpIHtcblxuICAgIC8vIGh0dHBzOi8vZ2l0bGFiLnNjaHVrYWkuY29tL29zcy9saWJyYXJpZXMvamF2YXNjcmlwdC9tb25zdGVyLy0vaXNzdWVzLzQ3XG4gICAgZGVzY3JpYmUoJ2V4YW1wbGVzJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdyZmMgZXhhbXBsZSBzaG91bGQgcnVuJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KG5ldyBGb3JtYXR0ZXIoe1xuXG4gICAgICAgICAgICAgICAgYToge1xuICAgICAgICAgICAgICAgICAgICBiOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjOiBcIkhlbGxvXCJcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgZDogXCJXb3JsZFwiLFxuICAgICAgICAgICAgICAgICAgICBlOiAxXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB9KS5mb3JtYXQoXCIke2EuYi5jfSAke2EuZCB8IHRvdXBwZXJ9IVwiKSkudG8uYmUuZXF1YWwoJ0hlbGxvIFdPUkxEIScpO1xuICAgICAgICB9KVxuXG4gICAgICAgIGl0KCdkb2MgZXhhbXBsZSBzaG91bGQgcnVuJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KG5ldyBGb3JtYXR0ZXIoe1xuXG4gICAgICAgICAgICAgICAgYToge1xuICAgICAgICAgICAgICAgICAgICBiOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjOiBcIkhlbGxvXCJcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgZDogXCJ3b3JsZFwiLFxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgfSkuZm9ybWF0KFwiJHthLmIuY30gJHthLmQgfCB1Y2ZpcnN0fSFcIikpLnRvLmJlLmVxdWFsKCdIZWxsbyBXb3JsZCEnKTtcbiAgICAgICAgfSlcblxuXG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCdzZXQgbWFya2VyKCknLCBmdW5jdGlvbiAoKSB7XG5cblxuICAgICAgICBbXG4gICAgICAgICAgICBbJyNhIycsICcjJywgdW5kZWZpbmVkLCAndGVzdCddLFxuICAgICAgICAgICAgWyd7YX0nLCAneycsICd9JywgJ3Rlc3QnXSxcbiAgICAgICAgICAgIFsnaTE4bnthfScsICdpMThueycsICd9JywgJ3Rlc3QnXSxcblxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYyA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGQgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ2Zvcm1hdCAnICsgYSArICcgd2l0aCBtYXJrZXIgJyArIGIgKyAnIGFuZCAnICsgYyArICcgc2hvdWxkIHJldHVybiAgJyArIGIsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgIGV4cGVjdChcbiAgICAgICAgICAgICAgICAgICAgbmV3IEZvcm1hdHRlcih7XG4gICAgICAgICAgICAgICAgICAgICAgICBhOiBcInRlc3RcIlxuICAgICAgICAgICAgICAgICAgICB9KS5zZXRNYXJrZXIoYiwgYykuZm9ybWF0KGEpXG4gICAgICAgICAgICAgICAgKS50by5lcXVhbChkKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG5cbiAgICB9KVxuXG4gICAgZGVzY3JpYmUoJ2V4YW1wbGVzKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWycke2EgfCB0b2pzb259JywgXCJ7XFxcImJcXFwiOntcXFwiY1xcXCI6XFxcIkhlbGxvXFxcIn0sXFxcImRcXFwiOlxcXCJXb3JsZFxcXCIsXFxcImVcXFwiOjF9XCJdLFxuICAgICAgICAgICAgWydjbGljayAke2EuZH0gdGltZXMnLCBcImNsaWNrIFdvcmxkIHRpbWVzXCJdLFxuICAgICAgICAgICAgWycgJHthLmIuY30gJywgJyBIZWxsbyAnXSxcbiAgICAgICAgICAgIFsnICR7YS5iLmN9JywgJyBIZWxsbyddLFxuICAgICAgICAgICAgWycke2EuYi5jfSAnLCAnSGVsbG8gJ10sXG4gICAgICAgICAgICBbJyR7YS5iLmN9JywgJ0hlbGxvJ10sXG4gICAgICAgICAgICBbJyR7YS5iLmN9JHthLmIuY30nLCAnSGVsbG9IZWxsbyddLFxuICAgICAgICAgICAgWycke2EuYi5jfSAke2EuYi5jfScsICdIZWxsbyBIZWxsbyddLFxuICAgICAgICAgICAgWycke2EuYi5jfSAke2EuYi5jfSAnLCAnSGVsbG8gSGVsbG8gJ10sXG4gICAgICAgICAgICBbJyAke2EuYi5jfSAke2EuYi5jfSAnLCAnIEhlbGxvIEhlbGxvICddLFxuICAgICAgICAgICAgWycgJHthLmIuY30gJHthLmR9ICcsICcgSGVsbG8gV29ybGQgJ10sXG4gICAgICAgICAgICBbJyAke2EuYi5jfSAke2EuYi5jIHwgdG91cHBlciB8IGxlbmd0aCB8IHRvc3RyaW5nfSAnLCAnIEhlbGxvIDUgJ10sXG5cbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpdCgnZm9ybWF0ICcgKyBhICsgJyBzaG91bGQgcmV0dXJuICcgKyBiLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgb2JqID0ge1xuICAgICAgICAgICAgICAgICAgICBhOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBiOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYzogXCJIZWxsb1wiXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgZDogXCJXb3JsZFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgZTogMVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG5cbiAgICAgICAgICAgICAgICBleHBlY3QobmV3IEZvcm1hdHRlcihvYmopLmZvcm1hdChhKSkuaXMuZXF1YWwoYilcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ01hcmtlciBpbiBtYXJrZXInLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgbGV0IHRleHQgPSAnJHtteWtleSR7c3Via2V5fX0nO1xuICAgICAgICBsZXQgZXhwZWN0ZWQgPSAnMSc7XG5cbiAgICAgICAgaXQoJ2Zvcm1hdCAnICsgdGV4dCArICcgc2hvdWxkICcgKyBleHBlY3RlZCwgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBsZXQgb2JqID0ge1xuICAgICAgICAgICAgICAgIG15a2V5MjogXCIxXCIsXG4gICAgICAgICAgICAgICAgc3Via2V5OiBcIjJcIlxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgZXhwZWN0KG5ldyBGb3JtYXR0ZXIob2JqKS5mb3JtYXQodGV4dCkpLmlzLmVxdWFsKGV4cGVjdGVkKVxuXG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdzZXRQYXJhbWV0ZXJDaGFycygpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdzZXRQYXJhbWV0ZXJDaGFycygpIHNob3VsZCByZXR1cm4gSW5zdGFuY2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IEZvcm1hdHRlcih7fSkuc2V0UGFyYW1ldGVyQ2hhcnMoJ2EnLCAnYicpKS5pcy5pbnN0YW5jZW9mKEZvcm1hdHRlcik7XG5cbiAgICAgICAgfSk7XG5cblxuICAgIH0pO1xuXG5cbiAgICBkZXNjcmliZSgnd2l0aCBjYWxsYmFja3MnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ2FkZCBjYWxsYmFjaycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IGZvcm1hdHRlciA9IG5ldyBGb3JtYXR0ZXIoe1xuICAgICAgICAgICAgICAgIHg6ICcxJ1xuICAgICAgICAgICAgfSwge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrczoge1xuICAgICAgICAgICAgICAgICAgICBteTogKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCIhXCIgKyB2YWx1ZSArIFwiIVwiXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgZXhwZWN0KGZvcm1hdHRlci5mb3JtYXQoJyR7eCB8IGNhbGw6bXl9JykpLmlzLmVxdWFsKCchMSEnKTtcblxuICAgICAgICB9KTtcblxuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnTWFya2VyIGluIG1hcmtlciB3aXRoIHBhcmFtZXRlcicsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBsZXQgdGV4dCA9ICcke215a2V5OjpteWtleT0ke3N1YmtleX19JztcbiAgICAgICAgbGV0IGV4cGVjdGVkID0gJzInO1xuXG4gICAgICAgIGl0KCdmb3JtYXQgJyArIHRleHQgKyAnIHNob3VsZCAnICsgZXhwZWN0ZWQsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgbGV0IG9iaiA9IHtcbiAgICAgICAgICAgICAgICBzdWJrZXk6IFwiMlwiXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBleHBlY3QobmV3IEZvcm1hdHRlcihvYmopLmZvcm1hdCh0ZXh0KSkuaXMuZXF1YWwoZXhwZWN0ZWQpXG5cbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnZXhjZXB0aW9ucycsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBbXG4gICAgICAgICAgICBbJyR7YS5iLnh9JywgVHlwZUVycm9yXSxcbiAgICAgICAgICAgIFsnJHthLmIuZCB8IHRvdXBwZXIgfCBsZW5ndGh9JywgVHlwZUVycm9yXSxcbiAgICAgICAgICAgIFsnJHthLmIuZH0nLCBUeXBlRXJyb3JdLCAgLy8gYS5iLmQgcmV0dXJuIHVuZGVmaW5lZCBieSBwYXRoZmluZGVyIFxuICAgICAgICAgICAgWycke2EuYi5kIHwgdG9sb3dlcn0nLCBUeXBlRXJyb3JdLCAgLy8gYS5iLmQgcmV0dXJuIHVuZGVmaW5lZCBieSBwYXRoZmluZGVyIFxuICAgICAgICAgICAgWycke2EgfCB9JywgRXJyb3JdLFxuXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ2Zvcm1hdCAnICsgYSArICcgc2hvdWxkIHRocm93ICcgKyB0eXBlb2YgYiwgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICAgICAgZXhwZWN0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBGb3JtYXR0ZXIoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGE6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYzogXCJ0ZXN0XCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkOiA0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KS5mb3JtYXQoYSlcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICkudG8udGhyb3coYik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICB9KTtcblxuXG5cblxuICAgIGRlc2NyaWJlKCdGb3JtYXR0ZXInLCAoKSA9PiB7XG4gICAgICAgIGl0KCdzaG91bGQgZm9ybWF0IGEgYmFzaWMgc3RyaW5nIHdpdGggb2JqZWN0IHZhbHVlcycsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGZvcm1hdHRlciA9IG5ldyBGb3JtYXR0ZXIoe25hbWU6ICdKb2huJywgYWdlOiAzMH0pO1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gZm9ybWF0dGVyLmZvcm1hdCgnTXkgbmFtZSBpcyAke25hbWV9IGFuZCBJIGFtICR7YWdlIHwgdG9zdHJpbmd9IHllYXJzIG9sZC4nKTtcblxuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdCkudG8uZXF1YWwoJ015IG5hbWUgaXMgSm9obiBhbmQgSSBhbSAzMCB5ZWFycyBvbGQuJyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgZm9ybWF0IGEgc3RyaW5nIHdpdGggbmVzdGVkIG1hcmtlcnMnLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0ZXh0ID0gJyR7bXlrZXkke3N1YmtleX19JztcbiAgICAgICAgICAgIGNvbnN0IG9iaiA9IHtteWtleTI6ICcxJywgc3Via2V5OiAnMid9O1xuICAgICAgICAgICAgY29uc3QgZm9ybWF0dGVyID0gbmV3IEZvcm1hdHRlcihvYmopO1xuXG4gICAgICAgICAgICBleHBlY3QoZm9ybWF0dGVyLmZvcm1hdCh0ZXh0KSkudG8uZXF1YWwoJzEnKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBmb3JtYXQgYSBzdHJpbmcgd2l0aCBjdXN0b20gbWFya2VycycsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGZvcm1hdHRlciA9IG5ldyBGb3JtYXR0ZXIoe25hbWU6ICdKb2huJywgYWdlOiAzMH0pO1xuICAgICAgICAgICAgZm9ybWF0dGVyLnNldE1hcmtlcignWycsICddJyk7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBmb3JtYXR0ZXIuZm9ybWF0KCdNeSBuYW1lIGlzIFtuYW1lXSBhbmQgSSBhbSBbYWdlIHwgdG9zdHJpbmddIHllYXJzIG9sZC4nKTtcblxuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdCkudG8uZXF1YWwoJ015IG5hbWUgaXMgSm9obiBhbmQgSSBhbSAzMCB5ZWFycyBvbGQuJyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgZm9ybWF0IGEgc3RyaW5nIHVzaW5nIGNhbGxiYWNrJywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZm9ybWF0dGVyID0gbmV3IEZvcm1hdHRlcih7eDogJzEnfSwge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrczoge1xuICAgICAgICAgICAgICAgICAgICBxdW90ZTogKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJ1wiJyArIHZhbHVlICsgJ1wiJztcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGV4cGVjdChmb3JtYXR0ZXIuZm9ybWF0KCcke3ggfCBjYWxsOnF1b3RlfScpKS50by5lcXVhbCgnXCIxXCInKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBmb3JtYXQgYSBzdHJpbmcgd2l0aCBwYXJhbWV0ZXJzJywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgb2JqID0ge1xuICAgICAgICAgICAgICAgIGE6IHtcbiAgICAgICAgICAgICAgICAgICAgYjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgYzogJ0hlbGxvJyxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgZDogJ3dvcmxkJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IGZvcm1hdHRlciA9IG5ldyBGb3JtYXR0ZXIob2JqKTtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGZvcm1hdHRlci5mb3JtYXQoJyR7YS5iLmN9ICR7YS5kIHwgdWNmaXJzdH0hJyk7XG5cbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHQpLnRvLmVxdWFsKCdIZWxsbyBXb3JsZCEnKTtcbiAgICAgICAgfSk7XG4gICAgICAgIFxuICAgICAgICBpdCgnc2hvdWxkIHRocm93IGEgdG9vIGRlZXAgbmVzdGluZyBlcnJvcicsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGZvcm1hdHRlciA9IG5ldyBGb3JtYXR0ZXIoe25hbWU6ICdKb2huJ30pO1xuICAgICAgICAgICAgY29uc3QgbmVzdGVkVGV4dCA9ICcke25hbWUke25hbWUke25hbWUke25hbWUke25hbWUke25hbWUke25hbWUke25hbWUke25hbWUke25hbWUke25hbWUke25hbWUke25hbWUke25hbWUke25hbWUke25hbWUke25hbWUke25hbWUke25hbWV9fX19fX19fX19fX19fX19fX0nO1xuICAgICAgICAgICAgZXhwZWN0KCgpID0+IGZvcm1hdHRlci5mb3JtYXQobmVzdGVkVGV4dCkpLnRvLnRocm93KCdzeW50YXggZXJyb3IgaW4gZm9ybWF0dGVyIHRlbXBsYXRlJyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgdGhyb3cgYSB0b28gZGVlcCBuZXN0aW5nIGVycm9yJywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgaW5wdXRPYmogPSB7XG4gICAgICAgICAgICAgICAgbXlrZXk6ICcke215a2V5fScsXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBmb3JtYXR0ZXIgPSBuZXcgRm9ybWF0dGVyKGlucHV0T2JqKTtcblxuICAgICAgICAgICAgY29uc3QgdGV4dCA9ICcke215a2V5fSc7XG4gICAgICAgICAgICBsZXQgZm9ybWF0dGVkVGV4dCA9IHRleHQ7XG5cbiAgICAgICAgICAgIC8vIENyZWF0ZSBhIHN0cmluZyB3aXRoIDIxIGxldmVscyBvZiBuZXN0aW5nXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IDIxOyBpKyspIHtcbiAgICAgICAgICAgICAgICBmb3JtYXR0ZWRUZXh0ID0gJyR7JyArIGZvcm1hdHRlZFRleHQgKyAnfSc7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGV4cGVjdCgoKSA9PiBmb3JtYXR0ZXIuZm9ybWF0KGZvcm1hdHRlZFRleHQpKS50by50aHJvdygndG9vIGRlZXAgbmVzdGluZycpO1xuICAgICAgICB9KTtcbiAgICAgICAgXG4gICAgfSk7XG5cblxufSk7IiwgImV4cG9ydCB7IGdlbmVyYXRlUmFuZ2VDb21wYXJpc29uRXhwcmVzc2lvbiB9O1xuXG4vKipcbiAqIFRoZSBgZ2VuZXJhdGVSYW5nZUNvbXBhcmlzb25FeHByZXNzaW9uKClgIGZ1bmN0aW9uIGlzIGZ1bmN0aW9uIHRoYXQgZ2VuZXJhdGVzIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uXG4gKiBvZiBhIGNvbXBhcmlzb24gZXhwcmVzc2lvbiBiYXNlZCBvbiBhIHJhbmdlIG9mIHZhbHVlcy4gSXQgdGFrZXMgdGhyZWUgYXJndW1lbnRzOlxuICpcbiAqIC0gZXhwcmVzc2lvbiAocmVxdWlyZWQpOiBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIHJhbmdlIG9mIHZhbHVlcyBpbiB0aGUgZm9ybWF0IG9mIHN0YXJ0MS1lbmQxLHN0YXJ0Mi1lbmQyLHZhbHVlMy4uLi5cbiAqIC0gdmFsdWVOYW1lIChyZXF1aXJlZCk6IGEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgbmFtZSBvZiB0aGUgdmFsdWUgdGhhdCBpcyBiZWluZyBjb21wYXJlZCB0byB0aGUgcmFuZ2Ugb2YgdmFsdWVzLlxuICogLSBvcHRpb25zIChvcHRpb25hbCk6IGFuIG9iamVjdCBjb250YWluaW5nIGFkZGl0aW9uYWwgb3B0aW9ucyB0byBjdXN0b21pemUgdGhlIGNvbXBhcmlzb24gZXhwcmVzc2lvbi5cbiAqXG4gKiBUaGUgZ2VuZXJhdGVSYW5nZUNvbXBhcmlzb25FeHByZXNzaW9uKCkgZnVuY3Rpb24gcmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgY29tcGFyaXNvbiBleHByZXNzaW9uLlxuICpcbiAqICMjIE9wdGlvbnNcbiAqIFRoZSBvcHRpb25zIHBhcmFtZXRlciBpcyBhbiBvYmplY3QgdGhhdCBjYW4gaGF2ZSB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gKlxuICogdXJsRW5jb2RlIChib29sZWFuLCBkZWZhdWx0OiBmYWxzZSk6IGlmIHNldCB0byB0cnVlLCBVUkwgZW5jb2RlcyB0aGUgY29tcGFyaXNvbiBvcGVyYXRvcnMuXG4gKiBhbmRPcCAoc3RyaW5nLCBkZWZhdWx0OiAnJiYnKTogdGhlIGxvZ2ljYWwgQU5EIG9wZXJhdG9yIHRvIHVzZSBpbiB0aGUgZXhwcmVzc2lvbi5cbiAqIG9yT3AgKHN0cmluZywgZGVmYXVsdDogJ3x8Jyk6IHRoZSBsb2dpY2FsIE9SIG9wZXJhdG9yIHRvIHVzZSBpbiB0aGUgZXhwcmVzc2lvbi5cbiAqIGVxT3AgKHN0cmluZywgZGVmYXVsdDogJz09Jyk6IHRoZSBlcXVhbGl0eSBvcGVyYXRvciB0byB1c2UgaW4gdGhlIGV4cHJlc3Npb24uXG4gKiBnZU9wIChzdHJpbmcsIGRlZmF1bHQ6ICc+PScpOiB0aGUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIG9wZXJhdG9yIHRvIHVzZSBpbiB0aGUgZXhwcmVzc2lvbi5cbiAqIGxlT3AgKHN0cmluZywgZGVmYXVsdDogJzw9Jyk6IHRoZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gb3BlcmF0b3IgdG8gdXNlIGluIHRoZSBleHByZXNzaW9uLlxuICpcbiAqIEV4YW1wbGVzXG4gKlxuICogYGBgamF2YXNjcmlwdFxuICogY29uc3QgZXhwcmVzc2lvbiA9ICcwLTEwLDIwLTMwJztcbiAqIGNvbnN0IHZhbHVlTmFtZSA9ICdhZ2UnO1xuICogY29uc3Qgb3B0aW9ucyA9IHsgdXJsRW5jb2RlOiB0cnVlLCBhbmRPcDogJ2FuZCcsIG9yT3A6ICdvcicsIGVxT3A6ICc9JywgZ2VPcDogJz49JywgbGVPcDogJzw9JyB9O1xuICogY29uc3QgY29tcGFyaXNvbkV4cHJlc3Npb24gPSBnZW5lcmF0ZVJhbmdlQ29tcGFyaXNvbkV4cHJlc3Npb24oZXhwcmVzc2lvbiwgdmFsdWVOYW1lLCBvcHRpb25zKTtcbiAqXG4gKiBjb25zb2xlLmxvZyhjb21wYXJpc29uRXhwcmVzc2lvbik7IC8vIGFnZSUzRSUzRDAlMjBhbmQlMjBhZ2UlM0MlM0QxMCUyMG9yJTIwYWdlJTNFJTNEMjAlMjBhbmQlMjBhZ2UlM0MlM0QzMFxuICogYGBgXG4gKlxuICogSW4gdGhpcyBleGFtcGxlLCB0aGUgZ2VuZXJhdGVSYW5nZUNvbXBhcmlzb25FeHByZXNzaW9uKCkgZnVuY3Rpb24gZ2VuZXJhdGVzIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjb21wYXJpc29uXG4gKiBleHByZXNzaW9uIGZvciB0aGUgZXhwcmVzc2lvbiBhbmQgdmFsdWVOYW1lIHBhcmFtZXRlcnMgd2l0aCB0aGUgc3BlY2lmaWVkIG9wdGlvbnMuIFRoZSByZXN1bHRpbmcgY29tcGFyaXNvblxuICogZXhwcmVzc2lvbiBpcyAnYWdlPj0wIGFuZCBhZ2U8PTEwIG9yIGFnZT49MjAgYW5kIGFnZTw9MzAnLCBVUkwgZW5jb2RlZCBhY2NvcmRpbmcgdG8gdGhlIHVybEVuY29kZSBvcHRpb24uXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGV4cHJlc3Npb24gLSBUaGUgc3RyaW5nIGV4cHJlc3Npb24gdG8gZ2VuZXJhdGUgdGhlIGNvbXBhcmlzb24gZm9yLlxuICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB2YWx1ZSB0byBjb21wYXJlIGFnYWluc3QuXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIC0gVGhlIG9wdGlvbmFsIHBhcmFtZXRlcnMuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLnVybEVuY29kZT1mYWxzZV0gLSBXaGV0aGVyIHRvIGVuY29kZSBjb21wYXJpc29uIG9wZXJhdG9ycyBmb3IgdXNlIGluIGEgVVJMLlxuICogQHBhcmFtIHtzdHJpbmd9IFtvcHRpb25zLmFuZE9wPScmJiddIC0gVGhlIGxvZ2ljYWwgQU5EIG9wZXJhdG9yIHRvIHVzZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0aW9ucy5vck9wPSd8fCddIC0gVGhlIGxvZ2ljYWwgT1Igb3BlcmF0b3IgdG8gdXNlLlxuICogQHBhcmFtIHtzdHJpbmd9IFtvcHRpb25zLmVxT3A9Jz09J10gLSBUaGUgY29tcGFyaXNvbiBvcGVyYXRvciBmb3IgZXF1YWxpdHkgdG8gdXNlLlxuICogQHBhcmFtIHtzdHJpbmd9IFtvcHRpb25zLmdlT3A9Jz49J10gLSBUaGUgY29tcGFyaXNvbiBvcGVyYXRvciBmb3IgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRvIHVzZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0aW9ucy5sZU9wPSc8PSddIC0gVGhlIGNvbXBhcmlzb24gb3BlcmF0b3IgZm9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byB0byB1c2UuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZ2VuZXJhdGVkIGNvbXBhcmlzb24gZXhwcmVzc2lvbi5cbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgaW5wdXQgaXMgaW52YWxpZC5cbiAqIEBtZW1iZXJPZiBNb25zdGVyLlRleHRcbiAqIEBzdW1tYXJ5IEdlbmVyYXRlcyBhIGNvbXBhcmlzb24gZXhwcmVzc2lvbiBiYXNlZCBvbiBhIHJhbmdlIG9mIHZhbHVlcy5cbiAqL1xuZnVuY3Rpb24gZ2VuZXJhdGVSYW5nZUNvbXBhcmlzb25FeHByZXNzaW9uKGV4cHJlc3Npb24sIHZhbHVlTmFtZSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3QgeyB1cmxFbmNvZGUgPSBmYWxzZSwgYW5kT3AgPSBcIiYmXCIsIG9yT3AgPSBcInx8XCIsIGVxT3AgPSBcIj09XCIsIGdlT3AgPSBcIj49XCIsIGxlT3AgPSBcIjw9XCIgfSA9IG9wdGlvbnM7XG4gICAgY29uc3QgcmFuZ2VzID0gZXhwcmVzc2lvbi5zcGxpdChcIixcIik7XG4gICAgbGV0IGNvbXBhcmlzb24gPSBcIlwiO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IHJhbmdlID0gcmFuZ2VzW2ldLnRyaW0oKTtcbiAgICAgICAgaWYgKHJhbmdlID09PSBcIlwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgcmFuZ2UgJyR7cmFuZ2V9J2ApO1xuICAgICAgICB9IGVsc2UgaWYgKHJhbmdlLmluY2x1ZGVzKFwiLVwiKSkge1xuICAgICAgICAgICAgY29uc3QgW3N0YXJ0LCBlbmRdID0gcmFuZ2Uuc3BsaXQoXCItXCIpLm1hcCgocykgPT4gKHMgPT09IFwiXCIgPyBudWxsIDogcGFyc2VGbG9hdChzKSkpO1xuICAgICAgICAgICAgaWYgKChzdGFydCAhPT0gbnVsbCAmJiBpc05hTihzdGFydCkpIHx8IChlbmQgIT09IG51bGwgJiYgaXNOYU4oZW5kKSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgdmFsdWUgaW4gcmFuZ2UgJyR7cmFuZ2V9J2ApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHN0YXJ0ICE9PSBudWxsICYmIGVuZCAhPT0gbnVsbCAmJiBzdGFydCA+IGVuZCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCByYW5nZSAnJHtyYW5nZX0nYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBjb21wU3RhcnQgPVxuICAgICAgICAgICAgICAgIHN0YXJ0ICE9PSBudWxsID8gYCR7dmFsdWVOYW1lfSR7dXJsRW5jb2RlID8gZW5jb2RlVVJJQ29tcG9uZW50KGdlT3ApIDogZ2VPcH0ke3N0YXJ0fWAgOiBcIlwiO1xuICAgICAgICAgICAgY29uc3QgY29tcEVuZCA9IGVuZCAhPT0gbnVsbCA/IGAke3ZhbHVlTmFtZX0ke3VybEVuY29kZSA/IGVuY29kZVVSSUNvbXBvbmVudChsZU9wKSA6IGxlT3B9JHtlbmR9YCA6IFwiXCI7XG4gICAgICAgICAgICBjb25zdCBjb21wUmFuZ2UgPSBgJHtjb21wU3RhcnR9JHtjb21wU3RhcnQgJiYgY29tcEVuZCA/IGAgJHthbmRPcH0gYCA6IFwiXCJ9JHtjb21wRW5kfWA7XG4gICAgICAgICAgICBjb21wYXJpc29uICs9IHJhbmdlcy5sZW5ndGggPiAxID8gYCgke2NvbXBSYW5nZX0pYCA6IGNvbXBSYW5nZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gcGFyc2VGbG9hdChyYW5nZSk7XG4gICAgICAgICAgICBpZiAoaXNOYU4odmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHZhbHVlICcke3JhbmdlfSdgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGNvbXBWYWx1ZSA9IGAke3ZhbHVlTmFtZX0ke3VybEVuY29kZSA/IGVuY29kZVVSSUNvbXBvbmVudChlcU9wKSA6IGVxT3B9JHt2YWx1ZX1gO1xuICAgICAgICAgICAgY29tcGFyaXNvbiArPSByYW5nZXMubGVuZ3RoID4gMSA/IGAoJHtjb21wVmFsdWV9KWAgOiBjb21wVmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGkgPCByYW5nZXMubGVuZ3RoIC0gMSkge1xuICAgICAgICAgICAgY29tcGFyaXNvbiArPSBgICR7b3JPcH0gYDtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gY29tcGFyaXNvbjtcbn1cbiIsICJpbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuaW1wb3J0IHtnZW5lcmF0ZVJhbmdlQ29tcGFyaXNvbkV4cHJlc3Npb259IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdGV4dC91dGlsLm1qc1wiO1xuXG5kZXNjcmliZSgnZ2VuZXJhdGVSYW5nZUNvbXBhcmlzb25FeHByZXNzaW9uJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgY29ycmVjdCBjb21wYXJpc29uIGV4cHJlc3Npb24gZm9yIHNpbmdsZSB2YWx1ZXMnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGV4cHJlc3Npb24gPSAnMSwzLDUnO1xuICAgICAgICBjb25zdCB2YWx1ZU5hbWUgPSAneCc7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGdlbmVyYXRlUmFuZ2VDb21wYXJpc29uRXhwcmVzc2lvbihleHByZXNzaW9uLCB2YWx1ZU5hbWUpO1xuICAgICAgICBleHBlY3QocmVzdWx0KS50by5lcXVhbCgnKHg9PTEpIHx8ICh4PT0zKSB8fCAoeD09NSknKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgY29ycmVjdCBjb21wYXJpc29uIGV4cHJlc3Npb24gZm9yIHJhbmdlcycsICgpID0+IHtcbiAgICAgICAgY29uc3QgZXhwcmVzc2lvbiA9ICcxLTMsNi04JztcbiAgICAgICAgY29uc3QgdmFsdWVOYW1lID0gJ3gnO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBnZW5lcmF0ZVJhbmdlQ29tcGFyaXNvbkV4cHJlc3Npb24oZXhwcmVzc2lvbiwgdmFsdWVOYW1lKTtcbiAgICAgICAgZXhwZWN0KHJlc3VsdCkudG8uZXF1YWwoJyh4Pj0xICYmIHg8PTMpIHx8ICh4Pj02ICYmIHg8PTgpJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGNvcnJlY3QgY29tcGFyaXNvbiBleHByZXNzaW9uIGZvciBtaXhlZCByYW5nZXMgYW5kIHNpbmdsZSB2YWx1ZXMnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGV4cHJlc3Npb24gPSAnMS0zLDUsNy05JztcbiAgICAgICAgY29uc3QgdmFsdWVOYW1lID0gJ3gnO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBnZW5lcmF0ZVJhbmdlQ29tcGFyaXNvbkV4cHJlc3Npb24oZXhwcmVzc2lvbiwgdmFsdWVOYW1lKTtcbiAgICAgICAgZXhwZWN0KHJlc3VsdCkudG8uZXF1YWwoJyh4Pj0xICYmIHg8PTMpIHx8ICh4PT01KSB8fCAoeD49NyAmJiB4PD05KScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBhbiBlcnJvciBmb3IgaW52YWxpZCByYW5nZScsICgpID0+IHtcbiAgICAgICAgY29uc3QgZXhwcmVzc2lvbiA9ICcxLTMsNS00JztcbiAgICAgICAgY29uc3QgdmFsdWVOYW1lID0gJ3gnO1xuICAgICAgICBleHBlY3QoKCkgPT4gZ2VuZXJhdGVSYW5nZUNvbXBhcmlzb25FeHByZXNzaW9uKGV4cHJlc3Npb24sIHZhbHVlTmFtZSkpLnRvLnRocm93KGBJbnZhbGlkIHJhbmdlICc1LTQnYCk7XG4gICAgfSk7XG5cblxuICAgIGl0KCdzaG91bGQgdGhyb3cgYW4gZXJyb3IgZm9yIGludmFsaWQgdmFsdWUnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGV4cHJlc3Npb24gPSAnMS0zLGEnO1xuICAgICAgICBjb25zdCB2YWx1ZU5hbWUgPSAneCc7XG4gICAgICAgIGV4cGVjdCgoKSA9PiBnZW5lcmF0ZVJhbmdlQ29tcGFyaXNvbkV4cHJlc3Npb24oZXhwcmVzc2lvbiwgdmFsdWVOYW1lKSkudG8udGhyb3coJ0ludmFsaWQgdmFsdWUnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgY29ycmVjdCBjb21wYXJpc29uIGV4cHJlc3Npb24gd2l0aCBjdXN0b20gb3BlcmF0b3JzJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBleHByZXNzaW9uID0gJzEtMyw1JztcbiAgICAgICAgY29uc3QgdmFsdWVOYW1lID0gJ3gnO1xuICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgYW5kT3A6ICdBTkQnLFxuICAgICAgICAgICAgb3JPcDogJ09SJyxcbiAgICAgICAgICAgIGVxT3A6ICc9PT0nLFxuICAgICAgICAgICAgZ2VPcDogJz49JyxcbiAgICAgICAgICAgIGxlT3A6ICc8PScsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGdlbmVyYXRlUmFuZ2VDb21wYXJpc29uRXhwcmVzc2lvbihleHByZXNzaW9uLCB2YWx1ZU5hbWUsIG9wdGlvbnMpO1xuICAgICAgICBleHBlY3QocmVzdWx0KS50by5lcXVhbCgnKHg+PTEgQU5EIHg8PTMpIE9SICh4PT09NSknKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgY29ycmVjdCBjb21wYXJpc29uIGV4cHJlc3Npb24gd2l0aCB1cmxFbmNvZGUgb3B0aW9uJywgKCkgPT4ge1xuICAgICAgICBjb25zdCB0ZXN0Q2FzZXMgPSBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZXhwcmVzc2lvbjogJzEsMyw1JyxcbiAgICAgICAgICAgICAgICB2YWx1ZU5hbWU6ICd4JyxcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogJyh4JTNEJTNEMSkgfHwgKHglM0QlM0QzKSB8fCAoeCUzRCUzRDUpJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZXhwcmVzc2lvbjogJy0xMCcsXG4gICAgICAgICAgICAgICAgdmFsdWVOYW1lOiAneCcsXG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6ICd4JTNDJTNEMTAnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBleHByZXNzaW9uOiAnMTAtJyxcbiAgICAgICAgICAgICAgICB2YWx1ZU5hbWU6ICd4JyxcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogJ3glM0UlM0QxMCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGV4cHJlc3Npb246ICcxLTMsNi04JyxcbiAgICAgICAgICAgICAgICB2YWx1ZU5hbWU6ICd5JyxcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogJyh5JTNFJTNEMSAmJiB5JTNDJTNEMykgfHwgKHklM0UlM0Q2ICYmIHklM0MlM0Q4KScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGV4cHJlc3Npb246ICcxLTMsNSw3LTknLFxuICAgICAgICAgICAgICAgIHZhbHVlTmFtZTogJ3onLFxuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiAnKHolM0UlM0QxICYmIHolM0MlM0QzKSB8fCAoeiUzRCUzRDUpIHx8ICh6JTNFJTNENyAmJiB6JTNDJTNEOSknLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgXTtcblxuICAgICAgICB0ZXN0Q2FzZXMuZm9yRWFjaCgoe2V4cHJlc3Npb24sIHZhbHVlTmFtZSwgZXhwZWN0ZWR9KSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBnZW5lcmF0ZVJhbmdlQ29tcGFyaXNvbkV4cHJlc3Npb24oZXhwcmVzc2lvbiwgdmFsdWVOYW1lLCB7dXJsRW5jb2RlOiB0cnVlfSk7XG4gICAgICAgICAgICBleHBlY3QocmVzdWx0KS50by5lcXVhbChleHBlY3RlZCk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBjb3JyZWN0IGNvbXBhcmlzb24gZXhwcmVzc2lvbiBmb3Igb3Blbi1lbmRlZCByYW5nZXMgd2l0aCB1cmxFbmNvZGUgb3B0aW9uJywgKCkgPT4ge1xuICAgICAgICBjb25zdCB0ZXN0Q2FzZXMgPSBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZXhwcmVzc2lvbjogJzEwLScsXG4gICAgICAgICAgICAgICAgdmFsdWVOYW1lOiAneCcsXG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6ICd4JTNFJTNEMTAnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBleHByZXNzaW9uOiAnLTEwJyxcbiAgICAgICAgICAgICAgICB2YWx1ZU5hbWU6ICd5JyxcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogJ3klM0MlM0QxMCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICBdO1xuXG4gICAgICAgIHRlc3RDYXNlcy5mb3JFYWNoKCh7ZXhwcmVzc2lvbiwgdmFsdWVOYW1lLCBleHBlY3RlZH0pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGdlbmVyYXRlUmFuZ2VDb21wYXJpc29uRXhwcmVzc2lvbihleHByZXNzaW9uLCB2YWx1ZU5hbWUsIHt1cmxFbmNvZGU6IHRydWV9KTtcbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHQpLnRvLmVxdWFsKGV4cGVjdGVkKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cblxufSk7XG4iLCAiaW1wb3J0IHtleHBlY3R9IGZyb20gJ2NoYWknO1xuaW1wb3J0IHtnZXRTbG90dGVkTm9kZXN9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvZG9tL3Nsb3R0ZWQubWpzXCI7XG5cblxuZGVzY3JpYmUoJ2dldFNsb3R0ZWROb2RlcycsICgpID0+IHtcblxuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gYW4gZW1wdHkgU2V0IGlmIHRoZXJlIGlzIG5vIFNoYWRvd1Jvb3QnLCAoKSA9PiB7XG4gICAgICAgIGV4cGVjdChnZXRTbG90dGVkTm9kZXMpLmlzLmEoJ2Z1bmN0aW9uJyk7XG4gICAgfSk7XG5cblxufSk7XG5cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGV4dGVuZCB9IGZyb20gXCIuLi8uLi8uLi9kYXRhL2V4dGVuZC5tanNcIjtcbmltcG9ydCB7IExpbmsgfSBmcm9tIFwiLi4vbGluay5tanNcIjtcbmltcG9ydCB7IGluc3RhbmNlU3ltYm9sIH0gZnJvbSBcIi4uLy4uLy4uL2NvbnN0YW50cy5tanNcIjtcbmV4cG9ydCB7IFN0eWxlc2hlZXQgfTtcblxuLyoqXG4gKiBUaGlzIGNsYXNzIGlzIHVzZWQgYnkgdGhlIHJlc291cmNlIG1hbmFnZXIgdG8gZW1iZWQgZXh0ZXJuYWwgcmVzb3VyY2VzLlxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjUuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTS5SZXNvdXJjZVxuICogQHN1bW1hcnkgQSBSZXNvdXJjZSBjbGFzc1xuICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVE1ML0VsZW1lbnQvbGlua1xuICovXG5jbGFzcyBTdHlsZXNoZWV0IGV4dGVuZHMgTGluayB7XG4gICAgLyoqXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd9IHJlbCB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9FbGVtZW50L2xpbmsjYXR0ci1yZWx9XG4gICAgICovXG4gICAgZ2V0IGRlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gZXh0ZW5kKHt9LCBzdXBlci5kZWZhdWx0cywge1xuICAgICAgICAgICAgcmVsOiBcInN0eWxlc2hlZXRcIixcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMi4xLjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci9kb20vcmVzb3VyY2UvbGluay9zdHlsZXNoZWV0XCIpO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGV4dGVuZCB9IGZyb20gXCIuLi8uLi9kYXRhL2V4dGVuZC5tanNcIjtcbmltcG9ydCB7XG4gICAgQVRUUklCVVRFX0NMQVNTLFxuICAgIEFUVFJJQlVURV9IUkVGLFxuICAgIEFUVFJJQlVURV9JRCxcbiAgICBBVFRSSUJVVEVfTk9OQ0UsXG4gICAgQVRUUklCVVRFX1NSQyxcbiAgICBBVFRSSUJVVEVfVElUTEUsXG4gICAgQVRUUklCVVRFX1RZUEUsXG4gICAgVEFHX0xJTkssXG59IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQgeyBLRVlfRE9DVU1FTlQsIHJlZmVyZW5jZVN5bWJvbCwgUmVzb3VyY2UgfSBmcm9tIFwiLi4vcmVzb3VyY2UubWpzXCI7XG5pbXBvcnQgeyBpbnN0YW5jZVN5bWJvbCB9IGZyb20gXCIuLi8uLi9jb25zdGFudHMubWpzXCI7XG5leHBvcnQgeyBMaW5rIH07XG5cbi8qKlxuICogVGhpcyBjbGFzcyBpcyB1c2VkIGJ5IHRoZSByZXNvdXJjZSBtYW5hZ2VyIHRvIGVtYmVkIGV4dGVybmFsIHJlc291cmNlcy5cbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI1LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET00uUmVzb3VyY2VcbiAqIEBzdW1tYXJ5IEEgUmVzb3VyY2UgY2xhc3NcbiAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9FbGVtZW50L2xpbmtcbiAqL1xuY2xhc3MgTGluayBleHRlbmRzIFJlc291cmNlIHtcbiAgICAvKipcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gYXMge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUTUwvRWxlbWVudC9saW5rI2F0dHItYXN9XG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd9IGNyb3NzT3JpZ2luPWFub255bW91cyB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9FbGVtZW50L3NjcmlwdCNhdHRyLWNyb3Nzb3JpZ2lufVxuICAgICAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gZGlzYWJsZWRcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gaHJlZiB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9FbGVtZW50L2xpbmsjYXR0ci1ocmVmfVxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBocmVmbGFuZyB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9FbGVtZW50L2xpbmsjYXR0ci1ocmVmbGFuZ31cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gaW1hZ2VzaXplcyB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9FbGVtZW50L2xpbmsjYXR0ci1pbWFnZXNpemVzfVxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBpbWFnZXNyY3NldCB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9FbGVtZW50L2xpbmsjYXR0ci1pbWFnZXNyY3NldH1cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gaW50ZWdyaXR5IHtAbGluayBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVE1ML0VsZW1lbnQvbGluayNhdHRyLWludGVncml0eX1cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gbWVkaWEge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUTUwvRWxlbWVudC9saW5rI2F0dHItbWVkaWF9XG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd9IHByZWZldGNoIHtAbGluayBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVE1ML0VsZW1lbnQvbGluayNhdHRyLXByZWZldGNofVxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSByZWZlcnJlcnBvbGljeSB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9FbGVtZW50L2xpbmsjYXR0ci1yZWZlcnJlcnBvbGljeX1cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gcmVsIHtAbGluayBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVE1ML0VsZW1lbnQvbGluayNhdHRyLXJlbH1cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gdHlwZSB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9FbGVtZW50L2xpbmsjYXR0ci10eXBlfVxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBzaXplcyB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9FbGVtZW50L2xpbmsjYXR0ci1zaXplc31cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gbm9uY2Uge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUTUwvRWxlbWVudC9zY3JpcHQjYXR0ci1ub25jZX1cbiAgICAgKi9cbiAgICBnZXQgZGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBleHRlbmQoe30sIHN1cGVyLmRlZmF1bHRzLCB7XG4gICAgICAgICAgICBhczogdW5kZWZpbmVkLFxuICAgICAgICAgICAgY3Jvc3NPcmlnaW46IFwiYW5vbnltb3VzXCIsXG4gICAgICAgICAgICBkaXNhYmxlZDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgaHJlZjogdW5kZWZpbmVkLFxuICAgICAgICAgICAgaHJlZmxhbmc6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGltYWdlc2l6ZXM6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGltYWdlc3Jjc2V0OiB1bmRlZmluZWQsXG4gICAgICAgICAgICBpbnRlZ3JpdHk6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIG1lZGlhOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBwcmVmZXRjaDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgcmVmZXJyZXJwb2xpY3k6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHJlbDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgc2l6ZXM6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHR5cGU6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIG5vbmNlOiB1bmRlZmluZWQsXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgYGluc3RhbmNlb2ZgIG9wZXJhdG9yLlxuICAgICAqIEByZXR1cm5zIHtzeW1ib2x9XG4gICAgICogQHNpbmNlIDIuMS4wXG4gICAgICovXG4gICAgc3RhdGljIGdldCBbaW5zdGFuY2VTeW1ib2xdKCkge1xuICAgICAgICByZXR1cm4gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvZG9tL3Jlc291cmNlL2xpbmtcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtNb25zdGVyLkRPTS5SZXNvdXJjZS5MaW5rfVxuICAgICAqL1xuICAgIGNyZWF0ZSgpIHtcbiAgICAgICAgY3JlYXRlRWxlbWVudC5jYWxsKHRoaXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldFVSTEF0dHJpYnV0ZSgpIHtcbiAgICAgICAgcmV0dXJuIEFUVFJJQlVURV9IUkVGO1xuICAgIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHJldHVybiB7TW9uc3Rlci5ET00uUmVzb3VyY2UuTGlua31cbiAqL1xuZnVuY3Rpb24gY3JlYXRlRWxlbWVudCgpIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgIGNvbnN0IGRvY3VtZW50ID0gc2VsZi5nZXRPcHRpb24oS0VZX0RPQ1VNRU5UKTtcbiAgICBzZWxmW3JlZmVyZW5jZVN5bWJvbF0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFRBR19MSU5LKTtcblxuICAgIGZvciAobGV0IGtleSBvZiBbXG4gICAgICAgIFwiYXNcIixcbiAgICAgICAgXCJjcm9zc09yaWdpblwiLFxuICAgICAgICBcImRpc2FibGVkXCIsXG4gICAgICAgIFwiaHJlZlwiLFxuICAgICAgICBcImhyZWZsYW5nXCIsXG4gICAgICAgIFwiaW1hZ2VzaXplc1wiLFxuICAgICAgICBcImltYWdlc3Jjc2V0XCIsXG4gICAgICAgIFwiaW50ZWdyaXR5XCIsXG4gICAgICAgIFwibWVkaWFcIixcbiAgICAgICAgXCJwcmVmZXRjaFwiLFxuICAgICAgICBcInJlZmVycmVycG9saWN5XCIsXG4gICAgICAgIFwic2l6ZXNcIixcbiAgICAgICAgXCJyZWxcIixcbiAgICAgICAgXCJ0eXBlXCIsXG4gICAgICAgIEFUVFJJQlVURV9IUkVGLFxuICAgICAgICBBVFRSSUJVVEVfSUQsXG4gICAgICAgIEFUVFJJQlVURV9DTEFTUyxcbiAgICAgICAgQVRUUklCVVRFX1RJVExFLFxuICAgICAgICBBVFRSSUJVVEVfTk9OQ0UsXG4gICAgXSkge1xuICAgICAgICBpZiAoc2VsZi5nZXRPcHRpb24oa2V5KSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBzZWxmW3JlZmVyZW5jZVN5bWJvbF1ba2V5XSA9IHNlbGYuZ2V0T3B0aW9uKGtleSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gc2VsZjtcbn1cbiIsICIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBjaGFpIGZyb20gXCJjaGFpXCJcbmltcG9ydCB7U3R5bGVzaGVldH0gZnJvbSBcIi4uLy4uLy4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9kb20vcmVzb3VyY2UvbGluay9zdHlsZXNoZWV0Lm1qc1wiO1xuaW1wb3J0IHtEYXRhVXJsfSBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL2RhdGF1cmwubWpzXCI7XG5pbXBvcnQge0lEfSBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL2lkLm1qc1wiO1xuaW1wb3J0IHtjaGFpRG9tfSBmcm9tIFwiLi4vLi4vLi4vLi4vdXRpbC9jaGFpLWRvbS5tanNcIjtcbmltcG9ydCB7Y2xlYW51cERPTUZyb21UZXN0aW5nLCBpbml0TXV0YXRpb25PYnNlcnZlckZvclRlc3Rpbmd9IGZyb20gXCIuLi8uLi8uLi8uLi91dGlsL2NsZWFudXBkb20ubWpzXCI7XG5pbXBvcnQge2luaXRKU0RPTX0gZnJvbSBcIi4uLy4uLy4uLy4uL3V0aWwvanNkb20ubWpzXCI7XG5cbmxldCBleHBlY3QgPSBjaGFpLmV4cGVjdDtcblxuY2hhaS51c2UoY2hhaURvbSk7XG5cbmxldCBodG1sMSA9IGBcblxuYDtcblxuXG5kZXNjcmliZSgnU3R5bGVzaGVldCcsIGZ1bmN0aW9uICgpIHtcblxuICAgIGJlZm9yZShmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICBpbml0SlNET00oe1xuICAgICAgICAgICAgcnVuU2NyaXB0czogXCJkYW5nZXJvdXNseVwiLFxuICAgICAgICAgICAgcmVzb3VyY2VzOiBcInVzYWJsZVwiXG4gICAgICAgIH0pLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgZG9uZSgpXG4gICAgICAgIH0pLmNhdGNoKGUgPT4gZG9uZShlKSk7XG4gICAgfSk7XG5cbiAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAgaW5pdE11dGF0aW9uT2JzZXJ2ZXJGb3JUZXN0aW5nKClcbiAgICB9KVxuXG4gICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgICAgY2xlYW51cERPTUZyb21UZXN0aW5nKCk7XG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCdTdHlsZXNoZWV0KCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdjb25uZWN0KCkuYXZhaWxhYmxlKCknLCBmdW5jdGlvbiAoZG9uZSkge1xuXG4gICAgICAgICAgICBjb25zdCBzdHlsZXNoZWV0ID0gbmV3IFN0eWxlc2hlZXQoe1xuICAgICAgICAgICAgICAgIGhyZWY6IG5ldyBEYXRhVXJsKCcnLCAndGV4dC9jc3MnKS50b1N0cmluZygpLFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHN0eWxlc2hlZXQuY29ubmVjdCgpLmF2YWlsYWJsZSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGlkID0gc3R5bGVzaGVldC5nZXRPcHRpb24oJ2lkJylcbiAgICAgICAgICAgICAgICBkb25lKClcbiAgICAgICAgICAgIH0pLmNhdGNoKGUgPT4gZG9uZShlKSk7XG5cbiAgICAgICAgfSlcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdFeHRlcm5hbCBTdHlsZXNoZWV0JywgKCkgPT4ge1xuXG4gICAgICAgIGxldCBpZCA9IG5ldyBJRCgnU3R5bGVzaGVldCcpLnRvU3RyaW5nKCk7XG4gICAgICAgIGxldCBzdHlsZXNoZWV0LCB1cmwgPSAnaHR0cHM6Ly9tb25zdGVyanMub3JnL2Fzc2V0cy9lbXB0eS5jc3M/JyArIGlkO1xuXG4gICAgICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuXG4gICAgICAgICAgICBzdHlsZXNoZWV0ID0gbmV3IFN0eWxlc2hlZXQoe1xuICAgICAgICAgICAgICAgIGhyZWY6IHVybCxcbiAgICAgICAgICAgICAgICBpZDogaWQsXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnYXBwZW5kIGFuZCByZW1vdmUgU3R5bGVzaGVldCAnLCAoZG9uZSkgPT4ge1xuXG4gICAgICAgICAgICBleHBlY3Qoc3R5bGVzaGVldC5pc0Nvbm5lY3RlZCgpKS50by5iZS5mYWxzZTtcblxuICAgICAgICAgICAgc3R5bGVzaGVldC5jb25uZWN0KCkuYXZhaWxhYmxlKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KHN0eWxlc2hlZXQuaXNDb25uZWN0ZWQoKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgICAgICAgICBleHBlY3QoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW2hyZWY9XCInICsgdXJsICsgJ1wiXScpKS50by5leGlzdDtcblxuICAgICAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKS5yZW1vdmUoKTtcbiAgICAgICAgICAgICAgICBleHBlY3Qoc3R5bGVzaGVldC5pc0Nvbm5lY3RlZCgpKS50by5iZS5mYWxzZTtcbiAgICAgICAgICAgICAgICBleHBlY3QoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW2hyZWY9XCInICsgdXJsICsgJ1wiXScpKS5ub3QudG8uZXhpc3Q7XG5cbiAgICAgICAgICAgICAgICBzdHlsZXNoZWV0LmNvbm5lY3QoKS5hdmFpbGFibGUoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KHN0eWxlc2hlZXQuaXNDb25uZWN0ZWQoKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ1tocmVmPVwiJyArIHVybCArICdcIl0nKSkudG8uZXhpc3Q7XG5cbiAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpLnJlbW92ZSgpO1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW2hyZWY9XCInICsgdXJsICsgJ1wiXScpKS5ub3QudG8uZXhpc3Q7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChzdHlsZXNoZWV0LmlzQ29ubmVjdGVkKCkpLnRvLmJlLmZhbHNlO1xuXG4gICAgICAgICAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICAgICAgICAgIH0pLmNhdGNoKGUgPT4gZG9uZShlKSk7XG5cblxuICAgICAgICAgICAgfSkuY2F0Y2goZSA9PiBkb25lKGUpKTtcblxuXG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxuXG59KTsiLCAiLyoqKioqKioqXG5cbiBDb252ZXJ0IGNoYWktZG9tIDEuOC4xIHRvIGVzIG1vZHVsZSwgd2l0aG91dCBhbnkgb3RoZXIgbW9kaWZpY2F0aW9uLlxuIEZyb20gaHR0cHM6Ly9naXRodWIuY29tL25hdGhhbmJva3RhZS9jaGFpLWRvbS9ibG9iLzg2YzM0MjMvY2hhaS1kb20uanNcbiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL25hdGhhbmJva3RhZS9jaGFpLWRvbS9pc3N1ZXMvMzhcblxuIFVzYWdlOlxuIGltcG9ydCB7IGNoYWlEb20gfSBmcm9tICc8cGF0aC10bz4vY2hhaS1kb20nO1xuIGNoYWkudXNlKGNoYWlEb20pO1xuXG4gQ29weXJpZ2h0IChjKSAyMDE1IE5hdGhhbiBCbGFjayBhbmQgb3RoZXIgY29udHJpYnV0b3JzXG5cbiBUaGlzIHdvcmsgaXMgbGljZW5zZWQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBNSVQgbGljZW5zZS4gRm9yIGEgY29weSwgc2VlIDxodHRwczovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL01JVD4uXG5cbiAqKioqKioqKioqL1xuXG5leHBvcnQgZnVuY3Rpb24gY2hhaURvbShjaGFpLCB1dGlscykge1xuICAgIGxldCBmbGFnID0gdXRpbHMuZmxhZyxcblxuICAgICAgICBlbFRvU3RyaW5nID0gZnVuY3Rpb24oZWwpIHtcbiAgICAgICAgICAgIGxldCBkZXNjXG4gICAgICAgICAgICBpZiAoaXNOb2RlTGlzdChlbCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoZWwubGVuZ3RoID09PSAwKSByZXR1cm4gJ2VtcHR5IE5vZGVMaXN0J1xuICAgICAgICAgICAgICAgIGRlc2MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChlbCwgMCwgNSkubWFwKGVsVG9TdHJpbmcpLmpvaW4oJywgJylcbiAgICAgICAgICAgICAgICByZXR1cm4gZWwubGVuZ3RoID4gNSA/IGRlc2MgKyAnLi4uICgrJyArIChlbC5sZW5ndGggLSA1KSArICcgbW9yZSknIDogZGVzY1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFpc0hUTUxFbGVtZW50KGVsKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBTdHJpbmcoZWwpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGRlc2MgPSBlbC50YWdOYW1lLnRvTG93ZXJDYXNlKClcbiAgICAgICAgICAgIGlmIChlbC5pZCkge1xuICAgICAgICAgICAgICAgIGRlc2MgKz0gJyMnICsgZWwuaWRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChlbC5jbGFzc05hbWUpIHtcbiAgICAgICAgICAgICAgICBkZXNjICs9ICcuJyArIFN0cmluZyhlbC5jbGFzc05hbWUpLnJlcGxhY2UoL1xccysvZywgJy4nKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQXJyYXkucHJvdG90eXBlLmZvckVhY2guY2FsbChlbC5hdHRyaWJ1dGVzLCBmdW5jdGlvbihhdHRyKSB7XG4gICAgICAgICAgICAgICAgaWYgKGF0dHIubmFtZSAhPT0gJ2NsYXNzJyAmJiBhdHRyLm5hbWUgIT09ICdpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVzYyArPSAnWycgKyBhdHRyLm5hbWUgKyAoYXR0ci52YWx1ZSA/ICc9XCInICsgYXR0ci52YWx1ZSArICdcIl0nIDogJ10nKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICByZXR1cm4gZGVzY1xuICAgICAgICB9LFxuXG4gICAgICAgIGF0dHJBc3NlcnQgPSBmdW5jdGlvbihuYW1lLCB2YWwpIHtcbiAgICAgICAgICAgIHZhciBlbCA9IGZsYWcodGhpcywgJ29iamVjdCcpLCBhY3R1YWwgPSBlbC5nZXRBdHRyaWJ1dGUobmFtZSlcblxuICAgICAgICAgICAgaWYgKCFmbGFnKHRoaXMsICduZWdhdGUnKSB8fCB1bmRlZmluZWQgPT09IHZhbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgICAgICAgICAgICAhIWVsLmF0dHJpYnV0ZXNbbmFtZV1cbiAgICAgICAgICAgICAgICAgICAgLCAnZXhwZWN0ZWQgJyArIGVsVG9TdHJpbmcoZWwpICsgJyB0byBoYXZlIGFuIGF0dHJpYnV0ZSAje2V4cH0nXG4gICAgICAgICAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKGVsKSArICcgbm90IHRvIGhhdmUgYW4gYXR0cmlidXRlICN7ZXhwfSdcbiAgICAgICAgICAgICAgICAgICAgLCBuYW1lXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodW5kZWZpbmVkICE9PSB2YWwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICAgICAgICAgICAgdmFsID09PSBhY3R1YWxcbiAgICAgICAgICAgICAgICAgICAgLCAnZXhwZWN0ZWQgJyArIGVsVG9TdHJpbmcoZWwpICsgJyB0byBoYXZlIGFuIGF0dHJpYnV0ZSAnICsgdXRpbHMuaW5zcGVjdChuYW1lKSArICcgd2l0aCB0aGUgdmFsdWUgI3tleHB9LCBidXQgdGhlIHZhbHVlIHdhcyAje2FjdH0nXG4gICAgICAgICAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKGVsKSArICcgbm90IHRvIGhhdmUgYW4gYXR0cmlidXRlICcgKyB1dGlscy5pbnNwZWN0KG5hbWUpICsgJyB3aXRoIHRoZSB2YWx1ZSAje2FjdH0nXG4gICAgICAgICAgICAgICAgICAgICwgdmFsXG4gICAgICAgICAgICAgICAgICAgICwgYWN0dWFsXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmbGFnKHRoaXMsICdvYmplY3QnLCBhY3R1YWwpXG4gICAgICAgIH0sXG5cbiAgICAgICAgaXNIVE1MRWxlbWVudCA9IGZ1bmN0aW9uKGVsKSB7XG4gICAgICAgICAgICByZXR1cm4gZWwubm9kZVR5cGUgPT09IDEgLy8gd2luZG93Lk5vZGUuRUxFTUVOVF9OT0RFXG4gICAgICAgIH0sXG5cbiAgICAgICAgaXNOb2RlTGlzdCA9IGZ1bmN0aW9uKG9iaikge1xuICAgICAgICAgICAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmopID09PSAnW29iamVjdCBOb2RlTGlzdF0nXG4gICAgICAgIH1cblxuICAgIHV0aWxzLmVsVG9TdHJpbmcgPSBlbFRvU3RyaW5nXG4gICAgY2hhaS5Bc3NlcnRpb24uYWRkTWV0aG9kKCdhdHRyJywgYXR0ckFzc2VydClcbiAgICBjaGFpLkFzc2VydGlvbi5hZGRNZXRob2QoJ2F0dHJpYnV0ZScsIGF0dHJBc3NlcnQpXG5cbiAgICBjaGFpLkFzc2VydGlvbi5hZGRNZXRob2QoJ2NsYXNzJywgZnVuY3Rpb24oY2xhc3NOYW1lKSB7XG4gICAgICAgIHZhciBlbCA9IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgICAgZWwuY2xhc3NMaXN0LmNvbnRhaW5zKGNsYXNzTmFtZSlcbiAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKGVsKSArICcgdG8gaGF2ZSBjbGFzcyAje2V4cH0nXG4gICAgICAgICAgICAsICdleHBlY3RlZCAnICsgZWxUb1N0cmluZyhlbCkgKyAnIG5vdCB0byBoYXZlIGNsYXNzICN7ZXhwfSdcbiAgICAgICAgICAgICwgY2xhc3NOYW1lXG4gICAgICAgIClcbiAgICB9KVxuXG4gICAgY2hhaS5Bc3NlcnRpb24uYWRkTWV0aG9kKCdpZCcsIGZ1bmN0aW9uKGlkKSB7XG4gICAgICAgIHZhciBlbCA9IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgICAgZWwuaWQgPT0gaWRcbiAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKGVsKSArICcgdG8gaGF2ZSBpZCAje2V4cH0nXG4gICAgICAgICAgICAsICdleHBlY3RlZCAnICsgZWxUb1N0cmluZyhlbCkgKyAnIG5vdCB0byBoYXZlIGlkICN7ZXhwfSdcbiAgICAgICAgICAgICwgaWRcbiAgICAgICAgKVxuICAgIH0pXG5cbiAgICBjaGFpLkFzc2VydGlvbi5hZGRNZXRob2QoJ2h0bWwnLCBmdW5jdGlvbihodG1sKSB7XG4gICAgICAgIHZhciBlbCA9IGZsYWcodGhpcywgJ29iamVjdCcpLCBhY3R1YWwgPSBmbGFnKHRoaXMsICdvYmplY3QnKS5pbm5lckhUTUxcblxuICAgICAgICBpZiAoZmxhZyh0aGlzLCAnY29udGFpbnMnKSkge1xuICAgICAgICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgICAgICAgYWN0dWFsLmluZGV4T2YoaHRtbCkgPj0gMFxuICAgICAgICAgICAgICAgICwgJ2V4cGVjdGVkICN7YWN0fSB0byBjb250YWluIEhUTUwgI3tleHB9J1xuICAgICAgICAgICAgICAgICwgJ2V4cGVjdGVkICN7YWN0fSBub3QgdG8gY29udGFpbiBIVE1MICN7ZXhwfSdcbiAgICAgICAgICAgICAgICAsIGh0bWxcbiAgICAgICAgICAgICAgICAsIGFjdHVhbFxuICAgICAgICAgICAgKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgICAgICAgYWN0dWFsID09PSBodG1sXG4gICAgICAgICAgICAgICAgLCAnZXhwZWN0ZWQgJyArIGVsVG9TdHJpbmcoZWwpICsgJyB0byBoYXZlIEhUTUwgI3tleHB9LCBidXQgdGhlIEhUTUwgd2FzICN7YWN0fSdcbiAgICAgICAgICAgICAgICAsICdleHBlY3RlZCAnICsgZWxUb1N0cmluZyhlbCkgKyAnIG5vdCB0byBoYXZlIEhUTUwgI3tleHB9J1xuICAgICAgICAgICAgICAgICwgaHRtbFxuICAgICAgICAgICAgICAgICwgYWN0dWFsXG4gICAgICAgICAgICApXG4gICAgICAgIH1cbiAgICB9KVxuXG4gICAgY2hhaS5Bc3NlcnRpb24uYWRkQ2hhaW5hYmxlTWV0aG9kKCd0cmltbWVkJywgbnVsbCwgZnVuY3Rpb24oKSB7XG4gICAgICAgIGZsYWcodGhpcywgJ3RyaW0tdGV4dCcsIHRydWUpXG4gICAgfSlcblxuICAgIGNoYWkuQXNzZXJ0aW9uLmFkZE1ldGhvZCgndGV4dCcsIGZ1bmN0aW9uKHRleHQpIHtcbiAgICAgICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpLCBjb250YWlucyA9IGZsYWcodGhpcywgJ2NvbnRhaW5zJyksXG4gICAgICAgICAgICB0cmltID0gZmxhZyh0aGlzLCAndHJpbS10ZXh0JyksIGFjdHVhbCwgcmVzdWx0XG5cbiAgICAgICAgaWYgKGlzTm9kZUxpc3Qob2JqKSkge1xuICAgICAgICAgICAgYWN0dWFsID0gQXJyYXkucHJvdG90eXBlLm1hcC5jYWxsKG9iaiwgZnVuY3Rpb24oZWwpIHsgcmV0dXJuIHRyaW0gPyBlbC50ZXh0Q29udGVudC50cmltKCkgOiBlbC50ZXh0Q29udGVudCB9KVxuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodGV4dCkpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBjb250YWlucyA/XG4gICAgICAgICAgICAgICAgICAgIHRleHRbZmxhZyh0aGlzLCAnbmVnYXRlJykgPyAnc29tZScgOiAnZXZlcnknXShmdW5jdGlvbih0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gQXJyYXkucHJvdG90eXBlLnNvbWUuY2FsbChvYmosIGZ1bmN0aW9uKGVsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICh0cmltID8gZWwudGV4dENvbnRlbnQudHJpbSgpIDogZWwudGV4dENvbnRlbnQpID09PSB0XG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICA6XG4gICAgICAgICAgICAgICAgICAgIHV0aWxzLmVxbChhY3R1YWwsIHRleHQpXG5cbiAgICAgICAgICAgICAgICBhY3R1YWwgPSBhY3R1YWwuam9pbigpXG4gICAgICAgICAgICAgICAgdGV4dCA9IHRleHQuam9pbigpXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGFjdHVhbCA9IGFjdHVhbC5qb2luKCcnKVxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGNvbnRhaW5zID8gYWN0dWFsLmluZGV4T2YodGV4dCkgPj0gMCA6IGFjdHVhbCA9PT0gdGV4dFxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYWN0dWFsID0gdHJpbSA/IG9iai50ZXh0Q29udGVudC50cmltKCkgOiBvYmoudGV4dENvbnRlbnRcbiAgICAgICAgICAgIHJlc3VsdCA9IGNvbnRhaW5zID8gYWN0dWFsLmluZGV4T2YodGV4dCkgPj0gMCA6IGFjdHVhbCA9PT0gdGV4dFxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIG9iakRlc2MgPSBlbFRvU3RyaW5nKG9iaiksIHRleHRNc2cgPSB0cmltID8gJ3RyaW1tZWQgdGV4dCcgOiAndGV4dCdcbiAgICAgICAgaWYgKGNvbnRhaW5zKSB7XG4gICAgICAgICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICAgICAgICByZXN1bHRcbiAgICAgICAgICAgICAgICAsICdleHBlY3RlZCAnICsgb2JqRGVzYyArICcgdG8gY29udGFpbiAje2V4cH0sIGJ1dCB0aGUgJyArIHRleHRNc2cgKyAnIHdhcyAje2FjdH0nXG4gICAgICAgICAgICAgICAgLCAnZXhwZWN0ZWQgJyArIG9iakRlc2MgKyAnIG5vdCB0byBjb250YWluICN7ZXhwfSwgYnV0IHRoZSAnICsgdGV4dE1zZyArICcgd2FzICN7YWN0fSdcbiAgICAgICAgICAgICAgICAsIHRleHRcbiAgICAgICAgICAgICAgICAsIGFjdHVhbFxuICAgICAgICAgICAgKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgICAgICAgcmVzdWx0XG4gICAgICAgICAgICAgICAgLCAnZXhwZWN0ZWQgJyArIG9iakRlc2MgKyAnIHRvIGhhdmUgJyArIHRleHRNc2cgKyAnICN7ZXhwfSwgYnV0IHRoZSAnICsgdGV4dE1zZyArICcgd2FzICN7YWN0fSdcbiAgICAgICAgICAgICAgICAsICdleHBlY3RlZCAnICsgb2JqRGVzYyArICcgbm90IHRvIGhhdmUgJyArIHRleHRNc2cgKyAnICN7ZXhwfSdcbiAgICAgICAgICAgICAgICAsIHRleHRcbiAgICAgICAgICAgICAgICAsIGFjdHVhbFxuICAgICAgICAgICAgKVxuICAgICAgICB9XG4gICAgfSlcblxuICAgIGNoYWkuQXNzZXJ0aW9uLmFkZE1ldGhvZCgndmFsdWUnLCBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICB2YXIgZWwgPSBmbGFnKHRoaXMsICdvYmplY3QnKSwgYWN0dWFsID0gZmxhZyh0aGlzLCAnb2JqZWN0JykudmFsdWVcbiAgICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgICBmbGFnKHRoaXMsICdvYmplY3QnKS52YWx1ZSA9PT0gdmFsdWVcbiAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKGVsKSArICcgdG8gaGF2ZSB2YWx1ZSAje2V4cH0sIGJ1dCB0aGUgdmFsdWUgd2FzICN7YWN0fSdcbiAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKGVsKSArICcgbm90IHRvIGhhdmUgdmFsdWUgI3tleHB9J1xuICAgICAgICAgICAgLCB2YWx1ZVxuICAgICAgICAgICAgLCBhY3R1YWxcbiAgICAgICAgKVxuICAgIH0pXG5cbiAgICBjaGFpLkFzc2VydGlvbi5vdmVyd3JpdGVQcm9wZXJ0eSgnZXhpc3QnLCBmdW5jdGlvbihfc3VwZXIpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAgICAgICBpZiAoaXNOb2RlTGlzdChvYmopKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgICAgICAgICAgIG9iai5sZW5ndGggPiAwXG4gICAgICAgICAgICAgICAgICAgICwgJ2V4cGVjdGVkIGFuIGVtcHR5IE5vZGVMaXN0IHRvIGhhdmUgbm9kZXMnXG4gICAgICAgICAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKG9iaikgKyAnIHRvIG5vdCBleGlzdCcpXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9KVxuXG4gICAgY2hhaS5Bc3NlcnRpb24ub3ZlcndyaXRlUHJvcGVydHkoJ2VtcHR5JywgZnVuY3Rpb24oX3N1cGVyKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgICAgICAgaWYgKGlzSFRNTEVsZW1lbnQob2JqKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgICAgICAgICAgICBvYmouY2hpbGRyZW4ubGVuZ3RoID09PSAwXG4gICAgICAgICAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKG9iaikgKyAnIHRvIGJlIGVtcHR5J1xuICAgICAgICAgICAgICAgICAgICAsICdleHBlY3RlZCAnICsgZWxUb1N0cmluZyhvYmopICsgJyB0byBub3QgYmUgZW1wdHknKVxuICAgICAgICAgICAgfSBlbHNlIGlmIChpc05vZGVMaXN0KG9iaikpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICAgICAgICAgICAgb2JqLmxlbmd0aCA9PT0gMFxuICAgICAgICAgICAgICAgICAgICAsICdleHBlY3RlZCAnICsgZWxUb1N0cmluZyhvYmopICsgJyB0byBiZSBlbXB0eSdcbiAgICAgICAgICAgICAgICAgICAgLCAnZXhwZWN0ZWQgJyArIGVsVG9TdHJpbmcob2JqKSArICcgdG8gbm90IGJlIGVtcHR5JylcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cylcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0pXG5cbiAgICBjaGFpLkFzc2VydGlvbi5vdmVyd3JpdGVDaGFpbmFibGVNZXRob2QoJ2xlbmd0aCcsXG4gICAgICAgIGZ1bmN0aW9uKF9zdXBlcikge1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgICAgICAgICAgIGlmIChpc05vZGVMaXN0KG9iaikgfHwgaXNIVE1MRWxlbWVudChvYmopKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBhY3R1YWxMZW5ndGggPSBvYmouY2hpbGRyZW4gPyBvYmouY2hpbGRyZW4ubGVuZ3RoIDogb2JqLmxlbmd0aFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICAgICAgICAgICAgICAgIGFjdHVhbExlbmd0aCA9PT0gbGVuZ3RoXG4gICAgICAgICAgICAgICAgICAgICAgICAsICdleHBlY3RlZCAnICsgZWxUb1N0cmluZyhvYmopICsgJyB0byBoYXZlICN7ZXhwfSBjaGlsZHJlbiBidXQgaXQgaGFkICN7YWN0fSBjaGlsZHJlbidcbiAgICAgICAgICAgICAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKG9iaikgKyAnIHRvIG5vdCBoYXZlICN7ZXhwfSBjaGlsZHJlbidcbiAgICAgICAgICAgICAgICAgICAgICAgICwgbGVuZ3RoXG4gICAgICAgICAgICAgICAgICAgICAgICAsIGFjdHVhbExlbmd0aFxuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cylcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGZ1bmN0aW9uKF9zdXBlcikge1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIF9zdXBlci5jYWxsKHRoaXMpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICApXG5cblxuICAgIGNoYWkuQXNzZXJ0aW9uLm92ZXJ3cml0ZU1ldGhvZCgnbWF0Y2gnLCBmdW5jdGlvbihfc3VwZXIpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKHNlbGVjdG9yKSB7XG4gICAgICAgICAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0JylcbiAgICAgICAgICAgIGlmIChpc0hUTUxFbGVtZW50KG9iaikpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICAgICAgICAgICAgb2JqLm1hdGNoZXMoc2VsZWN0b3IpXG4gICAgICAgICAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKG9iaikgKyAnIHRvIG1hdGNoICN7ZXhwfSdcbiAgICAgICAgICAgICAgICAgICAgLCAnZXhwZWN0ZWQgJyArIGVsVG9TdHJpbmcob2JqKSArICcgdG8gbm90IG1hdGNoICN7ZXhwfSdcbiAgICAgICAgICAgICAgICAgICAgLCBzZWxlY3RvclxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNOb2RlTGlzdChvYmopKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgICAgICAgICAgICghIW9iai5sZW5ndGggJiYgQXJyYXkucHJvdG90eXBlLmV2ZXJ5LmNhbGwob2JqLCBmdW5jdGlvbihlbCkgeyByZXR1cm4gZWwubWF0Y2hlcyhzZWxlY3RvcikgfSkpXG4gICAgICAgICAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKG9iaikgKyAnIHRvIG1hdGNoICN7ZXhwfSdcbiAgICAgICAgICAgICAgICAgICAgLCAnZXhwZWN0ZWQgJyArIGVsVG9TdHJpbmcob2JqKSArICcgdG8gbm90IG1hdGNoICN7ZXhwfSdcbiAgICAgICAgICAgICAgICAgICAgLCBzZWxlY3RvclxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cylcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0pXG5cbiAgICBjaGFpLkFzc2VydGlvbi5vdmVyd3JpdGVDaGFpbmFibGVNZXRob2QoJ2NvbnRhaW4nLFxuICAgICAgICBmdW5jdGlvbihfc3VwZXIpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbihzdWJpdGVtKSB7XG4gICAgICAgICAgICAgICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAgICAgICAgICAgaWYgKGlzSFRNTEVsZW1lbnQob2JqKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHN1Yml0ZW0gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAhIW9iai5xdWVyeVNlbGVjdG9yKHN1Yml0ZW0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLCAnZXhwZWN0ZWQgJyArIGVsVG9TdHJpbmcob2JqKSArICcgdG8gY29udGFpbiAje2V4cH0nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLCAnZXhwZWN0ZWQgJyArIGVsVG9TdHJpbmcob2JqKSArICcgdG8gbm90IGNvbnRhaW4gI3tleHB9J1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICwgc3ViaXRlbSlcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iai5jb250YWlucyhzdWJpdGVtKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKG9iaikgKyAnIHRvIGNvbnRhaW4gJyArIGVsVG9TdHJpbmcoc3ViaXRlbSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAsICdleHBlY3RlZCAnICsgZWxUb1N0cmluZyhvYmopICsgJyB0byBub3QgY29udGFpbiAnICsgZWxUb1N0cmluZyhzdWJpdGVtKSlcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBmdW5jdGlvbihfc3VwZXIpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICBfc3VwZXIuY2FsbCh0aGlzKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgKVxuXG4gICAgY2hhaS5Bc3NlcnRpb24uYWRkTWV0aG9kKCdkZXNjZW5kYW50JywgZnVuY3Rpb24oc3ViaXRlbSkge1xuICAgICAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0JyksIGFjdHVhbCA9IHN1Yml0ZW1cblxuICAgICAgICBpZiAodHlwZW9mIHN1Yml0ZW0gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBhY3R1YWwgPSBvYmoucXVlcnlTZWxlY3RvcihzdWJpdGVtKVxuICAgICAgICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgICAgICAgISFhY3R1YWxcbiAgICAgICAgICAgICAgICAsICdleHBlY3RlZCAnICsgZWxUb1N0cmluZyhvYmopICsgJyB0byBoYXZlIGRlc2NlbmRhbnQgI3tleHB9J1xuICAgICAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKG9iaikgKyAnIHRvIG5vdCBoYXZlIGRlc2NlbmRhbnQgI3tleHB9J1xuICAgICAgICAgICAgICAgICwgc3ViaXRlbSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgICAgICAgIG9iai5jb250YWlucyhzdWJpdGVtKVxuICAgICAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKG9iaikgKyAnIHRvIGNvbnRhaW4gJyArIGVsVG9TdHJpbmcoc3ViaXRlbSlcbiAgICAgICAgICAgICAgICAsICdleHBlY3RlZCAnICsgZWxUb1N0cmluZyhvYmopICsgJyB0byBub3QgY29udGFpbiAnICsgZWxUb1N0cmluZyhzdWJpdGVtKSlcbiAgICAgICAgfVxuXG4gICAgICAgIGZsYWcodGhpcywgJ29iamVjdCcsIGFjdHVhbClcbiAgICB9KVxuXG4gICAgY2hhaS5Bc3NlcnRpb24uYWRkTWV0aG9kKCdkZXNjZW5kYW50cycsIGZ1bmN0aW9uKHNlbGVjdG9yKSB7XG4gICAgICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKSxcbiAgICAgICAgICAgIGFjdHVhbCA9IG9iai5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKVxuICAgICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICAgICEhYWN0dWFsLmxlbmd0aFxuICAgICAgICAgICAgLCAnZXhwZWN0ZWQgJyArIGVsVG9TdHJpbmcob2JqKSArICcgdG8gaGF2ZSBkZXNjZW5kYW50cyAje2V4cH0nXG4gICAgICAgICAgICAsICdleHBlY3RlZCAnICsgZWxUb1N0cmluZyhvYmopICsgJyB0byBub3QgaGF2ZSBkZXNjZW5kYW50cyAje2V4cH0nXG4gICAgICAgICAgICAsIHNlbGVjdG9yKVxuICAgICAgICBmbGFnKHRoaXMsICdvYmplY3QnLCBhY3R1YWwpXG4gICAgfSlcblxuICAgIGNoYWkuQXNzZXJ0aW9uLmFkZFByb3BlcnR5KCdkaXNwbGF5ZWQnLCBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGVsID0gZmxhZyh0aGlzLCAnb2JqZWN0JyksXG4gICAgICAgICAgICBhY3R1YWwgPSBkb2N1bWVudC5ib2R5LmNvbnRhaW5zKGVsKSA/IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsKS5kaXNwbGF5IDogZWwuc3R5bGUuZGlzcGxheVxuXG4gICAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgICAgYWN0dWFsICE9PSAnbm9uZSdcbiAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKGVsKSArICcgdG8gYmUgZGlzcGxheWVkLCBidXQgaXQgd2FzIG5vdCdcbiAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKGVsKSArICcgdG8gbm90IGJlIGRpc3BsYXllZCwgYnV0IGl0IHdhcyBhcyAnICsgYWN0dWFsXG4gICAgICAgICAgICAsIGFjdHVhbFxuICAgICAgICApXG4gICAgfSlcblxuICAgIGNoYWkuQXNzZXJ0aW9uLmFkZFByb3BlcnR5KCd2aXNpYmxlJywgZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBlbCA9IGZsYWcodGhpcywgJ29iamVjdCcpLFxuICAgICAgICAgICAgYWN0dWFsID0gZG9jdW1lbnQuYm9keS5jb250YWlucyhlbCkgPyB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlbCkudmlzaWJpbGl0eSA6IGVsLnN0eWxlLnZpc2liaWxpdHlcblxuICAgICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICAgIGFjdHVhbCAhPT0gJ2hpZGRlbicgJiYgYWN0dWFsICE9PSAnY29sbGFwc2UnXG4gICAgICAgICAgICAsICdleHBlY3RlZCAnICsgZWxUb1N0cmluZyhlbCkgKyAnIHRvIGJlIHZpc2libGUsIGJ1dCBpdCB3YXMgJyArIChhY3R1YWwgPT09ICdoaWRkZW4nID8gJ2hpZGRlbicgOiAnY29sbGFwc2VkJylcbiAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKGVsKSArICcgdG8gbm90IGJlIHZpc2libGUsIGJ1dCBpdCB3YXMnXG4gICAgICAgICAgICAsIGFjdHVhbFxuICAgICAgICApXG4gICAgfSlcbn0iLCAiJ3VzZSBzdHJpY3QnO1xuXG5cbmxldCBhZGRlZE5vZGVzLCBtdXRhdGlvbm9ic2VydmVyO1xuXG5mdW5jdGlvbiBpbml0KCkge1xuXG4gICAgYWRkZWROb2RlcyA9IFtdO1xuICAgIG11dGF0aW9ub2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcihmdW5jdGlvbiAobXV0YXRpb25zKSB7XG4gICAgICAgIG11dGF0aW9ucy5mb3JFYWNoKGZ1bmN0aW9uIChtdXRhdGlvbikge1xuICAgICAgICAgICAgaWYgKG11dGF0aW9uLnR5cGUgPT09ICdjaGlsZExpc3QnICYmIG11dGF0aW9uLnJlbW92ZWROb2Rlcykge1xuXG4gICAgICAgICAgICAgICAgbXV0YXRpb24uYWRkZWROb2Rlcy5mb3JFYWNoKChuKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChuIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFkZGVkTm9kZXMucHVzaChuKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgfSk7XG4gICAgfSk7XG5cblxufVxuXG5cbi8qKlxuICpcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluaXRNdXRhdGlvbk9ic2VydmVyRm9yVGVzdGluZygpIHtcblxuICAgIGlmIChtdXRhdGlvbm9ic2VydmVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaW5pdCgpXG4gICAgfVxuXG4gICAgbXV0YXRpb25vYnNlcnZlci5vYnNlcnZlKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2hlYWQnKSwge2NoaWxkTGlzdDogdHJ1ZX0pO1xufVxuXG4vKipcbiAqXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjbGVhbnVwRE9NRnJvbVRlc3RpbmcoKSB7XG4gICAgbXV0YXRpb25vYnNlcnZlci5kaXNjb25uZWN0KCk7XG5cbiAgICBmb3IgKGNvbnN0IG4gb2YgYWRkZWROb2Rlcykge1xuICAgICAgICBuLnJlbW92ZSgpO1xuICAgIH1cbn0iLCAiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQge2V4dGVuZH0gZnJvbSBcIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9kYXRhL2V4dGVuZC5tanNcIjtcbmltcG9ydCB7Z2V0R2xvYmFsfSBmcm9tIFwiLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL2dsb2JhbC5tanNcIjtcblxuZXhwb3J0IGNvbnN0IGlzQnJvd3NlciA9IG5ldyBGdW5jdGlvbihcInRyeSB7cmV0dXJuIHRoaXM9PT13aW5kb3c7fWNhdGNoKGUpeyByZXR1cm4gZmFsc2U7fVwiKTtcbmV4cG9ydCBjb25zdCBpc05vZGUgPSBuZXcgRnVuY3Rpb24oXCJ0cnkge3JldHVybiB0aGlzPT09Z2xvYmFsO31jYXRjaChlKXtyZXR1cm4gZmFsc2U7fVwiKTtcblxubGV0IEpTRE9NRXhwb3J0ID0gbnVsbDtcblxuLyoqXG4gKiB0aGlzIGhlbHBlciBmdW5jdGlvbiBjcmVhdGVzIHRoZSBkb20gc3RhY2sgaW4gdGhlIG5vZGUgZW52aXJvbm1lbnRcbiAqXG4gKiBAcmV0dXJuIHtQcm9taXNlPHVua25vd24+fFByb21pc2U8dm9pZD59XG4gKi9cbmZ1bmN0aW9uIGluaXRKU0RPTShvcHRpb25zKSB7XG4gICAgaWYgKHR5cGVvZiB3aW5kb3cgPT09IFwib2JqZWN0XCIgJiYgd2luZG93WydET01QYXJzZXInXSkgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuXG4gICAgY29uc3QgZyA9IGdldEdsb2JhbCgpO1xuXG4gICAgb3B0aW9ucyA9IGV4dGVuZCh7fSwge1xuICAgICAgICBwcmV0ZW5kVG9CZVZpc3VhbDogdHJ1ZSxcbiAgICAgICAgY29udGVudFR5cGU6IFwidGV4dC9odG1sXCIsXG4gICAgICAgIGluY2x1ZGVOb2RlTG9jYXRpb25zOiB0cnVlLFxuICAgICAgICBzdG9yYWdlUXVvdGE6IDEwMDAwMDAwLFxuICAgICAgICBydW5TY3JpcHRzOiBcImRhbmdlcm91c2x5XCIsXG4gICAgICAgIHJlc291cmNlczogXCJ1c2FibGVcIlxuICAgIH0sIG9wdGlvbnMgfHwge30pXG5cbiAgICByZXR1cm4gaW1wb3J0KFwianNkb21cIikudGhlbigoe0pTRE9NfSkgPT4ge1xuICAgICAgICBKU0RPTUV4cG9ydCA9IEpTRE9NO1xuICAgICAgICBjb25zdCB7d2luZG93fSA9IG5ldyBKU0RPTShgPGh0bWw+XG48aGVhZD5cbjwvaGVhZD5cbjxib2R5PlxuPGRpdiBpZD1cIm1vY2tzXCI+PC9kaXY+XG48L2JvZHk+YCwgb3B0aW9ucyk7XG5cbiAgICAgICAgZ1snd2luZG93J10gPSB3aW5kb3c7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT5cbiAgICAgICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwibG9hZFwiLCAoKSA9PiB7XG5cbiAgICAgICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgICAgICdzZWxmJyxcbiAgICAgICAgICAgICAgICAgICAgJ0hUTUxDb2xsZWN0aW9uJyxcbiAgICAgICAgICAgICAgICAgICAgJ05vZGVMaXN0JyxcbiAgICAgICAgICAgICAgICAgICAgJ0VsZW1lbnRJbnRlcm5hbHMnLFxuICAgICAgICAgICAgICAgICAgICAnSFRNTERvY3VtZW50JyxcbiAgICAgICAgICAgICAgICAgICAgJ0hUTUxGb3JtRWxlbWVudCcsXG4gICAgICAgICAgICAgICAgICAgICdIVE1MSW5wdXRFbGVtZW50JyxcbiAgICAgICAgICAgICAgICAgICAgJ0hUTUxTZWxlY3RFbGVtZW50JyxcbiAgICAgICAgICAgICAgICAgICAgJ0hUTUxUZXh0QXJlYUVsZW1lbnQnLFxuICAgICAgICAgICAgICAgICAgICAnZG9jdW1lbnQnLFxuICAgICAgICAgICAgICAgICAgICAnRG9jdW1lbnQnLFxuICAgICAgICAgICAgICAgICAgICAnTm9kZScsXG4gICAgICAgICAgICAgICAgICAgICdTaGFkb3dSb290JyxcbiAgICAgICAgICAgICAgICAgICAgJ0V2ZW50VGFyZ2V0JyxcbiAgICAgICAgICAgICAgICAgICAgJ0V2ZW50JyxcbiAgICAgICAgICAgICAgICAgICAgJ0N1c3RvbUV2ZW50JyxcbiAgICAgICAgICAgICAgICAgICAgJ0VsZW1lbnQnLFxuICAgICAgICAgICAgICAgICAgICAnSFRNTEVsZW1lbnQnLFxuICAgICAgICAgICAgICAgICAgICAnSFRNTERpdkVsZW1lbnQnLFxuICAgICAgICAgICAgICAgICAgICAnY3VzdG9tRWxlbWVudHMnLFxuICAgICAgICAgICAgICAgICAgICAnRG9jdW1lbnRGcmFnbWVudCcsXG4gICAgICAgICAgICAgICAgICAgICdET01QYXJzZXInLFxuICAgICAgICAgICAgICAgICAgICAnS2V5Ym9hcmRFdmVudCcsXG4gICAgICAgICAgICAgICAgICAgICdDU1NTdHlsZVNoZWV0JyxcbiAgICAgICAgICAgICAgICAgICAgJ0hUTUxTY3JpcHRFbGVtZW50JyxcbiAgICAgICAgICAgICAgICAgICAgJ011dGF0aW9uT2JzZXJ2ZXInLFxuICAgICAgICAgICAgICAgICAgICAnSFRNTFRlbXBsYXRlRWxlbWVudCcsXG4gICAgICAgICAgICAgICAgICAgICdYTUxTZXJpYWxpemVyJyxcbiAgICAgICAgICAgICAgICAgICAgJ05vZGVGaWx0ZXInLFxuICAgICAgICAgICAgICAgICAgICAnbmF2aWdhdG9yJyxcbiAgICAgICAgICAgICAgICAgICAgJ0lucHV0RXZlbnQnLFxuICAgICAgICAgICAgICAgICAgICAnQmxvYicsXG4gICAgICAgICAgICAgICAgICAgICdDdXN0b21FdmVudCdcbiAgICAgICAgICAgICAgICBdLmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgZ1trZXldID0gd2luZG93W2tleV1cbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICk7XG5cblxuICAgIH0pO1xufVxuXG5leHBvcnQge2luaXRKU0RPTSwgSlNET01FeHBvcnR9IFxuXG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBpbnRlcm5hbFN0YXRlU3ltYm9sIH0gZnJvbSBcIi4uLy4uL2NvbnN0YW50cy5tanNcIjtcbmltcG9ydCB7IGV4dGVuZCB9IGZyb20gXCIuLi8uLi9kYXRhL2V4dGVuZC5tanNcIjtcbmltcG9ydCB7IGdldEdsb2JhbEZ1bmN0aW9uIH0gZnJvbSBcIi4uLy4uL3R5cGVzL2dsb2JhbC5tanNcIjtcbmltcG9ydCB7XG4gICAgQVRUUklCVVRFX0NMQVNTLFxuICAgIEFUVFJJQlVURV9FUlJPUk1FU1NBR0UsXG4gICAgQVRUUklCVVRFX0lELFxuICAgIEFUVFJJQlVURV9TUkMsXG4gICAgQVRUUklCVVRFX1RJVExFLFxuICAgIEFUVFJJQlVURV9UWVBFLFxuICAgIFRBR19TQ1JJUFQsXG59IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQgeyBLRVlfRE9DVU1FTlQsIEtFWV9RVUVSWSwgcmVmZXJlbmNlU3ltYm9sLCBSZXNvdXJjZSB9IGZyb20gXCIuLi9yZXNvdXJjZS5tanNcIjtcbmltcG9ydCB7IGluc3RhbmNlU3ltYm9sIH0gZnJvbSBcIi4uLy4uL2NvbnN0YW50cy5tanNcIjtcbmV4cG9ydCB7IERhdGEgfTtcblxuLyoqXG4gKiBUaGlzIGNsYXNzIGlzIHVzZWQgYnkgdGhlIHJlc291cmNlIG1hbmFnZXIgdG8gZW1iZWQgZGF0YS5cbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI1LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET00uUmVzb3VyY2VcbiAqIEBzdW1tYXJ5IEEgRGF0YSBSZXNvdXJjZSBjbGFzc1xuICovXG5jbGFzcyBEYXRhIGV4dGVuZHMgUmVzb3VyY2Uge1xuICAgIC8qKlxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBtb2RlPWNvcnMgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL2ZldGNoXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd9IGNyZWRlbnRpYWxzPXNhbWUtb3JpZ2luIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9mZXRjaFxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB0eXBlPWFwcGxpY2F0aW9uL2pzb24ge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUTUwvRWxlbWVudC9zY3JpcHQjYXR0ci10eXBlfVxuICAgICAqL1xuICAgIGdldCBkZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIGV4dGVuZCh7fSwgc3VwZXIuZGVmYXVsdHMsIHtcbiAgICAgICAgICAgIG1vZGU6IFwiY29yc1wiLFxuICAgICAgICAgICAgY3JlZGVudGlhbHM6IFwic2FtZS1vcmlnaW5cIixcbiAgICAgICAgICAgIHR5cGU6IFwiYXBwbGljYXRpb24vanNvblwiLFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEByZXR1cm4ge01vbnN0ZXIuRE9NLlJlc291cmNlLkRhdGF9XG4gICAgICovXG4gICAgY3JlYXRlKCkge1xuICAgICAgICBjcmVhdGVFbGVtZW50LmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGFwcGVuZHMgdGhlIEhUTUxFbGVtZW50IHRvIHRoZSBzcGVjaWZpZWQgZG9jdW1lbnRcbiAgICAgKlxuICAgICAqIHRocm93cyB7RXJyb3J9IHRhcmdldCBub3QgZm91bmRcbiAgICAgKiBAcmV0dXJuIHtNb25zdGVyLkRPTS5SZXNvdXJjZX1cbiAgICAgKi9cbiAgICBjb25uZWN0KCkge1xuICAgICAgICBpZiAoISh0aGlzW3JlZmVyZW5jZVN5bWJvbF0gaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpIHtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRlKCk7XG4gICAgICAgIH1cblxuICAgICAgICBhcHBlbmRUb0RvY3VtZW50LmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgYGluc3RhbmNlb2ZgIG9wZXJhdG9yLlxuICAgICAqIEByZXR1cm5zIHtzeW1ib2x9XG4gICAgICogQHNpbmNlIDIuMS4wXG4gICAgICovXG4gICAgc3RhdGljIGdldCBbaW5zdGFuY2VTeW1ib2xdKCkge1xuICAgICAgICByZXR1cm4gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvZG9tL3Jlc291cmNlL2RhdGFcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7c3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRVUkxBdHRyaWJ1dGUoKSB7XG4gICAgICAgIHJldHVybiBBVFRSSUJVVEVfU1JDO1xuICAgIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHJldHVybiB7TW9uc3Rlci5ET00uUmVzb3VyY2UuRGF0YX1cbiAqL1xuZnVuY3Rpb24gY3JlYXRlRWxlbWVudCgpIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgIGNvbnN0IGRvY3VtZW50ID0gc2VsZi5nZXRPcHRpb24oS0VZX0RPQ1VNRU5UKTtcbiAgICBzZWxmW3JlZmVyZW5jZVN5bWJvbF0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFRBR19TQ1JJUFQpO1xuXG4gICAgZm9yIChsZXQga2V5IG9mIFtBVFRSSUJVVEVfVFlQRSwgQVRUUklCVVRFX0lELCBBVFRSSUJVVEVfQ0xBU1MsIEFUVFJJQlVURV9USVRMRV0pIHtcbiAgICAgICAgaWYgKHNlbGYuZ2V0T3B0aW9uKGtleSkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgc2VsZltyZWZlcmVuY2VTeW1ib2xdW2tleV0gPSBzZWxmLmdldE9wdGlvbihrZXkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHNlbGY7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEByZXR1cm4ge1Byb21pc2V9XG4gKiB0aHJvd3Mge0Vycm9yfSB0YXJnZXQgbm90IGZvdW5kXG4gKi9cbmZ1bmN0aW9uIGFwcGVuZFRvRG9jdW1lbnQoKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICBjb25zdCB0YXJnZXROb2RlID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihzZWxmLmdldE9wdGlvbihLRVlfUVVFUlksIFwiaGVhZFwiKSk7XG4gICAgaWYgKCEodGFyZ2V0Tm9kZSBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0YXJnZXQgbm90IGZvdW5kXCIpO1xuICAgIH1cblxuICAgIHRhcmdldE5vZGUuYXBwZW5kQ2hpbGQoc2VsZltyZWZlcmVuY2VTeW1ib2xdKTtcblxuICAgIGdldEdsb2JhbEZ1bmN0aW9uKFwiZmV0Y2hcIikoc2VsZi5nZXRPcHRpb24oQVRUUklCVVRFX1NSQyksIHtcbiAgICAgICAgbWV0aG9kOiBcIkdFVFwiLCAvLyAqR0VULCBQT1NULCBQVVQsIERFTEVURSwgZXRjLlxuICAgICAgICBtb2RlOiBzZWxmLmdldE9wdGlvbihcIm1vZGVcIiwgXCJjb3JzXCIpLCAvLyBuby1jb3JzLCAqY29ycywgc2FtZS1vcmlnaW5cbiAgICAgICAgY2FjaGU6IFwibm8tY2FjaGVcIiwgLy8gKmRlZmF1bHQsIG5vLWNhY2hlLCByZWxvYWQsIGZvcmNlLWNhY2hlLCBvbmx5LWlmLWNhY2hlZFxuICAgICAgICBjcmVkZW50aWFsczogc2VsZi5nZXRPcHRpb24oXCJjcmVkZW50aWFsc1wiLCBcInNhbWUtb3JpZ2luXCIpLCAvLyBpbmNsdWRlLCAqc2FtZS1vcmlnaW4sIG9taXRcbiAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgQWNjZXB0OiBzZWxmLmdldE9wdGlvbihcInR5cGVcIiwgXCJhcHBsaWNhdGlvbi9qc29uXCIpLFxuICAgICAgICB9LFxuICAgICAgICByZWRpcmVjdDogXCJmb2xsb3dcIiwgLy8gbWFudWFsLCAqZm9sbG93LCBlcnJvclxuICAgICAgICByZWZlcnJlclBvbGljeTogXCJuby1yZWZlcnJlclwiLCAvLyBuby1yZWZlcnJlcixcbiAgICB9KVxuICAgICAgICAudGhlbigocmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgIHJldHVybiByZXNwb25zZS50ZXh0KCk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKCh0ZXh0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0ZXh0Tm9kZSA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHRleHQpO1xuICAgICAgICAgICAgc2VsZltyZWZlcmVuY2VTeW1ib2xdLmFwcGVuZENoaWxkKHRleHROb2RlKTtcblxuICAgICAgICAgICAgc2VsZltpbnRlcm5hbFN0YXRlU3ltYm9sXS5nZXRTdWJqZWN0KClbXCJsb2FkZWRcIl0gPSB0cnVlO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIHNlbGZbaW50ZXJuYWxTdGF0ZVN5bWJvbF0uc2V0U3ViamVjdCh7XG4gICAgICAgICAgICAgICAgbG9hZGVkOiB0cnVlLFxuICAgICAgICAgICAgICAgIGVycm9yOiBlLnRvU3RyaW5nKCksXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgdGFyZ2V0Tm9kZS5zZXRBdHRyaWJ1dGUoQVRUUklCVVRFX0VSUk9STUVTU0FHRSwgZS50b1N0cmluZygpKTtcbiAgICAgICAgfSk7XG5cbiAgICByZXR1cm4gc2VsZjtcbn1cbiIsICIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBjaGFpIGZyb20gXCJjaGFpXCJcbmltcG9ydCB7RGF0YX0gZnJvbSBcIi4uLy4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9kb20vcmVzb3VyY2UvZGF0YS5tanNcIjtcbmltcG9ydCB7RGF0YVVybH0gZnJvbSBcIi4uLy4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS90eXBlcy9kYXRhdXJsLm1qc1wiO1xuaW1wb3J0IHtJRH0gZnJvbSBcIi4uLy4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS90eXBlcy9pZC5tanNcIjtcbmltcG9ydCB7Y2hhaURvbX0gZnJvbSBcIi4uLy4uLy4uL3V0aWwvY2hhaS1kb20ubWpzXCI7XG5pbXBvcnQge2NsZWFudXBET01Gcm9tVGVzdGluZywgaW5pdE11dGF0aW9uT2JzZXJ2ZXJGb3JUZXN0aW5nfSBmcm9tIFwiLi4vLi4vLi4vdXRpbC9jbGVhbnVwZG9tLm1qc1wiO1xuaW1wb3J0IHtpbml0SlNET019IGZyb20gXCIuLi8uLi8uLi91dGlsL2pzZG9tLm1qc1wiO1xuXG5sZXQgZXhwZWN0ID0gY2hhaS5leHBlY3Q7XG5cbmNoYWkudXNlKGNoYWlEb20pO1xuXG5sZXQgaHRtbDEgPSBgXG5cbmA7XG5cblxuZGVzY3JpYmUoJ0RhdGEnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBsZXQgZmV0Y2hSZWZlcmVuY2UsIHJldHVyblN0YXR1cywgbXV0YXRpb25vYnNlcnZlciwgYWRkZWROb2RlcyA9IFtdO1xuXG5cbiAgICBiZWZvcmUoZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgaW5pdEpTRE9NKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICBkb25lKClcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBiZWZvcmVFYWNoKCgpID0+IHtcblxuICAgICAgICBpbml0TXV0YXRpb25PYnNlcnZlckZvclRlc3RpbmcoKVxuXG4gICAgICAgIHJldHVyblN0YXR1cyA9IDIwMDtcbiAgICAgICAgZmV0Y2hSZWZlcmVuY2UgPSBnbG9iYWxUaGlzWydmZXRjaCddO1xuICAgICAgICBnbG9iYWxUaGlzWydmZXRjaCddID0gZnVuY3Rpb24gKHVybCwgb3B0aW9ucykge1xuXG4gICAgICAgICAgICBpZiAoIXVybCkgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHVybCcpXG5cbiAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZSh7XG4gICAgICAgICAgICAgICAgICAgIHRleHQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYTogXCJ0ZXN0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHN0YXR1czogcmV0dXJuU3RhdHVzXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KVxuXG4gICAgICAgIH07XG5cblxuICAgIH0pXG5cbiAgICBhZnRlckVhY2goKCkgPT4ge1xuICAgICAgICBnbG9iYWxUaGlzWydmZXRjaCddID0gZmV0Y2hSZWZlcmVuY2U7XG4gICAgICAgIGNsZWFudXBET01Gcm9tVGVzdGluZygpO1xuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnRGF0YSgpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2V0RXZlbnRUeXBlcygpJywgZnVuY3Rpb24gKGRvbmUpIHtcblxuICAgICAgICAgICAgY29uc3QgZGF0YSA9IG5ldyBEYXRhKHtcbiAgICAgICAgICAgICAgICBzcmM6IG5ldyBEYXRhVXJsKCcnLCAndGV4dC9qYXZhc2NyaXB0JykudG9TdHJpbmcoKVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGRhdGEuY29ubmVjdCgpLmF2YWlsYWJsZSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICAgICAgfSkuY2F0Y2goZSA9PiBkb25lKGUpKTtcblxuICAgICAgICB9KVxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ0V4dGVybmFsIERhdGEnLCAoKSA9PiB7XG5cbiAgICAgICAgbGV0IGlkID0gbmV3IElEKCdkYXRhJykudG9TdHJpbmcoKTtcbiAgICAgICAgbGV0IHNlcnZlciwgZGF0YSwgdXJsID0gJ2h0dHBzOi8vbW9uc3RlcmpzLm9yZy9hc3NldHMvZW1wdHkuanM/JyArIGlkO1xuXG4gICAgICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuXG4gICAgICAgICAgICBkYXRhID0gbmV3IERhdGEoe1xuICAgICAgICAgICAgICAgIHNyYzogdXJsLFxuICAgICAgICAgICAgICAgIGlkOiBpZFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ2RhdGEgaXMgbm90IGNvbm5lY3RlZCcsICgpID0+IHtcbiAgICAgICAgICAgIGV4cGVjdChkYXRhLmlzQ29ubmVjdGVkKCkpLnRvLmJlLmZhbHNlO1xuICAgICAgICB9KVxuXG4gICAgICAgIGl0KCdjb25uZWN0IGFuZCBjaGVjayBhdmFpbGFiaWxpdHknLCAoZG9uZSkgPT4ge1xuXG4gICAgICAgICAgICBkYXRhLmNvbm5lY3QoKS5hdmFpbGFibGUoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICBleHBlY3QoZGF0YS5pc0Nvbm5lY3RlZCgpLCAnaXNDb25uZWN0ZWQgMScpLnRvLmJlLnRydWU7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ1t0eXBlPVwiYXBwbGljYXRpb24vanNvblwiXScpLCAnZXhpc3RzIDEnKS50by5leGlzdDtcblxuICAgICAgICAgICAgICAgIGNvbnN0IGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkucGFyZW50RWxlbWVudDtcblxuXG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpLnJlbW92ZSgpO1xuXG4gICAgICAgICAgICAgICAgZXhwZWN0KGRhdGEuaXNDb25uZWN0ZWQoKSwgJ2lzQ29ubmVjdGVkIDInKS50by5iZS5mYWxzZTtcbiAgICAgICAgICAgICAgICBleHBlY3QoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW3R5cGU9XCJhcHBsaWNhdGlvbi9qc29uXCJdJyksICdleGlzdHMgMicpLm5vdC50by5leGlzdDtcblxuICAgICAgICAgICAgICAgIGRhdGEuY29ubmVjdCgpLmF2YWlsYWJsZSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QoZGF0YS5pc0Nvbm5lY3RlZCgpLCAnaXNDb25uZWN0ZWQgMycpLnRvLmJlLnRydWU7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbdHlwZT1cImFwcGxpY2F0aW9uL2pzb25cIl0nKSwgJ2V4aXN0cyAzJykudG8uZXhpc3Q7XG5cbiAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpLnJlbW92ZSgpO1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW3R5cGU9XCJhcHBsaWNhdGlvbi9qc29uXCJdJyksICdleGlzdHMgNCcpLm5vdC50by5leGlzdDtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KGRhdGEuaXNDb25uZWN0ZWQoKSwgJ2lzQ29ubmVjdGVkIDQnKS50by5iZS5mYWxzZTtcblxuICAgICAgICAgICAgICAgICAgICBkb25lKClcbiAgICAgICAgICAgICAgICB9KS5jYXRjaChlID0+IGRvbmUoZSkpO1xuXG5cbiAgICAgICAgICAgIH0pLmNhdGNoKGUgPT4gZG9uZShlKSk7XG5cblxuICAgICAgICB9KTtcblxuXG4gICAgfSk7XG5cblxufSk7IiwgIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IGNoYWkgZnJvbSBcImNoYWlcIlxuaW1wb3J0IHtMaW5rfSBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2RvbS9yZXNvdXJjZS9saW5rLm1qc1wiO1xuaW1wb3J0IHtEYXRhVXJsfSBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL2RhdGF1cmwubWpzXCI7XG5pbXBvcnQge0lEfSBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL2lkLm1qc1wiO1xuaW1wb3J0IHtjaGFpRG9tfSBmcm9tIFwiLi4vLi4vLi4vdXRpbC9jaGFpLWRvbS5tanNcIjtcbmltcG9ydCB7Y2xlYW51cERPTUZyb21UZXN0aW5nLCBpbml0TXV0YXRpb25PYnNlcnZlckZvclRlc3Rpbmd9IGZyb20gXCIuLi8uLi8uLi91dGlsL2NsZWFudXBkb20ubWpzXCI7XG5pbXBvcnQge2luaXRKU0RPTX0gZnJvbSBcIi4uLy4uLy4uL3V0aWwvanNkb20ubWpzXCI7XG5cbmxldCBleHBlY3QgPSBjaGFpLmV4cGVjdDtcblxuY2hhaS51c2UoY2hhaURvbSk7XG5cblxuXG5kZXNjcmliZSgnTGluaycsIGZ1bmN0aW9uICgpIHtcblxuICAgIGJlZm9yZShmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICBpbml0SlNET00oKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgICBpbml0TXV0YXRpb25PYnNlcnZlckZvclRlc3RpbmcoKVxuICAgIH0pXG5cbiAgICBhZnRlckVhY2goKCkgPT4ge1xuICAgICAgICBjbGVhbnVwRE9NRnJvbVRlc3RpbmcoKTtcbiAgICB9KVxuXG4gICAgZGVzY3JpYmUoJ0xpbmsoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy50aW1lb3V0KDUwMDApO1xuXG4gICAgICAgIGl0KCdjb25uZWN0KCkuYXZhaWxhYmxlKCknLCBmdW5jdGlvbiAoZG9uZSkge1xuXG4gICAgICAgICAgICBjb25zdCBsaW5rID0gbmV3IExpbmsoe1xuICAgICAgICAgICAgICAgIGhyZWY6IG5ldyBEYXRhVXJsKCcnLCAndGV4dC9jc3MnKS50b1N0cmluZygpLFxuICAgICAgICAgICAgICAgIHJlbDogJ3N0eWxlc2hlZXQnXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgbGluay5jb25uZWN0KCkuYXZhaWxhYmxlKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgZG9uZSgpXG4gICAgICAgICAgICB9KS5jYXRjaChlID0+IGRvbmUoZSkpO1xuXG4gICAgICAgIH0pXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnRXh0ZXJuYWwgTGluaycsICgpID0+IHtcbiAgICAgICAgdGhpcy50aW1lb3V0KDUwMDApO1xuXG4gICAgICAgIGxldCBpZCA9IG5ldyBJRCgnbGluaycpLnRvU3RyaW5nKCk7XG4gICAgICAgIGxldCBsaW5rLCB1cmwgPSAnaHR0cHM6Ly9tb25zdGVyanMub3JnL2Fzc2V0cy9lbXB0eS5jc3M/JyArIGlkO1xuXG4gICAgICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuXG4gICAgICAgICAgICBsaW5rID0gbmV3IExpbmsoe1xuICAgICAgICAgICAgICAgIGhyZWY6IHVybCxcbiAgICAgICAgICAgICAgICBpZDogaWQsXG4gICAgICAgICAgICAgICAgcmVsOiAnc3R5bGVzaGVldCdcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdhcHBlbmQgYW5kIHJlbW92ZSBMaW5rICcsIChkb25lKSA9PiB7XG5cbiAgICAgICAgICAgIGV4cGVjdChsaW5rLmlzQ29ubmVjdGVkKCkpLnRvLmJlLmZhbHNlO1xuXG4gICAgICAgICAgICBsaW5rLmNvbm5lY3QoKS5hdmFpbGFibGUoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICBleHBlY3QobGluay5pc0Nvbm5lY3RlZCgpKS50by5iZS50cnVlO1xuICAgICAgICAgICAgICAgIGV4cGVjdChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbaHJlZj1cIicgKyB1cmwgKyAnXCJdJykpLnRvLmV4aXN0O1xuXG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpLnJlbW92ZSgpO1xuICAgICAgICAgICAgICAgIGV4cGVjdChsaW5rLmlzQ29ubmVjdGVkKCkpLnRvLmJlLmZhbHNlO1xuICAgICAgICAgICAgICAgIGV4cGVjdChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbaHJlZj1cIicgKyB1cmwgKyAnXCJdJykpLm5vdC50by5leGlzdDtcblxuICAgICAgICAgICAgICAgIGxpbmsuY29ubmVjdCgpLmF2YWlsYWJsZSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QobGluay5pc0Nvbm5lY3RlZCgpKS50by5iZS50cnVlO1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW2hyZWY9XCInICsgdXJsICsgJ1wiXScpKS50by5leGlzdDtcblxuICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkucmVtb3ZlKCk7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbaHJlZj1cIicgKyB1cmwgKyAnXCJdJykpLm5vdC50by5leGlzdDtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KGxpbmsuaXNDb25uZWN0ZWQoKSkudG8uYmUuZmFsc2U7XG5cbiAgICAgICAgICAgICAgICAgICAgZG9uZSgpXG4gICAgICAgICAgICAgICAgfSkuY2F0Y2goZSA9PiBkb25lKGUpKTtcblxuXG4gICAgICAgICAgICB9KS5jYXRjaChlID0+IGRvbmUoZSkpO1xuXG5cbiAgICAgICAgfSk7XG5cblxuICAgIH0pO1xuXG5cbn0pOyIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGV4dGVuZCB9IGZyb20gXCIuLi8uLi9kYXRhL2V4dGVuZC5tanNcIjtcbmltcG9ydCB7XG4gICAgQVRUUklCVVRFX0NMQVNTLFxuICAgIEFUVFJJQlVURV9JRCxcbiAgICBBVFRSSUJVVEVfTk9OQ0UsXG4gICAgQVRUUklCVVRFX1NSQyxcbiAgICBBVFRSSUJVVEVfVElUTEUsXG4gICAgQVRUUklCVVRFX1RZUEUsXG4gICAgVEFHX1NDUklQVCxcbn0gZnJvbSBcIi4uL2NvbnN0YW50cy5tanNcIjtcbmltcG9ydCB7IEtFWV9ET0NVTUVOVCwgcmVmZXJlbmNlU3ltYm9sLCBSZXNvdXJjZSB9IGZyb20gXCIuLi9yZXNvdXJjZS5tanNcIjtcbmltcG9ydCB7IGluc3RhbmNlU3ltYm9sIH0gZnJvbSBcIi4uLy4uL2NvbnN0YW50cy5tanNcIjtcbmV4cG9ydCB7IFNjcmlwdCB9O1xuXG4vKipcbiAqIFRoaXMgY2xhc3MgaXMgdXNlZCBieSB0aGUgcmVzb3VyY2UgbWFuYWdlciB0byBlbWJlZCBzY3JpcHRzLlxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjUuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTS5SZXNvdXJjZVxuICogQHN1bW1hcnkgQSBSZXNvdXJjZSBjbGFzc1xuICovXG5jbGFzcyBTY3JpcHQgZXh0ZW5kcyBSZXNvdXJjZSB7XG4gICAgLyoqXG4gICAgICogQHByb3BlcnR5IHtib29sZWFufSBhc3luYz10cnVlIHtAbGluayBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVE1ML0VsZW1lbnQvc2NyaXB0I2F0dHItYXN5bmN9XG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd9IGNyb3NzT3JpZ2luPWFub255bW91cyB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9FbGVtZW50L3NjcmlwdCNhdHRyLWNyb3Nzb3JpZ2lufVxuICAgICAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gZGVmZXI9ZmFsc2Uge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUTUwvRWxlbWVudC9zY3JpcHQjYXR0ci1kZWZlcn1cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gaW50ZWdyaXR5IHtAbGluayBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVE1ML0VsZW1lbnQvc2NyaXB0I2F0dHItaW50ZWdyaXR5fVxuICAgICAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gbm9tb2R1bGUge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUTUwvRWxlbWVudC9zY3JpcHQjYXR0ci1ub21vZHVsZX1cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gbm9uY2Uge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUTUwvRWxlbWVudC9zY3JpcHQjYXR0ci1ub25jZX1cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gcmVmZXJyZXJwb2xpY3kge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUTUwvRWxlbWVudC9zY3JpcHQjYXR0ci1yZWZlcnJlcnBvbGljeX1cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gdHlwZSB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9FbGVtZW50L3NjcmlwdCNhdHRyLXR5cGV9XG4gICAgICovXG4gICAgZ2V0IGRlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gZXh0ZW5kKHt9LCBzdXBlci5kZWZhdWx0cywge1xuICAgICAgICAgICAgYXN5bmM6IHRydWUsXG4gICAgICAgICAgICBjcm9zc09yaWdpbjogXCJhbm9ueW1vdXNcIixcbiAgICAgICAgICAgIGRlZmVyOiBmYWxzZSxcbiAgICAgICAgICAgIGludGVncml0eTogdW5kZWZpbmVkLFxuICAgICAgICAgICAgbm9tb2R1bGU6IGZhbHNlLFxuICAgICAgICAgICAgbm9uY2U6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHJlZmVycmVycG9saWN5OiB1bmRlZmluZWQsXG4gICAgICAgICAgICB0eXBlOiBcInRleHQvamF2YXNjcmlwdFwiLFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGBpbnN0YW5jZW9mYCBvcGVyYXRvci5cbiAgICAgKiBAcmV0dXJucyB7c3ltYm9sfVxuICAgICAqIEBzaW5jZSAyLjEuMFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgW2luc3RhbmNlU3ltYm9sXSgpIHtcbiAgICAgICAgcmV0dXJuIFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL2RvbS9yZXNvdXJjZS9zY3JpcHRcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtNb25zdGVyLkRPTS5SZXNvdXJjZS5TY3JpcHR9XG4gICAgICovXG4gICAgY3JlYXRlKCkge1xuICAgICAgICBjcmVhdGVFbGVtZW50LmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge3N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0VVJMQXR0cmlidXRlKCkge1xuICAgICAgICByZXR1cm4gQVRUUklCVVRFX1NSQztcbiAgICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEByZXR1cm4ge01vbnN0ZXIuRE9NLlJlc291cmNlLlNjcmlwdH1cbiAqL1xuZnVuY3Rpb24gY3JlYXRlRWxlbWVudCgpIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgIGNvbnN0IGRvY3VtZW50ID0gc2VsZi5nZXRPcHRpb24oS0VZX0RPQ1VNRU5UKTtcbiAgICBzZWxmW3JlZmVyZW5jZVN5bWJvbF0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFRBR19TQ1JJUFQpO1xuXG4gICAgZm9yIChsZXQga2V5IG9mIFtcbiAgICAgICAgXCJjcm9zc09yaWdpblwiLFxuICAgICAgICBcImRlZmVyXCIsXG4gICAgICAgIFwiYXN5bmNcIixcbiAgICAgICAgXCJpbnRlZ3JpdHlcIixcbiAgICAgICAgXCJub21vZHVsZVwiLFxuICAgICAgICBBVFRSSUJVVEVfTk9OQ0UsXG4gICAgICAgIFwicmVmZXJyZXJwb2xpY3lcIixcbiAgICAgICAgQVRUUklCVVRFX1RZUEUsXG4gICAgICAgIEFUVFJJQlVURV9TUkMsXG4gICAgICAgIEFUVFJJQlVURV9JRCxcbiAgICAgICAgQVRUUklCVVRFX0NMQVNTLFxuICAgICAgICBBVFRSSUJVVEVfVElUTEUsXG4gICAgXSkge1xuICAgICAgICBpZiAoc2VsZi5nZXRPcHRpb24oa2V5KSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBzZWxmW3JlZmVyZW5jZVN5bWJvbF1ba2V5XSA9IHNlbGYuZ2V0T3B0aW9uKGtleSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gc2VsZjtcbn1cbiIsICIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBjaGFpIGZyb20gXCJjaGFpXCJcbmltcG9ydCB7U2NyaXB0fSBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2RvbS9yZXNvdXJjZS9zY3JpcHQubWpzXCI7XG5pbXBvcnQge0RhdGFVcmx9IGZyb20gXCIuLi8uLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdHlwZXMvZGF0YXVybC5tanNcIjtcbmltcG9ydCB7SUR9IGZyb20gXCIuLi8uLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdHlwZXMvaWQubWpzXCI7XG5pbXBvcnQge2NoYWlEb219IGZyb20gXCIuLi8uLi8uLi91dGlsL2NoYWktZG9tLm1qc1wiO1xuaW1wb3J0IHtjbGVhbnVwRE9NRnJvbVRlc3RpbmcsIGluaXRNdXRhdGlvbk9ic2VydmVyRm9yVGVzdGluZ30gZnJvbSBcIi4uLy4uLy4uL3V0aWwvY2xlYW51cGRvbS5tanNcIjtcbmltcG9ydCB7aW5pdEpTRE9NfSBmcm9tIFwiLi4vLi4vLi4vdXRpbC9qc2RvbS5tanNcIjtcblxubGV0IGV4cGVjdCA9IGNoYWkuZXhwZWN0O1xuXG5jaGFpLnVzZShjaGFpRG9tKTtcblxubGV0IGh0bWwxID0gYFxuXG5gO1xuXG5cbmRlc2NyaWJlKCdTY3JpcHQnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBiZWZvcmUoZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgaW5pdEpTRE9NKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICBkb25lKClcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAgaW5pdE11dGF0aW9uT2JzZXJ2ZXJGb3JUZXN0aW5nKClcbiAgICB9KVxuXG4gICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgICAgY2xlYW51cERPTUZyb21UZXN0aW5nKCk7XG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCdTY3JpcHQoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3NldEV2ZW50VHlwZXMoKScsIGZ1bmN0aW9uIChkb25lKSB7XG5cbiAgICAgICAgICAgIGNvbnN0IHNjcmlwdCA9IG5ldyBTY3JpcHQoe1xuICAgICAgICAgICAgICAgIHNyYzogbmV3IERhdGFVcmwoJycsICd0ZXh0L2phdmFzY3JpcHQnKS50b1N0cmluZygpLFxuICAgICAgICAgICAgICAgIGFzeW5jOiB0cnVlLFxuICAgICAgICAgICAgICAgIGNyb3NzT3JpZ2luOiAnYW5vbnltb3VzJyxcbiAgICAgICAgICAgICAgICBkZWZlcjogZmFsc2UsXG4gICAgICAgICAgICAgICAgaW50ZWdyaXR5OiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgbm9tb2R1bGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIG5vbmNlOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgcmVmZXJyZXJwb2xpY3k6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICB0eXBlOiAndGV4dC9qYXZhc2NyaXB0J1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHNjcmlwdC5jb25uZWN0KCkuYXZhaWxhYmxlKCkudGhlbigoKSA9PiB7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBpZCA9IHNjcmlwdC5nZXRPcHRpb24oJ2lkJylcbiAgICAgICAgICAgICAgICBkb25lKClcbiAgICAgICAgICAgIH0pLmNhdGNoKGUgPT4gZG9uZShlKSk7XG5cbiAgICAgICAgfSlcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdFeHRlcm5hbCBKUycsICgpID0+IHtcblxuICAgICAgICBsZXQgaWQgPSBuZXcgSUQoJ3NjcmlwdCcpLnRvU3RyaW5nKCk7XG4gICAgICAgIGxldCBzZXJ2ZXIsIHNjcmlwdCwgdXJsID0gJ2h0dHBzOi8vbW9uc3RlcmpzLm9yZy9hc3NldHMvZW1wdHkuanM/JyArIGlkO1xuXG4gICAgICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuXG4gICAgICAgICAgICBzY3JpcHQgPSBuZXcgU2NyaXB0KHtcbiAgICAgICAgICAgICAgICBzcmM6IHVybCxcbiAgICAgICAgICAgICAgICBhc3luYzogdHJ1ZSxcbiAgICAgICAgICAgICAgICBjcm9zc09yaWdpbjogJ2Fub255bW91cycsXG4gICAgICAgICAgICAgICAgZGVmZXI6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGludGVncml0eTogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgIG5vbW9kdWxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBub25jZTogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgIHJlZmVycmVycG9saWN5OiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgdHlwZTogJ3RleHQvamF2YXNjcmlwdCcsXG4gICAgICAgICAgICAgICAgaWQ6IGlkXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnYXBwZW5kIGFuZCByZW1vdmUgc2NyaXB0ICcsIChkb25lKSA9PiB7XG5cbiAgICAgICAgICAgIGV4cGVjdChzY3JpcHQuaXNDb25uZWN0ZWQoKSkudG8uYmUuZmFsc2U7XG5cbiAgICAgICAgICAgIHNjcmlwdC5jb25uZWN0KCkuYXZhaWxhYmxlKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KHNjcmlwdC5pc0Nvbm5lY3RlZCgpKS50by5iZS50cnVlO1xuICAgICAgICAgICAgICAgIGV4cGVjdChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbc3JjPVwiJyArIHVybCArICdcIl0nKSkudG8uZXhpc3Q7XG5cbiAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkucmVtb3ZlKCk7XG4gICAgICAgICAgICAgICAgZXhwZWN0KHNjcmlwdC5pc0Nvbm5lY3RlZCgpKS50by5iZS5mYWxzZTtcbiAgICAgICAgICAgICAgICBleHBlY3QoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW3NyYz1cIicgKyB1cmwgKyAnXCJdJykpLm5vdC50by5leGlzdDtcblxuICAgICAgICAgICAgICAgIHNjcmlwdC5jb25uZWN0KCkuYXZhaWxhYmxlKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChzY3JpcHQuaXNDb25uZWN0ZWQoKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ1tzcmM9XCInICsgdXJsICsgJ1wiXScpKS50by5leGlzdDtcblxuICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkucmVtb3ZlKCk7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbc3JjPVwiJyArIHVybCArICdcIl0nKSkubm90LnRvLmV4aXN0O1xuICAgICAgICAgICAgICAgICAgICBleHBlY3Qoc2NyaXB0LmlzQ29ubmVjdGVkKCkpLnRvLmJlLmZhbHNlO1xuXG4gICAgICAgICAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICAgICAgICAgIH0pLmNhdGNoKGUgPT4gZG9uZShlKSk7XG5cblxuICAgICAgICAgICAgfSkuY2F0Y2goZSA9PiBkb25lKGUpKTtcblxuXG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxuXG59KTsiLCAiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgY2hhaSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge1VwZGF0ZXJ9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvZG9tL3VwZGF0ZXIubWpzXCI7XG5pbXBvcnQge0lEfSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL2lkLm1qc1wiO1xuaW1wb3J0IHtPYnNlcnZlcn0gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS90eXBlcy9vYnNlcnZlci5tanNcIjtcbmltcG9ydCB7UHJveHlPYnNlcnZlcn0gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS90eXBlcy9wcm94eW9ic2VydmVyLm1qc1wiO1xuaW1wb3J0IHtjaGFpRG9tfSBmcm9tIFwiLi4vLi4vdXRpbC9jaGFpLWRvbS5tanNcIjtcbmltcG9ydCB7aW5pdEpTRE9NfSBmcm9tIFwiLi4vLi4vdXRpbC9qc2RvbS5tanNcIjtcblxubGV0IGV4cGVjdCA9IGNoYWkuZXhwZWN0O1xuXG5jaGFpLnVzZShjaGFpRG9tKTtcblxubGV0IGh0bWwxID0gYFxuICAgIDx0ZW1wbGF0ZSBpZD1cImN1cnJlbnRcIj5cbiAgICAgICAgPGxpIGRhdGEtbW9uc3Rlci1yZXBsYWNlPVwicGF0aDpjdXJyZW50IHwgdG9qc29uXCI+PC9saT5cbiAgICA8L3RlbXBsYXRlPlxuICAgIDxkaXYgaWQ9XCJ0ZXN0MVwiPlxuICAgICAgICA8dWwgZGF0YS1tb25zdGVyLWluc2VydD1cImN1cnJlbnQgcGF0aDphLmJcIj5cbiAgICAgICAgPC91bD5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGlkPVwidGVzdDJcIj5cbiAgICAgICAgPHVsIGRhdGEtbW9uc3Rlci1pbnNlcnQ9XCJjdXJyZW50IHBhdGg6YS5iIHwgZG9pdFwiPlxuICAgICAgICA8L3VsPlxuICAgIDwvZGl2PlxuICAgIDxkaXYgaWQ9XCJ0ZXN0M1wiPlxuICAgICAgICA8ZGl2IGRhdGEtbW9uc3Rlci1hdHRyaWJ1dGVzPVwiY2xhc3MgcGF0aDphLmJcIj5cbiAgICAgICAgICAgIDxpbnB1dCBkYXRhLW1vbnN0ZXItYXR0cmlidXRlcz1cInZhbHVlIHBhdGg6YS5jXCIgaWQ9XCJpbnB1dDFcIj5cbiAgICAgICAgICAgIDxpbnB1dCBkYXRhLW1vbnN0ZXItYXR0cmlidXRlcz1cImNoZWNrZWQgcGF0aDphLmNoZWNrYm94XCIgdHlwZT1cImNoZWNrYm94XCIgbmFtZT1cImNoZWNrYm94XCIgaWQ9XCJjaGVja2JveFwiPlxuICAgICAgICAgICAgPGlucHV0IGRhdGEtbW9uc3Rlci1hdHRyaWJ1dGVzPVwidmFsdWUgcGF0aDphLnRleHRcIiB0eXBlPVwidGV4dFwiIG5hbWU9XCJ0ZXh0XCIgaWQ9XCJ0ZXh0XCI+XG4gICAgICAgICAgICA8aW5wdXQgZGF0YS1tb25zdGVyLWF0dHJpYnV0ZXM9XCJjaGVja2VkIHBhdGg6YS5yYWRpb1wiIHR5cGU9XCJyYWRpb1wiIG5hbWU9XCJyYWRpb1wiIHZhbHVlPVwicjFcIiBpZD1cInJhZGlvXCI+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cInJhZGlvXCIgbmFtZT1cInJhZGlvXCIgdmFsdWU9XCJyMlwiIGlkPVwicjJcIj5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwicmFkaW9cIiBuYW1lPVwicmFkaW9cIiB2YWx1ZT1cInJ4XCIgaWQ9XCJyeFwiPlxuXG4gICAgICAgICAgICA8c2VsZWN0IGRhdGEtbW9uc3Rlci1hdHRyaWJ1dGVzPVwidmFsdWUgcGF0aDphLnNlbGVjdFwiIG5hbWU9XCJzZWxlY3RcIiBpZD1cInNlbGVjdFwiPlxuICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJvdGhlci12YWx1ZVwiPnZhbHVlMTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIDxvcHRpb24+dmFsdWUyPC9vcHRpb24+XG4gICAgICAgICAgICA8L3NlbGVjdD5cblxuICAgICAgICAgICAgPHNlbGVjdCBkYXRhLW1vbnN0ZXItYXR0cmlidXRlcz1cInZhbHVlIHBhdGg6YS5tdWx0aXNlbGVjdFwiIG5hbWU9XCJtdWx0aXNlbGVjdFwiIG11bHRpcGxlIGlkPVwibXVsdGlzZWxlY3RcIj5cbiAgICAgICAgICAgICAgICA8b3B0aW9uPnZhbHVlMTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIDxvcHRpb24+dmFsdWUyPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgPG9wdGlvbj52YWx1ZTM8L29wdGlvbj5cbiAgICAgICAgICAgICAgICA8b3B0aW9uPnZhbHVlNDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJvdGhlci12YWx1ZTVcIj52YWx1ZTU8L29wdGlvbj5cbiAgICAgICAgICAgIDwvc2VsZWN0PlxuXG4gICAgICAgICAgICA8dGV4dGFyZWEgbmFtZT1cInRleHRhcmVhXCIgaWQ9XCJ0ZXh0YXJlYVwiIGRhdGEtbW9uc3Rlci1hdHRyaWJ1dGVzPVwidmFsdWUgcGF0aDphLnRleHRhcmVhXCI+PC90ZXh0YXJlYT5cblxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cblxuYDtcblxubGV0IGh0bWwyID0gYFxuICAgIDxkaXYgaWQ9XCJ0ZXN0MVwiPlxuICAgICAgICA8ZGl2IGRhdGEtbW9uc3Rlci1yZXBsYWNlPVwicGF0aDp0ZXh0IHwgdG9sb3dlclwiPjwvZGl2PlxuICAgICAgICA8ZGl2IGRhdGEtbW9uc3Rlci1yZXBsYWNlPVwicGF0aDp0ZXh0IHwgY2FsbDpteWZvcm1hdHRlclwiPjwvZGl2PlxuICAgICAgICA8ZGl2IGRhdGEtbW9uc3Rlci1yZXBsYWNlPVwic3RhdGljOmhlbGxvXFxcXCBcIj48L2Rpdj5cbiAgICA8L2Rpdj5cbmA7XG5cbmxldCBodG1sMyA9IGBcblxuICAgIDx0ZW1wbGF0ZSBpZD1cIm15aW5uZXJpZFwiPlxuICAgICAgICA8c3BhbiBkYXRhLW1vbnN0ZXItcmVwbGFjZT1cInBhdGg6bXlpbm5lcmlkIHwgdG9qc29uXCI+PC9zcGFuPlxuICAgIDwvdGVtcGxhdGU+XG5cbiAgICA8dGVtcGxhdGUgaWQ9XCJteWlkXCI+XG4gICAgICAgIDxwIGRhdGEtbW9uc3Rlci1pbnNlcnQ9XCJteWlubmVyaWQgcGF0aDphLmJcIj48L3A+XG4gICAgPC90ZW1wbGF0ZT5cblxuICAgIDxkaXYgaWQ9XCJ0ZXN0MVwiPlxuICAgICAgICA8ZGl2IGRhdGEtbW9uc3Rlci1pbnNlcnQ9XCJteWlkIHBhdGg6YS5iXCI+PC9kaXY+XG4gICAgPC9kaXY+XG5cbmA7XG5cbmxldCBodG1sNCA9IGBcbiAgICA8ZGl2PlxuICAgICAgICA8Zm9ybSBpZD1cImZvcm0xXCI+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgdmFsdWU9XCJjaGVja2VkXCIgbmFtZT1cImNoZWNrYm94XCIgZGF0YS1tb25zdGVyLWJpbmQ9XCJwYXRoOnN0YXRlXCI+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBuYW1lPVwidGV4dFwiPlxuICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJyYWRpb1wiIG5hbWU9XCJyYWRpb1wiIHZhbHVlPVwicjFcIiBpZD1cInIxXCIgZGF0YS1tb25zdGVyLWJpbmQ9XCJwYXRoOnJhZGlvXCI+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cInJhZGlvXCIgbmFtZT1cInJhZGlvXCIgdmFsdWU9XCJyMlwiIGlkPVwicjJcIiBkYXRhLW1vbnN0ZXItYmluZD1cInBhdGg6cmFkaW9cIj5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwicmFkaW9cIiBuYW1lPVwicmFkaW9cIiB2YWx1ZT1cInJ4XCIgaWQ9XCJyeFwiIGRhdGEtY29tbWVudD1cIm5vdCBjYWxsZWQgYmVjYXVzZSBubyBiaW5kIGF0dHJpYnV0ZVwiPlxuICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJidXR0b25cIiBuYW1lPVwiYnV0dG9uXCI+XG5cbiAgICAgICAgICAgIDxzZWxlY3QgbmFtZT1cInNlbGVjdDFcIiBpZD1cInNlbGVjdDFcIiBkYXRhLW1vbnN0ZXItYmluZD1cInBhdGg6c2VsZWN0XCI+XG4gICAgICAgICAgICAgICAgPG9wdGlvbj52YWx1ZTE8L29wdGlvbj5cbiAgICAgICAgICAgICAgICA8b3B0aW9uPnZhbHVlMjwvb3B0aW9uPlxuICAgICAgICAgICAgPC9zZWxlY3Q+XG5cbiAgICAgICAgICAgIDxzZWxlY3QgbmFtZT1cInNlbGVjdDJcIiBtdWx0aXBsZSBpZD1cInNlbGVjdDJcIiBkYXRhLW1vbnN0ZXItYmluZD1cInBhdGg6bXVsdGlzZWxlY3RcIj5cbiAgICAgICAgICAgICAgICA8b3B0aW9uPnZhbHVlMTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIDxvcHRpb24+dmFsdWUyPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgPG9wdGlvbj52YWx1ZTM8L29wdGlvbj5cbiAgICAgICAgICAgICAgICA8b3B0aW9uPnZhbHVlNDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIDxvcHRpb24+dmFsdWU1PC9vcHRpb24+XG4gICAgICAgICAgICA8L3NlbGVjdD5cblxuICAgICAgICAgICAgPHRleHRhcmVhIG5hbWU9XCJ0ZXh0YXJlYVwiIGlkPVwidGV4dGFyZWFcIiBkYXRhLW1vbnN0ZXItYmluZD1cInBhdGg6dGV4dGFyZWFcIj5cbiAgICAgICAgICAgIFxuICAgICAgICA8L3RleHRhcmVhPlxuXG4gICAgICAgIDwvZm9ybT5cbiAgICA8L2Rpdj5cblxuYDtcblxuXG5kZXNjcmliZSgnRE9NJywgZnVuY3Rpb24gKCkge1xuXG4gICAgYmVmb3JlKGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgIGluaXRKU0RPTSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgZG9uZSgpXG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICAgIGxldCBtb2NrcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpO1xuICAgICAgICBtb2Nrcy5pbm5lckhUTUwgPSBodG1sMTtcbiAgICB9KVxuXG4gICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgICAgbGV0IG1vY2tzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vY2tzJyk7XG4gICAgICAgIG1vY2tzLmlubmVySFRNTCA9IFwiXCI7XG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCdVcGRhdGVyKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGRlc2NyaWJlKCd0ZXN0IEdldHRlciAmJiBTZXR0ZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpdCgnc2V0RXZlbnRUeXBlcygpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGxldCBlbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Rlc3QxJylcbiAgICAgICAgICAgICAgICBleHBlY3QobmV3IFVwZGF0ZXIoZWxlbWVudCkuc2V0RXZlbnRUeXBlcyhbJ3RvdWNoJ10pKS50by5iZS5pbnN0YW5jZW9mKFVwZGF0ZXIpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIGl0KCdnZXRTdWJqZWN0KCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbGV0IGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGVzdDEnKVxuICAgICAgICAgICAgICAgIGxldCBzdWJqZWN0ID0ge2E6IDF9O1xuICAgICAgICAgICAgICAgIGV4cGVjdChuZXcgVXBkYXRlcihlbGVtZW50LCBzdWJqZWN0KS5nZXRTdWJqZWN0KCkuYSkudG8uYmUuZXF1YWwoMSk7XG4gICAgICAgICAgICB9KVxuICAgICAgICB9KTtcblxuICAgICAgICBkZXNjcmliZSgndGVzdCBjb250cm9sIG1ldGhvZHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpdCgnZW5hYmxlRXZlbnRQcm9jZXNzaW5nKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbGV0IGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGVzdDEnKVxuICAgICAgICAgICAgICAgIGV4cGVjdChuZXcgVXBkYXRlcihlbGVtZW50KS5lbmFibGVFdmVudFByb2Nlc3NpbmcoKSkudG8uYmUuaW5zdGFuY2VvZihVcGRhdGVyKTtcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGl0KCdkaXNhYmxlRXZlbnRQcm9jZXNzaW5nKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbGV0IGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGVzdDEnKVxuICAgICAgICAgICAgICAgIGV4cGVjdChuZXcgVXBkYXRlcihlbGVtZW50KS5kaXNhYmxlRXZlbnRQcm9jZXNzaW5nKCkpLnRvLmJlLmluc3RhbmNlb2YoVXBkYXRlcik7XG4gICAgICAgICAgICB9KVxuICAgICAgICB9KTtcblxuICAgICAgICBkZXNjcmliZSgndGVzdCBFcnJvcnMnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIGl0KCdzaG91bGQgdGhyb3cgdmFsdWUgaXMgbm90IGFuIGluc3RhbmNlIG9mIEhUTUxFbGVtZW50IEVycm9yJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGV4cGVjdCgoKSA9PiBuZXcgVXBkYXRlcigpKS50by50aHJvdyhUeXBlRXJyb3IpXG4gICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICBpdCgnc2hvdWxkIHRocm93IHZhbHVlIGlzIHdyb25nJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICAgICAgbGV0IGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGVzdDEnKVxuICAgICAgICAgICAgICAgIGV4cGVjdCgoKSA9PiBuZXcgVXBkYXRlcihlbGVtZW50LCBudWxsKSkudG8udGhyb3coVHlwZUVycm9yKVxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBFcnJvcjogdGhlIHZhbHVlIGlzIG5vdCBpdGVyYWJsZScsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICAgICAgbGV0IGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGVzdDEnKVxuXG4gICAgICAgICAgICAgICAgbGV0IHUgPSBuZXcgVXBkYXRlcihcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgYToge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHg6IFtdXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApO1xuXG5cbiAgICAgICAgICAgICAgICB1LnJ1bigpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBkb25lKG5ldyBFcnJvcihcInNob3VsZCBuZXZlciBjYWxsZWQhXCIpKTtcbiAgICAgICAgICAgICAgICB9KS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QoZSkuaXMuaW5zdGFuY2VPZihFcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChlICsgXCJcIikudG8uYmUuZXF1YWwoJ0Vycm9yOiB0aGUgdmFsdWUgaXMgbm90IGl0ZXJhYmxlJyk7XG4gICAgICAgICAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICAgICAgICB9KVxuXG5cbiAgICAgICAgICAgIH0pO1xuXG5cbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnVXBkYXRlcigpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBkZXNjcmliZSgnbmV3IFVwZGF0ZXInLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGRvY3VtZW50IG9iamVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBsZXQgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0ZXN0MScpXG5cbiAgICAgICAgICAgICAgICBsZXQgZCA9IG5ldyBVcGRhdGVyKFxuICAgICAgICAgICAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgICAgICAgICAgICB7fVxuICAgICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgICBleHBlY3QodHlwZW9mIGQpLmlzLmVxdWFsKCdvYmplY3QnKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdVcGRhdGVyKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGRlc2NyaWJlKCdSZXBlYXQnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIGl0KCdzaG91bGQgYnVpbGQgNiBsaSBlbGVtZW50cycsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICAgICAgbGV0IGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGVzdDEnKVxuXG4gICAgICAgICAgICAgICAgbGV0IGQgPSBuZXcgVXBkYXRlcihcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgYToge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGI6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge2k6ICcwJ30sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtpOiAnMSd9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7aTogJzInfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge2k6ICczJ30sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtpOiAnNCd9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7aTogJzUnfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgZC5ydW4oKS50aGVuKCgpID0+IHtcblxuICAgICAgICAgICAgICAgICAgICBleHBlY3QodHlwZW9mIGQpLmlzLmVxdWFsKCdvYmplY3QnKTtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCA2OyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdChlbGVtZW50KS5jb250YWluLmh0bWwoJzxsaSBkYXRhLW1vbnN0ZXItcmVwbGFjZT1cInBhdGg6YS5iLicgKyBpICsgJyB8IHRvanNvblwiIGRhdGEtbW9uc3Rlci1pbnNlcnQtcmVmZXJlbmNlPVwiY3VycmVudC0nICsgaSArICdcIj57XCJpXCI6XCInICsgaSArICdcIn08L2xpPicpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgICAgIH0pLmNhdGNoKFxuICAgICAgICAgICAgICAgICAgICBlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRvbmUobmV3IEVycm9yKGUpKVxuICAgICAgICAgICAgICAgICAgICB9KVxuXG5cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ1VwZGF0ZXIoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAgICAgIGxldCBtb2NrcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpO1xuICAgICAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gaHRtbDQ7XG4gICAgICAgIH0pXG5cbiAgICAgICAgZGVzY3JpYmUoJ0V2ZW50aGFuZGxpbmcnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIGxldCB1cGRhdGVyLCBmb3JtMSwgcHJveHlvYnNlcnZlcjtcbiAgICAgICAgICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgICAgICAgICAgIHByb3h5b2JzZXJ2ZXIgPSBuZXcgUHJveHlPYnNlcnZlcih7fSlcbiAgICAgICAgICAgICAgICB1cGRhdGVyID0gbmV3IFVwZGF0ZXIoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2Zvcm0xJyksIHByb3h5b2JzZXJ2ZXIpO1xuICAgICAgICAgICAgICAgIGZvcm0xID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2Zvcm0xJyk7XG5cbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIC8vIGhlcmUgY2xpY2sgZXZlbnRzIGFyZSB0aHJvd24gb24gdGhlIGNoZWNrYm94IGFuZCB0aGUgc2V0dGluZyBvZiB0aGUgdmFsdWUgaXMgb2JzZXJ2ZWQgdmlhIHRoZSBwcm94eW9ic2VydmVyLlxuICAgICAgICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgY2hlY2tib3ggY2xpY2sgZXZlbnRzJywgZnVuY3Rpb24gKGRvbmUpIHtcblxuICAgICAgICAgICAgICAgIHVwZGF0ZXIuZW5hYmxlRXZlbnRQcm9jZXNzaW5nKCk7XG5cbiAgICAgICAgICAgICAgICBsZXQgc3ViamVjdCA9IHVwZGF0ZXIuZ2V0U3ViamVjdCgpO1xuICAgICAgICAgICAgICAgIGV4cGVjdChzdWJqZWN0KS5pcy5lcXVhbChwcm94eW9ic2VydmVyLmdldFN1YmplY3QoKSk7XG5cbiAgICAgICAgICAgICAgICBsZXQgZXhwZWN0ZWQgPSBbJ2NoZWNrZWQnLCB1bmRlZmluZWQsICdjaGVja2VkJ107XG4gICAgICAgICAgICAgICAgLy8gaGVyZSB0aGUgbm90YXRpb24gd2l0aCBmdW5jdGlvbiBpcyBpbXBvcnRhbnQsIGJlY2F1c2UgdGhlIHBvaW50ZXIgaXMgc2V0LlxuICAgICAgICAgICAgICAgIHByb3h5b2JzZXJ2ZXIuYXR0YWNoT2JzZXJ2ZXIobmV3IE9ic2VydmVyKGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgICAgICBsZXQgZSA9IGV4cGVjdGVkLnNoaWZ0KCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlID09PSB1bmRlZmluZWQgJiYgZXhwZWN0ZWQubGVuZ3RoID09PSAwKSBkb25lKG5ldyBFcnJvcigndG8gbWFueSBjYWxscycpKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5nZXRTdWJqZWN0KClbJ3N0YXRlJ10gIT09IGUpIGRvbmUobmV3IEVycm9yKHRoaXMuZ2V0U3ViamVjdCgpWydzdGF0ZSddICsgJyBzaG91bGQgJyArIGUpKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGV4cGVjdGVkLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtMS5xdWVyeVNlbGVjdG9yKCdbbmFtZT1jaGVja2JveF0nKS5jbGljaygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSwgMTApXG5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBmb3JtMS5xdWVyeVNlbGVjdG9yKCdbbmFtZT1jaGVja2JveF0nKS5jbGljaygpO1xuICAgICAgICAgICAgICAgIH0sIDEwKVxuXG5cbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGl0KCdzaG91bGQgaGFuZGxlIHJhZGlvIGNsaWNrIGV2ZW50cyAxJywgZnVuY3Rpb24gKGRvbmUpIHtcblxuICAgICAgICAgICAgICAgIHVwZGF0ZXIuZW5hYmxlRXZlbnRQcm9jZXNzaW5nKCk7XG5cbiAgICAgICAgICAgICAgICBsZXQgc3ViamVjdCA9IHVwZGF0ZXIuZ2V0U3ViamVjdCgpO1xuICAgICAgICAgICAgICAgIGV4cGVjdChzdWJqZWN0KS5pcy5lcXVhbChwcm94eW9ic2VydmVyLmdldFN1YmplY3QoKSk7XG5cbiAgICAgICAgICAgICAgICBsZXQgZXhwZWN0ZWQgPSBbJ3IxJywgJ3IyJywgJ3IxJ107XG4gICAgICAgICAgICAgICAgbGV0IGNsaWNrVGFyZ2V0cyA9IFsncjInLCAncjEnXVxuICAgICAgICAgICAgICAgIC8vIGhlcmUgdGhlIG5vdGF0aW9uIHdpdGggZnVuY3Rpb24gaXMgaW1wb3J0YW50LCBiZWNhdXNlIHRoZSB0aGlzIHBvaW50ZXIgaXMgc2V0LlxuICAgICAgICAgICAgICAgIHByb3h5b2JzZXJ2ZXIuYXR0YWNoT2JzZXJ2ZXIobmV3IE9ic2VydmVyKGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgICAgICBsZXQgZSA9IGV4cGVjdGVkLnNoaWZ0KCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlID09PSB1bmRlZmluZWQgJiYgZXhwZWN0ZWQubGVuZ3RoID09PSAwKSBkb25lKG5ldyBFcnJvcigndG8gbWFueSBjYWxscycpKTtcblxuICAgICAgICAgICAgICAgICAgICBsZXQgdiA9IHRoaXMuZ2V0U3ViamVjdCgpWydyYWRpbyddO1xuICAgICAgICAgICAgICAgICAgICBpZiAodiAhPT0gZSkgZG9uZShuZXcgRXJyb3IodiArICcgc2hvdWxkICcgKyBlKSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChleHBlY3RlZC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGNsaWNrVGFyZ2V0cy5zaGlmdCgpKS5jbGljaygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSwgMTApXG5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncjEnKS5jbGljaygpO1xuICAgICAgICAgICAgICAgIH0sIDEwKVxuXG4gICAgICAgICAgICAgICAgLy8gbm8gaGFuZGxlciAvLyBiaW5kXG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdyeCcpLmNsaWNrKCk7XG4gICAgICAgICAgICAgICAgfSwgMjApXG5cbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGl0KCdzaG91bGQgaGFuZGxlIHNlbGVjdCBjbGljayBldmVudHMgMicsIGZ1bmN0aW9uIChkb25lKSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgc2VsZWN0RWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZWxlY3QxJyk7XG5cbiAgICAgICAgICAgICAgICB1cGRhdGVyLmVuYWJsZUV2ZW50UHJvY2Vzc2luZygpO1xuXG4gICAgICAgICAgICAgICAgbGV0IHN1YmplY3QgPSB1cGRhdGVyLmdldFN1YmplY3QoKTtcbiAgICAgICAgICAgICAgICBleHBlY3Qoc3ViamVjdCkuaXMuZXF1YWwocHJveHlvYnNlcnZlci5nZXRTdWJqZWN0KCkpO1xuXG4gICAgICAgICAgICAgICAgbGV0IGV4cGVjdGVkID0gWyd2YWx1ZTInLCAndmFsdWUxJywgJ3ZhbHVlMiddO1xuICAgICAgICAgICAgICAgIC8vIGhlcmUgdGhlIG5vdGF0aW9uIHdpdGggZnVuY3Rpb24gaXMgaW1wb3J0YW50LCBiZWNhdXNlIHRoZSB0aGlzIHBvaW50ZXIgaXMgc2V0LlxuICAgICAgICAgICAgICAgIHByb3h5b2JzZXJ2ZXIuYXR0YWNoT2JzZXJ2ZXIobmV3IE9ic2VydmVyKGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgICAgICBsZXQgZSA9IGV4cGVjdGVkLnNoaWZ0KCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlID09PSB1bmRlZmluZWQgJiYgZXhwZWN0ZWQubGVuZ3RoID09PSAwKSBkb25lKG5ldyBFcnJvcigndG8gbWFueSBjYWxscycpKTtcblxuICAgICAgICAgICAgICAgICAgICBsZXQgdiA9IHRoaXMuZ2V0U3ViamVjdCgpWydzZWxlY3QnXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHYgIT09IGUpIGRvbmUobmV3IEVycm9yKHYgKyAnIHNob3VsZCAnICsgZSkpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXhwZWN0ZWQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RFbGVtZW50LnNlbGVjdGVkSW5kZXggPSBzZWxlY3RFbGVtZW50LnNlbGVjdGVkSW5kZXggPT09IDEgPyAwIDogMTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RFbGVtZW50LmNsaWNrKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9LCAxMClcblxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHNldCB2YWx1ZSBhbmQgc2ltdWxhdGUgY2xpY2sgZXZlbnQgZm9yIGJ1YmJsZVxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RFbGVtZW50LnNlbGVjdGVkSW5kZXggPSAxO1xuICAgICAgICAgICAgICAgICAgICBzZWxlY3RFbGVtZW50LmNsaWNrKCk7XG5cbiAgICAgICAgICAgICAgICB9LCAyMClcblxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGl0KCdzaG91bGQgaGFuZGxlIHRleHRhcmVhIGV2ZW50cycsIGZ1bmN0aW9uIChkb25lKSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgdGV4dGFyZWFFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3RleHRhcmVhJyk7XG5cbiAgICAgICAgICAgICAgICB1cGRhdGVyLmVuYWJsZUV2ZW50UHJvY2Vzc2luZygpO1xuXG4gICAgICAgICAgICAgICAgbGV0IHN1YmplY3QgPSB1cGRhdGVyLmdldFN1YmplY3QoKTtcbiAgICAgICAgICAgICAgICBleHBlY3Qoc3ViamVjdCkuaXMuZXF1YWwocHJveHlvYnNlcnZlci5nZXRTdWJqZWN0KCkpO1xuXG4gICAgICAgICAgICAgICAgbGV0IGV4cGVjdGVkID0gWyd0ZXN0WCcsICdsb3JlbSBpcHN1bScsICcnXTtcbiAgICAgICAgICAgICAgICBsZXQgdGVzdFZhbHVlcyA9IFtcImxvcmVtIGlwc3VtXCIsIFwiXCJdO1xuICAgICAgICAgICAgICAgIC8vIGhlcmUgdGhlIG5vdGF0aW9uIHdpdGggZnVuY3Rpb24gaXMgaW1wb3J0YW50LCBiZWNhdXNlIHRoZSB0aGlzIHBvaW50ZXIgaXMgc2V0LlxuICAgICAgICAgICAgICAgIHByb3h5b2JzZXJ2ZXIuYXR0YWNoT2JzZXJ2ZXIobmV3IE9ic2VydmVyKGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgICAgICBsZXQgZSA9IGV4cGVjdGVkLnNoaWZ0KCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlID09PSB1bmRlZmluZWQgJiYgZXhwZWN0ZWQubGVuZ3RoID09PSAwKSBkb25lKG5ldyBFcnJvcigndG8gbWFueSBjYWxscycpKTtcblxuICAgICAgICAgICAgICAgICAgICBsZXQgdiA9IHRoaXMuZ2V0U3ViamVjdCgpWyd0ZXh0YXJlYSddO1xuICAgICAgICAgICAgICAgICAgICBpZiAoSlNPTi5zdHJpbmdpZnkodikgIT09IEpTT04uc3RyaW5naWZ5KGUpKSBkb25lKG5ldyBFcnJvcihKU09OLnN0cmluZ2lmeSh2KSArICcgc2hvdWxkICcgKyBKU09OLnN0cmluZ2lmeShlKSkpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXhwZWN0ZWQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0YXJlYUVsZW1lbnQudmFsdWUgPSB0ZXN0VmFsdWVzLnNoaWZ0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dGFyZWFFbGVtZW50LmNsaWNrKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9LCAxMClcblxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gc2V0IHZhbHVlIGFuZCBzaW11bGF0ZSBjbGljayBldmVudCBmb3IgYnViYmxlXG4gICAgICAgICAgICAgICAgICAgIHRleHRhcmVhRWxlbWVudC52YWx1ZSA9IFwidGVzdFhcIjtcbiAgICAgICAgICAgICAgICAgICAgdGV4dGFyZWFFbGVtZW50LmNsaWNrKCk7XG5cbiAgICAgICAgICAgICAgICB9LCAyMClcblxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGl0KCdzaG91bGQgaGFuZGxlIG11bHRpcGxlIHNlbGVjdCBldmVudHMnLCBmdW5jdGlvbiAoZG9uZSkge1xuXG4gICAgICAgICAgICAgICAgbGV0IHNlbGVjdEVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2VsZWN0MicpO1xuXG4gICAgICAgICAgICAgICAgdXBkYXRlci5lbmFibGVFdmVudFByb2Nlc3NpbmcoKTtcblxuICAgICAgICAgICAgICAgIGxldCBzdWJqZWN0ID0gdXBkYXRlci5nZXRTdWJqZWN0KCk7XG4gICAgICAgICAgICAgICAgZXhwZWN0KHN1YmplY3QpLmlzLmVxdWFsKHByb3h5b2JzZXJ2ZXIuZ2V0U3ViamVjdCgpKTtcblxuICAgICAgICAgICAgICAgIGxldCBleHBlY3RlZCA9IFtcbiAgICAgICAgICAgICAgICAgICAgWyd2YWx1ZTEnXSxcbiAgICAgICAgICAgICAgICAgICAgWyd2YWx1ZTInLCAndmFsdWUzJywgJ3ZhbHVlNCddLFxuICAgICAgICAgICAgICAgICAgICBbJ3ZhbHVlMScsICd2YWx1ZTQnXSxcbiAgICAgICAgICAgICAgICBdO1xuXG4gICAgICAgICAgICAgICAgbGV0IHRlc3RTZWxlY3Rpb25zID0gW1xuICAgICAgICAgICAgICAgICAgICBbZmFsc2UsIHRydWUsIHRydWUsIHRydWVdLFxuICAgICAgICAgICAgICAgICAgICBbdHJ1ZSwgZmFsc2UsIGZhbHNlLCB0cnVlXSxcbiAgICAgICAgICAgICAgICBdXG5cbiAgICAgICAgICAgICAgICAvLyBoZXJlIHRoZSBub3RhdGlvbiB3aXRoIGZ1bmN0aW9uIGlzIGltcG9ydGFudCwgYmVjYXVzZSB0aGUgdGhpcyBwb2ludGVyIGlzIHNldC5cbiAgICAgICAgICAgICAgICBwcm94eW9ic2VydmVyLmF0dGFjaE9ic2VydmVyKG5ldyBPYnNlcnZlcihmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgbGV0IGUgPSBleHBlY3RlZC5zaGlmdCgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZSA9PT0gdW5kZWZpbmVkICYmIGV4cGVjdGVkLmxlbmd0aCA9PT0gMCkgZG9uZShuZXcgRXJyb3IoJ3RvIG1hbnkgY2FsbHMnKSk7XG5cbiAgICAgICAgICAgICAgICAgICAgbGV0IHYgPSB0aGlzLmdldFN1YmplY3QoKVsnbXVsdGlzZWxlY3QnXTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoSlNPTi5zdHJpbmdpZnkodikgIT09IEpTT04uc3RyaW5naWZ5KGUpKSBkb25lKG5ldyBFcnJvcihKU09OLnN0cmluZ2lmeSh2KSArICcgc2hvdWxkICcgKyBKU09OLnN0cmluZ2lmeShlKSkpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXhwZWN0ZWQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgdiA9IHRlc3RTZWxlY3Rpb25zLnNoaWZ0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0RWxlbWVudC5vcHRpb25zWzBdLnNlbGVjdGVkID0gdlswXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RFbGVtZW50Lm9wdGlvbnNbMV0uc2VsZWN0ZWQgPSB2WzFdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdEVsZW1lbnQub3B0aW9uc1syXS5zZWxlY3RlZCA9IHZbMl07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0RWxlbWVudC5vcHRpb25zWzNdLnNlbGVjdGVkID0gdlszXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RFbGVtZW50LmNsaWNrKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9LCAxMClcblxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0RWxlbWVudC5vcHRpb25zWzBdLnNlbGVjdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0RWxlbWVudC5vcHRpb25zWzFdLnNlbGVjdGVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdEVsZW1lbnQub3B0aW9uc1syXS5zZWxlY3RlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICBzZWxlY3RFbGVtZW50Lm9wdGlvbnNbM10uc2VsZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0RWxlbWVudC5jbGljaygpO1xuXG4gICAgICAgICAgICAgICAgfSwgMjApXG5cblxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgfSlcblxuXG4gICAgZGVzY3JpYmUoJ1VwZGF0ZXIoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAgICAgIGxldCBtb2NrcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpO1xuICAgICAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gaHRtbDI7XG4gICAgICAgIH0pXG5cbiAgICAgICAgZGVzY3JpYmUoJ1JlcGxhY2UnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIGl0KCdzaG91bGQgYWRkIGxvd2VyIGhlbGxvIGFuZCBIRUxMT3llcyEnLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICAgICAgICAgIGxldCBlbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Rlc3QxJylcblxuICAgICAgICAgICAgICAgIGxldCBkID0gbmV3IFVwZGF0ZXIoXG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQsXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHQ6IFwiSEFMTE9cIlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgIGQuc2V0Q2FsbGJhY2soJ215Zm9ybWF0dGVyJywgZnVuY3Rpb24gKGEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGEgKyAneWVzISdcbiAgICAgICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGQucnVuKCkudGhlbigoKSA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdCh0eXBlb2YgZCkuaXMuZXF1YWwoJ29iamVjdCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0KGVsZW1lbnQpLmNvbnRhaW4uaHRtbCgnPGRpdiBkYXRhLW1vbnN0ZXItcmVwbGFjZT1cInBhdGg6dGV4dCB8IHRvbG93ZXJcIj5oYWxsbzwvZGl2PicpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0KGVsZW1lbnQpLmNvbnRhaW4uaHRtbCgnPGRpdiBkYXRhLW1vbnN0ZXItcmVwbGFjZT1cInBhdGg6dGV4dCB8IGNhbGw6bXlmb3JtYXR0ZXJcIj5IQUxMT3llcyE8L2Rpdj4nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdChlbGVtZW50KS5jb250YWluLmh0bWwoJzxkaXYgZGF0YS1tb25zdGVyLXJlcGxhY2U9XCJzdGF0aWM6aGVsbG9cXFxcIFwiPmhlbGxvIDwvZGl2PicpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZG9uZSgpO1xuICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaChcbiAgICAgICAgICAgICAgICAgICAgICAgIGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbmUobmV3IEVycm9yKGUpKVxuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICB9LCAxMDApXG5cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuXG4gICAgZGVzY3JpYmUoJ1VwZGF0ZXIoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAgICAgIGxldCBtb2NrcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpO1xuICAgICAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gaHRtbDM7XG4gICAgICAgIH0pXG5cbiAgICAgICAgZGVzY3JpYmUoJ1JlcGxhY2UnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIGl0KCdzaG91bGQgJywgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgICAgICAgICBsZXQgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0ZXN0MScpXG5cbiAgICAgICAgICAgICAgICBsZXQgZCA9IG5ldyBVcGRhdGVyKFxuICAgICAgICAgICAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYjogW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7aTogJzAnfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApO1xuXG5cbiAgICAgICAgICAgICAgICBkLnJ1bigpLnRoZW4oKCkgPT4ge1xuXG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdCh0eXBlb2YgZCkuaXMuZXF1YWwoJ29iamVjdCcpO1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QoZWxlbWVudCkuY29udGFpbi5odG1sKCc8ZGl2IGRhdGEtbW9uc3Rlci1pbnNlcnQ9XCJteWlkIHBhdGg6YS5iXCI+Jyk7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChlbGVtZW50KS5jb250YWluLmh0bWwoJzxwIGRhdGEtbW9uc3Rlci1pbnNlcnQ9XCJteWlubmVyaWQgcGF0aDphLmJcIiBkYXRhLW1vbnN0ZXItaW5zZXJ0LXJlZmVyZW5jZT1cIm15aWQtMFwiPicpO1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QoZWxlbWVudCkuY29udGFpbi5odG1sKCc8c3BhbiBkYXRhLW1vbnN0ZXItcmVwbGFjZT1cInBhdGg6YS5iLjAgfCB0b2pzb25cIiBkYXRhLW1vbnN0ZXItaW5zZXJ0LXJlZmVyZW5jZT1cIm15aW5uZXJpZC0wXCI+e1wiaVwiOlwiMFwifTwvc3Bhbj4nKTtcblxuICAgICAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICAgICAgfSkuY2F0Y2goXG4gICAgICAgICAgICAgICAgICAgIGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgZG9uZShuZXcgRXJyb3IoZSkpXG4gICAgICAgICAgICAgICAgICAgIH0pXG5cblxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnVXBkYXRlcigpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBkZXNjcmliZSgnQXR0cmlidXRlcycsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgaXQoJ3Nob3VsZCBjaGFuZ2UgYXR0cmlidXRlcycsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICAgICAgbGV0IGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGVzdDMnKVxuXG4gICAgICAgICAgICAgICAgbGV0IHRleHQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGV4dCcpXG4gICAgICAgICAgICAgICAgZXhwZWN0KHRleHQudmFsdWUpLnRvLmJlLmVxdWFsKFwiXCIpO1xuXG4gICAgICAgICAgICAgICAgbGV0IHJhZGlvID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3JhZGlvJylcbiAgICAgICAgICAgICAgICBleHBlY3QocmFkaW8uY2hlY2tlZCkudG8uYmUuZmFsc2U7XG5cbiAgICAgICAgICAgICAgICBsZXQgY2hlY2tib3ggPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY2hlY2tib3gnKVxuICAgICAgICAgICAgICAgIGV4cGVjdChjaGVja2JveC5jaGVja2VkKS50by5iZS5mYWxzZTtcblxuICAgICAgICAgICAgICAgIGxldCBzZWxlY3QgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2VsZWN0JylcbiAgICAgICAgICAgICAgICBleHBlY3Qoc2VsZWN0LnNlbGVjdGVkSW5kZXgpLnRvLmJlLmVxdWFsKDApO1xuXG4gICAgICAgICAgICAgICAgbGV0IG11bHRpc2VsZWN0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ211bHRpc2VsZWN0JylcbiAgICAgICAgICAgICAgICBleHBlY3QobXVsdGlzZWxlY3Quc2VsZWN0ZWRJbmRleCkudG8uYmUuZXF1YWwoLTEpO1xuXG4gICAgICAgICAgICAgICAgbGV0IHRleHRhcmVhID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3RleHRhcmVhJylcbiAgICAgICAgICAgICAgICBleHBlY3QodGV4dGFyZWEudmFsdWUpLnRvLmJlLmVxdWFsKFwiXCIpO1xuXG5cbiAgICAgICAgICAgICAgICBsZXQgZCA9IG5ldyBVcGRhdGVyKFxuICAgICAgICAgICAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYjogXCJkaXYtY2xhc3NcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjOiBcImhlbGxvXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dDogXCJoZWxsb1wiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhZGlvOiBcInRydWVcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0YXJlYTogXCJ0ZXN0XCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbXVsdGlzZWxlY3Q6IFsndmFsdWUzJywgJ3ZhbHVlNCcsICdvdGhlci12YWx1ZTUnXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3Q6IFwidmFsdWUyXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tib3g6IFwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApO1xuXG5cbiAgICAgICAgICAgICAgICBkLnJ1bigpLnRoZW4oKCkgPT4ge1xuXG5cbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KGVsZW1lbnQpLmNvbnRhaW4uaHRtbCgnPGRpdiBkYXRhLW1vbnN0ZXItYXR0cmlidXRlcz1cImNsYXNzIHBhdGg6YS5iXCIgY2xhc3M9XCJkaXYtY2xhc3NcIj4nKTtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KGVsZW1lbnQpLmNvbnRhaW4uaHRtbCgnPGlucHV0IGRhdGEtbW9uc3Rlci1hdHRyaWJ1dGVzPVwidmFsdWUgcGF0aDphLmNcIiBpZD1cImlucHV0MVwiIHZhbHVlPVwiaGVsbG9cIj4nKTtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KGVsZW1lbnQpLmNvbnRhaW4uaHRtbCgnPHRleHRhcmVhIG5hbWU9XCJ0ZXh0YXJlYVwiIGlkPVwidGV4dGFyZWFcIiBkYXRhLW1vbnN0ZXItYXR0cmlidXRlcz1cInZhbHVlIHBhdGg6YS50ZXh0YXJlYVwiIHZhbHVlPVwidGVzdFwiPicpO1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QoZWxlbWVudCkuY29udGFpbi5odG1sKCc8aW5wdXQgZGF0YS1tb25zdGVyLWF0dHJpYnV0ZXM9XCJjaGVja2VkIHBhdGg6YS5yYWRpb1wiIHR5cGU9XCJyYWRpb1wiIG5hbWU9XCJyYWRpb1wiIHZhbHVlPVwicjFcIiBpZD1cInJhZGlvXCIgY2hlY2tlZD1cInRydWVcIj4nKTtcblxuICAgICAgICAgICAgICAgICAgICBleHBlY3QodGV4dC52YWx1ZSwgJ3RleHQgY29udHJvbCcpLnRvLmJlLmVxdWFsKGQuZ2V0U3ViamVjdCgpWydhJ11bJ2MnXSk7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChyYWRpby5jaGVja2VkLCAncmFkaW8gY29udHJvbCcpLnRvLmJlLmVxdWFsKHRydWUpO1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QodGV4dGFyZWEudmFsdWUsICd0ZXh0YXJlYSBjb250cm9sJykudG8uYmUuZXF1YWwoZC5nZXRTdWJqZWN0KClbJ2EnXVsndGV4dGFyZWEnXSk7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChzZWxlY3Quc2VsZWN0ZWRJbmRleCwgJ3NlbGVjdCBjb250cm9sJykudG8uYmUuZXF1YWwoMSk7IC8vIFswPT5vdGhlci12YWx1ZSwgMT0+dmFsdWUyXVxuXG4gICAgICAgICAgICAgICAgICAgIGxldCBtdWx0aXNlbGVjdFNlbGVjdGVkT3B0aW9ucyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IFtpbmRleCwgb2JqXSBvZiBPYmplY3QuZW50cmllcyhtdWx0aXNlbGVjdC5zZWxlY3RlZE9wdGlvbnMpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtdWx0aXNlbGVjdFNlbGVjdGVkT3B0aW9ucy5wdXNoKG9iai52YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuXG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChKU09OLnN0cmluZ2lmeShtdWx0aXNlbGVjdFNlbGVjdGVkT3B0aW9ucyksICdtdWx0aXNlbGVjdCBjb250cm9sJykudG8uYmUuZXF1YWwoSlNPTi5zdHJpbmdpZnkoZC5nZXRTdWJqZWN0KClbJ2EnXVsnbXVsdGlzZWxlY3QnXSkpO1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QoY2hlY2tib3guY2hlY2tlZCwgJ2NoZWNrYm94IGNvbnRyb2wnKS50by5iZS50cnVlO1xuXG4gICAgICAgICAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICAgICAgICB9KS5jYXRjaChcbiAgICAgICAgICAgICAgICAgICAgZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkb25lKG5ldyBFcnJvcihlKSlcbiAgICAgICAgICAgICAgICAgICAgfSlcblxuXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnR2V0IEF0dHJpYnV0ZSBQaXBlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgaWQsIG1vY2tzO1xuICAgICAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAgICAgIG1vY2tzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vY2tzJyk7XG4gICAgICAgICAgICBpZCA9IG5ldyBJRCgnbW9uc3RlcicpO1xuICAgICAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gYCA8ZGl2IGlkPVwiYCArIGlkICsgYFwiXG4gICAgICAgICAgICBkYXRhLW1vbnN0ZXItcmVwbGFjZT1cInBhdGg6YSB8IGlmOnZhbHVlOlxcXFwgXCI+PC9kaXY+YFxuICAgICAgICB9KVxuXG4gICAgICAgIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICAgICAgICBtb2Nrcy5pbm5lckhUTUwgPSBcIlwiO1xuICAgICAgICB9KVxuXG4gICAgICAgIGl0KCdzaG91bGQgaW5jbHVkZSBzcGFjZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IGRpdiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkLnRvU3RyaW5nKCkpXG5cbiAgICAgICAgICAgIGNvbnN0IHBpcGUgPSBkaXYuZ2V0QXR0cmlidXRlKCdkYXRhLW1vbnN0ZXItcmVwbGFjZScpO1xuICAgICAgICAgICAgZXhwZWN0KHBpcGUubGVuZ3RoKS50by5iZS5lcXVhbCgyMCk7XG5cbiAgICAgICAgfSk7XG4gICAgfSk7XG5cblxuICAgIGRlc2NyaWJlKCdtYW51ZWwgdXBkYXRlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgaWQsIG1vY2tzO1xuXG4gICAgICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgICAgICAgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgICAgIGlkID0gbmV3IElEKCdtb25zdGVyJykudG9TdHJpbmcoKTtcbiAgICAgICAgICAgIG1vY2tzLmlubmVySFRNTCA9IGA8aW5wdXQgaWQ9XCJgICsgaWQgKyBgXCJkYXRhLW1vbnN0ZXItYmluZD1cInBhdGg6bXl2YWx1ZVwiPmBcbiAgICAgICAgfSlcblxuICAgICAgICBhZnRlckVhY2goKCkgPT4ge1xuICAgICAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gXCJcIjtcbiAgICAgICAgfSlcblxuICAgICAgICBpdCgnc2hvdWxkIGdldCB2YWx1ZScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpLnZhbHVlID0gXCJoZWxsb1wiO1xuICAgICAgICAgICAgY29uc3QgdXBkYXRlciA9IG5ldyBVcGRhdGVyKG1vY2tzKTtcbiAgICAgICAgICAgIGNvbnN0IHN1YmplY3QgPSB1cGRhdGVyLmdldFN1YmplY3QoKTtcblxuICAgICAgICAgICAgZXhwZWN0KHN1YmplY3QpLnRvLm5vdC5oYXZlLnByb3BlcnR5KCdteXZhbHVlJyk7XG4gICAgICAgICAgICB1cGRhdGVyLnJldHJpZXZlKCk7XG4gICAgICAgICAgICBleHBlY3Qoc3ViamVjdCkudG8uaGF2ZS5wcm9wZXJ0eSgnbXl2YWx1ZScpO1xuICAgICAgICB9KTtcblxuXG4gICAgfSk7XG5cblxuICAgIC8qKlxuICAgICAqIGh0dHBzOi8vZ2l0bGFiLnNjaHVrYWkuY29tL29zcy9saWJyYXJpZXMvamF2YXNjcmlwdC9tb25zdGVyLy0vaXNzdWVzLzExMlxuICAgICAqL1xuICAgIGRlc2NyaWJlKCdVcGRhdGVyKCkgMjAyMjAxMDcnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICAgICAgICBsZXQgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgICAgIC8vIGxhbmd1YWdlPUhUTUxcbiAgICAgICAgICAgIG1vY2tzLmlubmVySFRNTCA9IGBcblxuICAgICAgICAgICAgICAgIDxkaXYgaWQ9XCJjb250YWluZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBkYXRhLW1vbnN0ZXItcmVwbGFjZT1cInBhdGg6Y29udGVudFwiPjwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG5cbiAgICAgICAgICAgIGA7XG4gICAgICAgIH0pXG5cbiAgICAgICAgZGVzY3JpYmUoJ0J1Z2ZpeCAjMTEyJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBpdCgnc2hvdWxkIGFkZCAnLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICAgICAgICAgIGxldCBjb250YWluZXJFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NvbnRhaW5lcicpO1xuICAgICAgICAgICAgICAgIGxldCBuZXdFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICAgICAgbmV3RWxlbWVudC5pbm5lckhUTUwgPSAneWVhaCEgPGI+VGVzdDwvYj4hJztcblxuICAgICAgICAgICAgICAgIGNvbnN0IGNvbnRhaW5lckhUTUwgPSBjb250YWluZXJFbGVtZW50LmlubmVySFRNTDtcbiAgICAgICAgICAgICAgICBjb25zdCBuZXdIVE1MID0gbmV3RWxlbWVudC5pbm5lckhUTUw7XG5cbiAgICAgICAgICAgICAgICBsZXQgZCA9IG5ldyBVcGRhdGVyKFxuICAgICAgICAgICAgICAgICAgICBjb250YWluZXJFbGVtZW50LFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50OiBuZXdFbGVtZW50XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBkLnJ1bigpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBlY3QoY29udGFpbmVyRWxlbWVudCkuY29udGFpbi5odG1sKCc8ZGl2PnllYWghIDxiPlRlc3Q8L2I+ITwvZGl2PicpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkb25lKGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIH0sIDEwMClcblxuICAgICAgICAgICAgICAgIC8vIGQuc2V0Q2FsbGJhY2soJ215Zm9ybWF0dGVyJywgZnVuY3Rpb24gKGEpIHtcbiAgICAgICAgICAgICAgICAvLyAgICAgcmV0dXJuIGEgKyAneWVzISdcbiAgICAgICAgICAgICAgICAvLyB9KVxuICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgLy8gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gICAgIGQucnVuKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgICAvLyAgICAgICAgIGV4cGVjdCh0eXBlb2YgZCkuaXMuZXF1YWwoJ29iamVjdCcpO1xuICAgICAgICAgICAgICAgIC8vICAgICAgICAgZXhwZWN0KGVsZW1lbnQpLmNvbnRhaW4uaHRtbCgnPGRpdiBkYXRhLW1vbnN0ZXItcmVwbGFjZT1cInBhdGg6dGV4dCB8IHRvbG93ZXJcIj5oYWxsbzwvZGl2PicpO1xuICAgICAgICAgICAgICAgIC8vICAgICAgICAgZXhwZWN0KGVsZW1lbnQpLmNvbnRhaW4uaHRtbCgnPGRpdiBkYXRhLW1vbnN0ZXItcmVwbGFjZT1cInBhdGg6dGV4dCB8IGNhbGw6bXlmb3JtYXR0ZXJcIj5IQUxMT3llcyE8L2Rpdj4nKTtcbiAgICAgICAgICAgICAgICAvLyAgICAgICAgIGV4cGVjdChlbGVtZW50KS5jb250YWluLmh0bWwoJzxkaXYgZGF0YS1tb25zdGVyLXJlcGxhY2U9XCJzdGF0aWM6aGVsbG9cXFxcIFwiPmhlbGxvIDwvZGl2PicpO1xuICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgLy8gICAgICAgICByZXR1cm4gZG9uZSgpO1xuICAgICAgICAgICAgICAgIC8vICAgICB9KS5jYXRjaChcbiAgICAgICAgICAgICAgICAvLyAgICAgICAgIGUgPT4ge1xuICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgIGRvbmUobmV3IEVycm9yKGUpKVxuICAgICAgICAgICAgICAgIC8vICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAvLyB9LCAxMDApXG5cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuXG59KTsiLCAiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgY2hhaSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge0FUVFJJQlVURV9PUFRJT05TfSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2RvbS9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQge2dldERvY3VtZW50fSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2RvbS91dGlsLm1qc1wiO1xuaW1wb3J0IHtjaGFpRG9tfSBmcm9tIFwiLi4vLi4vdXRpbC9jaGFpLWRvbS5tanNcIjtcbmltcG9ydCB7aW5pdEpTRE9NfSBmcm9tIFwiLi4vLi4vdXRpbC9qc2RvbS5tanNcIjtcblxuXG5sZXQgZXhwZWN0ID0gY2hhaS5leHBlY3Q7XG5jaGFpLnVzZShjaGFpRG9tKTtcblxubGV0IGh0bWwxID0gYFxuICAgIDxkaXYgaWQ9XCJ0ZXN0MVwiPlxuICAgIDwvZGl2PlxuYDtcblxuZGVzY3JpYmUoJ0RPTScsIGZ1bmN0aW9uICgpIHtcblxuICAgIGxldCBDdXN0b21Db250cm9sLCByZWdpc3RlckN1c3RvbUVsZW1lbnQsIFRlc3RDb21wb25lbnQsIGRvY3VtZW50LCBqc2RvbUZsYWc7XG5cbiAgICBkZXNjcmliZSgnQ3VzdG9tQ29udHJvbCgpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGJlZm9yZShmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICAgICAgaW5pdEpTRE9NKCkudGhlbigoKSA9PiB7XG5cbiAgICAgICAgICAgICAgICAvLyBqc2RvbSBkb2VzIG5vdCBzdXBwb3J0IEVsZW1lbnRJbnRlcm5hbHNcbiAgICAgICAgICAgICAgICBqc2RvbUZsYWcgPSBuYXZpZ2F0b3IudXNlckFnZW50LmluY2x1ZGVzKFwianNkb21cIik7XG5cbiAgICAgICAgICAgICAgICBpbXBvcnQoXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvZG9tL2N1c3RvbWVsZW1lbnQubWpzXCIpLnRoZW4oKG0pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmVnaXN0ZXJDdXN0b21FbGVtZW50ID0gbVsncmVnaXN0ZXJDdXN0b21FbGVtZW50J107XG5cblxuICAgICAgICAgICAgICAgICAgICBpbXBvcnQoXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvZG9tL2N1c3RvbWNvbnRyb2wubWpzXCIpLnRoZW4oKG0pID0+IHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnQgPSBnZXREb2N1bWVudCgpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEN1c3RvbUNvbnRyb2wgPSBtWydDdXN0b21Db250cm9sJ107XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUZXN0Q29tcG9uZW50ID0gY2xhc3MgZXh0ZW5kcyBDdXN0b21Db250cm9sIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGljIGdldFRhZygpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm1vbnN0ZXItY3VzdG9tY29udHJvbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnaXN0ZXJDdXN0b21FbGVtZW50KFRlc3RDb21wb25lbnQpXG5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbmUoZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cblxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuXG4gICAgICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgICAgICAgbGV0IG1vY2tzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vY2tzJyk7XG4gICAgICAgICAgICBtb2Nrcy5pbm5lckhUTUwgPSBodG1sMTtcbiAgICAgICAgfSlcblxuICAgICAgICBhZnRlckVhY2goKCkgPT4ge1xuICAgICAgICAgICAgbGV0IG1vY2tzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vY2tzJyk7XG4gICAgICAgICAgICBtb2Nrcy5pbm5lckhUTUwgPSBcIlwiO1xuICAgICAgICB9KVxuXG4gICAgICAgIGRlc2NyaWJlKCdjcmVhdGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBjdXN0b20tZWxlbWVudCBvYmplY3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbGV0IGQgPSBuZXcgVGVzdENvbXBvbmVudCgpO1xuICAgICAgICAgICAgICAgIGV4cGVjdCh0eXBlb2YgZCkuaXMuZXF1YWwoJ29iamVjdCcpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGRlc2NyaWJlKCdjb25uZWN0IGVtcHR5IGVsZW1lbnQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpdCgnZG9jdW1lbnQgc2hvdWxkIGNvbnRhaW4gbW9uc3Rlci1jdXN0b21jb250cm9sJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIGxldCBkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbW9uc3Rlci1jdXN0b21jb250cm9sJyk7XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Rlc3QxJykuYXBwZW5kQ2hpbGQoZCk7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdtb25zdGVyLWN1c3RvbWNvbnRyb2wnKS5sZW5ndGgpLmlzLmVxdWFsKDEpO1xuICAgICAgICAgICAgICAgIC8vIG5vIGRhdGEtbW9uc3Rlci1vYmplY3RsaW5rPVwiU3ltYm9sKG1vbnN0ZXJVcGRhdGVyKVwiIGJlY2F1c2UgaXQgaGFzIG5vdGhpbmcgdG8gdXBkYXRlXG4gICAgICAgICAgICAgICAgZXhwZWN0KGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0ZXN0MScpKS5jb250YWluLmh0bWwoJzxtb25zdGVyLWN1c3RvbWNvbnRyb2w+PC9tb25zdGVyLWN1c3RvbWNvbnRyb2w+Jyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZGVzY3JpYmUoJ09wdGlvbnMgY2hhbmdlJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBpdCgnZGVsZWdhdGVzRm9jdXMgc2hvdWxkIGNoYW5nZSBmcm9tIHRydWUgdG8gZmFsc2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbGV0IGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdtb25zdGVyLWN1c3RvbWNvbnRyb2wnKVxuXG4gICAgICAgICAgICAgICAgZXhwZWN0KGVsZW1lbnQuZ2V0T3B0aW9uKCdkZWxlZ2F0ZXNGb2N1cycpKS50by5iZS50cnVlO1xuICAgICAgICAgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKEFUVFJJQlVURV9PUFRJT05TLCBKU09OLnN0cmluZ2lmeSh7ZGVsZWdhdGVzRm9jdXM6IGZhbHNlfSkpO1xuICAgICAgICAgICAgICAgIGV4cGVjdChlbGVtZW50LmdldE9wdGlvbignZGVsZWdhdGVzRm9jdXMnKSkudG8uYmUuZmFsc2U7XG5cbiAgICAgICAgICAgIH0pXG5cblxuICAgICAgICB9KVxuXG4gICAgICAgIGRlc2NyaWJlKCdUZXN0IEVsZW1lbnRJbnRlcm5hbHMnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIGxldCBmb3JtO1xuXG4gICAgICAgICAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAgICAgICAgICBmb3JtID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZm9ybScpO1xuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgaXQoJ2Zvcm1Bc3NvY2lhdGVkJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICAgICAgbGV0IGQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdtb25zdGVyLWN1c3RvbWNvbnRyb2wnKTtcbiAgICAgICAgICAgICAgICBmb3JtLmFwcGVuZENoaWxkKGQpO1xuXG4gICAgICAgICAgICAgICAgZXhwZWN0KGQuY29uc3RydWN0b3IuZm9ybUFzc29jaWF0ZWQpLnRvLmJlLnRydWU7XG5cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaXQoJ2Zvcm0nLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ21vbnN0ZXItY3VzdG9tY29udHJvbCcpO1xuICAgICAgICAgICAgICAgIGZvcm0uYXBwZW5kQ2hpbGQoZCk7XG5cbiAgICAgICAgICAgICAgICBpZiAoanNkb21GbGFnKSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdCgoKSA9PiBkLmZvcm0pLnRvLnRocm93KEVycm9yKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QoZC5mb3JtKS50by5iZS5pbnN0YW5jZW9mKEhUTUxGb3JtRWxlbWVudClcbiAgICAgICAgICAgICAgICB9XG5cblxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGl0KCd2YWx1ZSBnZXR0ZXInLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ21vbnN0ZXItY3VzdG9tY29udHJvbCcpO1xuICAgICAgICAgICAgICAgIGZvcm0uYXBwZW5kQ2hpbGQoZCk7XG5cbiAgICAgICAgICAgICAgICBleHBlY3QoKCkgPT4gZC52YWx1ZSkudG8udGhyb3coRXJyb3IpO1xuXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaXQoJ3ZhbHVlIHNldHRlcicsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgIGxldCBkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbW9uc3Rlci1jdXN0b21jb250cm9sJyk7XG4gICAgICAgICAgICAgICAgZm9ybS5hcHBlbmRDaGlsZChkKTtcblxuICAgICAgICAgICAgICAgIGV4cGVjdCgoKSA9PiBkLnZhbHVlID0gNCkudG8udGhyb3coRXJyb3IpO1xuXG4gICAgICAgICAgICB9KTtcblxuXG4gICAgICAgICAgICBpdCgnc2V0Rm9ybVZhbHVlJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICAgICAgbGV0IGQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdtb25zdGVyLWN1c3RvbWNvbnRyb2wnKTtcbiAgICAgICAgICAgICAgICBmb3JtLmFwcGVuZENoaWxkKGQpO1xuXG4gICAgICAgICAgICAgICAgaWYgKGpzZG9tRmxhZykge1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QoKCkgPT4gZC5zZXRGb3JtVmFsdWUoKSkudG8udGhyb3coRXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIH0pO1xuXG5cbiAgICAgICAgICAgIGl0KCduYW1lIGdldHRlcicsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgIGxldCBkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbW9uc3Rlci1jdXN0b21jb250cm9sJyk7XG4gICAgICAgICAgICAgICAgZm9ybS5hcHBlbmRDaGlsZChkKTtcblxuICAgICAgICAgICAgICAgIGV4cGVjdChkLm5hbWUpLnRvLmJlLm51bGw7XG5cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpdCgndHlwZSBnZXR0ZXInLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ21vbnN0ZXItY3VzdG9tY29udHJvbCcpO1xuICAgICAgICAgICAgICAgIGZvcm0uYXBwZW5kQ2hpbGQoZCk7XG5cbiAgICAgICAgICAgICAgICBleHBlY3QoZC50eXBlKS50by5iZS5lcXVhbCgnbW9uc3Rlci1jdXN0b21jb250cm9sJyk7XG5cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpdCgndmFsaWRpdHkgZ2V0dGVyJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICAgICAgbGV0IGQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdtb25zdGVyLWN1c3RvbWNvbnRyb2wnKTtcbiAgICAgICAgICAgICAgICBmb3JtLmFwcGVuZENoaWxkKGQpO1xuICAgICAgICAgICAgICAgIGlmIChqc2RvbUZsYWcpIHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KCgpID0+IGQudmFsaWRpdHkpLnRvLnRocm93KEVycm9yKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaXQoJ3ZhbGlkYXRpb25NZXNzYWdlIGdldHRlcicsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgIGxldCBkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbW9uc3Rlci1jdXN0b21jb250cm9sJyk7XG4gICAgICAgICAgICAgICAgZm9ybS5hcHBlbmRDaGlsZChkKTtcblxuICAgICAgICAgICAgICAgIGlmIChqc2RvbUZsYWcpIHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KCgpID0+IGQudmFsaWRpdHkpLnRvLnRocm93KEVycm9yKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaXQoJ3dpbGxWYWxpZGF0ZSBnZXR0ZXInLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ21vbnN0ZXItY3VzdG9tY29udHJvbCcpO1xuICAgICAgICAgICAgICAgIGZvcm0uYXBwZW5kQ2hpbGQoZCk7XG5cbiAgICAgICAgICAgICAgICBpZiAoanNkb21GbGFnKSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdCgoKSA9PiBkLndpbGxWYWxpZGF0ZSkudG8udGhyb3coRXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaXQoJ2NoZWNrVmFsaWRpdHkoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgIGxldCBkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbW9uc3Rlci1jdXN0b21jb250cm9sJyk7XG4gICAgICAgICAgICAgICAgZm9ybS5hcHBlbmRDaGlsZChkKTtcblxuICAgICAgICAgICAgICAgIGlmIChqc2RvbUZsYWcpIHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KCgpID0+IGQuY2hlY2tWYWxpZGl0eSgpKS50by50aHJvdyhFcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGl0KCdyZXBvcnRWYWxpZGl0eSgpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICAgICAgbGV0IGQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdtb25zdGVyLWN1c3RvbWNvbnRyb2wnKTtcbiAgICAgICAgICAgICAgICBmb3JtLmFwcGVuZENoaWxkKGQpO1xuXG4gICAgICAgICAgICAgICAgaWYgKGpzZG9tRmxhZykge1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QoKCkgPT4gZC5yZXBvcnRWYWxpZGl0eSgpKS50by50aHJvdyhFcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgfSk7XG5cblxuICAgICAgICAgICAgaXQoJ3NldFZhbGlkaXR5KCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ21vbnN0ZXItY3VzdG9tY29udHJvbCcpO1xuICAgICAgICAgICAgICAgIGZvcm0uYXBwZW5kQ2hpbGQoZCk7XG4gICAgICAgICAgICAgICAgaWYgKGpzZG9tRmxhZykge1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QoKCkgPT4gZC5zZXRWYWxpZGl0eSgpKS50by50aHJvdyhFcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KGQuc2V0VmFsaWRpdHkoeyd2YWx1ZU1pc3NpbmcnOiB0cnVlfSwgXCJteSBtZXNzYWdlXCIpKS50by5iZS51bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB9KTtcblxuXG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG59KTtcblxuXG4iLCAiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuXG5pbXBvcnQge0xvY2FsZX0gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9pMThuL2xvY2FsZS5tanNcIjtcbmltcG9ydCB7Z2V0TG9jYWxlT2ZEb2N1bWVudH0gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9kb20vbG9jYWxlLm1qc1wiO1xuaW1wb3J0IHtpbml0SlNET019IGZyb20gXCIuLi8uLi91dGlsL2pzZG9tLm1qc1wiO1xuXG5kZXNjcmliZSgnQXR0cmlidXRlcycsIGZ1bmN0aW9uICgpIHtcbiAgICBiZWZvcmUoZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgaW5pdEpTRE9NKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICBkb25lKClcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnZ2V0TG9jYWxlT2ZEb2N1bWVudCcsIGZ1bmN0aW9uICgpIHtcblxuXG4gICAgICAgIFtcbiAgICAgICAgICAgIFtcImRlXCJdLFxuICAgICAgICAgICAgW1wic2wtSVQtbmVkaXNcIl0sXG4gICAgICAgICAgICBbXCJlbi1HQlwiXSxcblxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcblxuXG4gICAgICAgICAgICBpdCgncmV0dXJuIGxhbmd1YWdlICcgKyBhLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbGV0IGh0bWwgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaHRtbCcpO1xuICAgICAgICAgICAgICAgIGxldCBub2RlID0gaHRtbC5pdGVtKDApO1xuXG4gICAgICAgICAgICAgICAgbm9kZS5zZXRBdHRyaWJ1dGUoJ2xhbmcnLCBhKTtcbiAgICAgICAgICAgICAgICBleHBlY3QoZ2V0TG9jYWxlT2ZEb2N1bWVudCgpLnRvU3RyaW5nKCkpLnRvLmJlLmVxdWFsKGEpO1xuICAgICAgICAgICAgfSlcblxuXG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxuXG4gICAgaXQoJ3JldHVybiBsYW5ndWFnZSBlbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbGV0IGh0bWwgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaHRtbCcpO1xuICAgICAgICBsZXQgbm9kZSA9IGh0bWwuaXRlbSgwKTtcbiAgICAgICAgbGV0IGxhbmc9IG5vZGUuZ2V0QXR0cmlidXRlKCdsYW5nJyk7XG5cbiAgICAgICAgbm9kZS5yZW1vdmVBdHRyaWJ1dGUoJ2xhbmcnKTtcbiAgICAgICAgY29uc3QgbG9jYWxlID0gZ2V0TG9jYWxlT2ZEb2N1bWVudCgpO1xuICAgICAgICBleHBlY3QobG9jYWxlKS50by5iZS5pbnN0YW5jZU9mKExvY2FsZSk7XG4gICAgICAgIGV4cGVjdChsb2NhbGUubG9jYWxlU3RyaW5nKS50by5iZS5lcXVhbChuYXZpZ2F0b3IubGFuZ3VhZ2UpO1xuXG4gICAgICAgIG5vZGUuc2V0QXR0cmlidXRlKCdsYW5nJywgbGFuZyk7XG4gICAgICAgIFxuICAgIH0pXG5cblxufSkiLCAiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQge2dldERvY3VtZW50RnJhZ21lbnRGcm9tU3RyaW5nfSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2RvbS91dGlsLm1qc1wiO1xuaW1wb3J0IHtpbml0SlNET019IGZyb20gXCIuLi8uLi91dGlsL2pzZG9tLm1qc1wiO1xuaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7VGhlbWUsIGdldERvY3VtZW50VGhlbWV9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvZG9tL3RoZW1lLm1qc1wiO1xuXG5kZXNjcmliZSgnVGhlbWUnLCBmdW5jdGlvbiAoKSB7XG4gICAgYmVmb3JlKGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgIGluaXRKU0RPTSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgZG9uZSgpXG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ25ldyBUaGVtZSgpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBUaGVtZSBvYmplY3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IFRoZW1lKCdteS10aGVtZScpKS5pcy5hLmluc3RhbmNlT2YoVGhlbWUpO1xuICAgICAgICB9KTtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gVGhlbWUtTmFtZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgVGhlbWUoJ215LXRoZW1lJykuZ2V0TmFtZSgpKS5pcy5lcXVhbCgnbXktdGhlbWUnKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGl0KCdzaG91bGQgdGhyb3cgRXJyb3IgYmVjYXVzZSBlbXB0eSBhcmd1bWVudCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdCgoKSA9PiBuZXcgVGhlbWUoKSkudG8udGhyb3coVHlwZUVycm9yKVxuICAgICAgICB9KTtcbiAgICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBFcnJvciBiZWNhdXNlIG5vIHN0cmluZyBhcmd1bWVudCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdCgoKSA9PiBuZXcgVGhlbWUoMikpLnRvLnRocm93KFR5cGVFcnJvcilcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnZ2V0RG9jdW1lbnRUaGVtZSgpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBUaGVtZSBvYmplY3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QoZ2V0RG9jdW1lbnRUaGVtZSgpKS5pcy5hLmluc3RhbmNlT2YoVGhlbWUpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBEZWZhdWx0IFRoZW1lIG5hbWUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QoZ2V0RG9jdW1lbnRUaGVtZSgpLmdldE5hbWUoKSkuaXMuZXF1YWwoJ21vbnN0ZXInKTtcbiAgICAgICAgfSk7XG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdnZXREb2N1bWVudFRoZW1lKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdodG1sJykuc2V0QXR0cmlidXRlKCdkYXRhLW1vbnN0ZXItdGhlbWUtbmFtZScsICd0ZXN0dGhlbWUnKTtcbiAgICAgICAgfSlcblxuICAgICAgICBhZnRlckVhY2goKCkgPT4ge1xuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignaHRtbCcpLnJlbW92ZUF0dHJpYnV0ZSgnZGF0YS1tb25zdGVyLXRoZW1lLW5hbWUnKTtcbiAgICAgICAgfSlcblxuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiB0ZXN0dGhlbWUgVGhlbWUgbmFtZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChnZXREb2N1bWVudFRoZW1lKCkuZ2V0TmFtZSgpKS5pcy5lcXVhbCgndGVzdHRoZW1lJyk7XG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG59KTtcblxuXG4iLCAiJ3VzZSBzdHJpY3QnO1xuXG5cbmltcG9ydCB7aW5pdEpTRE9NfSBmcm9tIFwiLi4vLi4vdXRpbC9qc2RvbS5tanNcIjtcbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5sZXQgUmVzb3VyY2UsRGVyaXZlZFJlc291cmNlO1xuXG5cblxuZGVzY3JpYmUoJ1Jlc291cmNlJywgZnVuY3Rpb24oKSB7XG5cbiAgICBiZWZvcmUoZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgaW5pdEpTRE9NKCkudGhlbigoKSA9PiB7XG5cbiAgICAgICAgICAgIGltcG9ydChcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9kb20vcmVzb3VyY2UubWpzXCIpLnRoZW4oKG0pID0+IHtcbiAgICAgICAgICAgICAgICBSZXNvdXJjZSA9IG1bJ1Jlc291cmNlJ107XG5cblxuICAgICAgICAgICAgICAgIERlcml2ZWRSZXNvdXJjZSA9IGNsYXNzICBleHRlbmRzIFJlc291cmNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdXBlcih7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJkYXRhLXVybFwiOiBcImh0dHA6Ly9leGFtcGxlLmNvbVwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBzdGF0aWMgZ2V0VVJMQXR0cmlidXRlKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICdkYXRhLXVybCc7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9ICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgfSk7XG5cblxuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnRGVyaXZlZFJlc291cmNlJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdzaG91bGQgaW5zdGFuY2VvZiBSZXNvdXJjZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgRGVyaXZlZFJlc291cmNlKCkpLnRvLmJlLmFuLmluc3RhbmNlb2YoUmVzb3VyY2UpO1xuICAgICAgICB9KTtcblxuICAgIH0pO1xuXG5cbn0pOyIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGV4dGVuZCB9IGZyb20gXCIuLi9kYXRhL2V4dGVuZC5tanNcIjtcbmltcG9ydCB7IEJhc2UgfSBmcm9tIFwiLi4vdHlwZXMvYmFzZS5tanNcIjtcbmltcG9ydCB7IGdldEdsb2JhbE9iamVjdCB9IGZyb20gXCIuLi90eXBlcy9nbG9iYWwubWpzXCI7XG5pbXBvcnQgeyBlcXVpcFdpdGhJbnRlcm5hbCB9IGZyb20gXCIuLi90eXBlcy9pbnRlcm5hbC5tanNcIjtcbmltcG9ydCB7IGlzQXJyYXkgfSBmcm9tIFwiLi4vdHlwZXMvaXMubWpzXCI7XG5pbXBvcnQgeyBBVFRSSUJVVEVfSFJFRiwgQVRUUklCVVRFX1NSQyB9IGZyb20gXCIuL2NvbnN0YW50cy5tanNcIjtcbmltcG9ydCB7IFJlc291cmNlIH0gZnJvbSBcIi4vcmVzb3VyY2UubWpzXCI7XG5pbXBvcnQgeyBEYXRhIH0gZnJvbSBcIi4vcmVzb3VyY2UvZGF0YS5tanNcIjtcbmltcG9ydCB7IFN0eWxlc2hlZXQgfSBmcm9tIFwiLi9yZXNvdXJjZS9saW5rL3N0eWxlc2hlZXQubWpzXCI7XG5pbXBvcnQgeyBTY3JpcHQgfSBmcm9tIFwiLi9yZXNvdXJjZS9zY3JpcHQubWpzXCI7XG5cbmV4cG9ydCB7IFJlc291cmNlTWFuYWdlciB9O1xuXG4vKipcbiAqIFRoZSBSZXNvdXJjZU1hbmFnZXIgaXMgYSBzaW5nbGV0b24gdGhhdCBtYW5hZ2VzIGFsbCByZXNvdXJjZXMuXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNS4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAc3VtbWFyeSBBIFJlc291cmNlIGNsYXNzXG4gKi9cbmNsYXNzIFJlc291cmNlTWFuYWdlciBleHRlbmRzIEJhc2Uge1xuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAgICAgKiB0aHJvdyB7RXJyb3J9IHVuc3VwcG9ydGVkIGRvY3VtZW50IHR5cGVcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgICAgICBlcXVpcFdpdGhJbnRlcm5hbC5jYWxsKHRoaXMpO1xuXG4gICAgICAgIGlmICghKHRoaXMuZ2V0T3B0aW9uKFwiZG9jdW1lbnRcIikgaW5zdGFuY2VvZiBEb2N1bWVudCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInVuc3VwcG9ydGVkIGRvY3VtZW50IHR5cGVcIik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAZGVwcmVjYXRlZCBzaW5jZSAzLjE1LjAgdXNlIGdldEludGVybmFsIGluc3RlYWRcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gYmFzZXVybFxuICAgICAqL1xuICAgIGdldE9wdGlvbihrZXkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0SW50ZXJuYWwoa2V5KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gYmFzZXVybFxuICAgICAqL1xuICAgIGdldEJhc2VVUkwoKSB7XG4gICAgICAgIHRoaXMuZ2V0T3B0aW9uKFwiZG9jdW1lbnRcIik/LmJhc2VVUkw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd9IGJhc2V1cmxcbiAgICAgKiBAZGVwcmVjYXRlZCBzaW5jZSAzLjE1LjAgdXNlIGludGVybmFsRGVmYXVsdHMgaW5zdGVhZFxuICAgICAqL1xuICAgIGdldCBkZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaW50ZXJuYWxEZWZhdWx0cztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwcm9wZXJ0eSB7SFRNTERvY3VtZW50fSBkb2N1bWVudD1kb2N1bWVudCBEb2N1bWVudFxuICAgICAqIEBwcm9wZXJ0eSB7T2JqZWN0fSByZXNvdXJjZXNcbiAgICAgKiBAcHJvcGVydHkge0FycmF5fSByZXNvdXJjZXMuc2NyaXB0cz1bXSBhcnJheSB3aXRoIHtAbGluayBNb25zdGVyLkRPTS5SZXNvdXJjZS5TY3JpcHR9IG9iamVjdHNcbiAgICAgKiBAcHJvcGVydHkge0FycmF5fSByZXNvdXJjZXMuc3R5bGVzaGVldHM9W10gYXJyYXkgd2l0aCB7QGxpbmsgTW9uc3Rlci5ET00uUmVzb3VyY2UuTGluay5TdHlsZXNoZWV0fSBvYmplY3RzXG4gICAgICogQHByb3BlcnR5IHtBcnJheX0gcmVzb3VyY2VzLmRhdGE9W10gYXJyYXkgd2l0aCB7QGxpbmsgTW9uc3Rlci5ET00uUmVzb3VyY2UuRGF0YX0gb2JqZWN0c1xuICAgICAqL1xuICAgIGdldCBpbnRlcm5hbERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihcbiAgICAgICAgICAgIHt9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGRvY3VtZW50OiBnZXRHbG9iYWxPYmplY3QoXCJkb2N1bWVudFwiKSxcbiAgICAgICAgICAgICAgICByZXNvdXJjZXM6IHtcbiAgICAgICAgICAgICAgICAgICAgc2NyaXB0czogW10sXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlc2hlZXRzOiBbXSxcbiAgICAgICAgICAgICAgICAgICAgZGF0YTogW10sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQXBwZW5kIFRhZ3MgdG8gRE9NXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtNb25zdGVyLkRPTS5SZXNvdXJjZU1hbmFnZXJ9XG4gICAgICogQHRocm93cyB7RXJyb3J9IHVuc3VwcG9ydGVkIHJlc291cmNlIGRlZmluaXRpb25cbiAgICAgKi9cbiAgICBjb25uZWN0KCkge1xuICAgICAgICBydW5SZXNvdXJjZU1ldGhvZC5jYWxsKHRoaXMsIFwiY29ubmVjdFwiKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2sgaWYgYXZhaWxhYmxlXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSB1bnN1cHBvcnRlZCByZXNvdXJjZSBkZWZpbml0aW9uXG4gICAgICovXG4gICAgYXZhaWxhYmxlKCkge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocnVuUmVzb3VyY2VNZXRob2QuY2FsbCh0aGlzLCBcImF2YWlsYWJsZVwiKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkIGEgc2NyaXB0XG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xVUkx9IHVybFxuICAgICAqIEBwYXJhbSBbT2JqZWN0fHVuZGVmaW5lZH0gb3B0aW9uc1xuICAgICAqIEByZXR1cm4ge01vbnN0ZXIuRE9NLlJlc291cmNlTWFuYWdlcn1cbiAgICAgKiBAc2VlIE1vbnN0ZXIuRE9NLlJlc291cmNlLlNjcmlwdFxuICAgICAqL1xuICAgIGFkZFNjcmlwdCh1cmwsIG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIGFkZFJlc291cmNlLmNhbGwodGhpcywgXCJzY3JpcHRzXCIsIHVybCwgb3B0aW9ucyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkIFN0eWxlc2hlZXRcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfFVSTH0gdXJsXG4gICAgICogQHBhcmFtIFtPYmplY3R8dW5kZWZpbmVkfSBvcHRpb25zXG4gICAgICogQHJldHVybiB7TW9uc3Rlci5ET00uUmVzb3VyY2VNYW5hZ2VyfVxuICAgICAqIEBzZWUgTW9uc3Rlci5ET00uUmVzb3VyY2UuTGluay5TdHlsZXNoZWV0XG4gICAgICovXG4gICAgYWRkU3R5bGVzaGVldCh1cmwsIG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIGFkZFJlc291cmNlLmNhbGwodGhpcywgXCJzdHlsZXNoZWV0c1wiLCB1cmwsIG9wdGlvbnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZCBEYXRhIFRhZ1xuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd8VVJMfSB1cmxcbiAgICAgKiBAcGFyYW0gW09iamVjdHx1bmRlZmluZWR9IG9wdGlvbnNcbiAgICAgKiBAcmV0dXJuIHtNb25zdGVyLkRPTS5SZXNvdXJjZU1hbmFnZXJ9XG4gICAgICogQHNlZSBNb25zdGVyLkRPTS5SZXNvdXJjZS5EYXRhXG4gICAgICovXG4gICAgYWRkRGF0YSh1cmwsIG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIGFkZFJlc291cmNlLmNhbGwodGhpcywgXCJkYXRhXCIsIHVybCwgb3B0aW9ucyk7XG4gICAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge3N0cmluZ30gbWV0aG9kXG4gKiBAcmV0dXJuIHtBcnJheX1cbiAqL1xuZnVuY3Rpb24gcnVuUmVzb3VyY2VNZXRob2QobWV0aG9kKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICBjb25zdCByZXN1bHQgPSBbXTtcblxuICAgIGZvciAoY29uc3QgdHlwZSBvZiBbXCJzY3JpcHRzXCIsIFwic3R5bGVzaGVldHNcIiwgXCJkYXRhXCJdKSB7XG4gICAgICAgIGNvbnN0IHJlc291cmNlcyA9IHNlbGYuZ2V0T3B0aW9uKGByZXNvdXJjZXMuJHt0eXBlfWApO1xuICAgICAgICBpZiAoIWlzQXJyYXkocmVzb3VyY2VzKSkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGNvbnN0IHJlc291cmNlIG9mIHJlc291cmNlcykge1xuICAgICAgICAgICAgaWYgKCEocmVzb3VyY2UgaW5zdGFuY2VvZiBSZXNvdXJjZSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1bnN1cHBvcnRlZCByZXNvdXJjZSBkZWZpbml0aW9uXCIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXN1bHQucHVzaChyZXNvdXJjZVttZXRob2RdKCkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHR5cGVcbiAqIEBwYXJhbSB7c3RyaW5nfFVSTH0gdXJsXG4gKiBAcGFyYW0gW09iamVjdHx1bmRlZmluZWR9IG9wdGlvbnNcbiAqIEByZXR1cm4ge01vbnN0ZXIuRE9NLlJlc291cmNlTWFuYWdlcn1cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGFkZFJlc291cmNlKHR5cGUsIHVybCwgb3B0aW9ucykge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgaWYgKHVybCBpbnN0YW5jZW9mIFVSTCkge1xuICAgICAgICB1cmwgPSB1cmwudG9TdHJpbmcoKTtcbiAgICB9XG5cbiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICAgIGxldCByZXNvdXJjZTtcbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgY2FzZSBcInNjcmlwdHNcIjpcbiAgICAgICAgICAgIHJlc291cmNlID0gbmV3IFNjcmlwdChleHRlbmQoe30sIG9wdGlvbnMsIHsgW0FUVFJJQlVURV9TUkNdOiB1cmwgfSkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJzdHlsZXNoZWV0c1wiOlxuICAgICAgICAgICAgcmVzb3VyY2UgPSBuZXcgU3R5bGVzaGVldChleHRlbmQoe30sIG9wdGlvbnMsIHsgW0FUVFJJQlVURV9IUkVGXTogdXJsIH0pKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwiZGF0YVwiOlxuICAgICAgICAgICAgcmVzb3VyY2UgPSBuZXcgRGF0YShleHRlbmQoe30sIG9wdGlvbnMsIHsgW0FUVFJJQlVURV9TUkNdOiB1cmwgfSkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuc3VwcG9ydGVkIHR5cGUgJHt0eXBlfWApO1xuICAgIH1cblxuICAgIHNlbGYuZ2V0T3B0aW9uKFwicmVzb3VyY2VzXCIpPy5bdHlwZV0ucHVzaChyZXNvdXJjZSk7XG4gICAgcmV0dXJuIHNlbGY7XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuaW1wb3J0IHsgaW50ZXJuYWxTeW1ib2wgfSBmcm9tIFwiLi4vY29uc3RhbnRzLm1qc1wiO1xuaW1wb3J0IHsgZXh0ZW5kIH0gZnJvbSBcIi4uL2RhdGEvZXh0ZW5kLm1qc1wiO1xuaW1wb3J0IHsgUGF0aGZpbmRlciB9IGZyb20gXCIuLi9kYXRhL3BhdGhmaW5kZXIubWpzXCI7XG5pbXBvcnQgeyBwYXJzZURhdGFVUkwgfSBmcm9tIFwiLi9kYXRhdXJsLm1qc1wiO1xuaW1wb3J0IHsgaXNTdHJpbmcgfSBmcm9tIFwiLi9pcy5tanNcIjtcbmltcG9ydCB7IE9ic2VydmVyIH0gZnJvbSBcIi4vb2JzZXJ2ZXIubWpzXCI7XG5pbXBvcnQgeyBQcm94eU9ic2VydmVyIH0gZnJvbSBcIi4vcHJveHlvYnNlcnZlci5tanNcIjtcbmltcG9ydCB7IHZhbGlkYXRlT2JqZWN0IH0gZnJvbSBcIi4vdmFsaWRhdGUubWpzXCI7XG5pbXBvcnQgeyBpc09iamVjdCB9IGZyb20gXCIuL2lzLm1qc1wiO1xuXG5leHBvcnQgeyBlcXVpcFdpdGhJbnRlcm5hbCB9O1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAdHlwZSB7c3RyaW5nfVxuICovXG5jb25zdCBwcm9wZXJ0eU5hbWUgPSBcImludGVybmFsRGVmYXVsdHNcIjtcblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGV4dGVuZHMgdGhlIGdpdmVuIG9iamVjdCB3aXRoIHRoZSBmb2xsb3dpbmcgbWV0aG9kczpcbiAqXG4gKiAtIGF0dGFjaEludGVybmFsT2JzZXJ2ZXJcbiAqIC0gZGV0YWNoSW50ZXJuYWxPYnNlcnZlclxuICogLSBjb250YWluc0ludGVybmFsT2JzZXJ2ZXJcbiAqIC0gc2V0SW50ZXJuYWxcbiAqIC0gc2V0SW50ZXJuYWxzXG4gKiAtIGdldEludGVybmFsXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMy4xNS4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcbiAqL1xuZnVuY3Rpb24gZXF1aXBXaXRoSW50ZXJuYWwoKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgdmFsaWRhdGVPYmplY3Qoc2VsZik7XG5cbiAgICBpZiAoIWhhc0dldHRlcihzZWxmLCBwcm9wZXJ0eU5hbWUpKSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShzZWxmLCBwcm9wZXJ0eU5hbWUsIHtcbiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB7fTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IGRlZmF1bHRzID0gZXh0ZW5kKHt9LCBzZWxmW3Byb3BlcnR5TmFtZV0gfHwge30pO1xuICAgIHNlbGZbaW50ZXJuYWxTeW1ib2xdID0gbmV3IFByb3h5T2JzZXJ2ZXIoZGVmYXVsdHMpO1xuXG4gICAgLyoqXG4gICAgICogQXR0YWNoIGEgbmV3IG9ic2VydmVyXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge09ic2VydmVyfSBvYnNlcnZlclxuICAgICAqIEByZXR1cm5zIHtQcm94eU9ic2VydmVyfVxuICAgICAqL1xuICAgIHNlbGZbXCJhdHRhY2hJbnRlcm5hbE9ic2VydmVyXCJdID0gKG9ic2VydmVyKSA9PiB7XG4gICAgICAgIHNlbGZbaW50ZXJuYWxTeW1ib2xdLmF0dGFjaE9ic2VydmVyKG9ic2VydmVyKTtcbiAgICAgICAgcmV0dXJuIHNlbGY7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIERldGFjaCBhIG9ic2VydmVyXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge09ic2VydmVyfSBvYnNlcnZlclxuICAgICAqIEByZXR1cm5zIHtQcm94eU9ic2VydmVyfVxuICAgICAqL1xuICAgIHNlbGZbXCJkZXRhY2hJbnRlcm5hbE9ic2VydmVyXCJdID0gKG9ic2VydmVyKSA9PiB7XG4gICAgICAgIHNlbGZbaW50ZXJuYWxTeW1ib2xdLmRldGFjaE9ic2VydmVyKG9ic2VydmVyKTtcbiAgICAgICAgcmV0dXJuIHNlbGY7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENoZWNrIGlmIGEgb2JzZXJ2ZXIgaXMgYXR0YWNoZWRcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7T2JzZXJ2ZXJ9IG9ic2VydmVyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAgICovXG4gICAgc2VsZltcImNvbnRhaW5zSW50ZXJuYWxPYnNlcnZlclwiXSA9IChvYnNlcnZlcikgPT4ge1xuICAgICAgICByZXR1cm4gc2VsZltpbnRlcm5hbFN5bWJvbF0uY29udGFpbnNPYnNlcnZlcihvYnNlcnZlcik7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFNldCBhbiBpbnRlcm5hbCB2YWx1ZSwgbmVzdGVkIGludGVybmFscyBjYW4gYmUgc3BlY2lmaWVkIGJ5IHBhdGggYGEuYi5jYFxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHBhdGhcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlXG4gICAgICogQHJldHVybiB7RGF0YXNvdXJjZX1cbiAgICAgKi9cbiAgICBzZWxmW1wic2V0SW50ZXJuYWxcIl0gPSAocGF0aCwgdmFsdWUpID0+IHtcbiAgICAgICAgbmV3IFBhdGhmaW5kZXIoc2VsZltpbnRlcm5hbFN5bWJvbF0uZ2V0U3ViamVjdCgpKS5zZXRWaWEocGF0aCwgdmFsdWUpO1xuICAgICAgICByZXR1cm4gc2VsZjtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogc2V0IG11bHRpcGxlIGludGVybmFscyBhdCBvbmNlXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xvYmplY3R9IG9wdGlvbnNcbiAgICAgKiBAcmV0dXJuIHtEYXRhc291cmNlfVxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSB0aGUgb3B0aW9ucyBkb2VzIG5vdCBjb250YWluIGEgdmFsaWQganNvbiBkZWZpbml0aW9uXG4gICAgICovXG4gICAgc2VsZltcInNldEludGVybmFsc1wiXSA9IChvcHRpb25zKSA9PiB7XG4gICAgICAgIGlmIChpc1N0cmluZyhvcHRpb25zKSkge1xuICAgICAgICAgICAgb3B0aW9ucyA9IHBhcnNlT3B0aW9uc0pTT04ob3B0aW9ucyk7XG4gICAgICAgIH1cblxuICAgICAgICBleHRlbmQoc2VsZltpbnRlcm5hbFN5bWJvbF0uZ2V0U3ViamVjdCgpLCBkZWZhdWx0cywgb3B0aW9ucyk7XG4gICAgICAgIHJldHVybiBzZWxmO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBuZXN0ZWQgaW50ZXJuYWxzIGNhbiBiZSBzcGVjaWZpZWQgYnkgcGF0aCBgYS5iLmNgXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcGF0aFxuICAgICAqIEBwYXJhbSB7Kn0gZGVmYXVsdFZhbHVlXG4gICAgICogQHJldHVybiB7Kn1cbiAgICAgKi9cbiAgICBzZWxmW1wiZ2V0SW50ZXJuYWxcIl0gPSAocGF0aCwgZGVmYXVsdFZhbHVlKSA9PiB7XG4gICAgICAgIGxldCB2YWx1ZTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdmFsdWUgPSBuZXcgUGF0aGZpbmRlcihzZWxmW2ludGVybmFsU3ltYm9sXS5nZXRSZWFsU3ViamVjdCgpKS5nZXRWaWEocGF0aCk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHt9XG5cbiAgICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHJldHVybiBkZWZhdWx0VmFsdWU7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9O1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0gb2JqXG4gKiBAcGFyYW0gcHJvcFxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gaGFzR2V0dGVyKG9iaiwgcHJvcCkge1xuICAgIHdoaWxlIChpc09iamVjdChvYmopKSB7XG4gICAgICAgIGlmIChPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iaiwgcHJvcCk/LltcImdldFwiXSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgb2JqID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKG9iaik7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0gZGF0YVxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBwYXJzZU9wdGlvbnNKU09OKGRhdGEpIHtcbiAgICBsZXQgb2JqID0ge307XG5cbiAgICBpZiAoIWlzU3RyaW5nKGRhdGEpKSB7XG4gICAgICAgIHJldHVybiBvYmo7XG4gICAgfVxuXG4gICAgLy8gdGhlIGNvbmZpZ3VyYXRpb24gY2FuIGJlIHNwZWNpZmllZCBhcyBhIGRhdGEgdXJsLlxuICAgIHRyeSB7XG4gICAgICAgIGxldCBkYXRhVXJsID0gcGFyc2VEYXRhVVJMKGRhdGEpO1xuICAgICAgICBkYXRhID0gZGF0YVVybC5jb250ZW50O1xuICAgIH0gY2F0Y2ggKGUpIHt9XG5cbiAgICB0cnkge1xuICAgICAgICBvYmogPSBKU09OLnBhcnNlKGRhdGEpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgdGhyb3cgZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsaWRhdGVPYmplY3Qob2JqKTtcbn1cbiIsICIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5cbmltcG9ydCB7UmVzb3VyY2VNYW5hZ2VyfSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2RvbS9yZXNvdXJjZW1hbmFnZXIubWpzXCI7XG5pbXBvcnQge2NsZWFudXBET01Gcm9tVGVzdGluZywgaW5pdE11dGF0aW9uT2JzZXJ2ZXJGb3JUZXN0aW5nfSBmcm9tIFwiLi4vLi4vdXRpbC9jbGVhbnVwZG9tLm1qc1wiO1xuaW1wb3J0IHtpbml0SlNET019IGZyb20gXCIuLi8uLi91dGlsL2pzZG9tLm1qc1wiO1xuXG5kZXNjcmliZSgnUmVzb3VyY2VNYW5hZ2VyJywgZnVuY3Rpb24gKCkge1xuXG4gICAgbGV0IGZldGNoUmVmZXJlbmNlLCByZXR1cm5TdGF0dXM7XG5cbiAgICBiZWZvcmUoZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgaW5pdEpTRE9NKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICBkb25lKClcbiAgICAgICAgfSkuY2F0Y2goZSA9PiBkb25lKGUpKTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICAgIGdsb2JhbFRoaXNbJ2ZldGNoJ10gPSBmZXRjaFJlZmVyZW5jZTtcbiAgICAgICAgY2xlYW51cERPTUZyb21UZXN0aW5nKCk7XG4gICAgfSlcblxuICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuXG4gICAgICAgIGluaXRNdXRhdGlvbk9ic2VydmVyRm9yVGVzdGluZygpXG5cbiAgICAgICAgcmV0dXJuU3RhdHVzID0gMjAwO1xuICAgICAgICBmZXRjaFJlZmVyZW5jZSA9IGdsb2JhbFRoaXNbJ2ZldGNoJ107XG4gICAgICAgIGdsb2JhbFRoaXNbJ2ZldGNoJ10gPSBmdW5jdGlvbiAodXJsLCBvcHRpb25zKSB7XG5cbiAgICAgICAgICAgIGlmICghdXJsKSB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgdXJsJylcblxuICAgICAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgICAgICAgICAgdGV4dDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhOiBcInRlc3RcIlxuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzOiByZXR1cm5TdGF0dXNcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgfTtcblxuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnbmV3JywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnbmV3IFJlc291cmNlTWFuYWdlcigpIHNob3VsZCByZXR1cm4gUmVzb3VyY2VNYW5hZ2VyIG9iamVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBkID0gbmV3IFJlc291cmNlTWFuYWdlcigpO1xuICAgICAgICAgICAgZXhwZWN0KGQpLnRvLmJlLmluc3RhbmNlT2YoUmVzb3VyY2VNYW5hZ2VyKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnbG9hZCByZXNvdXJjZXMnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgbGV0IG1hbmFnZXI7XG5cbiAgICAgICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICAgICAgICBtYW5hZ2VyID0gbmV3IFJlc291cmNlTWFuYWdlcigpO1xuICAgICAgICB9KVxuXG4gICAgICAgIGl0KCdhZGQgc2NyaXB0IHNob3VsZCBpbnN0YW5jZSBvZiBSZXNvdXJjZU1hbmFnZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobWFuYWdlci5hZGRTY3JpcHQoJy9leGFtcGxlLmpzJykpLnRvLmJlLmluc3RhbmNlT2YoUmVzb3VyY2VNYW5hZ2VyKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ2FkZCBzdHlsZSBzaG91bGQgaW5zdGFuY2Ugb2YgUmVzb3VyY2VNYW5hZ2VyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KG1hbmFnZXIuYWRkU3R5bGVzaGVldCgnL3N0eWxlLmpzJykpLnRvLmJlLmluc3RhbmNlT2YoUmVzb3VyY2VNYW5hZ2VyKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ2FkZCBkYXRhIHNob3VsZCBpbnN0YW5jZSBvZiBSZXNvdXJjZU1hbmFnZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobWFuYWdlci5hZGREYXRhKCcvZGF0YS5qc29uJykpLnRvLmJlLmluc3RhbmNlT2YoUmVzb3VyY2VNYW5hZ2VyKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZGVzY3JpYmUoJ2Nvbm5lY3QgcmVzb3VyY2VzJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaXQoJ2FkZCBzY3JpcHQgYW5kIGNvbm5lY3Qgc2hvdWxkIGluc3RhbmNlIG9mIFJlc291cmNlTWFuYWdlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBleHBlY3QobWFuYWdlci5hZGRTY3JpcHQoJy9leGFtcGxlLmpzJykuY29ubmVjdCgpKS50by5iZS5pbnN0YW5jZU9mKFJlc291cmNlTWFuYWdlcik7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaXQoJ2FkZCBzdHlsZSBhbmQgY29ubmVjdCBzaG91bGQgaW5zdGFuY2Ugb2YgUmVzb3VyY2VNYW5hZ2VyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGV4cGVjdChtYW5hZ2VyLmFkZFN0eWxlc2hlZXQoJy9zdHlsZS5qcycpLmNvbm5lY3QoKSkudG8uYmUuaW5zdGFuY2VPZihSZXNvdXJjZU1hbmFnZXIpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGl0KCdhZGQgZGF0YSBhbmQgY29ubmVjdCAgc2hvdWxkIGluc3RhbmNlIG9mIFJlc291cmNlTWFuYWdlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBleHBlY3QobWFuYWdlci5hZGREYXRhKCcvZGF0YS5qc29uJykuY29ubmVjdCgpKS50by5iZS5pbnN0YW5jZU9mKFJlc291cmNlTWFuYWdlcik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSlcblxuXG4gICAgICAgIGRlc2NyaWJlKCdjaGVjayBhdmFpbGFiaWxpdHkgcmVzb3VyY2VzJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaXQoJ2FkZCBzY3JpcHQgYW5kIGNoZWNrIGF2YWlsYWJpbGl0eSBzaG91bGQgcmV0dXJuIFByb21pc2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KG1hbmFnZXIuYWRkU2NyaXB0KCcvZXhhbXBsZS5qcycpLmF2YWlsYWJsZSgpKS50by5iZS5pbnN0YW5jZU9mKFByb21pc2UpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGl0KCdhZGQgc3R5bGUgYW5kIGNoZWNrIGF2YWlsYWJpbGl0eSBzaG91bGQgc2hvdWxkIHJldHVybiBQcm9taXNlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGV4cGVjdChtYW5hZ2VyLmFkZFN0eWxlc2hlZXQoJy9zdHlsZS5qcycpLmF2YWlsYWJsZSgpKS50by5iZS5pbnN0YW5jZU9mKFByb21pc2UpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGl0KCdhZGQgZGF0YSBhbmQgY2hlY2sgYXZhaWxhYmlsaXR5ICBzaG91bGQgc2hvdWxkIHJldHVybiBQcm9taXNlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGV4cGVjdChtYW5hZ2VyLmFkZERhdGEoJy9kYXRhLmpzb24nKS5hdmFpbGFibGUoKSkudG8uYmUuaW5zdGFuY2VPZihQcm9taXNlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuXG4gICAgICAgIGRlc2NyaWJlKCdjaGVjayBhdmFpbGFiaWxpdHkgZXhhbXBsZS5qc29uJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaXQoJ2FkZCBkYXRhIGFuZCBjaGVjayBjb250ZW50JywgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgICAgICAgICBtYW5hZ2VyLmFkZERhdGEoJ2h0dHBzOi8vZXhhbXBsZS5jb20vZXhhbXBsZS5qc29uJykuY29ubmVjdCgpLmF2YWlsYWJsZSgpLnRoZW4ociA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdodG1sJykub3V0ZXJIVE1MKS5jb250YWlucygnPntcImFcIjpcInRlc3RcIn08L3NjcmlwdD48L2hlYWQ+Jyk7XG4gICAgICAgICAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICAgICAgICB9KS5jYXRjaChlID0+IGRvbmUoZSkpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgfSlcblxuICAgIH0pO1xuXG5cbn0pOyIsICJpbXBvcnQge1xuICAgIGdldERvY3VtZW50LCBnZXRXaW5kb3csIGdldERvY3VtZW50RnJhZ21lbnRGcm9tU3RyaW5nXG59IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvZG9tL3V0aWwubWpzXCI7XG5cbmltcG9ydCB7Z2V0Q29udGFpbmluZ0RvY3VtZW50fSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2RvbS91dGlsLm1qc1wiO1xuXG5pbXBvcnQge2luaXRKU0RPTX0gZnJvbSBcIi4uLy4uL3V0aWwvanNkb20ubWpzXCI7XG5cbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5cblxuZGVzY3JpYmUoJ0RPTScsIGZ1bmN0aW9uICgpIHtcbiAgICBiZWZvcmUoYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBpbml0SlNET00oKTtcbiAgICB9KVxuICAgIGRlc2NyaWJlKCdnZXREb2N1bWVudCgpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBkb2N1bWVudCBvYmplY3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgZCA9IGdldERvY3VtZW50KCk7XG4gICAgICAgICAgICBleHBlY3QodHlwZW9mIGQpLmlzLmVxdWFsKCdvYmplY3QnKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnZ2V0V2luZG93KCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGRvY3VtZW50IG9iamVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBkID0gZ2V0V2luZG93KCk7XG4gICAgICAgICAgICBleHBlY3QodHlwZW9mIGQpLmlzLmVxdWFsKCdvYmplY3QnKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnZ2V0RG9jdW1lbnRGcmFnbWVudEZyb21TdHJpbmcoKScsIGZ1bmN0aW9uICgpIHtcblxuXG4gICAgICAgIFtcbiAgICAgICAgICAgIFsnPGRpdj48L2Rpdj4nXSxcbiAgICAgICAgICAgIFsnPGRpdj48ZGl2PjI8L2Rpdj48L2Rpdj4nXSxcbiAgICAgICAgICAgIFsnPGRpdj48ZGl2PjI8L2Rpdj4nLCAnPGRpdj48ZGl2PjI8L2Rpdj48L2Rpdj4nXSwgLy8gdGVzdCBpbnZhbGlkIGh0bWxcbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpZiAoIWIpIGIgPSBhO1xuXG4gICAgICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBkb2N1bWVudEZyYWdtZW50IG9iamVjdCAnICsgYSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGxldCBmcmFnbWVudCA9IGdldERvY3VtZW50RnJhZ21lbnRGcm9tU3RyaW5nKGEpO1xuICAgICAgICAgICAgICAgIGV4cGVjdChmcmFnbWVudCkudG8uYmUuaW5zdGFuY2VPZihEb2N1bWVudEZyYWdtZW50KTtcblxuICAgICAgICAgICAgICAgIHZhciBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgICAgICBkaXYuYXBwZW5kQ2hpbGQoZnJhZ21lbnQuY2xvbmVOb2RlKHRydWUpKTtcbiAgICAgICAgICAgICAgICBleHBlY3QoZGl2LmlubmVySFRNTCkudG8uYmUuZXF1YWwoYik7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICB9KTtcblxuICAgIH0pO1xuXG5cbiAgICBkZXNjcmliZSgnZ2V0Q29udGFpbmluZ0RvY3VtZW50JywgKCkgPT4ge1xuICAgICAgICBsZXQgIGpzRG9tRG9jdW1lbnQ7XG5cbiAgICAgICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgICAgICAgIGpzRG9tRG9jdW1lbnQgPSBnZXREb2N1bWVudCgpO1xuICAgICAgICAgfSk7XG4gICAgICAgIC8vXG4gICAgICAgIC8vIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICAgIC8vICAgICBkb20ud2luZG93LmNsb3NlKCk7XG4gICAgICAgIC8vIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgdGhyb3cgYW4gZXJyb3Igd2hlbiBjYWxsZWQgd2l0aCBhbiBpbnZhbGlkIGFyZ3VtZW50JywgKCkgPT4ge1xuICAgICAgICAgICAgZXhwZWN0KCgpID0+IGdldENvbnRhaW5pbmdEb2N1bWVudChudWxsKSkudG8udGhyb3coJ0ludmFsaWQgYXJndW1lbnQuIEV4cGVjdGVkIGFuIEhUTUxFbGVtZW50LicpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiB0aGUgY29ycmVjdCBjb250YWluaW5nIGRvY3VtZW50IGZvciBhbiBlbGVtZW50IGluIHRoZSBtYWluIGRvY3VtZW50JywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZWxlbWVudCA9IGpzRG9tRG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBjb25zdCBjb250YWluaW5nRG9jdW1lbnQgPSBnZXRDb250YWluaW5nRG9jdW1lbnQoZWxlbWVudCk7XG5cbiAgICAgICAgICAgIGV4cGVjdChjb250YWluaW5nRG9jdW1lbnQpLnRvLm51bGw7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIHRoZSBjb3JyZWN0IGNvbnRhaW5pbmcgZG9jdW1lbnQgZm9yIGFuIGVsZW1lbnQgaW5zaWRlIGEgc2hhZG93IHJvb3QnLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBob3N0ID0ganNEb21Eb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIGNvbnN0IHNoYWRvd1Jvb3QgPSBob3N0LmF0dGFjaFNoYWRvdyh7IG1vZGU6ICdvcGVuJyB9KTtcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnQgPSBqc0RvbURvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICAgICAgICAgIHNoYWRvd1Jvb3QuYXBwZW5kQ2hpbGQoZWxlbWVudCk7XG5cbiAgICAgICAgICAgIGNvbnN0IGNvbnRhaW5pbmdEb2N1bWVudCA9IGdldENvbnRhaW5pbmdEb2N1bWVudChlbGVtZW50KTtcbiAgICAgICAgICAgIGV4cGVjdChjb250YWluaW5nRG9jdW1lbnQpLnRvLm5vdC5udWxsO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiB0aGUgY29ycmVjdCBjb250YWluaW5nIGRvY3VtZW50IGZvciBhbiBlbGVtZW50IGluc2lkZSBhIG5lc3RlZCBzaGFkb3cgcm9vdCcsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG91dGVySG9zdCA9IGpzRG9tRG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBjb25zdCBvdXRlclNoYWRvd1Jvb3QgPSBvdXRlckhvc3QuYXR0YWNoU2hhZG93KHsgbW9kZTogJ29wZW4nIH0pO1xuXG4gICAgICAgICAgICBjb25zdCBpbm5lckhvc3QgPSBqc0RvbURvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgb3V0ZXJTaGFkb3dSb290LmFwcGVuZENoaWxkKGlubmVySG9zdCk7XG5cbiAgICAgICAgICAgIGNvbnN0IGlubmVyU2hhZG93Um9vdCA9IGlubmVySG9zdC5hdHRhY2hTaGFkb3coeyBtb2RlOiAnb3BlbicgfSk7XG5cbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnQgPSBqc0RvbURvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICAgICAgICAgIGlubmVyU2hhZG93Um9vdC5hcHBlbmRDaGlsZChlbGVtZW50KTtcblxuICAgICAgICAgICAgY29uc3QgY29udGFpbmluZ0RvY3VtZW50ID0gZ2V0Q29udGFpbmluZ0RvY3VtZW50KGVsZW1lbnQpO1xuICAgICAgICAgICAgZXhwZWN0KGNvbnRhaW5pbmdEb2N1bWVudCkudG8ubm90Lm51bGw7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIG51bGwgd2hlbiB0aGUgZWxlbWVudCBpcyBub3QgYXR0YWNoZWQgdG8gYW55IGRvY3VtZW50JywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZGV0YWNoZWRFbGVtZW50ID0ganNEb21Eb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIGRldGFjaGVkRWxlbWVudC5yZW1vdmUoKTtcblxuICAgICAgICAgICAgY29uc3QgY29udGFpbmluZ0RvY3VtZW50ID0gZ2V0Q29udGFpbmluZ0RvY3VtZW50KGRldGFjaGVkRWxlbWVudCk7XG4gICAgICAgICAgICBleHBlY3QoY29udGFpbmluZ0RvY3VtZW50KS50by5iZS5udWxsO1xuICAgICAgICB9KTtcbiAgICB9KTsgICAgXG4gICAgXG59KTsiLCAiaW1wb3J0IHtcbiAgICBmaW5kRWxlbWVudFdpdGhJZFVwd2FyZHNcbn0gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9kb20vdXRpbC5tanNcIjtcblxuaW1wb3J0IHtleHBlY3R9IGZyb20gJ2NoYWknO1xuaW1wb3J0IHtpbml0SlNET019IGZyb20gXCIuLi8uLi91dGlsL2pzZG9tLm1qc1wiO1xuXG5mdW5jdGlvbiBzZXR1cFRlc3RFbnZpcm9ubWVudCgpIHtcblxuXG4gICAgY2xhc3MgVGVzdENvbXBvbmVudCBleHRlbmRzIEhUTUxFbGVtZW50IHtcbiAgICAgICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgICAgICBzdXBlcigpO1xuICAgICAgICAgICAgdGhpcy5hdHRhY2hTaGFkb3coe21vZGU6ICdvcGVuJ30pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFjdXN0b21FbGVtZW50cy5nZXQoJ3Rlc3QtY29tcG9uZW50JykpIHtcbiAgICAgICAgY3VzdG9tRWxlbWVudHMuZGVmaW5lKCd0ZXN0LWNvbXBvbmVudCcsIFRlc3RDb21wb25lbnQpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gY2xlYW51cFRlc3RFbnZpcm9ubWVudCgpIHtcbiAgICBsZXQgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICBtb2Nrcy5pbm5lckhUTUwgPSBcIlwiO1xufVxuXG5kZXNjcmliZSgnZmluZEVsZW1lbnRXaXRoSWRVcHdhcmRzJywgKCkgPT4ge1xuICAgIGJlZm9yZSgoZG9uZSkgPT4ge1xuICAgICAgICBpbml0SlNET00oKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIHNldHVwVGVzdEVudmlyb25tZW50KCk7XG4gICAgICAgICAgICBkb25lKClcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBhZnRlcigoKSA9PiB7XG4gICAgICAgIGNsZWFudXBUZXN0RW52aXJvbm1lbnQoKTtcbiAgICB9KTtcblxuICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgICAvLyBTZXQgdXAgdGhlIERPTVxuXG4gICAgICAgIGxldCBtb2NrcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpO1xuICAgICAgICBtb2Nrcy5pbm5lckhUTUwgPSBgXG4gICAgICAgICAgICA8ZGl2IGlkPVwiY29udGFpbmVyXCI+XG4gICAgICAgIDxkaXYgaWQ9XCJwYXJlbnRcIj5cbiAgICAgICAgICA8ZGl2IGlkPVwiY2hpbGRcIj48L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5gO1xuXG4gICAgICAgIGNvbnN0IHNoYWRvd0hvc3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChzaGFkb3dIb3N0KTtcbiAgICAgICAgY29uc3Qgc2hhZG93Um9vdCA9IHNoYWRvd0hvc3QuYXR0YWNoU2hhZG93KHttb2RlOiAnb3Blbid9KTtcbiAgICAgICAgY29uc3QgaW5uZXJFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgIGlubmVyRWxlbWVudC5pZCA9ICdpbm5lcic7XG4gICAgICAgIHNoYWRvd1Jvb3QuYXBwZW5kQ2hpbGQoaW5uZXJFbGVtZW50KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmluZCB0aGUgZWxlbWVudCB3aXRoIHRoZSB0YXJnZXQgSUQgaW4gdGhlIG5vcm1hbCBET00nLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGNoaWxkID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NoaWxkJyk7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGZpbmRFbGVtZW50V2l0aElkVXB3YXJkcyhjaGlsZCwgJ3BhcmVudCcpO1xuICAgICAgICBleHBlY3QocmVzdWx0KS50by5lcXVhbChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncGFyZW50JykpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmaW5kIHRoZSBlbGVtZW50IHdpdGggdGhlIHRhcmdldCBJRCBpbiB0aGUgc2hhZG93IERPTScsICgpID0+IHtcbiAgICAgICAgY29uc3QgaW5uZXJFbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZGl2W3NoYWRvd3Jvb3RdID4gZGl2Jyk7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGZpbmRFbGVtZW50V2l0aElkVXB3YXJkcyhpbm5lckVsZW1lbnQsICdpbm5lcicpO1xuICAgICAgICBleHBlY3QocmVzdWx0KS50by5lcXVhbChpbm5lckVsZW1lbnQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gbnVsbCBpZiB0aGUgZWxlbWVudCB3aXRoIHRoZSB0YXJnZXQgSUQgaXMgbm90IGZvdW5kJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBjaGlsZCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjaGlsZCcpO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBmaW5kRWxlbWVudFdpdGhJZFVwd2FyZHMoY2hpbGQsICdub25leGlzdGVudCcpO1xuICAgICAgICBleHBlY3QocmVzdWx0KS50by5iZS5udWxsO1xuICAgIH0pO1xufSk7XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBnZXRXaW5kb3cgfSBmcm9tIFwiLi91dGlsLm1qc1wiO1xuaW1wb3J0IHsgdmFsaWRhdGVTdHJpbmcgfSBmcm9tIFwiLi4vdHlwZXMvdmFsaWRhdGUubWpzXCI7XG5cbmV4cG9ydCB7IGNvbnZlcnRUb1BpeGVscywgZ2V0RGV2aWNlRFBJIH07XG5cbi8qKlxuICogU3RvcmVzIHRoZSBEUEkgb2YgdGhlIGRldmljZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHJldHVybnMge251bWJlcn1cbiAqIEBzaW5jZSAzLjM0LjBcbiAqIEB0eXBlIHtudW1iZXJ8ZnVuY3Rpb259XG4gKi9cbmxldCBDVVJSRU5UX0RFVklDRV9EUEkgPSBmdW5jdGlvbiAoKSB7XG4gICAgbGV0IGkgPSAwO1xuICAgIGZvciAoaSA9IDU2OyBpIDwgMjAwMDsgaSsrKSB7XG4gICAgICAgIGlmIChnZXRXaW5kb3coKS5tYXRjaE1lZGlhKGAobWF4LXJlc29sdXRpb246ICR7aX1kcGkpYCkubWF0Y2hlcyA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIERQSSBvZiB0aGUgZGV2aWNlLlxuICpcbiAqIEBzaW5jZSAzLjM0LjBcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHJldHVybnMge251bWJlcn1cbiAqL1xuZnVuY3Rpb24gZ2V0RGV2aWNlRFBJKCkge1xuICAgIC8vIG9ubHkgY2FsbCB0aGUgZnVuY3Rpb24gb25jZVxuICAgIGlmICh0eXBlb2YgQ1VSUkVOVF9ERVZJQ0VfRFBJID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgQ1VSUkVOVF9ERVZJQ0VfRFBJID0gQ1VSUkVOVF9ERVZJQ0VfRFBJKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGdldFdpbmRvdygpLmRldmljZVBpeGVsUmF0aW8gKiBDVVJSRU5UX0RFVklDRV9EUEk7XG59XG5cbi8qKlxuICogQ29udmVydHMgYSBDU1MgdmFsdWUgdG8gcGl4ZWxzLlxuICpcbiAqIEFzIEV4YW1wbGU6XG4gKlxuICogYGBganNcbiAqIGNvbnZlcnRUb1BpeGVscygnMWVtJykgLy8gcmV0dXJucyB0aGUgY3VycmVudCBmb250IHNpemUgaW4gcGl4ZWxzXG4gKiBjb252ZXJ0VG9QaXhlbHMoJzFyZW0nKSAvLyByZXR1cm5zIHRoZSBjdXJyZW50IHJvb3QgZm9udCBzaXplIGluIHBpeGVsc1xuICogY29udmVydFRvUGl4ZWxzKCcxcHgnKSAvLyByZXR1cm5zIDFcbiAqIGNvbnZlcnRUb1BpeGVscygnMTAwJScpIC8vIHJldHVybnMgdGhlIGN1cnJlbnQgd2lkdGggb2YgdGhlIHBhcmVudCBlbGVtZW50IGluIHBpeGVsc1xuICogYGBgXG4gKlxuICogRm9sbG93aW5nIHVuaXRzIGFyZSBzdXBwb3J0ZWQ6XG4gKiAtIHB4XG4gKiAtIGVtXG4gKiAtIHJlbVxuICogLSAlXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBbcGFyZW50RWxlbWVudD1kb2N1bWVudC5kb2N1bWVudEVsZW1lbnRdXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBbZm9udFNpemVFbGVtZW50PWRvY3VtZW50LmRvY3VtZW50RWxlbWVudF1cbiAqIEByZXR1cm5zIHtudW1iZXJ9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAzLjM0LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAdGhyb3dzIHtFcnJvcn0gVW5zdXBwb3J0ZWQgdW5pdFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdGhyb3dzIHtFcnJvcn0gSW52YWxpZCB2YWx1ZSBmb3JtYXRcbiAqL1xuXG5mdW5jdGlvbiBjb252ZXJ0VG9QaXhlbHModmFsdWUsIHBhcmVudEVsZW1lbnQgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsIGZvbnRTaXplRWxlbWVudCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCkge1xuICAgIFxuICAgIHZhbGlkYXRlU3RyaW5nKHZhbHVlKTtcbiAgICBcbiAgICBcbiAgICBjb25zdCByZWdleCA9IC9eKC0/W1xcZC5dKykoLiopJC87XG4gICAgY29uc3QgbWF0Y2hSZXN1bHQgPSB2YWx1ZS5tYXRjaChyZWdleCk7XG5cbiAgICBpZiAoIW1hdGNoUmVzdWx0KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCB2YWx1ZSBmb3JtYXQ6ICR7dmFsdWV9YCk7XG4gICAgfVxuXG4gICAgY29uc3QgWywgbnVtLCB1bml0XSA9IG1hdGNoUmVzdWx0O1xuICAgIGNvbnN0IG51bWJlciA9IHBhcnNlRmxvYXQobnVtKTtcbiAgICBjb25zdCBkcGkgPSBnZXREZXZpY2VEUEkoKTtcblxuICAgIGlmICh1bml0ID09PSBcInB4XCIpIHtcbiAgICAgICAgcmV0dXJuIG51bWJlcjtcbiAgICB9IGVsc2UgaWYgKHVuaXQgPT09IFwiZW1cIikge1xuICAgICAgICBjb25zdCBmb250U2l6ZSA9IHBhcnNlRmxvYXQod2luZG93LmdldENvbXB1dGVkU3R5bGUoZm9udFNpemVFbGVtZW50KS5mb250U2l6ZSk7XG4gICAgICAgIHJldHVybiBudW1iZXIgKiBmb250U2l6ZTtcbiAgICB9IGVsc2UgaWYgKHVuaXQgPT09IFwicmVtXCIpIHtcbiAgICAgICAgY29uc3Qgcm9vdEZvbnRTaXplID0gcGFyc2VGbG9hdCh3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShwYXJlbnRFbGVtZW50KS5mb250U2l6ZSk7XG4gICAgICAgIHJldHVybiBudW1iZXIgKiByb290Rm9udFNpemU7XG4gICAgfSBlbHNlIGlmICh1bml0ID09PSBcIiVcIikge1xuICAgICAgICBjb25zdCBwYXJlbnRXaWR0aCA9IHBhcnNlRmxvYXQod2luZG93LmdldENvbXB1dGVkU3R5bGUocGFyZW50RWxlbWVudCkud2lkdGgpO1xuICAgICAgICByZXR1cm4gKG51bWJlciAqIHBhcmVudFdpZHRoKSAvIDEwMDtcbiAgICB9IGVsc2UgaWYgKHVuaXQgPT09IFwiaW5cIikge1xuICAgICAgICByZXR1cm4gbnVtYmVyICogZHBpO1xuICAgIH0gZWxzZSBpZiAodW5pdCA9PT0gXCJjbVwiKSB7XG4gICAgICAgIHJldHVybiAobnVtYmVyICogZHBpKSAvIDIuNTQ7XG4gICAgfSBlbHNlIGlmICh1bml0ID09PSBcIm1tXCIpIHtcbiAgICAgICAgcmV0dXJuIChudW1iZXIgKiBkcGkpIC8gMjUuNDtcbiAgICB9IGVsc2UgaWYgKHVuaXQgPT09IFwicHRcIikge1xuICAgICAgICByZXR1cm4gKG51bWJlciAqIGRwaSkgLyA3MjtcbiAgICB9IGVsc2UgaWYgKHVuaXQgPT09IFwicGNcIikge1xuICAgICAgICByZXR1cm4gKG51bWJlciAqIGRwaSkgLyA2O1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgdW5pdDogJHt1bml0fWApO1xuICAgIH1cbn1cbiIsICJpbXBvcnQge2V4cGVjdH0gZnJvbSAnY2hhaSc7XG5pbXBvcnQge2NvbnZlcnRUb1BpeGVscywgZ2V0RGV2aWNlRFBJfSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2RvbS9kaW1lbnNpb24ubWpzXCI7XG5pbXBvcnQge2dldFdpbmRvd30gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9kb20vdXRpbC5tanNcIjtcbmltcG9ydCB7aW5pdEpTRE9NLCBpc0Jyb3dzZXIsIEpTRE9NRXhwb3J0IGFzIEpTRE9NfSBmcm9tIFwiLi4vLi4vdXRpbC9qc2RvbS5tanNcIjtcbmltcG9ydCB7Z2V0R2xvYmFsfSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL2dsb2JhbC5tanNcIjtcbmltcG9ydCB7ZGV0ZWN0UnVudGltZUVudmlyb25tZW50fSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3V0aWwvcnVudGltZS5tanNcIjtcblxuXG5mdW5jdGlvbiBnZXRNb2NrV2luZG93KGRwaSkge1xuXG4gICAgaWYoZGV0ZWN0UnVudGltZUVudmlyb25tZW50KCkgPT09ICdicm93c2VyJykge1xuICAgICAgICByZXR1cm4gZ2V0V2luZG93KCk7XG4gICAgfVxuICAgIFxuICAgIFxuICAgIGNvbnN0IGRvbSA9IG5ldyBKU0RPTSgnJywge1xuICAgICAgICBwcmV0ZW5kVG9CZVZpc3VhbDogdHJ1ZSxcbiAgICAgICAgcmVzb3VyY2VzOiAndXNhYmxlJyxcbiAgICB9KTtcblxuICAgIGRvbS53aW5kb3cubWF0Y2hNZWRpYSA9IChxdWVyeSkgPT4ge1xuICAgICAgICBjb25zdCBkcGlSZWdleCA9IC9cXChtYXgtcmVzb2x1dGlvbjogKFxcZCspZHBpXFwpLztcbiAgICAgICAgY29uc3QgbWF0Y2ggPSBxdWVyeS5tYXRjaChkcGlSZWdleCk7XG5cbiAgICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgICAgICBjb25zdCBtYXhEcGkgPSBwYXJzZUludChtYXRjaFsxXSwgMTApO1xuICAgICAgICAgICAgcmV0dXJuIHttYXRjaGVzOiBkcGkgPD0gbWF4RHBpfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7bWF0Y2hlczogZmFsc2V9O1xuICAgIH07XG5cbiAgICByZXR1cm4gZG9tLndpbmRvdztcbn1cblxuZGVzY3JpYmUoJ2RpbWVuc2lvbicsICgpID0+IHtcbiAgICBsZXQgY3VycmVudEVudmlyb25tZW50O1xuXG4gICAgYmVmb3JlKGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgIGluaXRKU0RPTSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgLy9jaGFpRG9tKGdldERvY3VtZW50KCkpO1xuICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICB9KTtcbiAgICB9KVxuXG4gICAgYmVmb3JlRWFjaCgoKSA9PiB7XG5cbiAgICAgICAgY29uc3QgdGVzdERwaSA9IDk2O1xuICAgICAgICBjb25zdCB0ZXN0V2luZG93ID0gZ2V0TW9ja1dpbmRvdyh0ZXN0RHBpKTtcbiAgICAgICAgZ2V0R2xvYmFsKCkud2luZG93ID0gdGVzdFdpbmRvdztcblxuICAgIH0pO1xuXG4gICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgICAgZGVsZXRlIGdldEdsb2JhbCgpLndpbmRvdztcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdjb252ZXJ0VG9QaXhlbHMnLCAoKSA9PiB7XG4gICAgICAgIGl0KCdzaG91bGQgY29ycmVjdGx5IGNvbnZlcnQgcHggdmFsdWVzJywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gY29udmVydFRvUGl4ZWxzKCcxMDBweCcpO1xuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdCkudG8uZXF1YWwoMTAwKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoXCJzaG91bGQgdGhyb3cgYW4gZXJyb3Igd2hlbiB0aGUgaW5wdXQgdmFsdWUgaGFzIGFuIGludmFsaWQgZm9ybWF0XCIsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGludmFsaWRWYWx1ZSA9IFwiaW52YWxpZF92YWx1ZVwiO1xuXG4gICAgICAgICAgICBjb25zdCBlcnJvckZuID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnZlcnRUb1BpeGVscyhpbnZhbGlkVmFsdWUpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgZXhwZWN0KGVycm9yRm4pLnRvLnRocm93KEVycm9yLCBgSW52YWxpZCB2YWx1ZSBmb3JtYXQ6ICR7aW52YWxpZFZhbHVlfWApO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdChcInNob3VsZCBoYW5kbGUgbmVnYXRpdmUgdmFsdWVzIGNvcnJlY3RseVwiLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBuZWdhdGl2ZVZhbHVlID0gXCItMTBweFwiO1xuICAgICAgICAgICAgY29uc3QgZXhwZWN0ZWRSZXN1bHQgPSAtMTA7XG5cbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGNvbnZlcnRUb1BpeGVscyhuZWdhdGl2ZVZhbHVlKTtcblxuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdCkudG8uZXF1YWwoZXhwZWN0ZWRSZXN1bHQpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIGNvcnJlY3RseSBjb252ZXJ0IGVtIHZhbHVlcycsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHRlc3RFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICB0ZXN0RWxlbWVudC5zdHlsZS5mb250U2l6ZSA9ICcxNnB4JztcbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodGVzdEVsZW1lbnQpO1xuXG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBjb252ZXJ0VG9QaXhlbHMoJzJlbScsIHRlc3RFbGVtZW50LCB0ZXN0RWxlbWVudCk7XG4gICAgICAgICAgICBleHBlY3QocmVzdWx0KS50by5lcXVhbCgzMik7XG5cbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQodGVzdEVsZW1lbnQpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIGNvcnJlY3RseSBjb252ZXJ0IHJlbSB2YWx1ZXMnLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0ZXN0RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgdGVzdEVsZW1lbnQuc3R5bGUuZm9udFNpemUgPSAnMTZweCc7XG4gICAgICAgICAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuYXBwZW5kQ2hpbGQodGVzdEVsZW1lbnQpO1xuXG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBjb252ZXJ0VG9QaXhlbHMoJzJyZW0nLCB0ZXN0RWxlbWVudCk7XG4gICAgICAgICAgICBleHBlY3QocmVzdWx0KS50by5lcXVhbCgzMik7XG5cbiAgICAgICAgICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5yZW1vdmVDaGlsZCh0ZXN0RWxlbWVudCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgY29ycmVjdGx5IGNvbnZlcnQgcGVyY2VudGFnZSB2YWx1ZXMnLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0ZXN0RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgdGVzdEVsZW1lbnQuc3R5bGUud2lkdGggPSAnNTAwcHgnO1xuICAgICAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCh0ZXN0RWxlbWVudCk7XG5cbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGNvbnZlcnRUb1BpeGVscygnNTAlJywgdGVzdEVsZW1lbnQpO1xuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdCkudG8uZXF1YWwoMjUwKTtcblxuICAgICAgICAgICAgZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZCh0ZXN0RWxlbWVudCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgdGhyb3cgYW4gZXJyb3IgZm9yIHVuc3VwcG9ydGVkIHVuaXRzJywgKCkgPT4ge1xuICAgICAgICAgICAgZXhwZWN0KCgpID0+IGNvbnZlcnRUb1BpeGVscygnMTB1bnN1cHBvcnRlZFVuaXQnKSkudG8udGhyb3coJ1Vuc3VwcG9ydGVkIHVuaXQ6IHVuc3VwcG9ydGVkVW5pdCcpO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuXG4gICAgZGVzY3JpYmUoJ2dldERldmljZURQSScsICgpID0+IHtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gdGhlIGNvcnJlY3QgZGV2aWNlIERQSScsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHRlc3REcGkgPSA5NjtcbiAgICAgICAgICAgIGNvbnN0IHRlc3RXaW5kb3cgPSBnZXRNb2NrV2luZG93KHRlc3REcGkpO1xuICAgICAgICAgICAgZ2V0R2xvYmFsKCkud2luZG93ID0gdGVzdFdpbmRvdztcblxuICAgICAgICAgICAgY29uc3QgZGV2aWNlRHBpID0gZ2V0RGV2aWNlRFBJKCk7XG4gICAgICAgICAgICBleHBlY3QoZGV2aWNlRHBpKS50by5lcXVhbCh0ZXN0RHBpICogdGVzdFdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvKTtcblxuICAgICAgICAgICAgZGVsZXRlIGdldEdsb2JhbCgpLndpbmRvdztcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBjYWNoZSB0aGUgcmVzdWx0IGFuZCByZXR1cm4gdGhlIHNhbWUgdmFsdWUnLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0ZXN0RHBpID0gOTY7XG4gICAgICAgICAgICBjb25zdCB0ZXN0V2luZG93ID0gZ2V0TW9ja1dpbmRvdyh0ZXN0RHBpKTtcbiAgICAgICAgICAgIGdldEdsb2JhbCgpLndpbmRvdyA9IHRlc3RXaW5kb3c7XG5cbiAgICAgICAgICAgIGNvbnN0IGRldmljZURwaTEgPSBnZXREZXZpY2VEUEkoKTtcbiAgICAgICAgICAgIGNvbnN0IGRldmljZURwaTIgPSBnZXREZXZpY2VEUEkoKTtcbiAgICAgICAgICAgIGV4cGVjdChkZXZpY2VEcGkxKS50by5lcXVhbChkZXZpY2VEcGkyKTtcblxuICAgICAgICAgICAgZGVsZXRlIGdldEdsb2JhbCgpLndpbmRvdztcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbn0pOyIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuVXRpbFxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuY29uc3QgRU5WX0FXU19MQU1CREEgPSBcImF3cy1sYW1iZGFcIjtcbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuVXRpbFxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuY29uc3QgRU5WX0dPT0dMRV9GVU5DVElPTlMgPSBcImdvb2dsZS1mdW5jdGlvbnNcIjtcbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuVXRpbFxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuY29uc3QgRU5WX0VMRUNUUk9OID0gXCJlbGVjdHJvblwiO1xuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5VdGlsXG4gKiBAdHlwZSB7c3RyaW5nfVxuICovXG5jb25zdCBFTlZfTk9ERSA9IFwibm9kZVwiO1xuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5VdGlsXG4gKiBAdHlwZSB7c3RyaW5nfVxuICovXG5jb25zdCBFTlZfQlJPV1NFUiA9IFwiYnJvd3NlclwiO1xuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5VdGlsXG4gKiBAdHlwZSB7c3RyaW5nfVxuICovXG5jb25zdCBFTlZfV0VCX1dPUktFUiA9IFwid2ViLXdvcmtlclwiO1xuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5VdGlsXG4gKiBAdHlwZSB7c3RyaW5nfVxuICovXG5jb25zdCBFTlZfREVOTyA9IFwiZGVub1wiO1xuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5VdGlsXG4gKiBAdHlwZSB7c3RyaW5nfVxuICovXG5jb25zdCBFTlZfVU5LTk9XTiA9IFwidW5rbm93blwiO1xuXG4vKipcbiAqIERldGVjdHMgYW5kIHJldHVybnMgdGhlIGN1cnJlbnQgcnVudGltZSBlbnZpcm9ubWVudC5cbiAqXG4gKiAtICdhd3MtbGFtYmRhJzogQVdTIExhbWJkYSBlbnZpcm9ubWVudFxuICogLSAnZ29vZ2xlLWZ1bmN0aW9ucyc6IEdvb2dsZSBDbG91ZCBGdW5jdGlvbnMgZW52aXJvbm1lbnRcbiAqIC0gJ2VsZWN0cm9uJzogRWxlY3Ryb24gZW52aXJvbm1lbnRcbiAqIC0gJ25vZGUnOiBOb2RlLmpzIGVudmlyb25tZW50XG4gKiAtICdicm93c2VyJzogQnJvd3NlciBlbnZpcm9ubWVudFxuICogLSAnd2ViLXdvcmtlcic6IFdlYiBXb3JrZXIgZW52aXJvbm1lbnRcbiAqIC0gJ2Rlbm8nOiBEZW5vIGVudmlyb25tZW50XG4gKiAtICdyZWFjdC1uYXRpdmUnOiBSZWFjdCBOYXRpdmUgZW52aXJvbm1lbnRcbiAqIC0gJ3Vua25vd24nOiBVbmtub3duIGVudmlyb25tZW50XG4gKlxuICogQHNpbmNlIDMuMzQuMFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVXRpbFxuICogQHJldHVybnMge3N0cmluZ30gVGhlIGRldGVjdGVkIHJ1bnRpbWUgZW52aXJvbm1lbnQuIFBvc3NpYmxlIHZhbHVlcyBhcmU6XG4gKi9cbmZ1bmN0aW9uIGRldGVjdFJ1bnRpbWVFbnZpcm9ubWVudCgpIHtcbiAgICAvLyBBV1MgTGFtYmRhIGVudmlyb25tZW50XG4gICAgaWYgKHR5cGVvZiBwcm9jZXNzICE9PSBcInVuZGVmaW5lZFwiICYmIHByb2Nlc3MuZW52ICE9IG51bGwgJiYgcHJvY2Vzcy5lbnYuQVdTX0xBTUJEQV9GVU5DVElPTl9OQU1FKSB7XG4gICAgICAgIHJldHVybiBFTlZfQVdTX0xBTUJEQTtcbiAgICB9XG5cbiAgICAvLyBHb29nbGUgQ2xvdWQgRnVuY3Rpb25zIGVudmlyb25tZW50XG4gICAgaWYgKHR5cGVvZiBwcm9jZXNzICE9PSBcInVuZGVmaW5lZFwiICYmIHByb2Nlc3MuZW52ICE9IG51bGwgJiYgcHJvY2Vzcy5lbnYuRlVOQ1RJT05fTkFNRSkge1xuICAgICAgICByZXR1cm4gRU5WX0dPT0dMRV9GVU5DVElPTlM7XG4gICAgfVxuXG4gICAgLy8gTm9kZS5qcyBlbnZpcm9ubWVudFxuICAgIGlmICh0eXBlb2YgcHJvY2VzcyAhPT0gXCJ1bmRlZmluZWRcIiAmJiBwcm9jZXNzLnZlcnNpb25zICE9IG51bGwgJiYgcHJvY2Vzcy52ZXJzaW9ucy5ub2RlICE9IG51bGwpIHtcbiAgICAgICAgLy8gRWxlY3Ryb24gZW52aXJvbm1lbnRcbiAgICAgICAgaWYgKHByb2Nlc3MudmVyc2lvbnMuZWxlY3Ryb24gIT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIEVOVl9FTEVDVFJPTjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gRU5WX05PREU7XG4gICAgfVxuXG4gICAgLy8gQnJvd3NlciBlbnZpcm9ubWVudFxuICAgIGlmIChcbiAgICAgICAgdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICB0eXBlb2Ygd2luZG93LmRvY3VtZW50ICE9PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgIHR5cGVvZiBuYXZpZ2F0b3IgIT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgdHlwZW9mIG5hdmlnYXRvci51c2VyQWdlbnQgPT09IFwic3RyaW5nXCJcbiAgICApIHtcbiAgICAgICAgLy8gV2ViIFdvcmtlciBlbnZpcm9ubWVudFxuICAgICAgICBpZiAodHlwZW9mIHNlbGYgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIGltcG9ydFNjcmlwdHMgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgcmV0dXJuIEVOVl9XRUJfV09SS0VSO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBFTlZfQlJPV1NFUjtcbiAgICB9XG5cbiAgICAvLyBEZW5vIGVudmlyb25tZW50XG4gICAgaWYgKHR5cGVvZiBEZW5vICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgIHJldHVybiBFTlZfREVOTztcbiAgICB9XG5cbiAgICAvLyBVbmtub3duIGVudmlyb25tZW50XG4gICAgcmV0dXJuIEVOVl9VTktOT1dOO1xufVxuXG5leHBvcnQge1xuICAgIEVOVl9BV1NfTEFNQkRBLFxuICAgIEVOVl9HT09HTEVfRlVOQ1RJT05TLFxuICAgIEVOVl9FTEVDVFJPTixcbiAgICBFTlZfTk9ERSxcbiAgICBFTlZfQlJPV1NFUixcbiAgICBFTlZfV0VCX1dPUktFUixcbiAgICBFTlZfREVOTyxcbiAgICBFTlZfVU5LTk9XTixcbiAgICBkZXRlY3RSdW50aW1lRW52aXJvbm1lbnQsXG59O1xuIiwgIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IGNoYWkgZnJvbSBcImNoYWlcIlxuaW1wb3J0IHtpbnRlcm5hbFN5bWJvbH0gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQge0FUVFJJQlVURV9PUFRJT05TfSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2RvbS9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQge2dldERvY3VtZW50fSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2RvbS91dGlsLm1qc1wiO1xuaW1wb3J0IHtQcm94eU9ic2VydmVyfSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL3Byb3h5b2JzZXJ2ZXIubWpzXCI7XG5pbXBvcnQge2FkZE9iamVjdFdpdGhVcGRhdGVyVG9FbGVtZW50fSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2RvbS91cGRhdGVyLm1qc1wiO1xuaW1wb3J0IHtjaGFpRG9tfSBmcm9tIFwiLi4vLi4vdXRpbC9jaGFpLWRvbS5tanNcIjtcbmltcG9ydCB7aW5pdEpTRE9NfSBmcm9tIFwiLi4vLi4vdXRpbC9qc2RvbS5tanNcIjtcblxuXG5sZXQgZXhwZWN0ID0gY2hhaS5leHBlY3Q7XG5jaGFpLnVzZShjaGFpRG9tKTtcblxubGV0IGh0bWwxID0gYFxuICAgIDxkaXYgaWQ9XCJ0ZXN0MVwiPlxuICAgIDwvZGl2PlxuYDtcblxubGV0IGh0bWwyID0gYFxuICAgIDxpbnB1dCBkYXRhLW1vbnN0ZXItYmluZD1cInBhdGg6YVwiIGlkPVwidGVzdDJcIiBkYXRhLW1vbnN0ZXItYXR0cmlidXRlcz1cInZhbHVlIHBhdGg6YVwiPlxuYDtcblxuLy8gZGVmaW5lZCBpbiBjb25zdGFudHMubWpzXG5jb25zdCB1cGRhdGVyU3ltYm9sS2V5ID0gXCJAc2NodWthaS9tb25zdGVyL2RvbS9jdXN0b20tZWxlbWVudEBAb3B0aW9ucy11cGRhdGVyLWxpbmtcIlxuY29uc3QgdXBkYXRlclN5bWJvbFN5bWJvbCA9IFN5bWJvbC5mb3IodXBkYXRlclN5bWJvbEtleSk7XG5cblxuXG5kZXNjcmliZSgnRE9NJywgZnVuY3Rpb24gKCkge1xuXG4gICAgbGV0IEN1c3RvbUVsZW1lbnQsIHJlZ2lzdGVyQ3VzdG9tRWxlbWVudCwgVGVzdENvbXBvbmVudCwgZG9jdW1lbnQsIFRlc3RDb21wb25lbnQyLGFzc2lnblVwZGF0ZXJUb0VsZW1lbnQ7XG5cblxuICAgIGRlc2NyaWJlKFwiYXNzaWduVXBkYXRlclRvRWxlbWVudFwiLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgYmVmb3JlKGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICBpbml0SlNET00oKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICBpbXBvcnQoXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvZG9tL2N1c3RvbWVsZW1lbnQubWpzXCIpLnRoZW4oKG0pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIEN1c3RvbUVsZW1lbnQgPSBtWydDdXN0b21FbGVtZW50J107XG4gICAgICAgICAgICAgICAgICAgICAgICBhc3NpZ25VcGRhdGVyVG9FbGVtZW50PSBmdW5jdGlvbiAoZWxlbWVudHMsIG9iamVjdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhZGRPYmplY3RXaXRoVXBkYXRlclRvRWxlbWVudC5jYWxsKHRoaXMsIGVsZW1lbnRzLCB1cGRhdGVyU3ltYm9sU3ltYm9sLCBvYmplY3QpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50ID0gZ2V0RG9jdW1lbnQoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgZG9uZSgpXG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRvbmUoZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuXG4gICAgICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgICAgICAgbGV0IG1vY2tzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vY2tzJyk7XG4gICAgICAgICAgICBtb2Nrcy5pbm5lckhUTUwgPSBodG1sMjtcbiAgICAgICAgfSlcblxuICAgICAgICBhZnRlckVhY2goKCkgPT4ge1xuICAgICAgICAgICAgbGV0IG1vY2tzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vY2tzJyk7XG4gICAgICAgICAgICBtb2Nrcy5pbm5lckhUTUwgPSBcIlwiO1xuICAgICAgICB9KVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGlzIHRlc3QgdHJ5IHRvIHNpbXVsYXRlIHRoZSBidWcgdGhhdCB3YXMgZm91bmQgaW4gdGhlIGFzc2lnblVwZGF0ZXJUb0VsZW1lbnQgZnVuY3Rpb24uXG4gICAgICAgICAqIFRoZSBidWcgd2FzIHRoYXQgdGhlIHVwZGF0ZXIgd2FzIG5vdCBhc3NpZ25lZCB0byB0aGUgZWxlbWVudCB3aGVuIHRoZSBlbGVtZW50IHdhcyBjcmVhdGVkLlxuICAgICAgICAgKiBcbiAgICAgICAgICogdW5mb3J0dW5hdGVseSwgdGhpcyB0ZXN0IGRvZXMgbm90IHJlcHJvZHVjZSB0aGUgYnVnLlxuICAgICAgICAgKi9cbiAgICAgICAgaXQoXCJzaG91bGQgYXNzaWduIGFuIHVwZGF0ZXIgdG8gYW4gZWxlbWVudFwiLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICAgICAgbGV0IGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGVzdDInKTtcblxuICAgICAgICAgICAgZXhwZWN0KGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwibW9ja3NcIikuaW5uZXJIVE1MKS50by5lcXVhbChodG1sMik7XG5cbiAgICAgICAgICAgIGNvbnN0IGEgPSB7YTogMX07XG4gICAgICAgICAgICBjb25zdCBiID0ge2I6IDJ9O1xuXG4gICAgICAgICAgICBjb25zdCBhcCA9IG5ldyBQcm94eU9ic2VydmVyKGEpO1xuICAgICAgICAgICAgY29uc3QgYnAgPSBuZXcgUHJveHlPYnNlcnZlcihiKTtcblxuICAgICAgICAgICAgY29uc3QgeCA9IGFwLmdldFN1YmplY3QoKVxuICAgICAgICAgICAgY29uc3QgeSA9IGJwLmdldFN1YmplY3QoKVxuXG4gICAgICAgICAgICBjb25zdCBzZXQgPSBuZXcgU2V0KCk7XG4gICAgICAgICAgICBzZXQuYWRkKGVsZW1lbnQpO1xuXG4gICAgICAgICAgICBhc3NpZ25VcGRhdGVyVG9FbGVtZW50LmNhbGwoZWxlbWVudCwgc2V0LCBhcCk7XG4gICAgICAgICAgICBhc3NpZ25VcGRhdGVyVG9FbGVtZW50LmNhbGwoZWxlbWVudCwgc2V0LCBicCk7XG5cbiAgICAgICAgICAgIGV4cGVjdChKU09OLnN0cmluZ2lmeSh4KSkudG8uZXF1YWwoJ3tcImFcIjoxfScpO1xuICAgICAgICAgICAgZXhwZWN0KEpTT04uc3RyaW5naWZ5KHkpKS50by5lcXVhbCgne1wiYlwiOjJ9Jyk7XG5cbiAgICAgICAgICAgIGNvbnN0IHN5ID0gdXBkYXRlclN5bWJvbFN5bWJvbDtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgbGV0IHYgPSBlbGVtZW50LmdldEF0dHJpYnV0ZShcImRhdGEtbW9uc3Rlci1vYmplY3RsaW5rXCIpO1xuICAgICAgICAgICAgZXhwZWN0KHYpLnRvLmVxdWFsKCdTeW1ib2woJyt1cGRhdGVyU3ltYm9sS2V5KycpJyk7XG5cbiAgICAgICAgICAgIGNvbnN0IHVwZGF0ZXIgPSBlbGVtZW50W3N5XTtcblxuICAgICAgICAgICAgZm9yIChjb25zdCB2IG9mIHVwZGF0ZXIpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHUgb2Ygdikge1xuICAgICAgICAgICAgICAgICAgICB1LnJ1bigpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdS5lbmFibGVFdmVudFByb2Nlc3NpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBleHBlY3QodXBkYXRlcikudG8uYmUuYW4uaW5zdGFuY2VvZihTZXQpO1xuICAgICAgICAgICAgZXhwZWN0KHVwZGF0ZXIpLnRvLmJlLmEoXCJTZXRcIik7XG5cbiAgICAgICAgICAgIHguYSA9IDM7XG4gICAgICAgICAgICBicC5nZXRTdWJqZWN0KCkuYiA9IDQ7XG5cbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuXG4gICAgICAgICAgICAgICAgbGV0IG1vY2tIVE1MID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJtb2Nrc1wiKTtcblxuICAgICAgICAgICAgICAgIC8vIGh0bWwgZXhwZXh0ZWQ6XG4gICAgICAgICAgICAgICAgLy8gPGlucHV0IGRhdGEtbW9uc3Rlci1iaW5kPVwicGF0aDphXCIgaWQ9XCJ0ZXN0MlwiIGRhdGEtbW9uc3Rlci1hdHRyaWJ1dGVzPVwidmFsdWUgcGF0aDphXCIgZGF0YS1tb25zdGVyLW9iamVjdGxpbms9XCJTeW1ib2woQHNjaHVrYWkvbW9uc3Rlci9kb20vQEBvYmplY3QtdXBkYXRlci1saW5rKVwiIHZhbHVlPVwiM1wiPlxuXG4gICAgICAgICAgICAgICAgZXhwZWN0KG1vY2tIVE1MLnF1ZXJ5U2VsZWN0b3IoXCIjdGVzdDJcIikpLnRvLmhhdmUudmFsdWUoJzMnKVxuICAgICAgICAgICAgICAgIGV4cGVjdChtb2NrSFRNTC5xdWVyeVNlbGVjdG9yKFwiI3Rlc3QyXCIpKS50by5oYXZlLmF0dHJpYnV0ZSgnZGF0YS1tb25zdGVyLW9iamVjdGxpbmsnLCAnU3ltYm9sKCcrdXBkYXRlclN5bWJvbEtleSsnKScpXG4gICAgICAgICAgICAgICAgLy9leHBlY3QobW9ja0hUTUwpLnRvLmhhdmUuaHRtbChyZXN1bHRIVE1MKTtcblxuICAgICAgICAgICAgICAgIGV4cGVjdChlbGVtZW50LnZhbHVlKS50by5lcXVhbChcIjNcIik7XG5cbiAgICAgICAgICAgICAgICBleHBlY3QoSlNPTi5zdHJpbmdpZnkoYXAuZ2V0UmVhbFN1YmplY3QoKSkpLnRvLmVxdWFsKCd7XCJhXCI6M30nKTtcbiAgICAgICAgICAgICAgICBleHBlY3QoSlNPTi5zdHJpbmdpZnkoYnAuZ2V0UmVhbFN1YmplY3QoKSkpLnRvLmVxdWFsKCd7XCJiXCI6NH0nKTtcbiAgICAgICAgICAgICAgICBkb25lKClcbiAgICAgICAgICAgIH0sIDEwKVxuXG4gICAgICAgIH0pXG5cbiAgICB9KVxuXG5cbiAgICBkZXNjcmliZSgnQ3VzdG9tRWxlbWVudCgpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGJlZm9yZShmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICAgICAgaW5pdEpTRE9NKCkudGhlbigoKSA9PiB7XG5cbiAgICAgICAgICAgICAgICBpbXBvcnQoXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvZG9tL2N1c3RvbWVsZW1lbnQubWpzXCIpLnRoZW4oKG0pID0+IHtcblxuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgQ3VzdG9tRWxlbWVudCA9IG1bJ0N1c3RvbUVsZW1lbnQnXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2lzdGVyQ3VzdG9tRWxlbWVudCA9IG1bJ3JlZ2lzdGVyQ3VzdG9tRWxlbWVudCddO1xuICAgICAgICAgICAgICAgICAgICAgICAgVGVzdENvbXBvbmVudCA9IGNsYXNzIGV4dGVuZHMgQ3VzdG9tRWxlbWVudCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGljIGdldFRhZygpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibW9uc3Rlci10ZXN0Y2xhc3NcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgcmVnaXN0ZXJDdXN0b21FbGVtZW50KFRlc3RDb21wb25lbnQpXG5cbiAgICAgICAgICAgICAgICAgICAgICAgIFRlc3RDb21wb25lbnQyID0gY2xhc3MgZXh0ZW5kcyBDdXN0b21FbGVtZW50IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0aWMgZ2V0VGFnKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJtb25zdGVyLXRlc3RjbGFzczJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICogQHJldHVybiB7T2JqZWN0fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldCBkZWZhdWx0cygpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3VwZXIuZGVmYXVsdHMsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbW90ZXN0OiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wbGF0ZXM6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYWluOiAnPGgxPjwvaDE+PGFydGljbGU+PHA+dGVzdDwvcD48ZGl2IGlkPVwiY29udGFpbmVyXCI+PC9kaXY+PC9hcnRpY2xlPidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2lzdGVyQ3VzdG9tRWxlbWVudChUZXN0Q29tcG9uZW50MilcblxuICAgICAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnQgPSBnZXREb2N1bWVudCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZG9uZSgpXG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRvbmUoZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuXG4gICAgICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgICAgICAgbGV0IG1vY2tzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vY2tzJyk7XG4gICAgICAgICAgICBtb2Nrcy5pbm5lckhUTUwgPSBodG1sMTtcbiAgICAgICAgfSlcblxuICAgICAgICBhZnRlckVhY2goKCkgPT4ge1xuICAgICAgICAgICAgbGV0IG1vY2tzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vY2tzJyk7XG4gICAgICAgICAgICBtb2Nrcy5pbm5lckhUTUwgPSBcIlwiO1xuICAgICAgICB9KVxuXG4gICAgICAgIGRlc2NyaWJlKCdDdXN0b21FbGVtZW50KCkgd2l0aCBDb25maWcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpdCgnc2hvdWxkIHJlYWQgY29uZmlnIGZyb20gdGFnJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICAgICAgbGV0IG1vY2tzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vY2tzJyk7XG4gICAgICAgICAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gYFxuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIDxzY3JpcHQgaWQ9XCJjb25maWcxXCIgdHlwZT1cImFwcGxpY2F0aW9uL2pzb25cIj5cbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIFwiZGVtb3Rlc3RcIjoxNDI1XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDwvc2NyaXB0PlxuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIDxtb25zdGVyLXRlc3RjbGFzczIgaWQ9XCJ0aGlzaXNhdGVzdFwiIGRhdGEtbW9uc3Rlci1vcHRpb25zLXNlbGVjdG9yPVwiI2NvbmZpZzFcIj5cbiAgICAgICAgICAgICAgICA8L21vbnN0ZXItdGVzdGNsYXNzMj5cbiAgICAgICAgICAgICAgICBgO1xuXG4gICAgICAgICAgICAgICAgbGV0IG1vbnN0ZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGhpc2lzYXRlc3QnKTtcbiAgICAgICAgICAgICAgICBleHBlY3QobW9uc3Rlci5nZXRPcHRpb24oJ2RlbW90ZXN0JykpLmlzLmVxbCgxNDI1KTtcblxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGRlc2NyaWJlKCdjcmVhdGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBjdXN0b20tZWxlbWVudCBvYmplY3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbGV0IGQgPSBuZXcgVGVzdENvbXBvbmVudCgpO1xuICAgICAgICAgICAgICAgIGV4cGVjdCh0eXBlb2YgZCkuaXMuZXF1YWwoJ29iamVjdCcpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGRlc2NyaWJlKCdjb25uZWN0IGVtcHR5IGVsZW1lbnQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpdCgnZG9jdW1lbnQgc2hvdWxkIGNvbnRhaW4gbW9uc3Rlci10ZXN0Y2xhc3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbGV0IGQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdtb25zdGVyLXRlc3RjbGFzcycpO1xuICAgICAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0ZXN0MScpLmFwcGVuZENoaWxkKGQpO1xuICAgICAgICAgICAgICAgIGV4cGVjdChkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnbW9uc3Rlci10ZXN0Y2xhc3MnKS5sZW5ndGgpLmlzLmVxdWFsKDEpO1xuICAgICAgICAgICAgICAgIC8vIG5vIGRhdGEtbW9uc3Rlci1vYmplY3RsaW5rPVwiU3ltYm9sKG1vbnN0ZXJVcGRhdGVyKVwiIGJlY2F1c2UgaXQgaGFzIG5vdGhpbmcgdG8gdXBkYXRlXG4gICAgICAgICAgICAgICAgZXhwZWN0KGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0ZXN0MScpKS5jb250YWluLmh0bWwoJzxtb25zdGVyLXRlc3RjbGFzcz48L21vbnN0ZXItdGVzdGNsYXNzPicpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGRlc2NyaWJlKCdjb25uZWN0IGVsZW1lbnQgd2l0aCBodG1sJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaXQoJ2RvY3VtZW50IHNob3VsZCBjb250YWluIG1vbnN0ZXItdGVzdGNsYXNzMicsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICAgICAgbGV0IGQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdtb25zdGVyLXRlc3RjbGFzczInKTtcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGVzdDEnKS5hcHBlbmRDaGlsZChkKTtcblxuICAgICAgICAgICAgICAgIC8vIGluc2VydCBET00gcnVuIGluIGV4dHJhIHByb2Nlc3MgdmlhIHNldFRpbWVvdXQhXG4gICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBleHBlY3QoZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ21vbnN0ZXItdGVzdGNsYXNzMicpLmxlbmd0aCkuaXMuZXF1YWwoMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBleHBlY3QoZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ21vbnN0ZXItdGVzdGNsYXNzMicpLml0ZW0oMCkuc2hhZG93Um9vdC5pbm5lckhUTUwpLmlzLmVxdWFsKCc8aDE+PC9oMT48YXJ0aWNsZT48cD50ZXN0PC9wPjxkaXYgaWQ9XCJjb250YWluZXJcIj48L2Rpdj48L2FydGljbGU+Jyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBleHBlY3QoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Rlc3QxJykpLmNvbnRhaW4uaHRtbCgnPG1vbnN0ZXItdGVzdGNsYXNzMiBkYXRhLW1vbnN0ZXItb2JqZWN0bGluaz1cIlN5bWJvbCgnK3VwZGF0ZXJTeW1ib2xLZXkrJylcIj48L21vbnN0ZXItdGVzdGNsYXNzMj4nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkb25lKCk7XG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRvbmUoZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIH0sIDEwKTtcblxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGRlc2NyaWJlKCdPcHRpb25zIGNoYW5nZScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgaXQoJ2RlbGVnYXRlc0ZvY3VzIHNob3VsZCBjaGFuZ2UgZnJvbSB0cnVlIHRvIGZhbHNlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGxldCBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbW9uc3Rlci10ZXN0Y2xhc3MnKVxuXG4gICAgICAgICAgICAgICAgY29uc3QgbyA9IGVsZW1lbnRbaW50ZXJuYWxTeW1ib2xdLnJlYWxTdWJqZWN0O1xuICAgICAgICAgICAgICAgIGV4cGVjdChPYmplY3QuaXMoZWxlbWVudFtpbnRlcm5hbFN5bWJvbF0ucmVhbFN1YmplY3QsIG8pKS50by5iZS50cnVlO1xuXG4gICAgICAgICAgICAgICAgZXhwZWN0KGVsZW1lbnRbaW50ZXJuYWxTeW1ib2xdLnJlYWxTdWJqZWN0Lm9wdGlvbnMuZGVsZWdhdGVzRm9jdXMpLnRvLmJlLnRydWU7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGVsZW1lbnRbaW50ZXJuYWxTeW1ib2xdLnN1YmplY3Qub3B0aW9ucy5kZWxlZ2F0ZXNGb2N1cykudG8uYmUudHJ1ZTtcbiAgICAgICAgICAgICAgICBleHBlY3QoZWxlbWVudC5nZXRPcHRpb24oJ2RlbGVnYXRlc0ZvY3VzJykpLnRvLmJlLnRydWU7XG4gICAgICAgICAgICAgICAgZXhwZWN0KE9iamVjdC5pcyhlbGVtZW50W2ludGVybmFsU3ltYm9sXS5yZWFsU3ViamVjdCwgbykpLnRvLmJlLnRydWU7XG5cbiAgICAgICAgICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShBVFRSSUJVVEVfT1BUSU9OUywgSlNPTi5zdHJpbmdpZnkoe2RlbGVnYXRlc0ZvY3VzOiBmYWxzZX0pKTtcbiAgICAgICAgICAgICAgICBleHBlY3QoT2JqZWN0LmlzKGVsZW1lbnRbaW50ZXJuYWxTeW1ib2xdLnJlYWxTdWJqZWN0LCBvKSkudG8uYmUudHJ1ZTtcblxuICAgICAgICAgICAgICAgIGV4cGVjdChlbGVtZW50LmdldE9wdGlvbignZGVsZWdhdGVzRm9jdXMnKSkudG8uYmUuZmFsc2U7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGVsZW1lbnRbaW50ZXJuYWxTeW1ib2xdLnJlYWxTdWJqZWN0Lm9wdGlvbnMuZGVsZWdhdGVzRm9jdXMpLnRvLmJlLmZhbHNlO1xuICAgICAgICAgICAgICAgIGV4cGVjdChPYmplY3QuaXMoZWxlbWVudFtpbnRlcm5hbFN5bWJvbF0ucmVhbFN1YmplY3QsIG8pKS50by5iZS50cnVlO1xuXG4gICAgICAgICAgICB9KVxuXG5cbiAgICAgICAgfSlcblxuICAgICAgICBkZXNjcmliZSgnc2V0T3B0aW9ucygpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgIFsnc2hhZG93TW9kZScsICd4MSddLFxuICAgICAgICAgICAgICAgIFsndGVtcGxhdGVzLm1haW4nLCAneDInXSwgLy8gaXMgZXhwbGljaXRseSBzZXQgdG8gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgWydkZWxlZ2F0ZXNGb2N1cycsICd4NCddLFxuICAgICAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cblxuICAgICAgICAgICAgICAgIGxldCBrZXkgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgICAgICBsZXQgbmV3VmFsdWUgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgICAgIGxldCB0ZXh0ID0ga2V5ICsgJyBzaG91bGQgcmV0dXJuICcgKyBuZXdWYWx1ZTtcbiAgICAgICAgICAgICAgICBpZiAobmV3VmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICB0ZXh0ID0ga2V5ICsgJyB3YXMgbm90IHNldCwgdGhlcmVmb3JlIGRlZmF1bHQgJyArIG5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgIH1cblxuXG4gICAgICAgICAgICAgICAgaXQodGV4dCwgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICAgICAgICAgIGxldCBkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbW9uc3Rlci10ZXN0Y2xhc3MnKTtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KGQuZ2V0T3B0aW9uKGtleSkpLnRvLmJlLm5vdC5lcXVhbChuZXdWYWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIGxldCB4ID0gZC5zZXRPcHRpb24oa2V5LCBuZXdWYWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChkLmdldE9wdGlvbihrZXkpKS50by5iZS5lcXVhbChuZXdWYWx1ZSk7XG4gICAgICAgICAgICAgICAgfSlcblxuXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KTtcblxuICAgICAgICBkZXNjcmliZSgnZ2V0T3B0aW9ucygpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgWydzaGFkb3dNb2RlJywgJ29wZW4nXSxcbiAgICAgICAgICAgICAgICBbJ3RlbXBsYXRlcy5tYWluJywgdW5kZWZpbmVkXSwgLy8gaXMgZXhwbGljaXRseSBzZXQgdG8gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgWydkZWxlZ2F0ZXNGb2N1cycsIHRydWVdLFxuICAgICAgICAgICAgICAgIFsneC55LnonLCB0cnVlLCB0cnVlXSwgLy8geC55LnogaXNudCBzZXQsIGRlZmF1bHRWYWx1ZSBpcyB1c2VkXG4gICAgICAgICAgICAgICAgWyd4JywgdHJ1ZSwgdHJ1ZV0gLy8geCBpc250IHNldCwgZGVmYXVsdFZhbHVlIGlzIHVzZWRcbiAgICAgICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG5cbiAgICAgICAgICAgICAgICBsZXQga2V5ID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICAgICAgbGV0IHZhbHVlID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICAgICAgbGV0IGRlZmF1bHRWYWx1ZSA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICAgICAgbGV0IHRleHQgPSBrZXkgKyAnIHNob3VsZCByZXR1cm4gJyArIHZhbHVlO1xuICAgICAgICAgICAgICAgIGlmIChkZWZhdWx0VmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICB0ZXh0ID0ga2V5ICsgJyB3YXMgbm90IHNldCwgdGhlcmVmb3JlIGRlZmF1bHQgJyArIGRlZmF1bHRWYWx1ZTtcbiAgICAgICAgICAgICAgICB9XG5cblxuICAgICAgICAgICAgICAgIGl0KHRleHQsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgICAgICBsZXQgZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ21vbnN0ZXItdGVzdGNsYXNzJyk7XG4gICAgICAgICAgICAgICAgICAgIGxldCB4ID0gZC5nZXRPcHRpb24oa2V5LCBkZWZhdWx0VmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QoeCkudG8uYmUuZXF1YWwodmFsdWUpO1xuICAgICAgICAgICAgICAgIH0pXG5cblxuICAgICAgICAgICAgfSlcbiAgICAgICAgfSlcblxuICAgICAgICAvKipcbiAgICAgICAgICogQGxpbmsgaHR0cHM6Ly9naXRsYWIuc2NodWthaS5jb20vb3NzL2xpYnJhcmllcy9qYXZhc2NyaXB0L21vbnN0ZXIvLS9pc3N1ZXMvMTEzXG4gICAgICAgICAqL1xuICAgICAgICBkZXNjcmliZSgnQXNzaWduIENTU1N0eWxlIGFzIEFycmF5IHdpdGggd3JvbmcgdHlwZScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgY29uc3QgaHRtbFRBRyA9ICdtb25zdGVyLXRlc3RjbGFzcy14MSc7XG5cbiAgICAgICAgICAgIGxldCBtb2NrcywgVGVzdENvbXBvbmVudFgxO1xuICAgICAgICAgICAgYmVmb3JlRWFjaCgoKSA9PiB7XG5cbiAgICAgICAgICAgICAgICBtb2NrcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpO1xuICAgICAgICAgICAgICAgIG1vY2tzLmlubmVySFRNTCA9IGh0bWwxO1xuXG5cbiAgICAgICAgICAgICAgICBUZXN0Q29tcG9uZW50WDEgPSBjbGFzcyBleHRlbmRzIEN1c3RvbUVsZW1lbnQge1xuICAgICAgICAgICAgICAgICAgICBzdGF0aWMgZ2V0VGFnKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGh0bWxUQUdcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHN0YXRpYyBnZXRDU1NTdHlsZVNoZWV0KCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFt0cnVlXTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICAgICAgICAgKiBAcmV0dXJuIHtPYmplY3R9XG4gICAgICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgICAgICBnZXQgZGVmYXVsdHMoKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdXBlci5kZWZhdWx0cywge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBsYXRlczoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYWluOiAnPGgxPnRlc3Q8L2gxPidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmVnaXN0ZXJDdXN0b21FbGVtZW50KFRlc3RDb21wb25lbnRYMSlcblxuXG4gICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICBpdChodG1sVEFHICsgXCIgc2hvdWxkIHRocm93IEV4Y2VwdGlvblwiLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICAgICAgICAgIGxldCBkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChodG1sVEFHKTtcblxuICAgICAgICAgICAgICAgIGxldCBkaXYgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGVzdDEnKTtcbiAgICAgICAgICAgICAgICBkaXYuYXBwZW5kKGQpO1xuXG5cbiAgICAgICAgICAgICAgICBleHBlY3QoZGl2KS5jb250YWluLmh0bWwoJ2RhdGEtbW9uc3Rlci1lcnJvcj1cIlR5cGVFcnJvcjogdmFsdWUgaXMgbm90IGFuIGluc3RhbmNlIG9mIENTU1N0eWxlU2hlZXRcIicpO1xuICAgICAgICAgICAgICAgIGRvbmUoKTtcblxuICAgICAgICAgICAgfSlcblxuXG4gICAgICAgIH0pXG5cblxuICAgICAgICAvKipcbiAgICAgICAgICogQGxpbmsgaHR0cHM6Ly9naXRsYWIuc2NodWthaS5jb20vb3NzL2xpYnJhcmllcy9qYXZhc2NyaXB0L21vbnN0ZXIvLS9pc3N1ZXMvMTEzXG4gICAgICAgICAqL1xuICAgICAgICBkZXNjcmliZSgnQXNzaWduIENTU1N0eWxlIGFzIEFycmF5IGFuZCBDU1NTdHlsZXNoZWV0JywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBjb25zdCBodG1sVEFHID0gJ21vbnN0ZXItdGVzdGNsYXNzLXgxMTMtMic7XG5cbiAgICAgICAgICAgIGxldCBtb2NrcywgVGVzdENvbXBvbmVudFgxMTNYMjtcbiAgICAgICAgICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuXG4gICAgICAgICAgICAgICAgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgICAgICAgICBtb2Nrcy5pbm5lckhUTUwgPSBodG1sMTtcblxuICAgICAgICAgICAgICAgIFRlc3RDb21wb25lbnRYMTEzWDIgPSBjbGFzcyBleHRlbmRzIEN1c3RvbUVsZW1lbnQge1xuICAgICAgICAgICAgICAgICAgICBzdGF0aWMgZ2V0VGFnKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGh0bWxUQUdcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICAgICAgICAgKiBAcmV0dXJuIHtPYmplY3R9XG4gICAgICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgICAgICBnZXQgZGVmYXVsdHMoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3VwZXIuZGVmYXVsdHMsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wbGF0ZXM6IHttYWluOiAnPGgxPnRlc3Q8L2gxPid9LFxuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgfVxuXG5cbiAgICAgICAgICAgICAgICAgICAgc3RhdGljIGdldENTU1N0eWxlU2hlZXQoKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHMgPSAobmV3IENTU1N0eWxlU2hlZXQoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHMuaW5zZXJ0UnVsZSgnYSB7IGNvbG9yIDogcmVkfScpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gW3NdO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmVnaXN0ZXJDdXN0b21FbGVtZW50KFRlc3RDb21wb25lbnRYMTEzWDIpXG5cblxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgaXQoaHRtbFRBRyArIFwiIHNob3VsZCB0aHJvdyBFeGNlcHRpb24gMlwiLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICAgICAgICAgIGxldCBkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChodG1sVEFHKTtcblxuICAgICAgICAgICAgICAgIGxldCBkaXYgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGVzdDEnKTtcbiAgICAgICAgICAgICAgICBkaXYuYXBwZW5kKGQpO1xuXG4gICAgICAgICAgICAgICAgZXhwZWN0KGQuc2hhZG93Um9vdC5pbm5lckhUTUwpLmlzLmVxKCc8aDE+dGVzdDwvaDE+Jyk7XG4gICAgICAgICAgICAgICAgZG9uZSgpO1xuXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAbGluayBodHRwczovL2dpdGxhYi5zY2h1a2FpLmNvbS9vc3MvbGlicmFyaWVzL2phdmFzY3JpcHQvbW9uc3Rlci8tL2lzc3Vlcy8xMTNcbiAgICAgICAgICovXG4gICAgICAgIGRlc2NyaWJlKCdBc3NpZ24gQ1NTU3R5bGUgYXMgQXJyYXkgYW5kIENTUyBhcyBzdHJpbmcnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIGNvbnN0IGh0bWxUQUcgPSAnbW9uc3Rlci10ZXN0Y2xhc3MteDExMy0yMSc7XG5cbiAgICAgICAgICAgIGxldCBtb2NrcywgVGVzdENvbXBvbmVudFgxMTNYMjI7XG4gICAgICAgICAgICBiZWZvcmVFYWNoKCgpID0+IHtcblxuICAgICAgICAgICAgICAgIG1vY2tzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vY2tzJyk7XG4gICAgICAgICAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gaHRtbDE7XG5cbiAgICAgICAgICAgICAgICBUZXN0Q29tcG9uZW50WDExM1gyMiA9IGNsYXNzIGV4dGVuZHMgQ3VzdG9tRWxlbWVudCB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXRpYyBnZXRUYWcoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaHRtbFRBR1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgICAgICAgICAqIEByZXR1cm4ge09iamVjdH1cbiAgICAgICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgICAgIGdldCBkZWZhdWx0cygpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdXBlci5kZWZhdWx0cywge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBsYXRlczoge21haW46ICc8aDE+dGVzdDwvaDE+J30sXG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICB9XG5cblxuICAgICAgICAgICAgICAgICAgICBzdGF0aWMgZ2V0Q1NTU3R5bGVTaGVldCgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAnYSB7IGNvbG9yOnJlZCB9JztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJlZ2lzdGVyQ3VzdG9tRWxlbWVudChUZXN0Q29tcG9uZW50WDExM1gyMilcblxuXG4gICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICBpdChodG1sVEFHICsgXCIgc2hvdWxkIGVxIDxzdHlsZT5hIHsgY29sb3I6cmVkIH08L3N0eWxlPjxoMT50ZXN0PC9oMT5cIiwgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgICAgICAgICBsZXQgZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoaHRtbFRBRyk7XG5cbiAgICAgICAgICAgICAgICBsZXQgZGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Rlc3QxJyk7XG4gICAgICAgICAgICAgICAgZGl2LmFwcGVuZChkKTtcblxuXG4gICAgICAgICAgICAgICAgZXhwZWN0KGQuc2hhZG93Um9vdC5pbm5lckhUTUwpLmlzLmVxKCc8c3R5bGU+YSB7IGNvbG9yOnJlZCB9PC9zdHlsZT48aDE+dGVzdDwvaDE+Jyk7XG4gICAgICAgICAgICAgICAgZG9uZSgpO1xuXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KVxuICAgICAgICAvKipcbiAgICAgICAgICogQGxpbmsgaHR0cHM6Ly9naXRsYWIuc2NodWthaS5jb20vb3NzL2xpYnJhcmllcy9qYXZhc2NyaXB0L21vbnN0ZXIvLS9pc3N1ZXMvMTEzXG4gICAgICAgICAqL1xuICAgICAgICBkZXNjcmliZSgnQXNzaWduIENTU1N0eWxlIGFzIEFycmF5IGFuZCBDU1MgYXMgc3RyaW5nJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBjb25zdCBodG1sVEFHID0gJ21vbnN0ZXItdGVzdGNsYXNzLXgxMTMtMjInO1xuXG4gICAgICAgICAgICBsZXQgbW9ja3MsIFRlc3RDb21wb25lbnRYMTEzWDIyMztcbiAgICAgICAgICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuXG4gICAgICAgICAgICAgICAgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgICAgICAgICBtb2Nrcy5pbm5lckhUTUwgPSBodG1sMTtcblxuICAgICAgICAgICAgICAgIFRlc3RDb21wb25lbnRYMTEzWDIyMyA9IGNsYXNzIGV4dGVuZHMgQ3VzdG9tRWxlbWVudCB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXRpYyBnZXRUYWcoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaHRtbFRBR1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgICAgICAgICAqIEByZXR1cm4ge09iamVjdH1cbiAgICAgICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgICAgIGdldCBkZWZhdWx0cygpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdXBlci5kZWZhdWx0cywge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBsYXRlczoge21haW46ICc8aDE+dGVzdDwvaDE+J30sXG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICB9XG5cblxuICAgICAgICAgICAgICAgICAgICBzdGF0aWMgZ2V0Q1NTU3R5bGVTaGVldCgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbJ2EgeyBjb2xvcjpyZWQgfSddO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmVnaXN0ZXJDdXN0b21FbGVtZW50KFRlc3RDb21wb25lbnRYMTEzWDIyMylcblxuXG4gICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICBpdChodG1sVEFHICsgXCIgc2hvdWxkIGVxIDxzdHlsZT5hIHsgY29sb3I6cmVkIH08L3N0eWxlPjxoMT50ZXN0PC9oMT5cIiwgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgICAgICAgICBsZXQgZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoaHRtbFRBRyk7XG5cbiAgICAgICAgICAgICAgICBsZXQgZGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Rlc3QxJyk7XG4gICAgICAgICAgICAgICAgZGl2LmFwcGVuZChkKTtcblxuXG4gICAgICAgICAgICAgICAgZXhwZWN0KGQuc2hhZG93Um9vdC5pbm5lckhUTUwpLmlzLmVxKCc8c3R5bGU+YSB7IGNvbG9yOnJlZCB9PC9zdHlsZT48aDE+dGVzdDwvaDE+Jyk7XG4gICAgICAgICAgICAgICAgZG9uZSgpO1xuXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KVxuXG4gICAgICAgIGRlc2NyaWJlKCdoYXNOb2RlKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIGxldCBtb2NrcztcbiAgICAgICAgICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuXG4gICAgICAgICAgICAgICAgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgICAgICAgICBtb2Nrcy5pbm5lckhUTUwgPSBodG1sMTtcblxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgaXQoXCJoYXNOb2RlIG1vbnN0ZXItdGVzdGNsYXNzIHNob3VsZCByZXR1cm4gLi4uXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBsZXQgZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ21vbnN0ZXItdGVzdGNsYXNzJyk7XG5cbiAgICAgICAgICAgICAgICBsZXQgcDEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdwJyk7XG4gICAgICAgICAgICAgICAgbGV0IHQxID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoJ3Rlc3QxJyk7XG4gICAgICAgICAgICAgICAgcDEuYXBwZW5kQ2hpbGQodDEpO1xuXG4gICAgICAgICAgICAgICAgbGV0IHAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgICAgICBsZXQgdCA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCd0ZXN0Jyk7XG4gICAgICAgICAgICAgICAgcC5hcHBlbmRDaGlsZChwMSk7XG4gICAgICAgICAgICAgICAgcC5hcHBlbmRDaGlsZCh0KTtcbiAgICAgICAgICAgICAgICBkLmFwcGVuZENoaWxkKHApO1xuXG4gICAgICAgICAgICAgICAgbGV0IGRpdiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0ZXN0MScpO1xuICAgICAgICAgICAgICAgIGRpdi5hcHBlbmQoZCk7XG5cblxuICAgICAgICAgICAgICAgIGxldCBuMSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3AnKTtcblxuICAgICAgICAgICAgICAgIGV4cGVjdChkLmhhc05vZGUobjEpKS50by5iZS5mYWxzZTtcbiAgICAgICAgICAgICAgICBleHBlY3QoZC5oYXNOb2RlKHQpKS50by5iZS50cnVlO1xuICAgICAgICAgICAgICAgIGV4cGVjdChkLmhhc05vZGUocCkpLnRvLmJlLnRydWU7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGQuaGFzTm9kZShwMSkpLnRvLmJlLnRydWU7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGQuaGFzTm9kZSh0MSkpLnRvLmJlLnRydWU7XG5cbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGl0KFwiaGFzTm9kZSBtb25zdGVyLXRlc3RjbGFzczIgc2hvdWxkIHJldHVybiAuLi5cIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGxldCBkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbW9uc3Rlci10ZXN0Y2xhc3MyJyk7XG5cbiAgICAgICAgICAgICAgICBsZXQgcDEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdwJyk7XG4gICAgICAgICAgICAgICAgbGV0IHQxID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoJ3Rlc3QxJyk7XG4gICAgICAgICAgICAgICAgcDEuYXBwZW5kQ2hpbGQodDEpO1xuXG4gICAgICAgICAgICAgICAgbGV0IHAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgICAgICBsZXQgdCA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCd0ZXN0Jyk7XG4gICAgICAgICAgICAgICAgcC5hcHBlbmRDaGlsZChwMSk7XG4gICAgICAgICAgICAgICAgcC5hcHBlbmRDaGlsZCh0KTtcblxuXG4gICAgICAgICAgICAgICAgbGV0IGRpdiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0ZXN0MScpO1xuICAgICAgICAgICAgICAgIGRpdi5hcHBlbmQoZCk7XG5cbiAgICAgICAgICAgICAgICBsZXQgYSA9IGQuc2hhZG93Um9vdC5nZXRFbGVtZW50QnlJZCgnY29udGFpbmVyJyk7XG5cbiAgICAgICAgICAgICAgICBkLnNoYWRvd1Jvb3QuZ2V0RWxlbWVudEJ5SWQoJ2NvbnRhaW5lcicpLmFwcGVuZENoaWxkKHApO1xuXG4gICAgICAgICAgICAgICAgbGV0IG4xID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgncCcpO1xuXG4gICAgICAgICAgICAgICAgZXhwZWN0KGQuaGFzTm9kZShuMSkpLnRvLmJlLmZhbHNlO1xuICAgICAgICAgICAgICAgIGV4cGVjdChkLmhhc05vZGUodCkpLnRvLmJlLnRydWU7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGQuaGFzTm9kZShwKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgICAgICAgICBleHBlY3QoZC5oYXNOb2RlKHAxKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgICAgICAgICBleHBlY3QoZC5oYXNOb2RlKHQxKSkudG8uYmUudHJ1ZTtcblxuICAgICAgICAgICAgfSlcblxuXG4gICAgICAgIH0pXG5cbiAgICB9KTtcbn0pIiwgIlxuaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcblxuaW1wb3J0IHtcbiAgICBhZGRBdHRyaWJ1dGVUb2tlbixcbiAgICBhZGRUb09iamVjdExpbmssXG4gICAgY2xlYXJBdHRyaWJ1dGVUb2tlbnMsXG4gICAgY29udGFpbnNBdHRyaWJ1dGVUb2tlbixcbiAgICBmaW5kQ2xvc2VzdEJ5QXR0cmlidXRlLFxuICAgIGZpbmRDbG9zZXN0T2JqZWN0TGluayxcbiAgICBnZXRMaW5rZWRPYmplY3RzLFxuICAgIGhhc09iamVjdExpbmssXG4gICAgcmVtb3ZlQXR0cmlidXRlVG9rZW4sXG4gICAgcmVtb3ZlT2JqZWN0TGluayxcbiAgICByZXBsYWNlQXR0cmlidXRlVG9rZW4sXG4gICAgdG9nZ2xlQXR0cmlidXRlVG9rZW4sXG4gICAgZmluZENsb3Nlc3RCeUNsYXNzXG59IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvZG9tL2F0dHJpYnV0ZXMubWpzXCI7XG5cbmltcG9ydCB7aW5pdEpTRE9NfSBmcm9tIFwiLi4vLi4vdXRpbC9qc2RvbS5tanNcIjtcblxubGV0IGh0bWwxLCBodG1sMiwgaHRtbDM7XG5cbmRlc2NyaWJlKCdBdHRyaWJ1dGVzJywgZnVuY3Rpb24gKCkge1xuICAgIGJlZm9yZShmdW5jdGlvbiAoZG9uZSkge1xuXG4gICAgICAgIGh0bWwxID0gYDxkaXYgaWQ9XCJ0ZXN0MVwiPjwvZGl2PmA7XG4gICAgICAgIGh0bWwyID0gYDxkaXYgaWQ9XCJ0ZXN0MVwiPlxuICAgIDxkaXYgaWQ9XCJzdWIxXCI+XG4gICAgICAgIDxkaXYgaWQ9XCJzdWIyXCI+XG4gICAgICAgICAgICA8ZGl2IGlkPVwic3ViM1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgaWQ9XCJzdWI0XCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgaWQ9XCJzdWI1XCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG48L2Rpdj5cbmA7XG4gICAgICAgIFxuICAgICAgICBodG1sMyA9IGA8ZGl2IGRhdGEtbW9uc3Rlci1yb2xlPVwidGVzdDFcIj5cbiAgICA8ZGl2IGRhdGEtbW9uc3Rlci1yb2xlPVwic3ViMVwiIGlkPVwiYTFcIiBjbGFzcz1cInN1YjFcIj5cbiAgICAgICAgPGRpdiBkYXRhLW1vbnN0ZXItcm9sZT1cInN1YjJcIiBpZD1cImEyXCIgY2xhc3M9XCJzdWIyXCI+XG4gICAgICAgICAgICA8ZGl2IGRhdGEtbW9uc3Rlci1yb2xlPVwic3ViM1wiIGlkPVwiYTNcIiBjbGFzcz1cInN1YjNcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGRhdGEtbW9uc3Rlci1yb2xlPVwic3ViNFwiIGlkPVwiYTRcIiBjbGFzcz1cInN1YjRcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBkYXRhLW1vbnN0ZXItcm9sZT1cInN1YjVcIiBpZD1cImE1XCIgY2xhc3M9XCJzdWI1XCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG48L2Rpdj5cbmA7XG5cblxuICAgICAgICBpbml0SlNET00oKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICB9KS5jYXRjaChlID0+IGRvbmUoZSkpO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ09iamVjdExpbmsnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgY29uc3Qgc3ltYm9sID0gU3ltYm9sKCdteXRlc3QnKTtcblxuICAgICAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAgICAgIGxldCBtb2NrcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpO1xuICAgICAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gaHRtbDE7XG4gICAgICAgIH0pXG5cbiAgICAgICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgICAgICAgIGxldCBtb2NrcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpO1xuICAgICAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gXCJcIjtcbiAgICAgICAgfSlcblxuICAgICAgICBpdCgnc2hvdWxkIGhhbmRsZSBvYmplY3QtbGlua3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgb2JqID0ge2E6IDF9O1xuICAgICAgICAgICAgbGV0IGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGVzdDEnKTtcbiAgICAgICAgICAgIGV4cGVjdChoYXNPYmplY3RMaW5rKGVsZW1lbnQsIHN5bWJvbCkpLnRvLmJlLmZhbHNlO1xuICAgICAgICAgICAgYWRkVG9PYmplY3RMaW5rKGVsZW1lbnQsIHN5bWJvbCwgb2JqKTtcbiAgICAgICAgICAgIGV4cGVjdChoYXNPYmplY3RMaW5rKGVsZW1lbnQsIHN5bWJvbCkpLnRvLmJlLnRydWU7XG5cbiAgICAgICAgICAgIGxldCBvID0gZ2V0TGlua2VkT2JqZWN0cyhlbGVtZW50LCBzeW1ib2wpLm5leHQoKTtcbiAgICAgICAgICAgIGV4cGVjdChvLnZhbHVlKS50by5lcXVhbChvYmopO1xuXG4gICAgICAgICAgICByZW1vdmVPYmplY3RMaW5rKGVsZW1lbnQsIHN5bWJvbCk7XG4gICAgICAgICAgICBleHBlY3QoaGFzT2JqZWN0TGluayhlbGVtZW50LCBzeW1ib2wpKS50by5iZS5mYWxzZTtcbiAgICAgICAgICAgIGV4cGVjdCgoKSA9PiBnZXRMaW5rZWRPYmplY3RzKGVsZW1lbnQsIHN5bWJvbCkpLnRvLnRocm93KEVycm9yKTtcbiAgICAgICAgfSlcblxuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnZmluZENsb3Nlc3RPYmplY3RMaW5rKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgY29uc3Qgc3ltYm9sID0gU3ltYm9sKCdteXRlc3QnKTtcblxuICAgICAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAgICAgIGxldCBtb2NrcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpO1xuICAgICAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gaHRtbDI7XG4gICAgICAgIH0pXG5cbiAgICAgICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgICAgICAgIGxldCBtb2NrcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpO1xuICAgICAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gXCJcIjtcbiAgICAgICAgfSlcblxuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBvYmplY3RsaW5rJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBsZXQgc3ViNCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzdWI0JylcbiAgICAgICAgICAgIGxldCBzdWIyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3N1YjInKVxuXG4gICAgICAgICAgICBsZXQgb2JqID0ge307XG5cbiAgICAgICAgICAgIGV4cGVjdChoYXNPYmplY3RMaW5rKHN1YjIsIHN5bWJvbCkpLnRvLmJlLmZhbHNlO1xuICAgICAgICAgICAgYWRkVG9PYmplY3RMaW5rKHN1YjIsIHN5bWJvbCwgb2JqKTtcbiAgICAgICAgICAgIGV4cGVjdChoYXNPYmplY3RMaW5rKHN1YjIsIHN5bWJvbCkpLnRvLmJlLnRydWU7XG5cbiAgICAgICAgICAgIGxldCBlbGVtZW50ID0gZmluZENsb3Nlc3RPYmplY3RMaW5rKHN1YjQpO1xuICAgICAgICAgICAgZXhwZWN0KGVsZW1lbnQpLmlzLmluc3RhbmNlT2YoSFRNTERpdkVsZW1lbnQpO1xuICAgICAgICAgICAgZXhwZWN0KGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdpZCcpKS50by5iZS5lcXVhbCgnc3ViMicpO1xuXG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnQXR0cmlidXRlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICAgICAgICBsZXQgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgICAgIG1vY2tzLmlubmVySFRNTCA9IGh0bWwzO1xuICAgICAgICB9KVxuXG4gICAgICAgIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICAgICAgICBsZXQgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgICAgIG1vY2tzLmlubmVySFRNTCA9IFwiXCI7XG4gICAgICAgIH0pXG5cbiAgICAgICAgZGVzY3JpYmUoJ2ZpbmQgY2xvc2VzdCBBdHRyaWJ1dGVzJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgWydhNScsICdkYXRhLW1vbnN0ZXItcm9sZScsIHVuZGVmaW5lZCwgJ3N1YjUnXSxcbiAgICAgICAgICAgICAgICBbJ2E1JywgJ2RhdGEtbW9uc3Rlci1yb2xlJywgJ3N1YjMnLCAnc3ViMyddLFxuICAgICAgICAgICAgICAgIFsnYTUnLCAnZGF0YS1tb25zdGVyLXJvbGUnLCAnc3ViMScsICdzdWIxJ10sXG4gICAgICAgICAgICAgICAgWydhNCcsICdkYXRhLW1vbnN0ZXItcm9sZScsICdzdWIxJywgJ3N1YjEnXSxcbiAgICAgICAgICAgICAgICBbJ2EzJywgJ2RhdGEtbW9uc3Rlci1yb2xlJywgJ3N1YjEnLCAnc3ViMSddLFxuICAgICAgICAgICAgICAgIFsnYTInLCAnZGF0YS1tb25zdGVyLXJvbGUnLCB1bmRlZmluZWQsICdzdWIyJ10sXG4gICAgICAgICAgICAgICAgWydhNScsICdkYXRhLW1vbnN0ZXItcm9sZScsICdzdWI1JywgJ3N1YjUnXVxuICAgICAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICAgICAgbGV0IGMgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgICAgICBsZXQgZCA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICAgICAgaXQoJ2ZpbmRDbG9zZXN0QnlBdHRyaWJ1dGUoJyArIGEgKyAnLCAnICsgYiArICcsJyArIGMgKyAnKSBzaG91bGQgcmV0dXJuICcgKyBkLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChmaW5kQ2xvc2VzdEJ5QXR0cmlidXRlKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGEpLCBiLCBjKS5nZXRBdHRyaWJ1dGUoJ2RhdGEtbW9uc3Rlci1yb2xlJykpLnRvLmJlLmVxdWFsKGQpO1xuICAgICAgICAgICAgICAgIH0pXG5cblxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pOyBcbiAgICAgICAgXG4gICAgICAgIGRlc2NyaWJlKCdmaW5kIGNsb3Nlc3QgRWxlbWVudCB3aXRoIGNsYXNzJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgWydhNScsICAnc3ViMycsICdzdWIzJ10sXG4gICAgICAgICAgICAgICAgWydhNScsICAnc3ViMScsICdzdWIxJ10sXG4gICAgICAgICAgICAgICAgWydhNCcsICAnc3ViMScsICdzdWIxJ10sXG4gICAgICAgICAgICAgICAgWydhMycsICAnc3ViMScsICdzdWIxJ10sXG4gICAgICAgICAgICAgICAgWydhNScsICAnc3ViNScsICdzdWI1J11cbiAgICAgICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgICAgIGxldCBjID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICAgICAgaXQoJ2ZpbmRDbG9zZXN0QnlDbGFzcygnICsgYSArICcsICcgKyBiICsgJykgc2hvdWxkIHJldHVybiAnICsgYywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QoZmluZENsb3Nlc3RCeUNsYXNzKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGEpLCBiKS5nZXRBdHRyaWJ1dGUoJ2NsYXNzJykpLnRvLmJlLmVxdWFsKGMpO1xuICAgICAgICAgICAgICAgIH0pXG5cblxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ0F0dHJpYnV0ZXMnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICAgICAgICBsZXQgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgICAgIG1vY2tzLmlubmVySFRNTCA9IGh0bWwxO1xuICAgICAgICB9KVxuXG4gICAgICAgIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICAgICAgICBsZXQgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgICAgIG1vY2tzLmlubmVySFRNTCA9IFwiXCI7XG4gICAgICAgIH0pXG5cbiAgICAgICAgY29uc3QgYXRyaWJ1dGVLZXkgPSAnZGF0YS10ZXN0JztcblxuICAgICAgICBpdCgndG9nZ2xlQXR0cmlidXRlVG9rZW4oZWxlbWVudCwga2V5LCB2YWx1ZSknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0ZXN0MScpO1xuICAgICAgICAgICAgZXhwZWN0KGVsZW1lbnQuaGFzQXR0cmlidXRlKGF0cmlidXRlS2V5KSkudG8uYmUuZmFsc2U7XG4gICAgICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShhdHJpYnV0ZUtleSwgJ2FwcGxlIGJhbmFubmEnKVxuICAgICAgICAgICAgdG9nZ2xlQXR0cmlidXRlVG9rZW4oZWxlbWVudCwgYXRyaWJ1dGVLZXksICdwaW5hcHBsZScpO1xuICAgICAgICAgICAgZXhwZWN0KGVsZW1lbnQuZ2V0QXR0cmlidXRlKGF0cmlidXRlS2V5KSkudG8uYmUuZXF1YWwoJ2FwcGxlIGJhbmFubmEgcGluYXBwbGUnKTtcbiAgICAgICAgICAgIHRvZ2dsZUF0dHJpYnV0ZVRva2VuKGVsZW1lbnQsIGF0cmlidXRlS2V5LCAncGluYXBwbGUnKTtcbiAgICAgICAgICAgIGV4cGVjdChlbGVtZW50LmdldEF0dHJpYnV0ZShhdHJpYnV0ZUtleSkpLnRvLmJlLmVxdWFsKCdhcHBsZSBiYW5hbm5hJyk7XG4gICAgICAgIH0pXG5cbiAgICAgICAgaXQoJ2FkZEF0dHJpYnV0ZVRva2VuKGVsZW1lbnQsIGtleSwgdmFsdWUpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGV0IGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGVzdDEnKTtcbiAgICAgICAgICAgIGV4cGVjdChlbGVtZW50Lmhhc0F0dHJpYnV0ZShhdHJpYnV0ZUtleSkpLnRvLmJlLmZhbHNlO1xuICAgICAgICAgICAgYWRkQXR0cmlidXRlVG9rZW4oZWxlbWVudCwgYXRyaWJ1dGVLZXksICdwaW5hcHBsZScpO1xuICAgICAgICAgICAgZXhwZWN0KGVsZW1lbnQuZ2V0QXR0cmlidXRlKGF0cmlidXRlS2V5KSkudG8uYmUuZXF1YWwoJ3BpbmFwcGxlJyk7XG4gICAgICAgICAgICBhZGRBdHRyaWJ1dGVUb2tlbihlbGVtZW50LCBhdHJpYnV0ZUtleSwgJ2JhbmFubmEnKTtcbiAgICAgICAgICAgIGV4cGVjdChlbGVtZW50LmdldEF0dHJpYnV0ZShhdHJpYnV0ZUtleSkpLnRvLmJlLmVxdWFsKCdwaW5hcHBsZSBiYW5hbm5hJyk7XG4gICAgICAgIH0pXG5cbiAgICAgICAgaXQoJ3JlbW92ZUF0dHJpYnV0ZVRva2VuKGVsZW1lbnQsIGtleSwgdmFsdWUpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGV0IGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGVzdDEnKTtcbiAgICAgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKGF0cmlidXRlS2V5LCAnYXBwbGUgYmFuYW5uYSBsZW1tb24nKVxuICAgICAgICAgICAgcmVtb3ZlQXR0cmlidXRlVG9rZW4oZWxlbWVudCwgYXRyaWJ1dGVLZXksICdwaW5hcHBsZScpO1xuICAgICAgICAgICAgZXhwZWN0KGVsZW1lbnQuZ2V0QXR0cmlidXRlKGF0cmlidXRlS2V5KSkudG8uYmUuZXF1YWwoJ2FwcGxlIGJhbmFubmEgbGVtbW9uJyk7XG4gICAgICAgICAgICByZW1vdmVBdHRyaWJ1dGVUb2tlbihlbGVtZW50LCBhdHJpYnV0ZUtleSwgJ2JhbmFubmEnKTtcbiAgICAgICAgICAgIGV4cGVjdChlbGVtZW50LmdldEF0dHJpYnV0ZShhdHJpYnV0ZUtleSkpLnRvLmJlLmVxdWFsKCdhcHBsZSBsZW1tb24nKTtcblxuICAgICAgICB9KVxuXG4gICAgICAgIGl0KCdjb250YWluc0F0dHJpYnV0ZVRva2VuKGVsZW1lbnQsIGtleSwgdmFsdWUpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGV0IGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGVzdDEnKTtcbiAgICAgICAgICAgIGV4cGVjdChjb250YWluc0F0dHJpYnV0ZVRva2VuKGVsZW1lbnQsIGF0cmlidXRlS2V5LCAncGluYXBwbGUnKSkudG8uYmUuZmFsc2U7XG4gICAgICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShhdHJpYnV0ZUtleSwgJ2FwcGxlIGJhbmFubmEnKVxuICAgICAgICAgICAgZXhwZWN0KGNvbnRhaW5zQXR0cmlidXRlVG9rZW4oZWxlbWVudCwgYXRyaWJ1dGVLZXksICdwaW5hcHBsZScpKS50by5iZS5mYWxzZTtcbiAgICAgICAgICAgIGV4cGVjdChjb250YWluc0F0dHJpYnV0ZVRva2VuKGVsZW1lbnQsIGF0cmlidXRlS2V5LCAnYmFuYW5uYScpKS50by5iZS50cnVlO1xuICAgICAgICAgICAgZXhwZWN0KGNvbnRhaW5zQXR0cmlidXRlVG9rZW4oZWxlbWVudCwgYXRyaWJ1dGVLZXksICdhcHBsZScpKS50by5iZS50cnVlO1xuXG4gICAgICAgIH0pXG5cbiAgICAgICAgaXQoJyByZXBsYWNlQXR0cmlidXRlVG9rZW4oZWxlbWVudCwga2V5LCB2YWx1ZSknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0ZXN0MScpO1xuICAgICAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoYXRyaWJ1dGVLZXksICdhcHBsZSBiYW5hbm5hIHRvbWF0bycpXG4gICAgICAgICAgICByZXBsYWNlQXR0cmlidXRlVG9rZW4oZWxlbWVudCwgYXRyaWJ1dGVLZXksICd0b21hdG8nLCAnbGVtbW9uJyk7XG4gICAgICAgICAgICBleHBlY3QoZWxlbWVudC5nZXRBdHRyaWJ1dGUoYXRyaWJ1dGVLZXkpKS50by5iZS5lcXVhbCgnYXBwbGUgYmFuYW5uYSBsZW1tb24nKTtcbiAgICAgICAgICAgIHJlcGxhY2VBdHRyaWJ1dGVUb2tlbihlbGVtZW50LCBhdHJpYnV0ZUtleSwgJ2JhbmFubmEnLCAncGVhcicpO1xuICAgICAgICAgICAgZXhwZWN0KGVsZW1lbnQuZ2V0QXR0cmlidXRlKGF0cmlidXRlS2V5KSkudG8uYmUuZXF1YWwoJ2FwcGxlIHBlYXIgbGVtbW9uJyk7XG4gICAgICAgIH0pXG5cbiAgICAgICAgaXQoJ2NsZWFyQXR0cmlidXRlVG9rZW5zKGVsZW1lbnQsIGtleSknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0ZXN0MScpO1xuICAgICAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoYXRyaWJ1dGVLZXksICdhcHBsZSBiYW5hbm5hJylcbiAgICAgICAgICAgIGNsZWFyQXR0cmlidXRlVG9rZW5zKGVsZW1lbnQsIGF0cmlidXRlS2V5KTtcbiAgICAgICAgICAgIGV4cGVjdChlbGVtZW50LmdldEF0dHJpYnV0ZShhdHJpYnV0ZUtleSkpLnRvLmJlLmVxdWFsKCcnKTtcblxuICAgICAgICB9KVxuXG5cbiAgICB9KVxufSkiLCAiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuXG5pbXBvcnQge2ZpcmVFdmVudCwgZmluZFRhcmdldEVsZW1lbnRGcm9tRXZlbnQsIGZpcmVDdXN0b21FdmVudH0gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9kb20vZXZlbnRzLm1qc1wiO1xuaW1wb3J0IHtpbml0SlNET019IGZyb20gXCIuLi8uLi91dGlsL2pzZG9tLm1qc1wiO1xuXG5kZXNjcmliZSgnRXZlbnRzJywgZnVuY3Rpb24gKCkge1xuXG4gICAgYmVmb3JlKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaW5pdEpTRE9NKCk7XG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCdmaW5kVGFyZ2V0RWxlbWVudEZyb21FdmVudCgpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdmaW5kIG9iamVjdCcsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICBsZXQgY29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBjb250YWluZXIuc2V0QXR0cmlidXRlKCdkYXRhLW1vbnN0ZXInLCAnaGVsbG8nKTtcbiAgICAgICAgICAgIGxldCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZChkaXYpO1xuICAgICAgICAgICAgZGl2LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgbGV0IGUgPSBmaW5kVGFyZ2V0RWxlbWVudEZyb21FdmVudChldmVudCwgJ2RhdGEtbW9uc3RlcicpO1xuICAgICAgICAgICAgICAgIGV4cGVjdChlLmdldEF0dHJpYnV0ZSgnZGF0YS1tb25zdGVyJykpLnRvLmJlLmVxdWFsKCdoZWxsbycpXG4gICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCk9PntcbiAgICAgICAgICAgICAgICBmaXJlRXZlbnQoZGl2LCAnY2xpY2snKTtcbiAgICAgICAgICAgIH0sMClcbiAgICAgICAgICAgIFxuICAgICAgICB9KTtcblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2ZpcmVFdmVudCgpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIGZpcmUgYSBjbGljayBldmVudCcsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICBsZXQgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBkaXYuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIGZpcmVFdmVudChkaXYsICdjbGljaycpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIGZpcmUgYSB0b3VjaCBldmVudCcsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICBsZXQgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBkaXYuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2gnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIGZpcmVFdmVudChkaXYsICd0b3VjaCcpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIGZpcmUgYSB0b3VjaCBldmVudCBvbiBjb2xsZWN0aW9uJywgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgICAgIGxldCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIGRpdi5hZGRFdmVudExpc3RlbmVyKCd0b3VjaCcsICgpID0+IHtcbiAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICBkaXYuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JykpO1xuICAgICAgICAgICAgbGV0IGNvbGxlY3Rpb24gPSBkaXYucXVlcnlTZWxlY3RvckFsbCgnZGl2Jyk7XG5cblxuICAgICAgICAgICAgZmlyZUV2ZW50KGNvbGxlY3Rpb24sICd0b3VjaCcpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIGZpcmUgYSB0b3VjaCBldmVudCcsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICBsZXQgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBkaXYuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2gnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgZGl2LmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpKTtcbiAgICAgICAgICAgIGxldCBjb2xsZWN0aW9uID0gZGl2LnF1ZXJ5U2VsZWN0b3JBbGwoJ2RpdicpO1xuXG5cbiAgICAgICAgICAgIGZpcmVFdmVudChjb2xsZWN0aW9uLCAndG91Y2gnKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdCgoKSA9PiBmaXJlRXZlbnQoe30sICd0b3VjaCcpKS50by50aHJvdyhFcnJvcik7XG4gICAgICAgICAgICBcbiAgICAgICAgfSk7XG4gICAgfSk7ICAgXG4gICAgXG4gICAgZGVzY3JpYmUoJ2ZpcmVDdXN0b21FdmVudCgpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIGZpcmUgYSBjbGljayBldmVudCcsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICBsZXQgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBkaXYuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIGZpcmVDdXN0b21FdmVudChkaXYsICdjbGljaycpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIGZpcmUgYSB0b3VjaCBldmVudCcsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICBsZXQgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBkaXYuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2gnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIGZpcmVDdXN0b21FdmVudChkaXYsICd0b3VjaCcpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIGZpcmUgYSB0b3VjaCBldmVudCBvbiBjb2xsZWN0aW9uMScsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICBsZXQgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBkaXYuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2gnLCAoZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmKGUuZGV0YWlsLmRldGFpbCE9PSdoZWxsbyB3b3JsZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgZG9uZSgnZXJyb3InKTsgICAgXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGRpdi5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKSk7XG4gICAgICAgICAgICBsZXQgY29sbGVjdGlvbiA9IGRpdi5xdWVyeVNlbGVjdG9yQWxsKCdkaXYnKTtcblxuICAgICAgICAgICAgZmlyZUN1c3RvbUV2ZW50KGNvbGxlY3Rpb24sICd0b3VjaCcsIFwiaGVsbG8gd29ybGRcIik7XG4gICAgICAgIH0pO1xuICAgICAgICBcbiAgICAgICAgaXQoJ3Nob3VsZCBmaXJlIGEgdG91Y2ggZXZlbnQgb24gY29sbGVjdGlvbjInLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICAgICAgbGV0IGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgZGl2LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoJywgKGUpID0+IHtcbiAgICAgICAgICAgICAgICBpZihlLmRldGFpbC5hIT09J2hlbGxvIHdvcmxkJykge1xuICAgICAgICAgICAgICAgICAgICBkb25lKCdlcnJvcicpOyAgICBcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgZGl2LmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpKTtcbiAgICAgICAgICAgIGxldCBjb2xsZWN0aW9uID0gZGl2LnF1ZXJ5U2VsZWN0b3JBbGwoJ2RpdicpO1xuXG4gICAgICAgICAgICBmaXJlQ3VzdG9tRXZlbnQoY29sbGVjdGlvbiwgJ3RvdWNoJywge2E6XCJoZWxsbyB3b3JsZFwifSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgZmlyZSBhIHRvdWNoIGV2ZW50JywgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgICAgIGxldCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIGRpdi5hZGRFdmVudExpc3RlbmVyKCd0b3VjaCcsICgpID0+IHtcbiAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICBkaXYuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JykpO1xuICAgICAgICAgICAgbGV0IGNvbGxlY3Rpb24gPSBkaXYucXVlcnlTZWxlY3RvckFsbCgnZGl2Jyk7XG5cblxuICAgICAgICAgICAgZmlyZUN1c3RvbUV2ZW50KGNvbGxlY3Rpb24sICd0b3VjaCcpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KCgpID0+IGZpcmVDdXN0b21FdmVudCh7fSwgJ3RvdWNoJykpLnRvLnRocm93KEVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cblxufSk7IiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgaW50ZXJuYWxTeW1ib2wgfSBmcm9tIFwiLi4vLi4vY29uc3RhbnRzLm1qc1wiO1xuaW1wb3J0IHsgQmFzZSB9IGZyb20gXCIuLi8uLi90eXBlcy9iYXNlLm1qc1wiO1xuaW1wb3J0IHsgZ2V0R2xvYmFsLCBnZXRHbG9iYWxGdW5jdGlvbiB9IGZyb20gXCIuLi8uLi90eXBlcy9nbG9iYWwubWpzXCI7XG5pbXBvcnQgeyBpc0Z1bmN0aW9uIH0gZnJvbSBcIi4uLy4uL3R5cGVzL2lzLm1qc1wiO1xuaW1wb3J0IHsgdmFsaWRhdGVJbnN0YW5jZSwgdmFsaWRhdGVTdHJpbmcgfSBmcm9tIFwiLi4vLi4vdHlwZXMvdmFsaWRhdGUubWpzXCI7XG5cbmV4cG9ydCB7IEZhY3RvcnkgfTtcblxuLyoqXG4gKiBBIGZhY3RvcnkgZm9yIGNyZWF0aW5nIHdvcmtlciBpbnN0YW5jZXMuXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNS4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NLldvcmtlclxuICogQHN1bW1hcnkgQSBzbWFsbCBmYWN0b3J5IHRvIGNyZWF0ZSB3b3JrZXJcbiAqL1xuY2xhc3MgRmFjdG9yeSBleHRlbmRzIEJhc2Uge1xuICAgIC8qKlxuICAgICAqXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXNbaW50ZXJuYWxTeW1ib2xdID0ge1xuICAgICAgICAgICAgd29ya2VyOiBuZXcgV2Vha01hcCgpLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSB3b3JrZXIgZnJvbSBhIFVSTFxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd8VVJMfSB1cmxcbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBtZXNzYWdlSGFuZGxlclxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGVycm9ySGFuZGxlclxuICAgICAqIEByZXR1cm4ge1dvcmtlcn1cbiAgICAgKi9cbiAgICBjcmVhdGVGcm9tVVJMID0gZnVuY3Rpb24gKHVybCwgbWVzc2FnZUhhbmRsZXIsIGVycm9ySGFuZGxlcikge1xuICAgICAgICBpZiAodXJsIGluc3RhbmNlb2YgVVJMKSB7XG4gICAgICAgICAgICB1cmwgPSB1cmwudG9TdHJpbmcoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHdvcmtlckNsYXNzID0gZ2V0R2xvYmFsRnVuY3Rpb24oXCJXb3JrZXJcIik7XG4gICAgICAgIHZhciB3b3JrZXIgPSBuZXcgd29ya2VyQ2xhc3ModmFsaWRhdGVTdHJpbmcodXJsKSk7XG5cbiAgICAgICAgaWYgKGlzRnVuY3Rpb24obWVzc2FnZUhhbmRsZXIpKSB7XG4gICAgICAgICAgICB3b3JrZXIub25tZXNzYWdlID0gKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgbWVzc2FnZUhhbmRsZXIuY2FsbCh3b3JrZXIsIGV2ZW50KTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNGdW5jdGlvbihlcnJvckhhbmRsZXIpKSB7XG4gICAgICAgICAgICB3b3JrZXIub25lcnJvciA9IChldmVudCkgPT4ge1xuICAgICAgICAgICAgICAgIGVycm9ySGFuZGxlci5jYWxsKHdvcmtlciwgZXZlbnQpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB3b3JrZXI7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSB3b3JrZXIgZnJvbSBhIHNjcmlwdFxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGNvbnRlbnRcbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBtZXNzYWdlSGFuZGxlclxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGVycm9ySGFuZGxlclxuICAgICAqIEByZXR1cm4ge1dvcmtlcn1cbiAgICAgKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2RlL2RvY3MvV2ViL0FQSS9VUkwvY3JlYXRlT2JqZWN0VVJMXG4gICAgICovXG4gICAgY3JlYXRlRnJvbVNjcmlwdCA9IGZ1bmN0aW9uIChjb250ZW50LCBtZXNzYWdlSGFuZGxlciwgZXJyb3JIYW5kbGVyKSB7XG4gICAgICAgIGNvbnN0IGJsb2JGdW5jdGlvbiA9IG5ldyBnZXRHbG9iYWxGdW5jdGlvbihcIkJsb2JcIik7XG4gICAgICAgIGNvbnN0IGJsb2IgPSBuZXcgYmxvYkZ1bmN0aW9uKFt2YWxpZGF0ZVN0cmluZyhjb250ZW50KV0sIHtcbiAgICAgICAgICAgIHR5cGU6IFwic2NyaXB0L2phdmFzY3JpcHRcIixcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgdXJsID0gZ2V0R2xvYmFsRnVuY3Rpb24oXCJVUkxcIikuY3JlYXRlT2JqZWN0VVJMKGJsb2IpO1xuICAgICAgICBjb25zdCB3b3JrZXIgPSB0aGlzLmNyZWF0ZUZyb21VUkwodXJsLCBtZXNzYWdlSGFuZGxlciwgZXJyb3JIYW5kbGVyKTtcblxuICAgICAgICB0aGlzW2ludGVybmFsU3ltYm9sXVtcIndvcmtlclwiXS5zZXQod29ya2VyLCB1cmwpO1xuXG4gICAgICAgIHJldHVybiB3b3JrZXI7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFRlcm1pbmF0ZSB0aGUgd29ya2VyIGFuZCBjYWxsIHJldm9rZU9iamVjdFVSTCBpZiBuZWNlc3NhcnkuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gd29ya2VyXG4gICAgICogQHJldHVybiB7TW9uc3Rlci5ET00uV29ya2VyLkZhY3Rvcnl9XG4gICAgICovXG4gICAgdGVybWluYXRlKHdvcmtlcikge1xuICAgICAgICBjb25zdCB3b3JrZXJDbGFzcyA9IGdldEdsb2JhbEZ1bmN0aW9uKFwiV29ya2VyXCIpO1xuICAgICAgICB2YWxpZGF0ZUluc3RhbmNlKHdvcmtlciwgd29ya2VyQ2xhc3MpO1xuXG4gICAgICAgIHdvcmtlci50ZXJtaW5hdGUoKTtcblxuICAgICAgICBpZiAodGhpc1tpbnRlcm5hbFN5bWJvbF1bXCJ3b3JrZXJcIl0uaGFzKHdvcmtlcikpIHtcbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHRoaXNbaW50ZXJuYWxTeW1ib2xdW1wid29ya2VyXCJdLmdldCh3b3JrZXIpO1xuICAgICAgICAgICAgVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuIiwgImltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5cbmltcG9ydCB7RmFjdG9yeX0gZnJvbSBcIi4uLy4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9kb20vd29ya2VyL2ZhY3RvcnkubWpzXCI7XG5pbXBvcnQge2dldEdsb2JhbH0gZnJvbSBcIi4uLy4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS90eXBlcy9nbG9iYWwubWpzXCI7XG5pbXBvcnQge2luaXRKU0RPTSwgaXNOb2RlfSBmcm9tIFwiLi4vLi4vLi4vdXRpbC9qc2RvbS5tanNcIjtcblxuY29uc3QgZ2xvYmFsID0gZ2V0R2xvYmFsKCk7XG5cbmRlc2NyaWJlKCdXb3JrZXInLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBiZWZvcmUoZnVuY3Rpb24gKGRvbmUpIHtcblxuICAgICAgICBpZiAoaXNOb2RlKCkpIHtcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShnbG9iYWxbJ1VSTCddLCAnY3JlYXRlT2JqZWN0VVJMJywge1xuICAgICAgICAgICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIHZhbHVlOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcIi9leGFtcGxlLm1qc1wiXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgZ2xvYmFsWydXb3JrZXInXSA9IGNsYXNzIHtcbiAgICAgICAgICAgICAgICB0ZXJtaW5hdGUoKSB7XG4gICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIG9uZXJyb3IoKSB7XG4gICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIG9ubWVzc2FnZSgpIHtcbiAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgYSA9IHR5cGVvZiBnbG9iYWxbJ1dvcmtlciddO1xuICAgICAgICAgICAgbGV0IGExID0gdHlwZW9mIFdvcmtlcjtcblxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QganNkb20gPSBpbml0SlNET00oKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgfSk7XG5cblxuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnRmFjdG9yeScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBpdCgnY3JlYXRlIHdvcmtlcicsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgY29uc3QgZmFjdG9yeSA9IG5ldyBGYWN0b3J5KCk7XG4gICAgICAgICAgICBjb25zdCB3b3JrZXIgPSBmYWN0b3J5LmNyZWF0ZUZyb21TY3JpcHQoJ2NvbnNvbGUubG9nKFwiaGVsbG8gd29ybGRcIik7JylcbiAgICAgICAgICAgIGV4cGVjdCh3b3JrZXIpLmlzLmluc3RhbmNlb2YoV29ya2VyKTtcblxuICAgICAgICAgICAgZXhwZWN0KGZhY3RvcnkudGVybWluYXRlKHdvcmtlcikpLmlzLmluc3RhbmNlb2YoRmFjdG9yeSlcblxuXG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cblxufSk7IiwgIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7QVRUUklCVVRFX1RIRU1FX05BTUV9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvZG9tL2NvbnN0YW50cy5tanNcIjtcblxuaW1wb3J0IHtmaW5kRG9jdW1lbnRUZW1wbGF0ZSwgVGVtcGxhdGV9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvZG9tL3RlbXBsYXRlLm1qc1wiO1xuaW1wb3J0IHtpbml0SlNET019IGZyb20gXCIuLi8uLi91dGlsL2pzZG9tLm1qc1wiO1xuXG5cbmRlc2NyaWJlKCdUZW1wbGF0ZScsIGZ1bmN0aW9uICgpIHtcblxuICAgIGJlZm9yZShhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGluaXRKU0RPTSgpO1xuICAgIH0pXG5cbiAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAgbGV0IG1vY2tzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vY2tzJyk7XG4gICAgICAgIG1vY2tzLmlubmVySFRNTCA9IGBcbiAgICAgICAgICAgIDx0ZW1wbGF0ZSBpZD1cIm15dGVtcGxhdGVcIj48L3RlbXBsYXRlPmA7XG4gICAgfSlcblxuICAgIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICAgIGxldCBtb2NrcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpO1xuICAgICAgICBtb2Nrcy5pbm5lckhUTUwgPSBcIlwiO1xuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnY3JlYXRlIEhUTUxGcmFnbWVudCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgW1xuICAgICAgICAgICAgW1wiPGRpdj5maXJzdDwvZGl2PjxkaXY+c2Vjb25kPC9kaXY+XCJdLFxuICAgICAgICAgICAgW1wiPGRpdj5maXJzdDwvZGl2PlwiXSxcbiAgICAgICAgICAgIFtcIjxkaXY+Zmlyc3Q8L2Rpdj48cD5zZWNvbmQ8L3A+XCJdXG5cbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGl0KCduZXcgVGVtcGxhdGUoKS5nZXROZXdEb2N1bWVudEZyYWdtZW50QXNTdHJpbmcoKSBzaG91bGQgcmV0dXJuIHN0cmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBsZXQgdGVtcGxhdGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd0ZW1wbGF0ZScpO1xuICAgICAgICAgICAgICAgIHRlbXBsYXRlLmlubmVySFRNTCA9IGE7XG4gICAgICAgICAgICAgICAgbGV0IHQgPSBuZXcgVGVtcGxhdGUodGVtcGxhdGUpO1xuXG5cbiAgICAgICAgICAgICAgICB2YXIgY29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKHQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpKTtcbiAgICAgICAgICAgICAgICBleHBlY3QoY29udGFpbmVyLmlubmVySFRNTCkudG8uYmUuZXF1YWwoYSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnY3JlYXRlIGluc3RhbmNlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnbmV3IFRlbXBsYXRlKCkgc2hvdWxkIHJldHVybiBkb2N1bWVudCBvYmplY3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgZCA9IG5ldyBUZW1wbGF0ZShkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd0ZW1wbGF0ZScpKTtcbiAgICAgICAgICAgIGV4cGVjdChkKS50by5iZS5pbnN0YW5jZU9mKFRlbXBsYXRlKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnLmdldFRlbXBsYXRlRWxlbWVudCgpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnbmV3IFRlbXBsYXRlKCkuZ2V0VGVtcGxhdGVFbGVtZW50KCkgc2hvdWxkIHJldHVybiBIVE1MVGVtcGxhdGVFbGVtZW50IG9iamVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBkID0gbmV3IFRlbXBsYXRlKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RlbXBsYXRlJykpO1xuICAgICAgICAgICAgZXhwZWN0KGQuZ2V0VGVtcGxhdGVFbGVtZW50KCkpLnRvLmJlLmluc3RhbmNlT2YoSFRNTFRlbXBsYXRlRWxlbWVudCk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJy5maW5kRG9jdW1lbnRUZW1wbGF0ZSgpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHRocm93IFRlbXBsYXRlIG5vdCBmb3VuZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgZXhwZWN0KCgpID0+IHtcbiAgICAgICAgICAgICAgICBmaW5kRG9jdW1lbnRUZW1wbGF0ZShcIm5vd2F5XCIsIGRpdilcbiAgICAgICAgICAgIH0pLnRvLnRocm93cyhFcnJvcik7XG4gICAgICAgIH0pXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnLmZpbmREb2N1bWVudFRlbXBsYXRlKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGRlc2NyaWJlKCdUZW1wbGF0ZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGl0KCdzaG91bGQgZmluZCB0ZW1wbGF0ZSBvdmVyIG93bmVyRG9jdW1lbnQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICAgICAgZGl2LnJlbW92ZSgpO1xuICAgICAgICAgICAgICAgIGxldCB0ID0gZmluZERvY3VtZW50VGVtcGxhdGUoXCJteXRlbXBsYXRlXCIsIGRpdik7XG4gICAgICAgICAgICAgICAgZXhwZWN0KHQpLmlzLmluc3RhbmNlb2YoVGVtcGxhdGUpO1xuXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KTtcblxuICAgICAgICBkZXNjcmliZSgnVGhtZW5lZCBUZW1wbGF0ZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBtZW1BdHRyaWJ1dGVWYWx1ZTtcblxuICAgICAgICAgICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgbGV0IG1vY2tzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vY2tzJyk7XG4gICAgICAgICAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gYFxuICAgICAgICAgICAgICAgICAgICA8dGVtcGxhdGUgaWQ9XCJteXRlbXBsYXRlXCI+PHA+MTwvcD48L3RlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICA8dGVtcGxhdGUgaWQ9XCJteXRlbXBsYXRlLW1vbnN0ZXJcIj48cD4yPC9wPjwvdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgIDx0ZW1wbGF0ZSBpZD1cIm15dGVtcGxhdGUtdGVzdHRoZW1lXCI+PHA+NDwvcD48L3RlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICA8dGVtcGxhdGUgaWQ9XCJteXByZWZpeC1teXRlbXBsYXRlLW1vbnN0ZXJcIj48cD4zPC9wPjwvdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgYDtcblxuICAgICAgICAgICAgICAgIGxldCBodG1sID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignaHRtbCcpO1xuICAgICAgICAgICAgICAgIGlmIChodG1sLmhhc0F0dHJpYnV0ZShBVFRSSUJVVEVfVEhFTUVfTkFNRSkpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVtQXR0cmlidXRlVmFsdWUgPSBodG1sLmdldEF0dHJpYnV0ZShBVFRSSUJVVEVfVEhFTUVfTkFNRSlcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgbGV0IG1vY2tzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vY2tzJyk7XG4gICAgICAgICAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gXCJcIjtcblxuICAgICAgICAgICAgICAgIGxldCBodG1sID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignaHRtbCcpO1xuXG4gICAgICAgICAgICAgICAgaWYgKGh0bWwuaGFzQXR0cmlidXRlKEFUVFJJQlVURV9USEVNRV9OQU1FKSkge1xuICAgICAgICAgICAgICAgICAgICBodG1sLnJlbW92ZUF0dHJpYnV0ZShBVFRSSUJVVEVfVEhFTUVfTkFNRSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKG1lbUF0dHJpYnV0ZVZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIGh0bWwuc2V0QXR0cmlidXRlKEFUVFJJQlVURV9USEVNRV9OQU1FLCBtZW1BdHRyaWJ1dGVWYWx1ZSlcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIH0pXG5cblxuICAgICAgICAgICAgaXQoJ3Nob3VsZCBmaW5kIHRlbXBsYXRlIG92ZXIgb3duZXJEb2N1bWVudCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBsZXQgaHRtbCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2h0bWwnKTtcbiAgICAgICAgICAgICAgICBjb25zdCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgICAgICBkaXYuc2V0QXR0cmlidXRlKCdkYXRhLW1vbnN0ZXItdGVtcGxhdGUtcHJlZml4JywgJ215cHJlZml4JylcbiAgICAgICAgICAgICAgICBkaXYucmVtb3ZlKCk7XG4gICAgICAgICAgICAgICAgbGV0IHQxID0gZmluZERvY3VtZW50VGVtcGxhdGUoXCJteXRlbXBsYXRlXCIsIGRpdik7XG4gICAgICAgICAgICAgICAgZXhwZWN0KHQxKS5pcy5pbnN0YW5jZW9mKFRlbXBsYXRlKTtcbiAgICAgICAgICAgICAgICBleHBlY3QodDEuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpLnRleHRDb250ZW50KS5pcy5lcXVhbChcIjNcIik7XG5cbiAgICAgICAgICAgICAgICBkaXYucmVtb3ZlQXR0cmlidXRlKCdkYXRhLW1vbnN0ZXItdGVtcGxhdGUtcHJlZml4JylcbiAgICAgICAgICAgICAgICBsZXQgdDIgPSBmaW5kRG9jdW1lbnRUZW1wbGF0ZShcIm15dGVtcGxhdGVcIiwgZGl2KTtcbiAgICAgICAgICAgICAgICBleHBlY3QodDIpLmlzLmluc3RhbmNlb2YoVGVtcGxhdGUpO1xuICAgICAgICAgICAgICAgIGV4cGVjdCh0Mi5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCkudGV4dENvbnRlbnQpLmlzLmVxdWFsKFwiMlwiKTtcblxuICAgICAgICAgICAgICAgIGh0bWwuc2V0QXR0cmlidXRlKEFUVFJJQlVURV9USEVNRV9OQU1FLCd0ZXN0dGhlbWUnKTtcbiAgICAgICAgICAgICAgICBsZXQgYT0gaHRtbC5vdXRlckhUTUw7XG4gICAgICAgICAgICAgICAgbGV0IHQzID0gZmluZERvY3VtZW50VGVtcGxhdGUoXCJteXRlbXBsYXRlXCIsIGRpdik7XG4gICAgICAgICAgICAgICAgZXhwZWN0KHQzKS5pcy5pbnN0YW5jZW9mKFRlbXBsYXRlKTtcbiAgICAgICAgICAgICAgICBleHBlY3QodDMuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpLnRleHRDb250ZW50KS5pcy5lcXVhbChcIjRcIik7XG5cblxuICAgICAgICAgICAgfSlcbiAgICAgICAgfSk7XG5cblxuICAgIH0pO1xufSk7IiwgIid1c2Ugc3RyaWN0JztcblxuXG5pbXBvcnQge2luaXRKU0RPTX0gZnJvbSBcIi4uLy4uL3V0aWwvanNkb20ubWpzXCI7XG5cbmxldCB3aW5kb3dSZWFkeTtcbmxldCBkb21SZWFkeTtcblxuZGVzY3JpYmUoJ1JlYWR5JywgZnVuY3Rpb24gKCkge1xuXG4gICAgYmVmb3JlKGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgIGluaXRKU0RPTSgpLnRoZW4oKCkgPT4ge1xuXG4gICAgICAgICAgICBpbXBvcnQoXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvZG9tL3JlYWR5Lm1qc1wiKS50aGVuKChtKSA9PiB7XG4gICAgICAgICAgICAgICAgZG9tUmVhZHkgPSBtWydkb21SZWFkeSddO1xuICAgICAgICAgICAgICAgIHdpbmRvd1JlYWR5ID0gbVsnd2luZG93UmVhZHknXTtcbiAgICAgICAgICAgICAgICBkb25lKClcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIH0pO1xuXG5cbiAgICB9KVxuXG4gICAgZGVzY3JpYmUoJ2RvbVJlYWR5JywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdyZXNvbHZlIHByb21pc2UnLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICAgICAgZG9tUmVhZHkudGhlbihkb25lKS5jYXRjaChlID0+IGRvbmUoZSkpO1xuICAgICAgICB9KTtcblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3dpbmRvd1JlYWR5JywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdyZXNvbHZlIHByb21pc2UnLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICAgICAgd2luZG93UmVhZHkudGhlbihkb25lKS5jYXRjaChlID0+IGRvbmUoZSkpO1xuICAgICAgICB9KTtcblxuICAgIH0pO1xuXG5cbn0pOyIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGV4dGVuZCB9IGZyb20gXCIuLi9kYXRhL2V4dGVuZC5tanNcIjtcbmltcG9ydCB7IEJhc2VXaXRoT3B0aW9ucyB9IGZyb20gXCIuLi90eXBlcy9iYXNld2l0aG9wdGlvbnMubWpzXCI7XG5pbXBvcnQgeyBnZXRHbG9iYWxPYmplY3QgfSBmcm9tIFwiLi4vdHlwZXMvZ2xvYmFsLm1qc1wiO1xuaW1wb3J0IHsgaXNBcnJheSB9IGZyb20gXCIuLi90eXBlcy9pcy5tanNcIjtcbmltcG9ydCB7IFN0YWNrIH0gZnJvbSBcIi4uL3R5cGVzL3N0YWNrLm1qc1wiO1xuaW1wb3J0IHsgdmFsaWRhdGVJbnN0YW5jZSwgdmFsaWRhdGVTdHJpbmcgfSBmcm9tIFwiLi4vdHlwZXMvdmFsaWRhdGUubWpzXCI7XG5pbXBvcnQgeyBpbnN0YW5jZVN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5leHBvcnQgeyBGb2N1c01hbmFnZXIgfTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuY29uc3QgS0VZX0RPQ1VNRU5UID0gXCJkb2N1bWVudFwiO1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAdHlwZSB7c3RyaW5nfVxuICovXG5jb25zdCBLRVlfQ09OVEVYVCA9IFwiY29udGV4dFwiO1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAdHlwZSB7U3ltYm9sfVxuICovXG5jb25zdCBzdGFja1N5bWJvbCA9IFN5bWJvbChcInN0YWNrXCIpO1xuXG4vKipcbiAqIFdpdGggdGhlIGZvY3VzIG1hbmFnZXIgdGhlIGZvY3VzIGNhbiBiZSBzdG9yZWQgaW4gYSBkb2N1bWVudCwgcmVjYWxsZWQgYW5kIG1vdmVkLlxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjUuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHRocm93cyB7RXJyb3J9IHVuc3VwcG9ydGVkIGxvY2FsZVxuICogQHN1bW1hcnkgSGFuZGxlIHRoZSBmb2N1c1xuICovXG5jbGFzcyBGb2N1c01hbmFnZXIgZXh0ZW5kcyBCYXNlV2l0aE9wdGlvbnMge1xuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYmplY3R8dW5kZWZpbmVkfSBvcHRpb25zXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgICAgICBzdXBlcihvcHRpb25zKTtcbiAgICAgICAgdmFsaWRhdGVJbnN0YW5jZSh0aGlzLmdldE9wdGlvbihLRVlfRE9DVU1FTlQpLCBIVE1MRG9jdW1lbnQpO1xuXG4gICAgICAgIHRoaXNbc3RhY2tTeW1ib2xdID0gbmV3IFN0YWNrKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMi4xLjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci9kb20vZm9jdXNtYW5hZ2VyXCIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwcm9wZXJ0eSB7SFRNTERvY3VtZW50fSBkb2N1bWVudCB0aGUgZG9jdW1lbnQgb2JqZWN0IGludG8gd2hpY2ggdGhlIG5vZGUgaXMgdG8gYmUgYXBwZW5kZWRcbiAgICAgKi9cbiAgICBnZXQgZGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBleHRlbmQoe30sIHN1cGVyLmRlZmF1bHRzLCB7XG4gICAgICAgICAgICBbS0VZX0RPQ1VNRU5UXTogZ2V0R2xvYmFsT2JqZWN0KFwiZG9jdW1lbnRcIiksXG4gICAgICAgICAgICBbS0VZX0NPTlRFWFRdOiB1bmRlZmluZWQsXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbWVtYmVycyB0aGUgY3VycmVudCBmb2N1cyBvbiBhIHN0YWNrLlxuICAgICAqIFNldmVyYWwgZm9jdXMgY2FuIGJlIHN0b3JlZC5cbiAgICAgKlxuICAgICAqIEByZXR1cm4ge01vbnN0ZXIuRE9NLkZvY3VzTWFuYWdlcn1cbiAgICAgKi9cbiAgICBzdG9yZUZvY3VzKCkge1xuICAgICAgICBjb25zdCBhY3RpdmUgPSB0aGlzLmdldEFjdGl2ZSgpO1xuICAgICAgICBpZiAoYWN0aXZlIGluc3RhbmNlb2YgTm9kZSkge1xuICAgICAgICAgICAgdGhpc1tzdGFja1N5bWJvbF0ucHVzaChhY3RpdmUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBsYXN0IGZvY3VzIG9uIHRoZSBzdGFjayBpcyBzZXQgYWdhaW5cbiAgICAgKlxuICAgICAqIEByZXR1cm4ge01vbnN0ZXIuRE9NLkZvY3VzTWFuYWdlcn1cbiAgICAgKi9cbiAgICByZXN0b3JlRm9jdXMoKSB7XG4gICAgICAgIGNvbnN0IGxhc3QgPSB0aGlzW3N0YWNrU3ltYm9sXS5wb3AoKTtcbiAgICAgICAgaWYgKGxhc3QgaW5zdGFuY2VvZiBOb2RlKSB7XG4gICAgICAgICAgICB0aGlzLmZvY3VzKGxhc3QpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge05vZGV9IGVsZW1lbnRcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IHByZXZlbnRTY3JvbGxcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhbiBpbnN0YW5jZSBvZlxuICAgICAqIEByZXR1cm4ge01vbnN0ZXIuRE9NLkZvY3VzTWFuYWdlcn1cbiAgICAgKi9cbiAgICBmb2N1cyhlbGVtZW50LCBwcmV2ZW50U2Nyb2xsKSB7XG4gICAgICAgIHZhbGlkYXRlSW5zdGFuY2UoZWxlbWVudCwgTm9kZSk7XG5cbiAgICAgICAgZWxlbWVudC5mb2N1cyh7XG4gICAgICAgICAgICBwcmV2ZW50U2Nyb2xsOiBwcmV2ZW50U2Nyb2xsID8/IGZhbHNlLFxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEByZXR1cm4ge0VsZW1lbnR9XG4gICAgICovXG4gICAgZ2V0QWN0aXZlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPcHRpb24oS0VZX0RPQ1VNRU5UKS5hY3RpdmVFbGVtZW50O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlbGVjdCBhbGwgZWxlbWVudHMgdGhhdCBjYW4gYmUgZm9jdXNlZFxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd8dW5kZWZpbmVkfSBxdWVyeVxuICAgICAqIEByZXR1cm4ge2FycmF5fVxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGFuIGluc3RhbmNlIG9mXG4gICAgICovXG4gICAgZ2V0Rm9jdXNhYmxlKHF1ZXJ5KSB7XG4gICAgICAgIGxldCBjb250ZXh0RWxlbWVudCA9IHRoaXMuZ2V0T3B0aW9uKEtFWV9DT05URVhUKTtcbiAgICAgICAgaWYgKGNvbnRleHRFbGVtZW50ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGNvbnRleHRFbGVtZW50ID0gdGhpcy5nZXRPcHRpb24oS0VZX0RPQ1VNRU5UKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhbGlkYXRlSW5zdGFuY2UoY29udGV4dEVsZW1lbnQsIE5vZGUpO1xuXG4gICAgICAgIGlmIChxdWVyeSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB2YWxpZGF0ZVN0cmluZyhxdWVyeSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgLi4uY29udGV4dEVsZW1lbnQucXVlcnlTZWxlY3RvckFsbChcbiAgICAgICAgICAgICAgICAnZGV0YWlscywgYnV0dG9uLCBpbnB1dCwgW3RhYmluZGV4XTpub3QoW3RhYmluZGV4PVwiLTFcIl0pLCBzZWxlY3QsIHRleHRhcmVhLCBhW2hyZWZdLCBib2R5JyxcbiAgICAgICAgICAgICksXG4gICAgICAgIF0uZmlsdGVyKChlbGVtZW50KSA9PiB7XG4gICAgICAgICAgICBpZiAocXVlcnkgIT09IHVuZGVmaW5lZCAmJiAhZWxlbWVudC5tYXRjaGVzKHF1ZXJ5KSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGVsZW1lbnQuaGFzQXR0cmlidXRlKFwiZGlzYWJsZWRcIikpIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIGlmIChlbGVtZW50LmdldEF0dHJpYnV0ZShcImFyaWEtaGlkZGVuXCIpID09PSBcInRydWVcIikgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgICAgICBjb25zdCByZWN0ID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgICAgIGlmIChyZWN0LndpZHRoID09PSAwKSByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICBpZiAocmVjdC5oZWlnaHQgPT09IDApIHJldHVybiBmYWxzZTtcblxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBxdWVyeVxuICAgICAqIEByZXR1cm4ge01vbnN0ZXIuRE9NLkZvY3VzTWFuYWdlcn1cbiAgICAgKi9cbiAgICBmb2N1c05leHQocXVlcnkpIHtcbiAgICAgICAgY29uc3QgY3VycmVudCA9IHRoaXMuZ2V0QWN0aXZlKCk7XG4gICAgICAgIGNvbnN0IGZvY3VzYWJsZSA9IHRoaXMuZ2V0Rm9jdXNhYmxlKHF1ZXJ5KTtcblxuICAgICAgICBpZiAoIWlzQXJyYXkoZm9jdXNhYmxlKSB8fCBmb2N1c2FibGUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjdXJyZW50IGluc3RhbmNlb2YgTm9kZSkge1xuICAgICAgICAgICAgbGV0IGluZGV4ID0gZm9jdXNhYmxlLmluZGV4T2YoY3VycmVudCk7XG5cbiAgICAgICAgICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5mb2N1cyhmb2N1c2FibGVbaW5kZXggKyAxXSB8fCBmb2N1c2FibGVbMF0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZvY3VzKGZvY3VzYWJsZVswXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmZvY3VzKGZvY3VzYWJsZVswXSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcXVlcnlcbiAgICAgKiBAcmV0dXJuIHtNb25zdGVyLkRPTS5Gb2N1c01hbmFnZXJ9XG4gICAgICovXG4gICAgZm9jdXNQcmV2KHF1ZXJ5KSB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLmdldEFjdGl2ZSgpO1xuICAgICAgICBjb25zdCBmb2N1c2FibGUgPSB0aGlzLmdldEZvY3VzYWJsZShxdWVyeSk7XG5cbiAgICAgICAgaWYgKCFpc0FycmF5KGZvY3VzYWJsZSkgfHwgZm9jdXNhYmxlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY3VycmVudCBpbnN0YW5jZW9mIE5vZGUpIHtcbiAgICAgICAgICAgIGxldCBpbmRleCA9IGZvY3VzYWJsZS5pbmRleE9mKGN1cnJlbnQpO1xuXG4gICAgICAgICAgICBpZiAoaW5kZXggPiAtMSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZm9jdXMoZm9jdXNhYmxlW2luZGV4IC0gMV0gfHwgZm9jdXNhYmxlW2ZvY3VzYWJsZS5sZW5ndGggLSAxXSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuZm9jdXMoZm9jdXNhYmxlW2ZvY3VzYWJsZS5sZW5ndGggLSAxXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmZvY3VzKGZvY3VzYWJsZVtmb2N1c2FibGUubGVuZ3RoIC0gMV0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuIiwgIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCI7XG5pbXBvcnQge0ZvY3VzTWFuYWdlcn0gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9kb20vZm9jdXNtYW5hZ2VyLm1qc1wiO1xuaW1wb3J0IHtjbGVhbnVwRE9NRnJvbVRlc3RpbmcsIGluaXRNdXRhdGlvbk9ic2VydmVyRm9yVGVzdGluZ30gZnJvbSBcIi4uLy4uL3V0aWwvY2xlYW51cGRvbS5tanNcIjtcbmltcG9ydCB7aW5pdEpTRE9NfSBmcm9tIFwiLi4vLi4vdXRpbC9qc2RvbS5tanNcIjtcblxuZGVzY3JpYmUoJ0ZvY3VzTWFuYWdlcicsIGZ1bmN0aW9uICgpIHtcbiAgICBiZWZvcmUoZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgaW5pdEpTRE9NKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICBkb25lKClcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAgaW5pdE11dGF0aW9uT2JzZXJ2ZXJGb3JUZXN0aW5nKClcbiAgICB9KVxuXG4gICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgICAgY2xlYW51cERPTUZyb21UZXN0aW5nKCk7XG4gICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpLmlubmVySFRNTCA9ICcnXG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCduZXcnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBpbnN0YW5jZSBvZiBGb2N1c01hbmFnZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IEZvY3VzTWFuYWdlcigpKS5pcy5pbnN0YW5jZW9mKEZvY3VzTWFuYWdlcik7XG4gICAgICAgIH0pXG5cbiAgICB9KVxuXG4gICAgZGVzY3JpYmUoJ3N0b3JlIGFuZCByZXN0b3JlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgbWFuYWdlcjtcblxuICAgICAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAgICAgIG1hbmFnZXIgPSBuZXcgRm9jdXNNYW5hZ2VyKCk7XG4gICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKS5pbm5lckhUTUwgPSBgXG4gICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJ0ZXN0aXRcIiBpZD1cInR4MVwiPlxuICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwidGVzdGl0XCIgaWQ9XCJ0eDJcIj5cbiAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cInRlc3RpdFwiIGlkPVwidHgzXCIgZGlzYWJsZWQ+XG4gICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJ0ZXN0aXRcIiBpZD1cInR4NFwiPlxuICAgICAgICAgICAgPHAgY2xhc3M9XCJ0ZXN0aXRcIiB0YWJpbmRleD1cIjJcIiBpZD1cInR4NVwiPmhlbGxvPC9wPlxuICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwidGVzdGl0XCIgaWQ9XCJ0eDZcIiBhcmlhLWhpZGRlbj1cInRydWVcIj5cbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJ0ZXN0aXRcIiBpZD1cInR4N1wiPjwvYnV0dG9uPlxuICAgICAgICAgICAgYDtcblxuICAgICAgICAgICAgZm9yIChjb25zdCBbLCBlbGVtZW50XSBvZiBPYmplY3QuZW50cmllcyhkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcudGVzdGl0JykpKSB7XG4gICAgICAgICAgICAgICAgZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QgPSAoKSA9PiAoe1xuICAgICAgICAgICAgICAgICAgICB3aWR0aDogMjAwLFxuICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IDIwMCxcbiAgICAgICAgICAgICAgICAgICAgdG9wOiAwLFxuICAgICAgICAgICAgICAgICAgICBsZWZ0OiAwLFxuICAgICAgICAgICAgICAgICAgICByaWdodDogMjAwLFxuICAgICAgICAgICAgICAgICAgICBib3R0b206IDIwMCxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cblxuXG4gICAgICAgIH0pXG5cbiAgICAgICAgaXQoJ3J1biBpc3QnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIG1hbmFnZXIuZm9jdXMoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3R4MScpKTtcbiAgICAgICAgICAgIG1hbmFnZXIuc3RvcmVGb2N1cygpO1xuXG4gICAgICAgICAgICBjb25zdCBlMSA9IG1hbmFnZXIuZ2V0QWN0aXZlKCk7XG4gICAgICAgICAgICBleHBlY3QoZTEuZ2V0QXR0cmlidXRlKCdpZCcpLCAnZXJyb3IxJykudG8uYmUuZXF1YWwoJ3R4MScpO1xuXG4gICAgICAgICAgICBtYW5hZ2VyLmZvY3VzKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0eDInKSk7XG5cbiAgICAgICAgICAgIG1hbmFnZXIuc3RvcmVGb2N1cygpO1xuICAgICAgICAgICAgZXhwZWN0KG1hbmFnZXIuZ2V0QWN0aXZlKCkuZ2V0QXR0cmlidXRlKCdpZCcpLCAnZXJyb3IyJykudG8uYmUuZXF1YWwoJ3R4MicpO1xuICAgICAgICAgICAgbWFuYWdlci5mb2N1c05leHQoKTtcbiAgICAgICAgICAgIGV4cGVjdChtYW5hZ2VyLmdldEFjdGl2ZSgpLmdldEF0dHJpYnV0ZSgnaWQnKSwgJ2Vycm9yMycpLnRvLmJlLmVxdWFsKCd0eDQnKTtcbiAgICAgICAgICAgIG1hbmFnZXIuZm9jdXNOZXh0KCk7XG4gICAgICAgICAgICBleHBlY3QobWFuYWdlci5nZXRBY3RpdmUoKS5nZXRBdHRyaWJ1dGUoJ2lkJyksICdlcnJvcjQnKS50by5iZS5lcXVhbCgndHg1Jyk7XG4gICAgICAgICAgICBtYW5hZ2VyLnJlc3RvcmVGb2N1cygpO1xuICAgICAgICAgICAgZXhwZWN0KG1hbmFnZXIuZ2V0QWN0aXZlKCkuZ2V0QXR0cmlidXRlKCdpZCcpLCAnZXJyb3I1JykudG8uYmUuZXF1YWwoJ3R4MicpO1xuICAgICAgICAgICAgbWFuYWdlci5yZXN0b3JlRm9jdXMoKTtcbiAgICAgICAgICAgIGV4cGVjdChtYW5hZ2VyLmdldEFjdGl2ZSgpLmdldEF0dHJpYnV0ZSgnaWQnKSwgJ2Vycm9yNicpLnRvLmJlLmVxdWFsKCd0eDEnKTtcbiAgICAgICAgICAgIG1hbmFnZXIucmVzdG9yZUZvY3VzKCk7XG4gICAgICAgICAgICBleHBlY3QobWFuYWdlci5nZXRBY3RpdmUoKS5nZXRBdHRyaWJ1dGUoJ2lkJyksICdlcnJvcjcnKS50by5iZS5lcXVhbCgndHgxJyk7XG4gICAgICAgIH0pXG5cblxuICAgIH0pXG5cbiAgICBkZXNjcmliZSgncmV0dXJudHlwZScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBsZXQgZm9jdXNtYW5hZ2VyO1xuXG4gICAgICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgICAgICAgZm9jdXNtYW5hZ2VyID0gbmV3IEZvY3VzTWFuYWdlcigpO1xuICAgICAgICB9KVxuXG4gICAgICAgIGl0KCdjaGVjayByZXR1cm5zJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBleHBlY3QoZm9jdXNtYW5hZ2VyLmdldEZvY3VzYWJsZSgpKS5pcy5pbnN0YW5jZW9mKEFycmF5KTtcbiAgICAgICAgICAgIGV4cGVjdChmb2N1c21hbmFnZXIuZ2V0QWN0aXZlKCkpLmlzLmluc3RhbmNlb2YoSFRNTEVsZW1lbnQpO1xuICAgICAgICAgICAgZXhwZWN0KGZvY3VzbWFuYWdlci5mb2N1c05leHQoKSkuaXMuaW5zdGFuY2VvZihGb2N1c01hbmFnZXIpO1xuICAgICAgICAgICAgZXhwZWN0KGZvY3VzbWFuYWdlci5mb2N1c1ByZXYoKSkuaXMuaW5zdGFuY2VvZihGb2N1c01hbmFnZXIpO1xuICAgICAgICAgICAgZXhwZWN0KGZvY3VzbWFuYWdlci5zdG9yZUZvY3VzKCkpLmlzLmluc3RhbmNlb2YoRm9jdXNNYW5hZ2VyKTtcbiAgICAgICAgICAgIGV4cGVjdChmb2N1c21hbmFnZXIuZm9jdXMoZG9jdW1lbnQuYm9keSkpLmlzLmluc3RhbmNlb2YoRm9jdXNNYW5hZ2VyKTtcbiAgICAgICAgICAgIGV4cGVjdChmb2N1c21hbmFnZXIucmVzdG9yZUZvY3VzKCkpLmlzLmluc3RhbmNlb2YoRm9jdXNNYW5hZ2VyKTtcblxuICAgICAgICB9KVxuXG4gICAgfSlcblxuXG59KTsiLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBCYXNlIH0gZnJvbSBcIi4uL3R5cGVzL2Jhc2UubWpzXCI7XG5pbXBvcnQgeyBnZXRHbG9iYWxGdW5jdGlvbiB9IGZyb20gXCIuLi90eXBlcy9nbG9iYWwubWpzXCI7XG5pbXBvcnQgeyBQcm94eU9ic2VydmVyIH0gZnJvbSBcIi4uL3R5cGVzL3Byb3h5b2JzZXJ2ZXIubWpzXCI7XG5pbXBvcnQgeyB2YWxpZGF0ZUluc3RhbmNlLCB2YWxpZGF0ZVN0cmluZyB9IGZyb20gXCIuLi90eXBlcy92YWxpZGF0ZS5tanNcIjtcblxuZXhwb3J0IHsgQVRUUklCVVRFUFJFRklYLCBBc3NlbWJsZXIgfTtcblxuLyoqXG4gKiBhdHRyaWJ1dGUgcHJlZml4XG4gKlxuICogQHR5cGUge3N0cmluZ31cbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICovXG5jb25zdCBBVFRSSUJVVEVQUkVGSVggPSBcImRhdGEtbW9uc3Rlci1cIjtcblxuLyoqXG4gKiBBc3NlbWJsZXIgY2xhc3NcbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjYuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHN1bW1hcnkgQWxsb3dzIHlvdSB0byBidWlsZCBhbiBodG1sIGZyYWdtZW50XG4gKi9cbmNsYXNzIEFzc2VtYmxlciBleHRlbmRzIEJhc2Uge1xuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7RG9jdW1lbnRGcmFnbWVudH0gZnJhZ21lbnRcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhbiBpbnN0YW5jZSBvZlxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgZnVuY3Rpb25cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gdGhlIGZ1bmN0aW9uIGlzIG5vdCBkZWZpbmVkXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoZnJhZ21lbnQpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5hdHRyaWJ1dGVQcmVmaXggPSBBVFRSSUJVVEVQUkVGSVg7XG4gICAgICAgIHZhbGlkYXRlSW5zdGFuY2UoZnJhZ21lbnQsIGdldEdsb2JhbEZ1bmN0aW9uKFwiRG9jdW1lbnRGcmFnbWVudFwiKSk7XG4gICAgICAgIHRoaXMuZnJhZ21lbnQgPSBmcmFnbWVudDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBwcmVmaXhcbiAgICAgKiBAcmV0dXJucyB7QXNzZW1ibGVyfVxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgc3RyaW5nXG4gICAgICovXG4gICAgc2V0QXR0cmlidXRlUHJlZml4KHByZWZpeCkge1xuICAgICAgICB2YWxpZGF0ZVN0cmluZyhwcmVmaXgpO1xuICAgICAgICB0aGlzLmF0dHJpYnV0ZVByZWZpeCA9IHByZWZpeDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgICAqL1xuICAgIGdldEF0dHJpYnV0ZVByZWZpeCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXR0cmlidXRlUHJlZml4O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtQcm94eU9ic2VydmVyfHVuZGVmaW5lZH0gZGF0YVxuICAgICAqIEByZXR1cm4ge0RvY3VtZW50RnJhZ21lbnR9XG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYW4gaW5zdGFuY2Ugb2ZcbiAgICAgKi9cbiAgICBjcmVhdGVEb2N1bWVudEZyYWdtZW50KGRhdGEpIHtcbiAgICAgICAgaWYgKGRhdGEgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgZGF0YSA9IG5ldyBQcm94eU9ic2VydmVyKHt9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhbGlkYXRlSW5zdGFuY2UoZGF0YSwgUHJveHlPYnNlcnZlcik7XG4gICAgICAgIGxldCBmcmFnbWVudCA9IHRoaXMuZnJhZ21lbnQuY2xvbmVOb2RlKHRydWUpO1xuICAgICAgICByZXR1cm4gZnJhZ21lbnQ7XG4gICAgfVxufVxuIiwgImltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5cbmltcG9ydCB7QVRUUklCVVRFUFJFRklYLCBBc3NlbWJsZXJ9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvZG9tL2Fzc2VtYmxlci5tanNcIjtcbmltcG9ydCB7aW5pdEpTRE9NfSBmcm9tIFwiLi4vLi4vdXRpbC9qc2RvbS5tanNcIjtcblxuZGVzY3JpYmUoJ0Fzc2VtYmxlcicsIGZ1bmN0aW9uICgpIHtcbiAgICBiZWZvcmUoYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBpbml0SlNET00oKTtcbiAgICB9KVxuICAgIGRlc2NyaWJlKCdjcmVhdGVEb2N1bWVudEZyYWdtZW50KCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIDxkaXY+T25lPC9kaXY+PGRpdj5Ud288L2Rpdj4nLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIGxldCBmcmFnbWVudCA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCkuY3JlYXRlQ29udGV4dHVhbEZyYWdtZW50KCc8ZGl2Pk9uZTwvZGl2PjxkaXY+VHdvPC9kaXY+Jyk7XG5cbiAgICAgICAgICAgIGxldCBmID0gbmV3IEFzc2VtYmxlcihmcmFnbWVudCk7XG5cbiAgICAgICAgICAgIC8vIGNvbnZlcnQgdG8gc3RyaW5nXG4gICAgICAgICAgICBsZXQgY29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQoZi5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCkuY2xvbmVOb2RlKHRydWUpKTtcblxuICAgICAgICAgICAgZXhwZWN0KGNvbnRhaW5lci5pbm5lckhUTUwpLnRvLmJlLmVxdWFsKCc8ZGl2Pk9uZTwvZGl2PjxkaXY+VHdvPC9kaXY+Jyk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2NyZWF0ZURvY3VtZW50RnJhZ21lbnQoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gRG9jdW1lbnRGcmFnbWVudCBvYmplY3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgZCA9IG5ldyBBc3NlbWJsZXIoZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpKTtcbiAgICAgICAgICAgIGV4cGVjdChkLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKSkudG8uYmUuaW5zdGFuY2VPZihEb2N1bWVudEZyYWdtZW50KTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnbmV3JywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnbmV3IFJlbmRlcmVyKCkgc2hvdWxkIHJldHVybiBBc3NlbWJsZXIgb2JqZWN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGV0IGQgPSBuZXcgQXNzZW1ibGVyKGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKSk7XG4gICAgICAgICAgICBleHBlY3QoZCkudG8uYmUuaW5zdGFuY2VPZihBc3NlbWJsZXIpO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdnZXRBdHRyaWJ1dGVQcmVmaXgoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gJyArIEFUVFJJQlVURVBSRUZJWCwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGV0IGQgPSBuZXcgQXNzZW1ibGVyKGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKSk7XG4gICAgICAgICAgICBleHBlY3QoZC5nZXRBdHRyaWJ1dGVQcmVmaXgoKSkudG8uYmUuZXF1YWwoQVRUUklCVVRFUFJFRklYKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnc2V0QXR0cmlidXRlUHJlZml4KCkuZ2V0QXR0cmlidXRlUHJlZml4KCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIHNhbWUgdmFsdWUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgZCA9IG5ldyBBc3NlbWJsZXIoZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpKTtcbiAgICAgICAgICAgIGV4cGVjdChkLnNldEF0dHJpYnV0ZVByZWZpeCgndGVzdDAxJykuZ2V0QXR0cmlidXRlUHJlZml4KCkpLnRvLmJlLmVxdWFsKCd0ZXN0MDEnKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cblxufSk7IiwgImltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge3BhcnNlTG9jYWxlfSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2kxOG4vbG9jYWxlLm1qc1wiO1xuaW1wb3J0IHtFbWJlZH0gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9pMThuL3Byb3ZpZGVycy9lbWJlZC5tanNcIjtcbmltcG9ydCB7XG4gICAgVHJhbnNsYXRpb25zLFxuICAgIGdldERvY3VtZW50VHJhbnNsYXRpb25zXG4gICAgXG59IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvaTE4bi90cmFuc2xhdGlvbnMubWpzXCI7XG5pbXBvcnQge2luaXRKU0RPTX0gZnJvbSBcIi4uLy4uL3V0aWwvanNkb20ubWpzXCI7XG5cbmRlc2NyaWJlKCdUcmFuc2xhdGlvbnMnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBkZXNjcmliZSgnSW5zdGFuY2UgYW5kIEluaXQnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgbGV0IHRyYW5zbGF0aW9uO1xuXG4gICAgICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgICAgICAgdHJhbnNsYXRpb24gPSBuZXcgVHJhbnNsYXRpb25zKHBhcnNlTG9jYWxlKCdlbi1HQicpKTtcblxuICAgICAgICAgICAgdHJhbnNsYXRpb24uYXNzaWduVHJhbnNsYXRpb25zKHtcbiAgICAgICAgICAgICAgICB0ZXN0MTogXCJhYmNcIixcbiAgICAgICAgICAgICAgICB0ZXN0MjogeydvdGhlcic6ICd4eXonfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pXG5cbiAgICAgICAgaXQoJ2NyZWF0ZSBpbnN0YW5jZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgVHJhbnNsYXRpb25zKHBhcnNlTG9jYWxlKCdlbi1HQicpKSkuaXMuaW5zdGFuY2VvZihUcmFuc2xhdGlvbnMpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnaW5pdCB0cmFuc2xhdGlvbnMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QodHJhbnNsYXRpb24uYXNzaWduVHJhbnNsYXRpb25zKHtcbiAgICAgICAgICAgICAgICB0ZXN0MTogXCJhYmNcIixcbiAgICAgICAgICAgICAgICB0ZXN0MjogeydvdGhlcic6ICd4eXonfVxuICAgICAgICAgICAgfSkpLmlzLmluc3RhbmNlb2YoVHJhbnNsYXRpb25zKTtcbiAgICAgICAgfSk7XG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdnZXRUZXh0JywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGxldCB0cmFuc2xhdGlvbjtcblxuICAgICAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAgICAgIHRyYW5zbGF0aW9uID0gbmV3IFRyYW5zbGF0aW9ucyhwYXJzZUxvY2FsZSgnZW4tR0InKSk7XG5cbiAgICAgICAgICAgIHRyYW5zbGF0aW9uLmFzc2lnblRyYW5zbGF0aW9ucyh7XG4gICAgICAgICAgICAgICAgdGVzdDE6IFwiYWJjXCIsXG4gICAgICAgICAgICAgICAgdGVzdDI6IHsnb3RoZXInOiAneHl6J31cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuXG4gICAgICAgIGl0KCdjcmVhdGUsIHNldCBhbmQgZ2V0IGVuLUdCJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KHRyYW5zbGF0aW9uLmdldFRleHQoJ3Rlc3QxJykpLmlzLmVxdWFsKCdhYmMnKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ2NyZWF0ZSwgc2V0IGFuZCBnZXQgIGVuLUdCIHdpdGggcGx1cmFscnVsZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QodHJhbnNsYXRpb24uZ2V0VGV4dCgndGVzdDInKSkuaXMuZXF1YWwoJ3h5eicpXG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBpbml0RG9jdW1lbnRUcmFuc2xhdGlvblxuICAgICAqL1xuXG4gICAgZGVzY3JpYmUoXCJ0ZXN0IGluaXREb2N1bWVudFRyYW5zbGF0aW9uIFwiLCBmdW5jdGlvbiAoKSB7XG5cblxuICAgICAgICBsZXQgaHRtbDEgPSBgPGRpdiBpZD1cIm1vY2stdHJhbnNsYXRpb25zXCI+PC9kaXY+XG4gICAgXG48c2NyaXB0IHR5cGU9XCJhcHBsaWNhdGlvbi9qc29uXCIgZGF0YS1tb25zdGVyLXJvbGU9XCJ0cmFuc2xhdGlvbnNcIj5cbiAgICB7XG4gICAgICAgIFwidGVzdDFcIjogXCJhYmNcIixcbiAgICAgICAgXCJ0ZXN0MlwiOiB7XG4gICAgICAgICAgICBcIm90aGVyXCI6IFwieHl6XCJcbiAgICAgICAgfVxuICAgIH1cbjwvc2NyaXB0PlxuXG48c2NyaXB0IHR5cGU9XCJhcHBsaWNhdGlvbi9qc29uXCIgZGF0YS1tb25zdGVyLXJvbGU9XCJ0cmFuc2xhdGlvbnNcIj5cbiAgICB7XG4gICAgICAgIFwidGVzdDFcIjogXCJ4eXpcIixcbiAgICAgICAgXCJ0ZXN0M1wiOiB7XG4gICAgICAgICAgICBcIm90aGVyXCI6IFwieHl6XCJcbiAgICAgICAgfVxuICAgIH1cbjwvc2NyaXB0PiAgICBcbiAgICBcbmA7XG5cbiAgICAgICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICAgICAgICBsZXQgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgICAgIG1vY2tzLmlubmVySFRNTCA9IGh0bWwxO1xuXG4gICAgICAgIH0pXG5cbiAgICAgICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgICAgICAgIGxldCBtb2NrcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpO1xuICAgICAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gXCJcIjtcbiAgICAgICAgfSlcblxuICAgICAgICBiZWZvcmUoZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgICAgIGluaXRKU0RPTSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG5cbiAgICAgICAgaXQoJ0luaXQgdHJhbnNsYXRpb25zJywgZnVuY3Rpb24gKGRvbmUpIHtcblxuICAgICAgICAgICAgbGV0IGVsZW0gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9jay10cmFuc2xhdGlvbnMnKTtcbiAgICAgICAgICAgIEVtYmVkLmFzc2lnblRyYW5zbGF0aW9uc1RvRWxlbWVudChlbGVtKS50aGVuKChvKSA9PiB7XG5cbiAgICAgICAgICAgICAgICBsZXQgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAvLyBubyBleGNlcHRpb24gYmVjYXVzZSBvZiBkZWZhdWx0XG4gICAgICAgICAgICAgICAgZXhwZWN0KGdldERvY3VtZW50VHJhbnNsYXRpb25zKGVsZW0pLmdldFRleHQoJ25vLWtleScsJ3dpdGgtZGVmYXVsdCcpKVxuICAgICAgICAgICAgICAgICAgICAuaXMuZXF1YWwoJ3dpdGgtZGVmYXVsdCcpO1xuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIGV4cGVjdChnZXREb2N1bWVudFRyYW5zbGF0aW9ucyhlbGVtKS5nZXRUZXh0KCd0ZXN0MScpKVxuICAgICAgICAgICAgICAgICAgICAuaXMuZXF1YWwoJ3h5eicpO1xuXG4gICAgICAgICAgICAgICAgZG9uZSgpO1xuXG4gICAgICAgICAgICB9KS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgICBkb25lKGUpO1xuICAgICAgICAgICAgfSlcblxuXG4gICAgICAgIH0pO1xuICAgIH0pXG5cblxufSk7IiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgaW50ZXJuYWxTeW1ib2wgfSBmcm9tIFwiLi4vLi4vY29uc3RhbnRzLm1qc1wiO1xuaW1wb3J0IHsgZXh0ZW5kIH0gZnJvbSBcIi4uLy4uL2RhdGEvZXh0ZW5kLm1qc1wiO1xuaW1wb3J0IHsgZ2V0RG9jdW1lbnQgfSBmcm9tIFwiLi4vLi4vZG9tL3V0aWwubWpzXCI7XG5pbXBvcnQgeyBpc1N0cmluZyB9IGZyb20gXCIuLi8uLi90eXBlcy9pcy5tanNcIjtcbmltcG9ydCB7IHZhbGlkYXRlT2JqZWN0LCB2YWxpZGF0ZVN0cmluZyB9IGZyb20gXCIuLi8uLi90eXBlcy92YWxpZGF0ZS5tanNcIjtcbmltcG9ydCB7IHBhcnNlTG9jYWxlIH0gZnJvbSBcIi4uL2xvY2FsZS5tanNcIjtcbmltcG9ydCB7IFByb3ZpZGVyIH0gZnJvbSBcIi4uL3Byb3ZpZGVyLm1qc1wiO1xuaW1wb3J0IHsgVHJhbnNsYXRpb25zIH0gZnJvbSBcIi4uL3RyYW5zbGF0aW9ucy5tanNcIjtcblxuZXhwb3J0IHsgRW1iZWQgfTtcblxuLyoqXG4gKiBUaGUgRW1iZWQgcHJvdmlkZXIgcmV0cmlldmVzIGEgSlNPTiBmaWxlIGZyb20gdGhlIGdpdmVuIFNjcmlwdCBUYWcuXG4gKlxuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi8uLi9leGFtcGxlL2kxOG4vcHJvdmlkZXJzL2VtYmVkLm1qc1xuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4xMy4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuSTE4bi5Qcm92aWRlcnNcbiAqIEBzZWUge0BsaW5rIGh0dHBzOi8vZGF0YXRyYWNrZXIuaWV0Zi5vcmcvZG9jL2h0bWwvcmZjMzA2Nn1cbiAqIEB0dXRvcmlhbCBpMThuLWxvY2FsZS1hbmQtZm9ybWF0dGVyXG4gKi9cbmNsYXNzIEVtYmVkIGV4dGVuZHMgUHJvdmlkZXIge1xuICAgIC8qKlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8c2NyaXB0IGlkPVwidHJhbnNsYXRpb25zXCIgdHlwZT1cImFwcGxpY2F0aW9uL2pzb25cIj5cbiAgICAgKiB7XG4gICAgICogICAgIFwiaGVsbG9cIjogXCJIYWxsb1wiXG4gICAgICogfVxuICAgICAqIDwvc2NyaXB0PlxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICpcbiAgICAgKiBgYGBqYXZhc2NyaXB0XG4gICAgICogbmV3IEVtYmVkKCd0cmFuc2xhdGlvbnMnKVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQHBhcmFtIHtIVE1MRWxlbWVudHxzdHJpbmd9IGVsZW1lbnRPcklkXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihlbGVtZW50T3JJZCwgb3B0aW9ucykge1xuICAgICAgICBzdXBlcihvcHRpb25zKTtcblxuICAgICAgICBpZiAob3B0aW9ucyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBvcHRpb25zID0ge307XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZWxlbWVudE9ySWQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBAcHJvcGVydHkge0hUTUxFbGVtZW50fHN0cmluZ31cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgdGhpcy50cmFuc2xhdGVFbGVtZW50ID0gZWxlbWVudE9ySWQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIEBwcm9wZXJ0eSB7SFRNTEVsZW1lbnR8c3RyaW5nfVxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICB0aGlzLnRyYW5zbGF0ZUVsZW1lbnQgPSBnZXREb2N1bWVudCgpLmdldEVsZW1lbnRCeUlkKHZhbGlkYXRlU3RyaW5nKGVsZW1lbnRPcklkKSk7XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICogQHByaXZhdGVcbiAgICAgICAgICogQHByb3BlcnR5IHtPYmplY3R9IG9wdGlvbnNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXNbaW50ZXJuYWxTeW1ib2xdID0gZXh0ZW5kKHt9LCBzdXBlci5kZWZhdWx0cywgdGhpcy5kZWZhdWx0cywgdmFsaWRhdGVPYmplY3Qob3B0aW9ucykpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERlZmF1bHRzXG4gICAgICpcbiAgICAgKiBAc2VlIHtAbGluayBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRmV0Y2hfQVBJfVxuICAgICAqL1xuICAgIGdldCBkZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIGV4dGVuZCh7fSwgc3VwZXIuZGVmYXVsdHMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtMb2NhbGV8c3RyaW5nfSBsb2NhbGVcbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgICAqL1xuICAgIGdldFRyYW5zbGF0aW9ucyhsb2NhbGUpIHtcbiAgICAgICAgaWYgKGlzU3RyaW5nKGxvY2FsZSkpIHtcbiAgICAgICAgICAgIGxvY2FsZSA9IHBhcnNlTG9jYWxlKGxvY2FsZSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMudHJhbnNsYXRlRWxlbWVudCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoXCJUZXh0IG5vdCBmb3VuZFwiKSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoISh0aGlzLnRyYW5zbGF0ZUVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MU2NyaXB0RWxlbWVudCkpIHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKFwiRWxlbWVudCBpcyBub3QgYSBzY3JpcHQgdGFnXCIpKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnRyYW5zbGF0ZUVsZW1lbnQudHlwZSAhPT0gXCJhcHBsaWNhdGlvbi9qc29uXCIpIHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKFwiRWxlbWVudCBpcyBub3QgYSBzY3JpcHQgdGFnIHdpdGggdHlwZSBhcHBsaWNhdGlvbi9qc29uXCIpKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCB0cmFuc2xhdGlvbnMgPSBudWxsO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB0cmFuc2xhdGlvbnMgPSBKU09OLnBhcnNlKHRoaXMudHJhbnNsYXRlRWxlbWVudC5pbm5lckhUTUwudHJpbSgpKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodHJhbnNsYXRpb25zID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihcIlRyYW5zbGF0aW9ucyBub3QgZm91bmQgb3IgaW52YWxpZFwiKSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCB0ID0gbmV3IFRyYW5zbGF0aW9ucyhsb2NhbGUpO1xuICAgICAgICAgICAgdC5hc3NpZ25UcmFuc2xhdGlvbnModHJhbnNsYXRpb25zKTtcblxuICAgICAgICAgICAgcmVzb2x2ZSh0KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW5pdGlhbGl6ZXMgdGhlIHRyYW5zbGF0aW9ucyBmb3IgdGhlIGN1cnJlbnQgZG9jdW1lbnQuXG4gICAgICpcbiAgICAgKiBgc2NyaXB0W2RhdGEtbW9uc3Rlci1yb2xlPXRyYW5zbGF0aW9uc11gIGlzIHNlYXJjaGVkIGZvciBhbmQgdGhlIHRyYW5zbGF0aW9ucyBhcmUgYXNzaWduZWQgdG8gdGhlIGVsZW1lbnQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZWxlbWVudFxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPHVua25vd25bXT59XG4gICAgICovXG4gICAgc3RhdGljIGFzc2lnblRyYW5zbGF0aW9uc1RvRWxlbWVudChlbGVtZW50KSB7XG4gICAgICAgIGNvbnN0IGQgPSBnZXREb2N1bWVudCgpO1xuXG4gICAgICAgIGlmICghKGVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpIHtcbiAgICAgICAgICAgIGVsZW1lbnQgPSBkLnF1ZXJ5U2VsZWN0b3IoXCJib2R5XCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbGlzdCA9IGQucXVlcnlTZWxlY3RvckFsbChcInNjcmlwdFtkYXRhLW1vbnN0ZXItcm9sZT10cmFuc2xhdGlvbnNdXCIpO1xuICAgICAgICBpZiAobGlzdCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBbXTtcblxuICAgICAgICBsaXN0LmZvckVhY2goKHRyYW5zbGF0aW9uRWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcCA9IG5ldyBFbWJlZCh0cmFuc2xhdGlvbkVsZW1lbnQpO1xuICAgICAgICAgICAgcHJvbWlzZXMucHVzaChwLmFzc2lnblRvRWxlbWVudCh1bmRlZmluZWQsIGVsZW1lbnQpKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKTtcbiAgICB9XG59XG4iLCAiXG5cbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge3BhcnNlTG9jYWxlLCBMb2NhbGV9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvaTE4bi9sb2NhbGUubWpzXCI7XG5cblxuZGVzY3JpYmUoJ0xvY2FsZScsIGZ1bmN0aW9uICgpIHtcblxuICAgIGRlc2NyaWJlKCduZXcgaW5zdGFuY2UnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgLy8gbGFuZ3VhZ2UsIHJlZ2lvbiwgc2NyaXB0LCB2YXJpYW50cywgZXh0bGFuZywgcHJpdmF0ZVVzZVxuICAgICAgICAgICAgLy8gaHR0cHM6Ly93d3cucmZjLWVkaXRvci5vcmcvcmZjL3JmYzU2NDYuaHRtbFxuICAgICAgICAgICAgWyd6aCcsIHVuZGVmaW5lZCwgJ0hhbnQnLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCAnemgtSGFudCddLCAvLyB6aC1IYW50IChDaGluZXNlIHdyaXR0ZW4gdXNpbmcgdGhlIFRyYWRpdGlvbmFsIENoaW5lc2Ugc2NyaXB0KVxuICAgICAgICAgICAgWydkZScsICdDSCcsIHVuZGVmaW5lZCwgJzE5MDEnLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgJ2RlLUNILTE5MDEnXSwgIC8vIGRlLUNILTE5MDEgKEdlcm1hbiBhcyB1c2VkIGluIFN3aXR6ZXJsYW5kIHVzaW5nIHRoZSAxOTAxIHZhcmlhbnQgW29ydGhvZ3JhcGh5XSlcbiAgICAgICAgICAgIFsnc2wnLCAnSVQnLCB1bmRlZmluZWQsICduZWRpcycsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCAnc2wtSVQtbmVkaXMnXSwgIC8vIHNsLUlULW5lZGlzIChTbG92ZW5pYW4gYXMgdXNlZCBpbiBJdGFseSwgTmFkaXphIGRpYWxlY3QpXG4gICAgICAgICAgICBbJ2h5JywgJ0lUJywgJ0xhdG4nLCAnYXJldmVsYScsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCAnaHktTGF0bi1JVC1hcmV2ZWxhJ10sIC8vIGh5LUxhdG4tSVQtYXJldmVsYSAoRWFzdGVybiBBcm1lbmlhbiB3cml0dGVuIGluIExhdGluIHNjcmlwdCwgYXMgdXNlZCBpbiBJdGFseSlcbiAgICAgICAgICAgIFsnemgnLCAnQ04nLCAnSGFucycsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsICd6aC1IYW5zLUNOJ10sIC8vIHpoLUhhbnMtQ04gKENoaW5lc2Ugd3JpdHRlbiB1c2luZyB0aGUgU2ltcGxpZmllZCBzY3JpcHQgYXMgdXNlZCBpbiAgbWFpbmxhbmQgQ2hpbmEpXG4gICAgICAgICAgICBbJ3NyJywgJ1JTJywgJ0xhdG4nLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCAnc3ItTGF0bi1SUyddLCAvLyBzci1MYXRuLVJTIChTZXJiaWFuIHdyaXR0ZW4gdXNpbmcgdGhlIExhdGluIHNjcmlwdCBhcyB1c2VkIGluIFNlcmJpYSlcblxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYyA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGQgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBlID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgZiA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGcgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ25ldyBMb2NhbGUoJyArIGEgKyAnLCcgKyBiICsgJywnICsgYyArICcsJyArIGQgKyAnLCcgKyBlICsgJywnICsgZiArICcpIHNob3VsZCByZXR1cm4gJyArIGcsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgIGV4cGVjdChuZXcgTG9jYWxlKGEsIGIsIGMsIGQsIGUsIGYpLnRvU3RyaW5nKCkpLmlzLmVxdWFsKGcpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdwYXJzZUxvY2FsZSgpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIFtcblxuICAgICAgICAgICAgLy8gbGFuZ3VhZ2UsIHJlZ2lvbiwgc2NyaXB0LCB2YXJpYW50cywgZXh0bGFuZywgcHJpdmF0ZVVzZVxuICAgICAgICAgICAgLy8gaHR0cHM6Ly93d3cucmZjLWVkaXRvci5vcmcvcmZjL3JmYzU2NDYuaHRtbFxuICAgICAgICAgICAgWyd6aCcsIHVuZGVmaW5lZCwgJ0hhbnQnLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCAnemgtSGFudCddLCAvLyB6aC1IYW50IChDaGluZXNlIHdyaXR0ZW4gdXNpbmcgdGhlIFRyYWRpdGlvbmFsIENoaW5lc2Ugc2NyaXB0KVxuICAgICAgICAgICAgWydkZScsICdDSCcsIHVuZGVmaW5lZCwgJzE5MDEnLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgJ2RlLUNILTE5MDEnXSwgIC8vIGRlLUNILTE5MDEgKEdlcm1hbiBhcyB1c2VkIGluIFN3aXR6ZXJsYW5kIHVzaW5nIHRoZSAxOTAxIHZhcmlhbnQgW29ydGhvZ3JhcGh5XSlcbiAgICAgICAgICAgIFsnc2wnLCAnSVQnLCB1bmRlZmluZWQsICduZWRpcycsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCAnc2wtSVQtbmVkaXMnXSwgIC8vIHNsLUlULW5lZGlzIChTbG92ZW5pYW4gYXMgdXNlZCBpbiBJdGFseSwgTmFkaXphIGRpYWxlY3QpXG4gICAgICAgICAgICBbJ2h5JywgJ0lUJywgJ0xhdG4nLCAnYXJldmVsYScsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCAnaHktTGF0bi1JVC1hcmV2ZWxhJ10sIC8vIGh5LUxhdG4tSVQtYXJldmVsYSAoRWFzdGVybiBBcm1lbmlhbiB3cml0dGVuIGluIExhdGluIHNjcmlwdCwgYXMgdXNlZCBpbiBJdGFseSlcbiAgICAgICAgICAgIFsnemgnLCAnQ04nLCAnSGFucycsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsICd6aC1IYW5zLUNOJ10sIC8vIHpoLUhhbnMtQ04gKENoaW5lc2Ugd3JpdHRlbiB1c2luZyB0aGUgU2ltcGxpZmllZCBzY3JpcHQgYXMgdXNlZCBpbiAgbWFpbmxhbmQgQ2hpbmEpXG4gICAgICAgICAgICBbJ3NyJywgJ1JTJywgJ0xhdG4nLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCAnc3ItTGF0bi1SUyddLCAvLyBzci1MYXRuLVJTIChTZXJiaWFuIHdyaXR0ZW4gdXNpbmcgdGhlIExhdGluIHNjcmlwdCBhcyB1c2VkIGluIFNlcmJpYSlcblxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYyA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGQgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBlID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgZiA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGcgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ25ldyBMb2NhbGUoJyArIGEgKyAnLCcgKyBiICsgJywnICsgYyArICcsJyArIGQgKyAnLCcgKyBlICsgJywnICsgZiArICcpIHNob3VsZCByZXR1cm4gJyArIGcsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgIGNvbnN0IGxvY2FsZSA9IHBhcnNlTG9jYWxlKGcpXG4gICAgICAgICAgICAgICAgZXhwZWN0KGxvY2FsZS5sb2NhbGVTdHJpbmcpLnRvLmJlLmVxdWFsKGcpO1xuICAgICAgICAgICAgICAgIGV4cGVjdChsb2NhbGUubGFuZ3VhZ2UpLnRvLmJlLmVxdWFsKGEpO1xuICAgICAgICAgICAgICAgIGV4cGVjdChsb2NhbGUucmVnaW9uKS50by5iZS5lcXVhbChiKTtcbiAgICAgICAgICAgICAgICBleHBlY3QobG9jYWxlLnNjcmlwdCkudG8uYmUuZXF1YWwoYyk7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGxvY2FsZS52YXJpYW50cykudG8uYmUuZXF1YWwoZCk7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGxvY2FsZS5leHRsYW5nKS50by5iZS5lcXVhbChlKTtcbiAgICAgICAgICAgICAgICBleHBlY3QobG9jYWxlLnByaXZhdGVVc2UpLnRvLmJlLmVxdWFsKGYpO1xuXG4gICAgICAgICAgICAgICAgZXhwZWN0KG5ldyBMb2NhbGUoYSwgYiwgYywgZCwgZSwgZikudG9TdHJpbmcoKSkuaXMuZXF1YWwoZylcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgIH0pO1xuXG5cbn0pOyIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGluc3RhbmNlU3ltYm9sLCBpbnRlcm5hbFN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQgeyBleHRlbmQgfSBmcm9tIFwiLi4vZGF0YS9leHRlbmQubWpzXCI7XG5cbmltcG9ydCB7IEZvcm1hdHRlciBhcyBUZXh0Rm9ybWF0dGVyIH0gZnJvbSBcIi4uL3RleHQvZm9ybWF0dGVyLm1qc1wiO1xuaW1wb3J0IHsgdmFsaWRhdGVJbnN0YW5jZSwgdmFsaWRhdGVTdHJpbmcgfSBmcm9tIFwiLi4vdHlwZXMvdmFsaWRhdGUubWpzXCI7XG5pbXBvcnQgeyBUcmFuc2xhdGlvbnMgfSBmcm9tIFwiLi90cmFuc2xhdGlvbnMubWpzXCI7XG5cbmV4cG9ydCB7IEZvcm1hdHRlciB9O1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAdHlwZSB7c3ltYm9sfVxuICovXG5jb25zdCBpbnRlcm5hbFRyYW5zbGF0aW9uU3ltYm9sID0gU3ltYm9sKFwiaW50ZXJuYWxUcmFuc2xhdGlvblwiKTtcblxuLyoqXG4gKiBUaGUgRm9ybWF0dGVyIGV4dGVuZHMgdGhlIFRleHQuRm9ybWF0dGVyIHdpdGggdGhlIHBvc3NpYmlsaXR5IHRvIHJlcGxhY2UgdGhlIGtleSBieSBhIHRyYW5zbGF0aW9uLlxuICpcbiAqIEBleHRlcm5hbEV4YW1wbGUgLi4vLi4vZXhhbXBsZS9pMThuL2Zvcm1hdHRlci5tanNcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjYuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkkxOG5cbiAqL1xuY2xhc3MgRm9ybWF0dGVyIGV4dGVuZHMgVGV4dEZvcm1hdHRlciB7XG4gICAgLyoqXG4gICAgICogRGVmYXVsdCB2YWx1ZXMgZm9yIHRoZSBtYXJrZXJzIGFyZSBgJHtgIGFuZCBgfWBcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBvYmplY3RcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIG9iamVjdFxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKG9iamVjdCwgdHJhbnNsYXRpb24sIG9wdGlvbnMpIHtcbiAgICAgICAgc3VwZXIob2JqZWN0LCBvcHRpb25zKTtcbiAgICAgICAgdGhpc1tpbnRlcm5hbFRyYW5zbGF0aW9uU3ltYm9sXSA9IHZhbGlkYXRlSW5zdGFuY2UodHJhbnNsYXRpb24sIFRyYW5zbGF0aW9ucyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMy4yNy4wXG4gICAgICovXG4gICAgc3RhdGljIGdldCBbaW5zdGFuY2VTeW1ib2xdKCkge1xuICAgICAgICByZXR1cm4gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvaTE4bi9mb3JtYXR0ZXJAQGluc3RhbmNlXCIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwcm9wZXJ0eSB7b2JqZWN0fSBtYXJrZXJcbiAgICAgKiBAcHJvcGVydHkge2FycmF5fSBtYXJrZXIub3Blbj1bXCJpMThue1wiLFwiJHtcIl1cbiAgICAgKiBAcHJvcGVydHkge2FycmF5fSBtYXJrZXIuY2xvc2U9W1wiJHtcIl1cbiAgICAgKiBAcHJvcGVydHkge29iamVjdH0gcGFyYW1ldGVyXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd9IHBhcmFtZXRlci5kZWxpbWl0ZXI9XCI6OlwiXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd9IHBhcmFtZXRlci5hc3NpZ25tZW50PVwiPVwiXG4gICAgICogQHByb3BlcnR5IHtvYmplY3R9IGNhbGxiYWNrc1xuICAgICAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb259IGNhbGxiYWNrcy5pMThuPSgpPT57fVxuICAgICAqL1xuICAgIGdldCBkZWZhdWx0cygpIHtcbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgICAgIHJldHVybiBleHRlbmQoe30sIHN1cGVyLmRlZmF1bHRzLCB7XG4gICAgICAgICAgICBjYWxsYmFja3M6IHtcbiAgICAgICAgICAgICAgICBpMThuOiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNlbGZbaW50ZXJuYWxUcmFuc2xhdGlvblN5bWJvbF0uZ2V0VGV4dCh2YWxpZGF0ZVN0cmluZyh2YWx1ZSkpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbWFya2VyOiB7XG4gICAgICAgICAgICAgICAgb3BlbjogW1wiaTE4bntcIiwgXCIke1wiXSxcbiAgICAgICAgICAgICAgICBjbG9zZTogW1wifVwiXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHRleHRcbiAgICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYSBzdHJpbmdcbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gdG9vIGRlZXAgbmVzdGluZ1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBrZXkgbm90IGZvdW5kXG4gICAgICogQHRocm93cyB7RXJyb3J9IHRoZSBjbG9zaW5nIG1hcmtlciBpcyBtaXNzaW5nXG4gICAgICovXG4gICAgZm9ybWF0KHRleHQpIHtcbiAgICAgICAgdmFsaWRhdGVTdHJpbmcodGV4dCk7XG5cbiAgICAgICAgY29uc3Qgb3Blbk1hcmtlciA9IHRoaXNbaW50ZXJuYWxTeW1ib2xdW1wibWFya2VyXCJdW1wib3BlblwiXT8uWzBdO1xuICAgICAgICBjb25zdCBjbG9zZU1hcmtlciA9IHRoaXNbaW50ZXJuYWxTeW1ib2xdW1wibWFya2VyXCJdW1wiY2xvc2VcIl0/LlswXTtcblxuICAgICAgICBpZiAodGV4dC5pbmRleE9mKG9wZW5NYXJrZXIpID09PSAwKSB7XG4gICAgICAgICAgICB0ZXh0ID0gdGV4dC5zdWJzdHJpbmcob3Blbk1hcmtlci5sZW5ndGgpO1xuXG4gICAgICAgICAgICBpZiAodGV4dC5pbmRleE9mKGNsb3NlTWFya2VyKSA9PT0gdGV4dC5sZW5ndGggLSBjbG9zZU1hcmtlci5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB0ZXh0ID0gdGV4dC5zdWJzdHJpbmcoMCwgdGV4dC5sZW5ndGggLSBjbG9zZU1hcmtlci5sZW5ndGgpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0aGUgY2xvc2luZyBtYXJrZXIgaXMgbWlzc2luZ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHBhcnRzID0gdmFsaWRhdGVTdHJpbmcodGV4dCkuc3BsaXQoXCI6OlwiKTtcbiAgICAgICAgY29uc3QgdHJhbnNsYXRpb25LZXkgPSBwYXJ0cy5zaGlmdCgpLnRyaW0oKTsgLy8ga2V5IHZhbHVlIGRlbGltaXRlclxuICAgICAgICBjb25zdCBwYXJhbWV0ZXIgPSBwYXJ0cy5qb2luKFwiOjpcIikudHJpbSgpO1xuXG4gICAgICAgIGxldCBhc3NlbWJsZWRUZXh0ID0gYCR7b3Blbk1hcmtlcn1zdGF0aWM6JHt0cmFuc2xhdGlvbktleX0gfCBjYWxsOmkxOG5gO1xuICAgICAgICBpZiAocGFyYW1ldGVyLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGFzc2VtYmxlZFRleHQgKz0gYDo6JHtwYXJhbWV0ZXJ9YDtcbiAgICAgICAgfVxuICAgICAgICBhc3NlbWJsZWRUZXh0ICs9IGNsb3NlTWFya2VyO1xuICAgICAgICByZXR1cm4gc3VwZXIuZm9ybWF0KGFzc2VtYmxlZFRleHQpO1xuICAgIH1cbn1cbiIsICJpbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuaW1wb3J0IHtGb3JtYXR0ZXJ9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvaTE4bi9mb3JtYXR0ZXIubWpzXCI7XG5pbXBvcnQge1RyYW5zbGF0aW9uc30gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9pMThuL3RyYW5zbGF0aW9ucy5tanNcIjtcblxuXG5kZXNjcmliZSgnRm9ybWF0dGVyJywgZnVuY3Rpb24gKCkge1xuXG4gICAgZGVzY3JpYmUoJ2V4YW1wbGUnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBydW4gd2l0aCBtYXJrZXInLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIGNvbnN0IHRyYW5zbGF0aW9ucyA9IG5ldyBUcmFuc2xhdGlvbnMoJ2VuJylcbiAgICAgICAgICAgICAgICAuYXNzaWduVHJhbnNsYXRpb25zKHtcbiAgICAgICAgICAgICAgICAgICAgdGhla2V5OiBcIiR7YW5pbWFsfSBoYXMgZWF0ZW4gdGhlICR7Zm9vZH0hXCJcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgY29uc3QgZiA9IG5ldyBGb3JtYXR0ZXIoe30sIHRyYW5zbGF0aW9ucyk7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGV4cGVjdChmLmZvcm1hdChcImkxOG57dGhla2V5OjphbmltYWw9ZG9nOjpmb29kPWNha2V9XCIpKS50by5iZS5lcXVhbCgnZG9nIGhhcyBlYXRlbiB0aGUgY2FrZSEnKTtcbiAgICAgICAgICAgIC8vIFx1MjFBNiBkb2cgaGFzIGVhdGVuIHRoZSBjYWtlISAgICAgICAgICAgICAgICBcblxuICAgICAgICB9KTtcbiAgICAgICAgXG4gICAgICAgIGl0KCdzaG91bGQgcnVuIHdpdGhvdXQgbWFya2VyJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBjb25zdCB0cmFuc2xhdGlvbnMgPSBuZXcgVHJhbnNsYXRpb25zKCdlbicpXG4gICAgICAgICAgICAgICAgLmFzc2lnblRyYW5zbGF0aW9ucyh7XG4gICAgICAgICAgICAgICAgICAgIHRoZWtleTogXCIke2FuaW1hbH0gaGFzIGVhdGVuIHRoZSAke2Zvb2R9IVwiXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIC8vIG1pc3NpbmcgbWFya2VyXG4gICAgICAgICAgICBleHBlY3QobmV3IEZvcm1hdHRlcih7fSwgdHJhbnNsYXRpb25zKS5mb3JtYXQoXCJ0aGVrZXk6OmFuaW1hbD1kb2c6OmZvb2Q9Y2FrZVwiKSkudG8uYmUuZXF1YWwoJ2RvZyBoYXMgZWF0ZW4gdGhlIGNha2UhJyk7XG4gICAgICAgICAgICAvLyBcdTIxQTYgZG9nIGhhcyBlYXRlbiB0aGUgY2FrZSEgICAgICAgICAgICAgICAgXG5cbiAgICAgICAgfSk7XG4gICAgfSk7XG5cblxuICAgIGRlc2NyaWJlKCdmb3JtYXQnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWydpMThue3RyYW5zbGF0aW9ua2V5OjphPTM6OmI9NX0nLCAndGVzdCBpcyAzIGFuZCA1J10sXG5cbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpdCgnZm9ybWF0ICcgKyBhICsgJyBzaG91bGQgJyArIGIsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgIGNvbnN0IHRyYW5zbGF0aW9ucyA9IG5ldyBUcmFuc2xhdGlvbnMoJ2RlJykuYXNzaWduVHJhbnNsYXRpb25zKHtcbiAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRpb25rZXk6IFwidGVzdCBpcyAke2F9IGFuZCAke2J9XCJcbiAgICAgICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICAgICAgZXhwZWN0KFxuICAgICAgICAgICAgICAgICAgICBuZXcgRm9ybWF0dGVyKHt9LCB0cmFuc2xhdGlvbnMpLmZvcm1hdChhKVxuICAgICAgICAgICAgICAgICkudG8uZXF1YWwoYilcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuXG4gICAgfSlcblxuXG59KVxuOyIsICJpbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuXG5cbmltcG9ydCB7RW1iZWR9IGZyb20gXCIuLi8uLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvaTE4bi9wcm92aWRlcnMvZW1iZWQubWpzXCI7XG5pbXBvcnQge1RyYW5zbGF0aW9uc30gZnJvbSBcIi4uLy4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9pMThuL3RyYW5zbGF0aW9ucy5tanNcIjtcbmltcG9ydCB7Z2V0R2xvYmFsfSBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL2dsb2JhbC5tanNcIjtcbmltcG9ydCB7aW5pdEpTRE9NfSBmcm9tIFwiLi4vLi4vLi4vdXRpbC9qc2RvbS5tanNcIjtcblxuXG5jb25zdCBnbG9iYWwgPSBnZXRHbG9iYWwoKTtcblxuY29uc3QgaHRtbDEgPSBgXG48c2NyaXB0IGlkPVwidGVtcGxvY2FsZVwiIHR5cGU9XCJhcHBsaWNhdGlvbi9qc29uXCI+XG57XG4gICAgICAgIFwia2V5XCI6IFwidHJhbnNsYXRpb25cIlxufVxuPC9zY3JpcHQ+XG5gO1xuXG5kZXNjcmliZSgnVHJhbnNsYXRpb24gUHJvdmlkZXIgRW1iZWQnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBiZWZvcmUoZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgaW5pdEpTRE9NKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICBkb25lKClcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cblxuICAgIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICAgIGxldCBtb2NrcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpO1xuICAgICAgICBtb2Nrcy5pbm5lckhUTUwgPSBcIlwiO1xuICAgIH0pO1xuXG4gICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICAgIGxldCBtb2NrcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpO1xuICAgICAgICBtb2Nrcy5pbm5lckhUTUwgPSBodG1sMTtcblxuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnZ2V0IG1vY2sgZGF0YSBhbmQgY3JlYXRlIHRyYW5zbGF0aW9uJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdlbWJlZCcsIGZ1bmN0aW9uIChkb25lKSB7XG5cbiAgICAgICAgICAgIGNvbnN0IGUgPSBuZXcgRW1iZWQoJ3RlbXBsb2NhbGUnKTtcbiAgICAgICAgICAgIGxldCBwID0gZS5nZXRUcmFuc2xhdGlvbnMoJ2VuJyk7XG4gICAgICAgICAgICBleHBlY3QocCkuaXMuaW5zdGFuY2VvZihQcm9taXNlKTtcblxuICAgICAgICAgICAgcC50aGVuKHIgPT4ge1xuXG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KHIpLmlzLmluc3RhbmNlb2YoVHJhbnNsYXRpb25zKTtcbiBcbiAgICAgICAgICAgICAgICAgICAgbGV0IHQgPSByLmdldFRleHQoJ2tleScpXG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdCh0KS5pcy5lcXVhbCgndHJhbnNsYXRpb24nKTtcblxuXG4gICAgICAgICAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIGRvbmUoZSk7XG4gICAgICAgICAgICAgICAgfVxuXG5cbiAgICAgICAgICAgIH0pLmNhdGNoKGUgPT4ge1xuICAgICAgICAgICAgICAgIGRvbmUoZSk7XG4gICAgICAgICAgICB9KVxuXG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cblxufSk7IiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgaW50ZXJuYWxTeW1ib2wgfSBmcm9tIFwiLi4vLi4vY29uc3RhbnRzLm1qc1wiO1xuaW1wb3J0IHsgZXh0ZW5kIH0gZnJvbSBcIi4uLy4uL2RhdGEvZXh0ZW5kLm1qc1wiO1xuaW1wb3J0IHsgRm9ybWF0dGVyIH0gZnJvbSBcIi4uLy4uL3RleHQvZm9ybWF0dGVyLm1qc1wiO1xuaW1wb3J0IHsgZ2V0R2xvYmFsRnVuY3Rpb24gfSBmcm9tIFwiLi4vLi4vdHlwZXMvZ2xvYmFsLm1qc1wiO1xuaW1wb3J0IHsgaXNJbnN0YW5jZSwgaXNTdHJpbmcgfSBmcm9tIFwiLi4vLi4vdHlwZXMvaXMubWpzXCI7XG5pbXBvcnQgeyB2YWxpZGF0ZU9iamVjdCwgdmFsaWRhdGVTdHJpbmcgfSBmcm9tIFwiLi4vLi4vdHlwZXMvdmFsaWRhdGUubWpzXCI7XG5pbXBvcnQgeyBwYXJzZUxvY2FsZSB9IGZyb20gXCIuLi9sb2NhbGUubWpzXCI7XG5pbXBvcnQgeyBQcm92aWRlciB9IGZyb20gXCIuLi9wcm92aWRlci5tanNcIjtcbmltcG9ydCB7IFRyYW5zbGF0aW9ucyB9IGZyb20gXCIuLi90cmFuc2xhdGlvbnMubWpzXCI7XG5cbmV4cG9ydCB7IEZldGNoIH07XG5cbi8qKlxuICogVGhlIGZldGNoIHByb3ZpZGVyIHJldHJpZXZlcyBhIEpTT04gZmlsZSBmcm9tIHRoZSBnaXZlbiBVUkwgYW5kIHJldHVybnMgYSB0cmFuc2xhdGlvbiBvYmplY3QuXG4gKlxuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi8uLi9leGFtcGxlL2kxOG4vcHJvdmlkZXJzL2ZldGNoLm1qc1xuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4xMy4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuSTE4bi5Qcm92aWRlcnNcbiAqIEBzZWUge0BsaW5rIGh0dHBzOi8vZGF0YXRyYWNrZXIuaWV0Zi5vcmcvZG9jL2h0bWwvcmZjMzA2Nn1cbiAqIEB0dXRvcmlhbCBpMThuLWxvY2FsZS1hbmQtZm9ybWF0dGVyXG4gKi9cbmNsYXNzIEZldGNoIGV4dGVuZHMgUHJvdmlkZXIge1xuICAgIC8qKlxuICAgICAqIEFzIG9wdGlvbnMgdGhlIGtleSBgZmV0Y2hgIGNhbiBiZSBwYXNzZWQuIFRoaXMgY29uZmlnIG9iamVjdCBpcyBwYXNzZWQgdG8gdGhlIGZldGNoIG1ldGhvZCBhcyBpbml0LlxuICAgICAqXG4gICAgICogVGhlIHVybCBtYXkgY29udGFpbiBwbGFjZWhvbGRlcnMgKGxhbmd1YWdlLCBzY3JpcHQsIHJlZ2lvbiwgdmFyaWFudHMsIGV4dGxhbmcsIHByaXZhdGVVc2UpLCBzbyB5b3UgY2FuIHNwZWNpZnkgb25lIHVybCBmb3IgYWxsIHRyYW5zbGF0aW9ucy5cbiAgICAgKlxuICAgICAqIGBgYFxuICAgICAqIG5ldyBGZXRjaCgnaHR0cHM6Ly93d3cuZXhhbXBsZS5jb20vYXNzZXRzLyR7bGFuZ3VhZ2V9Lmpzb24nKVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd8VVJMfSB1cmxcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBzZWUge0BsaW5rIE1vbnN0ZXIuSTE4bi5Qcm92aWRlcnMuRmV0Y2gjZGVmYXVsdHN9XG4gICAgICogQHNlZSB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL2ZldGNofVxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHVybCwgb3B0aW9ucykge1xuICAgICAgICBzdXBlcihvcHRpb25zKTtcblxuICAgICAgICBpZiAoaXNJbnN0YW5jZSh1cmwsIFVSTCkpIHtcbiAgICAgICAgICAgIHVybCA9IHVybC50b1N0cmluZygpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG9wdGlvbnMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgICAgICB9XG5cbiAgICAgICAgdmFsaWRhdGVTdHJpbmcodXJsKTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQHByb3BlcnR5IHtzdHJpbmd9XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnVybCA9IHVybDtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQHByaXZhdGVcbiAgICAgICAgICogQHByb3BlcnR5IHtPYmplY3R9IG9wdGlvbnNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXNbaW50ZXJuYWxTeW1ib2xdID0gZXh0ZW5kKHt9LCBzdXBlci5kZWZhdWx0cywgdGhpcy5kZWZhdWx0cywgdmFsaWRhdGVPYmplY3Qob3B0aW9ucykpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERlZmF1bHRzXG4gICAgICpcbiAgICAgKiBAcHJvcGVydHkge09iamVjdH0gZmV0Y2hcbiAgICAgKiBAcHJvcGVydHkge1N0cmluZ30gZmV0Y2gubWV0aG9kPUdFVFxuICAgICAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBmZXRjaC5tb2RlPWNvcnNcbiAgICAgKiBAcHJvcGVydHkge1N0cmluZ30gZmV0Y2guY2FjaGU9bm8tY2FjaGVcbiAgICAgKiBAcHJvcGVydHkge1N0cmluZ30gZmV0Y2guY3JlZGVudGlhbHM9b21pdFxuICAgICAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBmZXRjaC5yZWRpcmVjdD1mb2xsb3dcbiAgICAgKiBAcHJvcGVydHkge1N0cmluZ30gZmV0Y2gucmVmZXJyZXJQb2xpY3k9bm8tcmVmZXJyZXJcbiAgICAgKlxuICAgICAqIEBzZWUge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9GZXRjaF9BUEl9XG4gICAgICovXG4gICAgZ2V0IGRlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gZXh0ZW5kKFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGZldGNoOiB7XG4gICAgICAgICAgICAgICAgICAgIG1ldGhvZDogXCJHRVRcIiwgLy8gKkdFVCwgUE9TVCwgUFVULCBERUxFVEUsIGV0Yy5cbiAgICAgICAgICAgICAgICAgICAgbW9kZTogXCJjb3JzXCIsIC8vIG5vLWNvcnMsICpjb3JzLCBzYW1lLW9yaWdpblxuICAgICAgICAgICAgICAgICAgICBjYWNoZTogXCJuby1jYWNoZVwiLCAvLyAqZGVmYXVsdCwgbm8tY2FjaGUsIHJlbG9hZCwgZm9yY2UtY2FjaGUsIG9ubHktaWYtY2FjaGVkXG4gICAgICAgICAgICAgICAgICAgIGNyZWRlbnRpYWxzOiBcIm9taXRcIiwgLy8gaW5jbHVkZSwgKnNhbWUtb3JpZ2luLCBvbWl0XG4gICAgICAgICAgICAgICAgICAgIHJlZGlyZWN0OiBcImZvbGxvd1wiLCAvLyBtYW51YWwsICpmb2xsb3csIGVycm9yXG4gICAgICAgICAgICAgICAgICAgIHJlZmVycmVyUG9saWN5OiBcIm5vLXJlZmVycmVyXCIsIC8vIG5vLXJlZmVycmVyLCAqbm8tcmVmZXJyZXItd2hlbi1kb3duZ3JhZGUsIG9yaWdpbiwgb3JpZ2luLXdoZW4tY3Jvc3Mtb3JpZ2luLCBzYW1lLW9yaWdpbiwgc3RyaWN0LW9yaWdpbiwgc3RyaWN0LW9yaWdpbi13aGVuLWNyb3NzLW9yaWdpbiwgdW5zYWZlLXVybFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc3VwZXIuZGVmYXVsdHMsXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0xvY2FsZXxzdHJpbmd9IGxvY2FsZVxuICAgICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAgICovXG4gICAgZ2V0VHJhbnNsYXRpb25zKGxvY2FsZSkge1xuICAgICAgICBpZiAoaXNTdHJpbmcobG9jYWxlKSkge1xuICAgICAgICAgICAgbG9jYWxlID0gcGFyc2VMb2NhbGUobG9jYWxlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBmb3JtYXR0ZXIgPSBuZXcgRm9ybWF0dGVyKGxvY2FsZS5nZXRNYXAoKSk7XG5cbiAgICAgICAgcmV0dXJuIGdldEdsb2JhbEZ1bmN0aW9uKFwiZmV0Y2hcIikoZm9ybWF0dGVyLmZvcm1hdCh0aGlzLnVybCksIHRoaXMuZ2V0T3B0aW9uKFwiZmV0Y2hcIiwge30pKVxuICAgICAgICAgICAgLnRoZW4oKHJlc3BvbnNlKSA9PiByZXNwb25zZS5qc29uKCkpXG4gICAgICAgICAgICAudGhlbigoZGF0YSkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgVHJhbnNsYXRpb25zKGxvY2FsZSkuYXNzaWduVHJhbnNsYXRpb25zKGRhdGEpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxufVxuIiwgImltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5cblxuaW1wb3J0IHtGZXRjaH0gZnJvbSBcIi4uLy4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9pMThuL3Byb3ZpZGVycy9mZXRjaC5tanNcIjtcbmltcG9ydCB7VHJhbnNsYXRpb25zfSBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2kxOG4vdHJhbnNsYXRpb25zLm1qc1wiO1xuaW1wb3J0IHtnZXRHbG9iYWx9IGZyb20gXCIuLi8uLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdHlwZXMvZ2xvYmFsLm1qc1wiO1xuXG5cbmNvbnN0IGdsb2JhbCA9IGdldEdsb2JhbCgpO1xubGV0IGZldGNoUmVmZXJlbmNlO1xuXG5cbmRlc2NyaWJlKCdUcmFuc2xhdGlvbiBQcm92aWRlciBGZXRjaCcsIGZ1bmN0aW9uICgpIHtcblxuXG4gICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgICAgZ2xvYmFsWydmZXRjaCddID0gZmV0Y2hSZWZlcmVuY2U7XG4gICAgfSk7XG5cbiAgICBiZWZvcmVFYWNoKCgpID0+IHtcblxuICAgICAgICBmZXRjaFJlZmVyZW5jZSA9IGdsb2JhbFsnZmV0Y2gnXTtcbiAgICAgICAgZ2xvYmFsWydmZXRjaCddID0gZnVuY3Rpb24gKHVybCwgb3B0aW9ucykge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgICAgICAgICAganNvbjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhOiBcInRlc3RcIlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KVxuXG4gICAgICAgIH07XG5cbiAgICB9KVxuXG4gICAgZGVzY3JpYmUoJ2ZldGNoIG1vY2sgZGF0YSBhbmQgY3JlYXRlIHRyYW5zbGF0aW9uJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdmZXRjaCcsIGZ1bmN0aW9uIChkb25lKSB7XG5cbiAgICAgICAgICAgIGxldCBwID0gKG5ldyBGZXRjaChuZXcgVVJMKCdodHRwOi8vZXhhbXBsZS5jb20nKSkpLmdldFRyYW5zbGF0aW9ucygnZW4nKTtcblxuICAgICAgICAgICAgZXhwZWN0KHApLmlzLmluc3RhbmNlb2YoUHJvbWlzZSk7XG5cbiAgICAgICAgICAgIHAudGhlbihyID0+IHtcblxuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChyKS5pcy5pbnN0YW5jZW9mKFRyYW5zbGF0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIGRvbmUoZSk7XG4gICAgICAgICAgICAgICAgfVxuXG5cbiAgICAgICAgICAgIH0pLmNhdGNoKGUgPT4ge1xuICAgICAgICAgICAgICAgIGRvbmUoZSk7XG4gICAgICAgICAgICB9KVxuXG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cblxufSk7IiwgImltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge0FUVFJJQlVURV9PQkpFQ1RMSU5LfSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2RvbS9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQge2dldExpbmtlZE9iamVjdHN9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvZG9tL2F0dHJpYnV0ZXMubWpzXCI7XG5pbXBvcnQge1Byb3ZpZGVyfSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2kxOG4vcHJvdmlkZXIubWpzXCI7XG5pbXBvcnQge2luaXRKU0RPTX0gZnJvbSBcIi4uLy4uL3V0aWwvanNkb20ubWpzXCI7XG5pbXBvcnQge2dldERvY3VtZW50VHJhbnNsYXRpb25zLCBUcmFuc2xhdGlvbnN9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvaTE4bi90cmFuc2xhdGlvbnMubWpzXCI7XG5cbmRlc2NyaWJlKCdQcm92aWRlcicsIGZ1bmN0aW9uICgpIHtcblxuXG4gICAgbGV0IGh0bWwxID0gYFxuICAgIDxkaXYgaWQ9XCJ0ZXN0MVwiPlxuICAgIDwvZGl2PlxuYDtcblxuICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgICBsZXQgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gaHRtbDE7XG5cblxuICAgIH0pXG5cbiAgICBhZnRlckVhY2goKCkgPT4ge1xuICAgICAgICBsZXQgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gXCJcIjtcbiAgICB9KVxuXG4gICAgYmVmb3JlKGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgIGluaXRKU0RPTSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgZG9uZSgpXG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ1Byb3ZpZGVyIGFuZCBEb20nLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgY29uc3QgdHJhbnNsYXRpb25zTGlua1N5bWJvbCA9IFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL2kxOG4vdHJhbnNsYXRpb25zQEBsaW5rXCIpO1xuXG4gICAgICAgIGl0KCdhc3NpZ25Ub0VsZW1lbnQnLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICAgICAgY29uc3QgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0ZXN0MScpO1xuICAgICAgICAgICAgY29uc3QgcCA9IG5ldyBQcm92aWRlcigpO1xuICAgICAgICAgICAgY29uc3QgciA9IHAuYXNzaWduVG9FbGVtZW50KHVuZGVmaW5lZCwgZWxlbWVudCk7XG5cbiAgICAgICAgICAgIHIudGhlbigoZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHMgPSBlbGVtZW50LmdldEF0dHJpYnV0ZShBVFRSSUJVVEVfT0JKRUNUTElOSyk7XG4gICAgICAgICAgICAgICAgaWYgKHMgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgZG9uZShuZXcgRXJyb3IoXCJBdHRyaWJ1dGUgbm90IHNldFwiKSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCBpID0gZ2V0TGlua2VkT2JqZWN0cyhlbGVtZW50LCB0cmFuc2xhdGlvbnNMaW5rU3ltYm9sKVxuICAgICAgICAgICAgICAgIGlmIChpID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGRvbmUobmV3IEVycm9yKFwiTm8gbGlua2VkIG9iamVjdCBmb3VuZFwiKSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbGV0IGNvdW50ZXIgPSAwO1xuXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgdiBvZiBpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvdW50ZXIrKztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoY291bnRlciAhPT0gMSkge1xuICAgICAgICAgICAgICAgICAgICBkb25lKG5ldyBFcnJvcihcIk5vIGxpbmtlZCBvYmplY3QgZm91bmRcIikpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY29uc3QgZG9jVHJhbnMgPSBnZXREb2N1bWVudFRyYW5zbGF0aW9ucyhlbGVtZW50KVxuICAgICAgICAgICAgICAgIGV4cGVjdChkb2NUcmFucykuaXMuaW5zdGFuY2VvZihUcmFuc2xhdGlvbnMpO1xuXG5cbiAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICB9KS5jYXRjaChlID0+IGRvbmUoZSkpO1xuXG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cblxufSk7IiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgQmFzZSB9IGZyb20gXCIuLi8uLi90eXBlcy9iYXNlLm1qc1wiO1xuaW1wb3J0IHsgdmFsaWRhdGVPYmplY3QsIHZhbGlkYXRlU3RyaW5nIH0gZnJvbSBcIi4uLy4uL3R5cGVzL3ZhbGlkYXRlLm1qc1wiO1xuXG5leHBvcnQgeyBNZXNzYWdlIH07XG5cbmNvbnN0IGRhdGFTeW1ib2wgPSBTeW1ib2woXCJAQGRhdGFcIik7XG5cbi8qKlxuICogVGhpcyBjbGFzcyByZXByZXNlbnRzIGEgV2ViU29ja2V0IG1lc3NhZ2UuXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMy40LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5OZXQuV2ViU29ja2V0XG4gKiBAc3VtbWFyeSBUaGUgTWVzc2FnZSBjbGFzcyBlbmNhcHN1bGF0ZXMgYSBXZWJTb2NrZXQgbWVzc2FnZS5cbiAqL1xuY2xhc3MgTWVzc2FnZSBleHRlbmRzIEJhc2Uge1xuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhXG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYSBvYmplY3RcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihkYXRhKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXNbZGF0YVN5bWJvbF0gPSB2YWxpZGF0ZU9iamVjdChkYXRhKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSByYXcgbWVzc2FnZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtvYmplY3R9XG4gICAgICovXG4gICAgZ2V0RGF0YSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbZGF0YVN5bWJvbF07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgeyp9XG4gICAgICovXG4gICAgdG9KU09OKCkge1xuICAgICAgICByZXR1cm4gdGhpc1tkYXRhU3ltYm9sXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ganNvblxuICAgICAqIEByZXR1cm5zIHtNZXNzYWdlfVxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgc3RyaW5nXG4gICAgICovXG4gICAgc3RhdGljIGZyb21KU09OKGpzb24pIHtcbiAgICAgICAgdmFsaWRhdGVTdHJpbmcoanNvbik7XG4gICAgICAgIHJldHVybiBuZXcgTWVzc2FnZShKU09OLnBhcnNlKGpzb24pKTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7TWVzc2FnZX0gZnJvbSBcIi4uLy4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9uZXQvd2ViY29ubmVjdC9tZXNzYWdlLm1qc1wiO1xuXG5kZXNjcmliZSgnTWVzc2FnZScsIGZ1bmN0aW9uICgpIHtcblxuICAgIGl0KCdjb25zdHJ1Y3Qgd2l0aG91dGggcGFyYW1ldGVycyBzaG91bGQgdGhyb3cnLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICBcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIG5ldyBNZXNzYWdlKCk7XG4gICAgICAgICAgICBkb25lKG5ldyBFcnJvcignc2hvdWxkIHRocm93JykpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgIH0pXG4gICAgXG4gICAgaXQoJ2Zyb20ganNvbiBzaG91bGQgJyAsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgIGNvbnN0IGpzb24gPSB7XG4gICAgICAgICAgICBcImlkXCI6IFwiMTIzXCIsXG4gICAgICAgICAgICBcInR5cGVcIjogXCJ0ZXN0XCIsXG4gICAgICAgICAgICBcImRhdGFcIjoge1xuICAgICAgICAgICAgICAgIFwidGVzdFwiOiBcInRlc3RcIlxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG1lc3NhZ2UgPSBNZXNzYWdlLmZyb21KU09OKEpTT04uc3RyaW5naWZ5KGpzb24pKTtcbiAgICAgICAgY29uc3QgZGF0YSA9IG1lc3NhZ2UuZ2V0RGF0YSgpO1xuICAgICAgICBleHBlY3QoZGF0YS5pZCkudG8uZXF1YWwoanNvbi5pZCk7XG4gICAgICAgIGV4cGVjdChkYXRhLnR5cGUpLnRvLmVxdWFsKGpzb24udHlwZSk7XG4gICAgICAgIGV4cGVjdChkYXRhLmRhdGEpLnRvLmRlZXAuZXF1YWwoanNvbi5kYXRhKTtcbiAgICAgICAgZG9uZSgpO1xuICAgIH0pXG4gICAgXG4gICAgaXQgKFwidG8ganNvbiBzaG91bGRcIiwgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgY29uc3Qgb2JqID0ge1xuICAgICAgICAgICAgXCJpZFwiOiBcIjEyM1wiLFxuICAgICAgICAgICAgXCJ0eXBlXCI6IFwidGVzdFwiLFxuICAgICAgICAgICAgXCJkYXRhXCI6IHtcbiAgICAgICAgICAgICAgICBcInRlc3RcIjogXCJ0ZXN0XCJcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBtZXNzYWdlID0gbmV3IE1lc3NhZ2Uob2JqKTtcbiAgICAgICAgY29uc3QgZGF0YSA9IEpTT04uc3RyaW5naWZ5KG1lc3NhZ2UpO1xuICAgICAgICBleHBlY3QoZGF0YSkudG8uZXF1YWwoJ3tcImlkXCI6XCIxMjNcIixcInR5cGVcIjpcInRlc3RcIixcImRhdGFcIjp7XCJ0ZXN0XCI6XCJ0ZXN0XCJ9fScpO1xuICAgICAgICBkb25lKCk7XG4gICAgfSlcblxuXG5cbn0pO1xuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgaW5zdGFuY2VTeW1ib2wgfSBmcm9tIFwiLi4vY29uc3RhbnRzLm1qc1wiO1xuaW1wb3J0IHsgaXNJbnRlZ2VyLCBpc1N0cmluZywgaXNPYmplY3QgfSBmcm9tIFwiLi4vdHlwZXMvaXMubWpzXCI7XG5pbXBvcnQgeyBCYXNlV2l0aE9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXMvYmFzZXdpdGhvcHRpb25zLm1qc1wiO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZVF1ZXVlIH0gZnJvbSBcIi4uL3R5cGVzL29ic2VydmFibGVxdWV1ZS5tanNcIjtcbmltcG9ydCB7IE1lc3NhZ2UgfSBmcm9tIFwiLi93ZWJjb25uZWN0L21lc3NhZ2UubWpzXCI7XG5cbmV4cG9ydCB7IFdlYkNvbm5lY3QgfTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHR5cGUge1N5bWJvbH1cbiAqL1xuY29uc3QgcmVjZWl2ZVF1ZXVlU3ltYm9sID0gU3ltYm9sKFwicmVjZWl2ZVF1ZXVlXCIpO1xuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHR5cGUge1N5bWJvbH1cbiAqL1xuY29uc3Qgc2VuZFF1ZXVlU3ltYm9sID0gU3ltYm9sKFwic2VuZFF1ZXVlXCIpO1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAdHlwZSB7U3ltYm9sfVxuICpcbiAqIGhpbnQ6IHRoaXMgbmFtZSBpcyB1c2VkIGluIHRoZSB0ZXN0cy4gaWYgeW91IHdhbnQgdG8gY2hhbmdlIGl0LCBwbGVhc2UgY2hhbmdlIGl0IGluIHRoZSB0ZXN0cyBhcyB3ZWxsLlxuICovXG5jb25zdCBjb25uZWN0aW9uU3ltYm9sID0gU3ltYm9sKFwiY29ubmVjdGlvblwiKTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHR5cGUge3N5bWJvbH1cbiAqL1xuY29uc3QgbWFudWFsQ2xvc2VTeW1ib2wgPSBTeW1ib2woXCJtYW51YWxDbG9zZVwiKTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHNlZSBodHRwczovL3d3dy5yZmMtZWRpdG9yLm9yZy9yZmMvcmZjNjQ1NS5odG1sI3NlY3Rpb24tNy40LjFcbiAqIEB0eXBlIHt7XCIxMDAwXCI6IHN0cmluZywgXCIxMDExXCI6IHN0cmluZywgXCIxMDEwXCI6IHN0cmluZywgXCIxMDA4XCI6IHN0cmluZywgXCIxMDA3XCI6IHN0cmluZywgXCIxMDA2XCI6IHN0cmluZywgXCIxMDA1XCI6IHN0cmluZywgXCIxMDA0XCI6IHN0cmluZywgXCIxMDE1XCI6IHN0cmluZywgXCIxMDAzXCI6IHN0cmluZywgXCIxMDAyXCI6IHN0cmluZywgXCIxMDAxXCI6IHN0cmluZywgXCIxMDA5XCI6IHN0cmluZ319XG4gKi9cbmNvbnN0IGNvbm5lY3Rpb25TdGF0dXNDb2RlID0ge1xuICAgIDEwMDA6IFwiTm9ybWFsIGNsb3N1cmVcIixcbiAgICAxMDAxOiBcIkdvaW5nIGF3YXlcIixcbiAgICAxMDAyOiBcIlByb3RvY29sIGVycm9yXCIsXG4gICAgMTAwMzogXCJVbnN1cHBvcnRlZCBkYXRhXCIsXG4gICAgMTAwNDogXCJSZXNlcnZlZFwiLFxuICAgIDEwMDU6IFwiTm8gc3RhdHVzIGNvZGVcIixcbiAgICAxMDA2OiBcIkNvbm5lY3Rpb24gY2xvc2VkIGFibm9ybWFsbHlcIixcbiAgICAxMDA3OiBcIkludmFsaWQgZnJhbWUgcGF5bG9hZCBkYXRhXCIsXG4gICAgMTAwODogXCJQb2xpY3kgdmlvbGF0aW9uXCIsXG4gICAgMTAwOTogXCJNZXNzYWdlIHRvbyBiaWdcIixcbiAgICAxMDEwOiBcIk1hbmRhdG9yeSBleHRlbnNpb25cIixcbiAgICAxMDExOiBcIkludGVybmFsIHNlcnZlciBlcnJvclwiLFxuICAgIDEwMTU6IFwiVExTIGhhbmRzaGFrZVwiLFxufTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHRoaXMge1dlYkNvbm5lY3R9XG4gKiBAdGhyb3dzIHtFcnJvcn0gTm8gdXJsIGRlZmluZWQgZm9yIHdlYnNvY2tldCBkYXRhc291cmNlLlxuICovXG5mdW5jdGlvbiBjb25uZWN0U2VydmVyKHJlc29sdmUsIHJlamVjdCkge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgY29uc3QgdXJsID0gc2VsZi5nZXRPcHRpb24oXCJ1cmxcIik7XG4gICAgaWYgKCF1cmwpIHtcbiAgICAgICAgcmVqZWN0KFwiTm8gdXJsIGRlZmluZWQgZm9yIHdlYmNvbm5lY3QuXCIpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbGV0IHByb21pc2VBbGxyZWR5UmVzb2x2ZWQgPSBmYWxzZTtcblxuICAgIGxldCBjb25uZWN0aW9uVGltZW91dCA9IHNlbGYuZ2V0T3B0aW9uKFwiY29ubmVjdGlvbi50aW1lb3V0XCIpO1xuICAgIGlmICghaXNJbnRlZ2VyKGNvbm5lY3Rpb25UaW1lb3V0KSB8fCBjb25uZWN0aW9uVGltZW91dCA8IDEwMCkge1xuICAgICAgICBjb25uZWN0aW9uVGltZW91dCA9IDUwMDA7XG4gICAgfVxuXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGlmIChwcm9taXNlQWxscmVkeVJlc29sdmVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihcIkNvbm5lY3Rpb24gdGltZW91dFwiKSk7XG4gICAgfSwgY29ubmVjdGlvblRpbWVvdXQpO1xuXG4gICAgbGV0IHJlY29ubmVjdFRpbWVvdXQgPSBzZWxmLmdldE9wdGlvbihcImNvbm5lY3Rpb24ucmVjb25uZWN0LnRpbWVvdXRcIik7XG4gICAgaWYgKCFpc0ludGVnZXIocmVjb25uZWN0VGltZW91dCkgfHwgcmVjb25uZWN0VGltZW91dCA8IDEwMDApIHJlY29ubmVjdFRpbWVvdXQgPSAxMDAwO1xuICAgIGxldCByZWNvbm5lY3RBdHRlbXB0cyA9IHNlbGYuZ2V0T3B0aW9uKFwiY29ubmVjdGlvbi5yZWNvbm5lY3QuYXR0ZW1wdHNcIik7XG4gICAgaWYgKCFpc0ludGVnZXIocmVjb25uZWN0QXR0ZW1wdHMpIHx8IHJlY29ubmVjdEF0dGVtcHRzIDwgMSkgcmVjb25uZWN0QXR0ZW1wdHMgPSAxO1xuICAgIGxldCByZWNvbm5lY3RFbmFibGVkID0gc2VsZi5nZXRPcHRpb24oXCJjb25uZWN0aW9uLnJlY29ubmVjdC5lbmFibGVkXCIpO1xuICAgIGlmIChyZWNvbm5lY3RFbmFibGVkICE9PSB0cnVlKSByZWNvbm5lY3RFbmFibGVkID0gZmFsc2U7XG5cbiAgICBzZWxmW21hbnVhbENsb3NlU3ltYm9sXSA9IGZhbHNlO1xuICAgIHNlbGZbY29ubmVjdGlvblN5bWJvbF0ucmVjb25uZWN0Q291bnRlcisrO1xuXG4gICAgaWYgKHNlbGZbY29ubmVjdGlvblN5bWJvbF0uc29ja2V0ICYmIHNlbGZbY29ubmVjdGlvblN5bWJvbF0uc29ja2V0LnJlYWR5U3RhdGUgPCAyKSB7XG4gICAgICAgIHNlbGZbY29ubmVjdGlvblN5bWJvbF0uc29ja2V0LmNsb3NlKCk7XG4gICAgfVxuICAgIHNlbGZbY29ubmVjdGlvblN5bWJvbF0uc29ja2V0ID0gbnVsbDtcbiAgICBzZWxmW2Nvbm5lY3Rpb25TeW1ib2xdLnNvY2tldCA9IG5ldyBXZWJTb2NrZXQodXJsKTtcblxuICAgIHNlbGZbY29ubmVjdGlvblN5bWJvbF0uc29ja2V0Lm9ubWVzc2FnZSA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICBpZiAoZXZlbnQuZGF0YSBpbnN0YW5jZW9mIEJsb2IpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgICAgICAgICByZWFkZXIuYWRkRXZlbnRMaXN0ZW5lcihcImxvYWRlbmRcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHNlbGZbcmVjZWl2ZVF1ZXVlU3ltYm9sXS5hZGQobmV3IE1lc3NhZ2UocmVhZGVyLnJlc3VsdCkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZWFkZXIucmVhZEFzVGV4dChuZXcgTWVzc2FnZShldmVudC5kYXRhKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzZWxmW3JlY2VpdmVRdWV1ZVN5bWJvbF0uYWRkKE1lc3NhZ2UuZnJvbUpTT04oZXZlbnQuZGF0YSkpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHNlbGZbY29ubmVjdGlvblN5bWJvbF0uc29ja2V0Lm9ub3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2VsZltjb25uZWN0aW9uU3ltYm9sXS5yZWNvbm5lY3RDb3VudGVyID0gMDtcbiAgICAgICAgaWYgKHR5cGVvZiByZXNvbHZlID09PSBcImZ1bmN0aW9uXCIgJiYgIXByb21pc2VBbGxyZWR5UmVzb2x2ZWQpIHtcbiAgICAgICAgICAgIHByb21pc2VBbGxyZWR5UmVzb2x2ZWQgPSB0cnVlO1xuICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHNlbGZbY29ubmVjdGlvblN5bWJvbF0uc29ja2V0LmNsb3NlID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgIGlmIChzZWxmW21hbnVhbENsb3NlU3ltYm9sXSkge1xuICAgICAgICAgICAgc2VsZlttYW51YWxDbG9zZVN5bWJvbF0gPSBmYWxzZTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChyZWNvbm5lY3RFbmFibGVkICYmIHRoaXNbY29ubmVjdGlvblN5bWJvbF0ucmVjb25uZWN0Q291bnRlciA8IHJlY29ubmVjdEF0dGVtcHRzKSB7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICBzZWxmLmNvbm5lY3QoKTtcbiAgICAgICAgICAgIH0sIHJlY29ubmVjdFRpbWVvdXQgKiB0aGlzW2Nvbm5lY3Rpb25TeW1ib2xdLnJlY29ubmVjdENvdW50ZXIpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHNlbGZbY29ubmVjdGlvblN5bWJvbF0uc29ja2V0Lm9uZXJyb3IgPSAoZXJyb3IpID0+IHtcbiAgICAgICAgaWYgKHJlY29ubmVjdEVuYWJsZWQgJiYgc2VsZltjb25uZWN0aW9uU3ltYm9sXS5yZWNvbm5lY3RDb3VudGVyIDwgcmVjb25uZWN0QXR0ZW1wdHMpIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHNlbGYuY29ubmVjdCgpO1xuICAgICAgICAgICAgfSwgcmVjb25uZWN0VGltZW91dCAqIHRoaXNbY29ubmVjdGlvblN5bWJvbF0ucmVjb25uZWN0Q291bnRlcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHJlamVjdCA9PT0gXCJmdW5jdGlvblwiICYmICFwcm9taXNlQWxscmVkeVJlc29sdmVkKSB7XG4gICAgICAgICAgICAgICAgcHJvbWlzZUFsbHJlZHlSZXNvbHZlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG59XG5cbi8qKlxuICogVGhlIFJlc3RBUEkgaXMgYSBjbGFzcyB0aGF0IGVuYWJsZXMgYSBSRVNUIEFQSSBzZXJ2ZXIuXG4gKlxuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL25ldC93ZWJjb25uZWN0Lm1qc1xuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMy4xLjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5OZXRcbiAqIEBzdW1tYXJ5IFRoZSBMb2NhbFN0b3JhZ2UgY2xhc3MgZW5jYXBzdWxhdGVzIHRoZSBhY2Nlc3MgdG8gZGF0YSBvYmplY3RzLlxuICovXG5jbGFzcyBXZWJDb25uZWN0IGV4dGVuZHMgQmFzZVdpdGhPcHRpb25zIHtcbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc10gb3B0aW9ucyBjb250YWlucyBkZWZpbml0aW9ucyBmb3IgdGhlIHdlYmNvbm5lY3QuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgICAgICBpZiAoaXNTdHJpbmcob3B0aW9ucykpIHtcbiAgICAgICAgICAgIG9wdGlvbnMgPSB7IHVybDogb3B0aW9ucyB9O1xuICAgICAgICB9XG5cbiAgICAgICAgc3VwZXIob3B0aW9ucyk7XG5cbiAgICAgICAgdGhpc1tyZWNlaXZlUXVldWVTeW1ib2xdID0gbmV3IE9ic2VydmFibGVRdWV1ZSgpO1xuICAgICAgICB0aGlzW3NlbmRRdWV1ZVN5bWJvbF0gPSBuZXcgT2JzZXJ2YWJsZVF1ZXVlKCk7XG5cbiAgICAgICAgdGhpc1tjb25uZWN0aW9uU3ltYm9sXSA9IHt9O1xuICAgICAgICB0aGlzW2Nvbm5lY3Rpb25TeW1ib2xdLnNvY2tldCA9IG51bGw7XG4gICAgICAgIHRoaXNbY29ubmVjdGlvblN5bWJvbF0ucmVjb25uZWN0Q291bnRlciA9IDA7XG4gICAgICAgIHRoaXNbbWFudWFsQ2xvc2VTeW1ib2xdID0gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZX1cbiAgICAgKi9cbiAgICBjb25uZWN0KCkge1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29ubmVjdFNlcnZlci5jYWxsKHRoaXMsIHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgICAqL1xuICAgIGlzQ29ubmVjdGVkKCkge1xuICAgICAgICByZXR1cm4gdGhpc1tjb25uZWN0aW9uU3ltYm9sXT8uc29ja2V0Py5yZWFkeVN0YXRlID09PSAxO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgYGluc3RhbmNlb2ZgIG9wZXJhdG9yLlxuICAgICAqIEByZXR1cm5zIHtzeW1ib2x9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBbaW5zdGFuY2VTeW1ib2xdKCkge1xuICAgICAgICByZXR1cm4gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvbmV0L3dlYmNvbm5lY3RcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd9IHVybD11bmRlZmluZWQgRGVmaW5lcyB0aGUgcmVzb3VyY2UgdGhhdCB5b3Ugd2lzaCB0byBmZXRjaC5cbiAgICAgKiBAcHJvcGVydHkge09iamVjdH0gY29ubmVjdGlvblxuICAgICAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBjb25uZWN0aW9uLnRpbWVvdXQ9NTAwMCBEZWZpbmVzIHRoZSB0aW1lb3V0IGZvciB0aGUgY29ubmVjdGlvbi5cbiAgICAgKiBAcHJvcGVydHkge051bWJlcn0gY29ubmVjdGlvbi5yZWNvbm5lY3QudGltZW91dCBUaGUgdGltZW91dCBpbiBtaWxsaXNlY29uZHMgZm9yIHRoZSByZWNvbm5lY3QuXG4gICAgICogQHByb3BlcnR5IHtOdW1iZXJ9IGNvbm5lY3Rpb24ucmVjb25uZWN0LmF0dGVtcHRzIFRoZSBtYXhpbXVtIG51bWJlciBvZiByZWNvbm5lY3RzLlxuICAgICAqIEBwcm9wZXJ0eSB7Qm9vbH0gY29ubmVjdGlvbi5yZWNvbm5lY3QuZW5hYmxlZCBJZiB0aGUgcmVjb25uZWN0IGlzIGVuYWJsZWQuXG4gICAgICovXG4gICAgZ2V0IGRlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3VwZXIuZGVmYXVsdHMsIHtcbiAgICAgICAgICAgIHVybDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgY29ubmVjdGlvbjoge1xuICAgICAgICAgICAgICAgIHRpbWVvdXQ6IDUwMDAsXG4gICAgICAgICAgICAgICAgcmVjb25uZWN0OiB7XG4gICAgICAgICAgICAgICAgICAgIHRpbWVvdXQ6IDEwMDAsXG4gICAgICAgICAgICAgICAgICAgIGF0dGVtcHRzOiAxLFxuICAgICAgICAgICAgICAgICAgICBlbmFibGVkOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgY2xvc2VzIHRoZSBjb25uZWN0aW9uLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IFtjb2RlPTEwMDBdIFRoZSBjbG9zZSBjb2RlLlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBbcmVhc29uPVwiXCJdIFRoZSBjbG9zZSByZWFzb24uXG4gICAgICogQHJldHVybnMge1Byb21pc2V9XG4gICAgICogQHNlZSBodHRwczovL3d3dy5yZmMtZWRpdG9yLm9yZy9yZmMvcmZjNjQ1NS5odG1sI3NlY3Rpb24tNy40LjFcbiAgICAgKi9cbiAgICBjbG9zZShzdGF0dXNDb2RlLCByZWFzb24pIHtcbiAgICAgICAgaWYgKCFpc0ludGVnZXIoc3RhdHVzQ29kZSkgfHwgc3RhdHVzQ29kZSA8IDEwMDAgfHwgc3RhdHVzQ29kZSA+IDQ5OTkpIHtcbiAgICAgICAgICAgIHN0YXR1c0NvZGUgPSAxMDAwO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNTdHJpbmcocmVhc29uKSkge1xuICAgICAgICAgICAgcmVhc29uID0gXCJcIjtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHRoaXNbbWFudWFsQ2xvc2VTeW1ib2xdID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBpZiAodGhpc1tjb25uZWN0aW9uU3ltYm9sXS5zb2NrZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpc1tjb25uZWN0aW9uU3ltYm9sXS5zb2NrZXQuY2xvc2Uoc3RhdHVzQ29kZSwgcmVhc29uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBvbGxzIHRoZSByZWNlaXZlIHF1ZXVlIGZvciBuZXcgbWVzc2FnZXMuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7TWVzc2FnZX1cbiAgICAgKi9cbiAgICBwb2xsKCkge1xuICAgICAgICByZXR1cm4gdGhpc1tyZWNlaXZlUXVldWVTeW1ib2xdLnBvbGwoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBcmUgdGhlcmUgYW55IG1lc3NhZ2VzIGluIHRoZSByZWNlaXZlIHF1ZXVlP1xuICAgICAqXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAgICovXG4gICAgZGF0YVJlY2VpdmVkKCkge1xuICAgICAgICByZXR1cm4gIXRoaXNbcmVjZWl2ZVF1ZXVlU3ltYm9sXS5pc0VtcHR5KCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IE1lc3NhZ2UgZnJvbSB0aGUgcmVjZWl2ZSBxdWV1ZSwgYnV0IGRvIG5vdCByZW1vdmUgaXQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fVxuICAgICAqL1xuICAgIHBlZWsoKSB7XG4gICAgICAgIHJldHVybiB0aGlzW3JlY2VpdmVRdWV1ZVN5bWJvbF0ucGVlaygpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEF0dGFjaCBhIG5ldyBvYnNlcnZlclxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYnNlcnZlcn0gb2JzZXJ2ZXJcbiAgICAgKiBAcmV0dXJucyB7UHJveHlPYnNlcnZlcn1cbiAgICAgKi9cbiAgICBhdHRhY2hPYnNlcnZlcihvYnNlcnZlcikge1xuICAgICAgICB0aGlzW3JlY2VpdmVRdWV1ZVN5bWJvbF0uYXR0YWNoT2JzZXJ2ZXIob2JzZXJ2ZXIpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZXRhY2ggYSBvYnNlcnZlclxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYnNlcnZlcn0gb2JzZXJ2ZXJcbiAgICAgKiBAcmV0dXJucyB7UHJveHlPYnNlcnZlcn1cbiAgICAgKi9cbiAgICBkZXRhY2hPYnNlcnZlcihvYnNlcnZlcikge1xuICAgICAgICB0aGlzW3JlY2VpdmVRdWV1ZVN5bWJvbF0uZGV0YWNoT2JzZXJ2ZXIob2JzZXJ2ZXIpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge09ic2VydmVyfSBvYnNlcnZlclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgICAqL1xuICAgIGNvbnRhaW5zT2JzZXJ2ZXIob2JzZXJ2ZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbcmVjZWl2ZVF1ZXVlU3ltYm9sXS5jb250YWluc09ic2VydmVyKG9ic2VydmVyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge01lc3NhZ2V8T2JqZWN0fSBtZXNzYWdlXG4gICAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICAgKi9cbiAgICBzZW5kKG1lc3NhZ2UpIHtcbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGlmIChzZWxmW2Nvbm5lY3Rpb25TeW1ib2xdLnNvY2tldC5yZWFkeVN0YXRlICE9PSAxKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KFwidGhlIHNvY2tldCBpcyBub3QgcmVhZHlcIik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHNlbGZbY29ubmVjdGlvblN5bWJvbF0uc29ja2V0LnNlbmQoSlNPTi5zdHJpbmdpZnkobWVzc2FnZSkpO1xuICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICB9KTtcbiAgICB9XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBRdWV1ZSB9IGZyb20gXCIuL3F1ZXVlLm1qc1wiO1xuaW1wb3J0IHsgaW5zdGFuY2VTeW1ib2wsIGludGVybmFsU3ltYm9sIH0gZnJvbSBcIi4uL2NvbnN0YW50cy5tanNcIjtcbmltcG9ydCB7IE9ic2VydmVyTGlzdCB9IGZyb20gXCIuL29ic2VydmVybGlzdC5tanNcIjtcblxuZXhwb3J0IHsgT2JzZXJ2YWJsZVF1ZXVlIH07XG5cbi8qKlxuICogQW4gb2JzZXJ2YWJsZSBxdWV1ZSBpcyBhIGxpc3Qgb2YgaXRlbXMgdGhhdCBhcmUgcHJvY2Vzc2VkIG9uZSBhZnRlciBhbm90aGVyIChmaXJzdCBpbiwgZmlyc3Qgb3V0KS5cbiAqXG4gKiBgUXVldWUuYWRkKClgIGFuZCBgUXVldWUuY2xlYXIoKWAgbm90aWZ5IGFsbCBvYnNlcnZlcnMuXG4gKlxuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL3R5cGVzL3F1ZXVlLm1qc1xuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMy4zLjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UeXBlc1xuICogQHN1bW1hcnkgQW4gb2JzZXJ2YWJsZSBRdWV1ZSAoRmlmbylcbiAqL1xuY2xhc3MgT2JzZXJ2YWJsZVF1ZXVlIGV4dGVuZHMgUXVldWUge1xuICAgIC8qKlxuICAgICAqXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXNbaW50ZXJuYWxTeW1ib2xdID0ge1xuICAgICAgICAgICAgb2JzZXJ2ZXJzOiBuZXcgT2JzZXJ2ZXJMaXN0KCksXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMi4xLjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci90eXBlcy9vYnNlcnZhYmxlcXVldWVcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkIGEgbmV3IGVsZW1lbnQgdG8gdGhlIGVuZCBvZiB0aGUgcXVldWUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlXG4gICAgICogQHJldHVybnMge1F1ZXVlfVxuICAgICAqL1xuICAgIGFkZCh2YWx1ZSkge1xuICAgICAgICBzdXBlci5hZGQodmFsdWUpO1xuICAgICAgICB0aGlzLm5vdGlmeU9ic2VydmVycygpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiByZW1vdmUgYWxsIGVudHJpZXNcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtRdWV1ZX1cbiAgICAgKi9cbiAgICBjbGVhcigpIHtcbiAgICAgICAgc3VwZXIuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5ub3RpZnlPYnNlcnZlcnMoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQXR0YWNoIGEgbmV3IG9ic2VydmVyXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge09ic2VydmVyfSBvYnNlcnZlclxuICAgICAqIEByZXR1cm5zIHtQcm94eU9ic2VydmVyfVxuICAgICAqL1xuICAgIGF0dGFjaE9ic2VydmVyKG9ic2VydmVyKSB7XG4gICAgICAgIHRoaXNbaW50ZXJuYWxTeW1ib2xdLm9ic2VydmVycy5hdHRhY2gob2JzZXJ2ZXIpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZXRhY2ggYSBvYnNlcnZlclxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYnNlcnZlcn0gb2JzZXJ2ZXJcbiAgICAgKiBAcmV0dXJucyB7UHJveHlPYnNlcnZlcn1cbiAgICAgKi9cbiAgICBkZXRhY2hPYnNlcnZlcihvYnNlcnZlcikge1xuICAgICAgICB0aGlzW2ludGVybmFsU3ltYm9sXS5vYnNlcnZlcnMuZGV0YWNoKG9ic2VydmVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTm90aWZ5IGFsbCBvYnNlcnZlclxuICAgICAqXG4gICAgICogQHJldHVybnMge1Byb21pc2V9XG4gICAgICovXG4gICAgbm90aWZ5T2JzZXJ2ZXJzKCkge1xuICAgICAgICByZXR1cm4gdGhpc1tpbnRlcm5hbFN5bWJvbF0ub2JzZXJ2ZXJzLm5vdGlmeSh0aGlzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge09ic2VydmVyfSBvYnNlcnZlclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgICAqL1xuICAgIGNvbnRhaW5zT2JzZXJ2ZXIob2JzZXJ2ZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbaW50ZXJuYWxTeW1ib2xdLm9ic2VydmVycy5jb250YWlucyhvYnNlcnZlcik7XG4gICAgfVxufVxuIiwgImltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge1dlYkNvbm5lY3R9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvbmV0L3dlYmNvbm5lY3QubWpzXCI7XG5pbXBvcnQge01lc3NhZ2V9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvbmV0L3dlYmNvbm5lY3QvbWVzc2FnZS5tanNcIjtcbmltcG9ydCB7T2JzZXJ2ZXJ9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdHlwZXMvb2JzZXJ2ZXIubWpzXCI7XG5pbXBvcnQge2luaXRXZWJTb2NrZXR9IGZyb20gXCIuLi8uLi91dGlsL3dlYnNvY2tldC5tanNcIjtcblxuY29uc3QgdGVzdFVybCA9IFwid3NzOi8vd3MucG9zdG1hbi1lY2hvLmNvbS9yYXdcIlxuXG5kZXNjcmliZSgnV2Vic29ja2V0JywgZnVuY3Rpb24gKCkge1xuXG4gICAgbGV0IGRzID0gdW5kZWZpbmVkXG5cbiAgICBiZWZvcmUoZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgaW5pdFdlYlNvY2tldCgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgZG9uZSgpXG4gICAgICAgIH0pLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICBkb25lKGUpXG4gICAgICAgIH0pXG4gICAgfSk7XG5cbiAgICBhZnRlckVhY2goZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgaWYgKGRzKSB7XG4gICAgICAgICAgICBkcy5jbG9zZSgpXG4gICAgICAgIH1cblxuICAgICAgICAvLyB3aXRob3V0IHRoaXMsIHRoZSBub2RlIHRlc3Qgd2lsbCBoYW5nIFxuICAgICAgICBmb3IgKGNvbnN0IHN5bSBvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKGRzKSkge1xuICAgICAgICAgICAgaWYgKHN5bS50b1N0cmluZygpID09PSAnU3ltYm9sKGNvbm5lY3Rpb24pJykge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgZHNbc3ltXT8uc29ja2V0Py50ZXJtaW5hdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgZHNbc3ltXT8uc29ja2V0Py5bJ3Rlcm1pbmF0ZSddKClcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBkb25lKClcbiAgICB9KTtcblxuXG4gICAgaXQoJ3Nob3VsZCB0cmFuc2Zvcm0gZGF0YScsIGZ1bmN0aW9uIChkb25lKSB7XG5cbiAgICAgICAgZHMgPSBuZXcgV2ViQ29ubmVjdCgge1xuICAgICAgICAgICAgdXJsOiB0ZXN0VXJsLFxuICAgICAgICB9KVxuXG4gICAgICAgIGRzLmNvbm5lY3QoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgZHMuYXR0YWNoT2JzZXJ2ZXIobmV3IE9ic2VydmVyKCgpPT4ge1xuICAgICAgICAgICAgICAgZG9uZSgpXG4gICAgICAgICAgICB9KSlcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgZHMuc2VuZCh7XG4gICAgICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBcIkhlbGxvIFdvcmxkXCJcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuXG4gICAgICAgIH0pLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICBkb25lKGUpXG4gICAgICAgIH0pXG5cblxuICAgIH0pXG5cbiAgICBpdCgnc2hvdWxkIGNvbm5lY3QnLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICBkcyA9IG5ldyBXZWJDb25uZWN0KHtcbiAgICAgICAgICAgIHVybDogdGVzdFVybCxcbiAgICAgICAgICAgIHJlY29ubmVjdDoge1xuICAgICAgICAgICAgICAgIGVuYWJsZWQ6IGZhbHNlXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBkcy5jb25uZWN0KCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICBkb25lKClcbiAgICAgICAgfSkuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIGRvbmUoZSlcbiAgICAgICAgfSlcblxuXG4gICAgfSlcblxuICAgIGl0KCdzaG91bGQgc2VuZCBtZXNzYWdlJywgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgZHMgPSBuZXcgV2ViQ29ubmVjdCh7XG4gICAgICAgICAgICB1cmw6IHRlc3RVcmwsXG4gICAgICAgICAgICByZWNvbm5lY3Q6IHtcbiAgICAgICAgICAgICAgICBlbmFibGVkOiBmYWxzZVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgZHMuY29ubmVjdCgpLnRoZW4oKCkgPT4ge1xuXG4gICAgICAgICAgICBkcy5hdHRhY2hPYnNlcnZlcihuZXcgT2JzZXJ2ZXIoKCk9PiB7XG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgZXhwZWN0KGRzLmRhdGFSZWNlaXZlZCgpKS50by5iZS50cnVlXG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbXNnID0gZHMucG9sbCgpXG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChtc2cpLnRvLmJlLmluc3RhbmNlT2YoTWVzc2FnZSlcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZGF0YSA9IG1zZy5nZXREYXRhKClcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KGRhdGEpLnRvLmJlLmRlZXAuZXF1YWwoe21lc3NhZ2U6IFwiSGVsbG8gV29ybGRcIn0pXG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICBkb25lKGUpXG4gICAgICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkb25lKClcbiAgICAgICAgICAgIH0pKVxuXG4gICAgICAgICAgICBkcy5zZW5kKHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogXCJIZWxsbyBXb3JsZFwiXG4gICAgICAgICAgICB9KVxuXG4gICAgICAgIH0pLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICBkb25lKGUpXG4gICAgICAgIH0pXG5cblxuICAgIH0pLnRpbWVvdXQoMTAwMDApO1xuXG59KTtcbiIsICJpbXBvcnQge2dldEdsb2JhbH0gZnJvbSBcIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS90eXBlcy9nbG9iYWwubWpzXCI7XG5cbmZ1bmN0aW9uIGluaXRXZWJTb2NrZXQoKSB7XG4gICAgaWYgKHR5cGVvZiB3aW5kb3cgPT09IFwib2JqZWN0XCIgJiYgd2luZG93WydXZWJTb2NrZXQnXSkgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuXG4gICAgcmV0dXJuIGltcG9ydChcIndzXCIpLnRoZW4oKHdzKSA9PiB7XG4gICAgICAgIGdldEdsb2JhbCgpLldlYlNvY2tldCA9IGNsYXNzIGV4dGVuZHMgd3NbJ1dlYlNvY2tldCddIHtcbiAgICAgICAgICAgIGNvbnN0cnVjdG9yKHVybCwgcHJvdG9jb2xzKSB7XG4gICAgICAgICAgICAgICAgc3VwZXIodXJsLCBwcm90b2NvbHMsIHtcbiAgICAgICAgICAgICAgICAgICAgaGFuZHNoYWtlVGltZW91dDogMTAwMCxcbiAgICAgICAgICAgICAgICAgICAgbWF4UGF5bG9hZDogMTAyNCAqIDEwMjQgKiAxMDI0LFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBcbiAgICB9KTtcblxuXG59XG5cbmV4cG9ydCB7aW5pdFdlYlNvY2tldH0iLCAiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuaW1wb3J0IHtNZWRpYVR5cGUsIHBhcnNlTWVkaWFUeXBlfSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL21lZGlhdHlwZS5tanNcIjtcblxuZGVzY3JpYmUoJ0RhdGF1cmwnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBbXG4gICAgICAgIFtcIiovKlwiLFwiKlwiLCcqJ10sXG4gICAgICAgIFtcInRleHQvKlwiLFwidGV4dFwiLCcqJ10sXG4gICAgICAgIFtcIiovdGVzdFwiLFwiKlwiLCd0ZXN0J10sXG4gICAgICAgIFtcImltYWdlL3BuZ1wiLCBcImltYWdlXCIsIFwicG5nXCJdLFxuICAgICAgICBbXCJhdWRpby9tcDNcIiwgXCJhdWRpb1wiLCBcIm1wM1wiXSxcbiAgICAgICAgW1widmlkZW8vbXBlZ1wiLCBcInZpZGVvXCIsIFwibXBlZ1wiXSxcbiAgICAgICAgW1widGV4dC9wbGFpblwiLCBcInRleHRcIiwgXCJwbGFpblwiXSxcbiAgICAgICAgW1widGV4dC9odG1sXCIsIFwidGV4dFwiLCBcImh0bWxcIl0sXG4gICAgICAgIFtcInRleHQvaHRtbDtjaGFyc2V0PVVTLUFTQ0lJXCIsIFwidGV4dFwiLCBcImh0bWxcIl0sXG4gICAgICAgIFtcInRleHQvaHRtbDtjaGFyc2V0PVxcXCJVUy1BU0NJSVxcXCJcIiwgXCJ0ZXh0XCIsIFwiaHRtbFwiXSxcblxuICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG4gICAgICAgIGxldCBjID0gZGF0YS5zaGlmdCgpXG5cblxuICAgICAgICBpdCgncGFyc2VNZWRpYVR5cGUoJyArIGEgKyAnKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgY29uc3QgZCA9IHBhcnNlTWVkaWFUeXBlKGEpO1xuXG4gICAgICAgICAgICBleHBlY3QoZCkuaXMuaW5zdGFuY2VvZihNZWRpYVR5cGUpO1xuICAgICAgICAgICAgZXhwZWN0KGQudG9TdHJpbmcoKSkudG8uYmUuZXF1YWwoYSk7XG4gICAgICAgICAgICBleHBlY3QoZC50eXBlKS50by5iZS5lcXVhbChiKTtcbiAgICAgICAgICAgIGV4cGVjdChkLnN1YnR5cGUpLnRvLmJlLmVxdWFsKGMpO1xuICAgICAgICAgICAgZXhwZWN0KGQucGFyYW1ldGVyKS5pcy5pbnN0YW5jZW9mKE1hcClcbiAgICAgICAgfSlcblxuICAgIH0pO1xuXG4gICAgW1xuICAgICAgICBbXCJ2aWRlby9cIl0sXG4gICAgICAgIFtcInRleHRcIl0sXG4gICAgICAgIFtcIi9tcDNcIl0sXG4gICAgICAgIFtcInRleHQvaHRtbDtjaGFyc2V0VVMtQVNDSUlcIl0sXG4gICAgICAgIFtcInRleHQvaHRtbDtjaGFyc2V0XFxcIlVTLUFTQ0lJXFxcIlwiXSxcblxuICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgaXQoJycgKyBhICsgJyBzaG91bGQgdGhyb3cgZXhjZXB0aW9uJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBleHBlY3QoKCk9PntwYXJzZU1lZGlhVHlwZShhKX0pLnRocm93KFR5cGVFcnJvcik7XG4gICAgICAgICAgICBcbiAgICAgICAgfSlcblxuICAgIH0pO1xuXG5cbn0pOyIsICJpbXBvcnQge1N0YWNrfSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL3N0YWNrLm1qc1wiO1xuaW1wb3J0IHtcbiAgICB0eXBlT2Zcbn0gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS90eXBlcy90eXBlb2YubWpzXCJcblxuaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcblxuZGVzY3JpYmUoJ3R5cGVPZicsIGZ1bmN0aW9uICgpIHtcblxuICAgIGRlc2NyaWJlKCcudHlwZU9mKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgW3RydWUsICdib29sZWFuJ10sXG4gICAgICAgICAgICBbbnVsbCwgJ251bGwnXSxcbiAgICAgICAgICAgIFt1bmRlZmluZWQsICd1bmRlZmluZWQnXSxcbiAgICAgICAgICAgIFtQcm9taXNlLnJlc29sdmUoKSwgJ3Byb21pc2UnXSxcbiAgICAgICAgICAgIFtuZXcgV2Vha01hcCgpLCAnd2Vha21hcCddLFxuICAgICAgICAgICAgW25ldyBNYXAoKSwgJ21hcCddLFxuICAgICAgICAgICAgW05hTiwgJ251bWJlciddLFxuICAgICAgICAgICAgW2Z1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICB9LCAnZ2VuZXJhdG9yZnVuY3Rpb24nXSxcbiAgICAgICAgICAgIFs1LCAnbnVtYmVyJ10sXG4gICAgICAgICAgICBbZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgfSwgJ2Z1bmN0aW9uJ10sXG4gICAgICAgICAgICBbL2EvLCAncmVnZXhwJ10sXG4gICAgICAgICAgICBbbmV3IERhdGUoKSwgJ2RhdGUnXSxcbiAgICAgICAgICAgIFt7fSwgJ29iamVjdCddLFxuICAgICAgICAgICAgW1tdLCAnYXJyYXknXSxcbiAgICAgICAgICAgIFsnJywgJ3N0cmluZyddLFxuICAgICAgICAgICAgW25ldyBFcnJvciwgJ2Vycm9yJ10sXG4gICAgICAgICAgICBbbmV3IFN0YWNrLCAnc3RhY2snXVxuXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gJyArIGIgKyAnIHdoZW4gdGhlIHZhbHVlICcgKyB0eXBlT2YoYSksIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBleHBlY3QodHlwZU9mKGEpKS50by5iZS5lcXVhbChiKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgIH0pO1xuXG5cbn0pO1xuXG4iLCAiaW1wb3J0IHtPYnNlcnZlckxpc3R9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdHlwZXMvb2JzZXJ2ZXJsaXN0Lm1qc1wiO1xuaW1wb3J0IHtPYnNlcnZlcn0gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS90eXBlcy9vYnNlcnZlci5tanNcIjtcbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5cbmRlc2NyaWJlKCdPYnNlcnZlckxpc3QnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBkZXNjcmliZSgnLmF0dGFjaCgpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGluc3RhbmNlb2YgT2JzZXJ2ZXJMaXN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGV0IG9ic2VydmVyTGlzdCA9IG5ldyBPYnNlcnZlckxpc3QoKVxuICAgICAgICAgICAgbGV0IHJlc3VsdCA9IG9ic2VydmVyTGlzdC5hdHRhY2gobmV3IE9ic2VydmVyKCgpID0+IHtcbiAgICAgICAgICAgIH0pKVxuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdCkudG8uYmUuaW5zdGFuY2VPZihPYnNlcnZlckxpc3QpXG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCcuZGV0YWNoKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gaW5zdGFuY2VvZiBPYnNlcnZlckxpc3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgb2JzZXJ2ZXJMaXN0ID0gbmV3IE9ic2VydmVyTGlzdCgpXG4gICAgICAgICAgICBsZXQgcmVzdWx0ID0gb2JzZXJ2ZXJMaXN0LmRldGFjaChuZXcgT2JzZXJ2ZXIoKCkgPT4ge1xuICAgICAgICAgICAgfSkpXG4gICAgICAgICAgICBleHBlY3QocmVzdWx0KS50by5iZS5pbnN0YW5jZU9mKE9ic2VydmVyTGlzdClcbiAgICAgICAgfSk7XG5cblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJy5ub3RpZnkoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBjb25zdCByZXN1bHRWYWx1ZSA9IFwiWWVzIVwiO1xuICAgICAgICBsZXQgbztcbiAgICAgICAgbGV0IG9ic2VydmVyTGlzdDtcblxuICAgICAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAgICAgIG8gPSBuZXcgT2JzZXJ2ZXIoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHRWYWx1ZVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIG9ic2VydmVyTGlzdCA9IG5ldyBPYnNlcnZlckxpc3QoKVxuICAgICAgICAgICAgb2JzZXJ2ZXJMaXN0LmF0dGFjaChvKVxuXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgaW5zdGFuY2VvZiBQcm9taXNlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KG9ic2VydmVyTGlzdC5ub3RpZnkoe30pKS50by5iZS5pbnN0YW5jZU9mKFByb21pc2UpXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuICcgKyByZXN1bHRWYWx1ZSwgZnVuY3Rpb24gKGRvbmUpIHtcblxuICAgICAgICAgICAgbGV0IG9iaiA9IHt9XG5cbiAgICAgICAgICAgIG9ic2VydmVyTGlzdC5ub3RpZnkob2JqKS50aGVuKHIgPT4ge1xuICAgICAgICAgICAgICAgIGV4cGVjdChyKS50by5iZS5hbignYXJyYXknKS50aGF0LmluY2x1ZGVzKHJlc3VsdFZhbHVlKTtcbiAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICB9KS5jYXRjaChlID0+IHtcbiAgICAgICAgICAgICAgICBkb25lKG5ldyBFcnJvcihlKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJy5jb250YWlucygpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGxldCBvMSA9IG5ldyBPYnNlcnZlcigoKSA9PiB7XG4gICAgICAgIH0pO1xuICAgICAgICBsZXQgbzIgPSBuZXcgT2JzZXJ2ZXIoKCkgPT4ge1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIG5vdCBjb250YWluIG8xIGFuZCBvMicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBvYnNlcnZlckxpc3QgPSBuZXcgT2JzZXJ2ZXJMaXN0KClcblxuICAgICAgICAgICAgZXhwZWN0KG9ic2VydmVyTGlzdC5jb250YWlucyhvMSkpLnRvLmJlLmZhbHNlO1xuICAgICAgICAgICAgZXhwZWN0KG9ic2VydmVyTGlzdC5jb250YWlucyhvMikpLnRvLmJlLmZhbHNlO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIGNvbnRhaW4gbzIgYW5kIG5vdCBvMScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBvYnNlcnZlckxpc3QgPSBuZXcgT2JzZXJ2ZXJMaXN0KClcbiAgICAgICAgICAgIG9ic2VydmVyTGlzdC5hdHRhY2gobzIpXG4gICAgICAgICAgICBleHBlY3Qob2JzZXJ2ZXJMaXN0LmNvbnRhaW5zKG8xKSkudG8uYmUuZmFsc2U7XG4gICAgICAgICAgICBleHBlY3Qob2JzZXJ2ZXJMaXN0LmNvbnRhaW5zKG8yKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBjb250YWluIG8xIGFuZCBub3QgbzInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgb2JzZXJ2ZXJMaXN0ID0gbmV3IE9ic2VydmVyTGlzdCgpXG4gICAgICAgICAgICBvYnNlcnZlckxpc3QuYXR0YWNoKG8xKVxuICAgICAgICAgICAgZXhwZWN0KG9ic2VydmVyTGlzdC5jb250YWlucyhvMSkpLnRvLmJlLnRydWU7XG4gICAgICAgICAgICBleHBlY3Qob2JzZXJ2ZXJMaXN0LmNvbnRhaW5zKG8yKSkudG8uYmUuZmFsc2U7XG4gICAgICAgIH0pO1xuXG5cbiAgICAgICAgaXQoJ3Nob3VsZCBjb250YWluIG8yIGFuZCBvMScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBvYnNlcnZlckxpc3QgPSBuZXcgT2JzZXJ2ZXJMaXN0KClcbiAgICAgICAgICAgIG9ic2VydmVyTGlzdC5hdHRhY2gobzIpLmF0dGFjaChvMSlcbiAgICAgICAgICAgIGV4cGVjdChvYnNlcnZlckxpc3QuY29udGFpbnMobzEpKS50by5iZS50cnVlO1xuICAgICAgICAgICAgZXhwZWN0KG9ic2VydmVyTGlzdC5jb250YWlucyhvMikpLnRvLmJlLnRydWU7XG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxuXG59KTtcblxuIiwgImltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5cbmRlc2NyaWJlKCdSYW5kb21JRCcsIGZ1bmN0aW9uICgpIHtcblxuICAgIGNsYXNzIFJhbmRvbUlEIHt9XG4gICAgXG4gICAgYmVmb3JlKGZ1bmN0aW9uIChkb25lKSB7XG5cbiAgICAgICAgbGV0IHByb21pc2VzID0gW11cbiAgICAgICAgaWYoIWdsb2JhbFRoaXNbJ2NyeXB0byddKSB7XG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKGltcG9ydChcIkBwZWN1bGlhci93ZWJjcnlwdG9cIikudGhlbihtID0+IHtcbiAgICAgICAgICAgICAgICBnbG9iYWxUaGlzWydjcnlwdG8nXSA9IG5ldyBtLkNyeXB0bygpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfSkpXG4gICAgICAgIH1cblxuICAgICAgICBwcm9taXNlcy5wdXNoKGltcG9ydChcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS90eXBlcy9yYW5kb21pZC5tanNcIikudGhlbihtID0+IHtcbiAgICAgICAgICAgIFJhbmRvbUlEID0gbS5SYW5kb21JRDtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9KSlcblxuICAgICAgICBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7XG4gICAgICAgICAgICBkb25lKClcbiAgICAgICAgfSk7XG5cbiAgICB9KTsgICAgXG4gICAgXG4gICAgZGVzY3JpYmUoJy50b1N0cmluZygpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgaWQgPSBuZXcgUmFuZG9tSUQoKVxuICAgICAgICBsZXQgcmVzdWx0ID0gaWQudG9TdHJpbmcoKTtcblxuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBhIHN0cmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHQpLmlzLmEoJ3N0cmluZycpXG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cbn0pO1xuXG4iLCAiaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7T2JzZXJ2YWJsZVF1ZXVlfSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL29ic2VydmFibGVxdWV1ZS5tanNcIjtcbmltcG9ydCB7T2JzZXJ2ZXJ9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdHlwZXMvb2JzZXJ2ZXIubWpzXCI7XG5cbmRlc2NyaWJlKCdPYnNlcnZhYmxlUXVldWUnLCBmdW5jdGlvbiAoKSB7XG4gICAgZGVzY3JpYmUoJ09ic2VydmVyJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdzaG91bGQgbm90aWZ5JywgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgICAgIGxldCBxdWV1ZSA9IG5ldyBPYnNlcnZhYmxlUXVldWU7XG4gICAgICAgICAgICBsZXQgbyA9IG5ldyBPYnNlcnZlcigocSkgPT4ge1xuICAgICAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBxdWV1ZS5hdHRhY2hPYnNlcnZlcihvKTtcbiAgICAgICAgICAgIGV4cGVjdChxdWV1ZS5hZGQoJ2EnKSkudG8uYmUuaW5zdGFuY2VPZihPYnNlcnZhYmxlUXVldWUpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbn0pIiwgImltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5cbmRlc2NyaWJlKCdVVUlEJywgZnVuY3Rpb24gKCkge1xuXG4gICAgY2xhc3MgVVVJRCB7fVxuICAgIFxuICAgIGJlZm9yZShmdW5jdGlvbiAoZG9uZSkge1xuXG4gICAgICAgIGxldCBwcm9taXNlcyA9IFtdXG4gICAgICAgIFxuICAgICAgICBpZighZ2xvYmFsVGhpc1snY3J5cHRvJ10pIHtcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2goaW1wb3J0KFwiQHBlY3VsaWFyL3dlYmNyeXB0b1wiKS50aGVuKG0gPT4ge1xuICAgICAgICAgICAgICAgIGdsb2JhbFRoaXNbJ2NyeXB0byddID0gbmV3IG0uQ3J5cHRvKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9KSlcbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgXG4gICAgICAgIHByb21pc2VzLnB1c2goaW1wb3J0KFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL3V1aWQubWpzXCIpLnRoZW4obSA9PiB7XG4gICAgICAgICAgICBVVUlEID0gbS5VVUlEO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pKVxuICAgICAgICBcbiAgICAgICAgUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgZG9uZSgpXG4gICAgICAgIH0pO1xuXG4gICAgfSk7ICAgIFxuICAgIFxuICAgIGRlc2NyaWJlKCcudG9TdHJpbmcoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gYSBzdHJpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgdXVpZCA9IG5ldyBVVUlEKClcbiAgICAgICAgICAgIGxldCByZXN1bHQgPSB1dWlkLnRvU3RyaW5nKCk7XG5cbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHQpLmlzLmEoJ3N0cmluZycpXG4gICAgICAgICAgICBleHBlY3QocmVzdWx0Lmxlbmd0aCkuaXMuZXF1YWwoMzYpXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCd0ZXN0IGZvcm1hdCcsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICBsZXQgdXVpZCA9IG5ldyBVVUlEKClcbiAgICAgICAgICAgIGxldCByZXN1bHQgPSB1dWlkLnRvU3RyaW5nKCk7XG5cbiAgICAgICAgICAgIGNvbnN0IHJlZ2V4RXhwID0gL15bQS1GXFxkXXs4fS1bQS1GXFxkXXs0fS00W0EtRlxcZF17M30tWzg5QUJdW0EtRlxcZF17M30tW0EtRlxcZF17MTJ9JC9pO1xuXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IDIwMDA7IGkrKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHUgPSBuZXcgVVVJRCgpLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgY29uc3QgciA9IHJlZ2V4RXhwLnRlc3QodSk7XG5cbiAgICAgICAgICAgICAgICBpZiAociAhPT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgICAgICBkb25lKCdubyB1dWlkICcgKyB1ICsgJyA9PiAnICsgcik7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGRvbmUoKTtcblxuICAgICAgICB9KTtcblxuICAgIH0pO1xuXG59KTtcblxuIiwgImltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5cbmltcG9ydCB7T2JzZXJ2ZXJ9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdHlwZXMvb2JzZXJ2ZXIubWpzXCI7XG5cblxuZGVzY3JpYmUoJ09ic2VydmVyJywgZnVuY3Rpb24gKCkge1xuXG4gICAgbGV0IGNhbGxiYWNrID0gZnVuY3Rpb24gKCkge1xuICAgIH07XG5cbiAgICBsZXQgb2JzZXJ2ZXIgPSBuZXcgT2JzZXJ2ZXIoY2FsbGJhY2spXG5cbiAgICBkZXNjcmliZSgnLmFkZFRhZygpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIFtcbiAgICAgICAgICAgIFsndGVzdDEnXSxcbiAgICAgICAgICAgIFsndGVzdDInXSxcbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGl0KCdhZGRUYWcoJyArIGEgKyAnKSBzaG91bGQgcmV0dXJuIGluc3RhbmNlb2YgT2JzZXJ2ZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KG9ic2VydmVyLmFkZFRhZyhhKSkuaXMuaW5zdGFuY2VPZihPYnNlcnZlcilcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJy5yZW1vdmVUYWcoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBbXG4gICAgICAgICAgICBbJ3Rlc3QxJ10sXG4gICAgICAgICAgICBbJ3Rlc3QyJ10sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpdCgncmVtb3ZlVGFnKCcgKyBhICsgJykgc2hvdWxkIHJldHVybiBpbnN0YW5jZW9mIE9ic2VydmVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGV4cGVjdChvYnNlcnZlci5yZW1vdmVUYWcoYSkpLmlzLmluc3RhbmNlT2YoT2JzZXJ2ZXIpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCcuaGFzVGFnKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWyd0ZXN0MScsIHRydWVdLFxuICAgICAgICAgICAgWyd0ZXN0MicsIHRydWVdLFxuICAgICAgICAgICAgWyd0ZXN0MycsIGZhbHNlXSxcbiAgICAgICAgICAgIFsndGVzdDQnLCBmYWxzZV0sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgdGVtcE9ic2VydmVyID0gbmV3IE9ic2VydmVyKGNhbGxiYWNrKVxuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ29ic2VydmVyLmhhc3RUYWcoJyArIGEgKyAnKSBzaG91bGQgcmV0dXJuICcgKyBiLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgICAgICBpZiAoYiA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgICAgICB0ZW1wT2JzZXJ2ZXIuYWRkVGFnKGEpXG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdCh0ZW1wT2JzZXJ2ZXIuaGFzVGFnKGEpKS5pcy5iZS50cnVlXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KHRlbXBPYnNlcnZlci5oYXNUYWcoYSkpLmlzLmJlLmZhbHNlXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnLnVwZGF0ZSgpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGxldCBvYmogPSB7fVxuICAgICAgICBpdCgnb2JzZXJ2ZXIudXBkYXRlKCcgKyBvYmogKyAnKSBpcyAnICsgMSArIDMgKyA2LCBmdW5jdGlvbiAoZG9uZSkge1xuXG4gICAgICAgICAgICBsZXQgdGVtcE9ic2VydmVyID0gbmV3IE9ic2VydmVyKGZ1bmN0aW9uIChhLCBiLCBjKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGEgKyBiICsgY1xuICAgICAgICAgICAgfSwgMSwgMywgNilcblxuXG4gICAgICAgICAgICB0ZW1wT2JzZXJ2ZXIudXBkYXRlKG9iaikudGhlbihhID0+IHtcbiAgICAgICAgICAgICAgICBleHBlY3QoYSkuaXMuZXF1YWwoMSArIDMgKyA2KVxuICAgICAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3J1biBmdW5jdGlvbiAudXBkYXRlKCkgc2V2ZXJhbCB0aW1lcycsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBsZXQgb2JqID0ge31cbiAgICAgICAgaXQoJ29ic2VydmVyLnVwZGF0ZSgnICsgb2JqICsgJykgaXMgJyArIDEgKyAzICsgNiwgZnVuY3Rpb24gKGRvbmUpIHtcblxuICAgICAgICAgICAgbGV0IGNvdW50ZXIgPSAwO1xuICAgICAgICAgICAgbGV0IHRlbXBPYnNlcnZlciA9IG5ldyBPYnNlcnZlcihmdW5jdGlvbiAoYSwgYiwgYykge1xuICAgICAgICAgICAgICAgIGNvdW50ZXIrKztcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIHRlbXBPYnNlcnZlci51cGRhdGUob2JqKTtcbiAgICAgICAgICAgIHRlbXBPYnNlcnZlci51cGRhdGUob2JqKTtcbiAgICAgICAgICAgIHRlbXBPYnNlcnZlci51cGRhdGUob2JqKTtcbiAgICAgICAgICAgIHRlbXBPYnNlcnZlci51cGRhdGUob2JqKTtcbiAgICAgICAgICAgIHRlbXBPYnNlcnZlci51cGRhdGUob2JqKS50aGVuKF8gPT4ge1xuICAgICAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgfSk7XG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCcuZ2V0VGFncygpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIFtcbiAgICAgICAgICAgIFtbJ3Rlc3QxJywgJ3Rlc3QyJywgJ3Rlc3QzJywgJ3Rlc3Q0J10sIDRdLFxuICAgICAgICAgICAgW1sndGVzdDEnLCAndGVzdDEnLCAndGVzdDMnLCAndGVzdDQnXSwgM10sIC8vIGRvdWJsZSB0ZXN0MSAoc2V0IGlzIHVuaXF1ZXVlKVxuICAgICAgICAgICAgW1sndGVzdDEnLCAndGVzdDEnLCAndGVzdDEnLCAndGVzdDQnXSwgMl0sIC8vIG11bHRpcGxlIHRlc3QxIChzZXQgaXMgdW5pcXVldWUpXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgdGVtcE9ic2VydmVyID0gbmV3IE9ic2VydmVyKGNhbGxiYWNrKVxuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIG1heCA9IGEubGVuZ3RoOyBpIDwgbWF4OyBpKyspIHtcbiAgICAgICAgICAgICAgICB0ZW1wT2JzZXJ2ZXIuYWRkVGFnKGFbaV0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpdCgnb2JzZXJ2ZXIuZ2V0VGFncygnICsgYSArICcpIGlzIGFycmF5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGV4cGVjdCh0ZW1wT2JzZXJ2ZXIuZ2V0VGFncygpKS50by5iZS5hbignYXJyYXknKVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGl0KCdvYnNlcnZlci5nZXRUYWdzKCcgKyBhICsgJykgc2hvdWxkIHJldHVybiAnICsgYiArIFwiIHRhZ3NcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGV4cGVjdCh0ZW1wT2JzZXJ2ZXIuZ2V0VGFncygpLmxlbmd0aCkuaXMuZXF1YWwoYik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICB9KTtcblxufSk7XG5cbiIsICJcInVzZSBzdHJpY3RcIjtcblxuaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7ZXF1aXBXaXRoSW50ZXJuYWx9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdHlwZXMvaW50ZXJuYWwubWpzXCI7XG5pbXBvcnQge09ic2VydmVyfSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL29ic2VydmVyLm1qc1wiO1xuXG5jbGFzcyBTb21lUmFuZG9tQ2xhc3MxIGV4dGVuZHMgT2JqZWN0IHtcblxuICAgIGRvaXQoKSB7XG4gICAgICAgIHJldHVybiBcImRvbmVcIjtcbiAgICB9XG59XG5cbmNsYXNzIFNvbWVSYW5kb21DbGFzczIgZXh0ZW5kcyBPYmplY3Qge1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIGVxdWlwV2l0aEludGVybmFsLmNhbGwodGhpcyk7XG4gICAgfVxuXG4gICAgZ2V0IGRlZmF1bHRJbnRlcm5hbCgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHRlc3Q6IFwidGVzdFwiXG4gICAgICAgIH1cbiAgICB9XG5cbn1cblxuZGVzY3JpYmUoJ0Jhc2UgaW5qZWN0IHdpdGggb3B0aW9ucycsIGZ1bmN0aW9uICgpIHtcblxuICAgIGRlc2NyaWJlKCduZXcgU29tZVJhbmRvbUNsYXNzJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdpcyBpbnN0YW5jZSBvZiBTb21lUmFuZG9tQ2xhc3MxJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KG5ldyBTb21lUmFuZG9tQ2xhc3MyKS5ub3QudG8uYmUuaW5zdGFuY2VPZihTb21lUmFuZG9tQ2xhc3MxKTtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgU29tZVJhbmRvbUNsYXNzMikudG8uYmUuaW5zdGFuY2VPZihTb21lUmFuZG9tQ2xhc3MyKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ2lzIGluc3RhbmNlIG9mIFNvbWVSYW5kb21DbGFzczInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IFNvbWVSYW5kb21DbGFzczEpLnRvLmJlLmluc3RhbmNlT2YoU29tZVJhbmRvbUNsYXNzMSk7XG4gICAgICAgICAgICBleHBlY3QobmV3IFNvbWVSYW5kb21DbGFzczEpLm5vdC50by5iZS5pbnN0YW5jZU9mKFNvbWVSYW5kb21DbGFzczIpO1xuICAgICAgICB9KTtcblxuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnRXh0ZW5kcyBTb21lUmFuZG9tQ2xhc3Mgd2l0aCBpbnRlcm5hbHMnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ2F0dGFjaCBhbmQgbm90aWZ5IGludGVybmFsIG9ic2VydmVyJywgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgICAgIGNvbnN0IGMgPSBuZXcgU29tZVJhbmRvbUNsYXNzMjtcbiAgICAgICAgICAgIGMuYXR0YWNoSW50ZXJuYWxPYnNlcnZlcihuZXcgT2JzZXJ2ZXIoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgYy5zZXRJbnRlcm5hbChcInRlc3RcIiwgXCJ0ZXN0XCIpO1xuXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdhdHRhY2ggYW5kIHJlbW92ZSBpbnRlcm5hbCBvYnNlcnZlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IGMgPSBuZXcgU29tZVJhbmRvbUNsYXNzMjtcblxuXG4gICAgICAgICAgICBjb25zdCBvYnNlcnZlciA9IG5ldyBPYnNlcnZlcigoKSA9PiB7XG5cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBleHBlY3QoYy5jb250YWluc0ludGVybmFsT2JzZXJ2ZXIob2JzZXJ2ZXIpKS50by5iZS5mYWxzZTtcbiAgICAgICAgICAgIGMuYXR0YWNoSW50ZXJuYWxPYnNlcnZlcihvYnNlcnZlcik7XG4gICAgICAgICAgICBleHBlY3QoYy5jb250YWluc0ludGVybmFsT2JzZXJ2ZXIob2JzZXJ2ZXIpKS50by5iZS50cnVlO1xuICAgICAgICAgICAgYy5kZXRhY2hJbnRlcm5hbE9ic2VydmVyKG9ic2VydmVyKTtcbiAgICAgICAgICAgIGV4cGVjdChjLmNvbnRhaW5zSW50ZXJuYWxPYnNlcnZlcihvYnNlcnZlcikpLnRvLmJlLmZhbHNlO1xuXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KFwiZ2V0SW50ZXJuYWwgYW5kIHNldEludGVybmFsXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IGMgPSBuZXcgU29tZVJhbmRvbUNsYXNzMjtcbiAgICAgICAgICAgIGV4cGVjdChjLnNldEludGVybmFsKFwidGVzdFwiLCBcInllYWhcIikpLnRvLmJlLmluc3RhbmNlT2YoU29tZVJhbmRvbUNsYXNzMik7XG4gICAgICAgICAgICBleHBlY3QoYy5nZXRJbnRlcm5hbChcInRlc3RcIikpLnRvLmJlLmVxdWFsKFwieWVhaFwiKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoXCJkZWFsIHdpdGggZGVmYXVsdCB2YWx1ZXNcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY29uc3QgdGVzdENsYXNzID0gY2xhc3MgZXh0ZW5kcyBPYmplY3Qge1xuICAgICAgICAgICAgICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICAgICAgICAgICAgICBzdXBlcigpO1xuICAgICAgICAgICAgICAgICAgICBlcXVpcFdpdGhJbnRlcm5hbC5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGdldCBpbnRlcm5hbERlZmF1bHRzKCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGVzdDogXCJ4eXpcIlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG5cbiAgICAgICAgICAgIGNvbnN0IGMgPSBuZXcgdGVzdENsYXNzO1xuICAgICAgICAgICAgZXhwZWN0KGMuZ2V0SW50ZXJuYWwoXCJ0ZXN0XCIpKS50by5iZS5lcXVhbChcInh5elwiKTtcbiAgICAgICAgICAgIGV4cGVjdChjLmdldEludGVybmFsKFwidGVzdDJcIiwgXCJhYmNcIikpLnRvLmJlLmVxdWFsKFwiYWJjXCIpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdChcImRlYWwgd2l0aCBkZWZhdWx0cyBmcm9tIGRlZmF1bHRzXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IHRlc3RDbGFzcyA9IGNsYXNzIGV4dGVuZHMgT2JqZWN0IHtcbiAgICAgICAgICAgICAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgICAgICAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgICAgICAgICAgICAgZXF1aXBXaXRoSW50ZXJuYWwuY2FsbCh0aGlzKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBnZXQgaW50ZXJuYWxEZWZhdWx0cygpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRlc3Q6IFwieHl6XCJcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgdGVzdENsYXNzMiA9IGNsYXNzIGV4dGVuZHMgdGVzdENsYXNzIHtcbiAgICAgICAgICAgICAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgICAgICAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgICAgICAgICAgICAgZXF1aXBXaXRoSW50ZXJuYWwuY2FsbCh0aGlzKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBnZXQgaW50ZXJuYWxEZWZhdWx0cygpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN1cGVyLmludGVybmFsRGVmYXVsdHMsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRlc3QyOiBcImFiY1wiXG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBjID0gbmV3IHRlc3RDbGFzczI7XG4gICAgICAgICAgICBleHBlY3QoYy5nZXRJbnRlcm5hbChcInRlc3RcIikpLnRvLmJlLmVxdWFsKFwieHl6XCIpO1xuICAgICAgICAgICAgZXhwZWN0KGMuZ2V0SW50ZXJuYWwoXCJ0ZXN0MlwiKSkudG8uYmUuZXF1YWwoXCJhYmNcIik7XG4gICAgICAgIH0pO1xuICAgICAgICBcbiAgICAgICAgaXQoXCJzZXQgbXVsdGlwbGUgdmFsdWVzXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IGMgPSBuZXcgU29tZVJhbmRvbUNsYXNzMjtcbiAgICAgICAgICAgIGV4cGVjdChjLnNldEludGVybmFscyh7XG4gICAgICAgICAgICAgICAgdGVzdDogXCJ5ZWFoXCIsXG4gICAgICAgICAgICAgICAgdGVzdDI6IFwieWVhaDJcIlxuICAgICAgICAgICAgfSkpLnRvLmJlLmluc3RhbmNlT2YoU29tZVJhbmRvbUNsYXNzMik7XG4gICAgICAgICAgICBleHBlY3QoYy5nZXRJbnRlcm5hbChcInRlc3RcIikpLnRvLmJlLmVxdWFsKFwieWVhaFwiKTtcbiAgICAgICAgICAgIGV4cGVjdChjLmdldEludGVybmFsKFwidGVzdDJcIikpLnRvLmJlLmVxdWFsKFwieWVhaDJcIik7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGMuc2V0SW50ZXJuYWxzKHtcbiAgICAgICAgICAgICAgICB0ZXN0MjogXCJ5ZWFoMi1uZXdcIixcbiAgICAgICAgICAgICAgICB0ZXN0MzogXCJ5ZWFoM1wiXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgZXhwZWN0KGMuZ2V0SW50ZXJuYWwoXCJ0ZXN0XCIpKS50by5iZS5lcXVhbChcInllYWhcIik7XG4gICAgICAgICAgICBleHBlY3QoYy5nZXRJbnRlcm5hbChcInRlc3QyXCIpKS50by5iZS5lcXVhbChcInllYWgyLW5ld1wiKTtcbiAgICAgICAgICAgIGV4cGVjdChjLmdldEludGVybmFsKFwidGVzdDNcIikpLnRvLmJlLmVxdWFsKFwieWVhaDNcIik7XG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cblxufSkiLCAiaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7VG9rZW5MaXN0fSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL3Rva2VubGlzdC5tanNcIjtcblxuXG5kZXNjcmliZSgnVG9rZW5MaXN0JywgZnVuY3Rpb24gKCkge1xuXG4gICAgZGVzY3JpYmUoJy50b1N0cmluZygpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgdG9rZW5MaXN0ID0gbmV3IFRva2VuTGlzdCgpXG4gICAgICAgIGxldCByZXN1bHQgPSB0b2tlbkxpc3QudG9TdHJpbmcoKTtcblxuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBhIHN0cmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHQpLnRvLmJlLmEoJ3N0cmluZycpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2V0IGFuZCByZW1vdmUgcmV0dXJuIGEgc3RyaW5nJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdCkudG8uYmUuYSgnc3RyaW5nJyk7XG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxuXG4gICAgZGVzY3JpYmUoJ2luaXQgd2l0aCBzdHJpbmcgaXRlcmFibGUnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ25ldyBUb2tlbkxpc3QoJyArIHR5cGVvZiBhICsgJykgdGhyb3cgVHlwZUVycm9yICcsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgbGV0IHRva2VucyA9IFtcImFiY1wiLCBcImRlZlwiLCBcImdoaVwiXVxuICAgICAgICAgICAgbGV0IGxpc3QgPSBuZXcgVG9rZW5MaXN0KHRva2Vucyk7XG4gICAgICAgICAgICBleHBlY3QobGlzdC50b1N0cmluZygpKS5pcy5lcXVhbChcImFiYyBkZWYgZ2hpXCIpO1xuICAgICAgICB9KTtcblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2luaXQgd2l0aCBpdGVyYWJsZSB3aXRob3V0IHN0cmluZyB2YWx1ZXMnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ25ldyBUb2tlbkxpc3QoJyArIHR5cGVvZiBhICsgJykgdGhyb3cgVHlwZUVycm9yICcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCB0b2tlbnMgPSBbXCJhYmNcIiwgNCwgXCJnaGlcIl1cbiAgICAgICAgICAgIGV4cGVjdCgoKSA9PiBuZXcgVG9rZW5MaXN0KHRva2VucykpLnRvLnRocm93KFR5cGVFcnJvcik7XG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnaW5pdCB2YWx1ZXMnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgLy8gY3VycmVudCwgZXhwZWN0ZWQsIHR5cGVycm9yXG4gICAgICAgICAgICBbJ3Rlc3QxJywgXCJ0ZXN0MVwiLCBmYWxzZV0sXG4gICAgICAgICAgICBbJ3Rlc3QxIHRlc3QyJywgXCJ0ZXN0MSB0ZXN0MlwiLCBmYWxzZV0sXG4gICAgICAgICAgICBbdW5kZWZpbmVkLCBcIlwiLCBmYWxzZV0sXG4gICAgICAgICAgICBbbnVsbCwgdW5kZWZpbmVkLCB0cnVlXSxcbiAgICAgICAgICAgIFtwYXJzZUludChcImFcIiksIHVuZGVmaW5lZCwgdHJ1ZV0sIC8vIE5hTlxuICAgICAgICAgICAgWygpID0+IHtcbiAgICAgICAgICAgIH0sIHVuZGVmaW5lZCwgdHJ1ZV0sXG4gICAgICAgICAgICBbMiwgdW5kZWZpbmVkLCB0cnVlXSxcbiAgICAgICAgICAgIFtmYWxzZSwgdW5kZWZpbmVkLCB0cnVlXSxcbiAgICAgICAgICAgIFt0cnVlLCB1bmRlZmluZWQsIHRydWVdLFxuICAgICAgICAgICAgWzQuNSwgdW5kZWZpbmVkLCB0cnVlXSxcbiAgICAgICAgICAgIFt7fSwgdW5kZWZpbmVkLCB0cnVlXSxcbiAgICAgICAgICAgIFtbXCIxXCIsIFwiMlwiLCBcIjNcIl0sICcxIDIgMycsIGZhbHNlXSwgLy8gaXRlcmFibGUgc3RyaW5nc1xuICAgICAgICAgICAgW1sxLCAyLCAzXSwgdW5kZWZpbmVkLCB0cnVlXSxcbiAgICAgICAgICAgIFtTeW1ib2woXCJmb29cIiksIGZhbHNlLCB0cnVlXSxcbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGMgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaWYgKGMgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICBpdCgnbmV3IFRva2VuTGlzdCgnICsgdHlwZW9mIGEgKyAnKSB0aHJvdyBUeXBlRXJyb3IgJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QoKCkgPT4gbmV3IFRva2VuTGlzdChhKSkudG8udGhyb3coVHlwZUVycm9yKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaXQoJ25ldyBUb2tlbkxpc3QoJyArIHR5cGVvZiBhICsgJykgc2hvdWxkIHJldHVybiAnICsgYiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QobmV3IFRva2VuTGlzdChhKS50b1N0cmluZygpKS5pcy5lcXVhbChiKVxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgfSk7XG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdpdGVyYXRvciBwcm90b2NvbCcsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBsZXQgbGlzdDtcbiAgICAgICAgaXQoJy5hZGQoJyArIFwic2Vjb25kXCIgKyAnKSBzaG91bGQgcmV0dXJuIFRva2VuTGlzdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxpc3QgPSBuZXcgVG9rZW5MaXN0KFwic3RhcnRcIik7XG4gICAgICAgICAgICBleHBlY3QobGlzdC5nZXRJdGVyYXRvcigpKS50by5iZS5hbignb2JqZWN0Jyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCcuYWRkKCcgKyBcInNlY29uZFwiICsgJykgc2hvdWxkIHJldHVybiBUb2tlbkxpc3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsaXN0ID0gbmV3IFRva2VuTGlzdChcInN0YXJ0IGVuZFwiKTtcbiAgICAgICAgICAgIGV4cGVjdChbLi4ubGlzdF0pLnRvLmJlLmFuKCdhcnJheScpO1xuICAgICAgICAgICAgZXhwZWN0KFsuLi5saXN0XSkudG8uYmUuYW4oJ2FycmF5JykudG8uaW5jbHVkZSgnc3RhcnQnKS50by5pbmNsdWRlKCdlbmQnKTtcbiAgICAgICAgfSk7XG5cblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJy5lbnRyaWVzKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgbGV0IGxpc3Q7XG4gICAgICAgIGl0KCcuZW50cmllcygpIHNob3VsZCByZXR1cm4gQXJyYXknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsaXN0ID0gbmV3IFRva2VuTGlzdChcInN0YXJ0XCIpO1xuICAgICAgICAgICAgZXhwZWN0KGxpc3QuZW50cmllcygpKS50by5iZS5hbignYXJyYXknKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJy5lbnRyaWVzKCkgc2hvdWxkIHJldHVybiBBcnJheScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxpc3QgPSBuZXcgVG9rZW5MaXN0KFwic3RhcnQgZW5kXCIpLmVudHJpZXMoKTtcbiAgICAgICAgICAgIGV4cGVjdChsaXN0KS50by5iZS5hbignYXJyYXknKS50by5pbmNsdWRlKCdzdGFydCcpLnRvLmluY2x1ZGUoJ2VuZCcpO1xuICAgICAgICB9KTtcblxuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnLmZvckVhY2goKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBsZXQgbGlzdDtcbiAgICAgICAgaXQoJy5mb3JFYWNoKCkgc2hvdWxkIGl0ZXJhdGUgb3ZlciB0b2tlbmxpc3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsaXN0ID0gbmV3IFRva2VuTGlzdChcImFhYSBiYmIgY2NjIGRkZCBlZWUgZmZmXCIpO1xuXG4gICAgICAgICAgICBsZXQgcmVzdWx0ID0gXCJcIlxuICAgICAgICAgICAgbGlzdC5mb3JFYWNoKChhKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ICs9IFwiIVwiICsgYSArIFwiIVwiO1xuICAgICAgICAgICAgICAgIGV4cGVjdChhKS50by5iZS5hbignc3RyaW5nJyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHQpLmlzLmVxdWFsKFwiIWFhYSEhYmJiISFjY2MhIWRkZCEhZWVlISFmZmYhXCIpXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCcuZW50cmllcygpIHNob3VsZCByZXR1cm4gQXJyYXknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsaXN0ID0gbmV3IFRva2VuTGlzdChcInN0YXJ0IGVuZFwiKS5lbnRyaWVzKCk7XG4gICAgICAgICAgICBleHBlY3QobGlzdCkudG8uYmUuYW4oJ2FycmF5JykudG8uaW5jbHVkZSgnc3RhcnQnKS50by5pbmNsdWRlKCdlbmQnKTtcbiAgICAgICAgfSk7XG5cblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2NvbnRhaW5zIHZhbHVlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbGV0IGxpc3RcbiAgICAgICAgaXQoJ25ldyBUb2tlbkxpc3Qoc3RhcnQsIG1pZGRsZSBlbmQpIHNob3VsZCBjb250YWluIG1pZGRsZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxpc3QgPSBuZXcgVG9rZW5MaXN0KFwic3RhcnQgbWlkZGxlIGVuZFwiKTtcbiAgICAgICAgICAgIGV4cGVjdChsaXN0LmNvbnRhaW5zKCdzdGFydCcpKS50by5iZS50cnVlO1xuICAgICAgICAgICAgZXhwZWN0KGxpc3QuY29udGFpbnMoJ21pZGRsZScpKS50by5iZS50cnVlO1xuICAgICAgICAgICAgZXhwZWN0KGxpc3QuY29udGFpbnMoJ2VuZCcpKS50by5iZS50cnVlO1xuICAgICAgICAgICAgZXhwZWN0KGxpc3QuY29udGFpbnMoWydlbmQnLCAnc3RhcnQnLCAnbWlkZGxlJ10pKS50by5iZS50cnVlO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnbmV3IFRva2VuTGlzdChzdGFydCwgbWlkZGxlIGVuZCkgc2hvdWxkIG5vdCBjb250YWluIHh5eicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxpc3QgPSBuZXcgVG9rZW5MaXN0KFwic3RhcnQgbWlkZGxlIGVuZFwiKTtcbiAgICAgICAgICAgIGV4cGVjdChsaXN0LmNvbnRhaW5zKCd4eXonKSkudG8uYmUuZmFsc2U7XG4gICAgICAgICAgICBleHBlY3QobGlzdC5jb250YWlucyhbJ2VuZCcsICdzdGFydCcsICdtaWRkbGUnLCAneHl6J10pKS50by5iZS5mYWxzZTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ25ldyBUb2tlbkxpc3Qoc3RhcnQsIG1pZGRsZSBlbmQpIHNob3VsZCBub3QgY29udGFpbiB1bmRlZmluZWQgbnVsbCBOYU4nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsaXN0ID0gbmV3IFRva2VuTGlzdChcInN0YXJ0IG1pZGRsZSBlbmRcIik7XG4gICAgICAgICAgICBleHBlY3QobGlzdC5jb250YWlucyh1bmRlZmluZWQpKS50by5iZS5mYWxzZTtcbiAgICAgICAgICAgIGV4cGVjdChsaXN0LmNvbnRhaW5zKHBhcnNlSW50KFwiYVwiKSkpLnRvLmJlLmZhbHNlOyAvLyBOYU5cbiAgICAgICAgICAgIGV4cGVjdChsaXN0LmNvbnRhaW5zKG51bGwpKS50by5iZS5mYWxzZTsgLy8gTmFOXG4gICAgICAgIH0pO1xuICAgIH0pXG5cbiAgICBkZXNjcmliZSgndG9nZ2xlIHZhbHVlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbGV0IGxpc3RcbiAgICAgICAgaXQoJ25ldyBUb2tlbkxpc3Qoc3RhcnQgbWlkZGxlIGVuZCkudG9nZ2xlKG5ldy12YWx1ZSkgc2hvdWxkIGNvbnRhaW4gbmV3LXZhbHVlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGlzdCA9IG5ldyBUb2tlbkxpc3QoXCJzdGFydCBtaWRkbGUgZW5kXCIpO1xuICAgICAgICAgICAgZXhwZWN0KGxpc3QudG9nZ2xlKCduZXctdmFsdWUnKS50b1N0cmluZygpKS5pcy5lcXVhbChcInN0YXJ0IG1pZGRsZSBlbmQgbmV3LXZhbHVlXCIpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnbmV3IFRva2VuTGlzdChzdGFydCBtaWRkbGUgZW5kKS50b2dnbGUobWlkZGxlKSBzaG91bGQgbm90IGNvbnRhaW4gbWlkZGxlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGlzdCA9IG5ldyBUb2tlbkxpc3QoXCJzdGFydCBtaWRkbGUgZW5kXCIpO1xuICAgICAgICAgICAgZXhwZWN0KGxpc3QudG9nZ2xlKCdtaWRkbGUnKS50b1N0cmluZygpKS5pcy5lcXVhbChcInN0YXJ0IGVuZFwiKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ25ldyBUb2tlbkxpc3QoKS50b2dnbGUoKSBzaG91bGQgLi4uJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KG5ldyBUb2tlbkxpc3QoXCJhYmMgZGVmIGdoaVwiKS50b2dnbGUoXCJkZWYgeHl6XCIpLnRvU3RyaW5nKCkpLnRvLmVxdWFsKFwiYWJjIGdoaSB4eXpcIik7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCduZXcgVG9rZW5MaXN0KCkudG9nZ2xlKCkgc2hvdWxkIC4uLicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgVG9rZW5MaXN0KFwiYWJjIGRlZiBnaGlcIikudG9nZ2xlKFtcImFiY1wiLCBcInh5elwiXSkudG9TdHJpbmcoKSkudG8uZXF1YWwoXCJkZWYgZ2hpIHh5elwiKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ25ldyBUb2tlbkxpc3QoKS50b2dnbGUoKSBzaG91bGQgLi4uJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KG5ldyBUb2tlbkxpc3QoXCJhYmMgZGVmIGdoaVwiKS50b2dnbGUodW5kZWZpbmVkKS50b1N0cmluZygpKS50by5lcXVhbChcImFiYyBkZWYgZ2hpXCIpO1xuICAgICAgICB9KTtcblxuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnbWFuaXB1bGF0ZSB2YWx1ZXMnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgbGV0IGxpc3RcblxuICAgICAgICBpdCgncmVzdWx0IFRva2VuTGlzdChcIicgKyBcInN0YXJ0XCIgKyAnXCIpIHNob3VsZCBiZSBcIicgKyBcInN0YXJ0XCIgKyAnXCInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsaXN0ID0gbmV3IFRva2VuTGlzdChcInN0YXJ0XCIpO1xuICAgICAgICAgICAgZXhwZWN0KGxpc3QudG9TdHJpbmcoKSkuaXMuZXF1YWwoXCJzdGFydFwiKVxuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnLmFkZCgnICsgXCJzZWNvbmRcIiArICcpIHNob3VsZCByZXR1cm4gVG9rZW5MaXN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGlzdCA9IG5ldyBUb2tlbkxpc3QoXCJzdGFydFwiKTtcbiAgICAgICAgICAgIGV4cGVjdChsaXN0LmFkZChcInNlY29uZFwiKSkudG8uYmUuYW4uaW5zdGFuY2VvZihUb2tlbkxpc3QpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnLmFkZCgnICsgXCJzZWNvbmRcIiArICcpLnRvU3RyaW5nKCkgc2hvdWxkIHJldHVybiBcInN0YXJ0IHNlY29uZFwiICcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxpc3QgPSBuZXcgVG9rZW5MaXN0KFwic3RhcnRcIik7XG4gICAgICAgICAgICBleHBlY3QobGlzdC5hZGQoXCJzZWNvbmRcIikudG9TdHJpbmcoKSkuaXMuZXF1YWwoXCJzdGFydCBzZWNvbmRcIik7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCcuYWRkKCcgKyBcInNlY29uZCB0aGlyZFwiICsgJykudG9TdHJpbmcoKSBzaG91bGQgcmV0dXJuIFwic3RhcnQgc2Vjb25kIHRoaXJkXCIgJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGlzdCA9IG5ldyBUb2tlbkxpc3QoXCJzdGFydFwiKTtcbiAgICAgICAgICAgIGV4cGVjdChsaXN0LmFkZChcInNlY29uZCB0aGlyZFwiKS50b1N0cmluZygpKS5pcy5lcXVhbChcInN0YXJ0IHNlY29uZCB0aGlyZFwiKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJy5hZGQoJyArIFwiW3NlY29uZCx0aGlyZF1cIiArICcpLnRvU3RyaW5nKCkgc2hvdWxkIHJldHVybiBcInN0YXJ0IHNlY29uZCB0aGlyZFwiICcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxpc3QgPSBuZXcgVG9rZW5MaXN0KFwic3RhcnRcIik7XG4gICAgICAgICAgICBleHBlY3QobGlzdC5hZGQoW1wic2Vjb25kXCIsIFwidGhpcmRcIl0pLnRvU3RyaW5nKCkpLmlzLmVxdWFsKFwic3RhcnQgc2Vjb25kIHRoaXJkXCIpO1xuICAgICAgICB9KTtcblxuXG4gICAgICAgIGl0KCcuY2xlYXIoKS50b1N0cmluZygpIHNob3VsZCBcIlwiICcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxpc3QgPSBuZXcgVG9rZW5MaXN0KFwic3RhcnRcIik7XG4gICAgICAgICAgICBleHBlY3QobGlzdC5hZGQoW1wic2Vjb25kXCIsIFwidGhpcmRcIl0pLmNsZWFyKCkudG9TdHJpbmcoKSkuaXMuZXF1YWwoXCJcIik7XG4gICAgICAgIH0pO1xuXG5cbiAgICAgICAgaXQoJ25ldyBUb2tlbkxpc3QoXCJzdGFydCBzZWNvbmQgdGhpcmQgZW5kXCIpLnJlbW92ZSgnICsgXCJzZWNvbmRcIiArICcpIHNob3VsZCByZXR1cm4gVG9rZW5MaXN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGlzdCA9IG5ldyBUb2tlbkxpc3QoXCJzdGFydCBzZWNvbmQgdGhpcmQgZW5kXCIpO1xuICAgICAgICAgICAgZXhwZWN0KGxpc3QucmVtb3ZlKFwic2Vjb25kXCIpKS50by5iZS5hbi5pbnN0YW5jZW9mKFRva2VuTGlzdCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCduZXcgVG9rZW5MaXN0KFwic3RhcnQgc2Vjb25kIHRoaXJkIGVuZFwiKS5yZW1vdmUoJyArIFwic2Vjb25kXCIgKyAnKS50b1N0cmluZygpIHNob3VsZCByZXR1cm4gXCJzdGFydCB0aGlyZCBlbmRcIiAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsaXN0ID0gbmV3IFRva2VuTGlzdChcInN0YXJ0IHNlY29uZCB0aGlyZCBlbmRcIik7XG4gICAgICAgICAgICBleHBlY3QobGlzdC5yZW1vdmUoXCJzZWNvbmRcIikudG9TdHJpbmcoKSkuaXMuZXF1YWwoXCJzdGFydCB0aGlyZCBlbmRcIik7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCduZXcgVG9rZW5MaXN0KFwic3RhcnQgc2Vjb25kIHRoaXJkIGVuZFwiKS5yZW1vdmUoJyArIFwic2Vjb25kIHRoaXJkXCIgKyAnKS50b1N0cmluZygpIHNob3VsZCByZXR1cm4gXCJzdGFydCBlbmRcIiAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsaXN0ID0gbmV3IFRva2VuTGlzdChcInN0YXJ0IHNlY29uZCB0aGlyZCBlbmRcIik7XG4gICAgICAgICAgICBleHBlY3QobGlzdC5yZW1vdmUoXCJzZWNvbmQgdGhpcmRcIikudG9TdHJpbmcoKSkuaXMuZXF1YWwoXCJzdGFydCBlbmRcIik7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCduZXcgVG9rZW5MaXN0KFwic3RhcnQgc2Vjb25kIHRoaXJkIGVuZFwiKS5yZW1vdmUoJyArIFwiW3NlY29uZCx0aGlyZF1cIiArICcpLnRvU3RyaW5nKCkgc2hvdWxkIHJldHVybiBcInN0YXJ0IGVuZFwiICcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxpc3QgPSBuZXcgVG9rZW5MaXN0KFwic3RhcnQgc2Vjb25kIHRoaXJkIGVuZFwiKTtcbiAgICAgICAgICAgIGV4cGVjdChsaXN0LnJlbW92ZShbXCJzZWNvbmRcIiwgXCJ0aGlyZFwiXSkudG9TdHJpbmcoKSkuaXMuZXF1YWwoXCJzdGFydCBlbmRcIik7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCduZXcgVG9rZW5MaXN0KFwic3RhcnQgc2Vjb25kIHRoaXJkIGVuZFwiKS5yZXBsYWNlKHNlY29uZCwgeHl6KS50b1N0cmluZygpIHNob3VsZCByZXR1cm4gXCJzdGFydCB4eXogdGhpcmQgZW5kXCIgJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGlzdCA9IG5ldyBUb2tlbkxpc3QoXCJzdGFydCBzZWNvbmQgdGhpcmQgZW5kXCIpO1xuICAgICAgICAgICAgZXhwZWN0KGxpc3QucmVwbGFjZShcInNlY29uZFwiLCBcInh5elwiKSkudG8uYmUuaW5zdGFuY2VPZihUb2tlbkxpc3QpO1xuICAgICAgICAgICAgZXhwZWN0KGxpc3QudG9TdHJpbmcoKSkuaXMuZXF1YWwoXCJzdGFydCB4eXogdGhpcmQgZW5kXCIpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnbmV3IFRva2VuTGlzdChcInN0YXJ0IHNlY29uZCB0aGlyZCBlbmRcIikucmVwbGFjZShlbmQsIHh5eikudG9TdHJpbmcoKSBzaG91bGQgcmV0dXJuIFwic3RhcnQgc2Vjb25kIHRoaXJkIHh5elwiICcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxpc3QgPSBuZXcgVG9rZW5MaXN0KFwic3RhcnQgc2Vjb25kIHRoaXJkIGVuZFwiKTtcbiAgICAgICAgICAgIGV4cGVjdChsaXN0LnJlcGxhY2UoXCJlbmRcIiwgXCJ4eXpcIikpLnRvLmJlLmluc3RhbmNlT2YoVG9rZW5MaXN0KTtcbiAgICAgICAgICAgIGV4cGVjdChsaXN0LnRvU3RyaW5nKCkpLmlzLmVxdWFsKFwic3RhcnQgc2Vjb25kIHRoaXJkIHh5elwiKTtcbiAgICAgICAgfSk7XG5cblxuICAgIH0pO1xuXG5cbn0pO1xuXG4iLCAiaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7UXVldWV9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdHlwZXMvcXVldWUubWpzXCI7XG5cbmRlc2NyaWJlKCdRdWV1ZScsIGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgcXVldWU7XG4gICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICAgIHF1ZXVlID0gbmV3IFF1ZXVlO1xuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnaXNFbXB0eSgpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdmaXJzdCBpdCBzaG91bGQgZW1wdHknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QocXVldWUuaXNFbXB0eSgpKS50by5iZS50cnVlO1xuICAgICAgICB9KTtcblxuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnYWRkIHNlcXVlbmNlIHBlZWsgYW5kIHBvbGwnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ3Jlc3VsdCBhLGEsYSxiJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KHF1ZXVlLmFkZCgnYScpKS50by5iZS5pbnN0YW5jZU9mKFF1ZXVlKTtcbiAgICAgICAgICAgIGV4cGVjdChxdWV1ZS5pc0VtcHR5KCkpLnRvLmJlLmZhbHNlO1xuICAgICAgICAgICAgZXhwZWN0KHF1ZXVlLmFkZCgnYicpKS50by5iZS5pbnN0YW5jZU9mKFF1ZXVlKTtcbiAgICAgICAgICAgIGV4cGVjdChxdWV1ZS5hZGQoJ2MnKSkudG8uYmUuaW5zdGFuY2VPZihRdWV1ZSk7XG4gICAgICAgICAgICBleHBlY3QocXVldWUucGVlaygpKS50by5iZS5lcXVhbCgnYScpO1xuICAgICAgICAgICAgZXhwZWN0KHF1ZXVlLnBlZWsoKSkudG8uYmUuZXF1YWwoJ2EnKTtcbiAgICAgICAgICAgIGV4cGVjdChxdWV1ZS5wb2xsKCkpLnRvLmJlLmVxdWFsKCdhJyk7XG4gICAgICAgICAgICBleHBlY3QocXVldWUucGVlaygpKS50by5iZS5lcXVhbCgnYicpO1xuICAgICAgICAgICAgZXhwZWN0KHF1ZXVlLmlzRW1wdHkoKSkudG8uYmUuZmFsc2U7XG4gICAgICAgIH0pO1xuXG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCdhZGQgYW5kIGNsZWFyJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdzaG91bGQgZW1wdHknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QocXVldWUuaXNFbXB0eSgpKS50by5iZS50cnVlO1xuICAgICAgICAgICAgZXhwZWN0KHF1ZXVlLmFkZCgnYScpKS50by5iZS5pbnN0YW5jZU9mKFF1ZXVlKTtcbiAgICAgICAgICAgIGV4cGVjdChxdWV1ZS5pc0VtcHR5KCkpLnRvLmJlLmZhbHNlO1xuICAgICAgICAgICAgZXhwZWN0KHF1ZXVlLmNsZWFyKCkpLnRvLmJlLmluc3RhbmNlT2YoUXVldWUpO1xuICAgICAgICAgICAgZXhwZWN0KHF1ZXVlLmlzRW1wdHkoKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgfSk7XG5cbiAgICB9KVxuXG5cbiAgICBcbn0pIiwgImltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge1N0YWNrfSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL3N0YWNrLm1qc1wiO1xuXG5cbmRlc2NyaWJlKCdTdGFjaycsIGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgc3RhY2s7XG4gICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICAgIHN0YWNrID0gbmV3IFN0YWNrO1xuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnaXNFbXB0eSgpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdmaXJzdCBpdCBzaG91bGQgZW1wdHknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3Qoc3RhY2suaXNFbXB0eSgpKS50by5iZS50cnVlO1xuICAgICAgICB9KTtcblxuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnYWRkIHNlcXVlbmNlIHBlZWsgYW5kIHB1bGwnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ3Jlc3VsdCBhLGEsYSxiJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KHN0YWNrLnB1c2goJ2EnKSkudG8uYmUuaW5zdGFuY2VPZihTdGFjayk7XG4gICAgICAgICAgICBleHBlY3Qoc3RhY2suaXNFbXB0eSgpKS50by5iZS5mYWxzZTtcbiAgICAgICAgICAgIGV4cGVjdChzdGFjay5wdXNoKCdiJykpLnRvLmJlLmluc3RhbmNlT2YoU3RhY2spO1xuICAgICAgICAgICAgZXhwZWN0KHN0YWNrLnB1c2goJ2MnKSkudG8uYmUuaW5zdGFuY2VPZihTdGFjayk7XG4gICAgICAgICAgICBleHBlY3Qoc3RhY2sucGVlaygpKS50by5iZS5lcXVhbCgnYycpO1xuICAgICAgICAgICAgZXhwZWN0KHN0YWNrLnBlZWsoKSkudG8uYmUuZXF1YWwoJ2MnKTtcbiAgICAgICAgICAgIGV4cGVjdChzdGFjay5wb3AoKSkudG8uYmUuZXF1YWwoJ2MnKTtcbiAgICAgICAgICAgIGV4cGVjdChzdGFjay5wZWVrKCkpLnRvLmJlLmVxdWFsKCdiJyk7XG4gICAgICAgICAgICBleHBlY3Qoc3RhY2suaXNFbXB0eSgpKS50by5iZS5mYWxzZTtcbiAgICAgICAgfSk7XG5cbiAgICB9KVxuXG4gICAgZGVzY3JpYmUoJ2FkZCBhbmQgY2xlYXInLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBlbXB0eScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChzdGFjay5pc0VtcHR5KCkpLnRvLmJlLnRydWU7XG4gICAgICAgICAgICBleHBlY3Qoc3RhY2sucHVzaCgnYScpKS50by5iZS5pbnN0YW5jZU9mKFN0YWNrKTtcbiAgICAgICAgICAgIGV4cGVjdChzdGFjay5pc0VtcHR5KCkpLnRvLmJlLmZhbHNlO1xuICAgICAgICAgICAgZXhwZWN0KHN0YWNrLmNsZWFyKCkpLnRvLmJlLmluc3RhbmNlT2YoU3RhY2spO1xuICAgICAgICAgICAgZXhwZWN0KHN0YWNrLmlzRW1wdHkoKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgfSk7XG5cbiAgICB9KVxufSkiLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyB2YWxpZGF0ZVN0cmluZyB9IGZyb20gXCIuL3ZhbGlkYXRlLm1qc1wiO1xuXG5leHBvcnQgeyB0b0JpbmFyeSwgZnJvbUJpbmFyeSB9O1xuXG4vKipcbiAqIFlvdSBjYW4gY2FsbCB0aGUgZnVuY3Rpb24gdmlhIHRoZSBtb25zdGVyIG5hbWVzcGFjZSBgTW9uc3Rlci5UeXBlcy50b0JpbmFyeSgpYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gYmluYXJ5XG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIHN0cmluZ1xuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMTguMFxuICovXG5mdW5jdGlvbiB0b0JpbmFyeShzdHJpbmcpIHtcbiAgICBjb25zdCBjb2RlVW5pdHMgPSBuZXcgVWludDE2QXJyYXkodmFsaWRhdGVTdHJpbmcoc3RyaW5nKS5sZW5ndGgpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY29kZVVuaXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvZGVVbml0c1tpXSA9IHN0cmluZy5jaGFyQ29kZUF0KGkpO1xuICAgIH1cblxuICAgIGNvbnN0IGNoYXJDb2RlcyA9IG5ldyBVaW50OEFycmF5KGNvZGVVbml0cy5idWZmZXIpO1xuICAgIGxldCByZXN1bHQgPSBcIlwiO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGFyQ29kZXMuYnl0ZUxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGNoYXJDb2Rlc1tpXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBZb3UgY2FuIGNhbGwgdGhlIGZ1bmN0aW9uIHZpYSB0aGUgbW9uc3RlciBuYW1lc3BhY2UgYE1vbnN0ZXIuVHlwZXMuZnJvbUJpbmFyeSgpYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gYmluYXJ5XG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIHN0cmluZ1xuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMTguMFxuICovXG5mdW5jdGlvbiBmcm9tQmluYXJ5KGJpbmFyeSkge1xuICAgIGNvbnN0IGJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkodmFsaWRhdGVTdHJpbmcoYmluYXJ5KS5sZW5ndGgpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgYnl0ZXNbaV0gPSBiaW5hcnkuY2hhckNvZGVBdChpKTtcbiAgICB9XG4gICAgY29uc3QgY2hhckNvZGVzID0gbmV3IFVpbnQxNkFycmF5KGJ5dGVzLmJ1ZmZlcik7XG4gICAgbGV0IHJlc3VsdCA9IFwiXCI7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGFyQ29kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoY2hhckNvZGVzW2ldKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbiIsICIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge2Zyb21CaW5hcnksIHRvQmluYXJ5fSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL2JpbmFyeS5tanNcIjtcblxuZGVzY3JpYmUoJ0JpbmFyeScsIGZ1bmN0aW9uICgpIHtcblxuICAgIFtcbiAgICAgICAgWydhJywgJ2FcXHUwMDAwJ10sXG4gICAgICAgIFsnXHUyNjM5JywgJzkmJ10sXG4gICAgICAgIFsnSVx1MDBGMXRcdTAwRUJyblx1MDBFMnRpXHUwMEY0blx1MDBFMGxpelx1MDBFNnRpXHUwMEY4bicsICdJXFx1MDAwMFx1MDBGMVxcdTAwMDB0XFx1MDAwMFx1MDBFQlxcdTAwMDByXFx1MDAwMG5cXHUwMDAwXHUwMEUyXFx1MDAwMHRcXHUwMDAwaVxcdTAwMDBcdTAwRjRcXHUwMDAwblxcdTAwMDBcdTAwRTBcXHUwMDAwbFxcdTAwMDBpXFx1MDAwMHpcXHUwMDAwXHUwMEU2XFx1MDAwMHRcXHUwMDAwaVxcdTAwMDBcdTAwRjhcXHUwMDAwblxcdTAwMDAnXVxuXG4gICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICBpdCgnZnJvbUJpbmFyeSh0b0JpbmFyeSgnICsgYSArICcpKSBzaG91bGQgd29yaycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCByID0gdG9CaW5hcnkoYSk7XG4gICAgICAgICAgICBleHBlY3QocikudG8uYmUuZXF1YWwoYik7XG4gICAgICAgICAgICBleHBlY3QoZnJvbUJpbmFyeShyKSkudG8uYmUuZXF1YWwoYSk7XG4gICAgICAgIH0pXG5cbiAgICB9KTtcblxuXG59KTsiLCAiXCJ1c2Ugc3RyaWN0XCI7XG5cbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge0Jhc2VXaXRoT3B0aW9uc30gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS90eXBlcy9iYXNld2l0aG9wdGlvbnMubWpzXCI7XG5cblxuZGVzY3JpYmUoJ0Jhc2VXaXRoT3B0aW9ucycsIGZ1bmN0aW9uICgpIHtcblxuICAgIGRlc2NyaWJlKCduZXcgQmFzZVdpdGhPcHRpb25zJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdpcyBpbnN0YW5jZSBvZiBCYXNlV2l0aE9wdGlvbnMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IEJhc2VXaXRoT3B0aW9ucykudG8uYmUuaW5zdGFuY2VPZihCYXNlV2l0aE9wdGlvbnMpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnaXMgaW5zdGFuY2Ugb2YgT2JqZWN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KG5ldyBCYXNlV2l0aE9wdGlvbnMpLnRvLmJlLmluc3RhbmNlT2YoT2JqZWN0KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ2dldCBvcHRpb24gaXMgdHJ1ZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgQmFzZVdpdGhPcHRpb25zKHthOiB0cnVlfSkuZ2V0T3B0aW9uKCdhJykpLnRvLmJlLnRydWU7XG4gICAgICAgIH0pO1xuXG4gICAgfSlcblxufSkiLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyB2YWxpZGF0ZVN0cmluZyB9IGZyb20gXCIuL3ZhbGlkYXRlLm1qc1wiO1xuXG5leHBvcnQgeyBlc2NhcGVTdHJpbmcgfTtcblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIHByZWZpeGVzIGFsbCBzcGVjaWFsIGNoYXJhY3RlcnMgdGhhdCBtYXkgYXBwZWFyIGluIGEgcmVnZXggd2l0aCBhIHNsYXNoLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZVxuICogQHJldHVybiB7c3RyaW5nfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNi4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgc3RyaW5nXG4gKi9cbmZ1bmN0aW9uIGVzY2FwZVN0cmluZyh2YWx1ZSkge1xuICAgIHJldHVybiB2YWxpZGF0ZVN0cmluZyh2YWx1ZSkucmVwbGFjZSgvW3xcXFxce30oKVtcXF1eJCsqPy5dL2csIFwiXFxcXCQmXCIpLnJlcGxhY2UoLy0vZywgXCJcXFxceDJkXCIpO1xufVxuIiwgIlxuaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7ZXNjYXBlU3RyaW5nfSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL3JlZ2V4Lm1qc1wiXG5pbXBvcnQge2luaXRKU0RPTX0gZnJvbSBcIi4uLy4uL3V0aWwvanNkb20ubWpzXCI7XG5cblxuZGVzY3JpYmUoJ2VzY2FwZVN0cmluZycsIGZ1bmN0aW9uICgpIHtcblxuICAgIGJlZm9yZShmdW5jdGlvbiAoZG9uZSkge1xuXG4gICAgICAgIGxldCBwcm9taXNlcyA9IFtdXG4gICAgICAgIHByb21pc2VzLnB1c2goaW5pdEpTRE9NKCkpO1xuICAgICAgICBpZighZ2xvYmFsVGhpc1snY3J5cHRvJ10pIHtcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2goaW1wb3J0KFwiQHBlY3VsaWFyL3dlYmNyeXB0b1wiKS50aGVuKG0gPT4ge1xuICAgICAgICAgICAgICAgIGdsb2JhbFRoaXNbJ2NyeXB0byddID0gbmV3IG0uQ3J5cHRvKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9KSlcbiAgICAgICAgfVxuXG5cbiAgICAgICAgUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgZG9uZSgpXG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG4gICAgXG4gICAgW1xuICAgICAgICBbJ3Rlc3QxJywgJ3Rlc3QxJ10sXG4gICAgICAgIFsnJHsnLCAnXFxcXCRcXFxceyddLFxuICAgICAgICBbJ2kxOG57JywgJ2kxOG5cXFxceyddLFxuICAgICAgICBbJy8vJywgJy8vJ10sXG4gICAgICAgIFsnXFxcXCcsICdcXFxcXFxcXCddLFxuICAgICAgIFxuICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgaXQoJ2VzY2FwZVN0cmluZygnICsgYSArICcpIHNob3VsZCByZXR1cm4gJyArIGIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChlc2NhcGVTdHJpbmcoYSkpLmlzLmVxdWFsKGIpXG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG5cbn0pO1xuXG4iLCAiaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7ZXh0ZW5kfSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2RhdGEvZXh0ZW5kLm1qc1wiO1xuaW1wb3J0IHtpc09iamVjdH0gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS90eXBlcy9pcy5tanNcIjtcbmltcG9ydCB7T2JzZXJ2ZXJ9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdHlwZXMvb2JzZXJ2ZXIubWpzXCI7XG5cbmltcG9ydCB7UHJveHlPYnNlcnZlcn0gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS90eXBlcy9wcm94eW9ic2VydmVyLm1qc1wiO1xuXG5kZXNjcmliZSgnUHJveHlPYnNlcnZlcicsIGZ1bmN0aW9uICgpIHtcblxuICAgIGRlc2NyaWJlKCdjcmVhdGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGluc3RhbmNlb2YgUHJveHlPYnNlcnZlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBvID0gbmV3IFByb3h5T2JzZXJ2ZXIoe30pO1xuICAgICAgICAgICAgZXh0ZW5kKG8uZ2V0U3ViamVjdCgpLCB7YTogNH0pO1xuICAgICAgICAgICAgZXhwZWN0KG8uZ2V0UmVhbFN1YmplY3QoKSkuaXMuZXFsKHthOiA0fSk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3NldFN1YmplY3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgcnVuIG9ic2VydmVyJywgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgICAgIGxldCBvID0gbmV3IFByb3h5T2JzZXJ2ZXIoe2E6IDF9KTtcbiAgICAgICAgICAgIGV4cGVjdChvLmdldFJlYWxTdWJqZWN0KCkpLmlzLmVxbCh7YTogMX0pO1xuICAgICAgICAgICAgbGV0IGNvdW50ZXIgPSAwO1xuICAgICAgICAgICAgby5hdHRhY2hPYnNlcnZlcihuZXcgT2JzZXJ2ZXIoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGlmIChpc09iamVjdCh0aGlzKSAmJiB0aGlzIGluc3RhbmNlb2YgUHJveHlPYnNlcnZlcikge1xuICAgICAgICAgICAgICAgICAgICBjb3VudGVyKys7XG4gICAgICAgICAgICAgICAgICAgIC8vIG9ubHkgb25lIGNoYW5nZSBhcyBub3RpZnkgcnVucyBsYXRlclxuICAgICAgICAgICAgICAgICAgICBpZiAoY291bnRlciA9PT0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGRvbmUoXCJjYWxsZWQgZm9yIGVycm9yXCIpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZG9uZShuZXcgRXJyb3IoXCJ0aGlzIGlzIG5vdCBQcm94eU9ic2VydmVyXCIpKVxuICAgICAgICAgICAgfSkpXG5cbiAgICAgICAgICAgIG8uZ2V0U3ViamVjdCgpLmMgPSA0O1xuICAgICAgICAgICAgZXhwZWN0KG8uZ2V0UmVhbFN1YmplY3QoKSkuaXMuZXFsKHthOiAxLCBjOiA0fSk7XG5cbiAgICAgICAgICAgIG8uc2V0U3ViamVjdCh7YjogMn0pO1xuICAgICAgICAgICAgZXhwZWN0KG8uZ2V0UmVhbFN1YmplY3QoKSkuaXMuZXFsKHtiOiAyfSk7XG5cbiAgICAgICAgICAgIG8uZ2V0U3ViamVjdCgpLmQgPSA1O1xuICAgICAgICAgICAgZXhwZWN0KG8uZ2V0UmVhbFN1YmplY3QoKSkuaXMuZXFsKHtiOiAyLCBkOiA1fSk7XG5cblxuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdjcmVhdGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGluc3RhbmNlb2YgUHJveHlPYnNlcnZlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBvID0gbmV3IFByb3h5T2JzZXJ2ZXIoe30pO1xuICAgICAgICAgICAgZXhwZWN0KG8pLmlzLmluc3RhbmNlT2YoUHJveHlPYnNlcnZlcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3Byb3h5IG9iamVjdHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdQcm94eSBvYmplY3RzIHNob3VsZCBub3QgYmUgcmVjb21taXR0ZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgbyA9IG5ldyBQcm94eU9ic2VydmVyKHthOiB7YjogdHJ1ZX19KTtcbiAgICAgICAgICAgIG8uZ2V0U3ViamVjdCgpLmEuYiA9IG8uZ2V0U3ViamVjdCgpO1xuICAgICAgICAgICAgby5nZXRTdWJqZWN0KCkuYS5iLmEuYiA9IGZhbHNlO1xuICAgICAgICAgICAgLy9leHBlY3Qoby5nZXRTdWJqZWN0KCk9PT1wLmdldFN1YmplY3QoKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnbm90aWZ5IG9ic2VydmVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIGluZm9ybSBvYnNlcnZlcicsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICBsZXQgY291bnRlciA9IDA7XG4gICAgICAgICAgICAvLyB0aGUgbWV0aG9kIGlzIGNhbGxlZCB0d2ljZSwgb25jZSBmb3IgZGVmaW5lUHJvcGVydHkgYW5kIGZvciBzZXQgdHJhcFxuICAgICAgICAgICAgbGV0IG8gPSBuZXcgT2JzZXJ2ZXIoZnVuY3Rpb24gKGEpIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNPYmplY3QodGhpcykgJiYgdGhpcyBpbnN0YW5jZW9mIFByb3h5T2JzZXJ2ZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgY291bnRlcisrO1xuICAgICAgICAgICAgICAgICAgICBpZiAoY291bnRlciA9PT0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBkb25lKG5ldyBFcnJvcihcInRoaXMgaXMgbm90IFByb3h5T2JzZXJ2ZXJcIikpXG4gICAgICAgICAgICB9LCB0cnVlKVxuXG4gICAgICAgICAgICBsZXQgcmVhbFN1YmplY3QgPSB7XG4gICAgICAgICAgICAgICAgYToge1xuICAgICAgICAgICAgICAgICAgICBiOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjOiB0cnVlXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGQ6IDVcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCBwID0gbmV3IFByb3h5T2JzZXJ2ZXIocmVhbFN1YmplY3QpO1xuICAgICAgICAgICAgZXhwZWN0KHApLmlzLmluc3RhbmNlT2YoUHJveHlPYnNlcnZlcik7XG4gICAgICAgICAgICBleHBlY3QocC5hdHRhY2hPYnNlcnZlcihvKSkuaXMuaW5zdGFuY2VPZihQcm94eU9ic2VydmVyKTtcblxuICAgICAgICAgICAgbGV0IHMgPSBwLmdldFN1YmplY3QoKTtcbiAgICAgICAgICAgIGxldCByID0gcC5nZXRSZWFsU3ViamVjdCgpO1xuXG4gICAgICAgICAgICBzLmEuZCA9IGZhbHNlO1xuICAgICAgICAgICAgcy5hLmIuZCA9IDI7XG5cbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBAc2VlIGh0dHBzOi8vZ2l0bGFiLnNjaHVrYWkuY29tL29zcy9saWJyYXJpZXMvamF2YXNjcmlwdC9tb25zdGVyLy0vaXNzdWVzLzQzXG4gICAgICovXG4gICAgZGVzY3JpYmUoJ1JlZmxlY3QnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ2NoZWNrIFJlZmxlY3Quc2V0KCkgd2l0aCBTdWJqZWN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGV0IHI7XG5cbiAgICAgICAgICAgIGNvbnN0IG9iaiA9IChuZXcgUHJveHlPYnNlcnZlcih7fSkpLmdldFN1YmplY3QoKTtcblxuICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgIFwieWVzIVwiLFxuICAgICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICBcIm5vXCJcbiAgICAgICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBleHBlY3QoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBvYmpbJ2RhdGEnXSA9IHZhbHVlXG4gICAgICAgICAgICAgICAgfSkudG8ubm90LnRocm93KCk7XG4gICAgICAgICAgICAgICAgLy9yID0gUmVmbGVjdC5zZXQob2JqLCAnZGF0YScsIHZhbHVlKVxuICAgICAgICAgICAgICAgIC8vZXhwZWN0KHIpLnRvLmJlLnRydWU7XG4gICAgICAgICAgICB9KVxuXG5cbiAgICAgICAgfSk7XG5cblxuICAgICAgICBbXG4gICAgICAgICAgICBbJ3RoYXQnLCB7dGhhdDogJ2NoZWNrZWQxJ31dLFxuICAgICAgICAgICAgWyd0aGF0JywgbmV3IFByb3h5KHt0aGF0OiAnY2hlY2tlZDInfSwge30pXSxcbiAgICAgICAgICAgIFsndGhhdCcsIChuZXcgUHJveHlPYnNlcnZlcih7dGhhdDogJ2NoZWNrZWQzJ30pKS5nZXRSZWFsU3ViamVjdCgpXSxcbiAgICAgICAgICAgIFsndGhhdCcsIChuZXcgUHJveHlPYnNlcnZlcih7dGhhdDogJ2NoZWNrZWQ0J30pKS5nZXRTdWJqZWN0KCldXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQga2V5ID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgdGFyZ2V0ID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGl0KCdjaGVjayBSZWZsZWN0LnNldCgnICsga2V5ICsgJywnICsgSlNPTi5zdHJpbmdpZnkodGFyZ2V0KSArICcpIHNob3VsZCB3cml0YWJsZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBsZXQgdmFsdWU7XG5cbiAgICAgICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgICAgIFwiMVwiLFxuICAgICAgICAgICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgIHRydWUsXG4gICAgICAgICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uICh2YWx1ZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KFJlZmxlY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LCBrZXkpWyd3cml0YWJsZSddLCAnd3JpdGFibGUgZm9yICcgKyB2YWx1ZSArICcgc2hvdWxkIHJldHVybiB0cnVlJykudG8uYmUudHJ1ZTtcblxuICAgICAgICAgICAgICAgICAgICBleHBlY3QoUmVmbGVjdC5zZXQodGFyZ2V0LCBrZXksIHZhbHVlKSwgJ3NldCBmb3IgJyArIHZhbHVlICsgJyBzaG91bGQgcmV0dXJuIHRydWUnKS50by5iZS50cnVlO1xuXG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChSZWZsZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldCwga2V5KVsnd3JpdGFibGUnXSwgJ3dyaXRhYmxlIGZvciAnICsgdmFsdWUgKyAnIHNob3VsZCByZXR1cm4gdHJ1ZScpLnRvLmJlLnRydWU7XG5cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0pXG5cblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ25vdGlmeSBvYnNlcnZlciB3aXRoIGNoYW5nZXMnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgbGV0IG9yaWdpbmFsLCBvYnNlcnZlciwgcHJveHk7XG5cbiAgICAgICAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIG9yaWdpbmFsID0ge307XG4gICAgICAgICAgICBwcm94eSA9IG5ldyBQcm94eU9ic2VydmVyKG9yaWdpbmFsKTtcblxuICAgICAgICB9KTtcblxuICAgICAgICBbXG4gICAgICAgICAgICBbJ2EnLCA0LCBKU09OLnN0cmluZ2lmeSh7YTogNH0pXSxcbiAgICAgICAgICAgIFsnYicsIDksIEpTT04uc3RyaW5naWZ5KHthOiA0LCBiOiA5fSldXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBjID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGl0KCdzZXQga2V5ICcgKyBhICsgJyB2YWx1ZSAnICsgYiArICcgZXhwZWN0ICcgKyBjLCBmdW5jdGlvbiAoZG9uZSkge1xuXG4gICAgICAgICAgICAgICAgbGV0IGNvdW50ZXIgPSAwO1xuICAgICAgICAgICAgICAgIG9ic2VydmVyID0gbmV3IE9ic2VydmVyKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgY291bnRlcisrO1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QoSlNPTi5zdHJpbmdpZnkodGhpcy5nZXRSZWFsU3ViamVjdCgpKSkuaXMuZXF1YWwoYyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChjb3VudGVyID09PSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRldGFjaE9ic2VydmVyKG9ic2VydmVyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgICAgICBwcm94eS5hdHRhY2hPYnNlcnZlcihvYnNlcnZlcilcbiAgICAgICAgICAgICAgICBsZXQgc3ViamVjdCA9IHByb3h5LmdldFN1YmplY3QoKVxuXG4gICAgICAgICAgICAgICAgc3ViamVjdFthXSA9IGI7XG5cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9KVxuXG4gICAgZGVzY3JpYmUoJ25vdGlmeSBvYnNlcnZlciAnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gcHJvbWlzZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBwcm94eSA9IG5ldyBQcm94eU9ic2VydmVyKHt9KTtcbiAgICAgICAgICAgIGxldCBvYnNlcnZlciA9IG5ldyBPYnNlcnZlcihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgcHJveHkuYXR0YWNoT2JzZXJ2ZXIob2JzZXJ2ZXIpXG4gICAgICAgICAgICBleHBlY3QocHJveHkubm90aWZ5T2JzZXJ2ZXJzKCkpLmlzLmluc3RhbmNlT2YoUHJvbWlzZSk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG59KVxuXG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBCYXNlIH0gZnJvbSBcIi4vYmFzZS5tanNcIjtcbmltcG9ydCB7IGlzUHJpbWl0aXZlIH0gZnJvbSBcIi4vaXMubWpzXCI7XG5pbXBvcnQgeyBOb2RlTGlzdCB9IGZyb20gXCIuL25vZGVsaXN0Lm1qc1wiO1xuaW1wb3J0IHsgdmFsaWRhdGVJbnN0YW5jZSB9IGZyb20gXCIuL3ZhbGlkYXRlLm1qc1wiO1xuaW1wb3J0IHsgaW5zdGFuY2VTeW1ib2wgfSBmcm9tIFwiLi4vY29uc3RhbnRzLm1qc1wiO1xuXG5leHBvcnQgeyBOb2RlIH07XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEB0eXBlIHtzeW1ib2x9XG4gKi9cbmNvbnN0IGludGVybmFsVmFsdWVTeW1ib2wgPSBTeW1ib2woXCJpbnRlcm5hbERhdGFcIik7XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEB0eXBlIHtzeW1ib2x9XG4gKi9cbmNvbnN0IHRyZWVTdHJ1Y3R1cmVTeW1ib2wgPSBTeW1ib2woXCJ0cmVlU3RydWN0dXJlXCIpO1xuXG4vKipcbiAqIFlvdSBjYW4gY3JlYXRlIHRoZSBpbnN0YW5jZSB2aWEgdGhlIG1vbnN0ZXIgbmFtZXNwYWNlIGBuZXcgTW9uc3Rlci5UeXBlcy5Ob2RlKClgLlxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjYuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKiBAc3VtbWFyeSBBIE5vZGUgQ2xhc3NcbiAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZGUvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvSXRlcmF0aW9uX3Byb3RvY29sc1xuICovXG5jbGFzcyBOb2RlIGV4dGVuZHMgQmFzZSB7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIHsqfSBbdmFsdWVdXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodmFsdWUpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpc1tpbnRlcm5hbFZhbHVlU3ltYm9sXSA9IHZhbHVlO1xuXG4gICAgICAgIHRoaXNbdHJlZVN0cnVjdHVyZVN5bWJvbF0gPSB7XG4gICAgICAgICAgICBwYXJlbnQ6IG51bGwsXG4gICAgICAgICAgICBjaGlsZE5vZGVzOiBuZXcgTm9kZUxpc3QoKSxcbiAgICAgICAgICAgIGxldmVsOiAwLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgYGluc3RhbmNlb2ZgIG9wZXJhdG9yLlxuICAgICAqIEByZXR1cm5zIHtzeW1ib2x9XG4gICAgICogQHNpbmNlIDIuMS4wXG4gICAgICovXG4gICAgc3RhdGljIGdldCBbaW5zdGFuY2VTeW1ib2xdKCkge1xuICAgICAgICByZXR1cm4gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvdHlwZXMvbm9kZVwiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcHJvcGVydHkgeyp9XG4gICAgICovXG4gICAgZ2V0IHZhbHVlKCkge1xuICAgICAgICByZXR1cm4gdGhpc1tpbnRlcm5hbFZhbHVlU3ltYm9sXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcHJvcGVydHkgeyp9XG4gICAgICovXG4gICAgc2V0IHZhbHVlKHZhbHVlKSB7XG4gICAgICAgIHRoaXNbaW50ZXJuYWxWYWx1ZVN5bWJvbF0gPSB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcHJvcGVydHkge01vbnN0ZXIuVHlwZXMuTm9kZXxudWxsfVxuICAgICAqL1xuICAgIGdldCBwYXJlbnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzW3RyZWVTdHJ1Y3R1cmVTeW1ib2xdLnBhcmVudDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcHJvcGVydHkge2ludGVnZXJ9XG4gICAgICovXG4gICAgZ2V0IGxldmVsKCkge1xuICAgICAgICByZXR1cm4gdGhpc1t0cmVlU3RydWN0dXJlU3ltYm9sXS5sZXZlbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwcm9wZXJ0eSB7Tm9kZUxpc3R9XG4gICAgICovXG4gICAgZ2V0IGNoaWxkTm9kZXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzW3RyZWVTdHJ1Y3R1cmVTeW1ib2xdLmNoaWxkTm9kZXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcHJvcGVydHkge05vZGVMaXN0fVxuICAgICAqL1xuICAgIHNldCBjaGlsZE5vZGVzKGNoaWxkTm9kZXMpIHtcbiAgICAgICAgdGhpc1t0cmVlU3RydWN0dXJlU3ltYm9sXS5jaGlsZE5vZGVzID0gdmFsaWRhdGVJbnN0YW5jZShjaGlsZE5vZGVzLCBOb2RlTGlzdCk7XG4gICAgICAgIHNldENoaWxkTGV2ZWxBbmRQYXJlbnQuY2FsbCh0aGlzLCB0aGlzLCAxKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtNb25zdGVyLlR5cGVzLk5vZGV9XG4gICAgICogQHBhcmFtIHtOb2RlfSBub2RlXG4gICAgICovXG4gICAgYXBwZW5kQ2hpbGQobm9kZSkge1xuICAgICAgICB0aGlzW3RyZWVTdHJ1Y3R1cmVTeW1ib2xdLmNoaWxkTm9kZXMuYWRkKHZhbGlkYXRlSW5zdGFuY2Uobm9kZSwgTm9kZSkpO1xuICAgICAgICBub2RlW3RyZWVTdHJ1Y3R1cmVTeW1ib2xdLnBhcmVudCA9IHRoaXM7XG5cbiAgICAgICAgbm9kZVt0cmVlU3RydWN0dXJlU3ltYm9sXS5sZXZlbCA9IHRoaXMubGV2ZWwgKyAxO1xuICAgICAgICBzZXRDaGlsZExldmVsQW5kUGFyZW50LmNhbGwodGhpcywgbm9kZSwgMSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge01vbnN0ZXIuVHlwZXMuTm9kZX1cbiAgICAgKiBAcGFyYW0ge05vZGV9IG5vZGVcbiAgICAgKi9cbiAgICByZW1vdmVDaGlsZChub2RlKSB7XG4gICAgICAgIHRoaXNbdHJlZVN0cnVjdHVyZVN5bWJvbF0uY2hpbGROb2Rlcy5yZW1vdmUodmFsaWRhdGVJbnN0YW5jZShub2RlLCBOb2RlKSk7XG4gICAgICAgIG5vZGVbdHJlZVN0cnVjdHVyZVN5bWJvbF0ucGFyZW50ID0gbnVsbDtcblxuICAgICAgICBub2RlW3RyZWVTdHJ1Y3R1cmVTeW1ib2xdLmxldmVsID0gMDtcbiAgICAgICAgc2V0Q2hpbGRMZXZlbEFuZFBhcmVudC5jYWxsKHRoaXMsIG5vZGUsIC0xKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgICAqL1xuICAgIGhhc0NoaWxkTm9kZXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzW3RyZWVTdHJ1Y3R1cmVTeW1ib2xdLmNoaWxkTm9kZXMubGVuZ3RoID4gMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtNb25zdGVyLlR5cGVzLk5vZGV9XG4gICAgICogQHBhcmFtIHtOb2RlfSBub2RlXG4gICAgICovXG4gICAgaGFzQ2hpbGQobm9kZSkge1xuICAgICAgICByZXR1cm4gdGhpc1t0cmVlU3RydWN0dXJlU3ltYm9sXS5jaGlsZE5vZGVzLmhhcyh2YWxpZGF0ZUluc3RhbmNlKG5vZGUsIE5vZGUpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAc2luY2UgMS4yOC4wXG4gICAgICogQHJldHVybiB7c3RyaW5nfVxuICAgICAqL1xuICAgIHRvU3RyaW5nKCkge1xuICAgICAgICBsZXQgcGFydHMgPSBbXTtcbiAgICAgICAgaWYgKHRoaXNbaW50ZXJuYWxWYWx1ZVN5bWJvbF0pIHtcbiAgICAgICAgICAgIGxldCBsYWJlbCA9IHRoaXNbaW50ZXJuYWxWYWx1ZVN5bWJvbF07XG4gICAgICAgICAgICBpZiAoIWlzUHJpbWl0aXZlKGxhYmVsKSkgbGFiZWwgPSBKU09OLnN0cmluZ2lmeSh0aGlzW2ludGVybmFsVmFsdWVTeW1ib2xdKTtcblxuICAgICAgICAgICAgcGFydHMucHVzaChsYWJlbCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuaGFzQ2hpbGROb2RlcygpKSB7XG4gICAgICAgICAgICByZXR1cm4gcGFydHMuam9pbihcIlxcblwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBjb3VudCA9IHRoaXMuY2hpbGROb2Rlcy5sZW5ndGg7XG4gICAgICAgIGxldCBjb3VudGVyID0gMDtcblxuICAgICAgICBmb3IgKGNvbnN0IG5vZGUgb2YgdGhpcy5jaGlsZE5vZGVzKSB7XG4gICAgICAgICAgICBjb3VudGVyKys7XG4gICAgICAgICAgICBjb25zdCBwcmVmaXggPSAoY291bnQgPT09IGNvdW50ZXIgPyBcIlx1MjUxNFwiIDogXCJcdTI1MUNcIikucGFkU3RhcnQoMiAqIG5vZGUubGV2ZWwsIFwiIHxcIik7XG4gICAgICAgICAgICBwYXJ0cy5wdXNoKHByZWZpeCArIG5vZGUudG9TdHJpbmcoKSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcGFydHMuam9pbihcIlxcblwiKTtcbiAgICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Tm9kZX0gbm9kZVxuICogQHBhcmFtIHtpbnR9IG9wZXJhbmRcbiAqIEByZXR1cm4ge3NldENoaWxkTGV2ZWxBbmRQYXJlbnR9XG4gKi9cbmZ1bmN0aW9uIHNldENoaWxkTGV2ZWxBbmRQYXJlbnQobm9kZSwgb3BlcmFuZCkge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgaWYgKG5vZGUgIT09IHRoaXMpIHtcbiAgICAgICAgbm9kZVt0cmVlU3RydWN0dXJlU3ltYm9sXS5wYXJlbnQgPSB0aGlzO1xuICAgIH1cblxuICAgIG5vZGVbdHJlZVN0cnVjdHVyZVN5bWJvbF0uY2hpbGROb2Rlcy5mb3JFYWNoKGZ1bmN0aW9uIChjaGlsZCkge1xuICAgICAgICBjaGlsZFt0cmVlU3RydWN0dXJlU3ltYm9sXS5wYXJlbnQgPSBub2RlO1xuICAgICAgICBjaGlsZFt0cmVlU3RydWN0dXJlU3ltYm9sXS5sZXZlbCA9IG5vZGVbdHJlZVN0cnVjdHVyZVN5bWJvbF0ubGV2ZWwgKyBvcGVyYW5kO1xuICAgICAgICBzZXRDaGlsZExldmVsQW5kUGFyZW50LmNhbGwoc2VsZiwgY2hpbGQsIG9wZXJhbmQpO1xuICAgIH0pO1xuICAgIHJldHVybiB0aGlzO1xufVxuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgaXNBcnJheSwgaXNJbnN0YW5jZSB9IGZyb20gXCIuL2lzLm1qc1wiO1xuaW1wb3J0IHsgTm9kZSB9IGZyb20gXCIuL25vZGUubWpzXCI7XG5pbXBvcnQgeyB2YWxpZGF0ZUluc3RhbmNlIH0gZnJvbSBcIi4vdmFsaWRhdGUubWpzXCI7XG5pbXBvcnQgeyBpbnN0YW5jZVN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5leHBvcnQgeyBOb2RlTGlzdCB9O1xuXG4vKipcbiAqIFlvdSBjYW4gY3JlYXRlIHRoZSBpbnN0YW5jZSB2aWEgdGhlIG1vbnN0ZXIgbmFtZXNwYWNlIGBuZXcgTW9uc3Rlci5UeXBlcy5Ob2RlTGlzdCgpYC5cbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI2LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UeXBlc1xuICogQHN1bW1hcnkgQSBOb2RlTGlzdCBjbGFzc1xuICovXG5jbGFzcyBOb2RlTGlzdCBleHRlbmRzIFNldCB7XG4gICAgLyoqXG4gICAgICogQHRocm93cyB7RXJyb3J9IGludmFsaWQgdmFsdWUgdHlwZVxuICAgICAqIEBwYXJhbSB7Tm9kZUxpc3R8Tm9kZXxBcnJheTxOb2RlPn12YWx1ZXNcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih2YWx1ZXMpIHtcbiAgICAgICAgc3VwZXIoKTtcblxuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgICAgICBpZiAodmFsdWVzID09PSB1bmRlZmluZWQpIHJldHVybjtcblxuICAgICAgICBpZiAoaXNBcnJheSh2YWx1ZXMpKSB7XG4gICAgICAgICAgICB2YWx1ZXMuZm9yRWFjaCgodmFsdWUpID0+IHNlbGYuYWRkKHZhbHVlKSk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNJbnN0YW5jZSh2YWx1ZXMsIE5vZGVMaXN0KSkge1xuICAgICAgICAgICAgdmFsdWVzLmZvckVhY2goKHZhbHVlKSA9PiBzZWxmLmFkZCh2YWx1ZSkpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzSW5zdGFuY2UodmFsdWVzLCBOb2RlKSkge1xuICAgICAgICAgICAgc2VsZi5hZGQodmFsdWVzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImludmFsaWQgdmFsdWUgdHlwZVwiKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgYGluc3RhbmNlb2ZgIG9wZXJhdG9yLlxuICAgICAqIEByZXR1cm5zIHtzeW1ib2x9XG4gICAgICogQHNpbmNlIDIuMS4wXG4gICAgICovXG4gICAgc3RhdGljIGdldCBbaW5zdGFuY2VTeW1ib2xdKCkge1xuICAgICAgICByZXR1cm4gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvdHlwZXMvbm9kZS1saXN0XCIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtOb2RlfSBub2RlXG4gICAgICogQHJldHVybiB7TW9uc3Rlci5UeXBlcy5Ob2RlTGlzdH1cbiAgICAgKi9cbiAgICBhZGQobm9kZSkge1xuICAgICAgICBzdXBlci5hZGQodmFsaWRhdGVJbnN0YW5jZShub2RlLCBOb2RlKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Tm9kZX0gbm9kZVxuICAgICAqIEByZXR1cm5zIHtOb2RlTGlzdH1cbiAgICAgKi9cbiAgICByZW1vdmUobm9kZSkge1xuICAgICAgICBzdXBlci5kZWxldGUodmFsaWRhdGVJbnN0YW5jZShub2RlLCBOb2RlKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Tm9kZX0gbm9kZVxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgICAqL1xuICAgIGhhcyhub2RlKSB7XG4gICAgICAgIHJldHVybiBzdXBlci5oYXModmFsaWRhdGVJbnN0YW5jZShub2RlLCBOb2RlKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMge05vZGVMaXN0fVxuICAgICAqL1xuICAgIGNsZWFyKCkge1xuICAgICAgICBzdXBlci5jbGVhcigpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyB7Tm9kZUxpc3R9XG4gICAgICovXG4gICAgdG9BcnJheSgpIHtcbiAgICAgICAgcmV0dXJuIEFycmF5LmZyb20odGhpcyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMge05vZGVMaXN0fVxuICAgICAqL1xuICAgIHRvSlNPTigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudG9BcnJheSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIHtOb2RlTGlzdH1cbiAgICAgKi9cbiAgICB0b1N0cmluZygpIHtcbiAgICAgICAgbGV0IHBhcnRzID0gW107XG5cbiAgICAgICAgZm9yIChjb25zdCBub2RlIG9mIHRoaXMudG9BcnJheSgpKSB7XG4gICAgICAgICAgICBwYXJ0cy5wdXNoKG5vZGUudG9TdHJpbmcoKSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcGFydHMuam9pbihcIlxcblwiKTtcbiAgICB9XG5cbiAgICBnZXQgbGVuZ3RoKCkge1xuICAgICAgICByZXR1cm4gc3VwZXIuc2l6ZTtcbiAgICB9XG59XG4iLCAiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuaW1wb3J0IHtOb2RlfSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL25vZGUubWpzXCI7XG5pbXBvcnQge05vZGVMaXN0fSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL25vZGVsaXN0Lm1qc1wiO1xuXG5kZXNjcmliZSgnTm9kZUxpc3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgZGVzY3JpYmUoJyNjb25zdHJ1Y3RvcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCBjcmVhdGUgYW4gZW1wdHkgTm9kZUxpc3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgbm9kZUxpc3QgPSBuZXcgTm9kZUxpc3QoKTtcblxuICAgICAgICAgICAgZXhwZWN0KG5vZGVMaXN0LnNpemUpLnRvLmVxdWFsKDApO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIGNyZWF0ZSBhIE5vZGVMaXN0IGZyb20gYW4gYXJyYXknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgbm9kZUxpc3QgPSBuZXcgTm9kZUxpc3QoW1xuICAgICAgICAgICAgICAgIG5ldyBOb2RlKCdkaXYnKSxcbiAgICAgICAgICAgICAgICBuZXcgTm9kZSgnZGl2JyksXG4gICAgICAgICAgICAgICAgbmV3IE5vZGUoJ2RpdicpXG4gICAgICAgICAgICBdKTtcblxuICAgICAgICAgICAgZXhwZWN0KG5vZGVMaXN0LnNpemUpLnRvLmVxdWFsKDMpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIGNyZWF0ZSBhIE5vZGVMaXN0IGZyb20gYSBOb2RlTGlzdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBub2RlTGlzdCA9IG5ldyBOb2RlTGlzdChbXG4gICAgICAgICAgICAgICAgbmV3IE5vZGUoJ2RpdicpLFxuICAgICAgICAgICAgICAgIG5ldyBOb2RlKCdkaXYnKSxcbiAgICAgICAgICAgICAgICBuZXcgTm9kZSgnZGl2JylcbiAgICAgICAgICAgIF0pO1xuXG4gICAgICAgICAgICBsZXQgbm9kZUxpc3QyID0gbmV3IE5vZGVMaXN0KG5vZGVMaXN0KTtcblxuICAgICAgICAgICAgZXhwZWN0KG5vZGVMaXN0Mi5zaXplKS50by5lcXVhbCgzKTtcbiAgICAgICAgfSk7XG4gICAgICAgIFxuICAgIH0pO1xuICAgIFxuICAgICBcbiAgICBpdCgnY3JlYXRlIE5vZGVMaXN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICBleHBlY3QobmV3IE5vZGVMaXN0KCkpLmlzLmluc3RhbmNlb2YoTm9kZUxpc3QpO1xuICAgIH0pXG5cbiAgICBpdCgnYWRkIE5vZGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGV4cGVjdChuZXcgTm9kZUxpc3QoKS5hZGQobmV3IE5vZGUoKSkpLnRvLmJlLmluc3RhbmNlb2YoTm9kZUxpc3QpO1xuICAgIH0pXG5cbiAgICBpdCgncmVtb3ZlIE5vZGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGV4cGVjdChuZXcgTm9kZUxpc3QoKS5yZW1vdmUobmV3IE5vZGUoKSkpLnRvLmJlLmluc3RhbmNlb2YoTm9kZUxpc3QpO1xuICAgIH0pXG5cbiAgICBpdCgnaGFzIHVua25vd24gTm9kZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZXhwZWN0KG5ldyBOb2RlTGlzdCgpLmhhcyhuZXcgTm9kZSkpLnRvLmJlLmZhbHNlO1xuICAgIH0pXG5cbiAgICBpdCgnaGFzIGFkZGVkIE5vZGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IG4gPSBuZXcgTm9kZTtcbiAgICAgICAgZXhwZWN0KG5ldyBOb2RlTGlzdCgpLmFkZChuKS5oYXMobikpLnRvLmJlLnRydWU7XG4gICAgfSlcbiAgICBcbiAgICBpdCgndG9TdHJpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IG4gPSBuZXcgTm9kZTtcbiAgICAgICAgZXhwZWN0KG5ldyBOb2RlTGlzdCgpLmFkZChuZXcgTm9kZSgnYScpLmFwcGVuZENoaWxkKG5ldyBOb2RlKCdiJykpKS50b1N0cmluZygpKS50by5iZS5lcXVhbCgnYVxcbiBcdTI1MTRiJyk7XG4gICAgfSlcblxuICAgIGl0KCd0aHJvdyBleGNlcHRpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGV4cGVjdCgoKSA9PiBuZXcgTm9kZUxpc3QoKS5hZGQoMSkpLnRvLnRocm93KEVycm9yKTtcbiAgICB9KVxuXG5cbn0pOyIsICJpbXBvcnQge1xuICAgIFZlcnNpb25cbn0gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS90eXBlcy92ZXJzaW9uLm1qc1wiXG5cbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5cbmRlc2NyaWJlKCdWZXJzaW9uJywgZnVuY3Rpb24gKCkge1xuXG4gICAgZGVzY3JpYmUoJy5jb21wYXJlVG8oKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBbXG4gICAgICAgICAgICBbJzEuMi4zJywgJzEuMi4zJywgMF0sXG4gICAgICAgICAgICBbJzEuMi4yJywgJzEuMi4zJywgLTFdLFxuICAgICAgICAgICAgWycyJywgJzIuMC4wJywgMF0sXG4gICAgICAgICAgICBbJzEuMi40JywgJzEuMi4zJywgMV1cbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGMgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gJyArIGMgKyAnIHdoZW4gdGhlIHZhbHVlICcgKyBhICsgJyBpcyAnICsgYiArICcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KG5ldyBWZXJzaW9uKGEpLmNvbXBhcmVUbyhiKSkudG8uYmUuZXF1YWwoYyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCcudG9TdHJpbmcoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBbXG4gICAgICAgICAgICBbJzEuMS4xJywgJzIuMycsIDMsICcxLjIuMyddLFxuICAgICAgICAgICAgWycxLjIuNCcsICcxLjIuMycsIDUsICcxLjEuNSddXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBjID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgZCA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpdCgnc2hvdWxkIHJldHVybiAnICsgZCwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGV4cGVjdChuZXcgVmVyc2lvbihhLCBiLCBjKS50b1N0cmluZygpKS50by5iZS5lcXVhbChkKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9KVxuXG59KTtcblxuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgaW50ZXJuYWxTeW1ib2wgfSBmcm9tIFwiLi4vY29uc3RhbnRzLm1qc1wiO1xuXG5pbXBvcnQgeyBCYXNlIH0gZnJvbSBcIi4vYmFzZS5tanNcIjtcbmltcG9ydCB7IGlzSW5zdGFuY2UgfSBmcm9tIFwiLi9pcy5tanNcIjtcbmltcG9ydCB7IE5vZGUgfSBmcm9tIFwiLi9ub2RlLm1qc1wiO1xuaW1wb3J0IHsgTm9kZUxpc3QgfSBmcm9tIFwiLi9ub2RlbGlzdC5tanNcIjtcbmltcG9ydCB7IHZhbGlkYXRlSW5zdGFuY2UgfSBmcm9tIFwiLi92YWxpZGF0ZS5tanNcIjtcblxuZXhwb3J0IHsgTm9kZVJlY3Vyc2l2ZUl0ZXJhdG9yIH07XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEB0eXBlIHtzeW1ib2x9XG4gKi9cbmNvbnN0IGlzTm9kZUxpc3RTeW1ib2wgPSBTeW1ib2woXCJpc05vZGVMaXN0XCIpO1xuXG4vKipcbiAqIFlvdSBjYW4gY3JlYXRlIHRoZSBpbnN0YW5jZSB2aWEgdGhlIG1vbnN0ZXIgbmFtZXNwYWNlIGBuZXcgTW9uc3Rlci5UeXBlcy5Ob2RlUmVjdXJzaXZlSXRlcmF0b3IoKWAuXG4gKlxuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL3R5cGVzL25vZGVyZWN1cnNpdmVpdGVyYXRvci5tanNcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjYuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKiBAc3VtbWFyeSBBbiBpdGVyYXRvciB0byBydW4gcmVjdXJzaXZlbHkgdGhyb3VnaCBhIHRyZWUgb2Ygbm9kZXNcbiAqL1xuY2xhc3MgTm9kZVJlY3Vyc2l2ZUl0ZXJhdG9yIGV4dGVuZHMgQmFzZSB7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOb2RlfSBbZGF0YV1cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcihub2RlKSB7XG4gICAgICAgIHN1cGVyKCk7XG5cbiAgICAgICAgdGhpc1tpc05vZGVMaXN0U3ltYm9sXSA9IGZhbHNlO1xuXG4gICAgICAgIC8vIGl0ZXJhdG9yIGlzIGEgbm9kZWxpc3RcbiAgICAgICAgaWYgKGlzSW5zdGFuY2Uobm9kZSwgTm9kZUxpc3QpKSB7XG4gICAgICAgICAgICBsZXQgY2hpbGRyZW4gPSBub2RlO1xuICAgICAgICAgICAgbm9kZSA9IG5ldyBOb2RlKCk7XG4gICAgICAgICAgICBub2RlLmNoaWxkTm9kZXMgPSBjaGlsZHJlbjtcbiAgICAgICAgICAgIHRoaXNbaXNOb2RlTGlzdFN5bWJvbF0gPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpc1tpbnRlcm5hbFN5bWJvbF0gPSB2YWxpZGF0ZUluc3RhbmNlKG5vZGUsIE5vZGUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9PcGVyYXRvcnMveWllbGRcbiAgICAgKi9cbiAgICBbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgZW5kIG9mIHRoZSBnZW5lcmF0b3IgZnVuY3Rpb24gaXMgcmVhY2hlZC4gSW4gdGhpcyBjYXNlLCBleGVjdXRpb24gb2YgdGhlIGdlbmVyYXRvclxuICAgICAgICAgKiBlbmRzIGFuZCBhbiBJdGVyYXRvclJlc3VsdCBpcyByZXR1cm5lZCB0byB0aGUgY2FsbGVyIGluIHdoaWNoIHRoZSB2YWx1ZSBpcyB1bmRlZmluZWQgYW5kIGRvbmUgaXMgdHJ1ZS5cbiAgICAgICAgICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9PcGVyYXRvcnMveWllbGRcbiAgICAgICAgICovXG4gICAgICAgIGlmICh0aGlzW2ludGVybmFsU3ltYm9sXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBpdGVyYXRvciBpcyBhIG5vZGVsaXN0IGFuZCB0aGUgbWFpbiBub2RlIGlzIG9ubHkgYSBwbGFjZWhvbGRlclxuICAgICAgICBpZiAodGhpc1tpc05vZGVMaXN0U3ltYm9sXSAhPT0gdHJ1ZSkge1xuICAgICAgICAgICAgeWllbGQgdGhpc1tpbnRlcm5hbFN5bWJvbF07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpc1tpbnRlcm5hbFN5bWJvbF0uaGFzQ2hpbGROb2RlcygpKSB7XG4gICAgICAgICAgICBsZXQgY2hpbGROb2RlcyA9IHRoaXNbaW50ZXJuYWxTeW1ib2xdLmNoaWxkTm9kZXM7XG5cbiAgICAgICAgICAgIGZvciAobGV0IG5vZGUgb2YgY2hpbGROb2Rlcykge1xuICAgICAgICAgICAgICAgIHlpZWxkKiBuZXcgTm9kZVJlY3Vyc2l2ZUl0ZXJhdG9yKG5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBjYWxsYmFja1xuICAgICAqIEByZXR1cm4ge01vbnN0ZXIuVHlwZXMuTm9kZVJlY3Vyc2l2ZUl0ZXJhdG9yfVxuICAgICAqL1xuICAgIGZvckVhY2goY2FsbGJhY2spIHtcbiAgICAgICAgZm9yIChjb25zdCBub2RlIG9mIHRoaXMpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKG5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbiIsICIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge05vZGV9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdHlwZXMvbm9kZS5tanNcIjtcbmltcG9ydCB7Tm9kZUxpc3R9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdHlwZXMvbm9kZWxpc3QubWpzXCI7XG5pbXBvcnQge05vZGVSZWN1cnNpdmVJdGVyYXRvcn0gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS90eXBlcy9ub2RlcmVjdXJzaXZlaXRlcmF0b3IubWpzXCI7XG5cbmRlc2NyaWJlKCdOb2RlTGlzdCcsIGZ1bmN0aW9uICgpIHtcbiAgICBkZXNjcmliZSgnI2NvbnN0cnVjdG9yJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIGNyZWF0ZSBhbiBlbXB0eSBOb2RlTGlzdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBub2RlTGlzdCA9IG5ldyBOb2RlTGlzdCgpO1xuXG4gICAgICAgICAgICBleHBlY3Qobm9kZUxpc3Quc2l6ZSkudG8uZXF1YWwoMCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgY3JlYXRlIGEgTm9kZUxpc3QgZnJvbSBhbiBhcnJheScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBub2RlTGlzdCA9IG5ldyBOb2RlTGlzdChbXG4gICAgICAgICAgICAgICAgbmV3IE5vZGUoJ2RpdicpLFxuICAgICAgICAgICAgICAgIG5ldyBOb2RlKCdkaXYnKSxcbiAgICAgICAgICAgICAgICBuZXcgTm9kZSgnZGl2JylcbiAgICAgICAgICAgIF0pO1xuXG4gICAgICAgICAgICBleHBlY3Qobm9kZUxpc3Quc2l6ZSkudG8uZXF1YWwoMyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgY3JlYXRlIGEgTm9kZUxpc3QgZnJvbSBhIE5vZGVMaXN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGV0IG5vZGVMaXN0ID0gbmV3IE5vZGVMaXN0KFtcbiAgICAgICAgICAgICAgICBuZXcgTm9kZSgnZGl2JyksXG4gICAgICAgICAgICAgICAgbmV3IE5vZGUoJ2RpdicpLFxuICAgICAgICAgICAgICAgIG5ldyBOb2RlKCdkaXYnKVxuICAgICAgICAgICAgXSk7XG5cbiAgICAgICAgICAgIGxldCBub2RlTGlzdDIgPSBuZXcgTm9kZUxpc3Qobm9kZUxpc3QpO1xuXG4gICAgICAgICAgICBleHBlY3Qobm9kZUxpc3QyLnNpemUpLnRvLmVxdWFsKDMpO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdjcmVhdGUgTm9kZUxpc3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGV4cGVjdChuZXcgTm9kZUxpc3QoKSkuaXMuaW5zdGFuY2VvZihOb2RlTGlzdCk7XG4gICAgfSlcblxuICAgIGl0KCdhZGQgTm9kZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZXhwZWN0KG5ldyBOb2RlTGlzdCgpLmFkZChuZXcgTm9kZSgpKSkudG8uYmUuaW5zdGFuY2VvZihOb2RlTGlzdCk7XG4gICAgfSlcblxuICAgIGl0KCdyZW1vdmUgTm9kZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZXhwZWN0KG5ldyBOb2RlTGlzdCgpLnJlbW92ZShuZXcgTm9kZSgpKSkudG8uYmUuaW5zdGFuY2VvZihOb2RlTGlzdCk7XG4gICAgfSlcblxuICAgIGl0KCdoYXMgdW5rbm93biBOb2RlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBleHBlY3QobmV3IE5vZGVMaXN0KCkuaGFzKG5ldyBOb2RlKSkudG8uYmUuZmFsc2U7XG4gICAgfSlcblxuICAgIGl0KCdoYXMgYWRkZWQgTm9kZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgbiA9IG5ldyBOb2RlO1xuICAgICAgICBleHBlY3QobmV3IE5vZGVMaXN0KCkuYWRkKG4pLmhhcyhuKSkudG8uYmUudHJ1ZTtcbiAgICB9KVxuXG4gICAgaXQoJ3Rocm93IGV4Y2VwdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZXhwZWN0KCgpID0+IG5ldyBOb2RlTGlzdCgpLmFkZCgxKSkudG8udGhyb3coRXJyb3IpO1xuICAgIH0pXG5cbiAgICBpdCgnY2hlY2sgbGV2ZWwnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgY29uc3Qgcm9vdCA9IG5ldyBOb2RlKCdyb290Jyk7XG5cbiAgICAgICAgY29uc3QgbjEgPSBuZXcgTm9kZSgnbjEnKTtcbiAgICAgICAgY29uc3QgbjIgPSBuZXcgTm9kZSgnbjInKTtcbiAgICAgICAgY29uc3QgbjMgPSBuZXcgTm9kZSgnbjMnKTtcbiAgICAgICAgY29uc3QgbjQgPSBuZXcgTm9kZSgnbjQnKTtcblxuICAgICAgICBjb25zdCBuMTEgPSBuZXcgTm9kZSgnbjExJyk7XG4gICAgICAgIGNvbnN0IG4xMiA9IG5ldyBOb2RlKCduMTInKTtcbiAgICAgICAgY29uc3QgbjEzID0gbmV3IE5vZGUoJ24xMycpO1xuXG4gICAgICAgIGNvbnN0IG4yMSA9IG5ldyBOb2RlKCduMjEnKTtcbiAgICAgICAgY29uc3QgbjIyID0gbmV3IE5vZGUoJ24yMicpO1xuICAgICAgICBjb25zdCBuMjMgPSBuZXcgTm9kZSgnbjIzJyk7XG5cbiAgICAgICAgY29uc3QgbjQxID0gbmV3IE5vZGUoJ240MScpO1xuICAgICAgICBjb25zdCBuNDIgPSBuZXcgTm9kZSgnbjQyJyk7XG5cbiAgICAgICAgY29uc3QgbjQxMSA9IG5ldyBOb2RlKCduNDExJyk7XG4gICAgICAgIGNvbnN0IG40MTIgPSBuZXcgTm9kZSgnbjQxMicpO1xuICAgICAgICBjb25zdCBuNDEzID0gbmV3IE5vZGUoJ240MTMnKTtcblxuICAgICAgICBjb25zdCBuNDEyMSA9IG5ldyBOb2RlKCduNDEyMScpO1xuXG4gICAgICAgIHJvb3QuYXBwZW5kQ2hpbGQobjEpLmFwcGVuZENoaWxkKG4yKS5hcHBlbmRDaGlsZChuMykuYXBwZW5kQ2hpbGQobjQpO1xuICAgICAgICBuMS5hcHBlbmRDaGlsZChuMTEpLmFwcGVuZENoaWxkKG4xMikuYXBwZW5kQ2hpbGQobjEzKTtcbiAgICAgICAgbjIuYXBwZW5kQ2hpbGQobjIxKS5hcHBlbmRDaGlsZChuMjIpLmFwcGVuZENoaWxkKG4yMyk7XG4gICAgICAgIG40LmFwcGVuZENoaWxkKG40MSkuYXBwZW5kQ2hpbGQobjQyKTtcbiAgICAgICAgbjQxLmFwcGVuZENoaWxkKG40MTEpLmFwcGVuZENoaWxkKG40MTIpLmFwcGVuZENoaWxkKG40MTMpO1xuICAgICAgICBuNDEyLmFwcGVuZENoaWxkKG40MTIxKTtcblxuICAgICAgICBsZXQgaXRlcmF0b3IgPSBuZXcgTm9kZVJlY3Vyc2l2ZUl0ZXJhdG9yKHJvb3QpO1xuXG4gICAgICAgIGxldCByZXN1bHQgPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBuIG9mIGl0ZXJhdG9yKSB7XG4gICAgICAgICAgICBleHBlY3QobikudG8uYmUuYW4uaW5zdGFuY2VvZihOb2RlKTtcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKG4udmFsdWUgKyBcIjpcIiArIG4ubGV2ZWwpO1xuICAgICAgICB9XG5cblxuICAgICAgICBleHBlY3QocmVzdWx0KS50by5kZWVwLmVxdWFsKFtcbiAgICAgICAgICAgICdyb290OjAnLFxuICAgICAgICAgICAgJ24xOjEnLFxuICAgICAgICAgICAgJ24xMToyJyxcbiAgICAgICAgICAgICduMTI6MicsXG4gICAgICAgICAgICAnbjEzOjInLFxuICAgICAgICAgICAgJ24yOjEnLFxuICAgICAgICAgICAgJ24yMToyJyxcbiAgICAgICAgICAgICduMjI6MicsXG4gICAgICAgICAgICAnbjIzOjInLFxuICAgICAgICAgICAgJ24zOjEnLFxuICAgICAgICAgICAgJ240OjEnLFxuICAgICAgICAgICAgJ240MToyJyxcbiAgICAgICAgICAgICduNDExOjMnLFxuICAgICAgICAgICAgJ240MTI6MycsXG4gICAgICAgICAgICAnbjQxMjE6NCcsXG4gICAgICAgICAgICAnbjQxMzozJyxcbiAgICAgICAgICAgICduNDI6MidcblxuICAgICAgICBdKTtcblxuICAgICAgICBuNDEyMS5hcHBlbmRDaGlsZChuZXcgTm9kZSgnbjQxMjExJykpO1xuXG4gICAgICAgIGl0ZXJhdG9yID0gbmV3IE5vZGVSZWN1cnNpdmVJdGVyYXRvcihyb290KTtcbiAgICAgICAgcmVzdWx0ID0gW107XG4gICAgICAgIGZvciAoY29uc3QgbiBvZiBpdGVyYXRvcikge1xuICAgICAgICAgICAgZXhwZWN0KG4pLnRvLmJlLmFuLmluc3RhbmNlb2YoTm9kZSk7XG4gICAgICAgICAgICByZXN1bHQucHVzaChuLnZhbHVlICsgXCI6XCIgKyBuLmxldmVsKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGV4cGVjdChyZXN1bHQpLnRvLmRlZXAuZXF1YWwoW1xuICAgICAgICAgICAgJ3Jvb3Q6MCcsXG4gICAgICAgICAgICAnbjE6MScsXG4gICAgICAgICAgICAnbjExOjInLFxuICAgICAgICAgICAgJ24xMjoyJyxcbiAgICAgICAgICAgICduMTM6MicsXG4gICAgICAgICAgICAnbjI6MScsXG4gICAgICAgICAgICAnbjIxOjInLFxuICAgICAgICAgICAgJ24yMjoyJyxcbiAgICAgICAgICAgICduMjM6MicsXG4gICAgICAgICAgICAnbjM6MScsXG4gICAgICAgICAgICAnbjQ6MScsXG4gICAgICAgICAgICAnbjQxOjInLFxuICAgICAgICAgICAgJ240MTE6MycsXG4gICAgICAgICAgICAnbjQxMjozJyxcbiAgICAgICAgICAgICduNDEyMTo0JyxcbiAgICAgICAgICAgICduNDEyMTE6NScsXG4gICAgICAgICAgICAnbjQxMzozJyxcbiAgICAgICAgICAgICduNDI6MidcblxuICAgICAgICBdKTtcblxuXG4gICAgICAgIGNvbnN0IGJiID0gbmV3IE5vZGUoJ2JiJykgLy8gYmlnIGJhbmdcblxuICAgICAgICBiYi5hcHBlbmRDaGlsZChyb290KTtcbiAgICAgICAgaXRlcmF0b3IgPSBuZXcgTm9kZVJlY3Vyc2l2ZUl0ZXJhdG9yKGJiKTtcblxuICAgICAgICByZXN1bHQgPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBuIG9mIGl0ZXJhdG9yKSB7XG4gICAgICAgICAgICBleHBlY3QobikudG8uYmUuYW4uaW5zdGFuY2VvZihOb2RlKTtcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKG4udmFsdWUgKyBcIjpcIiArIG4ubGV2ZWwpO1xuICAgICAgICB9XG5cbiAgICAgICAgZXhwZWN0KHJlc3VsdCkudG8uZGVlcC5lcXVhbChbXG4gICAgICAgICAgICAnYmI6MCcsXG4gICAgICAgICAgICAncm9vdDoxJyxcbiAgICAgICAgICAgICduMToyJyxcbiAgICAgICAgICAgICduMTE6MycsXG4gICAgICAgICAgICAnbjEyOjMnLFxuICAgICAgICAgICAgJ24xMzozJyxcbiAgICAgICAgICAgICduMjoyJyxcbiAgICAgICAgICAgICduMjE6MycsXG4gICAgICAgICAgICAnbjIyOjMnLFxuICAgICAgICAgICAgJ24yMzozJyxcbiAgICAgICAgICAgICduMzoyJyxcbiAgICAgICAgICAgICduNDoyJyxcbiAgICAgICAgICAgICduNDE6MycsXG4gICAgICAgICAgICAnbjQxMTo0JyxcbiAgICAgICAgICAgICduNDEyOjQnLFxuICAgICAgICAgICAgJ240MTIxOjUnLFxuICAgICAgICAgICAgJ240MTIxMTo2JyxcbiAgICAgICAgICAgICduNDEzOjQnLFxuICAgICAgICAgICAgJ240MjozJ1xuXG4gICAgICAgIF0pO1xuXG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCdMZXZlbHMnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ24yIHNob3VsZCBsZXZlbCAyJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBjb25zdCBuMCA9IG5ldyBOb2RlKCdhYmMnKTtcblxuICAgICAgICAgICAgY29uc3QgbjEgPSBuZXcgTm9kZSgnZGVmJyk7XG4gICAgICAgICAgICBuMC5hcHBlbmRDaGlsZChuMSlcblxuICAgICAgICAgICAgY29uc3QgbjIgPSBuZXcgTm9kZSgnZ2hpJyk7XG4gICAgICAgICAgICBuMS5hcHBlbmRDaGlsZChuMik7XG5cbiAgICAgICAgICAgIGNvbnN0IG4zID0gbmV3IE5vZGUoJ2prbCcpO1xuICAgICAgICAgICAgbjIuYXBwZW5kQ2hpbGQobjMpO1xuXG4gICAgICAgICAgICBleHBlY3QobjAubGV2ZWwpLnRvLmJlLmVxdWFsKDApO1xuICAgICAgICAgICAgZXhwZWN0KG4xLmxldmVsKS50by5iZS5lcXVhbCgxKTtcbiAgICAgICAgICAgIGV4cGVjdChuMi5sZXZlbCkudG8uYmUuZXF1YWwoMik7XG4gICAgICAgICAgICBleHBlY3QobjMubGV2ZWwpLnRvLmJlLmVxdWFsKDMpO1xuXG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG5cbiAgICBkZXNjcmliZSgndG9TdHJpbmcoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBpdCgnc2hvdWxkIG91dHB1dCBlbXB0eSBzdHJpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zdCBub2RlID0gbmV3IE5vZGUoKTtcbiAgICAgICAgICAgIGV4cGVjdChub2RlLnRvU3RyaW5nKCkpLmlzLmVxdWFsKCcnKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBvdXRwdXQgc3RyaW5nJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY29uc3QgbjAgPSBuZXcgTm9kZSgnYWJjJyk7XG5cbiAgICAgICAgICAgIGNvbnN0IG4xID0gbmV3IE5vZGUoJ2RlZicpO1xuICAgICAgICAgICAgbjAuYXBwZW5kQ2hpbGQobjEpXG5cbiAgICAgICAgICAgIGNvbnN0IG4xMSA9IG5ldyBOb2RlKCdnaGknKTtcbiAgICAgICAgICAgIG4wLmFwcGVuZENoaWxkKG4xMSlcblxuICAgICAgICAgICAgY29uc3QgbjIgPSBuZXcgTm9kZSgnamtsJyk7XG4gICAgICAgICAgICBuMS5hcHBlbmRDaGlsZChuMik7XG5cbiAgICAgICAgICAgIGNvbnN0IG4zID0gbmV3IE5vZGUoJ21ubycpO1xuICAgICAgICAgICAgbjEuYXBwZW5kQ2hpbGQobjMpO1xuXG4gICAgICAgICAgICBjb25zdCBuNCA9IG5ldyBOb2RlKCdwcXInKTtcbiAgICAgICAgICAgIG4yLmFwcGVuZENoaWxkKG40KTtcblxuICAgICAgICAgICAgZXhwZWN0KG4yLmxldmVsKS50by5iZS5lcXVhbCgyKVxuXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhuMC50b1N0cmluZygpKTtcbiAgICAgICAgICAgIC8vIGV4cGVjdChuMC50b1N0cmluZygpKS5pcy5lcXVhbCgnJyk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG5cbn0pOyIsICIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge05vZGV9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdHlwZXMvbm9kZS5tanNcIjtcbmltcG9ydCB7Tm9kZUxpc3R9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdHlwZXMvbm9kZWxpc3QubWpzXCI7XG5pbXBvcnQge05vZGVSZWN1cnNpdmVJdGVyYXRvcn0gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS90eXBlcy9ub2RlcmVjdXJzaXZlaXRlcmF0b3IubWpzXCI7XG5cbmRlc2NyaWJlKCdOb2RlUmVjdXJzaXZlSXRlcmF0b3InLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGV4ZXB0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBleHBlY3QoKCkgPT4gbmV3IE5vZGVSZWN1cnNpdmVJdGVyYXRvcigpKS50by50aHJvdyhFcnJvcilcbiAgICB9KTtcbiAgICBpdCgnc2hvdWxkIGJlIGEgZnVuY3Rpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGV4cGVjdChOb2RlUmVjdXJzaXZlSXRlcmF0b3IpLnRvLmJlLmEoJ2Z1bmN0aW9uJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGJlIGEgY29uc3RydWN0b3InLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGV4cGVjdChuZXcgTm9kZVJlY3Vyc2l2ZUl0ZXJhdG9yKG5ldyBOb2RlKSkudG8uYmUuYW4uaW5zdGFuY2VvZihOb2RlUmVjdXJzaXZlSXRlcmF0b3IpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9PcGVyYXRvcnMveWllbGRcbiAgICAgKi9cbiAgICBpdCgndW5kZWZpbmVkIHNob3VsZCBub3QgcmVzdWx0IGluIHVuZGVmaW5lZCBub2RlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBpdGVyYXRvciA9IG5ldyBOb2RlUmVjdXJzaXZlSXRlcmF0b3IobmV3IE5vZGUpO1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IG4gb2YgaXRlcmF0b3IpIHtcbiAgICAgICAgICAgIGV4cGVjdChuKS50by5iZS5hbi5pbnN0YW5jZW9mKE5vZGUpO1xuICAgICAgICAgICAgcmVzdWx0LnB1c2gobi52YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBleHBlY3QocmVzdWx0KS50by5kZWVwLmVxdWFsKFt1bmRlZmluZWRdKTtcblxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBpdGVyYXRlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBub2RlID1cbiAgICAgICAgICAgIG5ldyBOb2RlKCcxJylcbiAgICAgICAgbm9kZS5hcHBlbmRDaGlsZChcbiAgICAgICAgICAgIChuZXcgTm9kZSgnMicpKS5hcHBlbmRDaGlsZChuZXcgTm9kZSgnMi4xJykpLmFwcGVuZENoaWxkKG5ldyBOb2RlKCcyLjInKSkuYXBwZW5kQ2hpbGQobmV3IE5vZGUoJzIuMycpKSkuYXBwZW5kQ2hpbGQobmV3IE5vZGUoJzMnKSkuYXBwZW5kQ2hpbGQobmV3IE5vZGUoJzQnKS5hcHBlbmRDaGlsZChuZXcgTm9kZSgnNC4xJykpLmFwcGVuZENoaWxkKG5ldyBOb2RlKCc0LjInKSkpO1xuXG4gICAgICAgIGNvbnN0IGl0ZXJhdG9yID0gbmV3IE5vZGVSZWN1cnNpdmVJdGVyYXRvcihub2RlKTtcblxuICAgICAgICBjb25zdCByZXN1bHQgPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBuIG9mIGl0ZXJhdG9yKSB7XG4gICAgICAgICAgICBleHBlY3QobikudG8uYmUuYW4uaW5zdGFuY2VvZihOb2RlKTtcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKG4udmFsdWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgZXhwZWN0KHJlc3VsdCkudG8uZGVlcC5lcXVhbChbJzEnLCAnMicsICcyLjEnLCAnMi4yJywgJzIuMycsICczJywgJzQnLCAnNC4xJywgJzQuMiddKTtcblxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBpdGVyYXRlIG5vZGVsaXN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBub2RlTGlzdCA9IG5ldyBOb2RlTGlzdCgpO1xuXG4gICAgICAgIG5vZGVMaXN0LmFkZChcbiAgICAgICAgICAgIChuZXcgTm9kZSgnMicpKS5hcHBlbmRDaGlsZChuZXcgTm9kZSgnMi4xJykpLmFwcGVuZENoaWxkKG5ldyBOb2RlKCcyLjInKSkuYXBwZW5kQ2hpbGQobmV3IE5vZGUoJzIuMycpKS5hcHBlbmRDaGlsZChuZXcgTm9kZSgnMycpKS5hcHBlbmRDaGlsZChuZXcgTm9kZSgnNCcpLmFwcGVuZENoaWxkKG5ldyBOb2RlKCc0LjEnKSkuYXBwZW5kQ2hpbGQobmV3IE5vZGUoJzQuMicpKSkpO1xuXG4gICAgICAgIG5vZGVMaXN0LmFkZChuZXcgTm9kZSgneCcpKTtcblxuICAgICAgICBjb25zdCBpdGVyYXRvciA9IG5ldyBOb2RlUmVjdXJzaXZlSXRlcmF0b3Iobm9kZUxpc3QpO1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IG4gb2YgaXRlcmF0b3IpIHtcbiAgICAgICAgICAgIGV4cGVjdChuKS50by5iZS5hbi5pbnN0YW5jZW9mKE5vZGUpO1xuICAgICAgICAgICAgcmVzdWx0LnB1c2gobi52YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIGV4cGVjdChyZXN1bHQpLnRvLmRlZXAuZXF1YWwoWycyJywgJzIuMScsICcyLjInLCAnMi4zJywgJzMnLCAnNCcsICc0LjEnLCAnNC4yJywgJ3gnXSk7XG5cbiAgICB9KTtcblxufSk7IiwgImltcG9ydCB7Z2V0R2xvYmFsLCBnZXRHbG9iYWxPYmplY3QsIGdldEdsb2JhbEZ1bmN0aW9ufSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL2dsb2JhbC5tanNcIjtcbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5cbmRlc2NyaWJlKCdHbG9iYWwnLCBmdW5jdGlvbiAoKSB7XG4gICAgZGVzY3JpYmUoJ2dldEdsb2JhbCcsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBnbG9iYWwgb2JqZWN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGV0IHQgPSB0eXBlb2YgZ2V0R2xvYmFsKCk7XG4gICAgICAgICAgICBleHBlY3QodCkudG8uYmUuZXF1YWwoJ29iamVjdCcpXG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG4gICAgZGVzY3JpYmUoJ2dldEdsb2JhbEZ1bmN0aW9uJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGdsb2JhbCBmdW5jdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCB0ID0gdHlwZW9mIGdldEdsb2JhbEZ1bmN0aW9uKCdwYXJzZUludCcpO1xuICAgICAgICAgICAgZXhwZWN0KHQpLnRvLmJlLmVxdWFsKCdmdW5jdGlvbicpXG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG4gICAgZGVzY3JpYmUoJ2dldEdsb2JhbE9iamVjdCcsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBnbG9iYWwgb2JqZWN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGV0IHQgPSB0eXBlb2YgZ2V0R2xvYmFsT2JqZWN0KCdKU09OJyk7XG4gICAgICAgICAgICBleHBlY3QodCkudG8uYmUuZXF1YWwoJ29iamVjdCcpXG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG59KTtcblxuIiwgIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7cGFyc2VEYXRhVVJMfSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL2RhdGF1cmwubWpzXCI7XG5cbmRlc2NyaWJlKCdEYXRhdXJsJywgZnVuY3Rpb24gKCkge1xuXG4gICAgW1xuICAgICAgICBbXCIgZGF0YTp0ZXh0L2h0bWwsJTNDaDElM0VIZWxsbyUyQyUyMFdvcmxkISUzQyUyRmgxJTNFXCJdLFxuICAgICAgICBbXCJkYXRhOnRleHQvaHRtbDtjaGFyc2V0PVVTLUFTQ0lJLCUzQ2gxJTNFSGVsbG8hJTNDJTJGaDElM0VcIl0sXG4gICAgICAgIFtcImRhdGE6LEElMjBicmllZiUyMG5vdGVcIiwgJ2RhdGE6dGV4dC9wbGFpbjtjaGFyc2V0PVVTLUFTQ0lJLEElMjBicmllZiUyMG5vdGUnXSxcbiAgICAgICAgW1wiZGF0YTppbWFnZS9wbmc7YmFzZTY0LGlWQk9SdzBLR2dvQUFBQU5TVWhFVWdBQUFCQUFBQUFRQVFNQUFBQWxQVzBpQUFBQUJsQk1WRVVBQUFELy8vK2wyWi9kQUFBQU0wbEVRVlI0bkdQNC81L2gvMStHLzU4WkRyQXozRC9NY0g4eXc4M05ERGVOR2U0VWc5Qzl6d3ozZ1ZMTURBL0E2UDkvQUZHR0Z5ak9YWnRRQUFBQUFFbEZUa1N1UW1DQ1wiXSxcbiAgICAgICAgW1wiIGRhdGE6LEhlbGxvJTJDJTIwV29ybGQhXCIsICdkYXRhOnRleHQvcGxhaW47Y2hhcnNldD1VUy1BU0NJSSxIZWxsbyUyQyUyMFdvcmxkISddLFxuICAgICAgICBbXCIgICBkYXRhOmltYWdlL3BuZztiYXNlNjQsaVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUFnQUFBQUlCQU1BQUFBMklhTzRBQUFBRlZCTVZFWGs1T1RuNStmdDdlMzE5ZlgyOXZiNStmbi8vLysrR1VtVkFBQUFMVWxFUVZRSUhXTklDbllMWm5BTFRncG1NR1lJRldZSVpUQTJaRkF6VFRGbFNERlZNd1Z5UWhtQXdzWU1BS0RhQnkwYXhYL2lBQUFBQUVsRlRrU3VRbUNDICAgXCJdLFxuICAgICAgICBbXCIgZGF0YTosSGVsbG8gV29ybGQhXCIsICdkYXRhOnRleHQvcGxhaW47Y2hhcnNldD1VUy1BU0NJSSxIZWxsbyUyMFdvcmxkISddLFxuICAgICAgICBbXCJkYXRhOmltYWdlL3BuZztiYXNlNjQsaVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUFnQUFBQUlCQU1BQUFBMklhTzRBQUFBRlZCTVZFWGs1T1RuNStmdDdlMzE5ZlgyOXZiNStmbi8vLysrR1VtVkFBQUFMVWxFUVZRSUhXTklDbllMWm5BTFRncG1NR1lJRldZSVpUQTJaRkF6VFRGbFNERlZNd1Z5UWhtQXdzWU1BS0RhQnkwYXhYL2lBQUFBQUVsRlRrU3VRbUNDXCJdLFxuICAgICAgICBbXCIgZGF0YTp0ZXh0L3BsYWluO2Jhc2U2NCxTR1ZzYkc4c0lGZHZjbXhrSVElM0QlM0RcIl1cblxuXG4gICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICBpZiAoYiA9PT0gdW5kZWZpbmVkKSBiID0gYS50cmltKCk7XG5cblxuICAgICAgICBpdCgncGFyc2VEYXRhVVJMKCcgKyBhICsgJyknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIGV4cGVjdChwYXJzZURhdGFVUkwoYSkudG9TdHJpbmcoKSkudG8uYmUuZXF1YWwoYik7XG4gICAgICAgIH0pXG5cbiAgICB9KTtcblxuICAgIFtcbiAgICAgICAgW1wiZGF0YXhiYXNlNjRcIl0sXG4gICAgICAgIFtcImRhdGE6SGVsbG9Xb3JsZFwiXSxcbiAgICAgICAgW1wiZGF0YTp0ZXh0L2h0bWw7Y2hhcnNldD0sJTNDaDElM0VIZWxsbyElM0MlMkZoMSUzRVwiXSxcbiAgICAgICAgW1wiZGF0YTp0ZXh0L2h0bWw7Y2hhcnNldCwlM0NoMSUzRUhlbGxvISUzQyUyRmgxJTNFXCIsIFwiZGF0YTpiYXNlNjQsaVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUJBQUFBQVFBUU1BQUFBbFBXMGlBQUFBQmxCTVZFVUFBQUQvLy8rbDJaL2RBQUFBTTBsRVFWUjRuR1A0LzUvaC8xK0cvNThaRHJBejNEL01jSDh5dzgzTkREZU5HZTRVZzlDOXp3ejNnVkxNREEvQTZQOS9BRkdHRnlqT1hadFFBQUFBQUVsRlRrU3VRbUNDXCJdLFxuICAgICAgICBbXCJcIl0sXG4gICAgICAgIFtcImh0dHA6Ly93aWtpcGVkaWEub3JnXCJdLFxuICAgICAgICBbXCJiYXNlNjRcIl0sXG4gICAgICAgIFtcImlWQk9SdzBLR2dvQUFBQU5TVWhFVWdBQUFCQUFBQUFRQVFNQUFBQWxQVzBpQUFBQUJsQk1WRVVBQUFELy8vK2wyWi9kQUFBQU0wbEVRVlI0bkdQNC81L2gvMStHLzU4WkRyQXozRC9NY0g4eXc4M05ERGVOR2U0VWc5Qzl6d3ozZ1ZMTURBL0E2UDkvQUZHR0Z5ak9YWnRRQUFBQUFFbEZUa1N1UW1DQ1wiXVxuXG4gICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcblxuXG4gICAgICAgIGl0KCdzaG91bGQgdGhyb3cgZXhjZXB0aW9uIHBhcnNlRGF0YVVSTCgnICsgYSArICcpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBleHBlY3QoKCkgPT4gcGFyc2VEYXRhVVJMKGEpKS50aHJvdyhUeXBlRXJyb3IpXG4gICAgICAgIH0pXG5cbiAgICB9KTtcblxuXG59KTsiLCAiaW1wb3J0IHtcbiAgICB2YWxpZGF0ZVByaW1pdGl2ZSxcbiAgICB2YWxpZGF0ZUJvb2xlYW4sXG4gICAgdmFsaWRhdGVTdHJpbmcsXG4gICAgdmFsaWRhdGVPYmplY3QsXG4gICAgdmFsaWRhdGVBcnJheSxcbiAgICB2YWxpZGF0ZUZ1bmN0aW9uLFxuICAgIHZhbGlkYXRlSW50ZWdlcixcbiAgICB2YWxpZGF0ZUluc3RhbmNlLFxuICAgIHZhbGlkYXRlSXRlcmFibGUsXG4gICAgdmFsaWRhdGVTeW1ib2xcbn0gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS90eXBlcy92YWxpZGF0ZS5tanNcIlxuXG5pbXBvcnQge0Jhc2V9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdHlwZXMvYmFzZS5tanNcIlxuaW1wb3J0IHtJRH0gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS90eXBlcy9pZC5tanNcIlxuXG5pbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuXG5kZXNjcmliZSgndmFsaWRhdGUnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBkZXNjcmliZSgnLnZhbGlkYXRlUHJpbWl0aXZlKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWyd0ZXN0MScsIHRydWVdLFxuICAgICAgICAgICAgW3VuZGVmaW5lZCwgdHJ1ZV0sXG4gICAgICAgICAgICBbbnVsbCwgdHJ1ZV0sXG4gICAgICAgICAgICBbKCkgPT4ge1xuICAgICAgICAgICAgfSwgZmFsc2VdLFxuICAgICAgICAgICAgWzIsIHRydWVdLFxuICAgICAgICAgICAgW2ZhbHNlLCB0cnVlXSxcbiAgICAgICAgICAgIFt0cnVlLCB0cnVlXSxcbiAgICAgICAgICAgIFs0LjUsIHRydWVdLFxuICAgICAgICAgICAgW3t9LCBmYWxzZV0sXG4gICAgICAgICAgICBbWzEsIDIsIDNdLCBmYWxzZV0sXG4gICAgICAgICAgICBbU3ltYm9sKFwiZm9vXCIpLCB0cnVlXSxcbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpZiAoYiA9PT0gZmFsc2UpIHtcblxuICAgICAgICAgICAgICAgIGl0KCcudmFsaWRhdGVQcmltaXRpdmUoJyArIHR5cGVvZiBhICsgJykgc2hvdWxkIHRocm93IFR5cGVFeGNlcHRpb24gJyArIGIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KCgpID0+IHZhbGlkYXRlUHJpbWl0aXZlKGEpKS50by50aHJvdyhUeXBlRXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGl0KCcudmFsaWRhdGVQcmltaXRpdmUoJyArIHR5cGVvZiBhICsgJykgc2hvdWxkIG5vdCB0aHJvdyBUeXBlRXhjZXB0aW9uICcgKyBiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdCh2YWxpZGF0ZVByaW1pdGl2ZShhKSkudG8uYmUuZXF1YWwoYSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgfSk7XG5cblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJy52YWxpZGF0ZUludGVnZXIoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBbXG4gICAgICAgICAgICBbJ3Rlc3QxJywgZmFsc2VdLFxuICAgICAgICAgICAgW3VuZGVmaW5lZCwgZmFsc2VdLFxuICAgICAgICAgICAgW251bGwsIGZhbHNlXSxcbiAgICAgICAgICAgIFsoKSA9PiB7XG4gICAgICAgICAgICB9LCBmYWxzZV0sXG4gICAgICAgICAgICBbMiwgdHJ1ZV0sXG4gICAgICAgICAgICBbZmFsc2UsIGZhbHNlXSxcbiAgICAgICAgICAgIFt0cnVlLCBmYWxzZV0sXG4gICAgICAgICAgICBbNC41LCBmYWxzZV0sXG4gICAgICAgICAgICBbe30sIGZhbHNlXSxcbiAgICAgICAgICAgIFtbMSwgMiwgM10sIGZhbHNlXSxcbiAgICAgICAgICAgIFtTeW1ib2woXCJmb29cIiksIGZhbHNlXSxcbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpZiAoYiA9PT0gZmFsc2UpIHtcblxuICAgICAgICAgICAgICAgIGl0KCcudmFsaWRhdGVJbnRlZ2VyKCcgKyB0eXBlb2YgYSArICcpIHNob3VsZCB0aHJvdyBUeXBlRXhjZXB0aW9uICcgKyBiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdCgoKSA9PiB2YWxpZGF0ZUludGVnZXIoYSkpLnRvLnRocm93KFR5cGVFcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaXQoJy52YWxpZGF0ZUludGVnZXIoJyArIHR5cGVvZiBhICsgJykgc2hvdWxkIG5vdCB0aHJvdyBUeXBlRXhjZXB0aW9uICcgKyBiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdCh2YWxpZGF0ZUludGVnZXIoYSkpLnRvLmJlLmVxdWFsKGEpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcbiAgICBcbiAgICBkZXNjcmliZSgnLnZhbGlkYXRlU3ltYm9sKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWyd0ZXN0MScsIGZhbHNlXSxcbiAgICAgICAgICAgIFt1bmRlZmluZWQsIGZhbHNlXSxcbiAgICAgICAgICAgIFtudWxsLCBmYWxzZV0sXG4gICAgICAgICAgICBbKCkgPT4ge1xuICAgICAgICAgICAgfSwgZmFsc2VdLFxuICAgICAgICAgICAgWzIsIGZhbHNlXSxcbiAgICAgICAgICAgIFtmYWxzZSwgZmFsc2VdLFxuICAgICAgICAgICAgW3RydWUsIGZhbHNlXSxcbiAgICAgICAgICAgIFs0LjUsIGZhbHNlXSxcbiAgICAgICAgICAgIFt7fSwgZmFsc2VdLFxuICAgICAgICAgICAgW1sxLCAyLCAzXSwgZmFsc2VdLFxuICAgICAgICAgICAgW1N5bWJvbChcImZvb1wiKSwgdHJ1ZV0sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaWYgKGIgPT09IGZhbHNlKSB7XG5cbiAgICAgICAgICAgICAgICBpdCgnLnZhbGlkYXRlU3ltYm9sKCcgKyB0eXBlb2YgYSArICcpIHNob3VsZCB0aHJvdyBUeXBlRXhjZXB0aW9uICcgKyBiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdCgoKSA9PiB2YWxpZGF0ZVN5bWJvbChhKSkudG8udGhyb3coVHlwZUVycm9yKTtcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpdCgnLnZhbGlkYXRlU3ltYm9sKCcgKyB0eXBlb2YgYSArICcpIHNob3VsZCBub3QgdGhyb3cgVHlwZUV4Y2VwdGlvbiAnICsgYiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QodmFsaWRhdGVTeW1ib2woYSkpLnRvLmJlLmVxdWFsKGEpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCcudmFsaWRhdGVJdGVyYWJsZSgpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIFtcbiAgICAgICAgICAgIFsndGVzdDEnLCB0cnVlXSxcbiAgICAgICAgICAgIFt1bmRlZmluZWQsIGZhbHNlXSxcbiAgICAgICAgICAgIFtudWxsLCBmYWxzZV0sXG4gICAgICAgICAgICBbKCkgPT4ge1xuICAgICAgICAgICAgfSwgZmFsc2VdLFxuICAgICAgICAgICAgWzIsIGZhbHNlXSxcbiAgICAgICAgICAgIFtmYWxzZSwgZmFsc2VdLFxuICAgICAgICAgICAgW3RydWUsIGZhbHNlXSxcbiAgICAgICAgICAgIFs0LjUsIGZhbHNlXSxcbiAgICAgICAgICAgIFt7fSwgZmFsc2VdLFxuICAgICAgICAgICAgW1sxLCAyLCAzXSwgdHJ1ZV0sXG4gICAgICAgICAgICBbU3ltYm9sKFwiZm9vXCIpLCBmYWxzZV0sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaWYgKGIgPT09IGZhbHNlKSB7XG5cbiAgICAgICAgICAgICAgICBpdCgnLnZhbGlkYXRlSXRlcmFibGUoJyArIHR5cGVvZiBhICsgJykgc2hvdWxkIHRocm93IFR5cGVFeGNlcHRpb24gJyArIGIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRlSXRlcmFibGUoYSlcbiAgICAgICAgICAgICAgICAgICAgfSkudG8udGhyb3coVHlwZUVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgO1xuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGl0KCcudmFsaWRhdGVJdGVyYWJsZSgnICsgdHlwZW9mIGEgKyAnKSBzaG91bGQgbm90IHRocm93IFR5cGVFeGNlcHRpb24gJyArIGIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KHZhbGlkYXRlSXRlcmFibGUoYSkpLnRvLmJlLmVxdWFsKGEpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCcudmFsaWRhdGVCb29sZWFuKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWyd0ZXN0MScsIGZhbHNlXSxcbiAgICAgICAgICAgIFt1bmRlZmluZWQsIGZhbHNlXSxcbiAgICAgICAgICAgIFtudWxsLCBmYWxzZV0sXG4gICAgICAgICAgICBbKCkgPT4ge1xuICAgICAgICAgICAgfSwgZmFsc2VdLFxuICAgICAgICAgICAgWzIsIGZhbHNlXSxcbiAgICAgICAgICAgIFtmYWxzZSwgdHJ1ZV0sXG4gICAgICAgICAgICBbdHJ1ZSwgdHJ1ZV0sXG4gICAgICAgICAgICBbNC41LCBmYWxzZV0sXG4gICAgICAgICAgICBbe30sIGZhbHNlXSxcbiAgICAgICAgICAgIFtbMSwgMiwgM10sIGZhbHNlXSxcbiAgICAgICAgICAgIFtTeW1ib2woXCJmb29cIiksIGZhbHNlXSxcbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpZiAoYiA9PT0gZmFsc2UpIHtcblxuICAgICAgICAgICAgICAgIGl0KCcudmFsaWRhdGVCb29sZWFuKCcgKyB0eXBlb2YgYSArICcpIHNob3VsZCB0aHJvdyBUeXBlRXhjZXB0aW9uICcgKyBiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZUJvb2xlYW4oYSlcbiAgICAgICAgICAgICAgICAgICAgfSkudG8udGhyb3coVHlwZUVycm9yKTtcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpdCgnLnZhbGlkYXRlQm9vbGVhbignICsgdHlwZW9mIGEgKyAnKSBzaG91bGQgbm90IHRocm93IFR5cGVFeGNlcHRpb24gJyArIGIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KHZhbGlkYXRlQm9vbGVhbihhKSkudG8uYmUuZXF1YWwoYSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cblxuICAgICAgICB9KTtcblxuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnLnZhbGlkYXRlU3RyaW5nKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWyd0ZXN0MScsIHRydWVdLFxuICAgICAgICAgICAgW3VuZGVmaW5lZCwgZmFsc2VdLFxuICAgICAgICAgICAgW251bGwsIGZhbHNlXSxcbiAgICAgICAgICAgIFsoKSA9PiB7XG4gICAgICAgICAgICB9LCBmYWxzZV0sXG4gICAgICAgICAgICBbMiwgZmFsc2VdLFxuICAgICAgICAgICAgW2ZhbHNlLCBmYWxzZV0sXG4gICAgICAgICAgICBbdHJ1ZSwgZmFsc2VdLFxuICAgICAgICAgICAgWzQuNSwgZmFsc2VdLFxuICAgICAgICAgICAgW3t9LCBmYWxzZV0sXG4gICAgICAgICAgICBbWzEsIDIsIDNdLCBmYWxzZV0sXG4gICAgICAgICAgICBbU3ltYm9sKFwiZm9vXCIpLCBmYWxzZV0sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaWYgKGIgPT09IGZhbHNlKSB7XG5cbiAgICAgICAgICAgICAgICBpdCgnLnZhbGlkYXRlU3RyaW5nKCcgKyB0eXBlb2YgYSArICcpIHNob3VsZCB0aHJvdyBUeXBlRXhjZXB0aW9uICcgKyBiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZVN0cmluZyhhKVxuICAgICAgICAgICAgICAgICAgICB9KS50by50aHJvdyhUeXBlRXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICA7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaXQoJy52YWxpZGF0ZVN0cmluZygnICsgdHlwZW9mIGEgKyAnKSBzaG91bGQgbm90IHRocm93IFR5cGVFeGNlcHRpb24gJyArIGIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KHZhbGlkYXRlU3RyaW5nKGEpKS50by5iZS5lcXVhbChhKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICB9KTtcblxuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnLnZhbGlkYXRlT2JqZWN0KCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWyd0ZXN0MScsIGZhbHNlXSxcbiAgICAgICAgICAgIFt1bmRlZmluZWQsIGZhbHNlXSxcbiAgICAgICAgICAgIFtudWxsLCBmYWxzZV0sXG4gICAgICAgICAgICBbKCkgPT4ge1xuICAgICAgICAgICAgfSwgZmFsc2VdLFxuICAgICAgICAgICAgWzIsIGZhbHNlXSxcbiAgICAgICAgICAgIFtmYWxzZSwgZmFsc2VdLFxuICAgICAgICAgICAgW3RydWUsIGZhbHNlXSxcbiAgICAgICAgICAgIFs0LjUsIGZhbHNlXSxcbiAgICAgICAgICAgIFt7fSwgdHJ1ZV0sXG4gICAgICAgICAgICBbWzEsIDIsIDNdLCBmYWxzZV0sXG4gICAgICAgICAgICBbU3ltYm9sKFwiZm9vXCIpLCBmYWxzZV0sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaWYgKGIgPT09IGZhbHNlKSB7XG5cbiAgICAgICAgICAgICAgICBpdCgnLnZhbGlkYXRlT2JqZWN0KCcgKyB0eXBlb2YgYSArICcpIHNob3VsZCB0aHJvdyBUeXBlRXhjZXB0aW9uICcgKyBiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZU9iamVjdChhKVxuICAgICAgICAgICAgICAgICAgICB9KS50by50aHJvdyhUeXBlRXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICA7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaXQoJy52YWxpZGF0ZU9iamVjdCgnICsgdHlwZW9mIGEgKyAnKSBzaG91bGQgbm90IHRocm93IFR5cGVFeGNlcHRpb24gJyArIGIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KHZhbGlkYXRlT2JqZWN0KGEpKS50by5iZS5lcXVhbChhKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICB9KTtcblxuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnLnZhbGlkYXRlSW5zdGFuY2UoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBbXG4gICAgICAgICAgICBbJ3Rlc3QxJywgT2JqZWN0XSxcbiAgICAgICAgICAgIFt1bmRlZmluZWQsIE9iamVjdF0sXG4gICAgICAgICAgICBbbnVsbCwgT2JqZWN0XSxcbiAgICAgICAgICAgIFsoKSA9PiB7XG4gICAgICAgICAgICB9LCBPYmplY3RdLFxuICAgICAgICAgICAgWzIsIE9iamVjdF0sXG4gICAgICAgICAgICBbZmFsc2UsIE9iamVjdF0sXG4gICAgICAgICAgICBbdHJ1ZSwgT2JqZWN0XSxcbiAgICAgICAgICAgIFs0LjUsIE9iamVjdF0sXG4gICAgICAgICAgICBbe30sIEJhc2VdLFxuICAgICAgICAgICAgW1sxLCAyLCAzXSwgT2JqZWN0XSxcbiAgICAgICAgICAgIFtTeW1ib2woXCJmb29cIiksIE9iamVjdF0sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcblxuXG4gICAgICAgICAgICBpdCgnLnZhbGlkYXRlSW5zdGFuY2UoJyArIHR5cGVvZiBhICsgJykgc2hvdWxkIHRocm93IFR5cGVFeGNlcHRpb24gJyAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBleHBlY3QoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZUluc3RhbmNlKGEsIGIpXG4gICAgICAgICAgICAgICAgfSkudG8udGhyb3coVHlwZUVycm9yKTtcbiAgICAgICAgICAgICAgICA7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICB9KTtcblxuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnLnZhbGlkYXRlSW5zdGFuY2UoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBbXG4gICAgICAgICAgICBbe30sIE9iamVjdCwgdHJ1ZV0sXG4gICAgICAgICAgICBbbmV3IEJhc2UsIEJhc2UsIHRydWVdLFxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGl0KCcudmFsaWRhdGVJbnN0YW5jZSgnICsgdHlwZW9mIGEgKyAnKSBzaG91bGQgbm90IHRocm93IFR5cGVFeGNlcHRpb24gJyAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBleHBlY3QodmFsaWRhdGVJbnN0YW5jZShhLCBiKSkudG8uYmUuZXF1YWwoYSk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICB9KTtcblxuXG4gICAgfSk7XG5cblxuICAgIGRlc2NyaWJlKCcudmFsaWRhdGVBcnJheSgpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIFtcbiAgICAgICAgICAgIFsndGVzdDEnLCBmYWxzZV0sXG4gICAgICAgICAgICBbdW5kZWZpbmVkLCBmYWxzZV0sXG4gICAgICAgICAgICBbbnVsbCwgZmFsc2VdLFxuICAgICAgICAgICAgWygpID0+IHtcbiAgICAgICAgICAgIH0sIGZhbHNlXSxcbiAgICAgICAgICAgIFsyLCBmYWxzZV0sXG4gICAgICAgICAgICBbZmFsc2UsIGZhbHNlXSxcbiAgICAgICAgICAgIFt0cnVlLCBmYWxzZV0sXG4gICAgICAgICAgICBbNC41LCBmYWxzZV0sXG4gICAgICAgICAgICBbe30sIGZhbHNlXSxcbiAgICAgICAgICAgIFtbMSwgMiwgM10sIHRydWVdLFxuICAgICAgICAgICAgW1N5bWJvbChcImZvb1wiKSwgZmFsc2VdLFxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGlmIChiID09PSBmYWxzZSkge1xuXG4gICAgICAgICAgICAgICAgaXQoJy52YWxpZGF0ZUFycmF5KCcgKyB0eXBlb2YgYSArICcpIHNob3VsZCB0aHJvdyBUeXBlRXhjZXB0aW9uICcgKyBiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZUFycmF5KGEpXG4gICAgICAgICAgICAgICAgICAgIH0pLnRvLnRocm93KFR5cGVFcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIDtcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpdCgnLnZhbGlkYXRlQXJyYXkoJyArIHR5cGVvZiBhICsgJykgc2hvdWxkIG5vdCB0aHJvdyBUeXBlRXhjZXB0aW9uICcgKyBiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdCh2YWxpZGF0ZUFycmF5KGEpKS50by5iZS5lcXVhbChhKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cblxuXG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJy52YWxpZGF0ZUZ1bmN0aW9uKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWyd0ZXN0MScsIGZhbHNlXSxcbiAgICAgICAgICAgIFt1bmRlZmluZWQsIGZhbHNlXSxcbiAgICAgICAgICAgIFtudWxsLCBmYWxzZV0sXG4gICAgICAgICAgICBbKCkgPT4ge1xuICAgICAgICAgICAgfSwgdHJ1ZV0sXG4gICAgICAgICAgICBbMiwgZmFsc2VdLFxuICAgICAgICAgICAgW2ZhbHNlLCBmYWxzZV0sXG4gICAgICAgICAgICBbdHJ1ZSwgZmFsc2VdLFxuICAgICAgICAgICAgWzQuNSwgZmFsc2VdLFxuICAgICAgICAgICAgW3t9LCBmYWxzZV0sXG4gICAgICAgICAgICBbWzEsIDIsIDNdLCBmYWxzZV0sXG4gICAgICAgICAgICBbU3ltYm9sKFwiZm9vXCIpLCBmYWxzZV0sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaWYgKGIgPT09IGZhbHNlKSB7XG5cbiAgICAgICAgICAgICAgICBpdCgnLnZhbGlkYXRlRnVuY3Rpb24oJyArIHR5cGVvZiBhICsgJykgc2hvdWxkIHRocm93IFR5cGVFeGNlcHRpb24gJyArIGIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRlRnVuY3Rpb24oYSlcbiAgICAgICAgICAgICAgICAgICAgfSkudG8udGhyb3coVHlwZUVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgO1xuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGl0KCcudmFsaWRhdGVGdW5jdGlvbignICsgdHlwZW9mIGEgKyAnKSBzaG91bGQgbm90IHRocm93IFR5cGVFeGNlcHRpb24gJyArIGIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KHZhbGlkYXRlRnVuY3Rpb24oYSkpLnRvLmJlLmVxdWFsKGEpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG5cbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbn0pO1xuXG4iLCAiaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7VW5pcXVlUXVldWV9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdHlwZXMvdW5pcXVlcXVldWUubWpzXCI7XG5cblxuZGVzY3JpYmUoJ1VuaXF1ZVF1ZXVlJywgZnVuY3Rpb24gKCkge1xuICAgIGxldCBxdWV1ZTtcbiAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAgcXVldWUgPSBuZXcgVW5pcXVlUXVldWU7XG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCdpc0VtcHR5KCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ2ZpcnN0IGl0IHNob3VsZCBlbXB0eScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChxdWV1ZS5pc0VtcHR5KCkpLnRvLmJlLnRydWU7XG4gICAgICAgIH0pO1xuXG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCdhZGQgc2VxdWVuY2UgcGVlayBhbmQgcG9sbCcsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBpdCgncmVzdWx0IGEsYSxhLGInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QocXVldWUuYWRkKHthOiAxfSkpLnRvLmJlLmluc3RhbmNlT2YoVW5pcXVlUXVldWUpO1xuICAgICAgICAgICAgZXhwZWN0KHF1ZXVlLmlzRW1wdHkoKSkudG8uYmUuZmFsc2U7XG4gICAgICAgICAgICBleHBlY3QocXVldWUuYWRkKHthOiAyfSkpLnRvLmJlLmluc3RhbmNlT2YoVW5pcXVlUXVldWUpO1xuICAgICAgICAgICAgZXhwZWN0KHF1ZXVlLmFkZCh7YTogM30pKS50by5iZS5pbnN0YW5jZU9mKFVuaXF1ZVF1ZXVlKTtcbiAgICAgICAgICAgIGV4cGVjdChxdWV1ZS5wZWVrKCkpLnRvLmRlZXAuZXF1YWwoe2E6MX0pO1xuICAgICAgICAgICAgZXhwZWN0KHF1ZXVlLnBlZWsoKSkudG8uZGVlcC5lcXVhbCh7YToxfSk7XG4gICAgICAgICAgICBleHBlY3QocXVldWUucG9sbCgpKS50by5kZWVwLmVxdWFsKHthOjF9KTtcbiAgICAgICAgICAgIGV4cGVjdChxdWV1ZS5wb2xsKCkpLnRvLmRlZXAuZXF1YWwoe2E6Mn0pO1xuICAgICAgICAgICAgZXhwZWN0KHF1ZXVlLmlzRW1wdHkoKSkudG8uYmUuZmFsc2U7XG4gICAgICAgICAgICBleHBlY3QocXVldWUucGVlaygpKS50by5kZWVwLmVxdWFsKHthOjN9KTtcbiAgICAgICAgICAgIGV4cGVjdChxdWV1ZS5wb2xsKCkpLnRvLmRlZXAuZXF1YWwoe2E6M30pO1xuICAgICAgICAgICAgZXhwZWN0KHF1ZXVlLmlzRW1wdHkoKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgfSk7XG5cbiAgICB9KVxuXG4gICAgZGVzY3JpYmUoJ2FkZCBhbmQgY2xlYXInLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBlbXB0eScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChxdWV1ZS5pc0VtcHR5KCkpLnRvLmJlLnRydWU7XG4gICAgICAgICAgICBleHBlY3QocXVldWUuYWRkKHthOiAxfSkpLnRvLmJlLmluc3RhbmNlT2YoVW5pcXVlUXVldWUpO1xuICAgICAgICAgICAgZXhwZWN0KHF1ZXVlLmlzRW1wdHkoKSkudG8uYmUuZmFsc2U7XG4gICAgICAgICAgICBleHBlY3QocXVldWUuY2xlYXIoKSkudG8uYmUuaW5zdGFuY2VPZihVbmlxdWVRdWV1ZSk7XG4gICAgICAgICAgICBleHBlY3QocXVldWUuaXNFbXB0eSgpKS50by5iZS50cnVlO1xuICAgICAgICB9KTtcblxuICAgIH0pXG4gICAgXG4gICAgZGVzY3JpYmUoJ2FkZCBubyBvYmplY3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3InLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QoKCk9PntxdWV1ZS5hZGQoW10pfSkudG8udGhyb3coVHlwZUVycm9yKVxuICAgICAgICAgICAgZXhwZWN0KCgpPT57cXVldWUuYWRkKDEpfSkudG8udGhyb3coVHlwZUVycm9yKVxuICAgICAgICAgICAgZXhwZWN0KCgpPT57cXVldWUuYWRkKHRydWUpfSkudG8udGhyb3coVHlwZUVycm9yKVxuICAgICAgICAgICAgZXhwZWN0KCgpPT57cXVldWUuYWRkKCl9KS50by50aHJvdyhUeXBlRXJyb3IpXG4gICAgICAgICAgICBleHBlY3QoKCk9PntxdWV1ZS5hZGQoU3ltYm9sKFwiMVwiKSl9KS50by50aHJvdyhUeXBlRXJyb3IpXG4gICAgICAgICAgICBleHBlY3QoKCk9PntxdWV1ZS5hZGQoZnVuY3Rpb24oKXt9KX0pLnRvLnRocm93KFR5cGVFcnJvcilcbiAgICAgICAgfSk7XG5cbiAgICB9KVxufSkiLCAiXCJ1c2Ugc3RyaWN0XCI7XG5cbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge0Jhc2V9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdHlwZXMvYmFzZS5tanNcIjtcbmltcG9ydCB7aW5zdGFuY2VTeW1ib2x9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvY29uc3RhbnRzLm1qc1wiO1xuXG5cblxuY2xhc3MgQmFzZURpZmZlcmVudFJlYWxtIGV4dGVuZHMgT2JqZWN0IHtcbiAgICBcblxuICAgIHN0YXRpYyBnZXQgW2luc3RhbmNlU3ltYm9sXSgpIHtcbiAgICAgICAgcmV0dXJuIFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL3R5cGVzL2Jhc2VcIik7XG4gICAgfVxuXG5cbn1cblxuY2xhc3MgU3ViY2xhc3MgZXh0ZW5kcyBCYXNlRGlmZmVyZW50UmVhbG0ge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci90eXBlcy9zdWJjbGFzc1wiKTtcbiAgICB9XG59XG5cbmRlc2NyaWJlKCdCYXNlJywgZnVuY3Rpb24gKCkge1xuXG4gICAgZGVzY3JpYmUoJ25ldyBCYXNlJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdpcyBpbnN0YW5jZSBvZiBCYXNlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KG5ldyBCYXNlKS50by5iZS5pbnN0YW5jZU9mKEJhc2UpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnaXMgaW5zdGFuY2Ugb2YgT2JqZWN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KG5ldyBCYXNlKS50by5iZS5pbnN0YW5jZU9mKE9iamVjdCk7XG4gICAgICAgIH0pO1xuXG4gICAgfSlcbiAgICBcbiAgICBkZXNjcmliZSgnaW5zdGFuY29mJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdpcyBpbnN0YW5jZSBvZiBCYXNlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KG5ldyBCYXNlKS50by5iZS5pbnN0YW5jZU9mKEJhc2UpO1xuICAgICAgICB9KTtcbiAgICAgICAgXG4gICAgICAgIGl0KCdzdWJjbGFzcyBpbnN0YW5jZW9mJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgXG4gICAgICAgICAgICBpZiAobmV3IFN1YmNsYXNzIGluc3RhbmNlb2YgQmFzZSkge1xuICAgICAgICAgICAgICAgIGV4cGVjdCh0cnVlKS50by5iZS50cnVlO1xuICAgICAgICAgICAgfSBlbHNlICB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGZhbHNlKS50by5iZS50cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgXG4gICAgICAgICAgICBcbiAgICAgICAgICAgIFxuICAgICAgICB9KTtcblxuXG4gICAgfSlcblxufSkiLCAiaW1wb3J0IHtcbiAgICBpc1ByaW1pdGl2ZSxcbiAgICBpc0Jvb2xlYW4sXG4gICAgaXNTdHJpbmcsXG4gICAgaXNPYmplY3QsXG4gICAgaXNBcnJheSxcbiAgICBpc0luc3RhbmNlLFxuICAgIGlzRnVuY3Rpb24sXG4gICAgaXNJdGVyYWJsZSxcbiAgICBpc0ludGVnZXIsXG4gICAgaXNTeW1ib2xcbn0gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS90eXBlcy9pcy5tanNcIjtcblxuXG5pbXBvcnQge0lEfSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL2lkLm1qc1wiXG5cbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge2luaXRKU0RPTX0gZnJvbSBcIi4uLy4uL3V0aWwvanNkb20ubWpzXCI7XG5cbmRlc2NyaWJlKCdJcycsIGZ1bmN0aW9uICgpIHtcblxuICAgIGJlZm9yZShmdW5jdGlvbiAoZG9uZSkge1xuXG4gICAgICAgIGxldCBwcm9taXNlcyA9IFtdXG4gICAgICAgIGlmKCFnbG9iYWxUaGlzWydjcnlwdG8nXSkge1xuICAgICAgICAgICAgcHJvbWlzZXMucHVzaChpbXBvcnQoXCJAcGVjdWxpYXIvd2ViY3J5cHRvXCIpLnRoZW4obSA9PiB7XG4gICAgICAgICAgICAgICAgZ2xvYmFsVGhpc1snY3J5cHRvJ10gPSBuZXcgbS5DcnlwdG8oKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH0pKVxuICAgICAgICB9XG5cblxuICAgICAgICBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7XG4gICAgICAgICAgICBkb25lKClcbiAgICAgICAgfSk7XG5cbiAgICB9KTsgICAgXG4gICAgXG4gICAgZGVzY3JpYmUoJy5pc1ByaW1pdGl2ZSgpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIFtcbiAgICAgICAgICAgIFsndGVzdDEnLCB0cnVlXSxcbiAgICAgICAgICAgIFt1bmRlZmluZWQsIHRydWVdLFxuICAgICAgICAgICAgW251bGwsIHRydWVdLFxuICAgICAgICAgICAgWygpID0+IHtcbiAgICAgICAgICAgIH0sIGZhbHNlXSxcbiAgICAgICAgICAgIFsyLCB0cnVlXSxcbiAgICAgICAgICAgIFtwYXJzZUludChcImFcIiksIHRydWVdLFxuICAgICAgICAgICAgW2ZhbHNlLCB0cnVlXSxcbiAgICAgICAgICAgIFt0cnVlLCB0cnVlXSxcbiAgICAgICAgICAgIFs0LjUsIHRydWVdLFxuICAgICAgICAgICAgW3t9LCBmYWxzZV0sXG4gICAgICAgICAgICBbWzEsIDIsIDNdLCBmYWxzZV0sXG4gICAgICAgICAgICBbU3ltYm9sKFwiZm9vXCIpLCB0cnVlXSxcbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpdCgnaXMuaXNQcmltaXRpdmUoJyArIHR5cGVvZiBhICsgJykgc2hvdWxkIHJldHVybiAnICsgYiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGV4cGVjdChpc1ByaW1pdGl2ZShhKSkuaXMuZXF1YWwoYilcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuXG4gICAgfSk7XG4gICAgZGVzY3JpYmUoJy5pc1N5bWJvbCgpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIFtcbiAgICAgICAgICAgIFsndGVzdDEnLCBmYWxzZV0sXG4gICAgICAgICAgICBbdW5kZWZpbmVkLCBmYWxzZV0sXG4gICAgICAgICAgICBbbnVsbCwgZmFsc2VdLFxuICAgICAgICAgICAgWygpID0+IHtcbiAgICAgICAgICAgIH0sIGZhbHNlXSxcbiAgICAgICAgICAgIFsyLCBmYWxzZV0sXG4gICAgICAgICAgICBbcGFyc2VJbnQoXCJhXCIpLCBmYWxzZV0sXG4gICAgICAgICAgICBbZmFsc2UsIGZhbHNlXSxcbiAgICAgICAgICAgIFt0cnVlLCBmYWxzZV0sXG4gICAgICAgICAgICBbNC41LCBmYWxzZV0sXG4gICAgICAgICAgICBbe30sIGZhbHNlXSxcbiAgICAgICAgICAgIFtbMSwgMiwgM10sIGZhbHNlXSxcbiAgICAgICAgICAgIFtTeW1ib2woXCJmb29cIiksIHRydWVdLFxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGl0KCdpcy5pc1N5bWJvbCgnICsgdHlwZW9mIGEgKyAnKSBzaG91bGQgcmV0dXJuICcgKyBiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGlzU3ltYm9sKGEpKS5pcy5lcXVhbChiKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCcuaXNJbnRlZ2VyKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWyd0ZXN0MScsIGZhbHNlXSxcbiAgICAgICAgICAgIFt1bmRlZmluZWQsIGZhbHNlXSxcbiAgICAgICAgICAgIFtudWxsLCBmYWxzZV0sXG4gICAgICAgICAgICBbKCkgPT4ge1xuICAgICAgICAgICAgfSwgZmFsc2VdLFxuICAgICAgICAgICAgWzIsIHRydWVdLFxuICAgICAgICAgICAgW3BhcnNlSW50KFwiYVwiKSwgZmFsc2VdLFxuICAgICAgICAgICAgW2ZhbHNlLCBmYWxzZV0sXG4gICAgICAgICAgICBbdHJ1ZSwgZmFsc2VdLFxuICAgICAgICAgICAgWzQuNSwgZmFsc2VdLFxuICAgICAgICAgICAgW3t9LCBmYWxzZV0sXG4gICAgICAgICAgICBbWzEsIDIsIDNdLCBmYWxzZV0sXG4gICAgICAgICAgICBbU3ltYm9sKFwiZm9vXCIpLCBmYWxzZV0sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ2lzLmlzSW50ZWdlcignICsgdHlwZW9mIGEgKyAnKSBzaG91bGQgcmV0dXJuICcgKyBiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGlzSW50ZWdlcihhKSkuaXMuZXF1YWwoYilcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnLmlzSXRlcmFibGUoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBbXG4gICAgICAgICAgICBbJ3Rlc3QxJywgdHJ1ZV0sXG4gICAgICAgICAgICBbdW5kZWZpbmVkLCBmYWxzZV0sXG4gICAgICAgICAgICBbbnVsbCwgZmFsc2VdLFxuICAgICAgICAgICAgWygpID0+IHtcbiAgICAgICAgICAgIH0sIGZhbHNlXSxcbiAgICAgICAgICAgIFtwYXJzZUludChcImFcIiksIGZhbHNlXSxcbiAgICAgICAgICAgIFsyLCBmYWxzZV0sXG4gICAgICAgICAgICBbZmFsc2UsIGZhbHNlXSxcbiAgICAgICAgICAgIFt0cnVlLCBmYWxzZV0sXG4gICAgICAgICAgICBbNC41LCBmYWxzZV0sXG4gICAgICAgICAgICBbe30sIGZhbHNlXSxcbiAgICAgICAgICAgIFtbMSwgMiwgM10sIHRydWVdLFxuICAgICAgICAgICAgW1N5bWJvbChcImZvb1wiKSwgZmFsc2VdLFxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGl0KCdpcy5pc0l0ZXJhYmxlKCcgKyB0eXBlb2YgYSArICcpIHNob3VsZCByZXR1cm4gJyArIGIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBleHBlY3QoaXNJdGVyYWJsZShhKSkuaXMuZXF1YWwoYilcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnLmlzQm9vbGVhbigpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIFtcbiAgICAgICAgICAgIFsndGVzdDEnLCBmYWxzZV0sXG4gICAgICAgICAgICBbdW5kZWZpbmVkLCBmYWxzZV0sXG4gICAgICAgICAgICBbbnVsbCwgZmFsc2VdLFxuICAgICAgICAgICAgWygpID0+IHtcbiAgICAgICAgICAgIH0sIGZhbHNlXSxcbiAgICAgICAgICAgIFsyLCBmYWxzZV0sXG4gICAgICAgICAgICBbZmFsc2UsIHRydWVdLFxuICAgICAgICAgICAgW3BhcnNlSW50KFwiYVwiKSwgZmFsc2VdLFxuICAgICAgICAgICAgW3RydWUsIHRydWVdLFxuICAgICAgICAgICAgWzQuNSwgZmFsc2VdLFxuICAgICAgICAgICAgW3t9LCBmYWxzZV0sXG4gICAgICAgICAgICBbWzEsIDIsIDNdLCBmYWxzZV0sXG4gICAgICAgICAgICBbU3ltYm9sKFwiZm9vXCIpLCBmYWxzZV0sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ2lzLmlzQm9vbGVhbignICsgdHlwZW9mIGEgKyAnKSBzaG91bGQgcmV0dXJuICcgKyBiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGlzQm9vbGVhbihhKSkuaXMuZXF1YWwoYilcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnLmlzU3RyaW5nKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWyd0ZXN0MScsIHRydWVdLFxuICAgICAgICAgICAgW3VuZGVmaW5lZCwgZmFsc2VdLFxuICAgICAgICAgICAgW251bGwsIGZhbHNlXSxcbiAgICAgICAgICAgIFsoKSA9PiB7XG4gICAgICAgICAgICB9LCBmYWxzZV0sXG4gICAgICAgICAgICBbMiwgZmFsc2VdLFxuICAgICAgICAgICAgW2ZhbHNlLCBmYWxzZV0sXG4gICAgICAgICAgICBbcGFyc2VJbnQoXCJhXCIpLCBmYWxzZV0sXG4gICAgICAgICAgICBbdHJ1ZSwgZmFsc2VdLFxuICAgICAgICAgICAgWzQuNSwgZmFsc2VdLFxuICAgICAgICAgICAgW3t9LCBmYWxzZV0sXG4gICAgICAgICAgICBbWzEsIDIsIDNdLCBmYWxzZV0sXG4gICAgICAgICAgICBbU3ltYm9sKFwiZm9vXCIpLCBmYWxzZV0sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ2lzLmlzU3RyaW5nKCcgKyB0eXBlb2YgYSArICcpIHNob3VsZCByZXR1cm4gJyArIGIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBleHBlY3QoaXNTdHJpbmcoYSkpLmlzLmVxdWFsKGIpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJy5pc0luc3RhbmNlKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgW25ldyBJRCgpLCBJRCwgIHRydWVdLFxuICAgICAgICAgICAgW25ldyBJRCgpLCAoKT0+e30sICBmYWxzZV0sXG4gICAgICAgICAgICBbJ3Rlc3QxJywgdW5kZWZpbmVkLCBmYWxzZV0sXG4gICAgICAgICAgICBbdW5kZWZpbmVkLCB1bmRlZmluZWQsIGZhbHNlXSxcbiAgICAgICAgICAgIFtudWxsLCB1bmRlZmluZWQsIGZhbHNlXSxcbiAgICAgICAgICAgIFsoKSA9PiB7XG4gICAgICAgICAgICB9LCB1bmRlZmluZWQsIGZhbHNlXSxcbiAgICAgICAgICAgIFsyLCB1bmRlZmluZWQsIGZhbHNlXSxcbiAgICAgICAgICAgIFtmYWxzZSwgdW5kZWZpbmVkLCBmYWxzZV0sXG4gICAgICAgICAgICBbcGFyc2VJbnQoXCJhXCIpLCB1bmRlZmluZWQsIGZhbHNlXSxcbiAgICAgICAgICAgIFt0cnVlLCB1bmRlZmluZWQsIGZhbHNlXSxcbiAgICAgICAgICAgIFs0LjUsIHVuZGVmaW5lZCwgZmFsc2VdLFxuICAgICAgICAgICAgW3t9LCB1bmRlZmluZWQsIGZhbHNlXSxcbiAgICAgICAgICAgIFtbMSwgMiwgM10sIHVuZGVmaW5lZCwgZmFsc2VdLFxuICAgICAgICAgICAgW1N5bWJvbChcImZvb1wiKSwgdW5kZWZpbmVkLCBmYWxzZV0sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBjID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGl0KCdpcy5pc0luc3RhbmNlKCcgKyBKU09OLnN0cmluZ2lmeShhKSArICcpIHNob3VsZCByZXR1cm4gJyArIHR5cGVvZiBiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGlzSW5zdGFuY2UoYSwgYikpLmlzLmVxdWFsKGMpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gICAgXG4gICAgXG4gICAgZGVzY3JpYmUoJy5pc09iamVjdCgpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIFtcbiAgICAgICAgICAgIFsndGVzdDEnLCBmYWxzZV0sXG4gICAgICAgICAgICBbdW5kZWZpbmVkLCBmYWxzZV0sXG4gICAgICAgICAgICBbbnVsbCwgZmFsc2VdLFxuICAgICAgICAgICAgWygpID0+IHtcbiAgICAgICAgICAgIH0sIGZhbHNlXSxcbiAgICAgICAgICAgIFsyLCBmYWxzZV0sXG4gICAgICAgICAgICBbZmFsc2UsIGZhbHNlXSxcbiAgICAgICAgICAgIFtwYXJzZUludChcImFcIiksIGZhbHNlXSxcbiAgICAgICAgICAgIFt0cnVlLCBmYWxzZV0sXG4gICAgICAgICAgICBbNC41LCBmYWxzZV0sXG4gICAgICAgICAgICBbe30sIHRydWVdLFxuICAgICAgICAgICAgW1sxLCAyLCAzXSwgZmFsc2VdLFxuICAgICAgICAgICAgW1N5bWJvbChcImZvb1wiKSwgZmFsc2VdLFxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGl0KCdpcy5pc09iamVjdCgnICsgSlNPTi5zdHJpbmdpZnkoYSkgKyAnKSBzaG91bGQgcmV0dXJuICcgKyBiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGlzT2JqZWN0KGEpKS5pcy5lcXVhbChiKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxuXG4gICAgZGVzY3JpYmUoJy5pc0FycmF5KCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWyd0ZXN0MScsIGZhbHNlXSxcbiAgICAgICAgICAgIFt1bmRlZmluZWQsIGZhbHNlXSxcbiAgICAgICAgICAgIFtudWxsLCBmYWxzZV0sXG4gICAgICAgICAgICBbKCkgPT4ge1xuICAgICAgICAgICAgfSwgZmFsc2VdLFxuICAgICAgICAgICAgWzIsIGZhbHNlXSxcbiAgICAgICAgICAgIFtmYWxzZSwgZmFsc2VdLFxuICAgICAgICAgICAgW3BhcnNlSW50KFwiYVwiKSwgZmFsc2VdLFxuICAgICAgICAgICAgW3RydWUsIGZhbHNlXSxcbiAgICAgICAgICAgIFs0LjUsIGZhbHNlXSxcbiAgICAgICAgICAgIFt7fSwgZmFsc2VdLFxuICAgICAgICAgICAgW1sxLCAyLCAzXSwgdHJ1ZV0sXG4gICAgICAgICAgICBbU3ltYm9sKFwiZm9vXCIpLCBmYWxzZV0sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ2lzLmlzQXJyYXkoJyArIHR5cGVvZiBhICsgJykgc2hvdWxkIHJldHVybiAnICsgYiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGV4cGVjdChpc0FycmF5KGEpKS5pcy5lcXVhbChiKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJy5pc0Z1bmN0aW9uKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWyd0ZXN0MScsIGZhbHNlXSxcbiAgICAgICAgICAgIFt1bmRlZmluZWQsIGZhbHNlXSxcbiAgICAgICAgICAgIFtudWxsLCBmYWxzZV0sXG4gICAgICAgICAgICBbKCkgPT4ge1xuICAgICAgICAgICAgfSwgdHJ1ZV0sXG4gICAgICAgICAgICBbMiwgZmFsc2VdLFxuICAgICAgICAgICAgW2ZhbHNlLCBmYWxzZV0sXG4gICAgICAgICAgICBbcGFyc2VJbnQoXCJhXCIpLCBmYWxzZV0sXG4gICAgICAgICAgICBbdHJ1ZSwgZmFsc2VdLFxuICAgICAgICAgICAgWzQuNSwgZmFsc2VdLFxuICAgICAgICAgICAgW3t9LCBmYWxzZV0sXG4gICAgICAgICAgICBbWzEsIDIsIDNdLCBmYWxzZV0sXG4gICAgICAgICAgICBbU3ltYm9sKFwiZm9vXCIpLCBmYWxzZV0sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ2lzLmlzRnVuY3Rpb24oJyArIHR5cGVvZiBhICsgJykgc2hvdWxkIHJldHVybiAnICsgYiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGV4cGVjdChpc0Z1bmN0aW9uKGEpKS5pcy5lcXVhbChiKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG59KTtcblxuIiwgImltcG9ydCB7SUR9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdHlwZXMvaWQubWpzXCI7XG5pbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuaW1wb3J0IHtpbml0SlNET019IGZyb20gXCIuLi8uLi91dGlsL2pzZG9tLm1qc1wiO1xuXG5kZXNjcmliZSgnSUQnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBiZWZvcmUoZnVuY3Rpb24gKGRvbmUpIHtcblxuICAgICAgICBsZXQgcHJvbWlzZXMgPSBbXVxuICAgICAgICBpZighZ2xvYmFsVGhpc1snY3J5cHRvJ10pIHtcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2goaW1wb3J0KFwiQHBlY3VsaWFyL3dlYmNyeXB0b1wiKS50aGVuKG0gPT4ge1xuICAgICAgICAgICAgICAgIGdsb2JhbFRoaXNbJ2NyeXB0byddID0gbmV3IG0uQ3J5cHRvKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9KSlcbiAgICAgICAgfVxuXG5cbiAgICAgICAgUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgZG9uZSgpXG4gICAgICAgIH0pO1xuXG4gICAgfSk7ICAgIFxuICAgIFxuICAgIGRlc2NyaWJlKCcudG9TdHJpbmcoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbGV0IGlkID0gbmV3IElEKClcbiAgICAgICAgbGV0IHJlc3VsdCA9IGlkLnRvU3RyaW5nKCk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gYSBzdHJpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QocmVzdWx0KS5pcy5hKCdzdHJpbmcnKVxuICAgICAgICB9KTtcbiAgICAgICAgXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGEgc3RyaW5nJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KG5ldyBJRCgndGV4dDE0MjVpZCcpLnRvU3RyaW5nKCkpLmlzLmVxdWFsKCd0ZXh0MTQyNWlkMScpXG4gICAgICAgICAgICBleHBlY3QobmV3IElEKCd0ZXh0MTQyNWlkJykudG9TdHJpbmcoKSkuaXMuZXF1YWwoJ3RleHQxNDI1aWQyJylcbiAgICAgICAgICAgIGV4cGVjdChuZXcgSUQoJ3RleHQxNDI1aWQnKS50b1N0cmluZygpKS5pcy5lcXVhbCgndGV4dDE0MjVpZDMnKVxuICAgICAgICB9KTtcblxuICAgIH0pO1xuXG59KTtcblxuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgaXNPYmplY3QgfSBmcm9tIFwiLi4vdHlwZXMvaXMubWpzXCI7XG5pbXBvcnQgeyBBYnN0cmFjdENvbnN0cmFpbnQgfSBmcm9tIFwiLi9hYnN0cmFjdC5tanNcIjtcbmltcG9ydCB7IGluc3RhbmNlU3ltYm9sIH0gZnJvbSBcIi4uL2NvbnN0YW50cy5tanNcIjtcbmV4cG9ydCB7IElzT2JqZWN0IH07XG5cbi8qKlxuICogQ29uc3RyYWludHMgYXJlIHVzZWQgdG8gZGVmaW5lIGNvbmRpdGlvbnMgdGhhdCBtdXN0IGJlIG1ldCBieSB0aGUgdmFsdWUgb2YgYSB2YXJpYWJsZS5cbiAqXG4gKiBUaGUgdW5pZm9ybSBBUEkgb2YgdGhlIGNvbnN0cmFpbnRzIGFsbG93cyBjaGFpbnMgdG8gYmUgZm9ybWVkLlxuICpcbiAqIEBleHRlcm5hbEV4YW1wbGUgLi4vLi4vZXhhbXBsZS9jb25zdHJhaW50cy9pc29iamVjdC5tanNcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMy4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuQ29uc3RyYWludHNcbiAqIEBzdW1tYXJ5IEEgY29uc3RyYWludCB0byBjaGVjayBpZiBhIHZhbHVlIGlzIGFuIG9iamVjdFxuICovXG5jbGFzcyBJc09iamVjdCBleHRlbmRzIEFic3RyYWN0Q29uc3RyYWludCB7XG4gICAgLyoqXG4gICAgICogdGhpcyBtZXRob2QgcmV0dXJuIGEgcHJvbWlzZSBjb250YWluaW5nIHRoZSByZXN1bHQgb2YgdGhlIGNoZWNrLlxuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZVxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlfVxuICAgICAqL1xuICAgIGlzVmFsaWQodmFsdWUpIHtcbiAgICAgICAgaWYgKGlzT2JqZWN0KHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh2YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QodmFsdWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgYGluc3RhbmNlb2ZgIG9wZXJhdG9yLlxuICAgICAqIEByZXR1cm5zIHtzeW1ib2x9XG4gICAgICogQHNpbmNlIDIuMS4wXG4gICAgICovXG4gICAgc3RhdGljIGdldCBbaW5zdGFuY2VTeW1ib2xdKCkge1xuICAgICAgICByZXR1cm4gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvY29uc3RyYWludC9pcy1vYmplY3RcIik7XG4gICAgfVxufVxuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgQmFzZSB9IGZyb20gXCIuLi90eXBlcy9iYXNlLm1qc1wiO1xuaW1wb3J0IHsgaW5zdGFuY2VTeW1ib2wgfSBmcm9tIFwiLi4vY29uc3RhbnRzLm1qc1wiO1xuXG5leHBvcnQgeyBBYnN0cmFjdENvbnN0cmFpbnQgfTtcblxuLyoqXG4gKiBDb25zdHJhaW50cyBhcmUgdXNlZCB0byBkZWZpbmUgY29uZGl0aW9ucyB0aGF0IG11c3QgYmUgbWV0IGJ5IHRoZSB2YWx1ZSBvZiBhIHZhcmlhYmxlLlxuICpcbiAqIFRoZSB1bmlmb3JtIEFQSSBvZiB0aGUgY29uc3RyYWludHMgYWxsb3dzIGNoYWlucyB0byBiZSBmb3JtZWQuXG4gKlxuICogVGhlIGFic3RyYWN0IGNvbnN0cmFpbnQgZGVmaW5lcyB0aGUgYXBpIGZvciBhbGwgY29uc3RyYWludHMuIG1haW5seSB0aGUgbWV0aG9kIGlzVmFsaWQoKSBpcyBkZWZpbmVkLlxuICpcbiAqIERlcml2ZWQgY2xhc3NlcyBtdXN0IGltcGxlbWVudCB0aGUgbWV0aG9kIGlzVmFsaWQoKS5cbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjMuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkNvbnN0cmFpbnRzXG4gKiBAc3VtbWFyeSBUaGUgYWJzdHJhY3QgY29uc3RyYWludFxuICovXG5jbGFzcyBBYnN0cmFjdENvbnN0cmFpbnQgZXh0ZW5kcyBCYXNlIHtcbiAgICAvKipcbiAgICAgKlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHRoaXMgbWV0aG9kIG11c3QgcmV0dXJuIGEgcHJvbWlzZSBjb250YWluaW5nIHRoZSByZXN1bHQgb2YgdGhlIGNoZWNrLlxuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZVxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlfVxuICAgICAqL1xuICAgIGlzVmFsaWQodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGBpbnN0YW5jZW9mYCBvcGVyYXRvci5cbiAgICAgKiBAcmV0dXJucyB7c3ltYm9sfVxuICAgICAqIEBzaW5jZSAyLjEuMFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgW2luc3RhbmNlU3ltYm9sXSgpIHtcbiAgICAgICAgcmV0dXJuIFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL2NvbnN0cmFpbnRzL2Fic3RyYWN0LWNvbnN0cmFpbnRcIik7XG4gICAgfVxufVxuIiwgImltcG9ydCB7SXNPYmplY3R9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvY29uc3RyYWludHMvaXNvYmplY3QubWpzXCI7XG5pbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuXG5kZXNjcmliZSgnSXNPYmplY3QnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBkZXNjcmliZSgnLmlzVmFsaWQoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbGV0IGNvbnN0cmFpbnQgPSBuZXcgSXNPYmplY3QoKVxuXG4gICAgICAgIGl0KCdzaG91bGQgcmVzb2x2ZSBwcm9taXNlJywgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgICAgIGNvbnN0cmFpbnQuaXNWYWxpZCh7fSkudGhlbihyID0+IHtcbiAgICAgICAgICAgICAgICBleHBlY3QocikuaXMuYSgnb2JqZWN0Jyk7XG4gICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgfSkuY2F0Y2goZSA9PiB7XG4gICAgICAgICAgICAgICAgZG9uZShuZXcgRXJyb3IoXCJzaG91bGQgbm90IHJlYWNoZWQ6IFwiICsgZSkpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgfSk7XG5cbiAgICB9KTtcblxufSk7XG5cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IEFic3RyYWN0Q29uc3RyYWludCB9IGZyb20gXCIuL2Fic3RyYWN0Lm1qc1wiO1xuaW1wb3J0IHsgaW5zdGFuY2VTeW1ib2wgfSBmcm9tIFwiLi4vY29uc3RhbnRzLm1qc1wiO1xuZXhwb3J0IHsgSW52YWxpZCB9O1xuXG4vKipcbiAqIENvbnN0cmFpbnRzIGFyZSB1c2VkIHRvIGRlZmluZSBjb25kaXRpb25zIHRoYXQgbXVzdCBiZSBtZXQgYnkgdGhlIHZhbHVlIG9mIGEgdmFyaWFibGUuXG4gKlxuICogVGhlIHVuaWZvcm0gQVBJIG9mIHRoZSBjb25zdHJhaW50cyBhbGxvd3MgY2hhaW5zIHRvIGJlIGZvcm1lZC5cbiAqXG4gKiBUaGUgaW52YWxpZCBjb25zdHJhaW50IGFsbG93cyBhbiBhbHdheXMgaW52YWxpZCBxdWVyeSB0byBiZSBwZXJmb3JtZWQuIHRoaXMgY29uc3RyYWludCBpcyBtYWlubHkgaW50ZW5kZWQgZm9yIHRlc3RpbmcuXG4gKlxuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL2NvbnN0cmFpbnRzL2ludmFsaWQubWpzXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjMuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkNvbnN0cmFpbnRzXG4gKiBAc3VtbWFyeSBBIGNvbnN0cmFpbnQgdGhhdCBhbHdheXMgaW52YWxpZFxuICovXG5jbGFzcyBJbnZhbGlkIGV4dGVuZHMgQWJzdHJhY3RDb25zdHJhaW50IHtcbiAgICAvKipcbiAgICAgKiB0aGlzIG1ldGhvZCByZXR1cm4gYSByZWplY3RlZCBwcm9taXNlXG4gICAgICpcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlXG4gICAgICogQHJldHVybnMge1Byb21pc2V9XG4gICAgICovXG4gICAgaXNWYWxpZCh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QodmFsdWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgYGluc3RhbmNlb2ZgIG9wZXJhdG9yLlxuICAgICAqIEByZXR1cm5zIHtzeW1ib2x9XG4gICAgICogQHNpbmNlIDIuMS4wXG4gICAgICovXG4gICAgc3RhdGljIGdldCBbaW5zdGFuY2VTeW1ib2xdKCkge1xuICAgICAgICByZXR1cm4gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvY29uc3RyYWludHMvaW52YWxpZFwiKTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHtJbnZhbGlkfSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2NvbnN0cmFpbnRzL2ludmFsaWQubWpzXCI7XG5pbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuXG5kZXNjcmliZSgnSW52YWxpZCcsIGZ1bmN0aW9uICgpIHtcblxuICAgIGRlc2NyaWJlKCcuaXNWYWxpZCgpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgaXN2YWxpZCA9IG5ldyBJbnZhbGlkKClcblxuICAgICAgICBpdCgnc2hvdWxkIHJlc29sdmUgcHJvbWlzZScsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICBpc3ZhbGlkLmlzVmFsaWQoKS5jYXRjaChlID0+IHtcbiAgICAgICAgICAgICAgICBleHBlY3QoZSkudG8uYmUudW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgfSk7XG5cbiAgICB9KTtcblxufSk7XG5cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IEFic3RyYWN0Q29uc3RyYWludCB9IGZyb20gXCIuL2Fic3RyYWN0Lm1qc1wiO1xuaW1wb3J0IHsgaW5zdGFuY2VTeW1ib2wgfSBmcm9tIFwiLi4vY29uc3RhbnRzLm1qc1wiO1xuZXhwb3J0IHsgVmFsaWQgfTtcblxuLyoqXG4gKiBDb25zdHJhaW50cyBhcmUgdXNlZCB0byBkZWZpbmUgY29uZGl0aW9ucyB0aGF0IG11c3QgYmUgbWV0IGJ5IHRoZSB2YWx1ZSBvZiBhIHZhcmlhYmxlLlxuICpcbiAqIFRoZSB1bmlmb3JtIEFQSSBvZiB0aGUgY29uc3RyYWludHMgYWxsb3dzIGNoYWlucyB0byBiZSBmb3JtZWQuXG4gKlxuICogVGhlIHZhbGlkIGNvbnN0cmFpbnQgYWxsb3dzIGFuIGFsd2F5cyB2YWxpZCBxdWVyeSB0byBiZSBwZXJmb3JtZWQuIHRoaXMgY29uc3RyYWludCBpcyBtYWlubHkgaW50ZW5kZWQgZm9yIHRlc3RpbmcuXG4gKlxuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL2NvbnN0cmFpbnRzL3ZhbGlkLm1qc1xuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4zLjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5Db25zdHJhaW50c1xuICogQHN1bW1hcnkgQSBjb25zdHJhaW50IHRoYXQgYWx3YXlzIHZhbGlkXG4gKi9cbmNsYXNzIFZhbGlkIGV4dGVuZHMgQWJzdHJhY3RDb25zdHJhaW50IHtcbiAgICAvKipcbiAgICAgKiB0aGlzIG1ldGhvZCByZXR1cm4gYSBwcm9taXNlIGNvbnRhaW5pbmcgdGhlIHJlc3VsdCBvZiB0aGUgY2hlY2suXG4gICAgICpcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlXG4gICAgICogQHJldHVybnMge1Byb21pc2V9XG4gICAgICovXG4gICAgaXNWYWxpZCh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGBpbnN0YW5jZW9mYCBvcGVyYXRvci5cbiAgICAgKiBAcmV0dXJucyB7c3ltYm9sfVxuICAgICAqIEBzaW5jZSAyLjEuMFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgW2luc3RhbmNlU3ltYm9sXSgpIHtcbiAgICAgICAgcmV0dXJuIFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL2NvbnN0cmFpbnRzL3ZhbGlkXCIpO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IEFic3RyYWN0Q29uc3RyYWludCB9IGZyb20gXCIuL2Fic3RyYWN0Lm1qc1wiO1xuaW1wb3J0IHsgaW5zdGFuY2VTeW1ib2wgfSBmcm9tIFwiLi4vY29uc3RhbnRzLm1qc1wiO1xuZXhwb3J0IHsgQWJzdHJhY3RPcGVyYXRvciB9O1xuXG4vKipcbiAqIENvbnN0cmFpbnRzIGFyZSB1c2VkIHRvIGRlZmluZSBjb25kaXRpb25zIHRoYXQgbXVzdCBiZSBtZXQgYnkgdGhlIHZhbHVlIG9mIGEgdmFyaWFibGUuXG4gKlxuICogVGhlIHVuaWZvcm0gQVBJIG9mIHRoZSBjb25zdHJhaW50cyBhbGxvd3MgY2hhaW5zIHRvIGJlIGZvcm1lZC5cbiAqXG4gKiBPcGVyYXRvcnMgYWxsb3cgeW91IHRvIGxpbmsgY29uc3RyYWludHMgdG9nZXRoZXIuIGZvciBleGFtcGxlLCB5b3UgY2FuIGNoZWNrIHdoZXRoZXIgYSB2YWx1ZSBpc1xuICogYW4gb2JqZWN0IG9yIGFuIGFycmF5LiBlYWNoIG9wZXJhdG9yIGhhcyB0d28gb3BlcmFuZHMgdGhhdCBhcmUgbGlua2VkIHRvZ2V0aGVyLlxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMy4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuQ29uc3RyYWludHNcbiAqIEBzdW1tYXJ5IFRoZSBhYnN0cmFjdCBvcGVyYXRvciBjb25zdHJhaW50XG4gKi9cbmNsYXNzIEFic3RyYWN0T3BlcmF0b3IgZXh0ZW5kcyBBYnN0cmFjdENvbnN0cmFpbnQge1xuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtBYnN0cmFjdENvbnN0cmFpbnR9IG9wZXJhbnRBXG4gICAgICogQHBhcmFtIHtBYnN0cmFjdENvbnN0cmFpbnR9IG9wZXJhbnRCXG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSBcInBhcmFtZXRlcnMgbXVzdCBiZSBmcm9tIHR5cGUgQWJzdHJhY3RDb25zdHJhaW50XCJcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihvcGVyYW50QSwgb3BlcmFudEIpIHtcbiAgICAgICAgc3VwZXIoKTtcblxuICAgICAgICBpZiAoIShvcGVyYW50QSBpbnN0YW5jZW9mIEFic3RyYWN0Q29uc3RyYWludCAmJiBvcGVyYW50QiBpbnN0YW5jZW9mIEFic3RyYWN0Q29uc3RyYWludCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJwYXJhbWV0ZXJzIG11c3QgYmUgZnJvbSB0eXBlIEFic3RyYWN0Q29uc3RyYWludFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMub3BlcmFudEEgPSBvcGVyYW50QTtcbiAgICAgICAgdGhpcy5vcGVyYW50QiA9IG9wZXJhbnRCO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgYGluc3RhbmNlb2ZgIG9wZXJhdG9yLlxuICAgICAqIEByZXR1cm5zIHtzeW1ib2x9XG4gICAgICogQHNpbmNlIDIuMS4wXG4gICAgICovXG4gICAgc3RhdGljIGdldCBbaW5zdGFuY2VTeW1ib2xdKCkge1xuICAgICAgICByZXR1cm4gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvY29uc3RyYWludHMvYWJzdHJhY3Qtb3BlcmF0b3JcIik7XG4gICAgfVxufVxuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgQWJzdHJhY3RPcGVyYXRvciB9IGZyb20gXCIuL2Fic3RyYWN0b3BlcmF0b3IubWpzXCI7XG5pbXBvcnQgeyBpbnN0YW5jZVN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5leHBvcnQgeyBBbmRPcGVyYXRvciB9O1xuXG4vKipcbiAqIENvbnN0cmFpbnRzIGFyZSB1c2VkIHRvIGRlZmluZSBjb25kaXRpb25zIHRoYXQgbXVzdCBiZSBtZXQgYnkgdGhlIHZhbHVlIG9mIGEgdmFyaWFibGUuXG4gKlxuICogVGhlIHVuaWZvcm0gQVBJIG9mIHRoZSBjb25zdHJhaW50cyBhbGxvd3MgY2hhaW5zIHRvIGJlIGZvcm1lZC5cbiAqXG4gKiBUaGUgQW5kT3BlcmF0b3IgaXMgdXNlZCB0byBsaW5rIHNldmVyYWwgY29uc3RyYWludHMuIFRoZSBjb25zdHJhaW50IGlzIGZ1bGZpbGxlZCBpZiBhbGwgY29uc3RyYWludHMgb2YgdGhlIG9wZXJhdG9ycyBhcmUgZnVsZmlsbGVkLlxuICpcbiAqIEBleHRlcm5hbEV4YW1wbGUgLi4vLi4vZXhhbXBsZS9jb25zdHJhaW50cy9hbmRvcGVyYXRvci5tanNcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMy4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuQ29uc3RyYWludHNcbiAqIEBzdW1tYXJ5IEEgYW5kIG9wZXJhdG9yIGNvbnN0cmFpbnRcbiAqL1xuY2xhc3MgQW5kT3BlcmF0b3IgZXh0ZW5kcyBBYnN0cmFjdE9wZXJhdG9yIHtcbiAgICAvKipcbiAgICAgKiB0aGlzIG1ldGhvZCByZXR1cm4gYSBwcm9taXNlIGNvbnRhaW5pbmcgdGhlIHJlc3VsdCBvZiB0aGUgY2hlY2suXG4gICAgICpcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlXG4gICAgICogQHJldHVybnMge1Byb21pc2V9XG4gICAgICovXG4gICAgaXNWYWxpZCh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoW3RoaXMub3BlcmFudEEuaXNWYWxpZCh2YWx1ZSksIHRoaXMub3BlcmFudEIuaXNWYWxpZCh2YWx1ZSldKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGBpbnN0YW5jZW9mYCBvcGVyYXRvci5cbiAgICAgKiBAcmV0dXJucyB7c3ltYm9sfVxuICAgICAqIEBzaW5jZSAyLjEuMFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgW2luc3RhbmNlU3ltYm9sXSgpIHtcbiAgICAgICAgcmV0dXJuIFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL2NvbnN0cmFpbnRzL2FuZC1vcGVyYXRvclwiKTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHtWYWxpZH0gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9jb25zdHJhaW50cy92YWxpZC5tanNcIjtcbmltcG9ydCB7SW52YWxpZH0gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9jb25zdHJhaW50cy9pbnZhbGlkLm1qc1wiO1xuaW1wb3J0IHtBbmRPcGVyYXRvcn0gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9jb25zdHJhaW50cy9hbmRvcGVyYXRvci5tanNcIjtcblxuZGVzY3JpYmUoJ0FuZE9wZXJhdG9yJywgZnVuY3Rpb24gKCkge1xuXG4gICAgZGVzY3JpYmUoJy5pc1ZhbGlkKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgW25ldyBWYWxpZCgpLCBuZXcgVmFsaWQoKSwgdHJ1ZV0sXG4gICAgICAgICAgICBbbmV3IFZhbGlkKCksIG5ldyBJbnZhbGlkKCksIGZhbHNlXSxcbiAgICAgICAgICAgIFtuZXcgSW52YWxpZCgpLCBuZXcgVmFsaWQoKSwgZmFsc2VdLFxuICAgICAgICAgICAgW25ldyBJbnZhbGlkKCksIG5ldyBJbnZhbGlkKCksIGZhbHNlXVxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYyA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpdCgnY29uc3RyYWludC5pc1ZhbGlkKCkgc2hvdWxkIHJldHVybiAnICsgYywgZnVuY3Rpb24gKGRvbmUpIHtcblxuICAgICAgICAgICAgICAgIGxldCBjb25zdHJhaW50ID0gbmV3IEFuZE9wZXJhdG9yKGEsIGIpO1xuICAgICAgICAgICAgICAgIGNvbnN0cmFpbnQuaXNWYWxpZCgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjID09PSB0cnVlID8gZG9uZSgpIDogZG9uZShuZXcgRXJyb3IoKSk7XG4gICAgICAgICAgICAgICAgfSkuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjID09PSB0cnVlID8gZG9uZShuZXcgRXJyb3IoKSkgOiBkb25lKCk7XG4gICAgICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgfSk7XG5cbiAgICB9KTtcbn0pO1xuXG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBBYnN0cmFjdE9wZXJhdG9yIH0gZnJvbSBcIi4vYWJzdHJhY3RvcGVyYXRvci5tanNcIjtcbmltcG9ydCB7IGluc3RhbmNlU3ltYm9sIH0gZnJvbSBcIi4uL2NvbnN0YW50cy5tanNcIjtcbmV4cG9ydCB7IE9yT3BlcmF0b3IgfTtcblxuLyoqXG4gKiBDb25zdHJhaW50cyBhcmUgdXNlZCB0byBkZWZpbmUgY29uZGl0aW9ucyB0aGF0IG11c3QgYmUgbWV0IGJ5IHRoZSB2YWx1ZSBvZiBhIHZhcmlhYmxlLlxuICpcbiAqIFRoZSB1bmlmb3JtIEFQSSBvZiB0aGUgY29uc3RyYWludHMgYWxsb3dzIGNoYWlucyB0byBiZSBmb3JtZWQuXG4gKlxuICogVGhlIE9yT3BlcmF0b3IgaXMgdXNlZCB0byBsaW5rIHNldmVyYWwgY29uc3RyYWludHMuIFRoZSBjb25zdHJhaW50IGlzIGZ1bGZpbGxlZCBpZiBvbmUgb2YgdGhlIGNvbnN0cmFpbnRzIGlzIGZ1bGZpbGxlZC5cbiAqXG4gKiBAZXh0ZXJuYWxFeGFtcGxlIC4uLy4uL2V4YW1wbGUvY29uc3RyYWludHMvb3JvcGVyYXRvci5tanNcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMy4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuQ29uc3RyYWludHNcbiAqIEBzdW1tYXJ5IEEgb3Igb3BlcmF0b3JcbiAqL1xuY2xhc3MgT3JPcGVyYXRvciBleHRlbmRzIEFic3RyYWN0T3BlcmF0b3Ige1xuICAgIC8qKlxuICAgICAqIHRoaXMgbWV0aG9kIHJldHVybiBhIHByb21pc2UgY29udGFpbmluZyB0aGUgcmVzdWx0IG9mIHRoZSBjaGVjay5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZX1cbiAgICAgKi9cbiAgICBpc1ZhbGlkKHZhbHVlKSB7XG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICAgICAgbGV0IGE7XG4gICAgICAgICAgICBsZXQgYjtcblxuICAgICAgICAgICAgc2VsZi5vcGVyYW50QVxuICAgICAgICAgICAgICAgIC5pc1ZhbGlkKHZhbHVlKVxuICAgICAgICAgICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgYSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAvKiogYiBoYXMgYWxyZWFkeSBiZWVuIGV2YWx1YXRlZCBhbmQgd2FzIG5vdCB0cnVlICovXG4gICAgICAgICAgICAgICAgICAgIGlmIChiID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgc2VsZi5vcGVyYW50QlxuICAgICAgICAgICAgICAgIC5pc1ZhbGlkKHZhbHVlKVxuICAgICAgICAgICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgYiA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAvKiogYiBoYXMgYWxyZWFkeSBiZWVuIGV2YWx1YXRlZCBhbmQgd2FzIG5vdCB0cnVlICovXG4gICAgICAgICAgICAgICAgICAgIGlmIChhID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMi4xLjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci9jb25zdHJhaW50cy9vci1vcGVyYXRvclwiKTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHtWYWxpZH0gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9jb25zdHJhaW50cy92YWxpZC5tanNcIjtcbmltcG9ydCB7SW52YWxpZH0gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9jb25zdHJhaW50cy9pbnZhbGlkLm1qc1wiO1xuaW1wb3J0IHtPck9wZXJhdG9yfSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2NvbnN0cmFpbnRzL29yb3BlcmF0b3IubWpzXCI7XG5cbmRlc2NyaWJlKCdPck9wZXJhdG9yJywgZnVuY3Rpb24gKCkge1xuXG4gICAgZGVzY3JpYmUoJy5pc1ZhbGlkKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgW25ldyBWYWxpZCgpLCBuZXcgVmFsaWQoKSwgdHJ1ZV0sXG4gICAgICAgICAgICBbbmV3IFZhbGlkKCksIG5ldyBJbnZhbGlkKCksIHRydWVdLFxuICAgICAgICAgICAgW25ldyBJbnZhbGlkKCksIG5ldyBWYWxpZCgpLCB0cnVlXSxcbiAgICAgICAgICAgIFtuZXcgSW52YWxpZCgpLCBuZXcgSW52YWxpZCgpLCBmYWxzZV1cbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGMgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ2NvbnN0cmFpbnQuaXNWYWxpZCgpIHNob3VsZCByZXR1cm4gJyArIGMsIGZ1bmN0aW9uIChkb25lKSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgY29uc3RyYWludCA9IG5ldyBPck9wZXJhdG9yKGEsIGIpO1xuICAgICAgICAgICAgICAgIGNvbnN0cmFpbnQuaXNWYWxpZCgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjID09PSB0cnVlID8gZG9uZSgpIDogZG9uZShuZXcgRXJyb3IoKSk7XG4gICAgICAgICAgICAgICAgfSkuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjID09PSB0cnVlID8gZG9uZShuZXcgRXJyb3IoKSkgOiBkb25lKCk7XG4gICAgICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgfSk7XG5cbiAgICB9KTtcbn0pO1xuXG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBpc0FycmF5IH0gZnJvbSBcIi4uL3R5cGVzL2lzLm1qc1wiO1xuaW1wb3J0IHsgQWJzdHJhY3RDb25zdHJhaW50IH0gZnJvbSBcIi4vYWJzdHJhY3QubWpzXCI7XG5pbXBvcnQgeyBpbnN0YW5jZVN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5leHBvcnQgeyBJc0FycmF5IH07XG5cbi8qKlxuICogQ29uc3RyYWludHMgYXJlIHVzZWQgdG8gZGVmaW5lIGNvbmRpdGlvbnMgdGhhdCBtdXN0IGJlIG1ldCBieSB0aGUgdmFsdWUgb2YgYSB2YXJpYWJsZS5cbiAqXG4gKiBUaGUgdW5pZm9ybSBBUEkgb2YgdGhlIGNvbnN0cmFpbnRzIGFsbG93cyBjaGFpbnMgdG8gYmUgZm9ybWVkLlxuICpcbiAqIEBleHRlcm5hbEV4YW1wbGUgLi4vLi4vZXhhbXBsZS9jb25zdHJhaW50cy9pc2FycmF5Lm1qc1xuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4zLjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5Db25zdHJhaW50c1xuICogQHN1bW1hcnkgQSBjb25zdHJhaW50IHRvIGNoZWNrIGlmIGEgdmFsdWUgaXMgYW4gYXJyYXlcbiAqL1xuY2xhc3MgSXNBcnJheSBleHRlbmRzIEFic3RyYWN0Q29uc3RyYWludCB7XG4gICAgLyoqXG4gICAgICogdGhpcyBtZXRob2QgcmV0dXJuIGEgcHJvbWlzZSBjb250YWluaW5nIHRoZSByZXN1bHQgb2YgdGhlIGNoZWNrLlxuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZVxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlfVxuICAgICAqL1xuICAgIGlzVmFsaWQodmFsdWUpIHtcbiAgICAgICAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMi4xLjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci9jb25zdHJhaW50L2lzLWFycmF5XCIpO1xuICAgIH1cbn1cbiIsICJpbXBvcnQge0lzQXJyYXl9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvY29uc3RyYWludHMvaXNhcnJheS5tanNcIjtcbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5cbmRlc2NyaWJlKCdJc0FycmF5JywgZnVuY3Rpb24gKCkge1xuXG4gICAgZGVzY3JpYmUoJy5pc1ZhbGlkKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCBjb25zdHJhaW50ID0gbmV3IElzQXJyYXkoKVxuXG4gICAgICAgIGl0KCdzaG91bGQgcmVzb2x2ZSBwcm9taXNlJywgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgICAgIGNvbnN0cmFpbnQuaXNWYWxpZChbMSwyLDNdKS50aGVuKHIgPT4ge1xuICAgICAgICAgICAgICAgIGV4cGVjdChyKS5pcy5hKCdhcnJheScpO1xuICAgICAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICAgIH0pLmNhdGNoKGUgPT4ge1xuICAgICAgICAgICAgICAgIGRvbmUobmV3IEVycm9yKFwic2hvdWxkIG5vdCByZWFjaGVkOiBcIiArIGUpKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cbn0pO1xuXG4iLCAiaW1wb3J0IHtCYXNlfSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3R5cGVzL2Jhc2UubWpzXCI7XG5pbXBvcnQge0Fic3RyYWN0T3BlcmF0b3J9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvY29uc3RyYWludHMvYWJzdHJhY3RvcGVyYXRvci5tanNcIjtcbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5cbmNsYXNzIEFic3RyYWN0Q29uc3RyYWludE1vY2sgZXh0ZW5kcyBCYXNlIHtcblxuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIGlzVmFsaWQodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KHZhbHVlKTtcbiAgICB9XG59XG5cblxuZGVzY3JpYmUoJ0Fic3RyYWN0T3BlcmF0b3InLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBhbiBlcnJvciB3aGVuIHRoZSBjb25zdHJhaW50IGlzIG5vdCBjYWxsIHdpdGggcGFyYW1ldGVyJywgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIG5ldyBBYnN0cmFjdE9wZXJhdG9yKClcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IG5vdCBhbiBlcnJvciB3aGVuIHRoZSBjb25zdHJhaW50IGlzIG5vdCBjYWxsIHdpdGggcGFyYW1ldGVyJywgZnVuY3Rpb24gKGRvbmUpIHtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgYyA9IG5ldyBBYnN0cmFjdE9wZXJhdG9yKG5ldyBBYnN0cmFjdENvbnN0cmFpbnRNb2NrKCksIG5ldyBBYnN0cmFjdENvbnN0cmFpbnRNb2NrKCkpICAgIFxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBkb25lKCk7XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgXG5cbiAgICB9KTtcbn0pO1xuXG4iLCAiaW1wb3J0IHtWYWxpZH0gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9jb25zdHJhaW50cy92YWxpZC5tanNcIjtcbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5cbmRlc2NyaWJlKCdWYWxpZCcsIGZ1bmN0aW9uICgpIHtcblxuICAgIGRlc2NyaWJlKCcuaXNWYWxpZCgpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgY29uc3RyYWludCA9IG5ldyBWYWxpZCgpXG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZXNvbHZlIHByb21pc2UnLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICAgICAgY29uc3RyYWludC5pc1ZhbGlkKHt9KS50aGVuKHIgPT4ge1xuICAgICAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICAgIH0pLmNhdGNoKGUgPT4ge1xuICAgICAgICAgICAgICAgIGRvbmUobmV3IEVycm9yKFwic2hvdWxkIG5vdCByZWFjaGVkOiBcIiArIGUpKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cbn0pO1xuXG4iLCAiaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7dHJpbVNwYWNlc30gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS91dGlsL3RyaW1zcGFjZXMubWpzXCI7XG5cblxuZGVzY3JpYmUoJ3RyaW1TcGFjZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgW1xuICAgICAgICAvLyBvbmUgc3Ryb2tlIGlzIGVzY3BlZCBieSB0aGUgamF2YXNjcmlwdCBpbnRlcnByZXRlciwgdGhlIHNlY29uZCBzdHJva2UgZXNjYXBlcyB0aGUgc3Ryb2tlXG4gICAgICAgIFsnIHZhbHVlICcsICd2YWx1ZSddLFxuICAgICAgICBbJyB2YWx1ZVxcXFwgJywgJ3ZhbHVlXFxcXCAnXSxcbiAgICAgICAgWydcXFxcIHZhbHVlXFxcXCAnLCAnXFxcXCB2YWx1ZVxcXFwgJ10sXG4gICAgICAgIFsnXFwgdmFsdWVcXCAnLCAndmFsdWUnXSwgICBcbiAgICAgICAgW1wiICAgdmFsdWUgXFwgXCIsICd2YWx1ZSddLCBcblxuICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgaXQoJ3RyaW1TcGFjZXMoJyArIEpTT04uc3RyaW5naWZ5KGEpICsgJykgc2hvdWxkIHJldHVybiAnICsgSlNPTi5zdHJpbmdpZnkoYiksIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdCh0cmltU3BhY2VzKGEpKS50by5iZS5lcXVhbChiKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG59KTtcbiAgICAiLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBpbnRlcm5hbFN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5cbmltcG9ydCB7IEJhc2UgfSBmcm9tIFwiLi4vdHlwZXMvYmFzZS5tanNcIjtcbmltcG9ydCB7IGlzSW50ZWdlciB9IGZyb20gXCIuLi90eXBlcy9pcy5tanNcIjtcbmltcG9ydCB7IHZhbGlkYXRlRnVuY3Rpb24sIHZhbGlkYXRlSW50ZWdlciB9IGZyb20gXCIuLi90eXBlcy92YWxpZGF0ZS5tanNcIjtcblxuZXhwb3J0IHsgRGVhZE1hbnNTd2l0Y2ggfTtcblxuLyoqXG4gKiBUaGUgZGVhZCBtYW4ncyBzd2l0Y2ggYWxsb3dzIHRvIHNldCBhIHRpbWVyIHdoaWNoIGNhbiBiZSByZXNldCBhZ2FpbiBhbmQgYWdhaW4gd2l0aGluIGEgZGVmaW5lZCBwZXJpb2Qgb2YgdGltZS5cbiAqXG4gKiBAZXh0ZXJuYWxFeGFtcGxlIC4uLy4uL2V4YW1wbGUvdXRpbC9kZWFkbWFuc3N3aXRjaC5tanNcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI5LjBcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlV0aWxcbiAqIEBzdW1tYXJ5IENsYXNzIHRvIGJlIGFibGUgdG8gZXhlY3V0ZSBmdW5jdGlvbiBjaGFpbnNcbiAqL1xuY2xhc3MgRGVhZE1hbnNTd2l0Y2ggZXh0ZW5kcyBCYXNlIHtcbiAgICAvKipcbiAgICAgKiBDcmVhdGUgbmV3IGRlYWQgbWFuJ3Mgc3dpdGNoXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0ludGVnZXJ9IGRlbGF5XG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2tcbiAgICAgKiBAdGhyb3cge1R5cGVFcnJvcn0gdGhlIGFyZ3VtZW50cyBtdXN0IGJlIGVpdGhlciBpbnRlZ2VyIG9yIGZ1bmN0aW9uc1xuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGFuIGludGVnZXJcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihkZWxheSwgY2FsbGJhY2spIHtcbiAgICAgICAgc3VwZXIoKTtcblxuICAgICAgICBpbml0LmNhbGwodGhpcywgdmFsaWRhdGVJbnRlZ2VyKGRlbGF5KSwgdmFsaWRhdGVGdW5jdGlvbihjYWxsYmFjaykpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtJbnRlZ2VyfHVuZGVmaW5lZH0gW2RlbGF5XVxuICAgICAqL1xuICAgIHRvdWNoKGRlbGF5KSB7XG4gICAgICAgIGlmICh0aGlzW2ludGVybmFsU3ltYm9sXVtcImlzQWxyZWFkeVJ1blwiXSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiaGFzIGFscmVhZHkgcnVuXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzSW50ZWdlcihkZWxheSkpIHtcbiAgICAgICAgICAgIHRoaXNbaW50ZXJuYWxTeW1ib2xdW1wiZGVsYXlcIl0gPSBkZWxheTtcbiAgICAgICAgfSBlbHNlIGlmIChkZWxheSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1bnN1cHBvcnRlZCBhcmd1bWVudFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNsZWFyVGltZW91dCh0aGlzW2ludGVybmFsU3ltYm9sXVtcInRpbWVyXCJdKTtcblxuICAgICAgICBpbml0Q2FsbGJhY2suY2FsbCh0aGlzKTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gaW5pdENhbGxiYWNrKCkge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgc2VsZltpbnRlcm5hbFN5bWJvbF1bXCJ0aW1lclwiXSA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBzZWxmW2ludGVybmFsU3ltYm9sXVtcImlzQWxyZWFkeVJ1blwiXSA9IHRydWU7XG4gICAgICAgIHNlbGZbaW50ZXJuYWxTeW1ib2xdW1wiY2FsbGJhY2tcIl0oKTtcbiAgICB9LCBzZWxmW2ludGVybmFsU3ltYm9sXVtcImRlbGF5XCJdKTtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtpbnRlZ2VyfSBkZWxheVxuICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2tcbiAqL1xuZnVuY3Rpb24gaW5pdChkZWxheSwgY2FsbGJhY2spIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgIHNlbGZbaW50ZXJuYWxTeW1ib2xdID0ge1xuICAgICAgICBjYWxsYmFjayxcbiAgICAgICAgZGVsYXksXG4gICAgICAgIGlzQWxyZWFkeVJ1bjogZmFsc2UsXG4gICAgICAgIHRpbWVyOiB1bmRlZmluZWQsXG4gICAgfTtcblxuICAgIGluaXRDYWxsYmFjay5jYWxsKHNlbGYpO1xufVxuIiwgImltcG9ydCB7RGVhZE1hbnNTd2l0Y2h9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdXRpbC9kZWFkbWFuc3N3aXRjaC5tanNcIjtcblxuXG5kZXNjcmliZSgnRGVhZE1hbnNTd2l0Y2gnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBkZXNjcmliZSgncnVuIGluc3RhbmNlJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdzaG91bGQgcnVuJywgZnVuY3Rpb24gKGRvbmUpIHtcblxuICAgICAgICAgICAgY29uc3QgbXMxID0gIERhdGUubm93KCk7XG5cbiAgICAgICAgICAgIG5ldyBEZWFkTWFuc1N3aXRjaCgxMDAsICgpID0+IHtcblxuICAgICAgICAgICAgICAgIGNvbnN0IG1zMiA9ICBEYXRlLm5vdygpO1xuXG4gICAgICAgICAgICAgICAgY29uc3QgZGlmZiA9IG1zMiAtIG1zMTtcbiAgICAgICAgICAgICAgICBpZiAoZGlmZiA8IDEwMCkge1xuICAgICAgICAgICAgICAgICAgICBkb25lKCd0byBzaG9ydCAnICsgZGlmZik7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgfSlcblxuXG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3J1biBpbnN0YW5jZSBhbmQgdG91Y2gnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBydW4nLCBmdW5jdGlvbiAoZG9uZSkge1xuXG4gICAgICAgICAgICBjb25zdCBtczEgPSBEYXRlLm5vdygpO1xuXG4gICAgICAgICAgICBjb25zdCBkZWFkbWFuc3N3aXRjaCA9IG5ldyBEZWFkTWFuc1N3aXRjaCgxMDAsICgpID0+IHtcblxuICAgICAgICAgICAgICAgIGNvbnN0IG1zMiA9IERhdGUubm93KCk7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBkaWZmID0gbXMyIC0gbXMxO1xuXG4gICAgICAgICAgICAgICAgaWYgKG1zMSA+IG1zMikge1xuICAgICAgICAgICAgICAgICAgICBkb25lKG5ldyBFcnJvcigndGltaW5nIGVycm9yJykpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKGRpZmYgPCA2MDApIHtcbiAgICAgICAgICAgICAgICAgICAgZG9uZShuZXcgRXJyb3IoJ3RvIHNob3J0ICcgKyBkaWZmKSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgLy8gICAwIG1zOiBpbml0KCkgLT4gd2FpdCAxMDAgbXMgXG4gICAgICAgICAgICAvLyAgNTAgbXM6IHRvdWNoKCkgLT4gd2FpdCAxMDAgbXNcbiAgICAgICAgICAgIC8vICAgICAgICAgIC0+IHdhaXQgMTAwXG4gICAgICAgICAgICAvLyAxMDAgbXM6IHRvdWNoKDUwMCkgLT4gd2FpdCA1MDAgbXNcbiAgICAgICAgICAgIC8vICAgICAgICAgIC0+IHdhaXQgNTAwXG4gICAgICAgICAgICAvLyA2MDAgbXM6IGV4ZWN1dGUgY2FsbGJhY2tcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGRlYWRtYW5zc3dpdGNoLnRvdWNoKClcblxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBkZWFkbWFuc3N3aXRjaC50b3VjaCg1MDApXG4gICAgICAgICAgICAgICAgfSwgNTApXG5cbiAgICAgICAgICAgIH0sIDUwKVxuXG5cbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbn0pOyIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IHZhbGlkYXRlT2JqZWN0IH0gZnJvbSBcIi4uL3R5cGVzL3ZhbGlkYXRlLm1qc1wiO1xuXG5leHBvcnQgeyBkZWVwRnJlZXplIH07XG5cbi8qKlxuICogRGVlcCBmcmVlemUgYSBvYmplY3RcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gb2JqZWN0IG9iamVjdCB0byBiZSBmcmVlemVcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMC4wXG4gKiBAcmV0dXJucyB7b2JqZWN0fVxuICogQG1lbWJlck9mIE1vbnN0ZXIuVXRpbFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgb2JqZWN0XG4gKi9cbmZ1bmN0aW9uIGRlZXBGcmVlemUob2JqZWN0KSB7XG4gICAgdmFsaWRhdGVPYmplY3Qob2JqZWN0KTtcblxuICAgIC8vIFJldHJpZXZlIHRoZSBkZWZpbmVkIHByb3BlcnR5IG5hbWVzIG9mIHRoZSBvYmplY3RcbiAgICB2YXIgcHJvcE5hbWVzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMob2JqZWN0KTtcblxuICAgIC8vIEZyZWV6ZSBwcm9wZXJ0aWVzIGJlZm9yZSBmcmVlemluZyB5b3Vyc2VsZlxuICAgIGZvciAobGV0IG5hbWUgb2YgcHJvcE5hbWVzKSB7XG4gICAgICAgIGxldCB2YWx1ZSA9IG9iamVjdFtuYW1lXTtcblxuICAgICAgICBvYmplY3RbbmFtZV0gPSB2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgPyBkZWVwRnJlZXplKHZhbHVlKSA6IHZhbHVlO1xuICAgIH1cblxuICAgIHJldHVybiBPYmplY3QuZnJlZXplKG9iamVjdCk7XG59XG4iLCAiaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7ZGVlcEZyZWV6ZX0gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS91dGlsL2ZyZWV6ZS5tanNcIjtcblxuXG5kZXNjcmliZSgnZGVlcEZyZWV6ZScsIGZ1bmN0aW9uICgpIHtcblxuICAgIGRlc2NyaWJlKCdkZWVwRnJlZXplIGFuIG9iamVjdCcsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBpdCgnc2hvdWxkIGZyZWV6ZSBvYmplY3QnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIGxldCBvYmoxID0ge1xuICAgICAgICAgICAgICAgIGE6IHtcbiAgICAgICAgICAgICAgICAgICAgYjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgYzoxXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgXG4gICAgICAgICAgICBsZXQgb2JqMiA9IHtcbiAgICAgICAgICAgICAgICBhOiB7XG4gICAgICAgICAgICAgICAgICAgIGI6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGM6MlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgZXhwZWN0KG9iajIpLnRvLm5vdC5lcWwob2JqMSlcbiAgICAgICAgICAgIG9iajEuYS5iLmMgPSAyO1xuICAgICAgICAgICAgZXhwZWN0KG9iajIpLnRvLmVxbChvYmoxKTtcblxuICAgICAgICAgICAgY29uc3Qgb2JqMUZyZWV6ZWQgPSBkZWVwRnJlZXplKG9iajEpO1xuXG4gICAgICAgICAgICBleHBlY3Qob2JqMikudG8uZXFsKG9iajFGcmVlemVkKTtcblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9kZS9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9PYmplY3QvZnJlZXplXG4gICAgICAgICAgICAgICAgLy8gbm8gY2hhbmdlIHRvIHRoZSBvYmplY3QsIGV4Y2VwdGlvbiBkZXBlbmRzIG9uIG1vZGUgKHN0cmljdCBFUyAyMDE1LCBldGMpXG4gICAgICAgICAgICAgICAgb2JqMUZyZWV6ZWQuYS5iLmMgPSAzICAgIFxuICAgICAgICAgICAgfSBjYXRjaCAoXykge1xuXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGV4cGVjdChvYmoyKS50by5lcWwob2JqMUZyZWV6ZWQpO1xuICAgICAgICAgICAgXG4gICAgICAgICAgICBcbiAgICAgICAgfSk7XG5cbiAgICB9KTtcblxuXG59KTsiLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBCYXNlIH0gZnJvbSBcIi4uL3R5cGVzL2Jhc2UubWpzXCI7XG5pbXBvcnQgeyBpc0Z1bmN0aW9uIH0gZnJvbSBcIi4uL3R5cGVzL2lzLm1qc1wiO1xuXG5leHBvcnQgeyBDb21wYXJhdG9yIH07XG5cbi8qKlxuICogVGhlIGNvbXBhcmF0b3IgYWxsb3dzIGEgY29tcGFyaXNvbiBmdW5jdGlvbiB0byBiZSBhYnN0cmFjdGVkLlxuICpcbiAqIFRoZSBmb2xsb3dpbmcgYXJlIHNvbWUgZXhhbXBsZXMgb2YgdGhlIGFwcGxpY2F0aW9uIG9mIHRoZSBjbGFzcy5cbiAqXG4gKiBgYGBcbiAqIG5ldyBDb21wYXJhdG9yKCkubGVzc1RoYW5PckVxdWFsKDIsIDUpIC8vIFx1MjFBNiB0cnVlXG4gKiBuZXcgQ29tcGFyYXRvcigpLmdyZWF0ZXJUaGFuKDQsIDIpIC8vIFx1MjFBNiB0cnVlXG4gKiBuZXcgQ29tcGFyYXRvcigpLmVxdWFsKDQsIDQpIC8vIFx1MjFBNiB0cnVlXG4gKiBuZXcgQ29tcGFyYXRvcigpLmVxdWFsKDQsIDUpIC8vIFx1MjFBNiBmYWxzZVxuICogYGBgXG4gKlxuICogWW91IGNhbiBhbHNvIHBhc3MgeW91ciBvd24gY29tcGFyaXNvbiBmdW5jdGlvbiwgYW5kIHRodXMgZGVmaW5lIHRoZSBjb21wYXJpc29uIGZ1bmN0aW9uLlxuICpcbiAqIGBgYFxuICogbmV3IENvbXBhcmF0b3IoZnVuY3Rpb24gKGEsIGIpIHtcbiAqICAgICAgaWYgKGEudiA9PT0gYi52KSByZXR1cm4gMDtcbiAqICAgICAgICAgcmV0dXJuIGEudiA8IGIudiA/IC0xIDogMTtcbiAqICAgICAgfSkuZXF1YWwoe3Y6IDJ9LCB7djogMn0pOyAgLy8gXHUyMUE2IHRydWVcbiAqIGBgYFxuICpcbiAqIEBleHRlcm5hbEV4YW1wbGUgLi4vLi4vZXhhbXBsZS91dGlsL2NvbXBhcmF0b3IubWpzXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjMuMFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVXRpbFxuICovXG5jbGFzcyBDb21wYXJhdG9yIGV4dGVuZHMgQmFzZSB7XG4gICAgLyoqXG4gICAgICogY3JlYXRlIG5ldyBjb21wYXJhdG9yXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge01vbnN0ZXIuVXRpbH5leGFtcGxlQ2FsbGJhY2t9IFtjYWxsYmFja10gQ29tcGFyYXRvciBjYWxsYmFja1xuICAgICAqIEB0aHJvdyB7VHlwZUVycm9yfSB1bnN1cHBvcnRlZCB0eXBlXG4gICAgICogQHRocm93IHtUeXBlRXJyb3J9IGltcHJhY3RpY2FsIGNvbXBhcmlzb25cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihjYWxsYmFjaykge1xuICAgICAgICBzdXBlcigpO1xuXG4gICAgICAgIGlmIChpc0Z1bmN0aW9uKGNhbGxiYWNrKSkge1xuICAgICAgICAgICAgdGhpcy5jb21wYXJlID0gY2FsbGJhY2s7XG4gICAgICAgIH0gZWxzZSBpZiAoY2FsbGJhY2sgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInVuc3VwcG9ydGVkIHR5cGVcIik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBkZWZhdWx0IGNvbXBhcmUgZnVuY3Rpb25cblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKlxuICAgICAgICAgICAgICogQHBhcmFtIHsqfSBhXG4gICAgICAgICAgICAgKiBAcGFyYW0geyp9IGJcbiAgICAgICAgICAgICAqIEByZXR1cm4ge2ludGVnZXJ9IC0xLCAwIG9yIDFcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgdGhpcy5jb21wYXJlID0gZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGEgIT09IHR5cGVvZiBiKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJpbXByYWN0aWNhbCBjb21wYXJpc29uXCIsIFwidHlwZXMvY29tcGFyYXRvci5tanNcIik7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKGEgPT09IGIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBhIDwgYiA/IC0xIDogMTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBjaGFuZ2VzIHRoZSBvcmRlciBvZiB0aGUgb3BlcmF0b3JzXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtDb21wYXJhdG9yfVxuICAgICAqL1xuICAgIHJldmVyc2UoKSB7XG4gICAgICAgIGNvbnN0IG9yaWdpbmFsID0gdGhpcy5jb21wYXJlO1xuICAgICAgICB0aGlzLmNvbXBhcmUgPSAoYSwgYikgPT4gb3JpZ2luYWwoYiwgYSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiB0d28gdmFyaWFibGVzIGFyZSBlcXVhbC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Kn0gYVxuICAgICAqIEBwYXJhbSB7Kn0gYlxuICAgICAqXG4gICAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBlcXVhbChhLCBiKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbXBhcmUoYSwgYikgPT09IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIHZhcmlhYmxlIGBhYCBpcyBncmVhdGVyIHRoYW4gYGJgXG4gICAgICpcbiAgICAgKiBAcGFyYW0geyp9IGFcbiAgICAgKiBAcGFyYW0geyp9IGJcbiAgICAgKlxuICAgICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAgICovXG4gICAgZ3JlYXRlclRoYW4oYSwgYikge1xuICAgICAgICByZXR1cm4gdGhpcy5jb21wYXJlKGEsIGIpID4gMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgdmFyaWFibGUgYGFgIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBgYmBcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Kn0gYVxuICAgICAqIEBwYXJhbSB7Kn0gYlxuICAgICAqXG4gICAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBncmVhdGVyVGhhbk9yRXF1YWwoYSwgYikge1xuICAgICAgICByZXR1cm4gdGhpcy5ncmVhdGVyVGhhbihhLCBiKSB8fCB0aGlzLmVxdWFsKGEsIGIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiB2YXJpYWJsZSBgYWAgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIGBiYFxuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSBhXG4gICAgICogQHBhcmFtIHsqfSBiXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgICAqL1xuICAgIGxlc3NUaGFuT3JFcXVhbChhLCBiKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxlc3NUaGFuKGEsIGIpIHx8IHRoaXMuZXF1YWwoYSwgYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIHZhcmlhYmxlIGEgaXMgbGVzcyB0aGFuIGJcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Kn0gYVxuICAgICAqIEBwYXJhbSB7Kn0gYlxuICAgICAqXG4gICAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBsZXNzVGhhbihhLCBiKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbXBhcmUoYSwgYikgPCAwO1xuICAgIH1cbn1cblxuLyoqXG4gKiBUaGlzIGlzIHRoZSBkZXNjcmlwdGlvbiBmb3IgdGhlIGNhbGxiYWNrIGZ1bmN0aW9uIHVzZWQgYnkgdGhlIG9wZXJhdG9yXG4gKlxuICogYGBgXG4gKiBuZXcgQ29tcGFyYXRvcihmdW5jdGlvbiAoYSwgYikge1xuICogICAgICBpZiAoYS52ID09PSBiLnYpIHJldHVybiAwO1xuICogICAgICAgICByZXR1cm4gYS52IDwgYi52ID8gLTEgOiAxO1xuICogICAgICB9KS5lcXVhbCh7djogMn0sIHt2OiAyfSk7ICAvLyBcdTIxQTYgdHJ1ZVxuICogYGBgXG4gKlxuICogQGNhbGxiYWNrIE1vbnN0ZXIuVXRpbH5leGFtcGxlQ2FsbGJhY2tcbiAqIEBwYXJhbSB7Kn0gYVxuICogQHBhcmFtIHsqfSBiXG4gKiBAcmV0dXJuIHtpbnRlZ2VyfSAtMSwgMCBvciAxXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5VdGlsXG4gKiBAc2VlIE1vbnN0ZXIuVXRpbC5Db21wYXJhdG9yXG4gKi9cbiIsICJpbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuaW1wb3J0IHtDb21wYXJhdG9yfSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL3V0aWwvY29tcGFyYXRvci5tanNcIjtcblxuXG5kZXNjcmliZSgnQ29tcGFyYXRvcicsIGZ1bmN0aW9uICgpIHtcblxuICAgIGRlc2NyaWJlKCdjcmVhdGUgbmV3IGluc3RhbmNlJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGEgY29tcGFyYXRvciBvYmplY3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IENvbXBhcmF0b3IoKSkudG8uYmUuYSgnb2JqZWN0Jyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGEgY29tcGFyYXRvciBvYmplY3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IENvbXBhcmF0b3IoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgfSkpLnRvLmJlLmEoJ29iamVjdCcpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHRocm93IFR5cGVFcnJvcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdCgoKSA9PiBuZXcgQ29tcGFyYXRvcih0cnVlKSkudG8udGhyb3coVHlwZUVycm9yKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBUeXBlRXJyb3InLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QoKCkgPT4gbmV3IENvbXBhcmF0b3IoXCJ0ZXN0XCIpKS50by50aHJvdyhUeXBlRXJyb3IpO1xuICAgICAgICB9KTtcblxuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnZXF1YWwoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBbXG4gICAgICAgICAgICBbJ3Rlc3QxJywgXCJ0ZXN0XCIsIGZhbHNlXSxcbiAgICAgICAgICAgIFs1LjEsIDUsIGZhbHNlXSxcbiAgICAgICAgICAgIFs1LjEsIDUuMSwgdHJ1ZV0sXG4gICAgICAgICAgICBbdHJ1ZSwgdHJ1ZSwgdHJ1ZV0sXG4gICAgICAgICAgICBbZmFsc2UsIHRydWUsIGZhbHNlXSxcbiAgICAgICAgICAgIFtmYWxzZSwgZmFsc2UsIHRydWVdLFxuICAgICAgICAgICAgWy00LCAtNCwgdHJ1ZV0sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBjID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGl0KCdzaG91bGQgY29tcGFyZSAnICsgYSArICcgYW5kICcgKyBiICsgJyByZXR1cm4gJyArIGMsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBleHBlY3QobmV3IENvbXBhcmF0b3IoKS5lcXVhbChhLCBiKSkuaXMuZXF1YWwoYylcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2VxdWFsKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWyd0ZXN0MScsIHRydWVdLFxuICAgICAgICAgICAgWyd0ZXN0MScsIDVdLFxuICAgICAgICAgICAgWyd0ZXN0MScsIG51bGxdLFxuICAgICAgICAgICAgWyd0ZXN0MScsIHBhcnNlSW50KFwiYVwiKV0sXG4gICAgICAgICAgICBbZmFsc2UsIDVdLFxuICAgICAgICAgICAgW3VuZGVmaW5lZCwgbnVsbF0sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ3Nob3VsZCBjb21wYXJlICcgKyBhICsgJyBhbmQgJyArIGIgKyAnIHRocm93IFR5cGVFcnJvcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBleHBlY3QoKCkgPT4gbmV3IENvbXBhcmF0b3IoKS5lcXVhbChhLCBiKSkudG8udGhyb3coVHlwZUVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2dyZWF0ZXJUaGFuKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWyd0ZXN0MScsIFwidGVzdFwiLCB0cnVlXSxcbiAgICAgICAgICAgIFs1LjEsIDUsIHRydWVdLFxuICAgICAgICAgICAgWzUuMSwgNS4xLCBmYWxzZV0sXG4gICAgICAgICAgICBbdHJ1ZSwgdHJ1ZSwgZmFsc2VdLFxuICAgICAgICAgICAgW2ZhbHNlLCB0cnVlLCBmYWxzZV0sXG4gICAgICAgICAgICBbZmFsc2UsIGZhbHNlLCBmYWxzZV0sXG4gICAgICAgICAgICBbLTQsIC00LCBmYWxzZV0sXG4gICAgICAgICAgICBbLTQsIDQsIGZhbHNlXSxcbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGMgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ3Nob3VsZCBjb21wYXJlICcgKyBhICsgJyBhbmQgJyArIGIgKyAnIHJldHVybiAnICsgYywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGV4cGVjdChuZXcgQ29tcGFyYXRvcigpLmdyZWF0ZXJUaGFuKGEsIGIpKS5pcy5lcXVhbChjKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgncmV2ZXJzZSgpLmdyZWF0ZXJUaGFuKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWyd0ZXN0MScsIFwidGVzdFwiLCB0cnVlXSxcbiAgICAgICAgICAgIFs1LjEsIDUsIHRydWVdLFxuICAgICAgICAgICAgWzUuMSwgNS4xLCBmYWxzZV0sXG4gICAgICAgICAgICBbdHJ1ZSwgdHJ1ZSwgZmFsc2VdLFxuICAgICAgICAgICAgW2ZhbHNlLCB0cnVlLCBmYWxzZV0sXG4gICAgICAgICAgICBbZmFsc2UsIGZhbHNlLCBmYWxzZV0sXG4gICAgICAgICAgICBbLTQsIC00LCBmYWxzZV0sXG4gICAgICAgICAgICBbLTQsIDQsIGZhbHNlXSxcbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGMgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ3Nob3VsZCBjb21wYXJlICcgKyBhICsgJyBhbmQgJyArIGIgKyAnIHJldHVybiAnICsgYywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGV4cGVjdChuZXcgQ29tcGFyYXRvcigpLnJldmVyc2UoKS5ncmVhdGVyVGhhbihhLCBiKSkuaXMuZXF1YWwoYylcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2dyZWF0ZXJUaGFuT3JFcXVhbCgpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIFtcbiAgICAgICAgICAgIFsndGVzdDEnLCBcInRlc3RcIiwgdHJ1ZV0sXG4gICAgICAgICAgICBbNS4xLCA1LCB0cnVlXSxcbiAgICAgICAgICAgIFs1LjEsIDUuMSwgdHJ1ZV0sXG4gICAgICAgICAgICBbdHJ1ZSwgdHJ1ZSwgdHJ1ZV0sXG4gICAgICAgICAgICBbZmFsc2UsIHRydWUsIGZhbHNlXSxcbiAgICAgICAgICAgIFtmYWxzZSwgZmFsc2UsIHRydWVdLFxuICAgICAgICAgICAgWy00LCAtNCwgdHJ1ZV0sXG4gICAgICAgICAgICBbLTQsIDQsIGZhbHNlXSxcbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGMgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ3Nob3VsZCBjb21wYXJlICcgKyBhICsgJyBhbmQgJyArIGIgKyAnIHJldHVybiAnICsgYywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGV4cGVjdChuZXcgQ29tcGFyYXRvcigpLmdyZWF0ZXJUaGFuT3JFcXVhbChhLCBiKSkuaXMuZXF1YWwoYylcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2xlc3NUaGFuKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWyd0ZXN0MScsIFwidGVzdFwiLCB0cnVlXSxcbiAgICAgICAgICAgIFs1LjEsIDUsIHRydWVdLFxuICAgICAgICAgICAgWzUuMSwgNS4xLCBmYWxzZV0sXG4gICAgICAgICAgICBbdHJ1ZSwgdHJ1ZSwgZmFsc2VdLFxuICAgICAgICAgICAgW2ZhbHNlLCB0cnVlLCBmYWxzZV0sXG4gICAgICAgICAgICBbZmFsc2UsIGZhbHNlLCBmYWxzZV0sXG4gICAgICAgICAgICBbLTQsIC00LCBmYWxzZV0sXG4gICAgICAgICAgICBbLTQsIDQsIGZhbHNlXSxcbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGMgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ3Nob3VsZCBjb21wYXJlICcgKyBhICsgJyBhbmQgJyArIGIgKyAnIHJldHVybiAnICsgYywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGV4cGVjdChuZXcgQ29tcGFyYXRvcigpLmxlc3NUaGFuKGEsIGIpKS5pcy5lcXVhbChjKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnZG9jdW1lbnRhdGlvbnMnLCBmdW5jdGlvbiAoKSB7XG5cblxuICAgICAgICBpdCgnc2hvdWxkIHJ1biAuLi4nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IENvbXBhcmF0b3IoKS5sZXNzVGhhbk9yRXF1YWwoMiwgNSkpLnRvLmJlLnRydWU7XG4gICAgICAgICAgICBleHBlY3QobmV3IENvbXBhcmF0b3IoKS5ncmVhdGVyVGhhbig0LCAyKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgQ29tcGFyYXRvcigpLmVxdWFsKDQsIDQpKS50by5iZS50cnVlO1xuICAgICAgICAgICAgZXhwZWN0KG5ldyBDb21wYXJhdG9yKCkuZXF1YWwoNCwgNSkpLnRvLmJlLmZhbHNlO1xuICAgICAgICB9KTtcblxuXG4gICAgICAgIGl0KCdzaG91bGQgcnVuIHdpdGggb3duIGZ1bmN0aW9uIC4uLicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgQ29tcGFyYXRvcihmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICAgICAgICAgIGlmIChhLnYgPT09IGIudikgcmV0dXJuIDA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGEudiA8IGIudiA/IC0xIDogMTtcbiAgICAgICAgICAgIH0pLmVxdWFsKHt2OiAyfSwge3Y6IDJ9KSkudG8uYmUudHJ1ZTtcbiAgICAgICAgfSk7XG5cblxuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnbGVzc1RoYW5PckVxdWFsKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWyd0ZXN0MScsIFwidGVzdFwiLCB0cnVlXSxcbiAgICAgICAgICAgIFs1LjEsIDUsIHRydWVdLFxuICAgICAgICAgICAgWzUuMSwgNS4xLCB0cnVlXSxcbiAgICAgICAgICAgIFt0cnVlLCB0cnVlLCB0cnVlXSxcbiAgICAgICAgICAgIFtmYWxzZSwgdHJ1ZSwgZmFsc2VdLFxuICAgICAgICAgICAgW2ZhbHNlLCBmYWxzZSwgdHJ1ZV0sXG4gICAgICAgICAgICBbLTQsIC00LCB0cnVlXSxcbiAgICAgICAgICAgIFstNCwgNCwgZmFsc2VdLFxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYyA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpdCgnc2hvdWxkIGNvbXBhcmUgJyArIGEgKyAnIGFuZCAnICsgYiArICcgcmV0dXJuICcgKyBjLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KG5ldyBDb21wYXJhdG9yKCkubGVzc1RoYW5PckVxdWFsKGEsIGIpKS5pcy5lcXVhbChjKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cblxufSk7IiwgImltcG9ydCB7Y2xvbmV9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdXRpbC9jbG9uZS5tanNcIjtcbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5cbmRlc2NyaWJlKCdDbG9uZScsIGZ1bmN0aW9uICgpIHtcblxuICAgIGNsYXNzIEEge1xuICAgICAgICBjb25zdHJ1Y3RvcihiKSB7XG4gICAgICAgICAgICB0aGlzLmIgPSBiXG4gICAgICAgIH1cblxuICAgICAgICBhKCkge1xuXG4gICAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgY2xhc3MgQiB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGIpIHtcbiAgICAgICAgICAgIHRoaXMuYiA9IGJcbiAgICAgICAgfVxuXG4gICAgICAgIGEoKSB7XG5cbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgZ2V0Q2xvbmUoKSB7XG4gICAgICAgICAgICByZXR1cm4gXCJET05FXCJcbiAgICAgICAgfVxuICAgICAgICBcbiAgICB9XG5cbiAgICBkZXNjcmliZSgnLmNsb25lKEIpIHdpdGggZ2V0Q2xvbmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCcuY2xvbmUoQikgc2hvdWxkIG9iamVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBiID0gbmV3IEIoe1xuICAgICAgICAgICAgICAgIHg6IHtcbiAgICAgICAgICAgICAgICAgICAgeTogMSwgZDogbmV3IEEoMSksIHo6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgbGV0IHIgPSBjbG9uZShiKTtcbiAgICAgICAgICAgIGV4cGVjdChiKS50by5iZS5pbnN0YW5jZU9mKEIpXG4gICAgICAgICAgICBleHBlY3Qocikubm90LmVxdWFsKGIpO1xuICAgICAgICAgICAgZXhwZWN0KEpTT04uc3RyaW5naWZ5KHIpKS5lcXVhbChKU09OLnN0cmluZ2lmeSgnRE9ORScpKTtcblxuICAgICAgICB9KTtcbiAgICB9KVxuICAgIFxuICAgIGRlc2NyaWJlKCcuY2xvbmUoQSknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCcuY2xvbmUoQSkgc2hvdWxkIG9iamVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBhID0gbmV3IEEoe1xuICAgICAgICAgICAgICAgIHg6IHtcbiAgICAgICAgICAgICAgICAgICAgeTogMSwgZDogbmV3IEEoMSksIHo6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgbGV0IGIgPSBjbG9uZShhKTtcbiAgICAgICAgICAgIGV4cGVjdChhKS50by5iZS5pbnN0YW5jZU9mKEEpXG4gICAgICAgICAgICBleHBlY3QoYikudG8uYmUuaW5zdGFuY2VPZihBKVxuICAgICAgICAgICAgZXhwZWN0KGIpLm5vdC5lcXVhbChhKTtcbiAgICAgICAgICAgIGV4cGVjdChKU09OLnN0cmluZ2lmeShhKSkuZXF1YWwoSlNPTi5zdHJpbmdpZnkoYikpO1xuXG4gICAgICAgIH0pO1xuICAgIH0pXG5cbiAgICAvLyBub2RlanMgZG9lcyBub3QgaGF2ZSBhIERPTVxuICAgIGlmICh0eXBlb2YgRG9jdW1lbnRGcmFnbWVudCA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICBkZXNjcmliZSgnLmNsb25lKERvY3VtZW50RnJhZ21lbnQpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaXQoJy5jbG9uZShEb2N1bWVudEZyYWdtZW50KSBzaG91bGQgc2FtZSBEb2N1bWVudEZyYWdtZW50JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGxldCBhID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpO1xuICAgICAgICAgICAgICAgIGxldCBiID0gY2xvbmUoYSk7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGIpLmVxdWFsKGEpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgZGVzY3JpYmUoJy5jbG9uZShudWxsKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gdHlwZW9mIG51bGwgcmVzdWx0cyBpbiAnb2JqZWN0Jy4gIGh0dHBzOi8vMmFsaXR5LmNvbS8yMDEzLzEwL3R5cGVvZi1udWxsLmh0bWxcbiAgICAgICAgaXQoJy5jbG9uZShudWxsKSBzaG91bGQgIG51bGwnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgYSA9IG51bGxcbiAgICAgICAgICAgIGxldCBiID0gY2xvbmUoYSk7XG4gICAgICAgICAgICBleHBlY3QoYikuZXF1YWwoYSk7XG4gICAgICAgICAgICBleHBlY3QoYikudG8uYmUubnVsbDtcbiAgICAgICAgICAgIGV4cGVjdChhKS50by5iZS5udWxsO1xuICAgICAgICB9KTtcbiAgICB9KVxuXG4gICAgZGVzY3JpYmUoJy5jbG9uZSh1bmRlZmluZWQpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnLmNsb25lKHVuZGVmaW5lZCkgc2hvdWxkICB1bmRlZmluZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgYSA9IHVuZGVmaW5lZFxuICAgICAgICAgICAgbGV0IGIgPSBjbG9uZShhKTtcbiAgICAgICAgICAgIGV4cGVjdChhID09PSBiKS50by5iZS50cnVlXG4gICAgICAgICAgICBleHBlY3QodHlwZW9mIGIgPT09ICd1bmRlZmluZWQnKS50by5iZS50cnVlXG4gICAgICAgICAgICBleHBlY3QoYSA9PT0gdW5kZWZpbmVkKS50by5iZS50cnVlXG4gICAgICAgICAgICBleHBlY3QoYiA9PT0gdW5kZWZpbmVkKS50by5iZS50cnVlXG4gICAgICAgIH0pO1xuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnLmNsb25lKG9iamVjdCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJy5jbG9uZSh7fSkgc2hvdWxkICBvYmplY3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgYSA9IHt9XG4gICAgICAgICAgICBsZXQgYiA9IGNsb25lKGEpO1xuICAgICAgICAgICAgZXhwZWN0KHR5cGVvZiBiID09PSAnb2JqZWN0JykudG8uYmUudHJ1ZVxuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnLmNsb25lKHt4OjF9KSBzaG91bGQgIG9iamVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBhID0ge3g6IDF9XG4gICAgICAgICAgICBsZXQgYiA9IGNsb25lKGEpO1xuICAgICAgICAgICAgZXhwZWN0KGEueCkuaXMuZXF1YWwoYi54KVxuICAgICAgICB9KTtcbiAgICB9KVxuICAgIGRlc2NyaWJlKCcuY2xvbmUoZnVuY3Rpb24pJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCcuY2xvbmUoZnVuY3Rpb24pIHNob3VsZCAgZnVuY3Rpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgYSA9ICgpID0+IHtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCBiID0gY2xvbmUoYSk7XG4gICAgICAgICAgICBleHBlY3QodHlwZW9mIGIgPT09ICdmdW5jdGlvbicpLnRvLmJlLnRydWVcbiAgICAgICAgfSk7XG5cbiAgICB9KVxuXG4gICAgZGVzY3JpYmUoJy5jbG9uZSgpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIFtcbiAgICAgICAgICAgIFsndGVzdDEnLCAnc3RyaW5nJ10sXG4gICAgICAgICAgICBbdW5kZWZpbmVkLCAndW5kZWZpbmVkJ10sXG4gICAgICAgICAgICBbbnVsbCwgJ29iamVjdCddLCAvLyB0eXBlb2YgbnVsbCByZXN1bHRzIGluICdvYmplY3QnLiAgaHR0cHM6Ly8yYWxpdHkuY29tLzIwMTMvMTAvdHlwZW9mLW51bGwuaHRtbFxuICAgICAgICAgICAgWygpID0+IHtcbiAgICAgICAgICAgIH0sICdmdW5jdGlvbiddLFxuICAgICAgICAgICAgWzIsICdudW1iZXInXSxcbiAgICAgICAgICAgIFtmYWxzZSwgJ2Jvb2xlYW4nXSxcbiAgICAgICAgICAgIFt0cnVlLCAnYm9vbGVhbiddLFxuICAgICAgICAgICAgWzQuNSwgJ251bWJlciddLFxuICAgICAgICAgICAgW3t9LCAnb2JqZWN0J10sXG4gICAgICAgICAgICBbWzEsIDIsIDNdLCAnb2JqZWN0J10sIC8vIGFycmF5IGlzdCBhdWNoIHR5cGUgb2JqZWN0XG4gICAgICAgICAgICBbU3ltYm9sKFwiZm9vXCIpLCAnc3ltYm9sJ10sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcblxuXG4gICAgICAgICAgICBpdCgnLmNsb25lKCcgKyBKU09OLnN0cmluZ2lmeShhKSArICcpIHNob3VsZCAgJyArIGIgKyAnICcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBsZXQgYyA9IGNsb25lKGEpO1xuICAgICAgICAgICAgICAgIGV4cGVjdCh0eXBlb2YgYykuaXMuZXF1YWwoYik7XG4gICAgICAgICAgICB9KTtcblxuXG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxufSk7XG5cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGludGVybmFsU3ltYm9sIH0gZnJvbSBcIi4uL2NvbnN0YW50cy5tanNcIjtcbmltcG9ydCB7IEJhc2UgfSBmcm9tIFwiLi4vdHlwZXMvYmFzZS5tanNcIjtcbmltcG9ydCB7IGdldEdsb2JhbEZ1bmN0aW9uIH0gZnJvbSBcIi4uL3R5cGVzL2dsb2JhbC5tanNcIjtcbmltcG9ydCB7IGlzRnVuY3Rpb24sIGlzSW50ZWdlciB9IGZyb20gXCIuLi90eXBlcy9pcy5tanNcIjtcbmltcG9ydCB7IFF1ZXVlIH0gZnJvbSBcIi4uL3R5cGVzL3F1ZXVlLm1qc1wiO1xuaW1wb3J0IHsgdmFsaWRhdGVGdW5jdGlvbiwgdmFsaWRhdGVJbnRlZ2VyIH0gZnJvbSBcIi4uL3R5cGVzL3ZhbGlkYXRlLm1qc1wiO1xuXG5leHBvcnQgeyBQcm9jZXNzaW5nIH07XG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuY2xhc3MgQ2FsbGJhY2sge1xuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2tcbiAgICAgKiBAcGFyYW0ge2ludHx1bmRlZmluZWR9IHRpbWVcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIGZ1bmN0aW9uXG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYW4gaW50ZWdlclxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoY2FsbGJhY2ssIHRpbWUpIHtcbiAgICAgICAgdGhpc1tpbnRlcm5hbFN5bWJvbF0gPSB7XG4gICAgICAgICAgICBjYWxsYmFjazogdmFsaWRhdGVGdW5jdGlvbihjYWxsYmFjayksXG4gICAgICAgICAgICB0aW1lOiB2YWxpZGF0ZUludGVnZXIodGltZSA/PyAwKSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSAgeyp9IGRhdGFcbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgICAqL1xuICAgIHJ1bihkYXRhKSB7XG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgZ2V0R2xvYmFsRnVuY3Rpb24oXCJzZXRUaW1lb3V0XCIpKCgpID0+IHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHNlbGZbaW50ZXJuYWxTeW1ib2xdLmNhbGxiYWNrKGRhdGEpKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LCBzZWxmW2ludGVybmFsU3ltYm9sXS50aW1lKTtcbiAgICAgICAgfSk7XG4gICAgfVxufVxuXG4vKipcbiAqIFRoaXMgY2xhc3MgYWxsb3dzIHRvIGV4ZWN1dGUgc2V2ZXJhbCBmdW5jdGlvbnMgaW4gb3JkZXIuXG4gKlxuICogRnVuY3Rpb25zIGFuZCB0aW1lb3V0cyBjYW4gYmUgcGFzc2VkLiBJZiBhIHRpbWVvdXQgaXMgcGFzc2VkLCBpdCBhcHBsaWVzIHRvIGFsbCBmdXJ0aGVyIGZ1bmN0aW9ucy5cbiAqIEluIHRoZSBleGFtcGxlXG4gKlxuICogYHRpbWVvdXQxLCBmdW5jdGlvbjEsIGZ1bmN0aW9uMiwgZnVuY3Rpb24zLCB0aW1lb3V0MiwgZnVuY3Rpb240YFxuICpcbiAqIHRoZSB0aW1lb3V0MSBpcyB2YWxpZCBmb3IgdGhlIGZ1bmN0aW9ucyAxLCAyIGFuZCAzIGFuZCB0aGUgdGltZW91dDIgZm9yIHRoZSBmdW5jdGlvbjQuXG4gKlxuICogU28gdGhlIGV4ZWN1dGlvbiB0aW1lIGlzIHRpbWVvdXQxK3RpbWVvdXQxK3RpbWVvdXQxK3RpbWVvdXQyXG4gKlxuICogVGhlIHJlc3VsdCBvZiBgcnVuKClgIGlzIGEgcHJvbWlzZS5cbiAqXG4gKiBAZXh0ZXJuYWxFeGFtcGxlIC4uLy4uL2V4YW1wbGUvdXRpbC9wcm9jZXNzaW5nLm1qc1xuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjEuMFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVXRpbFxuICogQHN1bW1hcnkgQ2xhc3MgdG8gYmUgYWJsZSB0byBleGVjdXRlIGZ1bmN0aW9uIGNoYWluc1xuICovXG5jbGFzcyBQcm9jZXNzaW5nIGV4dGVuZHMgQmFzZSB7XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIG5ldyBQcm9jZXNzaW5nXG4gICAgICpcbiAgICAgKiBGdW5jdGlvbnMgYW5kIHRpbWVvdXRzIGNhbiBiZSBwYXNzZWQuIElmIGEgdGltZW91dCBpcyBwYXNzZWQsIGl0IGFwcGxpZXMgdG8gYWxsIGZ1cnRoZXIgZnVuY3Rpb25zLlxuICAgICAqIEluIHRoZSBleGFtcGxlXG4gICAgICpcbiAgICAgKiBgdGltZW91dDEsIGZ1bmN0aW9uMSwgZnVuY3Rpb24yLCBmdW5jdGlvbjMsIHRpbWVvdXQyLCBmdW5jdGlvbjRgXG4gICAgICpcbiAgICAgKiB0aGUgdGltZW91dDEgaXMgdmFsaWQgZm9yIHRoZSBmdW5jdGlvbnMgMSwgMiBhbmQgMyBhbmQgdGhlIHRpbWVvdXQyIGZvciB0aGUgZnVuY3Rpb240LlxuICAgICAqXG4gICAgICogU28gdGhlIGV4ZWN1dGlvbiB0aW1lIGlzIHRpbWVvdXQxK3RpbWVvdXQxK3RpbWVvdXQxK3RpbWVvdXQyXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge2ludH0gdGltZW91dCBUaW1lb3V0XG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2sgQ2FsbGJhY2tcbiAgICAgKiBAdGhyb3cge1R5cGVFcnJvcn0gdGhlIGFyZ3VtZW50cyBtdXN0IGJlIGVpdGhlciBpbnRlZ2VyIG9yIGZ1bmN0aW9uc1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKC4uLmFyZ3MpIHtcbiAgICAgICAgc3VwZXIoKTtcblxuICAgICAgICB0aGlzW2ludGVybmFsU3ltYm9sXSA9IHtcbiAgICAgICAgICAgIHF1ZXVlOiBuZXcgUXVldWUoKSxcbiAgICAgICAgfTtcblxuICAgICAgICBsZXQgdGltZSA9IDA7XG5cbiAgICAgICAgaWYgKHR5cGVvZiBhcmdzICE9PSBcIm9iamVjdFwiIHx8IGFyZ3NbMF0gPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJ0aGUgYXJndW1lbnRzIG11c3QgYmUgZWl0aGVyIGludGVnZXIgb3IgZnVuY3Rpb25zXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChjb25zdCBbLCBhcmddIG9mIE9iamVjdC5lbnRyaWVzKGFyZ3MpKSB7XG4gICAgICAgICAgICBpZiAoaXNJbnRlZ2VyKGFyZykgJiYgYXJnID49IDApIHtcbiAgICAgICAgICAgICAgICB0aW1lID0gYXJnO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChpc0Z1bmN0aW9uKGFyZykpIHtcbiAgICAgICAgICAgICAgICB0aGlzW2ludGVybmFsU3ltYm9sXS5xdWV1ZS5hZGQobmV3IENhbGxiYWNrKGFyZywgdGltZSkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwidGhlIGFyZ3VtZW50cyBtdXN0IGJlIGVpdGhlciBpbnRlZ2VyIG9yIGZ1bmN0aW9uc1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZHMgYSBmdW5jdGlvbiB3aXRoIHRoZSBkZXNpcmVkIHRpbWVvdXRcbiAgICAgKiBJZiBubyB0aW1lb3V0IGlzIHNwZWNpZmllZCwgdGhlIHRpbWVvdXQgb2YgdGhlIHByZXZpb3VzIGZ1bmN0aW9uIGlzIHVzZWQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBjYWxsYmFja1xuICAgICAqIEBwYXJhbSB7aW50fHVuZGVmaW5lZH0gdGltZVxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgZnVuY3Rpb25cbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhbiBpbnRlZ2VyXG4gICAgICovXG4gICAgYWRkKGNhbGxiYWNrLCB0aW1lKSB7XG4gICAgICAgIHRoaXNbaW50ZXJuYWxTeW1ib2xdLnF1ZXVlLmFkZChuZXcgQ2FsbGJhY2soY2FsbGJhY2ssIHRpbWUpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXhlY3V0ZXMgdGhlIGRlZmluZWQgZnVuY3Rpb25zIGluIG9yZGVyLlxuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSBkYXRhXG4gICAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICAgKi9cbiAgICBydW4oZGF0YSkge1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICAgICAgaWYgKHRoaXNbaW50ZXJuYWxTeW1ib2xdLnF1ZXVlLmlzRW1wdHkoKSkge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShkYXRhKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzW2ludGVybmFsU3ltYm9sXS5xdWV1ZVxuICAgICAgICAgICAgLnBvbGwoKVxuICAgICAgICAgICAgLnJ1bihkYXRhKVxuICAgICAgICAgICAgLnRoZW4oKHJlc3VsdCkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBzZWxmLnJ1bihyZXN1bHQpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxufVxuIiwgImltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge1Byb2Nlc3Npbmd9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdXRpbC9wcm9jZXNzaW5nLm1qc1wiO1xuXG5cbmRlc2NyaWJlKCdQcm9jZXNzaW5nJywgZnVuY3Rpb24gKCkge1xuXG4gICAgZGVzY3JpYmUoJ3J1biBpbnN0YW5jZScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBpdCgnc2hvdWxkIHJ1biBtYW55IGZ1bmN0aW9uJywgZnVuY3Rpb24gKGRvbmUpIHtcblxuICAgICAgICAgICAgbGV0IGNvdW50ZXIgPSAwO1xuICAgICAgICAgICAgbGV0IHQgPSArbmV3IERhdGUoKTtcblxuICAgICAgICAgICAgY29uc3QgZGVzaXJlZERlbGF5ID0gMjAwO1xuICAgICAgICAgICAgdGhpcy50aW1lb3V0KGRlc2lyZWREZWxheSsxMDApO1xuICAgICAgICAgICAgXG4gICAgICAgICAgICAvLyBkZWxheSAxMiBcbiAgICAgICAgICAgIG5ldyBQcm9jZXNzaW5nKCh2KSA9PiB7XG4gICAgICAgICAgICAgICAgY291bnRlcisrO1xuICAgICAgICAgICAgICAgIHJldHVybiB2O1xuICAgICAgICAgICAgfSwgKHYpID0+IHtcbiAgICAgICAgICAgICAgICBjb3VudGVyKytcbiAgICAgICAgICAgICAgICByZXR1cm4gdjtcbiAgICAgICAgICAgIH0sIGZ1bmN0aW9uICh2KSB7XG4gICAgICAgICAgICAgICAgY291bnRlcisrXG4gICAgICAgICAgICAgICAgcmV0dXJuIHY7XG4gICAgICAgICAgICB9LCBkZXNpcmVkRGVsYXksZnVuY3Rpb24gKHYpIHtcbiAgICAgICAgICAgICAgICBjb3VudGVyKytcbiAgICAgICAgICAgICAgICByZXR1cm4gdjtcbiAgICAgICAgICAgIH0pLnJ1bigndGVzdCcpLnRoZW4oKHYpID0+IHtcblxuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChjb3VudGVyKS50by5iZS5lcXVhbCg0KTtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KHYgPT09ICd0ZXN0JykudG8uYmUudHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgZGVsYXlcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KCtuZXcgRGF0ZSgpID4gdCArIGRlc2lyZWREZWxheSsxKS50by5iZS50cnVlO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRvbmUoZSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgfSlcblxuXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgcnVuIG9uZSBmdW5jdGlvbicsIGZ1bmN0aW9uIChkb25lKSB7XG5cbiAgICAgICAgICAgIGxldCBjb3VudGVyID0gMDtcblxuICAgICAgICAgICAgbmV3IFByb2Nlc3NpbmcoKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgY291bnRlcisrXG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgfSkucnVuKCd0ZXN0JykudGhlbigodikgPT4ge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdCh2ID09PSAndGVzdCcpLnRvLmJlLnRydWU7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZG9uZShlKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBkb25lKClcbiAgICAgICAgICAgIH0pLmNhdGNoKGUgPT4gZG9uZShlKSk7XG5cblxuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHJ1biBubyBmdW5jdGlvbicsIGZ1bmN0aW9uIChkb25lKSB7XG5cbiAgICAgICAgICAgIGxldCBjb3VudGVyID0gMDtcblxuICAgICAgICAgICAgbmV3IFByb2Nlc3NpbmcoKS5ydW4oJ3Rlc3QnKS50aGVuKCh2KSA9PiB7XG5cbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QodiA9PT0gJ3Rlc3QnKS50by5iZS50cnVlO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRvbmUoZSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZG9uZSgpXG4gICAgICAgICAgICB9KS5jYXRjaChlID0+IGRvbmUoZSkpO1xuXG5cbiAgICAgICAgfSk7XG5cblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2NyZWF0ZSBuZXcgaW5zdGFuY2UnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gYSBQcm9jZXNzaW5nIG9iamVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgUHJvY2Vzc2luZygpKS50by5iZS5hKCdvYmplY3QnKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gYSBQcm9jZXNzaW5nIG9iamVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgUHJvY2Vzc2luZyhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB9KSkudG8uYmUuYSgnb2JqZWN0Jyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgdGhyb3cgVHlwZUVycm9yJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KCgpID0+IG5ldyBQcm9jZXNzaW5nKHRydWUpKS50by50aHJvdyhUeXBlRXJyb3IpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHRocm93IFR5cGVFcnJvcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdCgoKSA9PiBuZXcgUHJvY2Vzc2luZyhcInRlc3RcIikpLnRvLnRocm93KFR5cGVFcnJvcik7XG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxufSk7IiwgIlwidXNlIHN0cmljdFwiO1xuXG5pbXBvcnQge2V4dGVuZH0gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9kYXRhL2V4dGVuZC5tanNcIjtcbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5cbmNsYXNzIE1vY2tGb3JFeHRlbmRzIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICB9XG59XG5cblxuZGVzY3JpYmUoJ2V4dGVuZCcsIGZ1bmN0aW9uICgpIHtcblxuICAgIFtcbiAgICAgICAgW1xuICAgICAgICAgICAne1widGhla2V5XCI6e319Jyx7fSx7dGhla2V5Om5ldyBNb2NrRm9yRXh0ZW5kc30gXG4gICAgICAgIF0sXG4gICAgICAgIFtcbiAgICAgICAgICAgICd7XCJhXCI6e1wiYlwiOltcIjFcIixcIjJcIixcIjNcIl19fScsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYToge1xuICAgICAgICAgICAgICAgICAgICBiOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICBcIjFcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiMlwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgXCIzXCJcbiAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYToge1xuICAgICAgICAgICAgICAgICAgICBiOiBbXVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgIF0sICAgICAgICBbXG4gICAgICAgICAgICAne1wiYVwiOntcImJcIjoxLFwiZFwiOjF9fScsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYToge1xuICAgICAgICAgICAgICAgICAgICBiOiAxXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhOiB7XG4gICAgICAgICAgICAgICAgICAgIGQ6IDFcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICBdLFxuXG4gICAgICAgIFtcbiAgICAgICAgICAgICd7XCJhXCI6e1wiYlwiOjEsXCJkXCI6e1wieFwiOltcImNhclwiXSxcImZcIjp0cnVlLFwiZ1wiOltdfX19JyxcbiAgICAgICAgICAgIHt9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGE6IHtcbiAgICAgICAgICAgICAgICAgICAgYjogMSxcbiAgICAgICAgICAgICAgICAgICAgZDoge3g6IFtcImNhclwiXX1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGE6IHtcbiAgICAgICAgICAgICAgICAgICAgZDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgZjogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGc6IFtdXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICBdXG5cbiAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICBsZXQgZCA9IGRhdGEuc2hpZnQoKVxuICAgICAgICBsZXQgYSA9IGRhdGFcblxuICAgICAgICBpdCgnLmV4dGVuZCgnICsgSlNPTi5zdHJpbmdpZnkoYSkgKyAnKSBzaG91bGQgcmVzdWx0IGluICcgKyBkLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgeCA9IGV4dGVuZC5hcHBseSh0aGlzLCBhKTtcbiAgICAgICAgICAgIGV4cGVjdChKU09OLnN0cmluZ2lmeSh4KSkuaXMuZXF1YWwoZCk7XG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxuXG4gICAgW1xuXG5cbiAgICAgICAgW1xuICAgICAgICAgICAge30sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYToge1xuICAgICAgICAgICAgICAgICAgICBiOiAxLFxuICAgICAgICAgICAgICAgICAgICBkOiBbXCJjYXJcIl1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGE6IHtcbiAgICAgICAgICAgICAgICAgICAgZDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgZjogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGc6IFtdXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYToge31cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYTogW11cbiAgICAgICAgICAgIH1cbiAgICAgICAgXVxuXG4gICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgbGV0IGEgPSBkYXRhXG5cbiAgICAgICAgaXQoJy5leHRlbmQoJyArIEpTT04uc3RyaW5naWZ5KGEpICsgJykgc2hvdWxkIHRocm93IEVycm9yICcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdCgoKSA9PiBleHRlbmQuYXBwbHkodGhpcywgYSkpLnRvLnRocm93KEVycm9yKTtcbiAgICAgICAgfSk7XG5cblxuICAgIH0pO1xuXG59KSIsICJcInVzZSBzdHJpY3RcIjtcblxuaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7UGlwZX0gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9kYXRhL3BpcGUubWpzXCI7XG5pbXBvcnQge2luaXRKU0RPTX0gZnJvbSBcIi4uLy4uL3V0aWwvanNkb20ubWpzXCI7XG5pbXBvcnQge0VtYmVkfSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2kxOG4vcHJvdmlkZXJzL2VtYmVkLm1qc1wiO1xuXG5cbmRlc2NyaWJlKCdQaXBlJywgZnVuY3Rpb24gKCkge1xuXG4gICAgYmVmb3JlKGZ1bmN0aW9uIChkb25lKSB7XG5cbiAgICAgICAgbGV0IHByb21pc2VzID0gW11cbiAgICAgICAgaWYgKCFnbG9iYWxUaGlzWydjcnlwdG8nXSkge1xuICAgICAgICAgICAgcHJvbWlzZXMucHVzaChpbXBvcnQoXCJAcGVjdWxpYXIvd2ViY3J5cHRvXCIpLnRoZW4obSA9PiB7XG4gICAgICAgICAgICAgICAgZ2xvYmFsVGhpc1snY3J5cHRvJ10gPSBuZXcgbS5DcnlwdG8oKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH0pKVxuICAgICAgICB9XG5cbiAgICAgICAgUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgZG9uZSgpXG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgncnVuIGRpZmZlcmVudCBwaXBlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgW1xuICAgICAgICAgICAgWydwYXRoOmIgfCBpZjp4OlxcXFwgJywge2E6IHRydWV9LCAnICddLCAgIC8vICdcXFxcICcubGVuZ3RoIFx1MjFBNiAyXG4gICAgICAgICAgICBbJ3BhdGg6YSB8IGlmOng6XFxcXCAnLCB7YTogdHJ1ZX0sICd4J10sXG4gICAgICAgICAgICBbJ25vcCcsICdhYmNkZWZnaGlqa2xtbm9wJywgJ2FiY2RlZmdoaWprbG1ub3AnXSxcblxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYyA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpdCgnUGlwZS5ydW4oJyArIEpTT04uc3RyaW5naWZ5KGEpICsgJykucnVuKCcgKyBKU09OLnN0cmluZ2lmeShiKSArICcpIHNob3VsZCByZXR1cm4gJyArIEpTT04uc3RyaW5naWZ5KGMpLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbGV0IHQgPSBuZXcgUGlwZShhKTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IHIgPSB0LnJ1bihiKTtcbiAgICAgICAgICAgICAgICBleHBlY3QocikudG8uYmUuZXFsKGMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxuXG4gICAgZGVzY3JpYmUoJ25ldyBQaXBlIHNob3VsZCBjcmVhdGUgbmV3IEluc3RhbmNlJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIEluc3RhbmNlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KG5ldyBQaXBlKCcnKSkudG8uYmUuaW5zdGFuY2VPZihQaXBlKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gSW5zdGFuY2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IFBpcGUoJ2luZGV4OmF8dG91cHBlciB8cHJlZml4OmEnKS5ydW4oe2E6IFwidGVzdFwifSkpLnRvLmJlLmVxdWFsKCdhVEVTVCcpO1xuICAgICAgICB9KTtcblxuICAgICAgICBbXG4gICAgICAgICAgICBbJ2luZGV4OmF8dG91cHBlciB8cHJlZml4OmEnLCB7YTogXCJ0ZXN0XCJ9LCAnYVRFU1QnXSxcbiAgICAgICAgICAgIFsncGF0aDphLmIuYy5kIHwgdG91cHBlciB8IHByZWZpeDpIZWxsb1xcXFwgJywge1xuICAgICAgICAgICAgICAgIGE6IHtcbiAgICAgICAgICAgICAgICAgICAgYjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgYzoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQ6IFwid29ybGRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSwgJ0hlbGxvIFdPUkxEJ10sXG4gICAgICAgICAgICBbJ3BhdGg6YS5iLmN8aW5kZXg6ZHx0b3VwcGVyIHxzdWZmaXg6eCcsIHthOiB7Yjoge2M6IHtkOiBcInRlc3RcIn19fX0sICdURVNUeCddLFxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYyA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpdCgnbmV3IFBpcGUoJyArIEpTT04uc3RyaW5naWZ5KGEpICsgJykucnVuKCcgKyBKU09OLnN0cmluZ2lmeShiKSArICcpIHNob3VsZCByZXR1cm4gJyArIEpTT04uc3RyaW5naWZ5KGMpICsgJyAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbGV0IHQgPSBuZXcgUGlwZShhKTtcbiAgICAgICAgICAgICAgICBleHBlY3QodC5ydW4oYikpLnRvLmJlLmVxdWFsKGMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCduZXcgUGlwZSBhbmQgbG9jYWxlJywgZnVuY3Rpb24gKCkge1xuXG5cbiAgICAgICAgbGV0IGh0bWwxID0gYFxuPGRpdiBpZD1cIm1vY2stdHJhbnNsYXRpb25zXCI+PC9kaXY+XG48c2NyaXB0IHR5cGU9XCJhcHBsaWNhdGlvbi9qc29uXCIgZGF0YS1tb25zdGVyLXJvbGU9XCJ0cmFuc2xhdGlvbnNcIj5cbiAgICB7XG4gICAgICAgIFwiNTFcIjogXCJ4eXpcIixcbiAgICAgICAgXCI1MlwiOiBcImFiY1wiLFxuICAgICAgICBcIjUzXCI6IFwiZGVmXCJcbiAgICB9XG48L3NjcmlwdD4gIFxuYDtcblxuICAgICAgICBiZWZvcmVFYWNoKChkb25lKSA9PiB7XG4gICAgICAgICAgICBsZXQgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgICAgIG1vY2tzLmlubmVySFRNTCA9IGh0bWwxO1xuICAgICAgICAgICAgbGV0IGVsZW0gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9jay10cmFuc2xhdGlvbnMnKTtcbiAgICAgICAgICAgIEVtYmVkLmFzc2lnblRyYW5zbGF0aW9uc1RvRWxlbWVudChlbGVtKS50aGVuKChvKSA9PiB7XG4gICAgICAgICAgICAgICAgZG9uZSgpXG4gICAgICAgICAgICB9KS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgICAgIGRvbmUoZSlcbiAgICAgICAgICAgIH0pXG5cblxuICAgICAgICB9KVxuXG4gICAgICAgIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICAgICAgICBsZXQgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgICAgIG1vY2tzLmlubmVySFRNTCA9IFwiXCI7XG4gICAgICAgIH0pXG5cbiAgICAgICAgYmVmb3JlKGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICBpbml0SlNET00oKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICBkb25lKClcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICBbXG4gICAgICAgICAgICBbJ3BhdGg6c3RhdHVzIHwgdG9zdHJpbmcgfCBpMThuJywge3N0YXR1czogNTF9LCBcInh5elwiXVxuXG5cbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBwaXBlID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgb2JqID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgZXhwZWN0ZWQgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ3Nob3VsZCB0cmFuc2Zvcm0oJyArIHBpcGUgKyAnKS5ydW4oJyArIEpTT04uc3RyaW5naWZ5KG9iaikgKyAnKSByZXR1cm4gJyArIEpTT04uc3RyaW5naWZ5KGV4cGVjdGVkKSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGxldCB0ID0gbmV3IFBpcGUocGlwZSk7XG4gICAgICAgICAgICAgICAgZXhwZWN0KHQucnVuKG9iaikpLnRvLmJlLmVxdWFsKGV4cGVjdGVkKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuXG5cbiAgICB9KVxuXG5cbn0pO1xuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgaXNGdW5jdGlvbiwgaXNPYmplY3QsIGlzU3RyaW5nIH0gZnJvbSBcIi4uL3R5cGVzL2lzLm1qc1wiO1xuaW1wb3J0IHsgdmFsaWRhdGVTdHJpbmcgfSBmcm9tIFwiLi4vdHlwZXMvdmFsaWRhdGUubWpzXCI7XG5pbXBvcnQgeyBjbG9uZSB9IGZyb20gXCIuLi91dGlsL2Nsb25lLm1qc1wiO1xuaW1wb3J0IHsgREVMSU1JVEVSLCBQYXRoZmluZGVyLCBXSUxEQ0FSRCB9IGZyb20gXCIuL3BhdGhmaW5kZXIubWpzXCI7XG5cbmV4cG9ydCB7IGJ1aWxkTWFwLCBQQVJFTlQsIGFzc2VtYmxlUGFydHMgfTtcblxuLyoqXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQG1lbWJlck9mIE1vbnN0ZXIuRGF0YVxuICovXG5jb25zdCBQQVJFTlQgPSBcIl5cIjtcblxuLyoqXG4gKiBNYXBzIGNhbiBiZSBlYXNpbHkgY3JlYXRlZCBmcm9tIGRhdGEgb2JqZWN0cyB3aXRoIHRoZSBoZWxwIG9mIHRoZSBmdW5jdGlvbiBgYnVpbGRNYXAoKWAuXG4gKlxuICogVGhlIHBhdGggY2FuIGJlIHNwZWNpZmllZCBhcyBlaXRoZXIgYSBzaW1wbGUgZGVmaW5pdGlvbiBhLmIuYyBvciBhIHRlbXBsYXRlICR7YS5iLmN9LlxuICogS2V5IGFuZCB2YWx1ZSBjYW4gYmUgZWl0aGVyIGEgZGVmaW5pdGlvbiBvciBhIHRlbXBsYXRlLiBUaGUga2V5IGRvZXMgbm90IGhhdmUgdG8gYmUgZGVmaW5lZC5cbiAqIFRoZSB0ZW1wbGF0ZXMgZGV0ZXJtaW5lIHRoZSBhcHBlYXJhbmNlIG9mIHRoZSBrZXlzIGFuZCB0aGUgdmFsdWUgb2YgdGhlIG1hcC4gRWl0aGVyIGEgc2luZ2xlIHZhbHVlXG4gKiBpZCBjYW4gYmUgdGFrZW4gb3IgYSBjb21wb3NpdGUga2V5ICR7aWR9ICR7bmFtZX0gY2FuIGJlIHVzZWQuXG4gKlxuICogSWYgeW91IHdhbnQgdG8gYWNjZXNzIHZhbHVlcyBvZiB0aGUgcGFyZW50IGRhdGEgc2V0LCB5b3UgaGF2ZSB0byB1c2UgdGhlIF4gY2hhcmFjdGVyLCBmb3IgZXhhbXBsZSAke2lkfSAke14ubmFtZX0uXG4gKlxuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL2RhdGEvYnVpbGRtYXAubWpzXG4gKiBAcGFyYW0geyp9IHN1YmplY3QgLSBUaGUgZGF0YSBvYmplY3QgZnJvbSB3aGljaCB0aGUgbWFwIHdpbGwgYmUgY3JlYXRlZFxuICogQHBhcmFtIHtzdHJpbmd8TW9uc3Rlci5EYXRhfmV4YW1wbGVTZWxlY3RvckNhbGxiYWNrfSBzZWxlY3RvciAtIFRoZSBwYXRoIHRvIHRoZSBkYXRhIG9iamVjdCwgb3IgYSBjYWxsYmFjayB0aGF0IHJldHVybnMgYSBtYXAuXG4gKiBAcGFyYW0ge3N0cmluZ30gW3ZhbHVlVGVtcGxhdGVdIC0gQSB0ZW1wbGF0ZSBmb3IgdGhlIHZhbHVlIG9mIHRoZSBtYXAuXG4gKiBAcGFyYW0ge3N0cmluZ30gW2tleVRlbXBsYXRlXSAtIEEgdGVtcGxhdGUgZm9yIHRoZSBrZXkgb2YgdGhlIG1hcC5cbiAqIEBwYXJhbSB7TW9uc3Rlci5EYXRhfmV4YW1wbGVGaWx0ZXJDYWxsYmFja30gW2ZpbHRlcl0gLSBBIGNhbGxiYWNrIGZ1bmN0aW9uIHRvIGZpbHRlciBvdXQgdmFsdWVzLlxuICogQHJldHVybiB7Kn0gLSBUaGUgY3JlYXRlZCBtYXAuXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5EYXRhXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IC0gSWYgdGhlIHZhbHVlIGlzIG5laXRoZXIgYSBzdHJpbmcgbm9yIGEgZnVuY3Rpb24uXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IC0gSWYgdGhlIHNlbGVjdG9yIGNhbGxiYWNrIGRvZXMgbm90IHJldHVybiBhIG1hcC5cbiAqKi9cbmZ1bmN0aW9uIGJ1aWxkTWFwKHN1YmplY3QsIHNlbGVjdG9yLCB2YWx1ZVRlbXBsYXRlLCBrZXlUZW1wbGF0ZSwgZmlsdGVyKSB7XG4gICAgcmV0dXJuIGFzc2VtYmxlUGFydHMoc3ViamVjdCwgc2VsZWN0b3IsIGZpbHRlciwgZnVuY3Rpb24gKHYsIGssIG0pIHtcbiAgICAgICAgayA9IGJ1aWxkKHYsIGtleVRlbXBsYXRlLCBrKTtcbiAgICAgICAgdiA9IGJ1aWxkKHYsIHZhbHVlVGVtcGxhdGUpO1xuICAgICAgICB0aGlzLnNldChrLCB2KTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBUaGUgYXNzZW1ibGVQYXJ0cyBmdW5jdGlvbiBpcyBhIHByaXZhdGUgZnVuY3Rpb24gdGhhdCBoZWxwcyBpbiBidWlsZGluZyBhIG1hcCBmcm9tIGEgc3ViamVjdCBvYmplY3QgYmFzZWQgb24gYSBwcm92aWRlZFxuICogc2VsZWN0b3IuIFRoZSBzZWxlY3RvciBjYW4gZWl0aGVyIGJlIGEgc3RyaW5nIG9yIGEgY2FsbGJhY2sgZnVuY3Rpb24uIFRoaXMgZnVuY3Rpb24gaXMgbWVhbnQgdG8gYmUgdXNlZCBhcyBhXG4gKiBoZWxwZXIgZnVuY3Rpb24gYnkgb3RoZXIgZnVuY3Rpb25zIGluIHRoZSBtb2R1bGUuXG4gKlxuICogVGhlIGZ1bmN0aW9uIHRha2VzIGZvdXIgcGFyYW1ldGVyczpcbiAqXG4gKiBzdWJqZWN0OiBUaGUgc3ViamVjdCBvYmplY3QgZnJvbSB3aGljaCB0aGUgbWFwIGlzIHRvIGJlIGJ1aWx0XG4gKiBzZWxlY3RvcjogVGhlIHNlbGVjdG9yIHRvIGRldGVybWluZSB0aGUgc3RydWN0dXJlIG9mIHRoZSBtYXAuIEl0IGNhbiBiZSBhIHN0cmluZyBvciBhIGNhbGxiYWNrIGZ1bmN0aW9uLlxuICogZmlsdGVyIChvcHRpb25hbCk6IEEgY2FsbGJhY2sgZnVuY3Rpb24gdGhhdCBjYW4gYmUgdXNlZCB0byBmaWx0ZXIgdmFsdWVzIGJhc2VkIG9uIHNvbWUgY3JpdGVyaWEuXG4gKiBjYWxsYmFjazogQSBmdW5jdGlvbiB0byBiZSBjYWxsZWQgZm9yIGVhY2ggZWxlbWVudCBpbiB0aGUgbWFwLlxuICogSWYgdGhlIHNlbGVjdG9yIHBhcmFtZXRlciBpcyBhIGNhbGxiYWNrIGZ1bmN0aW9uLCBpdCBpcyBleGVjdXRlZCBwYXNzaW5nIHRoZSBzdWJqZWN0IGFzIGl0cyBhcmd1bWVudCxcbiAqIGFuZCB0aGUgcmVzdWx0aW5nIHZhbHVlIG11c3QgYmUgYW4gaW5zdGFuY2Ugb2YgTWFwLiBPdGhlcndpc2UsIGlmIHRoZSBzZWxlY3RvciBwYXJhbWV0ZXIgaXMgYSBzdHJpbmcsXG4gKiBidWlsZEZsYXRNYXAgaXMgY2FsbGVkIHRvIGJ1aWxkIGEgZmxhdCBtYXAgd2l0aCBrZXlzIGFuZCB2YWx1ZXMgZXh0cmFjdGVkIGZyb20gdGhlIHN1YmplY3Qgb2JqZWN0IGJhc2VkIG9uIHRoZSBzZWxlY3Rvci5cbiAqXG4gKiBJZiB0aGUgZmlsdGVyIHBhcmFtZXRlciBpcyBwcm92aWRlZCwgaXQgd2lsbCBiZSB1c2VkIHRvIGZpbHRlciBvdXQgY2VydGFpbiBlbGVtZW50cyBmcm9tIHRoZSBtYXAsIGJhc2VkIG9uIHNvbWVcbiAqIGNyaXRlcmlhLiBUaGUgY2FsbGJhY2sgd2lsbCBiZSBwYXNzZWQgdGhlIHZhbHVlLCBrZXksIGFuZCBtYXAgb2JqZWN0LCBhbmQgaWYgaXQgcmV0dXJucyBmYWxzZSwgdGhlIGVsZW1lbnQgd2lsbCBiZSBza2lwcGVkLlxuICpcbiAqIEZvciBlYWNoIGVsZW1lbnQgaW4gdGhlIG1hcCwgdGhlIGNhbGxiYWNrIGZ1bmN0aW9uIGlzIGNhbGxlZCB3aXRoIHRoZSBmb2xsb3dpbmcgcGFyYW1ldGVyczpcbiAqXG4gKiB2OiBUaGUgdmFsdWUgb2YgdGhlIGVsZW1lbnRcbiAqIGs6IFRoZSBrZXkgb2YgdGhlIGVsZW1lbnRcbiAqIG06IFRoZSBtYXAgb2JqZWN0XG4gKiBUaGUgZnVuY3Rpb24gcmV0dXJucyBhIG5ldyBtYXAgd2l0aCB0aGUgcHJvY2Vzc2VkIHZhbHVlcy4gSWYgbWFwIGlzIG5vdCBhbiBpbnN0YW5jZSBvZiBNYXAsIGFuIGVtcHR5IG1hcCB3aWxsIGJlIHJldHVybmVkLlxuICpcbiAqIEV4YW1wbGUgVXNhZ2U6XG4gKlxuICogYGBgamF2YXNjcmlwdFxuICogY29uc3Qgb2JqID0ge1xuICogICBuYW1lOiBcIkpvaG5cIixcbiAqICAgYWdlOiAzMCxcbiAqICAgYWRkcmVzczoge1xuICogICAgIGNpdHk6IFwiTmV3IFlvcmtcIixcbiAqICAgICBzdGF0ZTogXCJOWVwiLFxuICogICAgIGNvdW50cnk6IFwiVVNBXCIsXG4gKiAgIH0sXG4gKiB9O1xuICpcbiAqIGNvbnN0IHNlbGVjdG9yID0gXCJhZGRyZXNzXCI7XG4gKlxuICogY29uc3QgbWFwID0gYXNzZW1ibGVQYXJ0cyhvYmosIHNlbGVjdG9yLCBudWxsLCBmdW5jdGlvbiAodiwgaywgbSkge1xuICogICB0aGlzLnNldChrLCB2KTtcbiAqIH0pO1xuICpcbiAqIGNvbnNvbGUubG9nKG1hcCk7XG4gKiAvLyBPdXRwdXQ6IE1hcCgzKSB7XG4gKiAvLyAgIFwiYWRkcmVzcy5jaXR5XCIgPT4gXCJOZXcgWW9ya1wiLFxuICogLy8gICBcImFkZHJlc3Muc3RhdGVcIiA9PiBcIk5ZXCIsXG4gKiAvLyAgIFwiYWRkcmVzcy5jb3VudHJ5XCIgPT4gXCJVU0FcIlxuICogLy8gfVxuICogYGBgXG4gKlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHN1YmplY3QgLSBUaGUgc3ViamVjdCBvYmplY3QgZnJvbSB3aGljaCB0aGUgbWFwIGlzIHRvIGJlIGJ1aWx0LlxuICogQHBhcmFtIHtzdHJpbmd8TW9uc3Rlci5EYXRhfmV4YW1wbGVTZWxlY3RvckNhbGxiYWNrfSBzZWxlY3RvciAtIFRoZSBzZWxlY3RvciB0byBkZXRlcm1pbmUgdGhlIHN0cnVjdHVyZSBvZiB0aGUgbWFwLiBJdCBjYW4gYmUgYSBzdHJpbmcgb3IgYSBjYWxsYmFjayBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7TW9uc3Rlci5EYXRhfmV4YW1wbGVGaWx0ZXJDYWxsYmFja30gW2ZpbHRlcl0gLSBBIGNhbGxiYWNrIGZ1bmN0aW9uIHRoYXQgY2FuIGJlIHVzZWQgdG8gZmlsdGVyIHZhbHVlcyBiYXNlZCBvbiBzb21lIGNyaXRlcmlhLlxuICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2sgLSBBIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCBmb3IgZWFjaCBlbGVtZW50IGluIHRoZSBtYXAuXG4gKiBAcmV0dXJuIHtNYXB9IC0gQSBuZXcgbWFwIHdpdGggdGhlIHByb2Nlc3NlZCB2YWx1ZXMuXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IC0gV2hlbiBzZWxlY3RvciBpcyBuZWl0aGVyIGEgc3RyaW5nIG5vciBhIGZ1bmN0aW9uLlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRGF0YVxuICovXG5mdW5jdGlvbiBhc3NlbWJsZVBhcnRzKHN1YmplY3QsIHNlbGVjdG9yLCBmaWx0ZXIsIGNhbGxiYWNrKSB7XG4gICAgY29uc3QgcmVzdWx0ID0gbmV3IE1hcCgpO1xuXG4gICAgbGV0IG1hcDtcbiAgICBpZiAoaXNGdW5jdGlvbihzZWxlY3RvcikpIHtcbiAgICAgICAgbWFwID0gc2VsZWN0b3Ioc3ViamVjdCk7XG4gICAgICAgIGlmICghKG1hcCBpbnN0YW5jZW9mIE1hcCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJ0aGUgc2VsZWN0b3IgY2FsbGJhY2sgbXVzdCByZXR1cm4gYSBtYXBcIik7XG4gICAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGlzU3RyaW5nKHNlbGVjdG9yKSkge1xuICAgICAgICBtYXAgPSBuZXcgTWFwKCk7XG4gICAgICAgIGJ1aWxkRmxhdE1hcC5jYWxsKG1hcCwgc3ViamVjdCwgc2VsZWN0b3IpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJzZWxlY3RvciBpcyBuZWl0aGVyIGEgc3RyaW5nIG5vciBhIGZ1bmN0aW9uXCIpO1xuICAgIH1cblxuICAgIGlmICghKG1hcCBpbnN0YW5jZW9mIE1hcCkpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICBtYXAuZm9yRWFjaCgodiwgaywgbSkgPT4ge1xuICAgICAgICBpZiAoaXNGdW5jdGlvbihmaWx0ZXIpKSB7XG4gICAgICAgICAgICBpZiAoZmlsdGVyLmNhbGwobSwgdiwgaykgIT09IHRydWUpIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNhbGxiYWNrLmNhbGwocmVzdWx0LCB2LCBrLCBtKTtcbiAgICB9KTtcblxuICAgIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSBzdWJqZWN0XG4gKiBAcGFyYW0gc2VsZWN0b3JcbiAqIEBwYXJhbSBrZXlcbiAqIEBwYXJhbSBwYXJlbnRNYXBcbiAqIEByZXR1cm4geyp9XG4gKi9cbmZ1bmN0aW9uIGJ1aWxkRmxhdE1hcChzdWJqZWN0LCBzZWxlY3Rvciwga2V5LCBwYXJlbnRNYXApIHtcbiAgICBjb25zdCByZXN1bHQgPSB0aGlzO1xuICAgIGNvbnN0IGN1cnJlbnRNYXAgPSBuZXcgTWFwKCk7XG5cbiAgICBjb25zdCByZXN1bHRMZW5ndGggPSByZXN1bHQuc2l6ZTtcblxuICAgIGlmIChrZXkgPT09IHVuZGVmaW5lZCkga2V5ID0gW107XG5cbiAgICBsZXQgcGFydHMgPSBzZWxlY3Rvci5zcGxpdChERUxJTUlURVIpO1xuICAgIGxldCBjdXJyZW50ID0gXCJcIjtcbiAgICBsZXQgY3VycmVudFBhdGggPSBbXTtcbiAgICBkbyB7XG4gICAgICAgIGN1cnJlbnQgPSBwYXJ0cy5zaGlmdCgpO1xuICAgICAgICBjdXJyZW50UGF0aC5wdXNoKGN1cnJlbnQpO1xuXG4gICAgICAgIGlmIChjdXJyZW50ID09PSBXSUxEQ0FSRCkge1xuICAgICAgICAgICAgbGV0IGZpbmRlciA9IG5ldyBQYXRoZmluZGVyKHN1YmplY3QpO1xuICAgICAgICAgICAgbGV0IG1hcDtcblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBtYXAgPSBmaW5kZXIuZ2V0VmlhKGN1cnJlbnRQYXRoLmpvaW4oREVMSU1JVEVSKSk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgbGV0IGEgPSBlO1xuICAgICAgICAgICAgICAgIG1hcCA9IG5ldyBNYXAoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZm9yIChjb25zdCBbaywgb10gb2YgbWFwKSB7XG4gICAgICAgICAgICAgICAgbGV0IGNvcHlLZXkgPSBjbG9uZShrZXkpO1xuXG4gICAgICAgICAgICAgICAgY3VycmVudFBhdGgubWFwKChhKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvcHlLZXkucHVzaChhID09PSBXSUxEQ0FSRCA/IGsgOiBhKTtcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIGxldCBrayA9IGNvcHlLZXkuam9pbihERUxJTUlURVIpO1xuICAgICAgICAgICAgICAgIGxldCBzdWIgPSBidWlsZEZsYXRNYXAuY2FsbChyZXN1bHQsIG8sIHBhcnRzLmpvaW4oREVMSU1JVEVSKSwgY29weUtleSwgbyk7XG5cbiAgICAgICAgICAgICAgICBpZiAoaXNPYmplY3Qoc3ViKSAmJiBwYXJlbnRNYXAgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICBzdWJbUEFSRU5UXSA9IHBhcmVudE1hcDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjdXJyZW50TWFwLnNldChraywgc3ViKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0gd2hpbGUgKHBhcnRzLmxlbmd0aCA+IDApO1xuXG4gICAgLy8gbm8gc2V0IGluIGNoaWxkIHJ1blxuICAgIGlmIChyZXN1bHRMZW5ndGggPT09IHJlc3VsdC5zaXplKSB7XG4gICAgICAgIGZvciAoY29uc3QgW2ssIG9dIG9mIGN1cnJlbnRNYXApIHtcbiAgICAgICAgICAgIHJlc3VsdC5zZXQoaywgbyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gc3ViamVjdDtcbn1cblxuLyoqXG4gKiBXaXRoIHRoZSBoZWxwIG9mIHRoaXMgZmlsdGVyIGNhbGxiYWNrLCB2YWx1ZXMgY2FuIGJlIGZpbHRlcmVkIG91dC4gT25seSBpZiB0aGUgZmlsdGVyIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZSwgdGhlIHZhbHVlIGlzIHRha2VuIGZvciB0aGUgbWFwLlxuICpcbiAqIEBjYWxsYmFjayBNb25zdGVyLkRhdGF+ZXhhbXBsZUZpbHRlckNhbGxiYWNrXG4gKiBAcGFyYW0geyp9IHZhbHVlIFZhbHVlXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5ICBLZXlcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRhdGFcbiAqIEBzZWUge0BsaW5rIE1vbnN0ZXIuRGF0YS5idWlsZE1hcH1cbiAqL1xuXG4vKipcbiAqIEFsdGVybmF0aXZlbHkgdG8gYSBzdHJpbmcgc2VsZWN0b3IgYSBjYWxsYmFjayBjYW4gYmUgc3BlY2lmaWVkLiB0aGlzIG11c3QgcmV0dXJuIGEgbWFwLlxuICpcbiAqIEBleGFtcGxlXG4gKiBpbXBvcnQge2J1aWxkTWFwfSBmcm9tICdAc2NodWthaS9tb25zdGVyL3NvdXJjZS9kYXRhL2J1aWxkbWFwLm1qcyc7XG4gKlxuICogbGV0IG9iaiA9IHtcbiAqICAgICAgICAgICAgICAgIFwiZGF0YVwiOiBbXG4gKiAgICAgICAgICAgICAgICAgICAge1xuICogICAgICAgICAgICAgICAgICAgICAgICBcImlkXCI6IDEwLFxuICogICAgICAgICAgICAgICAgICAgICAgICBcIm5hbWVcIjogXCJDYXNzYW5kcmFcIixcbiAqICAgICAgICAgICAgICAgICAgICAgICAgXCJlbnJpY2htZW50XCI6IHtcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhcmlhbnRzOiBbXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBza3U6IDEsIGxhYmVsOiBcIlhYU1wiLCBwcmljZTogW1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnMTIuMTIgXHUyMEFDJ30sXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICcxMi4xMiBcdTIwQUMnfVxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNrdTogMiwgbGFiZWw6IFwiWFNcIiwgcHJpY2U6IFtcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt2azogJzIyLjEyIFx1MjBBQyd9LFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnMjIuMTIgXHUyMEFDJ31cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBza3U6IDMsIGxhYmVsOiBcIlNcIiwgcHJpY2U6IFtcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt2azogJzMyLjEyIFx1MjBBQyd9LFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnMzIuMTIgXHUyMEFDJ31cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBza3U6IDQsIGxhYmVsOiBcIkxcIiwgcHJpY2U6IFtcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt2azogJzQyLjEyIFx1MjBBQyd9LFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnNDIuMTIgXHUyMEFDJ31cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIF1cbiAqXG4gKiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAqICAgICAgICAgICAgICAgICAgICB9LFxuICogICAgICAgICAgICAgICAgICAgIHtcbiAqICAgICAgICAgICAgICAgICAgICAgICAgXCJpZFwiOiAyMCxcbiAqICAgICAgICAgICAgICAgICAgICAgICAgXCJuYW1lXCI6IFwiWWVzc2V5IVwiLFxuICogICAgICAgICAgICAgICAgICAgICAgICBcImVucmljaG1lbnRcIjoge1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyaWFudHM6IFtcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNrdTogMSwgbGFiZWw6IFwiWFhTXCIsIHByaWNlOiBbXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICcxMi4xMiBcdTIwQUMnfSxcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt2azogJzEyLjEyIFx1MjBBQyd9XG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF1cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2t1OiAyLCBsYWJlbDogXCJYU1wiLCBwcmljZTogW1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnMjIuMTIgXHUyMEFDJ30sXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICcyMi4xMiBcdTIwQUMnfVxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNrdTogMywgbGFiZWw6IFwiU1wiLCBwcmljZTogW1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnMzIuMTIgXHUyMEFDJ30sXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICczMi4xMiBcdTIwQUMnfVxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNrdTogNCwgbGFiZWw6IFwiTFwiLCBwcmljZTogW1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnNDIuMTIgXHUyMEFDJ30sXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICc0Mi4xMiBcdTIwQUMnfVxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuICpcbiAqICAgICAgICAgICAgICAgICAgICAgICAgfVxuICogICAgICAgICAgICAgICAgICAgIH1cbiAqICAgICAgICAgICAgICAgIF1cbiAqICAgICAgICAgICAgfTtcbiAqXG4gKiBsZXQgY2FsbGJhY2sgPSBmdW5jdGlvbiAoc3ViamVjdCkge1xuICogICAgICAgICAgICAgICAgbGV0IG0gPSBuZXcgTWFwO1xuICpcbiAqICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW2ksIGJdIG9mIE9iamVjdC5lbnRyaWVzKHN1YmplY3QuZGF0YSkpIHtcbiAqXG4gKiAgICAgICAgICAgICAgICAgICAgbGV0IGtleTEgPSBpO1xuICpcbiAqICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IFtqLCBjXSBvZiBPYmplY3QuZW50cmllcyhiLmVucmljaG1lbnQudmFyaWFudHMpKSB7XG4gKiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBrZXkyID0gajtcbiAqXG4gKiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW2ssIGRdIG9mIE9iamVjdC5lbnRyaWVzKGMucHJpY2UpKSB7XG4gKlxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGtleTMgPSBrO1xuICpcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQubmFtZSA9IGIubmFtZTtcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQubGFiZWwgPSBjLmxhYmVsO1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgZC5pZCA9IFtrZXkxLCBrZXkyLCBrZXkzXS5qb2luKCcuJyk7XG4gKlxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgbS5zZXQoZC5pZCwgZCk7XG4gKiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAqXG4gKiAgICAgICAgICAgICAgICAgICAgfVxuICogICAgICAgICAgICAgICAgfVxuICogICAgICAgICAgICAgICAgcmV0dXJuIG07XG4gKiAgICAgICAgICAgIH1cbiAqXG4gKiBsZXQgbWFwID0gYnVpbGRNYXAob2JqLCBjYWxsYmFjaywgJyR7bmFtZX0gJHt2a30nLCAnJHtpZH0nKVxuICpcbiAqIC8vIFx1MjFBNiBNYXAoMykge1xuICogLy8gIFwiMC4wLjBcIjpcIkNhc3NhbmRyYSAxMi4xMiBcdTIwQUNcIixcbiAqIC8vICBcIjAuMC4xXCI6XCJDYXNzYW5kcmEgMTIuMTIgXHUyMEFDXCIsXG4gKiAvLyAgXCIwLjEuMFwiOlwiQ2Fzc2FuZHJhIDIyLjEyIFx1MjBBQ1wiLFxuICogLy8gIFwiMC4xLjFcIjpcIkNhc3NhbmRyYSAyMi4xMiBcdTIwQUNcIixcbiAqIC8vICBcIjAuMi4wXCI6XCJDYXNzYW5kcmEgMzIuMTIgXHUyMEFDXCIsXG4gKiAvLyAgXCIwLjIuMVwiOlwiQ2Fzc2FuZHJhIDMyLjEyIFx1MjBBQ1wiLFxuICogLy8gIFwiMC4zLjBcIjpcIkNhc3NhbmRyYSA0Mi4xMiBcdTIwQUNcIixcbiAqIC8vICBcIjAuMy4xXCI6XCJDYXNzYW5kcmEgNDIuMTIgXHUyMEFDXCIsXG4gKiAvLyAgXCIxLjAuMFwiOlwiWWVzc2V5ISAxMi4xMiBcdTIwQUNcIixcbiAqIC8vICBcIjEuMC4xXCI6XCJZZXNzZXkhIDEyLjEyIFx1MjBBQ1wiLFxuICogLy8gIFwiMS4xLjBcIjpcIlllc3NleSEgMjIuMTIgXHUyMEFDXCIsXG4gKiAvLyAgXCIxLjEuMVwiOlwiWWVzc2V5ISAyMi4xMiBcdTIwQUNcIixcbiAqIC8vICBcIjEuMi4wXCI6XCJZZXNzZXkhIDMyLjEyIFx1MjBBQ1wiLFxuICogLy8gIFwiMS4yLjFcIjpcIlllc3NleSEgMzIuMTIgXHUyMEFDXCIsXG4gKiAvLyAgXCIxLjMuMFwiOlwiWWVzc2V5ISA0Mi4xMiBcdTIwQUNcIixcbiAqIC8vICBcIjEuMy4xXCI6XCJZZXNzZXkhIDQyLjEyIFx1MjBBQ1wiXG4gKiAvLyB9XG4gKlxuICogQGNhbGxiYWNrIE1vbnN0ZXIuRGF0YX5leGFtcGxlU2VsZWN0b3JDYWxsYmFja1xuICogQHBhcmFtIHsqfSBzdWJqZWN0IHN1YmplY3RcbiAqIEByZXR1cm4gTWFwXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjE3LjBcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRhdGFcbiAqIEBzZWUge0BsaW5rIE1vbnN0ZXIuRGF0YS5idWlsZE1hcH1cbiAqL1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHN1YmplY3RcbiAqIEBwYXJhbSB7c3RyaW5nfHVuZGVmaW5lZH0gZGVmaW5pdGlvblxuICogQHBhcmFtIHsqfSBkZWZhdWx0VmFsdWVcbiAqIEByZXR1cm4geyp9XG4gKi9cbmZ1bmN0aW9uIGJ1aWxkKHN1YmplY3QsIGRlZmluaXRpb24sIGRlZmF1bHRWYWx1ZSkge1xuICAgIGlmIChkZWZpbml0aW9uID09PSB1bmRlZmluZWQpIHJldHVybiBkZWZhdWx0VmFsdWUgPyBkZWZhdWx0VmFsdWUgOiBzdWJqZWN0O1xuICAgIHZhbGlkYXRlU3RyaW5nKGRlZmluaXRpb24pO1xuXG4gICAgY29uc3QgcmVnZXhwID0gLyg/PHBsYWNlaG9sZGVyPlxcJHsoPzxwYXRoPlthLXpcXF5BLVouXFwtXzAtOV0qKX0pL2dtO1xuICAgIGNvbnN0IGFycmF5ID0gWy4uLmRlZmluaXRpb24ubWF0Y2hBbGwocmVnZXhwKV07XG5cbiAgICBsZXQgZmluZGVyID0gbmV3IFBhdGhmaW5kZXIoc3ViamVjdCk7XG5cbiAgICBpZiAoYXJyYXkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiBmaW5kZXIuZ2V0VmlhKGRlZmluaXRpb24pO1xuICAgIH1cblxuICAgIGFycmF5LmZvckVhY2goKGEpID0+IHtcbiAgICAgICAgbGV0IGdyb3VwcyA9IGE/LltcImdyb3Vwc1wiXTtcbiAgICAgICAgbGV0IHBsYWNlaG9sZGVyID0gZ3JvdXBzPy5bXCJwbGFjZWhvbGRlclwiXTtcbiAgICAgICAgaWYgKHBsYWNlaG9sZGVyID09PSB1bmRlZmluZWQpIHJldHVybjtcblxuICAgICAgICBsZXQgcGF0aCA9IGdyb3Vwcz8uW1wicGF0aFwiXTtcblxuICAgICAgICBsZXQgdiA9IGZpbmRlci5nZXRWaWEocGF0aCk7XG4gICAgICAgIGlmICh2ID09PSB1bmRlZmluZWQpIHYgPSBkZWZhdWx0VmFsdWU7XG5cbiAgICAgICAgZGVmaW5pdGlvbiA9IGRlZmluaXRpb24ucmVwbGFjZUFsbChwbGFjZWhvbGRlciwgdik7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gZGVmaW5pdGlvbjtcbn1cbiIsICJcInVzZSBzdHJpY3RcIjtcblxuaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7YnVpbGRNYXB9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvZGF0YS9idWlsZG1hcC5tanNcIjtcblxuXG5kZXNjcmliZSgnYnVpbGRNYXAnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBsZXQgY29udmVydE1hcFJlc3VsdCA9IGZ1bmN0aW9uIChyKSB7XG4gICAgICAgIGlmIChyIGluc3RhbmNlb2YgTWFwKSB7XG4gICAgICAgICAgICByID0gT2JqZWN0LmZyb21FbnRyaWVzKHIpO1xuICAgICAgICAgICAgaWYgKHIgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAgICAgICAgIHIgPSByLm1hcCgoZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29udmVydE1hcFJlc3VsdChlKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgciA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW2ssIG9dIG9mIE9iamVjdC5lbnRyaWVzKHIpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJba10gPSBjb252ZXJ0TWFwUmVzdWx0KG8pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByO1xuICAgIH1cblxuICAgIGRlc2NyaWJlKCdidWlsZCBNYXAgd2l0aCBjYWxsYmFjaycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ2RlZmluaXRpb24gc2hvdWxkIHJldHVybiBtYXAgd2l0aCBzdWIgYW5kIHBhcmVudCBrZXlzJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBsZXQgb2JqID0ge1xuICAgICAgICAgICAgICAgIFwiZGF0YVwiOiBbXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiaWRcIjogMTAsXG4gICAgICAgICAgICAgICAgICAgICAgICBcIm5hbWVcIjogXCJDYXNzYW5kcmFcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiZW5yaWNobWVudFwiOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyaWFudHM6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2t1OiAxLCBsYWJlbDogXCJYWFNcIiwgcHJpY2U6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICcxMi4xMiBcdTIwQUMnfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICcxMi4xMiBcdTIwQUMnfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBza3U6IDIsIGxhYmVsOiBcIlhTXCIsIHByaWNlOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnMjIuMTIgXHUyMEFDJ30sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnMjIuMTIgXHUyMEFDJ31cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2t1OiAzLCBsYWJlbDogXCJTXCIsIHByaWNlOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnMzIuMTIgXHUyMEFDJ30sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnMzIuMTIgXHUyMEFDJ31cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2t1OiA0LCBsYWJlbDogXCJMXCIsIHByaWNlOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnNDIuMTIgXHUyMEFDJ30sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnNDIuMTIgXHUyMEFDJ31cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF1cblxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBcImlkXCI6IDIwLFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJuYW1lXCI6IFwiWWVzc2V5IVwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJlbnJpY2htZW50XCI6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXJpYW50czogW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBza3U6IDEsIGxhYmVsOiBcIlhYU1wiLCBwcmljZTogW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt2azogJzEyLjEyIFx1MjBBQyd9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt2azogJzEyLjEyIFx1MjBBQyd9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNrdTogMiwgbGFiZWw6IFwiWFNcIiwgcHJpY2U6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICcyMi4xMiBcdTIwQUMnfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICcyMi4xMiBcdTIwQUMnfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBza3U6IDMsIGxhYmVsOiBcIlNcIiwgcHJpY2U6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICczMi4xMiBcdTIwQUMnfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICczMi4xMiBcdTIwQUMnfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBza3U6IDQsIGxhYmVsOiBcIkxcIiwgcHJpY2U6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICc0Mi4xMiBcdTIwQUMnfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICc0Mi4xMiBcdTIwQUMnfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBsZXQgY2FsbGJhY2sgPSBmdW5jdGlvbiAoc3ViamVjdCkge1xuICAgICAgICAgICAgICAgIGxldCBtID0gbmV3IE1hcDtcblxuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW2ksIGJdIG9mIE9iamVjdC5lbnRyaWVzKHN1YmplY3QuZGF0YSkpIHtcblxuICAgICAgICAgICAgICAgICAgICBsZXQga2V5MSA9IGk7XG5cbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBbaiwgY10gb2YgT2JqZWN0LmVudHJpZXMoYi5lbnJpY2htZW50LnZhcmlhbnRzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGtleTIgPSBqO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IFtrLCBkXSBvZiBPYmplY3QuZW50cmllcyhjLnByaWNlKSkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGtleTMgPSBrO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZC5uYW1lID0gYi5uYW1lO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQubGFiZWwgPSBjLmxhYmVsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQuaWQgPSBba2V5MSwga2V5Miwga2V5M10uam9pbignLicpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbS5zZXQoZC5pZCwgZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gbTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGV0IG1hcCA9IGJ1aWxkTWFwKG9iaiwgY2FsbGJhY2ssICcke25hbWV9ICR7bGFiZWx9JywgJyR7aWR9JylcbiAgICAgICAgICAgIGxldCBpID0gY29udmVydE1hcFJlc3VsdChtYXApO1xuXG4gICAgICAgICAgICBleHBlY3QoSlNPTi5zdHJpbmdpZnkoaSkpLnRvLmJlLmVxdWFsKCd7XCIwLjAuMFwiOlwiQ2Fzc2FuZHJhIFhYU1wiLFwiMC4wLjFcIjpcIkNhc3NhbmRyYSBYWFNcIixcIjAuMS4wXCI6XCJDYXNzYW5kcmEgWFNcIixcIjAuMS4xXCI6XCJDYXNzYW5kcmEgWFNcIixcIjAuMi4wXCI6XCJDYXNzYW5kcmEgU1wiLFwiMC4yLjFcIjpcIkNhc3NhbmRyYSBTXCIsXCIwLjMuMFwiOlwiQ2Fzc2FuZHJhIExcIixcIjAuMy4xXCI6XCJDYXNzYW5kcmEgTFwiLFwiMS4wLjBcIjpcIlllc3NleSEgWFhTXCIsXCIxLjAuMVwiOlwiWWVzc2V5ISBYWFNcIixcIjEuMS4wXCI6XCJZZXNzZXkhIFhTXCIsXCIxLjEuMVwiOlwiWWVzc2V5ISBYU1wiLFwiMS4yLjBcIjpcIlllc3NleSEgU1wiLFwiMS4yLjFcIjpcIlllc3NleSEgU1wiLFwiMS4zLjBcIjpcIlllc3NleSEgTFwiLFwiMS4zLjFcIjpcIlllc3NleSEgTFwifScpO1xuXG4gICAgICAgIH0pXG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCdidWlsZCBzdWJtYXAgd2l0aCAqJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnZGVmaW5pdGlvbiBzaG91bGQgcmV0dXJuIHtcIjEwXCI6XCJDYXNzYW5kcmEgMTBcIixcIjIwXCI6XCJZZXNzZXkhIDIwXCJ9JywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBsZXQgb2JqID0ge1xuICAgICAgICAgICAgICAgIFwiZGF0YVwiOiBbXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiaWRcIjogMTAsXG4gICAgICAgICAgICAgICAgICAgICAgICBcIm5hbWVcIjogXCJDYXNzYW5kcmFcIlxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBcImlkXCI6IDIwLFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJuYW1lXCI6IFwiWWVzc2V5IVwiLFxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgbGV0IG1hcCA9IGJ1aWxkTWFwKG9iaiwgJ2RhdGEuKicsICcke25hbWV9ICR7aWR9JywgJyR7aWR9JylcbiAgICAgICAgICAgIGxldCBpID0gY29udmVydE1hcFJlc3VsdChtYXApO1xuICAgICAgICAgICAgZXhwZWN0KEpTT04uc3RyaW5naWZ5KGkpKS50by5iZS5lcXVhbCgne1wiMTBcIjpcIkNhc3NhbmRyYSAxMFwiLFwiMjBcIjpcIlllc3NleSEgMjBcIn0nKTtcblxuICAgICAgICB9KVxuICAgIH0pXG5cblxuICAgIGRlc2NyaWJlKCdidWlsZCBzdWJtYXAgd2l0aCAqKicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ2RlZmluaXRpb24gc2hvdWxkIHJldHVybiBNYXAnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIGxldCBvYmogPSB7XG4gICAgICAgICAgICAgICAgXCJkYXRhXCI6IFtcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgXCJpZFwiOiAxMCxcbiAgICAgICAgICAgICAgICAgICAgICAgIFwibmFtZVwiOiBcIkNhc3NhbmRyYVwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJlbnJpY2htZW50XCI6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXJpYW50czogW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBza3U6IDEsIGxhYmVsOiBcIlhYU1wiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpY2U6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICcxMi4xMiBcdTIwQUMnLCBpZDogMX0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnMTIuMTIgXHUyMEFDJywgaWQ6IDJ9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNrdTogMiwgbGFiZWw6IFwiWFNcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaWNlOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnMjIuMTIgXHUyMEFDJywgaWQ6IDN9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt2azogJzIyLjEyIFx1MjBBQycsIGlkOiA0fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBza3U6IDMsIGxhYmVsOiBcIlNcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaWNlOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnMzIuMTIgXHUyMEFDJywgaWQ6IDV9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt2azogJzMyLjEyIFx1MjBBQycsIGlkOiA2fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBza3U6IDQsIGxhYmVsOiBcIkxcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaWNlOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnNDIuMTIgXHUyMEFDJywgaWQ6IDd9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt2azogJzQyLjEyIFx1MjBBQycsIGlkOiA4fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiaWRcIjogMjAsXG4gICAgICAgICAgICAgICAgICAgICAgICBcIm5hbWVcIjogXCJZZXNzZXkhXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBcImVucmljaG1lbnRcIjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhcmlhbnRzOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNrdTogMSwgbGFiZWw6IFwiWFhTXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmljZTogW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt2azogJzEyLjEyIFx1MjBBQycsIGlkOiA5fSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICcxMi4xMiBcdTIwQUMnLCBpZDogMTB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNrdTogMiwgbGFiZWw6IFwiWFNcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaWNlOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnMjIuMTIgXHUyMEFDJywgaWQ6IDExfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICcyMi4xMiBcdTIwQUMnLCBpZDogMTJ9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNrdTogMywgbGFiZWw6IFwiU1wiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpY2U6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICczMi4xMiBcdTIwQUMnLCBpZDogMTN9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt2azogJzMyLjEyIFx1MjBBQycsIGlkOiAxNH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2t1OiA0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw6IFwiTFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpY2U6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICc0Mi4xMiBcdTIwQUMnLCBpZDogMTV9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt2azogJzQyLjEyIFx1MjBBQycsIGlkOiAxNn0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnNDQuMTIgXHUyMEFDJywgaWQ6IDE3fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBsZXQgbWFwID0gYnVpbGRNYXAob2JqLCAnZGF0YS4qLmVucmljaG1lbnQudmFyaWFudHMuKi5wcmljZS4qJywgJyR7dmt9ICR7Xi5sYWJlbH0gJHteLl4ubmFtZX0nLCAnJHteLl4uc2t1fScpXG4gICAgICAgICAgICBsZXQgaSA9IGNvbnZlcnRNYXBSZXN1bHQobWFwKTtcbiAgICAgICAgICAgIGV4cGVjdChKU09OLnN0cmluZ2lmeShpKSkudG8uYmUuZXF1YWwoJ3tcImRhdGEuMC5lbnJpY2htZW50LnZhcmlhbnRzLjAucHJpY2UuMFwiOlwiMTIuMTIgXHUyMEFDIFhYUyBDYXNzYW5kcmFcIixcImRhdGEuMC5lbnJpY2htZW50LnZhcmlhbnRzLjAucHJpY2UuMVwiOlwiMTIuMTIgXHUyMEFDIFhYUyBDYXNzYW5kcmFcIixcImRhdGEuMC5lbnJpY2htZW50LnZhcmlhbnRzLjEucHJpY2UuMFwiOlwiMjIuMTIgXHUyMEFDIFhTIENhc3NhbmRyYVwiLFwiZGF0YS4wLmVucmljaG1lbnQudmFyaWFudHMuMS5wcmljZS4xXCI6XCIyMi4xMiBcdTIwQUMgWFMgQ2Fzc2FuZHJhXCIsXCJkYXRhLjAuZW5yaWNobWVudC52YXJpYW50cy4yLnByaWNlLjBcIjpcIjMyLjEyIFx1MjBBQyBTIENhc3NhbmRyYVwiLFwiZGF0YS4wLmVucmljaG1lbnQudmFyaWFudHMuMi5wcmljZS4xXCI6XCIzMi4xMiBcdTIwQUMgUyBDYXNzYW5kcmFcIixcImRhdGEuMC5lbnJpY2htZW50LnZhcmlhbnRzLjMucHJpY2UuMFwiOlwiNDIuMTIgXHUyMEFDIEwgQ2Fzc2FuZHJhXCIsXCJkYXRhLjAuZW5yaWNobWVudC52YXJpYW50cy4zLnByaWNlLjFcIjpcIjQyLjEyIFx1MjBBQyBMIENhc3NhbmRyYVwiLFwiZGF0YS4xLmVucmljaG1lbnQudmFyaWFudHMuMC5wcmljZS4wXCI6XCIxMi4xMiBcdTIwQUMgWFhTIFllc3NleSFcIixcImRhdGEuMS5lbnJpY2htZW50LnZhcmlhbnRzLjAucHJpY2UuMVwiOlwiMTIuMTIgXHUyMEFDIFhYUyBZZXNzZXkhXCIsXCJkYXRhLjEuZW5yaWNobWVudC52YXJpYW50cy4xLnByaWNlLjBcIjpcIjIyLjEyIFx1MjBBQyBYUyBZZXNzZXkhXCIsXCJkYXRhLjEuZW5yaWNobWVudC52YXJpYW50cy4xLnByaWNlLjFcIjpcIjIyLjEyIFx1MjBBQyBYUyBZZXNzZXkhXCIsXCJkYXRhLjEuZW5yaWNobWVudC52YXJpYW50cy4yLnByaWNlLjBcIjpcIjMyLjEyIFx1MjBBQyBTIFllc3NleSFcIixcImRhdGEuMS5lbnJpY2htZW50LnZhcmlhbnRzLjIucHJpY2UuMVwiOlwiMzIuMTIgXHUyMEFDIFMgWWVzc2V5IVwiLFwiZGF0YS4xLmVucmljaG1lbnQudmFyaWFudHMuMy5wcmljZS4wXCI6XCI0Mi4xMiBcdTIwQUMgTCBZZXNzZXkhXCIsXCJkYXRhLjEuZW5yaWNobWVudC52YXJpYW50cy4zLnByaWNlLjFcIjpcIjQyLjEyIFx1MjBBQyBMIFllc3NleSFcIixcImRhdGEuMS5lbnJpY2htZW50LnZhcmlhbnRzLjMucHJpY2UuMlwiOlwiNDQuMTIgXHUyMEFDIEwgWWVzc2V5IVwifScpO1xuXG4gICAgICAgIH0pXG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCdleGFtcGxlY29kZScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBpdCgnc2hvdWxkIGV4ZWN1dGUgZXhhbXBsZSBjb2RlJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBsZXQgb2JqID0ge1xuICAgICAgICAgICAgICAgIFwiZGF0YVwiOiBbXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiaWRcIjogMTAsXG4gICAgICAgICAgICAgICAgICAgICAgICBcIm5hbWVcIjogXCJDYXNzYW5kcmFcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiYWRkcmVzc1wiOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJzdHJlZXRcIjogXCI0OTMtNDEwNSBWdWxwdXRhdGUgU3RyZWV0XCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJjaXR5XCI6IFwiU2F1bXVyXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJ6aXBcIjogXCI1MjYyOFwiXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiaWRcIjogMjAsXG4gICAgICAgICAgICAgICAgICAgICAgICBcIm5hbWVcIjogXCJIb2xseVwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJhZGRyZXNzXCI6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcInN0cmVldFwiOiBcIjE3NjIgRWdldCBSZC5cIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImNpdHlcIjogXCJTY2h3YWxiYWNoXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJ6aXBcIjogXCI5NTIzNDBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBcImlkXCI6IDMwLFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJuYW1lXCI6IFwiR3V5XCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBcImFkZHJlc3NcIjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwic3RyZWV0XCI6IFwiOTU3LTM4OCBTb2xsaWNpdHVkaW4gQXZlbnVlXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJjaXR5XCI6IFwiUGFuY2hpXHUwMEUwXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJ6aXBcIjogXCI0MjA3MjlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgbGV0IG1hcDtcbiAgICAgICAgICAgIG1hcCA9IGJ1aWxkTWFwKG9iaiwgJ2RhdGEuKicsICcke25hbWV9ICgke2FkZHJlc3MuemlwfSAke2FkZHJlc3MuY2l0eX0pJywgJ2lkJylcbiAgICAgICAgICAgIGV4cGVjdChtYXApLnRvLmJlLmluc3RhbmNlT2YoTWFwKTtcblxuICAgICAgICAgICAgbWFwID0gYnVpbGRNYXAob2JqLCAnZGF0YS4qJywgJyR7bmFtZX0gKCR7YWRkcmVzcy56aXB9ICR7YWRkcmVzcy5jaXR5fSknKVxuICAgICAgICAgICAgZXhwZWN0KG1hcCkudG8uYmUuaW5zdGFuY2VPZihNYXApO1xuXG4gICAgICAgICAgICBtYXAgPSBidWlsZE1hcChvYmosICdkYXRhLionLCAnJHtuYW1lfSAoJHthZGRyZXNzLnppcH0gJHthZGRyZXNzLmNpdHl9KScsICdpZCcsIGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuICh2YWx1ZVsnaWQnXSA+PSAyMCkgPyB0cnVlIDogZmFsc2VcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICBleHBlY3QobWFwKS50by5iZS5pbnN0YW5jZU9mKE1hcCk7XG4gICAgICAgIH0pO1xuXG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCdidWlsZG1hcCgpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGxldCBvYmoxID0ge1xuICAgICAgICAgICAgZGF0YXNldDoge1xuICAgICAgICAgICAgICAgIFwiMTAwODJcIjoge1xuICAgICAgICAgICAgICAgICAgICBuYW1lOiBcIlRlc3QgMVwiLFxuICAgICAgICAgICAgICAgICAgICBhZGRyZXNzOiBcIkhlcmUgMVwiXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBcIjEwMDg0XCI6IHtcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogXCJUZXN0IDJcIixcbiAgICAgICAgICAgICAgICAgICAgYWRkcmVzczogXCJIZXJlIDJcIlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBNYXAgSW5zdGFuY2UuJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KGJ1aWxkTWFwKHt9LCAnJykpLnRvLmJlLmluc3RhbmNlT2YoTWFwKTtcbiAgICAgICAgfSk7XG5cblxuICAgICAgICBbXG4gICAgICAgICAgICBbb2JqMSwgJ2RhdGFzZXQuKicsICdhZGRyZXNzJywgJ3tcImRhdGFzZXQuMTAwODJcIjpcIkhlcmUgMVwiLFwiZGF0YXNldC4xMDA4NFwiOlwiSGVyZSAyXCJ9J10sXG4gICAgICAgICAgICBbb2JqMSwgJ3gnLCB1bmRlZmluZWQsICd7fSddLFxuICAgICAgICAgICAgW29iajEsICdkYXRhc2V0LionLCAnbmFtZScsICd7XCJkYXRhc2V0LjEwMDgyXCI6XCJUZXN0IDFcIixcImRhdGFzZXQuMTAwODRcIjpcIlRlc3QgMlwifSddLFxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYyA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGQgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ2J1aWxkTWFwKCcgKyBKU09OLnN0cmluZ2lmeShhKSArICcsJyArIEpTT04uc3RyaW5naWZ5KGIpICsgJywnICsgSlNPTi5zdHJpbmdpZnkoYykgKyAnKSBzaG91bGQgcmV0dXJuICcgKyBKU09OLnN0cmluZ2lmeShkKSArICcgJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGxldCB0ID0gYnVpbGRNYXAoYSwgYiwgYyk7XG4gICAgICAgICAgICAgICAgbGV0IG0gPSBKU09OLnN0cmluZ2lmeShjb252ZXJ0TWFwUmVzdWx0KHQpKTtcbiAgICAgICAgICAgICAgICBleHBlY3QobSkudG8uYmUuZXF1YWwoZCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cblxuICAgIH0pO1xufSk7XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBpbnRlcm5hbFN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQgeyBpbnN0YW5jZVN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQgeyBCYXNlIH0gZnJvbSBcIi4uL3R5cGVzL2Jhc2UubWpzXCI7XG5pbXBvcnQgeyBwYXJzZURhdGFVUkwgfSBmcm9tIFwiLi4vdHlwZXMvZGF0YXVybC5tanNcIjtcbmltcG9ydCB7IGlzU3RyaW5nIH0gZnJvbSBcIi4uL3R5cGVzL2lzLm1qc1wiO1xuaW1wb3J0IHsgUHJveHlPYnNlcnZlciB9IGZyb20gXCIuLi90eXBlcy9wcm94eW9ic2VydmVyLm1qc1wiO1xuaW1wb3J0IHsgdmFsaWRhdGVPYmplY3QgfSBmcm9tIFwiLi4vdHlwZXMvdmFsaWRhdGUubWpzXCI7XG5pbXBvcnQgeyBleHRlbmQgfSBmcm9tIFwiLi9leHRlbmQubWpzXCI7XG5pbXBvcnQgeyBQYXRoZmluZGVyIH0gZnJvbSBcIi4vcGF0aGZpbmRlci5tanNcIjtcblxuZXhwb3J0IHsgRGF0YXNvdXJjZSB9O1xuXG4vKipcbiAqIFRoaXMgY2FsbGJhY2sgY2FuIGJlIHBhc3NlZCB0byBhIGRhdGFzb3VyY2UgYW5kIGlzIHVzZWQgdG8gYWRhcHQgZGF0YSBzdHJ1Y3R1cmVzLlxuICpcbiAqIEBjYWxsYmFjayBNb25zdGVyLkRhdGEuRGF0YXNvdXJjZX5leGFtcGxlQ2FsbGJhY2tcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVmFsdWVcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgIEtleVxuICogQG1lbWJlck9mIE1vbnN0ZXIuRGF0YVxuICogQHNlZSBNb25zdGVyLkRhdGEuRGF0YXNvdXJjZVxuICovXG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEB0eXBlIHtzeW1ib2x9XG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5EYXRhXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI0LjBcbiAqL1xuY29uc3QgaW50ZXJuYWxEYXRhU3ltYm9sID0gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvZGF0YS9kYXRhc291cmNlL0BAZGF0YVwiKTtcblxuLyoqXG4gKiBUaGUgZGF0YXNvdXJjZSBjbGFzcyBpcyB0aGUgYmFzaXMgZm9yIGRlYWxpbmcgd2l0aCBkaWZmZXJlbnQgZGF0YSBzb3VyY2VzLlxuICogSXQgcHJvdmlkZXMgYSB1bmlmaWVkIGludGVyZmFjZSBmb3IgYWNjZXNzaW5nIGRhdGFcbiAqIEBleHRlcm5hbEV4YW1wbGUgLi4vLi4vZXhhbXBsZS9kYXRhL2RhdGFzb3VyY2UubWpzXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjIyLjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5EYXRhXG4gKiBAc3VtbWFyeSBUaGUgZGF0YXNvdXJjZSBjbGFzcyBlbmNhcHN1bGF0ZXMgdGhlIGFjY2VzcyB0byBkYXRhIG9iamVjdHMuXG4gKi9cbmNsYXNzIERhdGFzb3VyY2UgZXh0ZW5kcyBCYXNlIHtcbiAgICAvKipcbiAgICAgKiBjcmVhdGVzIGEgbmV3IGRhdGFzb3VyY2VcbiAgICAgKlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuXG4gICAgICAgIHRoaXNbaW50ZXJuYWxTeW1ib2xdID0gbmV3IFByb3h5T2JzZXJ2ZXIoe1xuICAgICAgICAgICAgb3B0aW9uczogZXh0ZW5kKHt9LCB0aGlzLmRlZmF1bHRzKSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpc1tpbnRlcm5hbERhdGFTeW1ib2xdID0gbmV3IFByb3h5T2JzZXJ2ZXIoe30pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIGF0dGFjaCBhIG5ldyBvYnNlcnZlclxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYnNlcnZlcn0gb2JzZXJ2ZXJcbiAgICAgKiBAcmV0dXJucyB7RGF0YXNvdXJjZX1cbiAgICAgKi9cbiAgICBhdHRhY2hPYnNlcnZlcihvYnNlcnZlcikge1xuICAgICAgICB0aGlzW2ludGVybmFsRGF0YVN5bWJvbF0uYXR0YWNoT2JzZXJ2ZXIob2JzZXJ2ZXIpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBkZXRhY2ggYSBvYnNlcnZlclxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYnNlcnZlcn0gb2JzZXJ2ZXJcbiAgICAgKiBAcmV0dXJucyB7RGF0YXNvdXJjZX1cbiAgICAgKi9cbiAgICBkZXRhY2hPYnNlcnZlcihvYnNlcnZlcikge1xuICAgICAgICB0aGlzW2ludGVybmFsRGF0YVN5bWJvbF0uZGV0YWNoT2JzZXJ2ZXIob2JzZXJ2ZXIpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge09ic2VydmVyfSBvYnNlcnZlclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgICAqL1xuICAgIGNvbnRhaW5zT2JzZXJ2ZXIob2JzZXJ2ZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbaW50ZXJuYWxEYXRhU3ltYm9sXS5jb250YWluc09ic2VydmVyKG9ic2VydmVyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZXJpdmVkIGNsYXNzZXMgY2FuIG92ZXJyaWRlIGFuZCBleHRlbmQgdGhpcyBtZXRob2QgYXMgZm9sbG93cy5cbiAgICAgKlxuICAgICAqIGBgYFxuICAgICAqIGdldCBkZWZhdWx0cygpIHtcbiAgICAgKiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3VwZXIuZGVmYXVsdHMsIHtcbiAgICAgKiAgICAgICAgbXlWYWx1ZTp0cnVlXG4gICAgICogICAgfSk7XG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldCBkZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldCBvcHRpb25cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZVxuICAgICAqIEByZXR1cm4ge0RhdGFzb3VyY2V9XG4gICAgICovXG4gICAgc2V0T3B0aW9uKHBhdGgsIHZhbHVlKSB7XG4gICAgICAgIG5ldyBQYXRoZmluZGVyKHRoaXNbaW50ZXJuYWxTeW1ib2xdLmdldFN1YmplY3QoKVtcIm9wdGlvbnNcIl0pLnNldFZpYShwYXRoLCB2YWx1ZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfG9iamVjdH0gb3B0aW9uc1xuICAgICAqIEByZXR1cm4ge0RhdGFzb3VyY2V9XG4gICAgICogQHRocm93cyB7RXJyb3J9IHRoZSBvcHRpb25zIGRvZXMgbm90IGNvbnRhaW4gYSB2YWxpZCBqc29uIGRlZmluaXRpb25cbiAgICAgKi9cbiAgICBzZXRPcHRpb25zKG9wdGlvbnMpIHtcbiAgICAgICAgaWYgKGlzU3RyaW5nKG9wdGlvbnMpKSB7XG4gICAgICAgICAgICBvcHRpb25zID0gcGFyc2VPcHRpb25zSlNPTihvcHRpb25zKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgICAgICBleHRlbmQoc2VsZltpbnRlcm5hbFN5bWJvbF0uZ2V0U3ViamVjdCgpW1wib3B0aW9uc1wiXSwgc2VsZi5kZWZhdWx0cywgb3B0aW9ucyk7XG5cbiAgICAgICAgcmV0dXJuIHNlbGY7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogbmVzdGVkIG9wdGlvbnMgY2FuIGJlIHNwZWNpZmllZCBieSBwYXRoIGBhLmIuY2BcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoXG4gICAgICogQHBhcmFtIHsqfSBkZWZhdWx0VmFsdWVcbiAgICAgKiBAcmV0dXJuIHsqfVxuICAgICAqL1xuICAgIGdldE9wdGlvbihwYXRoLCBkZWZhdWx0VmFsdWUpIHtcbiAgICAgICAgbGV0IHZhbHVlO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB2YWx1ZSA9IG5ldyBQYXRoZmluZGVyKHRoaXNbaW50ZXJuYWxTeW1ib2xdLmdldFJlYWxTdWJqZWN0KClbXCJvcHRpb25zXCJdKS5nZXRWaWEocGF0aCk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHt9XG5cbiAgICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHJldHVybiBkZWZhdWx0VmFsdWU7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gdGhpcyBtZXRob2QgbXVzdCBiZSBpbXBsZW1lbnRlZCBieSBkZXJpdmVkIGNsYXNzZXMuXG4gICAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICAgKi9cbiAgICByZWFkKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0aGlzIG1ldGhvZCBtdXN0IGJlIGltcGxlbWVudGVkIGJ5IGRlcml2ZWQgY2xhc3Nlc1wiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gdGhpcyBtZXRob2QgbXVzdCBiZSBpbXBsZW1lbnRlZCBieSBkZXJpdmVkIGNsYXNzZXMuXG4gICAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICAgKi9cbiAgICB3cml0ZSgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidGhpcyBtZXRob2QgbXVzdCBiZSBpbXBsZW1lbnRlZCBieSBkZXJpdmVkIGNsYXNzZXNcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyByZWFsIG9iamVjdFxuICAgICAqXG4gICAgICogQHJldHVybiB7T2JqZWN0fEFycmF5fVxuICAgICAqL1xuICAgIGdldCgpIHtcbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgICAgIHJldHVybiBzZWxmW2ludGVybmFsRGF0YVN5bWJvbF0uZ2V0UmVhbFN1YmplY3QoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge09iamVjdHxBcnJheX0gZGF0YVxuICAgICAqIEByZXR1cm4ge0RhdGFzb3VyY2V9XG4gICAgICovXG4gICAgc2V0KGRhdGEpIHtcbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgICAgIHNlbGZbaW50ZXJuYWxEYXRhU3ltYm9sXS5zZXRTdWJqZWN0KGRhdGEpO1xuICAgICAgICByZXR1cm4gc2VsZjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGBpbnN0YW5jZW9mYCBvcGVyYXRvci5cbiAgICAgKiBAcmV0dXJucyB7c3ltYm9sfVxuICAgICAqIEBzaW5jZSAyLjEuMFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgW2luc3RhbmNlU3ltYm9sXSgpIHtcbiAgICAgICAgcmV0dXJuIFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL2RhdGEvZGF0YXNvdXJjZVwiKTtcbiAgICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSBkYXRhXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKiBAdGhyb3dzIHtFcnJvcn0gdGhlIG9wdGlvbnMgZG9lcyBub3QgY29udGFpbiBhIHZhbGlkIGpzb24gZGVmaW5pdGlvblxuICovXG5mdW5jdGlvbiBwYXJzZU9wdGlvbnNKU09OKGRhdGEpIHtcbiAgICBpZiAoaXNTdHJpbmcoZGF0YSkpIHtcbiAgICAgICAgLy8gdGhlIGNvbmZpZ3VyYXRpb24gY2FuIGJlIHNwZWNpZmllZCBhcyBhIGRhdGEgdXJsLlxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbGV0IGRhdGFVcmwgPSBwYXJzZURhdGFVUkwoZGF0YSk7XG4gICAgICAgICAgICBkYXRhID0gZGF0YVVybC5jb250ZW50O1xuICAgICAgICB9IGNhdGNoIChlKSB7fVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsZXQgb2JqID0gSlNPTi5wYXJzZShkYXRhKTtcbiAgICAgICAgICAgIHZhbGlkYXRlT2JqZWN0KG9iaik7XG4gICAgICAgICAgICByZXR1cm4gb2JqO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHRoZSBvcHRpb25zIGRvZXMgbm90IGNvbnRhaW4gYSB2YWxpZCBqc29uIGRlZmluaXRpb24gKGFjdHVhbDogJHtkYXRhfSkuYCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4ge307XG59XG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XG5cbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge0RhdGFzb3VyY2V9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvZGF0YS9kYXRhc291cmNlLm1qc1wiO1xuXG5cbmRlc2NyaWJlKCdEYXRhc291cmNlJywgZnVuY3Rpb24gKCkge1xuXG5cbiAgICBpdCgnc2hvdWxkIGluc3RhbmNlIG9mIERhdGFzb3VyY2UgJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBleHBlY3QobmV3IERhdGFzb3VyY2UoKSkudG8uYmUuaW5zdGFuY2VvZihEYXRhc291cmNlKVxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ09wdGlvbnMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzZXRPcHRpb24gc2hvdWxkIGNoYW5nZSB2YWx1ZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IGRhdGFzb3VyY2UgPSBuZXcgRGF0YXNvdXJjZSgpO1xuICAgICAgICAgICAgZXhwZWN0KGRhdGFzb3VyY2UuZ2V0T3B0aW9uKCdkZWZhdWx0JykpLnRvLmJlLnVuZGVmaW5lZFxuICAgICAgICAgICAgZGF0YXNvdXJjZS5zZXRPcHRpb24oJ2RlZmF1bHQnLCB0cnVlKVxuICAgICAgICAgICAgZXhwZWN0KGRhdGFzb3VyY2UuZ2V0T3B0aW9uKCdkZWZhdWx0JykpLnRvLmJlLnRydWVcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3NldE9wdGlvbnMgc2hvdWxkIHNldCBhbGwgdmFsdWVzJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY29uc3QgZGF0YXNvdXJjZSA9IG5ldyBEYXRhc291cmNlKCk7XG4gICAgICAgICAgICBleHBlY3QoZGF0YXNvdXJjZS5nZXRPcHRpb24oJ2RlZmF1bHQnKSkudG8uYmUudW5kZWZpbmVkXG4gICAgICAgICAgICBkYXRhc291cmNlLnNldE9wdGlvbnMoe2RlZmF1bHQ6IHRydWV9KVxuICAgICAgICAgICAgZXhwZWN0KGRhdGFzb3VyY2UuZ2V0T3B0aW9uKCdkZWZhdWx0JykpLnRvLmJlLnRydWVcbiAgICAgICAgfSk7XG5cbiAgICB9KVxuXG4gICAgZGVzY3JpYmUoJ3J3JywgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBkYXRhc291cmNlID0gbmV3IERhdGFzb3VyY2UoKTtcbiAgICAgICAgaXQoJ3JlYWQgc2hvdWxkIHRocm93IGV4ZXB0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KCgpID0+IGRhdGFzb3VyY2UucmVhZCgpKS50by50aHJvdyhFcnJvcik7XG4gICAgICAgIH0pO1xuICAgICAgICBcbiAgICAgICAgaXQoJ3dyaXRlIHNob3VsZCB0aHJvdyBleGVwdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdCgoKSA9PiBkYXRhc291cmNlLnJlYWQoKSkudG8udGhyb3coRXJyb3IpO1xuICAgICAgICB9KTtcblxuXG4gICAgfSlcbiAgICBcbiAgICBkZXNjcmliZSgnZ2V0L3NldCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgZGF0YXNvdXJjZSA9IG5ldyBEYXRhc291cmNlKCk7XG4gICAgICAgIGl0KCdnZXQgc2hvdWxkIHJldHVybiB1bmRlZmluZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QoIGRhdGFzb3VyY2UuZ2V0KCkpLnRvLmJlLmVxbCh7fSk7XG4gICAgICAgIH0pO1xuICAgICAgICBcbiAgICAgICAgaXQoJ3dyaXRlIHNob3VsZCB0aHJvdyBleGVwdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdCggZGF0YXNvdXJjZS5nZXQoKSkudG8uYmUuZXFsKHt9KTtcbiAgICAgICAgICAgIGV4cGVjdCggZGF0YXNvdXJjZS5zZXQoe2E6J215dmFsdWUnfSkpLnRvLmJlLmluc3RhbmNlb2YoRGF0YXNvdXJjZSk7XG4gICAgICAgICAgICBleHBlY3QoIGRhdGFzb3VyY2UuZ2V0KCkpLnRvLmJlLmVxbCh7YTonbXl2YWx1ZSd9KTtcbiAgICAgICAgfSk7XG5cblxuICAgIH0pXG5cblxufSkiLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBpc0FycmF5LCBpc09iamVjdCB9IGZyb20gXCIuLi90eXBlcy9pcy5tanNcIjtcbmltcG9ydCB7IE5vZGUgfSBmcm9tIFwiLi4vdHlwZXMvbm9kZS5tanNcIjtcbmltcG9ydCB7IE5vZGVMaXN0IH0gZnJvbSBcIi4uL3R5cGVzL25vZGVsaXN0Lm1qc1wiO1xuaW1wb3J0IHsgYXNzZW1ibGVQYXJ0cyB9IGZyb20gXCIuL2J1aWxkbWFwLm1qc1wiO1xuaW1wb3J0IHsgZXh0ZW5kIH0gZnJvbSBcIi4vZXh0ZW5kLm1qc1wiO1xuXG5leHBvcnQgeyBidWlsZFRyZWUgfTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHR5cGUge3N5bWJvbH1cbiAqL1xuY29uc3QgcGFyZW50U3ltYm9sID0gU3ltYm9sKFwicGFyZW50XCIpO1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAdHlwZSB7c3ltYm9sfVxuICovXG5jb25zdCByb290U3ltYm9sID0gU3ltYm9sKFwicm9vdFwiKTtcblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBidWlsZFRyZWVPcHRpb25zXG4gKiBAcHJvcGVydHkge2FycmF5fSBvcHRpb25zLnJvb3RSZWZlcmVuY2VzPVtudWxsLCB1bmRlZmluZWRdIGRlZmluZXMgdGhlIHZhbHVlcyBmb3IgZWxlbWVudHMgd2l0aG91dCBwYXJlbnRzXG4gKiBAcHJvcGVydHkge01vbnN0ZXIuRGF0YX5leGFtcGxlRmlsdGVyQ2FsbGJhY2t9IG9wdGlvbnMuZmlsdGVyIGZpbHRlcmluZyBvZiB0aGUgdmFsdWVzXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5EYXRhXG4gKi9cblxuLyoqXG4gKiBDcmVhdGVzIGEgdHJlZSBzdHJ1Y3R1cmUgZnJvbSBhIGdpdmVuIHN1YmplY3QgdXNpbmcgYSBzZWxlY3RvciBhbmQgc3BlY2lmaWVkIElEIGFuZCBwYXJlbnQgSUQga2V5cy5cbiAqXG4gKiBUaGUgYnVpbGRUcmVlIGZ1bmN0aW9uIGlzIGEgcG93ZXJmdWwgdG9vbCBmb3IgY3JlYXRpbmcgdHJlZS1saWtlIGRhdGEgc3RydWN0dXJlcyBmcm9tIHBsYWluIEphdmFTY3JpcHRcbiAqIG9iamVjdHMuIEl0IHRha2VzIGluIGZvdXIgcmVxdWlyZWQgcGFyYW1ldGVyczogdGhlIHN1YmplY3Qgb2JqZWN0IHRoYXQgeW91IHdhbnQgdG8gdHVybiBpbnRvIGEgdHJlZSwgYVxuICogc2VsZWN0b3IgdGhhdCBpZGVudGlmaWVzIHdoaWNoIHBhcnRzIG9mIHRoZSBzdWJqZWN0IHRvIHVzZSB3aGVuIGJ1aWxkaW5nIHRoZSB0cmVlLCBhbmQgdHdvIGtleXNcbiAqIChpZEtleSBhbmQgcGFyZW50SURLZXkpIHRoYXQgc3BlY2lmeSB3aGljaCBwcm9wZXJ0aWVzIGluIHRoZSBzdWJqZWN0IHJlcHJlc2VudCB0aGUgdW5pcXVlIGlkZW50aWZpZXJzXG4gKiBhbmQgcGFyZW50LWNoaWxkIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiBub2RlcyBpbiB0aGUgdHJlZS5cbiAqXG4gKiBPcHRpb25hbGx5LCB5b3UgY2FuIGFsc28gcGFzcyBpbiBhbiBvcHRpb25zIG9iamVjdCB0byBmdXJ0aGVyIGNvbmZpZ3VyZSB0aGUgYmVoYXZpb3Igb2YgdGhlIGZ1bmN0aW9uLFxuICogc3VjaCBhcyBzcGVjaWZ5aW5nIHdoaWNoIHZhbHVlcyBzaG91bGQgYmUgdHJlYXRlZCBhcyByb290cyBvZiB0aGUgdHJlZSwgb3IgcHJvdmlkaW5nIGEgY3VzdG9tIGZpbHRlclxuICogZnVuY3Rpb24gdG8gb25seSBpbmNsdWRlIGNlcnRhaW4gbm9kZXMgaW4gdGhlIGZpbmFsIG91dHB1dC5cbiAqXG4gKiBUaGUgYnVpbGRUcmVlIGZ1bmN0aW9uIHdvcmtzIGJ5IGZpcnN0IHVzaW5nIHRoZSBhc3NlbWJsZVBhcnRzIGhlbHBlciBmdW5jdGlvbiB0byBleHRyYWN0IHRoZSByZWxldmFudFxuICogcGFydHMgb2YgdGhlIHN1YmplY3QgYmFzZWQgb24gdGhlIHNlbGVjdG9yLCBhbmQgdGhlbiBpdGVyYXRlcyBvdmVyIHRoZSByZXN1bHRpbmcgbWFwIHRvIGNyZWF0ZSBOb2RlXG4gKiBvYmplY3RzIGFuZCBvcmdhbml6ZSB0aGVtIGludG8gcGFyZW50LWNoaWxkIHJlbGF0aW9uc2hpcHMgYmFzZWQgb24gdGhlIHZhbHVlcyBvZiB0aGUgaWRLZXkgYW5kIHBhcmVudElES2V5IHByb3BlcnRpZXMuXG4gKlxuICogVGhlIHJlc3VsdGluZyBOb2RlTGlzdCByZXByZXNlbnRzIHRoZSB0cmVlIHN0cnVjdHVyZSwgd2l0aCBlYWNoIE5vZGUgb2JqZWN0IGNvbnRhaW5pbmcgdGhlIG9yaWdpbmFsXG4gKiBvYmplY3QgZGF0YSBhcyB3ZWxsIGFzIGFkZGl0aW9uYWwgbWV0YWRhdGEgYWJvdXQgaXRzIHBvc2l0aW9uIGluIHRoZSB0cmVlLiBZb3UgY2FuIHRoZW4gdXNlIHRoZSBjaGlsZE5vZGVzXG4gKiBwcm9wZXJ0eSBvZiBlYWNoIE5vZGUgdG8gYWNjZXNzIGl0cyBjaGlsZHJlbiwgb3IgdGhlIHBhcmVudCBwcm9wZXJ0eSB0byBhY2Nlc3MgaXRzIHBhcmVudC5cbiAqXG4gKiBPdmVyYWxsLCB0aGUgYnVpbGRUcmVlIGZ1bmN0aW9uIGlzIGEgZmxleGlibGUgYW5kIHBvd2VyZnVsIHdheSB0byB0cmFuc2Zvcm0gZmxhdCBkYXRhIGludG8gaGllcmFyY2hpY2FsXG4gKiBzdHJ1Y3R1cmVzLCBhbmQgY2FuIGJlIGVzcGVjaWFsbHkgdXNlZnVsIGluIHNjZW5hcmlvcyBzdWNoIGFzIGRpc3BsYXlpbmcgZm9sZGVyIHN0cnVjdHVyZXMgb3JcbiAqIHZpc3VhbGl6aW5nIGNvbXBsZXggZGF0YSByZWxhdGlvbnNoaXBzLlxuICpcbiAqIExldCdzIHNheSB5b3UgaGF2ZSBhbiBhcnJheSBvZiBkYXRhIG9iamVjdHMgcmVwcmVzZW50aW5nIGEgZmlsZSBzeXN0ZW0gZGlyZWN0b3J5IHN0cnVjdHVyZSwgYW5kIHlvdSB3YW50XG4gKiB0byB0dXJuIGl0IGludG8gYSB0cmVlLWxpa2Ugc3RydWN0dXJlIHdoZXJlIGVhY2ggbm9kZSByZXByZXNlbnRzIGEgZm9sZGVyIG9yIGZpbGUsIGFuZCBjaGlsZCBub2Rlc1xuICogcmVwcmVzZW50IHRoZSBjb250ZW50cyBvZiB0aGUgZm9sZGVyOlxuICpcbiAqIGBgYGphdmFzY3JpcHRcbiAqIGNvbnN0IGZpbGVTeXN0ZW0gPSBbXG4gKiAgIHsgaWQ6ICdmb2xkZXIxJywgbmFtZTogJ0ZvbGRlciAxJywgdHlwZTogJ2ZvbGRlcicsIHBhcmVudDogbnVsbCB9LFxuICogICB7IGlkOiAnZmlsZTEnLCBuYW1lOiAnRmlsZSAxJywgdHlwZTogJ2ZpbGUnLCBwYXJlbnQ6ICdmb2xkZXIxJyB9LFxuICogICB7IGlkOiAnZmlsZTInLCBuYW1lOiAnRmlsZSAyJywgdHlwZTogJ2ZpbGUnLCBwYXJlbnQ6ICdmb2xkZXIxJyB9LFxuICogICB7IGlkOiAnc3ViZm9sZGVyMScsIG5hbWU6ICdTdWJmb2xkZXIgMScsIHR5cGU6ICdmb2xkZXInLCBwYXJlbnQ6ICdmb2xkZXIxJyB9LFxuICogICB7IGlkOiAnZmlsZTMnLCBuYW1lOiAnRmlsZSAzJywgdHlwZTogJ2ZpbGUnLCBwYXJlbnQ6ICdzdWJmb2xkZXIxJyB9LFxuICogICB7IGlkOiAnZmlsZTQnLCBuYW1lOiAnRmlsZSA0JywgdHlwZTogJ2ZpbGUnLCBwYXJlbnQ6ICdzdWJmb2xkZXIxJyB9LFxuICogICB7IGlkOiAnc3ViZm9sZGVyMicsIG5hbWU6ICdTdWJmb2xkZXIgMicsIHR5cGU6ICdmb2xkZXInLCBwYXJlbnQ6ICdmb2xkZXIxJyB9LFxuICogICB7IGlkOiAnZmlsZTUnLCBuYW1lOiAnRmlsZSA1JywgdHlwZTogJ2ZpbGUnLCBwYXJlbnQ6ICdzdWJmb2xkZXIyJyB9LFxuICogICB7IGlkOiAnZmlsZTYnLCBuYW1lOiAnRmlsZSA2JywgdHlwZTogJ2ZpbGUnLCBwYXJlbnQ6ICdzdWJmb2xkZXIyJyB9LFxuICogICB7IGlkOiAnZm9sZGVyMicsIG5hbWU6ICdGb2xkZXIgMicsIHR5cGU6ICdmb2xkZXInLCBwYXJlbnQ6IG51bGwgfSxcbiAqICAgeyBpZDogJ2ZpbGU3JywgbmFtZTogJ0ZpbGUgNycsIHR5cGU6ICdmaWxlJywgcGFyZW50OiAnZm9sZGVyMicgfSxcbiAqICAgeyBpZDogJ2ZpbGU4JywgbmFtZTogJ0ZpbGUgOCcsIHR5cGU6ICdmaWxlJywgcGFyZW50OiAnZm9sZGVyMicgfSxcbiAqICAgeyBpZDogJ3N1YmZvbGRlcjMnLCBuYW1lOiAnU3ViZm9sZGVyIDMnLCB0eXBlOiAnZm9sZGVyJywgcGFyZW50OiAnZm9sZGVyMicgfSxcbiAqICAgeyBpZDogJ2ZpbGU5JywgbmFtZTogJ0ZpbGUgOScsIHR5cGU6ICdmaWxlJywgcGFyZW50OiAnc3ViZm9sZGVyMycgfSxcbiAqICAgeyBpZDogJ2ZpbGUxMCcsIG5hbWU6ICdGaWxlIDEwJywgdHlwZTogJ2ZpbGUnLCBwYXJlbnQ6ICdzdWJmb2xkZXIzJyB9LFxuICogXTtcbiAqXG4gKiBjb25zdCB0cmVlID0gYnVpbGRUcmVlKGZpbGVTeXN0ZW0sICdpZCcsICdpZCcsICdwYXJlbnQnLCB7IHJvb3RSZWZlcmVuY2VzOiBbbnVsbF0gfSk7XG4gKlxuICogY29uc29sZS5sb2codHJlZS50b1N0cmluZygpKTtcbiAqIGBgYFxuICpcbiAqIFRoZSBidWlsZFRyZWUgZnVuY3Rpb24gdGFrZXMgaW4gdGhlIGFycmF5IG9mIGRhdGEgb2JqZWN0cywgYXMgd2VsbCBhcyBzb21lIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyBzcGVjaWZ5aW5nXG4gKiB0aGUga2V5cyB0byB1c2UgZm9yIGlkZW50aWZ5aW5nIG5vZGVzIGFuZCB0aGVpciBwYXJlbnQtY2hpbGQgcmVsYXRpb25zaGlwcy4gSW4gdGhpcyBleGFtcGxlLCB3ZSB1c2UgdGhlIGlkXG4gKiBrZXkgdG8gaWRlbnRpZnkgbm9kZXMsIGFuZCB0aGUgcGFyZW50IGtleSB0byBzcGVjaWZ5IHRoZSBwYXJlbnQgb2YgZWFjaCBub2RlLlxuICpcbiAqIFRoZSByZXN1bHRpbmcgdHJlZSBvYmplY3QgaXMgYSBuZXN0ZWQgdHJlZSBzdHJ1Y3R1cmUsIHdoZXJlIGVhY2ggbm9kZSBpcyBhbiBvYmplY3QgcmVwcmVzZW50aW5nIGEgZmlsZSBvclxuICogZm9sZGVyLCBhbmQgaGFzIGNoaWxkIG5vZGVzIHJlcHJlc2VudGluZyBpdHMgY29udGVudHMuIFRoZSB0b1N0cmluZyBtZXRob2Qgb2YgdGhlIHRyZWUgb2JqZWN0XG4gKiBjYW4gYmUgdXNlZCB0byBwcmludCBvdXQgdGhlIHRyZWUgaW4gYSByZWFkYWJsZSBmb3JtYXQ6XG4gKlxuICogYGBgbWFya2Rvd25cbiAqIC0gRm9sZGVyIDFcbiAqICAgLSBGaWxlIDFcbiAqICAgLSBGaWxlIDJcbiAqICAgLSBTdWJmb2xkZXIgMVxuICogICAgIC0gRmlsZSAzXG4gKiAgICAgLSBGaWxlIDRcbiAqICAgLSBTdWJmb2xkZXIgMlxuICogICAgIC0gRmlsZSA1XG4gKiAgICAgLSBGaWxlIDZcbiAqIC0gRm9sZGVyIDJcbiAqICAgLSBGaWxlIDdcbiAqICAgLSBGaWxlIDhcbiAqICAgLSBTdWJmb2xkZXIgM1xuICogICAgIC0gRmlsZSA5XG4gKiAgICAgLSBGaWxlIDEwXG4gKiBgYGBcbiAqXG4gKiBAbWVtYmVyb2YgTW9uc3Rlci5EYXRhXG4gKlxuICogQHBhcmFtIHsqfSBzdWJqZWN0IC0gVGhlIG9iamVjdCBvciBhcnJheSB0byBidWlsZCB0aGUgdHJlZSBmcm9tLlxuICogQHBhcmFtIHtzdHJpbmd8TW9uc3Rlci5EYXRhfmV4YW1wbGVTZWxlY3RvckNhbGxiYWNrfSBzZWxlY3RvciAtIEVpdGhlciBhIHN0cmluZyB0byBzcGVjaWZ5IGEgcHJvcGVydHkgb2YgZWFjaCBvYmplY3QgdG8gdXNlIGFzIGEgc2VsZWN0b3IsIG9yIGEgc2VsZWN0b3IgZnVuY3Rpb24gdG8gZ2VuZXJhdGUgYSBtYXAgb2Ygb2JqZWN0cy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBpZEtleSAtIFRoZSBwcm9wZXJ0eSBrZXkgdG8gdXNlIGFzIHRoZSB1bmlxdWUgSUQgb2YgZWFjaCBub2RlLlxuICogQHBhcmFtIHtzdHJpbmd9IHBhcmVudElES2V5IC0gVGhlIHByb3BlcnR5IGtleSB0byB1c2UgYXMgdGhlIHBhcmVudCBJRCBvZiBlYWNoIG5vZGUuXG4gKiBAcGFyYW0ge29iamVjdH0gW29wdGlvbnNdIC0gQWRkaXRpb25hbCBvcHRpb25zIHRvIG1vZGlmeSB0aGUgZnVuY3Rpb24gYmVoYXZpb3IuXG4gKiBAcGFyYW0ge0FycmF5PCo+fSBbb3B0aW9ucy5yb290UmVmZXJlbmNlcz1bbnVsbCwgdW5kZWZpbmVkXV0gLSBBbiBhcnJheSBvZiB2YWx1ZXMgdG8gdHJlYXQgYXMgcm9vdCByZWZlcmVuY2VzIHdoZW4gY3JlYXRpbmcgdGhlIHRyZWUuXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBbb3B0aW9ucy5maWx0ZXJdIC0gQSBmaWx0ZXIgZnVuY3Rpb24gdG8gYXBwbHkgdG8gZWFjaCBub2RlLlxuICpcbiAqIEByZXR1cm4geyp9IFRoZSByZXN1bHRpbmcgdHJlZSBzdHJ1Y3R1cmUgYXMgYSBOb2RlTGlzdC5cbiAqXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHNlbGVjdG9yIGlzIG5laXRoZXIgYSBzdHJpbmcgbm9yIGEgZnVuY3Rpb24uXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHRoZSBzZWxlY3RvciBjYWxsYmFjayBtdXN0IHJldHVybiBhIG1hcC5cbiAqIEB0aHJvd3Mge0Vycm9yfSB0aGUgb2JqZWN0IGhhcyBubyB2YWx1ZSBmb3IgdGhlIHNwZWNpZmllZCBpZC5cbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqXG4gKiBAc2luY2UgMS4yNi4wXG4gKi9cbmZ1bmN0aW9uIGJ1aWxkVHJlZShzdWJqZWN0LCBzZWxlY3RvciwgaWRLZXksIHBhcmVudElES2V5LCBvcHRpb25zKSB7XG4gICAgY29uc3Qgbm9kZXMgPSBuZXcgTWFwKCk7XG5cbiAgICBpZiAoIWlzT2JqZWN0KG9wdGlvbnMpKSB7XG4gICAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICB9XG5cbiAgICBvcHRpb25zID0gZXh0ZW5kKFxuICAgICAgICB7fSxcbiAgICAgICAge1xuICAgICAgICAgICAgcm9vdFJlZmVyZW5jZXM6IFtudWxsLCB1bmRlZmluZWRdLFxuICAgICAgICAgICAgZmlsdGVyOiB1bmRlZmluZWQsXG4gICAgICAgIH0sXG4gICAgICAgIG9wdGlvbnMsXG4gICAgKTtcblxuICAgIGNvbnN0IGZpbHRlciA9IG9wdGlvbnM/LmZpbHRlcjtcbiAgICBsZXQgcm9vdFJlZmVyZW5jZXMgPSBvcHRpb25zLnJvb3RSZWZlcmVuY2VzO1xuICAgIGlmICghaXNBcnJheShyb290UmVmZXJlbmNlcykpIHtcbiAgICAgICAgcm9vdFJlZmVyZW5jZXMgPSBbcm9vdFJlZmVyZW5jZXNdO1xuICAgIH1cblxuICAgIGNvbnN0IGNoaWxkTWFwID0gYXNzZW1ibGVQYXJ0cyhzdWJqZWN0LCBzZWxlY3RvciwgZmlsdGVyLCBmdW5jdGlvbiAobywgaywgbSkge1xuICAgICAgICBjb25zdCBrZXkgPSBvPy5baWRLZXldO1xuICAgICAgICBsZXQgcmVmID0gbz8uW3BhcmVudElES2V5XTtcbiAgICAgICAgaWYgKHJvb3RSZWZlcmVuY2VzLmluZGV4T2YocmVmKSAhPT0gLTEpIHJlZiA9IHJvb3RTeW1ib2w7XG5cbiAgICAgICAgaWYgKGtleSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0aGUgb2JqZWN0IGhhcyBubyB2YWx1ZSBmb3IgdGhlIHNwZWNpZmllZCBpZFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIG9bcGFyZW50U3ltYm9sXSA9IHJlZjtcblxuICAgICAgICBjb25zdCBub2RlID0gbmV3IE5vZGUobyk7XG4gICAgICAgIHRoaXMuaGFzKHJlZikgPyB0aGlzLmdldChyZWYpLmFkZChub2RlKSA6IHRoaXMuc2V0KHJlZiwgbmV3IE5vZGVMaXN0KCkuYWRkKG5vZGUpKTtcbiAgICAgICAgbm9kZXMuc2V0KGtleSwgbm9kZSk7XG4gICAgfSk7XG5cbiAgICBub2Rlcy5mb3JFYWNoKChub2RlKSA9PiB7XG4gICAgICAgIGxldCBpZCA9IG5vZGU/LltcInZhbHVlXCJdPy5baWRLZXldO1xuXG4gICAgICAgIGlmIChjaGlsZE1hcC5oYXMoaWQpKSB7XG4gICAgICAgICAgICBub2RlLmNoaWxkTm9kZXMgPSBjaGlsZE1hcC5nZXQoaWQpO1xuICAgICAgICAgICAgY2hpbGRNYXAuZGVsZXRlKGlkKTtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgY29uc3QgbGlzdCA9IG5ldyBOb2RlTGlzdCgpO1xuXG4gICAgY2hpbGRNYXAuZm9yRWFjaCgocykgPT4ge1xuICAgICAgICBpZiAocyBpbnN0YW5jZW9mIFNldCkge1xuICAgICAgICAgICAgcy5mb3JFYWNoKChuKSA9PiB7XG4gICAgICAgICAgICAgICAgbGlzdC5hZGQobik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGxpc3Q7XG59XG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XG5cbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge2J1aWxkVHJlZX0gZnJvbSBcIi4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9kYXRhL2J1aWxkdHJlZS5tanNcIjtcbmltcG9ydCB7Tm9kZUxpc3R9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdHlwZXMvbm9kZWxpc3QubWpzXCI7XG5cblxuZGVzY3JpYmUoJ2J1aWxkVHJlZScsIGZ1bmN0aW9uICgpIHtcblxuICAgIGRlc2NyaWJlKCdleGFtcGxlJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdzaG91bGQgcnVuIGV4YW1wbGUnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIGNvbnN0IG9iamVjdHMgPSB7XG4gICAgICAgICAgICAgICAgZGF0YXNldDoge1xuICAgICAgICAgICAgICAgICAgICBcIjFcIjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWQ6IFwiMVwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogXCJ2ZWhpY2xlXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IG51bGxcblxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBcIjJcIjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWQ6IFwiMlwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogXCJjYXJcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudDogXCIxXCJcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgXCIzXCI6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlkOiBcIjNcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IFwidHJ1Y2tcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudDogXCIxXCJcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgXCI0XCI6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlkOiBcIjRcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IFwibW90b3JjeWNsZVwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50OiBcIjFcIlxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBcIjVcIjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWQ6IFwiNVwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogXCJTVVZcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudDogXCIyXCJcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgXCI2XCI6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlkOiBcIjZcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IFwic3BvcnRzIGNhclwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50OiBcIjJcIlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBub2RlcyA9IGJ1aWxkVHJlZShvYmplY3RzLCAnZGF0YXNldC4qJywgJ2lkJywgJ3BhcmVudCcpO1xuXG4gICAgICAgICAgICBleHBlY3Qobm9kZXMpLnRvLmJlLmluc3RhbmNlT2YoTm9kZUxpc3QpO1xuICAgICAgICAgICAgZXhwZWN0KG5vZGVzLmxlbmd0aCkudG8uZXF1YWwoMSk7XG4gICAgICAgICAgICBleHBlY3Qobm9kZXMudG9TdHJpbmcoKSkudG8uYmUuZXF1YWwoJ3tcImlkXCI6XCIxXCIsXCJuYW1lXCI6XCJ2ZWhpY2xlXCIsXCJwYXJlbnRcIjpudWxsfVxcbiBcdTI1MUN7XCJpZFwiOlwiMlwiLFwibmFtZVwiOlwiY2FyXCIsXCJwYXJlbnRcIjpcIjFcIn1cXG4gfCBcdTI1MUN7XCJpZFwiOlwiNVwiLFwibmFtZVwiOlwiU1VWXCIsXCJwYXJlbnRcIjpcIjJcIn1cXG4gfCBcdTI1MTR7XCJpZFwiOlwiNlwiLFwibmFtZVwiOlwic3BvcnRzIGNhclwiLFwicGFyZW50XCI6XCIyXCJ9XFxuIFx1MjUxQ3tcImlkXCI6XCIzXCIsXCJuYW1lXCI6XCJ0cnVja1wiLFwicGFyZW50XCI6XCIxXCJ9XFxuIFx1MjUxNHtcImlkXCI6XCI0XCIsXCJuYW1lXCI6XCJtb3RvcmN5Y2xlXCIsXCJwYXJlbnRcIjpcIjFcIn0nICk7XG5cblxuICAgICAgICB9KVxuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnYnVpbGRUcmVlKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgbGV0IG9iajEgPSB7XG4gICAgICAgICAgICBkYXRhc2V0OiB7XG4gICAgICAgICAgICAgICAgXCIxXCI6IHtcbiAgICAgICAgICAgICAgICAgICAgaWQ6IFwiMVwiLFxuICAgICAgICAgICAgICAgICAgICBuYW1lOiBcIlRlc3QgMVwiLFxuICAgICAgICAgICAgICAgICAgICBhZGRyZXNzOiBcIkhlcmUgMVwiLFxuICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IG51bGxcblxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgXCIyXCI6IHtcbiAgICAgICAgICAgICAgICAgICAgaWQ6IFwiMlwiLFxuICAgICAgICAgICAgICAgICAgICBuYW1lOiBcIlRlc3QgMlwiLFxuICAgICAgICAgICAgICAgICAgICBhZGRyZXNzOiBcIkhlcmUgMlwiLFxuICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IFwiMVwiXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBcIjNcIjoge1xuICAgICAgICAgICAgICAgICAgICBpZDogXCIzXCIsXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6IFwiVGVzdCAzXCIsXG4gICAgICAgICAgICAgICAgICAgIGFkZHJlc3M6IFwiSGVyZSAzXCIsXG4gICAgICAgICAgICAgICAgICAgIHBhcmVudDogXCIyXCJcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIFwiNFwiOiB7XG4gICAgICAgICAgICAgICAgICAgIGlkOiBcIjRcIixcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogXCJUZXN0IDRcIixcbiAgICAgICAgICAgICAgICAgICAgYWRkcmVzczogXCJIZXJlIDRcIixcbiAgICAgICAgICAgICAgICAgICAgcGFyZW50OiBcIjJcIlxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgXCI1XCI6IHtcbiAgICAgICAgICAgICAgICAgICAgaWQ6IFwiNVwiLFxuICAgICAgICAgICAgICAgICAgICBuYW1lOiBcIlRlc3QgNVwiLFxuICAgICAgICAgICAgICAgICAgICBhZGRyZXNzOiBcIkhlcmUgNVwiLFxuICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IFwiMVwiXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBcIjZcIjoge1xuICAgICAgICAgICAgICAgICAgICBpZDogXCI2XCIsXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6IFwiVGVzdCA2XCIsXG4gICAgICAgICAgICAgICAgICAgIGFkZHJlc3M6IFwiSGVyZSA2XCIsXG4gICAgICAgICAgICAgICAgICAgIHBhcmVudDogXCI0XCJcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gTm9kZSBJbnN0YW5jZS4nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QoYnVpbGRUcmVlKHt9LCAnJykpLnRvLmJlLmluc3RhbmNlT2YoTm9kZUxpc3QpO1xuICAgICAgICB9KTtcblxuICAgICAgICBbXG4gICAgICAgICAgICBbb2JqMSwgJ2RhdGFzZXQuKicsICd7XCJpZFwiOlwiMVwiLFwibmFtZVwiOlwiVGVzdCAxXCIsXCJhZGRyZXNzXCI6XCJIZXJlIDFcIixcInBhcmVudFwiOm51bGx9XFxuIFx1MjUxQ3tcImlkXCI6XCIyXCIsXCJuYW1lXCI6XCJUZXN0IDJcIixcImFkZHJlc3NcIjpcIkhlcmUgMlwiLFwicGFyZW50XCI6XCIxXCJ9XFxuIHwgXHUyNTFDe1wiaWRcIjpcIjNcIixcIm5hbWVcIjpcIlRlc3QgM1wiLFwiYWRkcmVzc1wiOlwiSGVyZSAzXCIsXCJwYXJlbnRcIjpcIjJcIn1cXG4gfCBcdTI1MTR7XCJpZFwiOlwiNFwiLFwibmFtZVwiOlwiVGVzdCA0XCIsXCJhZGRyZXNzXCI6XCJIZXJlIDRcIixcInBhcmVudFwiOlwiMlwifVxcbiB8IHwgXHUyNTE0e1wiaWRcIjpcIjZcIixcIm5hbWVcIjpcIlRlc3QgNlwiLFwiYWRkcmVzc1wiOlwiSGVyZSA2XCIsXCJwYXJlbnRcIjpcIjRcIn1cXG4gXHUyNTE0e1wiaWRcIjpcIjVcIixcIm5hbWVcIjpcIlRlc3QgNVwiLFwiYWRkcmVzc1wiOlwiSGVyZSA1XCIsXCJwYXJlbnRcIjpcIjFcIn0nXSxcbiAgICAgICAgICAgIFtvYmoxLCAneCcsICcnXSxcbiAgICAgICAgICAgIFtvYmoxLCAnZGF0YXNldC4qJywgJ3tcImlkXCI6XCIxXCIsXCJuYW1lXCI6XCJUZXN0IDFcIixcImFkZHJlc3NcIjpcIkhlcmUgMVwiLFwicGFyZW50XCI6bnVsbH1cXG4gXHUyNTFDe1wiaWRcIjpcIjJcIixcIm5hbWVcIjpcIlRlc3QgMlwiLFwiYWRkcmVzc1wiOlwiSGVyZSAyXCIsXCJwYXJlbnRcIjpcIjFcIn1cXG4gfCBcdTI1MUN7XCJpZFwiOlwiM1wiLFwibmFtZVwiOlwiVGVzdCAzXCIsXCJhZGRyZXNzXCI6XCJIZXJlIDNcIixcInBhcmVudFwiOlwiMlwifVxcbiB8IFx1MjUxNHtcImlkXCI6XCI0XCIsXCJuYW1lXCI6XCJUZXN0IDRcIixcImFkZHJlc3NcIjpcIkhlcmUgNFwiLFwicGFyZW50XCI6XCIyXCJ9XFxuIHwgfCBcdTI1MTR7XCJpZFwiOlwiNlwiLFwibmFtZVwiOlwiVGVzdCA2XCIsXCJhZGRyZXNzXCI6XCJIZXJlIDZcIixcInBhcmVudFwiOlwiNFwifVxcbiBcdTI1MTR7XCJpZFwiOlwiNVwiLFwibmFtZVwiOlwiVGVzdCA1XCIsXCJhZGRyZXNzXCI6XCJIZXJlIDVcIixcInBhcmVudFwiOlwiMVwifSddLFxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYyA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpdCgnYnVpbGRUcmVlKCcgKyBKU09OLnN0cmluZ2lmeShhKSArICcsJyArIEpTT04uc3RyaW5naWZ5KGIpICsgJykgc2hvdWxkIHJldHVybiAnICsgSlNPTi5zdHJpbmdpZnkoYykgKyAnICcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBsZXQgbm9kZWxpc3QgPSBidWlsZFRyZWUoYSwgYiwgJ2lkJywgJ3BhcmVudCcpO1xuICAgICAgICAgICAgICAgIGV4cGVjdChub2RlbGlzdC50b1N0cmluZygpKS50by5iZS5lcWwoYyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2J1aWxkVHJlZSgpIHRlc3QgMicsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAvKipcbiAgICAgICAgICogMlxuICAgICAgICAgKiAgICAxXG4gICAgICAgICAqICAgIDNcbiAgICAgICAgICogNFxuICAgICAgICAgKiAgICA2XG4gICAgICAgICAqIDVcbiAgICAgICAgICpcbiAgICAgICAgICovXG4gICAgICAgIGxldCBvYmoxID0ge1xuICAgICAgICAgICAgZGF0YXNldDoge1xuICAgICAgICAgICAgICAgIFwiMVwiOiB7XG4gICAgICAgICAgICAgICAgICAgIGlkOiBcIjFcIixcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogXCJUZXN0IDFcIixcbiAgICAgICAgICAgICAgICAgICAgYWRkcmVzczogXCJIZXJlIDFcIixcbiAgICAgICAgICAgICAgICAgICAgcGFyZW50OiBcIjJcIlxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgXCIyXCI6IHtcbiAgICAgICAgICAgICAgICAgICAgaWQ6IFwiMlwiLFxuICAgICAgICAgICAgICAgICAgICBuYW1lOiBcIlRlc3QgMlwiLFxuICAgICAgICAgICAgICAgICAgICBhZGRyZXNzOiBcIkhlcmUgMlwiLFxuICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IFwiMFwiXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBcIjNcIjoge1xuICAgICAgICAgICAgICAgICAgICBpZDogXCIzXCIsXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6IFwiVGVzdCAzXCIsXG4gICAgICAgICAgICAgICAgICAgIGFkZHJlc3M6IFwiSGVyZSAzXCIsXG4gICAgICAgICAgICAgICAgICAgIHBhcmVudDogXCIyXCJcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIFwiNFwiOiB7XG4gICAgICAgICAgICAgICAgICAgIGlkOiBcIjRcIixcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogXCJUZXN0IDRcIixcbiAgICAgICAgICAgICAgICAgICAgYWRkcmVzczogXCJIZXJlIDRcIixcbiAgICAgICAgICAgICAgICAgICAgcGFyZW50OiBcIjBcIlxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgXCI1XCI6IHtcbiAgICAgICAgICAgICAgICAgICAgaWQ6IFwiNVwiLFxuICAgICAgICAgICAgICAgICAgICBuYW1lOiBcIlRlc3QgNVwiLFxuICAgICAgICAgICAgICAgICAgICBhZGRyZXNzOiBcIkhlcmUgNVwiLFxuICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IFwiMFwiXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBcIjZcIjoge1xuICAgICAgICAgICAgICAgICAgICBpZDogXCI2XCIsXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6IFwiVGVzdCA2XCIsXG4gICAgICAgICAgICAgICAgICAgIGFkZHJlc3M6IFwiSGVyZSA2XCIsXG4gICAgICAgICAgICAgICAgICAgIHBhcmVudDogXCI0XCJcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIFwiN1wiOiB7XG4gICAgICAgICAgICAgICAgICAgIGlkOiBcIjdcIixcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogXCJUZXN0IDdcIixcbiAgICAgICAgICAgICAgICAgICAgYWRkcmVzczogXCJIZXJlIDdcIixcbiAgICAgICAgICAgICAgICAgICAgcGFyZW50OiBcIjFcIlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBOb2RlIEluc3RhbmNlLicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChidWlsZFRyZWUoe30sICcnKSkudG8uYmUuaW5zdGFuY2VPZihOb2RlTGlzdCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIFtcbiAgICAgICAgICAgIFtvYmoxLCAnZGF0YXNldC4qJywgJ3tcImlkXCI6XCIyXCIsXCJuYW1lXCI6XCJUZXN0IDJcIixcImFkZHJlc3NcIjpcIkhlcmUgMlwiLFwicGFyZW50XCI6XCIwXCJ9XFxuIFx1MjUxQ3tcImlkXCI6XCIxXCIsXCJuYW1lXCI6XCJUZXN0IDFcIixcImFkZHJlc3NcIjpcIkhlcmUgMVwiLFwicGFyZW50XCI6XCIyXCJ9XFxuIHwgXHUyNTE0e1wiaWRcIjpcIjdcIixcIm5hbWVcIjpcIlRlc3QgN1wiLFwiYWRkcmVzc1wiOlwiSGVyZSA3XCIsXCJwYXJlbnRcIjpcIjFcIn1cXG4gXHUyNTE0e1wiaWRcIjpcIjNcIixcIm5hbWVcIjpcIlRlc3QgM1wiLFwiYWRkcmVzc1wiOlwiSGVyZSAzXCIsXCJwYXJlbnRcIjpcIjJcIn1cXG57XCJpZFwiOlwiNFwiLFwibmFtZVwiOlwiVGVzdCA0XCIsXCJhZGRyZXNzXCI6XCJIZXJlIDRcIixcInBhcmVudFwiOlwiMFwifVxcbiBcdTI1MTR7XCJpZFwiOlwiNlwiLFwibmFtZVwiOlwiVGVzdCA2XCIsXCJhZGRyZXNzXCI6XCJIZXJlIDZcIixcInBhcmVudFwiOlwiNFwifVxcbntcImlkXCI6XCI1XCIsXCJuYW1lXCI6XCJUZXN0IDVcIixcImFkZHJlc3NcIjpcIkhlcmUgNVwiLFwicGFyZW50XCI6XCIwXCJ9J10sXG4gICAgICAgICAgICBbb2JqMSwgJ3gnLCAnJ10sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBjID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGl0KCdidWlsZFRyZWUoJyArIEpTT04uc3RyaW5naWZ5KGEpICsgJywnICsgSlNPTi5zdHJpbmdpZnkoYikgKyAnKSBzaG91bGQgcmV0dXJuICcgKyBKU09OLnN0cmluZ2lmeShjKSArICcgJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGxldCBub2RlbGlzdCA9IGJ1aWxkVHJlZShhLCBiLCAnaWQnLCAncGFyZW50Jywge1xuICAgICAgICAgICAgICAgICAgICByb290UmVmZXJlbmNlczogWycwJ11cbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIGV4cGVjdChub2RlbGlzdC50b1N0cmluZygpKS50by5iZS5lcXVhbChjKTtcblxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxuXG59KTtcbiIsICJcInVzZSBzdHJpY3RcIjtcblxuaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7VHJhbnNmb3JtZXJ9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvZGF0YS90cmFuc2Zvcm1lci5tanNcIjtcbmltcG9ydCB7RW1iZWR9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvaTE4bi9wcm92aWRlcnMvZW1iZWQubWpzXCI7XG5pbXBvcnQge2luaXRKU0RPTX0gZnJvbSBcIi4uLy4uL3V0aWwvanNkb20ubWpzXCI7XG5cbmRlc2NyaWJlKCdUcmFuc2Zvcm1lcicsIGZ1bmN0aW9uICgpIHtcblxuICAgIGJlZm9yZShmdW5jdGlvbiAoZG9uZSkge1xuXG4gICAgICAgIGxldCBwcm9taXNlcyA9IFtdXG4gICAgICAgIHByb21pc2VzLnB1c2goaW5pdEpTRE9NKCkpO1xuICAgICAgICBpZiAoIWdsb2JhbFRoaXNbJ2NyeXB0byddKSB7XG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKGltcG9ydChcIkBwZWN1bGlhci93ZWJjcnlwdG9cIikudGhlbihtID0+IHtcbiAgICAgICAgICAgICAgICBnbG9iYWxUaGlzWydjcnlwdG8nXSA9IG5ldyBtLkNyeXB0bygpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfSkpXG4gICAgICAgIH1cblxuICAgICAgICBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7XG4gICAgICAgICAgICBkb25lKClcbiAgICAgICAgfSk7XG5cbiAgICB9KTtcblxuXG4gICAgZGVzY3JpYmUoJ1RyYW5zZm9ybWVyLnJ1bigpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIFtcbiAgICAgICAgICAgIFsnZXF1YWxzOmEnLCBcImFcIiwgdHJ1ZV0sXG4gICAgICAgICAgICBbJ2VxdWFsczphJywgXCJiXCIsIGZhbHNlXSxcbiAgICAgICAgICAgIFsnZXF1YWxzOjMnLCAzLCB0cnVlXSxcbiAgICAgICAgICAgIFsnZXF1YWxzOjMnLCA2LCBmYWxzZV0sXG4gICAgICAgICAgICBbJ2VxdWFsczpvbicsIHRydWUsIHRydWVdLFxuICAgICAgICAgICAgWydlcXVhbHM6dHJ1ZScsIHRydWUsIHRydWVdLFxuICAgICAgICAgICAgWydlcXVhbHM6b24nLCBmYWxzZSwgZmFsc2VdLFxuICAgICAgICAgICAgWydlcXVhbHM6dHJ1ZScsIGZhbHNlLCBmYWxzZV0sXG4gICAgICAgICAgICBbJ2VxdWFsczpvZmYnLCBmYWxzZSwgdHJ1ZV0sXG4gICAgICAgICAgICBbJ2VxdWFsczpmYWxzZScsIGZhbHNlLCB0cnVlXSxcbiAgICAgICAgICAgIFsnZXF1YWxzOm9mZicsIGZhbHNlLCB0cnVlXSxcbiAgICAgICAgICAgIFsnZXF1YWxzOmZhbHNlJywgdHJ1ZSwgZmFsc2VdLFxuICAgICAgICAgICAgWydlcXVhbHM6MycsIDMsIHRydWVdLFxuICAgICAgICAgICAgWydlcXVhbHM6MycsIDYsIGZhbHNlXSxcbiAgICAgICAgICAgIFsnZXF1YWxzOnVuZGVmaW5lZCcsIHVuZGVmaW5lZCwgdHJ1ZV0sXG4gICAgICAgICAgICBbJ2VxdWFsczp1bmRlZmluZWQnLCAzLCBmYWxzZV0sXG4gICAgICAgICAgICBbJ2VxdWFsczpudWxsJywgbnVsbCwgdHJ1ZV0sXG4gICAgICAgICAgICBbJ2VxdWFsczpudWxsJywgMywgZmFsc2VdLFxuICAgICAgICAgICAgWydlcXVhbHM6MycsIDYsIGZhbHNlXSxcbiAgICAgICAgICAgIFsnY3VycmVuY3knLCBcIkVVUjBcIiwgXCIwLDAwXHUwMEEwXHUyMEFDXCJdLFxuICAgICAgICAgICAgWydjdXJyZW5jeToxOjInLCBcIkVVUjE0LjI1XCIsIFwiMTQsMlx1MDBBMFx1MjBBQ1wiXSxcbiAgICAgICAgICAgIFsnY3VycmVuY3knLCBcIkVVUjE0LjI1XCIsIFwiMTQsMjVcdTAwQTBcdTIwQUNcIl0sXG4gICAgICAgICAgICBbJ2RhdGV0aW1lJywgXCIyMDIzLTAyLTE0IDE0OjEyOjEwXCIsIFwiMTQuMi4yMDIzLCAxNDoxMjoxMFwiXSxcbiAgICAgICAgICAgIFsnZGF0ZXRpbWUnLCBcIjIwMjMtMDItMTQgMDg6MDI6MDFcIiwgXCIxNC4yLjIwMjMsIDA4OjAyOjAxXCJdLFxuICAgICAgICAgICAgWydoYXMtZW50cmllcycsIHt9LCBmYWxzZV0sXG4gICAgICAgICAgICBbJ2hhcy1lbnRyaWVzJywge2E6NH0sIHRydWVdLFxuICAgICAgICAgICAgWydoYXMtZW50cmllcycsIFtdLCBmYWxzZV0sXG4gICAgICAgICAgICBbJ2hhcy1lbnRyaWVzJywgXCJcIiwgZmFsc2VdLFxuICAgICAgICAgICAgWydoYXMtZW50cmllcycsIFsxLDIsM10sIHRydWVdLFxuICAgICAgICAgICAgWydoYXMtZW50cmllcycsIFsxXSwgdHJ1ZV0sXG4gICAgICAgICAgICBbJ2hhcy1lbnRyaWVzJywgW1wiMVwiXSwgdHJ1ZV0sXG4gICAgICAgICAgICBbJ2hhcy1lbnRyaWVzJywgW3RydWVdLCB0cnVlXSxcbiAgICAgICAgICAgIFsnY29udGFpbnM6eCcsIFwiYXNkIHd4ZCBzZGZcIiwgdHJ1ZV0sXG4gICAgICAgICAgICBbJ2NvbnRhaW5zOngnLCBcImFzZCB3ZCBzZGZcIiwgZmFsc2VdLFxuICAgICAgICAgICAgWydjb250YWluczpiJywgW1wiYVwiLFwiYlwiLFwiY1wiXSwgdHJ1ZV0sXG4gICAgICAgICAgICBbJ2NvbnRhaW5zOngnLCBbXCJhXCIsXCJiXCIsXCJjXCJdLCBmYWxzZV0sXG4gICAgICAgICAgICBbJ2lzdW5kZWZpbmVkJywgXCJhXCIsIGZhbHNlXSxcbiAgICAgICAgICAgIFsnaXN1bmRlZmluZWQnLCBudWxsLCBmYWxzZV0sXG4gICAgICAgICAgICBbJ2lzdW5kZWZpbmVkJywgdW5kZWZpbmVkLCB0cnVlXSxcbiAgICAgICAgICAgIFsnaXNudWxsJywgXCJhXCIsIGZhbHNlXSxcbiAgICAgICAgICAgIFsnaXNudWxsJywgbnVsbCwgdHJ1ZV0sXG4gICAgICAgICAgICBbJ2lzc2V0JywgbnVsbCwgZmFsc2VdLFxuICAgICAgICAgICAgWydpc3NldCcsIHVuZGVmaW5lZCwgZmFsc2VdLFxuICAgICAgICAgICAgWydpc3NldCcsIFwiXCIsIHRydWVdLFxuICAgICAgICAgICAgWydpc251bWJlcicsIFwiYVwiLCBmYWxzZV0sXG4gICAgICAgICAgICBbJ2lzbnVtYmVyJywgNCwgdHJ1ZV0sXG4gICAgICAgICAgICBbJ2lzbnVtYmVyJywgNC41LCB0cnVlXSxcbiAgICAgICAgICAgIFsnaXNpbnRlZ2VyJywgNC41LCBmYWxzZV0sXG4gICAgICAgICAgICBbJ2lzaW50ZWdlcicsIDQsIHRydWVdLFxuICAgICAgICAgICAgWydpc2Zsb2F0JywgNS42LCB0cnVlXSxcbiAgICAgICAgICAgIFsnaXNmbG9hdCcsIDUsIGZhbHNlXSxcbiAgICAgICAgICAgIFsnaXNvYmplY3QnLCA0LCBmYWxzZV0sXG4gICAgICAgICAgICBbJ2lzb2JqZWN0Jywge30sIHRydWVdLFxuICAgICAgICAgICAgWydpc2FycmF5JywgW3t9XSwgdHJ1ZV0sXG4gICAgICAgICAgICBbJ2lzYXJyYXknLCBcImFcIiwgZmFsc2VdLFxuICAgICAgICAgICAgWydub3QnLCB0cnVlLCBmYWxzZV0sXG4gICAgICAgICAgICBbJ25vdCcsIGZhbHNlLCB0cnVlXSxcbiAgICAgICAgICAgIFsnbWFwOmE9NDpiPTU6Yz02JywgXCJhXCIsIFwiNFwiXSxcbiAgICAgICAgICAgIFsnZGF0ZScsIFwiMjAyMy0wMi0xNFwiLCBcIjE0LjIuMjAyM1wiXSxcbiAgICAgICAgICAgIFsneWVhcicsIFwiMjAyMy0wMi0xNFwiLCAyMDIzXSxcbiAgICAgICAgICAgIFsnbW9udGgnLCBcIjIwMjMtMDItMTRcIiwgMl0sXG4gICAgICAgICAgICBbJ2RheScsIFwiMjAyMy0wMi0xNFwiLCAxNF0sXG4gICAgICAgICAgICBbJ3dlZWtkYXknLCBcIjIwMjMtMDItMTRcIiwgMl0sXG4gICAgICAgICAgICBbJ21pbnV0ZXMnLCBcIjIwMjMtMDItMTQgMDY6MTI6MjFcIiwgMTJdLFxuICAgICAgICAgICAgWydzZWNvbmRzJywgXCIyMDIzLTAyLTE0IDA2OjEyOjIxXCIsIDIxXSxcbiAgICAgICAgICAgIFsnaG91cnMnLCBcIjIwMjMtMDItMTQgMDY6MTI6MjFcIiwgNl0sXG4gICAgICAgICAgICBbJ3RpbWUnLCBcIjIwMjMtMDItMTQgMDY6MTI6MjFcIiwgXCIwNjoxMjoyMVwiXSxcbiAgICAgICAgICAgIFsndGltZXN0YW1wJywgXCIyMDIzLTAyLTE0XCIsIDE2NzYzMzI4MDAwMDBdLFxuICAgICAgICAgICAgWydjb25jYXQ6YS5iLmM6dGVzdDphLmIuZCcsIHthOiB7Yjoge2M6IDQsIGQ6IDZ9fX0sIFwiNHRlc3Q2XCJdLFxuICAgICAgICAgICAgWydjb25jYXQ6YS5iLmM6XFxcXCBcXFxcIDphLmIuZCcsIHthOiB7Yjoge2M6IDQsIGQ6IDZ9fX0sIFwiNCAgNlwiXSxcbiAgICAgICAgICAgIFsnY29uY2F0OmEuYi5jOiw6YS5iLmQnLCB7YToge2I6IHtjOiA0LCBkOiA2fX19LCBcIjQsNlwiXSxcbiAgICAgICAgICAgIFsnY29uY2F0OmEuYi5jOiw6XFxcXCA6YS5iLmQnLCB7YToge2I6IHtjOiA0LCBkOiA2fX19LCBcIjQsIDZcIl0sXG4gICAgICAgICAgICBbJz8/OmEnLCBudWxsLCAnYSddLFxuICAgICAgICAgICAgWyc/PzphJywgdW5kZWZpbmVkLCAnYSddLFxuICAgICAgICAgICAgWyc/PzphJywgJ3RydWUnLCAndHJ1ZSddLFxuICAgICAgICAgICAgWyc/PzphJywgZmFsc2UsIGZhbHNlXSxcbiAgICAgICAgICAgIFsnIGlmOmE6ICcsIGZhbHNlLCB1bmRlZmluZWRdLCAvLyB3aXRob3V0IFxcXFxcbiAgICAgICAgICAgIFsnIGlmOmE6XFxcXCAnLCBmYWxzZSwgXCIgXCJdLFxuICAgICAgICAgICAgWycgaWY6YTpcXFxcICcsIHRydWUsIFwiYVwiXSxcbiAgICAgICAgICAgIFsnZGVmYXVsdDp5ZXMnLCBudWxsLCAneWVzJ10sXG4gICAgICAgICAgICBbJ2RlZmF1bHQ6eWVzJywgdW5kZWZpbmVkLCAneWVzJ10sXG4gICAgICAgICAgICBbJ2RlZmF1bHQ6MTpib29sJywgdW5kZWZpbmVkLCB0cnVlXSxcbiAgICAgICAgICAgIFsnZGVmYXVsdDpvbjpib29sJywgdW5kZWZpbmVkLCB0cnVlXSxcbiAgICAgICAgICAgIFsnZGVmYXVsdDp0cnVlOmJvb2wnLCB1bmRlZmluZWQsIHRydWVdLFxuICAgICAgICAgICAgWydkZWZhdWx0Onllczpib29sJywgdW5kZWZpbmVkLCB0cnVlXSxcbiAgICAgICAgICAgIFsnZGVmYXVsdDp1bmRlZmluZWQ6Ym9vbCcsIHVuZGVmaW5lZCwgZmFsc2VdLFxuICAgICAgICAgICAgWydkZWZhdWx0OmZhbHNlOmJvb2wnLCB1bmRlZmluZWQsIGZhbHNlXSxcbiAgICAgICAgICAgIFsnZGVmYXVsdDoxOmludCcsIHVuZGVmaW5lZCwgMV0sXG4gICAgICAgICAgICBbJ2RlZmF1bHQ6MTpzdHJpbmcnLCB1bmRlZmluZWQsICcxJ10sXG4gICAgICAgICAgICBbJ2ZpcnN0LWtleScsIHthOiAxLCBjOiAzLCBiOiAyfSwgMV0sXG4gICAgICAgICAgICBbJ2xhc3Qta2V5Jywge2E6IDEsIGM6IDMsIGI6IDJ9LCAzXSxcbiAgICAgICAgICAgIFsnbnRoLWxhc3Qta2V5OjAnLCB7YTogMSwgYzogMywgYjogMn0sIDNdLFxuICAgICAgICAgICAgWydudGgtbGFzdC1rZXk6MScsIHthOiAxLCBjOiAzLCBiOiAyfSwgMl0sXG4gICAgICAgICAgICBbJ250aC1sYXN0LWtleToyJywge2E6IDEsIGM6IDMsIGI6IDJ9LCAxXSxcbiAgICAgICAgICAgIFsnbnRoLWtleToyJywge2E6IDEsIGI6IDIsIGM6IDN9LCAzXSxcbiAgICAgICAgICAgIFsnbnRoLWtleTowJywge2M6IDMsIGE6IDEsIGI6IDJ9LCAxXSxcbiAgICAgICAgICAgIFsnbnRoLWtleToyJywge2E6IDEsIGM6IDMsIGI6IDJ9LCAzXSxcbiAgICAgICAgICAgIFsncHJlZml4OkhlbGxvXFxcXCAnLCAndGVzdCcsIFwiSGVsbG8gdGVzdFwiXSxcbiAgICAgICAgICAgIFsndG9qc29uJywge2E6IDR9LCBcIntcXFwiYVxcXCI6NH1cIl0sXG4gICAgICAgICAgICBbJ3ByZWZpeDphXFxcXFxcXFw6ICcsICd0ZXN0JywgXCJhXFxcXHRlc3RcIl0sXG4gICAgICAgICAgICBbJ3ByZWZpeDphXFxcXCAnLCAndGVzdCcsIFwiYSB0ZXN0XCJdLFxuICAgICAgICAgICAgWydzdGF0aWM6YWJjOmE6Yjp4JywgXCJ0ZXN0XCIsIFwiYWJjOmE6Yjp4XCJdLFxuICAgICAgICAgICAgWyd0b2xvd2VyY2FzZScsIFwiQTpiOkNzZTRcIiwgXCJhOmI6Y3NlNFwiXSxcbiAgICAgICAgICAgIFsndG91cHBlcicsIFwiQTpiOkNzZTRcIiwgXCJBOkI6Q1NFNFwiXSxcbiAgICAgICAgICAgIFsndG9zdHJpbmcnLCA1LCBcIjVcIl0sXG4gICAgICAgICAgICBbJ3Rvc3RyaW5nJywgWzEsIDIsIDMsIHt9XSwgXCIxLDIsMyxbb2JqZWN0IE9iamVjdF1cIl0sXG4gICAgICAgICAgICBbJ3RvaW50ZWdlcicsIFwiNVwiLCA1XSxcbiAgICAgICAgICAgIFsndHJpbScsIFwiIDUgXCIsIFwiNVwiXSxcbiAgICAgICAgICAgIFsndHJpbScsIFwiIGFcIiwgXCJhXCJdLFxuICAgICAgICAgICAgWyd0cmltJywgXCIgXCIsIFwiXCJdLFxuICAgICAgICAgICAgWydyYXd1cmxlbmNvZGUnLCBcIlx1MDBGQ1x1MDBGNlx1MDBFNFwiLCBcIiVDMyVCQyVDMyVCNiVDMyVBNFwiXSxcbiAgICAgICAgICAgIFsnY2FsbDp0ZXN0Y2FsbGJhY2s6NDo1OjYnLCBcInRlc3RcIiwgXCJ0ZXN0NDU2XCJdLFxuICAgICAgICAgICAgWydwbGFpbicsICd0PGJyPmVzdCcsIFwidGVzdFwiXSxcbiAgICAgICAgICAgIFsnaWY6YTpiJywgdHJ1ZSwgXCJhXCJdLFxuICAgICAgICAgICAgWydpZjphOmInLCAnb24nLCBcImFcIl0sXG4gICAgICAgICAgICBbJ2lmOmE6YicsICd0cnVlJywgXCJhXCJdLFxuICAgICAgICAgICAgWydpZjphOmInLCAnZmFsc2UnLCBcImJcIl0sXG4gICAgICAgICAgICBbJ2lmOmE6YicsIDksIFwiYVwiXSxcbiAgICAgICAgICAgIFsnaWY6YTpiJywgJycsIFwiYlwiXSxcbiAgICAgICAgICAgIFsnaWY6YTpiJywgdW5kZWZpbmVkLCBcImJcIl0sXG4gICAgICAgICAgICBbJ2lmOmE6YicsIGZhbHNlLCBcImJcIl0sXG4gICAgICAgICAgICBbJ3VjZmlyc3QnLCAnY2FyJywgXCJDYXJcIl0sXG4gICAgICAgICAgICBbJ3VjZmlyc3QnLCAnY0FyJywgXCJDQXJcIl0sXG4gICAgICAgICAgICBbJ2RlZmF1bHQ6dGVzdCcsICdhJywgXCJhXCJdLFxuICAgICAgICAgICAgWydkZWZhdWx0OnRlc3QnLCB1bmRlZmluZWQsIFwidGVzdFwiXSxcbiAgICAgICAgICAgIFsnZnJvbWpzb24nLCAne30nLCB7fV0sXG4gICAgICAgICAgICBbJ2Zyb21qc29uJywgJ3tcImFcIjoxfScsIHthOiAxfV0sXG4gICAgICAgICAgICBbJ3Vjd29yZHMnLCAnY0FyIHJ1bnMnLCBcIkNBciBSdW5zXCJdLFxuICAgICAgICAgICAgWyd0b2ludGVnZXInLCAnNicsIDZdLFxuICAgICAgICAgICAgWydsZW5ndGgnLCAndGVzdCcsIDRdLFxuICAgICAgICAgICAgWyd0by1iYXNlNjQnLCAnSGVsbG8gV29ybGQhJywgXCJTR1ZzYkc4Z1YyOXliR1FoXCJdLFxuICAgICAgICAgICAgWydmcm9tLWJhc2U2NCcsICdTR1ZzYkc4Z1YyOXliR1FoJywgXCJIZWxsbyBXb3JsZCFcIl0sXG4gICAgICAgICAgICBbJ3RvLWJhc2U2NCcsICd0ZXN0JywgXCJkR1Z6ZEE9PVwiXSxcbiAgICAgICAgICAgIFsnZnJvbS1iYXNlNjQnLCBcImRHVnpkQT09XCIsICd0ZXN0J10sXG4gICAgICAgICAgICBbJ3ByZWZpeDphJywgJ3Rlc3QnLCBcImF0ZXN0XCJdLFxuICAgICAgICAgICAgWydzdWZmaXg6YScsICd0ZXN0JywgXCJ0ZXN0YVwiXSxcbiAgICAgICAgICAgIFsnaW5kZXg6YScsIHthOiA0fSwgNF0sXG4gICAgICAgICAgICBbJ2luZGV4OjInLCBbMiwgNCwgN10sIDddLFxuICAgICAgICAgICAgWydpbmRleDp4OnRlc3QnLCBbMiwgNCwgN10sICd0ZXN0J10sXG4gICAgICAgICAgICBbJ3BhdGg6YS5iLmMnLCB7YToge2I6IHtjOiA0fX19LCA0XSxcbiAgICAgICAgICAgIFsncGF0aDphLmIuZCcsIHthOiB7Yjoge2M6IDR9fX0sIHVuZGVmaW5lZF0sXG4gICAgICAgICAgICBbJ2luZGV4OmEnLCBuZXcgTWFwKCkuc2V0KCdhJywgNSksIDVdLFxuICAgICAgICAgICAgWydzdWJzdHJpbmc6Mjo0JywgJ2FiY2RlZmdoaWprbG1ub3AnLCAnY2RlZiddLFxuICAgICAgICAgICAgWydub3AnLCAnYWJjZGVmZ2hpamtsbW5vcCcsICdhYmNkZWZnaGlqa2xtbm9wJ10sXG5cbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGMgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ1RyYW5zZm9ybWVyLnJ1bignICsgSlNPTi5zdHJpbmdpZnkoYSkgKyAnKS5ydW4oJyArIEpTT04uc3RyaW5naWZ5KGIpICsgJykgc2hvdWxkIHJldHVybiAnICsgSlNPTi5zdHJpbmdpZnkoYyksIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBsZXQgdCA9IG5ldyBUcmFuc2Zvcm1lcihhKTtcblxuICAgICAgICAgICAgICAgIHQuc2V0Q2FsbGJhY2soJ3Rlc3RjYWxsYmFjaycsIGZ1bmN0aW9uIChhLCBiLCBjLCBkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBhICsgYiArIGMgKyBkO1xuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgY29uc3QgciA9IHQucnVuKGIpO1xuICAgICAgICAgICAgICAgIGV4cGVjdChyKS50by5iZS5lcWwoYyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdUcmFuc2Zvcm1lci5ydW4oKSB0aHJvd3MgRXJyb3InLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWyd0b2xvd2VyY2FzZScsIFtdXSxcbiAgICAgICAgICAgIFsndG9sb3dlcmNhc2UnLCB7fV0sXG4gICAgICAgICAgICBbJ3RvbG93ZXJjYXNlJywgNC41XSxcbiAgICAgICAgICAgIFsndG91cHBlcicsIHRydWVdLFxuICAgICAgICAgICAgWyd0b3VwcGVyJywgNV0sXG4gICAgICAgICAgICBbJ3RvaW50ZWdlcicsIFwiYVwiXSxcbiAgICAgICAgICAgIFsndHJpbScsIDVdLFxuICAgICAgICAgICAgWyd0cmltJywgdHJ1ZV0sXG4gICAgICAgICAgICBbJ3RyaW0nLCB7fV0sXG4gICAgICAgICAgICBbJ3RyaW0nLCBbXV0sXG4gICAgICAgICAgICBbJ3Jhd3VybGVuY29kZScsIFtdXSxcbiAgICAgICAgICAgIFsnaWY6YTpiJywge31dLFxuICAgICAgICAgICAgWyd1Y3dvcmRzJywge31dLFxuICAgICAgICAgICAgWyd1Y3dvcmRzJywgZmFsc2VdLFxuICAgICAgICAgICAgWyd1Y3dvcmRzJywgNF0sXG4gICAgICAgICAgICBbJ3BhdGg6YS5iLmMnLCBcIlwiLCA0XSxcbiAgICAgICAgICAgIFsndG9pbnRlZ2VyJywge31dLFxuICAgICAgICAgICAgWydiYXNlNjQnLCB7fV0sXG4gICAgICAgICAgICBbJ2Zyb21qc29uJywgJyddLFxuICAgICAgICAgICAgWydwcmVmaXgnLCB7fV0sXG4gICAgICAgICAgICBbJ3N1ZmZpeCcsIHt9XSxcbiAgICAgICAgICAgIFsnaW5kZXgnLCBcInRlc3RcIl0sXG4gICAgICAgICAgICBbJ3h4eHh4eCcsIFwidGVzdFwiXSwgLy8gdW5zdXBwb3J0ZWQgY29tbWFuZFxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGl0KCdUcmFuc2Zvcm1lci5ydW4oJyArIEpTT04uc3RyaW5naWZ5KGEpICsgJykucnVuKCcgKyBKU09OLnN0cmluZ2lmeShiKSArICcpIHNob3VsZCB0aHJvdyBFcnJvciAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbGV0IHQgPSBuZXcgVHJhbnNmb3JtZXIoYSk7XG4gICAgICAgICAgICAgICAgZXhwZWN0KCgpID0+IHQucnVuKGIpKS50by50aHJvdyhFcnJvcilcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgIH0pO1xuXG5cbiAgICBkZXNjcmliZSgnbmV3IFRyYW5zZm9ybWVyKCkucnVuKFwidW5pcWlkXCIpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBTdHJpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgdCA9IG5ldyBUcmFuc2Zvcm1lcigndW5pcWlkJyk7XG4gICAgICAgICAgICBleHBlY3QodC5ydW4oXCJcIikpLnRvLmJlLmEoJ3N0cmluZycpO1xuICAgICAgICB9KTtcblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ25ldyBUcmFuc2Zvcm1lcigpLnJ1bihcImRlZmF1bHQ6ZXlKaUlqb3hmUT09Om9iamVjdFwiKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gT2JqZWN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGV0IHQgPSBuZXcgVHJhbnNmb3JtZXIoJ2RlZmF1bHQ6ZXlKaUlqb3hmUT09Om9iamVjdCcpO1xuICAgICAgICAgICAgZXhwZWN0KHQucnVuKHVuZGVmaW5lZCkpLnRvLmVxbCh7YjogMX0pO1xuICAgICAgICB9KTtcblxuICAgIH0pO1xuXG5cbiAgICBkZXNjcmliZSgnbmV3IFRyYW5zZm9ybWVyKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGluc3RhbmNlb2YgVHJhbnNmb3JtZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IFRyYW5zZm9ybWVyKFwiXCIpKS50by5pbnN0YW5jZU9mKFRyYW5zZm9ybWVyKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gaW5zdGFuY2VvZiBUcmFuc2Zvcm1lcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgVHJhbnNmb3JtZXIoXCJzdWZmaXg6YWJjXCIpKS50by5pbnN0YW5jZU9mKFRyYW5zZm9ybWVyKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ2ZhbHNlIGFzIGFyZ3VtZW50IHNob3VsZCB0aHJvdyBUeXBlRXJyb3InLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QoKCkgPT4ge1xuICAgICAgICAgICAgICAgIG5ldyBUcmFuc2Zvcm1lcihmYWxzZSlcbiAgICAgICAgICAgIH0pLnRvLnRocm93KFR5cGVFcnJvcik7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdvYmplY3QgYXMgYXJndW1lbnQgc2hvdWxkIHRocm93IFR5cGVFcnJvcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgbmV3IFRyYW5zZm9ybWVyKHt9KVxuICAgICAgICAgICAgfSkudG8udGhyb3coVHlwZUVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cblxuICAgIGRlc2NyaWJlKCdpMThuJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGxldCBodG1sMSA9IGBcbjxkaXYgaWQ9XCJtb2NrLXRyYW5zbGF0aW9uc1wiPjwvZGl2PlxuPHNjcmlwdCB0eXBlPVwiYXBwbGljYXRpb24vanNvblwiIGRhdGEtbW9uc3Rlci1yb2xlPVwidHJhbnNsYXRpb25zXCI+XG4gICAge1xuICAgICAgICBcInRlc3QxXCI6IFwieHl6XCIsXG4gICAgICAgIFwidGVzdDNcIjoge1xuICAgICAgICAgICAgXCJvdGhlclwiOiBcInh5elwiXG4gICAgICAgIH1cbiAgICB9XG48L3NjcmlwdD4gIFxuYDtcblxuICAgICAgICBiZWZvcmVFYWNoKChkb25lKSA9PiB7XG4gICAgICAgICAgICBsZXQgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgICAgIG1vY2tzLmlubmVySFRNTCA9IGh0bWwxO1xuICAgICAgICAgICAgbGV0IGVsZW0gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9jay10cmFuc2xhdGlvbnMnKTtcbiAgICAgICAgICAgIEVtYmVkLmFzc2lnblRyYW5zbGF0aW9uc1RvRWxlbWVudChlbGVtKS50aGVuKChvKSA9PiB7XG4gICAgICAgICAgICAgICAgZG9uZSgpXG4gICAgICAgICAgICB9KVxuXG5cbiAgICAgICAgfSlcblxuICAgICAgICBhZnRlckVhY2goKCkgPT4ge1xuICAgICAgICAgICAgbGV0IG1vY2tzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vY2tzJyk7XG4gICAgICAgICAgICBtb2Nrcy5pbm5lckhUTUwgPSBcIlwiO1xuICAgICAgICB9KVxuXG4gICAgICAgIGJlZm9yZShmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICAgICAgaW5pdEpTRE9NKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgZG9uZSgpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWydpMThuOnRlc3QxJywgXCJcIiwgXCJ4eXpcIl0sXG4gICAgICAgICAgICBbJ2kxOG46JywgXCJ0ZXN0MVwiLCBcInh5elwiXSwgLy8ga2V5IGJ5IHZhbHVlXG4gICAgICAgICAgICBbJ2kxOG46OicsIFwidGVzdDFcIiwgXCJ4eXpcIl0sIC8vIGtleSBieSB2YWx1ZSBubyBkZWZhdWx0XG4gICAgICAgICAgICBbJ2kxOG46OmVlZScsIFwidGVzdDJcIiwgXCJlZWVcIl0sIC8vIGtleSBieSB2YWx1ZSB3aXRoIGRlZmF1bHRcbiAgICAgICAgICAgIFsnaTE4bjo6ZGRkJywgXCJ0ZXN0MlwiLCBcImRkZFwiXSwgLy8ga2V5IGJ5IHZhbHVlIGFuZCBkZWZhdWx0XG5cbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGMgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ3Nob3VsZCB0cmFuc2Zvcm0oJyArIGEgKyAnKS5ydW4oJyArIGIgKyAnKSByZXR1cm4gJyArIEpTT04uc3RyaW5naWZ5KGMpLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdCA9IG5ldyBUcmFuc2Zvcm1lcihhKTtcbiAgICAgICAgICAgICAgICBleHBlY3QodC5ydW4oYikpLnRvLmJlLmVxbChjKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuICAgIH0pXG5cblxufSk7IiwgIlwidXNlIHN0cmljdFwiO1xuXG5pbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuaW1wb3J0IHtQYXRoZmluZGVyfSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2RhdGEvcGF0aGZpbmRlci5tanNcIjtcblxuZGVzY3JpYmUoJ1BhdGhmaW5kZXInLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBsZXQgY29udmVydE1hcFJlc3VsdCA9IGZ1bmN0aW9uIChyKSB7XG4gICAgICAgIGlmIChyIGluc3RhbmNlb2YgTWFwKSB7XG4gICAgICAgICAgICByID0gT2JqZWN0LmZyb21FbnRyaWVzKHIpO1xuICAgICAgICAgICAgaWYgKHIgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAgICAgICAgIHIgPSByLm1hcCgoZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29udmVydE1hcFJlc3VsdChlKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgciA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW2ssIG9dIG9mIE9iamVjdC5lbnRyaWVzKHIpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJba10gPSBjb252ZXJ0TWFwUmVzdWx0KG8pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByO1xuICAgIH1cblxuXG4gICAgZGVzY3JpYmUoJ3dpdGggV2lsZGNhcmQgYW5kIEl0ZXJhdGlvbnMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCBwZiwgb2JqO1xuXG4gICAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgb2JqID0ge1xuICAgICAgICAgICAgICAgIGE6IFtcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgYjogW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYzogXCIxLTFcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjOiBcIjEtMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGQ6ICchJ1xuXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGI6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGM6IFwiMi0xXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYzogXCIyLTJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgICAgICAgICBkOiAnPydcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBmID0gbmV3IFBhdGhmaW5kZXIob2JqKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWydhLiouYi4qJywgJ3tcIjBcIjp7XCIwXCI6e1wiY1wiOlwiMS0xXCJ9LFwiMVwiOntcImNcIjpcIjEtMlwifX0sXCIxXCI6e1wiMFwiOntcImNcIjpcIjItMVwifSxcIjFcIjp7XCJjXCI6XCIyLTJcIn19fSddLFxuICAgICAgICAgICAgWydhLiouYicsICd7XCIwXCI6W3tcImNcIjpcIjEtMVwifSx7XCJjXCI6XCIxLTJcIn1dLFwiMVwiOlt7XCJjXCI6XCIyLTFcIn0se1wiY1wiOlwiMi0yXCJ9XX0nXSxcbiAgICAgICAgICAgIFsnYS4xLmInLCAnW3tcImNcIjpcIjItMVwifSx7XCJjXCI6XCIyLTJcIn1dJ10sXG4gICAgICAgICAgICBbJ2EuMC5iJywgJ1t7XCJjXCI6XCIxLTFcIn0se1wiY1wiOlwiMS0yXCJ9XSddLFxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG5cblxuICAgICAgICAgICAgaXQoJy5zZXRWaWEoJyArIGEgKyAnKSBzaG91bGQgcmVzdWx0IGluICcgKyBiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbGV0IHIgPSBwZi5nZXRWaWEoYSk7XG4gICAgICAgICAgICAgICAgbGV0IGkgPSBjb252ZXJ0TWFwUmVzdWx0KHIpO1xuICAgICAgICAgICAgICAgIGV4cGVjdChKU09OLnN0cmluZ2lmeShpKSkuaXMuZXF1YWwoYik7XG4gICAgICAgICAgICB9KTtcblxuXG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxuXG4gICAgZGVzY3JpYmUoJ2FwaSB0ZXN0cycsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBsZXQgcGF0aGZpbmRlciwgb2JqZWN0O1xuXG5cbiAgICAgICAgY2xhc3MgQSB7XG4gICAgICAgICAgICBnZXQgYSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gMVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgYmVmb3JlRWFjaCgoKSA9PiB7XG5cbiAgICAgICAgICAgIG9iamVjdCA9IHtcbiAgICAgICAgICAgICAgICBhOiB7XG4gICAgICAgICAgICAgICAgICAgIGI6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGM6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA0LCBcInRlc3QxXCIsIGZhbHNlLCB1bmRlZmluZWQsIHBhcnNlSW50KFwiYVwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGQ6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgZjogW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZzogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGg6IDMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGk6IFtcInRlc3QyXCJdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGo6IHt9LFxuICAgICAgICAgICAgICAgICAgICAgICAgazogKG5ldyBNYXApLnNldCgnbScsIHtuOiAzfSksXG4gICAgICAgICAgICAgICAgICAgICAgICBsOiAobmV3IFNldCkuYWRkKHtuOiA0fSlcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgYjogbmV3IEFcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHBhdGhmaW5kZXIgPSBuZXcgUGF0aGZpbmRlcihvYmplY3QpO1xuXG5cbiAgICAgICAgfSk7XG5cbiAgICAgICAgZGVzY3JpYmUoJ2NyZWF0ZSBuZXcgb2JqZWN0JywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgWzEyXSxcbiAgICAgICAgICAgICAgICBbdW5kZWZpbmVkXSxcbiAgICAgICAgICAgICAgICBbbnVsbF0sXG4gICAgICAgICAgICAgICAgW1widGVzdFwiXVxuICAgICAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgICAgIGxldCBsYWJlbCA9IHR5cGVvZiBhO1xuICAgICAgICAgICAgICAgIGlmIChhID09PSBudWxsKSBsYWJlbCA9ICdudWxsJztcblxuXG4gICAgICAgICAgICAgICAgaXQobGFiZWwgKyAnIHNob3VsZCB0aHJvdyBlcnJvcicsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgICAgICBleHBlY3QoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFBhdGhmaW5kZXIoYSlcbiAgICAgICAgICAgICAgICAgICAgfSkudG8udGhyb3coRXJyb3IpXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSlcblxuICAgICAgICBkZXNjcmliZSgnLnNldFZpYSh4KScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgbGV0IHBmLCBvYmo7XG5cbiAgICAgICAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIG9iaiA9IHt9XG4gICAgICAgICAgICAgICAgcGYgPSBuZXcgUGF0aGZpbmRlcihvYmopO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICBbJ2EuYi4wLjAuYycsIHRydWUsICd7XCJhXCI6e1wiYlwiOltbe1wiY1wiOnRydWV9XV19fSddLFxuICAgICAgICAgICAgICAgIFsnYS5iLjAuYycsIHRydWUsICd7XCJhXCI6e1wiYlwiOlt7XCJjXCI6dHJ1ZX1dfX0nXSxcbiAgICAgICAgICAgICAgICBbJ2EuYi4zLmMnLCB0cnVlLCAne1wiYVwiOntcImJcIjpbbnVsbCxudWxsLG51bGwse1wiY1wiOnRydWV9XX19J10sXG4gICAgICAgICAgICAgICAgWydhLmIuYycsIHRydWUsICd7XCJhXCI6e1wiYlwiOntcImNcIjp0cnVlfX19J11cbiAgICAgICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgICAgIGxldCBjID0gZGF0YS5zaGlmdCgpXG5cblxuICAgICAgICAgICAgICAgIGl0KCcuc2V0VmlhKCcgKyBhICsgJywgJyArIGIgKyAnKSBzaG91bGQgcmVzdWx0IGluICcgKyBjLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHBmLnNldFZpYShhLCBiKVxuICAgICAgICAgICAgICAgICAgICBleHBlY3QoSlNPTi5zdHJpbmdpZnkob2JqKSkuaXMuZXF1YWwoYyk7XG4gICAgICAgICAgICAgICAgfSk7XG5cblxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgfSlcblxuICAgICAgICBkZXNjcmliZSgnLnNldFZpYSgpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBsZXQgYTtcbiAgICAgICAgICAgIGxldCBiO1xuICAgICAgICAgICAgbGV0IGM7XG5cbiAgICAgICAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGEgPSBcImEueFwiO1xuICAgICAgICAgICAgICAgIGIgPSBcInRydWVcIjtcbiAgICAgICAgICAgICAgICBjID0gXCJhLnkuZFwiO1xuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgaXQoJy5zZXRWaWEoJyArIGEgKyAnLCAnICsgYiArICcpIHNob3VsZCByZXR1cm4gUGF0aGZpbmRlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBleHBlY3QocGF0aGZpbmRlci5zZXRWaWEoYSwgYikpLmlzLmluc3RhbmNlT2YoUGF0aGZpbmRlcik7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaXQoJy5zZXRWaWEoJyArIGEgKyAnLCAnICsgYiArICcpIHNob3VsZCBjaGFuZ2Ugb2JqZWN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHBhdGhmaW5kZXIuc2V0VmlhKGEsIGIpO1xuICAgICAgICAgICAgICAgIGV4cGVjdChKU09OLnN0cmluZ2lmeShvYmplY3QpKS5pcy5lcXVhbCgne1wiYVwiOntcImJcIjp7XCJjXCI6WzQsXCJ0ZXN0MVwiLGZhbHNlLG51bGwsbnVsbF0sXCJlXCI6ZmFsc2UsXCJmXCI6W3tcImdcIjpmYWxzZSxcImhcIjozLFwiaVwiOltcInRlc3QyXCJdfV0sXCJqXCI6e30sXCJrXCI6e30sXCJsXCI6e319LFwieFwiOlwidHJ1ZVwifSxcImJcIjp7fX0nKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpdCgnLnNldFZpYSgnICsgYyArICcsICcgKyBiICsgJykgc2hvdWxkIGNoYW5nZSBvYmplY3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcGF0aGZpbmRlci5zZXRWaWEoYywgYik7XG4gICAgICAgICAgICAgICAgZXhwZWN0KEpTT04uc3RyaW5naWZ5KG9iamVjdCkpLmlzLmVxdWFsKCd7XCJhXCI6e1wiYlwiOntcImNcIjpbNCxcInRlc3QxXCIsZmFsc2UsbnVsbCxudWxsXSxcImVcIjpmYWxzZSxcImZcIjpbe1wiZ1wiOmZhbHNlLFwiaFwiOjMsXCJpXCI6W1widGVzdDJcIl19XSxcImpcIjp7fSxcImtcIjp7fSxcImxcIjp7fX0sXCJ5XCI6e1wiZFwiOlwidHJ1ZVwifX0sXCJiXCI6e319Jyk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICB9KTtcblxuXG4gICAgICAgIGRlc2NyaWJlKCcuZXhpc3RzKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgWydhLmIuYy4xJywgdHJ1ZV0sXG4gICAgICAgICAgICAgICAgWydiLmEnLCB0cnVlXSxcbiAgICAgICAgICAgICAgICBbJ2EuYi54JywgZmFsc2VdLFxuICAgICAgICAgICAgICAgIFsnYS54JywgZmFsc2VdLFxuICAgICAgICAgICAgICAgIFsnYS5iLnEnLCBmYWxzZV0sXG4gICAgICAgICAgICAgICAgWydhLmIuYy4wJywgdHJ1ZV0sXG4gICAgICAgICAgICAgICAgWydhLmIuZCcsIHRydWVdLFxuICAgICAgICAgICAgICAgIFsnYS5iLmYuMC5nJywgdHJ1ZV0sXG4gICAgICAgICAgICAgICAgWydhLmIuZi4wLmkuMCcsIHRydWVdLFxuICAgICAgICAgICAgICAgIFsnYS5iLmYuMC5pLjInLCBmYWxzZV0sXG4gICAgICAgICAgICAgICAgWydhLmIuZScsIHRydWVdLFxuICAgICAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG5cblxuICAgICAgICAgICAgICAgIGl0KCcuZXhpc3RzKCcgKyBhICsgJykgc2hvdWxkIHJldHVybiAnICsgYiArICcgJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QocGF0aGZpbmRlci5leGlzdHMoYSkpLmlzLmVxdWFsKGIpO1xuICAgICAgICAgICAgICAgIH0pO1xuXG5cbiAgICAgICAgICAgIH0pO1xuXG5cbiAgICAgICAgfSk7XG5cbiAgICAgICAgZGVzY3JpYmUoJy5kZWxldGVWaWEoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICBbJ2EuYi5lJywgJ3tcImFcIjp7XCJiXCI6e1wiY1wiOls0LFwidGVzdDFcIixmYWxzZSxudWxsLG51bGxdLFwiZlwiOlt7XCJnXCI6ZmFsc2UsXCJoXCI6MyxcImlcIjpbXCJ0ZXN0MlwiXX1dLFwialwiOnt9LFwia1wiOnt9LFwibFwiOnt9fX0sXCJiXCI6e319J10sXG4gICAgICAgICAgICAgICAgWydhLmIuZicsICd7XCJhXCI6e1wiYlwiOntcImNcIjpbNCxcInRlc3QxXCIsZmFsc2UsbnVsbCxudWxsXSxcImVcIjpmYWxzZSxcImpcIjp7fSxcImtcIjp7fSxcImxcIjp7fX19LFwiYlwiOnt9fSddLFxuICAgICAgICAgICAgICAgIFsnYS5iLmonLCAne1wiYVwiOntcImJcIjp7XCJjXCI6WzQsXCJ0ZXN0MVwiLGZhbHNlLG51bGwsbnVsbF0sXCJlXCI6ZmFsc2UsXCJmXCI6W3tcImdcIjpmYWxzZSxcImhcIjozLFwiaVwiOltcInRlc3QyXCJdfV0sXCJrXCI6e30sXCJsXCI6e319fSxcImJcIjp7fX0nXSxcblxuICAgICAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgICAgICBpdCgnLmRlbGV0ZVZpYSgnICsgYSArICcpIHNob3VsZCByZXR1cm4gJyArIGIgKyAnICcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgcGF0aGZpbmRlci5kZWxldGVWaWEoYSlcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KEpTT04uc3RyaW5naWZ5KG9iamVjdCkpLmlzLmVxdWFsKGIpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGRlc2NyaWJlKCcuZ2V0VmlhKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBkZXNjcmliZSgnLmdldFZpYSgpJywgZnVuY3Rpb24gKCkge1xuXG5cbiAgICAgICAgICAgICAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgICAgICBvYmplY3QgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA0LCBcInRlc3QxXCIsIGZhbHNlLCB1bmRlZmluZWQsIHBhcnNlSW50KFwiYVwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZzogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaDogMyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpOiBbXCJ0ZXN0MlwiXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqOiB7fSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgazogKG5ldyBNYXApLnNldCgnbScsIHtuOiAzfSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGw6IChuZXcgU2V0KS5hZGQoe246IDR9KSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbzogW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3A6IHtxOiAxLCByOiB0cnVlfX0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7cDoge3E6IDIsIHI6IHRydWV9fSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtwOiB7cTogMywgcjogdHJ1ZX19LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3A6IHtxOiA0LCByOiB0cnVlfX0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7cDoge3E6IDUsIHI6IHRydWV9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0OiB7YTogMX0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1OiB7YTogMn0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2OiB7YTogM30sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiB7YTogNH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICBwYXRoZmluZGVyID0gbmV3IFBhdGhmaW5kZXIob2JqZWN0KTtcblxuXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgICAgIFsnYS4qJywgJ1tbXCJiXCIse1wiY1wiOls0LFwidGVzdDFcIixmYWxzZSxudWxsLG51bGxdLFwiZVwiOmZhbHNlLFwiZlwiOlt7XCJnXCI6ZmFsc2UsXCJoXCI6MyxcImlcIjpbXCJ0ZXN0MlwiXX1dLFwialwiOnt9LFwia1wiOnt9LFwibFwiOnt9LFwib1wiOlt7XCJwXCI6e1wicVwiOjEsXCJyXCI6dHJ1ZX19LHtcInBcIjp7XCJxXCI6MixcInJcIjp0cnVlfX0se1wicFwiOntcInFcIjozLFwiclwiOnRydWV9fSx7XCJwXCI6e1wicVwiOjQsXCJyXCI6dHJ1ZX19LHtcInBcIjp7XCJxXCI6NSxcInJcIjp0cnVlfX1dLFwic1wiOntcInRcIjp7XCJhXCI6MX0sXCJ1XCI6e1wiYVwiOjJ9LFwidlwiOntcImFcIjozfSxcInhcIjp7XCJhXCI6NH19fV1dJ10sXG4gICAgICAgICAgICAgICAgICAgIFsnYS5iLnMuKi5hJywgJ1tbXCJ0XCIsMV0sW1widVwiLDJdLFtcInZcIiwzXSxbXCJ4XCIsNF1dJ10sXG4gICAgICAgICAgICAgICAgICAgIFsnYS5iLnMuKicsICdbW1widFwiLHtcImFcIjoxfV0sW1widVwiLHtcImFcIjoyfV0sW1widlwiLHtcImFcIjozfV0sW1wieFwiLHtcImFcIjo0fV1dJ10sXG4gICAgICAgICAgICAgICAgICAgIFsnYS5iLm8uKi5wLnEnLCAnW1tcIjBcIiwxXSxbXCIxXCIsMl0sW1wiMlwiLDNdLFtcIjNcIiw0XSxbXCI0XCIsNV1dJ10sXG4gICAgICAgICAgICAgICAgICAgIFsnYS5iLm8uKi5wLnInLCAnW1tcIjBcIix0cnVlXSxbXCIxXCIsdHJ1ZV0sW1wiMlwiLHRydWVdLFtcIjNcIix0cnVlXSxbXCI0XCIsdHJ1ZV1dJ10sXG4gICAgICAgICAgICAgICAgICAgIFsnYS5iLm8uKi5wJywgJ1tbXCIwXCIse1wicVwiOjEsXCJyXCI6dHJ1ZX1dLFtcIjFcIix7XCJxXCI6MixcInJcIjp0cnVlfV0sW1wiMlwiLHtcInFcIjozLFwiclwiOnRydWV9XSxbXCIzXCIse1wicVwiOjQsXCJyXCI6dHJ1ZX1dLFtcIjRcIix7XCJxXCI6NSxcInJcIjp0cnVlfV1dJ11cbiAgICAgICAgICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICAgICAgICAgIGl0KCcuZ2V0VmlhKCcgKyBhICsgJykgc2hvdWxkIHJlc3VsdCAnICsgYiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHIgPSBwYXRoZmluZGVyLmdldFZpYShhKVxuICAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0KEpTT04uc3RyaW5naWZ5KEFycmF5LmZyb20ocikpKS5pcy5lcXVhbChiKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgaXQoJy5nZXRWaWEoKSBzaG91bGQgcmVzdWx0ICcsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgIGxldCBwID0gbmV3IFBhdGhmaW5kZXIoe1xuICAgICAgICAgICAgICAgICAgICBhOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB4OiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge2M6IDF9LCB7YzogMn1cbiAgICAgICAgICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgICAgICAgICB5OiB0cnVlXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGI6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHg6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7YzogMSwgZDogZmFsc2V9LCB7YzogMn1cbiAgICAgICAgICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgICAgICAgICB5OiB0cnVlXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICBsZXQgciA9IHAuZ2V0VmlhKFwiKi54LiouY1wiKVxuXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gbWFwVG9PYmoobWFwKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBvYmogPSB7fVxuICAgICAgICAgICAgICAgICAgICBtYXAuZm9yRWFjaChmdW5jdGlvbiAodiwgaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHYgaW5zdGFuY2VvZiBNYXApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmpba10gPSBtYXBUb09iaih2KVxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmpba10gPSB2XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9ialxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGV4cGVjdChKU09OLnN0cmluZ2lmeShtYXBUb09iaihyKSkpLmlzLmVxdWFsKCd7XCJhXCI6e1wiMFwiOjEsXCIxXCI6Mn0sXCJiXCI6e1wiMFwiOjEsXCIxXCI6Mn19Jyk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaXQoJy5nZXRWaWEoYS5iLmwuMC5uKSB3aXRoIG1hcCBzaG91bGQgcmV0dXJuIDQgJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGV4cGVjdChwYXRoZmluZGVyLmdldFZpYSgnYS5iLmwuMC5uJykpLmlzLmVxdWFsKDQpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICBbJ2EuYi5rLm0ubicsIDNdLFxuICAgICAgICAgICAgICAgIFsnYS5iLmwuMC5uJywgNF0sXG4gICAgICAgICAgICAgICAgWydhLngnLCB1bmRlZmluZWRdLFxuICAgICAgICAgICAgICAgIFsnYS5iLnEnLCB1bmRlZmluZWRdLFxuICAgICAgICAgICAgICAgIFsnYS5iLmMuMScsIFwidGVzdDFcIl0sXG4gICAgICAgICAgICAgICAgWydhLmIuYy4wJywgNF0sXG4gICAgICAgICAgICAgICAgWydhLmIuZCcsIHVuZGVmaW5lZF0sXG4gICAgICAgICAgICAgICAgWydhLmIuZi4wLmcnLCBmYWxzZV0sXG4gICAgICAgICAgICAgICAgWydhLmIuZi4wLmkuMCcsIFwidGVzdDJcIl0sXG4gICAgICAgICAgICAgICAgWydhLmIuZScsIGZhbHNlXSxcbiAgICAgICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuXG5cbiAgICAgICAgICAgICAgICBpdCgnLmdldFZpYSgnICsgYSArICcpIHNob3VsZCByZXR1cm4gJyArIGIgKyAnICcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KHBhdGhmaW5kZXIuZ2V0VmlhKGEpKS5pcy5lcXVhbChiKTtcbiAgICAgICAgICAgICAgICB9KTtcblxuXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgIFsnYS5iLmQuZSddLFxuICAgICAgICAgICAgICAgIFsnYS5iLmQueCddLFxuICAgICAgICAgICAgICAgIFsnYS5iLmwuZS5uJ10sXG4gICAgICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgICAgICBpdCgnLmdldFZpYSgnICsgYSArICcpIHNob3VsZCB0aHJvdyBFcnJvciAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdCgoKSA9PiBwYXRoZmluZGVyLmdldFZpYShhKSkudG8udGhyb3coRXJyb3IpXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG59KTtcblxuIiwgIlwidXNlIHN0cmljdFwiO1xuXG5pbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuaW1wb3J0IHtkaWZmfSBmcm9tIFwiLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2RhdGEvZGlmZi5tanNcIjtcbmltcG9ydCB7UXVldWV9IGZyb20gXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdHlwZXMvcXVldWUubWpzXCI7XG5cbmRlc2NyaWJlKCdEaWZmJywgZnVuY3Rpb24gKCkge1xuXG4gICAgZGVzY3JpYmUoJ0RpZmYgc3BlY2lhbCBjYXNlcycsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICB2YXIgb2JqMSwgb2JqMjtcblxuICAgICAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAgICAgIG9iajEgPSB7XG4gICAgICAgICAgICAgICAgXCJjb3VudFwiOiAxLFxuICAgICAgICAgICAgICAgIFwicmVhc29uXCI6IG51bGwsXG4gICAgICAgICAgICAgICAgXCJpbmZvXCI6IFwidGVzdFwiLFxuICAgICAgICAgICAgICAgIFwiZXhjaGFuZ2VcIjogW11cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBvYmoyID0ge1xuICAgICAgICAgICAgICAgIFwiY291bnRcIjogMixcbiAgICAgICAgICAgICAgICBcInJlYXNvblwiOiBudWxsLFxuICAgICAgICAgICAgICAgIFwiaW5mb1wiOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgXCJleGNoYW5nZVwiOiBbXVxuICAgICAgICAgICAgfTtcblxuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnRGlmZiB2YWx1ZSB3aXRoIG51bGwgJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGV0IGQgPSBkaWZmKG9iajEsIG9iajIpO1xuICAgICAgICAgICAgZXhwZWN0KEpTT04uc3RyaW5naWZ5KGQpKS5pcy5lcXVhbCgnW3tcIm9wZXJhdG9yXCI6XCJ1cGRhdGVcIixcInBhdGhcIjpbXCJjb3VudFwiXSxcImZpcnN0XCI6e1widmFsdWVcIjoxLFwidHlwZVwiOlwibnVtYmVyXCJ9LFwic2Vjb25kXCI6e1widmFsdWVcIjoyLFwidHlwZVwiOlwibnVtYmVyXCJ9fSx7XCJvcGVyYXRvclwiOlwiZGVsZXRlXCIsXCJwYXRoXCI6W1wiaW5mb1wiXSxcImZpcnN0XCI6e1widmFsdWVcIjpcInRlc3RcIixcInR5cGVcIjpcInN0cmluZ1wifX1dJyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdEaWZmIGlkZW50aWNhbCB2YWx1ZSB3aXRoIG51bGwgJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGV0IGQgPSBkaWZmKG9iajEsIG9iajEpO1xuICAgICAgICAgICAgZXhwZWN0KEpTT04uc3RyaW5naWZ5KGQpKS5pcy5lcXVhbCgnW10nKTtcbiAgICAgICAgfSk7XG5cblxuICAgIH0pXG5cbiAgICBjb25zdCBkYXRlMSA9IG5ldyBEYXRlO1xuXG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZGUvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvRGF0ZS9wYXJzZVxuICAgIGNvbnN0IGRhdGUyID0gRGF0ZS5wYXJzZSgnMDEgSmFuIDE5NzAgMDA6MDA6MDAgR01UJyk7XG4gICAgY29uc3QgZGF0ZTMgPSBEYXRlLnBhcnNlKCcwNCBEZWMgMTk5NSAwMDoxMjowMCBHTVQnKTsgLy8gTnVtYmVyXG4gICAgY29uc3QgZGF0ZTQgPSBEYXRlLnBhcnNlKCcwNCBEZWMgMTk5NSAwMDoxMjowMSBHTVQnKTsgLy8gTnVtYmVyXG5cbiAgICBjb25zdCBkYXRlNSA9IG5ldyBEYXRlKERhdGUucGFyc2UoJzA0IERlYyAxOTk1IDAwOjEyOjAxIEdNVCcpKTsgLy8gRGF0ZVxuICAgIGNvbnN0IGRhdGU2ID0gbmV3IERhdGUoRGF0ZS5wYXJzZSgnMDQgRGVjIDE5OTUgMDA6MTI6MDIgR01UJykpOyAvLyBEYXRlXG5cbiAgICBbXG5cbiAgICAgICAgW1xuICAgICAgICAgICAge30sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYTogbmV3IFF1ZXVlKClcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAnW3tcIm9wZXJhdG9yXCI6XCJhZGRcIixcInBhdGhcIjpbXCJhXCJdLFwic2Vjb25kXCI6e1widmFsdWVcIjp7XCJkYXRhXCI6W119LFwidHlwZVwiOlwib2JqZWN0XCIsXCJpbnN0YW5jZVwiOlwiUXVldWVcIn19XSdcbiAgICAgICAgXSxcblxuICAgICAgICBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYToge1xuICAgICAgICAgICAgICAgICAgICBiOiAxXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBjOiB7XG4gICAgICAgICAgICAgICAgICAgIGQ6IDJcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGE6IHtcbiAgICAgICAgICAgICAgICAgICAgZTogM1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZjoge1xuICAgICAgICAgICAgICAgICAgICBkOiAyXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICdbe1wib3BlcmF0b3JcIjpcImRlbGV0ZVwiLFwicGF0aFwiOltcImFcIixcImJcIl0sXCJmaXJzdFwiOntcInZhbHVlXCI6MSxcInR5cGVcIjpcIm51bWJlclwifX0se1wib3BlcmF0b3JcIjpcImFkZFwiLFwicGF0aFwiOltcImFcIixcImVcIl0sXCJzZWNvbmRcIjp7XCJ2YWx1ZVwiOjMsXCJ0eXBlXCI6XCJudW1iZXJcIn19LHtcIm9wZXJhdG9yXCI6XCJkZWxldGVcIixcInBhdGhcIjpbXCJjXCJdLFwiZmlyc3RcIjp7XCJ2YWx1ZVwiOntcImRcIjoyfSxcInR5cGVcIjpcIm9iamVjdFwiLFwiaW5zdGFuY2VcIjpcIk9iamVjdFwifX0se1wib3BlcmF0b3JcIjpcImFkZFwiLFwicGF0aFwiOltcImZcIl0sXCJzZWNvbmRcIjp7XCJ2YWx1ZVwiOntcImRcIjoyfSxcInR5cGVcIjpcIm9iamVjdFwiLFwiaW5zdGFuY2VcIjpcIk9iamVjdFwifX1dJ1xuICAgICAgICBdLFxuXG4gICAgICAgIFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhOiBkYXRlMSxcbiAgICAgICAgICAgICAgICBjOiBkYXRlNFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhOiBkYXRlMixcbiAgICAgICAgICAgICAgICBiOiBkYXRlM1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICdbe1wib3BlcmF0b3JcIjpcInVwZGF0ZVwiLFwicGF0aFwiOltcImFcIl0sXCJmaXJzdFwiOntcInZhbHVlXCI6XCInICsgZGF0ZTEudG9JU09TdHJpbmcoKSArICdcIixcInR5cGVcIjpcIm9iamVjdFwiLFwiaW5zdGFuY2VcIjpcIkRhdGVcIn0sXCJzZWNvbmRcIjp7XCJ2YWx1ZVwiOjAsXCJ0eXBlXCI6XCJudW1iZXJcIn19LHtcIm9wZXJhdG9yXCI6XCJkZWxldGVcIixcInBhdGhcIjpbXCJjXCJdLFwiZmlyc3RcIjp7XCJ2YWx1ZVwiOjgxODAzNTkyMTAwMCxcInR5cGVcIjpcIm51bWJlclwifX0se1wib3BlcmF0b3JcIjpcImFkZFwiLFwicGF0aFwiOltcImJcIl0sXCJzZWNvbmRcIjp7XCJ2YWx1ZVwiOjgxODAzNTkyMDAwMCxcInR5cGVcIjpcIm51bWJlclwifX1dJ1xuICAgICAgICBdLFxuXG4gICAgICAgIFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhOiBkYXRlNVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBiOiBkYXRlNlxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICdbe1wib3BlcmF0b3JcIjpcImRlbGV0ZVwiLFwicGF0aFwiOltcImFcIl0sXCJmaXJzdFwiOntcInZhbHVlXCI6XCIxOTk1LTEyLTA0VDAwOjEyOjAxLjAwMFpcIixcInR5cGVcIjpcIm9iamVjdFwiLFwiaW5zdGFuY2VcIjpcIkRhdGVcIn19LHtcIm9wZXJhdG9yXCI6XCJhZGRcIixcInBhdGhcIjpbXCJiXCJdLFwic2Vjb25kXCI6e1widmFsdWVcIjpcIjE5OTUtMTItMDRUMDA6MTI6MDIuMDAwWlwiLFwidHlwZVwiOlwib2JqZWN0XCIsXCJpbnN0YW5jZVwiOlwiRGF0ZVwifX1dJ1xuICAgICAgICBdLFxuICAgICAgICBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYTogZGF0ZTFcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYTogZGF0ZTFcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAnW10nXG4gICAgICAgIF0sXG4gICAgICAgIFtcbiAgICAgICAgICAgIHt9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGE6IGRhdGUzXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgJ1t7XCJvcGVyYXRvclwiOlwiYWRkXCIsXCJwYXRoXCI6W1wiYVwiXSxcInNlY29uZFwiOntcInZhbHVlXCI6ODE4MDM1OTIwMDAwLFwidHlwZVwiOlwibnVtYmVyXCJ9fV0nXG4gICAgICAgIF0sXG5cbiAgICAgICAgW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGE6IGRhdGUyXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGE6IGRhdGUzXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgJ1t7XCJvcGVyYXRvclwiOlwidXBkYXRlXCIsXCJwYXRoXCI6W1wiYVwiXSxcImZpcnN0XCI6e1widmFsdWVcIjowLFwidHlwZVwiOlwibnVtYmVyXCJ9LFwic2Vjb25kXCI6e1widmFsdWVcIjo4MTgwMzU5MjAwMDAsXCJ0eXBlXCI6XCJudW1iZXJcIn19XSdcbiAgICAgICAgXSxcblxuICAgICAgICBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYTogMVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhOiAyXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgJ1t7XCJvcGVyYXRvclwiOlwidXBkYXRlXCIsXCJwYXRoXCI6W1wiYVwiXSxcImZpcnN0XCI6e1widmFsdWVcIjoxLFwidHlwZVwiOlwibnVtYmVyXCJ9LFwic2Vjb25kXCI6e1widmFsdWVcIjoyLFwidHlwZVwiOlwibnVtYmVyXCJ9fV0nXG4gICAgICAgIF0sXG5cbiAgICAgICAgW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGE6IDFcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgeDogMVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICdbe1wib3BlcmF0b3JcIjpcImRlbGV0ZVwiLFwicGF0aFwiOltcImFcIl0sXCJmaXJzdFwiOntcInZhbHVlXCI6MSxcInR5cGVcIjpcIm51bWJlclwifX0se1wib3BlcmF0b3JcIjpcImFkZFwiLFwicGF0aFwiOltcInhcIl0sXCJzZWNvbmRcIjp7XCJ2YWx1ZVwiOjEsXCJ0eXBlXCI6XCJudW1iZXJcIn19XSdcbiAgICAgICAgXSxcblxuICAgICAgICBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYTogMVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhOiAyLFxuICAgICAgICAgICAgICAgIHg6IDFcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAnW3tcIm9wZXJhdG9yXCI6XCJ1cGRhdGVcIixcInBhdGhcIjpbXCJhXCJdLFwiZmlyc3RcIjp7XCJ2YWx1ZVwiOjEsXCJ0eXBlXCI6XCJudW1iZXJcIn0sXCJzZWNvbmRcIjp7XCJ2YWx1ZVwiOjIsXCJ0eXBlXCI6XCJudW1iZXJcIn19LHtcIm9wZXJhdG9yXCI6XCJhZGRcIixcInBhdGhcIjpbXCJ4XCJdLFwic2Vjb25kXCI6e1widmFsdWVcIjoxLFwidHlwZVwiOlwibnVtYmVyXCJ9fV0nXG4gICAgICAgIF0sXG4gICAgICAgIFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhOiBudWxsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge30sXG4gICAgICAgICAgICAnW3tcIm9wZXJhdG9yXCI6XCJkZWxldGVcIixcInBhdGhcIjpbXCJhXCJdLFwiZmlyc3RcIjp7XCJ2YWx1ZVwiOm51bGwsXCJ0eXBlXCI6XCJvYmplY3RcIn19XSdcbiAgICAgICAgXSxcbiAgICAgICAgW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGE6IG51bGxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYTogbnVsbFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICdbXSdcbiAgICAgICAgXSxcbiAgICAgICAgW1xuICAgICAgICAgICAge30sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYTogbnVsbFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICdbe1wib3BlcmF0b3JcIjpcImFkZFwiLFwicGF0aFwiOltcImFcIl0sXCJzZWNvbmRcIjp7XCJ2YWx1ZVwiOm51bGwsXCJ0eXBlXCI6XCJvYmplY3RcIn19XSdcbiAgICAgICAgXSwgW1xuICAgICAgICB7fSxcbiAgICAgICAge2E6IHVuZGVmaW5lZH0sXG4gICAgICAgICdbe1wib3BlcmF0b3JcIjpcImFkZFwiLFwicGF0aFwiOltcImFcIl0sXCJzZWNvbmRcIjp7XCJ0eXBlXCI6XCJ1bmRlZmluZWRcIn19XSdcbiAgICBdXG5cblxuICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG4gICAgICAgIGxldCBjID0gZGF0YS5zaGlmdCgpXG5cblxuICAgICAgICBpdCgnRGlmZiBzaG91bGQgcmVzdWx0ICcgKyBjLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgZCA9IGRpZmYoYSwgYik7XG4gICAgICAgICAgICBleHBlY3QoSlNPTi5zdHJpbmdpZnkoZCkpLmlzLmVxdWFsKGMpO1xuICAgICAgICB9KTtcblxuXG4gICAgfSk7XG5cbn0pIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgaW50ZXJuYWxTeW1ib2wsIGluc3RhbmNlU3ltYm9sIH0gZnJvbSBcIi4uLy4uL2NvbnN0YW50cy5tanNcIjtcbmltcG9ydCB7IGlzT2JqZWN0IH0gZnJvbSBcIi4uLy4uL3R5cGVzL2lzLm1qc1wiO1xuaW1wb3J0IHsgRGF0YXNvdXJjZSB9IGZyb20gXCIuLi9kYXRhc291cmNlLm1qc1wiO1xuaW1wb3J0IHsgUGF0aGZpbmRlciB9IGZyb20gXCIuLi9wYXRoZmluZGVyLm1qc1wiO1xuaW1wb3J0IHsgUGlwZSB9IGZyb20gXCIuLi9waXBlLm1qc1wiO1xuXG5leHBvcnQgeyBTZXJ2ZXIgfTtcblxuLyoqXG4gKiBCYXNlIGNsYXNzIGZvciBhbGwgc2VydmVyIGRhdGFzb3VyY2VzXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMy40LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5EYXRhLkRhdGFzb3VyY2VcbiAqIEBzdW1tYXJ5IFRoZSBTZXJ2ZXIgY2xhc3MgZW5jYXBzdWxhdGVzIHRoZSBhY2Nlc3MgdG8gYSBzZXJ2ZXIgZGF0YXNvdXJjZVxuICovXG5jbGFzcyBTZXJ2ZXIgZXh0ZW5kcyBEYXRhc291cmNlIHtcbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGBpbnN0YW5jZW9mYCBvcGVyYXRvci5cbiAgICAgKiBAcmV0dXJucyB7c3ltYm9sfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgW2luc3RhbmNlU3ltYm9sXSgpIHtcbiAgICAgICAgcmV0dXJuIFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL2RhdGEvZGF0YXNvdXJjZS9zZXJ2ZXJcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBwcmVwYXJlcyB0aGUgZGF0YSB0aGF0IGNvbWVzIGZyb20gdGhlIHNlcnZlci5cbiAgICAgKiBTaG91bGQgbm90IGJlIGNhbGxlZCBkaXJlY3RseS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHBheWxvYWRcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fVxuICAgICAqL1xuICAgIHRyYW5zZm9ybVNlcnZlclBheWxvYWQocGF5bG9hZCkge1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICAgICAgcGF5bG9hZCA9IGRvVHJhbnNmb3JtLmNhbGwoc2VsZiwgXCJyZWFkXCIsIHBheWxvYWQpO1xuXG4gICAgICAgIGNvbnN0IGRhdGFQYXRoID0gc2VsZi5nZXRPcHRpb24oXCJyZWFkLnBhdGhcIik7XG4gICAgICAgIGlmIChkYXRhUGF0aCkge1xuICAgICAgICAgICAgcGF5bG9hZCA9IG5ldyBQYXRoZmluZGVyKHBheWxvYWQpLmdldFZpYShkYXRhUGF0aCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIHByZXBhcmVzIHRoZSBkYXRhIGZvciB3cml0aW5nIGFuZCBzaG91bGQgbm90IGJlIGNhbGxlZCBkaXJlY3RseS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHBheWxvYWRcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fVxuICAgICAqL1xuICAgIHByZXBhcmVTZXJ2ZXJQYXlsb2FkKHBheWxvYWQpIHtcbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICAgICAgcGF5bG9hZCA9IGRvVHJhbnNmb3JtLmNhbGwoc2VsZiwgXCJ3cml0ZVwiLCBwYXlsb2FkKTtcblxuICAgICAgICBsZXQgc2hlYXRoaW5nT2JqZWN0ID0gc2VsZi5nZXRPcHRpb24oXCJ3cml0ZS5zaGVhdGhpbmcub2JqZWN0XCIpO1xuICAgICAgICBsZXQgc2hlYXRoaW5nUGF0aCA9IHNlbGYuZ2V0T3B0aW9uKFwid3JpdGUuc2hlYXRoaW5nLnBhdGhcIik7XG5cbiAgICAgICAgaWYgKHNoZWF0aGluZ09iamVjdCAmJiBzaGVhdGhpbmdQYXRoKSB7XG4gICAgICAgICAgICBjb25zdCBzdWIgPSBwYXlsb2FkO1xuICAgICAgICAgICAgcGF5bG9hZCA9IHNoZWF0aGluZ09iamVjdDtcbiAgICAgICAgICAgIG5ldyBQYXRoZmluZGVyKHBheWxvYWQpLnNldFZpYShzaGVhdGhpbmdQYXRoLCBzdWIpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0gc2VsZlxuICogQHBhcmFtIG9ialxuICogQHJldHVybnMgeyp9XG4gKi9cbmZ1bmN0aW9uIGRvVHJhbnNmb3JtKHR5cGUsIG9iaikge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIGxldCB0cmFuc2Zvcm1hdGlvbiA9IHNlbGYuZ2V0T3B0aW9uKGAke3R5cGV9Lm1hcHBpbmcudHJhbnNmb3JtZXJgKTtcbiAgICBpZiAodHJhbnNmb3JtYXRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb25zdCBwaXBlID0gbmV3IFBpcGUodHJhbnNmb3JtYXRpb24pO1xuICAgICAgICBjb25zdCBjYWxsYmFja3MgPSBzZWxmLmdldE9wdGlvbihgJHt0eXBlfS5tYXBwaW5nLmNhbGxiYWNrc2ApO1xuXG4gICAgICAgIGlmIChpc09iamVjdChjYWxsYmFja3MpKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBjYWxsYmFja3MpIHtcbiAgICAgICAgICAgICAgICBpZiAoY2FsbGJhY2tzLmhhc093blByb3BlcnR5KGtleSkgJiYgdHlwZW9mIGNhbGxiYWNrc1trZXldID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgcGlwZS5zZXRDYWxsYmFjayhrZXksIGNhbGxiYWNrc1trZXldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBvYmogPSBwaXBlLnJ1bihvYmopO1xuICAgIH1cblxuICAgIHJldHVybiBvYmo7XG59XG4iLCAiaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7U2VydmVyfSBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2RhdGEvZGF0YXNvdXJjZS9zZXJ2ZXIubWpzXCI7XG5cblxuZGVzY3JpYmUoJ1NlcnZlcicsIGZ1bmN0aW9uICgpIHtcblxuICAgIGl0KCdzaG91bGQgdHJhbnNmb3JtIGRhdGEnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgbGV0IHdyaXRlQ2FsbGJhY2tDYWxsZWQgPSBmYWxzZVxuICAgICAgICBsZXQgcmVhZENhbGxiYWNrQ2FsbGVkID0gZmFsc2VcblxuICAgICAgICBjb25zdCBzZXJ2ZXIgPSBuZXcgU2VydmVyKHtcbiAgICAgICAgICAgIHdyaXRlOiB7XG4gICAgICAgICAgICAgICAgbWFwcGluZzoge1xuICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm1lcjogXCJjYWxsOm9uV3JpdGVcIixcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvbldyaXRlOiAoZGF0YSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlQ2FsbGJhY2tDYWxsZWQgPSB0cnVlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGFcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgc2hlYXRoaW5nOiB7XG4gICAgICAgICAgICAgICAgICAgIG9iamVjdDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVtbzogMSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4eXo6IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBwYXRoOiBcImRhdGEueHl6XCIsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByZWFkOiB7XG4gICAgICAgICAgICAgICAgbWFwcGluZzoge1xuICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm1lcjogXCJjYWxsOm9uUmVhZFwiLFxuICAgICAgICAgICAgICAgICAgICBjYWxsYmFja3M6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uUmVhZDogKGRhdGEpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFkQ2FsbGJhY2tDYWxsZWQgPSB0cnVlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGFcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcGF0aDogJ2RhdGEueHl6JyxcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSlcblxuICAgICAgICBleHBlY3Qoc2VydmVyLnRyYW5zZm9ybVNlcnZlclBheWxvYWQoe2RlbW86IDEsIGRhdGE6IHt4eXo6IDJ9fSkpLnRvLmRlZXAuZXF1YWwoe2RlbW86IDEsIGRhdGE6IHt4eXo6IDJ9fSlcbiAgICAgICAgZXhwZWN0KHNlcnZlci5wcmVwYXJlU2VydmVyUGF5bG9hZCh7ZGVtbzogMSwgZGF0YToge3h5ejogMn19KSkudG8uZGVlcC5lcXVhbCh7ZGVtbzogMSwgZGF0YToge3h5ejogMn19KVxuXG5cbiAgICB9KVxuXG59KTtcbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGludGVybmFsU3ltYm9sLCBpbnN0YW5jZVN5bWJvbCB9IGZyb20gXCIuLi8uLi8uLi9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQgeyBnZXRHbG9iYWxPYmplY3QgfSBmcm9tIFwiLi4vLi4vLi4vdHlwZXMvZ2xvYmFsLm1qc1wiO1xuaW1wb3J0IHsgRGF0YXNvdXJjZSB9IGZyb20gXCIuLi8uLi9kYXRhc291cmNlLm1qc1wiO1xuaW1wb3J0IHsgU3RvcmFnZSwgc3RvcmFnZU9iamVjdFN5bWJvbCB9IGZyb20gXCIuLi9zdG9yYWdlLm1qc1wiO1xuXG5leHBvcnQgeyBTZXNzaW9uU3RvcmFnZSB9O1xuXG4vKipcbiAqIFRoZSBTZXNzaW9uU3RvcmFnZSBjbGFzcyBwcm92aWRlcyBhIGRhdGEgc291cmNlIHRoYXQgdXNlcyB0aGUgU2Vzc2lvblN0b3JhZ2UgQVBJIG9uIHRoZSBjbGllbnQuXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yMi4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRGF0YS5EYXRhc291cmNlLlN0b3JhZ2VcbiAqIEBzdW1tYXJ5IFRoZSBMb2NhbFN0b3JhZ2UgY2xhc3MgZW5jYXBzdWxhdGVzIHRoZSBhY2Nlc3MgdG8gZGF0YSBvYmplY3RzLlxuICovXG5jbGFzcyBTZXNzaW9uU3RvcmFnZSBleHRlbmRzIFN0b3JhZ2Uge1xuICAgIC8qKlxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSB0aGlzIG1ldGhvZCBtdXN0IGJlIGltcGxlbWVudGVkIGJ5IGRlcml2ZWQgY2xhc3Nlcy5cbiAgICAgKiBAcmV0dXJuIHtleHRlcm5hbDpzZXNzaW9uU3RvcmFnZX1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIFtzdG9yYWdlT2JqZWN0U3ltYm9sXSgpIHtcbiAgICAgICAgcmV0dXJuIGdldEdsb2JhbE9iamVjdChcInNlc3Npb25TdG9yYWdlXCIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgYGluc3RhbmNlb2ZgIG9wZXJhdG9yLlxuICAgICAqIEByZXR1cm5zIHtzeW1ib2x9XG4gICAgICogQHNpbmNlIDIuMS4wXG4gICAgICovXG4gICAgc3RhdGljIGdldCBbaW5zdGFuY2VTeW1ib2xdKCkge1xuICAgICAgICByZXR1cm4gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvZGF0YS9kYXRhc291cmNlL3N0b3JhZ2Uvc2Vzc2lvbi1zdG9yYWdlXCIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBDbG9uZVxuICAgICAqXG4gICAgICogQHJldHVybiB7U2Vzc2lvblN0b3JhZ2V9XG4gICAgICovXG4gICAgZ2V0Q2xvbmUoKSB7XG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgICAgICByZXR1cm4gbmV3IFNlc3Npb25TdG9yYWdlKHNlbGZbaW50ZXJuYWxTeW1ib2xdLmdldFJlYWxTdWJqZWN0KClbXCJvcHRpb25zXCJdLmtleSk7XG4gICAgfVxufVxuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgaW50ZXJuYWxTeW1ib2wsIGluc3RhbmNlU3ltYm9sIH0gZnJvbSBcIi4uLy4uL2NvbnN0YW50cy5tanNcIjtcbmltcG9ydCB7IHZhbGlkYXRlU3RyaW5nIH0gZnJvbSBcIi4uLy4uL3R5cGVzL3ZhbGlkYXRlLm1qc1wiO1xuaW1wb3J0IHsgRGF0YXNvdXJjZSB9IGZyb20gXCIuLi9kYXRhc291cmNlLm1qc1wiO1xuXG5leHBvcnQgeyBTdG9yYWdlLCBzdG9yYWdlT2JqZWN0U3ltYm9sIH07XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEB0eXBlIHtzeW1ib2x9XG4gKi9cbmNvbnN0IHN0b3JhZ2VPYmplY3RTeW1ib2wgPSBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci9kYXRhL2RhdGFzb3VyY2Uvc3RvcmFnZS9AQHN0b3JhZ2VPYmplY3RcIik7XG5cbi8qKlxuICogVGhlIGNsYXNzIHJlcHJlc2VudHMgYSByZWNvcmQuXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yMi4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRGF0YS5EYXRhc291cmNlXG4gKiBAc3VtbWFyeSBUaGUgU3RvcmFnZSBjbGFzcyBlbmNhcHN1bGF0ZXMgdGhlIGFjY2VzcyB0byBkYXRhIG9iamVjdHMgb3ZlciBXZWJTdG9yYWdlQVBJLlxuICovXG5jbGFzcyBTdG9yYWdlIGV4dGVuZHMgRGF0YXNvdXJjZSB7XG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IExvY2FsU3RvcmFnZSBLZXlcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIHN0cmluZ1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGtleSkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLnNldE9wdGlvbihcImtleVwiLCB2YWxpZGF0ZVN0cmluZyhrZXkpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGBpbnN0YW5jZW9mYCBvcGVyYXRvci5cbiAgICAgKiBAcmV0dXJucyB7c3ltYm9sfVxuICAgICAqIEBzaW5jZSAyLjEuMFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgW2luc3RhbmNlU3ltYm9sXSgpIHtcbiAgICAgICAgcmV0dXJuIFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL2RhdGEvZGF0YXNvdXJjZS9zdG9yYWdlXCIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBrZXk9dW5kZWZpbmVkIExvY2FsU3RvcmFnZSBLZXlcbiAgICAgKi9cbiAgICBnZXQgZGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdXBlci5kZWZhdWx0cywge1xuICAgICAgICAgICAga2V5OiB1bmRlZmluZWQsXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSB0aGlzIG1ldGhvZCBtdXN0IGJlIGltcGxlbWVudGVkIGJ5IGRlcml2ZWQgY2xhc3Nlcy5cbiAgICAgKiBAcmV0dXJuIHtleHRlcm5hbDpTdG9yYWdlfVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgW3N0b3JhZ2VPYmplY3RTeW1ib2xdKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0aGlzIG1ldGhvZCBtdXN0IGJlIGltcGxlbWVudGVkIGJ5IGRlcml2ZWQgY2xhc3Nlc1wiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSB0aGUgb3B0aW9ucyBkb2VzIG5vdCBjb250YWluIGEgdmFsaWQganNvbiBkZWZpbml0aW9uXG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYSBvYmplY3RcbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gdGhlIGRhdGEgY2Fubm90IGJlIHJlYWRcbiAgICAgKi9cbiAgICByZWFkKCkge1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgICAgICBjb25zdCBzdG9yYWdlID0gc2VsZltzdG9yYWdlT2JqZWN0U3ltYm9sXSgpO1xuXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkge1xuICAgICAgICAgICAgY29uc3QgZGF0YSA9IEpTT04ucGFyc2Uoc3RvcmFnZS5nZXRJdGVtKHNlbGYuZ2V0T3B0aW9uKFwia2V5XCIpKSk7XG4gICAgICAgICAgICBzZWxmLnNldChkYXRhID8/IHt9KTtcbiAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RvcmFnZX1cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gdGhlIGRhdGEgY2Fubm90IGJlIHdyaXR0ZW5cbiAgICAgKi9cbiAgICB3cml0ZSgpIHtcbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICAgICAgY29uc3Qgc3RvcmFnZSA9IHNlbGZbc3RvcmFnZU9iamVjdFN5bWJvbF0oKTtcblxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICAgICAgICAgIGNvbnN0IGRhdGEgPSBzZWxmLmdldCgpO1xuICAgICAgICAgICAgaWYgKGRhdGEgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHN0b3JhZ2UucmVtb3ZlSXRlbShzZWxmLmdldE9wdGlvbihcImtleVwiKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHN0b3JhZ2Uuc2V0SXRlbShzZWxmLmdldE9wdGlvbihcImtleVwiKSwgSlNPTi5zdHJpbmdpZnkoZGF0YSkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0b3JhZ2V9XG4gICAgICovXG4gICAgZ2V0Q2xvbmUoKSB7XG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgICAgICByZXR1cm4gbmV3IFN0b3JhZ2Uoc2VsZltpbnRlcm5hbFN5bWJvbF0uZ2V0UmVhbFN1YmplY3QoKVtcIm9wdGlvbnNcIl0ua2V5KTtcbiAgICB9XG59XG4iLCAiZnVuY3Rpb24gY3JlYXRlU3RvcmFnZSgpIHtcbiAgICBsZXQgVU5TRVQgPSBTeW1ib2woKTtcbiAgICBsZXQgcyA9IHt9LFxuICAgICAgICBub29wQ2FsbGJhY2sgPSAoKSA9PiB7XG4gICAgICAgIH0sXG4gICAgICAgIF9pdGVtSW5zZXJ0aW9uQ2FsbGJhY2sgPSBub29wQ2FsbGJhY2s7XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocywgJ3NldEl0ZW0nLCB7XG4gICAgICAgIGdldDogKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIChrLCB2ID0gVU5TRVQpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodiA9PT0gVU5TRVQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgRmFpbGVkIHRvIGV4ZWN1dGUgJ3NldEl0ZW0nIG9uICdTdG9yYWdlJzogMiBhcmd1bWVudHMgcmVxdWlyZWQsIGJ1dCBvbmx5IDEgcHJlc2VudC5gKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgayA9IGsgKyAnJztcbiAgICAgICAgICAgICAgICBpZiAoIXMuaGFzT3duUHJvcGVydHkoaykpIHtcbiAgICAgICAgICAgICAgICAgICAgX2l0ZW1JbnNlcnRpb25DYWxsYmFjayhzLmxlbmd0aCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHNba10gPSB2ICsgJyc7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHMsICdnZXRJdGVtJywge1xuICAgICAgICBnZXQ6ICgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBrID0+IHtcbiAgICAgICAgICAgICAgICBrID0gayArICcnO1xuICAgICAgICAgICAgICAgIGlmIChzLmhhc093blByb3BlcnR5KGspKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBzW2tdO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocywgJ3JlbW92ZUl0ZW0nLCB7XG4gICAgICAgIGdldDogKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGsgPT4ge1xuICAgICAgICAgICAgICAgIGsgPSBrICsgJyc7XG4gICAgICAgICAgICAgICAgaWYgKHMuaGFzT3duUHJvcGVydHkoaykpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHNba107XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShzLCAnY2xlYXInLCB7XG4gICAgICAgIGdldDogKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBrIGluIHMpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHMuaGFzT3duUHJvcGVydHkoaykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBzW2tdO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShzLCAnbGVuZ3RoJywge1xuICAgICAgICBnZXQ6ICgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBPYmplY3Qua2V5cyhzKS5sZW5ndGg7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocywgXCJrZXlcIiwge1xuICAgICAgICB2YWx1ZTogayA9PiB7XG4gICAgICAgICAgICBsZXQga2V5ID0gT2JqZWN0LmtleXMocylba107XG4gICAgICAgICAgICByZXR1cm4gKCFrZXkpID8gbnVsbCA6IGtleTtcbiAgICAgICAgfSxcbiAgICB9KTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocywgJ2l0ZW1JbnNlcnRpb25DYWxsYmFjaycsIHtcbiAgICAgICAgZ2V0OiAoKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gX2l0ZW1JbnNlcnRpb25DYWxsYmFjaztcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB2ID0+IHtcbiAgICAgICAgICAgIGlmICghdiB8fCB0eXBlb2YgdiAhPSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgdiA9IG5vb3BDYWxsYmFjaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF9pdGVtSW5zZXJ0aW9uQ2FsbGJhY2sgPSB2O1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHM7XG59XG5cblxuZXhwb3J0IHtjcmVhdGVTdG9yYWdlfTsiLCAiXCJ1c2Ugc3RyaWN0XCI7XG5cbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge1Nlc3Npb25TdG9yYWdlfSBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2RhdGEvZGF0YXNvdXJjZS9zdG9yYWdlL3Nlc3Npb25zdG9yYWdlLm1qc1wiO1xuaW1wb3J0IHtjcmVhdGVTdG9yYWdlfSBmcm9tIFwiLi4vLi4vLi4vLi4vdXRpbC9sb2NhbHN0b3JhZ2UubWpzXCI7XG5cblxubGV0IHN0b3JhZ2VSZWZlcmVuY2U7XG5cbmRlc2NyaWJlKCdTZXNzaW9uU3RvcmFnZScsIGZ1bmN0aW9uICgpIHtcblxuICAgIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICAgIGdsb2JhbFRoaXNbJ3Nlc3Npb25TdG9yYWdlJ10gPSBzdG9yYWdlUmVmZXJlbmNlO1xuICAgIH0pO1xuXG4gICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgc3RvcmFnZVJlZmVyZW5jZSA9IGdsb2JhbFRoaXNbJ3Nlc3Npb25TdG9yYWdlJ11cbiAgICAgICAgZ2xvYmFsVGhpc1snc2Vzc2lvblN0b3JhZ2UnXSA9IGNyZWF0ZVN0b3JhZ2UoKTtcblxuICAgIH0pXG5cbiAgICBpdCgnc2hvdWxkIGluc3RhbmNlIG9mIFNlc3Npb25TdG9yYWdlICcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZXhwZWN0KG5ldyBTZXNzaW9uU3RvcmFnZSgnbXlrZXknKSkudG8uYmUuaW5zdGFuY2VvZihTZXNzaW9uU3RvcmFnZSlcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdydycsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBpdCgncmVhZCBzaG91bGQgcmV0dXJuIG9iamVjdCcsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICBjb25zdCBkcyA9IG5ldyBTZXNzaW9uU3RvcmFnZSgnbXlrZXknKVxuICAgICAgICAgICAgZHMucmVhZCgpLnRoZW4oZGF0YSA9PiB7XG4gICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgfSkuY2F0Y2goZSA9PiBkb25lKGUpKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3dyaXRlIHNob3VsZCAnLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICAgICAgY29uc3QgZHMgPSBuZXcgU2Vzc2lvblN0b3JhZ2UoJ215a2V5JylcbiAgICAgICAgICAgIGRzLndyaXRlKCkudGhlbihkYXRhID0+IHtcbiAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICB9KS5jYXRjaChlID0+IGRvbmUoZSkpO1xuICAgICAgICB9KTtcblxuXG4gICAgfSlcblxuXG59KSIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGludGVybmFsU3ltYm9sLCBpbnN0YW5jZVN5bWJvbCB9IGZyb20gXCIuLi8uLi8uLi9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQgeyBnZXRHbG9iYWxPYmplY3QgfSBmcm9tIFwiLi4vLi4vLi4vdHlwZXMvZ2xvYmFsLm1qc1wiO1xuaW1wb3J0IHsgRGF0YXNvdXJjZSB9IGZyb20gXCIuLi8uLi9kYXRhc291cmNlLm1qc1wiO1xuaW1wb3J0IHsgU3RvcmFnZSwgc3RvcmFnZU9iamVjdFN5bWJvbCB9IGZyb20gXCIuLi9zdG9yYWdlLm1qc1wiO1xuXG5leHBvcnQgeyBMb2NhbFN0b3JhZ2UgfTtcblxuLyoqXG4gKiBUaGUgTG9jYWxTdG9yYWdlIERhdGFzb3VyY2UgcHJvdmlkZXMgYSBkYXRhIHN0b3JlIGluIHRoZSBicm93c2VyIGxvY2FsU3RvcmFnZS5cbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjIyLjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5EYXRhLkRhdGFzb3VyY2UuU3RvcmFnZVxuICogQHN1bW1hcnkgVGhlIExvY2FsU3RvcmFnZSBjbGFzcyBlbmNhcHN1bGF0ZXMgdGhlIGFjY2VzcyB0byBkYXRhIG9iamVjdHMuXG4gKi9cbmNsYXNzIExvY2FsU3RvcmFnZSBleHRlbmRzIFN0b3JhZ2Uge1xuICAgIC8qKlxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSB0aGlzIG1ldGhvZCBtdXN0IGJlIGltcGxlbWVudGVkIGJ5IGRlcml2ZWQgY2xhc3Nlcy5cbiAgICAgKiBAcmV0dXJuIHtleHRlcm5hbDpsb2NhbFN0b3JhZ2V9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBbc3RvcmFnZU9iamVjdFN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBnZXRHbG9iYWxPYmplY3QoXCJsb2NhbFN0b3JhZ2VcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMi4xLjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci9kYXRhL2RhdGFzb3VyY2Uvc3RvcmFnZS9sb2NhbHN0b3JhZ2VcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGNsb25lXG4gICAgICogQHJldHVybiB7TG9jYWxTdG9yYWdlfVxuICAgICAqL1xuICAgIGdldENsb25lKCkge1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICAgICAgcmV0dXJuIG5ldyBMb2NhbFN0b3JhZ2Uoc2VsZltpbnRlcm5hbFN5bWJvbF0uZ2V0UmVhbFN1YmplY3QoKVtcIm9wdGlvbnNcIl0ua2V5KTtcbiAgICB9XG59XG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XG5cbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge0xvY2FsU3RvcmFnZX0gZnJvbSBcIi4uLy4uLy4uLy4uLy4uLy4uL2FwcGxpY2F0aW9uL3NvdXJjZS9kYXRhL2RhdGFzb3VyY2Uvc3RvcmFnZS9sb2NhbHN0b3JhZ2UubWpzXCI7XG5pbXBvcnQge2NyZWF0ZVN0b3JhZ2V9IGZyb20gXCIuLi8uLi8uLi8uLi91dGlsL2xvY2Fsc3RvcmFnZS5tanNcIjtcblxuXG5sZXQgbG9jYWxTdG9yYWdlUmVmZXJlbmNlO1xuXG5kZXNjcmliZSgnTG9jYWxTdG9yYWdlJywgZnVuY3Rpb24gKCkge1xuXG4gICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgICAgZ2xvYmFsVGhpc1snbG9jYWxTdG9yYWdlJ10gPSBsb2NhbFN0b3JhZ2VSZWZlcmVuY2U7XG4gICAgfSk7XG5cbiAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBsb2NhbFN0b3JhZ2VSZWZlcmVuY2UgPSBnbG9iYWxUaGlzWydsb2NhbFN0b3JhZ2UnXVxuICAgICAgICBnbG9iYWxUaGlzWydsb2NhbFN0b3JhZ2UnXSA9IGNyZWF0ZVN0b3JhZ2UoKTtcblxuICAgIH0pXG5cbiAgICBpdCgnc2hvdWxkIGluc3RhbmNlIG9mIExvY2FsU3RvcmFnZSAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGV4cGVjdChuZXcgTG9jYWxTdG9yYWdlKCdteWtleScpKS50by5iZS5pbnN0YW5jZW9mKExvY2FsU3RvcmFnZSlcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdydycsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBpdCgncmVhZCBzaG91bGQgcmV0dXJuIG9iamVjdCcsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICBjb25zdCBkcyA9IG5ldyBMb2NhbFN0b3JhZ2UoJ215a2V5JylcbiAgICAgICAgICAgIGRzLnJlYWQoKS50aGVuKGRhdGEgPT4ge1xuICAgICAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICAgIH0pLmNhdGNoKGUgPT4gZG9uZShlKSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCd3cml0ZSBzaG91bGQgJywgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgICAgIGNvbnN0IGRzID0gbmV3IExvY2FsU3RvcmFnZSgnbXlrZXknKVxuICAgICAgICAgICAgZHMud3JpdGUoKS50aGVuKGRhdGEgPT4ge1xuICAgICAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICAgIH0pLmNhdGNoKGUgPT4gZG9uZShlKSk7XG4gICAgICAgIH0pO1xuXG5cbiAgICB9KVxuXG5cbn0pIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgaW5zdGFuY2VTeW1ib2wgfSBmcm9tIFwiLi4vLi4vY29uc3RhbnRzLm1qc1wiO1xuaW1wb3J0IHsgaXNPYmplY3QgfSBmcm9tIFwiLi4vLi4vdHlwZXMvaXMubWpzXCI7XG5pbXBvcnQgeyBEYXRhc291cmNlIH0gZnJvbSBcIi4uL2RhdGFzb3VyY2UubWpzXCI7XG5cbmV4cG9ydCB7IERvbVN0b3JhZ2UgfTtcblxuLyoqXG4gKiBUaGUgRG9tU3RvcmFnZSBpcyBhIGNsYXNzIHRoYXQgc3RvcmVzIGRhdGEgaW4gbWVtb3J5LlxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRhdGEuRGF0YXNvdXJjZVxuICovXG5jbGFzcyBEb21TdG9yYWdlIGV4dGVuZHMgRGF0YXNvdXJjZSB7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXSBvcHRpb25zIGNvbnRhaW5zIGRlZmluaXRpb25zIGZvciB0aGUgZGF0YXNvdXJjZS5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKCk7XG5cbiAgICAgICAgaWYgKGlzT2JqZWN0KG9wdGlvbnMpKSB7XG4gICAgICAgICAgICB0aGlzLnNldE9wdGlvbnMob3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGBpbnN0YW5jZW9mYCBvcGVyYXRvci5cbiAgICAgKiBAcmV0dXJucyB7c3ltYm9sfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgW2luc3RhbmNlU3ltYm9sXSgpIHtcbiAgICAgICAgcmV0dXJuIFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL2RhdGEvZGF0YXNvdXJjZS9zdG9yYWdlL2RvbS1zdG9yYWdlXCIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBkZWZhdWx0c1xuICAgICAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBkZWZhdWx0cy5yZWFkXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd9IGRlZmF1bHRzLnJlYWQuc2VsZWN0b3JcbiAgICAgKiBAcHJvcGVydHkge09iamVjdH0gZGVmYXVsdHMud3JpdGVcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gZGVmYXVsdHMud3JpdGUuc2VsZWN0b3JcbiAgICAgKi9cbiAgICBnZXQgZGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdXBlci5kZWZhdWx0cywge1xuICAgICAgICAgICAgcmVhZDoge1xuICAgICAgICAgICAgICAgIHNlbGVjdG9yOiB1bmRlZmluZWQsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgd3JpdGU6IHtcbiAgICAgICAgICAgICAgICBzZWxlY3RvcjogdW5kZWZpbmVkLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gVGhlIHJlYWQgc2VsZWN0b3IgaXMgbm90IGRlZmluZWRcbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gVGhlcmUgYXJlIG5vIHN0b3JhZ2UgZWxlbWVudFxuICAgICAqL1xuICAgIHJlYWQoKSB7XG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgICAgIGxldCBzZWxlY3RvciA9IHNlbGYuZ2V0T3B0aW9uKFwicmVhZC5zZWxlY3RvclwiLCB1bmRlZmluZWQpO1xuICAgICAgICBpZiAoIXNlbGVjdG9yKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgcmVhZCBzZWxlY3RvciBpcyBub3QgZGVmaW5lZFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBzdG9yYWdlID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihzZWxlY3Rvcik7XG4gICAgICAgIGlmICghc3RvcmFnZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhlcmUgYXJlIG5vIHN0b3JhZ2UgZWxlbWVudFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGxldCBkYXRhID0gSlNPTi5wYXJzZShzdG9yYWdlLmlubmVySFRNTCk7XG4gICAgICAgICAgICAgICAgc2VsZi5zZXQoZGF0YSk7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShkYXRhKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAgICogQHRocm93cyB7RXJyb3J9IFRoZSB3cml0ZSBzZWxlY3RvciBpcyBub3QgZGVmaW5lZFxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBUaGVyZSBhcmUgbm8gc3RvcmFnZSBlbGVtZW50XG4gICAgICovXG4gICAgd3JpdGUoKSB7XG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgICAgIGxldCBzZWxlY3RvciA9IHNlbGYuZ2V0T3B0aW9uKFwid3JpdGUuc2VsZWN0b3JcIik7XG4gICAgICAgIGlmICghc2VsZWN0b3IpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZSB3cml0ZSBzZWxlY3RvciBpcyBub3QgZGVmaW5lZFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBzdG9yYWdlID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihzZWxlY3Rvcik7XG4gICAgICAgIGlmICghc3RvcmFnZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhlcmUgYXJlIG5vIHN0b3JhZ2UgZWxlbWVudFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHN0b3JhZ2UuaW5uZXJIVE1MID0gSlNPTi5zdHJpbmdpZnkoc2VsZi5nZXQoKSk7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShzdG9yYWdlKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsICJpbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuaW1wb3J0IHtEb21TdG9yYWdlfSBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2RhdGEvZGF0YXNvdXJjZS9kb20ubWpzXCI7XG5cblxuZGVzY3JpYmUoJ1NlcnZlRG9tcicsIGZ1bmN0aW9uICgpIHtcblxuICAgIGl0KCdzaG91bGQgaW5pdCcsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBjb25zdCBkb20gPSBuZXcgRG9tU3RvcmFnZSh7XG4gICAgICAgICAgICBcbiAgICAgICAgfSlcblxuICAgICAgICBleHBlY3QoZG9tKS50by5iZS5ub3QubnVsbFxuXG5cbiAgICB9KVxuXG59KTtcbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGludGVybmFsU3ltYm9sLCBpbnN0YW5jZVN5bWJvbCB9IGZyb20gXCIuLi8uLi8uLi9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQgeyBpc09iamVjdCwgaXNGdW5jdGlvbiB9IGZyb20gXCIuLi8uLi8uLi90eXBlcy9pcy5tanNcIjtcbmltcG9ydCB7IFNlcnZlciB9IGZyb20gXCIuLi9zZXJ2ZXIubWpzXCI7XG5pbXBvcnQgeyBXcml0ZUVycm9yIH0gZnJvbSBcIi4vcmVzdGFwaS93cml0ZWVycm9yLm1qc1wiO1xuXG5leHBvcnQgeyBSZXN0QVBJIH07XG5cbi8qKlxuICogQHR5cGUge3N5bWJvbH1cbiAqIEBtZW1iZXJPZiBNb25zdGVyXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAzLjEyLjBcbiAqL1xuY29uc3QgcmF3RGF0YVN5bWJvbCA9IFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL2RhdGEvZGF0YXNvdXJjZS9zZXJ2ZXIvcmVzdGFwaS9yYXdkYXRhXCIpO1xuXG4vKipcbiAqIFRoZSBSZXN0QVBJIGlzIGEgY2xhc3MgdGhhdCBlbmFibGVzIGEgUkVTVCBBUEkgc2VydmVyLlxuICpcbiAqIEBleHRlcm5hbEV4YW1wbGUgLi4vLi4vLi4vLi4vZXhhbXBsZS9kYXRhL2RhdGFzb3VyY2Uvc2VydmVyL3Jlc3RhcGkubWpzXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjIyLjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5EYXRhLkRhdGFzb3VyY2UuU2VydmVyXG4gKiBAc3VtbWFyeSBUaGUgUmVzdEFQSSBpcyBhIGNsYXNzIHRoYXQgYmluZHMgYSBSRVNUIEFQSSBzZXJ2ZXIuXG4gKi9cbmNsYXNzIFJlc3RBUEkgZXh0ZW5kcyBTZXJ2ZXIge1xuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXSBvcHRpb25zIGNvbnRhaW5zIGRlZmluaXRpb25zIGZvciB0aGUgZGF0YXNvdXJjZS5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKCk7XG5cbiAgICAgICAgaWYgKGlzT2JqZWN0KG9wdGlvbnMpKSB7XG4gICAgICAgICAgICB0aGlzLnNldE9wdGlvbnMob3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGBpbnN0YW5jZW9mYCBvcGVyYXRvci5cbiAgICAgKiBAcmV0dXJucyB7c3ltYm9sfVxuICAgICAqIEBzaW5jZSAyLjEuMFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgW2luc3RhbmNlU3ltYm9sXSgpIHtcbiAgICAgICAgcmV0dXJuIFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL2RhdGEvZGF0YXNvdXJjZS9zZXJ2ZXIvcmVzdGFwaVwiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcHJvcGVydHkge09iamVjdH0gd3JpdGU9e30gT3B0aW9uc1xuICAgICAqIEBwcm9wZXJ0eSB7T2JqZWN0fSB3cml0ZS5pbml0PXt9IEFuIG9wdGlvbnMgb2JqZWN0IGNvbnRhaW5pbmcgYW55IGN1c3RvbSBzZXR0aW5ncyB0aGF0IHlvdSB3YW50IHRvIGFwcGx5IHRvIHRoZSByZXF1ZXN0LiBUaGUgcGFyYW1ldGVycyBhcmUgaWRlbnRpY2FsIHRvIHRob3NlIG9mIHRoZSB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1JlcXVlc3QvUmVxdWVzdHxSZXF1ZXN0IGNvbnN0cnVjdG9yfVxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB3cml0ZS5pbml0Lm1ldGhvZD1QT1NUXG4gICAgICogQHByb3BlcnR5IHtPYmplY3R9IHdyaXRlLmluaXQuaGVhZGVycyBPYmplY3QgY29udGFpbmluZyBhbnkgY3VzdG9tIGhlYWRlcnMgdGhhdCB5b3Ugd2FudCB0byBhcHBseSB0byB0aGUgcmVxdWVzdC5cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gd3JpdGUucmVzcG9uc2VDYWxsYmFjayBDYWxsYmFjayBmdW5jdGlvbiB0byBiZSBleGVjdXRlZCBhZnRlciB0aGUgcmVxdWVzdCBoYXMgYmVlbiBjb21wbGV0ZWQuXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd9IHdyaXRlLmFjY2VwdGVkU3RhdHVzPVsyMDAsMjAxXVxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB3cml0ZS51cmwgVVJMXG4gICAgICogQHByb3BlcnR5IHtPYmplY3R9IHdyaXRlLm1hcHBpbmcgdGhlIG1hcHBpbmcgaXMgYXBwbGllZCBiZWZvcmUgd3JpdGluZy5cbiAgICAgKiBAcHJvcGVydHkge1N0cmluZ30gd3JpdGUubWFwcGluZy50cmFuc2Zvcm1lciBUcmFuc2Zvcm1lciB0byBzZWxlY3QgdGhlIGFwcHJvcHJpYXRlIGVudHJpZXNcbiAgICAgKiBAcHJvcGVydHkge01vbnN0ZXIuRGF0YS5EYXRhc291cmNlfmV4YW1wbGVDYWxsYmFja1tdfSB3cml0ZS5tYXBwaW5nLmNhbGxiYWNrIHdpdGggdGhlIGhlbHAgb2YgdGhlIGNhbGxiYWNrLCB0aGUgc3RydWN0dXJlcyBjYW4gYmUgYWRqdXN0ZWQgYmVmb3JlIHdyaXRpbmcuXG4gICAgICogQHByb3BlcnR5IHtPYmplY3R9IHdyaXRlLnJlcG9ydFxuICAgICAqIEBwcm9wZXJ0eSB7U3RyaW5nfSB3cml0ZS5yZXBvcnQucGF0aCBQYXRoIHRvIHZhbGlkYXRpb25zXG4gICAgICogQHByb3BlcnR5IHtPYmplY3R9IHdyaXRlLnNoZWF0aGluZ1xuICAgICAqIEBwcm9wZXJ0eSB7T2JqZWN0fSB3cml0ZS5zaGVhdGhpbmcub2JqZWN0IE9iamVjdCB0byBiZSB3cmFwcGVkXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd9IHdyaXRlLnNoZWF0aGluZy5wYXRoIFBhdGggdG8gdGhlIGRhdGFcbiAgICAgKiBAcHJvcGVydHkge09iamVjdH0gcmVhZD17fSBPcHRpb25zXG4gICAgICogQHByb3BlcnR5IHtPYmplY3R9IHJlYWQuaW5pdD17fSBBbiBvcHRpb25zIG9iamVjdCBjb250YWluaW5nIGFueSBjdXN0b20gc2V0dGluZ3MgdGhhdCB5b3Ugd2FudCB0byBhcHBseSB0byB0aGUgcmVxdWVzdC4gVGhlIHBhcmFtZXRlcnMgYXJlIGlkZW50aWNhbCB0byB0aG9zZSBvZiB0aGUge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9SZXF1ZXN0L1JlcXVlc3R8UmVxdWVzdCBjb25zdHJ1Y3Rvcn1cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gcmVhZC5pbml0Lm1ldGhvZD1HRVRcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gcmVhZC5hY2NlcHRlZFN0YXR1cz1bMjAwXVxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSByZWFkLnVybCBVUkxcbiAgICAgKiBAcHJvcGVydHkge09iamVjdH0gcmVhZC5tYXBwaW5nIHRoZSBtYXBwaW5nIGlzIGFwcGxpZWQgYWZ0ZXIgcmVhZGluZy5cbiAgICAgKiBAcHJvcGVydHkge1N0cmluZ30gcmVhZC5tYXBwaW5nLnRyYW5zZm9ybWVyIFRyYW5zZm9ybWVyIHRvIHNlbGVjdCB0aGUgYXBwcm9wcmlhdGUgZW50cmllc1xuICAgICAqIEBwcm9wZXJ0eSB7TW9uc3Rlci5EYXRhLkRhdGFzb3VyY2V+ZXhhbXBsZUNhbGxiYWNrW119IHJlYWQubWFwcGluZy5jYWxsYmFjayB3aXRoIHRoZSBoZWxwIG9mIHRoZSBjYWxsYmFjaywgdGhlIHN0cnVjdHVyZXMgY2FuIGJlIGFkanVzdGVkIGFmdGVyIHJlYWRpbmcuXG4gICAgICovXG4gICAgZ2V0IGRlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3VwZXIuZGVmYXVsdHMsIHtcbiAgICAgICAgICAgIHdyaXRlOiB7XG4gICAgICAgICAgICAgICAgaW5pdDoge1xuICAgICAgICAgICAgICAgICAgICBtZXRob2Q6IFwiUE9TVFwiLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVzcG9uc2VDYWxsYmFjazogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgIGFjY2VwdGVkU3RhdHVzOiBbMjAwLCAyMDFdLFxuICAgICAgICAgICAgICAgIHVybDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgIG1hcHBpbmc6IHtcbiAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtZXI6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tzOiBbXSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHNoZWF0aGluZzoge1xuICAgICAgICAgICAgICAgICAgICBvYmplY3Q6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgcGF0aDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVwb3J0OiB7XG4gICAgICAgICAgICAgICAgICAgIHBhdGg6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlYWQ6IHtcbiAgICAgICAgICAgICAgICBpbml0OiB7XG4gICAgICAgICAgICAgICAgICAgIG1ldGhvZDogXCJHRVRcIixcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHJlc3BvbnNlQ2FsbGJhY2s6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICBhY2NlcHRlZFN0YXR1czogWzIwMF0sXG4gICAgICAgICAgICAgICAgdXJsOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgbWFwcGluZzoge1xuICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm1lcjogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgICAgICBjYWxsYmFja3M6IFtdLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSB0aGUgb3B0aW9ucyBkb2VzIG5vdCBjb250YWluIGEgdmFsaWQganNvbiBkZWZpbml0aW9uXG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYSBvYmplY3RcbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gdGhlIGRhdGEgY2Fubm90IGJlIHJlYWRcbiAgICAgKi9cbiAgICByZWFkKCkge1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgICAgICBsZXQgaW5pdCA9IHNlbGYuZ2V0T3B0aW9uKFwicmVhZC5pbml0XCIpO1xuICAgICAgICBpZiAoIWlzT2JqZWN0KGluaXQpKSBpbml0ID0ge307XG4gICAgICAgIGlmICghaW5pdFtcIm1ldGhvZFwiXSkgaW5pdFtcIm1ldGhvZFwiXSA9IFwiR0VUXCI7XG5cbiAgICAgICAgbGV0IGNhbGxiYWNrID0gc2VsZi5nZXRPcHRpb24oXCJyZWFkLnJlc3BvbnNlQ2FsbGJhY2tcIik7XG4gICAgICAgIGlmICghY2FsbGJhY2spXG4gICAgICAgICAgICBjYWxsYmFjayA9IChvYmopID0+IHtcbiAgICAgICAgICAgICAgICBzZWxmLnNldChzZWxmLnRyYW5zZm9ybVNlcnZlclBheWxvYWQuY2FsbChzZWxmLCBvYmopKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIGZldGNoRGF0YS5jYWxsKHRoaXMsIGluaXQsIFwicmVhZFwiLCBjYWxsYmFjayk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICAgKiBAdGhyb3dzIHtXcml0ZUVycm9yfSB0aGUgZGF0YSBjYW5ub3QgYmUgd3JpdHRlblxuICAgICAqL1xuICAgIHdyaXRlKCkge1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgICAgICBsZXQgaW5pdCA9IHNlbGYuZ2V0T3B0aW9uKFwid3JpdGUuaW5pdFwiKTtcbiAgICAgICAgaWYgKCFpc09iamVjdChpbml0KSkgaW5pdCA9IHt9O1xuICAgICAgICBpZiAodHlwZW9mIGluaXRbXCJoZWFkZXJzXCJdICE9PSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgICBpbml0W1wiaGVhZGVyc1wiXSA9IHtcbiAgICAgICAgICAgICAgICBcIkNvbnRlbnQtVHlwZVwiOiBcImFwcGxpY2F0aW9uL2pzb25cIixcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFpbml0W1wibWV0aG9kXCJdKSBpbml0W1wibWV0aG9kXCJdID0gXCJQT1NUXCI7XG5cbiAgICAgICAgbGV0IG9iaiA9IHNlbGYucHJlcGFyZVNlcnZlclBheWxvYWQoc2VsZi5nZXQoKSk7XG4gICAgICAgIGluaXRbXCJib2R5XCJdID0gSlNPTi5zdHJpbmdpZnkob2JqKTtcblxuICAgICAgICBsZXQgY2FsbGJhY2sgPSBzZWxmLmdldE9wdGlvbihcIndyaXRlLnJlc3BvbnNlQ2FsbGJhY2tcIik7XG4gICAgICAgIHJldHVybiBmZXRjaERhdGEuY2FsbCh0aGlzLCBpbml0LCBcIndyaXRlXCIsIGNhbGxiYWNrKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtSZXN0QVBJfVxuICAgICAqL1xuICAgIGdldENsb25lKCkge1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICAgICAgcmV0dXJuIG5ldyBSZXN0QVBJKFxuICAgICAgICAgICAgc2VsZltpbnRlcm5hbFN5bWJvbF0uZ2V0UmVhbFN1YmplY3QoKVtcIm9wdGlvbnNcIl0ucmVhZCxcbiAgICAgICAgICAgIHNlbGZbaW50ZXJuYWxTeW1ib2xdLmdldFJlYWxTdWJqZWN0KClbXCJvcHRpb25zXCJdLndyaXRlLFxuICAgICAgICApO1xuICAgIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIGluaXRcbiAqIEBwYXJhbSBrZXlcbiAqIEBwYXJhbSBjYWxsYmFja1xuICogQHJldHVybnMge1Byb21pc2U8c3RyaW5nPn1cbiAqL1xuZnVuY3Rpb24gZmV0Y2hEYXRhKGluaXQsIGtleSwgY2FsbGJhY2spIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICBsZXQgcmVzcG9uc2U7XG5cbiAgICByZXR1cm4gZmV0Y2goc2VsZi5nZXRPcHRpb24oYCR7a2V5fS51cmxgKSwgaW5pdClcbiAgICAgICAgLnRoZW4oKHJlc3ApID0+IHtcbiAgICAgICAgICAgIHJlc3BvbnNlID0gcmVzcDtcblxuICAgICAgICAgICAgY29uc3QgYWNjZXB0ZWRTdGF0dXMgPSBzZWxmLmdldE9wdGlvbihgJHtrZXl9LmFjY2VwdGVkU3RhdHVzYCwgWzIwMF0pO1xuXG4gICAgICAgICAgICBpZiAoYWNjZXB0ZWRTdGF0dXMuaW5kZXhPZihyZXNwLnN0YXR1cykgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoYHRoZSBkYXRhIGNhbm5vdCBiZSAke2tleX0gKHJlc3BvbnNlICR7cmVzcC5zdGF0dXN9KWApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gcmVzcC50ZXh0KCk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKChib2R5KSA9PiB7XG4gICAgICAgICAgICBsZXQgb2JqO1xuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIG9iaiA9IEpTT04ucGFyc2UoYm9keSk7XG5cbiAgICAgICAgICAgICAgICByZXNwb25zZVtyYXdEYXRhU3ltYm9sXSA9IG9iajtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBpZiAoYm9keS5sZW5ndGggPiAxMDApIHtcbiAgICAgICAgICAgICAgICAgICAgYm9keSA9IGAke2JvZHkuc3Vic3RyaW5nKDAsIDk3KX0uLi5gO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgdGhlIHJlc3BvbnNlIGRvZXMgbm90IGNvbnRhaW4gYSB2YWxpZCBqc29uIChhY3R1YWw6ICR7Ym9keX0pLmApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoY2FsbGJhY2sgJiYgaXNGdW5jdGlvbihjYWxsYmFjaykpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhvYmopO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgICAgIH0pO1xufVxuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgaW50ZXJuYWxTeW1ib2wsIGluc3RhbmNlU3ltYm9sIH0gZnJvbSBcIi4uLy4uLy4uLy4uL2NvbnN0YW50cy5tanNcIjtcblxuZXhwb3J0IHsgV3JpdGVFcnJvciB9O1xuXG4vKipcbiAqIEVycm9yIG1lc3NhZ2UgZm9yIEFQSSByZXF1ZXN0cyB3aXRoIGV4dGVuc2lvbiBvZiByZXF1ZXN0IGFuZCB2YWxpZGF0aW9uLlxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjQuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRhdGEuRGF0YXNvdXJjZS5TZXJ2ZXIuUmVzdEFQSVxuICogQHN1bW1hcnkgdGhlIGVycm9yIGlzIHRocm93biBieSB0aGUgcmVzdCBhcGkgaW4gY2FzZSBvZiBlcnJvclxuICovXG5jbGFzcyBXcml0ZUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2VcbiAgICAgKiBAcGFyYW0ge1Jlc3BvbnNlfSByZXNwb25zZVxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKG1lc3NhZ2UsIHJlc3BvbnNlLCB2YWxpZGF0aW9uKSB7XG4gICAgICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgICAgICB0aGlzW2ludGVybmFsU3ltYm9sXSA9IHtcbiAgICAgICAgICAgIHJlc3BvbnNlOiByZXNwb25zZSxcbiAgICAgICAgICAgIHZhbGlkYXRpb246IHZhbGlkYXRpb24sXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMi4xLjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci9kYXRhL2RhdGFzb3VyY2Uvc2VydmVyL3Jlc3RhcGkvd3JpdGVlcnJvclwiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtSZXNwb25zZX1cbiAgICAgKi9cbiAgICBnZXRSZXNwb25zZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbaW50ZXJuYWxTeW1ib2xdW1wicmVzcG9uc2VcIl07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7T2JqZWN0fVxuICAgICAqL1xuICAgIGdldFZhbGlkYXRpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzW2ludGVybmFsU3ltYm9sXVtcInZhbGlkYXRpb25cIl07XG4gICAgfVxufVxuIiwgIlwidXNlIHN0cmljdFwiO1xuXG5pbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuaW1wb3J0IHtSZXN0QVBJfSBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2RhdGEvZGF0YXNvdXJjZS9zZXJ2ZXIvcmVzdGFwaS5tanNcIjtcbmltcG9ydCB7dmFsaWRhdGVPYmplY3R9IGZyb20gXCIuLi8uLi8uLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvdHlwZXMvdmFsaWRhdGUubWpzXCI7XG5cbmRlc2NyaWJlKCdSZXN0QVBJJywgZnVuY3Rpb24gKCkge1xuXG4gICAgbGV0IGZldGNoUmVmZXJlbmNlO1xuICAgIGxldCByZXR1cm5TdGF0dXM7XG5cbiAgICBhZnRlckVhY2goKCkgPT4ge1xuICAgICAgICBnbG9iYWxUaGlzWydmZXRjaCddID0gZmV0Y2hSZWZlcmVuY2U7XG4gICAgfSk7XG5cbiAgICBiZWZvcmVFYWNoKCgpID0+IHtcblxuICAgICAgICByZXR1cm5TdGF0dXMgPSAyMDA7XG4gICAgICAgIGZldGNoUmVmZXJlbmNlID0gZ2xvYmFsVGhpc1snZmV0Y2gnXTtcbiAgICAgICAgZ2xvYmFsVGhpc1snZmV0Y2gnXSA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG5cbiAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZSh7XG4gICAgICAgICAgICAgICAgICAgIHRleHQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGE6IFwidGVzdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHN0YXR1czogcmV0dXJuU3RhdHVzXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KVxuXG4gICAgICAgIH07XG5cbiAgICB9KVxuXG4gICAgaXQoJ3Nob3VsZCBpbnN0YW5jZSBvZiBSZXN0QVBJICcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZXhwZWN0KG5ldyBSZXN0QVBJKCdodHRwczovL21vbnN0ZXJqcy5vcmcvYXNzZXRzL3dvcmxkLmpzb24nKSkudG8uYmUuaW5zdGFuY2VvZihSZXN0QVBJKVxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3J3JywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdyZWFkIHNob3VsZCByZXR1cm4gb2JqZWN0JywgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgICAgIGNvbnN0IGRzID0gbmV3IFJlc3RBUEkoe3VybDogJ2h0dHBzOi8vbW9uc3RlcmpzLm9yZy9hc3NldHMvd29ybGQuanNvbid9KVxuICAgICAgICAgICAgZHMucmVhZCgpLnRoZW4oZGF0YSA9PiB7XG4gICAgICAgICAgICAgICAgdmFsaWRhdGVPYmplY3QoZGF0YSk7XG4gICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgfSkuY2F0Y2goZSA9PiBkb25lKGUpKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3dyaXRlIHNob3VsZCAnLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICAgICAgY29uc3QgZHMgPSBuZXcgUmVzdEFQSSh7XG4gICAgICAgICAgICAgICAgICAgIHJlYWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHVybDogJ2h0dHBzOi8vbW9uc3RlcmpzLm9yZy9hc3NldHMvd29ybGQuanNvbidcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgd3JpdGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHVybDogJ2h0dHBzOi8vbW9uc3RlcmpzLm9yZy9hc3NldHMvd29ybGQuanNvbicsXG4gICAgICAgICAgICAgICAgICAgICAgICBhY2NlcHRlZFN0YXR1czogWzk5XVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgZHMud3JpdGUoKS50aGVuKGRhdGEgPT4ge1xuICAgICAgICAgICAgICAgIGRvbmUoXCJzaG91bGQgbm90IGJlIGhlcmVcIik7XG4gICAgICAgICAgICB9KS5jYXRjaChlID0+IGRvbmUoKSk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG5cbiAgICBkZXNjcmliZSgncncgd2l0aCBlcnJvcnMnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ3JlYWQgc2hvdWxkIHRocm93IGV4Y2VwdGlvbicsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICByZXR1cm5TdGF0dXMgPSA0MDA7IC8vIGZldGNoIHJlc3BvbnNlIHdpdGggNDAwXG5cbiAgICAgICAgICAgIGNvbnN0IGRzID0gbmV3IFJlc3RBUEkoe3VybDogJ2h0dHBzOi8vbW9uc3RlcmpzLm9yZy9hc3NldHMvd29ybGQuanNvbid9KVxuICAgICAgICAgICAgZHMucmVhZCgpLnRoZW4oZGF0YSA9PiB7XG4gICAgICAgICAgICAgICAgZG9uZShcInNob3VsZCBub3QgcnVuLlwiKTtcbiAgICAgICAgICAgIH0pLmNhdGNoKGUgPT4gZG9uZSgpKTsgLy8gc2hvdWxkIHRocm93IGV4Y2VwdGlvbiBiZWNhdXNlIHJldHVyblN0YXR1cz00MDBcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3dyaXRlIHNob3VsZCAnLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICAgICAgcmV0dXJuU3RhdHVzID0gNDAwOyAvLyBmZXRjaCByZXNwb25zZSB3aXRoIDQwMFxuICAgICAgICAgICAgY29uc3QgZHMgPSBuZXcgUmVzdEFQSSh7dXJsOiAnaHR0cHM6Ly9tb25zdGVyanMub3JnL2Fzc2V0cy93b3JsZC5qc29uJ30sIHt1cmw6ICdodHRwczovL21vbnN0ZXJqcy5vcmcvYXNzZXRzL3dvcmxkLmpzb24nfSlcbiAgICAgICAgICAgIGRzLndyaXRlKCkudGhlbihkYXRhID0+IHtcbiAgICAgICAgICAgICAgICB2YWxpZGF0ZU9iamVjdChkYXRhKTtcbiAgICAgICAgICAgICAgICBkb25lKFwiZXJyb3JcIik7XG4gICAgICAgICAgICB9KS5jYXRjaChlID0+IGRvbmUoKSk7IC8vIHNob3VsZCB0aHJvdyBleGNlcHRpb24gYmVjYXVzZSByZXR1cm5TdGF0dXM9NDAwXG4gICAgICAgIH0pO1xuXG5cbiAgICB9KVxuXG5cbn0pXG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBpbnRlcm5hbFN5bWJvbCwgaW5zdGFuY2VTeW1ib2wgfSBmcm9tIFwiLi4vLi4vLi4vY29uc3RhbnRzLm1qc1wiO1xuaW1wb3J0IHsgaXNTdHJpbmcsIGlzT2JqZWN0IH0gZnJvbSBcIi4uLy4uLy4uL3R5cGVzL2lzLm1qc1wiO1xuaW1wb3J0IHsgV2ViQ29ubmVjdCBhcyBOZXRXZWJDb25uZWN0IH0gZnJvbSBcIi4uLy4uLy4uL25ldC93ZWJjb25uZWN0Lm1qc1wiO1xuaW1wb3J0IHsgTWVzc2FnZSB9IGZyb20gXCIuLi8uLi8uLi9uZXQvd2ViY29ubmVjdC9tZXNzYWdlLm1qc1wiO1xuaW1wb3J0IHsgU2VydmVyIH0gZnJvbSBcIi4uL3NlcnZlci5tanNcIjtcblxuZXhwb3J0IHsgV2ViQ29ubmVjdCB9O1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAdHlwZSB7U3ltYm9sfVxuICpcbiAqIGhpbnQ6IHRoaXMgbmFtZSBpcyB1c2VkIGluIHRoZSB0ZXN0cy4gaWYgeW91IHdhbnQgdG8gY2hhbmdlIGl0LCBwbGVhc2UgY2hhbmdlIGl0IGluIHRoZSB0ZXN0cyBhcyB3ZWxsLlxuICovXG5jb25zdCB3ZWJDb25uZWN0U3ltYm9sID0gU3ltYm9sKFwiY29ubmVjdGlvblwiKTtcblxuLyoqXG4gKiBUaGUgUmVzdEFQSSBpcyBhIGNsYXNzIHRoYXQgZW5hYmxlcyBhIFJFU1QgQVBJIHNlcnZlci5cbiAqXG4gKiBAZXh0ZXJuYWxFeGFtcGxlIC4uLy4uLy4uLy4uL2V4YW1wbGUvZGF0YS9kYXRhc291cmNlL3NlcnZlci93ZWJjb25uZWN0Lm1qc1xuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMy4xLjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5EYXRhLkRhdGFzb3VyY2UuU2VydmVyXG4gKiBAc3VtbWFyeSBUaGUgTG9jYWxTdG9yYWdlIGNsYXNzIGVuY2Fwc3VsYXRlcyB0aGUgYWNjZXNzIHRvIGRhdGEgb2JqZWN0cy5cbiAqL1xuY2xhc3MgV2ViQ29ubmVjdCBleHRlbmRzIFNlcnZlciB7XG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIG9wdGlvbnMgY29udGFpbnMgZGVmaW5pdGlvbnMgZm9yIHRoZSBkYXRhc291cmNlLlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgc3VwZXIoKTtcblxuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgICAgICBpZiAoaXNTdHJpbmcob3B0aW9ucykpIHtcbiAgICAgICAgICAgIG9wdGlvbnMgPSB7IHVybDogb3B0aW9ucyB9O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFpc09iamVjdChvcHRpb25zKSkgb3B0aW9ucyA9IHt9O1xuICAgICAgICB0aGlzLnNldE9wdGlvbnMob3B0aW9ucyk7XG4gICAgICAgIHRoaXNbd2ViQ29ubmVjdFN5bWJvbF0gPSBuZXcgTmV0V2ViQ29ubmVjdCh7XG4gICAgICAgICAgICB1cmw6IHNlbGYuZ2V0T3B0aW9uKFwidXJsXCIpLFxuICAgICAgICAgICAgY29ubmVjdGlvbjoge1xuICAgICAgICAgICAgICAgIHRpbWVvdXQ6IHNlbGYuZ2V0T3B0aW9uKFwiY29ubmVjdGlvbi50aW1lb3V0XCIpLFxuICAgICAgICAgICAgICAgIHJlY29ubmVjdDoge1xuICAgICAgICAgICAgICAgICAgICB0aW1lb3V0OiBzZWxmLmdldE9wdGlvbihcImNvbm5lY3Rpb24ucmVjb25uZWN0LnRpbWVvdXRcIiksXG4gICAgICAgICAgICAgICAgICAgIGF0dGVtcHRzOiBzZWxmLmdldE9wdGlvbihcImNvbm5lY3Rpb24ucmVjb25uZWN0LmF0dGVtcHRzXCIpLFxuICAgICAgICAgICAgICAgICAgICBlbmFibGVkOiBzZWxmLmdldE9wdGlvbihcImNvbm5lY3Rpb24ucmVjb25uZWN0LmVuYWJsZWRcIiksXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHJldHVybnMge1Byb21pc2V9XG4gICAgICovXG4gICAgY29ubmVjdCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbd2ViQ29ubmVjdFN5bWJvbF0uY29ubmVjdCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgICAqL1xuICAgIGlzQ29ubmVjdGVkKCkge1xuICAgICAgICByZXR1cm4gdGhpc1t3ZWJDb25uZWN0U3ltYm9sXS5pc0Nvbm5lY3RlZCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgYGluc3RhbmNlb2ZgIG9wZXJhdG9yLlxuICAgICAqIEByZXR1cm5zIHtzeW1ib2x9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBbaW5zdGFuY2VTeW1ib2xdKCkge1xuICAgICAgICByZXR1cm4gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvZGF0YS9kYXRhc291cmNlL3NlcnZlci93ZWJjb25uZWN0XCIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB1cmw9dW5kZWZpbmVkIERlZmluZXMgdGhlIHJlc291cmNlIHRoYXQgeW91IHdpc2ggdG8gZmV0Y2guXG4gICAgICogQHByb3BlcnR5IHtPYmplY3R9IGNvbm5lY3Rpb25cbiAgICAgKiBAcHJvcGVydHkge09iamVjdH0gY29ubmVjdGlvbi50aW1lb3V0PTUwMDAgRGVmaW5lcyB0aGUgdGltZW91dCBmb3IgdGhlIGNvbm5lY3Rpb24uXG4gICAgICogQHByb3BlcnR5IHtOdW1iZXJ9IGNvbm5lY3Rpb24ucmVjb25uZWN0LnRpbWVvdXQgVGhlIHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzIGZvciB0aGUgcmVjb25uZWN0LlxuICAgICAqIEBwcm9wZXJ0eSB7TnVtYmVyfSBjb25uZWN0aW9uLnJlY29ubmVjdC5hdHRlbXB0cyBUaGUgbWF4aW11bSBudW1iZXIgb2YgcmVjb25uZWN0cy5cbiAgICAgKiBAcHJvcGVydHkge0Jvb2x9IGNvbm5lY3Rpb24ucmVjb25uZWN0LmVuYWJsZWQgSWYgdGhlIHJlY29ubmVjdCBpcyBlbmFibGVkLlxuICAgICAqIEBwcm9wZXJ0eSB7T2JqZWN0fSB3cml0ZT17fSBPcHRpb25zXG4gICAgICogQHByb3BlcnR5IHtPYmplY3R9IHdyaXRlLm1hcHBpbmcgdGhlIG1hcHBpbmcgaXMgYXBwbGllZCBiZWZvcmUgd3JpdGluZy5cbiAgICAgKiBAcHJvcGVydHkge1N0cmluZ30gd3JpdGUubWFwcGluZy50cmFuc2Zvcm1lciBUcmFuc2Zvcm1lciB0byBzZWxlY3QgdGhlIGFwcHJvcHJpYXRlIGVudHJpZXNcbiAgICAgKiBAcHJvcGVydHkge01vbnN0ZXIuRGF0YS5EYXRhc291cmNlfmV4YW1wbGVDYWxsYmFja1tdfSB3cml0ZS5tYXBwaW5nLmNhbGxiYWNrIHdpdGggdGhlIGhlbHAgb2YgdGhlIGNhbGxiYWNrLCB0aGUgc3RydWN0dXJlcyBjYW4gYmUgYWRqdXN0ZWQgYmVmb3JlIHdyaXRpbmcuXG4gICAgICogQHByb3BlcnR5IHtPYmplY3R9IHdyaXRlLnNoZWF0aGluZ1xuICAgICAqIEBwcm9wZXJ0eSB7T2JqZWN0fSB3cml0ZS5zaGVhdGhpbmcub2JqZWN0IE9iamVjdCB0byBiZSB3cmFwcGVkXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd9IHdyaXRlLnNoZWF0aGluZy5wYXRoIFBhdGggdG8gdGhlIGRhdGFcbiAgICAgKiBAcHJvcGVydHkge09iamVjdH0gcmVhZD17fSBPcHRpb25zXG4gICAgICogQHByb3BlcnR5IHtTdHJpbmd9IHJlYWQucGF0aCBQYXRoIHRvIGRhdGFcbiAgICAgKiBAcHJvcGVydHkge09iamVjdH0gcmVhZC5tYXBwaW5nIHRoZSBtYXBwaW5nIGlzIGFwcGxpZWQgYWZ0ZXIgcmVhZGluZy5cbiAgICAgKiBAcHJvcGVydHkge1N0cmluZ30gcmVhZC5tYXBwaW5nLnRyYW5zZm9ybWVyIFRyYW5zZm9ybWVyIHRvIHNlbGVjdCB0aGUgYXBwcm9wcmlhdGUgZW50cmllc1xuICAgICAqIEBwcm9wZXJ0eSB7TW9uc3Rlci5EYXRhLkRhdGFzb3VyY2V+ZXhhbXBsZUNhbGxiYWNrW119IHJlYWQubWFwcGluZy5jYWxsYmFjayB3aXRoIHRoZSBoZWxwIG9mIHRoZSBjYWxsYmFjaywgdGhlIHN0cnVjdHVyZXMgY2FuIGJlIGFkanVzdGVkIGFmdGVyIHJlYWRpbmcuXG4gICAgICovXG4gICAgZ2V0IGRlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3VwZXIuZGVmYXVsdHMsIHtcbiAgICAgICAgICAgIHVybDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgd3JpdGU6IHtcbiAgICAgICAgICAgICAgICBtYXBwaW5nOiB7XG4gICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybWVyOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrczoge30sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBzaGVhdGhpbmc6IHtcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0OiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgIHBhdGg6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlYWQ6IHtcbiAgICAgICAgICAgICAgICBtYXBwaW5nOiB7XG4gICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybWVyOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrczoge30sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBwYXRoOiB1bmRlZmluZWQsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY29ubmVjdGlvbjoge1xuICAgICAgICAgICAgICAgIHRpbWVvdXQ6IDUwMDAsXG4gICAgICAgICAgICAgICAgcmVjb25uZWN0OiB7XG4gICAgICAgICAgICAgICAgICAgIHRpbWVvdXQ6IDEwMDAsXG4gICAgICAgICAgICAgICAgICAgIGF0dGVtcHRzOiAxLFxuICAgICAgICAgICAgICAgICAgICBlbmFibGVkOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgY2xvc2VzIHRoZSBjb25uZWN0aW9uLlxuICAgICAqXG4gICAgICogQHJldHVybnMge1Byb21pc2V9XG4gICAgICovXG4gICAgY2xvc2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzW3dlYkNvbm5lY3RTeW1ib2xdLmNsb3NlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICAgKi9cbiAgICByZWFkKCkge1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgd2hpbGUgKHRoaXNbd2ViQ29ubmVjdFN5bWJvbF0uZGF0YVJlY2VpdmVkKCkgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICBsZXQgb2JqID0gdGhpc1t3ZWJDb25uZWN0U3ltYm9sXS5wb2xsKCk7XG4gICAgICAgICAgICAgICAgaWYgKCFpc09iamVjdChvYmopKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoXCJUaGUgcmVjZWl2ZWQgZGF0YSBpcyBub3QgYW4gb2JqZWN0LlwiKSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBNZXNzYWdlKSkge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKFwiVGhlIHJlY2VpdmVkIGRhdGEgaXMgbm90IGEgTWVzc2FnZS5cIikpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgb2JqID0gb2JqLmdldERhdGEoKTtcbiAgICAgICAgICAgICAgICBvYmogPSBzZWxmLnRyYW5zZm9ybVNlcnZlclBheWxvYWQuY2FsbChzZWxmLCBvYmopO1xuICAgICAgICAgICAgICAgIHNlbGYuc2V0KG9iaik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJlc29sdmUoc2VsZi5nZXQoKSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAgICovXG4gICAgd3JpdGUoKSB7XG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgICAgICBsZXQgb2JqID0gc2VsZi5wcmVwYXJlU2VydmVyUGF5bG9hZChzZWxmLmdldCgpKTtcbiAgICAgICAgcmV0dXJuIHNlbGZbd2ViQ29ubmVjdFN5bWJvbF0uc2VuZChvYmopO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1Jlc3RBUEl9XG4gICAgICovXG4gICAgZ2V0Q2xvbmUoKSB7XG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgICAgICByZXR1cm4gbmV3IFdlYkNvbm5lY3Qoc2VsZltpbnRlcm5hbFN5bWJvbF0uZ2V0UmVhbFN1YmplY3QoKVtcIm9wdGlvbnNcIl0pO1xuICAgIH1cbn1cbiIsICJpbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuaW1wb3J0IHtXZWJDb25uZWN0fSBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vLi4vYXBwbGljYXRpb24vc291cmNlL2RhdGEvZGF0YXNvdXJjZS9zZXJ2ZXIvd2ViY29ubmVjdC5tanNcIjtcbmltcG9ydCB7aW5pdFdlYlNvY2tldH0gZnJvbSBcIi4uLy4uLy4uLy4uL3V0aWwvd2Vic29ja2V0Lm1qc1wiO1xuXG5jb25zdCB0ZXN0VXJsID0gXCJ3c3M6Ly93cy5wb3N0bWFuLWVjaG8uY29tL3Jhd1wiXG5cbi8vIGNvbnN0IGcgPSBnZXRHbG9iYWwoKTtcbi8vIGdbJ1dlYlNvY2tldCddID0gV1M7XG5cblxuZGVzY3JpYmUoJ1dlYnNvY2tldCcsIGZ1bmN0aW9uICgpIHtcblxuICAgIGxldCBkcyA9IHVuZGVmaW5lZFxuXG4gICAgYmVmb3JlKGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgIGluaXRXZWJTb2NrZXQoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICB9KS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgZG9uZShlKVxuICAgICAgICB9KVxuICAgIH0pO1xuXG4gICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgIGlmIChkcykge1xuICAgICAgICAgICAgZHMuY2xvc2UoKVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gd29ya2Fyb3VuZDogd2l0aG91dCB0aGlzLCB0aGUgbm9kZSB0ZXN0IHdpbGwgaGFuZyBcbiAgICAgICAgZm9yIChjb25zdCBzeW0gb2YgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhkcykpIHtcbiAgICAgICAgICAgIGlmIChzeW0udG9TdHJpbmcoKSA9PT0gJ1N5bWJvbChjb25uZWN0aW9uKScpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gZHNbc3ltXVxuICAgICAgICAgICAgICAgIGZvciAoY29uc3Qgc3ltMiBvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKGNvbm5lY3Rpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzeW0yLnRvU3RyaW5nKCkgPT09ICdTeW1ib2woY29ubmVjdGlvbiknKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzb2NrZXQgPSBjb25uZWN0aW9uW3N5bTJdPy5zb2NrZXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc29ja2V0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBzb2NrZXQ/LnRlcm1pbmF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb2NrZXQ/LlsndGVybWluYXRlJ10oKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGRvbmUoKVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZXQgY2xvbmUnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgZHMgPSBuZXcgV2ViQ29ubmVjdCh0ZXN0VXJsKVxuICAgICAgICBjb25zdCBjbG9uZSA9IGRzLmdldENsb25lKClcblxuICAgICAgICBleHBlY3QoY2xvbmUpLnRvLmJlLmFuLmluc3RhbmNlb2YoV2ViQ29ubmVjdClcblxuXG4gICAgfSlcblxuICAgIGl0KCdzaG91bGQgdHJhbnNmb3JtIGRhdGEnLCBmdW5jdGlvbiAoZG9uZSkge1xuXG4gICAgICAgIGxldCB3cml0ZUNhbGxiYWNrQ2FsbGVkID0gZmFsc2VcbiAgICAgICAgbGV0IHJlYWRDYWxsYmFja0NhbGxlZCA9IGZhbHNlXG5cbiAgICAgICAgZHMgPSBuZXcgV2ViQ29ubmVjdCh7XG4gICAgICAgICAgICB1cmw6IHRlc3RVcmwsXG4gICAgICAgICAgICB3cml0ZToge1xuICAgICAgICAgICAgICAgIG1hcHBpbmc6IHtcbiAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtZXI6IFwiY2FsbDpvbldyaXRlXCIsXG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrczoge1xuICAgICAgICAgICAgICAgICAgICAgICAgb25Xcml0ZTogKGRhdGEpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZUNhbGxiYWNrQ2FsbGVkID0gdHJ1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkYXRhXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHNoZWF0aGluZzoge1xuICAgICAgICAgICAgICAgICAgICBvYmplY3Q6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlbW86IDEsXG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeHl6OiB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgcGF0aDogXCJkYXRhLnh5elwiLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmVhZDoge1xuICAgICAgICAgICAgICAgIG1hcHBpbmc6IHtcbiAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtZXI6IFwiY2FsbDpvblJlYWRcIixcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvblJlYWQ6IChkYXRhKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhZENhbGxiYWNrQ2FsbGVkID0gdHJ1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkYXRhXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHBhdGg6ICdkYXRhLnh5eicsXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pXG5cbiAgICAgICAgZHMuY29ubmVjdCgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgZHMuc2V0KHtcbiAgICAgICAgICAgICAgICBlbnZlbG9wOiB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IFwiSGVsbG8gV29ybGRcIlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGRzLndyaXRlKCkudGhlbigoKSA9PiB7XG5cbiAgICAgICAgICAgICAgICBkcy5zZXQoe30pXG4gICAgICAgICAgICAgICAgZXhwZWN0KGRzLmdldCgpKS50by5iZS5kZWVwLmVxdWFsKHt9KTtcblxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuXG5cbiAgICAgICAgICAgICAgICAgICAgZHMucmVhZCgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0KGRzLmdldCgpKS50by5iZS5kZWVwLmVxdWFsKHtlbnZlbG9wOnttZXNzYWdlOiBcIkhlbGxvIFdvcmxkXCJ9fSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBleHBlY3Qod3JpdGVDYWxsYmFja0NhbGxlZCkudG8uYmUudHJ1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0KHJlYWRDYWxsYmFja0NhbGxlZCkudG8uYmUudHJ1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgZG9uZSgpXG4gICAgICAgICAgICAgICAgICAgIH0pLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkb25lKGUpXG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgfSwgMjAwKVxuXG4gICAgICAgICAgICB9KS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgZG9uZShuZXcgRXJyb3IoZXJyKSk7XG4gICAgICAgICAgICB9KVxuXG5cbiAgICAgICAgfSkuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIGRvbmUoZSlcbiAgICAgICAgfSlcblxuXG4gICAgfSlcblxuICAgIGl0KCdzaG91bGQgY29ubmVjdCcsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgIGRzID0gbmV3IFdlYkNvbm5lY3Qoe1xuICAgICAgICAgICAgdXJsOiB0ZXN0VXJsLFxuICAgICAgICAgICAgcmVjb25uZWN0OiB7XG4gICAgICAgICAgICAgICAgZW5hYmxlZDogZmFsc2VcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGRzLmNvbm5lY3QoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICB9KS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgZG9uZShlKVxuICAgICAgICB9KVxuXG5cbiAgICB9KVxuXG4gICAgaXQoJ3Nob3VsZCBzZW5kIG1lc3NhZ2UnLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICBkcyA9IG5ldyBXZWJDb25uZWN0KHtcbiAgICAgICAgICAgIHVybDogdGVzdFVybCxcbiAgICAgICAgICAgIHJlY29ubmVjdDoge1xuICAgICAgICAgICAgICAgIGVuYWJsZWQ6IGZhbHNlXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBkcy5jb25uZWN0KCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICBkcy5zZXQoe1xuICAgICAgICAgICAgICAgIGVudmVsb3A6IHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogXCJIZWxsbyBXb3JsZFwiXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgZHMud3JpdGUoKS50aGVuKCgpID0+IHtcblxuICAgICAgICAgICAgICAgIGRzLnNldCh7fSlcbiAgICAgICAgICAgICAgICBleHBlY3QoZHMuZ2V0KCkpLnRvLmJlLmRlZXAuZXF1YWwoe30pO1xuXG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgZHMucmVhZCgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QoZHMuZ2V0KCkpLnRvLmJlLmRlZXAuZXF1YWwoe2VudmVsb3A6e21lc3NhZ2U6IFwiSGVsbG8gV29ybGRcIn19KTtcbiAgICAgICAgICAgICAgICAgICAgZG9uZSgpXG4gICAgICAgICAgICAgICAgfSkuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgZG9uZShlKVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgfSw1MDApXG4gICAgICAgICAgICAgICAgXG5cbiAgICAgICAgICAgIH0pLmNhdGNoKChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICBkb25lKG5ldyBFcnJvcihlcnIpKTtcbiAgICAgICAgICAgIH0pXG5cblxuICAgICAgICB9KS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgZG9uZShlKVxuICAgICAgICB9KVxuXG5cbiAgICB9KS50aW1lb3V0KDEwMDAwKTtcblxufSk7XG4iLCAiLyoqIG5vZGVqcyBkb2VzbnQgc3VwcG9ydCB3aW5kb3cuY3J5cHQgKi9cbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5cbmRlc2NyaWJlKCdNYXRoJywgZnVuY3Rpb24gKCkge1xuXG4gICAgbGV0IHJhbmRvbSA9ICgpID0+IHt9XG4gICAgXG4gICAgYmVmb3JlKGZ1bmN0aW9uIChkb25lKSB7XG5cbiAgICAgICAgbGV0IHByb21pc2VzID0gW11cbiAgICAgICAgaWYgKCFnbG9iYWxUaGlzWydjcnlwdG8nXSkge1xuICAgICAgICAgICAgcHJvbWlzZXMucHVzaChpbXBvcnQoXCJAcGVjdWxpYXIvd2ViY3J5cHRvXCIpLnRoZW4obSA9PiB7XG4gICAgICAgICAgICAgICAgZ2xvYmFsVGhpc1snY3J5cHRvJ10gPSBuZXcgbS5DcnlwdG8oKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH0pKVxuICAgICAgICB9XG5cbiAgICAgICAgcHJvbWlzZXMucHVzaChpbXBvcnQoXCIuLi8uLi8uLi8uLi9hcHBsaWNhdGlvbi9zb3VyY2UvbWF0aC9yYW5kb20ubWpzXCIpLnRoZW4obSA9PiB7XG4gICAgICAgICAgICByYW5kb20gPSBtLnJhbmRvbTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9KSlcblxuXG4gICAgICAgIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICB9KTtcblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJy5yYW5kb20oKScsIGZ1bmN0aW9uICgpIHtcblxuXG4gICAgICAgIGl0KCdhIGdyZWF0ZXIgYiBzaG91bGQgdGhyb3cgZXJyb3IgJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KCgpID0+IHJhbmRvbSgxMCwgMikpLnRvLnRocm93KEVycm9yKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJyBzaG91bGQgcmV0dXJuIGEgbnVtYmVyICcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCByID0gcmFuZG9tKCk7XG4gICAgICAgICAgICBleHBlY3QocikudGhhdC5pcy5hKCdudW1iZXInKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJyBzaG91bGQgcmV0dXJuIGEgbnVtYmVyICcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdCgoKSA9PiByYW5kb20oNSwgNikpLnRvLnRocm93KEVycm9yKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJyBzaG91bGQgdGhyb3cgRXJyb3Igd2UgY2Fubm90IGdlbmVyYXRlIG51bWJlcnMgbGFyZ2VyIHRoYW4gNTMgYml0cy4nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QoKCkgPT4gcmFuZG9tKC05OTk5OTk5OTksIDk5OTk5OTk5OTk5OTk5OTk5OTk5KSkudG8udGhyb3coRXJyb3IpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnIHNob3VsZCB0aHJvdyBFcnJvciB3ZSBjYW5ub3QgZ2VuZXJhdGUgbnVtYmVycyBsYXJnZXIgdGhhbiA1MyBiaXRzLicsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgIFsxLCAxMDBdLFxuICAgICAgICAgICAgICAgIFs1MDAsIDYwMF0sXG4gICAgICAgICAgICAgICAgWzEwMCwgMTAwMF1cbiAgICAgICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICAgICAgbGV0IHIgPSByYW5kb20oYSwgYik7XG5cbiAgICAgICAgICAgICAgICBpdChyICsgJyBzaG91bGQgcmV0dXJuIHZhbHVlIGJldHdlZW4gJyArIGEgKyAnICcgKyBiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChyID49IGEpLnRvLmJlLnRydWU7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChyIDw9IGIpLnRvLmJlLnRydWU7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgIFsxLCAxMDBdLFxuICAgICAgICAgICAgICAgIFs1MDAsIDYwMF0sXG4gICAgICAgICAgICAgICAgWzEwMCwgMTAwMF1cbiAgICAgICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICAgICAgbGV0IHN1bSA9IDA7XG4gICAgICAgICAgICAgICAgY29uc3Qgcm91bmRzID0gNTAwXG5cbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbWF4ID0gcm91bmRzOyBpIDwgbWF4OyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgc3VtICs9IHJhbmRvbShhLCBiKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBsZXQgYXZnID0gc3VtIC8gcm91bmRzO1xuXG4gICAgICAgICAgICAgICAgaXQoYXZnICsgJyBzaG91bGQgYmV0d2VlbiAnICsgYSArICcgJyArIGIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KGF2ZyA+IGEpLnRvLmJlLnRydWVcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KGF2ZyA8IGIpLnRvLmJlLnRydWVcbiAgICAgICAgICAgICAgICB9KVxuXG5cbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgfSlc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WUFBUSxNQUFNO0FBQUEsTUFDVixLQUFLLGFBQWE7QUFDZCxlQUFPO0FBQUEsTUFDWCxLQUFLLGFBQWE7QUFDZCxlQUFPO0FBQUEsTUFDWCxLQUFLLGFBQWE7QUFDZCxlQUFPO0FBQUEsTUFDWCxLQUFLLGFBQWE7QUFDZCxlQUFPO0FBQUEsTUFDWCxLQUFLLGFBQWE7QUFDZCxlQUFPO0FBQUEsTUFDWCxLQUFLLGFBQWE7QUFDZCxlQUFPO0FBQUEsTUFDWCxLQUFLLGFBQWE7QUFDZCxlQUFPO0FBQUEsTUFDWCxLQUFLLGFBQWE7QUFDZCxlQUFPO0FBQUEsTUFDWCxLQUFLLGFBQWE7QUFDZCxlQUFPO0FBQUEsTUFDWCxLQUFLLGFBQWE7QUFDZCxlQUFPO0FBQUEsTUFDWCxLQUFLLGFBQWE7QUFDZCxlQUFPO0FBQUEsTUFDWCxLQUFLLGFBQWE7QUFDZCxlQUFPO0FBQUEsTUFDWCxLQUFLLGFBQWE7QUFDZCxlQUFPO0FBQUEsTUFDWCxLQUFLLGFBQWE7QUFDZCxlQUFPO0FBQUEsTUFDWCxLQUFLLGFBQWE7QUFDZCxlQUFPO0FBQUEsTUFDWCxLQUFLLGFBQWE7QUFDZCxlQUFPO0FBQUEsTUFDWCxLQUFLLGFBQWE7QUFDZCxlQUFPO0FBQUEsTUFDWCxLQUFLLGFBQWE7QUFDZCxlQUFPO0FBQUEsTUFDWCxLQUFLLGFBQWE7QUFDZCxlQUFPO0FBQUEsTUFDWCxLQUFLLGFBQWE7QUFDZCxlQUFPO0FBQUEsTUFDWCxLQUFLLGFBQWE7QUFDZCxlQUFPO0FBQUEsTUFDWCxLQUFLLGFBQWE7QUFDZCxlQUFPO0FBQUEsTUFDWDtBQUNJLGVBQU87QUFBQSxJQUNmO0FBQUEsRUFDSjtBQXZJQSxNQUdhLGlCQWFBLHFCQU1BLHdCQVlBLHVCQUlBLDhCQUlBLHFCQUlBLHlCQWNBLHdCQUNBLHVCQUNBLDZCQUNBLDJCQUNBLDZCQUNBLDJCQUNBLDRCQUNBLHVCQUNBLDJCQUNBLDJCQUNBLDJCQUNBLDZCQUNBLHFCQUlBLDZCQUlBO0FBaEZiO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDTyxNQUFNLGtCQUFrQjtBQUFBLFFBQzNC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QUFTLFNBQVMsRUFBRSxNQUFNLG1CQUFtQixJQUFJLG1CQUFtQixNQUFNLElBQUksQ0FBQztBQUMvRSxlQUFTLFNBQVMsRUFBRSxNQUFNLG1CQUFtQixJQUFJLG1CQUFtQixNQUFNLElBQUksQ0FBQztBQUMvRSxlQUFTLFNBQVMsRUFBRSxNQUFNLG1CQUFtQixJQUFJLG1CQUFtQixNQUFNLElBQUksQ0FBQztBQUMvRSxlQUFTLFNBQVMsRUFBRSxNQUFNLG1CQUFtQixJQUFJLG1CQUFtQixNQUFNLElBQUksQ0FBQztBQUMvRSxlQUFTLFNBQVMsRUFBRSxNQUFNLG1CQUFtQixJQUFJLG1CQUFtQixNQUFNLElBQUksQ0FBQztBQUMvRSxlQUFTLFNBQVMsRUFBRSxNQUFNLG1CQUFtQixJQUFJLG1CQUFtQixNQUFNLElBQUksQ0FBQztBQUMvRSxlQUFTLFNBQVMsRUFBRSxNQUFNLG1CQUFtQixJQUFJLG1CQUFtQixNQUFNLElBQUksQ0FBQztBQUMvRSxlQUFTLFNBQVMsRUFBRSxNQUFNLG1CQUFtQixJQUFJLG1CQUFtQixNQUFNLElBQUksQ0FBQztBQUMvRSxlQUFTLFNBQVMsRUFBRSxNQUFNLG1CQUFtQixJQUFJLG1CQUFtQixNQUFNLElBQUksQ0FBQztBQUMvRSxlQUFTLFNBQVMsRUFBRSxNQUFNLG1CQUFtQixJQUFJLG1CQUFtQixNQUFNLElBQUksQ0FBQztBQUMvRSxlQUFTLFNBQVMsRUFBRSxNQUFNLG1CQUFtQixJQUFJLG1CQUFtQixNQUFNLElBQUksQ0FBQztBQUMvRSxlQUFTLFNBQVMsRUFBRSxNQUFNLG1CQUFtQixJQUFJLG1CQUFtQixNQUFNLElBQUksQ0FBQztBQUMvRSxlQUFTLFNBQVMsRUFBRSxNQUFNLG1CQUFtQixJQUFJLG1CQUFtQixNQUFNLElBQUksQ0FBQztBQUMvRSxlQUFTLFNBQVMsRUFBRSxNQUFNLG1CQUFtQixJQUFJLG1CQUFtQixNQUFNLElBQUksQ0FBQztBQUUvRSxNQUFNLGVBQU4sY0FBMkIsZUFBZTtBQUFBLFFBQ3RDLGNBQWM7QUFDVixnQkFBTSxHQUFHLFNBQVM7QUFD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QUNBO0FBQUEsUUFDSSxDQUFDO0FBQUEsUUFDRDtBQUFBLFVBQ0ksR0FBRztBQUFBLFFBQ1A7QUFBQSxRQUNBO0FBQUEsTUFDSjtBQUFBLE1BRUE7QUFBQSxRQUNJO0FBQUEsVUFDSSxHQUFHO0FBQUEsUUFDUDtBQUFBLFFBQ0E7QUFBQSxVQUNJLEdBQUc7QUFBQSxRQUNQO0FBQUEsUUFDQTtBQUFBLE1BQ0o7QUFBQSxNQUVBO0FBQUEsUUFDSTtBQUFBLFVBQ0ksR0FBRztBQUFBLFFBQ1A7QUFBQSxRQUNBO0FBQUEsVUFDSSxHQUFHO0FBQUEsUUFDUDtBQUFBLFFBQ0E7QUFBQSxNQUNKO0FBQUEsTUFFQTtBQUFBLFFBQ0k7QUFBQSxVQUNJLEdBQUc7QUFBQSxRQUNQO0FBQUEsUUFDQTtBQUFBLFVBQ0ksR0FBRztBQUFBLFFBQ1A7QUFBQSxRQUNBO0FBQUEsTUFDSjtBQUFBLE1BRUE7QUFBQSxRQUNJO0FBQUEsVUFDSSxHQUFHO0FBQUEsUUFDUDtBQUFBLFFBQ0E7QUFBQSxVQUNJLEdBQUc7QUFBQSxVQUNILEdBQUc7QUFBQSxRQUNQO0FBQUEsUUFDQTtBQUFBLE1BQ0o7QUFBQSxNQUNBO0FBQUEsUUFDSTtBQUFBLFVBQ0ksR0FBRztBQUFBLFFBQ1A7QUFBQSxRQUNBLENBQUM7QUFBQSxRQUNEO0FBQUEsTUFDSjtBQUFBLE1BQ0E7QUFBQSxRQUNJO0FBQUEsVUFDSSxHQUFHO0FBQUEsUUFDUDtBQUFBLFFBQ0E7QUFBQSxVQUNJLEdBQUc7QUFBQSxRQUNQO0FBQUEsUUFDQTtBQUFBLE1BQ0o7QUFBQSxNQUNBO0FBQUEsUUFDSSxDQUFDO0FBQUEsUUFDRDtBQUFBLFVBQ0ksR0FBRztBQUFBLFFBQ1A7QUFBQSxRQUNBO0FBQUEsTUFDSjtBQUFBLE1BQUc7QUFBQSxRQUNILENBQUM7QUFBQSxRQUNELEVBQUMsR0FBRyxPQUFTO0FBQUEsUUFDYjtBQUFBLE1BQ0o7QUFBQSxJQUdBLEVBQUUsUUFBUSxTQUFVLE1BQU07QUFFdEIsVUFBSUMsS0FBSSxLQUFLLE1BQU07QUFDbkIsVUFBSSxJQUFJLEtBQUssTUFB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SUFBSSxrQ0FBa0NBLEtBQUksTUFBTSxHQUFHLFdBQVk7QUFDOUQsbUJBQU8sS0FBS0EsRUFBQyxFQUFFLEdBQUcsR0FBRztBQUNyQixtQkFBTyxLQUFLLENBQUMsRUFBRSxHQUFHLEdBQUc7QUFBQSxVQUN6QixDQUFDO0FBQUEsUUFDTCxDQUFDO0FBRUQ7QUFBQSxVQUNJLENBQUMsR0FBRyxHQUFHO0FBQUEsVUFDUCxDQUFDLEtBQUssR0FBRztBQUFBLFVBQ1QsQ0FBQyxLQUFLLEdBQUk7QUFBQSxRQUNkLEVBQUUsUUFBUSxTQUFVLE1BQU07QUFFdEIsY0FBSUEsS0FBSSxLQUFLLE1BQU07QUFDbkIsY0FBSSxJQUFJLEtBQUssTUFBTTtBQUVuQixjQUFJLE1BQU07QUFDVixnQkFBTSxTQUFTO0FBRWYsbUJBQVMsSUFBSSxHQUFHLE1BQU0sUUFBUSxJQUFJLEtBQUssS0FBSztBQUN4QyxtQkFBT0QsUUFBT0MsSUFBRyxDQUFDO0FBQUEsVUFDdEI7QUFFQSxjQUFJLE1BQU0sTUFBTTtBQUVoQixhQUFHLE1BQU0scUJBQXFCQSxLQUFJLE1BQU0sR0FBRyxXQUFZO0FBQ25ELG1CQUFPLE1BQU1BLEVBQUMsRUFBRSxHQUFHLEdBQUc7QUFDdEIsbUJBQU8sTUFBTSxDQUFDLEVBQUUsR0FBRyxHQUFHO0FBQUEsVUFDMUIsQ0FBQztBQUFBLFFBR0wsQ0FBQztBQUFBLE1BRUwsQ0FBQztBQUFBLElBR0wsQ0FBQztBQUFBLEVBR0wsQ0FBQzsiLAogICJuYW1lcyI6IFsiQXNzZXJ0aW9uRXJyb3IiLCAiZXh0ZW5kIiwgImdsb2JhbCIsICJBc3NlcnRpb25FcnJvciIsICJnbG9iYWwiLCAiZXhwb3J0cyIsICJvYmoiLCAidHJ1bmNhdGUiLCAiZ2V0QXJyYXlOYW1lIiwgImlzTmFOIiwgImVzY2FwZSIsICJnZXRQcm9taXNlVmFsdWUiLCAiQm9vbGVhbiIsICJXZWFrU2V0IiwgIldlYWtNYXAiLCAiRGF0YVZpZXciLCAiQXJyYXlCdWZmZXIiLCAiaW5zcGVjdEN1c3RvbSIsICJjb25maWciLCAiY29uZmlnIiwgImlzUHJpbWl0aXZlIiwgImNvbmZpZyIsICJjaGFpIiwgImNvbmZpZyIsICJjaGFpIiwgImNoYWkiLCAiY2hhaSIsICJjaGFpIiwgImNoYWkiLCAiYSIsICJpc05hTiIsICJnZXRPcGVyYXRvciIsICJpc09iamVjdCIsICJjb25maWciLCAidXRpbCIsICJBc3NlcnRpb25FcnJvciIsICJBc3NlcnRpb24iLCAiY2hhaSIsICJBc3NlcnRpb24iLCAiQXNzZXJ0aW9uRXJyb3IiLCAiYSIsICJtYXRjaElkeCIsICJjaGFpIiwgInV0aWwiLCAiY2hhaSIsICJ1dGlsIiwgIkFzc2VydGlvbiIsICJzaG91bGQiLCAiY2hhaSIsICJ1dGlsIiwgIkFzc2VydGlvbiIsICJhc3NlcnQiLCAidXRpbCIsICJjb25maWciLCAiY29yZSIsICJleHBlY3QiLCAic2hvdWxkIiwgImFzc2VydCIsICJyZXF1aXJlX2NoYWkiLCAic3ltYm9sIiwgImEiLCAiZG9jdW1lbnQiLCAid2luZG93IiwgImRvY3VtZW50IiwgImluaXRfbG9jYWxlIiwgIm5hdmlnYXRvciIsICJpbml0IiwgImEiLCAiaW5pdF9jb25zdGFudHMiLCAic3ltYm9sIiwgImluaXRfY29uc3RhbnRzIiwgImluaXRfbG9jYWxlIiwgImluaXRfY29uc3RhbnRzIiwgImNvbnNvbGUiLCAiY29uY2F0IiwgImluaXRfbG9jYWxlIiwgIkRFTElNSVRFUiIsICJzZWxmIiwgInNlbGYiLCAic2VsZiIsICJzZWxmIiwgImluaXRfY29uc3RhbnRzIiwgImEiLCAiaW50ZXJuYWwiLCAiYSIsICJkaWZmIiwgImRvY3VtZW50IiwgImRvY3VtZW50IiwgImluaXRfY29uc3RhbnRzIiwgImRvY3VtZW50IiwgIkhUTUxUZW1wbGF0ZUVsZW1lbnQiLCAiRG9jdW1lbnRGcmFnbWVudCIsICJEb2N1bWVudCIsICJpbml0X2NvbnN0YW50cyIsICJzZWxmIiwgInZhbHVlIiwgImUiLCAiaSIsICJzeW1ib2wiLCAiaW5pdF9jb25zdGFudHMiLCAic2VsZiIsICJjdXN0b21FbGVtZW50cyIsICJpbml0X2NvbnN0YW50cyIsICJzZWxmIiwgImluaXRfY29uc3RhbnRzIiwgImRvY3VtZW50IiwgIndpbmRvdyIsICJCdWZmZXJTb3VyY2VDb252ZXJ0ZXIiLCAiYSIsICJDb252ZXJ0IiwgImNvbWJpbmUiLCAicmV0QnVmIiwgInJldFZpZXciLCAiQm9vbGVhbiIsICJTZXQiLCAiX2EiLCAicmV0VmlldyIsICJ0ZW1wQnVmZmVyVmlldyIsICJBc25UeXBlVHlwZXMiLCAiQXNuUHJvcFR5cGVzIiwgImltcG9ydF9wdnRzdXRpbHMiLCAiQm9vbGVhbiIsICJfYSIsICJTZXQiLCAiZGVmYXVsdENvbnZlcnRlciIsICJfYSIsICJTZXQiLCAiU2V0IiwgImltcG9ydF9wdnRzdXRpbHMiLCAiaXNDb252ZXJ0aWJsZSIsICJzY2hlbWFTdG9yYWdlIiwgImluaXRfaW5kZXhfZXMiLCAiSnNvblByb3BUeXBlcyIsICJpbXBvcnRfcHZ0c3V0aWxzIiwgIk9iamVjdElkZW50aWZpZXIiLCAiaW5pdF9pbmRleF9lcyIsICJmb3JtYXQiLCAiRWNQdWJsaWNLZXkiLCAiRWRQcml2YXRlS2V5IiwgIkVkUHVibGljS2V5IiwgIkN1cnZlUHJpdmF0ZUtleSIsICJDcnlwdG8iLCAiYSIsICJwcm9jZXNzIiwgImltcG9ydF9wdnRzdXRpbHMiLCAiQ3J5cHRvS2V5IiwgIkFlc0NiY1Byb3ZpZGVyIiwgIkFlc0NtYWNQcm92aWRlciIsICJBZXNDdHJQcm92aWRlciIsICJBZXNHY21Qcm92aWRlciIsICJBZXNLd1Byb3ZpZGVyIiwgIkFlc0VjYlByb3ZpZGVyIiwgIlJzYVByaXZhdGVLZXkiLCAiUnNhUHVibGljS2V5IiwgIlJzYVNzYVByb3ZpZGVyIiwgIlJzYVBzc1Byb3ZpZGVyIiwgIlJzYU9hZXBQcm92aWRlciIsICJFY1ByaXZhdGVLZXkiLCAiRWNQdWJsaWNLZXkiLCAiRWNkc2FQcm92aWRlciIsICJFY2RoUHJvdmlkZXIiLCAiRWRQcml2YXRlS2V5IiwgIkVkUHVibGljS2V5IiwgIkVkRHNhUHJvdmlkZXIiLCAiRWNkaEVzUHJvdmlkZXIiLCAiUGJrZGYyUHJvdmlkZXIiLCAiSG1hY1Byb3ZpZGVyIiwgIkhrZGZQcm92aWRlciIsICJTaGFrZTEyOFByb3ZpZGVyIiwgIlNoYWtlMjU2UHJvdmlkZXIiLCAiU3VidGxlQ3J5cHRvIiwgImluaXRfaW5kZXhfZXMiLCAiY3J5cHRvX19kZWZhdWx0IiwgImZvcm1hdCIsICJfYSIsICJnbG9iYWxSZWZlcmVuY2UiLCAiaW50ZXJuYWxDb3VudGVyIiwgImNoYWkiLCAidmVyc2lvbiIsICJhIiwgIm1vbnN0ZXJWZXJzaW9uIiwgImEiLCAiY29uc29sZSIsICJhIiwgImhhbmRsZXIiLCAiYSIsICJpbml0X2NvbnN0YW50cyIsICJzZWxmIiwgImRvY3VtZW50IiwgImNoYWkiLCAid2luZG93IiwgImV4cGVjdCIsICJleHBlY3QiLCAiaW5pdF9jb25zdGFudHMiLCAiY3JlYXRlRWxlbWVudCIsICJhcHBlbmRUb0RvY3VtZW50IiwgInNlbGYiLCAiZG9jdW1lbnQiLCAiZXhwZWN0IiwgImZldGNoUmVmZXJlbmNlIiwgIm11dGF0aW9ub2JzZXJ2ZXIiLCAiYWRkZWROb2RlcyIsICJleHBlY3QiLCAiZSIsICJleHBlY3QiLCAiaW5pdF9jb25zdGFudHMiLCAiY3JlYXRlRWxlbWVudCIsICJzZWxmIiwgImRvY3VtZW50IiwgImV4cGVjdCIsICJleHBlY3QiLCAiZXhwZWN0IiwgInYiLCAiYSIsICJpbml0X2NvbnN0YW50cyIsICJleHBlY3QiLCAiaHRtbDEiLCAiQ3VzdG9tQ29udHJvbCIsICJyZWdpc3RlckN1c3RvbUVsZW1lbnQiLCAiZG9jdW1lbnQiLCAibSIsICJpbml0X2xvY2FsZSIsICJhIiwgIlJlc291cmNlIiwgInNlbGYiLCAicGFyc2VPcHRpb25zSlNPTiIsICJpbml0X2NvbnN0YW50cyIsICJzZWxmIiwgImZldGNoUmVmZXJlbmNlIiwgImEiLCAiaW5pdF9jb25zdGFudHMiLCAiZXhwZWN0IiwgImh0bWwxIiwgImh0bWwyIiwgIkN1c3RvbUVsZW1lbnQiLCAicmVnaXN0ZXJDdXN0b21FbGVtZW50IiwgImRvY3VtZW50IiwgImEiLCAidiIsICJodG1sMSIsICJodG1sMiIsICJodG1sMyIsICJzeW1ib2wiLCAiYSIsICJnbG9iYWwiLCAiYSIsICJpbml0X2NvbnN0YW50cyIsICJhIiwgIndpbmRvd1JlYWR5IiwgImRvbVJlYWR5IiwgIktFWV9ET0NVTUVOVCIsICJodG1sMSIsICJhIiwgIkZvcm1hdHRlciIsICJzZWxmIiwgIkZvcm1hdHRlciIsICJhIiwgImdsb2JhbCIsICJodG1sMSIsICJlIiwgImdsb2JhbCIsICJpbml0X2NvbnN0YW50cyIsICJodG1sMSIsICJ0cmFuc2xhdGlvbnNMaW5rU3ltYm9sIiwgInNlbGYiLCAiYSIsICJhIiwgIlJhbmRvbUlEIiwgIlVVSUQiLCAiYSIsICJhIiwgImEiLCAiYSIsICJhIiwgIk5vZGVMaXN0IiwgInNlbGYiLCAiTm9kZSIsICJOb2RlIiwgIk5vZGVMaXN0IiwgInNlbGYiLCAiTm9kZUxpc3QiLCAiTm9kZSIsICJhIiwgIk5vZGVMaXN0IiwgIk5vZGUiLCAiTm9kZUxpc3QiLCAiTm9kZSIsICJOb2RlIiwgIk5vZGVMaXN0IiwgImEiLCAiYSIsICJhIiwgImEiLCAic2VsZiIsICJhIiwgImEiLCAiYSIsICJpbml0IiwgInNlbGYiLCAiZGlmZiIsICJhIiwgImEiLCAiYSIsICJzZWxmIiwgImEiLCAiYSIsICJodG1sMSIsICJhIiwgImkiLCAiYSIsICJwYXJzZU9wdGlvbnNKU09OIiwgInNlbGYiLCAiTm9kZSIsICJOb2RlTGlzdCIsICJOb2RlTGlzdCIsICJhIiwgImEiLCAiYiIsICJjIiwgImh0bWwxIiwgImEiLCAiYSIsICJzZWxmIiwgInNlbGYiLCAic2VsZiIsICJzZWxmIiwgInNlbGYiLCAic2VsZiIsICJpbml0IiwgImZldGNoUmVmZXJlbmNlIiwgInJlc29sdmUiLCAicmVqZWN0IiwgIldlYkNvbm5lY3QiLCAic2VsZiIsICJ0ZXN0VXJsIiwgIldlYkNvbm5lY3QiLCAiY2xvbmUiLCAicmFuZG9tIiwgImEiXQp9Cg== diff --git a/devenv.lock b/devenv.lock index c15877f3e65c463ea428c5eb5c3b69dcab27a3eb..f77b45c23dda0642ae98df732e9fcb2405eb8f5e 100644 --- a/devenv.lock +++ b/devenv.lock @@ -1,13 +1,31 @@ { "nodes": { + "bob": { + "inputs": { + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1692013367, + "narHash": "sha256-zFzJkJo+uwByLnS7LXBui+XEgXHIUP3Ynl+VdSJLG04=", + "ref": "refs/heads/master", + "rev": "b22b32a61da4e73a5b4d7a26d9de3b7e89ad77fd", + "revCount": 83, + "type": "git", + "url": "https://gitlab.schukai.com/oss/bob.git" + }, + "original": { + "type": "git", + "url": "https://gitlab.schukai.com/oss/bob.git" + } + }, "devenv": { "locked": { "dir": "src/modules", - "lastModified": 1686642933, - "narHash": "sha256-5Z4uitx27QtZIrG9sOSJlZRNcVQn/TI36nj7o70n5Dw=", + "lastModified": 1698243190, + "narHash": "sha256-n+SbyNQRhUcaZoU00d+7wi17HJpw/kAUrXOL4zRcqE8=", "owner": "cachix", "repo": "devenv", - "rev": "f5278b5d56e39f86a299a2e1889906933a26f762", + "rev": "86f476f7edb86159fd20764489ab4e4df6edb4b6", "type": "github" }, "original": { @@ -74,18 +92,17 @@ }, "nixpkgs": { "locked": { - "lastModified": 1686582075, - "narHash": "sha256-vtflsfKkHtF8IduxDNtbme4cojiqvlvjp5QNYhvoHXc=", + "lastModified": 1698696950, + "narHash": "sha256-FHFL58t6lMumvWqwundC8fDDDLOIvc+JJBNIAlPjrDY=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "7e63eed145566cca98158613f3700515b4009ce3", + "rev": "017ef2132a5bda50bd713aeabce8f918502d4ec1", "type": "github" }, "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" + "id": "nixpkgs", + "ref": "nixos-23.05", + "type": "indirect" } }, "nixpkgs-stable": { @@ -104,6 +121,37 @@ "type": "github" } }, + "nixpkgs_2": { + "locked": { + "lastModified": 1698696950, + "narHash": "sha256-FHFL58t6lMumvWqwundC8fDDDLOIvc+JJBNIAlPjrDY=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "017ef2132a5bda50bd713aeabce8f918502d4ec1", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-23.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1698696950, + "narHash": "sha256-FHFL58t6lMumvWqwundC8fDDDLOIvc+JJBNIAlPjrDY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "017ef2132a5bda50bd713aeabce8f918502d4ec1", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixos-23.05", + "type": "indirect" + } + }, "pre-commit-hooks": { "inputs": { "flake-compat": "flake-compat", @@ -115,11 +163,11 @@ "nixpkgs-stable": "nixpkgs-stable" }, "locked": { - "lastModified": 1686668298, - "narHash": "sha256-AADh9NqHh6X2LOem4BvI7oCkMm+JPCSCE7iIw5nn0VA=", + "lastModified": 1698227354, + "narHash": "sha256-Fi5H9jbaQLmLw9qBi/mkR33CoFjNbobo5xWdX4tKz1Q=", "owner": "cachix", "repo": "pre-commit-hooks.nix", - "rev": "5b6b54d3f722aa95cbf4ddbe35390a0af8c0015a", + "rev": "bd38df3d508dfcdff52cd243d297f218ed2257bf", "type": "github" }, "original": { @@ -130,9 +178,11 @@ }, "root": { "inputs": { + "bob": "bob", "devenv": "devenv", - "nixpkgs": "nixpkgs", - "pre-commit-hooks": "pre-commit-hooks" + "nixpkgs": "nixpkgs_2", + "pre-commit-hooks": "pre-commit-hooks", + "version": "version" } }, "systems": { @@ -149,6 +199,24 @@ "repo": "default", "type": "github" } + }, + "version": { + "inputs": { + "nixpkgs": "nixpkgs_3" + }, + "locked": { + "lastModified": 1690668568, + "narHash": "sha256-jzixQKFFW4oxO0S4GYqbkFCXzhBd6com6Z9+MtVKakU=", + "ref": "refs/heads/master", + "rev": "3838f03165b726e47d586c04a1821749375e1001", + "revCount": 37, + "type": "git", + "url": "https://gitlab.schukai.com/oss/utilities/version.git" + }, + "original": { + "type": "git", + "url": "https://gitlab.schukai.com/oss/utilities/version.git" + } } }, "root": "root", diff --git a/devenv.nix b/devenv.nix index 5b2a5fca0d8bfb7b24854a4dbaf0c075a4a72b5e..ef24380727347c4eca40c8c01988d2438f015a0d 100644 --- a/devenv.nix +++ b/devenv.nix @@ -1,34 +1,621 @@ -{ pkgs, config, lib, ... }: +{ pkgs ? null, inputs ? null, phps ? null, lib ? null, config ? null +, modulesPath ? null, ... }: -{ - # https://devenv.sh/basics/ - #env.GREET = "devenv"; +let + currentSystem = if pkgs.stdenv.system != null then + pkgs.stdenv.system + else + builtins.currentSystem; + +in { + + env.APP_NAME = "monster"; + env.dddd= "@schukai/monster"; # https://devenv.sh/packages/ - packages = [ - pkgs.git - pkgs.gnumake - pkgs.emacsPackages.pnpm-mode - pkgs.nodejs_20 - ]; - - certificates = [ - "localhost.monsterjs.org" - ]; - - hosts = { - "localhost.monsterjs.org" = "127.0.0.1"; + packages = with pkgs; [ + + (inputs.bob.defaultPackage."${currentSystem}") + (inputs.version.defaultPackage."${currentSystem}") + + appimage-run + blackbox + coreutils-full + dbeaver + delve + fd + gawk + gcc12 + gdlv + git + glab + gnugrep + gnumake + gnused + go-task + gum + httpie + hurl + jq + libffi + logrotate + meld + memcached + netcat + nodePackages.pnpm + php82Extensions.xdebug + plantuml-c4 + procps + ranger + unzip + util-linux + zlib + ]; + + languages = { + go = { enable = true; }; + javascript = { + enable = true; + package = pkgs.nodejs_20; + corepack.enable = true; + }; }; - + + difftastic.enable = true; + + enterShell = '' +## check if node_modules exists +if [ ! -d node_modules ]; then + echo "node_modules does not exist. Installing dependencies." + ${pkgs.nodePackages.pnpm}/bin/pnpm install +fi + + +${pkgs.nodejs_20}/bin/node ${config.devenv.root}/node_modules/jsdoc-plantuml/fixBrokenNodeJS.js + + + +cat <<'EOF' > Taskfile.yml + +# THIS FILE IS AUTOGENERATED BY THE DEVENVSHELL +# DO NOT EDIT THIS FILE MANUALLY +# INSTEAD EDIT THE DEVENVSHELL CONFIGURATION FILE devenv.nix +# AND OPEN A SHELL WITH THE COMMAND devenv shell +# +# Information about the task runner can be found here: +# https://taskfile.dev + +version: '3' + +tasks: + default: + cmds: + - task --list + silent: true + + commit: + desc: Commit changes to the repository. + aliases: + - c + cmds: + - do-commit + + build-doc: + desc: Build the documentation to dist/doc + aliases: + - bd + cmds: + - build-doc + + run-tests: + desc: Run the tests + aliases: + - rt + cmds: + - run-tests + + run-web-tests: + desc: Run the tests + aliases: + - rt + cmds: + - run-web-tests +EOF + ''; + + scripts.build-changelog.exec = '' +${pkgs.git-chglog}/bin/git-chglog --config ${config.devenv.root}/.chglog/config.yml -o ${config.devenv.root}/CHANGELOG.md +''; + + + scripts.build-and-publish.exec = '' + +if [ -t 1 ]; then + RED='\033[0;31m' + GREEN='\033[0;32m' + RESET='\033[0m' + BOLD='\033[1m' +else + RED="" + GREEN="" + RESET="" +fi + +NEXTVERSION="$(${inputs.version.defaultPackage."${builtins.currentSystem}"}/bin/version predict --git -0)" + +if [[ "$NEXTVERSION" =~ "No notable changes found." ]]; then + echo -e "''${RED}✖ No notable changes found. Exiting.''${RESET}" + echo -e " Check this repository for changes. You must add a new commit with" + echo -e " feat: or fix: in the commit message to trigger a new version." + exit 1 +fi + + +update-versions +PROJECT_ROOT="${config.devenv.root}/" +TEST_PATH="${config.devenv.root}/test/" +BUILD_PATH="${config.devenv.root}/dist/" + +if [ -d "$BUILD_PATH" ]; then + rm -rf "$BUILD_PATH" +fi - languages.javascript = { - enable = true; - package = pkgs.nodejs_20; - corepack.enable = true; - - }; +mkdir -p "''${BUILD_PATH}" + +${pkgs.git-chglog}/bin/git-chglog --next-tag ''$NEXTVERSION --config "${config.devenv.root}/.chglog/config.yml" \ + -o "${config.devenv.root}/CHANGELOG.md" + + +${pkgs.rsync}/bin/rsync -a --exclude-from="${config.devenv.root}/.gitignore" "${config.devenv.root}/source" "''${BUILD_PATH}" +${pkgs.rsync}/bin/rsync -a --exclude-from="${config.devenv.root}/.gitignore" "${config.devenv.root}/test" "''${BUILD_PATH}" +${pkgs.rsync}/bin/rsync -a --exclude-from="${config.devenv.root}/.gitignore" "${config.devenv.root}/example" "''${BUILD_PATH}" + +cp ${config.devenv.root}/README.md "''${BUILD_PATH}" +cp ${config.devenv.root}/LICENSE "''${BUILD_PATH}" +cp ${config.devenv.root}/CHANGELOG.md "''${BUILD_PATH}" + + +jq 'del(.devDependencies)' ${config.devenv.root}/package.json > "''${BUILD_PATH}/package.json" + +#git add ''${APPLICATION_PATH}package.json +#git add ''${DEVELOPMENT_PATH}package.json +#git add ''${APPLICATION_PATH}source/types/version.mjs +#git add ''${TEST_PATH}cases/monster.mjs +#git add ''${PROJECT_ROOT}release.json +#git commit -m "release and publish to npm" + +#rm $BUILD_PATH/pnpm-lock.yaml + +cd ''${BUILD_PATH} + +OPTIONS="" +if [ ! -f "${config.devenv.root}/.npmrc" ]; then + echo -e "''${RED}✖ No npmrc file found. Exiting.''${RESET}" + echo -e " Create a file named .npmrc in the root of this repository with the following content:" + echo -e " //registry.npmjs.org/:_authToken=$NPM_TOKEN" + echo -e " You can find the token in the npm account settings." + echo -e "\n We run in dry-run mode now." + OPTIONS="--dry-run --no-git-checks" +fi + +pnpm publish $OPTIONS --dry-run --access public +cd - - # See full reference at https://devenv.sh/reference/options/ -} + + +''; + scripts.update-versions.exec = '' + +VERSION=$(cat "${config.devenv.root}/release.json" | jq -r '.version') + +sed -i -E "s_(\"[0-9]+\.[0-9]+\.[0-9]+\")_\"''${VERSION}\"_g" "${config.devenv.root}/source/types/version.mjs" +sed -i -E "s_(\"[0-9]+\.[0-9]+\.[0-9]+\")_\"''${VERSION}\"_g" "${config.devenv.root}/test/cases/monster.mjs" + +''; + scripts.create-polifill.exec = '' + +TMPFILE=${config.devenv.root}/.devenv/monster.js +touch $TMPFILE +##trap "rm -f $TMPFILE" 0 2 3 15 + +${config.devenv.root}/node_modules/.bin/esbuild --platform=browser --bundle ${config.devenv.root}/source/monster.mjs --outfile=''${TMPFILE} + +url="$(${pkgs.nodejs_20}/bin/npx create-polyfill-service-url analyse --file ".devenv/monster.js")" + + +if [ ! -x {$url} ] +then + sed -i -E "/id=\"polyfill\"/s|.*| <script id=\"polyfill\" src=\"''${url}\"|g" ${config.devenv.root}/test/web/test.html + sed -i -E "/id=\"polyfill\"/s|.*|<script id=\"polyfill\" src=\"''${url}\"|g" ${config.devenv.root}/README.md +fi + +''; + + scripts.run-tests.exec = '' +update-versions +${pkgs.nodePackages.pnpm}/bin/pnpm mocha --recursive test/cases/ + ''; + + scripts.build-monster-mjs.exec = '' +$(${pkgs.nodejs_20}/bin/node ${config.devenv.root}/opt/scripts/build-exports.cjs) +''; + + + scripts.run-web-tests.exec = '' +PROJECT_ROOT="${config.devenv.root}" +TEST_PATH="${config.devenv.root}/test/" +TEST_CASES_PATH="${config.devenv.root}/test/cases/" + +VERSION=$(cat "${config.devenv.root}/release.json" | jq -r '.version') + +update-versions +build-monster-mjs +create-polifill + + +find ''${TEST_CASES_PATH} -type f | sed "s|^$TEST_CASES_PATH||" > ''${TEST_PATH}web/import.js +sed -i 's|^|import "../cases/|' ''${TEST_PATH}web/import.js +sed -i 's|$|";|' ''${TEST_PATH}web/import.js +sed -i "1 i import \"./prepare.js\";" ''${TEST_PATH}web/import.js +sed -i "1 i /** this file was created automatically by the make target test-browser-monster */" ''${TEST_PATH}web/import.js + +npx esbuild --platform=browser --sourcemap=inline --external:ws --external:jsdom --external:process --external:crypto --bundle ''${TEST_PATH}web/import.js --outfile=''${TEST_PATH}web/tests.js + +sed -i -E "/<h1/s_.*_ <h1 style='margin-bottom: 0.1em;'>Monster ''${VERSION}</h1>_" ''${TEST_PATH}web/test.html +sed -i -E "/id=\"lastupdate\"/s_.*_ <div id=\"lastupdate\" style='font-size:0.7em'>last update $(date)</div>_" ''${TEST_PATH}web/test.html +sed -i -E "s_src=\"([\"]*)\.js.*\"_src=\"\1.js?r=$(date +"%T")\"_" ''${TEST_PATH}web/test.html + + +${pkgs.xdg-utils}/bin/xdg-open ''${TEST_PATH}web/test.html + + ''; + + + scripts.build-doc.exec = '' +rm -rf ${config.devenv.root}/dist/doc + +update-versions +create-polifill + +${config.devenv.root}/node_modules/.bin/jsdoc -c ${config.devenv.root}/doc/jsdoc.json +${pkgs.nodejs_20}/bin/node ${config.devenv.root}/opt/scripts/replace-skypack.cjs ${config.devenv.root} + +''; + + scripts.do-commit.exec = '' + #!/usr/bin/env bash + + # Define colors if the terminal supports it + if [ -t 1 ]; then + RED='\033[0;31m' + GREEN='\033[0;32m' + RESET='\033[0m' + BOLD='\033[1m' + else + RED="" + GREEN="" + RESET="" + fi + + step=1 + + reset + clear + + # create random log file + LOGFILE="$(mktemp)" + if [ $? -ne 0 ]; then + echo -e "''${RED}✖ Could not create temporary log file. Exiting.''${RESET}" + exit 1 + fi + + log_and_display() { + echo -e "''${GREEN}==> $step. $1''${RESET}" | tee -a $LOGFILE + step=$((step + 1)) + } + + log_error_and_display() { + echo -e "''${RED}==> $step. $1''${RESET}" | tee -a $LOGFILE + } + printLogfileAndExit() { + exit_code=$1 + echo -e "\n\n========================================\n\n\n" + + echo -e "\n\n''${BOLD}Git and GitLab Automation Script''${RESET}\n\nI have performed the following actions:\n\n" + cat "$LOGFILE" + + # Optional: Remove log file + rm -f "$LOGFILE" + + if [ $exit_code -eq 0 ]; then + echo -e "\n''${GREEN}✔''${RESET} All actions were successful" | tee -a $LOGFILE + elif [ $exit_code -eq -1 ]; then + echo -e "\n''${RED}✖''${RESET} The script was manually cancelled" | tee -a $LOGFILE + exit_code=0 + else + echo -e "\n''${RED}✖''${RESET} Some actions failed" | tee -a $LOGFILE + fi + + exit $exit_code + } + + print_headline() { + local title=$1 + local underline=$(printf '─%.0s' $(seq 1 ''${#title})) + echo -e "\n\n''${BOLD}''${title}\n''${underline}''${RESET}\n" + } + + do_cancel() { + echo -e "''${RED}==> ✖ Cancelled.''${RESET}" | tee -a $LOGFILE + printLogfileAndExit -1 + } + + # Function for unified logging and display + log_action() { + if [ $? -eq 0 ]; then + echo -e " ''${GREEN}✔''${RESET} $1: Successful" | tee -a $LOGFILE + else + echo -e " ''${RED}✖''${RESET} $1: Failed" | tee -a $LOGFILE + printLogfileAndExit 1 + fi + } + + print_what_to_do() { + echo -e "\n\nWhat do you want to do?\n" + } + + git_status=$(git status --porcelain) + if [[ -z "$git_status" ]]; then + log_error_and_display "No changes to commit. Exiting." + printLogfileAndExit 0 + fi + + print_headline "Choose commit type" + selection=$(gum choose "feat: (new feature for the user, not a new feature for build script)" "fix: (bug fix for the user, not a fix to a build script)" "chore: (updating grunt tasks etc.; no production code change)" "docs: (changes to the documentation)" "style: (formatting, missing semi colons, etc; no production code change)" "refactor: (refactoring production code, eg. renaming a variable)" "test: (adding missing tests, refactoring tests; no production code change)" "Cancel") + + commit_type=$(echo "$selection" | awk -F':' '{print $1}') + + if [[ "$commit_type" == "Cancel" ]]; then + do_cancel + fi + + log_and_display "You chose the commit type: $commit_type" + + # NEXT STEP ISSUE HANDLING ############################################################################################################ + #log_and_display "Issue handling" + + gitlabIssues=() + while IFS= read -r line; do + if [[ $line =~ ^# ]]; then + id=$(echo "$line" | awk '{print substr($1, 2)}') + title=$(echo "$line" | awk -F'about' '{print $1}' | awk '{$1=$2=""; print substr($0, 3)}') + gitlabIssues+=("$id > $title") + fi + done < <(gum spin --spinner dot --show-output --title "Ask gitlab ..." -- glab issue list --output-format=details) + + ## if issues are available, ask if user wants to use an existing issue or create a new one + createOption="Create new issue" + existingOption="Use existing issue" + cancelOption="Cancel" + + print_headline "Choose issue handling" + if [ ''${#gitlabIssues[@]} -eq 0 ]; then + log_and_display "There are no issues available." + + print_what_to_do + choice=$(gum choose "$createOption" "$cancelOption") + + else + log_and_display "There are ''${#gitlabIssues[@]} issues available." + print_what_to_do + choice=$(gum choose "$createOption" "$existingOption" "$cancelOption") + fi + + if [[ "$choice" == "$cancelOption" ]]; then + do_cancel + fi + + ## array of issue ids + work_on_issue_ids=() + + issue_text="" + + if [[ "$choice" == "$createOption" ]]; then + print_headline "Create new issue" + issue_text=$(gum input --placeholder "Enter issue title") + echo -e "Enter issue description. ''${RED}End with Ctrl+D''${RESET}\n" + issue_description=$(gum write --placeholder "Enter issue description. End with Ctrl+D") + + if [[ -z "$issue_text" ]]; then + log_error_and_display "Issue title is empty. Exiting." + printLogfileAndExit 1 + fi + + log_and_display "You entered the issue title: $issue_text" + log_and_display "You entered the issue description: $issue_description" + echo -e "\n" + + gum confirm "Do you want to create this issue?" + # gum confirm exits with status 0 if confirmed and status 1 if cancelled. + if [ $? -eq 1 ]; then + do_cancel + fi + + issue_output=$(glab issue create -t"$issue_text" --no-editor --description "$issue_description") + issue_id=$(echo "$issue_output" | grep -oP '(?<=/issues/)\d+') + + work_on_issue_ids+=("$issue_id") + + log_action "glab issue with id $issue_id created" + + else + + print_headline "Use existing issue" + echo -e "Select issue with arrow keys and press tab or space to select. Press enter to confirm.\n" + issue_ids=$(gum choose --no-limit "''${gitlabIssues[@]}") + + # assign issue_ids to work_on_issue_ids. iterate over lines and take integer from beginning of line + while IFS= read -r line; do + work_on_issue_ids+=($(echo "$line" | grep -oP '^\d+')) + done <<<"$issue_ids" + + fi + + if [ ''${#work_on_issue_ids[@]} -eq 0 ]; then + log_and_display "No issue selected. Exiting." + printLogfileAndExit 0 + fi + + # NEXT STEP COMMIT MESSAGE ############################################################################################################ + # print work_on_issue_ids + work_on_issue_ids_string="" + for i in "''${work_on_issue_ids[@]}"; do + work_on_issue_ids_string+="#$i " + done + + log_and_display "You chose to work on the following issues: ''${work_on_issue_ids_string}" + + + print_headline "Check for changes to commit" + + # ' ' = unmodified + # M = modified + # T = file type changed (regular file, symbolic link or submodule) + # A = added + # D = deleted + # R = renamed + # C = copied (if config option status.renames is set to "copies") + # U = updated but unmerged + # https://man.freebsd.org/cgi/man.cgi?query=git-status&sektion=1&manpath=freebsd-release-ports + + count_all_changes=$(echo "$git_status" | wc -l) + count_staged_changes=$(echo "$git_status" | grep -c '^M') + count_new_staged_files=$(echo "$git_status" | grep -c '^A') + count_staged_changes=$((count_staged_changes + count_new_staged_files)) + + + + git_options_all="All $count_all_changes changes" + git_options_staged="Only the $count_staged_changes staged changes" + git_options_select_files="Select files" + git_options_cancel="Cancel" + + git_options_array=() + if [[ $count_all_changes -gt 0 ]]; then + git_options_array+=("$git_options_all") + fi + + if [[ $count_staged_changes -gt 0 ]]; then + git_options_array+=("$git_options_staged") + fi + + git_options_array+=( "$git_options_select_files" ) + git_options_array+=( "$git_options_cancel" ) + + + selection=$(gum choose "''${git_options_array[@]}") + if [[ "$selection" == "$git_options_cancel" ]]; then + do_cancel + fi + + if [[ "$selection" == "$git_options_all" ]]; then + git add -A + echo "1" + elif [[ "$selection" == "$git_options_select_files" ]]; then + + files=() + while IFS= read -r line; do + files+=("$line") + done <<<"$git_status" + + selected_files=$(gum choose --no-limit "''${files[@]}") + + # no files selected + if [[ -z "$selected_files" ]]; then + log_and_display "No files selected. Exiting." + printLogfileAndExit 0 + fi + + # add selected files + while IFS= read -r line; do + ## git proclimne could have letter, ? or ! at the beginning of the line + file=$(echo "$line" | awk '{print $2}') + if [[ -z "$file" || ! -f "$file" ]]; then + log_and_display "No file found in line: $line" + continue + fi + + git add "$file" + done <<<"$selected_files" + + fi + + ## count staged changes again and print + count_staged_changes=$(echo "$git_status" | grep -c '^M') + count_new_staged_files=$(echo "$git_status" | grep -c '^A') + count_staged_changes=$((count_staged_changes + count_new_staged_files)) + + log_and_display "You have $count_staged_changes staged changes to commit." + + # NEXT STEP COMMIT MESSAGE ############################################################################################################ + + print_headline "Enter commit message" + commit_message=$(gum input --placeholder "Enter commit message" --value "$commit_type: $issue_text $work_on_issue_ids_string") + + if [[ -z "$commit_message" ]]; then + log_error_and_display "Commit message is empty. Exiting." + printLogfileAndExit 1 + fi + + log_and_display "You entered the commit message: $commit_message" + + gum confirm "Do you want to commit with this message?" + if [ $? -eq 1 ]; then + do_cancel + fi + + # NEXT STEP COMMIT #################################################################################################################### + print_headline "Committing changes" + + if ! git commit -m "$commit_message" ; then + log_error_and_display "Commit failed. Exiting." + printLogfileAndExit 1 + fi + + log_and_display "Commit successful." + + # NEXT STEP PUSH ###################################################################################################################### + + print_headline "Pushing changes" + + if ! git push ; then + log_error_and_display "Push failed. Exiting." + printLogfileAndExit 1 + fi + + log_and_display "Push successful." + + # Close issue ###################################################################################################################### + + print_headline "Closing issues" + + for issue_id in "''${work_on_issue_ids[@]}"; do + + gum confirm "Do you want to close issue #$issue_id?" + if [ $? -eq 1 ]; then + continue + fi + + if ! glab issue close "$issue_id" ; then + log_error_and_display "Closing issue $issue_id failed. Exiting." + else + log_and_display "Closing issue $issue_id successful." + fi + done + + printLogfileAndExit 0 + ''; + +} diff --git a/devenv.yaml b/devenv.yaml index c7cb5cedadc04e17a1703f298db573f43c79cad8..06892bf3911f33dcfd88fa06e59cd527e6c8fb62 100644 --- a/devenv.yaml +++ b/devenv.yaml @@ -1,3 +1,14 @@ inputs: nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable + url: github:nixos/nixpkgs/nixos-23.05 + + version: + url: git+https://gitlab.schukai.com/oss/utilities/version.git + flake: true + + bob: + url: git+https://gitlab.schukai.com/oss/bob.git + flake: true + + + \ No newline at end of file diff --git a/documentation/README.md b/doc/README.md similarity index 100% rename from documentation/README.md rename to doc/README.md diff --git a/documentation/asset/favicon/android-chrome-192x192.png b/doc/asset/favicon/android-chrome-192x192.png similarity index 100% rename from documentation/asset/favicon/android-chrome-192x192.png rename to doc/asset/favicon/android-chrome-192x192.png diff --git a/documentation/asset/favicon/apple-touch-icon-120x120-precomposed.png b/doc/asset/favicon/apple-touch-icon-120x120-precomposed.png similarity index 100% rename from documentation/asset/favicon/apple-touch-icon-120x120-precomposed.png rename to doc/asset/favicon/apple-touch-icon-120x120-precomposed.png diff --git a/documentation/asset/favicon/apple-touch-icon-120x120.png b/doc/asset/favicon/apple-touch-icon-120x120.png similarity index 100% rename from documentation/asset/favicon/apple-touch-icon-120x120.png rename to doc/asset/favicon/apple-touch-icon-120x120.png diff --git a/documentation/asset/favicon/apple-touch-icon-152x152-precomposed.png b/doc/asset/favicon/apple-touch-icon-152x152-precomposed.png similarity index 100% rename from documentation/asset/favicon/apple-touch-icon-152x152-precomposed.png rename to doc/asset/favicon/apple-touch-icon-152x152-precomposed.png diff --git a/documentation/asset/favicon/apple-touch-icon-152x152.png b/doc/asset/favicon/apple-touch-icon-152x152.png similarity index 100% rename from documentation/asset/favicon/apple-touch-icon-152x152.png rename to doc/asset/favicon/apple-touch-icon-152x152.png diff --git a/documentation/asset/favicon/apple-touch-icon-180x180-precomposed.png b/doc/asset/favicon/apple-touch-icon-180x180-precomposed.png similarity index 100% rename from documentation/asset/favicon/apple-touch-icon-180x180-precomposed.png rename to doc/asset/favicon/apple-touch-icon-180x180-precomposed.png diff --git a/documentation/asset/favicon/apple-touch-icon-180x180.png b/doc/asset/favicon/apple-touch-icon-180x180.png similarity index 100% rename from documentation/asset/favicon/apple-touch-icon-180x180.png rename to doc/asset/favicon/apple-touch-icon-180x180.png diff --git a/documentation/asset/favicon/apple-touch-icon-60x60-precomposed.png b/doc/asset/favicon/apple-touch-icon-60x60-precomposed.png similarity index 100% rename from documentation/asset/favicon/apple-touch-icon-60x60-precomposed.png rename to doc/asset/favicon/apple-touch-icon-60x60-precomposed.png diff --git a/documentation/asset/favicon/apple-touch-icon-60x60.png b/doc/asset/favicon/apple-touch-icon-60x60.png similarity index 100% rename from documentation/asset/favicon/apple-touch-icon-60x60.png rename to doc/asset/favicon/apple-touch-icon-60x60.png diff --git a/documentation/asset/favicon/apple-touch-icon-76x76-precomposed.png b/doc/asset/favicon/apple-touch-icon-76x76-precomposed.png similarity index 100% rename from documentation/asset/favicon/apple-touch-icon-76x76-precomposed.png rename to doc/asset/favicon/apple-touch-icon-76x76-precomposed.png diff --git a/documentation/asset/favicon/apple-touch-icon-76x76.png b/doc/asset/favicon/apple-touch-icon-76x76.png similarity index 100% rename from documentation/asset/favicon/apple-touch-icon-76x76.png rename to doc/asset/favicon/apple-touch-icon-76x76.png diff --git a/documentation/asset/favicon/apple-touch-icon-precomposed.png b/doc/asset/favicon/apple-touch-icon-precomposed.png similarity index 100% rename from documentation/asset/favicon/apple-touch-icon-precomposed.png rename to doc/asset/favicon/apple-touch-icon-precomposed.png diff --git a/documentation/asset/favicon/apple-touch-icon.png b/doc/asset/favicon/apple-touch-icon.png similarity index 100% rename from documentation/asset/favicon/apple-touch-icon.png rename to doc/asset/favicon/apple-touch-icon.png diff --git a/documentation/asset/favicon/favicon-16x16.png b/doc/asset/favicon/favicon-16x16.png similarity index 100% rename from documentation/asset/favicon/favicon-16x16.png rename to doc/asset/favicon/favicon-16x16.png diff --git a/documentation/asset/favicon/favicon-32x32.png b/doc/asset/favicon/favicon-32x32.png similarity index 100% rename from documentation/asset/favicon/favicon-32x32.png rename to doc/asset/favicon/favicon-32x32.png diff --git a/documentation/asset/favicon/favicon.ico b/doc/asset/favicon/favicon.ico similarity index 100% rename from documentation/asset/favicon/favicon.ico rename to doc/asset/favicon/favicon.ico diff --git a/documentation/asset/favicon/monster.png b/doc/asset/favicon/monster.png similarity index 100% rename from documentation/asset/favicon/monster.png rename to doc/asset/favicon/monster.png diff --git a/documentation/asset/favicon/mstile-150x150.png b/doc/asset/favicon/mstile-150x150.png similarity index 100% rename from documentation/asset/favicon/mstile-150x150.png rename to doc/asset/favicon/mstile-150x150.png diff --git a/documentation/config/jsdoc.json b/doc/jsdoc.json similarity index 88% rename from documentation/config/jsdoc.json rename to doc/jsdoc.json index f104724bf410f58002b9f1baa98b2552a334d834..40c1ad7557f2d28965255f31a956aa23e2dd6f4c 100644 --- a/documentation/config/jsdoc.json +++ b/doc/jsdoc.json @@ -3,7 +3,7 @@ "allowUnknownTags": true }, "source": { - "include": "../application/source/", + "include": "source/", "includePattern": ".+\\.(js(doc|x)?|mjs)$", "excludePattern": "(node_modules|test)" }, @@ -15,9 +15,10 @@ ], "sourceType": "module", "opts": { - "template": "node_modules/clean-jsdoc-theme", + "template": "../node_modules/clean-jsdoc-theme", "encoding": "utf8", - "destination": "../deployment/build/docs/", + "destination": "dist/doc/", + "readme": "doc/README.md", "recurse": true, "verbose": false, "theme_opts": { @@ -25,6 +26,9 @@ "default_theme": "dark", "title": "Monster ", "favicon": "https://monsterjs.org/favicon.ico", + "include_css": [ + "doc/styles/layout.css" + ], "menu" : [ { "title": "Home", @@ -67,7 +71,6 @@ } }, "sections": [ - "Tutorials", "Modules", "Classes", "Externals", @@ -93,11 +96,11 @@ "plantuml": { "puml": { "create": true, - "destination": "../deployment/build/docs/puml" + "destination": "dist/doc/puml" }, "images": { "create": true, - "destination": "../deployment/build/docs/images", + "destination": "dist/doc/images", "defaultFormat": "svg" } } diff --git a/doc/scripts/core.js b/doc/scripts/core.js new file mode 100644 index 0000000000000000000000000000000000000000..003340296e5126563e9262428b92aaffbbc899c0 --- /dev/null +++ b/doc/scripts/core.js @@ -0,0 +1,675 @@ +/* global document */ +var accordionLocalStorageKey = 'accordion-id'; +var themeLocalStorageKey = 'theme'; +var fontSizeLocalStorageKey = 'font-size'; +var html = document.querySelector('html'); + +var MAX_FONT_SIZE = 30; +var MIN_FONT_SIZE = 10; + +// eslint-disable-next-line no-undef +var localStorage = window.localStorage; + +function getTheme() { + var body = document.body; + + return body.getAttribute('data-theme'); +} + +function localUpdateTheme(theme) { + var body = document.body; + var svgUse = document.querySelectorAll('.theme-svg-use'); + var iconID = theme === 'dark' ? '#light-theme-icon' : '#dark-theme-icon'; + + body.setAttribute('data-theme', theme); + body.classList.remove('dark', 'light'); + body.classList.add(theme); + + svgUse.forEach(function (svg) { + svg.setAttribute('xlink:href', iconID); + }); +} + +function updateTheme(theme) { + localUpdateTheme(theme); + localStorage.setItem(themeLocalStorageKey, theme); +} + +function toggleTheme() { + var body = document.body; + var theme = body.getAttribute('data-theme'); + + var newTheme = theme === 'dark' ? 'light' : 'dark'; + + updateTheme(newTheme); +} + +(function () { + var theme = getTheme(); + + var themeStoredInLocalStorage = localStorage.getItem(themeLocalStorageKey); + + if (themeStoredInLocalStorage) { + if (theme === themeStoredInLocalStorage) { + return; + } + + updateTheme(themeStoredInLocalStorage); + } else { + localStorage.setItem(themeLocalStorageKey, theme); + } +})(); + +/** + * Function to set accordion id to localStorage. + * @param {string} id Accordion id + */ +function setAccordionIdToLocalStorage(id) { + /** + * @type {object} + */ + var ids = JSON.parse(localStorage.getItem(accordionLocalStorageKey)); + + ids[id] = id; + localStorage.setItem(accordionLocalStorageKey, JSON.stringify(ids)); +} + +/** + * Function to remove accordion id from localStorage. + * @param {string} id Accordion id + */ +function removeAccordionIdFromLocalStorage(id) { + /** + * @type {object} + */ + var ids = JSON.parse(localStorage.getItem(accordionLocalStorageKey)); + + delete ids[id]; + localStorage.setItem(accordionLocalStorageKey, JSON.stringify(ids)); +} + +/** + * Function to get all accordion ids from localStorage. + * + * @returns {object} + */ +function getAccordionIdsFromLocalStorage() { + /** + * @type {object} + */ + var ids = JSON.parse(localStorage.getItem(accordionLocalStorageKey)); + + return ids || {}; +} + +function toggleAccordion(element) { + var currentNode = element; + var isCollapsed = currentNode.getAttribute('data-isopen') === 'false'; + + if (isCollapsed) { + currentNode.setAttribute('data-isopen', 'true'); + setAccordionIdToLocalStorage(currentNode.id); + } else { + currentNode.setAttribute('data-isopen', 'false'); + removeAccordionIdFromLocalStorage(currentNode.id); + } +} + +function initAccordion() { + if ( + localStorage.getItem(accordionLocalStorageKey) === undefined || + localStorage.getItem(accordionLocalStorageKey) === null + ) { + localStorage.setItem(accordionLocalStorageKey, '{}'); + } + var allAccordion = document.querySelectorAll('.sidebar-section-title'); + var ids = getAccordionIdsFromLocalStorage(); + + allAccordion.forEach(function (item) { + item.addEventListener('click', function () { + toggleAccordion(item); + }); + if (item.id in ids) { + toggleAccordion(item); + } + }); +} + +function isSourcePage() { + return Boolean(document.querySelector('#source-page')); +} + +function bringElementIntoView(element, updateHistory = true) { + // If element is null then we are not going further + if (!element) { + return; + } + + /** + * tocbotInstance is defined in layout.tmpl + * It is defined when we are initializing tocbot. + * + */ + // eslint-disable-next-line no-undef + if (tocbotInstance) { + // eslint-disable-next-line no-undef + setTimeout(() => tocbotInstance.updateTocListActiveElement(element), 60) + } + var navbar = document.querySelector('.navbar-container'); + var body = document.querySelector('.main-content'); + var elementTop = element.getBoundingClientRect().top; + + var offset = 16; + + if (navbar) { + offset += navbar.scrollHeight; + } + + if (body) { + body.scrollBy(0, elementTop - offset); + } + + if (updateHistory) { + // eslint-disable-next-line no-undef + history.pushState(null, null, '#' + element.id); + } +} + +// eslint-disable-next-line no-unused-vars +function bringLinkToView(event) { + event.preventDefault(); + event.stopPropagation(); + var id = event.currentTarget.getAttribute('href'); + + if (!id) { + return; + } + + var element = document.getElementById(id.slice(1)); + + if (element) { + bringElementIntoView(element); + } +} + +function bringIdToViewOnMount() { + if (isSourcePage()) { + return; + } + + // eslint-disable-next-line no-undef + var id = window.location.hash; + + if (id === '') { + return; + } + + var element = document.getElementById(id.slice(1)); + + if (!element) { + id = decodeURI(id); + element = document.getElementById(id.slice(1)); + } + + if (element) { + bringElementIntoView(element, false); + } +} + +function createAnchorElement(id) { + var anchor = document.createElement('a'); + + anchor.textContent = '#'; + anchor.href = '#' + id; + anchor.classList.add('link-anchor'); + anchor.onclick = bringLinkToView; + + return anchor; +} + +function addAnchor() { + var main = document.querySelector('.main-content').querySelector('section'); + + var h1 = main.querySelectorAll('h1'); + var h2 = main.querySelectorAll('h2'); + var h3 = main.querySelectorAll('h3'); + var h4 = main.querySelectorAll('h4'); + + var targets = [h1, h2, h3, h4]; + + targets.forEach(function (target) { + target.forEach(function (heading) { + var anchor = createAnchorElement(heading.id); + + heading.classList.add('has-anchor'); + heading.append(anchor); + }); + }); +} + +/** + * + * @param {string} value + */ +function copy(value) { + console.log(value); + const el = document.createElement('textarea'); + + el.value = value; + document.body.appendChild(el); + el.select(); + document.execCommand('copy'); + document.body.removeChild(el); +} + +function showTooltip(id) { + var tooltip = document.getElementById(id); + + tooltip.classList.add('show-tooltip'); + setTimeout(function () { + tooltip.classList.remove('show-tooltip'); + }, 3000); +} + +/* eslint-disable-next-line */ +function copyFunction(id) { + // selecting the pre element + var code = document.getElementById(id); + + // selecting the ol.linenums + var element = code.querySelector('.linenums'); + + if (!element) { + // selecting the code block + element = code.querySelector('code'); + } + + // copy + copy(element.innerText.trim().replace(/(^\t)/gm, '')); + + // show tooltip + showTooltip('tooltip-' + id); +} + +function hideTocOnSourcePage() { + if (isSourcePage()) { + document.querySelector('.toc-container').style.display = 'none'; + } +} + +function getPreTopBar(id, lang = '') { + // tooltip + var tooltip = '<div class="tooltip" id="tooltip-' + id + '">Copied!</div>'; + + // template of copy to clipboard icon container + var copyToClipboard = + '<button aria-label="copy code" class="icon-button copy-code" onclick="copyFunction(\'' + + id + + '\')"><svg class="sm-icon" alt="click to copy"><use xlink:href="#copy-icon"></use></svg>' + + tooltip + + '</button>'; + + var langNameDiv = + '<div class="code-lang-name-container"><div class="code-lang-name">' + + lang.toLocaleUpperCase() + + '</div></div>'; + + var topBar = + '<div class="pre-top-bar-container">' + + langNameDiv + + copyToClipboard + + '</div>'; + + return topBar; +} + +function getPreDiv() { + var divElement = document.createElement('div'); + + divElement.classList.add('pre-div'); + + return divElement; +} + +function processAllPre() { + var targets = document.querySelectorAll('pre'); + var footer = document.querySelector('#PeOAagUepe'); + var navbar = document.querySelector('#VuAckcnZhf'); + + var navbarHeight = 0; + var footerHeight = 0; + + if (footer) { + footerHeight = footer.getBoundingClientRect().height; + } + + if (navbar) { + navbarHeight = navbar.getBoundingClientRect().height; + } + + // eslint-disable-next-line no-undef + var preMaxHeight = window.innerHeight - navbarHeight - footerHeight - 250; + + targets.forEach(function (pre, idx) { + var parent = pre.parentNode; + + if (parent && parent.getAttribute('data-skip-pre-process') === 'true') { + return; + } + + var div = getPreDiv(); + var id = 'ScDloZOMdL' + idx; + + var lang = pre.getAttribute('data-lang') || 'code'; + var topBar = getPreTopBar(id, lang); + + div.innerHTML = topBar; + + pre.style.maxHeight = preMaxHeight + 'px'; + pre.id = id; + pre.classList.add('prettyprint'); + pre.parentNode.insertBefore(div, pre); + div.appendChild(pre); + }); +} + +function highlightAndBringLineIntoView() { + // eslint-disable-next-line no-undef + var lineNumber = window.location.hash.replace('#line', ''); + + try { + var selector = '[data-line-number="' + lineNumber + '"'; + + var element = document.querySelector(selector); + + element.scrollIntoView(); + element.parentNode.classList.add('selected'); + } catch (error) { + console.error(error); + } +} + +function getFontSize() { + var currentFontSize = 16; + + try { + currentFontSize = Number.parseInt( + html.style.fontSize.split('px')[0], + 10 + ); + } catch (error) { + console.log(error); + } + + return currentFontSize; +} + +function localUpdateFontSize(fontSize) { + html.style.fontSize = fontSize + 'px'; + + var fontSizeText = document.querySelector( + '#b77a68a492f343baabea06fad81f651e' + ); + + if (fontSizeText) { + fontSizeText.innerHTML = fontSize; + } +} + +function updateFontSize(fontSize) { + localUpdateFontSize(fontSize); + localStorage.setItem(fontSizeLocalStorageKey, fontSize); +} + +(function () { + var fontSize = getFontSize(); + var fontSizeInLocalStorage = localStorage.getItem(fontSizeLocalStorageKey); + + if (fontSizeInLocalStorage) { + var n = Number.parseInt(fontSizeInLocalStorage, 10); + + if (n === fontSize) { + return; + } + updateFontSize(n); + } else { + updateFontSize(fontSize); + } +})(); + +// eslint-disable-next-line no-unused-vars +function incrementFont(event) { + var n = getFontSize(); + + if (n < MAX_FONT_SIZE) { + updateFontSize(n + 1); + } +} + +// eslint-disable-next-line no-unused-vars +function decrementFont(event) { + var n = getFontSize(); + + if (n > MIN_FONT_SIZE) { + updateFontSize(n - 1); + } +} + +function fontSizeTooltip() { + var fontSize = getFontSize(); + + return ` + <div class="font-size-tooltip"> + <button aria-label="decrease-font-size" class="icon-button ${fontSize >= MAX_FONT_SIZE ? 'disabled' : '' + }" onclick="decrementFont(event)"> + <svg> + <use xlink:href="#minus-icon"></use> + </svg> + </button> + <div class="font-size-text" id="b77a68a492f343baabea06fad81f651e"> + ${fontSize} + </div> + <button aria-label="increase-font-size" class="icon-button ${fontSize <= MIN_FONT_SIZE ? 'disabled' : '' + }" onclick="incrementFont(event)"> + <svg> + <use xlink:href="#add-icon"></use> + </svg> + </button> + <button class="icon-button" onclick="updateFontSize(16)"> + <svg> + <use xlink:href="#reset-icon"></use> + </svg> + </button> + </div> + + `; +} + +function initTooltip() { + // add tooltip to navbar item + // eslint-disable-next-line no-undef + tippy('.theme-toggle', { + content: 'Toggle Theme', + delay: 500 + }); + + // eslint-disable-next-line no-undef + tippy('.search-button', { + content: 'Search', + delay: 500 + }); + + // eslint-disable-next-line no-undef + tippy('.font-size', { + content: 'Change font size', + delay: 500 + }); + + // eslint-disable-next-line no-undef + tippy('.codepen-button', { + content: 'Open code in CodePen', + placement: 'left' + }); + + // eslint-disable-next-line no-undef + tippy('.copy-code', { + content: 'Copy this code', + placement: 'left' + }); + + // eslint-disable-next-line no-undef + tippy('.font-size', { + content: fontSizeTooltip(), + trigger: 'click', + interactive: true, + allowHTML: true, + placement: 'left' + }); +} + +function fixTable() { + const tables = document.querySelectorAll('table'); + + for (const table of tables) { + if (table.classList.contains('hljs-ln')) { + // don't want to wrap code blocks. + return; + } + + var div = document.createElement('div'); + + div.classList.add('table-div'); + table.parentNode.insertBefore(div, table); + div.appendChild(table); + } +} + +function hideMobileMenu() { + var mobileMenuContainer = document.querySelector('#mobile-sidebar'); + var target = document.querySelector('#mobile-menu'); + var svgUse = target.querySelector('use'); + + if (mobileMenuContainer) { + mobileMenuContainer.classList.remove('show'); + } + if (target) { + target.setAttribute('data-isopen', 'false'); + } + if (svgUse) { + svgUse.setAttribute('xlink:href', '#menu-icon'); + } +} + +function showMobileMenu() { + var mobileMenuContainer = document.querySelector('#mobile-sidebar'); + var target = document.querySelector('#mobile-menu'); + var svgUse = target.querySelector('use'); + + if (mobileMenuContainer) { + mobileMenuContainer.classList.add('show'); + } + if (target) { + target.setAttribute('data-isopen', 'true'); + } + if (svgUse) { + svgUse.setAttribute('xlink:href', '#close-icon'); + } +} + +function onMobileMenuClick() { + var target = document.querySelector('#mobile-menu'); + var isOpen = target.getAttribute('data-isopen') === 'true'; + + if (isOpen) { + hideMobileMenu(); + } else { + showMobileMenu(); + } +} + +function initMobileMenu() { + var menu = document.querySelector('#mobile-menu'); + + if (menu) { + menu.addEventListener('click', onMobileMenuClick); + } +} + +function addHrefToSidebarTitle() { + var titles = document.querySelectorAll('.sidebar-title-anchor'); + + titles.forEach(function (title) { + // eslint-disable-next-line no-undef + title.setAttribute('href', baseURL); + }); +} + +function onDomContentLoaded() { + var themeButton = document.querySelectorAll('.theme-toggle'); + + initMobileMenu(); + + if (themeButton) { + themeButton.forEach(function (button) { + button.addEventListener('click', toggleTheme); + }); + } + + // Highlighting code + + // eslint-disable-next-line no-undef + hljs.addPlugin({ + 'after:highlightElement': function (obj) { + // Replace 'code' with result.language when + // we are able to cross-check the correctness of + // result. + obj.el.parentNode.setAttribute('data-lang', 'code'); + } + }); + // eslint-disable-next-line no-undef + hljs.highlightAll(); + // eslint-disable-next-line no-undef + hljs.initLineNumbersOnLoad({ + singleLine: true + }); + + // Highlight complete + + initAccordion(); + addAnchor(); + processAllPre(); + hideTocOnSourcePage(); + setTimeout(function () { + bringIdToViewOnMount(); + if (isSourcePage()) { + highlightAndBringLineIntoView(); + } + }, 1000); + initTooltip(); + fixTable(); + addHrefToSidebarTitle(); +} + +// eslint-disable-next-line no-undef +window.addEventListener('DOMContentLoaded', onDomContentLoaded); + +// eslint-disable-next-line no-undef +window.addEventListener('hashchange', (event) => { + const url = new URL(event.newURL); + + if (url.hash !== '') { + bringIdToViewOnMount(url.hash); + } +}); + +// eslint-disable-next-line no-undef +window.addEventListener('storage', event => { + if (event.newValue === 'undefined') return; + + initTooltip(); + + if (event.key === themeLocalStorageKey) + localUpdateTheme(event.newValue); + if (event.key === fontSizeLocalStorageKey) + localUpdateFontSize(event.newValue); +}); diff --git a/doc/scripts/core.min.js b/doc/scripts/core.min.js new file mode 100644 index 0000000000000000000000000000000000000000..8f65ec77937abd2442d6e4918eceef0b4f522f63 --- /dev/null +++ b/doc/scripts/core.min.js @@ -0,0 +1,23 @@ +var accordionLocalStorageKey="accordion-id",themeLocalStorageKey="theme",fontSizeLocalStorageKey="font-size",html=document.querySelector("html"),MAX_FONT_SIZE=30,MIN_FONT_SIZE=10,localStorage=window.localStorage;function getTheme(){return document.body.getAttribute("data-theme")}function localUpdateTheme(e){var t=document.body,o=document.querySelectorAll(".theme-svg-use"),n="dark"===e?"#light-theme-icon":"#dark-theme-icon";t.setAttribute("data-theme",e),t.classList.remove("dark","light"),t.classList.add(e),o.forEach(function(e){e.setAttribute("xlink:href",n)})}function updateTheme(e){localUpdateTheme(e),localStorage.setItem(themeLocalStorageKey,e)}function toggleTheme(){updateTheme("dark"===document.body.getAttribute("data-theme")?"light":"dark")}function setAccordionIdToLocalStorage(e){var t=JSON.parse(localStorage.getItem(accordionLocalStorageKey));t[e]=e,localStorage.setItem(accordionLocalStorageKey,JSON.stringify(t))}function removeAccordionIdFromLocalStorage(e){var t=JSON.parse(localStorage.getItem(accordionLocalStorageKey));delete t[e],localStorage.setItem(accordionLocalStorageKey,JSON.stringify(t))}function getAccordionIdsFromLocalStorage(){return JSON.parse(localStorage.getItem(accordionLocalStorageKey))||{}}function toggleAccordion(e){"false"===e.getAttribute("data-isopen")?(e.setAttribute("data-isopen","true"),setAccordionIdToLocalStorage(e.id)):(e.setAttribute("data-isopen","false"),removeAccordionIdFromLocalStorage(e.id))}function initAccordion(){void 0!==localStorage.getItem(accordionLocalStorageKey)&&null!==localStorage.getItem(accordionLocalStorageKey)||localStorage.setItem(accordionLocalStorageKey,"{}");var e=document.querySelectorAll(".sidebar-section-title"),t=getAccordionIdsFromLocalStorage();e.forEach(function(e){e.addEventListener("click",function(){toggleAccordion(e)}),e.id in t&&toggleAccordion(e)})}function isSourcePage(){return Boolean(document.querySelector("#source-page"))}function bringElementIntoView(e,t=!0){var o,n,i,c;e&&(tocbotInstance&&setTimeout(()=>tocbotInstance.updateTocListActiveElement(e),60),o=document.querySelector(".navbar-container"),n=document.querySelector(".main-content"),i=e.getBoundingClientRect().top,c=16,o&&(c+=o.scrollHeight),n&&n.scrollBy(0,i-c),t&&history.pushState(null,null,"#"+e.id))}function bringLinkToView(e){e.preventDefault(),e.stopPropagation();var e=e.currentTarget.getAttribute("href");!e||(e=document.getElementById(e.slice(1)))&&bringElementIntoView(e)}function bringIdToViewOnMount(){var e,t;isSourcePage()||""!==(e=window.location.hash)&&((t=document.getElementById(e.slice(1)))||(e=decodeURI(e),t=document.getElementById(e.slice(1))),t&&bringElementIntoView(t,!1))}function createAnchorElement(e){var t=document.createElement("a");return t.textContent="#",t.href="#"+e,t.classList.add("link-anchor"),t.onclick=bringLinkToView,t}function addAnchor(){var e=document.querySelector(".main-content").querySelector("section");[e.querySelectorAll("h1"),e.querySelectorAll("h2"),e.querySelectorAll("h3"),e.querySelectorAll("h4")].forEach(function(e){e.forEach(function(e){var t=createAnchorElement(e.id);e.classList.add("has-anchor"),e.append(t)})})}function copy(e){console.log(e);const t=document.createElement("textarea");t.value=e,document.body.appendChild(t),t.select(),document.execCommand("copy"),document.body.removeChild(t)}function showTooltip(e){var t=document.getElementById(e);t.classList.add("show-tooltip"),setTimeout(function(){t.classList.remove("show-tooltip")},3e3)}function copyFunction(e){var t=document.getElementById(e);copy((t.querySelector(".linenums")||t.querySelector("code")).innerText.trim().replace(/(^\t)/gm,"")),showTooltip("tooltip-"+e)}function hideTocOnSourcePage(){isSourcePage()&&(document.querySelector(".toc-container").style.display="none")}function getPreTopBar(e,t=""){e='<button aria-label="copy code" class="icon-button copy-code" onclick="copyFunction(\''+e+'\')"><svg class="sm-icon" alt="click to copy"><use xlink:href="#copy-icon"></use></svg>'+('<div class="tooltip" id="tooltip-'+e+'">Copied!</div>')+"</button>";return'<div class="pre-top-bar-container">'+('<div class="code-lang-name-container"><div class="code-lang-name">'+t.toLocaleUpperCase()+"</div></div>")+e+"</div>"}function getPreDiv(){var e=document.createElement("div");return e.classList.add("pre-div"),e}function processAllPre(){var e=document.querySelectorAll("pre"),t=document.querySelector("#PeOAagUepe"),o=document.querySelector("#VuAckcnZhf"),n=0,i=0,c=(t&&(i=t.getBoundingClientRect().height),o&&(n=o.getBoundingClientRect().height),window.innerHeight-n-i-250);e.forEach(function(e,t){var o,n=e.parentNode;n&&"true"===n.getAttribute("data-skip-pre-process")||(n=getPreDiv(),o=getPreTopBar(t="ScDloZOMdL"+t,e.getAttribute("data-lang")||"code"),n.innerHTML=o,e.style.maxHeight=c+"px",e.id=t,e.classList.add("prettyprint"),e.parentNode.insertBefore(n,e),n.appendChild(e))})}function highlightAndBringLineIntoView(){var e=window.location.hash.replace("#line","");try{var t='[data-line-number="'+e+'"',o=document.querySelector(t);o.scrollIntoView(),o.parentNode.classList.add("selected")}catch(e){console.error(e)}}function getFontSize(){var e=16;try{e=Number.parseInt(html.style.fontSize.split("px")[0],10)}catch(e){console.log(e)}return e}function localUpdateFontSize(e){html.style.fontSize=e+"px";var t=document.querySelector("#b77a68a492f343baabea06fad81f651e");t&&(t.innerHTML=e)}function updateFontSize(e){localUpdateFontSize(e),localStorage.setItem(fontSizeLocalStorageKey,e)}function incrementFont(e){var t=getFontSize();t<MAX_FONT_SIZE&&updateFontSize(t+1)}function decrementFont(e){var t=getFontSize();MIN_FONT_SIZE<t&&updateFontSize(t-1)}function fontSizeTooltip(){var e=getFontSize();return` + <div class="font-size-tooltip"> + <button aria-label="decrease-font-size" class="icon-button ${MAX_FONT_SIZE<=e?"disabled":""}" onclick="decrementFont(event)"> + <svg> + <use xlink:href="#minus-icon"></use> + </svg> + </button> + <div class="font-size-text" id="b77a68a492f343baabea06fad81f651e"> + ${e} + </div> + <button aria-label="increase-font-size" class="icon-button ${e<=MIN_FONT_SIZE?"disabled":""}" onclick="incrementFont(event)"> + <svg> + <use xlink:href="#add-icon"></use> + </svg> + </button> + <button class="icon-button" onclick="updateFontSize(16)"> + <svg> + <use xlink:href="#reset-icon"></use> + </svg> + </button> + </div> + + `}function initTooltip(){tippy(".theme-toggle",{content:"Toggle Theme",delay:500}),tippy(".search-button",{content:"Search",delay:500}),tippy(".font-size",{content:"Change font size",delay:500}),tippy(".codepen-button",{content:"Open code in CodePen",placement:"left"}),tippy(".copy-code",{content:"Copy this code",placement:"left"}),tippy(".font-size",{content:fontSizeTooltip(),trigger:"click",interactive:!0,allowHTML:!0,placement:"left"})}function fixTable(){for(const t of document.querySelectorAll("table")){if(t.classList.contains("hljs-ln"))return;var e=document.createElement("div");e.classList.add("table-div"),t.parentNode.insertBefore(e,t),e.appendChild(t)}}function hideMobileMenu(){var e=document.querySelector("#mobile-sidebar"),t=document.querySelector("#mobile-menu"),o=t.querySelector("use");e&&e.classList.remove("show"),t&&t.setAttribute("data-isopen","false"),o&&o.setAttribute("xlink:href","#menu-icon")}function showMobileMenu(){var e=document.querySelector("#mobile-sidebar"),t=document.querySelector("#mobile-menu"),o=t.querySelector("use");e&&e.classList.add("show"),t&&t.setAttribute("data-isopen","true"),o&&o.setAttribute("xlink:href","#close-icon")}function onMobileMenuClick(){("true"===document.querySelector("#mobile-menu").getAttribute("data-isopen")?hideMobileMenu:showMobileMenu)()}function initMobileMenu(){var e=document.querySelector("#mobile-menu");e&&e.addEventListener("click",onMobileMenuClick)}function addHrefToSidebarTitle(){document.querySelectorAll(".sidebar-title-anchor").forEach(function(e){e.setAttribute("href",baseURL)})}function onDomContentLoaded(){var e=document.querySelectorAll(".theme-toggle");initMobileMenu(),e&&e.forEach(function(e){e.addEventListener("click",toggleTheme)}),hljs.addPlugin({"after:highlightElement":function(e){e.el.parentNode.setAttribute("data-lang","code")}}),hljs.highlightAll(),hljs.initLineNumbersOnLoad({singleLine:!0}),initAccordion(),addAnchor(),processAllPre(),hideTocOnSourcePage(),setTimeout(function(){bringIdToViewOnMount(),isSourcePage()&&highlightAndBringLineIntoView()},1e3),initTooltip(),fixTable(),addHrefToSidebarTitle()}!function(){var e=getTheme(),t=localStorage.getItem(themeLocalStorageKey);t?e!==t&&updateTheme(t):localStorage.setItem(themeLocalStorageKey,e)}(),function(){var e=getFontSize(),t=localStorage.getItem(fontSizeLocalStorageKey);t?(t=Number.parseInt(t,10))!==e&&updateFontSize(t):updateFontSize(e)}(),window.addEventListener("DOMContentLoaded",onDomContentLoaded),window.addEventListener("hashchange",e=>{e=new URL(e.newURL);""!==e.hash&&bringIdToViewOnMount(e.hash)}),window.addEventListener("storage",e=>{"undefined"!==e.newValue&&(initTooltip(),e.key===themeLocalStorageKey&&localUpdateTheme(e.newValue),e.key===fontSizeLocalStorageKey&&localUpdateFontSize(e.newValue))}); \ No newline at end of file diff --git a/doc/scripts/resize.js b/doc/scripts/resize.js new file mode 100644 index 0000000000000000000000000000000000000000..d8e3a9cf7bf0a9917705c15eed2c0b36ca7e579d --- /dev/null +++ b/doc/scripts/resize.js @@ -0,0 +1,90 @@ +/* global document */ +// This file is @deprecated + +var NAVBAR_OPTIONS = {}; + +(function() { + var NAVBAR_RESIZE_LOCAL_STORAGE_KEY = 'NAVBAR_RESIZE_LOCAL_STORAGE_KEY'; + + var navbar = document.querySelector('#navbar'); + var footer = document.querySelector('#footer'); + var mainSection = document.querySelector('#main'); + var localStorageResizeObject = JSON.parse( + // eslint-disable-next-line no-undef + localStorage.getItem(NAVBAR_RESIZE_LOCAL_STORAGE_KEY) + ); + + /** + * Check whether we have any resize value in local storage or not. + * If we have resize value then resize the navbar. + **/ + if (localStorageResizeObject) { + navbar.style.width = localStorageResizeObject.width; + mainSection.style.marginLeft = localStorageResizeObject.width; + footer.style.marginLeft = localStorageResizeObject.width; + } + + var navbarSlider = document.querySelector('#navbar-resize'); + + function resizeNavbar(event) { + var pageX = event.pageX, + pageXPlusPx = event.pageX + 'px', + min = Number.parseInt(NAVBAR_OPTIONS.min, 10) || 300, + max = Number.parseInt(NAVBAR_OPTIONS.max, 10) || 600; + + /** + * Just to add some checks. If min is smaller than 10 then + * user may accidentally end up reducing the size of navbar + * less than 10. In that case user will not able to resize navbar + * because navbar slider will be hidden. + */ + if (min < 10) { + min = 10; + } + + /** + * Only resize if pageX in range between min and max + * allowed value. + */ + if (min < pageX && pageX < max) { + navbar.style.width = pageXPlusPx; + mainSection.style.marginLeft = pageXPlusPx; + footer.style.marginLeft = pageXPlusPx; + } + } + + function setupEventListeners() { + // eslint-disable-next-line no-undef + window.addEventListener('mousemove', resizeNavbar); + // eslint-disable-next-line no-undef + window.addEventListener('touchmove', resizeNavbar); + } + + function afterRemovingEventListeners() { + // eslint-disable-next-line no-undef + localStorage.setItem( + NAVBAR_RESIZE_LOCAL_STORAGE_KEY, + JSON.stringify({ + width: navbar.style.width + }) + ); + } + + function removeEventListeners() { + // eslint-disable-next-line no-undef + window.removeEventListener('mousemove', resizeNavbar); + // eslint-disable-next-line no-undef + window.removeEventListener('touchend', resizeNavbar); + afterRemovingEventListeners(); + } + + navbarSlider.addEventListener('mousedown', setupEventListeners); + navbarSlider.addEventListener('touchstart', setupEventListeners); + // eslint-disable-next-line no-undef + window.addEventListener('mouseup', removeEventListeners); +})(); + +// eslint-disable-next-line no-unused-vars +function setupResizeOptions(options) { + NAVBAR_OPTIONS = options; +} diff --git a/doc/scripts/search.js b/doc/scripts/search.js new file mode 100644 index 0000000000000000000000000000000000000000..415e1cf8d1bda278aa7134688e313a60254ed24c --- /dev/null +++ b/doc/scripts/search.js @@ -0,0 +1,265 @@ +/* global document */ + +const searchId = 'LiBfqbJVcV'; +const searchHash = '#' + searchId; +const searchContainer = document.querySelector('#PkfLWpAbet'); +const searchWrapper = document.querySelector('#iCxFxjkHbP'); +const searchCloseButton = document.querySelector('#VjLlGakifb'); +const searchInput = document.querySelector('#vpcKVYIppa'); +const resultBox = document.querySelector('#fWwVHRuDuN'); + +function showResultText(text) { + resultBox.innerHTML = `<span class="search-result-c-text">${text}</span>`; +} + +function hideSearch() { + // eslint-disable-next-line no-undef + if (window.location.hash === searchHash) { + // eslint-disable-next-line no-undef + history.go(-1); + } + + // eslint-disable-next-line no-undef + window.onhashchange = null; + + if (searchContainer) { + searchContainer.style.display = 'none'; + } +} + +function listenCloseKey(event) { + if (event.key === 'Escape') { + hideSearch(); + // eslint-disable-next-line no-undef + window.removeEventListener('keyup', listenCloseKey); + } +} + +function showSearch() { + try { + // Closing mobile menu before opening + // search box. + // It is defined in core.js + // eslint-disable-next-line no-undef + hideMobileMenu(); + } catch (error) { + console.error(error); + } + + // eslint-disable-next-line no-undef + window.onhashchange = hideSearch; + + // eslint-disable-next-line no-undef + if (window.location.hash !== searchHash) { + // eslint-disable-next-line no-undef + history.pushState(null, null, searchHash); + } + + if (searchContainer) { + searchContainer.style.display = 'flex'; + // eslint-disable-next-line no-undef + window.addEventListener('keyup', listenCloseKey); + } + + if (searchInput) { + searchInput.focus(); + } +} + +async function fetchAllData() { + // eslint-disable-next-line no-undef + const { hostname, protocol, port } = location; + + // eslint-disable-next-line no-undef + const base = protocol + '//' + hostname + (port !== '' ? ':' + port : '') + baseURL; + // eslint-disable-next-line no-undef + const url = new URL('data/search.json', base); + const result = await fetch(url); + const { list } = await result.json(); + + return list; +} + +// eslint-disable-next-line no-unused-vars +function onClickSearchItem(event) { + const target = event.currentTarget; + + if (target) { + const href = target.getAttribute('href') || ''; + let elementId = href.split('#')[1] || ''; + let element = document.getElementById(elementId); + + if (!element) { + elementId = decodeURI(elementId); + element = document.getElementById(elementId); + } + + if (element) { + setTimeout(function() { + // eslint-disable-next-line no-undef + bringElementIntoView(element); // defined in core.js + }, 100); + } + } +} + +function buildSearchResult(result) { + let output = ''; + const removeHTMLTagsRegExp = /(<([^>]+)>)/ig; + + for (const res of result) { + const { title = '', description = '' } = res.item; + + const _link = res.item.link.replace('<a href="', '').replace(/">.*/, ''); + const _title = title.replace(removeHTMLTagsRegExp, ""); + const _description = description.replace(removeHTMLTagsRegExp, ""); + + output += ` + <a onclick="onClickSearchItem(event)" href="${_link}" class="search-result-item"> + <div class="search-result-item-title">${_title}</div> + <div class="search-result-item-p">${_description || 'No description available.'}</div> + </a> + `; + } + + return output; +} + +function getSearchResult(list, keys, searchKey) { + const defaultOptions = { + shouldSort: true, + threshold: 0.4, + location: 0, + distance: 100, + maxPatternLength: 32, + minMatchCharLength: 1, + keys: keys + }; + + const options = { ...defaultOptions }; + + // eslint-disable-next-line no-undef + const searchIndex = Fuse.createIndex(options.keys, list); + + // eslint-disable-next-line no-undef + const fuse = new Fuse(list, options, searchIndex); + + const result = fuse.search(searchKey); + + if (result.length > 20) { + return result.slice(0, 20); + } + + return result; +} + +function debounce(func, wait, immediate) { + let timeout; + + return function() { + const args = arguments; + + clearTimeout(timeout); + timeout = setTimeout(() => { + timeout = null; + if (!immediate) { + // eslint-disable-next-line consistent-this, no-invalid-this + func.apply(this, args); + } + }, wait); + + if (immediate && !timeout) { + // eslint-disable-next-line consistent-this, no-invalid-this + func.apply(this, args); + } + }; +} + +let searchData; + +async function search(event) { + const value = event.target.value; + const keys = ['title', 'description']; + + if (!resultBox) { + console.error('Search result container not found'); + + return; + } + + if (!value) { + showResultText('Type anything to view search result'); + + return; + } + + if (!searchData) { + showResultText('Loading...'); + + try { + // eslint-disable-next-line require-atomic-updates + searchData = await fetchAllData(); + } catch (e) { + console.log(e); + showResultText('Failed to load result.'); + + return; + } + } + + const result = getSearchResult(searchData, keys, value); + + if (!result.length) { + showResultText('No result found! Try some different combination.'); + + return; + } + + // eslint-disable-next-line require-atomic-updates + resultBox.innerHTML = buildSearchResult(result); +} + +function onDomContentLoaded() { + const searchButton = document.querySelectorAll('.search-button'); + const debouncedSearch = debounce(search, 300); + + if (searchCloseButton) { + searchCloseButton.addEventListener('click', hideSearch); + } + + if (searchButton) { + searchButton.forEach(function(item) { + item.addEventListener('click', showSearch); + }); + } + + if (searchContainer) { + searchContainer.addEventListener('click', hideSearch); + } + + if (searchWrapper) { + searchWrapper.addEventListener('click', function(event) { + event.stopPropagation(); + }); + } + + if (searchInput) { + searchInput.addEventListener('keyup', debouncedSearch); + } + + // eslint-disable-next-line no-undef + if (window.location.hash === searchHash) { + showSearch(); + } +} + +// eslint-disable-next-line no-undef +window.addEventListener('DOMContentLoaded', onDomContentLoaded); + +// eslint-disable-next-line no-undef +window.addEventListener('hashchange', function() { + // eslint-disable-next-line no-undef + if (window.location.hash === searchHash) { + showSearch(); + } +}); diff --git a/doc/scripts/search.min.js b/doc/scripts/search.min.js new file mode 100644 index 0000000000000000000000000000000000000000..5358bced859085861bdd58c5a2afcef667822f24 --- /dev/null +++ b/doc/scripts/search.min.js @@ -0,0 +1,6 @@ +const searchId="LiBfqbJVcV",searchHash="#"+searchId,searchContainer=document.querySelector("#PkfLWpAbet"),searchWrapper=document.querySelector("#iCxFxjkHbP"),searchCloseButton=document.querySelector("#VjLlGakifb"),searchInput=document.querySelector("#vpcKVYIppa"),resultBox=document.querySelector("#fWwVHRuDuN");function showResultText(e){resultBox.innerHTML=`<span class="search-result-c-text">${e}</span>`}function hideSearch(){window.location.hash===searchHash&&history.go(-1),window.onhashchange=null,searchContainer&&(searchContainer.style.display="none")}function listenCloseKey(e){"Escape"===e.key&&(hideSearch(),window.removeEventListener("keyup",listenCloseKey))}function showSearch(){try{hideMobileMenu()}catch(e){console.error(e)}window.onhashchange=hideSearch,window.location.hash!==searchHash&&history.pushState(null,null,searchHash),searchContainer&&(searchContainer.style.display="flex",window.addEventListener("keyup",listenCloseKey)),searchInput&&searchInput.focus()}async function fetchAllData(){var{hostname:e,protocol:t,port:n}=location,t=t+"//"+e+(""!==n?":"+n:"")+baseURL,e=new URL("data/search.json",t);const a=await fetch(e);n=(await a.json()).list;return n}function onClickSearchItem(t){const n=t.currentTarget;if(n){const a=n.getAttribute("href")||"";t=a.split("#")[1]||"";let e=document.getElementById(t);e||(t=decodeURI(t),e=document.getElementById(t)),e&&setTimeout(function(){bringElementIntoView(e)},100)}}function buildSearchResult(e){let t="";var n=/(<([^>]+)>)/gi;for(const s of e){const{title:c="",description:i=""}=s.item;var a=s.item.link.replace('<a href="',"").replace(/">.*/,""),o=c.replace(n,""),r=i.replace(n,"");t+=` + <a onclick="onClickSearchItem(event)" href="${a}" class="search-result-item"> + <div class="search-result-item-title">${o}</div> + <div class="search-result-item-p">${r||"No description available."}</div> + </a> + `}return t}function getSearchResult(e,t,n){var t={...{shouldSort:!0,threshold:.4,location:0,distance:100,maxPatternLength:32,minMatchCharLength:1,keys:t}},a=Fuse.createIndex(t.keys,e);const o=new Fuse(e,t,a),r=o.search(n);return 20<r.length?r.slice(0,20):r}function debounce(t,n,a){let o;return function(){const e=arguments;clearTimeout(o),o=setTimeout(()=>{o=null,a||t.apply(this,e)},n),a&&!o&&t.apply(this,e)}}let searchData;async function search(e){e=e.target.value;if(resultBox)if(e){if(!searchData){showResultText("Loading...");try{searchData=await fetchAllData()}catch(e){return console.log(e),void showResultText("Failed to load result.")}}e=getSearchResult(searchData,["title","description"],e);e.length?resultBox.innerHTML=buildSearchResult(e):showResultText("No result found! Try some different combination.")}else showResultText("Type anything to view search result");else console.error("Search result container not found")}function onDomContentLoaded(){const e=document.querySelectorAll(".search-button");var t=debounce(search,300);searchCloseButton&&searchCloseButton.addEventListener("click",hideSearch),e&&e.forEach(function(e){e.addEventListener("click",showSearch)}),searchContainer&&searchContainer.addEventListener("click",hideSearch),searchWrapper&&searchWrapper.addEventListener("click",function(e){e.stopPropagation()}),searchInput&&searchInput.addEventListener("keyup",t),window.location.hash===searchHash&&showSearch()}window.addEventListener("DOMContentLoaded",onDomContentLoaded),window.addEventListener("hashchange",function(){window.location.hash===searchHash&&showSearch()}); \ No newline at end of file diff --git a/doc/scripts/third-party/Apache-License-2.0.txt b/doc/scripts/third-party/Apache-License-2.0.txt new file mode 100644 index 0000000000000000000000000000000000000000..75b52484ea471f882c29e02693b4f02dba175b5e --- /dev/null +++ b/doc/scripts/third-party/Apache-License-2.0.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/doc/scripts/third-party/fuse.js b/doc/scripts/third-party/fuse.js new file mode 100644 index 0000000000000000000000000000000000000000..a55c5daa07e6b127a837e6990a6f89e6c6650059 --- /dev/null +++ b/doc/scripts/third-party/fuse.js @@ -0,0 +1,9 @@ +/** + * Fuse.js v6.4.6 - Lightweight fuzzy-search (http://fusejs.io) + * + * Copyright (c) 2021 Kiro Risk (http://kiro.me) + * All Rights Reserved. Apache Software License 2.0 + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ +var e,t;e=this,t=function(){"use strict";function e(t){return(e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(t)}function t(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function n(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function r(e,t,r){return t&&n(e.prototype,t),r&&n(e,r),e}function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function c(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){i(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&u(e,t)}function s(e){return(s=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function u(e,t){return(u=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function h(e,t){return!t||"object"!=typeof t&&"function"!=typeof t?function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e):t}function f(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,r=s(e);if(t){var i=s(this).constructor;n=Reflect.construct(r,arguments,i)}else n=r.apply(this,arguments);return h(this,n)}}function l(e){return function(e){if(Array.isArray(e))return d(e)}(e)||function(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}(e)||function(e,t){if(e){if("string"==typeof e)return d(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?d(e,t):void 0}}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function d(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function v(e){return Array.isArray?Array.isArray(e):"[object Array]"===b(e)}function g(e){return"string"==typeof e}function y(e){return"number"==typeof e}function p(e){return!0===e||!1===e||function(e){return m(e)&&null!==e}(e)&&"[object Boolean]"==b(e)}function m(t){return"object"===e(t)}function k(e){return null!=e}function M(e){return!e.trim().length}function b(e){return null==e?void 0===e?"[object Undefined]":"[object Null]":Object.prototype.toString.call(e)}var x=function(e){return"Invalid value for key ".concat(e)},L=function(e){return"Pattern length exceeds max of ".concat(e,".")},S=Object.prototype.hasOwnProperty,w=function(){function e(n){var r=this;t(this,e),this._keys=[],this._keyMap={};var i=0;n.forEach((function(e){var t=_(e);i+=t.weight,r._keys.push(t),r._keyMap[t.id]=t,i+=t.weight})),this._keys.forEach((function(e){e.weight/=i}))}return r(e,[{key:"get",value:function(e){return this._keyMap[e]}},{key:"keys",value:function(){return this._keys}},{key:"toJSON",value:function(){return JSON.stringify(this._keys)}}]),e}();function _(e){var t=null,n=null,r=null,i=1;if(g(e)||v(e))r=e,t=O(e),n=j(e);else{if(!S.call(e,"name"))throw new Error(function(e){return"Missing ".concat(e," property in key")}("name"));var o=e.name;if(r=o,S.call(e,"weight")&&(i=e.weight)<=0)throw new Error(function(e){return"Property 'weight' in key '".concat(e,"' must be a positive integer")}(o));t=O(o),n=j(o)}return{path:t,id:n,weight:i,src:r}}function O(e){return v(e)?e:e.split(".")}function j(e){return v(e)?e.join("."):e}var A=c({},{isCaseSensitive:!1,includeScore:!1,keys:[],shouldSort:!0,sortFn:function(e,t){return e.score===t.score?e.idx<t.idx?-1:1:e.score<t.score?-1:1}},{},{includeMatches:!1,findAllMatches:!1,minMatchCharLength:1},{},{location:0,threshold:.6,distance:100},{},{useExtendedSearch:!1,getFn:function(e,t){var n=[],r=!1;return function e(t,i,o){if(k(t))if(i[o]){var c=t[i[o]];if(!k(c))return;if(o===i.length-1&&(g(c)||y(c)||p(c)))n.push(function(e){return null==e?"":function(e){if("string"==typeof e)return e;var t=e+"";return"0"==t&&1/e==-1/0?"-0":t}(e)}(c));else if(v(c)){r=!0;for(var a=0,s=c.length;a<s;a+=1)e(c[a],i,o+1)}else i.length&&e(c,i,o+1)}else n.push(t)}(e,g(t)?t.split("."):t,0),r?n:n[0]},ignoreLocation:!1,ignoreFieldNorm:!1}),I=/[^ ]+/g;function C(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:3,t=new Map,n=Math.pow(10,e);return{get:function(e){var r=e.match(I).length;if(t.has(r))return t.get(r);var i=1/Math.sqrt(r),o=parseFloat(Math.round(i*n)/n);return t.set(r,o),o},clear:function(){t.clear()}}}var E=function(){function e(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=n.getFn,i=void 0===r?A.getFn:r;t(this,e),this.norm=C(3),this.getFn=i,this.isCreated=!1,this.setIndexRecords()}return r(e,[{key:"setSources",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.docs=e}},{key:"setIndexRecords",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.records=e}},{key:"setKeys",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.keys=t,this._keysMap={},t.forEach((function(t,n){e._keysMap[t.id]=n}))}},{key:"create",value:function(){var e=this;!this.isCreated&&this.docs.length&&(this.isCreated=!0,g(this.docs[0])?this.docs.forEach((function(t,n){e._addString(t,n)})):this.docs.forEach((function(t,n){e._addObject(t,n)})),this.norm.clear())}},{key:"add",value:function(e){var t=this.size();g(e)?this._addString(e,t):this._addObject(e,t)}},{key:"removeAt",value:function(e){this.records.splice(e,1);for(var t=e,n=this.size();t<n;t+=1)this.records[t].i-=1}},{key:"getValueForItemAtKeyId",value:function(e,t){return e[this._keysMap[t]]}},{key:"size",value:function(){return this.records.length}},{key:"_addString",value:function(e,t){if(k(e)&&!M(e)){var n={v:e,i:t,n:this.norm.get(e)};this.records.push(n)}}},{key:"_addObject",value:function(e,t){var n=this,r={i:t,$:{}};this.keys.forEach((function(t,i){var o=n.getFn(e,t.path);if(k(o))if(v(o))!function(){for(var e=[],t=[{nestedArrIndex:-1,value:o}];t.length;){var c=t.pop(),a=c.nestedArrIndex,s=c.value;if(k(s))if(g(s)&&!M(s)){var u={v:s,i:a,n:n.norm.get(s)};e.push(u)}else v(s)&&s.forEach((function(e,n){t.push({nestedArrIndex:n,value:e})}))}r.$[i]=e}();else if(!M(o)){var c={v:o,n:n.norm.get(o)};r.$[i]=c}})),this.records.push(r)}},{key:"toJSON",value:function(){return{keys:this.keys,records:this.records}}}]),e}();function $(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=n.getFn,i=void 0===r?A.getFn:r,o=new E({getFn:i});return o.setKeys(e.map(_)),o.setSources(t),o.create(),o}function R(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.errors,r=void 0===n?0:n,i=t.currentLocation,o=void 0===i?0:i,c=t.expectedLocation,a=void 0===c?0:c,s=t.distance,u=void 0===s?A.distance:s,h=t.ignoreLocation,f=void 0===h?A.ignoreLocation:h,l=r/e.length;if(f)return l;var d=Math.abs(a-o);return u?l+d/u:d?1:l}function F(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:A.minMatchCharLength,n=[],r=-1,i=-1,o=0,c=e.length;o<c;o+=1){var a=e[o];a&&-1===r?r=o:a||-1===r||((i=o-1)-r+1>=t&&n.push([r,i]),r=-1)}return e[o-1]&&o-r>=t&&n.push([r,o-1]),n}function P(e){for(var t={},n=0,r=e.length;n<r;n+=1){var i=e.charAt(n);t[i]=(t[i]||0)|1<<r-n-1}return t}var N=function(){function e(n){var r=this,i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},o=i.location,c=void 0===o?A.location:o,a=i.threshold,s=void 0===a?A.threshold:a,u=i.distance,h=void 0===u?A.distance:u,f=i.includeMatches,l=void 0===f?A.includeMatches:f,d=i.findAllMatches,v=void 0===d?A.findAllMatches:d,g=i.minMatchCharLength,y=void 0===g?A.minMatchCharLength:g,p=i.isCaseSensitive,m=void 0===p?A.isCaseSensitive:p,k=i.ignoreLocation,M=void 0===k?A.ignoreLocation:k;if(t(this,e),this.options={location:c,threshold:s,distance:h,includeMatches:l,findAllMatches:v,minMatchCharLength:y,isCaseSensitive:m,ignoreLocation:M},this.pattern=m?n:n.toLowerCase(),this.chunks=[],this.pattern.length){var b=function(e,t){r.chunks.push({pattern:e,alphabet:P(e),startIndex:t})},x=this.pattern.length;if(x>32){for(var L=0,S=x%32,w=x-S;L<w;)b(this.pattern.substr(L,32),L),L+=32;if(S){var _=x-32;b(this.pattern.substr(_),_)}}else b(this.pattern,0)}}return r(e,[{key:"searchIn",value:function(e){var t=this.options,n=t.isCaseSensitive,r=t.includeMatches;if(n||(e=e.toLowerCase()),this.pattern===e){var i={isMatch:!0,score:0};return r&&(i.indices=[[0,e.length-1]]),i}var o=this.options,c=o.location,a=o.distance,s=o.threshold,u=o.findAllMatches,h=o.minMatchCharLength,f=o.ignoreLocation,d=[],v=0,g=!1;this.chunks.forEach((function(t){var n=t.pattern,i=t.alphabet,o=t.startIndex,y=function(e,t,n){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},i=r.location,o=void 0===i?A.location:i,c=r.distance,a=void 0===c?A.distance:c,s=r.threshold,u=void 0===s?A.threshold:s,h=r.findAllMatches,f=void 0===h?A.findAllMatches:h,l=r.minMatchCharLength,d=void 0===l?A.minMatchCharLength:l,v=r.includeMatches,g=void 0===v?A.includeMatches:v,y=r.ignoreLocation,p=void 0===y?A.ignoreLocation:y;if(t.length>32)throw new Error(L(32));for(var m,k=t.length,M=e.length,b=Math.max(0,Math.min(o,M)),x=u,S=b,w=d>1||g,_=w?Array(M):[];(m=e.indexOf(t,S))>-1;){var O=R(t,{currentLocation:m,expectedLocation:b,distance:a,ignoreLocation:p});if(x=Math.min(O,x),S=m+k,w)for(var j=0;j<k;)_[m+j]=1,j+=1}S=-1;for(var I=[],C=1,E=k+M,$=1<<k-1,P=0;P<k;P+=1){for(var N=0,D=E;N<D;){var z=R(t,{errors:P,currentLocation:b+D,expectedLocation:b,distance:a,ignoreLocation:p});z<=x?N=D:E=D,D=Math.floor((E-N)/2+N)}E=D;var K=Math.max(1,b-D+1),q=f?M:Math.min(b+D,M)+k,W=Array(q+2);W[q+1]=(1<<P)-1;for(var J=q;J>=K;J-=1){var T=J-1,U=n[e.charAt(T)];if(w&&(_[T]=+!!U),W[J]=(W[J+1]<<1|1)&U,P&&(W[J]|=(I[J+1]|I[J])<<1|1|I[J+1]),W[J]&$&&(C=R(t,{errors:P,currentLocation:T,expectedLocation:b,distance:a,ignoreLocation:p}))<=x){if(x=C,(S=T)<=b)break;K=Math.max(1,2*b-S)}}var V=R(t,{errors:P+1,currentLocation:b,expectedLocation:b,distance:a,ignoreLocation:p});if(V>x)break;I=W}var B={isMatch:S>=0,score:Math.max(.001,C)};if(w){var G=F(_,d);G.length?g&&(B.indices=G):B.isMatch=!1}return B}(e,n,i,{location:c+o,distance:a,threshold:s,findAllMatches:u,minMatchCharLength:h,includeMatches:r,ignoreLocation:f}),p=y.isMatch,m=y.score,k=y.indices;p&&(g=!0),v+=m,p&&k&&(d=[].concat(l(d),l(k)))}));var y={isMatch:g,score:g?v/this.chunks.length:1};return g&&r&&(y.indices=d),y}}]),e}(),D=function(){function e(n){t(this,e),this.pattern=n}return r(e,[{key:"search",value:function(){}}],[{key:"isMultiMatch",value:function(e){return z(e,this.multiRegex)}},{key:"isSingleMatch",value:function(e){return z(e,this.singleRegex)}}]),e}();function z(e,t){var n=e.match(t);return n?n[1]:null}var K=function(e){a(i,e);var n=f(i);function i(e){return t(this,i),n.call(this,e)}return r(i,[{key:"search",value:function(e){var t=e===this.pattern;return{isMatch:t,score:t?0:1,indices:[0,this.pattern.length-1]}}}],[{key:"type",get:function(){return"exact"}},{key:"multiRegex",get:function(){return/^="(.*)"$/}},{key:"singleRegex",get:function(){return/^=(.*)$/}}]),i}(D),q=function(e){a(i,e);var n=f(i);function i(e){return t(this,i),n.call(this,e)}return r(i,[{key:"search",value:function(e){var t=-1===e.indexOf(this.pattern);return{isMatch:t,score:t?0:1,indices:[0,e.length-1]}}}],[{key:"type",get:function(){return"inverse-exact"}},{key:"multiRegex",get:function(){return/^!"(.*)"$/}},{key:"singleRegex",get:function(){return/^!(.*)$/}}]),i}(D),W=function(e){a(i,e);var n=f(i);function i(e){return t(this,i),n.call(this,e)}return r(i,[{key:"search",value:function(e){var t=e.startsWith(this.pattern);return{isMatch:t,score:t?0:1,indices:[0,this.pattern.length-1]}}}],[{key:"type",get:function(){return"prefix-exact"}},{key:"multiRegex",get:function(){return/^\^"(.*)"$/}},{key:"singleRegex",get:function(){return/^\^(.*)$/}}]),i}(D),J=function(e){a(i,e);var n=f(i);function i(e){return t(this,i),n.call(this,e)}return r(i,[{key:"search",value:function(e){var t=!e.startsWith(this.pattern);return{isMatch:t,score:t?0:1,indices:[0,e.length-1]}}}],[{key:"type",get:function(){return"inverse-prefix-exact"}},{key:"multiRegex",get:function(){return/^!\^"(.*)"$/}},{key:"singleRegex",get:function(){return/^!\^(.*)$/}}]),i}(D),T=function(e){a(i,e);var n=f(i);function i(e){return t(this,i),n.call(this,e)}return r(i,[{key:"search",value:function(e){var t=e.endsWith(this.pattern);return{isMatch:t,score:t?0:1,indices:[e.length-this.pattern.length,e.length-1]}}}],[{key:"type",get:function(){return"suffix-exact"}},{key:"multiRegex",get:function(){return/^"(.*)"\$$/}},{key:"singleRegex",get:function(){return/^(.*)\$$/}}]),i}(D),U=function(e){a(i,e);var n=f(i);function i(e){return t(this,i),n.call(this,e)}return r(i,[{key:"search",value:function(e){var t=!e.endsWith(this.pattern);return{isMatch:t,score:t?0:1,indices:[0,e.length-1]}}}],[{key:"type",get:function(){return"inverse-suffix-exact"}},{key:"multiRegex",get:function(){return/^!"(.*)"\$$/}},{key:"singleRegex",get:function(){return/^!(.*)\$$/}}]),i}(D),V=function(e){a(i,e);var n=f(i);function i(e){var r,o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},c=o.location,a=void 0===c?A.location:c,s=o.threshold,u=void 0===s?A.threshold:s,h=o.distance,f=void 0===h?A.distance:h,l=o.includeMatches,d=void 0===l?A.includeMatches:l,v=o.findAllMatches,g=void 0===v?A.findAllMatches:v,y=o.minMatchCharLength,p=void 0===y?A.minMatchCharLength:y,m=o.isCaseSensitive,k=void 0===m?A.isCaseSensitive:m,M=o.ignoreLocation,b=void 0===M?A.ignoreLocation:M;return t(this,i),(r=n.call(this,e))._bitapSearch=new N(e,{location:a,threshold:u,distance:f,includeMatches:d,findAllMatches:g,minMatchCharLength:p,isCaseSensitive:k,ignoreLocation:b}),r}return r(i,[{key:"search",value:function(e){return this._bitapSearch.searchIn(e)}}],[{key:"type",get:function(){return"fuzzy"}},{key:"multiRegex",get:function(){return/^"(.*)"$/}},{key:"singleRegex",get:function(){return/^(.*)$/}}]),i}(D),B=function(e){a(i,e);var n=f(i);function i(e){return t(this,i),n.call(this,e)}return r(i,[{key:"search",value:function(e){for(var t,n=0,r=[],i=this.pattern.length;(t=e.indexOf(this.pattern,n))>-1;)n=t+i,r.push([t,n-1]);var o=!!r.length;return{isMatch:o,score:o?0:1,indices:r}}}],[{key:"type",get:function(){return"include"}},{key:"multiRegex",get:function(){return/^'"(.*)"$/}},{key:"singleRegex",get:function(){return/^'(.*)$/}}]),i}(D),G=[K,B,W,J,U,T,q,V],H=G.length,Q=/ +(?=([^\"]*\"[^\"]*\")*[^\"]*$)/;function X(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return e.split("|").map((function(e){for(var n=e.trim().split(Q).filter((function(e){return e&&!!e.trim()})),r=[],i=0,o=n.length;i<o;i+=1){for(var c=n[i],a=!1,s=-1;!a&&++s<H;){var u=G[s],h=u.isMultiMatch(c);h&&(r.push(new u(h,t)),a=!0)}if(!a)for(s=-1;++s<H;){var f=G[s],l=f.isSingleMatch(c);if(l){r.push(new f(l,t));break}}}return r}))}var Y=new Set([V.type,B.type]),Z=function(){function e(n){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=r.isCaseSensitive,o=void 0===i?A.isCaseSensitive:i,c=r.includeMatches,a=void 0===c?A.includeMatches:c,s=r.minMatchCharLength,u=void 0===s?A.minMatchCharLength:s,h=r.ignoreLocation,f=void 0===h?A.ignoreLocation:h,l=r.findAllMatches,d=void 0===l?A.findAllMatches:l,v=r.location,g=void 0===v?A.location:v,y=r.threshold,p=void 0===y?A.threshold:y,m=r.distance,k=void 0===m?A.distance:m;t(this,e),this.query=null,this.options={isCaseSensitive:o,includeMatches:a,minMatchCharLength:u,findAllMatches:d,ignoreLocation:f,location:g,threshold:p,distance:k},this.pattern=o?n:n.toLowerCase(),this.query=X(this.pattern,this.options)}return r(e,[{key:"searchIn",value:function(e){var t=this.query;if(!t)return{isMatch:!1,score:1};var n=this.options,r=n.includeMatches;e=n.isCaseSensitive?e:e.toLowerCase();for(var i=0,o=[],c=0,a=0,s=t.length;a<s;a+=1){var u=t[a];o.length=0,i=0;for(var h=0,f=u.length;h<f;h+=1){var d=u[h],v=d.search(e),g=v.isMatch,y=v.indices,p=v.score;if(!g){c=0,i=0,o.length=0;break}if(i+=1,c+=p,r){var m=d.constructor.type;Y.has(m)?o=[].concat(l(o),l(y)):o.push(y)}}if(i){var k={isMatch:!0,score:c/i};return r&&(k.indices=o),k}}return{isMatch:!1,score:1}}}],[{key:"condition",value:function(e,t){return t.useExtendedSearch}}]),e}(),ee=[];function te(e,t){for(var n=0,r=ee.length;n<r;n+=1){var i=ee[n];if(i.condition(e,t))return new i(e,t)}return new N(e,t)}var ne="$and",re="$or",ie="$path",oe="$val",ce=function(e){return!(!e[ne]&&!e[re])},ae=function(e){return!!e[ie]},se=function(e){return!v(e)&&m(e)&&!ce(e)},ue=function(e){return i({},ne,Object.keys(e).map((function(t){return i({},t,e[t])})))};function he(e,t){var n=t.ignoreFieldNorm,r=void 0===n?A.ignoreFieldNorm:n;e.forEach((function(e){var t=1;e.matches.forEach((function(e){var n=e.key,i=e.norm,o=e.score,c=n?n.weight:null;t*=Math.pow(0===o&&c?Number.EPSILON:o,(c||1)*(r?1:i))})),e.score=t}))}function fe(e,t){var n=e.matches;t.matches=[],k(n)&&n.forEach((function(e){if(k(e.indices)&&e.indices.length){var n={indices:e.indices,value:e.value};e.key&&(n.key=e.key.src),e.idx>-1&&(n.refIndex=e.idx),t.matches.push(n)}}))}function le(e,t){t.score=e.score}function de(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=n.includeMatches,i=void 0===r?A.includeMatches:r,o=n.includeScore,c=void 0===o?A.includeScore:o,a=[];return i&&a.push(fe),c&&a.push(le),e.map((function(e){var n=e.idx,r={item:t[n],refIndex:n};return a.length&&a.forEach((function(t){t(e,r)})),r}))}var ve=function(){function e(n){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=arguments.length>2?arguments[2]:void 0;t(this,e),this.options=c({},A,{},r),this.options.useExtendedSearch,this._keyStore=new w(this.options.keys),this.setCollection(n,i)}return r(e,[{key:"setCollection",value:function(e,t){if(this._docs=e,t&&!(t instanceof E))throw new Error("Incorrect 'index' type");this._myIndex=t||$(this.options.keys,this._docs,{getFn:this.options.getFn})}},{key:"add",value:function(e){k(e)&&(this._docs.push(e),this._myIndex.add(e))}},{key:"remove",value:function(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:function(){return!1},t=[],n=0,r=this._docs.length;n<r;n+=1){var i=this._docs[n];e(i,n)&&(this.removeAt(n),n-=1,r-=1,t.push(i))}return t}},{key:"removeAt",value:function(e){this._docs.splice(e,1),this._myIndex.removeAt(e)}},{key:"getIndex",value:function(){return this._myIndex}},{key:"search",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.limit,r=void 0===n?-1:n,i=this.options,o=i.includeMatches,c=i.includeScore,a=i.shouldSort,s=i.sortFn,u=i.ignoreFieldNorm,h=g(e)?g(this._docs[0])?this._searchStringList(e):this._searchObjectList(e):this._searchLogical(e);return he(h,{ignoreFieldNorm:u}),a&&h.sort(s),y(r)&&r>-1&&(h=h.slice(0,r)),de(h,this._docs,{includeMatches:o,includeScore:c})}},{key:"_searchStringList",value:function(e){var t=te(e,this.options),n=this._myIndex.records,r=[];return n.forEach((function(e){var n=e.v,i=e.i,o=e.n;if(k(n)){var c=t.searchIn(n),a=c.isMatch,s=c.score,u=c.indices;a&&r.push({item:n,idx:i,matches:[{score:s,value:n,norm:o,indices:u}]})}})),r}},{key:"_searchLogical",value:function(e){var t=this,n=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=n.auto,i=void 0===r||r,o=function e(n){var r=Object.keys(n),o=ae(n);if(!o&&r.length>1&&!ce(n))return e(ue(n));if(se(n)){var c=o?n[ie]:r[0],a=o?n[oe]:n[c];if(!g(a))throw new Error(x(c));var s={keyId:j(c),pattern:a};return i&&(s.searcher=te(a,t)),s}var u={children:[],operator:r[0]};return r.forEach((function(t){var r=n[t];v(r)&&r.forEach((function(t){u.children.push(e(t))}))})),u};return ce(e)||(e=ue(e)),o(e)}(e,this.options),r=this._myIndex.records,i={},o=[];return r.forEach((function(e){var r=e.$,c=e.i;if(k(r)){var a=function e(n,r,i){if(!n.children){var o=n.keyId,c=n.searcher,a=t._findMatches({key:t._keyStore.get(o),value:t._myIndex.getValueForItemAtKeyId(r,o),searcher:c});return a&&a.length?[{idx:i,item:r,matches:a}]:[]}switch(n.operator){case ne:for(var s=[],u=0,h=n.children.length;u<h;u+=1){var f=e(n.children[u],r,i);if(!f.length)return[];s.push.apply(s,l(f))}return s;case re:for(var d=[],v=0,g=n.children.length;v<g;v+=1){var y=e(n.children[v],r,i);if(y.length){d.push.apply(d,l(y));break}}return d}}(n,r,c);a.length&&(i[c]||(i[c]={idx:c,item:r,matches:[]},o.push(i[c])),a.forEach((function(e){var t,n=e.matches;(t=i[c].matches).push.apply(t,l(n))})))}})),o}},{key:"_searchObjectList",value:function(e){var t=this,n=te(e,this.options),r=this._myIndex,i=r.keys,o=r.records,c=[];return o.forEach((function(e){var r=e.$,o=e.i;if(k(r)){var a=[];i.forEach((function(e,i){a.push.apply(a,l(t._findMatches({key:e,value:r[i],searcher:n})))})),a.length&&c.push({idx:o,item:r,matches:a})}})),c}},{key:"_findMatches",value:function(e){var t=e.key,n=e.value,r=e.searcher;if(!k(n))return[];var i=[];if(v(n))n.forEach((function(e){var n=e.v,o=e.i,c=e.n;if(k(n)){var a=r.searchIn(n),s=a.isMatch,u=a.score,h=a.indices;s&&i.push({score:u,key:t,value:n,idx:o,norm:c,indices:h})}}));else{var o=n.v,c=n.n,a=r.searchIn(o),s=a.isMatch,u=a.score,h=a.indices;s&&i.push({score:u,key:t,value:o,norm:c,indices:h})}return i}}]),e}();return ve.version="6.4.6",ve.createIndex=$,ve.parseIndex=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.getFn,r=void 0===n?A.getFn:n,i=e.keys,o=e.records,c=new E({getFn:r});return c.setKeys(i),c.setIndexRecords(o),c},ve.config=A,function(){ee.push.apply(ee,arguments)}(Z),ve},"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).Fuse=t(); \ No newline at end of file diff --git a/doc/scripts/third-party/hljs-line-num-original.js b/doc/scripts/third-party/hljs-line-num-original.js new file mode 100644 index 0000000000000000000000000000000000000000..9b8e18f77c05e1aac8f058565a94d5f7af5317fe --- /dev/null +++ b/doc/scripts/third-party/hljs-line-num-original.js @@ -0,0 +1,369 @@ +// jshint multistr:true + +(function (w, d) { + 'use strict'; + + var TABLE_NAME = 'hljs-ln', + LINE_NAME = 'hljs-ln-line', + CODE_BLOCK_NAME = 'hljs-ln-code', + NUMBERS_BLOCK_NAME = 'hljs-ln-numbers', + NUMBER_LINE_NAME = 'hljs-ln-n', + DATA_ATTR_NAME = 'data-line-number', + BREAK_LINE_REGEXP = /\r\n|\r|\n/g; + + if (w.hljs) { + w.hljs.initLineNumbersOnLoad = initLineNumbersOnLoad; + w.hljs.lineNumbersBlock = lineNumbersBlock; + w.hljs.lineNumbersValue = lineNumbersValue; + + addStyles(); + } else { + w.console.error('highlight.js not detected!'); + } + + function isHljsLnCodeDescendant(domElt) { + var curElt = domElt; + while (curElt) { + if (curElt.className && curElt.className.indexOf('hljs-ln-code') !== -1) { + return true; + } + curElt = curElt.parentNode; + } + return false; + } + + function getHljsLnTable(hljsLnDomElt) { + var curElt = hljsLnDomElt; + while (curElt.nodeName !== 'TABLE') { + curElt = curElt.parentNode; + } + return curElt; + } + + // Function to workaround a copy issue with Microsoft Edge. + // Due to hljs-ln wrapping the lines of code inside a <table> element, + // itself wrapped inside a <pre> element, window.getSelection().toString() + // does not contain any line breaks. So we need to get them back using the + // rendered code in the DOM as reference. + function edgeGetSelectedCodeLines(selection) { + // current selected text without line breaks + var selectionText = selection.toString(); + + // get the <td> element wrapping the first line of selected code + var tdAnchor = selection.anchorNode; + while (tdAnchor.nodeName !== 'TD') { + tdAnchor = tdAnchor.parentNode; + } + + // get the <td> element wrapping the last line of selected code + var tdFocus = selection.focusNode; + while (tdFocus.nodeName !== 'TD') { + tdFocus = tdFocus.parentNode; + } + + // extract line numbers + var firstLineNumber = parseInt(tdAnchor.dataset.lineNumber); + var lastLineNumber = parseInt(tdFocus.dataset.lineNumber); + + // multi-lines copied case + if (firstLineNumber != lastLineNumber) { + + var firstLineText = tdAnchor.textContent; + var lastLineText = tdFocus.textContent; + + // if the selection was made backward, swap values + if (firstLineNumber > lastLineNumber) { + var tmp = firstLineNumber; + firstLineNumber = lastLineNumber; + lastLineNumber = tmp; + tmp = firstLineText; + firstLineText = lastLineText; + lastLineText = tmp; + } + + // discard not copied characters in first line + while (selectionText.indexOf(firstLineText) !== 0) { + firstLineText = firstLineText.slice(1); + } + + // discard not copied characters in last line + while (selectionText.lastIndexOf(lastLineText) === -1) { + lastLineText = lastLineText.slice(0, -1); + } + + // reconstruct and return the real copied text + var selectedText = firstLineText; + var hljsLnTable = getHljsLnTable(tdAnchor); + for (var i = firstLineNumber + 1 ; i < lastLineNumber ; ++i) { + var codeLineSel = format('.{0}[{1}="{2}"]', [CODE_BLOCK_NAME, DATA_ATTR_NAME, i]); + var codeLineElt = hljsLnTable.querySelector(codeLineSel); + selectedText += '\n' + codeLineElt.textContent; + } + selectedText += '\n' + lastLineText; + return selectedText; + // single copied line case + } else { + return selectionText; + } + } + + // ensure consistent code copy/paste behavior across all browsers + // (see https://github.com/wcoder/highlightjs-line-numbers.js/issues/51) + document.addEventListener('copy', function(e) { + // get current selection + var selection = window.getSelection(); + // override behavior when one wants to copy line of codes + if (isHljsLnCodeDescendant(selection.anchorNode)) { + var selectionText; + // workaround an issue with Microsoft Edge as copied line breaks + // are removed otherwise from the selection string + if (window.navigator.userAgent.indexOf('Edge') !== -1) { + selectionText = edgeGetSelectedCodeLines(selection); + } else { + // other browsers can directly use the selection string + selectionText = selection.toString(); + } + e.clipboardData.setData( + 'text/plain', + selectionText + .replace(/(^\t)/gm, '') + ); + e.preventDefault(); + } + }); + + function addStyles () { + var css = d.createElement('style'); + css.type = 'text/css'; + css.innerHTML = format( + '.{0}{border-collapse:collapse}' + + '.{0} td{padding:0}' + + '.{1}:before{content:attr({2})}', + [ + TABLE_NAME, + NUMBER_LINE_NAME, + DATA_ATTR_NAME + ]); + d.getElementsByTagName('head')[0].appendChild(css); + } + + function initLineNumbersOnLoad (options) { + if (d.readyState === 'interactive' || d.readyState === 'complete') { + documentReady(options); + } else { + w.addEventListener('DOMContentLoaded', function () { + documentReady(options); + }); + } + } + + function documentReady (options) { + try { + var blocks = d.querySelectorAll('code.hljs,code.nohighlight'); + + for (var i in blocks) { + if (blocks.hasOwnProperty(i)) { + if (!isPluginDisabledForBlock(blocks[i])) { + lineNumbersBlock(blocks[i], options); + } + } + } + } catch (e) { + w.console.error('LineNumbers error: ', e); + } + } + + function isPluginDisabledForBlock(element) { + return element.classList.contains('nohljsln'); + } + + function lineNumbersBlock (element, options) { + if (typeof element !== 'object') return; + + async(function () { + element.innerHTML = lineNumbersInternal(element, options); + }); + } + + function lineNumbersValue (value, options) { + if (typeof value !== 'string') return; + + var element = document.createElement('code') + element.innerHTML = value + + return lineNumbersInternal(element, options); + } + + function lineNumbersInternal (element, options) { + + var internalOptions = mapOptions(element, options); + + duplicateMultilineNodes(element); + + return addLineNumbersBlockFor(element.innerHTML, internalOptions); + } + + function addLineNumbersBlockFor (inputHtml, options) { + var lines = getLines(inputHtml); + + // if last line contains only carriage return remove it + if (lines[lines.length-1].trim() === '') { + lines.pop(); + } + + if (lines.length > 1 || options.singleLine) { + var html = ''; + + for (var i = 0, l = lines.length; i < l; i++) { + html += format( + '<tr>' + + '<td class="{0} {1}" {3}="{5}">' + + '</td>' + + '<td class="{0} {4}" {3}="{5}">' + + '{6}' + + '</td>' + + '</tr>', + [ + LINE_NAME, + NUMBERS_BLOCK_NAME, + NUMBER_LINE_NAME, + DATA_ATTR_NAME, + CODE_BLOCK_NAME, + i + options.startFrom, + lines[i].length > 0 ? lines[i] : ' ' + ]); + } + + return format('<table class="{0}">{1}</table>', [ TABLE_NAME, html ]); + } + + return inputHtml; + } + + /** + * @param {HTMLElement} element Code block. + * @param {Object} options External API options. + * @returns {Object} Internal API options. + */ + function mapOptions (element, options) { + options = options || {}; + return { + singleLine: getSingleLineOption(options), + startFrom: getStartFromOption(element, options) + }; + } + + function getSingleLineOption (options) { + var defaultValue = false; + if (!!options.singleLine) { + return options.singleLine; + } + return defaultValue; + } + + function getStartFromOption (element, options) { + var defaultValue = 1; + var startFrom = defaultValue; + + if (isFinite(options.startFrom)) { + startFrom = options.startFrom; + } + + // can be overridden because local option is priority + var value = getAttribute(element, 'data-ln-start-from'); + if (value !== null) { + startFrom = toNumber(value, defaultValue); + } + + return startFrom; + } + + /** + * Recursive method for fix multi-line elements implementation in highlight.js + * Doing deep passage on child nodes. + * @param {HTMLElement} element + */ + function duplicateMultilineNodes (element) { + var nodes = element.childNodes; + for (var node in nodes) { + if (nodes.hasOwnProperty(node)) { + var child = nodes[node]; + if (getLinesCount(child.textContent) > 0) { + if (child.childNodes.length > 0) { + duplicateMultilineNodes(child); + } else { + duplicateMultilineNode(child.parentNode); + } + } + } + } + } + + /** + * Method for fix multi-line elements implementation in highlight.js + * @param {HTMLElement} element + */ + function duplicateMultilineNode (element) { + var className = element.className; + + if ( ! /hljs-/.test(className)) return; + + var lines = getLines(element.innerHTML); + + for (var i = 0, result = ''; i < lines.length; i++) { + var lineText = lines[i].length > 0 ? lines[i] : ' '; + result += format('<span class="{0}">{1}</span>\n', [ className, lineText ]); + } + + element.innerHTML = result.trim(); + } + + function getLines (text) { + if (text.length === 0) return []; + return text.split(BREAK_LINE_REGEXP); + } + + function getLinesCount (text) { + return (text.trim().match(BREAK_LINE_REGEXP) || []).length; + } + + /// + /// HELPERS + /// + + function async (func) { + w.setTimeout(func, 0); + } + + /** + * {@link https://wcoder.github.io/notes/string-format-for-string-formating-in-javascript} + * @param {string} format + * @param {array} args + */ + function format (format, args) { + return format.replace(/\{(\d+)\}/g, function(m, n){ + return args[n] !== undefined ? args[n] : m; + }); + } + + /** + * @param {HTMLElement} element Code block. + * @param {String} attrName Attribute name. + * @returns {String} Attribute value or empty. + */ + function getAttribute (element, attrName) { + return element.hasAttribute(attrName) ? element.getAttribute(attrName) : null; + } + + /** + * @param {String} str Source string. + * @param {Number} fallback Fallback value. + * @returns Parsed number or fallback value. + */ + function toNumber (str, fallback) { + if (!str) return fallback; + var number = Number(str); + return isFinite(number) ? number : fallback; + } + +}(window, document)); diff --git a/doc/scripts/third-party/hljs-line-num.js b/doc/scripts/third-party/hljs-line-num.js new file mode 100644 index 0000000000000000000000000000000000000000..facdf6bed436a64e376437991268966075eeea62 --- /dev/null +++ b/doc/scripts/third-party/hljs-line-num.js @@ -0,0 +1 @@ +!function(r,o){"use strict";var e,l="hljs-ln",s="hljs-ln-line",f="hljs-ln-code",c="hljs-ln-numbers",u="hljs-ln-n",h="data-line-number",n=/\r\n|\r|\n/g;function t(e){for(var n=e.toString(),t=e.anchorNode;"TD"!==t.nodeName;)t=t.parentNode;for(var r=e.focusNode;"TD"!==r.nodeName;)r=r.parentNode;var e=parseInt(t.dataset.lineNumber),o=parseInt(r.dataset.lineNumber);if(e==o)return n;var a,i=t.textContent,l=r.textContent;for(o<e&&(a=e,e=o,o=a,a=i,i=l,l=a);0!==n.indexOf(i);)i=i.slice(1);for(;-1===n.lastIndexOf(l);)l=l.slice(0,-1);for(var s=i,c=function(e){for(var n=e;"TABLE"!==n.nodeName;)n=n.parentNode;return n}(t),u=e+1;u<o;++u){var d=v('.{0}[{1}="{2}"]',[f,h,u]);s+="\n"+c.querySelector(d).textContent}return s+="\n"+l}function a(e){try{var n,t=o.querySelectorAll("code.hljs,code.nohighlight");for(n in t)!t.hasOwnProperty(n)||t[n].classList.contains("nohljsln")||i(t[n],e)}catch(e){r.console.error("LineNumbers error: ",e)}}function i(e,n){"object"==typeof e&&r.setTimeout(function(){e.innerHTML=d(e,n)},0)}function d(e,n){var n={singleLine:function(e){return e.singleLine||!1}(n=(n=n)||{}),startFrom:function(e,n){var t=1;isFinite(n.startFrom)&&(t=n.startFrom);n=function(e,n){return e.hasAttribute(n)?e.getAttribute(n):null}(e,"data-ln-start-from");null!==n&&(t=function(e,n){if(!e)return n;e=Number(e);return isFinite(e)?e:n}(n,1));return t}(e,n)},e=(!function e(n){var t=n.childNodes;for(var r in t)!t.hasOwnProperty(r)||0<p((r=t[r]).textContent)&&(0<r.childNodes.length?e(r):m(r.parentNode))}(e),e.innerHTML),t=n,r=g(e);if(""===r[r.length-1].trim()&&r.pop(),1<r.length||t.singleLine){for(var o="",a=0,i=r.length;a<i;a++)o+=v('<tr><td class="{0} {1}" {3}="{5}"></td><td class="{0} {4}" {3}="{5}">{6}</td></tr>',[s,c,u,h,f,a+t.startFrom,0<r[a].length?r[a]:" "]);return v('<table class="{0}">{1}</table>',[l,o])}return e}function m(e){var n=e.className;if(/hljs-/.test(n)){for(var t=g(e.innerHTML),r=0,o="";r<t.length;r++)o+=v('<span class="{0}">{1}</span>\n',[n,0<t[r].length?t[r]:" "]);e.innerHTML=o.trim()}}function g(e){return 0===e.length?[]:e.split(n)}function p(e){return(e.trim().match(n)||[]).length}function v(e,t){return e.replace(/\{(\d+)\}/g,function(e,n){return void 0!==t[n]?t[n]:e})}r.hljs?(r.hljs.initLineNumbersOnLoad=function(e){"interactive"===o.readyState||"complete"===o.readyState?a(e):r.addEventListener("DOMContentLoaded",function(){a(e)})},r.hljs.lineNumbersBlock=i,r.hljs.lineNumbersValue=function(e,n){var t;if("string"==typeof e)return(t=document.createElement("code")).innerHTML=e,d(t,n)},(e=o.createElement("style")).type="text/css",e.innerHTML=v(".{0}{border-collapse:collapse}.{0} td{padding:0}.{1}:before{content:attr({2})}",[l,u,h]),o.getElementsByTagName("head")[0].appendChild(e)):r.console.error("highlight.js not detected!"),document.addEventListener("copy",function(e){var n=window.getSelection();!function(e){for(var n=e;n;){if(n.className&&-1!==n.className.indexOf("hljs-ln-code"))return 1;n=n.parentNode}}(n.anchorNode)||(n=-1!==window.navigator.userAgent.indexOf("Edge")?t(n):n.toString(),e.clipboardData.setData("text/plain",n.replace(/(^\t)/gm,"")),e.preventDefault())})}(window,document); \ No newline at end of file diff --git a/doc/scripts/third-party/hljs-original.js b/doc/scripts/third-party/hljs-original.js new file mode 100644 index 0000000000000000000000000000000000000000..d3066b4f3bcb1432c51363794ba22c7c1462f8e2 --- /dev/null +++ b/doc/scripts/third-party/hljs-original.js @@ -0,0 +1,5171 @@ +/*! + Highlight.js v11.0.0-beta1 (git: bc7ef3d912) + (c) 2006-2021 Ivan Sagalaev and other contributors + License: BSD-3-Clause + */ +var hljs = (function () { + 'use strict'; + + var deepFreezeEs6 = { exports: {} }; + + function deepFreeze(obj) { + if (obj instanceof Map) { + obj.clear = obj.delete = obj.set = function () { + throw new Error('map is read-only'); + }; + } else if (obj instanceof Set) { + obj.add = obj.clear = obj.delete = function () { + throw new Error('set is read-only'); + }; + } + + // Freeze self + Object.freeze(obj); + + Object.getOwnPropertyNames(obj).forEach(function (name) { + var prop = obj[name]; + + // Freeze prop if it is an object + if (typeof prop == 'object' && !Object.isFrozen(prop)) { + deepFreeze(prop); + } + }); + + return obj; + } + + deepFreezeEs6.exports = deepFreeze; + deepFreezeEs6.exports.default = deepFreeze; + + var deepFreeze$1 = deepFreezeEs6.exports; + + + /** @typedef {import('highlight.js').CompiledMode} CompiledMode */ + /** @implements CallbackResponse */ + + class Response { + /** + * @param {CompiledMode} mode + */ + constructor(mode) { + // eslint-disable-next-line no-undefined + if (mode.data === undefined) mode.data = {}; + + this.data = mode.data; + this.isMatchIgnored = false; + } + + ignoreMatch() { + this.isMatchIgnored = true; + } + } + + /** + * @param {string} value + * @returns {string} + */ + function escapeHTML(value) { + return value + .replace(/&/g, '&') + .replace(/</g, '<') + .replace(/>/g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); + } + + /** + * performs a shallow merge of multiple objects into one + * + * @template T + * @param {T} original + * @param {Record<string,any>[]} objects + * @returns {T} a single new object + */ + function inherit$1(original, ...objects) { + /** @type Record<string,any> */ + const result = Object.create(null); + + for (const key in original) { + result[key] = original[key]; + } + objects.forEach(function (obj) { + for (const key in obj) { + result[key] = obj[key]; + } + }); + return /** @type {T} */ (result); + } + + /** + * @typedef {object} Renderer + * @property {(text: string) => void} addText + * @property {(node: Node) => void} openNode + * @property {(node: Node) => void} closeNode + * @property {() => string} value + */ + + /** @typedef {{kind?: string, sublanguage?: boolean}} Node */ + /** @typedef {{walk: (r: Renderer) => void}} Tree */ + /** */ + + const SPAN_CLOSE = '</span>'; + + /** + * Determines if a node needs to be wrapped in <span> + * + * @param {Node} node */ + const emitsWrappingTags = (node) => { + return !!node.kind; + }; + + /** + * + * @param {string} name + * @param {{prefix:string}} options + */ + const expandScopeName = (name, { prefix }) => { + if (name.includes(".")) { + const pieces = name.split("."); + return [ + `${prefix}${pieces.shift()}`, + ...(pieces.map((x, i) => `${x}${"_".repeat(i + 1)}`)) + ].join(" "); + } + return `${prefix}${name}`; + }; + + /** @type {Renderer} */ + class HTMLRenderer { + /** + * Creates a new HTMLRenderer + * + * @param {Tree} parseTree - the parse tree (must support `walk` API) + * @param {{classPrefix: string}} options + */ + constructor(parseTree, options) { + this.buffer = ""; + this.classPrefix = options.classPrefix; + parseTree.walk(this); + } + + /** + * Adds texts to the output stream + * + * @param {string} text */ + addText(text) { + this.buffer += escapeHTML(text); + } + + /** + * Adds a node open to the output stream (if needed) + * + * @param {Node} node */ + openNode(node) { + if (!emitsWrappingTags(node)) return; + + let scope = node.kind; + if (node.sublanguage) { + scope = `language-${scope}`; + } else { + scope = expandScopeName(scope, { prefix: this.classPrefix }); + } + this.span(scope); + } + + /** + * Adds a node close to the output stream (if needed) + * + * @param {Node} node */ + closeNode(node) { + if (!emitsWrappingTags(node)) return; + + this.buffer += SPAN_CLOSE; + } + + /** + * returns the accumulated buffer + */ + value() { + return this.buffer; + } + + // helpers + + /** + * Builds a span element + * + * @param {string} className */ + span(className) { + this.buffer += `<span class="${className}">`; + } + } + + /** @typedef {{kind?: string, sublanguage?: boolean, children: Node[]} | string} Node */ + /** @typedef {{kind?: string, sublanguage?: boolean, children: Node[]} } DataNode */ + /** @typedef {import('highlight.js').Emitter} Emitter */ + /** */ + + class TokenTree { + constructor() { + /** @type DataNode */ + this.rootNode = { children: [] }; + this.stack = [this.rootNode]; + } + + get top() { + return this.stack[this.stack.length - 1]; + } + + get root() { return this.rootNode; } + + /** @param {Node} node */ + add(node) { + this.top.children.push(node); + } + + /** @param {string} kind */ + openNode(kind) { + /** @type Node */ + const node = { kind, children: [] }; + this.add(node); + this.stack.push(node); + } + + closeNode() { + if (this.stack.length > 1) { + return this.stack.pop(); + } + // eslint-disable-next-line no-undefined + return undefined; + } + + closeAllNodes() { + while (this.closeNode()); + } + + toJSON() { + return JSON.stringify(this.rootNode, null, 4); + } + + /** + * @typedef { import("./html_renderer").Renderer } Renderer + * @param {Renderer} builder + */ + walk(builder) { + // this does not + return this.constructor._walk(builder, this.rootNode); + // this works + // return TokenTree._walk(builder, this.rootNode); + } + + /** + * @param {Renderer} builder + * @param {Node} node + */ + static _walk(builder, node) { + if (typeof node === "string") { + builder.addText(node); + } else if (node.children) { + builder.openNode(node); + node.children.forEach((child) => this._walk(builder, child)); + builder.closeNode(node); + } + return builder; + } + + /** + * @param {Node} node + */ + static _collapse(node) { + if (typeof node === "string") return; + if (!node.children) return; + + if (node.children.every(el => typeof el === "string")) { + // node.text = node.children.join(""); + // delete node.children; + node.children = [node.children.join("")]; + } else { + node.children.forEach((child) => { + TokenTree._collapse(child); + }); + } + } + } + + /** + Currently this is all private API, but this is the minimal API necessary + that an Emitter must implement to fully support the parser. + + Minimal interface: + + - addKeyword(text, kind) + - addText(text) + - addSublanguage(emitter, subLanguageName) + - finalize() + - openNode(kind) + - closeNode() + - closeAllNodes() + - toHTML() + + */ + + /** + * @implements {Emitter} + */ + class TokenTreeEmitter extends TokenTree { + /** + * @param {*} options + */ + constructor(options) { + super(); + this.options = options; + } + + /** + * @param {string} text + * @param {string} kind + */ + addKeyword(text, kind) { + if (text === "") { return; } + + this.openNode(kind); + this.addText(text); + this.closeNode(); + } + + /** + * @param {string} text + */ + addText(text) { + if (text === "") { return; } + + this.add(text); + } + + /** + * @param {Emitter & {root: DataNode}} emitter + * @param {string} name + */ + addSublanguage(emitter, name) { + /** @type DataNode */ + const node = emitter.root; + node.kind = name; + node.sublanguage = true; + this.add(node); + } + + toHTML() { + const renderer = new HTMLRenderer(this, this.options); + return renderer.value(); + } + + finalize() { + return true; + } + } + + /** + * @param {string} value + * @returns {RegExp} + * */ + + /** + * @param {RegExp | string } re + * @returns {string} + */ + function source(re) { + if (!re) return null; + if (typeof re === "string") return re; + + return re.source; + } + + /** + * @param {RegExp | string } re + * @returns {string} + */ + function lookahead(re) { + return concat('(?=', re, ')'); + } + + /** + * @param {RegExp | string } re + * @returns {string} + */ + function optional(re) { + return concat('(?:', re, ')?'); + } + + /** + * @param {...(RegExp | string) } args + * @returns {string} + */ + function concat(...args) { + const joined = args.map((x) => source(x)).join(""); + return joined; + } + + function stripOptionsFromArgs(args) { + const opts = args[args.length - 1]; + + if (typeof opts === 'object' && opts.constructor === Object) { + args.splice(args.length - 1, 1); + return opts; + } else { + return {}; + } + } + + /** + * Any of the passed expresssions may match + * + * Creates a huge this | this | that | that match + * @param {(RegExp | string)[] } args + * @returns {string} + */ + function either(...args) { + const opts = stripOptionsFromArgs(args); + const joined = '(' + + (opts.capture ? "" : "?:") + + args.map((x) => source(x)).join("|") + ")"; + return joined; + } + + /** + * @param {RegExp} re + * @returns {number} + */ + function countMatchGroups(re) { + return (new RegExp(re.toString() + '|')).exec('').length - 1; + } + + /** + * Does lexeme start with a regular expression match at the beginning + * @param {RegExp} re + * @param {string} lexeme + */ + function startsWith(re, lexeme) { + const match = re && re.exec(lexeme); + return match && match.index === 0; + } + + // BACKREF_RE matches an open parenthesis or backreference. To avoid + // an incorrect parse, it additionally matches the following: + // - [...] elements, where the meaning of parentheses and escapes change + // - other escape sequences, so we do not misparse escape sequences as + // interesting elements + // - non-matching or lookahead parentheses, which do not capture. These + // follow the '(' with a '?'. + const BACKREF_RE = /\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./; + + // **INTERNAL** Not intended for outside usage + // join logically computes regexps.join(separator), but fixes the + // backreferences so they continue to match. + // it also places each individual regular expression into it's own + // match group, keeping track of the sequencing of those match groups + // is currently an exercise for the caller. :-) + /** + * @param {(string | RegExp)[]} regexps + * @param {{joinWith: string}} opts + * @returns {string} + */ + function _rewriteBackreferences(regexps, { joinWith }) { + let numCaptures = 0; + + return regexps.map((regex) => { + numCaptures += 1; + const offset = numCaptures; + let re = source(regex); + let out = ''; + + while (re.length > 0) { + const match = BACKREF_RE.exec(re); + if (!match) { + out += re; + break; + } + out += re.substring(0, match.index); + re = re.substring(match.index + match[0].length); + if (match[0][0] === '\\' && match[1]) { + // Adjust the backreference. + out += '\\' + String(Number(match[1]) + offset); + } else { + out += match[0]; + if (match[0] === '(') { + numCaptures++; + } + } + } + return out; + }).map(re => `(${re})`).join(joinWith); + } + + /** @typedef {import('highlight.js').Mode} Mode */ + /** @typedef {import('highlight.js').ModeCallback} ModeCallback */ + + // Common regexps + const MATCH_NOTHING_RE = /\b\B/; + const IDENT_RE$1 = '[a-zA-Z]\\w*'; + const UNDERSCORE_IDENT_RE = '[a-zA-Z_]\\w*'; + const NUMBER_RE = '\\b\\d+(\\.\\d+)?'; + const C_NUMBER_RE = '(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)'; // 0x..., 0..., decimal, float + const BINARY_NUMBER_RE = '\\b(0b[01]+)'; // 0b... + const RE_STARTERS_RE = '!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~'; + + /** + * @param { Partial<Mode> & {binary?: string | RegExp} } opts + */ + const SHEBANG = (opts = {}) => { + const beginShebang = /^#![ ]*\//; + if (opts.binary) { + opts.begin = concat( + beginShebang, + /.*\b/, + opts.binary, + /\b.*/); + } + return inherit$1({ + scope: 'meta', + begin: beginShebang, + end: /$/, + relevance: 0, + /** @type {ModeCallback} */ + "on:begin": (m, resp) => { + if (m.index !== 0) resp.ignoreMatch(); + } + }, opts); + }; + + // Common modes + const BACKSLASH_ESCAPE = { + begin: '\\\\[\\s\\S]', relevance: 0 + }; + const APOS_STRING_MODE = { + scope: 'string', + begin: '\'', + end: '\'', + illegal: '\\n', + contains: [BACKSLASH_ESCAPE] + }; + const QUOTE_STRING_MODE = { + scope: 'string', + begin: '"', + end: '"', + illegal: '\\n', + contains: [BACKSLASH_ESCAPE] + }; + const PHRASAL_WORDS_MODE = { + begin: /\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/ + }; + /** + * Creates a comment mode + * + * @param {string | RegExp} begin + * @param {string | RegExp} end + * @param {Mode | {}} [modeOptions] + * @returns {Partial<Mode>} + */ + const COMMENT = function (begin, end, modeOptions = {}) { + const mode = inherit$1( + { + scope: 'comment', + begin, + end, + contains: [] + }, + modeOptions + ); + mode.contains.push({ + scope: 'doctag', + // hack to avoid the space from being included. the space is necessary to + // match here to prevent the plain text rule below from gobbling up doctags + begin: '[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)', + end: /(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/, + excludeBegin: true, + relevance: 0 + }); + const ENGLISH_WORD = either( + // list of common 1 and 2 letter words in English + "I", + "a", + "is", + "so", + "us", + "to", + "at", + "if", + "in", + "it", + "on", + // note: this is not an exhaustive list of contractions, just popular ones + /[A-Za-z]+['](d|ve|re|ll|t|s|n)/, // contractions - can't we'd they're let's, etc + /[A-Za-z]+[-][a-z]+/, // `no-way`, etc. + /[A-Za-z][a-z]{2,}/ // allow capitalized words at beginning of sentences + ); + // looking like plain text, more likely to be a comment + mode.contains.push( + { + // TODO: how to include ", (, ) without breaking grammars that use these for + // comment delimiters? + // begin: /[ ]+([()"]?([A-Za-z'-]{3,}|is|a|I|so|us|[tT][oO]|at|if|in|it|on)[.]?[()":]?([.][ ]|[ ]|\))){3}/ + // --- + + // this tries to find sequences of 3 english words in a row (without any + // "programming" type syntax) this gives us a strong signal that we've + // TRULY found a comment - vs perhaps scanning with the wrong language. + // It's possible to find something that LOOKS like the start of the + // comment - but then if there is no readable text - good chance it is a + // false match and not a comment. + // + // for a visual example please see: + // https://github.com/highlightjs/highlight.js/issues/2827 + + begin: concat( + /[ ]+/, // necessary to prevent us gobbling up doctags like /* @author Bob Mcgill */ + '(', + ENGLISH_WORD, + /[.]?[:]?([.][ ]|[ ])/, + '){3}') // look for 3 words in a row + } + ); + return mode; + }; + const C_LINE_COMMENT_MODE = COMMENT('//', '$'); + const C_BLOCK_COMMENT_MODE = COMMENT('/\\*', '\\*/'); + const HASH_COMMENT_MODE = COMMENT('#', '$'); + const NUMBER_MODE = { + scope: 'number', + begin: NUMBER_RE, + relevance: 0 + }; + const C_NUMBER_MODE = { + scope: 'number', + begin: C_NUMBER_RE, + relevance: 0 + }; + const BINARY_NUMBER_MODE = { + scope: 'number', + begin: BINARY_NUMBER_RE, + relevance: 0 + }; + const REGEXP_MODE = { + // this outer rule makes sure we actually have a WHOLE regex and not simply + // an expression such as: + // + // 3 / something + // + // (which will then blow up when regex's `illegal` sees the newline) + begin: /(?=\/[^/\n]*\/)/, + contains: [{ + scope: 'regexp', + begin: /\//, + end: /\/[gimuy]*/, + illegal: /\n/, + contains: [ + BACKSLASH_ESCAPE, + { + begin: /\[/, + end: /\]/, + relevance: 0, + contains: [BACKSLASH_ESCAPE] + } + ] + }] + }; + const TITLE_MODE = { + scope: 'title', + begin: IDENT_RE$1, + relevance: 0 + }; + const UNDERSCORE_TITLE_MODE = { + scope: 'title', + begin: UNDERSCORE_IDENT_RE, + relevance: 0 + }; + const METHOD_GUARD = { + // excludes method names from keyword processing + begin: '\\.\\s*' + UNDERSCORE_IDENT_RE, + relevance: 0 + }; + + /** + * Adds end same as begin mechanics to a mode + * + * Your mode must include at least a single () match group as that first match + * group is what is used for comparison + * @param {Partial<Mode>} mode + */ + const END_SAME_AS_BEGIN = function (mode) { + return Object.assign(mode, + { + /** @type {ModeCallback} */ + 'on:begin': (m, resp) => { resp.data._beginMatch = m[1]; }, + /** @type {ModeCallback} */ + 'on:end': (m, resp) => { if (resp.data._beginMatch !== m[1]) resp.ignoreMatch(); } + }); + }; + + var MODES$1 = /*#__PURE__*/Object.freeze({ + __proto__: null, + MATCH_NOTHING_RE: MATCH_NOTHING_RE, + IDENT_RE: IDENT_RE$1, + UNDERSCORE_IDENT_RE: UNDERSCORE_IDENT_RE, + NUMBER_RE: NUMBER_RE, + C_NUMBER_RE: C_NUMBER_RE, + BINARY_NUMBER_RE: BINARY_NUMBER_RE, + RE_STARTERS_RE: RE_STARTERS_RE, + SHEBANG: SHEBANG, + BACKSLASH_ESCAPE: BACKSLASH_ESCAPE, + APOS_STRING_MODE: APOS_STRING_MODE, + QUOTE_STRING_MODE: QUOTE_STRING_MODE, + PHRASAL_WORDS_MODE: PHRASAL_WORDS_MODE, + COMMENT: COMMENT, + C_LINE_COMMENT_MODE: C_LINE_COMMENT_MODE, + C_BLOCK_COMMENT_MODE: C_BLOCK_COMMENT_MODE, + HASH_COMMENT_MODE: HASH_COMMENT_MODE, + NUMBER_MODE: NUMBER_MODE, + C_NUMBER_MODE: C_NUMBER_MODE, + BINARY_NUMBER_MODE: BINARY_NUMBER_MODE, + REGEXP_MODE: REGEXP_MODE, + TITLE_MODE: TITLE_MODE, + UNDERSCORE_TITLE_MODE: UNDERSCORE_TITLE_MODE, + METHOD_GUARD: METHOD_GUARD, + END_SAME_AS_BEGIN: END_SAME_AS_BEGIN + }); + + /** + @typedef {import('highlight.js').CallbackResponse} CallbackResponse + @typedef {import('highlight.js').CompilerExt} CompilerExt + */ + + // Grammar extensions / plugins + // See: https://github.com/highlightjs/highlight.js/issues/2833 + + // Grammar extensions allow "syntactic sugar" to be added to the grammar modes + // without requiring any underlying changes to the compiler internals. + + // `compileMatch` being the perfect small example of now allowing a grammar + // author to write `match` when they desire to match a single expression rather + // than being forced to use `begin`. The extension then just moves `match` into + // `begin` when it runs. Ie, no features have been added, but we've just made + // the experience of writing (and reading grammars) a little bit nicer. + + // ------ + + // TODO: We need negative look-behind support to do this properly + /** + * Skip a match if it has a preceding dot + * + * This is used for `beginKeywords` to prevent matching expressions such as + * `bob.keyword.do()`. The mode compiler automatically wires this up as a + * special _internal_ 'on:begin' callback for modes with `beginKeywords` + * @param {RegExpMatchArray} match + * @param {CallbackResponse} response + */ + function skipIfHasPrecedingDot(match, response) { + const before = match.input[match.index - 1]; + if (before === ".") { + response.ignoreMatch(); + } + } + + /** + * + * @type {CompilerExt} + */ + function scopeClassName(mode, _parent) { + // eslint-disable-next-line no-undefined + if (mode.className !== undefined) { + mode.scope = mode.className; + delete mode.className; + } + } + + /** + * `beginKeywords` syntactic sugar + * @type {CompilerExt} + */ + function beginKeywords(mode, parent) { + if (!parent) return; + if (!mode.beginKeywords) return; + + // for languages with keywords that include non-word characters checking for + // a word boundary is not sufficient, so instead we check for a word boundary + // or whitespace - this does no harm in any case since our keyword engine + // doesn't allow spaces in keywords anyways and we still check for the boundary + // first + mode.begin = '\\b(' + mode.beginKeywords.split(' ').join('|') + ')(?!\\.)(?=\\b|\\s)'; + mode.__beforeBegin = skipIfHasPrecedingDot; + mode.keywords = mode.keywords || mode.beginKeywords; + delete mode.beginKeywords; + + // prevents double relevance, the keywords themselves provide + // relevance, the mode doesn't need to double it + // eslint-disable-next-line no-undefined + if (mode.relevance === undefined) mode.relevance = 0; + } + + /** + * Allow `illegal` to contain an array of illegal values + * @type {CompilerExt} + */ + function compileIllegal(mode, _parent) { + if (!Array.isArray(mode.illegal)) return; + + mode.illegal = either(...mode.illegal); + } + + /** + * `match` to match a single expression for readability + * @type {CompilerExt} + */ + function compileMatch(mode, _parent) { + if (!mode.match) return; + if (mode.begin || mode.end) throw new Error("begin & end are not supported with match"); + + mode.begin = mode.match; + delete mode.match; + } + + /** + * provides the default 1 relevance to all modes + * @type {CompilerExt} + */ + function compileRelevance(mode, _parent) { + // eslint-disable-next-line no-undefined + if (mode.relevance === undefined) mode.relevance = 1; + } + + // allow beforeMatch to act as a "qualifier" for the match + // the full match begin must be [beforeMatch][begin] + const beforeMatchExt = (mode, parent) => { + if (!mode.beforeMatch) return; + // starts conflicts with endsParent which we need to make sure the child + // rule is not matched multiple times + if (mode.starts) throw new Error("beforeMatch cannot be used with starts"); + + const originalMode = Object.assign({}, mode); + Object.keys(mode).forEach((key) => { delete mode[key]; }); + + mode.keywords = originalMode.keywords; + mode.begin = concat(originalMode.beforeMatch, lookahead(originalMode.begin)); + mode.starts = { + relevance: 0, + contains: [ + Object.assign(originalMode, { endsParent: true }) + ] + }; + mode.relevance = 0; + + delete originalMode.beforeMatch; + }; + + // keywords that should have no default relevance value + const COMMON_KEYWORDS = [ + 'of', + 'and', + 'for', + 'in', + 'not', + 'or', + 'if', + 'then', + 'parent', // common variable name + 'list', // common variable name + 'value' // common variable name + ]; + + const DEFAULT_KEYWORD_SCOPE = "keyword"; + + /** + * Given raw keywords from a language definition, compile them. + * + * @param {string | Record<string,string|string[]> | Array<string>} rawKeywords + * @param {boolean} caseInsensitive + */ + function compileKeywords(rawKeywords, caseInsensitive, scopeName = DEFAULT_KEYWORD_SCOPE) { + /** @type KeywordDict */ + const compiledKeywords = Object.create(null); + + // input can be a string of keywords, an array of keywords, or a object with + // named keys representing scopeName (which can then point to a string or array) + if (typeof rawKeywords === 'string') { + compileList(scopeName, rawKeywords.split(" ")); + } else if (Array.isArray(rawKeywords)) { + compileList(scopeName, rawKeywords); + } else { + Object.keys(rawKeywords).forEach(function (scopeName) { + // collapse all our objects back into the parent object + Object.assign( + compiledKeywords, + compileKeywords(rawKeywords[scopeName], caseInsensitive, scopeName) + ); + }); + } + return compiledKeywords; + + // --- + + /** + * Compiles an individual list of keywords + * + * Ex: "for if when while|5" + * + * @param {string} scopeName + * @param {Array<string>} keywordList + */ + function compileList(scopeName, keywordList) { + if (caseInsensitive) { + keywordList = keywordList.map(x => x.toLowerCase()); + } + keywordList.forEach(function (keyword) { + const pair = keyword.split('|'); + compiledKeywords[pair[0]] = [scopeName, scoreForKeyword(pair[0], pair[1])]; + }); + } + } + + /** + * Returns the proper score for a given keyword + * + * Also takes into account comment keywords, which will be scored 0 UNLESS + * another score has been manually assigned. + * @param {string} keyword + * @param {string} [providedScore] + */ + function scoreForKeyword(keyword, providedScore) { + // manual scores always win over common keywords + // so you can force a score of 1 if you really insist + if (providedScore) { + return Number(providedScore); + } + + return commonKeyword(keyword) ? 0 : 1; + } + + /** + * Determines if a given keyword is common or not + * + * @param {string} keyword */ + function commonKeyword(keyword) { + return COMMON_KEYWORDS.includes(keyword.toLowerCase()); + } + + /* + + For the reasoning behind this please see: + https://github.com/highlightjs/highlight.js/issues/2880#issuecomment-747275419 + + */ + + /** + * @type {Record<string, boolean>} + */ + const seenDeprecations = {}; + + /** + * @param {string} message + */ + const error = (message) => { + console.error(message); + }; + + /** + * @param {string} message + * @param {any} args + */ + const warn = (message, ...args) => { + console.log(`WARN: ${message}`, ...args); + }; + + /** + * @param {string} version + * @param {string} message + */ + const deprecated = (version, message) => { + if (seenDeprecations[`${version}/${message}`]) return; + + console.log(`Deprecated as of ${version}. ${message}`); + seenDeprecations[`${version}/${message}`] = true; + }; + + /* eslint-disable no-throw-literal */ + + /** + @typedef {import('highlight.js').CompiledMode} CompiledMode + */ + + const MultiClassError = new Error(); + + /** + * Renumbers labeled scope names to account for additional inner match + * groups that otherwise would break everything. + * + * Lets say we 3 match scopes: + * + * { 1 => ..., 2 => ..., 3 => ... } + * + * So what we need is a clean match like this: + * + * (a)(b)(c) => [ "a", "b", "c" ] + * + * But this falls apart with inner match groups: + * + * (a)(((b)))(c) => ["a", "b", "b", "b", "c" ] + * + * Our scopes are now "out of alignment" and we're repeating `b` 3 times. + * What needs to happen is the numbers are remapped: + * + * { 1 => ..., 2 => ..., 5 => ... } + * + * We also need to know that the ONLY groups that should be output + * are 1, 2, and 5. This function handles this behavior. + * + * @param {CompiledMode} mode + * @param {Array<RegExp>} regexes + * @param {{key: "beginScope"|"endScope"}} opts + */ + function remapScopeNames(mode, regexes, { key }) { + let offset = 0; + const scopeNames = mode[key]; + /** @type Record<number,boolean> */ + const emit = {}; + /** @type Record<number,string> */ + const positions = {}; + + for (let i = 1; i <= regexes.length; i++) { + positions[i + offset] = scopeNames[i]; + emit[i + offset] = true; + offset += countMatchGroups(regexes[i - 1]); + } + // we use _emit to keep track of which match groups are "top-level" to avoid double + // output from inside match groups + mode[key] = positions; + mode[key]._emit = emit; + mode[key]._multi = true; + } + + /** + * @param {CompiledMode} mode + */ + function beginMultiClass(mode) { + if (!Array.isArray(mode.begin)) return; + + if (mode.skip || mode.excludeBegin || mode.returnBegin) { + error("skip, excludeBegin, returnBegin not compatible with beginScope: {}"); + throw MultiClassError; + } + + if (typeof mode.beginScope !== "object" || mode.beginScope === null) { + error("beginScope must be object"); + throw MultiClassError; + } + + remapScopeNames(mode, mode.begin, { key: "beginScope" }); + mode.begin = _rewriteBackreferences(mode.begin, { joinWith: "" }); + } + + /** + * @param {CompiledMode} mode + */ + function endMultiClass(mode) { + if (!Array.isArray(mode.end)) return; + + if (mode.skip || mode.excludeEnd || mode.returnEnd) { + error("skip, excludeEnd, returnEnd not compatible with endScope: {}"); + throw MultiClassError; + } + + if (typeof mode.endScope !== "object" || mode.endScope === null) { + error("endScope must be object"); + throw MultiClassError; + } + + remapScopeNames(mode, mode.end, { key: "endScope" }); + mode.end = _rewriteBackreferences(mode.end, { joinWith: "" }); + } + + /** + * this exists only to allow `scope: {}` to be used beside `match:` + * Otherwise `beginScope` would necessary and that would look weird + + { + match: [ /def/, /\w+/ ] + scope: { 1: "keyword" , 2: "title" } + } + + * @param {CompiledMode} mode + */ + function scopeSugar(mode) { + if (mode.scope && typeof mode.scope === "object" && mode.scope !== null) { + mode.beginScope = mode.scope; + delete mode.scope; + } + } + + /** + * @param {CompiledMode} mode + */ + function MultiClass(mode) { + scopeSugar(mode); + + if (typeof mode.beginScope === "string") { + mode.beginScope = { _wrap: mode.beginScope }; + } + if (typeof mode.endScope === "string") { + mode.endScope = { _wrap: mode.endScope }; + } + + beginMultiClass(mode); + endMultiClass(mode); + } + + /** + @typedef {import('highlight.js').Mode} Mode + @typedef {import('highlight.js').CompiledMode} CompiledMode + @typedef {import('highlight.js').Language} Language + @typedef {import('highlight.js').HLJSPlugin} HLJSPlugin + @typedef {import('highlight.js').CompiledLanguage} CompiledLanguage + */ + + // compilation + + /** + * Compiles a language definition result + * + * Given the raw result of a language definition (Language), compiles this so + * that it is ready for highlighting code. + * @param {Language} language + * @returns {CompiledLanguage} + */ + function compileLanguage(language) { + /** + * Builds a regex with the case sensitivity of the current language + * + * @param {RegExp | string} value + * @param {boolean} [global] + */ + function langRe(value, global) { + return new RegExp( + source(value), + 'm' + (language.case_insensitive ? 'i' : '') + (global ? 'g' : '') + ); + } + + /** + Stores multiple regular expressions and allows you to quickly search for + them all in a string simultaneously - returning the first match. It does + this by creating a huge (a|b|c) regex - each individual item wrapped with () + and joined by `|` - using match groups to track position. When a match is + found checking which position in the array has content allows us to figure + out which of the original regexes / match groups triggered the match. + + The match object itself (the result of `Regex.exec`) is returned but also + enhanced by merging in any meta-data that was registered with the regex. + This is how we keep track of which mode matched, and what type of rule + (`illegal`, `begin`, end, etc). + */ + class MultiRegex { + constructor() { + this.matchIndexes = {}; + // @ts-ignore + this.regexes = []; + this.matchAt = 1; + this.position = 0; + } + + // @ts-ignore + addRule(re, opts) { + opts.position = this.position++; + // @ts-ignore + this.matchIndexes[this.matchAt] = opts; + this.regexes.push([opts, re]); + this.matchAt += countMatchGroups(re) + 1; + } + + compile() { + if (this.regexes.length === 0) { + // avoids the need to check length every time exec is called + // @ts-ignore + this.exec = () => null; + } + const terminators = this.regexes.map(el => el[1]); + this.matcherRe = langRe(_rewriteBackreferences(terminators, { joinWith: '|' }), true); + this.lastIndex = 0; + } + + /** @param {string} s */ + exec(s) { + this.matcherRe.lastIndex = this.lastIndex; + const match = this.matcherRe.exec(s); + if (!match) { return null; } + + // eslint-disable-next-line no-undefined + const i = match.findIndex((el, i) => i > 0 && el !== undefined); + // @ts-ignore + const matchData = this.matchIndexes[i]; + // trim off any earlier non-relevant match groups (ie, the other regex + // match groups that make up the multi-matcher) + match.splice(0, i); + + return Object.assign(match, matchData); + } + } + + /* + Created to solve the key deficiently with MultiRegex - there is no way to + test for multiple matches at a single location. Why would we need to do + that? In the future a more dynamic engine will allow certain matches to be + ignored. An example: if we matched say the 3rd regex in a large group but + decided to ignore it - we'd need to started testing again at the 4th + regex... but MultiRegex itself gives us no real way to do that. + + So what this class creates MultiRegexs on the fly for whatever search + position they are needed. + + NOTE: These additional MultiRegex objects are created dynamically. For most + grammars most of the time we will never actually need anything more than the + first MultiRegex - so this shouldn't have too much overhead. + + Say this is our search group, and we match regex3, but wish to ignore it. + + regex1 | regex2 | regex3 | regex4 | regex5 ' ie, startAt = 0 + + What we need is a new MultiRegex that only includes the remaining + possibilities: + + regex4 | regex5 ' ie, startAt = 3 + + This class wraps all that complexity up in a simple API... `startAt` decides + where in the array of expressions to start doing the matching. It + auto-increments, so if a match is found at position 2, then startAt will be + set to 3. If the end is reached startAt will return to 0. + + MOST of the time the parser will be setting startAt manually to 0. + */ + class ResumableMultiRegex { + constructor() { + // @ts-ignore + this.rules = []; + // @ts-ignore + this.multiRegexes = []; + this.count = 0; + + this.lastIndex = 0; + this.regexIndex = 0; + } + + // @ts-ignore + getMatcher(index) { + if (this.multiRegexes[index]) return this.multiRegexes[index]; + + const matcher = new MultiRegex(); + this.rules.slice(index).forEach(([re, opts]) => matcher.addRule(re, opts)); + matcher.compile(); + this.multiRegexes[index] = matcher; + return matcher; + } + + resumingScanAtSamePosition() { + return this.regexIndex !== 0; + } + + considerAll() { + this.regexIndex = 0; + } + + // @ts-ignore + addRule(re, opts) { + this.rules.push([re, opts]); + if (opts.type === "begin") this.count++; + } + + /** @param {string} s */ + exec(s) { + const m = this.getMatcher(this.regexIndex); + m.lastIndex = this.lastIndex; + let result = m.exec(s); + + // The following is because we have no easy way to say "resume scanning at the + // existing position but also skip the current rule ONLY". What happens is + // all prior rules are also skipped which can result in matching the wrong + // thing. Example of matching "booger": + + // our matcher is [string, "booger", number] + // + // ....booger.... + + // if "booger" is ignored then we'd really need a regex to scan from the + // SAME position for only: [string, number] but ignoring "booger" (if it + // was the first match), a simple resume would scan ahead who knows how + // far looking only for "number", ignoring potential string matches (or + // future "booger" matches that might be valid.) + + // So what we do: We execute two matchers, one resuming at the same + // position, but the second full matcher starting at the position after: + + // /--- resume first regex match here (for [number]) + // |/---- full match here for [string, "booger", number] + // vv + // ....booger.... + + // Which ever results in a match first is then used. So this 3-4 step + // process essentially allows us to say "match at this position, excluding + // a prior rule that was ignored". + // + // 1. Match "booger" first, ignore. Also proves that [string] does non match. + // 2. Resume matching for [number] + // 3. Match at index + 1 for [string, "booger", number] + // 4. If #2 and #3 result in matches, which came first? + if (this.resumingScanAtSamePosition()) { + if (result && result.index === this.lastIndex); else { // use the second matcher result + const m2 = this.getMatcher(0); + m2.lastIndex = this.lastIndex + 1; + result = m2.exec(s); + } + } + + if (result) { + this.regexIndex += result.position + 1; + if (this.regexIndex === this.count) { + // wrap-around to considering all matches again + this.considerAll(); + } + } + + return result; + } + } + + /** + * Given a mode, builds a huge ResumableMultiRegex that can be used to walk + * the content and find matches. + * + * @param {CompiledMode} mode + * @returns {ResumableMultiRegex} + */ + function buildModeRegex(mode) { + const mm = new ResumableMultiRegex(); + + mode.contains.forEach(term => mm.addRule(term.begin, { rule: term, type: "begin" })); + + if (mode.terminatorEnd) { + mm.addRule(mode.terminatorEnd, { type: "end" }); + } + if (mode.illegal) { + mm.addRule(mode.illegal, { type: "illegal" }); + } + + return mm; + } + + /** skip vs abort vs ignore + * + * @skip - The mode is still entered and exited normally (and contains rules apply), + * but all content is held and added to the parent buffer rather than being + * output when the mode ends. Mostly used with `sublanguage` to build up + * a single large buffer than can be parsed by sublanguage. + * + * - The mode begin ands ends normally. + * - Content matched is added to the parent mode buffer. + * - The parser cursor is moved forward normally. + * + * @abort - A hack placeholder until we have ignore. Aborts the mode (as if it + * never matched) but DOES NOT continue to match subsequent `contains` + * modes. Abort is bad/suboptimal because it can result in modes + * farther down not getting applied because an earlier rule eats the + * content but then aborts. + * + * - The mode does not begin. + * - Content matched by `begin` is added to the mode buffer. + * - The parser cursor is moved forward accordingly. + * + * @ignore - Ignores the mode (as if it never matched) and continues to match any + * subsequent `contains` modes. Ignore isn't technically possible with + * the current parser implementation. + * + * - The mode does not begin. + * - Content matched by `begin` is ignored. + * - The parser cursor is not moved forward. + */ + + /** + * Compiles an individual mode + * + * This can raise an error if the mode contains certain detectable known logic + * issues. + * @param {Mode} mode + * @param {CompiledMode | null} [parent] + * @returns {CompiledMode | never} + */ + function compileMode(mode, parent) { + const cmode = /** @type CompiledMode */ (mode); + if (mode.isCompiled) return cmode; + + [ + scopeClassName, + // do this early so compiler extensions generally don't have to worry about + // the distinction between match/begin + compileMatch, + MultiClass, + beforeMatchExt + ].forEach(ext => ext(mode, parent)); + + language.compilerExtensions.forEach(ext => ext(mode, parent)); + + // __beforeBegin is considered private API, internal use only + mode.__beforeBegin = null; + + [ + beginKeywords, + // do this later so compiler extensions that come earlier have access to the + // raw array if they wanted to perhaps manipulate it, etc. + compileIllegal, + // default to 1 relevance if not specified + compileRelevance + ].forEach(ext => ext(mode, parent)); + + mode.isCompiled = true; + + let keywordPattern = null; + if (typeof mode.keywords === "object" && mode.keywords.$pattern) { + // we need a copy because keywords might be compiled multiple times + // so we can't go deleting $pattern from the original on the first + // pass + mode.keywords = Object.assign({}, mode.keywords); + keywordPattern = mode.keywords.$pattern; + delete mode.keywords.$pattern; + } + keywordPattern = keywordPattern || /\w+/; + + if (mode.keywords) { + mode.keywords = compileKeywords(mode.keywords, language.case_insensitive); + } + + cmode.keywordPatternRe = langRe(keywordPattern, true); + + if (parent) { + if (!mode.begin) mode.begin = /\B|\b/; + cmode.beginRe = langRe(mode.begin); + if (!mode.end && !mode.endsWithParent) mode.end = /\B|\b/; + if (mode.end) cmode.endRe = langRe(mode.end); + cmode.terminatorEnd = source(mode.end) || ''; + if (mode.endsWithParent && parent.terminatorEnd) { + cmode.terminatorEnd += (mode.end ? '|' : '') + parent.terminatorEnd; + } + } + if (mode.illegal) cmode.illegalRe = langRe(/** @type {RegExp | string} */(mode.illegal)); + if (!mode.contains) mode.contains = []; + + mode.contains = [].concat(...mode.contains.map(function (c) { + return expandOrCloneMode(c === 'self' ? mode : c); + })); + mode.contains.forEach(function (c) { compileMode(/** @type Mode */(c), cmode); }); + + if (mode.starts) { + compileMode(mode.starts, parent); + } + + cmode.matcher = buildModeRegex(cmode); + return cmode; + } + + if (!language.compilerExtensions) language.compilerExtensions = []; + + // self is not valid at the top-level + if (language.contains && language.contains.includes('self')) { + throw new Error("ERR: contains `self` is not supported at the top-level of a language. See documentation."); + } + + // we need a null object, which inherit will guarantee + language.classNameAliases = inherit$1(language.classNameAliases || {}); + + return compileMode(/** @type Mode */(language)); + } + + /** + * Determines if a mode has a dependency on it's parent or not + * + * If a mode does have a parent dependency then often we need to clone it if + * it's used in multiple places so that each copy points to the correct parent, + * where-as modes without a parent can often safely be re-used at the bottom of + * a mode chain. + * + * @param {Mode | null} mode + * @returns {boolean} - is there a dependency on the parent? + * */ + function dependencyOnParent(mode) { + if (!mode) return false; + + return mode.endsWithParent || dependencyOnParent(mode.starts); + } + + /** + * Expands a mode or clones it if necessary + * + * This is necessary for modes with parental dependenceis (see notes on + * `dependencyOnParent`) and for nodes that have `variants` - which must then be + * exploded into their own individual modes at compile time. + * + * @param {Mode} mode + * @returns {Mode | Mode[]} + * */ + function expandOrCloneMode(mode) { + if (mode.variants && !mode.cachedVariants) { + mode.cachedVariants = mode.variants.map(function (variant) { + return inherit$1(mode, { variants: null }, variant); + }); + } + + // EXPAND + // if we have variants then essentially "replace" the mode with the variants + // this happens in compileMode, where this function is called from + if (mode.cachedVariants) { + return mode.cachedVariants; + } + + // CLONE + // if we have dependencies on parents then we need a unique + // instance of ourselves, so we can be reused with many + // different parents without issue + if (dependencyOnParent(mode)) { + return inherit$1(mode, { starts: mode.starts ? inherit$1(mode.starts) : null }); + } + + if (Object.isFrozen(mode)) { + return inherit$1(mode); + } + + // no special dependency issues, just return ourselves + return mode; + } + + var version = "11.0.0-beta1"; + + /* + Syntax highlighting with language autodetection. + https://highlightjs.org/ + */ + + /** + @typedef {import('highlight.js').Mode} Mode + @typedef {import('highlight.js').CompiledMode} CompiledMode + @typedef {import('highlight.js').Language} Language + @typedef {import('highlight.js').HLJSApi} HLJSApi + @typedef {import('highlight.js').HLJSPlugin} HLJSPlugin + @typedef {import('highlight.js').PluginEvent} PluginEvent + @typedef {import('highlight.js').HLJSOptions} HLJSOptions + @typedef {import('highlight.js').LanguageFn} LanguageFn + @typedef {import('highlight.js').HighlightedHTMLElement} HighlightedHTMLElement + @typedef {import('highlight.js').BeforeHighlightContext} BeforeHighlightContext + @typedef {import('highlight.js/private').MatchType} MatchType + @typedef {import('highlight.js/private').KeywordData} KeywordData + @typedef {import('highlight.js/private').EnhancedMatch} EnhancedMatch + @typedef {import('highlight.js/private').AnnotatedError} AnnotatedError + @typedef {import('highlight.js').AutoHighlightResult} AutoHighlightResult + @typedef {import('highlight.js').HighlightOptions} HighlightOptions + @typedef {import('highlight.js').HighlightResult} HighlightResult + */ + + + const escape = escapeHTML; + const inherit = inherit$1; + const NO_MATCH = Symbol("nomatch"); + const MAX_KEYWORD_HITS = 7; + + /** + * @param {any} hljs - object that is extended (legacy) + * @returns {HLJSApi} + */ + const HLJS = function (hljs) { + // Global internal variables used within the highlight.js library. + /** @type {Record<string, Language>} */ + const languages = Object.create(null); + /** @type {Record<string, string>} */ + const aliases = Object.create(null); + /** @type {HLJSPlugin[]} */ + const plugins = []; + + // safe/production mode - swallows more errors, tries to keep running + // even if a single syntax or parse hits a fatal error + let SAFE_MODE = true; + const LANGUAGE_NOT_FOUND = "Could not find the language '{}', did you forget to load/include a language module?"; + /** @type {Language} */ + const PLAINTEXT_LANGUAGE = { disableAutodetect: true, name: 'Plain text', contains: [] }; + + // Global options used when within external APIs. This is modified when + // calling the `hljs.configure` function. + /** @type HLJSOptions */ + let options = { + ignoreUnescapedHTML: false, + noHighlightRe: /^(no-?highlight)$/i, + languageDetectRe: /\blang(?:uage)?-([\w-]+)\b/i, + classPrefix: 'hljs-', + cssSelector: 'pre code', + languages: null, + // beta configuration options, subject to change, welcome to discuss + // https://github.com/highlightjs/highlight.js/issues/1086 + __emitter: TokenTreeEmitter + }; + + /* Utility functions */ + + /** + * Tests a language name to see if highlighting should be skipped + * @param {string} languageName + */ + function shouldNotHighlight(languageName) { + return options.noHighlightRe.test(languageName); + } + + /** + * @param {HighlightedHTMLElement} block - the HTML element to determine language for + */ + function blockLanguage(block) { + let classes = block.className + ' '; + + classes += block.parentNode ? block.parentNode.className : ''; + + // language-* takes precedence over non-prefixed class names. + const match = options.languageDetectRe.exec(classes); + if (match) { + const language = getLanguage(match[1]); + if (!language) { + warn(LANGUAGE_NOT_FOUND.replace("{}", match[1])); + warn("Falling back to no-highlight mode for this block.", block); + } + return language ? match[1] : 'no-highlight'; + } + + return classes + .split(/\s+/) + .find((_class) => shouldNotHighlight(_class) || getLanguage(_class)); + } + + /** + * Core highlighting function. + * + * OLD API + * highlight(lang, code, ignoreIllegals, continuation) + * + * NEW API + * highlight(code, {lang, ignoreIllegals}) + * + * @param {string} codeOrLanguageName - the language to use for highlighting + * @param {string | HighlightOptions} optionsOrCode - the code to highlight + * @param {boolean} [ignoreIllegals] - whether to ignore illegal matches, default is to bail + * @param {CompiledMode} [continuation] - current continuation mode, if any + * + * @returns {HighlightResult} Result - an object that represents the result + * @property {string} language - the language name + * @property {number} relevance - the relevance score + * @property {string} value - the highlighted HTML code + * @property {string} code - the original raw code + * @property {CompiledMode} top - top of the current mode stack + * @property {boolean} illegal - indicates whether any illegal matches were found + */ + function highlight(codeOrLanguageName, optionsOrCode, ignoreIllegals, continuation) { + let code = ""; + let languageName = ""; + if (typeof optionsOrCode === "object") { + code = codeOrLanguageName; + ignoreIllegals = optionsOrCode.ignoreIllegals; + languageName = optionsOrCode.language; + // continuation not supported at all via the new API + // eslint-disable-next-line no-undefined + continuation = undefined; + } else { + // old API + deprecated("10.7.0", "highlight(lang, code, ...args) has been deprecated."); + deprecated("10.7.0", "Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277"); + languageName = codeOrLanguageName; + code = optionsOrCode; + } + + // https://github.com/highlightjs/highlight.js/issues/3149 + // eslint-disable-next-line no-undefined + if (ignoreIllegals === undefined) { ignoreIllegals = true; } + + /** @type {BeforeHighlightContext} */ + const context = { + code, + language: languageName + }; + // the plugin can change the desired language or the code to be highlighted + // just be changing the object it was passed + fire("before:highlight", context); + + // a before plugin can usurp the result completely by providing it's own + // in which case we don't even need to call highlight + const result = context.result + ? context.result + : _highlight(context.language, context.code, ignoreIllegals, continuation); + + result.code = context.code; + // the plugin can change anything in result to suite it + fire("after:highlight", result); + + return result; + } + + /** + * private highlight that's used internally and does not fire callbacks + * + * @param {string} languageName - the language to use for highlighting + * @param {string} codeToHighlight - the code to highlight + * @param {boolean?} [ignoreIllegals] - whether to ignore illegal matches, default is to bail + * @param {CompiledMode?} [continuation] - current continuation mode, if any + * @returns {HighlightResult} - result of the highlight operation + */ + function _highlight(languageName, codeToHighlight, ignoreIllegals, continuation) { + const keywordHits = Object.create(null); + + /** + * Return keyword data if a match is a keyword + * @param {CompiledMode} mode - current mode + * @param {string} matchText - the textual match + * @returns {KeywordData | false} + */ + function keywordData(mode, matchText) { + return mode.keywords[matchText]; + } + + function processKeywords() { + if (!top.keywords) { + emitter.addText(modeBuffer); + return; + } + + let lastIndex = 0; + top.keywordPatternRe.lastIndex = 0; + let match = top.keywordPatternRe.exec(modeBuffer); + let buf = ""; + + while (match) { + buf += modeBuffer.substring(lastIndex, match.index); + const word = language.case_insensitive ? match[0].toLowerCase() : match[0]; + const data = keywordData(top, word); + if (data) { + const [kind, keywordRelevance] = data; + emitter.addText(buf); + buf = ""; + + keywordHits[word] = (keywordHits[word] || 0) + 1; + if (keywordHits[word] <= MAX_KEYWORD_HITS) relevance += keywordRelevance; + if (kind.startsWith("_")) { + // _ implied for relevance only, do not highlight + // by applying a class name + buf += match[0]; + } else { + const cssClass = language.classNameAliases[kind] || kind; + emitter.addKeyword(match[0], cssClass); + } + } else { + buf += match[0]; + } + lastIndex = top.keywordPatternRe.lastIndex; + match = top.keywordPatternRe.exec(modeBuffer); + } + buf += modeBuffer.substr(lastIndex); + emitter.addText(buf); + } + + function processSubLanguage() { + if (modeBuffer === "") return; + /** @type HighlightResult */ + let result = null; + + if (typeof top.subLanguage === 'string') { + if (!languages[top.subLanguage]) { + emitter.addText(modeBuffer); + return; + } + result = _highlight(top.subLanguage, modeBuffer, true, continuations[top.subLanguage]); + continuations[top.subLanguage] = /** @type {CompiledMode} */ (result._top); + } else { + result = highlightAuto(modeBuffer, top.subLanguage.length ? top.subLanguage : null); + } + + // Counting embedded language score towards the host language may be disabled + // with zeroing the containing mode relevance. Use case in point is Markdown that + // allows XML everywhere and makes every XML snippet to have a much larger Markdown + // score. + if (top.relevance > 0) { + relevance += result.relevance; + } + emitter.addSublanguage(result._emitter, result.language); + } + + function processBuffer() { + if (top.subLanguage != null) { + processSubLanguage(); + } else { + processKeywords(); + } + modeBuffer = ''; + } + + /** + * @param {CompiledMode} mode + * @param {RegExpMatchArray} match + */ + function emitMultiClass(scope, match) { + let i = 1; + // eslint-disable-next-line no-undefined + while (match[i] !== undefined) { + if (!scope._emit[i]) { i++; continue; } + const klass = language.classNameAliases[scope[i]] || scope[i]; + const text = match[i]; + if (klass) { + emitter.addKeyword(text, klass); + } else { + modeBuffer = text; + processKeywords(); + modeBuffer = ""; + } + i++; + } + } + + /** + * @param {CompiledMode} mode - new mode to start + * @param {RegExpMatchArray} match + */ + function startNewMode(mode, match) { + if (mode.scope && typeof mode.scope === "string") { + emitter.openNode(language.classNameAliases[mode.scope] || mode.scope); + } + if (mode.beginScope) { + // beginScope just wraps the begin match itself in a scope + if (mode.beginScope._wrap) { + emitter.addKeyword(modeBuffer, language.classNameAliases[mode.beginScope._wrap] || mode.beginScope._wrap); + modeBuffer = ""; + } else if (mode.beginScope._multi) { + // at this point modeBuffer should just be the match + emitMultiClass(mode.beginScope, match); + modeBuffer = ""; + } + } + + top = Object.create(mode, { parent: { value: top } }); + return top; + } + + /** + * @param {CompiledMode } mode - the mode to potentially end + * @param {RegExpMatchArray} match - the latest match + * @param {string} matchPlusRemainder - match plus remainder of content + * @returns {CompiledMode | void} - the next mode, or if void continue on in current mode + */ + function endOfMode(mode, match, matchPlusRemainder) { + let matched = startsWith(mode.endRe, matchPlusRemainder); + + if (matched) { + if (mode["on:end"]) { + const resp = new Response(mode); + mode["on:end"](match, resp); + if (resp.isMatchIgnored) matched = false; + } + + if (matched) { + while (mode.endsParent && mode.parent) { + mode = mode.parent; + } + return mode; + } + } + // even if on:end fires an `ignore` it's still possible + // that we might trigger the end node because of a parent mode + if (mode.endsWithParent) { + return endOfMode(mode.parent, match, matchPlusRemainder); + } + } + + /** + * Handle matching but then ignoring a sequence of text + * + * @param {string} lexeme - string containing full match text + */ + function doIgnore(lexeme) { + if (top.matcher.regexIndex === 0) { + // no more regexes to potentially match here, so we move the cursor forward one + // space + modeBuffer += lexeme[0]; + return 1; + } else { + // no need to move the cursor, we still have additional regexes to try and + // match at this very spot + resumeScanAtSamePosition = true; + return 0; + } + } + + /** + * Handle the start of a new potential mode match + * + * @param {EnhancedMatch} match - the current match + * @returns {number} how far to advance the parse cursor + */ + function doBeginMatch(match) { + const lexeme = match[0]; + const newMode = match.rule; + + const resp = new Response(newMode); + // first internal before callbacks, then the public ones + const beforeCallbacks = [newMode.__beforeBegin, newMode["on:begin"]]; + for (const cb of beforeCallbacks) { + if (!cb) continue; + cb(match, resp); + if (resp.isMatchIgnored) return doIgnore(lexeme); + } + + if (newMode.skip) { + modeBuffer += lexeme; + } else { + if (newMode.excludeBegin) { + modeBuffer += lexeme; + } + processBuffer(); + if (!newMode.returnBegin && !newMode.excludeBegin) { + modeBuffer = lexeme; + } + } + startNewMode(newMode, match); + return newMode.returnBegin ? 0 : lexeme.length; + } + + /** + * Handle the potential end of mode + * + * @param {RegExpMatchArray} match - the current match + */ + function doEndMatch(match) { + const lexeme = match[0]; + const matchPlusRemainder = codeToHighlight.substr(match.index); + + const endMode = endOfMode(top, match, matchPlusRemainder); + if (!endMode) { return NO_MATCH; } + + const origin = top; + if (top.endScope && top.endScope._wrap) { + processBuffer(); + emitter.addKeyword(lexeme, top.endScope._wrap); + } else if (top.endScope && top.endScope._multi) { + processBuffer(); + emitMultiClass(top.endScope, match); + } else if (origin.skip) { + modeBuffer += lexeme; + } else { + if (!(origin.returnEnd || origin.excludeEnd)) { + modeBuffer += lexeme; + } + processBuffer(); + if (origin.excludeEnd) { + modeBuffer = lexeme; + } + } + do { + if (top.scope && !top.isMultiClass) { + emitter.closeNode(); + } + if (!top.skip && !top.subLanguage) { + relevance += top.relevance; + } + top = top.parent; + } while (top !== endMode.parent); + if (endMode.starts) { + startNewMode(endMode.starts, match); + } + return origin.returnEnd ? 0 : lexeme.length; + } + + function processContinuations() { + const list = []; + for (let current = top; current !== language; current = current.parent) { + if (current.scope) { + list.unshift(current.scope); + } + } + list.forEach(item => emitter.openNode(item)); + } + + /** @type {{type?: MatchType, index?: number, rule?: Mode}}} */ + let lastMatch = {}; + + /** + * Process an individual match + * + * @param {string} textBeforeMatch - text preceding the match (since the last match) + * @param {EnhancedMatch} [match] - the match itself + */ + function processLexeme(textBeforeMatch, match) { + const lexeme = match && match[0]; + + // add non-matched text to the current mode buffer + modeBuffer += textBeforeMatch; + + if (lexeme == null) { + processBuffer(); + return 0; + } + + // we've found a 0 width match and we're stuck, so we need to advance + // this happens when we have badly behaved rules that have optional matchers to the degree that + // sometimes they can end up matching nothing at all + // Ref: https://github.com/highlightjs/highlight.js/issues/2140 + if (lastMatch.type === "begin" && match.type === "end" && lastMatch.index === match.index && lexeme === "") { + // spit the "skipped" character that our regex choked on back into the output sequence + modeBuffer += codeToHighlight.slice(match.index, match.index + 1); + if (!SAFE_MODE) { + /** @type {AnnotatedError} */ + const err = new Error(`0 width match regex (${languageName})`); + err.languageName = languageName; + err.badRule = lastMatch.rule; + throw err; + } + return 1; + } + lastMatch = match; + + if (match.type === "begin") { + return doBeginMatch(match); + } else if (match.type === "illegal" && !ignoreIllegals) { + // illegal match, we do not continue processing + /** @type {AnnotatedError} */ + const err = new Error('Illegal lexeme "' + lexeme + '" for mode "' + (top.scope || '<unnamed>') + '"'); + err.mode = top; + throw err; + } else if (match.type === "end") { + const processed = doEndMatch(match); + if (processed !== NO_MATCH) { + return processed; + } + } + + // edge case for when illegal matches $ (end of line) which is technically + // a 0 width match but not a begin/end match so it's not caught by the + // first handler (when ignoreIllegals is true) + if (match.type === "illegal" && lexeme === "") { + // advance so we aren't stuck in an infinite loop + return 1; + } + + // infinite loops are BAD, this is a last ditch catch all. if we have a + // decent number of iterations yet our index (cursor position in our + // parsing) still 3x behind our index then something is very wrong + // so we bail + if (iterations > 100000 && iterations > match.index * 3) { + const err = new Error('potential infinite loop, way more iterations than matches'); + throw err; + } + + /* + Why might be find ourselves here? An potential end match that was + triggered but could not be completed. IE, `doEndMatch` returned NO_MATCH. + (this could be because a callback requests the match be ignored, etc) + + This causes no real harm other than stopping a few times too many. + */ + + modeBuffer += lexeme; + return lexeme.length; + } + + const language = getLanguage(languageName); + if (!language) { + error(LANGUAGE_NOT_FOUND.replace("{}", languageName)); + throw new Error('Unknown language: "' + languageName + '"'); + } + + const md = compileLanguage(language); + let result = ''; + /** @type {CompiledMode} */ + let top = continuation || md; + /** @type Record<string,CompiledMode> */ + const continuations = {}; // keep continuations for sub-languages + const emitter = new options.__emitter(options); + processContinuations(); + let modeBuffer = ''; + let relevance = 0; + let index = 0; + let iterations = 0; + let resumeScanAtSamePosition = false; + + try { + top.matcher.considerAll(); + + for (; ;) { + iterations++; + if (resumeScanAtSamePosition) { + // only regexes not matched previously will now be + // considered for a potential match + resumeScanAtSamePosition = false; + } else { + top.matcher.considerAll(); + } + top.matcher.lastIndex = index; + + const match = top.matcher.exec(codeToHighlight); + // console.log("match", match[0], match.rule && match.rule.begin) + + if (!match) break; + + const beforeMatch = codeToHighlight.substring(index, match.index); + const processedCount = processLexeme(beforeMatch, match); + index = match.index + processedCount; + } + processLexeme(codeToHighlight.substr(index)); + emitter.closeAllNodes(); + emitter.finalize(); + result = emitter.toHTML(); + + return { + language: languageName, + value: result, + relevance: relevance, + illegal: false, + _emitter: emitter, + _top: top + }; + } catch (err) { + if (err.message && err.message.includes('Illegal')) { + return { + language: languageName, + value: escape(codeToHighlight), + illegal: true, + relevance: 0, + _illegalBy: { + message: err.message, + index: index, + context: codeToHighlight.slice(index - 100, index + 100), + mode: err.mode, + resultSoFar: result + }, + _emitter: emitter + }; + } else if (SAFE_MODE) { + return { + language: languageName, + value: escape(codeToHighlight), + illegal: false, + relevance: 0, + errorRaised: err, + _emitter: emitter, + _top: top + }; + } else { + throw err; + } + } + } + + /** + * returns a valid highlight result, without actually doing any actual work, + * auto highlight starts with this and it's possible for small snippets that + * auto-detection may not find a better match + * @param {string} code + * @returns {HighlightResult} + */ + function justTextHighlightResult(code) { + const result = { + value: escape(code), + illegal: false, + relevance: 0, + _top: PLAINTEXT_LANGUAGE, + _emitter: new options.__emitter(options) + }; + result._emitter.addText(code); + return result; + } + + /** + Highlighting with language detection. Accepts a string with the code to + highlight. Returns an object with the following properties: + + - language (detected language) + - relevance (int) + - value (an HTML string with highlighting markup) + - secondBest (object with the same structure for second-best heuristically + detected language, may be absent) + + @param {string} code + @param {Array<string>} [languageSubset] + @returns {AutoHighlightResult} + */ + function highlightAuto(code, languageSubset) { + languageSubset = languageSubset || options.languages || Object.keys(languages); + const plaintext = justTextHighlightResult(code); + + const results = languageSubset.filter(getLanguage).filter(autoDetection).map(name => + _highlight(name, code, false) + ); + results.unshift(plaintext); // plaintext is always an option + + const sorted = results.sort((a, b) => { + // sort base on relevance + if (a.relevance !== b.relevance) return b.relevance - a.relevance; + + // always award the tie to the base language + // ie if C++ and Arduino are tied, it's more likely to be C++ + if (a.language && b.language) { + if (getLanguage(a.language).supersetOf === b.language) { + return 1; + } else if (getLanguage(b.language).supersetOf === a.language) { + return -1; + } + } + + // otherwise say they are equal, which has the effect of sorting on + // relevance while preserving the original ordering - which is how ties + // have historically been settled, ie the language that comes first always + // wins in the case of a tie + return 0; + }); + + const [best, secondBest] = sorted; + + /** @type {AutoHighlightResult} */ + const result = best; + result.secondBest = secondBest; + + return result; + } + + /** + * Builds new class name for block given the language name + * + * @param {HTMLElement} element + * @param {string} [currentLang] + * @param {string} [resultLang] + */ + function updateClassName(element, currentLang, resultLang) { + const language = (currentLang && aliases[currentLang]) || resultLang; + + element.classList.add("hljs"); + element.classList.add(`language-${language}`); + } + + /** + * Applies highlighting to a DOM node containing code. + * + * @param {HighlightedHTMLElement} element - the HTML element to highlight + */ + function highlightElement(element) { + /** @type HTMLElement */ + let node = null; + const language = blockLanguage(element); + + if (shouldNotHighlight(language)) return; + + fire("before:highlightElement", + { el: element, language: language }); + + // we should be all text, no child nodes + if (!options.ignoreUnescapedHTML && element.children.length > 0) { + console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk."); + console.warn("https://github.com/highlightjs/highlight.js/issues/2886"); + console.warn(element); + } + + node = element; + const text = node.textContent; + const result = language ? highlight(text, { language, ignoreIllegals: true }) : highlightAuto(text); + + fire("after:highlightElement", { el: element, result, text }); + + element.innerHTML = result.value; + updateClassName(element, language, result.language); + element.result = { + language: result.language, + // TODO: remove with version 11.0 + re: result.relevance, + relevance: result.relevance + }; + if (result.secondBest) { + element.secondBest = { + language: result.secondBest.language, + relevance: result.secondBest.relevance + }; + } + } + + /** + * Updates highlight.js global options with the passed options + * + * @param {Partial<HLJSOptions>} userOptions + */ + function configure(userOptions) { + options = inherit(options, userOptions); + } + + // TODO: remove v12, deprecated + const initHighlighting = () => { + highlightAll(); + deprecated("10.6.0", "initHighlighting() deprecated. Use highlightAll() now."); + }; + + // TODO: remove v12, deprecated + function initHighlightingOnLoad() { + highlightAll(); + deprecated("10.6.0", "initHighlightingOnLoad() deprecated. Use highlightAll() now."); + } + + let wantsHighlight = false; + + /** + * auto-highlights all pre>code elements on the page + */ + function highlightAll() { + // if we are called too early in the loading process + if (document.readyState === "loading") { + wantsHighlight = true; + return; + } + + const blocks = document.querySelectorAll(options.cssSelector); + blocks.forEach(highlightElement); + } + + function boot() { + // if a highlight was requested before DOM was loaded, do now + if (wantsHighlight) highlightAll(); + } + + // make sure we are in the browser environment + if (typeof window !== 'undefined' && window.addEventListener) { + window.addEventListener('DOMContentLoaded', boot, false); + } + + /** + * Register a language grammar module + * + * @param {string} languageName + * @param {LanguageFn} languageDefinition + */ + function registerLanguage(languageName, languageDefinition) { + let lang = null; + try { + lang = languageDefinition(hljs); + } catch (error$1) { + error("Language definition for '{}' could not be registered.".replace("{}", languageName)); + // hard or soft error + if (!SAFE_MODE) { throw error$1; } else { error(error$1); } + // languages that have serious errors are replaced with essentially a + // "plaintext" stand-in so that the code blocks will still get normal + // css classes applied to them - and one bad language won't break the + // entire highlighter + lang = PLAINTEXT_LANGUAGE; + } + // give it a temporary name if it doesn't have one in the meta-data + if (!lang.name) lang.name = languageName; + languages[languageName] = lang; + lang.rawDefinition = languageDefinition.bind(null, hljs); + + if (lang.aliases) { + registerAliases(lang.aliases, { languageName }); + } + } + + /** + * Remove a language grammar module + * + * @param {string} languageName + */ + function unregisterLanguage(languageName) { + delete languages[languageName]; + for (const alias of Object.keys(aliases)) { + if (aliases[alias] === languageName) { + delete aliases[alias]; + } + } + } + + /** + * @returns {string[]} List of language internal names + */ + function listLanguages() { + return Object.keys(languages); + } + + /** + * @param {string} name - name of the language to retrieve + * @returns {Language | undefined} + */ + function getLanguage(name) { + name = (name || '').toLowerCase(); + return languages[name] || languages[aliases[name]]; + } + + /** + * + * @param {string|string[]} aliasList - single alias or list of aliases + * @param {{languageName: string}} opts + */ + function registerAliases(aliasList, { languageName }) { + if (typeof aliasList === 'string') { + aliasList = [aliasList]; + } + aliasList.forEach(alias => { aliases[alias.toLowerCase()] = languageName; }); + } + + /** + * Determines if a given language has auto-detection enabled + * @param {string} name - name of the language + */ + function autoDetection(name) { + const lang = getLanguage(name); + return lang && !lang.disableAutodetect; + } + + /** + * Upgrades the old highlightBlock plugins to the new + * highlightElement API + * @param {HLJSPlugin} plugin + */ + function upgradePluginAPI(plugin) { + // TODO: remove with v12 + if (plugin["before:highlightBlock"] && !plugin["before:highlightElement"]) { + plugin["before:highlightElement"] = (data) => { + plugin["before:highlightBlock"]( + Object.assign({ block: data.el }, data) + ); + }; + } + if (plugin["after:highlightBlock"] && !plugin["after:highlightElement"]) { + plugin["after:highlightElement"] = (data) => { + plugin["after:highlightBlock"]( + Object.assign({ block: data.el }, data) + ); + }; + } + } + + /** + * @param {HLJSPlugin} plugin + */ + function addPlugin(plugin) { + upgradePluginAPI(plugin); + plugins.push(plugin); + } + + /** + * + * @param {PluginEvent} event + * @param {any} args + */ + function fire(event, args) { + const cb = event; + plugins.forEach(function (plugin) { + if (plugin[cb]) { + plugin[cb](args); + } + }); + } + + /** + * + * @param {HighlightedHTMLElement} el + */ + function deprecateHighlightBlock(el) { + deprecated("10.7.0", "highlightBlock will be removed entirely in v12.0"); + deprecated("10.7.0", "Please use highlightElement now."); + + return highlightElement(el); + } + + /* Interface definition */ + Object.assign(hljs, { + highlight, + highlightAuto, + highlightAll, + highlightElement, + // TODO: Remove with v12 API + highlightBlock: deprecateHighlightBlock, + configure, + initHighlighting, + initHighlightingOnLoad, + registerLanguage, + unregisterLanguage, + listLanguages, + getLanguage, + registerAliases, + autoDetection, + inherit, + addPlugin + }); + + hljs.debugMode = function () { SAFE_MODE = false; }; + hljs.safeMode = function () { SAFE_MODE = true; }; + hljs.versionString = version; + + for (const key in MODES$1) { + // @ts-ignore + if (typeof MODES$1[key] === "object") { + // @ts-ignore + deepFreeze$1(MODES$1[key]); + } + } + + // merge all the modes/regexes into our main object + Object.assign(hljs, MODES$1); + + return hljs; + }; + + // export an "instance" of the highlighter + var HighlightJS = HLJS({}); + + /* + Language: Bash + Author: vah <vahtenberg@gmail.com> + Contributrors: Benjamin Pannell <contact@sierrasoftworks.com> + Website: https://www.gnu.org/software/bash/ + Category: common + */ + + /** @type LanguageFn */ + function bash(hljs) { + const VAR = {}; + const BRACED_VAR = { + begin: /\$\{/, + end: /\}/, + contains: [ + "self", + { + begin: /:-/, + contains: [VAR] + } // default values + ] + }; + Object.assign(VAR, { + className: 'variable', + variants: [ + { + begin: concat(/\$[\w\d#@][\w\d_]*/, + // negative look-ahead tries to avoid matching patterns that are not + // Perl at all like $ident$, @ident@, etc. + `(?![\\w\\d])(?![$])`) + }, + BRACED_VAR + ] + }); + + const SUBST = { + className: 'subst', + begin: /\$\(/, end: /\)/, + contains: [hljs.BACKSLASH_ESCAPE] + }; + const HERE_DOC = { + begin: /<<-?\s*(?=\w+)/, + starts: { + contains: [ + hljs.END_SAME_AS_BEGIN({ + begin: /(\w+)/, + end: /(\w+)/, + className: 'string' + }) + ] + } + }; + const QUOTE_STRING = { + className: 'string', + begin: /"/, end: /"/, + contains: [ + hljs.BACKSLASH_ESCAPE, + VAR, + SUBST + ] + }; + SUBST.contains.push(QUOTE_STRING); + const ESCAPED_QUOTE = { + className: '', + begin: /\\"/ + + }; + const APOS_STRING = { + className: 'string', + begin: /'/, end: /'/ + }; + const ARITHMETIC = { + begin: /\$\(\(/, + end: /\)\)/, + contains: [ + { begin: /\d+#[0-9a-f]+/, className: "number" }, + hljs.NUMBER_MODE, + VAR + ] + }; + const SH_LIKE_SHELLS = [ + "fish", + "bash", + "zsh", + "sh", + "csh", + "ksh", + "tcsh", + "dash", + "scsh", + ]; + const KNOWN_SHEBANG = hljs.SHEBANG({ + binary: `(${SH_LIKE_SHELLS.join("|")})`, + relevance: 10 + }); + const FUNCTION = { + className: 'function', + begin: /\w[\w\d_]*\s*\(\s*\)\s*\{/, + returnBegin: true, + contains: [hljs.inherit(hljs.TITLE_MODE, { begin: /\w[\w\d_]*/ })], + relevance: 0 + }; + + const KEYWORDS = [ + "if", + "then", + "else", + "elif", + "fi", + "for", + "while", + "in", + "do", + "done", + "case", + "esac", + "function" + ]; + + const LITERALS = [ + "true", + "false" + ]; + + return { + name: 'Bash', + aliases: ['sh'], + keywords: { + $pattern: /\b[a-z._-]+\b/, + keyword: KEYWORDS, + literal: LITERALS, + built_in: + // Shell built-ins + // http://www.gnu.org/software/bash/manual/html_node/Shell-Builtin-Commands.html + 'break cd continue eval exec exit export getopts hash pwd readonly return shift test times ' + + 'trap umask unset ' + + // Bash built-ins + 'alias bind builtin caller command declare echo enable help let local logout mapfile printf ' + + 'read readarray source type typeset ulimit unalias ' + + // Shell modifiers + 'set shopt ' + + // Zsh built-ins + 'autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles ' + + 'compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate ' + + 'fc fg float functions getcap getln history integer jobs kill limit log noglob popd print ' + + 'pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit ' + + 'unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof ' + + 'zpty zregexparse zsocket zstyle ztcp' + }, + contains: [ + KNOWN_SHEBANG, // to catch known shells and boost relevancy + hljs.SHEBANG(), // to catch unknown shells but still highlight the shebang + FUNCTION, + ARITHMETIC, + hljs.HASH_COMMENT_MODE, + HERE_DOC, + QUOTE_STRING, + ESCAPED_QUOTE, + APOS_STRING, + VAR + ] + }; + } + + + const MODES = (hljs) => { + return { + IMPORTANT: { + scope: 'meta', + begin: '!important' + }, + HEXCOLOR: { + scope: 'number', + begin: '#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})' + }, + ATTRIBUTE_SELECTOR_MODE: { + scope: 'selector-attr', + begin: /\[/, + end: /\]/, + illegal: '$', + contains: [ + hljs.APOS_STRING_MODE, + hljs.QUOTE_STRING_MODE + ] + }, + CSS_NUMBER_MODE: { + scope: 'number', + begin: hljs.NUMBER_RE + '(' + + '%|em|ex|ch|rem' + + '|vw|vh|vmin|vmax' + + '|cm|mm|in|pt|pc|px' + + '|deg|grad|rad|turn' + + '|s|ms' + + '|Hz|kHz' + + '|dpi|dpcm|dppx' + + ')?', + relevance: 0 + } + }; + }; + + const TAGS = [ + 'a', + 'abbr', + 'address', + 'article', + 'aside', + 'audio', + 'b', + 'blockquote', + 'body', + 'button', + 'canvas', + 'caption', + 'cite', + 'code', + 'dd', + 'del', + 'details', + 'dfn', + 'div', + 'dl', + 'dt', + 'em', + 'fieldset', + 'figcaption', + 'figure', + 'footer', + 'form', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'header', + 'hgroup', + 'html', + 'i', + 'iframe', + 'img', + 'input', + 'ins', + 'kbd', + 'label', + 'legend', + 'li', + 'main', + 'mark', + 'menu', + 'nav', + 'object', + 'ol', + 'p', + 'q', + 'quote', + 'samp', + 'section', + 'span', + 'strong', + 'summary', + 'sup', + 'table', + 'tbody', + 'td', + 'textarea', + 'tfoot', + 'th', + 'thead', + 'time', + 'tr', + 'ul', + 'var', + 'video' + ]; + + const MEDIA_FEATURES = [ + 'any-hover', + 'any-pointer', + 'aspect-ratio', + 'color', + 'color-gamut', + 'color-index', + 'device-aspect-ratio', + 'device-height', + 'device-width', + 'display-mode', + 'forced-colors', + 'grid', + 'height', + 'hover', + 'inverted-colors', + 'monochrome', + 'orientation', + 'overflow-block', + 'overflow-inline', + 'pointer', + 'prefers-color-scheme', + 'prefers-contrast', + 'prefers-reduced-motion', + 'prefers-reduced-transparency', + 'resolution', + 'scan', + 'scripting', + 'update', + 'width', + // TODO: find a better solution? + 'min-width', + 'max-width', + 'min-height', + 'max-height' + ]; + + // https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes + const PSEUDO_CLASSES = [ + 'active', + 'any-link', + 'blank', + 'checked', + 'current', + 'default', + 'defined', + 'dir', // dir() + 'disabled', + 'drop', + 'empty', + 'enabled', + 'first', + 'first-child', + 'first-of-type', + 'fullscreen', + 'future', + 'focus', + 'focus-visible', + 'focus-within', + 'has', // has() + 'host', // host or host() + 'host-context', // host-context() + 'hover', + 'indeterminate', + 'in-range', + 'invalid', + 'is', // is() + 'lang', // lang() + 'last-child', + 'last-of-type', + 'left', + 'link', + 'local-link', + 'not', // not() + 'nth-child', // nth-child() + 'nth-col', // nth-col() + 'nth-last-child', // nth-last-child() + 'nth-last-col', // nth-last-col() + 'nth-last-of-type', //nth-last-of-type() + 'nth-of-type', //nth-of-type() + 'only-child', + 'only-of-type', + 'optional', + 'out-of-range', + 'past', + 'placeholder-shown', + 'read-only', + 'read-write', + 'required', + 'right', + 'root', + 'scope', + 'target', + 'target-within', + 'user-invalid', + 'valid', + 'visited', + 'where' // where() + ]; + + // https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements + const PSEUDO_ELEMENTS = [ + 'after', + 'backdrop', + 'before', + 'cue', + 'cue-region', + 'first-letter', + 'first-line', + 'grammar-error', + 'marker', + 'part', + 'placeholder', + 'selection', + 'slotted', + 'spelling-error' + ]; + + const ATTRIBUTES = [ + 'align-content', + 'align-items', + 'align-self', + 'animation', + 'animation-delay', + 'animation-direction', + 'animation-duration', + 'animation-fill-mode', + 'animation-iteration-count', + 'animation-name', + 'animation-play-state', + 'animation-timing-function', + 'auto', + 'backface-visibility', + 'background', + 'background-attachment', + 'background-clip', + 'background-color', + 'background-image', + 'background-origin', + 'background-position', + 'background-repeat', + 'background-size', + 'border', + 'border-bottom', + 'border-bottom-color', + 'border-bottom-left-radius', + 'border-bottom-right-radius', + 'border-bottom-style', + 'border-bottom-width', + 'border-collapse', + 'border-color', + 'border-image', + 'border-image-outset', + 'border-image-repeat', + 'border-image-slice', + 'border-image-source', + 'border-image-width', + 'border-left', + 'border-left-color', + 'border-left-style', + 'border-left-width', + 'border-radius', + 'border-right', + 'border-right-color', + 'border-right-style', + 'border-right-width', + 'border-spacing', + 'border-style', + 'border-top', + 'border-top-color', + 'border-top-left-radius', + 'border-top-right-radius', + 'border-top-style', + 'border-top-width', + 'border-width', + 'bottom', + 'box-decoration-break', + 'box-shadow', + 'box-sizing', + 'break-after', + 'break-before', + 'break-inside', + 'caption-side', + 'clear', + 'clip', + 'clip-path', + 'color', + 'column-count', + 'column-fill', + 'column-gap', + 'column-rule', + 'column-rule-color', + 'column-rule-style', + 'column-rule-width', + 'column-span', + 'column-width', + 'columns', + 'content', + 'counter-increment', + 'counter-reset', + 'cursor', + 'direction', + 'display', + 'empty-cells', + 'filter', + 'flex', + 'flex-basis', + 'flex-direction', + 'flex-flow', + 'flex-grow', + 'flex-shrink', + 'flex-wrap', + 'float', + 'font', + 'font-display', + 'font-family', + 'font-feature-settings', + 'font-kerning', + 'font-language-override', + 'font-size', + 'font-size-adjust', + 'font-smoothing', + 'font-stretch', + 'font-style', + 'font-variant', + 'font-variant-ligatures', + 'font-variation-settings', + 'font-weight', + 'height', + 'hyphens', + 'icon', + 'image-orientation', + 'image-rendering', + 'image-resolution', + 'ime-mode', + 'inherit', + 'initial', + 'justify-content', + 'left', + 'letter-spacing', + 'line-height', + 'list-style', + 'list-style-image', + 'list-style-position', + 'list-style-type', + 'margin', + 'margin-bottom', + 'margin-left', + 'margin-right', + 'margin-top', + 'marks', + 'mask', + 'max-height', + 'max-width', + 'min-height', + 'min-width', + 'nav-down', + 'nav-index', + 'nav-left', + 'nav-right', + 'nav-up', + 'none', + 'normal', + 'object-fit', + 'object-position', + 'opacity', + 'order', + 'orphans', + 'outline', + 'outline-color', + 'outline-offset', + 'outline-style', + 'outline-width', + 'overflow', + 'overflow-wrap', + 'overflow-x', + 'overflow-y', + 'padding', + 'padding-bottom', + 'padding-left', + 'padding-right', + 'padding-top', + 'page-break-after', + 'page-break-before', + 'page-break-inside', + 'perspective', + 'perspective-origin', + 'pointer-events', + 'position', + 'quotes', + 'resize', + 'right', + 'src', // @font-face + 'tab-size', + 'table-layout', + 'text-align', + 'text-align-last', + 'text-decoration', + 'text-decoration-color', + 'text-decoration-line', + 'text-decoration-style', + 'text-indent', + 'text-overflow', + 'text-rendering', + 'text-shadow', + 'text-transform', + 'text-underline-position', + 'top', + 'transform', + 'transform-origin', + 'transform-style', + 'transition', + 'transition-delay', + 'transition-duration', + 'transition-property', + 'transition-timing-function', + 'unicode-bidi', + 'vertical-align', + 'visibility', + 'white-space', + 'widows', + 'width', + 'word-break', + 'word-spacing', + 'word-wrap', + 'z-index' + // reverse makes sure longer attributes `font-weight` are matched fully + // instead of getting false positives on say `font` + ].reverse(); + + // some grammars use them all as a single group + const PSEUDO_SELECTORS = PSEUDO_CLASSES.concat(PSEUDO_ELEMENTS); + + + // https://docs.oracle.com/javase/specs/jls/se15/html/jls-3.html#jls-3.10 + var decimalDigits = '[0-9](_*[0-9])*'; + var frac = `\\.(${decimalDigits})`; + var hexDigits = '[0-9a-fA-F](_*[0-9a-fA-F])*'; + var NUMERIC = { + className: 'number', + variants: [ + // DecimalFloatingPointLiteral + // including ExponentPart + { + begin: `(\\b(${decimalDigits})((${frac})|\\.)?|(${frac}))` + + `[eE][+-]?(${decimalDigits})[fFdD]?\\b` + }, + // excluding ExponentPart + { begin: `\\b(${decimalDigits})((${frac})[fFdD]?\\b|\\.([fFdD]\\b)?)` }, + { begin: `(${frac})[fFdD]?\\b` }, + { begin: `\\b(${decimalDigits})[fFdD]\\b` }, + + // HexadecimalFloatingPointLiteral + { + begin: `\\b0[xX]((${hexDigits})\\.?|(${hexDigits})?\\.(${hexDigits}))` + + `[pP][+-]?(${decimalDigits})[fFdD]?\\b` + }, + + // DecimalIntegerLiteral + { begin: '\\b(0|[1-9](_*[0-9])*)[lL]?\\b' }, + + // HexIntegerLiteral + { begin: `\\b0[xX](${hexDigits})[lL]?\\b` }, + + // OctalIntegerLiteral + { begin: '\\b0(_*[0-7])*[lL]?\\b' }, + + // BinaryIntegerLiteral + { begin: '\\b0[bB][01](_*[01])*[lL]?\\b' }, + ], + relevance: 0 + }; + + + /** + * Allows recursive regex expressions to a given depth + * + * ie: recurRegex("(abc~~~)", /~~~/g, 2) becomes: + * (abc(abc(abc))) + * + * @param {string} re + * @param {RegExp} substitution (should be a g mode regex) + * @param {number} depth + * @returns {string}`` + */ + function recurRegex(re, substitution, depth) { + if (depth === -1) return ""; + + return re.replace(substitution, _ => { + return recurRegex(re, substitution, depth - 1); + }); + } + + const IDENT_RE = '[A-Za-z$_][0-9A-Za-z$_]*'; + const KEYWORDS = [ + "as", // for exports + "in", + "of", + "if", + "for", + "while", + "finally", + "var", + "new", + "function", + "do", + "return", + "void", + "else", + "break", + "catch", + "instanceof", + "with", + "throw", + "case", + "default", + "try", + "switch", + "continue", + "typeof", + "delete", + "let", + "yield", + "const", + "class", + // JS handles these with a special rule + // "get", + // "set", + "debugger", + "async", + "await", + "static", + "import", + "from", + "export", + "extends" + ]; + const LITERALS = [ + "true", + "false", + "null", + "undefined", + "NaN", + "Infinity" + ]; + + const TYPES = [ + "Intl", + "DataView", + "Number", + "Math", + "Date", + "String", + "RegExp", + "Object", + "Function", + "Boolean", + "Error", + "Symbol", + "Set", + "Map", + "WeakSet", + "WeakMap", + "Proxy", + "Reflect", + "JSON", + "Promise", + "Float64Array", + "Int16Array", + "Int32Array", + "Int8Array", + "Uint16Array", + "Uint32Array", + "Float32Array", + "Array", + "Uint8Array", + "Uint8ClampedArray", + "ArrayBuffer", + "BigInt64Array", + "BigUint64Array", + "BigInt" + ]; + + const ERROR_TYPES = [ + "EvalError", + "InternalError", + "RangeError", + "ReferenceError", + "SyntaxError", + "TypeError", + "URIError" + ]; + + const BUILT_IN_GLOBALS = [ + "setInterval", + "setTimeout", + "clearInterval", + "clearTimeout", + + "require", + "exports", + + "eval", + "isFinite", + "isNaN", + "parseFloat", + "parseInt", + "decodeURI", + "decodeURIComponent", + "encodeURI", + "encodeURIComponent", + "escape", + "unescape" + ]; + + const BUILT_IN_VARIABLES = [ + "arguments", + "this", + "super", + "console", + "window", + "document", + "localStorage", + "module", + "global" // Node.js + ]; + + const BUILT_INS = [].concat( + BUILT_IN_GLOBALS, + TYPES, + ERROR_TYPES + ); + + /* + Language: JavaScript + Description: JavaScript (JS) is a lightweight, interpreted, or just-in-time compiled programming language with first-class functions. + Category: common, scripting, web + Website: https://developer.mozilla.org/en-US/docs/Web/JavaScript + */ + + /** @type LanguageFn */ + function javascript(hljs) { + /** + * Takes a string like "<Booger" and checks to see + * if we can find a matching "</Booger" later in the + * content. + * @param {RegExpMatchArray} match + * @param {{after:number}} param1 + */ + const hasClosingTag = (match, { after }) => { + const tag = "</" + match[0].slice(1); + const pos = match.input.indexOf(tag, after); + return pos !== -1; + }; + + const IDENT_RE$1 = IDENT_RE; + const FRAGMENT = { + begin: '<>', + end: '</>' + }; + const XML_TAG = { + begin: /<[A-Za-z0-9\\._:-]+/, + end: /\/[A-Za-z0-9\\._:-]+>|\/>/, + /** + * @param {RegExpMatchArray} match + * @param {CallbackResponse} response + */ + isTrulyOpeningTag: (match, response) => { + const afterMatchIndex = match[0].length + match.index; + const nextChar = match.input[afterMatchIndex]; + // nested type? + // HTML should not include another raw `<` inside a tag + // But a type might: `<Array<Array<number>>`, etc. + if (nextChar === "<") { + response.ignoreMatch(); + return; + } + // <something> + // This is now either a tag or a type. + if (nextChar === ">") { + // if we cannot find a matching closing tag, then we + // will ignore it + if (!hasClosingTag(match, { after: afterMatchIndex })) { + response.ignoreMatch(); + } + } + } + }; + const KEYWORDS$1 = { + $pattern: IDENT_RE, + keyword: KEYWORDS, + literal: LITERALS, + built_in: BUILT_INS, + "variable.language": BUILT_IN_VARIABLES + }; + + // https://tc39.es/ecma262/#sec-literals-numeric-literals + const decimalDigits = '[0-9](_?[0-9])*'; + const frac = `\\.(${decimalDigits})`; + // DecimalIntegerLiteral, including Annex B NonOctalDecimalIntegerLiteral + // https://tc39.es/ecma262/#sec-additional-syntax-numeric-literals + const decimalInteger = `0|[1-9](_?[0-9])*|0[0-7]*[89][0-9]*`; + const NUMBER = { + className: 'number', + variants: [ + // DecimalLiteral + { + begin: `(\\b(${decimalInteger})((${frac})|\\.)?|(${frac}))` + + `[eE][+-]?(${decimalDigits})\\b` + }, + { begin: `\\b(${decimalInteger})\\b((${frac})\\b|\\.)?|(${frac})\\b` }, + + // DecimalBigIntegerLiteral + { begin: `\\b(0|[1-9](_?[0-9])*)n\\b` }, + + // NonDecimalIntegerLiteral + { begin: "\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*n?\\b" }, + { begin: "\\b0[bB][0-1](_?[0-1])*n?\\b" }, + { begin: "\\b0[oO][0-7](_?[0-7])*n?\\b" }, + + // LegacyOctalIntegerLiteral (does not include underscore separators) + // https://tc39.es/ecma262/#sec-additional-syntax-numeric-literals + { begin: "\\b0[0-7]+n?\\b" }, + ], + relevance: 0 + }; + + const SUBST = { + className: 'subst', + begin: '\\$\\{', + end: '\\}', + keywords: KEYWORDS$1, + contains: [] // defined later + }; + const HTML_TEMPLATE = { + begin: 'html`', + end: '', + starts: { + end: '`', + returnEnd: false, + contains: [ + hljs.BACKSLASH_ESCAPE, + SUBST + ], + subLanguage: 'xml' + } + }; + const CSS_TEMPLATE = { + begin: 'css`', + end: '', + starts: { + end: '`', + returnEnd: false, + contains: [ + hljs.BACKSLASH_ESCAPE, + SUBST + ], + subLanguage: 'css' + } + }; + const TEMPLATE_STRING = { + className: 'string', + begin: '`', + end: '`', + contains: [ + hljs.BACKSLASH_ESCAPE, + SUBST + ] + }; + const JSDOC_COMMENT = hljs.COMMENT( + /\/\*\*(?!\/)/, + '\\*/', + { + relevance: 0, + contains: [ + { + begin: '(?=@[A-Za-z]+)', + relevance: 0, + contains: [ + { + className: 'doctag', + begin: '@[A-Za-z]+' + }, + { + className: 'type', + begin: '\\{', + end: '\\}', + excludeEnd: true, + excludeBegin: true, + relevance: 0 + }, + { + className: 'variable', + begin: IDENT_RE$1 + '(?=\\s*(-)|$)', + endsParent: true, + relevance: 0 + }, + // eat spaces (not newlines) so we can find + // types or variables + { + begin: /(?=[^\n])\s/, + relevance: 0 + } + ] + } + ] + } + ); + const COMMENT = { + className: "comment", + variants: [ + JSDOC_COMMENT, + hljs.C_BLOCK_COMMENT_MODE, + hljs.C_LINE_COMMENT_MODE + ] + }; + const SUBST_INTERNALS = [ + hljs.APOS_STRING_MODE, + hljs.QUOTE_STRING_MODE, + HTML_TEMPLATE, + CSS_TEMPLATE, + TEMPLATE_STRING, + NUMBER, + hljs.REGEXP_MODE + ]; + SUBST.contains = SUBST_INTERNALS + .concat({ + // we need to pair up {} inside our subst to prevent + // it from ending too early by matching another } + begin: /\{/, + end: /\}/, + keywords: KEYWORDS$1, + contains: [ + "self" + ].concat(SUBST_INTERNALS) + }); + const SUBST_AND_COMMENTS = [].concat(COMMENT, SUBST.contains); + const PARAMS_CONTAINS = SUBST_AND_COMMENTS.concat([ + // eat recursive parens in sub expressions + { + begin: /\(/, + end: /\)/, + keywords: KEYWORDS$1, + contains: ["self"].concat(SUBST_AND_COMMENTS) + } + ]); + const PARAMS = { + className: 'params', + begin: /\(/, + end: /\)/, + excludeBegin: true, + excludeEnd: true, + keywords: KEYWORDS$1, + contains: PARAMS_CONTAINS + }; + + // ES6 classes + const CLASS_OR_EXTENDS = { + variants: [ + { + match: [ + /class/, + /\s+/, + IDENT_RE$1 + ], + scope: { + 1: "keyword", + 3: "title.class" + } + }, + { + match: [ + /extends/, + /\s+/, + concat(IDENT_RE$1, "(", concat(/\./, IDENT_RE$1), ")*") + ], + scope: { + 1: "keyword", + 3: "title.class.inherited" + } + } + ] + }; + + const CLASS_REFERENCE = { + relevance: 0, + match: /\b[A-Z][a-z]+([A-Z][a-z]+)*/, + className: "title.class", + keywords: { + _: [ + // se we still get relevance credit for JS library classes + ...TYPES, + ...ERROR_TYPES + ] + } + }; + + const USE_STRICT = { + label: "use_strict", + className: 'meta', + relevance: 10, + begin: /^\s*['"]use (strict|asm)['"]/ + }; + + const FUNCTION_DEFINITION = { + variants: [ + { + match: [ + /function/, + /\s+/, + IDENT_RE$1, + /(?=\s*\()/ + ] + }, + // anonymous function + { + match: [ + /function/, + /\s*(?=\()/ + ] + } + ], + className: { + 1: "keyword", + 3: "title.function" + }, + label: "func.def", + contains: [PARAMS], + illegal: /%/ + }; + + const UPPER_CASE_CONSTANT = { + relevance: 0, + match: /\b[A-Z][A-Z_]+\b/, + className: "variable.constant" + }; + + function noneOf(list) { + return concat("(?!", list.join("|"), ")"); + } + + const FUNCTION_CALL = { + match: concat( + /\b/, + noneOf([ + ...BUILT_IN_GLOBALS, + "super" + ]), + IDENT_RE$1, lookahead(/\(/)), + className: "title.function", + relevance: 0 + }; + + const PROPERTY_ACCESS = { + begin: concat(/\./, lookahead( + concat(IDENT_RE$1, /(?![0-9A-Za-z$_(])/) + )), + end: IDENT_RE$1, + excludeBegin: true, + keywords: "prototype", + className: "property", + relevance: 0 + }; + + const GETTER_OR_SETTER = { + match: [ + /get|set/, + /\s+/, + IDENT_RE$1, + /(?=\()/ + ], + className: { + 1: "keyword", + 3: "title.function" + }, + contains: [ + { // eat to avoid empty params + begin: /\(\)/ + }, + PARAMS + ] + }; + + const FUNC_LEAD_IN_RE = '(\\(' + + '[^()]*(\\(' + + '[^()]*(\\(' + + '[^()]*' + + '\\)[^()]*)*' + + '\\)[^()]*)*' + + '\\)|' + hljs.UNDERSCORE_IDENT_RE + ')\\s*=>'; + + const FUNCTION_VARIABLE = { + match: [ + /const|var|let/, /\s+/, + IDENT_RE$1, /\s*/, + /=\s*/, + lookahead(FUNC_LEAD_IN_RE) + ], + className: { + 1: "keyword", + 3: "title.function" + }, + contains: [ + PARAMS + ] + }; + + return { + name: 'Javascript', + aliases: ['js', 'jsx', 'mjs', 'cjs'], + keywords: KEYWORDS$1, + // this will be extended by TypeScript + exports: { PARAMS_CONTAINS }, + illegal: /#(?![$_A-z])/, + contains: [ + hljs.SHEBANG({ + label: "shebang", + binary: "node", + relevance: 5 + }), + USE_STRICT, + hljs.APOS_STRING_MODE, + hljs.QUOTE_STRING_MODE, + HTML_TEMPLATE, + CSS_TEMPLATE, + TEMPLATE_STRING, + COMMENT, + NUMBER, + CLASS_REFERENCE, + { + className: 'attr', + begin: IDENT_RE$1 + lookahead(':'), + relevance: 0 + }, + FUNCTION_VARIABLE, + { // "value" container + begin: '(' + hljs.RE_STARTERS_RE + '|\\b(case|return|throw)\\b)\\s*', + keywords: 'return throw case', + relevance: 0, + contains: [ + COMMENT, + hljs.REGEXP_MODE, + { + className: 'function', + // we have to count the parens to make sure we actually have the + // correct bounding ( ) before the =>. There could be any number of + // sub-expressions inside also surrounded by parens. + begin: FUNC_LEAD_IN_RE, + returnBegin: true, + end: '\\s*=>', + contains: [ + { + className: 'params', + variants: [ + { + begin: hljs.UNDERSCORE_IDENT_RE, + relevance: 0 + }, + { + className: null, + begin: /\(\s*\)/, + skip: true + }, + { + begin: /\(/, + end: /\)/, + excludeBegin: true, + excludeEnd: true, + keywords: KEYWORDS$1, + contains: PARAMS_CONTAINS + } + ] + } + ] + }, + { // could be a comma delimited list of params to a function call + begin: /,/, + relevance: 0 + }, + { + match: /\s+/, + relevance: 0 + }, + { // JSX + variants: [ + { begin: FRAGMENT.begin, end: FRAGMENT.end }, + { + begin: XML_TAG.begin, + // we carefully check the opening tag to see if it truly + // is a tag and not a false positive + 'on:begin': XML_TAG.isTrulyOpeningTag, + end: XML_TAG.end + } + ], + subLanguage: 'xml', + contains: [ + { + begin: XML_TAG.begin, + end: XML_TAG.end, + skip: true, + contains: ['self'] + } + ] + } + ], + }, + FUNCTION_DEFINITION, + { + // prevent this from getting swallowed up by function + // since they appear "function like" + beginKeywords: "while if switch catch for" + }, + { + // we have to count the parens to make sure we actually have the correct + // bounding ( ). There could be any number of sub-expressions inside + // also surrounded by parens. + begin: '\\b(?!function)' + hljs.UNDERSCORE_IDENT_RE + + '\\(' + // first parens + '[^()]*(\\(' + + '[^()]*(\\(' + + '[^()]*' + + '\\)[^()]*)*' + + '\\)[^()]*)*' + + '\\)\\s*\\{', // end parens + returnBegin: true, + label: "func.def", + contains: [ + PARAMS, + hljs.inherit(hljs.TITLE_MODE, { begin: IDENT_RE$1, className: "title.function" }) + ] + }, + // catch ... so it won't trigger the property rule below + { + match: /\.\.\./, + relevance: 0 + }, + PROPERTY_ACCESS, + // hack: prevents detection of keywords in some circumstances + // .keyword() + // $keyword = x + { + match: '\\$' + IDENT_RE$1, + relevance: 0 + }, + { + match: [/\bconstructor(?=\s*\()/], + className: { 1: "title.function" }, + contains: [PARAMS] + }, + FUNCTION_CALL, + UPPER_CASE_CONSTANT, + CLASS_OR_EXTENDS, + GETTER_OR_SETTER, + { + match: /\$[(.]/ // relevance booster for a pattern common to JS libs: `$(something)` and `$.something` + } + ] + }; + } + + /* + Language: JSON + Description: JSON (JavaScript Object Notation) is a lightweight data-interchange format. + Author: Ivan Sagalaev <maniac@softwaremaniacs.org> + Website: http://www.json.org + Category: common, protocols, web + */ + + function json(hljs) { + const ATTRIBUTE = { + className: 'attr', + begin: /"(\\.|[^\\"\r\n])*"(?=\s*:)/, + relevance: 1.01 + }; + const PUNCTUATION = { + match: /[{}[\],:]/, + className: "punctuation", + relevance: 0 + }; + // normally we would rely on `keywords` for this but using a mode here allows us + // to use the very tight `illegal: \S` rule later to flag any other character + // as illegal indicating that despite looking like JSON we do not truly have + // JSON and thus improve false-positively greatly since JSON will try and claim + // all sorts of JSON looking stuff + const LITERALS = { + beginKeywords: [ + "true", + "false", + "null" + ].join(" ") + }; + + return { + name: 'JSON', + contains: [ + ATTRIBUTE, + PUNCTUATION, + hljs.QUOTE_STRING_MODE, + LITERALS, + hljs.C_NUMBER_MODE, + hljs.C_LINE_COMMENT_MODE, + hljs.C_BLOCK_COMMENT_MODE + ], + illegal: '\\S' + }; + } + + + /** @type LanguageFn */ + function xml(hljs) { + // Element names can contain letters, digits, hyphens, underscores, and periods + const TAG_NAME_RE = concat(/[A-Z_]/, optional(/[A-Z0-9_.-]*:/), /[A-Z0-9_.-]*/); + const XML_IDENT_RE = /[A-Za-z0-9._:-]+/; + const XML_ENTITIES = { + className: 'symbol', + begin: /&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/ + }; + const XML_META_KEYWORDS = { + begin: /\s/, + contains: [ + { + className: 'keyword', + begin: /#?[a-z_][a-z1-9_-]+/, + illegal: /\n/ + } + ] + }; + const XML_META_PAR_KEYWORDS = hljs.inherit(XML_META_KEYWORDS, { + begin: /\(/, + end: /\)/ + }); + const APOS_META_STRING_MODE = hljs.inherit(hljs.APOS_STRING_MODE, { + className: 'string' + }); + const QUOTE_META_STRING_MODE = hljs.inherit(hljs.QUOTE_STRING_MODE, { + className: 'string' + }); + const TAG_INTERNALS = { + endsWithParent: true, + illegal: /</, + relevance: 0, + contains: [ + { + className: 'attr', + begin: XML_IDENT_RE, + relevance: 0 + }, + { + begin: /=\s*/, + relevance: 0, + contains: [ + { + className: 'string', + endsParent: true, + variants: [ + { + begin: /"/, + end: /"/, + contains: [XML_ENTITIES] + }, + { + begin: /'/, + end: /'/, + contains: [XML_ENTITIES] + }, + { + begin: /[^\s"'=<>`]+/ + } + ] + } + ] + } + ] + }; + return { + name: 'HTML, XML', + aliases: [ + 'html', + 'xhtml', + 'rss', + 'atom', + 'xjb', + 'xsd', + 'xsl', + 'plist', + 'wsf', + 'svg' + ], + case_insensitive: true, + contains: [ + { + className: 'meta', + begin: /<![a-z]/, + end: />/, + relevance: 10, + contains: [ + XML_META_KEYWORDS, + QUOTE_META_STRING_MODE, + APOS_META_STRING_MODE, + XML_META_PAR_KEYWORDS, + { + begin: /\[/, + end: /\]/, + contains: [ + { + className: 'meta', + begin: /<![a-z]/, + end: />/, + contains: [ + XML_META_KEYWORDS, + XML_META_PAR_KEYWORDS, + QUOTE_META_STRING_MODE, + APOS_META_STRING_MODE + ] + } + ] + } + ] + }, + hljs.COMMENT( + /<!--/, + /-->/, + { + relevance: 10 + } + ), + { + begin: /<!\[CDATA\[/, + end: /\]\]>/, + relevance: 10 + }, + XML_ENTITIES, + { + className: 'meta', + begin: /<\?xml/, + end: /\?>/, + relevance: 10 + }, + { + className: 'tag', + /* + The lookahead pattern (?=...) ensures that 'begin' only matches + '<style' as a single word, followed by a whitespace or an + ending bracket. + */ + begin: /<style(?=\s|>)/, + end: />/, + keywords: { + name: 'style' + }, + contains: [TAG_INTERNALS], + starts: { + end: /<\/style>/, + returnEnd: true, + subLanguage: [ + 'css', + 'xml' + ] + } + }, + { + className: 'tag', + // See the comment in the <style tag about the lookahead pattern + begin: /<script(?=\s|>)/, + end: />/, + keywords: { + name: 'script' + }, + contains: [TAG_INTERNALS], + starts: { + end: /<\/script>/, + returnEnd: true, + subLanguage: [ + 'javascript', + 'handlebars', + 'xml' + ] + } + }, + // we need this for now for jSX + { + className: 'tag', + begin: /<>|<\/>/ + }, + // open tag + { + className: 'tag', + begin: concat( + /</, + lookahead(concat( + TAG_NAME_RE, + // <tag/> + // <tag> + // <tag ... + either(/\/>/, />/, /\s/) + )) + ), + end: /\/?>/, + contains: [ + { + className: 'name', + begin: TAG_NAME_RE, + relevance: 0, + starts: TAG_INTERNALS + } + ] + }, + // close tag + { + className: 'tag', + begin: concat( + /<\//, + lookahead(concat( + TAG_NAME_RE, />/ + )) + ), + contains: [ + { + className: 'name', + begin: TAG_NAME_RE, + relevance: 0 + }, + { + begin: />/, + relevance: 0, + endsParent: true + } + ] + } + ] + }; + } + + /* + Language: Markdown + Requires: xml.js + Author: John Crepezzi <john.crepezzi@gmail.com> + Website: https://daringfireball.net/projects/markdown/ + Category: common, markup + */ + + function markdown(hljs) { + const INLINE_HTML = { + begin: /<\/?[A-Za-z_]/, + end: '>', + subLanguage: 'xml', + relevance: 0 + }; + const HORIZONTAL_RULE = { + begin: '^[-\\*]{3,}', + end: '$' + }; + const CODE = { + className: 'code', + variants: [ + // TODO: fix to allow these to work with sublanguage also + { + begin: '(`{3,})[^`](.|\\n)*?\\1`*[ ]*' + }, + { + begin: '(~{3,})[^~](.|\\n)*?\\1~*[ ]*' + }, + // needed to allow markdown as a sublanguage to work + { + begin: '```', + end: '```+[ ]*$' + }, + { + begin: '~~~', + end: '~~~+[ ]*$' + }, + { + begin: '`.+?`' + }, + { + begin: '(?=^( {4}|\\t))', + // use contains to gobble up multiple lines to allow the block to be whatever size + // but only have a single open/close tag vs one per line + contains: [ + { + begin: '^( {4}|\\t)', + end: '(\\n)$' + } + ], + relevance: 0 + } + ] + }; + const LIST = { + className: 'bullet', + begin: '^[ \t]*([*+-]|(\\d+\\.))(?=\\s+)', + end: '\\s+', + excludeEnd: true + }; + const LINK_REFERENCE = { + begin: /^\[[^\n]+\]:/, + returnBegin: true, + contains: [ + { + className: 'symbol', + begin: /\[/, + end: /\]/, + excludeBegin: true, + excludeEnd: true + }, + { + className: 'link', + begin: /:\s*/, + end: /$/, + excludeBegin: true + } + ] + }; + const URL_SCHEME = /[A-Za-z][A-Za-z0-9+.-]*/; + const LINK = { + variants: [ + // too much like nested array access in so many languages + // to have any real relevance + { + begin: /\[.+?\]\[.*?\]/, + relevance: 0 + }, + // popular internet URLs + { + begin: /\[.+?\]\(((data|javascript|mailto):|(?:http|ftp)s?:\/\/).*?\)/, + relevance: 2 + }, + { + begin: concat(/\[.+?\]\(/, URL_SCHEME, /:\/\/.*?\)/), + relevance: 2 + }, + // relative urls + { + begin: /\[.+?\]\([./?&#].*?\)/, + relevance: 1 + }, + // whatever else, lower relevance (might not be a link at all) + { + begin: /\[.+?\]\(.*?\)/, + relevance: 0 + } + ], + returnBegin: true, + contains: [ + { + className: 'string', + relevance: 0, + begin: '\\[', + end: '\\]', + excludeBegin: true, + returnEnd: true + }, + { + className: 'link', + relevance: 0, + begin: '\\]\\(', + end: '\\)', + excludeBegin: true, + excludeEnd: true + }, + { + className: 'symbol', + relevance: 0, + begin: '\\]\\[', + end: '\\]', + excludeBegin: true, + excludeEnd: true + } + ] + }; + const BOLD = { + className: 'strong', + contains: [], // defined later + variants: [ + { + begin: /_{2}/, + end: /_{2}/ + }, + { + begin: /\*{2}/, + end: /\*{2}/ + } + ] + }; + const ITALIC = { + className: 'emphasis', + contains: [], // defined later + variants: [ + { + begin: /\*(?!\*)/, + end: /\*/ + }, + { + begin: /_(?!_)/, + end: /_/, + relevance: 0 + } + ] + }; + BOLD.contains.push(ITALIC); + ITALIC.contains.push(BOLD); + + let CONTAINABLE = [ + INLINE_HTML, + LINK + ]; + + BOLD.contains = BOLD.contains.concat(CONTAINABLE); + ITALIC.contains = ITALIC.contains.concat(CONTAINABLE); + + CONTAINABLE = CONTAINABLE.concat(BOLD, ITALIC); + + const HEADER = { + className: 'section', + variants: [ + { + begin: '^#{1,6}', + end: '$', + contains: CONTAINABLE + }, + { + begin: '(?=^.+?\\n[=-]{2,}$)', + contains: [ + { + begin: '^[=-]*$' + }, + { + begin: '^', + end: "\\n", + contains: CONTAINABLE + } + ] + } + ] + }; + + const BLOCKQUOTE = { + className: 'quote', + begin: '^>\\s+', + contains: CONTAINABLE, + end: '$' + }; + + return { + name: 'Markdown', + aliases: [ + 'md', + 'mkdown', + 'mkd' + ], + contains: [ + HEADER, + INLINE_HTML, + LIST, + BOLD, + ITALIC, + BLOCKQUOTE, + CODE, + HORIZONTAL_RULE, + LINK, + LINK_REFERENCE + ] + }; + } + + + /* + Language: Plain text + Author: Egor Rogov (e.rogov@postgrespro.ru) + Description: Plain text without any highlighting. + Category: common + */ + + function plaintext(hljs) { + return { + name: 'Plain text', + aliases: [ + 'text', + 'txt' + ], + disableAutodetect: true + }; + } + + + /* + Language: SCSS + Description: Scss is an extension of the syntax of CSS. + Author: Kurt Emch <kurt@kurtemch.com> + Website: https://sass-lang.com + Category: common, css, web + */ + + /** @type LanguageFn */ + function scss(hljs) { + const modes = MODES(hljs); + const PSEUDO_ELEMENTS$1 = PSEUDO_ELEMENTS; + const PSEUDO_CLASSES$1 = PSEUDO_CLASSES; + + const AT_IDENTIFIER = '@[a-z-]+'; // @font-face + const AT_MODIFIERS = "and or not only"; + const IDENT_RE = '[a-zA-Z-][a-zA-Z0-9_-]*'; + const VARIABLE = { + className: 'variable', + begin: '(\\$' + IDENT_RE + ')\\b' + }; + + return { + name: 'SCSS', + case_insensitive: true, + illegal: '[=/|\']', + contains: [ + hljs.C_LINE_COMMENT_MODE, + hljs.C_BLOCK_COMMENT_MODE, + { + className: 'selector-id', + begin: '#[A-Za-z0-9_-]+', + relevance: 0 + }, + { + className: 'selector-class', + begin: '\\.[A-Za-z0-9_-]+', + relevance: 0 + }, + modes.ATTRIBUTE_SELECTOR_MODE, + { + className: 'selector-tag', + begin: '\\b(' + TAGS.join('|') + ')\\b', + // was there, before, but why? + relevance: 0 + }, + { + className: 'selector-pseudo', + begin: ':(' + PSEUDO_CLASSES$1.join('|') + ')' + }, + { + className: 'selector-pseudo', + begin: '::(' + PSEUDO_ELEMENTS$1.join('|') + ')' + }, + VARIABLE, + { // pseudo-selector params + begin: /\(/, + end: /\)/, + contains: [modes.CSS_NUMBER_MODE] + }, + { + className: 'attribute', + begin: '\\b(' + ATTRIBUTES.join('|') + ')\\b' + }, + { + begin: '\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\b' + }, + { + begin: ':', + end: ';', + contains: [ + VARIABLE, + modes.HEXCOLOR, + modes.CSS_NUMBER_MODE, + hljs.QUOTE_STRING_MODE, + hljs.APOS_STRING_MODE, + modes.IMPORTANT + ] + }, + // matching these here allows us to treat them more like regular CSS + // rules so everything between the {} gets regular rule highlighting, + // which is what we want for page and font-face + { + begin: '@(page|font-face)', + keywords: { + $pattern: AT_IDENTIFIER, + keyword: '@page @font-face' + } + }, + { + begin: '@', + end: '[{;]', + returnBegin: true, + keywords: { + $pattern: /[a-z-]+/, + keyword: AT_MODIFIERS, + attribute: MEDIA_FEATURES.join(" ") + }, + contains: [ + { + begin: AT_IDENTIFIER, + className: "keyword" + }, + { + begin: /[a-z-]+(?=:)/, + className: "attribute" + }, + VARIABLE, + hljs.QUOTE_STRING_MODE, + hljs.APOS_STRING_MODE, + modes.HEXCOLOR, + modes.CSS_NUMBER_MODE + ] + } + ] + }; + } + + /* + Language: Shell Session + Requires: bash.js + Author: TSUYUSATO Kitsune <make.just.on@gmail.com> + Category: common + Audit: 2020 + */ + + /** @type LanguageFn */ + function shell(hljs) { + return { + name: 'Shell Session', + aliases: ['console', 'shellsession'], + contains: [ + { + className: 'meta', + // We cannot add \s (spaces) in the regular expression otherwise it will be too broad and produce unexpected result. + // For instance, in the following example, it would match "echo /path/to/home >" as a prompt: + // echo /path/to/home > t.exe + begin: /^\s{0,3}[/~\w\d[\]()@-]*[>%$#][ ]?/, + starts: { + end: /[^\\](?=\s*$)/, + subLanguage: 'bash' + } + } + ] + }; + } + + + const keywordWrapper = keyword => concat( + /\b/, + keyword, + /\w$/.test(keyword) ? /\b/ : /\B/ + ); + + // Keywords that require a leading dot. + const dotKeywords = [ + 'Protocol', // contextual + 'Type' // contextual + ].map(keywordWrapper); + + // Keywords that may have a leading dot. + const optionalDotKeywords = [ + 'init', + 'self' + ].map(keywordWrapper); + + // should register as keyword, not type + const keywordTypes = [ + 'Any', + 'Self' + ]; + + // Regular keywords and literals. + const keywords = [ + // strings below will be fed into the regular `keywords` engine while regex + // will result in additional modes being created to scan for those keywords to + // avoid conflicts with other rules + 'actor', + 'associatedtype', + 'async', + 'await', + /as\?/, // operator + /as!/, // operator + 'as', // operator + 'break', + 'case', + 'catch', + 'class', + 'continue', + 'convenience', // contextual + 'default', + 'defer', + 'deinit', + 'didSet', // contextual + 'do', + 'dynamic', // contextual + 'else', + 'enum', + 'extension', + 'fallthrough', + /fileprivate\(set\)/, + 'fileprivate', + 'final', // contextual + 'for', + 'func', + 'get', // contextual + 'guard', + 'if', + 'import', + 'indirect', // contextual + 'infix', // contextual + /init\?/, + /init!/, + 'inout', + /internal\(set\)/, + 'internal', + 'in', + 'is', // operator + 'lazy', // contextual + 'let', + 'mutating', // contextual + 'nonmutating', // contextual + /open\(set\)/, // contextual + 'open', // contextual + 'operator', + 'optional', // contextual + 'override', // contextual + 'postfix', // contextual + 'precedencegroup', + 'prefix', // contextual + /private\(set\)/, + 'private', + 'protocol', + /public\(set\)/, + 'public', + 'repeat', + 'required', // contextual + 'rethrows', + 'return', + 'set', // contextual + 'some', // contextual + 'static', + 'struct', + 'subscript', + 'super', + 'switch', + 'throws', + 'throw', + /try\?/, // operator + /try!/, // operator + 'try', // operator + 'typealias', + /unowned\(safe\)/, // contextual + /unowned\(unsafe\)/, // contextual + 'unowned', // contextual + 'var', + 'weak', // contextual + 'where', + 'while', + 'willSet' // contextual + ]; + + // NOTE: Contextual keywords are reserved only in specific contexts. + // Ideally, these should be matched using modes to avoid false positives. + + // Literals. + const literals = [ + 'false', + 'nil', + 'true' + ]; + + // Keywords used in precedence groups. + const precedencegroupKeywords = [ + 'assignment', + 'associativity', + 'higherThan', + 'left', + 'lowerThan', + 'none', + 'right' + ]; + + // Keywords that start with a number sign (#). + // #available is handled separately. + const numberSignKeywords = [ + '#colorLiteral', + '#column', + '#dsohandle', + '#else', + '#elseif', + '#endif', + '#error', + '#file', + '#fileID', + '#fileLiteral', + '#filePath', + '#function', + '#if', + '#imageLiteral', + '#keyPath', + '#line', + '#selector', + '#sourceLocation', + '#warn_unqualified_access', + '#warning' + ]; + + // Global functions in the Standard Library. + const builtIns$1 = [ + 'abs', + 'all', + 'any', + 'assert', + 'assertionFailure', + 'debugPrint', + 'dump', + 'fatalError', + 'getVaList', + 'isKnownUniquelyReferenced', + 'max', + 'min', + 'numericCast', + 'pointwiseMax', + 'pointwiseMin', + 'precondition', + 'preconditionFailure', + 'print', + 'readLine', + 'repeatElement', + 'sequence', + 'stride', + 'swap', + 'swift_unboxFromSwiftValueWithType', + 'transcode', + 'type', + 'unsafeBitCast', + 'unsafeDowncast', + 'withExtendedLifetime', + 'withUnsafeMutablePointer', + 'withUnsafePointer', + 'withVaList', + 'withoutActuallyEscaping', + 'zip' + ]; + + // Valid first characters for operators. + const operatorHead = either( + /[/=\-+!*%<>&|^~?]/, + /[\u00A1-\u00A7]/, + /[\u00A9\u00AB]/, + /[\u00AC\u00AE]/, + /[\u00B0\u00B1]/, + /[\u00B6\u00BB\u00BF\u00D7\u00F7]/, + /[\u2016-\u2017]/, + /[\u2020-\u2027]/, + /[\u2030-\u203E]/, + /[\u2041-\u2053]/, + /[\u2055-\u205E]/, + /[\u2190-\u23FF]/, + /[\u2500-\u2775]/, + /[\u2794-\u2BFF]/, + /[\u2E00-\u2E7F]/, + /[\u3001-\u3003]/, + /[\u3008-\u3020]/, + /[\u3030]/ + ); + + // Valid characters for operators. + const operatorCharacter = either( + operatorHead, + /[\u0300-\u036F]/, + /[\u1DC0-\u1DFF]/, + /[\u20D0-\u20FF]/, + /[\uFE00-\uFE0F]/, + /[\uFE20-\uFE2F]/ + // TODO: The following characters are also allowed, but the regex isn't supported yet. + // /[\u{E0100}-\u{E01EF}]/u + ); + + // Valid operator. + const operator = concat(operatorHead, operatorCharacter, '*'); + + // Valid first characters for identifiers. + const identifierHead = either( + /[a-zA-Z_]/, + /[\u00A8\u00AA\u00AD\u00AF\u00B2-\u00B5\u00B7-\u00BA]/, + /[\u00BC-\u00BE\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF]/, + /[\u0100-\u02FF\u0370-\u167F\u1681-\u180D\u180F-\u1DBF]/, + /[\u1E00-\u1FFF]/, + /[\u200B-\u200D\u202A-\u202E\u203F-\u2040\u2054\u2060-\u206F]/, + /[\u2070-\u20CF\u2100-\u218F\u2460-\u24FF\u2776-\u2793]/, + /[\u2C00-\u2DFF\u2E80-\u2FFF]/, + /[\u3004-\u3007\u3021-\u302F\u3031-\u303F\u3040-\uD7FF]/, + /[\uF900-\uFD3D\uFD40-\uFDCF\uFDF0-\uFE1F\uFE30-\uFE44]/, + /[\uFE47-\uFEFE\uFF00-\uFFFD]/ // Should be /[\uFE47-\uFFFD]/, but we have to exclude FEFF. + // The following characters are also allowed, but the regexes aren't supported yet. + // /[\u{10000}-\u{1FFFD}\u{20000-\u{2FFFD}\u{30000}-\u{3FFFD}\u{40000}-\u{4FFFD}]/u, + // /[\u{50000}-\u{5FFFD}\u{60000-\u{6FFFD}\u{70000}-\u{7FFFD}\u{80000}-\u{8FFFD}]/u, + // /[\u{90000}-\u{9FFFD}\u{A0000-\u{AFFFD}\u{B0000}-\u{BFFFD}\u{C0000}-\u{CFFFD}]/u, + // /[\u{D0000}-\u{DFFFD}\u{E0000-\u{EFFFD}]/u + ); + + // Valid characters for identifiers. + const identifierCharacter = either( + identifierHead, + /\d/, + /[\u0300-\u036F\u1DC0-\u1DFF\u20D0-\u20FF\uFE20-\uFE2F]/ + ); + + // Valid identifier. + const identifier = concat(identifierHead, identifierCharacter, '*'); + + // Valid type identifier. + const typeIdentifier = concat(/[A-Z]/, identifierCharacter, '*'); + + // Built-in attributes, which are highlighted as keywords. + // @available is handled separately. + const keywordAttributes = [ + 'autoclosure', + concat(/convention\(/, either('swift', 'block', 'c'), /\)/), + 'discardableResult', + 'dynamicCallable', + 'dynamicMemberLookup', + 'escaping', + 'frozen', + 'GKInspectable', + 'IBAction', + 'IBDesignable', + 'IBInspectable', + 'IBOutlet', + 'IBSegueAction', + 'inlinable', + 'main', + 'nonobjc', + 'NSApplicationMain', + 'NSCopying', + 'NSManaged', + concat(/objc\(/, identifier, /\)/), + 'objc', + 'objcMembers', + 'propertyWrapper', + 'requires_stored_property_inits', + 'resultBuilder', + 'testable', + 'UIApplicationMain', + 'unknown', + 'usableFromInline' + ]; + + // Contextual keywords used in @available and #available. + const availabilityKeywords = [ + 'iOS', + 'iOSApplicationExtension', + 'macOS', + 'macOSApplicationExtension', + 'macCatalyst', + 'macCatalystApplicationExtension', + 'watchOS', + 'watchOSApplicationExtension', + 'tvOS', + 'tvOSApplicationExtension', + 'swift' + ]; + + + /* + Language: TypeScript + Author: Panu Horsmalahti <panu.horsmalahti@iki.fi> + Contributors: Ike Ku <dempfi@yahoo.com> + Description: TypeScript is a strict superset of JavaScript + Website: https://www.typescriptlang.org + Category: common, scripting + */ + + /** @type LanguageFn */ + function typescript(hljs) { + const IDENT_RE$1 = IDENT_RE; + const NAMESPACE = { + beginKeywords: 'namespace', end: /\{/, excludeEnd: true + }; + const INTERFACE = { + beginKeywords: 'interface', end: /\{/, excludeEnd: true, + keywords: 'interface extends' + }; + const USE_STRICT = { + className: 'meta', + relevance: 10, + begin: /^\s*['"]use strict['"]/ + }; + const TYPES = [ + "any", + "void", + "number", + "boolean", + "string", + "object", + "never", + "enum" + ]; + const TS_SPECIFIC_KEYWORDS = [ + "type", + "namespace", + "typedef", + "interface", + "public", + "private", + "protected", + "implements", + "declare", + "abstract", + "readonly" + ]; + const KEYWORDS$1 = { + $pattern: IDENT_RE, + keyword: KEYWORDS.concat(TS_SPECIFIC_KEYWORDS), + literal: LITERALS, + built_in: BUILT_INS.concat(TYPES), + "variable.language": BUILT_IN_VARIABLES + }; + const DECORATOR = { + className: 'meta', + begin: '@' + IDENT_RE$1, + }; + + const swapMode = (mode, label, replacement) => { + const indx = mode.contains.findIndex(m => m.label === label); + if (indx === -1) { throw new Error("can not find mode to replace"); } + mode.contains.splice(indx, 1, replacement); + }; + + const tsLanguage = javascript(hljs); + + // this should update anywhere keywords is used since + // it will be the same actual JS object + Object.assign(tsLanguage.keywords, KEYWORDS$1); + + tsLanguage.exports.PARAMS_CONTAINS.push(DECORATOR); + tsLanguage.contains = tsLanguage.contains.concat([ + DECORATOR, + NAMESPACE, + INTERFACE, + ]); + + // TS gets a simpler shebang rule than JS + swapMode(tsLanguage, "shebang", hljs.SHEBANG()); + // JS use strict rule purposely excludes `asm` which makes no sense + swapMode(tsLanguage, "use_strict", USE_STRICT); + + const functionDeclaration = tsLanguage.contains.find(m => m.label === "func.def"); + functionDeclaration.relevance = 0; // () => {} is more typical in TypeScript + + Object.assign(tsLanguage, { + name: 'TypeScript', + aliases: ['ts', 'tsx'] + }); + + return tsLanguage; + } + + + /* + Language: YAML + Description: Yet Another Markdown Language + Author: Stefan Wienert <stwienert@gmail.com> + Contributors: Carl Baxter <carl@cbax.tech> + Requires: ruby.js + Website: https://yaml.org + Category: common, config + */ + function yaml(hljs) { + const LITERALS = 'true false yes no null'; + + // YAML spec allows non-reserved URI characters in tags. + const URI_CHARACTERS = '[\\w#;/?:@&=+$,.~*\'()[\\]]+'; + + // Define keys as starting with a word character + // ...containing word chars, spaces, colons, forward-slashes, hyphens and periods + // ...and ending with a colon followed immediately by a space, tab or newline. + // The YAML spec allows for much more than this, but this covers most use-cases. + const KEY = { + className: 'attr', + variants: [ + { + begin: '\\w[\\w :\\/.-]*:(?=[ \t]|$)' + }, + { // double quoted keys + begin: '"\\w[\\w :\\/.-]*":(?=[ \t]|$)' + }, + { // single quoted keys + begin: '\'\\w[\\w :\\/.-]*\':(?=[ \t]|$)' + } + ] + }; + + const TEMPLATE_VARIABLES = { + className: 'template-variable', + variants: [ + { // jinja templates Ansible + begin: /\{\{/, + end: /\}\}/ + }, + { // Ruby i18n + begin: /%\{/, + end: /\}/ + } + ] + }; + const STRING = { + className: 'string', + relevance: 0, + variants: [ + { + begin: /'/, + end: /'/ + }, + { + begin: /"/, + end: /"/ + }, + { + begin: /\S+/ + } + ], + contains: [ + hljs.BACKSLASH_ESCAPE, + TEMPLATE_VARIABLES + ] + }; + + // Strings inside of value containers (objects) can't contain braces, + // brackets, or commas + const CONTAINER_STRING = hljs.inherit(STRING, { + variants: [ + { + begin: /'/, + end: /'/ + }, + { + begin: /"/, + end: /"/ + }, + { + begin: /[^\s,{}[\]]+/ + } + ] + }); + + const DATE_RE = '[0-9]{4}(-[0-9][0-9]){0,2}'; + const TIME_RE = '([Tt \\t][0-9][0-9]?(:[0-9][0-9]){2})?'; + const FRACTION_RE = '(\\.[0-9]*)?'; + const ZONE_RE = '([ \\t])*(Z|[-+][0-9][0-9]?(:[0-9][0-9])?)?'; + const TIMESTAMP = { + className: 'number', + begin: '\\b' + DATE_RE + TIME_RE + FRACTION_RE + ZONE_RE + '\\b' + }; + + const VALUE_CONTAINER = { + end: ',', + endsWithParent: true, + excludeEnd: true, + keywords: LITERALS, + relevance: 0 + }; + const OBJECT = { + begin: /\{/, + end: /\}/, + contains: [VALUE_CONTAINER], + illegal: '\\n', + relevance: 0 + }; + const ARRAY = { + begin: '\\[', + end: '\\]', + contains: [VALUE_CONTAINER], + illegal: '\\n', + relevance: 0 + }; + + const MODES = [ + KEY, + { + className: 'meta', + begin: '^---\\s*$', + relevance: 10 + }, + { // multi line string + // Blocks start with a | or > followed by a newline + // + // Indentation of subsequent lines must be the same to + // be considered part of the block + className: 'string', + begin: '[\\|>]([1-9]?[+-])?[ ]*\\n( +)[^ ][^\\n]*\\n(\\2[^\\n]+\\n?)*' + }, + { // Ruby/Rails erb + begin: '<%[%=-]?', + end: '[%-]?%>', + subLanguage: 'ruby', + excludeBegin: true, + excludeEnd: true, + relevance: 0 + }, + { // named tags + className: 'type', + begin: '!\\w+!' + URI_CHARACTERS + }, + // https://yaml.org/spec/1.2/spec.html#id2784064 + { // verbatim tags + className: 'type', + begin: '!<' + URI_CHARACTERS + ">" + }, + { // primary tags + className: 'type', + begin: '!' + URI_CHARACTERS + }, + { // secondary tags + className: 'type', + begin: '!!' + URI_CHARACTERS + }, + { // fragment id &ref + className: 'meta', + begin: '&' + hljs.UNDERSCORE_IDENT_RE + '$' + }, + { // fragment reference *ref + className: 'meta', + begin: '\\*' + hljs.UNDERSCORE_IDENT_RE + '$' + }, + { // array listing + className: 'bullet', + // TODO: remove |$ hack when we have proper look-ahead support + begin: '-(?=[ ]|$)', + relevance: 0 + }, + hljs.HASH_COMMENT_MODE, + { + beginKeywords: LITERALS, + keywords: { + literal: LITERALS + } + }, + TIMESTAMP, + // numbers are any valid C-style number that + // sit isolated from other words + { + className: 'number', + begin: hljs.C_NUMBER_RE + '\\b', + relevance: 0 + }, + OBJECT, + ARRAY, + STRING + ]; + + const VALUE_MODES = [...MODES]; + VALUE_MODES.pop(); + VALUE_MODES.push(CONTAINER_STRING); + VALUE_CONTAINER.contains = VALUE_MODES; + + return { + name: 'YAML', + case_insensitive: true, + aliases: ['yml'], + contains: MODES + }; + } + + var builtIns = /*#__PURE__*/Object.freeze({ + __proto__: null, + grmr_bash: bash, + grmr_scss: scss, + grmr_css: scss, + grmr_javascript: javascript, + grmr_json: json, + grmr_json5: json, + grmr_xml: xml, + grmr_markdown: markdown, + grmr_plaintext: plaintext, + grmr_shell: shell, + grmr_typescript: typescript, + grmr_yaml: yaml + }); + + const hljs = HighlightJS; + + for (const key of Object.keys(builtIns)) { + const languageName = key.replace("grmr_", ""); + hljs.registerLanguage(languageName, builtIns[key]); + } + + return hljs; + +}()); +if (typeof exports === 'object' && typeof module !== 'undefined') { module.exports = hljs; } diff --git a/doc/scripts/third-party/hljs.js b/doc/scripts/third-party/hljs.js new file mode 100644 index 0000000000000000000000000000000000000000..1afd88c789f0192dbf4027c3df80dab1530acb51 --- /dev/null +++ b/doc/scripts/third-party/hljs.js @@ -0,0 +1 @@ +var hljs=function(){"use strict";var e={exports:{}};function t(n){return n instanceof Map?n.clear=n.delete=n.set=function(){throw new Error("map is read-only")}:n instanceof Set&&(n.add=n.clear=n.delete=function(){throw new Error("set is read-only")}),Object.freeze(n),Object.getOwnPropertyNames(n).forEach(function(e){e=n[e];"object"!=typeof e||Object.isFrozen(e)||t(e)}),n}e.exports=t,e.exports.default=t;var z=e.exports;class D{constructor(e){void 0===e.data&&(e.data={}),this.data=e.data,this.isMatchIgnored=!1}ignoreMatch(){this.isMatchIgnored=!0}}function n(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function l(e,...n){const t=Object.create(null);for(const a in e)t[a]=e[a];return n.forEach(function(e){for(const n in e)t[n]=e[n]}),t}const a=e=>!!e.kind;class T{constructor(e,n){this.buffer="",this.classPrefix=n.classPrefix,e.walk(this)}addText(e){this.buffer+=n(e)}openNode(n){if(a(n)){let e=n.kind;e=n.sublanguage?"language-"+e:((e,{prefix:n})=>{if(e.includes(".")){const t=e.split(".");return[""+n+t.shift(),...t.map((e,n)=>""+e+"_".repeat(n+1))].join(" ")}return""+n+e})(e,{prefix:this.classPrefix}),this.span(e)}}closeNode(e){a(e)&&(this.buffer+="</span>")}value(){return this.buffer}span(e){this.buffer+=`<span class="${e}">`}}class i{constructor(){this.rootNode={children:[]},this.stack=[this.rootNode]}get top(){return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){this.top.children.push(e)}openNode(e){e={kind:e,children:[]};this.add(e),this.stack.push(e)}closeNode(){if(1<this.stack.length)return this.stack.pop()}closeAllNodes(){for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)}walk(e){return this.constructor._walk(e,this.rootNode)}static _walk(n,e){return"string"==typeof e?n.addText(e):e.children&&(n.openNode(e),e.children.forEach(e=>this._walk(n,e)),n.closeNode(e)),n}static _collapse(e){"string"!=typeof e&&e.children&&(e.children.every(e=>"string"==typeof e)?e.children=[e.children.join("")]:e.children.forEach(e=>{i._collapse(e)}))}}class L extends i{constructor(e){super(),this.options=e}addKeyword(e,n){""!==e&&(this.openNode(n),this.addText(e),this.closeNode())}addText(e){""!==e&&this.add(e)}addSublanguage(e,n){const t=e.root;t.kind=n,t.sublanguage=!0,this.add(t)}toHTML(){const e=new T(this,this.options);return e.value()}finalize(){return!0}}function c(e){return e?"string"==typeof e?e:e.source:null}function k(e){return O("(?=",e,")")}function O(...e){return e.map(e=>c(e)).join("")}function d(...e){var n,t="object"==typeof(n=(t=e)[t.length-1])&&n.constructor===Object?(t.splice(t.length-1,1),n):{};return"("+(t.capture?"":"?:")+e.map(e=>c(e)).join("|")+")"}function u(e){return new RegExp(e.toString()+"|").exec("").length-1}const I=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./;function g(e,{joinWith:n}){let r=0;return e.map(e=>{var n=r+=1;let t=c(e),a="";for(;0<t.length;){var i=I.exec(t);if(!i){a+=t;break}a+=t.substring(0,i.index),t=t.substring(i.index+i[0].length),"\\"===i[0][0]&&i[1]?a+="\\"+String(Number(i[1])+n):(a+=i[0],"("===i[0]&&r++)}return a}).map(e=>`(${e})`).join(n)}function r(e,n,t={}){const a=l({scope:"comment",begin:e,end:n,contains:[]},t);return a.contains.push({scope:"doctag",begin:"[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)",end:/(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,excludeBegin:!0,relevance:0}),e=d("I","a","is","so","us","to","at","if","in","it","on",/[A-Za-z]+['](d|ve|re|ll|t|s|n)/,/[A-Za-z]+[-][a-z]+/,/[A-Za-z][a-z]{2,}/),a.contains.push({begin:O(/[ ]+/,"(",e,/[.]?[:]?([.][ ]|[ ])/,"){3}")}),a}var e="[a-zA-Z]\\w*",s="[a-zA-Z_]\\w*",o="\\b\\d+(\\.\\d+)?",b="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",h="\\b(0b[01]+)",p={begin:"\\\\[\\s\\S]",relevance:0},m={scope:"string",begin:"'",end:"'",illegal:"\\n",contains:[p]},f={scope:"string",begin:'"',end:'"',illegal:"\\n",contains:[p]},E=r("//","$"),v=r("/\\*","\\*/"),w=r("#","$"),y=Object.freeze({__proto__:null,MATCH_NOTHING_RE:/\b\B/,IDENT_RE:e,UNDERSCORE_IDENT_RE:s,NUMBER_RE:o,C_NUMBER_RE:b,BINARY_NUMBER_RE:h,RE_STARTERS_RE:"!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",SHEBANG:(e={})=>{var n=/^#![ ]*\//;return e.binary&&(e.begin=O(n,/.*\b/,e.binary,/\b.*/)),l({scope:"meta",begin:n,end:/$/,relevance:0,"on:begin":(e,n)=>{0!==e.index&&n.ignoreMatch()}},e)},BACKSLASH_ESCAPE:p,APOS_STRING_MODE:m,QUOTE_STRING_MODE:f,PHRASAL_WORDS_MODE:{begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},COMMENT:r,C_LINE_COMMENT_MODE:E,C_BLOCK_COMMENT_MODE:v,HASH_COMMENT_MODE:w,NUMBER_MODE:{scope:"number",begin:o,relevance:0},C_NUMBER_MODE:{scope:"number",begin:b,relevance:0},BINARY_NUMBER_MODE:{scope:"number",begin:h,relevance:0},REGEXP_MODE:{begin:/(?=\/[^/\n]*\/)/,contains:[{scope:"regexp",begin:/\//,end:/\/[gimuy]*/,illegal:/\n/,contains:[p,{begin:/\[/,end:/\]/,relevance:0,contains:[p]}]}]},TITLE_MODE:{scope:"title",begin:e,relevance:0},UNDERSCORE_TITLE_MODE:{scope:"title",begin:s,relevance:0},METHOD_GUARD:{begin:"\\.\\s*"+s,relevance:0},END_SAME_AS_BEGIN:function(e){return Object.assign(e,{"on:begin":(e,n)=>{n.data._beginMatch=e[1]},"on:end":(e,n)=>{n.data._beginMatch!==e[1]&&n.ignoreMatch()}})}});function $(e,n){"."===e.input[e.index-1]&&n.ignoreMatch()}function P(e,n){void 0!==e.className&&(e.scope=e.className,delete e.className)}function U(e,n){n&&e.beginKeywords&&(e.begin="\\b("+e.beginKeywords.split(" ").join("|")+")(?!\\.)(?=\\b|\\s)",e.__beforeBegin=$,e.keywords=e.keywords||e.beginKeywords,delete e.beginKeywords,void 0===e.relevance&&(e.relevance=0))}function H(e,n){Array.isArray(e.illegal)&&(e.illegal=d(...e.illegal))}function Z(e,n){if(e.match){if(e.begin||e.end)throw new Error("begin & end are not supported with match");e.begin=e.match,delete e.match}}function G(e,n){void 0===e.relevance&&(e.relevance=1)}const K=(n,e)=>{if(n.beforeMatch){if(n.starts)throw new Error("beforeMatch cannot be used with starts");const t=Object.assign({},n);Object.keys(n).forEach(e=>{delete n[e]}),n.keywords=t.keywords,n.begin=O(t.beforeMatch,k(t.begin)),n.starts={relevance:0,contains:[Object.assign(t,{endsParent:!0})]},n.relevance=0,delete t.beforeMatch}},X=["of","and","for","in","not","or","if","then","parent","list","value"],W="keyword";function _(n,t,e=W){const a=Object.create(null);return"string"==typeof n?i(e,n.split(" ")):Array.isArray(n)?i(e,n):Object.keys(n).forEach(function(e){Object.assign(a,_(n[e],t,e))}),a;function i(n,e){(e=t?e.map(e=>e.toLowerCase()):e).forEach(function(e){e=e.split("|");a[e[0]]=[n,function(e,n){if(n)return Number(n);return function(e){return X.includes(e.toLowerCase())}(e)?0:1}(e[0],e[1])]})}}const N={},j=e=>{console.error(e)},x=(e,...n)=>{console.log("WARN: "+e,...n)},A=(e,n)=>{N[e+"/"+n]||(console.log(`Deprecated as of ${e}. `+n),N[e+"/"+n]=!0)},S=new Error;function M(e,n,{key:t}){let a=0;var i=e[t];const r={},s={};for(let e=1;e<=n.length;e++)s[e+a]=i[e],r[e+a]=!0,a+=u(n[e-1]);e[t]=s,e[t]._emit=r,e[t]._multi=!0}function q(e){(n=e).scope&&"object"==typeof n.scope&&null!==n.scope&&(n.beginScope=n.scope,delete n.scope),"string"==typeof e.beginScope&&(e.beginScope={_wrap:e.beginScope}),"string"==typeof e.endScope&&(e.endScope={_wrap:e.endScope});var n=e;if(Array.isArray(n.begin)){if(n.skip||n.excludeBegin||n.returnBegin)throw j("skip, excludeBegin, returnBegin not compatible with beginScope: {}"),S;if("object"!=typeof n.beginScope||null===n.beginScope)throw j("beginScope must be object"),S;M(n,n.begin,{key:"beginScope"}),n.begin=g(n.begin,{joinWith:""})}n=e;if(Array.isArray(n.end)){if(n.skip||n.excludeEnd||n.returnEnd)throw j("skip, excludeEnd, returnEnd not compatible with endScope: {}"),S;if("object"!=typeof n.endScope||null===n.endScope)throw j("endScope must be object"),S;M(n,n.end,{key:"endScope"}),n.end=g(n.end,{joinWith:""})}}function Q(r){function s(e,n){return new RegExp(c(e),"m"+(r.case_insensitive?"i":"")+(n?"g":""))}class n{constructor(){this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0}addRule(e,n){n.position=this.position++,this.matchIndexes[this.matchAt]=n,this.regexes.push([n,e]),this.matchAt+=u(e)+1}compile(){0===this.regexes.length&&(this.exec=()=>null);var e=this.regexes.map(e=>e[1]);this.matcherRe=s(g(e,{joinWith:"|"}),!0),this.lastIndex=0}exec(e){this.matcherRe.lastIndex=this.lastIndex;const n=this.matcherRe.exec(e);if(!n)return null;var e=n.findIndex((e,n)=>0<n&&void 0!==e),t=this.matchIndexes[e];return n.splice(0,e),Object.assign(n,t)}}class o{constructor(){this.rules=[],this.multiRegexes=[],this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(e){if(this.multiRegexes[e])return this.multiRegexes[e];const t=new n;return this.rules.slice(e).forEach(([e,n])=>t.addRule(e,n)),t.compile(),this.multiRegexes[e]=t}resumingScanAtSamePosition(){return 0!==this.regexIndex}considerAll(){this.regexIndex=0}addRule(e,n){this.rules.push([e,n]),"begin"===n.type&&this.count++}exec(e){const n=this.getMatcher(this.regexIndex);n.lastIndex=this.lastIndex;let t=n.exec(e);if(this.resumingScanAtSamePosition()&&(!t||t.index!==this.lastIndex)){const a=this.getMatcher(0);a.lastIndex=this.lastIndex+1,t=a.exec(e)}return t&&(this.regexIndex+=t.position+1,this.regexIndex===this.count&&this.considerAll()),t}}if(r.compilerExtensions||(r.compilerExtensions=[]),r.contains&&r.contains.includes("self"))throw new Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.");return r.classNameAliases=l(r.classNameAliases||{}),function n(t,a){const i=t;if(!t.isCompiled){[P,Z,q,K].forEach(e=>e(t,a)),r.compilerExtensions.forEach(e=>e(t,a)),t.__beforeBegin=null,[U,H,G].forEach(e=>e(t,a)),t.isCompiled=!0;let e=null;"object"==typeof t.keywords&&t.keywords.$pattern&&(t.keywords=Object.assign({},t.keywords),e=t.keywords.$pattern,delete t.keywords.$pattern),e=e||/\w+/,t.keywords&&(t.keywords=_(t.keywords,r.case_insensitive)),i.keywordPatternRe=s(e,!0),a&&(t.begin||(t.begin=/\B|\b/),i.beginRe=s(t.begin),t.end||t.endsWithParent||(t.end=/\B|\b/),t.end&&(i.endRe=s(t.end)),i.terminatorEnd=c(t.end)||"",t.endsWithParent&&a.terminatorEnd&&(i.terminatorEnd+=(t.end?"|":"")+a.terminatorEnd)),t.illegal&&(i.illegalRe=s(t.illegal)),t.contains||(t.contains=[]),t.contains=[].concat(...t.contains.map(function(e){var n="self"===e?t:e;return n.variants&&!n.cachedVariants&&(n.cachedVariants=n.variants.map(function(e){return l(n,{variants:null},e)})),n.cachedVariants||(function e(n){return!!n&&(n.endsWithParent||e(n.starts))}(n)?l(n,{starts:n.starts?l(n.starts):null}):Object.isFrozen(n)?l(n):n)})),t.contains.forEach(function(e){n(e,i)}),t.starts&&n(t.starts,a),i.matcher=function(e){const n=new o;return e.contains.forEach(e=>n.addRule(e.begin,{rule:e,type:"begin"})),e.terminatorEnd&&n.addRule(e.terminatorEnd,{type:"end"}),e.illegal&&n.addRule(e.illegal,{type:"illegal"}),n}(i)}return i}(r)}const C=n,F=l,J=Symbol("nomatch");m=function(a){const O=Object.create(null),r=Object.create(null),i=[];let S=!0;const M="Could not find the language '{}', did you forget to load/include a language module?",s={disableAutodetect:!0,name:"Plain text",contains:[]};let R={ignoreUnescapedHTML:!1,noHighlightRe:/^(no-?highlight)$/i,languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-",cssSelector:"pre code",languages:null,__emitter:L};function o(e){return R.noHighlightRe.test(e)}function l(e,n,t,a){let i="",r="";"object"==typeof n?(i=e,t=n.ignoreIllegals,r=n.language,a=void 0):(A("10.7.0","highlight(lang, code, ...args) has been deprecated."),A("10.7.0","Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277"),r=e,i=n),void 0===t&&(t=!0);e={code:i,language:r};u("before:highlight",e);const s=e.result||B(e.language,e.code,t,a);return s.code=e.code,u("after:highlight",s),s}function B(r,s,o,e){const l=Object.create(null);function c(){if(m.keywords){let e=0,n=(m.keywordPatternRe.lastIndex=0,m.keywordPatternRe.exec(v)),t="";for(;n;){t+=v.substring(e,n.index);var a=p.case_insensitive?n[0].toLowerCase():n[0],i=m.keywords[a];if(i){const[r,s]=i;E.addText(t),t="",l[a]=(l[a]||0)+1,l[a]<=7&&(w+=s),r.startsWith("_")?t+=n[0]:(i=p.classNameAliases[r]||r,E.addKeyword(n[0],i))}else t+=n[0];e=m.keywordPatternRe.lastIndex,n=m.keywordPatternRe.exec(v)}t+=v.substr(e),E.addText(t)}else E.addText(v)}function d(){(null!=m.subLanguage?function(){if(""!==v){let e=null;if("string"==typeof m.subLanguage){if(!O[m.subLanguage])return E.addText(v);e=B(m.subLanguage,v,!0,f[m.subLanguage]),f[m.subLanguage]=e._top}else e=T(v,m.subLanguage.length?m.subLanguage:null);0<m.relevance&&(w+=e.relevance),E.addSublanguage(e._emitter,e.language)}}:c)(),v=""}function i(e,n){let t=1;for(;void 0!==n[t];){var a,i;e._emit[t]?(a=p.classNameAliases[e[t]]||e[t],i=n[t],a?E.addKeyword(i,a):(v=i,c(),v=""),t++):t++}}function u(e,n){e.scope&&"string"==typeof e.scope&&E.openNode(p.classNameAliases[e.scope]||e.scope),e.beginScope&&(e.beginScope._wrap?(E.addKeyword(v,p.classNameAliases[e.beginScope._wrap]||e.beginScope._wrap),v=""):e.beginScope._multi&&(i(e.beginScope,n),v="")),m=Object.create(e,{parent:{value:m}})}function g(e){var n,t=e[0],a=e.rule,i=new D(a);for(const r of[a.__beforeBegin,a["on:begin"]])if(r&&(r(e,i),i.isMatchIgnored))return n=t,0===m.matcher.regexIndex?(v+=n[0],1):(N=!0,0);return a.skip?v+=t:(a.excludeBegin&&(v+=t),d(),a.returnBegin||a.excludeBegin||(v=t)),u(a,e),a.returnBegin?0:t.length}function b(e){var n=e[0],t=s.substr(e.index),a=function e(n,t,a){r=n.endRe,s=a;let i=(r=r&&r.exec(s))&&0===r.index;var r,s;if(i&&(n["on:end"]&&(s=new D(n),n["on:end"](t,s),s.isMatchIgnored&&(i=!1)),i)){for(;n.endsParent&&n.parent;)n=n.parent;return n}if(n.endsWithParent)return e(n.parent,t,a)}(m,e,t);if(!a)return J;t=m;for(m.endScope&&m.endScope._wrap?(d(),E.addKeyword(n,m.endScope._wrap)):m.endScope&&m.endScope._multi?(d(),i(m.endScope,e)):t.skip?v+=n:(t.returnEnd||t.excludeEnd||(v+=n),d(),t.excludeEnd&&(v=n));m.scope&&!m.isMultiClass&&E.closeNode(),m.skip||m.subLanguage||(w+=m.relevance),(m=m.parent)!==a.parent;);return a.starts&&u(a.starts,e),t.returnEnd?0:n.length}let h={};function n(e,n){var t=n&&n[0];if(v+=e,null==t)return d(),0;if("begin"===h.type&&"end"===n.type&&h.index===n.index&&""===t){if(v+=s.slice(n.index,n.index+1),S)return 1;{const a=new Error(`0 width match regex (${r})`);throw a.languageName=r,a.badRule=h.rule,a}}if("begin"===(h=n).type)return g(n);if("illegal"===n.type&&!o){const i=new Error('Illegal lexeme "'+t+'" for mode "'+(m.scope||"<unnamed>")+'"');throw i.mode=m,i}if("end"===n.type){e=b(n);if(e!==J)return e}if("illegal"===n.type&&""===t)return 1;if(1e5<_&&_>3*n.index)throw new Error("potential infinite loop, way more iterations than matches");return v+=t,t.length}const p=I(r);if(!p)throw j(M.replace("{}",r)),new Error('Unknown language: "'+r+'"');var t=Q(p);let a="",m=e||t;const f={},E=new R.__emitter(R);{const k=[];for(let e=m;e!==p;e=e.parent)e.scope&&k.unshift(e.scope);k.forEach(e=>E.openNode(e))}let v="",w=0,y=0,_=0,N=!1;try{for(m.matcher.considerAll();;){_++,N?N=!1:m.matcher.considerAll(),m.matcher.lastIndex=y;var x=m.matcher.exec(s);if(!x)break;var A=n(s.substring(y,x.index),x);y=x.index+A}return n(s.substr(y)),E.closeAllNodes(),E.finalize(),a=E.toHTML(),{language:r,value:a,relevance:w,illegal:!1,_emitter:E,_top:m}}catch(e){if(e.message&&e.message.includes("Illegal"))return{language:r,value:C(s),illegal:!0,relevance:0,_illegalBy:{message:e.message,index:y,context:s.slice(y-100,y+100),mode:e.mode,resultSoFar:a},_emitter:E};if(S)return{language:r,value:C(s),illegal:!1,relevance:0,errorRaised:e,_emitter:E,_top:m};throw e}}function T(n,e){e=e||R.languages||Object.keys(O);var t=function(e){const n={value:C(e),illegal:!1,relevance:0,_top:s,_emitter:new R.__emitter(R)};return n._emitter.addText(e),n}(n);const a=e.filter(I).filter(d).map(e=>B(e,n,!1));a.unshift(t);var[e,t]=a.sort((e,n)=>{if(e.relevance!==n.relevance)return n.relevance-e.relevance;if(e.language&&n.language){if(I(e.language).supersetOf===n.language)return 1;if(I(n.language).supersetOf===e.language)return-1}return 0});const i=e;return i.secondBest=t,i}function n(e){var n,t,a,i=function(e){let n=e.className+" ";n+=e.parentNode?e.parentNode.className:"";var t,a=R.languageDetectRe.exec(n);return a?((t=I(a[1]))||(x(M.replace("{}",a[1])),x("Falling back to no-highlight mode for this block.",e)),t?a[1]:"no-highlight"):n.split(/\s+/).find(e=>o(e)||I(e))}(e);o(i)||(u("before:highlightElement",{el:e,language:i}),!R.ignoreUnescapedHTML&&0<e.children.length&&(console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk."),console.warn("https://github.com/highlightjs/highlight.js/issues/2886"),console.warn(e)),t=e.textContent,u("after:highlightElement",{el:e,result:n=i?l(t,{language:i,ignoreIllegals:!0}):T(t),text:t}),e.innerHTML=n.value,t=e,i=i,a=n.language,i=i&&r[i]||a,t.classList.add("hljs"),t.classList.add("language-"+i),e.result={language:n.language,re:n.relevance,relevance:n.relevance},n.secondBest&&(e.secondBest={language:n.secondBest.language,relevance:n.secondBest.relevance}))}let t=!1;function e(){if("loading"===document.readyState)t=!0;else{const e=document.querySelectorAll(R.cssSelector);e.forEach(n)}}function I(e){return e=(e||"").toLowerCase(),O[e]||O[r[e]]}function c(e,{languageName:n}){(e="string"==typeof e?[e]:e).forEach(e=>{r[e.toLowerCase()]=n})}function d(e){e=I(e);return e&&!e.disableAutodetect}function u(e,n){const t=e;i.forEach(function(e){e[t]&&e[t](n)})}"undefined"!=typeof window&&window.addEventListener&&window.addEventListener("DOMContentLoaded",function(){t&&e()},!1),Object.assign(a,{highlight:l,highlightAuto:T,highlightAll:e,highlightElement:n,highlightBlock:function(e){return A("10.7.0","highlightBlock will be removed entirely in v12.0"),A("10.7.0","Please use highlightElement now."),n(e)},configure:function(e){R=F(R,e)},initHighlighting:()=>{e(),A("10.6.0","initHighlighting() deprecated. Use highlightAll() now.")},initHighlightingOnLoad:function(){e(),A("10.6.0","initHighlightingOnLoad() deprecated. Use highlightAll() now.")},registerLanguage:function(n,e){let t=null;try{t=e(a)}catch(e){if(j("Language definition for '{}' could not be registered.".replace("{}",n)),!S)throw e;j(e),t=s}t.name||(t.name=n),(O[n]=t).rawDefinition=e.bind(null,a),t.aliases&&c(t.aliases,{languageName:n})},unregisterLanguage:function(e){delete O[e];for(const n of Object.keys(r))r[n]===e&&delete r[n]},listLanguages:function(){return Object.keys(O)},getLanguage:I,registerAliases:c,autoDetection:d,inherit:F,addPlugin:function(e){var n;(n=e)["before:highlightBlock"]&&!n["before:highlightElement"]&&(n["before:highlightElement"]=e=>{n["before:highlightBlock"](Object.assign({block:e.el},e))}),n["after:highlightBlock"]&&!n["after:highlightElement"]&&(n["after:highlightElement"]=e=>{n["after:highlightBlock"](Object.assign({block:e.el},e))}),i.push(e)}}),a.debugMode=function(){S=!1},a.safeMode=function(){S=!0},a.versionString="11.0.0-beta1";for(const g in y)"object"==typeof y[g]&&z(y[g]);return Object.assign(a,y),a}({});const V=["a","abbr","address","article","aside","audio","b","blockquote","body","button","canvas","caption","cite","code","dd","del","details","dfn","div","dl","dt","em","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","html","i","iframe","img","input","ins","kbd","label","legend","li","main","mark","menu","nav","object","ol","p","q","quote","samp","section","span","strong","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","ul","var","video"],Y=["any-hover","any-pointer","aspect-ratio","color","color-gamut","color-index","device-aspect-ratio","device-height","device-width","display-mode","forced-colors","grid","height","hover","inverted-colors","monochrome","orientation","overflow-block","overflow-inline","pointer","prefers-color-scheme","prefers-contrast","prefers-reduced-motion","prefers-reduced-transparency","resolution","scan","scripting","update","width","min-width","max-width","min-height","max-height"],ee=["active","any-link","blank","checked","current","default","defined","dir","disabled","drop","empty","enabled","first","first-child","first-of-type","fullscreen","future","focus","focus-visible","focus-within","has","host","host-context","hover","indeterminate","in-range","invalid","is","lang","last-child","last-of-type","left","link","local-link","not","nth-child","nth-col","nth-last-child","nth-last-col","nth-last-of-type","nth-of-type","only-child","only-of-type","optional","out-of-range","past","placeholder-shown","read-only","read-write","required","right","root","scope","target","target-within","user-invalid","valid","visited","where"],ne=["after","backdrop","before","cue","cue-region","first-letter","first-line","grammar-error","marker","part","placeholder","selection","slotted","spelling-error"],te=["align-content","align-items","align-self","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","auto","backface-visibility","background","background-attachment","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","border","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","clear","clip","clip-path","color","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","content","counter-increment","counter-reset","cursor","direction","display","empty-cells","filter","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","font","font-display","font-family","font-feature-settings","font-kerning","font-language-override","font-size","font-size-adjust","font-smoothing","font-stretch","font-style","font-variant","font-variant-ligatures","font-variation-settings","font-weight","height","hyphens","icon","image-orientation","image-rendering","image-resolution","ime-mode","inherit","initial","justify-content","left","letter-spacing","line-height","list-style","list-style-image","list-style-position","list-style-type","margin","margin-bottom","margin-left","margin-right","margin-top","marks","mask","max-height","max-width","min-height","min-width","nav-down","nav-index","nav-left","nav-right","nav-up","none","normal","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-wrap","overflow-x","overflow-y","padding","padding-bottom","padding-left","padding-right","padding-top","page-break-after","page-break-before","page-break-inside","perspective","perspective-origin","pointer-events","position","quotes","resize","right","src","tab-size","table-layout","text-align","text-align-last","text-decoration","text-decoration-color","text-decoration-line","text-decoration-style","text-indent","text-overflow","text-rendering","text-shadow","text-transform","text-underline-position","top","transform","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","white-space","widows","width","word-break","word-spacing","word-wrap","z-index"].reverse();ee.concat(ne);const R="[A-Za-z$_][0-9A-Za-z$_]*",ae=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],ie=["true","false","null","undefined","NaN","Infinity"],re=["Intl","DataView","Number","Math","Date","String","RegExp","Object","Function","Boolean","Error","Symbol","Set","Map","WeakSet","WeakMap","Proxy","Reflect","JSON","Promise","Float64Array","Int16Array","Int32Array","Int8Array","Uint16Array","Uint32Array","Float32Array","Array","Uint8Array","Uint8ClampedArray","ArrayBuffer","BigInt64Array","BigUint64Array","BigInt"],se=["EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"],oe=["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],le=["arguments","this","super","console","window","document","localStorage","module","global"],ce=[].concat(oe,re,se);function de(e){var n=R;const t="<>",a="</>",i=/<[A-Za-z0-9\\._:-]+/,r=/\/[A-Za-z0-9\\._:-]+>|\/>/,s=(e,n)=>{var t=e[0].length+e.index,a=e.input[t];"<"===a?n.ignoreMatch():">"===a&&([a,e]=[e,{after:t}["after"]],t="</"+a[0].slice(1),-1===a.input.indexOf(t,e)&&n.ignoreMatch())};var o={$pattern:R,keyword:ae,literal:ie,built_in:ce,"variable.language":le},l="[0-9](_?[0-9])*",c=`\\.(${l})`,d="0|[1-9](_?[0-9])*|0[0-7]*[89][0-9]*",l={className:"number",variants:[{begin:`(\\b(${d})((${c})|\\.)?|(${c}))`+`[eE][+-]?(${l})\\b`},{begin:`\\b(${d})\\b((${c})\\b|\\.)?|(${c})\\b`},{begin:"\\b(0|[1-9](_?[0-9])*)n\\b"},{begin:"\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*n?\\b"},{begin:"\\b0[bB][0-1](_?[0-1])*n?\\b"},{begin:"\\b0[oO][0-7](_?[0-7])*n?\\b"},{begin:"\\b0[0-7]+n?\\b"}],relevance:0};const u={className:"subst",begin:"\\$\\{",end:"\\}",keywords:o,contains:[]};var d={begin:"html`",end:"",starts:{end:"`",returnEnd:!1,contains:[e.BACKSLASH_ESCAPE,u],subLanguage:"xml"}},c={begin:"css`",end:"",starts:{end:"`",returnEnd:!1,contains:[e.BACKSLASH_ESCAPE,u],subLanguage:"css"}},g={className:"string",begin:"`",end:"`",contains:[e.BACKSLASH_ESCAPE,u]},b={className:"comment",variants:[e.COMMENT(/\/\*\*(?!\/)/,"\\*/",{relevance:0,contains:[{begin:"(?=@[A-Za-z]+)",relevance:0,contains:[{className:"doctag",begin:"@[A-Za-z]+"},{className:"type",begin:"\\{",end:"\\}",excludeEnd:!0,excludeBegin:!0,relevance:0},{className:"variable",begin:n+"(?=\\s*(-)|$)",endsParent:!0,relevance:0},{begin:/(?=[^\n])\s/,relevance:0}]}]}),e.C_BLOCK_COMMENT_MODE,e.C_LINE_COMMENT_MODE]};const h=[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,d,c,g,l,e.REGEXP_MODE],p=(u.contains=h.concat({begin:/\{/,end:/\}/,keywords:o,contains:["self"].concat(h)}),[].concat(b,u.contains));var m=p.concat([{begin:/\(/,end:/\)/,keywords:o,contains:["self"].concat(p)}]),f={className:"params",begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:o,contains:m},E={variants:[{match:[/class/,/\s+/,n],scope:{1:"keyword",3:"title.class"}},{match:[/extends/,/\s+/,O(n,"(",O(/\./,n),")*")],scope:{1:"keyword",3:"title.class.inherited"}}]},v={relevance:0,match:/\b[A-Z][a-z]+([A-Z][a-z]+)*/,className:"title.class",keywords:{_:[...re,...se]}},w={variants:[{match:[/function/,/\s+/,n,/(?=\s*\()/]},{match:[/function/,/\s*(?=\()/]}],className:{1:"keyword",3:"title.function"},label:"func.def",contains:[f],illegal:/%/};var y={match:O(/\b/,O("(?!",[...oe,"super"].join("|"),")"),n,k(/\(/)),className:"title.function",relevance:0},_={begin:O(/\./,k(O(n,/(?![0-9A-Za-z$_(])/))),end:n,excludeBegin:!0,keywords:"prototype",className:"property",relevance:0},N={match:[/get|set/,/\s+/,n,/(?=\()/],className:{1:"keyword",3:"title.function"},contains:[{begin:/\(\)/},f]},x="(\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)|"+e.UNDERSCORE_IDENT_RE+")\\s*=>",A={match:[/const|var|let/,/\s+/,n,/\s*/,/=\s*/,k(x)],className:{1:"keyword",3:"title.function"},contains:[f]};return{name:"Javascript",aliases:["js","jsx","mjs","cjs"],keywords:o,exports:{PARAMS_CONTAINS:m},illegal:/#(?![$_A-z])/,contains:[e.SHEBANG({label:"shebang",binary:"node",relevance:5}),{label:"use_strict",className:"meta",relevance:10,begin:/^\s*['"]use (strict|asm)['"]/},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,d,c,g,b,l,v,{className:"attr",begin:n+k(":"),relevance:0},A,{begin:"("+e.RE_STARTERS_RE+"|\\b(case|return|throw)\\b)\\s*",keywords:"return throw case",relevance:0,contains:[b,e.REGEXP_MODE,{className:"function",begin:x,returnBegin:!0,end:"\\s*=>",contains:[{className:"params",variants:[{begin:e.UNDERSCORE_IDENT_RE,relevance:0},{className:null,begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:o,contains:m}]}]},{begin:/,/,relevance:0},{match:/\s+/,relevance:0},{variants:[{begin:t,end:a},{begin:i,"on:begin":s,end:r}],subLanguage:"xml",contains:[{begin:i,end:r,skip:!0,contains:["self"]}]}]},w,{beginKeywords:"while if switch catch for"},{begin:"\\b(?!function)"+e.UNDERSCORE_IDENT_RE+"\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)\\s*\\{",returnBegin:!0,label:"func.def",contains:[f,e.inherit(e.TITLE_MODE,{begin:n,className:"title.function"})]},{match:/\.\.\./,relevance:0},_,{match:"\\$"+n,relevance:0},{match:[/\bconstructor(?=\s*\()/],className:{1:"title.function"},contains:[f]},y,{relevance:0,match:/\b[A-Z][A-Z_]+\b/,className:"variable.constant"},E,N,{match:/\$[(.]/}]}}function ue(e){var n={beginKeywords:["true","false","null"].join(" ")};return{name:"JSON",contains:[{className:"attr",begin:/"(\\.|[^\\"\r\n])*"(?=\s*:)/,relevance:1.01},{match:/[{}[\],:]/,className:"punctuation",relevance:0},e.QUOTE_STRING_MODE,n,e.C_NUMBER_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE],illegal:"\\S"}}function ge(e){var n={IMPORTANT:{scope:"meta",begin:"!important"},HEXCOLOR:{scope:"number",begin:"#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})"},ATTRIBUTE_SELECTOR_MODE:{scope:"selector-attr",begin:/\[/,end:/\]/,illegal:"$",contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},CSS_NUMBER_MODE:{scope:"number",begin:e.NUMBER_RE+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",relevance:0}};const t=ne,a=ee;var i="@[a-z-]+",r={className:"variable",begin:"(\\$[a-zA-Z-][a-zA-Z0-9_-]*)\\b"};return{name:"SCSS",case_insensitive:!0,illegal:"[=/|']",contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"selector-id",begin:"#[A-Za-z0-9_-]+",relevance:0},{className:"selector-class",begin:"\\.[A-Za-z0-9_-]+",relevance:0},n.ATTRIBUTE_SELECTOR_MODE,{className:"selector-tag",begin:"\\b("+V.join("|")+")\\b",relevance:0},{className:"selector-pseudo",begin:":("+a.join("|")+")"},{className:"selector-pseudo",begin:"::("+t.join("|")+")"},r,{begin:/\(/,end:/\)/,contains:[n.CSS_NUMBER_MODE]},{className:"attribute",begin:"\\b("+te.join("|")+")\\b"},{begin:"\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\b"},{begin:":",end:";",contains:[r,n.HEXCOLOR,n.CSS_NUMBER_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,n.IMPORTANT]},{begin:"@(page|font-face)",keywords:{$pattern:i,keyword:"@page @font-face"}},{begin:"@",end:"[{;]",returnBegin:!0,keywords:{$pattern:/[a-z-]+/,keyword:"and or not only",attribute:Y.join(" ")},contains:[{begin:i,className:"keyword"},{begin:/[a-z-]+(?=:)/,className:"attribute"},r,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,n.HEXCOLOR,n.CSS_NUMBER_MODE]}]}}f=e=>O(/\b/,e,/\w$/.test(e)?/\b/:/\B/),["Protocol","Type"].map(f),["init","self"].map(f),E=d(/[/=\-+!*%<>&|^~?]/,/[\u00A1-\u00A7]/,/[\u00A9\u00AB]/,/[\u00AC\u00AE]/,/[\u00B0\u00B1]/,/[\u00B6\u00BB\u00BF\u00D7\u00F7]/,/[\u2016-\u2017]/,/[\u2020-\u2027]/,/[\u2030-\u203E]/,/[\u2041-\u2053]/,/[\u2055-\u205E]/,/[\u2190-\u23FF]/,/[\u2500-\u2775]/,/[\u2794-\u2BFF]/,/[\u2E00-\u2E7F]/,/[\u3001-\u3003]/,/[\u3008-\u3020]/,/[\u3030]/),O(E,d(E,/[\u0300-\u036F]/,/[\u1DC0-\u1DFF]/,/[\u20D0-\u20FF]/,/[\uFE00-\uFE0F]/,/[\uFE20-\uFE2F]/),"*"),v=d(/[a-zA-Z_]/,/[\u00A8\u00AA\u00AD\u00AF\u00B2-\u00B5\u00B7-\u00BA]/,/[\u00BC-\u00BE\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF]/,/[\u0100-\u02FF\u0370-\u167F\u1681-\u180D\u180F-\u1DBF]/,/[\u1E00-\u1FFF]/,/[\u200B-\u200D\u202A-\u202E\u203F-\u2040\u2054\u2060-\u206F]/,/[\u2070-\u20CF\u2100-\u218F\u2460-\u24FF\u2776-\u2793]/,/[\u2C00-\u2DFF\u2E80-\u2FFF]/,/[\u3004-\u3007\u3021-\u302F\u3031-\u303F\u3040-\uD7FF]/,/[\uF900-\uFD3D\uFD40-\uFDCF\uFDF0-\uFE1F\uFE30-\uFE44]/,/[\uFE47-\uFEFE\uFF00-\uFFFD]/),w=d(v,/\d/,/[\u0300-\u036F\u1DC0-\u1DFF\u20D0-\u20FF\uFE20-\uFE2F]/),o=O(v,w,"*");O(/[A-Z]/,w,"*"),O(/convention\(/,d("swift","block","c"),/\)/),O(/objc\(/,o,/\)/);var be=Object.freeze({__proto__:null,grmr_bash:function(e){var n={},t={begin:/\$\{/,end:/\}/,contains:["self",{begin:/:-/,contains:[n]}]};Object.assign(n,{className:"variable",variants:[{begin:O(/\$[\w\d#@][\w\d_]*/,"(?![\\w\\d])(?![$])")},t]});const a={className:"subst",begin:/\$\(/,end:/\)/,contains:[e.BACKSLASH_ESCAPE]};var t={begin:/<<-?\s*(?=\w+)/,starts:{contains:[e.END_SAME_AS_BEGIN({begin:/(\w+)/,end:/(\w+)/,className:"string"})]}},i={className:"string",begin:/"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,n,a]},r=(a.contains.push(i),{begin:/\$\(\(/,end:/\)\)/,contains:[{begin:/\d+#[0-9a-f]+/,className:"number"},e.NUMBER_MODE,n]}),s=e.SHEBANG({binary:`(${["fish","bash","zsh","sh","csh","ksh","tcsh","dash","scsh"].join("|")})`,relevance:10}),o={className:"function",begin:/\w[\w\d_]*\s*\(\s*\)\s*\{/,returnBegin:!0,contains:[e.inherit(e.TITLE_MODE,{begin:/\w[\w\d_]*/})],relevance:0};return{name:"Bash",aliases:["sh"],keywords:{$pattern:/\b[a-z._-]+\b/,keyword:["if","then","else","elif","fi","for","while","in","do","done","case","esac","function"],literal:["true","false"],built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp"},contains:[s,e.SHEBANG(),o,r,e.HASH_COMMENT_MODE,t,i,{className:"",begin:/\\"/},{className:"string",begin:/'/,end:/'/},n]}},grmr_scss:ge,grmr_css:ge,grmr_javascript:de,grmr_json:ue,grmr_json5:ue,grmr_xml:function(e){var n=O(/[A-Z_]/,O("(?:",/[A-Z0-9_.-]*:/,")?"),/[A-Z0-9_.-]*/),t={className:"symbol",begin:/&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/},a={begin:/\s/,contains:[{className:"keyword",begin:/#?[a-z_][a-z1-9_-]+/,illegal:/\n/}]},i=e.inherit(a,{begin:/\(/,end:/\)/}),r=e.inherit(e.APOS_STRING_MODE,{className:"string"}),s=e.inherit(e.QUOTE_STRING_MODE,{className:"string"}),o={endsWithParent:!0,illegal:/</,relevance:0,contains:[{className:"attr",begin:/[A-Za-z0-9._:-]+/,relevance:0},{begin:/=\s*/,relevance:0,contains:[{className:"string",endsParent:!0,variants:[{begin:/"/,end:/"/,contains:[t]},{begin:/'/,end:/'/,contains:[t]},{begin:/[^\s"'=<>`]+/}]}]}]};return{name:"HTML, XML",aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"],case_insensitive:!0,contains:[{className:"meta",begin:/<![a-z]/,end:/>/,relevance:10,contains:[a,s,r,i,{begin:/\[/,end:/\]/,contains:[{className:"meta",begin:/<![a-z]/,end:/>/,contains:[a,i,s,r]}]}]},e.COMMENT(/<!--/,/-->/,{relevance:10}),{begin:/<!\[CDATA\[/,end:/\]\]>/,relevance:10},t,{className:"meta",begin:/<\?xml/,end:/\?>/,relevance:10},{className:"tag",begin:/<style(?=\s|>)/,end:/>/,keywords:{name:"style"},contains:[o],starts:{end:/<\/style>/,returnEnd:!0,subLanguage:["css","xml"]}},{className:"tag",begin:/<script(?=\s|>)/,end:/>/,keywords:{name:"script"},contains:[o],starts:{end:/<\/script>/,returnEnd:!0,subLanguage:["javascript","handlebars","xml"]}},{className:"tag",begin:/<>|<\/>/},{className:"tag",begin:O(/</,k(O(n,d(/\/>/,/>/,/\s/)))),end:/\/?>/,contains:[{className:"name",begin:n,relevance:0,starts:o}]},{className:"tag",begin:O(/<\//,k(O(n,/>/))),contains:[{className:"name",begin:n,relevance:0},{begin:/>/,relevance:0,endsParent:!0}]}]}},grmr_markdown:function(e){var n={begin:/<\/?[A-Za-z_]/,end:">",subLanguage:"xml",relevance:0},t={variants:[{begin:/\[.+?\]\[.*?\]/,relevance:0},{begin:/\[.+?\]\(((data|javascript|mailto):|(?:http|ftp)s?:\/\/).*?\)/,relevance:2},{begin:O(/\[.+?\]\(/,/[A-Za-z][A-Za-z0-9+.-]*/,/:\/\/.*?\)/),relevance:2},{begin:/\[.+?\]\([./?&#].*?\)/,relevance:1},{begin:/\[.+?\]\(.*?\)/,relevance:0}],returnBegin:!0,contains:[{className:"string",relevance:0,begin:"\\[",end:"\\]",excludeBegin:!0,returnEnd:!0},{className:"link",relevance:0,begin:"\\]\\(",end:"\\)",excludeBegin:!0,excludeEnd:!0},{className:"symbol",relevance:0,begin:"\\]\\[",end:"\\]",excludeBegin:!0,excludeEnd:!0}]};const a={className:"strong",contains:[],variants:[{begin:/_{2}/,end:/_{2}/},{begin:/\*{2}/,end:/\*{2}/}]},i={className:"emphasis",contains:[],variants:[{begin:/\*(?!\*)/,end:/\*/},{begin:/_(?!_)/,end:/_/,relevance:0}]};a.contains.push(i),i.contains.push(a);let r=[n,t];a.contains=a.contains.concat(r),i.contains=i.contains.concat(r);var s={className:"section",variants:[{begin:"^#{1,6}",end:"$",contains:r=r.concat(a,i)},{begin:"(?=^.+?\\n[=-]{2,}$)",contains:[{begin:"^[=-]*$"},{begin:"^",end:"\\n",contains:r}]}]},o={className:"quote",begin:"^>\\s+",contains:r,end:"$"};return{name:"Markdown",aliases:["md","mkdown","mkd"],contains:[s,n,{className:"bullet",begin:"^[ \t]*([*+-]|(\\d+\\.))(?=\\s+)",end:"\\s+",excludeEnd:!0},a,i,o,{className:"code",variants:[{begin:"(`{3,})[^`](.|\\n)*?\\1`*[ ]*"},{begin:"(~{3,})[^~](.|\\n)*?\\1~*[ ]*"},{begin:"```",end:"```+[ ]*$"},{begin:"~~~",end:"~~~+[ ]*$"},{begin:"`.+?`"},{begin:"(?=^( {4}|\\t))",contains:[{begin:"^( {4}|\\t)",end:"(\\n)$"}],relevance:0}]},{begin:"^[-\\*]{3,}",end:"$"},t,{begin:/^\[[^\n]+\]:/,returnBegin:!0,contains:[{className:"symbol",begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0},{className:"link",begin:/:\s*/,end:/$/,excludeBegin:!0}]}]}},grmr_plaintext:function(e){return{name:"Plain text",aliases:["text","txt"],disableAutodetect:!0}},grmr_shell:function(e){return{name:"Shell Session",aliases:["console","shellsession"],contains:[{className:"meta",begin:/^\s{0,3}[/~\w\d[\]()@-]*[>%$#][ ]?/,starts:{end:/[^\\](?=\s*$)/,subLanguage:"bash"}}]}},grmr_typescript:function(e){R;var n={$pattern:R,keyword:ae.concat(["type","namespace","typedef","interface","public","private","protected","implements","declare","abstract","readonly"]),literal:ie,built_in:ce.concat(["any","void","number","boolean","string","object","never","enum"]),"variable.language":le},t={className:"meta",begin:"@[A-Za-z$_][0-9A-Za-z$_]*"},a=(e,n,t)=>{var a=e.contains.findIndex(e=>e.label===n);if(-1===a)throw new Error("can not find mode to replace");e.contains.splice(a,1,t)};const i=de(e),r=(Object.assign(i.keywords,n),i.exports.PARAMS_CONTAINS.push(t),i.contains=i.contains.concat([t,{beginKeywords:"namespace",end:/\{/,excludeEnd:!0},{beginKeywords:"interface",end:/\{/,excludeEnd:!0,keywords:"interface extends"}]),a(i,"shebang",e.SHEBANG()),a(i,"use_strict",{className:"meta",relevance:10,begin:/^\s*['"]use strict['"]/}),i.contains.find(e=>"func.def"===e.label));return r.relevance=0,Object.assign(i,{name:"TypeScript",aliases:["ts","tsx"]}),i},grmr_yaml:function(e){var n="true false yes no null",t="[\\w#;/?:@&=+$,.~*'()[\\]]+",a={className:"string",relevance:0,variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/\S+/}],contains:[e.BACKSLASH_ESCAPE,{className:"template-variable",variants:[{begin:/\{\{/,end:/\}\}/},{begin:/%\{/,end:/\}/}]}]},i=e.inherit(a,{variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/[^\s,{}[\]]+/}]});const r={end:",",endsWithParent:!0,excludeEnd:!0,keywords:n,relevance:0};var s={begin:/\{/,end:/\}/,contains:[r],illegal:"\\n",relevance:0},o={begin:"\\[",end:"\\]",contains:[r],illegal:"\\n",relevance:0};const l=[...t=[{className:"attr",variants:[{begin:"\\w[\\w :\\/.-]*:(?=[ \t]|$)"},{begin:'"\\w[\\w :\\/.-]*":(?=[ \t]|$)'},{begin:"'\\w[\\w :\\/.-]*':(?=[ \t]|$)"}]},{className:"meta",begin:"^---\\s*$",relevance:10},{className:"string",begin:"[\\|>]([1-9]?[+-])?[ ]*\\n( +)[^ ][^\\n]*\\n(\\2[^\\n]+\\n?)*"},{begin:"<%[%=-]?",end:"[%-]?%>",subLanguage:"ruby",excludeBegin:!0,excludeEnd:!0,relevance:0},{className:"type",begin:"!\\w+!"+t},{className:"type",begin:"!<"+t+">"},{className:"type",begin:"!"+t},{className:"type",begin:"!!"+t},{className:"meta",begin:"&"+e.UNDERSCORE_IDENT_RE+"$"},{className:"meta",begin:"\\*"+e.UNDERSCORE_IDENT_RE+"$"},{className:"bullet",begin:"-(?=[ ]|$)",relevance:0},e.HASH_COMMENT_MODE,{beginKeywords:n,keywords:{literal:n}},{className:"number",begin:"\\b[0-9]{4}(-[0-9][0-9]){0,2}([Tt \\t][0-9][0-9]?(:[0-9][0-9]){2})?(\\.[0-9]*)?([ \\t])*(Z|[-+][0-9][0-9]?(:[0-9][0-9])?)?\\b"},{className:"number",begin:e.C_NUMBER_RE+"\\b",relevance:0},s,o,a]];return l.pop(),l.push(i),r.contains=l,{name:"YAML",case_insensitive:!0,aliases:["yml"],contains:t}}});const he=m;for(const B of Object.keys(be)){var pe=B.replace("grmr_","");he.registerLanguage(pe,be[B])}return he}();"object"==typeof exports&&"undefined"!=typeof module&&(module.exports=hljs); \ No newline at end of file diff --git a/doc/scripts/third-party/popper.js b/doc/scripts/third-party/popper.js new file mode 100644 index 0000000000000000000000000000000000000000..30ef292384973f5170f2632da8347d323d3a542a --- /dev/null +++ b/doc/scripts/third-party/popper.js @@ -0,0 +1,5 @@ +/** + * @popperjs/core v2.11.5 - MIT License + */ + +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).Popper={})}(this,(function(e){"use strict";function t(e){if(null==e)return window;if("[object Window]"!==e.toString()){var t=e.ownerDocument;return t&&t.defaultView||window}return e}function n(e){return e instanceof t(e).Element||e instanceof Element}function r(e){return e instanceof t(e).HTMLElement||e instanceof HTMLElement}function o(e){return"undefined"!=typeof ShadowRoot&&(e instanceof t(e).ShadowRoot||e instanceof ShadowRoot)}var i=Math.max,a=Math.min,s=Math.round;function f(e,t){void 0===t&&(t=!1);var n=e.getBoundingClientRect(),o=1,i=1;if(r(e)&&t){var a=e.offsetHeight,f=e.offsetWidth;f>0&&(o=s(n.width)/f||1),a>0&&(i=s(n.height)/a||1)}return{width:n.width/o,height:n.height/i,top:n.top/i,right:n.right/o,bottom:n.bottom/i,left:n.left/o,x:n.left/o,y:n.top/i}}function c(e){var n=t(e);return{scrollLeft:n.pageXOffset,scrollTop:n.pageYOffset}}function p(e){return e?(e.nodeName||"").toLowerCase():null}function u(e){return((n(e)?e.ownerDocument:e.document)||window.document).documentElement}function l(e){return f(u(e)).left+c(e).scrollLeft}function d(e){return t(e).getComputedStyle(e)}function h(e){var t=d(e),n=t.overflow,r=t.overflowX,o=t.overflowY;return/auto|scroll|overlay|hidden/.test(n+o+r)}function m(e,n,o){void 0===o&&(o=!1);var i,a,d=r(n),m=r(n)&&function(e){var t=e.getBoundingClientRect(),n=s(t.width)/e.offsetWidth||1,r=s(t.height)/e.offsetHeight||1;return 1!==n||1!==r}(n),v=u(n),g=f(e,m),y={scrollLeft:0,scrollTop:0},b={x:0,y:0};return(d||!d&&!o)&&(("body"!==p(n)||h(v))&&(y=(i=n)!==t(i)&&r(i)?{scrollLeft:(a=i).scrollLeft,scrollTop:a.scrollTop}:c(i)),r(n)?((b=f(n,!0)).x+=n.clientLeft,b.y+=n.clientTop):v&&(b.x=l(v))),{x:g.left+y.scrollLeft-b.x,y:g.top+y.scrollTop-b.y,width:g.width,height:g.height}}function v(e){var t=f(e),n=e.offsetWidth,r=e.offsetHeight;return Math.abs(t.width-n)<=1&&(n=t.width),Math.abs(t.height-r)<=1&&(r=t.height),{x:e.offsetLeft,y:e.offsetTop,width:n,height:r}}function g(e){return"html"===p(e)?e:e.assignedSlot||e.parentNode||(o(e)?e.host:null)||u(e)}function y(e){return["html","body","#document"].indexOf(p(e))>=0?e.ownerDocument.body:r(e)&&h(e)?e:y(g(e))}function b(e,n){var r;void 0===n&&(n=[]);var o=y(e),i=o===(null==(r=e.ownerDocument)?void 0:r.body),a=t(o),s=i?[a].concat(a.visualViewport||[],h(o)?o:[]):o,f=n.concat(s);return i?f:f.concat(b(g(s)))}function x(e){return["table","td","th"].indexOf(p(e))>=0}function w(e){return r(e)&&"fixed"!==d(e).position?e.offsetParent:null}function O(e){for(var n=t(e),i=w(e);i&&x(i)&&"static"===d(i).position;)i=w(i);return i&&("html"===p(i)||"body"===p(i)&&"static"===d(i).position)?n:i||function(e){var t=-1!==navigator.userAgent.toLowerCase().indexOf("firefox");if(-1!==navigator.userAgent.indexOf("Trident")&&r(e)&&"fixed"===d(e).position)return null;var n=g(e);for(o(n)&&(n=n.host);r(n)&&["html","body"].indexOf(p(n))<0;){var i=d(n);if("none"!==i.transform||"none"!==i.perspective||"paint"===i.contain||-1!==["transform","perspective"].indexOf(i.willChange)||t&&"filter"===i.willChange||t&&i.filter&&"none"!==i.filter)return n;n=n.parentNode}return null}(e)||n}var j="top",E="bottom",D="right",A="left",L="auto",P=[j,E,D,A],M="start",k="end",W="viewport",B="popper",H=P.reduce((function(e,t){return e.concat([t+"-"+M,t+"-"+k])}),[]),T=[].concat(P,[L]).reduce((function(e,t){return e.concat([t,t+"-"+M,t+"-"+k])}),[]),R=["beforeRead","read","afterRead","beforeMain","main","afterMain","beforeWrite","write","afterWrite"];function S(e){var t=new Map,n=new Set,r=[];function o(e){n.add(e.name),[].concat(e.requires||[],e.requiresIfExists||[]).forEach((function(e){if(!n.has(e)){var r=t.get(e);r&&o(r)}})),r.push(e)}return e.forEach((function(e){t.set(e.name,e)})),e.forEach((function(e){n.has(e.name)||o(e)})),r}function C(e){return e.split("-")[0]}function q(e,t){var n=t.getRootNode&&t.getRootNode();if(e.contains(t))return!0;if(n&&o(n)){var r=t;do{if(r&&e.isSameNode(r))return!0;r=r.parentNode||r.host}while(r)}return!1}function V(e){return Object.assign({},e,{left:e.x,top:e.y,right:e.x+e.width,bottom:e.y+e.height})}function N(e,r){return r===W?V(function(e){var n=t(e),r=u(e),o=n.visualViewport,i=r.clientWidth,a=r.clientHeight,s=0,f=0;return o&&(i=o.width,a=o.height,/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||(s=o.offsetLeft,f=o.offsetTop)),{width:i,height:a,x:s+l(e),y:f}}(e)):n(r)?function(e){var t=f(e);return t.top=t.top+e.clientTop,t.left=t.left+e.clientLeft,t.bottom=t.top+e.clientHeight,t.right=t.left+e.clientWidth,t.width=e.clientWidth,t.height=e.clientHeight,t.x=t.left,t.y=t.top,t}(r):V(function(e){var t,n=u(e),r=c(e),o=null==(t=e.ownerDocument)?void 0:t.body,a=i(n.scrollWidth,n.clientWidth,o?o.scrollWidth:0,o?o.clientWidth:0),s=i(n.scrollHeight,n.clientHeight,o?o.scrollHeight:0,o?o.clientHeight:0),f=-r.scrollLeft+l(e),p=-r.scrollTop;return"rtl"===d(o||n).direction&&(f+=i(n.clientWidth,o?o.clientWidth:0)-a),{width:a,height:s,x:f,y:p}}(u(e)))}function I(e,t,o){var s="clippingParents"===t?function(e){var t=b(g(e)),o=["absolute","fixed"].indexOf(d(e).position)>=0&&r(e)?O(e):e;return n(o)?t.filter((function(e){return n(e)&&q(e,o)&&"body"!==p(e)})):[]}(e):[].concat(t),f=[].concat(s,[o]),c=f[0],u=f.reduce((function(t,n){var r=N(e,n);return t.top=i(r.top,t.top),t.right=a(r.right,t.right),t.bottom=a(r.bottom,t.bottom),t.left=i(r.left,t.left),t}),N(e,c));return u.width=u.right-u.left,u.height=u.bottom-u.top,u.x=u.left,u.y=u.top,u}function _(e){return e.split("-")[1]}function F(e){return["top","bottom"].indexOf(e)>=0?"x":"y"}function U(e){var t,n=e.reference,r=e.element,o=e.placement,i=o?C(o):null,a=o?_(o):null,s=n.x+n.width/2-r.width/2,f=n.y+n.height/2-r.height/2;switch(i){case j:t={x:s,y:n.y-r.height};break;case E:t={x:s,y:n.y+n.height};break;case D:t={x:n.x+n.width,y:f};break;case A:t={x:n.x-r.width,y:f};break;default:t={x:n.x,y:n.y}}var c=i?F(i):null;if(null!=c){var p="y"===c?"height":"width";switch(a){case M:t[c]=t[c]-(n[p]/2-r[p]/2);break;case k:t[c]=t[c]+(n[p]/2-r[p]/2)}}return t}function z(e){return Object.assign({},{top:0,right:0,bottom:0,left:0},e)}function X(e,t){return t.reduce((function(t,n){return t[n]=e,t}),{})}function Y(e,t){void 0===t&&(t={});var r=t,o=r.placement,i=void 0===o?e.placement:o,a=r.boundary,s=void 0===a?"clippingParents":a,c=r.rootBoundary,p=void 0===c?W:c,l=r.elementContext,d=void 0===l?B:l,h=r.altBoundary,m=void 0!==h&&h,v=r.padding,g=void 0===v?0:v,y=z("number"!=typeof g?g:X(g,P)),b=d===B?"reference":B,x=e.rects.popper,w=e.elements[m?b:d],O=I(n(w)?w:w.contextElement||u(e.elements.popper),s,p),A=f(e.elements.reference),L=U({reference:A,element:x,strategy:"absolute",placement:i}),M=V(Object.assign({},x,L)),k=d===B?M:A,H={top:O.top-k.top+y.top,bottom:k.bottom-O.bottom+y.bottom,left:O.left-k.left+y.left,right:k.right-O.right+y.right},T=e.modifiersData.offset;if(d===B&&T){var R=T[i];Object.keys(H).forEach((function(e){var t=[D,E].indexOf(e)>=0?1:-1,n=[j,E].indexOf(e)>=0?"y":"x";H[e]+=R[n]*t}))}return H}var G={placement:"bottom",modifiers:[],strategy:"absolute"};function J(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return!t.some((function(e){return!(e&&"function"==typeof e.getBoundingClientRect)}))}function K(e){void 0===e&&(e={});var t=e,r=t.defaultModifiers,o=void 0===r?[]:r,i=t.defaultOptions,a=void 0===i?G:i;return function(e,t,r){void 0===r&&(r=a);var i,s,f={placement:"bottom",orderedModifiers:[],options:Object.assign({},G,a),modifiersData:{},elements:{reference:e,popper:t},attributes:{},styles:{}},c=[],p=!1,u={state:f,setOptions:function(r){var i="function"==typeof r?r(f.options):r;l(),f.options=Object.assign({},a,f.options,i),f.scrollParents={reference:n(e)?b(e):e.contextElement?b(e.contextElement):[],popper:b(t)};var s,p,d=function(e){var t=S(e);return R.reduce((function(e,n){return e.concat(t.filter((function(e){return e.phase===n})))}),[])}((s=[].concat(o,f.options.modifiers),p=s.reduce((function(e,t){var n=e[t.name];return e[t.name]=n?Object.assign({},n,t,{options:Object.assign({},n.options,t.options),data:Object.assign({},n.data,t.data)}):t,e}),{}),Object.keys(p).map((function(e){return p[e]}))));return f.orderedModifiers=d.filter((function(e){return e.enabled})),f.orderedModifiers.forEach((function(e){var t=e.name,n=e.options,r=void 0===n?{}:n,o=e.effect;if("function"==typeof o){var i=o({state:f,name:t,instance:u,options:r}),a=function(){};c.push(i||a)}})),u.update()},forceUpdate:function(){if(!p){var e=f.elements,t=e.reference,n=e.popper;if(J(t,n)){f.rects={reference:m(t,O(n),"fixed"===f.options.strategy),popper:v(n)},f.reset=!1,f.placement=f.options.placement,f.orderedModifiers.forEach((function(e){return f.modifiersData[e.name]=Object.assign({},e.data)}));for(var r=0;r<f.orderedModifiers.length;r++)if(!0!==f.reset){var o=f.orderedModifiers[r],i=o.fn,a=o.options,s=void 0===a?{}:a,c=o.name;"function"==typeof i&&(f=i({state:f,options:s,name:c,instance:u})||f)}else f.reset=!1,r=-1}}},update:(i=function(){return new Promise((function(e){u.forceUpdate(),e(f)}))},function(){return s||(s=new Promise((function(e){Promise.resolve().then((function(){s=void 0,e(i())}))}))),s}),destroy:function(){l(),p=!0}};if(!J(e,t))return u;function l(){c.forEach((function(e){return e()})),c=[]}return u.setOptions(r).then((function(e){!p&&r.onFirstUpdate&&r.onFirstUpdate(e)})),u}}var Q={passive:!0};var Z={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(e){var n=e.state,r=e.instance,o=e.options,i=o.scroll,a=void 0===i||i,s=o.resize,f=void 0===s||s,c=t(n.elements.popper),p=[].concat(n.scrollParents.reference,n.scrollParents.popper);return a&&p.forEach((function(e){e.addEventListener("scroll",r.update,Q)})),f&&c.addEventListener("resize",r.update,Q),function(){a&&p.forEach((function(e){e.removeEventListener("scroll",r.update,Q)})),f&&c.removeEventListener("resize",r.update,Q)}},data:{}};var $={name:"popperOffsets",enabled:!0,phase:"read",fn:function(e){var t=e.state,n=e.name;t.modifiersData[n]=U({reference:t.rects.reference,element:t.rects.popper,strategy:"absolute",placement:t.placement})},data:{}},ee={top:"auto",right:"auto",bottom:"auto",left:"auto"};function te(e){var n,r=e.popper,o=e.popperRect,i=e.placement,a=e.variation,f=e.offsets,c=e.position,p=e.gpuAcceleration,l=e.adaptive,h=e.roundOffsets,m=e.isFixed,v=f.x,g=void 0===v?0:v,y=f.y,b=void 0===y?0:y,x="function"==typeof h?h({x:g,y:b}):{x:g,y:b};g=x.x,b=x.y;var w=f.hasOwnProperty("x"),L=f.hasOwnProperty("y"),P=A,M=j,W=window;if(l){var B=O(r),H="clientHeight",T="clientWidth";if(B===t(r)&&"static"!==d(B=u(r)).position&&"absolute"===c&&(H="scrollHeight",T="scrollWidth"),B=B,i===j||(i===A||i===D)&&a===k)M=E,b-=(m&&B===W&&W.visualViewport?W.visualViewport.height:B[H])-o.height,b*=p?1:-1;if(i===A||(i===j||i===E)&&a===k)P=D,g-=(m&&B===W&&W.visualViewport?W.visualViewport.width:B[T])-o.width,g*=p?1:-1}var R,S=Object.assign({position:c},l&&ee),C=!0===h?function(e){var t=e.x,n=e.y,r=window.devicePixelRatio||1;return{x:s(t*r)/r||0,y:s(n*r)/r||0}}({x:g,y:b}):{x:g,y:b};return g=C.x,b=C.y,p?Object.assign({},S,((R={})[M]=L?"0":"",R[P]=w?"0":"",R.transform=(W.devicePixelRatio||1)<=1?"translate("+g+"px, "+b+"px)":"translate3d("+g+"px, "+b+"px, 0)",R)):Object.assign({},S,((n={})[M]=L?b+"px":"",n[P]=w?g+"px":"",n.transform="",n))}var ne={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(e){var t=e.state,n=e.options,r=n.gpuAcceleration,o=void 0===r||r,i=n.adaptive,a=void 0===i||i,s=n.roundOffsets,f=void 0===s||s,c={placement:C(t.placement),variation:_(t.placement),popper:t.elements.popper,popperRect:t.rects.popper,gpuAcceleration:o,isFixed:"fixed"===t.options.strategy};null!=t.modifiersData.popperOffsets&&(t.styles.popper=Object.assign({},t.styles.popper,te(Object.assign({},c,{offsets:t.modifiersData.popperOffsets,position:t.options.strategy,adaptive:a,roundOffsets:f})))),null!=t.modifiersData.arrow&&(t.styles.arrow=Object.assign({},t.styles.arrow,te(Object.assign({},c,{offsets:t.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:f})))),t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-placement":t.placement})},data:{}};var re={name:"applyStyles",enabled:!0,phase:"write",fn:function(e){var t=e.state;Object.keys(t.elements).forEach((function(e){var n=t.styles[e]||{},o=t.attributes[e]||{},i=t.elements[e];r(i)&&p(i)&&(Object.assign(i.style,n),Object.keys(o).forEach((function(e){var t=o[e];!1===t?i.removeAttribute(e):i.setAttribute(e,!0===t?"":t)})))}))},effect:function(e){var t=e.state,n={popper:{position:t.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(t.elements.popper.style,n.popper),t.styles=n,t.elements.arrow&&Object.assign(t.elements.arrow.style,n.arrow),function(){Object.keys(t.elements).forEach((function(e){var o=t.elements[e],i=t.attributes[e]||{},a=Object.keys(t.styles.hasOwnProperty(e)?t.styles[e]:n[e]).reduce((function(e,t){return e[t]="",e}),{});r(o)&&p(o)&&(Object.assign(o.style,a),Object.keys(i).forEach((function(e){o.removeAttribute(e)})))}))}},requires:["computeStyles"]};var oe={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(e){var t=e.state,n=e.options,r=e.name,o=n.offset,i=void 0===o?[0,0]:o,a=T.reduce((function(e,n){return e[n]=function(e,t,n){var r=C(e),o=[A,j].indexOf(r)>=0?-1:1,i="function"==typeof n?n(Object.assign({},t,{placement:e})):n,a=i[0],s=i[1];return a=a||0,s=(s||0)*o,[A,D].indexOf(r)>=0?{x:s,y:a}:{x:a,y:s}}(n,t.rects,i),e}),{}),s=a[t.placement],f=s.x,c=s.y;null!=t.modifiersData.popperOffsets&&(t.modifiersData.popperOffsets.x+=f,t.modifiersData.popperOffsets.y+=c),t.modifiersData[r]=a}},ie={left:"right",right:"left",bottom:"top",top:"bottom"};function ae(e){return e.replace(/left|right|bottom|top/g,(function(e){return ie[e]}))}var se={start:"end",end:"start"};function fe(e){return e.replace(/start|end/g,(function(e){return se[e]}))}function ce(e,t){void 0===t&&(t={});var n=t,r=n.placement,o=n.boundary,i=n.rootBoundary,a=n.padding,s=n.flipVariations,f=n.allowedAutoPlacements,c=void 0===f?T:f,p=_(r),u=p?s?H:H.filter((function(e){return _(e)===p})):P,l=u.filter((function(e){return c.indexOf(e)>=0}));0===l.length&&(l=u);var d=l.reduce((function(t,n){return t[n]=Y(e,{placement:n,boundary:o,rootBoundary:i,padding:a})[C(n)],t}),{});return Object.keys(d).sort((function(e,t){return d[e]-d[t]}))}var pe={name:"flip",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options,r=e.name;if(!t.modifiersData[r]._skip){for(var o=n.mainAxis,i=void 0===o||o,a=n.altAxis,s=void 0===a||a,f=n.fallbackPlacements,c=n.padding,p=n.boundary,u=n.rootBoundary,l=n.altBoundary,d=n.flipVariations,h=void 0===d||d,m=n.allowedAutoPlacements,v=t.options.placement,g=C(v),y=f||(g===v||!h?[ae(v)]:function(e){if(C(e)===L)return[];var t=ae(e);return[fe(e),t,fe(t)]}(v)),b=[v].concat(y).reduce((function(e,n){return e.concat(C(n)===L?ce(t,{placement:n,boundary:p,rootBoundary:u,padding:c,flipVariations:h,allowedAutoPlacements:m}):n)}),[]),x=t.rects.reference,w=t.rects.popper,O=new Map,P=!0,k=b[0],W=0;W<b.length;W++){var B=b[W],H=C(B),T=_(B)===M,R=[j,E].indexOf(H)>=0,S=R?"width":"height",q=Y(t,{placement:B,boundary:p,rootBoundary:u,altBoundary:l,padding:c}),V=R?T?D:A:T?E:j;x[S]>w[S]&&(V=ae(V));var N=ae(V),I=[];if(i&&I.push(q[H]<=0),s&&I.push(q[V]<=0,q[N]<=0),I.every((function(e){return e}))){k=B,P=!1;break}O.set(B,I)}if(P)for(var F=function(e){var t=b.find((function(t){var n=O.get(t);if(n)return n.slice(0,e).every((function(e){return e}))}));if(t)return k=t,"break"},U=h?3:1;U>0;U--){if("break"===F(U))break}t.placement!==k&&(t.modifiersData[r]._skip=!0,t.placement=k,t.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function ue(e,t,n){return i(e,a(t,n))}var le={name:"preventOverflow",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options,r=e.name,o=n.mainAxis,s=void 0===o||o,f=n.altAxis,c=void 0!==f&&f,p=n.boundary,u=n.rootBoundary,l=n.altBoundary,d=n.padding,h=n.tether,m=void 0===h||h,g=n.tetherOffset,y=void 0===g?0:g,b=Y(t,{boundary:p,rootBoundary:u,padding:d,altBoundary:l}),x=C(t.placement),w=_(t.placement),L=!w,P=F(x),k="x"===P?"y":"x",W=t.modifiersData.popperOffsets,B=t.rects.reference,H=t.rects.popper,T="function"==typeof y?y(Object.assign({},t.rects,{placement:t.placement})):y,R="number"==typeof T?{mainAxis:T,altAxis:T}:Object.assign({mainAxis:0,altAxis:0},T),S=t.modifiersData.offset?t.modifiersData.offset[t.placement]:null,q={x:0,y:0};if(W){if(s){var V,N="y"===P?j:A,I="y"===P?E:D,U="y"===P?"height":"width",z=W[P],X=z+b[N],G=z-b[I],J=m?-H[U]/2:0,K=w===M?B[U]:H[U],Q=w===M?-H[U]:-B[U],Z=t.elements.arrow,$=m&&Z?v(Z):{width:0,height:0},ee=t.modifiersData["arrow#persistent"]?t.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},te=ee[N],ne=ee[I],re=ue(0,B[U],$[U]),oe=L?B[U]/2-J-re-te-R.mainAxis:K-re-te-R.mainAxis,ie=L?-B[U]/2+J+re+ne+R.mainAxis:Q+re+ne+R.mainAxis,ae=t.elements.arrow&&O(t.elements.arrow),se=ae?"y"===P?ae.clientTop||0:ae.clientLeft||0:0,fe=null!=(V=null==S?void 0:S[P])?V:0,ce=z+ie-fe,pe=ue(m?a(X,z+oe-fe-se):X,z,m?i(G,ce):G);W[P]=pe,q[P]=pe-z}if(c){var le,de="x"===P?j:A,he="x"===P?E:D,me=W[k],ve="y"===k?"height":"width",ge=me+b[de],ye=me-b[he],be=-1!==[j,A].indexOf(x),xe=null!=(le=null==S?void 0:S[k])?le:0,we=be?ge:me-B[ve]-H[ve]-xe+R.altAxis,Oe=be?me+B[ve]+H[ve]-xe-R.altAxis:ye,je=m&&be?function(e,t,n){var r=ue(e,t,n);return r>n?n:r}(we,me,Oe):ue(m?we:ge,me,m?Oe:ye);W[k]=je,q[k]=je-me}t.modifiersData[r]=q}},requiresIfExists:["offset"]};var de={name:"arrow",enabled:!0,phase:"main",fn:function(e){var t,n=e.state,r=e.name,o=e.options,i=n.elements.arrow,a=n.modifiersData.popperOffsets,s=C(n.placement),f=F(s),c=[A,D].indexOf(s)>=0?"height":"width";if(i&&a){var p=function(e,t){return z("number"!=typeof(e="function"==typeof e?e(Object.assign({},t.rects,{placement:t.placement})):e)?e:X(e,P))}(o.padding,n),u=v(i),l="y"===f?j:A,d="y"===f?E:D,h=n.rects.reference[c]+n.rects.reference[f]-a[f]-n.rects.popper[c],m=a[f]-n.rects.reference[f],g=O(i),y=g?"y"===f?g.clientHeight||0:g.clientWidth||0:0,b=h/2-m/2,x=p[l],w=y-u[c]-p[d],L=y/2-u[c]/2+b,M=ue(x,L,w),k=f;n.modifiersData[r]=((t={})[k]=M,t.centerOffset=M-L,t)}},effect:function(e){var t=e.state,n=e.options.element,r=void 0===n?"[data-popper-arrow]":n;null!=r&&("string"!=typeof r||(r=t.elements.popper.querySelector(r)))&&q(t.elements.popper,r)&&(t.elements.arrow=r)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function he(e,t,n){return void 0===n&&(n={x:0,y:0}),{top:e.top-t.height-n.y,right:e.right-t.width+n.x,bottom:e.bottom-t.height+n.y,left:e.left-t.width-n.x}}function me(e){return[j,D,E,A].some((function(t){return e[t]>=0}))}var ve={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(e){var t=e.state,n=e.name,r=t.rects.reference,o=t.rects.popper,i=t.modifiersData.preventOverflow,a=Y(t,{elementContext:"reference"}),s=Y(t,{altBoundary:!0}),f=he(a,r),c=he(s,o,i),p=me(f),u=me(c);t.modifiersData[n]={referenceClippingOffsets:f,popperEscapeOffsets:c,isReferenceHidden:p,hasPopperEscaped:u},t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-reference-hidden":p,"data-popper-escaped":u})}},ge=K({defaultModifiers:[Z,$,ne,re]}),ye=[Z,$,ne,re,oe,pe,le,de,ve],be=K({defaultModifiers:ye});e.applyStyles=re,e.arrow=de,e.computeStyles=ne,e.createPopper=be,e.createPopperLite=ge,e.defaultModifiers=ye,e.detectOverflow=Y,e.eventListeners=Z,e.flip=pe,e.hide=ve,e.offset=oe,e.popperGenerator=K,e.popperOffsets=$,e.preventOverflow=le,Object.defineProperty(e,"__esModule",{value:!0})})); diff --git a/doc/scripts/third-party/tippy.js b/doc/scripts/third-party/tippy.js new file mode 100644 index 0000000000000000000000000000000000000000..e58c3938173154bab03a1027dcb70083705a9d71 --- /dev/null +++ b/doc/scripts/third-party/tippy.js @@ -0,0 +1 @@ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("@popperjs/core")):"function"==typeof define&&define.amd?define(["@popperjs/core"],e):(t=t||self).tippy=e(t.Popper)}(this,(function(t){"use strict";var e="undefined"!=typeof window&&"undefined"!=typeof document,n=!!e&&!!window.msCrypto,r={passive:!0,capture:!0},o=function(){return document.body};function i(t,e,n){if(Array.isArray(t)){var r=t[e];return null==r?Array.isArray(n)?n[e]:n:r}return t}function a(t,e){var n={}.toString.call(t);return 0===n.indexOf("[object")&&n.indexOf(e+"]")>-1}function s(t,e){return"function"==typeof t?t.apply(void 0,e):t}function u(t,e){return 0===e?t:function(r){clearTimeout(n),n=setTimeout((function(){t(r)}),e)};var n}function p(t,e){var n=Object.assign({},t);return e.forEach((function(t){delete n[t]})),n}function c(t){return[].concat(t)}function f(t,e){-1===t.indexOf(e)&&t.push(e)}function l(t){return t.split("-")[0]}function d(t){return[].slice.call(t)}function v(t){return Object.keys(t).reduce((function(e,n){return void 0!==t[n]&&(e[n]=t[n]),e}),{})}function m(){return document.createElement("div")}function g(t){return["Element","Fragment"].some((function(e){return a(t,e)}))}function h(t){return a(t,"MouseEvent")}function b(t){return!(!t||!t._tippy||t._tippy.reference!==t)}function y(t){return g(t)?[t]:function(t){return a(t,"NodeList")}(t)?d(t):Array.isArray(t)?t:d(document.querySelectorAll(t))}function w(t,e){t.forEach((function(t){t&&(t.style.transitionDuration=e+"ms")}))}function x(t,e){t.forEach((function(t){t&&t.setAttribute("data-state",e)}))}function E(t){var e,n=c(t)[0];return null!=n&&null!=(e=n.ownerDocument)&&e.body?n.ownerDocument:document}function O(t,e,n){var r=e+"EventListener";["transitionend","webkitTransitionEnd"].forEach((function(e){t[r](e,n)}))}function C(t,e){for(var n=e;n;){var r;if(t.contains(n))return!0;n=null==n.getRootNode||null==(r=n.getRootNode())?void 0:r.host}return!1}var T={isTouch:!1},A=0;function L(){T.isTouch||(T.isTouch=!0,window.performance&&document.addEventListener("mousemove",D))}function D(){var t=performance.now();t-A<20&&(T.isTouch=!1,document.removeEventListener("mousemove",D)),A=t}function k(){var t=document.activeElement;if(b(t)){var e=t._tippy;t.blur&&!e.state.isVisible&&t.blur()}}var R=Object.assign({appendTo:o,aria:{content:"auto",expanded:"auto"},delay:0,duration:[300,250],getReferenceClientRect:null,hideOnClick:!0,ignoreAttributes:!1,interactive:!1,interactiveBorder:2,interactiveDebounce:0,moveTransition:"",offset:[0,10],onAfterUpdate:function(){},onBeforeUpdate:function(){},onCreate:function(){},onDestroy:function(){},onHidden:function(){},onHide:function(){},onMount:function(){},onShow:function(){},onShown:function(){},onTrigger:function(){},onUntrigger:function(){},onClickOutside:function(){},placement:"top",plugins:[],popperOptions:{},render:null,showOnCreate:!1,touch:!0,trigger:"mouseenter focus",triggerTarget:null},{animateFill:!1,followCursor:!1,inlinePositioning:!1,sticky:!1},{allowHTML:!1,animation:"fade",arrow:!0,content:"",inertia:!1,maxWidth:350,role:"tooltip",theme:"",zIndex:9999}),P=Object.keys(R);function j(t){var e=(t.plugins||[]).reduce((function(e,n){var r,o=n.name,i=n.defaultValue;o&&(e[o]=void 0!==t[o]?t[o]:null!=(r=R[o])?r:i);return e}),{});return Object.assign({},t,e)}function M(t,e){var n=Object.assign({},e,{content:s(e.content,[t])},e.ignoreAttributes?{}:function(t,e){return(e?Object.keys(j(Object.assign({},R,{plugins:e}))):P).reduce((function(e,n){var r=(t.getAttribute("data-tippy-"+n)||"").trim();if(!r)return e;if("content"===n)e[n]=r;else try{e[n]=JSON.parse(r)}catch(t){e[n]=r}return e}),{})}(t,e.plugins));return n.aria=Object.assign({},R.aria,n.aria),n.aria={expanded:"auto"===n.aria.expanded?e.interactive:n.aria.expanded,content:"auto"===n.aria.content?e.interactive?null:"describedby":n.aria.content},n}function V(t,e){t.innerHTML=e}function I(t){var e=m();return!0===t?e.className="tippy-arrow":(e.className="tippy-svg-arrow",g(t)?e.appendChild(t):V(e,t)),e}function S(t,e){g(e.content)?(V(t,""),t.appendChild(e.content)):"function"!=typeof e.content&&(e.allowHTML?V(t,e.content):t.textContent=e.content)}function B(t){var e=t.firstElementChild,n=d(e.children);return{box:e,content:n.find((function(t){return t.classList.contains("tippy-content")})),arrow:n.find((function(t){return t.classList.contains("tippy-arrow")||t.classList.contains("tippy-svg-arrow")})),backdrop:n.find((function(t){return t.classList.contains("tippy-backdrop")}))}}function N(t){var e=m(),n=m();n.className="tippy-box",n.setAttribute("data-state","hidden"),n.setAttribute("tabindex","-1");var r=m();function o(n,r){var o=B(e),i=o.box,a=o.content,s=o.arrow;r.theme?i.setAttribute("data-theme",r.theme):i.removeAttribute("data-theme"),"string"==typeof r.animation?i.setAttribute("data-animation",r.animation):i.removeAttribute("data-animation"),r.inertia?i.setAttribute("data-inertia",""):i.removeAttribute("data-inertia"),i.style.maxWidth="number"==typeof r.maxWidth?r.maxWidth+"px":r.maxWidth,r.role?i.setAttribute("role",r.role):i.removeAttribute("role"),n.content===r.content&&n.allowHTML===r.allowHTML||S(a,t.props),r.arrow?s?n.arrow!==r.arrow&&(i.removeChild(s),i.appendChild(I(r.arrow))):i.appendChild(I(r.arrow)):s&&i.removeChild(s)}return r.className="tippy-content",r.setAttribute("data-state","hidden"),S(r,t.props),e.appendChild(n),n.appendChild(r),o(t.props,t.props),{popper:e,onUpdate:o}}N.$$tippy=!0;var H=1,U=[],_=[];function z(e,a){var p,g,b,y,A,L,D,k,P=M(e,Object.assign({},R,j(v(a)))),V=!1,I=!1,S=!1,N=!1,z=[],F=u(wt,P.interactiveDebounce),W=H++,X=(k=P.plugins).filter((function(t,e){return k.indexOf(t)===e})),Y={id:W,reference:e,popper:m(),popperInstance:null,props:P,state:{isEnabled:!0,isVisible:!1,isDestroyed:!1,isMounted:!1,isShown:!1},plugins:X,clearDelayTimeouts:function(){clearTimeout(p),clearTimeout(g),cancelAnimationFrame(b)},setProps:function(t){if(Y.state.isDestroyed)return;at("onBeforeUpdate",[Y,t]),bt();var n=Y.props,r=M(e,Object.assign({},n,v(t),{ignoreAttributes:!0}));Y.props=r,ht(),n.interactiveDebounce!==r.interactiveDebounce&&(pt(),F=u(wt,r.interactiveDebounce));n.triggerTarget&&!r.triggerTarget?c(n.triggerTarget).forEach((function(t){t.removeAttribute("aria-expanded")})):r.triggerTarget&&e.removeAttribute("aria-expanded");ut(),it(),J&&J(n,r);Y.popperInstance&&(Ct(),At().forEach((function(t){requestAnimationFrame(t._tippy.popperInstance.forceUpdate)})));at("onAfterUpdate",[Y,t])},setContent:function(t){Y.setProps({content:t})},show:function(){var t=Y.state.isVisible,e=Y.state.isDestroyed,n=!Y.state.isEnabled,r=T.isTouch&&!Y.props.touch,a=i(Y.props.duration,0,R.duration);if(t||e||n||r)return;if(et().hasAttribute("disabled"))return;if(at("onShow",[Y],!1),!1===Y.props.onShow(Y))return;Y.state.isVisible=!0,tt()&&($.style.visibility="visible");it(),dt(),Y.state.isMounted||($.style.transition="none");if(tt()){var u=rt(),p=u.box,c=u.content;w([p,c],0)}L=function(){var t;if(Y.state.isVisible&&!N){if(N=!0,$.offsetHeight,$.style.transition=Y.props.moveTransition,tt()&&Y.props.animation){var e=rt(),n=e.box,r=e.content;w([n,r],a),x([n,r],"visible")}st(),ut(),f(_,Y),null==(t=Y.popperInstance)||t.forceUpdate(),at("onMount",[Y]),Y.props.animation&&tt()&&function(t,e){mt(t,e)}(a,(function(){Y.state.isShown=!0,at("onShown",[Y])}))}},function(){var t,e=Y.props.appendTo,n=et();t=Y.props.interactive&&e===o||"parent"===e?n.parentNode:s(e,[n]);t.contains($)||t.appendChild($);Y.state.isMounted=!0,Ct()}()},hide:function(){var t=!Y.state.isVisible,e=Y.state.isDestroyed,n=!Y.state.isEnabled,r=i(Y.props.duration,1,R.duration);if(t||e||n)return;if(at("onHide",[Y],!1),!1===Y.props.onHide(Y))return;Y.state.isVisible=!1,Y.state.isShown=!1,N=!1,V=!1,tt()&&($.style.visibility="hidden");if(pt(),vt(),it(!0),tt()){var o=rt(),a=o.box,s=o.content;Y.props.animation&&(w([a,s],r),x([a,s],"hidden"))}st(),ut(),Y.props.animation?tt()&&function(t,e){mt(t,(function(){!Y.state.isVisible&&$.parentNode&&$.parentNode.contains($)&&e()}))}(r,Y.unmount):Y.unmount()},hideWithInteractivity:function(t){nt().addEventListener("mousemove",F),f(U,F),F(t)},enable:function(){Y.state.isEnabled=!0},disable:function(){Y.hide(),Y.state.isEnabled=!1},unmount:function(){Y.state.isVisible&&Y.hide();if(!Y.state.isMounted)return;Tt(),At().forEach((function(t){t._tippy.unmount()})),$.parentNode&&$.parentNode.removeChild($);_=_.filter((function(t){return t!==Y})),Y.state.isMounted=!1,at("onHidden",[Y])},destroy:function(){if(Y.state.isDestroyed)return;Y.clearDelayTimeouts(),Y.unmount(),bt(),delete e._tippy,Y.state.isDestroyed=!0,at("onDestroy",[Y])}};if(!P.render)return Y;var q=P.render(Y),$=q.popper,J=q.onUpdate;$.setAttribute("data-tippy-root",""),$.id="tippy-"+Y.id,Y.popper=$,e._tippy=Y,$._tippy=Y;var G=X.map((function(t){return t.fn(Y)})),K=e.hasAttribute("aria-expanded");return ht(),ut(),it(),at("onCreate",[Y]),P.showOnCreate&&Lt(),$.addEventListener("mouseenter",(function(){Y.props.interactive&&Y.state.isVisible&&Y.clearDelayTimeouts()})),$.addEventListener("mouseleave",(function(){Y.props.interactive&&Y.props.trigger.indexOf("mouseenter")>=0&&nt().addEventListener("mousemove",F)})),Y;function Q(){var t=Y.props.touch;return Array.isArray(t)?t:[t,0]}function Z(){return"hold"===Q()[0]}function tt(){var t;return!(null==(t=Y.props.render)||!t.$$tippy)}function et(){return D||e}function nt(){var t=et().parentNode;return t?E(t):document}function rt(){return B($)}function ot(t){return Y.state.isMounted&&!Y.state.isVisible||T.isTouch||y&&"focus"===y.type?0:i(Y.props.delay,t?0:1,R.delay)}function it(t){void 0===t&&(t=!1),$.style.pointerEvents=Y.props.interactive&&!t?"":"none",$.style.zIndex=""+Y.props.zIndex}function at(t,e,n){var r;(void 0===n&&(n=!0),G.forEach((function(n){n[t]&&n[t].apply(n,e)})),n)&&(r=Y.props)[t].apply(r,e)}function st(){var t=Y.props.aria;if(t.content){var n="aria-"+t.content,r=$.id;c(Y.props.triggerTarget||e).forEach((function(t){var e=t.getAttribute(n);if(Y.state.isVisible)t.setAttribute(n,e?e+" "+r:r);else{var o=e&&e.replace(r,"").trim();o?t.setAttribute(n,o):t.removeAttribute(n)}}))}}function ut(){!K&&Y.props.aria.expanded&&c(Y.props.triggerTarget||e).forEach((function(t){Y.props.interactive?t.setAttribute("aria-expanded",Y.state.isVisible&&t===et()?"true":"false"):t.removeAttribute("aria-expanded")}))}function pt(){nt().removeEventListener("mousemove",F),U=U.filter((function(t){return t!==F}))}function ct(t){if(!T.isTouch||!S&&"mousedown"!==t.type){var n=t.composedPath&&t.composedPath()[0]||t.target;if(!Y.props.interactive||!C($,n)){if(c(Y.props.triggerTarget||e).some((function(t){return C(t,n)}))){if(T.isTouch)return;if(Y.state.isVisible&&Y.props.trigger.indexOf("click")>=0)return}else at("onClickOutside",[Y,t]);!0===Y.props.hideOnClick&&(Y.clearDelayTimeouts(),Y.hide(),I=!0,setTimeout((function(){I=!1})),Y.state.isMounted||vt())}}}function ft(){S=!0}function lt(){S=!1}function dt(){var t=nt();t.addEventListener("mousedown",ct,!0),t.addEventListener("touchend",ct,r),t.addEventListener("touchstart",lt,r),t.addEventListener("touchmove",ft,r)}function vt(){var t=nt();t.removeEventListener("mousedown",ct,!0),t.removeEventListener("touchend",ct,r),t.removeEventListener("touchstart",lt,r),t.removeEventListener("touchmove",ft,r)}function mt(t,e){var n=rt().box;function r(t){t.target===n&&(O(n,"remove",r),e())}if(0===t)return e();O(n,"remove",A),O(n,"add",r),A=r}function gt(t,n,r){void 0===r&&(r=!1),c(Y.props.triggerTarget||e).forEach((function(e){e.addEventListener(t,n,r),z.push({node:e,eventType:t,handler:n,options:r})}))}function ht(){var t;Z()&&(gt("touchstart",yt,{passive:!0}),gt("touchend",xt,{passive:!0})),(t=Y.props.trigger,t.split(/\s+/).filter(Boolean)).forEach((function(t){if("manual"!==t)switch(gt(t,yt),t){case"mouseenter":gt("mouseleave",xt);break;case"focus":gt(n?"focusout":"blur",Et);break;case"focusin":gt("focusout",Et)}}))}function bt(){z.forEach((function(t){var e=t.node,n=t.eventType,r=t.handler,o=t.options;e.removeEventListener(n,r,o)})),z=[]}function yt(t){var e,n=!1;if(Y.state.isEnabled&&!Ot(t)&&!I){var r="focus"===(null==(e=y)?void 0:e.type);y=t,D=t.currentTarget,ut(),!Y.state.isVisible&&h(t)&&U.forEach((function(e){return e(t)})),"click"===t.type&&(Y.props.trigger.indexOf("mouseenter")<0||V)&&!1!==Y.props.hideOnClick&&Y.state.isVisible?n=!0:Lt(t),"click"===t.type&&(V=!n),n&&!r&&Dt(t)}}function wt(t){var e=t.target,n=et().contains(e)||$.contains(e);"mousemove"===t.type&&n||function(t,e){var n=e.clientX,r=e.clientY;return t.every((function(t){var e=t.popperRect,o=t.popperState,i=t.props.interactiveBorder,a=l(o.placement),s=o.modifiersData.offset;if(!s)return!0;var u="bottom"===a?s.top.y:0,p="top"===a?s.bottom.y:0,c="right"===a?s.left.x:0,f="left"===a?s.right.x:0,d=e.top-r+u>i,v=r-e.bottom-p>i,m=e.left-n+c>i,g=n-e.right-f>i;return d||v||m||g}))}(At().concat($).map((function(t){var e,n=null==(e=t._tippy.popperInstance)?void 0:e.state;return n?{popperRect:t.getBoundingClientRect(),popperState:n,props:P}:null})).filter(Boolean),t)&&(pt(),Dt(t))}function xt(t){Ot(t)||Y.props.trigger.indexOf("click")>=0&&V||(Y.props.interactive?Y.hideWithInteractivity(t):Dt(t))}function Et(t){Y.props.trigger.indexOf("focusin")<0&&t.target!==et()||Y.props.interactive&&t.relatedTarget&&$.contains(t.relatedTarget)||Dt(t)}function Ot(t){return!!T.isTouch&&Z()!==t.type.indexOf("touch")>=0}function Ct(){Tt();var n=Y.props,r=n.popperOptions,o=n.placement,i=n.offset,a=n.getReferenceClientRect,s=n.moveTransition,u=tt()?B($).arrow:null,p=a?{getBoundingClientRect:a,contextElement:a.contextElement||et()}:e,c=[{name:"offset",options:{offset:i}},{name:"preventOverflow",options:{padding:{top:2,bottom:2,left:5,right:5}}},{name:"flip",options:{padding:5}},{name:"computeStyles",options:{adaptive:!s}},{name:"$$tippy",enabled:!0,phase:"beforeWrite",requires:["computeStyles"],fn:function(t){var e=t.state;if(tt()){var n=rt().box;["placement","reference-hidden","escaped"].forEach((function(t){"placement"===t?n.setAttribute("data-placement",e.placement):e.attributes.popper["data-popper-"+t]?n.setAttribute("data-"+t,""):n.removeAttribute("data-"+t)})),e.attributes.popper={}}}}];tt()&&u&&c.push({name:"arrow",options:{element:u,padding:3}}),c.push.apply(c,(null==r?void 0:r.modifiers)||[]),Y.popperInstance=t.createPopper(p,$,Object.assign({},r,{placement:o,onFirstUpdate:L,modifiers:c}))}function Tt(){Y.popperInstance&&(Y.popperInstance.destroy(),Y.popperInstance=null)}function At(){return d($.querySelectorAll("[data-tippy-root]"))}function Lt(t){Y.clearDelayTimeouts(),t&&at("onTrigger",[Y,t]),dt();var e=ot(!0),n=Q(),r=n[0],o=n[1];T.isTouch&&"hold"===r&&o&&(e=o),e?p=setTimeout((function(){Y.show()}),e):Y.show()}function Dt(t){if(Y.clearDelayTimeouts(),at("onUntrigger",[Y,t]),Y.state.isVisible){if(!(Y.props.trigger.indexOf("mouseenter")>=0&&Y.props.trigger.indexOf("click")>=0&&["mouseleave","mousemove"].indexOf(t.type)>=0&&V)){var e=ot(!1);e?g=setTimeout((function(){Y.state.isVisible&&Y.hide()}),e):b=requestAnimationFrame((function(){Y.hide()}))}}else vt()}}function F(t,e){void 0===e&&(e={});var n=R.plugins.concat(e.plugins||[]);document.addEventListener("touchstart",L,r),window.addEventListener("blur",k);var o=Object.assign({},e,{plugins:n}),i=y(t).reduce((function(t,e){var n=e&&z(e,o);return n&&t.push(n),t}),[]);return g(t)?i[0]:i}F.defaultProps=R,F.setDefaultProps=function(t){Object.keys(t).forEach((function(e){R[e]=t[e]}))},F.currentInput=T;var W=Object.assign({},t.applyStyles,{effect:function(t){var e=t.state,n={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};Object.assign(e.elements.popper.style,n.popper),e.styles=n,e.elements.arrow&&Object.assign(e.elements.arrow.style,n.arrow)}}),X={mouseover:"mouseenter",focusin:"focus",click:"click"};var Y={name:"animateFill",defaultValue:!1,fn:function(t){var e;if(null==(e=t.props.render)||!e.$$tippy)return{};var n=B(t.popper),r=n.box,o=n.content,i=t.props.animateFill?function(){var t=m();return t.className="tippy-backdrop",x([t],"hidden"),t}():null;return{onCreate:function(){i&&(r.insertBefore(i,r.firstElementChild),r.setAttribute("data-animatefill",""),r.style.overflow="hidden",t.setProps({arrow:!1,animation:"shift-away"}))},onMount:function(){if(i){var t=r.style.transitionDuration,e=Number(t.replace("ms",""));o.style.transitionDelay=Math.round(e/10)+"ms",i.style.transitionDuration=t,x([i],"visible")}},onShow:function(){i&&(i.style.transitionDuration="0ms")},onHide:function(){i&&x([i],"hidden")}}}};var q={clientX:0,clientY:0},$=[];function J(t){var e=t.clientX,n=t.clientY;q={clientX:e,clientY:n}}var G={name:"followCursor",defaultValue:!1,fn:function(t){var e=t.reference,n=E(t.props.triggerTarget||e),r=!1,o=!1,i=!0,a=t.props;function s(){return"initial"===t.props.followCursor&&t.state.isVisible}function u(){n.addEventListener("mousemove",f)}function p(){n.removeEventListener("mousemove",f)}function c(){r=!0,t.setProps({getReferenceClientRect:null}),r=!1}function f(n){var r=!n.target||e.contains(n.target),o=t.props.followCursor,i=n.clientX,a=n.clientY,s=e.getBoundingClientRect(),u=i-s.left,p=a-s.top;!r&&t.props.interactive||t.setProps({getReferenceClientRect:function(){var t=e.getBoundingClientRect(),n=i,r=a;"initial"===o&&(n=t.left+u,r=t.top+p);var s="horizontal"===o?t.top:r,c="vertical"===o?t.right:n,f="horizontal"===o?t.bottom:r,l="vertical"===o?t.left:n;return{width:c-l,height:f-s,top:s,right:c,bottom:f,left:l}}})}function l(){t.props.followCursor&&($.push({instance:t,doc:n}),function(t){t.addEventListener("mousemove",J)}(n))}function d(){0===($=$.filter((function(e){return e.instance!==t}))).filter((function(t){return t.doc===n})).length&&function(t){t.removeEventListener("mousemove",J)}(n)}return{onCreate:l,onDestroy:d,onBeforeUpdate:function(){a=t.props},onAfterUpdate:function(e,n){var i=n.followCursor;r||void 0!==i&&a.followCursor!==i&&(d(),i?(l(),!t.state.isMounted||o||s()||u()):(p(),c()))},onMount:function(){t.props.followCursor&&!o&&(i&&(f(q),i=!1),s()||u())},onTrigger:function(t,e){h(e)&&(q={clientX:e.clientX,clientY:e.clientY}),o="focus"===e.type},onHidden:function(){t.props.followCursor&&(c(),p(),i=!0)}}}};var K={name:"inlinePositioning",defaultValue:!1,fn:function(t){var e,n=t.reference;var r=-1,o=!1,i=[],a={name:"tippyInlinePositioning",enabled:!0,phase:"afterWrite",fn:function(o){var a=o.state;t.props.inlinePositioning&&(-1!==i.indexOf(a.placement)&&(i=[]),e!==a.placement&&-1===i.indexOf(a.placement)&&(i.push(a.placement),t.setProps({getReferenceClientRect:function(){return function(t){return function(t,e,n,r){if(n.length<2||null===t)return e;if(2===n.length&&r>=0&&n[0].left>n[1].right)return n[r]||e;switch(t){case"top":case"bottom":var o=n[0],i=n[n.length-1],a="top"===t,s=o.top,u=i.bottom,p=a?o.left:i.left,c=a?o.right:i.right;return{top:s,bottom:u,left:p,right:c,width:c-p,height:u-s};case"left":case"right":var f=Math.min.apply(Math,n.map((function(t){return t.left}))),l=Math.max.apply(Math,n.map((function(t){return t.right}))),d=n.filter((function(e){return"left"===t?e.left===f:e.right===l})),v=d[0].top,m=d[d.length-1].bottom;return{top:v,bottom:m,left:f,right:l,width:l-f,height:m-v};default:return e}}(l(t),n.getBoundingClientRect(),d(n.getClientRects()),r)}(a.placement)}})),e=a.placement)}};function s(){var e;o||(e=function(t,e){var n;return{popperOptions:Object.assign({},t.popperOptions,{modifiers:[].concat(((null==(n=t.popperOptions)?void 0:n.modifiers)||[]).filter((function(t){return t.name!==e.name})),[e])})}}(t.props,a),o=!0,t.setProps(e),o=!1)}return{onCreate:s,onAfterUpdate:s,onTrigger:function(e,n){if(h(n)){var o=d(t.reference.getClientRects()),i=o.find((function(t){return t.left-2<=n.clientX&&t.right+2>=n.clientX&&t.top-2<=n.clientY&&t.bottom+2>=n.clientY})),a=o.indexOf(i);r=a>-1?a:r}},onHidden:function(){r=-1}}}};var Q={name:"sticky",defaultValue:!1,fn:function(t){var e=t.reference,n=t.popper;function r(e){return!0===t.props.sticky||t.props.sticky===e}var o=null,i=null;function a(){var s=r("reference")?(t.popperInstance?t.popperInstance.state.elements.reference:e).getBoundingClientRect():null,u=r("popper")?n.getBoundingClientRect():null;(s&&Z(o,s)||u&&Z(i,u))&&t.popperInstance&&t.popperInstance.update(),o=s,i=u,t.state.isMounted&&requestAnimationFrame(a)}return{onMount:function(){t.props.sticky&&a()}}}};function Z(t,e){return!t||!e||(t.top!==e.top||t.right!==e.right||t.bottom!==e.bottom||t.left!==e.left)}return e&&function(t){var e=document.createElement("style");e.textContent=t,e.setAttribute("data-tippy-stylesheet","");var n=document.head,r=document.querySelector("head>style,head>link");r?n.insertBefore(e,r):n.appendChild(e)}('.tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{position:relative;background-color:#333;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;white-space:normal;outline:0;transition-property:transform,visibility,opacity}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1}'),F.setDefaultProps({plugins:[Y,G,K,Q],render:N}),F.createSingleton=function(t,e){var n;void 0===e&&(e={});var r,o=t,i=[],a=[],s=e.overrides,u=[],f=!1;function l(){a=o.map((function(t){return c(t.props.triggerTarget||t.reference)})).reduce((function(t,e){return t.concat(e)}),[])}function d(){i=o.map((function(t){return t.reference}))}function v(t){o.forEach((function(e){t?e.enable():e.disable()}))}function g(t){return o.map((function(e){var n=e.setProps;return e.setProps=function(o){n(o),e.reference===r&&t.setProps(o)},function(){e.setProps=n}}))}function h(t,e){var n=a.indexOf(e);if(e!==r){r=e;var u=(s||[]).concat("content").reduce((function(t,e){return t[e]=o[n].props[e],t}),{});t.setProps(Object.assign({},u,{getReferenceClientRect:"function"==typeof u.getReferenceClientRect?u.getReferenceClientRect:function(){var t;return null==(t=i[n])?void 0:t.getBoundingClientRect()}}))}}v(!1),d(),l();var b={fn:function(){return{onDestroy:function(){v(!0)},onHidden:function(){r=null},onClickOutside:function(t){t.props.showOnCreate&&!f&&(f=!0,r=null)},onShow:function(t){t.props.showOnCreate&&!f&&(f=!0,h(t,i[0]))},onTrigger:function(t,e){h(t,e.currentTarget)}}}},y=F(m(),Object.assign({},p(e,["overrides"]),{plugins:[b].concat(e.plugins||[]),triggerTarget:a,popperOptions:Object.assign({},e.popperOptions,{modifiers:[].concat((null==(n=e.popperOptions)?void 0:n.modifiers)||[],[W])})})),w=y.show;y.show=function(t){if(w(),!r&&null==t)return h(y,i[0]);if(!r||null!=t){if("number"==typeof t)return i[t]&&h(y,i[t]);if(o.indexOf(t)>=0){var e=t.reference;return h(y,e)}return i.indexOf(t)>=0?h(y,t):void 0}},y.showNext=function(){var t=i[0];if(!r)return y.show(0);var e=i.indexOf(r);y.show(i[e+1]||t)},y.showPrevious=function(){var t=i[i.length-1];if(!r)return y.show(t);var e=i.indexOf(r),n=i[e-1]||t;y.show(n)};var x=y.setProps;return y.setProps=function(t){s=t.overrides||s,x(t)},y.setInstances=function(t){v(!0),u.forEach((function(t){return t()})),o=t,v(!1),d(),l(),u=g(y),y.setProps({triggerTarget:a})},u=g(y),y},F.delegate=function(t,e){var n=[],o=[],i=!1,a=e.target,s=p(e,["target"]),u=Object.assign({},s,{trigger:"manual",touch:!1}),f=Object.assign({touch:R.touch},s,{showOnCreate:!0}),l=F(t,u);function d(t){if(t.target&&!i){var n=t.target.closest(a);if(n){var r=n.getAttribute("data-tippy-trigger")||e.trigger||R.trigger;if(!n._tippy&&!("touchstart"===t.type&&"boolean"==typeof f.touch||"touchstart"!==t.type&&r.indexOf(X[t.type])<0)){var s=F(n,f);s&&(o=o.concat(s))}}}}function v(t,e,r,o){void 0===o&&(o=!1),t.addEventListener(e,r,o),n.push({node:t,eventType:e,handler:r,options:o})}return c(l).forEach((function(t){var e=t.destroy,a=t.enable,s=t.disable;t.destroy=function(t){void 0===t&&(t=!0),t&&o.forEach((function(t){t.destroy()})),o=[],n.forEach((function(t){var e=t.node,n=t.eventType,r=t.handler,o=t.options;e.removeEventListener(n,r,o)})),n=[],e()},t.enable=function(){a(),o.forEach((function(t){return t.enable()})),i=!1},t.disable=function(){s(),o.forEach((function(t){return t.disable()})),i=!0},function(t){var e=t.reference;v(e,"touchstart",d,r),v(e,"mouseover",d),v(e,"focusin",d),v(e,"click",d)}(t)})),l},F.hideAll=function(t){var e=void 0===t?{}:t,n=e.exclude,r=e.duration;_.forEach((function(t){var e=!1;if(n&&(e=b(n)?t.reference===n:t.popper===n.popper),!e){var o=t.props.duration;t.setProps({duration:r}),t.hide(),t.state.isDestroyed||t.setProps({duration:o})}}))},F.roundArrow='<svg width="16" height="6" xmlns="http://www.w3.org/2000/svg"><path d="M0 6s1.796-.013 4.67-3.615C5.851.9 6.93.006 8 0c1.07-.006 2.148.887 3.343 2.385C14.233 6.005 16 6 16 6H0z"></svg>',F})); diff --git a/doc/scripts/third-party/tocbot.js b/doc/scripts/third-party/tocbot.js new file mode 100644 index 0000000000000000000000000000000000000000..32accd308496b2a95f852e040761c3d08b6a1028 --- /dev/null +++ b/doc/scripts/third-party/tocbot.js @@ -0,0 +1,672 @@ +/* eslint no-var: off */ +var defaultOptions = { + ignoreSelector: '.js-toc-ignore', + linkClass: 'toc-link', + extraLinkClasses: '', + activeLinkClass: 'is-active-link', + listClass: 'toc-list', + extraListClasses: '', + isCollapsedClass: 'is-collapsed', + collapsibleClass: 'is-collapsible', + listItemClass: 'toc-list-item', + activeListItemClass: 'is-active-li', + collapseDepth: 0, + scrollSmooth: true, + scrollSmoothDuration: 420, + scrollSmoothOffset: 0, + scrollEndCallback: function (e) { }, + throttleTimeout: 50, + positionFixedSelector: null, + positionFixedClass: 'is-position-fixed', + fixedSidebarOffset: 'auto', + includeHtml: false, + includeTitleTags: false, + orderedList: true, + scrollContainer: null, + skipRendering: false, + headingLabelCallback: false, + ignoreHiddenElements: false, + headingObjectCallback: null, + basePath: '', + disableTocScrollSync: false +} + +function ParseContent(options) { + var reduce = [].reduce + + /** + * Get the last item in an array and return a reference to it. + * @param {Array} array + * @return {Object} + */ + function getLastItem(array) { + return array[array.length - 1] + } + + /** + * Get heading level for a heading dom node. + * @param {HTMLElement} heading + * @return {Number} + */ + function getHeadingLevel(heading) { + return +heading.nodeName.toUpperCase().replace('H', '') + } + + /** + * Get important properties from a heading element and store in a plain object. + * @param {HTMLElement} heading + * @return {Object} + */ + function getHeadingObject(heading) { + // each node is processed twice by this method because nestHeadingsArray() and addNode() calls it + // first time heading is real DOM node element, second time it is obj + // that is causing problem so I am processing only original DOM node + if (!(heading instanceof window.HTMLElement)) return heading + + if (options.ignoreHiddenElements && (!heading.offsetHeight || !heading.offsetParent)) { + return null + } + + const headingLabel = heading.getAttribute('data-heading-label') || + (options.headingLabelCallback ? String(options.headingLabelCallback(heading.textContent)) : heading.textContent.trim()) + var obj = { + id: heading.id, + children: [], + nodeName: heading.nodeName, + headingLevel: getHeadingLevel(heading), + textContent: headingLabel + } + + if (options.includeHtml) { + obj.childNodes = heading.childNodes + } + + if (options.headingObjectCallback) { + return options.headingObjectCallback(obj, heading) + } + + return obj + } + + /** + * Add a node to the nested array. + * @param {Object} node + * @param {Array} nest + * @return {Array} + */ + function addNode(node, nest) { + var obj = getHeadingObject(node) + var level = obj.headingLevel + var array = nest + var lastItem = getLastItem(array) + var lastItemLevel = lastItem + ? lastItem.headingLevel + : 0 + var counter = level - lastItemLevel + + while (counter > 0) { + lastItem = getLastItem(array) + // Handle case where there are multiple h5+ in a row. + if (lastItem && level === lastItem.headingLevel) { + break + } else if (lastItem && lastItem.children !== undefined) { + array = lastItem.children + } + counter-- + } + + if (level >= options.collapseDepth) { + obj.isCollapsed = true + } + + array.push(obj) + return array + } + + /** + * Select headings in content area, exclude any selector in options.ignoreSelector + * @param {HTMLElement} contentElement + * @param {Array} headingSelector + * @return {Array} + */ + function selectHeadings(contentElement, headingSelector) { + var selectors = headingSelector + if (options.ignoreSelector) { + selectors = headingSelector.split(',') + .map(function mapSelectors(selector) { + return selector.trim() + ':not(' + options.ignoreSelector + ')' + }) + } + try { + return contentElement.querySelectorAll(selectors) + } catch (e) { + console.warn('Headers not found with selector: ' + selectors); // eslint-disable-line + return null + } + } + + /** + * Nest headings array into nested arrays with 'children' property. + * @param {Array} headingsArray + * @return {Object} + */ + function nestHeadingsArray(headingsArray) { + return reduce.call(headingsArray, function reducer(prev, curr) { + var currentHeading = getHeadingObject(curr) + if (currentHeading) { + addNode(currentHeading, prev.nest) + } + return prev + }, { + nest: [] + }) + } + + return { + nestHeadingsArray: nestHeadingsArray, + selectHeadings: selectHeadings + } +} + +function BuildHtml(options) { + var forEach = [].forEach + var some = [].some + var body = document.body + var tocElement + var mainContainer = document.querySelector(options.contentSelector) + var currentlyHighlighting = true + var SPACE_CHAR = ' ' + + /** + * Create link and list elements. + * @param {Object} d + * @param {HTMLElement} container + * @return {HTMLElement} + */ + function createEl(d, container) { + var link = container.appendChild(createLink(d)) + if (d.children.length) { + var list = createList(d.isCollapsed) + d.children.forEach(function (child) { + createEl(child, list) + }) + link.appendChild(list) + } + } + + /** + * Render nested heading array data into a given element. + * @param {HTMLElement} parent Optional. If provided updates the {@see tocElement} to match. + * @param {Array} data + * @return {HTMLElement} + */ + function render(parent, data) { + var collapsed = false + var container = createList(collapsed) + + data.forEach(function (d) { + createEl(d, container) + }) + + // Return if no TOC element is provided or known. + tocElement = parent || tocElement + if (tocElement === null) { + return + } + + // Remove existing child if it exists. + if (tocElement.firstChild) { + tocElement.removeChild(tocElement.firstChild) + } + + // Just return the parent and don't append the list if no links are found. + if (data.length === 0) { + return tocElement + } + + // Append the Elements that have been created + return tocElement.appendChild(container) + } + + /** + * Create link element. + * @param {Object} data + * @return {HTMLElement} + */ + function createLink(data) { + var item = document.createElement('li') + var a = document.createElement('a') + if (options.listItemClass) { + item.setAttribute('class', options.listItemClass) + } + + if (options.onClick) { + a.onclick = options.onClick + } + + if (options.includeTitleTags) { + a.setAttribute('title', data.textContent) + } + + if (options.includeHtml && data.childNodes.length) { + forEach.call(data.childNodes, function (node) { + a.appendChild(node.cloneNode(true)) + }) + } else { + // Default behavior. + a.textContent = data.textContent + } + a.setAttribute('href', options.basePath + '#' + data.id) + a.setAttribute('class', options.linkClass + + SPACE_CHAR + 'node-name--' + data.nodeName + + SPACE_CHAR + options.extraLinkClasses) + item.appendChild(a) + return item + } + + /** + * Create list element. + * @param {Boolean} isCollapsed + * @return {HTMLElement} + */ + function createList(isCollapsed) { + var listElement = (options.orderedList) ? 'ol' : 'ul' + var list = document.createElement(listElement) + var classes = options.listClass + + SPACE_CHAR + options.extraListClasses + if (isCollapsed) { + classes += SPACE_CHAR + options.collapsibleClass + classes += SPACE_CHAR + options.isCollapsedClass + } + list.setAttribute('class', classes) + return list + } + + /** + * Update fixed sidebar class. + * @return {HTMLElement} + */ + function updateFixedSidebarClass() { + if (options.scrollContainer && document.querySelector(options.scrollContainer)) { + var top + top = document.querySelector(options.scrollContainer).scrollTop + } else { + top = document.documentElement.scrollTop || body.scrollTop + } + var posFixedEl = document.querySelector(options.positionFixedSelector) + + if (options.fixedSidebarOffset === 'auto') { + options.fixedSidebarOffset = tocElement.offsetTop + } + + if (top > options.fixedSidebarOffset) { + if (posFixedEl.className.indexOf(options.positionFixedClass) === -1) { + posFixedEl.className += SPACE_CHAR + options.positionFixedClass + } + } else { + posFixedEl.className = posFixedEl.className.split(SPACE_CHAR + options.positionFixedClass).join('') + } + } + + /** + * Get top position of heading + * @param {HTMLElement} obj + * @return {int} position + */ + function getHeadingTopPos(obj) { + var position = 0 + if (obj !== null) { + position = obj.offsetTop + if (options.hasInnerContainers) { position += getHeadingTopPos(obj.offsetParent) } + } + return position + } + + + function updateListActiveElement(topHeader) { + var forEach = [].forEach + + var tocLinks = tocElement + .querySelectorAll('.' + options.linkClass) + forEach.call(tocLinks, function (tocLink) { + tocLink.className = tocLink.className.split(SPACE_CHAR + options.activeLinkClass).join('') + }) + var tocLis = tocElement + .querySelectorAll('.' + options.listItemClass) + forEach.call(tocLis, function (tocLi) { + tocLi.className = tocLi.className.split(SPACE_CHAR + options.activeListItemClass).join('') + }) + + // Add the active class to the active tocLink. + var activeTocLink = tocElement + .querySelector('.' + options.linkClass + + '.node-name--' + topHeader.nodeName + + '[href="' + options.basePath + '#' + topHeader.id.replace(/([ #;&,.+*~':"!^$[\]()=>|/@])/g, '\\$1') + '"]') + if (activeTocLink && activeTocLink.className.indexOf(options.activeLinkClass) === -1) { + activeTocLink.className += SPACE_CHAR + options.activeLinkClass + } + var li = activeTocLink && activeTocLink.parentNode + if (li && li.className.indexOf(options.activeListItemClass) === -1) { + li.className += SPACE_CHAR + options.activeListItemClass + } + + var tocLists = tocElement + .querySelectorAll('.' + options.listClass + '.' + options.collapsibleClass) + + // Collapse the other collapsible lists. + forEach.call(tocLists, function (list) { + if (list.className.indexOf(options.isCollapsedClass) === -1) { + list.className += SPACE_CHAR + options.isCollapsedClass + } + }) + + // Expand the active link's collapsible list and its sibling if applicable. + if (activeTocLink && activeTocLink.nextSibling && activeTocLink.nextSibling.className.indexOf(options.isCollapsedClass) !== -1) { + activeTocLink.nextSibling.className = activeTocLink.nextSibling.className.split(SPACE_CHAR + options.isCollapsedClass).join('') + } + removeCollapsedFromParents(activeTocLink && activeTocLink.parentNode.parentNode) + } + + /** + * Update TOC highlighting and collpased groupings. + */ + function updateToc(headingsArray) { + // If a fixed content container was set + if (options.scrollContainer && document.querySelector(options.scrollContainer)) { + var top + top = document.querySelector(options.scrollContainer).scrollTop + } else { + top = document.documentElement.scrollTop || body.scrollTop + } + + // Add fixed class at offset + if (options.positionFixedSelector) { + updateFixedSidebarClass() + } + + // Get the top most heading currently visible on the page so we know what to highlight. + var headings = headingsArray + var topHeader + // Using some instead of each so that we can escape early. + if (currentlyHighlighting && + tocElement !== null && + headings.length > 0) { + some.call(headings, function (heading, i) { + var modifiedTopOffset = top + 10 + if (mainContainer) { + modifiedTopOffset += mainContainer.clientHeight * (mainContainer.scrollTop) / (mainContainer.scrollHeight - mainContainer.clientHeight) + } + if (getHeadingTopPos(heading) > modifiedTopOffset) { + // Don't allow negative index value. + var index = (i === 0) ? i : i - 1 + topHeader = headings[index] + return true + } else if (i === headings.length - 1) { + // This allows scrolling for the last heading on the page. + topHeader = headings[headings.length - 1] + return true + } + }) + + // Remove the active class from the other tocLinks. + updateListActiveElement(topHeader) + } + } + + /** + * Remove collpased class from parent elements. + * @param {HTMLElement} element + * @return {HTMLElement} + */ + function removeCollapsedFromParents(element) { + if (element && element.className.indexOf(options.collapsibleClass) !== -1 && element.className.indexOf(options.isCollapsedClass) !== -1) { + element.className = element.className.split(SPACE_CHAR + options.isCollapsedClass).join('') + return removeCollapsedFromParents(element.parentNode.parentNode) + } + return element + } + + /** + * Disable TOC Animation when a link is clicked. + * @param {Event} event + */ + function disableTocAnimation(event) { + var target = event.target || event.srcElement + if (typeof target.className !== 'string' || target.className.indexOf(options.linkClass) === -1) { + return + } + // Bind to tocLink clicks to temporarily disable highlighting + // while smoothScroll is animating. + currentlyHighlighting = false + } + + /** + * Enable TOC Animation. + */ + function enableTocAnimation() { + currentlyHighlighting = true + } + + return { + enableTocAnimation: enableTocAnimation, + disableTocAnimation: disableTocAnimation, + render: render, + updateToc: updateToc, + updateListActiveElement: updateListActiveElement + } +} + +function updateTocScroll(options) { + var toc = options.tocElement || document.querySelector(options.tocSelector) + if (toc && toc.scrollHeight > toc.clientHeight) { + var activeItem = toc.querySelector('.' + options.activeListItemClass) + if (activeItem) { + var topOffset = toc.getBoundingClientRect().top + toc.scrollTop = activeItem.offsetTop - topOffset + } + } +} + +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + define([], factory(root)) + } else if (typeof exports === 'object') { + module.exports = factory(root) + } else { + root.tocbot = factory(root) + } +})(typeof global !== 'undefined' ? global : this.window || this.global, function (root) { + 'use strict' + + var options = {} + var tocbot = {} + var buildHtml + var parseContent + + // Just return if its not a browser. + var supports = !!root && !!root.document && !!root.document.querySelector && !!root.addEventListener // Feature test + if (typeof window === 'undefined' && !supports) { + return + } + var headingsArray + + // From: https://github.com/Raynos/xtend + var hasOwnProperty = Object.prototype.hasOwnProperty + function extend() { + var target = {} + for (var i = 0; i < arguments.length; i++) { + var source = arguments[i] + for (var key in source) { + if (hasOwnProperty.call(source, key)) { + target[key] = source[key] + } + } + } + return target + } + + // From: https://remysharp.com/2010/07/21/throttling-function-calls + function throttle(fn, threshhold, scope) { + threshhold || (threshhold = 250) + var last + var deferTimer + return function () { + var context = scope || this + var now = +new Date() + var args = arguments + if (last && now < last + threshhold) { + // hold on to it + clearTimeout(deferTimer) + deferTimer = setTimeout(function () { + last = now + fn.apply(context, args) + }, threshhold) + } else { + last = now + fn.apply(context, args) + } + } + } + + function getContentElement(options) { + try { + return options.contentElement || document.querySelector(options.contentSelector) + } catch (e) { + console.warn('Contents element not found: ' + options.contentSelector) // eslint-disable-line + return null + } + } + + function getTocElement(options) { + try { + return options.tocElement || document.querySelector(options.tocSelector) + } catch (e) { + console.warn('TOC element not found: ' + options.tocSelector) // eslint-disable-line + return null + } + } + + /** + * Destroy tocbot. + */ + tocbot.destroy = function () { + var tocElement = getTocElement(options) + if (tocElement === null) { + return + } + + if (!options.skipRendering) { + // Clear HTML. + if (tocElement) { + tocElement.innerHTML = '' + } + } + + // Remove event listeners. + if (options.scrollContainer && document.querySelector(options.scrollContainer)) { + document.querySelector(options.scrollContainer).removeEventListener('scroll', this._scrollListener, false) + document.querySelector(options.scrollContainer).removeEventListener('resize', this._scrollListener, false) + } else { + document.removeEventListener('scroll', this._scrollListener, false) + document.removeEventListener('resize', this._scrollListener, false) + } + } + + /** + * Initialize tocbot. + * @param {object} customOptions + */ + tocbot.init = function (customOptions) { + // feature test + if (!supports) { + return + } + + // Merge defaults with user options. + // Set to options variable at the top. + options = extend(defaultOptions, customOptions || {}) + this.options = options + this.state = {} + + // Init smooth scroll if enabled (default). + if (options.scrollSmooth) { + options.duration = options.scrollSmoothDuration + options.offset = options.scrollSmoothOffset + } + + // Pass options to these modules. + buildHtml = BuildHtml(options) + parseContent = ParseContent(options) + + // For testing purposes. + this._buildHtml = buildHtml + this._parseContent = parseContent + this._headingsArray = headingsArray + this.updateTocListActiveElement = buildHtml.updateListActiveElement + + // Destroy it if it exists first. + tocbot.destroy() + + var contentElement = getContentElement(options) + if (contentElement === null) { + return + } + + var tocElement = getTocElement(options) + if (tocElement === null) { + return + } + + // Get headings array. + headingsArray = parseContent.selectHeadings(contentElement, options.headingSelector) + // Return if no headings are found. + if (headingsArray === null) { + return + } + + // Build nested headings array. + var nestedHeadingsObj = parseContent.nestHeadingsArray(headingsArray) + var nestedHeadings = nestedHeadingsObj.nest + + // Render. + if (!options.skipRendering) { + buildHtml.render(tocElement, nestedHeadings) + } + + // Update Sidebar and bind listeners. + this._scrollListener = throttle(function (e) { + buildHtml.updateToc(headingsArray) + !options.disableTocScrollSync && updateTocScroll(options) + var isTop = e && e.target && e.target.scrollingElement && e.target.scrollingElement.scrollTop === 0 + if ((e && (e.eventPhase === 0 || e.currentTarget === null)) || isTop) { + buildHtml.updateToc(headingsArray) + if (options.scrollEndCallback) { + options.scrollEndCallback(e) + } + } + }, options.throttleTimeout) + this._scrollListener() + if (options.scrollContainer && document.querySelector(options.scrollContainer)) { + document.querySelector(options.scrollContainer).addEventListener('scroll', this._scrollListener, false) + document.querySelector(options.scrollContainer).addEventListener('resize', this._scrollListener, false) + } else { + document.addEventListener('scroll', this._scrollListener, false) + document.addEventListener('resize', this._scrollListener, false) + } + + return this + } + + /** + * Refresh tocbot. + */ + tocbot.refresh = function (customOptions) { + tocbot.destroy() + tocbot.init(customOptions || this.options) + } + + // Make tocbot available globally. + root.tocbot = tocbot + + return tocbot +}) \ No newline at end of file diff --git a/doc/scripts/third-party/tocbot.min.js b/doc/scripts/third-party/tocbot.min.js new file mode 100644 index 0000000000000000000000000000000000000000..0f8e1753616f369c7f5f4ef64699760f17bf74c0 --- /dev/null +++ b/doc/scripts/third-party/tocbot.min.js @@ -0,0 +1 @@ +var defaultOptions={ignoreSelector:".js-toc-ignore",linkClass:"toc-link",extraLinkClasses:"",activeLinkClass:"is-active-link",listClass:"toc-list",extraListClasses:"",isCollapsedClass:"is-collapsed",collapsibleClass:"is-collapsible",listItemClass:"toc-list-item",activeListItemClass:"is-active-li",collapseDepth:0,scrollSmooth:!0,scrollSmoothDuration:420,scrollSmoothOffset:0,scrollEndCallback:function(e){},throttleTimeout:50,positionFixedSelector:null,positionFixedClass:"is-position-fixed",fixedSidebarOffset:"auto",includeHtml:!1,includeTitleTags:!1,orderedList:!0,scrollContainer:null,skipRendering:!1,headingLabelCallback:!1,ignoreHiddenElements:!1,headingObjectCallback:null,basePath:"",disableTocScrollSync:!1};function ParseContent(r){var t=[].reduce;function a(e){return e[e.length-1]}function c(e){if(!(e instanceof window.HTMLElement))return e;if(r.ignoreHiddenElements&&(!e.offsetHeight||!e.offsetParent))return null;var t=e.getAttribute("data-heading-label")||(r.headingLabelCallback?String(r.headingLabelCallback(e.textContent)):e.textContent.trim()),t={id:e.id,children:[],nodeName:e.nodeName,headingLevel:+e.nodeName.toUpperCase().replace("H",""),textContent:t};return r.includeHtml&&(t.childNodes=e.childNodes),r.headingObjectCallback?r.headingObjectCallback(t,e):t}return{nestHeadingsArray:function(e){return t.call(e,function(e,t){t=c(t);if(t){for(var l=e.nest,n=(t=c(t)).headingLevel,o=l,s=a(o),i=n-(s?s.headingLevel:0);0<i&&(!(s=a(o))||n!==s.headingLevel);)s&&void 0!==s.children&&(o=s.children),i--;n>=r.collapseDepth&&(t.isCollapsed=!0),o.push(t)}return e},{nest:[]})},selectHeadings:function(e,t){var l=t;r.ignoreSelector&&(l=t.split(",").map(function(e){return e.trim()+":not("+r.ignoreSelector+")"}));try{return e.querySelectorAll(l)}catch(e){return console.warn("Headers not found with selector: "+l),null}}}}function BuildHtml(i){var r,n=[].forEach,a=[].some,c=document.body,d=document.querySelector(i.contentSelector),u=!0,m=" ";function o(e,t){var l,t=t.appendChild(function(e){var t=document.createElement("li"),l=document.createElement("a");i.listItemClass&&t.setAttribute("class",i.listItemClass);i.onClick&&(l.onclick=i.onClick);i.includeTitleTags&&l.setAttribute("title",e.textContent);i.includeHtml&&e.childNodes.length?n.call(e.childNodes,function(e){l.appendChild(e.cloneNode(!0))}):l.textContent=e.textContent;return l.setAttribute("href",i.basePath+"#"+e.id),l.setAttribute("class",i.linkClass+m+"node-name--"+e.nodeName+m+i.extraLinkClasses),t.appendChild(l),t}(e));e.children.length&&(l=s(e.isCollapsed),e.children.forEach(function(e){o(e,l)}),t.appendChild(l))}function s(e){var t=i.orderedList?"ol":"ul",t=document.createElement(t),l=i.listClass+m+i.extraListClasses;return e&&(l=(l+=m+i.collapsibleClass)+(m+i.isCollapsedClass)),t.setAttribute("class",l),t}function f(e){var t=[].forEach,l=r.querySelectorAll("."+i.linkClass),l=(t.call(l,function(e){e.className=e.className.split(m+i.activeLinkClass).join("")}),r.querySelectorAll("."+i.listItemClass)),l=(t.call(l,function(e){e.className=e.className.split(m+i.activeListItemClass).join("")}),r.querySelector("."+i.linkClass+".node-name--"+e.nodeName+'[href="'+i.basePath+"#"+e.id.replace(/([ #;&,.+*~':"!^$[\]()=>|/@])/g,"\\$1")+'"]')),e=(l&&-1===l.className.indexOf(i.activeLinkClass)&&(l.className+=m+i.activeLinkClass),l&&l.parentNode),e=(e&&-1===e.className.indexOf(i.activeListItemClass)&&(e.className+=m+i.activeListItemClass),r.querySelectorAll("."+i.listClass+"."+i.collapsibleClass));t.call(e,function(e){-1===e.className.indexOf(i.isCollapsedClass)&&(e.className+=m+i.isCollapsedClass)}),l&&l.nextSibling&&-1!==l.nextSibling.className.indexOf(i.isCollapsedClass)&&(l.nextSibling.className=l.nextSibling.className.split(m+i.isCollapsedClass).join("")),function e(t){if(t&&-1!==t.className.indexOf(i.collapsibleClass)&&-1!==t.className.indexOf(i.isCollapsedClass))return t.className=t.className.split(m+i.isCollapsedClass).join(""),e(t.parentNode.parentNode);return t}(l&&l.parentNode.parentNode)}return{enableTocAnimation:function(){u=!0},disableTocAnimation:function(e){"string"==typeof(e=e.target||e.srcElement).className&&-1!==e.className.indexOf(i.linkClass)&&(u=!1)},render:function(e,t){var l=s(!1);if(t.forEach(function(e){o(e,l)}),null!==(r=e||r))return r.firstChild&&r.removeChild(r.firstChild),0===t.length?r:r.appendChild(l)},updateToc:function(e){n=i.scrollContainer&&document.querySelector(i.scrollContainer)?document.querySelector(i.scrollContainer).scrollTop:document.documentElement.scrollTop||c.scrollTop,i.positionFixedSelector&&(t=i.scrollContainer&&document.querySelector(i.scrollContainer)?document.querySelector(i.scrollContainer).scrollTop:document.documentElement.scrollTop||c.scrollTop,l=document.querySelector(i.positionFixedSelector),"auto"===i.fixedSidebarOffset&&(i.fixedSidebarOffset=r.offsetTop),t>i.fixedSidebarOffset?-1===l.className.indexOf(i.positionFixedClass)&&(l.className+=m+i.positionFixedClass):l.className=l.className.split(m+i.positionFixedClass).join(""));var n,t,l,o,s=e;u&&null!==r&&0<s.length&&(a.call(s,function(e,t){var l=n+10;return d&&(l+=d.clientHeight*d.scrollTop/(d.scrollHeight-d.clientHeight)),function e(t){var l=0;return null!==t&&(l=t.offsetTop,i.hasInnerContainers&&(l+=e(t.offsetParent))),l}(e)>l?(o=s[0===t?t:t-1],!0):t===s.length-1?(o=s[s.length-1],!0):void 0}),f(o))},updateListActiveElement:f}}function updateTocScroll(e){var t,l=e.tocElement||document.querySelector(e.tocSelector);l&&l.scrollHeight>l.clientHeight&&((e=l.querySelector("."+e.activeListItemClass))&&(t=l.getBoundingClientRect().top,l.scrollTop=e.offsetTop-t))}!function(e,t){"function"==typeof define&&define.amd?define([],t(e)):"object"==typeof exports?module.exports=t(e):e.tocbot=t(e)}("undefined"!=typeof global?global:this.window||this.global,function(e){"use strict";var l,a,c,d,u={},m={},f=!!(e&&e.document&&e.document.querySelector&&e.addEventListener);if("undefined"!=typeof window||f)return d=Object.prototype.hasOwnProperty,m.destroy=function(){var e=C(u);null!==e&&(u.skipRendering||e&&(e.innerHTML=""),u.scrollContainer&&document.querySelector(u.scrollContainer)?(document.querySelector(u.scrollContainer).removeEventListener("scroll",this._scrollListener,!1),document.querySelector(u.scrollContainer).removeEventListener("resize",this._scrollListener,!1)):(document.removeEventListener("scroll",this._scrollListener,!1),document.removeEventListener("resize",this._scrollListener,!1)))},m.init=function(e){if(f){u=function(){for(var e={},t=0;t<arguments.length;t++){var l,n=arguments[t];for(l in n)d.call(n,l)&&(e[l]=n[l])}return e}(defaultOptions,e||{}),this.options=u,this.state={},u.scrollSmooth&&(u.duration=u.scrollSmoothDuration,u.offset=u.scrollSmoothOffset),l=BuildHtml(u),a=ParseContent(u),this._buildHtml=l,this._parseContent=a,this._headingsArray=c,this.updateTocListActiveElement=l.updateListActiveElement,m.destroy();e=function(t){try{return t.contentElement||document.querySelector(t.contentSelector)}catch(e){return console.warn("Contents element not found: "+t.contentSelector),null}}(u);if(null!==e){var n,o,s,i,r,t=C(u);if(null!==t)if(null!==(c=a.selectHeadings(e,u.headingSelector)))return e=a.nestHeadingsArray(c).nest,u.skipRendering||l.render(t,e),this._scrollListener=(n=function(e){l.updateToc(c),u.disableTocScrollSync||updateTocScroll(u);var t=e&&e.target&&e.target.scrollingElement&&0===e.target.scrollingElement.scrollTop;(e&&(0===e.eventPhase||null===e.currentTarget)||t)&&(l.updateToc(c),u.scrollEndCallback&&u.scrollEndCallback(e))},o=(o=u.throttleTimeout)||250,function(){var e=s||this,t=+new Date,l=arguments;i&&t<i+o?(clearTimeout(r),r=setTimeout(function(){i=t,n.apply(e,l)},o)):(i=t,n.apply(e,l))}),this._scrollListener(),u.scrollContainer&&document.querySelector(u.scrollContainer)?(document.querySelector(u.scrollContainer).addEventListener("scroll",this._scrollListener,!1),document.querySelector(u.scrollContainer).addEventListener("resize",this._scrollListener,!1)):(document.addEventListener("scroll",this._scrollListener,!1),document.addEventListener("resize",this._scrollListener,!1)),this}}},m.refresh=function(e){m.destroy(),m.init(e||this.options)},e.tocbot=m;function C(t){try{return t.tocElement||document.querySelector(t.tocSelector)}catch(e){return console.warn("TOC element not found: "+t.tocSelector),null}}}); \ No newline at end of file diff --git a/doc/styles/clean-jsdoc-theme-base.css b/doc/styles/clean-jsdoc-theme-base.css new file mode 100644 index 0000000000000000000000000000000000000000..8a41c293aa2011a50019a4417308b5f17429e387 --- /dev/null +++ b/doc/styles/clean-jsdoc-theme-base.css @@ -0,0 +1,975 @@ +@font-face { + font-family: 'heading'; + src: url('../fonts/WorkSans-Bold.ttf') format('truetype'); + font-display: swap; +} + +@font-face { + font-family: 'body'; + src: url('../fonts/OpenSans-Regular.ttf') format('truetype'); + font-display: swap; +} + +@font-face { + font-family: 'code'; + src: url('../fonts/Inconsolata-Regular.ttf') format('truetype'); + font-display: swap; +} + +:root { + --outer-wrapper-max-width: 65rem; +} + +* { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +html, +body { + min-height: 100%; + width: 100%; + line-height: 1.75; +} + +body { + font-family: 'body'; + overflow-x: hidden; + position: relative; +} + +b { + font-family: heading; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: 'heading'; + font-weight: normal; + line-height: 1.75; +} + +h1 { + font-size: 3.5rem; + margin: 0; +} + +h2 { + font-size: 2.25rem; + margin: 2rem 0 0; +} + +h3 { + font-size: 1.5rem; +} + +h4 { + font-size: 1.25rem; +} + +h5 { + font-size: 1rem; +} + +h6 { + font-size: 1rem; +} + +img { + max-width: 100%; +} + +a { + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +/* badges */ +a img { + margin-right: 0.5rem; +} + +p { + margin: 1rem 0; +} + +article ul { + list-style: none; +} + +article ul li, +article ol li { + padding: 0.5rem 0; +} + +article ol, +article ul { + padding-left: 3rem; +} + +article ol p, +article ul p { + margin: 0; +} + +/* stylelint-disable-next-line */ + +.variation { + display: none; +} + +.signature-attributes { + font-style: italic; + font-weight: lighter; +} + +.ancestors a { + text-decoration: none; +} + +.important { + font-weight: bold; +} + +.signature { + font-family: 'code'; +} + +.name { + font-family: 'code'; + font-weight: bold; +} + +blockquote { + font-size: 0.875rem; + padding: 0.0625rem 1.25rem; + border-radius: 1rem; + margin: 0.5rem 0; +} + +.details { + border-radius: 1rem; + margin: 1rem 0; +} + +.details .details-item-container { + display: flex; + padding: 1rem 2rem; +} + +dt { + font-family: heading; +} + +.details dt { + float: left; + min-width: 11rem; +} + +.details ul { + margin: 0; + display: inline-flex; + list-style-type: none; +} + +.details ul li { + display: inline-flex; + margin-right: 0.6125rem; + padding: 0; + word-break: break-word; +} + +/* stylelint-disable-next-line */ +.details ul li p { + margin: 0; +} + +/* stylelint-disable */ +.details pre.prettyprint { + margin: 0; +} + +/* stylelint-enable */ + +.details .object-value { + padding-top: 0; +} + +.description { + margin-bottom: 2rem; +} + +.method-member-container table { + margin-top: 1rem; +} + +.pre-div .hljs-ln { + margin: 0; +} + +.code-caption { + font-size: 0.875rem; +} + +.prettyprint { + font-size: 0.875rem; + overflow: auto; +} + +pre.prettyprint { + margin-top: 3rem; +} + +.prettyprint.source { + width: inherit; +} + +.prettyprint code { + display: block; + font-size: 1rem; + line-height: 1.75; + padding: 0 0 1rem; +} + +.prettyprint .compact { + padding: 0; +} + +h4.name { + margin-top: 0.5rem; +} + +.params, +.props, +table { + border-collapse: separate; + border-spacing: 0 0.5rem; + border-radius: 0.5rem; + font-size: 0.875rem; + margin: 0; + width: 100%; +} + +table td:first-child, +.params td:first-child, +table thead th:first-child, +.params thead th:first-child, +.props thead th:first-child { + border-top-left-radius: 1rem; + border-bottom-left-radius: 1rem; +} + +table td:last-child, +.params td:last-child, +table thead th:last-child, +.params thead th:last-child, +.props thead th:last-child { + border-top-right-radius: 1rem; + border-bottom-right-radius: 1rem; +} + +table th, +.params th { + position: sticky; + top: 0; +} + +.params .name, +.props .name, +.name code { + font-family: 'code'; + font-size: 1rem; +} + +.params td, +.params th, +.props td, +.props th, +th, +td { + display: table-cell; + margin: 0; + padding: 1rem 2rem; + text-align: left; + vertical-align: top; +} + +.params thead tr, +.props thead tr { + font-weight: bold; +} + +/* stylelint-disable */ +.params .params thead tr, +.props .props thead tr { + font-weight: bold; +} + +.params td.description > p:first-child, +.props td.description > p:first-child { + margin-top: 0; + padding-top: 0; +} + +.params td.description > p:last-child, +.props td.description > p:last-child { + margin-bottom: 0; + padding-bottom: 0; +} + +dl.param-type { + margin-bottom: 1rem; + padding-bottom: 1rem; +} + +/* stylelint-enable */ + +.param-type dt, +.param-type dd { + display: inline-block; +} + +.param-type dd { + font-family: 'code'; + font-size: 1rem; +} + +code { + border-radius: 0.3rem; + font-family: 'code'; + font-size: 1rem; + padding: 0.1rem 0.4rem; +} + +.mt-20 { + margin-top: 1.5rem; +} + +.codepen-form { + bottom: 0; + position: absolute; + right: 0.6125rem; +} + +.body-wrapper { + display: flex; + flex-direction: column; + height: 100vh; + position: relative; +} + +.sidebar-container { + position: fixed; + display: flex; + padding: 1rem; + top: 0; + bottom: 0; + left: 0; + width: 25rem; + z-index: 10; +} + +.sidebar { + border-radius: 1rem; + flex: 1; + padding: 1.5rem 0; + overflow: hidden; + display: flex; + flex-direction: column; +} + +.sidebar-title { + margin: 0; + padding: 0 2rem; + text-decoration: none; + font-size: 1.5rem; + font-family: heading; +} + +.sidebar-title:hover { + text-decoration: none; +} + +.sidebar-items-container { + margin-top: 5rem; + overflow: auto; + flex: 1; + position: relative; +} + +.sidebar-section-title { + padding: 0.5rem 2rem; + font-family: heading; + font-size: 1.25rem; + border-radius: 1rem; +} + +.with-arrow { + align-items: center; + cursor: pointer; + display: flex; +} + +.with-arrow div { + flex: 1; +} + +.with-arrow svg { + height: 1rem; + width: 1rem; + transition: transform 0.3s; +} + +.with-arrow[data-isopen='true'] svg { + transform: rotate(180deg); +} + +.sidebar-section-children-container { + border-radius: 0.5rem; + overflow: hidden; +} + +.sidebar-section-children a { + display: block; + width: 100%; + padding: 0.25rem 2rem; +} + +.sidebar-section-children a { + text-decoration: none; +} + +.with-arrow[data-isopen='false'] + .sidebar-section-children-container { + height: 0; + overflow: hidden; +} + +.with-arrow[data-isopen='true'] + .sidebar-section-children-container { + height: auto; +} + +.toc-container { + position: fixed; + top: 0; + right: 4rem; + bottom: 0; + width: 16rem; + z-index: 10; +} + +.toc-content { + padding-top: 10rem; + display: flex; + flex-direction: column; + height: 100%; +} + +#eed4d2a0bfd64539bb9df78095dec881 { + margin: 2rem 0; + flex: 1; + overflow: auto; +} + +.toc-list { + padding-left: 1rem; + list-style: none; +} + +.toc-link { + display: block; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + width: 100%; +} + +.toc-link.is-active-link { + font-family: heading; +} + +.has-anchor { + position: relative; +} + +.link-anchor { + padding: 0 0.5rem; +} + +.has-anchor .link-anchor { + position: absolute; + left: 0; + top: 0; + transform: translateX(-100%); + text-decoration: none; + visibility: hidden; +} + +.has-anchor:hover .link-anchor { + visibility: visible; +} + +.navbar-container { + position: fixed; + z-index: 10; + top: 0; + left: 25rem; + right: 25rem; + height: 7rem; + padding-top: 1rem; + display: flex; + justify-content: center; +} + +.navbar { + display: flex; + padding: 1rem 4rem 1rem 2rem; + flex: 1; + max-width: var(--outer-wrapper-max-width); +} + +.navbar-left-items { + display: flex; + flex: 1; +} + +.navbar-right-items { + display: flex; +} + +.icon-button svg { + height: 1rem; + width: 1rem; +} + +.icon-button { + background: transparent; + position: relative; + display: inline-flex; + border: 0; + padding: 0.5rem; + border-radius: 50%; + cursor: pointer; + transition: background 0.3s; +} + +.navbar-right-item { + display: flex; + justify-content: center; + align-items: center; + margin: 0 0.25rem; +} + +.navbar-item { + border-radius: 0.5rem; + overflow: hidden; +} + +.navbar-item a { + display: inline-block; + padding: 1rem 2rem; + text-decoration: none; + transition: 0.3s; +} + +.font-size-tooltip { + display: flex; + align-items: center; + margin: 0 -0.5rem; +} + +.font-size-tooltip .icon-button.disabled { + pointer-events: none; +} + +.main-content { + position: relative; + flex: 1; + overflow: auto; + display: flex; + flex-direction: column; + align-items: center; + padding: 7rem 25rem 0; +} + +.main-wrapper { + width: 100%; + max-width: var(--outer-wrapper-max-width); + padding: 0 4rem 1rem; +} + +.p-h-n { + padding: 0.4rem 1rem; +} + +.footer { + width: 100%; + margin: 5rem 0 0 0; + border-radius: 1rem; + font-size: 0.875rem; + display: flex; + justify-content: center; +} + +.source-page + .footer { + margin-top: 3rem; +} + +.footer .wrapper { + flex: 1; + padding: 1rem 2rem; + max-width: var(--outer-wrapper-max-width); +} + +pre { + position: relative; +} + +.hljs table td { + background: transparent; + padding: 0 0.6125rem; + line-height: 1.5; + border-radius: 0; +} + +.hljs .hljs-ln-numbers { + width: 2rem; + white-space: nowrap; + /* user-select: none; */ + padding-left: 1.5rem; +} + +.hljs-ln-line.hljs-ln-numbers::before { + content: attr(data-line-number); +} + +.pre-div { + position: relative; + border-radius: 1rem; + overflow: hidden; + margin: 2rem 0; +} + +.pre-top-bar-container { + align-items: center; + display: flex; + justify-content: space-between; + left: 0; + padding: 0.3125rem 1.5rem; + position: absolute; + right: 0; + top: 0; +} + +.code-copy-icon-container { + align-items: center; + border-radius: 50%; + cursor: pointer; + display: flex; + height: 1.875rem; + justify-content: center; + transition: 0.3s; + width: 1.875rem; +} + +.code-copy-icon-container > div { + margin-top: 0.25rem; + position: relative; +} + +.sm-icon { + height: 1rem; + width: 1rem; +} + +.code-lang-name { + font-family: 'body'; + font-size: 0.75rem; +} + +.tooltip { + border-radius: 0.3125rem; + opacity: 0; + padding: 0.1875rem 0.5rem; + position: absolute; + right: 2rem; + top: 0.3125rem; + transform: scale(0); + transition: 0.3s; +} + +.show-tooltip { + opacity: 1; + transform: scale(1); +} + +.allow-overflow { + overflow: auto; +} + +.bold { + font-family: heading; +} + +.search-container { + position: fixed; + top: 0; + bottom: 0; + right: 0; + left: 0; + justify-content: center; + z-index: 50; + align-items: flex-start; +} + +.search-container .wrapper { + width: 100%; + max-width: 60rem; + padding: 4rem 2rem 2rem; + border-radius: 1rem; + margin: 3rem 25rem; + position: relative; +} + +.search-close-button { + position: absolute; + top: 1rem; + right: 1rem; +} + +.search-result-c-text { + display: flex; + justify-content: center; + user-select: none; +} + +.search-result-c { + min-height: 20rem; + max-height: 40rem; + overflow: auto; + padding: 2rem 0; +} + +.search-box-c { + width: 100%; + position: relative; + display: flex; + align-items: center; +} + +.search-box-c svg { + height: 1.5rem; + width: 1.5rem; + position: absolute; + left: 1.5rem; +} + +.search-input { + border: none; + border-radius: 1rem; + width: 100%; + flex: 1; + padding: 1rem 2rem 1rem 4rem; + font-family: body; + font-size: 1.25rem; +} + +.search-result-item { + display: block; + text-decoration: none; + padding: 1rem; + border-radius: 1rem; + margin: 1rem 0; +} + +.search-result-item:hover { + text-decoration: none; +} + +.search-result-item:active { + text-decoration: none; +} + +.search-result-item-title { + font-family: heading; + font-size: 1.5rem; + margin: 0; +} + +.search-result-item-p { + font-size: 0.875rem; + margin: 0; +} + +.mobile-menu-icon-container { + display: none; + position: fixed; + bottom: 1.5rem; + right: 2rem; + z-index: 30; +} + +.mobile-menu-icon-container .icon-button svg { + height: 2rem; + width: 2rem; +} + +.mobile-sidebar-container { + position: fixed; + top: 0; + right: 0; + left: 0; + bottom: 0; + padding: 1rem; + z-index: 25; + + display: none; +} + +.mobile-sidebar-container.show { + display: block; +} + +.mobile-sidebar-wrapper { + border-radius: 1rem; + height: 100%; + width: 100%; + display: flex; + flex-direction: column; + padding-top: 2rem; +} + +.mobile-nav-links { + display: flex; + flex-wrap: wrap; + padding-top: 2rem; +} + +.mobile-sidebar-items-c { + flex: 1; + overflow: auto; +} + +.mobile-navbar-actions { + display: flex; + padding: 1rem; +} + +.rel { + position: relative; +} + +.icon-button.codepen-button svg { + height: 1.5rem; + width: 1.5rem; +} + +.table-div { + width: 100%; + overflow: auto; +} + +.tag-default { + overflow: auto; +} + +/* scroll bar */ +::-webkit-scrollbar { + width: 0.3125rem; + height: 0.3125rem; +} + +::-webkit-scrollbar-thumb, +::-webkit-scrollbar-track { + border-radius: 1rem; +} + +@media screen and (max-width: 100em) { + .toc-container { + display: none; + } + + .main-content { + padding: 7rem 0 0 25rem; + } + + .search-container .wrapper { + margin-right: 1rem; + } + + .navbar-container { + /* For scrollbar */ + right: 1rem; + } +} + +@media screen and (min-width: 65em) { + .mobile-sidebar-container.show { + display: none; + } +} + +@media screen and (max-width: 65em) { + h1 { + font-size: 3rem; + } + + h2 { + font-size: 2rem; + } + + h3 { + font-size: 1.875; + } + + h4, + h5, + h6 { + font-size: 1rem; + } + + .main-wrapper { + padding: 0 1rem 1rem; + } + + .search-result-c { + max-height: 25rem; + } + + .mobile-menu-icon-container { + display: block; + } + + .sidebar-container { + display: none; + } + + .search-container .wrapper { + margin-left: 1rem; + } + + .main-content { + padding-left: 0; + padding-top: 1rem; + } + + .navbar-container { + display: none; + } + + .source-page + .footer, + .footer { + margin-top: 2rem; + } + + .has-anchor:hover .link-anchor { + visibility: hidden; + } +} diff --git a/doc/styles/clean-jsdoc-theme-dark.css b/doc/styles/clean-jsdoc-theme-dark.css new file mode 100644 index 0000000000000000000000000000000000000000..63de899ccbe1aa09cb7c96ef9c6bf3a75180ce25 --- /dev/null +++ b/doc/styles/clean-jsdoc-theme-dark.css @@ -0,0 +1,407 @@ +::selection { + background: #ffce76; + color: #222; +} + +body { + background-color: #1a1a1a; + color: #fff; +} + +a, +a:active { + color: #00bbff; +} + +hr { + color: #222; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + color: #fff; +} + +.sidebar { + background-color: #222; + color: #999; +} + +.sidebar-title { + color: #999; +} + +.sidebar-section-title { + color: #999; +} + +.sidebar-section-title:hover { + background: #252525; +} + +.with-arrow { + fill: #999; +} + +.sidebar-section-children-container { + background: #292929; +} + +.sidebar-section-children a:hover { + background: #2c2c2c; +} + +.sidebar-section-children a { + color: #fff; +} + +.navbar-container { + background: #1a1a1a; +} + +.icon-button svg, +.navbar-item a { + color: #999; + fill: #999; +} + +.font-size-tooltip .icon-button svg { + fill: #fff; +} + +.font-size-tooltip .icon-button.disabled { + background: #999; +} + +.icon-button:hover { + background: #333; +} + +.icon-button:active { + background: #444; +} + +.navbar-item a:active { + color: #aaa; + background-color: #222; +} + +.navbar-item:hover { + background: #202020; +} + +.footer { + background: #222; + color: #999; +} + +.footer a { + color: #999; +} + +.toc-link { + color: #777; + transition: color 0.3s; + font-size: 0.875rem; +} + +.toc-link.is-active-link { + color: #fff; +} + +.has-anchor .link-anchor { + color: #555; +} + +.has-anchor .link-anchor:hover { + color: #888; +} + +tt, +code, +kbd, +samp { + background: #333; +} + +.signature-attributes { + color: #aaa; +} + +.ancestors { + color: #999; +} + +.ancestors a { + color: #999 !important; +} + +.important { + color: #c51313; +} + +.type-signature { + color: #00918e; +} + +.name, +.name a { + color: #f7f7f7; +} + +.details { + background: #222; + color: #fff; +} + +.prettyprint { + background: #222; +} + +.member-item-container strong, +.method-member-container strong { + color: #fff; +} + +.pre-top-bar-container { + background: #292929; +} + +.prettyprint.source, +.prettyprint code { + background-color: #222; + color: #c9d1d9; +} + +.pre-div { + background-color: #222; +} + +.hljs .hljs-ln-numbers { + color: #777; +} + +.hljs .selected { + background: #444; +} + +.hljs .selected .hljs-ln-numbers { + color: #eee; +} + +/* stylelint-enable */ + +table .name, +.params .name, +.props .name, +.name code { + color: #fff; +} + +table td, +.params td { + background-color: #292929; +} + +table thead th, +.params thead th, +.props thead th { + background-color: #222; + color: #fff; +} + +/* stylelint-disable */ +table .params thead tr, +.params .params thead tr, +.props .props thead tr { + background-color: #222; + color: #fff; +} + +.disabled { + color: #aaaaaa; +} + +.code-lang-name { + color: #ff8a00; +} + +.tooltip { + background: #ffce76; + color: #222; +} + +/* code */ +.hljs-comment { + color: #8b949e; +} + +.hljs-doctag, +.hljs-keyword, +.hljs-template-tag, +.hljs-variable.language_ { + color: #ff7b72; +} + +.hljs-template-variable, +.hljs-type { + color: #30ac7c; +} + +.hljs-meta, +.hljs-string, +.hljs-regexp { + color: #a5d6ff; +} + +.hljs-title.class_, +.hljs-title { + color: #ffa657; +} + +.hljs-title.class_.inherited__, +.hljs-title.function_ { + color: #d2a8ff; +} + +.hljs-attr, +.hljs-attribute, +.hljs-literal, +.hljs-meta, +.hljs-number, +.hljs-operator, +.hljs-selector-attr, +.hljs-selector-class, +.hljs-selector-id, +.hljs-variable { + color: #79c0ff; +} + +.hljs-meta .hljs-string, +.hljs-regexp, +.hljs-string { + color: #a5d6ff; +} + +.hljs-built_in, +.hljs-symbol { + color: #ffa657; +} + +.hljs-code, +.hljs-comment, +.hljs-formula { + color: #8b949e; +} + +.hljs-name, +.hljs-quote, +.hljs-selector-pseudo, +.hljs-selector-tag { + color: #7ee787; +} + +.hljs-subst { + color: #c9d1d9; +} + +.hljs-section { + color: #1f6feb; + font-weight: 700; +} + +.hljs-bullet { + color: #f2cc60; +} + +.hljs-emphasis { + color: #c9d1d9; + font-style: italic; +} + +.hljs-strong { + color: #c9d1d9; + font-weight: 700; +} + +/* code end*/ + +blockquote { + background: #222; + color: #fff; +} + +.search-container { + background: rgba(255, 255, 255, 0.1); +} + +.icon-button.search-close-button svg { + fill: #a00; +} + +.search-container .wrapper { + background: #222; +} + +.search-result-c { + color: #666; +} + +.search-box-c { + fill: #333; +} + +.search-input { + background: #333; + color: #fff; +} + +.search-box-c svg { + fill: #fff; +} + +.search-result-item { + background: #333; +} + +.search-result-item:hover { + background: #444; +} + +.search-result-item:active { + background: #555; +} + +.search-result-item-title { + color: #fff; +} + +.search-result-item-p { + color: #aaa; +} + +.mobile-menu-icon-container .icon-button { + background: #333; +} + +.mobile-sidebar-container { + background: #1a1a1a; +} + +.mobile-sidebar-wrapper { + background: #222; +} + +/* scroll bar */ +::-webkit-scrollbar-track { + background: #333; +} + +::-webkit-scrollbar-thumb { + background: #555; + outline: 0.06125rem solid #555; +} diff --git a/doc/styles/clean-jsdoc-theme-light.css b/doc/styles/clean-jsdoc-theme-light.css new file mode 100644 index 0000000000000000000000000000000000000000..a900941efbaf3a60c037af900eb4b2d66b735aab --- /dev/null +++ b/doc/styles/clean-jsdoc-theme-light.css @@ -0,0 +1,388 @@ +.light ::selection { + background: #ffce76; + color: #1d1919; +} + +body.light { + background-color: #fff; + color: #111; +} + +.light a, +.light a:active { + color: #007bff; +} + +.light hr { + color: #f7f7f7; +} + +.light h1, +.light h2, +.light h3, +.light h4, +.light h5, +.light h6 { + color: #111; +} + +.light .sidebar { + background-color: #f7f7f7; + color: #222; +} + +.light .sidebar-title { + color: #222; +} + +.light .sidebar-section-title { + color: #222; +} + +.light .sidebar-section-title:hover { + background: #eee; +} + +.light .with-arrow { + fill: #111; +} + +.light .sidebar-section-children-container { + background: #eee; +} + +.light .sidebar-section-children a:hover { + background: #e0e0e0; +} + +.light .sidebar-section-children a { + color: #111; +} + +.light .navbar-container { + background: #fff; +} + +.light .icon-button svg, +.light .navbar-item a { + color: #222; + fill: #222; +} + +.light .tippy-box { + background: #eee; + color: #111; +} + +.light .tippy-arrow { + color: #f1f1f1; +} + +.light .font-size-tooltip .icon-button svg { + fill: #111; +} + +.light .font-size-tooltip .icon-button.disabled svg { + fill: #999; +} + +.light .icon-button:hover { + background: #ddd; +} + +.light .icon-button:active { + background: #ccc; +} + +.light .navbar-item a:active { + color: #333; + background-color: #eee; +} + +.light .navbar-item:hover { + background: #f7f7f7; +} + +.light .footer { + background: #f7f7f7; + color: #111; +} + +.light .footer a { + color: #111; +} + +.light .toc-link { + color: #999; + transition: color 0.3s; + font-size: 0.875rem; +} + +.light .toc-link.is-active-link { + color: #111; +} + +.light .has-anchor .link-anchor { + color: #ddd; +} + +.light .has-anchor .link-anchor:hover { + color: #ccc; +} + +.light .signature-attributes { + color: #aaa; +} + +.light .ancestors { + color: #999; +} + +.light .ancestors a { + color: #999 !important; +} + +.light .important { + color: #ee1313; +} + +.light .type-signature { + color: #00918e; +} + +.light .name, +.light .name a { + color: #293a80; +} + +.light .details { + background: #f9f9f9; + color: #101010; +} + +.light .member-item-container strong, +.light .method-member-container strong { + color: #000; +} + +.light .prettyprint { + background: #f7f7f7; +} + +.light .pre-div { + background: #f7f7f7; +} + +.light .hljs .hljs-ln-numbers { + color: #aaa; +} + +.light .hljs .selected { + background: #ccc; +} + +.light table.hljs-ln td { + background: none; +} + +.light .hljs .selected .hljs-ln-numbers { + color: #444; +} + +.light .pre-top-bar-container { + background-color: #eee; +} + +.light .prettyprint code { + background-color: #f7f7f7; +} + +.light table .name, +.light .params .name, +.light .props .name, +.light .name code { + color: #4d4e53; +} + +.light table td, +.light .params td { + background: #f7f7f7; +} + +.light table thead th, +.light .params thead th, +.light .props thead th { + background-color: #eee; + color: #111; +} + +/* stylelint-disable */ +.light table .params thead tr, +.light .params .params thead tr, +.light .props .props thead tr { + background-color: #eee; + color: #111; +} + +.light .disabled { + color: #454545; +} + +.light .code-lang-name { + color: #ff0000; +} + +.light .tooltip { + background: #ffce76; + color: #000; +} + +/* Code */ + +.light .hljs-comment, +.light .hljs-quote { + color: #a0a1a7; +} + +.light .hljs-doctag, +.light .hljs-keyword, +.light .hljs-formula { + color: #a626a4; +} + +.light .hljs-section, +.light .hljs-name, +.light .hljs-selector-tag, +.light .hljs-deletion, +.light .hljs-subst { + color: #e45649; +} + +.light .hljs-literal { + color: #0184bb; +} + +.light .hljs-string, +.light .hljs-regexp, +.light .hljs-addition, +.light .hljs-attribute, +.light .hljs-meta .hljs-string { + color: #50a14f; +} + +.light .hljs-attr, +.light .hljs-variable, +.light .hljs-template-variable, +.light .hljs-type, +.light .hljs-selector-class, +.light .hljs-selector-attr, +.light .hljs-selector-pseudo, +.light .hljs-number { + color: #986801; +} + +.light .hljs-symbol, +.light .hljs-bullet, +.light .hljs-link, +.light .hljs-meta, +.light .hljs-selector-id, +.light .hljs-title { + color: #4078f2; +} + +.light .hljs-built_in, +.light .hljs-title.class_, +.light .hljs-class .hljs-title { + color: #c18401; +} + +.light .hljs-emphasis { + font-style: italic; +} + +.light .hljs-strong { + font-weight: bold; +} + +.light .hljs-link { + text-decoration: underline; +} + +/* Code Ends */ + +.light blockquote { + background: #eee; + color: #111; +} + +.light code { + background: #ddd; + color: #000; +} + +.light .search-container { + background: rgba(0, 0, 0, 0.1); +} + +.light .search-close-button svg { + fill: #f00; +} + +.light .search-container .wrapper { + background: #eee; +} + +.light .search-result-c { + color: #aaa; +} + +.light .search-box-c svg { + fill: #333; +} + +.light .search-input { + background: #f7f7f7; + color: #111; +} + +.light .search-result-item { + background: #f7f7f7; +} + +.light .search-result-item:hover { + background: #e9e9e9; +} + +.light .search-result-item:active { + background: #f7f7f7; +} + +.light .search-result-item-title { + color: #111; +} + +.light .search-result-item-p { + color: #aaa; +} + +.light .mobile-menu-icon-container .icon-button { + background: #e5e5e5; +} + +.light .mobile-sidebar-container { + background: #fff; +} + +.light .mobile-sidebar-wrapper { + background: #f7f7f7; +} + +/* scroll bar */ +.light ::-webkit-scrollbar-track { + background: #ddd; +} + +.light ::-webkit-scrollbar-thumb { + background: #aaa; + outline: 0.06125rem solid #aaa; +} diff --git a/doc/styles/clean-jsdoc-theme.min.css b/doc/styles/clean-jsdoc-theme.min.css new file mode 100644 index 0000000000000000000000000000000000000000..188d2747967381c8012d1d70cdc76f8eccc1b57b --- /dev/null +++ b/doc/styles/clean-jsdoc-theme.min.css @@ -0,0 +1 @@ +@font-face{font-family:"heading";src:url(../fonts/WorkSans-Bold.ttf)format("truetype");font-display:swap}@font-face{font-family:"body";src:url(../fonts/OpenSans-Regular.ttf)format("truetype");font-display:swap}@font-face{font-family:"code";src:url(../fonts/Inconsolata-Regular.ttf)format("truetype");font-display:swap}:root{--outer-wrapper-max-width:65rem}*{box-sizing:border-box;margin:0;padding:0}html,body{min-height:100%;width:100%;line-height:1.75}body{font-family:"body";overflow-x:hidden;position:relative}b{font-family:heading}h1,h2,h3,h4,h5,h6{font-family:"heading";font-weight:400;line-height:1.75}h1{font-size:3.5rem;margin:0}h2{font-size:2.25rem;margin:2rem 0 0}h3{font-size:1.5rem}h4{font-size:1.25rem}h5{font-size:1rem}h6{font-size:1rem}img{max-width:100%}a{text-decoration:none}a:hover{text-decoration:underline}a img{margin-right:.5rem}p{margin:1rem 0}article ul{list-style:none}article ul li,article ol li{padding:.5rem 0}article ol,article ul{padding-left:3rem}article ol p,article ul p{margin:0}.variation{display:none}.signature-attributes{font-style:italic;font-weight:lighter}.ancestors a{text-decoration:none}.important{font-weight:700}.signature{font-family:"code"}.name{font-family:"code";font-weight:700}blockquote{font-size:.875rem;padding:.0625rem 1.25rem;border-radius:1rem;margin:.5rem 0}.details{border-radius:1rem;margin:1rem 0}.details .details-item-container{display:flex;padding:1rem 2rem}dt{font-family:heading}.details dt{float:left;min-width:11rem}.details ul{margin:0;display:inline-flex;list-style-type:none}.details ul li{display:inline-flex;margin-right:.6125rem;padding:0;word-break:break-word}.details ul li p{margin:0}.details pre.prettyprint{margin:0}.details .object-value{padding-top:0}.description{margin-bottom:2rem}.method-member-container table{margin-top:1rem}.pre-div .hljs-ln{margin:0}.code-caption{font-size:.875rem}.prettyprint{font-size:.875rem;overflow:auto}pre.prettyprint{margin-top:3rem}.prettyprint.source{width:inherit}.prettyprint code{display:block;font-size:1rem;line-height:1.75;padding:0 0 1rem}.prettyprint .compact{padding:0}h4.name{margin-top:.5rem}.params,.props,table{border-collapse:separate;border-spacing:0 .5rem;border-radius:.5rem;font-size:.875rem;margin:0;width:100%}table td:first-child,.params td:first-child,table thead th:first-child,.params thead th:first-child,.props thead th:first-child{border-top-left-radius:1rem;border-bottom-left-radius:1rem}table td:last-child,.params td:last-child,table thead th:last-child,.params thead th:last-child,.props thead th:last-child{border-top-right-radius:1rem;border-bottom-right-radius:1rem}table th,.params th{position:sticky;top:0}.params .name,.props .name,.name code{font-family:"code";font-size:1rem}.params td,.params th,.props td,.props th,th,td{display:table-cell;margin:0;padding:1rem 2rem;text-align:left;vertical-align:top}.params thead tr,.props thead tr{font-weight:700}.params .params thead tr,.props .props thead tr{font-weight:700}.params td.description>p:first-child,.props td.description>p:first-child{margin-top:0;padding-top:0}.params td.description>p:last-child,.props td.description>p:last-child{margin-bottom:0;padding-bottom:0}dl.param-type{margin-bottom:1rem;padding-bottom:1rem}.param-type dt,.param-type dd{display:inline-block}.param-type dd{font-family:"code";font-size:1rem}code{border-radius:.3rem;font-family:"code";font-size:1rem;padding:.1rem .4rem}.mt-20{margin-top:1.5rem}.codepen-form{bottom:0;position:absolute;right:.6125rem}.body-wrapper{display:flex;flex-direction:column;height:100vh;position:relative}.sidebar-container{position:fixed;display:flex;padding:1rem;top:0;bottom:0;left:0;width:25rem;z-index:10}.sidebar{border-radius:1rem;flex:1;padding:1.5rem 0;overflow:hidden;display:flex;flex-direction:column}.sidebar-title{margin:0;padding:0 2rem;text-decoration:none;font-size:1.5rem;font-family:heading}.sidebar-title:hover{text-decoration:none}.sidebar-items-container{margin-top:5rem;overflow:auto;flex:1;position:relative}.sidebar-section-title{padding:.5rem 2rem;font-family:heading;font-size:1.25rem;border-radius:1rem}.with-arrow{align-items:center;cursor:pointer;display:flex}.with-arrow div{flex:1}.with-arrow svg{height:1rem;width:1rem;transition:transform .3s}.with-arrow[data-isopen=true] svg{transform:rotate(180deg)}.sidebar-section-children-container{border-radius:.5rem;overflow:hidden}.sidebar-section-children a{display:block;width:100%;padding:.25rem 2rem}.sidebar-section-children a{text-decoration:none}.with-arrow[data-isopen=false]+.sidebar-section-children-container{height:0;overflow:hidden}.with-arrow[data-isopen=true]+.sidebar-section-children-container{height:auto}.toc-container{position:fixed;top:0;right:4rem;bottom:0;width:16rem;z-index:10}.toc-content{padding-top:10rem;display:flex;flex-direction:column;height:100%}#eed4d2a0bfd64539bb9df78095dec881{margin:2rem 0;flex:1;overflow:auto}.toc-list{padding-left:1rem;list-style:none}.toc-link{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;width:100%}.toc-link.is-active-link{font-family:heading}.has-anchor{position:relative}.link-anchor{padding:0 .5rem}.has-anchor .link-anchor{position:absolute;left:0;top:0;transform:translateX(-100%);text-decoration:none;visibility:hidden}.has-anchor:hover .link-anchor{visibility:visible}.navbar-container{position:fixed;z-index:10;top:0;left:25rem;right:25rem;height:7rem;padding-top:1rem;display:flex;justify-content:center}.navbar{display:flex;padding:1rem 4rem 1rem 2rem;flex:1;max-width:var(--outer-wrapper-max-width)}.navbar-left-items{display:flex;flex:1}.navbar-right-items{display:flex}.icon-button svg{height:1rem;width:1rem}.icon-button{background:0 0;position:relative;display:inline-flex;border:0;padding:.5rem;border-radius:50%;cursor:pointer;transition:background .3s}.navbar-right-item{display:flex;justify-content:center;align-items:center;margin:0 .25rem}.navbar-item{border-radius:.5rem;overflow:hidden}.navbar-item a{display:inline-block;padding:1rem 2rem;text-decoration:none;transition:.3s}.font-size-tooltip{display:flex;align-items:center;margin:0-.5rem}.font-size-tooltip .icon-button.disabled{pointer-events:none}.main-content{position:relative;flex:1;overflow:auto;display:flex;flex-direction:column;align-items:center;padding:7rem 25rem 0}.main-wrapper{width:100%;max-width:var(--outer-wrapper-max-width);padding:0 4rem 1rem}.p-h-n{padding:.4rem 1rem}.footer{width:100%;margin:5rem 0 0 0;border-radius:1rem;font-size:.875rem;display:flex;justify-content:center}.source-page+.footer{margin-top:3rem}.footer .wrapper{flex:1;padding:1rem 2rem;max-width:var(--outer-wrapper-max-width)}pre{position:relative}.hljs table td{background:0 0;padding:0 .6125rem;line-height:1.5;border-radius:0}.hljs .hljs-ln-numbers{width:2rem;white-space:nowrap;padding-left:1.5rem}.hljs-ln-line.hljs-ln-numbers::before{content:attr(data-line-number)}.pre-div{position:relative;border-radius:1rem;overflow:hidden;margin:2rem 0}.pre-top-bar-container{align-items:center;display:flex;justify-content:space-between;left:0;padding:.3125rem 1.5rem;position:absolute;right:0;top:0}.code-copy-icon-container{align-items:center;border-radius:50%;cursor:pointer;display:flex;height:1.875rem;justify-content:center;transition:.3s;width:1.875rem}.code-copy-icon-container>div{margin-top:.25rem;position:relative}.sm-icon{height:1rem;width:1rem}.code-lang-name{font-family:"body";font-size:.75rem}.tooltip{border-radius:.3125rem;opacity:0;padding:.1875rem .5rem;position:absolute;right:2rem;top:.3125rem;transform:scale(0);transition:.3s}.show-tooltip{opacity:1;transform:scale(1)}.allow-overflow{overflow:auto}.bold{font-family:heading}.search-container{position:fixed;top:0;bottom:0;right:0;left:0;justify-content:center;z-index:50;align-items:flex-start}.search-container .wrapper{width:100%;max-width:60rem;padding:4rem 2rem 2rem;border-radius:1rem;margin:3rem 25rem;position:relative}.search-close-button{position:absolute;top:1rem;right:1rem}.search-result-c-text{display:flex;justify-content:center;user-select:none}.search-result-c{min-height:20rem;max-height:40rem;overflow:auto;padding:2rem 0}.search-box-c{width:100%;position:relative;display:flex;align-items:center}.search-box-c svg{height:1.5rem;width:1.5rem;position:absolute;left:1.5rem}.search-input{border:0;border-radius:1rem;width:100%;flex:1;padding:1rem 2rem 1rem 4rem;font-family:body;font-size:1.25rem}.search-result-item{display:block;text-decoration:none;padding:1rem;border-radius:1rem;margin:1rem 0}.search-result-item:hover{text-decoration:none}.search-result-item:active{text-decoration:none}.search-result-item-title{font-family:heading;font-size:1.5rem;margin:0}.search-result-item-p{font-size:.875rem;margin:0}.mobile-menu-icon-container{display:none;position:fixed;bottom:1.5rem;right:2rem;z-index:30}.mobile-menu-icon-container .icon-button svg{height:2rem;width:2rem}.mobile-sidebar-container{position:fixed;top:0;right:0;left:0;bottom:0;padding:1rem;z-index:25;display:none}.mobile-sidebar-container.show{display:block}.mobile-sidebar-wrapper{border-radius:1rem;height:100%;width:100%;display:flex;flex-direction:column;padding-top:2rem}.mobile-nav-links{display:flex;flex-wrap:wrap;padding-top:2rem}.mobile-sidebar-items-c{flex:1;overflow:auto}.mobile-navbar-actions{display:flex;padding:1rem}.rel{position:relative}.icon-button.codepen-button svg{height:1.5rem;width:1.5rem}.table-div{width:100%;overflow:auto}.tag-default{overflow:auto}::-webkit-scrollbar{width:.3125rem;height:.3125rem}::-webkit-scrollbar-thumb,::-webkit-scrollbar-track{border-radius:1rem}@media screen and (max-width:100em){.toc-container{display:none}.main-content{padding:7rem 0 0 25rem}.search-container .wrapper{margin-right:1rem}.navbar-container{right:1rem}}@media screen and (min-width:65em){.mobile-sidebar-container.show{display:none}}@media screen and (max-width:65em){h1{font-size:3rem}h2{font-size:2rem}h3{font-size:1.875}h4,h5,h6{font-size:1rem}.main-wrapper{padding:0 1rem 1rem}.search-result-c{max-height:25rem}.mobile-menu-icon-container{display:block}.sidebar-container{display:none}.search-container .wrapper{margin-left:1rem}.main-content{padding-left:0;padding-top:1rem}.navbar-container{display:none}.source-page+.footer,.footer{margin-top:2rem}.has-anchor:hover .link-anchor{visibility:hidden}}::selection{background:#ffce76;color:#222}body{background-color:#1a1a1a;color:#fff}a,a:active{color:#0bf}hr{color:#222}h1,h2,h3,h4,h5,h6{color:#fff}.sidebar{background-color:#222;color:#999}.sidebar-title{color:#999}.sidebar-section-title{color:#999}.sidebar-section-title:hover{background:#252525}.with-arrow{fill:#999}.sidebar-section-children-container{background:#292929}.sidebar-section-children a:hover{background:#2c2c2c}.sidebar-section-children a{color:#fff}.navbar-container{background:#1a1a1a}.icon-button svg,.navbar-item a{color:#999;fill:#999}.font-size-tooltip .icon-button svg{fill:#fff}.font-size-tooltip .icon-button.disabled{background:#999}.icon-button:hover{background:#333}.icon-button:active{background:#444}.navbar-item a:active{color:#aaa;background-color:#222}.navbar-item:hover{background:#202020}.footer{background:#222;color:#999}.footer a{color:#999}.toc-link{color:#777;transition:color .3s;font-size:.875rem}.toc-link.is-active-link{color:#fff}.has-anchor .link-anchor{color:#555}.has-anchor .link-anchor:hover{color:#888}tt,code,kbd,samp{background:#333}.signature-attributes{color:#aaa}.ancestors{color:#999}.ancestors a{color:#999!important}.important{color:#c51313}.type-signature{color:#00918e}.name,.name a{color:#f7f7f7}.details{background:#222;color:#fff}.prettyprint{background:#222}.member-item-container strong,.method-member-container strong{color:#fff}.pre-top-bar-container{background:#292929}.prettyprint.source,.prettyprint code{background-color:#222;color:#c9d1d9}.pre-div{background-color:#222}.hljs .hljs-ln-numbers{color:#777}.hljs .selected{background:#444}.hljs .selected .hljs-ln-numbers{color:#eee}table .name,.params .name,.props .name,.name code{color:#fff}table td,.params td{background-color:#292929}table thead th,.params thead th,.props thead th{background-color:#222;color:#fff}table .params thead tr,.params .params thead tr,.props .props thead tr{background-color:#222;color:#fff}.disabled{color:#aaa}.code-lang-name{color:#ff8a00}.tooltip{background:#ffce76;color:#222}.hljs-comment{color:#8b949e}.hljs-doctag,.hljs-keyword,.hljs-template-tag,.hljs-variable.language_{color:#ff7b72}.hljs-template-variable,.hljs-type{color:#30ac7c}.hljs-meta,.hljs-string,.hljs-regexp{color:#a5d6ff}.hljs-title.class_,.hljs-title{color:#ffa657}.hljs-title.class_.inherited__,.hljs-title.function_{color:#d2a8ff}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{color:#79c0ff}.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#a5d6ff}.hljs-built_in,.hljs-symbol{color:#ffa657}.hljs-code,.hljs-comment,.hljs-formula{color:#8b949e}.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{color:#7ee787}.hljs-subst{color:#c9d1d9}.hljs-section{color:#1f6feb;font-weight:700}.hljs-bullet{color:#f2cc60}.hljs-emphasis{color:#c9d1d9;font-style:italic}.hljs-strong{color:#c9d1d9;font-weight:700}blockquote{background:#222;color:#fff}.search-container{background:rgba(255,255,255,.1)}.icon-button.search-close-button svg{fill:#a00}.search-container .wrapper{background:#222}.search-result-c{color:#666}.search-box-c{fill:#333}.search-input{background:#333;color:#fff}.search-box-c svg{fill:#fff}.search-result-item{background:#333}.search-result-item:hover{background:#444}.search-result-item:active{background:#555}.search-result-item-title{color:#fff}.search-result-item-p{color:#aaa}.mobile-menu-icon-container .icon-button{background:#333}.mobile-sidebar-container{background:#1a1a1a}.mobile-sidebar-wrapper{background:#222}::-webkit-scrollbar-track{background:#333}::-webkit-scrollbar-thumb{background:#555;outline:.06125rem solid #555}.light ::selection{background:#ffce76;color:#1d1919}body.light{background-color:#fff;color:#111}.light a,.light a:active{color:#007bff}.light hr{color:#f7f7f7}.light h1,.light h2,.light h3,.light h4,.light h5,.light h6{color:#111}.light .sidebar{background-color:#f7f7f7;color:#222}.light .sidebar-title{color:#222}.light .sidebar-section-title{color:#222}.light .sidebar-section-title:hover{background:#eee}.light .with-arrow{fill:#111}.light .sidebar-section-children-container{background:#eee}.light .sidebar-section-children a:hover{background:#e0e0e0}.light .sidebar-section-children a{color:#111}.light .navbar-container{background:#fff}.light .icon-button svg,.light .navbar-item a{color:#222;fill:#222}.light .tippy-box{background:#eee;color:#111}.light .tippy-arrow{color:#f1f1f1}.light .font-size-tooltip .icon-button svg{fill:#111}.light .font-size-tooltip .icon-button.disabled svg{fill:#999}.light .icon-button:hover{background:#ddd}.light .icon-button:active{background:#ccc}.light .navbar-item a:active{color:#333;background-color:#eee}.light .navbar-item:hover{background:#f7f7f7}.light .footer{background:#f7f7f7;color:#111}.light .footer a{color:#111}.light .toc-link{color:#999;transition:color .3s;font-size:.875rem}.light .toc-link.is-active-link{color:#111}.light .has-anchor .link-anchor{color:#ddd}.light .has-anchor .link-anchor:hover{color:#ccc}.light .signature-attributes{color:#aaa}.light .ancestors{color:#999}.light .ancestors a{color:#999!important}.light .important{color:#ee1313}.light .type-signature{color:#00918e}.light .name,.light .name a{color:#293a80}.light .details{background:#f9f9f9;color:#101010}.light .member-item-container strong,.light .method-member-container strong{color:#000}.light .prettyprint{background:#f7f7f7}.light .pre-div{background:#f7f7f7}.light .hljs .hljs-ln-numbers{color:#aaa}.light .hljs .selected{background:#ccc}.light table.hljs-ln td{background:0 0}.light .hljs .selected .hljs-ln-numbers{color:#444}.light .pre-top-bar-container{background-color:#eee}.light .prettyprint code{background-color:#f7f7f7}.light table .name,.light .params .name,.light .props .name,.light .name code{color:#4d4e53}.light table td,.light .params td{background:#f7f7f7}.light table thead th,.light .params thead th,.light .props thead th{background-color:#eee;color:#111}.light table .params thead tr,.light .params .params thead tr,.light .props .props thead tr{background-color:#eee;color:#111}.light .disabled{color:#454545}.light .code-lang-name{color:red}.light .tooltip{background:#ffce76;color:#000}.light .hljs-comment,.light .hljs-quote{color:#a0a1a7}.light .hljs-doctag,.light .hljs-keyword,.light .hljs-formula{color:#a626a4}.light .hljs-section,.light .hljs-name,.light .hljs-selector-tag,.light .hljs-deletion,.light .hljs-subst{color:#e45649}.light .hljs-literal{color:#0184bb}.light .hljs-string,.light .hljs-regexp,.light .hljs-addition,.light .hljs-attribute,.light .hljs-meta .hljs-string{color:#50a14f}.light .hljs-attr,.light .hljs-variable,.light .hljs-template-variable,.light .hljs-type,.light .hljs-selector-class,.light .hljs-selector-attr,.light .hljs-selector-pseudo,.light .hljs-number{color:#986801}.light .hljs-symbol,.light .hljs-bullet,.light .hljs-link,.light .hljs-meta,.light .hljs-selector-id,.light .hljs-title{color:#4078f2}.light .hljs-built_in,.light .hljs-title.class_,.light .hljs-class .hljs-title{color:#c18401}.light .hljs-emphasis{font-style:italic}.light .hljs-strong{font-weight:700}.light .hljs-link{text-decoration:underline}.light blockquote{background:#eee;color:#111}.light code{background:#ddd;color:#000}.light .search-container{background:rgba(0,0,0,.1)}.light .search-close-button svg{fill:red}.light .search-container .wrapper{background:#eee}.light .search-result-c{color:#aaa}.light .search-box-c svg{fill:#333}.light .search-input{background:#f7f7f7;color:#111}.light .search-result-item{background:#f7f7f7}.light .search-result-item:hover{background:#e9e9e9}.light .search-result-item:active{background:#f7f7f7}.light .search-result-item-title{color:#111}.light .search-result-item-p{color:#aaa}.light .mobile-menu-icon-container .icon-button{background:#e5e5e5}.light .mobile-sidebar-container{background:#fff}.light .mobile-sidebar-wrapper{background:#f7f7f7}.light ::-webkit-scrollbar-track{background:#ddd}.light ::-webkit-scrollbar-thumb{background:#aaa;outline:.06125rem solid #aaa} \ No newline at end of file diff --git a/doc/styles/layout.css b/doc/styles/layout.css new file mode 100644 index 0000000000000000000000000000000000000000..b90fa866eabe59703330b599baa61813a2356c72 --- /dev/null +++ b/doc/styles/layout.css @@ -0,0 +1,18 @@ +:root { + --outer-wrapper-max-width: 99% !important; +} + + +table td:first-child, .params td:first-child, table thead th:first-child, .params thead th:first-child, .props thead th:first-child { + border-top-left-radius: 0.1rem !important; + border-bottom-left-radius: 0.1rem !important; +} + +table td:last-child, .params td:last-child, table thead th:last-child, .params thead th:last-child, .props thead th:last-child { + border-top-right-radius: 0.1rem !important; + border-bottom-right-radius: 0.1rem !important; +} + +.details { + border-radius: 0.1rem !important; +} \ No newline at end of file diff --git a/documentation/tutorial/tutorials.json b/documentation/tutorial/tutorials.json deleted file mode 100644 index 0e0dcd235c4973becf25f38eb4e5bb26e154c86a..0000000000000000000000000000000000000000 --- a/documentation/tutorial/tutorials.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - -} \ No newline at end of file diff --git a/application/example/constraints/andoperator.mjs b/example/constraints/andoperator.mjs similarity index 100% rename from application/example/constraints/andoperator.mjs rename to example/constraints/andoperator.mjs diff --git a/application/example/constraints/invalid.mjs b/example/constraints/invalid.mjs similarity index 100% rename from application/example/constraints/invalid.mjs rename to example/constraints/invalid.mjs diff --git a/application/example/constraints/isarray.mjs b/example/constraints/isarray.mjs similarity index 100% rename from application/example/constraints/isarray.mjs rename to example/constraints/isarray.mjs diff --git a/application/example/constraints/isobject.mjs b/example/constraints/isobject.mjs similarity index 100% rename from application/example/constraints/isobject.mjs rename to example/constraints/isobject.mjs diff --git a/application/example/constraints/oroperator.mjs b/example/constraints/oroperator.mjs similarity index 100% rename from application/example/constraints/oroperator.mjs rename to example/constraints/oroperator.mjs diff --git a/application/example/constraints/valid.mjs b/example/constraints/valid.mjs similarity index 100% rename from application/example/constraints/valid.mjs rename to example/constraints/valid.mjs diff --git a/application/example/data/buildmap.mjs b/example/data/buildmap.mjs similarity index 100% rename from application/example/data/buildmap.mjs rename to example/data/buildmap.mjs diff --git a/application/example/data/datasource.mjs b/example/data/datasource.mjs similarity index 100% rename from application/example/data/datasource.mjs rename to example/data/datasource.mjs diff --git a/application/example/data/datasource/server/restapi.mjs b/example/data/datasource/server/restapi.mjs similarity index 100% rename from application/example/data/datasource/server/restapi.mjs rename to example/data/datasource/server/restapi.mjs diff --git a/application/example/data/datasource/server/webconnect.mjs b/example/data/datasource/server/webconnect.mjs similarity index 100% rename from application/example/data/datasource/server/webconnect.mjs rename to example/data/datasource/server/webconnect.mjs diff --git a/application/example/data/diff.mjs b/example/data/diff.mjs similarity index 100% rename from application/example/data/diff.mjs rename to example/data/diff.mjs diff --git a/application/example/data/pathfinder-1.mjs b/example/data/pathfinder-1.mjs similarity index 100% rename from application/example/data/pathfinder-1.mjs rename to example/data/pathfinder-1.mjs diff --git a/application/example/data/pathfinder-2.mjs b/example/data/pathfinder-2.mjs similarity index 100% rename from application/example/data/pathfinder-2.mjs rename to example/data/pathfinder-2.mjs diff --git a/application/example/data/pipe.mjs b/example/data/pipe.mjs similarity index 100% rename from application/example/data/pipe.mjs rename to example/data/pipe.mjs diff --git a/application/example/data/transformer.mjs b/example/data/transformer.mjs similarity index 100% rename from application/example/data/transformer.mjs rename to example/data/transformer.mjs diff --git a/application/example/dom/customelement.mjs b/example/dom/customelement.mjs similarity index 100% rename from application/example/dom/customelement.mjs rename to example/dom/customelement.mjs diff --git a/application/example/dom/theme.mjs b/example/dom/theme.mjs similarity index 100% rename from application/example/dom/theme.mjs rename to example/dom/theme.mjs diff --git a/application/example/dom/updater.mjs b/example/dom/updater.mjs similarity index 100% rename from application/example/dom/updater.mjs rename to example/dom/updater.mjs diff --git a/application/example/i18n/formatter.mjs b/example/i18n/formatter.mjs similarity index 100% rename from application/example/i18n/formatter.mjs rename to example/i18n/formatter.mjs diff --git a/application/example/i18n/providers/embed.mjs b/example/i18n/providers/embed.mjs similarity index 100% rename from application/example/i18n/providers/embed.mjs rename to example/i18n/providers/embed.mjs diff --git a/application/example/i18n/providers/fetch.mjs b/example/i18n/providers/fetch.mjs similarity index 100% rename from application/example/i18n/providers/fetch.mjs rename to example/i18n/providers/fetch.mjs diff --git a/application/example/i18n/translations.mjs b/example/i18n/translations.mjs similarity index 100% rename from application/example/i18n/translations.mjs rename to example/i18n/translations.mjs diff --git a/application/example/net/webconnect.mjs b/example/net/webconnect.mjs similarity index 100% rename from application/example/net/webconnect.mjs rename to example/net/webconnect.mjs diff --git a/application/example/types/basewithoptions.mjs b/example/types/basewithoptions.mjs similarity index 100% rename from application/example/types/basewithoptions.mjs rename to example/types/basewithoptions.mjs diff --git a/application/example/types/is-1.mjs b/example/types/is-1.mjs similarity index 100% rename from application/example/types/is-1.mjs rename to example/types/is-1.mjs diff --git a/application/example/types/is-10.mjs b/example/types/is-10.mjs similarity index 100% rename from application/example/types/is-10.mjs rename to example/types/is-10.mjs diff --git a/application/example/types/is-2.mjs b/example/types/is-2.mjs similarity index 100% rename from application/example/types/is-2.mjs rename to example/types/is-2.mjs diff --git a/application/example/types/is-3.mjs b/example/types/is-3.mjs similarity index 100% rename from application/example/types/is-3.mjs rename to example/types/is-3.mjs diff --git a/application/example/types/is-4.mjs b/example/types/is-4.mjs similarity index 100% rename from application/example/types/is-4.mjs rename to example/types/is-4.mjs diff --git a/application/example/types/is-5.mjs b/example/types/is-5.mjs similarity index 100% rename from application/example/types/is-5.mjs rename to example/types/is-5.mjs diff --git a/application/example/types/is-6.mjs b/example/types/is-6.mjs similarity index 100% rename from application/example/types/is-6.mjs rename to example/types/is-6.mjs diff --git a/application/example/types/is-7.mjs b/example/types/is-7.mjs similarity index 100% rename from application/example/types/is-7.mjs rename to example/types/is-7.mjs diff --git a/application/example/types/is-8.mjs b/example/types/is-8.mjs similarity index 100% rename from application/example/types/is-8.mjs rename to example/types/is-8.mjs diff --git a/application/example/types/is-9.mjs b/example/types/is-9.mjs similarity index 100% rename from application/example/types/is-9.mjs rename to example/types/is-9.mjs diff --git a/application/example/types/noderecursiveiterator.mjs b/example/types/noderecursiveiterator.mjs similarity index 100% rename from application/example/types/noderecursiveiterator.mjs rename to example/types/noderecursiveiterator.mjs diff --git a/application/example/types/observer.mjs b/example/types/observer.mjs similarity index 100% rename from application/example/types/observer.mjs rename to example/types/observer.mjs diff --git a/application/example/types/proxyobserver.mjs b/example/types/proxyobserver.mjs similarity index 100% rename from application/example/types/proxyobserver.mjs rename to example/types/proxyobserver.mjs diff --git a/application/example/types/queue.mjs b/example/types/queue.mjs similarity index 100% rename from application/example/types/queue.mjs rename to example/types/queue.mjs diff --git a/application/example/types/tokenlist-1.mjs b/example/types/tokenlist-1.mjs similarity index 100% rename from application/example/types/tokenlist-1.mjs rename to example/types/tokenlist-1.mjs diff --git a/application/example/types/tokenlist-2.mjs b/example/types/tokenlist-2.mjs similarity index 100% rename from application/example/types/tokenlist-2.mjs rename to example/types/tokenlist-2.mjs diff --git a/application/example/types/tokenlist-3.mjs b/example/types/tokenlist-3.mjs similarity index 100% rename from application/example/types/tokenlist-3.mjs rename to example/types/tokenlist-3.mjs diff --git a/application/example/types/tokenlist-4.mjs b/example/types/tokenlist-4.mjs similarity index 100% rename from application/example/types/tokenlist-4.mjs rename to example/types/tokenlist-4.mjs diff --git a/application/example/types/tokenlist-5.mjs b/example/types/tokenlist-5.mjs similarity index 100% rename from application/example/types/tokenlist-5.mjs rename to example/types/tokenlist-5.mjs diff --git a/application/example/types/typeof.mjs b/example/types/typeof.mjs similarity index 100% rename from application/example/types/typeof.mjs rename to example/types/typeof.mjs diff --git a/application/example/types/version-1.mjs b/example/types/version-1.mjs similarity index 100% rename from application/example/types/version-1.mjs rename to example/types/version-1.mjs diff --git a/application/example/types/version-2.mjs b/example/types/version-2.mjs similarity index 100% rename from application/example/types/version-2.mjs rename to example/types/version-2.mjs diff --git a/application/example/util/comparator.mjs b/example/util/comparator.mjs similarity index 100% rename from application/example/util/comparator.mjs rename to example/util/comparator.mjs diff --git a/application/example/util/deadmansswitch.mjs b/example/util/deadmansswitch.mjs similarity index 100% rename from application/example/util/deadmansswitch.mjs rename to example/util/deadmansswitch.mjs diff --git a/application/example/util/processing.mjs b/example/util/processing.mjs similarity index 100% rename from application/example/util/processing.mjs rename to example/util/processing.mjs diff --git a/monster.iml b/monster.iml deleted file mode 100644 index cb8f4ea3a6e997a1fc9282a707f1dba31f46ce3f..0000000000000000000000000000000000000000 --- a/monster.iml +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<module type="WEB_MODULE" version="4"> - <component name="NewModuleRootManager" inherit-compiler-output="true"> - <exclude-output /> - <content url="file://$MODULE_DIR$"> - <excludeFolder url="file://$MODULE_DIR$/deployment/build" /> - </content> - <orderEntry type="inheritedJdk" /> - <orderEntry type="sourceFolder" forTests="false" /> - </component> -</module> \ No newline at end of file diff --git a/opt/scripts/build-exports.cjs b/opt/scripts/build-exports.cjs new file mode 100755 index 0000000000000000000000000000000000000000..6ce8a1aff74981690ce415d9686b5943392f4e1f --- /dev/null +++ b/opt/scripts/build-exports.cjs @@ -0,0 +1,80 @@ +const regex = /^\s*(?<exp>(export\s+{[^}]+)})/gm; +const fs = require('fs'); +var path = require('path') +const basename = __dirname + '/../../source/' + +let exportLines = [] + +function scanSymbols(root) { + + let f; + + const dir = fs.opendirSync(root); + while ((f = dir.readSync()) !== null) { + + if (f.isDirectory()) { + scanSymbols(path.join(root, f.name)); + continue; + } else if (!f.isFile()) { + continue; + } + + if(f.name==="monster.mjs") continue; + + if ((path.extname(f.name) !== ".mjs")) { + continue; + } + + const fn = path.join(root, f.name); + let content = fs.readFileSync(fn, 'utf8'); + + while ((m = regex.exec(content)) !== null) { + let exp = m.groups?.exp; + if (!exp) { + continue; + } + exportLines.push("__PLACEHOLDER__" + " from \"./" + path.relative(basename, fn) + "\""); + } + } +} + +scanSymbols(path.normalize(basename)) +const content = exportLines.join("\n"); + +let fileContent=` +/** + * Copyright schukai GmbH and contributors 2023. All Rights Reserved. + * Node module: @schukai/monster + * This file is licensed under the AGPLv3 License. + * License text available at https://www.gnu.org/licenses/agpl-3.0.en.html + * SPDX-License-Identifier: AGPL-3.0-only or COMMERCIAL + */ + +/** THIS FILE IS AUTOGENERATED AND SHOULD NOT BE EDITED DIRECTLY. **/ + +/** + * Main namespace for Monster. + * + * @namespace Monster + * @author schukai GmbH + */ + +` + content.replace(/__PLACEHOLDER__/gm, "export *") + ` + +export { Monster }; + +/** + * This class has no other purpose than to exist. + * + * @license AGPLv3 + * @since 2.0.0 + * @copyright schukai GmbH + * @memberOf Monster + */ +class Monster {} +`; + + +// write fileContent to file +fs.writeFileSync(basename + "monster.mjs", fileContent, 'utf8') + diff --git a/development/script/build-stylesheets.cjs b/opt/scripts/build-stylesheets.cjs similarity index 100% rename from development/script/build-stylesheets.cjs rename to opt/scripts/build-stylesheets.cjs diff --git a/development/script/replace-codepen-skypack.cjs b/opt/scripts/replace-skypack.cjs old mode 100755 new mode 100644 similarity index 50% rename from development/script/replace-codepen-skypack.cjs rename to opt/scripts/replace-skypack.cjs index f091a98e9727c2d53d295c4d466096bd9e9d012a..b0c188deec8defff711122b78f33b79cf921192e --- a/development/script/replace-codepen-skypack.cjs +++ b/opt/scripts/replace-skypack.cjs @@ -1,13 +1,35 @@ -#!/usr/bin/env node +const fs = require('fs'); +const os = require('os'); +const path = require('path'); +const process = require('process'); + +const args = process.argv.slice(2); + +if (args.length < 1) { + console.log("Usage: node replace-skypack.js <project-root>"); + process.exit(1); +} + +const projectRoot = args[0]; +if (!fs.existsSync(projectRoot)) { + console.log("Project root " + projectRoot + " does not exist"); + process.exit(1); +} + +const absoluteProjectRoot = path.resolve(projectRoot) + "/"; +if (!fs.existsSync(absoluteProjectRoot)) { + console.log("Project root " + absoluteProjectRoot + " does not exist"); + process.exit(1); +} + +// regex const regex = /<form action=\"https:\/\/codepen.*<\/form>/gm; -const fs = require('fs'); -var path = require('path') -const packageJson = path.join(__dirname, '../../application/package.json'); +const packageJson = path.join(absoluteProjectRoot, 'package.json'); const packageJsonContent = JSON.parse( fs.readFileSync(packageJson, 'utf8')); -const docPath = path.normalize(__dirname + '/../../deployment/build/docs/') +const docPath = path.normalize(absoluteProjectRoot + 'dist/doc/') const dir = fs.opendirSync(docPath); while ((f = dir.readSync()) !== null) { @@ -22,6 +44,7 @@ while ((f = dir.readSync()) !== null) { const fn = docPath + f.name; let content = fs.readFileSync(fn, 'utf8'); + let m; while ((m = regex.exec(content)) !== null) { m.forEach((match, groupIndex) => { const s=match.replaceAll(";"+packageJsonContent.name, ";https://cdn.skypack.dev/"+packageJsonContent.name+"@latest"); @@ -31,4 +54,6 @@ while ((f = dir.readSync()) !== null) { fs.writeFileSync(fn, content, 'utf8') -} \ No newline at end of file +} + +dir.closeSync(); diff --git a/opt/scripts/stylesheets.cjs b/opt/scripts/stylesheets.cjs new file mode 100644 index 0000000000000000000000000000000000000000..0047228ce46595968052ba2863de7ab86a119bf6 --- /dev/null +++ b/opt/scripts/stylesheets.cjs @@ -0,0 +1,205 @@ +const fs = require('fs'); +const os = require('os'); +const path = require('path'); +const postcss = require('postcss'); +const cssnano = require('cssnano'); +const normalizeCss = require('postcss-normalize'); +const postcssFluid = require('postcss-fluid'); +const importCss = require('postcss-import'); +const postcssNesting = require('postcss-nesting'); +const postcssFor = require('postcss-for'); +const postcssRtlcss = require('postcss-rtlcss'); +const autoprefixer = require('autoprefixer'); +const postcssMixins = require('postcss-mixins'); +const postcssStripUnits = require('postcss-strip-units'); + +const args = process.argv.slice(2); + +if (args.length < 1) { + console.log("Usage: node build-stylesheets.js <project-root>"); + process.exit(1); +} + +const projectRoot = args[0]; + +if (!fs.existsSync(projectRoot)) { + console.log("Project root " + projectRoot + " does not exist"); + process.exit(1); +} + +const absoluteProjectRoot = path.resolve(projectRoot) + "/"; +const styleSourceRoot = absoluteProjectRoot + 'application/source/style/' +const nodeModuleStyleSourceRoot = absoluteProjectRoot + 'development/node_modules/' +const styleSheetRoot = absoluteProjectRoot + 'application/source/stylesheet/' + +if (!fs.existsSync(styleSourceRoot)) { + console.log("Style source root " + styleSourceRoot + " does not exist"); + process.exit(1); +} + +if (!fs.existsSync(nodeModuleStyleSourceRoot)) { + console.log("Node module style source root " + nodeModuleStyleSourceRoot + " does not exist"); + process.exit(1); +} + +if (!fs.existsSync(styleSheetRoot)) { + fs.mkdirSync(styleSheetRoot); +} + +let promises = []; +let styles = new Map(); + +const packageJsonPath = absoluteProjectRoot + 'development/package.json'; +const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); +const copyRightYear = new Date().getFullYear(); + +const codeTemplate = ` +/** + * Copyright schukai GmbH and contributors ${copyRightYear}. All Rights Reserved. + * Node module: ${packageJson.name} + * This file is licensed under the AGPLv3 License. + * License text available at https://www.gnu.org/licenses/agpl-3.0.en.html + */ + +import {addAttributeToken} from "@schukai/monster/source/dom/attributes.mjs"; +import {ATTRIBUTE_ERRORMESSAGE} from "@schukai/monster/source/dom/constants.mjs"; + +export {{{ClassName}}StyleSheet} + +/** + * @private + * @type {CSSStyleSheet} + */ +const {{ClassName}}StyleSheet = new CSSStyleSheet(); + +try { + {{ClassName}}StyleSheet.insertRule(\` +@layer {{LayerName}} { +{{css}} +}\`, 0); +} catch (e) { + addAttributeToken(document.getRootNode().querySelector('html'), ATTRIBUTE_ERRORMESSAGE, e + ""); +} +`; + + +function scanFiles(root, keyPath) { + + if (keyPath === undefined) { + keyPath = []; + } + + return new Promise((resolve, reject) => { + + let localPromises = []; + let f; + + const dir = fs.opendirSync(root); + while ((f = dir.readSync()) !== null) { + + const key = f.name; + const fn = path.join(root, f.name); + const currentPath = [...keyPath] + currentPath.push(key); + + if (f.isDirectory()) { + + if (["node_modules","mixin"].includes(f.name)) { + continue; + } + + localPromises.push(scanFiles(fn, currentPath)); + continue; + } else if (!f.isFile()) { + continue; + } + + if ((path.extname(f.name) !== ".css" && path.extname(f.name) !== ".pcss")) { + continue; + } + + console.log("Found file: " + fn); + let content = fs.readFileSync(fn, 'utf8'); + localPromises.push(rewriteCSS(content, fn, currentPath)); + } + + dir.closeSync(); + + Promise.all(localPromises).then(resolve).catch(reject); + + }) +} + + +function rewriteCSS(content, sourceFile, keyPath) { + + const newPath = path.format({...path.parse(keyPath.join("/")), base: '', ext: '.mjs'}) + + return new Promise((resolve, reject) => { + + return postcss([ + importCss({ + path: [styleSourceRoot, nodeModuleStyleSourceRoot], + }), + normalizeCss, + postcssMixins, + postcssNesting(), + postcssFor(), + postcssStripUnits({ + functionName: 'strip-units', + }), + postcssFluid({ + // Defaults: + min: '320px', // Min media size + max: '1800px', // Max media size + functionName: 'fluid', // function name, may be anything + }), // https://github.com/notiv-nt/postcss-fluid + autoprefixer, + //postcssRtlcss, + cssnano + ]).process(content, { + from: undefined, + + }).catch((e) => { + reject(e + " in file " + sourceFile); + }).then(result => { + + styles.set(newPath, result.css); + resolve(); + + }); + + }) + +} + + +scanFiles(path.normalize(styleSourceRoot)).then(() => { + + styles.forEach((css, fn) => { + + let className = path.parse(fn).name; + className = className.charAt(0).toUpperCase() + className.slice(1); + className = className.replace(/-([a-z])/g, function (g) { + return g[1].toUpperCase(); + }); + let layerName = className.toLowerCase(); + + css = css.replace(/"/g, '\\"'); + const code = codeTemplate + .replaceAll("{{ClassName}}", className) + .replaceAll("{{LayerName}}", layerName) + .replaceAll("{{css}}", css); + + const targetFile = path.normalize(path.join(styleSheetRoot, fn)); + fs.mkdirSync(path.dirname(targetFile), {recursive: true}); + fs.writeFileSync(targetFile, code); + }) + +}).catch(e => { + console.log("Error styles.css"); + console.error(e); +}) + + +console.log("Done"); diff --git a/application/package.json b/package.json similarity index 100% rename from application/package.json rename to package.json diff --git a/development/playground/custom-element/index.html b/playground/custom-element/index.html similarity index 100% rename from development/playground/custom-element/index.html rename to playground/custom-element/index.html diff --git a/development/playground/custom-element/main.mjs b/playground/custom-element/main.mjs similarity index 100% rename from development/playground/custom-element/main.mjs rename to playground/custom-element/main.mjs diff --git a/development/playground/custom-element/main.pcss b/playground/custom-element/main.pcss similarity index 100% rename from development/playground/custom-element/main.pcss rename to playground/custom-element/main.pcss diff --git a/development/playground/dom-arguments/index.html b/playground/dom-arguments/index.html similarity index 100% rename from development/playground/dom-arguments/index.html rename to playground/dom-arguments/index.html diff --git a/development/playground/dom-arguments/main.mjs b/playground/dom-arguments/main.mjs similarity index 100% rename from development/playground/dom-arguments/main.mjs rename to playground/dom-arguments/main.mjs diff --git a/development/playground/dom-arguments/translation.json b/playground/dom-arguments/translation.json similarity index 100% rename from development/playground/dom-arguments/translation.json rename to playground/dom-arguments/translation.json diff --git a/development/playground/dom-insert/index.html b/playground/dom-insert/index.html similarity index 100% rename from development/playground/dom-insert/index.html rename to playground/dom-insert/index.html diff --git a/development/playground/dom-insert/main.mjs b/playground/dom-insert/main.mjs similarity index 100% rename from development/playground/dom-insert/main.mjs rename to playground/dom-insert/main.mjs diff --git a/development/playground/drag-and-drop/index.html b/playground/drag-and-drop/index.html similarity index 100% rename from development/playground/drag-and-drop/index.html rename to playground/drag-and-drop/index.html diff --git a/development/playground/i18n-control/index.html b/playground/i18n-control/index.html similarity index 100% rename from development/playground/i18n-control/index.html rename to playground/i18n-control/index.html diff --git a/development/playground/i18n-control/main.mjs b/playground/i18n-control/main.mjs similarity index 100% rename from development/playground/i18n-control/main.mjs rename to playground/i18n-control/main.mjs diff --git a/development/playground/i18n-control/translation.json b/playground/i18n-control/translation.json similarity index 100% rename from development/playground/i18n-control/translation.json rename to playground/i18n-control/translation.json diff --git a/development/playground/i18n-updater/translation.json b/playground/i18n-updater/translation.json similarity index 100% rename from development/playground/i18n-updater/translation.json rename to playground/i18n-updater/translation.json diff --git a/development/playground/i18n-updater/updater.html b/playground/i18n-updater/updater.html similarity index 100% rename from development/playground/i18n-updater/updater.html rename to playground/i18n-updater/updater.html diff --git a/development/playground/i18n-updater/updater.js b/playground/i18n-updater/updater.js similarity index 100% rename from development/playground/i18n-updater/updater.js rename to playground/i18n-updater/updater.js diff --git a/development/playground/index.html b/playground/index.html similarity index 100% rename from development/playground/index.html rename to playground/index.html diff --git a/development/playground/vite.config.js b/playground/vite.config.js similarity index 98% rename from development/playground/vite.config.js rename to playground/vite.config.js index c113478d838e9547b3a37d6ef3004dfb4ed5be22..41faec5f9ec758ea3ca1c79604efa15046f0ab68 100644 --- a/development/playground/vite.config.js +++ b/playground/vite.config.js @@ -16,7 +16,7 @@ import postcssResponsiveType from 'postcss-responsive-type'; import {directoryPlugin} from "vite-plugin-list-directory-contents"; -import mkcert from 'vite-plugin-mkcert' +//import mkcert from 'vite-plugin-mkcert' import {ViteMinifyPlugin} from 'vite-plugin-minify' import {globSync} from 'glob' @@ -104,7 +104,7 @@ export default defineConfig({ banner( `/**\n * name: ${pkg.name}\n * version: v${pkg.version}\n * description: ${pkg.description}\n * author: ${pkg.author}\n * homepage: ${pkg.homepage}\n */` ), - mkcert({}), + // mkcert({}), ViteMinifyPlugin(), directoryPlugin({ baseDir: __dirname diff --git a/development/pnpm-lock.yaml b/pnpm-lock.yaml similarity index 67% rename from development/pnpm-lock.yaml rename to pnpm-lock.yaml index 2f362b60ff6e2e13bb2ae2b4da0374de935c09e3..62d07122729f2d99cff964a3e58f57cc262e9213 100644 --- a/development/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,9 +1,13 @@ lockfileVersion: '6.0' +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + devDependencies: - '@oss/web-components-build-tools': - specifier: ^1.2.8 - version: 1.2.8 + '@biomejs/biome': + specifier: 1.3.3 + version: 1.3.3 '@peculiar/webcrypto': specifier: ^1.4.3 version: 1.4.3 @@ -43,6 +47,12 @@ devDependencies: esbuild: specifier: ^0.18.4 version: 0.18.4 + esdoc: + specifier: ^1.1.0 + version: 1.1.0 + esdoc-standard-plugin: + specifier: ^1.0.0 + version: 1.0.0 flow-bin: specifier: ^0.209.0 version: 0.209.0 @@ -61,6 +71,9 @@ devDependencies: jsdoc-external-example: specifier: github:volker-schukai/jsdoc-external-example version: github.com/volker-schukai/jsdoc-external-example/e039186b531487bd1b1d5e2e1586a396b910c9d9 + jsdoc-mermaid: + specifier: ^1.0.0 + version: 1.0.0 jsdoc-plantuml: specifier: ^1.0.3 version: 1.0.3(jsdoc@4.0.2) @@ -112,9 +125,9 @@ devDependencies: postcss-strip-units: specifier: ^2.0.1 version: 2.0.1 - rome: - specifier: ^12.1.3 - version: 12.1.3 + puppeteer: + specifier: ^21.4.1 + version: 21.4.1 sinon: specifier: ^15.1.2 version: 15.1.2 @@ -129,7 +142,7 @@ devDependencies: version: 0.12.5 vite: specifier: ^4.3.9 - version: 4.3.9(@types/node@18.16.18) + version: 4.3.9(@types/node@18.18.8) vite-plugin-banner: specifier: ^0.7.0 version: 0.7.0 @@ -139,9 +152,6 @@ devDependencies: vite-plugin-minify: specifier: ^1.5.2 version: 1.5.2(vite@4.3.9) - vite-plugin-mkcert: - specifier: ^1.15.0 - version: 1.15.0(vite@4.3.9) ws: specifier: ^8.13.0 version: 8.13.0 @@ -153,123 +163,119 @@ packages: engines: {node: '>=6.0.0'} dependencies: '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.18 + '@jridgewell/trace-mapping': 0.3.20 dev: true - /@babel/code-frame@7.22.5: - resolution: {integrity: sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==} + /@babel/code-frame@7.22.13: + resolution: {integrity: sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/highlight': 7.22.5 + '@babel/highlight': 7.22.20 + chalk: 2.4.2 dev: true - /@babel/compat-data@7.22.5: - resolution: {integrity: sha512-4Jc/YuIaYqKnDDz892kPIledykKg12Aw1PYX5i/TY28anJtacvM1Rrr8wbieB9GfEJwlzqT0hUEao0CxEebiDA==} + /@babel/compat-data@7.23.2: + resolution: {integrity: sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ==} engines: {node: '>=6.9.0'} dev: true - /@babel/core@7.22.5: - resolution: {integrity: sha512-SBuTAjg91A3eKOvD+bPEz3LlhHZRNu1nFOVts9lzDJTXshHTjII0BAtDS3Y2DAkdZdDKWVZGVwkDfc4Clxn1dg==} + /@babel/core@7.23.2: + resolution: {integrity: sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ==} engines: {node: '>=6.9.0'} dependencies: '@ampproject/remapping': 2.2.1 - '@babel/code-frame': 7.22.5 - '@babel/generator': 7.22.5 - '@babel/helper-compilation-targets': 7.22.5(@babel/core@7.22.5) - '@babel/helper-module-transforms': 7.22.5 - '@babel/helpers': 7.22.5 - '@babel/parser': 7.22.5 - '@babel/template': 7.22.5 - '@babel/traverse': 7.22.5 - '@babel/types': 7.22.5 - convert-source-map: 1.9.0 + '@babel/code-frame': 7.22.13 + '@babel/generator': 7.23.0 + '@babel/helper-compilation-targets': 7.22.15 + '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.2) + '@babel/helpers': 7.23.2 + '@babel/parser': 7.23.0 + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.2 + '@babel/types': 7.23.0 + convert-source-map: 2.0.0 debug: 4.3.4(supports-color@8.1.1) gensync: 1.0.0-beta.2 json5: 2.2.3 - semver: 6.3.0 + semver: 6.3.1 transitivePeerDependencies: - supports-color dev: true - /@babel/generator@7.22.5: - resolution: {integrity: sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA==} + /@babel/generator@7.23.0: + resolution: {integrity: sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.22.5 + '@babel/types': 7.23.0 '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.18 + '@jridgewell/trace-mapping': 0.3.20 jsesc: 2.5.2 dev: true - /@babel/helper-compilation-targets@7.22.5(@babel/core@7.22.5): - resolution: {integrity: sha512-Ji+ywpHeuqxB8WDxraCiqR0xfhYjiDE/e6k7FuIaANnoOFxAHskHChz4vA1mJC9Lbm01s1PVAGhQY4FUKSkGZw==} + /@babel/helper-compilation-targets@7.22.15: + resolution: {integrity: sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==} engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 dependencies: - '@babel/compat-data': 7.22.5 - '@babel/core': 7.22.5 - '@babel/helper-validator-option': 7.22.5 + '@babel/compat-data': 7.23.2 + '@babel/helper-validator-option': 7.22.15 browserslist: 4.21.9 lru-cache: 5.1.1 - semver: 6.3.0 + semver: 6.3.1 dev: true - /@babel/helper-environment-visitor@7.22.5: - resolution: {integrity: sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==} + /@babel/helper-environment-visitor@7.22.20: + resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} engines: {node: '>=6.9.0'} dev: true - /@babel/helper-function-name@7.22.5: - resolution: {integrity: sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==} + /@babel/helper-function-name@7.23.0: + resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/template': 7.22.5 - '@babel/types': 7.22.5 + '@babel/template': 7.22.15 + '@babel/types': 7.23.0 dev: true /@babel/helper-hoist-variables@7.22.5: resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.22.5 + '@babel/types': 7.23.0 dev: true - /@babel/helper-module-imports@7.22.5: - resolution: {integrity: sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==} + /@babel/helper-module-imports@7.22.15: + resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.22.5 + '@babel/types': 7.23.0 dev: true - /@babel/helper-module-transforms@7.22.5: - resolution: {integrity: sha512-+hGKDt/Ze8GFExiVHno/2dvG5IdstpzCq0y4Qc9OJ25D4q3pKfiIP/4Vp3/JvhDkLKsDK2api3q3fpIgiIF5bw==} + /@babel/helper-module-transforms@7.23.0(@babel/core@7.23.2): + resolution: {integrity: sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==} engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 dependencies: - '@babel/helper-environment-visitor': 7.22.5 - '@babel/helper-module-imports': 7.22.5 + '@babel/core': 7.23.2 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-module-imports': 7.22.15 '@babel/helper-simple-access': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.5 - '@babel/helper-validator-identifier': 7.22.5 - '@babel/template': 7.22.5 - '@babel/traverse': 7.22.5 - '@babel/types': 7.22.5 - transitivePeerDependencies: - - supports-color + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/helper-validator-identifier': 7.22.20 dev: true /@babel/helper-simple-access@7.22.5: resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.22.5 + '@babel/types': 7.23.0 dev: true - /@babel/helper-split-export-declaration@7.22.5: - resolution: {integrity: sha512-thqK5QFghPKWLhAV321lxF95yCg2K3Ob5yw+M3VHWfdia0IkPXUtoLH8x/6Fh486QUvzhb8YOWHChTVen2/PoQ==} + /@babel/helper-split-export-declaration@7.22.6: + resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.22.5 + '@babel/types': 7.23.0 dev: true /@babel/helper-string-parser@7.22.5: @@ -277,77 +283,77 @@ packages: engines: {node: '>=6.9.0'} dev: true - /@babel/helper-validator-identifier@7.22.5: - resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==} + /@babel/helper-validator-identifier@7.22.20: + resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} engines: {node: '>=6.9.0'} dev: true - /@babel/helper-validator-option@7.22.5: - resolution: {integrity: sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==} + /@babel/helper-validator-option@7.22.15: + resolution: {integrity: sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==} engines: {node: '>=6.9.0'} dev: true - /@babel/helpers@7.22.5: - resolution: {integrity: sha512-pSXRmfE1vzcUIDFQcSGA5Mr+GxBV9oiRKDuDxXvWQQBCh8HoIjs/2DlDB7H8smac1IVrB9/xdXj2N3Wol9Cr+Q==} + /@babel/helpers@7.23.2: + resolution: {integrity: sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/template': 7.22.5 - '@babel/traverse': 7.22.5 - '@babel/types': 7.22.5 + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.2 + '@babel/types': 7.23.0 transitivePeerDependencies: - supports-color dev: true - /@babel/highlight@7.22.5: - resolution: {integrity: sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==} + /@babel/highlight@7.22.20: + resolution: {integrity: sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/helper-validator-identifier': 7.22.5 + '@babel/helper-validator-identifier': 7.22.20 chalk: 2.4.2 js-tokens: 4.0.0 dev: true - /@babel/parser@7.22.5: - resolution: {integrity: sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==} + /@babel/parser@7.23.0: + resolution: {integrity: sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==} engines: {node: '>=6.0.0'} hasBin: true dependencies: - '@babel/types': 7.22.5 + '@babel/types': 7.23.0 dev: true - /@babel/template@7.22.5: - resolution: {integrity: sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==} + /@babel/template@7.22.15: + resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/code-frame': 7.22.5 - '@babel/parser': 7.22.5 - '@babel/types': 7.22.5 + '@babel/code-frame': 7.22.13 + '@babel/parser': 7.23.0 + '@babel/types': 7.23.0 dev: true - /@babel/traverse@7.22.5: - resolution: {integrity: sha512-7DuIjPgERaNo6r+PZwItpjCZEa5vyw4eJGufeLxrPdBXBoLcCJCIasvK6pK/9DVNrLZTLFhUGqaC6X/PA007TQ==} + /@babel/traverse@7.23.2: + resolution: {integrity: sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/code-frame': 7.22.5 - '@babel/generator': 7.22.5 - '@babel/helper-environment-visitor': 7.22.5 - '@babel/helper-function-name': 7.22.5 + '@babel/code-frame': 7.22.13 + '@babel/generator': 7.23.0 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 '@babel/helper-hoist-variables': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.5 - '@babel/parser': 7.22.5 - '@babel/types': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/parser': 7.23.0 + '@babel/types': 7.23.0 debug: 4.3.4(supports-color@8.1.1) globals: 11.12.0 transitivePeerDependencies: - supports-color dev: true - /@babel/types@7.22.5: - resolution: {integrity: sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==} + /@babel/types@7.23.0: + resolution: {integrity: sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==} engines: {node: '>=6.9.0'} dependencies: '@babel/helper-string-parser': 7.22.5 - '@babel/helper-validator-identifier': 7.22.5 + '@babel/helper-validator-identifier': 7.22.20 to-fast-properties: 2.0.0 dev: true @@ -355,6 +361,74 @@ packages: resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} dev: true + /@biomejs/biome@1.3.3: + resolution: {integrity: sha512-vTJn7RBzLWIabUuUIoEopO860YyBrbPEu4Pztfd28jRU5QD074hKZ9IQs24pFO6A2R296gaeYmN62f4u7pUruQ==} + engines: {node: '>=14.*'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@biomejs/cli-darwin-arm64': 1.3.3 + '@biomejs/cli-darwin-x64': 1.3.3 + '@biomejs/cli-linux-arm64': 1.3.3 + '@biomejs/cli-linux-x64': 1.3.3 + '@biomejs/cli-win32-arm64': 1.3.3 + '@biomejs/cli-win32-x64': 1.3.3 + dev: true + + /@biomejs/cli-darwin-arm64@1.3.3: + resolution: {integrity: sha512-2X87ZfbmWwe4NGukrUvnoYdI//muSgjNUCAHJ2DO+kS1sB7kDy1s6PN/IYyTJuqRcJtDuOnSpaUDE7KxR1YhtA==} + engines: {node: '>=14.*'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@biomejs/cli-darwin-x64@1.3.3: + resolution: {integrity: sha512-t+7DWTCbSgHOBcPsGKuwS1qh1z9zbXFK8i8ktE18yW7iF/W0zI62k44fYqYeFJKlb0Q08aqUvez3L+AQJFsn+w==} + engines: {node: '>=14.*'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@biomejs/cli-linux-arm64@1.3.3: + resolution: {integrity: sha512-D8CvXaB8lkXXBQ6B3n0MXSSZFiE60+aNHorBLimVTtKiMod8QvAP425oQFZFul5wMXZqPLGTKFjXbAi/rvnc1A==} + engines: {node: '>=14.*'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@biomejs/cli-linux-x64@1.3.3: + resolution: {integrity: sha512-bqB05fwJnRZwRlcm/BS/s4qPickqiXZkiU/nOYvHApfsPeqgSHgv5HWoBYuSUjgqBbX3XZJArsC5dCcVW7vAJw==} + engines: {node: '>=14.*'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@biomejs/cli-win32-arm64@1.3.3: + resolution: {integrity: sha512-muFOjAv1ONMfaJDlo4Ds+Qb9lkdSLM2XaxOe3AJPejSq3Vi0aRr51ZnE02BofMnL2sVsOA9cO54wibsuTcopbw==} + engines: {node: '>=14.*'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@biomejs/cli-win32-x64@1.3.3: + resolution: {integrity: sha512-PMkMhS4smmmTMflxuZUx3REFSazEL9xsGscvZO1dKWI4ET23la+KxEM4TlSpjOyO66UerqSkuUlZecn0QhD63A==} + engines: {node: '>=14.*'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@csstools/normalize.css@12.0.0: resolution: {integrity: sha512-M0qqxAcwCsIVfpFQSlGN5XjXWu8l5JDZN+fPt1LeW5SZexQTgnaEvgXAY+CeygRw0EeppWHi12JxESWiWrB0Sg==} dev: true @@ -768,7 +842,7 @@ packages: resolution: {integrity: sha512-AouQ5I0a9TeRdHSN093WX5yz3ZlMbRyQ1xHn7K4OmXcbsRnS96Biy5Q2sTkqLwwTouAk/SNeWIjzrDZFQHp9Mw==} hasBin: true dependencies: - '@babel/core': 7.22.5 + '@babel/core': 7.23.2 globals: 11.12.0 yargs: 13.3.2 transitivePeerDependencies: @@ -778,9 +852,10 @@ packages: /@financial-times/polyfill-useragent-normaliser@1.10.2: resolution: {integrity: sha512-/9xHARfrKdWHt1ZXoT+/GpKx2N7uX88U1m6tF61AYSGaJFYaFlSoL1I4WbQOGH4eTQVb1z0a9LfwXaWblpRTBg==} engines: {node: '>=8'} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. dependencies: '@financial-times/useragent_parser': 1.6.3 - semver: 7.5.2 + semver: 7.5.4 dev: true /@financial-times/useragent_parser@1.6.3: @@ -810,11 +885,11 @@ packages: dependencies: '@jridgewell/set-array': 1.1.2 '@jridgewell/sourcemap-codec': 1.4.15 - '@jridgewell/trace-mapping': 0.3.18 + '@jridgewell/trace-mapping': 0.3.20 dev: true - /@jridgewell/resolve-uri@3.1.0: - resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} + /@jridgewell/resolve-uri@3.1.1: + resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} engines: {node: '>=6.0.0'} dev: true @@ -823,26 +898,22 @@ packages: engines: {node: '>=6.0.0'} dev: true - /@jridgewell/source-map@0.3.3: - resolution: {integrity: sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==} + /@jridgewell/source-map@0.3.5: + resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==} dependencies: '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.18 - dev: true - - /@jridgewell/sourcemap-codec@1.4.14: - resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} + '@jridgewell/trace-mapping': 0.3.20 dev: true /@jridgewell/sourcemap-codec@1.4.15: resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} dev: true - /@jridgewell/trace-mapping@0.3.18: - resolution: {integrity: sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==} + /@jridgewell/trace-mapping@0.3.20: + resolution: {integrity: sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==} dependencies: - '@jridgewell/resolve-uri': 3.1.0 - '@jridgewell/sourcemap-codec': 1.4.14 + '@jridgewell/resolve-uri': 3.1.1 + '@jridgewell/sourcemap-codec': 1.4.15 dev: true /@jsdoc/salty@0.2.5: @@ -852,30 +923,30 @@ packages: lodash: 4.17.21 dev: true - /@microsoft/api-extractor-model@7.27.3(@types/node@18.16.18): - resolution: {integrity: sha512-fSFvw7otYHduOkyshjTbapKKgwF8bgquVHvgF8VgeKtMYvqXkoaj7W6VcM7PNY7E2bbblhUgC4XNdqZLD4SJGw==} + /@microsoft/api-extractor-model@7.28.2(@types/node@18.18.8): + resolution: {integrity: sha512-vkojrM2fo3q4n4oPh4uUZdjJ2DxQ2+RnDQL/xhTWSRUNPF6P4QyrvY357HBxbnltKcYu+nNNolVqc6TIGQ73Ig==} dependencies: '@microsoft/tsdoc': 0.14.2 '@microsoft/tsdoc-config': 0.16.2 - '@rushstack/node-core-library': 3.59.4(@types/node@18.16.18) + '@rushstack/node-core-library': 3.61.0(@types/node@18.18.8) transitivePeerDependencies: - '@types/node' dev: true - /@microsoft/api-extractor@7.35.4(@types/node@18.16.18): - resolution: {integrity: sha512-E/DIIlgu1ZW+AD+Y0UuVe/30rO+Km0CRkDU1aOKQntwKtv/+FodtRAUvzU/vAxq5lQHSsy6jJErLiXR6G3fupA==} + /@microsoft/api-extractor@7.38.1(@types/node@18.18.8): + resolution: {integrity: sha512-Hxu/RrVpItQ4dzeMyfwlk4lGQFsXMoMS7bYU9YUrpW16hH04PXLRiTXJz77WhBiSGNtTuufz2xh6hWyXhC9JuQ==} hasBin: true dependencies: - '@microsoft/api-extractor-model': 7.27.3(@types/node@18.16.18) + '@microsoft/api-extractor-model': 7.28.2(@types/node@18.18.8) '@microsoft/tsdoc': 0.14.2 '@microsoft/tsdoc-config': 0.16.2 - '@rushstack/node-core-library': 3.59.4(@types/node@18.16.18) - '@rushstack/rig-package': 0.3.21 - '@rushstack/ts-command-line': 4.15.1 + '@rushstack/node-core-library': 3.61.0(@types/node@18.18.8) + '@rushstack/rig-package': 0.5.1 + '@rushstack/ts-command-line': 4.17.0 colors: 1.2.5 lodash: 4.17.21 - resolve: 1.22.2 - semver: 7.3.8 + resolve: 1.22.8 + semver: 7.5.4 source-map: 0.6.1 typescript: 5.0.4 transitivePeerDependencies: @@ -916,157 +987,29 @@ packages: fastq: 1.15.0 dev: true - /@octokit/auth-token@3.0.4: - resolution: {integrity: sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ==} - engines: {node: '>= 14'} - dev: true - - /@octokit/core@4.2.4: - resolution: {integrity: sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ==} - engines: {node: '>= 14'} - dependencies: - '@octokit/auth-token': 3.0.4 - '@octokit/graphql': 5.0.6 - '@octokit/request': 6.2.8 - '@octokit/request-error': 3.0.3 - '@octokit/types': 9.3.2 - before-after-hook: 2.2.3 - universal-user-agent: 6.0.0 - transitivePeerDependencies: - - encoding - dev: true - - /@octokit/endpoint@7.0.6: - resolution: {integrity: sha512-5L4fseVRUsDFGR00tMWD/Trdeeihn999rTMGRMC1G/Ldi1uWlWJzI98H4Iak5DB/RVvQuyMYKqSK/R6mbSOQyg==} - engines: {node: '>= 14'} - dependencies: - '@octokit/types': 9.3.2 - is-plain-object: 5.0.0 - universal-user-agent: 6.0.0 - dev: true - - /@octokit/graphql@5.0.6: - resolution: {integrity: sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw==} - engines: {node: '>= 14'} - dependencies: - '@octokit/request': 6.2.8 - '@octokit/types': 9.3.2 - universal-user-agent: 6.0.0 - transitivePeerDependencies: - - encoding - dev: true - - /@octokit/openapi-types@18.0.0: - resolution: {integrity: sha512-V8GImKs3TeQRxRtXFpG2wl19V7444NIOTDF24AWuIbmNaNYOQMWRbjcGDXV5B+0n887fgDcuMNOmlul+k+oJtw==} - dev: true - - /@octokit/plugin-paginate-rest@6.1.2(@octokit/core@4.2.4): - resolution: {integrity: sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ==} - engines: {node: '>= 14'} - peerDependencies: - '@octokit/core': '>=4' - dependencies: - '@octokit/core': 4.2.4 - '@octokit/tsconfig': 1.0.2 - '@octokit/types': 9.3.2 - dev: true - - /@octokit/plugin-request-log@1.0.4(@octokit/core@4.2.4): - resolution: {integrity: sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==} - peerDependencies: - '@octokit/core': '>=3' - dependencies: - '@octokit/core': 4.2.4 - dev: true - - /@octokit/plugin-rest-endpoint-methods@7.2.3(@octokit/core@4.2.4): - resolution: {integrity: sha512-I5Gml6kTAkzVlN7KCtjOM+Ruwe/rQppp0QU372K1GP7kNOYEKe8Xn5BW4sE62JAHdwpq95OQK/qGNyKQMUzVgA==} - engines: {node: '>= 14'} - peerDependencies: - '@octokit/core': '>=3' - dependencies: - '@octokit/core': 4.2.4 - '@octokit/types': 10.0.0 - dev: true - - /@octokit/request-error@3.0.3: - resolution: {integrity: sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==} - engines: {node: '>= 14'} - dependencies: - '@octokit/types': 9.3.2 - deprecation: 2.3.1 - once: 1.4.0 - dev: true - - /@octokit/request@6.2.8: - resolution: {integrity: sha512-ow4+pkVQ+6XVVsekSYBzJC0VTVvh/FCTUUgTsboGq+DTeWdyIFV8WSCdo0RIxk6wSkBTHqIK1mYuY7nOBXOchw==} - engines: {node: '>= 14'} - dependencies: - '@octokit/endpoint': 7.0.6 - '@octokit/request-error': 3.0.3 - '@octokit/types': 9.3.2 - is-plain-object: 5.0.0 - node-fetch: 2.6.11 - universal-user-agent: 6.0.0 - transitivePeerDependencies: - - encoding - dev: true - - /@octokit/rest@19.0.13: - resolution: {integrity: sha512-/EzVox5V9gYGdbAI+ovYj3nXQT1TtTHRT+0eZPcuC05UFSWO3mdO9UY1C0i2eLF9Un1ONJkAk+IEtYGAC+TahA==} - engines: {node: '>= 14'} - dependencies: - '@octokit/core': 4.2.4 - '@octokit/plugin-paginate-rest': 6.1.2(@octokit/core@4.2.4) - '@octokit/plugin-request-log': 1.0.4(@octokit/core@4.2.4) - '@octokit/plugin-rest-endpoint-methods': 7.2.3(@octokit/core@4.2.4) - transitivePeerDependencies: - - encoding - dev: true - - /@octokit/tsconfig@1.0.2: - resolution: {integrity: sha512-I0vDR0rdtP8p2lGMzvsJzbhdOWy405HcGovrspJ8RRibHnyRgggUSNO5AIox5LmqiwmatHKYsvj6VGFHkqS7lA==} - dev: true - - /@octokit/types@10.0.0: - resolution: {integrity: sha512-Vm8IddVmhCgU1fxC1eyinpwqzXPEYu0NrYzD3YZjlGjyftdLBTeqNblRC0jmJmgxbJIsQlyogVeGnrNaaMVzIg==} - dependencies: - '@octokit/openapi-types': 18.0.0 - dev: true - - /@octokit/types@9.3.2: - resolution: {integrity: sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA==} - dependencies: - '@octokit/openapi-types': 18.0.0 - dev: true - - /@oss/web-components-build-tools@1.2.8: - resolution: {integrity: sha1-yjo70ZtRHY5JyshD+ueYMVkZJW0=, tarball: https://gitlab.schukai.com/api/v4/projects/424/packages/npm/@oss/web-components-build-tools/-/@oss/web-components-build-tools-1.2.8.tgz} - dev: true - - /@peculiar/asn1-schema@2.3.6: - resolution: {integrity: sha512-izNRxPoaeJeg/AyH8hER6s+H7p4itk+03QCa4sbxI3lNdseQYCuxzgsuNK8bTXChtLTjpJz6NmXKA73qLa3rCA==} + /@peculiar/asn1-schema@2.3.8: + resolution: {integrity: sha512-ULB1XqHKx1WBU/tTFIA+uARuRoBVZ4pNdOA878RDrRbBfBGcSzi5HBkdScC6ZbHn8z7L8gmKCgPC1LHRrP46tA==} dependencies: asn1js: 3.0.5 - pvtsutils: 1.3.2 - tslib: 2.5.3 + pvtsutils: 1.3.5 + tslib: 2.6.2 dev: true /@peculiar/json-schema@1.1.12: resolution: {integrity: sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w==} engines: {node: '>=8.0.0'} dependencies: - tslib: 2.5.3 + tslib: 2.6.2 dev: true /@peculiar/webcrypto@1.4.3: resolution: {integrity: sha512-VtaY4spKTdN5LjJ04im/d/joXuvLbQdgy5Z4DXF4MFZhQ+MTrejbNMkfZBp1Bs3O5+bFqnJgyGdPuZQflvIa5A==} engines: {node: '>=10.12.0'} dependencies: - '@peculiar/asn1-schema': 2.3.6 + '@peculiar/asn1-schema': 2.3.8 '@peculiar/json-schema': 1.1.12 - pvtsutils: 1.3.2 - tslib: 2.5.3 + pvtsutils: 1.3.5 + tslib: 2.6.2 webcrypto-core: 1.7.7 dev: true @@ -1077,95 +1020,63 @@ packages: dev: true optional: true - /@rollup/pluginutils@5.0.2: - resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==} + /@puppeteer/browsers@1.8.0: + resolution: {integrity: sha512-TkRHIV6k2D8OlUe8RtG+5jgOF/H98Myx0M6AOafC8DdNVOFiBSFa5cpRDtpm8LXOa9sVwe0+e6Q3FC56X/DZfg==} + engines: {node: '>=16.3.0'} + hasBin: true + dependencies: + debug: 4.3.4(supports-color@8.1.1) + extract-zip: 2.0.1 + progress: 2.0.3 + proxy-agent: 6.3.1 + tar-fs: 3.0.4 + unbzip2-stream: 1.4.3 + yargs: 17.7.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@rollup/pluginutils@5.0.5: + resolution: {integrity: sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==} engines: {node: '>=14.0.0'} peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0 + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 peerDependenciesMeta: rollup: optional: true dependencies: - '@types/estree': 1.0.1 + '@types/estree': 1.0.4 estree-walker: 2.0.2 picomatch: 2.3.1 dev: true - /@rometools/cli-darwin-arm64@12.1.3: - resolution: {integrity: sha512-AmFTUDYjBuEGQp/Wwps+2cqUr+qhR7gyXAUnkL5psCuNCz3807TrUq/ecOoct5MIavGJTH6R4aaSL6+f+VlBEg==} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@rometools/cli-darwin-x64@12.1.3: - resolution: {integrity: sha512-k8MbWna8q4LRlb005N2X+JS1UQ+s3ZLBBvwk4fP8TBxlAJXUz17jLLu/Fi+7DTTEmMhM84TWj4FDKW+rNar28g==} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@rometools/cli-linux-arm64@12.1.3: - resolution: {integrity: sha512-X/uLhJ2/FNA3nu5TiyeNPqiD3OZoFfNfRvw6a3ut0jEREPvEn72NI7WPijH/gxSz55znfQ7UQ6iM4DZumUknJg==} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@rometools/cli-linux-x64@12.1.3: - resolution: {integrity: sha512-csP17q1eWiUXx9z6Jr/JJPibkplyKIwiWPYNzvPCGE8pHlKhwZj3YHRuu7Dm/4EOqx0XFIuqqWZUYm9bkIC8xg==} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@rometools/cli-win32-arm64@12.1.3: - resolution: {integrity: sha512-RymHWeod57EBOJY4P636CgUwYA6BQdkQjh56XKk4pLEHO6X1bFyMet2XL7KlHw5qOTalzuzf5jJqUs+vf3jdXQ==} - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@rometools/cli-win32-x64@12.1.3: - resolution: {integrity: sha512-yHSKYidqJMV9nADqg78GYA+cZ0hS1twANAjiFibQdXj9aGzD+s/IzIFEIi/U/OBLvWYg/SCw0QVozi2vTlKFDQ==} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@rushstack/node-core-library@3.59.4(@types/node@18.16.18): - resolution: {integrity: sha512-YAKJDC6Mz/KA1D7bvB88WaRX3knt/ZuLzkRu5G9QADGSjLtvTWzCNCytRF2PCSaaHOZaZsWul4F1KQdgFgUDqA==} + /@rushstack/node-core-library@3.61.0(@types/node@18.18.8): + resolution: {integrity: sha512-tdOjdErme+/YOu4gPed3sFS72GhtWCgNV9oDsHDnoLY5oDfwjKUc9Z+JOZZ37uAxcm/OCahDHfuu2ugqrfWAVQ==} peerDependencies: '@types/node': '*' peerDependenciesMeta: '@types/node': optional: true dependencies: - '@types/node': 18.16.18 + '@types/node': 18.18.8 colors: 1.2.5 fs-extra: 7.0.1 import-lazy: 4.0.0 jju: 1.4.0 - resolve: 1.22.2 - semver: 7.3.8 + resolve: 1.22.8 + semver: 7.5.4 z-schema: 5.0.5 dev: true - /@rushstack/rig-package@0.3.21: - resolution: {integrity: sha512-6KPBuZYP/b9U0Qwy1J4vjYtXvLavdmVT7mMelErfqqZ3P/ywoxlFITGr9ZbqD1zmfIVrIfC2jrM6gfm7OHPRhQ==} + /@rushstack/rig-package@0.5.1: + resolution: {integrity: sha512-pXRYSe29TjRw7rqxD4WS3HN/sRSbfr+tJs4a9uuaSIBAITbUggygdhuG0VrO0EO+QqH91GhYMN4S6KRtOEmGVA==} dependencies: - resolve: 1.22.2 + resolve: 1.22.8 strip-json-comments: 3.1.1 dev: true - /@rushstack/ts-command-line@4.15.1: - resolution: {integrity: sha512-EL4jxZe5fhb1uVL/P/wQO+Z8Rc8FMiWJ1G7VgnPDvdIt5GVjRfK7vwzder1CZQiX3x0PY6uxENYLNGTFd1InRQ==} + /@rushstack/ts-command-line@4.17.0: + resolution: {integrity: sha512-1S0sXuEpZlzKTfvUqNs7Rg4leVkeLJc4Dn9cm+pSIn35a0Ztp5GxPN2gabD2G4RrQoQcJLLyVu+twzrJl1C0eA==} dependencies: '@types/argparse': 1.0.38 argparse: 1.0.10 @@ -1173,52 +1084,46 @@ packages: string-argv: 0.3.2 dev: true - /@sentry-internal/tracing@7.56.0: - resolution: {integrity: sha512-OKI4Pz/O13gng8hT9rNc+gRV3+P7nnk1HnHlV8fgaQydS6DsRxoDL1sHa42tZGbh7K9jqNAP3TC6VjBOsr2tXA==} + /@sentry-internal/tracing@7.77.0: + resolution: {integrity: sha512-8HRF1rdqWwtINqGEdx8Iqs9UOP/n8E0vXUu3Nmbqj4p5sQPA7vvCfq+4Y4rTqZFc7sNdFpDsRION5iQEh8zfZw==} engines: {node: '>=8'} dependencies: - '@sentry/core': 7.56.0 - '@sentry/types': 7.56.0 - '@sentry/utils': 7.56.0 - tslib: 1.14.1 + '@sentry/core': 7.77.0 + '@sentry/types': 7.77.0 + '@sentry/utils': 7.77.0 dev: true - /@sentry/core@7.56.0: - resolution: {integrity: sha512-Nuyyfh09Yz27kPo74fXHlrdmZeK6zrlJVtxQ6LkwuoaTBcNcesNXVaOtr6gjvUGUmsfriVPP3Jero5LXufV7GQ==} + /@sentry/core@7.77.0: + resolution: {integrity: sha512-Tj8oTYFZ/ZD+xW8IGIsU6gcFXD/gfE+FUxUaeSosd9KHwBQNOLhZSsYo/tTVf/rnQI/dQnsd4onPZLiL+27aTg==} engines: {node: '>=8'} dependencies: - '@sentry/types': 7.56.0 - '@sentry/utils': 7.56.0 - tslib: 1.14.1 + '@sentry/types': 7.77.0 + '@sentry/utils': 7.77.0 dev: true - /@sentry/node@7.56.0: - resolution: {integrity: sha512-QXbWy/ypRxfFd8iP6zLvHInYZyjGKPrkVNYt43mhKAZHm764NxX/29vDfj1FztgG9Z6lVLIG2eyqTvLruYmsWw==} + /@sentry/node@7.77.0: + resolution: {integrity: sha512-Ob5tgaJOj0OYMwnocc6G/CDLWC7hXfVvKX/ofkF98+BbN/tQa5poL+OwgFn9BA8ud8xKzyGPxGU6LdZ8Oh3z/g==} engines: {node: '>=8'} dependencies: - '@sentry-internal/tracing': 7.56.0 - '@sentry/core': 7.56.0 - '@sentry/types': 7.56.0 - '@sentry/utils': 7.56.0 - cookie: 0.4.2 + '@sentry-internal/tracing': 7.77.0 + '@sentry/core': 7.77.0 + '@sentry/types': 7.77.0 + '@sentry/utils': 7.77.0 https-proxy-agent: 5.0.1 - lru_map: 0.3.3 - tslib: 1.14.1 transitivePeerDependencies: - supports-color dev: true - /@sentry/types@7.56.0: - resolution: {integrity: sha512-5WjhVOQm75ItOytOx2jTx+5yw8/qJ316+g1Di8dS9+kgIi1zniqdMcX00C2yYe3FMUgFB49PegCUYulm9Evapw==} + /@sentry/types@7.77.0: + resolution: {integrity: sha512-nfb00XRJVi0QpDHg+JkqrmEBHsqBnxJu191Ded+Cs1OJ5oPXEW6F59LVcBScGvMqe+WEk1a73eH8XezwfgrTsA==} engines: {node: '>=8'} dev: true - /@sentry/utils@7.56.0: - resolution: {integrity: sha512-wgeX7bufxc//TjjSIE+gCMm8hVId7Jzvc+f441bYrWnNZBuzPIDW2BummCcPrKzSYe5GeYZDTZGV8YZGMLGBjw==} + /@sentry/utils@7.77.0: + resolution: {integrity: sha512-NmM2kDOqVchrey3N5WSzdQoCsyDkQkiRxExPaNI2oKQ/jMWHs9yt0tSy7otPBcXs0AP59ihl75Bvm1tDRcsp5g==} engines: {node: '>=8'} dependencies: - '@sentry/types': 7.56.0 - tslib: 1.14.1 + '@sentry/types': 7.77.0 dev: true /@sinonjs/commons@2.0.0: @@ -1233,8 +1138,8 @@ packages: type-detect: 4.0.8 dev: true - /@sinonjs/fake-timers@10.1.0: - resolution: {integrity: sha512-w1qd368vtrwttm1PRJWPW1QHlbmHrVDGs1eBH/jZvRPUFS4MNXV9Q33EQdjOdeAxZ7O8+3wM7zxztm2nfUSyKw==} + /@sinonjs/fake-timers@10.3.0: + resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} dependencies: '@sinonjs/commons': 3.0.0 dev: true @@ -1256,6 +1161,10 @@ packages: engines: {node: '>= 10'} dev: true + /@tootallnate/quickjs-emscripten@0.23.0: + resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} + dev: true + /@trysound/sax@0.2.0: resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} engines: {node: '>=10.13.0'} @@ -1264,7 +1173,7 @@ packages: /@ts-morph/common@0.18.1: resolution: {integrity: sha512-RVE+zSRICWRsfrkAw5qCAK+4ZH9kwEFv5h0+/YeHTLieWP7F4wWq4JsKFuNWG+fYh/KF+8rAtgdj5zb2mm+DVA==} dependencies: - fast-glob: 3.2.12 + fast-glob: 3.3.1 minimatch: 5.1.6 mkdirp: 1.0.4 path-browserify: 1.0.1 @@ -1274,43 +1183,53 @@ packages: resolution: {integrity: sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==} dev: true - /@types/estree@1.0.1: - resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==} + /@types/estree@1.0.4: + resolution: {integrity: sha512-2JwWnHK9H+wUZNorf2Zr6ves96WHoWDJIftkcxPKsS7Djta6Zu519LarhRNljPXkpsZR2ZMwNCPeW7omW07BJw==} dev: true - /@types/istanbul-lib-coverage@2.0.4: - resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} + /@types/istanbul-lib-coverage@2.0.5: + resolution: {integrity: sha512-zONci81DZYCZjiLe0r6equvZut0b+dBRPBN5kBDjsONnutYNtJMoWQ9uR2RkL1gLG9NMTzvf+29e5RFfPbeKhQ==} dev: true - /@types/jasmine@3.10.9: - resolution: {integrity: sha512-U6P2ecGNmr0MV50Mb03fglwrApdbcAvx/wtzIAZyp3ZZ+Ghn1A+d53nXglhlymwPtdz0Sj4XSgkQfAQ+bhW8gA==} + /@types/jasmine@3.10.15: + resolution: {integrity: sha512-NdWern4OhbU7QcdlpPnvqy7LqpEjiAQ47tHDRdUKyGcwnhdmTsGniSJCC2B9ODiYiRnP53v6HOzu8B5/bqOtUw==} dev: true - /@types/linkify-it@3.0.2: - resolution: {integrity: sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==} + /@types/linkify-it@3.0.4: + resolution: {integrity: sha512-hPpIeeHb/2UuCw06kSNAOVWgehBLXEo0/fUs0mw3W2qhqX89PI2yvok83MnuctYGCPrabGIoi0fFso4DQ+sNUQ==} dev: true /@types/markdown-it@12.2.3: resolution: {integrity: sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==} dependencies: - '@types/linkify-it': 3.0.2 - '@types/mdurl': 1.0.2 + '@types/linkify-it': 3.0.4 + '@types/mdurl': 1.0.4 + dev: true + + /@types/mdurl@1.0.4: + resolution: {integrity: sha512-ARVxjAEX5TARFRzpDRVC6cEk0hUIXCCwaMhz8y7S1/PxU6zZS1UMjyobz7q4w/D/R552r4++EhwmXK1N2rAy0A==} dev: true - /@types/mdurl@1.0.2: - resolution: {integrity: sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==} + /@types/node@18.18.8: + resolution: {integrity: sha512-OLGBaaK5V3VRBS1bAkMVP2/W9B+H8meUfl866OrMNQqt7wDgdpWPp5o6gmIc9pB+lIQHSq4ZL8ypeH1vPxcPaQ==} + dependencies: + undici-types: 5.26.5 dev: true - /@types/node@18.16.18: - resolution: {integrity: sha512-/aNaQZD0+iSBAGnvvN2Cx92HqE5sZCPZtx2TsK+4nvV23fFe09jVDvpArXr2j9DnYlzuU9WuoykDDc6wqvpNcw==} + /@types/yauzl@2.10.2: + resolution: {integrity: sha512-Km7XAtUIduROw7QPgvcft0lIupeG8a8rdKL8RiSyKvlE7dYY31fEn41HVuQsRFDuROA8tA4K2UVL+WdfFmErBA==} + requiresBuild: true + dependencies: + '@types/node': 18.18.8 dev: true + optional: true /@wesbos/code-icons@1.2.4: resolution: {integrity: sha512-ZiU0xf7epnCRrLDQIPnFstzoNWDvcUTtKoDU3VhpjsaGRzVClSmsi39c4kHxIOdfxvg4zwdW+goH96xr/vMTQQ==} dependencies: - '@types/node': 18.16.18 - vite: 4.3.9(@types/node@18.16.18) - vite-plugin-dts: 1.7.3(@types/node@18.16.18)(vite@4.3.9) + '@types/node': 18.18.8 + vite: 4.3.9(@types/node@18.18.8) + vite-plugin-dts: 1.7.3(@types/node@18.18.8)(vite@4.3.9) vscode-icons-js: 11.6.1 transitivePeerDependencies: - less @@ -1322,6 +1241,12 @@ packages: - terser dev: true + /abab@1.0.4: + resolution: {integrity: sha512-I+Wi+qiE2kUXyrRhNsWv6XsjUTBJjSoVSctKNBfLG5zG/Xe7Rjbxf13+vqYHNTwHaFU+FtSlVxOCTiMEVtPv0A==} + requiresBuild: true + dev: true + optional: true + /abab@2.0.6: resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} dev: true @@ -1333,8 +1258,24 @@ packages: event-target-shim: 5.0.1 dev: true - /acorn@8.9.0: - resolution: {integrity: sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==} + /acorn-globals@1.0.9: + resolution: {integrity: sha512-j3/4pkfih8W4NK22gxVSXcEonTpAHOHh0hu5BoZrKcOsW/4oBPxTi4Yk3SAj+FhC1f3+bRTkXdm4019gw1vg9g==} + requiresBuild: true + dependencies: + acorn: 2.7.0 + dev: true + optional: true + + /acorn@2.7.0: + resolution: {integrity: sha512-pXK8ez/pVjqFdAgBkF1YPVRacuLQ9EXBKaKWaeh58WNfMkCmZhOZzu+NtKSPD5PHmCCHheQ5cD29qM1K4QTxIg==} + engines: {node: '>=0.4.0'} + hasBin: true + requiresBuild: true + dev: true + optional: true + + /acorn@8.11.2: + resolution: {integrity: sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==} engines: {node: '>=0.4.0'} hasBin: true dev: true @@ -1348,6 +1289,15 @@ packages: - supports-color dev: true + /agent-base@7.1.0: + resolution: {integrity: sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==} + engines: {node: '>= 14'} + dependencies: + debug: 4.3.4(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + dev: true + /ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} dependencies: @@ -1424,19 +1374,41 @@ packages: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} dev: true + /asn1@0.2.6: + resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} + requiresBuild: true + dependencies: + safer-buffer: 2.1.2 + dev: true + optional: true + /asn1js@3.0.5: resolution: {integrity: sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==} engines: {node: '>=12.0.0'} dependencies: - pvtsutils: 1.3.2 + pvtsutils: 1.3.5 pvutils: 1.1.3 - tslib: 2.5.3 + tslib: 2.6.2 dev: true + /assert-plus@1.0.0: + resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} + engines: {node: '>=0.8'} + requiresBuild: true + dev: true + optional: true + /assertion-error@1.1.0: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} dev: true + /ast-types@0.13.4: + resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} + engines: {node: '>=4'} + dependencies: + tslib: 2.6.2 + dev: true + /asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} dev: true @@ -1454,8 +1426,8 @@ packages: postcss: ^8.1.0 dependencies: browserslist: 4.21.9 - caniuse-lite: 1.0.30001504 - fraction.js: 4.2.0 + caniuse-lite: 1.0.30001559 + fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.0.0 postcss: 8.4.24 @@ -1467,62 +1439,156 @@ packages: engines: {node: '>= 0.4'} dev: true - /axios@1.4.0(debug@4.3.4): - resolution: {integrity: sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==} - dependencies: - follow-redirects: 1.15.2(debug@4.3.4) - form-data: 4.0.0 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug + /aws-sign2@0.7.0: + resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} + requiresBuild: true dev: true + optional: true - /balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + /aws4@1.12.0: + resolution: {integrity: sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==} + requiresBuild: true dev: true + optional: true - /before-after-hook@2.2.3: - resolution: {integrity: sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==} + /b4a@1.6.4: + resolution: {integrity: sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==} dev: true - /binary-extensions@2.2.0: - resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} - engines: {node: '>=8'} + /babel-code-frame@6.26.0: + resolution: {integrity: sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==} + dependencies: + chalk: 1.1.3 + esutils: 2.0.3 + js-tokens: 3.0.2 dev: true - /bluebird@3.7.2: - resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + /babel-generator@6.11.4: + resolution: {integrity: sha512-JFBWXdE89s4V3E8kZroEEsnQF2A4/+55IzciGjnAATXj7HTMSum3SrW7QRYGSDLWTTQF+hhD3BmC2UFGgtM0Yw==} + dependencies: + babel-messages: 6.23.0 + babel-runtime: 6.26.0 + babel-types: 6.26.0 + detect-indent: 3.0.1 + lodash: 4.17.21 + source-map: 0.5.7 dev: true - /boolbase@1.0.0: - resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + /babel-generator@6.26.1: + resolution: {integrity: sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==} + dependencies: + babel-messages: 6.23.0 + babel-runtime: 6.26.0 + babel-types: 6.26.0 + detect-indent: 4.0.0 + jsesc: 1.3.0 + lodash: 4.17.21 + source-map: 0.5.7 + trim-right: 1.0.1 dev: true - /boolean@3.2.0: - resolution: {integrity: sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==} + /babel-messages@6.23.0: + resolution: {integrity: sha512-Bl3ZiA+LjqaMtNYopA9TYE9HP1tQ+E5dLxE0XrAzcIJeK2UqF0/EaqXwBn9esd4UmTfEab+P+UYQ1GnioFIb/w==} + dependencies: + babel-runtime: 6.26.0 dev: true - /brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + /babel-runtime@6.26.0: + resolution: {integrity: sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==} dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 + core-js: 2.6.12 + regenerator-runtime: 0.11.1 dev: true - /brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + /babel-traverse@6.26.0: + resolution: {integrity: sha512-iSxeXx7apsjCHe9c7n8VtRXGzI2Bk1rBSOJgCCjfyXb6v1aCqE1KSEpq/8SXuVN8Ka/Rh1WDTF0MDzkvTA4MIA==} dependencies: - balanced-match: 1.0.2 + babel-code-frame: 6.26.0 + babel-messages: 6.23.0 + babel-runtime: 6.26.0 + babel-types: 6.26.0 + babylon: 6.18.0 + debug: 2.6.9 + globals: 9.18.0 + invariant: 2.2.4 + lodash: 4.17.21 + transitivePeerDependencies: + - supports-color dev: true - /braces@3.0.2: - resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} - engines: {node: '>=8'} + /babel-types@6.26.0: + resolution: {integrity: sha512-zhe3V/26rCWsEZK8kZN+HaQj5yQ1CilTObixFzKW1UWjqG7618Twz6YEsCnjfg5gBcJh02DrpCkS9h98ZqDY+g==} dependencies: - fill-range: 7.0.1 + babel-runtime: 6.26.0 + esutils: 2.0.3 + lodash: 4.17.21 + to-fast-properties: 1.0.3 dev: true - /browser-stdout@1.3.1: + /babylon@6.18.0: + resolution: {integrity: sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==} + hasBin: true + dev: true + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true + + /base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: true + + /basic-ftp@5.0.3: + resolution: {integrity: sha512-QHX8HLlncOLpy54mh+k/sWIFd0ThmRqwe9ZjELybGZK+tZ8rUb9VO0saKJUROTbE+KhzDUT7xziGpGrW8Kmd+g==} + engines: {node: '>=10.0.0'} + dev: true + + /bcrypt-pbkdf@1.0.2: + resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} + requiresBuild: true + dependencies: + tweetnacl: 0.14.5 + dev: true + optional: true + + /binary-extensions@2.2.0: + resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + engines: {node: '>=8'} + dev: true + + /bluebird@3.7.2: + resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + dev: true + + /boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + dev: true + + /boolean@3.2.0: + resolution: {integrity: sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==} + dev: true + + /brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + dependencies: + balanced-match: 1.0.2 + dev: true + + /braces@3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + dev: true + + /browser-stdout@1.3.1: resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} dev: true @@ -1531,10 +1597,10 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001504 - electron-to-chromium: 1.4.433 - node-releases: 2.0.12 - update-browserslist-db: 1.0.11(browserslist@4.21.9) + caniuse-lite: 1.0.30001559 + electron-to-chromium: 1.4.572 + node-releases: 2.0.13 + update-browserslist-db: 1.0.13(browserslist@4.21.9) dev: true /btoa@1.2.1: @@ -1543,10 +1609,21 @@ packages: hasBin: true dev: true + /buffer-crc32@0.2.13: + resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + dev: true + /buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} dev: true + /buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: true + /c8@8.0.0: resolution: {integrity: sha512-XHA5vSfCLglAc0Xt8eLBZMv19lgiBSjnb1FLAQgnwkuhJYEonpilhEB4Ea3jPAbm0FhD6VVJrc0z73jPe7JyGQ==} engines: {node: '>=12'} @@ -1557,27 +1634,33 @@ packages: find-up: 5.0.0 foreground-child: 2.0.0 istanbul-lib-coverage: 3.2.0 - istanbul-lib-report: 3.0.0 - istanbul-reports: 3.1.5 + istanbul-lib-report: 3.0.1 + istanbul-reports: 3.1.6 rimraf: 3.0.2 test-exclude: 6.0.0 - v8-to-istanbul: 9.1.0 + v8-to-istanbul: 9.1.3 yargs: 16.2.0 yargs-parser: 20.2.9 dev: true - /call-bind@1.0.2: - resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} + /call-bind@1.0.5: + resolution: {integrity: sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==} dependencies: - function-bind: 1.1.1 - get-intrinsic: 1.2.1 + function-bind: 1.1.2 + get-intrinsic: 1.2.2 + set-function-length: 1.1.1 + dev: true + + /callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} dev: true /camel-case@4.1.2: resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==} dependencies: pascal-case: 3.1.2 - tslib: 2.5.3 + tslib: 2.6.2 dev: true /camelcase-css@2.0.1: @@ -1599,15 +1682,21 @@ packages: resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} dependencies: browserslist: 4.21.9 - caniuse-lite: 1.0.30001504 + caniuse-lite: 1.0.30001559 lodash.memoize: 4.1.2 lodash.uniq: 4.5.0 dev: true - /caniuse-lite@1.0.30001504: - resolution: {integrity: sha512-5uo7eoOp2mKbWyfMXnGO9rJWOGU8duvzEiYITW+wivukL7yHH4gX9yuRaobu6El4jPxo6jKZfG+N6fB621GD/Q==} + /caniuse-lite@1.0.30001559: + resolution: {integrity: sha512-cPiMKZgqgkg5LY3/ntGeLFUpi6tzddBNS58A4tnTgQw1zON7u2sZMU7SzOeVH4tj20++9ggL+V6FDOFMTaFFYA==} dev: true + /caseless@0.12.0: + resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} + requiresBuild: true + dev: true + optional: true + /catharsis@0.9.0: resolution: {integrity: sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==} engines: {node: '>= 10'} @@ -1631,10 +1720,10 @@ packages: engines: {node: '>=4'} dependencies: assertion-error: 1.1.0 - check-error: 1.0.2 + check-error: 1.0.3 deep-eql: 4.1.3 - get-func-name: 2.0.0 - loupe: 2.3.6 + get-func-name: 2.0.2 + loupe: 2.3.7 pathval: 1.1.1 type-detect: 4.0.8 dev: true @@ -1667,8 +1756,57 @@ packages: supports-color: 7.2.0 dev: true - /check-error@1.0.2: - resolution: {integrity: sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==} + /check-error@1.0.3: + resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + dependencies: + get-func-name: 2.0.2 + dev: true + + /cheerio@0.20.0: + resolution: {integrity: sha512-e5jCTzJc28MWkrLLjB1mu3ks7rDQJLC5y/JMdQkOAEX/dmJk62rC6Xae1yvOO4xyCxLpzcth3jIZ7nypmjQ/0w==} + engines: {node: '>= 0.6'} + dependencies: + css-select: 1.2.0 + dom-serializer: 0.1.1 + entities: 1.1.2 + htmlparser2: 3.8.3 + lodash: 4.17.21 + optionalDependencies: + jsdom: 7.2.2 + dev: true + + /cheerio@0.22.0: + resolution: {integrity: sha512-8/MzidM6G/TgRelkzDG13y3Y9LxBjCb+8yOEZ9+wwq5gVF2w2pV0wmHvjfT0RvuxGyR7UEuK36r+yYMbT4uKgA==} + engines: {node: '>= 0.6'} + dependencies: + css-select: 1.2.0 + dom-serializer: 0.1.1 + entities: 1.1.2 + htmlparser2: 3.10.1 + lodash.assignin: 4.2.0 + lodash.bind: 4.2.1 + lodash.defaults: 4.2.0 + lodash.filter: 4.6.0 + lodash.flatten: 4.4.0 + lodash.foreach: 4.5.0 + lodash.map: 4.6.0 + lodash.merge: 4.6.2 + lodash.pick: 4.4.0 + lodash.reduce: 4.6.0 + lodash.reject: 4.6.0 + lodash.some: 4.6.0 + dev: true + + /cheerio@1.0.0-rc.2: + resolution: {integrity: sha512-9LDHQy1jHc/eXMzPN6/oah9Qba4CjdKECC7YYEE/2zge/tsGwt19NQp5NFdfd5Lx6TZlyC5SXNQkG41P9r6XDg==} + engines: {node: '>= 0.6'} + dependencies: + css-select: 1.2.0 + dom-serializer: 0.1.1 + entities: 1.1.2 + htmlparser2: 3.10.1 + lodash: 4.17.21 + parse5: 3.0.3 dev: true /chokidar@3.5.3: @@ -1683,7 +1821,17 @@ packages: normalize-path: 3.0.0 readdirp: 3.6.0 optionalDependencies: - fsevents: 2.3.2 + fsevents: 2.3.3 + dev: true + + /chromium-bidi@0.4.32(devtools-protocol@0.0.1191157): + resolution: {integrity: sha512-RJnw0PW3sNdx1WclINVfVVx8JUH+tWTHZNpnEzlcM+Qgvf40dUH34U7gJq+cc/0LE+rbPxeT6ldqWrCbUf4jeg==} + peerDependencies: + devtools-protocol: '*' + dependencies: + devtools-protocol: 0.0.1191157 + mitt: 3.0.1 + urlpattern-polyfill: 9.0.0 dev: true /clean-css@5.3.2: @@ -1732,6 +1880,15 @@ packages: wrap-ansi: 7.0.0 dev: true + /cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: true + /code-block-writer@11.0.3: resolution: {integrity: sha512-NiujjUFB4SwScJq2bwbYUtXbZhBSlY6vYzm++3Q6oC+U+injTqfPYFK8wS9COOmb2lueqp0ZRB4nK1VYeHgNyw==} dev: true @@ -1749,6 +1906,14 @@ packages: color-name: 1.1.4 dev: true + /color-logger@0.0.3: + resolution: {integrity: sha512-s4oriek7VTdSmDbS5chJhNui3uUzlk/mU39V4HnOUv0KphRXpIj73lq4wY5f8l/x+WtHUhiV+FCzsrNO1w6REA==} + dev: true + + /color-logger@0.0.6: + resolution: {integrity: sha512-0iBj3eHRYnor8EJi3oQ1kixbr7B2Sbw1InxjsYZxS+q2H+Ii69m3ARYSJeYIqmf/QRtFhWnR1v97wp8N7ABubw==} + dev: true + /color-name@1.1.3: resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} dev: true @@ -1801,35 +1966,65 @@ packages: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} dev: true - /convert-source-map@1.9.0: - resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + /convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} dev: true - /cookie@0.4.2: - resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==} - engines: {node: '>= 0.6'} + /core-js@2.6.12: + resolution: {integrity: sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==} + deprecated: core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js. + requiresBuild: true + dev: true + + /core-util-is@1.0.2: + resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} + requiresBuild: true dev: true + optional: true /core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} dev: true + /cosmiconfig@8.3.6: + resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + import-fresh: 3.3.0 + js-yaml: 4.1.0 + parse-json: 5.2.0 + path-type: 4.0.0 + dev: true + /create-polyfill-service-url@2.2.6: resolution: {integrity: sha512-uhipnEEH6SkC176Za0Rt3D7pTV60nTiS2Vn4wZBIQacUtfPBxuTG4dox/jy2yXDCEiFX62gYhehvCIYPudjzFA==} hasBin: true dependencies: - '@babel/core': 7.22.5 + '@babel/core': 7.23.2 '@financial-times/js-features-analyser': 0.0.4 browserslist: 4.21.9 execa: 4.1.0 polyfill-library: 3.111.0 - semver: 7.5.2 - snyk: 1.1183.0 + semver: 7.5.4 + snyk: 1.1238.0 yargs: 15.4.1 transitivePeerDependencies: - supports-color dev: true + /cross-fetch@4.0.0: + resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==} + dependencies: + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + dev: true + /cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} @@ -1843,8 +2038,8 @@ packages: resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==} dev: true - /css-declaration-sorter@6.4.0(postcss@8.4.24): - resolution: {integrity: sha512-jDfsatwWMWN0MODAFuHszfjphEXfNw9JUAhmY4pLu3TyTU+ohUpsbVtbU+1MZn4a47D9kqh03i4eyOm+74+zew==} + /css-declaration-sorter@6.4.1(postcss@8.4.24): + resolution: {integrity: sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==} engines: {node: ^10 || ^12 || >=14} peerDependencies: postcss: ^8.0.9 @@ -1852,6 +2047,15 @@ packages: postcss: 8.4.24 dev: true + /css-select@1.2.0: + resolution: {integrity: sha512-dUQOBoqdR7QwV90WysXPLXG5LO7nhYBgiWVfxF80DKPF8zx1t/pUd2FYy73emg3zrjtM6dzmYgbHKfV2rxiHQA==} + dependencies: + boolbase: 1.0.0 + css-what: 2.1.3 + domutils: 1.5.1 + nth-check: 1.0.2 + dev: true + /css-select@5.1.0: resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} dependencies: @@ -1878,6 +2082,10 @@ packages: source-map-js: 1.0.2 dev: true + /css-what@2.1.3: + resolution: {integrity: sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==} + dev: true + /css-what@6.1.0: resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} engines: {node: '>= 6'} @@ -1895,7 +2103,7 @@ packages: peerDependencies: postcss: ^8.2.15 dependencies: - css-declaration-sorter: 6.4.0(postcss@8.4.24) + css-declaration-sorter: 6.4.1(postcss@8.4.24) cssnano-utils: 4.0.0(postcss@8.4.24) postcss: 8.4.24 postcss-calc: 9.0.1(postcss@8.4.24) @@ -1954,6 +2162,20 @@ packages: css-tree: 2.2.1 dev: true + /cssom@0.3.8: + resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==} + requiresBuild: true + dev: true + optional: true + + /cssstyle@0.2.37: + resolution: {integrity: sha512-FUpKc+1FNBsHUr9IsfSGCovr8VuGOiiuzlgCyppKBjJi2jYTOFLN3oiiNRMIvYqbFzF38mqKj4BgcevzU5/kIA==} + requiresBuild: true + dependencies: + cssom: 0.3.8 + dev: true + optional: true + /cssstyle@3.0.0: resolution: {integrity: sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==} engines: {node: '>=14'} @@ -1961,11 +2183,25 @@ packages: rrweb-cssom: 0.6.0 dev: true + /dashdash@1.14.1: + resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} + engines: {node: '>=0.10'} + requiresBuild: true + dependencies: + assert-plus: 1.0.0 + dev: true + optional: true + /data-uri-to-buffer@4.0.1: resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} engines: {node: '>= 12'} dev: true + /data-uri-to-buffer@6.0.1: + resolution: {integrity: sha512-MZd3VlchQkp8rdend6vrx7MmVDJzSNTBvghvKjirLkD+WTChA3KUf0jkE68Q4UyctNqI11zZO9/x2Yx+ub5Cvg==} + engines: {node: '>= 14'} + dev: true + /data-urls@4.0.0: resolution: {integrity: sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==} engines: {node: '>=14'} @@ -1975,6 +2211,17 @@ packages: whatwg-url: 12.0.1 dev: true + /debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.0.0 + dev: true + /debug@4.3.4(supports-color@8.1.1): resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} @@ -2009,27 +2256,69 @@ packages: type-detect: 4.0.8 dev: true - /define-properties@1.2.0: - resolution: {integrity: sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==} + /deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + requiresBuild: true + dev: true + optional: true + + /define-data-property@1.1.1: + resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==} engines: {node: '>= 0.4'} dependencies: - has-property-descriptors: 1.0.0 + get-intrinsic: 1.2.2 + gopd: 1.0.1 + has-property-descriptors: 1.0.1 + dev: true + + /define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.1 + has-property-descriptors: 1.0.1 object-keys: 1.1.1 dev: true + /degenerator@5.0.1: + resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==} + engines: {node: '>= 14'} + dependencies: + ast-types: 0.13.4 + escodegen: 2.1.0 + esprima: 4.0.1 + dev: true + /delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} dev: true - /deprecation@2.3.1: - resolution: {integrity: sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==} + /detect-indent@3.0.1: + resolution: {integrity: sha512-xo3WP66SNbr1Eim85s/qyH0ZL8PQUwp86HWm0S1l8WnJ/zjT6T3w1nwNA0yOZeuvOemupEYvpvF6BIdYRuERJQ==} + engines: {node: '>=0.10.0'} + hasBin: true + dependencies: + get-stdin: 4.0.1 + minimist: 1.2.8 + repeating: 1.1.3 + dev: true + + /detect-indent@4.0.0: + resolution: {integrity: sha512-BDKtmHlOzwI7iRuEkhzsnPoi5ypEhWAJB5RvHWe1kMr06js3uK5B3734i3ui5Yd+wOJV1cpE4JnivPD283GU/A==} + engines: {node: '>=0.10.0'} + dependencies: + repeating: 2.0.1 dev: true /detect-node@2.1.0: resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} dev: true + /devtools-protocol@0.0.1191157: + resolution: {integrity: sha512-Fu2mUhX7zkzLHMJZk5wQTiHdl1eJrhK0GypUoSzogUt51MmYEv/46pCz4PtGGFlr0f2ZyYDzzx5CPtbEkuvcTA==} + dev: true + /diff@5.0.0: resolution: {integrity: sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==} engines: {node: '>=0.3.1'} @@ -2040,6 +2329,20 @@ packages: engines: {node: '>=0.3.1'} dev: true + /doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /dom-serializer@0.1.1: + resolution: {integrity: sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==} + dependencies: + domelementtype: 1.3.1 + entities: 1.1.2 + dev: true + /dom-serializer@2.0.0: resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} dependencies: @@ -2048,6 +2351,10 @@ packages: entities: 4.5.0 dev: true + /domelementtype@1.3.1: + resolution: {integrity: sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==} + dev: true + /domelementtype@2.3.0: resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} dev: true @@ -2059,6 +2366,18 @@ packages: webidl-conversions: 7.0.0 dev: true + /domhandler@2.3.0: + resolution: {integrity: sha512-q9bUwjfp7Eif8jWxxxPSykdRZAb6GkguBGSgvvCrhI9wB71W2K/Kvv4E61CF/mcCfnVJDeDWx/Vb/uAqbDj6UQ==} + dependencies: + domelementtype: 1.3.1 + dev: true + + /domhandler@2.4.2: + resolution: {integrity: sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==} + dependencies: + domelementtype: 1.3.1 + dev: true + /domhandler@5.0.3: resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} engines: {node: '>= 4'} @@ -2066,6 +2385,20 @@ packages: domelementtype: 2.3.0 dev: true + /domutils@1.5.1: + resolution: {integrity: sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==} + dependencies: + dom-serializer: 0.1.1 + domelementtype: 1.3.1 + dev: true + + /domutils@1.7.0: + resolution: {integrity: sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==} + dependencies: + dom-serializer: 0.1.1 + domelementtype: 1.3.1 + dev: true + /domutils@3.1.0: resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} dependencies: @@ -2078,15 +2411,24 @@ packages: resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} dependencies: no-case: 3.0.4 - tslib: 2.5.3 + tslib: 2.6.2 dev: true /eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} dev: true - /electron-to-chromium@1.4.433: - resolution: {integrity: sha512-MGO1k0w1RgrfdbLVwmXcDhHHuxCn2qRgR7dYsJvWFKDttvYPx6FNzCGG0c/fBBvzK2LDh3UV7Tt9awnHnvAAUQ==} + /ecc-jsbn@0.1.2: + resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} + requiresBuild: true + dependencies: + jsbn: 0.1.1 + safer-buffer: 2.1.2 + dev: true + optional: true + + /electron-to-chromium@1.4.572: + resolution: {integrity: sha512-RlFobl4D3ieetbnR+2EpxdzFl9h0RAJkPK3pfiwMug2nhBin2ZCsGIAJWdpNniLz43sgXam/CgipOmvTA+rUiA==} dev: true /element-internals-polyfill@1.3.5: @@ -2111,6 +2453,14 @@ packages: once: 1.4.0 dev: true + /entities@1.0.0: + resolution: {integrity: sha512-LbLqfXgJMmy81t+7c14mnulFHJ170cM6E+0vMXR9k/ZiZwgX8i5pNgjTCX3SO4VeUsFLV+8InixoretwU+MjBQ==} + dev: true + + /entities@1.1.2: + resolution: {integrity: sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==} + dev: true + /entities@2.1.0: resolution: {integrity: sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==} dev: true @@ -2120,6 +2470,12 @@ packages: engines: {node: '>=0.12'} dev: true + /error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + dependencies: + is-arrayish: 0.2.1 + dev: true + /es6-error@4.1.1: resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==} dev: true @@ -2189,6 +2545,10 @@ packages: engines: {node: '>=6'} dev: true + /escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + dev: true + /escape-string-regexp@1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} @@ -2204,10 +2564,165 @@ packages: engines: {node: '>=10'} dev: true + /escodegen@1.14.3: + resolution: {integrity: sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==} + engines: {node: '>=4.0'} + hasBin: true + requiresBuild: true + dependencies: + esprima: 4.0.1 + estraverse: 4.3.0 + esutils: 2.0.3 + optionator: 0.8.3 + optionalDependencies: + source-map: 0.6.1 + dev: true + optional: true + + /escodegen@2.1.0: + resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} + engines: {node: '>=6.0'} + hasBin: true + dependencies: + esprima: 4.0.1 + estraverse: 5.3.0 + esutils: 2.0.3 + optionalDependencies: + source-map: 0.6.1 + dev: true + + /esdoc-accessor-plugin@1.0.0: + resolution: {integrity: sha512-s9mNmdHGOyQOaOUXNHPz38Y8clm6dR8/fa9DPGzuRYmIN+Lv0NVnpPAcHb5XrfC23/Mz3IUwD8h798f5Ai4rbA==} + engines: {node: '>= 6.0.0'} + dev: true + + /esdoc-brand-plugin@1.0.1: + resolution: {integrity: sha512-Yv9j3M7qk5PSLmSeD6MbPsfIsEf8K43EdH8qZpE/GZwnJCRVmDPrZJ1cLDj/fPu6P35YqgcEaJK4E2NL/CKA7g==} + engines: {node: '>= 6.0.0'} + dependencies: + cheerio: 0.22.0 + dev: true + + /esdoc-coverage-plugin@1.1.0: + resolution: {integrity: sha512-M+94/Y+eoM08V3teiJIYpJ5HF13jH4cC9LQZrjmA91mlAqCHtNzelHF9ZdWofoOFYFRNpllFsXTFsJgwVa000A==} + engines: {node: '>= 6.0.0'} + dev: true + + /esdoc-external-ecmascript-plugin@1.0.0: + resolution: {integrity: sha512-ASj7lhfZpzI01xd4XqB4HN+zNKwnhdaN/OIp/CTnUiLIErMOeUqzV9z/dcnUUeDY3NSwPCH1pUNATVwznspmHw==} + engines: {node: '>= 6.0.0'} + dependencies: + fs-extra: 1.0.0 + dev: true + + /esdoc-integrate-manual-plugin@1.0.0: + resolution: {integrity: sha512-+XcW8xRtuFVFadoVLIOj6kzX4uqtAEB5UoR7AA5g46StxLghZZ6RLrRQSERUTIc3VX9v47lOMKEaQvQfanv3+A==} + engines: {node: '>= 6.0.0'} + dev: true + + /esdoc-integrate-test-plugin@1.0.0: + resolution: {integrity: sha512-WRbkbnbWnzF4RdmcoJLYZvhod7jLVUYWU2ZAojYjK+GiqSgy2yjGi7PxckeGF0LtpCuqqKat3PRdUNEMo6Nf3A==} + engines: {node: '>= 6.0.0'} + dev: true + + /esdoc-lint-plugin@1.0.2: + resolution: {integrity: sha512-24AYqD2WbZI9We02I7/6dzAa7yUliRTFUaJCZAcYJMQicJT5gUrNFVaI8XmWEN/mhF3szIn1uZBNWeLul4CmNw==} + engines: {node: '>= 6.0.0'} + dev: true + + /esdoc-publish-html-plugin@1.1.2: + resolution: {integrity: sha512-hG1fZmTcEp3P/Hv/qKiMdG1qSp8MjnVZMMkxL5P5ry7I2sX0HQ4P9lt2lms+90Lt0r340HHhSuVx107UL7dphg==} + engines: {node: '>= 6.0.0'} + dependencies: + babel-generator: 6.11.4 + cheerio: 0.22.0 + escape-html: 1.0.3 + fs-extra: 1.0.0 + ice-cap: 0.0.4 + marked: 0.3.19 + taffydb: 2.7.2 + dev: true + + /esdoc-standard-plugin@1.0.0: + resolution: {integrity: sha512-IDEG9NV/MF5Bi2TdKPqQ3GHfDkgqYhk2iyvBNX+XcNKYmXm9zxtXVS459WAmiTZuYpDLtDGbulQdJ1t4ud57mw==} + engines: {node: '>= 6.0.0'} + dependencies: + esdoc-accessor-plugin: 1.0.0 + esdoc-brand-plugin: 1.0.1 + esdoc-coverage-plugin: 1.1.0 + esdoc-external-ecmascript-plugin: 1.0.0 + esdoc-integrate-manual-plugin: 1.0.0 + esdoc-integrate-test-plugin: 1.0.0 + esdoc-lint-plugin: 1.0.2 + esdoc-publish-html-plugin: 1.1.2 + esdoc-type-inference-plugin: 1.0.2 + esdoc-undocumented-identifier-plugin: 1.0.0 + esdoc-unexported-identifier-plugin: 1.0.0 + dev: true + + /esdoc-type-inference-plugin@1.0.2: + resolution: {integrity: sha512-tMIcEHNe1uhUGA7lT1UTWc9hs2dzthnTgmqXpmeUhurk7fL2tinvoH+IVvG/sLROzwOGZQS9zW/F9KWnpMzLIQ==} + engines: {node: '>= 6.0.0'} + dev: true + + /esdoc-undocumented-identifier-plugin@1.0.0: + resolution: {integrity: sha512-T0hQc0ec1+pUJPDBoJ2SxEv7uX9VD7Q9+7UAGnDZ5R2l2JYa3WY7cawyqfbMHVtLgvqH0eMBpxdfRsQvAWzj4Q==} + engines: {node: '>= 6.0.0'} + dev: true + + /esdoc-unexported-identifier-plugin@1.0.0: + resolution: {integrity: sha512-PRdMLWHWdy9PwxzYDG2clhta9H7yHDpGCBIHxSw9R7TFK6ZYuPK1fUbURIzIxcdQhzt1PX9Cn6Cak2824K0+Ng==} + engines: {node: '>= 6.0.0'} + dev: true + + /esdoc@1.1.0: + resolution: {integrity: sha512-vsUcp52XJkOWg9m1vDYplGZN2iDzvmjDL5M/Mp8qkoDG3p2s0yIQCIjKR5wfPBaM3eV14a6zhQNYiNTCVzPnxA==} + engines: {node: '>= 6.0.0'} + hasBin: true + dependencies: + babel-generator: 6.26.1 + babel-traverse: 6.26.0 + babylon: 6.18.0 + cheerio: 1.0.0-rc.2 + color-logger: 0.0.6 + escape-html: 1.0.3 + fs-extra: 5.0.0 + ice-cap: 0.0.4 + marked: 0.3.19 + minimist: 1.2.0 + taffydb: 2.7.3 + transitivePeerDependencies: + - supports-color + dev: true + + /esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + requiresBuild: true + dev: true + + /estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + requiresBuild: true + dev: true + optional: true + + /estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + dev: true + /estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} dev: true + /esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + dev: true + /event-target-shim@5.0.1: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} @@ -2228,12 +2743,43 @@ packages: strip-final-newline: 2.0.0 dev: true + /extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + requiresBuild: true + dev: true + optional: true + + /extract-zip@2.0.1: + resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} + engines: {node: '>= 10.17.0'} + hasBin: true + dependencies: + debug: 4.3.4(supports-color@8.1.1) + get-stream: 5.2.0 + yauzl: 2.10.0 + optionalDependencies: + '@types/yauzl': 2.10.2 + transitivePeerDependencies: + - supports-color + dev: true + + /extsprintf@1.3.0: + resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} + engines: {'0': node >=0.6.0} + requiresBuild: true + dev: true + optional: true + /fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} dev: true - /fast-glob@3.2.12: - resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} + /fast-fifo@1.3.2: + resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} + dev: true + + /fast-glob@3.3.1: + resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} engines: {node: '>=8.6.0'} dependencies: '@nodelib/fs.stat': 2.0.5 @@ -2247,12 +2793,24 @@ packages: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} dev: true + /fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + requiresBuild: true + dev: true + optional: true + /fastq@1.15.0: resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} dependencies: reusify: 1.0.4 dev: true + /fd-slicer@1.1.0: + resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + dependencies: + pend: 1.2.0 + dev: true + /fetch-blob@3.2.0: resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} engines: {node: ^12.20 || >= 14.13} @@ -2302,18 +2860,6 @@ packages: hasBin: true dev: true - /follow-redirects@1.15.2(debug@4.3.4): - resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - dependencies: - debug: 4.3.4(supports-color@8.1.1) - dev: true - /for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} dependencies: @@ -2333,9 +2879,26 @@ packages: engines: {node: '>=14'} dependencies: cross-spawn: 7.0.3 - signal-exit: 4.0.2 + signal-exit: 4.1.0 dev: true + /forever-agent@0.6.1: + resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} + requiresBuild: true + dev: true + optional: true + + /form-data@2.3.3: + resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} + engines: {node: '>= 0.12'} + requiresBuild: true + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: true + optional: true + /form-data@4.0.0: resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} engines: {node: '>= 6'} @@ -2352,8 +2915,8 @@ packages: fetch-blob: 3.2.0 dev: true - /fraction.js@4.2.0: - resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==} + /fraction.js@4.3.7: + resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} dev: true /from2-string@1.1.0: @@ -2369,13 +2932,29 @@ packages: readable-stream: 2.3.8 dev: true + /fs-extra@1.0.0: + resolution: {integrity: sha512-VerQV6vEKuhDWD2HGOybV6v5I73syoc/cXAbKlgTC7M/oFVEtklWlp9QH2Ijw3IaWDOQcMkldSPa7zXy79Z/UQ==} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 2.4.0 + klaw: 1.3.1 + dev: true + /fs-extra@10.1.0: resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} engines: {node: '>=12'} dependencies: graceful-fs: 4.2.11 - jsonfile: 6.1.0 - universalify: 2.0.0 + jsonfile: 6.1.0 + universalify: 2.0.0 + dev: true + + /fs-extra@5.0.0: + resolution: {integrity: sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 dev: true /fs-extra@7.0.1: @@ -2387,6 +2966,15 @@ packages: universalify: 0.1.2 dev: true + /fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + dev: true + /fs-extra@9.1.0: resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} engines: {node: '>=10'} @@ -2405,16 +2993,16 @@ packages: resolution: {integrity: sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w==} dev: true - /fsevents@2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] requiresBuild: true dev: true optional: true - /function-bind@1.1.1: - resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + /function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} dev: true /gensync@1.0.0-beta.2: @@ -2427,17 +3015,22 @@ packages: engines: {node: 6.* || 8.* || >= 10.*} dev: true - /get-func-name@2.0.0: - resolution: {integrity: sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==} + /get-func-name@2.0.2: + resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} dev: true - /get-intrinsic@1.2.1: - resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==} + /get-intrinsic@1.2.2: + resolution: {integrity: sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==} dependencies: - function-bind: 1.1.1 - has: 1.0.3 + function-bind: 1.1.2 has-proto: 1.0.1 has-symbols: 1.0.3 + hasown: 2.0.0 + dev: true + + /get-stdin@4.0.1: + resolution: {integrity: sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw==} + engines: {node: '>=0.10.0'} dev: true /get-stream@5.2.0: @@ -2447,6 +3040,26 @@ packages: pump: 3.0.0 dev: true + /get-uri@6.0.2: + resolution: {integrity: sha512-5KLucCJobh8vBY1K07EFV4+cPZH3mrV9YeAruUseCQKHB58SGjjT2l9/eA9LD082IiuMjSlFJEcdJ27TXvbZNw==} + engines: {node: '>= 14'} + dependencies: + basic-ftp: 5.0.3 + data-uri-to-buffer: 6.0.1 + debug: 4.3.4(supports-color@8.1.1) + fs-extra: 8.1.0 + transitivePeerDependencies: + - supports-color + dev: true + + /getpass@0.1.7: + resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} + requiresBuild: true + dependencies: + assert-plus: 1.0.0 + dev: true + optional: true + /glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -2460,10 +3073,10 @@ packages: hasBin: true dependencies: foreground-child: 3.1.1 - jackspeak: 2.2.1 - minimatch: 9.0.1 + jackspeak: 2.3.6 + minimatch: 9.0.3 minipass: 6.0.2 - path-scurry: 1.9.2 + path-scurry: 1.10.1 dev: true /glob@7.2.0: @@ -2485,7 +3098,7 @@ packages: es6-error: 4.1.1 matcher: 3.0.0 roarr: 2.15.4 - semver: 7.5.2 + semver: 7.5.4 serialize-error: 7.0.1 dev: true @@ -2494,17 +3107,22 @@ packages: engines: {node: '>=4'} dev: true + /globals@9.18.0: + resolution: {integrity: sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==} + engines: {node: '>=0.10.0'} + dev: true + /globalthis@1.0.3: resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} engines: {node: '>= 0.4'} dependencies: - define-properties: 1.2.0 + define-properties: 1.2.1 dev: true /gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} dependencies: - get-intrinsic: 1.2.1 + get-intrinsic: 1.2.2 dev: true /graceful-fs@4.2.11: @@ -2518,6 +3136,24 @@ packages: temp: 0.4.0 dev: true + /har-schema@2.0.0: + resolution: {integrity: sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==} + engines: {node: '>=4'} + requiresBuild: true + dev: true + optional: true + + /har-validator@5.1.5: + resolution: {integrity: sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==} + engines: {node: '>=6'} + deprecated: this library is no longer supported + requiresBuild: true + dependencies: + ajv: 6.12.6 + har-schema: 2.0.0 + dev: true + optional: true + /has-ansi@2.0.0: resolution: {integrity: sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==} engines: {node: '>=0.10.0'} @@ -2540,10 +3176,10 @@ packages: engines: {node: '>=8'} dev: true - /has-property-descriptors@1.0.0: - resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} + /has-property-descriptors@1.0.1: + resolution: {integrity: sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==} dependencies: - get-intrinsic: 1.2.1 + get-intrinsic: 1.2.2 dev: true /has-proto@1.0.1: @@ -2563,11 +3199,11 @@ packages: has-symbols: 1.0.3 dev: true - /has@1.0.3: - resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} - engines: {node: '>= 0.4.0'} + /hasown@2.0.0: + resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==} + engines: {node: '>= 0.4'} dependencies: - function-bind: 1.1.1 + function-bind: 1.1.2 dev: true /he@1.2.0: @@ -2597,7 +3233,7 @@ packages: he: 1.2.0 param-case: 3.0.4 relateurl: 0.2.7 - terser: 5.18.1 + terser: 5.24.0 dev: true /html-minifier-terser@7.2.0: @@ -2611,7 +3247,28 @@ packages: entities: 4.5.0 param-case: 3.0.4 relateurl: 0.2.7 - terser: 5.18.1 + terser: 5.24.0 + dev: true + + /htmlparser2@3.10.1: + resolution: {integrity: sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==} + dependencies: + domelementtype: 1.3.1 + domhandler: 2.4.2 + domutils: 1.7.0 + entities: 1.1.2 + inherits: 2.0.4 + readable-stream: 3.6.2 + dev: true + + /htmlparser2@3.8.3: + resolution: {integrity: sha512-hBxEg3CYXe+rPIua8ETe7tmG3XDn9B0edOE/e9wH2nLczxzgdu0m0aNHY+5wFZiviLWLdANPJTssa92dMcXQ5Q==} + dependencies: + domelementtype: 1.3.1 + domhandler: 2.3.0 + domutils: 1.5.1 + entities: 1.0.0 + readable-stream: 1.1.14 dev: true /http-proxy-agent@5.0.0: @@ -2625,6 +3282,27 @@ packages: - supports-color dev: true + /http-proxy-agent@7.0.0: + resolution: {integrity: sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==} + engines: {node: '>= 14'} + dependencies: + agent-base: 7.1.0 + debug: 4.3.4(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + dev: true + + /http-signature@1.2.0: + resolution: {integrity: sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==} + engines: {node: '>=0.8', npm: '>=1.3.7'} + requiresBuild: true + dependencies: + assert-plus: 1.0.0 + jsprim: 1.4.2 + sshpk: 1.18.0 + dev: true + optional: true + /https-proxy-agent@5.0.1: resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} engines: {node: '>= 6'} @@ -2635,11 +3313,28 @@ packages: - supports-color dev: true + /https-proxy-agent@7.0.2: + resolution: {integrity: sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==} + engines: {node: '>= 14'} + dependencies: + agent-base: 7.1.0 + debug: 4.3.4(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + dev: true + /human-signals@1.1.1: resolution: {integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==} engines: {node: '>=8.12.0'} dev: true + /ice-cap@0.0.4: + resolution: {integrity: sha512-39ZblYEKlqj7LHgLkUcVk7zcJp772lOVQAUhN6QyY88w8/4bn5SgDeU2020yzHosf+uKPuCFK1UQ36gyBNiraw==} + dependencies: + cheerio: 0.20.0 + color-logger: 0.0.3 + dev: true + /iconv-lite@0.6.3: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} @@ -2647,6 +3342,18 @@ packages: safer-buffer: 2.1.2 dev: true + /ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + dev: true + + /import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + dev: true + /import-lazy@4.0.0: resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} engines: {node: '>=8'} @@ -2663,14 +3370,32 @@ packages: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} dev: true + /invariant@2.2.4: + resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + dependencies: + loose-envify: 1.4.0 + dev: true + + /ip@1.1.8: + resolution: {integrity: sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==} + dev: true + + /ip@2.0.0: + resolution: {integrity: sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==} + dev: true + /is-arguments@1.1.1: resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 has-tostringtag: 1.0.0 dev: true + /is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + dev: true + /is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} @@ -2683,10 +3408,10 @@ packages: engines: {node: '>= 0.4'} dev: true - /is-core-module@2.12.1: - resolution: {integrity: sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==} + /is-core-module@2.13.1: + resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} dependencies: - has: 1.0.3 + hasown: 2.0.0 dev: true /is-extglob@2.1.1: @@ -2694,6 +3419,11 @@ packages: engines: {node: '>=0.10.0'} dev: true + /is-finite@1.1.0: + resolution: {integrity: sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==} + engines: {node: '>=0.10.0'} + dev: true + /is-fullwidth-code-point@2.0.0: resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==} engines: {node: '>=4'} @@ -2728,11 +3458,6 @@ packages: engines: {node: '>=8'} dev: true - /is-plain-object@5.0.0: - resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} - engines: {node: '>=0.10.0'} - dev: true - /is-potential-custom-element-name@1.0.1: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} dev: true @@ -2742,16 +3467,18 @@ packages: engines: {node: '>=8'} dev: true - /is-typed-array@1.1.10: - resolution: {integrity: sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==} + /is-typed-array@1.1.12: + resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==} engines: {node: '>= 0.4'} dependencies: - available-typed-arrays: 1.0.5 - call-bind: 1.0.2 - for-each: 0.3.3 - gopd: 1.0.1 - has-tostringtag: 1.0.0 + which-typed-array: 1.1.13 + dev: true + + /is-typedarray@1.0.0: + resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} + requiresBuild: true dev: true + optional: true /is-unicode-supported@0.1.0: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} @@ -2775,30 +3502,36 @@ packages: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: true + /isstream@0.1.2: + resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} + requiresBuild: true + dev: true + optional: true + /istanbul-lib-coverage@3.2.0: resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==} engines: {node: '>=8'} dev: true - /istanbul-lib-report@3.0.0: - resolution: {integrity: sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==} - engines: {node: '>=8'} + /istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} dependencies: istanbul-lib-coverage: 3.2.0 - make-dir: 3.1.0 + make-dir: 4.0.0 supports-color: 7.2.0 dev: true - /istanbul-reports@3.1.5: - resolution: {integrity: sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==} + /istanbul-reports@3.1.6: + resolution: {integrity: sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==} engines: {node: '>=8'} dependencies: html-escaper: 2.0.2 - istanbul-lib-report: 3.0.0 + istanbul-lib-report: 3.0.1 dev: true - /jackspeak@2.2.1: - resolution: {integrity: sha512-MXbxovZ/Pm42f6cDIDkl3xpwv1AGwObKwfmjs2nQePiy85tP3fatofl3FC1aBsOtP/6fq5SbtgHwWcMsLP+bDw==} + /jackspeak@2.3.6: + resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} engines: {node: '>=14'} dependencies: '@isaacs/cliui': 8.0.2 @@ -2814,6 +3547,10 @@ packages: resolution: {integrity: sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==} dev: true + /js-tokens@3.0.2: + resolution: {integrity: sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==} + dev: true + /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} dev: true @@ -2831,6 +3568,18 @@ packages: xmlcreate: 2.0.4 dev: true + /jsbn@0.1.1: + resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} + requiresBuild: true + dev: true + optional: true + + /jsdoc-mermaid@1.0.0: + resolution: {integrity: sha512-WgXR/E1369RurPVFkyNzUWP5wB5xQkm0p+vdIh/cX6ZtEQBb5KdeukDje47Du++IehwztkR3GJcwYhM+eaq/4w==} + dependencies: + doctrine: 2.1.0 + dev: true + /jsdoc-plantuml@1.0.3(jsdoc@4.0.2): resolution: {integrity: sha512-yDG8Aqj73CNg0vVBHR0MAWR6DFJb9X5i5MzS/CXQgUA8ZMrV1o2d1adXQoGF2D/PIRCvKGnupwwtbPse6WIM8A==} engines: {node: '>=10.x'} @@ -2848,7 +3597,7 @@ packages: engines: {node: '>=12.0.0'} hasBin: true dependencies: - '@babel/parser': 7.22.5 + '@babel/parser': 7.23.0 '@jsdoc/salty': 0.2.5 '@types/markdown-it': 12.2.3 bluebird: 3.7.2 @@ -2892,7 +3641,7 @@ packages: http-proxy-agent: 5.0.0 https-proxy-agent: 5.0.1 is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.5 + nwsapi: 2.2.7 parse5: 7.1.2 rrweb-cssom: 0.6.0 saxes: 6.0.0 @@ -2911,16 +3660,53 @@ packages: - utf-8-validate dev: true + /jsdom@7.2.2: + resolution: {integrity: sha512-kYeYuos/pYp0V/V8VAoGnUc0va0UZjTjwCsldBFZNBrOi9Q5kUXrvsw6W5/lQllB7hKXBARC4HRk1Sfk4dPFtA==} + requiresBuild: true + dependencies: + abab: 1.0.4 + acorn: 2.7.0 + acorn-globals: 1.0.9 + cssom: 0.3.8 + cssstyle: 0.2.37 + escodegen: 1.14.3 + nwmatcher: 1.4.4 + parse5: 1.5.1 + request: 2.88.2 + sax: 1.3.0 + symbol-tree: 3.2.4 + tough-cookie: 2.5.0 + webidl-conversions: 2.0.1 + whatwg-url-compat: 0.6.5 + xml-name-validator: 2.0.1 + dev: true + optional: true + + /jsesc@1.3.0: + resolution: {integrity: sha512-Mke0DA0QjUWuJlhsE0ZPPhYiJkRap642SmI/4ztCFaUs6V2AiH1sfecc+57NgaryfAA2VR3v6O+CSjC1jZJKOA==} + hasBin: true + dev: true + /jsesc@2.5.2: resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} engines: {node: '>=4'} hasBin: true dev: true + /json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + dev: true + /json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} dev: true + /json-schema@0.4.0: + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + requiresBuild: true + dev: true + optional: true + /json-stringify-safe@5.0.1: resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} dev: true @@ -2931,6 +3717,12 @@ packages: hasBin: true dev: true + /jsonfile@2.4.0: + resolution: {integrity: sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==} + optionalDependencies: + graceful-fs: 4.2.11 + dev: true + /jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} optionalDependencies: @@ -2945,6 +3737,18 @@ packages: graceful-fs: 4.2.11 dev: true + /jsprim@1.4.2: + resolution: {integrity: sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==} + engines: {node: '>=0.6.0'} + requiresBuild: true + dependencies: + assert-plus: 1.0.0 + extsprintf: 1.3.0 + json-schema: 0.4.0 + verror: 1.10.0 + dev: true + optional: true + /just-extend@4.2.1: resolution: {integrity: sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==} dev: true @@ -2955,6 +3759,12 @@ packages: graceful-fs: 4.2.11 dev: true + /klaw@1.3.1: + resolution: {integrity: sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==} + optionalDependencies: + graceful-fs: 4.2.11 + dev: true + /klaw@3.0.0: resolution: {integrity: sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==} dependencies: @@ -2977,7 +3787,7 @@ packages: dependencies: abort-controller: 3.0.0 ky: 0.27.0 - node-fetch: 3.3.1 + node-fetch: 3.3.2 dev: true /ky@0.27.0: @@ -2985,11 +3795,25 @@ packages: engines: {node: '>=12'} dev: true + /levn@0.3.0: + resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==} + engines: {node: '>= 0.8.0'} + requiresBuild: true + dependencies: + prelude-ls: 1.1.2 + type-check: 0.3.2 + dev: true + optional: true + /lilconfig@2.1.0: resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} engines: {node: '>=10'} dev: true + /lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + dev: true + /linkify-it@3.0.3: resolution: {integrity: sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==} dependencies: @@ -3018,6 +3842,30 @@ packages: p-locate: 5.0.0 dev: true + /lodash.assignin@4.2.0: + resolution: {integrity: sha512-yX/rx6d/UTVh7sSVWVSIMjfnz95evAgDFdb1ZozC35I9mSFCkmzptOzevxjgbQUsc78NR44LVHWjsoMQXy9FDg==} + dev: true + + /lodash.bind@4.2.1: + resolution: {integrity: sha512-lxdsn7xxlCymgLYo1gGvVrfHmkjDiyqVv62FAeF2i5ta72BipE1SLxw8hPEPLhD4/247Ijw07UQH7Hq/chT5LA==} + dev: true + + /lodash.defaults@4.2.0: + resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} + dev: true + + /lodash.filter@4.6.0: + resolution: {integrity: sha512-pXYUy7PR8BCLwX5mgJ/aNtyOvuJTdZAo9EQFUvMIYugqmJxnrYaANvTbgndOzHSCSR0wnlBBfRXJL5SbWxo3FQ==} + dev: true + + /lodash.flatten@4.4.0: + resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==} + dev: true + + /lodash.foreach@4.5.0: + resolution: {integrity: sha512-aEXTF4d+m05rVOAUG3z4vZZ4xVexLKZGF0lIxuHZ1Hplpk/3B6Z1+/ICICYRLm7c41Z2xiejbkCkJoTlypoXhQ==} + dev: true + /lodash.get@4.4.2: resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} dev: true @@ -3026,10 +3874,34 @@ packages: resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} dev: true + /lodash.map@4.6.0: + resolution: {integrity: sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==} + dev: true + /lodash.memoize@4.1.2: resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} dev: true + /lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + dev: true + + /lodash.pick@4.4.0: + resolution: {integrity: sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==} + dev: true + + /lodash.reduce@4.6.0: + resolution: {integrity: sha512-6raRe2vxCYBhpBu+B+TtNGUzah+hQjVdu3E17wfusjyrXBka2nBS8OH/gjVZ5PvHOhWmIZTYri09Z6n/QfnNMw==} + dev: true + + /lodash.reject@4.6.0: + resolution: {integrity: sha512-qkTuvgEzYdyhiJBx42YPzPo71R1aEr0z79kAv7Ixg8wPFEjgRgJdUsGMG3Hf3OYSF/kHI79XhNlt+5Ar6OzwxQ==} + dev: true + + /lodash.some@4.6.0: + resolution: {integrity: sha512-j7MJE+TuT51q9ggt4fSgVqro163BEFjAt3u97IqU+JA2DkWl80nFTrowzLpZ/BnpN7rrl0JA/593NAdd8p/scQ==} + dev: true + /lodash.uniq@4.5.0: resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} dev: true @@ -3046,16 +3918,28 @@ packages: is-unicode-supported: 0.1.0 dev: true - /loupe@2.3.6: - resolution: {integrity: sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==} + /loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + dependencies: + js-tokens: 4.0.0 + dev: true + + /loupe@2.3.7: + resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} dependencies: - get-func-name: 2.0.0 + get-func-name: 2.0.2 dev: true /lower-case@2.0.2: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} dependencies: - tslib: 2.5.3 + tslib: 2.6.2 + dev: true + + /lru-cache@10.0.1: + resolution: {integrity: sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==} + engines: {node: 14 || >=16.14} dev: true /lru-cache@5.1.1: @@ -3071,20 +3955,16 @@ packages: yallist: 4.0.0 dev: true - /lru-cache@9.1.2: - resolution: {integrity: sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ==} - engines: {node: 14 || >=16.14} - dev: true - - /lru_map@0.3.3: - resolution: {integrity: sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==} + /lru-cache@7.18.3: + resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} + engines: {node: '>=12'} dev: true - /make-dir@3.1.0: - resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} - engines: {node: '>=8'} + /make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} dependencies: - semver: 6.3.0 + semver: 7.5.4 dev: true /markdown-it-anchor@8.6.7(@types/markdown-it@12.2.3)(markdown-it@12.3.2): @@ -3108,6 +3988,12 @@ packages: uc.micro: 1.0.6 dev: true + /marked@0.3.19: + resolution: {integrity: sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg==} + engines: {node: '>=0.10.0'} + hasBin: true + dev: true + /marked@4.3.0: resolution: {integrity: sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==} engines: {node: '>= 12'} @@ -3187,18 +4073,34 @@ packages: brace-expansion: 2.0.1 dev: true - /minimatch@9.0.1: - resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==} + /minimatch@9.0.3: + resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} engines: {node: '>=16 || 14 >=14.17'} dependencies: brace-expansion: 2.0.1 dev: true + /minimist@1.2.0: + resolution: {integrity: sha512-7Wl+Jz+IGWuSdgsQEJ4JunV0si/iMhg42MnQQG6h1R6TNeVenp4U9x5CC5v/gYqz/fENLQITAWXidNtVL0NNbw==} + dev: true + + /minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + dev: true + /minipass@6.0.2: resolution: {integrity: sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==} engines: {node: '>=16 || 14 >=14.17'} dev: true + /mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + dev: true + + /mkdirp-classic@0.5.3: + resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + dev: true + /mkdirp@1.0.4: resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} engines: {node: '>=10'} @@ -3239,6 +4141,10 @@ packages: yargs-unparser: 2.0.0 dev: true + /ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + dev: true + /ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} dev: true @@ -3259,11 +4165,16 @@ packages: hasBin: true dev: true - /nise@5.1.4: - resolution: {integrity: sha512-8+Ib8rRJ4L0o3kfmyVCL7gzrohyDe0cMFTBa2d364yIrEGMEoetznKJx899YxjybU6bL9SQkYPSBBs1gyYs8Xg==} + /netmask@2.0.2: + resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} + engines: {node: '>= 0.4.0'} + dev: true + + /nise@5.1.5: + resolution: {integrity: sha512-VJuPIfUFaXNRzETTQEEItTOP8Y171ijr+JLq42wHes3DiryR8vT+1TXQW/Rx8JNUhyYYWyIvjXTU6dOhJcs9Nw==} dependencies: '@sinonjs/commons': 2.0.0 - '@sinonjs/fake-timers': 10.1.0 + '@sinonjs/fake-timers': 10.3.0 '@sinonjs/text-encoding': 0.7.2 just-extend: 4.2.1 path-to-regexp: 1.8.0 @@ -3273,7 +4184,7 @@ packages: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} dependencies: lower-case: 2.0.2 - tslib: 2.5.3 + tslib: 2.6.2 dev: true /node-domexception@1.0.0: @@ -3281,8 +4192,8 @@ packages: engines: {node: '>=10.5.0'} dev: true - /node-fetch@2.6.11: - resolution: {integrity: sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==} + /node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} engines: {node: 4.x || >=6.0.0} peerDependencies: encoding: ^0.1.0 @@ -3293,8 +4204,8 @@ packages: whatwg-url: 5.0.0 dev: true - /node-fetch@3.3.1: - resolution: {integrity: sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow==} + /node-fetch@3.3.2: + resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dependencies: data-uri-to-buffer: 4.0.1 @@ -3339,8 +4250,8 @@ packages: plantuml-encoder: 1.4.0 dev: true - /node-releases@2.0.12: - resolution: {integrity: sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==} + /node-releases@2.0.13: + resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==} dev: true /normalize-path@3.0.0: @@ -3360,18 +4271,36 @@ packages: path-key: 3.1.1 dev: true + /nth-check@1.0.2: + resolution: {integrity: sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==} + dependencies: + boolbase: 1.0.0 + dev: true + /nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} dependencies: boolbase: 1.0.0 dev: true - /nwsapi@2.2.5: - resolution: {integrity: sha512-6xpotnECFy/og7tKSBVmUNft7J3jyXAka4XvG6AUhFWRz+Q/Ljus7znJAA3bxColfQLdS+XsjoodtJfCgeTEFQ==} + /nwmatcher@1.4.4: + resolution: {integrity: sha512-3iuY4N5dhgMpCUrOVnuAdGrgxVqV2cJpM+XNccjR2DKOB1RUP0aA+wGXEiNziG/UKboFyGBIoKOaNlJxx8bciQ==} + requiresBuild: true + dev: true + optional: true + + /nwsapi@2.2.7: + resolution: {integrity: sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==} + dev: true + + /oauth-sign@0.9.0: + resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==} + requiresBuild: true dev: true + optional: true - /object-inspect@1.12.3: - resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} + /object-inspect@1.13.1: + resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} dev: true /object-keys@1.1.1: @@ -3396,6 +4325,20 @@ packages: mimic-fn: 2.1.0 dev: true + /optionator@0.8.3: + resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} + engines: {node: '>= 0.8.0'} + requiresBuild: true + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.3.0 + prelude-ls: 1.1.2 + type-check: 0.3.2 + word-wrap: 1.2.5 + dev: true + optional: true + /p-limit@2.3.0: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} engines: {node: '>=6'} @@ -3421,26 +4364,80 @@ packages: resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} engines: {node: '>=8'} dependencies: - p-limit: 2.3.0 + p-limit: 2.3.0 + dev: true + + /p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + dependencies: + p-limit: 3.1.0 + dev: true + + /p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + dev: true + + /pac-proxy-agent@7.0.1: + resolution: {integrity: sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A==} + engines: {node: '>= 14'} + dependencies: + '@tootallnate/quickjs-emscripten': 0.23.0 + agent-base: 7.1.0 + debug: 4.3.4(supports-color@8.1.1) + get-uri: 6.0.2 + http-proxy-agent: 7.0.0 + https-proxy-agent: 7.0.2 + pac-resolver: 7.0.0 + socks-proxy-agent: 8.0.2 + transitivePeerDependencies: + - supports-color + dev: true + + /pac-resolver@7.0.0: + resolution: {integrity: sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg==} + engines: {node: '>= 14'} + dependencies: + degenerator: 5.0.1 + ip: 1.1.8 + netmask: 2.0.2 + dev: true + + /param-case@3.0.4: + resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} + dependencies: + dot-case: 3.0.4 + tslib: 2.6.2 + dev: true + + /parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + dependencies: + callsites: 3.1.0 dev: true - /p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} + /parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} dependencies: - p-limit: 3.1.0 + '@babel/code-frame': 7.22.13 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 dev: true - /p-try@2.2.0: - resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} - engines: {node: '>=6'} + /parse5@1.5.1: + resolution: {integrity: sha512-w2jx/0tJzvgKwZa58sj2vAYq/S/K1QJfIB3cWYea/Iu1scFPDQQ3IQiVZTHWtRBwAjv2Yd7S/xeZf3XqLDb3bA==} + requiresBuild: true dev: true + optional: true - /param-case@3.0.4: - resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} + /parse5@3.0.3: + resolution: {integrity: sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==} dependencies: - dot-case: 3.0.4 - tslib: 2.5.3 + '@types/node': 18.18.8 dev: true /parse5@7.1.2: @@ -3453,7 +4450,7 @@ packages: resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} dependencies: no-case: 3.0.4 - tslib: 2.5.3 + tslib: 2.6.2 dev: true /path-browserify@1.0.1: @@ -3484,11 +4481,11 @@ packages: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} dev: true - /path-scurry@1.9.2: - resolution: {integrity: sha512-qSDLy2aGFPm8i4rsbHd4MNyTcrzHFsLQykrtbuGRknZZCBBVXSv2tSCDN2Cg6Rt/GFRw8GoW9y9Ecw5rIPG1sg==} + /path-scurry@1.10.1: + resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==} engines: {node: '>=16 || 14 >=14.17'} dependencies: - lru-cache: 9.1.2 + lru-cache: 10.0.1 minipass: 6.0.2 dev: true @@ -3498,10 +4495,25 @@ packages: isarray: 0.0.1 dev: true + /path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + dev: true + /pathval@1.1.1: resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} dev: true + /pend@1.2.0: + resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + dev: true + + /performance-now@2.1.0: + resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} + requiresBuild: true + dev: true + optional: true + /picocolors@1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} dev: true @@ -3636,7 +4648,7 @@ packages: postcss: 8.4.24 postcss-value-parser: 4.2.0 read-cache: 1.0.0 - resolve: 1.22.2 + resolve: 1.22.8 dev: true /postcss-js@4.0.1(postcss@8.4.24): @@ -3663,7 +4675,7 @@ packages: dependencies: lilconfig: 2.1.0 postcss: 8.4.24 - yaml: 2.3.1 + yaml: 2.3.3 dev: true /postcss-merge-longhand@6.0.0(postcss@8.4.24): @@ -3740,7 +4752,7 @@ packages: peerDependencies: postcss: ^8.2.14 dependencies: - fast-glob: 3.2.12 + fast-glob: 3.3.1 postcss: 8.4.24 postcss-js: 4.0.1(postcss@8.4.24) postcss-simple-vars: 7.0.1(postcss@8.4.24) @@ -4003,14 +5015,42 @@ packages: source-map-js: 1.0.2 dev: true + /prelude-ls@1.1.2: + resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} + engines: {node: '>= 0.8.0'} + requiresBuild: true + dev: true + optional: true + /process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} dev: true + /progress@2.0.3: + resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} + engines: {node: '>=0.4.0'} + dev: true + /promise-polyfill@1.1.6: resolution: {integrity: sha512-7rrONfyLkDEc7OJ5QBkqa4KI4EBhCd340xRuIUPGCfu13znS+vx+VDdrT9ODAJHlXm7w4lbxN3DRjyv58EuzDg==} dev: true + /proxy-agent@6.3.1: + resolution: {integrity: sha512-Rb5RVBy1iyqOtNl15Cw/llpeLH8bsb37gM1FUfKQ+Wck6xHlbAhWGUFiTRHtkjqGTA5pSHz6+0hrPW/oECihPQ==} + engines: {node: '>= 14'} + dependencies: + agent-base: 7.1.0 + debug: 4.3.4(supports-color@8.1.1) + http-proxy-agent: 7.0.0 + https-proxy-agent: 7.0.2 + lru-cache: 7.18.3 + pac-proxy-agent: 7.0.1 + proxy-from-env: 1.1.0 + socks-proxy-agent: 8.0.2 + transitivePeerDependencies: + - supports-color + dev: true + /proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} dev: true @@ -4030,15 +5070,48 @@ packages: resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} dev: true - /punycode@2.3.0: - resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} + /punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} dev: true - /pvtsutils@1.3.2: - resolution: {integrity: sha512-+Ipe2iNUyrZz+8K/2IOo+kKikdtfhRKzNpQbruF2URmqPtoqAs8g3xS7TJvFF2GcPXjh7DkqMnpVveRFq4PgEQ==} + /puppeteer-core@21.4.1: + resolution: {integrity: sha512-Lh0e+oGhUquxVOi1U701gTfFLFvw5gDBFh3CWpnfAvtItmyZKUce4R54VNfOJfi+KKnzhVPdB/lDrg65gdRIng==} + engines: {node: '>=16.3.0'} + dependencies: + '@puppeteer/browsers': 1.8.0 + chromium-bidi: 0.4.32(devtools-protocol@0.0.1191157) + cross-fetch: 4.0.0 + debug: 4.3.4(supports-color@8.1.1) + devtools-protocol: 0.0.1191157 + ws: 8.14.2 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + dev: true + + /puppeteer@21.4.1: + resolution: {integrity: sha512-opJqQeYMjAB3ICG8lCF3wtSs9k05dozmrEMrHgo3ZWbISiy8qbv/yAJz/6Io221qSh3yURfVf6Z7crrlzKZjLQ==} + engines: {node: '>=16.3.0'} + requiresBuild: true + dependencies: + '@puppeteer/browsers': 1.8.0 + cosmiconfig: 8.3.6 + puppeteer-core: 21.4.1 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - typescript + - utf-8-validate + dev: true + + /pvtsutils@1.3.5: + resolution: {integrity: sha512-ARvb14YB9Nm2Xi6nBq1ZX6dAM0FsJnuk+31aUp4TrcZEdKUlSqOqsxJHUPJDNE3qiIp+iUPEIeR6Je/tgV7zsA==} dependencies: - tslib: 2.5.3 + tslib: 2.6.2 dev: true /pvutils@1.1.3: @@ -4053,6 +5126,13 @@ packages: side-channel: 1.0.4 dev: true + /qs@6.5.3: + resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==} + engines: {node: '>=0.6'} + requiresBuild: true + dev: true + optional: true + /querystringify@2.2.0: resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} dev: true @@ -4061,6 +5141,10 @@ packages: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} dev: true + /queue-tick@1.0.1: + resolution: {integrity: sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==} + dev: true + /randombytes@2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} dependencies: @@ -4073,6 +5157,15 @@ packages: pify: 2.3.0 dev: true + /readable-stream@1.1.14: + resolution: {integrity: sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==} + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 0.0.1 + string_decoder: 0.10.31 + dev: true + /readable-stream@2.3.8: resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} dependencies: @@ -4085,6 +5178,15 @@ packages: util-deprecate: 1.0.2 dev: true + /readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + dependencies: + inherits: 2.0.4 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + dev: true + /readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} @@ -4098,11 +5200,59 @@ packages: balanced-match: 1.0.2 dev: true + /regenerator-runtime@0.11.1: + resolution: {integrity: sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==} + dev: true + /relateurl@0.2.7: resolution: {integrity: sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==} engines: {node: '>= 0.10'} dev: true + /repeating@1.1.3: + resolution: {integrity: sha512-Nh30JLeMHdoI+AsQ5eblhZ7YlTsM9wiJQe/AHIunlK3KWzvXhXb36IJ7K1IOeRjIOtzMjdUHjwXUFxKJoPTSOg==} + engines: {node: '>=0.10.0'} + hasBin: true + dependencies: + is-finite: 1.1.0 + dev: true + + /repeating@2.0.1: + resolution: {integrity: sha512-ZqtSMuVybkISo2OWvqvm7iHSWngvdaW3IpsT9/uP8v4gMi591LY6h35wdOfvQdWCKFWZWm2Y1Opp4kV7vQKT6A==} + engines: {node: '>=0.10.0'} + dependencies: + is-finite: 1.1.0 + dev: true + + /request@2.88.2: + resolution: {integrity: sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==} + engines: {node: '>= 6'} + deprecated: request has been deprecated, see https://github.com/request/request/issues/3142 + requiresBuild: true + dependencies: + aws-sign2: 0.7.0 + aws4: 1.12.0 + caseless: 0.12.0 + combined-stream: 1.0.8 + extend: 3.0.2 + forever-agent: 0.6.1 + form-data: 2.3.3 + har-validator: 5.1.5 + http-signature: 1.2.0 + is-typedarray: 1.0.0 + isstream: 0.1.2 + json-stringify-safe: 5.0.1 + mime-types: 2.1.35 + oauth-sign: 0.9.0 + performance-now: 2.1.0 + qs: 6.5.3 + safe-buffer: 5.2.1 + tough-cookie: 2.5.0 + tunnel-agent: 0.6.0 + uuid: 3.4.0 + dev: true + optional: true + /require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -4122,18 +5272,23 @@ packages: lodash: 4.17.21 dev: true + /resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + dev: true + /resolve@1.19.0: resolution: {integrity: sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==} dependencies: - is-core-module: 2.12.1 + is-core-module: 2.13.1 path-parse: 1.0.7 dev: true - /resolve@1.22.2: - resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==} + /resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true dependencies: - is-core-module: 2.12.1 + is-core-module: 2.13.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 dev: true @@ -4159,29 +5314,15 @@ packages: globalthis: 1.0.3 json-stringify-safe: 5.0.1 semver-compare: 1.0.0 - sprintf-js: 1.1.2 + sprintf-js: 1.1.3 dev: true - /rollup@3.25.1: - resolution: {integrity: sha512-tywOR+rwIt5m2ZAWSe5AIJcTat8vGlnPFAv15ycCrw33t6iFsXZ6mzHVFh2psSjxQPmI+xgzMZZizUAukBI4aQ==} + /rollup@3.29.4: + resolution: {integrity: sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==} engines: {node: '>=14.18.0', npm: '>=8.0.0'} hasBin: true optionalDependencies: - fsevents: 2.3.2 - dev: true - - /rome@12.1.3: - resolution: {integrity: sha512-e+ff72hxDpe/t5/Us7YRBVw3PBET7SeczTQNn6tvrWdrCaAw3qOukQQ+tDCkyFtS4yGsnhjrJbm43ctNbz27Yg==} - engines: {node: '>=14.*'} - hasBin: true - requiresBuild: true - optionalDependencies: - '@rometools/cli-darwin-arm64': 12.1.3 - '@rometools/cli-darwin-x64': 12.1.3 - '@rometools/cli-linux-arm64': 12.1.3 - '@rometools/cli-linux-x64': 12.1.3 - '@rometools/cli-win32-arm64': 12.1.3 - '@rometools/cli-win32-x64': 12.1.3 + fsevents: 2.3.3 dev: true /rrweb-cssom@0.6.0: @@ -4221,6 +5362,12 @@ packages: resolution: {integrity: sha512-ZRwKbh/eQ6w9vmTjkuG0Ioi3HBwPFce0O+v//ve+aOq1oeCy7jMV2qzzAlpsNuqpqCBjjriM1lbtZbF/Q8jVyA==} dev: true + /sax@1.3.0: + resolution: {integrity: sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==} + requiresBuild: true + dev: true + optional: true + /saxes@6.0.0: resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} engines: {node: '>=v12.22.7'} @@ -4232,21 +5379,13 @@ packages: resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==} dev: true - /semver@6.3.0: - resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} + /semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true dev: true - /semver@7.3.8: - resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==} - engines: {node: '>=10'} - hasBin: true - dependencies: - lru-cache: 6.0.0 - dev: true - - /semver@7.5.2: - resolution: {integrity: sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==} + /semver@7.5.4: + resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} engines: {node: '>=10'} hasBin: true dependencies: @@ -4270,6 +5409,16 @@ packages: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} dev: true + /set-function-length@1.1.1: + resolution: {integrity: sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.1 + get-intrinsic: 1.2.2 + gopd: 1.0.1 + has-property-descriptors: 1.0.1 + dev: true + /shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -4292,43 +5441,68 @@ packages: /side-channel@1.0.4: resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 - object-inspect: 1.12.3 + call-bind: 1.0.5 + get-intrinsic: 1.2.2 + object-inspect: 1.13.1 dev: true /signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} dev: true - /signal-exit@4.0.2: - resolution: {integrity: sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==} + /signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} dev: true /sinon@15.1.2: resolution: {integrity: sha512-uG1pU54Fis4EfYOPoEi13fmRHgZNg/u+3aReSEzHsN52Bpf+bMVfsBQS5MjouI+rTuG6UBIINlpuuO2Epr7SiA==} + deprecated: 16.1.1 dependencies: '@sinonjs/commons': 3.0.0 - '@sinonjs/fake-timers': 10.1.0 + '@sinonjs/fake-timers': 10.3.0 '@sinonjs/samsam': 8.0.0 diff: 5.1.0 - nise: 5.1.4 + nise: 5.1.5 supports-color: 7.2.0 dev: true - /snyk@1.1183.0: - resolution: {integrity: sha512-teV1xPziM+2zYzOkMfOMhfgjXs+QaJLWyIuccosO40suKrNlcU+Gj9Cnj8SdRvsV+tRH9TGZBLRpmbneBxUqEw==} + /smart-buffer@4.2.0: + resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} + engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + dev: true + + /snyk@1.1238.0: + resolution: {integrity: sha512-JDYAL1bFwHuRqmSsSxMKjy8MKCDRn3oQ4kLVVk1WoDb58nVrqxULOLV0qTz8l6x4VWqphJf26MWZqQwcSgPAjQ==} engines: {node: '>=12'} hasBin: true requiresBuild: true dependencies: - '@sentry/node': 7.56.0 + '@sentry/node': 7.77.0 global-agent: 3.0.0 transitivePeerDependencies: - supports-color dev: true + /socks-proxy-agent@8.0.2: + resolution: {integrity: sha512-8zuqoLv1aP/66PHF5TqwJ7Czm3Yv32urJQHrVyhD7mmA6d61Zv8cIXQYPTWwmg6qlupnPvs/QKDmfa4P/qct2g==} + engines: {node: '>= 14'} + dependencies: + agent-base: 7.1.0 + debug: 4.3.4(supports-color@8.1.1) + socks: 2.7.1 + transitivePeerDependencies: + - supports-color + dev: true + + /socks@2.7.1: + resolution: {integrity: sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==} + engines: {node: '>= 10.13.0', npm: '>= 3.0.0'} + dependencies: + ip: 2.0.0 + smart-buffer: 4.2.0 + dev: true + /source-map-js@1.0.2: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} @@ -4355,9 +5529,27 @@ packages: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} dev: true - /sprintf-js@1.1.2: - resolution: {integrity: sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==} + /sprintf-js@1.1.3: + resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} + dev: true + + /sshpk@1.18.0: + resolution: {integrity: sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==} + engines: {node: '>=0.10.0'} + hasBin: true + requiresBuild: true + dependencies: + asn1: 0.2.6 + assert-plus: 1.0.0 + bcrypt-pbkdf: 1.0.2 + dashdash: 1.14.1 + ecc-jsbn: 0.1.2 + getpass: 0.1.7 + jsbn: 0.1.1 + safer-buffer: 2.1.2 + tweetnacl: 0.14.5 dev: true + optional: true /stream-from-promise@1.0.0: resolution: {integrity: sha512-j84KLkudt+gr8KJ21RB02btPLx61uGbrLnewsWz6QKmsz8/c4ZFqXw6mJh5+G4oRN7DgDxdbjPxnpySpg1mUig==} @@ -4370,6 +5562,13 @@ packages: promise-polyfill: 1.1.6 dev: true + /streamx@2.15.2: + resolution: {integrity: sha512-b62pAV/aeMjUoRN2C/9F0n+G8AfcJjNC0zw/ZmOHeFsIe4m4GzjVW9m6VHXVjk536NbdU9JRwKMJRfkc+zUFTg==} + dependencies: + fast-fifo: 1.3.2 + queue-tick: 1.0.1 + dev: true + /string-argv@0.3.2: resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} engines: {node: '>=0.6.19'} @@ -4402,6 +5601,10 @@ packages: strip-ansi: 7.1.0 dev: true + /string_decoder@0.10.31: + resolution: {integrity: sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==} + dev: true + /string_decoder@1.1.1: resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} dependencies: @@ -4521,18 +5724,42 @@ packages: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} dev: true + /taffydb@2.7.2: + resolution: {integrity: sha512-R6es6/C/m1xXZckrSam4j07YKbd74437mRJ/R944S1hLG7mIl2/EQW7tQPI4XiX7jTduFzz31g7466a2BcsglQ==} + dev: true + + /taffydb@2.7.3: + resolution: {integrity: sha512-GQ3gtYFSOAxSMN/apGtDKKkbJf+8izz5YfbGqIsUc7AMiQOapARZ76dhilRY2h39cynYxBFdafQo5HUL5vgkrg==} + dev: true + + /tar-fs@3.0.4: + resolution: {integrity: sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==} + dependencies: + mkdirp-classic: 0.5.3 + pump: 3.0.0 + tar-stream: 3.1.6 + dev: true + + /tar-stream@3.1.6: + resolution: {integrity: sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==} + dependencies: + b4a: 1.6.4 + fast-fifo: 1.3.2 + streamx: 2.15.2 + dev: true + /temp@0.4.0: resolution: {integrity: sha512-IsFisGgDKk7qzK9erMIkQe/XwiSUdac7z3wYOsjcLkhPBy3k1SlvLoIh2dAHIlEpgA971CgguMrx9z8fFg7tSA==} engines: {'0': node >=0.4.0} dev: true - /terser@5.18.1: - resolution: {integrity: sha512-j1n0Ao919h/Ai5r43VAnfV/7azUYW43GPxK7qSATzrsERfW7+y2QW9Cp9ufnRF5CQUWbnLSo7UJokSWCqg4tsQ==} + /terser@5.24.0: + resolution: {integrity: sha512-ZpGR4Hy3+wBEzVEnHvstMvqpD/nABNelQn/z2r0fjVWGQsN3bpOLzQlqDxmb4CDZnXq5lpjnQ+mHQLAOpfM5iw==} engines: {node: '>=10'} hasBin: true dependencies: - '@jridgewell/source-map': 0.3.3 - acorn: 8.9.0 + '@jridgewell/source-map': 0.3.5 + acorn: 8.11.2 commander: 2.20.3 source-map-support: 0.5.21 dev: true @@ -4546,6 +5773,15 @@ packages: minimatch: 3.1.2 dev: true + /through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + dev: true + + /to-fast-properties@1.0.3: + resolution: {integrity: sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og==} + engines: {node: '>=0.10.0'} + dev: true + /to-fast-properties@2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} @@ -4562,25 +5798,41 @@ packages: resolution: {integrity: sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==} dev: true + /tough-cookie@2.5.0: + resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==} + engines: {node: '>=0.8'} + requiresBuild: true + dependencies: + psl: 1.9.0 + punycode: 2.3.1 + dev: true + optional: true + /tough-cookie@4.1.3: resolution: {integrity: sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==} engines: {node: '>=6'} dependencies: psl: 1.9.0 - punycode: 2.3.0 + punycode: 2.3.1 universalify: 0.2.0 url-parse: 1.5.10 dev: true /tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + requiresBuild: true dev: true /tr46@4.1.1: resolution: {integrity: sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==} engines: {node: '>=14'} dependencies: - punycode: 2.3.0 + punycode: 2.3.1 + dev: true + + /trim-right@1.0.1: + resolution: {integrity: sha512-WZGXGstmCWgeevgTL54hrCuw1dyMQIzWy7ZfqRJfSmJZBwklI15egmQytFP6bPidmw3M8d5yEowl1niq4vmqZw==} + engines: {node: '>=0.10.0'} dev: true /ts-morph@17.0.1: @@ -4590,13 +5842,32 @@ packages: code-block-writer: 11.0.3 dev: true - /tslib@1.14.1: - resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + /tslib@2.6.2: + resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + dev: true + + /tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + requiresBuild: true + dependencies: + safe-buffer: 5.2.1 + dev: true + optional: true + + /tweetnacl@0.14.5: + resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} + requiresBuild: true dev: true + optional: true - /tslib@2.5.3: - resolution: {integrity: sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==} + /type-check@0.3.2: + resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==} + engines: {node: '>= 0.8.0'} + requiresBuild: true + dependencies: + prelude-ls: 1.1.2 dev: true + optional: true /type-detect@4.0.8: resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} @@ -4618,12 +5889,19 @@ packages: resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==} dev: true + /unbzip2-stream@1.4.3: + resolution: {integrity: sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==} + dependencies: + buffer: 5.7.1 + through: 2.3.8 + dev: true + /underscore@1.13.6: resolution: {integrity: sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==} dev: true - /universal-user-agent@6.0.0: - resolution: {integrity: sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==} + /undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} dev: true /universalify@0.1.2: @@ -4641,8 +5919,8 @@ packages: engines: {node: '>= 10.0.0'} dev: true - /update-browserslist-db@1.0.11(browserslist@4.21.9): - resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} + /update-browserslist-db@1.0.13(browserslist@4.21.9): + resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' @@ -4655,7 +5933,7 @@ packages: /uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: - punycode: 2.3.0 + punycode: 2.3.1 dev: true /url-exist@3.0.1: @@ -4683,6 +5961,10 @@ packages: qs: 6.11.2 dev: true + /urlpattern-polyfill@9.0.0: + resolution: {integrity: sha512-WHN8KDQblxd32odxeIgo83rdVDE2bvdkb86it7bMhYZwWKJz0+O0RK/eZiHYnM+zgt/U7hAHOlCQGfjjvSkw2g==} + dev: true + /util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} dev: true @@ -4693,43 +5975,62 @@ packages: inherits: 2.0.4 is-arguments: 1.1.1 is-generator-function: 1.0.10 - is-typed-array: 1.1.10 - which-typed-array: 1.1.9 + is-typed-array: 1.1.12 + which-typed-array: 1.1.13 dev: true - /v8-to-istanbul@9.1.0: - resolution: {integrity: sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==} + /uuid@3.4.0: + resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} + deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. + hasBin: true + requiresBuild: true + dev: true + optional: true + + /v8-to-istanbul@9.1.3: + resolution: {integrity: sha512-9lDD+EVI2fjFsMWXc6dy5JJzBsVTcQ2fVkfBvncZ6xJWG9wtBhOldG+mHkSL0+V1K/xgZz0JDO5UT5hFwHUghg==} engines: {node: '>=10.12.0'} dependencies: - '@jridgewell/trace-mapping': 0.3.18 - '@types/istanbul-lib-coverage': 2.0.4 - convert-source-map: 1.9.0 + '@jridgewell/trace-mapping': 0.3.20 + '@types/istanbul-lib-coverage': 2.0.5 + convert-source-map: 2.0.0 dev: true - /validator@13.9.0: - resolution: {integrity: sha512-B+dGG8U3fdtM0/aNK4/X8CXq/EcxU2WPrPEkJGslb47qyHsxmbggTWK0yEA4qnYVNF+nxNlN88o14hIcPmSIEA==} + /validator@13.11.0: + resolution: {integrity: sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==} engines: {node: '>= 0.10'} dev: true + /verror@1.10.0: + resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} + engines: {'0': node >=0.6.0} + requiresBuild: true + dependencies: + assert-plus: 1.0.0 + core-util-is: 1.0.2 + extsprintf: 1.3.0 + dev: true + optional: true + /vite-plugin-banner@0.7.0: resolution: {integrity: sha512-g0cm0wbrR6b6wR8FWtfD1RSDPacdumKEOAnneXv+NpJ9ez+j6rklRv6lMOO+aPf+Y6Zb8OzgIk0FXBZ6h+DeZQ==} dev: true - /vite-plugin-dts@1.7.3(@types/node@18.16.18)(vite@4.3.9): + /vite-plugin-dts@1.7.3(@types/node@18.18.8)(vite@4.3.9): resolution: {integrity: sha512-u3t45p6fTbzUPMkwYe0ESwuUeiRMlwdPfD3dRyDKUwLe2WmEYcFyVp2o9/ke2EMrM51lQcmNWdV9eLcgjD1/ng==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: vite: '>=2.9.0' dependencies: - '@microsoft/api-extractor': 7.35.4(@types/node@18.16.18) - '@rollup/pluginutils': 5.0.2 - '@rushstack/node-core-library': 3.59.4(@types/node@18.16.18) + '@microsoft/api-extractor': 7.38.1(@types/node@18.18.8) + '@rollup/pluginutils': 5.0.5 + '@rushstack/node-core-library': 3.61.0(@types/node@18.18.8) debug: 4.3.4(supports-color@8.1.1) - fast-glob: 3.2.12 + fast-glob: 3.3.1 fs-extra: 10.1.0 kolorist: 1.8.0 ts-morph: 17.0.1 - vite: 4.3.9(@types/node@18.16.18) + vite: 4.3.9(@types/node@18.18.8) transitivePeerDependencies: - '@types/node' - rollup @@ -4740,8 +6041,8 @@ packages: resolution: {integrity: sha512-67Abh1X9rhJq7u9Hxq9CJznM0acAPynvumkQ33wzvigW1aaPfsHNNMnhArABYryXnqASlmiZHpbhYOtDI9KfYw==} dependencies: '@wesbos/code-icons': 1.2.4 - vite: 4.3.9(@types/node@18.16.18) - vite-plugin-dts: 1.7.3(@types/node@18.16.18)(vite@4.3.9) + vite: 4.3.9(@types/node@18.18.8) + vite-plugin-dts: 1.7.3(@types/node@18.18.8)(vite@4.3.9) vscode-icons-js: 11.6.1 transitivePeerDependencies: - '@types/node' @@ -4760,26 +6061,10 @@ packages: vite: '*' dependencies: html-minifier-terser: 6.1.0 - vite: 4.3.9(@types/node@18.16.18) - dev: true - - /vite-plugin-mkcert@1.15.0(vite@4.3.9): - resolution: {integrity: sha512-0Pz7iExvo7pS2HsxMe6Y/HIrsFJidXN8Sju7tsL1XYQdbUKb/D0L5Wkj3UoGQmbbWZUFf8nHHa0XYbd4FH6ZrA==} - engines: {node: '>=v16.7.0'} - peerDependencies: - vite: '>=3' - dependencies: - '@octokit/rest': 19.0.13 - axios: 1.4.0(debug@4.3.4) - debug: 4.3.4(supports-color@8.1.1) - picocolors: 1.0.0 - vite: 4.3.9(@types/node@18.16.18) - transitivePeerDependencies: - - encoding - - supports-color + vite: 4.3.9(@types/node@18.18.8) dev: true - /vite@4.3.9(@types/node@18.16.18): + /vite@4.3.9(@types/node@18.18.8): resolution: {integrity: sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true @@ -4804,18 +6089,18 @@ packages: terser: optional: true dependencies: - '@types/node': 18.16.18 + '@types/node': 18.18.8 esbuild: 0.17.19 postcss: 8.4.24 - rollup: 3.25.1 + rollup: 3.29.4 optionalDependencies: - fsevents: 2.3.2 + fsevents: 2.3.3 dev: true /vscode-icons-js@11.6.1: resolution: {integrity: sha512-rht18IFYv117UlqBn6o9j258SOtwhDBmtVrGwdoLPpSj6Z5LKQIzarQDd/tCRWneU68KEX25+nsh48tAoknKNw==} dependencies: - '@types/jasmine': 3.10.9 + '@types/jasmine': 3.10.15 dev: true /w3c-xmlserializer@4.0.0: @@ -4833,12 +6118,18 @@ packages: /webcrypto-core@1.7.7: resolution: {integrity: sha512-7FjigXNsBfopEj+5DV2nhNpfic2vumtjjgPmeDKk45z+MJwXKKfhPB7118Pfzrmh4jqOMST6Ch37iPAHoImg5g==} dependencies: - '@peculiar/asn1-schema': 2.3.6 + '@peculiar/asn1-schema': 2.3.8 '@peculiar/json-schema': 1.1.12 asn1js: 3.0.5 - pvtsutils: 1.3.2 - tslib: 2.5.3 + pvtsutils: 1.3.5 + tslib: 2.6.2 + dev: true + + /webidl-conversions@2.0.1: + resolution: {integrity: sha512-OZ7I/f0sM+T28T2/OXinNGfmvjm3KKptdyQy8NPRZyLfYBn+9vt72Bfr+uQaE9OvWyxJjQ5kHFygH2wOTUb76g==} + requiresBuild: true dev: true + optional: true /webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} @@ -4861,6 +6152,14 @@ packages: engines: {node: '>=12'} dev: true + /whatwg-url-compat@0.6.5: + resolution: {integrity: sha512-vbg5+JVNwGtHRI3GheZGWrcUlxF9BXHbA80dLa+2XqJjlV/BK6upoi2j8dIRW9FGPUUyaMm7Hf1pTexHnsk85g==} + requiresBuild: true + dependencies: + tr46: 0.0.3 + dev: true + optional: true + /whatwg-url@12.0.1: resolution: {integrity: sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==} engines: {node: '>=14'} @@ -4880,16 +6179,15 @@ packages: resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} dev: true - /which-typed-array@1.1.9: - resolution: {integrity: sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==} + /which-typed-array@1.1.13: + resolution: {integrity: sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==} engines: {node: '>= 0.4'} dependencies: available-typed-arrays: 1.0.5 - call-bind: 1.0.2 + call-bind: 1.0.5 for-each: 0.3.3 gopd: 1.0.1 has-tostringtag: 1.0.0 - is-typed-array: 1.1.10 dev: true /which@2.0.2: @@ -4900,6 +6198,13 @@ packages: isexe: 2.0.0 dev: true + /word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + requiresBuild: true + dev: true + optional: true + /workerpool@6.2.1: resolution: {integrity: sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==} dev: true @@ -4957,6 +6262,25 @@ packages: optional: true dev: true + /ws@8.14.2: + resolution: {integrity: sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: true + + /xml-name-validator@2.0.1: + resolution: {integrity: sha512-jRKe/iQYMyVJpzPH+3HL97Lgu5HrCfii+qSo+TfjKHtOnvbnvdVfMYrn9Q34YV81M2e5sviJlI6Ko9y+nByzvA==} + requiresBuild: true + dev: true + optional: true + /xml-name-validator@4.0.0: resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} engines: {node: '>=12'} @@ -4987,8 +6311,8 @@ packages: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} dev: true - /yaml@2.3.1: - resolution: {integrity: sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==} + /yaml@2.3.3: + resolution: {integrity: sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==} engines: {node: '>= 14'} dev: true @@ -5017,6 +6341,11 @@ packages: engines: {node: '>=10'} dev: true + /yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + dev: true + /yargs-unparser@2.0.0: resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} engines: {node: '>=10'} @@ -5072,6 +6401,26 @@ packages: yargs-parser: 20.2.9 dev: true + /yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + dependencies: + cliui: 8.0.1 + escalade: 3.1.1 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + dev: true + + /yauzl@2.10.0: + resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} + dependencies: + buffer-crc32: 0.2.13 + fd-slicer: 1.1.0 + dev: true + /yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} @@ -5084,7 +6433,7 @@ packages: dependencies: lodash.get: 4.4.2 lodash.isequal: 4.5.0 - validator: 13.9.0 + validator: 13.11.0 optionalDependencies: commander: 9.5.0 dev: true diff --git a/project.mk b/project.mk deleted file mode 100644 index 37a79dfe9fdb0add93b768dab04f0c6a2975d8ea..0000000000000000000000000000000000000000 --- a/project.mk +++ /dev/null @@ -1,9 +0,0 @@ - - -## Project directory in which the Makefiles should be located -MAKEFILE_IMPORT_PATH=$(PROJECT_ROOT)development/makefiles/ - - - - - diff --git a/application/source/constants.mjs b/source/constants.mjs similarity index 100% rename from application/source/constants.mjs rename to source/constants.mjs diff --git a/application/source/constraints/abstract.mjs b/source/constraints/abstract.mjs similarity index 100% rename from application/source/constraints/abstract.mjs rename to source/constraints/abstract.mjs diff --git a/application/source/constraints/abstractoperator.mjs b/source/constraints/abstractoperator.mjs similarity index 100% rename from application/source/constraints/abstractoperator.mjs rename to source/constraints/abstractoperator.mjs diff --git a/application/source/constraints/andoperator.mjs b/source/constraints/andoperator.mjs similarity index 100% rename from application/source/constraints/andoperator.mjs rename to source/constraints/andoperator.mjs diff --git a/application/source/constraints/invalid.mjs b/source/constraints/invalid.mjs similarity index 100% rename from application/source/constraints/invalid.mjs rename to source/constraints/invalid.mjs diff --git a/application/source/constraints/isarray.mjs b/source/constraints/isarray.mjs similarity index 100% rename from application/source/constraints/isarray.mjs rename to source/constraints/isarray.mjs diff --git a/application/source/constraints/isobject.mjs b/source/constraints/isobject.mjs similarity index 100% rename from application/source/constraints/isobject.mjs rename to source/constraints/isobject.mjs diff --git a/application/source/constraints/namespace.mjs b/source/constraints/namespace.mjs similarity index 100% rename from application/source/constraints/namespace.mjs rename to source/constraints/namespace.mjs diff --git a/application/source/constraints/oroperator.mjs b/source/constraints/oroperator.mjs similarity index 100% rename from application/source/constraints/oroperator.mjs rename to source/constraints/oroperator.mjs diff --git a/application/source/constraints/valid.mjs b/source/constraints/valid.mjs similarity index 100% rename from application/source/constraints/valid.mjs rename to source/constraints/valid.mjs diff --git a/application/source/data/buildmap.mjs b/source/data/buildmap.mjs similarity index 100% rename from application/source/data/buildmap.mjs rename to source/data/buildmap.mjs diff --git a/application/source/data/buildtree.mjs b/source/data/buildtree.mjs similarity index 100% rename from application/source/data/buildtree.mjs rename to source/data/buildtree.mjs diff --git a/application/source/data/datasource.mjs b/source/data/datasource.mjs similarity index 100% rename from application/source/data/datasource.mjs rename to source/data/datasource.mjs diff --git a/application/source/data/datasource/dom.mjs b/source/data/datasource/dom.mjs similarity index 100% rename from application/source/data/datasource/dom.mjs rename to source/data/datasource/dom.mjs diff --git a/application/source/data/datasource/namespace.mjs b/source/data/datasource/namespace.mjs similarity index 100% rename from application/source/data/datasource/namespace.mjs rename to source/data/datasource/namespace.mjs diff --git a/application/source/data/datasource/server.mjs b/source/data/datasource/server.mjs similarity index 100% rename from application/source/data/datasource/server.mjs rename to source/data/datasource/server.mjs diff --git a/application/source/data/datasource/server/namespace.mjs b/source/data/datasource/server/namespace.mjs similarity index 100% rename from application/source/data/datasource/server/namespace.mjs rename to source/data/datasource/server/namespace.mjs diff --git a/application/source/data/datasource/server/restapi.mjs b/source/data/datasource/server/restapi.mjs similarity index 100% rename from application/source/data/datasource/server/restapi.mjs rename to source/data/datasource/server/restapi.mjs diff --git a/application/source/data/datasource/server/restapi/data-fetch-error.mjs b/source/data/datasource/server/restapi/data-fetch-error.mjs similarity index 100% rename from application/source/data/datasource/server/restapi/data-fetch-error.mjs rename to source/data/datasource/server/restapi/data-fetch-error.mjs diff --git a/application/source/data/datasource/server/restapi/namespace.mjs b/source/data/datasource/server/restapi/namespace.mjs similarity index 100% rename from application/source/data/datasource/server/restapi/namespace.mjs rename to source/data/datasource/server/restapi/namespace.mjs diff --git a/application/source/data/datasource/server/restapi/writeerror.mjs b/source/data/datasource/server/restapi/writeerror.mjs similarity index 100% rename from application/source/data/datasource/server/restapi/writeerror.mjs rename to source/data/datasource/server/restapi/writeerror.mjs diff --git a/application/source/data/datasource/server/webconnect.mjs b/source/data/datasource/server/webconnect.mjs similarity index 100% rename from application/source/data/datasource/server/webconnect.mjs rename to source/data/datasource/server/webconnect.mjs diff --git a/application/source/data/datasource/storage.mjs b/source/data/datasource/storage.mjs similarity index 100% rename from application/source/data/datasource/storage.mjs rename to source/data/datasource/storage.mjs diff --git a/application/source/data/datasource/storage/localstorage.mjs b/source/data/datasource/storage/localstorage.mjs similarity index 100% rename from application/source/data/datasource/storage/localstorage.mjs rename to source/data/datasource/storage/localstorage.mjs diff --git a/application/source/data/datasource/storage/namespace.mjs b/source/data/datasource/storage/namespace.mjs similarity index 100% rename from application/source/data/datasource/storage/namespace.mjs rename to source/data/datasource/storage/namespace.mjs diff --git a/application/source/data/datasource/storage/sessionstorage.mjs b/source/data/datasource/storage/sessionstorage.mjs similarity index 100% rename from application/source/data/datasource/storage/sessionstorage.mjs rename to source/data/datasource/storage/sessionstorage.mjs diff --git a/application/source/data/diff.mjs b/source/data/diff.mjs similarity index 100% rename from application/source/data/diff.mjs rename to source/data/diff.mjs diff --git a/application/source/data/extend.mjs b/source/data/extend.mjs similarity index 100% rename from application/source/data/extend.mjs rename to source/data/extend.mjs diff --git a/application/source/data/namespace.mjs b/source/data/namespace.mjs similarity index 100% rename from application/source/data/namespace.mjs rename to source/data/namespace.mjs diff --git a/application/source/data/pathfinder.mjs b/source/data/pathfinder.mjs similarity index 100% rename from application/source/data/pathfinder.mjs rename to source/data/pathfinder.mjs diff --git a/application/source/data/pipe.mjs b/source/data/pipe.mjs similarity index 100% rename from application/source/data/pipe.mjs rename to source/data/pipe.mjs diff --git a/application/source/data/transformer.mjs b/source/data/transformer.mjs similarity index 100% rename from application/source/data/transformer.mjs rename to source/data/transformer.mjs diff --git a/application/source/dom/assembler.mjs b/source/dom/assembler.mjs similarity index 100% rename from application/source/dom/assembler.mjs rename to source/dom/assembler.mjs diff --git a/application/source/dom/attributes.mjs b/source/dom/attributes.mjs similarity index 100% rename from application/source/dom/attributes.mjs rename to source/dom/attributes.mjs diff --git a/application/source/dom/constants.mjs b/source/dom/constants.mjs similarity index 100% rename from application/source/dom/constants.mjs rename to source/dom/constants.mjs diff --git a/application/source/dom/customcontrol.mjs b/source/dom/customcontrol.mjs similarity index 100% rename from application/source/dom/customcontrol.mjs rename to source/dom/customcontrol.mjs diff --git a/application/source/dom/customelement.mjs b/source/dom/customelement.mjs similarity index 100% rename from application/source/dom/customelement.mjs rename to source/dom/customelement.mjs diff --git a/application/source/dom/dimension.mjs b/source/dom/dimension.mjs similarity index 100% rename from application/source/dom/dimension.mjs rename to source/dom/dimension.mjs diff --git a/application/source/dom/events.mjs b/source/dom/events.mjs similarity index 100% rename from application/source/dom/events.mjs rename to source/dom/events.mjs diff --git a/application/source/dom/focusmanager.mjs b/source/dom/focusmanager.mjs similarity index 100% rename from application/source/dom/focusmanager.mjs rename to source/dom/focusmanager.mjs diff --git a/application/source/dom/locale.mjs b/source/dom/locale.mjs similarity index 100% rename from application/source/dom/locale.mjs rename to source/dom/locale.mjs diff --git a/application/source/dom/namespace.mjs b/source/dom/namespace.mjs similarity index 100% rename from application/source/dom/namespace.mjs rename to source/dom/namespace.mjs diff --git a/application/source/dom/ready.mjs b/source/dom/ready.mjs similarity index 100% rename from application/source/dom/ready.mjs rename to source/dom/ready.mjs diff --git a/application/source/dom/resource.mjs b/source/dom/resource.mjs similarity index 100% rename from application/source/dom/resource.mjs rename to source/dom/resource.mjs diff --git a/application/source/dom/resource/data.mjs b/source/dom/resource/data.mjs similarity index 100% rename from application/source/dom/resource/data.mjs rename to source/dom/resource/data.mjs diff --git a/application/source/dom/resource/link.mjs b/source/dom/resource/link.mjs similarity index 100% rename from application/source/dom/resource/link.mjs rename to source/dom/resource/link.mjs diff --git a/application/source/dom/resource/link/namespace.mjs b/source/dom/resource/link/namespace.mjs similarity index 100% rename from application/source/dom/resource/link/namespace.mjs rename to source/dom/resource/link/namespace.mjs diff --git a/application/source/dom/resource/link/stylesheet.mjs b/source/dom/resource/link/stylesheet.mjs similarity index 100% rename from application/source/dom/resource/link/stylesheet.mjs rename to source/dom/resource/link/stylesheet.mjs diff --git a/application/source/dom/resource/namespace.mjs b/source/dom/resource/namespace.mjs similarity index 100% rename from application/source/dom/resource/namespace.mjs rename to source/dom/resource/namespace.mjs diff --git a/application/source/dom/resource/script.mjs b/source/dom/resource/script.mjs similarity index 100% rename from application/source/dom/resource/script.mjs rename to source/dom/resource/script.mjs diff --git a/application/source/dom/resourcemanager.mjs b/source/dom/resourcemanager.mjs similarity index 100% rename from application/source/dom/resourcemanager.mjs rename to source/dom/resourcemanager.mjs diff --git a/application/source/dom/slotted.mjs b/source/dom/slotted.mjs similarity index 100% rename from application/source/dom/slotted.mjs rename to source/dom/slotted.mjs diff --git a/application/source/dom/template.mjs b/source/dom/template.mjs similarity index 100% rename from application/source/dom/template.mjs rename to source/dom/template.mjs diff --git a/application/source/dom/theme.mjs b/source/dom/theme.mjs similarity index 100% rename from application/source/dom/theme.mjs rename to source/dom/theme.mjs diff --git a/application/source/dom/updater.mjs b/source/dom/updater.mjs similarity index 100% rename from application/source/dom/updater.mjs rename to source/dom/updater.mjs diff --git a/application/source/dom/util.mjs b/source/dom/util.mjs similarity index 100% rename from application/source/dom/util.mjs rename to source/dom/util.mjs diff --git a/application/source/dom/util/extract-keys.mjs b/source/dom/util/extract-keys.mjs similarity index 100% rename from application/source/dom/util/extract-keys.mjs rename to source/dom/util/extract-keys.mjs diff --git a/application/source/dom/util/init-options-from-attributes.mjs b/source/dom/util/init-options-from-attributes.mjs similarity index 100% rename from application/source/dom/util/init-options-from-attributes.mjs rename to source/dom/util/init-options-from-attributes.mjs diff --git a/application/source/dom/util/set-option-from-attribute.mjs b/source/dom/util/set-option-from-attribute.mjs similarity index 100% rename from application/source/dom/util/set-option-from-attribute.mjs rename to source/dom/util/set-option-from-attribute.mjs diff --git a/application/source/dom/worker/factory.mjs b/source/dom/worker/factory.mjs similarity index 100% rename from application/source/dom/worker/factory.mjs rename to source/dom/worker/factory.mjs diff --git a/application/source/dom/worker/namespace.mjs b/source/dom/worker/namespace.mjs similarity index 100% rename from application/source/dom/worker/namespace.mjs rename to source/dom/worker/namespace.mjs diff --git a/application/source/i18n/formatter.mjs b/source/i18n/formatter.mjs similarity index 100% rename from application/source/i18n/formatter.mjs rename to source/i18n/formatter.mjs diff --git a/application/source/i18n/locale.mjs b/source/i18n/locale.mjs similarity index 100% rename from application/source/i18n/locale.mjs rename to source/i18n/locale.mjs diff --git a/application/source/i18n/namespace.mjs b/source/i18n/namespace.mjs similarity index 100% rename from application/source/i18n/namespace.mjs rename to source/i18n/namespace.mjs diff --git a/application/source/i18n/provider.mjs b/source/i18n/provider.mjs similarity index 100% rename from application/source/i18n/provider.mjs rename to source/i18n/provider.mjs diff --git a/application/source/i18n/providers/embed.mjs b/source/i18n/providers/embed.mjs similarity index 100% rename from application/source/i18n/providers/embed.mjs rename to source/i18n/providers/embed.mjs diff --git a/application/source/i18n/providers/fetch.mjs b/source/i18n/providers/fetch.mjs similarity index 100% rename from application/source/i18n/providers/fetch.mjs rename to source/i18n/providers/fetch.mjs diff --git a/application/source/i18n/providers/namespace.mjs b/source/i18n/providers/namespace.mjs similarity index 100% rename from application/source/i18n/providers/namespace.mjs rename to source/i18n/providers/namespace.mjs diff --git a/application/source/i18n/translations.mjs b/source/i18n/translations.mjs similarity index 100% rename from application/source/i18n/translations.mjs rename to source/i18n/translations.mjs diff --git a/application/source/logging/handler.mjs b/source/logging/handler.mjs similarity index 100% rename from application/source/logging/handler.mjs rename to source/logging/handler.mjs diff --git a/application/source/logging/handler/console.mjs b/source/logging/handler/console.mjs similarity index 100% rename from application/source/logging/handler/console.mjs rename to source/logging/handler/console.mjs diff --git a/application/source/logging/handler/namespace.mjs b/source/logging/handler/namespace.mjs similarity index 100% rename from application/source/logging/handler/namespace.mjs rename to source/logging/handler/namespace.mjs diff --git a/application/source/logging/logentry.mjs b/source/logging/logentry.mjs similarity index 100% rename from application/source/logging/logentry.mjs rename to source/logging/logentry.mjs diff --git a/application/source/logging/logger.mjs b/source/logging/logger.mjs similarity index 100% rename from application/source/logging/logger.mjs rename to source/logging/logger.mjs diff --git a/application/source/logging/namespace.mjs b/source/logging/namespace.mjs similarity index 100% rename from application/source/logging/namespace.mjs rename to source/logging/namespace.mjs diff --git a/application/source/math/namespace.mjs b/source/math/namespace.mjs similarity index 100% rename from application/source/math/namespace.mjs rename to source/math/namespace.mjs diff --git a/application/source/math/random.mjs b/source/math/random.mjs similarity index 100% rename from application/source/math/random.mjs rename to source/math/random.mjs diff --git a/source/monster.mjs b/source/monster.mjs new file mode 100644 index 0000000000000000000000000000000000000000..f150069521f0ce4f56a60509ddbfedaa27f06cde --- /dev/null +++ b/source/monster.mjs @@ -0,0 +1,131 @@ + +/** + * Copyright schukai GmbH and contributors 2023. All Rights Reserved. + * Node module: @schukai/monster + * This file is licensed under the AGPLv3 License. + * License text available at https://www.gnu.org/licenses/agpl-3.0.en.html + * SPDX-License-Identifier: AGPL-3.0-only or COMMERCIAL + */ + +/** THIS FILE IS AUTOGENERATED AND SHOULD NOT BE EDITED DIRECTLY. **/ + +/** + * Main namespace for Monster. + * + * @namespace Monster + * @author schukai GmbH + */ + +export * from "./text/formatter.mjs" +export * from "./text/generate-range-comparison-expression.mjs" +export * from "./text/util.mjs" +export * from "./text/bracketed-key-value-hash.mjs" +export * from "./math/random.mjs" +export * from "./util/trimspaces.mjs" +export * from "./util/processing.mjs" +export * from "./util/runtime.mjs" +export * from "./util/deadmansswitch.mjs" +export * from "./util/comparator.mjs" +export * from "./util/freeze.mjs" +export * from "./util/clone.mjs" +export * from "./logging/handler/console.mjs" +export * from "./logging/logger.mjs" +export * from "./logging/handler.mjs" +export * from "./logging/logentry.mjs" +export * from "./net/webconnect.mjs" +export * from "./net/webconnect/message.mjs" +export * from "./constraints/invalid.mjs" +export * from "./constraints/abstractoperator.mjs" +export * from "./constraints/oroperator.mjs" +export * from "./constraints/isobject.mjs" +export * from "./constraints/andoperator.mjs" +export * from "./constraints/isarray.mjs" +export * from "./constraints/abstract.mjs" +export * from "./constraints/valid.mjs" +export * from "./dom/dimension.mjs" +export * from "./dom/resource/link/stylesheet.mjs" +export * from "./dom/resource/link.mjs" +export * from "./dom/resource/script.mjs" +export * from "./dom/resource/data.mjs" +export * from "./dom/util/init-options-from-attributes.mjs" +export * from "./dom/util/set-option-from-attribute.mjs" +export * from "./dom/util/extract-keys.mjs" +export * from "./dom/worker/factory.mjs" +export * from "./dom/updater.mjs" +export * from "./dom/locale.mjs" +export * from "./dom/theme.mjs" +export * from "./dom/customelement.mjs" +export * from "./dom/slotted.mjs" +export * from "./dom/focusmanager.mjs" +export * from "./dom/ready.mjs" +export * from "./dom/util.mjs" +export * from "./dom/attributes.mjs" +export * from "./dom/resource.mjs" +export * from "./dom/resourcemanager.mjs" +export * from "./dom/assembler.mjs" +export * from "./dom/customcontrol.mjs" +export * from "./dom/template.mjs" +export * from "./dom/constants.mjs" +export * from "./dom/events.mjs" +export * from "./data/datasource/dom.mjs" +export * from "./data/datasource/storage/localstorage.mjs" +export * from "./data/datasource/storage/sessionstorage.mjs" +export * from "./data/datasource/storage.mjs" +export * from "./data/datasource/server.mjs" +export * from "./data/datasource/server/restapi/data-fetch-error.mjs" +export * from "./data/datasource/server/restapi/writeerror.mjs" +export * from "./data/datasource/server/webconnect.mjs" +export * from "./data/datasource/server/restapi.mjs" +export * from "./data/datasource.mjs" +export * from "./data/buildmap.mjs" +export * from "./data/transformer.mjs" +export * from "./data/diff.mjs" +export * from "./data/buildtree.mjs" +export * from "./data/pathfinder.mjs" +export * from "./data/pipe.mjs" +export * from "./data/extend.mjs" +export * from "./types/nodelist.mjs" +export * from "./types/base.mjs" +export * from "./types/mediatype.mjs" +export * from "./types/tokenlist.mjs" +export * from "./types/proxyobserver.mjs" +export * from "./types/version.mjs" +export * from "./types/global.mjs" +export * from "./types/observerlist.mjs" +export * from "./types/internal.mjs" +export * from "./types/observablequeue.mjs" +export * from "./types/dataurl.mjs" +export * from "./types/binary.mjs" +export * from "./types/observer.mjs" +export * from "./types/regex.mjs" +export * from "./types/randomid.mjs" +export * from "./types/id.mjs" +export * from "./types/uuid.mjs" +export * from "./types/is.mjs" +export * from "./types/validate.mjs" +export * from "./types/typeof.mjs" +export * from "./types/uniquequeue.mjs" +export * from "./types/stack.mjs" +export * from "./types/basewithoptions.mjs" +export * from "./types/node.mjs" +export * from "./types/queue.mjs" +export * from "./types/noderecursiveiterator.mjs" +export * from "./i18n/formatter.mjs" +export * from "./i18n/locale.mjs" +export * from "./i18n/provider.mjs" +export * from "./i18n/providers/fetch.mjs" +export * from "./i18n/providers/embed.mjs" +export * from "./i18n/translations.mjs" +export * from "./constants.mjs" + +export { Monster }; + +/** + * This class has no other purpose than to exist. + * + * @license AGPLv3 + * @since 2.0.0 + * @copyright schukai GmbH + * @memberOf Monster + */ +class Monster {} diff --git a/application/source/net/namespace.mjs b/source/net/namespace.mjs similarity index 100% rename from application/source/net/namespace.mjs rename to source/net/namespace.mjs diff --git a/application/source/net/webconnect.mjs b/source/net/webconnect.mjs similarity index 100% rename from application/source/net/webconnect.mjs rename to source/net/webconnect.mjs diff --git a/application/source/net/webconnect/message.mjs b/source/net/webconnect/message.mjs similarity index 100% rename from application/source/net/webconnect/message.mjs rename to source/net/webconnect/message.mjs diff --git a/application/source/net/webconnect/namespace.mjs b/source/net/webconnect/namespace.mjs similarity index 100% rename from application/source/net/webconnect/namespace.mjs rename to source/net/webconnect/namespace.mjs diff --git a/application/source/text/bracketed-key-value-hash.mjs b/source/text/bracketed-key-value-hash.mjs similarity index 100% rename from application/source/text/bracketed-key-value-hash.mjs rename to source/text/bracketed-key-value-hash.mjs diff --git a/application/source/text/formatter.mjs b/source/text/formatter.mjs similarity index 100% rename from application/source/text/formatter.mjs rename to source/text/formatter.mjs diff --git a/application/source/text/generate-range-comparison-expression.mjs b/source/text/generate-range-comparison-expression.mjs similarity index 100% rename from application/source/text/generate-range-comparison-expression.mjs rename to source/text/generate-range-comparison-expression.mjs diff --git a/application/source/text/namespace.mjs b/source/text/namespace.mjs similarity index 100% rename from application/source/text/namespace.mjs rename to source/text/namespace.mjs diff --git a/application/source/text/util.mjs b/source/text/util.mjs similarity index 100% rename from application/source/text/util.mjs rename to source/text/util.mjs diff --git a/application/source/types/base.mjs b/source/types/base.mjs similarity index 100% rename from application/source/types/base.mjs rename to source/types/base.mjs diff --git a/application/source/types/basewithoptions.mjs b/source/types/basewithoptions.mjs similarity index 100% rename from application/source/types/basewithoptions.mjs rename to source/types/basewithoptions.mjs diff --git a/application/source/types/binary.mjs b/source/types/binary.mjs similarity index 100% rename from application/source/types/binary.mjs rename to source/types/binary.mjs diff --git a/application/source/types/dataurl.mjs b/source/types/dataurl.mjs similarity index 100% rename from application/source/types/dataurl.mjs rename to source/types/dataurl.mjs diff --git a/application/source/types/global.mjs b/source/types/global.mjs similarity index 100% rename from application/source/types/global.mjs rename to source/types/global.mjs diff --git a/application/source/types/id.mjs b/source/types/id.mjs similarity index 100% rename from application/source/types/id.mjs rename to source/types/id.mjs diff --git a/application/source/types/internal.mjs b/source/types/internal.mjs similarity index 100% rename from application/source/types/internal.mjs rename to source/types/internal.mjs diff --git a/application/source/types/is.mjs b/source/types/is.mjs similarity index 100% rename from application/source/types/is.mjs rename to source/types/is.mjs diff --git a/application/source/types/mediatype.mjs b/source/types/mediatype.mjs similarity index 100% rename from application/source/types/mediatype.mjs rename to source/types/mediatype.mjs diff --git a/application/source/types/namespace.mjs b/source/types/namespace.mjs similarity index 100% rename from application/source/types/namespace.mjs rename to source/types/namespace.mjs diff --git a/application/source/types/node.mjs b/source/types/node.mjs similarity index 100% rename from application/source/types/node.mjs rename to source/types/node.mjs diff --git a/application/source/types/nodelist.mjs b/source/types/nodelist.mjs similarity index 100% rename from application/source/types/nodelist.mjs rename to source/types/nodelist.mjs diff --git a/application/source/types/noderecursiveiterator.mjs b/source/types/noderecursiveiterator.mjs similarity index 100% rename from application/source/types/noderecursiveiterator.mjs rename to source/types/noderecursiveiterator.mjs diff --git a/application/source/types/observablequeue.mjs b/source/types/observablequeue.mjs similarity index 100% rename from application/source/types/observablequeue.mjs rename to source/types/observablequeue.mjs diff --git a/application/source/types/observer.mjs b/source/types/observer.mjs similarity index 100% rename from application/source/types/observer.mjs rename to source/types/observer.mjs diff --git a/application/source/types/observerlist.mjs b/source/types/observerlist.mjs similarity index 100% rename from application/source/types/observerlist.mjs rename to source/types/observerlist.mjs diff --git a/application/source/types/proxyobserver.mjs b/source/types/proxyobserver.mjs similarity index 100% rename from application/source/types/proxyobserver.mjs rename to source/types/proxyobserver.mjs diff --git a/application/source/types/queue.mjs b/source/types/queue.mjs similarity index 100% rename from application/source/types/queue.mjs rename to source/types/queue.mjs diff --git a/application/source/types/randomid.mjs b/source/types/randomid.mjs similarity index 100% rename from application/source/types/randomid.mjs rename to source/types/randomid.mjs diff --git a/application/source/types/regex.mjs b/source/types/regex.mjs similarity index 100% rename from application/source/types/regex.mjs rename to source/types/regex.mjs diff --git a/application/source/types/stack.mjs b/source/types/stack.mjs similarity index 100% rename from application/source/types/stack.mjs rename to source/types/stack.mjs diff --git a/application/source/types/tokenlist.mjs b/source/types/tokenlist.mjs similarity index 100% rename from application/source/types/tokenlist.mjs rename to source/types/tokenlist.mjs diff --git a/application/source/types/typeof.mjs b/source/types/typeof.mjs similarity index 100% rename from application/source/types/typeof.mjs rename to source/types/typeof.mjs diff --git a/application/source/types/uniquequeue.mjs b/source/types/uniquequeue.mjs similarity index 100% rename from application/source/types/uniquequeue.mjs rename to source/types/uniquequeue.mjs diff --git a/application/source/types/uuid.mjs b/source/types/uuid.mjs similarity index 100% rename from application/source/types/uuid.mjs rename to source/types/uuid.mjs diff --git a/application/source/types/validate.mjs b/source/types/validate.mjs similarity index 100% rename from application/source/types/validate.mjs rename to source/types/validate.mjs diff --git a/application/source/types/version.mjs b/source/types/version.mjs similarity index 100% rename from application/source/types/version.mjs rename to source/types/version.mjs diff --git a/application/source/util/clone.mjs b/source/util/clone.mjs similarity index 100% rename from application/source/util/clone.mjs rename to source/util/clone.mjs diff --git a/application/source/util/comparator.mjs b/source/util/comparator.mjs similarity index 100% rename from application/source/util/comparator.mjs rename to source/util/comparator.mjs diff --git a/application/source/util/deadmansswitch.mjs b/source/util/deadmansswitch.mjs similarity index 100% rename from application/source/util/deadmansswitch.mjs rename to source/util/deadmansswitch.mjs diff --git a/application/source/util/freeze.mjs b/source/util/freeze.mjs similarity index 100% rename from application/source/util/freeze.mjs rename to source/util/freeze.mjs diff --git a/application/source/util/namespace.mjs b/source/util/namespace.mjs similarity index 100% rename from application/source/util/namespace.mjs rename to source/util/namespace.mjs diff --git a/application/source/util/processing.mjs b/source/util/processing.mjs similarity index 100% rename from application/source/util/processing.mjs rename to source/util/processing.mjs diff --git a/application/source/util/runtime.mjs b/source/util/runtime.mjs similarity index 100% rename from application/source/util/runtime.mjs rename to source/util/runtime.mjs diff --git a/application/source/util/trimspaces.mjs b/source/util/trimspaces.mjs similarity index 100% rename from application/source/util/trimspaces.mjs rename to source/util/trimspaces.mjs diff --git a/development/test/cases/constraint/abstractoperator.mjs b/test/cases/constraint/abstractoperator.mjs similarity index 81% rename from development/test/cases/constraint/abstractoperator.mjs rename to test/cases/constraint/abstractoperator.mjs index 1eb6ea7e3ee5870fa794af4c426e13586d6763fa..27e7d924e3359973ae897d5f8a7594e22519937a 100644 --- a/development/test/cases/constraint/abstractoperator.mjs +++ b/test/cases/constraint/abstractoperator.mjs @@ -1,5 +1,5 @@ -import {Base} from "../../../../application/source/types/base.mjs"; -import {AbstractOperator} from "../../../../application/source/constraints/abstractoperator.mjs"; +import {Base} from "../../../source/types/base.mjs"; +import {AbstractOperator} from "../../../source/constraints/abstractoperator.mjs"; import {expect} from "chai" class AbstractConstraintMock extends Base { diff --git a/development/test/cases/constraint/andoperator.mjs b/test/cases/constraint/andoperator.mjs similarity index 77% rename from development/test/cases/constraint/andoperator.mjs rename to test/cases/constraint/andoperator.mjs index 49efd093f46e9d2dbeca14ce6ecc0c38a5c66eac..80109b208be98b47576c89c9cd3b228b4e27e590 100644 --- a/development/test/cases/constraint/andoperator.mjs +++ b/test/cases/constraint/andoperator.mjs @@ -1,6 +1,6 @@ -import {Valid} from "../../../../application/source/constraints/valid.mjs"; -import {Invalid} from "../../../../application/source/constraints/invalid.mjs"; -import {AndOperator} from "../../../../application/source/constraints/andoperator.mjs"; +import {Valid} from "../../../source/constraints/valid.mjs"; +import {Invalid} from "../../../source/constraints/invalid.mjs"; +import {AndOperator} from "../../../source/constraints/andoperator.mjs"; describe('AndOperator', function () { diff --git a/development/test/cases/constraint/invalid.mjs b/test/cases/constraint/invalid.mjs similarity index 81% rename from development/test/cases/constraint/invalid.mjs rename to test/cases/constraint/invalid.mjs index 6afcd38d5a53305dad987551d9fc0ef9afece77d..ce9e8f32869f176a534d9930a4aa39d5a5f7af7b 100644 --- a/development/test/cases/constraint/invalid.mjs +++ b/test/cases/constraint/invalid.mjs @@ -1,4 +1,4 @@ -import {Invalid} from "../../../../application/source/constraints/invalid.mjs"; +import {Invalid} from "../../../source/constraints/invalid.mjs"; import {expect} from "chai" describe('Invalid', function () { diff --git a/development/test/cases/constraint/isarray.mjs b/test/cases/constraint/isarray.mjs similarity index 84% rename from development/test/cases/constraint/isarray.mjs rename to test/cases/constraint/isarray.mjs index 6973902ea6dfe75cd66e930d0d3de4e20e51a84a..99b3d8c27454cdab99fdfefa7867c5919b239ea7 100644 --- a/development/test/cases/constraint/isarray.mjs +++ b/test/cases/constraint/isarray.mjs @@ -1,4 +1,4 @@ -import {IsArray} from "../../../../application/source/constraints/isarray.mjs"; +import {IsArray} from "../../../source/constraints/isarray.mjs"; import {expect} from "chai" describe('IsArray', function () { diff --git a/development/test/cases/constraint/isobject.mjs b/test/cases/constraint/isobject.mjs similarity index 84% rename from development/test/cases/constraint/isobject.mjs rename to test/cases/constraint/isobject.mjs index a9a5afd9549b9097aecb0c1cc61cb5aebaa7ce9f..7a551e2cb19bb5f95efedddafff2d1af7a8d9400 100644 --- a/development/test/cases/constraint/isobject.mjs +++ b/test/cases/constraint/isobject.mjs @@ -1,4 +1,4 @@ -import {IsObject} from "../../../../application/source/constraints/isobject.mjs"; +import {IsObject} from "../../../source/constraints/isobject.mjs"; import {expect} from "chai" describe('IsObject', function () { diff --git a/development/test/cases/constraint/oroperator.mjs b/test/cases/constraint/oroperator.mjs similarity index 77% rename from development/test/cases/constraint/oroperator.mjs rename to test/cases/constraint/oroperator.mjs index d430d672c3f212170d5f8fd0122e5631b77d3775..92401f7393e45fcccf8f155ab274d4027eccb9dc 100644 --- a/development/test/cases/constraint/oroperator.mjs +++ b/test/cases/constraint/oroperator.mjs @@ -1,6 +1,6 @@ -import {Valid} from "../../../../application/source/constraints/valid.mjs"; -import {Invalid} from "../../../../application/source/constraints/invalid.mjs"; -import {OrOperator} from "../../../../application/source/constraints/oroperator.mjs"; +import {Valid} from "../../../source/constraints/valid.mjs"; +import {Invalid} from "../../../source/constraints/invalid.mjs"; +import {OrOperator} from "../../../source/constraints/oroperator.mjs"; describe('OrOperator', function () { diff --git a/development/test/cases/constraint/valid.mjs b/test/cases/constraint/valid.mjs similarity index 83% rename from development/test/cases/constraint/valid.mjs rename to test/cases/constraint/valid.mjs index 3c2a692e5f616dd07dd871b91ae3a99d4e6ad408..74c790a411198def15aba3e57c8f50018d3f17e6 100644 --- a/development/test/cases/constraint/valid.mjs +++ b/test/cases/constraint/valid.mjs @@ -1,4 +1,4 @@ -import {Valid} from "../../../../application/source/constraints/valid.mjs"; +import {Valid} from "../../../source/constraints/valid.mjs"; import {expect} from "chai" describe('Valid', function () { diff --git a/development/test/cases/data/buildmap.mjs b/test/cases/data/buildmap.mjs similarity index 99% rename from development/test/cases/data/buildmap.mjs rename to test/cases/data/buildmap.mjs index d0b6d8d62119d2ebd25ee5cce635a458ce932ca5..63a05113b549325fea6e60aeaee715ffded358b8 100644 --- a/development/test/cases/data/buildmap.mjs +++ b/test/cases/data/buildmap.mjs @@ -1,7 +1,7 @@ "use strict"; import {expect} from "chai" -import {buildMap} from "../../../../application/source/data/buildmap.mjs"; +import {buildMap} from "../../../source/data/buildmap.mjs"; describe('buildMap', function () { diff --git a/development/test/cases/data/buildtree.mjs b/test/cases/data/buildtree.mjs similarity index 97% rename from development/test/cases/data/buildtree.mjs rename to test/cases/data/buildtree.mjs index 11ea56f5d3d9cee01c41a81e8ad117a7a5e10dcc..e6ff5aa1959d25b59474eb2ae84cabedbd83c35d 100644 --- a/development/test/cases/data/buildtree.mjs +++ b/test/cases/data/buildtree.mjs @@ -1,8 +1,8 @@ "use strict"; import {expect} from "chai" -import {buildTree} from "../../../../application/source/data/buildtree.mjs"; -import {NodeList} from "../../../../application/source/types/nodelist.mjs"; +import {buildTree} from "../../../source/data/buildtree.mjs"; +import {NodeList} from "../../../source/types/nodelist.mjs"; describe('buildTree', function () { diff --git a/development/test/cases/data/datasource.mjs b/test/cases/data/datasource.mjs similarity index 95% rename from development/test/cases/data/datasource.mjs rename to test/cases/data/datasource.mjs index 5d4005d846620a405666a153deff223b610e1c35..130b505e499410d6c6db7f75b1a41f68e2e10e35 100644 --- a/development/test/cases/data/datasource.mjs +++ b/test/cases/data/datasource.mjs @@ -1,7 +1,7 @@ "use strict"; import {expect} from "chai" -import {Datasource} from "../../../../application/source/data/datasource.mjs"; +import {Datasource} from "../../../source/data/datasource.mjs"; describe('Datasource', function () { diff --git a/development/test/cases/data/datasource/dom.mjs b/test/cases/data/datasource/dom.mjs similarity index 71% rename from development/test/cases/data/datasource/dom.mjs rename to test/cases/data/datasource/dom.mjs index 02258e42cd7c326c6072ecee64e1121cf61bd290..0137aec79bebcf72502687f8b227f447a18c0acf 100644 --- a/development/test/cases/data/datasource/dom.mjs +++ b/test/cases/data/datasource/dom.mjs @@ -1,5 +1,5 @@ import {expect} from "chai" -import {DomStorage} from "../../../../../application/source/data/datasource/dom.mjs"; +import {DomStorage} from "../../../../source/data/datasource/dom.mjs"; describe('ServeDomr', function () { diff --git a/development/test/cases/data/datasource/server.mjs b/test/cases/data/datasource/server.mjs similarity index 94% rename from development/test/cases/data/datasource/server.mjs rename to test/cases/data/datasource/server.mjs index 14f3d85145d2462a93d5927c2b8a5f4df24151bf..643d22446d0e69770c5b2abdd847a318609c4fae 100644 --- a/development/test/cases/data/datasource/server.mjs +++ b/test/cases/data/datasource/server.mjs @@ -1,5 +1,5 @@ import {expect} from "chai" -import {Server} from "../../../../../application/source/data/datasource/server.mjs"; +import {Server} from "../../../../source/data/datasource/server.mjs"; describe('Server', function () { diff --git a/development/test/cases/data/datasource/server/restapi.mjs b/test/cases/data/datasource/server/restapi.mjs similarity index 93% rename from development/test/cases/data/datasource/server/restapi.mjs rename to test/cases/data/datasource/server/restapi.mjs index d9958d50f7332bb28d48ce01eba76d6b03737be5..673d0f4d8278cb28f0594ec10df8deca8ec5f77a 100644 --- a/development/test/cases/data/datasource/server/restapi.mjs +++ b/test/cases/data/datasource/server/restapi.mjs @@ -1,8 +1,8 @@ "use strict"; import {expect} from "chai" -import {RestAPI} from "../../../../../../application/source/data/datasource/server/restapi.mjs"; -import {validateObject} from "../../../../../../application/source/types/validate.mjs"; +import {RestAPI} from "../../../../../source/data/datasource/server/restapi.mjs"; +import {validateObject} from "../../../../../source/types/validate.mjs"; describe('RestAPI', function () { diff --git a/development/test/cases/data/datasource/server/websocket.mjs b/test/cases/data/datasource/server/websocket.mjs similarity index 97% rename from development/test/cases/data/datasource/server/websocket.mjs rename to test/cases/data/datasource/server/websocket.mjs index aeb11a04930bb6f0b96196823a43f6f38bd0cdfd..33be357b2ea2ba19414060fe72faa289ffa5ea07 100644 --- a/development/test/cases/data/datasource/server/websocket.mjs +++ b/test/cases/data/datasource/server/websocket.mjs @@ -1,5 +1,5 @@ import {expect} from "chai" -import {WebConnect} from "../../../../../../application/source/data/datasource/server/webconnect.mjs"; +import {WebConnect} from "../../../../../source/data/datasource/server/webconnect.mjs"; import {initWebSocket} from "../../../../util/websocket.mjs"; const testUrl = "wss://ws.postman-echo.com/raw" diff --git a/development/test/cases/data/datasource/storage/localstorage.mjs b/test/cases/data/datasource/storage/localstorage.mjs similarity index 90% rename from development/test/cases/data/datasource/storage/localstorage.mjs rename to test/cases/data/datasource/storage/localstorage.mjs index f0e548d4dff78cb55473920d4b7b15c1c01b885e..e162936c9813335840b48c3eeb0cc8c7345d33b1 100644 --- a/development/test/cases/data/datasource/storage/localstorage.mjs +++ b/test/cases/data/datasource/storage/localstorage.mjs @@ -1,7 +1,7 @@ "use strict"; import {expect} from "chai" -import {LocalStorage} from "../../../../../../application/source/data/datasource/storage/localstorage.mjs"; +import {LocalStorage} from "../../../../../source/data/datasource/storage/localstorage.mjs"; import {createStorage} from "../../../../util/localstorage.mjs"; diff --git a/development/test/cases/data/datasource/storage/sessionstorage.mjs b/test/cases/data/datasource/storage/sessionstorage.mjs similarity index 90% rename from development/test/cases/data/datasource/storage/sessionstorage.mjs rename to test/cases/data/datasource/storage/sessionstorage.mjs index db8df471aaa727113b511bca217d83dd8f116d2e..7f07355608814a038d2489115b6d51dcbf8975a8 100644 --- a/development/test/cases/data/datasource/storage/sessionstorage.mjs +++ b/test/cases/data/datasource/storage/sessionstorage.mjs @@ -1,7 +1,7 @@ "use strict"; import {expect} from "chai" -import {SessionStorage} from "../../../../../../application/source/data/datasource/storage/sessionstorage.mjs"; +import {SessionStorage} from "../../../../../source/data/datasource/storage/sessionstorage.mjs"; import {createStorage} from "../../../../util/localstorage.mjs"; diff --git a/development/test/cases/data/diff.mjs b/test/cases/data/diff.mjs similarity index 97% rename from development/test/cases/data/diff.mjs rename to test/cases/data/diff.mjs index d102907fc802d0ab1b9c4d8c8153675b40268233..5013de024de448b158950c6332c1d50dd25cc702 100644 --- a/development/test/cases/data/diff.mjs +++ b/test/cases/data/diff.mjs @@ -1,8 +1,8 @@ "use strict"; import {expect} from "chai" -import {diff} from "../../../../application/source/data/diff.mjs"; -import {Queue} from "../../../../application/source/types/queue.mjs"; +import {diff} from "../../../source/data/diff.mjs"; +import {Queue} from "../../../source/types/queue.mjs"; describe('Diff', function () { diff --git a/development/test/cases/data/extend.mjs b/test/cases/data/extend.mjs similarity index 96% rename from development/test/cases/data/extend.mjs rename to test/cases/data/extend.mjs index e024274a70c82f8e9097251575ff6cc1b7b970b5..6255b28857a8f472b76998f47f9a3d42ce76dd09 100644 --- a/development/test/cases/data/extend.mjs +++ b/test/cases/data/extend.mjs @@ -1,6 +1,6 @@ "use strict"; -import {extend} from "../../../../application/source/data/extend.mjs"; +import {extend} from "../../../source/data/extend.mjs"; import {expect} from "chai" class MockForExtends { diff --git a/development/test/cases/data/pathfinder.mjs b/test/cases/data/pathfinder.mjs similarity index 99% rename from development/test/cases/data/pathfinder.mjs rename to test/cases/data/pathfinder.mjs index 82db2b4836db5155f4458c6c9c825fc8f16cdab2..c3ccc0d043483e5a36c58327e898a820cc2e4a9b 100644 --- a/development/test/cases/data/pathfinder.mjs +++ b/test/cases/data/pathfinder.mjs @@ -1,7 +1,7 @@ "use strict"; import {expect} from "chai" -import {Pathfinder} from "../../../../application/source/data/pathfinder.mjs"; +import {Pathfinder} from "../../../source/data/pathfinder.mjs"; describe('Pathfinder', function () { diff --git a/development/test/cases/data/pipe.mjs b/test/cases/data/pipe.mjs similarity index 96% rename from development/test/cases/data/pipe.mjs rename to test/cases/data/pipe.mjs index 5539e7dc00ffe65e93be0bc5f99b41414b902e82..2e40efd300a0c626800b5ab30b0a944a571725d0 100644 --- a/development/test/cases/data/pipe.mjs +++ b/test/cases/data/pipe.mjs @@ -1,9 +1,9 @@ "use strict"; import {expect} from "chai" -import {Pipe} from "../../../../application/source/data/pipe.mjs"; +import {Pipe} from "../../../source/data/pipe.mjs"; import {initJSDOM} from "../../util/jsdom.mjs"; -import {Embed} from "../../../../application/source/i18n/providers/embed.mjs"; +import {Embed} from "../../../source/i18n/providers/embed.mjs"; describe('Pipe', function () { diff --git a/development/test/cases/data/transformer.mjs b/test/cases/data/transformer.mjs similarity index 97% rename from development/test/cases/data/transformer.mjs rename to test/cases/data/transformer.mjs index 6ad0d73c5cf1ac7b9aadd1525d8c974b75c20eda..0f21d47fa24112a24a415c5f2b95d6281e551965 100644 --- a/development/test/cases/data/transformer.mjs +++ b/test/cases/data/transformer.mjs @@ -1,8 +1,8 @@ "use strict"; import {expect} from "chai" -import {Transformer} from "../../../../application/source/data/transformer.mjs"; -import {Embed} from "../../../../application/source/i18n/providers/embed.mjs"; +import {Transformer} from "../../../source/data/transformer.mjs"; +import {Embed} from "../../../source/i18n/providers/embed.mjs"; import {initJSDOM} from "../../util/jsdom.mjs"; describe('Transformer', function () { @@ -51,7 +51,7 @@ describe('Transformer', function () { ['equals:null', 3, false], ['equals:3', 6, false], ['currency', "EUR0", "0,00 €"], - ['currency:1:2', "EUR14.25", "14,2 €"], + // ['currency:1:2', "EUR14.25", "14,2 €"], nodejs and browser have different results (https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/124) ['currency', "EUR14.25", "14,25 €"], ['datetime', "2023-02-14 14:12:10", "14.2.2023, 14:12:10"], ['datetime', "2023-02-14 08:02:01", "14.2.2023, 08:02:01"], @@ -235,7 +235,6 @@ describe('Transformer', function () { }); - describe('new Transformer().run("uniqid")', function () { it('should return String', function () { let t = new Transformer('uniqid'); diff --git a/development/test/cases/dom/assembler.mjs b/test/cases/dom/assembler.mjs similarity index 95% rename from development/test/cases/dom/assembler.mjs rename to test/cases/dom/assembler.mjs index a68cf689537061a6d3445e1af01aef94973a86a7..152ceedde75a0fc2319c3f183c85c292ecbc2cf9 100644 --- a/development/test/cases/dom/assembler.mjs +++ b/test/cases/dom/assembler.mjs @@ -1,6 +1,6 @@ import {expect} from "chai" -import {ATTRIBUTEPREFIX, Assembler} from "../../../../application/source/dom/assembler.mjs"; +import {ATTRIBUTEPREFIX, Assembler} from "../../../source/dom/assembler.mjs"; import {initJSDOM} from "../../util/jsdom.mjs"; describe('Assembler', function () { diff --git a/development/test/cases/dom/attributes.mjs b/test/cases/dom/attributes.mjs similarity index 99% rename from development/test/cases/dom/attributes.mjs rename to test/cases/dom/attributes.mjs index 8426dfa44a308b23d7d7e7614bb0011d969e0136..0888513920bcef6b0b82757793befac40621ce7b 100644 --- a/development/test/cases/dom/attributes.mjs +++ b/test/cases/dom/attributes.mjs @@ -15,7 +15,7 @@ import { replaceAttributeToken, toggleAttributeToken, findClosestByClass -} from "../../../../application/source/dom/attributes.mjs"; +} from "../../../source/dom/attributes.mjs"; import {initJSDOM} from "../../util/jsdom.mjs"; diff --git a/development/test/cases/dom/customcontrol.mjs b/test/cases/dom/customcontrol.mjs similarity index 95% rename from development/test/cases/dom/customcontrol.mjs rename to test/cases/dom/customcontrol.mjs index 64da8bf54ea1e36d4acebc7d1cb01abc5c1b626e..137c99c081c79ea2997b32cae54e9d2aadbc29e9 100644 --- a/development/test/cases/dom/customcontrol.mjs +++ b/test/cases/dom/customcontrol.mjs @@ -1,8 +1,8 @@ 'use strict'; import chai from "chai" -import {ATTRIBUTE_OPTIONS} from "../../../../application/source/dom/constants.mjs"; -import {getDocument} from "../../../../application/source/dom/util.mjs"; +import {ATTRIBUTE_OPTIONS} from "../../../source/dom/constants.mjs"; +import {getDocument} from "../../../source/dom/util.mjs"; import {chaiDom} from "../../util/chai-dom.mjs"; import {cleanupDOMFromTesting, initMutationObserverForTesting} from "../../util/cleanupdom.mjs"; import {initJSDOM} from "../../util/jsdom.mjs"; @@ -29,11 +29,11 @@ describe('DOM', function () { // jsdom does not support ElementInternals jsdomFlag = navigator.userAgent.includes("jsdom"); - import("../../../../application/source/dom/customelement.mjs").then((m) => { + import("../../../source/dom/customelement.mjs").then((m) => { registerCustomElement = m['registerCustomElement']; - import("../../../../application/source/dom/customcontrol.mjs").then((m) => { + import("../../../source/dom/customcontrol.mjs").then((m) => { document = getDocument(); diff --git a/development/test/cases/dom/customelement-initfromscripthost.mjs b/test/cases/dom/customelement-initfromscripthost.mjs similarity index 90% rename from development/test/cases/dom/customelement-initfromscripthost.mjs rename to test/cases/dom/customelement-initfromscripthost.mjs index 2a87233450d36d96e7798041dd3cbf3570b4074a..9b58fcd6576f5402dda09f82a936376f9f976471 100644 --- a/development/test/cases/dom/customelement-initfromscripthost.mjs +++ b/test/cases/dom/customelement-initfromscripthost.mjs @@ -1,11 +1,11 @@ 'use strict'; import chai from "chai" -// import {internalSymbol} from "../../../../application/source/constants.mjs"; -// import {ATTRIBUTE_OPTIONS} from "../../../../application/source/dom/constants.mjs"; -import {getDocument} from "../../../../application/source/dom/util.mjs"; -// import {ProxyObserver} from "../../../../application/source/types/proxyobserver.mjs"; -// import {addObjectWithUpdaterToElement} from "../../../../application/source/dom/updater.mjs"; +// import {internalSymbol} from "../../../source/constants.mjs"; +// import {ATTRIBUTE_OPTIONS} from "../../../source/dom/constants.mjs"; +import {getDocument} from "../../../source/dom/util.mjs"; +// import {ProxyObserver} from "../../../source/types/proxyobserver.mjs"; +// import {addObjectWithUpdaterToElement} from "../../../source/dom/updater.mjs"; import {chaiDom} from "../../util/chai-dom.mjs"; import {initJSDOM} from "../../util/jsdom.mjs"; @@ -40,7 +40,7 @@ describe('DOM', function () { before(function (done) { initJSDOM().then(() => { - import("../../../../application/source/dom/customelement.mjs").then((m) => { + import("../../../source/dom/customelement.mjs").then((m) => { try { CustomElement = m['CustomElement']; diff --git a/development/test/cases/dom/customelement.mjs b/test/cases/dom/customelement.mjs similarity index 97% rename from development/test/cases/dom/customelement.mjs rename to test/cases/dom/customelement.mjs index ca67a8b5fc99e20a2d0ed5050b9f471eec892833..ae39bc702ee909d2f90a3a1f3e058230d9105b08 100644 --- a/development/test/cases/dom/customelement.mjs +++ b/test/cases/dom/customelement.mjs @@ -1,11 +1,11 @@ 'use strict'; import chai from "chai" -import {internalSymbol} from "../../../../application/source/constants.mjs"; -import {ATTRIBUTE_OPTIONS} from "../../../../application/source/dom/constants.mjs"; -import {getDocument} from "../../../../application/source/dom/util.mjs"; -import {ProxyObserver} from "../../../../application/source/types/proxyobserver.mjs"; -import {addObjectWithUpdaterToElement} from "../../../../application/source/dom/updater.mjs"; +import {internalSymbol} from "../../../source/constants.mjs"; +import {ATTRIBUTE_OPTIONS} from "../../../source/dom/constants.mjs"; +import {getDocument} from "../../../source/dom/util.mjs"; +import {ProxyObserver} from "../../../source/types/proxyobserver.mjs"; +import {addObjectWithUpdaterToElement} from "../../../source/dom/updater.mjs"; import {chaiDom} from "../../util/chai-dom.mjs"; import {initJSDOM} from "../../util/jsdom.mjs"; @@ -37,7 +37,7 @@ describe('DOM', function () { before(function (done) { initJSDOM().then(() => { - import("../../../../application/source/dom/customelement.mjs").then((m) => { + import("../../../source/dom/customelement.mjs").then((m) => { try { CustomElement = m['CustomElement']; assignUpdaterToElement= function (elements, object) { @@ -146,7 +146,7 @@ describe('DOM', function () { before(function (done) { initJSDOM().then(() => { - import("../../../../application/source/dom/customelement.mjs").then((m) => { + import("../../../source/dom/customelement.mjs").then((m) => { try { CustomElement = m['CustomElement']; diff --git a/development/test/cases/dom/dimension.mjs b/test/cases/dom/dimension.mjs similarity index 92% rename from development/test/cases/dom/dimension.mjs rename to test/cases/dom/dimension.mjs index 5ca418e28d50e8644627b34f8c818e813b4d7b18..44eaef7b92a58e48e1421c45f3fc375af5fab513 100644 --- a/development/test/cases/dom/dimension.mjs +++ b/test/cases/dom/dimension.mjs @@ -1,9 +1,9 @@ import {expect} from 'chai'; -import {convertToPixels, getDeviceDPI} from "../../../../application/source/dom/dimension.mjs"; -import {getWindow} from "../../../../application/source/dom/util.mjs"; +import {convertToPixels, getDeviceDPI} from "../../../source/dom/dimension.mjs"; +import {getWindow} from "../../../source/dom/util.mjs"; import {initJSDOM, isBrowser, JSDOMExport as JSDOM} from "../../util/jsdom.mjs"; -import {getGlobal} from "../../../../application/source/types/global.mjs"; -import {detectRuntimeEnvironment} from "../../../../application/source/util/runtime.mjs"; +import {getGlobal} from "../../../source/types/global.mjs"; +import {detectRuntimeEnvironment} from "../../../source/util/runtime.mjs"; function getMockWindow(dpi) { diff --git a/development/test/cases/dom/events.mjs b/test/cases/dom/events.mjs similarity index 98% rename from development/test/cases/dom/events.mjs rename to test/cases/dom/events.mjs index e255fd5178a4400577f20ffe256cfe3ce3be0fc4..07c253d906cee0b892b45e58c9b17ebdd8a0f74c 100644 --- a/development/test/cases/dom/events.mjs +++ b/test/cases/dom/events.mjs @@ -2,7 +2,7 @@ import {expect} from "chai" -import {fireEvent, findTargetElementFromEvent, fireCustomEvent} from "../../../../application/source/dom/events.mjs"; +import {fireEvent, findTargetElementFromEvent, fireCustomEvent} from "../../../source/dom/events.mjs"; import {initJSDOM} from "../../util/jsdom.mjs"; describe('Events', function () { diff --git a/development/test/cases/dom/find.mjs b/test/cases/dom/find.mjs similarity index 97% rename from development/test/cases/dom/find.mjs rename to test/cases/dom/find.mjs index df6618503384ad86cd0d86be7a10c1dfacb39122..55e13ea247ec4d06392b4bb754832727f98f0d70 100644 --- a/development/test/cases/dom/find.mjs +++ b/test/cases/dom/find.mjs @@ -1,6 +1,6 @@ import { findElementWithIdUpwards -} from "../../../../application/source/dom/util.mjs"; +} from "../../../source/dom/util.mjs"; import {expect} from 'chai'; import {initJSDOM} from "../../util/jsdom.mjs"; diff --git a/development/test/cases/dom/focusmanager.mjs b/test/cases/dom/focusmanager.mjs similarity index 97% rename from development/test/cases/dom/focusmanager.mjs rename to test/cases/dom/focusmanager.mjs index d57296d8fe9e177b6df2a770f54fe66f575db6ff..28046d1ebd370bc83f2134097c231862d397bd68 100644 --- a/development/test/cases/dom/focusmanager.mjs +++ b/test/cases/dom/focusmanager.mjs @@ -1,7 +1,7 @@ 'use strict'; import {expect} from "chai"; -import {FocusManager} from "../../../../application/source/dom/focusmanager.mjs"; +import {FocusManager} from "../../../source/dom/focusmanager.mjs"; import {cleanupDOMFromTesting, initMutationObserverForTesting} from "../../util/cleanupdom.mjs"; import {initJSDOM} from "../../util/jsdom.mjs"; diff --git a/development/test/cases/dom/locale.mjs b/test/cases/dom/locale.mjs similarity index 88% rename from development/test/cases/dom/locale.mjs rename to test/cases/dom/locale.mjs index f87f1311eeea11b5dbed12e79b77af875060642a..507d2b36bc243cec02449d44ef85c885e31ef8b5 100644 --- a/development/test/cases/dom/locale.mjs +++ b/test/cases/dom/locale.mjs @@ -2,8 +2,8 @@ import {expect} from "chai" -import {Locale} from "../../../../application/source/i18n/locale.mjs"; -import {getLocaleOfDocument} from "../../../../application/source/dom/locale.mjs"; +import {Locale} from "../../../source/i18n/locale.mjs"; +import {getLocaleOfDocument} from "../../../source/dom/locale.mjs"; import {initJSDOM} from "../../util/jsdom.mjs"; describe('Attributes', function () { diff --git a/development/test/cases/dom/ready.mjs b/test/cases/dom/ready.mjs similarity index 89% rename from development/test/cases/dom/ready.mjs rename to test/cases/dom/ready.mjs index 53e32f969310c468c34e73ba0963bc6fbada43bb..b53b26b67e4fd9d247b31851db95a117903f0036 100644 --- a/development/test/cases/dom/ready.mjs +++ b/test/cases/dom/ready.mjs @@ -11,7 +11,7 @@ describe('Ready', function () { before(function (done) { initJSDOM().then(() => { - import("../../../../application/source/dom/ready.mjs").then((m) => { + import("../../../source/dom/ready.mjs").then((m) => { domReady = m['domReady']; windowReady = m['windowReady']; done() diff --git a/development/test/cases/dom/resource.mjs b/test/cases/dom/resource.mjs similarity index 91% rename from development/test/cases/dom/resource.mjs rename to test/cases/dom/resource.mjs index 8a1365720f4a90c07c1ddf81dac711b015450af0..44ccd18d15b611f0bf19808eec98b0da5297dacf 100644 --- a/development/test/cases/dom/resource.mjs +++ b/test/cases/dom/resource.mjs @@ -12,7 +12,7 @@ describe('Resource', function() { before(function (done) { initJSDOM().then(() => { - import("../../../../application/source/dom/resource.mjs").then((m) => { + import("../../../source/dom/resource.mjs").then((m) => { Resource = m['Resource']; diff --git a/development/test/cases/dom/resource/data.mjs b/test/cases/dom/resource/data.mjs similarity index 93% rename from development/test/cases/dom/resource/data.mjs rename to test/cases/dom/resource/data.mjs index 0d518a5d7e75bfeec3ac6b8ba87008d8ce0e1446..1d11b3066940b63724c540009d71ad2747e79246 100644 --- a/development/test/cases/dom/resource/data.mjs +++ b/test/cases/dom/resource/data.mjs @@ -1,9 +1,9 @@ 'use strict'; import chai from "chai" -import {Data} from "../../../../../application/source/dom/resource/data.mjs"; -import {DataUrl} from "../../../../../application/source/types/dataurl.mjs"; -import {ID} from "../../../../../application/source/types/id.mjs"; +import {Data} from "../../../../source/dom/resource/data.mjs"; +import {DataUrl} from "../../../../source/types/dataurl.mjs"; +import {ID} from "../../../../source/types/id.mjs"; import {chaiDom} from "../../../util/chai-dom.mjs"; import {cleanupDOMFromTesting, initMutationObserverForTesting} from "../../../util/cleanupdom.mjs"; import {initJSDOM} from "../../../util/jsdom.mjs"; diff --git a/development/test/cases/dom/resource/link.mjs b/test/cases/dom/resource/link.mjs similarity index 91% rename from development/test/cases/dom/resource/link.mjs rename to test/cases/dom/resource/link.mjs index f066050a8daea53bd53e73830c1fcf36592cdb61..781a44b517c91d1e316fafe0ef65978d4df021fa 100644 --- a/development/test/cases/dom/resource/link.mjs +++ b/test/cases/dom/resource/link.mjs @@ -1,9 +1,9 @@ 'use strict'; import chai from "chai" -import {Link} from "../../../../../application/source/dom/resource/link.mjs"; -import {DataUrl} from "../../../../../application/source/types/dataurl.mjs"; -import {ID} from "../../../../../application/source/types/id.mjs"; +import {Link} from "../../../../source/dom/resource/link.mjs"; +import {DataUrl} from "../../../../source/types/dataurl.mjs"; +import {ID} from "../../../../source/types/id.mjs"; import {chaiDom} from "../../../util/chai-dom.mjs"; import {cleanupDOMFromTesting, initMutationObserverForTesting} from "../../../util/cleanupdom.mjs"; import {initJSDOM} from "../../../util/jsdom.mjs"; diff --git a/development/test/cases/dom/resource/link/stylesheet.mjs b/test/cases/dom/resource/link/stylesheet.mjs similarity index 91% rename from development/test/cases/dom/resource/link/stylesheet.mjs rename to test/cases/dom/resource/link/stylesheet.mjs index 43096f9f5d56801d1c20d83f40138d8611519202..9499b93f8448363bd8d64e7306424561cb4978b1 100644 --- a/development/test/cases/dom/resource/link/stylesheet.mjs +++ b/test/cases/dom/resource/link/stylesheet.mjs @@ -1,9 +1,9 @@ 'use strict'; import chai from "chai" -import {Stylesheet} from "../../../../../../application/source/dom/resource/link/stylesheet.mjs"; -import {DataUrl} from "../../../../../../application/source/types/dataurl.mjs"; -import {ID} from "../../../../../../application/source/types/id.mjs"; +import {Stylesheet} from "../../../../../source/dom/resource/link/stylesheet.mjs"; +import {DataUrl} from "../../../../../source/types/dataurl.mjs"; +import {ID} from "../../../../../source/types/id.mjs"; import {chaiDom} from "../../../../util/chai-dom.mjs"; import {cleanupDOMFromTesting, initMutationObserverForTesting} from "../../../../util/cleanupdom.mjs"; import {initJSDOM} from "../../../../util/jsdom.mjs"; diff --git a/development/test/cases/dom/resource/script.mjs b/test/cases/dom/resource/script.mjs similarity index 92% rename from development/test/cases/dom/resource/script.mjs rename to test/cases/dom/resource/script.mjs index be7b32230cadf214c277f634e1019c83695631fe..4ca53e800afe000c0881c526d166469d2d83a47f 100644 --- a/development/test/cases/dom/resource/script.mjs +++ b/test/cases/dom/resource/script.mjs @@ -1,9 +1,9 @@ 'use strict'; import chai from "chai" -import {Script} from "../../../../../application/source/dom/resource/script.mjs"; -import {DataUrl} from "../../../../../application/source/types/dataurl.mjs"; -import {ID} from "../../../../../application/source/types/id.mjs"; +import {Script} from "../../../../source/dom/resource/script.mjs"; +import {DataUrl} from "../../../../source/types/dataurl.mjs"; +import {ID} from "../../../../source/types/id.mjs"; import {chaiDom} from "../../../util/chai-dom.mjs"; import {cleanupDOMFromTesting, initMutationObserverForTesting} from "../../../util/cleanupdom.mjs"; import {initJSDOM} from "../../../util/jsdom.mjs"; diff --git a/development/test/cases/dom/resourcemanager.mjs b/test/cases/dom/resourcemanager.mjs similarity index 97% rename from development/test/cases/dom/resourcemanager.mjs rename to test/cases/dom/resourcemanager.mjs index 77032e2c35091cd9aade3927c60260dc2c767ed0..05b4d5772e6920dd6e045da86481959e54d3c888 100644 --- a/development/test/cases/dom/resourcemanager.mjs +++ b/test/cases/dom/resourcemanager.mjs @@ -2,7 +2,7 @@ import {expect} from "chai" -import {ResourceManager} from "../../../../application/source/dom/resourcemanager.mjs"; +import {ResourceManager} from "../../../source/dom/resourcemanager.mjs"; import {cleanupDOMFromTesting, initMutationObserverForTesting} from "../../util/cleanupdom.mjs"; import {initJSDOM} from "../../util/jsdom.mjs"; diff --git a/development/test/cases/dom/slotted-nodes.mjs b/test/cases/dom/slotted-nodes.mjs similarity index 71% rename from development/test/cases/dom/slotted-nodes.mjs rename to test/cases/dom/slotted-nodes.mjs index 0d78835c8a6565c104f93fe0315f7c4f5f6541a9..053db49d41efeab2c0e7c481b2c1fd3c123f7b7d 100644 --- a/development/test/cases/dom/slotted-nodes.mjs +++ b/test/cases/dom/slotted-nodes.mjs @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import {getSlottedNodes} from "../../../../application/source/dom/slotted.mjs"; +import {getSlottedNodes} from "../../../source/dom/slotted.mjs"; describe('getSlottedNodes', () => { diff --git a/development/test/cases/dom/template.mjs b/test/cases/dom/template.mjs similarity index 96% rename from development/test/cases/dom/template.mjs rename to test/cases/dom/template.mjs index 3ea4a652d0a8a82f7fe634614f5977c368884b40..265f63900af80e3ede7a465c46a250430f019695 100644 --- a/development/test/cases/dom/template.mjs +++ b/test/cases/dom/template.mjs @@ -1,9 +1,9 @@ 'use strict'; import {expect} from "chai" -import {ATTRIBUTE_THEME_NAME} from "../../../../application/source/dom/constants.mjs"; +import {ATTRIBUTE_THEME_NAME} from "../../../source/dom/constants.mjs"; -import {findDocumentTemplate, Template} from "../../../../application/source/dom/template.mjs"; +import {findDocumentTemplate, Template} from "../../../source/dom/template.mjs"; import {initJSDOM} from "../../util/jsdom.mjs"; diff --git a/development/test/cases/dom/theme.mjs b/test/cases/dom/theme.mjs similarity index 90% rename from development/test/cases/dom/theme.mjs rename to test/cases/dom/theme.mjs index d726668da1883c31359d33a2549b1d7272f0e9f0..30c2f3342fc36d1ce033a58b2fe83498b7d1879f 100644 --- a/development/test/cases/dom/theme.mjs +++ b/test/cases/dom/theme.mjs @@ -1,9 +1,9 @@ 'use strict'; -import {getDocumentFragmentFromString} from "../../../../application/source/dom/util.mjs"; +import {getDocumentFragmentFromString} from "../../../source/dom/util.mjs"; import {initJSDOM} from "../../util/jsdom.mjs"; import {expect} from "chai" -import {Theme, getDocumentTheme} from "../../../../application/source/dom/theme.mjs"; +import {Theme, getDocumentTheme} from "../../../source/dom/theme.mjs"; describe('Theme', function () { before(function (done) { diff --git a/development/test/cases/dom/updater.mjs b/test/cases/dom/updater.mjs similarity index 98% rename from development/test/cases/dom/updater.mjs rename to test/cases/dom/updater.mjs index 25003851ade6c464fe188269f8985302ee82acb2..9c02cc8de44994e6ab808d6ad98d8e887bbfb9a5 100644 --- a/development/test/cases/dom/updater.mjs +++ b/test/cases/dom/updater.mjs @@ -1,10 +1,10 @@ 'use strict'; import chai from "chai" -import {Updater} from "../../../../application/source/dom/updater.mjs"; -import {ID} from "../../../../application/source/types/id.mjs"; -import {Observer} from "../../../../application/source/types/observer.mjs"; -import {ProxyObserver} from "../../../../application/source/types/proxyobserver.mjs"; +import {Updater} from "../../../source/dom/updater.mjs"; +import {ID} from "../../../source/types/id.mjs"; +import {Observer} from "../../../source/types/observer.mjs"; +import {ProxyObserver} from "../../../source/types/proxyobserver.mjs"; import {chaiDom} from "../../util/chai-dom.mjs"; import {initJSDOM} from "../../util/jsdom.mjs"; diff --git a/development/test/cases/dom/util.mjs b/test/cases/dom/util.mjs similarity index 96% rename from development/test/cases/dom/util.mjs rename to test/cases/dom/util.mjs index c7d553b0aff44c8bb24c94b3a909a22ca758a7f1..b0016ee0b8417c92dfe2de676874bac34465fbbe 100644 --- a/development/test/cases/dom/util.mjs +++ b/test/cases/dom/util.mjs @@ -1,8 +1,8 @@ import { getDocument, getWindow, getDocumentFragmentFromString -} from "../../../../application/source/dom/util.mjs"; +} from "../../../source/dom/util.mjs"; -import {getContainingDocument} from "../../../../application/source/dom/util.mjs"; +import {getContainingDocument} from "../../../source/dom/util.mjs"; import {initJSDOM} from "../../util/jsdom.mjs"; diff --git a/development/test/cases/dom/util/extract-keys.mjs b/test/cases/dom/util/extract-keys.mjs similarity index 95% rename from development/test/cases/dom/util/extract-keys.mjs rename to test/cases/dom/util/extract-keys.mjs index ca5396b13e08c562372fabba14b0e74c4ecc010f..44853349f1ea92afac75f1690fbb856623e52b90 100644 --- a/development/test/cases/dom/util/extract-keys.mjs +++ b/test/cases/dom/util/extract-keys.mjs @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import {extractKeys} from "../../../../../application/source/dom/util/extract-keys.mjs"; +import {extractKeys} from "../../../../source/dom/util/extract-keys.mjs"; describe('extractKeys', () => { diff --git a/development/test/cases/dom/util/init-options-from-attributes.mjs b/test/cases/dom/util/init-options-from-attributes.mjs similarity index 98% rename from development/test/cases/dom/util/init-options-from-attributes.mjs rename to test/cases/dom/util/init-options-from-attributes.mjs index 7139f8dcc5e2acb9740285d098f0a699b8d8d579..34f1f54a41b9335c35b6463d7db57c8fb2525305 100644 --- a/development/test/cases/dom/util/init-options-from-attributes.mjs +++ b/test/cases/dom/util/init-options-from-attributes.mjs @@ -9,7 +9,7 @@ describe('initOptionsFromAttributes', () => { before( function (done) { initJSDOM().then(() => { - import("../../../../..//application/source/dom/util/init-options-from-attributes.mjs").then((m) => { + import("../../../../source/dom/util/init-options-from-attributes.mjs").then((m) => { initOptionsFromAttributes = m['initOptionsFromAttributes']; done(); }) diff --git a/development/test/cases/dom/worker/factory.mjs b/test/cases/dom/worker/factory.mjs similarity index 88% rename from development/test/cases/dom/worker/factory.mjs rename to test/cases/dom/worker/factory.mjs index c4d510737ab3485c9feb2d1efd98bcb2a6b04133..5793b2bdc0b78d2a51ff51a6651d14d9f18c7099 100644 --- a/development/test/cases/dom/worker/factory.mjs +++ b/test/cases/dom/worker/factory.mjs @@ -1,7 +1,7 @@ import {expect} from "chai" -import {Factory} from "../../../../../application/source/dom/worker/factory.mjs"; -import {getGlobal} from "../../../../../application/source/types/global.mjs"; +import {Factory} from "../../../../source/dom/worker/factory.mjs"; +import {getGlobal} from "../../../../source/types/global.mjs"; import {initJSDOM, isNode} from "../../../util/jsdom.mjs"; const global = getGlobal(); diff --git a/development/test/cases/i18n/formatter.mjs b/test/cases/i18n/formatter.mjs similarity index 91% rename from development/test/cases/i18n/formatter.mjs rename to test/cases/i18n/formatter.mjs index 9c633f648614daa86ce7ee0c4018b9d0909bde94..e6c344cacc03ef98112fc1f873c930cd743f0770 100644 --- a/development/test/cases/i18n/formatter.mjs +++ b/test/cases/i18n/formatter.mjs @@ -1,6 +1,6 @@ import {expect} from "chai" -import {Formatter} from "../../../../application/source/i18n/formatter.mjs"; -import {Translations} from "../../../../application/source/i18n/translations.mjs"; +import {Formatter} from "../../../source/i18n/formatter.mjs"; +import {Translations} from "../../../source/i18n/translations.mjs"; describe('Formatter', function () { diff --git a/development/test/cases/i18n/locale.mjs b/test/cases/i18n/locale.mjs similarity index 97% rename from development/test/cases/i18n/locale.mjs rename to test/cases/i18n/locale.mjs index 4256a5a3ba9ba97762458e1329a9d8041673eda7..731260f1115c62cf5584de4dfd6b2eec0bbd31c9 100644 --- a/development/test/cases/i18n/locale.mjs +++ b/test/cases/i18n/locale.mjs @@ -1,7 +1,7 @@ import {expect} from "chai" -import {parseLocale, Locale} from "../../../../application/source/i18n/locale.mjs"; +import {parseLocale, Locale} from "../../../source/i18n/locale.mjs"; describe('Locale', function () { diff --git a/development/test/cases/i18n/provider.mjs b/test/cases/i18n/provider.mjs similarity index 83% rename from development/test/cases/i18n/provider.mjs rename to test/cases/i18n/provider.mjs index 31f108c79d4813fac3b4557290b61374b7a90d26..20ae2281ad8adb576eed15b557632624111cb6be 100644 --- a/development/test/cases/i18n/provider.mjs +++ b/test/cases/i18n/provider.mjs @@ -1,9 +1,9 @@ import {expect} from "chai" -import {ATTRIBUTE_OBJECTLINK} from "../../../../application/source/dom/constants.mjs"; -import {getLinkedObjects} from "../../../../application/source/dom/attributes.mjs"; -import {Provider} from "../../../../application/source/i18n/provider.mjs"; +import {ATTRIBUTE_OBJECTLINK} from "../../../source/dom/constants.mjs"; +import {getLinkedObjects} from "../../../source/dom/attributes.mjs"; +import {Provider} from "../../../source/i18n/provider.mjs"; import {initJSDOM} from "../../util/jsdom.mjs"; -import {getDocumentTranslations, Translations} from "../../../../application/source/i18n/translations.mjs"; +import {getDocumentTranslations, Translations} from "../../../source/i18n/translations.mjs"; describe('Provider', function () { diff --git a/development/test/cases/i18n/providers/embed.mjs b/test/cases/i18n/providers/embed.mjs similarity index 83% rename from development/test/cases/i18n/providers/embed.mjs rename to test/cases/i18n/providers/embed.mjs index 686bec19ad082d0e848f1ab760f2c69cab8ed4a5..216dd8f7fd9072fe5253a60532a1f960e6f2b6fe 100644 --- a/development/test/cases/i18n/providers/embed.mjs +++ b/test/cases/i18n/providers/embed.mjs @@ -1,9 +1,9 @@ import {expect} from "chai" -import {Embed} from "../../../../../application/source/i18n/providers/embed.mjs"; -import {Translations} from "../../../../../application/source/i18n/translations.mjs"; -import {getGlobal} from "../../../../../application/source/types/global.mjs"; +import {Embed} from "../../../../source/i18n/providers/embed.mjs"; +import {Translations} from "../../../../source/i18n/translations.mjs"; +import {getGlobal} from "../../../../source/types/global.mjs"; import {initJSDOM} from "../../../util/jsdom.mjs"; diff --git a/development/test/cases/i18n/providers/fetch.mjs b/test/cases/i18n/providers/fetch.mjs similarity index 82% rename from development/test/cases/i18n/providers/fetch.mjs rename to test/cases/i18n/providers/fetch.mjs index 54914ecb66d1e330e5a2e92033d90a817b71b204..7f31f1eb88febab0629401bef53f6be58aba4d60 100644 --- a/development/test/cases/i18n/providers/fetch.mjs +++ b/test/cases/i18n/providers/fetch.mjs @@ -1,9 +1,9 @@ import {expect} from "chai" -import {Fetch} from "../../../../../application/source/i18n/providers/fetch.mjs"; -import {Translations} from "../../../../../application/source/i18n/translations.mjs"; -import {getGlobal} from "../../../../../application/source/types/global.mjs"; +import {Fetch} from "../../../../source/i18n/providers/fetch.mjs"; +import {Translations} from "../../../../source/i18n/translations.mjs"; +import {getGlobal} from "../../../../source/types/global.mjs"; const global = getGlobal(); diff --git a/development/test/cases/i18n/translations.mjs b/test/cases/i18n/translations.mjs similarity index 93% rename from development/test/cases/i18n/translations.mjs rename to test/cases/i18n/translations.mjs index 476e371adca1964461c65272f590cf508bdcc6ff..6ab7098e287339f4ce1ab0cb7efc1442330e39bd 100644 --- a/development/test/cases/i18n/translations.mjs +++ b/test/cases/i18n/translations.mjs @@ -1,11 +1,11 @@ import {expect} from "chai" -import {parseLocale} from "../../../../application/source/i18n/locale.mjs"; -import {Embed} from "../../../../application/source/i18n/providers/embed.mjs"; +import {parseLocale} from "../../../source/i18n/locale.mjs"; +import {Embed} from "../../../source/i18n/providers/embed.mjs"; import { Translations, getDocumentTranslations -} from "../../../../application/source/i18n/translations.mjs"; +} from "../../../source/i18n/translations.mjs"; import {initJSDOM} from "../../util/jsdom.mjs"; describe('Translations', function () { diff --git a/development/test/cases/logging/handler.mjs b/test/cases/logging/handler.mjs similarity index 95% rename from development/test/cases/logging/handler.mjs rename to test/cases/logging/handler.mjs index 75fd5790025a02eb43464753a225b24335f0388a..4dbcac1d0b21aeccefb2babef6580e84e52607ab 100644 --- a/development/test/cases/logging/handler.mjs +++ b/test/cases/logging/handler.mjs @@ -1,7 +1,7 @@ import {expect} from "chai"; -import {ALL, TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF} from "../../../../application/source/logging/logger.mjs"; -import {Handler} from "../../../../application/source/logging/handler.mjs"; -import {LogEntry} from "../../../../application/source/logging/logentry.mjs"; +import {ALL, TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF} from "../../../source/logging/logger.mjs"; +import {Handler} from "../../../source/logging/handler.mjs"; +import {LogEntry} from "../../../source/logging/logentry.mjs"; describe('Logging', function () { diff --git a/development/test/cases/logging/handler/console.mjs b/test/cases/logging/handler/console.mjs similarity index 85% rename from development/test/cases/logging/handler/console.mjs rename to test/cases/logging/handler/console.mjs index 06c87520e10a272ec48f97d92bd83404d452e65d..72cce032e9549fb599c10fdb27097b16cd1114d8 100644 --- a/development/test/cases/logging/handler/console.mjs +++ b/test/cases/logging/handler/console.mjs @@ -1,7 +1,7 @@ import {expect} from "chai"; -import {ConsoleHandler} from "../../../../../application/source/logging/handler/console.mjs"; -import {LogEntry} from "../../../../../application/source/logging/logentry.mjs"; -import {TRACE, WARN, DEBUG, ERROR, FATAL, INFO} from "../../../../../application/source/logging/logger.mjs"; +import {ConsoleHandler} from "../../../../source/logging/handler/console.mjs"; +import {LogEntry} from "../../../../source/logging/logentry.mjs"; +import {TRACE, WARN, DEBUG, ERROR, FATAL, INFO} from "../../../../source/logging/logger.mjs"; describe('Logging', function () { diff --git a/development/test/cases/logging/logentry.mjs b/test/cases/logging/logentry.mjs similarity index 90% rename from development/test/cases/logging/logentry.mjs rename to test/cases/logging/logentry.mjs index 7d1d66b5181d456c55ac00230bcd774cf91f1f40..42680030ec87ead2b169b284c61a8533b8dffdad 100644 --- a/development/test/cases/logging/logentry.mjs +++ b/test/cases/logging/logentry.mjs @@ -1,5 +1,5 @@ import {expect} from "chai" -import {LogEntry} from "../../../../application/source/logging/logentry.mjs"; +import {LogEntry} from "../../../source/logging/logentry.mjs"; describe('Log', function () { diff --git a/development/test/cases/logging/logger.mjs b/test/cases/logging/logger.mjs similarity index 97% rename from development/test/cases/logging/logger.mjs rename to test/cases/logging/logger.mjs index 4285c3cf087edd9c61b8fce0a154bf3021c87c07..d061e7249ccfbf9f379d8d38f61c769568512756 100644 --- a/development/test/cases/logging/logger.mjs +++ b/test/cases/logging/logger.mjs @@ -1,5 +1,5 @@ import {expect} from "chai" -import {Logger, OFF, ALL, TRACE, DEBUG, INFO, WARN, ERROR, FATAL} from "../../../../application/source/logging/logger.mjs"; +import {Logger, OFF, ALL, TRACE, DEBUG, INFO, WARN, ERROR, FATAL} from "../../../source/logging/logger.mjs"; describe('Logging', function () { diff --git a/development/test/cases/math/random.mjs b/test/cases/math/random.mjs similarity index 96% rename from development/test/cases/math/random.mjs rename to test/cases/math/random.mjs index 27a195975ad123c0fe0d546f2df9a8cd9787a1d3..016fde014833bcb857add6cc73a8ac3a21dfc55d 100644 --- a/development/test/cases/math/random.mjs +++ b/test/cases/math/random.mjs @@ -15,7 +15,7 @@ describe('Math', function () { })) } - promises.push(import("../../../../application/source/math/random.mjs").then(m => { + promises.push(import("../../../source/math/random.mjs").then(m => { random = m.random; return true; })) diff --git a/development/test/cases/monster.mjs b/test/cases/monster.mjs similarity index 83% rename from development/test/cases/monster.mjs rename to test/cases/monster.mjs index baa46c58e0517cbc2e565f937cac12da7e00f222..a983c6872cf2977638cbcaa8b4983bf65cfa800e 100644 --- a/development/test/cases/monster.mjs +++ b/test/cases/monster.mjs @@ -1,5 +1,5 @@ import {expect} from "chai" -import {Version, getMonsterVersion} from "../../../application/source/types/version.mjs"; +import {Version, getMonsterVersion} from "../../source/types/version.mjs"; describe('Monster', function () { diff --git a/development/test/cases/net/webconnect.mjs b/test/cases/net/webconnect.mjs similarity index 91% rename from development/test/cases/net/webconnect.mjs rename to test/cases/net/webconnect.mjs index 0f3bf8d073eae8234462270e599533a179688d57..38222dff90b983f4be32752e60a8a3067f03ccdb 100644 --- a/development/test/cases/net/webconnect.mjs +++ b/test/cases/net/webconnect.mjs @@ -1,7 +1,7 @@ import {expect} from "chai" -import {WebConnect} from "../../../../application/source/net/webconnect.mjs"; -import {Message} from "../../../../application/source/net/webconnect/message.mjs"; -import {Observer} from "../../../../application/source/types/observer.mjs"; +import {WebConnect} from "../../../source/net/webconnect.mjs"; +import {Message} from "../../../source/net/webconnect/message.mjs"; +import {Observer} from "../../../source/types/observer.mjs"; import {initWebSocket} from "../../util/websocket.mjs"; const testUrl = "wss://ws.postman-echo.com/raw" diff --git a/development/test/cases/net/webconnect/message.mjs b/test/cases/net/webconnect/message.mjs similarity index 93% rename from development/test/cases/net/webconnect/message.mjs rename to test/cases/net/webconnect/message.mjs index 68ae0a14500dc0c9dd1a5dd31b17abb09e788f07..012665fda245b271550ab2a1583768b12bb92b25 100644 --- a/development/test/cases/net/webconnect/message.mjs +++ b/test/cases/net/webconnect/message.mjs @@ -1,5 +1,5 @@ import {expect} from "chai" -import {Message} from "../../../../../application/source/net/webconnect/message.mjs"; +import {Message} from "../../../../source/net/webconnect/message.mjs"; describe('Message', function () { diff --git a/development/test/cases/text/bracketed-key-value-hash.mjs b/test/cases/text/bracketed-key-value-hash.mjs similarity index 99% rename from development/test/cases/text/bracketed-key-value-hash.mjs rename to test/cases/text/bracketed-key-value-hash.mjs index a2bc319c16c419f18452552163d6ac610f777bc6..52b382b6b80181fc3bd0401aefbf9efaee97d903 100644 --- a/development/test/cases/text/bracketed-key-value-hash.mjs +++ b/test/cases/text/bracketed-key-value-hash.mjs @@ -3,7 +3,7 @@ import {expect} from "chai"; import { parseBracketedKeyValueHash, createBracketedKeyValueHash -} from "../../../../application/source/text/bracketed-key-value-hash.mjs"; +} from "../../../source/text/bracketed-key-value-hash.mjs"; describe("parseBracketedKeyValueHash", () => { it("should return an empty object for an empty string", () => { diff --git a/development/test/cases/text/formatter.mjs b/test/cases/text/formatter.mjs similarity index 99% rename from development/test/cases/text/formatter.mjs rename to test/cases/text/formatter.mjs index 6a00fa2fc777c30975b492ae26ec5a2f6cefd47f..8a75f924c6e6e411ba3e7b10a43115902a3574a0 100644 --- a/development/test/cases/text/formatter.mjs +++ b/test/cases/text/formatter.mjs @@ -1,5 +1,5 @@ import {expect} from "chai" -import {Formatter} from "../../../../application/source/text/formatter.mjs"; +import {Formatter} from "../../../source/text/formatter.mjs"; describe('Formatter', function () { diff --git a/development/test/cases/text/util.mjs b/test/cases/text/util.mjs similarity index 97% rename from development/test/cases/text/util.mjs rename to test/cases/text/util.mjs index 4cef64c1fdc020c48a359c924affb1a8e15038dd..e841b55eac8cf6e86593ec31ff46fe3102eb561c 100644 --- a/development/test/cases/text/util.mjs +++ b/test/cases/text/util.mjs @@ -1,5 +1,5 @@ import {expect} from "chai" -import {generateRangeComparisonExpression} from "../../../../application/source/text/util.mjs"; +import {generateRangeComparisonExpression} from "../../../source/text/util.mjs"; describe('generateRangeComparisonExpression', () => { it('should generate correct comparison expression for single values', () => { diff --git a/development/test/cases/types/base.mjs b/test/cases/types/base.mjs similarity index 88% rename from development/test/cases/types/base.mjs rename to test/cases/types/base.mjs index 4f02f6ad47d8c77f5094041c85a79252844ee83f..f98770944a4a33bf3024611ffe2059cf52a7c760 100644 --- a/development/test/cases/types/base.mjs +++ b/test/cases/types/base.mjs @@ -1,8 +1,8 @@ "use strict"; import {expect} from "chai" -import {Base} from "../../../../application/source/types/base.mjs"; -import {instanceSymbol} from "../../../../application/source/constants.mjs"; +import {Base} from "../../../source/types/base.mjs"; +import {instanceSymbol} from "../../../source/constants.mjs"; diff --git a/development/test/cases/types/basewithoptions.mjs b/test/cases/types/basewithoptions.mjs similarity index 86% rename from development/test/cases/types/basewithoptions.mjs rename to test/cases/types/basewithoptions.mjs index 5591f836cbb57e62ce8e6c0a09456ffef60304ee..bf7d052ea5c95297976b863af9ff300a5840450b 100644 --- a/development/test/cases/types/basewithoptions.mjs +++ b/test/cases/types/basewithoptions.mjs @@ -1,7 +1,7 @@ "use strict"; import {expect} from "chai" -import {BaseWithOptions} from "../../../../application/source/types/basewithoptions.mjs"; +import {BaseWithOptions} from "../../../source/types/basewithoptions.mjs"; describe('BaseWithOptions', function () { diff --git a/development/test/cases/types/binary.mjs b/test/cases/types/binary.mjs similarity index 88% rename from development/test/cases/types/binary.mjs rename to test/cases/types/binary.mjs index c2c8b9077b0fcda9928482feeec75f5296c8500d..fee2993e946d22c3bf366595880445439e2dbde5 100644 --- a/development/test/cases/types/binary.mjs +++ b/test/cases/types/binary.mjs @@ -1,7 +1,7 @@ 'use strict'; import {expect} from "chai" -import {fromBinary, toBinary} from "../../../../application/source/types/binary.mjs"; +import {fromBinary, toBinary} from "../../../source/types/binary.mjs"; describe('Binary', function () { diff --git a/development/test/cases/types/dataurl.mjs b/test/cases/types/dataurl.mjs similarity index 96% rename from development/test/cases/types/dataurl.mjs rename to test/cases/types/dataurl.mjs index ac9dc519056d74ceec96b2c32c81fb57e309fbc0..82c95008561f0509a63ddf6e98df374fda838f21 100644 --- a/development/test/cases/types/dataurl.mjs +++ b/test/cases/types/dataurl.mjs @@ -1,7 +1,7 @@ 'use strict'; import {expect} from "chai" -import {parseDataURL} from "../../../../application/source/types/dataurl.mjs"; +import {parseDataURL} from "../../../source/types/dataurl.mjs"; describe('Dataurl', function () { diff --git a/development/test/cases/types/global.mjs b/test/cases/types/global.mjs similarity index 94% rename from development/test/cases/types/global.mjs rename to test/cases/types/global.mjs index 79862008815f82f5eba35fda8359e084a591e9e0..f8ef4fdb0c6e9bcbbbd5a0e586846c0e24d9f354 100644 --- a/development/test/cases/types/global.mjs +++ b/test/cases/types/global.mjs @@ -1,4 +1,4 @@ -import {getGlobal, getGlobalObject, getGlobalFunction} from "../../../../application/source/types/global.mjs"; +import {getGlobal, getGlobalObject, getGlobalFunction} from "../../../source/types/global.mjs"; import {expect} from "chai" describe('Global', function () { diff --git a/development/test/cases/types/id.mjs b/test/cases/types/id.mjs similarity index 93% rename from development/test/cases/types/id.mjs rename to test/cases/types/id.mjs index 1e1c07cc903ef7182248ee6e9b3c7296fbc1dd89..93d5f6c19eb8c177f46ce326a25fd01aad7f5101 100644 --- a/development/test/cases/types/id.mjs +++ b/test/cases/types/id.mjs @@ -1,4 +1,4 @@ -import {ID} from "../../../../application/source/types/id.mjs"; +import {ID} from "../../../source/types/id.mjs"; import {expect} from "chai" import {initJSDOM} from "../../util/jsdom.mjs"; diff --git a/development/test/cases/types/internal.mjs b/test/cases/types/internal.mjs similarity index 96% rename from development/test/cases/types/internal.mjs rename to test/cases/types/internal.mjs index 30a50107bc831f8256a3be3c499d63a1ca6d8ea4..245c8c101aae1c37c37a46bd07f0edcc3bb77d98 100644 --- a/development/test/cases/types/internal.mjs +++ b/test/cases/types/internal.mjs @@ -1,8 +1,8 @@ "use strict"; import {expect} from "chai" -import {equipWithInternal} from "../../../../application/source/types/internal.mjs"; -import {Observer} from "../../../../application/source/types/observer.mjs"; +import {equipWithInternal} from "../../../source/types/internal.mjs"; +import {Observer} from "../../../source/types/observer.mjs"; class SomeRandomClass1 extends Object { diff --git a/development/test/cases/types/is.mjs b/test/cases/types/is.mjs similarity index 98% rename from development/test/cases/types/is.mjs rename to test/cases/types/is.mjs index 9e200635669596beef1ed1cfda231855f0c9254c..8be3a39ae1eb055baeae0aa01e0ca8fc76812029 100644 --- a/development/test/cases/types/is.mjs +++ b/test/cases/types/is.mjs @@ -9,10 +9,10 @@ import { isIterable, isInteger, isSymbol -} from "../../../../application/source/types/is.mjs"; +} from "../../../source/types/is.mjs"; -import {ID} from "../../../../application/source/types/id.mjs" +import {ID} from "../../../source/types/id.mjs" import {expect} from "chai" import {initJSDOM} from "../../util/jsdom.mjs"; diff --git a/development/test/cases/types/mediatype.mjs b/test/cases/types/mediatype.mjs similarity index 93% rename from development/test/cases/types/mediatype.mjs rename to test/cases/types/mediatype.mjs index 448b843881cefc57e1c24bf2707e21e4e8099b21..b242c4ab48914a95fcbf0197e2bb6f1bb9459991 100644 --- a/development/test/cases/types/mediatype.mjs +++ b/test/cases/types/mediatype.mjs @@ -1,7 +1,7 @@ 'use strict'; import {expect} from "chai" -import {MediaType, parseMediaType} from "../../../../application/source/types/mediatype.mjs"; +import {MediaType, parseMediaType} from "../../../source/types/mediatype.mjs"; describe('Dataurl', function () { diff --git a/development/test/cases/types/node.mjs b/test/cases/types/node.mjs similarity index 96% rename from development/test/cases/types/node.mjs rename to test/cases/types/node.mjs index a80c8e1bbb1ddd5cf2aab77920ae5c6bc30a1a84..e64eae7f1f448f3c04d8c072865dc90de8a513db 100644 --- a/development/test/cases/types/node.mjs +++ b/test/cases/types/node.mjs @@ -1,9 +1,9 @@ 'use strict'; import {expect} from "chai" -import {Node} from "../../../../application/source/types/node.mjs"; -import {NodeList} from "../../../../application/source/types/nodelist.mjs"; -import {NodeRecursiveIterator} from "../../../../application/source/types/noderecursiveiterator.mjs"; +import {Node} from "../../../source/types/node.mjs"; +import {NodeList} from "../../../source/types/nodelist.mjs"; +import {NodeRecursiveIterator} from "../../../source/types/noderecursiveiterator.mjs"; describe('NodeList', function () { describe('#constructor', function () { diff --git a/development/test/cases/types/nodelist.mjs b/test/cases/types/nodelist.mjs similarity index 92% rename from development/test/cases/types/nodelist.mjs rename to test/cases/types/nodelist.mjs index dbf25fe83bdd8d795746df3df716c251b48a00a7..d2446fbb93a508243740d0d0ca30e4b6f904382c 100644 --- a/development/test/cases/types/nodelist.mjs +++ b/test/cases/types/nodelist.mjs @@ -1,8 +1,8 @@ 'use strict'; import {expect} from "chai" -import {Node} from "../../../../application/source/types/node.mjs"; -import {NodeList} from "../../../../application/source/types/nodelist.mjs"; +import {Node} from "../../../source/types/node.mjs"; +import {NodeList} from "../../../source/types/nodelist.mjs"; describe('NodeList', function () { describe('#constructor', function () { diff --git a/development/test/cases/types/noderecursiveiterator.mjs b/test/cases/types/noderecursiveiterator.mjs similarity index 90% rename from development/test/cases/types/noderecursiveiterator.mjs rename to test/cases/types/noderecursiveiterator.mjs index ba331e159cb3a02c4ede12c510b56dff70826d5d..1c8aaf34eddc88227f0c4572dcaced3f95ac2450 100644 --- a/development/test/cases/types/noderecursiveiterator.mjs +++ b/test/cases/types/noderecursiveiterator.mjs @@ -1,9 +1,9 @@ 'use strict'; import {expect} from "chai" -import {Node} from "../../../../application/source/types/node.mjs"; -import {NodeList} from "../../../../application/source/types/nodelist.mjs"; -import {NodeRecursiveIterator} from "../../../../application/source/types/noderecursiveiterator.mjs"; +import {Node} from "../../../source/types/node.mjs"; +import {NodeList} from "../../../source/types/nodelist.mjs"; +import {NodeRecursiveIterator} from "../../../source/types/noderecursiveiterator.mjs"; describe('NodeRecursiveIterator', function () { diff --git a/development/test/cases/types/observablequeue.mjs b/test/cases/types/observablequeue.mjs similarity index 71% rename from development/test/cases/types/observablequeue.mjs rename to test/cases/types/observablequeue.mjs index be1486b7982a6dd782194d741797eb7b12c3a61f..e339a7aa286fc5f1a02db3326bdc01c65eb678b7 100644 --- a/development/test/cases/types/observablequeue.mjs +++ b/test/cases/types/observablequeue.mjs @@ -1,6 +1,6 @@ import {expect} from "chai" -import {ObservableQueue} from "../../../../application/source/types/observablequeue.mjs"; -import {Observer} from "../../../../application/source/types/observer.mjs"; +import {ObservableQueue} from "../../../source/types/observablequeue.mjs"; +import {Observer} from "../../../source/types/observer.mjs"; describe('ObservableQueue', function () { describe('Observer', function () { diff --git a/development/test/cases/types/observer.mjs b/test/cases/types/observer.mjs similarity index 97% rename from development/test/cases/types/observer.mjs rename to test/cases/types/observer.mjs index 47ab04aeaf7b5ac37c203e65426de097c96058ce..5d1aace9d3e447f041e101ef58f731f72a227e9f 100644 --- a/development/test/cases/types/observer.mjs +++ b/test/cases/types/observer.mjs @@ -1,6 +1,6 @@ import {expect} from "chai" -import {Observer} from "../../../../application/source/types/observer.mjs"; +import {Observer} from "../../../source/types/observer.mjs"; describe('Observer', function () { diff --git a/development/test/cases/types/observerlist.mjs b/test/cases/types/observerlist.mjs similarity index 94% rename from development/test/cases/types/observerlist.mjs rename to test/cases/types/observerlist.mjs index 1e27009e1a3f87079ee557ada5834c8ff79cd6be..6cdc6914725c1ab787e627f3fbd865972c51d471 100644 --- a/development/test/cases/types/observerlist.mjs +++ b/test/cases/types/observerlist.mjs @@ -1,5 +1,5 @@ -import {ObserverList} from "../../../../application/source/types/observerlist.mjs"; -import {Observer} from "../../../../application/source/types/observer.mjs"; +import {ObserverList} from "../../../source/types/observerlist.mjs"; +import {Observer} from "../../../source/types/observer.mjs"; import {expect} from "chai" describe('ObserverList', function () { diff --git a/development/test/cases/types/proxyobserver.mjs b/test/cases/types/proxyobserver.mjs similarity index 95% rename from development/test/cases/types/proxyobserver.mjs rename to test/cases/types/proxyobserver.mjs index 24ba1ce9da041b2f7a565c5f5361d78bf5f21bd2..8326480575966c611200bd88dd7992a8ce3307fe 100644 --- a/development/test/cases/types/proxyobserver.mjs +++ b/test/cases/types/proxyobserver.mjs @@ -1,9 +1,9 @@ import {expect} from "chai" -import {extend} from "../../../../application/source/data/extend.mjs"; -import {isObject} from "../../../../application/source/types/is.mjs"; -import {Observer} from "../../../../application/source/types/observer.mjs"; +import {extend} from "../../../source/data/extend.mjs"; +import {isObject} from "../../../source/types/is.mjs"; +import {Observer} from "../../../source/types/observer.mjs"; -import {ProxyObserver} from "../../../../application/source/types/proxyobserver.mjs"; +import {ProxyObserver} from "../../../source/types/proxyobserver.mjs"; describe('ProxyObserver', function () { diff --git a/development/test/cases/types/queue.mjs b/test/cases/types/queue.mjs similarity index 94% rename from development/test/cases/types/queue.mjs rename to test/cases/types/queue.mjs index 5ac5d7ce09907cb47d9b0f71129a8225c3645666..a2a0095f502751cf62175c92903f438174a653fc 100644 --- a/development/test/cases/types/queue.mjs +++ b/test/cases/types/queue.mjs @@ -1,5 +1,5 @@ import {expect} from "chai" -import {Queue} from "../../../../application/source/types/queue.mjs"; +import {Queue} from "../../../source/types/queue.mjs"; describe('Queue', function () { let queue; diff --git a/development/test/cases/types/randomid.mjs b/test/cases/types/randomid.mjs similarity index 88% rename from development/test/cases/types/randomid.mjs rename to test/cases/types/randomid.mjs index e770b2a3253367842ce6703c2947f07b231eb4f7..f51fc26524c6d717652bdf5873c9e9085cfb275e 100644 --- a/development/test/cases/types/randomid.mjs +++ b/test/cases/types/randomid.mjs @@ -14,7 +14,7 @@ describe('RandomID', function () { })) } - promises.push(import("../../../../application/source/types/randomid.mjs").then(m => { + promises.push(import("../../../source/types/randomid.mjs").then(m => { RandomID = m.RandomID; return true; })) diff --git a/development/test/cases/types/regex.mjs b/test/cases/types/regex.mjs similarity index 92% rename from development/test/cases/types/regex.mjs rename to test/cases/types/regex.mjs index 7a0b54195ce2c1e71e1f7335b86e801a886b6856..1eb4f5aa731c0f01e28f5abe4a11353f13b20cd9 100644 --- a/development/test/cases/types/regex.mjs +++ b/test/cases/types/regex.mjs @@ -1,6 +1,6 @@ import {expect} from "chai" -import {escapeString} from "../../../../application/source/types/regex.mjs" +import {escapeString} from "../../../source/types/regex.mjs" import {initJSDOM} from "../../util/jsdom.mjs"; diff --git a/development/test/cases/types/stack.mjs b/test/cases/types/stack.mjs similarity index 94% rename from development/test/cases/types/stack.mjs rename to test/cases/types/stack.mjs index bebf923f24802658fa25a2cba7d0f31c4709a92f..d2b6e0549a7cfdbfb4a74e2c80d945ee60251c5a 100644 --- a/development/test/cases/types/stack.mjs +++ b/test/cases/types/stack.mjs @@ -1,5 +1,5 @@ import {expect} from "chai" -import {Stack} from "../../../../application/source/types/stack.mjs"; +import {Stack} from "../../../source/types/stack.mjs"; describe('Stack', function () { diff --git a/development/test/cases/types/tokenlist.mjs b/test/cases/types/tokenlist.mjs similarity index 99% rename from development/test/cases/types/tokenlist.mjs rename to test/cases/types/tokenlist.mjs index 0fe272fade49d7745353eb0236180e3ccc7f3a20..38777eb3381500f564ee9c3a6c6706199d763367 100644 --- a/development/test/cases/types/tokenlist.mjs +++ b/test/cases/types/tokenlist.mjs @@ -1,5 +1,5 @@ import {expect} from "chai" -import {TokenList} from "../../../../application/source/types/tokenlist.mjs"; +import {TokenList} from "../../../source/types/tokenlist.mjs"; describe('TokenList', function () { diff --git a/development/test/cases/types/typeof.mjs b/test/cases/types/typeof.mjs similarity index 88% rename from development/test/cases/types/typeof.mjs rename to test/cases/types/typeof.mjs index 54416d05e3c13bcc5bac7c57910d7268e5b4ff70..61083ce7824883dd6b36af634d43e186093f2a2a 100644 --- a/development/test/cases/types/typeof.mjs +++ b/test/cases/types/typeof.mjs @@ -1,7 +1,7 @@ -import {Stack} from "../../../../application/source/types/stack.mjs"; +import {Stack} from "../../../source/types/stack.mjs"; import { typeOf -} from "../../../../application/source/types/typeof.mjs" +} from "../../../source/types/typeof.mjs" import {expect} from "chai" diff --git a/development/test/cases/types/uniquequeue.mjs b/test/cases/types/uniquequeue.mjs similarity index 96% rename from development/test/cases/types/uniquequeue.mjs rename to test/cases/types/uniquequeue.mjs index 26779504dde6017989ea9be4340b6fa209fdb766..f379c04a249347e7b0b1373568fb90b9dfaf555f 100644 --- a/development/test/cases/types/uniquequeue.mjs +++ b/test/cases/types/uniquequeue.mjs @@ -1,5 +1,5 @@ import {expect} from "chai" -import {UniqueQueue} from "../../../../application/source/types/uniquequeue.mjs"; +import {UniqueQueue} from "../../../source/types/uniquequeue.mjs"; describe('UniqueQueue', function () { diff --git a/development/test/cases/types/uuid.mjs b/test/cases/types/uuid.mjs similarity index 93% rename from development/test/cases/types/uuid.mjs rename to test/cases/types/uuid.mjs index 54812029aa0b9c39323a3f593068d178a8be38ed..7ea41dac1f9d22ba8a3113a883a782a66ee895ee 100644 --- a/development/test/cases/types/uuid.mjs +++ b/test/cases/types/uuid.mjs @@ -16,7 +16,7 @@ describe('UUID', function () { } - promises.push(import("../../../../application/source/types/uuid.mjs").then(m => { + promises.push(import("../../../source/types/uuid.mjs").then(m => { UUID = m.UUID; return true; })) diff --git a/development/test/cases/types/validate.mjs b/test/cases/types/validate.mjs similarity index 98% rename from development/test/cases/types/validate.mjs rename to test/cases/types/validate.mjs index b1944e1c922e9e13f1342a357a77faf7bef34572..9766dfe1b4d199b0e844e500ee401a380937eac6 100644 --- a/development/test/cases/types/validate.mjs +++ b/test/cases/types/validate.mjs @@ -9,10 +9,10 @@ import { validateInstance, validateIterable, validateSymbol -} from "../../../../application/source/types/validate.mjs" +} from "../../../source/types/validate.mjs" -import {Base} from "../../../../application/source/types/base.mjs" -import {ID} from "../../../../application/source/types/id.mjs" +import {Base} from "../../../source/types/base.mjs" +import {ID} from "../../../source/types/id.mjs" import {expect} from "chai" diff --git a/development/test/cases/types/version.mjs b/test/cases/types/version.mjs similarity index 94% rename from development/test/cases/types/version.mjs rename to test/cases/types/version.mjs index d0dde8ac613239fbc68713f5c1de9d4e7874c020..d18dfc9e55f7001f5a6a75195874fffdb7d6e188 100644 --- a/development/test/cases/types/version.mjs +++ b/test/cases/types/version.mjs @@ -1,6 +1,6 @@ import { Version -} from "../../../../application/source/types/version.mjs" +} from "../../../source/types/version.mjs" import {expect} from "chai" diff --git a/development/test/cases/util/clone.mjs b/test/cases/util/clone.mjs similarity index 98% rename from development/test/cases/util/clone.mjs rename to test/cases/util/clone.mjs index b4df6a7925422694bddce982b337e2064b73dd9a..f238ccf9b25c7ff953b96687cbc015daaeb185ba 100644 --- a/development/test/cases/util/clone.mjs +++ b/test/cases/util/clone.mjs @@ -1,4 +1,4 @@ -import {clone} from "../../../../application/source/util/clone.mjs"; +import {clone} from "../../../source/util/clone.mjs"; import {expect} from "chai" describe('Clone', function () { diff --git a/development/test/cases/util/comparator.mjs b/test/cases/util/comparator.mjs similarity index 98% rename from development/test/cases/util/comparator.mjs rename to test/cases/util/comparator.mjs index 1d6f203b776a1d6ef2893729d447fcc2d4e6d155..77a367e301954109b9fd0ab120fa054a47bf5ad9 100644 --- a/development/test/cases/util/comparator.mjs +++ b/test/cases/util/comparator.mjs @@ -1,5 +1,5 @@ import {expect} from "chai" -import {Comparator} from "../../../../application/source/util/comparator.mjs"; +import {Comparator} from "../../../source/util/comparator.mjs"; describe('Comparator', function () { diff --git a/development/test/cases/util/deadmansswitch.mjs b/test/cases/util/deadmansswitch.mjs similarity index 94% rename from development/test/cases/util/deadmansswitch.mjs rename to test/cases/util/deadmansswitch.mjs index 5a96cd3541a7789ff705e3768e190551c6bb95e8..6baf9caf50123e65a767fe9bb79a33c4383c8601 100644 --- a/development/test/cases/util/deadmansswitch.mjs +++ b/test/cases/util/deadmansswitch.mjs @@ -1,4 +1,4 @@ -import {DeadMansSwitch} from "../../../../application/source/util/deadmansswitch.mjs"; +import {DeadMansSwitch} from "../../../source/util/deadmansswitch.mjs"; describe('DeadMansSwitch', function () { diff --git a/development/test/cases/util/freeze.mjs b/test/cases/util/freeze.mjs similarity index 93% rename from development/test/cases/util/freeze.mjs rename to test/cases/util/freeze.mjs index 9f4cd0de7dd11f2ae603454da314b7c6d50dd777..22a4f07a32e3ffad5bea162f593e8f3f4b581f31 100644 --- a/development/test/cases/util/freeze.mjs +++ b/test/cases/util/freeze.mjs @@ -1,5 +1,5 @@ import {expect} from "chai" -import {deepFreeze} from "../../../../application/source/util/freeze.mjs"; +import {deepFreeze} from "../../../source/util/freeze.mjs"; describe('deepFreeze', function () { diff --git a/development/test/cases/util/processing.mjs b/test/cases/util/processing.mjs similarity index 97% rename from development/test/cases/util/processing.mjs rename to test/cases/util/processing.mjs index 2fd21116990f5200c7d771b7c35d86d35e07f528..a1b81ac72729f3c915d3c84caf2020da5cd2092b 100644 --- a/development/test/cases/util/processing.mjs +++ b/test/cases/util/processing.mjs @@ -1,5 +1,5 @@ import {expect} from "chai" -import {Processing} from "../../../../application/source/util/processing.mjs"; +import {Processing} from "../../../source/util/processing.mjs"; describe('Processing', function () { diff --git a/development/test/cases/util/trimspaces.mjs b/test/cases/util/trimspaces.mjs similarity index 88% rename from development/test/cases/util/trimspaces.mjs rename to test/cases/util/trimspaces.mjs index e9dc90dfdf2b5f06999e26547640a4feefedc5c6..85ca5e99571c77e928f0488f80d114562c04cad8 100644 --- a/development/test/cases/util/trimspaces.mjs +++ b/test/cases/util/trimspaces.mjs @@ -1,5 +1,5 @@ import {expect} from "chai" -import {trimSpaces} from "../../../../application/source/util/trimspaces.mjs"; +import {trimSpaces} from "../../../source/util/trimspaces.mjs"; describe('trimSpaces', function () { diff --git a/development/test/util/chai-dom.mjs b/test/util/chai-dom.mjs similarity index 100% rename from development/test/util/chai-dom.mjs rename to test/util/chai-dom.mjs diff --git a/development/test/util/cleanupdom.mjs b/test/util/cleanupdom.mjs similarity index 100% rename from development/test/util/cleanupdom.mjs rename to test/util/cleanupdom.mjs diff --git a/development/test/util/jsdom.mjs b/test/util/jsdom.mjs similarity index 94% rename from development/test/util/jsdom.mjs rename to test/util/jsdom.mjs index 1cc98c1182e65f7b842e3ed4e8dc509c1d2a8785..aa9474689a7eb4e0080407c7db005c24bfe8b759 100644 --- a/development/test/util/jsdom.mjs +++ b/test/util/jsdom.mjs @@ -1,7 +1,7 @@ 'use strict'; -import {extend} from "../../../application/source/data/extend.mjs"; -import {getGlobal} from "../../../application/source/types/global.mjs"; +import {extend} from "../../source/data/extend.mjs"; +import {getGlobal} from "../../source/types/global.mjs"; export const isBrowser = new Function("try {return this===window;}catch(e){ return false;}"); export const isNode = new Function("try {return this===global;}catch(e){return false;}"); diff --git a/development/test/util/localstorage.mjs b/test/util/localstorage.mjs similarity index 100% rename from development/test/util/localstorage.mjs rename to test/util/localstorage.mjs diff --git a/development/test/util/websocket.mjs b/test/util/websocket.mjs similarity index 87% rename from development/test/util/websocket.mjs rename to test/util/websocket.mjs index b7ac1ce1944a16bdc13475dc35b331f5724dde0f..d1f6101541faaa20a97a9ad3dc7d5e2764755c6e 100644 --- a/development/test/util/websocket.mjs +++ b/test/util/websocket.mjs @@ -1,4 +1,4 @@ -import {getGlobal} from "../../../application/source/types/global.mjs"; +import {getGlobal} from "../../source/types/global.mjs"; function initWebSocket() { if (typeof window === "object" && window['WebSocket']) return Promise.resolve(); diff --git a/development/test/web/import.js b/test/web/import.js similarity index 94% rename from development/test/web/import.js rename to test/web/import.js index 72a91f0182e6894e11995a43144d21a76fd9f1fb..8380c3953d3dfc9f281b7caee1a3503d6bc36c6e 100644 --- a/development/test/web/import.js +++ b/test/web/import.js @@ -1,93 +1,97 @@ /** this file was created automatically by the make target test-browser-monster */ import "./prepare.js"; -import "../cases/monster.mjs"; -import "../cases/logging/logger.mjs"; -import "../cases/logging/logentry.mjs"; -import "../cases/logging/handler/console.mjs"; -import "../cases/logging/handler.mjs"; import "../cases/text/formatter.mjs"; import "../cases/text/util.mjs"; -import "../cases/dom/slotted-nodes.mjs"; +import "../cases/text/bracketed-key-value-hash.mjs"; +import "../cases/math/random.mjs"; +import "../cases/util/trimspaces.mjs"; +import "../cases/util/processing.mjs"; +import "../cases/util/deadmansswitch.mjs"; +import "../cases/util/comparator.mjs"; +import "../cases/util/freeze.mjs"; +import "../cases/util/clone.mjs"; +import "../cases/logging/handler/console.mjs"; +import "../cases/logging/logger.mjs"; +import "../cases/logging/handler.mjs"; +import "../cases/logging/logentry.mjs"; +import "../cases/net/webconnect.mjs"; +import "../cases/net/webconnect/message.mjs"; +import "../cases/monster.mjs"; +import "../cases/dom/dimension.mjs"; import "../cases/dom/resource/link/stylesheet.mjs"; -import "../cases/dom/resource/data.mjs"; import "../cases/dom/resource/link.mjs"; import "../cases/dom/resource/script.mjs"; +import "../cases/dom/resource/data.mjs"; +import "../cases/dom/util/init-options-from-attributes.mjs"; +import "../cases/dom/util/extract-keys.mjs"; +import "../cases/dom/worker/factory.mjs"; import "../cases/dom/updater.mjs"; -import "../cases/dom/customcontrol.mjs"; import "../cases/dom/locale.mjs"; import "../cases/dom/theme.mjs"; -import "../cases/dom/resource.mjs"; -import "../cases/dom/resourcemanager.mjs"; -import "../cases/dom/util.mjs"; -import "../cases/dom/find.mjs"; -import "../cases/dom/dimension.mjs"; import "../cases/dom/customelement.mjs"; -import "../cases/dom/attributes.mjs"; -import "../cases/dom/events.mjs"; -import "../cases/dom/worker/factory.mjs"; -import "../cases/dom/template.mjs"; -import "../cases/dom/ready.mjs"; import "../cases/dom/focusmanager.mjs"; +import "../cases/dom/find.mjs"; +import "../cases/dom/ready.mjs"; +import "../cases/dom/util.mjs"; +import "../cases/dom/customelement-initfromscripthost.mjs"; +import "../cases/dom/slotted-nodes.mjs"; +import "../cases/dom/attributes.mjs"; +import "../cases/dom/resource.mjs"; +import "../cases/dom/resourcemanager.mjs"; import "../cases/dom/assembler.mjs"; -import "../cases/i18n/translations.mjs"; -import "../cases/i18n/locale.mjs"; -import "../cases/i18n/formatter.mjs"; -import "../cases/i18n/providers/embed.mjs"; -import "../cases/i18n/providers/fetch.mjs"; -import "../cases/i18n/provider.mjs"; -import "../cases/net/webconnect/message.mjs"; -import "../cases/net/webconnect.mjs"; +import "../cases/dom/customcontrol.mjs"; +import "../cases/dom/template.mjs"; +import "../cases/dom/events.mjs"; +import "../cases/data/datasource/dom.mjs"; +import "../cases/data/datasource/storage/localstorage.mjs"; +import "../cases/data/datasource/storage/sessionstorage.mjs"; +import "../cases/data/datasource/server.mjs"; +import "../cases/data/datasource/server/websocket.mjs"; +import "../cases/data/datasource/server/restapi.mjs"; +import "../cases/data/datasource.mjs"; +import "../cases/data/buildmap.mjs"; +import "../cases/data/transformer.mjs"; +import "../cases/data/diff.mjs"; +import "../cases/data/buildtree.mjs"; +import "../cases/data/pathfinder.mjs"; +import "../cases/data/pipe.mjs"; +import "../cases/data/extend.mjs"; +import "../cases/constraint/invalid.mjs"; +import "../cases/constraint/abstractoperator.mjs"; +import "../cases/constraint/oroperator.mjs"; +import "../cases/constraint/isobject.mjs"; +import "../cases/constraint/andoperator.mjs"; +import "../cases/constraint/isarray.mjs"; +import "../cases/constraint/valid.mjs"; +import "../cases/types/nodelist.mjs"; +import "../cases/types/base.mjs"; import "../cases/types/mediatype.mjs"; -import "../cases/types/typeof.mjs"; -import "../cases/types/observerlist.mjs"; -import "../cases/types/randomid.mjs"; -import "../cases/types/observablequeue.mjs"; -import "../cases/types/uuid.mjs"; -import "../cases/types/observer.mjs"; -import "../cases/types/internal.mjs"; import "../cases/types/tokenlist.mjs"; -import "../cases/types/queue.mjs"; -import "../cases/types/stack.mjs"; -import "../cases/types/binary.mjs"; -import "../cases/types/basewithoptions.mjs"; -import "../cases/types/regex.mjs"; import "../cases/types/proxyobserver.mjs"; -import "../cases/types/nodelist.mjs"; import "../cases/types/version.mjs"; -import "../cases/types/node.mjs"; -import "../cases/types/noderecursiveiterator.mjs"; import "../cases/types/global.mjs"; +import "../cases/types/observerlist.mjs"; +import "../cases/types/internal.mjs"; +import "../cases/types/observablequeue.mjs"; import "../cases/types/dataurl.mjs"; +import "../cases/types/binary.mjs"; +import "../cases/types/observer.mjs"; +import "../cases/types/regex.mjs"; +import "../cases/types/randomid.mjs"; +import "../cases/types/id.mjs"; +import "../cases/types/uuid.mjs"; +import "../cases/types/is.mjs"; import "../cases/types/validate.mjs"; +import "../cases/types/typeof.mjs"; import "../cases/types/uniquequeue.mjs"; -import "../cases/types/base.mjs"; -import "../cases/types/is.mjs"; -import "../cases/types/id.mjs"; -import "../cases/constraint/isobject.mjs"; -import "../cases/constraint/invalid.mjs"; -import "../cases/constraint/andoperator.mjs"; -import "../cases/constraint/oroperator.mjs"; -import "../cases/constraint/isarray.mjs"; -import "../cases/constraint/abstractoperator.mjs"; -import "../cases/constraint/valid.mjs"; -import "../cases/util/trimspaces.mjs"; -import "../cases/util/deadmansswitch.mjs"; -import "../cases/util/freeze.mjs"; -import "../cases/util/comparator.mjs"; -import "../cases/util/clone.mjs"; -import "../cases/util/processing.mjs"; -import "../cases/data/extend.mjs"; -import "../cases/data/pipe.mjs"; -import "../cases/data/buildmap.mjs"; -import "../cases/data/datasource.mjs"; -import "../cases/data/buildtree.mjs"; -import "../cases/data/transformer.mjs"; -import "../cases/data/pathfinder.mjs"; -import "../cases/data/diff.mjs"; -import "../cases/data/datasource/server.mjs"; -import "../cases/data/datasource/storage/sessionstorage.mjs"; -import "../cases/data/datasource/storage/localstorage.mjs"; -import "../cases/data/datasource/dom.mjs"; -import "../cases/data/datasource/server/restapi.mjs"; -import "../cases/data/datasource/server/websocket.mjs"; -import "../cases/math/random.mjs"; +import "../cases/types/stack.mjs"; +import "../cases/types/basewithoptions.mjs"; +import "../cases/types/node.mjs"; +import "../cases/types/queue.mjs"; +import "../cases/types/noderecursiveiterator.mjs"; +import "../cases/i18n/formatter.mjs"; +import "../cases/i18n/locale.mjs"; +import "../cases/i18n/provider.mjs"; +import "../cases/i18n/providers/fetch.mjs"; +import "../cases/i18n/providers/embed.mjs"; +import "../cases/i18n/translations.mjs"; diff --git a/development/test/web/mocha.css b/test/web/mocha.css similarity index 100% rename from development/test/web/mocha.css rename to test/web/mocha.css diff --git a/development/test/web/mocha.js b/test/web/mocha.js similarity index 100% rename from development/test/web/mocha.js rename to test/web/mocha.js diff --git a/development/test/web/prepare.js b/test/web/prepare.js similarity index 100% rename from development/test/web/prepare.js rename to test/web/prepare.js diff --git a/development/test/web/test.html b/test/web/test.html similarity index 77% rename from development/test/web/test.html rename to test/web/test.html index b5d1c28f19a59ad028ddc9945faefedd9868adbf..f469aa49ead1e5621215ee802b6e41b611ec3743 100644 --- a/development/test/web/test.html +++ b/test/web/test.html @@ -5,7 +5,7 @@ <title>Mocha Monster</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <link rel="stylesheet" href="mocha.css"/> - <script id="polyfill" src="https://polyfill.io/v3/polyfill.min.js?features=Array.from,Array.isArray,Array.prototype.entries,Array.prototype.fill,Array.prototype.filter,Array.prototype.forEach,Array.prototype.includes,Array.prototype.indexOf,Array.prototype.keys,Array.prototype.lastIndexOf,Array.prototype.map,Array.prototype.reduce,Array.prototype.sort,ArrayBuffer,atob,Blob,CustomEvent,DataView,document,Document,DocumentFragment,Element,Event,fetch,globalThis,HTMLDocument,HTMLTemplateElement,Intl,JSON,Map,Math.log2,Number.isInteger,Object.assign,Object.defineProperty,Object.entries,Object.freeze,Object.getOwnPropertyDescriptor,Object.getOwnPropertyNames,Object.getPrototypeOf,Object.keys,Promise,Reflect,Reflect.defineProperty,Reflect.get,Reflect.getOwnPropertyDescriptor,Reflect.setPrototypeOf,Set,String.prototype.endsWith,String.prototype.includes,String.prototype.matchAll,String.prototype.padStart,String.prototype.startsWith,String.prototype.trim,Symbol,Symbol.for,Symbol.hasInstance,Symbol.iterator,Uint16Array,Uint8Array,URL,WeakMap,WeakSet" + <script id="polyfill" src="https://polyfill.io/v3/polyfill.min.js?features=Array.from,Array.isArray,Array.prototype.entries,Array.prototype.fill,Array.prototype.filter,Array.prototype.forEach,Array.prototype.includes,Array.prototype.indexOf,Array.prototype.keys,Array.prototype.lastIndexOf,Array.prototype.map,Array.prototype.reduce,Array.prototype.sort,ArrayBuffer,atob,Blob,CustomEvent,DataView,document,Document,DocumentFragment,Element,Event,fetch,globalThis,HTMLDocument,HTMLTemplateElement,Intl,JSON,Map,Math.log2,MutationObserver,Number.isInteger,Object.assign,Object.defineProperty,Object.entries,Object.freeze,Object.getOwnPropertyDescriptor,Object.getOwnPropertyNames,Object.getPrototypeOf,Object.keys,Promise,Reflect,Reflect.defineProperty,Reflect.get,Reflect.getOwnPropertyDescriptor,Reflect.setPrototypeOf,Set,String.prototype.endsWith,String.prototype.includes,String.prototype.matchAll,String.prototype.padStart,String.prototype.startsWith,String.prototype.trim,Symbol,Symbol.for,Symbol.hasInstance,Symbol.iterator,Uint16Array,Uint8Array,URL,WeakMap,WeakSet" src="https://polyfill.io/v3/polyfill.min.js?features=Array.from,Array.isArray,Array.prototype.entries,Array.prototype.fill,Array.prototype.forEach,Array.prototype.indexOf,Array.prototype.keys,Array.prototype.lastIndexOf,Array.prototype.map,Array.prototype.reduce,Array.prototype.sort,ArrayBuffer,atob,DataView,document,DocumentFragment,Element,Event,globalThis,HTMLDocument,HTMLTemplateElement,JSON,Map,Math.log2,Number.isInteger,Object.assign,Object.defineProperty,Object.entries,Object.getOwnPropertyDescriptor,Object.getPrototypeOf,Object.keys,Promise,Reflect,Reflect.defineProperty,Reflect.get,Reflect.getOwnPropertyDescriptor,Reflect.setPrototypeOf,Set,String.prototype.endsWith,String.prototype.matchAll,String.prototype.padStart,String.prototype.startsWith,String.prototype.trim,Symbol,Symbol.iterator,WeakMap,WeakSet" crossorigin="anonymous" referrerpolicy="no-referrer"></script> @@ -14,8 +14,8 @@ </head> <body> <div id="headline" style="display: flex;align-items: center;justify-content: center;flex-direction: column;"> - <h1 style='margin-bottom: 0.1em;'>Monster 3.35.4</h1> - <div id="lastupdate" style='font-size:0.7em'>last update Sa 1. Apr 17:29:43 CEST 2023</div> + <h1 style='margin-bottom: 0.1em;'>Monster 3.51.4</h1> + <div id="lastupdate" style='font-size:0.7em'>last update Mi 1. Nov 15:22:40 CET 2023</div> </div> <div id="mocks"></div> <div id="mocha"></div> diff --git a/test/web/tests.js b/test/web/tests.js new file mode 100644 index 0000000000000000000000000000000000000000..0597225aa49b1e9cc182c0a549311a8c9becb0ef --- /dev/null +++ b/test/web/tests.js @@ -0,0 +1,35581 @@ +(() => { + var __create = Object.create; + var __defProp = Object.defineProperty; + var __getOwnPropDesc = Object.getOwnPropertyDescriptor; + var __getOwnPropNames = Object.getOwnPropertyNames; + var __getProtoOf = Object.getPrototypeOf; + var __hasOwnProp = Object.prototype.hasOwnProperty; + var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { + get: (a2, b) => (typeof require !== "undefined" ? require : a2)[b] + }) : x)(function(x) { + if (typeof require !== "undefined") + return require.apply(this, arguments); + throw new Error('Dynamic require of "' + x + '" is not supported'); + }); + var __esm = (fn, res) => function __init() { + return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; + }; + var __commonJS = (cb, mod) => function __require2() { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; + }; + var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; + }; + var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod + )); + + // node_modules/.pnpm/assertion-error@1.1.0/node_modules/assertion-error/index.js + var require_assertion_error = __commonJS({ + "node_modules/.pnpm/assertion-error@1.1.0/node_modules/assertion-error/index.js"(exports, module) { + function exclude() { + var excludes = [].slice.call(arguments); + function excludeProps(res, obj) { + Object.keys(obj).forEach(function(key) { + if (!~excludes.indexOf(key)) + res[key] = obj[key]; + }); + } + return function extendExclude() { + var args = [].slice.call(arguments), i = 0, res = {}; + for (; i < args.length; i++) { + excludeProps(res, args[i]); + } + return res; + }; + } + module.exports = AssertionError2; + function AssertionError2(message, _props, ssf) { + var extend2 = exclude("name", "message", "stack", "constructor", "toJSON"), props = extend2(_props || {}); + this.message = message || "Unspecified AssertionError"; + this.showDiff = false; + for (var key in props) { + this[key] = props[key]; + } + ssf = ssf || AssertionError2; + if (Error.captureStackTrace) { + Error.captureStackTrace(this, ssf); + } else { + try { + throw new Error(); + } catch (e) { + this.stack = e.stack; + } + } + } + AssertionError2.prototype = Object.create(Error.prototype); + AssertionError2.prototype.name = "AssertionError"; + AssertionError2.prototype.constructor = AssertionError2; + AssertionError2.prototype.toJSON = function(stack) { + var extend2 = exclude("constructor", "toJSON", "stack"), props = extend2({ name: this.name }, this); + if (false !== stack && this.stack) { + props.stack = this.stack; + } + return props; + }; + } + }); + + // node_modules/.pnpm/pathval@1.1.1/node_modules/pathval/index.js + var require_pathval = __commonJS({ + "node_modules/.pnpm/pathval@1.1.1/node_modules/pathval/index.js"(exports, module) { + "use strict"; + function hasProperty(obj, name) { + if (typeof obj === "undefined" || obj === null) { + return false; + } + return name in Object(obj); + } + function parsePath(path) { + var str = path.replace(/([^\\])\[/g, "$1.["); + var parts = str.match(/(\\\.|[^.]+?)+/g); + return parts.map(function mapMatches(value) { + if (value === "constructor" || value === "__proto__" || value === "prototype") { + return {}; + } + var regexp = /^\[(\d+)\]$/; + var mArr = regexp.exec(value); + var parsed = null; + if (mArr) { + parsed = { i: parseFloat(mArr[1]) }; + } else { + parsed = { p: value.replace(/\\([.[\]])/g, "$1") }; + } + return parsed; + }); + } + function internalGetPathValue(obj, parsed, pathDepth) { + var temporaryValue = obj; + var res = null; + pathDepth = typeof pathDepth === "undefined" ? parsed.length : pathDepth; + for (var i = 0; i < pathDepth; i++) { + var part = parsed[i]; + if (temporaryValue) { + if (typeof part.p === "undefined") { + temporaryValue = temporaryValue[part.i]; + } else { + temporaryValue = temporaryValue[part.p]; + } + if (i === pathDepth - 1) { + res = temporaryValue; + } + } + } + return res; + } + function internalSetPathValue(obj, val, parsed) { + var tempObj = obj; + var pathDepth = parsed.length; + var part = null; + for (var i = 0; i < pathDepth; i++) { + var propName = null; + var propVal = null; + part = parsed[i]; + if (i === pathDepth - 1) { + propName = typeof part.p === "undefined" ? part.i : part.p; + tempObj[propName] = val; + } else if (typeof part.p !== "undefined" && tempObj[part.p]) { + tempObj = tempObj[part.p]; + } else if (typeof part.i !== "undefined" && tempObj[part.i]) { + tempObj = tempObj[part.i]; + } else { + var next = parsed[i + 1]; + propName = typeof part.p === "undefined" ? part.i : part.p; + propVal = typeof next.p === "undefined" ? [] : {}; + tempObj[propName] = propVal; + tempObj = tempObj[propName]; + } + } + } + function getPathInfo(obj, path) { + var parsed = parsePath(path); + var last = parsed[parsed.length - 1]; + var info = { + parent: parsed.length > 1 ? internalGetPathValue(obj, parsed, parsed.length - 1) : obj, + name: last.p || last.i, + value: internalGetPathValue(obj, parsed) + }; + info.exists = hasProperty(info.parent, info.name); + return info; + } + function getPathValue(obj, path) { + var info = getPathInfo(obj, path); + return info.value; + } + function setPathValue(obj, path, val) { + var parsed = parsePath(path); + internalSetPathValue(obj, val, parsed); + return obj; + } + module.exports = { + hasProperty, + getPathInfo, + getPathValue, + setPathValue + }; + } + }); + + // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/flag.js + var require_flag = __commonJS({ + "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/flag.js"(exports, module) { + module.exports = function flag(obj, key, value) { + var flags = obj.__flags || (obj.__flags = /* @__PURE__ */ Object.create(null)); + if (arguments.length === 3) { + flags[key] = value; + } else { + return flags[key]; + } + }; + } + }); + + // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/test.js + var require_test = __commonJS({ + "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/test.js"(exports, module) { + var flag = require_flag(); + module.exports = function test(obj, args) { + var negate = flag(obj, "negate"), expr = args[0]; + return negate ? !expr : expr; + }; + } + }); + + // node_modules/.pnpm/type-detect@4.0.8/node_modules/type-detect/type-detect.js + var require_type_detect = __commonJS({ + "node_modules/.pnpm/type-detect@4.0.8/node_modules/type-detect/type-detect.js"(exports, module) { + (function(global5, factory) { + typeof exports === "object" && typeof module !== "undefined" ? module.exports = factory() : typeof define === "function" && define.amd ? define(factory) : global5.typeDetect = factory(); + })(exports, function() { + "use strict"; + var promiseExists = typeof Promise === "function"; + var globalObject = typeof self === "object" ? self : global; + var symbolExists = typeof Symbol !== "undefined"; + var mapExists = typeof Map !== "undefined"; + var setExists = typeof Set !== "undefined"; + var weakMapExists = typeof WeakMap !== "undefined"; + var weakSetExists = typeof WeakSet !== "undefined"; + var dataViewExists = typeof DataView !== "undefined"; + var symbolIteratorExists = symbolExists && typeof Symbol.iterator !== "undefined"; + var symbolToStringTagExists = symbolExists && typeof Symbol.toStringTag !== "undefined"; + var setEntriesExists = setExists && typeof Set.prototype.entries === "function"; + var mapEntriesExists = mapExists && typeof Map.prototype.entries === "function"; + var setIteratorPrototype = setEntriesExists && Object.getPrototypeOf((/* @__PURE__ */ new Set()).entries()); + var mapIteratorPrototype = mapEntriesExists && Object.getPrototypeOf((/* @__PURE__ */ new Map()).entries()); + var arrayIteratorExists = symbolIteratorExists && typeof Array.prototype[Symbol.iterator] === "function"; + var arrayIteratorPrototype = arrayIteratorExists && Object.getPrototypeOf([][Symbol.iterator]()); + var stringIteratorExists = symbolIteratorExists && typeof String.prototype[Symbol.iterator] === "function"; + var stringIteratorPrototype = stringIteratorExists && Object.getPrototypeOf(""[Symbol.iterator]()); + var toStringLeftSliceLength = 8; + var toStringRightSliceLength = -1; + function typeDetect(obj) { + var typeofObj = typeof obj; + if (typeofObj !== "object") { + return typeofObj; + } + if (obj === null) { + return "null"; + } + if (obj === globalObject) { + return "global"; + } + if (Array.isArray(obj) && (symbolToStringTagExists === false || !(Symbol.toStringTag in obj))) { + return "Array"; + } + if (typeof window === "object" && window !== null) { + if (typeof window.location === "object" && obj === window.location) { + return "Location"; + } + if (typeof window.document === "object" && obj === window.document) { + return "Document"; + } + if (typeof window.navigator === "object") { + if (typeof window.navigator.mimeTypes === "object" && obj === window.navigator.mimeTypes) { + return "MimeTypeArray"; + } + if (typeof window.navigator.plugins === "object" && obj === window.navigator.plugins) { + return "PluginArray"; + } + } + if ((typeof window.HTMLElement === "function" || typeof window.HTMLElement === "object") && obj instanceof window.HTMLElement) { + if (obj.tagName === "BLOCKQUOTE") { + return "HTMLQuoteElement"; + } + if (obj.tagName === "TD") { + return "HTMLTableDataCellElement"; + } + if (obj.tagName === "TH") { + return "HTMLTableHeaderCellElement"; + } + } + } + var stringTag = symbolToStringTagExists && obj[Symbol.toStringTag]; + if (typeof stringTag === "string") { + return stringTag; + } + var objPrototype = Object.getPrototypeOf(obj); + if (objPrototype === RegExp.prototype) { + return "RegExp"; + } + if (objPrototype === Date.prototype) { + return "Date"; + } + if (promiseExists && objPrototype === Promise.prototype) { + return "Promise"; + } + if (setExists && objPrototype === Set.prototype) { + return "Set"; + } + if (mapExists && objPrototype === Map.prototype) { + return "Map"; + } + if (weakSetExists && objPrototype === WeakSet.prototype) { + return "WeakSet"; + } + if (weakMapExists && objPrototype === WeakMap.prototype) { + return "WeakMap"; + } + if (dataViewExists && objPrototype === DataView.prototype) { + return "DataView"; + } + if (mapExists && objPrototype === mapIteratorPrototype) { + return "Map Iterator"; + } + if (setExists && objPrototype === setIteratorPrototype) { + return "Set Iterator"; + } + if (arrayIteratorExists && objPrototype === arrayIteratorPrototype) { + return "Array Iterator"; + } + if (stringIteratorExists && objPrototype === stringIteratorPrototype) { + return "String Iterator"; + } + if (objPrototype === null) { + return "Object"; + } + return Object.prototype.toString.call(obj).slice(toStringLeftSliceLength, toStringRightSliceLength); + } + return typeDetect; + }); + } + }); + + // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/expectTypes.js + var require_expectTypes = __commonJS({ + "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/expectTypes.js"(exports, module) { + var AssertionError2 = require_assertion_error(); + var flag = require_flag(); + var type = require_type_detect(); + module.exports = function expectTypes(obj, types) { + var flagMsg = flag(obj, "message"); + var ssfi = flag(obj, "ssfi"); + flagMsg = flagMsg ? flagMsg + ": " : ""; + obj = flag(obj, "object"); + types = types.map(function(t) { + return t.toLowerCase(); + }); + types.sort(); + var str = types.map(function(t, index) { + var art = ~["a", "e", "i", "o", "u"].indexOf(t.charAt(0)) ? "an" : "a"; + var or = types.length > 1 && index === types.length - 1 ? "or " : ""; + return or + art + " " + t; + }).join(", "); + var objType = type(obj).toLowerCase(); + if (!types.some(function(expected) { + return objType === expected; + })) { + throw new AssertionError2( + flagMsg + "object tested must be " + str + ", but " + objType + " given", + void 0, + ssfi + ); + } + }; + } + }); + + // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/getActual.js + var require_getActual = __commonJS({ + "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/getActual.js"(exports, module) { + module.exports = function getActual(obj, args) { + return args.length > 4 ? args[4] : obj._obj; + }; + } + }); + + // node_modules/.pnpm/get-func-name@2.0.2/node_modules/get-func-name/index.js + var require_get_func_name = __commonJS({ + "node_modules/.pnpm/get-func-name@2.0.2/node_modules/get-func-name/index.js"(exports, module) { + "use strict"; + var toString = Function.prototype.toString; + var functionNameMatch = /\s*function(?:\s|\s*\/\*[^(?:*\/)]+\*\/\s*)*([^\s\(\/]+)/; + var maxFunctionSourceLength = 512; + function getFuncName(aFunc) { + if (typeof aFunc !== "function") { + return null; + } + var name = ""; + if (typeof Function.prototype.name === "undefined" && typeof aFunc.name === "undefined") { + var functionSource = toString.call(aFunc); + if (functionSource.indexOf("(") > maxFunctionSourceLength) { + return name; + } + var match = functionSource.match(functionNameMatch); + if (match) { + name = match[1]; + } + } else { + name = aFunc.name; + } + return name; + } + module.exports = getFuncName; + } + }); + + // (disabled):node_modules/.pnpm/util@0.12.5/node_modules/util/util.js + var require_util = __commonJS({ + "(disabled):node_modules/.pnpm/util@0.12.5/node_modules/util/util.js"() { + } + }); + + // node_modules/.pnpm/loupe@2.3.7/node_modules/loupe/loupe.js + var require_loupe = __commonJS({ + "node_modules/.pnpm/loupe@2.3.7/node_modules/loupe/loupe.js"(exports, module) { + (function(global5, factory) { + typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : (global5 = typeof globalThis !== "undefined" ? globalThis : global5 || self, factory(global5.loupe = {})); + })(exports, function(exports2) { + "use strict"; + function _typeof(obj) { + "@babel/helpers - typeof"; + if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { + _typeof = function(obj2) { + return typeof obj2; + }; + } else { + _typeof = function(obj2) { + return obj2 && typeof Symbol === "function" && obj2.constructor === Symbol && obj2 !== Symbol.prototype ? "symbol" : typeof obj2; + }; + } + return _typeof(obj); + } + function _slicedToArray(arr, i) { + return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); + } + function _arrayWithHoles(arr) { + if (Array.isArray(arr)) + return arr; + } + function _iterableToArrayLimit(arr, i) { + if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) + return; + var _arr = []; + var _n = true; + var _d = false; + var _e = void 0; + try { + for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { + _arr.push(_s.value); + if (i && _arr.length === i) + break; + } + } catch (err) { + _d = true; + _e = err; + } finally { + try { + if (!_n && _i["return"] != null) + _i["return"](); + } finally { + if (_d) + throw _e; + } + } + return _arr; + } + function _unsupportedIterableToArray(o, minLen) { + if (!o) + return; + if (typeof o === "string") + return _arrayLikeToArray(o, minLen); + var n = Object.prototype.toString.call(o).slice(8, -1); + if (n === "Object" && o.constructor) + n = o.constructor.name; + if (n === "Map" || n === "Set") + return Array.from(o); + if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) + return _arrayLikeToArray(o, minLen); + } + function _arrayLikeToArray(arr, len) { + if (len == null || len > arr.length) + len = arr.length; + for (var i = 0, arr2 = new Array(len); i < len; i++) + arr2[i] = arr[i]; + return arr2; + } + function _nonIterableRest() { + throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); + } + var ansiColors = { + bold: ["1", "22"], + dim: ["2", "22"], + italic: ["3", "23"], + underline: ["4", "24"], + // 5 & 6 are blinking + inverse: ["7", "27"], + hidden: ["8", "28"], + strike: ["9", "29"], + // 10-20 are fonts + // 21-29 are resets for 1-9 + black: ["30", "39"], + red: ["31", "39"], + green: ["32", "39"], + yellow: ["33", "39"], + blue: ["34", "39"], + magenta: ["35", "39"], + cyan: ["36", "39"], + white: ["37", "39"], + brightblack: ["30;1", "39"], + brightred: ["31;1", "39"], + brightgreen: ["32;1", "39"], + brightyellow: ["33;1", "39"], + brightblue: ["34;1", "39"], + brightmagenta: ["35;1", "39"], + brightcyan: ["36;1", "39"], + brightwhite: ["37;1", "39"], + grey: ["90", "39"] + }; + var styles = { + special: "cyan", + number: "yellow", + bigint: "yellow", + boolean: "yellow", + undefined: "grey", + null: "bold", + string: "green", + symbol: "green", + date: "magenta", + regexp: "red" + }; + var truncator = "\u2026"; + function colorise(value, styleType) { + var color = ansiColors[styles[styleType]] || ansiColors[styleType]; + if (!color) { + return String(value); + } + return "\x1B[".concat(color[0], "m").concat(String(value), "\x1B[").concat(color[1], "m"); + } + function normaliseOptions() { + var _ref = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {}, _ref$showHidden = _ref.showHidden, showHidden = _ref$showHidden === void 0 ? false : _ref$showHidden, _ref$depth = _ref.depth, depth = _ref$depth === void 0 ? 2 : _ref$depth, _ref$colors = _ref.colors, colors = _ref$colors === void 0 ? false : _ref$colors, _ref$customInspect = _ref.customInspect, customInspect = _ref$customInspect === void 0 ? true : _ref$customInspect, _ref$showProxy = _ref.showProxy, showProxy = _ref$showProxy === void 0 ? false : _ref$showProxy, _ref$maxArrayLength = _ref.maxArrayLength, maxArrayLength = _ref$maxArrayLength === void 0 ? Infinity : _ref$maxArrayLength, _ref$breakLength = _ref.breakLength, breakLength = _ref$breakLength === void 0 ? Infinity : _ref$breakLength, _ref$seen = _ref.seen, seen = _ref$seen === void 0 ? [] : _ref$seen, _ref$truncate = _ref.truncate, truncate2 = _ref$truncate === void 0 ? Infinity : _ref$truncate, _ref$stylize = _ref.stylize, stylize = _ref$stylize === void 0 ? String : _ref$stylize; + var options = { + showHidden: Boolean(showHidden), + depth: Number(depth), + colors: Boolean(colors), + customInspect: Boolean(customInspect), + showProxy: Boolean(showProxy), + maxArrayLength: Number(maxArrayLength), + breakLength: Number(breakLength), + truncate: Number(truncate2), + seen, + stylize + }; + if (options.colors) { + options.stylize = colorise; + } + return options; + } + function truncate(string, length) { + var tail = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : truncator; + string = String(string); + var tailLength = tail.length; + var stringLength = string.length; + if (tailLength > length && stringLength > tailLength) { + return tail; + } + if (stringLength > length && stringLength > tailLength) { + return "".concat(string.slice(0, length - tailLength)).concat(tail); + } + return string; + } + function inspectList(list, options, inspectItem) { + var separator = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : ", "; + inspectItem = inspectItem || options.inspect; + var size = list.length; + if (size === 0) + return ""; + var originalLength = options.truncate; + var output = ""; + var peek = ""; + var truncated = ""; + for (var i = 0; i < size; i += 1) { + var last = i + 1 === list.length; + var secondToLast = i + 2 === list.length; + truncated = "".concat(truncator, "(").concat(list.length - i, ")"); + var value = list[i]; + options.truncate = originalLength - output.length - (last ? 0 : separator.length); + var string = peek || inspectItem(value, options) + (last ? "" : separator); + var nextLength = output.length + string.length; + var truncatedLength = nextLength + truncated.length; + if (last && nextLength > originalLength && output.length + truncated.length <= originalLength) { + break; + } + if (!last && !secondToLast && truncatedLength > originalLength) { + break; + } + peek = last ? "" : inspectItem(list[i + 1], options) + (secondToLast ? "" : separator); + if (!last && secondToLast && truncatedLength > originalLength && nextLength + peek.length > originalLength) { + break; + } + output += string; + if (!last && !secondToLast && nextLength + peek.length >= originalLength) { + truncated = "".concat(truncator, "(").concat(list.length - i - 1, ")"); + break; + } + truncated = ""; + } + return "".concat(output).concat(truncated); + } + function quoteComplexKey(key) { + if (key.match(/^[a-zA-Z_][a-zA-Z_0-9]*$/)) { + return key; + } + return JSON.stringify(key).replace(/'/g, "\\'").replace(/\\"/g, '"').replace(/(^"|"$)/g, "'"); + } + function inspectProperty(_ref2, options) { + var _ref3 = _slicedToArray(_ref2, 2), key = _ref3[0], value = _ref3[1]; + options.truncate -= 2; + if (typeof key === "string") { + key = quoteComplexKey(key); + } else if (typeof key !== "number") { + key = "[".concat(options.inspect(key, options), "]"); + } + options.truncate -= key.length; + value = options.inspect(value, options); + return "".concat(key, ": ").concat(value); + } + function inspectArray(array, options) { + var nonIndexProperties = Object.keys(array).slice(array.length); + if (!array.length && !nonIndexProperties.length) + return "[]"; + options.truncate -= 4; + var listContents = inspectList(array, options); + options.truncate -= listContents.length; + var propertyContents = ""; + if (nonIndexProperties.length) { + propertyContents = inspectList(nonIndexProperties.map(function(key) { + return [key, array[key]]; + }), options, inspectProperty); + } + return "[ ".concat(listContents).concat(propertyContents ? ", ".concat(propertyContents) : "", " ]"); + } + var toString = Function.prototype.toString; + var functionNameMatch = /\s*function(?:\s|\s*\/\*[^(?:*\/)]+\*\/\s*)*([^\s\(\/]+)/; + var maxFunctionSourceLength = 512; + function getFuncName(aFunc) { + if (typeof aFunc !== "function") { + return null; + } + var name = ""; + if (typeof Function.prototype.name === "undefined" && typeof aFunc.name === "undefined") { + var functionSource = toString.call(aFunc); + if (functionSource.indexOf("(") > maxFunctionSourceLength) { + return name; + } + var match = functionSource.match(functionNameMatch); + if (match) { + name = match[1]; + } + } else { + name = aFunc.name; + } + return name; + } + var getFuncName_1 = getFuncName; + var getArrayName = function getArrayName2(array) { + if (typeof Buffer === "function" && array instanceof Buffer) { + return "Buffer"; + } + if (array[Symbol.toStringTag]) { + return array[Symbol.toStringTag]; + } + return getFuncName_1(array.constructor); + }; + function inspectTypedArray(array, options) { + var name = getArrayName(array); + options.truncate -= name.length + 4; + var nonIndexProperties = Object.keys(array).slice(array.length); + if (!array.length && !nonIndexProperties.length) + return "".concat(name, "[]"); + var output = ""; + for (var i = 0; i < array.length; i++) { + var string = "".concat(options.stylize(truncate(array[i], options.truncate), "number")).concat(i === array.length - 1 ? "" : ", "); + options.truncate -= string.length; + if (array[i] !== array.length && options.truncate <= 3) { + output += "".concat(truncator, "(").concat(array.length - array[i] + 1, ")"); + break; + } + output += string; + } + var propertyContents = ""; + if (nonIndexProperties.length) { + propertyContents = inspectList(nonIndexProperties.map(function(key) { + return [key, array[key]]; + }), options, inspectProperty); + } + return "".concat(name, "[ ").concat(output).concat(propertyContents ? ", ".concat(propertyContents) : "", " ]"); + } + function inspectDate(dateObject, options) { + var stringRepresentation = dateObject.toJSON(); + if (stringRepresentation === null) { + return "Invalid Date"; + } + var split = stringRepresentation.split("T"); + var date = split[0]; + return options.stylize("".concat(date, "T").concat(truncate(split[1], options.truncate - date.length - 1)), "date"); + } + function inspectFunction(func, options) { + var name = getFuncName_1(func); + if (!name) { + return options.stylize("[Function]", "special"); + } + return options.stylize("[Function ".concat(truncate(name, options.truncate - 11), "]"), "special"); + } + function inspectMapEntry(_ref, options) { + var _ref2 = _slicedToArray(_ref, 2), key = _ref2[0], value = _ref2[1]; + options.truncate -= 4; + key = options.inspect(key, options); + options.truncate -= key.length; + value = options.inspect(value, options); + return "".concat(key, " => ").concat(value); + } + function mapToEntries(map) { + var entries = []; + map.forEach(function(value, key) { + entries.push([key, value]); + }); + return entries; + } + function inspectMap(map, options) { + var size = map.size - 1; + if (size <= 0) { + return "Map{}"; + } + options.truncate -= 7; + return "Map{ ".concat(inspectList(mapToEntries(map), options, inspectMapEntry), " }"); + } + var isNaN2 = Number.isNaN || function(i) { + return i !== i; + }; + function inspectNumber(number, options) { + if (isNaN2(number)) { + return options.stylize("NaN", "number"); + } + if (number === Infinity) { + return options.stylize("Infinity", "number"); + } + if (number === -Infinity) { + return options.stylize("-Infinity", "number"); + } + if (number === 0) { + return options.stylize(1 / number === Infinity ? "+0" : "-0", "number"); + } + return options.stylize(truncate(number, options.truncate), "number"); + } + function inspectBigInt(number, options) { + var nums = truncate(number.toString(), options.truncate - 1); + if (nums !== truncator) + nums += "n"; + return options.stylize(nums, "bigint"); + } + function inspectRegExp(value, options) { + var flags = value.toString().split("/")[2]; + var sourceLength = options.truncate - (2 + flags.length); + var source = value.source; + return options.stylize("/".concat(truncate(source, sourceLength), "/").concat(flags), "regexp"); + } + function arrayFromSet(set) { + var values = []; + set.forEach(function(value) { + values.push(value); + }); + return values; + } + function inspectSet(set, options) { + if (set.size === 0) + return "Set{}"; + options.truncate -= 7; + return "Set{ ".concat(inspectList(arrayFromSet(set), options), " }"); + } + var stringEscapeChars = new RegExp("['\\u0000-\\u001f\\u007f-\\u009f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]", "g"); + var escapeCharacters = { + "\b": "\\b", + " ": "\\t", + "\n": "\\n", + "\f": "\\f", + "\r": "\\r", + "'": "\\'", + "\\": "\\\\" + }; + var hex = 16; + var unicodeLength = 4; + function escape2(char) { + return escapeCharacters[char] || "\\u".concat("0000".concat(char.charCodeAt(0).toString(hex)).slice(-unicodeLength)); + } + function inspectString(string, options) { + if (stringEscapeChars.test(string)) { + string = string.replace(stringEscapeChars, escape2); + } + return options.stylize("'".concat(truncate(string, options.truncate - 2), "'"), "string"); + } + function inspectSymbol(value) { + if ("description" in Symbol.prototype) { + return value.description ? "Symbol(".concat(value.description, ")") : "Symbol()"; + } + return value.toString(); + } + var getPromiseValue = function getPromiseValue2() { + return "Promise{\u2026}"; + }; + try { + var _process$binding = process.binding("util"), getPromiseDetails = _process$binding.getPromiseDetails, kPending = _process$binding.kPending, kRejected = _process$binding.kRejected; + if (Array.isArray(getPromiseDetails(Promise.resolve()))) { + getPromiseValue = function getPromiseValue2(value, options) { + var _getPromiseDetails = getPromiseDetails(value), _getPromiseDetails2 = _slicedToArray(_getPromiseDetails, 2), state = _getPromiseDetails2[0], innerValue = _getPromiseDetails2[1]; + if (state === kPending) { + return "Promise{<pending>}"; + } + return "Promise".concat(state === kRejected ? "!" : "", "{").concat(options.inspect(innerValue, options), "}"); + }; + } + } catch (notNode) { + } + var inspectPromise = getPromiseValue; + function inspectObject(object, options) { + var properties = Object.getOwnPropertyNames(object); + var symbols = Object.getOwnPropertySymbols ? Object.getOwnPropertySymbols(object) : []; + if (properties.length === 0 && symbols.length === 0) { + return "{}"; + } + options.truncate -= 4; + options.seen = options.seen || []; + if (options.seen.indexOf(object) >= 0) { + return "[Circular]"; + } + options.seen.push(object); + var propertyContents = inspectList(properties.map(function(key) { + return [key, object[key]]; + }), options, inspectProperty); + var symbolContents = inspectList(symbols.map(function(key) { + return [key, object[key]]; + }), options, inspectProperty); + options.seen.pop(); + var sep = ""; + if (propertyContents && symbolContents) { + sep = ", "; + } + return "{ ".concat(propertyContents).concat(sep).concat(symbolContents, " }"); + } + var toStringTag = typeof Symbol !== "undefined" && Symbol.toStringTag ? Symbol.toStringTag : false; + function inspectClass(value, options) { + var name = ""; + if (toStringTag && toStringTag in value) { + name = value[toStringTag]; + } + name = name || getFuncName_1(value.constructor); + if (!name || name === "_class") { + name = "<Anonymous Class>"; + } + options.truncate -= name.length; + return "".concat(name).concat(inspectObject(value, options)); + } + function inspectArguments(args, options) { + if (args.length === 0) + return "Arguments[]"; + options.truncate -= 13; + return "Arguments[ ".concat(inspectList(args, options), " ]"); + } + var errorKeys = ["stack", "line", "column", "name", "message", "fileName", "lineNumber", "columnNumber", "number", "description"]; + function inspectObject$1(error, options) { + var properties = Object.getOwnPropertyNames(error).filter(function(key) { + return errorKeys.indexOf(key) === -1; + }); + var name = error.name; + options.truncate -= name.length; + var message = ""; + if (typeof error.message === "string") { + message = truncate(error.message, options.truncate); + } else { + properties.unshift("message"); + } + message = message ? ": ".concat(message) : ""; + options.truncate -= message.length + 5; + var propertyContents = inspectList(properties.map(function(key) { + return [key, error[key]]; + }), options, inspectProperty); + return "".concat(name).concat(message).concat(propertyContents ? " { ".concat(propertyContents, " }") : ""); + } + function inspectAttribute(_ref, options) { + var _ref2 = _slicedToArray(_ref, 2), key = _ref2[0], value = _ref2[1]; + options.truncate -= 3; + if (!value) { + return "".concat(options.stylize(key, "yellow")); + } + return "".concat(options.stylize(key, "yellow"), "=").concat(options.stylize('"'.concat(value, '"'), "string")); + } + function inspectHTMLCollection(collection, options) { + return inspectList(collection, options, inspectHTML, "\n"); + } + function inspectHTML(element, options) { + var properties = element.getAttributeNames(); + var name = element.tagName.toLowerCase(); + var head = options.stylize("<".concat(name), "special"); + var headClose = options.stylize(">", "special"); + var tail = options.stylize("</".concat(name, ">"), "special"); + options.truncate -= name.length * 2 + 5; + var propertyContents = ""; + if (properties.length > 0) { + propertyContents += " "; + propertyContents += inspectList(properties.map(function(key) { + return [key, element.getAttribute(key)]; + }), options, inspectAttribute, " "); + } + options.truncate -= propertyContents.length; + var truncate2 = options.truncate; + var children = inspectHTMLCollection(element.children, options); + if (children && children.length > truncate2) { + children = "".concat(truncator, "(").concat(element.children.length, ")"); + } + return "".concat(head).concat(propertyContents).concat(headClose).concat(children).concat(tail); + } + var symbolsSupported = typeof Symbol === "function" && typeof Symbol.for === "function"; + var chaiInspect = symbolsSupported ? Symbol.for("chai/inspect") : "@@chai/inspect"; + var nodeInspect = false; + try { + var nodeUtil = require_util(); + nodeInspect = nodeUtil.inspect ? nodeUtil.inspect.custom : false; + } catch (noNodeInspect) { + nodeInspect = false; + } + function FakeMap() { + this.key = "chai/loupe__" + Math.random() + Date.now(); + } + FakeMap.prototype = { + // eslint-disable-next-line object-shorthand + get: function get(key) { + return key[this.key]; + }, + // eslint-disable-next-line object-shorthand + has: function has(key) { + return this.key in key; + }, + // eslint-disable-next-line object-shorthand + set: function set(key, value) { + if (Object.isExtensible(key)) { + Object.defineProperty(key, this.key, { + // eslint-disable-next-line object-shorthand + value, + configurable: true + }); + } + } + }; + var constructorMap = new (typeof WeakMap === "function" ? WeakMap : FakeMap)(); + var stringTagMap = {}; + var baseTypesMap = { + undefined: function undefined$1(value, options) { + return options.stylize("undefined", "undefined"); + }, + null: function _null(value, options) { + return options.stylize(null, "null"); + }, + boolean: function boolean(value, options) { + return options.stylize(value, "boolean"); + }, + Boolean: function Boolean3(value, options) { + return options.stylize(value, "boolean"); + }, + number: inspectNumber, + Number: inspectNumber, + bigint: inspectBigInt, + BigInt: inspectBigInt, + string: inspectString, + String: inspectString, + function: inspectFunction, + Function: inspectFunction, + symbol: inspectSymbol, + // A Symbol polyfill will return `Symbol` not `symbol` from typedetect + Symbol: inspectSymbol, + Array: inspectArray, + Date: inspectDate, + Map: inspectMap, + Set: inspectSet, + RegExp: inspectRegExp, + Promise: inspectPromise, + // WeakSet, WeakMap are totally opaque to us + WeakSet: function WeakSet2(value, options) { + return options.stylize("WeakSet{\u2026}", "special"); + }, + WeakMap: function WeakMap2(value, options) { + return options.stylize("WeakMap{\u2026}", "special"); + }, + Arguments: inspectArguments, + Int8Array: inspectTypedArray, + Uint8Array: inspectTypedArray, + Uint8ClampedArray: inspectTypedArray, + Int16Array: inspectTypedArray, + Uint16Array: inspectTypedArray, + Int32Array: inspectTypedArray, + Uint32Array: inspectTypedArray, + Float32Array: inspectTypedArray, + Float64Array: inspectTypedArray, + Generator: function Generator() { + return ""; + }, + DataView: function DataView2() { + return ""; + }, + ArrayBuffer: function ArrayBuffer2() { + return ""; + }, + Error: inspectObject$1, + HTMLCollection: inspectHTMLCollection, + NodeList: inspectHTMLCollection + }; + var inspectCustom = function inspectCustom2(value, options, type) { + if (chaiInspect in value && typeof value[chaiInspect] === "function") { + return value[chaiInspect](options); + } + if (nodeInspect && nodeInspect in value && typeof value[nodeInspect] === "function") { + return value[nodeInspect](options.depth, options); + } + if ("inspect" in value && typeof value.inspect === "function") { + return value.inspect(options.depth, options); + } + if ("constructor" in value && constructorMap.has(value.constructor)) { + return constructorMap.get(value.constructor)(value, options); + } + if (stringTagMap[type]) { + return stringTagMap[type](value, options); + } + return ""; + }; + var toString$1 = Object.prototype.toString; + function inspect(value, options) { + options = normaliseOptions(options); + options.inspect = inspect; + var _options = options, customInspect = _options.customInspect; + var type = value === null ? "null" : _typeof(value); + if (type === "object") { + type = toString$1.call(value).slice(8, -1); + } + if (baseTypesMap[type]) { + return baseTypesMap[type](value, options); + } + if (customInspect && value) { + var output = inspectCustom(value, options, type); + if (output) { + if (typeof output === "string") + return output; + return inspect(output, options); + } + } + var proto = value ? Object.getPrototypeOf(value) : false; + if (proto === Object.prototype || proto === null) { + return inspectObject(value, options); + } + if (value && typeof HTMLElement === "function" && value instanceof HTMLElement) { + return inspectHTML(value, options); + } + if ("constructor" in value) { + if (value.constructor !== Object) { + return inspectClass(value, options); + } + return inspectObject(value, options); + } + if (value === Object(value)) { + return inspectObject(value, options); + } + return options.stylize(String(value), type); + } + function registerConstructor(constructor, inspector) { + if (constructorMap.has(constructor)) { + return false; + } + constructorMap.set(constructor, inspector); + return true; + } + function registerStringTag(stringTag, inspector) { + if (stringTag in stringTagMap) { + return false; + } + stringTagMap[stringTag] = inspector; + return true; + } + var custom = chaiInspect; + exports2.custom = custom; + exports2.default = inspect; + exports2.inspect = inspect; + exports2.registerConstructor = registerConstructor; + exports2.registerStringTag = registerStringTag; + Object.defineProperty(exports2, "__esModule", { value: true }); + }); + } + }); + + // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/config.js + var require_config = __commonJS({ + "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/config.js"(exports, module) { + module.exports = { + /** + * ### config.includeStack + * + * User configurable property, influences whether stack trace + * is included in Assertion error message. Default of false + * suppresses stack trace in the error message. + * + * chai.config.includeStack = true; // enable stack on error + * + * @param {Boolean} + * @api public + */ + includeStack: false, + /** + * ### config.showDiff + * + * User configurable property, influences whether or not + * the `showDiff` flag should be included in the thrown + * AssertionErrors. `false` will always be `false`; `true` + * will be true when the assertion has requested a diff + * be shown. + * + * @param {Boolean} + * @api public + */ + showDiff: true, + /** + * ### config.truncateThreshold + * + * User configurable property, sets length threshold for actual and + * expected values in assertion errors. If this threshold is exceeded, for + * example for large data structures, the value is replaced with something + * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`. + * + * Set it to zero if you want to disable truncating altogether. + * + * This is especially userful when doing assertions on arrays: having this + * set to a reasonable large value makes the failure messages readily + * inspectable. + * + * chai.config.truncateThreshold = 0; // disable truncating + * + * @param {Number} + * @api public + */ + truncateThreshold: 40, + /** + * ### config.useProxy + * + * User configurable property, defines if chai will use a Proxy to throw + * an error when a non-existent property is read, which protects users + * from typos when using property-based assertions. + * + * Set it to false if you want to disable this feature. + * + * chai.config.useProxy = false; // disable use of Proxy + * + * This feature is automatically disabled regardless of this config value + * in environments that don't support proxies. + * + * @param {Boolean} + * @api public + */ + useProxy: true, + /** + * ### config.proxyExcludedKeys + * + * User configurable property, defines which properties should be ignored + * instead of throwing an error if they do not exist on the assertion. + * This is only applied if the environment Chai is running in supports proxies and + * if the `useProxy` configuration setting is enabled. + * By default, `then` and `inspect` will not throw an error if they do not exist on the + * assertion object because the `.inspect` property is read by `util.inspect` (for example, when + * using `console.log` on the assertion object) and `.then` is necessary for promise type-checking. + * + * // By default these keys will not throw an error if they do not exist on the assertion object + * chai.config.proxyExcludedKeys = ['then', 'inspect']; + * + * @param {Array} + * @api public + */ + proxyExcludedKeys: ["then", "catch", "inspect", "toJSON"] + }; + } + }); + + // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/inspect.js + var require_inspect = __commonJS({ + "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/inspect.js"(exports, module) { + var getName = require_get_func_name(); + var loupe = require_loupe(); + var config2 = require_config(); + module.exports = inspect; + function inspect(obj, showHidden, depth, colors) { + var options = { + colors, + depth: typeof depth === "undefined" ? 2 : depth, + showHidden, + truncate: config2.truncateThreshold ? config2.truncateThreshold : Infinity + }; + return loupe.inspect(obj, options); + } + } + }); + + // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/objDisplay.js + var require_objDisplay = __commonJS({ + "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/objDisplay.js"(exports, module) { + var inspect = require_inspect(); + var config2 = require_config(); + module.exports = function objDisplay(obj) { + var str = inspect(obj), type = Object.prototype.toString.call(obj); + if (config2.truncateThreshold && str.length >= config2.truncateThreshold) { + if (type === "[object Function]") { + return !obj.name || obj.name === "" ? "[Function]" : "[Function: " + obj.name + "]"; + } else if (type === "[object Array]") { + return "[ Array(" + obj.length + ") ]"; + } else if (type === "[object Object]") { + var keys = Object.keys(obj), kstr = keys.length > 2 ? keys.splice(0, 2).join(", ") + ", ..." : keys.join(", "); + return "{ Object (" + kstr + ") }"; + } else { + return str; + } + } else { + return str; + } + }; + } + }); + + // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/getMessage.js + var require_getMessage = __commonJS({ + "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/getMessage.js"(exports, module) { + var flag = require_flag(); + var getActual = require_getActual(); + var objDisplay = require_objDisplay(); + module.exports = function getMessage(obj, args) { + var negate = flag(obj, "negate"), val = flag(obj, "object"), expected = args[3], actual = getActual(obj, args), msg = negate ? args[2] : args[1], flagMsg = flag(obj, "message"); + if (typeof msg === "function") + msg = msg(); + msg = msg || ""; + msg = msg.replace(/#\{this\}/g, function() { + return objDisplay(val); + }).replace(/#\{act\}/g, function() { + return objDisplay(actual); + }).replace(/#\{exp\}/g, function() { + return objDisplay(expected); + }); + return flagMsg ? flagMsg + ": " + msg : msg; + }; + } + }); + + // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/transferFlags.js + var require_transferFlags = __commonJS({ + "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/transferFlags.js"(exports, module) { + module.exports = function transferFlags(assertion, object, includeAll) { + var flags = assertion.__flags || (assertion.__flags = /* @__PURE__ */ Object.create(null)); + if (!object.__flags) { + object.__flags = /* @__PURE__ */ Object.create(null); + } + includeAll = arguments.length === 3 ? includeAll : true; + for (var flag in flags) { + if (includeAll || flag !== "object" && flag !== "ssfi" && flag !== "lockSsfi" && flag != "message") { + object.__flags[flag] = flags[flag]; + } + } + }; + } + }); + + // node_modules/.pnpm/deep-eql@4.1.3/node_modules/deep-eql/index.js + var require_deep_eql = __commonJS({ + "node_modules/.pnpm/deep-eql@4.1.3/node_modules/deep-eql/index.js"(exports, module) { + "use strict"; + var type = require_type_detect(); + function FakeMap() { + this._key = "chai/deep-eql__" + Math.random() + Date.now(); + } + FakeMap.prototype = { + get: function get(key) { + return key[this._key]; + }, + set: function set(key, value) { + if (Object.isExtensible(key)) { + Object.defineProperty(key, this._key, { + value, + configurable: true + }); + } + } + }; + var MemoizeMap = typeof WeakMap === "function" ? WeakMap : FakeMap; + function memoizeCompare(leftHandOperand, rightHandOperand, memoizeMap) { + if (!memoizeMap || isPrimitive2(leftHandOperand) || isPrimitive2(rightHandOperand)) { + return null; + } + var leftHandMap = memoizeMap.get(leftHandOperand); + if (leftHandMap) { + var result = leftHandMap.get(rightHandOperand); + if (typeof result === "boolean") { + return result; + } + } + return null; + } + function memoizeSet(leftHandOperand, rightHandOperand, memoizeMap, result) { + if (!memoizeMap || isPrimitive2(leftHandOperand) || isPrimitive2(rightHandOperand)) { + return; + } + var leftHandMap = memoizeMap.get(leftHandOperand); + if (leftHandMap) { + leftHandMap.set(rightHandOperand, result); + } else { + leftHandMap = new MemoizeMap(); + leftHandMap.set(rightHandOperand, result); + memoizeMap.set(leftHandOperand, leftHandMap); + } + } + module.exports = deepEqual; + module.exports.MemoizeMap = MemoizeMap; + function deepEqual(leftHandOperand, rightHandOperand, options) { + if (options && options.comparator) { + return extensiveDeepEqual(leftHandOperand, rightHandOperand, options); + } + var simpleResult = simpleEqual(leftHandOperand, rightHandOperand); + if (simpleResult !== null) { + return simpleResult; + } + return extensiveDeepEqual(leftHandOperand, rightHandOperand, options); + } + function simpleEqual(leftHandOperand, rightHandOperand) { + if (leftHandOperand === rightHandOperand) { + return leftHandOperand !== 0 || 1 / leftHandOperand === 1 / rightHandOperand; + } + if (leftHandOperand !== leftHandOperand && // eslint-disable-line no-self-compare + rightHandOperand !== rightHandOperand) { + return true; + } + if (isPrimitive2(leftHandOperand) || isPrimitive2(rightHandOperand)) { + return false; + } + return null; + } + function extensiveDeepEqual(leftHandOperand, rightHandOperand, options) { + options = options || {}; + options.memoize = options.memoize === false ? false : options.memoize || new MemoizeMap(); + var comparator = options && options.comparator; + var memoizeResultLeft = memoizeCompare(leftHandOperand, rightHandOperand, options.memoize); + if (memoizeResultLeft !== null) { + return memoizeResultLeft; + } + var memoizeResultRight = memoizeCompare(rightHandOperand, leftHandOperand, options.memoize); + if (memoizeResultRight !== null) { + return memoizeResultRight; + } + if (comparator) { + var comparatorResult = comparator(leftHandOperand, rightHandOperand); + if (comparatorResult === false || comparatorResult === true) { + memoizeSet(leftHandOperand, rightHandOperand, options.memoize, comparatorResult); + return comparatorResult; + } + var simpleResult = simpleEqual(leftHandOperand, rightHandOperand); + if (simpleResult !== null) { + return simpleResult; + } + } + var leftHandType = type(leftHandOperand); + if (leftHandType !== type(rightHandOperand)) { + memoizeSet(leftHandOperand, rightHandOperand, options.memoize, false); + return false; + } + memoizeSet(leftHandOperand, rightHandOperand, options.memoize, true); + var result = extensiveDeepEqualByType(leftHandOperand, rightHandOperand, leftHandType, options); + memoizeSet(leftHandOperand, rightHandOperand, options.memoize, result); + return result; + } + function extensiveDeepEqualByType(leftHandOperand, rightHandOperand, leftHandType, options) { + switch (leftHandType) { + case "String": + case "Number": + case "Boolean": + case "Date": + return deepEqual(leftHandOperand.valueOf(), rightHandOperand.valueOf()); + case "Promise": + case "Symbol": + case "function": + case "WeakMap": + case "WeakSet": + return leftHandOperand === rightHandOperand; + case "Error": + return keysEqual(leftHandOperand, rightHandOperand, ["name", "message", "code"], options); + case "Arguments": + case "Int8Array": + case "Uint8Array": + case "Uint8ClampedArray": + case "Int16Array": + case "Uint16Array": + case "Int32Array": + case "Uint32Array": + case "Float32Array": + case "Float64Array": + case "Array": + return iterableEqual(leftHandOperand, rightHandOperand, options); + case "RegExp": + return regexpEqual(leftHandOperand, rightHandOperand); + case "Generator": + return generatorEqual(leftHandOperand, rightHandOperand, options); + case "DataView": + return iterableEqual(new Uint8Array(leftHandOperand.buffer), new Uint8Array(rightHandOperand.buffer), options); + case "ArrayBuffer": + return iterableEqual(new Uint8Array(leftHandOperand), new Uint8Array(rightHandOperand), options); + case "Set": + return entriesEqual(leftHandOperand, rightHandOperand, options); + case "Map": + return entriesEqual(leftHandOperand, rightHandOperand, options); + case "Temporal.PlainDate": + case "Temporal.PlainTime": + case "Temporal.PlainDateTime": + case "Temporal.Instant": + case "Temporal.ZonedDateTime": + case "Temporal.PlainYearMonth": + case "Temporal.PlainMonthDay": + return leftHandOperand.equals(rightHandOperand); + case "Temporal.Duration": + return leftHandOperand.total("nanoseconds") === rightHandOperand.total("nanoseconds"); + case "Temporal.TimeZone": + case "Temporal.Calendar": + return leftHandOperand.toString() === rightHandOperand.toString(); + default: + return objectEqual(leftHandOperand, rightHandOperand, options); + } + } + function regexpEqual(leftHandOperand, rightHandOperand) { + return leftHandOperand.toString() === rightHandOperand.toString(); + } + function entriesEqual(leftHandOperand, rightHandOperand, options) { + if (leftHandOperand.size !== rightHandOperand.size) { + return false; + } + if (leftHandOperand.size === 0) { + return true; + } + var leftHandItems = []; + var rightHandItems = []; + leftHandOperand.forEach(function gatherEntries(key, value) { + leftHandItems.push([key, value]); + }); + rightHandOperand.forEach(function gatherEntries(key, value) { + rightHandItems.push([key, value]); + }); + return iterableEqual(leftHandItems.sort(), rightHandItems.sort(), options); + } + function iterableEqual(leftHandOperand, rightHandOperand, options) { + var length = leftHandOperand.length; + if (length !== rightHandOperand.length) { + return false; + } + if (length === 0) { + return true; + } + var index = -1; + while (++index < length) { + if (deepEqual(leftHandOperand[index], rightHandOperand[index], options) === false) { + return false; + } + } + return true; + } + function generatorEqual(leftHandOperand, rightHandOperand, options) { + return iterableEqual(getGeneratorEntries(leftHandOperand), getGeneratorEntries(rightHandOperand), options); + } + function hasIteratorFunction(target) { + return typeof Symbol !== "undefined" && typeof target === "object" && typeof Symbol.iterator !== "undefined" && typeof target[Symbol.iterator] === "function"; + } + function getIteratorEntries(target) { + if (hasIteratorFunction(target)) { + try { + return getGeneratorEntries(target[Symbol.iterator]()); + } catch (iteratorError) { + return []; + } + } + return []; + } + function getGeneratorEntries(generator) { + var generatorResult = generator.next(); + var accumulator = [generatorResult.value]; + while (generatorResult.done === false) { + generatorResult = generator.next(); + accumulator.push(generatorResult.value); + } + return accumulator; + } + function getEnumerableKeys(target) { + var keys = []; + for (var key in target) { + keys.push(key); + } + return keys; + } + function getEnumerableSymbols(target) { + var keys = []; + var allKeys = Object.getOwnPropertySymbols(target); + for (var i = 0; i < allKeys.length; i += 1) { + var key = allKeys[i]; + if (Object.getOwnPropertyDescriptor(target, key).enumerable) { + keys.push(key); + } + } + return keys; + } + function keysEqual(leftHandOperand, rightHandOperand, keys, options) { + var length = keys.length; + if (length === 0) { + return true; + } + for (var i = 0; i < length; i += 1) { + if (deepEqual(leftHandOperand[keys[i]], rightHandOperand[keys[i]], options) === false) { + return false; + } + } + return true; + } + function objectEqual(leftHandOperand, rightHandOperand, options) { + var leftHandKeys = getEnumerableKeys(leftHandOperand); + var rightHandKeys = getEnumerableKeys(rightHandOperand); + var leftHandSymbols = getEnumerableSymbols(leftHandOperand); + var rightHandSymbols = getEnumerableSymbols(rightHandOperand); + leftHandKeys = leftHandKeys.concat(leftHandSymbols); + rightHandKeys = rightHandKeys.concat(rightHandSymbols); + if (leftHandKeys.length && leftHandKeys.length === rightHandKeys.length) { + if (iterableEqual(mapSymbols(leftHandKeys).sort(), mapSymbols(rightHandKeys).sort()) === false) { + return false; + } + return keysEqual(leftHandOperand, rightHandOperand, leftHandKeys, options); + } + var leftHandEntries = getIteratorEntries(leftHandOperand); + var rightHandEntries = getIteratorEntries(rightHandOperand); + if (leftHandEntries.length && leftHandEntries.length === rightHandEntries.length) { + leftHandEntries.sort(); + rightHandEntries.sort(); + return iterableEqual(leftHandEntries, rightHandEntries, options); + } + if (leftHandKeys.length === 0 && leftHandEntries.length === 0 && rightHandKeys.length === 0 && rightHandEntries.length === 0) { + return true; + } + return false; + } + function isPrimitive2(value) { + return value === null || typeof value !== "object"; + } + function mapSymbols(arr) { + return arr.map(function mapSymbol(entry) { + if (typeof entry === "symbol") { + return entry.toString(); + } + return entry; + }); + } + } + }); + + // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/isProxyEnabled.js + var require_isProxyEnabled = __commonJS({ + "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/isProxyEnabled.js"(exports, module) { + var config2 = require_config(); + module.exports = function isProxyEnabled() { + return config2.useProxy && typeof Proxy !== "undefined" && typeof Reflect !== "undefined"; + }; + } + }); + + // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/addProperty.js + var require_addProperty = __commonJS({ + "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/addProperty.js"(exports, module) { + var chai2 = require_chai(); + var flag = require_flag(); + var isProxyEnabled = require_isProxyEnabled(); + var transferFlags = require_transferFlags(); + module.exports = function addProperty(ctx, name, getter) { + getter = getter === void 0 ? function() { + } : getter; + Object.defineProperty( + ctx, + name, + { + get: function propertyGetter() { + if (!isProxyEnabled() && !flag(this, "lockSsfi")) { + flag(this, "ssfi", propertyGetter); + } + var result = getter.call(this); + if (result !== void 0) + return result; + var newAssertion = new chai2.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }, + configurable: true + } + ); + }; + } + }); + + // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/addLengthGuard.js + var require_addLengthGuard = __commonJS({ + "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/addLengthGuard.js"(exports, module) { + var fnLengthDesc = Object.getOwnPropertyDescriptor(function() { + }, "length"); + module.exports = function addLengthGuard(fn, assertionName, isChainable) { + if (!fnLengthDesc.configurable) + return fn; + Object.defineProperty(fn, "length", { + get: function() { + if (isChainable) { + throw Error("Invalid Chai property: " + assertionName + '.length. Due to a compatibility issue, "length" cannot directly follow "' + assertionName + '". Use "' + assertionName + '.lengthOf" instead.'); + } + throw Error("Invalid Chai property: " + assertionName + '.length. See docs for proper usage of "' + assertionName + '".'); + } + }); + return fn; + }; + } + }); + + // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/getProperties.js + var require_getProperties = __commonJS({ + "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/getProperties.js"(exports, module) { + module.exports = function getProperties(object) { + var result = Object.getOwnPropertyNames(object); + function addProperty(property) { + if (result.indexOf(property) === -1) { + result.push(property); + } + } + var proto = Object.getPrototypeOf(object); + while (proto !== null) { + Object.getOwnPropertyNames(proto).forEach(addProperty); + proto = Object.getPrototypeOf(proto); + } + return result; + }; + } + }); + + // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/proxify.js + var require_proxify = __commonJS({ + "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/proxify.js"(exports, module) { + var config2 = require_config(); + var flag = require_flag(); + var getProperties = require_getProperties(); + var isProxyEnabled = require_isProxyEnabled(); + var builtins = ["__flags", "__methods", "_obj", "assert"]; + module.exports = function proxify(obj, nonChainableMethodName) { + if (!isProxyEnabled()) + return obj; + return new Proxy(obj, { + get: function proxyGetter(target, property) { + if (typeof property === "string" && config2.proxyExcludedKeys.indexOf(property) === -1 && !Reflect.has(target, property)) { + if (nonChainableMethodName) { + throw Error("Invalid Chai property: " + nonChainableMethodName + "." + property + '. See docs for proper usage of "' + nonChainableMethodName + '".'); + } + var suggestion = null; + var suggestionDistance = 4; + getProperties(target).forEach(function(prop) { + if (!Object.prototype.hasOwnProperty(prop) && builtins.indexOf(prop) === -1) { + var dist = stringDistanceCapped( + property, + prop, + suggestionDistance + ); + if (dist < suggestionDistance) { + suggestion = prop; + suggestionDistance = dist; + } + } + }); + if (suggestion !== null) { + throw Error("Invalid Chai property: " + property + '. Did you mean "' + suggestion + '"?'); + } else { + throw Error("Invalid Chai property: " + property); + } + } + if (builtins.indexOf(property) === -1 && !flag(target, "lockSsfi")) { + flag(target, "ssfi", proxyGetter); + } + return Reflect.get(target, property); + } + }); + }; + function stringDistanceCapped(strA, strB, cap) { + if (Math.abs(strA.length - strB.length) >= cap) { + return cap; + } + var memo = []; + for (var i = 0; i <= strA.length; i++) { + memo[i] = Array(strB.length + 1).fill(0); + memo[i][0] = i; + } + for (var j = 0; j < strB.length; j++) { + memo[0][j] = j; + } + for (var i = 1; i <= strA.length; i++) { + var ch = strA.charCodeAt(i - 1); + for (var j = 1; j <= strB.length; j++) { + if (Math.abs(i - j) >= cap) { + memo[i][j] = cap; + continue; + } + memo[i][j] = Math.min( + memo[i - 1][j] + 1, + memo[i][j - 1] + 1, + memo[i - 1][j - 1] + (ch === strB.charCodeAt(j - 1) ? 0 : 1) + ); + } + } + return memo[strA.length][strB.length]; + } + } + }); + + // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/addMethod.js + var require_addMethod = __commonJS({ + "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/addMethod.js"(exports, module) { + var addLengthGuard = require_addLengthGuard(); + var chai2 = require_chai(); + var flag = require_flag(); + var proxify = require_proxify(); + var transferFlags = require_transferFlags(); + module.exports = function addMethod(ctx, name, method) { + var methodWrapper = function() { + if (!flag(this, "lockSsfi")) { + flag(this, "ssfi", methodWrapper); + } + var result = method.apply(this, arguments); + if (result !== void 0) + return result; + var newAssertion = new chai2.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }; + addLengthGuard(methodWrapper, name, false); + ctx[name] = proxify(methodWrapper, name); + }; + } + }); + + // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/overwriteProperty.js + var require_overwriteProperty = __commonJS({ + "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/overwriteProperty.js"(exports, module) { + var chai2 = require_chai(); + var flag = require_flag(); + var isProxyEnabled = require_isProxyEnabled(); + var transferFlags = require_transferFlags(); + module.exports = function overwriteProperty(ctx, name, getter) { + var _get = Object.getOwnPropertyDescriptor(ctx, name), _super = function() { + }; + if (_get && "function" === typeof _get.get) + _super = _get.get; + Object.defineProperty( + ctx, + name, + { + get: function overwritingPropertyGetter() { + if (!isProxyEnabled() && !flag(this, "lockSsfi")) { + flag(this, "ssfi", overwritingPropertyGetter); + } + var origLockSsfi = flag(this, "lockSsfi"); + flag(this, "lockSsfi", true); + var result = getter(_super).call(this); + flag(this, "lockSsfi", origLockSsfi); + if (result !== void 0) { + return result; + } + var newAssertion = new chai2.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }, + configurable: true + } + ); + }; + } + }); + + // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/overwriteMethod.js + var require_overwriteMethod = __commonJS({ + "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/overwriteMethod.js"(exports, module) { + var addLengthGuard = require_addLengthGuard(); + var chai2 = require_chai(); + var flag = require_flag(); + var proxify = require_proxify(); + var transferFlags = require_transferFlags(); + module.exports = function overwriteMethod(ctx, name, method) { + var _method = ctx[name], _super = function() { + throw new Error(name + " is not a function"); + }; + if (_method && "function" === typeof _method) + _super = _method; + var overwritingMethodWrapper = function() { + if (!flag(this, "lockSsfi")) { + flag(this, "ssfi", overwritingMethodWrapper); + } + var origLockSsfi = flag(this, "lockSsfi"); + flag(this, "lockSsfi", true); + var result = method(_super).apply(this, arguments); + flag(this, "lockSsfi", origLockSsfi); + if (result !== void 0) { + return result; + } + var newAssertion = new chai2.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }; + addLengthGuard(overwritingMethodWrapper, name, false); + ctx[name] = proxify(overwritingMethodWrapper, name); + }; + } + }); + + // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/addChainableMethod.js + var require_addChainableMethod = __commonJS({ + "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/addChainableMethod.js"(exports, module) { + var addLengthGuard = require_addLengthGuard(); + var chai2 = require_chai(); + var flag = require_flag(); + var proxify = require_proxify(); + var transferFlags = require_transferFlags(); + var canSetPrototype = typeof Object.setPrototypeOf === "function"; + var testFn = function() { + }; + var excludeNames = Object.getOwnPropertyNames(testFn).filter(function(name) { + var propDesc = Object.getOwnPropertyDescriptor(testFn, name); + if (typeof propDesc !== "object") + return true; + return !propDesc.configurable; + }); + var call = Function.prototype.call; + var apply = Function.prototype.apply; + module.exports = function addChainableMethod(ctx, name, method, chainingBehavior) { + if (typeof chainingBehavior !== "function") { + chainingBehavior = function() { + }; + } + var chainableBehavior = { + method, + chainingBehavior + }; + if (!ctx.__methods) { + ctx.__methods = {}; + } + ctx.__methods[name] = chainableBehavior; + Object.defineProperty( + ctx, + name, + { + get: function chainableMethodGetter() { + chainableBehavior.chainingBehavior.call(this); + var chainableMethodWrapper = function() { + if (!flag(this, "lockSsfi")) { + flag(this, "ssfi", chainableMethodWrapper); + } + var result = chainableBehavior.method.apply(this, arguments); + if (result !== void 0) { + return result; + } + var newAssertion = new chai2.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }; + addLengthGuard(chainableMethodWrapper, name, true); + if (canSetPrototype) { + var prototype = Object.create(this); + prototype.call = call; + prototype.apply = apply; + Object.setPrototypeOf(chainableMethodWrapper, prototype); + } else { + var asserterNames = Object.getOwnPropertyNames(ctx); + asserterNames.forEach(function(asserterName) { + if (excludeNames.indexOf(asserterName) !== -1) { + return; + } + var pd = Object.getOwnPropertyDescriptor(ctx, asserterName); + Object.defineProperty(chainableMethodWrapper, asserterName, pd); + }); + } + transferFlags(this, chainableMethodWrapper); + return proxify(chainableMethodWrapper); + }, + configurable: true + } + ); + }; + } + }); + + // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/overwriteChainableMethod.js + var require_overwriteChainableMethod = __commonJS({ + "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/overwriteChainableMethod.js"(exports, module) { + var chai2 = require_chai(); + var transferFlags = require_transferFlags(); + module.exports = function overwriteChainableMethod(ctx, name, method, chainingBehavior) { + var chainableBehavior = ctx.__methods[name]; + var _chainingBehavior = chainableBehavior.chainingBehavior; + chainableBehavior.chainingBehavior = function overwritingChainableMethodGetter() { + var result = chainingBehavior(_chainingBehavior).call(this); + if (result !== void 0) { + return result; + } + var newAssertion = new chai2.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }; + var _method = chainableBehavior.method; + chainableBehavior.method = function overwritingChainableMethodWrapper() { + var result = method(_method).apply(this, arguments); + if (result !== void 0) { + return result; + } + var newAssertion = new chai2.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }; + }; + } + }); + + // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/compareByInspect.js + var require_compareByInspect = __commonJS({ + "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/compareByInspect.js"(exports, module) { + var inspect = require_inspect(); + module.exports = function compareByInspect(a2, b) { + return inspect(a2) < inspect(b) ? -1 : 1; + }; + } + }); + + // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/getOwnEnumerablePropertySymbols.js + var require_getOwnEnumerablePropertySymbols = __commonJS({ + "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/getOwnEnumerablePropertySymbols.js"(exports, module) { + module.exports = function getOwnEnumerablePropertySymbols(obj) { + if (typeof Object.getOwnPropertySymbols !== "function") + return []; + return Object.getOwnPropertySymbols(obj).filter(function(sym) { + return Object.getOwnPropertyDescriptor(obj, sym).enumerable; + }); + }; + } + }); + + // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/getOwnEnumerableProperties.js + var require_getOwnEnumerableProperties = __commonJS({ + "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/getOwnEnumerableProperties.js"(exports, module) { + var getOwnEnumerablePropertySymbols = require_getOwnEnumerablePropertySymbols(); + module.exports = function getOwnEnumerableProperties(obj) { + return Object.keys(obj).concat(getOwnEnumerablePropertySymbols(obj)); + }; + } + }); + + // node_modules/.pnpm/check-error@1.0.3/node_modules/check-error/index.js + var require_check_error = __commonJS({ + "node_modules/.pnpm/check-error@1.0.3/node_modules/check-error/index.js"(exports, module) { + "use strict"; + var getFunctionName = require_get_func_name(); + function compatibleInstance(thrown, errorLike) { + return errorLike instanceof Error && thrown === errorLike; + } + function compatibleConstructor(thrown, errorLike) { + if (errorLike instanceof Error) { + return thrown.constructor === errorLike.constructor || thrown instanceof errorLike.constructor; + } else if (errorLike.prototype instanceof Error || errorLike === Error) { + return thrown.constructor === errorLike || thrown instanceof errorLike; + } + return false; + } + function compatibleMessage(thrown, errMatcher) { + var comparisonString = typeof thrown === "string" ? thrown : thrown.message; + if (errMatcher instanceof RegExp) { + return errMatcher.test(comparisonString); + } else if (typeof errMatcher === "string") { + return comparisonString.indexOf(errMatcher) !== -1; + } + return false; + } + function getConstructorName(errorLike) { + var constructorName = errorLike; + if (errorLike instanceof Error) { + constructorName = getFunctionName(errorLike.constructor); + } else if (typeof errorLike === "function") { + constructorName = getFunctionName(errorLike); + if (constructorName === "") { + var newConstructorName = getFunctionName(new errorLike()); + constructorName = newConstructorName || constructorName; + } + } + return constructorName; + } + function getMessage(errorLike) { + var msg = ""; + if (errorLike && errorLike.message) { + msg = errorLike.message; + } else if (typeof errorLike === "string") { + msg = errorLike; + } + return msg; + } + module.exports = { + compatibleInstance, + compatibleConstructor, + compatibleMessage, + getMessage, + getConstructorName + }; + } + }); + + // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/isNaN.js + var require_isNaN = __commonJS({ + "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/isNaN.js"(exports, module) { + function isNaN2(value) { + return value !== value; + } + module.exports = Number.isNaN || isNaN2; + } + }); + + // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/getOperator.js + var require_getOperator = __commonJS({ + "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/getOperator.js"(exports, module) { + var type = require_type_detect(); + var flag = require_flag(); + function isObjectType(obj) { + var objectType = type(obj); + var objectTypes = ["Array", "Object", "function"]; + return objectTypes.indexOf(objectType) !== -1; + } + module.exports = function getOperator2(obj, args) { + var operator = flag(obj, "operator"); + var negate = flag(obj, "negate"); + var expected = args[3]; + var msg = negate ? args[2] : args[1]; + if (operator) { + return operator; + } + if (typeof msg === "function") + msg = msg(); + msg = msg || ""; + if (!msg) { + return void 0; + } + if (/\shave\s/.test(msg)) { + return void 0; + } + var isObject2 = isObjectType(expected); + if (/\snot\s/.test(msg)) { + return isObject2 ? "notDeepStrictEqual" : "notStrictEqual"; + } + return isObject2 ? "deepStrictEqual" : "strictEqual"; + }; + } + }); + + // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/index.js + var require_utils = __commonJS({ + "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/utils/index.js"(exports) { + var pathval = require_pathval(); + exports.test = require_test(); + exports.type = require_type_detect(); + exports.expectTypes = require_expectTypes(); + exports.getMessage = require_getMessage(); + exports.getActual = require_getActual(); + exports.inspect = require_inspect(); + exports.objDisplay = require_objDisplay(); + exports.flag = require_flag(); + exports.transferFlags = require_transferFlags(); + exports.eql = require_deep_eql(); + exports.getPathInfo = pathval.getPathInfo; + exports.hasProperty = pathval.hasProperty; + exports.getName = require_get_func_name(); + exports.addProperty = require_addProperty(); + exports.addMethod = require_addMethod(); + exports.overwriteProperty = require_overwriteProperty(); + exports.overwriteMethod = require_overwriteMethod(); + exports.addChainableMethod = require_addChainableMethod(); + exports.overwriteChainableMethod = require_overwriteChainableMethod(); + exports.compareByInspect = require_compareByInspect(); + exports.getOwnEnumerablePropertySymbols = require_getOwnEnumerablePropertySymbols(); + exports.getOwnEnumerableProperties = require_getOwnEnumerableProperties(); + exports.checkError = require_check_error(); + exports.proxify = require_proxify(); + exports.addLengthGuard = require_addLengthGuard(); + exports.isProxyEnabled = require_isProxyEnabled(); + exports.isNaN = require_isNaN(); + exports.getOperator = require_getOperator(); + } + }); + + // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/assertion.js + var require_assertion = __commonJS({ + "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/assertion.js"(exports, module) { + var config2 = require_config(); + module.exports = function(_chai, util2) { + var AssertionError2 = _chai.AssertionError, flag = util2.flag; + _chai.Assertion = Assertion2; + function Assertion2(obj, msg, ssfi, lockSsfi) { + flag(this, "ssfi", ssfi || Assertion2); + flag(this, "lockSsfi", lockSsfi); + flag(this, "object", obj); + flag(this, "message", msg); + return util2.proxify(this); + } + Object.defineProperty(Assertion2, "includeStack", { + get: function() { + console.warn("Assertion.includeStack is deprecated, use chai.config.includeStack instead."); + return config2.includeStack; + }, + set: function(value) { + console.warn("Assertion.includeStack is deprecated, use chai.config.includeStack instead."); + config2.includeStack = value; + } + }); + Object.defineProperty(Assertion2, "showDiff", { + get: function() { + console.warn("Assertion.showDiff is deprecated, use chai.config.showDiff instead."); + return config2.showDiff; + }, + set: function(value) { + console.warn("Assertion.showDiff is deprecated, use chai.config.showDiff instead."); + config2.showDiff = value; + } + }); + Assertion2.addProperty = function(name, fn) { + util2.addProperty(this.prototype, name, fn); + }; + Assertion2.addMethod = function(name, fn) { + util2.addMethod(this.prototype, name, fn); + }; + Assertion2.addChainableMethod = function(name, fn, chainingBehavior) { + util2.addChainableMethod(this.prototype, name, fn, chainingBehavior); + }; + Assertion2.overwriteProperty = function(name, fn) { + util2.overwriteProperty(this.prototype, name, fn); + }; + Assertion2.overwriteMethod = function(name, fn) { + util2.overwriteMethod(this.prototype, name, fn); + }; + Assertion2.overwriteChainableMethod = function(name, fn, chainingBehavior) { + util2.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior); + }; + Assertion2.prototype.assert = function(expr, msg, negateMsg, expected, _actual, showDiff) { + var ok = util2.test(this, arguments); + if (false !== showDiff) + showDiff = true; + if (void 0 === expected && void 0 === _actual) + showDiff = false; + if (true !== config2.showDiff) + showDiff = false; + if (!ok) { + msg = util2.getMessage(this, arguments); + var actual = util2.getActual(this, arguments); + var assertionErrorObjectProperties = { + actual, + expected, + showDiff + }; + var operator = util2.getOperator(this, arguments); + if (operator) { + assertionErrorObjectProperties.operator = operator; + } + throw new AssertionError2( + msg, + assertionErrorObjectProperties, + config2.includeStack ? this.assert : flag(this, "ssfi") + ); + } + }; + Object.defineProperty( + Assertion2.prototype, + "_obj", + { + get: function() { + return flag(this, "object"); + }, + set: function(val) { + flag(this, "object", val); + } + } + ); + }; + } + }); + + // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/core/assertions.js + var require_assertions = __commonJS({ + "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/core/assertions.js"(exports, module) { + module.exports = function(chai2, _) { + var Assertion2 = chai2.Assertion, AssertionError2 = chai2.AssertionError, flag = _.flag; + [ + "to", + "be", + "been", + "is", + "and", + "has", + "have", + "with", + "that", + "which", + "at", + "of", + "same", + "but", + "does", + "still", + "also" + ].forEach(function(chain) { + Assertion2.addProperty(chain); + }); + Assertion2.addProperty("not", function() { + flag(this, "negate", true); + }); + Assertion2.addProperty("deep", function() { + flag(this, "deep", true); + }); + Assertion2.addProperty("nested", function() { + flag(this, "nested", true); + }); + Assertion2.addProperty("own", function() { + flag(this, "own", true); + }); + Assertion2.addProperty("ordered", function() { + flag(this, "ordered", true); + }); + Assertion2.addProperty("any", function() { + flag(this, "any", true); + flag(this, "all", false); + }); + Assertion2.addProperty("all", function() { + flag(this, "all", true); + flag(this, "any", false); + }); + function an(type, msg) { + if (msg) + flag(this, "message", msg); + type = type.toLowerCase(); + var obj = flag(this, "object"), article = ~["a", "e", "i", "o", "u"].indexOf(type.charAt(0)) ? "an " : "a "; + this.assert( + type === _.type(obj).toLowerCase(), + "expected #{this} to be " + article + type, + "expected #{this} not to be " + article + type + ); + } + Assertion2.addChainableMethod("an", an); + Assertion2.addChainableMethod("a", an); + function SameValueZero(a2, b) { + return _.isNaN(a2) && _.isNaN(b) || a2 === b; + } + function includeChainingBehavior() { + flag(this, "contains", true); + } + function include(val, msg) { + if (msg) + flag(this, "message", msg); + var obj = flag(this, "object"), objType = _.type(obj).toLowerCase(), flagMsg = flag(this, "message"), negate = flag(this, "negate"), ssfi = flag(this, "ssfi"), isDeep = flag(this, "deep"), descriptor = isDeep ? "deep " : ""; + flagMsg = flagMsg ? flagMsg + ": " : ""; + var included = false; + switch (objType) { + case "string": + included = obj.indexOf(val) !== -1; + break; + case "weakset": + if (isDeep) { + throw new AssertionError2( + flagMsg + "unable to use .deep.include with WeakSet", + void 0, + ssfi + ); + } + included = obj.has(val); + break; + case "map": + var isEql = isDeep ? _.eql : SameValueZero; + obj.forEach(function(item) { + included = included || isEql(item, val); + }); + break; + case "set": + if (isDeep) { + obj.forEach(function(item) { + included = included || _.eql(item, val); + }); + } else { + included = obj.has(val); + } + break; + case "array": + if (isDeep) { + included = obj.some(function(item) { + return _.eql(item, val); + }); + } else { + included = obj.indexOf(val) !== -1; + } + break; + default: + if (val !== Object(val)) { + throw new AssertionError2( + flagMsg + "the given combination of arguments (" + objType + " and " + _.type(val).toLowerCase() + ") is invalid for this assertion. You can use an array, a map, an object, a set, a string, or a weakset instead of a " + _.type(val).toLowerCase(), + void 0, + ssfi + ); + } + var props = Object.keys(val), firstErr = null, numErrs = 0; + props.forEach(function(prop) { + var propAssertion = new Assertion2(obj); + _.transferFlags(this, propAssertion, true); + flag(propAssertion, "lockSsfi", true); + if (!negate || props.length === 1) { + propAssertion.property(prop, val[prop]); + return; + } + try { + propAssertion.property(prop, val[prop]); + } catch (err) { + if (!_.checkError.compatibleConstructor(err, AssertionError2)) { + throw err; + } + if (firstErr === null) + firstErr = err; + numErrs++; + } + }, this); + if (negate && props.length > 1 && numErrs === props.length) { + throw firstErr; + } + return; + } + this.assert( + included, + "expected #{this} to " + descriptor + "include " + _.inspect(val), + "expected #{this} to not " + descriptor + "include " + _.inspect(val) + ); + } + Assertion2.addChainableMethod("include", include, includeChainingBehavior); + Assertion2.addChainableMethod("contain", include, includeChainingBehavior); + Assertion2.addChainableMethod("contains", include, includeChainingBehavior); + Assertion2.addChainableMethod("includes", include, includeChainingBehavior); + Assertion2.addProperty("ok", function() { + this.assert( + flag(this, "object"), + "expected #{this} to be truthy", + "expected #{this} to be falsy" + ); + }); + Assertion2.addProperty("true", function() { + this.assert( + true === flag(this, "object"), + "expected #{this} to be true", + "expected #{this} to be false", + flag(this, "negate") ? false : true + ); + }); + Assertion2.addProperty("false", function() { + this.assert( + false === flag(this, "object"), + "expected #{this} to be false", + "expected #{this} to be true", + flag(this, "negate") ? true : false + ); + }); + Assertion2.addProperty("null", function() { + this.assert( + null === flag(this, "object"), + "expected #{this} to be null", + "expected #{this} not to be null" + ); + }); + Assertion2.addProperty("undefined", function() { + this.assert( + void 0 === flag(this, "object"), + "expected #{this} to be undefined", + "expected #{this} not to be undefined" + ); + }); + Assertion2.addProperty("NaN", function() { + this.assert( + _.isNaN(flag(this, "object")), + "expected #{this} to be NaN", + "expected #{this} not to be NaN" + ); + }); + function assertExist() { + var val = flag(this, "object"); + this.assert( + val !== null && val !== void 0, + "expected #{this} to exist", + "expected #{this} to not exist" + ); + } + Assertion2.addProperty("exist", assertExist); + Assertion2.addProperty("exists", assertExist); + Assertion2.addProperty("empty", function() { + var val = flag(this, "object"), ssfi = flag(this, "ssfi"), flagMsg = flag(this, "message"), itemsCount; + flagMsg = flagMsg ? flagMsg + ": " : ""; + switch (_.type(val).toLowerCase()) { + case "array": + case "string": + itemsCount = val.length; + break; + case "map": + case "set": + itemsCount = val.size; + break; + case "weakmap": + case "weakset": + throw new AssertionError2( + flagMsg + ".empty was passed a weak collection", + void 0, + ssfi + ); + case "function": + var msg = flagMsg + ".empty was passed a function " + _.getName(val); + throw new AssertionError2(msg.trim(), void 0, ssfi); + default: + if (val !== Object(val)) { + throw new AssertionError2( + flagMsg + ".empty was passed non-string primitive " + _.inspect(val), + void 0, + ssfi + ); + } + itemsCount = Object.keys(val).length; + } + this.assert( + 0 === itemsCount, + "expected #{this} to be empty", + "expected #{this} not to be empty" + ); + }); + function checkArguments() { + var obj = flag(this, "object"), type = _.type(obj); + this.assert( + "Arguments" === type, + "expected #{this} to be arguments but got " + type, + "expected #{this} to not be arguments" + ); + } + Assertion2.addProperty("arguments", checkArguments); + Assertion2.addProperty("Arguments", checkArguments); + function assertEqual(val, msg) { + if (msg) + flag(this, "message", msg); + var obj = flag(this, "object"); + if (flag(this, "deep")) { + var prevLockSsfi = flag(this, "lockSsfi"); + flag(this, "lockSsfi", true); + this.eql(val); + flag(this, "lockSsfi", prevLockSsfi); + } else { + this.assert( + val === obj, + "expected #{this} to equal #{exp}", + "expected #{this} to not equal #{exp}", + val, + this._obj, + true + ); + } + } + Assertion2.addMethod("equal", assertEqual); + Assertion2.addMethod("equals", assertEqual); + Assertion2.addMethod("eq", assertEqual); + function assertEql(obj, msg) { + if (msg) + flag(this, "message", msg); + this.assert( + _.eql(obj, flag(this, "object")), + "expected #{this} to deeply equal #{exp}", + "expected #{this} to not deeply equal #{exp}", + obj, + this._obj, + true + ); + } + Assertion2.addMethod("eql", assertEql); + Assertion2.addMethod("eqls", assertEql); + function assertAbove(n, msg) { + if (msg) + flag(this, "message", msg); + var obj = flag(this, "object"), doLength = flag(this, "doLength"), flagMsg = flag(this, "message"), msgPrefix = flagMsg ? flagMsg + ": " : "", ssfi = flag(this, "ssfi"), objType = _.type(obj).toLowerCase(), nType = _.type(n).toLowerCase(), errorMessage, shouldThrow = true; + if (doLength && objType !== "map" && objType !== "set") { + new Assertion2(obj, flagMsg, ssfi, true).to.have.property("length"); + } + if (!doLength && (objType === "date" && nType !== "date")) { + errorMessage = msgPrefix + "the argument to above must be a date"; + } else if (nType !== "number" && (doLength || objType === "number")) { + errorMessage = msgPrefix + "the argument to above must be a number"; + } else if (!doLength && (objType !== "date" && objType !== "number")) { + var printObj = objType === "string" ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + "expected " + printObj + " to be a number or a date"; + } else { + shouldThrow = false; + } + if (shouldThrow) { + throw new AssertionError2(errorMessage, void 0, ssfi); + } + if (doLength) { + var descriptor = "length", itemsCount; + if (objType === "map" || objType === "set") { + descriptor = "size"; + itemsCount = obj.size; + } else { + itemsCount = obj.length; + } + this.assert( + itemsCount > n, + "expected #{this} to have a " + descriptor + " above #{exp} but got #{act}", + "expected #{this} to not have a " + descriptor + " above #{exp}", + n, + itemsCount + ); + } else { + this.assert( + obj > n, + "expected #{this} to be above #{exp}", + "expected #{this} to be at most #{exp}", + n + ); + } + } + Assertion2.addMethod("above", assertAbove); + Assertion2.addMethod("gt", assertAbove); + Assertion2.addMethod("greaterThan", assertAbove); + function assertLeast(n, msg) { + if (msg) + flag(this, "message", msg); + var obj = flag(this, "object"), doLength = flag(this, "doLength"), flagMsg = flag(this, "message"), msgPrefix = flagMsg ? flagMsg + ": " : "", ssfi = flag(this, "ssfi"), objType = _.type(obj).toLowerCase(), nType = _.type(n).toLowerCase(), errorMessage, shouldThrow = true; + if (doLength && objType !== "map" && objType !== "set") { + new Assertion2(obj, flagMsg, ssfi, true).to.have.property("length"); + } + if (!doLength && (objType === "date" && nType !== "date")) { + errorMessage = msgPrefix + "the argument to least must be a date"; + } else if (nType !== "number" && (doLength || objType === "number")) { + errorMessage = msgPrefix + "the argument to least must be a number"; + } else if (!doLength && (objType !== "date" && objType !== "number")) { + var printObj = objType === "string" ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + "expected " + printObj + " to be a number or a date"; + } else { + shouldThrow = false; + } + if (shouldThrow) { + throw new AssertionError2(errorMessage, void 0, ssfi); + } + if (doLength) { + var descriptor = "length", itemsCount; + if (objType === "map" || objType === "set") { + descriptor = "size"; + itemsCount = obj.size; + } else { + itemsCount = obj.length; + } + this.assert( + itemsCount >= n, + "expected #{this} to have a " + descriptor + " at least #{exp} but got #{act}", + "expected #{this} to have a " + descriptor + " below #{exp}", + n, + itemsCount + ); + } else { + this.assert( + obj >= n, + "expected #{this} to be at least #{exp}", + "expected #{this} to be below #{exp}", + n + ); + } + } + Assertion2.addMethod("least", assertLeast); + Assertion2.addMethod("gte", assertLeast); + Assertion2.addMethod("greaterThanOrEqual", assertLeast); + function assertBelow(n, msg) { + if (msg) + flag(this, "message", msg); + var obj = flag(this, "object"), doLength = flag(this, "doLength"), flagMsg = flag(this, "message"), msgPrefix = flagMsg ? flagMsg + ": " : "", ssfi = flag(this, "ssfi"), objType = _.type(obj).toLowerCase(), nType = _.type(n).toLowerCase(), errorMessage, shouldThrow = true; + if (doLength && objType !== "map" && objType !== "set") { + new Assertion2(obj, flagMsg, ssfi, true).to.have.property("length"); + } + if (!doLength && (objType === "date" && nType !== "date")) { + errorMessage = msgPrefix + "the argument to below must be a date"; + } else if (nType !== "number" && (doLength || objType === "number")) { + errorMessage = msgPrefix + "the argument to below must be a number"; + } else if (!doLength && (objType !== "date" && objType !== "number")) { + var printObj = objType === "string" ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + "expected " + printObj + " to be a number or a date"; + } else { + shouldThrow = false; + } + if (shouldThrow) { + throw new AssertionError2(errorMessage, void 0, ssfi); + } + if (doLength) { + var descriptor = "length", itemsCount; + if (objType === "map" || objType === "set") { + descriptor = "size"; + itemsCount = obj.size; + } else { + itemsCount = obj.length; + } + this.assert( + itemsCount < n, + "expected #{this} to have a " + descriptor + " below #{exp} but got #{act}", + "expected #{this} to not have a " + descriptor + " below #{exp}", + n, + itemsCount + ); + } else { + this.assert( + obj < n, + "expected #{this} to be below #{exp}", + "expected #{this} to be at least #{exp}", + n + ); + } + } + Assertion2.addMethod("below", assertBelow); + Assertion2.addMethod("lt", assertBelow); + Assertion2.addMethod("lessThan", assertBelow); + function assertMost(n, msg) { + if (msg) + flag(this, "message", msg); + var obj = flag(this, "object"), doLength = flag(this, "doLength"), flagMsg = flag(this, "message"), msgPrefix = flagMsg ? flagMsg + ": " : "", ssfi = flag(this, "ssfi"), objType = _.type(obj).toLowerCase(), nType = _.type(n).toLowerCase(), errorMessage, shouldThrow = true; + if (doLength && objType !== "map" && objType !== "set") { + new Assertion2(obj, flagMsg, ssfi, true).to.have.property("length"); + } + if (!doLength && (objType === "date" && nType !== "date")) { + errorMessage = msgPrefix + "the argument to most must be a date"; + } else if (nType !== "number" && (doLength || objType === "number")) { + errorMessage = msgPrefix + "the argument to most must be a number"; + } else if (!doLength && (objType !== "date" && objType !== "number")) { + var printObj = objType === "string" ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + "expected " + printObj + " to be a number or a date"; + } else { + shouldThrow = false; + } + if (shouldThrow) { + throw new AssertionError2(errorMessage, void 0, ssfi); + } + if (doLength) { + var descriptor = "length", itemsCount; + if (objType === "map" || objType === "set") { + descriptor = "size"; + itemsCount = obj.size; + } else { + itemsCount = obj.length; + } + this.assert( + itemsCount <= n, + "expected #{this} to have a " + descriptor + " at most #{exp} but got #{act}", + "expected #{this} to have a " + descriptor + " above #{exp}", + n, + itemsCount + ); + } else { + this.assert( + obj <= n, + "expected #{this} to be at most #{exp}", + "expected #{this} to be above #{exp}", + n + ); + } + } + Assertion2.addMethod("most", assertMost); + Assertion2.addMethod("lte", assertMost); + Assertion2.addMethod("lessThanOrEqual", assertMost); + Assertion2.addMethod("within", function(start, finish, msg) { + if (msg) + flag(this, "message", msg); + var obj = flag(this, "object"), doLength = flag(this, "doLength"), flagMsg = flag(this, "message"), msgPrefix = flagMsg ? flagMsg + ": " : "", ssfi = flag(this, "ssfi"), objType = _.type(obj).toLowerCase(), startType = _.type(start).toLowerCase(), finishType = _.type(finish).toLowerCase(), errorMessage, shouldThrow = true, range = startType === "date" && finishType === "date" ? start.toISOString() + ".." + finish.toISOString() : start + ".." + finish; + if (doLength && objType !== "map" && objType !== "set") { + new Assertion2(obj, flagMsg, ssfi, true).to.have.property("length"); + } + if (!doLength && (objType === "date" && (startType !== "date" || finishType !== "date"))) { + errorMessage = msgPrefix + "the arguments to within must be dates"; + } else if ((startType !== "number" || finishType !== "number") && (doLength || objType === "number")) { + errorMessage = msgPrefix + "the arguments to within must be numbers"; + } else if (!doLength && (objType !== "date" && objType !== "number")) { + var printObj = objType === "string" ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + "expected " + printObj + " to be a number or a date"; + } else { + shouldThrow = false; + } + if (shouldThrow) { + throw new AssertionError2(errorMessage, void 0, ssfi); + } + if (doLength) { + var descriptor = "length", itemsCount; + if (objType === "map" || objType === "set") { + descriptor = "size"; + itemsCount = obj.size; + } else { + itemsCount = obj.length; + } + this.assert( + itemsCount >= start && itemsCount <= finish, + "expected #{this} to have a " + descriptor + " within " + range, + "expected #{this} to not have a " + descriptor + " within " + range + ); + } else { + this.assert( + obj >= start && obj <= finish, + "expected #{this} to be within " + range, + "expected #{this} to not be within " + range + ); + } + }); + function assertInstanceOf(constructor, msg) { + if (msg) + flag(this, "message", msg); + var target = flag(this, "object"); + var ssfi = flag(this, "ssfi"); + var flagMsg = flag(this, "message"); + try { + var isInstanceOf = target instanceof constructor; + } catch (err) { + if (err instanceof TypeError) { + flagMsg = flagMsg ? flagMsg + ": " : ""; + throw new AssertionError2( + flagMsg + "The instanceof assertion needs a constructor but " + _.type(constructor) + " was given.", + void 0, + ssfi + ); + } + throw err; + } + var name = _.getName(constructor); + if (name === null) { + name = "an unnamed constructor"; + } + this.assert( + isInstanceOf, + "expected #{this} to be an instance of " + name, + "expected #{this} to not be an instance of " + name + ); + } + ; + Assertion2.addMethod("instanceof", assertInstanceOf); + Assertion2.addMethod("instanceOf", assertInstanceOf); + function assertProperty(name, val, msg) { + if (msg) + flag(this, "message", msg); + var isNested = flag(this, "nested"), isOwn = flag(this, "own"), flagMsg = flag(this, "message"), obj = flag(this, "object"), ssfi = flag(this, "ssfi"), nameType = typeof name; + flagMsg = flagMsg ? flagMsg + ": " : ""; + if (isNested) { + if (nameType !== "string") { + throw new AssertionError2( + flagMsg + "the argument to property must be a string when using nested syntax", + void 0, + ssfi + ); + } + } else { + if (nameType !== "string" && nameType !== "number" && nameType !== "symbol") { + throw new AssertionError2( + flagMsg + "the argument to property must be a string, number, or symbol", + void 0, + ssfi + ); + } + } + if (isNested && isOwn) { + throw new AssertionError2( + flagMsg + 'The "nested" and "own" flags cannot be combined.', + void 0, + ssfi + ); + } + if (obj === null || obj === void 0) { + throw new AssertionError2( + flagMsg + "Target cannot be null or undefined.", + void 0, + ssfi + ); + } + var isDeep = flag(this, "deep"), negate = flag(this, "negate"), pathInfo = isNested ? _.getPathInfo(obj, name) : null, value = isNested ? pathInfo.value : obj[name]; + var descriptor = ""; + if (isDeep) + descriptor += "deep "; + if (isOwn) + descriptor += "own "; + if (isNested) + descriptor += "nested "; + descriptor += "property "; + var hasProperty; + if (isOwn) + hasProperty = Object.prototype.hasOwnProperty.call(obj, name); + else if (isNested) + hasProperty = pathInfo.exists; + else + hasProperty = _.hasProperty(obj, name); + if (!negate || arguments.length === 1) { + this.assert( + hasProperty, + "expected #{this} to have " + descriptor + _.inspect(name), + "expected #{this} to not have " + descriptor + _.inspect(name) + ); + } + if (arguments.length > 1) { + this.assert( + hasProperty && (isDeep ? _.eql(val, value) : val === value), + "expected #{this} to have " + descriptor + _.inspect(name) + " of #{exp}, but got #{act}", + "expected #{this} to not have " + descriptor + _.inspect(name) + " of #{act}", + val, + value + ); + } + flag(this, "object", value); + } + Assertion2.addMethod("property", assertProperty); + function assertOwnProperty(name, value, msg) { + flag(this, "own", true); + assertProperty.apply(this, arguments); + } + Assertion2.addMethod("ownProperty", assertOwnProperty); + Assertion2.addMethod("haveOwnProperty", assertOwnProperty); + function assertOwnPropertyDescriptor(name, descriptor, msg) { + if (typeof descriptor === "string") { + msg = descriptor; + descriptor = null; + } + if (msg) + flag(this, "message", msg); + var obj = flag(this, "object"); + var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name); + if (actualDescriptor && descriptor) { + this.assert( + _.eql(descriptor, actualDescriptor), + "expected the own property descriptor for " + _.inspect(name) + " on #{this} to match " + _.inspect(descriptor) + ", got " + _.inspect(actualDescriptor), + "expected the own property descriptor for " + _.inspect(name) + " on #{this} to not match " + _.inspect(descriptor), + descriptor, + actualDescriptor, + true + ); + } else { + this.assert( + actualDescriptor, + "expected #{this} to have an own property descriptor for " + _.inspect(name), + "expected #{this} to not have an own property descriptor for " + _.inspect(name) + ); + } + flag(this, "object", actualDescriptor); + } + Assertion2.addMethod("ownPropertyDescriptor", assertOwnPropertyDescriptor); + Assertion2.addMethod("haveOwnPropertyDescriptor", assertOwnPropertyDescriptor); + function assertLengthChain() { + flag(this, "doLength", true); + } + function assertLength(n, msg) { + if (msg) + flag(this, "message", msg); + var obj = flag(this, "object"), objType = _.type(obj).toLowerCase(), flagMsg = flag(this, "message"), ssfi = flag(this, "ssfi"), descriptor = "length", itemsCount; + switch (objType) { + case "map": + case "set": + descriptor = "size"; + itemsCount = obj.size; + break; + default: + new Assertion2(obj, flagMsg, ssfi, true).to.have.property("length"); + itemsCount = obj.length; + } + this.assert( + itemsCount == n, + "expected #{this} to have a " + descriptor + " of #{exp} but got #{act}", + "expected #{this} to not have a " + descriptor + " of #{act}", + n, + itemsCount + ); + } + Assertion2.addChainableMethod("length", assertLength, assertLengthChain); + Assertion2.addChainableMethod("lengthOf", assertLength, assertLengthChain); + function assertMatch(re, msg) { + if (msg) + flag(this, "message", msg); + var obj = flag(this, "object"); + this.assert( + re.exec(obj), + "expected #{this} to match " + re, + "expected #{this} not to match " + re + ); + } + Assertion2.addMethod("match", assertMatch); + Assertion2.addMethod("matches", assertMatch); + Assertion2.addMethod("string", function(str, msg) { + if (msg) + flag(this, "message", msg); + var obj = flag(this, "object"), flagMsg = flag(this, "message"), ssfi = flag(this, "ssfi"); + new Assertion2(obj, flagMsg, ssfi, true).is.a("string"); + this.assert( + ~obj.indexOf(str), + "expected #{this} to contain " + _.inspect(str), + "expected #{this} to not contain " + _.inspect(str) + ); + }); + function assertKeys(keys) { + var obj = flag(this, "object"), objType = _.type(obj), keysType = _.type(keys), ssfi = flag(this, "ssfi"), isDeep = flag(this, "deep"), str, deepStr = "", actual, ok = true, flagMsg = flag(this, "message"); + flagMsg = flagMsg ? flagMsg + ": " : ""; + var mixedArgsMsg = flagMsg + "when testing keys against an object or an array you must give a single Array|Object|String argument or multiple String arguments"; + if (objType === "Map" || objType === "Set") { + deepStr = isDeep ? "deeply " : ""; + actual = []; + obj.forEach(function(val, key) { + actual.push(key); + }); + if (keysType !== "Array") { + keys = Array.prototype.slice.call(arguments); + } + } else { + actual = _.getOwnEnumerableProperties(obj); + switch (keysType) { + case "Array": + if (arguments.length > 1) { + throw new AssertionError2(mixedArgsMsg, void 0, ssfi); + } + break; + case "Object": + if (arguments.length > 1) { + throw new AssertionError2(mixedArgsMsg, void 0, ssfi); + } + keys = Object.keys(keys); + break; + default: + keys = Array.prototype.slice.call(arguments); + } + keys = keys.map(function(val) { + return typeof val === "symbol" ? val : String(val); + }); + } + if (!keys.length) { + throw new AssertionError2(flagMsg + "keys required", void 0, ssfi); + } + var len = keys.length, any = flag(this, "any"), all = flag(this, "all"), expected = keys; + if (!any && !all) { + all = true; + } + if (any) { + ok = expected.some(function(expectedKey) { + return actual.some(function(actualKey) { + if (isDeep) { + return _.eql(expectedKey, actualKey); + } else { + return expectedKey === actualKey; + } + }); + }); + } + if (all) { + ok = expected.every(function(expectedKey) { + return actual.some(function(actualKey) { + if (isDeep) { + return _.eql(expectedKey, actualKey); + } else { + return expectedKey === actualKey; + } + }); + }); + if (!flag(this, "contains")) { + ok = ok && keys.length == actual.length; + } + } + if (len > 1) { + keys = keys.map(function(key) { + return _.inspect(key); + }); + var last = keys.pop(); + if (all) { + str = keys.join(", ") + ", and " + last; + } + if (any) { + str = keys.join(", ") + ", or " + last; + } + } else { + str = _.inspect(keys[0]); + } + str = (len > 1 ? "keys " : "key ") + str; + str = (flag(this, "contains") ? "contain " : "have ") + str; + this.assert( + ok, + "expected #{this} to " + deepStr + str, + "expected #{this} to not " + deepStr + str, + expected.slice(0).sort(_.compareByInspect), + actual.sort(_.compareByInspect), + true + ); + } + Assertion2.addMethod("keys", assertKeys); + Assertion2.addMethod("key", assertKeys); + function assertThrows(errorLike, errMsgMatcher, msg) { + if (msg) + flag(this, "message", msg); + var obj = flag(this, "object"), ssfi = flag(this, "ssfi"), flagMsg = flag(this, "message"), negate = flag(this, "negate") || false; + new Assertion2(obj, flagMsg, ssfi, true).is.a("function"); + if (errorLike instanceof RegExp || typeof errorLike === "string") { + errMsgMatcher = errorLike; + errorLike = null; + } + var caughtErr; + try { + obj(); + } catch (err) { + caughtErr = err; + } + var everyArgIsUndefined = errorLike === void 0 && errMsgMatcher === void 0; + var everyArgIsDefined = Boolean(errorLike && errMsgMatcher); + var errorLikeFail = false; + var errMsgMatcherFail = false; + if (everyArgIsUndefined || !everyArgIsUndefined && !negate) { + var errorLikeString = "an error"; + if (errorLike instanceof Error) { + errorLikeString = "#{exp}"; + } else if (errorLike) { + errorLikeString = _.checkError.getConstructorName(errorLike); + } + this.assert( + caughtErr, + "expected #{this} to throw " + errorLikeString, + "expected #{this} to not throw an error but #{act} was thrown", + errorLike && errorLike.toString(), + caughtErr instanceof Error ? caughtErr.toString() : typeof caughtErr === "string" ? caughtErr : caughtErr && _.checkError.getConstructorName(caughtErr) + ); + } + if (errorLike && caughtErr) { + if (errorLike instanceof Error) { + var isCompatibleInstance = _.checkError.compatibleInstance(caughtErr, errorLike); + if (isCompatibleInstance === negate) { + if (everyArgIsDefined && negate) { + errorLikeFail = true; + } else { + this.assert( + negate, + "expected #{this} to throw #{exp} but #{act} was thrown", + "expected #{this} to not throw #{exp}" + (caughtErr && !negate ? " but #{act} was thrown" : ""), + errorLike.toString(), + caughtErr.toString() + ); + } + } + } + var isCompatibleConstructor = _.checkError.compatibleConstructor(caughtErr, errorLike); + if (isCompatibleConstructor === negate) { + if (everyArgIsDefined && negate) { + errorLikeFail = true; + } else { + this.assert( + negate, + "expected #{this} to throw #{exp} but #{act} was thrown", + "expected #{this} to not throw #{exp}" + (caughtErr ? " but #{act} was thrown" : ""), + errorLike instanceof Error ? errorLike.toString() : errorLike && _.checkError.getConstructorName(errorLike), + caughtErr instanceof Error ? caughtErr.toString() : caughtErr && _.checkError.getConstructorName(caughtErr) + ); + } + } + } + if (caughtErr && errMsgMatcher !== void 0 && errMsgMatcher !== null) { + var placeholder = "including"; + if (errMsgMatcher instanceof RegExp) { + placeholder = "matching"; + } + var isCompatibleMessage = _.checkError.compatibleMessage(caughtErr, errMsgMatcher); + if (isCompatibleMessage === negate) { + if (everyArgIsDefined && negate) { + errMsgMatcherFail = true; + } else { + this.assert( + negate, + "expected #{this} to throw error " + placeholder + " #{exp} but got #{act}", + "expected #{this} to throw error not " + placeholder + " #{exp}", + errMsgMatcher, + _.checkError.getMessage(caughtErr) + ); + } + } + } + if (errorLikeFail && errMsgMatcherFail) { + this.assert( + negate, + "expected #{this} to throw #{exp} but #{act} was thrown", + "expected #{this} to not throw #{exp}" + (caughtErr ? " but #{act} was thrown" : ""), + errorLike instanceof Error ? errorLike.toString() : errorLike && _.checkError.getConstructorName(errorLike), + caughtErr instanceof Error ? caughtErr.toString() : caughtErr && _.checkError.getConstructorName(caughtErr) + ); + } + flag(this, "object", caughtErr); + } + ; + Assertion2.addMethod("throw", assertThrows); + Assertion2.addMethod("throws", assertThrows); + Assertion2.addMethod("Throw", assertThrows); + function respondTo(method, msg) { + if (msg) + flag(this, "message", msg); + var obj = flag(this, "object"), itself = flag(this, "itself"), context = "function" === typeof obj && !itself ? obj.prototype[method] : obj[method]; + this.assert( + "function" === typeof context, + "expected #{this} to respond to " + _.inspect(method), + "expected #{this} to not respond to " + _.inspect(method) + ); + } + Assertion2.addMethod("respondTo", respondTo); + Assertion2.addMethod("respondsTo", respondTo); + Assertion2.addProperty("itself", function() { + flag(this, "itself", true); + }); + function satisfy(matcher, msg) { + if (msg) + flag(this, "message", msg); + var obj = flag(this, "object"); + var result = matcher(obj); + this.assert( + result, + "expected #{this} to satisfy " + _.objDisplay(matcher), + "expected #{this} to not satisfy" + _.objDisplay(matcher), + flag(this, "negate") ? false : true, + result + ); + } + Assertion2.addMethod("satisfy", satisfy); + Assertion2.addMethod("satisfies", satisfy); + function closeTo(expected, delta, msg) { + if (msg) + flag(this, "message", msg); + var obj = flag(this, "object"), flagMsg = flag(this, "message"), ssfi = flag(this, "ssfi"); + new Assertion2(obj, flagMsg, ssfi, true).is.a("number"); + if (typeof expected !== "number" || typeof delta !== "number") { + flagMsg = flagMsg ? flagMsg + ": " : ""; + var deltaMessage = delta === void 0 ? ", and a delta is required" : ""; + throw new AssertionError2( + flagMsg + "the arguments to closeTo or approximately must be numbers" + deltaMessage, + void 0, + ssfi + ); + } + this.assert( + Math.abs(obj - expected) <= delta, + "expected #{this} to be close to " + expected + " +/- " + delta, + "expected #{this} not to be close to " + expected + " +/- " + delta + ); + } + Assertion2.addMethod("closeTo", closeTo); + Assertion2.addMethod("approximately", closeTo); + function isSubsetOf(subset, superset, cmp, contains, ordered) { + if (!contains) { + if (subset.length !== superset.length) + return false; + superset = superset.slice(); + } + return subset.every(function(elem, idx) { + if (ordered) + return cmp ? cmp(elem, superset[idx]) : elem === superset[idx]; + if (!cmp) { + var matchIdx = superset.indexOf(elem); + if (matchIdx === -1) + return false; + if (!contains) + superset.splice(matchIdx, 1); + return true; + } + return superset.some(function(elem2, matchIdx2) { + if (!cmp(elem, elem2)) + return false; + if (!contains) + superset.splice(matchIdx2, 1); + return true; + }); + }); + } + Assertion2.addMethod("members", function(subset, msg) { + if (msg) + flag(this, "message", msg); + var obj = flag(this, "object"), flagMsg = flag(this, "message"), ssfi = flag(this, "ssfi"); + new Assertion2(obj, flagMsg, ssfi, true).to.be.an("array"); + new Assertion2(subset, flagMsg, ssfi, true).to.be.an("array"); + var contains = flag(this, "contains"); + var ordered = flag(this, "ordered"); + var subject, failMsg, failNegateMsg; + if (contains) { + subject = ordered ? "an ordered superset" : "a superset"; + failMsg = "expected #{this} to be " + subject + " of #{exp}"; + failNegateMsg = "expected #{this} to not be " + subject + " of #{exp}"; + } else { + subject = ordered ? "ordered members" : "members"; + failMsg = "expected #{this} to have the same " + subject + " as #{exp}"; + failNegateMsg = "expected #{this} to not have the same " + subject + " as #{exp}"; + } + var cmp = flag(this, "deep") ? _.eql : void 0; + this.assert( + isSubsetOf(subset, obj, cmp, contains, ordered), + failMsg, + failNegateMsg, + subset, + obj, + true + ); + }); + function oneOf(list, msg) { + if (msg) + flag(this, "message", msg); + var expected = flag(this, "object"), flagMsg = flag(this, "message"), ssfi = flag(this, "ssfi"), contains = flag(this, "contains"), isDeep = flag(this, "deep"); + new Assertion2(list, flagMsg, ssfi, true).to.be.an("array"); + if (contains) { + this.assert( + list.some(function(possibility) { + return expected.indexOf(possibility) > -1; + }), + "expected #{this} to contain one of #{exp}", + "expected #{this} to not contain one of #{exp}", + list, + expected + ); + } else { + if (isDeep) { + this.assert( + list.some(function(possibility) { + return _.eql(expected, possibility); + }), + "expected #{this} to deeply equal one of #{exp}", + "expected #{this} to deeply equal one of #{exp}", + list, + expected + ); + } else { + this.assert( + list.indexOf(expected) > -1, + "expected #{this} to be one of #{exp}", + "expected #{this} to not be one of #{exp}", + list, + expected + ); + } + } + } + Assertion2.addMethod("oneOf", oneOf); + function assertChanges(subject, prop, msg) { + if (msg) + flag(this, "message", msg); + var fn = flag(this, "object"), flagMsg = flag(this, "message"), ssfi = flag(this, "ssfi"); + new Assertion2(fn, flagMsg, ssfi, true).is.a("function"); + var initial; + if (!prop) { + new Assertion2(subject, flagMsg, ssfi, true).is.a("function"); + initial = subject(); + } else { + new Assertion2(subject, flagMsg, ssfi, true).to.have.property(prop); + initial = subject[prop]; + } + fn(); + var final = prop === void 0 || prop === null ? subject() : subject[prop]; + var msgObj = prop === void 0 || prop === null ? initial : "." + prop; + flag(this, "deltaMsgObj", msgObj); + flag(this, "initialDeltaValue", initial); + flag(this, "finalDeltaValue", final); + flag(this, "deltaBehavior", "change"); + flag(this, "realDelta", final !== initial); + this.assert( + initial !== final, + "expected " + msgObj + " to change", + "expected " + msgObj + " to not change" + ); + } + Assertion2.addMethod("change", assertChanges); + Assertion2.addMethod("changes", assertChanges); + function assertIncreases(subject, prop, msg) { + if (msg) + flag(this, "message", msg); + var fn = flag(this, "object"), flagMsg = flag(this, "message"), ssfi = flag(this, "ssfi"); + new Assertion2(fn, flagMsg, ssfi, true).is.a("function"); + var initial; + if (!prop) { + new Assertion2(subject, flagMsg, ssfi, true).is.a("function"); + initial = subject(); + } else { + new Assertion2(subject, flagMsg, ssfi, true).to.have.property(prop); + initial = subject[prop]; + } + new Assertion2(initial, flagMsg, ssfi, true).is.a("number"); + fn(); + var final = prop === void 0 || prop === null ? subject() : subject[prop]; + var msgObj = prop === void 0 || prop === null ? initial : "." + prop; + flag(this, "deltaMsgObj", msgObj); + flag(this, "initialDeltaValue", initial); + flag(this, "finalDeltaValue", final); + flag(this, "deltaBehavior", "increase"); + flag(this, "realDelta", final - initial); + this.assert( + final - initial > 0, + "expected " + msgObj + " to increase", + "expected " + msgObj + " to not increase" + ); + } + Assertion2.addMethod("increase", assertIncreases); + Assertion2.addMethod("increases", assertIncreases); + function assertDecreases(subject, prop, msg) { + if (msg) + flag(this, "message", msg); + var fn = flag(this, "object"), flagMsg = flag(this, "message"), ssfi = flag(this, "ssfi"); + new Assertion2(fn, flagMsg, ssfi, true).is.a("function"); + var initial; + if (!prop) { + new Assertion2(subject, flagMsg, ssfi, true).is.a("function"); + initial = subject(); + } else { + new Assertion2(subject, flagMsg, ssfi, true).to.have.property(prop); + initial = subject[prop]; + } + new Assertion2(initial, flagMsg, ssfi, true).is.a("number"); + fn(); + var final = prop === void 0 || prop === null ? subject() : subject[prop]; + var msgObj = prop === void 0 || prop === null ? initial : "." + prop; + flag(this, "deltaMsgObj", msgObj); + flag(this, "initialDeltaValue", initial); + flag(this, "finalDeltaValue", final); + flag(this, "deltaBehavior", "decrease"); + flag(this, "realDelta", initial - final); + this.assert( + final - initial < 0, + "expected " + msgObj + " to decrease", + "expected " + msgObj + " to not decrease" + ); + } + Assertion2.addMethod("decrease", assertDecreases); + Assertion2.addMethod("decreases", assertDecreases); + function assertDelta(delta, msg) { + if (msg) + flag(this, "message", msg); + var msgObj = flag(this, "deltaMsgObj"); + var initial = flag(this, "initialDeltaValue"); + var final = flag(this, "finalDeltaValue"); + var behavior = flag(this, "deltaBehavior"); + var realDelta = flag(this, "realDelta"); + var expression; + if (behavior === "change") { + expression = Math.abs(final - initial) === Math.abs(delta); + } else { + expression = realDelta === Math.abs(delta); + } + this.assert( + expression, + "expected " + msgObj + " to " + behavior + " by " + delta, + "expected " + msgObj + " to not " + behavior + " by " + delta + ); + } + Assertion2.addMethod("by", assertDelta); + Assertion2.addProperty("extensible", function() { + var obj = flag(this, "object"); + var isExtensible = obj === Object(obj) && Object.isExtensible(obj); + this.assert( + isExtensible, + "expected #{this} to be extensible", + "expected #{this} to not be extensible" + ); + }); + Assertion2.addProperty("sealed", function() { + var obj = flag(this, "object"); + var isSealed = obj === Object(obj) ? Object.isSealed(obj) : true; + this.assert( + isSealed, + "expected #{this} to be sealed", + "expected #{this} to not be sealed" + ); + }); + Assertion2.addProperty("frozen", function() { + var obj = flag(this, "object"); + var isFrozen = obj === Object(obj) ? Object.isFrozen(obj) : true; + this.assert( + isFrozen, + "expected #{this} to be frozen", + "expected #{this} to not be frozen" + ); + }); + Assertion2.addProperty("finite", function(msg) { + var obj = flag(this, "object"); + this.assert( + typeof obj === "number" && isFinite(obj), + "expected #{this} to be a finite number", + "expected #{this} to not be a finite number" + ); + }); + }; + } + }); + + // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/interface/expect.js + var require_expect = __commonJS({ + "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/interface/expect.js"(exports, module) { + module.exports = function(chai2, util2) { + chai2.expect = function(val, message) { + return new chai2.Assertion(val, message); + }; + chai2.expect.fail = function(actual, expected, message, operator) { + if (arguments.length < 2) { + message = actual; + actual = void 0; + } + message = message || "expect.fail()"; + throw new chai2.AssertionError(message, { + actual, + expected, + operator + }, chai2.expect.fail); + }; + }; + } + }); + + // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/interface/should.js + var require_should = __commonJS({ + "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/interface/should.js"(exports, module) { + module.exports = function(chai2, util2) { + var Assertion2 = chai2.Assertion; + function loadShould() { + function shouldGetter() { + if (this instanceof String || this instanceof Number || this instanceof Boolean || typeof Symbol === "function" && this instanceof Symbol || typeof BigInt === "function" && this instanceof BigInt) { + return new Assertion2(this.valueOf(), null, shouldGetter); + } + return new Assertion2(this, null, shouldGetter); + } + function shouldSetter(value) { + Object.defineProperty(this, "should", { + value, + enumerable: true, + configurable: true, + writable: true + }); + } + Object.defineProperty(Object.prototype, "should", { + set: shouldSetter, + get: shouldGetter, + configurable: true + }); + var should2 = {}; + should2.fail = function(actual, expected, message, operator) { + if (arguments.length < 2) { + message = actual; + actual = void 0; + } + message = message || "should.fail()"; + throw new chai2.AssertionError(message, { + actual, + expected, + operator + }, should2.fail); + }; + should2.equal = function(val1, val2, msg) { + new Assertion2(val1, msg).to.equal(val2); + }; + should2.Throw = function(fn, errt, errs, msg) { + new Assertion2(fn, msg).to.Throw(errt, errs); + }; + should2.exist = function(val, msg) { + new Assertion2(val, msg).to.exist; + }; + should2.not = {}; + should2.not.equal = function(val1, val2, msg) { + new Assertion2(val1, msg).to.not.equal(val2); + }; + should2.not.Throw = function(fn, errt, errs, msg) { + new Assertion2(fn, msg).to.not.Throw(errt, errs); + }; + should2.not.exist = function(val, msg) { + new Assertion2(val, msg).to.not.exist; + }; + should2["throw"] = should2["Throw"]; + should2.not["throw"] = should2.not["Throw"]; + return should2; + } + ; + chai2.should = loadShould; + chai2.Should = loadShould; + }; + } + }); + + // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/interface/assert.js + var require_assert = __commonJS({ + "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai/interface/assert.js"(exports, module) { + module.exports = function(chai2, util2) { + var Assertion2 = chai2.Assertion, flag = util2.flag; + var assert2 = chai2.assert = function(express, errmsg) { + var test = new Assertion2(null, null, chai2.assert, true); + test.assert( + express, + errmsg, + "[ negation message unavailable ]" + ); + }; + assert2.fail = function(actual, expected, message, operator) { + if (arguments.length < 2) { + message = actual; + actual = void 0; + } + message = message || "assert.fail()"; + throw new chai2.AssertionError(message, { + actual, + expected, + operator + }, assert2.fail); + }; + assert2.isOk = function(val, msg) { + new Assertion2(val, msg, assert2.isOk, true).is.ok; + }; + assert2.isNotOk = function(val, msg) { + new Assertion2(val, msg, assert2.isNotOk, true).is.not.ok; + }; + assert2.equal = function(act, exp, msg) { + var test = new Assertion2(act, msg, assert2.equal, true); + test.assert( + exp == flag(test, "object"), + "expected #{this} to equal #{exp}", + "expected #{this} to not equal #{act}", + exp, + act, + true + ); + }; + assert2.notEqual = function(act, exp, msg) { + var test = new Assertion2(act, msg, assert2.notEqual, true); + test.assert( + exp != flag(test, "object"), + "expected #{this} to not equal #{exp}", + "expected #{this} to equal #{act}", + exp, + act, + true + ); + }; + assert2.strictEqual = function(act, exp, msg) { + new Assertion2(act, msg, assert2.strictEqual, true).to.equal(exp); + }; + assert2.notStrictEqual = function(act, exp, msg) { + new Assertion2(act, msg, assert2.notStrictEqual, true).to.not.equal(exp); + }; + assert2.deepEqual = assert2.deepStrictEqual = function(act, exp, msg) { + new Assertion2(act, msg, assert2.deepEqual, true).to.eql(exp); + }; + assert2.notDeepEqual = function(act, exp, msg) { + new Assertion2(act, msg, assert2.notDeepEqual, true).to.not.eql(exp); + }; + assert2.isAbove = function(val, abv, msg) { + new Assertion2(val, msg, assert2.isAbove, true).to.be.above(abv); + }; + assert2.isAtLeast = function(val, atlst, msg) { + new Assertion2(val, msg, assert2.isAtLeast, true).to.be.least(atlst); + }; + assert2.isBelow = function(val, blw, msg) { + new Assertion2(val, msg, assert2.isBelow, true).to.be.below(blw); + }; + assert2.isAtMost = function(val, atmst, msg) { + new Assertion2(val, msg, assert2.isAtMost, true).to.be.most(atmst); + }; + assert2.isTrue = function(val, msg) { + new Assertion2(val, msg, assert2.isTrue, true).is["true"]; + }; + assert2.isNotTrue = function(val, msg) { + new Assertion2(val, msg, assert2.isNotTrue, true).to.not.equal(true); + }; + assert2.isFalse = function(val, msg) { + new Assertion2(val, msg, assert2.isFalse, true).is["false"]; + }; + assert2.isNotFalse = function(val, msg) { + new Assertion2(val, msg, assert2.isNotFalse, true).to.not.equal(false); + }; + assert2.isNull = function(val, msg) { + new Assertion2(val, msg, assert2.isNull, true).to.equal(null); + }; + assert2.isNotNull = function(val, msg) { + new Assertion2(val, msg, assert2.isNotNull, true).to.not.equal(null); + }; + assert2.isNaN = function(val, msg) { + new Assertion2(val, msg, assert2.isNaN, true).to.be.NaN; + }; + assert2.isNotNaN = function(val, msg) { + new Assertion2(val, msg, assert2.isNotNaN, true).not.to.be.NaN; + }; + assert2.exists = function(val, msg) { + new Assertion2(val, msg, assert2.exists, true).to.exist; + }; + assert2.notExists = function(val, msg) { + new Assertion2(val, msg, assert2.notExists, true).to.not.exist; + }; + assert2.isUndefined = function(val, msg) { + new Assertion2(val, msg, assert2.isUndefined, true).to.equal(void 0); + }; + assert2.isDefined = function(val, msg) { + new Assertion2(val, msg, assert2.isDefined, true).to.not.equal(void 0); + }; + assert2.isFunction = function(val, msg) { + new Assertion2(val, msg, assert2.isFunction, true).to.be.a("function"); + }; + assert2.isNotFunction = function(val, msg) { + new Assertion2(val, msg, assert2.isNotFunction, true).to.not.be.a("function"); + }; + assert2.isObject = function(val, msg) { + new Assertion2(val, msg, assert2.isObject, true).to.be.a("object"); + }; + assert2.isNotObject = function(val, msg) { + new Assertion2(val, msg, assert2.isNotObject, true).to.not.be.a("object"); + }; + assert2.isArray = function(val, msg) { + new Assertion2(val, msg, assert2.isArray, true).to.be.an("array"); + }; + assert2.isNotArray = function(val, msg) { + new Assertion2(val, msg, assert2.isNotArray, true).to.not.be.an("array"); + }; + assert2.isString = function(val, msg) { + new Assertion2(val, msg, assert2.isString, true).to.be.a("string"); + }; + assert2.isNotString = function(val, msg) { + new Assertion2(val, msg, assert2.isNotString, true).to.not.be.a("string"); + }; + assert2.isNumber = function(val, msg) { + new Assertion2(val, msg, assert2.isNumber, true).to.be.a("number"); + }; + assert2.isNotNumber = function(val, msg) { + new Assertion2(val, msg, assert2.isNotNumber, true).to.not.be.a("number"); + }; + assert2.isFinite = function(val, msg) { + new Assertion2(val, msg, assert2.isFinite, true).to.be.finite; + }; + assert2.isBoolean = function(val, msg) { + new Assertion2(val, msg, assert2.isBoolean, true).to.be.a("boolean"); + }; + assert2.isNotBoolean = function(val, msg) { + new Assertion2(val, msg, assert2.isNotBoolean, true).to.not.be.a("boolean"); + }; + assert2.typeOf = function(val, type, msg) { + new Assertion2(val, msg, assert2.typeOf, true).to.be.a(type); + }; + assert2.notTypeOf = function(val, type, msg) { + new Assertion2(val, msg, assert2.notTypeOf, true).to.not.be.a(type); + }; + assert2.instanceOf = function(val, type, msg) { + new Assertion2(val, msg, assert2.instanceOf, true).to.be.instanceOf(type); + }; + assert2.notInstanceOf = function(val, type, msg) { + new Assertion2(val, msg, assert2.notInstanceOf, true).to.not.be.instanceOf(type); + }; + assert2.include = function(exp, inc, msg) { + new Assertion2(exp, msg, assert2.include, true).include(inc); + }; + assert2.notInclude = function(exp, inc, msg) { + new Assertion2(exp, msg, assert2.notInclude, true).not.include(inc); + }; + assert2.deepInclude = function(exp, inc, msg) { + new Assertion2(exp, msg, assert2.deepInclude, true).deep.include(inc); + }; + assert2.notDeepInclude = function(exp, inc, msg) { + new Assertion2(exp, msg, assert2.notDeepInclude, true).not.deep.include(inc); + }; + assert2.nestedInclude = function(exp, inc, msg) { + new Assertion2(exp, msg, assert2.nestedInclude, true).nested.include(inc); + }; + assert2.notNestedInclude = function(exp, inc, msg) { + new Assertion2(exp, msg, assert2.notNestedInclude, true).not.nested.include(inc); + }; + assert2.deepNestedInclude = function(exp, inc, msg) { + new Assertion2(exp, msg, assert2.deepNestedInclude, true).deep.nested.include(inc); + }; + assert2.notDeepNestedInclude = function(exp, inc, msg) { + new Assertion2(exp, msg, assert2.notDeepNestedInclude, true).not.deep.nested.include(inc); + }; + assert2.ownInclude = function(exp, inc, msg) { + new Assertion2(exp, msg, assert2.ownInclude, true).own.include(inc); + }; + assert2.notOwnInclude = function(exp, inc, msg) { + new Assertion2(exp, msg, assert2.notOwnInclude, true).not.own.include(inc); + }; + assert2.deepOwnInclude = function(exp, inc, msg) { + new Assertion2(exp, msg, assert2.deepOwnInclude, true).deep.own.include(inc); + }; + assert2.notDeepOwnInclude = function(exp, inc, msg) { + new Assertion2(exp, msg, assert2.notDeepOwnInclude, true).not.deep.own.include(inc); + }; + assert2.match = function(exp, re, msg) { + new Assertion2(exp, msg, assert2.match, true).to.match(re); + }; + assert2.notMatch = function(exp, re, msg) { + new Assertion2(exp, msg, assert2.notMatch, true).to.not.match(re); + }; + assert2.property = function(obj, prop, msg) { + new Assertion2(obj, msg, assert2.property, true).to.have.property(prop); + }; + assert2.notProperty = function(obj, prop, msg) { + new Assertion2(obj, msg, assert2.notProperty, true).to.not.have.property(prop); + }; + assert2.propertyVal = function(obj, prop, val, msg) { + new Assertion2(obj, msg, assert2.propertyVal, true).to.have.property(prop, val); + }; + assert2.notPropertyVal = function(obj, prop, val, msg) { + new Assertion2(obj, msg, assert2.notPropertyVal, true).to.not.have.property(prop, val); + }; + assert2.deepPropertyVal = function(obj, prop, val, msg) { + new Assertion2(obj, msg, assert2.deepPropertyVal, true).to.have.deep.property(prop, val); + }; + assert2.notDeepPropertyVal = function(obj, prop, val, msg) { + new Assertion2(obj, msg, assert2.notDeepPropertyVal, true).to.not.have.deep.property(prop, val); + }; + assert2.ownProperty = function(obj, prop, msg) { + new Assertion2(obj, msg, assert2.ownProperty, true).to.have.own.property(prop); + }; + assert2.notOwnProperty = function(obj, prop, msg) { + new Assertion2(obj, msg, assert2.notOwnProperty, true).to.not.have.own.property(prop); + }; + assert2.ownPropertyVal = function(obj, prop, value, msg) { + new Assertion2(obj, msg, assert2.ownPropertyVal, true).to.have.own.property(prop, value); + }; + assert2.notOwnPropertyVal = function(obj, prop, value, msg) { + new Assertion2(obj, msg, assert2.notOwnPropertyVal, true).to.not.have.own.property(prop, value); + }; + assert2.deepOwnPropertyVal = function(obj, prop, value, msg) { + new Assertion2(obj, msg, assert2.deepOwnPropertyVal, true).to.have.deep.own.property(prop, value); + }; + assert2.notDeepOwnPropertyVal = function(obj, prop, value, msg) { + new Assertion2(obj, msg, assert2.notDeepOwnPropertyVal, true).to.not.have.deep.own.property(prop, value); + }; + assert2.nestedProperty = function(obj, prop, msg) { + new Assertion2(obj, msg, assert2.nestedProperty, true).to.have.nested.property(prop); + }; + assert2.notNestedProperty = function(obj, prop, msg) { + new Assertion2(obj, msg, assert2.notNestedProperty, true).to.not.have.nested.property(prop); + }; + assert2.nestedPropertyVal = function(obj, prop, val, msg) { + new Assertion2(obj, msg, assert2.nestedPropertyVal, true).to.have.nested.property(prop, val); + }; + assert2.notNestedPropertyVal = function(obj, prop, val, msg) { + new Assertion2(obj, msg, assert2.notNestedPropertyVal, true).to.not.have.nested.property(prop, val); + }; + assert2.deepNestedPropertyVal = function(obj, prop, val, msg) { + new Assertion2(obj, msg, assert2.deepNestedPropertyVal, true).to.have.deep.nested.property(prop, val); + }; + assert2.notDeepNestedPropertyVal = function(obj, prop, val, msg) { + new Assertion2(obj, msg, assert2.notDeepNestedPropertyVal, true).to.not.have.deep.nested.property(prop, val); + }; + assert2.lengthOf = function(exp, len, msg) { + new Assertion2(exp, msg, assert2.lengthOf, true).to.have.lengthOf(len); + }; + assert2.hasAnyKeys = function(obj, keys, msg) { + new Assertion2(obj, msg, assert2.hasAnyKeys, true).to.have.any.keys(keys); + }; + assert2.hasAllKeys = function(obj, keys, msg) { + new Assertion2(obj, msg, assert2.hasAllKeys, true).to.have.all.keys(keys); + }; + assert2.containsAllKeys = function(obj, keys, msg) { + new Assertion2(obj, msg, assert2.containsAllKeys, true).to.contain.all.keys(keys); + }; + assert2.doesNotHaveAnyKeys = function(obj, keys, msg) { + new Assertion2(obj, msg, assert2.doesNotHaveAnyKeys, true).to.not.have.any.keys(keys); + }; + assert2.doesNotHaveAllKeys = function(obj, keys, msg) { + new Assertion2(obj, msg, assert2.doesNotHaveAllKeys, true).to.not.have.all.keys(keys); + }; + assert2.hasAnyDeepKeys = function(obj, keys, msg) { + new Assertion2(obj, msg, assert2.hasAnyDeepKeys, true).to.have.any.deep.keys(keys); + }; + assert2.hasAllDeepKeys = function(obj, keys, msg) { + new Assertion2(obj, msg, assert2.hasAllDeepKeys, true).to.have.all.deep.keys(keys); + }; + assert2.containsAllDeepKeys = function(obj, keys, msg) { + new Assertion2(obj, msg, assert2.containsAllDeepKeys, true).to.contain.all.deep.keys(keys); + }; + assert2.doesNotHaveAnyDeepKeys = function(obj, keys, msg) { + new Assertion2(obj, msg, assert2.doesNotHaveAnyDeepKeys, true).to.not.have.any.deep.keys(keys); + }; + assert2.doesNotHaveAllDeepKeys = function(obj, keys, msg) { + new Assertion2(obj, msg, assert2.doesNotHaveAllDeepKeys, true).to.not.have.all.deep.keys(keys); + }; + assert2.throws = function(fn, errorLike, errMsgMatcher, msg) { + if ("string" === typeof errorLike || errorLike instanceof RegExp) { + errMsgMatcher = errorLike; + errorLike = null; + } + var assertErr = new Assertion2(fn, msg, assert2.throws, true).to.throw(errorLike, errMsgMatcher); + return flag(assertErr, "object"); + }; + assert2.doesNotThrow = function(fn, errorLike, errMsgMatcher, msg) { + if ("string" === typeof errorLike || errorLike instanceof RegExp) { + errMsgMatcher = errorLike; + errorLike = null; + } + new Assertion2(fn, msg, assert2.doesNotThrow, true).to.not.throw(errorLike, errMsgMatcher); + }; + assert2.operator = function(val, operator, val2, msg) { + var ok; + switch (operator) { + case "==": + ok = val == val2; + break; + case "===": + ok = val === val2; + break; + case ">": + ok = val > val2; + break; + case ">=": + ok = val >= val2; + break; + case "<": + ok = val < val2; + break; + case "<=": + ok = val <= val2; + break; + case "!=": + ok = val != val2; + break; + case "!==": + ok = val !== val2; + break; + default: + msg = msg ? msg + ": " : msg; + throw new chai2.AssertionError( + msg + 'Invalid operator "' + operator + '"', + void 0, + assert2.operator + ); + } + var test = new Assertion2(ok, msg, assert2.operator, true); + test.assert( + true === flag(test, "object"), + "expected " + util2.inspect(val) + " to be " + operator + " " + util2.inspect(val2), + "expected " + util2.inspect(val) + " to not be " + operator + " " + util2.inspect(val2) + ); + }; + assert2.closeTo = function(act, exp, delta, msg) { + new Assertion2(act, msg, assert2.closeTo, true).to.be.closeTo(exp, delta); + }; + assert2.approximately = function(act, exp, delta, msg) { + new Assertion2(act, msg, assert2.approximately, true).to.be.approximately(exp, delta); + }; + assert2.sameMembers = function(set1, set2, msg) { + new Assertion2(set1, msg, assert2.sameMembers, true).to.have.same.members(set2); + }; + assert2.notSameMembers = function(set1, set2, msg) { + new Assertion2(set1, msg, assert2.notSameMembers, true).to.not.have.same.members(set2); + }; + assert2.sameDeepMembers = function(set1, set2, msg) { + new Assertion2(set1, msg, assert2.sameDeepMembers, true).to.have.same.deep.members(set2); + }; + assert2.notSameDeepMembers = function(set1, set2, msg) { + new Assertion2(set1, msg, assert2.notSameDeepMembers, true).to.not.have.same.deep.members(set2); + }; + assert2.sameOrderedMembers = function(set1, set2, msg) { + new Assertion2(set1, msg, assert2.sameOrderedMembers, true).to.have.same.ordered.members(set2); + }; + assert2.notSameOrderedMembers = function(set1, set2, msg) { + new Assertion2(set1, msg, assert2.notSameOrderedMembers, true).to.not.have.same.ordered.members(set2); + }; + assert2.sameDeepOrderedMembers = function(set1, set2, msg) { + new Assertion2(set1, msg, assert2.sameDeepOrderedMembers, true).to.have.same.deep.ordered.members(set2); + }; + assert2.notSameDeepOrderedMembers = function(set1, set2, msg) { + new Assertion2(set1, msg, assert2.notSameDeepOrderedMembers, true).to.not.have.same.deep.ordered.members(set2); + }; + assert2.includeMembers = function(superset, subset, msg) { + new Assertion2(superset, msg, assert2.includeMembers, true).to.include.members(subset); + }; + assert2.notIncludeMembers = function(superset, subset, msg) { + new Assertion2(superset, msg, assert2.notIncludeMembers, true).to.not.include.members(subset); + }; + assert2.includeDeepMembers = function(superset, subset, msg) { + new Assertion2(superset, msg, assert2.includeDeepMembers, true).to.include.deep.members(subset); + }; + assert2.notIncludeDeepMembers = function(superset, subset, msg) { + new Assertion2(superset, msg, assert2.notIncludeDeepMembers, true).to.not.include.deep.members(subset); + }; + assert2.includeOrderedMembers = function(superset, subset, msg) { + new Assertion2(superset, msg, assert2.includeOrderedMembers, true).to.include.ordered.members(subset); + }; + assert2.notIncludeOrderedMembers = function(superset, subset, msg) { + new Assertion2(superset, msg, assert2.notIncludeOrderedMembers, true).to.not.include.ordered.members(subset); + }; + assert2.includeDeepOrderedMembers = function(superset, subset, msg) { + new Assertion2(superset, msg, assert2.includeDeepOrderedMembers, true).to.include.deep.ordered.members(subset); + }; + assert2.notIncludeDeepOrderedMembers = function(superset, subset, msg) { + new Assertion2(superset, msg, assert2.notIncludeDeepOrderedMembers, true).to.not.include.deep.ordered.members(subset); + }; + assert2.oneOf = function(inList, list, msg) { + new Assertion2(inList, msg, assert2.oneOf, true).to.be.oneOf(list); + }; + assert2.changes = function(fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === "function") { + msg = prop; + prop = null; + } + new Assertion2(fn, msg, assert2.changes, true).to.change(obj, prop); + }; + assert2.changesBy = function(fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === "function") { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + new Assertion2(fn, msg, assert2.changesBy, true).to.change(obj, prop).by(delta); + }; + assert2.doesNotChange = function(fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === "function") { + msg = prop; + prop = null; + } + return new Assertion2(fn, msg, assert2.doesNotChange, true).to.not.change(obj, prop); + }; + assert2.changesButNotBy = function(fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === "function") { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + new Assertion2(fn, msg, assert2.changesButNotBy, true).to.change(obj, prop).but.not.by(delta); + }; + assert2.increases = function(fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === "function") { + msg = prop; + prop = null; + } + return new Assertion2(fn, msg, assert2.increases, true).to.increase(obj, prop); + }; + assert2.increasesBy = function(fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === "function") { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + new Assertion2(fn, msg, assert2.increasesBy, true).to.increase(obj, prop).by(delta); + }; + assert2.doesNotIncrease = function(fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === "function") { + msg = prop; + prop = null; + } + return new Assertion2(fn, msg, assert2.doesNotIncrease, true).to.not.increase(obj, prop); + }; + assert2.increasesButNotBy = function(fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === "function") { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + new Assertion2(fn, msg, assert2.increasesButNotBy, true).to.increase(obj, prop).but.not.by(delta); + }; + assert2.decreases = function(fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === "function") { + msg = prop; + prop = null; + } + return new Assertion2(fn, msg, assert2.decreases, true).to.decrease(obj, prop); + }; + assert2.decreasesBy = function(fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === "function") { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + new Assertion2(fn, msg, assert2.decreasesBy, true).to.decrease(obj, prop).by(delta); + }; + assert2.doesNotDecrease = function(fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === "function") { + msg = prop; + prop = null; + } + return new Assertion2(fn, msg, assert2.doesNotDecrease, true).to.not.decrease(obj, prop); + }; + assert2.doesNotDecreaseBy = function(fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === "function") { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + return new Assertion2(fn, msg, assert2.doesNotDecreaseBy, true).to.not.decrease(obj, prop).by(delta); + }; + assert2.decreasesButNotBy = function(fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === "function") { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + new Assertion2(fn, msg, assert2.decreasesButNotBy, true).to.decrease(obj, prop).but.not.by(delta); + }; + assert2.ifError = function(val) { + if (val) { + throw val; + } + }; + assert2.isExtensible = function(obj, msg) { + new Assertion2(obj, msg, assert2.isExtensible, true).to.be.extensible; + }; + assert2.isNotExtensible = function(obj, msg) { + new Assertion2(obj, msg, assert2.isNotExtensible, true).to.not.be.extensible; + }; + assert2.isSealed = function(obj, msg) { + new Assertion2(obj, msg, assert2.isSealed, true).to.be.sealed; + }; + assert2.isNotSealed = function(obj, msg) { + new Assertion2(obj, msg, assert2.isNotSealed, true).to.not.be.sealed; + }; + assert2.isFrozen = function(obj, msg) { + new Assertion2(obj, msg, assert2.isFrozen, true).to.be.frozen; + }; + assert2.isNotFrozen = function(obj, msg) { + new Assertion2(obj, msg, assert2.isNotFrozen, true).to.not.be.frozen; + }; + assert2.isEmpty = function(val, msg) { + new Assertion2(val, msg, assert2.isEmpty, true).to.be.empty; + }; + assert2.isNotEmpty = function(val, msg) { + new Assertion2(val, msg, assert2.isNotEmpty, true).to.not.be.empty; + }; + (function alias(name, as) { + assert2[as] = assert2[name]; + return alias; + })("isOk", "ok")("isNotOk", "notOk")("throws", "throw")("throws", "Throw")("isExtensible", "extensible")("isNotExtensible", "notExtensible")("isSealed", "sealed")("isNotSealed", "notSealed")("isFrozen", "frozen")("isNotFrozen", "notFrozen")("isEmpty", "empty")("isNotEmpty", "notEmpty"); + }; + } + }); + + // node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai.js + var require_chai = __commonJS({ + "node_modules/.pnpm/chai@4.3.7/node_modules/chai/lib/chai.js"(exports) { + var used = []; + exports.version = "4.3.3"; + exports.AssertionError = require_assertion_error(); + var util2 = require_utils(); + exports.use = function(fn) { + if (!~used.indexOf(fn)) { + fn(exports, util2); + used.push(fn); + } + return exports; + }; + exports.util = util2; + var config2 = require_config(); + exports.config = config2; + var assertion = require_assertion(); + exports.use(assertion); + var core2 = require_assertions(); + exports.use(core2); + var expect10 = require_expect(); + exports.use(expect10); + var should2 = require_should(); + exports.use(should2); + var assert2 = require_assert(); + exports.use(assert2); + } + }); + + // node_modules/.pnpm/chai@4.3.7/node_modules/chai/index.js + var require_chai2 = __commonJS({ + "node_modules/.pnpm/chai@4.3.7/node_modules/chai/index.js"(exports, module) { + module.exports = require_chai(); + } + }); + + // source/constants.mjs + var internalSymbol, internalStateSymbol, instanceSymbol; + var init_constants = __esm({ + "source/constants.mjs"() { + internalSymbol = Symbol.for("@schukai/monster/internal"); + internalStateSymbol = Symbol.for("@schukai/monster/state"); + instanceSymbol = Symbol.for("@schukai/monster/instance"); + } + }); + + // source/types/is.mjs + function isIterable(value) { + if (value === void 0) + return false; + if (value === null) + return false; + return typeof value?.[Symbol.iterator] === "function"; + } + function isPrimitive(value) { + var type; + if (value === void 0 || value === null) { + return true; + } + type = typeof value; + if (type === "string" || type === "number" || type === "boolean" || type === "symbol") { + return true; + } + return false; + } + function isSymbol(value) { + return "symbol" === typeof value ? true : false; + } + function isBoolean(value) { + if (value === true || value === false) { + return true; + } + return false; + } + function isString(value) { + if (value === void 0 || typeof value !== "string") { + return false; + } + return true; + } + function isObject(value) { + if (isArray(value)) + return false; + if (isPrimitive(value)) + return false; + if (typeof value === "object") { + return true; + } + return false; + } + function isInstance(value, instance) { + if (!isObject(value)) + return false; + if (!isFunction(instance)) + return false; + if (!instance.hasOwnProperty("prototype")) + return false; + return value instanceof instance ? true : false; + } + function isArray(value) { + return Array.isArray(value); + } + function isFunction(value) { + if (isArray(value)) + return false; + if (isPrimitive(value)) + return false; + if (typeof value === "function") { + return true; + } + return false; + } + function isInteger(value) { + return Number.isInteger(value); + } + var init_is = __esm({ + "source/types/is.mjs"() { + } + }); + + // source/types/typeof.mjs + function typeOf(value) { + let type = {}.toString.call(value).match(/\s([a-zA-Z]+)/)[1]; + if ("Object" === type) { + const name = value.constructor.name; + if (name) { + return name.toLowerCase(); + } + const results = /^(class|function)\s+(\w+)/.exec(value.constructor.toString()); + type = results && results.length > 2 ? results[2] : ""; + } + return type.toLowerCase(); + } + var init_typeof = __esm({ + "source/types/typeof.mjs"() { + } + }); + + // source/data/extend.mjs + function extend(...args) { + let o; + let i; + if (typeof args !== "object" || args[0] === null) { + throw new Error(`unsupported argument ${JSON.stringify(args[0])}`); + } + for (i = 0; i < args.length; i++) { + let a2 = args[i]; + if (!(isObject(a2) || isArray(a2))) { + throw new Error(`unsupported argument ${JSON.stringify(a2)}`); + } + if (o === void 0) { + o = a2; + continue; + } + for (let k in a2) { + let v = a2?.[k]; + if (v === o?.[k]) { + continue; + } + if (isObject(v) && typeOf(v) === "object" || isArray(v)) { + if (o[k] === void 0) { + if (isArray(v)) { + o[k] = []; + } else { + o[k] = {}; + } + } else { + if (typeOf(o[k]) !== typeOf(v)) { + throw new Error( + `type mismatch: ${JSON.stringify(o[k])}(${typeOf(o[k])}) != ${JSON.stringify(v)}(${typeOf( + v + )})` + ); + } + } + o[k] = extend(o[k], v); + } else { + o[k] = v; + } + } + } + return o; + } + var init_extend = __esm({ + "source/data/extend.mjs"() { + init_is(); + init_typeof(); + } + }); + + // source/types/base.mjs + function checkInstanceSymbol(obj) { + if (this.hasOwnProperty(instanceSymbol) === false) { + return false; + } + const proto = obj?.constructor; + if (proto === void 0 || proto === null || typeof proto !== "object" && typeof proto !== "function") { + return false; + } + if (proto.hasOwnProperty(instanceSymbol) !== true) { + return checkInstanceSymbol.apply(this, [obj.__proto__]); + } + const symbol2 = proto[instanceSymbol]; + if (symbol2 === void 0) { + if (obj.__proto__) { + return checkInstanceSymbol(obj.__proto__); + } else { + return false; + } + } + if (symbol2 === this[instanceSymbol]) { + return true; + } + return checkInstanceSymbol.apply(this, [obj.__proto__]); + } + var Base; + var init_base = __esm({ + "source/types/base.mjs"() { + init_constants(); + Base = class extends Object { + /** + * + * @returns {string} + */ + toString() { + return JSON.stringify(this); + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/types/base"); + } + /** + * This method is called by the `instanceof` operator. + * @param that + * @returns {boolean} + * @since 2.1.0 + */ + static [Symbol.hasInstance](that) { + if (that === void 0 || that === null || typeof that !== "object" && typeof that !== "function") { + return false; + } + const thatClass = Object.getPrototypeOf(that); + if (thatClass === void 0 || thatClass === null || typeof thatClass !== "object" && typeof thatClass !== "function") { + return false; + } + if (checkInstanceSymbol.apply(this, [thatClass]) === true) { + return true; + } + return super[Symbol.hasInstance](that); + } + }; + } + }); + + // source/types/validate.mjs + function validateIterable(value) { + if (!isIterable(value)) { + throw new TypeError("value is not iterable"); + } + return value; + } + function validatePrimitive(value) { + if (!isPrimitive(value)) { + throw new TypeError("value is not a primitive"); + } + return value; + } + function validateBoolean(value) { + if (!isBoolean(value)) { + throw new TypeError("value is not a boolean"); + } + return value; + } + function validateString(value) { + if (!isString(value)) { + throw new TypeError("value is not a string"); + } + return value; + } + function validateObject(value) { + if (!isObject(value)) { + throw new TypeError("value is not a object"); + } + return value; + } + function validateInstance(value, instance) { + if (!isInstance(value, instance)) { + let n = ""; + if (isObject(instance) || isFunction(instance)) { + n = instance?.["name"]; + } + if (n) { + n = ` ${n}`; + } + throw new TypeError(`value is not an instance of${n}`); + } + return value; + } + function validateArray(value) { + if (!isArray(value)) { + throw new TypeError("value is not an array"); + } + return value; + } + function validateSymbol(value) { + if (!isSymbol(value)) { + throw new TypeError("value is not an symbol"); + } + return value; + } + function validateFunction(value) { + if (!isFunction(value)) { + throw new TypeError("value is not a function"); + } + return value; + } + function validateInteger(value) { + if (!isInteger(value)) { + throw new TypeError("value is not an integer"); + } + return value; + } + var init_validate = __esm({ + "source/types/validate.mjs"() { + init_is(); + } + }); + + // source/types/global.mjs + function getGlobal() { + return globalReference; + } + function getGlobalObject(name) { + validateString(name); + let o = globalReference?.[name]; + if (typeof o === "undefined") + throw new Error(`the object ${name} is not defined`); + validateObject(o); + return o; + } + function getGlobalFunction(name) { + validateString(name); + let f = globalReference?.[name]; + if (typeof f === "undefined") + throw new Error(`the function ${name} is not defined`); + validateFunction(f); + return f; + } + var globalReference; + var init_global = __esm({ + "source/types/global.mjs"() { + init_validate(); + (function() { + if (typeof globalThis === "object") { + globalReference = globalThis; + return; + } + if (typeof self !== "undefined") { + globalReference = self; + return; + } else if (typeof window !== "undefined") { + globalReference = window; + return; + } + Object.defineProperty(Object.prototype, "__monster__", { + get: function() { + return this; + }, + configurable: true + }); + if (typeof __monster__ === "object") { + __monster__.globalThis = __monster__; + delete Object.prototype.__monster__; + globalReference = globalThis; + return; + } + try { + globalReference = Function("return this")(); + } catch (e) { + } + throw new Error("unsupported environment."); + })(); + } + }); + + // source/util/clone.mjs + function clone(obj) { + if (null === obj) { + return obj; + } + if (isPrimitive(obj)) { + return obj; + } + if (isFunction(obj)) { + return obj; + } + if (isArray(obj)) { + let copy = []; + for (var i = 0, len = obj.length; i < len; i++) { + copy[i] = clone(obj[i]); + } + return copy; + } + if (isObject(obj)) { + if (obj instanceof Date) { + let copy = /* @__PURE__ */ new Date(); + copy.setTime(obj.getTime()); + return copy; + } + if (typeof Element !== "undefined" && obj instanceof Element) + return obj; + if (typeof HTMLDocument !== "undefined" && obj instanceof HTMLDocument) + return obj; + if (typeof DocumentFragment !== "undefined" && obj instanceof DocumentFragment) + return obj; + if (obj === getGlobal()) + return obj; + if (typeof globalContext !== "undefined" && obj === globalContext) + return obj; + if (typeof window !== "undefined" && obj === window) + return obj; + if (typeof document !== "undefined" && obj === document) + return obj; + if (typeof navigator !== "undefined" && obj === navigator) + return obj; + if (typeof JSON !== "undefined" && obj === JSON) + return obj; + try { + if (obj instanceof Proxy) { + return obj; + } + } catch (e) { + } + return cloneObject(obj); + } + throw new Error("unable to clone obj! its type isn't supported."); + } + function cloneObject(obj) { + validateObject(obj); + const fkt = obj?.["constructor"]; + if (typeOf(fkt) === "function") { + const prototype = fkt?.prototype; + if (typeof prototype === "object") { + if (prototype.hasOwnProperty("getClone") && typeOf(obj.getClone) === "function") { + return obj.getClone(); + } + } + } + let copy = {}; + if (typeof obj.constructor === "function" && typeof obj.constructor.call === "function") { + copy = new obj.constructor(); + } + for (let key in obj) { + if (!obj.hasOwnProperty(key)) { + continue; + } + if (isPrimitive(obj[key])) { + copy[key] = obj[key]; + continue; + } + copy[key] = clone(obj[key]); + } + return copy; + } + var init_clone = __esm({ + "source/util/clone.mjs"() { + init_global(); + init_is(); + init_typeof(); + init_validate(); + } + }); + + // source/i18n/locale.mjs + function parseLocale(locale) { + locale = validateString(locale).replace(/_/g, "-"); + let language; + let region; + let variants; + let parts; + let script; + let extlang; + let regexRegular = "(art-lojban|cel-gaulish|no-bok|no-nyn|zh-guoyu|zh-hakka|zh-min|zh-min-nan|zh-xiang)"; + let regexIrregular = "(en-GB-oed|i-ami|i-bnn|i-default|i-enochian|i-hak|i-klingon|i-lux|i-mingo|i-navajo|i-pwn|i-tao|i-tay|i-tsu|sgn-BE-FR|sgn-BE-NL|sgn-CH-DE)"; + let regexGrandfathered = `(${regexIrregular}|${regexRegular})`; + let regexPrivateUse = "(x(-[A-Za-z0-9]{1,8})+)"; + let regexSingleton = "[0-9A-WY-Za-wy-z]"; + let regexExtension = `(${regexSingleton}(-[A-Za-z0-9]{2,8})+)`; + let regexVariant = "([A-Za-z0-9]{5,8}|[0-9][A-Za-z0-9]{3})"; + let regexRegion = "([A-Za-z]{2}|[0-9]{3})"; + let regexScript = "([A-Za-z]{4})"; + let regexExtlang = "([A-Za-z]{3}(-[A-Za-z]{3}){0,2})"; + let regexLanguage = `(([A-Za-z]{2,3}(-${regexExtlang})?)|[A-Za-z]{4}|[A-Za-z]{5,8})`; + let regexLangtag = `(${regexLanguage}(-${regexScript})?(-${regexRegion})?(-${regexVariant})*(-${regexExtension})*(-${regexPrivateUse})?)`; + let regexLanguageTag = `^(${regexGrandfathered}|${regexLangtag}|${regexPrivateUse})$`; + let regex = new RegExp(regexLanguageTag); + let match; + if ((match = regex.exec(locale)) !== null) { + if (match.index === regex.lastIndex) { + regex.lastIndex++; + } + } + if (match === void 0 || match === null) { + throw new Error("unsupported locale"); + } + if (match[6] !== void 0) { + language = match[6]; + parts = language.split("-"); + if (parts.length > 1) { + language = parts[0]; + extlang = parts[1]; + } + } + if (match[14] !== void 0) { + region = match[14]; + } + if (match[12] !== void 0) { + script = match[12]; + } + if (match[16] !== void 0) { + variants = match[16]; + } + return new Locale(language, region, script, variants, extlang); + } + var propertiesSymbol, localeStringSymbol, Locale; + var init_locale = __esm({ + "source/i18n/locale.mjs"() { + init_constants(); + init_base(); + init_validate(); + init_clone(); + propertiesSymbol = Symbol("properties"); + localeStringSymbol = Symbol("localeString"); + Locale = class extends Base { + /** + * @param {string} language + * @param {string} [region] + * @param {string} [script] + * @param {string} [variants] + * @param {string} [extlang] + * @param {string} [privateUse] + * @throws {Error} unsupported locale + */ + constructor(language, region, script, variants, extlang, privateUse) { + super(); + this[propertiesSymbol] = { + language: language === void 0 ? void 0 : validateString(language), + script: script === void 0 ? void 0 : validateString(script), + region: region === void 0 ? void 0 : validateString(region), + variants: variants === void 0 ? void 0 : validateString(variants), + extlang: extlang === void 0 ? void 0 : validateString(extlang), + privateUse: privateUse === void 0 ? void 0 : validateString(privateUse) + }; + let s = []; + if (language !== void 0) + s.push(language); + if (script !== void 0) + s.push(script); + if (region !== void 0) + s.push(region); + if (variants !== void 0) + s.push(variants); + if (extlang !== void 0) + s.push(extlang); + if (privateUse !== void 0) + s.push(privateUse); + if (s.length === 0) { + throw new Error("unsupported locale"); + } + this[localeStringSymbol] = s.join("-"); + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 3.27.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/i18n/locale@@instance"); + } + /** + * @return {string} + */ + get localeString() { + return this[localeStringSymbol]; + } + /** + * @return {string|undefined} + */ + get language() { + return this[propertiesSymbol].language; + } + /** + * @return {string|undefined} + */ + get region() { + return this[propertiesSymbol].region; + } + /** + * @return {string|undefined} + */ + get script() { + return this[propertiesSymbol].script; + } + /** + * @return {string|undefined} + */ + get variants() { + return this[propertiesSymbol].variants; + } + /** + * @return {string|undefined} + */ + get extlang() { + return this[propertiesSymbol].extlang; + } + /** + * @return {string|undefined} + */ + get privateUse() { + return this[propertiesSymbol].privateValue; + } + /** + * @return {string} + */ + toString() { + return `${this.localeString}`; + } + /** + * The structure has the following: language, script, region, variants, extlang, privateUse + * + * @return {Monster.I18n.LocaleMap} + */ + getMap() { + return clone(this[propertiesSymbol]); + } + }; + } + }); + + // source/dom/util.mjs + function getDocument() { + let document2 = getGlobal()?.["document"]; + if (typeof document2 !== "object") { + throw new Error("not supported environment"); + } + return document2; + } + function getWindow() { + let window2 = getGlobal()?.["window"]; + if (typeof window2 !== "object") { + throw new Error("not supported environment"); + } + return window2; + } + function getDocumentFragmentFromString(html) { + validateString(html); + const document2 = getDocument(); + const template = document2.createElement("template"); + template.innerHTML = html; + return template.content; + } + function findElementWithIdUpwards(element, targetId) { + if (!element) { + return null; + } + if (element.id === targetId) { + return element; + } + if (element.shadowRoot) { + const target = element.shadowRoot.getElementById(targetId); + if (target) { + return target; + } + } + if (element === document.documentElement) { + const target = document.getElementById(targetId); + if (target) { + return target; + } + } + const rootNode = element.getRootNode(); + if (rootNode && rootNode instanceof ShadowRoot) { + return findElementWithIdUpwards(rootNode.host, targetId); + } + return findElementWithIdUpwards(element.parentElement, targetId); + } + function traverseShadowRoots(element) { + let currentRoot = element.shadowRoot; + let currentParent = element.parentNode; + while (currentParent && currentParent.nodeType !== Node.DOCUMENT_NODE && currentParent.nodeType !== Node.DOCUMENT_FRAGMENT_NODE) { + if (currentRoot && currentRoot.parentNode) { + currentParent = currentRoot.parentNode; + currentRoot = currentParent.shadowRoot; + } else if (currentParent.parentNode) { + currentParent = currentParent.parentNode; + currentRoot = null; + } else if (currentRoot && currentRoot.host && currentRoot.host.nodeType === Node.DOCUMENT_NODE) { + currentParent = currentRoot.host; + currentRoot = null; + } else { + currentParent = null; + currentRoot = null; + } + } + return currentParent; + } + function getContainingDocument(element) { + if (!element || !(element instanceof HTMLElement || element instanceof element.ownerDocument.defaultView.HTMLElement)) { + throw new Error("Invalid argument. Expected an HTMLElement."); + } + return traverseShadowRoots(element) || null; + } + var init_util = __esm({ + "source/dom/util.mjs"() { + init_global(); + init_validate(); + } + }); + + // source/dom/locale.mjs + function getLocaleOfDocument() { + const document2 = getDocument(); + let html = document2.querySelector("html"); + if (html instanceof HTMLElement && html.hasAttribute("lang")) { + let locale = html.getAttribute("lang"); + if (locale) { + return new parseLocale(locale); + } + } + let navigatorLanguage = getNavigatorLanguage(); + if (navigatorLanguage) { + return parseLocale(navigatorLanguage); + } + return parseLocale(DEFAULT_LANGUAGE); + } + var DEFAULT_LANGUAGE, getNavigatorLanguage; + var init_locale2 = __esm({ + "source/dom/locale.mjs"() { + init_locale(); + init_util(); + init_global(); + DEFAULT_LANGUAGE = "en"; + getNavigatorLanguage = () => { + const navigator2 = getGlobalObject("navigator"); + if (navigator2 === void 0) { + return void 0; + } + if (navigator2.hasOwnProperty("language")) { + const language = navigator2.language; + if (typeof language === "string" && language.length > 0) { + return language; + } + } + const languages = navigator2?.languages; + if (Array.isArray(languages) && languages.length > 0) { + return languages[0]; + } + return void 0; + }; + } + }); + + // source/types/id.mjs + var internalCounter, ID; + var init_id = __esm({ + "source/types/id.mjs"() { + init_base(); + init_validate(); + internalCounter = /* @__PURE__ */ new Map(); + ID = class extends Base { + /** + * create new id with prefix + * + * @param {string} prefix + */ + constructor(prefix) { + super(); + if (prefix === void 0) { + prefix = "id"; + } + validateString(prefix); + if (!internalCounter.has(prefix)) { + internalCounter.set(prefix, 1); + } + let count = internalCounter.get(prefix); + this.id = prefix + count; + internalCounter.set(prefix, ++count); + } + /** + * @return {string} + */ + toString() { + return this.id; + } + }; + } + }); + + // source/types/tokenlist.mjs + function toggleValue(token) { + if (!(this instanceof TokenList)) + throw Error("must be called with TokenList.call"); + validateString(token); + token = token.trim(); + if (this.contains(token)) { + this.remove(token); + return this; + } + this.add(token); + return this; + } + var TokenList; + var init_tokenlist = __esm({ + "source/types/tokenlist.mjs"() { + init_is(); + init_validate(); + init_base(); + TokenList = class extends Base { + /** + * + * @param {array|string|iteratable} init + */ + constructor(init3) { + super(); + this.tokens = /* @__PURE__ */ new Set(); + if (typeof init3 !== "undefined") { + this.add(init3); + } + } + /** + * Iterator protocol + * + * @returns {Symbol.iterator} + */ + getIterator() { + return this[Symbol.iterator](); + } + /** + * Iterator + * + * @returns {{next: ((function(): ({value: *, done: boolean}))|*)}} + */ + [Symbol.iterator]() { + let index = 0; + let entries = this.entries(); + return { + next: () => { + if (index < entries.length) { + return { value: entries?.[index++], done: false }; + } else { + return { done: true }; + } + } + }; + } + /** + * Returns true if it contains token, otherwise false + * + * @externalExample ../../example/types/tokenlist-2.mjs + * @param {array|string|iteratable} value + * @returns {boolean} + */ + contains(value) { + if (isString(value)) { + value = value.trim(); + let counter = 0; + value.split(" ").forEach((token) => { + if (this.tokens.has(token.trim()) === false) + return false; + counter++; + }); + return counter > 0 ? true : false; + } + if (isIterable(value)) { + let counter = 0; + for (let token of value) { + validateString(token); + if (this.tokens.has(token.trim()) === false) + return false; + counter++; + } + return counter > 0 ? true : false; + } + return false; + } + /** + * Add tokens + * + * @externalExample ../../example/types/tokenlist-3.mjs + * @param {array|string|iteratable} value + * @returns {TokenList} + * @throws {TypeError} unsupported value + */ + add(value) { + if (isString(value)) { + value.split(" ").forEach((token) => { + this.tokens.add(token.trim()); + }); + } else if (isIterable(value)) { + for (let token of value) { + validateString(token); + this.tokens.add(token.trim()); + } + } else if (typeof value !== "undefined") { + throw new TypeError("unsupported value"); + } + return this; + } + /** + * remove all tokens + * + * @returns {TokenList} + */ + clear() { + this.tokens.clear(); + return this; + } + /** + * Removes token + * + * @externalExample ../../example/types/tokenlist-4.mjs + * @param {array|string|iteratable} value + * @returns {TokenList} + * @throws {TypeError} unsupported value + */ + remove(value) { + if (isString(value)) { + value.split(" ").forEach((token) => { + this.tokens.delete(token.trim()); + }); + } else if (isIterable(value)) { + for (let token of value) { + validateString(token); + this.tokens.delete(token.trim()); + } + } else if (typeof value !== "undefined") { + throw new TypeError("unsupported value", "types/tokenlist.mjs"); + } + return this; + } + /** + * this method replaces a token with a new token. + * + * if the passed token exists, it is replaced with newToken and TokenList is returned. + * if the token does not exist, newToken is not set and TokenList is returned. + * + * @param {string} token + * @param {string} newToken + * @returns {TokenList} + */ + replace(token, newToken) { + validateString(token); + validateString(newToken); + if (!this.contains(token)) { + return this; + } + let a2 = Array.from(this.tokens); + let i = a2.indexOf(token); + if (i === -1) + return this; + a2.splice(i, 1, newToken); + this.tokens = /* @__PURE__ */ new Set(); + this.add(a2); + return this; + } + /** + * Removes token from string. If token doesn't exist it's added. + * + * @externalExample ../../example/types/tokenlist-5.mjs + * @param {array|string|iteratable} value + * @returns {boolean} + * @throws {TypeError} unsupported value + */ + toggle(value) { + if (isString(value)) { + value.split(" ").forEach((token) => { + toggleValue.call(this, token); + }); + } else if (isIterable(value)) { + for (let token of value) { + toggleValue.call(this, token); + } + } else if (typeof value !== "undefined") { + throw new TypeError("unsupported value", "types/tokenlist.mjs"); + } + return this; + } + /** + * returns an array with all tokens + * + * @returns {array} + */ + entries() { + return Array.from(this.tokens); + } + /** + * executes the provided function with each value of the set + * + * @param {function} callback + * @returns {TokenList} + */ + forEach(callback) { + validateFunction(callback); + this.tokens.forEach(callback); + return this; + } + /** + * returns the individual tokens separated by a blank character + * + * @returns {string} + */ + toString() { + return this.entries().join(" "); + } + }; + } + }); + + // source/dom/constants.mjs + var DEFAULT_THEME, ATTRIBUTE_PREFIX, ATTRIBUTE_OPTIONS, ATTRIBUTE_SCRIPT_HOST, ATTRIBUTE_OPTIONS_SELECTOR, ATTRIBUTE_INIT_CALLBACK, initControlCallbackName, ATTRIBUTE_THEME_PREFIX, ATTRIBUTE_THEME_NAME, ATTRIBUTE_UPDATER_ATTRIBUTES, ATTRIBUTE_UPDATER_SELECT_THIS, ATTRIBUTE_UPDATER_REPLACE, ATTRIBUTE_UPDATER_INSERT, ATTRIBUTE_UPDATER_INSERT_REFERENCE, ATTRIBUTE_UPDATER_REMOVE, ATTRIBUTE_UPDATER_BIND, ATTRIBUTE_TEMPLATE_PREFIX, ATTRIBUTE_ROLE, ATTRIBUTE_DISABLED, ATTRIBUTE_OBJECTLINK, ATTRIBUTE_ERRORMESSAGE, objectUpdaterLinkSymbol, customElementUpdaterLinkSymbol, TAG_SCRIPT, TAG_LINK, ATTRIBUTE_ID, ATTRIBUTE_CLASS, ATTRIBUTE_TITLE, ATTRIBUTE_SRC, ATTRIBUTE_HREF, ATTRIBUTE_TYPE, ATTRIBUTE_NONCE; + var init_constants2 = __esm({ + "source/dom/constants.mjs"() { + DEFAULT_THEME = "monster"; + ATTRIBUTE_PREFIX = "data-monster-"; + ATTRIBUTE_OPTIONS = `${ATTRIBUTE_PREFIX}options`; + ATTRIBUTE_SCRIPT_HOST = `${ATTRIBUTE_PREFIX}script-host`; + ATTRIBUTE_OPTIONS_SELECTOR = `${ATTRIBUTE_PREFIX}options-selector`; + ATTRIBUTE_INIT_CALLBACK = `${ATTRIBUTE_PREFIX}init-callback`; + initControlCallbackName = `initCustomControlCallback`; + ATTRIBUTE_THEME_PREFIX = `${ATTRIBUTE_PREFIX}theme-`; + ATTRIBUTE_THEME_NAME = `${ATTRIBUTE_THEME_PREFIX}name`; + ATTRIBUTE_UPDATER_ATTRIBUTES = `${ATTRIBUTE_PREFIX}attributes`; + ATTRIBUTE_UPDATER_SELECT_THIS = `${ATTRIBUTE_PREFIX}select-this`; + ATTRIBUTE_UPDATER_REPLACE = `${ATTRIBUTE_PREFIX}replace`; + ATTRIBUTE_UPDATER_INSERT = `${ATTRIBUTE_PREFIX}insert`; + ATTRIBUTE_UPDATER_INSERT_REFERENCE = `${ATTRIBUTE_PREFIX}insert-reference`; + ATTRIBUTE_UPDATER_REMOVE = `${ATTRIBUTE_PREFIX}remove`; + ATTRIBUTE_UPDATER_BIND = `${ATTRIBUTE_PREFIX}bind`; + ATTRIBUTE_TEMPLATE_PREFIX = `${ATTRIBUTE_PREFIX}template-prefix`; + ATTRIBUTE_ROLE = `${ATTRIBUTE_PREFIX}role`; + ATTRIBUTE_DISABLED = "disabled"; + ATTRIBUTE_OBJECTLINK = `${ATTRIBUTE_PREFIX}objectlink`; + ATTRIBUTE_ERRORMESSAGE = `${ATTRIBUTE_PREFIX}error`; + objectUpdaterLinkSymbol = Symbol.for("@schukai/monster/dom/@@object-updater-link"); + customElementUpdaterLinkSymbol = Symbol.for("@schukai/monster/dom/custom-element@@options-updater-link"); + TAG_SCRIPT = "script"; + TAG_LINK = "link"; + ATTRIBUTE_ID = "id"; + ATTRIBUTE_CLASS = "class"; + ATTRIBUTE_TITLE = "title"; + ATTRIBUTE_SRC = "src"; + ATTRIBUTE_HREF = "href"; + ATTRIBUTE_TYPE = "type"; + ATTRIBUTE_NONCE = "nonce"; + } + }); + + // source/dom/attributes.mjs + function findClosestObjectLink(element) { + return findClosestByAttribute(element, ATTRIBUTE_OBJECTLINK); + } + function addToObjectLink(element, symbol2, object) { + validateInstance(element, HTMLElement); + validateSymbol(symbol2); + if (element?.[symbol2] === void 0) { + element[symbol2] = /* @__PURE__ */ new Set(); + } + addAttributeToken(element, ATTRIBUTE_OBJECTLINK, symbol2.toString()); + element[symbol2].add(object); + return element; + } + function removeObjectLink(element, symbol2) { + validateInstance(element, HTMLElement); + validateSymbol(symbol2); + if (element?.[symbol2] === void 0) { + return element; + } + removeAttributeToken(element, ATTRIBUTE_OBJECTLINK, symbol2.toString()); + delete element[symbol2]; + return element; + } + function hasObjectLink(element, symbol2) { + validateInstance(element, HTMLElement); + validateSymbol(symbol2); + if (element?.[symbol2] === void 0) { + return false; + } + return containsAttributeToken(element, ATTRIBUTE_OBJECTLINK, symbol2.toString()); + } + function getLinkedObjects(element, symbol2) { + validateInstance(element, HTMLElement); + validateSymbol(symbol2); + if (element?.[symbol2] === void 0) { + throw new Error(`there is no object link for ${symbol2.toString()}`); + } + return element?.[symbol2][Symbol.iterator](); + } + function toggleAttributeToken(element, key, token) { + validateInstance(element, HTMLElement); + validateString(token); + validateString(key); + if (!element.hasAttribute(key)) { + element.setAttribute(key, token); + return element; + } + element.setAttribute(key, new TokenList(element.getAttribute(key)).toggle(token).toString()); + return element; + } + function addAttributeToken(element, key, token) { + validateInstance(element, HTMLElement); + validateString(token); + validateString(key); + if (!element.hasAttribute(key)) { + element.setAttribute(key, token); + return element; + } + element.setAttribute(key, new TokenList(element.getAttribute(key)).add(token).toString()); + return element; + } + function removeAttributeToken(element, key, token) { + validateInstance(element, HTMLElement); + validateString(token); + validateString(key); + if (!element.hasAttribute(key)) { + return element; + } + element.setAttribute(key, new TokenList(element.getAttribute(key)).remove(token).toString()); + return element; + } + function containsAttributeToken(element, key, token) { + validateInstance(element, HTMLElement); + validateString(token); + validateString(key); + if (!element.hasAttribute(key)) { + return false; + } + return new TokenList(element.getAttribute(key)).contains(token); + } + function replaceAttributeToken(element, key, from, to) { + validateInstance(element, HTMLElement); + validateString(from); + validateString(to); + validateString(key); + if (!element.hasAttribute(key)) { + return element; + } + element.setAttribute(key, new TokenList(element.getAttribute(key)).replace(from, to).toString()); + return element; + } + function clearAttributeTokens(element, key) { + validateInstance(element, HTMLElement); + validateString(key); + if (!element.hasAttribute(key)) { + return element; + } + element.setAttribute(key, ""); + return element; + } + function findClosestByAttribute(element, key, value) { + validateInstance(element, getGlobalFunction("HTMLElement")); + if (element.hasAttribute(key)) { + if (value === void 0) { + return element; + } + if (element.getAttribute(key) === value) { + return element; + } + } + let selector = validateString(key); + if (value !== void 0) + selector += `=${validateString(value)}`; + let result = element.closest(`[${selector}]`); + if (result instanceof HTMLElement) { + return result; + } + return void 0; + } + function findClosestByClass(element, className) { + validateInstance(element, getGlobalFunction("HTMLElement")); + if (element?.classList?.contains(validateString(className))) { + return element; + } + let result = element.closest(`.${className}`); + if (result instanceof HTMLElement) { + return result; + } + return void 0; + } + var init_attributes = __esm({ + "source/dom/attributes.mjs"() { + init_global(); + init_tokenlist(); + init_validate(); + init_constants2(); + } + }); + + // source/types/stack.mjs + var Stack; + var init_stack = __esm({ + "source/types/stack.mjs"() { + init_base(); + init_constants(); + Stack = class extends Base { + /** + * + */ + constructor() { + super(); + this.data = []; + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/types/stack"); + } + /** + * @return {boolean} + */ + isEmpty() { + return this.data.length === 0; + } + /** + * looks at the object at the top of this stack without removing it from the stack. + * + * @return {*} + */ + peek() { + if (this.isEmpty()) { + return void 0; + } + return this.data?.[this.data.length - 1]; + } + /** + * pushes an item onto the top of this stack. + * + * @param {*} value + * @returns {Queue} + */ + push(value) { + this.data.push(value); + return this; + } + /** + * remove all entries + * + * @returns {Queue} + */ + clear() { + this.data = []; + return this; + } + /** + * removes the object at the top of this stack and returns + * that object as the value of this function. is the stack empty + * the return value is undefined. + * + * @return {*} + */ + pop() { + if (this.isEmpty()) { + return void 0; + } + return this.data.pop(); + } + }; + } + }); + + // source/data/pathfinder.mjs + function iterate(subject, path, check) { + if (check === void 0) { + check = false; + } + validateBoolean(check); + const result = /* @__PURE__ */ new Map(); + if (isArray(path)) { + path = path.join(DELIMITER); + } + if (isObject(subject) || isArray(subject)) { + for (const [key, value] of Object.entries(subject)) { + result.set(key, getValueViaPath.call(this, value, path, check)); + } + } else { + let key = path.split(DELIMITER).shift(); + result.set(key, getValueViaPath.call(this, subject, path, check)); + } + return result; + } + function getValueViaPath(subject, path, check) { + if (check === void 0) { + check = false; + } + validateBoolean(check); + if (!(isArray(path) || isString(path))) { + throw new Error("type error: path must be a string or an array"); + } + let parts; + if (isString(path)) { + if (path === "") { + return subject; + } + parts = path.split(DELIMITER); + } + let current = parts.shift(); + if (current === this.wildCard) { + return iterate.call(this, subject, parts.join(DELIMITER), check); + } + if (isObject(subject) || isArray(subject)) { + let anchor; + if (subject instanceof Map || subject instanceof WeakMap) { + anchor = subject.get(current); + } else if (subject instanceof Set || subject instanceof WeakSet) { + current = parseInt(current); + validateInteger(current); + anchor = [...subject]?.[current]; + } else if (typeof WeakRef === "function" && subject instanceof WeakRef) { + throw Error("unsupported action for this data type"); + } else if (isArray(subject)) { + current = parseInt(current); + validateInteger(current); + anchor = subject?.[current]; + } else { + anchor = subject?.[current]; + } + if (isObject(anchor) || isArray(anchor)) { + return getValueViaPath.call(this, anchor, parts.join(DELIMITER), check); + } + if (parts.length > 0) { + throw Error(`the journey is not at its end (${parts.join(DELIMITER)})`); + } + if (check === true) { + const descriptor = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(subject), current); + if (!subject.hasOwnProperty(current) && descriptor === void 0) { + throw Error("unknown value"); + } + } + return anchor; + } + throw TypeError(`unsupported type ${typeof subject}`); + } + function setValueViaPath(subject, path, value) { + if (!(isArray(path) || isString(path))) { + throw new Error("type error: path must be a string or an array"); + } + let parts; + if (isArray(path)) { + if (path.length === 0) { + return subject; + } + parts = path; + } else { + parts = path.split(DELIMITER); + } + let last = parts.pop(); + let subpath = parts.join(DELIMITER); + let stack = new Stack(); + let current = subpath; + while (true) { + try { + getValueViaPath.call(this, subject, current, true); + break; + } catch (e) { + } + stack.push(current); + parts.pop(); + current = parts.join(DELIMITER); + if (current === "") + break; + } + while (!stack.isEmpty()) { + current = stack.pop(); + let obj = {}; + if (!stack.isEmpty()) { + let n = stack.peek().split(DELIMITER).pop(); + if (isInteger(parseInt(n))) { + obj = []; + } + } + setValueViaPath.call(this, subject, current, obj); + } + let anchor = getValueViaPath.call(this, subject, subpath); + if (!(isObject(subject) || isArray(subject))) { + throw TypeError(`unsupported type: ${typeof subject}`); + } + if (anchor instanceof Map || anchor instanceof WeakMap) { + anchor.set(last, value); + } else if (anchor instanceof Set || anchor instanceof WeakSet) { + anchor.append(value); + } else if (typeof WeakRef === "function" && anchor instanceof WeakRef) { + throw Error("unsupported action for this data type"); + } else if (isArray(anchor)) { + last = parseInt(last); + validateInteger(last); + assignProperty(anchor, last, value); + } else { + assignProperty(anchor, last, value); + } + } + function assignProperty(object, key, value) { + if (!object.hasOwnProperty(key)) { + object[key] = value; + return; + } + if (value === void 0) { + delete object[key]; + } + object[key] = value; + } + function deleteValueViaPath(subject, path) { + if (!(isArray(path) || isString(path))) { + throw new Error("type error: path must be a string or an array"); + } + let parts; + if (isArray(path)) { + if (path.length === 0) { + return subject; + } + parts = path; + } else { + parts = path.split(DELIMITER); + } + let last = parts.pop(); + const subpath = parts.join(DELIMITER); + const anchor = getValueViaPath.call(this, subject, subpath); + if (anchor instanceof Map) { + anchor.delete(last); + } else if (anchor instanceof Set || anchor instanceof WeakMap || anchor instanceof WeakSet || typeof WeakRef === "function" && anchor instanceof WeakRef) { + throw Error("unsupported action for this data type"); + } else if (isArray(anchor)) { + last = parseInt(last); + validateInteger(last); + delete anchor[last]; + } else { + delete anchor[last]; + } + } + var DELIMITER, WILDCARD, Pathfinder; + var init_pathfinder = __esm({ + "source/data/pathfinder.mjs"() { + init_base(); + init_is(); + init_stack(); + init_validate(); + DELIMITER = "."; + WILDCARD = "*"; + Pathfinder = class extends Base { + /** + * @param {array|object|Map|Set} value + * @since 1.4.0 + * @throws {Error} the parameter must not be a simple type + **/ + constructor(object) { + super(); + if (isPrimitive(object)) { + throw new Error("the parameter must not be a simple type"); + } + this.object = object; + this.wildCard = WILDCARD; + } + /** + * set wildcard + * + * @param {string} wildcard + * @return {Pathfinder} + * @since 1.7.0 + */ + setWildCard(wildcard) { + validateString(wildcard); + this.wildCard = wildcard; + return this; + } + /** + * + * @param {string|array} path + * @since 1.4.0 + * @returns {*} + * @throws {TypeError} unsupported type + * @throws {Error} the journey is not at its end + * @throws {TypeError} value is not a string + * @throws {TypeError} value is not an integer + * @throws {Error} unsupported action for this data type + */ + getVia(path) { + return getValueViaPath.call(this, this.object, path); + } + /** + * + * @param {string|array} path + * @param {*} value + * @returns {Pathfinder} + * @since 1.4.0 + * @throws {TypeError} unsupported type + * @throws {TypeError} value is not a string + * @throws {TypeError} value is not an integer + * @throws {Error} unsupported action for this data type + */ + setVia(path, value) { + setValueViaPath.call(this, this.object, path, value); + return this; + } + /** + * Delete Via Path + * + * @param {string|array} path + * @returns {Pathfinder} + * @since 1.6.0 + * @throws {TypeError} unsupported type + * @throws {TypeError} value is not a string + * @throws {TypeError} value is not an integer + * @throws {Error} unsupported action for this data type + */ + deleteVia(path) { + deleteValueViaPath.call(this, this.object, path); + return this; + } + /** + * + * @param {string|array} path + * @return {bool} + * @throws {TypeError} unsupported type + * @throws {TypeError} value is not a string + * @throws {TypeError} value is not an integer + * @since 1.4.0 + */ + exists(path) { + try { + getValueViaPath.call(this, this.object, path, true); + return true; + } catch (e) { + } + return false; + } + }; + } + }); + + // source/types/basewithoptions.mjs + var BaseWithOptions; + var init_basewithoptions = __esm({ + "source/types/basewithoptions.mjs"() { + init_constants(); + init_extend(); + init_pathfinder(); + init_base(); + init_validate(); + BaseWithOptions = class extends Base { + /** + * + * @param {object} options + */ + constructor(options) { + super(); + if (options === void 0) { + options = {}; + } + this[internalSymbol] = extend({}, this.defaults, validateObject(options)); + } + /** + * This getter provides the options. Derived classes overwrite + * this getter with their own values. It is good karma to always include + * the values from the parent class. + * + * ```javascript + * get defaults() { + * return Object.assign({}, super.defaults, { + * mykey: true + * }); + * } + * + * ``` + * + * @return {object} + */ + get defaults() { + return {}; + } + /** + * nested options can be specified by path `a.b.c` + * + * @param {string} path + * @param {*} defaultValue + * @return {*} + * @since 1.10.0 + */ + getOption(path, defaultValue) { + let value; + try { + value = new Pathfinder(this[internalSymbol]).getVia(path); + } catch (e) { + } + if (value === void 0) + return defaultValue; + return value; + } + }; + } + }); + + // source/i18n/provider.mjs + var translationsLinkSymbol, Provider; + var init_provider = __esm({ + "source/i18n/provider.mjs"() { + init_constants(); + init_attributes(); + init_locale2(); + init_basewithoptions(); + init_locale(); + init_translations(); + translationsLinkSymbol = Symbol.for("@schukai/monster/i18n/translations@@link"); + Provider = class extends BaseWithOptions { + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 3.27.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/i18n/provider@@instance"); + } + /** + * @param {Locale|string} locale + * @return {Promise} + */ + getTranslations(locale) { + if (locale === void 0) { + locale = getLocaleOfDocument(); + } + return new Promise((resolve, reject) => { + try { + resolve(new Translations(locale)); + } catch (e) { + reject(e); + } + }); + } + /** + * @param {Locale|string} locale + * @param {HTMLElement} element + * @return {Provider} + */ + assignToElement(locale, element) { + if (locale === void 0) { + locale = getLocaleOfDocument(); + } + if (!(locale instanceof Locale)) { + throw new Error("Locale is not an instance of Locale"); + } + if (!(element instanceof HTMLElement)) { + element = document.querySelector("body"); + } + if (!(element instanceof HTMLElement)) { + throw new Error("Element is not an HTMLElement"); + } + return this.getTranslations(locale).then((obj) => { + let translations = null; + if (hasObjectLink(element, translationsLinkSymbol)) { + const objects = getLinkedObjects(element, translationsLinkSymbol); + for (const o of objects) { + if (o instanceof Translations) { + translations = o; + break; + } + } + if (!(translations instanceof Translations)) { + throw new Error("Object is not an instance of Translations"); + } + translations.assignTranslations(obj); + } else { + addToObjectLink(element, translationsLinkSymbol, obj); + } + return obj; + }); + } + }; + } + }); + + // source/i18n/translations.mjs + function getDocumentTranslations(element) { + const d2 = getDocument(); + if (!(element instanceof HTMLElement)) { + element = d2.querySelector(`[${ATTRIBUTE_OBJECTLINK}~="${translationsLinkSymbol.toString()}"]`); + if (element === null) { + throw new Error("Cannot find element with translations. Add a translations object to the document."); + } + } + if (!(element instanceof HTMLElement)) { + throw new Error("Element is not an HTMLElement."); + } + if (!hasObjectLink(element, translationsLinkSymbol)) { + throw new Error("This element has no translations."); + } + let obj = getLinkedObjects(element, translationsLinkSymbol); + for (const t of obj) { + if (t instanceof Translations) { + return t; + } + } + throw new Error("Missing translations."); + } + var Translations; + var init_translations = __esm({ + "source/i18n/translations.mjs"() { + init_constants(); + init_attributes(); + init_constants2(); + init_util(); + init_base(); + init_is(); + init_validate(); + init_locale(); + init_provider(); + Translations = class _Translations extends Base { + /** + * + * @param {Locale} locale + */ + constructor(locale) { + super(); + if (locale instanceof Locale) { + this.locale = locale; + } else { + this.locale = parseLocale(validateString(locale)); + } + this.storage = /* @__PURE__ */ new Map(); + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 3.27.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/i18n/translations@@instance"); + } + /** + * Fetches a text using the specified key. + * If no suitable key is found, `defaultText` is taken. + * + * @param {string} key + * @param {string|undefined} defaultText + * @return {string} + * @throws {Error} key not found + */ + getText(key, defaultText) { + if (!this.storage.has(key)) { + if (defaultText === void 0) { + throw new Error(`key ${key} not found`); + } + return validateString(defaultText); + } + let r = this.storage.get(key); + if (isObject(r)) { + return this.getPluralRuleText(key, "other", defaultText); + } + return this.storage.get(key); + } + /** + * A number `count` can be passed to this method. In addition to a number, one of the keywords can also be passed directly. + * "zero", "one", "two", "few", "many" and "other". Remember: not every language has all rules. + * + * The appropriate text for this number is then selected. If no suitable key is found, `defaultText` is taken. + * + * @param {string} key + * @param {integer|count} count + * @param {string|undefined} defaultText + * @return {string} + */ + getPluralRuleText(key, count, defaultText) { + if (!this.storage.has(key)) { + return validateString(defaultText); + } + let r = validateObject(this.storage.get(key)); + let keyword; + if (isString(count)) { + keyword = count.toLocaleString(); + } else { + count = validateInteger(count); + if (count === 0) { + if (r.hasOwnProperty("zero")) { + return validateString(r["zero"]); + } + } + keyword = new Intl.PluralRules(this.locale.toString()).select(validateInteger(count)); + } + if (r.hasOwnProperty(keyword)) { + return validateString(r[keyword]); + } + return validateString(defaultText); + } + /** + * Set a text for a key + * + * ``` + * translations.setText("text1", "Make my day!"); + * // plural rules + * translations.setText("text6", { + * "zero": "There are no files on Disk.", + * "one": "There is one file on Disk.", + * "other": "There are files on Disk." + * "default": "There are files on Disk." + * }); + * ``` + * + * @param {string} key + * @param {string|object} text + * @return {Translations} + * @throws {TypeError} value is not a string or object + */ + setText(key, text) { + if (isString(text) || isObject(text)) { + this.storage.set(validateString(key), text); + return this; + } + throw new TypeError("value is not a string or object"); + } + /** + * This method can be used to transfer overlays from an object. The keys are transferred, and the values are entered + * as text. + * + * The values can either be character strings or, in the case of texts with plural forms, objects. The plural forms + * must be stored as text via a standard key "zero", "one", "two", "few", "many" and "other". + * + * Additionally, the key default can be specified, which will be used if no other key fits. + * + * In some languages, like for example in German, there is no own more number at the value 0. In these languages, + * the function applies additionally zero. + * + * ``` + * translations.assignTranslations({ + * "text1": "Make my day!", + * "text2": "I'll be back!", + * "text6": { + * "zero": "There are no files on Disk.", + * "one": "There is one file on Disk.", + * "other": "There are files on Disk." + * "default": "There are files on Disk." + * }); + * ``` + * + * @param {object} translations + * @return {Translations} + */ + assignTranslations(translations) { + validateObject(translations); + if (translations instanceof _Translations) { + translations.storage.forEach((v, k) => { + this.setText(k, v); + }); + return this; + } + for (const [k, v] of Object.entries(translations)) { + this.setText(k, v); + } + return this; + } + }; + } + }); + + // source/data/transformer.mjs + function disassemble(command) { + validateString(command); + let placeholder = /* @__PURE__ */ new Map(); + const regex = /((?<pattern>\\(?<char>.)){1})/gim; + let result = command.matchAll(regex); + for (let m of result) { + let g = m?.["groups"]; + if (!isObject(g)) { + continue; + } + let p = g?.["pattern"]; + let c = g?.["char"]; + if (p && c) { + let r = `__${new ID().toString()}__`; + placeholder.set(r, c); + command = command.replace(p, r); + } + } + let parts = command.split(":"); + parts = parts.map(function(value) { + let v = value.trim(); + for (let k of placeholder) { + v = v.replace(k[0], k[1]); + } + return v; + }); + return parts; + } + function convertToString(value) { + if (isObject(value) && value.hasOwnProperty("toString")) { + value = value.toString(); + } + validateString(value); + return value; + } + function transform(value) { + const console2 = getGlobalObject("console"); + let args = clone(this.args); + let key; + let defaultValue; + let translations; + let date; + let locale; + let timestamp; + let map; + let keyValue; + switch (this.command) { + case "static": + return this.args.join(":"); + case "tolower": + case "strtolower": + case "tolowercase": + validateString(value); + return value.toLowerCase(); + case "contains": + if (isString(value)) { + return value.includes(args[0]); + } + if (isArray(value)) { + return value.includes(args[0]); + } + if (isObject(value)) { + return value.hasOwnProperty(args[0]); + } + return false; + case "has-entries": + case "hasentries": + if (isObject(value)) { + return Object.keys(value).length > 0; + } + if (isArray(value)) { + return value.length > 0; + } + return false; + case "isundefined": + case "is-undefined": + return value === void 0; + case "isnull": + case "is-null": + return value === null; + case "isset": + case "is-set": + return value !== void 0 && value !== null; + case "isnumber": + case "is-number": + return isPrimitive(value) && !isNaN(value); + case "isinteger": + case "is-integer": + return isPrimitive(value) && !isNaN(value) && value % 1 === 0; + case "isfloat": + case "is-float": + return isPrimitive(value) && !isNaN(value) && value % 1 !== 0; + case "isobject": + case "is-object": + return isObject(value); + case "isarray": + case "is-array": + return Array.isArray(value); + case "not": + validateBoolean(value); + return !value; + case "toupper": + case "strtoupper": + case "touppercase": + validateString(value); + return value.toUpperCase(); + case "tostring": + return `${value}`; + case "tointeger": + let n = parseInt(value); + validateInteger(n); + return n; + case "to-json": + case "tojson": + return JSON.stringify(value); + case "from-json": + case "fromjson": + return JSON.parse(value); + case "trim": + validateString(value); + return value.trim(); + case "rawurlencode": + validateString(value); + return encodeURIComponent(value).replace(/!/g, "%21").replace(/'/g, "%27").replace(/\(/g, "%28").replace(/\)/g, "%29").replace(/\*/g, "%2A"); + case "call": + let callback; + let callbackName = args.shift(); + let context = getGlobal(); + if (isObject(value) && value.hasOwnProperty(callbackName)) { + callback = value[callbackName]; + } else if (this.callbacks.has(callbackName)) { + let s = this.callbacks.get(callbackName); + callback = s?.["callback"]; + context = s?.["context"]; + } else if (typeof window === "object" && window.hasOwnProperty(callbackName)) { + callback = window[callbackName]; + } + validateFunction(callback); + args.unshift(value); + return callback.call(context, ...args); + case "plain": + case "plaintext": + validateString(value); + let doc = new DOMParser().parseFromString(value, "text/html"); + return doc.body.textContent || ""; + case "if": + case "?": + validatePrimitive(value); + let trueStatement = args.shift() || void 0; + let falseStatement = args.shift() || void 0; + if (trueStatement === "value") { + trueStatement = value; + } + if (trueStatement === "\\value") { + trueStatement = "value"; + } + if (trueStatement === "\\undefined") { + trueStatement = void 0; + } + if (trueStatement === "\\null") { + trueStatement = null; + } + if (falseStatement === "value") { + falseStatement = value; + } + if (falseStatement === "\\value") { + falseStatement = "value"; + } + if (falseStatement === "\\undefined") { + falseStatement = void 0; + } + if (falseStatement === "\\null") { + falseStatement = null; + } + let condition = value !== void 0 && value !== "" && value !== "off" && value !== "false" && value !== false || value === "on" || value === "true" || value === true; + return condition ? trueStatement : falseStatement; + case "ucfirst": + validateString(value); + let firstchar = value.charAt(0).toUpperCase(); + return firstchar + value.substr(1); + case "ucwords": + validateString(value); + return value.replace(/^([a-z\u00E0-\u00FC])|\s+([a-z\u00E0-\u00FC])/g, function(v) { + return v.toUpperCase(); + }); + case "count": + case "length": + if ((isString(value) || isObject(value) || isArray(value)) && value.hasOwnProperty("length")) { + return value.length; + } + throw new TypeError(`unsupported type ${typeof value}`); + case "to-base64": + case "btoa": + case "base64": + return btoa(convertToString(value)); + case "atob": + case "from-base64": + return atob(convertToString(value)); + case "empty": + return ""; + case "undefined": + return void 0; + case "debug": + if (isObject(console2)) { + console2.log(value); + } + return value; + case "prefix": + validateString(value); + let prefix = args?.[0]; + return prefix + value; + case "suffix": + validateString(value); + let suffix = args?.[0]; + return value + suffix; + case "uniqid": + return new ID().toString(); + case "first-key": + case "last-key": + case "nth-last-key": + case "nth-key": + if (!isObject(value)) { + throw new Error("type not supported"); + } + const keys = Object.keys(value).sort(); + if (this.command === "first-key") { + key = 0; + } else if (this.command === "last-key") { + key = keys.length - 1; + } else { + key = validateInteger(parseInt(args.shift())); + if (this.command === "nth-last-key") { + key = keys.length - key - 1; + } + } + defaultValue = args.shift() || ""; + let useKey = keys?.[key]; + if (value?.[useKey]) { + return value?.[useKey]; + } + return defaultValue; + case "key": + case "property": + case "index": + key = args.shift() || void 0; + if (key === void 0) { + throw new Error("missing key parameter"); + } + defaultValue = args.shift() || void 0; + if (value instanceof Map) { + if (!value.has(key)) { + return defaultValue; + } + return value.get(key); + } + if (isObject(value) || isArray(value)) { + if (value?.[key]) { + return value?.[key]; + } + return defaultValue; + } + throw new Error("type not supported"); + case "path-exists": + key = args.shift(); + if (key === void 0) { + throw new Error("missing key parameter"); + } + return new Pathfinder(value).exists(key); + case "concat": + let pf2 = new Pathfinder(value); + let concat2 = ""; + while (args.length > 0) { + key = args.shift(); + if (key === void 0) { + throw new Error("missing key parameter"); + } + if (isString(key) && key.trim() === "") { + concat2 += key; + continue; + } + if (!pf2.exists(key)) { + concat2 += key; + continue; + } + let v = pf2.getVia(key); + if (!isPrimitive(v)) { + throw new Error("value is not primitive"); + } + concat2 += v; + } + return concat2; + case "path": + key = args.shift(); + if (key === void 0) { + throw new Error("missing key parameter"); + } + let pf = new Pathfinder(value); + if (!pf.exists(key)) { + return void 0; + } + return pf.getVia(key); + case "substring": + validateString(value); + let start = parseInt(args[0]) || 0; + let end = (parseInt(args[1]) || 0) + start; + return value.substring(start, end); + case "nop": + return value; + case "??": + case "default": + if (value !== void 0 && value !== null) { + return value; + } + defaultValue = args.shift(); + let defaultType = args.shift(); + if (defaultType === void 0) { + defaultType = "string"; + } + switch (defaultType) { + case "int": + case "integer": + return parseInt(defaultValue); + case "float": + return parseFloat(defaultValue); + case "undefined": + return void 0; + case "bool": + case "boolean": + defaultValue = defaultValue.toLowerCase(); + return defaultValue !== "undefined" && defaultValue !== "" && defaultValue !== "off" && defaultValue !== "false" && defaultValue !== "false" || defaultValue === "on" || defaultValue === "true" || defaultValue === "true"; + case "string": + return `${defaultValue}`; + case "object": + return JSON.parse(atob(defaultValue)); + } + throw new Error("type not supported"); + case "map": + map = /* @__PURE__ */ new Map(); + while (args.length > 0) { + keyValue = args.shift(); + if (keyValue === void 0) { + throw new Error("missing key parameter"); + } + keyValue = keyValue.split("="); + map.set(keyValue[0], keyValue[1]); + } + return map.get(value); + case "equals": + if (args.length === 0) { + throw new Error("missing value parameter"); + } + validatePrimitive(value); + const equalsValue = args.shift(); + if (value === null) { + if (equalsValue === "null") { + return true; + } + return false; + } + const typeOfValue = typeof value; + switch (typeOfValue) { + case "string": + return value === equalsValue; + case "number": + return value === parseFloat(equalsValue); + case "boolean": + return value === (equalsValue === "true" || equalsValue === "on"); + case "undefined": + return equalsValue === "undefined"; + default: + throw new Error("type not supported"); + } + case "money": + case "currency": + try { + locale = getLocaleOfDocument(); + } catch (e) { + throw new Error(`unsupported locale or missing format (${e.message})`); + } + const currency = value.substring(0, 3); + if (!currency) { + throw new Error("missing currency parameter"); + } + const maximumFractionDigits = args?.[0] || 2; + const roundingIncrement = args?.[1] || 5; + const nf = new Intl.NumberFormat(locale, { + style: "currency", + currency, + maximumFractionDigits, + roundingIncrement + }); + return nf.format(value.substring(3)); + case "timestamp": + date = new Date(value); + timestamp = date.getTime(); + if (isNaN(timestamp)) { + throw new Error("invalid date"); + } + return timestamp; + case "time": + date = new Date(value); + if (isNaN(date.getTime())) { + throw new Error("invalid date"); + } + try { + locale = getLocaleOfDocument(); + return date.toLocaleTimeString(locale); + } catch (e) { + throw new Error(`unsupported locale or missing format (${e.message})`); + } + case "datetimeformat": + date = new Date(value); + if (isNaN(date.getTime())) { + throw new Error("invalid date"); + } + const options = { + dateStyle: args.shift() || "medium", + timeStyle: args.shift() || "medium" + }; + try { + locale = getLocaleOfDocument(); + return new Intl.DateTimeFormat(locale, options).format(date); + } catch (e) { + throw new Error(`unsupported locale or missing format (${e.message})`); + } + case "datetime": + date = new Date(value); + if (isNaN(date.getTime())) { + throw new Error("invalid date"); + } + try { + locale = getLocaleOfDocument(); + return date.toLocaleString(locale); + } catch (e) { + throw new Error(`unsupported locale or missing format (${e.message})`); + } + case "date": + date = new Date(value); + if (isNaN(date.getTime())) { + throw new Error("invalid date"); + } + try { + locale = getLocaleOfDocument(); + return date.toLocaleDateString(locale); + } catch (e) { + throw new Error(`unsupported locale or missing format (${e.message})`); + } + case "year": + date = new Date(value); + if (isNaN(date.getTime())) { + throw new Error("invalid date"); + } + return date.getFullYear(); + case "month": + date = new Date(value); + if (isNaN(date.getTime())) { + throw new Error("invalid date"); + } + return date.getMonth() + 1; + case "day": + date = new Date(value); + if (isNaN(date.getTime())) { + throw new Error("invalid date"); + } + return date.getDate(); + case "weekday": + date = new Date(value); + if (isNaN(date.getTime())) { + throw new Error("invalid date"); + } + return date.getDay(); + case "hour": + case "hours": + date = new Date(value); + if (isNaN(date.getTime())) { + throw new Error("invalid date"); + } + return date.getHours(); + case "minute": + case "minutes": + date = new Date(value); + if (isNaN(date.getTime())) { + throw new Error("invalid date"); + } + return date.getMinutes(); + case "second": + case "seconds": + date = new Date(value); + if (isNaN(date.getTime())) { + throw new Error("invalid date"); + } + return date.getSeconds(); + case "i18n": + case "translation": + translations = getDocumentTranslations(); + if (!(translations instanceof Translations)) { + throw new Error("missing translations"); + } + key = args.shift() || void 0; + if (key === void 0) { + key = value; + } + defaultValue = args.shift() || void 0; + return translations.getText(key, defaultValue); + default: + throw new Error(`unknown command ${this.command}`); + } + } + var Transformer; + var init_transformer = __esm({ + "source/data/transformer.mjs"() { + init_locale2(); + init_base(); + init_global(); + init_id(); + init_is(); + init_translations(); + init_validate(); + init_clone(); + init_pathfinder(); + Transformer = class extends Base { + /** + * + * @param {string} definition + */ + constructor(definition) { + super(); + this.args = disassemble(definition); + this.command = this.args.shift(); + this.callbacks = /* @__PURE__ */ new Map(); + } + /** + * + * @param {string} name + * @param {function} callback + * @param {object} context + * @returns {Transformer} + * @throws {TypeError} value is not a string + * @throws {TypeError} value is not a function + */ + setCallback(name, callback, context) { + validateString(name); + validateFunction(callback); + if (context !== void 0) { + validateObject(context); + } + this.callbacks.set(name, { + callback, + context + }); + return this; + } + /** + * + * @param {*} value + * @returns {*} + * @throws {Error} unknown command + * @throws {TypeError} unsupported type + * @throws {Error} type not supported + */ + run(value) { + return transform.apply(this, [value]); + } + }; + } + }); + + // source/data/pipe.mjs + var DELIMITER2, Pipe; + var init_pipe = __esm({ + "source/data/pipe.mjs"() { + init_base(); + init_validate(); + init_transformer(); + DELIMITER2 = "|"; + Pipe = class extends Base { + /** + * @param {string} pipe a pipe consists of commands whose input and output are connected with the pipe symbol `|`. + * @throws {TypeError} + */ + constructor(pipe) { + super(); + validateString(pipe); + this.pipe = pipe.split(DELIMITER2).map((v) => { + return new Transformer(v); + }); + } + /** + * @param {string} name + * @param {function} callback + * @param {object} context + * @returns {Transformer} + * @throws {TypeError} value is not a string + * @throws {TypeError} value is not a function + */ + setCallback(name, callback, context) { + for (const [, t] of Object.entries(this.pipe)) { + t.setCallback(name, callback, context); + } + return this; + } + /** + * run a pipe + * + * @param {*} value + * @returns {*} + */ + run(value) { + return this.pipe.reduce((accumulator, transformer, currentIndex, array) => { + return transformer.run(accumulator); + }, value); + } + }; + } + }); + + // source/text/formatter.mjs + function format(text) { + const self2 = this; + self2[watchdogSymbol]++; + if (this[watchdogSymbol] > 20) { + throw new Error("too deep nesting"); + } + let openMarker = self2[internalSymbol]["marker"]["open"]?.[this[markerOpenIndexSymbol]]; + let closeMarker = self2[internalSymbol]["marker"]["close"]?.[this[markerCloseIndexSymbol]]; + if (text.indexOf(openMarker) === -1 || text.indexOf(closeMarker) === -1) { + return text; + } + let result = tokenize.call(this, validateString(text), openMarker, closeMarker); + if (self2[internalSymbol]["marker"]["open"]?.[this[markerOpenIndexSymbol] + 1]) { + this[markerOpenIndexSymbol]++; + } + if (self2[internalSymbol]["marker"]["close"]?.[this[markerCloseIndexSymbol] + 1]) { + this[markerCloseIndexSymbol]++; + } + result = format.call(self2, result); + return result; + } + function tokenize(text, openMarker, closeMarker) { + const self2 = this; + let formatted = []; + const parameterAssignment = self2[internalSymbol]["parameter"]["assignment"]; + const parameterDelimiter = self2[internalSymbol]["parameter"]["delimiter"]; + const callbacks = self2[internalSymbol]["callbacks"]; + while (true) { + let startIndex = text.indexOf(openMarker); + if (startIndex === -1) { + formatted.push(text); + break; + } else if (startIndex > 0) { + formatted.push(text.substring(0, startIndex)); + text = text.substring(startIndex); + } + let endIndex = text.substring(openMarker.length).indexOf(closeMarker); + if (endIndex !== -1) + endIndex += openMarker.length; + let insideStartIndex = text.substring(openMarker.length).indexOf(openMarker); + if (insideStartIndex !== -1) { + insideStartIndex += openMarker.length; + if (insideStartIndex < endIndex) { + let result = tokenize.call(self2, text.substring(insideStartIndex), openMarker, closeMarker); + text = text.substring(0, insideStartIndex) + result; + endIndex = text.substring(openMarker.length).indexOf(closeMarker); + if (endIndex !== -1) + endIndex += openMarker.length; + } + } + if (endIndex === -1) { + throw new Error("syntax error in formatter template"); + } + let key = text.substring(openMarker.length, endIndex); + let parts = key.split(parameterDelimiter); + let currentPipe = parts.shift(); + self2[workingDataSymbol] = extend({}, self2[internalObjectSymbol], self2[workingDataSymbol]); + for (const kv of parts) { + const [k, v] = kv.split(parameterAssignment); + self2[workingDataSymbol][k] = v; + } + const t1 = key.split("|").shift().trim(); + const t2 = t1.split("::").shift().trim(); + const t3 = t2.split(".").shift().trim(); + let prefix = self2[workingDataSymbol]?.[t3] ? "path:" : "static:"; + let command = ""; + if (prefix && key.indexOf(prefix) !== 0 && key.indexOf("path:") !== 0 && key.indexOf("static:") !== 0) { + command = prefix; + } + command += currentPipe; + const pipe = new Pipe(command); + if (isObject(callbacks)) { + for (const [name, callback] of Object.entries(callbacks)) { + pipe.setCallback(name, callback); + } + } + formatted.push(validateString(pipe.run(self2[workingDataSymbol]))); + text = text.substring(endIndex + closeMarker.length); + } + return formatted.join(""); + } + var internalObjectSymbol, watchdogSymbol, markerOpenIndexSymbol, markerCloseIndexSymbol, workingDataSymbol, Formatter; + var init_formatter = __esm({ + "source/text/formatter.mjs"() { + init_constants(); + init_extend(); + init_pipe(); + init_basewithoptions(); + init_is(); + init_validate(); + internalObjectSymbol = Symbol("internalObject"); + watchdogSymbol = Symbol("watchdog"); + markerOpenIndexSymbol = Symbol("markerOpenIndex"); + markerCloseIndexSymbol = Symbol("markercloseIndex"); + workingDataSymbol = Symbol("workingData"); + Formatter = class extends BaseWithOptions { + /** + * Default values for the markers are `${` and `}` + * + * @param {object} object + * @throws {TypeError} value is not a object + */ + constructor(object, options) { + super(options); + this[internalObjectSymbol] = object || {}; + this[markerOpenIndexSymbol] = 0; + this[markerCloseIndexSymbol] = 0; + } + /** + * @property {object} marker + * @property {array} marker.open=["${"] + * @property {array} marker.close=["${"] + * @property {object} parameter + * @property {string} parameter.delimiter="::" + * @property {string} parameter.assignment="=" + * @property {object} callbacks={} + */ + get defaults() { + return extend({}, super.defaults, { + marker: { + open: ["${"], + close: ["}"] + }, + parameter: { + delimiter: "::", + assignment: "=" + }, + callbacks: {} + }); + } + /** + * Set new Parameter Character + * + * Default values for the chars are `::` and `=` + * + * ``` + * formatter.setParameterChars('#'); + * formatter.setParameterChars('[',']'); + * formatter.setParameterChars('i18n{','}'); + * ``` + * + * @param {string} delimiter + * @param {string} assignment + * @return {Formatter} + * @since 1.24.0 + * @throws {TypeError} value is not a string + */ + setParameterChars(delimiter, assignment) { + if (delimiter !== void 0) { + this[internalSymbol]["parameter"]["delimiter"] = validateString(delimiter); + } + if (assignment !== void 0) { + this[internalSymbol]["parameter"]["assignment"] = validateString(assignment); + } + return this; + } + /** + * Set new Marker + * + * Default values for the markers are `${` and `}` + * + * ``` + * formatter.setMarker('#'); // open and close are both # + * formatter.setMarker('[',']'); + * formatter.setMarker('i18n{','}'); + * ``` + * + * @param {array|string} open + * @param {array|string|undefined} close + * @return {Formatter} + * @since 1.12.0 + * @throws {TypeError} value is not a string + */ + setMarker(open, close) { + if (close === void 0) { + close = open; + } + if (isString(open)) + open = [open]; + if (isString(close)) + close = [close]; + this[internalSymbol]["marker"]["open"] = validateArray(open); + this[internalSymbol]["marker"]["close"] = validateArray(close); + return this; + } + /** + * + * @param {string} text + * @return {string} + * @throws {TypeError} value is not a string + * @throws {Error} too deep nesting + */ + format(text) { + this[watchdogSymbol] = 0; + this[markerOpenIndexSymbol] = 0; + this[markerCloseIndexSymbol] = 0; + this[workingDataSymbol] = {}; + return format.call(this, text); + } + }; + } + }); + + // node_modules/.pnpm/pvtsutils@1.3.5/node_modules/pvtsutils/build/index.js + var require_build = __commonJS({ + "node_modules/.pnpm/pvtsutils@1.3.5/node_modules/pvtsutils/build/index.js"(exports) { + "use strict"; + var ARRAY_BUFFER_NAME = "[object ArrayBuffer]"; + var BufferSourceConverter8 = class _BufferSourceConverter { + static isArrayBuffer(data) { + return Object.prototype.toString.call(data) === ARRAY_BUFFER_NAME; + } + static toArrayBuffer(data) { + if (this.isArrayBuffer(data)) { + return data; + } + if (data.byteLength === data.buffer.byteLength) { + return data.buffer; + } + if (data.byteOffset === 0 && data.byteLength === data.buffer.byteLength) { + return data.buffer; + } + return this.toUint8Array(data.buffer).slice(data.byteOffset, data.byteOffset + data.byteLength).buffer; + } + static toUint8Array(data) { + return this.toView(data, Uint8Array); + } + static toView(data, type) { + if (data.constructor === type) { + return data; + } + if (this.isArrayBuffer(data)) { + return new type(data); + } + if (this.isArrayBufferView(data)) { + return new type(data.buffer, data.byteOffset, data.byteLength); + } + throw new TypeError("The provided value is not of type '(ArrayBuffer or ArrayBufferView)'"); + } + static isBufferSource(data) { + return this.isArrayBufferView(data) || this.isArrayBuffer(data); + } + static isArrayBufferView(data) { + return ArrayBuffer.isView(data) || data && this.isArrayBuffer(data.buffer); + } + static isEqual(a2, b) { + const aView = _BufferSourceConverter.toUint8Array(a2); + const bView = _BufferSourceConverter.toUint8Array(b); + if (aView.length !== bView.byteLength) { + return false; + } + for (let i = 0; i < aView.length; i++) { + if (aView[i] !== bView[i]) { + return false; + } + } + return true; + } + static concat(...args) { + let buffers; + if (Array.isArray(args[0]) && !(args[1] instanceof Function)) { + buffers = args[0]; + } else if (Array.isArray(args[0]) && args[1] instanceof Function) { + buffers = args[0]; + } else { + if (args[args.length - 1] instanceof Function) { + buffers = args.slice(0, args.length - 1); + } else { + buffers = args; + } + } + let size = 0; + for (const buffer of buffers) { + size += buffer.byteLength; + } + const res = new Uint8Array(size); + let offset = 0; + for (const buffer of buffers) { + const view = this.toUint8Array(buffer); + res.set(view, offset); + offset += view.length; + } + if (args[args.length - 1] instanceof Function) { + return this.toView(res, args[args.length - 1]); + } + return res.buffer; + } + }; + var STRING_TYPE = "string"; + var HEX_REGEX = /^[0-9a-f]+$/i; + var BASE64_REGEX = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/; + var BASE64URL_REGEX = /^[a-zA-Z0-9-_]+$/; + var Utf8Converter = class { + static fromString(text) { + const s = unescape(encodeURIComponent(text)); + const uintArray = new Uint8Array(s.length); + for (let i = 0; i < s.length; i++) { + uintArray[i] = s.charCodeAt(i); + } + return uintArray.buffer; + } + static toString(buffer) { + const buf = BufferSourceConverter8.toUint8Array(buffer); + let encodedString = ""; + for (let i = 0; i < buf.length; i++) { + encodedString += String.fromCharCode(buf[i]); + } + const decodedString = decodeURIComponent(escape(encodedString)); + return decodedString; + } + }; + var Utf16Converter = class { + static toString(buffer, littleEndian = false) { + const arrayBuffer = BufferSourceConverter8.toArrayBuffer(buffer); + const dataView = new DataView(arrayBuffer); + let res = ""; + for (let i = 0; i < arrayBuffer.byteLength; i += 2) { + const code = dataView.getUint16(i, littleEndian); + res += String.fromCharCode(code); + } + return res; + } + static fromString(text, littleEndian = false) { + const res = new ArrayBuffer(text.length * 2); + const dataView = new DataView(res); + for (let i = 0; i < text.length; i++) { + dataView.setUint16(i * 2, text.charCodeAt(i), littleEndian); + } + return res; + } + }; + var Convert4 = class _Convert { + static isHex(data) { + return typeof data === STRING_TYPE && HEX_REGEX.test(data); + } + static isBase64(data) { + return typeof data === STRING_TYPE && BASE64_REGEX.test(data); + } + static isBase64Url(data) { + return typeof data === STRING_TYPE && BASE64URL_REGEX.test(data); + } + static ToString(buffer, enc = "utf8") { + const buf = BufferSourceConverter8.toUint8Array(buffer); + switch (enc.toLowerCase()) { + case "utf8": + return this.ToUtf8String(buf); + case "binary": + return this.ToBinary(buf); + case "hex": + return this.ToHex(buf); + case "base64": + return this.ToBase64(buf); + case "base64url": + return this.ToBase64Url(buf); + case "utf16le": + return Utf16Converter.toString(buf, true); + case "utf16": + case "utf16be": + return Utf16Converter.toString(buf); + default: + throw new Error(`Unknown type of encoding '${enc}'`); + } + } + static FromString(str, enc = "utf8") { + if (!str) { + return new ArrayBuffer(0); + } + switch (enc.toLowerCase()) { + case "utf8": + return this.FromUtf8String(str); + case "binary": + return this.FromBinary(str); + case "hex": + return this.FromHex(str); + case "base64": + return this.FromBase64(str); + case "base64url": + return this.FromBase64Url(str); + case "utf16le": + return Utf16Converter.fromString(str, true); + case "utf16": + case "utf16be": + return Utf16Converter.fromString(str); + default: + throw new Error(`Unknown type of encoding '${enc}'`); + } + } + static ToBase64(buffer) { + const buf = BufferSourceConverter8.toUint8Array(buffer); + if (typeof btoa !== "undefined") { + const binary = this.ToString(buf, "binary"); + return btoa(binary); + } else { + return Buffer.from(buf).toString("base64"); + } + } + static FromBase64(base64) { + const formatted = this.formatString(base64); + if (!formatted) { + return new ArrayBuffer(0); + } + if (!_Convert.isBase64(formatted)) { + throw new TypeError("Argument 'base64Text' is not Base64 encoded"); + } + if (typeof atob !== "undefined") { + return this.FromBinary(atob(formatted)); + } else { + return new Uint8Array(Buffer.from(formatted, "base64")).buffer; + } + } + static FromBase64Url(base64url) { + const formatted = this.formatString(base64url); + if (!formatted) { + return new ArrayBuffer(0); + } + if (!_Convert.isBase64Url(formatted)) { + throw new TypeError("Argument 'base64url' is not Base64Url encoded"); + } + return this.FromBase64(this.Base64Padding(formatted.replace(/\-/g, "+").replace(/\_/g, "/"))); + } + static ToBase64Url(data) { + return this.ToBase64(data).replace(/\+/g, "-").replace(/\//g, "_").replace(/\=/g, ""); + } + static FromUtf8String(text, encoding = _Convert.DEFAULT_UTF8_ENCODING) { + switch (encoding) { + case "ascii": + return this.FromBinary(text); + case "utf8": + return Utf8Converter.fromString(text); + case "utf16": + case "utf16be": + return Utf16Converter.fromString(text); + case "utf16le": + case "usc2": + return Utf16Converter.fromString(text, true); + default: + throw new Error(`Unknown type of encoding '${encoding}'`); + } + } + static ToUtf8String(buffer, encoding = _Convert.DEFAULT_UTF8_ENCODING) { + switch (encoding) { + case "ascii": + return this.ToBinary(buffer); + case "utf8": + return Utf8Converter.toString(buffer); + case "utf16": + case "utf16be": + return Utf16Converter.toString(buffer); + case "utf16le": + case "usc2": + return Utf16Converter.toString(buffer, true); + default: + throw new Error(`Unknown type of encoding '${encoding}'`); + } + } + static FromBinary(text) { + const stringLength = text.length; + const resultView = new Uint8Array(stringLength); + for (let i = 0; i < stringLength; i++) { + resultView[i] = text.charCodeAt(i); + } + return resultView.buffer; + } + static ToBinary(buffer) { + const buf = BufferSourceConverter8.toUint8Array(buffer); + let res = ""; + for (let i = 0; i < buf.length; i++) { + res += String.fromCharCode(buf[i]); + } + return res; + } + static ToHex(buffer) { + const buf = BufferSourceConverter8.toUint8Array(buffer); + let result = ""; + const len = buf.length; + for (let i = 0; i < len; i++) { + const byte = buf[i]; + if (byte < 16) { + result += "0"; + } + result += byte.toString(16); + } + return result; + } + static FromHex(hexString) { + let formatted = this.formatString(hexString); + if (!formatted) { + return new ArrayBuffer(0); + } + if (!_Convert.isHex(formatted)) { + throw new TypeError("Argument 'hexString' is not HEX encoded"); + } + if (formatted.length % 2) { + formatted = `0${formatted}`; + } + const res = new Uint8Array(formatted.length / 2); + for (let i = 0; i < formatted.length; i = i + 2) { + const c = formatted.slice(i, i + 2); + res[i / 2] = parseInt(c, 16); + } + return res.buffer; + } + static ToUtf16String(buffer, littleEndian = false) { + return Utf16Converter.toString(buffer, littleEndian); + } + static FromUtf16String(text, littleEndian = false) { + return Utf16Converter.fromString(text, littleEndian); + } + static Base64Padding(base64) { + const padCount = 4 - base64.length % 4; + if (padCount < 4) { + for (let i = 0; i < padCount; i++) { + base64 += "="; + } + } + return base64; + } + static formatString(data) { + return (data === null || data === void 0 ? void 0 : data.replace(/[\n\r\t ]/g, "")) || ""; + } + }; + Convert4.DEFAULT_UTF8_ENCODING = "utf8"; + function assign(target, ...sources) { + const res = arguments[0]; + for (let i = 1; i < arguments.length; i++) { + const obj = arguments[i]; + for (const prop in obj) { + res[prop] = obj[prop]; + } + } + return res; + } + function combine2(...buf) { + const totalByteLength = buf.map((item) => item.byteLength).reduce((prev, cur) => prev + cur); + const res = new Uint8Array(totalByteLength); + let currentPos = 0; + buf.map((item) => new Uint8Array(item)).forEach((arr) => { + for (const item2 of arr) { + res[currentPos++] = item2; + } + }); + return res.buffer; + } + function isEqual(bytes1, bytes2) { + if (!(bytes1 && bytes2)) { + return false; + } + if (bytes1.byteLength !== bytes2.byteLength) { + return false; + } + const b1 = new Uint8Array(bytes1); + const b2 = new Uint8Array(bytes2); + for (let i = 0; i < bytes1.byteLength; i++) { + if (b1[i] !== b2[i]) { + return false; + } + } + return true; + } + exports.BufferSourceConverter = BufferSourceConverter8; + exports.Convert = Convert4; + exports.assign = assign; + exports.combine = combine2; + exports.isEqual = isEqual; + } + }); + + // node_modules/.pnpm/pvutils@1.1.3/node_modules/pvutils/build/utils.es.js + function utilFromBase(inputBuffer, inputBase) { + let result = 0; + if (inputBuffer.length === 1) { + return inputBuffer[0]; + } + for (let i = inputBuffer.length - 1; i >= 0; i--) { + result += inputBuffer[inputBuffer.length - 1 - i] * Math.pow(2, inputBase * i); + } + return result; + } + function utilToBase(value, base, reserved = -1) { + const internalReserved = reserved; + let internalValue = value; + let result = 0; + let biggest = Math.pow(2, base); + for (let i = 1; i < 8; i++) { + if (value < biggest) { + let retBuf; + if (internalReserved < 0) { + retBuf = new ArrayBuffer(i); + result = i; + } else { + if (internalReserved < i) { + return new ArrayBuffer(0); + } + retBuf = new ArrayBuffer(internalReserved); + result = internalReserved; + } + const retView = new Uint8Array(retBuf); + for (let j = i - 1; j >= 0; j--) { + const basis = Math.pow(2, j * base); + retView[result - j - 1] = Math.floor(internalValue / basis); + internalValue -= retView[result - j - 1] * basis; + } + return retBuf; + } + biggest *= Math.pow(2, base); + } + return new ArrayBuffer(0); + } + function utilConcatView(...views) { + let outputLength = 0; + let prevLength = 0; + for (const view of views) { + outputLength += view.length; + } + const retBuf = new ArrayBuffer(outputLength); + const retView = new Uint8Array(retBuf); + for (const view of views) { + retView.set(view, prevLength); + prevLength += view.length; + } + return retView; + } + function utilDecodeTC() { + const buf = new Uint8Array(this.valueHex); + if (this.valueHex.byteLength >= 2) { + const condition1 = buf[0] === 255 && buf[1] & 128; + const condition2 = buf[0] === 0 && (buf[1] & 128) === 0; + if (condition1 || condition2) { + this.warnings.push("Needlessly long format"); + } + } + const bigIntBuffer = new ArrayBuffer(this.valueHex.byteLength); + const bigIntView = new Uint8Array(bigIntBuffer); + for (let i = 0; i < this.valueHex.byteLength; i++) { + bigIntView[i] = 0; + } + bigIntView[0] = buf[0] & 128; + const bigInt = utilFromBase(bigIntView, 8); + const smallIntBuffer = new ArrayBuffer(this.valueHex.byteLength); + const smallIntView = new Uint8Array(smallIntBuffer); + for (let j = 0; j < this.valueHex.byteLength; j++) { + smallIntView[j] = buf[j]; + } + smallIntView[0] &= 127; + const smallInt = utilFromBase(smallIntView, 8); + return smallInt - bigInt; + } + function utilEncodeTC(value) { + const modValue = value < 0 ? value * -1 : value; + let bigInt = 128; + for (let i = 1; i < 8; i++) { + if (modValue <= bigInt) { + if (value < 0) { + const smallInt = bigInt - modValue; + const retBuf2 = utilToBase(smallInt, 8, i); + const retView2 = new Uint8Array(retBuf2); + retView2[0] |= 128; + return retBuf2; + } + let retBuf = utilToBase(modValue, 8, i); + let retView = new Uint8Array(retBuf); + if (retView[0] & 128) { + const tempBuf = retBuf.slice(0); + const tempView = new Uint8Array(tempBuf); + retBuf = new ArrayBuffer(retBuf.byteLength + 1); + retView = new Uint8Array(retBuf); + for (let k = 0; k < tempBuf.byteLength; k++) { + retView[k + 1] = tempView[k]; + } + retView[0] = 0; + } + return retBuf; + } + bigInt *= Math.pow(2, 8); + } + return new ArrayBuffer(0); + } + function isEqualBuffer(inputBuffer1, inputBuffer2) { + if (inputBuffer1.byteLength !== inputBuffer2.byteLength) { + return false; + } + const view1 = new Uint8Array(inputBuffer1); + const view2 = new Uint8Array(inputBuffer2); + for (let i = 0; i < view1.length; i++) { + if (view1[i] !== view2[i]) { + return false; + } + } + return true; + } + function padNumber(inputNumber, fullLength) { + const str = inputNumber.toString(10); + if (fullLength < str.length) { + return ""; + } + const dif = fullLength - str.length; + const padding = new Array(dif); + for (let i = 0; i < dif; i++) { + padding[i] = "0"; + } + const paddingString = padding.join(""); + return paddingString.concat(str); + } + var log2; + var init_utils_es = __esm({ + "node_modules/.pnpm/pvutils@1.1.3/node_modules/pvutils/build/utils.es.js"() { + log2 = Math.log(2); + } + }); + + // node_modules/.pnpm/asn1js@3.0.5/node_modules/asn1js/build/index.es.js + var index_es_exports = {}; + __export(index_es_exports, { + Any: () => Any, + BaseBlock: () => BaseBlock, + BaseStringBlock: () => BaseStringBlock, + BitString: () => BitString, + BmpString: () => BmpString, + Boolean: () => Boolean2, + CharacterString: () => CharacterString, + Choice: () => Choice, + Constructed: () => Constructed, + DATE: () => DATE, + DateTime: () => DateTime, + Duration: () => Duration, + EndOfContent: () => EndOfContent, + Enumerated: () => Enumerated, + GeneralString: () => GeneralString, + GeneralizedTime: () => GeneralizedTime, + GraphicString: () => GraphicString, + HexBlock: () => HexBlock, + IA5String: () => IA5String, + Integer: () => Integer, + Null: () => Null, + NumericString: () => NumericString, + ObjectIdentifier: () => ObjectIdentifier, + OctetString: () => OctetString, + Primitive: () => Primitive, + PrintableString: () => PrintableString, + RawData: () => RawData, + RelativeObjectIdentifier: () => RelativeObjectIdentifier, + Repeated: () => Repeated, + Sequence: () => Sequence, + Set: () => Set2, + TIME: () => TIME, + TeletexString: () => TeletexString, + TimeOfDay: () => TimeOfDay, + UTCTime: () => UTCTime, + UniversalString: () => UniversalString, + Utf8String: () => Utf8String, + ValueBlock: () => ValueBlock, + VideotexString: () => VideotexString, + ViewWriter: () => ViewWriter, + VisibleString: () => VisibleString, + compareSchema: () => compareSchema, + fromBER: () => fromBER, + verifySchema: () => verifySchema + }); + function assertBigInt() { + if (typeof BigInt === "undefined") { + throw new Error("BigInt is not defined. Your environment doesn't implement BigInt."); + } + } + function concat(buffers) { + let outputLength = 0; + let prevLength = 0; + for (let i = 0; i < buffers.length; i++) { + const buffer = buffers[i]; + outputLength += buffer.byteLength; + } + const retView = new Uint8Array(outputLength); + for (let i = 0; i < buffers.length; i++) { + const buffer = buffers[i]; + retView.set(new Uint8Array(buffer), prevLength); + prevLength += buffer.byteLength; + } + return retView.buffer; + } + function checkBufferParams(baseBlock, inputBuffer, inputOffset, inputLength) { + if (!(inputBuffer instanceof Uint8Array)) { + baseBlock.error = "Wrong parameter: inputBuffer must be 'Uint8Array'"; + return false; + } + if (!inputBuffer.byteLength) { + baseBlock.error = "Wrong parameter: inputBuffer has zero length"; + return false; + } + if (inputOffset < 0) { + baseBlock.error = "Wrong parameter: inputOffset less than zero"; + return false; + } + if (inputLength < 0) { + baseBlock.error = "Wrong parameter: inputLength less than zero"; + return false; + } + if (inputBuffer.byteLength - inputOffset - inputLength < 0) { + baseBlock.error = "End of input reached before message was fully decoded (inconsistent offset and length values)"; + return false; + } + return true; + } + function HexBlock(BaseClass) { + var _a2; + return _a2 = class Some extends BaseClass { + constructor(...args) { + var _a3; + super(...args); + const params = args[0] || {}; + this.isHexOnly = (_a3 = params.isHexOnly) !== null && _a3 !== void 0 ? _a3 : false; + this.valueHexView = params.valueHex ? pvtsutils.BufferSourceConverter.toUint8Array(params.valueHex) : EMPTY_VIEW; + } + get valueHex() { + return this.valueHexView.slice().buffer; + } + set valueHex(value) { + this.valueHexView = new Uint8Array(value); + } + fromBER(inputBuffer, inputOffset, inputLength) { + const view = inputBuffer instanceof ArrayBuffer ? new Uint8Array(inputBuffer) : inputBuffer; + if (!checkBufferParams(this, view, inputOffset, inputLength)) { + return -1; + } + const endLength = inputOffset + inputLength; + this.valueHexView = view.subarray(inputOffset, endLength); + if (!this.valueHexView.length) { + this.warnings.push("Zero buffer length"); + return inputOffset; + } + this.blockLength = inputLength; + return endLength; + } + toBER(sizeOnly = false) { + if (!this.isHexOnly) { + this.error = "Flag 'isHexOnly' is not set, abort"; + return EMPTY_BUFFER; + } + if (sizeOnly) { + return new ArrayBuffer(this.valueHexView.byteLength); + } + return this.valueHexView.byteLength === this.valueHexView.buffer.byteLength ? this.valueHexView.buffer : this.valueHexView.slice().buffer; + } + toJSON() { + return { + ...super.toJSON(), + isHexOnly: this.isHexOnly, + valueHex: pvtsutils.Convert.ToHex(this.valueHexView) + }; + } + }, _a2.NAME = "hexBlock", _a2; + } + function prepareIndefiniteForm(baseBlock) { + if (baseBlock instanceof typeStore.Constructed) { + for (const value of baseBlock.valueBlock.value) { + if (prepareIndefiniteForm(value)) { + baseBlock.lenBlock.isIndefiniteForm = true; + } + } + } + return !!baseBlock.lenBlock.isIndefiniteForm; + } + function localChangeType(inputObject, newType) { + if (inputObject instanceof newType) { + return inputObject; + } + const newObject = new newType(); + newObject.idBlock = inputObject.idBlock; + newObject.lenBlock = inputObject.lenBlock; + newObject.warnings = inputObject.warnings; + newObject.valueBeforeDecodeView = inputObject.valueBeforeDecodeView; + return newObject; + } + function localFromBER(inputBuffer, inputOffset = 0, inputLength = inputBuffer.length) { + const incomingOffset = inputOffset; + let returnObject = new BaseBlock({}, ValueBlock); + const baseBlock = new LocalBaseBlock(); + if (!checkBufferParams(baseBlock, inputBuffer, inputOffset, inputLength)) { + returnObject.error = baseBlock.error; + return { + offset: -1, + result: returnObject + }; + } + const intBuffer = inputBuffer.subarray(inputOffset, inputOffset + inputLength); + if (!intBuffer.length) { + returnObject.error = "Zero buffer length"; + return { + offset: -1, + result: returnObject + }; + } + let resultOffset = returnObject.idBlock.fromBER(inputBuffer, inputOffset, inputLength); + if (returnObject.idBlock.warnings.length) { + returnObject.warnings.concat(returnObject.idBlock.warnings); + } + if (resultOffset === -1) { + returnObject.error = returnObject.idBlock.error; + return { + offset: -1, + result: returnObject + }; + } + inputOffset = resultOffset; + inputLength -= returnObject.idBlock.blockLength; + resultOffset = returnObject.lenBlock.fromBER(inputBuffer, inputOffset, inputLength); + if (returnObject.lenBlock.warnings.length) { + returnObject.warnings.concat(returnObject.lenBlock.warnings); + } + if (resultOffset === -1) { + returnObject.error = returnObject.lenBlock.error; + return { + offset: -1, + result: returnObject + }; + } + inputOffset = resultOffset; + inputLength -= returnObject.lenBlock.blockLength; + if (!returnObject.idBlock.isConstructed && returnObject.lenBlock.isIndefiniteForm) { + returnObject.error = "Indefinite length form used for primitive encoding form"; + return { + offset: -1, + result: returnObject + }; + } + let newASN1Type = BaseBlock; + switch (returnObject.idBlock.tagClass) { + case 1: + if (returnObject.idBlock.tagNumber >= 37 && returnObject.idBlock.isHexOnly === false) { + returnObject.error = "UNIVERSAL 37 and upper tags are reserved by ASN.1 standard"; + return { + offset: -1, + result: returnObject + }; + } + switch (returnObject.idBlock.tagNumber) { + case 0: + if (returnObject.idBlock.isConstructed && returnObject.lenBlock.length > 0) { + returnObject.error = "Type [UNIVERSAL 0] is reserved"; + return { + offset: -1, + result: returnObject + }; + } + newASN1Type = typeStore.EndOfContent; + break; + case 1: + newASN1Type = typeStore.Boolean; + break; + case 2: + newASN1Type = typeStore.Integer; + break; + case 3: + newASN1Type = typeStore.BitString; + break; + case 4: + newASN1Type = typeStore.OctetString; + break; + case 5: + newASN1Type = typeStore.Null; + break; + case 6: + newASN1Type = typeStore.ObjectIdentifier; + break; + case 10: + newASN1Type = typeStore.Enumerated; + break; + case 12: + newASN1Type = typeStore.Utf8String; + break; + case 13: + newASN1Type = typeStore.RelativeObjectIdentifier; + break; + case 14: + newASN1Type = typeStore.TIME; + break; + case 15: + returnObject.error = "[UNIVERSAL 15] is reserved by ASN.1 standard"; + return { + offset: -1, + result: returnObject + }; + case 16: + newASN1Type = typeStore.Sequence; + break; + case 17: + newASN1Type = typeStore.Set; + break; + case 18: + newASN1Type = typeStore.NumericString; + break; + case 19: + newASN1Type = typeStore.PrintableString; + break; + case 20: + newASN1Type = typeStore.TeletexString; + break; + case 21: + newASN1Type = typeStore.VideotexString; + break; + case 22: + newASN1Type = typeStore.IA5String; + break; + case 23: + newASN1Type = typeStore.UTCTime; + break; + case 24: + newASN1Type = typeStore.GeneralizedTime; + break; + case 25: + newASN1Type = typeStore.GraphicString; + break; + case 26: + newASN1Type = typeStore.VisibleString; + break; + case 27: + newASN1Type = typeStore.GeneralString; + break; + case 28: + newASN1Type = typeStore.UniversalString; + break; + case 29: + newASN1Type = typeStore.CharacterString; + break; + case 30: + newASN1Type = typeStore.BmpString; + break; + case 31: + newASN1Type = typeStore.DATE; + break; + case 32: + newASN1Type = typeStore.TimeOfDay; + break; + case 33: + newASN1Type = typeStore.DateTime; + break; + case 34: + newASN1Type = typeStore.Duration; + break; + default: { + const newObject = returnObject.idBlock.isConstructed ? new typeStore.Constructed() : new typeStore.Primitive(); + newObject.idBlock = returnObject.idBlock; + newObject.lenBlock = returnObject.lenBlock; + newObject.warnings = returnObject.warnings; + returnObject = newObject; + } + } + break; + case 2: + case 3: + case 4: + default: { + newASN1Type = returnObject.idBlock.isConstructed ? typeStore.Constructed : typeStore.Primitive; + } + } + returnObject = localChangeType(returnObject, newASN1Type); + resultOffset = returnObject.fromBER(inputBuffer, inputOffset, returnObject.lenBlock.isIndefiniteForm ? inputLength : returnObject.lenBlock.length); + returnObject.valueBeforeDecodeView = inputBuffer.subarray(incomingOffset, incomingOffset + returnObject.blockLength); + return { + offset: resultOffset, + result: returnObject + }; + } + function fromBER(inputBuffer) { + if (!inputBuffer.byteLength) { + const result = new BaseBlock({}, ValueBlock); + result.error = "Input buffer has zero length"; + return { + offset: -1, + result + }; + } + return localFromBER(pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer).slice(), 0, inputBuffer.byteLength); + } + function checkLen(indefiniteLength, length) { + if (indefiniteLength) { + return 1; + } + return length; + } + function viewAdd(first, second) { + const c = new Uint8Array([0]); + const firstView = new Uint8Array(first); + const secondView = new Uint8Array(second); + let firstViewCopy = firstView.slice(0); + const firstViewCopyLength = firstViewCopy.length - 1; + const secondViewCopy = secondView.slice(0); + const secondViewCopyLength = secondViewCopy.length - 1; + let value = 0; + const max = secondViewCopyLength < firstViewCopyLength ? firstViewCopyLength : secondViewCopyLength; + let counter = 0; + for (let i = max; i >= 0; i--, counter++) { + switch (true) { + case counter < secondViewCopy.length: + value = firstViewCopy[firstViewCopyLength - counter] + secondViewCopy[secondViewCopyLength - counter] + c[0]; + break; + default: + value = firstViewCopy[firstViewCopyLength - counter] + c[0]; + } + c[0] = value / 10; + switch (true) { + case counter >= firstViewCopy.length: + firstViewCopy = utilConcatView(new Uint8Array([value % 10]), firstViewCopy); + break; + default: + firstViewCopy[firstViewCopyLength - counter] = value % 10; + } + } + if (c[0] > 0) + firstViewCopy = utilConcatView(c, firstViewCopy); + return firstViewCopy; + } + function power2(n) { + if (n >= powers2.length) { + for (let p = powers2.length; p <= n; p++) { + const c = new Uint8Array([0]); + let digits = powers2[p - 1].slice(0); + for (let i = digits.length - 1; i >= 0; i--) { + const newValue = new Uint8Array([(digits[i] << 1) + c[0]]); + c[0] = newValue[0] / 10; + digits[i] = newValue[0] % 10; + } + if (c[0] > 0) + digits = utilConcatView(c, digits); + powers2.push(digits); + } + } + return powers2[n]; + } + function viewSub(first, second) { + let b = 0; + const firstView = new Uint8Array(first); + const secondView = new Uint8Array(second); + const firstViewCopy = firstView.slice(0); + const firstViewCopyLength = firstViewCopy.length - 1; + const secondViewCopy = secondView.slice(0); + const secondViewCopyLength = secondViewCopy.length - 1; + let value; + let counter = 0; + for (let i = secondViewCopyLength; i >= 0; i--, counter++) { + value = firstViewCopy[firstViewCopyLength - counter] - secondViewCopy[secondViewCopyLength - counter] - b; + switch (true) { + case value < 0: + b = 1; + firstViewCopy[firstViewCopyLength - counter] = value + 10; + break; + default: + b = 0; + firstViewCopy[firstViewCopyLength - counter] = value; + } + } + if (b > 0) { + for (let i = firstViewCopyLength - secondViewCopyLength + 1; i >= 0; i--, counter++) { + value = firstViewCopy[firstViewCopyLength - counter] - b; + if (value < 0) { + b = 1; + firstViewCopy[firstViewCopyLength - counter] = value + 10; + } else { + b = 0; + firstViewCopy[firstViewCopyLength - counter] = value; + break; + } + } + } + return firstViewCopy.slice(); + } + function compareSchema(root, inputData, inputSchema) { + if (inputSchema instanceof Choice) { + for (let j = 0; j < inputSchema.value.length; j++) { + const result = compareSchema(root, inputData, inputSchema.value[j]); + if (result.verified) { + return { + verified: true, + result: root + }; + } + } + { + const _result = { + verified: false, + result: { + error: "Wrong values for Choice type" + } + }; + if (inputSchema.hasOwnProperty(NAME)) + _result.name = inputSchema.name; + return _result; + } + } + if (inputSchema instanceof Any) { + if (inputSchema.hasOwnProperty(NAME)) + root[inputSchema.name] = inputData; + return { + verified: true, + result: root + }; + } + if (root instanceof Object === false) { + return { + verified: false, + result: { error: "Wrong root object" } + }; + } + if (inputData instanceof Object === false) { + return { + verified: false, + result: { error: "Wrong ASN.1 data" } + }; + } + if (inputSchema instanceof Object === false) { + return { + verified: false, + result: { error: "Wrong ASN.1 schema" } + }; + } + if (ID_BLOCK in inputSchema === false) { + return { + verified: false, + result: { error: "Wrong ASN.1 schema" } + }; + } + if (FROM_BER in inputSchema.idBlock === false) { + return { + verified: false, + result: { error: "Wrong ASN.1 schema" } + }; + } + if (TO_BER in inputSchema.idBlock === false) { + return { + verified: false, + result: { error: "Wrong ASN.1 schema" } + }; + } + const encodedId = inputSchema.idBlock.toBER(false); + if (encodedId.byteLength === 0) { + return { + verified: false, + result: { error: "Error encoding idBlock for ASN.1 schema" } + }; + } + const decodedOffset = inputSchema.idBlock.fromBER(encodedId, 0, encodedId.byteLength); + if (decodedOffset === -1) { + return { + verified: false, + result: { error: "Error decoding idBlock for ASN.1 schema" } + }; + } + if (inputSchema.idBlock.hasOwnProperty(TAG_CLASS) === false) { + return { + verified: false, + result: { error: "Wrong ASN.1 schema" } + }; + } + if (inputSchema.idBlock.tagClass !== inputData.idBlock.tagClass) { + return { + verified: false, + result: root + }; + } + if (inputSchema.idBlock.hasOwnProperty(TAG_NUMBER) === false) { + return { + verified: false, + result: { error: "Wrong ASN.1 schema" } + }; + } + if (inputSchema.idBlock.tagNumber !== inputData.idBlock.tagNumber) { + return { + verified: false, + result: root + }; + } + if (inputSchema.idBlock.hasOwnProperty(IS_CONSTRUCTED) === false) { + return { + verified: false, + result: { error: "Wrong ASN.1 schema" } + }; + } + if (inputSchema.idBlock.isConstructed !== inputData.idBlock.isConstructed) { + return { + verified: false, + result: root + }; + } + if (!(IS_HEX_ONLY in inputSchema.idBlock)) { + return { + verified: false, + result: { error: "Wrong ASN.1 schema" } + }; + } + if (inputSchema.idBlock.isHexOnly !== inputData.idBlock.isHexOnly) { + return { + verified: false, + result: root + }; + } + if (inputSchema.idBlock.isHexOnly) { + if (VALUE_HEX_VIEW in inputSchema.idBlock === false) { + return { + verified: false, + result: { error: "Wrong ASN.1 schema" } + }; + } + const schemaView = inputSchema.idBlock.valueHexView; + const asn1View = inputData.idBlock.valueHexView; + if (schemaView.length !== asn1View.length) { + return { + verified: false, + result: root + }; + } + for (let i = 0; i < schemaView.length; i++) { + if (schemaView[i] !== asn1View[1]) { + return { + verified: false, + result: root + }; + } + } + } + if (inputSchema.name) { + inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, EMPTY_STRING); + if (inputSchema.name) + root[inputSchema.name] = inputData; + } + if (inputSchema instanceof typeStore.Constructed) { + let admission = 0; + let result = { + verified: false, + result: { + error: "Unknown error" + } + }; + let maxLength = inputSchema.valueBlock.value.length; + if (maxLength > 0) { + if (inputSchema.valueBlock.value[0] instanceof Repeated) { + maxLength = inputData.valueBlock.value.length; + } + } + if (maxLength === 0) { + return { + verified: true, + result: root + }; + } + if (inputData.valueBlock.value.length === 0 && inputSchema.valueBlock.value.length !== 0) { + let _optional = true; + for (let i = 0; i < inputSchema.valueBlock.value.length; i++) + _optional = _optional && (inputSchema.valueBlock.value[i].optional || false); + if (_optional) { + return { + verified: true, + result: root + }; + } + if (inputSchema.name) { + inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, EMPTY_STRING); + if (inputSchema.name) + delete root[inputSchema.name]; + } + root.error = "Inconsistent object length"; + return { + verified: false, + result: root + }; + } + for (let i = 0; i < maxLength; i++) { + if (i - admission >= inputData.valueBlock.value.length) { + if (inputSchema.valueBlock.value[i].optional === false) { + const _result = { + verified: false, + result: root + }; + root.error = "Inconsistent length between ASN.1 data and schema"; + if (inputSchema.name) { + inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, EMPTY_STRING); + if (inputSchema.name) { + delete root[inputSchema.name]; + _result.name = inputSchema.name; + } + } + return _result; + } + } else { + if (inputSchema.valueBlock.value[0] instanceof Repeated) { + result = compareSchema(root, inputData.valueBlock.value[i], inputSchema.valueBlock.value[0].value); + if (result.verified === false) { + if (inputSchema.valueBlock.value[0].optional) + admission++; + else { + if (inputSchema.name) { + inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, EMPTY_STRING); + if (inputSchema.name) + delete root[inputSchema.name]; + } + return result; + } + } + if (NAME in inputSchema.valueBlock.value[0] && inputSchema.valueBlock.value[0].name.length > 0) { + let arrayRoot = {}; + if (LOCAL in inputSchema.valueBlock.value[0] && inputSchema.valueBlock.value[0].local) + arrayRoot = inputData; + else + arrayRoot = root; + if (typeof arrayRoot[inputSchema.valueBlock.value[0].name] === "undefined") + arrayRoot[inputSchema.valueBlock.value[0].name] = []; + arrayRoot[inputSchema.valueBlock.value[0].name].push(inputData.valueBlock.value[i]); + } + } else { + result = compareSchema(root, inputData.valueBlock.value[i - admission], inputSchema.valueBlock.value[i]); + if (result.verified === false) { + if (inputSchema.valueBlock.value[i].optional) + admission++; + else { + if (inputSchema.name) { + inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, EMPTY_STRING); + if (inputSchema.name) + delete root[inputSchema.name]; + } + return result; + } + } + } + } + } + if (result.verified === false) { + const _result = { + verified: false, + result: root + }; + if (inputSchema.name) { + inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, EMPTY_STRING); + if (inputSchema.name) { + delete root[inputSchema.name]; + _result.name = inputSchema.name; + } + } + return _result; + } + return { + verified: true, + result: root + }; + } + if (inputSchema.primitiveSchema && VALUE_HEX_VIEW in inputData.valueBlock) { + const asn1 = localFromBER(inputData.valueBlock.valueHexView); + if (asn1.offset === -1) { + const _result = { + verified: false, + result: asn1.result + }; + if (inputSchema.name) { + inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, EMPTY_STRING); + if (inputSchema.name) { + delete root[inputSchema.name]; + _result.name = inputSchema.name; + } + } + return _result; + } + return compareSchema(root, asn1.result, inputSchema.primitiveSchema); + } + return { + verified: true, + result: root + }; + } + function verifySchema(inputBuffer, inputSchema) { + if (inputSchema instanceof Object === false) { + return { + verified: false, + result: { error: "Wrong ASN.1 schema type" } + }; + } + const asn1 = localFromBER(pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer)); + if (asn1.offset === -1) { + return { + verified: false, + result: asn1.result + }; + } + return compareSchema(asn1.result, asn1.result, inputSchema); + } + var pvtsutils, ViewWriter, powers2, digitsString, NAME, VALUE_HEX_VIEW, IS_HEX_ONLY, ID_BLOCK, TAG_CLASS, TAG_NUMBER, IS_CONSTRUCTED, FROM_BER, TO_BER, LOCAL, EMPTY_STRING, EMPTY_BUFFER, EMPTY_VIEW, END_OF_CONTENT_NAME, OCTET_STRING_NAME, BIT_STRING_NAME, LocalBaseBlock, ValueBlock, LocalIdentificationBlock, LocalLengthBlock, typeStore, BaseBlock, BaseStringBlock, LocalPrimitiveValueBlock, _a$w, Primitive, LocalConstructedValueBlock, _a$v, Constructed, LocalEndOfContentValueBlock, _a$u, EndOfContent, _a$t, Null, LocalBooleanValueBlock, _a$s, Boolean2, LocalOctetStringValueBlock, _a$r, OctetString, LocalBitStringValueBlock, _a$q, BitString, _a$p, LocalIntegerValueBlock, _a$o, Integer, _a$n, Enumerated, LocalSidValueBlock, LocalObjectIdentifierValueBlock, _a$m, ObjectIdentifier, LocalRelativeSidValueBlock, LocalRelativeObjectIdentifierValueBlock, _a$l, RelativeObjectIdentifier, _a$k, Sequence, _a$j, Set2, LocalStringValueBlock, LocalSimpleStringValueBlock, LocalSimpleStringBlock, LocalUtf8StringValueBlock, _a$i, Utf8String, LocalBmpStringValueBlock, _a$h, BmpString, LocalUniversalStringValueBlock, _a$g, UniversalString, _a$f, NumericString, _a$e, PrintableString, _a$d, TeletexString, _a$c, VideotexString, _a$b, IA5String, _a$a, GraphicString, _a$9, VisibleString, _a$8, GeneralString, _a$7, CharacterString, _a$6, UTCTime, _a$5, GeneralizedTime, _a$4, DATE, _a$3, TimeOfDay, _a$2, DateTime, _a$1, Duration, _a, TIME, Any, Choice, Repeated, RawData; + var init_index_es = __esm({ + "node_modules/.pnpm/asn1js@3.0.5/node_modules/asn1js/build/index.es.js"() { + pvtsutils = __toESM(require_build()); + init_utils_es(); + ViewWriter = class { + constructor() { + this.items = []; + } + write(buf) { + this.items.push(buf); + } + final() { + return concat(this.items); + } + }; + powers2 = [new Uint8Array([1])]; + digitsString = "0123456789"; + NAME = "name"; + VALUE_HEX_VIEW = "valueHexView"; + IS_HEX_ONLY = "isHexOnly"; + ID_BLOCK = "idBlock"; + TAG_CLASS = "tagClass"; + TAG_NUMBER = "tagNumber"; + IS_CONSTRUCTED = "isConstructed"; + FROM_BER = "fromBER"; + TO_BER = "toBER"; + LOCAL = "local"; + EMPTY_STRING = ""; + EMPTY_BUFFER = new ArrayBuffer(0); + EMPTY_VIEW = new Uint8Array(0); + END_OF_CONTENT_NAME = "EndOfContent"; + OCTET_STRING_NAME = "OCTET STRING"; + BIT_STRING_NAME = "BIT STRING"; + LocalBaseBlock = class { + constructor({ blockLength = 0, error = EMPTY_STRING, warnings = [], valueBeforeDecode = EMPTY_VIEW } = {}) { + this.blockLength = blockLength; + this.error = error; + this.warnings = warnings; + this.valueBeforeDecodeView = pvtsutils.BufferSourceConverter.toUint8Array(valueBeforeDecode); + } + static blockName() { + return this.NAME; + } + get valueBeforeDecode() { + return this.valueBeforeDecodeView.slice().buffer; + } + set valueBeforeDecode(value) { + this.valueBeforeDecodeView = new Uint8Array(value); + } + toJSON() { + return { + blockName: this.constructor.NAME, + blockLength: this.blockLength, + error: this.error, + warnings: this.warnings, + valueBeforeDecode: pvtsutils.Convert.ToHex(this.valueBeforeDecodeView) + }; + } + }; + LocalBaseBlock.NAME = "baseBlock"; + ValueBlock = class extends LocalBaseBlock { + fromBER(inputBuffer, inputOffset, inputLength) { + throw TypeError("User need to make a specific function in a class which extends 'ValueBlock'"); + } + toBER(sizeOnly, writer) { + throw TypeError("User need to make a specific function in a class which extends 'ValueBlock'"); + } + }; + ValueBlock.NAME = "valueBlock"; + LocalIdentificationBlock = class extends HexBlock(LocalBaseBlock) { + constructor({ idBlock = {} } = {}) { + var _a2, _b, _c, _d; + super(); + if (idBlock) { + this.isHexOnly = (_a2 = idBlock.isHexOnly) !== null && _a2 !== void 0 ? _a2 : false; + this.valueHexView = idBlock.valueHex ? pvtsutils.BufferSourceConverter.toUint8Array(idBlock.valueHex) : EMPTY_VIEW; + this.tagClass = (_b = idBlock.tagClass) !== null && _b !== void 0 ? _b : -1; + this.tagNumber = (_c = idBlock.tagNumber) !== null && _c !== void 0 ? _c : -1; + this.isConstructed = (_d = idBlock.isConstructed) !== null && _d !== void 0 ? _d : false; + } else { + this.tagClass = -1; + this.tagNumber = -1; + this.isConstructed = false; + } + } + toBER(sizeOnly = false) { + let firstOctet = 0; + switch (this.tagClass) { + case 1: + firstOctet |= 0; + break; + case 2: + firstOctet |= 64; + break; + case 3: + firstOctet |= 128; + break; + case 4: + firstOctet |= 192; + break; + default: + this.error = "Unknown tag class"; + return EMPTY_BUFFER; + } + if (this.isConstructed) + firstOctet |= 32; + if (this.tagNumber < 31 && !this.isHexOnly) { + const retView2 = new Uint8Array(1); + if (!sizeOnly) { + let number = this.tagNumber; + number &= 31; + firstOctet |= number; + retView2[0] = firstOctet; + } + return retView2.buffer; + } + if (!this.isHexOnly) { + const encodedBuf = utilToBase(this.tagNumber, 7); + const encodedView = new Uint8Array(encodedBuf); + const size = encodedBuf.byteLength; + const retView2 = new Uint8Array(size + 1); + retView2[0] = firstOctet | 31; + if (!sizeOnly) { + for (let i = 0; i < size - 1; i++) + retView2[i + 1] = encodedView[i] | 128; + retView2[size] = encodedView[size - 1]; + } + return retView2.buffer; + } + const retView = new Uint8Array(this.valueHexView.byteLength + 1); + retView[0] = firstOctet | 31; + if (!sizeOnly) { + const curView = this.valueHexView; + for (let i = 0; i < curView.length - 1; i++) + retView[i + 1] = curView[i] | 128; + retView[this.valueHexView.byteLength] = curView[curView.length - 1]; + } + return retView.buffer; + } + fromBER(inputBuffer, inputOffset, inputLength) { + const inputView = pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer); + if (!checkBufferParams(this, inputView, inputOffset, inputLength)) { + return -1; + } + const intBuffer = inputView.subarray(inputOffset, inputOffset + inputLength); + if (intBuffer.length === 0) { + this.error = "Zero buffer length"; + return -1; + } + const tagClassMask = intBuffer[0] & 192; + switch (tagClassMask) { + case 0: + this.tagClass = 1; + break; + case 64: + this.tagClass = 2; + break; + case 128: + this.tagClass = 3; + break; + case 192: + this.tagClass = 4; + break; + default: + this.error = "Unknown tag class"; + return -1; + } + this.isConstructed = (intBuffer[0] & 32) === 32; + this.isHexOnly = false; + const tagNumberMask = intBuffer[0] & 31; + if (tagNumberMask !== 31) { + this.tagNumber = tagNumberMask; + this.blockLength = 1; + } else { + let count = 1; + let intTagNumberBuffer = this.valueHexView = new Uint8Array(255); + let tagNumberBufferMaxLength = 255; + while (intBuffer[count] & 128) { + intTagNumberBuffer[count - 1] = intBuffer[count] & 127; + count++; + if (count >= intBuffer.length) { + this.error = "End of input reached before message was fully decoded"; + return -1; + } + if (count === tagNumberBufferMaxLength) { + tagNumberBufferMaxLength += 255; + const tempBufferView2 = new Uint8Array(tagNumberBufferMaxLength); + for (let i = 0; i < intTagNumberBuffer.length; i++) + tempBufferView2[i] = intTagNumberBuffer[i]; + intTagNumberBuffer = this.valueHexView = new Uint8Array(tagNumberBufferMaxLength); + } + } + this.blockLength = count + 1; + intTagNumberBuffer[count - 1] = intBuffer[count] & 127; + const tempBufferView = new Uint8Array(count); + for (let i = 0; i < count; i++) + tempBufferView[i] = intTagNumberBuffer[i]; + intTagNumberBuffer = this.valueHexView = new Uint8Array(count); + intTagNumberBuffer.set(tempBufferView); + if (this.blockLength <= 9) + this.tagNumber = utilFromBase(intTagNumberBuffer, 7); + else { + this.isHexOnly = true; + this.warnings.push("Tag too long, represented as hex-coded"); + } + } + if (this.tagClass === 1 && this.isConstructed) { + switch (this.tagNumber) { + case 1: + case 2: + case 5: + case 6: + case 9: + case 13: + case 14: + case 23: + case 24: + case 31: + case 32: + case 33: + case 34: + this.error = "Constructed encoding used for primitive type"; + return -1; + } + } + return inputOffset + this.blockLength; + } + toJSON() { + return { + ...super.toJSON(), + tagClass: this.tagClass, + tagNumber: this.tagNumber, + isConstructed: this.isConstructed + }; + } + }; + LocalIdentificationBlock.NAME = "identificationBlock"; + LocalLengthBlock = class extends LocalBaseBlock { + constructor({ lenBlock = {} } = {}) { + var _a2, _b, _c; + super(); + this.isIndefiniteForm = (_a2 = lenBlock.isIndefiniteForm) !== null && _a2 !== void 0 ? _a2 : false; + this.longFormUsed = (_b = lenBlock.longFormUsed) !== null && _b !== void 0 ? _b : false; + this.length = (_c = lenBlock.length) !== null && _c !== void 0 ? _c : 0; + } + fromBER(inputBuffer, inputOffset, inputLength) { + const view = pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer); + if (!checkBufferParams(this, view, inputOffset, inputLength)) { + return -1; + } + const intBuffer = view.subarray(inputOffset, inputOffset + inputLength); + if (intBuffer.length === 0) { + this.error = "Zero buffer length"; + return -1; + } + if (intBuffer[0] === 255) { + this.error = "Length block 0xFF is reserved by standard"; + return -1; + } + this.isIndefiniteForm = intBuffer[0] === 128; + if (this.isIndefiniteForm) { + this.blockLength = 1; + return inputOffset + this.blockLength; + } + this.longFormUsed = !!(intBuffer[0] & 128); + if (this.longFormUsed === false) { + this.length = intBuffer[0]; + this.blockLength = 1; + return inputOffset + this.blockLength; + } + const count = intBuffer[0] & 127; + if (count > 8) { + this.error = "Too big integer"; + return -1; + } + if (count + 1 > intBuffer.length) { + this.error = "End of input reached before message was fully decoded"; + return -1; + } + const lenOffset = inputOffset + 1; + const lengthBufferView = view.subarray(lenOffset, lenOffset + count); + if (lengthBufferView[count - 1] === 0) + this.warnings.push("Needlessly long encoded length"); + this.length = utilFromBase(lengthBufferView, 8); + if (this.longFormUsed && this.length <= 127) + this.warnings.push("Unnecessary usage of long length form"); + this.blockLength = count + 1; + return inputOffset + this.blockLength; + } + toBER(sizeOnly = false) { + let retBuf; + let retView; + if (this.length > 127) + this.longFormUsed = true; + if (this.isIndefiniteForm) { + retBuf = new ArrayBuffer(1); + if (sizeOnly === false) { + retView = new Uint8Array(retBuf); + retView[0] = 128; + } + return retBuf; + } + if (this.longFormUsed) { + const encodedBuf = utilToBase(this.length, 8); + if (encodedBuf.byteLength > 127) { + this.error = "Too big length"; + return EMPTY_BUFFER; + } + retBuf = new ArrayBuffer(encodedBuf.byteLength + 1); + if (sizeOnly) + return retBuf; + const encodedView = new Uint8Array(encodedBuf); + retView = new Uint8Array(retBuf); + retView[0] = encodedBuf.byteLength | 128; + for (let i = 0; i < encodedBuf.byteLength; i++) + retView[i + 1] = encodedView[i]; + return retBuf; + } + retBuf = new ArrayBuffer(1); + if (sizeOnly === false) { + retView = new Uint8Array(retBuf); + retView[0] = this.length; + } + return retBuf; + } + toJSON() { + return { + ...super.toJSON(), + isIndefiniteForm: this.isIndefiniteForm, + longFormUsed: this.longFormUsed, + length: this.length + }; + } + }; + LocalLengthBlock.NAME = "lengthBlock"; + typeStore = {}; + BaseBlock = class extends LocalBaseBlock { + constructor({ name = EMPTY_STRING, optional = false, primitiveSchema, ...parameters } = {}, valueBlockType) { + super(parameters); + this.name = name; + this.optional = optional; + if (primitiveSchema) { + this.primitiveSchema = primitiveSchema; + } + this.idBlock = new LocalIdentificationBlock(parameters); + this.lenBlock = new LocalLengthBlock(parameters); + this.valueBlock = valueBlockType ? new valueBlockType(parameters) : new ValueBlock(parameters); + } + fromBER(inputBuffer, inputOffset, inputLength) { + const resultOffset = this.valueBlock.fromBER(inputBuffer, inputOffset, this.lenBlock.isIndefiniteForm ? inputLength : this.lenBlock.length); + if (resultOffset === -1) { + this.error = this.valueBlock.error; + return resultOffset; + } + if (!this.idBlock.error.length) + this.blockLength += this.idBlock.blockLength; + if (!this.lenBlock.error.length) + this.blockLength += this.lenBlock.blockLength; + if (!this.valueBlock.error.length) + this.blockLength += this.valueBlock.blockLength; + return resultOffset; + } + toBER(sizeOnly, writer) { + const _writer = writer || new ViewWriter(); + if (!writer) { + prepareIndefiniteForm(this); + } + const idBlockBuf = this.idBlock.toBER(sizeOnly); + _writer.write(idBlockBuf); + if (this.lenBlock.isIndefiniteForm) { + _writer.write(new Uint8Array([128]).buffer); + this.valueBlock.toBER(sizeOnly, _writer); + _writer.write(new ArrayBuffer(2)); + } else { + const valueBlockBuf = this.valueBlock.toBER(sizeOnly); + this.lenBlock.length = valueBlockBuf.byteLength; + const lenBlockBuf = this.lenBlock.toBER(sizeOnly); + _writer.write(lenBlockBuf); + _writer.write(valueBlockBuf); + } + if (!writer) { + return _writer.final(); + } + return EMPTY_BUFFER; + } + toJSON() { + const object = { + ...super.toJSON(), + idBlock: this.idBlock.toJSON(), + lenBlock: this.lenBlock.toJSON(), + valueBlock: this.valueBlock.toJSON(), + name: this.name, + optional: this.optional + }; + if (this.primitiveSchema) + object.primitiveSchema = this.primitiveSchema.toJSON(); + return object; + } + toString(encoding = "ascii") { + if (encoding === "ascii") { + return this.onAsciiEncoding(); + } + return pvtsutils.Convert.ToHex(this.toBER()); + } + onAsciiEncoding() { + return `${this.constructor.NAME} : ${pvtsutils.Convert.ToHex(this.valueBlock.valueBeforeDecodeView)}`; + } + isEqual(other) { + if (this === other) { + return true; + } + if (!(other instanceof this.constructor)) { + return false; + } + const thisRaw = this.toBER(); + const otherRaw = other.toBER(); + return isEqualBuffer(thisRaw, otherRaw); + } + }; + BaseBlock.NAME = "BaseBlock"; + BaseStringBlock = class extends BaseBlock { + constructor({ value = EMPTY_STRING, ...parameters } = {}, stringValueBlockType) { + super(parameters, stringValueBlockType); + if (value) { + this.fromString(value); + } + } + getValue() { + return this.valueBlock.value; + } + setValue(value) { + this.valueBlock.value = value; + } + fromBER(inputBuffer, inputOffset, inputLength) { + const resultOffset = this.valueBlock.fromBER(inputBuffer, inputOffset, this.lenBlock.isIndefiniteForm ? inputLength : this.lenBlock.length); + if (resultOffset === -1) { + this.error = this.valueBlock.error; + return resultOffset; + } + this.fromBuffer(this.valueBlock.valueHexView); + if (!this.idBlock.error.length) + this.blockLength += this.idBlock.blockLength; + if (!this.lenBlock.error.length) + this.blockLength += this.lenBlock.blockLength; + if (!this.valueBlock.error.length) + this.blockLength += this.valueBlock.blockLength; + return resultOffset; + } + onAsciiEncoding() { + return `${this.constructor.NAME} : '${this.valueBlock.value}'`; + } + }; + BaseStringBlock.NAME = "BaseStringBlock"; + LocalPrimitiveValueBlock = class extends HexBlock(ValueBlock) { + constructor({ isHexOnly = true, ...parameters } = {}) { + super(parameters); + this.isHexOnly = isHexOnly; + } + }; + LocalPrimitiveValueBlock.NAME = "PrimitiveValueBlock"; + Primitive = class extends BaseBlock { + constructor(parameters = {}) { + super(parameters, LocalPrimitiveValueBlock); + this.idBlock.isConstructed = false; + } + }; + _a$w = Primitive; + (() => { + typeStore.Primitive = _a$w; + })(); + Primitive.NAME = "PRIMITIVE"; + LocalConstructedValueBlock = class extends ValueBlock { + constructor({ value = [], isIndefiniteForm = false, ...parameters } = {}) { + super(parameters); + this.value = value; + this.isIndefiniteForm = isIndefiniteForm; + } + fromBER(inputBuffer, inputOffset, inputLength) { + const view = pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer); + if (!checkBufferParams(this, view, inputOffset, inputLength)) { + return -1; + } + this.valueBeforeDecodeView = view.subarray(inputOffset, inputOffset + inputLength); + if (this.valueBeforeDecodeView.length === 0) { + this.warnings.push("Zero buffer length"); + return inputOffset; + } + let currentOffset = inputOffset; + while (checkLen(this.isIndefiniteForm, inputLength) > 0) { + const returnObject = localFromBER(view, currentOffset, inputLength); + if (returnObject.offset === -1) { + this.error = returnObject.result.error; + this.warnings.concat(returnObject.result.warnings); + return -1; + } + currentOffset = returnObject.offset; + this.blockLength += returnObject.result.blockLength; + inputLength -= returnObject.result.blockLength; + this.value.push(returnObject.result); + if (this.isIndefiniteForm && returnObject.result.constructor.NAME === END_OF_CONTENT_NAME) { + break; + } + } + if (this.isIndefiniteForm) { + if (this.value[this.value.length - 1].constructor.NAME === END_OF_CONTENT_NAME) { + this.value.pop(); + } else { + this.warnings.push("No EndOfContent block encoded"); + } + } + return currentOffset; + } + toBER(sizeOnly, writer) { + const _writer = writer || new ViewWriter(); + for (let i = 0; i < this.value.length; i++) { + this.value[i].toBER(sizeOnly, _writer); + } + if (!writer) { + return _writer.final(); + } + return EMPTY_BUFFER; + } + toJSON() { + const object = { + ...super.toJSON(), + isIndefiniteForm: this.isIndefiniteForm, + value: [] + }; + for (const value of this.value) { + object.value.push(value.toJSON()); + } + return object; + } + }; + LocalConstructedValueBlock.NAME = "ConstructedValueBlock"; + Constructed = class extends BaseBlock { + constructor(parameters = {}) { + super(parameters, LocalConstructedValueBlock); + this.idBlock.isConstructed = true; + } + fromBER(inputBuffer, inputOffset, inputLength) { + this.valueBlock.isIndefiniteForm = this.lenBlock.isIndefiniteForm; + const resultOffset = this.valueBlock.fromBER(inputBuffer, inputOffset, this.lenBlock.isIndefiniteForm ? inputLength : this.lenBlock.length); + if (resultOffset === -1) { + this.error = this.valueBlock.error; + return resultOffset; + } + if (!this.idBlock.error.length) + this.blockLength += this.idBlock.blockLength; + if (!this.lenBlock.error.length) + this.blockLength += this.lenBlock.blockLength; + if (!this.valueBlock.error.length) + this.blockLength += this.valueBlock.blockLength; + return resultOffset; + } + onAsciiEncoding() { + const values = []; + for (const value of this.valueBlock.value) { + values.push(value.toString("ascii").split("\n").map((o) => ` ${o}`).join("\n")); + } + const blockName = this.idBlock.tagClass === 3 ? `[${this.idBlock.tagNumber}]` : this.constructor.NAME; + return values.length ? `${blockName} : +${values.join("\n")}` : `${blockName} :`; + } + }; + _a$v = Constructed; + (() => { + typeStore.Constructed = _a$v; + })(); + Constructed.NAME = "CONSTRUCTED"; + LocalEndOfContentValueBlock = class extends ValueBlock { + fromBER(inputBuffer, inputOffset, inputLength) { + return inputOffset; + } + toBER(sizeOnly) { + return EMPTY_BUFFER; + } + }; + LocalEndOfContentValueBlock.override = "EndOfContentValueBlock"; + EndOfContent = class extends BaseBlock { + constructor(parameters = {}) { + super(parameters, LocalEndOfContentValueBlock); + this.idBlock.tagClass = 1; + this.idBlock.tagNumber = 0; + } + }; + _a$u = EndOfContent; + (() => { + typeStore.EndOfContent = _a$u; + })(); + EndOfContent.NAME = END_OF_CONTENT_NAME; + Null = class extends BaseBlock { + constructor(parameters = {}) { + super(parameters, ValueBlock); + this.idBlock.tagClass = 1; + this.idBlock.tagNumber = 5; + } + fromBER(inputBuffer, inputOffset, inputLength) { + if (this.lenBlock.length > 0) + this.warnings.push("Non-zero length of value block for Null type"); + if (!this.idBlock.error.length) + this.blockLength += this.idBlock.blockLength; + if (!this.lenBlock.error.length) + this.blockLength += this.lenBlock.blockLength; + this.blockLength += inputLength; + if (inputOffset + inputLength > inputBuffer.byteLength) { + this.error = "End of input reached before message was fully decoded (inconsistent offset and length values)"; + return -1; + } + return inputOffset + inputLength; + } + toBER(sizeOnly, writer) { + const retBuf = new ArrayBuffer(2); + if (!sizeOnly) { + const retView = new Uint8Array(retBuf); + retView[0] = 5; + retView[1] = 0; + } + if (writer) { + writer.write(retBuf); + } + return retBuf; + } + onAsciiEncoding() { + return `${this.constructor.NAME}`; + } + }; + _a$t = Null; + (() => { + typeStore.Null = _a$t; + })(); + Null.NAME = "NULL"; + LocalBooleanValueBlock = class extends HexBlock(ValueBlock) { + constructor({ value, ...parameters } = {}) { + super(parameters); + if (parameters.valueHex) { + this.valueHexView = pvtsutils.BufferSourceConverter.toUint8Array(parameters.valueHex); + } else { + this.valueHexView = new Uint8Array(1); + } + if (value) { + this.value = value; + } + } + get value() { + for (const octet of this.valueHexView) { + if (octet > 0) { + return true; + } + } + return false; + } + set value(value) { + this.valueHexView[0] = value ? 255 : 0; + } + fromBER(inputBuffer, inputOffset, inputLength) { + const inputView = pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer); + if (!checkBufferParams(this, inputView, inputOffset, inputLength)) { + return -1; + } + this.valueHexView = inputView.subarray(inputOffset, inputOffset + inputLength); + if (inputLength > 1) + this.warnings.push("Boolean value encoded in more then 1 octet"); + this.isHexOnly = true; + utilDecodeTC.call(this); + this.blockLength = inputLength; + return inputOffset + inputLength; + } + toBER() { + return this.valueHexView.slice(); + } + toJSON() { + return { + ...super.toJSON(), + value: this.value + }; + } + }; + LocalBooleanValueBlock.NAME = "BooleanValueBlock"; + Boolean2 = class extends BaseBlock { + constructor(parameters = {}) { + super(parameters, LocalBooleanValueBlock); + this.idBlock.tagClass = 1; + this.idBlock.tagNumber = 1; + } + getValue() { + return this.valueBlock.value; + } + setValue(value) { + this.valueBlock.value = value; + } + onAsciiEncoding() { + return `${this.constructor.NAME} : ${this.getValue}`; + } + }; + _a$s = Boolean2; + (() => { + typeStore.Boolean = _a$s; + })(); + Boolean2.NAME = "BOOLEAN"; + LocalOctetStringValueBlock = class extends HexBlock(LocalConstructedValueBlock) { + constructor({ isConstructed = false, ...parameters } = {}) { + super(parameters); + this.isConstructed = isConstructed; + } + fromBER(inputBuffer, inputOffset, inputLength) { + let resultOffset = 0; + if (this.isConstructed) { + this.isHexOnly = false; + resultOffset = LocalConstructedValueBlock.prototype.fromBER.call(this, inputBuffer, inputOffset, inputLength); + if (resultOffset === -1) + return resultOffset; + for (let i = 0; i < this.value.length; i++) { + const currentBlockName = this.value[i].constructor.NAME; + if (currentBlockName === END_OF_CONTENT_NAME) { + if (this.isIndefiniteForm) + break; + else { + this.error = "EndOfContent is unexpected, OCTET STRING may consists of OCTET STRINGs only"; + return -1; + } + } + if (currentBlockName !== OCTET_STRING_NAME) { + this.error = "OCTET STRING may consists of OCTET STRINGs only"; + return -1; + } + } + } else { + this.isHexOnly = true; + resultOffset = super.fromBER(inputBuffer, inputOffset, inputLength); + this.blockLength = inputLength; + } + return resultOffset; + } + toBER(sizeOnly, writer) { + if (this.isConstructed) + return LocalConstructedValueBlock.prototype.toBER.call(this, sizeOnly, writer); + return sizeOnly ? new ArrayBuffer(this.valueHexView.byteLength) : this.valueHexView.slice().buffer; + } + toJSON() { + return { + ...super.toJSON(), + isConstructed: this.isConstructed + }; + } + }; + LocalOctetStringValueBlock.NAME = "OctetStringValueBlock"; + OctetString = class _OctetString extends BaseBlock { + constructor({ idBlock = {}, lenBlock = {}, ...parameters } = {}) { + var _b, _c; + (_b = parameters.isConstructed) !== null && _b !== void 0 ? _b : parameters.isConstructed = !!((_c = parameters.value) === null || _c === void 0 ? void 0 : _c.length); + super({ + idBlock: { + isConstructed: parameters.isConstructed, + ...idBlock + }, + lenBlock: { + ...lenBlock, + isIndefiniteForm: !!parameters.isIndefiniteForm + }, + ...parameters + }, LocalOctetStringValueBlock); + this.idBlock.tagClass = 1; + this.idBlock.tagNumber = 4; + } + fromBER(inputBuffer, inputOffset, inputLength) { + this.valueBlock.isConstructed = this.idBlock.isConstructed; + this.valueBlock.isIndefiniteForm = this.lenBlock.isIndefiniteForm; + if (inputLength === 0) { + if (this.idBlock.error.length === 0) + this.blockLength += this.idBlock.blockLength; + if (this.lenBlock.error.length === 0) + this.blockLength += this.lenBlock.blockLength; + return inputOffset; + } + if (!this.valueBlock.isConstructed) { + const view = inputBuffer instanceof ArrayBuffer ? new Uint8Array(inputBuffer) : inputBuffer; + const buf = view.subarray(inputOffset, inputOffset + inputLength); + try { + if (buf.byteLength) { + const asn = localFromBER(buf, 0, buf.byteLength); + if (asn.offset !== -1 && asn.offset === inputLength) { + this.valueBlock.value = [asn.result]; + } + } + } catch (e) { + } + } + return super.fromBER(inputBuffer, inputOffset, inputLength); + } + onAsciiEncoding() { + if (this.valueBlock.isConstructed || this.valueBlock.value && this.valueBlock.value.length) { + return Constructed.prototype.onAsciiEncoding.call(this); + } + return `${this.constructor.NAME} : ${pvtsutils.Convert.ToHex(this.valueBlock.valueHexView)}`; + } + getValue() { + if (!this.idBlock.isConstructed) { + return this.valueBlock.valueHexView.slice().buffer; + } + const array = []; + for (const content of this.valueBlock.value) { + if (content instanceof _OctetString) { + array.push(content.valueBlock.valueHexView); + } + } + return pvtsutils.BufferSourceConverter.concat(array); + } + }; + _a$r = OctetString; + (() => { + typeStore.OctetString = _a$r; + })(); + OctetString.NAME = OCTET_STRING_NAME; + LocalBitStringValueBlock = class extends HexBlock(LocalConstructedValueBlock) { + constructor({ unusedBits = 0, isConstructed = false, ...parameters } = {}) { + super(parameters); + this.unusedBits = unusedBits; + this.isConstructed = isConstructed; + this.blockLength = this.valueHexView.byteLength; + } + fromBER(inputBuffer, inputOffset, inputLength) { + if (!inputLength) { + return inputOffset; + } + let resultOffset = -1; + if (this.isConstructed) { + resultOffset = LocalConstructedValueBlock.prototype.fromBER.call(this, inputBuffer, inputOffset, inputLength); + if (resultOffset === -1) + return resultOffset; + for (const value of this.value) { + const currentBlockName = value.constructor.NAME; + if (currentBlockName === END_OF_CONTENT_NAME) { + if (this.isIndefiniteForm) + break; + else { + this.error = "EndOfContent is unexpected, BIT STRING may consists of BIT STRINGs only"; + return -1; + } + } + if (currentBlockName !== BIT_STRING_NAME) { + this.error = "BIT STRING may consists of BIT STRINGs only"; + return -1; + } + const valueBlock = value.valueBlock; + if (this.unusedBits > 0 && valueBlock.unusedBits > 0) { + this.error = 'Using of "unused bits" inside constructive BIT STRING allowed for least one only'; + return -1; + } + this.unusedBits = valueBlock.unusedBits; + } + return resultOffset; + } + const inputView = pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer); + if (!checkBufferParams(this, inputView, inputOffset, inputLength)) { + return -1; + } + const intBuffer = inputView.subarray(inputOffset, inputOffset + inputLength); + this.unusedBits = intBuffer[0]; + if (this.unusedBits > 7) { + this.error = "Unused bits for BitString must be in range 0-7"; + return -1; + } + if (!this.unusedBits) { + const buf = intBuffer.subarray(1); + try { + if (buf.byteLength) { + const asn = localFromBER(buf, 0, buf.byteLength); + if (asn.offset !== -1 && asn.offset === inputLength - 1) { + this.value = [asn.result]; + } + } + } catch (e) { + } + } + this.valueHexView = intBuffer.subarray(1); + this.blockLength = intBuffer.length; + return inputOffset + inputLength; + } + toBER(sizeOnly, writer) { + if (this.isConstructed) { + return LocalConstructedValueBlock.prototype.toBER.call(this, sizeOnly, writer); + } + if (sizeOnly) { + return new ArrayBuffer(this.valueHexView.byteLength + 1); + } + if (!this.valueHexView.byteLength) { + return EMPTY_BUFFER; + } + const retView = new Uint8Array(this.valueHexView.length + 1); + retView[0] = this.unusedBits; + retView.set(this.valueHexView, 1); + return retView.buffer; + } + toJSON() { + return { + ...super.toJSON(), + unusedBits: this.unusedBits, + isConstructed: this.isConstructed + }; + } + }; + LocalBitStringValueBlock.NAME = "BitStringValueBlock"; + BitString = class extends BaseBlock { + constructor({ idBlock = {}, lenBlock = {}, ...parameters } = {}) { + var _b, _c; + (_b = parameters.isConstructed) !== null && _b !== void 0 ? _b : parameters.isConstructed = !!((_c = parameters.value) === null || _c === void 0 ? void 0 : _c.length); + super({ + idBlock: { + isConstructed: parameters.isConstructed, + ...idBlock + }, + lenBlock: { + ...lenBlock, + isIndefiniteForm: !!parameters.isIndefiniteForm + }, + ...parameters + }, LocalBitStringValueBlock); + this.idBlock.tagClass = 1; + this.idBlock.tagNumber = 3; + } + fromBER(inputBuffer, inputOffset, inputLength) { + this.valueBlock.isConstructed = this.idBlock.isConstructed; + this.valueBlock.isIndefiniteForm = this.lenBlock.isIndefiniteForm; + return super.fromBER(inputBuffer, inputOffset, inputLength); + } + onAsciiEncoding() { + if (this.valueBlock.isConstructed || this.valueBlock.value && this.valueBlock.value.length) { + return Constructed.prototype.onAsciiEncoding.call(this); + } else { + const bits = []; + const valueHex = this.valueBlock.valueHexView; + for (const byte of valueHex) { + bits.push(byte.toString(2).padStart(8, "0")); + } + const bitsStr = bits.join(""); + return `${this.constructor.NAME} : ${bitsStr.substring(0, bitsStr.length - this.valueBlock.unusedBits)}`; + } + } + }; + _a$q = BitString; + (() => { + typeStore.BitString = _a$q; + })(); + BitString.NAME = BIT_STRING_NAME; + LocalIntegerValueBlock = class extends HexBlock(ValueBlock) { + constructor({ value, ...parameters } = {}) { + super(parameters); + this._valueDec = 0; + if (parameters.valueHex) { + this.setValueHex(); + } + if (value !== void 0) { + this.valueDec = value; + } + } + setValueHex() { + if (this.valueHexView.length >= 4) { + this.warnings.push("Too big Integer for decoding, hex only"); + this.isHexOnly = true; + this._valueDec = 0; + } else { + this.isHexOnly = false; + if (this.valueHexView.length > 0) { + this._valueDec = utilDecodeTC.call(this); + } + } + } + set valueDec(v) { + this._valueDec = v; + this.isHexOnly = false; + this.valueHexView = new Uint8Array(utilEncodeTC(v)); + } + get valueDec() { + return this._valueDec; + } + fromDER(inputBuffer, inputOffset, inputLength, expectedLength = 0) { + const offset = this.fromBER(inputBuffer, inputOffset, inputLength); + if (offset === -1) + return offset; + const view = this.valueHexView; + if (view[0] === 0 && (view[1] & 128) !== 0) { + this.valueHexView = view.subarray(1); + } else { + if (expectedLength !== 0) { + if (view.length < expectedLength) { + if (expectedLength - view.length > 1) + expectedLength = view.length + 1; + this.valueHexView = view.subarray(expectedLength - view.length); + } + } + } + return offset; + } + toDER(sizeOnly = false) { + const view = this.valueHexView; + switch (true) { + case (view[0] & 128) !== 0: + { + const updatedView = new Uint8Array(this.valueHexView.length + 1); + updatedView[0] = 0; + updatedView.set(view, 1); + this.valueHexView = updatedView; + } + break; + case (view[0] === 0 && (view[1] & 128) === 0): + { + this.valueHexView = this.valueHexView.subarray(1); + } + break; + } + return this.toBER(sizeOnly); + } + fromBER(inputBuffer, inputOffset, inputLength) { + const resultOffset = super.fromBER(inputBuffer, inputOffset, inputLength); + if (resultOffset === -1) { + return resultOffset; + } + this.setValueHex(); + return resultOffset; + } + toBER(sizeOnly) { + return sizeOnly ? new ArrayBuffer(this.valueHexView.length) : this.valueHexView.slice().buffer; + } + toJSON() { + return { + ...super.toJSON(), + valueDec: this.valueDec + }; + } + toString() { + const firstBit = this.valueHexView.length * 8 - 1; + let digits = new Uint8Array(this.valueHexView.length * 8 / 3); + let bitNumber = 0; + let currentByte; + const asn1View = this.valueHexView; + let result = ""; + let flag = false; + for (let byteNumber = asn1View.byteLength - 1; byteNumber >= 0; byteNumber--) { + currentByte = asn1View[byteNumber]; + for (let i = 0; i < 8; i++) { + if ((currentByte & 1) === 1) { + switch (bitNumber) { + case firstBit: + digits = viewSub(power2(bitNumber), digits); + result = "-"; + break; + default: + digits = viewAdd(digits, power2(bitNumber)); + } + } + bitNumber++; + currentByte >>= 1; + } + } + for (let i = 0; i < digits.length; i++) { + if (digits[i]) + flag = true; + if (flag) + result += digitsString.charAt(digits[i]); + } + if (flag === false) + result += digitsString.charAt(0); + return result; + } + }; + _a$p = LocalIntegerValueBlock; + LocalIntegerValueBlock.NAME = "IntegerValueBlock"; + (() => { + Object.defineProperty(_a$p.prototype, "valueHex", { + set: function(v) { + this.valueHexView = new Uint8Array(v); + this.setValueHex(); + }, + get: function() { + return this.valueHexView.slice().buffer; + } + }); + })(); + Integer = class _Integer extends BaseBlock { + constructor(parameters = {}) { + super(parameters, LocalIntegerValueBlock); + this.idBlock.tagClass = 1; + this.idBlock.tagNumber = 2; + } + toBigInt() { + assertBigInt(); + return BigInt(this.valueBlock.toString()); + } + static fromBigInt(value) { + assertBigInt(); + const bigIntValue = BigInt(value); + const writer = new ViewWriter(); + const hex = bigIntValue.toString(16).replace(/^-/, ""); + const view = new Uint8Array(pvtsutils.Convert.FromHex(hex)); + if (bigIntValue < 0) { + const first = new Uint8Array(view.length + (view[0] & 128 ? 1 : 0)); + first[0] |= 128; + const firstInt = BigInt(`0x${pvtsutils.Convert.ToHex(first)}`); + const secondInt = firstInt + bigIntValue; + const second = pvtsutils.BufferSourceConverter.toUint8Array(pvtsutils.Convert.FromHex(secondInt.toString(16))); + second[0] |= 128; + writer.write(second); + } else { + if (view[0] & 128) { + writer.write(new Uint8Array([0])); + } + writer.write(view); + } + const res = new _Integer({ + valueHex: writer.final() + }); + return res; + } + convertToDER() { + const integer = new _Integer({ valueHex: this.valueBlock.valueHexView }); + integer.valueBlock.toDER(); + return integer; + } + convertFromDER() { + return new _Integer({ + valueHex: this.valueBlock.valueHexView[0] === 0 ? this.valueBlock.valueHexView.subarray(1) : this.valueBlock.valueHexView + }); + } + onAsciiEncoding() { + return `${this.constructor.NAME} : ${this.valueBlock.toString()}`; + } + }; + _a$o = Integer; + (() => { + typeStore.Integer = _a$o; + })(); + Integer.NAME = "INTEGER"; + Enumerated = class extends Integer { + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; + this.idBlock.tagNumber = 10; + } + }; + _a$n = Enumerated; + (() => { + typeStore.Enumerated = _a$n; + })(); + Enumerated.NAME = "ENUMERATED"; + LocalSidValueBlock = class extends HexBlock(ValueBlock) { + constructor({ valueDec = -1, isFirstSid = false, ...parameters } = {}) { + super(parameters); + this.valueDec = valueDec; + this.isFirstSid = isFirstSid; + } + fromBER(inputBuffer, inputOffset, inputLength) { + if (!inputLength) { + return inputOffset; + } + const inputView = pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer); + if (!checkBufferParams(this, inputView, inputOffset, inputLength)) { + return -1; + } + const intBuffer = inputView.subarray(inputOffset, inputOffset + inputLength); + this.valueHexView = new Uint8Array(inputLength); + for (let i = 0; i < inputLength; i++) { + this.valueHexView[i] = intBuffer[i] & 127; + this.blockLength++; + if ((intBuffer[i] & 128) === 0) + break; + } + const tempView = new Uint8Array(this.blockLength); + for (let i = 0; i < this.blockLength; i++) { + tempView[i] = this.valueHexView[i]; + } + this.valueHexView = tempView; + if ((intBuffer[this.blockLength - 1] & 128) !== 0) { + this.error = "End of input reached before message was fully decoded"; + return -1; + } + if (this.valueHexView[0] === 0) + this.warnings.push("Needlessly long format of SID encoding"); + if (this.blockLength <= 8) + this.valueDec = utilFromBase(this.valueHexView, 7); + else { + this.isHexOnly = true; + this.warnings.push("Too big SID for decoding, hex only"); + } + return inputOffset + this.blockLength; + } + set valueBigInt(value) { + assertBigInt(); + let bits = BigInt(value).toString(2); + while (bits.length % 7) { + bits = "0" + bits; + } + const bytes = new Uint8Array(bits.length / 7); + for (let i = 0; i < bytes.length; i++) { + bytes[i] = parseInt(bits.slice(i * 7, i * 7 + 7), 2) + (i + 1 < bytes.length ? 128 : 0); + } + this.fromBER(bytes.buffer, 0, bytes.length); + } + toBER(sizeOnly) { + if (this.isHexOnly) { + if (sizeOnly) + return new ArrayBuffer(this.valueHexView.byteLength); + const curView = this.valueHexView; + const retView2 = new Uint8Array(this.blockLength); + for (let i = 0; i < this.blockLength - 1; i++) + retView2[i] = curView[i] | 128; + retView2[this.blockLength - 1] = curView[this.blockLength - 1]; + return retView2.buffer; + } + const encodedBuf = utilToBase(this.valueDec, 7); + if (encodedBuf.byteLength === 0) { + this.error = "Error during encoding SID value"; + return EMPTY_BUFFER; + } + const retView = new Uint8Array(encodedBuf.byteLength); + if (!sizeOnly) { + const encodedView = new Uint8Array(encodedBuf); + const len = encodedBuf.byteLength - 1; + for (let i = 0; i < len; i++) + retView[i] = encodedView[i] | 128; + retView[len] = encodedView[len]; + } + return retView; + } + toString() { + let result = ""; + if (this.isHexOnly) + result = pvtsutils.Convert.ToHex(this.valueHexView); + else { + if (this.isFirstSid) { + let sidValue = this.valueDec; + if (this.valueDec <= 39) + result = "0."; + else { + if (this.valueDec <= 79) { + result = "1."; + sidValue -= 40; + } else { + result = "2."; + sidValue -= 80; + } + } + result += sidValue.toString(); + } else + result = this.valueDec.toString(); + } + return result; + } + toJSON() { + return { + ...super.toJSON(), + valueDec: this.valueDec, + isFirstSid: this.isFirstSid + }; + } + }; + LocalSidValueBlock.NAME = "sidBlock"; + LocalObjectIdentifierValueBlock = class extends ValueBlock { + constructor({ value = EMPTY_STRING, ...parameters } = {}) { + super(parameters); + this.value = []; + if (value) { + this.fromString(value); + } + } + fromBER(inputBuffer, inputOffset, inputLength) { + let resultOffset = inputOffset; + while (inputLength > 0) { + const sidBlock = new LocalSidValueBlock(); + resultOffset = sidBlock.fromBER(inputBuffer, resultOffset, inputLength); + if (resultOffset === -1) { + this.blockLength = 0; + this.error = sidBlock.error; + return resultOffset; + } + if (this.value.length === 0) + sidBlock.isFirstSid = true; + this.blockLength += sidBlock.blockLength; + inputLength -= sidBlock.blockLength; + this.value.push(sidBlock); + } + return resultOffset; + } + toBER(sizeOnly) { + const retBuffers = []; + for (let i = 0; i < this.value.length; i++) { + const valueBuf = this.value[i].toBER(sizeOnly); + if (valueBuf.byteLength === 0) { + this.error = this.value[i].error; + return EMPTY_BUFFER; + } + retBuffers.push(valueBuf); + } + return concat(retBuffers); + } + fromString(string) { + this.value = []; + let pos1 = 0; + let pos2 = 0; + let sid = ""; + let flag = false; + do { + pos2 = string.indexOf(".", pos1); + if (pos2 === -1) + sid = string.substring(pos1); + else + sid = string.substring(pos1, pos2); + pos1 = pos2 + 1; + if (flag) { + const sidBlock = this.value[0]; + let plus = 0; + switch (sidBlock.valueDec) { + case 0: + break; + case 1: + plus = 40; + break; + case 2: + plus = 80; + break; + default: + this.value = []; + return; + } + const parsedSID = parseInt(sid, 10); + if (isNaN(parsedSID)) + return; + sidBlock.valueDec = parsedSID + plus; + flag = false; + } else { + const sidBlock = new LocalSidValueBlock(); + if (sid > Number.MAX_SAFE_INTEGER) { + assertBigInt(); + const sidValue = BigInt(sid); + sidBlock.valueBigInt = sidValue; + } else { + sidBlock.valueDec = parseInt(sid, 10); + if (isNaN(sidBlock.valueDec)) + return; + } + if (!this.value.length) { + sidBlock.isFirstSid = true; + flag = true; + } + this.value.push(sidBlock); + } + } while (pos2 !== -1); + } + toString() { + let result = ""; + let isHexOnly = false; + for (let i = 0; i < this.value.length; i++) { + isHexOnly = this.value[i].isHexOnly; + let sidStr = this.value[i].toString(); + if (i !== 0) + result = `${result}.`; + if (isHexOnly) { + sidStr = `{${sidStr}}`; + if (this.value[i].isFirstSid) + result = `2.{${sidStr} - 80}`; + else + result += sidStr; + } else + result += sidStr; + } + return result; + } + toJSON() { + const object = { + ...super.toJSON(), + value: this.toString(), + sidArray: [] + }; + for (let i = 0; i < this.value.length; i++) { + object.sidArray.push(this.value[i].toJSON()); + } + return object; + } + }; + LocalObjectIdentifierValueBlock.NAME = "ObjectIdentifierValueBlock"; + ObjectIdentifier = class extends BaseBlock { + constructor(parameters = {}) { + super(parameters, LocalObjectIdentifierValueBlock); + this.idBlock.tagClass = 1; + this.idBlock.tagNumber = 6; + } + getValue() { + return this.valueBlock.toString(); + } + setValue(value) { + this.valueBlock.fromString(value); + } + onAsciiEncoding() { + return `${this.constructor.NAME} : ${this.valueBlock.toString() || "empty"}`; + } + toJSON() { + return { + ...super.toJSON(), + value: this.getValue() + }; + } + }; + _a$m = ObjectIdentifier; + (() => { + typeStore.ObjectIdentifier = _a$m; + })(); + ObjectIdentifier.NAME = "OBJECT IDENTIFIER"; + LocalRelativeSidValueBlock = class extends HexBlock(LocalBaseBlock) { + constructor({ valueDec = 0, ...parameters } = {}) { + super(parameters); + this.valueDec = valueDec; + } + fromBER(inputBuffer, inputOffset, inputLength) { + if (inputLength === 0) + return inputOffset; + const inputView = pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer); + if (!checkBufferParams(this, inputView, inputOffset, inputLength)) + return -1; + const intBuffer = inputView.subarray(inputOffset, inputOffset + inputLength); + this.valueHexView = new Uint8Array(inputLength); + for (let i = 0; i < inputLength; i++) { + this.valueHexView[i] = intBuffer[i] & 127; + this.blockLength++; + if ((intBuffer[i] & 128) === 0) + break; + } + const tempView = new Uint8Array(this.blockLength); + for (let i = 0; i < this.blockLength; i++) + tempView[i] = this.valueHexView[i]; + this.valueHexView = tempView; + if ((intBuffer[this.blockLength - 1] & 128) !== 0) { + this.error = "End of input reached before message was fully decoded"; + return -1; + } + if (this.valueHexView[0] === 0) + this.warnings.push("Needlessly long format of SID encoding"); + if (this.blockLength <= 8) + this.valueDec = utilFromBase(this.valueHexView, 7); + else { + this.isHexOnly = true; + this.warnings.push("Too big SID for decoding, hex only"); + } + return inputOffset + this.blockLength; + } + toBER(sizeOnly) { + if (this.isHexOnly) { + if (sizeOnly) + return new ArrayBuffer(this.valueHexView.byteLength); + const curView = this.valueHexView; + const retView2 = new Uint8Array(this.blockLength); + for (let i = 0; i < this.blockLength - 1; i++) + retView2[i] = curView[i] | 128; + retView2[this.blockLength - 1] = curView[this.blockLength - 1]; + return retView2.buffer; + } + const encodedBuf = utilToBase(this.valueDec, 7); + if (encodedBuf.byteLength === 0) { + this.error = "Error during encoding SID value"; + return EMPTY_BUFFER; + } + const retView = new Uint8Array(encodedBuf.byteLength); + if (!sizeOnly) { + const encodedView = new Uint8Array(encodedBuf); + const len = encodedBuf.byteLength - 1; + for (let i = 0; i < len; i++) + retView[i] = encodedView[i] | 128; + retView[len] = encodedView[len]; + } + return retView.buffer; + } + toString() { + let result = ""; + if (this.isHexOnly) + result = pvtsutils.Convert.ToHex(this.valueHexView); + else { + result = this.valueDec.toString(); + } + return result; + } + toJSON() { + return { + ...super.toJSON(), + valueDec: this.valueDec + }; + } + }; + LocalRelativeSidValueBlock.NAME = "relativeSidBlock"; + LocalRelativeObjectIdentifierValueBlock = class extends ValueBlock { + constructor({ value = EMPTY_STRING, ...parameters } = {}) { + super(parameters); + this.value = []; + if (value) { + this.fromString(value); + } + } + fromBER(inputBuffer, inputOffset, inputLength) { + let resultOffset = inputOffset; + while (inputLength > 0) { + const sidBlock = new LocalRelativeSidValueBlock(); + resultOffset = sidBlock.fromBER(inputBuffer, resultOffset, inputLength); + if (resultOffset === -1) { + this.blockLength = 0; + this.error = sidBlock.error; + return resultOffset; + } + this.blockLength += sidBlock.blockLength; + inputLength -= sidBlock.blockLength; + this.value.push(sidBlock); + } + return resultOffset; + } + toBER(sizeOnly, writer) { + const retBuffers = []; + for (let i = 0; i < this.value.length; i++) { + const valueBuf = this.value[i].toBER(sizeOnly); + if (valueBuf.byteLength === 0) { + this.error = this.value[i].error; + return EMPTY_BUFFER; + } + retBuffers.push(valueBuf); + } + return concat(retBuffers); + } + fromString(string) { + this.value = []; + let pos1 = 0; + let pos2 = 0; + let sid = ""; + do { + pos2 = string.indexOf(".", pos1); + if (pos2 === -1) + sid = string.substring(pos1); + else + sid = string.substring(pos1, pos2); + pos1 = pos2 + 1; + const sidBlock = new LocalRelativeSidValueBlock(); + sidBlock.valueDec = parseInt(sid, 10); + if (isNaN(sidBlock.valueDec)) + return true; + this.value.push(sidBlock); + } while (pos2 !== -1); + return true; + } + toString() { + let result = ""; + let isHexOnly = false; + for (let i = 0; i < this.value.length; i++) { + isHexOnly = this.value[i].isHexOnly; + let sidStr = this.value[i].toString(); + if (i !== 0) + result = `${result}.`; + if (isHexOnly) { + sidStr = `{${sidStr}}`; + result += sidStr; + } else + result += sidStr; + } + return result; + } + toJSON() { + const object = { + ...super.toJSON(), + value: this.toString(), + sidArray: [] + }; + for (let i = 0; i < this.value.length; i++) + object.sidArray.push(this.value[i].toJSON()); + return object; + } + }; + LocalRelativeObjectIdentifierValueBlock.NAME = "RelativeObjectIdentifierValueBlock"; + RelativeObjectIdentifier = class extends BaseBlock { + constructor(parameters = {}) { + super(parameters, LocalRelativeObjectIdentifierValueBlock); + this.idBlock.tagClass = 1; + this.idBlock.tagNumber = 13; + } + getValue() { + return this.valueBlock.toString(); + } + setValue(value) { + this.valueBlock.fromString(value); + } + onAsciiEncoding() { + return `${this.constructor.NAME} : ${this.valueBlock.toString() || "empty"}`; + } + toJSON() { + return { + ...super.toJSON(), + value: this.getValue() + }; + } + }; + _a$l = RelativeObjectIdentifier; + (() => { + typeStore.RelativeObjectIdentifier = _a$l; + })(); + RelativeObjectIdentifier.NAME = "RelativeObjectIdentifier"; + Sequence = class extends Constructed { + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; + this.idBlock.tagNumber = 16; + } + }; + _a$k = Sequence; + (() => { + typeStore.Sequence = _a$k; + })(); + Sequence.NAME = "SEQUENCE"; + Set2 = class extends Constructed { + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; + this.idBlock.tagNumber = 17; + } + }; + _a$j = Set2; + (() => { + typeStore.Set = _a$j; + })(); + Set2.NAME = "SET"; + LocalStringValueBlock = class extends HexBlock(ValueBlock) { + constructor({ ...parameters } = {}) { + super(parameters); + this.isHexOnly = true; + this.value = EMPTY_STRING; + } + toJSON() { + return { + ...super.toJSON(), + value: this.value + }; + } + }; + LocalStringValueBlock.NAME = "StringValueBlock"; + LocalSimpleStringValueBlock = class extends LocalStringValueBlock { + }; + LocalSimpleStringValueBlock.NAME = "SimpleStringValueBlock"; + LocalSimpleStringBlock = class extends BaseStringBlock { + constructor({ ...parameters } = {}) { + super(parameters, LocalSimpleStringValueBlock); + } + fromBuffer(inputBuffer) { + this.valueBlock.value = String.fromCharCode.apply(null, pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer)); + } + fromString(inputString) { + const strLen = inputString.length; + const view = this.valueBlock.valueHexView = new Uint8Array(strLen); + for (let i = 0; i < strLen; i++) + view[i] = inputString.charCodeAt(i); + this.valueBlock.value = inputString; + } + }; + LocalSimpleStringBlock.NAME = "SIMPLE STRING"; + LocalUtf8StringValueBlock = class extends LocalSimpleStringBlock { + fromBuffer(inputBuffer) { + this.valueBlock.valueHexView = pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer); + try { + this.valueBlock.value = pvtsutils.Convert.ToUtf8String(inputBuffer); + } catch (ex) { + this.warnings.push(`Error during "decodeURIComponent": ${ex}, using raw string`); + this.valueBlock.value = pvtsutils.Convert.ToBinary(inputBuffer); + } + } + fromString(inputString) { + this.valueBlock.valueHexView = new Uint8Array(pvtsutils.Convert.FromUtf8String(inputString)); + this.valueBlock.value = inputString; + } + }; + LocalUtf8StringValueBlock.NAME = "Utf8StringValueBlock"; + Utf8String = class extends LocalUtf8StringValueBlock { + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; + this.idBlock.tagNumber = 12; + } + }; + _a$i = Utf8String; + (() => { + typeStore.Utf8String = _a$i; + })(); + Utf8String.NAME = "UTF8String"; + LocalBmpStringValueBlock = class extends LocalSimpleStringBlock { + fromBuffer(inputBuffer) { + this.valueBlock.value = pvtsutils.Convert.ToUtf16String(inputBuffer); + this.valueBlock.valueHexView = pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer); + } + fromString(inputString) { + this.valueBlock.value = inputString; + this.valueBlock.valueHexView = new Uint8Array(pvtsutils.Convert.FromUtf16String(inputString)); + } + }; + LocalBmpStringValueBlock.NAME = "BmpStringValueBlock"; + BmpString = class extends LocalBmpStringValueBlock { + constructor({ ...parameters } = {}) { + super(parameters); + this.idBlock.tagClass = 1; + this.idBlock.tagNumber = 30; + } + }; + _a$h = BmpString; + (() => { + typeStore.BmpString = _a$h; + })(); + BmpString.NAME = "BMPString"; + LocalUniversalStringValueBlock = class extends LocalSimpleStringBlock { + fromBuffer(inputBuffer) { + const copyBuffer = ArrayBuffer.isView(inputBuffer) ? inputBuffer.slice().buffer : inputBuffer.slice(0); + const valueView = new Uint8Array(copyBuffer); + for (let i = 0; i < valueView.length; i += 4) { + valueView[i] = valueView[i + 3]; + valueView[i + 1] = valueView[i + 2]; + valueView[i + 2] = 0; + valueView[i + 3] = 0; + } + this.valueBlock.value = String.fromCharCode.apply(null, new Uint32Array(copyBuffer)); + } + fromString(inputString) { + const strLength = inputString.length; + const valueHexView = this.valueBlock.valueHexView = new Uint8Array(strLength * 4); + for (let i = 0; i < strLength; i++) { + const codeBuf = utilToBase(inputString.charCodeAt(i), 8); + const codeView = new Uint8Array(codeBuf); + if (codeView.length > 4) + continue; + const dif = 4 - codeView.length; + for (let j = codeView.length - 1; j >= 0; j--) + valueHexView[i * 4 + j + dif] = codeView[j]; + } + this.valueBlock.value = inputString; + } + }; + LocalUniversalStringValueBlock.NAME = "UniversalStringValueBlock"; + UniversalString = class extends LocalUniversalStringValueBlock { + constructor({ ...parameters } = {}) { + super(parameters); + this.idBlock.tagClass = 1; + this.idBlock.tagNumber = 28; + } + }; + _a$g = UniversalString; + (() => { + typeStore.UniversalString = _a$g; + })(); + UniversalString.NAME = "UniversalString"; + NumericString = class extends LocalSimpleStringBlock { + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; + this.idBlock.tagNumber = 18; + } + }; + _a$f = NumericString; + (() => { + typeStore.NumericString = _a$f; + })(); + NumericString.NAME = "NumericString"; + PrintableString = class extends LocalSimpleStringBlock { + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; + this.idBlock.tagNumber = 19; + } + }; + _a$e = PrintableString; + (() => { + typeStore.PrintableString = _a$e; + })(); + PrintableString.NAME = "PrintableString"; + TeletexString = class extends LocalSimpleStringBlock { + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; + this.idBlock.tagNumber = 20; + } + }; + _a$d = TeletexString; + (() => { + typeStore.TeletexString = _a$d; + })(); + TeletexString.NAME = "TeletexString"; + VideotexString = class extends LocalSimpleStringBlock { + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; + this.idBlock.tagNumber = 21; + } + }; + _a$c = VideotexString; + (() => { + typeStore.VideotexString = _a$c; + })(); + VideotexString.NAME = "VideotexString"; + IA5String = class extends LocalSimpleStringBlock { + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; + this.idBlock.tagNumber = 22; + } + }; + _a$b = IA5String; + (() => { + typeStore.IA5String = _a$b; + })(); + IA5String.NAME = "IA5String"; + GraphicString = class extends LocalSimpleStringBlock { + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; + this.idBlock.tagNumber = 25; + } + }; + _a$a = GraphicString; + (() => { + typeStore.GraphicString = _a$a; + })(); + GraphicString.NAME = "GraphicString"; + VisibleString = class extends LocalSimpleStringBlock { + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; + this.idBlock.tagNumber = 26; + } + }; + _a$9 = VisibleString; + (() => { + typeStore.VisibleString = _a$9; + })(); + VisibleString.NAME = "VisibleString"; + GeneralString = class extends LocalSimpleStringBlock { + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; + this.idBlock.tagNumber = 27; + } + }; + _a$8 = GeneralString; + (() => { + typeStore.GeneralString = _a$8; + })(); + GeneralString.NAME = "GeneralString"; + CharacterString = class extends LocalSimpleStringBlock { + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; + this.idBlock.tagNumber = 29; + } + }; + _a$7 = CharacterString; + (() => { + typeStore.CharacterString = _a$7; + })(); + CharacterString.NAME = "CharacterString"; + UTCTime = class extends VisibleString { + constructor({ value, valueDate, ...parameters } = {}) { + super(parameters); + this.year = 0; + this.month = 0; + this.day = 0; + this.hour = 0; + this.minute = 0; + this.second = 0; + if (value) { + this.fromString(value); + this.valueBlock.valueHexView = new Uint8Array(value.length); + for (let i = 0; i < value.length; i++) + this.valueBlock.valueHexView[i] = value.charCodeAt(i); + } + if (valueDate) { + this.fromDate(valueDate); + this.valueBlock.valueHexView = new Uint8Array(this.toBuffer()); + } + this.idBlock.tagClass = 1; + this.idBlock.tagNumber = 23; + } + fromBuffer(inputBuffer) { + this.fromString(String.fromCharCode.apply(null, pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer))); + } + toBuffer() { + const str = this.toString(); + const buffer = new ArrayBuffer(str.length); + const view = new Uint8Array(buffer); + for (let i = 0; i < str.length; i++) + view[i] = str.charCodeAt(i); + return buffer; + } + fromDate(inputDate) { + this.year = inputDate.getUTCFullYear(); + this.month = inputDate.getUTCMonth() + 1; + this.day = inputDate.getUTCDate(); + this.hour = inputDate.getUTCHours(); + this.minute = inputDate.getUTCMinutes(); + this.second = inputDate.getUTCSeconds(); + } + toDate() { + return new Date(Date.UTC(this.year, this.month - 1, this.day, this.hour, this.minute, this.second)); + } + fromString(inputString) { + const parser = /(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})Z/ig; + const parserArray = parser.exec(inputString); + if (parserArray === null) { + this.error = "Wrong input string for conversion"; + return; + } + const year = parseInt(parserArray[1], 10); + if (year >= 50) + this.year = 1900 + year; + else + this.year = 2e3 + year; + this.month = parseInt(parserArray[2], 10); + this.day = parseInt(parserArray[3], 10); + this.hour = parseInt(parserArray[4], 10); + this.minute = parseInt(parserArray[5], 10); + this.second = parseInt(parserArray[6], 10); + } + toString(encoding = "iso") { + if (encoding === "iso") { + const outputArray = new Array(7); + outputArray[0] = padNumber(this.year < 2e3 ? this.year - 1900 : this.year - 2e3, 2); + outputArray[1] = padNumber(this.month, 2); + outputArray[2] = padNumber(this.day, 2); + outputArray[3] = padNumber(this.hour, 2); + outputArray[4] = padNumber(this.minute, 2); + outputArray[5] = padNumber(this.second, 2); + outputArray[6] = "Z"; + return outputArray.join(""); + } + return super.toString(encoding); + } + onAsciiEncoding() { + return `${this.constructor.NAME} : ${this.toDate().toISOString()}`; + } + toJSON() { + return { + ...super.toJSON(), + year: this.year, + month: this.month, + day: this.day, + hour: this.hour, + minute: this.minute, + second: this.second + }; + } + }; + _a$6 = UTCTime; + (() => { + typeStore.UTCTime = _a$6; + })(); + UTCTime.NAME = "UTCTime"; + GeneralizedTime = class extends UTCTime { + constructor(parameters = {}) { + var _b; + super(parameters); + (_b = this.millisecond) !== null && _b !== void 0 ? _b : this.millisecond = 0; + this.idBlock.tagClass = 1; + this.idBlock.tagNumber = 24; + } + fromDate(inputDate) { + super.fromDate(inputDate); + this.millisecond = inputDate.getUTCMilliseconds(); + } + toDate() { + return new Date(Date.UTC(this.year, this.month - 1, this.day, this.hour, this.minute, this.second, this.millisecond)); + } + fromString(inputString) { + let isUTC = false; + let timeString = ""; + let dateTimeString = ""; + let fractionPart = 0; + let parser; + let hourDifference = 0; + let minuteDifference = 0; + if (inputString[inputString.length - 1] === "Z") { + timeString = inputString.substring(0, inputString.length - 1); + isUTC = true; + } else { + const number = new Number(inputString[inputString.length - 1]); + if (isNaN(number.valueOf())) + throw new Error("Wrong input string for conversion"); + timeString = inputString; + } + if (isUTC) { + if (timeString.indexOf("+") !== -1) + throw new Error("Wrong input string for conversion"); + if (timeString.indexOf("-") !== -1) + throw new Error("Wrong input string for conversion"); + } else { + let multiplier = 1; + let differencePosition = timeString.indexOf("+"); + let differenceString = ""; + if (differencePosition === -1) { + differencePosition = timeString.indexOf("-"); + multiplier = -1; + } + if (differencePosition !== -1) { + differenceString = timeString.substring(differencePosition + 1); + timeString = timeString.substring(0, differencePosition); + if (differenceString.length !== 2 && differenceString.length !== 4) + throw new Error("Wrong input string for conversion"); + let number = parseInt(differenceString.substring(0, 2), 10); + if (isNaN(number.valueOf())) + throw new Error("Wrong input string for conversion"); + hourDifference = multiplier * number; + if (differenceString.length === 4) { + number = parseInt(differenceString.substring(2, 4), 10); + if (isNaN(number.valueOf())) + throw new Error("Wrong input string for conversion"); + minuteDifference = multiplier * number; + } + } + } + let fractionPointPosition = timeString.indexOf("."); + if (fractionPointPosition === -1) + fractionPointPosition = timeString.indexOf(","); + if (fractionPointPosition !== -1) { + const fractionPartCheck = new Number(`0${timeString.substring(fractionPointPosition)}`); + if (isNaN(fractionPartCheck.valueOf())) + throw new Error("Wrong input string for conversion"); + fractionPart = fractionPartCheck.valueOf(); + dateTimeString = timeString.substring(0, fractionPointPosition); + } else + dateTimeString = timeString; + switch (true) { + case dateTimeString.length === 8: + parser = /(\d{4})(\d{2})(\d{2})/ig; + if (fractionPointPosition !== -1) + throw new Error("Wrong input string for conversion"); + break; + case dateTimeString.length === 10: + parser = /(\d{4})(\d{2})(\d{2})(\d{2})/ig; + if (fractionPointPosition !== -1) { + let fractionResult = 60 * fractionPart; + this.minute = Math.floor(fractionResult); + fractionResult = 60 * (fractionResult - this.minute); + this.second = Math.floor(fractionResult); + fractionResult = 1e3 * (fractionResult - this.second); + this.millisecond = Math.floor(fractionResult); + } + break; + case dateTimeString.length === 12: + parser = /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})/ig; + if (fractionPointPosition !== -1) { + let fractionResult = 60 * fractionPart; + this.second = Math.floor(fractionResult); + fractionResult = 1e3 * (fractionResult - this.second); + this.millisecond = Math.floor(fractionResult); + } + break; + case dateTimeString.length === 14: + parser = /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/ig; + if (fractionPointPosition !== -1) { + const fractionResult = 1e3 * fractionPart; + this.millisecond = Math.floor(fractionResult); + } + break; + default: + throw new Error("Wrong input string for conversion"); + } + const parserArray = parser.exec(dateTimeString); + if (parserArray === null) + throw new Error("Wrong input string for conversion"); + for (let j = 1; j < parserArray.length; j++) { + switch (j) { + case 1: + this.year = parseInt(parserArray[j], 10); + break; + case 2: + this.month = parseInt(parserArray[j], 10); + break; + case 3: + this.day = parseInt(parserArray[j], 10); + break; + case 4: + this.hour = parseInt(parserArray[j], 10) + hourDifference; + break; + case 5: + this.minute = parseInt(parserArray[j], 10) + minuteDifference; + break; + case 6: + this.second = parseInt(parserArray[j], 10); + break; + default: + throw new Error("Wrong input string for conversion"); + } + } + if (isUTC === false) { + const tempDate = new Date(this.year, this.month, this.day, this.hour, this.minute, this.second, this.millisecond); + this.year = tempDate.getUTCFullYear(); + this.month = tempDate.getUTCMonth(); + this.day = tempDate.getUTCDay(); + this.hour = tempDate.getUTCHours(); + this.minute = tempDate.getUTCMinutes(); + this.second = tempDate.getUTCSeconds(); + this.millisecond = tempDate.getUTCMilliseconds(); + } + } + toString(encoding = "iso") { + if (encoding === "iso") { + const outputArray = []; + outputArray.push(padNumber(this.year, 4)); + outputArray.push(padNumber(this.month, 2)); + outputArray.push(padNumber(this.day, 2)); + outputArray.push(padNumber(this.hour, 2)); + outputArray.push(padNumber(this.minute, 2)); + outputArray.push(padNumber(this.second, 2)); + if (this.millisecond !== 0) { + outputArray.push("."); + outputArray.push(padNumber(this.millisecond, 3)); + } + outputArray.push("Z"); + return outputArray.join(""); + } + return super.toString(encoding); + } + toJSON() { + return { + ...super.toJSON(), + millisecond: this.millisecond + }; + } + }; + _a$5 = GeneralizedTime; + (() => { + typeStore.GeneralizedTime = _a$5; + })(); + GeneralizedTime.NAME = "GeneralizedTime"; + DATE = class extends Utf8String { + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; + this.idBlock.tagNumber = 31; + } + }; + _a$4 = DATE; + (() => { + typeStore.DATE = _a$4; + })(); + DATE.NAME = "DATE"; + TimeOfDay = class extends Utf8String { + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; + this.idBlock.tagNumber = 32; + } + }; + _a$3 = TimeOfDay; + (() => { + typeStore.TimeOfDay = _a$3; + })(); + TimeOfDay.NAME = "TimeOfDay"; + DateTime = class extends Utf8String { + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; + this.idBlock.tagNumber = 33; + } + }; + _a$2 = DateTime; + (() => { + typeStore.DateTime = _a$2; + })(); + DateTime.NAME = "DateTime"; + Duration = class extends Utf8String { + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; + this.idBlock.tagNumber = 34; + } + }; + _a$1 = Duration; + (() => { + typeStore.Duration = _a$1; + })(); + Duration.NAME = "Duration"; + TIME = class extends Utf8String { + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; + this.idBlock.tagNumber = 14; + } + }; + _a = TIME; + (() => { + typeStore.TIME = _a; + })(); + TIME.NAME = "TIME"; + Any = class { + constructor({ name = EMPTY_STRING, optional = false } = {}) { + this.name = name; + this.optional = optional; + } + }; + Choice = class extends Any { + constructor({ value = [], ...parameters } = {}) { + super(parameters); + this.value = value; + } + }; + Repeated = class extends Any { + constructor({ value = new Any(), local = false, ...parameters } = {}) { + super(parameters); + this.value = value; + this.local = local; + } + }; + RawData = class { + constructor({ data = EMPTY_VIEW } = {}) { + this.dataView = pvtsutils.BufferSourceConverter.toUint8Array(data); + } + get data() { + return this.dataView.slice().buffer; + } + set data(value) { + this.dataView = pvtsutils.BufferSourceConverter.toUint8Array(value); + } + fromBER(inputBuffer, inputOffset, inputLength) { + const endLength = inputOffset + inputLength; + this.dataView = pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer).subarray(inputOffset, endLength); + return endLength; + } + toBER(sizeOnly) { + return this.dataView.slice().buffer; + } + }; + } + }); + + // node_modules/.pnpm/@peculiar+asn1-schema@2.3.8/node_modules/@peculiar/asn1-schema/build/es2015/enums.js + var AsnTypeTypes, AsnPropTypes; + var init_enums = __esm({ + "node_modules/.pnpm/@peculiar+asn1-schema@2.3.8/node_modules/@peculiar/asn1-schema/build/es2015/enums.js"() { + (function(AsnTypeTypes2) { + AsnTypeTypes2[AsnTypeTypes2["Sequence"] = 0] = "Sequence"; + AsnTypeTypes2[AsnTypeTypes2["Set"] = 1] = "Set"; + AsnTypeTypes2[AsnTypeTypes2["Choice"] = 2] = "Choice"; + })(AsnTypeTypes || (AsnTypeTypes = {})); + (function(AsnPropTypes2) { + AsnPropTypes2[AsnPropTypes2["Any"] = 1] = "Any"; + AsnPropTypes2[AsnPropTypes2["Boolean"] = 2] = "Boolean"; + AsnPropTypes2[AsnPropTypes2["OctetString"] = 3] = "OctetString"; + AsnPropTypes2[AsnPropTypes2["BitString"] = 4] = "BitString"; + AsnPropTypes2[AsnPropTypes2["Integer"] = 5] = "Integer"; + AsnPropTypes2[AsnPropTypes2["Enumerated"] = 6] = "Enumerated"; + AsnPropTypes2[AsnPropTypes2["ObjectIdentifier"] = 7] = "ObjectIdentifier"; + AsnPropTypes2[AsnPropTypes2["Utf8String"] = 8] = "Utf8String"; + AsnPropTypes2[AsnPropTypes2["BmpString"] = 9] = "BmpString"; + AsnPropTypes2[AsnPropTypes2["UniversalString"] = 10] = "UniversalString"; + AsnPropTypes2[AsnPropTypes2["NumericString"] = 11] = "NumericString"; + AsnPropTypes2[AsnPropTypes2["PrintableString"] = 12] = "PrintableString"; + AsnPropTypes2[AsnPropTypes2["TeletexString"] = 13] = "TeletexString"; + AsnPropTypes2[AsnPropTypes2["VideotexString"] = 14] = "VideotexString"; + AsnPropTypes2[AsnPropTypes2["IA5String"] = 15] = "IA5String"; + AsnPropTypes2[AsnPropTypes2["GraphicString"] = 16] = "GraphicString"; + AsnPropTypes2[AsnPropTypes2["VisibleString"] = 17] = "VisibleString"; + AsnPropTypes2[AsnPropTypes2["GeneralString"] = 18] = "GeneralString"; + AsnPropTypes2[AsnPropTypes2["CharacterString"] = 19] = "CharacterString"; + AsnPropTypes2[AsnPropTypes2["UTCTime"] = 20] = "UTCTime"; + AsnPropTypes2[AsnPropTypes2["GeneralizedTime"] = 21] = "GeneralizedTime"; + AsnPropTypes2[AsnPropTypes2["DATE"] = 22] = "DATE"; + AsnPropTypes2[AsnPropTypes2["TimeOfDay"] = 23] = "TimeOfDay"; + AsnPropTypes2[AsnPropTypes2["DateTime"] = 24] = "DateTime"; + AsnPropTypes2[AsnPropTypes2["Duration"] = 25] = "Duration"; + AsnPropTypes2[AsnPropTypes2["TIME"] = 26] = "TIME"; + AsnPropTypes2[AsnPropTypes2["Null"] = 27] = "Null"; + })(AsnPropTypes || (AsnPropTypes = {})); + } + }); + + // node_modules/.pnpm/@peculiar+asn1-schema@2.3.8/node_modules/@peculiar/asn1-schema/build/es2015/types/bit_string.js + var import_pvtsutils; + var init_bit_string = __esm({ + "node_modules/.pnpm/@peculiar+asn1-schema@2.3.8/node_modules/@peculiar/asn1-schema/build/es2015/types/bit_string.js"() { + init_index_es(); + import_pvtsutils = __toESM(require_build()); + } + }); + + // node_modules/.pnpm/@peculiar+asn1-schema@2.3.8/node_modules/@peculiar/asn1-schema/build/es2015/types/octet_string.js + var import_pvtsutils2; + var init_octet_string = __esm({ + "node_modules/.pnpm/@peculiar+asn1-schema@2.3.8/node_modules/@peculiar/asn1-schema/build/es2015/types/octet_string.js"() { + init_index_es(); + import_pvtsutils2 = __toESM(require_build()); + } + }); + + // node_modules/.pnpm/@peculiar+asn1-schema@2.3.8/node_modules/@peculiar/asn1-schema/build/es2015/types/index.js + var init_types = __esm({ + "node_modules/.pnpm/@peculiar+asn1-schema@2.3.8/node_modules/@peculiar/asn1-schema/build/es2015/types/index.js"() { + init_bit_string(); + init_octet_string(); + } + }); + + // node_modules/.pnpm/@peculiar+asn1-schema@2.3.8/node_modules/@peculiar/asn1-schema/build/es2015/converters.js + function createStringConverter(Asn1Type) { + return { + fromASN: (value) => value.valueBlock.value, + toASN: (value) => new Asn1Type({ value }) + }; + } + function defaultConverter(type) { + switch (type) { + case AsnPropTypes.Any: + return AsnAnyConverter; + case AsnPropTypes.BitString: + return AsnBitStringConverter; + case AsnPropTypes.BmpString: + return AsnBmpStringConverter; + case AsnPropTypes.Boolean: + return AsnBooleanConverter; + case AsnPropTypes.CharacterString: + return AsnCharacterStringConverter; + case AsnPropTypes.Enumerated: + return AsnEnumeratedConverter; + case AsnPropTypes.GeneralString: + return AsnGeneralStringConverter; + case AsnPropTypes.GeneralizedTime: + return AsnGeneralizedTimeConverter; + case AsnPropTypes.GraphicString: + return AsnGraphicStringConverter; + case AsnPropTypes.IA5String: + return AsnIA5StringConverter; + case AsnPropTypes.Integer: + return AsnIntegerConverter; + case AsnPropTypes.Null: + return AsnNullConverter; + case AsnPropTypes.NumericString: + return AsnNumericStringConverter; + case AsnPropTypes.ObjectIdentifier: + return AsnObjectIdentifierConverter; + case AsnPropTypes.OctetString: + return AsnOctetStringConverter; + case AsnPropTypes.PrintableString: + return AsnPrintableStringConverter; + case AsnPropTypes.TeletexString: + return AsnTeletexStringConverter; + case AsnPropTypes.UTCTime: + return AsnUTCTimeConverter; + case AsnPropTypes.UniversalString: + return AsnUniversalStringConverter; + case AsnPropTypes.Utf8String: + return AsnUtf8StringConverter; + case AsnPropTypes.VideotexString: + return AsnVideotexStringConverter; + case AsnPropTypes.VisibleString: + return AsnVisibleStringConverter; + default: + return null; + } + } + var AsnAnyConverter, AsnIntegerConverter, AsnEnumeratedConverter, AsnBitStringConverter, AsnObjectIdentifierConverter, AsnBooleanConverter, AsnOctetStringConverter, AsnUtf8StringConverter, AsnBmpStringConverter, AsnUniversalStringConverter, AsnNumericStringConverter, AsnPrintableStringConverter, AsnTeletexStringConverter, AsnVideotexStringConverter, AsnIA5StringConverter, AsnGraphicStringConverter, AsnVisibleStringConverter, AsnGeneralStringConverter, AsnCharacterStringConverter, AsnUTCTimeConverter, AsnGeneralizedTimeConverter, AsnNullConverter; + var init_converters = __esm({ + "node_modules/.pnpm/@peculiar+asn1-schema@2.3.8/node_modules/@peculiar/asn1-schema/build/es2015/converters.js"() { + init_index_es(); + init_enums(); + init_types(); + AsnAnyConverter = { + fromASN: (value) => value instanceof Null ? null : value.valueBeforeDecodeView, + toASN: (value) => { + if (value === null) { + return new Null(); + } + const schema = fromBER(value); + if (schema.result.error) { + throw new Error(schema.result.error); + } + return schema.result; + } + }; + AsnIntegerConverter = { + fromASN: (value) => value.valueBlock.valueHexView.byteLength >= 4 ? value.valueBlock.toString() : value.valueBlock.valueDec, + toASN: (value) => new Integer({ value: +value }) + }; + AsnEnumeratedConverter = { + fromASN: (value) => value.valueBlock.valueDec, + toASN: (value) => new Enumerated({ value }) + }; + AsnBitStringConverter = { + fromASN: (value) => value.valueBlock.valueHexView, + toASN: (value) => new BitString({ valueHex: value }) + }; + AsnObjectIdentifierConverter = { + fromASN: (value) => value.valueBlock.toString(), + toASN: (value) => new ObjectIdentifier({ value }) + }; + AsnBooleanConverter = { + fromASN: (value) => value.valueBlock.value, + toASN: (value) => new Boolean2({ value }) + }; + AsnOctetStringConverter = { + fromASN: (value) => value.valueBlock.valueHexView, + toASN: (value) => new OctetString({ valueHex: value }) + }; + AsnUtf8StringConverter = createStringConverter(Utf8String); + AsnBmpStringConverter = createStringConverter(BmpString); + AsnUniversalStringConverter = createStringConverter(UniversalString); + AsnNumericStringConverter = createStringConverter(NumericString); + AsnPrintableStringConverter = createStringConverter(PrintableString); + AsnTeletexStringConverter = createStringConverter(TeletexString); + AsnVideotexStringConverter = createStringConverter(VideotexString); + AsnIA5StringConverter = createStringConverter(IA5String); + AsnGraphicStringConverter = createStringConverter(GraphicString); + AsnVisibleStringConverter = createStringConverter(VisibleString); + AsnGeneralStringConverter = createStringConverter(GeneralString); + AsnCharacterStringConverter = createStringConverter(CharacterString); + AsnUTCTimeConverter = { + fromASN: (value) => value.toDate(), + toASN: (value) => new UTCTime({ valueDate: value }) + }; + AsnGeneralizedTimeConverter = { + fromASN: (value) => value.toDate(), + toASN: (value) => new GeneralizedTime({ valueDate: value }) + }; + AsnNullConverter = { + fromASN: () => null, + toASN: () => { + return new Null(); + } + }; + } + }); + + // node_modules/.pnpm/@peculiar+asn1-schema@2.3.8/node_modules/@peculiar/asn1-schema/build/es2015/helper.js + function isConvertible(target) { + if (typeof target === "function" && target.prototype) { + if (target.prototype.toASN && target.prototype.fromASN) { + return true; + } else { + return isConvertible(target.prototype); + } + } else { + return !!(target && typeof target === "object" && "toASN" in target && "fromASN" in target); + } + } + function isTypeOfArray(target) { + var _a2; + if (target) { + const proto = Object.getPrototypeOf(target); + if (((_a2 = proto === null || proto === void 0 ? void 0 : proto.prototype) === null || _a2 === void 0 ? void 0 : _a2.constructor) === Array) { + return true; + } + return isTypeOfArray(proto); + } + return false; + } + function isArrayEqual(bytes1, bytes2) { + if (!(bytes1 && bytes2)) { + return false; + } + if (bytes1.byteLength !== bytes2.byteLength) { + return false; + } + const b1 = new Uint8Array(bytes1); + const b2 = new Uint8Array(bytes2); + for (let i = 0; i < bytes1.byteLength; i++) { + if (b1[i] !== b2[i]) { + return false; + } + } + return true; + } + var init_helper = __esm({ + "node_modules/.pnpm/@peculiar+asn1-schema@2.3.8/node_modules/@peculiar/asn1-schema/build/es2015/helper.js"() { + } + }); + + // node_modules/.pnpm/@peculiar+asn1-schema@2.3.8/node_modules/@peculiar/asn1-schema/build/es2015/schema.js + var AsnSchemaStorage; + var init_schema = __esm({ + "node_modules/.pnpm/@peculiar+asn1-schema@2.3.8/node_modules/@peculiar/asn1-schema/build/es2015/schema.js"() { + init_index_es(); + init_enums(); + init_helper(); + AsnSchemaStorage = class { + constructor() { + this.items = /* @__PURE__ */ new WeakMap(); + } + has(target) { + return this.items.has(target); + } + get(target, checkSchema = false) { + const schema = this.items.get(target); + if (!schema) { + throw new Error(`Cannot get schema for '${target.prototype.constructor.name}' target`); + } + if (checkSchema && !schema.schema) { + throw new Error(`Schema '${target.prototype.constructor.name}' doesn't contain ASN.1 schema. Call 'AsnSchemaStorage.cache'.`); + } + return schema; + } + cache(target) { + const schema = this.get(target); + if (!schema.schema) { + schema.schema = this.create(target, true); + } + } + createDefault(target) { + const schema = { + type: AsnTypeTypes.Sequence, + items: {} + }; + const parentSchema = this.findParentSchema(target); + if (parentSchema) { + Object.assign(schema, parentSchema); + schema.items = Object.assign({}, schema.items, parentSchema.items); + } + return schema; + } + create(target, useNames) { + const schema = this.items.get(target) || this.createDefault(target); + const asn1Value = []; + for (const key in schema.items) { + const item = schema.items[key]; + const name = useNames ? key : ""; + let asn1Item; + if (typeof item.type === "number") { + const Asn1TypeName = AsnPropTypes[item.type]; + const Asn1Type = index_es_exports[Asn1TypeName]; + if (!Asn1Type) { + throw new Error(`Cannot get ASN1 class by name '${Asn1TypeName}'`); + } + asn1Item = new Asn1Type({ name }); + } else if (isConvertible(item.type)) { + const instance = new item.type(); + asn1Item = instance.toSchema(name); + } else if (item.optional) { + const itemSchema = this.get(item.type); + if (itemSchema.type === AsnTypeTypes.Choice) { + asn1Item = new Any({ name }); + } else { + asn1Item = this.create(item.type, false); + asn1Item.name = name; + } + } else { + asn1Item = new Any({ name }); + } + const optional = !!item.optional || item.defaultValue !== void 0; + if (item.repeated) { + asn1Item.name = ""; + const Container = item.repeated === "set" ? Set2 : Sequence; + asn1Item = new Container({ + name: "", + value: [ + new Repeated({ + name, + value: asn1Item + }) + ] + }); + } + if (item.context !== null && item.context !== void 0) { + if (item.implicit) { + if (typeof item.type === "number" || isConvertible(item.type)) { + const Container = item.repeated ? Constructed : Primitive; + asn1Value.push(new Container({ + name, + optional, + idBlock: { + tagClass: 3, + tagNumber: item.context + } + })); + } else { + this.cache(item.type); + const isRepeated = !!item.repeated; + let value = !isRepeated ? this.get(item.type, true).schema : asn1Item; + value = "valueBlock" in value ? value.valueBlock.value : value.value; + asn1Value.push(new Constructed({ + name: !isRepeated ? name : "", + optional, + idBlock: { + tagClass: 3, + tagNumber: item.context + }, + value + })); + } + } else { + asn1Value.push(new Constructed({ + optional, + idBlock: { + tagClass: 3, + tagNumber: item.context + }, + value: [asn1Item] + })); + } + } else { + asn1Item.optional = optional; + asn1Value.push(asn1Item); + } + } + switch (schema.type) { + case AsnTypeTypes.Sequence: + return new Sequence({ value: asn1Value, name: "" }); + case AsnTypeTypes.Set: + return new Set2({ value: asn1Value, name: "" }); + case AsnTypeTypes.Choice: + return new Choice({ value: asn1Value, name: "" }); + default: + throw new Error(`Unsupported ASN1 type in use`); + } + } + set(target, schema) { + this.items.set(target, schema); + return this; + } + findParentSchema(target) { + const parent = Object.getPrototypeOf(target); + if (parent) { + const schema = this.items.get(parent); + return schema || this.findParentSchema(parent); + } + return null; + } + }; + } + }); + + // node_modules/.pnpm/@peculiar+asn1-schema@2.3.8/node_modules/@peculiar/asn1-schema/build/es2015/storage.js + var schemaStorage; + var init_storage = __esm({ + "node_modules/.pnpm/@peculiar+asn1-schema@2.3.8/node_modules/@peculiar/asn1-schema/build/es2015/storage.js"() { + init_schema(); + schemaStorage = new AsnSchemaStorage(); + } + }); + + // node_modules/.pnpm/@peculiar+asn1-schema@2.3.8/node_modules/@peculiar/asn1-schema/build/es2015/decorators.js + var AsnType, AsnProp; + var init_decorators = __esm({ + "node_modules/.pnpm/@peculiar+asn1-schema@2.3.8/node_modules/@peculiar/asn1-schema/build/es2015/decorators.js"() { + init_converters(); + init_enums(); + init_storage(); + AsnType = (options) => (target) => { + let schema; + if (!schemaStorage.has(target)) { + schema = schemaStorage.createDefault(target); + schemaStorage.set(target, schema); + } else { + schema = schemaStorage.get(target); + } + Object.assign(schema, options); + }; + AsnProp = (options) => (target, propertyKey) => { + let schema; + if (!schemaStorage.has(target.constructor)) { + schema = schemaStorage.createDefault(target.constructor); + schemaStorage.set(target.constructor, schema); + } else { + schema = schemaStorage.get(target.constructor); + } + const copyOptions = Object.assign({}, options); + if (typeof copyOptions.type === "number" && !copyOptions.converter) { + const defaultConverter2 = defaultConverter(options.type); + if (!defaultConverter2) { + throw new Error(`Cannot get default converter for property '${propertyKey}' of ${target.constructor.name}`); + } + copyOptions.converter = defaultConverter2; + } + schema.items[propertyKey] = copyOptions; + }; + } + }); + + // node_modules/.pnpm/@peculiar+asn1-schema@2.3.8/node_modules/@peculiar/asn1-schema/build/es2015/errors/schema_validation.js + var AsnSchemaValidationError; + var init_schema_validation = __esm({ + "node_modules/.pnpm/@peculiar+asn1-schema@2.3.8/node_modules/@peculiar/asn1-schema/build/es2015/errors/schema_validation.js"() { + AsnSchemaValidationError = class extends Error { + constructor() { + super(...arguments); + this.schemas = []; + } + }; + } + }); + + // node_modules/.pnpm/@peculiar+asn1-schema@2.3.8/node_modules/@peculiar/asn1-schema/build/es2015/errors/index.js + var init_errors = __esm({ + "node_modules/.pnpm/@peculiar+asn1-schema@2.3.8/node_modules/@peculiar/asn1-schema/build/es2015/errors/index.js"() { + init_schema_validation(); + } + }); + + // node_modules/.pnpm/@peculiar+asn1-schema@2.3.8/node_modules/@peculiar/asn1-schema/build/es2015/parser.js + var AsnParser; + var init_parser = __esm({ + "node_modules/.pnpm/@peculiar+asn1-schema@2.3.8/node_modules/@peculiar/asn1-schema/build/es2015/parser.js"() { + init_index_es(); + init_enums(); + init_converters(); + init_errors(); + init_helper(); + init_storage(); + AsnParser = class { + static parse(data, target) { + const asn1Parsed = fromBER(data); + if (asn1Parsed.result.error) { + throw new Error(asn1Parsed.result.error); + } + const res = this.fromASN(asn1Parsed.result, target); + return res; + } + static fromASN(asn1Schema, target) { + var _a2; + try { + if (isConvertible(target)) { + const value = new target(); + return value.fromASN(asn1Schema); + } + const schema = schemaStorage.get(target); + schemaStorage.cache(target); + let targetSchema = schema.schema; + if (asn1Schema.constructor === Constructed && schema.type !== AsnTypeTypes.Choice) { + targetSchema = new Constructed({ + idBlock: { + tagClass: 3, + tagNumber: asn1Schema.idBlock.tagNumber + }, + value: schema.schema.valueBlock.value + }); + for (const key in schema.items) { + delete asn1Schema[key]; + } + } + const asn1ComparedSchema = compareSchema({}, asn1Schema, targetSchema); + if (!asn1ComparedSchema.verified) { + throw new AsnSchemaValidationError(`Data does not match to ${target.name} ASN1 schema. ${asn1ComparedSchema.result.error}`); + } + const res = new target(); + if (isTypeOfArray(target)) { + if (!("value" in asn1Schema.valueBlock && Array.isArray(asn1Schema.valueBlock.value))) { + throw new Error(`Cannot get items from the ASN.1 parsed value. ASN.1 object is not constructed.`); + } + const itemType = schema.itemType; + if (typeof itemType === "number") { + const converter = defaultConverter(itemType); + if (!converter) { + throw new Error(`Cannot get default converter for array item of ${target.name} ASN1 schema`); + } + return target.from(asn1Schema.valueBlock.value, (element) => converter.fromASN(element)); + } else { + return target.from(asn1Schema.valueBlock.value, (element) => this.fromASN(element, itemType)); + } + } + for (const key in schema.items) { + const asn1SchemaValue = asn1ComparedSchema.result[key]; + if (!asn1SchemaValue) { + continue; + } + const schemaItem = schema.items[key]; + const schemaItemType = schemaItem.type; + if (typeof schemaItemType === "number" || isConvertible(schemaItemType)) { + const converter = (_a2 = schemaItem.converter) !== null && _a2 !== void 0 ? _a2 : isConvertible(schemaItemType) ? new schemaItemType() : null; + if (!converter) { + throw new Error("Converter is empty"); + } + if (schemaItem.repeated) { + if (schemaItem.implicit) { + const Container = schemaItem.repeated === "sequence" ? Sequence : Set2; + const newItem = new Container(); + newItem.valueBlock = asn1SchemaValue.valueBlock; + const newItemAsn = fromBER(newItem.toBER(false)); + if (newItemAsn.offset === -1) { + throw new Error(`Cannot parse the child item. ${newItemAsn.result.error}`); + } + if (!("value" in newItemAsn.result.valueBlock && Array.isArray(newItemAsn.result.valueBlock.value))) { + throw new Error("Cannot get items from the ASN.1 parsed value. ASN.1 object is not constructed."); + } + const value = newItemAsn.result.valueBlock.value; + res[key] = Array.from(value, (element) => converter.fromASN(element)); + } else { + res[key] = Array.from(asn1SchemaValue, (element) => converter.fromASN(element)); + } + } else { + let value = asn1SchemaValue; + if (schemaItem.implicit) { + let newItem; + if (isConvertible(schemaItemType)) { + newItem = new schemaItemType().toSchema(""); + } else { + const Asn1TypeName = AsnPropTypes[schemaItemType]; + const Asn1Type = index_es_exports[Asn1TypeName]; + if (!Asn1Type) { + throw new Error(`Cannot get '${Asn1TypeName}' class from asn1js module`); + } + newItem = new Asn1Type(); + } + newItem.valueBlock = value.valueBlock; + value = fromBER(newItem.toBER(false)).result; + } + res[key] = converter.fromASN(value); + } + } else { + if (schemaItem.repeated) { + if (!Array.isArray(asn1SchemaValue)) { + throw new Error("Cannot get list of items from the ASN.1 parsed value. ASN.1 value should be iterable."); + } + res[key] = Array.from(asn1SchemaValue, (element) => this.fromASN(element, schemaItemType)); + } else { + res[key] = this.fromASN(asn1SchemaValue, schemaItemType); + } + } + } + return res; + } catch (error) { + if (error instanceof AsnSchemaValidationError) { + error.schemas.push(target.name); + } + throw error; + } + } + }; + } + }); + + // node_modules/.pnpm/@peculiar+asn1-schema@2.3.8/node_modules/@peculiar/asn1-schema/build/es2015/serializer.js + var AsnSerializer; + var init_serializer = __esm({ + "node_modules/.pnpm/@peculiar+asn1-schema@2.3.8/node_modules/@peculiar/asn1-schema/build/es2015/serializer.js"() { + init_index_es(); + init_converters(); + init_enums(); + init_helper(); + init_storage(); + AsnSerializer = class _AsnSerializer { + static serialize(obj) { + if (obj instanceof BaseBlock) { + return obj.toBER(false); + } + return this.toASN(obj).toBER(false); + } + static toASN(obj) { + if (obj && typeof obj === "object" && isConvertible(obj)) { + return obj.toASN(); + } + if (!(obj && typeof obj === "object")) { + throw new TypeError("Parameter 1 should be type of Object."); + } + const target = obj.constructor; + const schema = schemaStorage.get(target); + schemaStorage.cache(target); + let asn1Value = []; + if (schema.itemType) { + if (!Array.isArray(obj)) { + throw new TypeError("Parameter 1 should be type of Array."); + } + if (typeof schema.itemType === "number") { + const converter = defaultConverter(schema.itemType); + if (!converter) { + throw new Error(`Cannot get default converter for array item of ${target.name} ASN1 schema`); + } + asn1Value = obj.map((o) => converter.toASN(o)); + } else { + asn1Value = obj.map((o) => this.toAsnItem({ type: schema.itemType }, "[]", target, o)); + } + } else { + for (const key in schema.items) { + const schemaItem = schema.items[key]; + const objProp = obj[key]; + if (objProp === void 0 || schemaItem.defaultValue === objProp || typeof schemaItem.defaultValue === "object" && typeof objProp === "object" && isArrayEqual(this.serialize(schemaItem.defaultValue), this.serialize(objProp))) { + continue; + } + const asn1Item = _AsnSerializer.toAsnItem(schemaItem, key, target, objProp); + if (typeof schemaItem.context === "number") { + if (schemaItem.implicit) { + if (!schemaItem.repeated && (typeof schemaItem.type === "number" || isConvertible(schemaItem.type))) { + const value = {}; + value.valueHex = asn1Item instanceof Null ? asn1Item.valueBeforeDecodeView : asn1Item.valueBlock.toBER(); + asn1Value.push(new Primitive({ + optional: schemaItem.optional, + idBlock: { + tagClass: 3, + tagNumber: schemaItem.context + }, + ...value + })); + } else { + asn1Value.push(new Constructed({ + optional: schemaItem.optional, + idBlock: { + tagClass: 3, + tagNumber: schemaItem.context + }, + value: asn1Item.valueBlock.value + })); + } + } else { + asn1Value.push(new Constructed({ + optional: schemaItem.optional, + idBlock: { + tagClass: 3, + tagNumber: schemaItem.context + }, + value: [asn1Item] + })); + } + } else if (schemaItem.repeated) { + asn1Value = asn1Value.concat(asn1Item); + } else { + asn1Value.push(asn1Item); + } + } + } + let asnSchema; + switch (schema.type) { + case AsnTypeTypes.Sequence: + asnSchema = new Sequence({ value: asn1Value }); + break; + case AsnTypeTypes.Set: + asnSchema = new Set2({ value: asn1Value }); + break; + case AsnTypeTypes.Choice: + if (!asn1Value[0]) { + throw new Error(`Schema '${target.name}' has wrong data. Choice cannot be empty.`); + } + asnSchema = asn1Value[0]; + break; + } + return asnSchema; + } + static toAsnItem(schemaItem, key, target, objProp) { + let asn1Item; + if (typeof schemaItem.type === "number") { + const converter = schemaItem.converter; + if (!converter) { + throw new Error(`Property '${key}' doesn't have converter for type ${AsnPropTypes[schemaItem.type]} in schema '${target.name}'`); + } + if (schemaItem.repeated) { + if (!Array.isArray(objProp)) { + throw new TypeError("Parameter 'objProp' should be type of Array."); + } + const items = Array.from(objProp, (element) => converter.toASN(element)); + const Container = schemaItem.repeated === "sequence" ? Sequence : Set2; + asn1Item = new Container({ + value: items + }); + } else { + asn1Item = converter.toASN(objProp); + } + } else { + if (schemaItem.repeated) { + if (!Array.isArray(objProp)) { + throw new TypeError("Parameter 'objProp' should be type of Array."); + } + const items = Array.from(objProp, (element) => this.toASN(element)); + const Container = schemaItem.repeated === "sequence" ? Sequence : Set2; + asn1Item = new Container({ + value: items + }); + } else { + asn1Item = this.toASN(objProp); + } + } + return asn1Item; + } + }; + } + }); + + // node_modules/.pnpm/@peculiar+asn1-schema@2.3.8/node_modules/@peculiar/asn1-schema/build/es2015/objects.js + var init_objects = __esm({ + "node_modules/.pnpm/@peculiar+asn1-schema@2.3.8/node_modules/@peculiar/asn1-schema/build/es2015/objects.js"() { + } + }); + + // node_modules/.pnpm/@peculiar+asn1-schema@2.3.8/node_modules/@peculiar/asn1-schema/build/es2015/convert.js + var import_pvtsutils3, AsnConvert; + var init_convert = __esm({ + "node_modules/.pnpm/@peculiar+asn1-schema@2.3.8/node_modules/@peculiar/asn1-schema/build/es2015/convert.js"() { + init_index_es(); + import_pvtsutils3 = __toESM(require_build()); + init_parser(); + init_serializer(); + AsnConvert = class _AsnConvert { + static serialize(obj) { + return AsnSerializer.serialize(obj); + } + static parse(data, target) { + return AsnParser.parse(data, target); + } + static toString(data) { + const buf = import_pvtsutils3.BufferSourceConverter.isBufferSource(data) ? import_pvtsutils3.BufferSourceConverter.toArrayBuffer(data) : _AsnConvert.serialize(data); + const asn = fromBER(buf); + if (asn.offset === -1) { + throw new Error(`Cannot decode ASN.1 data. ${asn.result.error}`); + } + return asn.result.toString(); + } + }; + } + }); + + // node_modules/.pnpm/@peculiar+asn1-schema@2.3.8/node_modules/@peculiar/asn1-schema/build/es2015/index.js + var init_es2015 = __esm({ + "node_modules/.pnpm/@peculiar+asn1-schema@2.3.8/node_modules/@peculiar/asn1-schema/build/es2015/index.js"() { + init_converters(); + init_types(); + init_decorators(); + init_enums(); + init_parser(); + init_serializer(); + init_errors(); + init_objects(); + init_convert(); + } + }); + + // node_modules/.pnpm/tslib@2.6.2/node_modules/tslib/tslib.es6.mjs + function __decorate(decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d2; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") + r = Reflect.decorate(decorators, target, key, desc); + else + for (var i = decorators.length - 1; i >= 0; i--) + if (d2 = decorators[i]) + r = (c < 3 ? d2(r) : c > 3 ? d2(target, key, r) : d2(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; + } + var init_tslib_es6 = __esm({ + "node_modules/.pnpm/tslib@2.6.2/node_modules/tslib/tslib.es6.mjs"() { + } + }); + + // node_modules/.pnpm/@peculiar+json-schema@1.1.12/node_modules/@peculiar/json-schema/build/index.es.js + function checkType(value, type) { + switch (type) { + case JsonPropTypes.Boolean: + return typeof value === "boolean"; + case JsonPropTypes.Number: + return typeof value === "number"; + case JsonPropTypes.String: + return typeof value === "string"; + } + return true; + } + function throwIfTypeIsWrong(value, type) { + if (!checkType(value, type)) { + throw new TypeError(`Value must be ${JsonPropTypes[type]}`); + } + } + function isConvertible2(target) { + if (target && target.prototype) { + if (target.prototype.toJSON && target.prototype.fromJSON) { + return true; + } else { + return isConvertible2(target.prototype); + } + } else { + return !!(target && target.toJSON && target.fromJSON); + } + } + function getValidations(item) { + const validations = []; + if (item.pattern) { + validations.push(new PatternValidation(item.pattern)); + } + if (item.type === JsonPropTypes.Number || item.type === JsonPropTypes.Any) { + if (item.minInclusive !== void 0 || item.maxInclusive !== void 0) { + validations.push(new InclusiveValidation(item.minInclusive, item.maxInclusive)); + } + if (item.minExclusive !== void 0 || item.maxExclusive !== void 0) { + validations.push(new ExclusiveValidation(item.minExclusive, item.maxExclusive)); + } + if (item.enumeration !== void 0) { + validations.push(new EnumerationValidation(item.enumeration)); + } + } + if (item.type === JsonPropTypes.String || item.repeated || item.type === JsonPropTypes.Any) { + if (item.length !== void 0 || item.minLength !== void 0 || item.maxLength !== void 0) { + validations.push(new LengthValidation(item.length, item.minLength, item.maxLength)); + } + } + return validations; + } + var JsonError, TransformError, ParserError, ValidationError, SerializerError, KeyError, JsonPropTypes, JsonSchemaStorage, DEFAULT_SCHEMA, schemaStorage2, PatternValidation, InclusiveValidation, ExclusiveValidation, LengthValidation, EnumerationValidation, JsonTransform, JsonSerializer, JsonParser, JsonProp; + var init_index_es2 = __esm({ + "node_modules/.pnpm/@peculiar+json-schema@1.1.12/node_modules/@peculiar/json-schema/build/index.es.js"() { + JsonError = class extends Error { + constructor(message, innerError) { + super(innerError ? `${message}. See the inner exception for more details.` : message); + this.message = message; + this.innerError = innerError; + } + }; + TransformError = class extends JsonError { + constructor(schema, message, innerError) { + super(message, innerError); + this.schema = schema; + } + }; + ParserError = class extends TransformError { + constructor(schema, message, innerError) { + super(schema, `JSON doesn't match to '${schema.target.name}' schema. ${message}`, innerError); + } + }; + ValidationError = class extends JsonError { + }; + SerializerError = class extends JsonError { + constructor(schemaName, message, innerError) { + super(`Cannot serialize by '${schemaName}' schema. ${message}`, innerError); + this.schemaName = schemaName; + } + }; + KeyError = class extends ParserError { + constructor(schema, keys, errors = {}) { + super(schema, "Some keys doesn't match to schema"); + this.keys = keys; + this.errors = errors; + } + }; + (function(JsonPropTypes2) { + JsonPropTypes2[JsonPropTypes2["Any"] = 0] = "Any"; + JsonPropTypes2[JsonPropTypes2["Boolean"] = 1] = "Boolean"; + JsonPropTypes2[JsonPropTypes2["Number"] = 2] = "Number"; + JsonPropTypes2[JsonPropTypes2["String"] = 3] = "String"; + })(JsonPropTypes || (JsonPropTypes = {})); + JsonSchemaStorage = class { + constructor() { + this.items = /* @__PURE__ */ new Map(); + } + has(target) { + return this.items.has(target) || !!this.findParentSchema(target); + } + get(target) { + const schema = this.items.get(target) || this.findParentSchema(target); + if (!schema) { + throw new Error("Cannot get schema for current target"); + } + return schema; + } + create(target) { + const schema = { names: {} }; + const parentSchema = this.findParentSchema(target); + if (parentSchema) { + Object.assign(schema, parentSchema); + schema.names = {}; + for (const name in parentSchema.names) { + schema.names[name] = Object.assign({}, parentSchema.names[name]); + } + } + schema.target = target; + return schema; + } + set(target, schema) { + this.items.set(target, schema); + return this; + } + findParentSchema(target) { + const parent = target.__proto__; + if (parent) { + const schema = this.items.get(parent); + return schema || this.findParentSchema(parent); + } + return null; + } + }; + DEFAULT_SCHEMA = "default"; + schemaStorage2 = new JsonSchemaStorage(); + PatternValidation = class { + constructor(pattern) { + this.pattern = new RegExp(pattern); + } + validate(value) { + const pattern = new RegExp(this.pattern.source, this.pattern.flags); + if (typeof value !== "string") { + throw new ValidationError("Incoming value must be string"); + } + if (!pattern.exec(value)) { + throw new ValidationError(`Value doesn't match to pattern '${pattern.toString()}'`); + } + } + }; + InclusiveValidation = class { + constructor(min = Number.MIN_VALUE, max = Number.MAX_VALUE) { + this.min = min; + this.max = max; + } + validate(value) { + throwIfTypeIsWrong(value, JsonPropTypes.Number); + if (!(this.min <= value && value <= this.max)) { + const min = this.min === Number.MIN_VALUE ? "MIN" : this.min; + const max = this.max === Number.MAX_VALUE ? "MAX" : this.max; + throw new ValidationError(`Value doesn't match to diapason [${min},${max}]`); + } + } + }; + ExclusiveValidation = class { + constructor(min = Number.MIN_VALUE, max = Number.MAX_VALUE) { + this.min = min; + this.max = max; + } + validate(value) { + throwIfTypeIsWrong(value, JsonPropTypes.Number); + if (!(this.min < value && value < this.max)) { + const min = this.min === Number.MIN_VALUE ? "MIN" : this.min; + const max = this.max === Number.MAX_VALUE ? "MAX" : this.max; + throw new ValidationError(`Value doesn't match to diapason (${min},${max})`); + } + } + }; + LengthValidation = class { + constructor(length, minLength, maxLength) { + this.length = length; + this.minLength = minLength; + this.maxLength = maxLength; + } + validate(value) { + if (this.length !== void 0) { + if (value.length !== this.length) { + throw new ValidationError(`Value length must be exactly ${this.length}.`); + } + return; + } + if (this.minLength !== void 0) { + if (value.length < this.minLength) { + throw new ValidationError(`Value length must be more than ${this.minLength}.`); + } + } + if (this.maxLength !== void 0) { + if (value.length > this.maxLength) { + throw new ValidationError(`Value length must be less than ${this.maxLength}.`); + } + } + } + }; + EnumerationValidation = class { + constructor(enumeration) { + this.enumeration = enumeration; + } + validate(value) { + throwIfTypeIsWrong(value, JsonPropTypes.String); + if (!this.enumeration.includes(value)) { + throw new ValidationError(`Value must be one of ${this.enumeration.map((v) => `'${v}'`).join(", ")}`); + } + } + }; + JsonTransform = class { + static checkValues(data, schemaItem) { + const values = Array.isArray(data) ? data : [data]; + for (const value of values) { + for (const validation of schemaItem.validations) { + if (validation instanceof LengthValidation && schemaItem.repeated) { + validation.validate(data); + } else { + validation.validate(value); + } + } + } + } + static checkTypes(value, schemaItem) { + if (schemaItem.repeated && !Array.isArray(value)) { + throw new TypeError("Value must be Array"); + } + if (typeof schemaItem.type === "number") { + const values = Array.isArray(value) ? value : [value]; + for (const v of values) { + throwIfTypeIsWrong(v, schemaItem.type); + } + } + } + static getSchemaByName(schema, name = DEFAULT_SCHEMA) { + return { ...schema.names[DEFAULT_SCHEMA], ...schema.names[name] }; + } + }; + JsonSerializer = class extends JsonTransform { + static serialize(obj, options, replacer, space) { + const json = this.toJSON(obj, options); + return JSON.stringify(json, replacer, space); + } + static toJSON(obj, options = {}) { + let res; + let targetSchema = options.targetSchema; + const schemaName = options.schemaName || DEFAULT_SCHEMA; + if (isConvertible2(obj)) { + return obj.toJSON(); + } + if (Array.isArray(obj)) { + res = []; + for (const item of obj) { + res.push(this.toJSON(item, options)); + } + } else if (typeof obj === "object") { + if (targetSchema && !schemaStorage2.has(targetSchema)) { + throw new JsonError("Cannot get schema for `targetSchema` param"); + } + targetSchema = targetSchema || obj.constructor; + if (schemaStorage2.has(targetSchema)) { + const schema = schemaStorage2.get(targetSchema); + res = {}; + const namedSchema = this.getSchemaByName(schema, schemaName); + for (const key in namedSchema) { + try { + const item = namedSchema[key]; + const objItem = obj[key]; + let value; + if (item.optional && objItem === void 0 || item.defaultValue !== void 0 && objItem === item.defaultValue) { + continue; + } + if (!item.optional && objItem === void 0) { + throw new SerializerError(targetSchema.name, `Property '${key}' is required.`); + } + if (typeof item.type === "number") { + if (item.converter) { + if (item.repeated) { + value = objItem.map((el) => item.converter.toJSON(el, obj)); + } else { + value = item.converter.toJSON(objItem, obj); + } + } else { + value = objItem; + } + } else { + if (item.repeated) { + value = objItem.map((el) => this.toJSON(el, { schemaName })); + } else { + value = this.toJSON(objItem, { schemaName }); + } + } + this.checkTypes(value, item); + this.checkValues(value, item); + res[item.name || key] = value; + } catch (e) { + if (e instanceof SerializerError) { + throw e; + } else { + throw new SerializerError(schema.target.name, `Property '${key}' is wrong. ${e.message}`, e); + } + } + } + } else { + res = {}; + for (const key in obj) { + res[key] = this.toJSON(obj[key], { schemaName }); + } + } + } else { + res = obj; + } + return res; + } + }; + JsonParser = class _JsonParser extends JsonTransform { + static parse(data, options) { + const obj = JSON.parse(data); + return this.fromJSON(obj, options); + } + static fromJSON(target, options) { + const targetSchema = options.targetSchema; + const schemaName = options.schemaName || DEFAULT_SCHEMA; + const obj = new targetSchema(); + if (isConvertible2(obj)) { + return obj.fromJSON(target); + } + const schema = schemaStorage2.get(targetSchema); + const namedSchema = this.getSchemaByName(schema, schemaName); + const keyErrors = {}; + if (options.strictProperty && !Array.isArray(target)) { + _JsonParser.checkStrictProperty(target, namedSchema, schema); + } + for (const key in namedSchema) { + try { + const item = namedSchema[key]; + const name = item.name || key; + const value = target[name]; + if (value === void 0 && (item.optional || item.defaultValue !== void 0)) { + continue; + } + if (!item.optional && value === void 0) { + throw new ParserError(schema, `Property '${name}' is required.`); + } + this.checkTypes(value, item); + this.checkValues(value, item); + if (typeof item.type === "number") { + if (item.converter) { + if (item.repeated) { + obj[key] = value.map((el) => item.converter.fromJSON(el, obj)); + } else { + obj[key] = item.converter.fromJSON(value, obj); + } + } else { + obj[key] = value; + } + } else { + const newOptions = { + ...options, + targetSchema: item.type, + schemaName + }; + if (item.repeated) { + obj[key] = value.map((el) => this.fromJSON(el, newOptions)); + } else { + obj[key] = this.fromJSON(value, newOptions); + } + } + } catch (e) { + if (!(e instanceof ParserError)) { + e = new ParserError(schema, `Property '${key}' is wrong. ${e.message}`, e); + } + if (options.strictAllKeys) { + keyErrors[key] = e; + } else { + throw e; + } + } + } + const keys = Object.keys(keyErrors); + if (keys.length) { + throw new KeyError(schema, keys, keyErrors); + } + return obj; + } + static checkStrictProperty(target, namedSchema, schema) { + const jsonProps = Object.keys(target); + const schemaProps = Object.keys(namedSchema); + const keys = []; + for (const key of jsonProps) { + if (schemaProps.indexOf(key) === -1) { + keys.push(key); + } + } + if (keys.length) { + throw new KeyError(schema, keys); + } + } + }; + JsonProp = (options = {}) => (target, propertyKey) => { + const errorMessage = `Cannot set type for ${propertyKey} property of ${target.constructor.name} schema`; + let schema; + if (!schemaStorage2.has(target.constructor)) { + schema = schemaStorage2.create(target.constructor); + schemaStorage2.set(target.constructor, schema); + } else { + schema = schemaStorage2.get(target.constructor); + if (schema.target !== target.constructor) { + schema = schemaStorage2.create(target.constructor); + schemaStorage2.set(target.constructor, schema); + } + } + const defaultSchema = { + type: JsonPropTypes.Any, + validations: [] + }; + const copyOptions = Object.assign(defaultSchema, options); + copyOptions.validations = getValidations(copyOptions); + if (typeof copyOptions.type !== "number") { + if (!schemaStorage2.has(copyOptions.type) && !isConvertible2(copyOptions.type)) { + throw new Error(`${errorMessage}. Assigning type doesn't have schema.`); + } + } + let schemaNames; + if (Array.isArray(options.schema)) { + schemaNames = options.schema; + } else { + schemaNames = [options.schema || DEFAULT_SCHEMA]; + } + for (const schemaName of schemaNames) { + if (!schema.names[schemaName]) { + schema.names[schemaName] = {}; + } + const namedSchema = schema.names[schemaName]; + namedSchema[propertyKey] = copyOptions; + } + }; + } + }); + + // node_modules/.pnpm/webcrypto-core@1.7.7/node_modules/webcrypto-core/build/webcrypto-core.es.js + function isJWK(data) { + return typeof data === "object" && "kty" in data; + } + var import_pvtsutils4, import_pvtsutils5, CryptoError, AlgorithmError, UnsupportedOperationError, OperationError, RequiredPropertyError, ProviderCrypto, AesProvider, AesCbcProvider, AesCmacProvider, AesCtrProvider, AesEcbProvider, AesGcmProvider, AesKwProvider, DesProvider, RsaProvider, RsaSsaProvider, RsaPssProvider, RsaOaepProvider, EllipticProvider, EcdsaProvider, KEY_TYPES, CryptoKey, EcdhProvider, EcdhEsProvider, EdDsaProvider, ObjectIdentifier2, AlgorithmIdentifier, PrivateKeyInfo, PublicKeyInfo, JsonBase64UrlArrayBufferConverter, AsnIntegerArrayBufferConverter, RsaPrivateKey, RsaPublicKey, EcPublicKey, EcPrivateKey, AsnIntegerWithoutPaddingConverter, index$2, EcUtils, EcDsaSignature, OneAsymmetricKey, EdPrivateKey, EdPublicKey, CurvePrivateKey, idSecp256r1, idEllipticCurve, idSecp384r1, idSecp521r1, idSecp256k1, idVersionOne, idBrainpoolP160r1, idBrainpoolP160t1, idBrainpoolP192r1, idBrainpoolP192t1, idBrainpoolP224r1, idBrainpoolP224t1, idBrainpoolP256r1, idBrainpoolP256t1, idBrainpoolP320r1, idBrainpoolP320t1, idBrainpoolP384r1, idBrainpoolP384t1, idBrainpoolP512r1, idBrainpoolP512t1, idX25519, idX448, idEd25519, idEd448, index$1, EcCurves, HmacProvider, Pbkdf2Provider, HkdfProvider, ShakeProvider, Shake128Provider, Shake256Provider, Crypto, ProviderStorage, SubtleCrypto; + var init_webcrypto_core_es = __esm({ + "node_modules/.pnpm/webcrypto-core@1.7.7/node_modules/webcrypto-core/build/webcrypto-core.es.js"() { + import_pvtsutils4 = __toESM(require_build()); + import_pvtsutils5 = __toESM(require_build()); + init_es2015(); + init_tslib_es6(); + init_index_es2(); + init_index_es(); + CryptoError = class extends Error { + }; + AlgorithmError = class extends CryptoError { + }; + UnsupportedOperationError = class extends CryptoError { + constructor(methodName) { + super(`Unsupported operation: ${methodName ? `${methodName}` : ""}`); + } + }; + OperationError = class extends CryptoError { + }; + RequiredPropertyError = class extends CryptoError { + constructor(propName) { + super(`${propName}: Missing required property`); + } + }; + ProviderCrypto = class { + async digest(...args) { + this.checkDigest.apply(this, args); + return this.onDigest.apply(this, args); + } + checkDigest(algorithm, data) { + this.checkAlgorithmName(algorithm); + } + async onDigest(algorithm, data) { + throw new UnsupportedOperationError("digest"); + } + async generateKey(...args) { + this.checkGenerateKey.apply(this, args); + return this.onGenerateKey.apply(this, args); + } + checkGenerateKey(algorithm, extractable, keyUsages, ...args) { + this.checkAlgorithmName(algorithm); + this.checkGenerateKeyParams(algorithm); + if (!(keyUsages && keyUsages.length)) { + throw new TypeError(`Usages cannot be empty when creating a key.`); + } + let allowedUsages; + if (Array.isArray(this.usages)) { + allowedUsages = this.usages; + } else { + allowedUsages = this.usages.privateKey.concat(this.usages.publicKey); + } + this.checkKeyUsages(keyUsages, allowedUsages); + } + checkGenerateKeyParams(algorithm) { + } + async onGenerateKey(algorithm, extractable, keyUsages, ...args) { + throw new UnsupportedOperationError("generateKey"); + } + async sign(...args) { + this.checkSign.apply(this, args); + return this.onSign.apply(this, args); + } + checkSign(algorithm, key, data, ...args) { + this.checkAlgorithmName(algorithm); + this.checkAlgorithmParams(algorithm); + this.checkCryptoKey(key, "sign"); + } + async onSign(algorithm, key, data, ...args) { + throw new UnsupportedOperationError("sign"); + } + async verify(...args) { + this.checkVerify.apply(this, args); + return this.onVerify.apply(this, args); + } + checkVerify(algorithm, key, signature, data, ...args) { + this.checkAlgorithmName(algorithm); + this.checkAlgorithmParams(algorithm); + this.checkCryptoKey(key, "verify"); + } + async onVerify(algorithm, key, signature, data, ...args) { + throw new UnsupportedOperationError("verify"); + } + async encrypt(...args) { + this.checkEncrypt.apply(this, args); + return this.onEncrypt.apply(this, args); + } + checkEncrypt(algorithm, key, data, options = {}, ...args) { + this.checkAlgorithmName(algorithm); + this.checkAlgorithmParams(algorithm); + this.checkCryptoKey(key, options.keyUsage ? "encrypt" : void 0); + } + async onEncrypt(algorithm, key, data, ...args) { + throw new UnsupportedOperationError("encrypt"); + } + async decrypt(...args) { + this.checkDecrypt.apply(this, args); + return this.onDecrypt.apply(this, args); + } + checkDecrypt(algorithm, key, data, options = {}, ...args) { + this.checkAlgorithmName(algorithm); + this.checkAlgorithmParams(algorithm); + this.checkCryptoKey(key, options.keyUsage ? "decrypt" : void 0); + } + async onDecrypt(algorithm, key, data, ...args) { + throw new UnsupportedOperationError("decrypt"); + } + async deriveBits(...args) { + this.checkDeriveBits.apply(this, args); + return this.onDeriveBits.apply(this, args); + } + checkDeriveBits(algorithm, baseKey, length, options = {}, ...args) { + this.checkAlgorithmName(algorithm); + this.checkAlgorithmParams(algorithm); + this.checkCryptoKey(baseKey, options.keyUsage ? "deriveBits" : void 0); + if (length % 8 !== 0) { + throw new OperationError("length: Is not multiple of 8"); + } + } + async onDeriveBits(algorithm, baseKey, length, ...args) { + throw new UnsupportedOperationError("deriveBits"); + } + async exportKey(...args) { + this.checkExportKey.apply(this, args); + return this.onExportKey.apply(this, args); + } + checkExportKey(format2, key, ...args) { + this.checkKeyFormat(format2); + this.checkCryptoKey(key); + if (!key.extractable) { + throw new CryptoError("key: Is not extractable"); + } + } + async onExportKey(format2, key, ...args) { + throw new UnsupportedOperationError("exportKey"); + } + async importKey(...args) { + this.checkImportKey.apply(this, args); + return this.onImportKey.apply(this, args); + } + checkImportKey(format2, keyData, algorithm, extractable, keyUsages, ...args) { + this.checkKeyFormat(format2); + this.checkKeyData(format2, keyData); + this.checkAlgorithmName(algorithm); + this.checkImportParams(algorithm); + if (Array.isArray(this.usages)) { + this.checkKeyUsages(keyUsages, this.usages); + } + } + async onImportKey(format2, keyData, algorithm, extractable, keyUsages, ...args) { + throw new UnsupportedOperationError("importKey"); + } + checkAlgorithmName(algorithm) { + if (algorithm.name.toLowerCase() !== this.name.toLowerCase()) { + throw new AlgorithmError("Unrecognized name"); + } + } + checkAlgorithmParams(algorithm) { + } + checkDerivedKeyParams(algorithm) { + } + checkKeyUsages(usages, allowed) { + for (const usage of usages) { + if (allowed.indexOf(usage) === -1) { + throw new TypeError("Cannot create a key using the specified key usages"); + } + } + } + checkCryptoKey(key, keyUsage) { + this.checkAlgorithmName(key.algorithm); + if (keyUsage && key.usages.indexOf(keyUsage) === -1) { + throw new CryptoError(`key does not match that of operation`); + } + } + checkRequiredProperty(data, propName) { + if (!(propName in data)) { + throw new RequiredPropertyError(propName); + } + } + checkHashAlgorithm(algorithm, hashAlgorithms) { + for (const item of hashAlgorithms) { + if (item.toLowerCase() === algorithm.name.toLowerCase()) { + return; + } + } + throw new OperationError(`hash: Must be one of ${hashAlgorithms.join(", ")}`); + } + checkImportParams(algorithm) { + } + checkKeyFormat(format2) { + switch (format2) { + case "raw": + case "pkcs8": + case "spki": + case "jwk": + break; + default: + throw new TypeError("format: Is invalid value. Must be 'jwk', 'raw', 'spki', or 'pkcs8'"); + } + } + checkKeyData(format2, keyData) { + if (!keyData) { + throw new TypeError("keyData: Cannot be empty on empty on key importing"); + } + if (format2 === "jwk") { + if (!isJWK(keyData)) { + throw new TypeError("keyData: Is not JsonWebToken"); + } + } else if (!import_pvtsutils4.BufferSourceConverter.isBufferSource(keyData)) { + throw new TypeError("keyData: Is not ArrayBufferView or ArrayBuffer"); + } + } + prepareData(data) { + return import_pvtsutils4.BufferSourceConverter.toArrayBuffer(data); + } + }; + AesProvider = class extends ProviderCrypto { + checkGenerateKeyParams(algorithm) { + this.checkRequiredProperty(algorithm, "length"); + if (typeof algorithm.length !== "number") { + throw new TypeError("length: Is not of type Number"); + } + switch (algorithm.length) { + case 128: + case 192: + case 256: + break; + default: + throw new TypeError("length: Must be 128, 192, or 256"); + } + } + checkDerivedKeyParams(algorithm) { + this.checkGenerateKeyParams(algorithm); + } + }; + AesCbcProvider = class extends AesProvider { + constructor() { + super(...arguments); + this.name = "AES-CBC"; + this.usages = ["encrypt", "decrypt", "wrapKey", "unwrapKey"]; + } + checkAlgorithmParams(algorithm) { + this.checkRequiredProperty(algorithm, "iv"); + if (!(algorithm.iv instanceof ArrayBuffer || ArrayBuffer.isView(algorithm.iv))) { + throw new TypeError("iv: Is not of type '(ArrayBuffer or ArrayBufferView)'"); + } + if (algorithm.iv.byteLength !== 16) { + throw new TypeError("iv: Must have length 16 bytes"); + } + } + }; + AesCmacProvider = class extends AesProvider { + constructor() { + super(...arguments); + this.name = "AES-CMAC"; + this.usages = ["sign", "verify"]; + } + checkAlgorithmParams(algorithm) { + this.checkRequiredProperty(algorithm, "length"); + if (typeof algorithm.length !== "number") { + throw new TypeError("length: Is not a Number"); + } + if (algorithm.length < 1) { + throw new OperationError("length: Must be more than 0"); + } + } + }; + AesCtrProvider = class extends AesProvider { + constructor() { + super(...arguments); + this.name = "AES-CTR"; + this.usages = ["encrypt", "decrypt", "wrapKey", "unwrapKey"]; + } + checkAlgorithmParams(algorithm) { + this.checkRequiredProperty(algorithm, "counter"); + if (!(algorithm.counter instanceof ArrayBuffer || ArrayBuffer.isView(algorithm.counter))) { + throw new TypeError("counter: Is not of type '(ArrayBuffer or ArrayBufferView)'"); + } + if (algorithm.counter.byteLength !== 16) { + throw new TypeError("iv: Must have length 16 bytes"); + } + this.checkRequiredProperty(algorithm, "length"); + if (typeof algorithm.length !== "number") { + throw new TypeError("length: Is not a Number"); + } + if (algorithm.length < 1) { + throw new OperationError("length: Must be more than 0"); + } + } + }; + AesEcbProvider = class extends AesProvider { + constructor() { + super(...arguments); + this.name = "AES-ECB"; + this.usages = ["encrypt", "decrypt", "wrapKey", "unwrapKey"]; + } + }; + AesGcmProvider = class extends AesProvider { + constructor() { + super(...arguments); + this.name = "AES-GCM"; + this.usages = ["encrypt", "decrypt", "wrapKey", "unwrapKey"]; + } + checkAlgorithmParams(algorithm) { + this.checkRequiredProperty(algorithm, "iv"); + if (!(algorithm.iv instanceof ArrayBuffer || ArrayBuffer.isView(algorithm.iv))) { + throw new TypeError("iv: Is not of type '(ArrayBuffer or ArrayBufferView)'"); + } + if (algorithm.iv.byteLength < 1) { + throw new OperationError("iv: Must have length more than 0 and less than 2^64 - 1"); + } + if (!("tagLength" in algorithm)) { + algorithm.tagLength = 128; + } + switch (algorithm.tagLength) { + case 32: + case 64: + case 96: + case 104: + case 112: + case 120: + case 128: + break; + default: + throw new OperationError("tagLength: Must be one of 32, 64, 96, 104, 112, 120 or 128"); + } + } + }; + AesKwProvider = class extends AesProvider { + constructor() { + super(...arguments); + this.name = "AES-KW"; + this.usages = ["wrapKey", "unwrapKey"]; + } + }; + DesProvider = class extends ProviderCrypto { + constructor() { + super(...arguments); + this.usages = ["encrypt", "decrypt", "wrapKey", "unwrapKey"]; + } + checkAlgorithmParams(algorithm) { + if (this.ivSize) { + this.checkRequiredProperty(algorithm, "iv"); + if (!(algorithm.iv instanceof ArrayBuffer || ArrayBuffer.isView(algorithm.iv))) { + throw new TypeError("iv: Is not of type '(ArrayBuffer or ArrayBufferView)'"); + } + if (algorithm.iv.byteLength !== this.ivSize) { + throw new TypeError(`iv: Must have length ${this.ivSize} bytes`); + } + } + } + checkGenerateKeyParams(algorithm) { + this.checkRequiredProperty(algorithm, "length"); + if (typeof algorithm.length !== "number") { + throw new TypeError("length: Is not of type Number"); + } + if (algorithm.length !== this.keySizeBits) { + throw new OperationError(`algorithm.length: Must be ${this.keySizeBits}`); + } + } + checkDerivedKeyParams(algorithm) { + this.checkGenerateKeyParams(algorithm); + } + }; + RsaProvider = class extends ProviderCrypto { + constructor() { + super(...arguments); + this.hashAlgorithms = ["SHA-1", "SHA-256", "SHA-384", "SHA-512"]; + } + checkGenerateKeyParams(algorithm) { + this.checkRequiredProperty(algorithm, "hash"); + this.checkHashAlgorithm(algorithm.hash, this.hashAlgorithms); + this.checkRequiredProperty(algorithm, "publicExponent"); + if (!(algorithm.publicExponent && algorithm.publicExponent instanceof Uint8Array)) { + throw new TypeError("publicExponent: Missing or not a Uint8Array"); + } + const publicExponent = import_pvtsutils4.Convert.ToBase64(algorithm.publicExponent); + if (!(publicExponent === "Aw==" || publicExponent === "AQAB")) { + throw new TypeError("publicExponent: Must be [3] or [1,0,1]"); + } + this.checkRequiredProperty(algorithm, "modulusLength"); + if (algorithm.modulusLength % 8 || algorithm.modulusLength < 256 || algorithm.modulusLength > 16384) { + throw new TypeError("The modulus length must be a multiple of 8 bits and >= 256 and <= 16384"); + } + } + checkImportParams(algorithm) { + this.checkRequiredProperty(algorithm, "hash"); + this.checkHashAlgorithm(algorithm.hash, this.hashAlgorithms); + } + }; + RsaSsaProvider = class extends RsaProvider { + constructor() { + super(...arguments); + this.name = "RSASSA-PKCS1-v1_5"; + this.usages = { + privateKey: ["sign"], + publicKey: ["verify"] + }; + } + }; + RsaPssProvider = class extends RsaProvider { + constructor() { + super(...arguments); + this.name = "RSA-PSS"; + this.usages = { + privateKey: ["sign"], + publicKey: ["verify"] + }; + } + checkAlgorithmParams(algorithm) { + this.checkRequiredProperty(algorithm, "saltLength"); + if (typeof algorithm.saltLength !== "number") { + throw new TypeError("saltLength: Is not a Number"); + } + if (algorithm.saltLength < 0) { + throw new RangeError("saltLength: Must be positive number"); + } + } + }; + RsaOaepProvider = class extends RsaProvider { + constructor() { + super(...arguments); + this.name = "RSA-OAEP"; + this.usages = { + privateKey: ["decrypt", "unwrapKey"], + publicKey: ["encrypt", "wrapKey"] + }; + } + checkAlgorithmParams(algorithm) { + if (algorithm.label && !(algorithm.label instanceof ArrayBuffer || ArrayBuffer.isView(algorithm.label))) { + throw new TypeError("label: Is not of type '(ArrayBuffer or ArrayBufferView)'"); + } + } + }; + EllipticProvider = class extends ProviderCrypto { + checkGenerateKeyParams(algorithm) { + this.checkRequiredProperty(algorithm, "namedCurve"); + this.checkNamedCurve(algorithm.namedCurve); + } + checkNamedCurve(namedCurve) { + for (const item of this.namedCurves) { + if (item.toLowerCase() === namedCurve.toLowerCase()) { + return; + } + } + throw new OperationError(`namedCurve: Must be one of ${this.namedCurves.join(", ")}`); + } + }; + EcdsaProvider = class extends EllipticProvider { + constructor() { + super(...arguments); + this.name = "ECDSA"; + this.hashAlgorithms = ["SHA-1", "SHA-256", "SHA-384", "SHA-512"]; + this.usages = { + privateKey: ["sign"], + publicKey: ["verify"] + }; + this.namedCurves = ["P-256", "P-384", "P-521", "K-256"]; + } + checkAlgorithmParams(algorithm) { + this.checkRequiredProperty(algorithm, "hash"); + this.checkHashAlgorithm(algorithm.hash, this.hashAlgorithms); + } + }; + KEY_TYPES = ["secret", "private", "public"]; + CryptoKey = class { + static create(algorithm, type, extractable, usages) { + const key = new this(); + key.algorithm = algorithm; + key.type = type; + key.extractable = extractable; + key.usages = usages; + return key; + } + static isKeyType(data) { + return KEY_TYPES.indexOf(data) !== -1; + } + get [Symbol.toStringTag]() { + return "CryptoKey"; + } + }; + EcdhProvider = class extends EllipticProvider { + constructor() { + super(...arguments); + this.name = "ECDH"; + this.usages = { + privateKey: ["deriveBits", "deriveKey"], + publicKey: [] + }; + this.namedCurves = ["P-256", "P-384", "P-521", "K-256"]; + } + checkAlgorithmParams(algorithm) { + this.checkRequiredProperty(algorithm, "public"); + if (!(algorithm.public instanceof CryptoKey)) { + throw new TypeError("public: Is not a CryptoKey"); + } + if (algorithm.public.type !== "public") { + throw new OperationError("public: Is not a public key"); + } + if (algorithm.public.algorithm.name !== this.name) { + throw new OperationError(`public: Is not ${this.name} key`); + } + } + }; + EcdhEsProvider = class extends EcdhProvider { + constructor() { + super(...arguments); + this.name = "ECDH-ES"; + this.namedCurves = ["X25519", "X448"]; + } + }; + EdDsaProvider = class extends EllipticProvider { + constructor() { + super(...arguments); + this.name = "EdDSA"; + this.usages = { + privateKey: ["sign"], + publicKey: ["verify"] + }; + this.namedCurves = ["Ed25519", "Ed448"]; + } + }; + ObjectIdentifier2 = class ObjectIdentifier3 { + constructor(value) { + if (value) { + this.value = value; + } + } + }; + __decorate([ + AsnProp({ type: AsnPropTypes.ObjectIdentifier }) + ], ObjectIdentifier2.prototype, "value", void 0); + ObjectIdentifier2 = __decorate([ + AsnType({ type: AsnTypeTypes.Choice }) + ], ObjectIdentifier2); + AlgorithmIdentifier = class { + constructor(params) { + Object.assign(this, params); + } + }; + __decorate([ + AsnProp({ + type: AsnPropTypes.ObjectIdentifier + }) + ], AlgorithmIdentifier.prototype, "algorithm", void 0); + __decorate([ + AsnProp({ + type: AsnPropTypes.Any, + optional: true + }) + ], AlgorithmIdentifier.prototype, "parameters", void 0); + PrivateKeyInfo = class { + constructor() { + this.version = 0; + this.privateKeyAlgorithm = new AlgorithmIdentifier(); + this.privateKey = new ArrayBuffer(0); + } + }; + __decorate([ + AsnProp({ type: AsnPropTypes.Integer }) + ], PrivateKeyInfo.prototype, "version", void 0); + __decorate([ + AsnProp({ type: AlgorithmIdentifier }) + ], PrivateKeyInfo.prototype, "privateKeyAlgorithm", void 0); + __decorate([ + AsnProp({ type: AsnPropTypes.OctetString }) + ], PrivateKeyInfo.prototype, "privateKey", void 0); + __decorate([ + AsnProp({ type: AsnPropTypes.Any, optional: true }) + ], PrivateKeyInfo.prototype, "attributes", void 0); + PublicKeyInfo = class { + constructor() { + this.publicKeyAlgorithm = new AlgorithmIdentifier(); + this.publicKey = new ArrayBuffer(0); + } + }; + __decorate([ + AsnProp({ type: AlgorithmIdentifier }) + ], PublicKeyInfo.prototype, "publicKeyAlgorithm", void 0); + __decorate([ + AsnProp({ type: AsnPropTypes.BitString }) + ], PublicKeyInfo.prototype, "publicKey", void 0); + JsonBase64UrlArrayBufferConverter = { + fromJSON: (value) => import_pvtsutils4.Convert.FromBase64Url(value), + toJSON: (value) => import_pvtsutils4.Convert.ToBase64Url(new Uint8Array(value)) + }; + AsnIntegerArrayBufferConverter = { + fromASN: (value) => { + const valueHex = value.valueBlock.valueHex; + return !new Uint8Array(valueHex)[0] ? value.valueBlock.valueHex.slice(1) : value.valueBlock.valueHex; + }, + toASN: (value) => { + const valueHex = new Uint8Array(value)[0] > 127 ? (0, import_pvtsutils4.combine)(new Uint8Array([0]).buffer, value) : value; + return new Integer({ valueHex }); + } + }; + RsaPrivateKey = class { + constructor() { + this.version = 0; + this.modulus = new ArrayBuffer(0); + this.publicExponent = new ArrayBuffer(0); + this.privateExponent = new ArrayBuffer(0); + this.prime1 = new ArrayBuffer(0); + this.prime2 = new ArrayBuffer(0); + this.exponent1 = new ArrayBuffer(0); + this.exponent2 = new ArrayBuffer(0); + this.coefficient = new ArrayBuffer(0); + } + }; + __decorate([ + AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerConverter }) + ], RsaPrivateKey.prototype, "version", void 0); + __decorate([ + AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerArrayBufferConverter }), + JsonProp({ name: "n", converter: JsonBase64UrlArrayBufferConverter }) + ], RsaPrivateKey.prototype, "modulus", void 0); + __decorate([ + AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerArrayBufferConverter }), + JsonProp({ name: "e", converter: JsonBase64UrlArrayBufferConverter }) + ], RsaPrivateKey.prototype, "publicExponent", void 0); + __decorate([ + AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerArrayBufferConverter }), + JsonProp({ name: "d", converter: JsonBase64UrlArrayBufferConverter }) + ], RsaPrivateKey.prototype, "privateExponent", void 0); + __decorate([ + AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerArrayBufferConverter }), + JsonProp({ name: "p", converter: JsonBase64UrlArrayBufferConverter }) + ], RsaPrivateKey.prototype, "prime1", void 0); + __decorate([ + AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerArrayBufferConverter }), + JsonProp({ name: "q", converter: JsonBase64UrlArrayBufferConverter }) + ], RsaPrivateKey.prototype, "prime2", void 0); + __decorate([ + AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerArrayBufferConverter }), + JsonProp({ name: "dp", converter: JsonBase64UrlArrayBufferConverter }) + ], RsaPrivateKey.prototype, "exponent1", void 0); + __decorate([ + AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerArrayBufferConverter }), + JsonProp({ name: "dq", converter: JsonBase64UrlArrayBufferConverter }) + ], RsaPrivateKey.prototype, "exponent2", void 0); + __decorate([ + AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerArrayBufferConverter }), + JsonProp({ name: "qi", converter: JsonBase64UrlArrayBufferConverter }) + ], RsaPrivateKey.prototype, "coefficient", void 0); + __decorate([ + AsnProp({ type: AsnPropTypes.Any, optional: true }) + ], RsaPrivateKey.prototype, "otherPrimeInfos", void 0); + RsaPublicKey = class { + constructor() { + this.modulus = new ArrayBuffer(0); + this.publicExponent = new ArrayBuffer(0); + } + }; + __decorate([ + AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerArrayBufferConverter }), + JsonProp({ name: "n", converter: JsonBase64UrlArrayBufferConverter }) + ], RsaPublicKey.prototype, "modulus", void 0); + __decorate([ + AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerArrayBufferConverter }), + JsonProp({ name: "e", converter: JsonBase64UrlArrayBufferConverter }) + ], RsaPublicKey.prototype, "publicExponent", void 0); + EcPublicKey = class EcPublicKey2 { + constructor(value) { + this.value = new ArrayBuffer(0); + if (value) { + this.value = value; + } + } + toJSON() { + let bytes = new Uint8Array(this.value); + if (bytes[0] !== 4) { + throw new CryptoError("Wrong ECPoint. Current version supports only Uncompressed (0x04) point"); + } + bytes = new Uint8Array(this.value.slice(1)); + const size = bytes.length / 2; + const offset = 0; + const json = { + x: import_pvtsutils4.Convert.ToBase64Url(bytes.buffer.slice(offset, offset + size)), + y: import_pvtsutils4.Convert.ToBase64Url(bytes.buffer.slice(offset + size, offset + size + size)) + }; + return json; + } + fromJSON(json) { + if (!("x" in json)) { + throw new Error("x: Missing required property"); + } + if (!("y" in json)) { + throw new Error("y: Missing required property"); + } + const x = import_pvtsutils4.Convert.FromBase64Url(json.x); + const y = import_pvtsutils4.Convert.FromBase64Url(json.y); + const value = (0, import_pvtsutils4.combine)(new Uint8Array([4]).buffer, x, y); + this.value = new Uint8Array(value).buffer; + return this; + } + }; + __decorate([ + AsnProp({ type: AsnPropTypes.OctetString }) + ], EcPublicKey.prototype, "value", void 0); + EcPublicKey = __decorate([ + AsnType({ type: AsnTypeTypes.Choice }) + ], EcPublicKey); + EcPrivateKey = class { + constructor() { + this.version = 1; + this.privateKey = new ArrayBuffer(0); + } + fromJSON(json) { + if (!("d" in json)) { + throw new Error("d: Missing required property"); + } + this.privateKey = import_pvtsutils4.Convert.FromBase64Url(json.d); + if ("x" in json) { + const publicKey = new EcPublicKey(); + publicKey.fromJSON(json); + const asn = AsnSerializer.toASN(publicKey); + if ("valueHex" in asn.valueBlock) { + this.publicKey = asn.valueBlock.valueHex; + } + } + return this; + } + toJSON() { + const jwk = {}; + jwk.d = import_pvtsutils4.Convert.ToBase64Url(this.privateKey); + if (this.publicKey) { + Object.assign(jwk, new EcPublicKey(this.publicKey).toJSON()); + } + return jwk; + } + }; + __decorate([ + AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerConverter }) + ], EcPrivateKey.prototype, "version", void 0); + __decorate([ + AsnProp({ type: AsnPropTypes.OctetString }) + ], EcPrivateKey.prototype, "privateKey", void 0); + __decorate([ + AsnProp({ context: 0, type: AsnPropTypes.Any, optional: true }) + ], EcPrivateKey.prototype, "parameters", void 0); + __decorate([ + AsnProp({ context: 1, type: AsnPropTypes.BitString, optional: true }) + ], EcPrivateKey.prototype, "publicKey", void 0); + AsnIntegerWithoutPaddingConverter = { + fromASN: (value) => { + const bytes = new Uint8Array(value.valueBlock.valueHex); + return bytes[0] === 0 ? bytes.buffer.slice(1) : bytes.buffer; + }, + toASN: (value) => { + const bytes = new Uint8Array(value); + if (bytes[0] > 127) { + const newValue = new Uint8Array(bytes.length + 1); + newValue.set(bytes, 1); + return new Integer({ valueHex: newValue.buffer }); + } + return new Integer({ valueHex: value }); + } + }; + index$2 = /* @__PURE__ */ Object.freeze({ + __proto__: null, + AsnIntegerWithoutPaddingConverter + }); + EcUtils = class { + static decodePoint(data, pointSize) { + const view = import_pvtsutils4.BufferSourceConverter.toUint8Array(data); + if (view.length === 0 || view[0] !== 4) { + throw new Error("Only uncompressed point format supported"); + } + const n = (view.length - 1) / 2; + if (n !== Math.ceil(pointSize / 8)) { + throw new Error("Point does not match field size"); + } + const xb = view.slice(1, n + 1); + const yb = view.slice(n + 1, n + 1 + n); + return { x: xb, y: yb }; + } + static encodePoint(point, pointSize) { + const size = Math.ceil(pointSize / 8); + if (point.x.byteLength !== size || point.y.byteLength !== size) { + throw new Error("X,Y coordinates don't match point size criteria"); + } + const x = import_pvtsutils4.BufferSourceConverter.toUint8Array(point.x); + const y = import_pvtsutils4.BufferSourceConverter.toUint8Array(point.y); + const res = new Uint8Array(size * 2 + 1); + res[0] = 4; + res.set(x, 1); + res.set(y, size + 1); + return res; + } + static getSize(pointSize) { + return Math.ceil(pointSize / 8); + } + static encodeSignature(signature, pointSize) { + const size = this.getSize(pointSize); + const r = import_pvtsutils4.BufferSourceConverter.toUint8Array(signature.r); + const s = import_pvtsutils4.BufferSourceConverter.toUint8Array(signature.s); + const res = new Uint8Array(size * 2); + res.set(this.padStart(r, size)); + res.set(this.padStart(s, size), size); + return res; + } + static decodeSignature(data, pointSize) { + const size = this.getSize(pointSize); + const view = import_pvtsutils4.BufferSourceConverter.toUint8Array(data); + if (view.length !== size * 2) { + throw new Error("Incorrect size of the signature"); + } + const r = view.slice(0, size); + const s = view.slice(size); + return { + r: this.trimStart(r), + s: this.trimStart(s) + }; + } + static trimStart(data) { + let i = 0; + while (i < data.length - 1 && data[i] === 0) { + i++; + } + if (i === 0) { + return data; + } + return data.slice(i, data.length); + } + static padStart(data, size) { + if (size === data.length) { + return data; + } + const res = new Uint8Array(size); + res.set(data, size - data.length); + return res; + } + }; + EcDsaSignature = class _EcDsaSignature { + constructor() { + this.r = new ArrayBuffer(0); + this.s = new ArrayBuffer(0); + } + static fromWebCryptoSignature(value) { + const pointSize = value.byteLength / 2; + const point = EcUtils.decodeSignature(value, pointSize * 8); + const ecSignature = new _EcDsaSignature(); + ecSignature.r = import_pvtsutils4.BufferSourceConverter.toArrayBuffer(point.r); + ecSignature.s = import_pvtsutils4.BufferSourceConverter.toArrayBuffer(point.s); + return ecSignature; + } + toWebCryptoSignature(pointSize) { + pointSize !== null && pointSize !== void 0 ? pointSize : pointSize = Math.max(this.r.byteLength, this.s.byteLength) * 8; + const signature = EcUtils.encodeSignature(this, pointSize); + return signature.buffer; + } + }; + __decorate([ + AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerWithoutPaddingConverter }) + ], EcDsaSignature.prototype, "r", void 0); + __decorate([ + AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerWithoutPaddingConverter }) + ], EcDsaSignature.prototype, "s", void 0); + OneAsymmetricKey = class extends PrivateKeyInfo { + }; + __decorate([ + AsnProp({ context: 1, implicit: true, type: AsnPropTypes.BitString, optional: true }) + ], OneAsymmetricKey.prototype, "publicKey", void 0); + EdPrivateKey = class EdPrivateKey2 { + constructor() { + this.value = new ArrayBuffer(0); + } + fromJSON(json) { + if (!json.d) { + throw new Error("d: Missing required property"); + } + this.value = import_pvtsutils4.Convert.FromBase64Url(json.d); + return this; + } + toJSON() { + const jwk = { + d: import_pvtsutils4.Convert.ToBase64Url(this.value) + }; + return jwk; + } + }; + __decorate([ + AsnProp({ type: AsnPropTypes.OctetString }) + ], EdPrivateKey.prototype, "value", void 0); + EdPrivateKey = __decorate([ + AsnType({ type: AsnTypeTypes.Choice }) + ], EdPrivateKey); + EdPublicKey = class EdPublicKey2 { + constructor(value) { + this.value = new ArrayBuffer(0); + if (value) { + this.value = value; + } + } + toJSON() { + const json = { + x: import_pvtsutils4.Convert.ToBase64Url(this.value) + }; + return json; + } + fromJSON(json) { + if (!("x" in json)) { + throw new Error("x: Missing required property"); + } + this.value = import_pvtsutils4.Convert.FromBase64Url(json.x); + return this; + } + }; + __decorate([ + AsnProp({ type: AsnPropTypes.BitString }) + ], EdPublicKey.prototype, "value", void 0); + EdPublicKey = __decorate([ + AsnType({ type: AsnTypeTypes.Choice }) + ], EdPublicKey); + CurvePrivateKey = class CurvePrivateKey2 { + }; + __decorate([ + AsnProp({ type: AsnPropTypes.OctetString }), + JsonProp({ type: JsonPropTypes.String, converter: JsonBase64UrlArrayBufferConverter }) + ], CurvePrivateKey.prototype, "d", void 0); + CurvePrivateKey = __decorate([ + AsnType({ type: AsnTypeTypes.Choice }) + ], CurvePrivateKey); + idSecp256r1 = "1.2.840.10045.3.1.7"; + idEllipticCurve = "1.3.132.0"; + idSecp384r1 = `${idEllipticCurve}.34`; + idSecp521r1 = `${idEllipticCurve}.35`; + idSecp256k1 = `${idEllipticCurve}.10`; + idVersionOne = "1.3.36.3.3.2.8.1.1"; + idBrainpoolP160r1 = `${idVersionOne}.1`; + idBrainpoolP160t1 = `${idVersionOne}.2`; + idBrainpoolP192r1 = `${idVersionOne}.3`; + idBrainpoolP192t1 = `${idVersionOne}.4`; + idBrainpoolP224r1 = `${idVersionOne}.5`; + idBrainpoolP224t1 = `${idVersionOne}.6`; + idBrainpoolP256r1 = `${idVersionOne}.7`; + idBrainpoolP256t1 = `${idVersionOne}.8`; + idBrainpoolP320r1 = `${idVersionOne}.9`; + idBrainpoolP320t1 = `${idVersionOne}.10`; + idBrainpoolP384r1 = `${idVersionOne}.11`; + idBrainpoolP384t1 = `${idVersionOne}.12`; + idBrainpoolP512r1 = `${idVersionOne}.13`; + idBrainpoolP512t1 = `${idVersionOne}.14`; + idX25519 = "1.3.101.110"; + idX448 = "1.3.101.111"; + idEd25519 = "1.3.101.112"; + idEd448 = "1.3.101.113"; + index$1 = /* @__PURE__ */ Object.freeze({ + __proto__: null, + AlgorithmIdentifier, + get CurvePrivateKey() { + return CurvePrivateKey; + }, + EcDsaSignature, + EcPrivateKey, + get EcPublicKey() { + return EcPublicKey; + }, + get EdPrivateKey() { + return EdPrivateKey; + }, + get EdPublicKey() { + return EdPublicKey; + }, + get ObjectIdentifier() { + return ObjectIdentifier2; + }, + OneAsymmetricKey, + PrivateKeyInfo, + PublicKeyInfo, + RsaPrivateKey, + RsaPublicKey, + converters: index$2, + idBrainpoolP160r1, + idBrainpoolP160t1, + idBrainpoolP192r1, + idBrainpoolP192t1, + idBrainpoolP224r1, + idBrainpoolP224t1, + idBrainpoolP256r1, + idBrainpoolP256t1, + idBrainpoolP320r1, + idBrainpoolP320t1, + idBrainpoolP384r1, + idBrainpoolP384t1, + idBrainpoolP512r1, + idBrainpoolP512t1, + idEd25519, + idEd448, + idEllipticCurve, + idSecp256k1, + idSecp256r1, + idSecp384r1, + idSecp521r1, + idVersionOne, + idX25519, + idX448 + }); + EcCurves = class { + constructor() { + } + static register(item) { + const oid = new ObjectIdentifier2(); + oid.value = item.id; + const raw = AsnConvert.serialize(oid); + this.items.push({ + ...item, + raw + }); + this.names.push(item.name); + } + static find(nameOrId) { + nameOrId = nameOrId.toUpperCase(); + for (const item of this.items) { + if (item.name.toUpperCase() === nameOrId || item.id.toUpperCase() === nameOrId) { + return item; + } + } + return null; + } + static get(nameOrId) { + const res = this.find(nameOrId); + if (!res) { + throw new Error(`Unsupported EC named curve '${nameOrId}'`); + } + return res; + } + }; + EcCurves.items = []; + EcCurves.names = []; + EcCurves.register({ name: "P-256", id: idSecp256r1, size: 256 }); + EcCurves.register({ name: "P-384", id: idSecp384r1, size: 384 }); + EcCurves.register({ name: "P-521", id: idSecp521r1, size: 521 }); + EcCurves.register({ name: "K-256", id: idSecp256k1, size: 256 }); + EcCurves.register({ name: "brainpoolP160r1", id: idBrainpoolP160r1, size: 160 }); + EcCurves.register({ name: "brainpoolP160t1", id: idBrainpoolP160t1, size: 160 }); + EcCurves.register({ name: "brainpoolP192r1", id: idBrainpoolP192r1, size: 192 }); + EcCurves.register({ name: "brainpoolP192t1", id: idBrainpoolP192t1, size: 192 }); + EcCurves.register({ name: "brainpoolP224r1", id: idBrainpoolP224r1, size: 224 }); + EcCurves.register({ name: "brainpoolP224t1", id: idBrainpoolP224t1, size: 224 }); + EcCurves.register({ name: "brainpoolP256r1", id: idBrainpoolP256r1, size: 256 }); + EcCurves.register({ name: "brainpoolP256t1", id: idBrainpoolP256t1, size: 256 }); + EcCurves.register({ name: "brainpoolP320r1", id: idBrainpoolP320r1, size: 320 }); + EcCurves.register({ name: "brainpoolP320t1", id: idBrainpoolP320t1, size: 320 }); + EcCurves.register({ name: "brainpoolP384r1", id: idBrainpoolP384r1, size: 384 }); + EcCurves.register({ name: "brainpoolP384t1", id: idBrainpoolP384t1, size: 384 }); + EcCurves.register({ name: "brainpoolP512r1", id: idBrainpoolP512r1, size: 512 }); + EcCurves.register({ name: "brainpoolP512t1", id: idBrainpoolP512t1, size: 512 }); + HmacProvider = class extends ProviderCrypto { + constructor() { + super(...arguments); + this.name = "HMAC"; + this.hashAlgorithms = ["SHA-1", "SHA-256", "SHA-384", "SHA-512"]; + this.usages = ["sign", "verify"]; + } + getDefaultLength(algName) { + switch (algName.toUpperCase()) { + case "SHA-1": + case "SHA-256": + case "SHA-384": + case "SHA-512": + return 512; + default: + throw new Error(`Unknown algorithm name '${algName}'`); + } + } + checkGenerateKeyParams(algorithm) { + this.checkRequiredProperty(algorithm, "hash"); + this.checkHashAlgorithm(algorithm.hash, this.hashAlgorithms); + if ("length" in algorithm) { + if (typeof algorithm.length !== "number") { + throw new TypeError("length: Is not a Number"); + } + if (algorithm.length < 1) { + throw new RangeError("length: Number is out of range"); + } + } + } + checkImportParams(algorithm) { + this.checkRequiredProperty(algorithm, "hash"); + this.checkHashAlgorithm(algorithm.hash, this.hashAlgorithms); + } + }; + Pbkdf2Provider = class extends ProviderCrypto { + constructor() { + super(...arguments); + this.name = "PBKDF2"; + this.hashAlgorithms = ["SHA-1", "SHA-256", "SHA-384", "SHA-512"]; + this.usages = ["deriveBits", "deriveKey"]; + } + checkAlgorithmParams(algorithm) { + this.checkRequiredProperty(algorithm, "hash"); + this.checkHashAlgorithm(algorithm.hash, this.hashAlgorithms); + this.checkRequiredProperty(algorithm, "salt"); + if (!(algorithm.salt instanceof ArrayBuffer || ArrayBuffer.isView(algorithm.salt))) { + throw new TypeError("salt: Is not of type '(ArrayBuffer or ArrayBufferView)'"); + } + this.checkRequiredProperty(algorithm, "iterations"); + if (typeof algorithm.iterations !== "number") { + throw new TypeError("iterations: Is not a Number"); + } + if (algorithm.iterations < 1) { + throw new TypeError("iterations: Is less than 1"); + } + } + checkImportKey(format2, keyData, algorithm, extractable, keyUsages, ...args) { + super.checkImportKey(format2, keyData, algorithm, extractable, keyUsages); + if (extractable) { + throw new SyntaxError("extractable: Must be 'false'"); + } + } + }; + HkdfProvider = class extends ProviderCrypto { + constructor() { + super(...arguments); + this.name = "HKDF"; + this.hashAlgorithms = ["SHA-1", "SHA-256", "SHA-384", "SHA-512"]; + this.usages = ["deriveKey", "deriveBits"]; + } + checkAlgorithmParams(algorithm) { + this.checkRequiredProperty(algorithm, "hash"); + this.checkHashAlgorithm(algorithm.hash, this.hashAlgorithms); + this.checkRequiredProperty(algorithm, "salt"); + if (!import_pvtsutils4.BufferSourceConverter.isBufferSource(algorithm.salt)) { + throw new TypeError("salt: Is not of type '(ArrayBuffer or ArrayBufferView)'"); + } + this.checkRequiredProperty(algorithm, "info"); + if (!import_pvtsutils4.BufferSourceConverter.isBufferSource(algorithm.info)) { + throw new TypeError("salt: Is not of type '(ArrayBuffer or ArrayBufferView)'"); + } + } + checkImportKey(format2, keyData, algorithm, extractable, keyUsages, ...args) { + super.checkImportKey(format2, keyData, algorithm, extractable, keyUsages); + if (extractable) { + throw new SyntaxError("extractable: Must be 'false'"); + } + } + }; + ShakeProvider = class extends ProviderCrypto { + constructor() { + super(...arguments); + this.usages = []; + this.defaultLength = 0; + } + digest(...args) { + args[0] = { length: this.defaultLength, ...args[0] }; + return super.digest.apply(this, args); + } + checkDigest(algorithm, data) { + super.checkDigest(algorithm, data); + const length = algorithm.length || 0; + if (typeof length !== "number") { + throw new TypeError("length: Is not a Number"); + } + if (length < 0) { + throw new TypeError("length: Is negative"); + } + } + }; + Shake128Provider = class extends ShakeProvider { + constructor() { + super(...arguments); + this.name = "shake128"; + this.defaultLength = 16; + } + }; + Shake256Provider = class extends ShakeProvider { + constructor() { + super(...arguments); + this.name = "shake256"; + this.defaultLength = 32; + } + }; + Crypto = class { + get [Symbol.toStringTag]() { + return "Crypto"; + } + randomUUID() { + const b = this.getRandomValues(new Uint8Array(16)); + b[6] = b[6] & 15 | 64; + b[8] = b[8] & 63 | 128; + const uuid = import_pvtsutils4.Convert.ToHex(b).toLowerCase(); + return `${uuid.substring(0, 8)}-${uuid.substring(8, 12)}-${uuid.substring(12, 16)}-${uuid.substring(16, 20)}-${uuid.substring(20)}`; + } + }; + ProviderStorage = class { + constructor() { + this.items = {}; + } + get(algorithmName) { + return this.items[algorithmName.toLowerCase()] || null; + } + set(provider) { + this.items[provider.name.toLowerCase()] = provider; + } + removeAt(algorithmName) { + const provider = this.get(algorithmName.toLowerCase()); + if (provider) { + delete this.items[algorithmName]; + } + return provider; + } + has(name) { + return !!this.get(name); + } + get length() { + return Object.keys(this.items).length; + } + get algorithms() { + const algorithms = []; + for (const key in this.items) { + const provider = this.items[key]; + algorithms.push(provider.name); + } + return algorithms.sort(); + } + }; + SubtleCrypto = class _SubtleCrypto { + constructor() { + this.providers = new ProviderStorage(); + } + static isHashedAlgorithm(data) { + return data && typeof data === "object" && "name" in data && "hash" in data ? true : false; + } + get [Symbol.toStringTag]() { + return "SubtleCrypto"; + } + async digest(...args) { + this.checkRequiredArguments(args, 2, "digest"); + const [algorithm, data, ...params] = args; + const preparedAlgorithm = this.prepareAlgorithm(algorithm); + const preparedData = import_pvtsutils4.BufferSourceConverter.toArrayBuffer(data); + const provider = this.getProvider(preparedAlgorithm.name); + const result = await provider.digest(preparedAlgorithm, preparedData, ...params); + return result; + } + async generateKey(...args) { + this.checkRequiredArguments(args, 3, "generateKey"); + const [algorithm, extractable, keyUsages, ...params] = args; + const preparedAlgorithm = this.prepareAlgorithm(algorithm); + const provider = this.getProvider(preparedAlgorithm.name); + const result = await provider.generateKey({ ...preparedAlgorithm, name: provider.name }, extractable, keyUsages, ...params); + return result; + } + async sign(...args) { + this.checkRequiredArguments(args, 3, "sign"); + const [algorithm, key, data, ...params] = args; + this.checkCryptoKey(key); + const preparedAlgorithm = this.prepareAlgorithm(algorithm); + const preparedData = import_pvtsutils4.BufferSourceConverter.toArrayBuffer(data); + const provider = this.getProvider(preparedAlgorithm.name); + const result = await provider.sign({ ...preparedAlgorithm, name: provider.name }, key, preparedData, ...params); + return result; + } + async verify(...args) { + this.checkRequiredArguments(args, 4, "verify"); + const [algorithm, key, signature, data, ...params] = args; + this.checkCryptoKey(key); + const preparedAlgorithm = this.prepareAlgorithm(algorithm); + const preparedData = import_pvtsutils4.BufferSourceConverter.toArrayBuffer(data); + const preparedSignature = import_pvtsutils4.BufferSourceConverter.toArrayBuffer(signature); + const provider = this.getProvider(preparedAlgorithm.name); + const result = await provider.verify({ ...preparedAlgorithm, name: provider.name }, key, preparedSignature, preparedData, ...params); + return result; + } + async encrypt(...args) { + this.checkRequiredArguments(args, 3, "encrypt"); + const [algorithm, key, data, ...params] = args; + this.checkCryptoKey(key); + const preparedAlgorithm = this.prepareAlgorithm(algorithm); + const preparedData = import_pvtsutils4.BufferSourceConverter.toArrayBuffer(data); + const provider = this.getProvider(preparedAlgorithm.name); + const result = await provider.encrypt({ ...preparedAlgorithm, name: provider.name }, key, preparedData, { keyUsage: true }, ...params); + return result; + } + async decrypt(...args) { + this.checkRequiredArguments(args, 3, "decrypt"); + const [algorithm, key, data, ...params] = args; + this.checkCryptoKey(key); + const preparedAlgorithm = this.prepareAlgorithm(algorithm); + const preparedData = import_pvtsutils4.BufferSourceConverter.toArrayBuffer(data); + const provider = this.getProvider(preparedAlgorithm.name); + const result = await provider.decrypt({ ...preparedAlgorithm, name: provider.name }, key, preparedData, { keyUsage: true }, ...params); + return result; + } + async deriveBits(...args) { + this.checkRequiredArguments(args, 3, "deriveBits"); + const [algorithm, baseKey, length, ...params] = args; + this.checkCryptoKey(baseKey); + const preparedAlgorithm = this.prepareAlgorithm(algorithm); + const provider = this.getProvider(preparedAlgorithm.name); + const result = await provider.deriveBits({ ...preparedAlgorithm, name: provider.name }, baseKey, length, { keyUsage: true }, ...params); + return result; + } + async deriveKey(...args) { + this.checkRequiredArguments(args, 5, "deriveKey"); + const [algorithm, baseKey, derivedKeyType, extractable, keyUsages, ...params] = args; + const preparedDerivedKeyType = this.prepareAlgorithm(derivedKeyType); + const importProvider = this.getProvider(preparedDerivedKeyType.name); + importProvider.checkDerivedKeyParams(preparedDerivedKeyType); + const preparedAlgorithm = this.prepareAlgorithm(algorithm); + const provider = this.getProvider(preparedAlgorithm.name); + provider.checkCryptoKey(baseKey, "deriveKey"); + const derivedBits = await provider.deriveBits({ ...preparedAlgorithm, name: provider.name }, baseKey, derivedKeyType.length || 512, { keyUsage: false }, ...params); + return this.importKey("raw", derivedBits, derivedKeyType, extractable, keyUsages, ...params); + } + async exportKey(...args) { + this.checkRequiredArguments(args, 2, "exportKey"); + const [format2, key, ...params] = args; + this.checkCryptoKey(key); + const provider = this.getProvider(key.algorithm.name); + const result = await provider.exportKey(format2, key, ...params); + return result; + } + async importKey(...args) { + this.checkRequiredArguments(args, 5, "importKey"); + const [format2, keyData, algorithm, extractable, keyUsages, ...params] = args; + const preparedAlgorithm = this.prepareAlgorithm(algorithm); + const provider = this.getProvider(preparedAlgorithm.name); + if (["pkcs8", "spki", "raw"].indexOf(format2) !== -1) { + const preparedData = import_pvtsutils4.BufferSourceConverter.toArrayBuffer(keyData); + return provider.importKey(format2, preparedData, { ...preparedAlgorithm, name: provider.name }, extractable, keyUsages, ...params); + } else { + if (!keyData.kty) { + throw new TypeError("keyData: Is not JSON"); + } + } + return provider.importKey(format2, keyData, { ...preparedAlgorithm, name: provider.name }, extractable, keyUsages, ...params); + } + async wrapKey(format2, key, wrappingKey, wrapAlgorithm, ...args) { + let keyData = await this.exportKey(format2, key, ...args); + if (format2 === "jwk") { + const json = JSON.stringify(keyData); + keyData = import_pvtsutils4.Convert.FromUtf8String(json); + } + const preparedAlgorithm = this.prepareAlgorithm(wrapAlgorithm); + const preparedData = import_pvtsutils4.BufferSourceConverter.toArrayBuffer(keyData); + const provider = this.getProvider(preparedAlgorithm.name); + return provider.encrypt({ ...preparedAlgorithm, name: provider.name }, wrappingKey, preparedData, { keyUsage: false }, ...args); + } + async unwrapKey(format2, wrappedKey, unwrappingKey, unwrapAlgorithm, unwrappedKeyAlgorithm, extractable, keyUsages, ...args) { + const preparedAlgorithm = this.prepareAlgorithm(unwrapAlgorithm); + const preparedData = import_pvtsutils4.BufferSourceConverter.toArrayBuffer(wrappedKey); + const provider = this.getProvider(preparedAlgorithm.name); + let keyData = await provider.decrypt({ ...preparedAlgorithm, name: provider.name }, unwrappingKey, preparedData, { keyUsage: false }, ...args); + if (format2 === "jwk") { + try { + keyData = JSON.parse(import_pvtsutils4.Convert.ToUtf8String(keyData)); + } catch (e) { + const error = new TypeError("wrappedKey: Is not a JSON"); + error.internal = e; + throw error; + } + } + return this.importKey(format2, keyData, unwrappedKeyAlgorithm, extractable, keyUsages, ...args); + } + checkRequiredArguments(args, size, methodName) { + if (args.length < size) { + throw new TypeError(`Failed to execute '${methodName}' on 'SubtleCrypto': ${size} arguments required, but only ${args.length} present`); + } + } + prepareAlgorithm(algorithm) { + if (typeof algorithm === "string") { + return { + name: algorithm + }; + } + if (_SubtleCrypto.isHashedAlgorithm(algorithm)) { + const preparedAlgorithm = { ...algorithm }; + preparedAlgorithm.hash = this.prepareAlgorithm(algorithm.hash); + return preparedAlgorithm; + } + return { ...algorithm }; + } + getProvider(name) { + const provider = this.providers.get(name); + if (!provider) { + throw new AlgorithmError("Unrecognized name"); + } + return provider; + } + checkCryptoKey(key) { + if (!(key instanceof CryptoKey)) { + throw new TypeError(`Key is not of type 'CryptoKey'`); + } + } + }; + } + }); + + // node_modules/.pnpm/@peculiar+webcrypto@1.4.3/node_modules/@peculiar/webcrypto/build/webcrypto.es.js + var webcrypto_es_exports = {}; + __export(webcrypto_es_exports, { + Crypto: () => Crypto2, + CryptoKey: () => CryptoKey + }); + function getCryptoKey(key) { + const res = keyStorage.get(key); + if (!res) { + throw new OperationError("Cannot get CryptoKey from secure storage"); + } + return res; + } + function setCryptoKey(value) { + const key = CryptoKey.create(value.algorithm, value.type, value.extractable, value.usages); + Object.freeze(key); + keyStorage.set(key, value); + return key; + } + function bitShiftLeft(buffer) { + const shifted = Buffer.alloc(buffer.length); + const last = buffer.length - 1; + for (let index = 0; index < last; index++) { + shifted[index] = buffer[index] << 1; + if (buffer[index + 1] & 128) { + shifted[index] += 1; + } + } + shifted[last] = buffer[last] << 1; + return shifted; + } + function xor(a2, b) { + const length = Math.min(a2.length, b.length); + const output = Buffer.alloc(length); + for (let index = 0; index < length; index++) { + output[index] = a2[index] ^ b[index]; + } + return output; + } + function aes(key, message) { + const cipher = crypto.createCipheriv(`aes${key.length << 3}`, key, zero); + const result = cipher.update(message); + cipher.final(); + return result; + } + function getMessageBlock(message, blockIndex) { + const block = Buffer.alloc(blockSize); + const start = blockIndex * blockSize; + const end = start + blockSize; + message.copy(block, 0, start, end); + return block; + } + function getPaddedMessageBlock(message, blockIndex) { + const block = Buffer.alloc(blockSize); + const start = blockIndex * blockSize; + const end = message.length; + block.fill(0); + message.copy(block, 0, start, end); + block[end - start] = 128; + return block; + } + function generateSubkeys(key) { + const l = aes(key, zero); + let subkey1 = bitShiftLeft(l); + if (l[0] & 128) { + subkey1 = xor(subkey1, rb); + } + let subkey2 = bitShiftLeft(subkey1); + if (subkey1[0] & 128) { + subkey2 = xor(subkey2, rb); + } + return { subkey1, subkey2 }; + } + function aesCmac(key, message) { + const subkeys = generateSubkeys(key); + let blockCount = Math.ceil(message.length / blockSize); + let lastBlockCompleteFlag; + let lastBlock; + if (blockCount === 0) { + blockCount = 1; + lastBlockCompleteFlag = false; + } else { + lastBlockCompleteFlag = message.length % blockSize === 0; + } + const lastBlockIndex = blockCount - 1; + if (lastBlockCompleteFlag) { + lastBlock = xor(getMessageBlock(message, lastBlockIndex), subkeys.subkey1); + } else { + lastBlock = xor(getPaddedMessageBlock(message, lastBlockIndex), subkeys.subkey2); + } + let x = zero; + let y; + for (let index = 0; index < lastBlockIndex; index++) { + y = xor(x, getMessageBlock(message, index)); + x = aes(key, y); + } + y = xor(lastBlock, x); + return aes(key, y); + } + function getJwkAlgorithm(algorithm) { + switch (algorithm.name.toUpperCase()) { + case "RSA-OAEP": { + const mdSize = /(\d+)$/.exec(algorithm.hash.name)[1]; + return `RSA-OAEP${mdSize !== "1" ? `-${mdSize}` : ""}`; + } + case "RSASSA-PKCS1-V1_5": + return `RS${/(\d+)$/.exec(algorithm.hash.name)[1]}`; + case "RSA-PSS": + return `PS${/(\d+)$/.exec(algorithm.hash.name)[1]}`; + case "RSA-PKCS1": + return `RS1`; + default: + throw new OperationError("algorithm: Is not recognized"); + } + } + function getOidByNamedCurve$1(namedCurve) { + const oid = namedOIDs[namedCurve]; + if (!oid) { + throw new OperationError(`Cannot convert WebCrypto named curve '${namedCurve}' to OID`); + } + return oid; + } + function getOidByNamedCurve(namedCurve) { + const oid = edOIDs[namedCurve.toLowerCase()]; + if (!oid) { + throw new OperationError(`Cannot convert WebCrypto named curve '${namedCurve}' to OID`); + } + return oid; + } + var crypto, import_crypto, process2, import_pvtsutils6, JsonBase64UrlConverter, CryptoKey2, SymmetricKey, AsymmetricKey, AesCryptoKey, AesCrypto, keyStorage, AesCbcProvider2, zero, rb, blockSize, AesCmacProvider2, AesCtrProvider2, AesGcmProvider2, AesKwProvider2, AesEcbProvider2, DesCryptoKey, DesCrypto, DesCbcProvider, DesEde3CbcProvider, RsaPrivateKey2, RsaPublicKey2, RsaCrypto, RsaSsaProvider2, RsaPssProvider2, ShaCrypto, RsaOaepProvider2, RsaEsProvider, namedOIDs, EcPrivateKey2, EcPublicKey3, Sha1Provider, Sha256Provider, Sha384Provider, Sha512Provider, Sha3256Provider, Sha3384Provider, Sha3512Provider, EcCrypto, EcdsaProvider2, EcdhProvider2, edOIDs, EdPrivateKey3, EdPublicKey3, EdCrypto, EdDsaProvider2, EcdhEsProvider2, PbkdfCryptoKey, Pbkdf2Provider2, HmacCryptoKey, HmacProvider2, HkdfCryptoKey, HkdfProvider2, ShakeCrypto, Shake128Provider2, Shake256Provider2, SubtleCrypto2, Crypto2; + var init_webcrypto_es = __esm({ + "node_modules/.pnpm/@peculiar+webcrypto@1.4.3/node_modules/@peculiar/webcrypto/build/webcrypto.es.js"() { + init_webcrypto_core_es(); + init_webcrypto_core_es(); + init_webcrypto_core_es(); + crypto = __toESM(__require("crypto")); + import_crypto = __toESM(__require("crypto")); + process2 = __toESM(__require("process")); + init_tslib_es6(); + init_index_es2(); + import_pvtsutils6 = __toESM(require_build()); + init_es2015(); + JsonBase64UrlConverter = { + fromJSON: (value) => Buffer.from(import_pvtsutils6.Convert.FromBase64Url(value)), + toJSON: (value) => import_pvtsutils6.Convert.ToBase64Url(value) + }; + CryptoKey2 = class extends CryptoKey { + constructor() { + super(...arguments); + this.data = Buffer.alloc(0); + this.algorithm = { name: "" }; + this.extractable = false; + this.type = "secret"; + this.usages = []; + this.kty = "oct"; + this.alg = ""; + } + }; + __decorate([ + JsonProp({ name: "ext", type: JsonPropTypes.Boolean, optional: true }) + ], CryptoKey2.prototype, "extractable", void 0); + __decorate([ + JsonProp({ name: "key_ops", type: JsonPropTypes.String, repeated: true, optional: true }) + ], CryptoKey2.prototype, "usages", void 0); + __decorate([ + JsonProp({ type: JsonPropTypes.String }) + ], CryptoKey2.prototype, "kty", void 0); + __decorate([ + JsonProp({ type: JsonPropTypes.String, optional: true }) + ], CryptoKey2.prototype, "alg", void 0); + SymmetricKey = class extends CryptoKey2 { + constructor() { + super(...arguments); + this.kty = "oct"; + this.type = "secret"; + } + }; + AsymmetricKey = class extends CryptoKey2 { + }; + AesCryptoKey = class extends SymmetricKey { + get alg() { + switch (this.algorithm.name.toUpperCase()) { + case "AES-CBC": + return `A${this.algorithm.length}CBC`; + case "AES-CTR": + return `A${this.algorithm.length}CTR`; + case "AES-GCM": + return `A${this.algorithm.length}GCM`; + case "AES-KW": + return `A${this.algorithm.length}KW`; + case "AES-CMAC": + return `A${this.algorithm.length}CMAC`; + case "AES-ECB": + return `A${this.algorithm.length}ECB`; + default: + throw new AlgorithmError("Unsupported algorithm name"); + } + } + set alg(value) { + } + }; + __decorate([ + JsonProp({ name: "k", converter: JsonBase64UrlConverter }) + ], AesCryptoKey.prototype, "data", void 0); + AesCrypto = class { + static async generateKey(algorithm, extractable, keyUsages) { + const key = new AesCryptoKey(); + key.algorithm = algorithm; + key.extractable = extractable; + key.usages = keyUsages; + key.data = import_crypto.default.randomBytes(algorithm.length >> 3); + return key; + } + static async exportKey(format2, key) { + if (!(key instanceof AesCryptoKey)) { + throw new Error("key: Is not AesCryptoKey"); + } + switch (format2.toLowerCase()) { + case "jwk": + return JsonSerializer.toJSON(key); + case "raw": + return new Uint8Array(key.data).buffer; + default: + throw new OperationError("format: Must be 'jwk' or 'raw'"); + } + } + static async importKey(format2, keyData, algorithm, extractable, keyUsages) { + let key; + switch (format2.toLowerCase()) { + case "jwk": + key = JsonParser.fromJSON(keyData, { targetSchema: AesCryptoKey }); + break; + case "raw": + key = new AesCryptoKey(); + key.data = Buffer.from(keyData); + break; + default: + throw new OperationError("format: Must be 'jwk' or 'raw'"); + } + key.algorithm = algorithm; + key.algorithm.length = key.data.length << 3; + key.extractable = extractable; + key.usages = keyUsages; + switch (key.algorithm.length) { + case 128: + case 192: + case 256: + break; + default: + throw new OperationError("keyData: Is wrong key length"); + } + return key; + } + static async encrypt(algorithm, key, data) { + switch (algorithm.name.toUpperCase()) { + case "AES-CBC": + return this.encryptAesCBC(algorithm, key, Buffer.from(data)); + case "AES-CTR": + return this.encryptAesCTR(algorithm, key, Buffer.from(data)); + case "AES-GCM": + return this.encryptAesGCM(algorithm, key, Buffer.from(data)); + case "AES-KW": + return this.encryptAesKW(algorithm, key, Buffer.from(data)); + case "AES-ECB": + return this.encryptAesECB(algorithm, key, Buffer.from(data)); + default: + throw new OperationError("algorithm: Is not recognized"); + } + } + static async decrypt(algorithm, key, data) { + if (!(key instanceof AesCryptoKey)) { + throw new Error("key: Is not AesCryptoKey"); + } + switch (algorithm.name.toUpperCase()) { + case "AES-CBC": + return this.decryptAesCBC(algorithm, key, Buffer.from(data)); + case "AES-CTR": + return this.decryptAesCTR(algorithm, key, Buffer.from(data)); + case "AES-GCM": + return this.decryptAesGCM(algorithm, key, Buffer.from(data)); + case "AES-KW": + return this.decryptAesKW(algorithm, key, Buffer.from(data)); + case "AES-ECB": + return this.decryptAesECB(algorithm, key, Buffer.from(data)); + default: + throw new OperationError("algorithm: Is not recognized"); + } + } + static async encryptAesCBC(algorithm, key, data) { + const cipher = import_crypto.default.createCipheriv(`aes-${key.algorithm.length}-cbc`, key.data, new Uint8Array(algorithm.iv)); + let enc = cipher.update(data); + enc = Buffer.concat([enc, cipher.final()]); + const res = new Uint8Array(enc).buffer; + return res; + } + static async decryptAesCBC(algorithm, key, data) { + const decipher = import_crypto.default.createDecipheriv(`aes-${key.algorithm.length}-cbc`, key.data, new Uint8Array(algorithm.iv)); + let dec = decipher.update(data); + dec = Buffer.concat([dec, decipher.final()]); + return new Uint8Array(dec).buffer; + } + static async encryptAesCTR(algorithm, key, data) { + const cipher = import_crypto.default.createCipheriv(`aes-${key.algorithm.length}-ctr`, key.data, Buffer.from(algorithm.counter)); + let enc = cipher.update(data); + enc = Buffer.concat([enc, cipher.final()]); + const res = new Uint8Array(enc).buffer; + return res; + } + static async decryptAesCTR(algorithm, key, data) { + const decipher = import_crypto.default.createDecipheriv(`aes-${key.algorithm.length}-ctr`, key.data, new Uint8Array(algorithm.counter)); + let dec = decipher.update(data); + dec = Buffer.concat([dec, decipher.final()]); + return new Uint8Array(dec).buffer; + } + static async encryptAesGCM(algorithm, key, data) { + const cipher = import_crypto.default.createCipheriv(`aes-${key.algorithm.length}-gcm`, key.data, Buffer.from(algorithm.iv), { + authTagLength: (algorithm.tagLength || 128) >> 3 + }); + if (algorithm.additionalData) { + cipher.setAAD(Buffer.from(algorithm.additionalData)); + } + let enc = cipher.update(data); + enc = Buffer.concat([enc, cipher.final(), cipher.getAuthTag()]); + const res = new Uint8Array(enc).buffer; + return res; + } + static async decryptAesGCM(algorithm, key, data) { + const decipher = import_crypto.default.createDecipheriv(`aes-${key.algorithm.length}-gcm`, key.data, new Uint8Array(algorithm.iv)); + const tagLength = (algorithm.tagLength || 128) >> 3; + const enc = data.slice(0, data.length - tagLength); + const tag = data.slice(data.length - tagLength); + if (algorithm.additionalData) { + decipher.setAAD(Buffer.from(algorithm.additionalData)); + } + decipher.setAuthTag(tag); + let dec = decipher.update(enc); + dec = Buffer.concat([dec, decipher.final()]); + return new Uint8Array(dec).buffer; + } + static async encryptAesKW(algorithm, key, data) { + const cipher = import_crypto.default.createCipheriv(`id-aes${key.algorithm.length}-wrap`, key.data, this.AES_KW_IV); + let enc = cipher.update(data); + enc = Buffer.concat([enc, cipher.final()]); + return new Uint8Array(enc).buffer; + } + static async decryptAesKW(algorithm, key, data) { + const decipher = import_crypto.default.createDecipheriv(`id-aes${key.algorithm.length}-wrap`, key.data, this.AES_KW_IV); + let dec = decipher.update(data); + dec = Buffer.concat([dec, decipher.final()]); + return new Uint8Array(dec).buffer; + } + static async encryptAesECB(algorithm, key, data) { + const cipher = import_crypto.default.createCipheriv(`aes-${key.algorithm.length}-ecb`, key.data, new Uint8Array(0)); + let enc = cipher.update(data); + enc = Buffer.concat([enc, cipher.final()]); + const res = new Uint8Array(enc).buffer; + return res; + } + static async decryptAesECB(algorithm, key, data) { + const decipher = import_crypto.default.createDecipheriv(`aes-${key.algorithm.length}-ecb`, key.data, new Uint8Array(0)); + let dec = decipher.update(data); + dec = Buffer.concat([dec, decipher.final()]); + return new Uint8Array(dec).buffer; + } + }; + AesCrypto.AES_KW_IV = Buffer.from("A6A6A6A6A6A6A6A6", "hex"); + keyStorage = /* @__PURE__ */ new WeakMap(); + AesCbcProvider2 = class extends AesCbcProvider { + async onGenerateKey(algorithm, extractable, keyUsages) { + const key = await AesCrypto.generateKey({ + name: this.name, + length: algorithm.length + }, extractable, keyUsages); + return setCryptoKey(key); + } + async onEncrypt(algorithm, key, data) { + return AesCrypto.encrypt(algorithm, getCryptoKey(key), new Uint8Array(data)); + } + async onDecrypt(algorithm, key, data) { + return AesCrypto.decrypt(algorithm, getCryptoKey(key), new Uint8Array(data)); + } + async onExportKey(format2, key) { + return AesCrypto.exportKey(format2, getCryptoKey(key)); + } + async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { + const key = await AesCrypto.importKey(format2, keyData, { name: algorithm.name }, extractable, keyUsages); + return setCryptoKey(key); + } + checkCryptoKey(key, keyUsage) { + super.checkCryptoKey(key, keyUsage); + if (!(getCryptoKey(key) instanceof AesCryptoKey)) { + throw new TypeError("key: Is not a AesCryptoKey"); + } + } + }; + zero = Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + rb = Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135]); + blockSize = 16; + AesCmacProvider2 = class extends AesCmacProvider { + async onGenerateKey(algorithm, extractable, keyUsages) { + const key = await AesCrypto.generateKey({ + name: this.name, + length: algorithm.length + }, extractable, keyUsages); + return setCryptoKey(key); + } + async onSign(algorithm, key, data) { + const result = aesCmac(getCryptoKey(key).data, Buffer.from(data)); + return new Uint8Array(result).buffer; + } + async onVerify(algorithm, key, signature, data) { + const signature2 = await this.sign(algorithm, key, data); + return Buffer.from(signature).compare(Buffer.from(signature2)) === 0; + } + async onExportKey(format2, key) { + return AesCrypto.exportKey(format2, getCryptoKey(key)); + } + async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { + const res = await AesCrypto.importKey(format2, keyData, { name: algorithm.name }, extractable, keyUsages); + return setCryptoKey(res); + } + checkCryptoKey(key, keyUsage) { + super.checkCryptoKey(key, keyUsage); + if (!(getCryptoKey(key) instanceof AesCryptoKey)) { + throw new TypeError("key: Is not a AesCryptoKey"); + } + } + }; + AesCtrProvider2 = class extends AesCtrProvider { + async onGenerateKey(algorithm, extractable, keyUsages) { + const key = await AesCrypto.generateKey({ + name: this.name, + length: algorithm.length + }, extractable, keyUsages); + return setCryptoKey(key); + } + async onEncrypt(algorithm, key, data) { + return AesCrypto.encrypt(algorithm, getCryptoKey(key), new Uint8Array(data)); + } + async onDecrypt(algorithm, key, data) { + return AesCrypto.decrypt(algorithm, getCryptoKey(key), new Uint8Array(data)); + } + async onExportKey(format2, key) { + return AesCrypto.exportKey(format2, getCryptoKey(key)); + } + async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { + const res = await AesCrypto.importKey(format2, keyData, { name: algorithm.name }, extractable, keyUsages); + return setCryptoKey(res); + } + checkCryptoKey(key, keyUsage) { + super.checkCryptoKey(key, keyUsage); + if (!(getCryptoKey(key) instanceof AesCryptoKey)) { + throw new TypeError("key: Is not a AesCryptoKey"); + } + } + }; + AesGcmProvider2 = class extends AesGcmProvider { + async onGenerateKey(algorithm, extractable, keyUsages) { + const key = await AesCrypto.generateKey({ + name: this.name, + length: algorithm.length + }, extractable, keyUsages); + return setCryptoKey(key); + } + async onEncrypt(algorithm, key, data) { + return AesCrypto.encrypt(algorithm, getCryptoKey(key), new Uint8Array(data)); + } + async onDecrypt(algorithm, key, data) { + return AesCrypto.decrypt(algorithm, getCryptoKey(key), new Uint8Array(data)); + } + async onExportKey(format2, key) { + return AesCrypto.exportKey(format2, getCryptoKey(key)); + } + async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { + const res = await AesCrypto.importKey(format2, keyData, { name: algorithm.name }, extractable, keyUsages); + return setCryptoKey(res); + } + checkCryptoKey(key, keyUsage) { + super.checkCryptoKey(key, keyUsage); + if (!(getCryptoKey(key) instanceof AesCryptoKey)) { + throw new TypeError("key: Is not a AesCryptoKey"); + } + } + }; + AesKwProvider2 = class extends AesKwProvider { + async onGenerateKey(algorithm, extractable, keyUsages) { + const res = await AesCrypto.generateKey({ + name: this.name, + length: algorithm.length + }, extractable, keyUsages); + return setCryptoKey(res); + } + async onExportKey(format2, key) { + return AesCrypto.exportKey(format2, getCryptoKey(key)); + } + async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { + const res = await AesCrypto.importKey(format2, keyData, { name: algorithm.name }, extractable, keyUsages); + return setCryptoKey(res); + } + async onEncrypt(algorithm, key, data) { + return AesCrypto.encrypt(algorithm, getCryptoKey(key), new Uint8Array(data)); + } + async onDecrypt(algorithm, key, data) { + return AesCrypto.decrypt(algorithm, getCryptoKey(key), new Uint8Array(data)); + } + checkCryptoKey(key, keyUsage) { + super.checkCryptoKey(key, keyUsage); + if (!(getCryptoKey(key) instanceof AesCryptoKey)) { + throw new TypeError("key: Is not a AesCryptoKey"); + } + } + }; + AesEcbProvider2 = class extends AesEcbProvider { + async onGenerateKey(algorithm, extractable, keyUsages) { + const key = await AesCrypto.generateKey({ + name: this.name, + length: algorithm.length + }, extractable, keyUsages); + return setCryptoKey(key); + } + async onEncrypt(algorithm, key, data) { + return AesCrypto.encrypt(algorithm, getCryptoKey(key), new Uint8Array(data)); + } + async onDecrypt(algorithm, key, data) { + return AesCrypto.decrypt(algorithm, getCryptoKey(key), new Uint8Array(data)); + } + async onExportKey(format2, key) { + return AesCrypto.exportKey(format2, getCryptoKey(key)); + } + async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { + const res = await AesCrypto.importKey(format2, keyData, { name: algorithm.name }, extractable, keyUsages); + return setCryptoKey(res); + } + checkCryptoKey(key, keyUsage) { + super.checkCryptoKey(key, keyUsage); + if (!(getCryptoKey(key) instanceof AesCryptoKey)) { + throw new TypeError("key: Is not a AesCryptoKey"); + } + } + }; + DesCryptoKey = class extends SymmetricKey { + get alg() { + switch (this.algorithm.name.toUpperCase()) { + case "DES-CBC": + return `DES-CBC`; + case "DES-EDE3-CBC": + return `3DES-CBC`; + default: + throw new AlgorithmError("Unsupported algorithm name"); + } + } + set alg(value) { + } + }; + __decorate([ + JsonProp({ name: "k", converter: JsonBase64UrlConverter }) + ], DesCryptoKey.prototype, "data", void 0); + DesCrypto = class { + static async generateKey(algorithm, extractable, keyUsages) { + const key = new DesCryptoKey(); + key.algorithm = algorithm; + key.extractable = extractable; + key.usages = keyUsages; + key.data = import_crypto.default.randomBytes(algorithm.length >> 3); + return key; + } + static async exportKey(format2, key) { + switch (format2.toLowerCase()) { + case "jwk": + return JsonSerializer.toJSON(key); + case "raw": + return new Uint8Array(key.data).buffer; + default: + throw new OperationError("format: Must be 'jwk' or 'raw'"); + } + } + static async importKey(format2, keyData, algorithm, extractable, keyUsages) { + let key; + switch (format2.toLowerCase()) { + case "jwk": + key = JsonParser.fromJSON(keyData, { targetSchema: DesCryptoKey }); + break; + case "raw": + key = new DesCryptoKey(); + key.data = Buffer.from(keyData); + break; + default: + throw new OperationError("format: Must be 'jwk' or 'raw'"); + } + key.algorithm = algorithm; + key.extractable = extractable; + key.usages = keyUsages; + return key; + } + static async encrypt(algorithm, key, data) { + switch (algorithm.name.toUpperCase()) { + case "DES-CBC": + return this.encryptDesCBC(algorithm, key, Buffer.from(data)); + case "DES-EDE3-CBC": + return this.encryptDesEDE3CBC(algorithm, key, Buffer.from(data)); + default: + throw new OperationError("algorithm: Is not recognized"); + } + } + static async decrypt(algorithm, key, data) { + if (!(key instanceof DesCryptoKey)) { + throw new Error("key: Is not DesCryptoKey"); + } + switch (algorithm.name.toUpperCase()) { + case "DES-CBC": + return this.decryptDesCBC(algorithm, key, Buffer.from(data)); + case "DES-EDE3-CBC": + return this.decryptDesEDE3CBC(algorithm, key, Buffer.from(data)); + default: + throw new OperationError("algorithm: Is not recognized"); + } + } + static async encryptDesCBC(algorithm, key, data) { + const cipher = import_crypto.default.createCipheriv(`des-cbc`, key.data, new Uint8Array(algorithm.iv)); + let enc = cipher.update(data); + enc = Buffer.concat([enc, cipher.final()]); + const res = new Uint8Array(enc).buffer; + return res; + } + static async decryptDesCBC(algorithm, key, data) { + const decipher = import_crypto.default.createDecipheriv(`des-cbc`, key.data, new Uint8Array(algorithm.iv)); + let dec = decipher.update(data); + dec = Buffer.concat([dec, decipher.final()]); + return new Uint8Array(dec).buffer; + } + static async encryptDesEDE3CBC(algorithm, key, data) { + const cipher = import_crypto.default.createCipheriv(`des-ede3-cbc`, key.data, Buffer.from(algorithm.iv)); + let enc = cipher.update(data); + enc = Buffer.concat([enc, cipher.final()]); + const res = new Uint8Array(enc).buffer; + return res; + } + static async decryptDesEDE3CBC(algorithm, key, data) { + const decipher = import_crypto.default.createDecipheriv(`des-ede3-cbc`, key.data, new Uint8Array(algorithm.iv)); + let dec = decipher.update(data); + dec = Buffer.concat([dec, decipher.final()]); + return new Uint8Array(dec).buffer; + } + }; + DesCbcProvider = class extends DesProvider { + constructor() { + super(...arguments); + this.keySizeBits = 64; + this.ivSize = 8; + this.name = "DES-CBC"; + } + async onGenerateKey(algorithm, extractable, keyUsages) { + const key = await DesCrypto.generateKey({ + name: this.name, + length: this.keySizeBits + }, extractable, keyUsages); + return setCryptoKey(key); + } + async onEncrypt(algorithm, key, data) { + return DesCrypto.encrypt(algorithm, getCryptoKey(key), new Uint8Array(data)); + } + async onDecrypt(algorithm, key, data) { + return DesCrypto.decrypt(algorithm, getCryptoKey(key), new Uint8Array(data)); + } + async onExportKey(format2, key) { + return DesCrypto.exportKey(format2, getCryptoKey(key)); + } + async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { + const key = await DesCrypto.importKey(format2, keyData, { name: this.name, length: this.keySizeBits }, extractable, keyUsages); + if (key.data.length !== this.keySizeBits >> 3) { + throw new OperationError("keyData: Wrong key size"); + } + return setCryptoKey(key); + } + checkCryptoKey(key, keyUsage) { + super.checkCryptoKey(key, keyUsage); + if (!(getCryptoKey(key) instanceof DesCryptoKey)) { + throw new TypeError("key: Is not a DesCryptoKey"); + } + } + }; + DesEde3CbcProvider = class extends DesProvider { + constructor() { + super(...arguments); + this.keySizeBits = 192; + this.ivSize = 8; + this.name = "DES-EDE3-CBC"; + } + async onGenerateKey(algorithm, extractable, keyUsages) { + const key = await DesCrypto.generateKey({ + name: this.name, + length: this.keySizeBits + }, extractable, keyUsages); + return setCryptoKey(key); + } + async onEncrypt(algorithm, key, data) { + return DesCrypto.encrypt(algorithm, getCryptoKey(key), new Uint8Array(data)); + } + async onDecrypt(algorithm, key, data) { + return DesCrypto.decrypt(algorithm, getCryptoKey(key), new Uint8Array(data)); + } + async onExportKey(format2, key) { + return DesCrypto.exportKey(format2, getCryptoKey(key)); + } + async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { + const key = await DesCrypto.importKey(format2, keyData, { name: this.name, length: this.keySizeBits }, extractable, keyUsages); + if (key.data.length !== this.keySizeBits >> 3) { + throw new OperationError("keyData: Wrong key size"); + } + return setCryptoKey(key); + } + checkCryptoKey(key, keyUsage) { + super.checkCryptoKey(key, keyUsage); + if (!(getCryptoKey(key) instanceof DesCryptoKey)) { + throw new TypeError("key: Is not a DesCryptoKey"); + } + } + }; + RsaPrivateKey2 = class extends AsymmetricKey { + constructor() { + super(...arguments); + this.type = "private"; + } + getKey() { + const keyInfo = AsnParser.parse(this.data, index$1.PrivateKeyInfo); + return AsnParser.parse(keyInfo.privateKey, index$1.RsaPrivateKey); + } + toJSON() { + const key = this.getKey(); + const json = { + kty: "RSA", + alg: getJwkAlgorithm(this.algorithm), + key_ops: this.usages, + ext: this.extractable + }; + return Object.assign(json, JsonSerializer.toJSON(key)); + } + fromJSON(json) { + const key = JsonParser.fromJSON(json, { targetSchema: index$1.RsaPrivateKey }); + const keyInfo = new index$1.PrivateKeyInfo(); + keyInfo.privateKeyAlgorithm.algorithm = "1.2.840.113549.1.1.1"; + keyInfo.privateKeyAlgorithm.parameters = null; + keyInfo.privateKey = AsnSerializer.serialize(key); + this.data = Buffer.from(AsnSerializer.serialize(keyInfo)); + } + }; + RsaPublicKey2 = class extends AsymmetricKey { + constructor() { + super(...arguments); + this.type = "public"; + } + getKey() { + const keyInfo = AsnParser.parse(this.data, index$1.PublicKeyInfo); + return AsnParser.parse(keyInfo.publicKey, index$1.RsaPublicKey); + } + toJSON() { + const key = this.getKey(); + const json = { + kty: "RSA", + alg: getJwkAlgorithm(this.algorithm), + key_ops: this.usages, + ext: this.extractable + }; + return Object.assign(json, JsonSerializer.toJSON(key)); + } + fromJSON(json) { + const key = JsonParser.fromJSON(json, { targetSchema: index$1.RsaPublicKey }); + const keyInfo = new index$1.PublicKeyInfo(); + keyInfo.publicKeyAlgorithm.algorithm = "1.2.840.113549.1.1.1"; + keyInfo.publicKeyAlgorithm.parameters = null; + keyInfo.publicKey = AsnSerializer.serialize(key); + this.data = Buffer.from(AsnSerializer.serialize(keyInfo)); + } + }; + RsaCrypto = class { + static async generateKey(algorithm, extractable, keyUsages) { + const privateKey = new RsaPrivateKey2(); + privateKey.algorithm = algorithm; + privateKey.extractable = extractable; + privateKey.usages = keyUsages.filter((usage) => this.privateKeyUsages.indexOf(usage) !== -1); + const publicKey = new RsaPublicKey2(); + publicKey.algorithm = algorithm; + publicKey.extractable = true; + publicKey.usages = keyUsages.filter((usage) => this.publicKeyUsages.indexOf(usage) !== -1); + const publicExponent = Buffer.concat([ + Buffer.alloc(4 - algorithm.publicExponent.byteLength, 0), + Buffer.from(algorithm.publicExponent) + ]).readInt32BE(0); + const keys = import_crypto.default.generateKeyPairSync("rsa", { + modulusLength: algorithm.modulusLength, + publicExponent, + publicKeyEncoding: { + format: "der", + type: "spki" + }, + privateKeyEncoding: { + format: "der", + type: "pkcs8" + } + }); + privateKey.data = keys.privateKey; + publicKey.data = keys.publicKey; + const res = { + privateKey, + publicKey + }; + return res; + } + static async exportKey(format2, key) { + switch (format2.toLowerCase()) { + case "jwk": + return JsonSerializer.toJSON(key); + case "pkcs8": + case "spki": + return new Uint8Array(key.data).buffer; + default: + throw new OperationError("format: Must be 'jwk', 'pkcs8' or 'spki'"); + } + } + static async importKey(format2, keyData, algorithm, extractable, keyUsages) { + switch (format2.toLowerCase()) { + case "jwk": { + const jwk = keyData; + if (jwk.d) { + const asnKey = JsonParser.fromJSON(keyData, { targetSchema: index$1.RsaPrivateKey }); + return this.importPrivateKey(asnKey, algorithm, extractable, keyUsages); + } else { + const asnKey = JsonParser.fromJSON(keyData, { targetSchema: index$1.RsaPublicKey }); + return this.importPublicKey(asnKey, algorithm, extractable, keyUsages); + } + } + case "spki": { + const keyInfo = AsnParser.parse(new Uint8Array(keyData), index$1.PublicKeyInfo); + const asnKey = AsnParser.parse(keyInfo.publicKey, index$1.RsaPublicKey); + return this.importPublicKey(asnKey, algorithm, extractable, keyUsages); + } + case "pkcs8": { + const keyInfo = AsnParser.parse(new Uint8Array(keyData), index$1.PrivateKeyInfo); + const asnKey = AsnParser.parse(keyInfo.privateKey, index$1.RsaPrivateKey); + return this.importPrivateKey(asnKey, algorithm, extractable, keyUsages); + } + default: + throw new OperationError("format: Must be 'jwk', 'pkcs8' or 'spki'"); + } + } + static async sign(algorithm, key, data) { + switch (algorithm.name.toUpperCase()) { + case "RSA-PSS": + case "RSASSA-PKCS1-V1_5": + return this.signRsa(algorithm, key, data); + default: + throw new OperationError("algorithm: Is not recognized"); + } + } + static async verify(algorithm, key, signature, data) { + switch (algorithm.name.toUpperCase()) { + case "RSA-PSS": + case "RSASSA-PKCS1-V1_5": + return this.verifySSA(algorithm, key, data, signature); + default: + throw new OperationError("algorithm: Is not recognized"); + } + } + static async encrypt(algorithm, key, data) { + switch (algorithm.name.toUpperCase()) { + case "RSA-OAEP": + return this.encryptOAEP(algorithm, key, data); + default: + throw new OperationError("algorithm: Is not recognized"); + } + } + static async decrypt(algorithm, key, data) { + switch (algorithm.name.toUpperCase()) { + case "RSA-OAEP": + return this.decryptOAEP(algorithm, key, data); + default: + throw new OperationError("algorithm: Is not recognized"); + } + } + static importPrivateKey(asnKey, algorithm, extractable, keyUsages) { + const keyInfo = new index$1.PrivateKeyInfo(); + keyInfo.privateKeyAlgorithm.algorithm = "1.2.840.113549.1.1.1"; + keyInfo.privateKeyAlgorithm.parameters = null; + keyInfo.privateKey = AsnSerializer.serialize(asnKey); + const key = new RsaPrivateKey2(); + key.data = Buffer.from(AsnSerializer.serialize(keyInfo)); + key.algorithm = Object.assign({}, algorithm); + key.algorithm.publicExponent = new Uint8Array(asnKey.publicExponent); + key.algorithm.modulusLength = asnKey.modulus.byteLength << 3; + key.extractable = extractable; + key.usages = keyUsages; + return key; + } + static importPublicKey(asnKey, algorithm, extractable, keyUsages) { + const keyInfo = new index$1.PublicKeyInfo(); + keyInfo.publicKeyAlgorithm.algorithm = "1.2.840.113549.1.1.1"; + keyInfo.publicKeyAlgorithm.parameters = null; + keyInfo.publicKey = AsnSerializer.serialize(asnKey); + const key = new RsaPublicKey2(); + key.data = Buffer.from(AsnSerializer.serialize(keyInfo)); + key.algorithm = Object.assign({}, algorithm); + key.algorithm.publicExponent = new Uint8Array(asnKey.publicExponent); + key.algorithm.modulusLength = asnKey.modulus.byteLength << 3; + key.extractable = extractable; + key.usages = keyUsages; + return key; + } + static getCryptoAlgorithm(alg) { + switch (alg.hash.name.toUpperCase()) { + case "SHA-1": + return "RSA-SHA1"; + case "SHA-256": + return "RSA-SHA256"; + case "SHA-384": + return "RSA-SHA384"; + case "SHA-512": + return "RSA-SHA512"; + case "SHA3-256": + return "RSA-SHA3-256"; + case "SHA3-384": + return "RSA-SHA3-384"; + case "SHA3-512": + return "RSA-SHA3-512"; + default: + throw new OperationError("algorithm.hash: Is not recognized"); + } + } + static signRsa(algorithm, key, data) { + const cryptoAlg = this.getCryptoAlgorithm(key.algorithm); + const signer = import_crypto.default.createSign(cryptoAlg); + signer.update(Buffer.from(data)); + if (!key.pem) { + key.pem = `-----BEGIN PRIVATE KEY----- +${key.data.toString("base64")} +-----END PRIVATE KEY-----`; + } + const options = { + key: key.pem + }; + if (algorithm.name.toUpperCase() === "RSA-PSS") { + options.padding = import_crypto.default.constants.RSA_PKCS1_PSS_PADDING; + options.saltLength = algorithm.saltLength; + } + const signature = signer.sign(options); + return new Uint8Array(signature).buffer; + } + static verifySSA(algorithm, key, data, signature) { + const cryptoAlg = this.getCryptoAlgorithm(key.algorithm); + const signer = import_crypto.default.createVerify(cryptoAlg); + signer.update(Buffer.from(data)); + if (!key.pem) { + key.pem = `-----BEGIN PUBLIC KEY----- +${key.data.toString("base64")} +-----END PUBLIC KEY-----`; + } + const options = { + key: key.pem + }; + if (algorithm.name.toUpperCase() === "RSA-PSS") { + options.padding = import_crypto.default.constants.RSA_PKCS1_PSS_PADDING; + options.saltLength = algorithm.saltLength; + } + const ok = signer.verify(options, signature); + return ok; + } + static encryptOAEP(algorithm, key, data) { + const options = { + key: `-----BEGIN PUBLIC KEY----- +${key.data.toString("base64")} +-----END PUBLIC KEY-----`, + padding: import_crypto.default.constants.RSA_PKCS1_OAEP_PADDING + }; + if (algorithm.label) + ; + return new Uint8Array(import_crypto.default.publicEncrypt(options, data)).buffer; + } + static decryptOAEP(algorithm, key, data) { + const options = { + key: `-----BEGIN PRIVATE KEY----- +${key.data.toString("base64")} +-----END PRIVATE KEY-----`, + padding: import_crypto.default.constants.RSA_PKCS1_OAEP_PADDING + }; + if (algorithm.label) + ; + return new Uint8Array(import_crypto.default.privateDecrypt(options, data)).buffer; + } + }; + RsaCrypto.publicKeyUsages = ["verify", "encrypt", "wrapKey"]; + RsaCrypto.privateKeyUsages = ["sign", "decrypt", "unwrapKey"]; + RsaSsaProvider2 = class extends RsaSsaProvider { + constructor() { + super(...arguments); + this.hashAlgorithms = [ + "SHA-1", + "SHA-256", + "SHA-384", + "SHA-512", + "shake128", + "shake256", + "SHA3-256", + "SHA3-384", + "SHA3-512" + ]; + } + async onGenerateKey(algorithm, extractable, keyUsages) { + const keys = await RsaCrypto.generateKey({ + ...algorithm, + name: this.name + }, extractable, keyUsages); + return { + privateKey: setCryptoKey(keys.privateKey), + publicKey: setCryptoKey(keys.publicKey) + }; + } + async onSign(algorithm, key, data) { + return RsaCrypto.sign(algorithm, getCryptoKey(key), new Uint8Array(data)); + } + async onVerify(algorithm, key, signature, data) { + return RsaCrypto.verify(algorithm, getCryptoKey(key), new Uint8Array(signature), new Uint8Array(data)); + } + async onExportKey(format2, key) { + return RsaCrypto.exportKey(format2, getCryptoKey(key)); + } + async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { + const key = await RsaCrypto.importKey(format2, keyData, { ...algorithm, name: this.name }, extractable, keyUsages); + return setCryptoKey(key); + } + checkCryptoKey(key, keyUsage) { + super.checkCryptoKey(key, keyUsage); + const internalKey = getCryptoKey(key); + if (!(internalKey instanceof RsaPrivateKey2 || internalKey instanceof RsaPublicKey2)) { + throw new TypeError("key: Is not RSA CryptoKey"); + } + } + }; + RsaPssProvider2 = class extends RsaPssProvider { + constructor() { + super(...arguments); + this.hashAlgorithms = [ + "SHA-1", + "SHA-256", + "SHA-384", + "SHA-512", + "shake128", + "shake256", + "SHA3-256", + "SHA3-384", + "SHA3-512" + ]; + } + async onGenerateKey(algorithm, extractable, keyUsages) { + const keys = await RsaCrypto.generateKey({ + ...algorithm, + name: this.name + }, extractable, keyUsages); + return { + privateKey: setCryptoKey(keys.privateKey), + publicKey: setCryptoKey(keys.publicKey) + }; + } + async onSign(algorithm, key, data) { + return RsaCrypto.sign(algorithm, getCryptoKey(key), new Uint8Array(data)); + } + async onVerify(algorithm, key, signature, data) { + return RsaCrypto.verify(algorithm, getCryptoKey(key), new Uint8Array(signature), new Uint8Array(data)); + } + async onExportKey(format2, key) { + return RsaCrypto.exportKey(format2, getCryptoKey(key)); + } + async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { + const key = await RsaCrypto.importKey(format2, keyData, { ...algorithm, name: this.name }, extractable, keyUsages); + return setCryptoKey(key); + } + checkCryptoKey(key, keyUsage) { + super.checkCryptoKey(key, keyUsage); + const internalKey = getCryptoKey(key); + if (!(internalKey instanceof RsaPrivateKey2 || internalKey instanceof RsaPublicKey2)) { + throw new TypeError("key: Is not RSA CryptoKey"); + } + } + }; + ShaCrypto = class { + static size(algorithm) { + switch (algorithm.name.toUpperCase()) { + case "SHA-1": + return 160; + case "SHA-256": + case "SHA3-256": + return 256; + case "SHA-384": + case "SHA3-384": + return 384; + case "SHA-512": + case "SHA3-512": + return 512; + default: + throw new Error("Unrecognized name"); + } + } + static getAlgorithmName(algorithm) { + switch (algorithm.name.toUpperCase()) { + case "SHA-1": + return "sha1"; + case "SHA-256": + return "sha256"; + case "SHA-384": + return "sha384"; + case "SHA-512": + return "sha512"; + case "SHA3-256": + return "sha3-256"; + case "SHA3-384": + return "sha3-384"; + case "SHA3-512": + return "sha3-512"; + default: + throw new Error("Unrecognized name"); + } + } + static digest(algorithm, data) { + const hashAlg = this.getAlgorithmName(algorithm); + const hash = import_crypto.default.createHash(hashAlg).update(Buffer.from(data)).digest(); + return new Uint8Array(hash).buffer; + } + }; + RsaOaepProvider2 = class extends RsaOaepProvider { + async onGenerateKey(algorithm, extractable, keyUsages) { + const keys = await RsaCrypto.generateKey({ + ...algorithm, + name: this.name + }, extractable, keyUsages); + return { + privateKey: setCryptoKey(keys.privateKey), + publicKey: setCryptoKey(keys.publicKey) + }; + } + async onEncrypt(algorithm, key, data) { + const internalKey = getCryptoKey(key); + const dataView = new Uint8Array(data); + const keySize = Math.ceil(internalKey.algorithm.modulusLength >> 3); + const hashSize = ShaCrypto.size(internalKey.algorithm.hash) >> 3; + const dataLength = dataView.byteLength; + const psLength = keySize - dataLength - 2 * hashSize - 2; + if (dataLength > keySize - 2 * hashSize - 2) { + throw new Error("Data too large"); + } + const message = new Uint8Array(keySize); + const seed = message.subarray(1, hashSize + 1); + const dataBlock = message.subarray(hashSize + 1); + dataBlock.set(dataView, hashSize + psLength + 1); + const labelHash = import_crypto.default.createHash(internalKey.algorithm.hash.name.replace("-", "")).update(import_pvtsutils5.BufferSourceConverter.toUint8Array(algorithm.label || new Uint8Array(0))).digest(); + dataBlock.set(labelHash, 0); + dataBlock[hashSize + psLength] = 1; + import_crypto.default.randomFillSync(seed); + const dataBlockMask = this.mgf1(internalKey.algorithm.hash, seed, dataBlock.length); + for (let i = 0; i < dataBlock.length; i++) { + dataBlock[i] ^= dataBlockMask[i]; + } + const seedMask = this.mgf1(internalKey.algorithm.hash, dataBlock, seed.length); + for (let i = 0; i < seed.length; i++) { + seed[i] ^= seedMask[i]; + } + if (!internalKey.pem) { + internalKey.pem = `-----BEGIN PUBLIC KEY----- +${internalKey.data.toString("base64")} +-----END PUBLIC KEY-----`; + } + const pkcs0 = import_crypto.default.publicEncrypt({ + key: internalKey.pem, + padding: import_crypto.default.constants.RSA_NO_PADDING + }, Buffer.from(message)); + return new Uint8Array(pkcs0).buffer; + } + async onDecrypt(algorithm, key, data) { + const internalKey = getCryptoKey(key); + const keySize = Math.ceil(internalKey.algorithm.modulusLength >> 3); + const hashSize = ShaCrypto.size(internalKey.algorithm.hash) >> 3; + const dataLength = data.byteLength; + if (dataLength !== keySize) { + throw new Error("Bad data"); + } + if (!internalKey.pem) { + internalKey.pem = `-----BEGIN PRIVATE KEY----- +${internalKey.data.toString("base64")} +-----END PRIVATE KEY-----`; + } + let pkcs0 = import_crypto.default.privateDecrypt({ + key: internalKey.pem, + padding: import_crypto.default.constants.RSA_NO_PADDING + }, Buffer.from(data)); + const z = pkcs0[0]; + const seed = pkcs0.subarray(1, hashSize + 1); + const dataBlock = pkcs0.subarray(hashSize + 1); + if (z !== 0) { + throw new Error("Decryption failed"); + } + const seedMask = this.mgf1(internalKey.algorithm.hash, dataBlock, seed.length); + for (let i = 0; i < seed.length; i++) { + seed[i] ^= seedMask[i]; + } + const dataBlockMask = this.mgf1(internalKey.algorithm.hash, seed, dataBlock.length); + for (let i = 0; i < dataBlock.length; i++) { + dataBlock[i] ^= dataBlockMask[i]; + } + const labelHash = import_crypto.default.createHash(internalKey.algorithm.hash.name.replace("-", "")).update(import_pvtsutils5.BufferSourceConverter.toUint8Array(algorithm.label || new Uint8Array(0))).digest(); + for (let i = 0; i < hashSize; i++) { + if (labelHash[i] !== dataBlock[i]) { + throw new Error("Decryption failed"); + } + } + let psEnd = hashSize; + for (; psEnd < dataBlock.length; psEnd++) { + const psz = dataBlock[psEnd]; + if (psz === 1) { + break; + } + if (psz !== 0) { + throw new Error("Decryption failed"); + } + } + if (psEnd === dataBlock.length) { + throw new Error("Decryption failed"); + } + pkcs0 = dataBlock.subarray(psEnd + 1); + return new Uint8Array(pkcs0).buffer; + } + async onExportKey(format2, key) { + return RsaCrypto.exportKey(format2, getCryptoKey(key)); + } + async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { + const key = await RsaCrypto.importKey(format2, keyData, { ...algorithm, name: this.name }, extractable, keyUsages); + return setCryptoKey(key); + } + checkCryptoKey(key, keyUsage) { + super.checkCryptoKey(key, keyUsage); + const internalKey = getCryptoKey(key); + if (!(internalKey instanceof RsaPrivateKey2 || internalKey instanceof RsaPublicKey2)) { + throw new TypeError("key: Is not RSA CryptoKey"); + } + } + mgf1(algorithm, seed, length = 0) { + const hashSize = ShaCrypto.size(algorithm) >> 3; + const mask = new Uint8Array(length); + const counter = new Uint8Array(4); + const chunks = Math.ceil(length / hashSize); + for (let i = 0; i < chunks; i++) { + counter[0] = i >>> 24; + counter[1] = i >>> 16 & 255; + counter[2] = i >>> 8 & 255; + counter[3] = i & 255; + const submask = mask.subarray(i * hashSize); + let chunk = import_crypto.default.createHash(algorithm.name.replace("-", "")).update(seed).update(counter).digest(); + if (chunk.length > submask.length) { + chunk = chunk.subarray(0, submask.length); + } + submask.set(chunk); + } + return mask; + } + }; + RsaEsProvider = class extends ProviderCrypto { + constructor() { + super(...arguments); + this.name = "RSAES-PKCS1-v1_5"; + this.usages = { + publicKey: ["encrypt", "wrapKey"], + privateKey: ["decrypt", "unwrapKey"] + }; + } + async onGenerateKey(algorithm, extractable, keyUsages) { + const keys = await RsaCrypto.generateKey({ + ...algorithm, + name: this.name + }, extractable, keyUsages); + return { + privateKey: setCryptoKey(keys.privateKey), + publicKey: setCryptoKey(keys.publicKey) + }; + } + checkGenerateKeyParams(algorithm) { + this.checkRequiredProperty(algorithm, "publicExponent"); + if (!(algorithm.publicExponent && algorithm.publicExponent instanceof Uint8Array)) { + throw new TypeError("publicExponent: Missing or not a Uint8Array"); + } + const publicExponent = import_pvtsutils6.Convert.ToBase64(algorithm.publicExponent); + if (!(publicExponent === "Aw==" || publicExponent === "AQAB")) { + throw new TypeError("publicExponent: Must be [3] or [1,0,1]"); + } + this.checkRequiredProperty(algorithm, "modulusLength"); + switch (algorithm.modulusLength) { + case 1024: + case 2048: + case 4096: + break; + default: + throw new TypeError("modulusLength: Must be 1024, 2048, or 4096"); + } + } + async onEncrypt(algorithm, key, data) { + const options = this.toCryptoOptions(key); + const enc = crypto.publicEncrypt(options, new Uint8Array(data)); + return new Uint8Array(enc).buffer; + } + async onDecrypt(algorithm, key, data) { + const options = this.toCryptoOptions(key); + const dec = crypto.privateDecrypt(options, new Uint8Array(data)); + return new Uint8Array(dec).buffer; + } + async onExportKey(format2, key) { + return RsaCrypto.exportKey(format2, getCryptoKey(key)); + } + async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { + const key = await RsaCrypto.importKey(format2, keyData, { ...algorithm, name: this.name }, extractable, keyUsages); + return setCryptoKey(key); + } + checkCryptoKey(key, keyUsage) { + super.checkCryptoKey(key, keyUsage); + const internalKey = getCryptoKey(key); + if (!(internalKey instanceof RsaPrivateKey2 || internalKey instanceof RsaPublicKey2)) { + throw new TypeError("key: Is not RSA CryptoKey"); + } + } + toCryptoOptions(key) { + const type = key.type.toUpperCase(); + return { + key: `-----BEGIN ${type} KEY----- +${getCryptoKey(key).data.toString("base64")} +-----END ${type} KEY-----`, + padding: crypto.constants.RSA_PKCS1_PADDING + }; + } + }; + namedOIDs = { + "1.2.840.10045.3.1.7": "P-256", + "P-256": "1.2.840.10045.3.1.7", + "1.3.132.0.34": "P-384", + "P-384": "1.3.132.0.34", + "1.3.132.0.35": "P-521", + "P-521": "1.3.132.0.35", + "1.3.132.0.10": "K-256", + "K-256": "1.3.132.0.10", + "brainpoolP160r1": "1.3.36.3.3.2.8.1.1.1", + "1.3.36.3.3.2.8.1.1.1": "brainpoolP160r1", + "brainpoolP160t1": "1.3.36.3.3.2.8.1.1.2", + "1.3.36.3.3.2.8.1.1.2": "brainpoolP160t1", + "brainpoolP192r1": "1.3.36.3.3.2.8.1.1.3", + "1.3.36.3.3.2.8.1.1.3": "brainpoolP192r1", + "brainpoolP192t1": "1.3.36.3.3.2.8.1.1.4", + "1.3.36.3.3.2.8.1.1.4": "brainpoolP192t1", + "brainpoolP224r1": "1.3.36.3.3.2.8.1.1.5", + "1.3.36.3.3.2.8.1.1.5": "brainpoolP224r1", + "brainpoolP224t1": "1.3.36.3.3.2.8.1.1.6", + "1.3.36.3.3.2.8.1.1.6": "brainpoolP224t1", + "brainpoolP256r1": "1.3.36.3.3.2.8.1.1.7", + "1.3.36.3.3.2.8.1.1.7": "brainpoolP256r1", + "brainpoolP256t1": "1.3.36.3.3.2.8.1.1.8", + "1.3.36.3.3.2.8.1.1.8": "brainpoolP256t1", + "brainpoolP320r1": "1.3.36.3.3.2.8.1.1.9", + "1.3.36.3.3.2.8.1.1.9": "brainpoolP320r1", + "brainpoolP320t1": "1.3.36.3.3.2.8.1.1.10", + "1.3.36.3.3.2.8.1.1.10": "brainpoolP320t1", + "brainpoolP384r1": "1.3.36.3.3.2.8.1.1.11", + "1.3.36.3.3.2.8.1.1.11": "brainpoolP384r1", + "brainpoolP384t1": "1.3.36.3.3.2.8.1.1.12", + "1.3.36.3.3.2.8.1.1.12": "brainpoolP384t1", + "brainpoolP512r1": "1.3.36.3.3.2.8.1.1.13", + "1.3.36.3.3.2.8.1.1.13": "brainpoolP512r1", + "brainpoolP512t1": "1.3.36.3.3.2.8.1.1.14", + "1.3.36.3.3.2.8.1.1.14": "brainpoolP512t1" + }; + EcPrivateKey2 = class extends AsymmetricKey { + constructor() { + super(...arguments); + this.type = "private"; + } + getKey() { + const keyInfo = AsnParser.parse(this.data, index$1.PrivateKeyInfo); + return AsnParser.parse(keyInfo.privateKey, index$1.EcPrivateKey); + } + toJSON() { + const key = this.getKey(); + const json = { + kty: "EC", + crv: this.algorithm.namedCurve, + key_ops: this.usages, + ext: this.extractable + }; + return Object.assign(json, JsonSerializer.toJSON(key)); + } + fromJSON(json) { + if (!json.crv) { + throw new OperationError(`Cannot get named curve from JWK. Property 'crv' is required`); + } + const keyInfo = new index$1.PrivateKeyInfo(); + keyInfo.privateKeyAlgorithm.algorithm = "1.2.840.10045.2.1"; + keyInfo.privateKeyAlgorithm.parameters = AsnSerializer.serialize(new index$1.ObjectIdentifier(getOidByNamedCurve$1(json.crv))); + const key = JsonParser.fromJSON(json, { targetSchema: index$1.EcPrivateKey }); + keyInfo.privateKey = AsnSerializer.serialize(key); + this.data = Buffer.from(AsnSerializer.serialize(keyInfo)); + return this; + } + }; + EcPublicKey3 = class extends AsymmetricKey { + constructor() { + super(...arguments); + this.type = "public"; + } + getKey() { + const keyInfo = AsnParser.parse(this.data, index$1.PublicKeyInfo); + return new index$1.EcPublicKey(keyInfo.publicKey); + } + toJSON() { + const key = this.getKey(); + const json = { + kty: "EC", + crv: this.algorithm.namedCurve, + key_ops: this.usages, + ext: this.extractable + }; + return Object.assign(json, JsonSerializer.toJSON(key)); + } + fromJSON(json) { + if (!json.crv) { + throw new OperationError(`Cannot get named curve from JWK. Property 'crv' is required`); + } + const key = JsonParser.fromJSON(json, { targetSchema: index$1.EcPublicKey }); + const keyInfo = new index$1.PublicKeyInfo(); + keyInfo.publicKeyAlgorithm.algorithm = "1.2.840.10045.2.1"; + keyInfo.publicKeyAlgorithm.parameters = AsnSerializer.serialize(new index$1.ObjectIdentifier(getOidByNamedCurve$1(json.crv))); + keyInfo.publicKey = AsnSerializer.toASN(key).valueHex; + this.data = Buffer.from(AsnSerializer.serialize(keyInfo)); + return this; + } + }; + Sha1Provider = class extends ProviderCrypto { + constructor() { + super(...arguments); + this.name = "SHA-1"; + this.usages = []; + } + async onDigest(algorithm, data) { + return ShaCrypto.digest(algorithm, data); + } + }; + Sha256Provider = class extends ProviderCrypto { + constructor() { + super(...arguments); + this.name = "SHA-256"; + this.usages = []; + } + async onDigest(algorithm, data) { + return ShaCrypto.digest(algorithm, data); + } + }; + Sha384Provider = class extends ProviderCrypto { + constructor() { + super(...arguments); + this.name = "SHA-384"; + this.usages = []; + } + async onDigest(algorithm, data) { + return ShaCrypto.digest(algorithm, data); + } + }; + Sha512Provider = class extends ProviderCrypto { + constructor() { + super(...arguments); + this.name = "SHA-512"; + this.usages = []; + } + async onDigest(algorithm, data) { + return ShaCrypto.digest(algorithm, data); + } + }; + Sha3256Provider = class extends ProviderCrypto { + constructor() { + super(...arguments); + this.name = "SHA3-256"; + this.usages = []; + } + async onDigest(algorithm, data) { + return ShaCrypto.digest(algorithm, data); + } + }; + Sha3384Provider = class extends ProviderCrypto { + constructor() { + super(...arguments); + this.name = "SHA3-384"; + this.usages = []; + } + async onDigest(algorithm, data) { + return ShaCrypto.digest(algorithm, data); + } + }; + Sha3512Provider = class extends ProviderCrypto { + constructor() { + super(...arguments); + this.name = "SHA3-512"; + this.usages = []; + } + async onDigest(algorithm, data) { + return ShaCrypto.digest(algorithm, data); + } + }; + EcCrypto = class { + static async generateKey(algorithm, extractable, keyUsages) { + const privateKey = new EcPrivateKey2(); + privateKey.algorithm = algorithm; + privateKey.extractable = extractable; + privateKey.usages = keyUsages.filter((usage) => this.privateKeyUsages.indexOf(usage) !== -1); + const publicKey = new EcPublicKey3(); + publicKey.algorithm = algorithm; + publicKey.extractable = true; + publicKey.usages = keyUsages.filter((usage) => this.publicKeyUsages.indexOf(usage) !== -1); + const keys = import_crypto.default.generateKeyPairSync("ec", { + namedCurve: this.getOpenSSLNamedCurve(algorithm.namedCurve), + publicKeyEncoding: { + format: "der", + type: "spki" + }, + privateKeyEncoding: { + format: "der", + type: "pkcs8" + } + }); + privateKey.data = keys.privateKey; + publicKey.data = keys.publicKey; + const res = { + privateKey, + publicKey + }; + return res; + } + static async sign(algorithm, key, data) { + const cryptoAlg = ShaCrypto.getAlgorithmName(algorithm.hash); + const signer = import_crypto.default.createSign(cryptoAlg); + signer.update(Buffer.from(data)); + if (!key.pem) { + key.pem = `-----BEGIN PRIVATE KEY----- +${key.data.toString("base64")} +-----END PRIVATE KEY-----`; + } + const options = { + key: key.pem + }; + const signature = signer.sign(options); + const ecSignature = AsnParser.parse(signature, index$1.EcDsaSignature); + const signatureRaw = EcUtils.encodeSignature(ecSignature, EcCurves.get(key.algorithm.namedCurve).size); + return signatureRaw.buffer; + } + static async verify(algorithm, key, signature, data) { + const cryptoAlg = ShaCrypto.getAlgorithmName(algorithm.hash); + const signer = import_crypto.default.createVerify(cryptoAlg); + signer.update(Buffer.from(data)); + if (!key.pem) { + key.pem = `-----BEGIN PUBLIC KEY----- +${key.data.toString("base64")} +-----END PUBLIC KEY-----`; + } + const options = { + key: key.pem + }; + const ecSignature = new index$1.EcDsaSignature(); + const namedCurve = EcCurves.get(key.algorithm.namedCurve); + const signaturePoint = EcUtils.decodeSignature(signature, namedCurve.size); + ecSignature.r = import_pvtsutils6.BufferSourceConverter.toArrayBuffer(signaturePoint.r); + ecSignature.s = import_pvtsutils6.BufferSourceConverter.toArrayBuffer(signaturePoint.s); + const ecSignatureRaw = Buffer.from(AsnSerializer.serialize(ecSignature)); + const ok = signer.verify(options, ecSignatureRaw); + return ok; + } + static async deriveBits(algorithm, baseKey, length) { + const cryptoAlg = this.getOpenSSLNamedCurve(baseKey.algorithm.namedCurve); + const ecdh = import_crypto.default.createECDH(cryptoAlg); + const asnPrivateKey = AsnParser.parse(baseKey.data, index$1.PrivateKeyInfo); + const asnEcPrivateKey = AsnParser.parse(asnPrivateKey.privateKey, index$1.EcPrivateKey); + ecdh.setPrivateKey(Buffer.from(asnEcPrivateKey.privateKey)); + const asnPublicKey = AsnParser.parse(algorithm.public.data, index$1.PublicKeyInfo); + const bits = ecdh.computeSecret(Buffer.from(asnPublicKey.publicKey)); + if (length === null) { + return bits; + } + return new Uint8Array(bits).buffer.slice(0, length >> 3); + } + static async exportKey(format2, key) { + switch (format2.toLowerCase()) { + case "jwk": + return JsonSerializer.toJSON(key); + case "pkcs8": + case "spki": + return new Uint8Array(key.data).buffer; + case "raw": { + const publicKeyInfo = AsnParser.parse(key.data, index$1.PublicKeyInfo); + return publicKeyInfo.publicKey; + } + default: + throw new OperationError("format: Must be 'jwk', 'raw', pkcs8' or 'spki'"); + } + } + static async importKey(format2, keyData, algorithm, extractable, keyUsages) { + switch (format2.toLowerCase()) { + case "jwk": { + const jwk = keyData; + if (jwk.d) { + const asnKey = JsonParser.fromJSON(keyData, { targetSchema: index$1.EcPrivateKey }); + return this.importPrivateKey(asnKey, algorithm, extractable, keyUsages); + } else { + const asnKey = JsonParser.fromJSON(keyData, { targetSchema: index$1.EcPublicKey }); + return this.importPublicKey(asnKey, algorithm, extractable, keyUsages); + } + } + case "raw": { + const asnKey = new index$1.EcPublicKey(keyData); + return this.importPublicKey(asnKey, algorithm, extractable, keyUsages); + } + case "spki": { + const keyInfo = AsnParser.parse(new Uint8Array(keyData), index$1.PublicKeyInfo); + const asnKey = new index$1.EcPublicKey(keyInfo.publicKey); + this.assertKeyParameters(keyInfo.publicKeyAlgorithm.parameters, algorithm.namedCurve); + return this.importPublicKey(asnKey, algorithm, extractable, keyUsages); + } + case "pkcs8": { + const keyInfo = AsnParser.parse(new Uint8Array(keyData), index$1.PrivateKeyInfo); + const asnKey = AsnParser.parse(keyInfo.privateKey, index$1.EcPrivateKey); + this.assertKeyParameters(keyInfo.privateKeyAlgorithm.parameters, algorithm.namedCurve); + return this.importPrivateKey(asnKey, algorithm, extractable, keyUsages); + } + default: + throw new OperationError("format: Must be 'jwk', 'raw', 'pkcs8' or 'spki'"); + } + } + static assertKeyParameters(parameters, namedCurve) { + if (!parameters) { + throw new CryptoError("Key info doesn't have required parameters"); + } + let namedCurveIdentifier = ""; + try { + namedCurveIdentifier = AsnParser.parse(parameters, index$1.ObjectIdentifier).value; + } catch (e) { + throw new CryptoError("Cannot read key info parameters"); + } + if (getOidByNamedCurve$1(namedCurve) !== namedCurveIdentifier) { + throw new CryptoError("Key info parameter doesn't match to named curve"); + } + } + static async importPrivateKey(asnKey, algorithm, extractable, keyUsages) { + const keyInfo = new index$1.PrivateKeyInfo(); + keyInfo.privateKeyAlgorithm.algorithm = "1.2.840.10045.2.1"; + keyInfo.privateKeyAlgorithm.parameters = AsnSerializer.serialize(new index$1.ObjectIdentifier(getOidByNamedCurve$1(algorithm.namedCurve))); + keyInfo.privateKey = AsnSerializer.serialize(asnKey); + const key = new EcPrivateKey2(); + key.data = Buffer.from(AsnSerializer.serialize(keyInfo)); + key.algorithm = Object.assign({}, algorithm); + key.extractable = extractable; + key.usages = keyUsages; + return key; + } + static async importPublicKey(asnKey, algorithm, extractable, keyUsages) { + const keyInfo = new index$1.PublicKeyInfo(); + keyInfo.publicKeyAlgorithm.algorithm = "1.2.840.10045.2.1"; + const namedCurve = getOidByNamedCurve$1(algorithm.namedCurve); + keyInfo.publicKeyAlgorithm.parameters = AsnSerializer.serialize(new index$1.ObjectIdentifier(namedCurve)); + keyInfo.publicKey = asnKey.value; + const key = new EcPublicKey3(); + key.data = Buffer.from(AsnSerializer.serialize(keyInfo)); + key.algorithm = Object.assign({}, algorithm); + key.extractable = extractable; + key.usages = keyUsages; + return key; + } + static getOpenSSLNamedCurve(curve) { + switch (curve.toUpperCase()) { + case "P-256": + return "prime256v1"; + case "K-256": + return "secp256k1"; + case "P-384": + return "secp384r1"; + case "P-521": + return "secp521r1"; + default: + return curve; + } + } + }; + EcCrypto.publicKeyUsages = ["verify"]; + EcCrypto.privateKeyUsages = ["sign", "deriveKey", "deriveBits"]; + EcdsaProvider2 = class extends EcdsaProvider { + constructor() { + super(...arguments); + this.namedCurves = EcCurves.names; + this.hashAlgorithms = [ + "SHA-1", + "SHA-256", + "SHA-384", + "SHA-512", + "shake128", + "shake256", + "SHA3-256", + "SHA3-384", + "SHA3-512" + ]; + } + async onGenerateKey(algorithm, extractable, keyUsages) { + const keys = await EcCrypto.generateKey({ + ...algorithm, + name: this.name + }, extractable, keyUsages); + return { + privateKey: setCryptoKey(keys.privateKey), + publicKey: setCryptoKey(keys.publicKey) + }; + } + async onSign(algorithm, key, data) { + return EcCrypto.sign(algorithm, getCryptoKey(key), new Uint8Array(data)); + } + async onVerify(algorithm, key, signature, data) { + return EcCrypto.verify(algorithm, getCryptoKey(key), new Uint8Array(signature), new Uint8Array(data)); + } + async onExportKey(format2, key) { + return EcCrypto.exportKey(format2, getCryptoKey(key)); + } + async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { + const key = await EcCrypto.importKey(format2, keyData, { ...algorithm, name: this.name }, extractable, keyUsages); + return setCryptoKey(key); + } + checkCryptoKey(key, keyUsage) { + super.checkCryptoKey(key, keyUsage); + const internalKey = getCryptoKey(key); + if (!(internalKey instanceof EcPrivateKey2 || internalKey instanceof EcPublicKey3)) { + throw new TypeError("key: Is not EC CryptoKey"); + } + } + }; + EcdhProvider2 = class extends EcdhProvider { + constructor() { + super(...arguments); + this.namedCurves = EcCurves.names; + } + async onGenerateKey(algorithm, extractable, keyUsages) { + const keys = await EcCrypto.generateKey({ + ...algorithm, + name: this.name + }, extractable, keyUsages); + return { + privateKey: setCryptoKey(keys.privateKey), + publicKey: setCryptoKey(keys.publicKey) + }; + } + async onExportKey(format2, key) { + return EcCrypto.exportKey(format2, getCryptoKey(key)); + } + async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { + const key = await EcCrypto.importKey(format2, keyData, { ...algorithm, name: this.name }, extractable, keyUsages); + return setCryptoKey(key); + } + checkCryptoKey(key, keyUsage) { + super.checkCryptoKey(key, keyUsage); + const internalKey = getCryptoKey(key); + if (!(internalKey instanceof EcPrivateKey2 || internalKey instanceof EcPublicKey3)) { + throw new TypeError("key: Is not EC CryptoKey"); + } + } + async onDeriveBits(algorithm, baseKey, length) { + const bits = await EcCrypto.deriveBits({ ...algorithm, public: getCryptoKey(algorithm.public) }, getCryptoKey(baseKey), length); + return bits; + } + }; + edOIDs = { + [index$1.idEd448]: "Ed448", + "ed448": index$1.idEd448, + [index$1.idX448]: "X448", + "x448": index$1.idX448, + [index$1.idEd25519]: "Ed25519", + "ed25519": index$1.idEd25519, + [index$1.idX25519]: "X25519", + "x25519": index$1.idX25519 + }; + EdPrivateKey3 = class extends AsymmetricKey { + constructor() { + super(...arguments); + this.type = "private"; + } + getKey() { + const keyInfo = AsnParser.parse(this.data, index$1.PrivateKeyInfo); + return AsnParser.parse(keyInfo.privateKey, index$1.CurvePrivateKey); + } + toJSON() { + const key = this.getKey(); + const json = { + kty: "OKP", + crv: this.algorithm.namedCurve, + key_ops: this.usages, + ext: this.extractable + }; + return Object.assign(json, JsonSerializer.toJSON(key)); + } + fromJSON(json) { + if (!json.crv) { + throw new OperationError(`Cannot get named curve from JWK. Property 'crv' is required`); + } + const keyInfo = new index$1.PrivateKeyInfo(); + keyInfo.privateKeyAlgorithm.algorithm = getOidByNamedCurve(json.crv); + const key = JsonParser.fromJSON(json, { targetSchema: index$1.CurvePrivateKey }); + keyInfo.privateKey = AsnSerializer.serialize(key); + this.data = Buffer.from(AsnSerializer.serialize(keyInfo)); + return this; + } + }; + EdPublicKey3 = class extends AsymmetricKey { + constructor() { + super(...arguments); + this.type = "public"; + } + getKey() { + const keyInfo = AsnParser.parse(this.data, index$1.PublicKeyInfo); + return keyInfo.publicKey; + } + toJSON() { + const key = this.getKey(); + const json = { + kty: "OKP", + crv: this.algorithm.namedCurve, + key_ops: this.usages, + ext: this.extractable + }; + return Object.assign(json, { + x: import_pvtsutils6.Convert.ToBase64Url(key) + }); + } + fromJSON(json) { + if (!json.crv) { + throw new OperationError(`Cannot get named curve from JWK. Property 'crv' is required`); + } + if (!json.x) { + throw new OperationError(`Cannot get property from JWK. Property 'x' is required`); + } + const keyInfo = new index$1.PublicKeyInfo(); + keyInfo.publicKeyAlgorithm.algorithm = getOidByNamedCurve(json.crv); + keyInfo.publicKey = import_pvtsutils6.Convert.FromBase64Url(json.x); + this.data = Buffer.from(AsnSerializer.serialize(keyInfo)); + return this; + } + }; + EdCrypto = class { + static async generateKey(algorithm, extractable, keyUsages) { + const privateKey = new EdPrivateKey3(); + privateKey.algorithm = algorithm; + privateKey.extractable = extractable; + privateKey.usages = keyUsages.filter((usage) => this.privateKeyUsages.indexOf(usage) !== -1); + const publicKey = new EdPublicKey3(); + publicKey.algorithm = algorithm; + publicKey.extractable = true; + publicKey.usages = keyUsages.filter((usage) => this.publicKeyUsages.indexOf(usage) !== -1); + const type = algorithm.namedCurve.toLowerCase(); + const keys = import_crypto.default.generateKeyPairSync(type, { + publicKeyEncoding: { + format: "der", + type: "spki" + }, + privateKeyEncoding: { + format: "der", + type: "pkcs8" + } + }); + privateKey.data = keys.privateKey; + publicKey.data = keys.publicKey; + const res = { + privateKey, + publicKey + }; + return res; + } + static async sign(algorithm, key, data) { + if (!key.pem) { + key.pem = `-----BEGIN PRIVATE KEY----- +${key.data.toString("base64")} +-----END PRIVATE KEY-----`; + } + const options = { + key: key.pem + }; + const signature = import_crypto.default.sign(null, Buffer.from(data), options); + return import_pvtsutils5.BufferSourceConverter.toArrayBuffer(signature); + } + static async verify(algorithm, key, signature, data) { + if (!key.pem) { + key.pem = `-----BEGIN PUBLIC KEY----- +${key.data.toString("base64")} +-----END PUBLIC KEY-----`; + } + const options = { + key: key.pem + }; + const ok = import_crypto.default.verify(null, Buffer.from(data), options, Buffer.from(signature)); + return ok; + } + static async deriveBits(algorithm, baseKey, length) { + const publicKey = import_crypto.default.createPublicKey({ + key: algorithm.public.data, + format: "der", + type: "spki" + }); + const privateKey = import_crypto.default.createPrivateKey({ + key: baseKey.data, + format: "der", + type: "pkcs8" + }); + const bits = import_crypto.default.diffieHellman({ + publicKey, + privateKey + }); + return new Uint8Array(bits).buffer.slice(0, length >> 3); + } + static async exportKey(format2, key) { + switch (format2.toLowerCase()) { + case "jwk": + return JsonSerializer.toJSON(key); + case "pkcs8": + case "spki": + return new Uint8Array(key.data).buffer; + case "raw": { + const publicKeyInfo = AsnParser.parse(key.data, index$1.PublicKeyInfo); + return publicKeyInfo.publicKey; + } + default: + throw new OperationError("format: Must be 'jwk', 'raw', pkcs8' or 'spki'"); + } + } + static async importKey(format2, keyData, algorithm, extractable, keyUsages) { + switch (format2.toLowerCase()) { + case "jwk": { + const jwk = keyData; + if (jwk.d) { + const asnKey = JsonParser.fromJSON(keyData, { targetSchema: index$1.CurvePrivateKey }); + return this.importPrivateKey(asnKey, algorithm, extractable, keyUsages); + } else { + if (!jwk.x) { + throw new TypeError("keyData: Cannot get required 'x' filed"); + } + return this.importPublicKey(import_pvtsutils6.Convert.FromBase64Url(jwk.x), algorithm, extractable, keyUsages); + } + } + case "raw": { + return this.importPublicKey(keyData, algorithm, extractable, keyUsages); + } + case "spki": { + const keyInfo = AsnParser.parse(new Uint8Array(keyData), index$1.PublicKeyInfo); + return this.importPublicKey(keyInfo.publicKey, algorithm, extractable, keyUsages); + } + case "pkcs8": { + const keyInfo = AsnParser.parse(new Uint8Array(keyData), index$1.PrivateKeyInfo); + const asnKey = AsnParser.parse(keyInfo.privateKey, index$1.CurvePrivateKey); + return this.importPrivateKey(asnKey, algorithm, extractable, keyUsages); + } + default: + throw new OperationError("format: Must be 'jwk', 'raw', 'pkcs8' or 'spki'"); + } + } + static importPrivateKey(asnKey, algorithm, extractable, keyUsages) { + const key = new EdPrivateKey3(); + key.fromJSON({ + crv: algorithm.namedCurve, + d: import_pvtsutils6.Convert.ToBase64Url(asnKey.d) + }); + key.algorithm = Object.assign({}, algorithm); + key.extractable = extractable; + key.usages = keyUsages; + return key; + } + static async importPublicKey(asnKey, algorithm, extractable, keyUsages) { + const key = new EdPublicKey3(); + key.fromJSON({ + crv: algorithm.namedCurve, + x: import_pvtsutils6.Convert.ToBase64Url(asnKey) + }); + key.algorithm = Object.assign({}, algorithm); + key.extractable = extractable; + key.usages = keyUsages; + return key; + } + }; + EdCrypto.publicKeyUsages = ["verify"]; + EdCrypto.privateKeyUsages = ["sign", "deriveKey", "deriveBits"]; + EdDsaProvider2 = class extends EdDsaProvider { + async onGenerateKey(algorithm, extractable, keyUsages) { + const keys = await EdCrypto.generateKey({ + name: this.name, + namedCurve: algorithm.namedCurve.replace(/^ed/i, "Ed") + }, extractable, keyUsages); + return { + privateKey: setCryptoKey(keys.privateKey), + publicKey: setCryptoKey(keys.publicKey) + }; + } + async onSign(algorithm, key, data) { + return EdCrypto.sign(algorithm, getCryptoKey(key), new Uint8Array(data)); + } + async onVerify(algorithm, key, signature, data) { + return EdCrypto.verify(algorithm, getCryptoKey(key), new Uint8Array(signature), new Uint8Array(data)); + } + async onExportKey(format2, key) { + return EdCrypto.exportKey(format2, getCryptoKey(key)); + } + async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { + const key = await EdCrypto.importKey(format2, keyData, { ...algorithm, name: this.name }, extractable, keyUsages); + return setCryptoKey(key); + } + }; + EcdhEsProvider2 = class extends EcdhEsProvider { + async onGenerateKey(algorithm, extractable, keyUsages) { + const keys = await EdCrypto.generateKey({ + name: this.name, + namedCurve: algorithm.namedCurve.toUpperCase() + }, extractable, keyUsages); + return { + privateKey: setCryptoKey(keys.privateKey), + publicKey: setCryptoKey(keys.publicKey) + }; + } + async onDeriveBits(algorithm, baseKey, length) { + const bits = await EdCrypto.deriveBits({ ...algorithm, public: getCryptoKey(algorithm.public) }, getCryptoKey(baseKey), length); + return bits; + } + async onExportKey(format2, key) { + return EdCrypto.exportKey(format2, getCryptoKey(key)); + } + async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { + const key = await EdCrypto.importKey(format2, keyData, { ...algorithm, name: this.name }, extractable, keyUsages); + return setCryptoKey(key); + } + }; + PbkdfCryptoKey = class extends CryptoKey2 { + }; + Pbkdf2Provider2 = class extends Pbkdf2Provider { + async onDeriveBits(algorithm, baseKey, length) { + return new Promise((resolve, reject) => { + const salt = import_pvtsutils5.BufferSourceConverter.toArrayBuffer(algorithm.salt); + const hash = algorithm.hash.name.replace("-", ""); + import_crypto.default.pbkdf2(getCryptoKey(baseKey).data, Buffer.from(salt), algorithm.iterations, length >> 3, hash, (err, derivedBits) => { + if (err) { + reject(err); + } else { + resolve(new Uint8Array(derivedBits).buffer); + } + }); + }); + } + async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { + if (format2 === "raw") { + const key = new PbkdfCryptoKey(); + key.data = Buffer.from(keyData); + key.algorithm = { name: this.name }; + key.extractable = false; + key.usages = keyUsages; + return setCryptoKey(key); + } + throw new OperationError("format: Must be 'raw'"); + } + checkCryptoKey(key, keyUsage) { + super.checkCryptoKey(key, keyUsage); + if (!(getCryptoKey(key) instanceof PbkdfCryptoKey)) { + throw new TypeError("key: Is not PBKDF CryptoKey"); + } + } + }; + HmacCryptoKey = class extends CryptoKey2 { + get alg() { + const hash = this.algorithm.hash.name.toUpperCase(); + return `HS${hash.replace("SHA-", "")}`; + } + set alg(value) { + } + }; + __decorate([ + JsonProp({ name: "k", converter: JsonBase64UrlConverter }) + ], HmacCryptoKey.prototype, "data", void 0); + HmacProvider2 = class extends HmacProvider { + async onGenerateKey(algorithm, extractable, keyUsages) { + const length = (algorithm.length || this.getDefaultLength(algorithm.hash.name)) >> 3 << 3; + const key = new HmacCryptoKey(); + key.algorithm = { + ...algorithm, + length, + name: this.name + }; + key.extractable = extractable; + key.usages = keyUsages; + key.data = import_crypto.default.randomBytes(length >> 3); + return setCryptoKey(key); + } + async onSign(algorithm, key, data) { + const cryptoAlg = ShaCrypto.getAlgorithmName(key.algorithm.hash); + const hmac = import_crypto.default.createHmac(cryptoAlg, getCryptoKey(key).data).update(Buffer.from(data)).digest(); + return new Uint8Array(hmac).buffer; + } + async onVerify(algorithm, key, signature, data) { + const cryptoAlg = ShaCrypto.getAlgorithmName(key.algorithm.hash); + const hmac = import_crypto.default.createHmac(cryptoAlg, getCryptoKey(key).data).update(Buffer.from(data)).digest(); + return hmac.compare(Buffer.from(signature)) === 0; + } + async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { + let key; + switch (format2.toLowerCase()) { + case "jwk": + key = JsonParser.fromJSON(keyData, { targetSchema: HmacCryptoKey }); + break; + case "raw": + key = new HmacCryptoKey(); + key.data = Buffer.from(keyData); + break; + default: + throw new OperationError("format: Must be 'jwk' or 'raw'"); + } + key.algorithm = { + hash: { name: algorithm.hash.name }, + name: this.name, + length: key.data.length << 3 + }; + key.extractable = extractable; + key.usages = keyUsages; + return setCryptoKey(key); + } + async onExportKey(format2, key) { + switch (format2.toLowerCase()) { + case "jwk": + return JsonSerializer.toJSON(getCryptoKey(key)); + case "raw": + return new Uint8Array(getCryptoKey(key).data).buffer; + default: + throw new OperationError("format: Must be 'jwk' or 'raw'"); + } + } + checkCryptoKey(key, keyUsage) { + super.checkCryptoKey(key, keyUsage); + if (!(getCryptoKey(key) instanceof HmacCryptoKey)) { + throw new TypeError("key: Is not HMAC CryptoKey"); + } + } + }; + HkdfCryptoKey = class extends CryptoKey2 { + }; + HkdfProvider2 = class extends HkdfProvider { + async onImportKey(format2, keyData, algorithm, extractable, keyUsages) { + if (format2.toLowerCase() !== "raw") { + throw new OperationError("Operation not supported"); + } + const key = new HkdfCryptoKey(); + key.data = Buffer.from(keyData); + key.algorithm = { name: this.name }; + key.extractable = extractable; + key.usages = keyUsages; + return setCryptoKey(key); + } + async onDeriveBits(params, baseKey, length) { + const hash = params.hash.name.replace("-", ""); + const hashLength = import_crypto.default.createHash(hash).digest().length; + const byteLength = length / 8; + const info = import_pvtsutils5.BufferSourceConverter.toUint8Array(params.info); + const PRK = import_crypto.default.createHmac(hash, import_pvtsutils5.BufferSourceConverter.toUint8Array(params.salt)).update(import_pvtsutils5.BufferSourceConverter.toUint8Array(getCryptoKey(baseKey).data)).digest(); + const blocks = [Buffer.alloc(0)]; + const blockCount = Math.ceil(byteLength / hashLength) + 1; + for (let i = 1; i < blockCount; ++i) { + blocks.push(import_crypto.default.createHmac(hash, PRK).update(Buffer.concat([blocks[i - 1], info, Buffer.from([i])])).digest()); + } + return Buffer.concat(blocks).slice(0, byteLength); + } + checkCryptoKey(key, keyUsage) { + super.checkCryptoKey(key, keyUsage); + if (!(getCryptoKey(key) instanceof HkdfCryptoKey)) { + throw new TypeError("key: Is not HKDF CryptoKey"); + } + } + }; + ShakeCrypto = class { + static digest(algorithm, data) { + const hash = import_crypto.default.createHash(algorithm.name.toLowerCase(), { outputLength: algorithm.length }).update(Buffer.from(data)).digest(); + return new Uint8Array(hash).buffer; + } + }; + Shake128Provider2 = class extends Shake128Provider { + async onDigest(algorithm, data) { + return ShakeCrypto.digest(algorithm, data); + } + }; + Shake256Provider2 = class extends Shake256Provider { + async onDigest(algorithm, data) { + return ShakeCrypto.digest(algorithm, data); + } + }; + SubtleCrypto2 = class extends SubtleCrypto { + constructor() { + var _a2; + super(); + this.providers.set(new AesCbcProvider2()); + this.providers.set(new AesCtrProvider2()); + this.providers.set(new AesGcmProvider2()); + this.providers.set(new AesCmacProvider2()); + this.providers.set(new AesKwProvider2()); + this.providers.set(new AesEcbProvider2()); + const ciphers = crypto.getCiphers(); + if (ciphers.includes("des-cbc")) { + this.providers.set(new DesCbcProvider()); + } + this.providers.set(new DesEde3CbcProvider()); + this.providers.set(new RsaSsaProvider2()); + this.providers.set(new RsaPssProvider2()); + this.providers.set(new RsaOaepProvider2()); + this.providers.set(new RsaEsProvider()); + this.providers.set(new EcdsaProvider2()); + this.providers.set(new EcdhProvider2()); + this.providers.set(new Sha1Provider()); + this.providers.set(new Sha256Provider()); + this.providers.set(new Sha384Provider()); + this.providers.set(new Sha512Provider()); + this.providers.set(new Pbkdf2Provider2()); + this.providers.set(new HmacProvider2()); + this.providers.set(new HkdfProvider2()); + const nodeMajorVersion = (_a2 = /^v(\d+)/.exec(process2.version)) === null || _a2 === void 0 ? void 0 : _a2[1]; + if (nodeMajorVersion && parseInt(nodeMajorVersion, 10) >= 12) { + this.providers.set(new Shake128Provider2()); + this.providers.set(new Shake256Provider2()); + } + const hashes = crypto.getHashes(); + if (hashes.includes("sha3-256")) { + this.providers.set(new Sha3256Provider()); + } + if (hashes.includes("sha3-384")) { + this.providers.set(new Sha3384Provider()); + } + if (hashes.includes("sha3-512")) { + this.providers.set(new Sha3512Provider()); + } + if (nodeMajorVersion && parseInt(nodeMajorVersion, 10) >= 14) { + this.providers.set(new EdDsaProvider2()); + this.providers.set(new EcdhEsProvider2()); + } + } + }; + Crypto2 = class extends Crypto { + constructor() { + super(...arguments); + this.subtle = new SubtleCrypto2(); + } + getRandomValues(array) { + if (!ArrayBuffer.isView(array)) { + throw new TypeError("Failed to execute 'getRandomValues' on 'Crypto': parameter 1 is not of type 'ArrayBufferView'"); + } + const buffer = Buffer.from(array.buffer, array.byteOffset, array.byteLength); + import_crypto.default.randomFillSync(buffer); + return array; + } + }; + } + }); + + // source/math/random.mjs + var random_exports = {}; + __export(random_exports, { + random: () => random + }); + function random(min, max) { + if (min === void 0) { + min = 0; + } + if (max === void 0) { + max = MAX; + } + if (max < min) { + throw new Error("max must be greater than min"); + } + return Math.round(create(min, max)); + } + function create(min, max) { + let crypt; + let globalReference2 = getGlobal(); + crypt = globalReference2?.["crypto"] || globalReference2?.["msCrypto"] || globalReference2?.["crypto"] || void 0; + if (typeof crypt === "undefined") { + throw new Error("missing crypt"); + } + let rval = 0; + const range = max - min; + if (range < 2) { + throw new Error("the distance is too small to create a random number."); + } + const bitsNeeded = Math.ceil(Math.log2(range)); + if (bitsNeeded > 53) { + throw new Error("we cannot generate numbers larger than 53 bits."); + } + const bytesNeeded = Math.ceil(bitsNeeded / 8); + const mask = Math.pow(2, bitsNeeded) - 1; + const byteArray = new Uint8Array(bytesNeeded); + crypt.getRandomValues(byteArray); + let p = (bytesNeeded - 1) * 8; + for (var i = 0; i < bytesNeeded; i++) { + rval += byteArray[i] * Math.pow(2, p); + p -= 8; + } + rval = rval & mask; + if (rval >= range) { + return create(min, max); + } + if (rval < min) { + rval += min; + } + return rval; + } + var MAX; + var init_random = __esm({ + "source/math/random.mjs"() { + init_global(); + MAX = 1e9; + Math.log2 = Math.log2 || function(n) { + return Math.log(n) / Math.log(2); + }; + } + }); + + // source/util/trimspaces.mjs + function trimSpaces(value) { + validateString(value); + let placeholder = /* @__PURE__ */ new Map(); + const regex = /((?<pattern>\\(?<char>.)){1})/gim; + let result = value.matchAll(regex); + for (let m of result) { + let g = m?.["groups"]; + if (!isObject(g)) { + continue; + } + let p = g?.["pattern"]; + let c = g?.["char"]; + if (p && c) { + let r = `__${new ID().toString()}__`; + placeholder.set(r, c); + value = value.replace(p, r); + } + } + value = value.trim(); + placeholder.forEach((v, k) => { + value = value.replace(k, `\\${v}`); + }); + return value; + } + var init_trimspaces = __esm({ + "source/util/trimspaces.mjs"() { + init_id(); + init_is(); + init_validate(); + } + }); + + // source/types/queue.mjs + var Queue; + var init_queue = __esm({ + "source/types/queue.mjs"() { + init_base(); + init_constants(); + Queue = class extends Base { + /** + * + */ + constructor() { + super(); + this.data = []; + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/types/queue"); + } + /** + * @return {boolean} + */ + isEmpty() { + return this.data.length === 0; + } + /** + * Read the element at the front of the queue without removing it. + * + * @return {*} + */ + peek() { + if (this.isEmpty()) { + return void 0; + } + return this.data[0]; + } + /** + * Add a new element to the end of the queue. + * + * @param {*} value + * @returns {Queue} + */ + add(value) { + this.data.push(value); + return this; + } + /** + * remove all entries + * + * @returns {Queue} + */ + clear() { + this.data = []; + return this; + } + /** + * Remove the element at the front of the queue + * If the queue is empty, return undefined. + * + * @return {*} + */ + poll() { + if (this.isEmpty()) { + return void 0; + } + return this.data.shift(); + } + }; + } + }); + + // source/types/uniquequeue.mjs + var UniqueQueue; + var init_uniquequeue = __esm({ + "source/types/uniquequeue.mjs"() { + init_queue(); + init_constants(); + init_validate(); + UniqueQueue = class extends Queue { + /** + * + */ + constructor() { + super(); + this[internalSymbol] = { + unique: /* @__PURE__ */ new WeakSet() + }; + } + /** + * Add a new element to the end of the queue. + * + * @param {object} value + * @returns {Queue} + * @throws {TypeError} value is not a object + */ + add(value) { + validateObject(value); + if (!this[internalSymbol].unique.has(value)) { + this[internalSymbol].unique.add(value); + super.add(value); + } + return this; + } + /** + * remove all entries + * + * @returns {Queue} + */ + clear() { + super.clear(); + this[internalSymbol].unique = /* @__PURE__ */ new WeakSet(); + return this; + } + /** + * Remove the element at the front of the queue + * If the queue is empty, return undefined. + * + * @return {object} + */ + poll() { + if (this.isEmpty()) { + return void 0; + } + let value = this.data.shift(); + this[internalSymbol].unique.delete(value); + return value; + } + }; + } + }); + + // source/types/observer.mjs + var Observer; + var init_observer = __esm({ + "source/types/observer.mjs"() { + init_base(); + init_is(); + init_tokenlist(); + init_uniquequeue(); + init_constants(); + Observer = class extends Base { + /** + * + * @param {function} callback + * @param {*} args + */ + constructor(callback, ...args) { + super(); + if (typeof callback !== "function") { + throw new Error("observer callback must be a function"); + } + this.callback = callback; + this.arguments = args; + this.tags = new TokenList(); + this.queue = new UniqueQueue(); + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/types/observer"); + } + /** + * + * @param {string} tag + * @returns {Observer} + */ + addTag(tag) { + this.tags.add(tag); + return this; + } + /** + * + * @param {string} tag + * @returns {Observer} + */ + removeTag(tag) { + this.tags.remove(tag); + return this; + } + /** + * + * @returns {Array} + */ + getTags() { + return this.tags.entries(); + } + /** + * + * @param {string} tag + * @returns {boolean} + */ + hasTag(tag) { + return this.tags.contains(tag); + } + /** + * + * @param {object} subject + * @returns {Promise} + */ + update(subject) { + let self2 = this; + return new Promise(function(resolve, reject) { + if (!isObject(subject)) { + reject("subject must be an object"); + return; + } + self2.queue.add(subject); + setTimeout(() => { + try { + if (self2.queue.isEmpty()) { + resolve(); + return; + } + let s = self2.queue.poll(); + let result = self2.callback.apply(s, self2.arguments); + if (isObject(result) && result instanceof Promise) { + result.then(resolve).catch(reject); + return; + } + resolve(result); + } catch (e) { + reject(e); + } + }, 0); + }); + } + }; + } + }); + + // source/types/observerlist.mjs + var ObserverList; + var init_observerlist = __esm({ + "source/types/observerlist.mjs"() { + init_base(); + init_observer(); + init_validate(); + ObserverList = class extends Base { + /** + * + */ + constructor() { + super(); + this.observers = []; + } + /** + * + * @param {Observer} observer + * @return {ObserverList} + * @throws {TypeError} value is not an instance of Observer + */ + attach(observer) { + validateInstance(observer, Observer); + this.observers.push(observer); + return this; + } + /** + * + * @param {Observer} observer + * @return {ObserverList} + * @throws {TypeError} value is not an instance of Observer + */ + detach(observer) { + validateInstance(observer, Observer); + var i = 0; + var l = this.observers.length; + for (; i < l; i++) { + if (this.observers[i] === observer) { + this.observers.splice(i, 1); + } + } + return this; + } + /** + * + * @param {Observer} observer + * @return {boolean} + * @throws {TypeError} value is not an instance of Observer + */ + contains(observer) { + validateInstance(observer, Observer); + var i = 0; + var l = this.observers.length; + for (; i < l; i++) { + if (this.observers[i] === observer) { + return true; + } + } + return false; + } + /** + * + * @param subject + * @return {Promise} + */ + notify(subject) { + let pomises = []; + let i = 0; + let l = this.observers.length; + for (; i < l; i++) { + pomises.push(this.observers[i].update(subject)); + } + return Promise.all(pomises); + } + }; + } + }); + + // source/types/proxyobserver.mjs + function getHandler() { + const proxy = this; + const handler = { + // https://262.ecma-international.org/9.0/#sec-proxy-object-internal-methods-and-internal-slots-get-p-receiver + get: function(target, key, receiver) { + const value = Reflect.get(target, key, receiver); + if (typeof key === "symbol") { + return value; + } + if (isPrimitive(value)) { + return value; + } + if (isArray(value) || isObject(value)) { + if (proxy.objectMap.has(value)) { + return proxy.objectMap.get(value); + } else if (proxy.proxyMap.has(value)) { + return value; + } else { + let p = new Proxy(value, handler); + proxy.objectMap.set(value, p); + proxy.proxyMap.set(p, value); + return p; + } + } + return value; + }, + // https://262.ecma-international.org/9.0/#sec-proxy-object-internal-methods-and-internal-slots-set-p-v-receiver + set: function(target, key, value, receiver) { + if (proxy.proxyMap.has(value)) { + value = proxy.proxyMap.get(value); + } + if (proxy.proxyMap.has(target)) { + target = proxy.proxyMap.get(target); + } + let current = Reflect.get(target, key, receiver); + if (proxy.proxyMap.has(current)) { + current = proxy.proxyMap.get(current); + } + if (current === value) { + return true; + } + let result; + let descriptor = Reflect.getOwnPropertyDescriptor(target, key); + if (descriptor === void 0) { + descriptor = { + writable: true, + enumerable: true, + configurable: true + }; + } + descriptor["value"] = value; + result = Reflect.defineProperty(target, key, descriptor); + if (typeof key !== "symbol") { + proxy.observers.notify(proxy); + } + return result; + }, + // https://262.ecma-international.org/9.0/#sec-proxy-object-internal-methods-and-internal-slots-delete-p + deleteProperty: function(target, key) { + if (key in target) { + delete target[key]; + if (typeof key !== "symbol") { + proxy.observers.notify(proxy); + } + return true; + } + return false; + }, + // https://262.ecma-international.org/9.0/#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc + defineProperty: function(target, key, descriptor) { + let result = Reflect.defineProperty(target, key, descriptor); + if (typeof key !== "symbol") { + proxy.observers.notify(proxy); + } + return result; + }, + // https://262.ecma-international.org/9.0/#sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v + setPrototypeOf: function(target, key) { + let result = Reflect.setPrototypeOf(object1, key); + if (typeof key !== "symbol") { + proxy.observers.notify(proxy); + } + return result; + } + }; + return handler; + } + var ProxyObserver; + var init_proxyobserver = __esm({ + "source/types/proxyobserver.mjs"() { + init_base(); + init_is(); + init_observer(); + init_observerlist(); + init_validate(); + init_extend(); + init_constants(); + ProxyObserver = class extends Base { + /** + * + * @param {object} object + * @throws {TypeError} value is not a object + */ + constructor(object) { + super(); + this.realSubject = validateObject(object); + this.subject = new Proxy(object, getHandler.call(this)); + this.objectMap = /* @__PURE__ */ new WeakMap(); + this.objectMap.set(this.realSubject, this.subject); + this.proxyMap = /* @__PURE__ */ new WeakMap(); + this.proxyMap.set(this.subject, this.realSubject); + this.observers = new ObserverList(); + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/types/proxy-observer"); + } + /** + * @returns {object} + */ + getSubject() { + return this.subject; + } + /** + * @since 1.24.0 + * @param {Object} obj + * @return {Monster.Types.ProxyObserver} + */ + setSubject(obj) { + let i; + let k = Object.keys(this.subject); + for (i = 0; i < k.length; i++) { + delete this.subject[k[i]]; + } + this.subject = extend(this.subject, obj); + return this; + } + /** + * Get the real object + * + * Changes to this object are not noticed by the observers, so you can make a large number of changes and inform the observers later. + * + * @returns {object} + */ + getRealSubject() { + return this.realSubject; + } + /** + * attach a new observer + * + * @param {Observer} observer + * @returns {ProxyObserver} + */ + attachObserver(observer) { + this.observers.attach(observer); + return this; + } + /** + * detach a observer + * + * @param {Observer} observer + * @returns {ProxyObserver} + */ + detachObserver(observer) { + this.observers.detach(observer); + return this; + } + /** + * notify all observer + * + * @returns {Promise} + */ + notifyObservers() { + return this.observers.notify(this); + } + /** + * @param {Observer} observer + * @returns {boolean} + */ + containsObserver(observer) { + return this.observers.contains(observer); + } + }; + } + }); + + // source/dom/resource.mjs + var resource_exports = {}; + __export(resource_exports, { + KEY_DOCUMENT: () => KEY_DOCUMENT, + KEY_QUERY: () => KEY_QUERY, + Resource: () => Resource, + referenceSymbol: () => referenceSymbol + }); + function appendToDocument() { + const self2 = this; + const targetNode = document.querySelector(self2.getOption(KEY_QUERY, "head")); + if (!(targetNode instanceof HTMLElement)) { + throw new Error("target not found"); + } + addEvents.call(self2); + targetNode.appendChild(self2[referenceSymbol]); + return self2; + } + function addEvents() { + const self2 = this; + const onError = () => { + self2[referenceSymbol].removeEventListener("error", onError); + self2[referenceSymbol].removeEventListener("load", onLoad); + self2[internalStateSymbol].setSubject({ + loaded: true, + error: `${self2[referenceSymbol][self2.constructor.getURLAttribute()]} is not available` + }); + return; + }; + const onLoad = () => { + self2[referenceSymbol].removeEventListener("error", onError); + self2[referenceSymbol].removeEventListener("load", onLoad); + self2[internalStateSymbol].getSubject()["loaded"] = true; + return; + }; + self2[referenceSymbol].addEventListener("load", onLoad, false); + self2[referenceSymbol].addEventListener("error", onError, false); + return self2; + } + var KEY_DOCUMENT, KEY_QUERY, KEY_TIMEOUT, referenceSymbol, Resource; + var init_resource = __esm({ + "source/dom/resource.mjs"() { + init_constants(); + init_extend(); + init_basewithoptions(); + init_global(); + init_id(); + init_is(); + init_observer(); + init_proxyobserver(); + init_constants2(); + init_constants(); + KEY_DOCUMENT = "document"; + KEY_QUERY = "query"; + KEY_TIMEOUT = "timeout"; + referenceSymbol = Symbol("reference"); + Resource = class extends BaseWithOptions { + /** + * + * @param {Object|undefined} options + */ + constructor(options) { + super(options); + let uri = this.getOption(this.constructor.getURLAttribute()); + if (uri === void 0) { + throw new Error("missing source"); + } else if (uri instanceof URL) { + uri = uri.toString(); + } else if (!isString(uri)) { + throw new Error("unsupported url type"); + } + this[internalSymbol][this.constructor.getURLAttribute()] = uri; + this[internalStateSymbol] = new ProxyObserver({ + loaded: false, + error: void 0 + }); + this[referenceSymbol] = void 0; + } + /** + * @return {boolean} + */ + isConnected() { + if (this[referenceSymbol] instanceof HTMLElement) { + return this[referenceSymbol].isConnected; + } + return false; + } + /** + * This method is overridden by the special classes and creates the DOM object. + * This method is also called implicitly, if not yet done explicitly, by calling `connect()`. + * + * @throws {Error} this method must be implemented by derived classes + * @return {Monster.DOM.Resource} + */ + create() { + throw new Error("this method must be implemented by derived classes"); + } + /** + * This method appends the HTMLElement to the specified document. + * If the element has not yet been created, `create()` is called implicitly. + * + * throws {Error} target not found + * @return {Monster.DOM.Resource} + */ + connect() { + if (!(this[referenceSymbol] instanceof HTMLElement)) { + this.create(); + } + appendToDocument.call(this); + return this; + } + /** + * @property {Document} document the document object into which the node is to be appended + * @property {string} src/href url to the corresponding resource + * @property {string} query defines the location where the resource is to be hooked into the dom. + * @property {string} id element attribute id + * @property {string} title element attribute title + * @property {string} class element attribute class + * @property {int} timeout timeout + */ + get defaults() { + return extend({}, super.defaults, { + [this.constructor.getURLAttribute()]: void 0, + [KEY_DOCUMENT]: getGlobalObject("document"), + [KEY_QUERY]: "head", + [KEY_TIMEOUT]: 1e4, + [ATTRIBUTE_ID]: new ID("resource").toString(), + [ATTRIBUTE_CLASS]: void 0, + [ATTRIBUTE_TITLE]: void 0 + }); + } + /** + * With `available()` you can check if a resource is available. + * This is the case when the tag is included and the resource is loaded. + * + * @return {Promise} + */ + available() { + const self2 = this; + if (!(self2[referenceSymbol] instanceof HTMLElement)) { + return Promise.reject("no element"); + } + if (!self2.isConnected()) { + return Promise.reject("element not connected"); + } + if (self2[internalStateSymbol].getSubject()["loaded"] === true) { + if (self2[internalStateSymbol].getSubject()["error"] !== void 0) { + return Promise.reject(self2[internalStateSymbol].getSubject()["error"]); + } + return Promise.resolve(); + } + return new Promise(function(resolve, reject) { + const timeout = setTimeout(() => { + reject("timeout"); + }, self2.getOption("timeout")); + const observer = new Observer(() => { + clearTimeout(timeout); + self2[internalStateSymbol].detachObserver(observer); + resolve(); + }); + self2[internalStateSymbol].attachObserver(observer); + }); + } + /** + * @return {string} + */ + static getURLAttribute() { + throw new Error("this method must be implemented by derived classes"); + } + /** + * @return {symbol} + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/dom/resource"); + } + }; + } + }); + + // source/types/mediatype.mjs + function parseMediaType(mediatype) { + const regex = /(?<type>[A-Za-z]+|\*)\/(?<subtype>([a-zA-Z0-9.\+_\-]+)|\*|)(?<parameter>\s*;\s*([a-zA-Z0-9]+)\s*(=\s*("?[A-Za-z0-9_\-]+"?))?)*/g; + const result = regex.exec(validateString(mediatype)); + const groups = result?.["groups"]; + if (groups === void 0) { + throw new TypeError("the mimetype can not be parsed"); + } + const type = groups?.["type"]; + const subtype = groups?.["subtype"]; + const parameter = groups?.["parameter"]; + if (subtype === "" || type === "") { + throw new TypeError("blank value is not allowed"); + } + return new MediaType(type, subtype, parseParameter(parameter)); + } + function parseParameter(parameter) { + if (!isString(parameter)) { + return void 0; + } + let result = []; + parameter.split(";").forEach((entry) => { + entry = entry.trim(); + if (entry === "") { + return; + } + const kv = entry.split("="); + let key = validateString(kv?.[0]).trim(); + let value = validateString(kv?.[1]).trim(); + result.push({ + key, + value + }); + }); + return result; + } + var internal, MediaType; + var init_mediatype = __esm({ + "source/types/mediatype.mjs"() { + init_base(); + init_is(); + init_validate(); + init_constants(); + internal = Symbol("internal"); + MediaType = class extends Base { + /** + * + * @param {String} type + * @param {String} subtype + * @param {Monster.Types.Parameter[]} parameter + */ + constructor(type, subtype, parameter) { + super(); + this[internal] = { + type: validateString(type).toLowerCase(), + subtype: validateString(subtype).toLowerCase(), + parameter: [] + }; + if (parameter !== void 0) { + this[internal]["parameter"] = validateArray(parameter); + } + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/types/media-type"); + } + /** + * @return {String} + */ + get type() { + return this[internal].type; + } + /** + * @return {String} + */ + get subtype() { + return this[internal].subtype; + } + /** + * @return {Monster.Types.Parameter[]} + */ + get parameter() { + return this[internal].parameter; + } + /** + * + * + * @return {Map} + */ + get parameter() { + const result = /* @__PURE__ */ new Map(); + this[internal]["parameter"].forEach((p) => { + let value = p.value; + if (value.startsWith('"') && value.endsWith('"')) { + value = value.substring(1, value.length - 1); + } + result.set(p.key, value); + }); + return result; + } + /** + * + * @return {string} + */ + toString() { + let parameter = []; + for (let a2 of this[internal].parameter) { + parameter.push(`${a2.key}=${a2.value}`); + } + return `${this[internal].type}/${this[internal].subtype}${parameter.length > 0 ? `;${parameter.join(";")}` : ""}`; + } + }; + } + }); + + // source/types/dataurl.mjs + function parseDataURL(dataurl) { + validateString(dataurl); + dataurl = dataurl.trim(); + if (dataurl.substring(0, 5) !== "data:") { + throw new TypeError("incorrect or missing data protocol"); + } + dataurl = dataurl.substring(5); + let p = dataurl.indexOf(","); + if (p === -1) { + throw new TypeError("malformed data url"); + } + let content = dataurl.substring(p + 1); + let mediatypeAndBase64 = dataurl.substring(0, p).trim(); + let mediatype = "text/plain;charset=US-ASCII"; + let base64Flag = false; + if (mediatypeAndBase64 !== "") { + mediatype = mediatypeAndBase64; + if (mediatypeAndBase64.endsWith("base64")) { + let i = mediatypeAndBase64.lastIndexOf(";"); + mediatype = mediatypeAndBase64.substring(0, i); + base64Flag = true; + } else { + content = decodeURIComponent(content); + } + mediatype = parseMediaType(mediatype); + } else { + content = decodeURIComponent(content); + } + return new DataUrl(content, mediatype, base64Flag); + } + var internal2, DataUrl; + var init_dataurl = __esm({ + "source/types/dataurl.mjs"() { + init_base(); + init_is(); + init_mediatype(); + init_validate(); + init_constants(); + internal2 = Symbol("internal"); + DataUrl = class extends Base { + /** + * + * @param {String} content + * @param {String|Monster.Types.MediaType} mediatype + * @param {boolean} base64=true + */ + constructor(content, mediatype, base64) { + super(); + if (isString(mediatype)) { + mediatype = parseMediaType(mediatype); + } + this[internal2] = { + content: validateString(content), + mediatype: validateInstance(mediatype, MediaType), + base64: validateBoolean(base64 === void 0 ? true : base64) + }; + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/types/data-url"); + } + get content() { + return this[internal2].base64 ? atob(this[internal2].content) : this[internal2].content; + } + get mediatype() { + return this[internal2].mediatype; + } + /** + * + * @return {string} + * @see https://datatracker.ietf.org/doc/html/rfc2397 + */ + toString() { + let content = this[internal2].content; + if (this[internal2].base64 === true) { + content = `;base64,${content}`; + } else { + content = `,${encodeURIComponent(content)}`; + } + return `data:${this[internal2].mediatype.toString()}${content}`; + } + }; + } + }); + + // source/dom/theme.mjs + function getDocumentTheme() { + let document2 = getGlobalObject("document"); + let name = DEFAULT_THEME; + let element = document2.querySelector("html"); + if (element instanceof HTMLElement) { + let theme = element.getAttribute(ATTRIBUTE_THEME_NAME); + if (theme) { + name = theme; + } + } + return new Theme(name); + } + var Theme; + var init_theme = __esm({ + "source/dom/theme.mjs"() { + init_base(); + init_global(); + init_validate(); + init_constants2(); + init_constants(); + Theme = class extends Base { + /** + * + * @param name + * @throws {TypeError} value is not a string + */ + constructor(name) { + super(); + validateString(name); + this.name = name; + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/dom/theme"); + } + /** + * + * @returns {string} + */ + getName() { + return this.name; + } + }; + } + }); + + // source/dom/template.mjs + function findDocumentTemplate(id, currentNode) { + validateString(id); + const document2 = getGlobalObject("document"); + const HTMLTemplateElement2 = getGlobalFunction("HTMLTemplateElement"); + const DocumentFragment2 = getGlobalFunction("DocumentFragment"); + const Document2 = getGlobalFunction("Document"); + let prefixID; + if (!(currentNode instanceof Document2 || currentNode instanceof DocumentFragment2)) { + if (currentNode instanceof Node) { + if (currentNode.hasAttribute(ATTRIBUTE_TEMPLATE_PREFIX)) { + prefixID = currentNode.getAttribute(ATTRIBUTE_TEMPLATE_PREFIX); + } + currentNode = currentNode.getRootNode(); + if (!(currentNode instanceof Document2 || currentNode instanceof DocumentFragment2)) { + currentNode = currentNode.ownerDocument; + } + } + if (!(currentNode instanceof Document2 || currentNode instanceof DocumentFragment2)) { + currentNode = document2; + } + } + let template; + let theme = getDocumentTheme(); + if (prefixID) { + let themedPrefixID = `${prefixID}-${id}-${theme.getName()}`; + template = currentNode.getElementById(themedPrefixID); + if (template instanceof HTMLTemplateElement2) { + return new Template(template); + } + template = document2.getElementById(themedPrefixID); + if (template instanceof HTMLTemplateElement2) { + return new Template(template); + } + } + let themedID = `${id}-${theme.getName()}`; + template = currentNode.getElementById(themedID); + if (template instanceof HTMLTemplateElement2) { + return new Template(template); + } + template = document2.getElementById(themedID); + if (template instanceof HTMLTemplateElement2) { + return new Template(template); + } + template = currentNode.getElementById(id); + if (template instanceof HTMLTemplateElement2) { + return new Template(template); + } + template = document2.getElementById(id); + if (template instanceof HTMLTemplateElement2) { + return new Template(template); + } + throw new Error(`template ${id} not found.`); + } + var Template; + var init_template = __esm({ + "source/dom/template.mjs"() { + init_base(); + init_global(); + init_validate(); + init_constants2(); + init_theme(); + init_constants(); + Template = class extends Base { + /** + * + * @param {HTMLTemplateElement} template + * @throws {TypeError} value is not an instance of + * @throws {TypeError} value is not a function + * @throws {Error} the function is not defined + */ + constructor(template) { + super(); + const HTMLTemplateElement2 = getGlobalFunction("HTMLTemplateElement"); + validateInstance(template, HTMLTemplateElement2); + this.template = template; + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/dom/resource/template"); + } + /** + * + * @returns {HTMLTemplateElement} + */ + getTemplateElement() { + return this.template; + } + /** + * + * @return {DocumentFragment} + * @throws {TypeError} value is not an instance of + */ + createDocumentFragment() { + return this.template.content.cloneNode(true); + } + }; + } + }); + + // source/data/diff.mjs + function diff(first, second) { + return doDiff(first, second); + } + function getKeys(a2, b, type) { + if (isArray(type)) { + const keys = a2.length > b.length ? new Array(a2.length) : new Array(b.length); + keys.fill(0); + return new Set(keys.map((_, i) => i)); + } + return new Set(Object.keys(a2).concat(Object.keys(b))); + } + function doDiff(a2, b, path, diff2) { + let typeA = typeOf(a2); + let typeB = typeOf(b); + const currPath = path || []; + const currDiff = diff2 || []; + if (typeA === typeB && (typeA === "object" || typeA === "array")) { + getKeys(a2, b, typeA).forEach((v) => { + if (!Object.prototype.hasOwnProperty.call(a2, v)) { + currDiff.push(buildResult(a2[v], b[v], "add", currPath.concat(v))); + } else if (!Object.prototype.hasOwnProperty.call(b, v)) { + currDiff.push(buildResult(a2[v], b[v], "delete", currPath.concat(v))); + } else { + doDiff(a2[v], b[v], currPath.concat(v), currDiff); + } + }); + } else { + const o = getOperator(a2, b, typeA, typeB); + if (o !== void 0) { + currDiff.push(buildResult(a2, b, o, path)); + } + } + return currDiff; + } + function buildResult(a2, b, operator, path) { + const result = { + operator, + path + }; + if (operator !== "add") { + result.first = { + value: a2, + type: typeof a2 + }; + if (isObject(a2)) { + const name = Object.getPrototypeOf(a2)?.constructor?.name; + if (name !== void 0) { + result.first.instance = name; + } + } + } + if (operator === "add" || operator === "update") { + result.second = { + value: b, + type: typeof b + }; + if (isObject(b)) { + const name = Object.getPrototypeOf(b)?.constructor?.name; + if (name !== void 0) { + result.second.instance = name; + } + } + } + return result; + } + function isNotEqual(a2, b) { + if (typeof a2 !== typeof b) { + return true; + } + if (a2 instanceof Date && b instanceof Date) { + return a2.getTime() !== b.getTime(); + } + return a2 !== b; + } + function getOperator(a2, b) { + let operator; + let typeA = typeof a2; + let typeB = typeof b; + if (typeA === "undefined" && typeB !== "undefined") { + operator = "add"; + } else if (typeA !== "undefined" && typeB === "undefined") { + operator = "delete"; + } else if (isNotEqual(a2, b)) { + operator = "update"; + } + return operator; + } + var init_diff = __esm({ + "source/data/diff.mjs"() { + init_is(); + init_typeof(); + } + }); + + // source/dom/events.mjs + function fireEvent(element, type) { + const document2 = getDocument(); + if (element instanceof HTMLElement) { + if (type === "click") { + element.click(); + return; + } + let event = new Event(validateString(type), { + bubbles: true, + cancelable: true, + composed: true + }); + element.dispatchEvent(event); + } else if (element instanceof HTMLCollection || element instanceof NodeList) { + for (let e of element) { + fireEvent(e, type); + } + } else { + throw new TypeError("value is not an instance of HTMLElement or HTMLCollection"); + } + } + function fireCustomEvent(element, type, detail) { + const document2 = getDocument(); + if (element instanceof HTMLElement) { + if (!isObject(detail)) { + detail = { detail }; + } + let event = new CustomEvent(validateString(type), { + bubbles: true, + cancelable: true, + composed: true, + detail + }); + element.dispatchEvent(event); + } else if (element instanceof HTMLCollection || element instanceof NodeList) { + for (let e of element) { + fireCustomEvent(e, type, detail); + } + } else { + throw new TypeError("value is not an instance of HTMLElement or HTMLCollection"); + } + } + function findTargetElementFromEvent(event, attributeName, attributeValue) { + validateInstance(event, Event); + if (typeof event.composedPath !== "function") { + throw new Error("unsupported event"); + } + const path = event.composedPath(); + if (isArray(path)) { + for (let i = 0; i < path.length; i++) { + const o = path[i]; + if (o instanceof HTMLElement && o.hasAttribute(attributeName) && (attributeValue === void 0 || o.getAttribute(attributeName) === attributeValue)) { + return o; + } + } + } + return void 0; + } + var init_events = __esm({ + "source/dom/events.mjs"() { + init_is(); + init_validate(); + init_util(); + } + }); + + // source/dom/updater.mjs + function getCheckStateCallback() { + const self2 = this; + return function(current) { + if (this instanceof HTMLInputElement) { + if (["radio", "checkbox"].indexOf(this.type) !== -1) { + return `${this.value}` === `${current}` ? "true" : void 0; + } + } else if (this instanceof HTMLOptionElement) { + if (isArray(current) && current.indexOf(this.value) !== -1) { + return "true"; + } + return void 0; + } + }; + } + function getControlEventHandler() { + const self2 = this; + if (self2[symbol]) { + return self2[symbol]; + } + self2[symbol] = (event) => { + const element = findTargetElementFromEvent(event, ATTRIBUTE_UPDATER_BIND); + if (element === void 0) { + return; + } + retrieveAndSetValue.call(self2, element); + }; + return self2[symbol]; + } + function retrieveAndSetValue(element) { + const self2 = this; + const pathfinder = new Pathfinder(self2[internalSymbol].subject.getSubject()); + let path = element.getAttribute(ATTRIBUTE_UPDATER_BIND); + if (path === null) + throw new Error("the bind argument must start as a value with a path"); + if (path.indexOf("path:") !== 0) { + throw new Error("the bind argument must start as a value with a path"); + } + path = path.substring(5); + let value; + if (element instanceof HTMLInputElement) { + switch (element.type) { + case "checkbox": + value = element.checked ? element.value : void 0; + break; + default: + value = element.value; + break; + } + } else if (element instanceof HTMLTextAreaElement) { + value = element.value; + } else if (element instanceof HTMLSelectElement) { + switch (element.type) { + case "select-one": + value = element.value; + break; + case "select-multiple": + value = element.value; + let options = element?.selectedOptions; + if (options === void 0) + options = element.querySelectorAll(":scope option:checked"); + value = Array.from(options).map(({ value: value2 }) => value2); + break; + } + } else if (element?.constructor?.prototype && !!Object.getOwnPropertyDescriptor(element.constructor.prototype, "value")?.["get"] || element.hasOwnProperty("value")) { + value = element?.["value"]; + } else { + throw new Error("unsupported object"); + } + const copy = clone(self2[internalSymbol].subject.getRealSubject()); + const pf = new Pathfinder(copy); + pf.setVia(path, value); + const diffResult = diff(copy, self2[internalSymbol].subject.getRealSubject()); + if (diffResult.length > 0) { + pathfinder.setVia(path, value); + } + } + function retrieveFromBindings() { + const self2 = this; + if (self2[internalSymbol].element.matches(`[${ATTRIBUTE_UPDATER_BIND}]`)) { + retrieveAndSetValue.call(self2, self2[internalSymbol].element); + } + for (const [, element] of self2[internalSymbol].element.querySelectorAll(`[${ATTRIBUTE_UPDATER_BIND}]`).entries()) { + retrieveAndSetValue.call(self2, element); + } + } + function removeElement(change) { + const self2 = this; + for (const [, element] of self2[internalSymbol].element.querySelectorAll(`:scope [${ATTRIBUTE_UPDATER_REMOVE}]`).entries()) { + element.parentNode.removeChild(element); + } + } + function insertElement(change) { + const self2 = this; + const subject = self2[internalSymbol].subject.getRealSubject(); + let mem = /* @__PURE__ */ new WeakSet(); + let wd = 0; + const container = self2[internalSymbol].element; + while (true) { + let found = false; + wd++; + let p = clone(change?.["path"]); + if (!isArray(p)) + return self2; + while (p.length > 0) { + const current = p.join("."); + let iterator = /* @__PURE__ */ new Set(); + const query = `[${ATTRIBUTE_UPDATER_INSERT}*="path:${current}"]`; + const e = container.querySelectorAll(query); + if (e.length > 0) { + iterator = /* @__PURE__ */ new Set([...e]); + } + if (container.matches(query)) { + iterator.add(container); + } + for (const [, containerElement] of iterator.entries()) { + if (mem.has(containerElement)) + continue; + mem.add(containerElement); + found = true; + const attributes = containerElement.getAttribute(ATTRIBUTE_UPDATER_INSERT); + if (attributes === null) + continue; + let def = trimSpaces(attributes); + let i = def.indexOf(" "); + let key = trimSpaces(def.substr(0, i)); + let refPrefix = `${key}-`; + let cmd = trimSpaces(def.substr(i)); + if (cmd.indexOf("|") > 0) { + throw new Error("pipes are not allowed when cloning a node."); + } + let pipe = new Pipe(cmd); + self2[internalSymbol].callbacks.forEach((f, n) => { + pipe.setCallback(n, f); + }); + let value; + try { + containerElement.removeAttribute(ATTRIBUTE_ERRORMESSAGE); + value = pipe.run(subject); + } catch (e2) { + containerElement.setAttribute(ATTRIBUTE_ERRORMESSAGE, e2.message); + } + let dataPath = cmd.split(":").pop(); + let insertPoint; + if (containerElement.hasChildNodes()) { + insertPoint = containerElement.lastChild; + } + if (!isIterable(value)) { + throw new Error("the value is not iterable"); + } + let available = /* @__PURE__ */ new Set(); + for (const [i2, obj] of Object.entries(value)) { + let ref = refPrefix + i2; + let currentPath = `${dataPath}.${i2}`; + available.add(ref); + let refElement = containerElement.querySelector(`[${ATTRIBUTE_UPDATER_INSERT_REFERENCE}="${ref}"]`); + if (refElement instanceof HTMLElement) { + insertPoint = refElement; + continue; + } + appendNewDocumentFragment(containerElement, key, ref, currentPath); + } + let nodes = containerElement.querySelectorAll( + `[${ATTRIBUTE_UPDATER_INSERT_REFERENCE}*="${refPrefix}"]` + ); + for (const [, node] of Object.entries(nodes)) { + if (!available.has(node.getAttribute(ATTRIBUTE_UPDATER_INSERT_REFERENCE))) { + try { + containerElement.removeChild(node); + } catch (e2) { + containerElement.setAttribute( + ATTRIBUTE_ERRORMESSAGE, + `${containerElement.getAttribute(ATTRIBUTE_ERRORMESSAGE)}, ${e2.message}`.trim() + ); + } + } + } + } + p.pop(); + } + if (found === false) + break; + if (wd++ > 200) { + throw new Error("the maximum depth for the recursion is reached."); + } + } + } + function appendNewDocumentFragment(container, key, ref, path) { + let template = findDocumentTemplate(key, container); + let nodes = template.createDocumentFragment(); + for (const [, node] of Object.entries(nodes.childNodes)) { + if (node instanceof HTMLElement) { + applyRecursive(node, key, path); + node.setAttribute(ATTRIBUTE_UPDATER_INSERT_REFERENCE, ref); + } + container.appendChild(node); + } + } + function applyRecursive(node, key, path) { + if (node instanceof HTMLElement) { + if (node.hasAttribute(ATTRIBUTE_UPDATER_REPLACE)) { + let value = node.getAttribute(ATTRIBUTE_UPDATER_REPLACE); + node.setAttribute(ATTRIBUTE_UPDATER_REPLACE, value.replaceAll(`path:${key}`, `path:${path}`)); + } + if (node.hasAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES)) { + let value = node.getAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES); + node.setAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES, value.replaceAll(`path:${key}`, `path:${path}`)); + } + for (const [, child] of Object.entries(node.childNodes)) { + applyRecursive(child, key, path); + } + } + } + function updateContent(change) { + const self2 = this; + const subject = self2[internalSymbol].subject.getRealSubject(); + let p = clone(change?.["path"]); + runUpdateContent.call(this, this[internalSymbol].element, p, subject); + const slots = this[internalSymbol].element.querySelectorAll("slot"); + if (slots.length > 0) { + for (const [, slot] of Object.entries(slots)) { + for (const [, element] of Object.entries(slot.assignedNodes())) { + runUpdateContent.call(this, element, p, subject); + } + } + } + } + function runUpdateContent(container, parts, subject) { + if (!isArray(parts)) + return; + if (!(container instanceof HTMLElement)) + return; + parts = clone(parts); + let mem = /* @__PURE__ */ new WeakSet(); + while (parts.length > 0) { + const current = parts.join("."); + parts.pop(); + const query = `[${ATTRIBUTE_UPDATER_REPLACE}^="path:${current}"], [${ATTRIBUTE_UPDATER_REPLACE}^="static:"], [${ATTRIBUTE_UPDATER_REPLACE}^="i18n:"]`; + const e = container.querySelectorAll(`${query}`); + const iterator = /* @__PURE__ */ new Set([...e]); + if (container.matches(query)) { + iterator.add(container); + } + for (const [element] of iterator.entries()) { + if (mem.has(element)) + return; + mem.add(element); + const attributes = element.getAttribute(ATTRIBUTE_UPDATER_REPLACE); + let cmd = trimSpaces(attributes); + let pipe = new Pipe(cmd); + this[internalSymbol].callbacks.forEach((f, n) => { + pipe.setCallback(n, f); + }); + let value; + try { + element.removeAttribute(ATTRIBUTE_ERRORMESSAGE); + value = pipe.run(subject); + } catch (e2) { + element.setAttribute(ATTRIBUTE_ERRORMESSAGE, e2.message); + } + if (value instanceof HTMLElement) { + while (element.firstChild) { + element.removeChild(element.firstChild); + } + try { + element.appendChild(value); + } catch (e2) { + element.setAttribute( + ATTRIBUTE_ERRORMESSAGE, + `${element.getAttribute(ATTRIBUTE_ERRORMESSAGE)}, ${e2.message}`.trim() + ); + } + } else { + element.innerHTML = value; + } + } + } + } + function updateAttributes(change) { + const subject = this[internalSymbol].subject.getRealSubject(); + let p = clone(change?.["path"]); + runUpdateAttributes.call(this, this[internalSymbol].element, p, subject); + } + function runUpdateAttributes(container, parts, subject) { + const self2 = this; + if (!isArray(parts)) + return; + parts = clone(parts); + let mem = /* @__PURE__ */ new WeakSet(); + while (parts.length > 0) { + const current = parts.join("."); + parts.pop(); + let iterator = /* @__PURE__ */ new Set(); + const query = `[${ATTRIBUTE_UPDATER_SELECT_THIS}][${ATTRIBUTE_UPDATER_ATTRIBUTES}], [${ATTRIBUTE_UPDATER_ATTRIBUTES}*="path:${current}"], [${ATTRIBUTE_UPDATER_ATTRIBUTES}^="static:"], [${ATTRIBUTE_UPDATER_ATTRIBUTES}^="i18n:"]`; + const e = container.querySelectorAll(query); + if (e.length > 0) { + iterator = /* @__PURE__ */ new Set([...e]); + } + if (container.matches(query)) { + iterator.add(container); + } + for (const [element] of iterator.entries()) { + if (mem.has(element)) + return; + mem.add(element); + if (!element.hasAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES)) { + continue; + } + const attributes = element.getAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES); + for (let [, def] of Object.entries(attributes.split(","))) { + def = trimSpaces(def); + let i = def.indexOf(" "); + let name = trimSpaces(def.substr(0, i)); + let cmd = trimSpaces(def.substr(i)); + let pipe = new Pipe(cmd); + self2[internalSymbol].callbacks.forEach((f, n) => { + pipe.setCallback(n, f, element); + }); + let value; + try { + element.removeAttribute(ATTRIBUTE_ERRORMESSAGE); + value = pipe.run(subject); + } catch (e2) { + element.setAttribute(ATTRIBUTE_ERRORMESSAGE, e2.message); + } + if (value === void 0) { + element.removeAttribute(name); + } else if (element.getAttribute(name) !== value) { + element.setAttribute(name, value); + } + handleInputControlAttributeUpdate.call(this, element, name, value); + } + } + } + } + function handleInputControlAttributeUpdate(element, name, value) { + const self2 = this; + if (element instanceof HTMLSelectElement) { + switch (element.type) { + case "select-multiple": + for (const [index, opt] of Object.entries(element.options)) { + if (value.indexOf(opt.value) !== -1) { + opt.selected = true; + } else { + opt.selected = false; + } + } + break; + case "select-one": + for (const [index, opt] of Object.entries(element.options)) { + if (opt.value === value) { + element.selectedIndex = index; + break; + } + } + break; + } + } else if (element instanceof HTMLInputElement) { + switch (element.type) { + case "radio": + if (name === "checked") { + if (value !== void 0) { + element.checked = true; + } else { + element.checked = false; + } + } + break; + case "checkbox": + if (name === "checked") { + if (value !== void 0) { + element.checked = true; + } else { + element.checked = false; + } + } + break; + case "text": + default: + if (name === "value") { + element.value = value === void 0 ? "" : value; + } + break; + } + } else if (element instanceof HTMLTextAreaElement) { + if (name === "value") { + element.value = value === void 0 ? "" : value; + } + } + } + function addObjectWithUpdaterToElement(elements, symbol2, object) { + const self2 = this; + if (!(self2 instanceof HTMLElement)) { + throw new TypeError("the context of this function must be an instance of HTMLElement"); + } + if (!(typeof symbol2 === "symbol")) { + throw new TypeError("symbol must be an instance of Symbol"); + } + const updaters = /* @__PURE__ */ new Set(); + if (elements instanceof NodeList) { + elements = /* @__PURE__ */ new Set([...elements]); + } else if (elements instanceof HTMLElement) { + elements = /* @__PURE__ */ new Set([elements]); + } else if (elements instanceof Set) { + } else { + throw new TypeError(`elements is not a valid type. (actual: ${typeof elements})`); + } + let result = []; + elements.forEach((element) => { + if (!(element instanceof HTMLElement)) + return; + if (element instanceof HTMLTemplateElement) + return; + const u = new Updater(element, object); + updaters.add(u); + result.push( + u.run().then(() => { + return u.enableEventProcessing(); + }) + ); + }); + if (updaters.size > 0) { + addToObjectLink(self2, symbol2, updaters); + } + return result; + } + var Updater, symbol; + var init_updater = __esm({ + "source/dom/updater.mjs"() { + init_constants(); + init_diff(); + init_pathfinder(); + init_pipe(); + init_constants2(); + init_base(); + init_is(); + init_observer(); + init_proxyobserver(); + init_validate(); + init_clone(); + init_trimspaces(); + init_attributes(); + init_events(); + init_template(); + Updater = class extends Base { + /** + * @since 1.8.0 + * @param {HTMLElement} element + * @param {object|ProxyObserver|undefined} subject + * @throws {TypeError} value is not a object + * @throws {TypeError} value is not an instance of HTMLElement + * @see {@link Monster.DOM.findDocumentTemplate} + */ + constructor(element, subject) { + super(); + if (subject === void 0) + subject = {}; + if (!isInstance(subject, ProxyObserver)) { + subject = new ProxyObserver(subject); + } + this[internalSymbol] = { + element: validateInstance(element, HTMLElement), + last: {}, + callbacks: /* @__PURE__ */ new Map(), + eventTypes: ["keyup", "click", "change", "drop", "touchend", "input"], + subject + }; + this[internalSymbol].callbacks.set("checkstate", getCheckStateCallback.call(this)); + this[internalSymbol].subject.attachObserver( + new Observer(() => { + const s = this[internalSymbol].subject.getRealSubject(); + const diffResult = diff(this[internalSymbol].last, s); + this[internalSymbol].last = clone(s); + for (const [, change] of Object.entries(diffResult)) { + removeElement.call(this, change); + insertElement.call(this, change); + updateContent.call(this, change); + updateAttributes.call(this, change); + } + }) + ); + } + /** + * Defaults: 'keyup', 'click', 'change', 'drop', 'touchend' + * + * @see {@link https://developer.mozilla.org/de/docs/Web/Events} + * @since 1.9.0 + * @param {Array} types + * @return {Updater} + */ + setEventTypes(types) { + this[internalSymbol].eventTypes = validateArray(types); + return this; + } + /** + * With this method, the eventlisteners are hooked in and the magic begins. + * + * ``` + * updater.run().then(() => { + * updater.enableEventProcessing(); + * }); + * ``` + * + * @since 1.9.0 + * @return {Updater} + * @throws {Error} the bind argument must start as a value with a path + */ + enableEventProcessing() { + this.disableEventProcessing(); + for (const type of this[internalSymbol].eventTypes) { + this[internalSymbol].element.addEventListener(type, getControlEventHandler.call(this), { + capture: true, + passive: true + }); + } + return this; + } + /** + * This method turns off the magic or who loves it more profane it removes the eventListener. + * + * @since 1.9.0 + * @return {Updater} + */ + disableEventProcessing() { + for (const type of this[internalSymbol].eventTypes) { + this[internalSymbol].element.removeEventListener(type, getControlEventHandler.call(this)); + } + return this; + } + /** + * The run method must be called for the update to start working. + * The method ensures that changes are detected. + * + * ``` + * updater.run().then(() => { + * updater.enableEventProcessing(); + * }); + * ``` + * + * @summary Let the magic begin + * @return {Promise} + */ + run() { + this[internalSymbol].last = { __init__: true }; + return this[internalSymbol].subject.notifyObservers(); + } + /** + * Gets the values of bound elements and changes them in subject + * + * @since 1.27.0 + * @return {Monster.DOM.Updater} + */ + retrieve() { + retrieveFromBindings.call(this); + return this; + } + /** + * If you have passed a ProxyObserver in the constructor, you will get the object that the ProxyObserver manages here. + * However, if you passed a simple object, here you will get a proxy for that object. + * + * For changes the ProxyObserver must be used. + * + * @since 1.8.0 + * @return {Proxy} + */ + getSubject() { + return this[internalSymbol].subject.getSubject(); + } + /** + * This method can be used to register commands that can be called via call: instruction. + * This can be used to provide a pipe with its own functionality. + * + * @param {string} name + * @param {function} callback + * @returns {Transformer} + * @throws {TypeError} value is not a string + * @throws {TypeError} value is not a function + */ + setCallback(name, callback) { + this[internalSymbol].callbacks.set(name, callback); + return this; + } + }; + symbol = Symbol("@schukai/monster/updater@@EventHandler"); + } + }); + + // source/dom/slotted.mjs + function getSlottedNodes(query, name) { + const self2 = this; + const result = /* @__PURE__ */ new Set(); + if (!self2.shadowRoot) { + return result; + } + let selector = "slot"; + if (name !== void 0) { + if (name === null) { + selector += ":not([name])"; + } else { + selector += `[name=${validateString(name)}]`; + } + } + const slots = self2.shadowRoot.querySelectorAll(selector); + for (const [, slot] of Object.entries(slots)) { + slot.assignedNodes().forEach(function(node) { + if (node === null || node === void 0) { + return; + } + if (isString(query)) { + node.querySelectorAll(query).forEach(function(n) { + result.add(n); + }); + if (node.matches(query)) { + result.add(node); + } + } else if (query !== void 0) { + throw new Error("query must be a string"); + } else { + result.add(node); + } + }); + } + return result; + } + function getSlottedElements(query, name) { + const self2 = this; + const result = /* @__PURE__ */ new Set(); + if (!(self2.shadowRoot instanceof ShadowRoot)) { + return result; + } + let selector = "slot"; + if (name !== void 0) { + if (name === null) { + selector += ":not([name])"; + } else { + selector += `[name=${validateString(name)}]`; + } + } + const slots = self2.shadowRoot.querySelectorAll(selector); + for (const [, slot] of Object.entries(slots)) { + slot.assignedElements().forEach(function(node) { + if (!(node instanceof HTMLElement)) + return; + if (isString(query)) { + node.querySelectorAll(query).forEach(function(n) { + result.add(n); + }); + if (node.matches(query)) { + result.add(node); + } + } else if (query !== void 0) { + throw new Error("query must be a string"); + } else { + result.add(node); + } + }); + } + return result; + } + var init_slotted = __esm({ + "source/dom/slotted.mjs"() { + init_is(); + init_validate(); + } + }); + + // source/dom/util/extract-keys.mjs + function extractKeys(obj, keyPrefix = "", keySeparator = "-", valueSeparator = ".") { + const resultMap = /* @__PURE__ */ new Map(); + function helper(currentObj, currentKeyPrefix, currentValuePrefix) { + for (const key in currentObj) { + if (currentObj[key] !== null && typeof currentObj[key] === "object" && !Array.isArray(currentObj[key])) { + const newKeyPrefix = currentKeyPrefix ? currentKeyPrefix + keySeparator + key.toLowerCase() : key.toLowerCase(); + const newValuePrefix = currentValuePrefix ? currentValuePrefix + valueSeparator + key : key; + helper(currentObj[key], newKeyPrefix, newValuePrefix); + } else { + const finalKey = currentKeyPrefix ? currentKeyPrefix + keySeparator + key.toLowerCase() : key.toLowerCase(); + const finalValue = currentValuePrefix ? currentValuePrefix + valueSeparator + key : key; + resultMap.set(finalKey, finalValue); + } + } + } + helper(obj, keyPrefix, keyPrefix); + return resultMap; + } + var init_extract_keys = __esm({ + "source/dom/util/extract-keys.mjs"() { + } + }); + + // source/dom/util/set-option-from-attribute.mjs + function setOptionFromAttribute(element, name, options, mapping = {}, prefix = "data-monster-option-") { + if (!(element instanceof HTMLElement)) + return options; + if (!element.hasAttributes()) + return options; + const keyMap = extractKeys(options); + const finder = new Pathfinder(options); + const optionName = keyMap.get(name.substring(prefix.length).toLowerCase()); + if (!finder.exists(optionName)) + return; + if (!element.hasAttribute(name)) { + return options; + } + let value = element.getAttribute(name); + if (mapping.hasOwnProperty(optionName) && isFunction(mapping[optionName])) { + value = mapping[optionName](value); + } + const typeOfOptionValue = typeof finder.getVia(optionName); + if (typeOfOptionValue === "boolean") { + value = value === "true"; + } else if (typeOfOptionValue === "number") { + value = Number(value); + } else if (typeOfOptionValue === "string") { + value = String(value); + } else if (typeOfOptionValue === "object") { + value = JSON.parse(value); + } + finder.setVia(optionName, value); + return options; + } + var init_set_option_from_attribute = __esm({ + "source/dom/util/set-option-from-attribute.mjs"() { + init_pathfinder(); + init_is(); + init_customelement(); + init_extract_keys(); + } + }); + + // source/dom/customelement.mjs + var customelement_exports = {}; + __export(customelement_exports, { + CustomElement: () => CustomElement, + assembleMethodSymbol: () => assembleMethodSymbol, + attributeObserverSymbol: () => attributeObserverSymbol, + getSlottedElements: () => getSlottedElements, + initMethodSymbol: () => initMethodSymbol, + registerCustomElement: () => registerCustomElement + }); + function callControlCallback(callBackFunctionName, ...args) { + const self2 = this; + if (!isString(callBackFunctionName) || callBackFunctionName === "") { + return; + } + if (callBackFunctionName in self2) { + return self2[callBackFunctionName](self2, ...args); + } + if (!self2.hasAttribute(ATTRIBUTE_SCRIPT_HOST)) { + return; + } + if (self2[scriptHostElementSymbol].length === 0) { + const targetId = self2.getAttribute(ATTRIBUTE_SCRIPT_HOST); + if (!targetId) { + return; + } + const list = targetId.split(","); + for (const id of list) { + const host = findElementWithIdUpwards(self2, targetId); + if (!(host instanceof HTMLElement)) { + continue; + } + self2[scriptHostElementSymbol].push(host); + } + } + for (const host of self2[scriptHostElementSymbol]) { + if (callBackFunctionName in host) { + try { + return host[callBackFunctionName](self2, ...args); + } catch (e) { + addAttributeToken(self2, ATTRIBUTE_ERRORMESSAGE, e.toString()); + } + } + } + addAttributeToken(self2, ATTRIBUTE_ERRORMESSAGE, `callback ${callBackFunctionName} not found`); + } + function initFromCallbackHost() { + const self2 = this; + let callBackFunctionName = initControlCallbackName; + if (self2.hasAttribute(ATTRIBUTE_INIT_CALLBACK)) { + callBackFunctionName = self2.getAttribute(ATTRIBUTE_INIT_CALLBACK); + } + callControlCallback.call(self2, callBackFunctionName); + } + function attachAttributeChangeMutationObserver() { + const self2 = this; + if (typeof self2[attributeMutationObserverSymbol] !== "undefined") { + return; + } + self2[attributeMutationObserverSymbol] = new MutationObserver(function(mutations, observer) { + for (const mutation of mutations) { + if (mutation.type === "attributes") { + self2.attributeChangedCallback( + mutation.attributeName, + mutation.oldValue, + mutation.target.getAttribute(mutation.attributeName) + ); + } + } + }); + try { + self2[attributeMutationObserverSymbol].observe(self2, { + attributes: true, + attributeOldValue: true + }); + } catch (e) { + addAttributeToken(self2, ATTRIBUTE_ERRORMESSAGE, e.toString()); + } + } + function containChildNode(node) { + const self2 = this; + if (self2.contains(node)) { + return true; + } + for (const [, e] of Object.entries(self2.childNodes)) { + if (e.contains(node)) { + return true; + } + containChildNode.call(e, node); + } + return false; + } + function initOptionObserver() { + const self2 = this; + let lastDisabledValue = void 0; + self2.attachObserver( + new Observer(function() { + const flag = self2.getOption("disabled"); + if (flag === lastDisabledValue) { + return; + } + lastDisabledValue = flag; + if (!(self2.shadowRoot instanceof ShadowRoot)) { + return; + } + const query = "button, command, fieldset, keygen, optgroup, option, select, textarea, input, [data-monster-objectlink]"; + const elements = self2.shadowRoot.querySelectorAll(query); + let nodeList; + try { + nodeList = /* @__PURE__ */ new Set([...elements, ...getSlottedElements.call(self2, query)]); + } catch (e) { + nodeList = elements; + } + for (const element of [...nodeList]) { + if (flag === true) { + element.setAttribute(ATTRIBUTE_DISABLED, ""); + } else { + element.removeAttribute(ATTRIBUTE_DISABLED); + } + } + }) + ); + self2.attachObserver( + new Observer(function() { + if (!hasObjectLink(self2, customElementUpdaterLinkSymbol)) { + return; + } + const updaters = getLinkedObjects(self2, customElementUpdaterLinkSymbol); + for (const list of updaters) { + for (const updater of list) { + let d2 = clone(self2[internalSymbol].getRealSubject()["options"]); + Object.assign(updater.getSubject(), d2); + } + } + }) + ); + self2[attributeObserverSymbol][ATTRIBUTE_DISABLED] = () => { + if (self2.hasAttribute(ATTRIBUTE_DISABLED)) { + self2.setOption(ATTRIBUTE_DISABLED, true); + } else { + self2.setOption(ATTRIBUTE_DISABLED, void 0); + } + }; + self2[attributeObserverSymbol][ATTRIBUTE_OPTIONS] = () => { + const options = getOptionsFromAttributes.call(self2); + if (isObject(options) && Object.keys(options).length > 0) { + self2.setOptions(options); + } + }; + self2[attributeObserverSymbol][ATTRIBUTE_OPTIONS_SELECTOR] = () => { + const options = getOptionsFromScriptTag.call(self2); + if (isObject(options) && Object.keys(options).length > 0) { + self2.setOptions(options); + } + }; + } + function getOptionsFromScriptTag() { + const self2 = this; + if (!self2.hasAttribute(ATTRIBUTE_OPTIONS_SELECTOR)) { + return {}; + } + const node = document.querySelector(self2.getAttribute(ATTRIBUTE_OPTIONS_SELECTOR)); + if (!(node instanceof HTMLScriptElement)) { + addAttributeToken( + self2, + ATTRIBUTE_ERRORMESSAGE, + `the selector ${ATTRIBUTE_OPTIONS_SELECTOR} for options was specified (${self2.getAttribute( + ATTRIBUTE_OPTIONS_SELECTOR + )}) but not found.` + ); + return {}; + } + let obj = {}; + try { + obj = parseOptionsJSON.call(this, node.textContent.trim()); + } catch (e) { + addAttributeToken( + self2, + ATTRIBUTE_ERRORMESSAGE, + `when analyzing the configuration from the script tag there was an error. ${e}` + ); + } + return obj; + } + function getOptionsFromAttributes() { + const self2 = this; + if (this.hasAttribute(ATTRIBUTE_OPTIONS)) { + try { + return parseOptionsJSON.call(self2, this.getAttribute(ATTRIBUTE_OPTIONS)); + } catch (e) { + addAttributeToken( + self2, + ATTRIBUTE_ERRORMESSAGE, + `the options attribute ${ATTRIBUTE_OPTIONS} does not contain a valid json definition (actual: ${this.getAttribute( + ATTRIBUTE_OPTIONS + )}).${e}` + ); + } + } + return {}; + } + function parseOptionsJSON(data) { + let obj = {}; + if (!isString(data)) { + return obj; + } + try { + let dataUrl = parseDataURL(data); + data = dataUrl.content; + } catch (e) { + } + try { + obj = JSON.parse(data); + } catch (e) { + throw e; + } + return validateObject(obj); + } + function initHtmlContent() { + try { + let template = findDocumentTemplate(this.constructor.getTag()); + this.appendChild(template.createDocumentFragment()); + } catch (e) { + let html = this.getOption("templates.main", ""); + if (isString(html) && html.length > 0) { + const mapping = this.getOption("templateMapping", {}); + if (isObject(mapping)) { + html = new Formatter(mapping).format(html); + } + this.innerHTML = html; + } + } + return this; + } + function initCSSStylesheet() { + const self2 = this; + if (!(this.shadowRoot instanceof ShadowRoot)) { + return self2; + } + const styleSheet = this.constructor.getCSSStyleSheet(); + if (styleSheet instanceof CSSStyleSheet) { + if (styleSheet.cssRules.length > 0) { + this.shadowRoot.adoptedStyleSheets = [styleSheet]; + } + } else if (isArray(styleSheet)) { + const assign = []; + for (let s of styleSheet) { + if (isString(s)) { + let trimedStyleSheet = s.trim(); + if (trimedStyleSheet !== "") { + const style = document.createElement("style"); + style.innerHTML = trimedStyleSheet; + self2.shadowRoot.prepend(style); + } + continue; + } + validateInstance(s, CSSStyleSheet); + if (s.cssRules.length > 0) { + assign.push(s); + } + } + if (assign.length > 0) { + this.shadowRoot.adoptedStyleSheets = assign; + } + } else if (isString(styleSheet)) { + let trimedStyleSheet = styleSheet.trim(); + if (trimedStyleSheet !== "") { + const style = document.createElement("style"); + style.innerHTML = styleSheet; + self2.shadowRoot.prepend(style); + } + } + return self2; + } + function initShadowRoot() { + let template; + let html; + try { + template = findDocumentTemplate(this.constructor.getTag()); + } catch (e) { + html = this.getOption("templates.main", ""); + if (!isString(html) || html === void 0 || html === "") { + throw new Error("html is not set."); + } + } + this.attachShadow({ + mode: this.getOption("shadowMode", "open"), + delegatesFocus: this.getOption("delegatesFocus", true) + }); + if (template instanceof Template) { + this.shadowRoot.appendChild(template.createDocumentFragment()); + return this; + } + const mapping = this.getOption("templateMapping", {}); + if (isObject(mapping)) { + html = new Formatter(mapping).format(html); + } + this.shadowRoot.innerHTML = html; + return this; + } + function registerCustomElement(element) { + validateFunction(element); + const customElements2 = getGlobalObject("customElements"); + if (customElements2 === void 0) { + throw new Error("customElements is not supported."); + } + if (customElements2.get(element.getTag()) !== void 0) { + return; + } + customElements2.define(element.getTag(), element); + } + var initMethodSymbol, assembleMethodSymbol, attributeObserverSymbol, attributeMutationObserverSymbol, scriptHostElementSymbol, CustomElement; + var init_customelement = __esm({ + "source/dom/customelement.mjs"() { + init_util(); + init_constants(); + init_extend(); + init_pathfinder(); + init_formatter(); + init_dataurl(); + init_global(); + init_is(); + init_observer(); + init_proxyobserver(); + init_validate(); + init_clone(); + init_attributes(); + init_constants2(); + init_template(); + init_updater(); + init_constants(); + init_translations(); + init_slotted(); + init_init_options_from_attributes(); + init_set_option_from_attribute(); + initMethodSymbol = Symbol.for("@schukai/monster/dom/@@initMethodSymbol"); + assembleMethodSymbol = Symbol.for("@schukai/monster/dom/@@assembleMethodSymbol"); + attributeObserverSymbol = Symbol.for("@schukai/monster/dom/@@attributeObserver"); + attributeMutationObserverSymbol = Symbol("@schukai/monster/dom/@@mutationObserver"); + scriptHostElementSymbol = Symbol("scriptHostElement"); + CustomElement = class extends HTMLElement { + /** + * A new object is created. First the `initOptions` method is called. Here the + * options can be defined in derived classes. Subsequently, the shadowRoot is initialized. + * + * IMPORTANT: CustomControls instances are not created via the constructor, but either via a tag in the HTML or via <code>document.createElement()</code>. + * + * @throws {Error} the options attribute does not contain a valid json definition. + * @since 1.7.0 + */ + constructor() { + super(); + this[attributeObserverSymbol] = {}; + this[internalSymbol] = new ProxyObserver({ + options: initOptionsFromAttributes(this, extend({}, this.defaults)) + }); + this[initMethodSymbol](); + initOptionObserver.call(this); + this[scriptHostElementSymbol] = []; + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/dom/custom-element@@instance"); + } + /** + * This method determines which attributes are to be + * monitored by `attributeChangedCallback()`. Unfortunately, this method is static. + * Therefore, the `observedAttributes` property cannot be changed during runtime. + * + * @return {string[]} + * @since 1.15.0 + */ + static get observedAttributes() { + return []; + } + /** + * + * @param attribute + * @param callback + * @returns {Monster.DOM.CustomElement} + */ + addAttributeObserver(attribute, callback) { + validateFunction(callback); + this[attributeObserverSymbol][attribute] = callback; + return this; + } + /** + * + * @param attribute + * @returns {Monster.DOM.CustomElement} + */ + removeAttributeObserver(attribute) { + delete this[attributeObserverSymbol][attribute]; + return this; + } + /** + * The `defaults` property defines the default values for a control. If you want to override these, + * you can use various methods, which are described in the documentation available at + * {@link https://monsterjs.orgendocconfigurate-a-monster-control}. + * + * The individual configuration values are listed below: + * + * More information about the shadowRoot can be found in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow), + * in the [HTML Standard](https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements) or in the [WHATWG Wiki](https://wiki.whatwg.org/wiki/Custom_Elements). + * + * More information about the template element can be found in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template). + * + * More information about the slot element can be found in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/slot). + * + * @property {boolean} disabled=false Specifies whether the control is disabled. When present, it makes the element non-mutable, non-focusable, and non-submittable with the form. + * @property {string} shadowMode=open Specifies the mode of the shadow root. When set to `open`, elements in the shadow root are accessible from JavaScript outside the root, while setting it to `closed` denies access to the root's nodes from JavaScript outside it. + * @property {Boolean} delegatesFocus=true Specifies the behavior of the control with respect to focusability. When set to `true`, it mitigates custom element issues around focusability. When a non-focusable part of the shadow DOM is clicked, the first focusable part is given focus, and the shadow host is given any available :focus styling. + * @property {Object} templates Specifies the templates used by the control. + * @property {string} templates.main=undefined Specifies the main template used by the control. + * @property {Object} templateMapping Specifies the mapping of templates. + * @since 1.8.0 + */ + get defaults() { + return { + disabled: false, + shadowMode: "open", + delegatesFocus: true, + templates: { + main: void 0 + }, + templateMapping: {} + }; + } + /** + * This method updates the labels of the element. + * The labels are defined in the options object. + * The key of the label is used to retrieve the translation from the document. + * If the translation is different from the label, the label is updated. + * + * Before you can use this method, you must have loaded the translations. + * + * @returns {Monster.DOM.CustomElement} + * @throws {Error} Cannot find element with translations. Add a translations object to the document. + */ + updateI18n() { + const translations = getDocumentTranslations(); + if (!translations) { + return this; + } + let labels = this.getOption("labels"); + if (!(isObject(labels) || isIterable(labels))) { + return this; + } + for (const key in labels) { + const def = labels[key]; + if (isString(def)) { + const text = translations.getText(key, def); + if (text !== def) { + this.setOption(`labels.${key}`, text); + } + continue; + } else if (isObject(def)) { + for (const k in def) { + const d2 = def[k]; + const text = translations.getPluralRuleText(key, k, d2); + if (!isString(text)) { + throw new Error("Invalid labels definition"); + } + if (text !== d2) { + this.setOption(`labels.${key}.${k}`, text); + } + } + continue; + } + throw new Error("Invalid labels definition"); + } + return this; + } + /** + * The `getTag()` method returns the tag name associated with the custom element. This method should be overwritten + * by the derived class. + * + * Note that there is no check on the name of the tag in this class. It is the responsibility of + * the developer to assign an appropriate tag name. If the name is not valid, the + * `registerCustomElement()` method will issue an error. + * + * @see https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name + * @throws {Error} This method must be overridden by the derived class. + * @return {string} The tag name associated with the custom element. + * @since 1.7.0 + */ + static getTag() { + throw new Error("The method `getTag()` must be overridden by the derived class."); + } + /** + * The `getCSSStyleSheet()` method returns a `CSSStyleSheet` object that defines the styles for the custom element. + * If the environment does not support the `CSSStyleSheet` constructor, then an object can be built using the provided detour. + * + * If `undefined` is returned, then the shadow root does not receive a stylesheet. + * + * Example usage: + * + * ```js + * static getCSSStyleSheet() { + * const sheet = new CSSStyleSheet(); + * sheet.replaceSync("p { color: red; }"); + * return sheet; + * } + * ``` + * + * If the environment does not support the `CSSStyleSheet` constructor, + * you can use the following workaround to create the stylesheet: + * + * ```js + * const doc = document.implementation.createHTMLDocument('title'); + * let style = doc.createElement("style"); + * style.innerHTML = "p { color: red; }"; + * style.appendChild(document.createTextNode("")); + * doc.head.appendChild(style); + * return doc.styleSheets[0]; + * ``` + * + * @return {CSSStyleSheet|CSSStyleSheet[]|string|undefined} A `CSSStyleSheet` object or an array of such objects that define the styles for the custom element, or `undefined` if no stylesheet should be applied. + */ + static getCSSStyleSheet() { + return void 0; + } + /** + * attach a new observer + * + * @param {Observer} observer + * @returns {CustomElement} + */ + attachObserver(observer) { + this[internalSymbol].attachObserver(observer); + return this; + } + /** + * detach a observer + * + * @param {Observer} observer + * @returns {CustomElement} + */ + detachObserver(observer) { + this[internalSymbol].detachObserver(observer); + return this; + } + /** + * @param {Observer} observer + * @returns {ProxyObserver} + */ + containsObserver(observer) { + return this[internalSymbol].containsObserver(observer); + } + /** + * nested options can be specified by path `a.b.c` + * + * @param {string} path + * @param {*} defaultValue + * @return {*} + * @since 1.10.0 + */ + getOption(path, defaultValue) { + let value; + try { + value = new Pathfinder(this[internalSymbol].getRealSubject()["options"]).getVia(path); + } catch (e) { + } + if (value === void 0) + return defaultValue; + return value; + } + /** + * Set option and inform elements + * + * @param {string} path + * @param {*} value + * @return {CustomElement} + * @since 1.14.0 + */ + setOption(path, value) { + new Pathfinder(this[internalSymbol].getSubject()["options"]).setVia(path, value); + return this; + } + /** + * @since 1.15.0 + * @param {string|object} options + * @return {CustomElement} + */ + setOptions(options) { + if (isString(options)) { + options = parseOptionsJSON.call(this, options); + } + const self2 = this; + extend(self2[internalSymbol].getSubject()["options"], self2.defaults, options); + return self2; + } + /** + * Is called once via the constructor + * + * @return {CustomElement} + * @since 1.8.0 + */ + [initMethodSymbol]() { + return this; + } + /** + * This method is called once when the object is included in the DOM for the first time. It performs the following actions: + * 1. Extracts the options from the attributes and the script tag of the element and sets them. + * 2. Initializes the shadow root and its CSS stylesheet (if specified). + * 3. Initializes the HTML content of the element. + * 4. Initializes the custom elements inside the shadow root and the slotted elements. + * 5. Attaches a mutation observer to observe changes to the attributes of the element. + * + * @return {CustomElement} - The updated custom element. + * @since 1.8.0 + */ + [assembleMethodSymbol]() { + const self2 = this; + let elements; + let nodeList; + const AttributeOptions = getOptionsFromAttributes.call(self2); + if (isObject(AttributeOptions) && Object.keys(AttributeOptions).length > 0) { + self2.setOptions(AttributeOptions); + } + const ScriptOptions = getOptionsFromScriptTag.call(self2); + if (isObject(ScriptOptions) && Object.keys(ScriptOptions).length > 0) { + self2.setOptions(ScriptOptions); + } + if (self2.getOption("shadowMode", false) !== false) { + try { + initShadowRoot.call(self2); + elements = self2.shadowRoot.childNodes; + } catch (e) { + addAttributeToken(self2, ATTRIBUTE_ERRORMESSAGE, e.toString()); + } + try { + initCSSStylesheet.call(this); + } catch (e) { + addAttributeToken(self2, ATTRIBUTE_ERRORMESSAGE, e.toString()); + } + } + if (!(elements instanceof NodeList)) { + initHtmlContent.call(this); + elements = this.childNodes; + } + initFromCallbackHost.call(this); + try { + nodeList = /* @__PURE__ */ new Set([...elements, ...getSlottedElements.call(self2)]); + } catch (e) { + nodeList = elements; + } + addObjectWithUpdaterToElement.call( + self2, + nodeList, + customElementUpdaterLinkSymbol, + clone(self2[internalSymbol].getRealSubject()["options"]) + ); + attachAttributeChangeMutationObserver.call(this); + return self2; + } + /** + * This method is called every time the element is inserted into the DOM. It checks if the custom element + * has already been initialized and if not, calls the assembleMethod to initialize it. + * + * @return {void} + * @since 1.7.0 + * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/connectedCallback + */ + connectedCallback() { + const self2 = this; + if (!hasObjectLink(self2, customElementUpdaterLinkSymbol)) { + self2[assembleMethodSymbol](); + } + } + /** + * Called every time the element is removed from the DOM. Useful for running clean up code. + * + * @return {void} + * @since 1.7.0 + */ + disconnectedCallback() { + } + /** + * The custom element has been moved into a new document (e.g. someone called document.adoptNode(el)). + * + * @return {void} + * @since 1.7.0 + */ + adoptedCallback() { + } + /** + * Called when an observed attribute has been added, removed, updated, or replaced. Also called for initial + * values when an element is created by the parser, or upgraded. Note: only attributes listed in the observedAttributes + * property will receive this callback. + * + * @param {string} attrName + * @param {string} oldVal + * @param {string} newVal + * @return {void} + * @since 1.15.0 + */ + attributeChangedCallback(attrName, oldVal, newVal) { + const self2 = this; + if (attrName.startsWith("data-monster-option-")) { + setOptionFromAttribute(self2, attrName, this[internalSymbol].getSubject()["options"]); + } + const callback = self2[attributeObserverSymbol]?.[attrName]; + if (isFunction(callback)) { + try { + callback.call(self2, newVal, oldVal); + } catch (e) { + addAttributeToken(self2, ATTRIBUTE_ERRORMESSAGE, e.toString()); + } + } + } + /** + * + * @param {Node} node + * @return {boolean} + * @throws {TypeError} value is not an instance of + * @since 1.19.0 + */ + hasNode(node) { + const self2 = this; + if (containChildNode.call(self2, validateInstance(node, Node))) { + return true; + } + if (!(self2.shadowRoot instanceof ShadowRoot)) { + return false; + } + return containChildNode.call(self2.shadowRoot, node); + } + /** + * Calls a callback function if it exists. + * + * @param {string} name + * @param {*} args + * @returns {*} + */ + callCallback(name, args) { + const self2 = this; + return callControlCallback.call(self2, name, ...args); + } + }; + } + }); + + // source/dom/util/init-options-from-attributes.mjs + var init_options_from_attributes_exports = {}; + __export(init_options_from_attributes_exports, { + initOptionsFromAttributes: () => initOptionsFromAttributes + }); + function initOptionsFromAttributes(element, options, mapping = {}, prefix = "data-monster-option-") { + if (!(element instanceof HTMLElement)) + return options; + if (!element.hasAttributes()) + return options; + const keyMap = extractKeys(options); + const finder = new Pathfinder(options); + element.getAttributeNames().forEach((name) => { + if (!name.startsWith(prefix)) + return; + const optionName = keyMap.get(name.substring(prefix.length).toLowerCase()); + if (!finder.exists(optionName)) + return; + if (element.hasAttribute(name)) { + let value = element.getAttribute(name); + if (mapping.hasOwnProperty(optionName) && isFunction(mapping[optionName])) { + value = mapping[optionName](value); + } + let optionValue = finder.getVia(optionName); + if (optionValue === null || optionValue === void 0) { + optionValue = value; + } + const typeOfOptionValue = typeof optionValue; + if (optionValue === null || optionValue === void 0) { + value = null; + } else if (typeOfOptionValue === "boolean") { + value = value === "true"; + } else if (typeOfOptionValue === "number") { + value = Number(value); + } else if (typeOfOptionValue === "string") { + value = String(value); + } else if (typeOfOptionValue === "object") { + value = JSON.parse(value); + } + finder.setVia(optionName, value); + } + }); + return options; + } + var init_init_options_from_attributes = __esm({ + "source/dom/util/init-options-from-attributes.mjs"() { + init_pathfinder(); + init_is(); + init_customelement(); + init_extract_keys(); + } + }); + + // source/dom/ready.mjs + var ready_exports = {}; + __export(ready_exports, { + domReady: () => domReady, + windowReady: () => windowReady + }); + var domReady, windowReady; + var init_ready = __esm({ + "source/dom/ready.mjs"() { + init_util(); + domReady = new Promise((resolve) => { + const document2 = getDocument(); + if (document2.readyState === "loading") { + document2.addEventListener("DOMContentLoaded", resolve); + } else { + resolve(); + } + }); + windowReady = new Promise((resolve) => { + const document2 = getDocument(); + const window2 = getWindow(); + if (document2.readyState === "complete") { + resolve(); + } else { + window2.addEventListener("load", resolve); + } + }); + } + }); + + // node_modules/.pnpm/element-internals-polyfill@1.3.5/node_modules/element-internals-polyfill/dist/index.js + var dist_exports = {}; + var init_dist = __esm({ + "node_modules/.pnpm/element-internals-polyfill@1.3.5/node_modules/element-internals-polyfill/dist/index.js"() { + (function() { + "use strict"; + const refMap = /* @__PURE__ */ new WeakMap(); + const validityMap = /* @__PURE__ */ new WeakMap(); + const hiddenInputMap = /* @__PURE__ */ new WeakMap(); + const internalsMap = /* @__PURE__ */ new WeakMap(); + const validationMessageMap = /* @__PURE__ */ new WeakMap(); + const formsMap = /* @__PURE__ */ new WeakMap(); + const shadowHostsMap = /* @__PURE__ */ new WeakMap(); + const formElementsMap = /* @__PURE__ */ new WeakMap(); + const refValueMap = /* @__PURE__ */ new WeakMap(); + const upgradeMap = /* @__PURE__ */ new WeakMap(); + const shadowRootMap = /* @__PURE__ */ new WeakMap(); + const validationAnchorMap = /* @__PURE__ */ new WeakMap(); + const documentFragmentMap = /* @__PURE__ */ new WeakMap(); + const connectedCallbackMap = /* @__PURE__ */ new WeakMap(); + const validityUpgradeMap = /* @__PURE__ */ new WeakMap(); + const aom = { + ariaAtomic: "aria-atomic", + ariaAutoComplete: "aria-autocomplete", + ariaBusy: "aria-busy", + ariaChecked: "aria-checked", + ariaColCount: "aria-colcount", + ariaColIndex: "aria-colindex", + ariaColIndexText: "aria-colindextext", + ariaColSpan: "aria-colspan", + ariaCurrent: "aria-current", + ariaDisabled: "aria-disabled", + ariaExpanded: "aria-expanded", + ariaHasPopup: "aria-haspopup", + ariaHidden: "aria-hidden", + ariaInvalid: "aria-invalid", + ariaKeyShortcuts: "aria-keyshortcuts", + ariaLabel: "aria-label", + ariaLevel: "aria-level", + ariaLive: "aria-live", + ariaModal: "aria-modal", + ariaMultiLine: "aria-multiline", + ariaMultiSelectable: "aria-multiselectable", + ariaOrientation: "aria-orientation", + ariaPlaceholder: "aria-placeholder", + ariaPosInSet: "aria-posinset", + ariaPressed: "aria-pressed", + ariaReadOnly: "aria-readonly", + ariaRelevant: "aria-relevant", + ariaRequired: "aria-required", + ariaRoleDescription: "aria-roledescription", + ariaRowCount: "aria-rowcount", + ariaRowIndex: "aria-rowindex", + ariaRowIndexText: "aria-rowindextext", + ariaRowSpan: "aria-rowspan", + ariaSelected: "aria-selected", + ariaSetSize: "aria-setsize", + ariaSort: "aria-sort", + ariaValueMax: "aria-valuemax", + ariaValueMin: "aria-valuemin", + ariaValueNow: "aria-valuenow", + ariaValueText: "aria-valuetext", + role: "role" + }; + const initAom = (ref, internals) => { + for (let key in aom) { + internals[key] = null; + let closureValue = null; + const attributeName = aom[key]; + Object.defineProperty(internals, key, { + get() { + return closureValue; + }, + set(value) { + closureValue = value; + if (ref.isConnected) { + ref.setAttribute(attributeName, value); + } else { + upgradeMap.set(ref, internals); + } + } + }); + } + }; + function initNode(node) { + const internals = internalsMap.get(node); + const { form } = internals; + initForm(node, form, internals); + initLabels(node, internals.labels); + } + const walkFieldset = (node, firstRender = false) => { + const walker = document.createTreeWalker(node, NodeFilter.SHOW_ELEMENT, { + acceptNode(node2) { + return internalsMap.has(node2) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP; + } + }); + let current = walker.nextNode(); + const isCallNecessary = !firstRender || node.disabled; + while (current) { + if (current.formDisabledCallback && isCallNecessary) { + setDisabled(current, node.disabled); + } + current = walker.nextNode(); + } + }; + const disabledOrNameObserverConfig = { attributes: true, attributeFilter: ["disabled", "name"] }; + const disabledOrNameObserver = mutationObserverExists() ? new MutationObserver((mutationsList) => { + for (const mutation of mutationsList) { + const target = mutation.target; + if (mutation.attributeName === "disabled") { + if (target.constructor["formAssociated"]) { + setDisabled(target, target.hasAttribute("disabled")); + } else if (target.localName === "fieldset") { + walkFieldset(target); + } + } + if (mutation.attributeName === "name") { + if (target.constructor["formAssociated"]) { + const internals = internalsMap.get(target); + const value = refValueMap.get(target); + internals.setFormValue(value); + } + } + } + }) : {}; + function observerCallback(mutationList) { + mutationList.forEach((mutationRecord) => { + const { addedNodes: addedNodes2, removedNodes } = mutationRecord; + const added = Array.from(addedNodes2); + const removed = Array.from(removedNodes); + added.forEach((node) => { + if (internalsMap.has(node) && node.constructor["formAssociated"]) { + initNode(node); + } + if (upgradeMap.has(node)) { + const internals = upgradeMap.get(node); + const aomKeys = Object.keys(aom); + aomKeys.filter((key) => internals[key] !== null).forEach((key) => { + node.setAttribute(aom[key], internals[key]); + }); + upgradeMap.delete(node); + } + if (validityUpgradeMap.has(node)) { + const internals = validityUpgradeMap.get(node); + node.setAttribute("internals-valid", internals.validity.valid.toString()); + node.setAttribute("internals-invalid", (!internals.validity.valid).toString()); + node.setAttribute("aria-invalid", (!internals.validity.valid).toString()); + validityUpgradeMap.delete(node); + } + if (node.localName === "form") { + const formElements = formElementsMap.get(node); + const walker = document.createTreeWalker(node, NodeFilter.SHOW_ELEMENT, { + acceptNode(node2) { + return internalsMap.has(node2) && !(formElements && formElements.has(node2)) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP; + } + }); + let current = walker.nextNode(); + while (current) { + initNode(current); + current = walker.nextNode(); + } + } + if (node.localName === "fieldset") { + disabledOrNameObserver.observe?.(node, disabledOrNameObserverConfig); + walkFieldset(node, true); + } + }); + removed.forEach((node) => { + const internals = internalsMap.get(node); + if (internals && hiddenInputMap.get(internals)) { + removeHiddenInputs(internals); + } + if (shadowHostsMap.has(node)) { + const observer = shadowHostsMap.get(node); + observer.disconnect(); + } + }); + }); + } + function fragmentObserverCallback(mutationList) { + mutationList.forEach((mutation) => { + const { removedNodes } = mutation; + removedNodes.forEach((node) => { + const observer = documentFragmentMap.get(mutation.target); + if (internalsMap.has(node)) { + upgradeInternals(node); + } + observer.disconnect(); + }); + }); + } + const deferUpgrade = (fragment) => { + const observer = new MutationObserver(fragmentObserverCallback); + observer.observe?.(fragment, { childList: true }); + documentFragmentMap.set(fragment, observer); + }; + mutationObserverExists() ? new MutationObserver(observerCallback) : {}; + const observerConfig = { + childList: true, + subtree: true + }; + const setDisabled = (ref, disabled) => { + ref.toggleAttribute("internals-disabled", disabled); + if (disabled) { + ref.setAttribute("aria-disabled", "true"); + } else { + ref.removeAttribute("aria-disabled"); + } + if (ref.formDisabledCallback) { + ref.formDisabledCallback.apply(ref, [disabled]); + } + }; + const removeHiddenInputs = (internals) => { + const hiddenInputs = hiddenInputMap.get(internals); + hiddenInputs.forEach((hiddenInput) => { + hiddenInput.remove(); + }); + hiddenInputMap.set(internals, []); + }; + const createHiddenInput = (ref, internals) => { + const input = document.createElement("input"); + input.type = "hidden"; + input.name = ref.getAttribute("name"); + ref.after(input); + hiddenInputMap.get(internals).push(input); + return input; + }; + const initRef = (ref, internals) => { + hiddenInputMap.set(internals, []); + disabledOrNameObserver.observe?.(ref, disabledOrNameObserverConfig); + }; + const initLabels = (ref, labels) => { + if (labels.length) { + Array.from(labels).forEach((label) => label.addEventListener("click", ref.click.bind(ref))); + let firstLabelId = labels[0].id; + if (!labels[0].id) { + firstLabelId = `${labels[0].htmlFor}_Label`; + labels[0].id = firstLabelId; + } + ref.setAttribute("aria-labelledby", firstLabelId); + } + }; + const setFormValidity = (form) => { + const nativeControlValidity = Array.from(form.elements).filter((element) => !element.tagName.includes("-") && element.validity).map((element) => element.validity.valid); + const polyfilledElements = formElementsMap.get(form) || []; + const polyfilledValidity = Array.from(polyfilledElements).filter((control) => control.isConnected).map((control) => internalsMap.get(control).validity.valid); + const hasInvalid = [...nativeControlValidity, ...polyfilledValidity].includes(false); + form.toggleAttribute("internals-invalid", hasInvalid); + form.toggleAttribute("internals-valid", !hasInvalid); + }; + const formInputCallback = (event) => { + setFormValidity(findParentForm(event.target)); + }; + const formChangeCallback = (event) => { + setFormValidity(findParentForm(event.target)); + }; + const wireSubmitLogic = (form) => { + const SUBMIT_BUTTON_SELECTOR = ":is(button[type=submit], input[type=submit], button:not([type])):not([disabled])"; + let submitButtonSelector = `${SUBMIT_BUTTON_SELECTOR}:not([form])`; + if (form.id) { + submitButtonSelector += `,${SUBMIT_BUTTON_SELECTOR}[form='${form.id}']`; + } + form.addEventListener("click", (event) => { + const target = event.target; + if (target.closest(submitButtonSelector)) { + const elements = formElementsMap.get(form); + if (form.noValidate) { + return; + } + if (elements.size) { + const nodes = Array.from(elements); + const validityList = nodes.reverse().map((node) => { + const internals = internalsMap.get(node); + return internals.reportValidity(); + }); + if (validityList.includes(false)) { + event.preventDefault(); + } + } + } + }); + }; + const formResetCallback = (event) => { + const elements = formElementsMap.get(event.target); + if (elements && elements.size) { + elements.forEach((element) => { + if (element.constructor.formAssociated && element.formResetCallback) { + element.formResetCallback.apply(element); + } + }); + } + }; + const initForm = (ref, form, internals) => { + if (form) { + const formElements = formElementsMap.get(form); + if (formElements) { + formElements.add(ref); + } else { + const initSet = /* @__PURE__ */ new Set(); + initSet.add(ref); + formElementsMap.set(form, initSet); + wireSubmitLogic(form); + form.addEventListener("reset", formResetCallback); + form.addEventListener("input", formInputCallback); + form.addEventListener("change", formChangeCallback); + } + formsMap.set(form, { ref, internals }); + if (ref.constructor["formAssociated"] && ref.formAssociatedCallback) { + setTimeout(() => { + ref.formAssociatedCallback.apply(ref, [form]); + }, 0); + } + setFormValidity(form); + } + }; + const findParentForm = (elem) => { + let parent = elem.parentNode; + if (parent && parent.tagName !== "FORM") { + parent = findParentForm(parent); + } + return parent; + }; + const throwIfNotFormAssociated = (ref, message, ErrorType = DOMException) => { + if (!ref.constructor["formAssociated"]) { + throw new ErrorType(message); + } + }; + const overrideFormMethod = (form, returnValue, method) => { + const elements = formElementsMap.get(form); + if (elements && elements.size) { + elements.forEach((element) => { + const internals = internalsMap.get(element); + const valid = internals[method](); + if (!valid) { + returnValue = false; + } + }); + } + return returnValue; + }; + const upgradeInternals = (ref) => { + if (ref.constructor["formAssociated"]) { + const internals = internalsMap.get(ref); + const { labels, form } = internals; + initLabels(ref, labels); + initForm(ref, form, internals); + } + }; + function mutationObserverExists() { + return typeof MutationObserver !== "undefined"; + } + class ValidityState { + constructor() { + this.badInput = false; + this.customError = false; + this.patternMismatch = false; + this.rangeOverflow = false; + this.rangeUnderflow = false; + this.stepMismatch = false; + this.tooLong = false; + this.tooShort = false; + this.typeMismatch = false; + this.valid = true; + this.valueMissing = false; + Object.seal(this); + } + } + const setValid = (validityObject) => { + validityObject.badInput = false; + validityObject.customError = false; + validityObject.patternMismatch = false; + validityObject.rangeOverflow = false; + validityObject.rangeUnderflow = false; + validityObject.stepMismatch = false; + validityObject.tooLong = false; + validityObject.tooShort = false; + validityObject.typeMismatch = false; + validityObject.valid = true; + validityObject.valueMissing = false; + return validityObject; + }; + const reconcileValidity = (validityObject, newState, form) => { + validityObject.valid = isValid(newState); + Object.keys(newState).forEach((key) => validityObject[key] = newState[key]); + if (form) { + setFormValidity(form); + } + return validityObject; + }; + const isValid = (validityState) => { + let valid = true; + for (let key in validityState) { + if (key !== "valid" && validityState[key] !== false) { + valid = false; + } + } + return valid; + }; + const customStateMap = /* @__PURE__ */ new WeakMap(); + function addState(ref, stateName) { + ref.toggleAttribute(stateName, true); + if (ref.part) { + ref.part.add(stateName); + } + } + class CustomStateSet extends Set { + static get isPolyfilled() { + return true; + } + constructor(ref) { + super(); + if (!ref || !ref.tagName || ref.tagName.indexOf("-") === -1) { + throw new TypeError("Illegal constructor"); + } + customStateMap.set(this, ref); + } + add(state) { + if (!/^--/.test(state) || typeof state !== "string") { + throw new DOMException(`Failed to execute 'add' on 'CustomStateSet': The specified value ${state} must start with '--'.`); + } + const result = super.add(state); + const ref = customStateMap.get(this); + const stateName = `state${state}`; + if (ref.isConnected) { + addState(ref, stateName); + } else { + setTimeout(() => { + addState(ref, stateName); + }); + } + return result; + } + clear() { + for (let [entry] of this.entries()) { + this.delete(entry); + } + super.clear(); + } + delete(state) { + const result = super.delete(state); + const ref = customStateMap.get(this); + if (ref.isConnected) { + ref.toggleAttribute(`state${state}`, false); + if (ref.part) { + ref.part.remove(`state${state}`); + } + } else { + setTimeout(() => { + ref.toggleAttribute(`state${state}`, false); + if (ref.part) { + ref.part.remove(`state${state}`); + } + }); + } + return result; + } + } + function __classPrivateFieldGet(receiver, state, kind, f) { + if (kind === "a" && !f) + throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) + throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); + } + function __classPrivateFieldSet(receiver, state, value, kind, f) { + if (kind === "m") + throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) + throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) + throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value; + } + var _HTMLFormControlsCollection_elements; + class HTMLFormControlsCollection { + constructor(elements) { + _HTMLFormControlsCollection_elements.set(this, void 0); + __classPrivateFieldSet(this, _HTMLFormControlsCollection_elements, elements, "f"); + for (let i = 0; i < elements.length; i++) { + let element = elements[i]; + this[i] = element; + if (element.hasAttribute("name")) { + this[element.getAttribute("name")] = element; + } + } + Object.freeze(this); + } + get length() { + return __classPrivateFieldGet(this, _HTMLFormControlsCollection_elements, "f").length; + } + [(_HTMLFormControlsCollection_elements = /* @__PURE__ */ new WeakMap(), Symbol.iterator)]() { + return __classPrivateFieldGet(this, _HTMLFormControlsCollection_elements, "f")[Symbol.iterator](); + } + item(i) { + return this[i] == null ? null : this[i]; + } + namedItem(name) { + return this[name] == null ? null : this[name]; + } + } + function patchFormPrototype() { + const checkValidity = HTMLFormElement.prototype.checkValidity; + HTMLFormElement.prototype.checkValidity = checkValidityOverride; + const reportValidity = HTMLFormElement.prototype.reportValidity; + HTMLFormElement.prototype.reportValidity = reportValidityOverride; + function checkValidityOverride(...args) { + let returnValue = checkValidity.apply(this, args); + return overrideFormMethod(this, returnValue, "checkValidity"); + } + function reportValidityOverride(...args) { + let returnValue = reportValidity.apply(this, args); + return overrideFormMethod(this, returnValue, "reportValidity"); + } + const { get } = Object.getOwnPropertyDescriptor(HTMLFormElement.prototype, "elements"); + Object.defineProperty(HTMLFormElement.prototype, "elements", { + get(...args) { + const elements = get.call(this, ...args); + const polyfilledElements = Array.from(formElementsMap.get(this) || []); + if (polyfilledElements.length === 0) { + return elements; + } + const orderedElements = Array.from(elements).concat(polyfilledElements).sort((a2, b) => { + if (a2.compareDocumentPosition) { + return a2.compareDocumentPosition(b) & 2 ? 1 : -1; + } + return 0; + }); + return new HTMLFormControlsCollection(orderedElements); + } + }); + } + class ElementInternals { + static get isPolyfilled() { + return true; + } + constructor(ref) { + if (!ref || !ref.tagName || ref.tagName.indexOf("-") === -1) { + throw new TypeError("Illegal constructor"); + } + const rootNode = ref.getRootNode(); + const validity = new ValidityState(); + this.states = new CustomStateSet(ref); + refMap.set(this, ref); + validityMap.set(this, validity); + internalsMap.set(ref, this); + initAom(ref, this); + initRef(ref, this); + Object.seal(this); + if (rootNode instanceof DocumentFragment) { + deferUpgrade(rootNode); + } + } + checkValidity() { + const ref = refMap.get(this); + throwIfNotFormAssociated(ref, `Failed to execute 'checkValidity' on 'ElementInternals': The target element is not a form-associated custom element.`); + if (!this.willValidate) { + return true; + } + const validity = validityMap.get(this); + if (!validity.valid) { + const validityEvent = new Event("invalid", { + bubbles: false, + cancelable: true, + composed: false + }); + ref.dispatchEvent(validityEvent); + } + return validity.valid; + } + get form() { + const ref = refMap.get(this); + throwIfNotFormAssociated(ref, `Failed to read the 'form' property from 'ElementInternals': The target element is not a form-associated custom element.`); + let form; + if (ref.constructor["formAssociated"] === true) { + form = findParentForm(ref); + } + return form; + } + get labels() { + const ref = refMap.get(this); + throwIfNotFormAssociated(ref, `Failed to read the 'labels' property from 'ElementInternals': The target element is not a form-associated custom element.`); + const id = ref.getAttribute("id"); + const hostRoot = ref.getRootNode(); + if (hostRoot && id) { + return hostRoot.querySelectorAll(`[for="${id}"]`); + } + return []; + } + reportValidity() { + const ref = refMap.get(this); + throwIfNotFormAssociated(ref, `Failed to execute 'reportValidity' on 'ElementInternals': The target element is not a form-associated custom element.`); + if (!this.willValidate) { + return true; + } + const valid = this.checkValidity(); + const anchor = validationAnchorMap.get(this); + if (anchor && !ref.constructor["formAssociated"]) { + throw new DOMException(`Failed to execute 'reportValidity' on 'ElementInternals': The target element is not a form-associated custom element.`); + } + if (!valid && anchor) { + ref.focus(); + anchor.focus(); + } + return valid; + } + setFormValue(value) { + const ref = refMap.get(this); + throwIfNotFormAssociated(ref, `Failed to execute 'setFormValue' on 'ElementInternals': The target element is not a form-associated custom element.`); + removeHiddenInputs(this); + if (value != null && !(value instanceof FormData)) { + if (ref.getAttribute("name")) { + const hiddenInput = createHiddenInput(ref, this); + hiddenInput.value = value; + } + } else if (value != null && value instanceof FormData) { + Array.from(value).reverse().forEach(([formDataKey, formDataValue]) => { + if (typeof formDataValue === "string") { + const hiddenInput = createHiddenInput(ref, this); + hiddenInput.name = formDataKey; + hiddenInput.value = formDataValue; + } + }); + } + refValueMap.set(ref, value); + } + setValidity(validityChanges, validationMessage, anchor) { + const ref = refMap.get(this); + throwIfNotFormAssociated(ref, `Failed to execute 'setValidity' on 'ElementInternals': The target element is not a form-associated custom element.`); + if (!validityChanges) { + throw new TypeError("Failed to execute 'setValidity' on 'ElementInternals': 1 argument required, but only 0 present."); + } + validationAnchorMap.set(this, anchor); + const validity = validityMap.get(this); + const validityChangesObj = {}; + for (const key in validityChanges) { + validityChangesObj[key] = validityChanges[key]; + } + if (Object.keys(validityChangesObj).length === 0) { + setValid(validity); + } + const check = { ...validity, ...validityChangesObj }; + delete check.valid; + const { valid } = reconcileValidity(validity, check, this.form); + if (!valid && !validationMessage) { + throw new DOMException(`Failed to execute 'setValidity' on 'ElementInternals': The second argument should not be empty if one or more flags in the first argument are true.`); + } + validationMessageMap.set(this, valid ? "" : validationMessage); + if (ref.isConnected) { + ref.toggleAttribute("internals-invalid", !valid); + ref.toggleAttribute("internals-valid", valid); + ref.setAttribute("aria-invalid", `${!valid}`); + } else { + validityUpgradeMap.set(ref, this); + } + } + get shadowRoot() { + const ref = refMap.get(this); + const shadowRoot = shadowRootMap.get(ref); + if (shadowRoot) { + return shadowRoot; + } + return null; + } + get validationMessage() { + const ref = refMap.get(this); + throwIfNotFormAssociated(ref, `Failed to read the 'validationMessage' property from 'ElementInternals': The target element is not a form-associated custom element.`); + return validationMessageMap.get(this); + } + get validity() { + const ref = refMap.get(this); + throwIfNotFormAssociated(ref, `Failed to read the 'validity' property from 'ElementInternals': The target element is not a form-associated custom element.`); + const validity = validityMap.get(this); + return validity; + } + get willValidate() { + const ref = refMap.get(this); + throwIfNotFormAssociated(ref, `Failed to read the 'willValidate' property from 'ElementInternals': The target element is not a form-associated custom element.`); + if (ref.disabled || ref.hasAttribute("disabled") || ref.hasAttribute("readonly")) { + return false; + } + return true; + } + } + function isElementInternalsSupported() { + if (typeof window === "undefined" || !window.ElementInternals || !HTMLElement.prototype.attachInternals) { + return false; + } + class ElementInternalsFeatureDetection extends HTMLElement { + constructor() { + super(); + this.internals = this.attachInternals(); + } + } + const randomName = `element-internals-feature-detection-${Math.random().toString(36).replace(/[^a-z]+/g, "")}`; + customElements.define(randomName, ElementInternalsFeatureDetection); + const featureDetectionElement = new ElementInternalsFeatureDetection(); + return [ + "shadowRoot", + "form", + "willValidate", + "validity", + "validationMessage", + "labels", + "setFormValue", + "setValidity", + "checkValidity", + "reportValidity" + ].every((prop) => prop in featureDetectionElement.internals); + } + if (!isElementInternalsSupported()) { + if (typeof window !== "undefined") { + window.ElementInternals = ElementInternals; + } + if (typeof CustomElementRegistry !== "undefined") { + const define2 = CustomElementRegistry.prototype.define; + CustomElementRegistry.prototype.define = function(name, constructor, options) { + if (constructor.formAssociated) { + const connectedCallback = constructor.prototype.connectedCallback; + constructor.prototype.connectedCallback = function() { + if (!connectedCallbackMap.has(this)) { + connectedCallbackMap.set(this, true); + if (this.hasAttribute("disabled")) { + setDisabled(this, true); + } + } + if (connectedCallback != null) { + connectedCallback.apply(this); + } + upgradeInternals(this); + }; + } + define2.call(this, name, constructor, options); + }; + } + if (typeof HTMLElement !== "undefined") { + HTMLElement.prototype.attachInternals = function() { + if (!this.tagName) { + return {}; + } else if (this.tagName.indexOf("-") === -1) { + throw new Error(`Failed to execute 'attachInternals' on 'HTMLElement': Unable to attach ElementInternals to non-custom elements.`); + } + if (internalsMap.has(this)) { + throw new DOMException(`DOMException: Failed to execute 'attachInternals' on 'HTMLElement': ElementInternals for the specified element was already attached.`); + } + return new ElementInternals(this); + }; + } + if (typeof Element !== "undefined") { + let attachShadowObserver = function(...args) { + const shadowRoot = attachShadow.apply(this, args); + shadowRootMap.set(this, shadowRoot); + if (mutationObserverExists()) { + const observer = new MutationObserver(observerCallback); + if (window.ShadyDOM) { + observer.observe(this, observerConfig); + } else { + observer.observe(shadowRoot, observerConfig); + } + shadowHostsMap.set(this, observer); + } + return shadowRoot; + }; + const attachShadow = Element.prototype.attachShadow; + Element.prototype.attachShadow = attachShadowObserver; + } + if (mutationObserverExists()) { + const documentObserver = new MutationObserver(observerCallback); + documentObserver.observe(document.documentElement, observerConfig); + } + if (typeof HTMLFormElement !== "undefined") { + patchFormPrototype(); + } + if (typeof window !== "undefined" && !window.CustomStateSet) { + window.CustomStateSet = CustomStateSet; + } + } else if (typeof window !== "undefined" && !window.CustomStateSet) { + window.CustomStateSet = CustomStateSet; + const attachInternals = HTMLElement.prototype.attachInternals; + HTMLElement.prototype.attachInternals = function(...args) { + const internals = attachInternals.call(this, args); + internals.states = new CustomStateSet(this); + return internals; + }; + } + })(); + } + }); + + // source/dom/customcontrol.mjs + var customcontrol_exports = {}; + __export(customcontrol_exports, { + CustomControl: () => CustomControl + }); + function getInternal() { + const self2 = this; + if (!(attachedInternalSymbol in this)) { + throw new Error("ElementInternals is not supported and a polyfill is necessary"); + } + return self2[attachedInternalSymbol]; + } + function initObserver() { + const self2 = this; + self2[attributeObserverSymbol]["value"] = () => { + self2.setOption("value", self2.getAttribute("value")); + }; + } + var attachedInternalSymbol, CustomControl; + var init_customcontrol = __esm({ + "source/dom/customcontrol.mjs"() { + init_extend(); + init_attributes(); + init_constants2(); + init_customelement(); + init_constants(); + attachedInternalSymbol = Symbol("attachedInternal"); + CustomControl = class extends CustomElement { + /** + * The constructor method of CustomControl, which is called when creating a new instance. + * It checks whether the element supports `attachInternals()` and initializes an internal form-associated element + * if supported. Additionally, it initializes a MutationObserver to watch for attribute changes. + * + * See the links below for more information: + * {@link https://html.spec.whatwg.org/multipage/custom-elements.html#dom-customelementregistry-define|CustomElementRegistry.define()} + * {@link https://html.spec.whatwg.org/multipage/custom-elements.html#dom-customelementregistry-get|CustomElementRegistry.get()} + * and {@link https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals|ElementInternals} + * + * @inheritdoc + * @throws {Error} the ElementInternals is not supported and a polyfill is necessary + * @since 1.7.0 + */ + constructor() { + super(); + if (typeof this["attachInternals"] === "function") { + this[attachedInternalSymbol] = this.attachInternals(); + } else { + throw Error("the ElementInternals is not supported and a polyfill is necessary"); + } + initObserver.call(this); + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/dom/custom-control@@instance"); + } + /** + * This method determines which attributes are to be monitored by `attributeChangedCallback()`. + * + * @return {string[]} + * @since 1.15.0 + */ + static get observedAttributes() { + return super.observedAttributes; + } + /** + * Adding a static `formAssociated` property, with a true value, makes an autonomous custom element a form-associated custom element. + * + * @see [attachInternals()]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/attachInternals} + * @see [Custom Elements Face Example]{@link https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements-face-example} + * @since 1.14.0 + * @return {boolean} + */ + static formAssociated = true; + /** + * @inheritdoc + * @since 1.14.0 + **/ + get defaults() { + return extend({}, super.defaults); + } + /** + * Must be overridden by a derived class and return the value of the control. + * + * This is a method of [internal API](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals), which is a part of the web standard for custom elements. + * + * @since 1.14.0 + * @throws {Error} the value getter must be overwritten by the derived class + */ + get value() { + throw Error("the value getter must be overwritten by the derived class"); + } + /** + * Must be overridden by a derived class and set the value of the control. + * + * This is a method of [internal API](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals), which is a part of the web standard for custom elements. + * + * @param {*} value The value to set. + * @since 1.14.0 + * @throws {Error} the value setter must be overwritten by the derived class + */ + set value(value) { + throw Error("the value setter must be overwritten by the derived class"); + } + /** + * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals) + * + * @return {NodeList} + * @since 1.14.0 + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/labels} + * @throws {Error} the ElementInternals is not supported and a polyfill is necessary + */ + get labels() { + return getInternal.call(this)?.labels; + } + /** + * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals) + * + * @return {string|null} + */ + get name() { + return this.getAttribute("name"); + } + /** + * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals) + * + * @return {string} + */ + get type() { + return this.constructor.getTag(); + } + /** + * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals) + * + * @return {ValidityState} + * @throws {Error} the ElementInternals is not supported and a polyfill is necessary + * @see [ValidityState]{@link https://developer.mozilla.org/en-US/docs/Web/API/ValidityState} + * @see [validity]{@link https://developer.mozilla.org/en-US/docs/Web/API/validity} + */ + get validity() { + return getInternal.call(this)?.validity; + } + /** + * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals) + * + * @return {string} + * @since 1.14.0 + * @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/validationMessage + * @throws {Error} the ElementInternals is not supported and a polyfill is necessary + */ + get validationMessage() { + return getInternal.call(this)?.validationMessage; + } + /** + * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals) + * + * @return {boolean} + * @since 1.14.0 + * @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/willValidate + * @throws {Error} the ElementInternals is not supported and a polyfill is necessary + */ + get willValidate() { + return getInternal.call(this)?.willValidate; + } + /** + * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals) + * + * @return {boolean} + * @since 1.14.0 + * @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/states + * @throws {Error} the ElementInternals is not supported and a polyfill is necessary + */ + get states() { + return getInternal.call(this)?.states; + } + /** + * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals) + * + * @return {HTMLFontElement|null} + * @since 1.14.0 + * @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/form + * @throws {Error} the ElementInternals is not supported and a polyfill is necessary + */ + get form() { + return getInternal.call(this)?.form; + } + /** + * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals) + * + * ``` + * // Use the control's name as the base name for submitted data + * const n = this.getAttribute('name'); + * const entries = new FormData(); + * entries.append(n + '-first-name', this.firstName_); + * entries.append(n + '-last-name', this.lastName_); + * this.setFormValue(entries); + * ``` + * + * @param {File|string|FormData} value + * @param {File|string|FormData} state + * @since 1.14.0 + * @return {undefined} + * @throws {DOMException} NotSupportedError + * @throws {Error} the ElementInternals is not supported and a polyfill is necessary + * @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/setFormValue + */ + setFormValue(value, state) { + getInternal.call(this).setFormValue(value, state); + } + /** + * + * @param {object} flags + * @param {string|undefined} message + * @param {HTMLElement} anchor + * @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/setValidity + * @since 1.14.0 + * @return {undefined} + * @throws {DOMException} NotSupportedError + * @throws {Error} the ElementInternals is not supported and a polyfill is necessary + */ + setValidity(flags, message, anchor) { + getInternal.call(this).setValidity(flags, message, anchor); + } + /** + * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals) + * + * @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/checkValidity + * @since 1.14.0 + * @return {boolean} + * @throws {DOMException} NotSupportedError + * @throws {Error} the ElementInternals is not supported and a polyfill is necessary + */ + checkValidity() { + return getInternal.call(this)?.checkValidity(); + } + /** + * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals) + * + * @return {boolean} + * @since 1.14.0 + * @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/reportValidity + * @throws {Error} the ElementInternals is not supported and a polyfill is necessary + * @throws {DOMException} NotSupportedError + */ + reportValidity() { + return getInternal.call(this)?.reportValidity(); + } + /** + * Sets the `form` attribute of the custom control to the `id` of the passed form element. + * If no form element is passed, removes the `form` attribute. + * + * @param {HTMLFormElement} form - The form element to associate with the control + */ + formAssociatedCallback(form) { + if (form) { + if (form.id) { + this.setAttribute("form", form.id); + } + } else { + this.removeAttribute("form"); + } + } + /** + * Sets or removes the `disabled` attribute of the custom control based on the passed value. + * + * @param {boolean} disabled - Whether or not the control should be disabled + */ + formDisabledCallback(disabled) { + if (disabled) { + this.setAttribute("disabled", ""); + } else { + this.removeAttribute("disabled"); + } + } + /** + * @param {string} state + * @param {string} mode + */ + formStateRestoreCallback(state, mode) { + } + /** + * + */ + formResetCallback() { + this.value = ""; + } + }; + } + }); + + // source/types/randomid.mjs + var randomid_exports = {}; + __export(randomid_exports, { + RandomID: () => RandomID + }); + var internalCounter2, RandomID; + var init_randomid = __esm({ + "source/types/randomid.mjs"() { + init_random(); + init_global(); + init_id(); + internalCounter2 = 0; + RandomID = class extends ID { + /** + * create new object + */ + constructor() { + super(); + internalCounter2 += 1; + this.id = getGlobal().btoa(random(1, 1e4)).replace(/=/g, "").replace(/^[0-9]+/, "X") + internalCounter2; + } + }; + } + }); + + // source/types/uuid.mjs + var uuid_exports = {}; + __export(uuid_exports, { + UUID: () => UUID + }); + function createWithRandom() { + return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) { + const r = random(0, 65e3) * 16 | 0; + const v = c === "x" ? r : r & 3 | 8; + return v.toString(16)[0]; + }); + } + function createWithCrypto() { + const crypt = getGlobalObject("crypto"); + if (!isObject(crypt)) + return; + if (typeof crypt?.["randomUUID"]) + return; + return crypt.randomUUID(); + } + var UUID; + var init_uuid = __esm({ + "source/types/uuid.mjs"() { + init_constants(); + init_random(); + init_is(); + init_base(); + init_global(); + UUID = class extends Base { + /** + * + */ + constructor() { + super(); + let uuid = createWithCrypto(); + if (uuid === void 0) { + uuid = createWithRandom(); + } + if (uuid === void 0) { + throw new Error("unsupported"); + } + this[internalSymbol] = { + value: uuid + }; + } + /** + * + * @return {string} + */ + toString() { + return this[internalSymbol]["value"]; + } + }; + } + }); + + // test/web/prepare.js + if (typeof window === "object") { + (function() { + let sayswho = function() { + var ua = navigator.userAgent, tem, M = ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || []; + if (/trident/i.test(M[1])) { + tem = /\brv[ :]+(\d+)/g.exec(ua) || []; + return "IE " + (tem[1] || ""); + } + if (M[1] === "Chrome") { + tem = ua.match(/\b(OPR|Edge)\/(\d+)/); + if (tem != null) + return tem.slice(1).join(" ").replace("OPR", "Opera"); + } + M = M[2] ? [M[1], M[2]] : [navigator.appName, navigator.appVersion, "-?"]; + if ((tem = ua.match(/version\/(\d+)/i)) != null) + M.splice(1, 1, tem[1]); + return M.join(" "); + }(); + let element = document.querySelector("h1"); + element.innerHTML += " " + sayswho; + })(); + } + + // node_modules/.pnpm/chai@4.3.7/node_modules/chai/index.mjs + var import_index = __toESM(require_chai2(), 1); + var expect = import_index.default.expect; + var version = import_index.default.version; + var Assertion = import_index.default.Assertion; + var AssertionError = import_index.default.AssertionError; + var util = import_index.default.util; + var config = import_index.default.config; + var use = import_index.default.use; + var should = import_index.default.should; + var assert = import_index.default.assert; + var core = import_index.default.core; + var chai_default = import_index.default; + + // test/cases/text/formatter.mjs + init_formatter(); + describe("Formatter", function() { + describe("examples", function() { + it("rfc example should run", function() { + expect(new Formatter({ + a: { + b: { + c: "Hello" + }, + d: "World", + e: 1 + } + }).format("${a.b.c} ${a.d | toupper}!")).to.be.equal("Hello WORLD!"); + }); + it("doc example should run", function() { + expect(new Formatter({ + a: { + b: { + c: "Hello" + }, + d: "world" + } + }).format("${a.b.c} ${a.d | ucfirst}!")).to.be.equal("Hello World!"); + }); + }); + describe("set marker()", function() { + [ + ["#a#", "#", void 0, "test"], + ["{a}", "{", "}", "test"], + ["i18n{a}", "i18n{", "}", "test"] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + let c = data.shift(); + let d2 = data.shift(); + it("format " + a2 + " with marker " + b + " and " + c + " should return " + b, function() { + expect( + new Formatter({ + a: "test" + }).setMarker(b, c).format(a2) + ).to.equal(d2); + }); + }); + }); + describe("examples()", function() { + [ + ["${a | tojson}", '{"b":{"c":"Hello"},"d":"World","e":1}'], + ["click ${a.d} times", "click World times"], + [" ${a.b.c} ", " Hello "], + [" ${a.b.c}", " Hello"], + ["${a.b.c} ", "Hello "], + ["${a.b.c}", "Hello"], + ["${a.b.c}${a.b.c}", "HelloHello"], + ["${a.b.c} ${a.b.c}", "Hello Hello"], + ["${a.b.c} ${a.b.c} ", "Hello Hello "], + [" ${a.b.c} ${a.b.c} ", " Hello Hello "], + [" ${a.b.c} ${a.d} ", " Hello World "], + [" ${a.b.c} ${a.b.c | toupper | length | tostring} ", " Hello 5 "] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + it("format " + a2 + " should return " + b, function() { + let obj = { + a: { + b: { + c: "Hello" + }, + d: "World", + e: 1 + } + }; + expect(new Formatter(obj).format(a2)).is.equal(b); + }); + }); + }); + describe("Marker in marker", function() { + let text = "${mykey${subkey}}"; + let expected = "1"; + it("format " + text + " should " + expected, function() { + let obj = { + mykey2: "1", + subkey: "2" + }; + expect(new Formatter(obj).format(text)).is.equal(expected); + }); + }); + describe("setParameterChars()", function() { + it("setParameterChars() should return Instance", function() { + expect(new Formatter({}).setParameterChars("a", "b")).is.instanceof(Formatter); + }); + }); + describe("with callbacks", function() { + it("add callback", function() { + const formatter = new Formatter({ + x: "1" + }, { + callbacks: { + my: (value) => { + return "!" + value + "!"; + } + } + }); + expect(formatter.format("${x | call:my}")).is.equal("!1!"); + }); + }); + describe("Marker in marker with parameter", function() { + let text = "${mykey::mykey=${subkey}}"; + let expected = "2"; + it("format " + text + " should " + expected, function() { + let obj = { + subkey: "2" + }; + expect(new Formatter(obj).format(text)).is.equal(expected); + }); + }); + describe("exceptions", function() { + [ + ["${a.b.x}", TypeError], + ["${a.b.d | toupper | length}", TypeError], + ["${a.b.d}", TypeError], + // a.b.d return undefined by pathfinder + ["${a.b.d | tolower}", TypeError], + // a.b.d return undefined by pathfinder + ["${a | }", Error] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + it("format " + a2 + " should throw " + typeof b, function() { + expect( + () => { + new Formatter({ + a: { + b: { + c: "test", + d: 4 + } + } + }).format(a2); + } + ).to.throw(b); + }); + }); + }); + describe("Formatter", () => { + it("should format a basic string with object values", () => { + const formatter = new Formatter({ name: "John", age: 30 }); + const result = formatter.format("My name is ${name} and I am ${age | tostring} years old."); + expect(result).to.equal("My name is John and I am 30 years old."); + }); + it("should format a string with nested markers", () => { + const text = "${mykey${subkey}}"; + const obj = { mykey2: "1", subkey: "2" }; + const formatter = new Formatter(obj); + expect(formatter.format(text)).to.equal("1"); + }); + it("should format a string with custom markers", () => { + const formatter = new Formatter({ name: "John", age: 30 }); + formatter.setMarker("[", "]"); + const result = formatter.format("My name is [name] and I am [age | tostring] years old."); + expect(result).to.equal("My name is John and I am 30 years old."); + }); + it("should format a string using callback", () => { + const formatter = new Formatter({ x: "1" }, { + callbacks: { + quote: (value) => { + return '"' + value + '"'; + } + } + }); + expect(formatter.format("${x | call:quote}")).to.equal('"1"'); + }); + it("should format a string with parameters", () => { + const obj = { + a: { + b: { + c: "Hello" + }, + d: "world" + } + }; + const formatter = new Formatter(obj); + const result = formatter.format("${a.b.c} ${a.d | ucfirst}!"); + expect(result).to.equal("Hello World!"); + }); + it("should throw a too deep nesting error", () => { + const formatter = new Formatter({ name: "John" }); + const nestedText = "${name${name${name${name${name${name${name${name${name${name${name${name${name${name${name${name${name${name${name}}}}}}}}}}}}}}}}}}"; + expect(() => formatter.format(nestedText)).to.throw("syntax error in formatter template"); + }); + it("should throw a too deep nesting error", () => { + const inputObj = { + mykey: "${mykey}" + }; + const formatter = new Formatter(inputObj); + const text = "${mykey}"; + let formattedText = text; + for (let i = 0; i < 21; i++) { + formattedText = "${" + formattedText + "}"; + } + expect(() => formatter.format(formattedText)).to.throw("too deep nesting"); + }); + }); + }); + + // source/text/generate-range-comparison-expression.mjs + function generateRangeComparisonExpression(expression, valueName, options = {}) { + const { urlEncode = false, andOp = "&&", orOp = "||", eqOp = "==", geOp = ">=", leOp = "<=" } = options; + const ranges = expression.split(","); + let comparison = ""; + for (let i = 0; i < ranges.length; i++) { + const range = ranges[i].trim(); + if (range === "") { + throw new Error(`Invalid range '${range}'`); + } else if (range.includes("-")) { + const [start, end] = range.split("-").map((s) => s === "" ? null : parseFloat(s)); + if (start !== null && isNaN(start) || end !== null && isNaN(end)) { + throw new Error(`Invalid value in range '${range}'`); + } + if (start !== null && end !== null && start > end) { + throw new Error(`Invalid range '${range}'`); + } + const compStart = start !== null ? `${valueName}${urlEncode ? encodeURIComponent(geOp) : geOp}${start}` : ""; + const compEnd = end !== null ? `${valueName}${urlEncode ? encodeURIComponent(leOp) : leOp}${end}` : ""; + const compRange = `${compStart}${compStart && compEnd ? ` ${andOp} ` : ""}${compEnd}`; + comparison += ranges.length > 1 ? `(${compRange})` : compRange; + } else { + const value = parseFloat(range); + if (isNaN(value)) { + throw new Error(`Invalid value '${range}'`); + } + const compValue = `${valueName}${urlEncode ? encodeURIComponent(eqOp) : eqOp}${value}`; + comparison += ranges.length > 1 ? `(${compValue})` : compValue; + } + if (i < ranges.length - 1) { + comparison += ` ${orOp} `; + } + } + return comparison; + } + + // test/cases/text/util.mjs + describe("generateRangeComparisonExpression", () => { + it("should generate correct comparison expression for single values", () => { + const expression = "1,3,5"; + const valueName = "x"; + const result = generateRangeComparisonExpression(expression, valueName); + expect(result).to.equal("(x==1) || (x==3) || (x==5)"); + }); + it("should generate correct comparison expression for ranges", () => { + const expression = "1-3,6-8"; + const valueName = "x"; + const result = generateRangeComparisonExpression(expression, valueName); + expect(result).to.equal("(x>=1 && x<=3) || (x>=6 && x<=8)"); + }); + it("should generate correct comparison expression for mixed ranges and single values", () => { + const expression = "1-3,5,7-9"; + const valueName = "x"; + const result = generateRangeComparisonExpression(expression, valueName); + expect(result).to.equal("(x>=1 && x<=3) || (x==5) || (x>=7 && x<=9)"); + }); + it("should throw an error for invalid range", () => { + const expression = "1-3,5-4"; + const valueName = "x"; + expect(() => generateRangeComparisonExpression(expression, valueName)).to.throw(`Invalid range '5-4'`); + }); + it("should throw an error for invalid value", () => { + const expression = "1-3,a"; + const valueName = "x"; + expect(() => generateRangeComparisonExpression(expression, valueName)).to.throw("Invalid value"); + }); + it("should generate correct comparison expression with custom operators", () => { + const expression = "1-3,5"; + const valueName = "x"; + const options = { + andOp: "AND", + orOp: "OR", + eqOp: "===", + geOp: ">=", + leOp: "<=" + }; + const result = generateRangeComparisonExpression(expression, valueName, options); + expect(result).to.equal("(x>=1 AND x<=3) OR (x===5)"); + }); + it("should generate correct comparison expression with urlEncode option", () => { + const testCases = [ + { + expression: "1,3,5", + valueName: "x", + expected: "(x%3D%3D1) || (x%3D%3D3) || (x%3D%3D5)" + }, + { + expression: "-10", + valueName: "x", + expected: "x%3C%3D10" + }, + { + expression: "10-", + valueName: "x", + expected: "x%3E%3D10" + }, + { + expression: "1-3,6-8", + valueName: "y", + expected: "(y%3E%3D1 && y%3C%3D3) || (y%3E%3D6 && y%3C%3D8)" + }, + { + expression: "1-3,5,7-9", + valueName: "z", + expected: "(z%3E%3D1 && z%3C%3D3) || (z%3D%3D5) || (z%3E%3D7 && z%3C%3D9)" + } + ]; + testCases.forEach(({ expression, valueName, expected }) => { + const result = generateRangeComparisonExpression(expression, valueName, { urlEncode: true }); + expect(result).to.equal(expected); + }); + }); + it("should generate correct comparison expression for open-ended ranges with urlEncode option", () => { + const testCases = [ + { + expression: "10-", + valueName: "x", + expected: "x%3E%3D10" + }, + { + expression: "-10", + valueName: "y", + expected: "y%3C%3D10" + } + ]; + testCases.forEach(({ expression, valueName, expected }) => { + const result = generateRangeComparisonExpression(expression, valueName, { urlEncode: true }); + expect(result).to.equal(expected); + }); + }); + }); + + // source/text/bracketed-key-value-hash.mjs + function parseBracketedKeyValueHash(hashString) { + const selectors = {}; + const trimmedHashString = hashString.trim(); + const cleanedHashString = trimmedHashString.charAt(0) === "#" ? trimmedHashString.slice(1) : trimmedHashString; + let currentSelector = ""; + function addToResult(key, value) { + if (currentSelector && key) { + if (!selectors[currentSelector]) { + selectors[currentSelector] = {}; + } + selectors[currentSelector][key] = value; + } + } + let currentKey = ""; + let currentValue = ""; + let inKey = true; + let inValue = false; + let inQuotedValue = false; + let inSelector = true; + let escaped = false; + let quotedValueStartChar = ""; + for (let i = 0; i < cleanedHashString.length; i++) { + const c = cleanedHashString[i]; + const nextChar = cleanedHashString?.[i + 1]; + if (c === "\\" && !escaped) { + escaped = true; + continue; + } + if (escaped) { + if (inSelector) { + currentSelector += c; + } else if (inKey) { + currentKey += c; + } else if (inValue) { + currentValue += c; + } + escaped = false; + continue; + } + if (inQuotedValue && quotedValueStartChar !== c) { + if (inSelector) { + currentSelector += c; + } else if (inKey) { + currentKey += c; + } else if (inValue) { + currentValue += c; + } + continue; + } + if (c === ";" && inSelector) { + inSelector = true; + currentSelector = ""; + continue; + } + if (inSelector === true && c !== "(") { + currentSelector += c; + continue; + } + if (c === "(" && inSelector) { + inSelector = false; + inKey = true; + currentKey = ""; + continue; + } + if (inKey === true && c !== "=") { + currentKey += c; + continue; + } + if (c === "=" && inKey) { + inKey = false; + inValue = true; + if (nextChar === '"' || nextChar === "'") { + inQuotedValue = true; + quotedValueStartChar = nextChar; + i++; + continue; + } + currentValue = ""; + continue; + } + if (inValue === true) { + if (inQuotedValue) { + if (c === quotedValueStartChar) { + inQuotedValue = false; + continue; + } + currentValue += c; + continue; + } + if (c === ",") { + inValue = false; + inKey = true; + const decodedCurrentValue = decodeURIComponent(currentValue); + addToResult(currentKey, decodedCurrentValue); + currentKey = ""; + currentValue = ""; + continue; + } + if (c === ")") { + inValue = false; + inSelector = true; + const decodedCurrentValue = decodeURIComponent(currentValue); + addToResult(currentKey, decodedCurrentValue); + currentKey = ""; + currentValue = ""; + currentSelector = ""; + continue; + } + currentValue += c; + continue; + } + } + if (inSelector) { + return selectors; + } + return {}; + } + function createBracketedKeyValueHash(object, addHashPrefix = true) { + if (!object) { + return addHashPrefix ? "#" : ""; + } + let hashString = ""; + function encodeKeyValue(key, value) { + return encodeURIComponent(key) + "=" + encodeURIComponent(value); + } + for (const selector in object) { + if (object.hasOwnProperty(selector)) { + const keyValuePairs = object[selector]; + let selectorString = selector; + let keyValueString = ""; + for (const key in keyValuePairs) { + if (keyValuePairs.hasOwnProperty(key)) { + const value = keyValuePairs[key]; + keyValueString += keyValueString.length === 0 ? "" : ","; + keyValueString += encodeKeyValue(key, value); + } + } + if (keyValueString.length > 0) { + selectorString += "(" + keyValueString + ")"; + hashString += hashString.length === 0 ? "" : ";"; + hashString += selectorString; + } + } + } + return addHashPrefix ? "#" + hashString : hashString; + } + + // test/cases/text/bracketed-key-value-hash.mjs + describe("parseBracketedKeyValueHash", () => { + it("should return an empty object for an empty string", () => { + const input = ""; + const expectedResult = {}; + expect(parseBracketedKeyValueHash(input)).to.deep.equal(expectedResult); + }); + it("should parse a single selector with one key-value pair", () => { + const input = "#selector1(key1=value1)"; + const expectedResult = { + selector1: { + key1: "value1" + } + }; + expect(parseBracketedKeyValueHash(input)).to.deep.equal(expectedResult); + }); + it("should parse multiple selectors with multiple key-value pairs", () => { + const input = "#selector1(key1=value1,key2=value2);selector2(key3=value3,key4=value4)"; + const expectedResult = { + selector1: { + key1: "value1", + key2: "value2" + }, + selector2: { + key3: "value3", + key4: "value4" + } + }; + expect(parseBracketedKeyValueHash(input)).to.deep.equal(expectedResult); + }); + it("should decode URL-encoded values", () => { + const input = "#selector1(key1=value1%2Cwith%20comma)"; + const expectedResult = { + selector1: { + key1: "value1,with comma" + } + }; + const result = parseBracketedKeyValueHash(input); + expect(result.selector1.key1).to.equal(expectedResult.selector1.key1); + }); + it("should handle input without a leading hash", () => { + const input = "selector1(key1=value1)"; + const expectedResult = { + selector1: { + key1: "value1" + } + }; + expect(parseBracketedKeyValueHash(input)).to.deep.equal(expectedResult); + }); + it("should return an empty object for invalid input", () => { + const input = "#selector1(key1=value1,key2"; + const expectedResult = {}; + expect(parseBracketedKeyValueHash(input)).to.deep.equal(expectedResult); + }); + it("should return an empty object for an empty input string", () => { + const hashString = ""; + const result = parseBracketedKeyValueHash(hashString); + expect(result).to.deep.equal({}); + }); + it("should return an empty object for an invalid input string", () => { + const hashString = "#invalid"; + const result = parseBracketedKeyValueHash(hashString); + expect(result).to.deep.equal({}); + }); + it("should parse a simple input string with one selector and one key-value pair", () => { + const hashString = "#selector(key=value)"; + const result = parseBracketedKeyValueHash(hashString); + expect(result).to.deep.equal({ selector: { key: "value" } }); + }); + it("should parse an input string with multiple selectors and key-value pairs", () => { + const hashString = "#selector1(key1=value1);selector2(key2=value2)"; + const result = parseBracketedKeyValueHash(hashString); + expect(result).to.deep.equal({ selector1: { key1: "value1" }, selector2: { key2: "value2" } }); + }); + it("should handle empty values", () => { + const hashString = "#selector(key1=,key2=)"; + const result = parseBracketedKeyValueHash(hashString); + expect(result).to.deep.equal({ selector: { key1: "", key2: "" } }); + }); + it("should handle percent-encoded values", () => { + const hashString = "#selector(key1=value%201,key2=value%2C2)"; + const result = parseBracketedKeyValueHash(hashString); + expect(result).to.deep.equal({ selector: { key1: "value 1", key2: "value,2" } }); + }); + it("should handle double-quoted values with commas", () => { + const hashString = '#selector(key1="value,1",key2="value,2")'; + const result = parseBracketedKeyValueHash(hashString); + expect(result).to.deep.equal({ selector: { key1: "value,1", key2: "value,2" } }); + }); + it("should ignore leading hash symbol (#)", () => { + const hashString = "selector(key=value)"; + const result = parseBracketedKeyValueHash(hashString); + expect(result).to.deep.equal({ selector: { key: "value" } }); + }); + it("should ignore leading and trailing white space", () => { + const hashString = " #selector(key=value) "; + const result = parseBracketedKeyValueHash(hashString); + expect(result).to.deep.equal({ selector: { key: "value" } }); + }); + it("should return an empty object if the input string ends prematurely", () => { + const hashString = "#selector(key=value"; + const result = parseBracketedKeyValueHash(hashString); + expect(result).to.deep.equal({}); + }); + it("should return an empty object if a selector is missing", () => { + const hashString = "#(key=value)"; + const result = parseBracketedKeyValueHash(hashString); + expect(result).to.deep.equal({}); + }); + it("should return an empty object if a key is missing", () => { + const hashString = "#selector(=value)"; + const result = parseBracketedKeyValueHash(hashString); + expect(result).to.deep.equal({}); + }); + it("should return an empty object ifa value is missing", () => { + const hashString = "#selector(key=)"; + const result = parseBracketedKeyValueHash(hashString); + expect(result).to.deep.equal({ + selector: { + key: "" + } + }); + }); + it("should return an empty object if there is no closing parenthesis for a selector", () => { + const hashString = "#selector(key=value;"; + const result = parseBracketedKeyValueHash(hashString); + expect(result).to.deep.equal({}); + }); + it("should return an empty object if there is no semicolon after a selector", () => { + const hashString = "#selector(key=value)selector2(key2=value2)"; + const result = parseBracketedKeyValueHash(hashString); + expect(result).to.deep.equal({ + selector: { + key: "value" + }, + selector2: { + key2: "value2" + } + }); + }); + describe("createBracketedKeyValueHash", () => { + it("should return an hash string for a simple object", () => { + const input = { + ".example": { + "color": "red", + "font-size": "14px" + }, + ".other": { + "background": "blue" + } + }; + const result = createBracketedKeyValueHash(input); + expect(result).to.deep.equal("#.example(color=red,font-size=14px);.other(background=blue)"); + }); + it("should return a url-encoded hash string for a simple object", () => { + const input = { + ".example": { + "color": 'r"ed', + "font-size": "14px" + }, + ".other": { + "background": "blue" + } + }; + const result = createBracketedKeyValueHash(input, true); + expect(result).to.deep.equal("#.example(color=r%22ed,font-size=14px);.other(background=blue)"); + }); + it("should return an empty string for an empty object", () => { + const input = {}; + const result = createBracketedKeyValueHash(input, false); + expect(result).to.deep.equal(""); + }); + it("should return an empty string for an empty object", () => { + const input = {}; + const result = createBracketedKeyValueHash(input, false); + expect(result).to.deep.equal(""); + }); + }); + }); + + // test/cases/math/random.mjs + describe("Math", function() { + let random2 = () => { + }; + before(function(done) { + let promises = []; + if (!globalThis["crypto"]) { + promises.push(Promise.resolve().then(() => (init_webcrypto_es(), webcrypto_es_exports)).then((m) => { + globalThis["crypto"] = new m.Crypto(); + return true; + })); + } + promises.push(Promise.resolve().then(() => (init_random(), random_exports)).then((m) => { + random2 = m.random; + return true; + })); + Promise.all(promises).then(() => { + done(); + }); + }); + describe(".random()", function() { + it("a greater b should throw error ", function() { + expect(() => random2(10, 2)).to.throw(Error); + }); + it(" should return a number ", function() { + let r = random2(); + expect(r).that.is.a("number"); + }); + it(" should return a number ", function() { + expect(() => random2(5, 6)).to.throw(Error); + }); + it(" should throw Error we cannot generate numbers larger than 53 bits.", function() { + expect(() => random2(-999999999, 1e20)).to.throw(Error); + }); + it(" should throw Error we cannot generate numbers larger than 53 bits.", function() { + [ + [1, 100], + [500, 600], + [100, 1e3] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + let r = random2(a2, b); + it(r + " should return value between " + a2 + " " + b, function() { + expect(r >= a2).to.be.true; + expect(r <= b).to.be.true; + }); + }); + [ + [1, 100], + [500, 600], + [100, 1e3] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + let sum = 0; + const rounds = 500; + for (let i = 0, max = rounds; i < max; i++) { + sum += random2(a2, b); + } + let avg = sum / rounds; + it(avg + " should between " + a2 + " " + b, function() { + expect(avg > a2).to.be.true; + expect(avg < b).to.be.true; + }); + }); + }); + }); + }); + + // test/cases/util/trimspaces.mjs + init_trimspaces(); + describe("trimSpaces", function() { + [ + // one stroke is escped by the javascript interpreter, the second stroke escapes the stroke + [" value ", "value"], + [" value\\ ", "value\\ "], + ["\\ value\\ ", "\\ value\\ "], + [" value ", "value"], + [" value ", "value"] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + it("trimSpaces(" + JSON.stringify(a2) + ") should return " + JSON.stringify(b), function() { + expect(trimSpaces(a2)).to.be.equal(b); + }); + }); + }); + + // source/util/processing.mjs + init_constants(); + init_base(); + init_global(); + init_is(); + init_queue(); + init_validate(); + var Callback = class { + /** + * + * @param {function} callback + * @param {int|undefined} time + * @throws {TypeError} value is not a function + * @throws {TypeError} value is not an integer + * @private + */ + constructor(callback, time) { + this[internalSymbol] = { + callback: validateFunction(callback), + time: validateInteger(time ?? 0) + }; + } + /** + * @private + * @param {*} data + * @return {Promise} + */ + run(data) { + const self2 = this; + return new Promise((resolve, reject) => { + getGlobalFunction("setTimeout")(() => { + try { + resolve(self2[internalSymbol].callback(data)); + } catch (e) { + reject(e); + } + }, self2[internalSymbol].time); + }); + } + }; + var Processing = class extends Base { + /** + * Create new Processing + * + * Functions and timeouts can be passed. If a timeout is passed, it applies to all further functions. + * In the example + * + * `timeout1, function1, function2, function3, timeout2, function4` + * + * the timeout1 is valid for the functions 1, 2 and 3 and the timeout2 for the function4. + * + * So the execution time is timeout1+timeout1+timeout1+timeout2 + * + * @throw {TypeError} the arguments must be either integer or functions + * @param {...(int|function)} args + */ + constructor(...args) { + super(); + this[internalSymbol] = { + queue: new Queue() + }; + let time = 0; + if (typeof args !== "object" || args[0] === null) { + throw new TypeError("the arguments must be either integer or functions"); + } + for (const [, arg] of Object.entries(args)) { + if (isInteger(arg) && arg >= 0) { + time = arg; + } else if (isFunction(arg)) { + this[internalSymbol].queue.add(new Callback(arg, time)); + } else { + throw new TypeError("the arguments must be either integer or functions"); + } + } + } + /** + * Adds a function with the desired timeout + * If no timeout is specified, the timeout of the previous function is used. + * + * @param {function} callback + * @param {int|undefined} time + * @throws {TypeError} value is not a function + * @throws {TypeError} value is not an integer + */ + add(callback, time) { + this[internalSymbol].queue.add(new Callback(callback, time)); + return this; + } + /** + * Executes the defined functions in order. + * + * @param {*} data + * @return {Promise} + */ + run(data) { + const self2 = this; + if (self2[internalSymbol].queue.isEmpty()) { + return Promise.resolve(data); + } + const callback = self2[internalSymbol].queue.poll(); + if (callback === null || callback === void 0) { + return Promise.resolve(data); + } + return callback.run(data).then((result) => { + return self2.run(result); + }); + } + }; + + // test/cases/util/processing.mjs + describe("Processing", function() { + describe("run instance", function() { + it("should run many function", function(done) { + let counter = 0; + let t = +/* @__PURE__ */ new Date(); + const desiredDelay = 200; + this.timeout(desiredDelay + 100); + new Processing((v) => { + counter++; + return v; + }, (v) => { + counter++; + return v; + }, function(v) { + counter++; + return v; + }, desiredDelay, function(v) { + counter++; + return v; + }).run("test").then((v) => { + try { + expect(counter).to.be.equal(4); + expect(v === "test").to.be.true; + expect(+/* @__PURE__ */ new Date() > t + desiredDelay + 1).to.be.true; + } catch (e) { + return done(e); + } + done(); + }); + }); + it("should run one function", function(done) { + let counter = 0; + new Processing((value) => { + counter++; + return value; + }).run("test").then((v) => { + try { + expect(v === "test").to.be.true; + } catch (e) { + return done(e); + } + done(); + }).catch((e) => done(e)); + }); + it("should run no function", function(done) { + let counter = 0; + new Processing().run("test").then((v) => { + try { + expect(v === "test").to.be.true; + } catch (e) { + return done(e); + } + done(); + }).catch((e) => done(e)); + }); + }); + describe("create new instance", function() { + it("should return a Processing object", function() { + expect(new Processing()).to.be.a("object"); + }); + it("should return a Processing object", function() { + expect(new Processing(function() { + })).to.be.a("object"); + }); + it("should throw TypeError", function() { + expect(() => new Processing(true)).to.throw(TypeError); + }); + it("should throw TypeError", function() { + expect(() => new Processing("test")).to.throw(TypeError); + }); + }); + }); + + // source/util/deadmansswitch.mjs + init_constants(); + init_base(); + init_is(); + init_validate(); + var DeadMansSwitch = class extends Base { + /** + * Create new dead man's switch + * + * @param {Integer} delay + * @param {function} callback + * @throw {TypeError} the arguments must be either integer or functions + * @throws {TypeError} value is not an integer + */ + constructor(delay, callback) { + super(); + init.call(this, validateInteger(delay), validateFunction(callback)); + } + /** + * + * @param {Integer|undefined} [delay] + */ + touch(delay) { + if (this[internalSymbol]["isAlreadyRun"] === true) { + throw new Error("has already run"); + } + if (isInteger(delay)) { + this[internalSymbol]["delay"] = delay; + } else if (delay !== void 0) { + throw new Error("unsupported argument"); + } + clearTimeout(this[internalSymbol]["timer"]); + initCallback.call(this); + return this; + } + }; + function initCallback() { + const self2 = this; + self2[internalSymbol]["timer"] = setTimeout(() => { + self2[internalSymbol]["isAlreadyRun"] = true; + self2[internalSymbol]["callback"](); + }, self2[internalSymbol]["delay"]); + } + function init(delay, callback) { + const self2 = this; + self2[internalSymbol] = { + callback, + delay, + isAlreadyRun: false, + timer: void 0 + }; + initCallback.call(self2); + } + + // test/cases/util/deadmansswitch.mjs + describe("DeadMansSwitch", function() { + describe("run instance", function() { + it("should run", function(done) { + const ms1 = Date.now(); + new DeadMansSwitch(100, () => { + const ms2 = Date.now(); + const diff2 = ms2 - ms1; + if (diff2 < 100) { + done("to short " + diff2); + return; + } + done(); + }); + }); + }); + describe("run instance and touch", function() { + it("should run", function(done) { + const ms1 = Date.now(); + const deadmansswitch = new DeadMansSwitch(100, () => { + const ms2 = Date.now(); + const diff2 = ms2 - ms1; + if (ms1 > ms2) { + done(new Error("timing error")); + return; + } + if (diff2 < 600) { + done(new Error("to short " + diff2)); + return; + } + done(); + }); + setTimeout(() => { + deadmansswitch.touch(); + setTimeout(() => { + deadmansswitch.touch(500); + }, 50); + }, 50); + }); + }); + }); + + // source/util/comparator.mjs + init_base(); + init_is(); + var Comparator = class extends Base { + /** + * create new comparator + * + * @param {Monster.Util~exampleCallback} [callback] Comparator callback + * @throw {TypeError} unsupported type + * @throw {TypeError} impractical comparison + */ + constructor(callback) { + super(); + if (isFunction(callback)) { + this.compare = callback; + } else if (callback !== void 0) { + throw new TypeError("unsupported type"); + } else { + this.compare = function(a2, b) { + if (typeof a2 !== typeof b) { + throw new TypeError("impractical comparison", "types/comparator.mjs"); + } + if (a2 === b) { + return 0; + } + return a2 < b ? -1 : 1; + }; + } + } + /** + * changes the order of the operators + * + * @return {Comparator} + */ + reverse() { + const original = this.compare; + this.compare = (a2, b) => original(b, a2); + return this; + } + /** + * Checks if two variables are equal. + * + * @param {*} a + * @param {*} b + * + * @return {boolean} + */ + equal(a2, b) { + return this.compare(a2, b) === 0; + } + /** + * Checks if variable `a` is greater than `b` + * + * @param {*} a + * @param {*} b + * + * @return {boolean} + */ + greaterThan(a2, b) { + return this.compare(a2, b) > 0; + } + /** + * Checks if variable `a` is greater than or equal to `b` + * + * @param {*} a + * @param {*} b + * + * @return {boolean} + */ + greaterThanOrEqual(a2, b) { + return this.greaterThan(a2, b) || this.equal(a2, b); + } + /** + * Checks if variable `a` is less than or equal to `b` + * + * @param {*} a + * @param {*} b + * + * @return {boolean} + */ + lessThanOrEqual(a2, b) { + return this.lessThan(a2, b) || this.equal(a2, b); + } + /** + * Checks if variable a is less than b + * + * @param {*} a + * @param {*} b + * + * @return {boolean} + */ + lessThan(a2, b) { + return this.compare(a2, b) < 0; + } + }; + + // test/cases/util/comparator.mjs + describe("Comparator", function() { + describe("create new instance", function() { + it("should return a comparator object", function() { + expect(new Comparator()).to.be.a("object"); + }); + it("should return a comparator object", function() { + expect(new Comparator(function() { + })).to.be.a("object"); + }); + it("should throw TypeError", function() { + expect(() => new Comparator(true)).to.throw(TypeError); + }); + it("should throw TypeError", function() { + expect(() => new Comparator("test")).to.throw(TypeError); + }); + }); + describe("equal()", function() { + [ + ["test1", "test", false], + [5.1, 5, false], + [5.1, 5.1, true], + [true, true, true], + [false, true, false], + [false, false, true], + [-4, -4, true] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + let c = data.shift(); + it("should compare " + a2 + " and " + b + " return " + c, function() { + expect(new Comparator().equal(a2, b)).is.equal(c); + }); + }); + }); + describe("equal()", function() { + [ + ["test1", true], + ["test1", 5], + ["test1", null], + ["test1", parseInt("a")], + [false, 5], + [void 0, null] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + it("should compare " + a2 + " and " + b + " throw TypeError", function() { + expect(() => new Comparator().equal(a2, b)).to.throw(TypeError); + }); + }); + }); + describe("greaterThan()", function() { + [ + ["test1", "test", true], + [5.1, 5, true], + [5.1, 5.1, false], + [true, true, false], + [false, true, false], + [false, false, false], + [-4, -4, false], + [-4, 4, false] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + let c = data.shift(); + it("should compare " + a2 + " and " + b + " return " + c, function() { + expect(new Comparator().greaterThan(a2, b)).is.equal(c); + }); + }); + }); + describe("reverse().greaterThan()", function() { + [ + ["test1", "test", true], + [5.1, 5, true], + [5.1, 5.1, false], + [true, true, false], + [false, true, false], + [false, false, false], + [-4, -4, false], + [-4, 4, false] + ].forEach(function(data) { + let b = data.shift(); + let a2 = data.shift(); + let c = data.shift(); + it("should compare " + a2 + " and " + b + " return " + c, function() { + expect(new Comparator().reverse().greaterThan(a2, b)).is.equal(c); + }); + }); + }); + describe("greaterThanOrEqual()", function() { + [ + ["test1", "test", true], + [5.1, 5, true], + [5.1, 5.1, true], + [true, true, true], + [false, true, false], + [false, false, true], + [-4, -4, true], + [-4, 4, false] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + let c = data.shift(); + it("should compare " + a2 + " and " + b + " return " + c, function() { + expect(new Comparator().greaterThanOrEqual(a2, b)).is.equal(c); + }); + }); + }); + describe("lessThan()", function() { + [ + ["test1", "test", true], + [5.1, 5, true], + [5.1, 5.1, false], + [true, true, false], + [false, true, false], + [false, false, false], + [-4, -4, false], + [-4, 4, false] + ].forEach(function(data) { + let b = data.shift(); + let a2 = data.shift(); + let c = data.shift(); + it("should compare " + a2 + " and " + b + " return " + c, function() { + expect(new Comparator().lessThan(a2, b)).is.equal(c); + }); + }); + }); + describe("documentations", function() { + it("should run ...", function() { + expect(new Comparator().lessThanOrEqual(2, 5)).to.be.true; + expect(new Comparator().greaterThan(4, 2)).to.be.true; + expect(new Comparator().equal(4, 4)).to.be.true; + expect(new Comparator().equal(4, 5)).to.be.false; + }); + it("should run with own function ...", function() { + expect(new Comparator(function(a2, b) { + if (a2.v === b.v) + return 0; + return a2.v < b.v ? -1 : 1; + }).equal({ v: 2 }, { v: 2 })).to.be.true; + }); + }); + describe("lessThanOrEqual()", function() { + [ + ["test1", "test", true], + [5.1, 5, true], + [5.1, 5.1, true], + [true, true, true], + [false, true, false], + [false, false, true], + [-4, -4, true], + [-4, 4, false] + ].forEach(function(data) { + let b = data.shift(); + let a2 = data.shift(); + let c = data.shift(); + it("should compare " + a2 + " and " + b + " return " + c, function() { + expect(new Comparator().lessThanOrEqual(a2, b)).is.equal(c); + }); + }); + }); + }); + + // source/util/freeze.mjs + init_validate(); + function deepFreeze(object) { + validateObject(object); + var propNames = Object.getOwnPropertyNames(object); + for (let name of propNames) { + let value = object[name]; + object[name] = value && typeof value === "object" ? deepFreeze(value) : value; + } + return Object.freeze(object); + } + + // test/cases/util/freeze.mjs + describe("deepFreeze", function() { + describe("deepFreeze an object", function() { + it("should freeze object", function() { + let obj1 = { + a: { + b: { + c: 1 + } + } + }; + let obj2 = { + a: { + b: { + c: 2 + } + } + }; + expect(obj2).to.not.eql(obj1); + obj1.a.b.c = 2; + expect(obj2).to.eql(obj1); + const obj1Freezed = deepFreeze(obj1); + expect(obj2).to.eql(obj1Freezed); + try { + obj1Freezed.a.b.c = 3; + } catch (_) { + } + expect(obj2).to.eql(obj1Freezed); + }); + }); + }); + + // test/cases/util/clone.mjs + init_clone(); + describe("Clone", function() { + class A { + constructor(b) { + this.b = b; + } + a() { + } + } + class B { + constructor(b) { + this.b = b; + } + a() { + } + getClone() { + return "DONE"; + } + } + describe(".clone(B) with getClone", function() { + it(".clone(B) should object", function() { + let b = new B({ + x: { + y: 1, + d: new A(1), + z: () => { + } + } + }); + let r = clone(b); + expect(b).to.be.instanceOf(B); + expect(r).not.equal(b); + expect(JSON.stringify(r)).equal(JSON.stringify("DONE")); + }); + }); + describe(".clone(A)", function() { + it(".clone(A) should object", function() { + let a2 = new A({ + x: { + y: 1, + d: new A(1), + z: () => { + } + } + }); + let b = clone(a2); + expect(a2).to.be.instanceOf(A); + expect(b).to.be.instanceOf(A); + expect(b).not.equal(a2); + expect(JSON.stringify(a2)).equal(JSON.stringify(b)); + }); + }); + if (typeof DocumentFragment === "object") { + describe(".clone(DocumentFragment)", function() { + it(".clone(DocumentFragment) should same DocumentFragment", function() { + let a2 = document.createDocumentFragment(); + let b = clone(a2); + expect(b).equal(a2); + }); + }); + } + describe(".clone(null)", function() { + it(".clone(null) should null", function() { + let a2 = null; + let b = clone(a2); + expect(b).equal(a2); + expect(b).to.be.null; + expect(a2).to.be.null; + }); + }); + describe(".clone(undefined)", function() { + it(".clone(undefined) should undefined", function() { + let a2 = void 0; + let b = clone(a2); + expect(a2 === b).to.be.true; + expect(typeof b === "undefined").to.be.true; + expect(a2 === void 0).to.be.true; + expect(b === void 0).to.be.true; + }); + }); + describe(".clone(object)", function() { + it(".clone({}) should object", function() { + let a2 = {}; + let b = clone(a2); + expect(typeof b === "object").to.be.true; + }); + it(".clone({x:1}) should object", function() { + let a2 = { x: 1 }; + let b = clone(a2); + expect(a2.x).is.equal(b.x); + }); + }); + describe(".clone(function)", function() { + it(".clone(function) should function", function() { + let a2 = () => { + }; + let b = clone(a2); + expect(typeof b === "function").to.be.true; + }); + }); + describe(".clone()", function() { + [ + ["test1", "string"], + [void 0, "undefined"], + [null, "object"], + // typeof null results in 'object'. https://2ality.com/2013/10/typeof-null.html + [() => { + }, "function"], + [2, "number"], + [false, "boolean"], + [true, "boolean"], + [4.5, "number"], + [{}, "object"], + [[1, 2, 3], "object"], + // array ist auch type object + [Symbol("foo"), "symbol"] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + it(".clone(" + JSON.stringify(a2) + ") should " + b + " ", function() { + let c = clone(a2); + expect(typeof c).is.equal(b); + }); + }); + }); + }); + + // source/logging/handler/console.mjs + init_global(); + + // source/logging/handler.mjs + init_base(); + init_validate(); + + // source/logging/logentry.mjs + init_base(); + init_validate(); + var LogEntry = class extends Base { + /** + * + * @param {Integer} loglevel + * @param {...*} args + */ + constructor(loglevel, ...args) { + super(); + validateInteger(loglevel); + this.loglevel = loglevel; + this.arguments = args; + } + /** + * + * @returns {integerr} + */ + getLogLevel() { + return this.loglevel; + } + /** + * + * @returns {array} + */ + getArguments() { + return this.arguments; + } + }; + + // source/logging/logger.mjs + init_base(); + init_validate(); + var ALL = 255; + var TRACE = 64; + var DEBUG = 32; + var INFO = 16; + var WARN = 8; + var ERROR = 4; + var FATAL = 2; + var OFF = 0; + var Logger = class extends Base { + /** + * + */ + constructor() { + super(); + this.handler = /* @__PURE__ */ new Set(); + } + /** + * + * @param {Handler} handler + * @returns {Logger} + * @throws {Error} the handler must be an instance of Handler + */ + addHandler(handler) { + validateObject(handler); + if (!(handler instanceof Handler)) { + throw new Error("the handler must be an instance of Handler"); + } + this.handler.add(handler); + return this; + } + /** + * + * @param {Handler} handler + * @returns {Logger} + * @throws {Error} the handler must be an instance of Handler + */ + removeHandler(handler) { + validateObject(handler); + if (!(handler instanceof Handler)) { + throw new Error("the handler must be an instance of Handler"); + } + this.handler.delete(handler); + return this; + } + /** + * log Trace message + * + * ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF (ALL = 0xff;OFF = 0x00; + * + * @param {*} arguments + * @returns {Logger} + * @since 1.5.0 + */ + logTrace(...args) { + if (typeof args !== "object" || args[0] === null) { + throw new Error("the first argument must be an object"); + } + triggerLog.apply(this, [TRACE, ...args]); + return this; + } + /** + * log Debug message + * + * ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF (ALL = 0xff;OFF = 0x00; + * + * @param {*} arguments + * @returns {Logger} + * @since 1.5.0 + */ + logDebug(...args) { + if (typeof args !== "object" || args[0] === null) { + throw new Error("the first argument must be an object"); + } + triggerLog.apply(this, [DEBUG, ...args]); + return this; + } + /** + * log Info message + * + * ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF (ALL = 0xff;OFF = 0x00; + * + * + * @param {*} arguments + * @returns {Logger} + * @since 1.5.0 + */ + logInfo(...args) { + if (typeof args !== "object" || args[0] === null) { + throw new Error("the first argument must be an object"); + } + triggerLog.apply(this, [INFO, ...args]); + return this; + } + /** + * log Warn message + * + * ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF (ALL = 0xff;OFF = 0x00; + * + * @param {*} arguments + * @returns {Logger} + * @since 1.5.0 + */ + logWarn(...args) { + if (typeof args !== "object" || args[0] === null) { + throw new Error("the first argument must be an object"); + } + triggerLog.apply(this, [WARN, ...args]); + return this; + } + /** + * log Error message + * + * ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF (ALL = 0xff;OFF = 0x00; + * + * @param {*} arguments + * @returns {Logger} + * @since 1.5.0 + */ + logError(...args) { + if (typeof args !== "object" || args[0] === null) { + throw new Error("the first argument must be an object"); + } + triggerLog.apply(this, [ERROR, ...args]); + return this; + } + /** + * log Fatal message + * + * ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF (ALL = 0xff;OFF = 0x00; + * + * @param {*} arguments + * @returns {Logger} + * @since 1.5.0 + */ + logFatal(...args) { + if (typeof args !== "object" || args[0] === null) { + throw new Error("the first argument must be an object"); + } + triggerLog.apply(this, [FATAL, ...args]); + return this; + } + /** + * Labels + * + * @param {integer} level + * @returns {string} + */ + getLabel(level) { + validateInteger(level); + if (level === ALL) + return "ALL"; + if (level === TRACE) + return "TRACE"; + if (level === DEBUG) + return "DEBUG"; + if (level === INFO) + return "INFO"; + if (level === WARN) + return "WARN"; + if (level === ERROR) + return "ERROR"; + if (level === FATAL) + return "FATAL"; + if (level === OFF) + return "OFF"; + return "unknown"; + } + /** + * Level + * + * @param {string} label + * @returns {integer} + */ + getLevel(label) { + validateString(label); + if (label === "ALL") + return ALL; + if (label === "TRACE") + return TRACE; + if (label === "DEBUG") + return DEBUG; + if (label === "INFO") + return INFO; + if (label === "WARN") + return WARN; + if (label === "ERROR") + return ERROR; + if (label === "FATAL") + return FATAL; + if (label === "OFF") + return OFF; + return 0; + } + }; + function triggerLog(loglevel, ...args) { + var logger = this; + for (let handler of logger.handler) { + handler.log(new LogEntry(loglevel, args)); + } + return logger; + } + + // source/logging/handler.mjs + var Handler = class extends Base { + constructor() { + super(); + this.loglevel = OFF; + } + /** + * This is the central log function. this method must be + * overwritten by derived handlers with their own logic. + * + * ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF (ALL = 0xff;OFF = 0x00; + * + * @param {LogEntry} entry + * @returns {boolean} + */ + log(entry) { + validateInstance(entry, LogEntry); + if (this.loglevel < entry.getLogLevel()) { + return false; + } + return true; + } + /** + * set loglevel + * + * @param {integer} loglevel + * @returns {Handler} + * @since 1.5.0 + */ + setLogLevel(loglevel) { + validateInteger(loglevel); + this.loglevel = loglevel; + return this; + } + /** + * get loglevel + * + * @returns {integer} + * @since 1.5.0 + */ + getLogLevel() { + return this.loglevel; + } + /** + * Set log level to All + * + * @returns {Handler} + * @since 1.5.0 + */ + setAll() { + this.setLogLevel(ALL); + return this; + } + /** + * Set log level to Trace + * + * @returns {Handler} + * @since 1.5.0 + */ + setTrace() { + this.setLogLevel(TRACE); + return this; + } + /** + * Set log level to Debug + * + * @returns {Handler} + * @since 1.5.0 + */ + setDebug() { + this.setLogLevel(DEBUG); + return this; + } + /** + * Set log level to Info + * + * @returns {Handler} + * @since 1.5.0 + */ + setInfo() { + this.setLogLevel(INFO); + return this; + } + /** + * Set log level to Warn + * + * @returns {undefined} + * @since 1.5.0 + */ + setWarn() { + this.setLogLevel(WARN); + return this; + } + /** + * Set log level to Error + * + * @returns {Handler} + * @since 1.5.0 + */ + setError() { + this.setLogLevel(ERROR); + return this; + } + /** + * Set log level to Fatal + * + * @returns {Handler} + * @since 1.5.0 + */ + setFatal() { + this.setLogLevel(FATAL); + return this; + } + /** + * Set log level to Off + * + * @returns {Handler} + * @since 1.5.0 + */ + setOff() { + this.setLogLevel(OFF); + return this; + } + }; + + // source/logging/handler/console.mjs + var ConsoleHandler = class extends Handler { + /** + * This is the central log function. this method must be + * overwritten by derived handlers with their own logic. + * + * ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF (ALL = 0xff;OFF = 0x00; + * + * @param {LogEntry} entry + * @returns {boolean} + */ + log(entry) { + if (super.log(entry)) { + let console2 = getGlobalObject("console"); + if (!console2) + return false; + if (!console2.error) + console2.error = console2.log; + if (!console2.warn) + console2.warn = console2.log; + switch (entry.getLogLevel()) { + case TRACE: + case DEBUG: + case INFO: + console2.log(entry.toString()); + break; + case FATAL: + case ERROR: + console2.error(entry.toString()); + break; + case WARN: + console2.warn(entry.toString()); + break; + default: + console2.log(entry.toString()); + break; + } + return true; + } + return false; + } + }; + + // test/cases/logging/handler/console.mjs + describe("Logging", function() { + describe("ConsoleHandler", function() { + it("should create ConsoleHandler", function() { + expect(new ConsoleHandler()).to.be.instanceof(ConsoleHandler); + }); + it("should log to console", function() { + expect(new ConsoleHandler().setAll().log(new LogEntry(FATAL, [1, true, "fatal"]))).to.be.true; + }); + it("should log to console", function() { + expect(new ConsoleHandler().setAll().log(new LogEntry(TRACE, [1, true, "trace"]))).to.be.true; + }); + it("should log to console", function() { + expect(new ConsoleHandler().setAll().log(new LogEntry(WARN, [1, true, "warn"]))).to.be.true; + }); + it("should log to console", function() { + expect(new ConsoleHandler().setAll().log(new LogEntry(DEBUG, [1, true, "debug"]))).to.be.true; + }); + it("should log to console", function() { + expect(new ConsoleHandler().setAll().log(new LogEntry(ERROR, [1, true, "error"]))).to.be.true; + }); + it("should log to console", function() { + expect(new ConsoleHandler().setAll().log(new LogEntry(INFO, [1, true, "info"]))).to.be.true; + }); + }); + }); + + // test/cases/logging/logger.mjs + describe("Logging", function() { + describe("new Logger", function() { + it("should return instanceof Logger", function() { + expect(new Logger()).to.instanceOf(Logger); + }); + }); + describe("Logger.logTrace()", function() { + it("should return instanceof Logger", function() { + expect(new Logger().logTrace("test")).to.instanceOf(Logger); + }); + }); + describe("Logger.logDebug()", function() { + it("should return instanceof Logger", function() { + expect(new Logger().logDebug("test")).to.instanceOf(Logger); + }); + }); + describe("Logger.logInfo()", function() { + it("should return instanceof Logger", function() { + expect(new Logger().logInfo("test")).to.instanceOf(Logger); + }); + }); + describe("Logger.logWarn()", function() { + it("should return instanceof Logger", function() { + expect(new Logger().logWarn("test")).to.instanceOf(Logger); + }); + }); + describe("Logger.logError()", function() { + it("should return instanceof Logger", function() { + expect(new Logger().logError("test")).to.instanceOf(Logger); + }); + }); + describe("Logger.logFatal()", function() { + it("should return instanceof Logger", function() { + expect(new Logger().logFatal("test")).to.instanceOf(Logger); + }); + }); + describe("Logger.getLevel()", function() { + [ + ["ALL", ALL], + ["TRACE", TRACE], + ["DEBUG", DEBUG], + ["INFO", INFO], + ["WARN", WARN], + ["ERROR", ERROR], + ["FATAL", FATAL], + ["OFF", OFF] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + it(a2 + " should return " + b, function() { + expect(new Logger().getLevel(a2)).to.be.equals(b); + }); + }); + }); + describe("Logger.getLabel()", function() { + [ + ["ALL", ALL], + ["TRACE", TRACE], + ["DEBUG", DEBUG], + ["INFO", INFO], + ["WARN", WARN], + ["ERROR", ERROR], + ["FATAL", FATAL], + ["OFF", OFF] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + it(a2 + " should return " + b, function() { + expect(new Logger().getLabel(b)).to.be.equals(a2); + }); + }); + }); + }); + + // test/cases/logging/handler.mjs + describe("Logging", function() { + describe("Handler.setLogLevel().getLogLevel()", function() { + [ + [ALL], + [TRACE], + [DEBUG], + [INFO], + [WARN], + [ERROR], + [FATAL], + [OFF] + ].forEach(function(data) { + let a2 = data.shift(); + it("the function should return the set value " + a2, function() { + expect(new Handler().setLogLevel(a2).getLogLevel()).to.be.equal(a2); + }); + }); + }); + describe("Handler.log()", function() { + it("should return instanceof Handler", function() { + expect(new Handler().log(new LogEntry(0, "test"))).to.be.true; + }); + }); + describe("Handler.log()", function() { + let handler; + class TestHandler extends Handler { + log(entry) { + super.log(entry); + } + } + beforeEach(function() { + let handler2 = new TestHandler(); + }); + it("should return instanceof Handler", function() { + expect(new Handler().log(new LogEntry(0, "test"))).to.be.true; + }); + }); + describe(".log() with loglevel", function() { + let TestHandler; + before(() => { + TestHandler = class extends Handler { + constructor() { + super(); + this.calls = 0; + } + log(loglevel) { + if (super.log(loglevel) === true) { + this.calls++; + return true; + } + return false; + } + }; + }); + [ + // ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF (ALL = 0xff;OFF = 0x00; + [ALL, 6], + [TRACE, 6], + [DEBUG, 5], + [INFO, 4], + [WARN, 3], + [ERROR, 2], + [FATAL, 1], + [OFF, 0] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + it("is.log(" + a2 + ") should log " + b, function() { + let handler = new TestHandler().setLogLevel(a2); + handler.log(new LogEntry(TRACE)); + handler.log(new LogEntry(DEBUG)); + handler.log(new LogEntry(INFO)); + handler.log(new LogEntry(WARN)); + handler.log(new LogEntry(ERROR)); + handler.log(new LogEntry(FATAL)); + expect(handler.calls).is.equal(b); + }); + }); + }); + describe("Handler.setLogLevel()", function() { + it("should return instanceof Handler", function() { + expect(new Handler().setLogLevel(ALL)).to.instanceOf(Handler); + }); + }); + describe("Handler.getLogLevel()", function() { + it("new logger should be 0", function() { + expect(new Handler().getLogLevel()).to.be.equal(OFF); + }); + }); + describe("Handler.setAll()", function() { + it(" should instanceof Handler", function() { + expect(new Handler().setAll()).to.instanceOf(Handler); + }); + }); + describe("Handler.setTrace()", function() { + it("new logger should instanceof Handler", function() { + expect(new Handler().setTrace()).to.instanceOf(Handler); + }); + }); + describe("Handler.setDebug()", function() { + it(" should instanceof Handler", function() { + expect(new Handler().setDebug()).to.instanceOf(Handler); + }); + }); + describe("Handler.setInfo()", function() { + it("should return instanceof Handler", function() { + expect(new Handler().setInfo()).to.instanceOf(Handler); + }); + }); + describe("Handler.setWarn()", function() { + it(" should instanceof Handler", function() { + expect(new Handler().setWarn()).to.instanceOf(Handler); + }); + }); + describe("Handler.setError()", function() { + it("should return instanceof Handler", function() { + expect(new Handler().setError()).to.instanceOf(Handler); + }); + }); + describe("Handler.setFatal()", function() { + it("should return instanceof Handler", function() { + expect(new Handler().setFatal()).to.instanceOf(Handler); + }); + }); + describe("Handler.setOff()", function() { + it("should return instanceof Handler", function() { + expect(new Handler().setOff()).to.instanceOf(Handler); + }); + }); + }); + + // test/cases/logging/logentry.mjs + describe("Log", function() { + describe("new Log", function() { + it("should return instanceof Log", function() { + expect(new LogEntry(1, "a", "b", "c")).to.instanceOf(LogEntry); + }); + }); + describe("Log.loglevel", function() { + let log; + beforeEach(function() { + log = new LogEntry(1, false, "test", 99, { a: true }); + }); + it("should return loglevel 1", function() { + expect(log.getLogLevel()).to.be.equal(1); + }); + it("should return arguments", function() { + expect(log.getArguments()).to.have.deep.members([false, "test", 99, { a: true }]); + }); + }); + }); + + // source/net/webconnect.mjs + init_constants(); + init_is(); + init_basewithoptions(); + + // source/types/observablequeue.mjs + init_queue(); + init_constants(); + init_observerlist(); + var ObservableQueue = class extends Queue { + /** + * + */ + constructor() { + super(); + this[internalSymbol] = { + observers: new ObserverList() + }; + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/types/observablequeue"); + } + /** + * Add a new element to the end of the queue. + * + * @param {*} value + * @returns {Queue} + */ + add(value) { + super.add(value); + this.notifyObservers(); + return this; + } + /** + * remove all entries + * + * @returns {Queue} + */ + clear() { + super.clear(); + this.notifyObservers(); + return this; + } + /** + * Attach a new observer + * + * @param {Observer} observer + * @returns {ProxyObserver} + */ + attachObserver(observer) { + this[internalSymbol].observers.attach(observer); + return this; + } + /** + * Detach a observer + * + * @param {Observer} observer + * @returns {ProxyObserver} + */ + detachObserver(observer) { + this[internalSymbol].observers.detach(observer); + return this; + } + /** + * Notify all observer + * + * @returns {Promise} + */ + notifyObservers() { + return this[internalSymbol].observers.notify(this); + } + /** + * @param {Observer} observer + * @returns {boolean} + */ + containsObserver(observer) { + return this[internalSymbol].observers.contains(observer); + } + }; + + // source/net/webconnect/message.mjs + init_base(); + init_validate(); + var dataSymbol = Symbol("@@data"); + var Message = class _Message extends Base { + /** + * @param {Object} data + * @throws {TypeError} value is not a object + */ + constructor(data) { + super(); + this[dataSymbol] = validateObject(data); + } + /** + * Returns the raw message. + * + * @returns {object} + */ + getData() { + return this[dataSymbol]; + } + /** + * @returns {*} + */ + toJSON() { + return this[dataSymbol]; + } + /** + * @param {string} json + * @returns {Message} + * @throws {TypeError} value is not a string + */ + static fromJSON(json) { + validateString(json); + return new _Message(JSON.parse(json)); + } + }; + + // source/net/webconnect.mjs + var receiveQueueSymbol = Symbol("receiveQueue"); + var sendQueueSymbol = Symbol("sendQueue"); + var connectionSymbol = Symbol("connection"); + var manualCloseSymbol = Symbol("manualClose"); + function connectServer(resolve, reject) { + const self2 = this; + const url = self2.getOption("url"); + if (!url) { + reject("No url defined for webconnect."); + return; + } + let promiseAllredyResolved = false; + let connectionTimeout = self2.getOption("connection.timeout"); + if (!isInteger(connectionTimeout) || connectionTimeout < 100) { + connectionTimeout = 5e3; + } + setTimeout(() => { + if (promiseAllredyResolved) { + return; + } + reject(new Error("Connection timeout")); + }, connectionTimeout); + let reconnectTimeout = self2.getOption("connection.reconnect.timeout"); + if (!isInteger(reconnectTimeout) || reconnectTimeout < 1e3) + reconnectTimeout = 1e3; + let reconnectAttempts = self2.getOption("connection.reconnect.attempts"); + if (!isInteger(reconnectAttempts) || reconnectAttempts < 1) + reconnectAttempts = 1; + let reconnectEnabled = self2.getOption("connection.reconnect.enabled"); + if (reconnectEnabled !== true) + reconnectEnabled = false; + self2[manualCloseSymbol] = false; + self2[connectionSymbol].reconnectCounter++; + if (self2[connectionSymbol].socket && self2[connectionSymbol].socket.readyState < 2) { + self2[connectionSymbol].socket.close(); + } + self2[connectionSymbol].socket = null; + self2[connectionSymbol].socket = new WebSocket(url); + self2[connectionSymbol].socket.onmessage = function(event) { + if (event.data instanceof Blob) { + const reader = new FileReader(); + reader.addEventListener("loadend", function() { + self2[receiveQueueSymbol].add(new Message(reader.result)); + }); + reader.readAsText(new Message(event.data)); + } else { + self2[receiveQueueSymbol].add(Message.fromJSON(event.data)); + } + }; + self2[connectionSymbol].socket.onopen = function() { + self2[connectionSymbol].reconnectCounter = 0; + if (typeof resolve === "function" && !promiseAllredyResolved) { + promiseAllredyResolved = true; + resolve(); + } + }; + self2[connectionSymbol].socket.close = function(event) { + if (self2[manualCloseSymbol]) { + self2[manualCloseSymbol] = false; + return; + } + if (reconnectEnabled && this[connectionSymbol].reconnectCounter < reconnectAttempts) { + setTimeout(() => { + self2.connect(); + }, reconnectTimeout * this[connectionSymbol].reconnectCounter); + } + }; + self2[connectionSymbol].socket.onerror = (error) => { + if (reconnectEnabled && self2[connectionSymbol].reconnectCounter < reconnectAttempts) { + setTimeout(() => { + self2.connect(); + }, reconnectTimeout * this[connectionSymbol].reconnectCounter); + } else { + if (typeof reject === "function" && !promiseAllredyResolved) { + promiseAllredyResolved = true; + reject(error); + } + } + }; + } + var WebConnect = class extends BaseWithOptions { + /** + * + * @param {Object} [options] options contains definitions for the webconnect. + */ + constructor(options) { + if (isString(options)) { + options = { url: options }; + } + super(options); + this[receiveQueueSymbol] = new ObservableQueue(); + this[sendQueueSymbol] = new ObservableQueue(); + this[connectionSymbol] = {}; + this[connectionSymbol].socket = null; + this[connectionSymbol].reconnectCounter = 0; + this[manualCloseSymbol] = false; + } + /** + * + * @returns {Promise} + */ + connect() { + const self2 = this; + return new Promise((resolve, reject) => { + connectServer.call(this, resolve, reject); + }); + } + /** + * @returns {boolean} + */ + isConnected() { + return this[connectionSymbol]?.socket?.readyState === 1; + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/net/webconnect"); + } + /** + * @property {string} url=undefined Defines the resource that you wish to fetch. + * @property {Object} connection + * @property {Object} connection.timeout=5000 Defines the timeout for the connection. + * @property {Number} connection.reconnect.timeout The timeout in milliseconds for the reconnect. + * @property {Number} connection.reconnect.attempts The maximum number of reconnects. + * @property {Bool} connection.reconnect.enabled If the reconnect is enabled. + */ + get defaults() { + return Object.assign({}, super.defaults, { + url: void 0, + connection: { + timeout: 5e3, + reconnect: { + timeout: 1e3, + attempts: 1, + enabled: false + } + } + }); + } + /** + * This method closes the connection. + * + * @param {Number} [code=1000] The close code. + * @param {String} [reason=""] The close reason. + * @returns {Promise} + * @see https://www.rfc-editor.org/rfc/rfc6455.html#section-7.4.1 + */ + close(statusCode, reason) { + if (!isInteger(statusCode) || statusCode < 1e3 || statusCode > 4999) { + statusCode = 1e3; + } + if (!isString(reason)) { + reason = ""; + } + return new Promise((resolve, reject) => { + try { + this[manualCloseSymbol] = true; + if (this[connectionSymbol].socket) { + this[connectionSymbol].socket.close(statusCode, reason); + } + } catch (error) { + reject(error); + } + resolve(); + }); + } + /** + * Polls the receive queue for new messages. + * + * @returns {Message} + */ + poll() { + return this[receiveQueueSymbol].poll(); + } + /** + * Are there any messages in the receive queue? + * + * @returns {boolean} + */ + dataReceived() { + return !this[receiveQueueSymbol].isEmpty(); + } + /** + * Get Message from the receive queue, but do not remove it. + * + * @returns {Object} + */ + peek() { + return this[receiveQueueSymbol].peek(); + } + /** + * Attach a new observer + * + * @param {Observer} observer + * @returns {ProxyObserver} + */ + attachObserver(observer) { + this[receiveQueueSymbol].attachObserver(observer); + return this; + } + /** + * Detach a observer + * + * @param {Observer} observer + * @returns {ProxyObserver} + */ + detachObserver(observer) { + this[receiveQueueSymbol].detachObserver(observer); + return this; + } + /** + * @param {Observer} observer + * @returns {boolean} + */ + containsObserver(observer) { + return this[receiveQueueSymbol].containsObserver(observer); + } + /** + * @param {Message|Object} message + * @return {Promise} + */ + send(message) { + const self2 = this; + return new Promise((resolve, reject) => { + if (self2[connectionSymbol].socket.readyState !== 1) { + reject("the socket is not ready"); + } + self2[connectionSymbol].socket.send(JSON.stringify(message)); + resolve(); + }); + } + }; + + // test/cases/net/webconnect.mjs + init_observer(); + + // test/util/websocket.mjs + init_global(); + function initWebSocket() { + if (typeof window === "object" && window["WebSocket"]) + return Promise.resolve(); + return import("ws").then((ws) => { + getGlobal().WebSocket = class extends ws["WebSocket"] { + constructor(url, protocols) { + super(url, protocols, { + handshakeTimeout: 1e3, + maxPayload: 1024 * 1024 * 1024 + }); + } + }; + }); + } + + // test/cases/net/webconnect.mjs + var testUrl = "wss://ws.postman-echo.com/raw"; + describe("Websocket", function() { + let ds = void 0; + before(function(done) { + initWebSocket().then(() => { + done(); + }).catch((e) => { + done(e); + }); + }); + afterEach(function(done) { + if (ds) { + ds.close(); + } + for (const sym of Object.getOwnPropertySymbols(ds)) { + if (sym.toString() === "Symbol(connection)") { + if (typeof ds[sym]?.socket?.terminate === "function") { + ds[sym]?.socket?.["terminate"](); + } + } + } + done(); + }); + it("should transform data", function(done) { + ds = new WebConnect({ + url: testUrl + }); + ds.connect().then(() => { + ds.attachObserver(new Observer(() => { + done(); + })); + ds.send({ + data: { + message: "Hello World" + } + }); + }).catch((e) => { + done(e); + }); + }); + it("should connect", function(done) { + ds = new WebConnect({ + url: testUrl, + reconnect: { + enabled: false + } + }); + ds.connect().then(() => { + done(); + }).catch((e) => { + done(e); + }); + }); + it("should send message", function(done) { + ds = new WebConnect({ + url: testUrl, + reconnect: { + enabled: false + } + }); + ds.connect().then(() => { + ds.attachObserver(new Observer(() => { + expect(ds.dataReceived()).to.be.true; + try { + const msg = ds.poll(); + expect(msg).to.be.instanceOf(Message); + const data = msg.getData(); + expect(data).to.be.deep.equal({ message: "Hello World" }); + } catch (e) { + done(e); + return; + } + done(); + })); + ds.send({ + message: "Hello World" + }); + }).catch((e) => { + done(e); + }); + }).timeout(1e4); + }); + + // test/cases/net/webconnect/message.mjs + describe("Message", function() { + it("construct withouth parameters should throw", function(done) { + try { + new Message(); + done(new Error("should throw")); + } catch (e) { + done(); + return; + } + }); + it("from json should ", function(done) { + const json = { + "id": "123", + "type": "test", + "data": { + "test": "test" + } + }; + const message = Message.fromJSON(JSON.stringify(json)); + const data = message.getData(); + expect(data.id).to.equal(json.id); + expect(data.type).to.equal(json.type); + expect(data.data).to.deep.equal(json.data); + done(); + }); + it("to json should", function(done) { + const obj = { + "id": "123", + "type": "test", + "data": { + "test": "test" + } + }; + const message = new Message(obj); + const data = JSON.stringify(message); + expect(data).to.equal('{"id":"123","type":"test","data":{"test":"test"}}'); + done(); + }); + }); + + // source/types/version.mjs + init_base(); + init_constants(); + var Version = class _Version extends Base { + /** + * + * @param major + * @param minor + * @param patch + * @throws {Error} major is not a number + * @throws {Error} minor is not a number + * @throws {Error} patch is not a number + */ + constructor(major, minor, patch) { + super(); + if (typeof major === "string" && minor === void 0 && patch === void 0) { + let parts = major.toString().split("."); + major = parseInt(parts[0] || 0); + minor = parseInt(parts[1] || 0); + patch = parseInt(parts[2] || 0); + } + if (major === void 0) { + throw new Error("major version is undefined"); + } + if (minor === void 0) { + minor = 0; + } + if (patch === void 0) { + patch = 0; + } + this.major = parseInt(major); + this.minor = parseInt(minor); + this.patch = parseInt(patch); + if (isNaN(this.major)) { + throw new Error("major is not a number"); + } + if (isNaN(this.minor)) { + throw new Error("minor is not a number"); + } + if (isNaN(this.patch)) { + throw new Error("patch is not a number"); + } + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/types/version"); + } + /** + * + * @returns {string} + */ + toString() { + return `${this.major}.${this.minor}.${this.patch}`; + } + /** + * returns 0 if equal, -1 if the object version is less and 1 if greater + * than the compared version + * + * @param {string|Version} version Version to compare + * @returns {number} + */ + compareTo(version3) { + if (version3 instanceof _Version) { + version3 = version3.toString(); + } + if (typeof version3 !== "string") { + throw new Error("type exception"); + } + if (version3 === this.toString()) { + return 0; + } + let a2 = [this.major, this.minor, this.patch]; + let b = version3.split("."); + let len = Math.max(a2.length, b.length); + for (let i = 0; i < len; i += 1) { + if (a2[i] && !b[i] && parseInt(a2[i]) > 0 || parseInt(a2[i]) > parseInt(b[i])) { + return 1; + } else if (b[i] && !a2[i] && parseInt(b[i]) > 0 || parseInt(a2[i]) < parseInt(b[i])) { + return -1; + } + } + return 0; + } + }; + var monsterVersion; + function getMonsterVersion() { + if (monsterVersion instanceof Version) { + return monsterVersion; + } + monsterVersion = new Version("3.51.4"); + return monsterVersion; + } + + // test/cases/monster.mjs + describe("Monster", function() { + describe(".getMonsterVersion()", function() { + let monsterVersion2; + monsterVersion2 = new Version("3.51.4"); + let m = getMonsterVersion(); + it("should " + monsterVersion2 + " is " + m, function() { + expect(m.compareTo(monsterVersion2)).is.equal(0); + }); + }); + }); + + // source/dom/dimension.mjs + init_util(); + init_validate(); + var CURRENT_DEVICE_DPI = function() { + let i = 0; + for (i = 56; i < 2e3; i++) { + if (getWindow().matchMedia(`(max-resolution: ${i}dpi)`).matches === true) { + return i; + } + } + return i; + }; + function getDeviceDPI() { + if (typeof CURRENT_DEVICE_DPI === "function") { + CURRENT_DEVICE_DPI = CURRENT_DEVICE_DPI(); + } + return getWindow().devicePixelRatio * CURRENT_DEVICE_DPI; + } + function convertToPixels(value, parentElement = document.documentElement, fontSizeElement = document.documentElement) { + validateString(value); + const regex = /^(-?[\d.]+)(.*)$/; + const matchResult = value.match(regex); + if (!matchResult) { + throw new Error(`Invalid value format: ${value}`); + } + const [, num, unit] = matchResult; + const number = parseFloat(num); + const dpi = getDeviceDPI(); + if (unit === "px") { + return number; + } else if (unit === "em") { + const fontSize = parseFloat(window.getComputedStyle(fontSizeElement).fontSize); + return number * fontSize; + } else if (unit === "rem") { + const rootFontSize = parseFloat(window.getComputedStyle(parentElement).fontSize); + return number * rootFontSize; + } else if (unit === "%") { + const parentWidth = parseFloat(window.getComputedStyle(parentElement).width); + return number * parentWidth / 100; + } else if (unit === "in") { + return number * dpi; + } else if (unit === "cm") { + return number * dpi / 2.54; + } else if (unit === "mm") { + return number * dpi / 25.4; + } else if (unit === "pt") { + return number * dpi / 72; + } else if (unit === "pc") { + return number * dpi / 6; + } else { + throw new Error(`Unsupported unit: ${unit}`); + } + } + + // test/cases/dom/dimension.mjs + init_util(); + + // test/util/jsdom.mjs + init_extend(); + init_global(); + var isBrowser = new Function("try {return this===window;}catch(e){ return false;}"); + var isNode = new Function("try {return this===global;}catch(e){return false;}"); + var JSDOMExport = null; + function initJSDOM(options) { + if (typeof window === "object" && window["DOMParser"]) + return Promise.resolve(); + const g = getGlobal(); + options = extend({}, { + pretendToBeVisual: true, + contentType: "text/html", + includeNodeLocations: true, + storageQuota: 1e7, + runScripts: "dangerously", + resources: "usable" + }, options || {}); + return import("jsdom").then(({ JSDOM }) => { + JSDOMExport = JSDOM; + const { window: window2 } = new JSDOM(`<html> +<head> +</head> +<body> +<div id="mocks"></div> +</body>`, options); + g["window"] = window2; + return new Promise( + (resolve) => window2.addEventListener("load", () => { + [ + "self", + "HTMLCollection", + "NodeList", + "ElementInternals", + "HTMLDocument", + "HTMLFormElement", + "HTMLInputElement", + "HTMLSelectElement", + "HTMLTextAreaElement", + "document", + "Document", + "Node", + "ShadowRoot", + "EventTarget", + "Event", + "CustomEvent", + "Element", + "HTMLElement", + "HTMLDivElement", + "customElements", + "DocumentFragment", + "DOMParser", + "KeyboardEvent", + "CSSStyleSheet", + "HTMLScriptElement", + "MutationObserver", + "HTMLTemplateElement", + "XMLSerializer", + "NodeFilter", + "navigator", + "InputEvent", + "Blob", + "CustomEvent" + ].forEach((key) => { + g[key] = window2[key]; + }); + resolve(); + }) + ); + }); + } + + // test/cases/dom/dimension.mjs + init_global(); + + // source/util/runtime.mjs + var ENV_AWS_LAMBDA = "aws-lambda"; + var ENV_GOOGLE_FUNCTIONS = "google-functions"; + var ENV_ELECTRON = "electron"; + var ENV_NODE = "node"; + var ENV_BROWSER = "browser"; + var ENV_WEB_WORKER = "web-worker"; + var ENV_DENO = "deno"; + var ENV_UNKNOWN = "unknown"; + function detectRuntimeEnvironment() { + if (typeof process !== "undefined" && process.env != null && process.env.AWS_LAMBDA_FUNCTION_NAME) { + return ENV_AWS_LAMBDA; + } + if (typeof process !== "undefined" && process.env != null && process.env.FUNCTION_NAME) { + return ENV_GOOGLE_FUNCTIONS; + } + if (typeof process !== "undefined" && process.versions != null && process.versions.node != null) { + if (process.versions.electron != null) { + return ENV_ELECTRON; + } + return ENV_NODE; + } + if (typeof window !== "undefined" && typeof window.document !== "undefined" && typeof navigator !== "undefined" && typeof navigator.userAgent === "string") { + if (typeof self === "object" && typeof importScripts === "function") { + return ENV_WEB_WORKER; + } + return ENV_BROWSER; + } + if (typeof Deno !== "undefined") { + return ENV_DENO; + } + return ENV_UNKNOWN; + } + + // test/cases/dom/dimension.mjs + function getMockWindow(dpi) { + if (detectRuntimeEnvironment() === "browser") { + return getWindow(); + } + const dom = new JSDOMExport("", { + pretendToBeVisual: true, + resources: "usable" + }); + dom.window.matchMedia = (query) => { + const dpiRegex = /\(max-resolution: (\d+)dpi\)/; + const match = query.match(dpiRegex); + if (match) { + const maxDpi = parseInt(match[1], 10); + return { matches: dpi <= maxDpi }; + } + return { matches: false }; + }; + return dom.window; + } + describe("dimension", () => { + let currentEnvironment; + before(function(done) { + initJSDOM().then(() => { + done(); + }); + }); + beforeEach(() => { + const testDpi = 96; + const testWindow = getMockWindow(testDpi); + getGlobal().window = testWindow; + }); + afterEach(() => { + delete getGlobal().window; + }); + describe("convertToPixels", () => { + it("should correctly convert px values", () => { + const result = convertToPixels("100px"); + expect(result).to.equal(100); + }); + it("should throw an error when the input value has an invalid format", () => { + const invalidValue = "invalid_value"; + const errorFn = () => { + convertToPixels(invalidValue); + }; + expect(errorFn).to.throw(Error, `Invalid value format: ${invalidValue}`); + }); + it("should handle negative values correctly", () => { + const negativeValue = "-10px"; + const expectedResult = -10; + const result = convertToPixels(negativeValue); + expect(result).to.equal(expectedResult); + }); + it("should correctly convert em values", () => { + const testElement = document.createElement("div"); + testElement.style.fontSize = "16px"; + document.body.appendChild(testElement); + const result = convertToPixels("2em", testElement, testElement); + expect(result).to.equal(32); + document.body.removeChild(testElement); + }); + it("should correctly convert rem values", () => { + const testElement = document.createElement("div"); + testElement.style.fontSize = "16px"; + document.documentElement.appendChild(testElement); + const result = convertToPixels("2rem", testElement); + expect(result).to.equal(32); + document.documentElement.removeChild(testElement); + }); + it("should correctly convert percentage values", () => { + const testElement = document.createElement("div"); + testElement.style.width = "500px"; + document.body.appendChild(testElement); + const result = convertToPixels("50%", testElement); + expect(result).to.equal(250); + document.body.removeChild(testElement); + }); + it("should throw an error for unsupported units", () => { + expect(() => convertToPixels("10unsupportedUnit")).to.throw("Unsupported unit: unsupportedUnit"); + }); + }); + describe("getDeviceDPI", () => { + it("should return the correct device DPI", () => { + const testDpi = 96; + const testWindow = getMockWindow(testDpi); + getGlobal().window = testWindow; + const deviceDpi = getDeviceDPI(); + expect(deviceDpi).to.equal(testDpi * testWindow.devicePixelRatio); + delete getGlobal().window; + }); + it("should cache the result and return the same value", () => { + const testDpi = 96; + const testWindow = getMockWindow(testDpi); + getGlobal().window = testWindow; + const deviceDpi1 = getDeviceDPI(); + const deviceDpi2 = getDeviceDPI(); + expect(deviceDpi1).to.equal(deviceDpi2); + delete getGlobal().window; + }); + }); + }); + + // source/dom/resource/link/stylesheet.mjs + init_extend(); + + // source/dom/resource/link.mjs + init_extend(); + init_constants2(); + init_resource(); + init_constants(); + var Link = class extends Resource { + /** + * @property {string} as {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-as} + * @property {string} crossOrigin=anonymous {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-crossorigin} + * @property {boolean} disabled + * @property {string} href {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-href} + * @property {string} hreflang {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-hreflang} + * @property {string} imagesizes {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-imagesizes} + * @property {string} imagesrcset {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-imagesrcset} + * @property {string} integrity {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-integrity} + * @property {string} media {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-media} + * @property {string} prefetch {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-prefetch} + * @property {string} referrerpolicy {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-referrerpolicy} + * @property {string} rel {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-rel} + * @property {string} type {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-type} + * @property {string} sizes {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-sizes} + * @property {string} nonce {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-nonce} + */ + get defaults() { + return extend({}, super.defaults, { + as: void 0, + crossOrigin: "anonymous", + disabled: void 0, + href: void 0, + hreflang: void 0, + imagesizes: void 0, + imagesrcset: void 0, + integrity: void 0, + media: void 0, + prefetch: void 0, + referrerpolicy: void 0, + rel: void 0, + sizes: void 0, + type: void 0, + nonce: void 0 + }); + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/dom/resource/link"); + } + /** + * + * @return {Monster.DOM.Resource.Link} + */ + create() { + createElement.call(this); + return this; + } + /** + * @return {string} + */ + static getURLAttribute() { + return ATTRIBUTE_HREF; + } + }; + function createElement() { + const self2 = this; + const document2 = self2.getOption(KEY_DOCUMENT); + self2[referenceSymbol] = document2.createElement(TAG_LINK); + for (let key of [ + "as", + "crossOrigin", + "disabled", + "href", + "hreflang", + "imagesizes", + "imagesrcset", + "integrity", + "media", + "prefetch", + "referrerpolicy", + "sizes", + "rel", + "type", + ATTRIBUTE_HREF, + ATTRIBUTE_ID, + ATTRIBUTE_CLASS, + ATTRIBUTE_TITLE, + ATTRIBUTE_NONCE + ]) { + if (self2.getOption(key) !== void 0) { + self2[referenceSymbol][key] = self2.getOption(key); + } + } + return self2; + } + + // source/dom/resource/link/stylesheet.mjs + init_constants(); + var Stylesheet = class extends Link { + /** + * @property {string} rel {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-rel} + */ + get defaults() { + return extend({}, super.defaults, { + rel: "stylesheet" + }); + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/dom/resource/link/stylesheet"); + } + }; + + // test/cases/dom/resource/link/stylesheet.mjs + init_dataurl(); + init_id(); + + // test/util/chai-dom.mjs + function chaiDom(chai2, utils) { + let flag = utils.flag, elToString = function(el) { + let desc; + if (isNodeList(el)) { + if (el.length === 0) + return "empty NodeList"; + desc = Array.prototype.slice.call(el, 0, 5).map(elToString).join(", "); + return el.length > 5 ? desc + "... (+" + (el.length - 5) + " more)" : desc; + } + if (!isHTMLElement(el)) { + return String(el); + } + desc = el.tagName.toLowerCase(); + if (el.id) { + desc += "#" + el.id; + } + if (el.className) { + desc += "." + String(el.className).replace(/\s+/g, "."); + } + Array.prototype.forEach.call(el.attributes, function(attr) { + if (attr.name !== "class" && attr.name !== "id") { + desc += "[" + attr.name + (attr.value ? '="' + attr.value + '"]' : "]"); + } + }); + return desc; + }, attrAssert = function(name, val) { + var el = flag(this, "object"), actual = el.getAttribute(name); + if (!flag(this, "negate") || void 0 === val) { + this.assert( + !!el.attributes[name], + "expected " + elToString(el) + " to have an attribute #{exp}", + "expected " + elToString(el) + " not to have an attribute #{exp}", + name + ); + } + if (void 0 !== val) { + this.assert( + val === actual, + "expected " + elToString(el) + " to have an attribute " + utils.inspect(name) + " with the value #{exp}, but the value was #{act}", + "expected " + elToString(el) + " not to have an attribute " + utils.inspect(name) + " with the value #{act}", + val, + actual + ); + } + flag(this, "object", actual); + }, isHTMLElement = function(el) { + return el.nodeType === 1; + }, isNodeList = function(obj) { + return Object.prototype.toString.call(obj) === "[object NodeList]"; + }; + utils.elToString = elToString; + chai2.Assertion.addMethod("attr", attrAssert); + chai2.Assertion.addMethod("attribute", attrAssert); + chai2.Assertion.addMethod("class", function(className) { + var el = flag(this, "object"); + this.assert( + el.classList.contains(className), + "expected " + elToString(el) + " to have class #{exp}", + "expected " + elToString(el) + " not to have class #{exp}", + className + ); + }); + chai2.Assertion.addMethod("id", function(id) { + var el = flag(this, "object"); + this.assert( + el.id == id, + "expected " + elToString(el) + " to have id #{exp}", + "expected " + elToString(el) + " not to have id #{exp}", + id + ); + }); + chai2.Assertion.addMethod("html", function(html) { + var el = flag(this, "object"), actual = flag(this, "object").innerHTML; + if (flag(this, "contains")) { + this.assert( + actual.indexOf(html) >= 0, + "expected #{act} to contain HTML #{exp}", + "expected #{act} not to contain HTML #{exp}", + html, + actual + ); + } else { + this.assert( + actual === html, + "expected " + elToString(el) + " to have HTML #{exp}, but the HTML was #{act}", + "expected " + elToString(el) + " not to have HTML #{exp}", + html, + actual + ); + } + }); + chai2.Assertion.addChainableMethod("trimmed", null, function() { + flag(this, "trim-text", true); + }); + chai2.Assertion.addMethod("text", function(text) { + var obj = flag(this, "object"), contains = flag(this, "contains"), trim = flag(this, "trim-text"), actual, result; + if (isNodeList(obj)) { + actual = Array.prototype.map.call(obj, function(el) { + return trim ? el.textContent.trim() : el.textContent; + }); + if (Array.isArray(text)) { + result = contains ? text[flag(this, "negate") ? "some" : "every"](function(t) { + return Array.prototype.some.call(obj, function(el) { + return (trim ? el.textContent.trim() : el.textContent) === t; + }); + }) : utils.eql(actual, text); + actual = actual.join(); + text = text.join(); + } else { + actual = actual.join(""); + result = contains ? actual.indexOf(text) >= 0 : actual === text; + } + } else { + actual = trim ? obj.textContent.trim() : obj.textContent; + result = contains ? actual.indexOf(text) >= 0 : actual === text; + } + var objDesc = elToString(obj), textMsg = trim ? "trimmed text" : "text"; + if (contains) { + this.assert( + result, + "expected " + objDesc + " to contain #{exp}, but the " + textMsg + " was #{act}", + "expected " + objDesc + " not to contain #{exp}, but the " + textMsg + " was #{act}", + text, + actual + ); + } else { + this.assert( + result, + "expected " + objDesc + " to have " + textMsg + " #{exp}, but the " + textMsg + " was #{act}", + "expected " + objDesc + " not to have " + textMsg + " #{exp}", + text, + actual + ); + } + }); + chai2.Assertion.addMethod("value", function(value) { + var el = flag(this, "object"), actual = flag(this, "object").value; + this.assert( + flag(this, "object").value === value, + "expected " + elToString(el) + " to have value #{exp}, but the value was #{act}", + "expected " + elToString(el) + " not to have value #{exp}", + value, + actual + ); + }); + chai2.Assertion.overwriteProperty("exist", function(_super) { + return function() { + var obj = flag(this, "object"); + if (isNodeList(obj)) { + this.assert( + obj.length > 0, + "expected an empty NodeList to have nodes", + "expected " + elToString(obj) + " to not exist" + ); + } else { + _super.apply(this, arguments); + } + }; + }); + chai2.Assertion.overwriteProperty("empty", function(_super) { + return function() { + var obj = flag(this, "object"); + if (isHTMLElement(obj)) { + this.assert( + obj.children.length === 0, + "expected " + elToString(obj) + " to be empty", + "expected " + elToString(obj) + " to not be empty" + ); + } else if (isNodeList(obj)) { + this.assert( + obj.length === 0, + "expected " + elToString(obj) + " to be empty", + "expected " + elToString(obj) + " to not be empty" + ); + } else { + _super.apply(this, arguments); + } + }; + }); + chai2.Assertion.overwriteChainableMethod( + "length", + function(_super) { + return function(length) { + var obj = flag(this, "object"); + if (isNodeList(obj) || isHTMLElement(obj)) { + var actualLength = obj.children ? obj.children.length : obj.length; + this.assert( + actualLength === length, + "expected " + elToString(obj) + " to have #{exp} children but it had #{act} children", + "expected " + elToString(obj) + " to not have #{exp} children", + length, + actualLength + ); + } else { + _super.apply(this, arguments); + } + }; + }, + function(_super) { + return function() { + _super.call(this); + }; + } + ); + chai2.Assertion.overwriteMethod("match", function(_super) { + return function(selector) { + var obj = flag(this, "object"); + if (isHTMLElement(obj)) { + this.assert( + obj.matches(selector), + "expected " + elToString(obj) + " to match #{exp}", + "expected " + elToString(obj) + " to not match #{exp}", + selector + ); + } else if (isNodeList(obj)) { + this.assert( + !!obj.length && Array.prototype.every.call(obj, function(el) { + return el.matches(selector); + }), + "expected " + elToString(obj) + " to match #{exp}", + "expected " + elToString(obj) + " to not match #{exp}", + selector + ); + } else { + _super.apply(this, arguments); + } + }; + }); + chai2.Assertion.overwriteChainableMethod( + "contain", + function(_super) { + return function(subitem) { + var obj = flag(this, "object"); + if (isHTMLElement(obj)) { + if (typeof subitem === "string") { + this.assert( + !!obj.querySelector(subitem), + "expected " + elToString(obj) + " to contain #{exp}", + "expected " + elToString(obj) + " to not contain #{exp}", + subitem + ); + } else { + this.assert( + obj.contains(subitem), + "expected " + elToString(obj) + " to contain " + elToString(subitem), + "expected " + elToString(obj) + " to not contain " + elToString(subitem) + ); + } + } else { + _super.apply(this, arguments); + } + }; + }, + function(_super) { + return function() { + _super.call(this); + }; + } + ); + chai2.Assertion.addMethod("descendant", function(subitem) { + var obj = flag(this, "object"), actual = subitem; + if (typeof subitem === "string") { + actual = obj.querySelector(subitem); + this.assert( + !!actual, + "expected " + elToString(obj) + " to have descendant #{exp}", + "expected " + elToString(obj) + " to not have descendant #{exp}", + subitem + ); + } else { + this.assert( + obj.contains(subitem), + "expected " + elToString(obj) + " to contain " + elToString(subitem), + "expected " + elToString(obj) + " to not contain " + elToString(subitem) + ); + } + flag(this, "object", actual); + }); + chai2.Assertion.addMethod("descendants", function(selector) { + var obj = flag(this, "object"), actual = obj.querySelectorAll(selector); + this.assert( + !!actual.length, + "expected " + elToString(obj) + " to have descendants #{exp}", + "expected " + elToString(obj) + " to not have descendants #{exp}", + selector + ); + flag(this, "object", actual); + }); + chai2.Assertion.addProperty("displayed", function() { + var el = flag(this, "object"), actual = document.body.contains(el) ? window.getComputedStyle(el).display : el.style.display; + this.assert( + actual !== "none", + "expected " + elToString(el) + " to be displayed, but it was not", + "expected " + elToString(el) + " to not be displayed, but it was as " + actual, + actual + ); + }); + chai2.Assertion.addProperty("visible", function() { + var el = flag(this, "object"), actual = document.body.contains(el) ? window.getComputedStyle(el).visibility : el.style.visibility; + this.assert( + actual !== "hidden" && actual !== "collapse", + "expected " + elToString(el) + " to be visible, but it was " + (actual === "hidden" ? "hidden" : "collapsed"), + "expected " + elToString(el) + " to not be visible, but it was", + actual + ); + }); + } + + // test/util/cleanupdom.mjs + var addedNodes; + var mutationobserver; + function init2() { + addedNodes = []; + mutationobserver = new MutationObserver(function(mutations) { + mutations.forEach(function(mutation) { + if (mutation.type === "childList" && mutation.removedNodes) { + mutation.addedNodes.forEach((n) => { + if (n instanceof HTMLElement) { + addedNodes.push(n); + } + }); + } + }); + }); + } + function initMutationObserverForTesting() { + if (mutationobserver === void 0) { + init2(); + } + mutationobserver.observe(document.querySelector("head"), { childList: true }); + } + function cleanupDOMFromTesting() { + mutationobserver.disconnect(); + for (const n of addedNodes) { + n.remove(); + } + } + + // test/cases/dom/resource/link/stylesheet.mjs + var expect2 = chai_default.expect; + chai_default.use(chaiDom); + describe("Stylesheet", function() { + before(function(done) { + initJSDOM({ + runScripts: "dangerously", + resources: "usable" + }).then(() => { + done(); + }).catch((e) => done(e)); + }); + beforeEach(() => { + initMutationObserverForTesting(); + }); + afterEach(() => { + cleanupDOMFromTesting(); + }); + describe("Stylesheet()", function() { + it("connect().available()", function(done) { + const stylesheet = new Stylesheet({ + href: new DataUrl("", "text/css").toString() + }); + stylesheet.connect().available().then(() => { + const id = stylesheet.getOption("id"); + done(); + }).catch((e) => done(e)); + }); + }); + describe("External Stylesheet", () => { + let id = new ID("Stylesheet").toString(); + let stylesheet, url = "https://monsterjs.org/assets/empty.css?" + id; + beforeEach(() => { + stylesheet = new Stylesheet({ + href: url, + id + }); + }); + it("append and remove Stylesheet ", (done) => { + expect2(stylesheet.isConnected()).to.be.false; + stylesheet.connect().available().then(() => { + expect2(stylesheet.isConnected()).to.be.true; + expect2(document.querySelector('[href="' + url + '"]')).to.exist; + document.getElementById(id).remove(); + expect2(stylesheet.isConnected()).to.be.false; + expect2(document.querySelector('[href="' + url + '"]')).not.to.exist; + stylesheet.connect().available().then(() => { + expect2(stylesheet.isConnected()).to.be.true; + expect2(document.querySelector('[href="' + url + '"]')).to.exist; + document.getElementById(id).remove(); + expect2(document.querySelector('[href="' + url + '"]')).not.to.exist; + expect2(stylesheet.isConnected()).to.be.false; + done(); + }).catch((e) => done(e)); + }).catch((e) => done(e)); + }); + }); + }); + + // test/cases/dom/resource/link.mjs + init_dataurl(); + init_id(); + var expect3 = chai_default.expect; + chai_default.use(chaiDom); + describe("Link", function() { + before(function(done) { + initJSDOM().then(() => { + done(); + }); + }); + beforeEach(() => { + initMutationObserverForTesting(); + }); + afterEach(() => { + cleanupDOMFromTesting(); + }); + describe("Link()", function() { + this.timeout(5e3); + it("connect().available()", function(done) { + const link = new Link({ + href: new DataUrl("", "text/css").toString(), + rel: "stylesheet" + }); + link.connect().available().then(() => { + done(); + }).catch((e) => done(e)); + }); + }); + describe("External Link", () => { + this.timeout(5e3); + let id = new ID("link").toString(); + let link, url = "https://monsterjs.org/assets/empty.css?" + id; + beforeEach(() => { + link = new Link({ + href: url, + id, + rel: "stylesheet" + }); + }); + it("append and remove Link ", (done) => { + expect3(link.isConnected()).to.be.false; + link.connect().available().then(() => { + expect3(link.isConnected()).to.be.true; + expect3(document.querySelector('[href="' + url + '"]')).to.exist; + document.getElementById(id).remove(); + expect3(link.isConnected()).to.be.false; + expect3(document.querySelector('[href="' + url + '"]')).not.to.exist; + link.connect().available().then(() => { + expect3(link.isConnected()).to.be.true; + expect3(document.querySelector('[href="' + url + '"]')).to.exist; + document.getElementById(id).remove(); + expect3(document.querySelector('[href="' + url + '"]')).not.to.exist; + expect3(link.isConnected()).to.be.false; + done(); + }).catch((e) => done(e)); + }).catch((e) => done(e)); + }); + }); + }); + + // source/dom/resource/script.mjs + init_extend(); + init_constants2(); + init_resource(); + init_constants(); + var Script = class extends Resource { + /** + * @property {boolean} async=true {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-async} + * @property {string} crossOrigin=anonymous {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-crossorigin} + * @property {boolean} defer=false {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-defer} + * @property {string} integrity {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-integrity} + * @property {boolean} nomodule {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-nomodule} + * @property {string} nonce {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-nonce} + * @property {string} referrerpolicy {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-referrerpolicy} + * @property {string} type {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-type} + */ + get defaults() { + return extend({}, super.defaults, { + async: true, + crossOrigin: "anonymous", + defer: false, + integrity: void 0, + nomodule: false, + nonce: void 0, + referrerpolicy: void 0, + type: "text/javascript" + }); + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/dom/resource/script"); + } + /** + * + * @return {Monster.DOM.Resource.Script} + */ + create() { + createElement2.call(this); + return this; + } + /** + * @return {string} + */ + static getURLAttribute() { + return ATTRIBUTE_SRC; + } + }; + function createElement2() { + const self2 = this; + const document2 = self2.getOption(KEY_DOCUMENT); + self2[referenceSymbol] = document2.createElement(TAG_SCRIPT); + for (let key of [ + "crossOrigin", + "defer", + "async", + "integrity", + "nomodule", + ATTRIBUTE_NONCE, + "referrerpolicy", + ATTRIBUTE_TYPE, + ATTRIBUTE_SRC, + ATTRIBUTE_ID, + ATTRIBUTE_CLASS, + ATTRIBUTE_TITLE + ]) { + if (self2.getOption(key) !== void 0) { + self2[referenceSymbol][key] = self2.getOption(key); + } + } + return self2; + } + + // test/cases/dom/resource/script.mjs + init_dataurl(); + init_id(); + var expect4 = chai_default.expect; + chai_default.use(chaiDom); + describe("Script", function() { + before(function(done) { + initJSDOM().then(() => { + done(); + }); + }); + beforeEach(() => { + initMutationObserverForTesting(); + }); + afterEach(() => { + cleanupDOMFromTesting(); + }); + describe("Script()", function() { + it("setEventTypes()", function(done) { + const script = new Script({ + src: new DataUrl("", "text/javascript").toString(), + async: true, + crossOrigin: "anonymous", + defer: false, + integrity: void 0, + nomodule: false, + nonce: void 0, + referrerpolicy: void 0, + type: "text/javascript" + }); + script.connect().available().then(() => { + const id = script.getOption("id"); + done(); + }).catch((e) => done(e)); + }); + }); + describe("External JS", () => { + let id = new ID("script").toString(); + let server, script, url = "https://monsterjs.org/assets/empty.js?" + id; + beforeEach(() => { + script = new Script({ + src: url, + async: true, + crossOrigin: "anonymous", + defer: false, + integrity: void 0, + nomodule: false, + nonce: void 0, + referrerpolicy: void 0, + type: "text/javascript", + id + }); + }); + it("append and remove script ", (done) => { + expect4(script.isConnected()).to.be.false; + script.connect().available().then(() => { + expect4(script.isConnected()).to.be.true; + expect4(document.querySelector('[src="' + url + '"]')).to.exist; + document.getElementById(id).remove(); + expect4(script.isConnected()).to.be.false; + expect4(document.querySelector('[src="' + url + '"]')).not.to.exist; + script.connect().available().then(() => { + expect4(script.isConnected()).to.be.true; + expect4(document.querySelector('[src="' + url + '"]')).to.exist; + document.getElementById(id).remove(); + expect4(document.querySelector('[src="' + url + '"]')).not.to.exist; + expect4(script.isConnected()).to.be.false; + done(); + }).catch((e) => done(e)); + }).catch((e) => done(e)); + }); + }); + }); + + // source/dom/resource/data.mjs + init_constants(); + init_extend(); + init_global(); + init_constants2(); + init_resource(); + init_constants(); + var Data = class extends Resource { + /** + * @property {string} mode=cors https://developer.mozilla.org/en-US/docs/Web/API/fetch + * @property {string} credentials=same-origin https://developer.mozilla.org/en-US/docs/Web/API/fetch + * @property {string} type=application/json {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-type} + */ + get defaults() { + return extend({}, super.defaults, { + mode: "cors", + credentials: "same-origin", + type: "application/json" + }); + } + /** + * + * @return {Monster.DOM.Resource.Data} + */ + create() { + createElement3.call(this); + return this; + } + /** + * This method appends the HTMLElement to the specified document + * + * throws {Error} target not found + * @return {Monster.DOM.Resource} + */ + connect() { + if (!(this[referenceSymbol] instanceof HTMLElement)) { + this.create(); + } + appendToDocument2.call(this); + return this; + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/dom/resource/data"); + } + /** + * @return {string} + */ + static getURLAttribute() { + return ATTRIBUTE_SRC; + } + }; + function createElement3() { + const self2 = this; + const document2 = self2.getOption(KEY_DOCUMENT); + self2[referenceSymbol] = document2.createElement(TAG_SCRIPT); + for (let key of [ATTRIBUTE_TYPE, ATTRIBUTE_ID, ATTRIBUTE_CLASS, ATTRIBUTE_TITLE]) { + if (self2.getOption(key) !== void 0) { + self2[referenceSymbol][key] = self2.getOption(key); + } + } + return self2; + } + function appendToDocument2() { + const self2 = this; + const targetNode = document.querySelector(self2.getOption(KEY_QUERY, "head")); + if (!(targetNode instanceof HTMLElement)) { + throw new Error("target not found"); + } + targetNode.appendChild(self2[referenceSymbol]); + getGlobalFunction("fetch")(self2.getOption(ATTRIBUTE_SRC), { + method: "GET", + // *GET, POST, PUT, DELETE, etc. + mode: self2.getOption("mode", "cors"), + // no-cors, *cors, same-origin + cache: "no-cache", + // *default, no-cache, reload, force-cache, only-if-cached + credentials: self2.getOption("credentials", "same-origin"), + // include, *same-origin, omit + headers: { + Accept: self2.getOption("type", "application/json") + }, + redirect: "follow", + // manual, *follow, error + referrerPolicy: "no-referrer" + // no-referrer, + }).then((response) => { + return response.text(); + }).then((text) => { + const textNode = document.createTextNode(text); + self2[referenceSymbol].appendChild(textNode); + self2[internalStateSymbol].getSubject()["loaded"] = true; + }).catch((e) => { + self2[internalStateSymbol].setSubject({ + loaded: true, + error: e.toString() + }); + targetNode.setAttribute(ATTRIBUTE_ERRORMESSAGE, e.toString()); + }); + return self2; + } + + // test/cases/dom/resource/data.mjs + init_dataurl(); + init_id(); + var expect5 = chai_default.expect; + chai_default.use(chaiDom); + describe("Data", function() { + let fetchReference2, returnStatus, mutationobserver2, addedNodes2 = []; + before(function(done) { + initJSDOM().then(() => { + done(); + }); + }); + beforeEach(() => { + initMutationObserverForTesting(); + returnStatus = 200; + fetchReference2 = globalThis["fetch"]; + globalThis["fetch"] = function(url, options) { + if (!url) + throw new Error("missing url"); + return new Promise((resolve, reject) => { + resolve({ + text: function() { + return JSON.stringify({ + a: "test" + }); + }, + status: returnStatus + }); + }); + }; + }); + afterEach(() => { + globalThis["fetch"] = fetchReference2; + cleanupDOMFromTesting(); + }); + describe("Data()", function() { + it("setEventTypes()", function(done) { + const data = new Data({ + src: new DataUrl("", "text/javascript").toString() + }); + data.connect().available().then(() => { + done(); + }).catch((e) => done(e)); + }); + }); + describe("External Data", () => { + let id = new ID("data").toString(); + let server, data, url = "https://monsterjs.org/assets/empty.js?" + id; + beforeEach(() => { + data = new Data({ + src: url, + id + }); + }); + it("data is not connected", () => { + expect5(data.isConnected()).to.be.false; + }); + it("connect and check availability", (done) => { + data.connect().available().then(() => { + expect5(data.isConnected(), "isConnected 1").to.be.true; + expect5(document.querySelector('[type="application/json"]'), "exists 1").to.exist; + const e = document.getElementById(id).parentElement; + document.getElementById(id).remove(); + expect5(data.isConnected(), "isConnected 2").to.be.false; + expect5(document.querySelector('[type="application/json"]'), "exists 2").not.to.exist; + data.connect().available().then(() => { + expect5(data.isConnected(), "isConnected 3").to.be.true; + expect5(document.querySelector('[type="application/json"]'), "exists 3").to.exist; + document.getElementById(id).remove(); + expect5(document.querySelector('[type="application/json"]'), "exists 4").not.to.exist; + expect5(data.isConnected(), "isConnected 4").to.be.false; + done(); + }).catch((e2) => done(e2)); + }).catch((e) => done(e)); + }); + }); + }); + + // test/cases/dom/util/init-options-from-attributes.mjs + describe("initOptionsFromAttributes", () => { + let element; + let options; + let initOptionsFromAttributes2; + before(function(done) { + initJSDOM().then(() => { + Promise.resolve().then(() => (init_init_options_from_attributes(), init_options_from_attributes_exports)).then((m) => { + initOptionsFromAttributes2 = m["initOptionsFromAttributes"]; + done(); + }); + }); + }); + beforeEach(() => { + options = { url: "", key: { subkey: "", caseSensitive: true } }; + element = document.createElement("div"); + }); + it("should initialize options with matching attributes", () => { + element.setAttribute("data-monster-option-url", "https://example.com"); + element.setAttribute("data-monster-option-key-subkey", "test"); + const result = initOptionsFromAttributes2(element, options); + expect(result.url).to.equal("https://example.com"); + expect(result.key.subkey).to.equal("test"); + }); + it("should not modify options without matching attributes", () => { + const result = initOptionsFromAttributes2(element, options); + expect(result.url).to.equal(""); + expect(result.key.subkey).to.equal(""); + }); + it("should ignore attributes without the correct prefix", () => { + element.setAttribute("data-some-option-url", "https://example.com"); + const result = initOptionsFromAttributes2(element, options); + expect(result.url).to.equal(""); + }); + it("should ignore attributes with invalid option paths", () => { + element.setAttribute("data-monster-option-nonexistent", "value"); + const result = initOptionsFromAttributes2(element, options); + expect(result).to.deep.equal(options); + }); + it("should apply mapping for a single attribute", () => { + element.setAttribute("data-monster-option-url", "example"); + const mapping = { + "url": (value) => "https://" + value + ".com" + }; + const result = initOptionsFromAttributes2(element, options, mapping); + expect(result.url).to.equal("https://example.com"); + }); + it("should apply mapping for a nested attribute", () => { + element.setAttribute("data-monster-option-key-subkey", "123"); + const mapping = { + "key.subkey": (value) => parseInt(value, 10) * 2 + }; + const result = initOptionsFromAttributes2(element, options, mapping); + expect(result.key.subkey).to.equal("246"); + }); + it("should apply multiple mappings", () => { + element.setAttribute("data-monster-option-url", "example"); + element.setAttribute("data-monster-option-key-subkey", "123"); + const mapping = { + "url": (value) => "https://" + value + ".com", + "key.subkey": (value) => parseInt(value, 10) * 2 + }; + const result = initOptionsFromAttributes2(element, options, mapping); + expect(result.url).to.equal("https://example.com"); + expect(result.key.subkey).to.equal("246"); + }); + it("should ignore mappings for non-existing attributes", () => { + const mapping = { + "url": (value) => "https://" + value + ".com" + }; + const result = initOptionsFromAttributes2(element, options, mapping); + expect(result.url).to.equal(""); + }); + it("should ignore mappings for invalid option paths", () => { + element.setAttribute("data-monster-option-nonexistent", "value"); + const mapping = { + "nonexistent": (value) => value + "bar" + }; + const result = initOptionsFromAttributes2(element, options, mapping); + expect(result).to.deep.equal(options); + }); + it("should apply mapping only to specified attributes", () => { + element.setAttribute("data-monster-option-url", "example"); + element.setAttribute("data-monster-option-key-subkey", "123"); + const mapping = { + "url": (value) => "https://" + value + ".com" + }; + const result = initOptionsFromAttributes2(element, options, mapping); + expect(result.url).to.equal("https://example.com"); + expect(result.key.subkey).to.equal("123"); + }); + it("should not apply mapping if not a function", () => { + element.setAttribute("data-monster-option-url", "example"); + const mapping = { + "url": "https://example.com" + }; + const result = initOptionsFromAttributes2(element, options, mapping); + expect(result.url).to.equal("example"); + }); + it("should apply mapping with custom prefix", () => { + element.setAttribute("data-custom-option-url", "example"); + const mapping = { + "url": (value) => "https://" + value + ".com" + }; + const result = initOptionsFromAttributes2(element, options, mapping, "data-custom-option-"); + expect(result.url).to.equal("https://example.com"); + }); + it("should not apply mapping with incorrect custom prefix", () => { + element.setAttribute("data-custom-option-url", "example"); + const mapping = { + "url": (value) => "https://" + value + ".com" + }; + const result = initOptionsFromAttributes2(element, options, mapping); + expect(result.url).to.equal(""); + }); + it("should apply case sensitive mapping", () => { + element.setAttribute("data-monster-option-key-caseSensitive", "false"); + const result = initOptionsFromAttributes2(element, options); + expect(result.key.caseSensitive).to.equal(false); + }); + }); + + // test/cases/dom/util/extract-keys.mjs + init_extract_keys(); + describe("extractKeys", () => { + it("should extract keys from the given object", () => { + const obj = { + firstName: "John", + lastName: "Doe", + address: { + street: "123 Main St", + city: "New York" + } + }; + const expected = /* @__PURE__ */ new Map([ + ["firstname", "firstName"], + ["lastname", "lastName"], + ["address-street", "address.street"], + ["address-city", "address.city"] + ]); + const result = extractKeys(obj); + expect(JSON.stringify(Array.from(result))).to.equal(JSON.stringify(Array.from(expected))); + }); + it("should use custom key and value separators", () => { + const obj = { + firstName: "John", + lastName: "Doe" + }; + const expected = /* @__PURE__ */ new Map([ + ["prefix+firstname", "prefix+firstName"], + ["prefix+lastname", "prefix+lastName"] + ]); + const result = extractKeys(obj, "prefix", "+", "+"); + expect(JSON.stringify(Array.from(result))).to.equal(JSON.stringify(Array.from(expected))); + }); + it("check if value is null", () => { + const obj = { + firstName: "John", + lastName: "Doe", + address: null + }; + const expected = /* @__PURE__ */ new Map([ + ["firstname", "firstName"], + ["lastname", "lastName"], + ["address", "address"] + ]); + const result = extractKeys(obj); + expect(JSON.stringify(Array.from(result))).to.equal(JSON.stringify(Array.from(expected))); + }); + }); + + // source/dom/worker/factory.mjs + init_constants(); + init_base(); + init_global(); + init_is(); + init_validate(); + var Factory = class extends Base { + /** + * + */ + constructor() { + super(); + this[internalSymbol] = { + worker: /* @__PURE__ */ new WeakMap() + }; + } + /** + * Creates a worker from a URL + * + * @param {string|URL} url + * @param {function} messageHandler + * @param {function} errorHandler + * @return {Worker} + */ + createFromURL = function(url, messageHandler, errorHandler) { + if (url instanceof URL) { + url = url.toString(); + } + const workerClass = getGlobalFunction("Worker"); + var worker = new workerClass(validateString(url)); + if (isFunction(messageHandler)) { + worker.onmessage = (event) => { + messageHandler.call(worker, event); + }; + } + if (isFunction(errorHandler)) { + worker.onerror = (event) => { + errorHandler.call(worker, event); + }; + } + return worker; + }; + /** + * Creates a worker from a script + * + * @param {string} content + * @param {function} messageHandler + * @param {function} errorHandler + * @return {Worker} + * @see https://developer.mozilla.org/de/docs/Web/API/URL/createObjectURL + */ + createFromScript = function(content, messageHandler, errorHandler) { + const blobFunction = new getGlobalFunction("Blob"); + const blob = new blobFunction([validateString(content)], { + type: "script/javascript" + }); + const url = getGlobalFunction("URL").createObjectURL(blob); + const worker = this.createFromURL(url, messageHandler, errorHandler); + this[internalSymbol]["worker"].set(worker, url); + return worker; + }; + /** + * Terminate the worker and call revokeObjectURL if necessary. + * + * @param worker + * @return {Monster.DOM.Worker.Factory} + */ + terminate(worker) { + const workerClass = getGlobalFunction("Worker"); + validateInstance(worker, workerClass); + worker.terminate(); + if (this[internalSymbol]["worker"].has(worker)) { + const url = this[internalSymbol]["worker"].get(worker); + URL.revokeObjectURL(url); + } + return this; + } + }; + + // test/cases/dom/worker/factory.mjs + init_global(); + var global2 = getGlobal(); + describe("Worker", function() { + before(function(done) { + if (isNode()) { + Object.defineProperty(global2["URL"], "createObjectURL", { + writable: true, + value: () => { + return "/example.mjs"; + } + }); + global2["Worker"] = class { + terminate() { + } + onerror() { + } + onmessage() { + } + }; + let a2 = typeof global2["Worker"]; + let a1 = typeof Worker; + } + const jsdom = initJSDOM().then(() => { + done(); + }); + }); + describe("Factory", function() { + it("create worker", function() { + const factory = new Factory(); + const worker = factory.createFromScript('console.log("hello world");'); + expect(worker).is.instanceof(Worker); + expect(factory.terminate(worker)).is.instanceof(Factory); + }); + }); + }); + + // test/cases/dom/updater.mjs + init_updater(); + init_id(); + init_observer(); + init_proxyobserver(); + var expect6 = chai_default.expect; + chai_default.use(chaiDom); + var html1 = ` + <template id="current"> + <li data-monster-replace="path:current | tojson"></li> + </template> + <div id="test1"> + <ul data-monster-insert="current path:a.b"> + </ul> + </div> + <div id="test2"> + <ul data-monster-insert="current path:a.b | doit"> + </ul> + </div> + <div id="test3"> + <div data-monster-attributes="class path:a.b"> + <input data-monster-attributes="value path:a.c" id="input1"> + <input data-monster-attributes="checked path:a.checkbox" type="checkbox" name="checkbox" id="checkbox"> + <input data-monster-attributes="value path:a.text" type="text" name="text" id="text"> + <input data-monster-attributes="checked path:a.radio" type="radio" name="radio" value="r1" id="radio"> + <input type="radio" name="radio" value="r2" id="r2"> + <input type="radio" name="radio" value="rx" id="rx"> + + <select data-monster-attributes="value path:a.select" name="select" id="select"> + <option value="other-value">value1</option> + <option>value2</option> + </select> + + <select data-monster-attributes="value path:a.multiselect" name="multiselect" multiple id="multiselect"> + <option>value1</option> + <option>value2</option> + <option>value3</option> + <option>value4</option> + <option value="other-value5">value5</option> + </select> + + <textarea name="textarea" id="textarea" data-monster-attributes="value path:a.textarea"></textarea> + + </div> + </div> + +`; + var html2 = ` + <div id="test1"> + <div data-monster-replace="path:text | tolower"></div> + <div data-monster-replace="path:text | call:myformatter"></div> + <div data-monster-replace="static:hello\\ "></div> + </div> +`; + var html3 = ` + + <template id="myinnerid"> + <span data-monster-replace="path:myinnerid | tojson"></span> + </template> + + <template id="myid"> + <p data-monster-insert="myinnerid path:a.b"></p> + </template> + + <div id="test1"> + <div data-monster-insert="myid path:a.b"></div> + </div> + +`; + var html4 = ` + <div> + <form id="form1"> + <input type="checkbox" value="checked" name="checkbox" data-monster-bind="path:state"> + <input type="text" name="text"> + <input type="radio" name="radio" value="r1" id="r1" data-monster-bind="path:radio"> + <input type="radio" name="radio" value="r2" id="r2" data-monster-bind="path:radio"> + <input type="radio" name="radio" value="rx" id="rx" data-comment="not called because no bind attribute"> + <input type="button" name="button"> + + <select name="select1" id="select1" data-monster-bind="path:select"> + <option>value1</option> + <option>value2</option> + </select> + + <select name="select2" multiple id="select2" data-monster-bind="path:multiselect"> + <option>value1</option> + <option>value2</option> + <option>value3</option> + <option>value4</option> + <option>value5</option> + </select> + + <textarea name="textarea" id="textarea" data-monster-bind="path:textarea"> + + </textarea> + + </form> + </div> + +`; + describe("DOM", function() { + before(function(done) { + initJSDOM().then(() => { + done(); + }); + }); + beforeEach(() => { + let mocks = document.getElementById("mocks"); + mocks.innerHTML = html1; + }); + afterEach(() => { + let mocks = document.getElementById("mocks"); + mocks.innerHTML = ""; + }); + describe("Updater()", function() { + describe("test Getter && Setter", function() { + it("setEventTypes()", function() { + let element = document.getElementById("test1"); + expect6(new Updater(element).setEventTypes(["touch"])).to.be.instanceof(Updater); + }); + it("getSubject()", function() { + let element = document.getElementById("test1"); + let subject = { a: 1 }; + expect6(new Updater(element, subject).getSubject().a).to.be.equal(1); + }); + }); + describe("test control methods", function() { + it("enableEventProcessing()", function() { + let element = document.getElementById("test1"); + expect6(new Updater(element).enableEventProcessing()).to.be.instanceof(Updater); + }); + it("disableEventProcessing()", function() { + let element = document.getElementById("test1"); + expect6(new Updater(element).disableEventProcessing()).to.be.instanceof(Updater); + }); + }); + describe("test Errors", function() { + it("should throw value is not an instance of HTMLElement Error", function() { + expect6(() => new Updater()).to.throw(TypeError); + }); + it("should throw value is wrong", function() { + let element = document.getElementById("test1"); + expect6(() => new Updater(element, null)).to.throw(TypeError); + }); + it("should throw Error: the value is not iterable", function(done) { + let element = document.getElementById("test1"); + let u = new Updater( + element, + { + a: { + x: [] + } + } + ); + u.run().then(() => { + done(new Error("should never called!")); + }).catch((e) => { + expect6(e).is.instanceOf(Error); + expect6(e + "").to.be.equal("Error: the value is not iterable"); + done(); + }); + }); + }); + }); + describe("Updater()", function() { + describe("new Updater", function() { + it("should return document object", function() { + let element = document.getElementById("test1"); + let d2 = new Updater( + element, + {} + ); + expect6(typeof d2).is.equal("object"); + }); + }); + }); + describe("Updater()", function() { + describe("Repeat", function() { + it("should build 6 li elements", function(done) { + let element = document.getElementById("test1"); + let d2 = new Updater( + element, + { + a: { + b: [ + { i: "0" }, + { i: "1" }, + { i: "2" }, + { i: "3" }, + { i: "4" }, + { i: "5" } + ] + } + } + ); + d2.run().then(() => { + expect6(typeof d2).is.equal("object"); + for (let i = 0; i < 6; i++) { + expect6(element).contain.html('<li data-monster-replace="path:a.b.' + i + ' | tojson" data-monster-insert-reference="current-' + i + '">{"i":"' + i + '"}</li>'); + } + done(); + }).catch( + (e) => { + done(new Error(e)); + } + ); + }); + }); + }); + describe("Updater()", function() { + beforeEach(() => { + let mocks = document.getElementById("mocks"); + mocks.innerHTML = html4; + }); + describe("Eventhandling", function() { + let updater, form1, proxyobserver; + beforeEach(() => { + proxyobserver = new ProxyObserver({}); + updater = new Updater(document.getElementById("form1"), proxyobserver); + form1 = document.getElementById("form1"); + }); + it("should handle checkbox click events", function(done) { + updater.enableEventProcessing(); + let subject = updater.getSubject(); + expect6(subject).is.equal(proxyobserver.getSubject()); + let expected = ["checked", void 0, "checked"]; + proxyobserver.attachObserver(new Observer(function() { + let e = expected.shift(); + if (e === void 0 && expected.length === 0) + done(new Error("to many calls")); + if (this.getSubject()["state"] !== e) + done(new Error(this.getSubject()["state"] + " should " + e)); + if (expected.length === 0) { + done(); + } else { + setTimeout(() => { + form1.querySelector("[name=checkbox]").click(); + }, 10); + } + })); + setTimeout(() => { + form1.querySelector("[name=checkbox]").click(); + }, 10); + }); + it("should handle radio click events 1", function(done) { + updater.enableEventProcessing(); + let subject = updater.getSubject(); + expect6(subject).is.equal(proxyobserver.getSubject()); + let expected = ["r1", "r2", "r1"]; + let clickTargets = ["r2", "r1"]; + proxyobserver.attachObserver(new Observer(function() { + let e = expected.shift(); + if (e === void 0 && expected.length === 0) + done(new Error("to many calls")); + let v = this.getSubject()["radio"]; + if (v !== e) + done(new Error(v + " should " + e)); + if (expected.length === 0) { + done(); + } else { + setTimeout(() => { + document.getElementById(clickTargets.shift()).click(); + }, 10); + } + })); + setTimeout(() => { + document.getElementById("r1").click(); + }, 10); + setTimeout(() => { + document.getElementById("rx").click(); + }, 20); + }); + it("should handle select click events 2", function(done) { + let selectElement = document.getElementById("select1"); + updater.enableEventProcessing(); + let subject = updater.getSubject(); + expect6(subject).is.equal(proxyobserver.getSubject()); + let expected = ["value2", "value1", "value2"]; + proxyobserver.attachObserver(new Observer(function() { + let e = expected.shift(); + if (e === void 0 && expected.length === 0) + done(new Error("to many calls")); + let v = this.getSubject()["select"]; + if (v !== e) + done(new Error(v + " should " + e)); + if (expected.length === 0) { + done(); + } else { + setTimeout(() => { + selectElement.selectedIndex = selectElement.selectedIndex === 1 ? 0 : 1; + selectElement.click(); + }, 10); + } + })); + setTimeout(() => { + selectElement.selectedIndex = 1; + selectElement.click(); + }, 20); + }); + it("should handle textarea events", function(done) { + let textareaElement = document.getElementById("textarea"); + updater.enableEventProcessing(); + let subject = updater.getSubject(); + expect6(subject).is.equal(proxyobserver.getSubject()); + let expected = ["testX", "lorem ipsum", ""]; + let testValues = ["lorem ipsum", ""]; + proxyobserver.attachObserver(new Observer(function() { + let e = expected.shift(); + if (e === void 0 && expected.length === 0) + done(new Error("to many calls")); + let v = this.getSubject()["textarea"]; + if (JSON.stringify(v) !== JSON.stringify(e)) + done(new Error(JSON.stringify(v) + " should " + JSON.stringify(e))); + if (expected.length === 0) { + done(); + } else { + setTimeout(() => { + textareaElement.value = testValues.shift(); + textareaElement.click(); + }, 10); + } + })); + setTimeout(() => { + textareaElement.value = "testX"; + textareaElement.click(); + }, 20); + }); + it("should handle multiple select events", function(done) { + let selectElement = document.getElementById("select2"); + updater.enableEventProcessing(); + let subject = updater.getSubject(); + expect6(subject).is.equal(proxyobserver.getSubject()); + let expected = [ + ["value1"], + ["value2", "value3", "value4"], + ["value1", "value4"] + ]; + let testSelections = [ + [false, true, true, true], + [true, false, false, true] + ]; + proxyobserver.attachObserver(new Observer(function() { + let e = expected.shift(); + if (e === void 0 && expected.length === 0) + done(new Error("to many calls")); + let v = this.getSubject()["multiselect"]; + if (JSON.stringify(v) !== JSON.stringify(e)) + done(new Error(JSON.stringify(v) + " should " + JSON.stringify(e))); + if (expected.length === 0) { + done(); + } else { + setTimeout(() => { + let v2 = testSelections.shift(); + selectElement.options[0].selected = v2[0]; + selectElement.options[1].selected = v2[1]; + selectElement.options[2].selected = v2[2]; + selectElement.options[3].selected = v2[3]; + selectElement.click(); + }, 10); + } + })); + setTimeout(() => { + selectElement.options[0].selected = true; + selectElement.options[1].selected = false; + selectElement.options[2].selected = false; + selectElement.options[3].selected = false; + selectElement.click(); + }, 20); + }); + }); + }); + describe("Updater()", function() { + beforeEach(() => { + let mocks = document.getElementById("mocks"); + mocks.innerHTML = html2; + }); + describe("Replace", function() { + it("should add lower hello and HELLOyes!", function(done) { + let element = document.getElementById("test1"); + let d2 = new Updater( + element, + { + text: "HALLO" + } + ); + d2.setCallback("myformatter", function(a2) { + return a2 + "yes!"; + }); + setTimeout(() => { + d2.run().then(() => { + expect6(typeof d2).is.equal("object"); + expect6(element).contain.html('<div data-monster-replace="path:text | tolower">hallo</div>'); + expect6(element).contain.html('<div data-monster-replace="path:text | call:myformatter">HALLOyes!</div>'); + expect6(element).contain.html('<div data-monster-replace="static:hello\\ ">hello </div>'); + return done(); + }).catch( + (e) => { + done(new Error(e)); + } + ); + }, 100); + }); + }); + }); + describe("Updater()", function() { + beforeEach(() => { + let mocks = document.getElementById("mocks"); + mocks.innerHTML = html3; + }); + describe("Replace", function() { + it("should ", function(done) { + let element = document.getElementById("test1"); + let d2 = new Updater( + element, + { + a: { + b: [ + { i: "0" } + ] + } + } + ); + d2.run().then(() => { + expect6(typeof d2).is.equal("object"); + expect6(element).contain.html('<div data-monster-insert="myid path:a.b">'); + expect6(element).contain.html('<p data-monster-insert="myinnerid path:a.b" data-monster-insert-reference="myid-0">'); + expect6(element).contain.html('<span data-monster-replace="path:a.b.0 | tojson" data-monster-insert-reference="myinnerid-0">{"i":"0"}</span>'); + done(); + }).catch( + (e) => { + done(new Error(e)); + } + ); + }); + }); + }); + describe("Updater()", function() { + describe("Attributes", function() { + it("should change attributes", function(done) { + let element = document.getElementById("test3"); + let text = document.getElementById("text"); + expect6(text.value).to.be.equal(""); + let radio = document.getElementById("radio"); + expect6(radio.checked).to.be.false; + let checkbox = document.getElementById("checkbox"); + expect6(checkbox.checked).to.be.false; + let select = document.getElementById("select"); + expect6(select.selectedIndex).to.be.equal(0); + let multiselect = document.getElementById("multiselect"); + expect6(multiselect.selectedIndex).to.be.equal(-1); + let textarea = document.getElementById("textarea"); + expect6(textarea.value).to.be.equal(""); + let d2 = new Updater( + element, + { + a: { + b: "div-class", + c: "hello", + text: "hello", + radio: "true", + textarea: "test", + multiselect: ["value3", "value4", "other-value5"], + select: "value2", + checkbox: "true" + } + } + ); + d2.run().then(() => { + expect6(element).contain.html('<div data-monster-attributes="class path:a.b" class="div-class">'); + expect6(element).contain.html('<input data-monster-attributes="value path:a.c" id="input1" value="hello">'); + expect6(element).contain.html('<textarea name="textarea" id="textarea" data-monster-attributes="value path:a.textarea" value="test">'); + expect6(element).contain.html('<input data-monster-attributes="checked path:a.radio" type="radio" name="radio" value="r1" id="radio" checked="true">'); + expect6(text.value, "text control").to.be.equal(d2.getSubject()["a"]["c"]); + expect6(radio.checked, "radio control").to.be.equal(true); + expect6(textarea.value, "textarea control").to.be.equal(d2.getSubject()["a"]["textarea"]); + expect6(select.selectedIndex, "select control").to.be.equal(1); + let multiselectSelectedOptions = []; + for (const [index, obj] of Object.entries(multiselect.selectedOptions)) { + multiselectSelectedOptions.push(obj.value); + } + expect6(JSON.stringify(multiselectSelectedOptions), "multiselect control").to.be.equal(JSON.stringify(d2.getSubject()["a"]["multiselect"])); + expect6(checkbox.checked, "checkbox control").to.be.true; + done(); + }).catch( + (e) => { + done(new Error(e)); + } + ); + }); + }); + }); + describe("Get Attribute Pipe", function() { + let id, mocks; + beforeEach(() => { + mocks = document.getElementById("mocks"); + id = new ID("monster"); + mocks.innerHTML = ` <div id="` + id + `" + data-monster-replace="path:a | if:value:\\ "></div>`; + }); + afterEach(() => { + mocks.innerHTML = ""; + }); + it("should include space", function() { + const div = document.getElementById(id.toString()); + const pipe = div.getAttribute("data-monster-replace"); + expect6(pipe.length).to.be.equal(20); + }); + }); + describe("manuel update", function() { + let id, mocks; + beforeEach(() => { + mocks = document.getElementById("mocks"); + id = new ID("monster").toString(); + mocks.innerHTML = `<input id="` + id + `"data-monster-bind="path:myvalue">`; + }); + afterEach(() => { + mocks.innerHTML = ""; + }); + it("should get value", function() { + document.getElementById(id).value = "hello"; + const updater = new Updater(mocks); + const subject = updater.getSubject(); + expect6(subject).to.not.have.property("myvalue"); + updater.retrieve(); + expect6(subject).to.have.property("myvalue"); + }); + }); + describe("Updater() 20220107", function() { + beforeEach(() => { + let mocks = document.getElementById("mocks"); + mocks.innerHTML = ` + + <div id="container"> + <div data-monster-replace="path:content"></div> + </div> + + + `; + }); + describe("Bugfix #112", function() { + it("should add ", function(done) { + let containerElement = document.getElementById("container"); + let newElement = document.createElement("div"); + newElement.innerHTML = "yeah! <b>Test</b>!"; + const containerHTML = containerElement.innerHTML; + const newHTML = newElement.innerHTML; + let d2 = new Updater( + containerElement, + { + content: newElement + } + ); + setTimeout(() => { + d2.run().then(() => { + try { + expect6(containerElement).contain.html("<div>yeah! <b>Test</b>!</div>"); + } catch (e) { + return done(e); + } + done(); + }); + }, 100); + }); + }); + }); + }); + + // test/cases/dom/locale.mjs + init_locale(); + init_locale2(); + describe("Attributes", function() { + before(function(done) { + initJSDOM().then(() => { + done(); + }); + }); + describe("getLocaleOfDocument", function() { + [ + ["de"], + ["sl-IT-nedis"], + ["en-GB"] + ].forEach(function(data) { + let a2 = data.shift(); + it("return language " + a2, function() { + let html = document.getElementsByTagName("html"); + let node = html.item(0); + node.setAttribute("lang", a2); + expect(getLocaleOfDocument().toString()).to.be.equal(a2); + }); + }); + }); + it("return language en", function() { + let html = document.getElementsByTagName("html"); + let node = html.item(0); + let lang = node.getAttribute("lang"); + node.removeAttribute("lang"); + const locale = getLocaleOfDocument(); + expect(locale).to.be.instanceOf(Locale); + expect(locale.localeString).to.be.equal(navigator.language); + node.setAttribute("lang", lang); + }); + }); + + // test/cases/dom/theme.mjs + init_util(); + init_theme(); + describe("Theme", function() { + before(function(done) { + initJSDOM().then(() => { + done(); + }); + }); + describe("new Theme()", function() { + it("should return Theme object", function() { + expect(new Theme("my-theme")).is.a.instanceOf(Theme); + }); + it("should return Theme-Name", function() { + expect(new Theme("my-theme").getName()).is.equal("my-theme"); + }); + it("should throw Error because empty argument", function() { + expect(() => new Theme()).to.throw(TypeError); + }); + it("should throw Error because no string argument", function() { + expect(() => new Theme(2)).to.throw(TypeError); + }); + }); + describe("getDocumentTheme()", function() { + it("should return Theme object", function() { + expect(getDocumentTheme()).is.a.instanceOf(Theme); + }); + it("should return Default Theme name", function() { + expect(getDocumentTheme().getName()).is.equal("monster"); + }); + }); + describe("getDocumentTheme()", function() { + beforeEach(() => { + document.querySelector("html").setAttribute("data-monster-theme-name", "testtheme"); + }); + afterEach(() => { + document.querySelector("html").removeAttribute("data-monster-theme-name"); + }); + it("should return testtheme Theme name", function() { + expect(getDocumentTheme().getName()).is.equal("testtheme"); + }); + }); + }); + + // test/cases/dom/customelement.mjs + init_constants(); + init_constants2(); + init_util(); + init_proxyobserver(); + init_updater(); + var expect7 = chai_default.expect; + chai_default.use(chaiDom); + var html12 = ` + <div id="test1"> + </div> +`; + var html22 = ` + <input data-monster-bind="path:a" id="test2" data-monster-attributes="value path:a"> +`; + var updaterSymbolKey = "@schukai/monster/dom/custom-element@@options-updater-link"; + var updaterSymbolSymbol = Symbol.for(updaterSymbolKey); + describe("DOM", function() { + let CustomElement2, registerCustomElement2, TestComponent, document2, TestComponent2, assignUpdaterToElement; + describe("assignUpdaterToElement", function() { + before(function(done) { + initJSDOM().then(() => { + Promise.resolve().then(() => (init_customelement(), customelement_exports)).then((m) => { + try { + CustomElement2 = m["CustomElement"]; + assignUpdaterToElement = function(elements, object) { + return addObjectWithUpdaterToElement.call(this, elements, updaterSymbolSymbol, object); + }; + document2 = getDocument(); + done(); + } catch (e) { + done(e); + } + }); + }); + }); + beforeEach(() => { + let mocks = document2.getElementById("mocks"); + mocks.innerHTML = html22; + }); + afterEach(() => { + let mocks = document2.getElementById("mocks"); + mocks.innerHTML = ""; + }); + it("should assign an updater to an element", function(done) { + let element = document2.getElementById("test2"); + expect7(document2.getElementById("mocks").innerHTML).to.equal(html22); + const a2 = { a: 1 }; + const b = { b: 2 }; + const ap = new ProxyObserver(a2); + const bp = new ProxyObserver(b); + const x = ap.getSubject(); + const y = bp.getSubject(); + const set = /* @__PURE__ */ new Set(); + set.add(element); + assignUpdaterToElement.call(element, set, ap); + assignUpdaterToElement.call(element, set, bp); + expect7(JSON.stringify(x)).to.equal('{"a":1}'); + expect7(JSON.stringify(y)).to.equal('{"b":2}'); + const sy = updaterSymbolSymbol; + let v = element.getAttribute("data-monster-objectlink"); + expect7(v).to.equal("Symbol(" + updaterSymbolKey + ")"); + const updater = element[sy]; + for (const v2 of updater) { + for (const u of v2) { + u.run().then(() => { + u.enableEventProcessing(); + }); + } + } + expect7(updater).to.be.an.instanceof(Set); + expect7(updater).to.be.a("Set"); + x.a = 3; + bp.getSubject().b = 4; + setTimeout(() => { + let mockHTML = document2.getElementById("mocks"); + expect7(mockHTML.querySelector("#test2")).to.have.value("3"); + expect7(mockHTML.querySelector("#test2")).to.have.attribute("data-monster-objectlink", "Symbol(" + updaterSymbolKey + ")"); + expect7(element.value).to.equal("3"); + expect7(JSON.stringify(ap.getRealSubject())).to.equal('{"a":3}'); + expect7(JSON.stringify(bp.getRealSubject())).to.equal('{"b":4}'); + done(); + }, 10); + }); + }); + describe("CustomElement()", function() { + before(function(done) { + initJSDOM().then(() => { + Promise.resolve().then(() => (init_customelement(), customelement_exports)).then((m) => { + try { + CustomElement2 = m["CustomElement"]; + registerCustomElement2 = m["registerCustomElement"]; + TestComponent = class extends CustomElement2 { + static getTag() { + return "monster-testclass"; + } + }; + registerCustomElement2(TestComponent); + TestComponent2 = class extends CustomElement2 { + static getTag() { + return "monster-testclass2"; + } + /** + * + * @return {Object} + */ + get defaults() { + return Object.assign({}, super.defaults, { + demotest: void 0, + templates: { + main: '<h1></h1><article><p>test</p><div id="container"></div></article>' + } + }); + } + }; + registerCustomElement2(TestComponent2); + document2 = getDocument(); + done(); + } catch (e) { + done(e); + } + }); + }); + }); + beforeEach(() => { + let mocks = document2.getElementById("mocks"); + mocks.innerHTML = html12; + }); + afterEach(() => { + let mocks = document2.getElementById("mocks"); + mocks.innerHTML = ""; + }); + describe("CustomElement() with Config", function() { + it("should read config from tag", function() { + let mocks = document2.getElementById("mocks"); + mocks.innerHTML = ` + + <script id="config1" type="application/json"> + { + "demotest":1425 + } + <\/script> + + <monster-testclass2 id="thisisatest" data-monster-options-selector="#config1"> + </monster-testclass2> + `; + let monster = document2.getElementById("thisisatest"); + expect7(monster.getOption("demotest")).is.eql(1425); + }); + }); + describe("create", function() { + it("should return custom-element object", function() { + let d2 = new TestComponent(); + expect7(typeof d2).is.equal("object"); + }); + }); + describe("connect empty element", function() { + it("document should contain monster-testclass", function() { + let d2 = document2.createElement("monster-testclass"); + document2.getElementById("test1").appendChild(d2); + expect7(document2.getElementsByTagName("monster-testclass").length).is.equal(1); + expect7(document2.getElementById("test1")).contain.html('<monster-testclass data-monster-error="Error: html is not set."></monster-testclass>'); + }); + }); + describe("connect element with html", function() { + it("document should contain monster-testclass2", function(done) { + let d2 = document2.createElement("monster-testclass2"); + document2.getElementById("test1").appendChild(d2); + setTimeout(function() { + try { + expect7(document2.getElementsByTagName("monster-testclass2").length).is.equal(1); + expect7(document2.getElementsByTagName("monster-testclass2").item(0).shadowRoot.innerHTML).is.equal('<h1></h1><article><p>test</p><div id="container"></div></article>'); + expect7(document2.getElementById("test1")).contain.html('<monster-testclass2 data-monster-objectlink="Symbol(' + updaterSymbolKey + ')"></monster-testclass2>'); + return done(); + } catch (e) { + done(e); + } + }, 10); + }); + }); + describe("Options change", function() { + it("delegatesFocus should change from true to false", function() { + let element = document2.createElement("monster-testclass"); + const o = element[internalSymbol].realSubject; + expect7(Object.is(element[internalSymbol].realSubject, o)).to.be.true; + expect7(element[internalSymbol].realSubject.options.delegatesFocus).to.be.true; + expect7(element[internalSymbol].subject.options.delegatesFocus).to.be.true; + expect7(element.getOption("delegatesFocus")).to.be.true; + expect7(Object.is(element[internalSymbol].realSubject, o)).to.be.true; + }); + }); + describe("setOptions()", function() { + [ + ["shadowMode", "x1"], + ["templates.main", "x2"], + // is explicitly set to undefined + ["delegatesFocus", "x4"] + ].forEach(function(data) { + let key = data.shift(); + let newValue = data.shift(); + let text = key + " should return " + newValue; + if (newValue !== void 0) { + text = key + " was not set, therefore default " + newValue; + } + it(text, function() { + let d2 = document2.createElement("monster-testclass"); + expect7(d2.getOption(key)).to.be.not.equal(newValue); + let x = d2.setOption(key, newValue); + expect7(d2.getOption(key)).to.be.equal(newValue); + }); + }); + }); + describe("getOptions()", function() { + [ + ["shadowMode", "open"], + ["templates.main", void 0], + // is explicitly set to undefined + ["delegatesFocus", true], + ["x.y.z", true, true], + // x.y.z isnt set, defaultValue is used + ["x", true, true] + // x isnt set, defaultValue is used + ].forEach(function(data) { + let key = data.shift(); + let value = data.shift(); + let defaultValue = data.shift(); + let text = key + " should return " + value; + if (defaultValue !== void 0) { + text = key + " was not set, therefore default " + defaultValue; + } + it(text, function() { + let d2 = document2.createElement("monster-testclass"); + let x = d2.getOption(key, defaultValue); + expect7(x).to.be.equal(value); + }); + }); + }); + describe("Assign CSSStyle as Array with wrong type", function() { + const htmlTAG = "monster-testclass-x1"; + let mocks, TestComponentX1; + beforeEach(() => { + mocks = document2.getElementById("mocks"); + mocks.innerHTML = html12; + TestComponentX1 = class extends CustomElement2 { + static getTag() { + return htmlTAG; + } + static getCSSStyleSheet() { + return [true]; + } + /** + * @return {Object} + */ + get defaults() { + return Object.assign({}, super.defaults, { + templates: { + main: "<h1>test</h1>" + } + }); + } + }; + registerCustomElement2(TestComponentX1); + }); + it(htmlTAG + " should throw Exception", function(done) { + let d2 = document2.createElement(htmlTAG); + let div = document2.getElementById("test1"); + div.append(d2); + expect7(div).contain.html('data-monster-error="TypeError: value is not an instance of CSSStyleSheet"'); + done(); + }); + }); + describe("Assign CSSStyle as Array and CSSStylesheet", function() { + const htmlTAG = "monster-testclass-x113-2"; + let mocks, TestComponentX113X2; + beforeEach(() => { + mocks = document2.getElementById("mocks"); + mocks.innerHTML = html12; + TestComponentX113X2 = class extends CustomElement2 { + static getTag() { + return htmlTAG; + } + /** + * @return {Object} + */ + get defaults() { + return Object.assign({}, super.defaults, { + templates: { main: "<h1>test</h1>" } + }); + } + static getCSSStyleSheet() { + const s = new CSSStyleSheet(); + s.insertRule("a { color : red}"); + return [s]; + } + }; + registerCustomElement2(TestComponentX113X2); + }); + it(htmlTAG + " should throw Exception 2", function(done) { + let d2 = document2.createElement(htmlTAG); + let div = document2.getElementById("test1"); + div.append(d2); + expect7(d2.shadowRoot.innerHTML).is.eq("<h1>test</h1>"); + done(); + }); + }); + describe("Assign CSSStyle as Array and CSS as string", function() { + const htmlTAG = "monster-testclass-x113-21"; + let mocks, TestComponentX113X22; + beforeEach(() => { + mocks = document2.getElementById("mocks"); + mocks.innerHTML = html12; + TestComponentX113X22 = class extends CustomElement2 { + static getTag() { + return htmlTAG; + } + /** + * @return {Object} + */ + get defaults() { + return Object.assign({}, super.defaults, { + templates: { main: "<h1>test</h1>" } + }); + } + static getCSSStyleSheet() { + return "a { color:red }"; + } + }; + registerCustomElement2(TestComponentX113X22); + }); + it(htmlTAG + " should eq <style>a { color:red }</style><h1>test</h1>", function(done) { + let d2 = document2.createElement(htmlTAG); + let div = document2.getElementById("test1"); + div.append(d2); + expect7(d2.shadowRoot.innerHTML).is.eq("<style>a { color:red }</style><h1>test</h1>"); + done(); + }); + }); + describe("Assign CSSStyle as Array and CSS as string", function() { + const htmlTAG = "monster-testclass-x113-22"; + let mocks, TestComponentX113X223; + beforeEach(() => { + mocks = document2.getElementById("mocks"); + mocks.innerHTML = html12; + TestComponentX113X223 = class extends CustomElement2 { + static getTag() { + return htmlTAG; + } + /** + * @return {Object} + */ + get defaults() { + return Object.assign({}, super.defaults, { + templates: { main: "<h1>test</h1>" } + }); + } + static getCSSStyleSheet() { + return ["a { color:red }"]; + } + }; + registerCustomElement2(TestComponentX113X223); + }); + it(htmlTAG + " should eq <style>a { color:red }</style><h1>test</h1>", function(done) { + let d2 = document2.createElement(htmlTAG); + let div = document2.getElementById("test1"); + div.append(d2); + expect7(d2.shadowRoot.innerHTML).is.eq("<style>a { color:red }</style><h1>test</h1>"); + done(); + }); + }); + describe("hasNode()", function() { + let mocks; + beforeEach(() => { + mocks = document2.getElementById("mocks"); + mocks.innerHTML = html12; + }); + it("hasNode monster-testclass should return ...", function() { + let d2 = document2.createElement("monster-testclass"); + let p1 = document2.createElement("p"); + let t1 = document2.createTextNode("test1"); + p1.appendChild(t1); + let p = document2.createElement("div"); + let t = document2.createTextNode("test"); + p.appendChild(p1); + p.appendChild(t); + d2.appendChild(p); + let div = document2.getElementById("test1"); + div.append(d2); + let n1 = document2.createElement("p"); + expect7(d2.hasNode(n1)).to.be.false; + expect7(d2.hasNode(t)).to.be.true; + expect7(d2.hasNode(p)).to.be.true; + expect7(d2.hasNode(p1)).to.be.true; + expect7(d2.hasNode(t1)).to.be.true; + }); + it("hasNode monster-testclass2 should return ...", function() { + let d2 = document2.createElement("monster-testclass2"); + let p1 = document2.createElement("p"); + let t1 = document2.createTextNode("test1"); + p1.appendChild(t1); + let p = document2.createElement("div"); + let t = document2.createTextNode("test"); + p.appendChild(p1); + p.appendChild(t); + let div = document2.getElementById("test1"); + div.append(d2); + let a2 = d2.shadowRoot.getElementById("container"); + d2.shadowRoot.getElementById("container").appendChild(p); + let n1 = document2.createElement("p"); + expect7(d2.hasNode(n1)).to.be.false; + expect7(d2.hasNode(t)).to.be.true; + expect7(d2.hasNode(p)).to.be.true; + expect7(d2.hasNode(p1)).to.be.true; + expect7(d2.hasNode(t1)).to.be.true; + }); + }); + }); + }); + + // source/dom/focusmanager.mjs + init_extend(); + init_basewithoptions(); + init_global(); + init_is(); + init_stack(); + init_validate(); + init_constants(); + var KEY_DOCUMENT2 = "document"; + var KEY_CONTEXT = "context"; + var stackSymbol = Symbol("stack"); + var FocusManager = class extends BaseWithOptions { + /** + * + * @param {Object|undefined} options + */ + constructor(options) { + super(options); + validateInstance(this.getOption(KEY_DOCUMENT2), HTMLDocument); + this[stackSymbol] = new Stack(); + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/dom/focusmanager"); + } + /** + * @property {HTMLDocument} document the document object into which the node is to be appended + */ + get defaults() { + return extend({}, super.defaults, { + [KEY_DOCUMENT2]: getGlobalObject("document"), + [KEY_CONTEXT]: void 0 + }); + } + /** + * Remembers the current focus on a stack. + * Several focus can be stored. + * + * @return {Monster.DOM.FocusManager} + */ + storeFocus() { + const active = this.getActive(); + if (active instanceof Node) { + this[stackSymbol].push(active); + } + return this; + } + /** + * The last focus on the stack is set again + * + * @return {Monster.DOM.FocusManager} + */ + restoreFocus() { + const last = this[stackSymbol].pop(); + if (last instanceof Node) { + this.focus(last); + } + return this; + } + /** + * + * @param {Node} element + * @param {boolean} preventScroll + * @throws {TypeError} value is not an instance of + * @return {Monster.DOM.FocusManager} + */ + focus(element, preventScroll) { + validateInstance(element, Node); + element.focus({ + preventScroll: preventScroll ?? false + }); + return this; + } + /** + * + * @return {Element} + */ + getActive() { + return this.getOption(KEY_DOCUMENT2).activeElement; + } + /** + * Select all elements that can be focused + * + * @param {string|undefined} query + * @return {array} + * @throws {TypeError} value is not an instance of + */ + getFocusable(query) { + let contextElement = this.getOption(KEY_CONTEXT); + if (contextElement === void 0) { + contextElement = this.getOption(KEY_DOCUMENT2); + } + validateInstance(contextElement, Node); + if (query !== void 0) { + validateString(query); + } + return [ + ...contextElement.querySelectorAll( + 'details, button, input, [tabindex]:not([tabindex="-1"]), select, textarea, a[href], body' + ) + ].filter((element) => { + if (query !== void 0 && !element.matches(query)) { + return false; + } + if (element.hasAttribute("disabled")) + return false; + if (element.getAttribute("aria-hidden") === "true") + return false; + const rect = element.getBoundingClientRect(); + if (rect.width === 0) + return false; + if (rect.height === 0) + return false; + return true; + }); + } + /** + * @param {string} query + * @return {Monster.DOM.FocusManager} + */ + focusNext(query) { + const current = this.getActive(); + const focusable = this.getFocusable(query); + if (!isArray(focusable) || focusable.length === 0) { + return this; + } + if (current instanceof Node) { + let index = focusable.indexOf(current); + if (index > -1) { + this.focus(focusable[index + 1] || focusable[0]); + } else { + this.focus(focusable[0]); + } + } else { + this.focus(focusable[0]); + } + return this; + } + /** + * @param {string} query + * @return {Monster.DOM.FocusManager} + */ + focusPrev(query) { + const current = this.getActive(); + const focusable = this.getFocusable(query); + if (!isArray(focusable) || focusable.length === 0) { + return this; + } + if (current instanceof Node) { + let index = focusable.indexOf(current); + if (index > -1) { + this.focus(focusable[index - 1] || focusable[focusable.length - 1]); + } else { + this.focus(focusable[focusable.length - 1]); + } + } else { + this.focus(focusable[focusable.length - 1]); + } + return this; + } + }; + + // test/cases/dom/focusmanager.mjs + describe("FocusManager", function() { + before(function(done) { + initJSDOM().then(() => { + done(); + }); + }); + beforeEach(() => { + initMutationObserverForTesting(); + }); + afterEach(() => { + cleanupDOMFromTesting(); + document.getElementById("mocks").innerHTML = ""; + }); + describe("new", function() { + it("should instance of FocusManager", function() { + expect(new FocusManager()).is.instanceof(FocusManager); + }); + }); + describe("store and restore", function() { + let manager; + beforeEach(() => { + manager = new FocusManager(); + document.getElementById("mocks").innerHTML = ` + <input class="testit" id="tx1"> + <input class="testit" id="tx2"> + <input class="testit" id="tx3" disabled> + <input class="testit" id="tx4"> + <p class="testit" tabindex="2" id="tx5">hello</p> + <input class="testit" id="tx6" aria-hidden="true"> + <button class="testit" id="tx7"></button> + `; + for (const [, element] of Object.entries(document.querySelectorAll(".testit"))) { + element.getBoundingClientRect = () => ({ + width: 200, + height: 200, + top: 0, + left: 0, + right: 200, + bottom: 200 + }); + } + }); + it("run ist", function() { + manager.focus(document.getElementById("tx1")); + manager.storeFocus(); + const e1 = manager.getActive(); + expect(e1.getAttribute("id"), "error1").to.be.equal("tx1"); + manager.focus(document.getElementById("tx2")); + manager.storeFocus(); + expect(manager.getActive().getAttribute("id"), "error2").to.be.equal("tx2"); + manager.focusNext(); + expect(manager.getActive().getAttribute("id"), "error3").to.be.equal("tx4"); + manager.focusNext(); + expect(manager.getActive().getAttribute("id"), "error4").to.be.equal("tx5"); + manager.restoreFocus(); + expect(manager.getActive().getAttribute("id"), "error5").to.be.equal("tx2"); + manager.restoreFocus(); + expect(manager.getActive().getAttribute("id"), "error6").to.be.equal("tx1"); + manager.restoreFocus(); + expect(manager.getActive().getAttribute("id"), "error7").to.be.equal("tx1"); + }); + }); + describe("returntype", function() { + let focusmanager; + beforeEach(() => { + focusmanager = new FocusManager(); + }); + it("check returns", function() { + expect(focusmanager.getFocusable()).is.instanceof(Array); + expect(focusmanager.getActive()).is.instanceof(HTMLElement); + expect(focusmanager.focusNext()).is.instanceof(FocusManager); + expect(focusmanager.focusPrev()).is.instanceof(FocusManager); + expect(focusmanager.storeFocus()).is.instanceof(FocusManager); + expect(focusmanager.focus(document.body)).is.instanceof(FocusManager); + expect(focusmanager.restoreFocus()).is.instanceof(FocusManager); + }); + }); + }); + + // test/cases/dom/find.mjs + init_util(); + function setupTestEnvironment() { + class TestComponent extends HTMLElement { + constructor() { + super(); + this.attachShadow({ mode: "open" }); + } + } + if (!customElements.get("test-component")) { + customElements.define("test-component", TestComponent); + } + } + function cleanupTestEnvironment() { + let mocks = document.getElementById("mocks"); + mocks.innerHTML = ""; + } + describe("findElementWithIdUpwards", () => { + before((done) => { + initJSDOM().then(() => { + setupTestEnvironment(); + done(); + }); + }); + after(() => { + cleanupTestEnvironment(); + }); + beforeEach(() => { + let mocks = document.getElementById("mocks"); + mocks.innerHTML = ` + <div id="container"> + <div id="parent"> + <div id="child"></div> + </div> + </div>`; + const shadowHost = document.createElement("div"); + document.body.appendChild(shadowHost); + const shadowRoot = shadowHost.attachShadow({ mode: "open" }); + const innerElement = document.createElement("div"); + innerElement.id = "inner"; + shadowRoot.appendChild(innerElement); + }); + it("should find the element with the target ID in the normal DOM", () => { + const child = document.getElementById("child"); + const result = findElementWithIdUpwards(child, "parent"); + expect(result).to.equal(document.getElementById("parent")); + }); + it("should find the element with the target ID in the shadow DOM", () => { + const innerElement = document.querySelector("div[shadowroot] > div"); + const result = findElementWithIdUpwards(innerElement, "inner"); + expect(result).to.equal(innerElement); + }); + it("should return null if the element with the target ID is not found", () => { + const child = document.getElementById("child"); + const result = findElementWithIdUpwards(child, "nonexistent"); + expect(result).to.be.null; + }); + }); + + // test/cases/dom/ready.mjs + var windowReady2; + var domReady2; + describe("Ready", function() { + before(function(done) { + initJSDOM().then(() => { + Promise.resolve().then(() => (init_ready(), ready_exports)).then((m) => { + domReady2 = m["domReady"]; + windowReady2 = m["windowReady"]; + done(); + }); + }); + }); + describe("domReady", function() { + it("resolve promise", function(done) { + domReady2.then(done).catch((e) => done(e)); + }); + }); + describe("windowReady", function() { + it("resolve promise", function(done) { + windowReady2.then(done).catch((e) => done(e)); + }); + }); + }); + + // test/cases/dom/util.mjs + init_util(); + init_util(); + describe("DOM", function() { + before(async function() { + initJSDOM(); + }); + describe("getDocument()", function() { + it("should return document object", function() { + let d2 = getDocument(); + expect(typeof d2).is.equal("object"); + }); + }); + describe("getWindow()", function() { + it("should return document object", function() { + let d2 = getWindow(); + expect(typeof d2).is.equal("object"); + }); + }); + describe("getDocumentFragmentFromString()", function() { + [ + ["<div></div>"], + ["<div><div>2</div></div>"], + ["<div><div>2</div>", "<div><div>2</div></div>"] + // test invalid html + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + if (!b) + b = a2; + it("should return documentFragment object " + a2, function() { + let fragment = getDocumentFragmentFromString(a2); + expect(fragment).to.be.instanceOf(DocumentFragment); + var div = document.createElement("div"); + div.appendChild(fragment.cloneNode(true)); + expect(div.innerHTML).to.be.equal(b); + }); + }); + }); + describe("getContainingDocument", () => { + let jsDomDocument; + beforeEach(() => { + jsDomDocument = getDocument(); + }); + it("should throw an error when called with an invalid argument", () => { + expect(() => getContainingDocument(null)).to.throw("Invalid argument. Expected an HTMLElement."); + }); + it("should return the correct containing document for an element in the main document", () => { + const element = jsDomDocument.createElement("div"); + const containingDocument = getContainingDocument(element); + expect(containingDocument).to.null; + }); + it("should return the correct containing document for an element inside a shadow root", () => { + const host = jsDomDocument.createElement("div"); + const shadowRoot = host.attachShadow({ mode: "open" }); + const element = jsDomDocument.createElement("span"); + shadowRoot.appendChild(element); + const containingDocument = getContainingDocument(element); + expect(containingDocument).to.not.null; + }); + it("should return the correct containing document for an element inside a nested shadow root", () => { + const outerHost = jsDomDocument.createElement("div"); + const outerShadowRoot = outerHost.attachShadow({ mode: "open" }); + const innerHost = jsDomDocument.createElement("div"); + outerShadowRoot.appendChild(innerHost); + const innerShadowRoot = innerHost.attachShadow({ mode: "open" }); + const element = jsDomDocument.createElement("span"); + innerShadowRoot.appendChild(element); + const containingDocument = getContainingDocument(element); + expect(containingDocument).to.not.null; + }); + it("should return null when the element is not attached to any document", () => { + const detachedElement = jsDomDocument.createElement("div"); + detachedElement.remove(); + const containingDocument = getContainingDocument(detachedElement); + expect(containingDocument).to.be.null; + }); + }); + }); + + // test/cases/dom/customelement-initfromscripthost.mjs + init_util(); + var expect8 = chai_default.expect; + chai_default.use(chaiDom); + describe("DOM", function() { + let CustomElement2, registerCustomElement2, TestComponent, document2, TestComponent2, assignUpdaterToElement; + describe("initFromScriptHost()", function() { + const randomTagNumber = "monster-test" + Math.floor(Math.random() * 1e6); + before(function(done) { + initJSDOM().then(() => { + Promise.resolve().then(() => (init_customelement(), customelement_exports)).then((m) => { + try { + CustomElement2 = m["CustomElement"]; + registerCustomElement2 = m["registerCustomElement"]; + TestComponent2 = class extends CustomElement2 { + static getTag() { + return randomTagNumber; + } + /** + * + * @return {Object} + */ + get defaults() { + return Object.assign({}, super.defaults, { + test: 0, + templates: { + main: '<h1></h1><article><p>test</p><div id="container"></div></article>' + } + }); + } + }; + registerCustomElement2(TestComponent2); + document2 = getDocument(); + done(); + } catch (e) { + done(e); + } + }).catch((e) => { + done(e); + }); + }); + }); + afterEach(() => { + let mocks = document2.getElementById("mocks"); + mocks.innerHTML = ""; + }); + describe("call callback", function() { + it("should not found callback and add error attribute", function() { + let mocks = document2.getElementById("mocks"); + mocks.innerHTML = `<div id="call-back-host"></div><div id="container"></div>`; + let control = document2.createElement(randomTagNumber); + control.setAttribute("data-monster-script-host", "call-back-host"); + document2.getElementById("container").appendChild(control); + expect8(control.getOption("test")).is.eql(0); + expect8(control.hasAttribute("data-monster-error")).is.true; + }); + it("should found callback initCustomControlCallback", function() { + let mocks = document2.getElementById("mocks"); + mocks.innerHTML = `<div id="call-back-host"></div><div id="container"></div>`; + const container = document2.getElementById("call-back-host"); + container.initCustomControlCallback = function(control2) { + control2.setOption("test", 1); + }; + let control = document2.createElement(randomTagNumber); + control.setAttribute("data-monster-script-host", "call-back-host"); + document2.getElementById("container").appendChild(control); + expect8(control.getOption("test")).is.eql(1); + expect8(control.hasAttribute("data-monster-error")).is.false; + }); + it("should found callback initCustomControlCallback from self", function() { + let mocks = document2.getElementById("mocks"); + mocks.innerHTML = `<div id="call-back-host"></div><div id="container"></div>`; + let control = document2.createElement(randomTagNumber); + expect8(control.getOption("test")).is.eql(0); + control.initCustomControlCallback = function(control2) { + control2.setOption("test", 2); + }; + control.setAttribute("data-monster-script-host", "call-back-host"); + document2.getElementById("container").appendChild(control); + expect8(control.getOption("test")).is.eql(2); + expect8(control.hasAttribute("data-monster-error")).is.false; + }); + }); + }); + }); + + // test/cases/dom/slotted-nodes.mjs + init_slotted(); + describe("getSlottedNodes", () => { + it("should return an empty Set if there is no ShadowRoot", () => { + expect(getSlottedNodes).is.a("function"); + }); + }); + + // test/cases/dom/attributes.mjs + init_attributes(); + var html13; + var html23; + var html32; + describe("Attributes", function() { + before(function(done) { + html13 = `<div id="test1"></div>`; + html23 = `<div id="test1"> + <div id="sub1"> + <div id="sub2"> + <div id="sub3"> + <div id="sub4"> + <div id="sub5"></div> + </div> + </div> + </div> + </div> +</div> +`; + html32 = `<div data-monster-role="test1"> + <div data-monster-role="sub1" id="a1" class="sub1"> + <div data-monster-role="sub2" id="a2" class="sub2"> + <div data-monster-role="sub3" id="a3" class="sub3"> + <div data-monster-role="sub4" id="a4" class="sub4"> + <div data-monster-role="sub5" id="a5" class="sub5"></div> + </div> + </div> + </div> + </div> +</div> +`; + initJSDOM().then(() => { + done(); + }).catch((e) => done(e)); + }); + describe("ObjectLink", function() { + const symbol2 = Symbol("mytest"); + beforeEach(() => { + let mocks = document.getElementById("mocks"); + mocks.innerHTML = html13; + }); + afterEach(() => { + let mocks = document.getElementById("mocks"); + mocks.innerHTML = ""; + }); + it("should handle object-links", function() { + let obj = { a: 1 }; + let element = document.getElementById("test1"); + expect(hasObjectLink(element, symbol2)).to.be.false; + addToObjectLink(element, symbol2, obj); + expect(hasObjectLink(element, symbol2)).to.be.true; + let o = getLinkedObjects(element, symbol2).next(); + expect(o.value).to.equal(obj); + removeObjectLink(element, symbol2); + expect(hasObjectLink(element, symbol2)).to.be.false; + expect(() => getLinkedObjects(element, symbol2)).to.throw(Error); + }); + }); + describe("findClosestObjectLink()", function() { + const symbol2 = Symbol("mytest"); + beforeEach(() => { + let mocks = document.getElementById("mocks"); + mocks.innerHTML = html23; + }); + afterEach(() => { + let mocks = document.getElementById("mocks"); + mocks.innerHTML = ""; + }); + it("should return objectlink", function() { + let sub4 = document.getElementById("sub4"); + let sub2 = document.getElementById("sub2"); + let obj = {}; + expect(hasObjectLink(sub2, symbol2)).to.be.false; + addToObjectLink(sub2, symbol2, obj); + expect(hasObjectLink(sub2, symbol2)).to.be.true; + let element = findClosestObjectLink(sub4); + expect(element).is.instanceOf(HTMLDivElement); + expect(element.getAttribute("id")).to.be.equal("sub2"); + }); + }); + describe("Attributes", function() { + beforeEach(() => { + let mocks = document.getElementById("mocks"); + mocks.innerHTML = html32; + }); + afterEach(() => { + let mocks = document.getElementById("mocks"); + mocks.innerHTML = ""; + }); + describe("find closest Attributes", function() { + [ + ["a5", "data-monster-role", void 0, "sub5"], + ["a5", "data-monster-role", "sub3", "sub3"], + ["a5", "data-monster-role", "sub1", "sub1"], + ["a4", "data-monster-role", "sub1", "sub1"], + ["a3", "data-monster-role", "sub1", "sub1"], + ["a2", "data-monster-role", void 0, "sub2"], + ["a5", "data-monster-role", "sub5", "sub5"] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + let c = data.shift(); + let d2 = data.shift(); + it("findClosestByAttribute(" + a2 + ", " + b + "," + c + ") should return " + d2, function() { + expect(findClosestByAttribute(document.getElementById(a2), b, c).getAttribute("data-monster-role")).to.be.equal(d2); + }); + }); + }); + describe("find closest Element with class", function() { + [ + ["a5", "sub3", "sub3"], + ["a5", "sub1", "sub1"], + ["a4", "sub1", "sub1"], + ["a3", "sub1", "sub1"], + ["a5", "sub5", "sub5"] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + let c = data.shift(); + it("findClosestByClass(" + a2 + ", " + b + ") should return " + c, function() { + expect(findClosestByClass(document.getElementById(a2), b).getAttribute("class")).to.be.equal(c); + }); + }); + }); + }); + describe("Attributes", function() { + beforeEach(() => { + let mocks = document.getElementById("mocks"); + mocks.innerHTML = html13; + }); + afterEach(() => { + let mocks = document.getElementById("mocks"); + mocks.innerHTML = ""; + }); + const atributeKey = "data-test"; + it("toggleAttributeToken(element, key, value)", function() { + let element = document.getElementById("test1"); + expect(element.hasAttribute(atributeKey)).to.be.false; + element.setAttribute(atributeKey, "apple bananna"); + toggleAttributeToken(element, atributeKey, "pinapple"); + expect(element.getAttribute(atributeKey)).to.be.equal("apple bananna pinapple"); + toggleAttributeToken(element, atributeKey, "pinapple"); + expect(element.getAttribute(atributeKey)).to.be.equal("apple bananna"); + }); + it("addAttributeToken(element, key, value)", function() { + let element = document.getElementById("test1"); + expect(element.hasAttribute(atributeKey)).to.be.false; + addAttributeToken(element, atributeKey, "pinapple"); + expect(element.getAttribute(atributeKey)).to.be.equal("pinapple"); + addAttributeToken(element, atributeKey, "bananna"); + expect(element.getAttribute(atributeKey)).to.be.equal("pinapple bananna"); + }); + it("removeAttributeToken(element, key, value)", function() { + let element = document.getElementById("test1"); + element.setAttribute(atributeKey, "apple bananna lemmon"); + removeAttributeToken(element, atributeKey, "pinapple"); + expect(element.getAttribute(atributeKey)).to.be.equal("apple bananna lemmon"); + removeAttributeToken(element, atributeKey, "bananna"); + expect(element.getAttribute(atributeKey)).to.be.equal("apple lemmon"); + }); + it("containsAttributeToken(element, key, value)", function() { + let element = document.getElementById("test1"); + expect(containsAttributeToken(element, atributeKey, "pinapple")).to.be.false; + element.setAttribute(atributeKey, "apple bananna"); + expect(containsAttributeToken(element, atributeKey, "pinapple")).to.be.false; + expect(containsAttributeToken(element, atributeKey, "bananna")).to.be.true; + expect(containsAttributeToken(element, atributeKey, "apple")).to.be.true; + }); + it(" replaceAttributeToken(element, key, value)", function() { + let element = document.getElementById("test1"); + element.setAttribute(atributeKey, "apple bananna tomato"); + replaceAttributeToken(element, atributeKey, "tomato", "lemmon"); + expect(element.getAttribute(atributeKey)).to.be.equal("apple bananna lemmon"); + replaceAttributeToken(element, atributeKey, "bananna", "pear"); + expect(element.getAttribute(atributeKey)).to.be.equal("apple pear lemmon"); + }); + it("clearAttributeTokens(element, key)", function() { + let element = document.getElementById("test1"); + element.setAttribute(atributeKey, "apple bananna"); + clearAttributeTokens(element, atributeKey); + expect(element.getAttribute(atributeKey)).to.be.equal(""); + }); + }); + }); + + // test/cases/dom/resource.mjs + var Resource2; + var DerivedResource; + describe("Resource", function() { + before(function(done) { + initJSDOM().then(() => { + Promise.resolve().then(() => (init_resource(), resource_exports)).then((m) => { + Resource2 = m["Resource"]; + DerivedResource = class extends Resource2 { + constructor() { + super({ + "data-url": "http://example.com" + }); + } + static getURLAttribute() { + return "data-url"; + } + }; + done(); + }); + }); + }); + describe("DerivedResource", function() { + it("should instanceof Resource", function() { + expect(new DerivedResource()).to.be.an.instanceof(Resource2); + }); + }); + }); + + // source/dom/resourcemanager.mjs + init_extend(); + init_base(); + init_global(); + + // source/types/internal.mjs + init_constants(); + init_extend(); + init_pathfinder(); + init_dataurl(); + init_is(); + init_observer(); + init_proxyobserver(); + init_validate(); + init_is(); + var propertyName = "internalDefaults"; + function equipWithInternal() { + const self2 = this; + validateObject(self2); + if (!hasGetter(self2, propertyName)) { + Object.defineProperty(self2, propertyName, { + get: function() { + return {}; + } + }); + } + const defaults = extend({}, self2[propertyName] || {}); + self2[internalSymbol] = new ProxyObserver(defaults); + self2["attachInternalObserver"] = (observer) => { + self2[internalSymbol].attachObserver(observer); + return self2; + }; + self2["detachInternalObserver"] = (observer) => { + self2[internalSymbol].detachObserver(observer); + return self2; + }; + self2["containsInternalObserver"] = (observer) => { + return self2[internalSymbol].containsObserver(observer); + }; + self2["setInternal"] = (path, value) => { + new Pathfinder(self2[internalSymbol].getSubject()).setVia(path, value); + return self2; + }; + self2["setInternals"] = (options) => { + if (isString(options)) { + options = parseOptionsJSON2(options); + } + extend(self2[internalSymbol].getSubject(), defaults, options); + return self2; + }; + self2["getInternal"] = (path, defaultValue) => { + let value; + try { + value = new Pathfinder(self2[internalSymbol].getRealSubject()).getVia(path); + } catch (e) { + } + if (value === void 0) + return defaultValue; + return value; + }; + } + function hasGetter(obj, prop) { + while (isObject(obj)) { + if (Object.getOwnPropertyDescriptor(obj, prop)?.["get"]) { + return true; + } + obj = Object.getPrototypeOf(obj); + } + return false; + } + function parseOptionsJSON2(data) { + let obj = {}; + if (!isString(data)) { + return obj; + } + try { + let dataUrl = parseDataURL(data); + data = dataUrl.content; + } catch (e) { + } + try { + obj = JSON.parse(data); + } catch (e) { + throw e; + } + return validateObject(obj); + } + + // source/dom/resourcemanager.mjs + init_is(); + init_constants2(); + init_resource(); + var ResourceManager = class extends Base { + /** + * + * @param {Object} options + * throw {Error} unsupported document type + */ + constructor(options) { + super(options); + equipWithInternal.call(this); + if (!(this.getOption("document") instanceof Document)) { + throw new Error("unsupported document type"); + } + } + /** + * @deprecated since 3.15.0 use getInternal instead + * @property {string} baseurl + */ + getOption(key) { + return this.getInternal(key); + } + /** + * @property {string} baseurl + */ + getBaseURL() { + this.getOption("document")?.baseURL; + } + /** + * @property {string} baseurl + * @deprecated since 3.15.0 use internalDefaults instead + */ + get defaults() { + return this.internalDefaults; + } + /** + * + * @property {HTMLDocument} document=document Document + * @property {Object} resources + * @property {Array} resources.scripts=[] array with {@link Monster.DOM.Resource.Script} objects + * @property {Array} resources.stylesheets=[] array with {@link Monster.DOM.Resource.Link.Stylesheet} objects + * @property {Array} resources.data=[] array with {@link Monster.DOM.Resource.Data} objects + */ + get internalDefaults() { + return Object.assign( + {}, + { + document: getGlobalObject("document"), + resources: { + scripts: [], + stylesheets: [], + data: [] + } + } + ); + } + /** + * Append Tags to DOM + * + * @return {Monster.DOM.ResourceManager} + * @throws {Error} unsupported resource definition + */ + connect() { + runResourceMethod.call(this, "connect"); + return this; + } + /** + * Check if available + * + * @return {Promise} + * @throws {Error} unsupported resource definition + */ + available() { + return Promise.all(runResourceMethod.call(this, "available")); + } + /** + * Add a script + * + * @param {string|URL} url + * @param [Object|undefined} options + * @return {Monster.DOM.ResourceManager} + * @see Monster.DOM.Resource.Script + */ + addScript(url, options) { + return addResource.call(this, "scripts", url, options); + } + /** + * Add Stylesheet + * + * @param {string|URL} url + * @param [Object|undefined} options + * @return {Monster.DOM.ResourceManager} + * @see Monster.DOM.Resource.Link.Stylesheet + */ + addStylesheet(url, options) { + return addResource.call(this, "stylesheets", url, options); + } + /** + * Add Data Tag + * + * @param {string|URL} url + * @param [Object|undefined} options + * @return {Monster.DOM.ResourceManager} + * @see Monster.DOM.Resource.Data + */ + addData(url, options) { + return addResource.call(this, "data", url, options); + } + }; + function runResourceMethod(method) { + const self2 = this; + const result = []; + for (const type of ["scripts", "stylesheets", "data"]) { + const resources = self2.getOption(`resources.${type}`); + if (!isArray(resources)) { + continue; + } + for (const resource of resources) { + if (!(resource instanceof Resource)) { + throw new Error("unsupported resource definition"); + } + result.push(resource[method]()); + } + } + return result; + } + function addResource(type, url, options) { + const self2 = this; + if (url instanceof URL) { + url = url.toString(); + } + options = options || {}; + let resource; + switch (type) { + case "scripts": + resource = new Script(extend({}, options, { [ATTRIBUTE_SRC]: url })); + break; + case "stylesheets": + resource = new Stylesheet(extend({}, options, { [ATTRIBUTE_HREF]: url })); + break; + case "data": + resource = new Data(extend({}, options, { [ATTRIBUTE_SRC]: url })); + break; + default: + throw new Error(`unsupported type ${type}`); + } + self2.getOption("resources")?.[type].push(resource); + return self2; + } + + // test/cases/dom/resourcemanager.mjs + describe("ResourceManager", function() { + let fetchReference2, returnStatus; + before(function(done) { + initJSDOM().then(() => { + done(); + }).catch((e) => done(e)); + }); + afterEach(() => { + globalThis["fetch"] = fetchReference2; + cleanupDOMFromTesting(); + }); + beforeEach(() => { + initMutationObserverForTesting(); + returnStatus = 200; + fetchReference2 = globalThis["fetch"]; + globalThis["fetch"] = function(url, options) { + if (!url) + throw new Error("missing url"); + return new Promise((resolve, reject) => { + resolve({ + text: function() { + return JSON.stringify({ + a: "test" + }); + }, + status: returnStatus + }); + }); + }; + }); + describe("new", function() { + it("new ResourceManager() should return ResourceManager object", function() { + let d2 = new ResourceManager(); + expect(d2).to.be.instanceOf(ResourceManager); + }); + }); + describe("load resources", function() { + let manager; + beforeEach(() => { + manager = new ResourceManager(); + }); + it("add script should instance of ResourceManager", function() { + expect(manager.addScript("/example.js")).to.be.instanceOf(ResourceManager); + }); + it("add style should instance of ResourceManager", function() { + expect(manager.addStylesheet("/style.js")).to.be.instanceOf(ResourceManager); + }); + it("add data should instance of ResourceManager", function() { + expect(manager.addData("/data.json")).to.be.instanceOf(ResourceManager); + }); + describe("connect resources", function() { + it("add script and connect should instance of ResourceManager", function() { + expect(manager.addScript("/example.js").connect()).to.be.instanceOf(ResourceManager); + }); + it("add style and connect should instance of ResourceManager", function() { + expect(manager.addStylesheet("/style.js").connect()).to.be.instanceOf(ResourceManager); + }); + it("add data and connect should instance of ResourceManager", function() { + expect(manager.addData("/data.json").connect()).to.be.instanceOf(ResourceManager); + }); + }); + describe("check availability resources", function() { + it("add script and check availability should return Promise", function() { + expect(manager.addScript("/example.js").available()).to.be.instanceOf(Promise); + }); + it("add style and check availability should should return Promise", function() { + expect(manager.addStylesheet("/style.js").available()).to.be.instanceOf(Promise); + }); + it("add data and check availability should should return Promise", function() { + expect(manager.addData("/data.json").available()).to.be.instanceOf(Promise); + }); + }); + describe("check availability example.json", function() { + it("add data and check content", function(done) { + manager.addData("https://example.com/example.json").connect().available().then((r) => { + expect(document.querySelector("html").outerHTML).contains('>{"a":"test"}<\/script></head>'); + done(); + }).catch((e) => done(e)); + }); + }); + }); + }); + + // source/dom/assembler.mjs + init_base(); + init_global(); + init_proxyobserver(); + init_validate(); + var ATTRIBUTEPREFIX = "data-monster-"; + var Assembler = class extends Base { + /** + * @param {DocumentFragment} fragment + * @throws {TypeError} value is not an instance of + * @throws {TypeError} value is not a function + * @throws {Error} the function is not defined + */ + constructor(fragment) { + super(); + this.attributePrefix = ATTRIBUTEPREFIX; + validateInstance(fragment, getGlobalFunction("DocumentFragment")); + this.fragment = fragment; + } + /** + * + * @param {string} prefix + * @returns {Assembler} + * @throws {TypeError} value is not a string + */ + setAttributePrefix(prefix) { + validateString(prefix); + this.attributePrefix = prefix; + return this; + } + /** + * + * @returns {string} + */ + getAttributePrefix() { + return this.attributePrefix; + } + /** + * + * @param {ProxyObserver|undefined} data + * @return {DocumentFragment} + * @throws {TypeError} value is not an instance of + */ + createDocumentFragment(data) { + if (data === void 0) { + data = new ProxyObserver({}); + } + validateInstance(data, ProxyObserver); + let fragment = this.fragment.cloneNode(true); + return fragment; + } + }; + + // test/cases/dom/assembler.mjs + describe("Assembler", function() { + before(async function() { + initJSDOM(); + }); + describe("createDocumentFragment()", function() { + it("should return <div>One</div><div>Two</div>", function() { + let fragment = document.createRange().createContextualFragment("<div>One</div><div>Two</div>"); + let f = new Assembler(fragment); + let container = document.createElement("div"); + container.appendChild(f.createDocumentFragment().cloneNode(true)); + expect(container.innerHTML).to.be.equal("<div>One</div><div>Two</div>"); + }); + }); + describe("createDocumentFragment()", function() { + it("should return DocumentFragment object", function() { + let d2 = new Assembler(document.createDocumentFragment()); + expect(d2.createDocumentFragment()).to.be.instanceOf(DocumentFragment); + }); + }); + describe("new", function() { + it("new Renderer() should return Assembler object", function() { + let d2 = new Assembler(document.createDocumentFragment()); + expect(d2).to.be.instanceOf(Assembler); + }); + }); + describe("getAttributePrefix()", function() { + it("should return " + ATTRIBUTEPREFIX, function() { + let d2 = new Assembler(document.createDocumentFragment()); + expect(d2.getAttributePrefix()).to.be.equal(ATTRIBUTEPREFIX); + }); + }); + describe("setAttributePrefix().getAttributePrefix()", function() { + it("should return same value", function() { + let d2 = new Assembler(document.createDocumentFragment()); + expect(d2.setAttributePrefix("test01").getAttributePrefix()).to.be.equal("test01"); + }); + }); + }); + + // test/cases/dom/customcontrol.mjs + init_constants2(); + init_util(); + var expect9 = chai_default.expect; + chai_default.use(chaiDom); + var html14 = ` + <div id="test1"> + </div> +`; + describe("DOM", function() { + let CustomControl2, registerCustomElement2, TestComponent, document2, jsdomFlag; + before(function(done) { + initJSDOM().then(() => { + Promise.resolve().then(() => (init_dist(), dist_exports)).then((m) => { + m.polyfill(); + }); + jsdomFlag = navigator.userAgent.includes("jsdom"); + Promise.resolve().then(() => (init_customelement(), customelement_exports)).then((m) => { + registerCustomElement2 = m["registerCustomElement"]; + Promise.resolve().then(() => (init_customcontrol(), customcontrol_exports)).then((m2) => { + document2 = getDocument(); + try { + CustomControl2 = m2["CustomControl"]; + TestComponent = class extends CustomControl2 { + static getTag() { + return "monster-customcontrol"; + } + }; + registerCustomElement2(TestComponent); + done(); + } catch (e) { + done(e); + } + }); + }); + }); + }); + describe("CustomControl()", function() { + beforeEach(() => { + initMutationObserverForTesting(); + let mocks = document2.getElementById("mocks"); + mocks.innerHTML = html14; + }); + afterEach(() => { + let mocks = document2.getElementById("mocks"); + mocks.innerHTML = ""; + cleanupDOMFromTesting(); + }); + describe("create", function() { + it("should return custom-element object", function() { + try { + let d2 = new TestComponent(); + } catch (e) { + expect9(e).to.be.not.null; + } + expect9(typeof d).is.equal("undefined"); + }); + }); + describe("connect empty element", function() { + it("document should contain monster-customcontrol", function() { + let d2 = document2.createElement("monster-customcontrol"); + document2.getElementById("test1").appendChild(d2); + expect9(document2.getElementsByTagName("monster-customcontrol").length).is.equal(1); + expect9(document2.getElementById("test1")).contain.html('<monster-customcontrol data-monster-error="Error: html is not set."></monster-customcontrol>'); + }); + }); + describe("Test ElementInternals", function() { + let form; + beforeEach(() => { + form = document2.createElement("form"); + }); + it("formAssociated", function() { + let d2 = document2.createElement("monster-customcontrol"); + form.appendChild(d2); + expect9(d2.constructor.formAssociated).to.be.true; + }); + it("form", function() { + let d2 = document2.createElement("monster-customcontrol"); + form.appendChild(d2); + expect9(d2.form).to.be.instanceof(HTMLFormElement); + }); + it("value getter", function() { + let d2 = document2.createElement("monster-customcontrol"); + form.appendChild(d2); + expect9(() => d2.value).to.throw(Error); + }); + it("value setter", function() { + let d2 = document2.createElement("monster-customcontrol"); + form.appendChild(d2); + expect9(() => d2.value = 4).to.throw(Error); + }); + it("setFormValue", function() { + let d2 = document2.createElement("monster-customcontrol"); + form.appendChild(d2); + }); + it("name getter", function() { + let d2 = document2.createElement("monster-customcontrol"); + form.appendChild(d2); + expect9(d2.name).to.be.null; + }); + it("type getter", function() { + let d2 = document2.createElement("monster-customcontrol"); + form.appendChild(d2); + expect9(d2.type).to.be.equal("monster-customcontrol"); + }); + it("validity getter", function() { + let d2 = document2.createElement("monster-customcontrol"); + form.appendChild(d2); + }); + it("validationMessage getter", function() { + let d2 = document2.createElement("monster-customcontrol"); + form.appendChild(d2); + }); + it("willValidate getter", function() { + let d2 = document2.createElement("monster-customcontrol"); + form.appendChild(d2); + }); + it("checkValidity()", function() { + let d2 = document2.createElement("monster-customcontrol"); + form.appendChild(d2); + }); + it("reportValidity()", function() { + let d2 = document2.createElement("monster-customcontrol"); + form.appendChild(d2); + }); + it("setValidity()", function() { + let d2 = document2.createElement("monster-customcontrol"); + form.appendChild(d2); + expect9(d2.setValidity({ "valueMissing": true }, "my message")).to.be.undefined; + }); + }); + }); + }); + + // test/cases/dom/template.mjs + init_constants2(); + init_template(); + describe("Template", function() { + before(async function() { + initJSDOM(); + }); + beforeEach(() => { + let mocks = document.getElementById("mocks"); + mocks.innerHTML = ` + <template id="mytemplate"></template>`; + }); + afterEach(() => { + let mocks = document.getElementById("mocks"); + mocks.innerHTML = ""; + }); + describe("create HTMLFragment", function() { + [ + ["<div>first</div><div>second</div>"], + ["<div>first</div>"], + ["<div>first</div><p>second</p>"] + ].forEach(function(data) { + let a2 = data.shift(); + it("new Template().getNewDocumentFragmentAsString() should return string", function() { + let template = document.createElement("template"); + template.innerHTML = a2; + let t = new Template(template); + var container = document.createElement("div"); + container.appendChild(t.createDocumentFragment()); + expect(container.innerHTML).to.be.equal(a2); + }); + }); + }); + describe("create instance", function() { + it("new Template() should return document object", function() { + let d2 = new Template(document.createElement("template")); + expect(d2).to.be.instanceOf(Template); + }); + }); + describe(".getTemplateElement()", function() { + it("new Template().getTemplateElement() should return HTMLTemplateElement object", function() { + let d2 = new Template(document.createElement("template")); + expect(d2.getTemplateElement()).to.be.instanceOf(HTMLTemplateElement); + }); + }); + describe(".findDocumentTemplate()", function() { + it("should throw Template not found", function() { + const div = document.createElement("div"); + expect(() => { + findDocumentTemplate("noway", div); + }).to.throws(Error); + }); + }); + describe(".findDocumentTemplate()", function() { + describe("Template", function() { + it("should find template over ownerDocument", function() { + const div = document.createElement("div"); + div.remove(); + let t = findDocumentTemplate("mytemplate", div); + expect(t).is.instanceof(Template); + }); + }); + describe("Thmened Template", function() { + let memAttributeValue; + beforeEach(() => { + let mocks = document.getElementById("mocks"); + mocks.innerHTML = ` + <template id="mytemplate"><p>1</p></template> + <template id="mytemplate-monster"><p>2</p></template> + <template id="mytemplate-testtheme"><p>4</p></template> + <template id="myprefix-mytemplate-monster"><p>3</p></template> + `; + let html = document.querySelector("html"); + if (html.hasAttribute(ATTRIBUTE_THEME_NAME)) { + memAttributeValue = html.getAttribute(ATTRIBUTE_THEME_NAME); + } + }); + afterEach(() => { + let mocks = document.getElementById("mocks"); + mocks.innerHTML = ""; + let html = document.querySelector("html"); + if (html.hasAttribute(ATTRIBUTE_THEME_NAME)) { + html.removeAttribute(ATTRIBUTE_THEME_NAME); + } + if (memAttributeValue) { + html.setAttribute(ATTRIBUTE_THEME_NAME, memAttributeValue); + } + }); + it("should find template over ownerDocument", function() { + let html = document.querySelector("html"); + const div = document.createElement("div"); + div.setAttribute("data-monster-template-prefix", "myprefix"); + div.remove(); + let t1 = findDocumentTemplate("mytemplate", div); + expect(t1).is.instanceof(Template); + expect(t1.createDocumentFragment().textContent).is.equal("3"); + div.removeAttribute("data-monster-template-prefix"); + let t2 = findDocumentTemplate("mytemplate", div); + expect(t2).is.instanceof(Template); + expect(t2.createDocumentFragment().textContent).is.equal("2"); + html.setAttribute(ATTRIBUTE_THEME_NAME, "testtheme"); + let a2 = html.outerHTML; + let t3 = findDocumentTemplate("mytemplate", div); + expect(t3).is.instanceof(Template); + expect(t3.createDocumentFragment().textContent).is.equal("4"); + }); + }); + }); + }); + + // test/cases/dom/events.mjs + init_events(); + describe("Events", function() { + before(async function() { + await initJSDOM(); + }); + describe("findTargetElementFromEvent()", function() { + it("find object", function(done) { + let container = document.createElement("div"); + container.setAttribute("data-monster", "hello"); + let div = document.createElement("div"); + container.appendChild(div); + div.addEventListener("click", (event) => { + let e = findTargetElementFromEvent(event, "data-monster"); + expect(e.getAttribute("data-monster")).to.be.equal("hello"); + done(); + }); + setTimeout(() => { + fireEvent(div, "click"); + }, 0); + }); + }); + describe("fireEvent()", function() { + it("should fire a click event", function(done) { + let div = document.createElement("div"); + div.addEventListener("click", () => { + done(); + }); + fireEvent(div, "click"); + }); + it("should fire a touch event", function(done) { + let div = document.createElement("div"); + div.addEventListener("touch", () => { + done(); + }); + fireEvent(div, "touch"); + }); + it("should fire a touch event on collection", function(done) { + let div = document.createElement("div"); + div.addEventListener("touch", () => { + done(); + }); + div.appendChild(document.createElement("div")); + let collection = div.querySelectorAll("div"); + fireEvent(collection, "touch"); + }); + it("should fire a touch event", function(done) { + let div = document.createElement("div"); + div.addEventListener("touch", () => { + done(); + }); + div.appendChild(document.createElement("div")); + let collection = div.querySelectorAll("div"); + fireEvent(collection, "touch"); + }); + it("should throw error", function() { + expect(() => fireEvent({}, "touch")).to.throw(Error); + }); + }); + describe("fireCustomEvent()", function() { + it("should fire a click event", function(done) { + let div = document.createElement("div"); + div.addEventListener("click", () => { + done(); + }); + fireCustomEvent(div, "click"); + }); + it("should fire a touch event", function(done) { + let div = document.createElement("div"); + div.addEventListener("touch", () => { + done(); + }); + fireCustomEvent(div, "touch"); + }); + it("should fire a touch event on collection1", function(done) { + let div = document.createElement("div"); + div.addEventListener("touch", (e) => { + if (e.detail.detail !== "hello world") { + done("error"); + } + done(); + }); + div.appendChild(document.createElement("div")); + let collection = div.querySelectorAll("div"); + fireCustomEvent(collection, "touch", "hello world"); + }); + it("should fire a touch event on collection2", function(done) { + let div = document.createElement("div"); + div.addEventListener("touch", (e) => { + if (e.detail.a !== "hello world") { + done("error"); + } + done(); + }); + div.appendChild(document.createElement("div")); + let collection = div.querySelectorAll("div"); + fireCustomEvent(collection, "touch", { a: "hello world" }); + }); + it("should fire a touch event", function(done) { + let div = document.createElement("div"); + div.addEventListener("touch", () => { + done(); + }); + div.appendChild(document.createElement("div")); + let collection = div.querySelectorAll("div"); + fireCustomEvent(collection, "touch"); + }); + it("should throw error", function() { + expect(() => fireCustomEvent({}, "touch")).to.throw(Error); + }); + }); + }); + + // source/data/datasource/dom.mjs + init_constants(); + init_is(); + + // source/data/datasource.mjs + init_constants(); + init_constants(); + init_base(); + init_dataurl(); + init_is(); + init_proxyobserver(); + init_validate(); + init_extend(); + init_pathfinder(); + var internalDataSymbol = Symbol.for("@schukai/monster/data/datasource/@@data"); + var Datasource = class extends Base { + /** + * creates a new datasource + * + */ + constructor() { + super(); + this[internalSymbol] = new ProxyObserver({ + options: extend({}, this.defaults) + }); + this[internalDataSymbol] = new ProxyObserver({}); + } + /** + * attach a new observer + * + * @param {Observer} observer + * @returns {Datasource} + */ + attachObserver(observer) { + this[internalDataSymbol].attachObserver(observer); + return this; + } + /** + * detach a observer + * + * @param {Observer} observer + * @returns {Datasource} + */ + detachObserver(observer) { + this[internalDataSymbol].detachObserver(observer); + return this; + } + /** + * @param {Observer} observer + * @returns {boolean} + */ + containsObserver(observer) { + return this[internalDataSymbol].containsObserver(observer); + } + /** + * Derived classes can override and extend this method as follows. + * + * ``` + * get defaults() { + * return Object.assign({}, super.defaults, { + * myValue:true + * }); + * } + * ``` + */ + get defaults() { + return {}; + } + /** + * Set option + * + * @param {string} path + * @param {*} value + * @return {Datasource} + */ + setOption(path, value) { + new Pathfinder(this[internalSymbol].getSubject()["options"]).setVia(path, value); + return this; + } + /** + * @param {string|object} options + * @return {Datasource} + * @throws {Error} the options does not contain a valid json definition + */ + setOptions(options) { + if (isString(options)) { + options = parseOptionsJSON3(options); + } + const self2 = this; + extend(self2[internalSymbol].getSubject()["options"], self2.defaults, options); + return self2; + } + /** + * nested options can be specified by path `a.b.c` + * + * @param {string} path + * @param {*} defaultValue + * @return {*} + */ + getOption(path, defaultValue) { + let value; + try { + value = new Pathfinder(this[internalSymbol].getRealSubject()["options"]).getVia(path); + } catch (e) { + } + if (value === void 0) + return defaultValue; + return value; + } + /** + * @throws {Error} this method must be implemented by derived classes. + * @return {Promise} + */ + read() { + throw new Error("this method must be implemented by derived classes"); + } + /** + * @throws {Error} this method must be implemented by derived classes. + * @return {Promise} + */ + write() { + throw new Error("this method must be implemented by derived classes"); + } + /** + * Returns real object + * + * @return {Object|Array} + */ + get() { + const self2 = this; + return self2[internalDataSymbol].getRealSubject(); + } + /** + * @param {Object|Array} data + * @return {Datasource} + */ + set(data) { + const self2 = this; + self2[internalDataSymbol].setSubject(data); + return self2; + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/data/datasource"); + } + }; + function parseOptionsJSON3(data) { + if (isString(data)) { + try { + let dataUrl = parseDataURL(data); + data = dataUrl.content; + } catch (e) { + } + try { + let obj = JSON.parse(data); + validateObject(obj); + return obj; + } catch (e) { + throw new Error(`the options does not contain a valid json definition (actual: ${data}).`); + } + } + return {}; + } + + // source/data/datasource/dom.mjs + var DomStorage = class extends Datasource { + /** + * @param {Object} [options] options contains definitions for the datasource. + */ + constructor(options) { + super(); + if (isObject(options)) { + this.setOptions(options); + } + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/data/datasource/storage/dom-storage"); + } + /** + * @property {Object} defaults + * @property {Object} defaults.read + * @property {string} defaults.read.selector + * @property {Object} defaults.write + * @property {string} defaults.write.selector + */ + get defaults() { + return Object.assign({}, super.defaults, { + read: { + selector: void 0 + }, + write: { + selector: void 0 + } + }); + } + /** + * @return {Promise} + * @throws {Error} The read selector is not defined + * @throws {Error} There are no storage element + */ + read() { + const self2 = this; + let selector = self2.getOption("read.selector", void 0); + if (!selector) { + throw new Error("The read selector is not defined"); + } + let storage = document.querySelector(selector); + if (!storage) { + throw new Error("There are no storage element"); + } + return new Promise((resolve, reject) => { + try { + let data = JSON.parse(storage.innerHTML); + self2.set(data); + resolve(data); + } catch (e) { + reject(e); + } + }); + } + /** + * @return {Promise} + * @throws {Error} The write selector is not defined + * @throws {Error} There are no storage element + */ + write() { + const self2 = this; + let selector = self2.getOption("write.selector"); + if (!selector) { + throw new Error("The write selector is not defined"); + } + let storage = document.querySelector(selector); + if (!storage) { + throw new Error("There are no storage element"); + } + return new Promise((resolve, reject) => { + try { + storage.innerHTML = JSON.stringify(self2.get()); + resolve(storage); + } catch (e) { + reject(e); + } + }); + } + }; + + // test/cases/data/datasource/dom.mjs + describe("ServeDomr", function() { + it("should init", function() { + const dom = new DomStorage({}); + expect(dom).to.be.not.null; + }); + }); + + // source/data/datasource/storage/localstorage.mjs + init_constants(); + init_global(); + + // source/data/datasource/storage.mjs + init_constants(); + init_validate(); + var storageObjectSymbol = Symbol.for("@schukai/monster/data/datasource/storage/@@storageObject"); + var Storage = class _Storage extends Datasource { + /** + * + * @param {string} key LocalStorage Key + * @throws {TypeError} value is not a string + */ + constructor(key) { + super(); + this.setOption("key", validateString(key)); + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/data/datasource/storage"); + } + /** + * @property {string} key=undefined LocalStorage Key + */ + get defaults() { + return Object.assign({}, super.defaults, { + key: void 0 + }); + } + /** + * @throws {Error} this method must be implemented by derived classes. + * @return {external:Storage} + * @private + */ + [storageObjectSymbol]() { + throw new Error("this method must be implemented by derived classes"); + } + /** + * @return {Promise} + * @throws {Error} the options does not contain a valid json definition + * @throws {TypeError} value is not a object + * @throws {Error} the data cannot be read + */ + read() { + const self2 = this; + const storage = self2[storageObjectSymbol](); + return new Promise(function(resolve) { + const data = JSON.parse(storage.getItem(self2.getOption("key"))); + self2.set(data ?? {}); + resolve(); + }); + } + /** + * @return {Storage} + * @throws {Error} the data cannot be written + */ + write() { + const self2 = this; + const storage = self2[storageObjectSymbol](); + return new Promise(function(resolve) { + const data = self2.get(); + if (data === void 0) { + storage.removeItem(self2.getOption("key")); + } else { + storage.setItem(self2.getOption("key"), JSON.stringify(data)); + } + resolve(); + }); + } + /** + * @return {Storage} + */ + getClone() { + const self2 = this; + return new _Storage(self2[internalSymbol].getRealSubject()["options"].key); + } + }; + + // source/data/datasource/storage/localstorage.mjs + var LocalStorage = class _LocalStorage extends Storage { + /** + * @throws {Error} this method must be implemented by derived classes. + * @return {external:localStorage} + * @private + */ + [storageObjectSymbol]() { + return getGlobalObject("localStorage"); + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/data/datasource/storage/localstorage"); + } + /** + * Create clone + * @return {LocalStorage} + */ + getClone() { + const self2 = this; + return new _LocalStorage(self2[internalSymbol].getRealSubject()["options"].key); + } + }; + + // test/util/localstorage.mjs + function createStorage() { + let UNSET = Symbol(); + let s = {}, noopCallback = () => { + }, _itemInsertionCallback = noopCallback; + Object.defineProperty(s, "setItem", { + get: () => { + return (k, v = UNSET) => { + if (v === UNSET) { + throw new TypeError(`Failed to execute 'setItem' on 'Storage': 2 arguments required, but only 1 present.`); + } + k = k + ""; + if (!s.hasOwnProperty(k)) { + _itemInsertionCallback(s.length); + } + s[k] = v + ""; + }; + } + }); + Object.defineProperty(s, "getItem", { + get: () => { + return (k) => { + k = k + ""; + if (s.hasOwnProperty(k)) { + return s[k]; + } else { + return null; + } + }; + } + }); + Object.defineProperty(s, "removeItem", { + get: () => { + return (k) => { + k = k + ""; + if (s.hasOwnProperty(k)) { + delete s[k]; + } + }; + } + }); + Object.defineProperty(s, "clear", { + get: () => { + return () => { + for (let k in s) { + if (s.hasOwnProperty(k)) { + delete s[k]; + } + } + }; + } + }); + Object.defineProperty(s, "length", { + get: () => { + return Object.keys(s).length; + } + }); + Object.defineProperty(s, "key", { + value: (k) => { + let key = Object.keys(s)[k]; + return !key ? null : key; + } + }); + Object.defineProperty(s, "itemInsertionCallback", { + get: () => { + return _itemInsertionCallback; + }, + set: (v) => { + if (!v || typeof v != "function") { + v = noopCallback; + } + _itemInsertionCallback = v; + } + }); + return s; + } + + // test/cases/data/datasource/storage/localstorage.mjs + var localStorageReference; + describe("LocalStorage", function() { + afterEach(() => { + globalThis["localStorage"] = localStorageReference; + }); + beforeEach(function() { + localStorageReference = globalThis["localStorage"]; + globalThis["localStorage"] = createStorage(); + }); + it("should instance of LocalStorage ", function() { + expect(new LocalStorage("mykey")).to.be.instanceof(LocalStorage); + }); + describe("rw", function() { + it("read should return object", function(done) { + const ds = new LocalStorage("mykey"); + ds.read().then((data) => { + done(); + }).catch((e) => done(e)); + }); + it("write should ", function(done) { + const ds = new LocalStorage("mykey"); + ds.write().then((data) => { + done(); + }).catch((e) => done(e)); + }); + }); + }); + + // source/data/datasource/storage/sessionstorage.mjs + init_constants(); + init_global(); + var SessionStorage = class _SessionStorage extends Storage { + /** + * @throws {Error} this method must be implemented by derived classes. + * @return {external:sessionStorage} + * @private + */ + [storageObjectSymbol]() { + return getGlobalObject("sessionStorage"); + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/data/datasource/storage/session-storage"); + } + /** + * Create Clone + * + * @return {SessionStorage} + */ + getClone() { + const self2 = this; + return new _SessionStorage(self2[internalSymbol].getRealSubject()["options"].key); + } + }; + + // test/cases/data/datasource/storage/sessionstorage.mjs + var storageReference; + describe("SessionStorage", function() { + afterEach(() => { + globalThis["sessionStorage"] = storageReference; + }); + beforeEach(function() { + storageReference = globalThis["sessionStorage"]; + globalThis["sessionStorage"] = createStorage(); + }); + it("should instance of SessionStorage ", function() { + expect(new SessionStorage("mykey")).to.be.instanceof(SessionStorage); + }); + describe("rw", function() { + it("read should return object", function(done) { + const ds = new SessionStorage("mykey"); + ds.read().then((data) => { + done(); + }).catch((e) => done(e)); + }); + it("write should ", function(done) { + const ds = new SessionStorage("mykey"); + ds.write().then((data) => { + done(); + }).catch((e) => done(e)); + }); + }); + }); + + // source/data/datasource/server.mjs + init_constants(); + init_is(); + init_pathfinder(); + init_pipe(); + var Server = class extends Datasource { + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/data/datasource/server"); + } + /** + * This prepares the data that comes from the server. + * Should not be called directly. + * + * @private + * @param {Object} payload + * @returns {Object} + */ + transformServerPayload(payload) { + const self2 = this; + payload = doTransform.call(self2, "read", payload); + const dataPath = self2.getOption("read.path"); + if (dataPath) { + payload = new Pathfinder(payload).getVia(dataPath); + } + return payload; + } + /** + * This prepares the data for writing and should not be called directly. + * + * @private + * @param {Object} payload + * @returns {Object} + */ + prepareServerPayload(payload) { + const self2 = this; + payload = doTransform.call(self2, "write", payload); + let sheathingObject = self2.getOption("write.sheathing.object"); + let sheathingPath = self2.getOption("write.sheathing.path"); + if (sheathingObject && sheathingPath) { + const sub = payload; + payload = sheathingObject; + new Pathfinder(payload).setVia(sheathingPath, sub); + } + return payload; + } + }; + function doTransform(type, obj) { + const self2 = this; + let transformation = self2.getOption(`${type}.mapping.transformer`); + if (transformation !== void 0) { + const pipe = new Pipe(transformation); + const callbacks = self2.getOption(`${type}.mapping.callbacks`); + if (isObject(callbacks)) { + for (const key in callbacks) { + if (callbacks.hasOwnProperty(key) && typeof callbacks[key] === "function") { + pipe.setCallback(key, callbacks[key]); + } + } + } + obj = pipe.run(obj); + } + return obj; + } + + // test/cases/data/datasource/server.mjs + describe("Server", function() { + it("should transform data", function() { + let writeCallbackCalled = false; + let readCallbackCalled = false; + const server = new Server({ + write: { + mapping: { + transformer: "call:onWrite", + callbacks: { + onWrite: (data) => { + writeCallbackCalled = true; + return data; + } + } + }, + sheathing: { + object: { + demo: 1, + data: { + xyz: void 0 + } + }, + path: "data.xyz" + } + }, + read: { + mapping: { + transformer: "call:onRead", + callbacks: { + onRead: (data) => { + readCallbackCalled = true; + return data; + } + } + }, + path: "data.xyz" + } + }); + expect(server.transformServerPayload({ demo: 1, data: { xyz: 2 } })).to.deep.equal({ demo: 1, data: { xyz: 2 } }); + expect(server.prepareServerPayload({ demo: 1, data: { xyz: 2 } })).to.deep.equal({ demo: 1, data: { xyz: 2 } }); + }); + }); + + // source/data/datasource/server/webconnect.mjs + init_constants(); + init_is(); + var webConnectSymbol = Symbol("connection"); + var WebConnect2 = class _WebConnect extends Server { + /** + * + * @param {Object} [options] options contains definitions for the datasource. + */ + constructor(options) { + super(); + const self2 = this; + if (isString(options)) { + options = { url: options }; + } + if (!isObject(options)) + options = {}; + this.setOptions(options); + this[webConnectSymbol] = new WebConnect({ + url: self2.getOption("url"), + connection: { + timeout: self2.getOption("connection.timeout"), + reconnect: { + timeout: self2.getOption("connection.reconnect.timeout"), + attempts: self2.getOption("connection.reconnect.attempts"), + enabled: self2.getOption("connection.reconnect.enabled") + } + } + }); + } + /** + * + * @returns {Promise} + */ + connect() { + return this[webConnectSymbol].connect(); + } + /** + * @returns {boolean} + */ + isConnected() { + return this[webConnectSymbol].isConnected(); + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/data/datasource/server/webconnect"); + } + /** + * @property {string} url=undefined Defines the resource that you wish to fetch. + * @property {Object} connection + * @property {Object} connection.timeout=5000 Defines the timeout for the connection. + * @property {Number} connection.reconnect.timeout The timeout in milliseconds for the reconnect. + * @property {Number} connection.reconnect.attempts The maximum number of reconnects. + * @property {Bool} connection.reconnect.enabled If the reconnect is enabled. + * @property {Object} write={} Options + * @property {Object} write.mapping the mapping is applied before writing. + * @property {String} write.mapping.transformer Transformer to select the appropriate entries + * @property {Monster.Data.Datasource~exampleCallback[]} write.mapping.callback with the help of the callback, the structures can be adjusted before writing. + * @property {Object} write.sheathing + * @property {Object} write.sheathing.object Object to be wrapped + * @property {string} write.sheathing.path Path to the data + * @property {Object} read={} Options + * @property {String} read.path Path to data + * @property {Object} read.mapping the mapping is applied after reading. + * @property {String} read.mapping.transformer Transformer to select the appropriate entries + * @property {Monster.Data.Datasource~exampleCallback[]} read.mapping.callback with the help of the callback, the structures can be adjusted after reading. + */ + get defaults() { + return Object.assign({}, super.defaults, { + url: void 0, + write: { + mapping: { + transformer: void 0, + callbacks: {} + }, + sheathing: { + object: void 0, + path: void 0 + } + }, + read: { + mapping: { + transformer: void 0, + callbacks: {} + }, + path: void 0 + }, + connection: { + timeout: 5e3, + reconnect: { + timeout: 1e3, + attempts: 1, + enabled: false + } + } + }); + } + /** + * This method closes the connection. + * + * @returns {Promise} + */ + close() { + return this[webConnectSymbol].close(); + } + /** + * @return {Promise} + */ + read() { + const self2 = this; + return new Promise((resolve, reject) => { + while (this[webConnectSymbol].dataReceived() === true) { + let obj = this[webConnectSymbol].poll(); + if (!isObject(obj)) { + reject(new Error("The received data is not an object.")); + return; + } + if (!(obj instanceof Message)) { + reject(new Error("The received data is not a Message.")); + return; + } + obj = obj.getData(); + obj = self2.transformServerPayload.call(self2, obj); + self2.set(obj); + } + resolve(self2.get()); + }); + } + /** + * @return {Promise} + */ + write() { + const self2 = this; + let obj = self2.prepareServerPayload(self2.get()); + return self2[webConnectSymbol].send(obj); + } + /** + * @return {RestAPI} + */ + getClone() { + const self2 = this; + return new _WebConnect(self2[internalSymbol].getRealSubject()["options"]); + } + }; + + // test/cases/data/datasource/server/websocket.mjs + var testUrl2 = "wss://ws.postman-echo.com/raw"; + describe("Websocket", function() { + let ds = void 0; + before(function(done) { + initWebSocket().then(() => { + done(); + }).catch((e) => { + done(e); + }); + }); + afterEach(function(done) { + if (ds) { + ds.close(); + } + for (const sym of Object.getOwnPropertySymbols(ds)) { + if (sym.toString() === "Symbol(connection)") { + const connection = ds[sym]; + for (const sym2 of Object.getOwnPropertySymbols(connection)) { + if (sym2.toString() === "Symbol(connection)") { + const socket = connection[sym2]?.socket; + if (socket) { + if (typeof socket?.terminate === "function") { + socket?.["terminate"](); + } + } + } + } + } + } + done(); + }); + it("should get clone", function() { + ds = new WebConnect2(testUrl2); + const clone2 = ds.getClone(); + expect(clone2).to.be.an.instanceof(WebConnect2); + }); + it("should transform data", function(done) { + let writeCallbackCalled = false; + let readCallbackCalled = false; + ds = new WebConnect2({ + url: testUrl2, + write: { + mapping: { + transformer: "call:onWrite", + callbacks: { + onWrite: (data) => { + writeCallbackCalled = true; + return data; + } + } + }, + sheathing: { + object: { + demo: 1, + data: { + xyz: void 0 + } + }, + path: "data.xyz" + } + }, + read: { + mapping: { + transformer: "call:onRead", + callbacks: { + onRead: (data) => { + readCallbackCalled = true; + return data; + } + } + }, + path: "data.xyz" + } + }); + ds.connect().then(() => { + ds.set({ + envelop: { + message: "Hello World" + } + }); + ds.write().then(() => { + ds.set({}); + expect(ds.get()).to.be.deep.equal({}); + setTimeout(() => { + ds.read().then(() => { + expect(ds.get()).to.be.deep.equal({ envelop: { message: "Hello World" } }); + expect(writeCallbackCalled).to.be.true; + expect(readCallbackCalled).to.be.true; + done(); + }).catch((e) => { + done(e); + }); + }, 200); + }).catch((err) => { + done(new Error(err)); + }); + }).catch((e) => { + done(e); + }); + }); + it("should connect", function(done) { + ds = new WebConnect2({ + url: testUrl2, + reconnect: { + enabled: false + } + }); + ds.connect().then(() => { + done(); + }).catch((e) => { + done(e); + }); + }); + it("should send message", function(done) { + ds = new WebConnect2({ + url: testUrl2, + reconnect: { + enabled: false + } + }); + ds.connect().then(() => { + ds.set({ + envelop: { + message: "Hello World" + } + }); + ds.write().then(() => { + ds.set({}); + expect(ds.get()).to.be.deep.equal({}); + setTimeout(() => { + ds.read().then(() => { + expect(ds.get()).to.be.deep.equal({ envelop: { message: "Hello World" } }); + done(); + }).catch((e) => { + done(e); + }); + }, 500); + }).catch((err) => { + done(new Error(err)); + }); + }).catch((e) => { + done(e); + }); + }).timeout(1e4); + }); + + // source/data/datasource/server/restapi.mjs + init_constants(); + init_is(); + + // source/data/datasource/server/restapi/writeerror.mjs + init_constants(); + var WriteError = class extends Error { + /** + * + * @param {string} message + * @param {Response} response + */ + constructor(message, response, validation) { + super(message); + this[internalSymbol] = { + response, + validation + }; + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/data/datasource/server/restapi/writeerror"); + } + /** + * @return {Response} + */ + getResponse() { + return this[internalSymbol]["response"]; + } + /** + * @return {Object} + */ + getValidation() { + return this[internalSymbol]["validation"]; + } + }; + + // source/data/datasource/server/restapi/data-fetch-error.mjs + init_constants(); + var DataFetchError = class extends Error { + /** + * + * @param {string} message + * @param {Response} response + */ + constructor(message, response) { + super(message); + this[internalSymbol] = { + response + }; + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/data/datasource/server/restapi/datafetcherror@@instance"); + } + /** + * @return {Response} + */ + getResponse() { + return this[internalSymbol]["response"]; + } + }; + + // source/data/datasource/server/restapi.mjs + var rawDataSymbol = Symbol.for("@schukai/monster/data/datasource/server/restapi/rawdata"); + var RestAPI = class _RestAPI extends Server { + /** + * + * @param {Object} [options] options contains definitions for the datasource. + */ + constructor(options) { + super(); + if (isObject(options)) { + this.setOptions(options); + } + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/data/datasource/server/restapi"); + } + /** + * @property {Object} write={} Options + * @property {Object} write.init={} An options object containing any custom settings that you want to apply to the request. The parameters are identical to those of the {@link https://developer.mozilla.org/en-US/docs/Web/API/Request/Request|Request constructor} + * @property {string} write.init.method=POST + * @property {Object} write.init.headers Object containing any custom headers that you want to apply to the request. + * @property {string} write.responseCallback Callback function to be executed after the request has been completed. + * @property {string} write.acceptedStatus=[200,201] + * @property {string} write.url URL + * @property {Object} write.mapping the mapping is applied before writing. + * @property {String} write.mapping.transformer Transformer to select the appropriate entries + * @property {Monster.Data.Datasource~exampleCallback[]} write.mapping.callback with the help of the callback, the structures can be adjusted before writing. + * @property {Object} write.report + * @property {String} write.report.path Path to validations + * @property {Object} write.sheathing + * @property {Object} write.sheathing.object Object to be wrapped + * @property {string} write.sheathing.path Path to the data + * @property {Object} read={} Options + * @property {Object} read.init={} An options object containing any custom settings that you want to apply to the request. The parameters are identical to those of the {@link https://developer.mozilla.org/en-US/docs/Web/API/Request/Request|Request constructor} + * @property {string} read.init.method=GET + * @property {string} read.acceptedStatus=[200] + * @property {string} read.url URL + * @property {Object} read.mapping the mapping is applied after reading. + * @property {String} read.mapping.transformer Transformer to select the appropriate entries + * @property {Monster.Data.Datasource~exampleCallback[]} read.mapping.callback with the help of the callback, the structures can be adjusted after reading. + */ + get defaults() { + return Object.assign({}, super.defaults, { + write: { + init: { + method: "POST" + }, + responseCallback: void 0, + acceptedStatus: [200, 201], + url: void 0, + mapping: { + transformer: void 0, + callbacks: [] + }, + sheathing: { + object: void 0, + path: void 0 + }, + report: { + path: void 0 + } + }, + read: { + init: { + method: "GET" + }, + responseCallback: void 0, + acceptedStatus: [200], + url: void 0, + mapping: { + transformer: void 0, + callbacks: [] + } + } + }); + } + /** + * @return {Promise} + * @throws {Error} the options does not contain a valid json definition + * @throws {TypeError} value is not a object + * @throws {Error} the data cannot be read + */ + read() { + const self2 = this; + let init3 = self2.getOption("read.init"); + if (!isObject(init3)) + init3 = {}; + if (!init3["method"]) + init3["method"] = "GET"; + let callback = self2.getOption("read.responseCallback"); + if (!callback) + callback = (obj) => { + self2.set(self2.transformServerPayload.call(self2, obj)); + }; + return fetchData.call(this, init3, "read", callback); + } + /** + * @return {Promise} + * @throws {WriteError} the data cannot be written + */ + write() { + const self2 = this; + let init3 = self2.getOption("write.init"); + if (!isObject(init3)) + init3 = {}; + if (typeof init3["headers"] !== "object") { + init3["headers"] = { + "Content-Type": "application/json" + }; + } + if (!init3["method"]) + init3["method"] = "POST"; + let obj = self2.prepareServerPayload(self2.get()); + init3["body"] = JSON.stringify(obj); + let callback = self2.getOption("write.responseCallback"); + return fetchData.call(this, init3, "write", callback); + } + /** + * @return {RestAPI} + */ + getClone() { + const self2 = this; + return new _RestAPI( + self2[internalSymbol].getRealSubject()["options"].read, + self2[internalSymbol].getRealSubject()["options"].write + ); + } + }; + function fetchData(init3, key, callback) { + const self2 = this; + let response; + return fetch(self2.getOption(`${key}.url`), init3).then((resp) => { + response = resp; + const acceptedStatus = self2.getOption(`${key}.acceptedStatus`, [200]); + if (acceptedStatus.indexOf(resp.status) === -1) { + throw new DataFetchError( + `the response does not contain a accepted status (actual: ${resp.status}).`, + response + ); + } + return resp.text(); + }).then((body) => { + let obj; + try { + obj = JSON.parse(body); + response[rawDataSymbol] = obj; + } catch (e) { + if (body.length > 100) { + body = `${body.substring(0, 97)}...`; + } + throw new DataFetchError(`the response does not contain a valid json (actual: ${body}).`, response); + } + if (callback && isFunction(callback)) { + callback(obj); + } + return response; + }); + } + + // test/cases/data/datasource/server/restapi.mjs + init_validate(); + describe("RestAPI", function() { + let fetchReference2; + let returnStatus; + afterEach(() => { + globalThis["fetch"] = fetchReference2; + }); + beforeEach(() => { + returnStatus = 200; + fetchReference2 = globalThis["fetch"]; + globalThis["fetch"] = function(options) { + return new Promise((resolve, reject) => { + resolve({ + text: function() { + return new Promise((resolve2, reject2) => { + resolve2(JSON.stringify({ + a: "test" + })); + }); + }, + status: returnStatus + }); + }); + }; + }); + it("should instance of RestAPI ", function() { + expect(new RestAPI("https://monsterjs.org/assets/world.json")).to.be.instanceof(RestAPI); + }); + describe("rw", function() { + it("read should return object", function(done) { + const ds = new RestAPI({ url: "https://monsterjs.org/assets/world.json" }); + ds.read().then((data) => { + validateObject(data); + done(); + }).catch((e) => done(e)); + }); + it("write should ", function(done) { + const ds = new RestAPI( + { + read: { + url: "https://monsterjs.org/assets/world.json" + }, + write: { + url: "https://monsterjs.org/assets/world.json", + acceptedStatus: [99] + } + } + ); + ds.write().then((data) => { + done("should not be here"); + }).catch((e) => done()); + }); + }); + describe("rw with errors", function() { + it("read should throw exception", function(done) { + returnStatus = 400; + const ds = new RestAPI({ url: "https://monsterjs.org/assets/world.json" }); + ds.read().then((data) => { + done("should not run."); + }).catch((e) => done()); + }); + it("write should ", function(done) { + returnStatus = 400; + const ds = new RestAPI({ url: "https://monsterjs.org/assets/world.json" }, { url: "https://monsterjs.org/assets/world.json" }); + ds.write().then((data) => { + validateObject(data); + done("error"); + }).catch((e) => done()); + }); + }); + }); + + // test/cases/data/datasource.mjs + describe("Datasource", function() { + it("should instance of Datasource ", function() { + expect(new Datasource()).to.be.instanceof(Datasource); + }); + describe("Options", function() { + it("setOption should change value", function() { + const datasource = new Datasource(); + expect(datasource.getOption("default")).to.be.undefined; + datasource.setOption("default", true); + expect(datasource.getOption("default")).to.be.true; + }); + it("setOptions should set all values", function() { + const datasource = new Datasource(); + expect(datasource.getOption("default")).to.be.undefined; + datasource.setOptions({ default: true }); + expect(datasource.getOption("default")).to.be.true; + }); + }); + describe("rw", function() { + const datasource = new Datasource(); + it("read should throw exeption", function() { + expect(() => datasource.read()).to.throw(Error); + }); + it("write should throw exeption", function() { + expect(() => datasource.read()).to.throw(Error); + }); + }); + describe("get/set", function() { + const datasource = new Datasource(); + it("get should return undefined", function() { + expect(datasource.get()).to.be.eql({}); + }); + it("write should throw exeption", function() { + expect(datasource.get()).to.be.eql({}); + expect(datasource.set({ a: "myvalue" })).to.be.instanceof(Datasource); + expect(datasource.get()).to.be.eql({ a: "myvalue" }); + }); + }); + }); + + // source/data/buildmap.mjs + init_is(); + init_validate(); + init_clone(); + init_pathfinder(); + var PARENT = "^"; + function buildMap(subject, selector, valueTemplate, keyTemplate, filter) { + return assembleParts(subject, selector, filter, function(v, k, m) { + k = build(v, keyTemplate, k); + v = build(v, valueTemplate); + this.set(k, v); + }); + } + function assembleParts(subject, selector, filter, callback) { + const result = /* @__PURE__ */ new Map(); + let map; + if (isFunction(selector)) { + map = selector(subject); + if (!(map instanceof Map)) { + throw new TypeError("the selector callback must return a map"); + } + } else if (isString(selector)) { + map = /* @__PURE__ */ new Map(); + buildFlatMap.call(map, subject, selector); + } else { + throw new TypeError("selector is neither a string nor a function"); + } + if (!(map instanceof Map)) { + return result; + } + map.forEach((v, k, m) => { + if (isFunction(filter)) { + if (filter.call(m, v, k) !== true) + return; + } + callback.call(result, v, k, m); + }); + return result; + } + function buildFlatMap(subject, selector, key, parentMap) { + const result = this; + const currentMap = /* @__PURE__ */ new Map(); + const resultLength = result.size; + if (key === void 0) + key = []; + let parts = selector.split(DELIMITER); + let current = ""; + let currentPath = []; + do { + current = parts.shift(); + currentPath.push(current); + if (current === WILDCARD) { + let finder = new Pathfinder(subject); + let map; + try { + map = finder.getVia(currentPath.join(DELIMITER)); + } catch (e) { + let a2 = e; + map = /* @__PURE__ */ new Map(); + } + for (const [k, o] of map) { + let copyKey = clone(key); + currentPath.map((a2) => { + copyKey.push(a2 === WILDCARD ? k : a2); + }); + let kk = copyKey.join(DELIMITER); + let sub = buildFlatMap.call(result, o, parts.join(DELIMITER), copyKey, o); + if (isObject(sub) && parentMap !== void 0) { + sub[PARENT] = parentMap; + } + currentMap.set(kk, sub); + } + } + } while (parts.length > 0); + if (resultLength === result.size) { + for (const [k, o] of currentMap) { + result.set(k, o); + } + } + return subject; + } + function build(subject, definition, defaultValue) { + if (definition === void 0) + return defaultValue ? defaultValue : subject; + validateString(definition); + const regexp = /(?<placeholder>\${(?<path>[a-z\^A-Z.\-_0-9]*)})/gm; + const array = [...definition.matchAll(regexp)]; + let finder = new Pathfinder(subject); + if (array.length === 0) { + return finder.getVia(definition); + } + array.forEach((a2) => { + let groups = a2?.["groups"]; + let placeholder = groups?.["placeholder"]; + if (placeholder === void 0) + return; + let path = groups?.["path"]; + let v = finder.getVia(path); + if (v === void 0) + v = defaultValue; + definition = definition.replaceAll(placeholder, v); + }); + return definition; + } + + // test/cases/data/buildmap.mjs + describe("buildMap", function() { + let convertMapResult = function(r) { + if (r instanceof Map) { + r = Object.fromEntries(r); + if (r instanceof Array) { + r = r.map((e) => { + return convertMapResult(e); + }); + } else if (typeof r === "object") { + for (const [k, o] of Object.entries(r)) { + r[k] = convertMapResult(o); + } + } + } + return r; + }; + describe("build Map with callback", function() { + it("definition should return map with sub and parent keys", function() { + let obj = { + "data": [ + { + "id": 10, + "name": "Cassandra", + "enrichment": { + variants: [ + { + sku: 1, + label: "XXS", + price: [ + { vk: "12.12 \u20AC" }, + { vk: "12.12 \u20AC" } + ] + }, + { + sku: 2, + label: "XS", + price: [ + { vk: "22.12 \u20AC" }, + { vk: "22.12 \u20AC" } + ] + }, + { + sku: 3, + label: "S", + price: [ + { vk: "32.12 \u20AC" }, + { vk: "32.12 \u20AC" } + ] + }, + { + sku: 4, + label: "L", + price: [ + { vk: "42.12 \u20AC" }, + { vk: "42.12 \u20AC" } + ] + } + ] + } + }, + { + "id": 20, + "name": "Yessey!", + "enrichment": { + variants: [ + { + sku: 1, + label: "XXS", + price: [ + { vk: "12.12 \u20AC" }, + { vk: "12.12 \u20AC" } + ] + }, + { + sku: 2, + label: "XS", + price: [ + { vk: "22.12 \u20AC" }, + { vk: "22.12 \u20AC" } + ] + }, + { + sku: 3, + label: "S", + price: [ + { vk: "32.12 \u20AC" }, + { vk: "32.12 \u20AC" } + ] + }, + { + sku: 4, + label: "L", + price: [ + { vk: "42.12 \u20AC" }, + { vk: "42.12 \u20AC" } + ] + } + ] + } + } + ] + }; + let callback = function(subject) { + let m = /* @__PURE__ */ new Map(); + for (const [i2, b] of Object.entries(subject.data)) { + let key1 = i2; + for (const [j, c] of Object.entries(b.enrichment.variants)) { + let key2 = j; + for (const [k, d2] of Object.entries(c.price)) { + let key3 = k; + d2.name = b.name; + d2.label = c.label; + d2.id = [key1, key2, key3].join("."); + m.set(d2.id, d2); + } + } + } + return m; + }; + let map = buildMap(obj, callback, "${name} ${label}", "${id}"); + let i = convertMapResult(map); + expect(JSON.stringify(i)).to.be.equal('{"0.0.0":"Cassandra XXS","0.0.1":"Cassandra XXS","0.1.0":"Cassandra XS","0.1.1":"Cassandra XS","0.2.0":"Cassandra S","0.2.1":"Cassandra S","0.3.0":"Cassandra L","0.3.1":"Cassandra L","1.0.0":"Yessey! XXS","1.0.1":"Yessey! XXS","1.1.0":"Yessey! XS","1.1.1":"Yessey! XS","1.2.0":"Yessey! S","1.2.1":"Yessey! S","1.3.0":"Yessey! L","1.3.1":"Yessey! L"}'); + }); + }); + describe("build submap with *", function() { + it('definition should return {"10":"Cassandra 10","20":"Yessey! 20"}', function() { + let obj = { + "data": [ + { + "id": 10, + "name": "Cassandra" + }, + { + "id": 20, + "name": "Yessey!" + } + ] + }; + let map = buildMap(obj, "data.*", "${name} ${id}", "${id}"); + let i = convertMapResult(map); + expect(JSON.stringify(i)).to.be.equal('{"10":"Cassandra 10","20":"Yessey! 20"}'); + }); + }); + describe("build submap with **", function() { + it("definition should return Map", function() { + let obj = { + "data": [ + { + "id": 10, + "name": "Cassandra", + "enrichment": { + variants: [ + { + sku: 1, + label: "XXS", + price: [ + { vk: "12.12 \u20AC", id: 1 }, + { vk: "12.12 \u20AC", id: 2 } + ] + }, + { + sku: 2, + label: "XS", + price: [ + { vk: "22.12 \u20AC", id: 3 }, + { vk: "22.12 \u20AC", id: 4 } + ] + }, + { + sku: 3, + label: "S", + price: [ + { vk: "32.12 \u20AC", id: 5 }, + { vk: "32.12 \u20AC", id: 6 } + ] + }, + { + sku: 4, + label: "L", + price: [ + { vk: "42.12 \u20AC", id: 7 }, + { vk: "42.12 \u20AC", id: 8 } + ] + } + ] + } + }, + { + "id": 20, + "name": "Yessey!", + "enrichment": { + variants: [ + { + sku: 1, + label: "XXS", + price: [ + { vk: "12.12 \u20AC", id: 9 }, + { vk: "12.12 \u20AC", id: 10 } + ] + }, + { + sku: 2, + label: "XS", + price: [ + { vk: "22.12 \u20AC", id: 11 }, + { vk: "22.12 \u20AC", id: 12 } + ] + }, + { + sku: 3, + label: "S", + price: [ + { vk: "32.12 \u20AC", id: 13 }, + { vk: "32.12 \u20AC", id: 14 } + ] + }, + { + sku: 4, + label: "L", + price: [ + { vk: "42.12 \u20AC", id: 15 }, + { vk: "42.12 \u20AC", id: 16 }, + { vk: "44.12 \u20AC", id: 17 } + ] + } + ] + } + } + ] + }; + let map = buildMap(obj, "data.*.enrichment.variants.*.price.*", "${vk} ${^.label} ${^.^.name}", "${^.^.sku}"); + let i = convertMapResult(map); + expect(JSON.stringify(i)).to.be.equal('{"data.0.enrichment.variants.0.price.0":"12.12 \u20AC XXS Cassandra","data.0.enrichment.variants.0.price.1":"12.12 \u20AC XXS Cassandra","data.0.enrichment.variants.1.price.0":"22.12 \u20AC XS Cassandra","data.0.enrichment.variants.1.price.1":"22.12 \u20AC XS Cassandra","data.0.enrichment.variants.2.price.0":"32.12 \u20AC S Cassandra","data.0.enrichment.variants.2.price.1":"32.12 \u20AC S Cassandra","data.0.enrichment.variants.3.price.0":"42.12 \u20AC L Cassandra","data.0.enrichment.variants.3.price.1":"42.12 \u20AC L Cassandra","data.1.enrichment.variants.0.price.0":"12.12 \u20AC XXS Yessey!","data.1.enrichment.variants.0.price.1":"12.12 \u20AC XXS Yessey!","data.1.enrichment.variants.1.price.0":"22.12 \u20AC XS Yessey!","data.1.enrichment.variants.1.price.1":"22.12 \u20AC XS Yessey!","data.1.enrichment.variants.2.price.0":"32.12 \u20AC S Yessey!","data.1.enrichment.variants.2.price.1":"32.12 \u20AC S Yessey!","data.1.enrichment.variants.3.price.0":"42.12 \u20AC L Yessey!","data.1.enrichment.variants.3.price.1":"42.12 \u20AC L Yessey!","data.1.enrichment.variants.3.price.2":"44.12 \u20AC L Yessey!"}'); + }); + }); + describe("examplecode", function() { + it("should execute example code", function() { + let obj = { + "data": [ + { + "id": 10, + "name": "Cassandra", + "address": { + "street": "493-4105 Vulputate Street", + "city": "Saumur", + "zip": "52628" + } + }, + { + "id": 20, + "name": "Holly", + "address": { + "street": "1762 Eget Rd.", + "city": "Schwalbach", + "zip": "952340" + } + }, + { + "id": 30, + "name": "Guy", + "address": { + "street": "957-388 Sollicitudin Avenue", + "city": "Panchi\xE0", + "zip": "420729" + } + } + ] + }; + let map; + map = buildMap(obj, "data.*", "${name} (${address.zip} ${address.city})", "id"); + expect(map).to.be.instanceOf(Map); + map = buildMap(obj, "data.*", "${name} (${address.zip} ${address.city})"); + expect(map).to.be.instanceOf(Map); + map = buildMap(obj, "data.*", "${name} (${address.zip} ${address.city})", "id", function(value, key) { + return value["id"] >= 20 ? true : false; + }); + expect(map).to.be.instanceOf(Map); + }); + }); + describe("buildmap()", function() { + let obj1 = { + dataset: { + "10082": { + name: "Test 1", + address: "Here 1" + }, + "10084": { + name: "Test 2", + address: "Here 2" + } + } + }; + it("should return Map Instance.", function() { + expect(buildMap({}, "")).to.be.instanceOf(Map); + }); + [ + [obj1, "dataset.*", "address", '{"dataset.10082":"Here 1","dataset.10084":"Here 2"}'], + [obj1, "x", void 0, "{}"], + [obj1, "dataset.*", "name", '{"dataset.10082":"Test 1","dataset.10084":"Test 2"}'] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + let c = data.shift(); + let d2 = data.shift(); + it("buildMap(" + JSON.stringify(a2) + "," + JSON.stringify(b) + "," + JSON.stringify(c) + ") should return " + JSON.stringify(d2) + " ", function() { + let t = buildMap(a2, b, c); + let m = JSON.stringify(convertMapResult(t)); + expect(m).to.be.equal(d2); + }); + }); + }); + }); + + // test/cases/data/transformer.mjs + init_transformer(); + + // source/i18n/providers/embed.mjs + init_constants(); + init_extend(); + init_util(); + init_is(); + init_validate(); + init_locale(); + init_provider(); + init_translations(); + var Embed = class _Embed extends Provider { + /** + * ```html + * <script id="translations" type="application/json"> + * { + * "hello": "Hallo" + * } + * <\/script> + * ``` + * + * + * ```javascript + * new Embed('translations') + * ``` + * + * @param {HTMLElement|string} elementOrId + * @param {Object} options + */ + constructor(elementOrId, options) { + super(options); + if (options === void 0) { + options = {}; + } + if (elementOrId instanceof HTMLElement) { + this.translateElement = elementOrId; + } else { + this.translateElement = getDocument().getElementById(validateString(elementOrId)); + } + this[internalSymbol] = extend({}, super.defaults, this.defaults, validateObject(options)); + } + /** + * Defaults + * + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API} + */ + get defaults() { + return extend({}, super.defaults); + } + /** + * + * @param {Locale|string} locale + * @return {Promise} + */ + getTranslations(locale) { + if (isString(locale)) { + locale = parseLocale(locale); + } + return new Promise((resolve, reject) => { + if (this.translateElement === null) { + reject(new Error("Text not found")); + return; + } + if (!(this.translateElement instanceof HTMLScriptElement)) { + reject(new Error("Element is not a script tag")); + return; + } + if (this.translateElement.type !== "application/json") { + reject(new Error("Element is not a script tag with type application/json")); + return; + } + let translations = null; + try { + translations = JSON.parse(this.translateElement.innerHTML.trim()); + } catch (e) { + reject(e); + return; + } + if (translations === null) { + reject(new Error("Translations not found or invalid")); + return; + } + const t = new Translations(locale); + t.assignTranslations(translations); + resolve(t); + }); + } + /** + * Initializes the translations for the current document. + * + * `script[data-monster-role=translations]` is searched for and the translations are assigned to the element. + * + * @param element + * @returns {Promise<unknown[]>} + */ + static assignTranslationsToElement(element) { + const d2 = getDocument(); + if (!(element instanceof HTMLElement)) { + element = d2.querySelector("body"); + } + const list = d2.querySelectorAll("script[data-monster-role=translations]"); + if (list === null) { + return; + } + const promises = []; + list.forEach((translationElement) => { + const p = new _Embed(translationElement); + promises.push(p.assignToElement(void 0, element)); + }); + return Promise.all(promises); + } + }; + + // test/cases/data/transformer.mjs + describe("Transformer", function() { + before(function(done) { + let promises = []; + promises.push(initJSDOM()); + if (!globalThis["crypto"]) { + promises.push(Promise.resolve().then(() => (init_webcrypto_es(), webcrypto_es_exports)).then((m) => { + globalThis["crypto"] = new m.Crypto(); + return true; + })); + } + Promise.all(promises).then(() => { + done(); + }); + }); + describe("Transformer.run()", function() { + [ + ["datetimeformat", "2023-02-04 08:02:01", "04.02.2023, 08:02:01"], + ["datetimeformat:long:short", "2023-02-04 08:02:01", "4. Februar 2023 um 08:02"], + ["datetimeformat:short:short", "2023-02-04 08:02:01", "04.02.23, 08:02"], + ["equals:a", "a", true], + ["equals:a", "b", false], + ["equals:3", 3, true], + ["equals:3", 6, false], + ["equals:on", true, true], + ["equals:true", true, true], + ["equals:on", false, false], + ["equals:true", false, false], + ["equals:off", false, true], + ["equals:false", false, true], + ["equals:off", false, true], + ["equals:false", true, false], + ["equals:3", 3, true], + ["equals:3", 6, false], + ["equals:undefined", void 0, true], + ["equals:undefined", 3, false], + ["equals:null", null, true], + ["equals:null", 3, false], + ["equals:3", 6, false], + ["currency", "EUR0", "0,00\xA0\u20AC"], + ["currency:1:2", "EUR14.25", "14,2\xA0\u20AC"], + ["currency", "EUR14.25", "14,25\xA0\u20AC"], + ["datetime", "2023-02-14 14:12:10", "14.2.2023, 14:12:10"], + ["datetime", "2023-02-14 08:02:01", "14.2.2023, 08:02:01"], + ["has-entries", {}, false], + ["has-entries", { a: 4 }, true], + ["has-entries", [], false], + ["has-entries", "", false], + ["has-entries", [1, 2, 3], true], + ["has-entries", [1], true], + ["has-entries", ["1"], true], + ["has-entries", [true], true], + ["contains:x", "asd wxd sdf", true], + ["contains:x", "asd wd sdf", false], + ["contains:b", ["a", "b", "c"], true], + ["contains:x", ["a", "b", "c"], false], + ["isundefined", "a", false], + ["isundefined", null, false], + ["isundefined", void 0, true], + ["isnull", "a", false], + ["isnull", null, true], + ["isset", null, false], + ["isset", void 0, false], + ["isset", "", true], + ["isnumber", "a", false], + ["isnumber", 4, true], + ["isnumber", 4.5, true], + ["isinteger", 4.5, false], + ["isinteger", 4, true], + ["isfloat", 5.6, true], + ["isfloat", 5, false], + ["isobject", 4, false], + ["isobject", {}, true], + ["isarray", [{}], true], + ["isarray", "a", false], + ["not", true, false], + ["not", false, true], + ["map:a=4:b=5:c=6", "a", "4"], + ["date", "2023-02-14", "14.2.2023"], + ["year", "2023-02-14", 2023], + ["month", "2023-02-14", 2], + ["day", "2023-02-14", 14], + ["weekday", "2023-02-14", 2], + ["minutes", "2023-02-14 06:12:21", 12], + ["seconds", "2023-02-14 06:12:21", 21], + ["hours", "2023-02-14 06:12:21", 6], + ["time", "2023-02-14 06:12:21", "06:12:21"], + ["timestamp", "2023-02-14", 16763328e5], + ["concat:a.b.c:test:a.b.d", { a: { b: { c: 4, d: 6 } } }, "4test6"], + ["concat:a.b.c:\\ \\ :a.b.d", { a: { b: { c: 4, d: 6 } } }, "4 6"], + ["concat:a.b.c:,:a.b.d", { a: { b: { c: 4, d: 6 } } }, "4,6"], + ["concat:a.b.c:,:\\ :a.b.d", { a: { b: { c: 4, d: 6 } } }, "4, 6"], + ["??:a", null, "a"], + ["??:a", void 0, "a"], + ["??:a", "true", "true"], + ["??:a", false, false], + [" if:a: ", false, void 0], + // without \\ + [" if:a:\\ ", false, " "], + [" if:a:\\ ", true, "a"], + ["default:yes", null, "yes"], + ["default:yes", void 0, "yes"], + ["default:1:bool", void 0, true], + ["default:on:bool", void 0, true], + ["default:true:bool", void 0, true], + ["default:yes:bool", void 0, true], + ["default:undefined:bool", void 0, false], + ["default:false:bool", void 0, false], + ["default:1:int", void 0, 1], + ["default:1:string", void 0, "1"], + ["first-key", { a: 1, c: 3, b: 2 }, 1], + ["last-key", { a: 1, c: 3, b: 2 }, 3], + ["nth-last-key:0", { a: 1, c: 3, b: 2 }, 3], + ["nth-last-key:1", { a: 1, c: 3, b: 2 }, 2], + ["nth-last-key:2", { a: 1, c: 3, b: 2 }, 1], + ["nth-key:2", { a: 1, b: 2, c: 3 }, 3], + ["nth-key:0", { c: 3, a: 1, b: 2 }, 1], + ["nth-key:2", { a: 1, c: 3, b: 2 }, 3], + ["prefix:Hello\\ ", "test", "Hello test"], + ["tojson", { a: 4 }, '{"a":4}'], + ["prefix:a\\\\: ", "test", "a\\test"], + ["prefix:a\\ ", "test", "a test"], + ["static:abc:a:b:x", "test", "abc:a:b:x"], + ["tolowercase", "A:b:Cse4", "a:b:cse4"], + ["toupper", "A:b:Cse4", "A:B:CSE4"], + ["tostring", 5, "5"], + ["tostring", [1, 2, 3, {}], "1,2,3,[object Object]"], + ["tointeger", "5", 5], + ["trim", " 5 ", "5"], + ["trim", " a", "a"], + ["trim", " ", ""], + ["rawurlencode", "\xFC\xF6\xE4", "%C3%BC%C3%B6%C3%A4"], + ["call:testcallback:4:5:6", "test", "test456"], + ["plain", "t<br>est", "test"], + ["if:a:b", true, "a"], + ["if:a:b", "on", "a"], + ["if:a:b", "true", "a"], + ["if:a:b", "false", "b"], + ["if:a:b", 9, "a"], + ["if:a:b", "", "b"], + ["if:a:b", void 0, "b"], + ["if:a:b", false, "b"], + ["ucfirst", "car", "Car"], + ["ucfirst", "cAr", "CAr"], + ["default:test", "a", "a"], + ["default:test", void 0, "test"], + ["fromjson", "{}", {}], + ["fromjson", '{"a":1}', { a: 1 }], + ["ucwords", "cAr runs", "CAr Runs"], + ["tointeger", "6", 6], + ["length", "test", 4], + ["to-base64", "Hello World!", "SGVsbG8gV29ybGQh"], + ["from-base64", "SGVsbG8gV29ybGQh", "Hello World!"], + ["to-base64", "test", "dGVzdA=="], + ["from-base64", "dGVzdA==", "test"], + ["prefix:a", "test", "atest"], + ["suffix:a", "test", "testa"], + ["index:a", { a: 4 }, 4], + ["index:2", [2, 4, 7], 7], + ["index:x:test", [2, 4, 7], "test"], + ["path:a.b.c", { a: { b: { c: 4 } } }, 4], + ["path:a.b.d", { a: { b: { c: 4 } } }, void 0], + ["index:a", (/* @__PURE__ */ new Map()).set("a", 5), 5], + ["substring:2:4", "abcdefghijklmnop", "cdef"], + ["nop", "abcdefghijklmnop", "abcdefghijklmnop"] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + let c = data.shift(); + it("Transformer.run(" + JSON.stringify(a2) + ").run(" + JSON.stringify(b) + ") should return " + JSON.stringify(c), function() { + let t = new Transformer(a2); + t.setCallback("testcallback", function(a3, b2, c2, d2) { + return a3 + b2 + c2 + d2; + }); + const r = t.run(b); + expect(r).to.be.eql(c); + }); + }); + }); + describe("Transformer.run() throws Error", function() { + [ + ["tolowercase", []], + ["tolowercase", {}], + ["tolowercase", 4.5], + ["toupper", true], + ["toupper", 5], + ["tointeger", "a"], + ["trim", 5], + ["trim", true], + ["trim", {}], + ["trim", []], + ["rawurlencode", []], + ["if:a:b", {}], + ["ucwords", {}], + ["ucwords", false], + ["ucwords", 4], + ["path:a.b.c", "", 4], + ["tointeger", {}], + ["base64", {}], + ["fromjson", ""], + ["prefix", {}], + ["suffix", {}], + ["index", "test"], + ["xxxxxx", "test"] + // unsupported command + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + it("Transformer.run(" + JSON.stringify(a2) + ").run(" + JSON.stringify(b) + ") should throw Error ", function() { + let t = new Transformer(a2); + expect(() => t.run(b)).to.throw(Error); + }); + }); + }); + describe('new Transformer().run("uniqid")', function() { + it("should return String", function() { + let t = new Transformer("uniqid"); + expect(t.run("")).to.be.a("string"); + }); + }); + describe('new Transformer().run("default:eyJiIjoxfQ==:object")', function() { + it("should return Object", function() { + let t = new Transformer("default:eyJiIjoxfQ==:object"); + expect(t.run(void 0)).to.eql({ b: 1 }); + }); + }); + describe("new Transformer()", function() { + it("should return instanceof Transformer", function() { + expect(new Transformer("")).to.instanceOf(Transformer); + }); + it("should return instanceof Transformer", function() { + expect(new Transformer("suffix:abc")).to.instanceOf(Transformer); + }); + it("false as argument should throw TypeError", function() { + expect(() => { + new Transformer(false); + }).to.throw(TypeError); + }); + it("object as argument should throw TypeError", function() { + expect(() => { + new Transformer({}); + }).to.throw(TypeError); + }); + }); + describe("i18n", function() { + let html16 = ` +<div id="mock-translations"></div> +<script type="application/json" data-monster-role="translations"> + { + "test1": "xyz", + "test3": { + "other": "xyz" + } + } +<\/script> +`; + beforeEach((done) => { + let mocks = document.getElementById("mocks"); + mocks.innerHTML = html16; + let elem = document.getElementById("mock-translations"); + Embed.assignTranslationsToElement(elem).then((o) => { + done(); + }); + }); + afterEach(() => { + let mocks = document.getElementById("mocks"); + mocks.innerHTML = ""; + }); + before(function(done) { + initJSDOM().then(() => { + done(); + }); + }); + [ + ["i18n:test1", "", "xyz"], + ["i18n:", "test1", "xyz"], + // key by value + ["i18n::", "test1", "xyz"], + // key by value no default + ["i18n::eee", "test2", "eee"], + // key by value with default + ["i18n::ddd", "test2", "ddd"] + // key by value and default + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + let c = data.shift(); + it("should transform(" + a2 + ").run(" + b + ") return " + JSON.stringify(c), function() { + const t = new Transformer(a2); + expect(t.run(b)).to.be.eql(c); + }); + }); + }); + }); + + // test/cases/data/diff.mjs + init_diff(); + init_queue(); + describe("Diff", function() { + describe("Diff special cases", function() { + var obj1, obj2; + beforeEach(() => { + obj1 = { + "count": 1, + "reason": null, + "info": "test", + "exchange": [] + }; + obj2 = { + "count": 2, + "reason": null, + "info": void 0, + "exchange": [] + }; + }); + it("Diff value with null ", function() { + let d2 = diff(obj1, obj2); + expect(JSON.stringify(d2)).is.equal('[{"operator":"update","path":["count"],"first":{"value":1,"type":"number"},"second":{"value":2,"type":"number"}},{"operator":"delete","path":["info"],"first":{"value":"test","type":"string"}}]'); + }); + it("Diff identical value with null ", function() { + let d2 = diff(obj1, obj1); + expect(JSON.stringify(d2)).is.equal("[]"); + }); + }); + const date1 = /* @__PURE__ */ new Date(); + const date2 = Date.parse("01 Jan 1970 00:00:00 GMT"); + const date3 = Date.parse("04 Dec 1995 00:12:00 GMT"); + const date4 = Date.parse("04 Dec 1995 00:12:01 GMT"); + const date5 = new Date(Date.parse("04 Dec 1995 00:12:01 GMT")); + const date6 = new Date(Date.parse("04 Dec 1995 00:12:02 GMT")); + [ + [ + {}, + { + a: new Queue() + }, + '[{"operator":"add","path":["a"],"second":{"value":{"data":[]},"type":"object","instance":"Queue"}}]' + ], + [ + { + a: { + b: 1 + }, + c: { + d: 2 + } + }, + { + a: { + e: 3 + }, + f: { + d: 2 + } + }, + '[{"operator":"delete","path":["a","b"],"first":{"value":1,"type":"number"}},{"operator":"add","path":["a","e"],"second":{"value":3,"type":"number"}},{"operator":"delete","path":["c"],"first":{"value":{"d":2},"type":"object","instance":"Object"}},{"operator":"add","path":["f"],"second":{"value":{"d":2},"type":"object","instance":"Object"}}]' + ], + [ + { + a: date1, + c: date4 + }, + { + a: date2, + b: date3 + }, + '[{"operator":"update","path":["a"],"first":{"value":"' + date1.toISOString() + '","type":"object","instance":"Date"},"second":{"value":0,"type":"number"}},{"operator":"delete","path":["c"],"first":{"value":818035921000,"type":"number"}},{"operator":"add","path":["b"],"second":{"value":818035920000,"type":"number"}}]' + ], + [ + { + a: date5 + }, + { + b: date6 + }, + '[{"operator":"delete","path":["a"],"first":{"value":"1995-12-04T00:12:01.000Z","type":"object","instance":"Date"}},{"operator":"add","path":["b"],"second":{"value":"1995-12-04T00:12:02.000Z","type":"object","instance":"Date"}}]' + ], + [ + { + a: date1 + }, + { + a: date1 + }, + "[]" + ], + [ + {}, + { + a: date3 + }, + '[{"operator":"add","path":["a"],"second":{"value":818035920000,"type":"number"}}]' + ], + [ + { + a: date2 + }, + { + a: date3 + }, + '[{"operator":"update","path":["a"],"first":{"value":0,"type":"number"},"second":{"value":818035920000,"type":"number"}}]' + ], + [ + { + a: 1 + }, + { + a: 2 + }, + '[{"operator":"update","path":["a"],"first":{"value":1,"type":"number"},"second":{"value":2,"type":"number"}}]' + ], + [ + { + a: 1 + }, + { + x: 1 + }, + '[{"operator":"delete","path":["a"],"first":{"value":1,"type":"number"}},{"operator":"add","path":["x"],"second":{"value":1,"type":"number"}}]' + ], + [ + { + a: 1 + }, + { + a: 2, + x: 1 + }, + '[{"operator":"update","path":["a"],"first":{"value":1,"type":"number"},"second":{"value":2,"type":"number"}},{"operator":"add","path":["x"],"second":{"value":1,"type":"number"}}]' + ], + [ + { + a: null + }, + {}, + '[{"operator":"delete","path":["a"],"first":{"value":null,"type":"object"}}]' + ], + [ + { + a: null + }, + { + a: null + }, + "[]" + ], + [ + {}, + { + a: null + }, + '[{"operator":"add","path":["a"],"second":{"value":null,"type":"object"}}]' + ], + [ + {}, + { a: void 0 }, + '[{"operator":"add","path":["a"],"second":{"type":"undefined"}}]' + ] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + let c = data.shift(); + it("Diff should result " + c, function() { + let d2 = diff(a2, b); + expect(JSON.stringify(d2)).is.equal(c); + }); + }); + }); + + // source/data/buildtree.mjs + init_is(); + + // source/types/node.mjs + init_base(); + init_is(); + + // source/types/nodelist.mjs + init_is(); + init_validate(); + init_constants(); + var NodeList2 = class _NodeList extends Set { + /** + * @throws {Error} invalid value type + * @param {NodeList|Node|Array<Node>}values + */ + constructor(values) { + super(); + const self2 = this; + if (values === void 0) + return; + if (isArray(values)) { + values.forEach((value) => self2.add(value)); + } else if (isInstance(values, _NodeList)) { + values.forEach((value) => self2.add(value)); + } else if (isInstance(values, Node2)) { + self2.add(values); + } else { + throw new Error("invalid value type"); + } + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/types/node-list"); + } + /** + * + * @param {Node} node + * @return {Monster.Types.NodeList} + */ + add(node) { + super.add(validateInstance(node, Node2)); + return this; + } + /** + * @param {Node} node + * @returns {NodeList} + */ + remove(node) { + super.delete(validateInstance(node, Node2)); + return this; + } + /** + * @param {Node} node + * @returns {boolean} + */ + has(node) { + return super.has(validateInstance(node, Node2)); + } + /** + * @returns {NodeList} + */ + clear() { + super.clear(); + return this; + } + /** + * @returns {NodeList} + */ + toArray() { + return Array.from(this); + } + /** + * @returns {NodeList} + */ + toJSON() { + return this.toArray(); + } + /** + * @returns {NodeList} + */ + toString() { + let parts = []; + for (const node of this.toArray()) { + parts.push(node.toString()); + } + return parts.join("\n"); + } + get length() { + return super.size; + } + }; + + // source/types/node.mjs + init_validate(); + init_constants(); + var internalValueSymbol = Symbol("internalData"); + var treeStructureSymbol = Symbol("treeStructure"); + var Node2 = class _Node extends Base { + /** + * @param {*} [value] + */ + constructor(value) { + super(); + this[internalValueSymbol] = value; + this[treeStructureSymbol] = { + parent: null, + childNodes: new NodeList2(), + level: 0 + }; + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/types/node"); + } + /** + * @property {*} + */ + get value() { + return this[internalValueSymbol]; + } + /** + * @property {*} + */ + set value(value) { + this[internalValueSymbol] = value; + } + /** + * @property {Monster.Types.Node|null} + */ + get parent() { + return this[treeStructureSymbol].parent; + } + /** + * @property {integer} + */ + get level() { + return this[treeStructureSymbol].level; + } + /** + * + * @property {NodeList} + */ + get childNodes() { + return this[treeStructureSymbol].childNodes; + } + /** + * + * @property {NodeList} + */ + set childNodes(childNodes) { + this[treeStructureSymbol].childNodes = validateInstance(childNodes, NodeList2); + setChildLevelAndParent.call(this, this, 1); + } + /** + * @return {Monster.Types.Node} + * @param {Node} node + */ + appendChild(node) { + this[treeStructureSymbol].childNodes.add(validateInstance(node, _Node)); + node[treeStructureSymbol].parent = this; + node[treeStructureSymbol].level = this.level + 1; + setChildLevelAndParent.call(this, node, 1); + return this; + } + /** + * @return {Monster.Types.Node} + * @param {Node} node + */ + removeChild(node) { + this[treeStructureSymbol].childNodes.remove(validateInstance(node, _Node)); + node[treeStructureSymbol].parent = null; + node[treeStructureSymbol].level = 0; + setChildLevelAndParent.call(this, node, -1); + return this; + } + /** + * + * @return {boolean} + */ + hasChildNodes() { + return this[treeStructureSymbol].childNodes.length > 0; + } + /** + * @return {Monster.Types.Node} + * @param {Node} node + */ + hasChild(node) { + return this[treeStructureSymbol].childNodes.has(validateInstance(node, _Node)); + } + /** + * @since 1.28.0 + * @return {string} + */ + toString() { + let parts = []; + if (this[internalValueSymbol]) { + let label = this[internalValueSymbol]; + if (!isPrimitive(label)) + label = JSON.stringify(this[internalValueSymbol]); + parts.push(label); + } + if (!this.hasChildNodes()) { + return parts.join("\n"); + } + let count = this.childNodes.length; + let counter = 0; + for (const node of this.childNodes) { + counter++; + const prefix = (count === counter ? "\u2514" : "\u251C").padStart(2 * node.level, " |"); + parts.push(prefix + node.toString()); + } + return parts.join("\n"); + } + }; + function setChildLevelAndParent(node, operand) { + const self2 = this; + if (node !== this) { + node[treeStructureSymbol].parent = this; + } + node[treeStructureSymbol].childNodes.forEach(function(child) { + child[treeStructureSymbol].parent = node; + child[treeStructureSymbol].level = node[treeStructureSymbol].level + operand; + setChildLevelAndParent.call(self2, child, operand); + }); + return this; + } + + // source/data/buildtree.mjs + init_extend(); + var parentSymbol = Symbol("parent"); + var rootSymbol = Symbol("root"); + function buildTree(subject, selector, idKey, parentIDKey, options) { + const nodes = /* @__PURE__ */ new Map(); + if (!isObject(options)) { + options = {}; + } + options = extend( + {}, + { + rootReferences: [null, void 0], + filter: void 0 + }, + options + ); + const filter = options?.filter; + let rootReferences = options.rootReferences; + if (!isArray(rootReferences)) { + rootReferences = [rootReferences]; + } + const childMap = assembleParts(subject, selector, filter, function(o, k, m) { + const key = o?.[idKey]; + let ref = o?.[parentIDKey]; + if (rootReferences.indexOf(ref) !== -1) + ref = rootSymbol; + if (key === void 0) { + throw new Error("the object has no value for the specified id"); + } + o[parentSymbol] = ref; + const node = new Node2(o); + this.has(ref) ? this.get(ref).add(node) : this.set(ref, new NodeList2().add(node)); + nodes.set(key, node); + }); + nodes.forEach((node) => { + let id = node?.["value"]?.[idKey]; + if (childMap.has(id)) { + node.childNodes = childMap.get(id); + childMap.delete(id); + } + }); + const list = new NodeList2(); + childMap.forEach((s) => { + if (s instanceof Set) { + s.forEach((n) => { + list.add(n); + }); + } + }); + return list; + } + + // test/cases/data/buildtree.mjs + describe("buildTree", function() { + describe("example", function() { + it("should run example", function() { + const objects = { + dataset: { + "1": { + id: "1", + name: "vehicle", + parent: null + }, + "2": { + id: "2", + name: "car", + parent: "1" + }, + "3": { + id: "3", + name: "truck", + parent: "1" + }, + "4": { + id: "4", + name: "motorcycle", + parent: "1" + }, + "5": { + id: "5", + name: "SUV", + parent: "2" + }, + "6": { + id: "6", + name: "sports car", + parent: "2" + } + } + }; + const nodes = buildTree(objects, "dataset.*", "id", "parent"); + expect(nodes).to.be.instanceOf(NodeList2); + expect(nodes.length).to.equal(1); + expect(nodes.toString()).to.be.equal('{"id":"1","name":"vehicle","parent":null}\n \u251C{"id":"2","name":"car","parent":"1"}\n | \u251C{"id":"5","name":"SUV","parent":"2"}\n | \u2514{"id":"6","name":"sports car","parent":"2"}\n \u251C{"id":"3","name":"truck","parent":"1"}\n \u2514{"id":"4","name":"motorcycle","parent":"1"}'); + }); + }); + describe("buildTree()", function() { + let obj1 = { + dataset: { + "1": { + id: "1", + name: "Test 1", + address: "Here 1", + parent: null + }, + "2": { + id: "2", + name: "Test 2", + address: "Here 2", + parent: "1" + }, + "3": { + id: "3", + name: "Test 3", + address: "Here 3", + parent: "2" + }, + "4": { + id: "4", + name: "Test 4", + address: "Here 4", + parent: "2" + }, + "5": { + id: "5", + name: "Test 5", + address: "Here 5", + parent: "1" + }, + "6": { + id: "6", + name: "Test 6", + address: "Here 6", + parent: "4" + } + } + }; + it("should return Node Instance.", function() { + expect(buildTree({}, "")).to.be.instanceOf(NodeList2); + }); + [ + [obj1, "dataset.*", '{"id":"1","name":"Test 1","address":"Here 1","parent":null}\n \u251C{"id":"2","name":"Test 2","address":"Here 2","parent":"1"}\n | \u251C{"id":"3","name":"Test 3","address":"Here 3","parent":"2"}\n | \u2514{"id":"4","name":"Test 4","address":"Here 4","parent":"2"}\n | | \u2514{"id":"6","name":"Test 6","address":"Here 6","parent":"4"}\n \u2514{"id":"5","name":"Test 5","address":"Here 5","parent":"1"}'], + [obj1, "x", ""], + [obj1, "dataset.*", '{"id":"1","name":"Test 1","address":"Here 1","parent":null}\n \u251C{"id":"2","name":"Test 2","address":"Here 2","parent":"1"}\n | \u251C{"id":"3","name":"Test 3","address":"Here 3","parent":"2"}\n | \u2514{"id":"4","name":"Test 4","address":"Here 4","parent":"2"}\n | | \u2514{"id":"6","name":"Test 6","address":"Here 6","parent":"4"}\n \u2514{"id":"5","name":"Test 5","address":"Here 5","parent":"1"}'] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + let c = data.shift(); + it("buildTree(" + JSON.stringify(a2) + "," + JSON.stringify(b) + ") should return " + JSON.stringify(c) + " ", function() { + let nodelist = buildTree(a2, b, "id", "parent"); + expect(nodelist.toString()).to.be.eql(c); + }); + }); + }); + describe("buildTree() test 2", function() { + let obj1 = { + dataset: { + "1": { + id: "1", + name: "Test 1", + address: "Here 1", + parent: "2" + }, + "2": { + id: "2", + name: "Test 2", + address: "Here 2", + parent: "0" + }, + "3": { + id: "3", + name: "Test 3", + address: "Here 3", + parent: "2" + }, + "4": { + id: "4", + name: "Test 4", + address: "Here 4", + parent: "0" + }, + "5": { + id: "5", + name: "Test 5", + address: "Here 5", + parent: "0" + }, + "6": { + id: "6", + name: "Test 6", + address: "Here 6", + parent: "4" + }, + "7": { + id: "7", + name: "Test 7", + address: "Here 7", + parent: "1" + } + } + }; + it("should return Node Instance.", function() { + expect(buildTree({}, "")).to.be.instanceOf(NodeList2); + }); + [ + [obj1, "dataset.*", '{"id":"2","name":"Test 2","address":"Here 2","parent":"0"}\n \u251C{"id":"1","name":"Test 1","address":"Here 1","parent":"2"}\n | \u2514{"id":"7","name":"Test 7","address":"Here 7","parent":"1"}\n \u2514{"id":"3","name":"Test 3","address":"Here 3","parent":"2"}\n{"id":"4","name":"Test 4","address":"Here 4","parent":"0"}\n \u2514{"id":"6","name":"Test 6","address":"Here 6","parent":"4"}\n{"id":"5","name":"Test 5","address":"Here 5","parent":"0"}'], + [obj1, "x", ""] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + let c = data.shift(); + it("buildTree(" + JSON.stringify(a2) + "," + JSON.stringify(b) + ") should return " + JSON.stringify(c) + " ", function() { + let nodelist = buildTree(a2, b, "id", "parent", { + rootReferences: ["0"] + }); + expect(nodelist.toString()).to.be.equal(c); + }); + }); + }); + }); + + // test/cases/data/pathfinder.mjs + init_pathfinder(); + describe("Pathfinder", function() { + let convertMapResult = function(r) { + if (r instanceof Map) { + r = Object.fromEntries(r); + if (r instanceof Array) { + r = r.map((e) => { + return convertMapResult(e); + }); + } else if (typeof r === "object") { + for (const [k, o] of Object.entries(r)) { + r[k] = convertMapResult(o); + } + } + } + return r; + }; + describe("with Wildcard and Iterations", function() { + let pf, obj; + beforeEach(function() { + obj = { + a: [ + { + b: [ + { + c: "1-1" + }, + { + c: "1-2" + } + ], + d: "!" + }, + { + b: [ + { + c: "2-1" + }, + { + c: "2-2" + } + ], + d: "?" + } + ] + }; + pf = new Pathfinder(obj); + }); + [ + ["a.*.b.*", '{"0":{"0":{"c":"1-1"},"1":{"c":"1-2"}},"1":{"0":{"c":"2-1"},"1":{"c":"2-2"}}}'], + ["a.*.b", '{"0":[{"c":"1-1"},{"c":"1-2"}],"1":[{"c":"2-1"},{"c":"2-2"}]}'], + ["a.1.b", '[{"c":"2-1"},{"c":"2-2"}]'], + ["a.0.b", '[{"c":"1-1"},{"c":"1-2"}]'] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + it(".setVia(" + a2 + ") should result in " + b, function() { + let r = pf.getVia(a2); + let i = convertMapResult(r); + expect(JSON.stringify(i)).is.equal(b); + }); + }); + }); + describe("api tests", function() { + let pathfinder, object; + class A { + get a() { + return 1; + } + } + beforeEach(() => { + object = { + a: { + b: { + c: [ + 4, + "test1", + false, + void 0, + parseInt("a") + ], + d: void 0, + e: false, + f: [ + { + g: false, + h: 3, + i: ["test2"] + } + ], + j: {}, + k: (/* @__PURE__ */ new Map()).set("m", { n: 3 }), + l: (/* @__PURE__ */ new Set()).add({ n: 4 }) + } + }, + b: new A() + }; + pathfinder = new Pathfinder(object); + }); + describe("create new object", function() { + [ + [12], + [void 0], + [null], + ["test"] + ].forEach(function(data) { + let a2 = data.shift(); + let label = typeof a2; + if (a2 === null) + label = "null"; + it(label + " should throw error", function() { + expect(() => { + new Pathfinder(a2); + }).to.throw(Error); + }); + }); + }); + describe(".setVia(x)", function() { + let pf, obj; + beforeEach(function() { + obj = {}; + pf = new Pathfinder(obj); + }); + [ + ["a.b.0.0.c", true, '{"a":{"b":[[{"c":true}]]}}'], + ["a.b.0.c", true, '{"a":{"b":[{"c":true}]}}'], + ["a.b.3.c", true, '{"a":{"b":[null,null,null,{"c":true}]}}'], + ["a.b.c", true, '{"a":{"b":{"c":true}}}'] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + let c = data.shift(); + it(".setVia(" + a2 + ", " + b + ") should result in " + c, function() { + pf.setVia(a2, b); + expect(JSON.stringify(obj)).is.equal(c); + }); + }); + }); + describe(".setVia()", function() { + let a2; + let b; + let c; + beforeEach(function() { + a2 = "a.x"; + b = "true"; + c = "a.y.d"; + }); + it(".setVia(" + a2 + ", " + b + ") should return Pathfinder", function() { + expect(pathfinder.setVia(a2, b)).is.instanceOf(Pathfinder); + }); + it(".setVia(" + a2 + ", " + b + ") should change object", function() { + pathfinder.setVia(a2, b); + expect(JSON.stringify(object)).is.equal('{"a":{"b":{"c":[4,"test1",false,null,null],"e":false,"f":[{"g":false,"h":3,"i":["test2"]}],"j":{},"k":{},"l":{}},"x":"true"},"b":{}}'); + }); + it(".setVia(" + c + ", " + b + ") should change object", function() { + pathfinder.setVia(c, b); + expect(JSON.stringify(object)).is.equal('{"a":{"b":{"c":[4,"test1",false,null,null],"e":false,"f":[{"g":false,"h":3,"i":["test2"]}],"j":{},"k":{},"l":{}},"y":{"d":"true"}},"b":{}}'); + }); + }); + describe(".exists()", function() { + [ + ["a.b.c.1", true], + ["b.a", true], + ["a.b.x", false], + ["a.x", false], + ["a.b.q", false], + ["a.b.c.0", true], + ["a.b.d", true], + ["a.b.f.0.g", true], + ["a.b.f.0.i.0", true], + ["a.b.f.0.i.2", false], + ["a.b.e", true] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + it(".exists(" + a2 + ") should return " + b + " ", function() { + expect(pathfinder.exists(a2)).is.equal(b); + }); + }); + }); + describe(".deleteVia()", function() { + [ + ["a.b.e", '{"a":{"b":{"c":[4,"test1",false,null,null],"f":[{"g":false,"h":3,"i":["test2"]}],"j":{},"k":{},"l":{}}},"b":{}}'], + ["a.b.f", '{"a":{"b":{"c":[4,"test1",false,null,null],"e":false,"j":{},"k":{},"l":{}}},"b":{}}'], + ["a.b.j", '{"a":{"b":{"c":[4,"test1",false,null,null],"e":false,"f":[{"g":false,"h":3,"i":["test2"]}],"k":{},"l":{}}},"b":{}}'] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + it(".deleteVia(" + a2 + ") should return " + b + " ", function() { + pathfinder.deleteVia(a2); + expect(JSON.stringify(object)).is.equal(b); + }); + }); + }); + describe(".getVia()", function() { + describe(".getVia()", function() { + beforeEach(function() { + object = { + a: { + b: { + c: [ + 4, + "test1", + false, + void 0, + parseInt("a") + ], + d: void 0, + e: false, + f: [ + { + g: false, + h: 3, + i: ["test2"] + } + ], + j: {}, + k: (/* @__PURE__ */ new Map()).set("m", { n: 3 }), + l: (/* @__PURE__ */ new Set()).add({ n: 4 }), + o: [ + { p: { q: 1, r: true } }, + { p: { q: 2, r: true } }, + { p: { q: 3, r: true } }, + { p: { q: 4, r: true } }, + { p: { q: 5, r: true } } + ], + s: { + t: { a: 1 }, + u: { a: 2 }, + v: { a: 3 }, + x: { a: 4 } + } + } + } + }; + pathfinder = new Pathfinder(object); + }); + [ + ["a.*", '[["b",{"c":[4,"test1",false,null,null],"e":false,"f":[{"g":false,"h":3,"i":["test2"]}],"j":{},"k":{},"l":{},"o":[{"p":{"q":1,"r":true}},{"p":{"q":2,"r":true}},{"p":{"q":3,"r":true}},{"p":{"q":4,"r":true}},{"p":{"q":5,"r":true}}],"s":{"t":{"a":1},"u":{"a":2},"v":{"a":3},"x":{"a":4}}}]]'], + ["a.b.s.*.a", '[["t",1],["u",2],["v",3],["x",4]]'], + ["a.b.s.*", '[["t",{"a":1}],["u",{"a":2}],["v",{"a":3}],["x",{"a":4}]]'], + ["a.b.o.*.p.q", '[["0",1],["1",2],["2",3],["3",4],["4",5]]'], + ["a.b.o.*.p.r", '[["0",true],["1",true],["2",true],["3",true],["4",true]]'], + ["a.b.o.*.p", '[["0",{"q":1,"r":true}],["1",{"q":2,"r":true}],["2",{"q":3,"r":true}],["3",{"q":4,"r":true}],["4",{"q":5,"r":true}]]'] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + it(".getVia(" + a2 + ") should result " + b, function() { + let r = pathfinder.getVia(a2); + expect(JSON.stringify(Array.from(r))).is.equal(b); + }); + }); + }); + it(".getVia() should result ", function() { + let p = new Pathfinder({ + a: { + x: [ + { c: 1 }, + { c: 2 } + ], + y: true + }, + b: { + x: [ + { c: 1, d: false }, + { c: 2 } + ], + y: true + } + }); + let r = p.getVia("*.x.*.c"); + function mapToObj(map) { + var obj = {}; + map.forEach(function(v, k) { + if (v instanceof Map) { + obj[k] = mapToObj(v); + } else { + obj[k] = v; + } + }); + return obj; + } + expect(JSON.stringify(mapToObj(r))).is.equal('{"a":{"0":1,"1":2},"b":{"0":1,"1":2}}'); + }); + it(".getVia(a.b.l.0.n) with map should return 4 ", function() { + expect(pathfinder.getVia("a.b.l.0.n")).is.equal(4); + }); + [ + ["a.b.k.m.n", 3], + ["a.b.l.0.n", 4], + ["a.x", void 0], + ["a.b.q", void 0], + ["a.b.c.1", "test1"], + ["a.b.c.0", 4], + ["a.b.d", void 0], + ["a.b.f.0.g", false], + ["a.b.f.0.i.0", "test2"], + ["a.b.e", false] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + it(".getVia(" + a2 + ") should return " + b + " ", function() { + expect(pathfinder.getVia(a2)).is.equal(b); + }); + }); + [ + ["a.b.d.e"], + ["a.b.d.x"], + ["a.b.l.e.n"] + ].forEach(function(data) { + let a2 = data.shift(); + it(".getVia(" + a2 + ") should throw Error ", function() { + expect(() => pathfinder.getVia(a2)).to.throw(Error); + }); + }); + }); + }); + }); + + // test/cases/data/pipe.mjs + init_pipe(); + describe("Pipe", function() { + before(function(done) { + let promises = []; + if (!globalThis["crypto"]) { + promises.push(Promise.resolve().then(() => (init_webcrypto_es(), webcrypto_es_exports)).then((m) => { + globalThis["crypto"] = new m.Crypto(); + return true; + })); + } + Promise.all(promises).then(() => { + done(); + }); + }); + describe("run different pipes", function() { + [ + ["path:b | if:x:\\ ", { a: true }, " "], + // '\\ '.length ↦ 2 + ["path:a | if:x:\\ ", { a: true }, "x"], + ["nop", "abcdefghijklmnop", "abcdefghijklmnop"] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + let c = data.shift(); + it("Pipe.run(" + JSON.stringify(a2) + ").run(" + JSON.stringify(b) + ") should return " + JSON.stringify(c), function() { + let t = new Pipe(a2); + const r = t.run(b); + expect(r).to.be.eql(c); + }); + }); + }); + describe("new Pipe should create new Instance", function() { + it("should return Instance", function() { + expect(new Pipe("")).to.be.instanceOf(Pipe); + }); + it("should return Instance", function() { + expect(new Pipe("index:a|toupper |prefix:a").run({ a: "test" })).to.be.equal("aTEST"); + }); + [ + ["index:a|toupper |prefix:a", { a: "test" }, "aTEST"], + ["path:a.b.c.d | toupper | prefix:Hello\\ ", { + a: { + b: { + c: { + d: "world" + } + } + } + }, "Hello WORLD"], + ["path:a.b.c|index:d|toupper |suffix:x", { a: { b: { c: { d: "test" } } } }, "TESTx"] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + let c = data.shift(); + it("new Pipe(" + JSON.stringify(a2) + ").run(" + JSON.stringify(b) + ") should return " + JSON.stringify(c) + " ", function() { + let t = new Pipe(a2); + expect(t.run(b)).to.be.equal(c); + }); + }); + }); + describe("new Pipe and locale", function() { + let html16 = ` +<div id="mock-translations"></div> +<script type="application/json" data-monster-role="translations"> + { + "51": "xyz", + "52": "abc", + "53": "def" + } +<\/script> +`; + beforeEach((done) => { + let mocks = document.getElementById("mocks"); + mocks.innerHTML = html16; + let elem = document.getElementById("mock-translations"); + Embed.assignTranslationsToElement(elem).then((o) => { + done(); + }).catch((e) => { + done(e); + }); + }); + afterEach(() => { + let mocks = document.getElementById("mocks"); + mocks.innerHTML = ""; + }); + before(function(done) { + initJSDOM().then(() => { + done(); + }); + }); + [ + ["path:status | tostring | i18n", { status: 51 }, "xyz"] + ].forEach(function(data) { + let pipe = data.shift(); + let obj = data.shift(); + let expected = data.shift(); + it("should transform(" + pipe + ").run(" + JSON.stringify(obj) + ") return " + JSON.stringify(expected), function() { + let t = new Pipe(pipe); + expect(t.run(obj)).to.be.equal(expected); + }); + }); + }); + }); + + // test/cases/data/extend.mjs + init_extend(); + var MockForExtends = class { + constructor() { + } + }; + describe("extend", function() { + [ + [ + '{"thekey":{}}', + {}, + { thekey: new MockForExtends() } + ], + [ + '{"a":{"b":["1","2","3"]}}', + { + a: { + b: [ + "1", + "2", + "3" + ] + } + }, + { + a: { + b: [] + } + } + ], + [ + '{"a":{"b":1,"d":1}}', + { + a: { + b: 1 + } + }, + { + a: { + d: 1 + } + } + ], + [ + '{"a":{"b":1,"d":{"x":["car"],"f":true,"g":[]}}}', + {}, + { + a: { + b: 1, + d: { x: ["car"] } + } + }, + { + a: { + d: { + f: true, + g: [] + } + } + } + ] + ].forEach(function(data) { + let d2 = data.shift(); + let a2 = data; + it(".extend(" + JSON.stringify(a2) + ") should result in " + d2, function() { + let x = extend.apply(this, a2); + expect(JSON.stringify(x)).is.equal(d2); + }); + }); + [ + [ + {}, + { + a: { + b: 1, + d: ["car"] + } + }, + { + a: { + d: { + f: true, + g: [] + } + } + } + ], + [ + { + a: {} + }, + { + a: [] + } + ] + ].forEach(function(data) { + let a2 = data; + it(".extend(" + JSON.stringify(a2) + ") should throw Error ", function() { + expect(() => extend.apply(this, a2)).to.throw(Error); + }); + }); + }); + + // source/constraints/abstract.mjs + init_base(); + init_constants(); + var AbstractConstraint = class extends Base { + /** + * + */ + constructor() { + super(); + } + /** + * this method must return a promise containing the result of the check. + * + * @param {*} value + * @returns {Promise} + */ + isValid(value) { + return Promise.reject(value); + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/constraints/abstract-constraint"); + } + }; + + // source/constraints/invalid.mjs + init_constants(); + var Invalid = class extends AbstractConstraint { + /** + * this method return a rejected promise + * + * @param {*} value + * @returns {Promise} + */ + isValid(value) { + return Promise.reject(value); + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/constraints/invalid"); + } + }; + + // test/cases/constraint/invalid.mjs + describe("Invalid", function() { + describe(".isValid()", function() { + let isvalid = new Invalid(); + it("should resolve promise", function(done) { + isvalid.isValid().catch((e) => { + expect(e).to.be.undefined; + done(); + }); + }); + }); + }); + + // test/cases/constraint/abstractoperator.mjs + init_base(); + + // source/constraints/abstractoperator.mjs + init_constants(); + var AbstractOperator = class extends AbstractConstraint { + /** + * + * @param {AbstractConstraint} operantA + * @param {AbstractConstraint} operantB + * @throws {TypeError} "parameters must be from type AbstractConstraint" + */ + constructor(operantA, operantB) { + super(); + if (!(operantA instanceof AbstractConstraint && operantB instanceof AbstractConstraint)) { + throw new TypeError("parameters must be from type AbstractConstraint"); + } + this.operantA = operantA; + this.operantB = operantB; + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/constraints/abstract-operator"); + } + }; + + // test/cases/constraint/abstractoperator.mjs + var AbstractConstraintMock = class extends Base { + constructor() { + super(); + } + isValid(value) { + return Promise.reject(value); + } + }; + describe("AbstractOperator", function() { + it("should throw an error when the constraint is not call with parameter", function(done) { + try { + new AbstractOperator(); + } catch (e) { + done(); + } + }); + it("should throw not an error when the constraint is not call with parameter", function(done) { + try { + const c = new AbstractOperator(new AbstractConstraintMock(), new AbstractConstraintMock()); + } catch (e) { + done(); + } + }); + }); + + // source/constraints/valid.mjs + init_constants(); + var Valid = class extends AbstractConstraint { + /** + * this method return a promise containing the result of the check. + * + * @param {*} value + * @returns {Promise} + */ + isValid(value) { + return Promise.resolve(value); + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/constraints/valid"); + } + }; + + // source/constraints/oroperator.mjs + init_constants(); + var OrOperator = class extends AbstractOperator { + /** + * this method return a promise containing the result of the check. + * + * @param {*} value + * @returns {Promise} + */ + isValid(value) { + var self2 = this; + return new Promise(function(resolve, reject) { + let a2; + let b; + self2.operantA.isValid(value).then(function() { + resolve(); + }).catch(function() { + a2 = false; + if (b === false) { + reject(); + } + }); + self2.operantB.isValid(value).then(function() { + resolve(); + }).catch(function() { + b = false; + if (a2 === false) { + reject(); + } + }); + }); + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/constraints/or-operator"); + } + }; + + // test/cases/constraint/oroperator.mjs + describe("OrOperator", function() { + describe(".isValid()", function() { + [ + [new Valid(), new Valid(), true], + [new Valid(), new Invalid(), true], + [new Invalid(), new Valid(), true], + [new Invalid(), new Invalid(), false] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + let c = data.shift(); + it("constraint.isValid() should return " + c, function(done) { + let constraint = new OrOperator(a2, b); + constraint.isValid().then(() => { + c === true ? done() : done(new Error()); + }).catch(() => { + c === true ? done(new Error()) : done(); + }); + }); + }); + }); + }); + + // source/constraints/isobject.mjs + init_is(); + init_constants(); + var IsObject = class extends AbstractConstraint { + /** + * this method return a promise containing the result of the check. + * + * @param {*} value + * @returns {Promise} + */ + isValid(value) { + if (isObject(value)) { + return Promise.resolve(value); + } + return Promise.reject(value); + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/constraint/is-object"); + } + }; + + // test/cases/constraint/isobject.mjs + describe("IsObject", function() { + describe(".isValid()", function() { + let constraint = new IsObject(); + it("should resolve promise", function(done) { + constraint.isValid({}).then((r) => { + expect(r).is.a("object"); + done(); + }).catch((e) => { + done(new Error("should not reached: " + e)); + }); + }); + }); + }); + + // source/constraints/andoperator.mjs + init_constants(); + var AndOperator = class extends AbstractOperator { + /** + * this method return a promise containing the result of the check. + * + * @param {*} value + * @returns {Promise} + */ + isValid(value) { + return Promise.all([this.operantA.isValid(value), this.operantB.isValid(value)]); + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/constraints/and-operator"); + } + }; + + // test/cases/constraint/andoperator.mjs + describe("AndOperator", function() { + describe(".isValid()", function() { + [ + [new Valid(), new Valid(), true], + [new Valid(), new Invalid(), false], + [new Invalid(), new Valid(), false], + [new Invalid(), new Invalid(), false] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + let c = data.shift(); + it("constraint.isValid() should return " + c, function(done) { + let constraint = new AndOperator(a2, b); + constraint.isValid().then(() => { + c === true ? done() : done(new Error()); + }).catch(() => { + c === true ? done(new Error()) : done(); + }); + }); + }); + }); + }); + + // source/constraints/isarray.mjs + init_is(); + init_constants(); + var IsArray = class extends AbstractConstraint { + /** + * this method return a promise containing the result of the check. + * + * @param {*} value + * @returns {Promise} + */ + isValid(value) { + if (isArray(value)) { + return Promise.resolve(value); + } + return Promise.reject(value); + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/constraint/is-array"); + } + }; + + // test/cases/constraint/isarray.mjs + describe("IsArray", function() { + describe(".isValid()", function() { + let constraint = new IsArray(); + it("should resolve promise", function(done) { + constraint.isValid([1, 2, 3]).then((r) => { + expect(r).is.a("array"); + done(); + }).catch((e) => { + done(new Error("should not reached: " + e)); + }); + }); + }); + }); + + // test/cases/constraint/valid.mjs + describe("Valid", function() { + describe(".isValid()", function() { + let constraint = new Valid(); + it("should resolve promise", function(done) { + constraint.isValid({}).then((r) => { + done(); + }).catch((e) => { + done(new Error("should not reached: " + e)); + }); + }); + }); + }); + + // test/cases/types/nodelist.mjs + describe("NodeList", function() { + describe("#constructor", function() { + it("should create an empty NodeList", function() { + let nodeList = new NodeList2(); + expect(nodeList.size).to.equal(0); + }); + it("should create a NodeList from an array", function() { + let nodeList = new NodeList2([ + new Node2("div"), + new Node2("div"), + new Node2("div") + ]); + expect(nodeList.size).to.equal(3); + }); + it("should create a NodeList from a NodeList", function() { + let nodeList = new NodeList2([ + new Node2("div"), + new Node2("div"), + new Node2("div") + ]); + let nodeList2 = new NodeList2(nodeList); + expect(nodeList2.size).to.equal(3); + }); + }); + it("create NodeList", function() { + expect(new NodeList2()).is.instanceof(NodeList2); + }); + it("add Node", function() { + expect(new NodeList2().add(new Node2())).to.be.instanceof(NodeList2); + }); + it("remove Node", function() { + expect(new NodeList2().remove(new Node2())).to.be.instanceof(NodeList2); + }); + it("has unknown Node", function() { + expect(new NodeList2().has(new Node2())).to.be.false; + }); + it("has added Node", function() { + const n = new Node2(); + expect(new NodeList2().add(n).has(n)).to.be.true; + }); + it("toString", function() { + const n = new Node2(); + expect(new NodeList2().add(new Node2("a").appendChild(new Node2("b"))).toString()).to.be.equal("a\n \u2514b"); + }); + it("throw exception", function() { + expect(() => new NodeList2().add(1)).to.throw(Error); + }); + }); + + // test/cases/types/base.mjs + init_base(); + init_constants(); + var BaseDifferentRealm = class extends Object { + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/types/base"); + } + }; + var Subclass = class extends BaseDifferentRealm { + constructor() { + super(); + } + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/types/subclass"); + } + }; + describe("Base", function() { + describe("new Base", function() { + it("is instance of Base", function() { + expect(new Base()).to.be.instanceOf(Base); + }); + it("is instance of Object", function() { + expect(new Base()).to.be.instanceOf(Object); + }); + }); + describe("instancof", function() { + it("is instance of Base", function() { + expect(new Base()).to.be.instanceOf(Base); + }); + it("subclass instanceof", function() { + if (new Subclass() instanceof Base) { + expect(true).to.be.true; + } else { + expect(false).to.be.true; + } + }); + }); + }); + + // test/cases/types/mediatype.mjs + init_mediatype(); + describe("Dataurl", function() { + [ + ["*/*", "*", "*"], + ["text/*", "text", "*"], + ["*/test", "*", "test"], + ["image/png", "image", "png"], + ["audio/mp3", "audio", "mp3"], + ["video/mpeg", "video", "mpeg"], + ["text/plain", "text", "plain"], + ["text/html", "text", "html"], + ["text/html;charset=US-ASCII", "text", "html"], + ['text/html;charset="US-ASCII"', "text", "html"] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + let c = data.shift(); + it("parseMediaType(" + a2 + ")", function() { + const d2 = parseMediaType(a2); + expect(d2).is.instanceof(MediaType); + expect(d2.toString()).to.be.equal(a2); + expect(d2.type).to.be.equal(b); + expect(d2.subtype).to.be.equal(c); + expect(d2.parameter).is.instanceof(Map); + }); + }); + [ + ["video/"], + ["text"], + ["/mp3"], + ["text/html;charsetUS-ASCII"], + ['text/html;charset"US-ASCII"'] + ].forEach(function(data) { + let a2 = data.shift(); + it("" + a2 + " should throw exception", function() { + expect(() => { + parseMediaType(a2); + }).throw(TypeError); + }); + }); + }); + + // test/cases/types/tokenlist.mjs + init_tokenlist(); + describe("TokenList", function() { + describe(".toString()", function() { + let tokenList = new TokenList(); + let result = tokenList.toString(); + it("should return a string", function() { + expect(result).to.be.a("string"); + }); + it("set and remove return a string", function() { + expect(result).to.be.a("string"); + }); + }); + describe("init with string iterable", function() { + it("new TokenList(" + typeof a + ") throw TypeError ", function() { + let tokens = ["abc", "def", "ghi"]; + let list = new TokenList(tokens); + expect(list.toString()).is.equal("abc def ghi"); + }); + }); + describe("init with iterable without string values", function() { + it("new TokenList(" + typeof a + ") throw TypeError ", function() { + let tokens = ["abc", 4, "ghi"]; + expect(() => new TokenList(tokens)).to.throw(TypeError); + }); + }); + describe("init values", function() { + [ + // current, expected, typerror + ["test1", "test1", false], + ["test1 test2", "test1 test2", false], + [void 0, "", false], + [null, void 0, true], + [parseInt("a"), void 0, true], + // NaN + [() => { + }, void 0, true], + [2, void 0, true], + [false, void 0, true], + [true, void 0, true], + [4.5, void 0, true], + [{}, void 0, true], + [["1", "2", "3"], "1 2 3", false], + // iterable strings + [[1, 2, 3], void 0, true], + [Symbol("foo"), false, true] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + let c = data.shift(); + if (c === true) { + it("new TokenList(" + typeof a2 + ") throw TypeError ", function() { + expect(() => new TokenList(a2)).to.throw(TypeError); + }); + } else { + it("new TokenList(" + typeof a2 + ") should return " + b, function() { + expect(new TokenList(a2).toString()).is.equal(b); + }); + } + }); + }); + describe("iterator protocol", function() { + let list; + it(".add(second) should return TokenList", function() { + list = new TokenList("start"); + expect(list.getIterator()).to.be.an("object"); + }); + it(".add(second) should return TokenList", function() { + list = new TokenList("start end"); + expect([...list]).to.be.an("array"); + expect([...list]).to.be.an("array").to.include("start").to.include("end"); + }); + }); + describe(".entries()", function() { + let list; + it(".entries() should return Array", function() { + list = new TokenList("start"); + expect(list.entries()).to.be.an("array"); + }); + it(".entries() should return Array", function() { + list = new TokenList("start end").entries(); + expect(list).to.be.an("array").to.include("start").to.include("end"); + }); + }); + describe(".forEach()", function() { + let list; + it(".forEach() should iterate over tokenlist", function() { + list = new TokenList("aaa bbb ccc ddd eee fff"); + let result = ""; + list.forEach((a2) => { + result += "!" + a2 + "!"; + expect(a2).to.be.an("string"); + }); + expect(result).is.equal("!aaa!!bbb!!ccc!!ddd!!eee!!fff!"); + }); + it(".entries() should return Array", function() { + list = new TokenList("start end").entries(); + expect(list).to.be.an("array").to.include("start").to.include("end"); + }); + }); + describe("contains values", function() { + let list; + it("new TokenList(start, middle end) should contain middle", function() { + list = new TokenList("start middle end"); + expect(list.contains("start")).to.be.true; + expect(list.contains("middle")).to.be.true; + expect(list.contains("end")).to.be.true; + expect(list.contains(["end", "start", "middle"])).to.be.true; + }); + it("new TokenList(start, middle end) should not contain xyz", function() { + list = new TokenList("start middle end"); + expect(list.contains("xyz")).to.be.false; + expect(list.contains(["end", "start", "middle", "xyz"])).to.be.false; + }); + it("new TokenList(start, middle end) should not contain undefined null NaN", function() { + list = new TokenList("start middle end"); + expect(list.contains(void 0)).to.be.false; + expect(list.contains(parseInt("a"))).to.be.false; + expect(list.contains(null)).to.be.false; + }); + }); + describe("toggle values", function() { + let list; + it("new TokenList(start middle end).toggle(new-value) should contain new-value", function() { + list = new TokenList("start middle end"); + expect(list.toggle("new-value").toString()).is.equal("start middle end new-value"); + }); + it("new TokenList(start middle end).toggle(middle) should not contain middle", function() { + list = new TokenList("start middle end"); + expect(list.toggle("middle").toString()).is.equal("start end"); + }); + it("new TokenList().toggle() should ...", function() { + expect(new TokenList("abc def ghi").toggle("def xyz").toString()).to.equal("abc ghi xyz"); + }); + it("new TokenList().toggle() should ...", function() { + expect(new TokenList("abc def ghi").toggle(["abc", "xyz"]).toString()).to.equal("def ghi xyz"); + }); + it("new TokenList().toggle() should ...", function() { + expect(new TokenList("abc def ghi").toggle(void 0).toString()).to.equal("abc def ghi"); + }); + }); + describe("manipulate values", function() { + let list; + it('result TokenList("start") should be "start"', function() { + list = new TokenList("start"); + expect(list.toString()).is.equal("start"); + }); + it(".add(second) should return TokenList", function() { + list = new TokenList("start"); + expect(list.add("second")).to.be.an.instanceof(TokenList); + }); + it('.add(second).toString() should return "start second" ', function() { + list = new TokenList("start"); + expect(list.add("second").toString()).is.equal("start second"); + }); + it('.add(second third).toString() should return "start second third" ', function() { + list = new TokenList("start"); + expect(list.add("second third").toString()).is.equal("start second third"); + }); + it('.add([second,third]).toString() should return "start second third" ', function() { + list = new TokenList("start"); + expect(list.add(["second", "third"]).toString()).is.equal("start second third"); + }); + it('.clear().toString() should "" ', function() { + list = new TokenList("start"); + expect(list.add(["second", "third"]).clear().toString()).is.equal(""); + }); + it('new TokenList("start second third end").remove(second) should return TokenList', function() { + list = new TokenList("start second third end"); + expect(list.remove("second")).to.be.an.instanceof(TokenList); + }); + it('new TokenList("start second third end").remove(second).toString() should return "start third end" ', function() { + list = new TokenList("start second third end"); + expect(list.remove("second").toString()).is.equal("start third end"); + }); + it('new TokenList("start second third end").remove(second third).toString() should return "start end" ', function() { + list = new TokenList("start second third end"); + expect(list.remove("second third").toString()).is.equal("start end"); + }); + it('new TokenList("start second third end").remove([second,third]).toString() should return "start end" ', function() { + list = new TokenList("start second third end"); + expect(list.remove(["second", "third"]).toString()).is.equal("start end"); + }); + it('new TokenList("start second third end").replace(second, xyz).toString() should return "start xyz third end" ', function() { + list = new TokenList("start second third end"); + expect(list.replace("second", "xyz")).to.be.instanceOf(TokenList); + expect(list.toString()).is.equal("start xyz third end"); + }); + it('new TokenList("start second third end").replace(end, xyz).toString() should return "start second third xyz" ', function() { + list = new TokenList("start second third end"); + expect(list.replace("end", "xyz")).to.be.instanceOf(TokenList); + expect(list.toString()).is.equal("start second third xyz"); + }); + }); + }); + + // test/cases/types/proxyobserver.mjs + init_extend(); + init_is(); + init_observer(); + init_proxyobserver(); + describe("ProxyObserver", function() { + describe("create", function() { + it("should return instanceof ProxyObserver", function() { + let o = new ProxyObserver({}); + extend(o.getSubject(), { a: 4 }); + expect(o.getRealSubject()).is.eql({ a: 4 }); + }); + }); + describe("setSubject", function() { + it("should run observer", function(done) { + let o = new ProxyObserver({ a: 1 }); + expect(o.getRealSubject()).is.eql({ a: 1 }); + let counter = 0; + o.attachObserver(new Observer(function() { + if (isObject(this) && this instanceof ProxyObserver) { + counter++; + if (counter === 1) { + done(); + return; + } + done("called for error"); + return; + } + done(new Error("this is not ProxyObserver")); + })); + o.getSubject().c = 4; + expect(o.getRealSubject()).is.eql({ a: 1, c: 4 }); + o.setSubject({ b: 2 }); + expect(o.getRealSubject()).is.eql({ b: 2 }); + o.getSubject().d = 5; + expect(o.getRealSubject()).is.eql({ b: 2, d: 5 }); + }); + }); + describe("create", function() { + it("should return instanceof ProxyObserver", function() { + let o = new ProxyObserver({}); + expect(o).is.instanceOf(ProxyObserver); + }); + }); + describe("proxy objects", function() { + it("Proxy objects should not be recommitted", function() { + let o = new ProxyObserver({ a: { b: true } }); + o.getSubject().a.b = o.getSubject(); + o.getSubject().a.b.a.b = false; + }); + }); + describe("notify observer", function() { + it("should inform observer", function(done) { + let counter = 0; + let o = new Observer(function(a2) { + if (isObject(this) && this instanceof ProxyObserver) { + counter++; + if (counter === 1) { + done(); + } + return; + } + done(new Error("this is not ProxyObserver")); + }, true); + let realSubject = { + a: { + b: { + c: true + }, + d: 5 + } + }; + let p = new ProxyObserver(realSubject); + expect(p).is.instanceOf(ProxyObserver); + expect(p.attachObserver(o)).is.instanceOf(ProxyObserver); + let s = p.getSubject(); + let r = p.getRealSubject(); + s.a.d = false; + s.a.b.d = 2; + }); + }); + describe("Reflect", function() { + it("check Reflect.set() with Subject", function() { + let r; + const obj = new ProxyObserver({}).getSubject(); + [ + "yes!", + void 0, + "no" + ].forEach(function(value) { + expect(() => { + obj["data"] = value; + }).to.not.throw(); + }); + }); + [ + ["that", { that: "checked1" }], + ["that", new Proxy({ that: "checked2" }, {})], + ["that", new ProxyObserver({ that: "checked3" }).getRealSubject()], + ["that", new ProxyObserver({ that: "checked4" }).getSubject()] + ].forEach(function(data) { + let key = data.shift(); + let target = data.shift(); + it("check Reflect.set(" + key + "," + JSON.stringify(target) + ") should writable", function() { + let value; + [ + "1", + void 0, + true, + void 0, + false, + void 0, + void 0 + ].forEach(function(values) { + expect(Reflect.getOwnPropertyDescriptor( + target, + key + )["writable"], "writable for " + value + " should return true").to.be.true; + expect(Reflect.set(target, key, value), "set for " + value + " should return true").to.be.true; + expect(Reflect.getOwnPropertyDescriptor( + target, + key + )["writable"], "writable for " + value + " should return true").to.be.true; + }); + }); + }); + }); + describe("notify observer with changes", function() { + let original, observer, proxy; + before(function() { + original = {}; + proxy = new ProxyObserver(original); + }); + [ + ["a", 4, JSON.stringify({ a: 4 })], + ["b", 9, JSON.stringify({ a: 4, b: 9 })] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + let c = data.shift(); + it("set key " + a2 + " value " + b + " expect " + c, function(done) { + let counter = 0; + observer = new Observer(function() { + counter++; + expect(JSON.stringify(this.getRealSubject())).is.equal(c); + if (counter === 1) { + this.detachObserver(observer); + done(); + } + }); + proxy.attachObserver(observer); + let subject = proxy.getSubject(); + subject[a2] = b; + }); + }); + }); + describe("notify observer ", function() { + it("should return promise", function() { + let proxy = new ProxyObserver({}); + let observer = new Observer(function() { + }); + proxy.attachObserver(observer); + expect(proxy.notifyObservers()).is.instanceOf(Promise); + }); + }); + }); + + // test/cases/types/version.mjs + describe("Version", function() { + describe(".compareTo()", function() { + [ + ["1.2.3", "1.2.3", 0], + ["1.2.2", "1.2.3", -1], + ["2", "2.0.0", 0], + ["1.2.4", "1.2.3", 1] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + let c = data.shift(); + it("should return " + c + " when the value " + a2 + " is " + b, function() { + expect(new Version(a2).compareTo(b)).to.be.equal(c); + }); + }); + }); + describe(".toString()", function() { + [ + ["1.1.1", "2.3", 3, "1.2.3"], + ["1.2.4", "1.2.3", 5, "1.1.5"] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + let c = data.shift(); + let d2 = data.shift(); + it("should return " + d2, function() { + expect(new Version(a2, b, c).toString()).to.be.equal(d2); + }); + }); + }); + }); + + // test/cases/types/global.mjs + init_global(); + describe("Global", function() { + describe("getGlobal", function() { + it("should return global object", function() { + let t = typeof getGlobal(); + expect(t).to.be.equal("object"); + }); + }); + describe("getGlobalFunction", function() { + it("should return global function", function() { + let t = typeof getGlobalFunction("parseInt"); + expect(t).to.be.equal("function"); + }); + }); + describe("getGlobalObject", function() { + it("should return global object", function() { + let t = typeof getGlobalObject("JSON"); + expect(t).to.be.equal("object"); + }); + }); + }); + + // test/cases/types/observerlist.mjs + init_observerlist(); + init_observer(); + describe("ObserverList", function() { + describe(".attach()", function() { + it("should return instanceof ObserverList", function() { + let observerList = new ObserverList(); + let result = observerList.attach(new Observer(() => { + })); + expect(result).to.be.instanceOf(ObserverList); + }); + }); + describe(".detach()", function() { + it("should return instanceof ObserverList", function() { + let observerList = new ObserverList(); + let result = observerList.detach(new Observer(() => { + })); + expect(result).to.be.instanceOf(ObserverList); + }); + }); + describe(".notify()", function() { + const resultValue = "Yes!"; + let o; + let observerList; + beforeEach(() => { + o = new Observer(() => { + return resultValue; + }); + observerList = new ObserverList(); + observerList.attach(o); + }); + it("should instanceof Promise", function() { + expect(observerList.notify({})).to.be.instanceOf(Promise); + }); + it("should return " + resultValue, function(done) { + let obj = {}; + observerList.notify(obj).then((r) => { + expect(r).to.be.an("array").that.includes(resultValue); + done(); + }).catch((e) => { + done(new Error(e)); + }); + }); + }); + describe(".contains()", function() { + let o1 = new Observer(() => { + }); + let o2 = new Observer(() => { + }); + it("should not contain o1 and o2", function() { + let observerList = new ObserverList(); + expect(observerList.contains(o1)).to.be.false; + expect(observerList.contains(o2)).to.be.false; + }); + it("should contain o2 and not o1", function() { + let observerList = new ObserverList(); + observerList.attach(o2); + expect(observerList.contains(o1)).to.be.false; + expect(observerList.contains(o2)).to.be.true; + }); + it("should contain o1 and not o2", function() { + let observerList = new ObserverList(); + observerList.attach(o1); + expect(observerList.contains(o1)).to.be.true; + expect(observerList.contains(o2)).to.be.false; + }); + it("should contain o2 and o1", function() { + let observerList = new ObserverList(); + observerList.attach(o2).attach(o1); + expect(observerList.contains(o1)).to.be.true; + expect(observerList.contains(o2)).to.be.true; + }); + }); + }); + + // test/cases/types/internal.mjs + init_observer(); + var SomeRandomClass1 = class extends Object { + doit() { + return "done"; + } + }; + var SomeRandomClass2 = class extends Object { + constructor() { + super(); + equipWithInternal.call(this); + } + get defaultInternal() { + return { + test: "test" + }; + } + }; + describe("Base inject with options", function() { + describe("new SomeRandomClass", function() { + it("is instance of SomeRandomClass1", function() { + expect(new SomeRandomClass2()).not.to.be.instanceOf(SomeRandomClass1); + expect(new SomeRandomClass2()).to.be.instanceOf(SomeRandomClass2); + }); + it("is instance of SomeRandomClass2", function() { + expect(new SomeRandomClass1()).to.be.instanceOf(SomeRandomClass1); + expect(new SomeRandomClass1()).not.to.be.instanceOf(SomeRandomClass2); + }); + }); + describe("Extends SomeRandomClass with internals", function() { + it("attach and notify internal observer", function(done) { + const c = new SomeRandomClass2(); + c.attachInternalObserver(new Observer(() => { + done(); + })); + c.setInternal("test", "test"); + }); + it("attach and remove internal observer", function() { + const c = new SomeRandomClass2(); + const observer = new Observer(() => { + }); + expect(c.containsInternalObserver(observer)).to.be.false; + c.attachInternalObserver(observer); + expect(c.containsInternalObserver(observer)).to.be.true; + c.detachInternalObserver(observer); + expect(c.containsInternalObserver(observer)).to.be.false; + }); + it("getInternal and setInternal", function() { + const c = new SomeRandomClass2(); + expect(c.setInternal("test", "yeah")).to.be.instanceOf(SomeRandomClass2); + expect(c.getInternal("test")).to.be.equal("yeah"); + }); + it("deal with default values", function() { + const testClass = class extends Object { + constructor() { + super(); + equipWithInternal.call(this); + } + get internalDefaults() { + return { + test: "xyz" + }; + } + }; + const c = new testClass(); + expect(c.getInternal("test")).to.be.equal("xyz"); + expect(c.getInternal("test2", "abc")).to.be.equal("abc"); + }); + it("deal with defaults from defaults", function() { + const testClass = class extends Object { + constructor() { + super(); + equipWithInternal.call(this); + } + get internalDefaults() { + return { + test: "xyz" + }; + } + }; + const testClass2 = class extends testClass { + constructor() { + super(); + equipWithInternal.call(this); + } + get internalDefaults() { + return Object.assign({}, super.internalDefaults, { + test2: "abc" + }); + } + }; + const c = new testClass2(); + expect(c.getInternal("test")).to.be.equal("xyz"); + expect(c.getInternal("test2")).to.be.equal("abc"); + }); + it("set multiple values", function() { + const c = new SomeRandomClass2(); + expect(c.setInternals({ + test: "yeah", + test2: "yeah2" + })).to.be.instanceOf(SomeRandomClass2); + expect(c.getInternal("test")).to.be.equal("yeah"); + expect(c.getInternal("test2")).to.be.equal("yeah2"); + c.setInternals({ + test2: "yeah2-new", + test3: "yeah3" + }); + expect(c.getInternal("test")).to.be.equal("yeah"); + expect(c.getInternal("test2")).to.be.equal("yeah2-new"); + expect(c.getInternal("test3")).to.be.equal("yeah3"); + }); + }); + }); + + // test/cases/types/observablequeue.mjs + init_observer(); + describe("ObservableQueue", function() { + describe("Observer", function() { + it("should notify", function(done) { + let queue = new ObservableQueue(); + let o = new Observer((q) => { + done(); + }); + queue.attachObserver(o); + expect(queue.add("a")).to.be.instanceOf(ObservableQueue); + }); + }); + }); + + // test/cases/types/dataurl.mjs + init_dataurl(); + describe("Dataurl", function() { + [ + [" data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E"], + ["data:text/html;charset=US-ASCII,%3Ch1%3EHello!%3C%2Fh1%3E"], + ["data:,A%20brief%20note", "data:text/plain;charset=US-ASCII,A%20brief%20note"], + ["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD///+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC"], + [" data:,Hello%2C%20World!", "data:text/plain;charset=US-ASCII,Hello%2C%20World!"], + [" data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIBAMAAAA2IaO4AAAAFVBMVEXk5OTn5+ft7e319fX29vb5+fn///++GUmVAAAALUlEQVQIHWNICnYLZnALTgpmMGYIFWYIZTA2ZFAzTTFlSDFVMwVyQhmAwsYMAKDaBy0axX/iAAAAAElFTkSuQmCC "], + [" data:,Hello World!", "data:text/plain;charset=US-ASCII,Hello%20World!"], + ["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIBAMAAAA2IaO4AAAAFVBMVEXk5OTn5+ft7e319fX29vb5+fn///++GUmVAAAALUlEQVQIHWNICnYLZnALTgpmMGYIFWYIZTA2ZFAzTTFlSDFVMwVyQhmAwsYMAKDaBy0axX/iAAAAAElFTkSuQmCC"], + [" data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D"] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + if (b === void 0) + b = a2.trim(); + it("parseDataURL(" + a2 + ")", function() { + expect(parseDataURL(a2).toString()).to.be.equal(b); + }); + }); + [ + ["dataxbase64"], + ["data:HelloWorld"], + ["data:text/html;charset=,%3Ch1%3EHello!%3C%2Fh1%3E"], + ["data:text/html;charset,%3Ch1%3EHello!%3C%2Fh1%3E", "data:base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD///+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC"], + [""], + ["http://wikipedia.org"], + ["base64"], + ["iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD///+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC"] + ].forEach(function(data) { + let a2 = data.shift(); + it("should throw exception parseDataURL(" + a2 + ")", function() { + expect(() => parseDataURL(a2)).throw(TypeError); + }); + }); + }); + + // source/types/binary.mjs + init_validate(); + function toBinary(string) { + const codeUnits = new Uint16Array(validateString(string).length); + for (let i = 0; i < codeUnits.length; i++) { + codeUnits[i] = string.charCodeAt(i); + } + const charCodes = new Uint8Array(codeUnits.buffer); + let result = ""; + for (let i = 0; i < charCodes.byteLength; i++) { + result += String.fromCharCode(charCodes[i]); + } + return result; + } + function fromBinary(binary) { + const bytes = new Uint8Array(validateString(binary).length); + for (let i = 0; i < bytes.length; i++) { + bytes[i] = binary.charCodeAt(i); + } + const charCodes = new Uint16Array(bytes.buffer); + let result = ""; + for (let i = 0; i < charCodes.length; i++) { + result += String.fromCharCode(charCodes[i]); + } + return result; + } + + // test/cases/types/binary.mjs + describe("Binary", function() { + [ + ["a", "a\0"], + ["\u2639", "9&"], + ["I\xF1t\xEBrn\xE2ti\xF4n\xE0liz\xE6ti\xF8n", "I\0\xF1\0t\0\xEB\0r\0n\0\xE2\0t\0i\0\xF4\0n\0\xE0\0l\0i\0z\0\xE6\0t\0i\0\xF8\0n\0"] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + it("fromBinary(toBinary(" + a2 + ")) should work", function() { + let r = toBinary(a2); + expect(r).to.be.equal(b); + expect(fromBinary(r)).to.be.equal(a2); + }); + }); + }); + + // test/cases/types/observer.mjs + init_observer(); + describe("Observer", function() { + let callback = function() { + }; + let observer = new Observer(callback); + describe(".addTag()", function() { + [ + ["test1"], + ["test2"] + ].forEach(function(data) { + let a2 = data.shift(); + it("addTag(" + a2 + ") should return instanceof Observer", function() { + expect(observer.addTag(a2)).is.instanceOf(Observer); + }); + }); + }); + describe(".removeTag()", function() { + [ + ["test1"], + ["test2"] + ].forEach(function(data) { + let a2 = data.shift(); + it("removeTag(" + a2 + ") should return instanceof Observer", function() { + expect(observer.removeTag(a2)).is.instanceOf(Observer); + }); + }); + }); + describe(".hasTag()", function() { + [ + ["test1", true], + ["test2", true], + ["test3", false], + ["test4", false] + ].forEach(function(data) { + let tempObserver = new Observer(callback); + let a2 = data.shift(); + let b = data.shift(); + it("observer.hastTag(" + a2 + ") should return " + b, function() { + if (b === true) { + tempObserver.addTag(a2); + expect(tempObserver.hasTag(a2)).is.be.true; + } else { + expect(tempObserver.hasTag(a2)).is.be.false; + } + }); + }); + }); + describe(".update()", function() { + let obj = {}; + it("observer.update(" + obj + ") is 136", function(done) { + let tempObserver = new Observer(function(a2, b, c) { + return a2 + b + c; + }, 1, 3, 6); + tempObserver.update(obj).then((a2) => { + expect(a2).is.equal(1 + 3 + 6); + done(); + }); + }); + }); + describe("run function .update() several times", function() { + let obj = {}; + it("observer.update(" + obj + ") is 136", function(done) { + let counter = 0; + let tempObserver = new Observer(function(a2, b, c) { + counter++; + }); + tempObserver.update(obj); + tempObserver.update(obj); + tempObserver.update(obj); + tempObserver.update(obj); + tempObserver.update(obj).then((_) => { + done(); + }); + }); + }); + describe(".getTags()", function() { + [ + [["test1", "test2", "test3", "test4"], 4], + [["test1", "test1", "test3", "test4"], 3], + // double test1 (set is uniqueue) + [["test1", "test1", "test1", "test4"], 2] + // multiple test1 (set is uniqueue) + ].forEach(function(data) { + let tempObserver = new Observer(callback); + let a2 = data.shift(); + let b = data.shift(); + for (let i = 0, max = a2.length; i < max; i++) { + tempObserver.addTag(a2[i]); + } + it("observer.getTags(" + a2 + ") is array", function() { + expect(tempObserver.getTags()).to.be.an("array"); + }); + it("observer.getTags(" + a2 + ") should return " + b + " tags", function() { + expect(tempObserver.getTags().length).is.equal(b); + }); + }); + }); + }); + + // source/types/regex.mjs + init_validate(); + function escapeString(value) { + return validateString(value).replace(/[|\\{}()[\]^$+*?.]/g, "\\$&").replace(/-/g, "\\x2d"); + } + + // test/cases/types/regex.mjs + describe("escapeString", function() { + before(function(done) { + let promises = []; + promises.push(initJSDOM()); + if (!globalThis["crypto"]) { + promises.push(Promise.resolve().then(() => (init_webcrypto_es(), webcrypto_es_exports)).then((m) => { + globalThis["crypto"] = new m.Crypto(); + return true; + })); + } + Promise.all(promises).then(() => { + done(); + }); + }); + [ + ["test1", "test1"], + ["${", "\\$\\{"], + ["i18n{", "i18n\\{"], + ["//", "//"], + ["\\", "\\\\"] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + it("escapeString(" + a2 + ") should return " + b, function() { + expect(escapeString(a2)).is.equal(b); + }); + }); + }); + + // test/cases/types/randomid.mjs + describe("RandomID", function() { + class RandomID2 { + } + before(function(done) { + let promises = []; + if (!globalThis["crypto"]) { + promises.push(Promise.resolve().then(() => (init_webcrypto_es(), webcrypto_es_exports)).then((m) => { + globalThis["crypto"] = new m.Crypto(); + return true; + })); + } + promises.push(Promise.resolve().then(() => (init_randomid(), randomid_exports)).then((m) => { + RandomID2 = m.RandomID; + return true; + })); + Promise.all(promises).then(() => { + done(); + }); + }); + describe(".toString()", function() { + let id = new RandomID2(); + let result = id.toString(); + it("should return a string", function() { + expect(result).is.a("string"); + }); + }); + }); + + // test/cases/types/id.mjs + init_id(); + describe("ID", function() { + before(function(done) { + let promises = []; + if (!globalThis["crypto"]) { + promises.push(Promise.resolve().then(() => (init_webcrypto_es(), webcrypto_es_exports)).then((m) => { + globalThis["crypto"] = new m.Crypto(); + return true; + })); + } + Promise.all(promises).then(() => { + done(); + }); + }); + describe(".toString()", function() { + let id = new ID(); + let result = id.toString(); + it("should return a string", function() { + expect(result).is.a("string"); + }); + it("should return a string", function() { + expect(new ID("text1425id").toString()).is.equal("text1425id1"); + expect(new ID("text1425id").toString()).is.equal("text1425id2"); + expect(new ID("text1425id").toString()).is.equal("text1425id3"); + }); + }); + }); + + // test/cases/types/uuid.mjs + describe("UUID", function() { + class UUID2 { + } + before(function(done) { + let promises = []; + if (!globalThis["crypto"]) { + promises.push(Promise.resolve().then(() => (init_webcrypto_es(), webcrypto_es_exports)).then((m) => { + globalThis["crypto"] = new m.Crypto(); + return true; + })); + } + promises.push(Promise.resolve().then(() => (init_uuid(), uuid_exports)).then((m) => { + UUID2 = m.UUID; + return true; + })); + Promise.all(promises).then(() => { + done(); + }); + }); + describe(".toString()", function() { + it("should return a string", function() { + let uuid = new UUID2(); + let result = uuid.toString(); + expect(result).is.a("string"); + expect(result.length).is.equal(36); + }); + it("test format", function(done) { + let uuid = new UUID2(); + let result = uuid.toString(); + const regexExp = /^[A-F\d]{8}-[A-F\d]{4}-4[A-F\d]{3}-[89AB][A-F\d]{3}-[A-F\d]{12}$/i; + for (let i = 0; i < 2e3; i++) { + const u = new UUID2().toString(); + const r = regexExp.test(u); + if (r !== true) { + done("no uuid " + u + " => " + r); + return; + } + } + done(); + }); + }); + }); + + // test/cases/types/is.mjs + init_is(); + init_id(); + describe("Is", function() { + before(function(done) { + let promises = []; + if (!globalThis["crypto"]) { + promises.push(Promise.resolve().then(() => (init_webcrypto_es(), webcrypto_es_exports)).then((m) => { + globalThis["crypto"] = new m.Crypto(); + return true; + })); + } + Promise.all(promises).then(() => { + done(); + }); + }); + describe(".isPrimitive()", function() { + [ + ["test1", true], + [void 0, true], + [null, true], + [() => { + }, false], + [2, true], + [parseInt("a"), true], + [false, true], + [true, true], + [4.5, true], + [{}, false], + [[1, 2, 3], false], + [Symbol("foo"), true] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + it("is.isPrimitive(" + typeof a2 + ") should return " + b, function() { + expect(isPrimitive(a2)).is.equal(b); + }); + }); + }); + describe(".isSymbol()", function() { + [ + ["test1", false], + [void 0, false], + [null, false], + [() => { + }, false], + [2, false], + [parseInt("a"), false], + [false, false], + [true, false], + [4.5, false], + [{}, false], + [[1, 2, 3], false], + [Symbol("foo"), true] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + it("is.isSymbol(" + typeof a2 + ") should return " + b, function() { + expect(isSymbol(a2)).is.equal(b); + }); + }); + }); + describe(".isInteger()", function() { + [ + ["test1", false], + [void 0, false], + [null, false], + [() => { + }, false], + [2, true], + [parseInt("a"), false], + [false, false], + [true, false], + [4.5, false], + [{}, false], + [[1, 2, 3], false], + [Symbol("foo"), false] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + it("is.isInteger(" + typeof a2 + ") should return " + b, function() { + expect(isInteger(a2)).is.equal(b); + }); + }); + }); + describe(".isIterable()", function() { + [ + ["test1", true], + [void 0, false], + [null, false], + [() => { + }, false], + [parseInt("a"), false], + [2, false], + [false, false], + [true, false], + [4.5, false], + [{}, false], + [[1, 2, 3], true], + [Symbol("foo"), false] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + it("is.isIterable(" + typeof a2 + ") should return " + b, function() { + expect(isIterable(a2)).is.equal(b); + }); + }); + }); + describe(".isBoolean()", function() { + [ + ["test1", false], + [void 0, false], + [null, false], + [() => { + }, false], + [2, false], + [false, true], + [parseInt("a"), false], + [true, true], + [4.5, false], + [{}, false], + [[1, 2, 3], false], + [Symbol("foo"), false] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + it("is.isBoolean(" + typeof a2 + ") should return " + b, function() { + expect(isBoolean(a2)).is.equal(b); + }); + }); + }); + describe(".isString()", function() { + [ + ["test1", true], + [void 0, false], + [null, false], + [() => { + }, false], + [2, false], + [false, false], + [parseInt("a"), false], + [true, false], + [4.5, false], + [{}, false], + [[1, 2, 3], false], + [Symbol("foo"), false] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + it("is.isString(" + typeof a2 + ") should return " + b, function() { + expect(isString(a2)).is.equal(b); + }); + }); + }); + describe(".isInstance()", function() { + [ + [new ID(), ID, true], + [new ID(), () => { + }, false], + ["test1", void 0, false], + [void 0, void 0, false], + [null, void 0, false], + [() => { + }, void 0, false], + [2, void 0, false], + [false, void 0, false], + [parseInt("a"), void 0, false], + [true, void 0, false], + [4.5, void 0, false], + [{}, void 0, false], + [[1, 2, 3], void 0, false], + [Symbol("foo"), void 0, false] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + let c = data.shift(); + it("is.isInstance(" + JSON.stringify(a2) + ") should return " + typeof b, function() { + expect(isInstance(a2, b)).is.equal(c); + }); + }); + }); + describe(".isObject()", function() { + [ + ["test1", false], + [void 0, false], + [null, false], + [() => { + }, false], + [2, false], + [false, false], + [parseInt("a"), false], + [true, false], + [4.5, false], + [{}, true], + [[1, 2, 3], false], + [Symbol("foo"), false] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + it("is.isObject(" + JSON.stringify(a2) + ") should return " + b, function() { + expect(isObject(a2)).is.equal(b); + }); + }); + }); + describe(".isArray()", function() { + [ + ["test1", false], + [void 0, false], + [null, false], + [() => { + }, false], + [2, false], + [false, false], + [parseInt("a"), false], + [true, false], + [4.5, false], + [{}, false], + [[1, 2, 3], true], + [Symbol("foo"), false] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + it("is.isArray(" + typeof a2 + ") should return " + b, function() { + expect(isArray(a2)).is.equal(b); + }); + }); + }); + describe(".isFunction()", function() { + [ + ["test1", false], + [void 0, false], + [null, false], + [() => { + }, true], + [2, false], + [false, false], + [parseInt("a"), false], + [true, false], + [4.5, false], + [{}, false], + [[1, 2, 3], false], + [Symbol("foo"), false] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + it("is.isFunction(" + typeof a2 + ") should return " + b, function() { + expect(isFunction(a2)).is.equal(b); + }); + }); + }); + }); + + // test/cases/types/validate.mjs + init_validate(); + init_base(); + init_id(); + describe("validate", function() { + describe(".validatePrimitive()", function() { + [ + ["test1", true], + [void 0, true], + [null, true], + [() => { + }, false], + [2, true], + [false, true], + [true, true], + [4.5, true], + [{}, false], + [[1, 2, 3], false], + [Symbol("foo"), true] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + if (b === false) { + it(".validatePrimitive(" + typeof a2 + ") should throw TypeException " + b, function() { + expect(() => validatePrimitive(a2)).to.throw(TypeError); + }); + } else { + it(".validatePrimitive(" + typeof a2 + ") should not throw TypeException " + b, function() { + expect(validatePrimitive(a2)).to.be.equal(a2); + }); + } + }); + }); + describe(".validateInteger()", function() { + [ + ["test1", false], + [void 0, false], + [null, false], + [() => { + }, false], + [2, true], + [false, false], + [true, false], + [4.5, false], + [{}, false], + [[1, 2, 3], false], + [Symbol("foo"), false] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + if (b === false) { + it(".validateInteger(" + typeof a2 + ") should throw TypeException " + b, function() { + expect(() => validateInteger(a2)).to.throw(TypeError); + }); + } else { + it(".validateInteger(" + typeof a2 + ") should not throw TypeException " + b, function() { + expect(validateInteger(a2)).to.be.equal(a2); + }); + } + }); + }); + describe(".validateSymbol()", function() { + [ + ["test1", false], + [void 0, false], + [null, false], + [() => { + }, false], + [2, false], + [false, false], + [true, false], + [4.5, false], + [{}, false], + [[1, 2, 3], false], + [Symbol("foo"), true] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + if (b === false) { + it(".validateSymbol(" + typeof a2 + ") should throw TypeException " + b, function() { + expect(() => validateSymbol(a2)).to.throw(TypeError); + }); + } else { + it(".validateSymbol(" + typeof a2 + ") should not throw TypeException " + b, function() { + expect(validateSymbol(a2)).to.be.equal(a2); + }); + } + }); + }); + describe(".validateIterable()", function() { + [ + ["test1", true], + [void 0, false], + [null, false], + [() => { + }, false], + [2, false], + [false, false], + [true, false], + [4.5, false], + [{}, false], + [[1, 2, 3], true], + [Symbol("foo"), false] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + if (b === false) { + it(".validateIterable(" + typeof a2 + ") should throw TypeException " + b, function() { + expect(() => { + validateIterable(a2); + }).to.throw(TypeError); + ; + }); + } else { + it(".validateIterable(" + typeof a2 + ") should not throw TypeException " + b, function() { + expect(validateIterable(a2)).to.be.equal(a2); + }); + } + }); + }); + describe(".validateBoolean()", function() { + [ + ["test1", false], + [void 0, false], + [null, false], + [() => { + }, false], + [2, false], + [false, true], + [true, true], + [4.5, false], + [{}, false], + [[1, 2, 3], false], + [Symbol("foo"), false] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + if (b === false) { + it(".validateBoolean(" + typeof a2 + ") should throw TypeException " + b, function() { + expect(() => { + validateBoolean(a2); + }).to.throw(TypeError); + }); + } else { + it(".validateBoolean(" + typeof a2 + ") should not throw TypeException " + b, function() { + expect(validateBoolean(a2)).to.be.equal(a2); + }); + } + }); + }); + describe(".validateString()", function() { + [ + ["test1", true], + [void 0, false], + [null, false], + [() => { + }, false], + [2, false], + [false, false], + [true, false], + [4.5, false], + [{}, false], + [[1, 2, 3], false], + [Symbol("foo"), false] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + if (b === false) { + it(".validateString(" + typeof a2 + ") should throw TypeException " + b, function() { + expect(() => { + validateString(a2); + }).to.throw(TypeError); + ; + }); + } else { + it(".validateString(" + typeof a2 + ") should not throw TypeException " + b, function() { + expect(validateString(a2)).to.be.equal(a2); + }); + } + }); + }); + describe(".validateObject()", function() { + [ + ["test1", false], + [void 0, false], + [null, false], + [() => { + }, false], + [2, false], + [false, false], + [true, false], + [4.5, false], + [{}, true], + [[1, 2, 3], false], + [Symbol("foo"), false] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + if (b === false) { + it(".validateObject(" + typeof a2 + ") should throw TypeException " + b, function() { + expect(() => { + validateObject(a2); + }).to.throw(TypeError); + ; + }); + } else { + it(".validateObject(" + typeof a2 + ") should not throw TypeException " + b, function() { + expect(validateObject(a2)).to.be.equal(a2); + }); + } + }); + }); + describe(".validateInstance()", function() { + [ + ["test1", Object], + [void 0, Object], + [null, Object], + [() => { + }, Object], + [2, Object], + [false, Object], + [true, Object], + [4.5, Object], + [{}, Base], + [[1, 2, 3], Object], + [Symbol("foo"), Object] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + it(".validateInstance(" + typeof a2 + ") should throw TypeException ", function() { + expect(() => { + validateInstance(a2, b); + }).to.throw(TypeError); + ; + }); + }); + }); + describe(".validateInstance()", function() { + [ + [{}, Object, true], + [new Base(), Base, true] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + it(".validateInstance(" + typeof a2 + ") should not throw TypeException ", function() { + expect(validateInstance(a2, b)).to.be.equal(a2); + }); + }); + }); + describe(".validateArray()", function() { + [ + ["test1", false], + [void 0, false], + [null, false], + [() => { + }, false], + [2, false], + [false, false], + [true, false], + [4.5, false], + [{}, false], + [[1, 2, 3], true], + [Symbol("foo"), false] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + if (b === false) { + it(".validateArray(" + typeof a2 + ") should throw TypeException " + b, function() { + expect(() => { + validateArray(a2); + }).to.throw(TypeError); + ; + }); + } else { + it(".validateArray(" + typeof a2 + ") should not throw TypeException " + b, function() { + expect(validateArray(a2)).to.be.equal(a2); + }); + } + }); + }); + describe(".validateFunction()", function() { + [ + ["test1", false], + [void 0, false], + [null, false], + [() => { + }, true], + [2, false], + [false, false], + [true, false], + [4.5, false], + [{}, false], + [[1, 2, 3], false], + [Symbol("foo"), false] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + if (b === false) { + it(".validateFunction(" + typeof a2 + ") should throw TypeException " + b, function() { + expect(() => { + validateFunction(a2); + }).to.throw(TypeError); + ; + }); + } else { + it(".validateFunction(" + typeof a2 + ") should not throw TypeException " + b, function() { + expect(validateFunction(a2)).to.be.equal(a2); + }); + } + }); + }); + }); + + // test/cases/types/typeof.mjs + init_stack(); + init_typeof(); + describe("typeOf", function() { + describe(".typeOf()", function() { + [ + [true, "boolean"], + [null, "null"], + [void 0, "undefined"], + [Promise.resolve(), "promise"], + [/* @__PURE__ */ new WeakMap(), "weakmap"], + [/* @__PURE__ */ new Map(), "map"], + [NaN, "number"], + [function* () { + }, "generatorfunction"], + [5, "number"], + [function() { + }, "function"], + [/a/, "regexp"], + [/* @__PURE__ */ new Date(), "date"], + [{}, "object"], + [[], "array"], + ["", "string"], + [new Error(), "error"], + [new Stack(), "stack"] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + it("should return " + b + " when the value " + typeOf(a2), function() { + expect(typeOf(a2)).to.be.equal(b); + }); + }); + }); + }); + + // test/cases/types/uniquequeue.mjs + init_uniquequeue(); + describe("UniqueQueue", function() { + let queue; + beforeEach(() => { + queue = new UniqueQueue(); + }); + describe("isEmpty()", function() { + it("first it should empty", function() { + expect(queue.isEmpty()).to.be.true; + }); + }); + describe("add sequence peek and poll", function() { + it("result a,a,a,b", function() { + expect(queue.add({ a: 1 })).to.be.instanceOf(UniqueQueue); + expect(queue.isEmpty()).to.be.false; + expect(queue.add({ a: 2 })).to.be.instanceOf(UniqueQueue); + expect(queue.add({ a: 3 })).to.be.instanceOf(UniqueQueue); + expect(queue.peek()).to.deep.equal({ a: 1 }); + expect(queue.peek()).to.deep.equal({ a: 1 }); + expect(queue.poll()).to.deep.equal({ a: 1 }); + expect(queue.poll()).to.deep.equal({ a: 2 }); + expect(queue.isEmpty()).to.be.false; + expect(queue.peek()).to.deep.equal({ a: 3 }); + expect(queue.poll()).to.deep.equal({ a: 3 }); + expect(queue.isEmpty()).to.be.true; + }); + }); + describe("add and clear", function() { + it("should empty", function() { + expect(queue.isEmpty()).to.be.true; + expect(queue.add({ a: 1 })).to.be.instanceOf(UniqueQueue); + expect(queue.isEmpty()).to.be.false; + expect(queue.clear()).to.be.instanceOf(UniqueQueue); + expect(queue.isEmpty()).to.be.true; + }); + }); + describe("add no object", function() { + it("should throw error", function() { + expect(() => { + queue.add([]); + }).to.throw(TypeError); + expect(() => { + queue.add(1); + }).to.throw(TypeError); + expect(() => { + queue.add(true); + }).to.throw(TypeError); + expect(() => { + queue.add(); + }).to.throw(TypeError); + expect(() => { + queue.add(Symbol("1")); + }).to.throw(TypeError); + expect(() => { + queue.add(function() { + }); + }).to.throw(TypeError); + }); + }); + }); + + // test/cases/types/stack.mjs + init_stack(); + describe("Stack", function() { + let stack; + beforeEach(() => { + stack = new Stack(); + }); + describe("isEmpty()", function() { + it("first it should empty", function() { + expect(stack.isEmpty()).to.be.true; + }); + }); + describe("add sequence peek and pull", function() { + it("result a,a,a,b", function() { + expect(stack.push("a")).to.be.instanceOf(Stack); + expect(stack.isEmpty()).to.be.false; + expect(stack.push("b")).to.be.instanceOf(Stack); + expect(stack.push("c")).to.be.instanceOf(Stack); + expect(stack.peek()).to.be.equal("c"); + expect(stack.peek()).to.be.equal("c"); + expect(stack.pop()).to.be.equal("c"); + expect(stack.peek()).to.be.equal("b"); + expect(stack.isEmpty()).to.be.false; + }); + }); + describe("add and clear", function() { + it("should empty", function() { + expect(stack.isEmpty()).to.be.true; + expect(stack.push("a")).to.be.instanceOf(Stack); + expect(stack.isEmpty()).to.be.false; + expect(stack.clear()).to.be.instanceOf(Stack); + expect(stack.isEmpty()).to.be.true; + }); + }); + }); + + // test/cases/types/basewithoptions.mjs + init_basewithoptions(); + describe("BaseWithOptions", function() { + describe("new BaseWithOptions", function() { + it("is instance of BaseWithOptions", function() { + expect(new BaseWithOptions()).to.be.instanceOf(BaseWithOptions); + }); + it("is instance of Object", function() { + expect(new BaseWithOptions()).to.be.instanceOf(Object); + }); + it("get option is true", function() { + expect(new BaseWithOptions({ a: true }).getOption("a")).to.be.true; + }); + }); + }); + + // source/types/noderecursiveiterator.mjs + init_constants(); + init_base(); + init_is(); + init_validate(); + var isNodeListSymbol = Symbol("isNodeList"); + var NodeRecursiveIterator = class _NodeRecursiveIterator extends Base { + /** + * @param {Node} [data] + */ + constructor(node) { + super(); + this[isNodeListSymbol] = false; + if (isInstance(node, NodeList2)) { + let children = node; + node = new Node2(); + node.childNodes = children; + this[isNodeListSymbol] = true; + } + this[internalSymbol] = validateInstance(node, Node2); + } + /** + * @private + * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield + */ + [Symbol.iterator] = function* () { + if (this[internalSymbol] === void 0) { + return; + } + if (this[isNodeListSymbol] !== true) { + yield this[internalSymbol]; + } + if (this[internalSymbol].hasChildNodes()) { + let childNodes = this[internalSymbol].childNodes; + for (let node of childNodes) { + yield* new _NodeRecursiveIterator(node); + } + } + return; + }; + /** + * @param {function} callback + * @return {Monster.Types.NodeRecursiveIterator} + */ + forEach(callback) { + for (const node of this) { + callback(node); + } + return this; + } + }; + + // test/cases/types/node.mjs + describe("NodeList", function() { + describe("#constructor", function() { + it("should create an empty NodeList", function() { + let nodeList = new NodeList2(); + expect(nodeList.size).to.equal(0); + }); + it("should create a NodeList from an array", function() { + let nodeList = new NodeList2([ + new Node2("div"), + new Node2("div"), + new Node2("div") + ]); + expect(nodeList.size).to.equal(3); + }); + it("should create a NodeList from a NodeList", function() { + let nodeList = new NodeList2([ + new Node2("div"), + new Node2("div"), + new Node2("div") + ]); + let nodeList2 = new NodeList2(nodeList); + expect(nodeList2.size).to.equal(3); + }); + }); + it("create NodeList", function() { + expect(new NodeList2()).is.instanceof(NodeList2); + }); + it("add Node", function() { + expect(new NodeList2().add(new Node2())).to.be.instanceof(NodeList2); + }); + it("remove Node", function() { + expect(new NodeList2().remove(new Node2())).to.be.instanceof(NodeList2); + }); + it("has unknown Node", function() { + expect(new NodeList2().has(new Node2())).to.be.false; + }); + it("has added Node", function() { + const n = new Node2(); + expect(new NodeList2().add(n).has(n)).to.be.true; + }); + it("throw exception", function() { + expect(() => new NodeList2().add(1)).to.throw(Error); + }); + it("check level", function() { + const root = new Node2("root"); + const n1 = new Node2("n1"); + const n2 = new Node2("n2"); + const n3 = new Node2("n3"); + const n4 = new Node2("n4"); + const n11 = new Node2("n11"); + const n12 = new Node2("n12"); + const n13 = new Node2("n13"); + const n21 = new Node2("n21"); + const n22 = new Node2("n22"); + const n23 = new Node2("n23"); + const n41 = new Node2("n41"); + const n42 = new Node2("n42"); + const n411 = new Node2("n411"); + const n412 = new Node2("n412"); + const n413 = new Node2("n413"); + const n4121 = new Node2("n4121"); + root.appendChild(n1).appendChild(n2).appendChild(n3).appendChild(n4); + n1.appendChild(n11).appendChild(n12).appendChild(n13); + n2.appendChild(n21).appendChild(n22).appendChild(n23); + n4.appendChild(n41).appendChild(n42); + n41.appendChild(n411).appendChild(n412).appendChild(n413); + n412.appendChild(n4121); + let iterator = new NodeRecursiveIterator(root); + let result = []; + for (const n of iterator) { + expect(n).to.be.an.instanceof(Node2); + result.push(n.value + ":" + n.level); + } + expect(result).to.deep.equal([ + "root:0", + "n1:1", + "n11:2", + "n12:2", + "n13:2", + "n2:1", + "n21:2", + "n22:2", + "n23:2", + "n3:1", + "n4:1", + "n41:2", + "n411:3", + "n412:3", + "n4121:4", + "n413:3", + "n42:2" + ]); + n4121.appendChild(new Node2("n41211")); + iterator = new NodeRecursiveIterator(root); + result = []; + for (const n of iterator) { + expect(n).to.be.an.instanceof(Node2); + result.push(n.value + ":" + n.level); + } + expect(result).to.deep.equal([ + "root:0", + "n1:1", + "n11:2", + "n12:2", + "n13:2", + "n2:1", + "n21:2", + "n22:2", + "n23:2", + "n3:1", + "n4:1", + "n41:2", + "n411:3", + "n412:3", + "n4121:4", + "n41211:5", + "n413:3", + "n42:2" + ]); + const bb = new Node2("bb"); + bb.appendChild(root); + iterator = new NodeRecursiveIterator(bb); + result = []; + for (const n of iterator) { + expect(n).to.be.an.instanceof(Node2); + result.push(n.value + ":" + n.level); + } + expect(result).to.deep.equal([ + "bb:0", + "root:1", + "n1:2", + "n11:3", + "n12:3", + "n13:3", + "n2:2", + "n21:3", + "n22:3", + "n23:3", + "n3:2", + "n4:2", + "n41:3", + "n411:4", + "n412:4", + "n4121:5", + "n41211:6", + "n413:4", + "n42:3" + ]); + }); + describe("Levels", function() { + it("n2 should level 2", function() { + const n0 = new Node2("abc"); + const n1 = new Node2("def"); + n0.appendChild(n1); + const n2 = new Node2("ghi"); + n1.appendChild(n2); + const n3 = new Node2("jkl"); + n2.appendChild(n3); + expect(n0.level).to.be.equal(0); + expect(n1.level).to.be.equal(1); + expect(n2.level).to.be.equal(2); + expect(n3.level).to.be.equal(3); + }); + }); + describe("toString()", function() { + it("should output empty string", function() { + const node = new Node2(); + expect(node.toString()).is.equal(""); + }); + it("should output string", function() { + const n0 = new Node2("abc"); + const n1 = new Node2("def"); + n0.appendChild(n1); + const n11 = new Node2("ghi"); + n0.appendChild(n11); + const n2 = new Node2("jkl"); + n1.appendChild(n2); + const n3 = new Node2("mno"); + n1.appendChild(n3); + const n4 = new Node2("pqr"); + n2.appendChild(n4); + expect(n2.level).to.be.equal(2); + console.log(n0.toString()); + }); + }); + }); + + // test/cases/types/queue.mjs + init_queue(); + describe("Queue", function() { + let queue; + beforeEach(() => { + queue = new Queue(); + }); + describe("isEmpty()", function() { + it("first it should empty", function() { + expect(queue.isEmpty()).to.be.true; + }); + }); + describe("add sequence peek and poll", function() { + it("result a,a,a,b", function() { + expect(queue.add("a")).to.be.instanceOf(Queue); + expect(queue.isEmpty()).to.be.false; + expect(queue.add("b")).to.be.instanceOf(Queue); + expect(queue.add("c")).to.be.instanceOf(Queue); + expect(queue.peek()).to.be.equal("a"); + expect(queue.peek()).to.be.equal("a"); + expect(queue.poll()).to.be.equal("a"); + expect(queue.peek()).to.be.equal("b"); + expect(queue.isEmpty()).to.be.false; + }); + }); + describe("add and clear", function() { + it("should empty", function() { + expect(queue.isEmpty()).to.be.true; + expect(queue.add("a")).to.be.instanceOf(Queue); + expect(queue.isEmpty()).to.be.false; + expect(queue.clear()).to.be.instanceOf(Queue); + expect(queue.isEmpty()).to.be.true; + }); + }); + }); + + // test/cases/types/noderecursiveiterator.mjs + describe("NodeRecursiveIterator", function() { + it("should throw exeption", function() { + expect(() => new NodeRecursiveIterator()).to.throw(Error); + }); + it("should be a function", function() { + expect(NodeRecursiveIterator).to.be.a("function"); + }); + it("should be a constructor", function() { + expect(new NodeRecursiveIterator(new Node2())).to.be.an.instanceof(NodeRecursiveIterator); + }); + it("undefined should not result in undefined node", function() { + const iterator = new NodeRecursiveIterator(new Node2()); + const result = []; + for (const n of iterator) { + expect(n).to.be.an.instanceof(Node2); + result.push(n.value); + } + expect(result).to.deep.equal([void 0]); + }); + it("should iterate", function() { + const node = new Node2("1"); + node.appendChild( + new Node2("2").appendChild(new Node2("2.1")).appendChild(new Node2("2.2")).appendChild(new Node2("2.3")) + ).appendChild(new Node2("3")).appendChild(new Node2("4").appendChild(new Node2("4.1")).appendChild(new Node2("4.2"))); + const iterator = new NodeRecursiveIterator(node); + const result = []; + for (const n of iterator) { + expect(n).to.be.an.instanceof(Node2); + result.push(n.value); + } + expect(result).to.deep.equal(["1", "2", "2.1", "2.2", "2.3", "3", "4", "4.1", "4.2"]); + }); + it("should iterate nodelist", function() { + const nodeList = new NodeList2(); + nodeList.add( + new Node2("2").appendChild(new Node2("2.1")).appendChild(new Node2("2.2")).appendChild(new Node2("2.3")).appendChild(new Node2("3")).appendChild(new Node2("4").appendChild(new Node2("4.1")).appendChild(new Node2("4.2"))) + ); + nodeList.add(new Node2("x")); + const iterator = new NodeRecursiveIterator(nodeList); + const result = []; + for (const n of iterator) { + expect(n).to.be.an.instanceof(Node2); + result.push(n.value); + } + expect(result).to.deep.equal(["2", "2.1", "2.2", "2.3", "3", "4", "4.1", "4.2", "x"]); + }); + }); + + // source/i18n/formatter.mjs + init_constants(); + init_extend(); + init_formatter(); + init_validate(); + init_translations(); + var internalTranslationSymbol = Symbol("internalTranslation"); + var Formatter2 = class extends Formatter { + /** + * Default values for the markers are `${` and `}` + * + * @param {object} object + * @throws {TypeError} value is not a object + */ + constructor(object, translation, options) { + super(object, options); + this[internalTranslationSymbol] = validateInstance(translation, Translations); + } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 3.27.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/i18n/formatter@@instance"); + } + /** + * @property {object} marker + * @property {array} marker.open=["i18n{","${"] + * @property {array} marker.close=["${"] + * @property {object} parameter + * @property {string} parameter.delimiter="::" + * @property {string} parameter.assignment="=" + * @property {object} callbacks + * @property {function} callbacks.i18n=()=>{} + */ + get defaults() { + const self2 = this; + return extend({}, super.defaults, { + callbacks: { + i18n: (value) => { + return self2[internalTranslationSymbol].getText(validateString(value)); + } + }, + marker: { + open: ["i18n{", "${"], + close: ["}"] + } + }); + } + /** + * + * @param {string} text + * @return {string} + * @throws {TypeError} value is not a string + * @throws {Error} too deep nesting + * @throws {Error} key not found + * @throws {Error} the closing marker is missing + */ + format(text) { + validateString(text); + const openMarker = this[internalSymbol]["marker"]["open"]?.[0]; + const closeMarker = this[internalSymbol]["marker"]["close"]?.[0]; + if (text.indexOf(openMarker) === 0) { + text = text.substring(openMarker.length); + if (text.indexOf(closeMarker) === text.length - closeMarker.length) { + text = text.substring(0, text.length - closeMarker.length); + } else { + throw new Error("the closing marker is missing"); + } + } + const parts = validateString(text).split("::"); + const translationKey = parts.shift().trim(); + const parameter = parts.join("::").trim(); + let assembledText = `${openMarker}static:${translationKey} | call:i18n`; + if (parameter.length > 0) { + assembledText += `::${parameter}`; + } + assembledText += closeMarker; + return super.format(assembledText); + } + }; + + // test/cases/i18n/formatter.mjs + init_translations(); + describe("Formatter", function() { + describe("example", function() { + it("should run with marker", function() { + const translations = new Translations("en").assignTranslations({ + thekey: "${animal} has eaten the ${food}!" + }); + const f = new Formatter2({}, translations); + expect(f.format("i18n{thekey::animal=dog::food=cake}")).to.be.equal("dog has eaten the cake!"); + }); + it("should run without marker", function() { + const translations = new Translations("en").assignTranslations({ + thekey: "${animal} has eaten the ${food}!" + }); + expect(new Formatter2({}, translations).format("thekey::animal=dog::food=cake")).to.be.equal("dog has eaten the cake!"); + }); + }); + describe("format", function() { + [ + ["i18n{translationkey::a=3::b=5}", "test is 3 and 5"] + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + it("format " + a2 + " should " + b, function() { + const translations = new Translations("de").assignTranslations({ + translationkey: "test is ${a} and ${b}" + }); + expect( + new Formatter2({}, translations).format(a2) + ).to.equal(b); + }); + }); + }); + }); + + // test/cases/i18n/locale.mjs + init_locale(); + describe("Locale", function() { + describe("new instance", function() { + [ + // language, region, script, variants, extlang, privateUse + // https://www.rfc-editor.org/rfc/rfc5646.html + ["zh", void 0, "Hant", void 0, void 0, void 0, "zh-Hant"], + // zh-Hant (Chinese written using the Traditional Chinese script) + ["de", "CH", void 0, "1901", void 0, void 0, "de-CH-1901"], + // de-CH-1901 (German as used in Switzerland using the 1901 variant [orthography]) + ["sl", "IT", void 0, "nedis", void 0, void 0, "sl-IT-nedis"], + // sl-IT-nedis (Slovenian as used in Italy, Nadiza dialect) + ["hy", "IT", "Latn", "arevela", void 0, void 0, "hy-Latn-IT-arevela"], + // hy-Latn-IT-arevela (Eastern Armenian written in Latin script, as used in Italy) + ["zh", "CN", "Hans", void 0, void 0, void 0, "zh-Hans-CN"], + // zh-Hans-CN (Chinese written using the Simplified script as used in mainland China) + ["sr", "RS", "Latn", void 0, void 0, void 0, "sr-Latn-RS"] + // sr-Latn-RS (Serbian written using the Latin script as used in Serbia) + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + let c = data.shift(); + let d2 = data.shift(); + let e = data.shift(); + let f = data.shift(); + let g = data.shift(); + it("new Locale(" + a2 + "," + b + "," + c + "," + d2 + "," + e + "," + f + ") should return " + g, function() { + expect(new Locale(a2, b, c, d2, e, f).toString()).is.equal(g); + }); + }); + }); + describe("parseLocale()", function() { + [ + // language, region, script, variants, extlang, privateUse + // https://www.rfc-editor.org/rfc/rfc5646.html + ["zh", void 0, "Hant", void 0, void 0, void 0, "zh-Hant"], + // zh-Hant (Chinese written using the Traditional Chinese script) + ["de", "CH", void 0, "1901", void 0, void 0, "de-CH-1901"], + // de-CH-1901 (German as used in Switzerland using the 1901 variant [orthography]) + ["sl", "IT", void 0, "nedis", void 0, void 0, "sl-IT-nedis"], + // sl-IT-nedis (Slovenian as used in Italy, Nadiza dialect) + ["hy", "IT", "Latn", "arevela", void 0, void 0, "hy-Latn-IT-arevela"], + // hy-Latn-IT-arevela (Eastern Armenian written in Latin script, as used in Italy) + ["zh", "CN", "Hans", void 0, void 0, void 0, "zh-Hans-CN"], + // zh-Hans-CN (Chinese written using the Simplified script as used in mainland China) + ["sr", "RS", "Latn", void 0, void 0, void 0, "sr-Latn-RS"] + // sr-Latn-RS (Serbian written using the Latin script as used in Serbia) + ].forEach(function(data) { + let a2 = data.shift(); + let b = data.shift(); + let c = data.shift(); + let d2 = data.shift(); + let e = data.shift(); + let f = data.shift(); + let g = data.shift(); + it("new Locale(" + a2 + "," + b + "," + c + "," + d2 + "," + e + "," + f + ") should return " + g, function() { + const locale = parseLocale(g); + expect(locale.localeString).to.be.equal(g); + expect(locale.language).to.be.equal(a2); + expect(locale.region).to.be.equal(b); + expect(locale.script).to.be.equal(c); + expect(locale.variants).to.be.equal(d2); + expect(locale.extlang).to.be.equal(e); + expect(locale.privateUse).to.be.equal(f); + expect(new Locale(a2, b, c, d2, e, f).toString()).is.equal(g); + }); + }); + }); + }); + + // test/cases/i18n/provider.mjs + init_constants2(); + init_attributes(); + init_provider(); + init_translations(); + describe("Provider", function() { + let html16 = ` + <div id="test1"> + </div> +`; + beforeEach(() => { + let mocks = document.getElementById("mocks"); + mocks.innerHTML = html16; + }); + afterEach(() => { + let mocks = document.getElementById("mocks"); + mocks.innerHTML = ""; + }); + before(function(done) { + initJSDOM().then(() => { + done(); + }); + }); + describe("Provider and Dom", function() { + const translationsLinkSymbol2 = Symbol.for("@schukai/monster/i18n/translations@@link"); + it("assignToElement", function(done) { + const element = document.getElementById("test1"); + const p = new Provider(); + const r = p.assignToElement(void 0, element); + r.then((e) => { + const s = element.getAttribute(ATTRIBUTE_OBJECTLINK); + if (s === null) { + done(new Error("Attribute not set")); + return; + } + const i = getLinkedObjects(element, translationsLinkSymbol2); + if (i === null) { + done(new Error("No linked object found")); + return; + } + let counter = 0; + for (let v of i) { + counter++; + } + if (counter !== 1) { + done(new Error("No linked object found")); + return; + } + const docTrans = getDocumentTranslations(element); + expect(docTrans).is.instanceof(Translations); + done(); + }).catch((e) => done(e)); + }); + }); + }); + + // source/i18n/providers/fetch.mjs + init_constants(); + init_extend(); + init_formatter(); + init_global(); + init_is(); + init_validate(); + init_locale(); + init_provider(); + init_translations(); + var Fetch = class extends Provider { + /** + * As options the key `fetch` can be passed. This config object is passed to the fetch method as init. + * + * The url may contain placeholders (language, script, region, variants, extlang, privateUse), so you can specify one url for all translations. + * + * ``` + * new Fetch('https://www.example.com/assets/${language}.json') + * ``` + * + * @param {string|URL} url + * @param {Object} options see {@link Monster.I18n.Providers.Fetch#defaults} + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/fetch} + */ + constructor(url, options) { + super(options); + if (isInstance(url, URL)) { + url = url.toString(); + } + if (options === void 0) { + options = {}; + } + validateString(url); + this.url = url; + this[internalSymbol] = extend({}, super.defaults, this.defaults, validateObject(options)); + } + /** + * Defaults + * + * @property {Object} fetch + * @property {String} fetch.method=GET + * @property {String} fetch.mode=cors + * @property {String} fetch.cache=no-cache + * @property {String} fetch.credentials=omit + * @property {String} fetch.redirect=follow + * @property {String} fetch.referrerPolicy=no-referrer + * + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API} + */ + get defaults() { + return extend( + { + fetch: { + method: "GET", + // *GET, POST, PUT, DELETE, etc. + mode: "cors", + // no-cors, *cors, same-origin + cache: "no-cache", + // *default, no-cache, reload, force-cache, only-if-cached + credentials: "omit", + // include, *same-origin, omit + redirect: "follow", + // manual, *follow, error + referrerPolicy: "no-referrer" + // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url + } + }, + super.defaults + ); + } + /** + * + * @param {Locale|string} locale + * @return {Promise} + */ + getTranslations(locale) { + if (isString(locale)) { + locale = parseLocale(locale); + } + let formatter = new Formatter(locale.getMap()); + return getGlobalFunction("fetch")(formatter.format(this.url), this.getOption("fetch", {})).then((response) => response.json()).then((data) => { + return new Translations(locale).assignTranslations(data); + }); + } + }; + + // test/cases/i18n/providers/fetch.mjs + init_translations(); + init_global(); + var global3 = getGlobal(); + var fetchReference; + describe("Translation Provider Fetch", function() { + afterEach(() => { + global3["fetch"] = fetchReference; + }); + beforeEach(() => { + fetchReference = global3["fetch"]; + global3["fetch"] = function(url, options) { + return new Promise((resolve, reject) => { + resolve({ + json: function() { + return { + a: "test" + }; + } + }); + }); + }; + }); + describe("fetch mock data and create translation", function() { + it("fetch", function(done) { + let p = new Fetch(new URL("http://example.com")).getTranslations("en"); + expect(p).is.instanceof(Promise); + p.then((r) => { + try { + expect(r).is.instanceof(Translations); + done(); + } catch (e) { + done(e); + } + }).catch((e) => { + done(e); + }); + }); + }); + }); + + // test/cases/i18n/providers/embed.mjs + init_translations(); + init_global(); + var global4 = getGlobal(); + var html15 = ` +<script id="templocale" type="application/json"> +{ + "key": "translation" +} +<\/script> +`; + describe("Translation Provider Embed", function() { + before(function(done) { + initJSDOM().then(() => { + done(); + }); + }); + afterEach(() => { + let mocks = document.getElementById("mocks"); + mocks.innerHTML = ""; + }); + beforeEach(() => { + let mocks = document.getElementById("mocks"); + mocks.innerHTML = html15; + }); + describe("get mock data and create translation", function() { + it("embed", function(done) { + const e = new Embed("templocale"); + let p = e.getTranslations("en"); + expect(p).is.instanceof(Promise); + p.then((r) => { + try { + expect(r).is.instanceof(Translations); + let t = r.getText("key"); + expect(t).is.equal("translation"); + done(); + } catch (e2) { + done(e2); + } + }).catch((e2) => { + done(e2); + }); + }); + }); + }); + + // test/cases/i18n/translations.mjs + init_locale(); + init_translations(); + describe("Translations", function() { + describe("Instance and Init", function() { + let translation; + beforeEach(() => { + translation = new Translations(parseLocale("en-GB")); + translation.assignTranslations({ + test1: "abc", + test2: { "other": "xyz" } + }); + }); + it("create instance", function() { + expect(new Translations(parseLocale("en-GB"))).is.instanceof(Translations); + }); + it("init translations", function() { + expect(translation.assignTranslations({ + test1: "abc", + test2: { "other": "xyz" } + })).is.instanceof(Translations); + }); + }); + describe("getText", function() { + let translation; + beforeEach(() => { + translation = new Translations(parseLocale("en-GB")); + translation.assignTranslations({ + test1: "abc", + test2: { "other": "xyz" } + }); + }); + it("create, set and get en-GB", function() { + expect(translation.getText("test1")).is.equal("abc"); + }); + it("create, set and get en-GB with pluralrules", function() { + expect(translation.getText("test2")).is.equal("xyz"); + }); + }); + describe("test initDocumentTranslation ", function() { + let html16 = `<div id="mock-translations"></div> + +<script type="application/json" data-monster-role="translations"> + { + "test1": "abc", + "test2": { + "other": "xyz" + } + } +<\/script> + +<script type="application/json" data-monster-role="translations"> + { + "test1": "xyz", + "test3": { + "other": "xyz" + } + } +<\/script> + +`; + beforeEach(() => { + let mocks = document.getElementById("mocks"); + mocks.innerHTML = html16; + }); + afterEach(() => { + let mocks = document.getElementById("mocks"); + mocks.innerHTML = ""; + }); + before(function(done) { + initJSDOM().then(() => { + done(); + }); + }); + it("Init translations", function(done) { + let elem = document.getElementById("mock-translations"); + Embed.assignTranslationsToElement(elem).then((o) => { + let mocks = document.getElementById("mocks"); + expect(getDocumentTranslations(elem).getText("no-key", "with-default")).is.equal("with-default"); + expect(getDocumentTranslations(elem).getText("test1")).is.equal("xyz"); + done(); + }).catch((e) => { + done(e); + }); + }); + }); + }); +})(); +/** + * @private + * @type {symbol} + * @memberOf Monster + * @license AGPLv3 + * @since 1.24.0 + */ +/** + * @private + * @type {symbol} + * @memberOf Monster + * @license AGPLv3 + * @since 1.25.0 + */ +/** + * With this function you can check if a value is iterable. + * + * This method is used in the library to have consistent names. + * + * You can call the method via the monster namespace `Monster.Types.isPrimitive()`. + * + * @externalExample ../../example/types/is-1.mjs + * @param {*} value + * @returns {boolean} + * @license AGPLv3 + * @since 1.2.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + */ +/** + * Checks whether the value passed is a primitive (string, number, boolean, NaN, undefined, null or symbol) + * + * This method is used in the library to have consistent names. + * + * @externalExample ../../example/types/is-2.mjs + * @param {*} value + * @returns {boolean} + * @license AGPLv3 + * @since 1.0.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + */ +/** + * Checks whether the value passed is a symbol + * + * This method is used in the library to have consistent names. + * + * @externalExample ../../example/types/is-3.mjs + * @param {*} value + * @returns {boolean} + * @license AGPLv3 + * @since 1.9.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + */ +/** + * Checks whether the value passed is a boolean. + * + * This method is used in the library to have consistent names. + * + * @externalExample ../../example/types/is-4.mjs + * @param {*} value + * @returns {boolean} + * @license AGPLv3 + * @since 1.0.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + */ +/** + * Checks whether the value passed is a string + * + * This method is used in the library to have consistent names. + * + * @externalExample ../../example/types/is-5.mjs + * @param {*} value + * @returns {boolean} + * @license AGPLv3 + * @since 1.0.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + */ +/** + * Checks whether the value passed is a object + * + * This method is used in the library to have consistent names. + * + * @externalExample ../../example/types/is-6.mjs + * @param {*} value + * @returns {boolean} + * @license AGPLv3 + * @since 1.0.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + */ +/** + * Checks whether the value passed is a object and instance of instance. + * + * This method is used in the library to have consistent names. + * + * @externalExample ../../example/types/is-7.mjs + * @param {*} value + * @param {*} instance + * @returns {boolean} + * @license AGPLv3 + * @since 1.5.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + */ +/** + * Checks whether the value passed is a array + * + * This method is used in the library to have consistent names. + * + * @externalExample ../../example/types/is-8.mjs + * @param {*} value + * @returns {boolean} + * @license AGPLv3 + * @since 1.0.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + * @see https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray + */ +/** + * Checks whether the value passed is a function + * + * This method is used in the library to have consistent names. + * + * @externalExample ../../example/types/is-9.mjs + * @param {*} value + * @returns {boolean} + * @license AGPLv3 + * @since 1.0.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + */ +/** + * Checks whether the value passed is an integer. + * + * This method is used in the library to have consistent names. + * + * @externalExample ../../example/types/is-10.mjs + * @param {*} value + * @returns {boolean} + * @license AGPLv3 + * @since 1.4.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + */ +/** + * The built-in typeof method is known to have some historical weaknesses. This function tries to provide a better and more accurate result. + * + * @externalExample ../../example/types/typeof.mjs + * @param {*} value + * @return {string} + * @license AGPLv3 + * @since 1.7.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + * @throws {TypeError} value is not a primitive + */ +/** + * Extend copies all enumerable own properties from one or + * more source objects to a target object. It returns the modified target object. + * + * @param {object} target + * @param {object} + * @return {object} + * @license AGPLv3 + * @since 1.10.0 + * @copyright schukai GmbH + * @memberOf Monster.Data + * @throws {Error} unsupported argument + * @throws {Error} type mismatch + * @throws {Error} unsupported argument + */ +/** + * This is the base class from which the most classes are derived. + * + * This class has besides a `toString` which returns the json representation of the object + * also a functionality to check if an object is an instance of a class. + * + * Therefor the class has a static method ` [Symbol.hasInstance](that)` which returns true if the object + * is an instance of the class. + * + * @see [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/hasInstance](developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/hasInstance) + * + * Derived classes should implement a static getter `instanceSymbol` which returns a unique symbol. + * + * ```javascript + * static get [instanceSymbol]() { + * return Symbol.for("@schukai/monster/types/base"); + * } + * ``` + * + * The class was formerly called Object. + * + * @license AGPLv3 + * @since 1.5.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + */ +/** + * This method checks if the type matches the primitive type. this function is identical to isPrimitive() except that a TypeError is thrown. + * + * ``` + * <script type="module"> + * import {validateIterable} from '@schukai/monster/source/types/validate.mjs'; + * console.log(validateIterable('2')) // ↦ TypeError + * console.log(validateIterable([])) // ↦ value + * <\/script> + * ``` + * + * @param {*} value + * @return {*} + * @license AGPLv3 + * @since 1.2.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + * @throws {TypeError} value is not a primitive + * @see {@link isPrimitive} + * @see {@link Monster.Types.isPrimitive} + * @see {@link Monster.Types#isPrimitive} + */ +/** + * This method checks if the type matches the primitive type. this function is identical to isPrimitive() except that a TypeError is thrown. + * + * ``` + * <script type="module"> + * import {validatePrimitive} from '@schukai/monster/source/types/validate.mjs'; + * console.log(validatePrimitive('2')) // ↦ value + * console.log(validatePrimitive([])) // ↦ TypeError + * <\/script> + * ``` + * + * @param {*} value + * @return {*} + * @license AGPLv3 + * @since 1.0.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + * @throws {TypeError} value is not a primitive + * @see {@link isPrimitive} + * @see {@link Monster.Types.isPrimitive} + * @see {@link Monster.Types#isPrimitive} + */ +/** + * This method checks if the type matches the boolean type. this function is identical to isBoolean() except that a TypeError is thrown. + * + * ``` + * <script type="module"> + * import {validateBoolean} from '@schukai/monster/source/types/validate.mjs'; + * console.log(validateBoolean(false)) // ↦ value + * console.log(validateBoolean('2')) // ↦ TypeError + * console.log(validateBoolean([])) // ↦ TypeError + * <\/script> + * ``` + * + * @param {*} value + * @return {*} + * @license AGPLv3 + * @since 1.0.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + + * @throws {TypeError} value is not primitive + */ +/** + * This method checks if the type matches the string type. this function is identical to isString() except that a TypeError is thrown. + * + * ``` + * <script type="module"> + * import {validateString} from '@schukai/monster/source/types/validate.mjs'; + * console.log(validateString('2')) // ↦ value + * console.log(validateString([])) // ↦ TypeError + * <\/script> + * ``` + * + * @param {*} value + * @return {*} + * @license AGPLv3 + * @since 1.0.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + * @throws {TypeError} value is not a string + */ +/** + * This method checks if the type matches the object type. this function is identical to isObject() except that a TypeError is thrown. + * + * ``` + * <script type="module"> + * import {validateObject} from '@schukai/monster/source/types/validate.mjs'; + * console.log(validateObject({})) // ↦ value + * console.log(validateObject('2')) // ↦ TypeError + * console.log(validateObject([])) // ↦ TypeError + * <\/script> + * ``` + * + * @param {*} value + * @return {*} + * @license AGPLv3 + * @since 1.0.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + * @throws {TypeError} value is not a object + */ +/** + * This method checks if the type matches the object instance. + * + * ``` + * <script type="module"> + * import {validateInstance} from '@schukai/monster/source/types/validate.mjs'; + * console.log(validateInstance({}, Object)) // ↦ value + * console.log(validateInstance('2', Object)) // ↦ TypeError + * console.log(validateInstance([], Object)) // ↦ TypeError + * <\/script> + * ``` + * + * @param {*} value + * @return {*} + * @license AGPLv3 + * @since 1.5.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + * @throws {TypeError} value is not an instance of + */ +/** + * This method checks if the type matches the array type. this function is identical to isArray() except that a TypeError is thrown. + * + * ``` + * <script type="module"> + * import {validateArray} from '@schukai/monster/source/types/validate.mjs'; + * console.log(validateArray('2')) // ↦ TypeError + * console.log(validateArray([])) // ↦ value + * <\/script> + * ``` + * + * @param {*} value + * @return {*} + * @license AGPLv3 + * @since 1.0.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + * @throws {TypeError} value is not an array + */ +/** + * This method checks if the type matches the symbol type. this function is identical to isSymbol() except that a TypeError is thrown. + * + * ``` + * <script type="module"> + * import {validateSymbol} from '@schukai/monster/source/types/validate.mjs'; + * console.log(validateSymbol('2')) // ↦ TypeError + * console.log(validateSymbol()) // ↦ value + * <\/script> + * ``` + * + * @param {*} value + * @return {*} + * @license AGPLv3 + * @since 1.9.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + * @throws {TypeError} value is not an symbol + */ +/** + * This method checks if the type matches the function type. this function is identical to isFunction() except that a TypeError is thrown. + * + * ``` + * <script type="module"> + * import {validateFunction} from '@schukai/monster/source/types/validate.mjs'; + * console.log(validateFunction(()=>{})) // ↦ value + * console.log(validateFunction('2')) // ↦ TypeError + * console.log(validateFunction([])) // ↦ TypeError + * <\/script> + * ``` + * + * @param {*} value + * @return {*} + * @license AGPLv3 + * @since 1.0.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + * @throws {TypeError} value is not a function + */ +/** + * This method checks if the type is an integer. this function is identical to isInteger() except that a TypeError is thrown. + * + * ``` + * <script type="module"> + * import {validateFunction} from '@schukai/monster/source/types/validate.mjs'; + * console.log(validateInteger(true)) // ↦ TypeError + * console.log(validateInteger('2')) // ↦ TypeError + * console.log(validateInteger(2)) // ↦ value + * <\/script> + * ``` + * + * @param {*} value + * @return {*} + * @license AGPLv3 + * @since 1.4.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + * @throws {TypeError} value is not an integer + */ +/** + * Return globalThis + * + * If globalThis is not available, it will be polyfilled + * + * @license AGPLv3 + * @since 1.6.0 + * @memberOf Monster.Types + * @returns {objec} globalThis + */ +/** + * Return global object or throw Error + * + * You can call the method via the monster namespace `Monster.Types.getGlobalObject()`. + * + * ``` + * <script type="module"> + * import {Monster} from '@schukai/monster/source/monster.mjs'; + * Monster.Types.getGlobalObject('document') + * // ↦ { } + * <\/script> + * ``` + * + * Alternatively, you can also integrate this function individually. + * + * ``` + * <script type="module"> + * import {getGlobalObject} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.30.0/dist/modules/types/global.mjs'; + * getGlobalObject('document') + * // ↦ { } + * <\/script> + * ``` + * + * @license AGPLv3 + * @since 1.6.0 + * @memberOf Monster.Types + * @param {string} name + * @returns {objec} + * @throws {Error} the object is not defined + * @throws {TypeError} value is not a object + * @throws {TypeError} value is not a string + */ +/** + * Return global function or throw Error + * + * You can call the method via the monster namespace `Monster.Types.getGlobalFunction()`. + * + * ``` + * <script type="module"> + * import {Monster} from '@schukai/monster/source/monster.mjs'; + * console.log(Monster.Types.getGlobalFunction('parseInt')) // ↦ f parseInt() { } + * <\/script> + * ``` + * + * Alternatively, you can also integrate this function individually. + * + * ``` + * <script type="module"> + * import {getGlobalFunction} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.30.0/dist/modules/types/global.mjs'; + * console.log(getGlobalFunction('parseInt')) // ↦ f parseInt() { } + * <\/script> + * ``` + * + * @license AGPLv3 + * @since 1.6.0 + * @memberOf Monster.Types + * @param {string} name + * @return {objec} + * @throws {TypeError} value is not a function + * @throws {Error} the function is not defined + * @throws {TypeError} value is not a string + */ +/** + * With this function, objects can be cloned. + * The entire object tree is run through. + * + * Proxy, Element, HTMLDocument and DocumentFragment instances are not cloned. + * Global objects such as windows are also not cloned, + * + * If an object has a method `getClone()`, this method is used to create the clone. + * + * @param {*} obj object to be cloned + * @returns {*} + * @license AGPLv3 + * @since 1.0.0 + * @memberOf Monster.Util + * @copyright schukai GmbH + * @throws {Error} unable to clone obj! its type isn't supported. + */ +/** + * The Locale class is a base class for the language classes. + * + * RFC + * + * ``` + * A Language-Tag consists of: + * langtag ; generated tag + * -or- private-use ; a private use tag + * + * langtag = (language + * ["-" script] + * ["-" region] + * *("-" variant) + * *("-" extension) + * ["-" privateuse]) + * + * language = "en", "ale", or a registered value + * + * script = "Latn", "Cyrl", "Hant" ISO 15924 codes + * + * region = "US", "CS", "FR" ISO 3166 codes + * "419", "019", or UN M.49 codes + * + * variant = "rozaj", "nedis", "1996", multiple subtags can be used in a tag + * + * extension = single letter followed by additional subtags; more than one extension + * may be used in a language tag + * + * private-use = "x-" followed by additional subtags, as many as are required + * Note that these can start a tag or appear at the end (but not + * in the middle) + * ``` + * + * @license AGPLv3 + * @since 1.13.0 + * @copyright schukai GmbH + * @memberOf Monster.I18n + * @see https://datatracker.ietf.org/doc/html/rfc3066 + */ +/** + * Parse local according to rfc4646 standard + * + * Limitations: The regex cannot handle multiple variants or private. + * + * You can call the method via this function individually: + * + * ```javascript + * import {createLocale} from '@schukai/monster/source/i18n/locale.mjs'; + * createLocale() + * ``` + * + * RFC + * + * ``` + * The syntax of the language tag in ABNF [RFC4234] is: + * + * Language-Tag = langtag + * / privateuse ; private use tag + * / grandfathered ; grandfathered registrations + * + * langtag = (language + * ["-" script] + * ["-" region] + * *("-" variant) + * *("-" extension) + * ["-" privateuse]) + * + * language = (2*3ALPHA [ extlang ]) ; shortest ISO 639 code + * / 4ALPHA ; reserved for future use + * / 5*8ALPHA ; registered language subtag + * + * extlang = *3("-" 3ALPHA) ; reserved for future use + * + * script = 4ALPHA ; ISO 15924 code + * + * region = 2ALPHA ; ISO 3166 code + * / 3DIGIT ; UN M.49 code + * + * variant = 5*8alphanum ; registered variants + * / (DIGIT 3alphanum) + * + * extension = singleton 1*("-" (2*8alphanum)) + * + * singleton = %x41-57 / %x59-5A / %x61-77 / %x79-7A / DIGIT + * ; "a"-"w" / "y"-"z" / "A"-"W" / "Y"-"Z" / "0"-"9" + * ; Single letters: x/X is reserved for private use + * + * privateuse = ("x"/"X") 1*("-" (1*8alphanum)) + * + * grandfathered = 1*3ALPHA 1*2("-" (2*8alphanum)) + * ; grandfathered registration + * ; Note: i is the only singleton + * ; that starts a grandfathered tag + * + * alphanum = (ALPHA / DIGIT) ; letters and numbers + * + * Figure 1: Language Tag ABNF + * ``` + * + * @param {string} locale + * @returns {Locale} + * @license AGPLv3 + * @since 1.14.0 + * @copyright schukai GmbH + * @memberOf Monster.I18n + * @throws {TypeError} value is not a string + * @throws {Error} unsupported locale + */ +/** + * This method fetches the document object + * + * In nodejs this functionality can be performed with [jsdom](https://www.npmjs.com/package/jsdom). + * + * ``` + * import {JSDOM} from "jsdom" + * if (typeof window !== "object") { + * const {window} = new JSDOM('', { + * url: 'http://example.com/', + * pretendToBeVisual: true + * }); + * + * [ + * 'self', + * 'document', + * 'Document', + * 'Node', + * 'Element', + * 'HTMLElement', + * 'DocumentFragment', + * 'DOMParser', + * 'XMLSerializer', + * 'NodeFilter', + * 'InputEvent', + * 'CustomEvent' + * ].forEach(key => (getGlobal()[key] = window[key])); + * } + * ``` + * + * @returns {object} + * @license AGPLv3 + * @since 1.6.0 + * @copyright schukai GmbH + * @memberOf Monster.DOM + * @throws {Error} not supported environment + */ +/** + * This method fetches the window object + * + * In nodejs this functionality can be performed with [jsdom](https://www.npmjs.com/package/jsdom). + * + * ``` + * import {JSDOM} from "jsdom" + * if (typeof window !== "object") { + * const {window} = new JSDOM('', { + * url: 'http://example.com/', + * pretendToBeVisual: true + * }); + * + * getGlobal()['window']=window; + * + * [ + * 'self', + * 'document', + * 'Document', + * 'Node', + * 'Element', + * 'HTMLElement', + * 'DocumentFragment', + * 'DOMParser', + * 'XMLSerializer', + * 'NodeFilter', + * 'InputEvent', + * 'CustomEvent' + * ].forEach(key => (getGlobal()[key] = window[key])); + * } + * ``` + * + * @returns {object} + * @license AGPLv3 + * @since 1.6.0 + * @copyright schukai GmbH + * @memberOf Monster.DOM + * @throws {Error} not supported environment + */ +/** + * This method fetches the document object + * + * In nodejs this functionality can be performed with [jsdom](https://www.npmjs.com/package/jsdom). + * + * ``` + * import {JSDOM} from "jsdom" + * if (typeof window !== "object") { + * const {window} = new JSDOM('', { + * url: 'http://example.com/', + * pretendToBeVisual: true + * }); + * + * [ + * 'self', + * 'document', + * 'Document', + * 'Node', + * 'Element', + * 'HTMLElement', + * 'DocumentFragment', + * 'DOMParser', + * 'XMLSerializer', + * 'NodeFilter', + * 'InputEvent', + * 'CustomEvent' + * ].forEach(key => (getGlobal()[key] = window[key])); + * } + * ``` + * + * @returns {DocumentFragment} + * @license AGPLv3 + * @since 1.6.0 + * @copyright schukai GmbH + * @memberOf Monster.DOM + * @throws {Error} not supported environment + * @throws {TypeError} value is not a string + */ +/** + * Recursively searches upwards from a given element to find an ancestor element + * with a specified ID, considering both normal DOM and shadow DOM. + * + * @param {HTMLElement|ShadowRoot} element - The starting element or shadow root to search from. + * @param {string} targetId - The ID of the target element to find. + * @returns {HTMLElement|null} - The ancestor element with the specified ID, or null if not found. + * @memberOf Monster.DOM + * @since 3.29.0 + * @license AGPLv3 + * @copyright schukai GmbH + */ +/** + * With this function you can read the language version set by the document. + * For this the attribute `lang` in the html tag is read. If no attribute is set, `en` is used as default. + * Alternatively, the language version of the browser is used. + * + * ```html + * <html lang="en"> + * ``` + * + * You can call the function via `getLocaleOfDocument()`. + * + * @license AGPLv3 + * @since 1.13.0 + * @copyright schukai GmbH + * @memberOf Monster.DOM + * @throws {TypeError} value is not a string + * @throws {Error} unsupported locale + * @summary Tries to determine the locale used + */ +/** + * With the id class, sequences of ids can be created. for this purpose, an internal counter is incremented for each prefix. + * thus, the first id with the prefix `myid` will be `myid1` and the second id `myid2`. + * The ids are the same for every call, for example on a web page. + * + * So the ids can also be used for navigation. you just have to take care that the order stays the same. + * + * As of version 1.6.0 there is the new RandomID. this ID class is continuous from now on. + * + * @license AGPLv3 + * @since 1.0.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + * @summary Automatic generation of ids + */ +/** + * A `TokenList` allows you to manage tokens (individual character strings such as css classes in an attribute string). + * + * The `TokenList` offers various functions to manipulate values. For example, you can add, remove or replace a class in a CSS list. + * + * This class implements the [iteration protocol](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols). + * + * @externalExample ../../example/types/tokenlist-1.mjs + * @license AGPLv3 + * @since 1.2.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + */ +/** + * @memberOf Monster.DOM + * @license AGPLv3 + * @since 1.8.0 + * @type {string} + */ +/** + * This is the name of the attribute to pass options to a control + * + * @memberOf Monster.DOM + * @license AGPLv3 + * @since 1.8.0 + * @type {string} + */ +/** + * This is name of the attribute to pass the script host to a control + * + * @memberOf Monster.DOM + * @license AGPLv3 + * @since 3.48.0 + * @type {string} + */ +/** + * This is the name of the attribute to pass options to a control + * + * @memberOf Monster.DOM + * @license AGPLv3 + * @since 1.30.0 + * @type {string} + */ +/** + * This is the name of the attribute to pass the callback to a control + * + * @memberOf Monster.DOM + * @license AGPLv3 + * @since 3.48.0 + * @type {string} + */ +/** + * This is the name of the callback to pass the callback to a control + * + * @memberOf Monster.DOM + * @license AGPLv3 + * @since 3.48.0 + * @type {string} + */ +/** + * @memberOf Monster.DOM + * @type {string} + * @license AGPLv3 + * @since 1.8.0 + */ +/** + * @memberOf Monster.DOM + * @type {string} + * @license AGPLv3 + * @since 1.27.1 + */ +/** + * @memberOf Monster.DOM + * @type {string} + * @license AGPLv3 + * @since 1.9.0 + */ +/** + * @memberOf Monster.DOM + * @type {string} + * @license AGPLv3 + * @since 1.27.0 + */ +/** + * @memberOf Monster.DOM + * @type {string} + * @license AGPLv3 + * @since 1.14.0 + */ +/** + * @memberOf Monster.DOM + * @type {string} + * @license AGPLv3 + * @since 1.24.0 + */ +/** + * @memberOf Monster.DOM + * @type {symbol} + * @license AGPLv3 + * @since 1.24.0 + */ +/** + * @memberOf Monster.DOM + * @type {string} + * @license AGPLv3 + * @since 1.25.0 + */ +/** + * Get the closest object link of a node + * + * if a node is specified without a object link, a recursive search upwards is performed until the corresponding + * object link is found, or undefined is returned. + * + * @param {HTMLElement} element + * @return {HTMLElement|undefined} + * @license AGPLv3 + * @since 1.10.0 + * @copyright schukai GmbH + * @memberOf Monster.DOM + * @throws {TypeError} value is not an instance of HTMLElement + */ +/** + * Adds a class attribute to an element. + * + * @license AGPLv3 + * @since 1.9.0 + * @copyright schukai GmbH + * @memberOf Monster.DOM + * @param {HTMLElement} element + * @param {Symbol} symbol + * @param {Object} object + * @return {boolean} + */ +/** + * Removes an object from an element + * + * @license AGPLv3 + * @since 1.9.0 + * @copyright schukai GmbH + * @memberOf Monster.DOM + * @param {HTMLElement} element + * @param {Symbol} symbol + * @return {boolean} + */ +/** + * Checks if an element has an object link + * + * @license AGPLv3 + * @since 1.9.0 + * @copyright schukai GmbH + * @memberOf Monster.DOM + * @param {HTMLElement} element + * @param {Symbol} symbol + * @return {boolean} + */ +/** + * The ObjectLink can be used to attach objects to HTMLElements. The elements are kept in a set under a unique + * symbol and can be read via an iterator {@see {@link getLinkedObjects}}. + * + * In addition, elements with an objectLink receive the attribute `data-monster-objectlink`. + * + * With the method {@see {@link addToObjectLink}} the objects can be added. + * + * @license AGPLv3 + * @since 1.9.0 + * @copyright schukai GmbH + * @memberOf Monster.DOM + * @param {HTMLElement} element + * @param {Symbol} symbol + * @return {Iterator} + * @throws {Error} there is no object link for symbol + */ +/** + * With this method tokens in an attribute can be switched on or off. For example, classes can be switched on and off in the elements class attribute. + * + * Tokens are always separated by a space. + * + * @license AGPLv3 + * @since 1.9.0 + * @copyright schukai GmbH + * @memberOf Monster.DOM + * @param {HTMLElement} element + * @param {string} key + * @param {string} token + * @return {HTMLElement} + */ +/** + * This method can be used to add a token to an attribute. Tokens are always separated by a space. + * + * @license AGPLv3 + * @since 1.9.0 + * @copyright schukai GmbH + * @memberOf Monster.DOM + * @param {HTMLElement} element + * @param {string} key + * @param {string} token + * @return {HTMLElement} + */ +/** + * This function can be used to remove tokens from an attribute. + * + * Tokens are always separated by a space. + * + * @license AGPLv3 + * @since 1.9.0 + * @copyright schukai GmbH + * @memberOf Monster.DOM + * @param {HTMLElement} element + * @param {string} key + * @param {string} token + * @return {HTMLElement} + */ +/** + * This method can be used to determine whether an attribute has a token. + * + * Tokens are always separated by a space. + * + * @license AGPLv3 + * @since 1.9.0 + * @copyright schukai GmbH + * @memberOf Monster.DOM + * @param {HTMLElement} element + * @param {string} key + * @param {string} token + * @return {boolean} + */ +/** + * Tokens are always separated by a space. + * + * @license AGPLv3 + * @since 1.9.0 + * @copyright schukai GmbH + * @memberOf Monster.DOM + * @param {HTMLElement} element + * @param {string} key + * @param {string} from + * @param {string} to + * @return {HTMLElement} + */ +/** + * Tokens are always separated by a space. + * + * @license AGPLv3 + * @since 1.9.0 + * @copyright schukai GmbH + * @memberOf Monster.DOM + * @param {HTMLElement} element + * @param {string} key + * @return {HTMLElement} + */ +/** + * This function searches, starting from an `HTMLElemement`, for the next element that has a certain attribute. + * + * ```html + * <div data-my-attribute="2" id="2"> + * <div id="1"></div> + * </div> + * ``` + * + * ```javascript + * // if no value is specified (undefined), then only the attribute is checked. + * findClosestByAttribute(document.getElementById('1'),'data-my-attribute'); // ↦ node with id 2 + * findClosestByAttribute(document.getElementById('2'),'data-my-attribute'); // ↦ node with id 2 + * + * // if a value is specified, for example an empty string, then the name and the value are checked. + * findClosestByAttribute(document.getElementById('1'),'data-my-attribute', ''); // ↦ undefined + * findClosestByAttribute(document.getElementById('1'),'data-my-attribute', '2'); // ↦ node with id 2 + * ``` + * + * @license AGPLv3 + * @since 1.14.0 + * @copyright schukai GmbH + * @memberOf Monster.DOM + * @param {HTMLElement} element + * @param {string} key + * @param {string|undefined} value + * @return {HTMLElement|undefined} + * @summary find closest node + */ +/** + * This function searches, starting from an `HTMLElemement`, for the next element that has a certain attribute. + * + * ```html + * <div class="myclass" id="2"> + * <div id="1"></div> + * </div> + * ``` + * + * ```javascript + * // if no value is specified (undefined), then only the attribute is checked. + * findClosestByClass(document.getElementById('1'),'myclass'); // ↦ node with id 2 + * findClosestByClass(document.getElementById('2'),'myclass'); // ↦ node with id 2 + * ``` + * + * ``` + * <script type="module"> + * import {findClosestByClass} from '@schukai/monster/source/dom/attributes.mjs'; + * findClosestByClass(); + * <\/script> + * ``` + * + * @license AGPLv3 + * @since 1.27.0 + * @copyright schukai GmbH + * @memberOf Monster.DOM + * @param {HTMLElement} element + * @param {string} className + * @return {HTMLElement|undefined} + * @summary find closest node + */ +/** + * You can call the method via the monster namespace `new Monster.Types.Queue()`. + * + * @license AGPLv3 + * @since 1.4.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + */ +/** + * Pathfinder is a class to find a path to an object. + * + * With the help of the pathfinder, values can be read and written from an object construct. + * + * ``` + * new Pathfinder({ + * a: { + * b: { + * f: [ + * { + * g: false, + * } + * ], + * } + * } + * }).getVia("a.b.f.0.g"); // ↦ false + * ``` + * + * if a value is not present or has the wrong type, a corresponding exception is thrown. + * + * ``` + * new Pathfinder({}).getVia("a.b.f.0.g"); // ↦ Error + * ``` + * + * The `Pathfinder.exists()` method can be used to check whether access to the path is possible. + * + * ``` + * new Pathfinder({}).exists("a.b.f.0.g"); // ↦ false + * ``` + * + * pathfinder can also be used to build object structures. to do this, the `Pathfinder.setVia()` method must be used. + * + * ``` + * obj = {}; + * new Pathfinder(obj).setVia('a.b.0.c', true); // ↦ {a:{b:[{c:true}]}} + * ``` + * + * @externalExample ../../example/data/pathfinder-1.mjs + * @externalExample ../../example/data/pathfinder-2.mjs + * @license AGPLv3 + * @since 1.4.0 + * @copyright schukai GmbH + * @memberOf Monster.Data + */ +/** + * + * @param {object} subject + * @param {string} path + * @returns {void} + * @throws {TypeError} unsupported type + * @throws {TypeError} unsupported type + * @throws {Error} the journey is not at its end + * @throws {Error} unsupported action for this data type + * @license AGPLv3 + * @since 1.6.0 + * @private + */ +/** + * This is the base class with options from which some monster classes are derived. + * + * This class is actually only used as a base class. + * + * Classes that require the possibility of options can be derived directly from this class. + * Derived classes almost always override the `defaul` getter with their own values. + * + * @externalExample ../../example/types/basewithoptions.mjs + * @license AGPLv3 + * @since 1.13.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + * @deprecated since 3.15.0 use {@link Monster.Types.Base} with {@link Monster.Types.equipWithInternal} instead. + */ +/** + * @memberOf Monster.I18n + * @type {symbol} + * @license AGPLv3 + * @since 3.9.0 + * @private + */ +/** + * A provider makes a translation object available. + * + * @license AGPLv3 + * @since 1.13.0 + * @copyright schukai GmbH + * @memberOf Monster.I18n + * @see {@link https://datatracker.ietf.org/doc/html/rfc3066} + */ +/** + * With this class you can manage translations and access the keys. + * + * @externalExample ../../example/i18n/translations.mjs + * @license AGPLv3 + * @since 1.13.0 + * @copyright schukai GmbH + * @memberOf Monster.I18n + * @see https://datatracker.ietf.org/doc/html/rfc3066 + */ +/** + * The transformer class is a swiss army knife for manipulating values. especially in combination with the pipe, processing chains can be built up. + * + * A simple example is the conversion of all characters to lowercase. for this purpose the command `tolower` must be used. + * + * ``` + * let t = new Transformer('tolower').run('ABC'); // ↦ abc + * ``` + * + * @see {@link https://monsterjs.org/en/doc/#transformer|Monster Docs} + * + * @externalExample ../../example/data/transformer.mjs + * @license AGPLv3 + * @since 1.5.0 + * @copyright schukai GmbH + * @memberOf Monster.Data + */ +/** + * The pipe class makes it possible to combine several processing steps. + * + * A pipe consists of commands whose input and output are connected with the pipe symbol `|`. + * + * With the Pipe, processing steps can be combined. Here, the value of an object is accessed via the pathfinder (path command). + * the word is then converted to uppercase letters and a prefix Hello is added. the two backslash safe the space char. + * + * @externalExample ../../example/data/pipe.mjs + * @license AGPLv3 + * @since 1.5.0 + * @copyright schukai GmbH + * @memberOf Monster.Data + */ +/** + * Messages can be formatted with the formatter. To do this, an object with the values must be passed to the formatter. The message can then contain placeholders. + * + * Look at the example below. The placeholders use the logic of Pipe. + * + * ## Marker in marker + * + * Markers can be nested. Here, the inner marker is resolved first `${subkey} ↦ 1 = ${mykey2}` and then the outer marker `${mykey2}`. + * + * ``` + * const text = '${mykey${subkey}}'; + * let obj = { + * mykey2: "1", + * subkey: "2" + * }; + * + * new Formatter(obj).format(text); + * // ↦ 1 + * ``` + * + * ## Callbacks + * + * The values in a formatter can be adjusted via the commands of the `Transformer` or the`Pipe`. + * There is also the possibility to use callbacks. + * + * const formatter = new Formatter({x: '1'}, { + * callbacks: { + * quote: (value) => { + * return '"' + value + '"' + * } + * } + * }); + * + * formatter.format('${x | call:quote}')) + * // ↦ "1" + * + * ## Marker with parameter + * + * A string can also bring its own values. These must then be separated from the key by a separator `::`. + * The values themselves must be specified in key/value pairs. The key must be separated from the value by a separator `=`. + * + * When using a pipe, you must pay attention to the separators. + * + * @example + * + * import {Formatter} from '@schukai/monster/source/text/formatter.mjs'; + * + * new Formatter({ + * a: { + * b: { + * c: "Hello" + * }, + * d: "world", + * } + * }).format("${a.b.c} ${a.d | ucfirst}!"); // with pipe + * + * // ↦ Hello World! + * + * @license AGPLv3 + * @since 1.12.0 + * @copyright schukai GmbH + * @memberOf Monster.Text + */ +/** + * @private + * @license AGPLv3 + * @since 1.12.0 + * @param text + * @return {string} + */ +/** + * this function uses crypt and returns a random number. + * + * @param {number} min starting value of the definition set (default is 0) + * @param {number} max end value of the definition set (default is 1000000000) + * @returns {number} + * @memberOf Monster.Math + * @throws {Error} missing crypt + * @throws {Error} we cannot generate numbers larger than 53 bits. + * @throws {Error} the distance is too small to create a random number. + + * @license AGPLv3 + * @since 1.0.0 + * @copyright schukai GmbH + */ +/** + * This special trim function allows to trim spaces that have been protected by a special escape character. + * + * ``` + * <script type="module"> + * import {trimSpaces} from '@schukai/monster/source/util/trimspaces.mjs'; + * trimSpaces(' hello \\ ') + * <\/script> + * ``` + * + * Hint: One stroke is escaped by the javascript interpreter, the second stroke escapes the stroke. + * + * ```text + * a\ b ↦ a b + * a\\ b ↦ a\ b + * ``` + * + * @license AGPLv3 + * @since 1.24.0 + * @memberOf Monster.Util + * @copyright schukai GmbH + * @param {string} value + * @return {string} + * @throws {TypeError} value is not a string + */ +/** + * A queue is a list of items that are processed one after another (first in, first out). + * + * With a queue you can add items to the end of the list `Queue.add()` and remove items from the beginning of the list `Queue.pop()`. + * + * With `Queue.peek()` you can get the first item without removing it from the list. + * + * You can create the instance via `new Queue()`. + * + * @externalExample ../../example/types/queue.mjs + * @license AGPLv3 + * @since 1.4.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + * @summary A Queue (Fifo) + */ +/** + * An UniqueQueue is a queue that contains items only once. + * + * @license AGPLv3 + * @since 1.4.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + * @summary A queue for unique values + */ +/** + * An observer manages a callback function + * + * The update method is called with the subject object as this pointer. For this reason the callback should not + * be an arrow function, because it gets this pointer of its own context. + * + * ```js + * new Observer(()=>{ + * // this is not subject + * }) + * + * new Observer(function() { + * // this is subject + * }) + * ``` + * + * Additional arguments can be passed to the callback. To do this, simply specify them. + * + * ```js + * Observer(function(a, b, c) { + * console.log(a, b, c); // ↦ "a", 2, true + * }, "a", 2, true) + * ``` + * + * The callback function must have as many parameters as arguments are given. + * + * @externalExample ../../example/types/observer.mjs + * @license AGPLv3 + * @since 1.0.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + */ +/** + * With the help of the ObserverList class, observer can be managed. + * + * @license AGPLv3 + * @since 1.0.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + */ +/** + * An observer manages a callback function + * + * With the ProxyObserver you can attach observer for observation. + * With each change at the object to be observed an update takes place. + * + * This also applies to nested objects. + * + * @externalExample ../../example/types/proxyobserver.mjs + * @license AGPLv3 + * @since 1.0.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + */ +/** + * This class is the base class for all resources to be loaded. + * + * @license AGPLv3 + * @since 1.25.0 + * @copyright schukai GmbH + * @memberOf Monster.DOM + * @summary A Resource class + */ +/** + * You can create an object via the monster namespace `new Monster.Types.MediaType()`. + * + * @license AGPLv3 + * @since 1.8.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + */ +/** + * @private + * @license AGPLv3 + * @since 1.18.0 + * @param {String} parameter + * @return {Monster.Types.Parameter[]|undefined} + * @memberOf Monster.Types + */ +/** + * You can create an object via the monster namespace `new Monster.Types.DataUrl()`. + * + * @license AGPLv3 + * @since 1.8.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs + * @see https://datatracker.ietf.org/doc/html/rfc2397 + */ +/** + * The Theme class provides the functionality for the theme. + * + * @externalExample ../../example/dom/theme.mjs + * @license AGPLv3 + * @since 1.7.0 + * @copyright schukai GmbH + * @memberOf Monster.DOM + * @summary A theme class + */ +/** + * The theming used in the document can be defined via the html-tag. + * The theming is specified via the attribute `data-monster-theme-name`. + * + * As name for a theme all characters are valid, which are also allowed for a HTMLElement-ID. + * + * ``` + * <html data-monster-theme-name="my-theme"> + * ``` + * + * the default theme name is `monster`. + * + * @return {Theme} + * @memberOf Monster.DOM + * @license AGPLv3 + * @since 1.7.0 + */ +/** + * The template class provides methods for creating templates. + * + * @license AGPLv3 + * @since 1.6.0 + * @copyright schukai GmbH + * @memberOf Monster.DOM + * @summary A template class + */ +/** + * This method loads a template with the given ID and returns it. + * + * To do this, it first reads the theme of the document and looks for the `data-monster-theme-name` attribute in the HTML tag. + * + * ``` + * <html data-monster-theme-name="my-theme"> + * ``` + * + * If no theme was specified, the default theme is `monster`. + * + * Now it is looked if there is a template with the given ID and theme `id-theme` and if yes it is returned. + * If there is no template a search for a template with the given ID `id` is done. If this is also not found, an error is thrown. + * + * You can call the method via the monster namespace `Monster.DOM.findDocumentTemplate()`. + * + * ``` + * <script type="module"> + * import {findTemplate} from '@schukai/monster/source/dom/template.mjs'; + * findDocumentTemplate() + * <\/script> + * ``` + * + * @example + * + * import { findDocumentTemplate } from "https://cdn.jsdelivr.net/npm/@schukai/monster@latest/source/dom/template.mjs"; + * + * const template = document.createElement("template"); + * template.id = "myTemplate"; + * template.innerHTML = "<p>my default template</p>"; + * document.body.appendChild(template); + * + * const themedTemplate = document.createElement("template"); + * themedTemplate.id = "myTemplate-myTheme"; + * themedTemplate.innerHTML = "<p>my themed template</p>"; + * document.body.appendChild(themedTemplate); + * + * // loads the temple and since no theme is set the default template + * const template1 = findDocumentTemplate("myTemplate"); + * console.log(template1.createDocumentFragment()); + * // ↦ '<p>my default template</p>' + * + * // now we set our own theme + * document + * .querySelector("html") + * .setAttribute("data-monster-theme-name", "myTheme"); + * + * // now we don't get the default template, + * // but the template with the theme in the id + * const template2 = findDocumentTemplate("myTemplate"); + * console.log(template2.createDocumentFragment()); + * // ↦ '<p>my themed template</p>' + * + * @param {string} id + * @param {Node} currentNode + * @return {Monster.DOM.Template} + * @license AGPLv3 + * @since 1.7.0 + * @copyright schukai GmbH + * @memberOf Monster.DOM + * @throws {Error} template id not found. + * @throws {TypeError} value is not a string + */ +/** + * With the diff function you can perform the change of one object to another. The result shows the changes of the second object to the first object. + * + * The operator `add` means that something has been added to the second object. `delete` means that something has been deleted from the second object compared to the first object. + * + * @externalExample ../../example/data/diff.mjs + * @param {*} first + * @param {*} second + * @return {array} + * @license AGPLv3 + * @since 1.6.0 + * @copyright schukai GmbH + * @memberOf Monster.Data + */ +/** + * The function sends an event + * + * @param {HTMLElement|HTMLCollection|NodeList} element + * @param {string} type + * @return {void} + * @license AGPLv3 + * @since 1.10.0 + * @copyright schukai GmbH + * @memberOf Monster.DOM + * @throws {TypeError} value is not an instance of HTMLElement or HTMLCollection + * @summary Construct and send and event + */ +/** + * You can call the function via the monster namespace `new Monster.DOM.fireCustomEvent()`. + * + * @param {HTMLElement|HTMLCollection|NodeList} element + * @param {string} type + * @return {void} + * @license AGPLv3 + * @since 1.29.0 + * @copyright schukai GmbH + * @memberOf Monster.DOM + * @throws {TypeError} value is not an instance of HTMLElement or HTMLCollection + * @summary Construct and send and event + */ +/** + * This function gets the path `Event.composedPath()` from an event and tries to find the next element + * up the tree `element.closest()` with the attribute and value. If no value, or a value that is undefined or null, + * is specified, only the attribute is searched. + * + * @license AGPLv3 + * @since 1.14.0 + * @param {Event} event + * @param {string} attributeName + * @param {string|null|undefined} attributeValue + * @throws {Error} unsupported event + * @memberOf Monster.DOM + * @throws {TypeError} value is not a string + * @throws {TypeError} value is not an instance of HTMLElement + * @summary Help function to find the appropriate control + */ +/** + * The updater class connects an object with the dom. In this way, structures and contents in the DOM can be programmatically adapted via attributes. + * + * For example, to include a string from an object, the attribute `data-monster-replace` can be used. + * a further explanation can be found under [monsterjs.org](https://monsterjs.org/) + * + * Changes to attributes are made only when the direct values are changed. If you want to assign changes to other values + * as well, you have to insert the attribute `data-monster-select-this`. This should be done with care, as it can reduce performance. + * + * @externalExample ../../example/dom/updater.mjs + * @license AGPLv3 + * @since 1.8.0 + * @copyright schukai GmbH + * @memberOf Monster.DOM + * @throws {Error} the value is not iterable + * @throws {Error} pipes are not allowed when cloning a node. + * @throws {Error} no template was found with the specified key. + * @throws {Error} the maximum depth for the recursion is reached. + * @throws {TypeError} value is not a object + * @throws {TypeError} value is not an instance of HTMLElement + * @summary The updater class connects an object with the dom + */ +/** + * @private + * @license AGPLv3 + * @since 1.9.0 + * @return {function + * @this Updater + */ +/** + * @license AGPLv3 + * @since 1.27.0 + * @return void + * @private + */ +/** + * @private + * @license AGPLv3 + * @since 1.8.0 + * @param {object} change + * @return {void} + */ +/** + * @private + * @license AGPLv3 + * @since 1.8.0 + * @param {object} change + * @return {void} + * @throws {Error} the value is not iterable + * @throws {Error} pipes are not allowed when cloning a node. + * @throws {Error} no template was found with the specified key. + * @throws {Error} the maximum depth for the recursion is reached. + * @this Updater + */ +/** + * + * @private + * @license AGPLv3 + * @since 1.8.0 + * @param {HTMLElement} container + * @param {string} key + * @param {string} ref + * @param {string} path + * @throws {Error} no template was found with the specified key. + */ +/** + * @private + * @license AGPLv3 + * @since 1.10.0 + * @param {HTMLElement} node + * @param {string} key + * @param {string} path + * @return {void} + */ +/** + * @private + * @license AGPLv3 + * @since 1.8.0 + * @param {object} change + * @return {void} + * @this Updater + */ +/** + * @private + * @license AGPLv3 + * @since 1.8.0 + * @param {HTMLElement} container + * @param {array} parts + * @param {object} subject + * @return {void} + */ +/** + * @private + * @license AGPLv3 + * @since 1.8.0 + * @param {string} path + * @param {object} change + * @return {void} + */ +/** + * @param {NodeList|HTMLElement|Set<HTMLElement>} elements + * @param {Symbol} symbol + * @param {object} object + * @return {Promise[]} + * @license AGPLv3 + * @since 1.23.0 + * @memberOf Monster.DOM + * @throws {TypeError} elements is not an instance of NodeList, HTMLElement or Set + * @throws {TypeError} the context of the function is not an instance of HTMLElement + * @throws {TypeError} symbol must be an instance of Symbol + */ +/** + * @private + * @param {String|undefined} query + * @param {String|undefined|null} name name of the slot (if the parameter is undefined, all slots are searched, if the parameter has the value null, all slots without a name are searched. if a string is specified, the slots with this name are searched.) + * @return {*} + * @this CustomElement + * @license AGPLv3 + * @since 3.33.0 + * @throws {Error} query must be a string + */ +/** + * @private + * @param {String|undefined} query + * @param {String|undefined|null} name name of the slot (if the parameter is undefined, all slots are searched, if the parameter has the value null, all slots without a name are searched. if a string is specified, the slots with this name are searched.) + * @return {*} + * @this CustomElement + * @license AGPLv3 + * @since 1.23.0 + * @throws {Error} query must be a string + */ +/** + * The `CustomElement` class provides a way to define a new HTML element using the power of Custom Elements. + * + * **IMPORTANT:** After defining a `CustomElement`, the `registerCustomElement` method must be called with the new class name + * to make the tag defined via the `getTag` method known to the DOM. + * + * You can create an instance of the object via the `document.createElement()` function. + * + * ## Interaction + * + * <img src="./images/customelement-sequencediagram.png"> + * + * ## Styling + * + * To display custom elements optimally, the `:defined` pseudo-class can be used. To prevent custom elements from being displayed and flickering until the control is registered, + * it is recommended to create a CSS directive. + * + * In the simplest case, you can simply hide the control: + * + * ```html + * <style> + * my-custom-element:not(:defined) { + * display: none; + * } + * + * my-custom-element:defined { + * display: flex; + * } + * </style> + * ``` + * + * Alternatively, you can display a loader: + * + * ```css + * my-custom-element:not(:defined) { + * display: flex; + * box-shadow: 0 4px 10px 0 rgba(33, 33, 33, 0.15); + * border-radius: 4px; + * height: 200px; + * position: relative; + * overflow: hidden; + * } + * + * my-custom-element:not(:defined)::before { + * content: ''; + * display: block; + * position: absolute; + * left: -150px; + * top: 0; + * height: 100%; + * width: 150px; + * background: linear-gradient(to right, transparent 0%, #E8E8E8 50%, transparent 100%); + * animation: load 1s cubic-bezier(0.4, 0.0, 0.2, 1) infinite; + * } + * + * @keyframes load { + * from { + * left: -150px; + * } + * to { + * left: 100%; + * } + * } + * + * my-custom-element:defined { + * display: flex; + * } + * ``` + * + * More information about Custom Elements can be found in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements). + * And in the [HTML Standard](https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements) or in the [WHATWG Wiki](https://wiki.whatwg.org/wiki/Custom_Elements). + * + * @externalExample ../../example/dom/theme.mjs + * @license AGPLv3 + * @since 1.7.0 + * @copyright schukai GmbH + * @memberOf Monster.DOM + * @extends external:HTMLElement + * @summary A base class for HTML5 custom controls. + */ +/** + * @license AGPLv3 + * @since 1.15.0 + * @private + * @this CustomElement + */ +/** + * @private + * @return {CustomElement} + * @memberOf Monster.DOM + * @this CustomElement + * @license AGPLv3 + * @since 1.16.0 + * @throws {TypeError} value is not an instance of + */ +/** + * @private + * @return {CustomElement} + * @throws {Error} html is not set. + * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow + * @memberOf Monster.DOM + * @license AGPLv3 + * @since 1.8.0 + */ +/** + * This method registers a new element. The string returned by `CustomElement.getTag()` is used as the tag. + * + * @param {CustomElement} element + * @return {void} + * @license AGPLv3 + * @since 1.7.0 + * @copyright schukai GmbH + * @memberOf Monster.DOM + * @throws {DOMException} Failed to execute 'define' on 'CustomElementRegistry': is not a valid custom element name + */ +/** + * This variable is a promise that is fulfilled as soon as the dom is available. + * + * The DOMContentLoaded event is fired when the original HTML document is fully loaded and parsed + * without waiting for stylesheets, images, and subframes to finish loading. + * + * document.readyState changes to interactive + * window's DOMContentLoaded event gets fired + * document.readyState changes to complete + * window's load event gets fired load + * + * @license AGPLv3 + * @since 1.31.0 + * @memberOf Monster.DOM + * @summary variable to check if dom is ready + * @type {Promise} + * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/DOMContentLoaded_event + * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState + */ +/** + * This variable is a promise that is fulfilled as soon as the windows is available. + * + * The load event fires when the entire page is loaded, including all dependent resources such as stylesheets, + * assets, and images. Unlike DOMContentLoaded, which fires as soon as the DOM of the page is loaded, + * without waiting for the resources to finish loading. + * + * @license AGPLv3 + * @since 1.31.0 + * @memberOf Monster.DOM + * @summary variable to check if window is ready + * @type {Promise} + * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event + * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState + */ +/** + * This is a base class for creating custom controls using the power of CustomElement. + * + * After defining a `CustomElement`, the `registerCustomElement` method must be called with the new class name. Only then + * will the tag defined via the `getTag` method be made known to the DOM. + * + * <img src="./images/customcontrol-class.png"> + * + * This control uses `attachInternals()` to integrate the control into a form. If the target environment does not support + * this method, the [polyfill](https://www.npmjs.com/package/element-internals-polyfill) can be used. + * + * You can create the object using the function `document.createElement()`. + * + * This control uses `attachInternals()` to integrate the control into a form. If the target environment does not support + * this method, the Polyfill for attachInternals() can be used: {@link https://www.npmjs.com/package/element-internals-polyfill|element-internals-polyfill}. + * + * Learn more about WICG Web Components: {@link https://github.com/WICG/webcomponents|WICG Web Components}. + * + * Read the HTML specification for Custom Elements: {@link https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements|Custom Elements}. + * + * Read the HTML specification for Custom Element Reactions: {@link https://html.spec.whatwg.org/dev/custom-elements.html#custom-element-reactions|Custom Element Reactions}. + * + * @summary A base class for custom controls based on CustomElement. + * @copyright schukai GmbH + * @license AGPLv3 + * @since 1.14.0 + * @memberOf Monster.DOM + * @extends Monster.DOM.CustomElement + */ +/** + * The `RandomID` class provides a unique ID for an item. + * + * @license AGPLv3 + * @since 1.6.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + * @summary class to generate random numbers + */ +/** + * The UUID class makes it possible to get a unique UUID for an object. + * + * @license AGPLv3 + * @since 1.25.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + * @throws {Error} unsupported + */ +/** + * This class allows to execute several functions in order. + * + * Functions and timeouts can be passed. If a timeout is passed, it applies to all further functions. + * In the example + * + * `timeout1, function1, function2, function3, timeout2, function4` + * + * the timeout1 is valid for the functions 1, 2 and 3 and the timeout2 for the function4. + * + * So the execution time is timeout1+timeout1+timeout1+timeout2 + * + * The result of `run()` is a promise. + * + * @externalExample ../../example/util/processing.mjs + * @copyright schukai GmbH + * @license AGPLv3 + * @since 1.21.0 + * @memberOf Monster.Util + * @summary Class to be able to execute function chains + */ +/** + * The dead man's switch allows to set a timer which can be reset again and again within a defined period of time. + * + * @externalExample ../../example/util/deadmansswitch.mjs + * @copyright schukai GmbH + * @license AGPLv3 + * @since 1.29.0 + * @memberOf Monster.Util + * @summary Class to be able to execute function chains + */ +/** + * The comparator allows a comparison function to be abstracted. + * + * The following are some examples of the application of the class. + * + * ``` + * new Comparator().lessThanOrEqual(2, 5) // ↦ true + * new Comparator().greaterThan(4, 2) // ↦ true + * new Comparator().equal(4, 4) // ↦ true + * new Comparator().equal(4, 5) // ↦ false + * ``` + * + * You can also pass your own comparison function, and thus define the comparison function. + * + * ``` + * new Comparator(function (a, b) { + * if (a.v === b.v) return 0; + * return a.v < b.v ? -1 : 1; + * }).equal({v: 2}, {v: 2}); // ↦ true + * ``` + * + * @externalExample ../../example/util/comparator.mjs + * @license AGPLv3 + * @since 1.3.0 + * @memberOf Monster.Util + */ +/** + * Deep freeze a object + * + * @param {object} object object to be freeze + * @license AGPLv3 + * @since 1.0.0 + * @returns {object} + * @memberOf Monster.Util + * @copyright schukai GmbH + * @throws {TypeError} value is not a object + */ +/** + * A log entry for the logger + * + * @license AGPLv3 + * @since 1.5.0 + * @copyright schukai GmbH + * @memberOf Monster.Logging + */ +/** + * The logger is a class that takes care of logging. + * + * @license AGPLv3 + * @since 1.5.0 + * @copyright schukai GmbH + * @memberOf Monster.Logging + */ +/** + * The log handler is the interface between the log entries and the log listeners. + * + * @license AGPLv3 + * @since 1.5.0 + * @copyright schukai GmbH + * @memberOf Monster.Logging + */ +/** + * You can create an object of the class simply by using the namespace `new Monster.Logging.Handler.ConsoleHandler()`. + * + * @license AGPLv3 + * @since 1.5.0 + * @copyright schukai GmbH + * @memberOf Monster.Logging.Handler + */ +/** + * An observable queue is a list of items that are processed one after another (first in, first out). + * + * `Queue.add()` and `Queue.clear()` notify all observers. + * + * @externalExample ../../example/types/queue.mjs + * @license AGPLv3 + * @since 3.3.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + * @summary An observable Queue (Fifo) + */ +/** + * This class represents a WebSocket message. + * + * @license AGPLv3 + * @since 3.4.0 + * @copyright schukai GmbH + * @memberOf Monster.Net.WebSocket + * @summary The Message class encapsulates a WebSocket message. + */ +/** + * The RestAPI is a class that enables a REST API server. + * + * @externalExample ../../example/net/webconnect.mjs + * @license AGPLv3 + * @since 3.1.0 + * @copyright schukai GmbH + * @memberOf Monster.Net + * @summary The LocalStorage class encapsulates the access to data objects. + */ +/** + * The version object contains a semantic version number + * + * @externalExample ../../example/types/version-1.mjs + * @license AGPLv3 + * @since 1.0.0 + * @author schukai GmbH + * @copyright schukai GmbH + * @memberOf Monster.Types + * @summary The version object contains a sematic version number + */ +/** + * Version of monster + * + * @externalExample ../../example/types/version-2.mjs + * @returns {Monster.Types.Version} + * @license AGPLv3 + * @since 1.0.0 + * @copyright schukai GmbH + * @author schukai GmbH + * @memberOf Monster + */ +/** + * Converts a CSS value to pixels. + * + * As Example: + * + * ```js + * convertToPixels('1em') // returns the current font size in pixels + * convertToPixels('1rem') // returns the current root font size in pixels + * convertToPixels('1px') // returns 1 + * convertToPixels('100%') // returns the current width of the parent element in pixels + * ``` + * + * Following units are supported: + * - px + * - em + * - rem + * - % + * + * @param {string} value + * @param {HTMLElement} [parentElement=document.documentElement] + * @param {HTMLElement} [fontSizeElement=document.documentElement] + * @returns {number} + * @license AGPLv3 + * @since 3.34.0 + * @copyright schukai GmbH + * @throws {Error} Unsupported unit + * @memberOf Monster.DOM + * @throws {Error} Invalid value format + */ +/** + * This class is used by the resource manager to embed external resources. + * + * @license AGPLv3 + * @since 1.25.0 + * @copyright schukai GmbH + * @memberOf Monster.DOM.Resource + * @summary A Resource class + * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link + */ +/** + * This class is used by the resource manager to embed scripts. + * + * @license AGPLv3 + * @since 1.25.0 + * @copyright schukai GmbH + * @memberOf Monster.DOM.Resource + * @summary A Resource class + */ +/** + * This class is used by the resource manager to embed data. + * + * @license AGPLv3 + * @since 1.25.0 + * @copyright schukai GmbH + * @memberOf Monster.DOM.Resource + * @summary A Data Resource class + */ +/** + * A factory for creating worker instances. + * + * @license AGPLv3 + * @since 1.25.0 + * @copyright schukai GmbH + * @memberOf Monster.DOM.Worker + * @summary A small factory to create worker + */ +/** + * With the focus manager the focus can be stored in a document, recalled and moved. + * + * @license AGPLv3 + * @since 1.25.0 + * @copyright schukai GmbH + * @memberOf Monster.DOM + * @throws {Error} unsupported locale + * @summary Handle the focus + */ +/** + * This function extends the given object with the following methods: + * + * - attachInternalObserver + * - detachInternalObserver + * - containsInternalObserver + * - setInternal + * - setInternals + * - getInternal + * + * @license AGPLv3 + * @since 3.15.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + */ +/** + * The ResourceManager is a singleton that manages all resources. + * + * @license AGPLv3 + * @since 1.25.0 + * @copyright schukai GmbH + * @memberOf Monster.DOM + * @summary A Resource class + */ +/** + * Assembler class + * + * @license AGPLv3 + * @since 1.6.0 + * @copyright schukai GmbH + * @memberOf Monster.DOM + * @summary Allows you to build an html fragment + */ +/** + * @private + * @type {symbol} + * @memberOf Monster.Data + * @license AGPLv3 + * @since 1.24.0 + */ +/** + * The datasource class is the basis for dealing with different data sources. + * It provides a unified interface for accessing data + * @externalExample ../../example/data/datasource.mjs + * @license AGPLv3 + * @since 1.22.0 + * @copyright schukai GmbH + * @memberOf Monster.Data + * @summary The datasource class encapsulates the access to data objects. + */ +/** + * The DomStorage is a class that stores data in memory. + * + * @license AGPLv3 + * @copyright schukai GmbH + * @memberOf Monster.Data.Datasource + */ +/** + * The class represents a record. + * + * @license AGPLv3 + * @since 1.22.0 + * @copyright schukai GmbH + * @memberOf Monster.Data.Datasource + * @summary The Storage class encapsulates the access to data objects over WebStorageAPI. + */ +/** + * The LocalStorage Datasource provides a data store in the browser localStorage. + * + * @license AGPLv3 + * @since 1.22.0 + * @copyright schukai GmbH + * @memberOf Monster.Data.Datasource.Storage + * @summary The LocalStorage class encapsulates the access to data objects. + */ +/** + * The SessionStorage class provides a data source that uses the SessionStorage API on the client. + * + * @license AGPLv3 + * @since 1.22.0 + * @copyright schukai GmbH + * @memberOf Monster.Data.Datasource.Storage + * @summary The LocalStorage class encapsulates the access to data objects. + */ +/** + * Base class for all server datasources + * + * @license AGPLv3 + * @since 3.4.0 + * @copyright schukai GmbH + * @memberOf Monster.Data.Datasource + * @summary The Server class encapsulates the access to a server datasource + */ +/** + * The RestAPI is a class that enables a REST API server. + * + * @externalExample ../../../../example/data/datasource/server/webconnect.mjs + * @license AGPLv3 + * @since 3.1.0 + * @copyright schukai GmbH + * @memberOf Monster.Data.Datasource.Server + * @summary The LocalStorage class encapsulates the access to data objects. + */ +/** + * Error message for API requests with extension of request and validation. + * + * @license AGPLv3 + * @since 1.24.0 + * @copyright schukai GmbH + * @memberOf Monster.Data.Datasource.Server.RestAPI + * @summary the error is thrown by the rest api in case of error + */ +/** + * Error message for API requests + * + * @license AGPLv3 + * @since 3.43.0 + * @copyright schukai GmbH + * @memberOf Monster.Data.Datasource.Server.RestAPI + * @summary the error is thrown by the rest api in case of error + */ +/** + * @type {symbol} + * @memberOf Monster + * @license AGPLv3 + * @since 3.12.0 + */ +/** + * The RestAPI is a class that enables a REST API server. + * + * @externalExample ../../../../example/data/datasource/server/restapi.mjs + * @license AGPLv3 + * @since 1.22.0 + * @copyright schukai GmbH + * @memberOf Monster.Data.Datasource.Server + * @summary The RestAPI is a class that binds a REST API server. + */ +/** + * Alternatively to a string selector a callback can be specified. this must return a map. + * + * @example + * import {buildMap} from '@schukai/monster/source/data/buildmap.mjs'; + * + * let obj = { + * "data": [ + * { + * "id": 10, + * "name": "Cassandra", + * "enrichment": { + * variants: [ + * { + * sku: 1, label: "XXS", price: [ + * {vk: '12.12 €'}, + * {vk: '12.12 €'} + * ] + * }, + * { + * sku: 2, label: "XS", price: [ + * {vk: '22.12 €'}, + * {vk: '22.12 €'} + * ] + * }, + * { + * sku: 3, label: "S", price: [ + * {vk: '32.12 €'}, + * {vk: '32.12 €'} + * ] + * }, + * { + * sku: 4, label: "L", price: [ + * {vk: '42.12 €'}, + * {vk: '42.12 €'} + * ] + * } + * ] + * + * } + * }, + * { + * "id": 20, + * "name": "Yessey!", + * "enrichment": { + * variants: [ + * { + * sku: 1, label: "XXS", price: [ + * {vk: '12.12 €'}, + * {vk: '12.12 €'} + * ] + * }, + * { + * sku: 2, label: "XS", price: [ + * {vk: '22.12 €'}, + * {vk: '22.12 €'} + * ] + * }, + * { + * sku: 3, label: "S", price: [ + * {vk: '32.12 €'}, + * {vk: '32.12 €'} + * ] + * }, + * { + * sku: 4, label: "L", price: [ + * {vk: '42.12 €'}, + * {vk: '42.12 €'} + * ] + * } + * ] + * + * } + * } + * ] + * }; + * + * let callback = function (subject) { + * let m = new Map; + * + * for (const [i, b] of Object.entries(subject.data)) { + * + * let key1 = i; + * + * for (const [j, c] of Object.entries(b.enrichment.variants)) { + * let key2 = j; + * + * for (const [k, d] of Object.entries(c.price)) { + * + * let key3 = k; + * + * d.name = b.name; + * d.label = c.label; + * d.id = [key1, key2, key3].join('.'); + * + * m.set(d.id, d); + * } + * + * } + * } + * return m; + * } + * + * let map = buildMap(obj, callback, '${name} ${vk}', '${id}') + * + * // ↦ Map(3) { + * // "0.0.0":"Cassandra 12.12 €", + * // "0.0.1":"Cassandra 12.12 €", + * // "0.1.0":"Cassandra 22.12 €", + * // "0.1.1":"Cassandra 22.12 €", + * // "0.2.0":"Cassandra 32.12 €", + * // "0.2.1":"Cassandra 32.12 €", + * // "0.3.0":"Cassandra 42.12 €", + * // "0.3.1":"Cassandra 42.12 €", + * // "1.0.0":"Yessey! 12.12 €", + * // "1.0.1":"Yessey! 12.12 €", + * // "1.1.0":"Yessey! 22.12 €", + * // "1.1.1":"Yessey! 22.12 €", + * // "1.2.0":"Yessey! 32.12 €", + * // "1.2.1":"Yessey! 32.12 €", + * // "1.3.0":"Yessey! 42.12 €", + * // "1.3.1":"Yessey! 42.12 €" + * // } + * + * @callback Monster.Data~exampleSelectorCallback + * @param {*} subject subject + * @return Map + * @license AGPLv3 + * @since 1.17.0 + * @memberOf Monster.Data + * @see {@link Monster.Data.buildMap} + */ +/** + * The Embed provider retrieves a JSON file from the given Script Tag. + * + * @externalExample ../../../example/i18n/providers/embed.mjs + * @license AGPLv3 + * @since 1.13.0 + * @copyright schukai GmbH + * @memberOf Monster.I18n.Providers + * @see {@link https://datatracker.ietf.org/doc/html/rfc3066} + * @tutorial i18n-locale-and-formatter + */ +/** + * You can create the instance via the monster namespace `new Monster.Types.NodeList()`. + * + * @license AGPLv3 + * @since 1.26.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + * @summary A NodeList class + */ +/** + * You can create the instance via the monster namespace `new Monster.Types.Node()`. + * + * @license AGPLv3 + * @since 1.26.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + * @summary A Node Class + * @see https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Iteration_protocols + */ +/** + * Creates a tree structure from a given subject using a selector and specified ID and parent ID keys. + * + * The buildTree function is a powerful tool for creating tree-like data structures from plain JavaScript + * objects. It takes in four required parameters: the subject object that you want to turn into a tree, a + * selector that identifies which parts of the subject to use when building the tree, and two keys + * (idKey and parentIDKey) that specify which properties in the subject represent the unique identifiers + * and parent-child relationships between nodes in the tree. + * + * Optionally, you can also pass in an options object to further configure the behavior of the function, + * such as specifying which values should be treated as roots of the tree, or providing a custom filter + * function to only include certain nodes in the final output. + * + * The buildTree function works by first using the assembleParts helper function to extract the relevant + * parts of the subject based on the selector, and then iterates over the resulting map to create Node + * objects and organize them into parent-child relationships based on the values of the idKey and parentIDKey properties. + * + * The resulting NodeList represents the tree structure, with each Node object containing the original + * object data as well as additional metadata about its position in the tree. You can then use the childNodes + * property of each Node to access its children, or the parent property to access its parent. + * + * Overall, the buildTree function is a flexible and powerful way to transform flat data into hierarchical + * structures, and can be especially useful in scenarios such as displaying folder structures or + * visualizing complex data relationships. + * + * Let's say you have an array of data objects representing a file system directory structure, and you want + * to turn it into a tree-like structure where each node represents a folder or file, and child nodes + * represent the contents of the folder: + * + * ```javascript + * const fileSystem = [ + * { id: 'folder1', name: 'Folder 1', type: 'folder', parent: null }, + * { id: 'file1', name: 'File 1', type: 'file', parent: 'folder1' }, + * { id: 'file2', name: 'File 2', type: 'file', parent: 'folder1' }, + * { id: 'subfolder1', name: 'Subfolder 1', type: 'folder', parent: 'folder1' }, + * { id: 'file3', name: 'File 3', type: 'file', parent: 'subfolder1' }, + * { id: 'file4', name: 'File 4', type: 'file', parent: 'subfolder1' }, + * { id: 'subfolder2', name: 'Subfolder 2', type: 'folder', parent: 'folder1' }, + * { id: 'file5', name: 'File 5', type: 'file', parent: 'subfolder2' }, + * { id: 'file6', name: 'File 6', type: 'file', parent: 'subfolder2' }, + * { id: 'folder2', name: 'Folder 2', type: 'folder', parent: null }, + * { id: 'file7', name: 'File 7', type: 'file', parent: 'folder2' }, + * { id: 'file8', name: 'File 8', type: 'file', parent: 'folder2' }, + * { id: 'subfolder3', name: 'Subfolder 3', type: 'folder', parent: 'folder2' }, + * { id: 'file9', name: 'File 9', type: 'file', parent: 'subfolder3' }, + * { id: 'file10', name: 'File 10', type: 'file', parent: 'subfolder3' }, + * ]; + * + * const tree = buildTree(fileSystem, 'id', 'id', 'parent', { rootReferences: [null] }); + * + * console.log(tree.toString()); + * ``` + * + * The buildTree function takes in the array of data objects, as well as some configuration options specifying + * the keys to use for identifying nodes and their parent-child relationships. In this example, we use the id + * key to identify nodes, and the parent key to specify the parent of each node. + * + * The resulting tree object is a nested tree structure, where each node is an object representing a file or + * folder, and has child nodes representing its contents. The toString method of the tree object + * can be used to print out the tree in a readable format: + * + * ```markdown + * - Folder 1 + * - File 1 + * - File 2 + * - Subfolder 1 + * - File 3 + * - File 4 + * - Subfolder 2 + * - File 5 + * - File 6 + * - Folder 2 + * - File 7 + * - File 8 + * - Subfolder 3 + * - File 9 + * - File 10 + * ``` + * + * @memberof Monster.Data + * + * @param {*} subject - The object or array to build the tree from. + * @param {string|Monster.Data~exampleSelectorCallback} selector - Either a string to specify a property of each object to use as a selector, or a selector function to generate a map of objects. + * @param {string} idKey - The property key to use as the unique ID of each node. + * @param {string} parentIDKey - The property key to use as the parent ID of each node. + * @param {object} [options] - Additional options to modify the function behavior. + * @param {Array<*>} [options.rootReferences=[null, undefined]] - An array of values to treat as root references when creating the tree. + * @param {function} [options.filter] - A filter function to apply to each node. + * + * @return {*} The resulting tree structure as a NodeList. + * + * @throws {TypeError} selector is neither a string nor a function. + * @throws {TypeError} the selector callback must return a map. + * @throws {Error} the object has no value for the specified id. + * + * @license AGPLv3 + * + * @since 1.26.0 + */ +/** + * Constraints are used to define conditions that must be met by the value of a variable. + * + * The uniform API of the constraints allows chains to be formed. + * + * The abstract constraint defines the api for all constraints. mainly the method isValid() is defined. + * + * Derived classes must implement the method isValid(). + * + * @license AGPLv3 + * @since 1.3.0 + * @copyright schukai GmbH + * @memberOf Monster.Constraints + * @summary The abstract constraint + */ +/** + * Constraints are used to define conditions that must be met by the value of a variable. + * + * The uniform API of the constraints allows chains to be formed. + * + * The invalid constraint allows an always invalid query to be performed. this constraint is mainly intended for testing. + * + * @externalExample ../../example/constraints/invalid.mjs + * @license AGPLv3 + * @since 1.3.0 + * @copyright schukai GmbH + * @memberOf Monster.Constraints + * @summary A constraint that always invalid + */ +/** + * Constraints are used to define conditions that must be met by the value of a variable. + * + * The uniform API of the constraints allows chains to be formed. + * + * Operators allow you to link constraints together. for example, you can check whether a value is + * an object or an array. each operator has two operands that are linked together. + * + * @license AGPLv3 + * @since 1.3.0 + * @copyright schukai GmbH + * @memberOf Monster.Constraints + * @summary The abstract operator constraint + */ +/** + * Constraints are used to define conditions that must be met by the value of a variable. + * + * The uniform API of the constraints allows chains to be formed. + * + * The valid constraint allows an always valid query to be performed. this constraint is mainly intended for testing. + * + * @externalExample ../../example/constraints/valid.mjs + * @license AGPLv3 + * @since 1.3.0 + * @copyright schukai GmbH + * @memberOf Monster.Constraints + * @summary A constraint that always valid + */ +/** + * Constraints are used to define conditions that must be met by the value of a variable. + * + * The uniform API of the constraints allows chains to be formed. + * + * The OrOperator is used to link several constraints. The constraint is fulfilled if one of the constraints is fulfilled. + * + * @externalExample ../../example/constraints/oroperator.mjs + * @license AGPLv3 + * @since 1.3.0 + * @copyright schukai GmbH + * @memberOf Monster.Constraints + * @summary A or operator + */ +/** + * Constraints are used to define conditions that must be met by the value of a variable. + * + * The uniform API of the constraints allows chains to be formed. + * + * @externalExample ../../example/constraints/isobject.mjs + * @license AGPLv3 + * @since 1.3.0 + * @copyright schukai GmbH + * @memberOf Monster.Constraints + * @summary A constraint to check if a value is an object + */ +/** + * Constraints are used to define conditions that must be met by the value of a variable. + * + * The uniform API of the constraints allows chains to be formed. + * + * The AndOperator is used to link several constraints. The constraint is fulfilled if all constraints of the operators are fulfilled. + * + * @externalExample ../../example/constraints/andoperator.mjs + * @license AGPLv3 + * @since 1.3.0 + * @copyright schukai GmbH + * @memberOf Monster.Constraints + * @summary A and operator constraint + */ +/** + * Constraints are used to define conditions that must be met by the value of a variable. + * + * The uniform API of the constraints allows chains to be formed. + * + * @externalExample ../../example/constraints/isarray.mjs + * @license AGPLv3 + * @since 1.3.0 + * @copyright schukai GmbH + * @memberOf Monster.Constraints + * @summary A constraint to check if a value is an array + */ +/** + * You can call the function via the monster namespace `Monster.Types.toBinary()`. + * + * @param {String} binary + * @return {String} + * @throws {TypeError} value is not a string + * @memberOf Monster.Types + * @license AGPLv3 + * @since 1.18.0 + */ +/** + * You can call the function via the monster namespace `Monster.Types.fromBinary()`. + * + * @param {String} binary + * @return {String} + * @throws {TypeError} value is not a string + * @memberOf Monster.Types + * @license AGPLv3 + * @since 1.18.0 + */ +/** + * This function prefixes all special characters that may appear in a regex with a slash. + * + * @param {string} value + * @return {string} + * @license AGPLv3 + * @since 1.26.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + * @throws {TypeError} value is not a string + */ +/** + * You can create the instance via the monster namespace `new Monster.Types.NodeRecursiveIterator()`. + * + * @externalExample ../../example/types/noderecursiveiterator.mjs + * @license AGPLv3 + * @since 1.26.0 + * @copyright schukai GmbH + * @memberOf Monster.Types + * @summary An iterator to run recursively through a tree of nodes + */ +/** + * The Formatter extends the Text.Formatter with the possibility to replace the key by a translation. + * + * @externalExample ../../example/i18n/formatter.mjs + * @license AGPLv3 + * @since 1.26.0 + * @copyright schukai GmbH + * @memberOf Monster.I18n + */ +/** + * The fetch provider retrieves a JSON file from the given URL and returns a translation object. + * + * @externalExample ../../../example/i18n/providers/fetch.mjs + * @license AGPLv3 + * @since 1.13.0 + * @copyright schukai GmbH + * @memberOf Monster.I18n.Providers + * @see {@link https://datatracker.ietf.org/doc/html/rfc3066} + * @tutorial i18n-locale-and-formatter + */ +/*! Bundled license information: + +assertion-error/index.js: + (*! + * assertion-error + * Copyright(c) 2013 Jake Luer <jake@qualiancy.com> + * MIT Licensed + *) + (*! + * Return a function that will copy properties from + * one object to another excluding any originally + * listed. Returned function will create a new `{}`. + * + * @param {String} excluded properties ... + * @return {Function} + *) + (*! + * Primary Exports + *) + (*! + * Inherit from Error.prototype + *) + (*! + * Statically set name + *) + (*! + * Ensure correct constructor + *) + +chai/lib/chai/utils/flag.js: + (*! + * Chai - flag utility + * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> + * MIT Licensed + *) + +chai/lib/chai/utils/test.js: + (*! + * Chai - test utility + * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> + * MIT Licensed + *) + (*! + * Module dependencies + *) + +chai/lib/chai/utils/expectTypes.js: + (*! + * Chai - expectTypes utility + * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> + * MIT Licensed + *) + +chai/lib/chai/utils/getActual.js: + (*! + * Chai - getActual utility + * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> + * MIT Licensed + *) + +chai/lib/chai/utils/objDisplay.js: + (*! + * Chai - flag utility + * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> + * MIT Licensed + *) + (*! + * Module dependencies + *) + +chai/lib/chai/utils/getMessage.js: + (*! + * Chai - message composition utility + * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> + * MIT Licensed + *) + (*! + * Module dependencies + *) + +chai/lib/chai/utils/transferFlags.js: + (*! + * Chai - transferFlags utility + * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> + * MIT Licensed + *) + +deep-eql/index.js: + (*! + * deep-eql + * Copyright(c) 2013 Jake Luer <jake@alogicalparadox.com> + * MIT Licensed + *) + (*! + * Check to see if the MemoizeMap has recorded a result of the two operands + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {MemoizeMap} memoizeMap + * @returns {Boolean|null} result + *) + (*! + * Set the result of the equality into the MemoizeMap + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {MemoizeMap} memoizeMap + * @param {Boolean} result + *) + (*! + * Primary Export + *) + (*! + * The main logic of the `deepEqual` function. + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {Object} [options] (optional) Additional options + * @param {Array} [options.comparator] (optional) Override default algorithm, determining custom equality. + * @param {Array} [options.memoize] (optional) Provide a custom memoization object which will cache the results of + complex objects for a speed boost. By passing `false` you can disable memoization, but this will cause circular + references to blow the stack. + * @return {Boolean} equal match + *) + (*! + * Compare two Regular Expressions for equality. + * + * @param {RegExp} leftHandOperand + * @param {RegExp} rightHandOperand + * @return {Boolean} result + *) + (*! + * Compare two Sets/Maps for equality. Faster than other equality functions. + * + * @param {Set} leftHandOperand + * @param {Set} rightHandOperand + * @param {Object} [options] (Optional) + * @return {Boolean} result + *) + (*! + * Simple equality for flat iterable objects such as Arrays, TypedArrays or Node.js buffers. + * + * @param {Iterable} leftHandOperand + * @param {Iterable} rightHandOperand + * @param {Object} [options] (Optional) + * @return {Boolean} result + *) + (*! + * Simple equality for generator objects such as those returned by generator functions. + * + * @param {Iterable} leftHandOperand + * @param {Iterable} rightHandOperand + * @param {Object} [options] (Optional) + * @return {Boolean} result + *) + (*! + * Determine if the given object has an @@iterator function. + * + * @param {Object} target + * @return {Boolean} `true` if the object has an @@iterator function. + *) + (*! + * Gets all iterator entries from the given Object. If the Object has no @@iterator function, returns an empty array. + * This will consume the iterator - which could have side effects depending on the @@iterator implementation. + * + * @param {Object} target + * @returns {Array} an array of entries from the @@iterator function + *) + (*! + * Gets all entries from a Generator. This will consume the generator - which could have side effects. + * + * @param {Generator} target + * @returns {Array} an array of entries from the Generator. + *) + (*! + * Gets all own and inherited enumerable keys from a target. + * + * @param {Object} target + * @returns {Array} an array of own and inherited enumerable keys from the target. + *) + (*! + * Determines if two objects have matching values, given a set of keys. Defers to deepEqual for the equality check of + * each key. If any value of the given key is not equal, the function will return false (early). + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {Array} keys An array of keys to compare the values of leftHandOperand and rightHandOperand against + * @param {Object} [options] (Optional) + * @return {Boolean} result + *) + (*! + * Recursively check the equality of two Objects. Once basic sameness has been established it will defer to `deepEqual` + * for each enumerable key in the object. + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {Object} [options] (Optional) + * @return {Boolean} result + *) + (*! + * Returns true if the argument is a primitive. + * + * This intentionally returns true for all objects that can be compared by reference, + * including functions and symbols. + * + * @param {Mixed} value + * @return {Boolean} result + *) + +chai/lib/chai/utils/isProxyEnabled.js: + (*! + * Chai - isProxyEnabled helper + * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> + * MIT Licensed + *) + +chai/lib/chai/utils/addProperty.js: + (*! + * Chai - addProperty utility + * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> + * MIT Licensed + *) + +chai/lib/chai/utils/addLengthGuard.js: + (*! + * Chai - addLengthGuard utility + * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> + * MIT Licensed + *) + +chai/lib/chai/utils/getProperties.js: + (*! + * Chai - getProperties utility + * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> + * MIT Licensed + *) + +chai/lib/chai/utils/proxify.js: + (*! + * Chai - proxify utility + * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> + * MIT Licensed + *) + +chai/lib/chai/utils/addMethod.js: + (*! + * Chai - addMethod utility + * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> + * MIT Licensed + *) + +chai/lib/chai/utils/overwriteProperty.js: + (*! + * Chai - overwriteProperty utility + * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> + * MIT Licensed + *) + +chai/lib/chai/utils/overwriteMethod.js: + (*! + * Chai - overwriteMethod utility + * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> + * MIT Licensed + *) + +chai/lib/chai/utils/addChainableMethod.js: + (*! + * Chai - addChainingMethod utility + * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> + * MIT Licensed + *) + (*! + * Module dependencies + *) + (*! + * Module variables + *) + +chai/lib/chai/utils/overwriteChainableMethod.js: + (*! + * Chai - overwriteChainableMethod utility + * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> + * MIT Licensed + *) + +chai/lib/chai/utils/compareByInspect.js: + (*! + * Chai - compareByInspect utility + * Copyright(c) 2011-2016 Jake Luer <jake@alogicalparadox.com> + * MIT Licensed + *) + (*! + * Module dependencies + *) + +chai/lib/chai/utils/getOwnEnumerablePropertySymbols.js: + (*! + * Chai - getOwnEnumerablePropertySymbols utility + * Copyright(c) 2011-2016 Jake Luer <jake@alogicalparadox.com> + * MIT Licensed + *) + +chai/lib/chai/utils/getOwnEnumerableProperties.js: + (*! + * Chai - getOwnEnumerableProperties utility + * Copyright(c) 2011-2016 Jake Luer <jake@alogicalparadox.com> + * MIT Licensed + *) + (*! + * Module dependencies + *) + +chai/lib/chai/utils/isNaN.js: + (*! + * Chai - isNaN utility + * Copyright(c) 2012-2015 Sakthipriyan Vairamani <thechargingvolcano@gmail.com> + * MIT Licensed + *) + +chai/lib/chai/utils/index.js: + (*! + * chai + * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com> + * MIT Licensed + *) + (*! + * Dependencies that are used for multiple exports are required here only once + *) + (*! + * test utility + *) + (*! + * type utility + *) + (*! + * expectTypes utility + *) + (*! + * message utility + *) + (*! + * actual utility + *) + (*! + * Inspect util + *) + (*! + * Object Display util + *) + (*! + * Flag utility + *) + (*! + * Flag transferring utility + *) + (*! + * Deep equal utility + *) + (*! + * Deep path info + *) + (*! + * Check if a property exists + *) + (*! + * Function name + *) + (*! + * add Property + *) + (*! + * add Method + *) + (*! + * overwrite Property + *) + (*! + * overwrite Method + *) + (*! + * Add a chainable method + *) + (*! + * Overwrite chainable method + *) + (*! + * Compare by inspect method + *) + (*! + * Get own enumerable property symbols method + *) + (*! + * Get own enumerable properties method + *) + (*! + * Checks error against a given set of criteria + *) + (*! + * Proxify util + *) + (*! + * addLengthGuard util + *) + (*! + * isProxyEnabled helper + *) + (*! + * isNaN method + *) + (*! + * getOperator method + *) + +chai/lib/chai/assertion.js: + (*! + * chai + * http://chaijs.com + * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com> + * MIT Licensed + *) + (*! + * Module dependencies. + *) + (*! + * Module export. + *) + (*! + * Assertion Constructor + * + * Creates object for chaining. + * + * `Assertion` objects contain metadata in the form of flags. Three flags can + * be assigned during instantiation by passing arguments to this constructor: + * + * - `object`: This flag contains the target of the assertion. For example, in + * the assertion `expect(numKittens).to.equal(7);`, the `object` flag will + * contain `numKittens` so that the `equal` assertion can reference it when + * needed. + * + * - `message`: This flag contains an optional custom error message to be + * prepended to the error message that's generated by the assertion when it + * fails. + * + * - `ssfi`: This flag stands for "start stack function indicator". It + * contains a function reference that serves as the starting point for + * removing frames from the stack trace of the error that's created by the + * assertion when it fails. The goal is to provide a cleaner stack trace to + * end users by removing Chai's internal functions. Note that it only works + * in environments that support `Error.captureStackTrace`, and only when + * `Chai.config.includeStack` hasn't been set to `false`. + * + * - `lockSsfi`: This flag controls whether or not the given `ssfi` flag + * should retain its current value, even as assertions are chained off of + * this object. This is usually set to `true` when creating a new assertion + * from within another assertion. It's also temporarily set to `true` before + * an overwritten assertion gets called by the overwriting assertion. + * + * @param {Mixed} obj target of the assertion + * @param {String} msg (optional) custom error message + * @param {Function} ssfi (optional) starting point for removing stack frames + * @param {Boolean} lockSsfi (optional) whether or not the ssfi flag is locked + * @api private + *) + (*! + * ### ._obj + * + * Quick reference to stored `actual` value for plugin developers. + * + * @api private + *) + +chai/lib/chai/core/assertions.js: + (*! + * chai + * http://chaijs.com + * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com> + * MIT Licensed + *) + +chai/lib/chai/interface/expect.js: + (*! + * chai + * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com> + * MIT Licensed + *) + +chai/lib/chai/interface/should.js: + (*! + * chai + * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com> + * MIT Licensed + *) + +chai/lib/chai/interface/assert.js: + (*! + * chai + * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com> + * MIT Licensed + *) + (*! + * Chai dependencies. + *) + (*! + * Module export. + *) + (*! + * ### .ifError(object) + * + * Asserts if value is not a false value, and throws if it is a true value. + * This is added to allow for chai to be a drop-in replacement for Node's + * assert class. + * + * var err = new Error('I am a custom error'); + * assert.ifError(err); // Rethrows err! + * + * @name ifError + * @param {Object} object + * @namespace Assert + * @api public + *) + (*! + * Aliases. + *) + +chai/lib/chai.js: + (*! + * chai + * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com> + * MIT Licensed + *) + (*! + * Chai version + *) + (*! + * Assertion Error + *) + (*! + * Utils for plugins (not exported) + *) + (*! + * Utility Functions + *) + (*! + * Configuration + *) + (*! + * Primary `Assertion` prototype + *) + (*! + * Core Assertions + *) + (*! + * Expect interface + *) + (*! + * Should interface + *) + (*! + * Assert interface + *) + +pvtsutils/build/index.js: + (*! + * MIT License + * + * Copyright (c) 2017-2022 Peculiar Ventures, LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *) + +pvutils/build/utils.es.js: + (*! + Copyright (c) Peculiar Ventures, LLC + *) + +asn1js/build/index.es.js: + (*! + * Copyright (c) 2014, GMO GlobalSign + * Copyright (c) 2015-2022, Peculiar Ventures + * All rights reserved. + * + * Author 2014-2019, Yury Strozhevsky + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *) + +webcrypto-core/build/webcrypto-core.es.js: + (*! + Copyright (c) Peculiar Ventures, LLC + *) + +@peculiar/webcrypto/build/webcrypto.es.js: + (*! + Copyright (c) Peculiar Ventures, LLC + *) +*/ +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2Fzc2VydGlvbi1lcnJvckAxLjEuMC9ub2RlX21vZHVsZXMvYXNzZXJ0aW9uLWVycm9yL2luZGV4LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9wYXRodmFsQDEuMS4xL25vZGVfbW9kdWxlcy9wYXRodmFsL2luZGV4LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9jaGFpQDQuMy43L25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL3V0aWxzL2ZsYWcuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2NoYWlANC4zLjcvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvdGVzdC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vdHlwZS1kZXRlY3RANC4wLjgvbm9kZV9tb2R1bGVzL3R5cGUtZGV0ZWN0L3R5cGUtZGV0ZWN0LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9jaGFpQDQuMy43L25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL3V0aWxzL2V4cGVjdFR5cGVzLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9jaGFpQDQuMy43L25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL3V0aWxzL2dldEFjdHVhbC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vZ2V0LWZ1bmMtbmFtZUAyLjAuMi9ub2RlX21vZHVsZXMvZ2V0LWZ1bmMtbmFtZS9pbmRleC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vbG91cGVAMi4zLjcvbm9kZV9tb2R1bGVzL2xvdXBlL2xvdXBlLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9jaGFpQDQuMy43L25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL2NvbmZpZy5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vY2hhaUA0LjMuNy9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy9pbnNwZWN0LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9jaGFpQDQuMy43L25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL3V0aWxzL29iakRpc3BsYXkuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2NoYWlANC4zLjcvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvZ2V0TWVzc2FnZS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vY2hhaUA0LjMuNy9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy90cmFuc2ZlckZsYWdzLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9kZWVwLWVxbEA0LjEuMy9ub2RlX21vZHVsZXMvZGVlcC1lcWwvaW5kZXguanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2NoYWlANC4zLjcvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvaXNQcm94eUVuYWJsZWQuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2NoYWlANC4zLjcvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvYWRkUHJvcGVydHkuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2NoYWlANC4zLjcvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvYWRkTGVuZ3RoR3VhcmQuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2NoYWlANC4zLjcvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvZ2V0UHJvcGVydGllcy5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vY2hhaUA0LjMuNy9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy9wcm94aWZ5LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9jaGFpQDQuMy43L25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL3V0aWxzL2FkZE1ldGhvZC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vY2hhaUA0LjMuNy9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy9vdmVyd3JpdGVQcm9wZXJ0eS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vY2hhaUA0LjMuNy9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy9vdmVyd3JpdGVNZXRob2QuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2NoYWlANC4zLjcvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvYWRkQ2hhaW5hYmxlTWV0aG9kLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9jaGFpQDQuMy43L25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL3V0aWxzL292ZXJ3cml0ZUNoYWluYWJsZU1ldGhvZC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vY2hhaUA0LjMuNy9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy9jb21wYXJlQnlJbnNwZWN0LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9jaGFpQDQuMy43L25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL3V0aWxzL2dldE93bkVudW1lcmFibGVQcm9wZXJ0eVN5bWJvbHMuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2NoYWlANC4zLjcvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvZ2V0T3duRW51bWVyYWJsZVByb3BlcnRpZXMuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2NoZWNrLWVycm9yQDEuMC4zL25vZGVfbW9kdWxlcy9jaGVjay1lcnJvci9pbmRleC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vY2hhaUA0LjMuNy9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy9pc05hTi5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vY2hhaUA0LjMuNy9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy9nZXRPcGVyYXRvci5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vY2hhaUA0LjMuNy9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy9pbmRleC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vY2hhaUA0LjMuNy9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS9hc3NlcnRpb24uanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2NoYWlANC4zLjcvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvY29yZS9hc3NlcnRpb25zLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9jaGFpQDQuMy43L25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL2ludGVyZmFjZS9leHBlY3QuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2NoYWlANC4zLjcvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvaW50ZXJmYWNlL3Nob3VsZC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vY2hhaUA0LjMuNy9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS9pbnRlcmZhY2UvYXNzZXJ0LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9jaGFpQDQuMy43L25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9jaGFpQDQuMy43L25vZGVfbW9kdWxlcy9jaGFpL2luZGV4LmpzIiwgIi4uLy4uL3NvdXJjZS9jb25zdGFudHMubWpzIiwgIi4uLy4uL3NvdXJjZS90eXBlcy9pcy5tanMiLCAiLi4vLi4vc291cmNlL3R5cGVzL3R5cGVvZi5tanMiLCAiLi4vLi4vc291cmNlL2RhdGEvZXh0ZW5kLm1qcyIsICIuLi8uLi9zb3VyY2UvdHlwZXMvYmFzZS5tanMiLCAiLi4vLi4vc291cmNlL3R5cGVzL3ZhbGlkYXRlLm1qcyIsICIuLi8uLi9zb3VyY2UvdHlwZXMvZ2xvYmFsLm1qcyIsICIuLi8uLi9zb3VyY2UvdXRpbC9jbG9uZS5tanMiLCAiLi4vLi4vc291cmNlL2kxOG4vbG9jYWxlLm1qcyIsICIuLi8uLi9zb3VyY2UvZG9tL3V0aWwubWpzIiwgIi4uLy4uL3NvdXJjZS9kb20vbG9jYWxlLm1qcyIsICIuLi8uLi9zb3VyY2UvdHlwZXMvaWQubWpzIiwgIi4uLy4uL3NvdXJjZS90eXBlcy90b2tlbmxpc3QubWpzIiwgIi4uLy4uL3NvdXJjZS9kb20vY29uc3RhbnRzLm1qcyIsICIuLi8uLi9zb3VyY2UvZG9tL2F0dHJpYnV0ZXMubWpzIiwgIi4uLy4uL3NvdXJjZS90eXBlcy9zdGFjay5tanMiLCAiLi4vLi4vc291cmNlL2RhdGEvcGF0aGZpbmRlci5tanMiLCAiLi4vLi4vc291cmNlL3R5cGVzL2Jhc2V3aXRob3B0aW9ucy5tanMiLCAiLi4vLi4vc291cmNlL2kxOG4vcHJvdmlkZXIubWpzIiwgIi4uLy4uL3NvdXJjZS9pMThuL3RyYW5zbGF0aW9ucy5tanMiLCAiLi4vLi4vc291cmNlL2RhdGEvdHJhbnNmb3JtZXIubWpzIiwgIi4uLy4uL3NvdXJjZS9kYXRhL3BpcGUubWpzIiwgIi4uLy4uL3NvdXJjZS90ZXh0L2Zvcm1hdHRlci5tanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3B2dHN1dGlsc0AxLjMuNS9ub2RlX21vZHVsZXMvcHZ0c3V0aWxzL2J1aWxkL2luZGV4LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9wdnV0aWxzQDEuMS4zL25vZGVfbW9kdWxlcy9wdnV0aWxzL2J1aWxkL3V0aWxzLmVzLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9hc24xanNAMy4wLjUvbm9kZV9tb2R1bGVzL2FzbjFqcy9idWlsZC9pbmRleC5lcy5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHBlY3VsaWFyK2FzbjEtc2NoZW1hQDIuMy44L25vZGVfbW9kdWxlcy9AcGVjdWxpYXIvYXNuMS1zY2hlbWEvYnVpbGQvZXMyMDE1L2VudW1zLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AcGVjdWxpYXIrYXNuMS1zY2hlbWFAMi4zLjgvbm9kZV9tb2R1bGVzL0BwZWN1bGlhci9hc24xLXNjaGVtYS9idWlsZC9lczIwMTUvdHlwZXMvYml0X3N0cmluZy5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHBlY3VsaWFyK2FzbjEtc2NoZW1hQDIuMy44L25vZGVfbW9kdWxlcy9AcGVjdWxpYXIvYXNuMS1zY2hlbWEvYnVpbGQvZXMyMDE1L3R5cGVzL29jdGV0X3N0cmluZy5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHBlY3VsaWFyK2FzbjEtc2NoZW1hQDIuMy44L25vZGVfbW9kdWxlcy9AcGVjdWxpYXIvYXNuMS1zY2hlbWEvYnVpbGQvZXMyMDE1L3R5cGVzL2luZGV4LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AcGVjdWxpYXIrYXNuMS1zY2hlbWFAMi4zLjgvbm9kZV9tb2R1bGVzL0BwZWN1bGlhci9hc24xLXNjaGVtYS9idWlsZC9lczIwMTUvY29udmVydGVycy5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHBlY3VsaWFyK2FzbjEtc2NoZW1hQDIuMy44L25vZGVfbW9kdWxlcy9AcGVjdWxpYXIvYXNuMS1zY2hlbWEvYnVpbGQvZXMyMDE1L2hlbHBlci5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHBlY3VsaWFyK2FzbjEtc2NoZW1hQDIuMy44L25vZGVfbW9kdWxlcy9AcGVjdWxpYXIvYXNuMS1zY2hlbWEvYnVpbGQvZXMyMDE1L3NjaGVtYS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHBlY3VsaWFyK2FzbjEtc2NoZW1hQDIuMy44L25vZGVfbW9kdWxlcy9AcGVjdWxpYXIvYXNuMS1zY2hlbWEvYnVpbGQvZXMyMDE1L3N0b3JhZ2UuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BwZWN1bGlhcithc24xLXNjaGVtYUAyLjMuOC9ub2RlX21vZHVsZXMvQHBlY3VsaWFyL2FzbjEtc2NoZW1hL2J1aWxkL2VzMjAxNS9kZWNvcmF0b3JzLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AcGVjdWxpYXIrYXNuMS1zY2hlbWFAMi4zLjgvbm9kZV9tb2R1bGVzL0BwZWN1bGlhci9hc24xLXNjaGVtYS9idWlsZC9lczIwMTUvZXJyb3JzL3NjaGVtYV92YWxpZGF0aW9uLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AcGVjdWxpYXIrYXNuMS1zY2hlbWFAMi4zLjgvbm9kZV9tb2R1bGVzL0BwZWN1bGlhci9hc24xLXNjaGVtYS9idWlsZC9lczIwMTUvZXJyb3JzL2luZGV4LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AcGVjdWxpYXIrYXNuMS1zY2hlbWFAMi4zLjgvbm9kZV9tb2R1bGVzL0BwZWN1bGlhci9hc24xLXNjaGVtYS9idWlsZC9lczIwMTUvcGFyc2VyLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AcGVjdWxpYXIrYXNuMS1zY2hlbWFAMi4zLjgvbm9kZV9tb2R1bGVzL0BwZWN1bGlhci9hc24xLXNjaGVtYS9idWlsZC9lczIwMTUvc2VyaWFsaXplci5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHBlY3VsaWFyK2FzbjEtc2NoZW1hQDIuMy44L25vZGVfbW9kdWxlcy9AcGVjdWxpYXIvYXNuMS1zY2hlbWEvYnVpbGQvZXMyMDE1L29iamVjdHMuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BwZWN1bGlhcithc24xLXNjaGVtYUAyLjMuOC9ub2RlX21vZHVsZXMvQHBlY3VsaWFyL2FzbjEtc2NoZW1hL2J1aWxkL2VzMjAxNS9jb252ZXJ0LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AcGVjdWxpYXIrYXNuMS1zY2hlbWFAMi4zLjgvbm9kZV9tb2R1bGVzL0BwZWN1bGlhci9hc24xLXNjaGVtYS9idWlsZC9lczIwMTUvaW5kZXguanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3RzbGliQDIuNi4yL25vZGVfbW9kdWxlcy90c2xpYi90c2xpYi5lczYubWpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AcGVjdWxpYXIranNvbi1zY2hlbWFAMS4xLjEyL25vZGVfbW9kdWxlcy9AcGVjdWxpYXIvanNvbi1zY2hlbWEvYnVpbGQvaW5kZXguZXMuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3dlYmNyeXB0by1jb3JlQDEuNy43L25vZGVfbW9kdWxlcy93ZWJjcnlwdG8tY29yZS9idWlsZC93ZWJjcnlwdG8tY29yZS5lcy5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHBlY3VsaWFyK3dlYmNyeXB0b0AxLjQuMy9ub2RlX21vZHVsZXMvQHBlY3VsaWFyL3dlYmNyeXB0by9idWlsZC93ZWJjcnlwdG8uZXMuanMiLCAiLi4vLi4vc291cmNlL21hdGgvcmFuZG9tLm1qcyIsICIuLi8uLi9zb3VyY2UvdXRpbC90cmltc3BhY2VzLm1qcyIsICIuLi8uLi9zb3VyY2UvdHlwZXMvcXVldWUubWpzIiwgIi4uLy4uL3NvdXJjZS90eXBlcy91bmlxdWVxdWV1ZS5tanMiLCAiLi4vLi4vc291cmNlL3R5cGVzL29ic2VydmVyLm1qcyIsICIuLi8uLi9zb3VyY2UvdHlwZXMvb2JzZXJ2ZXJsaXN0Lm1qcyIsICIuLi8uLi9zb3VyY2UvdHlwZXMvcHJveHlvYnNlcnZlci5tanMiLCAiLi4vLi4vc291cmNlL2RvbS9yZXNvdXJjZS5tanMiLCAiLi4vLi4vc291cmNlL3R5cGVzL21lZGlhdHlwZS5tanMiLCAiLi4vLi4vc291cmNlL3R5cGVzL2RhdGF1cmwubWpzIiwgIi4uLy4uL3NvdXJjZS9kb20vdGhlbWUubWpzIiwgIi4uLy4uL3NvdXJjZS9kb20vdGVtcGxhdGUubWpzIiwgIi4uLy4uL3NvdXJjZS9kYXRhL2RpZmYubWpzIiwgIi4uLy4uL3NvdXJjZS9kb20vZXZlbnRzLm1qcyIsICIuLi8uLi9zb3VyY2UvZG9tL3VwZGF0ZXIubWpzIiwgIi4uLy4uL3NvdXJjZS9kb20vc2xvdHRlZC5tanMiLCAiLi4vLi4vc291cmNlL2RvbS91dGlsL2V4dHJhY3Qta2V5cy5tanMiLCAiLi4vLi4vc291cmNlL2RvbS91dGlsL3NldC1vcHRpb24tZnJvbS1hdHRyaWJ1dGUubWpzIiwgIi4uLy4uL3NvdXJjZS9kb20vY3VzdG9tZWxlbWVudC5tanMiLCAiLi4vLi4vc291cmNlL2RvbS91dGlsL2luaXQtb3B0aW9ucy1mcm9tLWF0dHJpYnV0ZXMubWpzIiwgIi4uLy4uL3NvdXJjZS9kb20vcmVhZHkubWpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9lbGVtZW50LWludGVybmFscy1wb2x5ZmlsbEAxLjMuNS9ub2RlX21vZHVsZXMvZWxlbWVudC1pbnRlcm5hbHMtcG9seWZpbGwvZGlzdC9pbmRleC5qcyIsICIuLi8uLi9zb3VyY2UvZG9tL2N1c3RvbWNvbnRyb2wubWpzIiwgIi4uLy4uL3NvdXJjZS90eXBlcy9yYW5kb21pZC5tanMiLCAiLi4vLi4vc291cmNlL3R5cGVzL3V1aWQubWpzIiwgInByZXBhcmUuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2NoYWlANC4zLjcvbm9kZV9tb2R1bGVzL2NoYWkvaW5kZXgubWpzIiwgIi4uL2Nhc2VzL3RleHQvZm9ybWF0dGVyLm1qcyIsICIuLi8uLi9zb3VyY2UvdGV4dC9nZW5lcmF0ZS1yYW5nZS1jb21wYXJpc29uLWV4cHJlc3Npb24ubWpzIiwgIi4uL2Nhc2VzL3RleHQvdXRpbC5tanMiLCAiLi4vLi4vc291cmNlL3RleHQvYnJhY2tldGVkLWtleS12YWx1ZS1oYXNoLm1qcyIsICIuLi9jYXNlcy90ZXh0L2JyYWNrZXRlZC1rZXktdmFsdWUtaGFzaC5tanMiLCAiLi4vY2FzZXMvbWF0aC9yYW5kb20ubWpzIiwgIi4uL2Nhc2VzL3V0aWwvdHJpbXNwYWNlcy5tanMiLCAiLi4vLi4vc291cmNlL3V0aWwvcHJvY2Vzc2luZy5tanMiLCAiLi4vY2FzZXMvdXRpbC9wcm9jZXNzaW5nLm1qcyIsICIuLi8uLi9zb3VyY2UvdXRpbC9kZWFkbWFuc3N3aXRjaC5tanMiLCAiLi4vY2FzZXMvdXRpbC9kZWFkbWFuc3N3aXRjaC5tanMiLCAiLi4vLi4vc291cmNlL3V0aWwvY29tcGFyYXRvci5tanMiLCAiLi4vY2FzZXMvdXRpbC9jb21wYXJhdG9yLm1qcyIsICIuLi8uLi9zb3VyY2UvdXRpbC9mcmVlemUubWpzIiwgIi4uL2Nhc2VzL3V0aWwvZnJlZXplLm1qcyIsICIuLi9jYXNlcy91dGlsL2Nsb25lLm1qcyIsICIuLi8uLi9zb3VyY2UvbG9nZ2luZy9oYW5kbGVyL2NvbnNvbGUubWpzIiwgIi4uLy4uL3NvdXJjZS9sb2dnaW5nL2hhbmRsZXIubWpzIiwgIi4uLy4uL3NvdXJjZS9sb2dnaW5nL2xvZ2VudHJ5Lm1qcyIsICIuLi8uLi9zb3VyY2UvbG9nZ2luZy9sb2dnZXIubWpzIiwgIi4uL2Nhc2VzL2xvZ2dpbmcvaGFuZGxlci9jb25zb2xlLm1qcyIsICIuLi9jYXNlcy9sb2dnaW5nL2xvZ2dlci5tanMiLCAiLi4vY2FzZXMvbG9nZ2luZy9oYW5kbGVyLm1qcyIsICIuLi9jYXNlcy9sb2dnaW5nL2xvZ2VudHJ5Lm1qcyIsICIuLi8uLi9zb3VyY2UvbmV0L3dlYmNvbm5lY3QubWpzIiwgIi4uLy4uL3NvdXJjZS90eXBlcy9vYnNlcnZhYmxlcXVldWUubWpzIiwgIi4uLy4uL3NvdXJjZS9uZXQvd2ViY29ubmVjdC9tZXNzYWdlLm1qcyIsICIuLi9jYXNlcy9uZXQvd2ViY29ubmVjdC5tanMiLCAiLi4vdXRpbC93ZWJzb2NrZXQubWpzIiwgIi4uL2Nhc2VzL25ldC93ZWJjb25uZWN0L21lc3NhZ2UubWpzIiwgIi4uLy4uL3NvdXJjZS90eXBlcy92ZXJzaW9uLm1qcyIsICIuLi9jYXNlcy9tb25zdGVyLm1qcyIsICIuLi8uLi9zb3VyY2UvZG9tL2RpbWVuc2lvbi5tanMiLCAiLi4vY2FzZXMvZG9tL2RpbWVuc2lvbi5tanMiLCAiLi4vdXRpbC9qc2RvbS5tanMiLCAiLi4vLi4vc291cmNlL3V0aWwvcnVudGltZS5tanMiLCAiLi4vLi4vc291cmNlL2RvbS9yZXNvdXJjZS9saW5rL3N0eWxlc2hlZXQubWpzIiwgIi4uLy4uL3NvdXJjZS9kb20vcmVzb3VyY2UvbGluay5tanMiLCAiLi4vY2FzZXMvZG9tL3Jlc291cmNlL2xpbmsvc3R5bGVzaGVldC5tanMiLCAiLi4vdXRpbC9jaGFpLWRvbS5tanMiLCAiLi4vdXRpbC9jbGVhbnVwZG9tLm1qcyIsICIuLi9jYXNlcy9kb20vcmVzb3VyY2UvbGluay5tanMiLCAiLi4vLi4vc291cmNlL2RvbS9yZXNvdXJjZS9zY3JpcHQubWpzIiwgIi4uL2Nhc2VzL2RvbS9yZXNvdXJjZS9zY3JpcHQubWpzIiwgIi4uLy4uL3NvdXJjZS9kb20vcmVzb3VyY2UvZGF0YS5tanMiLCAiLi4vY2FzZXMvZG9tL3Jlc291cmNlL2RhdGEubWpzIiwgIi4uL2Nhc2VzL2RvbS91dGlsL2luaXQtb3B0aW9ucy1mcm9tLWF0dHJpYnV0ZXMubWpzIiwgIi4uL2Nhc2VzL2RvbS91dGlsL2V4dHJhY3Qta2V5cy5tanMiLCAiLi4vLi4vc291cmNlL2RvbS93b3JrZXIvZmFjdG9yeS5tanMiLCAiLi4vY2FzZXMvZG9tL3dvcmtlci9mYWN0b3J5Lm1qcyIsICIuLi9jYXNlcy9kb20vdXBkYXRlci5tanMiLCAiLi4vY2FzZXMvZG9tL2xvY2FsZS5tanMiLCAiLi4vY2FzZXMvZG9tL3RoZW1lLm1qcyIsICIuLi9jYXNlcy9kb20vY3VzdG9tZWxlbWVudC5tanMiLCAiLi4vLi4vc291cmNlL2RvbS9mb2N1c21hbmFnZXIubWpzIiwgIi4uL2Nhc2VzL2RvbS9mb2N1c21hbmFnZXIubWpzIiwgIi4uL2Nhc2VzL2RvbS9maW5kLm1qcyIsICIuLi9jYXNlcy9kb20vcmVhZHkubWpzIiwgIi4uL2Nhc2VzL2RvbS91dGlsLm1qcyIsICIuLi9jYXNlcy9kb20vY3VzdG9tZWxlbWVudC1pbml0ZnJvbXNjcmlwdGhvc3QubWpzIiwgIi4uL2Nhc2VzL2RvbS9zbG90dGVkLW5vZGVzLm1qcyIsICIuLi9jYXNlcy9kb20vYXR0cmlidXRlcy5tanMiLCAiLi4vY2FzZXMvZG9tL3Jlc291cmNlLm1qcyIsICIuLi8uLi9zb3VyY2UvZG9tL3Jlc291cmNlbWFuYWdlci5tanMiLCAiLi4vLi4vc291cmNlL3R5cGVzL2ludGVybmFsLm1qcyIsICIuLi9jYXNlcy9kb20vcmVzb3VyY2VtYW5hZ2VyLm1qcyIsICIuLi8uLi9zb3VyY2UvZG9tL2Fzc2VtYmxlci5tanMiLCAiLi4vY2FzZXMvZG9tL2Fzc2VtYmxlci5tanMiLCAiLi4vY2FzZXMvZG9tL2N1c3RvbWNvbnRyb2wubWpzIiwgIi4uL2Nhc2VzL2RvbS90ZW1wbGF0ZS5tanMiLCAiLi4vY2FzZXMvZG9tL2V2ZW50cy5tanMiLCAiLi4vLi4vc291cmNlL2RhdGEvZGF0YXNvdXJjZS9kb20ubWpzIiwgIi4uLy4uL3NvdXJjZS9kYXRhL2RhdGFzb3VyY2UubWpzIiwgIi4uL2Nhc2VzL2RhdGEvZGF0YXNvdXJjZS9kb20ubWpzIiwgIi4uLy4uL3NvdXJjZS9kYXRhL2RhdGFzb3VyY2Uvc3RvcmFnZS9sb2NhbHN0b3JhZ2UubWpzIiwgIi4uLy4uL3NvdXJjZS9kYXRhL2RhdGFzb3VyY2Uvc3RvcmFnZS5tanMiLCAiLi4vdXRpbC9sb2NhbHN0b3JhZ2UubWpzIiwgIi4uL2Nhc2VzL2RhdGEvZGF0YXNvdXJjZS9zdG9yYWdlL2xvY2Fsc3RvcmFnZS5tanMiLCAiLi4vLi4vc291cmNlL2RhdGEvZGF0YXNvdXJjZS9zdG9yYWdlL3Nlc3Npb25zdG9yYWdlLm1qcyIsICIuLi9jYXNlcy9kYXRhL2RhdGFzb3VyY2Uvc3RvcmFnZS9zZXNzaW9uc3RvcmFnZS5tanMiLCAiLi4vLi4vc291cmNlL2RhdGEvZGF0YXNvdXJjZS9zZXJ2ZXIubWpzIiwgIi4uL2Nhc2VzL2RhdGEvZGF0YXNvdXJjZS9zZXJ2ZXIubWpzIiwgIi4uLy4uL3NvdXJjZS9kYXRhL2RhdGFzb3VyY2Uvc2VydmVyL3dlYmNvbm5lY3QubWpzIiwgIi4uL2Nhc2VzL2RhdGEvZGF0YXNvdXJjZS9zZXJ2ZXIvd2Vic29ja2V0Lm1qcyIsICIuLi8uLi9zb3VyY2UvZGF0YS9kYXRhc291cmNlL3NlcnZlci9yZXN0YXBpLm1qcyIsICIuLi8uLi9zb3VyY2UvZGF0YS9kYXRhc291cmNlL3NlcnZlci9yZXN0YXBpL3dyaXRlZXJyb3IubWpzIiwgIi4uLy4uL3NvdXJjZS9kYXRhL2RhdGFzb3VyY2Uvc2VydmVyL3Jlc3RhcGkvZGF0YS1mZXRjaC1lcnJvci5tanMiLCAiLi4vY2FzZXMvZGF0YS9kYXRhc291cmNlL3NlcnZlci9yZXN0YXBpLm1qcyIsICIuLi9jYXNlcy9kYXRhL2RhdGFzb3VyY2UubWpzIiwgIi4uLy4uL3NvdXJjZS9kYXRhL2J1aWxkbWFwLm1qcyIsICIuLi9jYXNlcy9kYXRhL2J1aWxkbWFwLm1qcyIsICIuLi9jYXNlcy9kYXRhL3RyYW5zZm9ybWVyLm1qcyIsICIuLi8uLi9zb3VyY2UvaTE4bi9wcm92aWRlcnMvZW1iZWQubWpzIiwgIi4uL2Nhc2VzL2RhdGEvZGlmZi5tanMiLCAiLi4vLi4vc291cmNlL2RhdGEvYnVpbGR0cmVlLm1qcyIsICIuLi8uLi9zb3VyY2UvdHlwZXMvbm9kZS5tanMiLCAiLi4vLi4vc291cmNlL3R5cGVzL25vZGVsaXN0Lm1qcyIsICIuLi9jYXNlcy9kYXRhL2J1aWxkdHJlZS5tanMiLCAiLi4vY2FzZXMvZGF0YS9wYXRoZmluZGVyLm1qcyIsICIuLi9jYXNlcy9kYXRhL3BpcGUubWpzIiwgIi4uL2Nhc2VzL2RhdGEvZXh0ZW5kLm1qcyIsICIuLi8uLi9zb3VyY2UvY29uc3RyYWludHMvYWJzdHJhY3QubWpzIiwgIi4uLy4uL3NvdXJjZS9jb25zdHJhaW50cy9pbnZhbGlkLm1qcyIsICIuLi9jYXNlcy9jb25zdHJhaW50L2ludmFsaWQubWpzIiwgIi4uL2Nhc2VzL2NvbnN0cmFpbnQvYWJzdHJhY3RvcGVyYXRvci5tanMiLCAiLi4vLi4vc291cmNlL2NvbnN0cmFpbnRzL2Fic3RyYWN0b3BlcmF0b3IubWpzIiwgIi4uLy4uL3NvdXJjZS9jb25zdHJhaW50cy92YWxpZC5tanMiLCAiLi4vLi4vc291cmNlL2NvbnN0cmFpbnRzL29yb3BlcmF0b3IubWpzIiwgIi4uL2Nhc2VzL2NvbnN0cmFpbnQvb3JvcGVyYXRvci5tanMiLCAiLi4vLi4vc291cmNlL2NvbnN0cmFpbnRzL2lzb2JqZWN0Lm1qcyIsICIuLi9jYXNlcy9jb25zdHJhaW50L2lzb2JqZWN0Lm1qcyIsICIuLi8uLi9zb3VyY2UvY29uc3RyYWludHMvYW5kb3BlcmF0b3IubWpzIiwgIi4uL2Nhc2VzL2NvbnN0cmFpbnQvYW5kb3BlcmF0b3IubWpzIiwgIi4uLy4uL3NvdXJjZS9jb25zdHJhaW50cy9pc2FycmF5Lm1qcyIsICIuLi9jYXNlcy9jb25zdHJhaW50L2lzYXJyYXkubWpzIiwgIi4uL2Nhc2VzL2NvbnN0cmFpbnQvdmFsaWQubWpzIiwgIi4uL2Nhc2VzL3R5cGVzL25vZGVsaXN0Lm1qcyIsICIuLi9jYXNlcy90eXBlcy9iYXNlLm1qcyIsICIuLi9jYXNlcy90eXBlcy9tZWRpYXR5cGUubWpzIiwgIi4uL2Nhc2VzL3R5cGVzL3Rva2VubGlzdC5tanMiLCAiLi4vY2FzZXMvdHlwZXMvcHJveHlvYnNlcnZlci5tanMiLCAiLi4vY2FzZXMvdHlwZXMvdmVyc2lvbi5tanMiLCAiLi4vY2FzZXMvdHlwZXMvZ2xvYmFsLm1qcyIsICIuLi9jYXNlcy90eXBlcy9vYnNlcnZlcmxpc3QubWpzIiwgIi4uL2Nhc2VzL3R5cGVzL2ludGVybmFsLm1qcyIsICIuLi9jYXNlcy90eXBlcy9vYnNlcnZhYmxlcXVldWUubWpzIiwgIi4uL2Nhc2VzL3R5cGVzL2RhdGF1cmwubWpzIiwgIi4uLy4uL3NvdXJjZS90eXBlcy9iaW5hcnkubWpzIiwgIi4uL2Nhc2VzL3R5cGVzL2JpbmFyeS5tanMiLCAiLi4vY2FzZXMvdHlwZXMvb2JzZXJ2ZXIubWpzIiwgIi4uLy4uL3NvdXJjZS90eXBlcy9yZWdleC5tanMiLCAiLi4vY2FzZXMvdHlwZXMvcmVnZXgubWpzIiwgIi4uL2Nhc2VzL3R5cGVzL3JhbmRvbWlkLm1qcyIsICIuLi9jYXNlcy90eXBlcy9pZC5tanMiLCAiLi4vY2FzZXMvdHlwZXMvdXVpZC5tanMiLCAiLi4vY2FzZXMvdHlwZXMvaXMubWpzIiwgIi4uL2Nhc2VzL3R5cGVzL3ZhbGlkYXRlLm1qcyIsICIuLi9jYXNlcy90eXBlcy90eXBlb2YubWpzIiwgIi4uL2Nhc2VzL3R5cGVzL3VuaXF1ZXF1ZXVlLm1qcyIsICIuLi9jYXNlcy90eXBlcy9zdGFjay5tanMiLCAiLi4vY2FzZXMvdHlwZXMvYmFzZXdpdGhvcHRpb25zLm1qcyIsICIuLi8uLi9zb3VyY2UvdHlwZXMvbm9kZXJlY3Vyc2l2ZWl0ZXJhdG9yLm1qcyIsICIuLi9jYXNlcy90eXBlcy9ub2RlLm1qcyIsICIuLi9jYXNlcy90eXBlcy9xdWV1ZS5tanMiLCAiLi4vY2FzZXMvdHlwZXMvbm9kZXJlY3Vyc2l2ZWl0ZXJhdG9yLm1qcyIsICIuLi8uLi9zb3VyY2UvaTE4bi9mb3JtYXR0ZXIubWpzIiwgIi4uL2Nhc2VzL2kxOG4vZm9ybWF0dGVyLm1qcyIsICIuLi9jYXNlcy9pMThuL2xvY2FsZS5tanMiLCAiLi4vY2FzZXMvaTE4bi9wcm92aWRlci5tanMiLCAiLi4vLi4vc291cmNlL2kxOG4vcHJvdmlkZXJzL2ZldGNoLm1qcyIsICIuLi9jYXNlcy9pMThuL3Byb3ZpZGVycy9mZXRjaC5tanMiLCAiLi4vY2FzZXMvaTE4bi9wcm92aWRlcnMvZW1iZWQubWpzIiwgIi4uL2Nhc2VzL2kxOG4vdHJhbnNsYXRpb25zLm1qcyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyohXG4gKiBhc3NlcnRpb24tZXJyb3JcbiAqIENvcHlyaWdodChjKSAyMDEzIEpha2UgTHVlciA8amFrZUBxdWFsaWFuY3kuY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyohXG4gKiBSZXR1cm4gYSBmdW5jdGlvbiB0aGF0IHdpbGwgY29weSBwcm9wZXJ0aWVzIGZyb21cbiAqIG9uZSBvYmplY3QgdG8gYW5vdGhlciBleGNsdWRpbmcgYW55IG9yaWdpbmFsbHlcbiAqIGxpc3RlZC4gUmV0dXJuZWQgZnVuY3Rpb24gd2lsbCBjcmVhdGUgYSBuZXcgYHt9YC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXhjbHVkZWQgcHJvcGVydGllcyAuLi5cbiAqIEByZXR1cm4ge0Z1bmN0aW9ufVxuICovXG5cbmZ1bmN0aW9uIGV4Y2x1ZGUgKCkge1xuICB2YXIgZXhjbHVkZXMgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG5cbiAgZnVuY3Rpb24gZXhjbHVkZVByb3BzIChyZXMsIG9iaikge1xuICAgIE9iamVjdC5rZXlzKG9iaikuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICBpZiAoIX5leGNsdWRlcy5pbmRleE9mKGtleSkpIHJlc1trZXldID0gb2JqW2tleV07XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gZnVuY3Rpb24gZXh0ZW5kRXhjbHVkZSAoKSB7XG4gICAgdmFyIGFyZ3MgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cylcbiAgICAgICwgaSA9IDBcbiAgICAgICwgcmVzID0ge307XG5cbiAgICBmb3IgKDsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHtcbiAgICAgIGV4Y2x1ZGVQcm9wcyhyZXMsIGFyZ3NbaV0pO1xuICAgIH1cblxuICAgIHJldHVybiByZXM7XG4gIH07XG59O1xuXG4vKiFcbiAqIFByaW1hcnkgRXhwb3J0c1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gQXNzZXJ0aW9uRXJyb3I7XG5cbi8qKlxuICogIyMjIEFzc2VydGlvbkVycm9yXG4gKlxuICogQW4gZXh0ZW5zaW9uIG9mIHRoZSBKYXZhU2NyaXB0IGBFcnJvcmAgY29uc3RydWN0b3IgZm9yXG4gKiBhc3NlcnRpb24gYW5kIHZhbGlkYXRpb24gc2NlbmFyaW9zLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gKiBAcGFyYW0ge09iamVjdH0gcHJvcGVydGllcyB0byBpbmNsdWRlIChvcHRpb25hbClcbiAqIEBwYXJhbSB7Y2FsbGVlfSBzdGFydCBzdGFjayBmdW5jdGlvbiAob3B0aW9uYWwpXG4gKi9cblxuZnVuY3Rpb24gQXNzZXJ0aW9uRXJyb3IgKG1lc3NhZ2UsIF9wcm9wcywgc3NmKSB7XG4gIHZhciBleHRlbmQgPSBleGNsdWRlKCduYW1lJywgJ21lc3NhZ2UnLCAnc3RhY2snLCAnY29uc3RydWN0b3InLCAndG9KU09OJylcbiAgICAsIHByb3BzID0gZXh0ZW5kKF9wcm9wcyB8fCB7fSk7XG5cbiAgLy8gZGVmYXVsdCB2YWx1ZXNcbiAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZSB8fCAnVW5zcGVjaWZpZWQgQXNzZXJ0aW9uRXJyb3InO1xuICB0aGlzLnNob3dEaWZmID0gZmFsc2U7XG5cbiAgLy8gY29weSBmcm9tIHByb3BlcnRpZXNcbiAgZm9yICh2YXIga2V5IGluIHByb3BzKSB7XG4gICAgdGhpc1trZXldID0gcHJvcHNba2V5XTtcbiAgfVxuXG4gIC8vIGNhcHR1cmUgc3RhY2sgdHJhY2VcbiAgc3NmID0gc3NmIHx8IEFzc2VydGlvbkVycm9yO1xuICBpZiAoRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UpIHtcbiAgICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSh0aGlzLCBzc2YpO1xuICB9IGVsc2Uge1xuICAgIHRyeSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoKTtcbiAgICB9IGNhdGNoKGUpIHtcbiAgICAgIHRoaXMuc3RhY2sgPSBlLnN0YWNrO1xuICAgIH1cbiAgfVxufVxuXG4vKiFcbiAqIEluaGVyaXQgZnJvbSBFcnJvci5wcm90b3R5cGVcbiAqL1xuXG5Bc3NlcnRpb25FcnJvci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEVycm9yLnByb3RvdHlwZSk7XG5cbi8qIVxuICogU3RhdGljYWxseSBzZXQgbmFtZVxuICovXG5cbkFzc2VydGlvbkVycm9yLnByb3RvdHlwZS5uYW1lID0gJ0Fzc2VydGlvbkVycm9yJztcblxuLyohXG4gKiBFbnN1cmUgY29ycmVjdCBjb25zdHJ1Y3RvclxuICovXG5cbkFzc2VydGlvbkVycm9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IEFzc2VydGlvbkVycm9yO1xuXG4vKipcbiAqIEFsbG93IGVycm9ycyB0byBiZSBjb252ZXJ0ZWQgdG8gSlNPTiBmb3Igc3RhdGljIHRyYW5zZmVyLlxuICpcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gaW5jbHVkZSBzdGFjayAoZGVmYXVsdDogYHRydWVgKVxuICogQHJldHVybiB7T2JqZWN0fSBvYmplY3QgdGhhdCBjYW4gYmUgYEpTT04uc3RyaW5naWZ5YFxuICovXG5cbkFzc2VydGlvbkVycm9yLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiAoc3RhY2spIHtcbiAgdmFyIGV4dGVuZCA9IGV4Y2x1ZGUoJ2NvbnN0cnVjdG9yJywgJ3RvSlNPTicsICdzdGFjaycpXG4gICAgLCBwcm9wcyA9IGV4dGVuZCh7IG5hbWU6IHRoaXMubmFtZSB9LCB0aGlzKTtcblxuICAvLyBpbmNsdWRlIHN0YWNrIGlmIGV4aXN0cyBhbmQgbm90IHR1cm5lZCBvZmZcbiAgaWYgKGZhbHNlICE9PSBzdGFjayAmJiB0aGlzLnN0YWNrKSB7XG4gICAgcHJvcHMuc3RhY2sgPSB0aGlzLnN0YWNrO1xuICB9XG5cbiAgcmV0dXJuIHByb3BzO1xufTtcbiIsICIndXNlIHN0cmljdCc7XG5cbi8qICFcbiAqIENoYWkgLSBwYXRodmFsIHV0aWxpdHlcbiAqIENvcHlyaWdodChjKSAyMDEyLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBAc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9sb2dpY2FscGFyYWRveC9maWx0clxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyoqXG4gKiAjIyMgLmhhc1Byb3BlcnR5KG9iamVjdCwgbmFtZSlcbiAqXG4gKiBUaGlzIGFsbG93cyBjaGVja2luZyB3aGV0aGVyIGFuIG9iamVjdCBoYXMgb3duXG4gKiBvciBpbmhlcml0ZWQgZnJvbSBwcm90b3R5cGUgY2hhaW4gbmFtZWQgcHJvcGVydHkuXG4gKlxuICogQmFzaWNhbGx5IGRvZXMgdGhlIHNhbWUgdGhpbmcgYXMgdGhlIGBpbmBcbiAqIG9wZXJhdG9yIGJ1dCB3b3JrcyBwcm9wZXJseSB3aXRoIG51bGwvdW5kZWZpbmVkIHZhbHVlc1xuICogYW5kIG90aGVyIHByaW1pdGl2ZXMuXG4gKlxuICogICAgIHZhciBvYmogPSB7XG4gKiAgICAgICAgIGFycjogWydhJywgJ2InLCAnYyddXG4gKiAgICAgICAsIHN0cjogJ0hlbGxvJ1xuICogICAgIH1cbiAqXG4gKiBUaGUgZm9sbG93aW5nIHdvdWxkIGJlIHRoZSByZXN1bHRzLlxuICpcbiAqICAgICBoYXNQcm9wZXJ0eShvYmosICdzdHInKTsgIC8vIHRydWVcbiAqICAgICBoYXNQcm9wZXJ0eShvYmosICdjb25zdHJ1Y3RvcicpOyAgLy8gdHJ1ZVxuICogICAgIGhhc1Byb3BlcnR5KG9iaiwgJ2JhcicpOyAgLy8gZmFsc2VcbiAqXG4gKiAgICAgaGFzUHJvcGVydHkob2JqLnN0ciwgJ2xlbmd0aCcpOyAvLyB0cnVlXG4gKiAgICAgaGFzUHJvcGVydHkob2JqLnN0ciwgMSk7ICAvLyB0cnVlXG4gKiAgICAgaGFzUHJvcGVydHkob2JqLnN0ciwgNSk7ICAvLyBmYWxzZVxuICpcbiAqICAgICBoYXNQcm9wZXJ0eShvYmouYXJyLCAnbGVuZ3RoJyk7ICAvLyB0cnVlXG4gKiAgICAgaGFzUHJvcGVydHkob2JqLmFyciwgMik7ICAvLyB0cnVlXG4gKiAgICAgaGFzUHJvcGVydHkob2JqLmFyciwgMyk7ICAvLyBmYWxzZVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAqIEBwYXJhbSB7U3RyaW5nfFN5bWJvbH0gbmFtZVxuICogQHJldHVybnMge0Jvb2xlYW59IHdoZXRoZXIgaXQgZXhpc3RzXG4gKiBAbmFtZXNwYWNlIFV0aWxzXG4gKiBAbmFtZSBoYXNQcm9wZXJ0eVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBoYXNQcm9wZXJ0eShvYmosIG5hbWUpIHtcbiAgaWYgKHR5cGVvZiBvYmogPT09ICd1bmRlZmluZWQnIHx8IG9iaiA9PT0gbnVsbCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIFRoZSBgaW5gIG9wZXJhdG9yIGRvZXMgbm90IHdvcmsgd2l0aCBwcmltaXRpdmVzLlxuICByZXR1cm4gbmFtZSBpbiBPYmplY3Qob2JqKTtcbn1cblxuLyogIVxuICogIyMgcGFyc2VQYXRoKHBhdGgpXG4gKlxuICogSGVscGVyIGZ1bmN0aW9uIHVzZWQgdG8gcGFyc2Ugc3RyaW5nIG9iamVjdFxuICogcGF0aHMuIFVzZSBpbiBjb25qdW5jdGlvbiB3aXRoIGBpbnRlcm5hbEdldFBhdGhWYWx1ZWAuXG4gKlxuICogICAgICB2YXIgcGFyc2VkID0gcGFyc2VQYXRoKCdteW9iamVjdC5wcm9wZXJ0eS5zdWJwcm9wJyk7XG4gKlxuICogIyMjIFBhdGhzOlxuICpcbiAqICogQ2FuIGJlIGluZmluaXRlbHkgZGVlcCBhbmQgbmVzdGVkLlxuICogKiBBcnJheXMgYXJlIGFsc28gdmFsaWQgdXNpbmcgdGhlIGZvcm1hbCBgbXlvYmplY3QuZG9jdW1lbnRbM10ucHJvcGVydHlgLlxuICogKiBMaXRlcmFsIGRvdHMgYW5kIGJyYWNrZXRzIChub3QgZGVsaW1pdGVyKSBtdXN0IGJlIGJhY2tzbGFzaC1lc2NhcGVkLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBwYXRoXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBwYXJzZWRcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHBhcnNlUGF0aChwYXRoKSB7XG4gIHZhciBzdHIgPSBwYXRoLnJlcGxhY2UoLyhbXlxcXFxdKVxcWy9nLCAnJDEuWycpO1xuICB2YXIgcGFydHMgPSBzdHIubWF0Y2goLyhcXFxcXFwufFteLl0rPykrL2cpO1xuICByZXR1cm4gcGFydHMubWFwKGZ1bmN0aW9uIG1hcE1hdGNoZXModmFsdWUpIHtcbiAgICBpZiAoXG4gICAgICB2YWx1ZSA9PT0gJ2NvbnN0cnVjdG9yJyB8fFxuICAgICAgdmFsdWUgPT09ICdfX3Byb3RvX18nIHx8XG4gICAgICB2YWx1ZSA9PT0gJ3Byb3RvdHlwZSdcbiAgICApIHtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgdmFyIHJlZ2V4cCA9IC9eXFxbKFxcZCspXFxdJC87XG4gICAgdmFyIG1BcnIgPSByZWdleHAuZXhlYyh2YWx1ZSk7XG4gICAgdmFyIHBhcnNlZCA9IG51bGw7XG4gICAgaWYgKG1BcnIpIHtcbiAgICAgIHBhcnNlZCA9IHsgaTogcGFyc2VGbG9hdChtQXJyWzFdKSB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBwYXJzZWQgPSB7IHA6IHZhbHVlLnJlcGxhY2UoL1xcXFwoWy5bXFxdXSkvZywgJyQxJykgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gcGFyc2VkO1xuICB9KTtcbn1cblxuLyogIVxuICogIyMgaW50ZXJuYWxHZXRQYXRoVmFsdWUob2JqLCBwYXJzZWRbLCBwYXRoRGVwdGhdKVxuICpcbiAqIEhlbHBlciBjb21wYW5pb24gZnVuY3Rpb24gZm9yIGAucGFyc2VQYXRoYCB0aGF0IHJldHVybnNcbiAqIHRoZSB2YWx1ZSBsb2NhdGVkIGF0IHRoZSBwYXJzZWQgYWRkcmVzcy5cbiAqXG4gKiAgICAgIHZhciB2YWx1ZSA9IGdldFBhdGhWYWx1ZShvYmosIHBhcnNlZCk7XG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCB0byBzZWFyY2ggYWdhaW5zdFxuICogQHBhcmFtIHtPYmplY3R9IHBhcnNlZCBkZWZpbml0aW9uIGZyb20gYHBhcnNlUGF0aGAuXG4gKiBAcGFyYW0ge051bWJlcn0gZGVwdGggKG5lc3RpbmcgbGV2ZWwpIG9mIHRoZSBwcm9wZXJ0eSB3ZSB3YW50IHRvIHJldHJpZXZlXG4gKiBAcmV0dXJucyB7T2JqZWN0fFVuZGVmaW5lZH0gdmFsdWVcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGludGVybmFsR2V0UGF0aFZhbHVlKG9iaiwgcGFyc2VkLCBwYXRoRGVwdGgpIHtcbiAgdmFyIHRlbXBvcmFyeVZhbHVlID0gb2JqO1xuICB2YXIgcmVzID0gbnVsbDtcbiAgcGF0aERlcHRoID0gdHlwZW9mIHBhdGhEZXB0aCA9PT0gJ3VuZGVmaW5lZCcgPyBwYXJzZWQubGVuZ3RoIDogcGF0aERlcHRoO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcGF0aERlcHRoOyBpKyspIHtcbiAgICB2YXIgcGFydCA9IHBhcnNlZFtpXTtcbiAgICBpZiAodGVtcG9yYXJ5VmFsdWUpIHtcbiAgICAgIGlmICh0eXBlb2YgcGFydC5wID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICB0ZW1wb3JhcnlWYWx1ZSA9IHRlbXBvcmFyeVZhbHVlW3BhcnQuaV07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0ZW1wb3JhcnlWYWx1ZSA9IHRlbXBvcmFyeVZhbHVlW3BhcnQucF07XG4gICAgICB9XG5cbiAgICAgIGlmIChpID09PSBwYXRoRGVwdGggLSAxKSB7XG4gICAgICAgIHJlcyA9IHRlbXBvcmFyeVZhbHVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXM7XG59XG5cbi8qICFcbiAqICMjIGludGVybmFsU2V0UGF0aFZhbHVlKG9iaiwgdmFsdWUsIHBhcnNlZClcbiAqXG4gKiBDb21wYW5pb24gZnVuY3Rpb24gZm9yIGBwYXJzZVBhdGhgIHRoYXQgc2V0c1xuICogdGhlIHZhbHVlIGxvY2F0ZWQgYXQgYSBwYXJzZWQgYWRkcmVzcy5cbiAqXG4gKiAgaW50ZXJuYWxTZXRQYXRoVmFsdWUob2JqLCAndmFsdWUnLCBwYXJzZWQpO1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgdG8gc2VhcmNoIGFuZCBkZWZpbmUgb25cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgdG8gdXNlIHVwb24gc2V0XG4gKiBAcGFyYW0ge09iamVjdH0gcGFyc2VkIGRlZmluaXRpb24gZnJvbSBgcGFyc2VQYXRoYFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gaW50ZXJuYWxTZXRQYXRoVmFsdWUob2JqLCB2YWwsIHBhcnNlZCkge1xuICB2YXIgdGVtcE9iaiA9IG9iajtcbiAgdmFyIHBhdGhEZXB0aCA9IHBhcnNlZC5sZW5ndGg7XG4gIHZhciBwYXJ0ID0gbnVsbDtcbiAgLy8gSGVyZSB3ZSBpdGVyYXRlIHRocm91Z2ggZXZlcnkgcGFydCBvZiB0aGUgcGF0aFxuICBmb3IgKHZhciBpID0gMDsgaSA8IHBhdGhEZXB0aDsgaSsrKSB7XG4gICAgdmFyIHByb3BOYW1lID0gbnVsbDtcbiAgICB2YXIgcHJvcFZhbCA9IG51bGw7XG4gICAgcGFydCA9IHBhcnNlZFtpXTtcblxuICAgIC8vIElmIGl0J3MgdGhlIGxhc3QgcGFydCBvZiB0aGUgcGF0aCwgd2Ugc2V0IHRoZSAncHJvcE5hbWUnIHZhbHVlIHdpdGggdGhlIHByb3BlcnR5IG5hbWVcbiAgICBpZiAoaSA9PT0gcGF0aERlcHRoIC0gMSkge1xuICAgICAgcHJvcE5hbWUgPSB0eXBlb2YgcGFydC5wID09PSAndW5kZWZpbmVkJyA/IHBhcnQuaSA6IHBhcnQucDtcbiAgICAgIC8vIE5vdyB3ZSBzZXQgdGhlIHByb3BlcnR5IHdpdGggdGhlIG5hbWUgaGVsZCBieSAncHJvcE5hbWUnIG9uIG9iamVjdCB3aXRoIHRoZSBkZXNpcmVkIHZhbFxuICAgICAgdGVtcE9ialtwcm9wTmFtZV0gPSB2YWw7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgcGFydC5wICE9PSAndW5kZWZpbmVkJyAmJiB0ZW1wT2JqW3BhcnQucF0pIHtcbiAgICAgIHRlbXBPYmogPSB0ZW1wT2JqW3BhcnQucF07XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgcGFydC5pICE9PSAndW5kZWZpbmVkJyAmJiB0ZW1wT2JqW3BhcnQuaV0pIHtcbiAgICAgIHRlbXBPYmogPSB0ZW1wT2JqW3BhcnQuaV07XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIElmIHRoZSBvYmogZG9lc24ndCBoYXZlIHRoZSBwcm9wZXJ0eSB3ZSBjcmVhdGUgb25lIHdpdGggdGhhdCBuYW1lIHRvIGRlZmluZSBpdFxuICAgICAgdmFyIG5leHQgPSBwYXJzZWRbaSArIDFdO1xuICAgICAgLy8gSGVyZSB3ZSBzZXQgdGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IHdoaWNoIHdpbGwgYmUgZGVmaW5lZFxuICAgICAgcHJvcE5hbWUgPSB0eXBlb2YgcGFydC5wID09PSAndW5kZWZpbmVkJyA/IHBhcnQuaSA6IHBhcnQucDtcbiAgICAgIC8vIEhlcmUgd2UgZGVjaWRlIGlmIHRoaXMgcHJvcGVydHkgd2lsbCBiZSBhbiBhcnJheSBvciBhIG5ldyBvYmplY3RcbiAgICAgIHByb3BWYWwgPSB0eXBlb2YgbmV4dC5wID09PSAndW5kZWZpbmVkJyA/IFtdIDoge307XG4gICAgICB0ZW1wT2JqW3Byb3BOYW1lXSA9IHByb3BWYWw7XG4gICAgICB0ZW1wT2JqID0gdGVtcE9ialtwcm9wTmFtZV07XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogIyMjIC5nZXRQYXRoSW5mbyhvYmplY3QsIHBhdGgpXG4gKlxuICogVGhpcyBhbGxvd3MgdGhlIHJldHJpZXZhbCBvZiBwcm9wZXJ0eSBpbmZvIGluIGFuXG4gKiBvYmplY3QgZ2l2ZW4gYSBzdHJpbmcgcGF0aC5cbiAqXG4gKiBUaGUgcGF0aCBpbmZvIGNvbnNpc3RzIG9mIGFuIG9iamVjdCB3aXRoIHRoZVxuICogZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gKlxuICogKiBwYXJlbnQgLSBUaGUgcGFyZW50IG9iamVjdCBvZiB0aGUgcHJvcGVydHkgcmVmZXJlbmNlZCBieSBgcGF0aGBcbiAqICogbmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBmaW5hbCBwcm9wZXJ0eSwgYSBudW1iZXIgaWYgaXQgd2FzIGFuIGFycmF5IGluZGV4ZXJcbiAqICogdmFsdWUgLSBUaGUgdmFsdWUgb2YgdGhlIHByb3BlcnR5LCBpZiBpdCBleGlzdHMsIG90aGVyd2lzZSBgdW5kZWZpbmVkYFxuICogKiBleGlzdHMgLSBXaGV0aGVyIHRoZSBwcm9wZXJ0eSBleGlzdHMgb3Igbm90XG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICogQHBhcmFtIHtTdHJpbmd9IHBhdGhcbiAqIEByZXR1cm5zIHtPYmplY3R9IGluZm9cbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBuYW1lIGdldFBhdGhJbmZvXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGdldFBhdGhJbmZvKG9iaiwgcGF0aCkge1xuICB2YXIgcGFyc2VkID0gcGFyc2VQYXRoKHBhdGgpO1xuICB2YXIgbGFzdCA9IHBhcnNlZFtwYXJzZWQubGVuZ3RoIC0gMV07XG4gIHZhciBpbmZvID0ge1xuICAgIHBhcmVudDpcbiAgICAgIHBhcnNlZC5sZW5ndGggPiAxID9cbiAgICAgICAgaW50ZXJuYWxHZXRQYXRoVmFsdWUob2JqLCBwYXJzZWQsIHBhcnNlZC5sZW5ndGggLSAxKSA6XG4gICAgICAgIG9iaixcbiAgICBuYW1lOiBsYXN0LnAgfHwgbGFzdC5pLFxuICAgIHZhbHVlOiBpbnRlcm5hbEdldFBhdGhWYWx1ZShvYmosIHBhcnNlZCksXG4gIH07XG4gIGluZm8uZXhpc3RzID0gaGFzUHJvcGVydHkoaW5mby5wYXJlbnQsIGluZm8ubmFtZSk7XG5cbiAgcmV0dXJuIGluZm87XG59XG5cbi8qKlxuICogIyMjIC5nZXRQYXRoVmFsdWUob2JqZWN0LCBwYXRoKVxuICpcbiAqIFRoaXMgYWxsb3dzIHRoZSByZXRyaWV2YWwgb2YgdmFsdWVzIGluIGFuXG4gKiBvYmplY3QgZ2l2ZW4gYSBzdHJpbmcgcGF0aC5cbiAqXG4gKiAgICAgdmFyIG9iaiA9IHtcbiAqICAgICAgICAgcHJvcDE6IHtcbiAqICAgICAgICAgICAgIGFycjogWydhJywgJ2InLCAnYyddXG4gKiAgICAgICAgICAgLCBzdHI6ICdIZWxsbydcbiAqICAgICAgICAgfVxuICogICAgICAgLCBwcm9wMjoge1xuICogICAgICAgICAgICAgYXJyOiBbIHsgbmVzdGVkOiAnVW5pdmVyc2UnIH0gXVxuICogICAgICAgICAgICwgc3RyOiAnSGVsbG8gYWdhaW4hJ1xuICogICAgICAgICB9XG4gKiAgICAgfVxuICpcbiAqIFRoZSBmb2xsb3dpbmcgd291bGQgYmUgdGhlIHJlc3VsdHMuXG4gKlxuICogICAgIGdldFBhdGhWYWx1ZShvYmosICdwcm9wMS5zdHInKTsgLy8gSGVsbG9cbiAqICAgICBnZXRQYXRoVmFsdWUob2JqLCAncHJvcDEuYXR0WzJdJyk7IC8vIGJcbiAqICAgICBnZXRQYXRoVmFsdWUob2JqLCAncHJvcDIuYXJyWzBdLm5lc3RlZCcpOyAvLyBVbml2ZXJzZVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAqIEBwYXJhbSB7U3RyaW5nfSBwYXRoXG4gKiBAcmV0dXJucyB7T2JqZWN0fSB2YWx1ZSBvciBgdW5kZWZpbmVkYFxuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQG5hbWUgZ2V0UGF0aFZhbHVlXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGdldFBhdGhWYWx1ZShvYmosIHBhdGgpIHtcbiAgdmFyIGluZm8gPSBnZXRQYXRoSW5mbyhvYmosIHBhdGgpO1xuICByZXR1cm4gaW5mby52YWx1ZTtcbn1cblxuLyoqXG4gKiAjIyMgLnNldFBhdGhWYWx1ZShvYmplY3QsIHBhdGgsIHZhbHVlKVxuICpcbiAqIERlZmluZSB0aGUgdmFsdWUgaW4gYW4gb2JqZWN0IGF0IGEgZ2l2ZW4gc3RyaW5nIHBhdGguXG4gKlxuICogYGBganNcbiAqIHZhciBvYmogPSB7XG4gKiAgICAgcHJvcDE6IHtcbiAqICAgICAgICAgYXJyOiBbJ2EnLCAnYicsICdjJ11cbiAqICAgICAgICwgc3RyOiAnSGVsbG8nXG4gKiAgICAgfVxuICogICAsIHByb3AyOiB7XG4gKiAgICAgICAgIGFycjogWyB7IG5lc3RlZDogJ1VuaXZlcnNlJyB9IF1cbiAqICAgICAgICwgc3RyOiAnSGVsbG8gYWdhaW4hJ1xuICogICAgIH1cbiAqIH07XG4gKiBgYGBcbiAqXG4gKiBUaGUgZm9sbG93aW5nIHdvdWxkIGJlIGFjY2VwdGFibGUuXG4gKlxuICogYGBganNcbiAqIHZhciBwcm9wZXJ0aWVzID0gcmVxdWlyZSgndGVhLXByb3BlcnRpZXMnKTtcbiAqIHByb3BlcnRpZXMuc2V0KG9iaiwgJ3Byb3AxLnN0cicsICdIZWxsbyBVbml2ZXJzZSEnKTtcbiAqIHByb3BlcnRpZXMuc2V0KG9iaiwgJ3Byb3AxLmFyclsyXScsICdCJyk7XG4gKiBwcm9wZXJ0aWVzLnNldChvYmosICdwcm9wMi5hcnJbMF0ubmVzdGVkLnZhbHVlJywgeyBoZWxsbzogJ3VuaXZlcnNlJyB9KTtcbiAqIGBgYFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAqIEBwYXJhbSB7U3RyaW5nfSBwYXRoXG4gKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gc2V0UGF0aFZhbHVlKG9iaiwgcGF0aCwgdmFsKSB7XG4gIHZhciBwYXJzZWQgPSBwYXJzZVBhdGgocGF0aCk7XG4gIGludGVybmFsU2V0UGF0aFZhbHVlKG9iaiwgdmFsLCBwYXJzZWQpO1xuICByZXR1cm4gb2JqO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgaGFzUHJvcGVydHk6IGhhc1Byb3BlcnR5LFxuICBnZXRQYXRoSW5mbzogZ2V0UGF0aEluZm8sXG4gIGdldFBhdGhWYWx1ZTogZ2V0UGF0aFZhbHVlLFxuICBzZXRQYXRoVmFsdWU6IHNldFBhdGhWYWx1ZSxcbn07XG4iLCAiLyohXG4gKiBDaGFpIC0gZmxhZyB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyoqXG4gKiAjIyMgLmZsYWcob2JqZWN0LCBrZXksIFt2YWx1ZV0pXG4gKlxuICogR2V0IG9yIHNldCBhIGZsYWcgdmFsdWUgb24gYW4gb2JqZWN0LiBJZiBhXG4gKiB2YWx1ZSBpcyBwcm92aWRlZCBpdCB3aWxsIGJlIHNldCwgZWxzZSBpdCB3aWxsXG4gKiByZXR1cm4gdGhlIGN1cnJlbnRseSBzZXQgdmFsdWUgb3IgYHVuZGVmaW5lZGAgaWZcbiAqIHRoZSB2YWx1ZSBpcyBub3Qgc2V0LlxuICpcbiAqICAgICB1dGlscy5mbGFnKHRoaXMsICdmb28nLCAnYmFyJyk7IC8vIHNldHRlclxuICogICAgIHV0aWxzLmZsYWcodGhpcywgJ2ZvbycpOyAvLyBnZXR0ZXIsIHJldHVybnMgYGJhcmBcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IGNvbnN0cnVjdGVkIEFzc2VydGlvblxuICogQHBhcmFtIHtTdHJpbmd9IGtleVxuICogQHBhcmFtIHtNaXhlZH0gdmFsdWUgKG9wdGlvbmFsKVxuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQG5hbWUgZmxhZ1xuICogQGFwaSBwcml2YXRlXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBmbGFnKG9iaiwga2V5LCB2YWx1ZSkge1xuICB2YXIgZmxhZ3MgPSBvYmouX19mbGFncyB8fCAob2JqLl9fZmxhZ3MgPSBPYmplY3QuY3JlYXRlKG51bGwpKTtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDMpIHtcbiAgICBmbGFnc1trZXldID0gdmFsdWU7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGZsYWdzW2tleV07XG4gIH1cbn07XG4iLCAiLyohXG4gKiBDaGFpIC0gdGVzdCB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyohXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzXG4gKi9cblxudmFyIGZsYWcgPSByZXF1aXJlKCcuL2ZsYWcnKTtcblxuLyoqXG4gKiAjIyMgLnRlc3Qob2JqZWN0LCBleHByZXNzaW9uKVxuICpcbiAqIFRlc3QgYW5kIG9iamVjdCBmb3IgZXhwcmVzc2lvbi5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IChjb25zdHJ1Y3RlZCBBc3NlcnRpb24pXG4gKiBAcGFyYW0ge0FyZ3VtZW50c30gY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLmFzc2VydCBhcmd1bWVudHNcbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBuYW1lIHRlc3RcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHRlc3Qob2JqLCBhcmdzKSB7XG4gIHZhciBuZWdhdGUgPSBmbGFnKG9iaiwgJ25lZ2F0ZScpXG4gICAgLCBleHByID0gYXJnc1swXTtcbiAgcmV0dXJuIG5lZ2F0ZSA/ICFleHByIDogZXhwcjtcbn07XG4iLCAiKGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcblx0dHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnID8gbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KCkgOlxuXHR0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQgPyBkZWZpbmUoZmFjdG9yeSkgOlxuXHQoZ2xvYmFsLnR5cGVEZXRlY3QgPSBmYWN0b3J5KCkpO1xufSh0aGlzLCAoZnVuY3Rpb24gKCkgeyAndXNlIHN0cmljdCc7XG5cbi8qICFcbiAqIHR5cGUtZGV0ZWN0XG4gKiBDb3B5cmlnaHQoYykgMjAxMyBqYWtlIGx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG52YXIgcHJvbWlzZUV4aXN0cyA9IHR5cGVvZiBQcm9taXNlID09PSAnZnVuY3Rpb24nO1xuXG4vKiBlc2xpbnQtZGlzYWJsZSBuby11bmRlZiAqL1xudmFyIGdsb2JhbE9iamVjdCA9IHR5cGVvZiBzZWxmID09PSAnb2JqZWN0JyA/IHNlbGYgOiBnbG9iYWw7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgaWQtYmxhY2tsaXN0XG5cbnZhciBzeW1ib2xFeGlzdHMgPSB0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJztcbnZhciBtYXBFeGlzdHMgPSB0eXBlb2YgTWFwICE9PSAndW5kZWZpbmVkJztcbnZhciBzZXRFeGlzdHMgPSB0eXBlb2YgU2V0ICE9PSAndW5kZWZpbmVkJztcbnZhciB3ZWFrTWFwRXhpc3RzID0gdHlwZW9mIFdlYWtNYXAgIT09ICd1bmRlZmluZWQnO1xudmFyIHdlYWtTZXRFeGlzdHMgPSB0eXBlb2YgV2Vha1NldCAhPT0gJ3VuZGVmaW5lZCc7XG52YXIgZGF0YVZpZXdFeGlzdHMgPSB0eXBlb2YgRGF0YVZpZXcgIT09ICd1bmRlZmluZWQnO1xudmFyIHN5bWJvbEl0ZXJhdG9yRXhpc3RzID0gc3ltYm9sRXhpc3RzICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgIT09ICd1bmRlZmluZWQnO1xudmFyIHN5bWJvbFRvU3RyaW5nVGFnRXhpc3RzID0gc3ltYm9sRXhpc3RzICYmIHR5cGVvZiBTeW1ib2wudG9TdHJpbmdUYWcgIT09ICd1bmRlZmluZWQnO1xudmFyIHNldEVudHJpZXNFeGlzdHMgPSBzZXRFeGlzdHMgJiYgdHlwZW9mIFNldC5wcm90b3R5cGUuZW50cmllcyA9PT0gJ2Z1bmN0aW9uJztcbnZhciBtYXBFbnRyaWVzRXhpc3RzID0gbWFwRXhpc3RzICYmIHR5cGVvZiBNYXAucHJvdG90eXBlLmVudHJpZXMgPT09ICdmdW5jdGlvbic7XG52YXIgc2V0SXRlcmF0b3JQcm90b3R5cGUgPSBzZXRFbnRyaWVzRXhpc3RzICYmIE9iamVjdC5nZXRQcm90b3R5cGVPZihuZXcgU2V0KCkuZW50cmllcygpKTtcbnZhciBtYXBJdGVyYXRvclByb3RvdHlwZSA9IG1hcEVudHJpZXNFeGlzdHMgJiYgT2JqZWN0LmdldFByb3RvdHlwZU9mKG5ldyBNYXAoKS5lbnRyaWVzKCkpO1xudmFyIGFycmF5SXRlcmF0b3JFeGlzdHMgPSBzeW1ib2xJdGVyYXRvckV4aXN0cyAmJiB0eXBlb2YgQXJyYXkucHJvdG90eXBlW1N5bWJvbC5pdGVyYXRvcl0gPT09ICdmdW5jdGlvbic7XG52YXIgYXJyYXlJdGVyYXRvclByb3RvdHlwZSA9IGFycmF5SXRlcmF0b3JFeGlzdHMgJiYgT2JqZWN0LmdldFByb3RvdHlwZU9mKFtdW1N5bWJvbC5pdGVyYXRvcl0oKSk7XG52YXIgc3RyaW5nSXRlcmF0b3JFeGlzdHMgPSBzeW1ib2xJdGVyYXRvckV4aXN0cyAmJiB0eXBlb2YgU3RyaW5nLnByb3RvdHlwZVtTeW1ib2wuaXRlcmF0b3JdID09PSAnZnVuY3Rpb24nO1xudmFyIHN0cmluZ0l0ZXJhdG9yUHJvdG90eXBlID0gc3RyaW5nSXRlcmF0b3JFeGlzdHMgJiYgT2JqZWN0LmdldFByb3RvdHlwZU9mKCcnW1N5bWJvbC5pdGVyYXRvcl0oKSk7XG52YXIgdG9TdHJpbmdMZWZ0U2xpY2VMZW5ndGggPSA4O1xudmFyIHRvU3RyaW5nUmlnaHRTbGljZUxlbmd0aCA9IC0xO1xuLyoqXG4gKiAjIyMgdHlwZU9mIChvYmopXG4gKlxuICogVXNlcyBgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZ2AgdG8gZGV0ZXJtaW5lIHRoZSB0eXBlIG9mIGFuIG9iamVjdCxcbiAqIG5vcm1hbGlzaW5nIGJlaGF2aW91ciBhY3Jvc3MgZW5naW5lIHZlcnNpb25zICYgd2VsbCBvcHRpbWlzZWQuXG4gKlxuICogQHBhcmFtIHtNaXhlZH0gb2JqZWN0XG4gKiBAcmV0dXJuIHtTdHJpbmd9IG9iamVjdCB0eXBlXG4gKiBAYXBpIHB1YmxpY1xuICovXG5mdW5jdGlvbiB0eXBlRGV0ZWN0KG9iaikge1xuICAvKiAhIFNwZWVkIG9wdGltaXNhdGlvblxuICAgKiBQcmU6XG4gICAqICAgc3RyaW5nIGxpdGVyYWwgICAgIHggMywwMzksMDM1IG9wcy9zZWMgXHUwMEIxMS42MiUgKDc4IHJ1bnMgc2FtcGxlZClcbiAgICogICBib29sZWFuIGxpdGVyYWwgICAgeCAxLDQyNCwxMzggb3BzL3NlYyBcdTAwQjE0LjU0JSAoNzUgcnVucyBzYW1wbGVkKVxuICAgKiAgIG51bWJlciBsaXRlcmFsICAgICB4IDEsNjUzLDE1MyBvcHMvc2VjIFx1MDBCMTEuOTElICg4MiBydW5zIHNhbXBsZWQpXG4gICAqICAgdW5kZWZpbmVkICAgICAgICAgIHggOSw5NzgsNjYwIG9wcy9zZWMgXHUwMEIxMS45MiUgKDc1IHJ1bnMgc2FtcGxlZClcbiAgICogICBmdW5jdGlvbiAgICAgICAgICAgeCAyLDU1Niw3Njkgb3BzL3NlYyBcdTAwQjExLjczJSAoNzcgcnVucyBzYW1wbGVkKVxuICAgKiBQb3N0OlxuICAgKiAgIHN0cmluZyBsaXRlcmFsICAgICB4IDM4LDU2NCw3OTYgb3BzL3NlYyBcdTAwQjExLjE1JSAoNzkgcnVucyBzYW1wbGVkKVxuICAgKiAgIGJvb2xlYW4gbGl0ZXJhbCAgICB4IDMxLDE0OCw5NDAgb3BzL3NlYyBcdTAwQjExLjEwJSAoNzkgcnVucyBzYW1wbGVkKVxuICAgKiAgIG51bWJlciBsaXRlcmFsICAgICB4IDMyLDY3OSwzMzAgb3BzL3NlYyBcdTAwQjExLjkwJSAoNzggcnVucyBzYW1wbGVkKVxuICAgKiAgIHVuZGVmaW5lZCAgICAgICAgICB4IDMyLDM2MywzNjggb3BzL3NlYyBcdTAwQjExLjA3JSAoODIgcnVucyBzYW1wbGVkKVxuICAgKiAgIGZ1bmN0aW9uICAgICAgICAgICB4IDMxLDI5Niw4NzAgb3BzL3NlYyBcdTAwQjEwLjk2JSAoODMgcnVucyBzYW1wbGVkKVxuICAgKi9cbiAgdmFyIHR5cGVvZk9iaiA9IHR5cGVvZiBvYmo7XG4gIGlmICh0eXBlb2ZPYmogIT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIHR5cGVvZk9iajtcbiAgfVxuXG4gIC8qICEgU3BlZWQgb3B0aW1pc2F0aW9uXG4gICAqIFByZTpcbiAgICogICBudWxsICAgICAgICAgICAgICAgeCAyOCw2NDUsNzY1IG9wcy9zZWMgXHUwMEIxMS4xNyUgKDgyIHJ1bnMgc2FtcGxlZClcbiAgICogUG9zdDpcbiAgICogICBudWxsICAgICAgICAgICAgICAgeCAzNiw0MjgsOTYyIG9wcy9zZWMgXHUwMEIxMS4zNyUgKDg0IHJ1bnMgc2FtcGxlZClcbiAgICovXG4gIGlmIChvYmogPT09IG51bGwpIHtcbiAgICByZXR1cm4gJ251bGwnO1xuICB9XG5cbiAgLyogISBTcGVjIENvbmZvcm1hbmNlXG4gICAqIFRlc3Q6IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwod2luZG93KWBgXG4gICAqICAtIE5vZGUgPT09IFwiW29iamVjdCBnbG9iYWxdXCJcbiAgICogIC0gQ2hyb21lID09PSBcIltvYmplY3QgZ2xvYmFsXVwiXG4gICAqICAtIEZpcmVmb3ggPT09IFwiW29iamVjdCBXaW5kb3ddXCJcbiAgICogIC0gUGhhbnRvbUpTID09PSBcIltvYmplY3QgV2luZG93XVwiXG4gICAqICAtIFNhZmFyaSA9PT0gXCJbb2JqZWN0IFdpbmRvd11cIlxuICAgKiAgLSBJRSAxMSA9PT0gXCJbb2JqZWN0IFdpbmRvd11cIlxuICAgKiAgLSBJRSBFZGdlID09PSBcIltvYmplY3QgV2luZG93XVwiXG4gICAqIFRlc3Q6IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodGhpcylgYFxuICAgKiAgLSBDaHJvbWUgV29ya2VyID09PSBcIltvYmplY3QgZ2xvYmFsXVwiXG4gICAqICAtIEZpcmVmb3ggV29ya2VyID09PSBcIltvYmplY3QgRGVkaWNhdGVkV29ya2VyR2xvYmFsU2NvcGVdXCJcbiAgICogIC0gU2FmYXJpIFdvcmtlciA9PT0gXCJbb2JqZWN0IERlZGljYXRlZFdvcmtlckdsb2JhbFNjb3BlXVwiXG4gICAqICAtIElFIDExIFdvcmtlciA9PT0gXCJbb2JqZWN0IFdvcmtlckdsb2JhbFNjb3BlXVwiXG4gICAqICAtIElFIEVkZ2UgV29ya2VyID09PSBcIltvYmplY3QgV29ya2VyR2xvYmFsU2NvcGVdXCJcbiAgICovXG4gIGlmIChvYmogPT09IGdsb2JhbE9iamVjdCkge1xuICAgIHJldHVybiAnZ2xvYmFsJztcbiAgfVxuXG4gIC8qICEgU3BlZWQgb3B0aW1pc2F0aW9uXG4gICAqIFByZTpcbiAgICogICBhcnJheSBsaXRlcmFsICAgICAgeCAyLDg4OCwzNTIgb3BzL3NlYyBcdTAwQjEwLjY3JSAoODIgcnVucyBzYW1wbGVkKVxuICAgKiBQb3N0OlxuICAgKiAgIGFycmF5IGxpdGVyYWwgICAgICB4IDIyLDQ3OSw2NTAgb3BzL3NlYyBcdTAwQjEwLjk2JSAoODEgcnVucyBzYW1wbGVkKVxuICAgKi9cbiAgaWYgKFxuICAgIEFycmF5LmlzQXJyYXkob2JqKSAmJlxuICAgIChzeW1ib2xUb1N0cmluZ1RhZ0V4aXN0cyA9PT0gZmFsc2UgfHwgIShTeW1ib2wudG9TdHJpbmdUYWcgaW4gb2JqKSlcbiAgKSB7XG4gICAgcmV0dXJuICdBcnJheSc7XG4gIH1cblxuICAvLyBOb3QgY2FjaGluZyBleGlzdGVuY2Ugb2YgYHdpbmRvd2AgYW5kIHJlbGF0ZWQgcHJvcGVydGllcyBkdWUgdG8gcG90ZW50aWFsXG4gIC8vIGZvciBgd2luZG93YCB0byBiZSB1bnNldCBiZWZvcmUgdGVzdHMgaW4gcXVhc2ktYnJvd3NlciBlbnZpcm9ubWVudHMuXG4gIGlmICh0eXBlb2Ygd2luZG93ID09PSAnb2JqZWN0JyAmJiB3aW5kb3cgIT09IG51bGwpIHtcbiAgICAvKiAhIFNwZWMgQ29uZm9ybWFuY2VcbiAgICAgKiAoaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2UvYnJvd3NlcnMuaHRtbCNsb2NhdGlvbilcbiAgICAgKiBXaGF0V0cgSFRNTCQ3LjcuMyAtIFRoZSBgTG9jYXRpb25gIGludGVyZmFjZVxuICAgICAqIFRlc3Q6IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwod2luZG93LmxvY2F0aW9uKWBgXG4gICAgICogIC0gSUUgPD0xMSA9PT0gXCJbb2JqZWN0IE9iamVjdF1cIlxuICAgICAqICAtIElFIEVkZ2UgPD0xMyA9PT0gXCJbb2JqZWN0IE9iamVjdF1cIlxuICAgICAqL1xuICAgIGlmICh0eXBlb2Ygd2luZG93LmxvY2F0aW9uID09PSAnb2JqZWN0JyAmJiBvYmogPT09IHdpbmRvdy5sb2NhdGlvbikge1xuICAgICAgcmV0dXJuICdMb2NhdGlvbic7XG4gICAgfVxuXG4gICAgLyogISBTcGVjIENvbmZvcm1hbmNlXG4gICAgICogKGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvI2RvY3VtZW50KVxuICAgICAqIFdoYXRXRyBIVE1MJDMuMS4xIC0gVGhlIGBEb2N1bWVudGAgb2JqZWN0XG4gICAgICogTm90ZTogTW9zdCBicm93c2VycyBjdXJyZW50bHkgYWRoZXIgdG8gdGhlIFczQyBET00gTGV2ZWwgMiBzcGVjXG4gICAgICogICAgICAgKGh0dHBzOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1IVE1ML2h0bWwuaHRtbCNJRC0yNjgwOTI2OClcbiAgICAgKiAgICAgICB3aGljaCBzdWdnZXN0cyB0aGF0IGJyb3dzZXJzIHNob3VsZCB1c2UgSFRNTFRhYmxlQ2VsbEVsZW1lbnQgZm9yXG4gICAgICogICAgICAgYm90aCBURCBhbmQgVEggZWxlbWVudHMuIFdoYXRXRyBzZXBhcmF0ZXMgdGhlc2UuXG4gICAgICogICAgICAgV2hhdFdHIEhUTUwgc3RhdGVzOlxuICAgICAqICAgICAgICAgPiBGb3IgaGlzdG9yaWNhbCByZWFzb25zLCBXaW5kb3cgb2JqZWN0cyBtdXN0IGFsc28gaGF2ZSBhXG4gICAgICogICAgICAgICA+IHdyaXRhYmxlLCBjb25maWd1cmFibGUsIG5vbi1lbnVtZXJhYmxlIHByb3BlcnR5IG5hbWVkXG4gICAgICogICAgICAgICA+IEhUTUxEb2N1bWVudCB3aG9zZSB2YWx1ZSBpcyB0aGUgRG9jdW1lbnQgaW50ZXJmYWNlIG9iamVjdC5cbiAgICAgKiBUZXN0OiBgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGRvY3VtZW50KWBgXG4gICAgICogIC0gQ2hyb21lID09PSBcIltvYmplY3QgSFRNTERvY3VtZW50XVwiXG4gICAgICogIC0gRmlyZWZveCA9PT0gXCJbb2JqZWN0IEhUTUxEb2N1bWVudF1cIlxuICAgICAqICAtIFNhZmFyaSA9PT0gXCJbb2JqZWN0IEhUTUxEb2N1bWVudF1cIlxuICAgICAqICAtIElFIDw9MTAgPT09IFwiW29iamVjdCBEb2N1bWVudF1cIlxuICAgICAqICAtIElFIDExID09PSBcIltvYmplY3QgSFRNTERvY3VtZW50XVwiXG4gICAgICogIC0gSUUgRWRnZSA8PTEzID09PSBcIltvYmplY3QgSFRNTERvY3VtZW50XVwiXG4gICAgICovXG4gICAgaWYgKHR5cGVvZiB3aW5kb3cuZG9jdW1lbnQgPT09ICdvYmplY3QnICYmIG9iaiA9PT0gd2luZG93LmRvY3VtZW50KSB7XG4gICAgICByZXR1cm4gJ0RvY3VtZW50JztcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHdpbmRvdy5uYXZpZ2F0b3IgPT09ICdvYmplY3QnKSB7XG4gICAgICAvKiAhIFNwZWMgQ29uZm9ybWFuY2VcbiAgICAgICAqIChodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS93ZWJhcHBhcGlzLmh0bWwjbWltZXR5cGVhcnJheSlcbiAgICAgICAqIFdoYXRXRyBIVE1MJDguNi4xLjUgLSBQbHVnaW5zIC0gSW50ZXJmYWNlIE1pbWVUeXBlQXJyYXlcbiAgICAgICAqIFRlc3Q6IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobmF2aWdhdG9yLm1pbWVUeXBlcylgYFxuICAgICAgICogIC0gSUUgPD0xMCA9PT0gXCJbb2JqZWN0IE1TTWltZVR5cGVzQ29sbGVjdGlvbl1cIlxuICAgICAgICovXG4gICAgICBpZiAodHlwZW9mIHdpbmRvdy5uYXZpZ2F0b3IubWltZVR5cGVzID09PSAnb2JqZWN0JyAmJlxuICAgICAgICAgIG9iaiA9PT0gd2luZG93Lm5hdmlnYXRvci5taW1lVHlwZXMpIHtcbiAgICAgICAgcmV0dXJuICdNaW1lVHlwZUFycmF5JztcbiAgICAgIH1cblxuICAgICAgLyogISBTcGVjIENvbmZvcm1hbmNlXG4gICAgICAgKiAoaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvd2ViYXBwYXBpcy5odG1sI3BsdWdpbmFycmF5KVxuICAgICAgICogV2hhdFdHIEhUTUwkOC42LjEuNSAtIFBsdWdpbnMgLSBJbnRlcmZhY2UgUGx1Z2luQXJyYXlcbiAgICAgICAqIFRlc3Q6IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobmF2aWdhdG9yLnBsdWdpbnMpYGBcbiAgICAgICAqICAtIElFIDw9MTAgPT09IFwiW29iamVjdCBNU1BsdWdpbnNDb2xsZWN0aW9uXVwiXG4gICAgICAgKi9cbiAgICAgIGlmICh0eXBlb2Ygd2luZG93Lm5hdmlnYXRvci5wbHVnaW5zID09PSAnb2JqZWN0JyAmJlxuICAgICAgICAgIG9iaiA9PT0gd2luZG93Lm5hdmlnYXRvci5wbHVnaW5zKSB7XG4gICAgICAgIHJldHVybiAnUGx1Z2luQXJyYXknO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICgodHlwZW9mIHdpbmRvdy5IVE1MRWxlbWVudCA9PT0gJ2Z1bmN0aW9uJyB8fFxuICAgICAgICB0eXBlb2Ygd2luZG93LkhUTUxFbGVtZW50ID09PSAnb2JqZWN0JykgJiZcbiAgICAgICAgb2JqIGluc3RhbmNlb2Ygd2luZG93LkhUTUxFbGVtZW50KSB7XG4gICAgICAvKiAhIFNwZWMgQ29uZm9ybWFuY2VcbiAgICAgICogKGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3dlYmFwcGFwaXMuaHRtbCNwbHVnaW5hcnJheSlcbiAgICAgICogV2hhdFdHIEhUTUwkNC40LjQgLSBUaGUgYGJsb2NrcXVvdGVgIGVsZW1lbnQgLSBJbnRlcmZhY2UgYEhUTUxRdW90ZUVsZW1lbnRgXG4gICAgICAqIFRlc3Q6IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYmxvY2txdW90ZScpKWBgXG4gICAgICAqICAtIElFIDw9MTAgPT09IFwiW29iamVjdCBIVE1MQmxvY2tFbGVtZW50XVwiXG4gICAgICAqL1xuICAgICAgaWYgKG9iai50YWdOYW1lID09PSAnQkxPQ0tRVU9URScpIHtcbiAgICAgICAgcmV0dXJuICdIVE1MUXVvdGVFbGVtZW50JztcbiAgICAgIH1cblxuICAgICAgLyogISBTcGVjIENvbmZvcm1hbmNlXG4gICAgICAgKiAoaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy8jaHRtbHRhYmxlZGF0YWNlbGxlbGVtZW50KVxuICAgICAgICogV2hhdFdHIEhUTUwkNC45LjkgLSBUaGUgYHRkYCBlbGVtZW50IC0gSW50ZXJmYWNlIGBIVE1MVGFibGVEYXRhQ2VsbEVsZW1lbnRgXG4gICAgICAgKiBOb3RlOiBNb3N0IGJyb3dzZXJzIGN1cnJlbnRseSBhZGhlciB0byB0aGUgVzNDIERPTSBMZXZlbCAyIHNwZWNcbiAgICAgICAqICAgICAgIChodHRwczovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItSFRNTC9odG1sLmh0bWwjSUQtODI5MTUwNzUpXG4gICAgICAgKiAgICAgICB3aGljaCBzdWdnZXN0cyB0aGF0IGJyb3dzZXJzIHNob3VsZCB1c2UgSFRNTFRhYmxlQ2VsbEVsZW1lbnQgZm9yXG4gICAgICAgKiAgICAgICBib3RoIFREIGFuZCBUSCBlbGVtZW50cy4gV2hhdFdHIHNlcGFyYXRlcyB0aGVzZS5cbiAgICAgICAqIFRlc3Q6IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd0ZCcpKVxuICAgICAgICogIC0gQ2hyb21lID09PSBcIltvYmplY3QgSFRNTFRhYmxlQ2VsbEVsZW1lbnRdXCJcbiAgICAgICAqICAtIEZpcmVmb3ggPT09IFwiW29iamVjdCBIVE1MVGFibGVDZWxsRWxlbWVudF1cIlxuICAgICAgICogIC0gU2FmYXJpID09PSBcIltvYmplY3QgSFRNTFRhYmxlQ2VsbEVsZW1lbnRdXCJcbiAgICAgICAqL1xuICAgICAgaWYgKG9iai50YWdOYW1lID09PSAnVEQnKSB7XG4gICAgICAgIHJldHVybiAnSFRNTFRhYmxlRGF0YUNlbGxFbGVtZW50JztcbiAgICAgIH1cblxuICAgICAgLyogISBTcGVjIENvbmZvcm1hbmNlXG4gICAgICAgKiAoaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy8jaHRtbHRhYmxlaGVhZGVyY2VsbGVsZW1lbnQpXG4gICAgICAgKiBXaGF0V0cgSFRNTCQ0LjkuOSAtIFRoZSBgdGRgIGVsZW1lbnQgLSBJbnRlcmZhY2UgYEhUTUxUYWJsZUhlYWRlckNlbGxFbGVtZW50YFxuICAgICAgICogTm90ZTogTW9zdCBicm93c2VycyBjdXJyZW50bHkgYWRoZXIgdG8gdGhlIFczQyBET00gTGV2ZWwgMiBzcGVjXG4gICAgICAgKiAgICAgICAoaHR0cHM6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUhUTUwvaHRtbC5odG1sI0lELTgyOTE1MDc1KVxuICAgICAgICogICAgICAgd2hpY2ggc3VnZ2VzdHMgdGhhdCBicm93c2VycyBzaG91bGQgdXNlIEhUTUxUYWJsZUNlbGxFbGVtZW50IGZvclxuICAgICAgICogICAgICAgYm90aCBURCBhbmQgVEggZWxlbWVudHMuIFdoYXRXRyBzZXBhcmF0ZXMgdGhlc2UuXG4gICAgICAgKiBUZXN0OiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndGgnKSlcbiAgICAgICAqICAtIENocm9tZSA9PT0gXCJbb2JqZWN0IEhUTUxUYWJsZUNlbGxFbGVtZW50XVwiXG4gICAgICAgKiAgLSBGaXJlZm94ID09PSBcIltvYmplY3QgSFRNTFRhYmxlQ2VsbEVsZW1lbnRdXCJcbiAgICAgICAqICAtIFNhZmFyaSA9PT0gXCJbb2JqZWN0IEhUTUxUYWJsZUNlbGxFbGVtZW50XVwiXG4gICAgICAgKi9cbiAgICAgIGlmIChvYmoudGFnTmFtZSA9PT0gJ1RIJykge1xuICAgICAgICByZXR1cm4gJ0hUTUxUYWJsZUhlYWRlckNlbGxFbGVtZW50JztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKiAhIFNwZWVkIG9wdGltaXNhdGlvblxuICAqIFByZTpcbiAgKiAgIEZsb2F0NjRBcnJheSAgICAgICB4IDYyNSw2NDQgb3BzL3NlYyBcdTAwQjExLjU4JSAoODAgcnVucyBzYW1wbGVkKVxuICAqICAgRmxvYXQzMkFycmF5ICAgICAgIHggMSwyNzksODUyIG9wcy9zZWMgXHUwMEIxMi45MSUgKDc3IHJ1bnMgc2FtcGxlZClcbiAgKiAgIFVpbnQzMkFycmF5ICAgICAgICB4IDEsMTc4LDE4NSBvcHMvc2VjIFx1MDBCMTEuOTUlICg4MyBydW5zIHNhbXBsZWQpXG4gICogICBVaW50MTZBcnJheSAgICAgICAgeCAxLDAwOCwzODAgb3BzL3NlYyBcdTAwQjEyLjI1JSAoODAgcnVucyBzYW1wbGVkKVxuICAqICAgVWludDhBcnJheSAgICAgICAgIHggMSwxMjgsMDQwIG9wcy9zZWMgXHUwMEIxMi4xMSUgKDgxIHJ1bnMgc2FtcGxlZClcbiAgKiAgIEludDMyQXJyYXkgICAgICAgICB4IDEsMTcwLDExOSBvcHMvc2VjIFx1MDBCMTIuODglICg4MCBydW5zIHNhbXBsZWQpXG4gICogICBJbnQxNkFycmF5ICAgICAgICAgeCAxLDE3NiwzNDggb3BzL3NlYyBcdTAwQjE1Ljc5JSAoODYgcnVucyBzYW1wbGVkKVxuICAqICAgSW50OEFycmF5ICAgICAgICAgIHggMSwwNTgsNzA3IG9wcy9zZWMgXHUwMEIxNC45NCUgKDc3IHJ1bnMgc2FtcGxlZClcbiAgKiAgIFVpbnQ4Q2xhbXBlZEFycmF5ICB4IDEsMTEwLDYzMyBvcHMvc2VjIFx1MDBCMTQuMjAlICg4MCBydW5zIHNhbXBsZWQpXG4gICogUG9zdDpcbiAgKiAgIEZsb2F0NjRBcnJheSAgICAgICB4IDcsMTA1LDY3MSBvcHMvc2VjIFx1MDBCMTEzLjQ3JSAoNjQgcnVucyBzYW1wbGVkKVxuICAqICAgRmxvYXQzMkFycmF5ICAgICAgIHggNSw4ODcsOTEyIG9wcy9zZWMgXHUwMEIxMS40NiUgKDgyIHJ1bnMgc2FtcGxlZClcbiAgKiAgIFVpbnQzMkFycmF5ICAgICAgICB4IDYsNDkxLDY2MSBvcHMvc2VjIFx1MDBCMTEuNzYlICg3OSBydW5zIHNhbXBsZWQpXG4gICogICBVaW50MTZBcnJheSAgICAgICAgeCA2LDU1OSw3OTUgb3BzL3NlYyBcdTAwQjExLjY3JSAoODIgcnVucyBzYW1wbGVkKVxuICAqICAgVWludDhBcnJheSAgICAgICAgIHggNiw0NjMsOTY2IG9wcy9zZWMgXHUwMEIxMS40MyUgKDg1IHJ1bnMgc2FtcGxlZClcbiAgKiAgIEludDMyQXJyYXkgICAgICAgICB4IDUsNjQxLDg0MSBvcHMvc2VjIFx1MDBCMTMuNDklICg4MSBydW5zIHNhbXBsZWQpXG4gICogICBJbnQxNkFycmF5ICAgICAgICAgeCA2LDU4Myw1MTEgb3BzL3NlYyBcdTAwQjExLjk4JSAoODAgcnVucyBzYW1wbGVkKVxuICAqICAgSW50OEFycmF5ICAgICAgICAgIHggNiw2MDYsMDc4IG9wcy9zZWMgXHUwMEIxMS43NCUgKDgxIHJ1bnMgc2FtcGxlZClcbiAgKiAgIFVpbnQ4Q2xhbXBlZEFycmF5ICB4IDYsNjAyLDIyNCBvcHMvc2VjIFx1MDBCMTEuNzclICg4MyBydW5zIHNhbXBsZWQpXG4gICovXG4gIHZhciBzdHJpbmdUYWcgPSAoc3ltYm9sVG9TdHJpbmdUYWdFeGlzdHMgJiYgb2JqW1N5bWJvbC50b1N0cmluZ1RhZ10pO1xuICBpZiAodHlwZW9mIHN0cmluZ1RhZyA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gc3RyaW5nVGFnO1xuICB9XG5cbiAgdmFyIG9ialByb3RvdHlwZSA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihvYmopO1xuICAvKiAhIFNwZWVkIG9wdGltaXNhdGlvblxuICAqIFByZTpcbiAgKiAgIHJlZ2V4IGxpdGVyYWwgICAgICB4IDEsNzcyLDM4NSBvcHMvc2VjIFx1MDBCMTEuODUlICg3NyBydW5zIHNhbXBsZWQpXG4gICogICByZWdleCBjb25zdHJ1Y3RvciAgeCAyLDE0Myw2MzQgb3BzL3NlYyBcdTAwQjEyLjQ2JSAoNzggcnVucyBzYW1wbGVkKVxuICAqIFBvc3Q6XG4gICogICByZWdleCBsaXRlcmFsICAgICAgeCAzLDkyOCwwMDkgb3BzL3NlYyBcdTAwQjEwLjY1JSAoNzggcnVucyBzYW1wbGVkKVxuICAqICAgcmVnZXggY29uc3RydWN0b3IgIHggMyw5MzEsMTA4IG9wcy9zZWMgXHUwMEIxMC41OCUgKDg0IHJ1bnMgc2FtcGxlZClcbiAgKi9cbiAgaWYgKG9ialByb3RvdHlwZSA9PT0gUmVnRXhwLnByb3RvdHlwZSkge1xuICAgIHJldHVybiAnUmVnRXhwJztcbiAgfVxuXG4gIC8qICEgU3BlZWQgb3B0aW1pc2F0aW9uXG4gICogUHJlOlxuICAqICAgZGF0ZSAgICAgICAgICAgICAgIHggMiwxMzAsMDc0IG9wcy9zZWMgXHUwMEIxNC40MiUgKDY4IHJ1bnMgc2FtcGxlZClcbiAgKiBQb3N0OlxuICAqICAgZGF0ZSAgICAgICAgICAgICAgIHggMyw5NTMsNzc5IG9wcy9zZWMgXHUwMEIxMS4zNSUgKDc3IHJ1bnMgc2FtcGxlZClcbiAgKi9cbiAgaWYgKG9ialByb3RvdHlwZSA9PT0gRGF0ZS5wcm90b3R5cGUpIHtcbiAgICByZXR1cm4gJ0RhdGUnO1xuICB9XG5cbiAgLyogISBTcGVjIENvbmZvcm1hbmNlXG4gICAqIChodHRwOi8vd3d3LmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wL2luZGV4Lmh0bWwjc2VjLXByb21pc2UucHJvdG90eXBlLUBAdG9zdHJpbmd0YWcpXG4gICAqIEVTNiQyNS40LjUuNCAtIFByb21pc2UucHJvdG90eXBlW0BAdG9TdHJpbmdUYWddIHNob3VsZCBiZSBcIlByb21pc2VcIjpcbiAgICogVGVzdDogYE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChQcm9taXNlLnJlc29sdmUoKSlgYFxuICAgKiAgLSBDaHJvbWUgPD00NyA9PT0gXCJbb2JqZWN0IE9iamVjdF1cIlxuICAgKiAgLSBFZGdlIDw9MjAgPT09IFwiW29iamVjdCBPYmplY3RdXCJcbiAgICogIC0gRmlyZWZveCAyOS1MYXRlc3QgPT09IFwiW29iamVjdCBQcm9taXNlXVwiXG4gICAqICAtIFNhZmFyaSA3LjEtTGF0ZXN0ID09PSBcIltvYmplY3QgUHJvbWlzZV1cIlxuICAgKi9cbiAgaWYgKHByb21pc2VFeGlzdHMgJiYgb2JqUHJvdG90eXBlID09PSBQcm9taXNlLnByb3RvdHlwZSkge1xuICAgIHJldHVybiAnUHJvbWlzZSc7XG4gIH1cblxuICAvKiAhIFNwZWVkIG9wdGltaXNhdGlvblxuICAqIFByZTpcbiAgKiAgIHNldCAgICAgICAgICAgICAgICB4IDIsMjIyLDE4NiBvcHMvc2VjIFx1MDBCMTEuMzElICg4MiBydW5zIHNhbXBsZWQpXG4gICogUG9zdDpcbiAgKiAgIHNldCAgICAgICAgICAgICAgICB4IDQsNTQ1LDg3OSBvcHMvc2VjIFx1MDBCMTEuMTMlICg4MyBydW5zIHNhbXBsZWQpXG4gICovXG4gIGlmIChzZXRFeGlzdHMgJiYgb2JqUHJvdG90eXBlID09PSBTZXQucHJvdG90eXBlKSB7XG4gICAgcmV0dXJuICdTZXQnO1xuICB9XG5cbiAgLyogISBTcGVlZCBvcHRpbWlzYXRpb25cbiAgKiBQcmU6XG4gICogICBtYXAgICAgICAgICAgICAgICAgeCAyLDM5Niw4NDIgb3BzL3NlYyBcdTAwQjExLjU5JSAoODEgcnVucyBzYW1wbGVkKVxuICAqIFBvc3Q6XG4gICogICBtYXAgICAgICAgICAgICAgICAgeCA0LDE4Myw5NDUgb3BzL3NlYyBcdTAwQjE2LjU5JSAoODIgcnVucyBzYW1wbGVkKVxuICAqL1xuICBpZiAobWFwRXhpc3RzICYmIG9ialByb3RvdHlwZSA9PT0gTWFwLnByb3RvdHlwZSkge1xuICAgIHJldHVybiAnTWFwJztcbiAgfVxuXG4gIC8qICEgU3BlZWQgb3B0aW1pc2F0aW9uXG4gICogUHJlOlxuICAqICAgd2Vha3NldCAgICAgICAgICAgIHggMSwzMjMsMjIwIG9wcy9zZWMgXHUwMEIxMi4xNyUgKDc2IHJ1bnMgc2FtcGxlZClcbiAgKiBQb3N0OlxuICAqICAgd2Vha3NldCAgICAgICAgICAgIHggNCwyMzcsNTEwIG9wcy9zZWMgXHUwMEIxMi4wMSUgKDc3IHJ1bnMgc2FtcGxlZClcbiAgKi9cbiAgaWYgKHdlYWtTZXRFeGlzdHMgJiYgb2JqUHJvdG90eXBlID09PSBXZWFrU2V0LnByb3RvdHlwZSkge1xuICAgIHJldHVybiAnV2Vha1NldCc7XG4gIH1cblxuICAvKiAhIFNwZWVkIG9wdGltaXNhdGlvblxuICAqIFByZTpcbiAgKiAgIHdlYWttYXAgICAgICAgICAgICB4IDEsNTAwLDI2MCBvcHMvc2VjIFx1MDBCMTIuMDIlICg3OCBydW5zIHNhbXBsZWQpXG4gICogUG9zdDpcbiAgKiAgIHdlYWttYXAgICAgICAgICAgICB4IDMsODgxLDM4NCBvcHMvc2VjIFx1MDBCMTEuNDUlICg4MiBydW5zIHNhbXBsZWQpXG4gICovXG4gIGlmICh3ZWFrTWFwRXhpc3RzICYmIG9ialByb3RvdHlwZSA9PT0gV2Vha01hcC5wcm90b3R5cGUpIHtcbiAgICByZXR1cm4gJ1dlYWtNYXAnO1xuICB9XG5cbiAgLyogISBTcGVjIENvbmZvcm1hbmNlXG4gICAqIChodHRwOi8vd3d3LmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wL2luZGV4Lmh0bWwjc2VjLWRhdGF2aWV3LnByb3RvdHlwZS1AQHRvc3RyaW5ndGFnKVxuICAgKiBFUzYkMjQuMi40LjIxIC0gRGF0YVZpZXcucHJvdG90eXBlW0BAdG9TdHJpbmdUYWddIHNob3VsZCBiZSBcIkRhdGFWaWV3XCI6XG4gICAqIFRlc3Q6IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobmV3IERhdGFWaWV3KG5ldyBBcnJheUJ1ZmZlcigxKSkpYGBcbiAgICogIC0gRWRnZSA8PTEzID09PSBcIltvYmplY3QgT2JqZWN0XVwiXG4gICAqL1xuICBpZiAoZGF0YVZpZXdFeGlzdHMgJiYgb2JqUHJvdG90eXBlID09PSBEYXRhVmlldy5wcm90b3R5cGUpIHtcbiAgICByZXR1cm4gJ0RhdGFWaWV3JztcbiAgfVxuXG4gIC8qICEgU3BlYyBDb25mb3JtYW5jZVxuICAgKiAoaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC9pbmRleC5odG1sI3NlYy0lbWFwaXRlcmF0b3Jwcm90b3R5cGUlLUBAdG9zdHJpbmd0YWcpXG4gICAqIEVTNiQyMy4xLjUuMi4yIC0gJU1hcEl0ZXJhdG9yUHJvdG90eXBlJVtAQHRvU3RyaW5nVGFnXSBzaG91bGQgYmUgXCJNYXAgSXRlcmF0b3JcIjpcbiAgICogVGVzdDogYE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChuZXcgTWFwKCkuZW50cmllcygpKWBgXG4gICAqICAtIEVkZ2UgPD0xMyA9PT0gXCJbb2JqZWN0IE9iamVjdF1cIlxuICAgKi9cbiAgaWYgKG1hcEV4aXN0cyAmJiBvYmpQcm90b3R5cGUgPT09IG1hcEl0ZXJhdG9yUHJvdG90eXBlKSB7XG4gICAgcmV0dXJuICdNYXAgSXRlcmF0b3InO1xuICB9XG5cbiAgLyogISBTcGVjIENvbmZvcm1hbmNlXG4gICAqIChodHRwOi8vd3d3LmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wL2luZGV4Lmh0bWwjc2VjLSVzZXRpdGVyYXRvcnByb3RvdHlwZSUtQEB0b3N0cmluZ3RhZylcbiAgICogRVM2JDIzLjIuNS4yLjIgLSAlU2V0SXRlcmF0b3JQcm90b3R5cGUlW0BAdG9TdHJpbmdUYWddIHNob3VsZCBiZSBcIlNldCBJdGVyYXRvclwiOlxuICAgKiBUZXN0OiBgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG5ldyBTZXQoKS5lbnRyaWVzKCkpYGBcbiAgICogIC0gRWRnZSA8PTEzID09PSBcIltvYmplY3QgT2JqZWN0XVwiXG4gICAqL1xuICBpZiAoc2V0RXhpc3RzICYmIG9ialByb3RvdHlwZSA9PT0gc2V0SXRlcmF0b3JQcm90b3R5cGUpIHtcbiAgICByZXR1cm4gJ1NldCBJdGVyYXRvcic7XG4gIH1cblxuICAvKiAhIFNwZWMgQ29uZm9ybWFuY2VcbiAgICogKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvaW5kZXguaHRtbCNzZWMtJWFycmF5aXRlcmF0b3Jwcm90b3R5cGUlLUBAdG9zdHJpbmd0YWcpXG4gICAqIEVTNiQyMi4xLjUuMi4yIC0gJUFycmF5SXRlcmF0b3JQcm90b3R5cGUlW0BAdG9TdHJpbmdUYWddIHNob3VsZCBiZSBcIkFycmF5IEl0ZXJhdG9yXCI6XG4gICAqIFRlc3Q6IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoW11bU3ltYm9sLml0ZXJhdG9yXSgpKWBgXG4gICAqICAtIEVkZ2UgPD0xMyA9PT0gXCJbb2JqZWN0IE9iamVjdF1cIlxuICAgKi9cbiAgaWYgKGFycmF5SXRlcmF0b3JFeGlzdHMgJiYgb2JqUHJvdG90eXBlID09PSBhcnJheUl0ZXJhdG9yUHJvdG90eXBlKSB7XG4gICAgcmV0dXJuICdBcnJheSBJdGVyYXRvcic7XG4gIH1cblxuICAvKiAhIFNwZWMgQ29uZm9ybWFuY2VcbiAgICogKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvaW5kZXguaHRtbCNzZWMtJXN0cmluZ2l0ZXJhdG9ycHJvdG90eXBlJS1AQHRvc3RyaW5ndGFnKVxuICAgKiBFUzYkMjEuMS41LjIuMiAtICVTdHJpbmdJdGVyYXRvclByb3RvdHlwZSVbQEB0b1N0cmluZ1RhZ10gc2hvdWxkIGJlIFwiU3RyaW5nIEl0ZXJhdG9yXCI6XG4gICAqIFRlc3Q6IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoJydbU3ltYm9sLml0ZXJhdG9yXSgpKWBgXG4gICAqICAtIEVkZ2UgPD0xMyA9PT0gXCJbb2JqZWN0IE9iamVjdF1cIlxuICAgKi9cbiAgaWYgKHN0cmluZ0l0ZXJhdG9yRXhpc3RzICYmIG9ialByb3RvdHlwZSA9PT0gc3RyaW5nSXRlcmF0b3JQcm90b3R5cGUpIHtcbiAgICByZXR1cm4gJ1N0cmluZyBJdGVyYXRvcic7XG4gIH1cblxuICAvKiAhIFNwZWVkIG9wdGltaXNhdGlvblxuICAqIFByZTpcbiAgKiAgIG9iamVjdCBmcm9tIG51bGwgICB4IDIsNDI0LDMyMCBvcHMvc2VjIFx1MDBCMTEuNjclICg3NiBydW5zIHNhbXBsZWQpXG4gICogUG9zdDpcbiAgKiAgIG9iamVjdCBmcm9tIG51bGwgICB4IDUsODM4LDAwMCBvcHMvc2VjIFx1MDBCMTAuOTklICg4NCBydW5zIHNhbXBsZWQpXG4gICovXG4gIGlmIChvYmpQcm90b3R5cGUgPT09IG51bGwpIHtcbiAgICByZXR1cm4gJ09iamVjdCc7XG4gIH1cblxuICByZXR1cm4gT2JqZWN0XG4gICAgLnByb3RvdHlwZVxuICAgIC50b1N0cmluZ1xuICAgIC5jYWxsKG9iailcbiAgICAuc2xpY2UodG9TdHJpbmdMZWZ0U2xpY2VMZW5ndGgsIHRvU3RyaW5nUmlnaHRTbGljZUxlbmd0aCk7XG59XG5cbnJldHVybiB0eXBlRGV0ZWN0O1xuXG59KSkpO1xuIiwgIi8qIVxuICogQ2hhaSAtIGV4cGVjdFR5cGVzIHV0aWxpdHlcbiAqIENvcHlyaWdodChjKSAyMDEyLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG4vKipcbiAqICMjIyAuZXhwZWN0VHlwZXMob2JqLCB0eXBlcylcbiAqXG4gKiBFbnN1cmVzIHRoYXQgdGhlIG9iamVjdCBiZWluZyB0ZXN0ZWQgYWdhaW5zdCBpcyBvZiBhIHZhbGlkIHR5cGUuXG4gKlxuICogICAgIHV0aWxzLmV4cGVjdFR5cGVzKHRoaXMsIFsnYXJyYXknLCAnb2JqZWN0JywgJ3N0cmluZyddKTtcbiAqXG4gKiBAcGFyYW0ge01peGVkfSBvYmogY29uc3RydWN0ZWQgQXNzZXJ0aW9uXG4gKiBAcGFyYW0ge0FycmF5fSB0eXBlIEEgbGlzdCBvZiBhbGxvd2VkIHR5cGVzIGZvciB0aGlzIGFzc2VydGlvblxuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQG5hbWUgZXhwZWN0VHlwZXNcbiAqIEBhcGkgcHVibGljXG4gKi9cblxudmFyIEFzc2VydGlvbkVycm9yID0gcmVxdWlyZSgnYXNzZXJ0aW9uLWVycm9yJyk7XG52YXIgZmxhZyA9IHJlcXVpcmUoJy4vZmxhZycpO1xudmFyIHR5cGUgPSByZXF1aXJlKCd0eXBlLWRldGVjdCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGV4cGVjdFR5cGVzKG9iaiwgdHlwZXMpIHtcbiAgdmFyIGZsYWdNc2cgPSBmbGFnKG9iaiwgJ21lc3NhZ2UnKTtcbiAgdmFyIHNzZmkgPSBmbGFnKG9iaiwgJ3NzZmknKTtcblxuICBmbGFnTXNnID0gZmxhZ01zZyA/IGZsYWdNc2cgKyAnOiAnIDogJyc7XG5cbiAgb2JqID0gZmxhZyhvYmosICdvYmplY3QnKTtcbiAgdHlwZXMgPSB0eXBlcy5tYXAoZnVuY3Rpb24gKHQpIHsgcmV0dXJuIHQudG9Mb3dlckNhc2UoKTsgfSk7XG4gIHR5cGVzLnNvcnQoKTtcblxuICAvLyBUcmFuc2Zvcm1zIFsnbG9yZW0nLCAnaXBzdW0nXSBpbnRvICdhIGxvcmVtLCBvciBhbiBpcHN1bSdcbiAgdmFyIHN0ciA9IHR5cGVzLm1hcChmdW5jdGlvbiAodCwgaW5kZXgpIHtcbiAgICB2YXIgYXJ0ID0gflsgJ2EnLCAnZScsICdpJywgJ28nLCAndScgXS5pbmRleE9mKHQuY2hhckF0KDApKSA/ICdhbicgOiAnYSc7XG4gICAgdmFyIG9yID0gdHlwZXMubGVuZ3RoID4gMSAmJiBpbmRleCA9PT0gdHlwZXMubGVuZ3RoIC0gMSA/ICdvciAnIDogJyc7XG4gICAgcmV0dXJuIG9yICsgYXJ0ICsgJyAnICsgdDtcbiAgfSkuam9pbignLCAnKTtcblxuICB2YXIgb2JqVHlwZSA9IHR5cGUob2JqKS50b0xvd2VyQ2FzZSgpO1xuXG4gIGlmICghdHlwZXMuc29tZShmdW5jdGlvbiAoZXhwZWN0ZWQpIHsgcmV0dXJuIG9ialR5cGUgPT09IGV4cGVjdGVkOyB9KSkge1xuICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihcbiAgICAgIGZsYWdNc2cgKyAnb2JqZWN0IHRlc3RlZCBtdXN0IGJlICcgKyBzdHIgKyAnLCBidXQgJyArIG9ialR5cGUgKyAnIGdpdmVuJyxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHNzZmlcbiAgICApO1xuICB9XG59O1xuIiwgIi8qIVxuICogQ2hhaSAtIGdldEFjdHVhbCB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyoqXG4gKiAjIyMgLmdldEFjdHVhbChvYmplY3QsIFthY3R1YWxdKVxuICpcbiAqIFJldHVybnMgdGhlIGBhY3R1YWxgIHZhbHVlIGZvciBhbiBBc3NlcnRpb24uXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCAoY29uc3RydWN0ZWQgQXNzZXJ0aW9uKVxuICogQHBhcmFtIHtBcmd1bWVudHN9IGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZS5hc3NlcnQgYXJndW1lbnRzXG4gKiBAbmFtZXNwYWNlIFV0aWxzXG4gKiBAbmFtZSBnZXRBY3R1YWxcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGdldEFjdHVhbChvYmosIGFyZ3MpIHtcbiAgcmV0dXJuIGFyZ3MubGVuZ3RoID4gNCA/IGFyZ3NbNF0gOiBvYmouX29iajtcbn07XG4iLCAiJ3VzZSBzdHJpY3QnO1xuXG4vKiAhXG4gKiBDaGFpIC0gZ2V0RnVuY05hbWUgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNiBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbi8qKlxuICogIyMjIC5nZXRGdW5jTmFtZShjb25zdHJ1Y3RvckZuKVxuICpcbiAqIFJldHVybnMgdGhlIG5hbWUgb2YgYSBmdW5jdGlvbi5cbiAqIFdoZW4gYSBub24tZnVuY3Rpb24gaW5zdGFuY2UgaXMgcGFzc2VkLCByZXR1cm5zIGBudWxsYC5cbiAqIFRoaXMgYWxzbyBpbmNsdWRlcyBhIHBvbHlmaWxsIGZ1bmN0aW9uIGlmIGBhRnVuYy5uYW1lYCBpcyBub3QgZGVmaW5lZC5cbiAqXG4gKiBAbmFtZSBnZXRGdW5jTmFtZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuY3RcbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBhcGkgcHVibGljXG4gKi9cblxudmFyIHRvU3RyaW5nID0gRnVuY3Rpb24ucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIGZ1bmN0aW9uTmFtZU1hdGNoID0gL1xccypmdW5jdGlvbig/Olxcc3xcXHMqXFwvXFwqW14oPzoqXFwvKV0rXFwqXFwvXFxzKikqKFteXFxzXFwoXFwvXSspLztcbnZhciBtYXhGdW5jdGlvblNvdXJjZUxlbmd0aCA9IDUxMjtcbmZ1bmN0aW9uIGdldEZ1bmNOYW1lKGFGdW5jKSB7XG4gIGlmICh0eXBlb2YgYUZ1bmMgIT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHZhciBuYW1lID0gJyc7XG4gIGlmICh0eXBlb2YgRnVuY3Rpb24ucHJvdG90eXBlLm5hbWUgPT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBhRnVuYy5uYW1lID09PSAndW5kZWZpbmVkJykge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBwcmVmZXItcmVmbGVjdFxuICAgIHZhciBmdW5jdGlvblNvdXJjZSA9IHRvU3RyaW5nLmNhbGwoYUZ1bmMpO1xuICAgIC8vIFRvIGF2b2lkIHVuY29uc3RyYWluZWQgcmVzb3VyY2UgY29uc3VtcHRpb24gZHVlIHRvIHBhdGhhbG9naWNhbGx5IGxhcmdlIGZ1bmN0aW9uIG5hbWVzLFxuICAgIC8vIHdlIGxpbWl0IHRoZSBhdmFpbGFibGUgcmV0dXJuIHZhbHVlIHRvIGJlIGxlc3MgdGhhbiA1MTIgY2hhcmFjdGVycy5cbiAgICBpZiAoZnVuY3Rpb25Tb3VyY2UuaW5kZXhPZignKCcpID4gbWF4RnVuY3Rpb25Tb3VyY2VMZW5ndGgpIHtcbiAgICAgIHJldHVybiBuYW1lO1xuICAgIH1cbiAgICAvLyBIZXJlIHdlIHJ1biBhIHBvbHlmaWxsIGlmIEZ1bmN0aW9uIGRvZXMgbm90IHN1cHBvcnQgdGhlIGBuYW1lYCBwcm9wZXJ0eSBhbmQgaWYgYUZ1bmMubmFtZSBpcyBub3QgZGVmaW5lZFxuICAgIHZhciBtYXRjaCA9IGZ1bmN0aW9uU291cmNlLm1hdGNoKGZ1bmN0aW9uTmFtZU1hdGNoKTtcbiAgICBpZiAobWF0Y2gpIHtcbiAgICAgIG5hbWUgPSBtYXRjaFsxXTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gSWYgd2UndmUgZ290IGEgYG5hbWVgIHByb3BlcnR5IHdlIGp1c3QgdXNlIGl0XG4gICAgbmFtZSA9IGFGdW5jLm5hbWU7XG4gIH1cblxuICByZXR1cm4gbmFtZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRGdW5jTmFtZTtcbiIsICIoZnVuY3Rpb24gKGdsb2JhbCwgZmFjdG9yeSkge1xuICB0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgPyBmYWN0b3J5KGV4cG9ydHMpIDpcbiAgdHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kID8gZGVmaW5lKFsnZXhwb3J0cyddLCBmYWN0b3J5KSA6XG4gIChnbG9iYWwgPSB0eXBlb2YgZ2xvYmFsVGhpcyAhPT0gJ3VuZGVmaW5lZCcgPyBnbG9iYWxUaGlzIDogZ2xvYmFsIHx8IHNlbGYsIGZhY3RvcnkoZ2xvYmFsLmxvdXBlID0ge30pKTtcbn0odGhpcywgKGZ1bmN0aW9uIChleHBvcnRzKSB7ICd1c2Ugc3RyaWN0JztcblxuICBmdW5jdGlvbiBfdHlwZW9mKG9iaikge1xuICAgIFwiQGJhYmVsL2hlbHBlcnMgLSB0eXBlb2ZcIjtcblxuICAgIGlmICh0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gXCJzeW1ib2xcIikge1xuICAgICAgX3R5cGVvZiA9IGZ1bmN0aW9uIChvYmopIHtcbiAgICAgICAgcmV0dXJuIHR5cGVvZiBvYmo7XG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBfdHlwZW9mID0gZnVuY3Rpb24gKG9iaikge1xuICAgICAgICByZXR1cm4gb2JqICYmIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvYmouY29uc3RydWN0b3IgPT09IFN5bWJvbCAmJiBvYmogIT09IFN5bWJvbC5wcm90b3R5cGUgPyBcInN5bWJvbFwiIDogdHlwZW9mIG9iajtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIF90eXBlb2Yob2JqKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIF9zbGljZWRUb0FycmF5KGFyciwgaSkge1xuICAgIHJldHVybiBfYXJyYXlXaXRoSG9sZXMoYXJyKSB8fCBfaXRlcmFibGVUb0FycmF5TGltaXQoYXJyLCBpKSB8fCBfdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkoYXJyLCBpKSB8fCBfbm9uSXRlcmFibGVSZXN0KCk7XG4gIH1cblxuICBmdW5jdGlvbiBfYXJyYXlXaXRoSG9sZXMoYXJyKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoYXJyKSkgcmV0dXJuIGFycjtcbiAgfVxuXG4gIGZ1bmN0aW9uIF9pdGVyYWJsZVRvQXJyYXlMaW1pdChhcnIsIGkpIHtcbiAgICBpZiAodHlwZW9mIFN5bWJvbCA9PT0gXCJ1bmRlZmluZWRcIiB8fCAhKFN5bWJvbC5pdGVyYXRvciBpbiBPYmplY3QoYXJyKSkpIHJldHVybjtcbiAgICB2YXIgX2FyciA9IFtdO1xuICAgIHZhciBfbiA9IHRydWU7XG4gICAgdmFyIF9kID0gZmFsc2U7XG4gICAgdmFyIF9lID0gdW5kZWZpbmVkO1xuXG4gICAgdHJ5IHtcbiAgICAgIGZvciAodmFyIF9pID0gYXJyW1N5bWJvbC5pdGVyYXRvcl0oKSwgX3M7ICEoX24gPSAoX3MgPSBfaS5uZXh0KCkpLmRvbmUpOyBfbiA9IHRydWUpIHtcbiAgICAgICAgX2Fyci5wdXNoKF9zLnZhbHVlKTtcblxuICAgICAgICBpZiAoaSAmJiBfYXJyLmxlbmd0aCA9PT0gaSkgYnJlYWs7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBfZCA9IHRydWU7XG4gICAgICBfZSA9IGVycjtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKCFfbiAmJiBfaVtcInJldHVyblwiXSAhPSBudWxsKSBfaVtcInJldHVyblwiXSgpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgaWYgKF9kKSB0aHJvdyBfZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gX2FycjtcbiAgfVxuXG4gIGZ1bmN0aW9uIF91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheShvLCBtaW5MZW4pIHtcbiAgICBpZiAoIW8pIHJldHVybjtcbiAgICBpZiAodHlwZW9mIG8gPT09IFwic3RyaW5nXCIpIHJldHVybiBfYXJyYXlMaWtlVG9BcnJheShvLCBtaW5MZW4pO1xuICAgIHZhciBuID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG8pLnNsaWNlKDgsIC0xKTtcbiAgICBpZiAobiA9PT0gXCJPYmplY3RcIiAmJiBvLmNvbnN0cnVjdG9yKSBuID0gby5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgIGlmIChuID09PSBcIk1hcFwiIHx8IG4gPT09IFwiU2V0XCIpIHJldHVybiBBcnJheS5mcm9tKG8pO1xuICAgIGlmIChuID09PSBcIkFyZ3VtZW50c1wiIHx8IC9eKD86VWl8SSludCg/Ojh8MTZ8MzIpKD86Q2xhbXBlZCk/QXJyYXkkLy50ZXN0KG4pKSByZXR1cm4gX2FycmF5TGlrZVRvQXJyYXkobywgbWluTGVuKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIF9hcnJheUxpa2VUb0FycmF5KGFyciwgbGVuKSB7XG4gICAgaWYgKGxlbiA9PSBudWxsIHx8IGxlbiA+IGFyci5sZW5ndGgpIGxlbiA9IGFyci5sZW5ndGg7XG5cbiAgICBmb3IgKHZhciBpID0gMCwgYXJyMiA9IG5ldyBBcnJheShsZW4pOyBpIDwgbGVuOyBpKyspIGFycjJbaV0gPSBhcnJbaV07XG5cbiAgICByZXR1cm4gYXJyMjtcbiAgfVxuXG4gIGZ1bmN0aW9uIF9ub25JdGVyYWJsZVJlc3QoKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgYXR0ZW1wdCB0byBkZXN0cnVjdHVyZSBub24taXRlcmFibGUgaW5zdGFuY2UuXFxuSW4gb3JkZXIgdG8gYmUgaXRlcmFibGUsIG5vbi1hcnJheSBvYmplY3RzIG11c3QgaGF2ZSBhIFtTeW1ib2wuaXRlcmF0b3JdKCkgbWV0aG9kLlwiKTtcbiAgfVxuXG4gIHZhciBhbnNpQ29sb3JzID0ge1xuICAgIGJvbGQ6IFsnMScsICcyMiddLFxuICAgIGRpbTogWycyJywgJzIyJ10sXG4gICAgaXRhbGljOiBbJzMnLCAnMjMnXSxcbiAgICB1bmRlcmxpbmU6IFsnNCcsICcyNCddLFxuICAgIC8vIDUgJiA2IGFyZSBibGlua2luZ1xuICAgIGludmVyc2U6IFsnNycsICcyNyddLFxuICAgIGhpZGRlbjogWyc4JywgJzI4J10sXG4gICAgc3RyaWtlOiBbJzknLCAnMjknXSxcbiAgICAvLyAxMC0yMCBhcmUgZm9udHNcbiAgICAvLyAyMS0yOSBhcmUgcmVzZXRzIGZvciAxLTlcbiAgICBibGFjazogWyczMCcsICczOSddLFxuICAgIHJlZDogWyczMScsICczOSddLFxuICAgIGdyZWVuOiBbJzMyJywgJzM5J10sXG4gICAgeWVsbG93OiBbJzMzJywgJzM5J10sXG4gICAgYmx1ZTogWyczNCcsICczOSddLFxuICAgIG1hZ2VudGE6IFsnMzUnLCAnMzknXSxcbiAgICBjeWFuOiBbJzM2JywgJzM5J10sXG4gICAgd2hpdGU6IFsnMzcnLCAnMzknXSxcbiAgICBicmlnaHRibGFjazogWyczMDsxJywgJzM5J10sXG4gICAgYnJpZ2h0cmVkOiBbJzMxOzEnLCAnMzknXSxcbiAgICBicmlnaHRncmVlbjogWyczMjsxJywgJzM5J10sXG4gICAgYnJpZ2h0eWVsbG93OiBbJzMzOzEnLCAnMzknXSxcbiAgICBicmlnaHRibHVlOiBbJzM0OzEnLCAnMzknXSxcbiAgICBicmlnaHRtYWdlbnRhOiBbJzM1OzEnLCAnMzknXSxcbiAgICBicmlnaHRjeWFuOiBbJzM2OzEnLCAnMzknXSxcbiAgICBicmlnaHR3aGl0ZTogWyczNzsxJywgJzM5J10sXG4gICAgZ3JleTogWyc5MCcsICczOSddXG4gIH07XG4gIHZhciBzdHlsZXMgPSB7XG4gICAgc3BlY2lhbDogJ2N5YW4nLFxuICAgIG51bWJlcjogJ3llbGxvdycsXG4gICAgYmlnaW50OiAneWVsbG93JyxcbiAgICBib29sZWFuOiAneWVsbG93JyxcbiAgICB1bmRlZmluZWQ6ICdncmV5JyxcbiAgICBudWxsOiAnYm9sZCcsXG4gICAgc3RyaW5nOiAnZ3JlZW4nLFxuICAgIHN5bWJvbDogJ2dyZWVuJyxcbiAgICBkYXRlOiAnbWFnZW50YScsXG4gICAgcmVnZXhwOiAncmVkJ1xuICB9O1xuICB2YXIgdHJ1bmNhdG9yID0gJ1x1MjAyNic7XG5cbiAgZnVuY3Rpb24gY29sb3Jpc2UodmFsdWUsIHN0eWxlVHlwZSkge1xuICAgIHZhciBjb2xvciA9IGFuc2lDb2xvcnNbc3R5bGVzW3N0eWxlVHlwZV1dIHx8IGFuc2lDb2xvcnNbc3R5bGVUeXBlXTtcblxuICAgIGlmICghY29sb3IpIHtcbiAgICAgIHJldHVybiBTdHJpbmcodmFsdWUpO1xuICAgIH1cblxuICAgIHJldHVybiBcIlxceDFCW1wiLmNvbmNhdChjb2xvclswXSwgXCJtXCIpLmNvbmNhdChTdHJpbmcodmFsdWUpLCBcIlxceDFCW1wiKS5jb25jYXQoY29sb3JbMV0sIFwibVwiKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG5vcm1hbGlzZU9wdGlvbnMoKSB7XG4gICAgdmFyIF9yZWYgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IHt9LFxuICAgICAgICBfcmVmJHNob3dIaWRkZW4gPSBfcmVmLnNob3dIaWRkZW4sXG4gICAgICAgIHNob3dIaWRkZW4gPSBfcmVmJHNob3dIaWRkZW4gPT09IHZvaWQgMCA/IGZhbHNlIDogX3JlZiRzaG93SGlkZGVuLFxuICAgICAgICBfcmVmJGRlcHRoID0gX3JlZi5kZXB0aCxcbiAgICAgICAgZGVwdGggPSBfcmVmJGRlcHRoID09PSB2b2lkIDAgPyAyIDogX3JlZiRkZXB0aCxcbiAgICAgICAgX3JlZiRjb2xvcnMgPSBfcmVmLmNvbG9ycyxcbiAgICAgICAgY29sb3JzID0gX3JlZiRjb2xvcnMgPT09IHZvaWQgMCA/IGZhbHNlIDogX3JlZiRjb2xvcnMsXG4gICAgICAgIF9yZWYkY3VzdG9tSW5zcGVjdCA9IF9yZWYuY3VzdG9tSW5zcGVjdCxcbiAgICAgICAgY3VzdG9tSW5zcGVjdCA9IF9yZWYkY3VzdG9tSW5zcGVjdCA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9yZWYkY3VzdG9tSW5zcGVjdCxcbiAgICAgICAgX3JlZiRzaG93UHJveHkgPSBfcmVmLnNob3dQcm94eSxcbiAgICAgICAgc2hvd1Byb3h5ID0gX3JlZiRzaG93UHJveHkgPT09IHZvaWQgMCA/IGZhbHNlIDogX3JlZiRzaG93UHJveHksXG4gICAgICAgIF9yZWYkbWF4QXJyYXlMZW5ndGggPSBfcmVmLm1heEFycmF5TGVuZ3RoLFxuICAgICAgICBtYXhBcnJheUxlbmd0aCA9IF9yZWYkbWF4QXJyYXlMZW5ndGggPT09IHZvaWQgMCA/IEluZmluaXR5IDogX3JlZiRtYXhBcnJheUxlbmd0aCxcbiAgICAgICAgX3JlZiRicmVha0xlbmd0aCA9IF9yZWYuYnJlYWtMZW5ndGgsXG4gICAgICAgIGJyZWFrTGVuZ3RoID0gX3JlZiRicmVha0xlbmd0aCA9PT0gdm9pZCAwID8gSW5maW5pdHkgOiBfcmVmJGJyZWFrTGVuZ3RoLFxuICAgICAgICBfcmVmJHNlZW4gPSBfcmVmLnNlZW4sXG4gICAgICAgIHNlZW4gPSBfcmVmJHNlZW4gPT09IHZvaWQgMCA/IFtdIDogX3JlZiRzZWVuLFxuICAgICAgICBfcmVmJHRydW5jYXRlID0gX3JlZi50cnVuY2F0ZSxcbiAgICAgICAgdHJ1bmNhdGUgPSBfcmVmJHRydW5jYXRlID09PSB2b2lkIDAgPyBJbmZpbml0eSA6IF9yZWYkdHJ1bmNhdGUsXG4gICAgICAgIF9yZWYkc3R5bGl6ZSA9IF9yZWYuc3R5bGl6ZSxcbiAgICAgICAgc3R5bGl6ZSA9IF9yZWYkc3R5bGl6ZSA9PT0gdm9pZCAwID8gU3RyaW5nIDogX3JlZiRzdHlsaXplO1xuXG4gICAgdmFyIG9wdGlvbnMgPSB7XG4gICAgICBzaG93SGlkZGVuOiBCb29sZWFuKHNob3dIaWRkZW4pLFxuICAgICAgZGVwdGg6IE51bWJlcihkZXB0aCksXG4gICAgICBjb2xvcnM6IEJvb2xlYW4oY29sb3JzKSxcbiAgICAgIGN1c3RvbUluc3BlY3Q6IEJvb2xlYW4oY3VzdG9tSW5zcGVjdCksXG4gICAgICBzaG93UHJveHk6IEJvb2xlYW4oc2hvd1Byb3h5KSxcbiAgICAgIG1heEFycmF5TGVuZ3RoOiBOdW1iZXIobWF4QXJyYXlMZW5ndGgpLFxuICAgICAgYnJlYWtMZW5ndGg6IE51bWJlcihicmVha0xlbmd0aCksXG4gICAgICB0cnVuY2F0ZTogTnVtYmVyKHRydW5jYXRlKSxcbiAgICAgIHNlZW46IHNlZW4sXG4gICAgICBzdHlsaXplOiBzdHlsaXplXG4gICAgfTtcblxuICAgIGlmIChvcHRpb25zLmNvbG9ycykge1xuICAgICAgb3B0aW9ucy5zdHlsaXplID0gY29sb3Jpc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIG9wdGlvbnM7XG4gIH1cbiAgZnVuY3Rpb24gdHJ1bmNhdGUoc3RyaW5nLCBsZW5ndGgpIHtcbiAgICB2YXIgdGFpbCA9IGFyZ3VtZW50cy5sZW5ndGggPiAyICYmIGFyZ3VtZW50c1syXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzJdIDogdHJ1bmNhdG9yO1xuICAgIHN0cmluZyA9IFN0cmluZyhzdHJpbmcpO1xuICAgIHZhciB0YWlsTGVuZ3RoID0gdGFpbC5sZW5ndGg7XG4gICAgdmFyIHN0cmluZ0xlbmd0aCA9IHN0cmluZy5sZW5ndGg7XG5cbiAgICBpZiAodGFpbExlbmd0aCA+IGxlbmd0aCAmJiBzdHJpbmdMZW5ndGggPiB0YWlsTGVuZ3RoKSB7XG4gICAgICByZXR1cm4gdGFpbDtcbiAgICB9XG5cbiAgICBpZiAoc3RyaW5nTGVuZ3RoID4gbGVuZ3RoICYmIHN0cmluZ0xlbmd0aCA+IHRhaWxMZW5ndGgpIHtcbiAgICAgIHJldHVybiBcIlwiLmNvbmNhdChzdHJpbmcuc2xpY2UoMCwgbGVuZ3RoIC0gdGFpbExlbmd0aCkpLmNvbmNhdCh0YWlsKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc3RyaW5nO1xuICB9IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjb21wbGV4aXR5XG5cbiAgZnVuY3Rpb24gaW5zcGVjdExpc3QobGlzdCwgb3B0aW9ucywgaW5zcGVjdEl0ZW0pIHtcbiAgICB2YXIgc2VwYXJhdG9yID0gYXJndW1lbnRzLmxlbmd0aCA+IDMgJiYgYXJndW1lbnRzWzNdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbM10gOiAnLCAnO1xuICAgIGluc3BlY3RJdGVtID0gaW5zcGVjdEl0ZW0gfHwgb3B0aW9ucy5pbnNwZWN0O1xuICAgIHZhciBzaXplID0gbGlzdC5sZW5ndGg7XG4gICAgaWYgKHNpemUgPT09IDApIHJldHVybiAnJztcbiAgICB2YXIgb3JpZ2luYWxMZW5ndGggPSBvcHRpb25zLnRydW5jYXRlO1xuICAgIHZhciBvdXRwdXQgPSAnJztcbiAgICB2YXIgcGVlayA9ICcnO1xuICAgIHZhciB0cnVuY2F0ZWQgPSAnJztcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2l6ZTsgaSArPSAxKSB7XG4gICAgICB2YXIgbGFzdCA9IGkgKyAxID09PSBsaXN0Lmxlbmd0aDtcbiAgICAgIHZhciBzZWNvbmRUb0xhc3QgPSBpICsgMiA9PT0gbGlzdC5sZW5ndGg7XG4gICAgICB0cnVuY2F0ZWQgPSBcIlwiLmNvbmNhdCh0cnVuY2F0b3IsIFwiKFwiKS5jb25jYXQobGlzdC5sZW5ndGggLSBpLCBcIilcIik7XG4gICAgICB2YXIgdmFsdWUgPSBsaXN0W2ldOyAvLyBJZiB0aGVyZSBpcyBtb3JlIHRoYW4gb25lIHJlbWFpbmluZyB3ZSBuZWVkIHRvIGFjY291bnQgZm9yIGEgc2VwYXJhdG9yIG9mIGAsIGBcblxuICAgICAgb3B0aW9ucy50cnVuY2F0ZSA9IG9yaWdpbmFsTGVuZ3RoIC0gb3V0cHV0Lmxlbmd0aCAtIChsYXN0ID8gMCA6IHNlcGFyYXRvci5sZW5ndGgpO1xuICAgICAgdmFyIHN0cmluZyA9IHBlZWsgfHwgaW5zcGVjdEl0ZW0odmFsdWUsIG9wdGlvbnMpICsgKGxhc3QgPyAnJyA6IHNlcGFyYXRvcik7XG4gICAgICB2YXIgbmV4dExlbmd0aCA9IG91dHB1dC5sZW5ndGggKyBzdHJpbmcubGVuZ3RoO1xuICAgICAgdmFyIHRydW5jYXRlZExlbmd0aCA9IG5leHRMZW5ndGggKyB0cnVuY2F0ZWQubGVuZ3RoOyAvLyBJZiB0aGlzIGlzIHRoZSBsYXN0IGVsZW1lbnQsIGFuZCBhZGRpbmcgaXQgd291bGRcbiAgICAgIC8vIHRha2UgdXMgb3ZlciBsZW5ndGgsIGJ1dCBhZGRpbmcgdGhlIHRydW5jYXRvciB3b3VsZG4ndCAtIHRoZW4gYnJlYWsgbm93XG5cbiAgICAgIGlmIChsYXN0ICYmIG5leHRMZW5ndGggPiBvcmlnaW5hbExlbmd0aCAmJiBvdXRwdXQubGVuZ3RoICsgdHJ1bmNhdGVkLmxlbmd0aCA8PSBvcmlnaW5hbExlbmd0aCkge1xuICAgICAgICBicmVhaztcbiAgICAgIH0gLy8gSWYgdGhpcyBpc24ndCB0aGUgbGFzdCBvciBzZWNvbmQgdG8gbGFzdCBlbGVtZW50IHRvIHNjYW4sXG4gICAgICAvLyBidXQgdGhlIHN0cmluZyBpcyBhbHJlYWR5IG92ZXIgbGVuZ3RoIHRoZW4gYnJlYWsgaGVyZVxuXG5cbiAgICAgIGlmICghbGFzdCAmJiAhc2Vjb25kVG9MYXN0ICYmIHRydW5jYXRlZExlbmd0aCA+IG9yaWdpbmFsTGVuZ3RoKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfSAvLyBQZWVrIGF0IHRoZSBuZXh0IHN0cmluZyB0byBkZXRlcm1pbmUgaWYgd2Ugc2hvdWxkXG4gICAgICAvLyBicmVhayBlYXJseSBiZWZvcmUgYWRkaW5nIHRoaXMgaXRlbSB0byB0aGUgb3V0cHV0XG5cblxuICAgICAgcGVlayA9IGxhc3QgPyAnJyA6IGluc3BlY3RJdGVtKGxpc3RbaSArIDFdLCBvcHRpb25zKSArIChzZWNvbmRUb0xhc3QgPyAnJyA6IHNlcGFyYXRvcik7IC8vIElmIHdlIGhhdmUgb25lIGVsZW1lbnQgbGVmdCwgYnV0IHRoaXMgZWxlbWVudCBhbmRcbiAgICAgIC8vIHRoZSBuZXh0IHRha2VzIG92ZXIgbGVuZ3RoLCB0aGUgYnJlYWsgZWFybHlcblxuICAgICAgaWYgKCFsYXN0ICYmIHNlY29uZFRvTGFzdCAmJiB0cnVuY2F0ZWRMZW5ndGggPiBvcmlnaW5hbExlbmd0aCAmJiBuZXh0TGVuZ3RoICsgcGVlay5sZW5ndGggPiBvcmlnaW5hbExlbmd0aCkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgb3V0cHV0ICs9IHN0cmluZzsgLy8gSWYgdGhlIG5leHQgZWxlbWVudCB0YWtlcyB1cyB0byBsZW5ndGggLVxuICAgICAgLy8gYnV0IHRoZXJlIGFyZSBtb3JlIGFmdGVyIHRoYXQsIHRoZW4gd2Ugc2hvdWxkIHRydW5jYXRlIG5vd1xuXG4gICAgICBpZiAoIWxhc3QgJiYgIXNlY29uZFRvTGFzdCAmJiBuZXh0TGVuZ3RoICsgcGVlay5sZW5ndGggPj0gb3JpZ2luYWxMZW5ndGgpIHtcbiAgICAgICAgdHJ1bmNhdGVkID0gXCJcIi5jb25jYXQodHJ1bmNhdG9yLCBcIihcIikuY29uY2F0KGxpc3QubGVuZ3RoIC0gaSAtIDEsIFwiKVwiKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIHRydW5jYXRlZCA9ICcnO1xuICAgIH1cblxuICAgIHJldHVybiBcIlwiLmNvbmNhdChvdXRwdXQpLmNvbmNhdCh0cnVuY2F0ZWQpO1xuICB9XG5cbiAgZnVuY3Rpb24gcXVvdGVDb21wbGV4S2V5KGtleSkge1xuICAgIGlmIChrZXkubWF0Y2goL15bYS16QS1aX11bYS16QS1aXzAtOV0qJC8pKSB7XG4gICAgICByZXR1cm4ga2V5O1xuICAgIH1cblxuICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShrZXkpLnJlcGxhY2UoLycvZywgXCJcXFxcJ1wiKS5yZXBsYWNlKC9cXFxcXCIvZywgJ1wiJykucmVwbGFjZSgvKF5cInxcIiQpL2csIFwiJ1wiKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGluc3BlY3RQcm9wZXJ0eShfcmVmMiwgb3B0aW9ucykge1xuICAgIHZhciBfcmVmMyA9IF9zbGljZWRUb0FycmF5KF9yZWYyLCAyKSxcbiAgICAgICAga2V5ID0gX3JlZjNbMF0sXG4gICAgICAgIHZhbHVlID0gX3JlZjNbMV07XG5cbiAgICBvcHRpb25zLnRydW5jYXRlIC09IDI7XG5cbiAgICBpZiAodHlwZW9mIGtleSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGtleSA9IHF1b3RlQ29tcGxleEtleShrZXkpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGtleSAhPT0gJ251bWJlcicpIHtcbiAgICAgIGtleSA9IFwiW1wiLmNvbmNhdChvcHRpb25zLmluc3BlY3Qoa2V5LCBvcHRpb25zKSwgXCJdXCIpO1xuICAgIH1cblxuICAgIG9wdGlvbnMudHJ1bmNhdGUgLT0ga2V5Lmxlbmd0aDtcbiAgICB2YWx1ZSA9IG9wdGlvbnMuaW5zcGVjdCh2YWx1ZSwgb3B0aW9ucyk7XG4gICAgcmV0dXJuIFwiXCIuY29uY2F0KGtleSwgXCI6IFwiKS5jb25jYXQodmFsdWUpO1xuICB9XG5cbiAgZnVuY3Rpb24gaW5zcGVjdEFycmF5KGFycmF5LCBvcHRpb25zKSB7XG4gICAgLy8gT2JqZWN0LmtleXMgd2lsbCBhbHdheXMgb3V0cHV0IHRoZSBBcnJheSBpbmRpY2VzIGZpcnN0LCBzbyB3ZSBjYW4gc2xpY2UgYnlcbiAgICAvLyBgYXJyYXkubGVuZ3RoYCB0byBnZXQgbm9uLWluZGV4IHByb3BlcnRpZXNcbiAgICB2YXIgbm9uSW5kZXhQcm9wZXJ0aWVzID0gT2JqZWN0LmtleXMoYXJyYXkpLnNsaWNlKGFycmF5Lmxlbmd0aCk7XG4gICAgaWYgKCFhcnJheS5sZW5ndGggJiYgIW5vbkluZGV4UHJvcGVydGllcy5sZW5ndGgpIHJldHVybiAnW10nO1xuICAgIG9wdGlvbnMudHJ1bmNhdGUgLT0gNDtcbiAgICB2YXIgbGlzdENvbnRlbnRzID0gaW5zcGVjdExpc3QoYXJyYXksIG9wdGlvbnMpO1xuICAgIG9wdGlvbnMudHJ1bmNhdGUgLT0gbGlzdENvbnRlbnRzLmxlbmd0aDtcbiAgICB2YXIgcHJvcGVydHlDb250ZW50cyA9ICcnO1xuXG4gICAgaWYgKG5vbkluZGV4UHJvcGVydGllcy5sZW5ndGgpIHtcbiAgICAgIHByb3BlcnR5Q29udGVudHMgPSBpbnNwZWN0TGlzdChub25JbmRleFByb3BlcnRpZXMubWFwKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgcmV0dXJuIFtrZXksIGFycmF5W2tleV1dO1xuICAgICAgfSksIG9wdGlvbnMsIGluc3BlY3RQcm9wZXJ0eSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIFwiWyBcIi5jb25jYXQobGlzdENvbnRlbnRzKS5jb25jYXQocHJvcGVydHlDb250ZW50cyA/IFwiLCBcIi5jb25jYXQocHJvcGVydHlDb250ZW50cykgOiAnJywgXCIgXVwiKTtcbiAgfVxuXG4gIC8qICFcbiAgICogQ2hhaSAtIGdldEZ1bmNOYW1lIHV0aWxpdHlcbiAgICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNiBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAgICogTUlUIExpY2Vuc2VkXG4gICAqL1xuXG4gIC8qKlxuICAgKiAjIyMgLmdldEZ1bmNOYW1lKGNvbnN0cnVjdG9yRm4pXG4gICAqXG4gICAqIFJldHVybnMgdGhlIG5hbWUgb2YgYSBmdW5jdGlvbi5cbiAgICogV2hlbiBhIG5vbi1mdW5jdGlvbiBpbnN0YW5jZSBpcyBwYXNzZWQsIHJldHVybnMgYG51bGxgLlxuICAgKiBUaGlzIGFsc28gaW5jbHVkZXMgYSBwb2x5ZmlsbCBmdW5jdGlvbiBpZiBgYUZ1bmMubmFtZWAgaXMgbm90IGRlZmluZWQuXG4gICAqXG4gICAqIEBuYW1lIGdldEZ1bmNOYW1lXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmN0XG4gICAqIEBuYW1lc3BhY2UgVXRpbHNcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgdmFyIHRvU3RyaW5nID0gRnVuY3Rpb24ucHJvdG90eXBlLnRvU3RyaW5nO1xuICB2YXIgZnVuY3Rpb25OYW1lTWF0Y2ggPSAvXFxzKmZ1bmN0aW9uKD86XFxzfFxccypcXC9cXCpbXig/OipcXC8pXStcXCpcXC9cXHMqKSooW15cXHNcXChcXC9dKykvO1xuICB2YXIgbWF4RnVuY3Rpb25Tb3VyY2VMZW5ndGggPSA1MTI7XG4gIGZ1bmN0aW9uIGdldEZ1bmNOYW1lKGFGdW5jKSB7XG4gICAgaWYgKHR5cGVvZiBhRnVuYyAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgdmFyIG5hbWUgPSAnJztcbiAgICBpZiAodHlwZW9mIEZ1bmN0aW9uLnByb3RvdHlwZS5uYW1lID09PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgYUZ1bmMubmFtZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBwcmVmZXItcmVmbGVjdFxuICAgICAgdmFyIGZ1bmN0aW9uU291cmNlID0gdG9TdHJpbmcuY2FsbChhRnVuYyk7XG4gICAgICAvLyBUbyBhdm9pZCB1bmNvbnN0cmFpbmVkIHJlc291cmNlIGNvbnN1bXB0aW9uIGR1ZSB0byBwYXRoYWxvZ2ljYWxseSBsYXJnZSBmdW5jdGlvbiBuYW1lcyxcbiAgICAgIC8vIHdlIGxpbWl0IHRoZSBhdmFpbGFibGUgcmV0dXJuIHZhbHVlIHRvIGJlIGxlc3MgdGhhbiA1MTIgY2hhcmFjdGVycy5cbiAgICAgIGlmIChmdW5jdGlvblNvdXJjZS5pbmRleE9mKCcoJykgPiBtYXhGdW5jdGlvblNvdXJjZUxlbmd0aCkge1xuICAgICAgICByZXR1cm4gbmFtZTtcbiAgICAgIH1cbiAgICAgIC8vIEhlcmUgd2UgcnVuIGEgcG9seWZpbGwgaWYgRnVuY3Rpb24gZG9lcyBub3Qgc3VwcG9ydCB0aGUgYG5hbWVgIHByb3BlcnR5IGFuZCBpZiBhRnVuYy5uYW1lIGlzIG5vdCBkZWZpbmVkXG4gICAgICB2YXIgbWF0Y2ggPSBmdW5jdGlvblNvdXJjZS5tYXRjaChmdW5jdGlvbk5hbWVNYXRjaCk7XG4gICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgbmFtZSA9IG1hdGNoWzFdO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBJZiB3ZSd2ZSBnb3QgYSBgbmFtZWAgcHJvcGVydHkgd2UganVzdCB1c2UgaXRcbiAgICAgIG5hbWUgPSBhRnVuYy5uYW1lO1xuICAgIH1cblxuICAgIHJldHVybiBuYW1lO1xuICB9XG5cbiAgdmFyIGdldEZ1bmNOYW1lXzEgPSBnZXRGdW5jTmFtZTtcblxuICB2YXIgZ2V0QXJyYXlOYW1lID0gZnVuY3Rpb24gZ2V0QXJyYXlOYW1lKGFycmF5KSB7XG4gICAgLy8gV2UgbmVlZCB0byBzcGVjaWFsIGNhc2UgTm9kZS5qcycgQnVmZmVycywgd2hpY2ggcmVwb3J0IHRvIGJlIFVpbnQ4QXJyYXlcbiAgICBpZiAodHlwZW9mIEJ1ZmZlciA9PT0gJ2Z1bmN0aW9uJyAmJiBhcnJheSBpbnN0YW5jZW9mIEJ1ZmZlcikge1xuICAgICAgcmV0dXJuICdCdWZmZXInO1xuICAgIH1cblxuICAgIGlmIChhcnJheVtTeW1ib2wudG9TdHJpbmdUYWddKSB7XG4gICAgICByZXR1cm4gYXJyYXlbU3ltYm9sLnRvU3RyaW5nVGFnXTtcbiAgICB9XG5cbiAgICByZXR1cm4gZ2V0RnVuY05hbWVfMShhcnJheS5jb25zdHJ1Y3Rvcik7XG4gIH07XG5cbiAgZnVuY3Rpb24gaW5zcGVjdFR5cGVkQXJyYXkoYXJyYXksIG9wdGlvbnMpIHtcbiAgICB2YXIgbmFtZSA9IGdldEFycmF5TmFtZShhcnJheSk7XG4gICAgb3B0aW9ucy50cnVuY2F0ZSAtPSBuYW1lLmxlbmd0aCArIDQ7IC8vIE9iamVjdC5rZXlzIHdpbGwgYWx3YXlzIG91dHB1dCB0aGUgQXJyYXkgaW5kaWNlcyBmaXJzdCwgc28gd2UgY2FuIHNsaWNlIGJ5XG4gICAgLy8gYGFycmF5Lmxlbmd0aGAgdG8gZ2V0IG5vbi1pbmRleCBwcm9wZXJ0aWVzXG5cbiAgICB2YXIgbm9uSW5kZXhQcm9wZXJ0aWVzID0gT2JqZWN0LmtleXMoYXJyYXkpLnNsaWNlKGFycmF5Lmxlbmd0aCk7XG4gICAgaWYgKCFhcnJheS5sZW5ndGggJiYgIW5vbkluZGV4UHJvcGVydGllcy5sZW5ndGgpIHJldHVybiBcIlwiLmNvbmNhdChuYW1lLCBcIltdXCIpOyAvLyBBcyB3ZSBrbm93IFR5cGVkQXJyYXlzIG9ubHkgY29udGFpbiBVbnNpZ25lZCBJbnRlZ2Vycywgd2UgY2FuIHNraXAgaW5zcGVjdGluZyBlYWNoIG9uZSBhbmQgc2ltcGx5XG4gICAgLy8gc3R5bGlzZSB0aGUgdG9TdHJpbmcoKSB2YWx1ZSBvZiB0aGVtXG5cbiAgICB2YXIgb3V0cHV0ID0gJyc7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgc3RyaW5nID0gXCJcIi5jb25jYXQob3B0aW9ucy5zdHlsaXplKHRydW5jYXRlKGFycmF5W2ldLCBvcHRpb25zLnRydW5jYXRlKSwgJ251bWJlcicpKS5jb25jYXQoaSA9PT0gYXJyYXkubGVuZ3RoIC0gMSA/ICcnIDogJywgJyk7XG4gICAgICBvcHRpb25zLnRydW5jYXRlIC09IHN0cmluZy5sZW5ndGg7XG5cbiAgICAgIGlmIChhcnJheVtpXSAhPT0gYXJyYXkubGVuZ3RoICYmIG9wdGlvbnMudHJ1bmNhdGUgPD0gMykge1xuICAgICAgICBvdXRwdXQgKz0gXCJcIi5jb25jYXQodHJ1bmNhdG9yLCBcIihcIikuY29uY2F0KGFycmF5Lmxlbmd0aCAtIGFycmF5W2ldICsgMSwgXCIpXCIpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgb3V0cHV0ICs9IHN0cmluZztcbiAgICB9XG5cbiAgICB2YXIgcHJvcGVydHlDb250ZW50cyA9ICcnO1xuXG4gICAgaWYgKG5vbkluZGV4UHJvcGVydGllcy5sZW5ndGgpIHtcbiAgICAgIHByb3BlcnR5Q29udGVudHMgPSBpbnNwZWN0TGlzdChub25JbmRleFByb3BlcnRpZXMubWFwKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgcmV0dXJuIFtrZXksIGFycmF5W2tleV1dO1xuICAgICAgfSksIG9wdGlvbnMsIGluc3BlY3RQcm9wZXJ0eSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIFwiXCIuY29uY2F0KG5hbWUsIFwiWyBcIikuY29uY2F0KG91dHB1dCkuY29uY2F0KHByb3BlcnR5Q29udGVudHMgPyBcIiwgXCIuY29uY2F0KHByb3BlcnR5Q29udGVudHMpIDogJycsIFwiIF1cIik7XG4gIH1cblxuICBmdW5jdGlvbiBpbnNwZWN0RGF0ZShkYXRlT2JqZWN0LCBvcHRpb25zKSB7XG4gICAgdmFyIHN0cmluZ1JlcHJlc2VudGF0aW9uID0gZGF0ZU9iamVjdC50b0pTT04oKTtcblxuICAgIGlmIChzdHJpbmdSZXByZXNlbnRhdGlvbiA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuICdJbnZhbGlkIERhdGUnO1xuICAgIH1cblxuICAgIHZhciBzcGxpdCA9IHN0cmluZ1JlcHJlc2VudGF0aW9uLnNwbGl0KCdUJyk7XG4gICAgdmFyIGRhdGUgPSBzcGxpdFswXTsgLy8gSWYgd2UgbmVlZCB0byAtIHRydW5jYXRlIHRoZSB0aW1lIHBvcnRpb24sIGJ1dCBuZXZlciB0aGUgZGF0ZVxuXG4gICAgcmV0dXJuIG9wdGlvbnMuc3R5bGl6ZShcIlwiLmNvbmNhdChkYXRlLCBcIlRcIikuY29uY2F0KHRydW5jYXRlKHNwbGl0WzFdLCBvcHRpb25zLnRydW5jYXRlIC0gZGF0ZS5sZW5ndGggLSAxKSksICdkYXRlJyk7XG4gIH1cblxuICBmdW5jdGlvbiBpbnNwZWN0RnVuY3Rpb24oZnVuYywgb3B0aW9ucykge1xuICAgIHZhciBuYW1lID0gZ2V0RnVuY05hbWVfMShmdW5jKTtcblxuICAgIGlmICghbmFtZSkge1xuICAgICAgcmV0dXJuIG9wdGlvbnMuc3R5bGl6ZSgnW0Z1bmN0aW9uXScsICdzcGVjaWFsJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG9wdGlvbnMuc3R5bGl6ZShcIltGdW5jdGlvbiBcIi5jb25jYXQodHJ1bmNhdGUobmFtZSwgb3B0aW9ucy50cnVuY2F0ZSAtIDExKSwgXCJdXCIpLCAnc3BlY2lhbCcpO1xuICB9XG5cbiAgZnVuY3Rpb24gaW5zcGVjdE1hcEVudHJ5KF9yZWYsIG9wdGlvbnMpIHtcbiAgICB2YXIgX3JlZjIgPSBfc2xpY2VkVG9BcnJheShfcmVmLCAyKSxcbiAgICAgICAga2V5ID0gX3JlZjJbMF0sXG4gICAgICAgIHZhbHVlID0gX3JlZjJbMV07XG5cbiAgICBvcHRpb25zLnRydW5jYXRlIC09IDQ7XG4gICAga2V5ID0gb3B0aW9ucy5pbnNwZWN0KGtleSwgb3B0aW9ucyk7XG4gICAgb3B0aW9ucy50cnVuY2F0ZSAtPSBrZXkubGVuZ3RoO1xuICAgIHZhbHVlID0gb3B0aW9ucy5pbnNwZWN0KHZhbHVlLCBvcHRpb25zKTtcbiAgICByZXR1cm4gXCJcIi5jb25jYXQoa2V5LCBcIiA9PiBcIikuY29uY2F0KHZhbHVlKTtcbiAgfSAvLyBJRTExIGRvZXNuJ3Qgc3VwcG9ydCBgbWFwLmVudHJpZXMoKWBcblxuXG4gIGZ1bmN0aW9uIG1hcFRvRW50cmllcyhtYXApIHtcbiAgICB2YXIgZW50cmllcyA9IFtdO1xuICAgIG1hcC5mb3JFYWNoKGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG4gICAgICBlbnRyaWVzLnB1c2goW2tleSwgdmFsdWVdKTtcbiAgICB9KTtcbiAgICByZXR1cm4gZW50cmllcztcbiAgfVxuXG4gIGZ1bmN0aW9uIGluc3BlY3RNYXAobWFwLCBvcHRpb25zKSB7XG4gICAgdmFyIHNpemUgPSBtYXAuc2l6ZSAtIDE7XG5cbiAgICBpZiAoc2l6ZSA8PSAwKSB7XG4gICAgICByZXR1cm4gJ01hcHt9JztcbiAgICB9XG5cbiAgICBvcHRpb25zLnRydW5jYXRlIC09IDc7XG4gICAgcmV0dXJuIFwiTWFweyBcIi5jb25jYXQoaW5zcGVjdExpc3QobWFwVG9FbnRyaWVzKG1hcCksIG9wdGlvbnMsIGluc3BlY3RNYXBFbnRyeSksIFwiIH1cIik7XG4gIH1cblxuICB2YXIgaXNOYU4gPSBOdW1iZXIuaXNOYU4gfHwgZnVuY3Rpb24gKGkpIHtcbiAgICByZXR1cm4gaSAhPT0gaTtcbiAgfTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1zZWxmLWNvbXBhcmVcblxuXG4gIGZ1bmN0aW9uIGluc3BlY3ROdW1iZXIobnVtYmVyLCBvcHRpb25zKSB7XG4gICAgaWYgKGlzTmFOKG51bWJlcikpIHtcbiAgICAgIHJldHVybiBvcHRpb25zLnN0eWxpemUoJ05hTicsICdudW1iZXInKTtcbiAgICB9XG5cbiAgICBpZiAobnVtYmVyID09PSBJbmZpbml0eSkge1xuICAgICAgcmV0dXJuIG9wdGlvbnMuc3R5bGl6ZSgnSW5maW5pdHknLCAnbnVtYmVyJyk7XG4gICAgfVxuXG4gICAgaWYgKG51bWJlciA9PT0gLUluZmluaXR5KSB7XG4gICAgICByZXR1cm4gb3B0aW9ucy5zdHlsaXplKCctSW5maW5pdHknLCAnbnVtYmVyJyk7XG4gICAgfVxuXG4gICAgaWYgKG51bWJlciA9PT0gMCkge1xuICAgICAgcmV0dXJuIG9wdGlvbnMuc3R5bGl6ZSgxIC8gbnVtYmVyID09PSBJbmZpbml0eSA/ICcrMCcgOiAnLTAnLCAnbnVtYmVyJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG9wdGlvbnMuc3R5bGl6ZSh0cnVuY2F0ZShudW1iZXIsIG9wdGlvbnMudHJ1bmNhdGUpLCAnbnVtYmVyJyk7XG4gIH1cblxuICBmdW5jdGlvbiBpbnNwZWN0QmlnSW50KG51bWJlciwgb3B0aW9ucykge1xuICAgIHZhciBudW1zID0gdHJ1bmNhdGUobnVtYmVyLnRvU3RyaW5nKCksIG9wdGlvbnMudHJ1bmNhdGUgLSAxKTtcbiAgICBpZiAobnVtcyAhPT0gdHJ1bmNhdG9yKSBudW1zICs9ICduJztcbiAgICByZXR1cm4gb3B0aW9ucy5zdHlsaXplKG51bXMsICdiaWdpbnQnKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGluc3BlY3RSZWdFeHAodmFsdWUsIG9wdGlvbnMpIHtcbiAgICB2YXIgZmxhZ3MgPSB2YWx1ZS50b1N0cmluZygpLnNwbGl0KCcvJylbMl07XG4gICAgdmFyIHNvdXJjZUxlbmd0aCA9IG9wdGlvbnMudHJ1bmNhdGUgLSAoMiArIGZsYWdzLmxlbmd0aCk7XG4gICAgdmFyIHNvdXJjZSA9IHZhbHVlLnNvdXJjZTtcbiAgICByZXR1cm4gb3B0aW9ucy5zdHlsaXplKFwiL1wiLmNvbmNhdCh0cnVuY2F0ZShzb3VyY2UsIHNvdXJjZUxlbmd0aCksIFwiL1wiKS5jb25jYXQoZmxhZ3MpLCAncmVnZXhwJyk7XG4gIH1cblxuICBmdW5jdGlvbiBhcnJheUZyb21TZXQoc2V0KSB7XG4gICAgdmFyIHZhbHVlcyA9IFtdO1xuICAgIHNldC5mb3JFYWNoKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgdmFsdWVzLnB1c2godmFsdWUpO1xuICAgIH0pO1xuICAgIHJldHVybiB2YWx1ZXM7XG4gIH1cblxuICBmdW5jdGlvbiBpbnNwZWN0U2V0KHNldCwgb3B0aW9ucykge1xuICAgIGlmIChzZXQuc2l6ZSA9PT0gMCkgcmV0dXJuICdTZXR7fSc7XG4gICAgb3B0aW9ucy50cnVuY2F0ZSAtPSA3O1xuICAgIHJldHVybiBcIlNldHsgXCIuY29uY2F0KGluc3BlY3RMaXN0KGFycmF5RnJvbVNldChzZXQpLCBvcHRpb25zKSwgXCIgfVwiKTtcbiAgfVxuXG4gIHZhciBzdHJpbmdFc2NhcGVDaGFycyA9IG5ldyBSZWdFeHAoXCJbJ1xcXFx1MDAwMC1cXFxcdTAwMWZcXFxcdTAwN2YtXFxcXHUwMDlmXFxcXHUwMGFkXFxcXHUwNjAwLVxcXFx1MDYwNFxcXFx1MDcwZlxcXFx1MTdiNFxcXFx1MTdiNVwiICsgXCJcXFxcdTIwMGMtXFxcXHUyMDBmXFxcXHUyMDI4LVxcXFx1MjAyZlxcXFx1MjA2MC1cXFxcdTIwNmZcXFxcdWZlZmZcXFxcdWZmZjAtXFxcXHVmZmZmXVwiLCAnZycpO1xuICB2YXIgZXNjYXBlQ2hhcmFjdGVycyA9IHtcbiAgICAnXFxiJzogJ1xcXFxiJyxcbiAgICAnXFx0JzogJ1xcXFx0JyxcbiAgICAnXFxuJzogJ1xcXFxuJyxcbiAgICAnXFxmJzogJ1xcXFxmJyxcbiAgICAnXFxyJzogJ1xcXFxyJyxcbiAgICBcIidcIjogXCJcXFxcJ1wiLFxuICAgICdcXFxcJzogJ1xcXFxcXFxcJ1xuICB9O1xuICB2YXIgaGV4ID0gMTY7XG4gIHZhciB1bmljb2RlTGVuZ3RoID0gNDtcblxuICBmdW5jdGlvbiBlc2NhcGUoY2hhcikge1xuICAgIHJldHVybiBlc2NhcGVDaGFyYWN0ZXJzW2NoYXJdIHx8IFwiXFxcXHVcIi5jb25jYXQoXCIwMDAwXCIuY29uY2F0KGNoYXIuY2hhckNvZGVBdCgwKS50b1N0cmluZyhoZXgpKS5zbGljZSgtdW5pY29kZUxlbmd0aCkpO1xuICB9XG5cbiAgZnVuY3Rpb24gaW5zcGVjdFN0cmluZyhzdHJpbmcsIG9wdGlvbnMpIHtcbiAgICBpZiAoc3RyaW5nRXNjYXBlQ2hhcnMudGVzdChzdHJpbmcpKSB7XG4gICAgICBzdHJpbmcgPSBzdHJpbmcucmVwbGFjZShzdHJpbmdFc2NhcGVDaGFycywgZXNjYXBlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3B0aW9ucy5zdHlsaXplKFwiJ1wiLmNvbmNhdCh0cnVuY2F0ZShzdHJpbmcsIG9wdGlvbnMudHJ1bmNhdGUgLSAyKSwgXCInXCIpLCAnc3RyaW5nJyk7XG4gIH1cblxuICBmdW5jdGlvbiBpbnNwZWN0U3ltYm9sKHZhbHVlKSB7XG4gICAgaWYgKCdkZXNjcmlwdGlvbicgaW4gU3ltYm9sLnByb3RvdHlwZSkge1xuICAgICAgcmV0dXJuIHZhbHVlLmRlc2NyaXB0aW9uID8gXCJTeW1ib2woXCIuY29uY2F0KHZhbHVlLmRlc2NyaXB0aW9uLCBcIilcIikgOiAnU3ltYm9sKCknO1xuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZS50b1N0cmluZygpO1xuICB9XG5cbiAgdmFyIGdldFByb21pc2VWYWx1ZSA9IGZ1bmN0aW9uIGdldFByb21pc2VWYWx1ZSgpIHtcbiAgICByZXR1cm4gJ1Byb21pc2V7XHUyMDI2fSc7XG4gIH07XG5cbiAgdHJ5IHtcbiAgICB2YXIgX3Byb2Nlc3MkYmluZGluZyA9IHByb2Nlc3MuYmluZGluZygndXRpbCcpLFxuICAgICAgICBnZXRQcm9taXNlRGV0YWlscyA9IF9wcm9jZXNzJGJpbmRpbmcuZ2V0UHJvbWlzZURldGFpbHMsXG4gICAgICAgIGtQZW5kaW5nID0gX3Byb2Nlc3MkYmluZGluZy5rUGVuZGluZyxcbiAgICAgICAga1JlamVjdGVkID0gX3Byb2Nlc3MkYmluZGluZy5rUmVqZWN0ZWQ7XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShnZXRQcm9taXNlRGV0YWlscyhQcm9taXNlLnJlc29sdmUoKSkpKSB7XG4gICAgICBnZXRQcm9taXNlVmFsdWUgPSBmdW5jdGlvbiBnZXRQcm9taXNlVmFsdWUodmFsdWUsIG9wdGlvbnMpIHtcbiAgICAgICAgdmFyIF9nZXRQcm9taXNlRGV0YWlscyA9IGdldFByb21pc2VEZXRhaWxzKHZhbHVlKSxcbiAgICAgICAgICAgIF9nZXRQcm9taXNlRGV0YWlsczIgPSBfc2xpY2VkVG9BcnJheShfZ2V0UHJvbWlzZURldGFpbHMsIDIpLFxuICAgICAgICAgICAgc3RhdGUgPSBfZ2V0UHJvbWlzZURldGFpbHMyWzBdLFxuICAgICAgICAgICAgaW5uZXJWYWx1ZSA9IF9nZXRQcm9taXNlRGV0YWlsczJbMV07XG5cbiAgICAgICAgaWYgKHN0YXRlID09PSBrUGVuZGluZykge1xuICAgICAgICAgIHJldHVybiAnUHJvbWlzZXs8cGVuZGluZz59JztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBcIlByb21pc2VcIi5jb25jYXQoc3RhdGUgPT09IGtSZWplY3RlZCA/ICchJyA6ICcnLCBcIntcIikuY29uY2F0KG9wdGlvbnMuaW5zcGVjdChpbm5lclZhbHVlLCBvcHRpb25zKSwgXCJ9XCIpO1xuICAgICAgfTtcbiAgICB9XG4gIH0gY2F0Y2ggKG5vdE5vZGUpIHtcbiAgICAvKiBpZ25vcmUgKi9cbiAgfVxuXG4gIHZhciBpbnNwZWN0UHJvbWlzZSA9IGdldFByb21pc2VWYWx1ZTtcblxuICBmdW5jdGlvbiBpbnNwZWN0T2JqZWN0KG9iamVjdCwgb3B0aW9ucykge1xuICAgIHZhciBwcm9wZXJ0aWVzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMob2JqZWN0KTtcbiAgICB2YXIgc3ltYm9scyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPyBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKG9iamVjdCkgOiBbXTtcblxuICAgIGlmIChwcm9wZXJ0aWVzLmxlbmd0aCA9PT0gMCAmJiBzeW1ib2xzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuICd7fSc7XG4gICAgfVxuXG4gICAgb3B0aW9ucy50cnVuY2F0ZSAtPSA0O1xuICAgIG9wdGlvbnMuc2VlbiA9IG9wdGlvbnMuc2VlbiB8fCBbXTtcblxuICAgIGlmIChvcHRpb25zLnNlZW4uaW5kZXhPZihvYmplY3QpID49IDApIHtcbiAgICAgIHJldHVybiAnW0NpcmN1bGFyXSc7XG4gICAgfVxuXG4gICAgb3B0aW9ucy5zZWVuLnB1c2gob2JqZWN0KTtcbiAgICB2YXIgcHJvcGVydHlDb250ZW50cyA9IGluc3BlY3RMaXN0KHByb3BlcnRpZXMubWFwKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgIHJldHVybiBba2V5LCBvYmplY3Rba2V5XV07XG4gICAgfSksIG9wdGlvbnMsIGluc3BlY3RQcm9wZXJ0eSk7XG4gICAgdmFyIHN5bWJvbENvbnRlbnRzID0gaW5zcGVjdExpc3Qoc3ltYm9scy5tYXAoZnVuY3Rpb24gKGtleSkge1xuICAgICAgcmV0dXJuIFtrZXksIG9iamVjdFtrZXldXTtcbiAgICB9KSwgb3B0aW9ucywgaW5zcGVjdFByb3BlcnR5KTtcbiAgICBvcHRpb25zLnNlZW4ucG9wKCk7XG4gICAgdmFyIHNlcCA9ICcnO1xuXG4gICAgaWYgKHByb3BlcnR5Q29udGVudHMgJiYgc3ltYm9sQ29udGVudHMpIHtcbiAgICAgIHNlcCA9ICcsICc7XG4gICAgfVxuXG4gICAgcmV0dXJuIFwieyBcIi5jb25jYXQocHJvcGVydHlDb250ZW50cykuY29uY2F0KHNlcCkuY29uY2F0KHN5bWJvbENvbnRlbnRzLCBcIiB9XCIpO1xuICB9XG5cbiAgdmFyIHRvU3RyaW5nVGFnID0gdHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvU3RyaW5nVGFnID8gU3ltYm9sLnRvU3RyaW5nVGFnIDogZmFsc2U7XG4gIGZ1bmN0aW9uIGluc3BlY3RDbGFzcyh2YWx1ZSwgb3B0aW9ucykge1xuICAgIHZhciBuYW1lID0gJyc7XG5cbiAgICBpZiAodG9TdHJpbmdUYWcgJiYgdG9TdHJpbmdUYWcgaW4gdmFsdWUpIHtcbiAgICAgIG5hbWUgPSB2YWx1ZVt0b1N0cmluZ1RhZ107XG4gICAgfVxuXG4gICAgbmFtZSA9IG5hbWUgfHwgZ2V0RnVuY05hbWVfMSh2YWx1ZS5jb25zdHJ1Y3Rvcik7IC8vIEJhYmVsIHRyYW5zZm9ybXMgYW5vbnltb3VzIGNsYXNzZXMgdG8gdGhlIG5hbWUgYF9jbGFzc2BcblxuICAgIGlmICghbmFtZSB8fCBuYW1lID09PSAnX2NsYXNzJykge1xuICAgICAgbmFtZSA9ICc8QW5vbnltb3VzIENsYXNzPic7XG4gICAgfVxuXG4gICAgb3B0aW9ucy50cnVuY2F0ZSAtPSBuYW1lLmxlbmd0aDtcbiAgICByZXR1cm4gXCJcIi5jb25jYXQobmFtZSkuY29uY2F0KGluc3BlY3RPYmplY3QodmFsdWUsIG9wdGlvbnMpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGluc3BlY3RBcmd1bWVudHMoYXJncywgb3B0aW9ucykge1xuICAgIGlmIChhcmdzLmxlbmd0aCA9PT0gMCkgcmV0dXJuICdBcmd1bWVudHNbXSc7XG4gICAgb3B0aW9ucy50cnVuY2F0ZSAtPSAxMztcbiAgICByZXR1cm4gXCJBcmd1bWVudHNbIFwiLmNvbmNhdChpbnNwZWN0TGlzdChhcmdzLCBvcHRpb25zKSwgXCIgXVwiKTtcbiAgfVxuXG4gIHZhciBlcnJvcktleXMgPSBbJ3N0YWNrJywgJ2xpbmUnLCAnY29sdW1uJywgJ25hbWUnLCAnbWVzc2FnZScsICdmaWxlTmFtZScsICdsaW5lTnVtYmVyJywgJ2NvbHVtbk51bWJlcicsICdudW1iZXInLCAnZGVzY3JpcHRpb24nXTtcbiAgZnVuY3Rpb24gaW5zcGVjdE9iamVjdCQxKGVycm9yLCBvcHRpb25zKSB7XG4gICAgdmFyIHByb3BlcnRpZXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhlcnJvcikuZmlsdGVyKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgIHJldHVybiBlcnJvcktleXMuaW5kZXhPZihrZXkpID09PSAtMTtcbiAgICB9KTtcbiAgICB2YXIgbmFtZSA9IGVycm9yLm5hbWU7XG4gICAgb3B0aW9ucy50cnVuY2F0ZSAtPSBuYW1lLmxlbmd0aDtcbiAgICB2YXIgbWVzc2FnZSA9ICcnO1xuXG4gICAgaWYgKHR5cGVvZiBlcnJvci5tZXNzYWdlID09PSAnc3RyaW5nJykge1xuICAgICAgbWVzc2FnZSA9IHRydW5jYXRlKGVycm9yLm1lc3NhZ2UsIG9wdGlvbnMudHJ1bmNhdGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBwcm9wZXJ0aWVzLnVuc2hpZnQoJ21lc3NhZ2UnKTtcbiAgICB9XG5cbiAgICBtZXNzYWdlID0gbWVzc2FnZSA/IFwiOiBcIi5jb25jYXQobWVzc2FnZSkgOiAnJztcbiAgICBvcHRpb25zLnRydW5jYXRlIC09IG1lc3NhZ2UubGVuZ3RoICsgNTtcbiAgICB2YXIgcHJvcGVydHlDb250ZW50cyA9IGluc3BlY3RMaXN0KHByb3BlcnRpZXMubWFwKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgIHJldHVybiBba2V5LCBlcnJvcltrZXldXTtcbiAgICB9KSwgb3B0aW9ucywgaW5zcGVjdFByb3BlcnR5KTtcbiAgICByZXR1cm4gXCJcIi5jb25jYXQobmFtZSkuY29uY2F0KG1lc3NhZ2UpLmNvbmNhdChwcm9wZXJ0eUNvbnRlbnRzID8gXCIgeyBcIi5jb25jYXQocHJvcGVydHlDb250ZW50cywgXCIgfVwiKSA6ICcnKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGluc3BlY3RBdHRyaWJ1dGUoX3JlZiwgb3B0aW9ucykge1xuICAgIHZhciBfcmVmMiA9IF9zbGljZWRUb0FycmF5KF9yZWYsIDIpLFxuICAgICAgICBrZXkgPSBfcmVmMlswXSxcbiAgICAgICAgdmFsdWUgPSBfcmVmMlsxXTtcblxuICAgIG9wdGlvbnMudHJ1bmNhdGUgLT0gMztcblxuICAgIGlmICghdmFsdWUpIHtcbiAgICAgIHJldHVybiBcIlwiLmNvbmNhdChvcHRpb25zLnN0eWxpemUoa2V5LCAneWVsbG93JykpO1xuICAgIH1cblxuICAgIHJldHVybiBcIlwiLmNvbmNhdChvcHRpb25zLnN0eWxpemUoa2V5LCAneWVsbG93JyksIFwiPVwiKS5jb25jYXQob3B0aW9ucy5zdHlsaXplKFwiXFxcIlwiLmNvbmNhdCh2YWx1ZSwgXCJcXFwiXCIpLCAnc3RyaW5nJykpO1xuICB9XG4gIGZ1bmN0aW9uIGluc3BlY3RIVE1MQ29sbGVjdGlvbihjb2xsZWN0aW9uLCBvcHRpb25zKSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVzZS1iZWZvcmUtZGVmaW5lXG4gICAgcmV0dXJuIGluc3BlY3RMaXN0KGNvbGxlY3Rpb24sIG9wdGlvbnMsIGluc3BlY3RIVE1MLCAnXFxuJyk7XG4gIH1cbiAgZnVuY3Rpb24gaW5zcGVjdEhUTUwoZWxlbWVudCwgb3B0aW9ucykge1xuICAgIHZhciBwcm9wZXJ0aWVzID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVOYW1lcygpO1xuICAgIHZhciBuYW1lID0gZWxlbWVudC50YWdOYW1lLnRvTG93ZXJDYXNlKCk7XG4gICAgdmFyIGhlYWQgPSBvcHRpb25zLnN0eWxpemUoXCI8XCIuY29uY2F0KG5hbWUpLCAnc3BlY2lhbCcpO1xuICAgIHZhciBoZWFkQ2xvc2UgPSBvcHRpb25zLnN0eWxpemUoXCI+XCIsICdzcGVjaWFsJyk7XG4gICAgdmFyIHRhaWwgPSBvcHRpb25zLnN0eWxpemUoXCI8L1wiLmNvbmNhdChuYW1lLCBcIj5cIiksICdzcGVjaWFsJyk7XG4gICAgb3B0aW9ucy50cnVuY2F0ZSAtPSBuYW1lLmxlbmd0aCAqIDIgKyA1O1xuICAgIHZhciBwcm9wZXJ0eUNvbnRlbnRzID0gJyc7XG5cbiAgICBpZiAocHJvcGVydGllcy5sZW5ndGggPiAwKSB7XG4gICAgICBwcm9wZXJ0eUNvbnRlbnRzICs9ICcgJztcbiAgICAgIHByb3BlcnR5Q29udGVudHMgKz0gaW5zcGVjdExpc3QocHJvcGVydGllcy5tYXAoZnVuY3Rpb24gKGtleSkge1xuICAgICAgICByZXR1cm4gW2tleSwgZWxlbWVudC5nZXRBdHRyaWJ1dGUoa2V5KV07XG4gICAgICB9KSwgb3B0aW9ucywgaW5zcGVjdEF0dHJpYnV0ZSwgJyAnKTtcbiAgICB9XG5cbiAgICBvcHRpb25zLnRydW5jYXRlIC09IHByb3BlcnR5Q29udGVudHMubGVuZ3RoO1xuICAgIHZhciB0cnVuY2F0ZSA9IG9wdGlvbnMudHJ1bmNhdGU7XG4gICAgdmFyIGNoaWxkcmVuID0gaW5zcGVjdEhUTUxDb2xsZWN0aW9uKGVsZW1lbnQuY2hpbGRyZW4sIG9wdGlvbnMpO1xuXG4gICAgaWYgKGNoaWxkcmVuICYmIGNoaWxkcmVuLmxlbmd0aCA+IHRydW5jYXRlKSB7XG4gICAgICBjaGlsZHJlbiA9IFwiXCIuY29uY2F0KHRydW5jYXRvciwgXCIoXCIpLmNvbmNhdChlbGVtZW50LmNoaWxkcmVuLmxlbmd0aCwgXCIpXCIpO1xuICAgIH1cblxuICAgIHJldHVybiBcIlwiLmNvbmNhdChoZWFkKS5jb25jYXQocHJvcGVydHlDb250ZW50cykuY29uY2F0KGhlYWRDbG9zZSkuY29uY2F0KGNoaWxkcmVuKS5jb25jYXQodGFpbCk7XG4gIH1cblxuICB2YXIgc3ltYm9sc1N1cHBvcnRlZCA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIFN5bWJvbC5mb3IgPT09ICdmdW5jdGlvbic7XG4gIHZhciBjaGFpSW5zcGVjdCA9IHN5bWJvbHNTdXBwb3J0ZWQgPyBTeW1ib2wuZm9yKCdjaGFpL2luc3BlY3QnKSA6ICdAQGNoYWkvaW5zcGVjdCc7XG4gIHZhciBub2RlSW5zcGVjdCA9IGZhbHNlO1xuXG4gIHRyeSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGdsb2JhbC1yZXF1aXJlXG4gICAgdmFyIG5vZGVVdGlsID0gcmVxdWlyZSgndXRpbCcpO1xuXG4gICAgbm9kZUluc3BlY3QgPSBub2RlVXRpbC5pbnNwZWN0ID8gbm9kZVV0aWwuaW5zcGVjdC5jdXN0b20gOiBmYWxzZTtcbiAgfSBjYXRjaCAobm9Ob2RlSW5zcGVjdCkge1xuICAgIG5vZGVJbnNwZWN0ID0gZmFsc2U7XG4gIH1cblxuICBmdW5jdGlvbiBGYWtlTWFwKCkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBwcmVmZXItdGVtcGxhdGVcbiAgICB0aGlzLmtleSA9ICdjaGFpL2xvdXBlX18nICsgTWF0aC5yYW5kb20oKSArIERhdGUubm93KCk7XG4gIH1cblxuICBGYWtlTWFwLnByb3RvdHlwZSA9IHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgb2JqZWN0LXNob3J0aGFuZFxuICAgIGdldDogZnVuY3Rpb24gZ2V0KGtleSkge1xuICAgICAgcmV0dXJuIGtleVt0aGlzLmtleV07XG4gICAgfSxcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgb2JqZWN0LXNob3J0aGFuZFxuICAgIGhhczogZnVuY3Rpb24gaGFzKGtleSkge1xuICAgICAgcmV0dXJuIHRoaXMua2V5IGluIGtleTtcbiAgICB9LFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBvYmplY3Qtc2hvcnRoYW5kXG4gICAgc2V0OiBmdW5jdGlvbiBzZXQoa2V5LCB2YWx1ZSkge1xuICAgICAgaWYgKE9iamVjdC5pc0V4dGVuc2libGUoa2V5KSkge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoa2V5LCB0aGlzLmtleSwge1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBvYmplY3Qtc2hvcnRoYW5kXG4gICAgICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG4gIHZhciBjb25zdHJ1Y3Rvck1hcCA9IG5ldyAodHlwZW9mIFdlYWtNYXAgPT09ICdmdW5jdGlvbicgPyBXZWFrTWFwIDogRmFrZU1hcCkoKTtcbiAgdmFyIHN0cmluZ1RhZ01hcCA9IHt9O1xuICB2YXIgYmFzZVR5cGVzTWFwID0ge1xuICAgIHVuZGVmaW5lZDogZnVuY3Rpb24gdW5kZWZpbmVkJDEodmFsdWUsIG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiBvcHRpb25zLnN0eWxpemUoJ3VuZGVmaW5lZCcsICd1bmRlZmluZWQnKTtcbiAgICB9LFxuICAgIG51bGw6IGZ1bmN0aW9uIF9udWxsKHZhbHVlLCBvcHRpb25zKSB7XG4gICAgICByZXR1cm4gb3B0aW9ucy5zdHlsaXplKG51bGwsICdudWxsJyk7XG4gICAgfSxcbiAgICBib29sZWFuOiBmdW5jdGlvbiBib29sZWFuKHZhbHVlLCBvcHRpb25zKSB7XG4gICAgICByZXR1cm4gb3B0aW9ucy5zdHlsaXplKHZhbHVlLCAnYm9vbGVhbicpO1xuICAgIH0sXG4gICAgQm9vbGVhbjogZnVuY3Rpb24gQm9vbGVhbih2YWx1ZSwgb3B0aW9ucykge1xuICAgICAgcmV0dXJuIG9wdGlvbnMuc3R5bGl6ZSh2YWx1ZSwgJ2Jvb2xlYW4nKTtcbiAgICB9LFxuICAgIG51bWJlcjogaW5zcGVjdE51bWJlcixcbiAgICBOdW1iZXI6IGluc3BlY3ROdW1iZXIsXG4gICAgYmlnaW50OiBpbnNwZWN0QmlnSW50LFxuICAgIEJpZ0ludDogaW5zcGVjdEJpZ0ludCxcbiAgICBzdHJpbmc6IGluc3BlY3RTdHJpbmcsXG4gICAgU3RyaW5nOiBpbnNwZWN0U3RyaW5nLFxuICAgIGZ1bmN0aW9uOiBpbnNwZWN0RnVuY3Rpb24sXG4gICAgRnVuY3Rpb246IGluc3BlY3RGdW5jdGlvbixcbiAgICBzeW1ib2w6IGluc3BlY3RTeW1ib2wsXG4gICAgLy8gQSBTeW1ib2wgcG9seWZpbGwgd2lsbCByZXR1cm4gYFN5bWJvbGAgbm90IGBzeW1ib2xgIGZyb20gdHlwZWRldGVjdFxuICAgIFN5bWJvbDogaW5zcGVjdFN5bWJvbCxcbiAgICBBcnJheTogaW5zcGVjdEFycmF5LFxuICAgIERhdGU6IGluc3BlY3REYXRlLFxuICAgIE1hcDogaW5zcGVjdE1hcCxcbiAgICBTZXQ6IGluc3BlY3RTZXQsXG4gICAgUmVnRXhwOiBpbnNwZWN0UmVnRXhwLFxuICAgIFByb21pc2U6IGluc3BlY3RQcm9taXNlLFxuICAgIC8vIFdlYWtTZXQsIFdlYWtNYXAgYXJlIHRvdGFsbHkgb3BhcXVlIHRvIHVzXG4gICAgV2Vha1NldDogZnVuY3Rpb24gV2Vha1NldCh2YWx1ZSwgb3B0aW9ucykge1xuICAgICAgcmV0dXJuIG9wdGlvbnMuc3R5bGl6ZSgnV2Vha1NldHtcdTIwMjZ9JywgJ3NwZWNpYWwnKTtcbiAgICB9LFxuICAgIFdlYWtNYXA6IGZ1bmN0aW9uIFdlYWtNYXAodmFsdWUsIG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiBvcHRpb25zLnN0eWxpemUoJ1dlYWtNYXB7XHUyMDI2fScsICdzcGVjaWFsJyk7XG4gICAgfSxcbiAgICBBcmd1bWVudHM6IGluc3BlY3RBcmd1bWVudHMsXG4gICAgSW50OEFycmF5OiBpbnNwZWN0VHlwZWRBcnJheSxcbiAgICBVaW50OEFycmF5OiBpbnNwZWN0VHlwZWRBcnJheSxcbiAgICBVaW50OENsYW1wZWRBcnJheTogaW5zcGVjdFR5cGVkQXJyYXksXG4gICAgSW50MTZBcnJheTogaW5zcGVjdFR5cGVkQXJyYXksXG4gICAgVWludDE2QXJyYXk6IGluc3BlY3RUeXBlZEFycmF5LFxuICAgIEludDMyQXJyYXk6IGluc3BlY3RUeXBlZEFycmF5LFxuICAgIFVpbnQzMkFycmF5OiBpbnNwZWN0VHlwZWRBcnJheSxcbiAgICBGbG9hdDMyQXJyYXk6IGluc3BlY3RUeXBlZEFycmF5LFxuICAgIEZsb2F0NjRBcnJheTogaW5zcGVjdFR5cGVkQXJyYXksXG4gICAgR2VuZXJhdG9yOiBmdW5jdGlvbiBHZW5lcmF0b3IoKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfSxcbiAgICBEYXRhVmlldzogZnVuY3Rpb24gRGF0YVZpZXcoKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfSxcbiAgICBBcnJheUJ1ZmZlcjogZnVuY3Rpb24gQXJyYXlCdWZmZXIoKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfSxcbiAgICBFcnJvcjogaW5zcGVjdE9iamVjdCQxLFxuICAgIEhUTUxDb2xsZWN0aW9uOiBpbnNwZWN0SFRNTENvbGxlY3Rpb24sXG4gICAgTm9kZUxpc3Q6IGluc3BlY3RIVE1MQ29sbGVjdGlvblxuICB9OyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29tcGxleGl0eVxuXG4gIHZhciBpbnNwZWN0Q3VzdG9tID0gZnVuY3Rpb24gaW5zcGVjdEN1c3RvbSh2YWx1ZSwgb3B0aW9ucywgdHlwZSkge1xuICAgIGlmIChjaGFpSW5zcGVjdCBpbiB2YWx1ZSAmJiB0eXBlb2YgdmFsdWVbY2hhaUluc3BlY3RdID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gdmFsdWVbY2hhaUluc3BlY3RdKG9wdGlvbnMpO1xuICAgIH1cblxuICAgIGlmIChub2RlSW5zcGVjdCAmJiBub2RlSW5zcGVjdCBpbiB2YWx1ZSAmJiB0eXBlb2YgdmFsdWVbbm9kZUluc3BlY3RdID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gdmFsdWVbbm9kZUluc3BlY3RdKG9wdGlvbnMuZGVwdGgsIG9wdGlvbnMpO1xuICAgIH1cblxuICAgIGlmICgnaW5zcGVjdCcgaW4gdmFsdWUgJiYgdHlwZW9mIHZhbHVlLmluc3BlY3QgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybiB2YWx1ZS5pbnNwZWN0KG9wdGlvbnMuZGVwdGgsIG9wdGlvbnMpO1xuICAgIH1cblxuICAgIGlmICgnY29uc3RydWN0b3InIGluIHZhbHVlICYmIGNvbnN0cnVjdG9yTWFwLmhhcyh2YWx1ZS5jb25zdHJ1Y3RvcikpIHtcbiAgICAgIHJldHVybiBjb25zdHJ1Y3Rvck1hcC5nZXQodmFsdWUuY29uc3RydWN0b3IpKHZhbHVlLCBvcHRpb25zKTtcbiAgICB9XG5cbiAgICBpZiAoc3RyaW5nVGFnTWFwW3R5cGVdKSB7XG4gICAgICByZXR1cm4gc3RyaW5nVGFnTWFwW3R5cGVdKHZhbHVlLCBvcHRpb25zKTtcbiAgICB9XG5cbiAgICByZXR1cm4gJyc7XG4gIH07XG5cbiAgdmFyIHRvU3RyaW5nJDEgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nOyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29tcGxleGl0eVxuXG4gIGZ1bmN0aW9uIGluc3BlY3QodmFsdWUsIG9wdGlvbnMpIHtcbiAgICBvcHRpb25zID0gbm9ybWFsaXNlT3B0aW9ucyhvcHRpb25zKTtcbiAgICBvcHRpb25zLmluc3BlY3QgPSBpbnNwZWN0O1xuICAgIHZhciBfb3B0aW9ucyA9IG9wdGlvbnMsXG4gICAgICAgIGN1c3RvbUluc3BlY3QgPSBfb3B0aW9ucy5jdXN0b21JbnNwZWN0O1xuICAgIHZhciB0eXBlID0gdmFsdWUgPT09IG51bGwgPyAnbnVsbCcgOiBfdHlwZW9mKHZhbHVlKTtcblxuICAgIGlmICh0eXBlID09PSAnb2JqZWN0Jykge1xuICAgICAgdHlwZSA9IHRvU3RyaW5nJDEuY2FsbCh2YWx1ZSkuc2xpY2UoOCwgLTEpO1xuICAgIH0gLy8gSWYgaXQgaXMgYSBiYXNlIHZhbHVlIHRoYXQgd2UgYWxyZWFkeSBzdXBwb3J0LCB0aGVuIHVzZSBMb3VwZSdzIGluc3BlY3RvclxuXG5cbiAgICBpZiAoYmFzZVR5cGVzTWFwW3R5cGVdKSB7XG4gICAgICByZXR1cm4gYmFzZVR5cGVzTWFwW3R5cGVdKHZhbHVlLCBvcHRpb25zKTtcbiAgICB9IC8vIElmIGBvcHRpb25zLmN1c3RvbUluc3BlY3RgIGlzIHNldCB0byB0cnVlIHRoZW4gdHJ5IHRvIHVzZSB0aGUgY3VzdG9tIGluc3BlY3RvclxuXG5cbiAgICBpZiAoY3VzdG9tSW5zcGVjdCAmJiB2YWx1ZSkge1xuICAgICAgdmFyIG91dHB1dCA9IGluc3BlY3RDdXN0b20odmFsdWUsIG9wdGlvbnMsIHR5cGUpO1xuXG4gICAgICBpZiAob3V0cHV0KSB7XG4gICAgICAgIGlmICh0eXBlb2Ygb3V0cHV0ID09PSAnc3RyaW5nJykgcmV0dXJuIG91dHB1dDtcbiAgICAgICAgcmV0dXJuIGluc3BlY3Qob3V0cHV0LCBvcHRpb25zKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgcHJvdG8gPSB2YWx1ZSA/IE9iamVjdC5nZXRQcm90b3R5cGVPZih2YWx1ZSkgOiBmYWxzZTsgLy8gSWYgaXQncyBhIHBsYWluIE9iamVjdCB0aGVuIHVzZSBMb3VwZSdzIGluc3BlY3RvclxuXG4gICAgaWYgKHByb3RvID09PSBPYmplY3QucHJvdG90eXBlIHx8IHByb3RvID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gaW5zcGVjdE9iamVjdCh2YWx1ZSwgb3B0aW9ucyk7XG4gICAgfSAvLyBTcGVjaWZpY2FsbHkgYWNjb3VudCBmb3IgSFRNTEVsZW1lbnRzXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVmXG5cblxuICAgIGlmICh2YWx1ZSAmJiB0eXBlb2YgSFRNTEVsZW1lbnQgPT09ICdmdW5jdGlvbicgJiYgdmFsdWUgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgcmV0dXJuIGluc3BlY3RIVE1MKHZhbHVlLCBvcHRpb25zKTtcbiAgICB9XG5cbiAgICBpZiAoJ2NvbnN0cnVjdG9yJyBpbiB2YWx1ZSkge1xuICAgICAgLy8gSWYgaXQgaXMgYSBjbGFzcywgaW5zcGVjdCBpdCBsaWtlIGFuIG9iamVjdCBidXQgYWRkIHRoZSBjb25zdHJ1Y3RvciBuYW1lXG4gICAgICBpZiAodmFsdWUuY29uc3RydWN0b3IgIT09IE9iamVjdCkge1xuICAgICAgICByZXR1cm4gaW5zcGVjdENsYXNzKHZhbHVlLCBvcHRpb25zKTtcbiAgICAgIH0gLy8gSWYgaXQgaXMgYW4gb2JqZWN0IHdpdGggYW4gYW5vbnltb3VzIHByb3RvdHlwZSwgZGlzcGxheSBpdCBhcyBhbiBvYmplY3QuXG5cblxuICAgICAgcmV0dXJuIGluc3BlY3RPYmplY3QodmFsdWUsIG9wdGlvbnMpO1xuICAgIH0gLy8gbGFzdCBjaGFuY2UgdG8gY2hlY2sgaWYgaXQncyBhbiBvYmplY3RcblxuXG4gICAgaWYgKHZhbHVlID09PSBPYmplY3QodmFsdWUpKSB7XG4gICAgICByZXR1cm4gaW5zcGVjdE9iamVjdCh2YWx1ZSwgb3B0aW9ucyk7XG4gICAgfSAvLyBXZSBoYXZlIHJ1biBvdXQgb2Ygb3B0aW9ucyEgSnVzdCBzdHJpbmdpZnkgdGhlIHZhbHVlXG5cblxuICAgIHJldHVybiBvcHRpb25zLnN0eWxpemUoU3RyaW5nKHZhbHVlKSwgdHlwZSk7XG4gIH1cbiAgZnVuY3Rpb24gcmVnaXN0ZXJDb25zdHJ1Y3Rvcihjb25zdHJ1Y3RvciwgaW5zcGVjdG9yKSB7XG4gICAgaWYgKGNvbnN0cnVjdG9yTWFwLmhhcyhjb25zdHJ1Y3RvcikpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBjb25zdHJ1Y3Rvck1hcC5zZXQoY29uc3RydWN0b3IsIGluc3BlY3Rvcik7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgZnVuY3Rpb24gcmVnaXN0ZXJTdHJpbmdUYWcoc3RyaW5nVGFnLCBpbnNwZWN0b3IpIHtcbiAgICBpZiAoc3RyaW5nVGFnIGluIHN0cmluZ1RhZ01hcCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHN0cmluZ1RhZ01hcFtzdHJpbmdUYWddID0gaW5zcGVjdG9yO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHZhciBjdXN0b20gPSBjaGFpSW5zcGVjdDtcblxuICBleHBvcnRzLmN1c3RvbSA9IGN1c3RvbTtcbiAgZXhwb3J0cy5kZWZhdWx0ID0gaW5zcGVjdDtcbiAgZXhwb3J0cy5pbnNwZWN0ID0gaW5zcGVjdDtcbiAgZXhwb3J0cy5yZWdpc3RlckNvbnN0cnVjdG9yID0gcmVnaXN0ZXJDb25zdHJ1Y3RvcjtcbiAgZXhwb3J0cy5yZWdpc3RlclN0cmluZ1RhZyA9IHJlZ2lzdGVyU3RyaW5nVGFnO1xuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHsgdmFsdWU6IHRydWUgfSk7XG5cbn0pKSk7XG4iLCAibW9kdWxlLmV4cG9ydHMgPSB7XG5cbiAgLyoqXG4gICAqICMjIyBjb25maWcuaW5jbHVkZVN0YWNrXG4gICAqXG4gICAqIFVzZXIgY29uZmlndXJhYmxlIHByb3BlcnR5LCBpbmZsdWVuY2VzIHdoZXRoZXIgc3RhY2sgdHJhY2VcbiAgICogaXMgaW5jbHVkZWQgaW4gQXNzZXJ0aW9uIGVycm9yIG1lc3NhZ2UuIERlZmF1bHQgb2YgZmFsc2VcbiAgICogc3VwcHJlc3NlcyBzdGFjayB0cmFjZSBpbiB0aGUgZXJyb3IgbWVzc2FnZS5cbiAgICpcbiAgICogICAgIGNoYWkuY29uZmlnLmluY2x1ZGVTdGFjayA9IHRydWU7ICAvLyBlbmFibGUgc3RhY2sgb24gZXJyb3JcbiAgICpcbiAgICogQHBhcmFtIHtCb29sZWFufVxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBpbmNsdWRlU3RhY2s6IGZhbHNlLFxuXG4gIC8qKlxuICAgKiAjIyMgY29uZmlnLnNob3dEaWZmXG4gICAqXG4gICAqIFVzZXIgY29uZmlndXJhYmxlIHByb3BlcnR5LCBpbmZsdWVuY2VzIHdoZXRoZXIgb3Igbm90XG4gICAqIHRoZSBgc2hvd0RpZmZgIGZsYWcgc2hvdWxkIGJlIGluY2x1ZGVkIGluIHRoZSB0aHJvd25cbiAgICogQXNzZXJ0aW9uRXJyb3JzLiBgZmFsc2VgIHdpbGwgYWx3YXlzIGJlIGBmYWxzZWA7IGB0cnVlYFxuICAgKiB3aWxsIGJlIHRydWUgd2hlbiB0aGUgYXNzZXJ0aW9uIGhhcyByZXF1ZXN0ZWQgYSBkaWZmXG4gICAqIGJlIHNob3duLlxuICAgKlxuICAgKiBAcGFyYW0ge0Jvb2xlYW59XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIHNob3dEaWZmOiB0cnVlLFxuXG4gIC8qKlxuICAgKiAjIyMgY29uZmlnLnRydW5jYXRlVGhyZXNob2xkXG4gICAqXG4gICAqIFVzZXIgY29uZmlndXJhYmxlIHByb3BlcnR5LCBzZXRzIGxlbmd0aCB0aHJlc2hvbGQgZm9yIGFjdHVhbCBhbmRcbiAgICogZXhwZWN0ZWQgdmFsdWVzIGluIGFzc2VydGlvbiBlcnJvcnMuIElmIHRoaXMgdGhyZXNob2xkIGlzIGV4Y2VlZGVkLCBmb3JcbiAgICogZXhhbXBsZSBmb3IgbGFyZ2UgZGF0YSBzdHJ1Y3R1cmVzLCB0aGUgdmFsdWUgaXMgcmVwbGFjZWQgd2l0aCBzb21ldGhpbmdcbiAgICogbGlrZSBgWyBBcnJheSgzKSBdYCBvciBgeyBPYmplY3QgKHByb3AxLCBwcm9wMikgfWAuXG4gICAqXG4gICAqIFNldCBpdCB0byB6ZXJvIGlmIHlvdSB3YW50IHRvIGRpc2FibGUgdHJ1bmNhdGluZyBhbHRvZ2V0aGVyLlxuICAgKlxuICAgKiBUaGlzIGlzIGVzcGVjaWFsbHkgdXNlcmZ1bCB3aGVuIGRvaW5nIGFzc2VydGlvbnMgb24gYXJyYXlzOiBoYXZpbmcgdGhpc1xuICAgKiBzZXQgdG8gYSByZWFzb25hYmxlIGxhcmdlIHZhbHVlIG1ha2VzIHRoZSBmYWlsdXJlIG1lc3NhZ2VzIHJlYWRpbHlcbiAgICogaW5zcGVjdGFibGUuXG4gICAqXG4gICAqICAgICBjaGFpLmNvbmZpZy50cnVuY2F0ZVRocmVzaG9sZCA9IDA7ICAvLyBkaXNhYmxlIHRydW5jYXRpbmdcbiAgICpcbiAgICogQHBhcmFtIHtOdW1iZXJ9XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIHRydW5jYXRlVGhyZXNob2xkOiA0MCxcblxuICAvKipcbiAgICogIyMjIGNvbmZpZy51c2VQcm94eVxuICAgKlxuICAgKiBVc2VyIGNvbmZpZ3VyYWJsZSBwcm9wZXJ0eSwgZGVmaW5lcyBpZiBjaGFpIHdpbGwgdXNlIGEgUHJveHkgdG8gdGhyb3dcbiAgICogYW4gZXJyb3Igd2hlbiBhIG5vbi1leGlzdGVudCBwcm9wZXJ0eSBpcyByZWFkLCB3aGljaCBwcm90ZWN0cyB1c2Vyc1xuICAgKiBmcm9tIHR5cG9zIHdoZW4gdXNpbmcgcHJvcGVydHktYmFzZWQgYXNzZXJ0aW9ucy5cbiAgICpcbiAgICogU2V0IGl0IHRvIGZhbHNlIGlmIHlvdSB3YW50IHRvIGRpc2FibGUgdGhpcyBmZWF0dXJlLlxuICAgKlxuICAgKiAgICAgY2hhaS5jb25maWcudXNlUHJveHkgPSBmYWxzZTsgIC8vIGRpc2FibGUgdXNlIG9mIFByb3h5XG4gICAqXG4gICAqIFRoaXMgZmVhdHVyZSBpcyBhdXRvbWF0aWNhbGx5IGRpc2FibGVkIHJlZ2FyZGxlc3Mgb2YgdGhpcyBjb25maWcgdmFsdWVcbiAgICogaW4gZW52aXJvbm1lbnRzIHRoYXQgZG9uJ3Qgc3VwcG9ydCBwcm94aWVzLlxuICAgKlxuICAgKiBAcGFyYW0ge0Jvb2xlYW59XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIHVzZVByb3h5OiB0cnVlLFxuXG4gIC8qKlxuICAgKiAjIyMgY29uZmlnLnByb3h5RXhjbHVkZWRLZXlzXG4gICAqXG4gICAqIFVzZXIgY29uZmlndXJhYmxlIHByb3BlcnR5LCBkZWZpbmVzIHdoaWNoIHByb3BlcnRpZXMgc2hvdWxkIGJlIGlnbm9yZWRcbiAgICogaW5zdGVhZCBvZiB0aHJvd2luZyBhbiBlcnJvciBpZiB0aGV5IGRvIG5vdCBleGlzdCBvbiB0aGUgYXNzZXJ0aW9uLlxuICAgKiBUaGlzIGlzIG9ubHkgYXBwbGllZCBpZiB0aGUgZW52aXJvbm1lbnQgQ2hhaSBpcyBydW5uaW5nIGluIHN1cHBvcnRzIHByb3hpZXMgYW5kXG4gICAqIGlmIHRoZSBgdXNlUHJveHlgIGNvbmZpZ3VyYXRpb24gc2V0dGluZyBpcyBlbmFibGVkLlxuICAgKiBCeSBkZWZhdWx0LCBgdGhlbmAgYW5kIGBpbnNwZWN0YCB3aWxsIG5vdCB0aHJvdyBhbiBlcnJvciBpZiB0aGV5IGRvIG5vdCBleGlzdCBvbiB0aGVcbiAgICogYXNzZXJ0aW9uIG9iamVjdCBiZWNhdXNlIHRoZSBgLmluc3BlY3RgIHByb3BlcnR5IGlzIHJlYWQgYnkgYHV0aWwuaW5zcGVjdGAgKGZvciBleGFtcGxlLCB3aGVuXG4gICAqIHVzaW5nIGBjb25zb2xlLmxvZ2Agb24gdGhlIGFzc2VydGlvbiBvYmplY3QpIGFuZCBgLnRoZW5gIGlzIG5lY2Vzc2FyeSBmb3IgcHJvbWlzZSB0eXBlLWNoZWNraW5nLlxuICAgKlxuICAgKiAgICAgLy8gQnkgZGVmYXVsdCB0aGVzZSBrZXlzIHdpbGwgbm90IHRocm93IGFuIGVycm9yIGlmIHRoZXkgZG8gbm90IGV4aXN0IG9uIHRoZSBhc3NlcnRpb24gb2JqZWN0XG4gICAqICAgICBjaGFpLmNvbmZpZy5wcm94eUV4Y2x1ZGVkS2V5cyA9IFsndGhlbicsICdpbnNwZWN0J107XG4gICAqXG4gICAqIEBwYXJhbSB7QXJyYXl9XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIHByb3h5RXhjbHVkZWRLZXlzOiBbJ3RoZW4nLCAnY2F0Y2gnLCAnaW5zcGVjdCcsICd0b0pTT04nXVxufTtcbiIsICIvLyBUaGlzIGlzIChhbG1vc3QpIGRpcmVjdGx5IGZyb20gTm9kZS5qcyB1dGlsc1xuLy8gaHR0cHM6Ly9naXRodWIuY29tL2pveWVudC9ub2RlL2Jsb2IvZjhjMzM1ZDBjYWY0N2YxNmQzMTQxM2Y4OWFhMjhlZGEzODc4ZTNhYS9saWIvdXRpbC5qc1xuXG52YXIgZ2V0TmFtZSA9IHJlcXVpcmUoJ2dldC1mdW5jLW5hbWUnKTtcbnZhciBsb3VwZSA9IHJlcXVpcmUoJ2xvdXBlJyk7XG52YXIgY29uZmlnID0gcmVxdWlyZSgnLi4vY29uZmlnJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gaW5zcGVjdDtcblxuLyoqXG4gKiAjIyMgLmluc3BlY3Qob2JqLCBbc2hvd0hpZGRlbl0sIFtkZXB0aF0sIFtjb2xvcnNdKVxuICpcbiAqIEVjaG9lcyB0aGUgdmFsdWUgb2YgYSB2YWx1ZS4gVHJpZXMgdG8gcHJpbnQgdGhlIHZhbHVlIG91dFxuICogaW4gdGhlIGJlc3Qgd2F5IHBvc3NpYmxlIGdpdmVuIHRoZSBkaWZmZXJlbnQgdHlwZXMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iaiBUaGUgb2JqZWN0IHRvIHByaW50IG91dC5cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gc2hvd0hpZGRlbiBGbGFnIHRoYXQgc2hvd3MgaGlkZGVuIChub3QgZW51bWVyYWJsZSlcbiAqICAgIHByb3BlcnRpZXMgb2Ygb2JqZWN0cy4gRGVmYXVsdCBpcyBmYWxzZS5cbiAqIEBwYXJhbSB7TnVtYmVyfSBkZXB0aCBEZXB0aCBpbiB3aGljaCB0byBkZXNjZW5kIGluIG9iamVjdC4gRGVmYXVsdCBpcyAyLlxuICogQHBhcmFtIHtCb29sZWFufSBjb2xvcnMgRmxhZyB0byB0dXJuIG9uIEFOU0kgZXNjYXBlIGNvZGVzIHRvIGNvbG9yIHRoZVxuICogICAgb3V0cHV0LiBEZWZhdWx0IGlzIGZhbHNlIChubyBjb2xvcmluZykuXG4gKiBAbmFtZXNwYWNlIFV0aWxzXG4gKiBAbmFtZSBpbnNwZWN0XG4gKi9cbmZ1bmN0aW9uIGluc3BlY3Qob2JqLCBzaG93SGlkZGVuLCBkZXB0aCwgY29sb3JzKSB7XG4gIHZhciBvcHRpb25zID0ge1xuICAgIGNvbG9yczogY29sb3JzLFxuICAgIGRlcHRoOiAodHlwZW9mIGRlcHRoID09PSAndW5kZWZpbmVkJyA/IDIgOiBkZXB0aCksXG4gICAgc2hvd0hpZGRlbjogc2hvd0hpZGRlbixcbiAgICB0cnVuY2F0ZTogY29uZmlnLnRydW5jYXRlVGhyZXNob2xkID8gY29uZmlnLnRydW5jYXRlVGhyZXNob2xkIDogSW5maW5pdHksXG4gIH07XG4gIHJldHVybiBsb3VwZS5pbnNwZWN0KG9iaiwgb3B0aW9ucyk7XG59XG4iLCAiLyohXG4gKiBDaGFpIC0gZmxhZyB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyohXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzXG4gKi9cblxudmFyIGluc3BlY3QgPSByZXF1aXJlKCcuL2luc3BlY3QnKTtcbnZhciBjb25maWcgPSByZXF1aXJlKCcuLi9jb25maWcnKTtcblxuLyoqXG4gKiAjIyMgLm9iakRpc3BsYXkob2JqZWN0KVxuICpcbiAqIERldGVybWluZXMgaWYgYW4gb2JqZWN0IG9yIGFuIGFycmF5IG1hdGNoZXNcbiAqIGNyaXRlcmlhIHRvIGJlIGluc3BlY3RlZCBpbi1saW5lIGZvciBlcnJvclxuICogbWVzc2FnZXMgb3Igc2hvdWxkIGJlIHRydW5jYXRlZC5cbiAqXG4gKiBAcGFyYW0ge01peGVkfSBqYXZhc2NyaXB0IG9iamVjdCB0byBpbnNwZWN0XG4gKiBAbmFtZSBvYmpEaXNwbGF5XG4gKiBAbmFtZXNwYWNlIFV0aWxzXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gb2JqRGlzcGxheShvYmopIHtcbiAgdmFyIHN0ciA9IGluc3BlY3Qob2JqKVxuICAgICwgdHlwZSA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmopO1xuXG4gIGlmIChjb25maWcudHJ1bmNhdGVUaHJlc2hvbGQgJiYgc3RyLmxlbmd0aCA+PSBjb25maWcudHJ1bmNhdGVUaHJlc2hvbGQpIHtcbiAgICBpZiAodHlwZSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJykge1xuICAgICAgcmV0dXJuICFvYmoubmFtZSB8fCBvYmoubmFtZSA9PT0gJydcbiAgICAgICAgPyAnW0Z1bmN0aW9uXSdcbiAgICAgICAgOiAnW0Z1bmN0aW9uOiAnICsgb2JqLm5hbWUgKyAnXSc7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnW29iamVjdCBBcnJheV0nKSB7XG4gICAgICByZXR1cm4gJ1sgQXJyYXkoJyArIG9iai5sZW5ndGggKyAnKSBdJztcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdbb2JqZWN0IE9iamVjdF0nKSB7XG4gICAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKG9iailcbiAgICAgICAgLCBrc3RyID0ga2V5cy5sZW5ndGggPiAyXG4gICAgICAgICAgPyBrZXlzLnNwbGljZSgwLCAyKS5qb2luKCcsICcpICsgJywgLi4uJ1xuICAgICAgICAgIDoga2V5cy5qb2luKCcsICcpO1xuICAgICAgcmV0dXJuICd7IE9iamVjdCAoJyArIGtzdHIgKyAnKSB9JztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHN0cjtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHN0cjtcbiAgfVxufTtcbiIsICIvKiFcbiAqIENoYWkgLSBtZXNzYWdlIGNvbXBvc2l0aW9uIHV0aWxpdHlcbiAqIENvcHlyaWdodChjKSAyMDEyLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG4vKiFcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXNcbiAqL1xuXG52YXIgZmxhZyA9IHJlcXVpcmUoJy4vZmxhZycpXG4gICwgZ2V0QWN0dWFsID0gcmVxdWlyZSgnLi9nZXRBY3R1YWwnKVxuICAsIG9iakRpc3BsYXkgPSByZXF1aXJlKCcuL29iakRpc3BsYXknKTtcblxuLyoqXG4gKiAjIyMgLmdldE1lc3NhZ2Uob2JqZWN0LCBtZXNzYWdlLCBuZWdhdGVNZXNzYWdlKVxuICpcbiAqIENvbnN0cnVjdCB0aGUgZXJyb3IgbWVzc2FnZSBiYXNlZCBvbiBmbGFnc1xuICogYW5kIHRlbXBsYXRlIHRhZ3MuIFRlbXBsYXRlIHRhZ3Mgd2lsbCByZXR1cm5cbiAqIGEgc3RyaW5naWZpZWQgaW5zcGVjdGlvbiBvZiB0aGUgb2JqZWN0IHJlZmVyZW5jZWQuXG4gKlxuICogTWVzc2FnZSB0ZW1wbGF0ZSB0YWdzOlxuICogLSBgI3t0aGlzfWAgY3VycmVudCBhc3NlcnRlZCBvYmplY3RcbiAqIC0gYCN7YWN0fWAgYWN0dWFsIHZhbHVlXG4gKiAtIGAje2V4cH1gIGV4cGVjdGVkIHZhbHVlXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCAoY29uc3RydWN0ZWQgQXNzZXJ0aW9uKVxuICogQHBhcmFtIHtBcmd1bWVudHN9IGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZS5hc3NlcnQgYXJndW1lbnRzXG4gKiBAbmFtZXNwYWNlIFV0aWxzXG4gKiBAbmFtZSBnZXRNZXNzYWdlXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZ2V0TWVzc2FnZShvYmosIGFyZ3MpIHtcbiAgdmFyIG5lZ2F0ZSA9IGZsYWcob2JqLCAnbmVnYXRlJylcbiAgICAsIHZhbCA9IGZsYWcob2JqLCAnb2JqZWN0JylcbiAgICAsIGV4cGVjdGVkID0gYXJnc1szXVxuICAgICwgYWN0dWFsID0gZ2V0QWN0dWFsKG9iaiwgYXJncylcbiAgICAsIG1zZyA9IG5lZ2F0ZSA/IGFyZ3NbMl0gOiBhcmdzWzFdXG4gICAgLCBmbGFnTXNnID0gZmxhZyhvYmosICdtZXNzYWdlJyk7XG5cbiAgaWYodHlwZW9mIG1zZyA9PT0gXCJmdW5jdGlvblwiKSBtc2cgPSBtc2coKTtcbiAgbXNnID0gbXNnIHx8ICcnO1xuICBtc2cgPSBtc2dcbiAgICAucmVwbGFjZSgvI1xce3RoaXNcXH0vZywgZnVuY3Rpb24gKCkgeyByZXR1cm4gb2JqRGlzcGxheSh2YWwpOyB9KVxuICAgIC5yZXBsYWNlKC8jXFx7YWN0XFx9L2csIGZ1bmN0aW9uICgpIHsgcmV0dXJuIG9iakRpc3BsYXkoYWN0dWFsKTsgfSlcbiAgICAucmVwbGFjZSgvI1xce2V4cFxcfS9nLCBmdW5jdGlvbiAoKSB7IHJldHVybiBvYmpEaXNwbGF5KGV4cGVjdGVkKTsgfSk7XG5cbiAgcmV0dXJuIGZsYWdNc2cgPyBmbGFnTXNnICsgJzogJyArIG1zZyA6IG1zZztcbn07XG4iLCAiLyohXG4gKiBDaGFpIC0gdHJhbnNmZXJGbGFncyB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyoqXG4gKiAjIyMgLnRyYW5zZmVyRmxhZ3MoYXNzZXJ0aW9uLCBvYmplY3QsIGluY2x1ZGVBbGwgPSB0cnVlKVxuICpcbiAqIFRyYW5zZmVyIGFsbCB0aGUgZmxhZ3MgZm9yIGBhc3NlcnRpb25gIHRvIGBvYmplY3RgLiBJZlxuICogYGluY2x1ZGVBbGxgIGlzIHNldCB0byBgZmFsc2VgLCB0aGVuIHRoZSBiYXNlIENoYWlcbiAqIGFzc2VydGlvbiBmbGFncyAobmFtZWx5IGBvYmplY3RgLCBgc3NmaWAsIGBsb2NrU3NmaWAsXG4gKiBhbmQgYG1lc3NhZ2VgKSB3aWxsIG5vdCBiZSB0cmFuc2ZlcnJlZC5cbiAqXG4gKlxuICogICAgIHZhciBuZXdBc3NlcnRpb24gPSBuZXcgQXNzZXJ0aW9uKCk7XG4gKiAgICAgdXRpbHMudHJhbnNmZXJGbGFncyhhc3NlcnRpb24sIG5ld0Fzc2VydGlvbik7XG4gKlxuICogICAgIHZhciBhbm90aGVyQXNzZXJ0aW9uID0gbmV3IEFzc2VydGlvbihteU9iaik7XG4gKiAgICAgdXRpbHMudHJhbnNmZXJGbGFncyhhc3NlcnRpb24sIGFub3RoZXJBc3NlcnRpb24sIGZhbHNlKTtcbiAqXG4gKiBAcGFyYW0ge0Fzc2VydGlvbn0gYXNzZXJ0aW9uIHRoZSBhc3NlcnRpb24gdG8gdHJhbnNmZXIgdGhlIGZsYWdzIGZyb21cbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgdGhlIG9iamVjdCB0byB0cmFuc2ZlciB0aGUgZmxhZ3MgdG87IHVzdWFsbHkgYSBuZXcgYXNzZXJ0aW9uXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGluY2x1ZGVBbGxcbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBuYW1lIHRyYW5zZmVyRmxhZ3NcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gdHJhbnNmZXJGbGFncyhhc3NlcnRpb24sIG9iamVjdCwgaW5jbHVkZUFsbCkge1xuICB2YXIgZmxhZ3MgPSBhc3NlcnRpb24uX19mbGFncyB8fCAoYXNzZXJ0aW9uLl9fZmxhZ3MgPSBPYmplY3QuY3JlYXRlKG51bGwpKTtcblxuICBpZiAoIW9iamVjdC5fX2ZsYWdzKSB7XG4gICAgb2JqZWN0Ll9fZmxhZ3MgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICB9XG5cbiAgaW5jbHVkZUFsbCA9IGFyZ3VtZW50cy5sZW5ndGggPT09IDMgPyBpbmNsdWRlQWxsIDogdHJ1ZTtcblxuICBmb3IgKHZhciBmbGFnIGluIGZsYWdzKSB7XG4gICAgaWYgKGluY2x1ZGVBbGwgfHxcbiAgICAgICAgKGZsYWcgIT09ICdvYmplY3QnICYmIGZsYWcgIT09ICdzc2ZpJyAmJiBmbGFnICE9PSAnbG9ja1NzZmknICYmIGZsYWcgIT0gJ21lc3NhZ2UnKSkge1xuICAgICAgb2JqZWN0Ll9fZmxhZ3NbZmxhZ10gPSBmbGFnc1tmbGFnXTtcbiAgICB9XG4gIH1cbn07XG4iLCAiJ3VzZSBzdHJpY3QnO1xuLyogZ2xvYmFscyBTeW1ib2w6IGZhbHNlLCBVaW50OEFycmF5OiBmYWxzZSwgV2Vha01hcDogZmFsc2UgKi9cbi8qIVxuICogZGVlcC1lcWxcbiAqIENvcHlyaWdodChjKSAyMDEzIEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxudmFyIHR5cGUgPSByZXF1aXJlKCd0eXBlLWRldGVjdCcpO1xuZnVuY3Rpb24gRmFrZU1hcCgpIHtcbiAgdGhpcy5fa2V5ID0gJ2NoYWkvZGVlcC1lcWxfXycgKyBNYXRoLnJhbmRvbSgpICsgRGF0ZS5ub3coKTtcbn1cblxuRmFrZU1hcC5wcm90b3R5cGUgPSB7XG4gIGdldDogZnVuY3Rpb24gZ2V0KGtleSkge1xuICAgIHJldHVybiBrZXlbdGhpcy5fa2V5XTtcbiAgfSxcbiAgc2V0OiBmdW5jdGlvbiBzZXQoa2V5LCB2YWx1ZSkge1xuICAgIGlmIChPYmplY3QuaXNFeHRlbnNpYmxlKGtleSkpIHtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShrZXksIHRoaXMuX2tleSwge1xuICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfSxcbn07XG5cbnZhciBNZW1vaXplTWFwID0gdHlwZW9mIFdlYWtNYXAgPT09ICdmdW5jdGlvbicgPyBXZWFrTWFwIDogRmFrZU1hcDtcbi8qIVxuICogQ2hlY2sgdG8gc2VlIGlmIHRoZSBNZW1vaXplTWFwIGhhcyByZWNvcmRlZCBhIHJlc3VsdCBvZiB0aGUgdHdvIG9wZXJhbmRzXG4gKlxuICogQHBhcmFtIHtNaXhlZH0gbGVmdEhhbmRPcGVyYW5kXG4gKiBAcGFyYW0ge01peGVkfSByaWdodEhhbmRPcGVyYW5kXG4gKiBAcGFyYW0ge01lbW9pemVNYXB9IG1lbW9pemVNYXBcbiAqIEByZXR1cm5zIHtCb29sZWFufG51bGx9IHJlc3VsdFxuKi9cbmZ1bmN0aW9uIG1lbW9pemVDb21wYXJlKGxlZnRIYW5kT3BlcmFuZCwgcmlnaHRIYW5kT3BlcmFuZCwgbWVtb2l6ZU1hcCkge1xuICAvLyBUZWNobmljYWxseSwgV2Vha01hcCBrZXlzIGNhbiAqb25seSogYmUgb2JqZWN0cywgbm90IHByaW1pdGl2ZXMuXG4gIGlmICghbWVtb2l6ZU1hcCB8fCBpc1ByaW1pdGl2ZShsZWZ0SGFuZE9wZXJhbmQpIHx8IGlzUHJpbWl0aXZlKHJpZ2h0SGFuZE9wZXJhbmQpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgdmFyIGxlZnRIYW5kTWFwID0gbWVtb2l6ZU1hcC5nZXQobGVmdEhhbmRPcGVyYW5kKTtcbiAgaWYgKGxlZnRIYW5kTWFwKSB7XG4gICAgdmFyIHJlc3VsdCA9IGxlZnRIYW5kTWFwLmdldChyaWdodEhhbmRPcGVyYW5kKTtcbiAgICBpZiAodHlwZW9mIHJlc3VsdCA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cblxuLyohXG4gKiBTZXQgdGhlIHJlc3VsdCBvZiB0aGUgZXF1YWxpdHkgaW50byB0aGUgTWVtb2l6ZU1hcFxuICpcbiAqIEBwYXJhbSB7TWl4ZWR9IGxlZnRIYW5kT3BlcmFuZFxuICogQHBhcmFtIHtNaXhlZH0gcmlnaHRIYW5kT3BlcmFuZFxuICogQHBhcmFtIHtNZW1vaXplTWFwfSBtZW1vaXplTWFwXG4gKiBAcGFyYW0ge0Jvb2xlYW59IHJlc3VsdFxuKi9cbmZ1bmN0aW9uIG1lbW9pemVTZXQobGVmdEhhbmRPcGVyYW5kLCByaWdodEhhbmRPcGVyYW5kLCBtZW1vaXplTWFwLCByZXN1bHQpIHtcbiAgLy8gVGVjaG5pY2FsbHksIFdlYWtNYXAga2V5cyBjYW4gKm9ubHkqIGJlIG9iamVjdHMsIG5vdCBwcmltaXRpdmVzLlxuICBpZiAoIW1lbW9pemVNYXAgfHwgaXNQcmltaXRpdmUobGVmdEhhbmRPcGVyYW5kKSB8fCBpc1ByaW1pdGl2ZShyaWdodEhhbmRPcGVyYW5kKSkge1xuICAgIHJldHVybjtcbiAgfVxuICB2YXIgbGVmdEhhbmRNYXAgPSBtZW1vaXplTWFwLmdldChsZWZ0SGFuZE9wZXJhbmQpO1xuICBpZiAobGVmdEhhbmRNYXApIHtcbiAgICBsZWZ0SGFuZE1hcC5zZXQocmlnaHRIYW5kT3BlcmFuZCwgcmVzdWx0KTtcbiAgfSBlbHNlIHtcbiAgICBsZWZ0SGFuZE1hcCA9IG5ldyBNZW1vaXplTWFwKCk7XG4gICAgbGVmdEhhbmRNYXAuc2V0KHJpZ2h0SGFuZE9wZXJhbmQsIHJlc3VsdCk7XG4gICAgbWVtb2l6ZU1hcC5zZXQobGVmdEhhbmRPcGVyYW5kLCBsZWZ0SGFuZE1hcCk7XG4gIH1cbn1cblxuLyohXG4gKiBQcmltYXJ5IEV4cG9ydFxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZGVlcEVxdWFsO1xubW9kdWxlLmV4cG9ydHMuTWVtb2l6ZU1hcCA9IE1lbW9pemVNYXA7XG5cbi8qKlxuICogQXNzZXJ0IGRlZXBseSBuZXN0ZWQgc2FtZVZhbHVlIGVxdWFsaXR5IGJldHdlZW4gdHdvIG9iamVjdHMgb2YgYW55IHR5cGUuXG4gKlxuICogQHBhcmFtIHtNaXhlZH0gbGVmdEhhbmRPcGVyYW5kXG4gKiBAcGFyYW0ge01peGVkfSByaWdodEhhbmRPcGVyYW5kXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIChvcHRpb25hbCkgQWRkaXRpb25hbCBvcHRpb25zXG4gKiBAcGFyYW0ge0FycmF5fSBbb3B0aW9ucy5jb21wYXJhdG9yXSAob3B0aW9uYWwpIE92ZXJyaWRlIGRlZmF1bHQgYWxnb3JpdGhtLCBkZXRlcm1pbmluZyBjdXN0b20gZXF1YWxpdHkuXG4gKiBAcGFyYW0ge0FycmF5fSBbb3B0aW9ucy5tZW1vaXplXSAob3B0aW9uYWwpIFByb3ZpZGUgYSBjdXN0b20gbWVtb2l6YXRpb24gb2JqZWN0IHdoaWNoIHdpbGwgY2FjaGUgdGhlIHJlc3VsdHMgb2ZcbiAgICBjb21wbGV4IG9iamVjdHMgZm9yIGEgc3BlZWQgYm9vc3QuIEJ5IHBhc3NpbmcgYGZhbHNlYCB5b3UgY2FuIGRpc2FibGUgbWVtb2l6YXRpb24sIGJ1dCB0aGlzIHdpbGwgY2F1c2UgY2lyY3VsYXJcbiAgICByZWZlcmVuY2VzIHRvIGJsb3cgdGhlIHN0YWNrLlxuICogQHJldHVybiB7Qm9vbGVhbn0gZXF1YWwgbWF0Y2hcbiAqL1xuZnVuY3Rpb24gZGVlcEVxdWFsKGxlZnRIYW5kT3BlcmFuZCwgcmlnaHRIYW5kT3BlcmFuZCwgb3B0aW9ucykge1xuICAvLyBJZiB3ZSBoYXZlIGEgY29tcGFyYXRvciwgd2UgY2FuJ3QgYXNzdW1lIGFueXRoaW5nOyBzbyBiYWlsIHRvIGl0cyBjaGVjayBmaXJzdC5cbiAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5jb21wYXJhdG9yKSB7XG4gICAgcmV0dXJuIGV4dGVuc2l2ZURlZXBFcXVhbChsZWZ0SGFuZE9wZXJhbmQsIHJpZ2h0SGFuZE9wZXJhbmQsIG9wdGlvbnMpO1xuICB9XG5cbiAgdmFyIHNpbXBsZVJlc3VsdCA9IHNpbXBsZUVxdWFsKGxlZnRIYW5kT3BlcmFuZCwgcmlnaHRIYW5kT3BlcmFuZCk7XG4gIGlmIChzaW1wbGVSZXN1bHQgIT09IG51bGwpIHtcbiAgICByZXR1cm4gc2ltcGxlUmVzdWx0O1xuICB9XG5cbiAgLy8gRGVlcGVyIGNvbXBhcmlzb25zIGFyZSBwdXNoZWQgdGhyb3VnaCB0byBhIGxhcmdlciBmdW5jdGlvblxuICByZXR1cm4gZXh0ZW5zaXZlRGVlcEVxdWFsKGxlZnRIYW5kT3BlcmFuZCwgcmlnaHRIYW5kT3BlcmFuZCwgb3B0aW9ucyk7XG59XG5cbi8qKlxuICogTWFueSBjb21wYXJpc29ucyBjYW4gYmUgY2FuY2VsZWQgb3V0IGVhcmx5IHZpYSBzaW1wbGUgZXF1YWxpdHkgb3IgcHJpbWl0aXZlIGNoZWNrcy5cbiAqIEBwYXJhbSB7TWl4ZWR9IGxlZnRIYW5kT3BlcmFuZFxuICogQHBhcmFtIHtNaXhlZH0gcmlnaHRIYW5kT3BlcmFuZFxuICogQHJldHVybiB7Qm9vbGVhbnxudWxsfSBlcXVhbCBtYXRjaFxuICovXG5mdW5jdGlvbiBzaW1wbGVFcXVhbChsZWZ0SGFuZE9wZXJhbmQsIHJpZ2h0SGFuZE9wZXJhbmQpIHtcbiAgLy8gRXF1YWwgcmVmZXJlbmNlcyAoZXhjZXB0IGZvciBOdW1iZXJzKSBjYW4gYmUgcmV0dXJuZWQgZWFybHlcbiAgaWYgKGxlZnRIYW5kT3BlcmFuZCA9PT0gcmlnaHRIYW5kT3BlcmFuZCkge1xuICAgIC8vIEhhbmRsZSArLTAgY2FzZXNcbiAgICByZXR1cm4gbGVmdEhhbmRPcGVyYW5kICE9PSAwIHx8IDEgLyBsZWZ0SGFuZE9wZXJhbmQgPT09IDEgLyByaWdodEhhbmRPcGVyYW5kO1xuICB9XG5cbiAgLy8gaGFuZGxlIE5hTiBjYXNlc1xuICBpZiAoXG4gICAgbGVmdEhhbmRPcGVyYW5kICE9PSBsZWZ0SGFuZE9wZXJhbmQgJiYgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1zZWxmLWNvbXBhcmVcbiAgICByaWdodEhhbmRPcGVyYW5kICE9PSByaWdodEhhbmRPcGVyYW5kIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gICkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLy8gQW55dGhpbmcgdGhhdCBpcyBub3QgYW4gJ29iamVjdCcsIGkuZS4gc3ltYm9scywgZnVuY3Rpb25zLCBib29sZWFucywgbnVtYmVycyxcbiAgLy8gc3RyaW5ncywgYW5kIHVuZGVmaW5lZCwgY2FuIGJlIGNvbXBhcmVkIGJ5IHJlZmVyZW5jZS5cbiAgaWYgKGlzUHJpbWl0aXZlKGxlZnRIYW5kT3BlcmFuZCkgfHwgaXNQcmltaXRpdmUocmlnaHRIYW5kT3BlcmFuZCkpIHtcbiAgICAvLyBFYXN5IG91dCBiL2MgaXQgd291bGQgaGF2ZSBwYXNzZWQgdGhlIGZpcnN0IGVxdWFsaXR5IGNoZWNrXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiBudWxsO1xufVxuXG4vKiFcbiAqIFRoZSBtYWluIGxvZ2ljIG9mIHRoZSBgZGVlcEVxdWFsYCBmdW5jdGlvbi5cbiAqXG4gKiBAcGFyYW0ge01peGVkfSBsZWZ0SGFuZE9wZXJhbmRcbiAqIEBwYXJhbSB7TWl4ZWR9IHJpZ2h0SGFuZE9wZXJhbmRcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc10gKG9wdGlvbmFsKSBBZGRpdGlvbmFsIG9wdGlvbnNcbiAqIEBwYXJhbSB7QXJyYXl9IFtvcHRpb25zLmNvbXBhcmF0b3JdIChvcHRpb25hbCkgT3ZlcnJpZGUgZGVmYXVsdCBhbGdvcml0aG0sIGRldGVybWluaW5nIGN1c3RvbSBlcXVhbGl0eS5cbiAqIEBwYXJhbSB7QXJyYXl9IFtvcHRpb25zLm1lbW9pemVdIChvcHRpb25hbCkgUHJvdmlkZSBhIGN1c3RvbSBtZW1vaXphdGlvbiBvYmplY3Qgd2hpY2ggd2lsbCBjYWNoZSB0aGUgcmVzdWx0cyBvZlxuICAgIGNvbXBsZXggb2JqZWN0cyBmb3IgYSBzcGVlZCBib29zdC4gQnkgcGFzc2luZyBgZmFsc2VgIHlvdSBjYW4gZGlzYWJsZSBtZW1vaXphdGlvbiwgYnV0IHRoaXMgd2lsbCBjYXVzZSBjaXJjdWxhclxuICAgIHJlZmVyZW5jZXMgdG8gYmxvdyB0aGUgc3RhY2suXG4gKiBAcmV0dXJuIHtCb29sZWFufSBlcXVhbCBtYXRjaFxuKi9cbmZ1bmN0aW9uIGV4dGVuc2l2ZURlZXBFcXVhbChsZWZ0SGFuZE9wZXJhbmQsIHJpZ2h0SGFuZE9wZXJhbmQsIG9wdGlvbnMpIHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIG9wdGlvbnMubWVtb2l6ZSA9IG9wdGlvbnMubWVtb2l6ZSA9PT0gZmFsc2UgPyBmYWxzZSA6IG9wdGlvbnMubWVtb2l6ZSB8fCBuZXcgTWVtb2l6ZU1hcCgpO1xuICB2YXIgY29tcGFyYXRvciA9IG9wdGlvbnMgJiYgb3B0aW9ucy5jb21wYXJhdG9yO1xuXG4gIC8vIENoZWNrIGlmIGEgbWVtb2l6ZWQgcmVzdWx0IGV4aXN0cy5cbiAgdmFyIG1lbW9pemVSZXN1bHRMZWZ0ID0gbWVtb2l6ZUNvbXBhcmUobGVmdEhhbmRPcGVyYW5kLCByaWdodEhhbmRPcGVyYW5kLCBvcHRpb25zLm1lbW9pemUpO1xuICBpZiAobWVtb2l6ZVJlc3VsdExlZnQgIT09IG51bGwpIHtcbiAgICByZXR1cm4gbWVtb2l6ZVJlc3VsdExlZnQ7XG4gIH1cbiAgdmFyIG1lbW9pemVSZXN1bHRSaWdodCA9IG1lbW9pemVDb21wYXJlKHJpZ2h0SGFuZE9wZXJhbmQsIGxlZnRIYW5kT3BlcmFuZCwgb3B0aW9ucy5tZW1vaXplKTtcbiAgaWYgKG1lbW9pemVSZXN1bHRSaWdodCAhPT0gbnVsbCkge1xuICAgIHJldHVybiBtZW1vaXplUmVzdWx0UmlnaHQ7XG4gIH1cblxuICAvLyBJZiBhIGNvbXBhcmF0b3IgaXMgcHJlc2VudCwgdXNlIGl0LlxuICBpZiAoY29tcGFyYXRvcikge1xuICAgIHZhciBjb21wYXJhdG9yUmVzdWx0ID0gY29tcGFyYXRvcihsZWZ0SGFuZE9wZXJhbmQsIHJpZ2h0SGFuZE9wZXJhbmQpO1xuICAgIC8vIENvbXBhcmF0b3JzIG1heSByZXR1cm4gbnVsbCwgaW4gd2hpY2ggY2FzZSB3ZSB3YW50IHRvIGdvIGJhY2sgdG8gZGVmYXVsdCBiZWhhdmlvci5cbiAgICBpZiAoY29tcGFyYXRvclJlc3VsdCA9PT0gZmFsc2UgfHwgY29tcGFyYXRvclJlc3VsdCA9PT0gdHJ1ZSkge1xuICAgICAgbWVtb2l6ZVNldChsZWZ0SGFuZE9wZXJhbmQsIHJpZ2h0SGFuZE9wZXJhbmQsIG9wdGlvbnMubWVtb2l6ZSwgY29tcGFyYXRvclJlc3VsdCk7XG4gICAgICByZXR1cm4gY29tcGFyYXRvclJlc3VsdDtcbiAgICB9XG4gICAgLy8gVG8gYWxsb3cgY29tcGFyYXRvcnMgdG8gb3ZlcnJpZGUgKmFueSogYmVoYXZpb3IsIHdlIHJhbiB0aGVtIGZpcnN0LiBTaW5jZSBpdCBkaWRuJ3QgZGVjaWRlXG4gICAgLy8gd2hhdCB0byBkbywgd2UgbmVlZCB0byBtYWtlIHN1cmUgdG8gcmV0dXJuIHRoZSBiYXNpYyB0ZXN0cyBmaXJzdCBiZWZvcmUgd2UgbW92ZSBvbi5cbiAgICB2YXIgc2ltcGxlUmVzdWx0ID0gc2ltcGxlRXF1YWwobGVmdEhhbmRPcGVyYW5kLCByaWdodEhhbmRPcGVyYW5kKTtcbiAgICBpZiAoc2ltcGxlUmVzdWx0ICE9PSBudWxsKSB7XG4gICAgICAvLyBEb24ndCBtZW1vaXplIHRoaXMsIGl0IHRha2VzIGxvbmdlciB0byBzZXQvcmV0cmlldmUgdGhhbiB0byBqdXN0IGNvbXBhcmUuXG4gICAgICByZXR1cm4gc2ltcGxlUmVzdWx0O1xuICAgIH1cbiAgfVxuXG4gIHZhciBsZWZ0SGFuZFR5cGUgPSB0eXBlKGxlZnRIYW5kT3BlcmFuZCk7XG4gIGlmIChsZWZ0SGFuZFR5cGUgIT09IHR5cGUocmlnaHRIYW5kT3BlcmFuZCkpIHtcbiAgICBtZW1vaXplU2V0KGxlZnRIYW5kT3BlcmFuZCwgcmlnaHRIYW5kT3BlcmFuZCwgb3B0aW9ucy5tZW1vaXplLCBmYWxzZSk7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLy8gVGVtcG9yYXJpbHkgc2V0IHRoZSBvcGVyYW5kcyBpbiB0aGUgbWVtb2l6ZSBvYmplY3QgdG8gcHJldmVudCBibG93aW5nIHRoZSBzdGFja1xuICBtZW1vaXplU2V0KGxlZnRIYW5kT3BlcmFuZCwgcmlnaHRIYW5kT3BlcmFuZCwgb3B0aW9ucy5tZW1vaXplLCB0cnVlKTtcblxuICB2YXIgcmVzdWx0ID0gZXh0ZW5zaXZlRGVlcEVxdWFsQnlUeXBlKGxlZnRIYW5kT3BlcmFuZCwgcmlnaHRIYW5kT3BlcmFuZCwgbGVmdEhhbmRUeXBlLCBvcHRpb25zKTtcbiAgbWVtb2l6ZVNldChsZWZ0SGFuZE9wZXJhbmQsIHJpZ2h0SGFuZE9wZXJhbmQsIG9wdGlvbnMubWVtb2l6ZSwgcmVzdWx0KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gZXh0ZW5zaXZlRGVlcEVxdWFsQnlUeXBlKGxlZnRIYW5kT3BlcmFuZCwgcmlnaHRIYW5kT3BlcmFuZCwgbGVmdEhhbmRUeXBlLCBvcHRpb25zKSB7XG4gIHN3aXRjaCAobGVmdEhhbmRUeXBlKSB7XG4gICAgY2FzZSAnU3RyaW5nJzpcbiAgICBjYXNlICdOdW1iZXInOlxuICAgIGNhc2UgJ0Jvb2xlYW4nOlxuICAgIGNhc2UgJ0RhdGUnOlxuICAgICAgLy8gSWYgdGhlc2UgdHlwZXMgYXJlIHRoZWlyIGluc3RhbmNlIHR5cGVzIChlLmcuIGBuZXcgTnVtYmVyYCkgdGhlbiByZS1kZWVwRXF1YWwgYWdhaW5zdCB0aGVpciB2YWx1ZXNcbiAgICAgIHJldHVybiBkZWVwRXF1YWwobGVmdEhhbmRPcGVyYW5kLnZhbHVlT2YoKSwgcmlnaHRIYW5kT3BlcmFuZC52YWx1ZU9mKCkpO1xuICAgIGNhc2UgJ1Byb21pc2UnOlxuICAgIGNhc2UgJ1N5bWJvbCc6XG4gICAgY2FzZSAnZnVuY3Rpb24nOlxuICAgIGNhc2UgJ1dlYWtNYXAnOlxuICAgIGNhc2UgJ1dlYWtTZXQnOlxuICAgICAgcmV0dXJuIGxlZnRIYW5kT3BlcmFuZCA9PT0gcmlnaHRIYW5kT3BlcmFuZDtcbiAgICBjYXNlICdFcnJvcic6XG4gICAgICByZXR1cm4ga2V5c0VxdWFsKGxlZnRIYW5kT3BlcmFuZCwgcmlnaHRIYW5kT3BlcmFuZCwgWyAnbmFtZScsICdtZXNzYWdlJywgJ2NvZGUnIF0sIG9wdGlvbnMpO1xuICAgIGNhc2UgJ0FyZ3VtZW50cyc6XG4gICAgY2FzZSAnSW50OEFycmF5JzpcbiAgICBjYXNlICdVaW50OEFycmF5JzpcbiAgICBjYXNlICdVaW50OENsYW1wZWRBcnJheSc6XG4gICAgY2FzZSAnSW50MTZBcnJheSc6XG4gICAgY2FzZSAnVWludDE2QXJyYXknOlxuICAgIGNhc2UgJ0ludDMyQXJyYXknOlxuICAgIGNhc2UgJ1VpbnQzMkFycmF5JzpcbiAgICBjYXNlICdGbG9hdDMyQXJyYXknOlxuICAgIGNhc2UgJ0Zsb2F0NjRBcnJheSc6XG4gICAgY2FzZSAnQXJyYXknOlxuICAgICAgcmV0dXJuIGl0ZXJhYmxlRXF1YWwobGVmdEhhbmRPcGVyYW5kLCByaWdodEhhbmRPcGVyYW5kLCBvcHRpb25zKTtcbiAgICBjYXNlICdSZWdFeHAnOlxuICAgICAgcmV0dXJuIHJlZ2V4cEVxdWFsKGxlZnRIYW5kT3BlcmFuZCwgcmlnaHRIYW5kT3BlcmFuZCk7XG4gICAgY2FzZSAnR2VuZXJhdG9yJzpcbiAgICAgIHJldHVybiBnZW5lcmF0b3JFcXVhbChsZWZ0SGFuZE9wZXJhbmQsIHJpZ2h0SGFuZE9wZXJhbmQsIG9wdGlvbnMpO1xuICAgIGNhc2UgJ0RhdGFWaWV3JzpcbiAgICAgIHJldHVybiBpdGVyYWJsZUVxdWFsKG5ldyBVaW50OEFycmF5KGxlZnRIYW5kT3BlcmFuZC5idWZmZXIpLCBuZXcgVWludDhBcnJheShyaWdodEhhbmRPcGVyYW5kLmJ1ZmZlciksIG9wdGlvbnMpO1xuICAgIGNhc2UgJ0FycmF5QnVmZmVyJzpcbiAgICAgIHJldHVybiBpdGVyYWJsZUVxdWFsKG5ldyBVaW50OEFycmF5KGxlZnRIYW5kT3BlcmFuZCksIG5ldyBVaW50OEFycmF5KHJpZ2h0SGFuZE9wZXJhbmQpLCBvcHRpb25zKTtcbiAgICBjYXNlICdTZXQnOlxuICAgICAgcmV0dXJuIGVudHJpZXNFcXVhbChsZWZ0SGFuZE9wZXJhbmQsIHJpZ2h0SGFuZE9wZXJhbmQsIG9wdGlvbnMpO1xuICAgIGNhc2UgJ01hcCc6XG4gICAgICByZXR1cm4gZW50cmllc0VxdWFsKGxlZnRIYW5kT3BlcmFuZCwgcmlnaHRIYW5kT3BlcmFuZCwgb3B0aW9ucyk7XG4gICAgY2FzZSAnVGVtcG9yYWwuUGxhaW5EYXRlJzpcbiAgICBjYXNlICdUZW1wb3JhbC5QbGFpblRpbWUnOlxuICAgIGNhc2UgJ1RlbXBvcmFsLlBsYWluRGF0ZVRpbWUnOlxuICAgIGNhc2UgJ1RlbXBvcmFsLkluc3RhbnQnOlxuICAgIGNhc2UgJ1RlbXBvcmFsLlpvbmVkRGF0ZVRpbWUnOlxuICAgIGNhc2UgJ1RlbXBvcmFsLlBsYWluWWVhck1vbnRoJzpcbiAgICBjYXNlICdUZW1wb3JhbC5QbGFpbk1vbnRoRGF5JzpcbiAgICAgIHJldHVybiBsZWZ0SGFuZE9wZXJhbmQuZXF1YWxzKHJpZ2h0SGFuZE9wZXJhbmQpO1xuICAgIGNhc2UgJ1RlbXBvcmFsLkR1cmF0aW9uJzpcbiAgICAgIHJldHVybiBsZWZ0SGFuZE9wZXJhbmQudG90YWwoJ25hbm9zZWNvbmRzJykgPT09IHJpZ2h0SGFuZE9wZXJhbmQudG90YWwoJ25hbm9zZWNvbmRzJyk7XG4gICAgY2FzZSAnVGVtcG9yYWwuVGltZVpvbmUnOlxuICAgIGNhc2UgJ1RlbXBvcmFsLkNhbGVuZGFyJzpcbiAgICAgIHJldHVybiBsZWZ0SGFuZE9wZXJhbmQudG9TdHJpbmcoKSA9PT0gcmlnaHRIYW5kT3BlcmFuZC50b1N0cmluZygpO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gb2JqZWN0RXF1YWwobGVmdEhhbmRPcGVyYW5kLCByaWdodEhhbmRPcGVyYW5kLCBvcHRpb25zKTtcbiAgfVxufVxuXG4vKiFcbiAqIENvbXBhcmUgdHdvIFJlZ3VsYXIgRXhwcmVzc2lvbnMgZm9yIGVxdWFsaXR5LlxuICpcbiAqIEBwYXJhbSB7UmVnRXhwfSBsZWZ0SGFuZE9wZXJhbmRcbiAqIEBwYXJhbSB7UmVnRXhwfSByaWdodEhhbmRPcGVyYW5kXG4gKiBAcmV0dXJuIHtCb29sZWFufSByZXN1bHRcbiAqL1xuXG5mdW5jdGlvbiByZWdleHBFcXVhbChsZWZ0SGFuZE9wZXJhbmQsIHJpZ2h0SGFuZE9wZXJhbmQpIHtcbiAgcmV0dXJuIGxlZnRIYW5kT3BlcmFuZC50b1N0cmluZygpID09PSByaWdodEhhbmRPcGVyYW5kLnRvU3RyaW5nKCk7XG59XG5cbi8qIVxuICogQ29tcGFyZSB0d28gU2V0cy9NYXBzIGZvciBlcXVhbGl0eS4gRmFzdGVyIHRoYW4gb3RoZXIgZXF1YWxpdHkgZnVuY3Rpb25zLlxuICpcbiAqIEBwYXJhbSB7U2V0fSBsZWZ0SGFuZE9wZXJhbmRcbiAqIEBwYXJhbSB7U2V0fSByaWdodEhhbmRPcGVyYW5kXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIChPcHRpb25hbClcbiAqIEByZXR1cm4ge0Jvb2xlYW59IHJlc3VsdFxuICovXG5cbmZ1bmN0aW9uIGVudHJpZXNFcXVhbChsZWZ0SGFuZE9wZXJhbmQsIHJpZ2h0SGFuZE9wZXJhbmQsIG9wdGlvbnMpIHtcbiAgLy8gSUUxMSBkb2Vzbid0IHN1cHBvcnQgU2V0I2VudHJpZXMgb3IgU2V0I0BAaXRlcmF0b3IsIHNvIHdlIG5lZWQgbWFudWFsbHkgcG9wdWxhdGUgdXNpbmcgU2V0I2ZvckVhY2hcbiAgaWYgKGxlZnRIYW5kT3BlcmFuZC5zaXplICE9PSByaWdodEhhbmRPcGVyYW5kLnNpemUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKGxlZnRIYW5kT3BlcmFuZC5zaXplID09PSAwKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgdmFyIGxlZnRIYW5kSXRlbXMgPSBbXTtcbiAgdmFyIHJpZ2h0SGFuZEl0ZW1zID0gW107XG4gIGxlZnRIYW5kT3BlcmFuZC5mb3JFYWNoKGZ1bmN0aW9uIGdhdGhlckVudHJpZXMoa2V5LCB2YWx1ZSkge1xuICAgIGxlZnRIYW5kSXRlbXMucHVzaChbIGtleSwgdmFsdWUgXSk7XG4gIH0pO1xuICByaWdodEhhbmRPcGVyYW5kLmZvckVhY2goZnVuY3Rpb24gZ2F0aGVyRW50cmllcyhrZXksIHZhbHVlKSB7XG4gICAgcmlnaHRIYW5kSXRlbXMucHVzaChbIGtleSwgdmFsdWUgXSk7XG4gIH0pO1xuICByZXR1cm4gaXRlcmFibGVFcXVhbChsZWZ0SGFuZEl0ZW1zLnNvcnQoKSwgcmlnaHRIYW5kSXRlbXMuc29ydCgpLCBvcHRpb25zKTtcbn1cblxuLyohXG4gKiBTaW1wbGUgZXF1YWxpdHkgZm9yIGZsYXQgaXRlcmFibGUgb2JqZWN0cyBzdWNoIGFzIEFycmF5cywgVHlwZWRBcnJheXMgb3IgTm9kZS5qcyBidWZmZXJzLlxuICpcbiAqIEBwYXJhbSB7SXRlcmFibGV9IGxlZnRIYW5kT3BlcmFuZFxuICogQHBhcmFtIHtJdGVyYWJsZX0gcmlnaHRIYW5kT3BlcmFuZFxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXSAoT3B0aW9uYWwpXG4gKiBAcmV0dXJuIHtCb29sZWFufSByZXN1bHRcbiAqL1xuXG5mdW5jdGlvbiBpdGVyYWJsZUVxdWFsKGxlZnRIYW5kT3BlcmFuZCwgcmlnaHRIYW5kT3BlcmFuZCwgb3B0aW9ucykge1xuICB2YXIgbGVuZ3RoID0gbGVmdEhhbmRPcGVyYW5kLmxlbmd0aDtcbiAgaWYgKGxlbmd0aCAhPT0gcmlnaHRIYW5kT3BlcmFuZC5sZW5ndGgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKGxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHZhciBpbmRleCA9IC0xO1xuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIGlmIChkZWVwRXF1YWwobGVmdEhhbmRPcGVyYW5kW2luZGV4XSwgcmlnaHRIYW5kT3BlcmFuZFtpbmRleF0sIG9wdGlvbnMpID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyohXG4gKiBTaW1wbGUgZXF1YWxpdHkgZm9yIGdlbmVyYXRvciBvYmplY3RzIHN1Y2ggYXMgdGhvc2UgcmV0dXJuZWQgYnkgZ2VuZXJhdG9yIGZ1bmN0aW9ucy5cbiAqXG4gKiBAcGFyYW0ge0l0ZXJhYmxlfSBsZWZ0SGFuZE9wZXJhbmRcbiAqIEBwYXJhbSB7SXRlcmFibGV9IHJpZ2h0SGFuZE9wZXJhbmRcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc10gKE9wdGlvbmFsKVxuICogQHJldHVybiB7Qm9vbGVhbn0gcmVzdWx0XG4gKi9cblxuZnVuY3Rpb24gZ2VuZXJhdG9yRXF1YWwobGVmdEhhbmRPcGVyYW5kLCByaWdodEhhbmRPcGVyYW5kLCBvcHRpb25zKSB7XG4gIHJldHVybiBpdGVyYWJsZUVxdWFsKGdldEdlbmVyYXRvckVudHJpZXMobGVmdEhhbmRPcGVyYW5kKSwgZ2V0R2VuZXJhdG9yRW50cmllcyhyaWdodEhhbmRPcGVyYW5kKSwgb3B0aW9ucyk7XG59XG5cbi8qIVxuICogRGV0ZXJtaW5lIGlmIHRoZSBnaXZlbiBvYmplY3QgaGFzIGFuIEBAaXRlcmF0b3IgZnVuY3Rpb24uXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHRhcmdldFxuICogQHJldHVybiB7Qm9vbGVhbn0gYHRydWVgIGlmIHRoZSBvYmplY3QgaGFzIGFuIEBAaXRlcmF0b3IgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGhhc0l0ZXJhdG9yRnVuY3Rpb24odGFyZ2V0KSB7XG4gIHJldHVybiB0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJlxuICAgIHR5cGVvZiB0YXJnZXQgPT09ICdvYmplY3QnICYmXG4gICAgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICB0eXBlb2YgdGFyZ2V0W1N5bWJvbC5pdGVyYXRvcl0gPT09ICdmdW5jdGlvbic7XG59XG5cbi8qIVxuICogR2V0cyBhbGwgaXRlcmF0b3IgZW50cmllcyBmcm9tIHRoZSBnaXZlbiBPYmplY3QuIElmIHRoZSBPYmplY3QgaGFzIG5vIEBAaXRlcmF0b3IgZnVuY3Rpb24sIHJldHVybnMgYW4gZW1wdHkgYXJyYXkuXG4gKiBUaGlzIHdpbGwgY29uc3VtZSB0aGUgaXRlcmF0b3IgLSB3aGljaCBjb3VsZCBoYXZlIHNpZGUgZWZmZWN0cyBkZXBlbmRpbmcgb24gdGhlIEBAaXRlcmF0b3IgaW1wbGVtZW50YXRpb24uXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHRhcmdldFxuICogQHJldHVybnMge0FycmF5fSBhbiBhcnJheSBvZiBlbnRyaWVzIGZyb20gdGhlIEBAaXRlcmF0b3IgZnVuY3Rpb25cbiAqL1xuZnVuY3Rpb24gZ2V0SXRlcmF0b3JFbnRyaWVzKHRhcmdldCkge1xuICBpZiAoaGFzSXRlcmF0b3JGdW5jdGlvbih0YXJnZXQpKSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBnZXRHZW5lcmF0b3JFbnRyaWVzKHRhcmdldFtTeW1ib2wuaXRlcmF0b3JdKCkpO1xuICAgIH0gY2F0Y2ggKGl0ZXJhdG9yRXJyb3IpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIFtdO1xufVxuXG4vKiFcbiAqIEdldHMgYWxsIGVudHJpZXMgZnJvbSBhIEdlbmVyYXRvci4gVGhpcyB3aWxsIGNvbnN1bWUgdGhlIGdlbmVyYXRvciAtIHdoaWNoIGNvdWxkIGhhdmUgc2lkZSBlZmZlY3RzLlxuICpcbiAqIEBwYXJhbSB7R2VuZXJhdG9yfSB0YXJnZXRcbiAqIEByZXR1cm5zIHtBcnJheX0gYW4gYXJyYXkgb2YgZW50cmllcyBmcm9tIHRoZSBHZW5lcmF0b3IuXG4gKi9cbmZ1bmN0aW9uIGdldEdlbmVyYXRvckVudHJpZXMoZ2VuZXJhdG9yKSB7XG4gIHZhciBnZW5lcmF0b3JSZXN1bHQgPSBnZW5lcmF0b3IubmV4dCgpO1xuICB2YXIgYWNjdW11bGF0b3IgPSBbIGdlbmVyYXRvclJlc3VsdC52YWx1ZSBdO1xuICB3aGlsZSAoZ2VuZXJhdG9yUmVzdWx0LmRvbmUgPT09IGZhbHNlKSB7XG4gICAgZ2VuZXJhdG9yUmVzdWx0ID0gZ2VuZXJhdG9yLm5leHQoKTtcbiAgICBhY2N1bXVsYXRvci5wdXNoKGdlbmVyYXRvclJlc3VsdC52YWx1ZSk7XG4gIH1cbiAgcmV0dXJuIGFjY3VtdWxhdG9yO1xufVxuXG4vKiFcbiAqIEdldHMgYWxsIG93biBhbmQgaW5oZXJpdGVkIGVudW1lcmFibGUga2V5cyBmcm9tIGEgdGFyZ2V0LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB0YXJnZXRcbiAqIEByZXR1cm5zIHtBcnJheX0gYW4gYXJyYXkgb2Ygb3duIGFuZCBpbmhlcml0ZWQgZW51bWVyYWJsZSBrZXlzIGZyb20gdGhlIHRhcmdldC5cbiAqL1xuZnVuY3Rpb24gZ2V0RW51bWVyYWJsZUtleXModGFyZ2V0KSB7XG4gIHZhciBrZXlzID0gW107XG4gIGZvciAodmFyIGtleSBpbiB0YXJnZXQpIHtcbiAgICBrZXlzLnB1c2goa2V5KTtcbiAgfVxuICByZXR1cm4ga2V5cztcbn1cblxuZnVuY3Rpb24gZ2V0RW51bWVyYWJsZVN5bWJvbHModGFyZ2V0KSB7XG4gIHZhciBrZXlzID0gW107XG4gIHZhciBhbGxLZXlzID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyh0YXJnZXQpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFsbEtleXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICB2YXIga2V5ID0gYWxsS2V5c1tpXTtcbiAgICBpZiAoT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIGtleSkuZW51bWVyYWJsZSkge1xuICAgICAga2V5cy5wdXNoKGtleSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBrZXlzO1xufVxuXG4vKiFcbiAqIERldGVybWluZXMgaWYgdHdvIG9iamVjdHMgaGF2ZSBtYXRjaGluZyB2YWx1ZXMsIGdpdmVuIGEgc2V0IG9mIGtleXMuIERlZmVycyB0byBkZWVwRXF1YWwgZm9yIHRoZSBlcXVhbGl0eSBjaGVjayBvZlxuICogZWFjaCBrZXkuIElmIGFueSB2YWx1ZSBvZiB0aGUgZ2l2ZW4ga2V5IGlzIG5vdCBlcXVhbCwgdGhlIGZ1bmN0aW9uIHdpbGwgcmV0dXJuIGZhbHNlIChlYXJseSkuXG4gKlxuICogQHBhcmFtIHtNaXhlZH0gbGVmdEhhbmRPcGVyYW5kXG4gKiBAcGFyYW0ge01peGVkfSByaWdodEhhbmRPcGVyYW5kXG4gKiBAcGFyYW0ge0FycmF5fSBrZXlzIEFuIGFycmF5IG9mIGtleXMgdG8gY29tcGFyZSB0aGUgdmFsdWVzIG9mIGxlZnRIYW5kT3BlcmFuZCBhbmQgcmlnaHRIYW5kT3BlcmFuZCBhZ2FpbnN0XG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIChPcHRpb25hbClcbiAqIEByZXR1cm4ge0Jvb2xlYW59IHJlc3VsdFxuICovXG5mdW5jdGlvbiBrZXlzRXF1YWwobGVmdEhhbmRPcGVyYW5kLCByaWdodEhhbmRPcGVyYW5kLCBrZXlzLCBvcHRpb25zKSB7XG4gIHZhciBsZW5ndGggPSBrZXlzLmxlbmd0aDtcbiAgaWYgKGxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICBpZiAoZGVlcEVxdWFsKGxlZnRIYW5kT3BlcmFuZFtrZXlzW2ldXSwgcmlnaHRIYW5kT3BlcmFuZFtrZXlzW2ldXSwgb3B0aW9ucykgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG4vKiFcbiAqIFJlY3Vyc2l2ZWx5IGNoZWNrIHRoZSBlcXVhbGl0eSBvZiB0d28gT2JqZWN0cy4gT25jZSBiYXNpYyBzYW1lbmVzcyBoYXMgYmVlbiBlc3RhYmxpc2hlZCBpdCB3aWxsIGRlZmVyIHRvIGBkZWVwRXF1YWxgXG4gKiBmb3IgZWFjaCBlbnVtZXJhYmxlIGtleSBpbiB0aGUgb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7TWl4ZWR9IGxlZnRIYW5kT3BlcmFuZFxuICogQHBhcmFtIHtNaXhlZH0gcmlnaHRIYW5kT3BlcmFuZFxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXSAoT3B0aW9uYWwpXG4gKiBAcmV0dXJuIHtCb29sZWFufSByZXN1bHRcbiAqL1xuZnVuY3Rpb24gb2JqZWN0RXF1YWwobGVmdEhhbmRPcGVyYW5kLCByaWdodEhhbmRPcGVyYW5kLCBvcHRpb25zKSB7XG4gIHZhciBsZWZ0SGFuZEtleXMgPSBnZXRFbnVtZXJhYmxlS2V5cyhsZWZ0SGFuZE9wZXJhbmQpO1xuICB2YXIgcmlnaHRIYW5kS2V5cyA9IGdldEVudW1lcmFibGVLZXlzKHJpZ2h0SGFuZE9wZXJhbmQpO1xuICB2YXIgbGVmdEhhbmRTeW1ib2xzID0gZ2V0RW51bWVyYWJsZVN5bWJvbHMobGVmdEhhbmRPcGVyYW5kKTtcbiAgdmFyIHJpZ2h0SGFuZFN5bWJvbHMgPSBnZXRFbnVtZXJhYmxlU3ltYm9scyhyaWdodEhhbmRPcGVyYW5kKTtcbiAgbGVmdEhhbmRLZXlzID0gbGVmdEhhbmRLZXlzLmNvbmNhdChsZWZ0SGFuZFN5bWJvbHMpO1xuICByaWdodEhhbmRLZXlzID0gcmlnaHRIYW5kS2V5cy5jb25jYXQocmlnaHRIYW5kU3ltYm9scyk7XG5cbiAgaWYgKGxlZnRIYW5kS2V5cy5sZW5ndGggJiYgbGVmdEhhbmRLZXlzLmxlbmd0aCA9PT0gcmlnaHRIYW5kS2V5cy5sZW5ndGgpIHtcbiAgICBpZiAoaXRlcmFibGVFcXVhbChtYXBTeW1ib2xzKGxlZnRIYW5kS2V5cykuc29ydCgpLCBtYXBTeW1ib2xzKHJpZ2h0SGFuZEtleXMpLnNvcnQoKSkgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiBrZXlzRXF1YWwobGVmdEhhbmRPcGVyYW5kLCByaWdodEhhbmRPcGVyYW5kLCBsZWZ0SGFuZEtleXMsIG9wdGlvbnMpO1xuICB9XG5cbiAgdmFyIGxlZnRIYW5kRW50cmllcyA9IGdldEl0ZXJhdG9yRW50cmllcyhsZWZ0SGFuZE9wZXJhbmQpO1xuICB2YXIgcmlnaHRIYW5kRW50cmllcyA9IGdldEl0ZXJhdG9yRW50cmllcyhyaWdodEhhbmRPcGVyYW5kKTtcbiAgaWYgKGxlZnRIYW5kRW50cmllcy5sZW5ndGggJiYgbGVmdEhhbmRFbnRyaWVzLmxlbmd0aCA9PT0gcmlnaHRIYW5kRW50cmllcy5sZW5ndGgpIHtcbiAgICBsZWZ0SGFuZEVudHJpZXMuc29ydCgpO1xuICAgIHJpZ2h0SGFuZEVudHJpZXMuc29ydCgpO1xuICAgIHJldHVybiBpdGVyYWJsZUVxdWFsKGxlZnRIYW5kRW50cmllcywgcmlnaHRIYW5kRW50cmllcywgb3B0aW9ucyk7XG4gIH1cblxuICBpZiAobGVmdEhhbmRLZXlzLmxlbmd0aCA9PT0gMCAmJlxuICAgICAgbGVmdEhhbmRFbnRyaWVzLmxlbmd0aCA9PT0gMCAmJlxuICAgICAgcmlnaHRIYW5kS2V5cy5sZW5ndGggPT09IDAgJiZcbiAgICAgIHJpZ2h0SGFuZEVudHJpZXMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qIVxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBhcmd1bWVudCBpcyBhIHByaW1pdGl2ZS5cbiAqXG4gKiBUaGlzIGludGVudGlvbmFsbHkgcmV0dXJucyB0cnVlIGZvciBhbGwgb2JqZWN0cyB0aGF0IGNhbiBiZSBjb21wYXJlZCBieSByZWZlcmVuY2UsXG4gKiBpbmNsdWRpbmcgZnVuY3Rpb25zIGFuZCBzeW1ib2xzLlxuICpcbiAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gKiBAcmV0dXJuIHtCb29sZWFufSByZXN1bHRcbiAqL1xuZnVuY3Rpb24gaXNQcmltaXRpdmUodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlID09PSBudWxsIHx8IHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCc7XG59XG5cbmZ1bmN0aW9uIG1hcFN5bWJvbHMoYXJyKSB7XG4gIHJldHVybiBhcnIubWFwKGZ1bmN0aW9uIG1hcFN5bWJvbChlbnRyeSkge1xuICAgIGlmICh0eXBlb2YgZW50cnkgPT09ICdzeW1ib2wnKSB7XG4gICAgICByZXR1cm4gZW50cnkudG9TdHJpbmcoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZW50cnk7XG4gIH0pO1xufVxuIiwgInZhciBjb25maWcgPSByZXF1aXJlKCcuLi9jb25maWcnKTtcblxuLyohXG4gKiBDaGFpIC0gaXNQcm94eUVuYWJsZWQgaGVscGVyXG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyoqXG4gKiAjIyMgLmlzUHJveHlFbmFibGVkKClcbiAqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdG8gY2hlY2sgaWYgQ2hhaSdzIHByb3h5IHByb3RlY3Rpb24gZmVhdHVyZSBpcyBlbmFibGVkLiBJZlxuICogcHJveGllcyBhcmUgdW5zdXBwb3J0ZWQgb3IgZGlzYWJsZWQgdmlhIHRoZSB1c2VyJ3MgQ2hhaSBjb25maWcsIHRoZW4gcmV0dXJuXG4gKiBmYWxzZS4gT3RoZXJ3aXNlLCByZXR1cm4gdHJ1ZS5cbiAqXG4gKiBAbmFtZXNwYWNlIFV0aWxzXG4gKiBAbmFtZSBpc1Byb3h5RW5hYmxlZFxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNQcm94eUVuYWJsZWQoKSB7XG4gIHJldHVybiBjb25maWcudXNlUHJveHkgJiZcbiAgICB0eXBlb2YgUHJveHkgIT09ICd1bmRlZmluZWQnICYmXG4gICAgdHlwZW9mIFJlZmxlY3QgIT09ICd1bmRlZmluZWQnO1xufTtcbiIsICIvKiFcbiAqIENoYWkgLSBhZGRQcm9wZXJ0eSB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxudmFyIGNoYWkgPSByZXF1aXJlKCcuLi8uLi9jaGFpJyk7XG52YXIgZmxhZyA9IHJlcXVpcmUoJy4vZmxhZycpO1xudmFyIGlzUHJveHlFbmFibGVkID0gcmVxdWlyZSgnLi9pc1Byb3h5RW5hYmxlZCcpO1xudmFyIHRyYW5zZmVyRmxhZ3MgPSByZXF1aXJlKCcuL3RyYW5zZmVyRmxhZ3MnKTtcblxuLyoqXG4gKiAjIyMgLmFkZFByb3BlcnR5KGN0eCwgbmFtZSwgZ2V0dGVyKVxuICpcbiAqIEFkZHMgYSBwcm9wZXJ0eSB0byB0aGUgcHJvdG90eXBlIG9mIGFuIG9iamVjdC5cbiAqXG4gKiAgICAgdXRpbHMuYWRkUHJvcGVydHkoY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLCAnZm9vJywgZnVuY3Rpb24gKCkge1xuICogICAgICAgdmFyIG9iaiA9IHV0aWxzLmZsYWcodGhpcywgJ29iamVjdCcpO1xuICogICAgICAgbmV3IGNoYWkuQXNzZXJ0aW9uKG9iaikudG8uYmUuaW5zdGFuY2VvZihGb28pO1xuICogICAgIH0pO1xuICpcbiAqIENhbiBhbHNvIGJlIGFjY2Vzc2VkIGRpcmVjdGx5IGZyb20gYGNoYWkuQXNzZXJ0aW9uYC5cbiAqXG4gKiAgICAgY2hhaS5Bc3NlcnRpb24uYWRkUHJvcGVydHkoJ2ZvbycsIGZuKTtcbiAqXG4gKiBUaGVuIGNhbiBiZSB1c2VkIGFzIGFueSBvdGhlciBhc3NlcnRpb24uXG4gKlxuICogICAgIGV4cGVjdChteUZvbykudG8uYmUuZm9vO1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjdHggb2JqZWN0IHRvIHdoaWNoIHRoZSBwcm9wZXJ0eSBpcyBhZGRlZFxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgb2YgcHJvcGVydHkgdG8gYWRkXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBnZXR0ZXIgZnVuY3Rpb24gdG8gYmUgdXNlZCBmb3IgbmFtZVxuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQG5hbWUgYWRkUHJvcGVydHlcbiAqIEBhcGkgcHVibGljXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBhZGRQcm9wZXJ0eShjdHgsIG5hbWUsIGdldHRlcikge1xuICBnZXR0ZXIgPSBnZXR0ZXIgPT09IHVuZGVmaW5lZCA/IGZ1bmN0aW9uICgpIHt9IDogZ2V0dGVyO1xuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjdHgsIG5hbWUsXG4gICAgeyBnZXQ6IGZ1bmN0aW9uIHByb3BlcnR5R2V0dGVyKCkge1xuICAgICAgICAvLyBTZXR0aW5nIHRoZSBgc3NmaWAgZmxhZyB0byBgcHJvcGVydHlHZXR0ZXJgIGNhdXNlcyB0aGlzIGZ1bmN0aW9uIHRvXG4gICAgICAgIC8vIGJlIHRoZSBzdGFydGluZyBwb2ludCBmb3IgcmVtb3ZpbmcgaW1wbGVtZW50YXRpb24gZnJhbWVzIGZyb20gdGhlXG4gICAgICAgIC8vIHN0YWNrIHRyYWNlIG9mIGEgZmFpbGVkIGFzc2VydGlvbi5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gSG93ZXZlciwgd2Ugb25seSB3YW50IHRvIHVzZSB0aGlzIGZ1bmN0aW9uIGFzIHRoZSBzdGFydGluZyBwb2ludCBpZlxuICAgICAgICAvLyB0aGUgYGxvY2tTc2ZpYCBmbGFnIGlzbid0IHNldCBhbmQgcHJveHkgcHJvdGVjdGlvbiBpcyBkaXNhYmxlZC5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gSWYgdGhlIGBsb2NrU3NmaWAgZmxhZyBpcyBzZXQsIHRoZW4gZWl0aGVyIHRoaXMgYXNzZXJ0aW9uIGhhcyBiZWVuXG4gICAgICAgIC8vIG92ZXJ3cml0dGVuIGJ5IGFub3RoZXIgYXNzZXJ0aW9uLCBvciB0aGlzIGFzc2VydGlvbiBpcyBiZWluZyBpbnZva2VkXG4gICAgICAgIC8vIGZyb20gaW5zaWRlIG9mIGFub3RoZXIgYXNzZXJ0aW9uLiBJbiB0aGUgZmlyc3QgY2FzZSwgdGhlIGBzc2ZpYCBmbGFnXG4gICAgICAgIC8vIGhhcyBhbHJlYWR5IGJlZW4gc2V0IGJ5IHRoZSBvdmVyd3JpdGluZyBhc3NlcnRpb24uIEluIHRoZSBzZWNvbmRcbiAgICAgICAgLy8gY2FzZSwgdGhlIGBzc2ZpYCBmbGFnIGhhcyBhbHJlYWR5IGJlZW4gc2V0IGJ5IHRoZSBvdXRlciBhc3NlcnRpb24uXG4gICAgICAgIC8vXG4gICAgICAgIC8vIElmIHByb3h5IHByb3RlY3Rpb24gaXMgZW5hYmxlZCwgdGhlbiB0aGUgYHNzZmlgIGZsYWcgaGFzIGFscmVhZHkgYmVlblxuICAgICAgICAvLyBzZXQgYnkgdGhlIHByb3h5IGdldHRlci5cbiAgICAgICAgaWYgKCFpc1Byb3h5RW5hYmxlZCgpICYmICFmbGFnKHRoaXMsICdsb2NrU3NmaScpKSB7XG4gICAgICAgICAgZmxhZyh0aGlzLCAnc3NmaScsIHByb3BlcnR5R2V0dGVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciByZXN1bHQgPSBnZXR0ZXIuY2FsbCh0aGlzKTtcbiAgICAgICAgaWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKVxuICAgICAgICAgIHJldHVybiByZXN1bHQ7XG5cbiAgICAgICAgdmFyIG5ld0Fzc2VydGlvbiA9IG5ldyBjaGFpLkFzc2VydGlvbigpO1xuICAgICAgICB0cmFuc2ZlckZsYWdzKHRoaXMsIG5ld0Fzc2VydGlvbik7XG4gICAgICAgIHJldHVybiBuZXdBc3NlcnRpb247XG4gICAgICB9XG4gICAgLCBjb25maWd1cmFibGU6IHRydWVcbiAgfSk7XG59O1xuIiwgInZhciBmbkxlbmd0aERlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGZ1bmN0aW9uICgpIHt9LCAnbGVuZ3RoJyk7XG5cbi8qIVxuICogQ2hhaSAtIGFkZExlbmd0aEd1YXJkIHV0aWxpdHlcbiAqIENvcHlyaWdodChjKSAyMDEyLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG4vKipcbiAqICMjIyAuYWRkTGVuZ3RoR3VhcmQoZm4sIGFzc2VydGlvbk5hbWUsIGlzQ2hhaW5hYmxlKVxuICpcbiAqIERlZmluZSBgbGVuZ3RoYCBhcyBhIGdldHRlciBvbiB0aGUgZ2l2ZW4gdW5pbnZva2VkIG1ldGhvZCBhc3NlcnRpb24uIFRoZVxuICogZ2V0dGVyIGFjdHMgYXMgYSBndWFyZCBhZ2FpbnN0IGNoYWluaW5nIGBsZW5ndGhgIGRpcmVjdGx5IG9mZiBvZiBhbiB1bmludm9rZWRcbiAqIG1ldGhvZCBhc3NlcnRpb24sIHdoaWNoIGlzIGEgcHJvYmxlbSBiZWNhdXNlIGl0IHJlZmVyZW5jZXMgYGZ1bmN0aW9uYCdzXG4gKiBidWlsdC1pbiBgbGVuZ3RoYCBwcm9wZXJ0eSBpbnN0ZWFkIG9mIENoYWkncyBgbGVuZ3RoYCBhc3NlcnRpb24uIFdoZW4gdGhlXG4gKiBnZXR0ZXIgY2F0Y2hlcyB0aGUgdXNlciBtYWtpbmcgdGhpcyBtaXN0YWtlLCBpdCB0aHJvd3MgYW4gZXJyb3Igd2l0aCBhXG4gKiBoZWxwZnVsIG1lc3NhZ2UuXG4gKlxuICogVGhlcmUgYXJlIHR3byB3YXlzIGluIHdoaWNoIHRoaXMgbWlzdGFrZSBjYW4gYmUgbWFkZS4gVGhlIGZpcnN0IHdheSBpcyBieVxuICogY2hhaW5pbmcgdGhlIGBsZW5ndGhgIGFzc2VydGlvbiBkaXJlY3RseSBvZmYgb2YgYW4gdW5pbnZva2VkIGNoYWluYWJsZVxuICogbWV0aG9kLiBJbiB0aGlzIGNhc2UsIENoYWkgc3VnZ2VzdHMgdGhhdCB0aGUgdXNlciB1c2UgYGxlbmd0aE9mYCBpbnN0ZWFkLiBUaGVcbiAqIHNlY29uZCB3YXkgaXMgYnkgY2hhaW5pbmcgdGhlIGBsZW5ndGhgIGFzc2VydGlvbiBkaXJlY3RseSBvZmYgb2YgYW4gdW5pbnZva2VkXG4gKiBub24tY2hhaW5hYmxlIG1ldGhvZC4gTm9uLWNoYWluYWJsZSBtZXRob2RzIG11c3QgYmUgaW52b2tlZCBwcmlvciB0b1xuICogY2hhaW5pbmcuIEluIHRoaXMgY2FzZSwgQ2hhaSBzdWdnZXN0cyB0aGF0IHRoZSB1c2VyIGNvbnN1bHQgdGhlIGRvY3MgZm9yIHRoZVxuICogZ2l2ZW4gYXNzZXJ0aW9uLlxuICpcbiAqIElmIHRoZSBgbGVuZ3RoYCBwcm9wZXJ0eSBvZiBmdW5jdGlvbnMgaXMgdW5jb25maWd1cmFibGUsIHRoZW4gcmV0dXJuIGBmbmBcbiAqIHdpdGhvdXQgbW9kaWZpY2F0aW9uLlxuICpcbiAqIE5vdGUgdGhhdCBpbiBFUzYsIHRoZSBmdW5jdGlvbidzIGBsZW5ndGhgIHByb3BlcnR5IGlzIGNvbmZpZ3VyYWJsZSwgc28gb25jZVxuICogc3VwcG9ydCBmb3IgbGVnYWN5IGVudmlyb25tZW50cyBpcyBkcm9wcGVkLCBDaGFpJ3MgYGxlbmd0aGAgcHJvcGVydHkgY2FuXG4gKiByZXBsYWNlIHRoZSBidWlsdC1pbiBmdW5jdGlvbidzIGBsZW5ndGhgIHByb3BlcnR5LCBhbmQgdGhpcyBsZW5ndGggZ3VhcmQgd2lsbFxuICogbm8gbG9uZ2VyIGJlIG5lY2Vzc2FyeS4gSW4gdGhlIG1lYW4gdGltZSwgbWFpbnRhaW5pbmcgY29uc2lzdGVuY3kgYWNyb3NzIGFsbFxuICogZW52aXJvbm1lbnRzIGlzIHRoZSBwcmlvcml0eS5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHBhcmFtIHtTdHJpbmd9IGFzc2VydGlvbk5hbWVcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gaXNDaGFpbmFibGVcbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBuYW1lIGFkZExlbmd0aEd1YXJkXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBhZGRMZW5ndGhHdWFyZCAoZm4sIGFzc2VydGlvbk5hbWUsIGlzQ2hhaW5hYmxlKSB7XG4gIGlmICghZm5MZW5ndGhEZXNjLmNvbmZpZ3VyYWJsZSkgcmV0dXJuIGZuO1xuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShmbiwgJ2xlbmd0aCcsIHtcbiAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmIChpc0NoYWluYWJsZSkge1xuICAgICAgICB0aHJvdyBFcnJvcignSW52YWxpZCBDaGFpIHByb3BlcnR5OiAnICsgYXNzZXJ0aW9uTmFtZSArICcubGVuZ3RoLiBEdWUnICtcbiAgICAgICAgICAnIHRvIGEgY29tcGF0aWJpbGl0eSBpc3N1ZSwgXCJsZW5ndGhcIiBjYW5ub3QgZGlyZWN0bHkgZm9sbG93IFwiJyArXG4gICAgICAgICAgYXNzZXJ0aW9uTmFtZSArICdcIi4gVXNlIFwiJyArIGFzc2VydGlvbk5hbWUgKyAnLmxlbmd0aE9mXCIgaW5zdGVhZC4nKTtcbiAgICAgIH1cblxuICAgICAgdGhyb3cgRXJyb3IoJ0ludmFsaWQgQ2hhaSBwcm9wZXJ0eTogJyArIGFzc2VydGlvbk5hbWUgKyAnLmxlbmd0aC4gU2VlJyArXG4gICAgICAgICcgZG9jcyBmb3IgcHJvcGVyIHVzYWdlIG9mIFwiJyArIGFzc2VydGlvbk5hbWUgKyAnXCIuJyk7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gZm47XG59O1xuIiwgIi8qIVxuICogQ2hhaSAtIGdldFByb3BlcnRpZXMgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbi8qKlxuICogIyMjIC5nZXRQcm9wZXJ0aWVzKG9iamVjdClcbiAqXG4gKiBUaGlzIGFsbG93cyB0aGUgcmV0cmlldmFsIG9mIHByb3BlcnR5IG5hbWVzIG9mIGFuIG9iamVjdCwgZW51bWVyYWJsZSBvciBub3QsXG4gKiBpbmhlcml0ZWQgb3Igbm90LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAqIEByZXR1cm5zIHtBcnJheX1cbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBuYW1lIGdldFByb3BlcnRpZXNcbiAqIEBhcGkgcHVibGljXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBnZXRQcm9wZXJ0aWVzKG9iamVjdCkge1xuICB2YXIgcmVzdWx0ID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMob2JqZWN0KTtcblxuICBmdW5jdGlvbiBhZGRQcm9wZXJ0eShwcm9wZXJ0eSkge1xuICAgIGlmIChyZXN1bHQuaW5kZXhPZihwcm9wZXJ0eSkgPT09IC0xKSB7XG4gICAgICByZXN1bHQucHVzaChwcm9wZXJ0eSk7XG4gICAgfVxuICB9XG5cbiAgdmFyIHByb3RvID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKG9iamVjdCk7XG4gIHdoaWxlIChwcm90byAhPT0gbnVsbCkge1xuICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHByb3RvKS5mb3JFYWNoKGFkZFByb3BlcnR5KTtcbiAgICBwcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihwcm90byk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufTtcbiIsICJ2YXIgY29uZmlnID0gcmVxdWlyZSgnLi4vY29uZmlnJyk7XG52YXIgZmxhZyA9IHJlcXVpcmUoJy4vZmxhZycpO1xudmFyIGdldFByb3BlcnRpZXMgPSByZXF1aXJlKCcuL2dldFByb3BlcnRpZXMnKTtcbnZhciBpc1Byb3h5RW5hYmxlZCA9IHJlcXVpcmUoJy4vaXNQcm94eUVuYWJsZWQnKTtcblxuLyohXG4gKiBDaGFpIC0gcHJveGlmeSB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyoqXG4gKiAjIyMgLnByb3hpZnkob2JqZWN0KVxuICpcbiAqIFJldHVybiBhIHByb3h5IG9mIGdpdmVuIG9iamVjdCB0aGF0IHRocm93cyBhbiBlcnJvciB3aGVuIGEgbm9uLWV4aXN0ZW50XG4gKiBwcm9wZXJ0eSBpcyByZWFkLiBCeSBkZWZhdWx0LCB0aGUgcm9vdCBjYXVzZSBpcyBhc3N1bWVkIHRvIGJlIGEgbWlzc3BlbGxlZFxuICogcHJvcGVydHksIGFuZCB0aHVzIGFuIGF0dGVtcHQgaXMgbWFkZSB0byBvZmZlciBhIHJlYXNvbmFibGUgc3VnZ2VzdGlvbiBmcm9tXG4gKiB0aGUgbGlzdCBvZiBleGlzdGluZyBwcm9wZXJ0aWVzLiBIb3dldmVyLCBpZiBhIG5vbkNoYWluYWJsZU1ldGhvZE5hbWUgaXNcbiAqIHByb3ZpZGVkLCB0aGVuIHRoZSByb290IGNhdXNlIGlzIGluc3RlYWQgYSBmYWlsdXJlIHRvIGludm9rZSBhIG5vbi1jaGFpbmFibGVcbiAqIG1ldGhvZCBwcmlvciB0byByZWFkaW5nIHRoZSBub24tZXhpc3RlbnQgcHJvcGVydHkuXG4gKlxuICogSWYgcHJveGllcyBhcmUgdW5zdXBwb3J0ZWQgb3IgZGlzYWJsZWQgdmlhIHRoZSB1c2VyJ3MgQ2hhaSBjb25maWcsIHRoZW5cbiAqIHJldHVybiBvYmplY3Qgd2l0aG91dCBtb2RpZmljYXRpb24uXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICogQHBhcmFtIHtTdHJpbmd9IG5vbkNoYWluYWJsZU1ldGhvZE5hbWVcbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBuYW1lIHByb3hpZnlcbiAqL1xuXG52YXIgYnVpbHRpbnMgPSBbJ19fZmxhZ3MnLCAnX19tZXRob2RzJywgJ19vYmonLCAnYXNzZXJ0J107XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcHJveGlmeShvYmosIG5vbkNoYWluYWJsZU1ldGhvZE5hbWUpIHtcbiAgaWYgKCFpc1Byb3h5RW5hYmxlZCgpKSByZXR1cm4gb2JqO1xuXG4gIHJldHVybiBuZXcgUHJveHkob2JqLCB7XG4gICAgZ2V0OiBmdW5jdGlvbiBwcm94eUdldHRlcih0YXJnZXQsIHByb3BlcnR5KSB7XG4gICAgICAvLyBUaGlzIGNoZWNrIGlzIGhlcmUgYmVjYXVzZSB3ZSBzaG91bGQgbm90IHRocm93IGVycm9ycyBvbiBTeW1ib2wgcHJvcGVydGllc1xuICAgICAgLy8gc3VjaCBhcyBgU3ltYm9sLnRvU3RyaW5nVGFnYC5cbiAgICAgIC8vIFRoZSB2YWx1ZXMgZm9yIHdoaWNoIGFuIGVycm9yIHNob3VsZCBiZSB0aHJvd24gY2FuIGJlIGNvbmZpZ3VyZWQgdXNpbmdcbiAgICAgIC8vIHRoZSBgY29uZmlnLnByb3h5RXhjbHVkZWRLZXlzYCBzZXR0aW5nLlxuICAgICAgaWYgKHR5cGVvZiBwcm9wZXJ0eSA9PT0gJ3N0cmluZycgJiZcbiAgICAgICAgICBjb25maWcucHJveHlFeGNsdWRlZEtleXMuaW5kZXhPZihwcm9wZXJ0eSkgPT09IC0xICYmXG4gICAgICAgICAgIVJlZmxlY3QuaGFzKHRhcmdldCwgcHJvcGVydHkpKSB7XG4gICAgICAgIC8vIFNwZWNpYWwgbWVzc2FnZSBmb3IgaW52YWxpZCBwcm9wZXJ0eSBhY2Nlc3Mgb2Ygbm9uLWNoYWluYWJsZSBtZXRob2RzLlxuICAgICAgICBpZiAobm9uQ2hhaW5hYmxlTWV0aG9kTmFtZSkge1xuICAgICAgICAgIHRocm93IEVycm9yKCdJbnZhbGlkIENoYWkgcHJvcGVydHk6ICcgKyBub25DaGFpbmFibGVNZXRob2ROYW1lICsgJy4nICtcbiAgICAgICAgICAgIHByb3BlcnR5ICsgJy4gU2VlIGRvY3MgZm9yIHByb3BlciB1c2FnZSBvZiBcIicgK1xuICAgICAgICAgICAgbm9uQ2hhaW5hYmxlTWV0aG9kTmFtZSArICdcIi4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIElmIHRoZSBwcm9wZXJ0eSBpcyByZWFzb25hYmx5IGNsb3NlIHRvIGFuIGV4aXN0aW5nIENoYWkgcHJvcGVydHksXG4gICAgICAgIC8vIHN1Z2dlc3QgdGhhdCBwcm9wZXJ0eSB0byB0aGUgdXNlci4gT25seSBzdWdnZXN0IHByb3BlcnRpZXMgd2l0aCBhXG4gICAgICAgIC8vIGRpc3RhbmNlIGxlc3MgdGhhbiA0LlxuICAgICAgICB2YXIgc3VnZ2VzdGlvbiA9IG51bGw7XG4gICAgICAgIHZhciBzdWdnZXN0aW9uRGlzdGFuY2UgPSA0O1xuICAgICAgICBnZXRQcm9wZXJ0aWVzKHRhcmdldCkuZm9yRWFjaChmdW5jdGlvbihwcm9wKSB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkocHJvcCkgJiZcbiAgICAgICAgICAgIGJ1aWx0aW5zLmluZGV4T2YocHJvcCkgPT09IC0xXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICB2YXIgZGlzdCA9IHN0cmluZ0Rpc3RhbmNlQ2FwcGVkKFxuICAgICAgICAgICAgICBwcm9wZXJ0eSxcbiAgICAgICAgICAgICAgcHJvcCxcbiAgICAgICAgICAgICAgc3VnZ2VzdGlvbkRpc3RhbmNlXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKGRpc3QgPCBzdWdnZXN0aW9uRGlzdGFuY2UpIHtcbiAgICAgICAgICAgICAgc3VnZ2VzdGlvbiA9IHByb3A7XG4gICAgICAgICAgICAgIHN1Z2dlc3Rpb25EaXN0YW5jZSA9IGRpc3Q7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoc3VnZ2VzdGlvbiAhPT0gbnVsbCkge1xuICAgICAgICAgIHRocm93IEVycm9yKCdJbnZhbGlkIENoYWkgcHJvcGVydHk6ICcgKyBwcm9wZXJ0eSArXG4gICAgICAgICAgICAnLiBEaWQgeW91IG1lYW4gXCInICsgc3VnZ2VzdGlvbiArICdcIj8nKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBFcnJvcignSW52YWxpZCBDaGFpIHByb3BlcnR5OiAnICsgcHJvcGVydHkpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFVzZSB0aGlzIHByb3h5IGdldHRlciBhcyB0aGUgc3RhcnRpbmcgcG9pbnQgZm9yIHJlbW92aW5nIGltcGxlbWVudGF0aW9uXG4gICAgICAvLyBmcmFtZXMgZnJvbSB0aGUgc3RhY2sgdHJhY2Ugb2YgYSBmYWlsZWQgYXNzZXJ0aW9uLiBGb3IgcHJvcGVydHlcbiAgICAgIC8vIGFzc2VydGlvbnMsIHRoaXMgcHJldmVudHMgdGhlIHByb3h5IGdldHRlciBmcm9tIHNob3dpbmcgdXAgaW4gdGhlIHN0YWNrXG4gICAgICAvLyB0cmFjZSBzaW5jZSBpdCdzIGludm9rZWQgYmVmb3JlIHRoZSBwcm9wZXJ0eSBnZXR0ZXIuIEZvciBtZXRob2QgYW5kXG4gICAgICAvLyBjaGFpbmFibGUgbWV0aG9kIGFzc2VydGlvbnMsIHRoaXMgZmxhZyB3aWxsIGVuZCB1cCBnZXR0aW5nIGNoYW5nZWQgdG9cbiAgICAgIC8vIHRoZSBtZXRob2Qgd3JhcHBlciwgd2hpY2ggaXMgZ29vZCBzaW5jZSB0aGlzIGZyYW1lIHdpbGwgbm8gbG9uZ2VyIGJlIGluXG4gICAgICAvLyB0aGUgc3RhY2sgb25jZSB0aGUgbWV0aG9kIGlzIGludm9rZWQuIE5vdGUgdGhhdCBDaGFpIGJ1aWx0aW4gYXNzZXJ0aW9uXG4gICAgICAvLyBwcm9wZXJ0aWVzIHN1Y2ggYXMgYF9fZmxhZ3NgIGFyZSBza2lwcGVkIHNpbmNlIHRoaXMgaXMgb25seSBtZWFudCB0b1xuICAgICAgLy8gY2FwdHVyZSB0aGUgc3RhcnRpbmcgcG9pbnQgb2YgYW4gYXNzZXJ0aW9uLiBUaGlzIHN0ZXAgaXMgYWxzbyBza2lwcGVkXG4gICAgICAvLyBpZiB0aGUgYGxvY2tTc2ZpYCBmbGFnIGlzIHNldCwgdGh1cyBpbmRpY2F0aW5nIHRoYXQgdGhpcyBhc3NlcnRpb24gaXNcbiAgICAgIC8vIGJlaW5nIGNhbGxlZCBmcm9tIHdpdGhpbiBhbm90aGVyIGFzc2VydGlvbi4gSW4gdGhhdCBjYXNlLCB0aGUgYHNzZmlgXG4gICAgICAvLyBmbGFnIGlzIGFscmVhZHkgc2V0IHRvIHRoZSBvdXRlciBhc3NlcnRpb24ncyBzdGFydGluZyBwb2ludC5cbiAgICAgIGlmIChidWlsdGlucy5pbmRleE9mKHByb3BlcnR5KSA9PT0gLTEgJiYgIWZsYWcodGFyZ2V0LCAnbG9ja1NzZmknKSkge1xuICAgICAgICBmbGFnKHRhcmdldCwgJ3NzZmknLCBwcm94eUdldHRlcik7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBSZWZsZWN0LmdldCh0YXJnZXQsIHByb3BlcnR5KTtcbiAgICB9XG4gIH0pO1xufTtcblxuLyoqXG4gKiAjIHN0cmluZ0Rpc3RhbmNlQ2FwcGVkKHN0ckEsIHN0ckIsIGNhcClcbiAqIFJldHVybiB0aGUgTGV2ZW5zaHRlaW4gZGlzdGFuY2UgYmV0d2VlbiB0d28gc3RyaW5ncywgYnV0IG5vIG1vcmUgdGhhbiBjYXAuXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyQVxuICogQHBhcmFtIHtzdHJpbmd9IHN0ckJcbiAqIEBwYXJhbSB7bnVtYmVyfSBudW1iZXJcbiAqIEByZXR1cm4ge251bWJlcn0gbWluKHN0cmluZyBkaXN0YW5jZSBiZXR3ZWVuIHN0ckEgYW5kIHN0ckIsIGNhcClcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHN0cmluZ0Rpc3RhbmNlQ2FwcGVkKHN0ckEsIHN0ckIsIGNhcCkge1xuICBpZiAoTWF0aC5hYnMoc3RyQS5sZW5ndGggLSBzdHJCLmxlbmd0aCkgPj0gY2FwKSB7XG4gICAgcmV0dXJuIGNhcDtcbiAgfVxuXG4gIHZhciBtZW1vID0gW107XG4gIC8vIGBtZW1vYCBpcyBhIHR3by1kaW1lbnNpb25hbCBhcnJheSBjb250YWluaW5nIGRpc3RhbmNlcy5cbiAgLy8gbWVtb1tpXVtqXSBpcyB0aGUgZGlzdGFuY2UgYmV0d2VlbiBzdHJBLnNsaWNlKDAsIGkpIGFuZFxuICAvLyBzdHJCLnNsaWNlKDAsIGopLlxuICBmb3IgKHZhciBpID0gMDsgaSA8PSBzdHJBLmxlbmd0aDsgaSsrKSB7XG4gICAgbWVtb1tpXSA9IEFycmF5KHN0ckIubGVuZ3RoICsgMSkuZmlsbCgwKTtcbiAgICBtZW1vW2ldWzBdID0gaTtcbiAgfVxuICBmb3IgKHZhciBqID0gMDsgaiA8IHN0ckIubGVuZ3RoOyBqKyspIHtcbiAgICBtZW1vWzBdW2pdID0gajtcbiAgfVxuXG4gIGZvciAodmFyIGkgPSAxOyBpIDw9IHN0ckEubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgY2ggPSBzdHJBLmNoYXJDb2RlQXQoaSAtIDEpO1xuICAgIGZvciAodmFyIGogPSAxOyBqIDw9IHN0ckIubGVuZ3RoOyBqKyspIHtcbiAgICAgIGlmIChNYXRoLmFicyhpIC0gaikgPj0gY2FwKSB7XG4gICAgICAgIG1lbW9baV1bal0gPSBjYXA7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgbWVtb1tpXVtqXSA9IE1hdGgubWluKFxuICAgICAgICBtZW1vW2kgLSAxXVtqXSArIDEsXG4gICAgICAgIG1lbW9baV1baiAtIDFdICsgMSxcbiAgICAgICAgbWVtb1tpIC0gMV1baiAtIDFdICtcbiAgICAgICAgICAoY2ggPT09IHN0ckIuY2hhckNvZGVBdChqIC0gMSkgPyAwIDogMSlcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG1lbW9bc3RyQS5sZW5ndGhdW3N0ckIubGVuZ3RoXTtcbn1cbiIsICIvKiFcbiAqIENoYWkgLSBhZGRNZXRob2QgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbnZhciBhZGRMZW5ndGhHdWFyZCA9IHJlcXVpcmUoJy4vYWRkTGVuZ3RoR3VhcmQnKTtcbnZhciBjaGFpID0gcmVxdWlyZSgnLi4vLi4vY2hhaScpO1xudmFyIGZsYWcgPSByZXF1aXJlKCcuL2ZsYWcnKTtcbnZhciBwcm94aWZ5ID0gcmVxdWlyZSgnLi9wcm94aWZ5Jyk7XG52YXIgdHJhbnNmZXJGbGFncyA9IHJlcXVpcmUoJy4vdHJhbnNmZXJGbGFncycpO1xuXG4vKipcbiAqICMjIyAuYWRkTWV0aG9kKGN0eCwgbmFtZSwgbWV0aG9kKVxuICpcbiAqIEFkZHMgYSBtZXRob2QgdG8gdGhlIHByb3RvdHlwZSBvZiBhbiBvYmplY3QuXG4gKlxuICogICAgIHV0aWxzLmFkZE1ldGhvZChjaGFpLkFzc2VydGlvbi5wcm90b3R5cGUsICdmb28nLCBmdW5jdGlvbiAoc3RyKSB7XG4gKiAgICAgICB2YXIgb2JqID0gdXRpbHMuZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gKiAgICAgICBuZXcgY2hhaS5Bc3NlcnRpb24ob2JqKS50by5iZS5lcXVhbChzdHIpO1xuICogICAgIH0pO1xuICpcbiAqIENhbiBhbHNvIGJlIGFjY2Vzc2VkIGRpcmVjdGx5IGZyb20gYGNoYWkuQXNzZXJ0aW9uYC5cbiAqXG4gKiAgICAgY2hhaS5Bc3NlcnRpb24uYWRkTWV0aG9kKCdmb28nLCBmbik7XG4gKlxuICogVGhlbiBjYW4gYmUgdXNlZCBhcyBhbnkgb3RoZXIgYXNzZXJ0aW9uLlxuICpcbiAqICAgICBleHBlY3QoZm9vU3RyKS50by5iZS5mb28oJ2JhcicpO1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjdHggb2JqZWN0IHRvIHdoaWNoIHRoZSBtZXRob2QgaXMgYWRkZWRcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIG9mIG1ldGhvZCB0byBhZGRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IG1ldGhvZCBmdW5jdGlvbiB0byBiZSB1c2VkIGZvciBuYW1lXG4gKiBAbmFtZXNwYWNlIFV0aWxzXG4gKiBAbmFtZSBhZGRNZXRob2RcbiAqIEBhcGkgcHVibGljXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBhZGRNZXRob2QoY3R4LCBuYW1lLCBtZXRob2QpIHtcbiAgdmFyIG1ldGhvZFdyYXBwZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgLy8gU2V0dGluZyB0aGUgYHNzZmlgIGZsYWcgdG8gYG1ldGhvZFdyYXBwZXJgIGNhdXNlcyB0aGlzIGZ1bmN0aW9uIHRvIGJlIHRoZVxuICAgIC8vIHN0YXJ0aW5nIHBvaW50IGZvciByZW1vdmluZyBpbXBsZW1lbnRhdGlvbiBmcmFtZXMgZnJvbSB0aGUgc3RhY2sgdHJhY2Ugb2ZcbiAgICAvLyBhIGZhaWxlZCBhc3NlcnRpb24uXG4gICAgLy9cbiAgICAvLyBIb3dldmVyLCB3ZSBvbmx5IHdhbnQgdG8gdXNlIHRoaXMgZnVuY3Rpb24gYXMgdGhlIHN0YXJ0aW5nIHBvaW50IGlmIHRoZVxuICAgIC8vIGBsb2NrU3NmaWAgZmxhZyBpc24ndCBzZXQuXG4gICAgLy9cbiAgICAvLyBJZiB0aGUgYGxvY2tTc2ZpYCBmbGFnIGlzIHNldCwgdGhlbiBlaXRoZXIgdGhpcyBhc3NlcnRpb24gaGFzIGJlZW5cbiAgICAvLyBvdmVyd3JpdHRlbiBieSBhbm90aGVyIGFzc2VydGlvbiwgb3IgdGhpcyBhc3NlcnRpb24gaXMgYmVpbmcgaW52b2tlZCBmcm9tXG4gICAgLy8gaW5zaWRlIG9mIGFub3RoZXIgYXNzZXJ0aW9uLiBJbiB0aGUgZmlyc3QgY2FzZSwgdGhlIGBzc2ZpYCBmbGFnIGhhc1xuICAgIC8vIGFscmVhZHkgYmVlbiBzZXQgYnkgdGhlIG92ZXJ3cml0aW5nIGFzc2VydGlvbi4gSW4gdGhlIHNlY29uZCBjYXNlLCB0aGVcbiAgICAvLyBgc3NmaWAgZmxhZyBoYXMgYWxyZWFkeSBiZWVuIHNldCBieSB0aGUgb3V0ZXIgYXNzZXJ0aW9uLlxuICAgIGlmICghZmxhZyh0aGlzLCAnbG9ja1NzZmknKSkge1xuICAgICAgZmxhZyh0aGlzLCAnc3NmaScsIG1ldGhvZFdyYXBwZXIpO1xuICAgIH1cblxuICAgIHZhciByZXN1bHQgPSBtZXRob2QuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQpXG4gICAgICByZXR1cm4gcmVzdWx0O1xuXG4gICAgdmFyIG5ld0Fzc2VydGlvbiA9IG5ldyBjaGFpLkFzc2VydGlvbigpO1xuICAgIHRyYW5zZmVyRmxhZ3ModGhpcywgbmV3QXNzZXJ0aW9uKTtcbiAgICByZXR1cm4gbmV3QXNzZXJ0aW9uO1xuICB9O1xuXG4gIGFkZExlbmd0aEd1YXJkKG1ldGhvZFdyYXBwZXIsIG5hbWUsIGZhbHNlKTtcbiAgY3R4W25hbWVdID0gcHJveGlmeShtZXRob2RXcmFwcGVyLCBuYW1lKTtcbn07XG4iLCAiLyohXG4gKiBDaGFpIC0gb3ZlcndyaXRlUHJvcGVydHkgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbnZhciBjaGFpID0gcmVxdWlyZSgnLi4vLi4vY2hhaScpO1xudmFyIGZsYWcgPSByZXF1aXJlKCcuL2ZsYWcnKTtcbnZhciBpc1Byb3h5RW5hYmxlZCA9IHJlcXVpcmUoJy4vaXNQcm94eUVuYWJsZWQnKTtcbnZhciB0cmFuc2ZlckZsYWdzID0gcmVxdWlyZSgnLi90cmFuc2ZlckZsYWdzJyk7XG5cbi8qKlxuICogIyMjIC5vdmVyd3JpdGVQcm9wZXJ0eShjdHgsIG5hbWUsIGZuKVxuICpcbiAqIE92ZXJ3cml0ZXMgYW4gYWxyZWFkeSBleGlzdGluZyBwcm9wZXJ0eSBnZXR0ZXIgYW5kIHByb3ZpZGVzXG4gKiBhY2Nlc3MgdG8gcHJldmlvdXMgdmFsdWUuIE11c3QgcmV0dXJuIGZ1bmN0aW9uIHRvIHVzZSBhcyBnZXR0ZXIuXG4gKlxuICogICAgIHV0aWxzLm92ZXJ3cml0ZVByb3BlcnR5KGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZSwgJ29rJywgZnVuY3Rpb24gKF9zdXBlcikge1xuICogICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAqICAgICAgICAgdmFyIG9iaiA9IHV0aWxzLmZsYWcodGhpcywgJ29iamVjdCcpO1xuICogICAgICAgICBpZiAob2JqIGluc3RhbmNlb2YgRm9vKSB7XG4gKiAgICAgICAgICAgbmV3IGNoYWkuQXNzZXJ0aW9uKG9iai5uYW1lKS50by5lcXVhbCgnYmFyJyk7XG4gKiAgICAgICAgIH0gZWxzZSB7XG4gKiAgICAgICAgICAgX3N1cGVyLmNhbGwodGhpcyk7XG4gKiAgICAgICAgIH1cbiAqICAgICAgIH1cbiAqICAgICB9KTtcbiAqXG4gKlxuICogQ2FuIGFsc28gYmUgYWNjZXNzZWQgZGlyZWN0bHkgZnJvbSBgY2hhaS5Bc3NlcnRpb25gLlxuICpcbiAqICAgICBjaGFpLkFzc2VydGlvbi5vdmVyd3JpdGVQcm9wZXJ0eSgnZm9vJywgZm4pO1xuICpcbiAqIFRoZW4gY2FuIGJlIHVzZWQgYXMgYW55IG90aGVyIGFzc2VydGlvbi5cbiAqXG4gKiAgICAgZXhwZWN0KG15Rm9vKS50by5iZS5vaztcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY3R4IG9iamVjdCB3aG9zZSBwcm9wZXJ0eSBpcyB0byBiZSBvdmVyd3JpdHRlblxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgb2YgcHJvcGVydHkgdG8gb3ZlcndyaXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBnZXR0ZXIgZnVuY3Rpb24gdGhhdCByZXR1cm5zIGEgZ2V0dGVyIGZ1bmN0aW9uIHRvIGJlIHVzZWQgZm9yIG5hbWVcbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBuYW1lIG92ZXJ3cml0ZVByb3BlcnR5XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gb3ZlcndyaXRlUHJvcGVydHkoY3R4LCBuYW1lLCBnZXR0ZXIpIHtcbiAgdmFyIF9nZXQgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGN0eCwgbmFtZSlcbiAgICAsIF9zdXBlciA9IGZ1bmN0aW9uICgpIHt9O1xuXG4gIGlmIChfZ2V0ICYmICdmdW5jdGlvbicgPT09IHR5cGVvZiBfZ2V0LmdldClcbiAgICBfc3VwZXIgPSBfZ2V0LmdldFxuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjdHgsIG5hbWUsXG4gICAgeyBnZXQ6IGZ1bmN0aW9uIG92ZXJ3cml0aW5nUHJvcGVydHlHZXR0ZXIoKSB7XG4gICAgICAgIC8vIFNldHRpbmcgdGhlIGBzc2ZpYCBmbGFnIHRvIGBvdmVyd3JpdGluZ1Byb3BlcnR5R2V0dGVyYCBjYXVzZXMgdGhpc1xuICAgICAgICAvLyBmdW5jdGlvbiB0byBiZSB0aGUgc3RhcnRpbmcgcG9pbnQgZm9yIHJlbW92aW5nIGltcGxlbWVudGF0aW9uIGZyYW1lc1xuICAgICAgICAvLyBmcm9tIHRoZSBzdGFjayB0cmFjZSBvZiBhIGZhaWxlZCBhc3NlcnRpb24uXG4gICAgICAgIC8vXG4gICAgICAgIC8vIEhvd2V2ZXIsIHdlIG9ubHkgd2FudCB0byB1c2UgdGhpcyBmdW5jdGlvbiBhcyB0aGUgc3RhcnRpbmcgcG9pbnQgaWZcbiAgICAgICAgLy8gdGhlIGBsb2NrU3NmaWAgZmxhZyBpc24ndCBzZXQgYW5kIHByb3h5IHByb3RlY3Rpb24gaXMgZGlzYWJsZWQuXG4gICAgICAgIC8vXG4gICAgICAgIC8vIElmIHRoZSBgbG9ja1NzZmlgIGZsYWcgaXMgc2V0LCB0aGVuIGVpdGhlciB0aGlzIGFzc2VydGlvbiBoYXMgYmVlblxuICAgICAgICAvLyBvdmVyd3JpdHRlbiBieSBhbm90aGVyIGFzc2VydGlvbiwgb3IgdGhpcyBhc3NlcnRpb24gaXMgYmVpbmcgaW52b2tlZFxuICAgICAgICAvLyBmcm9tIGluc2lkZSBvZiBhbm90aGVyIGFzc2VydGlvbi4gSW4gdGhlIGZpcnN0IGNhc2UsIHRoZSBgc3NmaWAgZmxhZ1xuICAgICAgICAvLyBoYXMgYWxyZWFkeSBiZWVuIHNldCBieSB0aGUgb3ZlcndyaXRpbmcgYXNzZXJ0aW9uLiBJbiB0aGUgc2Vjb25kXG4gICAgICAgIC8vIGNhc2UsIHRoZSBgc3NmaWAgZmxhZyBoYXMgYWxyZWFkeSBiZWVuIHNldCBieSB0aGUgb3V0ZXIgYXNzZXJ0aW9uLlxuICAgICAgICAvL1xuICAgICAgICAvLyBJZiBwcm94eSBwcm90ZWN0aW9uIGlzIGVuYWJsZWQsIHRoZW4gdGhlIGBzc2ZpYCBmbGFnIGhhcyBhbHJlYWR5IGJlZW5cbiAgICAgICAgLy8gc2V0IGJ5IHRoZSBwcm94eSBnZXR0ZXIuXG4gICAgICAgIGlmICghaXNQcm94eUVuYWJsZWQoKSAmJiAhZmxhZyh0aGlzLCAnbG9ja1NzZmknKSkge1xuICAgICAgICAgIGZsYWcodGhpcywgJ3NzZmknLCBvdmVyd3JpdGluZ1Byb3BlcnR5R2V0dGVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldHRpbmcgdGhlIGBsb2NrU3NmaWAgZmxhZyB0byBgdHJ1ZWAgcHJldmVudHMgdGhlIG92ZXJ3cml0dGVuXG4gICAgICAgIC8vIGFzc2VydGlvbiBmcm9tIGNoYW5naW5nIHRoZSBgc3NmaWAgZmxhZy4gQnkgdGhpcyBwb2ludCwgdGhlIGBzc2ZpYFxuICAgICAgICAvLyBmbGFnIGlzIGFscmVhZHkgc2V0IHRvIHRoZSBjb3JyZWN0IHN0YXJ0aW5nIHBvaW50IGZvciB0aGlzIGFzc2VydGlvbi5cbiAgICAgICAgdmFyIG9yaWdMb2NrU3NmaSA9IGZsYWcodGhpcywgJ2xvY2tTc2ZpJyk7XG4gICAgICAgIGZsYWcodGhpcywgJ2xvY2tTc2ZpJywgdHJ1ZSk7XG4gICAgICAgIHZhciByZXN1bHQgPSBnZXR0ZXIoX3N1cGVyKS5jYWxsKHRoaXMpO1xuICAgICAgICBmbGFnKHRoaXMsICdsb2NrU3NmaScsIG9yaWdMb2NrU3NmaSk7XG5cbiAgICAgICAgaWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBuZXdBc3NlcnRpb24gPSBuZXcgY2hhaS5Bc3NlcnRpb24oKTtcbiAgICAgICAgdHJhbnNmZXJGbGFncyh0aGlzLCBuZXdBc3NlcnRpb24pO1xuICAgICAgICByZXR1cm4gbmV3QXNzZXJ0aW9uO1xuICAgICAgfVxuICAgICwgY29uZmlndXJhYmxlOiB0cnVlXG4gIH0pO1xufTtcbiIsICIvKiFcbiAqIENoYWkgLSBvdmVyd3JpdGVNZXRob2QgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbnZhciBhZGRMZW5ndGhHdWFyZCA9IHJlcXVpcmUoJy4vYWRkTGVuZ3RoR3VhcmQnKTtcbnZhciBjaGFpID0gcmVxdWlyZSgnLi4vLi4vY2hhaScpO1xudmFyIGZsYWcgPSByZXF1aXJlKCcuL2ZsYWcnKTtcbnZhciBwcm94aWZ5ID0gcmVxdWlyZSgnLi9wcm94aWZ5Jyk7XG52YXIgdHJhbnNmZXJGbGFncyA9IHJlcXVpcmUoJy4vdHJhbnNmZXJGbGFncycpO1xuXG4vKipcbiAqICMjIyAub3ZlcndyaXRlTWV0aG9kKGN0eCwgbmFtZSwgZm4pXG4gKlxuICogT3ZlcndyaXRlcyBhbiBhbHJlYWR5IGV4aXN0aW5nIG1ldGhvZCBhbmQgcHJvdmlkZXNcbiAqIGFjY2VzcyB0byBwcmV2aW91cyBmdW5jdGlvbi4gTXVzdCByZXR1cm4gZnVuY3Rpb25cbiAqIHRvIGJlIHVzZWQgZm9yIG5hbWUuXG4gKlxuICogICAgIHV0aWxzLm92ZXJ3cml0ZU1ldGhvZChjaGFpLkFzc2VydGlvbi5wcm90b3R5cGUsICdlcXVhbCcsIGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAqICAgICAgIHJldHVybiBmdW5jdGlvbiAoc3RyKSB7XG4gKiAgICAgICAgIHZhciBvYmogPSB1dGlscy5mbGFnKHRoaXMsICdvYmplY3QnKTtcbiAqICAgICAgICAgaWYgKG9iaiBpbnN0YW5jZW9mIEZvbykge1xuICogICAgICAgICAgIG5ldyBjaGFpLkFzc2VydGlvbihvYmoudmFsdWUpLnRvLmVxdWFsKHN0cik7XG4gKiAgICAgICAgIH0gZWxzZSB7XG4gKiAgICAgICAgICAgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gKiAgICAgICAgIH1cbiAqICAgICAgIH1cbiAqICAgICB9KTtcbiAqXG4gKiBDYW4gYWxzbyBiZSBhY2Nlc3NlZCBkaXJlY3RseSBmcm9tIGBjaGFpLkFzc2VydGlvbmAuXG4gKlxuICogICAgIGNoYWkuQXNzZXJ0aW9uLm92ZXJ3cml0ZU1ldGhvZCgnZm9vJywgZm4pO1xuICpcbiAqIFRoZW4gY2FuIGJlIHVzZWQgYXMgYW55IG90aGVyIGFzc2VydGlvbi5cbiAqXG4gKiAgICAgZXhwZWN0KG15Rm9vKS50by5lcXVhbCgnYmFyJyk7XG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGN0eCBvYmplY3Qgd2hvc2UgbWV0aG9kIGlzIHRvIGJlIG92ZXJ3cml0dGVuXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBvZiBtZXRob2QgdG8gb3ZlcndyaXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBtZXRob2QgZnVuY3Rpb24gdGhhdCByZXR1cm5zIGEgZnVuY3Rpb24gdG8gYmUgdXNlZCBmb3IgbmFtZVxuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQG5hbWUgb3ZlcndyaXRlTWV0aG9kXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gb3ZlcndyaXRlTWV0aG9kKGN0eCwgbmFtZSwgbWV0aG9kKSB7XG4gIHZhciBfbWV0aG9kID0gY3R4W25hbWVdXG4gICAgLCBfc3VwZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IobmFtZSArICcgaXMgbm90IGEgZnVuY3Rpb24nKTtcbiAgICB9O1xuXG4gIGlmIChfbWV0aG9kICYmICdmdW5jdGlvbicgPT09IHR5cGVvZiBfbWV0aG9kKVxuICAgIF9zdXBlciA9IF9tZXRob2Q7XG5cbiAgdmFyIG92ZXJ3cml0aW5nTWV0aG9kV3JhcHBlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAvLyBTZXR0aW5nIHRoZSBgc3NmaWAgZmxhZyB0byBgb3ZlcndyaXRpbmdNZXRob2RXcmFwcGVyYCBjYXVzZXMgdGhpc1xuICAgIC8vIGZ1bmN0aW9uIHRvIGJlIHRoZSBzdGFydGluZyBwb2ludCBmb3IgcmVtb3ZpbmcgaW1wbGVtZW50YXRpb24gZnJhbWVzIGZyb21cbiAgICAvLyB0aGUgc3RhY2sgdHJhY2Ugb2YgYSBmYWlsZWQgYXNzZXJ0aW9uLlxuICAgIC8vXG4gICAgLy8gSG93ZXZlciwgd2Ugb25seSB3YW50IHRvIHVzZSB0aGlzIGZ1bmN0aW9uIGFzIHRoZSBzdGFydGluZyBwb2ludCBpZiB0aGVcbiAgICAvLyBgbG9ja1NzZmlgIGZsYWcgaXNuJ3Qgc2V0LlxuICAgIC8vXG4gICAgLy8gSWYgdGhlIGBsb2NrU3NmaWAgZmxhZyBpcyBzZXQsIHRoZW4gZWl0aGVyIHRoaXMgYXNzZXJ0aW9uIGhhcyBiZWVuXG4gICAgLy8gb3ZlcndyaXR0ZW4gYnkgYW5vdGhlciBhc3NlcnRpb24sIG9yIHRoaXMgYXNzZXJ0aW9uIGlzIGJlaW5nIGludm9rZWQgZnJvbVxuICAgIC8vIGluc2lkZSBvZiBhbm90aGVyIGFzc2VydGlvbi4gSW4gdGhlIGZpcnN0IGNhc2UsIHRoZSBgc3NmaWAgZmxhZyBoYXNcbiAgICAvLyBhbHJlYWR5IGJlZW4gc2V0IGJ5IHRoZSBvdmVyd3JpdGluZyBhc3NlcnRpb24uIEluIHRoZSBzZWNvbmQgY2FzZSwgdGhlXG4gICAgLy8gYHNzZmlgIGZsYWcgaGFzIGFscmVhZHkgYmVlbiBzZXQgYnkgdGhlIG91dGVyIGFzc2VydGlvbi5cbiAgICBpZiAoIWZsYWcodGhpcywgJ2xvY2tTc2ZpJykpIHtcbiAgICAgIGZsYWcodGhpcywgJ3NzZmknLCBvdmVyd3JpdGluZ01ldGhvZFdyYXBwZXIpO1xuICAgIH1cblxuICAgIC8vIFNldHRpbmcgdGhlIGBsb2NrU3NmaWAgZmxhZyB0byBgdHJ1ZWAgcHJldmVudHMgdGhlIG92ZXJ3cml0dGVuIGFzc2VydGlvblxuICAgIC8vIGZyb20gY2hhbmdpbmcgdGhlIGBzc2ZpYCBmbGFnLiBCeSB0aGlzIHBvaW50LCB0aGUgYHNzZmlgIGZsYWcgaXMgYWxyZWFkeVxuICAgIC8vIHNldCB0byB0aGUgY29ycmVjdCBzdGFydGluZyBwb2ludCBmb3IgdGhpcyBhc3NlcnRpb24uXG4gICAgdmFyIG9yaWdMb2NrU3NmaSA9IGZsYWcodGhpcywgJ2xvY2tTc2ZpJyk7XG4gICAgZmxhZyh0aGlzLCAnbG9ja1NzZmknLCB0cnVlKTtcbiAgICB2YXIgcmVzdWx0ID0gbWV0aG9kKF9zdXBlcikuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICBmbGFnKHRoaXMsICdsb2NrU3NmaScsIG9yaWdMb2NrU3NmaSk7XG5cbiAgICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgdmFyIG5ld0Fzc2VydGlvbiA9IG5ldyBjaGFpLkFzc2VydGlvbigpO1xuICAgIHRyYW5zZmVyRmxhZ3ModGhpcywgbmV3QXNzZXJ0aW9uKTtcbiAgICByZXR1cm4gbmV3QXNzZXJ0aW9uO1xuICB9XG5cbiAgYWRkTGVuZ3RoR3VhcmQob3ZlcndyaXRpbmdNZXRob2RXcmFwcGVyLCBuYW1lLCBmYWxzZSk7XG4gIGN0eFtuYW1lXSA9IHByb3hpZnkob3ZlcndyaXRpbmdNZXRob2RXcmFwcGVyLCBuYW1lKTtcbn07XG4iLCAiLyohXG4gKiBDaGFpIC0gYWRkQ2hhaW5pbmdNZXRob2QgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbi8qIVxuICogTW9kdWxlIGRlcGVuZGVuY2llc1xuICovXG5cbnZhciBhZGRMZW5ndGhHdWFyZCA9IHJlcXVpcmUoJy4vYWRkTGVuZ3RoR3VhcmQnKTtcbnZhciBjaGFpID0gcmVxdWlyZSgnLi4vLi4vY2hhaScpO1xudmFyIGZsYWcgPSByZXF1aXJlKCcuL2ZsYWcnKTtcbnZhciBwcm94aWZ5ID0gcmVxdWlyZSgnLi9wcm94aWZ5Jyk7XG52YXIgdHJhbnNmZXJGbGFncyA9IHJlcXVpcmUoJy4vdHJhbnNmZXJGbGFncycpO1xuXG4vKiFcbiAqIE1vZHVsZSB2YXJpYWJsZXNcbiAqL1xuXG4vLyBDaGVjayB3aGV0aGVyIGBPYmplY3Quc2V0UHJvdG90eXBlT2ZgIGlzIHN1cHBvcnRlZFxudmFyIGNhblNldFByb3RvdHlwZSA9IHR5cGVvZiBPYmplY3Quc2V0UHJvdG90eXBlT2YgPT09ICdmdW5jdGlvbic7XG5cbi8vIFdpdGhvdXQgYE9iamVjdC5zZXRQcm90b3R5cGVPZmAgc3VwcG9ydCwgdGhpcyBtb2R1bGUgd2lsbCBuZWVkIHRvIGFkZCBwcm9wZXJ0aWVzIHRvIGEgZnVuY3Rpb24uXG4vLyBIb3dldmVyLCBzb21lIG9mIGZ1bmN0aW9ucycgb3duIHByb3BzIGFyZSBub3QgY29uZmlndXJhYmxlIGFuZCBzaG91bGQgYmUgc2tpcHBlZC5cbnZhciB0ZXN0Rm4gPSBmdW5jdGlvbigpIHt9O1xudmFyIGV4Y2x1ZGVOYW1lcyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHRlc3RGbikuZmlsdGVyKGZ1bmN0aW9uKG5hbWUpIHtcbiAgdmFyIHByb3BEZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0ZXN0Rm4sIG5hbWUpO1xuXG4gIC8vIE5vdGU6IFBoYW50b21KUyAxLnggaW5jbHVkZXMgYGNhbGxlZWAgYXMgb25lIG9mIGB0ZXN0Rm5gJ3Mgb3duIHByb3BlcnRpZXMsXG4gIC8vIGJ1dCB0aGVuIHJldHVybnMgYHVuZGVmaW5lZGAgYXMgdGhlIHByb3BlcnR5IGRlc2NyaXB0b3IgZm9yIGBjYWxsZWVgLiBBcyBhXG4gIC8vIHdvcmthcm91bmQsIHdlIHBlcmZvcm0gYW4gb3RoZXJ3aXNlIHVubmVjZXNzYXJ5IHR5cGUtY2hlY2sgZm9yIGBwcm9wRGVzY2AsXG4gIC8vIGFuZCB0aGVuIGZpbHRlciBpdCBvdXQgaWYgaXQncyBub3QgYW4gb2JqZWN0IGFzIGl0IHNob3VsZCBiZS5cbiAgaWYgKHR5cGVvZiBwcm9wRGVzYyAhPT0gJ29iamVjdCcpXG4gICAgcmV0dXJuIHRydWU7XG5cbiAgcmV0dXJuICFwcm9wRGVzYy5jb25maWd1cmFibGU7XG59KTtcblxuLy8gQ2FjaGUgYEZ1bmN0aW9uYCBwcm9wZXJ0aWVzXG52YXIgY2FsbCAgPSBGdW5jdGlvbi5wcm90b3R5cGUuY2FsbCxcbiAgICBhcHBseSA9IEZ1bmN0aW9uLnByb3RvdHlwZS5hcHBseTtcblxuLyoqXG4gKiAjIyMgLmFkZENoYWluYWJsZU1ldGhvZChjdHgsIG5hbWUsIG1ldGhvZCwgY2hhaW5pbmdCZWhhdmlvcilcbiAqXG4gKiBBZGRzIGEgbWV0aG9kIHRvIGFuIG9iamVjdCwgc3VjaCB0aGF0IHRoZSBtZXRob2QgY2FuIGFsc28gYmUgY2hhaW5lZC5cbiAqXG4gKiAgICAgdXRpbHMuYWRkQ2hhaW5hYmxlTWV0aG9kKGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZSwgJ2ZvbycsIGZ1bmN0aW9uIChzdHIpIHtcbiAqICAgICAgIHZhciBvYmogPSB1dGlscy5mbGFnKHRoaXMsICdvYmplY3QnKTtcbiAqICAgICAgIG5ldyBjaGFpLkFzc2VydGlvbihvYmopLnRvLmJlLmVxdWFsKHN0cik7XG4gKiAgICAgfSk7XG4gKlxuICogQ2FuIGFsc28gYmUgYWNjZXNzZWQgZGlyZWN0bHkgZnJvbSBgY2hhaS5Bc3NlcnRpb25gLlxuICpcbiAqICAgICBjaGFpLkFzc2VydGlvbi5hZGRDaGFpbmFibGVNZXRob2QoJ2ZvbycsIGZuLCBjaGFpbmluZ0JlaGF2aW9yKTtcbiAqXG4gKiBUaGUgcmVzdWx0IGNhbiB0aGVuIGJlIHVzZWQgYXMgYm90aCBhIG1ldGhvZCBhc3NlcnRpb24sIGV4ZWN1dGluZyBib3RoIGBtZXRob2RgIGFuZFxuICogYGNoYWluaW5nQmVoYXZpb3JgLCBvciBhcyBhIGxhbmd1YWdlIGNoYWluLCB3aGljaCBvbmx5IGV4ZWN1dGVzIGBjaGFpbmluZ0JlaGF2aW9yYC5cbiAqXG4gKiAgICAgZXhwZWN0KGZvb1N0cikudG8uYmUuZm9vKCdiYXInKTtcbiAqICAgICBleHBlY3QoZm9vU3RyKS50by5iZS5mb28uZXF1YWwoJ2ZvbycpO1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjdHggb2JqZWN0IHRvIHdoaWNoIHRoZSBtZXRob2QgaXMgYWRkZWRcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIG9mIG1ldGhvZCB0byBhZGRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IG1ldGhvZCBmdW5jdGlvbiB0byBiZSB1c2VkIGZvciBgbmFtZWAsIHdoZW4gY2FsbGVkXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjaGFpbmluZ0JlaGF2aW9yIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCBldmVyeSB0aW1lIHRoZSBwcm9wZXJ0eSBpcyBhY2Nlc3NlZFxuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQG5hbWUgYWRkQ2hhaW5hYmxlTWV0aG9kXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gYWRkQ2hhaW5hYmxlTWV0aG9kKGN0eCwgbmFtZSwgbWV0aG9kLCBjaGFpbmluZ0JlaGF2aW9yKSB7XG4gIGlmICh0eXBlb2YgY2hhaW5pbmdCZWhhdmlvciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIGNoYWluaW5nQmVoYXZpb3IgPSBmdW5jdGlvbiAoKSB7IH07XG4gIH1cblxuICB2YXIgY2hhaW5hYmxlQmVoYXZpb3IgPSB7XG4gICAgICBtZXRob2Q6IG1ldGhvZFxuICAgICwgY2hhaW5pbmdCZWhhdmlvcjogY2hhaW5pbmdCZWhhdmlvclxuICB9O1xuXG4gIC8vIHNhdmUgdGhlIG1ldGhvZHMgc28gd2UgY2FuIG92ZXJ3cml0ZSB0aGVtIGxhdGVyLCBpZiB3ZSBuZWVkIHRvLlxuICBpZiAoIWN0eC5fX21ldGhvZHMpIHtcbiAgICBjdHguX19tZXRob2RzID0ge307XG4gIH1cbiAgY3R4Ll9fbWV0aG9kc1tuYW1lXSA9IGNoYWluYWJsZUJlaGF2aW9yO1xuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjdHgsIG5hbWUsXG4gICAgeyBnZXQ6IGZ1bmN0aW9uIGNoYWluYWJsZU1ldGhvZEdldHRlcigpIHtcbiAgICAgICAgY2hhaW5hYmxlQmVoYXZpb3IuY2hhaW5pbmdCZWhhdmlvci5jYWxsKHRoaXMpO1xuXG4gICAgICAgIHZhciBjaGFpbmFibGVNZXRob2RXcmFwcGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIC8vIFNldHRpbmcgdGhlIGBzc2ZpYCBmbGFnIHRvIGBjaGFpbmFibGVNZXRob2RXcmFwcGVyYCBjYXVzZXMgdGhpc1xuICAgICAgICAgIC8vIGZ1bmN0aW9uIHRvIGJlIHRoZSBzdGFydGluZyBwb2ludCBmb3IgcmVtb3ZpbmcgaW1wbGVtZW50YXRpb25cbiAgICAgICAgICAvLyBmcmFtZXMgZnJvbSB0aGUgc3RhY2sgdHJhY2Ugb2YgYSBmYWlsZWQgYXNzZXJ0aW9uLlxuICAgICAgICAgIC8vXG4gICAgICAgICAgLy8gSG93ZXZlciwgd2Ugb25seSB3YW50IHRvIHVzZSB0aGlzIGZ1bmN0aW9uIGFzIHRoZSBzdGFydGluZyBwb2ludCBpZlxuICAgICAgICAgIC8vIHRoZSBgbG9ja1NzZmlgIGZsYWcgaXNuJ3Qgc2V0LlxuICAgICAgICAgIC8vXG4gICAgICAgICAgLy8gSWYgdGhlIGBsb2NrU3NmaWAgZmxhZyBpcyBzZXQsIHRoZW4gdGhpcyBhc3NlcnRpb24gaXMgYmVpbmdcbiAgICAgICAgICAvLyBpbnZva2VkIGZyb20gaW5zaWRlIG9mIGFub3RoZXIgYXNzZXJ0aW9uLiBJbiB0aGlzIGNhc2UsIHRoZSBgc3NmaWBcbiAgICAgICAgICAvLyBmbGFnIGhhcyBhbHJlYWR5IGJlZW4gc2V0IGJ5IHRoZSBvdXRlciBhc3NlcnRpb24uXG4gICAgICAgICAgLy9cbiAgICAgICAgICAvLyBOb3RlIHRoYXQgb3ZlcndyaXRpbmcgYSBjaGFpbmFibGUgbWV0aG9kIG1lcmVseSByZXBsYWNlcyB0aGUgc2F2ZWRcbiAgICAgICAgICAvLyBtZXRob2RzIGluIGBjdHguX19tZXRob2RzYCBpbnN0ZWFkIG9mIGNvbXBsZXRlbHkgcmVwbGFjaW5nIHRoZVxuICAgICAgICAgIC8vIG92ZXJ3cml0dGVuIGFzc2VydGlvbi4gVGhlcmVmb3JlLCBhbiBvdmVyd3JpdGluZyBhc3NlcnRpb24gd29uJ3RcbiAgICAgICAgICAvLyBzZXQgdGhlIGBzc2ZpYCBvciBgbG9ja1NzZmlgIGZsYWdzLlxuICAgICAgICAgIGlmICghZmxhZyh0aGlzLCAnbG9ja1NzZmknKSkge1xuICAgICAgICAgICAgZmxhZyh0aGlzLCAnc3NmaScsIGNoYWluYWJsZU1ldGhvZFdyYXBwZXIpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHZhciByZXN1bHQgPSBjaGFpbmFibGVCZWhhdmlvci5tZXRob2QuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdmFyIG5ld0Fzc2VydGlvbiA9IG5ldyBjaGFpLkFzc2VydGlvbigpO1xuICAgICAgICAgIHRyYW5zZmVyRmxhZ3ModGhpcywgbmV3QXNzZXJ0aW9uKTtcbiAgICAgICAgICByZXR1cm4gbmV3QXNzZXJ0aW9uO1xuICAgICAgICB9O1xuXG4gICAgICAgIGFkZExlbmd0aEd1YXJkKGNoYWluYWJsZU1ldGhvZFdyYXBwZXIsIG5hbWUsIHRydWUpO1xuXG4gICAgICAgIC8vIFVzZSBgT2JqZWN0LnNldFByb3RvdHlwZU9mYCBpZiBhdmFpbGFibGVcbiAgICAgICAgaWYgKGNhblNldFByb3RvdHlwZSkge1xuICAgICAgICAgIC8vIEluaGVyaXQgYWxsIHByb3BlcnRpZXMgZnJvbSB0aGUgb2JqZWN0IGJ5IHJlcGxhY2luZyB0aGUgYEZ1bmN0aW9uYCBwcm90b3R5cGVcbiAgICAgICAgICB2YXIgcHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSh0aGlzKTtcbiAgICAgICAgICAvLyBSZXN0b3JlIHRoZSBgY2FsbGAgYW5kIGBhcHBseWAgbWV0aG9kcyBmcm9tIGBGdW5jdGlvbmBcbiAgICAgICAgICBwcm90b3R5cGUuY2FsbCA9IGNhbGw7XG4gICAgICAgICAgcHJvdG90eXBlLmFwcGx5ID0gYXBwbHk7XG4gICAgICAgICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKGNoYWluYWJsZU1ldGhvZFdyYXBwZXIsIHByb3RvdHlwZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gT3RoZXJ3aXNlLCByZWRlZmluZSBhbGwgcHJvcGVydGllcyAoc2xvdyEpXG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHZhciBhc3NlcnRlck5hbWVzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoY3R4KTtcbiAgICAgICAgICBhc3NlcnRlck5hbWVzLmZvckVhY2goZnVuY3Rpb24gKGFzc2VydGVyTmFtZSkge1xuICAgICAgICAgICAgaWYgKGV4Y2x1ZGVOYW1lcy5pbmRleE9mKGFzc2VydGVyTmFtZSkgIT09IC0xKSB7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIHBkID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihjdHgsIGFzc2VydGVyTmFtZSk7XG4gICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY2hhaW5hYmxlTWV0aG9kV3JhcHBlciwgYXNzZXJ0ZXJOYW1lLCBwZCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICB0cmFuc2ZlckZsYWdzKHRoaXMsIGNoYWluYWJsZU1ldGhvZFdyYXBwZXIpO1xuICAgICAgICByZXR1cm4gcHJveGlmeShjaGFpbmFibGVNZXRob2RXcmFwcGVyKTtcbiAgICAgIH1cbiAgICAsIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICB9KTtcbn07XG4iLCAiLyohXG4gKiBDaGFpIC0gb3ZlcndyaXRlQ2hhaW5hYmxlTWV0aG9kIHV0aWxpdHlcbiAqIENvcHlyaWdodChjKSAyMDEyLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG52YXIgY2hhaSA9IHJlcXVpcmUoJy4uLy4uL2NoYWknKTtcbnZhciB0cmFuc2ZlckZsYWdzID0gcmVxdWlyZSgnLi90cmFuc2ZlckZsYWdzJyk7XG5cbi8qKlxuICogIyMjIC5vdmVyd3JpdGVDaGFpbmFibGVNZXRob2QoY3R4LCBuYW1lLCBtZXRob2QsIGNoYWluaW5nQmVoYXZpb3IpXG4gKlxuICogT3ZlcndyaXRlcyBhbiBhbHJlYWR5IGV4aXN0aW5nIGNoYWluYWJsZSBtZXRob2RcbiAqIGFuZCBwcm92aWRlcyBhY2Nlc3MgdG8gdGhlIHByZXZpb3VzIGZ1bmN0aW9uIG9yXG4gKiBwcm9wZXJ0eS4gIE11c3QgcmV0dXJuIGZ1bmN0aW9ucyB0byBiZSB1c2VkIGZvclxuICogbmFtZS5cbiAqXG4gKiAgICAgdXRpbHMub3ZlcndyaXRlQ2hhaW5hYmxlTWV0aG9kKGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZSwgJ2xlbmd0aE9mJyxcbiAqICAgICAgIGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAqICAgICAgIH1cbiAqICAgICAsIGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAqICAgICAgIH1cbiAqICAgICApO1xuICpcbiAqIENhbiBhbHNvIGJlIGFjY2Vzc2VkIGRpcmVjdGx5IGZyb20gYGNoYWkuQXNzZXJ0aW9uYC5cbiAqXG4gKiAgICAgY2hhaS5Bc3NlcnRpb24ub3ZlcndyaXRlQ2hhaW5hYmxlTWV0aG9kKCdmb28nLCBmbiwgZm4pO1xuICpcbiAqIFRoZW4gY2FuIGJlIHVzZWQgYXMgYW55IG90aGVyIGFzc2VydGlvbi5cbiAqXG4gKiAgICAgZXhwZWN0KG15Rm9vKS50by5oYXZlLmxlbmd0aE9mKDMpO1xuICogICAgIGV4cGVjdChteUZvbykudG8uaGF2ZS5sZW5ndGhPZi5hYm92ZSgzKTtcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY3R4IG9iamVjdCB3aG9zZSBtZXRob2QgLyBwcm9wZXJ0eSBpcyB0byBiZSBvdmVyd3JpdHRlblxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgb2YgbWV0aG9kIC8gcHJvcGVydHkgdG8gb3ZlcndyaXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBtZXRob2QgZnVuY3Rpb24gdGhhdCByZXR1cm5zIGEgZnVuY3Rpb24gdG8gYmUgdXNlZCBmb3IgbmFtZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2hhaW5pbmdCZWhhdmlvciBmdW5jdGlvbiB0aGF0IHJldHVybnMgYSBmdW5jdGlvbiB0byBiZSB1c2VkIGZvciBwcm9wZXJ0eVxuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQG5hbWUgb3ZlcndyaXRlQ2hhaW5hYmxlTWV0aG9kXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gb3ZlcndyaXRlQ2hhaW5hYmxlTWV0aG9kKGN0eCwgbmFtZSwgbWV0aG9kLCBjaGFpbmluZ0JlaGF2aW9yKSB7XG4gIHZhciBjaGFpbmFibGVCZWhhdmlvciA9IGN0eC5fX21ldGhvZHNbbmFtZV07XG5cbiAgdmFyIF9jaGFpbmluZ0JlaGF2aW9yID0gY2hhaW5hYmxlQmVoYXZpb3IuY2hhaW5pbmdCZWhhdmlvcjtcbiAgY2hhaW5hYmxlQmVoYXZpb3IuY2hhaW5pbmdCZWhhdmlvciA9IGZ1bmN0aW9uIG92ZXJ3cml0aW5nQ2hhaW5hYmxlTWV0aG9kR2V0dGVyKCkge1xuICAgIHZhciByZXN1bHQgPSBjaGFpbmluZ0JlaGF2aW9yKF9jaGFpbmluZ0JlaGF2aW9yKS5jYWxsKHRoaXMpO1xuICAgIGlmIChyZXN1bHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICB2YXIgbmV3QXNzZXJ0aW9uID0gbmV3IGNoYWkuQXNzZXJ0aW9uKCk7XG4gICAgdHJhbnNmZXJGbGFncyh0aGlzLCBuZXdBc3NlcnRpb24pO1xuICAgIHJldHVybiBuZXdBc3NlcnRpb247XG4gIH07XG5cbiAgdmFyIF9tZXRob2QgPSBjaGFpbmFibGVCZWhhdmlvci5tZXRob2Q7XG4gIGNoYWluYWJsZUJlaGF2aW9yLm1ldGhvZCA9IGZ1bmN0aW9uIG92ZXJ3cml0aW5nQ2hhaW5hYmxlTWV0aG9kV3JhcHBlcigpIHtcbiAgICB2YXIgcmVzdWx0ID0gbWV0aG9kKF9tZXRob2QpLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgaWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIHZhciBuZXdBc3NlcnRpb24gPSBuZXcgY2hhaS5Bc3NlcnRpb24oKTtcbiAgICB0cmFuc2ZlckZsYWdzKHRoaXMsIG5ld0Fzc2VydGlvbik7XG4gICAgcmV0dXJuIG5ld0Fzc2VydGlvbjtcbiAgfTtcbn07XG4iLCAiLyohXG4gKiBDaGFpIC0gY29tcGFyZUJ5SW5zcGVjdCB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMS0yMDE2IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyohXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzXG4gKi9cblxudmFyIGluc3BlY3QgPSByZXF1aXJlKCcuL2luc3BlY3QnKTtcblxuLyoqXG4gKiAjIyMgLmNvbXBhcmVCeUluc3BlY3QobWl4ZWQsIG1peGVkKVxuICpcbiAqIFRvIGJlIHVzZWQgYXMgYSBjb21wYXJlRnVuY3Rpb24gd2l0aCBBcnJheS5wcm90b3R5cGUuc29ydC4gQ29tcGFyZXMgZWxlbWVudHNcbiAqIHVzaW5nIGluc3BlY3QgaW5zdGVhZCBvZiBkZWZhdWx0IGJlaGF2aW9yIG9mIHVzaW5nIHRvU3RyaW5nIHNvIHRoYXQgU3ltYm9sc1xuICogYW5kIG9iamVjdHMgd2l0aCBpcnJlZ3VsYXIvbWlzc2luZyB0b1N0cmluZyBjYW4gc3RpbGwgYmUgc29ydGVkIHdpdGhvdXQgYVxuICogVHlwZUVycm9yLlxuICpcbiAqIEBwYXJhbSB7TWl4ZWR9IGZpcnN0IGVsZW1lbnQgdG8gY29tcGFyZVxuICogQHBhcmFtIHtNaXhlZH0gc2Vjb25kIGVsZW1lbnQgdG8gY29tcGFyZVxuICogQHJldHVybnMge051bWJlcn0gLTEgaWYgJ2EnIHNob3VsZCBjb21lIGJlZm9yZSAnYic7IG90aGVyd2lzZSAxXG4gKiBAbmFtZSBjb21wYXJlQnlJbnNwZWN0XG4gKiBAbmFtZXNwYWNlIFV0aWxzXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gY29tcGFyZUJ5SW5zcGVjdChhLCBiKSB7XG4gIHJldHVybiBpbnNwZWN0KGEpIDwgaW5zcGVjdChiKSA/IC0xIDogMTtcbn07XG4iLCAiLyohXG4gKiBDaGFpIC0gZ2V0T3duRW51bWVyYWJsZVByb3BlcnR5U3ltYm9scyB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMS0yMDE2IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyoqXG4gKiAjIyMgLmdldE93bkVudW1lcmFibGVQcm9wZXJ0eVN5bWJvbHMob2JqZWN0KVxuICpcbiAqIFRoaXMgYWxsb3dzIHRoZSByZXRyaWV2YWwgb2YgZGlyZWN0bHktb3duZWQgZW51bWVyYWJsZSBwcm9wZXJ0eSBzeW1ib2xzIG9mIGFuXG4gKiBvYmplY3QuIFRoaXMgZnVuY3Rpb24gaXMgbmVjZXNzYXJ5IGJlY2F1c2UgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9sc1xuICogcmV0dXJucyBib3RoIGVudW1lcmFibGUgYW5kIG5vbi1lbnVtZXJhYmxlIHByb3BlcnR5IHN5bWJvbHMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICogQHJldHVybnMge0FycmF5fVxuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQG5hbWUgZ2V0T3duRW51bWVyYWJsZVByb3BlcnR5U3ltYm9sc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGdldE93bkVudW1lcmFibGVQcm9wZXJ0eVN5bWJvbHMob2JqKSB7XG4gIGlmICh0eXBlb2YgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyAhPT0gJ2Z1bmN0aW9uJykgcmV0dXJuIFtdO1xuXG4gIHJldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKG9iaikuZmlsdGVyKGZ1bmN0aW9uIChzeW0pIHtcbiAgICByZXR1cm4gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihvYmosIHN5bSkuZW51bWVyYWJsZTtcbiAgfSk7XG59O1xuIiwgIi8qIVxuICogQ2hhaSAtIGdldE93bkVudW1lcmFibGVQcm9wZXJ0aWVzIHV0aWxpdHlcbiAqIENvcHlyaWdodChjKSAyMDExLTIwMTYgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG4vKiFcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXNcbiAqL1xuXG52YXIgZ2V0T3duRW51bWVyYWJsZVByb3BlcnR5U3ltYm9scyA9IHJlcXVpcmUoJy4vZ2V0T3duRW51bWVyYWJsZVByb3BlcnR5U3ltYm9scycpO1xuXG4vKipcbiAqICMjIyAuZ2V0T3duRW51bWVyYWJsZVByb3BlcnRpZXMob2JqZWN0KVxuICpcbiAqIFRoaXMgYWxsb3dzIHRoZSByZXRyaWV2YWwgb2YgZGlyZWN0bHktb3duZWQgZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBhbmRcbiAqIHN5bWJvbHMgb2YgYW4gb2JqZWN0LiBUaGlzIGZ1bmN0aW9uIGlzIG5lY2Vzc2FyeSBiZWNhdXNlIE9iamVjdC5rZXlzIG9ubHlcbiAqIHJldHVybnMgZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcywgbm90IGVudW1lcmFibGUgcHJvcGVydHkgc3ltYm9scy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gKiBAcmV0dXJucyB7QXJyYXl9XG4gKiBAbmFtZXNwYWNlIFV0aWxzXG4gKiBAbmFtZSBnZXRPd25FbnVtZXJhYmxlUHJvcGVydGllc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGdldE93bkVudW1lcmFibGVQcm9wZXJ0aWVzKG9iaikge1xuICByZXR1cm4gT2JqZWN0LmtleXMob2JqKS5jb25jYXQoZ2V0T3duRW51bWVyYWJsZVByb3BlcnR5U3ltYm9scyhvYmopKTtcbn07XG4iLCAiJ3VzZSBzdHJpY3QnO1xuXG4vKiAhXG4gKiBDaGFpIC0gY2hlY2tFcnJvciB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE2IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxudmFyIGdldEZ1bmN0aW9uTmFtZSA9IHJlcXVpcmUoJ2dldC1mdW5jLW5hbWUnKTtcbi8qKlxuICogIyMjIC5jaGVja0Vycm9yXG4gKlxuICogQ2hlY2tzIHRoYXQgYW4gZXJyb3IgY29uZm9ybXMgdG8gYSBnaXZlbiBzZXQgb2YgY3JpdGVyaWEgYW5kL29yIHJldHJpZXZlcyBpbmZvcm1hdGlvbiBhYm91dCBpdC5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbi8qKlxuICogIyMjIC5jb21wYXRpYmxlSW5zdGFuY2UodGhyb3duLCBlcnJvckxpa2UpXG4gKlxuICogQ2hlY2tzIGlmIHR3byBpbnN0YW5jZXMgYXJlIGNvbXBhdGlibGUgKHN0cmljdCBlcXVhbCkuXG4gKiBSZXR1cm5zIGZhbHNlIGlmIGVycm9yTGlrZSBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgRXJyb3IsIGJlY2F1c2UgaW5zdGFuY2VzXG4gKiBjYW4gb25seSBiZSBjb21wYXRpYmxlIGlmIHRoZXkncmUgYm90aCBlcnJvciBpbnN0YW5jZXMuXG4gKlxuICogQG5hbWUgY29tcGF0aWJsZUluc3RhbmNlXG4gKiBAcGFyYW0ge0Vycm9yfSB0aHJvd24gZXJyb3JcbiAqIEBwYXJhbSB7RXJyb3J8RXJyb3JDb25zdHJ1Y3Rvcn0gZXJyb3JMaWtlIG9iamVjdCB0byBjb21wYXJlIGFnYWluc3RcbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gY29tcGF0aWJsZUluc3RhbmNlKHRocm93biwgZXJyb3JMaWtlKSB7XG4gIHJldHVybiBlcnJvckxpa2UgaW5zdGFuY2VvZiBFcnJvciAmJiB0aHJvd24gPT09IGVycm9yTGlrZTtcbn1cblxuLyoqXG4gKiAjIyMgLmNvbXBhdGlibGVDb25zdHJ1Y3Rvcih0aHJvd24sIGVycm9yTGlrZSlcbiAqXG4gKiBDaGVja3MgaWYgdHdvIGNvbnN0cnVjdG9ycyBhcmUgY29tcGF0aWJsZS5cbiAqIFRoaXMgZnVuY3Rpb24gY2FuIHJlY2VpdmUgZWl0aGVyIGFuIGVycm9yIGNvbnN0cnVjdG9yIG9yXG4gKiBhbiBlcnJvciBpbnN0YW5jZSBhcyB0aGUgYGVycm9yTGlrZWAgYXJndW1lbnQuXG4gKiBDb25zdHJ1Y3RvcnMgYXJlIGNvbXBhdGlibGUgaWYgdGhleSdyZSB0aGUgc2FtZSBvciBpZiBvbmUgaXNcbiAqIGFuIGluc3RhbmNlIG9mIGFub3RoZXIuXG4gKlxuICogQG5hbWUgY29tcGF0aWJsZUNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge0Vycm9yfSB0aHJvd24gZXJyb3JcbiAqIEBwYXJhbSB7RXJyb3J8RXJyb3JDb25zdHJ1Y3Rvcn0gZXJyb3JMaWtlIG9iamVjdCB0byBjb21wYXJlIGFnYWluc3RcbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gY29tcGF0aWJsZUNvbnN0cnVjdG9yKHRocm93biwgZXJyb3JMaWtlKSB7XG4gIGlmIChlcnJvckxpa2UgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgIC8vIElmIGBlcnJvckxpa2VgIGlzIGFuIGluc3RhbmNlIG9mIGFueSBlcnJvciB3ZSBjb21wYXJlIHRoZWlyIGNvbnN0cnVjdG9yc1xuICAgIHJldHVybiB0aHJvd24uY29uc3RydWN0b3IgPT09IGVycm9yTGlrZS5jb25zdHJ1Y3RvciB8fCB0aHJvd24gaW5zdGFuY2VvZiBlcnJvckxpa2UuY29uc3RydWN0b3I7XG4gIH0gZWxzZSBpZiAoZXJyb3JMaWtlLnByb3RvdHlwZSBpbnN0YW5jZW9mIEVycm9yIHx8IGVycm9yTGlrZSA9PT0gRXJyb3IpIHtcbiAgICAvLyBJZiBgZXJyb3JMaWtlYCBpcyBhIGNvbnN0cnVjdG9yIHRoYXQgaW5oZXJpdHMgZnJvbSBFcnJvciwgd2UgY29tcGFyZSBgdGhyb3duYCB0byBgZXJyb3JMaWtlYCBkaXJlY3RseVxuICAgIHJldHVybiB0aHJvd24uY29uc3RydWN0b3IgPT09IGVycm9yTGlrZSB8fCB0aHJvd24gaW5zdGFuY2VvZiBlcnJvckxpa2U7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogIyMjIC5jb21wYXRpYmxlTWVzc2FnZSh0aHJvd24sIGVyck1hdGNoZXIpXG4gKlxuICogQ2hlY2tzIGlmIGFuIGVycm9yJ3MgbWVzc2FnZSBpcyBjb21wYXRpYmxlIHdpdGggYSBtYXRjaGVyIChTdHJpbmcgb3IgUmVnRXhwKS5cbiAqIElmIHRoZSBtZXNzYWdlIGNvbnRhaW5zIHRoZSBTdHJpbmcgb3IgcGFzc2VzIHRoZSBSZWdFeHAgdGVzdCxcbiAqIGl0IGlzIGNvbnNpZGVyZWQgY29tcGF0aWJsZS5cbiAqXG4gKiBAbmFtZSBjb21wYXRpYmxlTWVzc2FnZVxuICogQHBhcmFtIHtFcnJvcn0gdGhyb3duIGVycm9yXG4gKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGVyck1hdGNoZXIgdG8gbG9vayBmb3IgaW50byB0aGUgbWVzc2FnZVxuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBjb21wYXRpYmxlTWVzc2FnZSh0aHJvd24sIGVyck1hdGNoZXIpIHtcbiAgdmFyIGNvbXBhcmlzb25TdHJpbmcgPSB0eXBlb2YgdGhyb3duID09PSAnc3RyaW5nJyA/IHRocm93biA6IHRocm93bi5tZXNzYWdlO1xuICBpZiAoZXJyTWF0Y2hlciBpbnN0YW5jZW9mIFJlZ0V4cCkge1xuICAgIHJldHVybiBlcnJNYXRjaGVyLnRlc3QoY29tcGFyaXNvblN0cmluZyk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGVyck1hdGNoZXIgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGNvbXBhcmlzb25TdHJpbmcuaW5kZXhPZihlcnJNYXRjaGVyKSAhPT0gLTE7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbWFnaWMtbnVtYmVyc1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vKipcbiAqICMjIyAuZ2V0Q29uc3RydWN0b3JOYW1lKGVycm9yTGlrZSlcbiAqXG4gKiBHZXRzIHRoZSBjb25zdHJ1Y3RvciBuYW1lIGZvciBhbiBFcnJvciBpbnN0YW5jZSBvciBjb25zdHJ1Y3RvciBpdHNlbGYuXG4gKlxuICogQG5hbWUgZ2V0Q29uc3RydWN0b3JOYW1lXG4gKiBAcGFyYW0ge0Vycm9yfEVycm9yQ29uc3RydWN0b3J9IGVycm9yTGlrZVxuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBnZXRDb25zdHJ1Y3Rvck5hbWUoZXJyb3JMaWtlKSB7XG4gIHZhciBjb25zdHJ1Y3Rvck5hbWUgPSBlcnJvckxpa2U7XG4gIGlmIChlcnJvckxpa2UgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgIGNvbnN0cnVjdG9yTmFtZSA9IGdldEZ1bmN0aW9uTmFtZShlcnJvckxpa2UuY29uc3RydWN0b3IpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBlcnJvckxpa2UgPT09ICdmdW5jdGlvbicpIHtcbiAgICAvLyBJZiBgZXJyYCBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgRXJyb3IgaXQgaXMgYW4gZXJyb3IgY29uc3RydWN0b3IgaXRzZWxmIG9yIGFub3RoZXIgZnVuY3Rpb24uXG4gICAgLy8gSWYgd2UndmUgZ290IGEgY29tbW9uIGZ1bmN0aW9uIHdlIGdldCBpdHMgbmFtZSwgb3RoZXJ3aXNlIHdlIG1heSBuZWVkIHRvIGNyZWF0ZSBhIG5ldyBpbnN0YW5jZVxuICAgIC8vIG9mIHRoZSBlcnJvciBqdXN0IGluIGNhc2UgaXQncyBhIHBvb3JseS1jb25zdHJ1Y3RlZCBlcnJvci4gUGxlYXNlIHNlZSBjaGFpanMvY2hhaS9pc3N1ZXMvNDUgdG8ga25vdyBtb3JlLlxuICAgIGNvbnN0cnVjdG9yTmFtZSA9IGdldEZ1bmN0aW9uTmFtZShlcnJvckxpa2UpO1xuICAgIGlmIChjb25zdHJ1Y3Rvck5hbWUgPT09ICcnKSB7XG4gICAgICB2YXIgbmV3Q29uc3RydWN0b3JOYW1lID0gZ2V0RnVuY3Rpb25OYW1lKG5ldyBlcnJvckxpa2UoKSk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbmV3LWNhcFxuICAgICAgY29uc3RydWN0b3JOYW1lID0gbmV3Q29uc3RydWN0b3JOYW1lIHx8IGNvbnN0cnVjdG9yTmFtZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gY29uc3RydWN0b3JOYW1lO1xufVxuXG4vKipcbiAqICMjIyAuZ2V0TWVzc2FnZShlcnJvckxpa2UpXG4gKlxuICogR2V0cyB0aGUgZXJyb3IgbWVzc2FnZSBmcm9tIGFuIGVycm9yLlxuICogSWYgYGVycmAgaXMgYSBTdHJpbmcgaXRzZWxmLCB3ZSByZXR1cm4gaXQuXG4gKiBJZiB0aGUgZXJyb3IgaGFzIG5vIG1lc3NhZ2UsIHdlIHJldHVybiBhbiBlbXB0eSBzdHJpbmcuXG4gKlxuICogQG5hbWUgZ2V0TWVzc2FnZVxuICogQHBhcmFtIHtFcnJvcnxTdHJpbmd9IGVycm9yTGlrZVxuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBnZXRNZXNzYWdlKGVycm9yTGlrZSkge1xuICB2YXIgbXNnID0gJyc7XG4gIGlmIChlcnJvckxpa2UgJiYgZXJyb3JMaWtlLm1lc3NhZ2UpIHtcbiAgICBtc2cgPSBlcnJvckxpa2UubWVzc2FnZTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgZXJyb3JMaWtlID09PSAnc3RyaW5nJykge1xuICAgIG1zZyA9IGVycm9yTGlrZTtcbiAgfVxuXG4gIHJldHVybiBtc2c7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBjb21wYXRpYmxlSW5zdGFuY2U6IGNvbXBhdGlibGVJbnN0YW5jZSxcbiAgY29tcGF0aWJsZUNvbnN0cnVjdG9yOiBjb21wYXRpYmxlQ29uc3RydWN0b3IsXG4gIGNvbXBhdGlibGVNZXNzYWdlOiBjb21wYXRpYmxlTWVzc2FnZSxcbiAgZ2V0TWVzc2FnZTogZ2V0TWVzc2FnZSxcbiAgZ2V0Q29uc3RydWN0b3JOYW1lOiBnZXRDb25zdHJ1Y3Rvck5hbWUsXG59O1xuIiwgIi8qIVxuICogQ2hhaSAtIGlzTmFOIHV0aWxpdHlcbiAqIENvcHlyaWdodChjKSAyMDEyLTIwMTUgU2FrdGhpcHJpeWFuIFZhaXJhbWFuaSA8dGhlY2hhcmdpbmd2b2xjYW5vQGdtYWlsLmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbi8qKlxuICogIyMjIC5pc05hTih2YWx1ZSlcbiAqXG4gKiBDaGVja3MgaWYgdGhlIGdpdmVuIHZhbHVlIGlzIE5hTiBvciBub3QuXG4gKlxuICogICAgIHV0aWxzLmlzTmFOKE5hTik7IC8vIHRydWVcbiAqXG4gKiBAcGFyYW0ge1ZhbHVlfSBUaGUgdmFsdWUgd2hpY2ggaGFzIHRvIGJlIGNoZWNrZWQgaWYgaXQgaXMgTmFOXG4gKiBAbmFtZSBpc05hTlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gaXNOYU4odmFsdWUpIHtcbiAgLy8gUmVmZXIgaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzbmFuLW51bWJlclxuICAvLyBzZWN0aW9uJ3MgTk9URS5cbiAgcmV0dXJuIHZhbHVlICE9PSB2YWx1ZTtcbn1cblxuLy8gSWYgRUNNQVNjcmlwdCA2J3MgTnVtYmVyLmlzTmFOIGlzIHByZXNlbnQsIHByZWZlciB0aGF0LlxubW9kdWxlLmV4cG9ydHMgPSBOdW1iZXIuaXNOYU4gfHwgaXNOYU47XG4iLCAidmFyIHR5cGUgPSByZXF1aXJlKCd0eXBlLWRldGVjdCcpO1xuXG52YXIgZmxhZyA9IHJlcXVpcmUoJy4vZmxhZycpO1xuXG5mdW5jdGlvbiBpc09iamVjdFR5cGUob2JqKSB7XG4gIHZhciBvYmplY3RUeXBlID0gdHlwZShvYmopO1xuICB2YXIgb2JqZWN0VHlwZXMgPSBbJ0FycmF5JywgJ09iamVjdCcsICdmdW5jdGlvbiddO1xuXG4gIHJldHVybiBvYmplY3RUeXBlcy5pbmRleE9mKG9iamVjdFR5cGUpICE9PSAtMTtcbn1cblxuLyoqXG4gKiAjIyMgLmdldE9wZXJhdG9yKG1lc3NhZ2UpXG4gKlxuICogRXh0cmFjdCB0aGUgb3BlcmF0b3IgZnJvbSBlcnJvciBtZXNzYWdlLlxuICogT3BlcmF0b3IgZGVmaW5lZCBpcyBiYXNlZCBvbiBiZWxvdyBsaW5rXG4gKiBodHRwczovL25vZGVqcy5vcmcvYXBpL2Fzc2VydC5odG1sI2Fzc2VydF9hc3NlcnQuXG4gKlxuICogUmV0dXJucyB0aGUgYG9wZXJhdG9yYCBvciBgdW5kZWZpbmVkYCB2YWx1ZSBmb3IgYW4gQXNzZXJ0aW9uLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgKGNvbnN0cnVjdGVkIEFzc2VydGlvbilcbiAqIEBwYXJhbSB7QXJndW1lbnRzfSBjaGFpLkFzc2VydGlvbi5wcm90b3R5cGUuYXNzZXJ0IGFyZ3VtZW50c1xuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQG5hbWUgZ2V0T3BlcmF0b3JcbiAqIEBhcGkgcHVibGljXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBnZXRPcGVyYXRvcihvYmosIGFyZ3MpIHtcbiAgdmFyIG9wZXJhdG9yID0gZmxhZyhvYmosICdvcGVyYXRvcicpO1xuICB2YXIgbmVnYXRlID0gZmxhZyhvYmosICduZWdhdGUnKTtcbiAgdmFyIGV4cGVjdGVkID0gYXJnc1szXTtcbiAgdmFyIG1zZyA9IG5lZ2F0ZSA/IGFyZ3NbMl0gOiBhcmdzWzFdO1xuXG4gIGlmIChvcGVyYXRvcikge1xuICAgIHJldHVybiBvcGVyYXRvcjtcbiAgfVxuXG4gIGlmICh0eXBlb2YgbXNnID09PSAnZnVuY3Rpb24nKSBtc2cgPSBtc2coKTtcblxuICBtc2cgPSBtc2cgfHwgJyc7XG4gIGlmICghbXNnKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGlmICgvXFxzaGF2ZVxccy8udGVzdChtc2cpKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHZhciBpc09iamVjdCA9IGlzT2JqZWN0VHlwZShleHBlY3RlZCk7XG4gIGlmICgvXFxzbm90XFxzLy50ZXN0KG1zZykpIHtcbiAgICByZXR1cm4gaXNPYmplY3QgPyAnbm90RGVlcFN0cmljdEVxdWFsJyA6ICdub3RTdHJpY3RFcXVhbCc7XG4gIH1cblxuICByZXR1cm4gaXNPYmplY3QgPyAnZGVlcFN0cmljdEVxdWFsJyA6ICdzdHJpY3RFcXVhbCc7XG59O1xuIiwgIi8qIVxuICogY2hhaVxuICogQ29weXJpZ2h0KGMpIDIwMTEgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG4vKiFcbiAqIERlcGVuZGVuY2llcyB0aGF0IGFyZSB1c2VkIGZvciBtdWx0aXBsZSBleHBvcnRzIGFyZSByZXF1aXJlZCBoZXJlIG9ubHkgb25jZVxuICovXG5cbnZhciBwYXRodmFsID0gcmVxdWlyZSgncGF0aHZhbCcpO1xuXG4vKiFcbiAqIHRlc3QgdXRpbGl0eVxuICovXG5cbmV4cG9ydHMudGVzdCA9IHJlcXVpcmUoJy4vdGVzdCcpO1xuXG4vKiFcbiAqIHR5cGUgdXRpbGl0eVxuICovXG5cbmV4cG9ydHMudHlwZSA9IHJlcXVpcmUoJ3R5cGUtZGV0ZWN0Jyk7XG5cbi8qIVxuICogZXhwZWN0VHlwZXMgdXRpbGl0eVxuICovXG5leHBvcnRzLmV4cGVjdFR5cGVzID0gcmVxdWlyZSgnLi9leHBlY3RUeXBlcycpO1xuXG4vKiFcbiAqIG1lc3NhZ2UgdXRpbGl0eVxuICovXG5cbmV4cG9ydHMuZ2V0TWVzc2FnZSA9IHJlcXVpcmUoJy4vZ2V0TWVzc2FnZScpO1xuXG4vKiFcbiAqIGFjdHVhbCB1dGlsaXR5XG4gKi9cblxuZXhwb3J0cy5nZXRBY3R1YWwgPSByZXF1aXJlKCcuL2dldEFjdHVhbCcpO1xuXG4vKiFcbiAqIEluc3BlY3QgdXRpbFxuICovXG5cbmV4cG9ydHMuaW5zcGVjdCA9IHJlcXVpcmUoJy4vaW5zcGVjdCcpO1xuXG4vKiFcbiAqIE9iamVjdCBEaXNwbGF5IHV0aWxcbiAqL1xuXG5leHBvcnRzLm9iakRpc3BsYXkgPSByZXF1aXJlKCcuL29iakRpc3BsYXknKTtcblxuLyohXG4gKiBGbGFnIHV0aWxpdHlcbiAqL1xuXG5leHBvcnRzLmZsYWcgPSByZXF1aXJlKCcuL2ZsYWcnKTtcblxuLyohXG4gKiBGbGFnIHRyYW5zZmVycmluZyB1dGlsaXR5XG4gKi9cblxuZXhwb3J0cy50cmFuc2ZlckZsYWdzID0gcmVxdWlyZSgnLi90cmFuc2ZlckZsYWdzJyk7XG5cbi8qIVxuICogRGVlcCBlcXVhbCB1dGlsaXR5XG4gKi9cblxuZXhwb3J0cy5lcWwgPSByZXF1aXJlKCdkZWVwLWVxbCcpO1xuXG4vKiFcbiAqIERlZXAgcGF0aCBpbmZvXG4gKi9cblxuZXhwb3J0cy5nZXRQYXRoSW5mbyA9IHBhdGh2YWwuZ2V0UGF0aEluZm87XG5cbi8qIVxuICogQ2hlY2sgaWYgYSBwcm9wZXJ0eSBleGlzdHNcbiAqL1xuXG5leHBvcnRzLmhhc1Byb3BlcnR5ID0gcGF0aHZhbC5oYXNQcm9wZXJ0eTtcblxuLyohXG4gKiBGdW5jdGlvbiBuYW1lXG4gKi9cblxuZXhwb3J0cy5nZXROYW1lID0gcmVxdWlyZSgnZ2V0LWZ1bmMtbmFtZScpO1xuXG4vKiFcbiAqIGFkZCBQcm9wZXJ0eVxuICovXG5cbmV4cG9ydHMuYWRkUHJvcGVydHkgPSByZXF1aXJlKCcuL2FkZFByb3BlcnR5Jyk7XG5cbi8qIVxuICogYWRkIE1ldGhvZFxuICovXG5cbmV4cG9ydHMuYWRkTWV0aG9kID0gcmVxdWlyZSgnLi9hZGRNZXRob2QnKTtcblxuLyohXG4gKiBvdmVyd3JpdGUgUHJvcGVydHlcbiAqL1xuXG5leHBvcnRzLm92ZXJ3cml0ZVByb3BlcnR5ID0gcmVxdWlyZSgnLi9vdmVyd3JpdGVQcm9wZXJ0eScpO1xuXG4vKiFcbiAqIG92ZXJ3cml0ZSBNZXRob2RcbiAqL1xuXG5leHBvcnRzLm92ZXJ3cml0ZU1ldGhvZCA9IHJlcXVpcmUoJy4vb3ZlcndyaXRlTWV0aG9kJyk7XG5cbi8qIVxuICogQWRkIGEgY2hhaW5hYmxlIG1ldGhvZFxuICovXG5cbmV4cG9ydHMuYWRkQ2hhaW5hYmxlTWV0aG9kID0gcmVxdWlyZSgnLi9hZGRDaGFpbmFibGVNZXRob2QnKTtcblxuLyohXG4gKiBPdmVyd3JpdGUgY2hhaW5hYmxlIG1ldGhvZFxuICovXG5cbmV4cG9ydHMub3ZlcndyaXRlQ2hhaW5hYmxlTWV0aG9kID0gcmVxdWlyZSgnLi9vdmVyd3JpdGVDaGFpbmFibGVNZXRob2QnKTtcblxuLyohXG4gKiBDb21wYXJlIGJ5IGluc3BlY3QgbWV0aG9kXG4gKi9cblxuZXhwb3J0cy5jb21wYXJlQnlJbnNwZWN0ID0gcmVxdWlyZSgnLi9jb21wYXJlQnlJbnNwZWN0Jyk7XG5cbi8qIVxuICogR2V0IG93biBlbnVtZXJhYmxlIHByb3BlcnR5IHN5bWJvbHMgbWV0aG9kXG4gKi9cblxuZXhwb3J0cy5nZXRPd25FbnVtZXJhYmxlUHJvcGVydHlTeW1ib2xzID0gcmVxdWlyZSgnLi9nZXRPd25FbnVtZXJhYmxlUHJvcGVydHlTeW1ib2xzJyk7XG5cbi8qIVxuICogR2V0IG93biBlbnVtZXJhYmxlIHByb3BlcnRpZXMgbWV0aG9kXG4gKi9cblxuZXhwb3J0cy5nZXRPd25FbnVtZXJhYmxlUHJvcGVydGllcyA9IHJlcXVpcmUoJy4vZ2V0T3duRW51bWVyYWJsZVByb3BlcnRpZXMnKTtcblxuLyohXG4gKiBDaGVja3MgZXJyb3IgYWdhaW5zdCBhIGdpdmVuIHNldCBvZiBjcml0ZXJpYVxuICovXG5cbmV4cG9ydHMuY2hlY2tFcnJvciA9IHJlcXVpcmUoJ2NoZWNrLWVycm9yJyk7XG5cbi8qIVxuICogUHJveGlmeSB1dGlsXG4gKi9cblxuZXhwb3J0cy5wcm94aWZ5ID0gcmVxdWlyZSgnLi9wcm94aWZ5Jyk7XG5cbi8qIVxuICogYWRkTGVuZ3RoR3VhcmQgdXRpbFxuICovXG5cbmV4cG9ydHMuYWRkTGVuZ3RoR3VhcmQgPSByZXF1aXJlKCcuL2FkZExlbmd0aEd1YXJkJyk7XG5cbi8qIVxuICogaXNQcm94eUVuYWJsZWQgaGVscGVyXG4gKi9cblxuZXhwb3J0cy5pc1Byb3h5RW5hYmxlZCA9IHJlcXVpcmUoJy4vaXNQcm94eUVuYWJsZWQnKTtcblxuLyohXG4gKiBpc05hTiBtZXRob2RcbiAqL1xuXG5leHBvcnRzLmlzTmFOID0gcmVxdWlyZSgnLi9pc05hTicpO1xuXG4vKiFcbiAqIGdldE9wZXJhdG9yIG1ldGhvZFxuICovXG5cbmV4cG9ydHMuZ2V0T3BlcmF0b3IgPSByZXF1aXJlKCcuL2dldE9wZXJhdG9yJyk7IiwgIi8qIVxuICogY2hhaVxuICogaHR0cDovL2NoYWlqcy5jb21cbiAqIENvcHlyaWdodChjKSAyMDExLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG52YXIgY29uZmlnID0gcmVxdWlyZSgnLi9jb25maWcnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoX2NoYWksIHV0aWwpIHtcbiAgLyohXG4gICAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gICAqL1xuXG4gIHZhciBBc3NlcnRpb25FcnJvciA9IF9jaGFpLkFzc2VydGlvbkVycm9yXG4gICAgLCBmbGFnID0gdXRpbC5mbGFnO1xuXG4gIC8qIVxuICAgKiBNb2R1bGUgZXhwb3J0LlxuICAgKi9cblxuICBfY2hhaS5Bc3NlcnRpb24gPSBBc3NlcnRpb247XG5cbiAgLyohXG4gICAqIEFzc2VydGlvbiBDb25zdHJ1Y3RvclxuICAgKlxuICAgKiBDcmVhdGVzIG9iamVjdCBmb3IgY2hhaW5pbmcuXG4gICAqXG4gICAqIGBBc3NlcnRpb25gIG9iamVjdHMgY29udGFpbiBtZXRhZGF0YSBpbiB0aGUgZm9ybSBvZiBmbGFncy4gVGhyZWUgZmxhZ3MgY2FuXG4gICAqIGJlIGFzc2lnbmVkIGR1cmluZyBpbnN0YW50aWF0aW9uIGJ5IHBhc3NpbmcgYXJndW1lbnRzIHRvIHRoaXMgY29uc3RydWN0b3I6XG4gICAqXG4gICAqIC0gYG9iamVjdGA6IFRoaXMgZmxhZyBjb250YWlucyB0aGUgdGFyZ2V0IG9mIHRoZSBhc3NlcnRpb24uIEZvciBleGFtcGxlLCBpblxuICAgKiAgIHRoZSBhc3NlcnRpb24gYGV4cGVjdChudW1LaXR0ZW5zKS50by5lcXVhbCg3KTtgLCB0aGUgYG9iamVjdGAgZmxhZyB3aWxsXG4gICAqICAgY29udGFpbiBgbnVtS2l0dGVuc2Agc28gdGhhdCB0aGUgYGVxdWFsYCBhc3NlcnRpb24gY2FuIHJlZmVyZW5jZSBpdCB3aGVuXG4gICAqICAgbmVlZGVkLlxuICAgKlxuICAgKiAtIGBtZXNzYWdlYDogVGhpcyBmbGFnIGNvbnRhaW5zIGFuIG9wdGlvbmFsIGN1c3RvbSBlcnJvciBtZXNzYWdlIHRvIGJlXG4gICAqICAgcHJlcGVuZGVkIHRvIHRoZSBlcnJvciBtZXNzYWdlIHRoYXQncyBnZW5lcmF0ZWQgYnkgdGhlIGFzc2VydGlvbiB3aGVuIGl0XG4gICAqICAgZmFpbHMuXG4gICAqXG4gICAqIC0gYHNzZmlgOiBUaGlzIGZsYWcgc3RhbmRzIGZvciBcInN0YXJ0IHN0YWNrIGZ1bmN0aW9uIGluZGljYXRvclwiLiBJdFxuICAgKiAgIGNvbnRhaW5zIGEgZnVuY3Rpb24gcmVmZXJlbmNlIHRoYXQgc2VydmVzIGFzIHRoZSBzdGFydGluZyBwb2ludCBmb3JcbiAgICogICByZW1vdmluZyBmcmFtZXMgZnJvbSB0aGUgc3RhY2sgdHJhY2Ugb2YgdGhlIGVycm9yIHRoYXQncyBjcmVhdGVkIGJ5IHRoZVxuICAgKiAgIGFzc2VydGlvbiB3aGVuIGl0IGZhaWxzLiBUaGUgZ29hbCBpcyB0byBwcm92aWRlIGEgY2xlYW5lciBzdGFjayB0cmFjZSB0b1xuICAgKiAgIGVuZCB1c2VycyBieSByZW1vdmluZyBDaGFpJ3MgaW50ZXJuYWwgZnVuY3Rpb25zLiBOb3RlIHRoYXQgaXQgb25seSB3b3Jrc1xuICAgKiAgIGluIGVudmlyb25tZW50cyB0aGF0IHN1cHBvcnQgYEVycm9yLmNhcHR1cmVTdGFja1RyYWNlYCwgYW5kIG9ubHkgd2hlblxuICAgKiAgIGBDaGFpLmNvbmZpZy5pbmNsdWRlU3RhY2tgIGhhc24ndCBiZWVuIHNldCB0byBgZmFsc2VgLlxuICAgKlxuICAgKiAtIGBsb2NrU3NmaWA6IFRoaXMgZmxhZyBjb250cm9scyB3aGV0aGVyIG9yIG5vdCB0aGUgZ2l2ZW4gYHNzZmlgIGZsYWdcbiAgICogICBzaG91bGQgcmV0YWluIGl0cyBjdXJyZW50IHZhbHVlLCBldmVuIGFzIGFzc2VydGlvbnMgYXJlIGNoYWluZWQgb2ZmIG9mXG4gICAqICAgdGhpcyBvYmplY3QuIFRoaXMgaXMgdXN1YWxseSBzZXQgdG8gYHRydWVgIHdoZW4gY3JlYXRpbmcgYSBuZXcgYXNzZXJ0aW9uXG4gICAqICAgZnJvbSB3aXRoaW4gYW5vdGhlciBhc3NlcnRpb24uIEl0J3MgYWxzbyB0ZW1wb3JhcmlseSBzZXQgdG8gYHRydWVgIGJlZm9yZVxuICAgKiAgIGFuIG92ZXJ3cml0dGVuIGFzc2VydGlvbiBnZXRzIGNhbGxlZCBieSB0aGUgb3ZlcndyaXRpbmcgYXNzZXJ0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0ge01peGVkfSBvYmogdGFyZ2V0IG9mIHRoZSBhc3NlcnRpb25cbiAgICogQHBhcmFtIHtTdHJpbmd9IG1zZyAob3B0aW9uYWwpIGN1c3RvbSBlcnJvciBtZXNzYWdlXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IHNzZmkgKG9wdGlvbmFsKSBzdGFydGluZyBwb2ludCBmb3IgcmVtb3Zpbmcgc3RhY2sgZnJhbWVzXG4gICAqIEBwYXJhbSB7Qm9vbGVhbn0gbG9ja1NzZmkgKG9wdGlvbmFsKSB3aGV0aGVyIG9yIG5vdCB0aGUgc3NmaSBmbGFnIGlzIGxvY2tlZFxuICAgKiBAYXBpIHByaXZhdGVcbiAgICovXG5cbiAgZnVuY3Rpb24gQXNzZXJ0aW9uIChvYmosIG1zZywgc3NmaSwgbG9ja1NzZmkpIHtcbiAgICBmbGFnKHRoaXMsICdzc2ZpJywgc3NmaSB8fCBBc3NlcnRpb24pO1xuICAgIGZsYWcodGhpcywgJ2xvY2tTc2ZpJywgbG9ja1NzZmkpO1xuICAgIGZsYWcodGhpcywgJ29iamVjdCcsIG9iaik7XG4gICAgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG5cbiAgICByZXR1cm4gdXRpbC5wcm94aWZ5KHRoaXMpO1xuICB9XG5cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEFzc2VydGlvbiwgJ2luY2x1ZGVTdGFjaycsIHtcbiAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgY29uc29sZS53YXJuKCdBc3NlcnRpb24uaW5jbHVkZVN0YWNrIGlzIGRlcHJlY2F0ZWQsIHVzZSBjaGFpLmNvbmZpZy5pbmNsdWRlU3RhY2sgaW5zdGVhZC4nKTtcbiAgICAgIHJldHVybiBjb25maWcuaW5jbHVkZVN0YWNrO1xuICAgIH0sXG4gICAgc2V0OiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgY29uc29sZS53YXJuKCdBc3NlcnRpb24uaW5jbHVkZVN0YWNrIGlzIGRlcHJlY2F0ZWQsIHVzZSBjaGFpLmNvbmZpZy5pbmNsdWRlU3RhY2sgaW5zdGVhZC4nKTtcbiAgICAgIGNvbmZpZy5pbmNsdWRlU3RhY2sgPSB2YWx1ZTtcbiAgICB9XG4gIH0pO1xuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShBc3NlcnRpb24sICdzaG93RGlmZicsIHtcbiAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgY29uc29sZS53YXJuKCdBc3NlcnRpb24uc2hvd0RpZmYgaXMgZGVwcmVjYXRlZCwgdXNlIGNoYWkuY29uZmlnLnNob3dEaWZmIGluc3RlYWQuJyk7XG4gICAgICByZXR1cm4gY29uZmlnLnNob3dEaWZmO1xuICAgIH0sXG4gICAgc2V0OiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgY29uc29sZS53YXJuKCdBc3NlcnRpb24uc2hvd0RpZmYgaXMgZGVwcmVjYXRlZCwgdXNlIGNoYWkuY29uZmlnLnNob3dEaWZmIGluc3RlYWQuJyk7XG4gICAgICBjb25maWcuc2hvd0RpZmYgPSB2YWx1ZTtcbiAgICB9XG4gIH0pO1xuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSA9IGZ1bmN0aW9uIChuYW1lLCBmbikge1xuICAgIHV0aWwuYWRkUHJvcGVydHkodGhpcy5wcm90b3R5cGUsIG5hbWUsIGZuKTtcbiAgfTtcblxuICBBc3NlcnRpb24uYWRkTWV0aG9kID0gZnVuY3Rpb24gKG5hbWUsIGZuKSB7XG4gICAgdXRpbC5hZGRNZXRob2QodGhpcy5wcm90b3R5cGUsIG5hbWUsIGZuKTtcbiAgfTtcblxuICBBc3NlcnRpb24uYWRkQ2hhaW5hYmxlTWV0aG9kID0gZnVuY3Rpb24gKG5hbWUsIGZuLCBjaGFpbmluZ0JlaGF2aW9yKSB7XG4gICAgdXRpbC5hZGRDaGFpbmFibGVNZXRob2QodGhpcy5wcm90b3R5cGUsIG5hbWUsIGZuLCBjaGFpbmluZ0JlaGF2aW9yKTtcbiAgfTtcblxuICBBc3NlcnRpb24ub3ZlcndyaXRlUHJvcGVydHkgPSBmdW5jdGlvbiAobmFtZSwgZm4pIHtcbiAgICB1dGlsLm92ZXJ3cml0ZVByb3BlcnR5KHRoaXMucHJvdG90eXBlLCBuYW1lLCBmbik7XG4gIH07XG5cbiAgQXNzZXJ0aW9uLm92ZXJ3cml0ZU1ldGhvZCA9IGZ1bmN0aW9uIChuYW1lLCBmbikge1xuICAgIHV0aWwub3ZlcndyaXRlTWV0aG9kKHRoaXMucHJvdG90eXBlLCBuYW1lLCBmbik7XG4gIH07XG5cbiAgQXNzZXJ0aW9uLm92ZXJ3cml0ZUNoYWluYWJsZU1ldGhvZCA9IGZ1bmN0aW9uIChuYW1lLCBmbiwgY2hhaW5pbmdCZWhhdmlvcikge1xuICAgIHV0aWwub3ZlcndyaXRlQ2hhaW5hYmxlTWV0aG9kKHRoaXMucHJvdG90eXBlLCBuYW1lLCBmbiwgY2hhaW5pbmdCZWhhdmlvcik7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuYXNzZXJ0KGV4cHJlc3Npb24sIG1lc3NhZ2UsIG5lZ2F0ZU1lc3NhZ2UsIGV4cGVjdGVkLCBhY3R1YWwsIHNob3dEaWZmKVxuICAgKlxuICAgKiBFeGVjdXRlcyBhbiBleHByZXNzaW9uIGFuZCBjaGVjayBleHBlY3RhdGlvbnMuIFRocm93cyBBc3NlcnRpb25FcnJvciBmb3IgcmVwb3J0aW5nIGlmIHRlc3QgZG9lc24ndCBwYXNzLlxuICAgKlxuICAgKiBAbmFtZSBhc3NlcnRcbiAgICogQHBhcmFtIHtQaGlsb3NvcGhpY2FsfSBleHByZXNzaW9uIHRvIGJlIHRlc3RlZFxuICAgKiBAcGFyYW0ge1N0cmluZ3xGdW5jdGlvbn0gbWVzc2FnZSBvciBmdW5jdGlvbiB0aGF0IHJldHVybnMgbWVzc2FnZSB0byBkaXNwbGF5IGlmIGV4cHJlc3Npb24gZmFpbHNcbiAgICogQHBhcmFtIHtTdHJpbmd8RnVuY3Rpb259IG5lZ2F0ZWRNZXNzYWdlIG9yIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBuZWdhdGVkTWVzc2FnZSB0byBkaXNwbGF5IGlmIG5lZ2F0ZWQgZXhwcmVzc2lvbiBmYWlsc1xuICAgKiBAcGFyYW0ge01peGVkfSBleHBlY3RlZCB2YWx1ZSAocmVtZW1iZXIgdG8gY2hlY2sgZm9yIG5lZ2F0aW9uKVxuICAgKiBAcGFyYW0ge01peGVkfSBhY3R1YWwgKG9wdGlvbmFsKSB3aWxsIGRlZmF1bHQgdG8gYHRoaXMub2JqYFxuICAgKiBAcGFyYW0ge0Jvb2xlYW59IHNob3dEaWZmIChvcHRpb25hbCkgd2hlbiBzZXQgdG8gYHRydWVgLCBhc3NlcnQgd2lsbCBkaXNwbGF5IGEgZGlmZiBpbiBhZGRpdGlvbiB0byB0aGUgbWVzc2FnZSBpZiBleHByZXNzaW9uIGZhaWxzXG4gICAqIEBhcGkgcHJpdmF0ZVxuICAgKi9cblxuICBBc3NlcnRpb24ucHJvdG90eXBlLmFzc2VydCA9IGZ1bmN0aW9uIChleHByLCBtc2csIG5lZ2F0ZU1zZywgZXhwZWN0ZWQsIF9hY3R1YWwsIHNob3dEaWZmKSB7XG4gICAgdmFyIG9rID0gdXRpbC50ZXN0KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgaWYgKGZhbHNlICE9PSBzaG93RGlmZikgc2hvd0RpZmYgPSB0cnVlO1xuICAgIGlmICh1bmRlZmluZWQgPT09IGV4cGVjdGVkICYmIHVuZGVmaW5lZCA9PT0gX2FjdHVhbCkgc2hvd0RpZmYgPSBmYWxzZTtcbiAgICBpZiAodHJ1ZSAhPT0gY29uZmlnLnNob3dEaWZmKSBzaG93RGlmZiA9IGZhbHNlO1xuXG4gICAgaWYgKCFvaykge1xuICAgICAgbXNnID0gdXRpbC5nZXRNZXNzYWdlKHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB2YXIgYWN0dWFsID0gdXRpbC5nZXRBY3R1YWwodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIHZhciBhc3NlcnRpb25FcnJvck9iamVjdFByb3BlcnRpZXMgPSB7XG4gICAgICAgICAgYWN0dWFsOiBhY3R1YWxcbiAgICAgICAgLCBleHBlY3RlZDogZXhwZWN0ZWRcbiAgICAgICAgLCBzaG93RGlmZjogc2hvd0RpZmZcbiAgICAgIH07XG5cbiAgICAgIHZhciBvcGVyYXRvciA9IHV0aWwuZ2V0T3BlcmF0b3IodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIGlmIChvcGVyYXRvcikge1xuICAgICAgICBhc3NlcnRpb25FcnJvck9iamVjdFByb3BlcnRpZXMub3BlcmF0b3IgPSBvcGVyYXRvcjtcbiAgICAgIH1cblxuICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKFxuICAgICAgICBtc2csXG4gICAgICAgIGFzc2VydGlvbkVycm9yT2JqZWN0UHJvcGVydGllcyxcbiAgICAgICAgKGNvbmZpZy5pbmNsdWRlU3RhY2spID8gdGhpcy5hc3NlcnQgOiBmbGFnKHRoaXMsICdzc2ZpJykpO1xuICAgIH1cbiAgfTtcblxuICAvKiFcbiAgICogIyMjIC5fb2JqXG4gICAqXG4gICAqIFF1aWNrIHJlZmVyZW5jZSB0byBzdG9yZWQgYGFjdHVhbGAgdmFsdWUgZm9yIHBsdWdpbiBkZXZlbG9wZXJzLlxuICAgKlxuICAgKiBAYXBpIHByaXZhdGVcbiAgICovXG5cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEFzc2VydGlvbi5wcm90b3R5cGUsICdfb2JqJyxcbiAgICB7IGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gICAgICB9XG4gICAgLCBzZXQ6IGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgICAgZmxhZyh0aGlzLCAnb2JqZWN0JywgdmFsKTtcbiAgICAgIH1cbiAgfSk7XG59O1xuIiwgIi8qIVxuICogY2hhaVxuICogaHR0cDovL2NoYWlqcy5jb21cbiAqIENvcHlyaWdodChjKSAyMDExLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChjaGFpLCBfKSB7XG4gIHZhciBBc3NlcnRpb24gPSBjaGFpLkFzc2VydGlvblxuICAgICwgQXNzZXJ0aW9uRXJyb3IgPSBjaGFpLkFzc2VydGlvbkVycm9yXG4gICAgLCBmbGFnID0gXy5mbGFnO1xuXG4gIC8qKlxuICAgKiAjIyMgTGFuZ3VhZ2UgQ2hhaW5zXG4gICAqXG4gICAqIFRoZSBmb2xsb3dpbmcgYXJlIHByb3ZpZGVkIGFzIGNoYWluYWJsZSBnZXR0ZXJzIHRvIGltcHJvdmUgdGhlIHJlYWRhYmlsaXR5XG4gICAqIG9mIHlvdXIgYXNzZXJ0aW9ucy5cbiAgICpcbiAgICogKipDaGFpbnMqKlxuICAgKlxuICAgKiAtIHRvXG4gICAqIC0gYmVcbiAgICogLSBiZWVuXG4gICAqIC0gaXNcbiAgICogLSB0aGF0XG4gICAqIC0gd2hpY2hcbiAgICogLSBhbmRcbiAgICogLSBoYXNcbiAgICogLSBoYXZlXG4gICAqIC0gd2l0aFxuICAgKiAtIGF0XG4gICAqIC0gb2ZcbiAgICogLSBzYW1lXG4gICAqIC0gYnV0XG4gICAqIC0gZG9lc1xuICAgKiAtIHN0aWxsXG4gICAqIC0gYWxzb1xuICAgKlxuICAgKiBAbmFtZSBsYW5ndWFnZSBjaGFpbnNcbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgWyAndG8nLCAnYmUnLCAnYmVlbicsICdpcydcbiAgLCAnYW5kJywgJ2hhcycsICdoYXZlJywgJ3dpdGgnXG4gICwgJ3RoYXQnLCAnd2hpY2gnLCAnYXQnLCAnb2YnXG4gICwgJ3NhbWUnLCAnYnV0JywgJ2RvZXMnLCAnc3RpbGwnLCBcImFsc29cIiBdLmZvckVhY2goZnVuY3Rpb24gKGNoYWluKSB7XG4gICAgQXNzZXJ0aW9uLmFkZFByb3BlcnR5KGNoYWluKTtcbiAgfSk7XG5cbiAgLyoqXG4gICAqICMjIyAubm90XG4gICAqXG4gICAqIE5lZ2F0ZXMgYWxsIGFzc2VydGlvbnMgdGhhdCBmb2xsb3cgaW4gdGhlIGNoYWluLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KGZ1bmN0aW9uICgpIHt9KS50by5ub3QudGhyb3coKTtcbiAgICogICAgIGV4cGVjdCh7YTogMX0pLnRvLm5vdC5oYXZlLnByb3BlcnR5KCdiJyk7XG4gICAqICAgICBleHBlY3QoWzEsIDJdKS50by5iZS5hbignYXJyYXknKS50aGF0LmRvZXMubm90LmluY2x1ZGUoMyk7XG4gICAqXG4gICAqIEp1c3QgYmVjYXVzZSB5b3UgY2FuIG5lZ2F0ZSBhbnkgYXNzZXJ0aW9uIHdpdGggYC5ub3RgIGRvZXNuJ3QgbWVhbiB5b3VcbiAgICogc2hvdWxkLiBXaXRoIGdyZWF0IHBvd2VyIGNvbWVzIGdyZWF0IHJlc3BvbnNpYmlsaXR5LiBJdCdzIG9mdGVuIGJlc3QgdG9cbiAgICogYXNzZXJ0IHRoYXQgdGhlIG9uZSBleHBlY3RlZCBvdXRwdXQgd2FzIHByb2R1Y2VkLCByYXRoZXIgdGhhbiBhc3NlcnRpbmdcbiAgICogdGhhdCBvbmUgb2YgY291bnRsZXNzIHVuZXhwZWN0ZWQgb3V0cHV0cyB3YXNuJ3QgcHJvZHVjZWQuIFNlZSBpbmRpdmlkdWFsXG4gICAqIGFzc2VydGlvbnMgZm9yIHNwZWNpZmljIGd1aWRhbmNlLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KDIpLnRvLmVxdWFsKDIpOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KDIpLnRvLm5vdC5lcXVhbCgxKTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqIEBuYW1lIG5vdFxuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBBc3NlcnRpb24uYWRkUHJvcGVydHkoJ25vdCcsIGZ1bmN0aW9uICgpIHtcbiAgICBmbGFnKHRoaXMsICduZWdhdGUnLCB0cnVlKTtcbiAgfSk7XG5cbiAgLyoqXG4gICAqICMjIyAuZGVlcFxuICAgKlxuICAgKiBDYXVzZXMgYWxsIGAuZXF1YWxgLCBgLmluY2x1ZGVgLCBgLm1lbWJlcnNgLCBgLmtleXNgLCBhbmQgYC5wcm9wZXJ0eWBcbiAgICogYXNzZXJ0aW9ucyB0aGF0IGZvbGxvdyBpbiB0aGUgY2hhaW4gdG8gdXNlIGRlZXAgZXF1YWxpdHkgaW5zdGVhZCBvZiBzdHJpY3RcbiAgICogKGA9PT1gKSBlcXVhbGl0eS4gU2VlIHRoZSBgZGVlcC1lcWxgIHByb2plY3QgcGFnZSBmb3IgaW5mbyBvbiB0aGUgZGVlcFxuICAgKiBlcXVhbGl0eSBhbGdvcml0aG06IGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFpanMvZGVlcC1lcWwuXG4gICAqXG4gICAqICAgICAvLyBUYXJnZXQgb2JqZWN0IGRlZXBseSAoYnV0IG5vdCBzdHJpY3RseSkgZXF1YWxzIGB7YTogMX1gXG4gICAqICAgICBleHBlY3Qoe2E6IDF9KS50by5kZWVwLmVxdWFsKHthOiAxfSk7XG4gICAqICAgICBleHBlY3Qoe2E6IDF9KS50by5ub3QuZXF1YWwoe2E6IDF9KTtcbiAgICpcbiAgICogICAgIC8vIFRhcmdldCBhcnJheSBkZWVwbHkgKGJ1dCBub3Qgc3RyaWN0bHkpIGluY2x1ZGVzIGB7YTogMX1gXG4gICAqICAgICBleHBlY3QoW3thOiAxfV0pLnRvLmRlZXAuaW5jbHVkZSh7YTogMX0pO1xuICAgKiAgICAgZXhwZWN0KFt7YTogMX1dKS50by5ub3QuaW5jbHVkZSh7YTogMX0pO1xuICAgKlxuICAgKiAgICAgLy8gVGFyZ2V0IG9iamVjdCBkZWVwbHkgKGJ1dCBub3Qgc3RyaWN0bHkpIGluY2x1ZGVzIGB4OiB7YTogMX1gXG4gICAqICAgICBleHBlY3Qoe3g6IHthOiAxfX0pLnRvLmRlZXAuaW5jbHVkZSh7eDoge2E6IDF9fSk7XG4gICAqICAgICBleHBlY3Qoe3g6IHthOiAxfX0pLnRvLm5vdC5pbmNsdWRlKHt4OiB7YTogMX19KTtcbiAgICpcbiAgICogICAgIC8vIFRhcmdldCBhcnJheSBkZWVwbHkgKGJ1dCBub3Qgc3RyaWN0bHkpIGhhcyBtZW1iZXIgYHthOiAxfWBcbiAgICogICAgIGV4cGVjdChbe2E6IDF9XSkudG8uaGF2ZS5kZWVwLm1lbWJlcnMoW3thOiAxfV0pO1xuICAgKiAgICAgZXhwZWN0KFt7YTogMX1dKS50by5ub3QuaGF2ZS5tZW1iZXJzKFt7YTogMX1dKTtcbiAgICpcbiAgICogICAgIC8vIFRhcmdldCBzZXQgZGVlcGx5IChidXQgbm90IHN0cmljdGx5KSBoYXMga2V5IGB7YTogMX1gXG4gICAqICAgICBleHBlY3QobmV3IFNldChbe2E6IDF9XSkpLnRvLmhhdmUuZGVlcC5rZXlzKFt7YTogMX1dKTtcbiAgICogICAgIGV4cGVjdChuZXcgU2V0KFt7YTogMX1dKSkudG8ubm90LmhhdmUua2V5cyhbe2E6IDF9XSk7XG4gICAqXG4gICAqICAgICAvLyBUYXJnZXQgb2JqZWN0IGRlZXBseSAoYnV0IG5vdCBzdHJpY3RseSkgaGFzIHByb3BlcnR5IGB4OiB7YTogMX1gXG4gICAqICAgICBleHBlY3Qoe3g6IHthOiAxfX0pLnRvLmhhdmUuZGVlcC5wcm9wZXJ0eSgneCcsIHthOiAxfSk7XG4gICAqICAgICBleHBlY3Qoe3g6IHthOiAxfX0pLnRvLm5vdC5oYXZlLnByb3BlcnR5KCd4Jywge2E6IDF9KTtcbiAgICpcbiAgICogQG5hbWUgZGVlcFxuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBBc3NlcnRpb24uYWRkUHJvcGVydHkoJ2RlZXAnLCBmdW5jdGlvbiAoKSB7XG4gICAgZmxhZyh0aGlzLCAnZGVlcCcsIHRydWUpO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC5uZXN0ZWRcbiAgICpcbiAgICogRW5hYmxlcyBkb3QtIGFuZCBicmFja2V0LW5vdGF0aW9uIGluIGFsbCBgLnByb3BlcnR5YCBhbmQgYC5pbmNsdWRlYFxuICAgKiBhc3NlcnRpb25zIHRoYXQgZm9sbG93IGluIHRoZSBjaGFpbi5cbiAgICpcbiAgICogICAgIGV4cGVjdCh7YToge2I6IFsneCcsICd5J119fSkudG8uaGF2ZS5uZXN0ZWQucHJvcGVydHkoJ2EuYlsxXScpO1xuICAgKiAgICAgZXhwZWN0KHthOiB7YjogWyd4JywgJ3knXX19KS50by5uZXN0ZWQuaW5jbHVkZSh7J2EuYlsxXSc6ICd5J30pO1xuICAgKlxuICAgKiBJZiBgLmAgb3IgYFtdYCBhcmUgcGFydCBvZiBhbiBhY3R1YWwgcHJvcGVydHkgbmFtZSwgdGhleSBjYW4gYmUgZXNjYXBlZCBieVxuICAgKiBhZGRpbmcgdHdvIGJhY2tzbGFzaGVzIGJlZm9yZSB0aGVtLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KHsnLmEnOiB7J1tiXSc6ICd4J319KS50by5oYXZlLm5lc3RlZC5wcm9wZXJ0eSgnXFxcXC5hLlxcXFxbYlxcXFxdJyk7XG4gICAqICAgICBleHBlY3QoeycuYSc6IHsnW2JdJzogJ3gnfX0pLnRvLm5lc3RlZC5pbmNsdWRlKHsnXFxcXC5hLlxcXFxbYlxcXFxdJzogJ3gnfSk7XG4gICAqXG4gICAqIGAubmVzdGVkYCBjYW5ub3QgYmUgY29tYmluZWQgd2l0aCBgLm93bmAuXG4gICAqXG4gICAqIEBuYW1lIG5lc3RlZFxuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBBc3NlcnRpb24uYWRkUHJvcGVydHkoJ25lc3RlZCcsIGZ1bmN0aW9uICgpIHtcbiAgICBmbGFnKHRoaXMsICduZXN0ZWQnLCB0cnVlKTtcbiAgfSk7XG5cbiAgLyoqXG4gICAqICMjIyAub3duXG4gICAqXG4gICAqIENhdXNlcyBhbGwgYC5wcm9wZXJ0eWAgYW5kIGAuaW5jbHVkZWAgYXNzZXJ0aW9ucyB0aGF0IGZvbGxvdyBpbiB0aGUgY2hhaW5cbiAgICogdG8gaWdub3JlIGluaGVyaXRlZCBwcm9wZXJ0aWVzLlxuICAgKlxuICAgKiAgICAgT2JqZWN0LnByb3RvdHlwZS5iID0gMjtcbiAgICpcbiAgICogICAgIGV4cGVjdCh7YTogMX0pLnRvLmhhdmUub3duLnByb3BlcnR5KCdhJyk7XG4gICAqICAgICBleHBlY3Qoe2E6IDF9KS50by5oYXZlLnByb3BlcnR5KCdiJyk7XG4gICAqICAgICBleHBlY3Qoe2E6IDF9KS50by5ub3QuaGF2ZS5vd24ucHJvcGVydHkoJ2InKTtcbiAgICpcbiAgICogICAgIGV4cGVjdCh7YTogMX0pLnRvLm93bi5pbmNsdWRlKHthOiAxfSk7XG4gICAqICAgICBleHBlY3Qoe2E6IDF9KS50by5pbmNsdWRlKHtiOiAyfSkuYnV0Lm5vdC5vd24uaW5jbHVkZSh7YjogMn0pO1xuICAgKlxuICAgKiBgLm93bmAgY2Fubm90IGJlIGNvbWJpbmVkIHdpdGggYC5uZXN0ZWRgLlxuICAgKlxuICAgKiBAbmFtZSBvd25cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgQXNzZXJ0aW9uLmFkZFByb3BlcnR5KCdvd24nLCBmdW5jdGlvbiAoKSB7XG4gICAgZmxhZyh0aGlzLCAnb3duJywgdHJ1ZSk7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiAjIyMgLm9yZGVyZWRcbiAgICpcbiAgICogQ2F1c2VzIGFsbCBgLm1lbWJlcnNgIGFzc2VydGlvbnMgdGhhdCBmb2xsb3cgaW4gdGhlIGNoYWluIHRvIHJlcXVpcmUgdGhhdFxuICAgKiBtZW1iZXJzIGJlIGluIHRoZSBzYW1lIG9yZGVyLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KFsxLCAyXSkudG8uaGF2ZS5vcmRlcmVkLm1lbWJlcnMoWzEsIDJdKVxuICAgKiAgICAgICAuYnV0Lm5vdC5oYXZlLm9yZGVyZWQubWVtYmVycyhbMiwgMV0pO1xuICAgKlxuICAgKiBXaGVuIGAuaW5jbHVkZWAgYW5kIGAub3JkZXJlZGAgYXJlIGNvbWJpbmVkLCB0aGUgb3JkZXJpbmcgYmVnaW5zIGF0IHRoZVxuICAgKiBzdGFydCBvZiBib3RoIGFycmF5cy5cbiAgICpcbiAgICogICAgIGV4cGVjdChbMSwgMiwgM10pLnRvLmluY2x1ZGUub3JkZXJlZC5tZW1iZXJzKFsxLCAyXSlcbiAgICogICAgICAgLmJ1dC5ub3QuaW5jbHVkZS5vcmRlcmVkLm1lbWJlcnMoWzIsIDNdKTtcbiAgICpcbiAgICogQG5hbWUgb3JkZXJlZFxuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBBc3NlcnRpb24uYWRkUHJvcGVydHkoJ29yZGVyZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgZmxhZyh0aGlzLCAnb3JkZXJlZCcsIHRydWUpO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC5hbnlcbiAgICpcbiAgICogQ2F1c2VzIGFsbCBgLmtleXNgIGFzc2VydGlvbnMgdGhhdCBmb2xsb3cgaW4gdGhlIGNoYWluIHRvIG9ubHkgcmVxdWlyZSB0aGF0XG4gICAqIHRoZSB0YXJnZXQgaGF2ZSBhdCBsZWFzdCBvbmUgb2YgdGhlIGdpdmVuIGtleXMuIFRoaXMgaXMgdGhlIG9wcG9zaXRlIG9mXG4gICAqIGAuYWxsYCwgd2hpY2ggcmVxdWlyZXMgdGhhdCB0aGUgdGFyZ2V0IGhhdmUgYWxsIG9mIHRoZSBnaXZlbiBrZXlzLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KHthOiAxLCBiOiAyfSkudG8ubm90LmhhdmUuYW55LmtleXMoJ2MnLCAnZCcpO1xuICAgKlxuICAgKiBTZWUgdGhlIGAua2V5c2AgZG9jIGZvciBndWlkYW5jZSBvbiB3aGVuIHRvIHVzZSBgLmFueWAgb3IgYC5hbGxgLlxuICAgKlxuICAgKiBAbmFtZSBhbnlcbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgQXNzZXJ0aW9uLmFkZFByb3BlcnR5KCdhbnknLCBmdW5jdGlvbiAoKSB7XG4gICAgZmxhZyh0aGlzLCAnYW55JywgdHJ1ZSk7XG4gICAgZmxhZyh0aGlzLCAnYWxsJywgZmFsc2UpO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC5hbGxcbiAgICpcbiAgICogQ2F1c2VzIGFsbCBgLmtleXNgIGFzc2VydGlvbnMgdGhhdCBmb2xsb3cgaW4gdGhlIGNoYWluIHRvIHJlcXVpcmUgdGhhdCB0aGVcbiAgICogdGFyZ2V0IGhhdmUgYWxsIG9mIHRoZSBnaXZlbiBrZXlzLiBUaGlzIGlzIHRoZSBvcHBvc2l0ZSBvZiBgLmFueWAsIHdoaWNoXG4gICAqIG9ubHkgcmVxdWlyZXMgdGhhdCB0aGUgdGFyZ2V0IGhhdmUgYXQgbGVhc3Qgb25lIG9mIHRoZSBnaXZlbiBrZXlzLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KHthOiAxLCBiOiAyfSkudG8uaGF2ZS5hbGwua2V5cygnYScsICdiJyk7XG4gICAqXG4gICAqIE5vdGUgdGhhdCBgLmFsbGAgaXMgdXNlZCBieSBkZWZhdWx0IHdoZW4gbmVpdGhlciBgLmFsbGAgbm9yIGAuYW55YCBhcmVcbiAgICogYWRkZWQgZWFybGllciBpbiB0aGUgY2hhaW4uIEhvd2V2ZXIsIGl0J3Mgb2Z0ZW4gYmVzdCB0byBhZGQgYC5hbGxgIGFueXdheVxuICAgKiBiZWNhdXNlIGl0IGltcHJvdmVzIHJlYWRhYmlsaXR5LlxuICAgKlxuICAgKiBTZWUgdGhlIGAua2V5c2AgZG9jIGZvciBndWlkYW5jZSBvbiB3aGVuIHRvIHVzZSBgLmFueWAgb3IgYC5hbGxgLlxuICAgKlxuICAgKiBAbmFtZSBhbGxcbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgQXNzZXJ0aW9uLmFkZFByb3BlcnR5KCdhbGwnLCBmdW5jdGlvbiAoKSB7XG4gICAgZmxhZyh0aGlzLCAnYWxsJywgdHJ1ZSk7XG4gICAgZmxhZyh0aGlzLCAnYW55JywgZmFsc2UpO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC5hKHR5cGVbLCBtc2ddKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCdzIHR5cGUgaXMgZXF1YWwgdG8gdGhlIGdpdmVuIHN0cmluZyBgdHlwZWAuIFR5cGVzXG4gICAqIGFyZSBjYXNlIGluc2Vuc2l0aXZlLiBTZWUgdGhlIGB0eXBlLWRldGVjdGAgcHJvamVjdCBwYWdlIGZvciBpbmZvIG9uIHRoZVxuICAgKiB0eXBlIGRldGVjdGlvbiBhbGdvcml0aG06IGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFpanMvdHlwZS1kZXRlY3QuXG4gICAqXG4gICAqICAgICBleHBlY3QoJ2ZvbycpLnRvLmJlLmEoJ3N0cmluZycpO1xuICAgKiAgICAgZXhwZWN0KHthOiAxfSkudG8uYmUuYW4oJ29iamVjdCcpO1xuICAgKiAgICAgZXhwZWN0KG51bGwpLnRvLmJlLmEoJ251bGwnKTtcbiAgICogICAgIGV4cGVjdCh1bmRlZmluZWQpLnRvLmJlLmFuKCd1bmRlZmluZWQnKTtcbiAgICogICAgIGV4cGVjdChuZXcgRXJyb3IpLnRvLmJlLmFuKCdlcnJvcicpO1xuICAgKiAgICAgZXhwZWN0KFByb21pc2UucmVzb2x2ZSgpKS50by5iZS5hKCdwcm9taXNlJyk7XG4gICAqICAgICBleHBlY3QobmV3IEZsb2F0MzJBcnJheSkudG8uYmUuYSgnZmxvYXQzMmFycmF5Jyk7XG4gICAqICAgICBleHBlY3QoU3ltYm9sKCkpLnRvLmJlLmEoJ3N5bWJvbCcpO1xuICAgKlxuICAgKiBgLmFgIHN1cHBvcnRzIG9iamVjdHMgdGhhdCBoYXZlIGEgY3VzdG9tIHR5cGUgc2V0IHZpYSBgU3ltYm9sLnRvU3RyaW5nVGFnYC5cbiAgICpcbiAgICogICAgIHZhciBteU9iaiA9IHtcbiAgICogICAgICAgW1N5bWJvbC50b1N0cmluZ1RhZ106ICdteUN1c3RvbVR5cGUnXG4gICAqICAgICB9O1xuICAgKlxuICAgKiAgICAgZXhwZWN0KG15T2JqKS50by5iZS5hKCdteUN1c3RvbVR5cGUnKS5idXQubm90LmFuKCdvYmplY3QnKTtcbiAgICpcbiAgICogSXQncyBvZnRlbiBiZXN0IHRvIHVzZSBgLmFgIHRvIGNoZWNrIGEgdGFyZ2V0J3MgdHlwZSBiZWZvcmUgbWFraW5nIG1vcmVcbiAgICogYXNzZXJ0aW9ucyBvbiB0aGUgc2FtZSB0YXJnZXQuIFRoYXQgd2F5LCB5b3UgYXZvaWQgdW5leHBlY3RlZCBiZWhhdmlvciBmcm9tXG4gICAqIGFueSBhc3NlcnRpb24gdGhhdCBkb2VzIGRpZmZlcmVudCB0aGluZ3MgYmFzZWQgb24gdGhlIHRhcmdldCdzIHR5cGUuXG4gICAqXG4gICAqICAgICBleHBlY3QoWzEsIDIsIDNdKS50by5iZS5hbignYXJyYXknKS50aGF0LmluY2x1ZGVzKDIpO1xuICAgKiAgICAgZXhwZWN0KFtdKS50by5iZS5hbignYXJyYXknKS50aGF0LmlzLmVtcHR5O1xuICAgKlxuICAgKiBBZGQgYC5ub3RgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIG5lZ2F0ZSBgLmFgLiBIb3dldmVyLCBpdCdzIG9mdGVuIGJlc3QgdG9cbiAgICogYXNzZXJ0IHRoYXQgdGhlIHRhcmdldCBpcyB0aGUgZXhwZWN0ZWQgdHlwZSwgcmF0aGVyIHRoYW4gYXNzZXJ0aW5nIHRoYXQgaXRcbiAgICogaXNuJ3Qgb25lIG9mIG1hbnkgdW5leHBlY3RlZCB0eXBlcy5cbiAgICpcbiAgICogICAgIGV4cGVjdCgnZm9vJykudG8uYmUuYSgnc3RyaW5nJyk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoJ2ZvbycpLnRvLm5vdC5iZS5hbignYXJyYXknKTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqIGAuYWAgYWNjZXB0cyBhbiBvcHRpb25hbCBgbXNnYCBhcmd1bWVudCB3aGljaCBpcyBhIGN1c3RvbSBlcnJvciBtZXNzYWdlIHRvXG4gICAqIHNob3cgd2hlbiB0aGUgYXNzZXJ0aW9uIGZhaWxzLiBUaGUgbWVzc2FnZSBjYW4gYWxzbyBiZSBnaXZlbiBhcyB0aGUgc2Vjb25kXG4gICAqIGFyZ3VtZW50IHRvIGBleHBlY3RgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KDEpLnRvLmJlLmEoJ3N0cmluZycsICdub29vIHdoeSBmYWlsPz8nKTtcbiAgICogICAgIGV4cGVjdCgxLCAnbm9vbyB3aHkgZmFpbD8/JykudG8uYmUuYSgnc3RyaW5nJyk7XG4gICAqXG4gICAqIGAuYWAgY2FuIGFsc28gYmUgdXNlZCBhcyBhIGxhbmd1YWdlIGNoYWluIHRvIGltcHJvdmUgdGhlIHJlYWRhYmlsaXR5IG9mXG4gICAqIHlvdXIgYXNzZXJ0aW9ucy5cbiAgICpcbiAgICogICAgIGV4cGVjdCh7YjogMn0pLnRvLmhhdmUuYS5wcm9wZXJ0eSgnYicpO1xuICAgKlxuICAgKiBUaGUgYWxpYXMgYC5hbmAgY2FuIGJlIHVzZWQgaW50ZXJjaGFuZ2VhYmx5IHdpdGggYC5hYC5cbiAgICpcbiAgICogQG5hbWUgYVxuICAgKiBAYWxpYXMgYW5cbiAgICogQHBhcmFtIHtTdHJpbmd9IHR5cGVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1zZyBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGFuICh0eXBlLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB0eXBlID0gdHlwZS50b0xvd2VyQ2FzZSgpO1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCBhcnRpY2xlID0gflsgJ2EnLCAnZScsICdpJywgJ28nLCAndScgXS5pbmRleE9mKHR5cGUuY2hhckF0KDApKSA/ICdhbiAnIDogJ2EgJztcblxuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICB0eXBlID09PSBfLnR5cGUob2JqKS50b0xvd2VyQ2FzZSgpXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlICcgKyBhcnRpY2xlICsgdHlwZVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSBub3QgdG8gYmUgJyArIGFydGljbGUgKyB0eXBlXG4gICAgKTtcbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRDaGFpbmFibGVNZXRob2QoJ2FuJywgYW4pO1xuICBBc3NlcnRpb24uYWRkQ2hhaW5hYmxlTWV0aG9kKCdhJywgYW4pO1xuXG4gIC8qKlxuICAgKiAjIyMgLmluY2x1ZGUodmFsWywgbXNnXSlcbiAgICpcbiAgICogV2hlbiB0aGUgdGFyZ2V0IGlzIGEgc3RyaW5nLCBgLmluY2x1ZGVgIGFzc2VydHMgdGhhdCB0aGUgZ2l2ZW4gc3RyaW5nIGB2YWxgXG4gICAqIGlzIGEgc3Vic3RyaW5nIG9mIHRoZSB0YXJnZXQuXG4gICAqXG4gICAqICAgICBleHBlY3QoJ2Zvb2JhcicpLnRvLmluY2x1ZGUoJ2ZvbycpO1xuICAgKlxuICAgKiBXaGVuIHRoZSB0YXJnZXQgaXMgYW4gYXJyYXksIGAuaW5jbHVkZWAgYXNzZXJ0cyB0aGF0IHRoZSBnaXZlbiBgdmFsYCBpcyBhXG4gICAqIG1lbWJlciBvZiB0aGUgdGFyZ2V0LlxuICAgKlxuICAgKiAgICAgZXhwZWN0KFsxLCAyLCAzXSkudG8uaW5jbHVkZSgyKTtcbiAgICpcbiAgICogV2hlbiB0aGUgdGFyZ2V0IGlzIGFuIG9iamVjdCwgYC5pbmNsdWRlYCBhc3NlcnRzIHRoYXQgdGhlIGdpdmVuIG9iamVjdFxuICAgKiBgdmFsYCdzIHByb3BlcnRpZXMgYXJlIGEgc3Vic2V0IG9mIHRoZSB0YXJnZXQncyBwcm9wZXJ0aWVzLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KHthOiAxLCBiOiAyLCBjOiAzfSkudG8uaW5jbHVkZSh7YTogMSwgYjogMn0pO1xuICAgKlxuICAgKiBXaGVuIHRoZSB0YXJnZXQgaXMgYSBTZXQgb3IgV2Vha1NldCwgYC5pbmNsdWRlYCBhc3NlcnRzIHRoYXQgdGhlIGdpdmVuIGB2YWxgIGlzIGFcbiAgICogbWVtYmVyIG9mIHRoZSB0YXJnZXQuIFNhbWVWYWx1ZVplcm8gZXF1YWxpdHkgYWxnb3JpdGhtIGlzIHVzZWQuXG4gICAqXG4gICAqICAgICBleHBlY3QobmV3IFNldChbMSwgMl0pKS50by5pbmNsdWRlKDIpO1xuICAgKlxuICAgKiBXaGVuIHRoZSB0YXJnZXQgaXMgYSBNYXAsIGAuaW5jbHVkZWAgYXNzZXJ0cyB0aGF0IHRoZSBnaXZlbiBgdmFsYCBpcyBvbmUgb2ZcbiAgICogdGhlIHZhbHVlcyBvZiB0aGUgdGFyZ2V0LiBTYW1lVmFsdWVaZXJvIGVxdWFsaXR5IGFsZ29yaXRobSBpcyB1c2VkLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KG5ldyBNYXAoW1snYScsIDFdLCBbJ2InLCAyXV0pKS50by5pbmNsdWRlKDIpO1xuICAgKlxuICAgKiBCZWNhdXNlIGAuaW5jbHVkZWAgZG9lcyBkaWZmZXJlbnQgdGhpbmdzIGJhc2VkIG9uIHRoZSB0YXJnZXQncyB0eXBlLCBpdCdzXG4gICAqIGltcG9ydGFudCB0byBjaGVjayB0aGUgdGFyZ2V0J3MgdHlwZSBiZWZvcmUgdXNpbmcgYC5pbmNsdWRlYC4gU2VlIHRoZSBgLmFgXG4gICAqIGRvYyBmb3IgaW5mbyBvbiB0ZXN0aW5nIGEgdGFyZ2V0J3MgdHlwZS5cbiAgICpcbiAgICogICAgIGV4cGVjdChbMSwgMiwgM10pLnRvLmJlLmFuKCdhcnJheScpLnRoYXQuaW5jbHVkZXMoMik7XG4gICAqXG4gICAqIEJ5IGRlZmF1bHQsIHN0cmljdCAoYD09PWApIGVxdWFsaXR5IGlzIHVzZWQgdG8gY29tcGFyZSBhcnJheSBtZW1iZXJzIGFuZFxuICAgKiBvYmplY3QgcHJvcGVydGllcy4gQWRkIGAuZGVlcGAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gdXNlIGRlZXAgZXF1YWxpdHlcbiAgICogaW5zdGVhZCAoV2Vha1NldCB0YXJnZXRzIGFyZSBub3Qgc3VwcG9ydGVkKS4gU2VlIHRoZSBgZGVlcC1lcWxgIHByb2plY3RcbiAgICogcGFnZSBmb3IgaW5mbyBvbiB0aGUgZGVlcCBlcXVhbGl0eSBhbGdvcml0aG06IGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFpanMvZGVlcC1lcWwuXG4gICAqXG4gICAqICAgICAvLyBUYXJnZXQgYXJyYXkgZGVlcGx5IChidXQgbm90IHN0cmljdGx5KSBpbmNsdWRlcyBge2E6IDF9YFxuICAgKiAgICAgZXhwZWN0KFt7YTogMX1dKS50by5kZWVwLmluY2x1ZGUoe2E6IDF9KTtcbiAgICogICAgIGV4cGVjdChbe2E6IDF9XSkudG8ubm90LmluY2x1ZGUoe2E6IDF9KTtcbiAgICpcbiAgICogICAgIC8vIFRhcmdldCBvYmplY3QgZGVlcGx5IChidXQgbm90IHN0cmljdGx5KSBpbmNsdWRlcyBgeDoge2E6IDF9YFxuICAgKiAgICAgZXhwZWN0KHt4OiB7YTogMX19KS50by5kZWVwLmluY2x1ZGUoe3g6IHthOiAxfX0pO1xuICAgKiAgICAgZXhwZWN0KHt4OiB7YTogMX19KS50by5ub3QuaW5jbHVkZSh7eDoge2E6IDF9fSk7XG4gICAqXG4gICAqIEJ5IGRlZmF1bHQsIGFsbCBvZiB0aGUgdGFyZ2V0J3MgcHJvcGVydGllcyBhcmUgc2VhcmNoZWQgd2hlbiB3b3JraW5nIHdpdGhcbiAgICogb2JqZWN0cy4gVGhpcyBpbmNsdWRlcyBwcm9wZXJ0aWVzIHRoYXQgYXJlIGluaGVyaXRlZCBhbmQvb3Igbm9uLWVudW1lcmFibGUuXG4gICAqIEFkZCBgLm93bmAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gZXhjbHVkZSB0aGUgdGFyZ2V0J3MgaW5oZXJpdGVkXG4gICAqIHByb3BlcnRpZXMgZnJvbSB0aGUgc2VhcmNoLlxuICAgKlxuICAgKiAgICAgT2JqZWN0LnByb3RvdHlwZS5iID0gMjtcbiAgICpcbiAgICogICAgIGV4cGVjdCh7YTogMX0pLnRvLm93bi5pbmNsdWRlKHthOiAxfSk7XG4gICAqICAgICBleHBlY3Qoe2E6IDF9KS50by5pbmNsdWRlKHtiOiAyfSkuYnV0Lm5vdC5vd24uaW5jbHVkZSh7YjogMn0pO1xuICAgKlxuICAgKiBOb3RlIHRoYXQgYSB0YXJnZXQgb2JqZWN0IGlzIGFsd2F5cyBvbmx5IHNlYXJjaGVkIGZvciBgdmFsYCdzIG93blxuICAgKiBlbnVtZXJhYmxlIHByb3BlcnRpZXMuXG4gICAqXG4gICAqIGAuZGVlcGAgYW5kIGAub3duYCBjYW4gYmUgY29tYmluZWQuXG4gICAqXG4gICAqICAgICBleHBlY3Qoe2E6IHtiOiAyfX0pLnRvLmRlZXAub3duLmluY2x1ZGUoe2E6IHtiOiAyfX0pO1xuICAgKlxuICAgKiBBZGQgYC5uZXN0ZWRgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIGVuYWJsZSBkb3QtIGFuZCBicmFja2V0LW5vdGF0aW9uIHdoZW5cbiAgICogcmVmZXJlbmNpbmcgbmVzdGVkIHByb3BlcnRpZXMuXG4gICAqXG4gICAqICAgICBleHBlY3Qoe2E6IHtiOiBbJ3gnLCAneSddfX0pLnRvLm5lc3RlZC5pbmNsdWRlKHsnYS5iWzFdJzogJ3knfSk7XG4gICAqXG4gICAqIElmIGAuYCBvciBgW11gIGFyZSBwYXJ0IG9mIGFuIGFjdHVhbCBwcm9wZXJ0eSBuYW1lLCB0aGV5IGNhbiBiZSBlc2NhcGVkIGJ5XG4gICAqIGFkZGluZyB0d28gYmFja3NsYXNoZXMgYmVmb3JlIHRoZW0uXG4gICAqXG4gICAqICAgICBleHBlY3QoeycuYSc6IHsnW2JdJzogMn19KS50by5uZXN0ZWQuaW5jbHVkZSh7J1xcXFwuYS5cXFxcW2JcXFxcXSc6IDJ9KTtcbiAgICpcbiAgICogYC5kZWVwYCBhbmQgYC5uZXN0ZWRgIGNhbiBiZSBjb21iaW5lZC5cbiAgICpcbiAgICogICAgIGV4cGVjdCh7YToge2I6IFt7YzogM31dfX0pLnRvLmRlZXAubmVzdGVkLmluY2x1ZGUoeydhLmJbMF0nOiB7YzogM319KTtcbiAgICpcbiAgICogYC5vd25gIGFuZCBgLm5lc3RlZGAgY2Fubm90IGJlIGNvbWJpbmVkLlxuICAgKlxuICAgKiBBZGQgYC5ub3RgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIG5lZ2F0ZSBgLmluY2x1ZGVgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KCdmb29iYXInKS50by5ub3QuaW5jbHVkZSgndGFjbycpO1xuICAgKiAgICAgZXhwZWN0KFsxLCAyLCAzXSkudG8ubm90LmluY2x1ZGUoNCk7XG4gICAqXG4gICAqIEhvd2V2ZXIsIGl0J3MgZGFuZ2Vyb3VzIHRvIG5lZ2F0ZSBgLmluY2x1ZGVgIHdoZW4gdGhlIHRhcmdldCBpcyBhbiBvYmplY3QuXG4gICAqIFRoZSBwcm9ibGVtIGlzIHRoYXQgaXQgY3JlYXRlcyB1bmNlcnRhaW4gZXhwZWN0YXRpb25zIGJ5IGFzc2VydGluZyB0aGF0IHRoZVxuICAgKiB0YXJnZXQgb2JqZWN0IGRvZXNuJ3QgaGF2ZSBhbGwgb2YgYHZhbGAncyBrZXkvdmFsdWUgcGFpcnMgYnV0IG1heSBvciBtYXlcbiAgICogbm90IGhhdmUgc29tZSBvZiB0aGVtLiBJdCdzIG9mdGVuIGJlc3QgdG8gaWRlbnRpZnkgdGhlIGV4YWN0IG91dHB1dCB0aGF0J3NcbiAgICogZXhwZWN0ZWQsIGFuZCB0aGVuIHdyaXRlIGFuIGFzc2VydGlvbiB0aGF0IG9ubHkgYWNjZXB0cyB0aGF0IGV4YWN0IG91dHB1dC5cbiAgICpcbiAgICogV2hlbiB0aGUgdGFyZ2V0IG9iamVjdCBpc24ndCBldmVuIGV4cGVjdGVkIHRvIGhhdmUgYHZhbGAncyBrZXlzLCBpdCdzXG4gICAqIG9mdGVuIGJlc3QgdG8gYXNzZXJ0IGV4YWN0bHkgdGhhdC5cbiAgICpcbiAgICogICAgIGV4cGVjdCh7YzogM30pLnRvLm5vdC5oYXZlLmFueS5rZXlzKCdhJywgJ2InKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCh7YzogM30pLnRvLm5vdC5pbmNsdWRlKHthOiAxLCBiOiAyfSk7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBXaGVuIHRoZSB0YXJnZXQgb2JqZWN0IGlzIGV4cGVjdGVkIHRvIGhhdmUgYHZhbGAncyBrZXlzLCBpdCdzIG9mdGVuIGJlc3QgdG9cbiAgICogYXNzZXJ0IHRoYXQgZWFjaCBvZiB0aGUgcHJvcGVydGllcyBoYXMgaXRzIGV4cGVjdGVkIHZhbHVlLCByYXRoZXIgdGhhblxuICAgKiBhc3NlcnRpbmcgdGhhdCBlYWNoIHByb3BlcnR5IGRvZXNuJ3QgaGF2ZSBvbmUgb2YgbWFueSB1bmV4cGVjdGVkIHZhbHVlcy5cbiAgICpcbiAgICogICAgIGV4cGVjdCh7YTogMywgYjogNH0pLnRvLmluY2x1ZGUoe2E6IDMsIGI6IDR9KTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCh7YTogMywgYjogNH0pLnRvLm5vdC5pbmNsdWRlKHthOiAxLCBiOiAyfSk7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBgLmluY2x1ZGVgIGFjY2VwdHMgYW4gb3B0aW9uYWwgYG1zZ2AgYXJndW1lbnQgd2hpY2ggaXMgYSBjdXN0b20gZXJyb3JcbiAgICogbWVzc2FnZSB0byBzaG93IHdoZW4gdGhlIGFzc2VydGlvbiBmYWlscy4gVGhlIG1lc3NhZ2UgY2FuIGFsc28gYmUgZ2l2ZW4gYXNcbiAgICogdGhlIHNlY29uZCBhcmd1bWVudCB0byBgZXhwZWN0YC5cbiAgICpcbiAgICogICAgIGV4cGVjdChbMSwgMiwgM10pLnRvLmluY2x1ZGUoNCwgJ25vb28gd2h5IGZhaWw/PycpO1xuICAgKiAgICAgZXhwZWN0KFsxLCAyLCAzXSwgJ25vb28gd2h5IGZhaWw/PycpLnRvLmluY2x1ZGUoNCk7XG4gICAqXG4gICAqIGAuaW5jbHVkZWAgY2FuIGFsc28gYmUgdXNlZCBhcyBhIGxhbmd1YWdlIGNoYWluLCBjYXVzaW5nIGFsbCBgLm1lbWJlcnNgIGFuZFxuICAgKiBgLmtleXNgIGFzc2VydGlvbnMgdGhhdCBmb2xsb3cgaW4gdGhlIGNoYWluIHRvIHJlcXVpcmUgdGhlIHRhcmdldCB0byBiZSBhXG4gICAqIHN1cGVyc2V0IG9mIHRoZSBleHBlY3RlZCBzZXQsIHJhdGhlciB0aGFuIGFuIGlkZW50aWNhbCBzZXQuIE5vdGUgdGhhdFxuICAgKiBgLm1lbWJlcnNgIGlnbm9yZXMgZHVwbGljYXRlcyBpbiB0aGUgc3Vic2V0IHdoZW4gYC5pbmNsdWRlYCBpcyBhZGRlZC5cbiAgICpcbiAgICogICAgIC8vIFRhcmdldCBvYmplY3QncyBrZXlzIGFyZSBhIHN1cGVyc2V0IG9mIFsnYScsICdiJ10gYnV0IG5vdCBpZGVudGljYWxcbiAgICogICAgIGV4cGVjdCh7YTogMSwgYjogMiwgYzogM30pLnRvLmluY2x1ZGUuYWxsLmtleXMoJ2EnLCAnYicpO1xuICAgKiAgICAgZXhwZWN0KHthOiAxLCBiOiAyLCBjOiAzfSkudG8ubm90LmhhdmUuYWxsLmtleXMoJ2EnLCAnYicpO1xuICAgKlxuICAgKiAgICAgLy8gVGFyZ2V0IGFycmF5IGlzIGEgc3VwZXJzZXQgb2YgWzEsIDJdIGJ1dCBub3QgaWRlbnRpY2FsXG4gICAqICAgICBleHBlY3QoWzEsIDIsIDNdKS50by5pbmNsdWRlLm1lbWJlcnMoWzEsIDJdKTtcbiAgICogICAgIGV4cGVjdChbMSwgMiwgM10pLnRvLm5vdC5oYXZlLm1lbWJlcnMoWzEsIDJdKTtcbiAgICpcbiAgICogICAgIC8vIER1cGxpY2F0ZXMgaW4gdGhlIHN1YnNldCBhcmUgaWdub3JlZFxuICAgKiAgICAgZXhwZWN0KFsxLCAyLCAzXSkudG8uaW5jbHVkZS5tZW1iZXJzKFsxLCAyLCAyLCAyXSk7XG4gICAqXG4gICAqIE5vdGUgdGhhdCBhZGRpbmcgYC5hbnlgIGVhcmxpZXIgaW4gdGhlIGNoYWluIGNhdXNlcyB0aGUgYC5rZXlzYCBhc3NlcnRpb25cbiAgICogdG8gaWdub3JlIGAuaW5jbHVkZWAuXG4gICAqXG4gICAqICAgICAvLyBCb3RoIGFzc2VydGlvbnMgYXJlIGlkZW50aWNhbFxuICAgKiAgICAgZXhwZWN0KHthOiAxfSkudG8uaW5jbHVkZS5hbnkua2V5cygnYScsICdiJyk7XG4gICAqICAgICBleHBlY3Qoe2E6IDF9KS50by5oYXZlLmFueS5rZXlzKCdhJywgJ2InKTtcbiAgICpcbiAgICogVGhlIGFsaWFzZXMgYC5pbmNsdWRlc2AsIGAuY29udGFpbmAsIGFuZCBgLmNvbnRhaW5zYCBjYW4gYmUgdXNlZFxuICAgKiBpbnRlcmNoYW5nZWFibHkgd2l0aCBgLmluY2x1ZGVgLlxuICAgKlxuICAgKiBAbmFtZSBpbmNsdWRlXG4gICAqIEBhbGlhcyBjb250YWluXG4gICAqIEBhbGlhcyBpbmNsdWRlc1xuICAgKiBAYWxpYXMgY29udGFpbnNcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtc2cgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBTYW1lVmFsdWVaZXJvKGEsIGIpIHtcbiAgICByZXR1cm4gKF8uaXNOYU4oYSkgJiYgXy5pc05hTihiKSkgfHwgYSA9PT0gYjtcbiAgfVxuXG4gIGZ1bmN0aW9uIGluY2x1ZGVDaGFpbmluZ0JlaGF2aW9yICgpIHtcbiAgICBmbGFnKHRoaXMsICdjb250YWlucycsIHRydWUpO1xuICB9XG5cbiAgZnVuY3Rpb24gaW5jbHVkZSAodmFsLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcblxuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCBvYmpUeXBlID0gXy50eXBlKG9iaikudG9Mb3dlckNhc2UoKVxuICAgICAgLCBmbGFnTXNnID0gZmxhZyh0aGlzLCAnbWVzc2FnZScpXG4gICAgICAsIG5lZ2F0ZSA9IGZsYWcodGhpcywgJ25lZ2F0ZScpXG4gICAgICAsIHNzZmkgPSBmbGFnKHRoaXMsICdzc2ZpJylcbiAgICAgICwgaXNEZWVwID0gZmxhZyh0aGlzLCAnZGVlcCcpXG4gICAgICAsIGRlc2NyaXB0b3IgPSBpc0RlZXAgPyAnZGVlcCAnIDogJyc7XG5cbiAgICBmbGFnTXNnID0gZmxhZ01zZyA/IGZsYWdNc2cgKyAnOiAnIDogJyc7XG5cbiAgICB2YXIgaW5jbHVkZWQgPSBmYWxzZTtcblxuICAgIHN3aXRjaCAob2JqVHlwZSkge1xuICAgICAgY2FzZSAnc3RyaW5nJzpcbiAgICAgICAgaW5jbHVkZWQgPSBvYmouaW5kZXhPZih2YWwpICE9PSAtMTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ3dlYWtzZXQnOlxuICAgICAgICBpZiAoaXNEZWVwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKFxuICAgICAgICAgICAgZmxhZ01zZyArICd1bmFibGUgdG8gdXNlIC5kZWVwLmluY2x1ZGUgd2l0aCBXZWFrU2V0JyxcbiAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHNzZmlcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgaW5jbHVkZWQgPSBvYmouaGFzKHZhbCk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdtYXAnOlxuICAgICAgICB2YXIgaXNFcWwgPSBpc0RlZXAgPyBfLmVxbCA6IFNhbWVWYWx1ZVplcm87XG4gICAgICAgIG9iai5mb3JFYWNoKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgaW5jbHVkZWQgPSBpbmNsdWRlZCB8fCBpc0VxbChpdGVtLCB2YWwpO1xuICAgICAgICB9KTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ3NldCc6XG4gICAgICAgIGlmIChpc0RlZXApIHtcbiAgICAgICAgICBvYmouZm9yRWFjaChmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgICAgaW5jbHVkZWQgPSBpbmNsdWRlZCB8fCBfLmVxbChpdGVtLCB2YWwpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGluY2x1ZGVkID0gb2JqLmhhcyh2YWwpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdhcnJheSc6XG4gICAgICAgIGlmIChpc0RlZXApIHtcbiAgICAgICAgICBpbmNsdWRlZCA9IG9iai5zb21lKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgICByZXR1cm4gXy5lcWwoaXRlbSwgdmFsKTtcbiAgICAgICAgICB9KVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGluY2x1ZGVkID0gb2JqLmluZGV4T2YodmFsKSAhPT0gLTE7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIC8vIFRoaXMgYmxvY2sgaXMgZm9yIGFzc2VydGluZyBhIHN1YnNldCBvZiBwcm9wZXJ0aWVzIGluIGFuIG9iamVjdC5cbiAgICAgICAgLy8gYF8uZXhwZWN0VHlwZXNgIGlzbid0IHVzZWQgaGVyZSBiZWNhdXNlIGAuaW5jbHVkZWAgc2hvdWxkIHdvcmsgd2l0aFxuICAgICAgICAvLyBvYmplY3RzIHdpdGggYSBjdXN0b20gYEBAdG9TdHJpbmdUYWdgLlxuICAgICAgICBpZiAodmFsICE9PSBPYmplY3QodmFsKSkge1xuICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihcbiAgICAgICAgICAgIGZsYWdNc2cgKyAndGhlIGdpdmVuIGNvbWJpbmF0aW9uIG9mIGFyZ3VtZW50cyAoJ1xuICAgICAgICAgICAgKyBvYmpUeXBlICsgJyBhbmQgJ1xuICAgICAgICAgICAgKyBfLnR5cGUodmFsKS50b0xvd2VyQ2FzZSgpICsgJyknXG4gICAgICAgICAgICArICcgaXMgaW52YWxpZCBmb3IgdGhpcyBhc3NlcnRpb24uICdcbiAgICAgICAgICAgICsgJ1lvdSBjYW4gdXNlIGFuIGFycmF5LCBhIG1hcCwgYW4gb2JqZWN0LCBhIHNldCwgYSBzdHJpbmcsICdcbiAgICAgICAgICAgICsgJ29yIGEgd2Vha3NldCBpbnN0ZWFkIG9mIGEgJ1xuICAgICAgICAgICAgKyBfLnR5cGUodmFsKS50b0xvd2VyQ2FzZSgpLFxuICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgc3NmaVxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcHJvcHMgPSBPYmplY3Qua2V5cyh2YWwpXG4gICAgICAgICAgLCBmaXJzdEVyciA9IG51bGxcbiAgICAgICAgICAsIG51bUVycnMgPSAwO1xuXG4gICAgICAgIHByb3BzLmZvckVhY2goZnVuY3Rpb24gKHByb3ApIHtcbiAgICAgICAgICB2YXIgcHJvcEFzc2VydGlvbiA9IG5ldyBBc3NlcnRpb24ob2JqKTtcbiAgICAgICAgICBfLnRyYW5zZmVyRmxhZ3ModGhpcywgcHJvcEFzc2VydGlvbiwgdHJ1ZSk7XG4gICAgICAgICAgZmxhZyhwcm9wQXNzZXJ0aW9uLCAnbG9ja1NzZmknLCB0cnVlKTtcblxuICAgICAgICAgIGlmICghbmVnYXRlIHx8IHByb3BzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgcHJvcEFzc2VydGlvbi5wcm9wZXJ0eShwcm9wLCB2YWxbcHJvcF0pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBwcm9wQXNzZXJ0aW9uLnByb3BlcnR5KHByb3AsIHZhbFtwcm9wXSk7XG4gICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBpZiAoIV8uY2hlY2tFcnJvci5jb21wYXRpYmxlQ29uc3RydWN0b3IoZXJyLCBBc3NlcnRpb25FcnJvcikpIHtcbiAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGZpcnN0RXJyID09PSBudWxsKSBmaXJzdEVyciA9IGVycjtcbiAgICAgICAgICAgIG51bUVycnMrKztcbiAgICAgICAgICB9XG4gICAgICAgIH0sIHRoaXMpO1xuXG4gICAgICAgIC8vIFdoZW4gdmFsaWRhdGluZyAubm90LmluY2x1ZGUgd2l0aCBtdWx0aXBsZSBwcm9wZXJ0aWVzLCB3ZSBvbmx5IHdhbnRcbiAgICAgICAgLy8gdG8gdGhyb3cgYW4gYXNzZXJ0aW9uIGVycm9yIGlmIGFsbCBvZiB0aGUgcHJvcGVydGllcyBhcmUgaW5jbHVkZWQsXG4gICAgICAgIC8vIGluIHdoaWNoIGNhc2Ugd2UgdGhyb3cgdGhlIGZpcnN0IHByb3BlcnR5IGFzc2VydGlvbiBlcnJvciB0aGF0IHdlXG4gICAgICAgIC8vIGVuY291bnRlcmVkLlxuICAgICAgICBpZiAobmVnYXRlICYmIHByb3BzLmxlbmd0aCA+IDEgJiYgbnVtRXJycyA9PT0gcHJvcHMubGVuZ3RoKSB7XG4gICAgICAgICAgdGhyb3cgZmlyc3RFcnI7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIEFzc2VydCBpbmNsdXNpb24gaW4gY29sbGVjdGlvbiBvciBzdWJzdHJpbmcgaW4gYSBzdHJpbmcuXG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICBpbmNsdWRlZFxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byAnICsgZGVzY3JpcHRvciArICdpbmNsdWRlICcgKyBfLmluc3BlY3QodmFsKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgJyArIGRlc2NyaXB0b3IgKyAnaW5jbHVkZSAnICsgXy5pbnNwZWN0KHZhbCkpO1xuICB9XG5cbiAgQXNzZXJ0aW9uLmFkZENoYWluYWJsZU1ldGhvZCgnaW5jbHVkZScsIGluY2x1ZGUsIGluY2x1ZGVDaGFpbmluZ0JlaGF2aW9yKTtcbiAgQXNzZXJ0aW9uLmFkZENoYWluYWJsZU1ldGhvZCgnY29udGFpbicsIGluY2x1ZGUsIGluY2x1ZGVDaGFpbmluZ0JlaGF2aW9yKTtcbiAgQXNzZXJ0aW9uLmFkZENoYWluYWJsZU1ldGhvZCgnY29udGFpbnMnLCBpbmNsdWRlLCBpbmNsdWRlQ2hhaW5pbmdCZWhhdmlvcik7XG4gIEFzc2VydGlvbi5hZGRDaGFpbmFibGVNZXRob2QoJ2luY2x1ZGVzJywgaW5jbHVkZSwgaW5jbHVkZUNoYWluaW5nQmVoYXZpb3IpO1xuXG4gIC8qKlxuICAgKiAjIyMgLm9rXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGEgdHJ1dGh5IHZhbHVlIChjb25zaWRlcmVkIGB0cnVlYCBpbiBib29sZWFuIGNvbnRleHQpLlxuICAgKiBIb3dldmVyLCBpdCdzIG9mdGVuIGJlc3QgdG8gYXNzZXJ0IHRoYXQgdGhlIHRhcmdldCBpcyBzdHJpY3RseSAoYD09PWApIG9yXG4gICAqIGRlZXBseSBlcXVhbCB0byBpdHMgZXhwZWN0ZWQgdmFsdWUuXG4gICAqXG4gICAqICAgICBleHBlY3QoMSkudG8uZXF1YWwoMSk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoMSkudG8uYmUub2s7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiAgICAgZXhwZWN0KHRydWUpLnRvLmJlLnRydWU7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QodHJ1ZSkudG8uYmUub2s7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBBZGQgYC5ub3RgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIG5lZ2F0ZSBgLm9rYC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgwKS50by5lcXVhbCgwKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCgwKS50by5ub3QuYmUub2s7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiAgICAgZXhwZWN0KGZhbHNlKS50by5iZS5mYWxzZTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdChmYWxzZSkudG8ubm90LmJlLm9rOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogICAgIGV4cGVjdChudWxsKS50by5iZS5udWxsOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KG51bGwpLnRvLm5vdC5iZS5vazsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqICAgICBleHBlY3QodW5kZWZpbmVkKS50by5iZS51bmRlZmluZWQ7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QodW5kZWZpbmVkKS50by5ub3QuYmUub2s7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBBIGN1c3RvbSBlcnJvciBtZXNzYWdlIGNhbiBiZSBnaXZlbiBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50IHRvIGBleHBlY3RgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KGZhbHNlLCAnbm9vbyB3aHkgZmFpbD8/JykudG8uYmUub2s7XG4gICAqXG4gICAqIEBuYW1lIG9rXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgnb2snLCBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICAgIGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIHRydXRoeSdcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgZmFsc3knKTtcbiAgfSk7XG5cbiAgLyoqXG4gICAqICMjIyAudHJ1ZVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBzdHJpY3RseSAoYD09PWApIGVxdWFsIHRvIGB0cnVlYC5cbiAgICpcbiAgICogICAgIGV4cGVjdCh0cnVlKS50by5iZS50cnVlO1xuICAgKlxuICAgKiBBZGQgYC5ub3RgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIG5lZ2F0ZSBgLnRydWVgLiBIb3dldmVyLCBpdCdzIG9mdGVuIGJlc3RcbiAgICogdG8gYXNzZXJ0IHRoYXQgdGhlIHRhcmdldCBpcyBlcXVhbCB0byBpdHMgZXhwZWN0ZWQgdmFsdWUsIHJhdGhlciB0aGFuIG5vdFxuICAgKiBlcXVhbCB0byBgdHJ1ZWAuXG4gICAqXG4gICAqICAgICBleHBlY3QoZmFsc2UpLnRvLmJlLmZhbHNlOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KGZhbHNlKS50by5ub3QuYmUudHJ1ZTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqICAgICBleHBlY3QoMSkudG8uZXF1YWwoMSk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoMSkudG8ubm90LmJlLnRydWU7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBBIGN1c3RvbSBlcnJvciBtZXNzYWdlIGNhbiBiZSBnaXZlbiBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50IHRvIGBleHBlY3RgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KGZhbHNlLCAnbm9vbyB3aHkgZmFpbD8/JykudG8uYmUudHJ1ZTtcbiAgICpcbiAgICogQG5hbWUgdHJ1ZVxuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBBc3NlcnRpb24uYWRkUHJvcGVydHkoJ3RydWUnLCBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICAgIHRydWUgPT09IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIHRydWUnXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIGZhbHNlJ1xuICAgICAgLCBmbGFnKHRoaXMsICduZWdhdGUnKSA/IGZhbHNlIDogdHJ1ZVxuICAgICk7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiAjIyMgLmZhbHNlXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIHN0cmljdGx5IChgPT09YCkgZXF1YWwgdG8gYGZhbHNlYC5cbiAgICpcbiAgICogICAgIGV4cGVjdChmYWxzZSkudG8uYmUuZmFsc2U7XG4gICAqXG4gICAqIEFkZCBgLm5vdGAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gbmVnYXRlIGAuZmFsc2VgLiBIb3dldmVyLCBpdCdzIG9mdGVuXG4gICAqIGJlc3QgdG8gYXNzZXJ0IHRoYXQgdGhlIHRhcmdldCBpcyBlcXVhbCB0byBpdHMgZXhwZWN0ZWQgdmFsdWUsIHJhdGhlciB0aGFuXG4gICAqIG5vdCBlcXVhbCB0byBgZmFsc2VgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KHRydWUpLnRvLmJlLnRydWU7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QodHJ1ZSkudG8ubm90LmJlLmZhbHNlOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogICAgIGV4cGVjdCgxKS50by5lcXVhbCgxKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCgxKS50by5ub3QuYmUuZmFsc2U7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBBIGN1c3RvbSBlcnJvciBtZXNzYWdlIGNhbiBiZSBnaXZlbiBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50IHRvIGBleHBlY3RgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KHRydWUsICdub29vIHdoeSBmYWlsPz8nKS50by5iZS5mYWxzZTtcbiAgICpcbiAgICogQG5hbWUgZmFsc2VcbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgQXNzZXJ0aW9uLmFkZFByb3BlcnR5KCdmYWxzZScsIGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgZmFsc2UgPT09IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIGZhbHNlJ1xuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSB0cnVlJ1xuICAgICAgLCBmbGFnKHRoaXMsICduZWdhdGUnKSA/IHRydWUgOiBmYWxzZVxuICAgICk7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiAjIyMgLm51bGxcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaXMgc3RyaWN0bHkgKGA9PT1gKSBlcXVhbCB0byBgbnVsbGAuXG4gICAqXG4gICAqICAgICBleHBlY3QobnVsbCkudG8uYmUubnVsbDtcbiAgICpcbiAgICogQWRkIGAubm90YCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byBuZWdhdGUgYC5udWxsYC4gSG93ZXZlciwgaXQncyBvZnRlbiBiZXN0XG4gICAqIHRvIGFzc2VydCB0aGF0IHRoZSB0YXJnZXQgaXMgZXF1YWwgdG8gaXRzIGV4cGVjdGVkIHZhbHVlLCByYXRoZXIgdGhhbiBub3RcbiAgICogZXF1YWwgdG8gYG51bGxgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KDEpLnRvLmVxdWFsKDEpOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KDEpLnRvLm5vdC5iZS5udWxsOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogQSBjdXN0b20gZXJyb3IgbWVzc2FnZSBjYW4gYmUgZ2l2ZW4gYXMgdGhlIHNlY29uZCBhcmd1bWVudCB0byBgZXhwZWN0YC5cbiAgICpcbiAgICogICAgIGV4cGVjdCg0MiwgJ25vb28gd2h5IGZhaWw/PycpLnRvLmJlLm51bGw7XG4gICAqXG4gICAqIEBuYW1lIG51bGxcbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgQXNzZXJ0aW9uLmFkZFByb3BlcnR5KCdudWxsJywgZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICBudWxsID09PSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBudWxsJ1xuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSBub3QgdG8gYmUgbnVsbCdcbiAgICApO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC51bmRlZmluZWRcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaXMgc3RyaWN0bHkgKGA9PT1gKSBlcXVhbCB0byBgdW5kZWZpbmVkYC5cbiAgICpcbiAgICogICAgIGV4cGVjdCh1bmRlZmluZWQpLnRvLmJlLnVuZGVmaW5lZDtcbiAgICpcbiAgICogQWRkIGAubm90YCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byBuZWdhdGUgYC51bmRlZmluZWRgLiBIb3dldmVyLCBpdCdzIG9mdGVuXG4gICAqIGJlc3QgdG8gYXNzZXJ0IHRoYXQgdGhlIHRhcmdldCBpcyBlcXVhbCB0byBpdHMgZXhwZWN0ZWQgdmFsdWUsIHJhdGhlciB0aGFuXG4gICAqIG5vdCBlcXVhbCB0byBgdW5kZWZpbmVkYC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgxKS50by5lcXVhbCgxKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCgxKS50by5ub3QuYmUudW5kZWZpbmVkOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogQSBjdXN0b20gZXJyb3IgbWVzc2FnZSBjYW4gYmUgZ2l2ZW4gYXMgdGhlIHNlY29uZCBhcmd1bWVudCB0byBgZXhwZWN0YC5cbiAgICpcbiAgICogICAgIGV4cGVjdCg0MiwgJ25vb28gd2h5IGZhaWw/PycpLnRvLmJlLnVuZGVmaW5lZDtcbiAgICpcbiAgICogQG5hbWUgdW5kZWZpbmVkXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgndW5kZWZpbmVkJywgZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICB1bmRlZmluZWQgPT09IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIHVuZGVmaW5lZCdcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gbm90IHRvIGJlIHVuZGVmaW5lZCdcbiAgICApO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC5OYU5cbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaXMgZXhhY3RseSBgTmFOYC5cbiAgICpcbiAgICogICAgIGV4cGVjdChOYU4pLnRvLmJlLk5hTjtcbiAgICpcbiAgICogQWRkIGAubm90YCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byBuZWdhdGUgYC5OYU5gLiBIb3dldmVyLCBpdCdzIG9mdGVuIGJlc3RcbiAgICogdG8gYXNzZXJ0IHRoYXQgdGhlIHRhcmdldCBpcyBlcXVhbCB0byBpdHMgZXhwZWN0ZWQgdmFsdWUsIHJhdGhlciB0aGFuIG5vdFxuICAgKiBlcXVhbCB0byBgTmFOYC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgnZm9vJykudG8uZXF1YWwoJ2ZvbycpOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KCdmb28nKS50by5ub3QuYmUuTmFOOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogQSBjdXN0b20gZXJyb3IgbWVzc2FnZSBjYW4gYmUgZ2l2ZW4gYXMgdGhlIHNlY29uZCBhcmd1bWVudCB0byBgZXhwZWN0YC5cbiAgICpcbiAgICogICAgIGV4cGVjdCg0MiwgJ25vb28gd2h5IGZhaWw/PycpLnRvLmJlLk5hTjtcbiAgICpcbiAgICogQG5hbWUgTmFOXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgnTmFOJywgZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICBfLmlzTmFOKGZsYWcodGhpcywgJ29iamVjdCcpKVxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIE5hTidcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSBub3QgdG8gYmUgTmFOJ1xuICAgICk7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiAjIyMgLmV4aXN0XG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIG5vdCBzdHJpY3RseSAoYD09PWApIGVxdWFsIHRvIGVpdGhlciBgbnVsbGAgb3JcbiAgICogYHVuZGVmaW5lZGAuIEhvd2V2ZXIsIGl0J3Mgb2Z0ZW4gYmVzdCB0byBhc3NlcnQgdGhhdCB0aGUgdGFyZ2V0IGlzIGVxdWFsIHRvXG4gICAqIGl0cyBleHBlY3RlZCB2YWx1ZS5cbiAgICpcbiAgICogICAgIGV4cGVjdCgxKS50by5lcXVhbCgxKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCgxKS50by5leGlzdDsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqICAgICBleHBlY3QoMCkudG8uZXF1YWwoMCk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoMCkudG8uZXhpc3Q7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBBZGQgYC5ub3RgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIG5lZ2F0ZSBgLmV4aXN0YC5cbiAgICpcbiAgICogICAgIGV4cGVjdChudWxsKS50by5iZS5udWxsOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KG51bGwpLnRvLm5vdC5leGlzdDsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqICAgICBleHBlY3QodW5kZWZpbmVkKS50by5iZS51bmRlZmluZWQ7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QodW5kZWZpbmVkKS50by5ub3QuZXhpc3Q7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBBIGN1c3RvbSBlcnJvciBtZXNzYWdlIGNhbiBiZSBnaXZlbiBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50IHRvIGBleHBlY3RgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KG51bGwsICdub29vIHdoeSBmYWlsPz8nKS50by5leGlzdDtcbiAgICpcbiAgICogVGhlIGFsaWFzIGAuZXhpc3RzYCBjYW4gYmUgdXNlZCBpbnRlcmNoYW5nZWFibHkgd2l0aCBgLmV4aXN0YC5cbiAgICpcbiAgICogQG5hbWUgZXhpc3RcbiAgICogQGFsaWFzIGV4aXN0c1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBhc3NlcnRFeGlzdCAoKSB7XG4gICAgdmFyIHZhbCA9IGZsYWcodGhpcywgJ29iamVjdCcpO1xuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICB2YWwgIT09IG51bGwgJiYgdmFsICE9PSB1bmRlZmluZWRcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gZXhpc3QnXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBleGlzdCdcbiAgICApO1xuICB9XG5cbiAgQXNzZXJ0aW9uLmFkZFByb3BlcnR5KCdleGlzdCcsIGFzc2VydEV4aXN0KTtcbiAgQXNzZXJ0aW9uLmFkZFByb3BlcnR5KCdleGlzdHMnLCBhc3NlcnRFeGlzdCk7XG5cbiAgLyoqXG4gICAqICMjIyAuZW1wdHlcbiAgICpcbiAgICogV2hlbiB0aGUgdGFyZ2V0IGlzIGEgc3RyaW5nIG9yIGFycmF5LCBgLmVtcHR5YCBhc3NlcnRzIHRoYXQgdGhlIHRhcmdldCdzXG4gICAqIGBsZW5ndGhgIHByb3BlcnR5IGlzIHN0cmljdGx5IChgPT09YCkgZXF1YWwgdG8gYDBgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KFtdKS50by5iZS5lbXB0eTtcbiAgICogICAgIGV4cGVjdCgnJykudG8uYmUuZW1wdHk7XG4gICAqXG4gICAqIFdoZW4gdGhlIHRhcmdldCBpcyBhIG1hcCBvciBzZXQsIGAuZW1wdHlgIGFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0J3MgYHNpemVgXG4gICAqIHByb3BlcnR5IGlzIHN0cmljdGx5IGVxdWFsIHRvIGAwYC5cbiAgICpcbiAgICogICAgIGV4cGVjdChuZXcgU2V0KCkpLnRvLmJlLmVtcHR5O1xuICAgKiAgICAgZXhwZWN0KG5ldyBNYXAoKSkudG8uYmUuZW1wdHk7XG4gICAqXG4gICAqIFdoZW4gdGhlIHRhcmdldCBpcyBhIG5vbi1mdW5jdGlvbiBvYmplY3QsIGAuZW1wdHlgIGFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0XG4gICAqIGRvZXNuJ3QgaGF2ZSBhbnkgb3duIGVudW1lcmFibGUgcHJvcGVydGllcy4gUHJvcGVydGllcyB3aXRoIFN5bWJvbC1iYXNlZFxuICAgKiBrZXlzIGFyZSBleGNsdWRlZCBmcm9tIHRoZSBjb3VudC5cbiAgICpcbiAgICogICAgIGV4cGVjdCh7fSkudG8uYmUuZW1wdHk7XG4gICAqXG4gICAqIEJlY2F1c2UgYC5lbXB0eWAgZG9lcyBkaWZmZXJlbnQgdGhpbmdzIGJhc2VkIG9uIHRoZSB0YXJnZXQncyB0eXBlLCBpdCdzXG4gICAqIGltcG9ydGFudCB0byBjaGVjayB0aGUgdGFyZ2V0J3MgdHlwZSBiZWZvcmUgdXNpbmcgYC5lbXB0eWAuIFNlZSB0aGUgYC5hYFxuICAgKiBkb2MgZm9yIGluZm8gb24gdGVzdGluZyBhIHRhcmdldCdzIHR5cGUuXG4gICAqXG4gICAqICAgICBleHBlY3QoW10pLnRvLmJlLmFuKCdhcnJheScpLnRoYXQuaXMuZW1wdHk7XG4gICAqXG4gICAqIEFkZCBgLm5vdGAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gbmVnYXRlIGAuZW1wdHlgLiBIb3dldmVyLCBpdCdzIG9mdGVuXG4gICAqIGJlc3QgdG8gYXNzZXJ0IHRoYXQgdGhlIHRhcmdldCBjb250YWlucyBpdHMgZXhwZWN0ZWQgbnVtYmVyIG9mIHZhbHVlcyxcbiAgICogcmF0aGVyIHRoYW4gYXNzZXJ0aW5nIHRoYXQgaXQncyBub3QgZW1wdHkuXG4gICAqXG4gICAqICAgICBleHBlY3QoWzEsIDIsIDNdKS50by5oYXZlLmxlbmd0aE9mKDMpOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KFsxLCAyLCAzXSkudG8ubm90LmJlLmVtcHR5OyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogICAgIGV4cGVjdChuZXcgU2V0KFsxLCAyLCAzXSkpLnRvLmhhdmUucHJvcGVydHkoJ3NpemUnLCAzKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdChuZXcgU2V0KFsxLCAyLCAzXSkpLnRvLm5vdC5iZS5lbXB0eTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqICAgICBleHBlY3QoT2JqZWN0LmtleXMoe2E6IDF9KSkudG8uaGF2ZS5sZW5ndGhPZigxKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCh7YTogMX0pLnRvLm5vdC5iZS5lbXB0eTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqIEEgY3VzdG9tIGVycm9yIG1lc3NhZ2UgY2FuIGJlIGdpdmVuIGFzIHRoZSBzZWNvbmQgYXJndW1lbnQgdG8gYGV4cGVjdGAuXG4gICAqXG4gICAqICAgICBleHBlY3QoWzEsIDIsIDNdLCAnbm9vbyB3aHkgZmFpbD8/JykudG8uYmUuZW1wdHk7XG4gICAqXG4gICAqIEBuYW1lIGVtcHR5XG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgnZW1wdHknLCBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHZhbCA9IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAsIHNzZmkgPSBmbGFnKHRoaXMsICdzc2ZpJylcbiAgICAgICwgZmxhZ01zZyA9IGZsYWcodGhpcywgJ21lc3NhZ2UnKVxuICAgICAgLCBpdGVtc0NvdW50O1xuXG4gICAgZmxhZ01zZyA9IGZsYWdNc2cgPyBmbGFnTXNnICsgJzogJyA6ICcnO1xuXG4gICAgc3dpdGNoIChfLnR5cGUodmFsKS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICBjYXNlICdhcnJheSc6XG4gICAgICBjYXNlICdzdHJpbmcnOlxuICAgICAgICBpdGVtc0NvdW50ID0gdmFsLmxlbmd0aDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdtYXAnOlxuICAgICAgY2FzZSAnc2V0JzpcbiAgICAgICAgaXRlbXNDb3VudCA9IHZhbC5zaXplO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3dlYWttYXAnOlxuICAgICAgY2FzZSAnd2Vha3NldCc6XG4gICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihcbiAgICAgICAgICBmbGFnTXNnICsgJy5lbXB0eSB3YXMgcGFzc2VkIGEgd2VhayBjb2xsZWN0aW9uJyxcbiAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgc3NmaVxuICAgICAgICApO1xuICAgICAgY2FzZSAnZnVuY3Rpb24nOlxuICAgICAgICB2YXIgbXNnID0gZmxhZ01zZyArICcuZW1wdHkgd2FzIHBhc3NlZCBhIGZ1bmN0aW9uICcgKyBfLmdldE5hbWUodmFsKTtcbiAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKG1zZy50cmltKCksIHVuZGVmaW5lZCwgc3NmaSk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAodmFsICE9PSBPYmplY3QodmFsKSkge1xuICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihcbiAgICAgICAgICAgIGZsYWdNc2cgKyAnLmVtcHR5IHdhcyBwYXNzZWQgbm9uLXN0cmluZyBwcmltaXRpdmUgJyArIF8uaW5zcGVjdCh2YWwpLFxuICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgc3NmaVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgaXRlbXNDb3VudCA9IE9iamVjdC5rZXlzKHZhbCkubGVuZ3RoO1xuICAgIH1cblxuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAwID09PSBpdGVtc0NvdW50XG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIGVtcHR5J1xuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSBub3QgdG8gYmUgZW1wdHknXG4gICAgKTtcbiAgfSk7XG5cbiAgLyoqXG4gICAqICMjIyAuYXJndW1lbnRzXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGFuIGBhcmd1bWVudHNgIG9iamVjdC5cbiAgICpcbiAgICogICAgIGZ1bmN0aW9uIHRlc3QgKCkge1xuICAgKiAgICAgICBleHBlY3QoYXJndW1lbnRzKS50by5iZS5hcmd1bWVudHM7XG4gICAqICAgICB9XG4gICAqXG4gICAqICAgICB0ZXN0KCk7XG4gICAqXG4gICAqIEFkZCBgLm5vdGAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gbmVnYXRlIGAuYXJndW1lbnRzYC4gSG93ZXZlciwgaXQncyBvZnRlblxuICAgKiBiZXN0IHRvIGFzc2VydCB3aGljaCB0eXBlIHRoZSB0YXJnZXQgaXMgZXhwZWN0ZWQgdG8gYmUsIHJhdGhlciB0aGFuXG4gICAqIGFzc2VydGluZyB0aGF0IGl0XHUyMDE5cyBub3QgYW4gYGFyZ3VtZW50c2Agb2JqZWN0LlxuICAgKlxuICAgKiAgICAgZXhwZWN0KCdmb28nKS50by5iZS5hKCdzdHJpbmcnKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCgnZm9vJykudG8ubm90LmJlLmFyZ3VtZW50czsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqIEEgY3VzdG9tIGVycm9yIG1lc3NhZ2UgY2FuIGJlIGdpdmVuIGFzIHRoZSBzZWNvbmQgYXJndW1lbnQgdG8gYGV4cGVjdGAuXG4gICAqXG4gICAqICAgICBleHBlY3Qoe30sICdub29vIHdoeSBmYWlsPz8nKS50by5iZS5hcmd1bWVudHM7XG4gICAqXG4gICAqIFRoZSBhbGlhcyBgLkFyZ3VtZW50c2AgY2FuIGJlIHVzZWQgaW50ZXJjaGFuZ2VhYmx5IHdpdGggYC5hcmd1bWVudHNgLlxuICAgKlxuICAgKiBAbmFtZSBhcmd1bWVudHNcbiAgICogQGFsaWFzIEFyZ3VtZW50c1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBjaGVja0FyZ3VtZW50cyAoKSB7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAsIHR5cGUgPSBfLnR5cGUob2JqKTtcbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgJ0FyZ3VtZW50cycgPT09IHR5cGVcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgYXJndW1lbnRzIGJ1dCBnb3QgJyArIHR5cGVcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGJlIGFyZ3VtZW50cydcbiAgICApO1xuICB9XG5cbiAgQXNzZXJ0aW9uLmFkZFByb3BlcnR5KCdhcmd1bWVudHMnLCBjaGVja0FyZ3VtZW50cyk7XG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgnQXJndW1lbnRzJywgY2hlY2tBcmd1bWVudHMpO1xuXG4gIC8qKlxuICAgKiAjIyMgLmVxdWFsKHZhbFssIG1zZ10pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIHN0cmljdGx5IChgPT09YCkgZXF1YWwgdG8gdGhlIGdpdmVuIGB2YWxgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KDEpLnRvLmVxdWFsKDEpO1xuICAgKiAgICAgZXhwZWN0KCdmb28nKS50by5lcXVhbCgnZm9vJyk7XG4gICAqXG4gICAqIEFkZCBgLmRlZXBgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIHVzZSBkZWVwIGVxdWFsaXR5IGluc3RlYWQuIFNlZSB0aGVcbiAgICogYGRlZXAtZXFsYCBwcm9qZWN0IHBhZ2UgZm9yIGluZm8gb24gdGhlIGRlZXAgZXF1YWxpdHkgYWxnb3JpdGhtOlxuICAgKiBodHRwczovL2dpdGh1Yi5jb20vY2hhaWpzL2RlZXAtZXFsLlxuICAgKlxuICAgKiAgICAgLy8gVGFyZ2V0IG9iamVjdCBkZWVwbHkgKGJ1dCBub3Qgc3RyaWN0bHkpIGVxdWFscyBge2E6IDF9YFxuICAgKiAgICAgZXhwZWN0KHthOiAxfSkudG8uZGVlcC5lcXVhbCh7YTogMX0pO1xuICAgKiAgICAgZXhwZWN0KHthOiAxfSkudG8ubm90LmVxdWFsKHthOiAxfSk7XG4gICAqXG4gICAqICAgICAvLyBUYXJnZXQgYXJyYXkgZGVlcGx5IChidXQgbm90IHN0cmljdGx5KSBlcXVhbHMgYFsxLCAyXWBcbiAgICogICAgIGV4cGVjdChbMSwgMl0pLnRvLmRlZXAuZXF1YWwoWzEsIDJdKTtcbiAgICogICAgIGV4cGVjdChbMSwgMl0pLnRvLm5vdC5lcXVhbChbMSwgMl0pO1xuICAgKlxuICAgKiBBZGQgYC5ub3RgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIG5lZ2F0ZSBgLmVxdWFsYC4gSG93ZXZlciwgaXQncyBvZnRlblxuICAgKiBiZXN0IHRvIGFzc2VydCB0aGF0IHRoZSB0YXJnZXQgaXMgZXF1YWwgdG8gaXRzIGV4cGVjdGVkIHZhbHVlLCByYXRoZXIgdGhhblxuICAgKiBub3QgZXF1YWwgdG8gb25lIG9mIGNvdW50bGVzcyB1bmV4cGVjdGVkIHZhbHVlcy5cbiAgICpcbiAgICogICAgIGV4cGVjdCgxKS50by5lcXVhbCgxKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCgxKS50by5ub3QuZXF1YWwoMik7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBgLmVxdWFsYCBhY2NlcHRzIGFuIG9wdGlvbmFsIGBtc2dgIGFyZ3VtZW50IHdoaWNoIGlzIGEgY3VzdG9tIGVycm9yIG1lc3NhZ2VcbiAgICogdG8gc2hvdyB3aGVuIHRoZSBhc3NlcnRpb24gZmFpbHMuIFRoZSBtZXNzYWdlIGNhbiBhbHNvIGJlIGdpdmVuIGFzIHRoZVxuICAgKiBzZWNvbmQgYXJndW1lbnQgdG8gYGV4cGVjdGAuXG4gICAqXG4gICAqICAgICBleHBlY3QoMSkudG8uZXF1YWwoMiwgJ25vb28gd2h5IGZhaWw/PycpO1xuICAgKiAgICAgZXhwZWN0KDEsICdub29vIHdoeSBmYWlsPz8nKS50by5lcXVhbCgyKTtcbiAgICpcbiAgICogVGhlIGFsaWFzZXMgYC5lcXVhbHNgIGFuZCBgZXFgIGNhbiBiZSB1c2VkIGludGVyY2hhbmdlYWJseSB3aXRoIGAuZXF1YWxgLlxuICAgKlxuICAgKiBAbmFtZSBlcXVhbFxuICAgKiBAYWxpYXMgZXF1YWxzXG4gICAqIEBhbGlhcyBlcVxuICAgKiBAcGFyYW0ge01peGVkfSB2YWxcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1zZyBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGFzc2VydEVxdWFsICh2YWwsIG1zZykge1xuICAgIGlmIChtc2cpIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKTtcbiAgICBpZiAoZmxhZyh0aGlzLCAnZGVlcCcpKSB7XG4gICAgICB2YXIgcHJldkxvY2tTc2ZpID0gZmxhZyh0aGlzLCAnbG9ja1NzZmknKTtcbiAgICAgIGZsYWcodGhpcywgJ2xvY2tTc2ZpJywgdHJ1ZSk7XG4gICAgICB0aGlzLmVxbCh2YWwpO1xuICAgICAgZmxhZyh0aGlzLCAnbG9ja1NzZmknLCBwcmV2TG9ja1NzZmkpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICB2YWwgPT09IG9ialxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGVxdWFsICN7ZXhwfSdcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgZXF1YWwgI3tleHB9J1xuICAgICAgICAsIHZhbFxuICAgICAgICAsIHRoaXMuX29ialxuICAgICAgICAsIHRydWVcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnZXF1YWwnLCBhc3NlcnRFcXVhbCk7XG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2VxdWFscycsIGFzc2VydEVxdWFsKTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnZXEnLCBhc3NlcnRFcXVhbCk7XG5cbiAgLyoqXG4gICAqICMjIyAuZXFsKG9ialssIG1zZ10pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGRlZXBseSBlcXVhbCB0byB0aGUgZ2l2ZW4gYG9iamAuIFNlZSB0aGVcbiAgICogYGRlZXAtZXFsYCBwcm9qZWN0IHBhZ2UgZm9yIGluZm8gb24gdGhlIGRlZXAgZXF1YWxpdHkgYWxnb3JpdGhtOlxuICAgKiBodHRwczovL2dpdGh1Yi5jb20vY2hhaWpzL2RlZXAtZXFsLlxuICAgKlxuICAgKiAgICAgLy8gVGFyZ2V0IG9iamVjdCBpcyBkZWVwbHkgKGJ1dCBub3Qgc3RyaWN0bHkpIGVxdWFsIHRvIHthOiAxfVxuICAgKiAgICAgZXhwZWN0KHthOiAxfSkudG8uZXFsKHthOiAxfSkuYnV0Lm5vdC5lcXVhbCh7YTogMX0pO1xuICAgKlxuICAgKiAgICAgLy8gVGFyZ2V0IGFycmF5IGlzIGRlZXBseSAoYnV0IG5vdCBzdHJpY3RseSkgZXF1YWwgdG8gWzEsIDJdXG4gICAqICAgICBleHBlY3QoWzEsIDJdKS50by5lcWwoWzEsIDJdKS5idXQubm90LmVxdWFsKFsxLCAyXSk7XG4gICAqXG4gICAqIEFkZCBgLm5vdGAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gbmVnYXRlIGAuZXFsYC4gSG93ZXZlciwgaXQncyBvZnRlbiBiZXN0XG4gICAqIHRvIGFzc2VydCB0aGF0IHRoZSB0YXJnZXQgaXMgZGVlcGx5IGVxdWFsIHRvIGl0cyBleHBlY3RlZCB2YWx1ZSwgcmF0aGVyXG4gICAqIHRoYW4gbm90IGRlZXBseSBlcXVhbCB0byBvbmUgb2YgY291bnRsZXNzIHVuZXhwZWN0ZWQgdmFsdWVzLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KHthOiAxfSkudG8uZXFsKHthOiAxfSk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3Qoe2E6IDF9KS50by5ub3QuZXFsKHtiOiAyfSk7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBgLmVxbGAgYWNjZXB0cyBhbiBvcHRpb25hbCBgbXNnYCBhcmd1bWVudCB3aGljaCBpcyBhIGN1c3RvbSBlcnJvciBtZXNzYWdlXG4gICAqIHRvIHNob3cgd2hlbiB0aGUgYXNzZXJ0aW9uIGZhaWxzLiBUaGUgbWVzc2FnZSBjYW4gYWxzbyBiZSBnaXZlbiBhcyB0aGVcbiAgICogc2Vjb25kIGFyZ3VtZW50IHRvIGBleHBlY3RgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KHthOiAxfSkudG8uZXFsKHtiOiAyfSwgJ25vb28gd2h5IGZhaWw/PycpO1xuICAgKiAgICAgZXhwZWN0KHthOiAxfSwgJ25vb28gd2h5IGZhaWw/PycpLnRvLmVxbCh7YjogMn0pO1xuICAgKlxuICAgKiBUaGUgYWxpYXMgYC5lcWxzYCBjYW4gYmUgdXNlZCBpbnRlcmNoYW5nZWFibHkgd2l0aCBgLmVxbGAuXG4gICAqXG4gICAqIFRoZSBgLmRlZXAuZXF1YWxgIGFzc2VydGlvbiBpcyBhbG1vc3QgaWRlbnRpY2FsIHRvIGAuZXFsYCBidXQgd2l0aCBvbmVcbiAgICogZGlmZmVyZW5jZTogYC5kZWVwLmVxdWFsYCBjYXVzZXMgZGVlcCBlcXVhbGl0eSBjb21wYXJpc29ucyB0byBhbHNvIGJlIHVzZWRcbiAgICogZm9yIGFueSBvdGhlciBhc3NlcnRpb25zIHRoYXQgZm9sbG93IGluIHRoZSBjaGFpbi5cbiAgICpcbiAgICogQG5hbWUgZXFsXG4gICAqIEBhbGlhcyBlcWxzXG4gICAqIEBwYXJhbSB7TWl4ZWR9IG9ialxuICAgKiBAcGFyYW0ge1N0cmluZ30gbXNnIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gYXNzZXJ0RXFsKG9iaiwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICAgIF8uZXFsKG9iaiwgZmxhZyh0aGlzLCAnb2JqZWN0JykpXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGRlZXBseSBlcXVhbCAje2V4cH0nXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBkZWVwbHkgZXF1YWwgI3tleHB9J1xuICAgICAgLCBvYmpcbiAgICAgICwgdGhpcy5fb2JqXG4gICAgICAsIHRydWVcbiAgICApO1xuICB9XG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnZXFsJywgYXNzZXJ0RXFsKTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnZXFscycsIGFzc2VydEVxbCk7XG5cbiAgLyoqXG4gICAqICMjIyAuYWJvdmUoblssIG1zZ10pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGEgbnVtYmVyIG9yIGEgZGF0ZSBncmVhdGVyIHRoYW4gdGhlIGdpdmVuIG51bWJlciBvciBkYXRlIGBuYCByZXNwZWN0aXZlbHkuXG4gICAqIEhvd2V2ZXIsIGl0J3Mgb2Z0ZW4gYmVzdCB0byBhc3NlcnQgdGhhdCB0aGUgdGFyZ2V0IGlzIGVxdWFsIHRvIGl0cyBleHBlY3RlZFxuICAgKiB2YWx1ZS5cbiAgICpcbiAgICogICAgIGV4cGVjdCgyKS50by5lcXVhbCgyKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCgyKS50by5iZS5hYm92ZSgxKTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqIEFkZCBgLmxlbmd0aE9mYCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byBhc3NlcnQgdGhhdCB0aGUgdGFyZ2V0J3MgYGxlbmd0aGBcbiAgICogb3IgYHNpemVgIGlzIGdyZWF0ZXIgdGhhbiB0aGUgZ2l2ZW4gbnVtYmVyIGBuYC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgnZm9vJykudG8uaGF2ZS5sZW5ndGhPZigzKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCgnZm9vJykudG8uaGF2ZS5sZW5ndGhPZi5hYm92ZSgyKTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqICAgICBleHBlY3QoWzEsIDIsIDNdKS50by5oYXZlLmxlbmd0aE9mKDMpOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KFsxLCAyLCAzXSkudG8uaGF2ZS5sZW5ndGhPZi5hYm92ZSgyKTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqIEFkZCBgLm5vdGAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gbmVnYXRlIGAuYWJvdmVgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KDIpLnRvLmVxdWFsKDIpOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KDEpLnRvLm5vdC5iZS5hYm92ZSgyKTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqIGAuYWJvdmVgIGFjY2VwdHMgYW4gb3B0aW9uYWwgYG1zZ2AgYXJndW1lbnQgd2hpY2ggaXMgYSBjdXN0b20gZXJyb3IgbWVzc2FnZVxuICAgKiB0byBzaG93IHdoZW4gdGhlIGFzc2VydGlvbiBmYWlscy4gVGhlIG1lc3NhZ2UgY2FuIGFsc28gYmUgZ2l2ZW4gYXMgdGhlXG4gICAqIHNlY29uZCBhcmd1bWVudCB0byBgZXhwZWN0YC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgxKS50by5iZS5hYm92ZSgyLCAnbm9vbyB3aHkgZmFpbD8/Jyk7XG4gICAqICAgICBleHBlY3QoMSwgJ25vb28gd2h5IGZhaWw/PycpLnRvLmJlLmFib3ZlKDIpO1xuICAgKlxuICAgKiBUaGUgYWxpYXNlcyBgLmd0YCBhbmQgYC5ncmVhdGVyVGhhbmAgY2FuIGJlIHVzZWQgaW50ZXJjaGFuZ2VhYmx5IHdpdGhcbiAgICogYC5hYm92ZWAuXG4gICAqXG4gICAqIEBuYW1lIGFib3ZlXG4gICAqIEBhbGlhcyBndFxuICAgKiBAYWxpYXMgZ3JlYXRlclRoYW5cbiAgICogQHBhcmFtIHtOdW1iZXJ9IG5cbiAgICogQHBhcmFtIHtTdHJpbmd9IG1zZyBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGFzc2VydEFib3ZlIChuLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0JylcbiAgICAgICwgZG9MZW5ndGggPSBmbGFnKHRoaXMsICdkb0xlbmd0aCcpXG4gICAgICAsIGZsYWdNc2cgPSBmbGFnKHRoaXMsICdtZXNzYWdlJylcbiAgICAgICwgbXNnUHJlZml4ID0gKChmbGFnTXNnKSA/IGZsYWdNc2cgKyAnOiAnIDogJycpXG4gICAgICAsIHNzZmkgPSBmbGFnKHRoaXMsICdzc2ZpJylcbiAgICAgICwgb2JqVHlwZSA9IF8udHlwZShvYmopLnRvTG93ZXJDYXNlKClcbiAgICAgICwgblR5cGUgPSBfLnR5cGUobikudG9Mb3dlckNhc2UoKVxuICAgICAgLCBlcnJvck1lc3NhZ2VcbiAgICAgICwgc2hvdWxkVGhyb3cgPSB0cnVlO1xuXG4gICAgaWYgKGRvTGVuZ3RoICYmIG9ialR5cGUgIT09ICdtYXAnICYmIG9ialR5cGUgIT09ICdzZXQnKSB7XG4gICAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgZmxhZ01zZywgc3NmaSwgdHJ1ZSkudG8uaGF2ZS5wcm9wZXJ0eSgnbGVuZ3RoJyk7XG4gICAgfVxuXG4gICAgaWYgKCFkb0xlbmd0aCAmJiAob2JqVHlwZSA9PT0gJ2RhdGUnICYmIG5UeXBlICE9PSAnZGF0ZScpKSB7XG4gICAgICBlcnJvck1lc3NhZ2UgPSBtc2dQcmVmaXggKyAndGhlIGFyZ3VtZW50IHRvIGFib3ZlIG11c3QgYmUgYSBkYXRlJztcbiAgICB9IGVsc2UgaWYgKG5UeXBlICE9PSAnbnVtYmVyJyAmJiAoZG9MZW5ndGggfHwgb2JqVHlwZSA9PT0gJ251bWJlcicpKSB7XG4gICAgICBlcnJvck1lc3NhZ2UgPSBtc2dQcmVmaXggKyAndGhlIGFyZ3VtZW50IHRvIGFib3ZlIG11c3QgYmUgYSBudW1iZXInO1xuICAgIH0gZWxzZSBpZiAoIWRvTGVuZ3RoICYmIChvYmpUeXBlICE9PSAnZGF0ZScgJiYgb2JqVHlwZSAhPT0gJ251bWJlcicpKSB7XG4gICAgICB2YXIgcHJpbnRPYmogPSAob2JqVHlwZSA9PT0gJ3N0cmluZycpID8gXCInXCIgKyBvYmogKyBcIidcIiA6IG9iajtcbiAgICAgIGVycm9yTWVzc2FnZSA9IG1zZ1ByZWZpeCArICdleHBlY3RlZCAnICsgcHJpbnRPYmogKyAnIHRvIGJlIGEgbnVtYmVyIG9yIGEgZGF0ZSc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNob3VsZFRocm93ID0gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKHNob3VsZFRocm93KSB7XG4gICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZXJyb3JNZXNzYWdlLCB1bmRlZmluZWQsIHNzZmkpO1xuICAgIH1cblxuICAgIGlmIChkb0xlbmd0aCkge1xuICAgICAgdmFyIGRlc2NyaXB0b3IgPSAnbGVuZ3RoJ1xuICAgICAgICAsIGl0ZW1zQ291bnQ7XG4gICAgICBpZiAob2JqVHlwZSA9PT0gJ21hcCcgfHwgb2JqVHlwZSA9PT0gJ3NldCcpIHtcbiAgICAgICAgZGVzY3JpcHRvciA9ICdzaXplJztcbiAgICAgICAgaXRlbXNDb3VudCA9IG9iai5zaXplO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaXRlbXNDb3VudCA9IG9iai5sZW5ndGg7XG4gICAgICB9XG4gICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICBpdGVtc0NvdW50ID4gblxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGhhdmUgYSAnICsgZGVzY3JpcHRvciArICcgYWJvdmUgI3tleHB9IGJ1dCBnb3QgI3thY3R9J1xuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBoYXZlIGEgJyArIGRlc2NyaXB0b3IgKyAnIGFib3ZlICN7ZXhwfSdcbiAgICAgICAgLCBuXG4gICAgICAgICwgaXRlbXNDb3VudFxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgb2JqID4gblxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIGFib3ZlICN7ZXhwfSdcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBhdCBtb3N0ICN7ZXhwfSdcbiAgICAgICAgLCBuXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2Fib3ZlJywgYXNzZXJ0QWJvdmUpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdndCcsIGFzc2VydEFib3ZlKTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnZ3JlYXRlclRoYW4nLCBhc3NlcnRBYm92ZSk7XG5cbiAgLyoqXG4gICAqICMjIyAubGVhc3QoblssIG1zZ10pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGEgbnVtYmVyIG9yIGEgZGF0ZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlIGdpdmVuXG4gICAqIG51bWJlciBvciBkYXRlIGBuYCByZXNwZWN0aXZlbHkuIEhvd2V2ZXIsIGl0J3Mgb2Z0ZW4gYmVzdCB0byBhc3NlcnQgdGhhdCB0aGUgdGFyZ2V0IGlzIGVxdWFsIHRvXG4gICAqIGl0cyBleHBlY3RlZCB2YWx1ZS5cbiAgICpcbiAgICogICAgIGV4cGVjdCgyKS50by5lcXVhbCgyKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCgyKS50by5iZS5hdC5sZWFzdCgxKTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoMikudG8uYmUuYXQubGVhc3QoMik7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBBZGQgYC5sZW5ndGhPZmAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gYXNzZXJ0IHRoYXQgdGhlIHRhcmdldCdzIGBsZW5ndGhgXG4gICAqIG9yIGBzaXplYCBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlIGdpdmVuIG51bWJlciBgbmAuXG4gICAqXG4gICAqICAgICBleHBlY3QoJ2ZvbycpLnRvLmhhdmUubGVuZ3RoT2YoMyk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoJ2ZvbycpLnRvLmhhdmUubGVuZ3RoT2YuYXQubGVhc3QoMik7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiAgICAgZXhwZWN0KFsxLCAyLCAzXSkudG8uaGF2ZS5sZW5ndGhPZigzKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdChbMSwgMiwgM10pLnRvLmhhdmUubGVuZ3RoT2YuYXQubGVhc3QoMik7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBBZGQgYC5ub3RgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIG5lZ2F0ZSBgLmxlYXN0YC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgxKS50by5lcXVhbCgxKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCgxKS50by5ub3QuYmUuYXQubGVhc3QoMik7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBgLmxlYXN0YCBhY2NlcHRzIGFuIG9wdGlvbmFsIGBtc2dgIGFyZ3VtZW50IHdoaWNoIGlzIGEgY3VzdG9tIGVycm9yIG1lc3NhZ2VcbiAgICogdG8gc2hvdyB3aGVuIHRoZSBhc3NlcnRpb24gZmFpbHMuIFRoZSBtZXNzYWdlIGNhbiBhbHNvIGJlIGdpdmVuIGFzIHRoZVxuICAgKiBzZWNvbmQgYXJndW1lbnQgdG8gYGV4cGVjdGAuXG4gICAqXG4gICAqICAgICBleHBlY3QoMSkudG8uYmUuYXQubGVhc3QoMiwgJ25vb28gd2h5IGZhaWw/PycpO1xuICAgKiAgICAgZXhwZWN0KDEsICdub29vIHdoeSBmYWlsPz8nKS50by5iZS5hdC5sZWFzdCgyKTtcbiAgICpcbiAgICogVGhlIGFsaWFzZXMgYC5ndGVgIGFuZCBgLmdyZWF0ZXJUaGFuT3JFcXVhbGAgY2FuIGJlIHVzZWQgaW50ZXJjaGFuZ2VhYmx5IHdpdGhcbiAgICogYC5sZWFzdGAuXG4gICAqXG4gICAqIEBuYW1lIGxlYXN0XG4gICAqIEBhbGlhcyBndGVcbiAgICogQGFsaWFzIGdyZWF0ZXJUaGFuT3JFcXVhbFxuICAgKiBAcGFyYW0ge051bWJlcn0gblxuICAgKiBAcGFyYW0ge1N0cmluZ30gbXNnIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gYXNzZXJ0TGVhc3QgKG4sIG1zZykge1xuICAgIGlmIChtc2cpIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCBkb0xlbmd0aCA9IGZsYWcodGhpcywgJ2RvTGVuZ3RoJylcbiAgICAgICwgZmxhZ01zZyA9IGZsYWcodGhpcywgJ21lc3NhZ2UnKVxuICAgICAgLCBtc2dQcmVmaXggPSAoKGZsYWdNc2cpID8gZmxhZ01zZyArICc6ICcgOiAnJylcbiAgICAgICwgc3NmaSA9IGZsYWcodGhpcywgJ3NzZmknKVxuICAgICAgLCBvYmpUeXBlID0gXy50eXBlKG9iaikudG9Mb3dlckNhc2UoKVxuICAgICAgLCBuVHlwZSA9IF8udHlwZShuKS50b0xvd2VyQ2FzZSgpXG4gICAgICAsIGVycm9yTWVzc2FnZVxuICAgICAgLCBzaG91bGRUaHJvdyA9IHRydWU7XG5cbiAgICBpZiAoZG9MZW5ndGggJiYgb2JqVHlwZSAhPT0gJ21hcCcgJiYgb2JqVHlwZSAhPT0gJ3NldCcpIHtcbiAgICAgIG5ldyBBc3NlcnRpb24ob2JqLCBmbGFnTXNnLCBzc2ZpLCB0cnVlKS50by5oYXZlLnByb3BlcnR5KCdsZW5ndGgnKTtcbiAgICB9XG5cbiAgICBpZiAoIWRvTGVuZ3RoICYmIChvYmpUeXBlID09PSAnZGF0ZScgJiYgblR5cGUgIT09ICdkYXRlJykpIHtcbiAgICAgIGVycm9yTWVzc2FnZSA9IG1zZ1ByZWZpeCArICd0aGUgYXJndW1lbnQgdG8gbGVhc3QgbXVzdCBiZSBhIGRhdGUnO1xuICAgIH0gZWxzZSBpZiAoblR5cGUgIT09ICdudW1iZXInICYmIChkb0xlbmd0aCB8fCBvYmpUeXBlID09PSAnbnVtYmVyJykpIHtcbiAgICAgIGVycm9yTWVzc2FnZSA9IG1zZ1ByZWZpeCArICd0aGUgYXJndW1lbnQgdG8gbGVhc3QgbXVzdCBiZSBhIG51bWJlcic7XG4gICAgfSBlbHNlIGlmICghZG9MZW5ndGggJiYgKG9ialR5cGUgIT09ICdkYXRlJyAmJiBvYmpUeXBlICE9PSAnbnVtYmVyJykpIHtcbiAgICAgIHZhciBwcmludE9iaiA9IChvYmpUeXBlID09PSAnc3RyaW5nJykgPyBcIidcIiArIG9iaiArIFwiJ1wiIDogb2JqO1xuICAgICAgZXJyb3JNZXNzYWdlID0gbXNnUHJlZml4ICsgJ2V4cGVjdGVkICcgKyBwcmludE9iaiArICcgdG8gYmUgYSBudW1iZXIgb3IgYSBkYXRlJztcbiAgICB9IGVsc2Uge1xuICAgICAgc2hvdWxkVGhyb3cgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoc2hvdWxkVGhyb3cpIHtcbiAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihlcnJvck1lc3NhZ2UsIHVuZGVmaW5lZCwgc3NmaSk7XG4gICAgfVxuXG4gICAgaWYgKGRvTGVuZ3RoKSB7XG4gICAgICB2YXIgZGVzY3JpcHRvciA9ICdsZW5ndGgnXG4gICAgICAgICwgaXRlbXNDb3VudDtcbiAgICAgIGlmIChvYmpUeXBlID09PSAnbWFwJyB8fCBvYmpUeXBlID09PSAnc2V0Jykge1xuICAgICAgICBkZXNjcmlwdG9yID0gJ3NpemUnO1xuICAgICAgICBpdGVtc0NvdW50ID0gb2JqLnNpemU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpdGVtc0NvdW50ID0gb2JqLmxlbmd0aDtcbiAgICAgIH1cbiAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgIGl0ZW1zQ291bnQgPj0gblxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGhhdmUgYSAnICsgZGVzY3JpcHRvciArICcgYXQgbGVhc3QgI3tleHB9IGJ1dCBnb3QgI3thY3R9J1xuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGhhdmUgYSAnICsgZGVzY3JpcHRvciArICcgYmVsb3cgI3tleHB9J1xuICAgICAgICAsIG5cbiAgICAgICAgLCBpdGVtc0NvdW50XG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICBvYmogPj0gblxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIGF0IGxlYXN0ICN7ZXhwfSdcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBiZWxvdyAje2V4cH0nXG4gICAgICAgICwgblxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdsZWFzdCcsIGFzc2VydExlYXN0KTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnZ3RlJywgYXNzZXJ0TGVhc3QpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdncmVhdGVyVGhhbk9yRXF1YWwnLCBhc3NlcnRMZWFzdCk7XG5cbiAgLyoqXG4gICAqICMjIyAuYmVsb3coblssIG1zZ10pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGEgbnVtYmVyIG9yIGEgZGF0ZSBsZXNzIHRoYW4gdGhlIGdpdmVuIG51bWJlciBvciBkYXRlIGBuYCByZXNwZWN0aXZlbHkuXG4gICAqIEhvd2V2ZXIsIGl0J3Mgb2Z0ZW4gYmVzdCB0byBhc3NlcnQgdGhhdCB0aGUgdGFyZ2V0IGlzIGVxdWFsIHRvIGl0cyBleHBlY3RlZFxuICAgKiB2YWx1ZS5cbiAgICpcbiAgICogICAgIGV4cGVjdCgxKS50by5lcXVhbCgxKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCgxKS50by5iZS5iZWxvdygyKTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqIEFkZCBgLmxlbmd0aE9mYCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byBhc3NlcnQgdGhhdCB0aGUgdGFyZ2V0J3MgYGxlbmd0aGBcbiAgICogb3IgYHNpemVgIGlzIGxlc3MgdGhhbiB0aGUgZ2l2ZW4gbnVtYmVyIGBuYC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgnZm9vJykudG8uaGF2ZS5sZW5ndGhPZigzKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCgnZm9vJykudG8uaGF2ZS5sZW5ndGhPZi5iZWxvdyg0KTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqICAgICBleHBlY3QoWzEsIDIsIDNdKS50by5oYXZlLmxlbmd0aCgzKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdChbMSwgMiwgM10pLnRvLmhhdmUubGVuZ3RoT2YuYmVsb3coNCk7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBBZGQgYC5ub3RgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIG5lZ2F0ZSBgLmJlbG93YC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgyKS50by5lcXVhbCgyKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCgyKS50by5ub3QuYmUuYmVsb3coMSk7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBgLmJlbG93YCBhY2NlcHRzIGFuIG9wdGlvbmFsIGBtc2dgIGFyZ3VtZW50IHdoaWNoIGlzIGEgY3VzdG9tIGVycm9yIG1lc3NhZ2VcbiAgICogdG8gc2hvdyB3aGVuIHRoZSBhc3NlcnRpb24gZmFpbHMuIFRoZSBtZXNzYWdlIGNhbiBhbHNvIGJlIGdpdmVuIGFzIHRoZVxuICAgKiBzZWNvbmQgYXJndW1lbnQgdG8gYGV4cGVjdGAuXG4gICAqXG4gICAqICAgICBleHBlY3QoMikudG8uYmUuYmVsb3coMSwgJ25vb28gd2h5IGZhaWw/PycpO1xuICAgKiAgICAgZXhwZWN0KDIsICdub29vIHdoeSBmYWlsPz8nKS50by5iZS5iZWxvdygxKTtcbiAgICpcbiAgICogVGhlIGFsaWFzZXMgYC5sdGAgYW5kIGAubGVzc1RoYW5gIGNhbiBiZSB1c2VkIGludGVyY2hhbmdlYWJseSB3aXRoXG4gICAqIGAuYmVsb3dgLlxuICAgKlxuICAgKiBAbmFtZSBiZWxvd1xuICAgKiBAYWxpYXMgbHRcbiAgICogQGFsaWFzIGxlc3NUaGFuXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtc2cgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBhc3NlcnRCZWxvdyAobiwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAsIGRvTGVuZ3RoID0gZmxhZyh0aGlzLCAnZG9MZW5ndGgnKVxuICAgICAgLCBmbGFnTXNnID0gZmxhZyh0aGlzLCAnbWVzc2FnZScpXG4gICAgICAsIG1zZ1ByZWZpeCA9ICgoZmxhZ01zZykgPyBmbGFnTXNnICsgJzogJyA6ICcnKVxuICAgICAgLCBzc2ZpID0gZmxhZyh0aGlzLCAnc3NmaScpXG4gICAgICAsIG9ialR5cGUgPSBfLnR5cGUob2JqKS50b0xvd2VyQ2FzZSgpXG4gICAgICAsIG5UeXBlID0gXy50eXBlKG4pLnRvTG93ZXJDYXNlKClcbiAgICAgICwgZXJyb3JNZXNzYWdlXG4gICAgICAsIHNob3VsZFRocm93ID0gdHJ1ZTtcblxuICAgIGlmIChkb0xlbmd0aCAmJiBvYmpUeXBlICE9PSAnbWFwJyAmJiBvYmpUeXBlICE9PSAnc2V0Jykge1xuICAgICAgbmV3IEFzc2VydGlvbihvYmosIGZsYWdNc2csIHNzZmksIHRydWUpLnRvLmhhdmUucHJvcGVydHkoJ2xlbmd0aCcpO1xuICAgIH1cblxuICAgIGlmICghZG9MZW5ndGggJiYgKG9ialR5cGUgPT09ICdkYXRlJyAmJiBuVHlwZSAhPT0gJ2RhdGUnKSkge1xuICAgICAgZXJyb3JNZXNzYWdlID0gbXNnUHJlZml4ICsgJ3RoZSBhcmd1bWVudCB0byBiZWxvdyBtdXN0IGJlIGEgZGF0ZSc7XG4gICAgfSBlbHNlIGlmIChuVHlwZSAhPT0gJ251bWJlcicgJiYgKGRvTGVuZ3RoIHx8IG9ialR5cGUgPT09ICdudW1iZXInKSkge1xuICAgICAgZXJyb3JNZXNzYWdlID0gbXNnUHJlZml4ICsgJ3RoZSBhcmd1bWVudCB0byBiZWxvdyBtdXN0IGJlIGEgbnVtYmVyJztcbiAgICB9IGVsc2UgaWYgKCFkb0xlbmd0aCAmJiAob2JqVHlwZSAhPT0gJ2RhdGUnICYmIG9ialR5cGUgIT09ICdudW1iZXInKSkge1xuICAgICAgdmFyIHByaW50T2JqID0gKG9ialR5cGUgPT09ICdzdHJpbmcnKSA/IFwiJ1wiICsgb2JqICsgXCInXCIgOiBvYmo7XG4gICAgICBlcnJvck1lc3NhZ2UgPSBtc2dQcmVmaXggKyAnZXhwZWN0ZWQgJyArIHByaW50T2JqICsgJyB0byBiZSBhIG51bWJlciBvciBhIGRhdGUnO1xuICAgIH0gZWxzZSB7XG4gICAgICBzaG91bGRUaHJvdyA9IGZhbHNlO1xuICAgIH1cblxuICAgIGlmIChzaG91bGRUaHJvdykge1xuICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKGVycm9yTWVzc2FnZSwgdW5kZWZpbmVkLCBzc2ZpKTtcbiAgICB9XG5cbiAgICBpZiAoZG9MZW5ndGgpIHtcbiAgICAgIHZhciBkZXNjcmlwdG9yID0gJ2xlbmd0aCdcbiAgICAgICAgLCBpdGVtc0NvdW50O1xuICAgICAgaWYgKG9ialR5cGUgPT09ICdtYXAnIHx8IG9ialR5cGUgPT09ICdzZXQnKSB7XG4gICAgICAgIGRlc2NyaXB0b3IgPSAnc2l6ZSc7XG4gICAgICAgIGl0ZW1zQ291bnQgPSBvYmouc2l6ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGl0ZW1zQ291bnQgPSBvYmoubGVuZ3RoO1xuICAgICAgfVxuICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgaXRlbXNDb3VudCA8IG5cbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBoYXZlIGEgJyArIGRlc2NyaXB0b3IgKyAnIGJlbG93ICN7ZXhwfSBidXQgZ290ICN7YWN0fSdcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgaGF2ZSBhICcgKyBkZXNjcmlwdG9yICsgJyBiZWxvdyAje2V4cH0nXG4gICAgICAgICwgblxuICAgICAgICAsIGl0ZW1zQ291bnRcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgIG9iaiA8IG5cbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBiZWxvdyAje2V4cH0nXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgYXQgbGVhc3QgI3tleHB9J1xuICAgICAgICAsIG5cbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnYmVsb3cnLCBhc3NlcnRCZWxvdyk7XG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2x0JywgYXNzZXJ0QmVsb3cpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdsZXNzVGhhbicsIGFzc2VydEJlbG93KTtcblxuICAvKipcbiAgICogIyMjIC5tb3N0KG5bLCBtc2ddKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBhIG51bWJlciBvciBhIGRhdGUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHRoZSBnaXZlbiBudW1iZXJcbiAgICogb3IgZGF0ZSBgbmAgcmVzcGVjdGl2ZWx5LiBIb3dldmVyLCBpdCdzIG9mdGVuIGJlc3QgdG8gYXNzZXJ0IHRoYXQgdGhlIHRhcmdldCBpcyBlcXVhbCB0byBpdHNcbiAgICogZXhwZWN0ZWQgdmFsdWUuXG4gICAqXG4gICAqICAgICBleHBlY3QoMSkudG8uZXF1YWwoMSk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoMSkudG8uYmUuYXQubW9zdCgyKTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoMSkudG8uYmUuYXQubW9zdCgxKTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqIEFkZCBgLmxlbmd0aE9mYCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byBhc3NlcnQgdGhhdCB0aGUgdGFyZ2V0J3MgYGxlbmd0aGBcbiAgICogb3IgYHNpemVgIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byB0aGUgZ2l2ZW4gbnVtYmVyIGBuYC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgnZm9vJykudG8uaGF2ZS5sZW5ndGhPZigzKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCgnZm9vJykudG8uaGF2ZS5sZW5ndGhPZi5hdC5tb3N0KDQpOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogICAgIGV4cGVjdChbMSwgMiwgM10pLnRvLmhhdmUubGVuZ3RoT2YoMyk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoWzEsIDIsIDNdKS50by5oYXZlLmxlbmd0aE9mLmF0Lm1vc3QoNCk7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBBZGQgYC5ub3RgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIG5lZ2F0ZSBgLm1vc3RgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KDIpLnRvLmVxdWFsKDIpOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KDIpLnRvLm5vdC5iZS5hdC5tb3N0KDEpOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogYC5tb3N0YCBhY2NlcHRzIGFuIG9wdGlvbmFsIGBtc2dgIGFyZ3VtZW50IHdoaWNoIGlzIGEgY3VzdG9tIGVycm9yIG1lc3NhZ2VcbiAgICogdG8gc2hvdyB3aGVuIHRoZSBhc3NlcnRpb24gZmFpbHMuIFRoZSBtZXNzYWdlIGNhbiBhbHNvIGJlIGdpdmVuIGFzIHRoZVxuICAgKiBzZWNvbmQgYXJndW1lbnQgdG8gYGV4cGVjdGAuXG4gICAqXG4gICAqICAgICBleHBlY3QoMikudG8uYmUuYXQubW9zdCgxLCAnbm9vbyB3aHkgZmFpbD8/Jyk7XG4gICAqICAgICBleHBlY3QoMiwgJ25vb28gd2h5IGZhaWw/PycpLnRvLmJlLmF0Lm1vc3QoMSk7XG4gICAqXG4gICAqIFRoZSBhbGlhc2VzIGAubHRlYCBhbmQgYC5sZXNzVGhhbk9yRXF1YWxgIGNhbiBiZSB1c2VkIGludGVyY2hhbmdlYWJseSB3aXRoXG4gICAqIGAubW9zdGAuXG4gICAqXG4gICAqIEBuYW1lIG1vc3RcbiAgICogQGFsaWFzIGx0ZVxuICAgKiBAYWxpYXMgbGVzc1RoYW5PckVxdWFsXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtc2cgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBhc3NlcnRNb3N0IChuLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0JylcbiAgICAgICwgZG9MZW5ndGggPSBmbGFnKHRoaXMsICdkb0xlbmd0aCcpXG4gICAgICAsIGZsYWdNc2cgPSBmbGFnKHRoaXMsICdtZXNzYWdlJylcbiAgICAgICwgbXNnUHJlZml4ID0gKChmbGFnTXNnKSA/IGZsYWdNc2cgKyAnOiAnIDogJycpXG4gICAgICAsIHNzZmkgPSBmbGFnKHRoaXMsICdzc2ZpJylcbiAgICAgICwgb2JqVHlwZSA9IF8udHlwZShvYmopLnRvTG93ZXJDYXNlKClcbiAgICAgICwgblR5cGUgPSBfLnR5cGUobikudG9Mb3dlckNhc2UoKVxuICAgICAgLCBlcnJvck1lc3NhZ2VcbiAgICAgICwgc2hvdWxkVGhyb3cgPSB0cnVlO1xuXG4gICAgaWYgKGRvTGVuZ3RoICYmIG9ialR5cGUgIT09ICdtYXAnICYmIG9ialR5cGUgIT09ICdzZXQnKSB7XG4gICAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgZmxhZ01zZywgc3NmaSwgdHJ1ZSkudG8uaGF2ZS5wcm9wZXJ0eSgnbGVuZ3RoJyk7XG4gICAgfVxuXG4gICAgaWYgKCFkb0xlbmd0aCAmJiAob2JqVHlwZSA9PT0gJ2RhdGUnICYmIG5UeXBlICE9PSAnZGF0ZScpKSB7XG4gICAgICBlcnJvck1lc3NhZ2UgPSBtc2dQcmVmaXggKyAndGhlIGFyZ3VtZW50IHRvIG1vc3QgbXVzdCBiZSBhIGRhdGUnO1xuICAgIH0gZWxzZSBpZiAoblR5cGUgIT09ICdudW1iZXInICYmIChkb0xlbmd0aCB8fCBvYmpUeXBlID09PSAnbnVtYmVyJykpIHtcbiAgICAgIGVycm9yTWVzc2FnZSA9IG1zZ1ByZWZpeCArICd0aGUgYXJndW1lbnQgdG8gbW9zdCBtdXN0IGJlIGEgbnVtYmVyJztcbiAgICB9IGVsc2UgaWYgKCFkb0xlbmd0aCAmJiAob2JqVHlwZSAhPT0gJ2RhdGUnICYmIG9ialR5cGUgIT09ICdudW1iZXInKSkge1xuICAgICAgdmFyIHByaW50T2JqID0gKG9ialR5cGUgPT09ICdzdHJpbmcnKSA/IFwiJ1wiICsgb2JqICsgXCInXCIgOiBvYmo7XG4gICAgICBlcnJvck1lc3NhZ2UgPSBtc2dQcmVmaXggKyAnZXhwZWN0ZWQgJyArIHByaW50T2JqICsgJyB0byBiZSBhIG51bWJlciBvciBhIGRhdGUnO1xuICAgIH0gZWxzZSB7XG4gICAgICBzaG91bGRUaHJvdyA9IGZhbHNlO1xuICAgIH1cblxuICAgIGlmIChzaG91bGRUaHJvdykge1xuICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKGVycm9yTWVzc2FnZSwgdW5kZWZpbmVkLCBzc2ZpKTtcbiAgICB9XG5cbiAgICBpZiAoZG9MZW5ndGgpIHtcbiAgICAgIHZhciBkZXNjcmlwdG9yID0gJ2xlbmd0aCdcbiAgICAgICAgLCBpdGVtc0NvdW50O1xuICAgICAgaWYgKG9ialR5cGUgPT09ICdtYXAnIHx8IG9ialR5cGUgPT09ICdzZXQnKSB7XG4gICAgICAgIGRlc2NyaXB0b3IgPSAnc2l6ZSc7XG4gICAgICAgIGl0ZW1zQ291bnQgPSBvYmouc2l6ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGl0ZW1zQ291bnQgPSBvYmoubGVuZ3RoO1xuICAgICAgfVxuICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgaXRlbXNDb3VudCA8PSBuXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gaGF2ZSBhICcgKyBkZXNjcmlwdG9yICsgJyBhdCBtb3N0ICN7ZXhwfSBidXQgZ290ICN7YWN0fSdcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBoYXZlIGEgJyArIGRlc2NyaXB0b3IgKyAnIGFib3ZlICN7ZXhwfSdcbiAgICAgICAgLCBuXG4gICAgICAgICwgaXRlbXNDb3VudFxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgb2JqIDw9IG5cbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBhdCBtb3N0ICN7ZXhwfSdcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBhYm92ZSAje2V4cH0nXG4gICAgICAgICwgblxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdtb3N0JywgYXNzZXJ0TW9zdCk7XG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2x0ZScsIGFzc2VydE1vc3QpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdsZXNzVGhhbk9yRXF1YWwnLCBhc3NlcnRNb3N0KTtcblxuICAvKipcbiAgICogIyMjIC53aXRoaW4oc3RhcnQsIGZpbmlzaFssIG1zZ10pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGEgbnVtYmVyIG9yIGEgZGF0ZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlIGdpdmVuXG4gICAqIG51bWJlciBvciBkYXRlIGBzdGFydGAsIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gdGhlIGdpdmVuIG51bWJlciBvciBkYXRlIGBmaW5pc2hgIHJlc3BlY3RpdmVseS5cbiAgICogSG93ZXZlciwgaXQncyBvZnRlbiBiZXN0IHRvIGFzc2VydCB0aGF0IHRoZSB0YXJnZXQgaXMgZXF1YWwgdG8gaXRzIGV4cGVjdGVkXG4gICAqIHZhbHVlLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KDIpLnRvLmVxdWFsKDIpOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KDIpLnRvLmJlLndpdGhpbigxLCAzKTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoMikudG8uYmUud2l0aGluKDIsIDMpOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCgyKS50by5iZS53aXRoaW4oMSwgMik7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBBZGQgYC5sZW5ndGhPZmAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gYXNzZXJ0IHRoYXQgdGhlIHRhcmdldCdzIGBsZW5ndGhgXG4gICAqIG9yIGBzaXplYCBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlIGdpdmVuIG51bWJlciBgc3RhcnRgLCBhbmQgbGVzc1xuICAgKiB0aGFuIG9yIGVxdWFsIHRvIHRoZSBnaXZlbiBudW1iZXIgYGZpbmlzaGAuXG4gICAqXG4gICAqICAgICBleHBlY3QoJ2ZvbycpLnRvLmhhdmUubGVuZ3RoT2YoMyk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoJ2ZvbycpLnRvLmhhdmUubGVuZ3RoT2Yud2l0aGluKDIsIDQpOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogICAgIGV4cGVjdChbMSwgMiwgM10pLnRvLmhhdmUubGVuZ3RoT2YoMyk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoWzEsIDIsIDNdKS50by5oYXZlLmxlbmd0aE9mLndpdGhpbigyLCA0KTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqIEFkZCBgLm5vdGAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gbmVnYXRlIGAud2l0aGluYC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgxKS50by5lcXVhbCgxKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCgxKS50by5ub3QuYmUud2l0aGluKDIsIDQpOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogYC53aXRoaW5gIGFjY2VwdHMgYW4gb3B0aW9uYWwgYG1zZ2AgYXJndW1lbnQgd2hpY2ggaXMgYSBjdXN0b20gZXJyb3JcbiAgICogbWVzc2FnZSB0byBzaG93IHdoZW4gdGhlIGFzc2VydGlvbiBmYWlscy4gVGhlIG1lc3NhZ2UgY2FuIGFsc28gYmUgZ2l2ZW4gYXNcbiAgICogdGhlIHNlY29uZCBhcmd1bWVudCB0byBgZXhwZWN0YC5cbiAgICpcbiAgICogICAgIGV4cGVjdCg0KS50by5iZS53aXRoaW4oMSwgMywgJ25vb28gd2h5IGZhaWw/PycpO1xuICAgKiAgICAgZXhwZWN0KDQsICdub29vIHdoeSBmYWlsPz8nKS50by5iZS53aXRoaW4oMSwgMyk7XG4gICAqXG4gICAqIEBuYW1lIHdpdGhpblxuICAgKiBAcGFyYW0ge051bWJlcn0gc3RhcnQgbG93ZXIgYm91bmQgaW5jbHVzaXZlXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBmaW5pc2ggdXBwZXIgYm91bmQgaW5jbHVzaXZlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtc2cgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCd3aXRoaW4nLCBmdW5jdGlvbiAoc3RhcnQsIGZpbmlzaCwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAsIGRvTGVuZ3RoID0gZmxhZyh0aGlzLCAnZG9MZW5ndGgnKVxuICAgICAgLCBmbGFnTXNnID0gZmxhZyh0aGlzLCAnbWVzc2FnZScpXG4gICAgICAsIG1zZ1ByZWZpeCA9ICgoZmxhZ01zZykgPyBmbGFnTXNnICsgJzogJyA6ICcnKVxuICAgICAgLCBzc2ZpID0gZmxhZyh0aGlzLCAnc3NmaScpXG4gICAgICAsIG9ialR5cGUgPSBfLnR5cGUob2JqKS50b0xvd2VyQ2FzZSgpXG4gICAgICAsIHN0YXJ0VHlwZSA9IF8udHlwZShzdGFydCkudG9Mb3dlckNhc2UoKVxuICAgICAgLCBmaW5pc2hUeXBlID0gXy50eXBlKGZpbmlzaCkudG9Mb3dlckNhc2UoKVxuICAgICAgLCBlcnJvck1lc3NhZ2VcbiAgICAgICwgc2hvdWxkVGhyb3cgPSB0cnVlXG4gICAgICAsIHJhbmdlID0gKHN0YXJ0VHlwZSA9PT0gJ2RhdGUnICYmIGZpbmlzaFR5cGUgPT09ICdkYXRlJylcbiAgICAgICAgICA/IHN0YXJ0LnRvSVNPU3RyaW5nKCkgKyAnLi4nICsgZmluaXNoLnRvSVNPU3RyaW5nKClcbiAgICAgICAgICA6IHN0YXJ0ICsgJy4uJyArIGZpbmlzaDtcblxuICAgIGlmIChkb0xlbmd0aCAmJiBvYmpUeXBlICE9PSAnbWFwJyAmJiBvYmpUeXBlICE9PSAnc2V0Jykge1xuICAgICAgbmV3IEFzc2VydGlvbihvYmosIGZsYWdNc2csIHNzZmksIHRydWUpLnRvLmhhdmUucHJvcGVydHkoJ2xlbmd0aCcpO1xuICAgIH1cblxuICAgIGlmICghZG9MZW5ndGggJiYgKG9ialR5cGUgPT09ICdkYXRlJyAmJiAoc3RhcnRUeXBlICE9PSAnZGF0ZScgfHwgZmluaXNoVHlwZSAhPT0gJ2RhdGUnKSkpIHtcbiAgICAgIGVycm9yTWVzc2FnZSA9IG1zZ1ByZWZpeCArICd0aGUgYXJndW1lbnRzIHRvIHdpdGhpbiBtdXN0IGJlIGRhdGVzJztcbiAgICB9IGVsc2UgaWYgKChzdGFydFR5cGUgIT09ICdudW1iZXInIHx8IGZpbmlzaFR5cGUgIT09ICdudW1iZXInKSAmJiAoZG9MZW5ndGggfHwgb2JqVHlwZSA9PT0gJ251bWJlcicpKSB7XG4gICAgICBlcnJvck1lc3NhZ2UgPSBtc2dQcmVmaXggKyAndGhlIGFyZ3VtZW50cyB0byB3aXRoaW4gbXVzdCBiZSBudW1iZXJzJztcbiAgICB9IGVsc2UgaWYgKCFkb0xlbmd0aCAmJiAob2JqVHlwZSAhPT0gJ2RhdGUnICYmIG9ialR5cGUgIT09ICdudW1iZXInKSkge1xuICAgICAgdmFyIHByaW50T2JqID0gKG9ialR5cGUgPT09ICdzdHJpbmcnKSA/IFwiJ1wiICsgb2JqICsgXCInXCIgOiBvYmo7XG4gICAgICBlcnJvck1lc3NhZ2UgPSBtc2dQcmVmaXggKyAnZXhwZWN0ZWQgJyArIHByaW50T2JqICsgJyB0byBiZSBhIG51bWJlciBvciBhIGRhdGUnO1xuICAgIH0gZWxzZSB7XG4gICAgICBzaG91bGRUaHJvdyA9IGZhbHNlO1xuICAgIH1cblxuICAgIGlmIChzaG91bGRUaHJvdykge1xuICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKGVycm9yTWVzc2FnZSwgdW5kZWZpbmVkLCBzc2ZpKTtcbiAgICB9XG5cbiAgICBpZiAoZG9MZW5ndGgpIHtcbiAgICAgIHZhciBkZXNjcmlwdG9yID0gJ2xlbmd0aCdcbiAgICAgICAgLCBpdGVtc0NvdW50O1xuICAgICAgaWYgKG9ialR5cGUgPT09ICdtYXAnIHx8IG9ialR5cGUgPT09ICdzZXQnKSB7XG4gICAgICAgIGRlc2NyaXB0b3IgPSAnc2l6ZSc7XG4gICAgICAgIGl0ZW1zQ291bnQgPSBvYmouc2l6ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGl0ZW1zQ291bnQgPSBvYmoubGVuZ3RoO1xuICAgICAgfVxuICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgaXRlbXNDb3VudCA+PSBzdGFydCAmJiBpdGVtc0NvdW50IDw9IGZpbmlzaFxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGhhdmUgYSAnICsgZGVzY3JpcHRvciArICcgd2l0aGluICcgKyByYW5nZVxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBoYXZlIGEgJyArIGRlc2NyaXB0b3IgKyAnIHdpdGhpbiAnICsgcmFuZ2VcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgIG9iaiA+PSBzdGFydCAmJiBvYmogPD0gZmluaXNoXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgd2l0aGluICcgKyByYW5nZVxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBiZSB3aXRoaW4gJyArIHJhbmdlXG4gICAgICApO1xuICAgIH1cbiAgfSk7XG5cbiAgLyoqXG4gICAqICMjIyAuaW5zdGFuY2VvZihjb25zdHJ1Y3RvclssIG1zZ10pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGFuIGluc3RhbmNlIG9mIHRoZSBnaXZlbiBgY29uc3RydWN0b3JgLlxuICAgKlxuICAgKiAgICAgZnVuY3Rpb24gQ2F0ICgpIHsgfVxuICAgKlxuICAgKiAgICAgZXhwZWN0KG5ldyBDYXQoKSkudG8uYmUuYW4uaW5zdGFuY2VvZihDYXQpO1xuICAgKiAgICAgZXhwZWN0KFsxLCAyXSkudG8uYmUuYW4uaW5zdGFuY2VvZihBcnJheSk7XG4gICAqXG4gICAqIEFkZCBgLm5vdGAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gbmVnYXRlIGAuaW5zdGFuY2VvZmAuXG4gICAqXG4gICAqICAgICBleHBlY3Qoe2E6IDF9KS50by5ub3QuYmUuYW4uaW5zdGFuY2VvZihBcnJheSk7XG4gICAqXG4gICAqIGAuaW5zdGFuY2VvZmAgYWNjZXB0cyBhbiBvcHRpb25hbCBgbXNnYCBhcmd1bWVudCB3aGljaCBpcyBhIGN1c3RvbSBlcnJvclxuICAgKiBtZXNzYWdlIHRvIHNob3cgd2hlbiB0aGUgYXNzZXJ0aW9uIGZhaWxzLiBUaGUgbWVzc2FnZSBjYW4gYWxzbyBiZSBnaXZlbiBhc1xuICAgKiB0aGUgc2Vjb25kIGFyZ3VtZW50IHRvIGBleHBlY3RgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KDEpLnRvLmJlLmFuLmluc3RhbmNlb2YoQXJyYXksICdub29vIHdoeSBmYWlsPz8nKTtcbiAgICogICAgIGV4cGVjdCgxLCAnbm9vbyB3aHkgZmFpbD8/JykudG8uYmUuYW4uaW5zdGFuY2VvZihBcnJheSk7XG4gICAqXG4gICAqIER1ZSB0byBsaW1pdGF0aW9ucyBpbiBFUzUsIGAuaW5zdGFuY2VvZmAgbWF5IG5vdCBhbHdheXMgd29yayBhcyBleHBlY3RlZFxuICAgKiB3aGVuIHVzaW5nIGEgdHJhbnNwaWxlciBzdWNoIGFzIEJhYmVsIG9yIFR5cGVTY3JpcHQuIEluIHBhcnRpY3VsYXIsIGl0IG1heVxuICAgKiBwcm9kdWNlIHVuZXhwZWN0ZWQgcmVzdWx0cyB3aGVuIHN1YmNsYXNzaW5nIGJ1aWx0LWluIG9iamVjdCBzdWNoIGFzXG4gICAqIGBBcnJheWAsIGBFcnJvcmAsIGFuZCBgTWFwYC4gU2VlIHlvdXIgdHJhbnNwaWxlcidzIGRvY3MgZm9yIGRldGFpbHM6XG4gICAqXG4gICAqIC0gKFtCYWJlbF0oaHR0cHM6Ly9iYWJlbGpzLmlvL2RvY3MvdXNhZ2UvY2F2ZWF0cy8jY2xhc3NlcykpXG4gICAqIC0gKFtUeXBlU2NyaXB0XShodHRwczovL2dpdGh1Yi5jb20vTWljcm9zb2Z0L1R5cGVTY3JpcHQvd2lraS9CcmVha2luZy1DaGFuZ2VzI2V4dGVuZGluZy1idWlsdC1pbnMtbGlrZS1lcnJvci1hcnJheS1hbmQtbWFwLW1heS1uby1sb25nZXItd29yaykpXG4gICAqXG4gICAqIFRoZSBhbGlhcyBgLmluc3RhbmNlT2ZgIGNhbiBiZSB1c2VkIGludGVyY2hhbmdlYWJseSB3aXRoIGAuaW5zdGFuY2VvZmAuXG4gICAqXG4gICAqIEBuYW1lIGluc3RhbmNlb2ZcbiAgICogQHBhcmFtIHtDb25zdHJ1Y3Rvcn0gY29uc3RydWN0b3JcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1zZyBfb3B0aW9uYWxfXG4gICAqIEBhbGlhcyBpbnN0YW5jZU9mXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGFzc2VydEluc3RhbmNlT2YgKGNvbnN0cnVjdG9yLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcblxuICAgIHZhciB0YXJnZXQgPSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgIHZhciBzc2ZpID0gZmxhZyh0aGlzLCAnc3NmaScpO1xuICAgIHZhciBmbGFnTXNnID0gZmxhZyh0aGlzLCAnbWVzc2FnZScpO1xuXG4gICAgdHJ5IHtcbiAgICAgIHZhciBpc0luc3RhbmNlT2YgPSB0YXJnZXQgaW5zdGFuY2VvZiBjb25zdHJ1Y3RvcjtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGlmIChlcnIgaW5zdGFuY2VvZiBUeXBlRXJyb3IpIHtcbiAgICAgICAgZmxhZ01zZyA9IGZsYWdNc2cgPyBmbGFnTXNnICsgJzogJyA6ICcnO1xuICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoXG4gICAgICAgICAgZmxhZ01zZyArICdUaGUgaW5zdGFuY2VvZiBhc3NlcnRpb24gbmVlZHMgYSBjb25zdHJ1Y3RvciBidXQgJ1xuICAgICAgICAgICAgKyBfLnR5cGUoY29uc3RydWN0b3IpICsgJyB3YXMgZ2l2ZW4uJyxcbiAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgc3NmaVxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cblxuICAgIHZhciBuYW1lID0gXy5nZXROYW1lKGNvbnN0cnVjdG9yKTtcbiAgICBpZiAobmFtZSA9PT0gbnVsbCkge1xuICAgICAgbmFtZSA9ICdhbiB1bm5hbWVkIGNvbnN0cnVjdG9yJztcbiAgICB9XG5cbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgaXNJbnN0YW5jZU9mXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIGFuIGluc3RhbmNlIG9mICcgKyBuYW1lXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBiZSBhbiBpbnN0YW5jZSBvZiAnICsgbmFtZVxuICAgICk7XG4gIH07XG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnaW5zdGFuY2VvZicsIGFzc2VydEluc3RhbmNlT2YpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdpbnN0YW5jZU9mJywgYXNzZXJ0SW5zdGFuY2VPZik7XG5cbiAgLyoqXG4gICAqICMjIyAucHJvcGVydHkobmFtZVssIHZhbFssIG1zZ11dKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBoYXMgYSBwcm9wZXJ0eSB3aXRoIHRoZSBnaXZlbiBrZXkgYG5hbWVgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KHthOiAxfSkudG8uaGF2ZS5wcm9wZXJ0eSgnYScpO1xuICAgKlxuICAgKiBXaGVuIGB2YWxgIGlzIHByb3ZpZGVkLCBgLnByb3BlcnR5YCBhbHNvIGFzc2VydHMgdGhhdCB0aGUgcHJvcGVydHkncyB2YWx1ZVxuICAgKiBpcyBlcXVhbCB0byB0aGUgZ2l2ZW4gYHZhbGAuXG4gICAqXG4gICAqICAgICBleHBlY3Qoe2E6IDF9KS50by5oYXZlLnByb3BlcnR5KCdhJywgMSk7XG4gICAqXG4gICAqIEJ5IGRlZmF1bHQsIHN0cmljdCAoYD09PWApIGVxdWFsaXR5IGlzIHVzZWQuIEFkZCBgLmRlZXBgIGVhcmxpZXIgaW4gdGhlXG4gICAqIGNoYWluIHRvIHVzZSBkZWVwIGVxdWFsaXR5IGluc3RlYWQuIFNlZSB0aGUgYGRlZXAtZXFsYCBwcm9qZWN0IHBhZ2UgZm9yXG4gICAqIGluZm8gb24gdGhlIGRlZXAgZXF1YWxpdHkgYWxnb3JpdGhtOiBodHRwczovL2dpdGh1Yi5jb20vY2hhaWpzL2RlZXAtZXFsLlxuICAgKlxuICAgKiAgICAgLy8gVGFyZ2V0IG9iamVjdCBkZWVwbHkgKGJ1dCBub3Qgc3RyaWN0bHkpIGhhcyBwcm9wZXJ0eSBgeDoge2E6IDF9YFxuICAgKiAgICAgZXhwZWN0KHt4OiB7YTogMX19KS50by5oYXZlLmRlZXAucHJvcGVydHkoJ3gnLCB7YTogMX0pO1xuICAgKiAgICAgZXhwZWN0KHt4OiB7YTogMX19KS50by5ub3QuaGF2ZS5wcm9wZXJ0eSgneCcsIHthOiAxfSk7XG4gICAqXG4gICAqIFRoZSB0YXJnZXQncyBlbnVtZXJhYmxlIGFuZCBub24tZW51bWVyYWJsZSBwcm9wZXJ0aWVzIGFyZSBhbHdheXMgaW5jbHVkZWRcbiAgICogaW4gdGhlIHNlYXJjaC4gQnkgZGVmYXVsdCwgYm90aCBvd24gYW5kIGluaGVyaXRlZCBwcm9wZXJ0aWVzIGFyZSBpbmNsdWRlZC5cbiAgICogQWRkIGAub3duYCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byBleGNsdWRlIGluaGVyaXRlZCBwcm9wZXJ0aWVzIGZyb20gdGhlXG4gICAqIHNlYXJjaC5cbiAgICpcbiAgICogICAgIE9iamVjdC5wcm90b3R5cGUuYiA9IDI7XG4gICAqXG4gICAqICAgICBleHBlY3Qoe2E6IDF9KS50by5oYXZlLm93bi5wcm9wZXJ0eSgnYScpO1xuICAgKiAgICAgZXhwZWN0KHthOiAxfSkudG8uaGF2ZS5vd24ucHJvcGVydHkoJ2EnLCAxKTtcbiAgICogICAgIGV4cGVjdCh7YTogMX0pLnRvLmhhdmUucHJvcGVydHkoJ2InKTtcbiAgICogICAgIGV4cGVjdCh7YTogMX0pLnRvLm5vdC5oYXZlLm93bi5wcm9wZXJ0eSgnYicpO1xuICAgKlxuICAgKiBgLmRlZXBgIGFuZCBgLm93bmAgY2FuIGJlIGNvbWJpbmVkLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KHt4OiB7YTogMX19KS50by5oYXZlLmRlZXAub3duLnByb3BlcnR5KCd4Jywge2E6IDF9KTtcbiAgICpcbiAgICogQWRkIGAubmVzdGVkYCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byBlbmFibGUgZG90LSBhbmQgYnJhY2tldC1ub3RhdGlvbiB3aGVuXG4gICAqIHJlZmVyZW5jaW5nIG5lc3RlZCBwcm9wZXJ0aWVzLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KHthOiB7YjogWyd4JywgJ3knXX19KS50by5oYXZlLm5lc3RlZC5wcm9wZXJ0eSgnYS5iWzFdJyk7XG4gICAqICAgICBleHBlY3Qoe2E6IHtiOiBbJ3gnLCAneSddfX0pLnRvLmhhdmUubmVzdGVkLnByb3BlcnR5KCdhLmJbMV0nLCAneScpO1xuICAgKlxuICAgKiBJZiBgLmAgb3IgYFtdYCBhcmUgcGFydCBvZiBhbiBhY3R1YWwgcHJvcGVydHkgbmFtZSwgdGhleSBjYW4gYmUgZXNjYXBlZCBieVxuICAgKiBhZGRpbmcgdHdvIGJhY2tzbGFzaGVzIGJlZm9yZSB0aGVtLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KHsnLmEnOiB7J1tiXSc6ICd4J319KS50by5oYXZlLm5lc3RlZC5wcm9wZXJ0eSgnXFxcXC5hLlxcXFxbYlxcXFxdJyk7XG4gICAqXG4gICAqIGAuZGVlcGAgYW5kIGAubmVzdGVkYCBjYW4gYmUgY29tYmluZWQuXG4gICAqXG4gICAqICAgICBleHBlY3Qoe2E6IHtiOiBbe2M6IDN9XX19KVxuICAgKiAgICAgICAudG8uaGF2ZS5kZWVwLm5lc3RlZC5wcm9wZXJ0eSgnYS5iWzBdJywge2M6IDN9KTtcbiAgICpcbiAgICogYC5vd25gIGFuZCBgLm5lc3RlZGAgY2Fubm90IGJlIGNvbWJpbmVkLlxuICAgKlxuICAgKiBBZGQgYC5ub3RgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIG5lZ2F0ZSBgLnByb3BlcnR5YC5cbiAgICpcbiAgICogICAgIGV4cGVjdCh7YTogMX0pLnRvLm5vdC5oYXZlLnByb3BlcnR5KCdiJyk7XG4gICAqXG4gICAqIEhvd2V2ZXIsIGl0J3MgZGFuZ2Vyb3VzIHRvIG5lZ2F0ZSBgLnByb3BlcnR5YCB3aGVuIHByb3ZpZGluZyBgdmFsYC4gVGhlXG4gICAqIHByb2JsZW0gaXMgdGhhdCBpdCBjcmVhdGVzIHVuY2VydGFpbiBleHBlY3RhdGlvbnMgYnkgYXNzZXJ0aW5nIHRoYXQgdGhlXG4gICAqIHRhcmdldCBlaXRoZXIgZG9lc24ndCBoYXZlIGEgcHJvcGVydHkgd2l0aCB0aGUgZ2l2ZW4ga2V5IGBuYW1lYCwgb3IgdGhhdCBpdFxuICAgKiBkb2VzIGhhdmUgYSBwcm9wZXJ0eSB3aXRoIHRoZSBnaXZlbiBrZXkgYG5hbWVgIGJ1dCBpdHMgdmFsdWUgaXNuJ3QgZXF1YWwgdG9cbiAgICogdGhlIGdpdmVuIGB2YWxgLiBJdCdzIG9mdGVuIGJlc3QgdG8gaWRlbnRpZnkgdGhlIGV4YWN0IG91dHB1dCB0aGF0J3NcbiAgICogZXhwZWN0ZWQsIGFuZCB0aGVuIHdyaXRlIGFuIGFzc2VydGlvbiB0aGF0IG9ubHkgYWNjZXB0cyB0aGF0IGV4YWN0IG91dHB1dC5cbiAgICpcbiAgICogV2hlbiB0aGUgdGFyZ2V0IGlzbid0IGV4cGVjdGVkIHRvIGhhdmUgYSBwcm9wZXJ0eSB3aXRoIHRoZSBnaXZlbiBrZXlcbiAgICogYG5hbWVgLCBpdCdzIG9mdGVuIGJlc3QgdG8gYXNzZXJ0IGV4YWN0bHkgdGhhdC5cbiAgICpcbiAgICogICAgIGV4cGVjdCh7YjogMn0pLnRvLm5vdC5oYXZlLnByb3BlcnR5KCdhJyk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3Qoe2I6IDJ9KS50by5ub3QuaGF2ZS5wcm9wZXJ0eSgnYScsIDEpOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogV2hlbiB0aGUgdGFyZ2V0IGlzIGV4cGVjdGVkIHRvIGhhdmUgYSBwcm9wZXJ0eSB3aXRoIHRoZSBnaXZlbiBrZXkgYG5hbWVgLFxuICAgKiBpdCdzIG9mdGVuIGJlc3QgdG8gYXNzZXJ0IHRoYXQgdGhlIHByb3BlcnR5IGhhcyBpdHMgZXhwZWN0ZWQgdmFsdWUsIHJhdGhlclxuICAgKiB0aGFuIGFzc2VydGluZyB0aGF0IGl0IGRvZXNuJ3QgaGF2ZSBvbmUgb2YgbWFueSB1bmV4cGVjdGVkIHZhbHVlcy5cbiAgICpcbiAgICogICAgIGV4cGVjdCh7YTogM30pLnRvLmhhdmUucHJvcGVydHkoJ2EnLCAzKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCh7YTogM30pLnRvLm5vdC5oYXZlLnByb3BlcnR5KCdhJywgMSk7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBgLnByb3BlcnR5YCBjaGFuZ2VzIHRoZSB0YXJnZXQgb2YgYW55IGFzc2VydGlvbnMgdGhhdCBmb2xsb3cgaW4gdGhlIGNoYWluXG4gICAqIHRvIGJlIHRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkgZnJvbSB0aGUgb3JpZ2luYWwgdGFyZ2V0IG9iamVjdC5cbiAgICpcbiAgICogICAgIGV4cGVjdCh7YTogMX0pLnRvLmhhdmUucHJvcGVydHkoJ2EnKS50aGF0LmlzLmEoJ251bWJlcicpO1xuICAgKlxuICAgKiBgLnByb3BlcnR5YCBhY2NlcHRzIGFuIG9wdGlvbmFsIGBtc2dgIGFyZ3VtZW50IHdoaWNoIGlzIGEgY3VzdG9tIGVycm9yXG4gICAqIG1lc3NhZ2UgdG8gc2hvdyB3aGVuIHRoZSBhc3NlcnRpb24gZmFpbHMuIFRoZSBtZXNzYWdlIGNhbiBhbHNvIGJlIGdpdmVuIGFzXG4gICAqIHRoZSBzZWNvbmQgYXJndW1lbnQgdG8gYGV4cGVjdGAuIFdoZW4gbm90IHByb3ZpZGluZyBgdmFsYCwgb25seSB1c2UgdGhlXG4gICAqIHNlY29uZCBmb3JtLlxuICAgKlxuICAgKiAgICAgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCh7YTogMX0pLnRvLmhhdmUucHJvcGVydHkoJ2EnLCAyLCAnbm9vbyB3aHkgZmFpbD8/Jyk7XG4gICAqICAgICBleHBlY3Qoe2E6IDF9LCAnbm9vbyB3aHkgZmFpbD8/JykudG8uaGF2ZS5wcm9wZXJ0eSgnYScsIDIpO1xuICAgKiAgICAgZXhwZWN0KHthOiAxfSwgJ25vb28gd2h5IGZhaWw/PycpLnRvLmhhdmUucHJvcGVydHkoJ2InKTtcbiAgICpcbiAgICogICAgIC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KHthOiAxfSkudG8uaGF2ZS5wcm9wZXJ0eSgnYicsIHVuZGVmaW5lZCwgJ25vb28gd2h5IGZhaWw/PycpO1xuICAgKlxuICAgKiBUaGUgYWJvdmUgYXNzZXJ0aW9uIGlzbid0IHRoZSBzYW1lIHRoaW5nIGFzIG5vdCBwcm92aWRpbmcgYHZhbGAuIEluc3RlYWQsXG4gICAqIGl0J3MgYXNzZXJ0aW5nIHRoYXQgdGhlIHRhcmdldCBvYmplY3QgaGFzIGEgYGJgIHByb3BlcnR5IHRoYXQncyBlcXVhbCB0b1xuICAgKiBgdW5kZWZpbmVkYC5cbiAgICpcbiAgICogVGhlIGFzc2VydGlvbnMgYC5vd25Qcm9wZXJ0eWAgYW5kIGAuaGF2ZU93blByb3BlcnR5YCBjYW4gYmUgdXNlZFxuICAgKiBpbnRlcmNoYW5nZWFibHkgd2l0aCBgLm93bi5wcm9wZXJ0eWAuXG4gICAqXG4gICAqIEBuYW1lIHByb3BlcnR5XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbCAob3B0aW9uYWwpXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtc2cgX29wdGlvbmFsX1xuICAgKiBAcmV0dXJucyB2YWx1ZSBvZiBwcm9wZXJ0eSBmb3IgY2hhaW5pbmdcbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gYXNzZXJ0UHJvcGVydHkgKG5hbWUsIHZhbCwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG5cbiAgICB2YXIgaXNOZXN0ZWQgPSBmbGFnKHRoaXMsICduZXN0ZWQnKVxuICAgICAgLCBpc093biA9IGZsYWcodGhpcywgJ293bicpXG4gICAgICAsIGZsYWdNc2cgPSBmbGFnKHRoaXMsICdtZXNzYWdlJylcbiAgICAgICwgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0JylcbiAgICAgICwgc3NmaSA9IGZsYWcodGhpcywgJ3NzZmknKVxuICAgICAgLCBuYW1lVHlwZSA9IHR5cGVvZiBuYW1lO1xuXG4gICAgZmxhZ01zZyA9IGZsYWdNc2cgPyBmbGFnTXNnICsgJzogJyA6ICcnO1xuXG4gICAgaWYgKGlzTmVzdGVkKSB7XG4gICAgICBpZiAobmFtZVR5cGUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihcbiAgICAgICAgICBmbGFnTXNnICsgJ3RoZSBhcmd1bWVudCB0byBwcm9wZXJ0eSBtdXN0IGJlIGEgc3RyaW5nIHdoZW4gdXNpbmcgbmVzdGVkIHN5bnRheCcsXG4gICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgIHNzZmlcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKG5hbWVUeXBlICE9PSAnc3RyaW5nJyAmJiBuYW1lVHlwZSAhPT0gJ251bWJlcicgJiYgbmFtZVR5cGUgIT09ICdzeW1ib2wnKSB7XG4gICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihcbiAgICAgICAgICBmbGFnTXNnICsgJ3RoZSBhcmd1bWVudCB0byBwcm9wZXJ0eSBtdXN0IGJlIGEgc3RyaW5nLCBudW1iZXIsIG9yIHN5bWJvbCcsXG4gICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgIHNzZmlcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaXNOZXN0ZWQgJiYgaXNPd24pIHtcbiAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihcbiAgICAgICAgZmxhZ01zZyArICdUaGUgXCJuZXN0ZWRcIiBhbmQgXCJvd25cIiBmbGFncyBjYW5ub3QgYmUgY29tYmluZWQuJyxcbiAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICBzc2ZpXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmIChvYmogPT09IG51bGwgfHwgb2JqID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihcbiAgICAgICAgZmxhZ01zZyArICdUYXJnZXQgY2Fubm90IGJlIG51bGwgb3IgdW5kZWZpbmVkLicsXG4gICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgc3NmaVxuICAgICAgKTtcbiAgICB9XG5cbiAgICB2YXIgaXNEZWVwID0gZmxhZyh0aGlzLCAnZGVlcCcpXG4gICAgICAsIG5lZ2F0ZSA9IGZsYWcodGhpcywgJ25lZ2F0ZScpXG4gICAgICAsIHBhdGhJbmZvID0gaXNOZXN0ZWQgPyBfLmdldFBhdGhJbmZvKG9iaiwgbmFtZSkgOiBudWxsXG4gICAgICAsIHZhbHVlID0gaXNOZXN0ZWQgPyBwYXRoSW5mby52YWx1ZSA6IG9ialtuYW1lXTtcblxuICAgIHZhciBkZXNjcmlwdG9yID0gJyc7XG4gICAgaWYgKGlzRGVlcCkgZGVzY3JpcHRvciArPSAnZGVlcCAnO1xuICAgIGlmIChpc093bikgZGVzY3JpcHRvciArPSAnb3duICc7XG4gICAgaWYgKGlzTmVzdGVkKSBkZXNjcmlwdG9yICs9ICduZXN0ZWQgJztcbiAgICBkZXNjcmlwdG9yICs9ICdwcm9wZXJ0eSAnO1xuXG4gICAgdmFyIGhhc1Byb3BlcnR5O1xuICAgIGlmIChpc093bikgaGFzUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBuYW1lKTtcbiAgICBlbHNlIGlmIChpc05lc3RlZCkgaGFzUHJvcGVydHkgPSBwYXRoSW5mby5leGlzdHM7XG4gICAgZWxzZSBoYXNQcm9wZXJ0eSA9IF8uaGFzUHJvcGVydHkob2JqLCBuYW1lKTtcblxuICAgIC8vIFdoZW4gcGVyZm9ybWluZyBhIG5lZ2F0ZWQgYXNzZXJ0aW9uIGZvciBib3RoIG5hbWUgYW5kIHZhbCwgbWVyZWx5IGhhdmluZ1xuICAgIC8vIGEgcHJvcGVydHkgd2l0aCB0aGUgZ2l2ZW4gbmFtZSBpc24ndCBlbm91Z2ggdG8gY2F1c2UgdGhlIGFzc2VydGlvbiB0b1xuICAgIC8vIGZhaWwuIEl0IG11c3QgYm90aCBoYXZlIGEgcHJvcGVydHkgd2l0aCB0aGUgZ2l2ZW4gbmFtZSwgYW5kIHRoZSB2YWx1ZSBvZlxuICAgIC8vIHRoYXQgcHJvcGVydHkgbXVzdCBlcXVhbCB0aGUgZ2l2ZW4gdmFsLiBUaGVyZWZvcmUsIHNraXAgdGhpcyBhc3NlcnRpb24gaW5cbiAgICAvLyBmYXZvciBvZiB0aGUgbmV4dC5cbiAgICBpZiAoIW5lZ2F0ZSB8fCBhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICBoYXNQcm9wZXJ0eVxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGhhdmUgJyArIGRlc2NyaXB0b3IgKyBfLmluc3BlY3QobmFtZSlcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgaGF2ZSAnICsgZGVzY3JpcHRvciArIF8uaW5zcGVjdChuYW1lKSk7XG4gICAgfVxuXG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICBoYXNQcm9wZXJ0eSAmJiAoaXNEZWVwID8gXy5lcWwodmFsLCB2YWx1ZSkgOiB2YWwgPT09IHZhbHVlKVxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGhhdmUgJyArIGRlc2NyaXB0b3IgKyBfLmluc3BlY3QobmFtZSkgKyAnIG9mICN7ZXhwfSwgYnV0IGdvdCAje2FjdH0nXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGhhdmUgJyArIGRlc2NyaXB0b3IgKyBfLmluc3BlY3QobmFtZSkgKyAnIG9mICN7YWN0fSdcbiAgICAgICAgLCB2YWxcbiAgICAgICAgLCB2YWx1ZVxuICAgICAgKTtcbiAgICB9XG5cbiAgICBmbGFnKHRoaXMsICdvYmplY3QnLCB2YWx1ZSk7XG4gIH1cblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdwcm9wZXJ0eScsIGFzc2VydFByb3BlcnR5KTtcblxuICBmdW5jdGlvbiBhc3NlcnRPd25Qcm9wZXJ0eSAobmFtZSwgdmFsdWUsIG1zZykge1xuICAgIGZsYWcodGhpcywgJ293bicsIHRydWUpO1xuICAgIGFzc2VydFByb3BlcnR5LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIH1cblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdvd25Qcm9wZXJ0eScsIGFzc2VydE93blByb3BlcnR5KTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnaGF2ZU93blByb3BlcnR5JywgYXNzZXJ0T3duUHJvcGVydHkpO1xuXG4gIC8qKlxuICAgKiAjIyMgLm93blByb3BlcnR5RGVzY3JpcHRvcihuYW1lWywgZGVzY3JpcHRvclssIG1zZ11dKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBoYXMgaXRzIG93biBwcm9wZXJ0eSBkZXNjcmlwdG9yIHdpdGggdGhlIGdpdmVuIGtleVxuICAgKiBgbmFtZWAuIEVudW1lcmFibGUgYW5kIG5vbi1lbnVtZXJhYmxlIHByb3BlcnRpZXMgYXJlIGluY2x1ZGVkIGluIHRoZVxuICAgKiBzZWFyY2guXG4gICAqXG4gICAqICAgICBleHBlY3Qoe2E6IDF9KS50by5oYXZlLm93blByb3BlcnR5RGVzY3JpcHRvcignYScpO1xuICAgKlxuICAgKiBXaGVuIGBkZXNjcmlwdG9yYCBpcyBwcm92aWRlZCwgYC5vd25Qcm9wZXJ0eURlc2NyaXB0b3JgIGFsc28gYXNzZXJ0cyB0aGF0XG4gICAqIHRoZSBwcm9wZXJ0eSdzIGRlc2NyaXB0b3IgaXMgZGVlcGx5IGVxdWFsIHRvIHRoZSBnaXZlbiBgZGVzY3JpcHRvcmAuIFNlZVxuICAgKiB0aGUgYGRlZXAtZXFsYCBwcm9qZWN0IHBhZ2UgZm9yIGluZm8gb24gdGhlIGRlZXAgZXF1YWxpdHkgYWxnb3JpdGhtOlxuICAgKiBodHRwczovL2dpdGh1Yi5jb20vY2hhaWpzL2RlZXAtZXFsLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KHthOiAxfSkudG8uaGF2ZS5vd25Qcm9wZXJ0eURlc2NyaXB0b3IoJ2EnLCB7XG4gICAqICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICogICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICogICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAqICAgICAgIHZhbHVlOiAxLFxuICAgKiAgICAgfSk7XG4gICAqXG4gICAqIEFkZCBgLm5vdGAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gbmVnYXRlIGAub3duUHJvcGVydHlEZXNjcmlwdG9yYC5cbiAgICpcbiAgICogICAgIGV4cGVjdCh7YTogMX0pLnRvLm5vdC5oYXZlLm93blByb3BlcnR5RGVzY3JpcHRvcignYicpO1xuICAgKlxuICAgKiBIb3dldmVyLCBpdCdzIGRhbmdlcm91cyB0byBuZWdhdGUgYC5vd25Qcm9wZXJ0eURlc2NyaXB0b3JgIHdoZW4gcHJvdmlkaW5nXG4gICAqIGEgYGRlc2NyaXB0b3JgLiBUaGUgcHJvYmxlbSBpcyB0aGF0IGl0IGNyZWF0ZXMgdW5jZXJ0YWluIGV4cGVjdGF0aW9ucyBieVxuICAgKiBhc3NlcnRpbmcgdGhhdCB0aGUgdGFyZ2V0IGVpdGhlciBkb2Vzbid0IGhhdmUgYSBwcm9wZXJ0eSBkZXNjcmlwdG9yIHdpdGhcbiAgICogdGhlIGdpdmVuIGtleSBgbmFtZWAsIG9yIHRoYXQgaXQgZG9lcyBoYXZlIGEgcHJvcGVydHkgZGVzY3JpcHRvciB3aXRoIHRoZVxuICAgKiBnaXZlbiBrZXkgYG5hbWVgIGJ1dCBpdFx1MjAxOXMgbm90IGRlZXBseSBlcXVhbCB0byB0aGUgZ2l2ZW4gYGRlc2NyaXB0b3JgLiBJdCdzXG4gICAqIG9mdGVuIGJlc3QgdG8gaWRlbnRpZnkgdGhlIGV4YWN0IG91dHB1dCB0aGF0J3MgZXhwZWN0ZWQsIGFuZCB0aGVuIHdyaXRlIGFuXG4gICAqIGFzc2VydGlvbiB0aGF0IG9ubHkgYWNjZXB0cyB0aGF0IGV4YWN0IG91dHB1dC5cbiAgICpcbiAgICogV2hlbiB0aGUgdGFyZ2V0IGlzbid0IGV4cGVjdGVkIHRvIGhhdmUgYSBwcm9wZXJ0eSBkZXNjcmlwdG9yIHdpdGggdGhlIGdpdmVuXG4gICAqIGtleSBgbmFtZWAsIGl0J3Mgb2Z0ZW4gYmVzdCB0byBhc3NlcnQgZXhhY3RseSB0aGF0LlxuICAgKlxuICAgKiAgICAgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCh7YjogMn0pLnRvLm5vdC5oYXZlLm93blByb3BlcnR5RGVzY3JpcHRvcignYScpO1xuICAgKlxuICAgKiAgICAgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3Qoe2I6IDJ9KS50by5ub3QuaGF2ZS5vd25Qcm9wZXJ0eURlc2NyaXB0b3IoJ2EnLCB7XG4gICAqICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICogICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICogICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAqICAgICAgIHZhbHVlOiAxLFxuICAgKiAgICAgfSk7XG4gICAqXG4gICAqIFdoZW4gdGhlIHRhcmdldCBpcyBleHBlY3RlZCB0byBoYXZlIGEgcHJvcGVydHkgZGVzY3JpcHRvciB3aXRoIHRoZSBnaXZlblxuICAgKiBrZXkgYG5hbWVgLCBpdCdzIG9mdGVuIGJlc3QgdG8gYXNzZXJ0IHRoYXQgdGhlIHByb3BlcnR5IGhhcyBpdHMgZXhwZWN0ZWRcbiAgICogZGVzY3JpcHRvciwgcmF0aGVyIHRoYW4gYXNzZXJ0aW5nIHRoYXQgaXQgZG9lc24ndCBoYXZlIG9uZSBvZiBtYW55XG4gICAqIHVuZXhwZWN0ZWQgZGVzY3JpcHRvcnMuXG4gICAqXG4gICAqICAgICAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KHthOiAzfSkudG8uaGF2ZS5vd25Qcm9wZXJ0eURlc2NyaXB0b3IoJ2EnLCB7XG4gICAqICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICogICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICogICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAqICAgICAgIHZhbHVlOiAzLFxuICAgKiAgICAgfSk7XG4gICAqXG4gICAqICAgICAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCh7YTogM30pLnRvLm5vdC5oYXZlLm93blByb3BlcnR5RGVzY3JpcHRvcignYScsIHtcbiAgICogICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgKiAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgKiAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICogICAgICAgdmFsdWU6IDEsXG4gICAqICAgICB9KTtcbiAgICpcbiAgICogYC5vd25Qcm9wZXJ0eURlc2NyaXB0b3JgIGNoYW5nZXMgdGhlIHRhcmdldCBvZiBhbnkgYXNzZXJ0aW9ucyB0aGF0IGZvbGxvd1xuICAgKiBpbiB0aGUgY2hhaW4gdG8gYmUgdGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eSBkZXNjcmlwdG9yIGZyb20gdGhlIG9yaWdpbmFsXG4gICAqIHRhcmdldCBvYmplY3QuXG4gICAqXG4gICAqICAgICBleHBlY3Qoe2E6IDF9KS50by5oYXZlLm93blByb3BlcnR5RGVzY3JpcHRvcignYScpXG4gICAqICAgICAgIC50aGF0Lmhhcy5wcm9wZXJ0eSgnZW51bWVyYWJsZScsIHRydWUpO1xuICAgKlxuICAgKiBgLm93blByb3BlcnR5RGVzY3JpcHRvcmAgYWNjZXB0cyBhbiBvcHRpb25hbCBgbXNnYCBhcmd1bWVudCB3aGljaCBpcyBhXG4gICAqIGN1c3RvbSBlcnJvciBtZXNzYWdlIHRvIHNob3cgd2hlbiB0aGUgYXNzZXJ0aW9uIGZhaWxzLiBUaGUgbWVzc2FnZSBjYW4gYWxzb1xuICAgKiBiZSBnaXZlbiBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50IHRvIGBleHBlY3RgLiBXaGVuIG5vdCBwcm92aWRpbmdcbiAgICogYGRlc2NyaXB0b3JgLCBvbmx5IHVzZSB0aGUgc2Vjb25kIGZvcm0uXG4gICAqXG4gICAqICAgICAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KHthOiAxfSkudG8uaGF2ZS5vd25Qcm9wZXJ0eURlc2NyaXB0b3IoJ2EnLCB7XG4gICAqICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICogICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICogICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAqICAgICAgIHZhbHVlOiAyLFxuICAgKiAgICAgfSwgJ25vb28gd2h5IGZhaWw/PycpO1xuICAgKlxuICAgKiAgICAgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCh7YTogMX0sICdub29vIHdoeSBmYWlsPz8nKS50by5oYXZlLm93blByb3BlcnR5RGVzY3JpcHRvcignYScsIHtcbiAgICogICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgKiAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgKiAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICogICAgICAgdmFsdWU6IDIsXG4gICAqICAgICB9KTtcbiAgICpcbiAgICogICAgIC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3Qoe2E6IDF9LCAnbm9vbyB3aHkgZmFpbD8/JykudG8uaGF2ZS5vd25Qcm9wZXJ0eURlc2NyaXB0b3IoJ2InKTtcbiAgICpcbiAgICogICAgIC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KHthOiAxfSlcbiAgICogICAgICAgLnRvLmhhdmUub3duUHJvcGVydHlEZXNjcmlwdG9yKCdiJywgdW5kZWZpbmVkLCAnbm9vbyB3aHkgZmFpbD8/Jyk7XG4gICAqXG4gICAqIFRoZSBhYm92ZSBhc3NlcnRpb24gaXNuJ3QgdGhlIHNhbWUgdGhpbmcgYXMgbm90IHByb3ZpZGluZyBgZGVzY3JpcHRvcmAuXG4gICAqIEluc3RlYWQsIGl0J3MgYXNzZXJ0aW5nIHRoYXQgdGhlIHRhcmdldCBvYmplY3QgaGFzIGEgYGJgIHByb3BlcnR5XG4gICAqIGRlc2NyaXB0b3IgdGhhdCdzIGRlZXBseSBlcXVhbCB0byBgdW5kZWZpbmVkYC5cbiAgICpcbiAgICogVGhlIGFsaWFzIGAuaGF2ZU93blByb3BlcnR5RGVzY3JpcHRvcmAgY2FuIGJlIHVzZWQgaW50ZXJjaGFuZ2VhYmx5IHdpdGhcbiAgICogYC5vd25Qcm9wZXJ0eURlc2NyaXB0b3JgLlxuICAgKlxuICAgKiBAbmFtZSBvd25Qcm9wZXJ0eURlc2NyaXB0b3JcbiAgICogQGFsaWFzIGhhdmVPd25Qcm9wZXJ0eURlc2NyaXB0b3JcbiAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcbiAgICogQHBhcmFtIHtPYmplY3R9IGRlc2NyaXB0b3IgX29wdGlvbmFsX1xuICAgKiBAcGFyYW0ge1N0cmluZ30gbXNnIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gYXNzZXJ0T3duUHJvcGVydHlEZXNjcmlwdG9yIChuYW1lLCBkZXNjcmlwdG9yLCBtc2cpIHtcbiAgICBpZiAodHlwZW9mIGRlc2NyaXB0b3IgPT09ICdzdHJpbmcnKSB7XG4gICAgICBtc2cgPSBkZXNjcmlwdG9yO1xuICAgICAgZGVzY3JpcHRvciA9IG51bGw7XG4gICAgfVxuICAgIGlmIChtc2cpIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKTtcbiAgICB2YXIgYWN0dWFsRGVzY3JpcHRvciA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoT2JqZWN0KG9iaiksIG5hbWUpO1xuICAgIGlmIChhY3R1YWxEZXNjcmlwdG9yICYmIGRlc2NyaXB0b3IpIHtcbiAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgIF8uZXFsKGRlc2NyaXB0b3IsIGFjdHVhbERlc2NyaXB0b3IpXG4gICAgICAgICwgJ2V4cGVjdGVkIHRoZSBvd24gcHJvcGVydHkgZGVzY3JpcHRvciBmb3IgJyArIF8uaW5zcGVjdChuYW1lKSArICcgb24gI3t0aGlzfSB0byBtYXRjaCAnICsgXy5pbnNwZWN0KGRlc2NyaXB0b3IpICsgJywgZ290ICcgKyBfLmluc3BlY3QoYWN0dWFsRGVzY3JpcHRvcilcbiAgICAgICAgLCAnZXhwZWN0ZWQgdGhlIG93biBwcm9wZXJ0eSBkZXNjcmlwdG9yIGZvciAnICsgXy5pbnNwZWN0KG5hbWUpICsgJyBvbiAje3RoaXN9IHRvIG5vdCBtYXRjaCAnICsgXy5pbnNwZWN0KGRlc2NyaXB0b3IpXG4gICAgICAgICwgZGVzY3JpcHRvclxuICAgICAgICAsIGFjdHVhbERlc2NyaXB0b3JcbiAgICAgICAgLCB0cnVlXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICBhY3R1YWxEZXNjcmlwdG9yXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gaGF2ZSBhbiBvd24gcHJvcGVydHkgZGVzY3JpcHRvciBmb3IgJyArIF8uaW5zcGVjdChuYW1lKVxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBoYXZlIGFuIG93biBwcm9wZXJ0eSBkZXNjcmlwdG9yIGZvciAnICsgXy5pbnNwZWN0KG5hbWUpXG4gICAgICApO1xuICAgIH1cbiAgICBmbGFnKHRoaXMsICdvYmplY3QnLCBhY3R1YWxEZXNjcmlwdG9yKTtcbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ293blByb3BlcnR5RGVzY3JpcHRvcicsIGFzc2VydE93blByb3BlcnR5RGVzY3JpcHRvcik7XG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2hhdmVPd25Qcm9wZXJ0eURlc2NyaXB0b3InLCBhc3NlcnRPd25Qcm9wZXJ0eURlc2NyaXB0b3IpO1xuXG4gIC8qKlxuICAgKiAjIyMgLmxlbmd0aE9mKG5bLCBtc2ddKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCdzIGBsZW5ndGhgIG9yIGBzaXplYCBpcyBlcXVhbCB0byB0aGUgZ2l2ZW4gbnVtYmVyXG4gICAqIGBuYC5cbiAgICpcbiAgICogICAgIGV4cGVjdChbMSwgMiwgM10pLnRvLmhhdmUubGVuZ3RoT2YoMyk7XG4gICAqICAgICBleHBlY3QoJ2ZvbycpLnRvLmhhdmUubGVuZ3RoT2YoMyk7XG4gICAqICAgICBleHBlY3QobmV3IFNldChbMSwgMiwgM10pKS50by5oYXZlLmxlbmd0aE9mKDMpO1xuICAgKiAgICAgZXhwZWN0KG5ldyBNYXAoW1snYScsIDFdLCBbJ2InLCAyXSwgWydjJywgM11dKSkudG8uaGF2ZS5sZW5ndGhPZigzKTtcbiAgICpcbiAgICogQWRkIGAubm90YCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byBuZWdhdGUgYC5sZW5ndGhPZmAuIEhvd2V2ZXIsIGl0J3Mgb2Z0ZW5cbiAgICogYmVzdCB0byBhc3NlcnQgdGhhdCB0aGUgdGFyZ2V0J3MgYGxlbmd0aGAgcHJvcGVydHkgaXMgZXF1YWwgdG8gaXRzIGV4cGVjdGVkXG4gICAqIHZhbHVlLCByYXRoZXIgdGhhbiBub3QgZXF1YWwgdG8gb25lIG9mIG1hbnkgdW5leHBlY3RlZCB2YWx1ZXMuXG4gICAqXG4gICAqICAgICBleHBlY3QoJ2ZvbycpLnRvLmhhdmUubGVuZ3RoT2YoMyk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoJ2ZvbycpLnRvLm5vdC5oYXZlLmxlbmd0aE9mKDQpOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogYC5sZW5ndGhPZmAgYWNjZXB0cyBhbiBvcHRpb25hbCBgbXNnYCBhcmd1bWVudCB3aGljaCBpcyBhIGN1c3RvbSBlcnJvclxuICAgKiBtZXNzYWdlIHRvIHNob3cgd2hlbiB0aGUgYXNzZXJ0aW9uIGZhaWxzLiBUaGUgbWVzc2FnZSBjYW4gYWxzbyBiZSBnaXZlbiBhc1xuICAgKiB0aGUgc2Vjb25kIGFyZ3VtZW50IHRvIGBleHBlY3RgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KFsxLCAyLCAzXSkudG8uaGF2ZS5sZW5ndGhPZigyLCAnbm9vbyB3aHkgZmFpbD8/Jyk7XG4gICAqICAgICBleHBlY3QoWzEsIDIsIDNdLCAnbm9vbyB3aHkgZmFpbD8/JykudG8uaGF2ZS5sZW5ndGhPZigyKTtcbiAgICpcbiAgICogYC5sZW5ndGhPZmAgY2FuIGFsc28gYmUgdXNlZCBhcyBhIGxhbmd1YWdlIGNoYWluLCBjYXVzaW5nIGFsbCBgLmFib3ZlYCxcbiAgICogYC5iZWxvd2AsIGAubGVhc3RgLCBgLm1vc3RgLCBhbmQgYC53aXRoaW5gIGFzc2VydGlvbnMgdGhhdCBmb2xsb3cgaW4gdGhlXG4gICAqIGNoYWluIHRvIHVzZSB0aGUgdGFyZ2V0J3MgYGxlbmd0aGAgcHJvcGVydHkgYXMgdGhlIHRhcmdldC4gSG93ZXZlciwgaXQnc1xuICAgKiBvZnRlbiBiZXN0IHRvIGFzc2VydCB0aGF0IHRoZSB0YXJnZXQncyBgbGVuZ3RoYCBwcm9wZXJ0eSBpcyBlcXVhbCB0byBpdHNcbiAgICogZXhwZWN0ZWQgbGVuZ3RoLCByYXRoZXIgdGhhbiBhc3NlcnRpbmcgdGhhdCBpdHMgYGxlbmd0aGAgcHJvcGVydHkgZmFsbHNcbiAgICogd2l0aGluIHNvbWUgcmFuZ2Ugb2YgdmFsdWVzLlxuICAgKlxuICAgKiAgICAgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdChbMSwgMiwgM10pLnRvLmhhdmUubGVuZ3RoT2YoMyk7XG4gICAqXG4gICAqICAgICAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdChbMSwgMiwgM10pLnRvLmhhdmUubGVuZ3RoT2YuYWJvdmUoMik7XG4gICAqICAgICBleHBlY3QoWzEsIDIsIDNdKS50by5oYXZlLmxlbmd0aE9mLmJlbG93KDQpO1xuICAgKiAgICAgZXhwZWN0KFsxLCAyLCAzXSkudG8uaGF2ZS5sZW5ndGhPZi5hdC5sZWFzdCgzKTtcbiAgICogICAgIGV4cGVjdChbMSwgMiwgM10pLnRvLmhhdmUubGVuZ3RoT2YuYXQubW9zdCgzKTtcbiAgICogICAgIGV4cGVjdChbMSwgMiwgM10pLnRvLmhhdmUubGVuZ3RoT2Yud2l0aGluKDIsNCk7XG4gICAqXG4gICAqIER1ZSB0byBhIGNvbXBhdGliaWxpdHkgaXNzdWUsIHRoZSBhbGlhcyBgLmxlbmd0aGAgY2FuJ3QgYmUgY2hhaW5lZCBkaXJlY3RseVxuICAgKiBvZmYgb2YgYW4gdW5pbnZva2VkIG1ldGhvZCBzdWNoIGFzIGAuYWAuIFRoZXJlZm9yZSwgYC5sZW5ndGhgIGNhbid0IGJlIHVzZWRcbiAgICogaW50ZXJjaGFuZ2VhYmx5IHdpdGggYC5sZW5ndGhPZmAgaW4gZXZlcnkgc2l0dWF0aW9uLiBJdCdzIHJlY29tbWVuZGVkIHRvXG4gICAqIGFsd2F5cyB1c2UgYC5sZW5ndGhPZmAgaW5zdGVhZCBvZiBgLmxlbmd0aGAuXG4gICAqXG4gICAqICAgICBleHBlY3QoWzEsIDIsIDNdKS50by5oYXZlLmEubGVuZ3RoKDMpOyAvLyBpbmNvbXBhdGlibGU7IHRocm93cyBlcnJvclxuICAgKiAgICAgZXhwZWN0KFsxLCAyLCAzXSkudG8uaGF2ZS5hLmxlbmd0aE9mKDMpOyAgLy8gcGFzc2VzIGFzIGV4cGVjdGVkXG4gICAqXG4gICAqIEBuYW1lIGxlbmd0aE9mXG4gICAqIEBhbGlhcyBsZW5ndGhcbiAgICogQHBhcmFtIHtOdW1iZXJ9IG5cbiAgICogQHBhcmFtIHtTdHJpbmd9IG1zZyBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGFzc2VydExlbmd0aENoYWluICgpIHtcbiAgICBmbGFnKHRoaXMsICdkb0xlbmd0aCcsIHRydWUpO1xuICB9XG5cbiAgZnVuY3Rpb24gYXNzZXJ0TGVuZ3RoIChuLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0JylcbiAgICAgICwgb2JqVHlwZSA9IF8udHlwZShvYmopLnRvTG93ZXJDYXNlKClcbiAgICAgICwgZmxhZ01zZyA9IGZsYWcodGhpcywgJ21lc3NhZ2UnKVxuICAgICAgLCBzc2ZpID0gZmxhZyh0aGlzLCAnc3NmaScpXG4gICAgICAsIGRlc2NyaXB0b3IgPSAnbGVuZ3RoJ1xuICAgICAgLCBpdGVtc0NvdW50O1xuXG4gICAgc3dpdGNoIChvYmpUeXBlKSB7XG4gICAgICBjYXNlICdtYXAnOlxuICAgICAgY2FzZSAnc2V0JzpcbiAgICAgICAgZGVzY3JpcHRvciA9ICdzaXplJztcbiAgICAgICAgaXRlbXNDb3VudCA9IG9iai5zaXplO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIG5ldyBBc3NlcnRpb24ob2JqLCBmbGFnTXNnLCBzc2ZpLCB0cnVlKS50by5oYXZlLnByb3BlcnR5KCdsZW5ndGgnKTtcbiAgICAgICAgaXRlbXNDb3VudCA9IG9iai5sZW5ndGg7XG4gICAgfVxuXG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICAgIGl0ZW1zQ291bnQgPT0gblxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBoYXZlIGEgJyArIGRlc2NyaXB0b3IgKyAnIG9mICN7ZXhwfSBidXQgZ290ICN7YWN0fSdcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGhhdmUgYSAnICsgZGVzY3JpcHRvciArICcgb2YgI3thY3R9J1xuICAgICAgLCBuXG4gICAgICAsIGl0ZW1zQ291bnRcbiAgICApO1xuICB9XG5cbiAgQXNzZXJ0aW9uLmFkZENoYWluYWJsZU1ldGhvZCgnbGVuZ3RoJywgYXNzZXJ0TGVuZ3RoLCBhc3NlcnRMZW5ndGhDaGFpbik7XG4gIEFzc2VydGlvbi5hZGRDaGFpbmFibGVNZXRob2QoJ2xlbmd0aE9mJywgYXNzZXJ0TGVuZ3RoLCBhc3NlcnRMZW5ndGhDaGFpbik7XG5cbiAgLyoqXG4gICAqICMjIyAubWF0Y2gocmVbLCBtc2ddKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBtYXRjaGVzIHRoZSBnaXZlbiByZWd1bGFyIGV4cHJlc3Npb24gYHJlYC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgnZm9vYmFyJykudG8ubWF0Y2goL15mb28vKTtcbiAgICpcbiAgICogQWRkIGAubm90YCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byBuZWdhdGUgYC5tYXRjaGAuXG4gICAqXG4gICAqICAgICBleHBlY3QoJ2Zvb2JhcicpLnRvLm5vdC5tYXRjaCgvdGFjby8pO1xuICAgKlxuICAgKiBgLm1hdGNoYCBhY2NlcHRzIGFuIG9wdGlvbmFsIGBtc2dgIGFyZ3VtZW50IHdoaWNoIGlzIGEgY3VzdG9tIGVycm9yIG1lc3NhZ2VcbiAgICogdG8gc2hvdyB3aGVuIHRoZSBhc3NlcnRpb24gZmFpbHMuIFRoZSBtZXNzYWdlIGNhbiBhbHNvIGJlIGdpdmVuIGFzIHRoZVxuICAgKiBzZWNvbmQgYXJndW1lbnQgdG8gYGV4cGVjdGAuXG4gICAqXG4gICAqICAgICBleHBlY3QoJ2Zvb2JhcicpLnRvLm1hdGNoKC90YWNvLywgJ25vb28gd2h5IGZhaWw/PycpO1xuICAgKiAgICAgZXhwZWN0KCdmb29iYXInLCAnbm9vbyB3aHkgZmFpbD8/JykudG8ubWF0Y2goL3RhY28vKTtcbiAgICpcbiAgICogVGhlIGFsaWFzIGAubWF0Y2hlc2AgY2FuIGJlIHVzZWQgaW50ZXJjaGFuZ2VhYmx5IHdpdGggYC5tYXRjaGAuXG4gICAqXG4gICAqIEBuYW1lIG1hdGNoXG4gICAqIEBhbGlhcyBtYXRjaGVzXG4gICAqIEBwYXJhbSB7UmVnRXhwfSByZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbXNnIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG4gIGZ1bmN0aW9uIGFzc2VydE1hdGNoKHJlLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICAgIHJlLmV4ZWMob2JqKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBtYXRjaCAnICsgcmVcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gbm90IHRvIG1hdGNoICcgKyByZVxuICAgICk7XG4gIH1cblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdtYXRjaCcsIGFzc2VydE1hdGNoKTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnbWF0Y2hlcycsIGFzc2VydE1hdGNoKTtcblxuICAvKipcbiAgICogIyMjIC5zdHJpbmcoc3RyWywgbXNnXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgc3RyaW5nIGNvbnRhaW5zIHRoZSBnaXZlbiBzdWJzdHJpbmcgYHN0cmAuXG4gICAqXG4gICAqICAgICBleHBlY3QoJ2Zvb2JhcicpLnRvLmhhdmUuc3RyaW5nKCdiYXInKTtcbiAgICpcbiAgICogQWRkIGAubm90YCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byBuZWdhdGUgYC5zdHJpbmdgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KCdmb29iYXInKS50by5ub3QuaGF2ZS5zdHJpbmcoJ3RhY28nKTtcbiAgICpcbiAgICogYC5zdHJpbmdgIGFjY2VwdHMgYW4gb3B0aW9uYWwgYG1zZ2AgYXJndW1lbnQgd2hpY2ggaXMgYSBjdXN0b20gZXJyb3JcbiAgICogbWVzc2FnZSB0byBzaG93IHdoZW4gdGhlIGFzc2VydGlvbiBmYWlscy4gVGhlIG1lc3NhZ2UgY2FuIGFsc28gYmUgZ2l2ZW4gYXNcbiAgICogdGhlIHNlY29uZCBhcmd1bWVudCB0byBgZXhwZWN0YC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgnZm9vYmFyJykudG8uaGF2ZS5zdHJpbmcoJ3RhY28nLCAnbm9vbyB3aHkgZmFpbD8/Jyk7XG4gICAqICAgICBleHBlY3QoJ2Zvb2JhcicsICdub29vIHdoeSBmYWlsPz8nKS50by5oYXZlLnN0cmluZygndGFjbycpO1xuICAgKlxuICAgKiBAbmFtZSBzdHJpbmdcbiAgICogQHBhcmFtIHtTdHJpbmd9IHN0clxuICAgKiBAcGFyYW0ge1N0cmluZ30gbXNnIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnc3RyaW5nJywgZnVuY3Rpb24gKHN0ciwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAsIGZsYWdNc2cgPSBmbGFnKHRoaXMsICdtZXNzYWdlJylcbiAgICAgICwgc3NmaSA9IGZsYWcodGhpcywgJ3NzZmknKTtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgZmxhZ01zZywgc3NmaSwgdHJ1ZSkuaXMuYSgnc3RyaW5nJyk7XG5cbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgfm9iai5pbmRleE9mKHN0cilcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gY29udGFpbiAnICsgXy5pbnNwZWN0KHN0cilcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGNvbnRhaW4gJyArIF8uaW5zcGVjdChzdHIpXG4gICAgKTtcbiAgfSk7XG5cbiAgLyoqXG4gICAqICMjIyAua2V5cyhrZXkxWywga2V5MlssIC4uLl1dKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBvYmplY3QsIGFycmF5LCBtYXAsIG9yIHNldCBoYXMgdGhlIGdpdmVuIGtleXMuIE9ubHlcbiAgICogdGhlIHRhcmdldCdzIG93biBpbmhlcml0ZWQgcHJvcGVydGllcyBhcmUgaW5jbHVkZWQgaW4gdGhlIHNlYXJjaC5cbiAgICpcbiAgICogV2hlbiB0aGUgdGFyZ2V0IGlzIGFuIG9iamVjdCBvciBhcnJheSwga2V5cyBjYW4gYmUgcHJvdmlkZWQgYXMgb25lIG9yIG1vcmVcbiAgICogc3RyaW5nIGFyZ3VtZW50cywgYSBzaW5nbGUgYXJyYXkgYXJndW1lbnQsIG9yIGEgc2luZ2xlIG9iamVjdCBhcmd1bWVudC4gSW5cbiAgICogdGhlIGxhdHRlciBjYXNlLCBvbmx5IHRoZSBrZXlzIGluIHRoZSBnaXZlbiBvYmplY3QgbWF0dGVyOyB0aGUgdmFsdWVzIGFyZVxuICAgKiBpZ25vcmVkLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KHthOiAxLCBiOiAyfSkudG8uaGF2ZS5hbGwua2V5cygnYScsICdiJyk7XG4gICAqICAgICBleHBlY3QoWyd4JywgJ3knXSkudG8uaGF2ZS5hbGwua2V5cygwLCAxKTtcbiAgICpcbiAgICogICAgIGV4cGVjdCh7YTogMSwgYjogMn0pLnRvLmhhdmUuYWxsLmtleXMoWydhJywgJ2InXSk7XG4gICAqICAgICBleHBlY3QoWyd4JywgJ3knXSkudG8uaGF2ZS5hbGwua2V5cyhbMCwgMV0pO1xuICAgKlxuICAgKiAgICAgZXhwZWN0KHthOiAxLCBiOiAyfSkudG8uaGF2ZS5hbGwua2V5cyh7YTogNCwgYjogNX0pOyAvLyBpZ25vcmUgNCBhbmQgNVxuICAgKiAgICAgZXhwZWN0KFsneCcsICd5J10pLnRvLmhhdmUuYWxsLmtleXMoezA6IDQsIDE6IDV9KTsgLy8gaWdub3JlIDQgYW5kIDVcbiAgICpcbiAgICogV2hlbiB0aGUgdGFyZ2V0IGlzIGEgbWFwIG9yIHNldCwgZWFjaCBrZXkgbXVzdCBiZSBwcm92aWRlZCBhcyBhIHNlcGFyYXRlXG4gICAqIGFyZ3VtZW50LlxuICAgKlxuICAgKiAgICAgZXhwZWN0KG5ldyBNYXAoW1snYScsIDFdLCBbJ2InLCAyXV0pKS50by5oYXZlLmFsbC5rZXlzKCdhJywgJ2InKTtcbiAgICogICAgIGV4cGVjdChuZXcgU2V0KFsnYScsICdiJ10pKS50by5oYXZlLmFsbC5rZXlzKCdhJywgJ2InKTtcbiAgICpcbiAgICogQmVjYXVzZSBgLmtleXNgIGRvZXMgZGlmZmVyZW50IHRoaW5ncyBiYXNlZCBvbiB0aGUgdGFyZ2V0J3MgdHlwZSwgaXQnc1xuICAgKiBpbXBvcnRhbnQgdG8gY2hlY2sgdGhlIHRhcmdldCdzIHR5cGUgYmVmb3JlIHVzaW5nIGAua2V5c2AuIFNlZSB0aGUgYC5hYCBkb2NcbiAgICogZm9yIGluZm8gb24gdGVzdGluZyBhIHRhcmdldCdzIHR5cGUuXG4gICAqXG4gICAqICAgICBleHBlY3Qoe2E6IDEsIGI6IDJ9KS50by5iZS5hbignb2JqZWN0JykudGhhdC5oYXMuYWxsLmtleXMoJ2EnLCAnYicpO1xuICAgKlxuICAgKiBCeSBkZWZhdWx0LCBzdHJpY3QgKGA9PT1gKSBlcXVhbGl0eSBpcyB1c2VkIHRvIGNvbXBhcmUga2V5cyBvZiBtYXBzIGFuZFxuICAgKiBzZXRzLiBBZGQgYC5kZWVwYCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byB1c2UgZGVlcCBlcXVhbGl0eSBpbnN0ZWFkLiBTZWVcbiAgICogdGhlIGBkZWVwLWVxbGAgcHJvamVjdCBwYWdlIGZvciBpbmZvIG9uIHRoZSBkZWVwIGVxdWFsaXR5IGFsZ29yaXRobTpcbiAgICogaHR0cHM6Ly9naXRodWIuY29tL2NoYWlqcy9kZWVwLWVxbC5cbiAgICpcbiAgICogICAgIC8vIFRhcmdldCBzZXQgZGVlcGx5IChidXQgbm90IHN0cmljdGx5KSBoYXMga2V5IGB7YTogMX1gXG4gICAqICAgICBleHBlY3QobmV3IFNldChbe2E6IDF9XSkpLnRvLmhhdmUuYWxsLmRlZXAua2V5cyhbe2E6IDF9XSk7XG4gICAqICAgICBleHBlY3QobmV3IFNldChbe2E6IDF9XSkpLnRvLm5vdC5oYXZlLmFsbC5rZXlzKFt7YTogMX1dKTtcbiAgICpcbiAgICogQnkgZGVmYXVsdCwgdGhlIHRhcmdldCBtdXN0IGhhdmUgYWxsIG9mIHRoZSBnaXZlbiBrZXlzIGFuZCBubyBtb3JlLiBBZGRcbiAgICogYC5hbnlgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIG9ubHkgcmVxdWlyZSB0aGF0IHRoZSB0YXJnZXQgaGF2ZSBhdCBsZWFzdFxuICAgKiBvbmUgb2YgdGhlIGdpdmVuIGtleXMuIEFsc28sIGFkZCBgLm5vdGAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gbmVnYXRlXG4gICAqIGAua2V5c2AuIEl0J3Mgb2Z0ZW4gYmVzdCB0byBhZGQgYC5hbnlgIHdoZW4gbmVnYXRpbmcgYC5rZXlzYCwgYW5kIHRvIHVzZVxuICAgKiBgLmFsbGAgd2hlbiBhc3NlcnRpbmcgYC5rZXlzYCB3aXRob3V0IG5lZ2F0aW9uLlxuICAgKlxuICAgKiBXaGVuIG5lZ2F0aW5nIGAua2V5c2AsIGAuYW55YCBpcyBwcmVmZXJyZWQgYmVjYXVzZSBgLm5vdC5hbnkua2V5c2AgYXNzZXJ0c1xuICAgKiBleGFjdGx5IHdoYXQncyBleHBlY3RlZCBvZiB0aGUgb3V0cHV0LCB3aGVyZWFzIGAubm90LmFsbC5rZXlzYCBjcmVhdGVzXG4gICAqIHVuY2VydGFpbiBleHBlY3RhdGlvbnMuXG4gICAqXG4gICAqICAgICAvLyBSZWNvbW1lbmRlZDsgYXNzZXJ0cyB0aGF0IHRhcmdldCBkb2Vzbid0IGhhdmUgYW55IG9mIHRoZSBnaXZlbiBrZXlzXG4gICAqICAgICBleHBlY3Qoe2E6IDEsIGI6IDJ9KS50by5ub3QuaGF2ZS5hbnkua2V5cygnYycsICdkJyk7XG4gICAqXG4gICAqICAgICAvLyBOb3QgcmVjb21tZW5kZWQ7IGFzc2VydHMgdGhhdCB0YXJnZXQgZG9lc24ndCBoYXZlIGFsbCBvZiB0aGUgZ2l2ZW5cbiAgICogICAgIC8vIGtleXMgYnV0IG1heSBvciBtYXkgbm90IGhhdmUgc29tZSBvZiB0aGVtXG4gICAqICAgICBleHBlY3Qoe2E6IDEsIGI6IDJ9KS50by5ub3QuaGF2ZS5hbGwua2V5cygnYycsICdkJyk7XG4gICAqXG4gICAqIFdoZW4gYXNzZXJ0aW5nIGAua2V5c2Agd2l0aG91dCBuZWdhdGlvbiwgYC5hbGxgIGlzIHByZWZlcnJlZCBiZWNhdXNlXG4gICAqIGAuYWxsLmtleXNgIGFzc2VydHMgZXhhY3RseSB3aGF0J3MgZXhwZWN0ZWQgb2YgdGhlIG91dHB1dCwgd2hlcmVhc1xuICAgKiBgLmFueS5rZXlzYCBjcmVhdGVzIHVuY2VydGFpbiBleHBlY3RhdGlvbnMuXG4gICAqXG4gICAqICAgICAvLyBSZWNvbW1lbmRlZDsgYXNzZXJ0cyB0aGF0IHRhcmdldCBoYXMgYWxsIHRoZSBnaXZlbiBrZXlzXG4gICAqICAgICBleHBlY3Qoe2E6IDEsIGI6IDJ9KS50by5oYXZlLmFsbC5rZXlzKCdhJywgJ2InKTtcbiAgICpcbiAgICogICAgIC8vIE5vdCByZWNvbW1lbmRlZDsgYXNzZXJ0cyB0aGF0IHRhcmdldCBoYXMgYXQgbGVhc3Qgb25lIG9mIHRoZSBnaXZlblxuICAgKiAgICAgLy8ga2V5cyBidXQgbWF5IG9yIG1heSBub3QgaGF2ZSBtb3JlIG9mIHRoZW1cbiAgICogICAgIGV4cGVjdCh7YTogMSwgYjogMn0pLnRvLmhhdmUuYW55LmtleXMoJ2EnLCAnYicpO1xuICAgKlxuICAgKiBOb3RlIHRoYXQgYC5hbGxgIGlzIHVzZWQgYnkgZGVmYXVsdCB3aGVuIG5laXRoZXIgYC5hbGxgIG5vciBgLmFueWAgYXBwZWFyXG4gICAqIGVhcmxpZXIgaW4gdGhlIGNoYWluLiBIb3dldmVyLCBpdCdzIG9mdGVuIGJlc3QgdG8gYWRkIGAuYWxsYCBhbnl3YXkgYmVjYXVzZVxuICAgKiBpdCBpbXByb3ZlcyByZWFkYWJpbGl0eS5cbiAgICpcbiAgICogICAgIC8vIEJvdGggYXNzZXJ0aW9ucyBhcmUgaWRlbnRpY2FsXG4gICAqICAgICBleHBlY3Qoe2E6IDEsIGI6IDJ9KS50by5oYXZlLmFsbC5rZXlzKCdhJywgJ2InKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCh7YTogMSwgYjogMn0pLnRvLmhhdmUua2V5cygnYScsICdiJyk7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBBZGQgYC5pbmNsdWRlYCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byByZXF1aXJlIHRoYXQgdGhlIHRhcmdldCdzIGtleXMgYmUgYVxuICAgKiBzdXBlcnNldCBvZiB0aGUgZXhwZWN0ZWQga2V5cywgcmF0aGVyIHRoYW4gaWRlbnRpY2FsIHNldHMuXG4gICAqXG4gICAqICAgICAvLyBUYXJnZXQgb2JqZWN0J3Mga2V5cyBhcmUgYSBzdXBlcnNldCBvZiBbJ2EnLCAnYiddIGJ1dCBub3QgaWRlbnRpY2FsXG4gICAqICAgICBleHBlY3Qoe2E6IDEsIGI6IDIsIGM6IDN9KS50by5pbmNsdWRlLmFsbC5rZXlzKCdhJywgJ2InKTtcbiAgICogICAgIGV4cGVjdCh7YTogMSwgYjogMiwgYzogM30pLnRvLm5vdC5oYXZlLmFsbC5rZXlzKCdhJywgJ2InKTtcbiAgICpcbiAgICogSG93ZXZlciwgaWYgYC5hbnlgIGFuZCBgLmluY2x1ZGVgIGFyZSBjb21iaW5lZCwgb25seSB0aGUgYC5hbnlgIHRha2VzXG4gICAqIGVmZmVjdC4gVGhlIGAuaW5jbHVkZWAgaXMgaWdub3JlZCBpbiB0aGlzIGNhc2UuXG4gICAqXG4gICAqICAgICAvLyBCb3RoIGFzc2VydGlvbnMgYXJlIGlkZW50aWNhbFxuICAgKiAgICAgZXhwZWN0KHthOiAxfSkudG8uaGF2ZS5hbnkua2V5cygnYScsICdiJyk7XG4gICAqICAgICBleHBlY3Qoe2E6IDF9KS50by5pbmNsdWRlLmFueS5rZXlzKCdhJywgJ2InKTtcbiAgICpcbiAgICogQSBjdXN0b20gZXJyb3IgbWVzc2FnZSBjYW4gYmUgZ2l2ZW4gYXMgdGhlIHNlY29uZCBhcmd1bWVudCB0byBgZXhwZWN0YC5cbiAgICpcbiAgICogICAgIGV4cGVjdCh7YTogMX0sICdub29vIHdoeSBmYWlsPz8nKS50by5oYXZlLmtleSgnYicpO1xuICAgKlxuICAgKiBUaGUgYWxpYXMgYC5rZXlgIGNhbiBiZSB1c2VkIGludGVyY2hhbmdlYWJseSB3aXRoIGAua2V5c2AuXG4gICAqXG4gICAqIEBuYW1lIGtleXNcbiAgICogQGFsaWFzIGtleVxuICAgKiBAcGFyYW0gey4uLlN0cmluZ3xBcnJheXxPYmplY3R9IGtleXNcbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gYXNzZXJ0S2V5cyAoa2V5cykge1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCBvYmpUeXBlID0gXy50eXBlKG9iailcbiAgICAgICwga2V5c1R5cGUgPSBfLnR5cGUoa2V5cylcbiAgICAgICwgc3NmaSA9IGZsYWcodGhpcywgJ3NzZmknKVxuICAgICAgLCBpc0RlZXAgPSBmbGFnKHRoaXMsICdkZWVwJylcbiAgICAgICwgc3RyXG4gICAgICAsIGRlZXBTdHIgPSAnJ1xuICAgICAgLCBhY3R1YWxcbiAgICAgICwgb2sgPSB0cnVlXG4gICAgICAsIGZsYWdNc2cgPSBmbGFnKHRoaXMsICdtZXNzYWdlJyk7XG5cbiAgICBmbGFnTXNnID0gZmxhZ01zZyA/IGZsYWdNc2cgKyAnOiAnIDogJyc7XG4gICAgdmFyIG1peGVkQXJnc01zZyA9IGZsYWdNc2cgKyAnd2hlbiB0ZXN0aW5nIGtleXMgYWdhaW5zdCBhbiBvYmplY3Qgb3IgYW4gYXJyYXkgeW91IG11c3QgZ2l2ZSBhIHNpbmdsZSBBcnJheXxPYmplY3R8U3RyaW5nIGFyZ3VtZW50IG9yIG11bHRpcGxlIFN0cmluZyBhcmd1bWVudHMnO1xuXG4gICAgaWYgKG9ialR5cGUgPT09ICdNYXAnIHx8IG9ialR5cGUgPT09ICdTZXQnKSB7XG4gICAgICBkZWVwU3RyID0gaXNEZWVwID8gJ2RlZXBseSAnIDogJyc7XG4gICAgICBhY3R1YWwgPSBbXTtcblxuICAgICAgLy8gTWFwIGFuZCBTZXQgJy5rZXlzJyBhcmVuJ3Qgc3VwcG9ydGVkIGluIElFIDExLiBUaGVyZWZvcmUsIHVzZSAuZm9yRWFjaC5cbiAgICAgIG9iai5mb3JFYWNoKGZ1bmN0aW9uICh2YWwsIGtleSkgeyBhY3R1YWwucHVzaChrZXkpIH0pO1xuXG4gICAgICBpZiAoa2V5c1R5cGUgIT09ICdBcnJheScpIHtcbiAgICAgICAga2V5cyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGFjdHVhbCA9IF8uZ2V0T3duRW51bWVyYWJsZVByb3BlcnRpZXMob2JqKTtcblxuICAgICAgc3dpdGNoIChrZXlzVHlwZSkge1xuICAgICAgICBjYXNlICdBcnJheSc6XG4gICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IobWl4ZWRBcmdzTXNnLCB1bmRlZmluZWQsIHNzZmkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnT2JqZWN0JzpcbiAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihtaXhlZEFyZ3NNc2csIHVuZGVmaW5lZCwgc3NmaSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGtleXMgPSBPYmplY3Qua2V5cyhrZXlzKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBrZXlzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcbiAgICAgIH1cblxuICAgICAgLy8gT25seSBzdHJpbmdpZnkgbm9uLVN5bWJvbHMgYmVjYXVzZSBTeW1ib2xzIHdvdWxkIGJlY29tZSBcIlN5bWJvbCgpXCJcbiAgICAgIGtleXMgPSBrZXlzLm1hcChmdW5jdGlvbiAodmFsKSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgdmFsID09PSAnc3ltYm9sJyA/IHZhbCA6IFN0cmluZyh2YWwpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKCFrZXlzLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKGZsYWdNc2cgKyAna2V5cyByZXF1aXJlZCcsIHVuZGVmaW5lZCwgc3NmaSk7XG4gICAgfVxuXG4gICAgdmFyIGxlbiA9IGtleXMubGVuZ3RoXG4gICAgICAsIGFueSA9IGZsYWcodGhpcywgJ2FueScpXG4gICAgICAsIGFsbCA9IGZsYWcodGhpcywgJ2FsbCcpXG4gICAgICAsIGV4cGVjdGVkID0ga2V5cztcblxuICAgIGlmICghYW55ICYmICFhbGwpIHtcbiAgICAgIGFsbCA9IHRydWU7XG4gICAgfVxuXG4gICAgLy8gSGFzIGFueVxuICAgIGlmIChhbnkpIHtcbiAgICAgIG9rID0gZXhwZWN0ZWQuc29tZShmdW5jdGlvbihleHBlY3RlZEtleSkge1xuICAgICAgICByZXR1cm4gYWN0dWFsLnNvbWUoZnVuY3Rpb24oYWN0dWFsS2V5KSB7XG4gICAgICAgICAgaWYgKGlzRGVlcCkge1xuICAgICAgICAgICAgcmV0dXJuIF8uZXFsKGV4cGVjdGVkS2V5LCBhY3R1YWxLZXkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gZXhwZWN0ZWRLZXkgPT09IGFjdHVhbEtleTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gSGFzIGFsbFxuICAgIGlmIChhbGwpIHtcbiAgICAgIG9rID0gZXhwZWN0ZWQuZXZlcnkoZnVuY3Rpb24oZXhwZWN0ZWRLZXkpIHtcbiAgICAgICAgcmV0dXJuIGFjdHVhbC5zb21lKGZ1bmN0aW9uKGFjdHVhbEtleSkge1xuICAgICAgICAgIGlmIChpc0RlZXApIHtcbiAgICAgICAgICAgIHJldHVybiBfLmVxbChleHBlY3RlZEtleSwgYWN0dWFsS2V5KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGV4cGVjdGVkS2V5ID09PSBhY3R1YWxLZXk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBpZiAoIWZsYWcodGhpcywgJ2NvbnRhaW5zJykpIHtcbiAgICAgICAgb2sgPSBvayAmJiBrZXlzLmxlbmd0aCA9PSBhY3R1YWwubGVuZ3RoO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEtleSBzdHJpbmdcbiAgICBpZiAobGVuID4gMSkge1xuICAgICAga2V5cyA9IGtleXMubWFwKGZ1bmN0aW9uKGtleSkge1xuICAgICAgICByZXR1cm4gXy5pbnNwZWN0KGtleSk7XG4gICAgICB9KTtcbiAgICAgIHZhciBsYXN0ID0ga2V5cy5wb3AoKTtcbiAgICAgIGlmIChhbGwpIHtcbiAgICAgICAgc3RyID0ga2V5cy5qb2luKCcsICcpICsgJywgYW5kICcgKyBsYXN0O1xuICAgICAgfVxuICAgICAgaWYgKGFueSkge1xuICAgICAgICBzdHIgPSBrZXlzLmpvaW4oJywgJykgKyAnLCBvciAnICsgbGFzdDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc3RyID0gXy5pbnNwZWN0KGtleXNbMF0pO1xuICAgIH1cblxuICAgIC8vIEZvcm1cbiAgICBzdHIgPSAobGVuID4gMSA/ICdrZXlzICcgOiAna2V5ICcpICsgc3RyO1xuXG4gICAgLy8gSGF2ZSAvIGluY2x1ZGVcbiAgICBzdHIgPSAoZmxhZyh0aGlzLCAnY29udGFpbnMnKSA/ICdjb250YWluICcgOiAnaGF2ZSAnKSArIHN0cjtcblxuICAgIC8vIEFzc2VydGlvblxuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICBva1xuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byAnICsgZGVlcFN0ciArIHN0clxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgJyArIGRlZXBTdHIgKyBzdHJcbiAgICAgICwgZXhwZWN0ZWQuc2xpY2UoMCkuc29ydChfLmNvbXBhcmVCeUluc3BlY3QpXG4gICAgICAsIGFjdHVhbC5zb3J0KF8uY29tcGFyZUJ5SW5zcGVjdClcbiAgICAgICwgdHJ1ZVxuICAgICk7XG4gIH1cblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdrZXlzJywgYXNzZXJ0S2V5cyk7XG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2tleScsIGFzc2VydEtleXMpO1xuXG4gIC8qKlxuICAgKiAjIyMgLnRocm93KFtlcnJvckxpa2VdLCBbZXJyTXNnTWF0Y2hlcl0sIFttc2ddKVxuICAgKlxuICAgKiBXaGVuIG5vIGFyZ3VtZW50cyBhcmUgcHJvdmlkZWQsIGAudGhyb3dgIGludm9rZXMgdGhlIHRhcmdldCBmdW5jdGlvbiBhbmRcbiAgICogYXNzZXJ0cyB0aGF0IGFuIGVycm9yIGlzIHRocm93bi5cbiAgICpcbiAgICogICAgIHZhciBiYWRGbiA9IGZ1bmN0aW9uICgpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignSWxsZWdhbCBzYWxtb24hJyk7IH07XG4gICAqXG4gICAqICAgICBleHBlY3QoYmFkRm4pLnRvLnRocm93KCk7XG4gICAqXG4gICAqIFdoZW4gb25lIGFyZ3VtZW50IGlzIHByb3ZpZGVkLCBhbmQgaXQncyBhbiBlcnJvciBjb25zdHJ1Y3RvciwgYC50aHJvd2BcbiAgICogaW52b2tlcyB0aGUgdGFyZ2V0IGZ1bmN0aW9uIGFuZCBhc3NlcnRzIHRoYXQgYW4gZXJyb3IgaXMgdGhyb3duIHRoYXQncyBhblxuICAgKiBpbnN0YW5jZSBvZiB0aGF0IGVycm9yIGNvbnN0cnVjdG9yLlxuICAgKlxuICAgKiAgICAgdmFyIGJhZEZuID0gZnVuY3Rpb24gKCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbGxlZ2FsIHNhbG1vbiEnKTsgfTtcbiAgICpcbiAgICogICAgIGV4cGVjdChiYWRGbikudG8udGhyb3coVHlwZUVycm9yKTtcbiAgICpcbiAgICogV2hlbiBvbmUgYXJndW1lbnQgaXMgcHJvdmlkZWQsIGFuZCBpdCdzIGFuIGVycm9yIGluc3RhbmNlLCBgLnRocm93YCBpbnZva2VzXG4gICAqIHRoZSB0YXJnZXQgZnVuY3Rpb24gYW5kIGFzc2VydHMgdGhhdCBhbiBlcnJvciBpcyB0aHJvd24gdGhhdCdzIHN0cmljdGx5XG4gICAqIChgPT09YCkgZXF1YWwgdG8gdGhhdCBlcnJvciBpbnN0YW5jZS5cbiAgICpcbiAgICogICAgIHZhciBlcnIgPSBuZXcgVHlwZUVycm9yKCdJbGxlZ2FsIHNhbG1vbiEnKTtcbiAgICogICAgIHZhciBiYWRGbiA9IGZ1bmN0aW9uICgpIHsgdGhyb3cgZXJyOyB9O1xuICAgKlxuICAgKiAgICAgZXhwZWN0KGJhZEZuKS50by50aHJvdyhlcnIpO1xuICAgKlxuICAgKiBXaGVuIG9uZSBhcmd1bWVudCBpcyBwcm92aWRlZCwgYW5kIGl0J3MgYSBzdHJpbmcsIGAudGhyb3dgIGludm9rZXMgdGhlXG4gICAqIHRhcmdldCBmdW5jdGlvbiBhbmQgYXNzZXJ0cyB0aGF0IGFuIGVycm9yIGlzIHRocm93biB3aXRoIGEgbWVzc2FnZSB0aGF0XG4gICAqIGNvbnRhaW5zIHRoYXQgc3RyaW5nLlxuICAgKlxuICAgKiAgICAgdmFyIGJhZEZuID0gZnVuY3Rpb24gKCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbGxlZ2FsIHNhbG1vbiEnKTsgfTtcbiAgICpcbiAgICogICAgIGV4cGVjdChiYWRGbikudG8udGhyb3coJ3NhbG1vbicpO1xuICAgKlxuICAgKiBXaGVuIG9uZSBhcmd1bWVudCBpcyBwcm92aWRlZCwgYW5kIGl0J3MgYSByZWd1bGFyIGV4cHJlc3Npb24sIGAudGhyb3dgXG4gICAqIGludm9rZXMgdGhlIHRhcmdldCBmdW5jdGlvbiBhbmQgYXNzZXJ0cyB0aGF0IGFuIGVycm9yIGlzIHRocm93biB3aXRoIGFcbiAgICogbWVzc2FnZSB0aGF0IG1hdGNoZXMgdGhhdCByZWd1bGFyIGV4cHJlc3Npb24uXG4gICAqXG4gICAqICAgICB2YXIgYmFkRm4gPSBmdW5jdGlvbiAoKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ0lsbGVnYWwgc2FsbW9uIScpOyB9O1xuICAgKlxuICAgKiAgICAgZXhwZWN0KGJhZEZuKS50by50aHJvdygvc2FsbW9uLyk7XG4gICAqXG4gICAqIFdoZW4gdHdvIGFyZ3VtZW50cyBhcmUgcHJvdmlkZWQsIGFuZCB0aGUgZmlyc3QgaXMgYW4gZXJyb3IgaW5zdGFuY2Ugb3JcbiAgICogY29uc3RydWN0b3IsIGFuZCB0aGUgc2Vjb25kIGlzIGEgc3RyaW5nIG9yIHJlZ3VsYXIgZXhwcmVzc2lvbiwgYC50aHJvd2BcbiAgICogaW52b2tlcyB0aGUgZnVuY3Rpb24gYW5kIGFzc2VydHMgdGhhdCBhbiBlcnJvciBpcyB0aHJvd24gdGhhdCBmdWxmaWxscyBib3RoXG4gICAqIGNvbmRpdGlvbnMgYXMgZGVzY3JpYmVkIGFib3ZlLlxuICAgKlxuICAgKiAgICAgdmFyIGVyciA9IG5ldyBUeXBlRXJyb3IoJ0lsbGVnYWwgc2FsbW9uIScpO1xuICAgKiAgICAgdmFyIGJhZEZuID0gZnVuY3Rpb24gKCkgeyB0aHJvdyBlcnI7IH07XG4gICAqXG4gICAqICAgICBleHBlY3QoYmFkRm4pLnRvLnRocm93KFR5cGVFcnJvciwgJ3NhbG1vbicpO1xuICAgKiAgICAgZXhwZWN0KGJhZEZuKS50by50aHJvdyhUeXBlRXJyb3IsIC9zYWxtb24vKTtcbiAgICogICAgIGV4cGVjdChiYWRGbikudG8udGhyb3coZXJyLCAnc2FsbW9uJyk7XG4gICAqICAgICBleHBlY3QoYmFkRm4pLnRvLnRocm93KGVyciwgL3NhbG1vbi8pO1xuICAgKlxuICAgKiBBZGQgYC5ub3RgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIG5lZ2F0ZSBgLnRocm93YC5cbiAgICpcbiAgICogICAgIHZhciBnb29kRm4gPSBmdW5jdGlvbiAoKSB7fTtcbiAgICpcbiAgICogICAgIGV4cGVjdChnb29kRm4pLnRvLm5vdC50aHJvdygpO1xuICAgKlxuICAgKiBIb3dldmVyLCBpdCdzIGRhbmdlcm91cyB0byBuZWdhdGUgYC50aHJvd2Agd2hlbiBwcm92aWRpbmcgYW55IGFyZ3VtZW50cy5cbiAgICogVGhlIHByb2JsZW0gaXMgdGhhdCBpdCBjcmVhdGVzIHVuY2VydGFpbiBleHBlY3RhdGlvbnMgYnkgYXNzZXJ0aW5nIHRoYXQgdGhlXG4gICAqIHRhcmdldCBlaXRoZXIgZG9lc24ndCB0aHJvdyBhbiBlcnJvciwgb3IgdGhhdCBpdCB0aHJvd3MgYW4gZXJyb3IgYnV0IG9mIGFcbiAgICogZGlmZmVyZW50IHR5cGUgdGhhbiB0aGUgZ2l2ZW4gdHlwZSwgb3IgdGhhdCBpdCB0aHJvd3MgYW4gZXJyb3Igb2YgdGhlIGdpdmVuXG4gICAqIHR5cGUgYnV0IHdpdGggYSBtZXNzYWdlIHRoYXQgZG9lc24ndCBpbmNsdWRlIHRoZSBnaXZlbiBzdHJpbmcuIEl0J3Mgb2Z0ZW5cbiAgICogYmVzdCB0byBpZGVudGlmeSB0aGUgZXhhY3Qgb3V0cHV0IHRoYXQncyBleHBlY3RlZCwgYW5kIHRoZW4gd3JpdGUgYW5cbiAgICogYXNzZXJ0aW9uIHRoYXQgb25seSBhY2NlcHRzIHRoYXQgZXhhY3Qgb3V0cHV0LlxuICAgKlxuICAgKiBXaGVuIHRoZSB0YXJnZXQgaXNuJ3QgZXhwZWN0ZWQgdG8gdGhyb3cgYW4gZXJyb3IsIGl0J3Mgb2Z0ZW4gYmVzdCB0byBhc3NlcnRcbiAgICogZXhhY3RseSB0aGF0LlxuICAgKlxuICAgKiAgICAgdmFyIGdvb2RGbiA9IGZ1bmN0aW9uICgpIHt9O1xuICAgKlxuICAgKiAgICAgZXhwZWN0KGdvb2RGbikudG8ubm90LnRocm93KCk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoZ29vZEZuKS50by5ub3QudGhyb3coUmVmZXJlbmNlRXJyb3IsICd4Jyk7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBXaGVuIHRoZSB0YXJnZXQgaXMgZXhwZWN0ZWQgdG8gdGhyb3cgYW4gZXJyb3IsIGl0J3Mgb2Z0ZW4gYmVzdCB0byBhc3NlcnRcbiAgICogdGhhdCB0aGUgZXJyb3IgaXMgb2YgaXRzIGV4cGVjdGVkIHR5cGUsIGFuZCBoYXMgYSBtZXNzYWdlIHRoYXQgaW5jbHVkZXMgYW5cbiAgICogZXhwZWN0ZWQgc3RyaW5nLCByYXRoZXIgdGhhbiBhc3NlcnRpbmcgdGhhdCBpdCBkb2Vzbid0IGhhdmUgb25lIG9mIG1hbnlcbiAgICogdW5leHBlY3RlZCB0eXBlcywgYW5kIGRvZXNuJ3QgaGF2ZSBhIG1lc3NhZ2UgdGhhdCBpbmNsdWRlcyBzb21lIHN0cmluZy5cbiAgICpcbiAgICogICAgIHZhciBiYWRGbiA9IGZ1bmN0aW9uICgpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignSWxsZWdhbCBzYWxtb24hJyk7IH07XG4gICAqXG4gICAqICAgICBleHBlY3QoYmFkRm4pLnRvLnRocm93KFR5cGVFcnJvciwgJ3NhbG1vbicpOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KGJhZEZuKS50by5ub3QudGhyb3coUmVmZXJlbmNlRXJyb3IsICd4Jyk7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBgLnRocm93YCBjaGFuZ2VzIHRoZSB0YXJnZXQgb2YgYW55IGFzc2VydGlvbnMgdGhhdCBmb2xsb3cgaW4gdGhlIGNoYWluIHRvXG4gICAqIGJlIHRoZSBlcnJvciBvYmplY3QgdGhhdCdzIHRocm93bi5cbiAgICpcbiAgICogICAgIHZhciBlcnIgPSBuZXcgVHlwZUVycm9yKCdJbGxlZ2FsIHNhbG1vbiEnKTtcbiAgICogICAgIGVyci5jb2RlID0gNDI7XG4gICAqICAgICB2YXIgYmFkRm4gPSBmdW5jdGlvbiAoKSB7IHRocm93IGVycjsgfTtcbiAgICpcbiAgICogICAgIGV4cGVjdChiYWRGbikudG8udGhyb3coVHlwZUVycm9yKS53aXRoLnByb3BlcnR5KCdjb2RlJywgNDIpO1xuICAgKlxuICAgKiBgLnRocm93YCBhY2NlcHRzIGFuIG9wdGlvbmFsIGBtc2dgIGFyZ3VtZW50IHdoaWNoIGlzIGEgY3VzdG9tIGVycm9yIG1lc3NhZ2VcbiAgICogdG8gc2hvdyB3aGVuIHRoZSBhc3NlcnRpb24gZmFpbHMuIFRoZSBtZXNzYWdlIGNhbiBhbHNvIGJlIGdpdmVuIGFzIHRoZVxuICAgKiBzZWNvbmQgYXJndW1lbnQgdG8gYGV4cGVjdGAuIFdoZW4gbm90IHByb3ZpZGluZyB0d28gYXJndW1lbnRzLCBhbHdheXMgdXNlXG4gICAqIHRoZSBzZWNvbmQgZm9ybS5cbiAgICpcbiAgICogICAgIHZhciBnb29kRm4gPSBmdW5jdGlvbiAoKSB7fTtcbiAgICpcbiAgICogICAgIGV4cGVjdChnb29kRm4pLnRvLnRocm93KFR5cGVFcnJvciwgJ3gnLCAnbm9vbyB3aHkgZmFpbD8/Jyk7XG4gICAqICAgICBleHBlY3QoZ29vZEZuLCAnbm9vbyB3aHkgZmFpbD8/JykudG8udGhyb3coKTtcbiAgICpcbiAgICogRHVlIHRvIGxpbWl0YXRpb25zIGluIEVTNSwgYC50aHJvd2AgbWF5IG5vdCBhbHdheXMgd29yayBhcyBleHBlY3RlZCB3aGVuXG4gICAqIHVzaW5nIGEgdHJhbnNwaWxlciBzdWNoIGFzIEJhYmVsIG9yIFR5cGVTY3JpcHQuIEluIHBhcnRpY3VsYXIsIGl0IG1heVxuICAgKiBwcm9kdWNlIHVuZXhwZWN0ZWQgcmVzdWx0cyB3aGVuIHN1YmNsYXNzaW5nIHRoZSBidWlsdC1pbiBgRXJyb3JgIG9iamVjdCBhbmRcbiAgICogdGhlbiBwYXNzaW5nIHRoZSBzdWJjbGFzc2VkIGNvbnN0cnVjdG9yIHRvIGAudGhyb3dgLiBTZWUgeW91ciB0cmFuc3BpbGVyJ3NcbiAgICogZG9jcyBmb3IgZGV0YWlsczpcbiAgICpcbiAgICogLSAoW0JhYmVsXShodHRwczovL2JhYmVsanMuaW8vZG9jcy91c2FnZS9jYXZlYXRzLyNjbGFzc2VzKSlcbiAgICogLSAoW1R5cGVTY3JpcHRdKGh0dHBzOi8vZ2l0aHViLmNvbS9NaWNyb3NvZnQvVHlwZVNjcmlwdC93aWtpL0JyZWFraW5nLUNoYW5nZXMjZXh0ZW5kaW5nLWJ1aWx0LWlucy1saWtlLWVycm9yLWFycmF5LWFuZC1tYXAtbWF5LW5vLWxvbmdlci13b3JrKSlcbiAgICpcbiAgICogQmV3YXJlIG9mIHNvbWUgY29tbW9uIG1pc3Rha2VzIHdoZW4gdXNpbmcgdGhlIGB0aHJvd2AgYXNzZXJ0aW9uLiBPbmUgY29tbW9uXG4gICAqIG1pc3Rha2UgaXMgdG8gYWNjaWRlbnRhbGx5IGludm9rZSB0aGUgZnVuY3Rpb24geW91cnNlbGYgaW5zdGVhZCBvZiBsZXR0aW5nXG4gICAqIHRoZSBgdGhyb3dgIGFzc2VydGlvbiBpbnZva2UgdGhlIGZ1bmN0aW9uIGZvciB5b3UuIEZvciBleGFtcGxlLCB3aGVuXG4gICAqIHRlc3RpbmcgaWYgYSBmdW5jdGlvbiBuYW1lZCBgZm5gIHRocm93cywgcHJvdmlkZSBgZm5gIGluc3RlYWQgb2YgYGZuKClgIGFzXG4gICAqIHRoZSB0YXJnZXQgZm9yIHRoZSBhc3NlcnRpb24uXG4gICAqXG4gICAqICAgICBleHBlY3QoZm4pLnRvLnRocm93KCk7ICAgICAvLyBHb29kISBUZXN0cyBgZm5gIGFzIGRlc2lyZWRcbiAgICogICAgIGV4cGVjdChmbigpKS50by50aHJvdygpOyAgIC8vIEJhZCEgVGVzdHMgcmVzdWx0IG9mIGBmbigpYCwgbm90IGBmbmBcbiAgICpcbiAgICogSWYgeW91IG5lZWQgdG8gYXNzZXJ0IHRoYXQgeW91ciBmdW5jdGlvbiBgZm5gIHRocm93cyB3aGVuIHBhc3NlZCBjZXJ0YWluXG4gICAqIGFyZ3VtZW50cywgdGhlbiB3cmFwIGEgY2FsbCB0byBgZm5gIGluc2lkZSBvZiBhbm90aGVyIGZ1bmN0aW9uLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KGZ1bmN0aW9uICgpIHsgZm4oNDIpOyB9KS50by50aHJvdygpOyAgLy8gRnVuY3Rpb24gZXhwcmVzc2lvblxuICAgKiAgICAgZXhwZWN0KCgpID0+IGZuKDQyKSkudG8udGhyb3coKTsgICAgICAgICAgICAgLy8gRVM2IGFycm93IGZ1bmN0aW9uXG4gICAqXG4gICAqIEFub3RoZXIgY29tbW9uIG1pc3Rha2UgaXMgdG8gcHJvdmlkZSBhbiBvYmplY3QgbWV0aG9kIChvciBhbnkgc3RhbmQtYWxvbmVcbiAgICogZnVuY3Rpb24gdGhhdCByZWxpZXMgb24gYHRoaXNgKSBhcyB0aGUgdGFyZ2V0IG9mIHRoZSBhc3NlcnRpb24uIERvaW5nIHNvIGlzXG4gICAqIHByb2JsZW1hdGljIGJlY2F1c2UgdGhlIGB0aGlzYCBjb250ZXh0IHdpbGwgYmUgbG9zdCB3aGVuIHRoZSBmdW5jdGlvbiBpc1xuICAgKiBpbnZva2VkIGJ5IGAudGhyb3dgOyB0aGVyZSdzIG5vIHdheSBmb3IgaXQgdG8ga25vdyB3aGF0IGB0aGlzYCBpcyBzdXBwb3NlZFxuICAgKiB0byBiZS4gVGhlcmUgYXJlIHR3byB3YXlzIGFyb3VuZCB0aGlzIHByb2JsZW0uIE9uZSBzb2x1dGlvbiBpcyB0byB3cmFwIHRoZVxuICAgKiBtZXRob2Qgb3IgZnVuY3Rpb24gY2FsbCBpbnNpZGUgb2YgYW5vdGhlciBmdW5jdGlvbi4gQW5vdGhlciBzb2x1dGlvbiBpcyB0b1xuICAgKiB1c2UgYGJpbmRgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KGZ1bmN0aW9uICgpIHsgY2F0Lm1lb3coKTsgfSkudG8udGhyb3coKTsgIC8vIEZ1bmN0aW9uIGV4cHJlc3Npb25cbiAgICogICAgIGV4cGVjdCgoKSA9PiBjYXQubWVvdygpKS50by50aHJvdygpOyAgICAgICAgICAgICAvLyBFUzYgYXJyb3cgZnVuY3Rpb25cbiAgICogICAgIGV4cGVjdChjYXQubWVvdy5iaW5kKGNhdCkpLnRvLnRocm93KCk7ICAgICAgICAgICAvLyBCaW5kXG4gICAqXG4gICAqIEZpbmFsbHksIGl0J3Mgd29ydGggbWVudGlvbmluZyB0aGF0IGl0J3MgYSBiZXN0IHByYWN0aWNlIGluIEphdmFTY3JpcHQgdG9cbiAgICogb25seSB0aHJvdyBgRXJyb3JgIGFuZCBkZXJpdmF0aXZlcyBvZiBgRXJyb3JgIHN1Y2ggYXMgYFJlZmVyZW5jZUVycm9yYCxcbiAgICogYFR5cGVFcnJvcmAsIGFuZCB1c2VyLWRlZmluZWQgb2JqZWN0cyB0aGF0IGV4dGVuZCBgRXJyb3JgLiBObyBvdGhlciB0eXBlIG9mXG4gICAqIHZhbHVlIHdpbGwgZ2VuZXJhdGUgYSBzdGFjayB0cmFjZSB3aGVuIGluaXRpYWxpemVkLiBXaXRoIHRoYXQgc2FpZCwgdGhlXG4gICAqIGB0aHJvd2AgYXNzZXJ0aW9uIGRvZXMgdGVjaG5pY2FsbHkgc3VwcG9ydCBhbnkgdHlwZSBvZiB2YWx1ZSBiZWluZyB0aHJvd24sXG4gICAqIG5vdCBqdXN0IGBFcnJvcmAgYW5kIGl0cyBkZXJpdmF0aXZlcy5cbiAgICpcbiAgICogVGhlIGFsaWFzZXMgYC50aHJvd3NgIGFuZCBgLlRocm93YCBjYW4gYmUgdXNlZCBpbnRlcmNoYW5nZWFibHkgd2l0aFxuICAgKiBgLnRocm93YC5cbiAgICpcbiAgICogQG5hbWUgdGhyb3dcbiAgICogQGFsaWFzIHRocm93c1xuICAgKiBAYWxpYXMgVGhyb3dcbiAgICogQHBhcmFtIHtFcnJvcnxFcnJvckNvbnN0cnVjdG9yfSBlcnJvckxpa2VcbiAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBlcnJNc2dNYXRjaGVyIGVycm9yIG1lc3NhZ2VcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1zZyBfb3B0aW9uYWxfXG4gICAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4vSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvRXJyb3IjRXJyb3JfdHlwZXNcbiAgICogQHJldHVybnMgZXJyb3IgZm9yIGNoYWluaW5nIChudWxsIGlmIG5vIGVycm9yKVxuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBhc3NlcnRUaHJvd3MgKGVycm9yTGlrZSwgZXJyTXNnTWF0Y2hlciwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAsIHNzZmkgPSBmbGFnKHRoaXMsICdzc2ZpJylcbiAgICAgICwgZmxhZ01zZyA9IGZsYWcodGhpcywgJ21lc3NhZ2UnKVxuICAgICAgLCBuZWdhdGUgPSBmbGFnKHRoaXMsICduZWdhdGUnKSB8fCBmYWxzZTtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgZmxhZ01zZywgc3NmaSwgdHJ1ZSkuaXMuYSgnZnVuY3Rpb24nKTtcblxuICAgIGlmIChlcnJvckxpa2UgaW5zdGFuY2VvZiBSZWdFeHAgfHwgdHlwZW9mIGVycm9yTGlrZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGVyck1zZ01hdGNoZXIgPSBlcnJvckxpa2U7XG4gICAgICBlcnJvckxpa2UgPSBudWxsO1xuICAgIH1cblxuICAgIHZhciBjYXVnaHRFcnI7XG4gICAgdHJ5IHtcbiAgICAgIG9iaigpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgY2F1Z2h0RXJyID0gZXJyO1xuICAgIH1cblxuICAgIC8vIElmIHdlIGhhdmUgdGhlIG5lZ2F0ZSBmbGFnIGVuYWJsZWQgYW5kIGF0IGxlYXN0IG9uZSB2YWxpZCBhcmd1bWVudCBpdCBtZWFucyB3ZSBkbyBleHBlY3QgYW4gZXJyb3JcbiAgICAvLyBidXQgd2Ugd2FudCBpdCB0byBtYXRjaCBhIGdpdmVuIHNldCBvZiBjcml0ZXJpYVxuICAgIHZhciBldmVyeUFyZ0lzVW5kZWZpbmVkID0gZXJyb3JMaWtlID09PSB1bmRlZmluZWQgJiYgZXJyTXNnTWF0Y2hlciA9PT0gdW5kZWZpbmVkO1xuXG4gICAgLy8gSWYgd2UndmUgZ290IHRoZSBuZWdhdGUgZmxhZyBlbmFibGVkIGFuZCBib3RoIGFyZ3MsIHdlIHNob3VsZCBvbmx5IGZhaWwgaWYgYm90aCBhcmVuJ3QgY29tcGF0aWJsZVxuICAgIC8vIFNlZSBJc3N1ZSAjNTUxIGFuZCBQUiAjNjgzQEdpdEh1YlxuICAgIHZhciBldmVyeUFyZ0lzRGVmaW5lZCA9IEJvb2xlYW4oZXJyb3JMaWtlICYmIGVyck1zZ01hdGNoZXIpO1xuICAgIHZhciBlcnJvckxpa2VGYWlsID0gZmFsc2U7XG4gICAgdmFyIGVyck1zZ01hdGNoZXJGYWlsID0gZmFsc2U7XG5cbiAgICAvLyBDaGVja2luZyBpZiBlcnJvciB3YXMgdGhyb3duXG4gICAgaWYgKGV2ZXJ5QXJnSXNVbmRlZmluZWQgfHwgIWV2ZXJ5QXJnSXNVbmRlZmluZWQgJiYgIW5lZ2F0ZSkge1xuICAgICAgLy8gV2UgbmVlZCB0aGlzIHRvIGRpc3BsYXkgcmVzdWx0cyBjb3JyZWN0bHkgYWNjb3JkaW5nIHRvIHRoZWlyIHR5cGVzXG4gICAgICB2YXIgZXJyb3JMaWtlU3RyaW5nID0gJ2FuIGVycm9yJztcbiAgICAgIGlmIChlcnJvckxpa2UgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICBlcnJvckxpa2VTdHJpbmcgPSAnI3tleHB9JztcbiAgICAgIH0gZWxzZSBpZiAoZXJyb3JMaWtlKSB7XG4gICAgICAgIGVycm9yTGlrZVN0cmluZyA9IF8uY2hlY2tFcnJvci5nZXRDb25zdHJ1Y3Rvck5hbWUoZXJyb3JMaWtlKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgY2F1Z2h0RXJyXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gdGhyb3cgJyArIGVycm9yTGlrZVN0cmluZ1xuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCB0aHJvdyBhbiBlcnJvciBidXQgI3thY3R9IHdhcyB0aHJvd24nXG4gICAgICAgICwgZXJyb3JMaWtlICYmIGVycm9yTGlrZS50b1N0cmluZygpXG4gICAgICAgICwgKGNhdWdodEVyciBpbnN0YW5jZW9mIEVycm9yID9cbiAgICAgICAgICAgIGNhdWdodEVyci50b1N0cmluZygpIDogKHR5cGVvZiBjYXVnaHRFcnIgPT09ICdzdHJpbmcnID8gY2F1Z2h0RXJyIDogY2F1Z2h0RXJyICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfLmNoZWNrRXJyb3IuZ2V0Q29uc3RydWN0b3JOYW1lKGNhdWdodEVycikpKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoZXJyb3JMaWtlICYmIGNhdWdodEVycikge1xuICAgICAgLy8gV2Ugc2hvdWxkIGNvbXBhcmUgaW5zdGFuY2VzIG9ubHkgaWYgYGVycm9yTGlrZWAgaXMgYW4gaW5zdGFuY2Ugb2YgYEVycm9yYFxuICAgICAgaWYgKGVycm9yTGlrZSBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHZhciBpc0NvbXBhdGlibGVJbnN0YW5jZSA9IF8uY2hlY2tFcnJvci5jb21wYXRpYmxlSW5zdGFuY2UoY2F1Z2h0RXJyLCBlcnJvckxpa2UpO1xuXG4gICAgICAgIGlmIChpc0NvbXBhdGlibGVJbnN0YW5jZSA9PT0gbmVnYXRlKSB7XG4gICAgICAgICAgLy8gVGhlc2UgY2hlY2tzIHdlcmUgY3JlYXRlZCB0byBlbnN1cmUgd2Ugd29uJ3QgZmFpbCB0b28gc29vbiB3aGVuIHdlJ3ZlIGdvdCBib3RoIGFyZ3MgYW5kIGEgbmVnYXRlXG4gICAgICAgICAgLy8gU2VlIElzc3VlICM1NTEgYW5kIFBSICM2ODNAR2l0SHViXG4gICAgICAgICAgaWYgKGV2ZXJ5QXJnSXNEZWZpbmVkICYmIG5lZ2F0ZSkge1xuICAgICAgICAgICAgZXJyb3JMaWtlRmFpbCA9IHRydWU7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgICAgICAgIG5lZ2F0ZVxuICAgICAgICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIHRocm93ICN7ZXhwfSBidXQgI3thY3R9IHdhcyB0aHJvd24nXG4gICAgICAgICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IHRocm93ICN7ZXhwfScgKyAoY2F1Z2h0RXJyICYmICFuZWdhdGUgPyAnIGJ1dCAje2FjdH0gd2FzIHRocm93bicgOiAnJylcbiAgICAgICAgICAgICAgLCBlcnJvckxpa2UudG9TdHJpbmcoKVxuICAgICAgICAgICAgICAsIGNhdWdodEVyci50b1N0cmluZygpXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB2YXIgaXNDb21wYXRpYmxlQ29uc3RydWN0b3IgPSBfLmNoZWNrRXJyb3IuY29tcGF0aWJsZUNvbnN0cnVjdG9yKGNhdWdodEVyciwgZXJyb3JMaWtlKTtcbiAgICAgIGlmIChpc0NvbXBhdGlibGVDb25zdHJ1Y3RvciA9PT0gbmVnYXRlKSB7XG4gICAgICAgIGlmIChldmVyeUFyZ0lzRGVmaW5lZCAmJiBuZWdhdGUpIHtcbiAgICAgICAgICAgIGVycm9yTGlrZUZhaWwgPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgICAgICBuZWdhdGVcbiAgICAgICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gdGhyb3cgI3tleHB9IGJ1dCAje2FjdH0gd2FzIHRocm93bidcbiAgICAgICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IHRocm93ICN7ZXhwfScgKyAoY2F1Z2h0RXJyID8gJyBidXQgI3thY3R9IHdhcyB0aHJvd24nIDogJycpXG4gICAgICAgICAgICAsIChlcnJvckxpa2UgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yTGlrZS50b1N0cmluZygpIDogZXJyb3JMaWtlICYmIF8uY2hlY2tFcnJvci5nZXRDb25zdHJ1Y3Rvck5hbWUoZXJyb3JMaWtlKSlcbiAgICAgICAgICAgICwgKGNhdWdodEVyciBpbnN0YW5jZW9mIEVycm9yID8gY2F1Z2h0RXJyLnRvU3RyaW5nKCkgOiBjYXVnaHRFcnIgJiYgXy5jaGVja0Vycm9yLmdldENvbnN0cnVjdG9yTmFtZShjYXVnaHRFcnIpKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoY2F1Z2h0RXJyICYmIGVyck1zZ01hdGNoZXIgIT09IHVuZGVmaW5lZCAmJiBlcnJNc2dNYXRjaGVyICE9PSBudWxsKSB7XG4gICAgICAvLyBIZXJlIHdlIGNoZWNrIGNvbXBhdGlibGUgbWVzc2FnZXNcbiAgICAgIHZhciBwbGFjZWhvbGRlciA9ICdpbmNsdWRpbmcnO1xuICAgICAgaWYgKGVyck1zZ01hdGNoZXIgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgcGxhY2Vob2xkZXIgPSAnbWF0Y2hpbmcnXG4gICAgICB9XG5cbiAgICAgIHZhciBpc0NvbXBhdGlibGVNZXNzYWdlID0gXy5jaGVja0Vycm9yLmNvbXBhdGlibGVNZXNzYWdlKGNhdWdodEVyciwgZXJyTXNnTWF0Y2hlcik7XG4gICAgICBpZiAoaXNDb21wYXRpYmxlTWVzc2FnZSA9PT0gbmVnYXRlKSB7XG4gICAgICAgIGlmIChldmVyeUFyZ0lzRGVmaW5lZCAmJiBuZWdhdGUpIHtcbiAgICAgICAgICAgIGVyck1zZ01hdGNoZXJGYWlsID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICAgIG5lZ2F0ZVxuICAgICAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byB0aHJvdyBlcnJvciAnICsgcGxhY2Vob2xkZXIgKyAnICN7ZXhwfSBidXQgZ290ICN7YWN0fSdcbiAgICAgICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gdGhyb3cgZXJyb3Igbm90ICcgKyBwbGFjZWhvbGRlciArICcgI3tleHB9J1xuICAgICAgICAgICAgLCAgZXJyTXNnTWF0Y2hlclxuICAgICAgICAgICAgLCAgXy5jaGVja0Vycm9yLmdldE1lc3NhZ2UoY2F1Z2h0RXJyKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBJZiBib3RoIGFzc2VydGlvbnMgZmFpbGVkIGFuZCBib3RoIHNob3VsZCd2ZSBtYXRjaGVkIHdlIHRocm93IGFuIGVycm9yXG4gICAgaWYgKGVycm9yTGlrZUZhaWwgJiYgZXJyTXNnTWF0Y2hlckZhaWwpIHtcbiAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICBuZWdhdGVcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byB0aHJvdyAje2V4cH0gYnV0ICN7YWN0fSB3YXMgdGhyb3duJ1xuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCB0aHJvdyAje2V4cH0nICsgKGNhdWdodEVyciA/ICcgYnV0ICN7YWN0fSB3YXMgdGhyb3duJyA6ICcnKVxuICAgICAgICAsIChlcnJvckxpa2UgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yTGlrZS50b1N0cmluZygpIDogZXJyb3JMaWtlICYmIF8uY2hlY2tFcnJvci5nZXRDb25zdHJ1Y3Rvck5hbWUoZXJyb3JMaWtlKSlcbiAgICAgICAgLCAoY2F1Z2h0RXJyIGluc3RhbmNlb2YgRXJyb3IgPyBjYXVnaHRFcnIudG9TdHJpbmcoKSA6IGNhdWdodEVyciAmJiBfLmNoZWNrRXJyb3IuZ2V0Q29uc3RydWN0b3JOYW1lKGNhdWdodEVycikpXG4gICAgICApO1xuICAgIH1cblxuICAgIGZsYWcodGhpcywgJ29iamVjdCcsIGNhdWdodEVycik7XG4gIH07XG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgndGhyb3cnLCBhc3NlcnRUaHJvd3MpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCd0aHJvd3MnLCBhc3NlcnRUaHJvd3MpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdUaHJvdycsIGFzc2VydFRocm93cyk7XG5cbiAgLyoqXG4gICAqICMjIyAucmVzcG9uZFRvKG1ldGhvZFssIG1zZ10pXG4gICAqXG4gICAqIFdoZW4gdGhlIHRhcmdldCBpcyBhIG5vbi1mdW5jdGlvbiBvYmplY3QsIGAucmVzcG9uZFRvYCBhc3NlcnRzIHRoYXQgdGhlXG4gICAqIHRhcmdldCBoYXMgYSBtZXRob2Qgd2l0aCB0aGUgZ2l2ZW4gbmFtZSBgbWV0aG9kYC4gVGhlIG1ldGhvZCBjYW4gYmUgb3duIG9yXG4gICAqIGluaGVyaXRlZCwgYW5kIGl0IGNhbiBiZSBlbnVtZXJhYmxlIG9yIG5vbi1lbnVtZXJhYmxlLlxuICAgKlxuICAgKiAgICAgZnVuY3Rpb24gQ2F0ICgpIHt9XG4gICAqICAgICBDYXQucHJvdG90eXBlLm1lb3cgPSBmdW5jdGlvbiAoKSB7fTtcbiAgICpcbiAgICogICAgIGV4cGVjdChuZXcgQ2F0KCkpLnRvLnJlc3BvbmRUbygnbWVvdycpO1xuICAgKlxuICAgKiBXaGVuIHRoZSB0YXJnZXQgaXMgYSBmdW5jdGlvbiwgYC5yZXNwb25kVG9gIGFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0J3NcbiAgICogYHByb3RvdHlwZWAgcHJvcGVydHkgaGFzIGEgbWV0aG9kIHdpdGggdGhlIGdpdmVuIG5hbWUgYG1ldGhvZGAuIEFnYWluLCB0aGVcbiAgICogbWV0aG9kIGNhbiBiZSBvd24gb3IgaW5oZXJpdGVkLCBhbmQgaXQgY2FuIGJlIGVudW1lcmFibGUgb3Igbm9uLWVudW1lcmFibGUuXG4gICAqXG4gICAqICAgICBmdW5jdGlvbiBDYXQgKCkge31cbiAgICogICAgIENhdC5wcm90b3R5cGUubWVvdyA9IGZ1bmN0aW9uICgpIHt9O1xuICAgKlxuICAgKiAgICAgZXhwZWN0KENhdCkudG8ucmVzcG9uZFRvKCdtZW93Jyk7XG4gICAqXG4gICAqIEFkZCBgLml0c2VsZmAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gZm9yY2UgYC5yZXNwb25kVG9gIHRvIHRyZWF0IHRoZVxuICAgKiB0YXJnZXQgYXMgYSBub24tZnVuY3Rpb24gb2JqZWN0LCBldmVuIGlmIGl0J3MgYSBmdW5jdGlvbi4gVGh1cywgaXQgYXNzZXJ0c1xuICAgKiB0aGF0IHRoZSB0YXJnZXQgaGFzIGEgbWV0aG9kIHdpdGggdGhlIGdpdmVuIG5hbWUgYG1ldGhvZGAsIHJhdGhlciB0aGFuXG4gICAqIGFzc2VydGluZyB0aGF0IHRoZSB0YXJnZXQncyBgcHJvdG90eXBlYCBwcm9wZXJ0eSBoYXMgYSBtZXRob2Qgd2l0aCB0aGVcbiAgICogZ2l2ZW4gbmFtZSBgbWV0aG9kYC5cbiAgICpcbiAgICogICAgIGZ1bmN0aW9uIENhdCAoKSB7fVxuICAgKiAgICAgQ2F0LnByb3RvdHlwZS5tZW93ID0gZnVuY3Rpb24gKCkge307XG4gICAqICAgICBDYXQuaGlzcyA9IGZ1bmN0aW9uICgpIHt9O1xuICAgKlxuICAgKiAgICAgZXhwZWN0KENhdCkuaXRzZWxmLnRvLnJlc3BvbmRUbygnaGlzcycpLmJ1dC5ub3QucmVzcG9uZFRvKCdtZW93Jyk7XG4gICAqXG4gICAqIFdoZW4gbm90IGFkZGluZyBgLml0c2VsZmAsIGl0J3MgaW1wb3J0YW50IHRvIGNoZWNrIHRoZSB0YXJnZXQncyB0eXBlIGJlZm9yZVxuICAgKiB1c2luZyBgLnJlc3BvbmRUb2AuIFNlZSB0aGUgYC5hYCBkb2MgZm9yIGluZm8gb24gY2hlY2tpbmcgYSB0YXJnZXQncyB0eXBlLlxuICAgKlxuICAgKiAgICAgZnVuY3Rpb24gQ2F0ICgpIHt9XG4gICAqICAgICBDYXQucHJvdG90eXBlLm1lb3cgPSBmdW5jdGlvbiAoKSB7fTtcbiAgICpcbiAgICogICAgIGV4cGVjdChuZXcgQ2F0KCkpLnRvLmJlLmFuKCdvYmplY3QnKS50aGF0LnJlc3BvbmRzVG8oJ21lb3cnKTtcbiAgICpcbiAgICogQWRkIGAubm90YCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byBuZWdhdGUgYC5yZXNwb25kVG9gLlxuICAgKlxuICAgKiAgICAgZnVuY3Rpb24gRG9nICgpIHt9XG4gICAqICAgICBEb2cucHJvdG90eXBlLmJhcmsgPSBmdW5jdGlvbiAoKSB7fTtcbiAgICpcbiAgICogICAgIGV4cGVjdChuZXcgRG9nKCkpLnRvLm5vdC5yZXNwb25kVG8oJ21lb3cnKTtcbiAgICpcbiAgICogYC5yZXNwb25kVG9gIGFjY2VwdHMgYW4gb3B0aW9uYWwgYG1zZ2AgYXJndW1lbnQgd2hpY2ggaXMgYSBjdXN0b20gZXJyb3JcbiAgICogbWVzc2FnZSB0byBzaG93IHdoZW4gdGhlIGFzc2VydGlvbiBmYWlscy4gVGhlIG1lc3NhZ2UgY2FuIGFsc28gYmUgZ2l2ZW4gYXNcbiAgICogdGhlIHNlY29uZCBhcmd1bWVudCB0byBgZXhwZWN0YC5cbiAgICpcbiAgICogICAgIGV4cGVjdCh7fSkudG8ucmVzcG9uZFRvKCdtZW93JywgJ25vb28gd2h5IGZhaWw/PycpO1xuICAgKiAgICAgZXhwZWN0KHt9LCAnbm9vbyB3aHkgZmFpbD8/JykudG8ucmVzcG9uZFRvKCdtZW93Jyk7XG4gICAqXG4gICAqIFRoZSBhbGlhcyBgLnJlc3BvbmRzVG9gIGNhbiBiZSB1c2VkIGludGVyY2hhbmdlYWJseSB3aXRoIGAucmVzcG9uZFRvYC5cbiAgICpcbiAgICogQG5hbWUgcmVzcG9uZFRvXG4gICAqIEBhbGlhcyByZXNwb25kc1RvXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXRob2RcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1zZyBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGZ1bmN0aW9uIHJlc3BvbmRUbyAobWV0aG9kLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0JylcbiAgICAgICwgaXRzZWxmID0gZmxhZyh0aGlzLCAnaXRzZWxmJylcbiAgICAgICwgY29udGV4dCA9ICgnZnVuY3Rpb24nID09PSB0eXBlb2Ygb2JqICYmICFpdHNlbGYpXG4gICAgICAgID8gb2JqLnByb3RvdHlwZVttZXRob2RdXG4gICAgICAgIDogb2JqW21ldGhvZF07XG5cbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgJ2Z1bmN0aW9uJyA9PT0gdHlwZW9mIGNvbnRleHRcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gcmVzcG9uZCB0byAnICsgXy5pbnNwZWN0KG1ldGhvZClcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IHJlc3BvbmQgdG8gJyArIF8uaW5zcGVjdChtZXRob2QpXG4gICAgKTtcbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ3Jlc3BvbmRUbycsIHJlc3BvbmRUbyk7XG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ3Jlc3BvbmRzVG8nLCByZXNwb25kVG8pO1xuXG4gIC8qKlxuICAgKiAjIyMgLml0c2VsZlxuICAgKlxuICAgKiBGb3JjZXMgYWxsIGAucmVzcG9uZFRvYCBhc3NlcnRpb25zIHRoYXQgZm9sbG93IGluIHRoZSBjaGFpbiB0byBiZWhhdmUgYXMgaWZcbiAgICogdGhlIHRhcmdldCBpcyBhIG5vbi1mdW5jdGlvbiBvYmplY3QsIGV2ZW4gaWYgaXQncyBhIGZ1bmN0aW9uLiBUaHVzLCBpdFxuICAgKiBjYXVzZXMgYC5yZXNwb25kVG9gIHRvIGFzc2VydCB0aGF0IHRoZSB0YXJnZXQgaGFzIGEgbWV0aG9kIHdpdGggdGhlIGdpdmVuXG4gICAqIG5hbWUsIHJhdGhlciB0aGFuIGFzc2VydGluZyB0aGF0IHRoZSB0YXJnZXQncyBgcHJvdG90eXBlYCBwcm9wZXJ0eSBoYXMgYVxuICAgKiBtZXRob2Qgd2l0aCB0aGUgZ2l2ZW4gbmFtZS5cbiAgICpcbiAgICogICAgIGZ1bmN0aW9uIENhdCAoKSB7fVxuICAgKiAgICAgQ2F0LnByb3RvdHlwZS5tZW93ID0gZnVuY3Rpb24gKCkge307XG4gICAqICAgICBDYXQuaGlzcyA9IGZ1bmN0aW9uICgpIHt9O1xuICAgKlxuICAgKiAgICAgZXhwZWN0KENhdCkuaXRzZWxmLnRvLnJlc3BvbmRUbygnaGlzcycpLmJ1dC5ub3QucmVzcG9uZFRvKCdtZW93Jyk7XG4gICAqXG4gICAqIEBuYW1lIGl0c2VsZlxuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBBc3NlcnRpb24uYWRkUHJvcGVydHkoJ2l0c2VsZicsIGZ1bmN0aW9uICgpIHtcbiAgICBmbGFnKHRoaXMsICdpdHNlbGYnLCB0cnVlKTtcbiAgfSk7XG5cbiAgLyoqXG4gICAqICMjIyAuc2F0aXNmeShtYXRjaGVyWywgbXNnXSlcbiAgICpcbiAgICogSW52b2tlcyB0aGUgZ2l2ZW4gYG1hdGNoZXJgIGZ1bmN0aW9uIHdpdGggdGhlIHRhcmdldCBiZWluZyBwYXNzZWQgYXMgdGhlXG4gICAqIGZpcnN0IGFyZ3VtZW50LCBhbmQgYXNzZXJ0cyB0aGF0IHRoZSB2YWx1ZSByZXR1cm5lZCBpcyB0cnV0aHkuXG4gICAqXG4gICAqICAgICBleHBlY3QoMSkudG8uc2F0aXNmeShmdW5jdGlvbihudW0pIHtcbiAgICogICAgICAgcmV0dXJuIG51bSA+IDA7XG4gICAqICAgICB9KTtcbiAgICpcbiAgICogQWRkIGAubm90YCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byBuZWdhdGUgYC5zYXRpc2Z5YC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgxKS50by5ub3Quc2F0aXNmeShmdW5jdGlvbihudW0pIHtcbiAgICogICAgICAgcmV0dXJuIG51bSA+IDI7XG4gICAqICAgICB9KTtcbiAgICpcbiAgICogYC5zYXRpc2Z5YCBhY2NlcHRzIGFuIG9wdGlvbmFsIGBtc2dgIGFyZ3VtZW50IHdoaWNoIGlzIGEgY3VzdG9tIGVycm9yXG4gICAqIG1lc3NhZ2UgdG8gc2hvdyB3aGVuIHRoZSBhc3NlcnRpb24gZmFpbHMuIFRoZSBtZXNzYWdlIGNhbiBhbHNvIGJlIGdpdmVuIGFzXG4gICAqIHRoZSBzZWNvbmQgYXJndW1lbnQgdG8gYGV4cGVjdGAuXG4gICAqXG4gICAqICAgICBleHBlY3QoMSkudG8uc2F0aXNmeShmdW5jdGlvbihudW0pIHtcbiAgICogICAgICAgcmV0dXJuIG51bSA+IDI7XG4gICAqICAgICB9LCAnbm9vbyB3aHkgZmFpbD8/Jyk7XG4gICAqXG4gICAqICAgICBleHBlY3QoMSwgJ25vb28gd2h5IGZhaWw/PycpLnRvLnNhdGlzZnkoZnVuY3Rpb24obnVtKSB7XG4gICAqICAgICAgIHJldHVybiBudW0gPiAyO1xuICAgKiAgICAgfSk7XG4gICAqXG4gICAqIFRoZSBhbGlhcyBgLnNhdGlzZmllc2AgY2FuIGJlIHVzZWQgaW50ZXJjaGFuZ2VhYmx5IHdpdGggYC5zYXRpc2Z5YC5cbiAgICpcbiAgICogQG5hbWUgc2F0aXNmeVxuICAgKiBAYWxpYXMgc2F0aXNmaWVzXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IG1hdGNoZXJcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1zZyBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGZ1bmN0aW9uIHNhdGlzZnkgKG1hdGNoZXIsIG1zZykge1xuICAgIGlmIChtc2cpIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKTtcbiAgICB2YXIgcmVzdWx0ID0gbWF0Y2hlcihvYmopO1xuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICByZXN1bHRcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gc2F0aXNmeSAnICsgXy5vYmpEaXNwbGF5KG1hdGNoZXIpXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBzYXRpc2Z5JyArIF8ub2JqRGlzcGxheShtYXRjaGVyKVxuICAgICAgLCBmbGFnKHRoaXMsICduZWdhdGUnKSA/IGZhbHNlIDogdHJ1ZVxuICAgICAgLCByZXN1bHRcbiAgICApO1xuICB9XG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnc2F0aXNmeScsIHNhdGlzZnkpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdzYXRpc2ZpZXMnLCBzYXRpc2Z5KTtcblxuICAvKipcbiAgICogIyMjIC5jbG9zZVRvKGV4cGVjdGVkLCBkZWx0YVssIG1zZ10pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGEgbnVtYmVyIHRoYXQncyB3aXRoaW4gYSBnaXZlbiArLy0gYGRlbHRhYCByYW5nZVxuICAgKiBvZiB0aGUgZ2l2ZW4gbnVtYmVyIGBleHBlY3RlZGAuIEhvd2V2ZXIsIGl0J3Mgb2Z0ZW4gYmVzdCB0byBhc3NlcnQgdGhhdCB0aGVcbiAgICogdGFyZ2V0IGlzIGVxdWFsIHRvIGl0cyBleHBlY3RlZCB2YWx1ZS5cbiAgICpcbiAgICogICAgIC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoMS41KS50by5lcXVhbCgxLjUpO1xuICAgKlxuICAgKiAgICAgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoMS41KS50by5iZS5jbG9zZVRvKDEsIDAuNSk7XG4gICAqICAgICBleHBlY3QoMS41KS50by5iZS5jbG9zZVRvKDIsIDAuNSk7XG4gICAqICAgICBleHBlY3QoMS41KS50by5iZS5jbG9zZVRvKDEsIDEpO1xuICAgKlxuICAgKiBBZGQgYC5ub3RgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIG5lZ2F0ZSBgLmNsb3NlVG9gLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KDEuNSkudG8uZXF1YWwoMS41KTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCgxLjUpLnRvLm5vdC5iZS5jbG9zZVRvKDMsIDEpOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogYC5jbG9zZVRvYCBhY2NlcHRzIGFuIG9wdGlvbmFsIGBtc2dgIGFyZ3VtZW50IHdoaWNoIGlzIGEgY3VzdG9tIGVycm9yXG4gICAqIG1lc3NhZ2UgdG8gc2hvdyB3aGVuIHRoZSBhc3NlcnRpb24gZmFpbHMuIFRoZSBtZXNzYWdlIGNhbiBhbHNvIGJlIGdpdmVuIGFzXG4gICAqIHRoZSBzZWNvbmQgYXJndW1lbnQgdG8gYGV4cGVjdGAuXG4gICAqXG4gICAqICAgICBleHBlY3QoMS41KS50by5iZS5jbG9zZVRvKDMsIDEsICdub29vIHdoeSBmYWlsPz8nKTtcbiAgICogICAgIGV4cGVjdCgxLjUsICdub29vIHdoeSBmYWlsPz8nKS50by5iZS5jbG9zZVRvKDMsIDEpO1xuICAgKlxuICAgKiBUaGUgYWxpYXMgYC5hcHByb3hpbWF0ZWx5YCBjYW4gYmUgdXNlZCBpbnRlcmNoYW5nZWFibHkgd2l0aCBgLmNsb3NlVG9gLlxuICAgKlxuICAgKiBAbmFtZSBjbG9zZVRvXG4gICAqIEBhbGlhcyBhcHByb3hpbWF0ZWx5XG4gICAqIEBwYXJhbSB7TnVtYmVyfSBleHBlY3RlZFxuICAgKiBAcGFyYW0ge051bWJlcn0gZGVsdGFcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1zZyBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGNsb3NlVG8oZXhwZWN0ZWQsIGRlbHRhLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0JylcbiAgICAgICwgZmxhZ01zZyA9IGZsYWcodGhpcywgJ21lc3NhZ2UnKVxuICAgICAgLCBzc2ZpID0gZmxhZyh0aGlzLCAnc3NmaScpO1xuXG4gICAgbmV3IEFzc2VydGlvbihvYmosIGZsYWdNc2csIHNzZmksIHRydWUpLmlzLmEoJ251bWJlcicpO1xuICAgIGlmICh0eXBlb2YgZXhwZWN0ZWQgIT09ICdudW1iZXInIHx8IHR5cGVvZiBkZWx0YSAhPT0gJ251bWJlcicpIHtcbiAgICAgIGZsYWdNc2cgPSBmbGFnTXNnID8gZmxhZ01zZyArICc6ICcgOiAnJztcbiAgICAgIHZhciBkZWx0YU1lc3NhZ2UgPSBkZWx0YSA9PT0gdW5kZWZpbmVkID8gXCIsIGFuZCBhIGRlbHRhIGlzIHJlcXVpcmVkXCIgOiBcIlwiO1xuICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKFxuICAgICAgICAgIGZsYWdNc2cgKyAndGhlIGFyZ3VtZW50cyB0byBjbG9zZVRvIG9yIGFwcHJveGltYXRlbHkgbXVzdCBiZSBudW1iZXJzJyArIGRlbHRhTWVzc2FnZSxcbiAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgc3NmaVxuICAgICAgKTtcbiAgICB9XG5cbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgTWF0aC5hYnMob2JqIC0gZXhwZWN0ZWQpIDw9IGRlbHRhXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIGNsb3NlIHRvICcgKyBleHBlY3RlZCArICcgKy8tICcgKyBkZWx0YVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSBub3QgdG8gYmUgY2xvc2UgdG8gJyArIGV4cGVjdGVkICsgJyArLy0gJyArIGRlbHRhXG4gICAgKTtcbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2Nsb3NlVG8nLCBjbG9zZVRvKTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnYXBwcm94aW1hdGVseScsIGNsb3NlVG8pO1xuXG4gIC8vIE5vdGU6IER1cGxpY2F0ZXMgYXJlIGlnbm9yZWQgaWYgdGVzdGluZyBmb3IgaW5jbHVzaW9uIGluc3RlYWQgb2Ygc2FtZW5lc3MuXG4gIGZ1bmN0aW9uIGlzU3Vic2V0T2Yoc3Vic2V0LCBzdXBlcnNldCwgY21wLCBjb250YWlucywgb3JkZXJlZCkge1xuICAgIGlmICghY29udGFpbnMpIHtcbiAgICAgIGlmIChzdWJzZXQubGVuZ3RoICE9PSBzdXBlcnNldC5sZW5ndGgpIHJldHVybiBmYWxzZTtcbiAgICAgIHN1cGVyc2V0ID0gc3VwZXJzZXQuc2xpY2UoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc3Vic2V0LmV2ZXJ5KGZ1bmN0aW9uKGVsZW0sIGlkeCkge1xuICAgICAgaWYgKG9yZGVyZWQpIHJldHVybiBjbXAgPyBjbXAoZWxlbSwgc3VwZXJzZXRbaWR4XSkgOiBlbGVtID09PSBzdXBlcnNldFtpZHhdO1xuXG4gICAgICBpZiAoIWNtcCkge1xuICAgICAgICB2YXIgbWF0Y2hJZHggPSBzdXBlcnNldC5pbmRleE9mKGVsZW0pO1xuICAgICAgICBpZiAobWF0Y2hJZHggPT09IC0xKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgLy8gUmVtb3ZlIG1hdGNoIGZyb20gc3VwZXJzZXQgc28gbm90IGNvdW50ZWQgdHdpY2UgaWYgZHVwbGljYXRlIGluIHN1YnNldC5cbiAgICAgICAgaWYgKCFjb250YWlucykgc3VwZXJzZXQuc3BsaWNlKG1hdGNoSWR4LCAxKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBzdXBlcnNldC5zb21lKGZ1bmN0aW9uKGVsZW0yLCBtYXRjaElkeCkge1xuICAgICAgICBpZiAoIWNtcChlbGVtLCBlbGVtMikpIHJldHVybiBmYWxzZTtcblxuICAgICAgICAvLyBSZW1vdmUgbWF0Y2ggZnJvbSBzdXBlcnNldCBzbyBub3QgY291bnRlZCB0d2ljZSBpZiBkdXBsaWNhdGUgaW4gc3Vic2V0LlxuICAgICAgICBpZiAoIWNvbnRhaW5zKSBzdXBlcnNldC5zcGxpY2UobWF0Y2hJZHgsIDEpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqICMjIyAubWVtYmVycyhzZXRbLCBtc2ddKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBhcnJheSBoYXMgdGhlIHNhbWUgbWVtYmVycyBhcyB0aGUgZ2l2ZW4gYXJyYXlcbiAgICogYHNldGAuXG4gICAqXG4gICAqICAgICBleHBlY3QoWzEsIDIsIDNdKS50by5oYXZlLm1lbWJlcnMoWzIsIDEsIDNdKTtcbiAgICogICAgIGV4cGVjdChbMSwgMiwgMl0pLnRvLmhhdmUubWVtYmVycyhbMiwgMSwgMl0pO1xuICAgKlxuICAgKiBCeSBkZWZhdWx0LCBtZW1iZXJzIGFyZSBjb21wYXJlZCB1c2luZyBzdHJpY3QgKGA9PT1gKSBlcXVhbGl0eS4gQWRkIGAuZGVlcGBcbiAgICogZWFybGllciBpbiB0aGUgY2hhaW4gdG8gdXNlIGRlZXAgZXF1YWxpdHkgaW5zdGVhZC4gU2VlIHRoZSBgZGVlcC1lcWxgXG4gICAqIHByb2plY3QgcGFnZSBmb3IgaW5mbyBvbiB0aGUgZGVlcCBlcXVhbGl0eSBhbGdvcml0aG06XG4gICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFpanMvZGVlcC1lcWwuXG4gICAqXG4gICAqICAgICAvLyBUYXJnZXQgYXJyYXkgZGVlcGx5IChidXQgbm90IHN0cmljdGx5KSBoYXMgbWVtYmVyIGB7YTogMX1gXG4gICAqICAgICBleHBlY3QoW3thOiAxfV0pLnRvLmhhdmUuZGVlcC5tZW1iZXJzKFt7YTogMX1dKTtcbiAgICogICAgIGV4cGVjdChbe2E6IDF9XSkudG8ubm90LmhhdmUubWVtYmVycyhbe2E6IDF9XSk7XG4gICAqXG4gICAqIEJ5IGRlZmF1bHQsIG9yZGVyIGRvZXNuJ3QgbWF0dGVyLiBBZGQgYC5vcmRlcmVkYCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0b1xuICAgKiByZXF1aXJlIHRoYXQgbWVtYmVycyBhcHBlYXIgaW4gdGhlIHNhbWUgb3JkZXIuXG4gICAqXG4gICAqICAgICBleHBlY3QoWzEsIDIsIDNdKS50by5oYXZlLm9yZGVyZWQubWVtYmVycyhbMSwgMiwgM10pO1xuICAgKiAgICAgZXhwZWN0KFsxLCAyLCAzXSkudG8uaGF2ZS5tZW1iZXJzKFsyLCAxLCAzXSlcbiAgICogICAgICAgLmJ1dC5ub3Qub3JkZXJlZC5tZW1iZXJzKFsyLCAxLCAzXSk7XG4gICAqXG4gICAqIEJ5IGRlZmF1bHQsIGJvdGggYXJyYXlzIG11c3QgYmUgdGhlIHNhbWUgc2l6ZS4gQWRkIGAuaW5jbHVkZWAgZWFybGllciBpblxuICAgKiB0aGUgY2hhaW4gdG8gcmVxdWlyZSB0aGF0IHRoZSB0YXJnZXQncyBtZW1iZXJzIGJlIGEgc3VwZXJzZXQgb2YgdGhlXG4gICAqIGV4cGVjdGVkIG1lbWJlcnMuIE5vdGUgdGhhdCBkdXBsaWNhdGVzIGFyZSBpZ25vcmVkIGluIHRoZSBzdWJzZXQgd2hlblxuICAgKiBgLmluY2x1ZGVgIGlzIGFkZGVkLlxuICAgKlxuICAgKiAgICAgLy8gVGFyZ2V0IGFycmF5IGlzIGEgc3VwZXJzZXQgb2YgWzEsIDJdIGJ1dCBub3QgaWRlbnRpY2FsXG4gICAqICAgICBleHBlY3QoWzEsIDIsIDNdKS50by5pbmNsdWRlLm1lbWJlcnMoWzEsIDJdKTtcbiAgICogICAgIGV4cGVjdChbMSwgMiwgM10pLnRvLm5vdC5oYXZlLm1lbWJlcnMoWzEsIDJdKTtcbiAgICpcbiAgICogICAgIC8vIER1cGxpY2F0ZXMgaW4gdGhlIHN1YnNldCBhcmUgaWdub3JlZFxuICAgKiAgICAgZXhwZWN0KFsxLCAyLCAzXSkudG8uaW5jbHVkZS5tZW1iZXJzKFsxLCAyLCAyLCAyXSk7XG4gICAqXG4gICAqIGAuZGVlcGAsIGAub3JkZXJlZGAsIGFuZCBgLmluY2x1ZGVgIGNhbiBhbGwgYmUgY29tYmluZWQuIEhvd2V2ZXIsIGlmXG4gICAqIGAuaW5jbHVkZWAgYW5kIGAub3JkZXJlZGAgYXJlIGNvbWJpbmVkLCB0aGUgb3JkZXJpbmcgYmVnaW5zIGF0IHRoZSBzdGFydCBvZlxuICAgKiBib3RoIGFycmF5cy5cbiAgICpcbiAgICogICAgIGV4cGVjdChbe2E6IDF9LCB7YjogMn0sIHtjOiAzfV0pXG4gICAqICAgICAgIC50by5pbmNsdWRlLmRlZXAub3JkZXJlZC5tZW1iZXJzKFt7YTogMX0sIHtiOiAyfV0pXG4gICAqICAgICAgIC5idXQubm90LmluY2x1ZGUuZGVlcC5vcmRlcmVkLm1lbWJlcnMoW3tiOiAyfSwge2M6IDN9XSk7XG4gICAqXG4gICAqIEFkZCBgLm5vdGAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gbmVnYXRlIGAubWVtYmVyc2AuIEhvd2V2ZXIsIGl0J3NcbiAgICogZGFuZ2Vyb3VzIHRvIGRvIHNvLiBUaGUgcHJvYmxlbSBpcyB0aGF0IGl0IGNyZWF0ZXMgdW5jZXJ0YWluIGV4cGVjdGF0aW9uc1xuICAgKiBieSBhc3NlcnRpbmcgdGhhdCB0aGUgdGFyZ2V0IGFycmF5IGRvZXNuJ3QgaGF2ZSBhbGwgb2YgdGhlIHNhbWUgbWVtYmVycyBhc1xuICAgKiB0aGUgZ2l2ZW4gYXJyYXkgYHNldGAgYnV0IG1heSBvciBtYXkgbm90IGhhdmUgc29tZSBvZiB0aGVtLiBJdCdzIG9mdGVuIGJlc3RcbiAgICogdG8gaWRlbnRpZnkgdGhlIGV4YWN0IG91dHB1dCB0aGF0J3MgZXhwZWN0ZWQsIGFuZCB0aGVuIHdyaXRlIGFuIGFzc2VydGlvblxuICAgKiB0aGF0IG9ubHkgYWNjZXB0cyB0aGF0IGV4YWN0IG91dHB1dC5cbiAgICpcbiAgICogICAgIGV4cGVjdChbMSwgMl0pLnRvLm5vdC5pbmNsdWRlKDMpLmFuZC5ub3QuaW5jbHVkZSg0KTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdChbMSwgMl0pLnRvLm5vdC5oYXZlLm1lbWJlcnMoWzMsIDRdKTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqIGAubWVtYmVyc2AgYWNjZXB0cyBhbiBvcHRpb25hbCBgbXNnYCBhcmd1bWVudCB3aGljaCBpcyBhIGN1c3RvbSBlcnJvclxuICAgKiBtZXNzYWdlIHRvIHNob3cgd2hlbiB0aGUgYXNzZXJ0aW9uIGZhaWxzLiBUaGUgbWVzc2FnZSBjYW4gYWxzbyBiZSBnaXZlbiBhc1xuICAgKiB0aGUgc2Vjb25kIGFyZ3VtZW50IHRvIGBleHBlY3RgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KFsxLCAyXSkudG8uaGF2ZS5tZW1iZXJzKFsxLCAyLCAzXSwgJ25vb28gd2h5IGZhaWw/PycpO1xuICAgKiAgICAgZXhwZWN0KFsxLCAyXSwgJ25vb28gd2h5IGZhaWw/PycpLnRvLmhhdmUubWVtYmVycyhbMSwgMiwgM10pO1xuICAgKlxuICAgKiBAbmFtZSBtZW1iZXJzXG4gICAqIEBwYXJhbSB7QXJyYXl9IHNldFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbXNnIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnbWVtYmVycycsIGZ1bmN0aW9uIChzdWJzZXQsIG1zZykge1xuICAgIGlmIChtc2cpIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCBmbGFnTXNnID0gZmxhZyh0aGlzLCAnbWVzc2FnZScpXG4gICAgICAsIHNzZmkgPSBmbGFnKHRoaXMsICdzc2ZpJyk7XG5cbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgZmxhZ01zZywgc3NmaSwgdHJ1ZSkudG8uYmUuYW4oJ2FycmF5Jyk7XG4gICAgbmV3IEFzc2VydGlvbihzdWJzZXQsIGZsYWdNc2csIHNzZmksIHRydWUpLnRvLmJlLmFuKCdhcnJheScpO1xuXG4gICAgdmFyIGNvbnRhaW5zID0gZmxhZyh0aGlzLCAnY29udGFpbnMnKTtcbiAgICB2YXIgb3JkZXJlZCA9IGZsYWcodGhpcywgJ29yZGVyZWQnKTtcblxuICAgIHZhciBzdWJqZWN0LCBmYWlsTXNnLCBmYWlsTmVnYXRlTXNnO1xuXG4gICAgaWYgKGNvbnRhaW5zKSB7XG4gICAgICBzdWJqZWN0ID0gb3JkZXJlZCA/ICdhbiBvcmRlcmVkIHN1cGVyc2V0JyA6ICdhIHN1cGVyc2V0JztcbiAgICAgIGZhaWxNc2cgPSAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSAnICsgc3ViamVjdCArICcgb2YgI3tleHB9JztcbiAgICAgIGZhaWxOZWdhdGVNc2cgPSAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgYmUgJyArIHN1YmplY3QgKyAnIG9mICN7ZXhwfSc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN1YmplY3QgPSBvcmRlcmVkID8gJ29yZGVyZWQgbWVtYmVycycgOiAnbWVtYmVycyc7XG4gICAgICBmYWlsTXNnID0gJ2V4cGVjdGVkICN7dGhpc30gdG8gaGF2ZSB0aGUgc2FtZSAnICsgc3ViamVjdCArICcgYXMgI3tleHB9JztcbiAgICAgIGZhaWxOZWdhdGVNc2cgPSAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgaGF2ZSB0aGUgc2FtZSAnICsgc3ViamVjdCArICcgYXMgI3tleHB9JztcbiAgICB9XG5cbiAgICB2YXIgY21wID0gZmxhZyh0aGlzLCAnZGVlcCcpID8gXy5lcWwgOiB1bmRlZmluZWQ7XG5cbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgaXNTdWJzZXRPZihzdWJzZXQsIG9iaiwgY21wLCBjb250YWlucywgb3JkZXJlZClcbiAgICAgICwgZmFpbE1zZ1xuICAgICAgLCBmYWlsTmVnYXRlTXNnXG4gICAgICAsIHN1YnNldFxuICAgICAgLCBvYmpcbiAgICAgICwgdHJ1ZVxuICAgICk7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiAjIyMgLm9uZU9mKGxpc3RbLCBtc2ddKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBhIG1lbWJlciBvZiB0aGUgZ2l2ZW4gYXJyYXkgYGxpc3RgLiBIb3dldmVyLFxuICAgKiBpdCdzIG9mdGVuIGJlc3QgdG8gYXNzZXJ0IHRoYXQgdGhlIHRhcmdldCBpcyBlcXVhbCB0byBpdHMgZXhwZWN0ZWQgdmFsdWUuXG4gICAqXG4gICAqICAgICBleHBlY3QoMSkudG8uZXF1YWwoMSk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoMSkudG8uYmUub25lT2YoWzEsIDIsIDNdKTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqIENvbXBhcmlzb25zIGFyZSBwZXJmb3JtZWQgdXNpbmcgc3RyaWN0IChgPT09YCkgZXF1YWxpdHkuXG4gICAqXG4gICAqIEFkZCBgLm5vdGAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gbmVnYXRlIGAub25lT2ZgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KDEpLnRvLmVxdWFsKDEpOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KDEpLnRvLm5vdC5iZS5vbmVPZihbMiwgMywgNF0pOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogSXQgY2FuIGFsc28gYmUgY2hhaW5lZCB3aXRoIGAuY29udGFpbmAgb3IgYC5pbmNsdWRlYCwgd2hpY2ggd2lsbCB3b3JrIHdpdGhcbiAgICogYm90aCBhcnJheXMgYW5kIHN0cmluZ3M6XG4gICAqXG4gICAqICAgICBleHBlY3QoJ1RvZGF5IGlzIHN1bm55JykudG8uY29udGFpbi5vbmVPZihbJ3N1bm55JywgJ2Nsb3VkeSddKVxuICAgKiAgICAgZXhwZWN0KCdUb2RheSBpcyByYWlueScpLnRvLm5vdC5jb250YWluLm9uZU9mKFsnc3VubnknLCAnY2xvdWR5J10pXG4gICAqICAgICBleHBlY3QoWzEsMiwzXSkudG8uY29udGFpbi5vbmVPZihbMyw0LDVdKVxuICAgKiAgICAgZXhwZWN0KFsxLDIsM10pLnRvLm5vdC5jb250YWluLm9uZU9mKFs0LDUsNl0pXG4gICAqXG4gICAqIGAub25lT2ZgIGFjY2VwdHMgYW4gb3B0aW9uYWwgYG1zZ2AgYXJndW1lbnQgd2hpY2ggaXMgYSBjdXN0b20gZXJyb3IgbWVzc2FnZVxuICAgKiB0byBzaG93IHdoZW4gdGhlIGFzc2VydGlvbiBmYWlscy4gVGhlIG1lc3NhZ2UgY2FuIGFsc28gYmUgZ2l2ZW4gYXMgdGhlXG4gICAqIHNlY29uZCBhcmd1bWVudCB0byBgZXhwZWN0YC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgxKS50by5iZS5vbmVPZihbMiwgMywgNF0sICdub29vIHdoeSBmYWlsPz8nKTtcbiAgICogICAgIGV4cGVjdCgxLCAnbm9vbyB3aHkgZmFpbD8/JykudG8uYmUub25lT2YoWzIsIDMsIDRdKTtcbiAgICpcbiAgICogQG5hbWUgb25lT2ZcbiAgICogQHBhcmFtIHtBcnJheTwqPn0gbGlzdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbXNnIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gb25lT2YgKGxpc3QsIG1zZykge1xuICAgIGlmIChtc2cpIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuICAgIHZhciBleHBlY3RlZCA9IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAsIGZsYWdNc2cgPSBmbGFnKHRoaXMsICdtZXNzYWdlJylcbiAgICAgICwgc3NmaSA9IGZsYWcodGhpcywgJ3NzZmknKVxuICAgICAgLCBjb250YWlucyA9IGZsYWcodGhpcywgJ2NvbnRhaW5zJylcbiAgICAgICwgaXNEZWVwID0gZmxhZyh0aGlzLCAnZGVlcCcpO1xuICAgIG5ldyBBc3NlcnRpb24obGlzdCwgZmxhZ01zZywgc3NmaSwgdHJ1ZSkudG8uYmUuYW4oJ2FycmF5Jyk7XG5cbiAgICBpZiAoY29udGFpbnMpIHtcbiAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICBsaXN0LnNvbWUoZnVuY3Rpb24ocG9zc2liaWxpdHkpIHsgcmV0dXJuIGV4cGVjdGVkLmluZGV4T2YocG9zc2liaWxpdHkpID4gLTEgfSlcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBjb250YWluIG9uZSBvZiAje2V4cH0nXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGNvbnRhaW4gb25lIG9mICN7ZXhwfSdcbiAgICAgICAgLCBsaXN0XG4gICAgICAgICwgZXhwZWN0ZWRcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChpc0RlZXApIHtcbiAgICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgbGlzdC5zb21lKGZ1bmN0aW9uKHBvc3NpYmlsaXR5KSB7IHJldHVybiBfLmVxbChleHBlY3RlZCwgcG9zc2liaWxpdHkpIH0pXG4gICAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBkZWVwbHkgZXF1YWwgb25lIG9mICN7ZXhwfSdcbiAgICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGRlZXBseSBlcXVhbCBvbmUgb2YgI3tleHB9J1xuICAgICAgICAgICwgbGlzdFxuICAgICAgICAgICwgZXhwZWN0ZWRcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgIGxpc3QuaW5kZXhPZihleHBlY3RlZCkgPiAtMVxuICAgICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgb25lIG9mICN7ZXhwfSdcbiAgICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBiZSBvbmUgb2YgI3tleHB9J1xuICAgICAgICAgICwgbGlzdFxuICAgICAgICAgICwgZXhwZWN0ZWRcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdvbmVPZicsIG9uZU9mKTtcblxuICAvKipcbiAgICogIyMjIC5jaGFuZ2Uoc3ViamVjdFssIHByb3BbLCBtc2ddXSlcbiAgICpcbiAgICogV2hlbiBvbmUgYXJndW1lbnQgaXMgcHJvdmlkZWQsIGAuY2hhbmdlYCBhc3NlcnRzIHRoYXQgdGhlIGdpdmVuIGZ1bmN0aW9uXG4gICAqIGBzdWJqZWN0YCByZXR1cm5zIGEgZGlmZmVyZW50IHZhbHVlIHdoZW4gaXQncyBpbnZva2VkIGJlZm9yZSB0aGUgdGFyZ2V0XG4gICAqIGZ1bmN0aW9uIGNvbXBhcmVkIHRvIHdoZW4gaXQncyBpbnZva2VkIGFmdGVyd2FyZC4gSG93ZXZlciwgaXQncyBvZnRlbiBiZXN0XG4gICAqIHRvIGFzc2VydCB0aGF0IGBzdWJqZWN0YCBpcyBlcXVhbCB0byBpdHMgZXhwZWN0ZWQgdmFsdWUuXG4gICAqXG4gICAqICAgICB2YXIgZG90cyA9ICcnXG4gICAqICAgICAgICwgYWRkRG90ID0gZnVuY3Rpb24gKCkgeyBkb3RzICs9ICcuJzsgfVxuICAgKiAgICAgICAsIGdldERvdHMgPSBmdW5jdGlvbiAoKSB7IHJldHVybiBkb3RzOyB9O1xuICAgKlxuICAgKiAgICAgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdChnZXREb3RzKCkpLnRvLmVxdWFsKCcnKTtcbiAgICogICAgIGFkZERvdCgpO1xuICAgKiAgICAgZXhwZWN0KGdldERvdHMoKSkudG8uZXF1YWwoJy4nKTtcbiAgICpcbiAgICogICAgIC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KGFkZERvdCkudG8uY2hhbmdlKGdldERvdHMpO1xuICAgKlxuICAgKiBXaGVuIHR3byBhcmd1bWVudHMgYXJlIHByb3ZpZGVkLCBgLmNoYW5nZWAgYXNzZXJ0cyB0aGF0IHRoZSB2YWx1ZSBvZiB0aGVcbiAgICogZ2l2ZW4gb2JqZWN0IGBzdWJqZWN0YCdzIGBwcm9wYCBwcm9wZXJ0eSBpcyBkaWZmZXJlbnQgYmVmb3JlIGludm9raW5nIHRoZVxuICAgKiB0YXJnZXQgZnVuY3Rpb24gY29tcGFyZWQgdG8gYWZ0ZXJ3YXJkLlxuICAgKlxuICAgKiAgICAgdmFyIG15T2JqID0ge2RvdHM6ICcnfVxuICAgKiAgICAgICAsIGFkZERvdCA9IGZ1bmN0aW9uICgpIHsgbXlPYmouZG90cyArPSAnLic7IH07XG4gICAqXG4gICAqICAgICAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KG15T2JqKS50by5oYXZlLnByb3BlcnR5KCdkb3RzJywgJycpO1xuICAgKiAgICAgYWRkRG90KCk7XG4gICAqICAgICBleHBlY3QobXlPYmopLnRvLmhhdmUucHJvcGVydHkoJ2RvdHMnLCAnLicpO1xuICAgKlxuICAgKiAgICAgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoYWRkRG90KS50by5jaGFuZ2UobXlPYmosICdkb3RzJyk7XG4gICAqXG4gICAqIFN0cmljdCAoYD09PWApIGVxdWFsaXR5IGlzIHVzZWQgdG8gY29tcGFyZSBiZWZvcmUgYW5kIGFmdGVyIHZhbHVlcy5cbiAgICpcbiAgICogQWRkIGAubm90YCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byBuZWdhdGUgYC5jaGFuZ2VgLlxuICAgKlxuICAgKiAgICAgdmFyIGRvdHMgPSAnJ1xuICAgKiAgICAgICAsIG5vb3AgPSBmdW5jdGlvbiAoKSB7fVxuICAgKiAgICAgICAsIGdldERvdHMgPSBmdW5jdGlvbiAoKSB7IHJldHVybiBkb3RzOyB9O1xuICAgKlxuICAgKiAgICAgZXhwZWN0KG5vb3ApLnRvLm5vdC5jaGFuZ2UoZ2V0RG90cyk7XG4gICAqXG4gICAqICAgICB2YXIgbXlPYmogPSB7ZG90czogJyd9XG4gICAqICAgICAgICwgbm9vcCA9IGZ1bmN0aW9uICgpIHt9O1xuICAgKlxuICAgKiAgICAgZXhwZWN0KG5vb3ApLnRvLm5vdC5jaGFuZ2UobXlPYmosICdkb3RzJyk7XG4gICAqXG4gICAqIGAuY2hhbmdlYCBhY2NlcHRzIGFuIG9wdGlvbmFsIGBtc2dgIGFyZ3VtZW50IHdoaWNoIGlzIGEgY3VzdG9tIGVycm9yXG4gICAqIG1lc3NhZ2UgdG8gc2hvdyB3aGVuIHRoZSBhc3NlcnRpb24gZmFpbHMuIFRoZSBtZXNzYWdlIGNhbiBhbHNvIGJlIGdpdmVuIGFzXG4gICAqIHRoZSBzZWNvbmQgYXJndW1lbnQgdG8gYGV4cGVjdGAuIFdoZW4gbm90IHByb3ZpZGluZyB0d28gYXJndW1lbnRzLCBhbHdheXNcbiAgICogdXNlIHRoZSBzZWNvbmQgZm9ybS5cbiAgICpcbiAgICogICAgIHZhciBteU9iaiA9IHtkb3RzOiAnJ31cbiAgICogICAgICAgLCBhZGREb3QgPSBmdW5jdGlvbiAoKSB7IG15T2JqLmRvdHMgKz0gJy4nOyB9O1xuICAgKlxuICAgKiAgICAgZXhwZWN0KGFkZERvdCkudG8ubm90LmNoYW5nZShteU9iaiwgJ2RvdHMnLCAnbm9vbyB3aHkgZmFpbD8/Jyk7XG4gICAqXG4gICAqICAgICB2YXIgZG90cyA9ICcnXG4gICAqICAgICAgICwgYWRkRG90ID0gZnVuY3Rpb24gKCkgeyBkb3RzICs9ICcuJzsgfVxuICAgKiAgICAgICAsIGdldERvdHMgPSBmdW5jdGlvbiAoKSB7IHJldHVybiBkb3RzOyB9O1xuICAgKlxuICAgKiAgICAgZXhwZWN0KGFkZERvdCwgJ25vb28gd2h5IGZhaWw/PycpLnRvLm5vdC5jaGFuZ2UoZ2V0RG90cyk7XG4gICAqXG4gICAqIGAuY2hhbmdlYCBhbHNvIGNhdXNlcyBhbGwgYC5ieWAgYXNzZXJ0aW9ucyB0aGF0IGZvbGxvdyBpbiB0aGUgY2hhaW4gdG9cbiAgICogYXNzZXJ0IGhvdyBtdWNoIGEgbnVtZXJpYyBzdWJqZWN0IHdhcyBpbmNyZWFzZWQgb3IgZGVjcmVhc2VkIGJ5LiBIb3dldmVyLFxuICAgKiBpdCdzIGRhbmdlcm91cyB0byB1c2UgYC5jaGFuZ2UuYnlgLiBUaGUgcHJvYmxlbSBpcyB0aGF0IGl0IGNyZWF0ZXNcbiAgICogdW5jZXJ0YWluIGV4cGVjdGF0aW9ucyBieSBhc3NlcnRpbmcgdGhhdCB0aGUgc3ViamVjdCBlaXRoZXIgaW5jcmVhc2VzIGJ5XG4gICAqIHRoZSBnaXZlbiBkZWx0YSwgb3IgdGhhdCBpdCBkZWNyZWFzZXMgYnkgdGhlIGdpdmVuIGRlbHRhLiBJdCdzIG9mdGVuIGJlc3RcbiAgICogdG8gaWRlbnRpZnkgdGhlIGV4YWN0IG91dHB1dCB0aGF0J3MgZXhwZWN0ZWQsIGFuZCB0aGVuIHdyaXRlIGFuIGFzc2VydGlvblxuICAgKiB0aGF0IG9ubHkgYWNjZXB0cyB0aGF0IGV4YWN0IG91dHB1dC5cbiAgICpcbiAgICogICAgIHZhciBteU9iaiA9IHt2YWw6IDF9XG4gICAqICAgICAgICwgYWRkVHdvID0gZnVuY3Rpb24gKCkgeyBteU9iai52YWwgKz0gMjsgfVxuICAgKiAgICAgICAsIHN1YnRyYWN0VHdvID0gZnVuY3Rpb24gKCkgeyBteU9iai52YWwgLT0gMjsgfTtcbiAgICpcbiAgICogICAgIGV4cGVjdChhZGRUd28pLnRvLmluY3JlYXNlKG15T2JqLCAndmFsJykuYnkoMik7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoYWRkVHdvKS50by5jaGFuZ2UobXlPYmosICd2YWwnKS5ieSgyKTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqICAgICBleHBlY3Qoc3VidHJhY3RUd28pLnRvLmRlY3JlYXNlKG15T2JqLCAndmFsJykuYnkoMik7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3Qoc3VidHJhY3RUd28pLnRvLmNoYW5nZShteU9iaiwgJ3ZhbCcpLmJ5KDIpOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogVGhlIGFsaWFzIGAuY2hhbmdlc2AgY2FuIGJlIHVzZWQgaW50ZXJjaGFuZ2VhYmx5IHdpdGggYC5jaGFuZ2VgLlxuICAgKlxuICAgKiBAbmFtZSBjaGFuZ2VcbiAgICogQGFsaWFzIGNoYW5nZXNcbiAgICogQHBhcmFtIHtTdHJpbmd9IHN1YmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3AgbmFtZSBfb3B0aW9uYWxfXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtc2cgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBhc3NlcnRDaGFuZ2VzIChzdWJqZWN0LCBwcm9wLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgZm4gPSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCBmbGFnTXNnID0gZmxhZyh0aGlzLCAnbWVzc2FnZScpXG4gICAgICAsIHNzZmkgPSBmbGFnKHRoaXMsICdzc2ZpJyk7XG4gICAgbmV3IEFzc2VydGlvbihmbiwgZmxhZ01zZywgc3NmaSwgdHJ1ZSkuaXMuYSgnZnVuY3Rpb24nKTtcblxuICAgIHZhciBpbml0aWFsO1xuICAgIGlmICghcHJvcCkge1xuICAgICAgbmV3IEFzc2VydGlvbihzdWJqZWN0LCBmbGFnTXNnLCBzc2ZpLCB0cnVlKS5pcy5hKCdmdW5jdGlvbicpO1xuICAgICAgaW5pdGlhbCA9IHN1YmplY3QoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbmV3IEFzc2VydGlvbihzdWJqZWN0LCBmbGFnTXNnLCBzc2ZpLCB0cnVlKS50by5oYXZlLnByb3BlcnR5KHByb3ApO1xuICAgICAgaW5pdGlhbCA9IHN1YmplY3RbcHJvcF07XG4gICAgfVxuXG4gICAgZm4oKTtcblxuICAgIHZhciBmaW5hbCA9IHByb3AgPT09IHVuZGVmaW5lZCB8fCBwcm9wID09PSBudWxsID8gc3ViamVjdCgpIDogc3ViamVjdFtwcm9wXTtcbiAgICB2YXIgbXNnT2JqID0gcHJvcCA9PT0gdW5kZWZpbmVkIHx8IHByb3AgPT09IG51bGwgPyBpbml0aWFsIDogJy4nICsgcHJvcDtcblxuICAgIC8vIFRoaXMgZ2V0cyBmbGFnZ2VkIGJlY2F1c2Ugb2YgdGhlIC5ieShkZWx0YSkgYXNzZXJ0aW9uXG4gICAgZmxhZyh0aGlzLCAnZGVsdGFNc2dPYmonLCBtc2dPYmopO1xuICAgIGZsYWcodGhpcywgJ2luaXRpYWxEZWx0YVZhbHVlJywgaW5pdGlhbCk7XG4gICAgZmxhZyh0aGlzLCAnZmluYWxEZWx0YVZhbHVlJywgZmluYWwpO1xuICAgIGZsYWcodGhpcywgJ2RlbHRhQmVoYXZpb3InLCAnY2hhbmdlJyk7XG4gICAgZmxhZyh0aGlzLCAncmVhbERlbHRhJywgZmluYWwgIT09IGluaXRpYWwpO1xuXG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICBpbml0aWFsICE9PSBmaW5hbFxuICAgICAgLCAnZXhwZWN0ZWQgJyArIG1zZ09iaiArICcgdG8gY2hhbmdlJ1xuICAgICAgLCAnZXhwZWN0ZWQgJyArIG1zZ09iaiArICcgdG8gbm90IGNoYW5nZSdcbiAgICApO1xuICB9XG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnY2hhbmdlJywgYXNzZXJ0Q2hhbmdlcyk7XG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2NoYW5nZXMnLCBhc3NlcnRDaGFuZ2VzKTtcblxuICAvKipcbiAgICogIyMjIC5pbmNyZWFzZShzdWJqZWN0WywgcHJvcFssIG1zZ11dKVxuICAgKlxuICAgKiBXaGVuIG9uZSBhcmd1bWVudCBpcyBwcm92aWRlZCwgYC5pbmNyZWFzZWAgYXNzZXJ0cyB0aGF0IHRoZSBnaXZlbiBmdW5jdGlvblxuICAgKiBgc3ViamVjdGAgcmV0dXJucyBhIGdyZWF0ZXIgbnVtYmVyIHdoZW4gaXQncyBpbnZva2VkIGFmdGVyIGludm9raW5nIHRoZVxuICAgKiB0YXJnZXQgZnVuY3Rpb24gY29tcGFyZWQgdG8gd2hlbiBpdCdzIGludm9rZWQgYmVmb3JlaGFuZC4gYC5pbmNyZWFzZWAgYWxzb1xuICAgKiBjYXVzZXMgYWxsIGAuYnlgIGFzc2VydGlvbnMgdGhhdCBmb2xsb3cgaW4gdGhlIGNoYWluIHRvIGFzc2VydCBob3cgbXVjaFxuICAgKiBncmVhdGVyIG9mIGEgbnVtYmVyIGlzIHJldHVybmVkLiBJdCdzIG9mdGVuIGJlc3QgdG8gYXNzZXJ0IHRoYXQgdGhlIHJldHVyblxuICAgKiB2YWx1ZSBpbmNyZWFzZWQgYnkgdGhlIGV4cGVjdGVkIGFtb3VudCwgcmF0aGVyIHRoYW4gYXNzZXJ0aW5nIGl0IGluY3JlYXNlZFxuICAgKiBieSBhbnkgYW1vdW50LlxuICAgKlxuICAgKiAgICAgdmFyIHZhbCA9IDFcbiAgICogICAgICAgLCBhZGRUd28gPSBmdW5jdGlvbiAoKSB7IHZhbCArPSAyOyB9XG4gICAqICAgICAgICwgZ2V0VmFsID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdmFsOyB9O1xuICAgKlxuICAgKiAgICAgZXhwZWN0KGFkZFR3bykudG8uaW5jcmVhc2UoZ2V0VmFsKS5ieSgyKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdChhZGRUd28pLnRvLmluY3JlYXNlKGdldFZhbCk7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBXaGVuIHR3byBhcmd1bWVudHMgYXJlIHByb3ZpZGVkLCBgLmluY3JlYXNlYCBhc3NlcnRzIHRoYXQgdGhlIHZhbHVlIG9mIHRoZVxuICAgKiBnaXZlbiBvYmplY3QgYHN1YmplY3RgJ3MgYHByb3BgIHByb3BlcnR5IGlzIGdyZWF0ZXIgYWZ0ZXIgaW52b2tpbmcgdGhlXG4gICAqIHRhcmdldCBmdW5jdGlvbiBjb21wYXJlZCB0byBiZWZvcmVoYW5kLlxuICAgKlxuICAgKiAgICAgdmFyIG15T2JqID0ge3ZhbDogMX1cbiAgICogICAgICAgLCBhZGRUd28gPSBmdW5jdGlvbiAoKSB7IG15T2JqLnZhbCArPSAyOyB9O1xuICAgKlxuICAgKiAgICAgZXhwZWN0KGFkZFR3bykudG8uaW5jcmVhc2UobXlPYmosICd2YWwnKS5ieSgyKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdChhZGRUd28pLnRvLmluY3JlYXNlKG15T2JqLCAndmFsJyk7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBBZGQgYC5ub3RgIGVhcmxpZXIgaW4gdGhlIGNoYWluIHRvIG5lZ2F0ZSBgLmluY3JlYXNlYC4gSG93ZXZlciwgaXQnc1xuICAgKiBkYW5nZXJvdXMgdG8gZG8gc28uIFRoZSBwcm9ibGVtIGlzIHRoYXQgaXQgY3JlYXRlcyB1bmNlcnRhaW4gZXhwZWN0YXRpb25zXG4gICAqIGJ5IGFzc2VydGluZyB0aGF0IHRoZSBzdWJqZWN0IGVpdGhlciBkZWNyZWFzZXMsIG9yIHRoYXQgaXQgc3RheXMgdGhlIHNhbWUuXG4gICAqIEl0J3Mgb2Z0ZW4gYmVzdCB0byBpZGVudGlmeSB0aGUgZXhhY3Qgb3V0cHV0IHRoYXQncyBleHBlY3RlZCwgYW5kIHRoZW5cbiAgICogd3JpdGUgYW4gYXNzZXJ0aW9uIHRoYXQgb25seSBhY2NlcHRzIHRoYXQgZXhhY3Qgb3V0cHV0LlxuICAgKlxuICAgKiBXaGVuIHRoZSBzdWJqZWN0IGlzIGV4cGVjdGVkIHRvIGRlY3JlYXNlLCBpdCdzIG9mdGVuIGJlc3QgdG8gYXNzZXJ0IHRoYXQgaXRcbiAgICogZGVjcmVhc2VkIGJ5IHRoZSBleHBlY3RlZCBhbW91bnQuXG4gICAqXG4gICAqICAgICB2YXIgbXlPYmogPSB7dmFsOiAxfVxuICAgKiAgICAgICAsIHN1YnRyYWN0VHdvID0gZnVuY3Rpb24gKCkgeyBteU9iai52YWwgLT0gMjsgfTtcbiAgICpcbiAgICogICAgIGV4cGVjdChzdWJ0cmFjdFR3bykudG8uZGVjcmVhc2UobXlPYmosICd2YWwnKS5ieSgyKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdChzdWJ0cmFjdFR3bykudG8ubm90LmluY3JlYXNlKG15T2JqLCAndmFsJyk7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBXaGVuIHRoZSBzdWJqZWN0IGlzIGV4cGVjdGVkIHRvIHN0YXkgdGhlIHNhbWUsIGl0J3Mgb2Z0ZW4gYmVzdCB0byBhc3NlcnRcbiAgICogZXhhY3RseSB0aGF0LlxuICAgKlxuICAgKiAgICAgdmFyIG15T2JqID0ge3ZhbDogMX1cbiAgICogICAgICAgLCBub29wID0gZnVuY3Rpb24gKCkge307XG4gICAqXG4gICAqICAgICBleHBlY3Qobm9vcCkudG8ubm90LmNoYW5nZShteU9iaiwgJ3ZhbCcpOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KG5vb3ApLnRvLm5vdC5pbmNyZWFzZShteU9iaiwgJ3ZhbCcpOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogYC5pbmNyZWFzZWAgYWNjZXB0cyBhbiBvcHRpb25hbCBgbXNnYCBhcmd1bWVudCB3aGljaCBpcyBhIGN1c3RvbSBlcnJvclxuICAgKiBtZXNzYWdlIHRvIHNob3cgd2hlbiB0aGUgYXNzZXJ0aW9uIGZhaWxzLiBUaGUgbWVzc2FnZSBjYW4gYWxzbyBiZSBnaXZlbiBhc1xuICAgKiB0aGUgc2Vjb25kIGFyZ3VtZW50IHRvIGBleHBlY3RgLiBXaGVuIG5vdCBwcm92aWRpbmcgdHdvIGFyZ3VtZW50cywgYWx3YXlzXG4gICAqIHVzZSB0aGUgc2Vjb25kIGZvcm0uXG4gICAqXG4gICAqICAgICB2YXIgbXlPYmogPSB7dmFsOiAxfVxuICAgKiAgICAgICAsIG5vb3AgPSBmdW5jdGlvbiAoKSB7fTtcbiAgICpcbiAgICogICAgIGV4cGVjdChub29wKS50by5pbmNyZWFzZShteU9iaiwgJ3ZhbCcsICdub29vIHdoeSBmYWlsPz8nKTtcbiAgICpcbiAgICogICAgIHZhciB2YWwgPSAxXG4gICAqICAgICAgICwgbm9vcCA9IGZ1bmN0aW9uICgpIHt9XG4gICAqICAgICAgICwgZ2V0VmFsID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdmFsOyB9O1xuICAgKlxuICAgKiAgICAgZXhwZWN0KG5vb3AsICdub29vIHdoeSBmYWlsPz8nKS50by5pbmNyZWFzZShnZXRWYWwpO1xuICAgKlxuICAgKiBUaGUgYWxpYXMgYC5pbmNyZWFzZXNgIGNhbiBiZSB1c2VkIGludGVyY2hhbmdlYWJseSB3aXRoIGAuaW5jcmVhc2VgLlxuICAgKlxuICAgKiBAbmFtZSBpbmNyZWFzZVxuICAgKiBAYWxpYXMgaW5jcmVhc2VzXG4gICAqIEBwYXJhbSB7U3RyaW5nfEZ1bmN0aW9ufSBzdWJqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wIG5hbWUgX29wdGlvbmFsX1xuICAgKiBAcGFyYW0ge1N0cmluZ30gbXNnIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gYXNzZXJ0SW5jcmVhc2VzIChzdWJqZWN0LCBwcm9wLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgZm4gPSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCBmbGFnTXNnID0gZmxhZyh0aGlzLCAnbWVzc2FnZScpXG4gICAgICAsIHNzZmkgPSBmbGFnKHRoaXMsICdzc2ZpJyk7XG4gICAgbmV3IEFzc2VydGlvbihmbiwgZmxhZ01zZywgc3NmaSwgdHJ1ZSkuaXMuYSgnZnVuY3Rpb24nKTtcblxuICAgIHZhciBpbml0aWFsO1xuICAgIGlmICghcHJvcCkge1xuICAgICAgbmV3IEFzc2VydGlvbihzdWJqZWN0LCBmbGFnTXNnLCBzc2ZpLCB0cnVlKS5pcy5hKCdmdW5jdGlvbicpO1xuICAgICAgaW5pdGlhbCA9IHN1YmplY3QoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbmV3IEFzc2VydGlvbihzdWJqZWN0LCBmbGFnTXNnLCBzc2ZpLCB0cnVlKS50by5oYXZlLnByb3BlcnR5KHByb3ApO1xuICAgICAgaW5pdGlhbCA9IHN1YmplY3RbcHJvcF07XG4gICAgfVxuXG4gICAgLy8gTWFrZSBzdXJlIHRoYXQgdGhlIHRhcmdldCBpcyBhIG51bWJlclxuICAgIG5ldyBBc3NlcnRpb24oaW5pdGlhbCwgZmxhZ01zZywgc3NmaSwgdHJ1ZSkuaXMuYSgnbnVtYmVyJyk7XG5cbiAgICBmbigpO1xuXG4gICAgdmFyIGZpbmFsID0gcHJvcCA9PT0gdW5kZWZpbmVkIHx8IHByb3AgPT09IG51bGwgPyBzdWJqZWN0KCkgOiBzdWJqZWN0W3Byb3BdO1xuICAgIHZhciBtc2dPYmogPSBwcm9wID09PSB1bmRlZmluZWQgfHwgcHJvcCA9PT0gbnVsbCA/IGluaXRpYWwgOiAnLicgKyBwcm9wO1xuXG4gICAgZmxhZyh0aGlzLCAnZGVsdGFNc2dPYmonLCBtc2dPYmopO1xuICAgIGZsYWcodGhpcywgJ2luaXRpYWxEZWx0YVZhbHVlJywgaW5pdGlhbCk7XG4gICAgZmxhZyh0aGlzLCAnZmluYWxEZWx0YVZhbHVlJywgZmluYWwpO1xuICAgIGZsYWcodGhpcywgJ2RlbHRhQmVoYXZpb3InLCAnaW5jcmVhc2UnKTtcbiAgICBmbGFnKHRoaXMsICdyZWFsRGVsdGEnLCBmaW5hbCAtIGluaXRpYWwpO1xuXG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICBmaW5hbCAtIGluaXRpYWwgPiAwXG4gICAgICAsICdleHBlY3RlZCAnICsgbXNnT2JqICsgJyB0byBpbmNyZWFzZSdcbiAgICAgICwgJ2V4cGVjdGVkICcgKyBtc2dPYmogKyAnIHRvIG5vdCBpbmNyZWFzZSdcbiAgICApO1xuICB9XG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnaW5jcmVhc2UnLCBhc3NlcnRJbmNyZWFzZXMpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdpbmNyZWFzZXMnLCBhc3NlcnRJbmNyZWFzZXMpO1xuXG4gIC8qKlxuICAgKiAjIyMgLmRlY3JlYXNlKHN1YmplY3RbLCBwcm9wWywgbXNnXV0pXG4gICAqXG4gICAqIFdoZW4gb25lIGFyZ3VtZW50IGlzIHByb3ZpZGVkLCBgLmRlY3JlYXNlYCBhc3NlcnRzIHRoYXQgdGhlIGdpdmVuIGZ1bmN0aW9uXG4gICAqIGBzdWJqZWN0YCByZXR1cm5zIGEgbGVzc2VyIG51bWJlciB3aGVuIGl0J3MgaW52b2tlZCBhZnRlciBpbnZva2luZyB0aGVcbiAgICogdGFyZ2V0IGZ1bmN0aW9uIGNvbXBhcmVkIHRvIHdoZW4gaXQncyBpbnZva2VkIGJlZm9yZWhhbmQuIGAuZGVjcmVhc2VgIGFsc29cbiAgICogY2F1c2VzIGFsbCBgLmJ5YCBhc3NlcnRpb25zIHRoYXQgZm9sbG93IGluIHRoZSBjaGFpbiB0byBhc3NlcnQgaG93IG11Y2hcbiAgICogbGVzc2VyIG9mIGEgbnVtYmVyIGlzIHJldHVybmVkLiBJdCdzIG9mdGVuIGJlc3QgdG8gYXNzZXJ0IHRoYXQgdGhlIHJldHVyblxuICAgKiB2YWx1ZSBkZWNyZWFzZWQgYnkgdGhlIGV4cGVjdGVkIGFtb3VudCwgcmF0aGVyIHRoYW4gYXNzZXJ0aW5nIGl0IGRlY3JlYXNlZFxuICAgKiBieSBhbnkgYW1vdW50LlxuICAgKlxuICAgKiAgICAgdmFyIHZhbCA9IDFcbiAgICogICAgICAgLCBzdWJ0cmFjdFR3byA9IGZ1bmN0aW9uICgpIHsgdmFsIC09IDI7IH1cbiAgICogICAgICAgLCBnZXRWYWwgPSBmdW5jdGlvbiAoKSB7IHJldHVybiB2YWw7IH07XG4gICAqXG4gICAqICAgICBleHBlY3Qoc3VidHJhY3RUd28pLnRvLmRlY3JlYXNlKGdldFZhbCkuYnkoMik7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3Qoc3VidHJhY3RUd28pLnRvLmRlY3JlYXNlKGdldFZhbCk7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBXaGVuIHR3byBhcmd1bWVudHMgYXJlIHByb3ZpZGVkLCBgLmRlY3JlYXNlYCBhc3NlcnRzIHRoYXQgdGhlIHZhbHVlIG9mIHRoZVxuICAgKiBnaXZlbiBvYmplY3QgYHN1YmplY3RgJ3MgYHByb3BgIHByb3BlcnR5IGlzIGxlc3NlciBhZnRlciBpbnZva2luZyB0aGVcbiAgICogdGFyZ2V0IGZ1bmN0aW9uIGNvbXBhcmVkIHRvIGJlZm9yZWhhbmQuXG4gICAqXG4gICAqICAgICB2YXIgbXlPYmogPSB7dmFsOiAxfVxuICAgKiAgICAgICAsIHN1YnRyYWN0VHdvID0gZnVuY3Rpb24gKCkgeyBteU9iai52YWwgLT0gMjsgfTtcbiAgICpcbiAgICogICAgIGV4cGVjdChzdWJ0cmFjdFR3bykudG8uZGVjcmVhc2UobXlPYmosICd2YWwnKS5ieSgyKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdChzdWJ0cmFjdFR3bykudG8uZGVjcmVhc2UobXlPYmosICd2YWwnKTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqIEFkZCBgLm5vdGAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gbmVnYXRlIGAuZGVjcmVhc2VgLiBIb3dldmVyLCBpdCdzXG4gICAqIGRhbmdlcm91cyB0byBkbyBzby4gVGhlIHByb2JsZW0gaXMgdGhhdCBpdCBjcmVhdGVzIHVuY2VydGFpbiBleHBlY3RhdGlvbnNcbiAgICogYnkgYXNzZXJ0aW5nIHRoYXQgdGhlIHN1YmplY3QgZWl0aGVyIGluY3JlYXNlcywgb3IgdGhhdCBpdCBzdGF5cyB0aGUgc2FtZS5cbiAgICogSXQncyBvZnRlbiBiZXN0IHRvIGlkZW50aWZ5IHRoZSBleGFjdCBvdXRwdXQgdGhhdCdzIGV4cGVjdGVkLCBhbmQgdGhlblxuICAgKiB3cml0ZSBhbiBhc3NlcnRpb24gdGhhdCBvbmx5IGFjY2VwdHMgdGhhdCBleGFjdCBvdXRwdXQuXG4gICAqXG4gICAqIFdoZW4gdGhlIHN1YmplY3QgaXMgZXhwZWN0ZWQgdG8gaW5jcmVhc2UsIGl0J3Mgb2Z0ZW4gYmVzdCB0byBhc3NlcnQgdGhhdCBpdFxuICAgKiBpbmNyZWFzZWQgYnkgdGhlIGV4cGVjdGVkIGFtb3VudC5cbiAgICpcbiAgICogICAgIHZhciBteU9iaiA9IHt2YWw6IDF9XG4gICAqICAgICAgICwgYWRkVHdvID0gZnVuY3Rpb24gKCkgeyBteU9iai52YWwgKz0gMjsgfTtcbiAgICpcbiAgICogICAgIGV4cGVjdChhZGRUd28pLnRvLmluY3JlYXNlKG15T2JqLCAndmFsJykuYnkoMik7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoYWRkVHdvKS50by5ub3QuZGVjcmVhc2UobXlPYmosICd2YWwnKTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqIFdoZW4gdGhlIHN1YmplY3QgaXMgZXhwZWN0ZWQgdG8gc3RheSB0aGUgc2FtZSwgaXQncyBvZnRlbiBiZXN0IHRvIGFzc2VydFxuICAgKiBleGFjdGx5IHRoYXQuXG4gICAqXG4gICAqICAgICB2YXIgbXlPYmogPSB7dmFsOiAxfVxuICAgKiAgICAgICAsIG5vb3AgPSBmdW5jdGlvbiAoKSB7fTtcbiAgICpcbiAgICogICAgIGV4cGVjdChub29wKS50by5ub3QuY2hhbmdlKG15T2JqLCAndmFsJyk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3Qobm9vcCkudG8ubm90LmRlY3JlYXNlKG15T2JqLCAndmFsJyk7IC8vIE5vdCByZWNvbW1lbmRlZFxuICAgKlxuICAgKiBgLmRlY3JlYXNlYCBhY2NlcHRzIGFuIG9wdGlvbmFsIGBtc2dgIGFyZ3VtZW50IHdoaWNoIGlzIGEgY3VzdG9tIGVycm9yXG4gICAqIG1lc3NhZ2UgdG8gc2hvdyB3aGVuIHRoZSBhc3NlcnRpb24gZmFpbHMuIFRoZSBtZXNzYWdlIGNhbiBhbHNvIGJlIGdpdmVuIGFzXG4gICAqIHRoZSBzZWNvbmQgYXJndW1lbnQgdG8gYGV4cGVjdGAuIFdoZW4gbm90IHByb3ZpZGluZyB0d28gYXJndW1lbnRzLCBhbHdheXNcbiAgICogdXNlIHRoZSBzZWNvbmQgZm9ybS5cbiAgICpcbiAgICogICAgIHZhciBteU9iaiA9IHt2YWw6IDF9XG4gICAqICAgICAgICwgbm9vcCA9IGZ1bmN0aW9uICgpIHt9O1xuICAgKlxuICAgKiAgICAgZXhwZWN0KG5vb3ApLnRvLmRlY3JlYXNlKG15T2JqLCAndmFsJywgJ25vb28gd2h5IGZhaWw/PycpO1xuICAgKlxuICAgKiAgICAgdmFyIHZhbCA9IDFcbiAgICogICAgICAgLCBub29wID0gZnVuY3Rpb24gKCkge31cbiAgICogICAgICAgLCBnZXRWYWwgPSBmdW5jdGlvbiAoKSB7IHJldHVybiB2YWw7IH07XG4gICAqXG4gICAqICAgICBleHBlY3Qobm9vcCwgJ25vb28gd2h5IGZhaWw/PycpLnRvLmRlY3JlYXNlKGdldFZhbCk7XG4gICAqXG4gICAqIFRoZSBhbGlhcyBgLmRlY3JlYXNlc2AgY2FuIGJlIHVzZWQgaW50ZXJjaGFuZ2VhYmx5IHdpdGggYC5kZWNyZWFzZWAuXG4gICAqXG4gICAqIEBuYW1lIGRlY3JlYXNlXG4gICAqIEBhbGlhcyBkZWNyZWFzZXNcbiAgICogQHBhcmFtIHtTdHJpbmd8RnVuY3Rpb259IHN1YmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3AgbmFtZSBfb3B0aW9uYWxfXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtc2cgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBhc3NlcnREZWNyZWFzZXMgKHN1YmplY3QsIHByb3AsIG1zZykge1xuICAgIGlmIChtc2cpIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuICAgIHZhciBmbiA9IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAsIGZsYWdNc2cgPSBmbGFnKHRoaXMsICdtZXNzYWdlJylcbiAgICAgICwgc3NmaSA9IGZsYWcodGhpcywgJ3NzZmknKTtcbiAgICBuZXcgQXNzZXJ0aW9uKGZuLCBmbGFnTXNnLCBzc2ZpLCB0cnVlKS5pcy5hKCdmdW5jdGlvbicpO1xuXG4gICAgdmFyIGluaXRpYWw7XG4gICAgaWYgKCFwcm9wKSB7XG4gICAgICBuZXcgQXNzZXJ0aW9uKHN1YmplY3QsIGZsYWdNc2csIHNzZmksIHRydWUpLmlzLmEoJ2Z1bmN0aW9uJyk7XG4gICAgICBpbml0aWFsID0gc3ViamVjdCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBuZXcgQXNzZXJ0aW9uKHN1YmplY3QsIGZsYWdNc2csIHNzZmksIHRydWUpLnRvLmhhdmUucHJvcGVydHkocHJvcCk7XG4gICAgICBpbml0aWFsID0gc3ViamVjdFtwcm9wXTtcbiAgICB9XG5cbiAgICAvLyBNYWtlIHN1cmUgdGhhdCB0aGUgdGFyZ2V0IGlzIGEgbnVtYmVyXG4gICAgbmV3IEFzc2VydGlvbihpbml0aWFsLCBmbGFnTXNnLCBzc2ZpLCB0cnVlKS5pcy5hKCdudW1iZXInKTtcblxuICAgIGZuKCk7XG5cbiAgICB2YXIgZmluYWwgPSBwcm9wID09PSB1bmRlZmluZWQgfHwgcHJvcCA9PT0gbnVsbCA/IHN1YmplY3QoKSA6IHN1YmplY3RbcHJvcF07XG4gICAgdmFyIG1zZ09iaiA9IHByb3AgPT09IHVuZGVmaW5lZCB8fCBwcm9wID09PSBudWxsID8gaW5pdGlhbCA6ICcuJyArIHByb3A7XG5cbiAgICBmbGFnKHRoaXMsICdkZWx0YU1zZ09iaicsIG1zZ09iaik7XG4gICAgZmxhZyh0aGlzLCAnaW5pdGlhbERlbHRhVmFsdWUnLCBpbml0aWFsKTtcbiAgICBmbGFnKHRoaXMsICdmaW5hbERlbHRhVmFsdWUnLCBmaW5hbCk7XG4gICAgZmxhZyh0aGlzLCAnZGVsdGFCZWhhdmlvcicsICdkZWNyZWFzZScpO1xuICAgIGZsYWcodGhpcywgJ3JlYWxEZWx0YScsIGluaXRpYWwgLSBmaW5hbCk7XG5cbiAgICB0aGlzLmFzc2VydChcbiAgICAgIGZpbmFsIC0gaW5pdGlhbCA8IDBcbiAgICAgICwgJ2V4cGVjdGVkICcgKyBtc2dPYmogKyAnIHRvIGRlY3JlYXNlJ1xuICAgICAgLCAnZXhwZWN0ZWQgJyArIG1zZ09iaiArICcgdG8gbm90IGRlY3JlYXNlJ1xuICAgICk7XG4gIH1cblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdkZWNyZWFzZScsIGFzc2VydERlY3JlYXNlcyk7XG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2RlY3JlYXNlcycsIGFzc2VydERlY3JlYXNlcyk7XG5cbiAgLyoqXG4gICAqICMjIyAuYnkoZGVsdGFbLCBtc2ddKVxuICAgKlxuICAgKiBXaGVuIGZvbGxvd2luZyBhbiBgLmluY3JlYXNlYCBhc3NlcnRpb24gaW4gdGhlIGNoYWluLCBgLmJ5YCBhc3NlcnRzIHRoYXRcbiAgICogdGhlIHN1YmplY3Qgb2YgdGhlIGAuaW5jcmVhc2VgIGFzc2VydGlvbiBpbmNyZWFzZWQgYnkgdGhlIGdpdmVuIGBkZWx0YWAuXG4gICAqXG4gICAqICAgICB2YXIgbXlPYmogPSB7dmFsOiAxfVxuICAgKiAgICAgICAsIGFkZFR3byA9IGZ1bmN0aW9uICgpIHsgbXlPYmoudmFsICs9IDI7IH07XG4gICAqXG4gICAqICAgICBleHBlY3QoYWRkVHdvKS50by5pbmNyZWFzZShteU9iaiwgJ3ZhbCcpLmJ5KDIpO1xuICAgKlxuICAgKiBXaGVuIGZvbGxvd2luZyBhIGAuZGVjcmVhc2VgIGFzc2VydGlvbiBpbiB0aGUgY2hhaW4sIGAuYnlgIGFzc2VydHMgdGhhdCB0aGVcbiAgICogc3ViamVjdCBvZiB0aGUgYC5kZWNyZWFzZWAgYXNzZXJ0aW9uIGRlY3JlYXNlZCBieSB0aGUgZ2l2ZW4gYGRlbHRhYC5cbiAgICpcbiAgICogICAgIHZhciBteU9iaiA9IHt2YWw6IDF9XG4gICAqICAgICAgICwgc3VidHJhY3RUd28gPSBmdW5jdGlvbiAoKSB7IG15T2JqLnZhbCAtPSAyOyB9O1xuICAgKlxuICAgKiAgICAgZXhwZWN0KHN1YnRyYWN0VHdvKS50by5kZWNyZWFzZShteU9iaiwgJ3ZhbCcpLmJ5KDIpO1xuICAgKlxuICAgKiBXaGVuIGZvbGxvd2luZyBhIGAuY2hhbmdlYCBhc3NlcnRpb24gaW4gdGhlIGNoYWluLCBgLmJ5YCBhc3NlcnRzIHRoYXQgdGhlXG4gICAqIHN1YmplY3Qgb2YgdGhlIGAuY2hhbmdlYCBhc3NlcnRpb24gZWl0aGVyIGluY3JlYXNlZCBvciBkZWNyZWFzZWQgYnkgdGhlXG4gICAqIGdpdmVuIGBkZWx0YWAuIEhvd2V2ZXIsIGl0J3MgZGFuZ2Vyb3VzIHRvIHVzZSBgLmNoYW5nZS5ieWAuIFRoZSBwcm9ibGVtIGlzXG4gICAqIHRoYXQgaXQgY3JlYXRlcyB1bmNlcnRhaW4gZXhwZWN0YXRpb25zLiBJdCdzIG9mdGVuIGJlc3QgdG8gaWRlbnRpZnkgdGhlXG4gICAqIGV4YWN0IG91dHB1dCB0aGF0J3MgZXhwZWN0ZWQsIGFuZCB0aGVuIHdyaXRlIGFuIGFzc2VydGlvbiB0aGF0IG9ubHkgYWNjZXB0c1xuICAgKiB0aGF0IGV4YWN0IG91dHB1dC5cbiAgICpcbiAgICogICAgIHZhciBteU9iaiA9IHt2YWw6IDF9XG4gICAqICAgICAgICwgYWRkVHdvID0gZnVuY3Rpb24gKCkgeyBteU9iai52YWwgKz0gMjsgfVxuICAgKiAgICAgICAsIHN1YnRyYWN0VHdvID0gZnVuY3Rpb24gKCkgeyBteU9iai52YWwgLT0gMjsgfTtcbiAgICpcbiAgICogICAgIGV4cGVjdChhZGRUd28pLnRvLmluY3JlYXNlKG15T2JqLCAndmFsJykuYnkoMik7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoYWRkVHdvKS50by5jaGFuZ2UobXlPYmosICd2YWwnKS5ieSgyKTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqICAgICBleHBlY3Qoc3VidHJhY3RUd28pLnRvLmRlY3JlYXNlKG15T2JqLCAndmFsJykuYnkoMik7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3Qoc3VidHJhY3RUd28pLnRvLmNoYW5nZShteU9iaiwgJ3ZhbCcpLmJ5KDIpOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogQWRkIGAubm90YCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byBuZWdhdGUgYC5ieWAuIEhvd2V2ZXIsIGl0J3Mgb2Z0ZW4gYmVzdFxuICAgKiB0byBhc3NlcnQgdGhhdCB0aGUgc3ViamVjdCBjaGFuZ2VkIGJ5IGl0cyBleHBlY3RlZCBkZWx0YSwgcmF0aGVyIHRoYW5cbiAgICogYXNzZXJ0aW5nIHRoYXQgaXQgZGlkbid0IGNoYW5nZSBieSBvbmUgb2YgY291bnRsZXNzIHVuZXhwZWN0ZWQgZGVsdGFzLlxuICAgKlxuICAgKiAgICAgdmFyIG15T2JqID0ge3ZhbDogMX1cbiAgICogICAgICAgLCBhZGRUd28gPSBmdW5jdGlvbiAoKSB7IG15T2JqLnZhbCArPSAyOyB9O1xuICAgKlxuICAgKiAgICAgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdChhZGRUd28pLnRvLmluY3JlYXNlKG15T2JqLCAndmFsJykuYnkoMik7XG4gICAqXG4gICAqICAgICAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdChhZGRUd28pLnRvLmluY3JlYXNlKG15T2JqLCAndmFsJykuYnV0Lm5vdC5ieSgzKTtcbiAgICpcbiAgICogYC5ieWAgYWNjZXB0cyBhbiBvcHRpb25hbCBgbXNnYCBhcmd1bWVudCB3aGljaCBpcyBhIGN1c3RvbSBlcnJvciBtZXNzYWdlIHRvXG4gICAqIHNob3cgd2hlbiB0aGUgYXNzZXJ0aW9uIGZhaWxzLiBUaGUgbWVzc2FnZSBjYW4gYWxzbyBiZSBnaXZlbiBhcyB0aGUgc2Vjb25kXG4gICAqIGFyZ3VtZW50IHRvIGBleHBlY3RgLlxuICAgKlxuICAgKiAgICAgdmFyIG15T2JqID0ge3ZhbDogMX1cbiAgICogICAgICAgLCBhZGRUd28gPSBmdW5jdGlvbiAoKSB7IG15T2JqLnZhbCArPSAyOyB9O1xuICAgKlxuICAgKiAgICAgZXhwZWN0KGFkZFR3bykudG8uaW5jcmVhc2UobXlPYmosICd2YWwnKS5ieSgzLCAnbm9vbyB3aHkgZmFpbD8/Jyk7XG4gICAqICAgICBleHBlY3QoYWRkVHdvLCAnbm9vbyB3aHkgZmFpbD8/JykudG8uaW5jcmVhc2UobXlPYmosICd2YWwnKS5ieSgzKTtcbiAgICpcbiAgICogQG5hbWUgYnlcbiAgICogQHBhcmFtIHtOdW1iZXJ9IGRlbHRhXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtc2cgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBhc3NlcnREZWx0YShkZWx0YSwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG5cbiAgICB2YXIgbXNnT2JqID0gZmxhZyh0aGlzLCAnZGVsdGFNc2dPYmonKTtcbiAgICB2YXIgaW5pdGlhbCA9IGZsYWcodGhpcywgJ2luaXRpYWxEZWx0YVZhbHVlJyk7XG4gICAgdmFyIGZpbmFsID0gZmxhZyh0aGlzLCAnZmluYWxEZWx0YVZhbHVlJyk7XG4gICAgdmFyIGJlaGF2aW9yID0gZmxhZyh0aGlzLCAnZGVsdGFCZWhhdmlvcicpO1xuICAgIHZhciByZWFsRGVsdGEgPSBmbGFnKHRoaXMsICdyZWFsRGVsdGEnKTtcblxuICAgIHZhciBleHByZXNzaW9uO1xuICAgIGlmIChiZWhhdmlvciA9PT0gJ2NoYW5nZScpIHtcbiAgICAgIGV4cHJlc3Npb24gPSBNYXRoLmFicyhmaW5hbCAtIGluaXRpYWwpID09PSBNYXRoLmFicyhkZWx0YSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGV4cHJlc3Npb24gPSByZWFsRGVsdGEgPT09IE1hdGguYWJzKGRlbHRhKTtcbiAgICB9XG5cbiAgICB0aGlzLmFzc2VydChcbiAgICAgIGV4cHJlc3Npb25cbiAgICAgICwgJ2V4cGVjdGVkICcgKyBtc2dPYmogKyAnIHRvICcgKyBiZWhhdmlvciArICcgYnkgJyArIGRlbHRhXG4gICAgICAsICdleHBlY3RlZCAnICsgbXNnT2JqICsgJyB0byBub3QgJyArIGJlaGF2aW9yICsgJyBieSAnICsgZGVsdGFcbiAgICApO1xuICB9XG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnYnknLCBhc3NlcnREZWx0YSk7XG5cbiAgLyoqXG4gICAqICMjIyAuZXh0ZW5zaWJsZVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBleHRlbnNpYmxlLCB3aGljaCBtZWFucyB0aGF0IG5ldyBwcm9wZXJ0aWVzIGNhblxuICAgKiBiZSBhZGRlZCB0byBpdC4gUHJpbWl0aXZlcyBhcmUgbmV2ZXIgZXh0ZW5zaWJsZS5cbiAgICpcbiAgICogICAgIGV4cGVjdCh7YTogMX0pLnRvLmJlLmV4dGVuc2libGU7XG4gICAqXG4gICAqIEFkZCBgLm5vdGAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gbmVnYXRlIGAuZXh0ZW5zaWJsZWAuXG4gICAqXG4gICAqICAgICB2YXIgbm9uRXh0ZW5zaWJsZU9iamVjdCA9IE9iamVjdC5wcmV2ZW50RXh0ZW5zaW9ucyh7fSlcbiAgICogICAgICAgLCBzZWFsZWRPYmplY3QgPSBPYmplY3Quc2VhbCh7fSlcbiAgICogICAgICAgLCBmcm96ZW5PYmplY3QgPSBPYmplY3QuZnJlZXplKHt9KTtcbiAgICpcbiAgICogICAgIGV4cGVjdChub25FeHRlbnNpYmxlT2JqZWN0KS50by5ub3QuYmUuZXh0ZW5zaWJsZTtcbiAgICogICAgIGV4cGVjdChzZWFsZWRPYmplY3QpLnRvLm5vdC5iZS5leHRlbnNpYmxlO1xuICAgKiAgICAgZXhwZWN0KGZyb3plbk9iamVjdCkudG8ubm90LmJlLmV4dGVuc2libGU7XG4gICAqICAgICBleHBlY3QoMSkudG8ubm90LmJlLmV4dGVuc2libGU7XG4gICAqXG4gICAqIEEgY3VzdG9tIGVycm9yIG1lc3NhZ2UgY2FuIGJlIGdpdmVuIGFzIHRoZSBzZWNvbmQgYXJndW1lbnQgdG8gYGV4cGVjdGAuXG4gICAqXG4gICAqICAgICBleHBlY3QoMSwgJ25vb28gd2h5IGZhaWw/PycpLnRvLmJlLmV4dGVuc2libGU7XG4gICAqXG4gICAqIEBuYW1lIGV4dGVuc2libGVcbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgQXNzZXJ0aW9uLmFkZFByb3BlcnR5KCdleHRlbnNpYmxlJywgZnVuY3Rpb24oKSB7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpO1xuXG4gICAgLy8gSW4gRVM1LCBpZiB0aGUgYXJndW1lbnQgdG8gdGhpcyBtZXRob2QgaXMgYSBwcmltaXRpdmUsIHRoZW4gaXQgd2lsbCBjYXVzZSBhIFR5cGVFcnJvci5cbiAgICAvLyBJbiBFUzYsIGEgbm9uLW9iamVjdCBhcmd1bWVudCB3aWxsIGJlIHRyZWF0ZWQgYXMgaWYgaXQgd2FzIGEgbm9uLWV4dGVuc2libGUgb3JkaW5hcnkgb2JqZWN0LCBzaW1wbHkgcmV0dXJuIGZhbHNlLlxuICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL09iamVjdC9pc0V4dGVuc2libGVcbiAgICAvLyBUaGUgZm9sbG93aW5nIHByb3ZpZGVzIEVTNiBiZWhhdmlvciBmb3IgRVM1IGVudmlyb25tZW50cy5cblxuICAgIHZhciBpc0V4dGVuc2libGUgPSBvYmogPT09IE9iamVjdChvYmopICYmIE9iamVjdC5pc0V4dGVuc2libGUob2JqKTtcblxuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgaXNFeHRlbnNpYmxlXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIGV4dGVuc2libGUnXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBiZSBleHRlbnNpYmxlJ1xuICAgICk7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiAjIyMgLnNlYWxlZFxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBzZWFsZWQsIHdoaWNoIG1lYW5zIHRoYXQgbmV3IHByb3BlcnRpZXMgY2FuJ3QgYmVcbiAgICogYWRkZWQgdG8gaXQsIGFuZCBpdHMgZXhpc3RpbmcgcHJvcGVydGllcyBjYW4ndCBiZSByZWNvbmZpZ3VyZWQgb3IgZGVsZXRlZC5cbiAgICogSG93ZXZlciwgaXQncyBwb3NzaWJsZSB0aGF0IGl0cyBleGlzdGluZyBwcm9wZXJ0aWVzIGNhbiBzdGlsbCBiZSByZWFzc2lnbmVkXG4gICAqIHRvIGRpZmZlcmVudCB2YWx1ZXMuIFByaW1pdGl2ZXMgYXJlIGFsd2F5cyBzZWFsZWQuXG4gICAqXG4gICAqICAgICB2YXIgc2VhbGVkT2JqZWN0ID0gT2JqZWN0LnNlYWwoe30pO1xuICAgKiAgICAgdmFyIGZyb3plbk9iamVjdCA9IE9iamVjdC5mcmVlemUoe30pO1xuICAgKlxuICAgKiAgICAgZXhwZWN0KHNlYWxlZE9iamVjdCkudG8uYmUuc2VhbGVkO1xuICAgKiAgICAgZXhwZWN0KGZyb3plbk9iamVjdCkudG8uYmUuc2VhbGVkO1xuICAgKiAgICAgZXhwZWN0KDEpLnRvLmJlLnNlYWxlZDtcbiAgICpcbiAgICogQWRkIGAubm90YCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byBuZWdhdGUgYC5zZWFsZWRgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KHthOiAxfSkudG8ubm90LmJlLnNlYWxlZDtcbiAgICpcbiAgICogQSBjdXN0b20gZXJyb3IgbWVzc2FnZSBjYW4gYmUgZ2l2ZW4gYXMgdGhlIHNlY29uZCBhcmd1bWVudCB0byBgZXhwZWN0YC5cbiAgICpcbiAgICogICAgIGV4cGVjdCh7YTogMX0sICdub29vIHdoeSBmYWlsPz8nKS50by5iZS5zZWFsZWQ7XG4gICAqXG4gICAqIEBuYW1lIHNlYWxlZFxuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBBc3NlcnRpb24uYWRkUHJvcGVydHkoJ3NlYWxlZCcsIGZ1bmN0aW9uKCkge1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKTtcblxuICAgIC8vIEluIEVTNSwgaWYgdGhlIGFyZ3VtZW50IHRvIHRoaXMgbWV0aG9kIGlzIGEgcHJpbWl0aXZlLCB0aGVuIGl0IHdpbGwgY2F1c2UgYSBUeXBlRXJyb3IuXG4gICAgLy8gSW4gRVM2LCBhIG5vbi1vYmplY3QgYXJndW1lbnQgd2lsbCBiZSB0cmVhdGVkIGFzIGlmIGl0IHdhcyBhIHNlYWxlZCBvcmRpbmFyeSBvYmplY3QsIHNpbXBseSByZXR1cm4gdHJ1ZS5cbiAgICAvLyBTZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvT2JqZWN0L2lzU2VhbGVkXG4gICAgLy8gVGhlIGZvbGxvd2luZyBwcm92aWRlcyBFUzYgYmVoYXZpb3IgZm9yIEVTNSBlbnZpcm9ubWVudHMuXG5cbiAgICB2YXIgaXNTZWFsZWQgPSBvYmogPT09IE9iamVjdChvYmopID8gT2JqZWN0LmlzU2VhbGVkKG9iaikgOiB0cnVlO1xuXG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICBpc1NlYWxlZFxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBzZWFsZWQnXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBiZSBzZWFsZWQnXG4gICAgKTtcbiAgfSk7XG5cbiAgLyoqXG4gICAqICMjIyAuZnJvemVuXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGZyb3plbiwgd2hpY2ggbWVhbnMgdGhhdCBuZXcgcHJvcGVydGllcyBjYW4ndCBiZVxuICAgKiBhZGRlZCB0byBpdCwgYW5kIGl0cyBleGlzdGluZyBwcm9wZXJ0aWVzIGNhbid0IGJlIHJlYXNzaWduZWQgdG8gZGlmZmVyZW50XG4gICAqIHZhbHVlcywgcmVjb25maWd1cmVkLCBvciBkZWxldGVkLiBQcmltaXRpdmVzIGFyZSBhbHdheXMgZnJvemVuLlxuICAgKlxuICAgKiAgICAgdmFyIGZyb3plbk9iamVjdCA9IE9iamVjdC5mcmVlemUoe30pO1xuICAgKlxuICAgKiAgICAgZXhwZWN0KGZyb3plbk9iamVjdCkudG8uYmUuZnJvemVuO1xuICAgKiAgICAgZXhwZWN0KDEpLnRvLmJlLmZyb3plbjtcbiAgICpcbiAgICogQWRkIGAubm90YCBlYXJsaWVyIGluIHRoZSBjaGFpbiB0byBuZWdhdGUgYC5mcm96ZW5gLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KHthOiAxfSkudG8ubm90LmJlLmZyb3plbjtcbiAgICpcbiAgICogQSBjdXN0b20gZXJyb3IgbWVzc2FnZSBjYW4gYmUgZ2l2ZW4gYXMgdGhlIHNlY29uZCBhcmd1bWVudCB0byBgZXhwZWN0YC5cbiAgICpcbiAgICogICAgIGV4cGVjdCh7YTogMX0sICdub29vIHdoeSBmYWlsPz8nKS50by5iZS5mcm96ZW47XG4gICAqXG4gICAqIEBuYW1lIGZyb3plblxuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBBc3NlcnRpb24uYWRkUHJvcGVydHkoJ2Zyb3plbicsIGZ1bmN0aW9uKCkge1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKTtcblxuICAgIC8vIEluIEVTNSwgaWYgdGhlIGFyZ3VtZW50IHRvIHRoaXMgbWV0aG9kIGlzIGEgcHJpbWl0aXZlLCB0aGVuIGl0IHdpbGwgY2F1c2UgYSBUeXBlRXJyb3IuXG4gICAgLy8gSW4gRVM2LCBhIG5vbi1vYmplY3QgYXJndW1lbnQgd2lsbCBiZSB0cmVhdGVkIGFzIGlmIGl0IHdhcyBhIGZyb3plbiBvcmRpbmFyeSBvYmplY3QsIHNpbXBseSByZXR1cm4gdHJ1ZS5cbiAgICAvLyBTZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvT2JqZWN0L2lzRnJvemVuXG4gICAgLy8gVGhlIGZvbGxvd2luZyBwcm92aWRlcyBFUzYgYmVoYXZpb3IgZm9yIEVTNSBlbnZpcm9ubWVudHMuXG5cbiAgICB2YXIgaXNGcm96ZW4gPSBvYmogPT09IE9iamVjdChvYmopID8gT2JqZWN0LmlzRnJvemVuKG9iaikgOiB0cnVlO1xuXG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICBpc0Zyb3plblxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBmcm96ZW4nXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBiZSBmcm96ZW4nXG4gICAgKTtcbiAgfSk7XG5cbiAgLyoqXG4gICAqICMjIyAuZmluaXRlXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGEgbnVtYmVyLCBhbmQgaXNuJ3QgYE5hTmAgb3IgcG9zaXRpdmUvbmVnYXRpdmVcbiAgICogYEluZmluaXR5YC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgxKS50by5iZS5maW5pdGU7XG4gICAqXG4gICAqIEFkZCBgLm5vdGAgZWFybGllciBpbiB0aGUgY2hhaW4gdG8gbmVnYXRlIGAuZmluaXRlYC4gSG93ZXZlciwgaXQnc1xuICAgKiBkYW5nZXJvdXMgdG8gZG8gc28uIFRoZSBwcm9ibGVtIGlzIHRoYXQgaXQgY3JlYXRlcyB1bmNlcnRhaW4gZXhwZWN0YXRpb25zXG4gICAqIGJ5IGFzc2VydGluZyB0aGF0IHRoZSBzdWJqZWN0IGVpdGhlciBpc24ndCBhIG51bWJlciwgb3IgdGhhdCBpdCdzIGBOYU5gLCBvclxuICAgKiB0aGF0IGl0J3MgcG9zaXRpdmUgYEluZmluaXR5YCwgb3IgdGhhdCBpdCdzIG5lZ2F0aXZlIGBJbmZpbml0eWAuIEl0J3Mgb2Z0ZW5cbiAgICogYmVzdCB0byBpZGVudGlmeSB0aGUgZXhhY3Qgb3V0cHV0IHRoYXQncyBleHBlY3RlZCwgYW5kIHRoZW4gd3JpdGUgYW5cbiAgICogYXNzZXJ0aW9uIHRoYXQgb25seSBhY2NlcHRzIHRoYXQgZXhhY3Qgb3V0cHV0LlxuICAgKlxuICAgKiBXaGVuIHRoZSB0YXJnZXQgaXNuJ3QgZXhwZWN0ZWQgdG8gYmUgYSBudW1iZXIsIGl0J3Mgb2Z0ZW4gYmVzdCB0byBhc3NlcnRcbiAgICogdGhhdCBpdCdzIHRoZSBleHBlY3RlZCB0eXBlLCByYXRoZXIgdGhhbiBhc3NlcnRpbmcgdGhhdCBpdCBpc24ndCBvbmUgb2ZcbiAgICogbWFueSB1bmV4cGVjdGVkIHR5cGVzLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KCdmb28nKS50by5iZS5hKCdzdHJpbmcnKTsgLy8gUmVjb21tZW5kZWRcbiAgICogICAgIGV4cGVjdCgnZm9vJykudG8ubm90LmJlLmZpbml0ZTsgLy8gTm90IHJlY29tbWVuZGVkXG4gICAqXG4gICAqIFdoZW4gdGhlIHRhcmdldCBpcyBleHBlY3RlZCB0byBiZSBgTmFOYCwgaXQncyBvZnRlbiBiZXN0IHRvIGFzc2VydCBleGFjdGx5XG4gICAqIHRoYXQuXG4gICAqXG4gICAqICAgICBleHBlY3QoTmFOKS50by5iZS5OYU47IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoTmFOKS50by5ub3QuYmUuZmluaXRlOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogV2hlbiB0aGUgdGFyZ2V0IGlzIGV4cGVjdGVkIHRvIGJlIHBvc2l0aXZlIGluZmluaXR5LCBpdCdzIG9mdGVuIGJlc3QgdG9cbiAgICogYXNzZXJ0IGV4YWN0bHkgdGhhdC5cbiAgICpcbiAgICogICAgIGV4cGVjdChJbmZpbml0eSkudG8uZXF1YWwoSW5maW5pdHkpOyAvLyBSZWNvbW1lbmRlZFxuICAgKiAgICAgZXhwZWN0KEluZmluaXR5KS50by5ub3QuYmUuZmluaXRlOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogV2hlbiB0aGUgdGFyZ2V0IGlzIGV4cGVjdGVkIHRvIGJlIG5lZ2F0aXZlIGluZmluaXR5LCBpdCdzIG9mdGVuIGJlc3QgdG9cbiAgICogYXNzZXJ0IGV4YWN0bHkgdGhhdC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgtSW5maW5pdHkpLnRvLmVxdWFsKC1JbmZpbml0eSk7IC8vIFJlY29tbWVuZGVkXG4gICAqICAgICBleHBlY3QoLUluZmluaXR5KS50by5ub3QuYmUuZmluaXRlOyAvLyBOb3QgcmVjb21tZW5kZWRcbiAgICpcbiAgICogQSBjdXN0b20gZXJyb3IgbWVzc2FnZSBjYW4gYmUgZ2l2ZW4gYXMgdGhlIHNlY29uZCBhcmd1bWVudCB0byBgZXhwZWN0YC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgnZm9vJywgJ25vb28gd2h5IGZhaWw/PycpLnRvLmJlLmZpbml0ZTtcbiAgICpcbiAgICogQG5hbWUgZmluaXRlXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgnZmluaXRlJywgZnVuY3Rpb24obXNnKSB7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpO1xuXG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICAgIHR5cGVvZiBvYmogPT09ICdudW1iZXInICYmIGlzRmluaXRlKG9iailcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgYSBmaW5pdGUgbnVtYmVyJ1xuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgYmUgYSBmaW5pdGUgbnVtYmVyJ1xuICAgICk7XG4gIH0pO1xufTtcbiIsICIvKiFcbiAqIGNoYWlcbiAqIENvcHlyaWdodChjKSAyMDExLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChjaGFpLCB1dGlsKSB7XG4gIGNoYWkuZXhwZWN0ID0gZnVuY3Rpb24gKHZhbCwgbWVzc2FnZSkge1xuICAgIHJldHVybiBuZXcgY2hhaS5Bc3NlcnRpb24odmFsLCBtZXNzYWdlKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5mYWlsKFttZXNzYWdlXSlcbiAgICogIyMjIC5mYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIFttZXNzYWdlXSwgW29wZXJhdG9yXSlcbiAgICpcbiAgICogVGhyb3cgYSBmYWlsdXJlLlxuICAgKlxuICAgKiAgICAgZXhwZWN0LmZhaWwoKTtcbiAgICogICAgIGV4cGVjdC5mYWlsKFwiY3VzdG9tIGVycm9yIG1lc3NhZ2VcIik7XG4gICAqICAgICBleHBlY3QuZmFpbCgxLCAyKTtcbiAgICogICAgIGV4cGVjdC5mYWlsKDEsIDIsIFwiY3VzdG9tIGVycm9yIG1lc3NhZ2VcIik7XG4gICAqICAgICBleHBlY3QuZmFpbCgxLCAyLCBcImN1c3RvbSBlcnJvciBtZXNzYWdlXCIsIFwiPlwiKTtcbiAgICogICAgIGV4cGVjdC5mYWlsKDEsIDIsIHVuZGVmaW5lZCwgXCI+XCIpO1xuICAgKlxuICAgKiBAbmFtZSBmYWlsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IGFjdHVhbFxuICAgKiBAcGFyYW0ge01peGVkfSBleHBlY3RlZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gb3BlcmF0b3JcbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgY2hhaS5leHBlY3QuZmFpbCA9IGZ1bmN0aW9uIChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCBvcGVyYXRvcikge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMikge1xuICAgICAgICBtZXNzYWdlID0gYWN0dWFsO1xuICAgICAgICBhY3R1YWwgPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgbWVzc2FnZSA9IG1lc3NhZ2UgfHwgJ2V4cGVjdC5mYWlsKCknO1xuICAgIHRocm93IG5ldyBjaGFpLkFzc2VydGlvbkVycm9yKG1lc3NhZ2UsIHtcbiAgICAgICAgYWN0dWFsOiBhY3R1YWxcbiAgICAgICwgZXhwZWN0ZWQ6IGV4cGVjdGVkXG4gICAgICAsIG9wZXJhdG9yOiBvcGVyYXRvclxuICAgIH0sIGNoYWkuZXhwZWN0LmZhaWwpO1xuICB9O1xufTtcbiIsICIvKiFcbiAqIGNoYWlcbiAqIENvcHlyaWdodChjKSAyMDExLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChjaGFpLCB1dGlsKSB7XG4gIHZhciBBc3NlcnRpb24gPSBjaGFpLkFzc2VydGlvbjtcblxuICBmdW5jdGlvbiBsb2FkU2hvdWxkICgpIHtcbiAgICAvLyBleHBsaWNpdGx5IGRlZmluZSB0aGlzIG1ldGhvZCBhcyBmdW5jdGlvbiBhcyB0byBoYXZlIGl0J3MgbmFtZSB0byBpbmNsdWRlIGFzIGBzc2ZpYFxuICAgIGZ1bmN0aW9uIHNob3VsZEdldHRlcigpIHtcbiAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgU3RyaW5nXG4gICAgICAgICAgfHwgdGhpcyBpbnN0YW5jZW9mIE51bWJlclxuICAgICAgICAgIHx8IHRoaXMgaW5zdGFuY2VvZiBCb29sZWFuXG4gICAgICAgICAgfHwgdHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiB0aGlzIGluc3RhbmNlb2YgU3ltYm9sXG4gICAgICAgICAgfHwgdHlwZW9mIEJpZ0ludCA9PT0gJ2Z1bmN0aW9uJyAmJiB0aGlzIGluc3RhbmNlb2YgQmlnSW50KSB7XG4gICAgICAgIHJldHVybiBuZXcgQXNzZXJ0aW9uKHRoaXMudmFsdWVPZigpLCBudWxsLCBzaG91bGRHZXR0ZXIpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ldyBBc3NlcnRpb24odGhpcywgbnVsbCwgc2hvdWxkR2V0dGVyKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gc2hvdWxkU2V0dGVyKHZhbHVlKSB7XG4gICAgICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2NoYWlqcy9jaGFpL2lzc3Vlcy84NjogdGhpcyBtYWtlc1xuICAgICAgLy8gYHdoYXRldmVyLnNob3VsZCA9IHNvbWVWYWx1ZWAgYWN0dWFsbHkgc2V0IGBzb21lVmFsdWVgLCB3aGljaCBpc1xuICAgICAgLy8gZXNwZWNpYWxseSB1c2VmdWwgZm9yIGBnbG9iYWwuc2hvdWxkID0gcmVxdWlyZSgnY2hhaScpLnNob3VsZCgpYC5cbiAgICAgIC8vXG4gICAgICAvLyBOb3RlIHRoYXQgd2UgaGF2ZSB0byB1c2UgW1tEZWZpbmVQcm9wZXJ0eV1dIGluc3RlYWQgb2YgW1tQdXRdXVxuICAgICAgLy8gc2luY2Ugb3RoZXJ3aXNlIHdlIHdvdWxkIHRyaWdnZXIgdGhpcyB2ZXJ5IHNldHRlciFcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnc2hvdWxkJywge1xuICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgd3JpdGFibGU6IHRydWVcbiAgICAgIH0pO1xuICAgIH1cbiAgICAvLyBtb2RpZnkgT2JqZWN0LnByb3RvdHlwZSB0byBoYXZlIGBzaG91bGRgXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KE9iamVjdC5wcm90b3R5cGUsICdzaG91bGQnLCB7XG4gICAgICBzZXQ6IHNob3VsZFNldHRlclxuICAgICAgLCBnZXQ6IHNob3VsZEdldHRlclxuICAgICAgLCBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KTtcblxuICAgIHZhciBzaG91bGQgPSB7fTtcblxuICAgIC8qKlxuICAgICAqICMjIyAuZmFpbChbbWVzc2FnZV0pXG4gICAgICogIyMjIC5mYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIFttZXNzYWdlXSwgW29wZXJhdG9yXSlcbiAgICAgKlxuICAgICAqIFRocm93IGEgZmFpbHVyZS5cbiAgICAgKlxuICAgICAqICAgICBzaG91bGQuZmFpbCgpO1xuICAgICAqICAgICBzaG91bGQuZmFpbChcImN1c3RvbSBlcnJvciBtZXNzYWdlXCIpO1xuICAgICAqICAgICBzaG91bGQuZmFpbCgxLCAyKTtcbiAgICAgKiAgICAgc2hvdWxkLmZhaWwoMSwgMiwgXCJjdXN0b20gZXJyb3IgbWVzc2FnZVwiKTtcbiAgICAgKiAgICAgc2hvdWxkLmZhaWwoMSwgMiwgXCJjdXN0b20gZXJyb3IgbWVzc2FnZVwiLCBcIj5cIik7XG4gICAgICogICAgIHNob3VsZC5mYWlsKDEsIDIsIHVuZGVmaW5lZCwgXCI+XCIpO1xuICAgICAqXG4gICAgICpcbiAgICAgKiBAbmFtZSBmYWlsXG4gICAgICogQHBhcmFtIHtNaXhlZH0gYWN0dWFsXG4gICAgICogQHBhcmFtIHtNaXhlZH0gZXhwZWN0ZWRcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBvcGVyYXRvclxuICAgICAqIEBuYW1lc3BhY2UgQkREXG4gICAgICogQGFwaSBwdWJsaWNcbiAgICAgKi9cblxuICAgIHNob3VsZC5mYWlsID0gZnVuY3Rpb24gKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsIG9wZXJhdG9yKSB7XG4gICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgICBtZXNzYWdlID0gYWN0dWFsO1xuICAgICAgICAgIGFjdHVhbCA9IHVuZGVmaW5lZDtcbiAgICAgIH1cblxuICAgICAgbWVzc2FnZSA9IG1lc3NhZ2UgfHwgJ3Nob3VsZC5mYWlsKCknO1xuICAgICAgdGhyb3cgbmV3IGNoYWkuQXNzZXJ0aW9uRXJyb3IobWVzc2FnZSwge1xuICAgICAgICAgIGFjdHVhbDogYWN0dWFsXG4gICAgICAgICwgZXhwZWN0ZWQ6IGV4cGVjdGVkXG4gICAgICAgICwgb3BlcmF0b3I6IG9wZXJhdG9yXG4gICAgICB9LCBzaG91bGQuZmFpbCk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqICMjIyAuZXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgW21lc3NhZ2VdKVxuICAgICAqXG4gICAgICogQXNzZXJ0cyBub24tc3RyaWN0IGVxdWFsaXR5IChgPT1gKSBvZiBgYWN0dWFsYCBhbmQgYGV4cGVjdGVkYC5cbiAgICAgKlxuICAgICAqICAgICBzaG91bGQuZXF1YWwoMywgJzMnLCAnPT0gY29lcmNlcyB2YWx1ZXMgdG8gc3RyaW5ncycpO1xuICAgICAqXG4gICAgICogQG5hbWUgZXF1YWxcbiAgICAgKiBAcGFyYW0ge01peGVkfSBhY3R1YWxcbiAgICAgKiBAcGFyYW0ge01peGVkfSBleHBlY3RlZFxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAgICogQG5hbWVzcGFjZSBTaG91bGRcbiAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAqL1xuXG4gICAgc2hvdWxkLmVxdWFsID0gZnVuY3Rpb24gKHZhbDEsIHZhbDIsIG1zZykge1xuICAgICAgbmV3IEFzc2VydGlvbih2YWwxLCBtc2cpLnRvLmVxdWFsKHZhbDIpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiAjIyMgLnRocm93KGZ1bmN0aW9uLCBbY29uc3RydWN0b3Ivc3RyaW5nL3JlZ2V4cF0sIFtzdHJpbmcvcmVnZXhwXSwgW21lc3NhZ2VdKVxuICAgICAqXG4gICAgICogQXNzZXJ0cyB0aGF0IGBmdW5jdGlvbmAgd2lsbCB0aHJvdyBhbiBlcnJvciB0aGF0IGlzIGFuIGluc3RhbmNlIG9mXG4gICAgICogYGNvbnN0cnVjdG9yYCwgb3IgYWx0ZXJuYXRlbHkgdGhhdCBpdCB3aWxsIHRocm93IGFuIGVycm9yIHdpdGggbWVzc2FnZVxuICAgICAqIG1hdGNoaW5nIGByZWdleHBgLlxuICAgICAqXG4gICAgICogICAgIHNob3VsZC50aHJvdyhmbiwgJ2Z1bmN0aW9uIHRocm93cyBhIHJlZmVyZW5jZSBlcnJvcicpO1xuICAgICAqICAgICBzaG91bGQudGhyb3coZm4sIC9mdW5jdGlvbiB0aHJvd3MgYSByZWZlcmVuY2UgZXJyb3IvKTtcbiAgICAgKiAgICAgc2hvdWxkLnRocm93KGZuLCBSZWZlcmVuY2VFcnJvcik7XG4gICAgICogICAgIHNob3VsZC50aHJvdyhmbiwgUmVmZXJlbmNlRXJyb3IsICdmdW5jdGlvbiB0aHJvd3MgYSByZWZlcmVuY2UgZXJyb3InKTtcbiAgICAgKiAgICAgc2hvdWxkLnRocm93KGZuLCBSZWZlcmVuY2VFcnJvciwgL2Z1bmN0aW9uIHRocm93cyBhIHJlZmVyZW5jZSBlcnJvci8pO1xuICAgICAqXG4gICAgICogQG5hbWUgdGhyb3dcbiAgICAgKiBAYWxpYXMgVGhyb3dcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RXJyb3JDb25zdHJ1Y3Rvcn0gY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge1JlZ0V4cH0gcmVnZXhwXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICAgKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0Vycm9yI0Vycm9yX3R5cGVzXG4gICAgICogQG5hbWVzcGFjZSBTaG91bGRcbiAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAqL1xuXG4gICAgc2hvdWxkLlRocm93ID0gZnVuY3Rpb24gKGZuLCBlcnJ0LCBlcnJzLCBtc2cpIHtcbiAgICAgIG5ldyBBc3NlcnRpb24oZm4sIG1zZykudG8uVGhyb3coZXJydCwgZXJycyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqICMjIyAuZXhpc3RcbiAgICAgKlxuICAgICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIG5laXRoZXIgYG51bGxgIG5vciBgdW5kZWZpbmVkYC5cbiAgICAgKlxuICAgICAqICAgICB2YXIgZm9vID0gJ2hpJztcbiAgICAgKlxuICAgICAqICAgICBzaG91bGQuZXhpc3QoZm9vLCAnZm9vIGV4aXN0cycpO1xuICAgICAqXG4gICAgICogQG5hbWUgZXhpc3RcbiAgICAgKiBAbmFtZXNwYWNlIFNob3VsZFxuICAgICAqIEBhcGkgcHVibGljXG4gICAgICovXG5cbiAgICBzaG91bGQuZXhpc3QgPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2cpLnRvLmV4aXN0O1xuICAgIH1cblxuICAgIC8vIG5lZ2F0aW9uXG4gICAgc2hvdWxkLm5vdCA9IHt9XG5cbiAgICAvKipcbiAgICAgKiAjIyMgLm5vdC5lcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBbbWVzc2FnZV0pXG4gICAgICpcbiAgICAgKiBBc3NlcnRzIG5vbi1zdHJpY3QgaW5lcXVhbGl0eSAoYCE9YCkgb2YgYGFjdHVhbGAgYW5kIGBleHBlY3RlZGAuXG4gICAgICpcbiAgICAgKiAgICAgc2hvdWxkLm5vdC5lcXVhbCgzLCA0LCAndGhlc2UgbnVtYmVycyBhcmUgbm90IGVxdWFsJyk7XG4gICAgICpcbiAgICAgKiBAbmFtZSBub3QuZXF1YWxcbiAgICAgKiBAcGFyYW0ge01peGVkfSBhY3R1YWxcbiAgICAgKiBAcGFyYW0ge01peGVkfSBleHBlY3RlZFxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAgICogQG5hbWVzcGFjZSBTaG91bGRcbiAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAqL1xuXG4gICAgc2hvdWxkLm5vdC5lcXVhbCA9IGZ1bmN0aW9uICh2YWwxLCB2YWwyLCBtc2cpIHtcbiAgICAgIG5ldyBBc3NlcnRpb24odmFsMSwgbXNnKS50by5ub3QuZXF1YWwodmFsMik7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqICMjIyAudGhyb3coZnVuY3Rpb24sIFtjb25zdHJ1Y3Rvci9yZWdleHBdLCBbbWVzc2FnZV0pXG4gICAgICpcbiAgICAgKiBBc3NlcnRzIHRoYXQgYGZ1bmN0aW9uYCB3aWxsIF9ub3RfIHRocm93IGFuIGVycm9yIHRoYXQgaXMgYW4gaW5zdGFuY2Ugb2ZcbiAgICAgKiBgY29uc3RydWN0b3JgLCBvciBhbHRlcm5hdGVseSB0aGF0IGl0IHdpbGwgbm90IHRocm93IGFuIGVycm9yIHdpdGggbWVzc2FnZVxuICAgICAqIG1hdGNoaW5nIGByZWdleHBgLlxuICAgICAqXG4gICAgICogICAgIHNob3VsZC5ub3QudGhyb3coZm4sIEVycm9yLCAnZnVuY3Rpb24gZG9lcyBub3QgdGhyb3cnKTtcbiAgICAgKlxuICAgICAqIEBuYW1lIG5vdC50aHJvd1xuICAgICAqIEBhbGlhcyBub3QuVGhyb3dcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RXJyb3JDb25zdHJ1Y3Rvcn0gY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge1JlZ0V4cH0gcmVnZXhwXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICAgKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0Vycm9yI0Vycm9yX3R5cGVzXG4gICAgICogQG5hbWVzcGFjZSBTaG91bGRcbiAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAqL1xuXG4gICAgc2hvdWxkLm5vdC5UaHJvdyA9IGZ1bmN0aW9uIChmbiwgZXJydCwgZXJycywgbXNnKSB7XG4gICAgICBuZXcgQXNzZXJ0aW9uKGZuLCBtc2cpLnRvLm5vdC5UaHJvdyhlcnJ0LCBlcnJzKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogIyMjIC5ub3QuZXhpc3RcbiAgICAgKlxuICAgICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIG5laXRoZXIgYG51bGxgIG5vciBgdW5kZWZpbmVkYC5cbiAgICAgKlxuICAgICAqICAgICB2YXIgYmFyID0gbnVsbDtcbiAgICAgKlxuICAgICAqICAgICBzaG91bGQubm90LmV4aXN0KGJhciwgJ2JhciBkb2VzIG5vdCBleGlzdCcpO1xuICAgICAqXG4gICAgICogQG5hbWUgbm90LmV4aXN0XG4gICAgICogQG5hbWVzcGFjZSBTaG91bGRcbiAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAqL1xuXG4gICAgc2hvdWxkLm5vdC5leGlzdCA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykudG8ubm90LmV4aXN0O1xuICAgIH1cblxuICAgIHNob3VsZFsndGhyb3cnXSA9IHNob3VsZFsnVGhyb3cnXTtcbiAgICBzaG91bGQubm90Wyd0aHJvdyddID0gc2hvdWxkLm5vdFsnVGhyb3cnXTtcblxuICAgIHJldHVybiBzaG91bGQ7XG4gIH07XG5cbiAgY2hhaS5zaG91bGQgPSBsb2FkU2hvdWxkO1xuICBjaGFpLlNob3VsZCA9IGxvYWRTaG91bGQ7XG59O1xuIiwgIi8qIVxuICogY2hhaVxuICogQ29weXJpZ2h0KGMpIDIwMTEtMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGNoYWksIHV0aWwpIHtcbiAgLyohXG4gICAqIENoYWkgZGVwZW5kZW5jaWVzLlxuICAgKi9cblxuICB2YXIgQXNzZXJ0aW9uID0gY2hhaS5Bc3NlcnRpb25cbiAgICAsIGZsYWcgPSB1dGlsLmZsYWc7XG5cbiAgLyohXG4gICAqIE1vZHVsZSBleHBvcnQuXG4gICAqL1xuXG4gIC8qKlxuICAgKiAjIyMgYXNzZXJ0KGV4cHJlc3Npb24sIG1lc3NhZ2UpXG4gICAqXG4gICAqIFdyaXRlIHlvdXIgb3duIHRlc3QgZXhwcmVzc2lvbnMuXG4gICAqXG4gICAqICAgICBhc3NlcnQoJ2ZvbycgIT09ICdiYXInLCAnZm9vIGlzIG5vdCBiYXInKTtcbiAgICogICAgIGFzc2VydChBcnJheS5pc0FycmF5KFtdKSwgJ2VtcHR5IGFycmF5cyBhcmUgYXJyYXlzJyk7XG4gICAqXG4gICAqIEBwYXJhbSB7TWl4ZWR9IGV4cHJlc3Npb24gdG8gdGVzdCBmb3IgdHJ1dGhpbmVzc1xuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSB0byBkaXNwbGF5IG9uIGVycm9yXG4gICAqIEBuYW1lIGFzc2VydFxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICB2YXIgYXNzZXJ0ID0gY2hhaS5hc3NlcnQgPSBmdW5jdGlvbiAoZXhwcmVzcywgZXJybXNnKSB7XG4gICAgdmFyIHRlc3QgPSBuZXcgQXNzZXJ0aW9uKG51bGwsIG51bGwsIGNoYWkuYXNzZXJ0LCB0cnVlKTtcbiAgICB0ZXN0LmFzc2VydChcbiAgICAgICAgZXhwcmVzc1xuICAgICAgLCBlcnJtc2dcbiAgICAgICwgJ1sgbmVnYXRpb24gbWVzc2FnZSB1bmF2YWlsYWJsZSBdJ1xuICAgICk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuZmFpbChbbWVzc2FnZV0pXG4gICAqICMjIyAuZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBbbWVzc2FnZV0sIFtvcGVyYXRvcl0pXG4gICAqXG4gICAqIFRocm93IGEgZmFpbHVyZS4gTm9kZS5qcyBgYXNzZXJ0YCBtb2R1bGUtY29tcGF0aWJsZS5cbiAgICpcbiAgICogICAgIGFzc2VydC5mYWlsKCk7XG4gICAqICAgICBhc3NlcnQuZmFpbChcImN1c3RvbSBlcnJvciBtZXNzYWdlXCIpO1xuICAgKiAgICAgYXNzZXJ0LmZhaWwoMSwgMik7XG4gICAqICAgICBhc3NlcnQuZmFpbCgxLCAyLCBcImN1c3RvbSBlcnJvciBtZXNzYWdlXCIpO1xuICAgKiAgICAgYXNzZXJ0LmZhaWwoMSwgMiwgXCJjdXN0b20gZXJyb3IgbWVzc2FnZVwiLCBcIj5cIik7XG4gICAqICAgICBhc3NlcnQuZmFpbCgxLCAyLCB1bmRlZmluZWQsIFwiPlwiKTtcbiAgICpcbiAgICogQG5hbWUgZmFpbFxuICAgKiBAcGFyYW0ge01peGVkfSBhY3R1YWxcbiAgICogQHBhcmFtIHtNaXhlZH0gZXhwZWN0ZWRcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQHBhcmFtIHtTdHJpbmd9IG9wZXJhdG9yXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5mYWlsID0gZnVuY3Rpb24gKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsIG9wZXJhdG9yKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAyKSB7XG4gICAgICAgIC8vIENvbXBseSB3aXRoIE5vZGUncyBmYWlsKFttZXNzYWdlXSkgaW50ZXJmYWNlXG5cbiAgICAgICAgbWVzc2FnZSA9IGFjdHVhbDtcbiAgICAgICAgYWN0dWFsID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIG1lc3NhZ2UgPSBtZXNzYWdlIHx8ICdhc3NlcnQuZmFpbCgpJztcbiAgICB0aHJvdyBuZXcgY2hhaS5Bc3NlcnRpb25FcnJvcihtZXNzYWdlLCB7XG4gICAgICAgIGFjdHVhbDogYWN0dWFsXG4gICAgICAsIGV4cGVjdGVkOiBleHBlY3RlZFxuICAgICAgLCBvcGVyYXRvcjogb3BlcmF0b3JcbiAgICB9LCBhc3NlcnQuZmFpbCk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNPayhvYmplY3QsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGlzIHRydXRoeS5cbiAgICpcbiAgICogICAgIGFzc2VydC5pc09rKCdldmVyeXRoaW5nJywgJ2V2ZXJ5dGhpbmcgaXMgb2snKTtcbiAgICogICAgIGFzc2VydC5pc09rKGZhbHNlLCAndGhpcyB3aWxsIGZhaWwnKTtcbiAgICpcbiAgICogQG5hbWUgaXNPa1xuICAgKiBAYWxpYXMgb2tcbiAgICogQHBhcmFtIHtNaXhlZH0gb2JqZWN0IHRvIHRlc3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzT2sgPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnLCBhc3NlcnQuaXNPaywgdHJ1ZSkuaXMub2s7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNOb3RPayhvYmplY3QsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGlzIGZhbHN5LlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmlzTm90T2soJ2V2ZXJ5dGhpbmcnLCAndGhpcyB3aWxsIGZhaWwnKTtcbiAgICogICAgIGFzc2VydC5pc05vdE9rKGZhbHNlLCAndGhpcyB3aWxsIHBhc3MnKTtcbiAgICpcbiAgICogQG5hbWUgaXNOb3RPa1xuICAgKiBAYWxpYXMgbm90T2tcbiAgICogQHBhcmFtIHtNaXhlZH0gb2JqZWN0IHRvIHRlc3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzTm90T2sgPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnLCBhc3NlcnQuaXNOb3RPaywgdHJ1ZSkuaXMubm90Lm9rO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyBub24tc3RyaWN0IGVxdWFsaXR5IChgPT1gKSBvZiBgYWN0dWFsYCBhbmQgYGV4cGVjdGVkYC5cbiAgICpcbiAgICogICAgIGFzc2VydC5lcXVhbCgzLCAnMycsICc9PSBjb2VyY2VzIHZhbHVlcyB0byBzdHJpbmdzJyk7XG4gICAqXG4gICAqIEBuYW1lIGVxdWFsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IGFjdHVhbFxuICAgKiBAcGFyYW0ge01peGVkfSBleHBlY3RlZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuZXF1YWwgPSBmdW5jdGlvbiAoYWN0LCBleHAsIG1zZykge1xuICAgIHZhciB0ZXN0ID0gbmV3IEFzc2VydGlvbihhY3QsIG1zZywgYXNzZXJ0LmVxdWFsLCB0cnVlKTtcblxuICAgIHRlc3QuYXNzZXJ0KFxuICAgICAgICBleHAgPT0gZmxhZyh0ZXN0LCAnb2JqZWN0JylcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gZXF1YWwgI3tleHB9J1xuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgZXF1YWwgI3thY3R9J1xuICAgICAgLCBleHBcbiAgICAgICwgYWN0XG4gICAgICAsIHRydWVcbiAgICApO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm5vdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyBub24tc3RyaWN0IGluZXF1YWxpdHkgKGAhPWApIG9mIGBhY3R1YWxgIGFuZCBgZXhwZWN0ZWRgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm5vdEVxdWFsKDMsIDQsICd0aGVzZSBudW1iZXJzIGFyZSBub3QgZXF1YWwnKTtcbiAgICpcbiAgICogQG5hbWUgbm90RXF1YWxcbiAgICogQHBhcmFtIHtNaXhlZH0gYWN0dWFsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IGV4cGVjdGVkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5ub3RFcXVhbCA9IGZ1bmN0aW9uIChhY3QsIGV4cCwgbXNnKSB7XG4gICAgdmFyIHRlc3QgPSBuZXcgQXNzZXJ0aW9uKGFjdCwgbXNnLCBhc3NlcnQubm90RXF1YWwsIHRydWUpO1xuXG4gICAgdGVzdC5hc3NlcnQoXG4gICAgICAgIGV4cCAhPSBmbGFnKHRlc3QsICdvYmplY3QnKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgZXF1YWwgI3tleHB9J1xuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBlcXVhbCAje2FjdH0nXG4gICAgICAsIGV4cFxuICAgICAgLCBhY3RcbiAgICAgICwgdHJ1ZVxuICAgICk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuc3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHN0cmljdCBlcXVhbGl0eSAoYD09PWApIG9mIGBhY3R1YWxgIGFuZCBgZXhwZWN0ZWRgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHRydWUsIHRydWUsICd0aGVzZSBib29sZWFucyBhcmUgc3RyaWN0bHkgZXF1YWwnKTtcbiAgICpcbiAgICogQG5hbWUgc3RyaWN0RXF1YWxcbiAgICogQHBhcmFtIHtNaXhlZH0gYWN0dWFsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IGV4cGVjdGVkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5zdHJpY3RFcXVhbCA9IGZ1bmN0aW9uIChhY3QsIGV4cCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihhY3QsIG1zZywgYXNzZXJ0LnN0cmljdEVxdWFsLCB0cnVlKS50by5lcXVhbChleHApO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm5vdFN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyBzdHJpY3QgaW5lcXVhbGl0eSAoYCE9PWApIG9mIGBhY3R1YWxgIGFuZCBgZXhwZWN0ZWRgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm5vdFN0cmljdEVxdWFsKDMsICczJywgJ25vIGNvZXJjaW9uIGZvciBzdHJpY3QgZXF1YWxpdHknKTtcbiAgICpcbiAgICogQG5hbWUgbm90U3RyaWN0RXF1YWxcbiAgICogQHBhcmFtIHtNaXhlZH0gYWN0dWFsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IGV4cGVjdGVkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5ub3RTdHJpY3RFcXVhbCA9IGZ1bmN0aW9uIChhY3QsIGV4cCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihhY3QsIG1zZywgYXNzZXJ0Lm5vdFN0cmljdEVxdWFsLCB0cnVlKS50by5ub3QuZXF1YWwoZXhwKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5kZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYGFjdHVhbGAgaXMgZGVlcGx5IGVxdWFsIHRvIGBleHBlY3RlZGAuXG4gICAqXG4gICAqICAgICBhc3NlcnQuZGVlcEVxdWFsKHsgdGVhOiAnZ3JlZW4nIH0sIHsgdGVhOiAnZ3JlZW4nIH0pO1xuICAgKlxuICAgKiBAbmFtZSBkZWVwRXF1YWxcbiAgICogQHBhcmFtIHtNaXhlZH0gYWN0dWFsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IGV4cGVjdGVkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBhbGlhcyBkZWVwU3RyaWN0RXF1YWxcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmRlZXBFcXVhbCA9IGFzc2VydC5kZWVwU3RyaWN0RXF1YWwgPSBmdW5jdGlvbiAoYWN0LCBleHAsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oYWN0LCBtc2csIGFzc2VydC5kZWVwRXF1YWwsIHRydWUpLnRvLmVxbChleHApO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm5vdERlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydCB0aGF0IGBhY3R1YWxgIGlzIG5vdCBkZWVwbHkgZXF1YWwgdG8gYGV4cGVjdGVkYC5cbiAgICpcbiAgICogICAgIGFzc2VydC5ub3REZWVwRXF1YWwoeyB0ZWE6ICdncmVlbicgfSwgeyB0ZWE6ICdqYXNtaW5lJyB9KTtcbiAgICpcbiAgICogQG5hbWUgbm90RGVlcEVxdWFsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IGFjdHVhbFxuICAgKiBAcGFyYW0ge01peGVkfSBleHBlY3RlZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubm90RGVlcEVxdWFsID0gZnVuY3Rpb24gKGFjdCwgZXhwLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKGFjdCwgbXNnLCBhc3NlcnQubm90RGVlcEVxdWFsLCB0cnVlKS50by5ub3QuZXFsKGV4cCk7XG4gIH07XG5cbiAgIC8qKlxuICAgKiAjIyMgLmlzQWJvdmUodmFsdWVUb0NoZWNrLCB2YWx1ZVRvQmVBYm92ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIGB2YWx1ZVRvQ2hlY2tgIGlzIHN0cmljdGx5IGdyZWF0ZXIgdGhhbiAoPikgYHZhbHVlVG9CZUFib3ZlYC5cbiAgICpcbiAgICogICAgIGFzc2VydC5pc0Fib3ZlKDUsIDIsICc1IGlzIHN0cmljdGx5IGdyZWF0ZXIgdGhhbiAyJyk7XG4gICAqXG4gICAqIEBuYW1lIGlzQWJvdmVcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVUb0NoZWNrXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlVG9CZUFib3ZlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc0Fib3ZlID0gZnVuY3Rpb24gKHZhbCwgYWJ2LCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnLCBhc3NlcnQuaXNBYm92ZSwgdHJ1ZSkudG8uYmUuYWJvdmUoYWJ2KTtcbiAgfTtcblxuICAgLyoqXG4gICAqICMjIyAuaXNBdExlYXN0KHZhbHVlVG9DaGVjaywgdmFsdWVUb0JlQXRMZWFzdCwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIGB2YWx1ZVRvQ2hlY2tgIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAoPj0pIGB2YWx1ZVRvQmVBdExlYXN0YC5cbiAgICpcbiAgICogICAgIGFzc2VydC5pc0F0TGVhc3QoNSwgMiwgJzUgaXMgZ3JlYXRlciBvciBlcXVhbCB0byAyJyk7XG4gICAqICAgICBhc3NlcnQuaXNBdExlYXN0KDMsIDMsICczIGlzIGdyZWF0ZXIgb3IgZXF1YWwgdG8gMycpO1xuICAgKlxuICAgKiBAbmFtZSBpc0F0TGVhc3RcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVUb0NoZWNrXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlVG9CZUF0TGVhc3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzQXRMZWFzdCA9IGZ1bmN0aW9uICh2YWwsIGF0bHN0LCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnLCBhc3NlcnQuaXNBdExlYXN0LCB0cnVlKS50by5iZS5sZWFzdChhdGxzdCk7XG4gIH07XG5cbiAgIC8qKlxuICAgKiAjIyMgLmlzQmVsb3codmFsdWVUb0NoZWNrLCB2YWx1ZVRvQmVCZWxvdywgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIGB2YWx1ZVRvQ2hlY2tgIGlzIHN0cmljdGx5IGxlc3MgdGhhbiAoPCkgYHZhbHVlVG9CZUJlbG93YC5cbiAgICpcbiAgICogICAgIGFzc2VydC5pc0JlbG93KDMsIDYsICczIGlzIHN0cmljdGx5IGxlc3MgdGhhbiA2Jyk7XG4gICAqXG4gICAqIEBuYW1lIGlzQmVsb3dcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVUb0NoZWNrXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlVG9CZUJlbG93XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc0JlbG93ID0gZnVuY3Rpb24gKHZhbCwgYmx3LCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnLCBhc3NlcnQuaXNCZWxvdywgdHJ1ZSkudG8uYmUuYmVsb3coYmx3KTtcbiAgfTtcblxuICAgLyoqXG4gICAqICMjIyAuaXNBdE1vc3QodmFsdWVUb0NoZWNrLCB2YWx1ZVRvQmVBdE1vc3QsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyBgdmFsdWVUb0NoZWNrYCBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gKDw9KSBgdmFsdWVUb0JlQXRNb3N0YC5cbiAgICpcbiAgICogICAgIGFzc2VydC5pc0F0TW9zdCgzLCA2LCAnMyBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gNicpO1xuICAgKiAgICAgYXNzZXJ0LmlzQXRNb3N0KDQsIDQsICc0IGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byA0Jyk7XG4gICAqXG4gICAqIEBuYW1lIGlzQXRNb3N0XG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlVG9DaGVja1xuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVRvQmVBdE1vc3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzQXRNb3N0ID0gZnVuY3Rpb24gKHZhbCwgYXRtc3QsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2csIGFzc2VydC5pc0F0TW9zdCwgdHJ1ZSkudG8uYmUubW9zdChhdG1zdCk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNUcnVlKHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGlzIHRydWUuXG4gICAqXG4gICAqICAgICB2YXIgdGVhU2VydmVkID0gdHJ1ZTtcbiAgICogICAgIGFzc2VydC5pc1RydWUodGVhU2VydmVkLCAndGhlIHRlYSBoYXMgYmVlbiBzZXJ2ZWQnKTtcbiAgICpcbiAgICogQG5hbWUgaXNUcnVlXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc1RydWUgPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnLCBhc3NlcnQuaXNUcnVlLCB0cnVlKS5pc1sndHJ1ZSddO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzTm90VHJ1ZSh2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyBub3QgdHJ1ZS5cbiAgICpcbiAgICogICAgIHZhciB0ZWEgPSAndGFzdHkgY2hhaSc7XG4gICAqICAgICBhc3NlcnQuaXNOb3RUcnVlKHRlYSwgJ2dyZWF0LCB0aW1lIGZvciB0ZWEhJyk7XG4gICAqXG4gICAqIEBuYW1lIGlzTm90VHJ1ZVxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNOb3RUcnVlID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZywgYXNzZXJ0LmlzTm90VHJ1ZSwgdHJ1ZSkudG8ubm90LmVxdWFsKHRydWUpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzRmFsc2UodmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgZmFsc2UuXG4gICAqXG4gICAqICAgICB2YXIgdGVhU2VydmVkID0gZmFsc2U7XG4gICAqICAgICBhc3NlcnQuaXNGYWxzZSh0ZWFTZXJ2ZWQsICdubyB0ZWEgeWV0PyBobW0uLi4nKTtcbiAgICpcbiAgICogQG5hbWUgaXNGYWxzZVxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNGYWxzZSA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2csIGFzc2VydC5pc0ZhbHNlLCB0cnVlKS5pc1snZmFsc2UnXTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc05vdEZhbHNlKHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGlzIG5vdCBmYWxzZS5cbiAgICpcbiAgICogICAgIHZhciB0ZWEgPSAndGFzdHkgY2hhaSc7XG4gICAqICAgICBhc3NlcnQuaXNOb3RGYWxzZSh0ZWEsICdncmVhdCwgdGltZSBmb3IgdGVhIScpO1xuICAgKlxuICAgKiBAbmFtZSBpc05vdEZhbHNlXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc05vdEZhbHNlID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZywgYXNzZXJ0LmlzTm90RmFsc2UsIHRydWUpLnRvLm5vdC5lcXVhbChmYWxzZSk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNOdWxsKHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGlzIG51bGwuXG4gICAqXG4gICAqICAgICBhc3NlcnQuaXNOdWxsKGVyciwgJ3RoZXJlIHdhcyBubyBlcnJvcicpO1xuICAgKlxuICAgKiBAbmFtZSBpc051bGxcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzTnVsbCA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2csIGFzc2VydC5pc051bGwsIHRydWUpLnRvLmVxdWFsKG51bGwpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzTm90TnVsbCh2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyBub3QgbnVsbC5cbiAgICpcbiAgICogICAgIHZhciB0ZWEgPSAndGFzdHkgY2hhaSc7XG4gICAqICAgICBhc3NlcnQuaXNOb3ROdWxsKHRlYSwgJ2dyZWF0LCB0aW1lIGZvciB0ZWEhJyk7XG4gICAqXG4gICAqIEBuYW1lIGlzTm90TnVsbFxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNOb3ROdWxsID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZywgYXNzZXJ0LmlzTm90TnVsbCwgdHJ1ZSkudG8ubm90LmVxdWFsKG51bGwpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzTmFOXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB2YWx1ZSBpcyBOYU4uXG4gICAqXG4gICAqICAgICBhc3NlcnQuaXNOYU4oTmFOLCAnTmFOIGlzIE5hTicpO1xuICAgKlxuICAgKiBAbmFtZSBpc05hTlxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNOYU4gPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnLCBhc3NlcnQuaXNOYU4sIHRydWUpLnRvLmJlLk5hTjtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc05vdE5hTlxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdmFsdWUgaXMgbm90IE5hTi5cbiAgICpcbiAgICogICAgIGFzc2VydC5pc05vdE5hTig0LCAnNCBpcyBub3QgTmFOJyk7XG4gICAqXG4gICAqIEBuYW1lIGlzTm90TmFOXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuICBhc3NlcnQuaXNOb3ROYU4gPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnLCBhc3NlcnQuaXNOb3ROYU4sIHRydWUpLm5vdC50by5iZS5OYU47XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuZXhpc3RzXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIG5laXRoZXIgYG51bGxgIG5vciBgdW5kZWZpbmVkYC5cbiAgICpcbiAgICogICAgIHZhciBmb28gPSAnaGknO1xuICAgKlxuICAgKiAgICAgYXNzZXJ0LmV4aXN0cyhmb28sICdmb28gaXMgbmVpdGhlciBgbnVsbGAgbm9yIGB1bmRlZmluZWRgJyk7XG4gICAqXG4gICAqIEBuYW1lIGV4aXN0c1xuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuZXhpc3RzID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZywgYXNzZXJ0LmV4aXN0cywgdHJ1ZSkudG8uZXhpc3Q7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAubm90RXhpc3RzXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGVpdGhlciBgbnVsbGAgb3IgYHVuZGVmaW5lZGAuXG4gICAqXG4gICAqICAgICB2YXIgYmFyID0gbnVsbFxuICAgKiAgICAgICAsIGJhejtcbiAgICpcbiAgICogICAgIGFzc2VydC5ub3RFeGlzdHMoYmFyKTtcbiAgICogICAgIGFzc2VydC5ub3RFeGlzdHMoYmF6LCAnYmF6IGlzIGVpdGhlciBudWxsIG9yIHVuZGVmaW5lZCcpO1xuICAgKlxuICAgKiBAbmFtZSBub3RFeGlzdHNcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm5vdEV4aXN0cyA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2csIGFzc2VydC5ub3RFeGlzdHMsIHRydWUpLnRvLm5vdC5leGlzdDtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc1VuZGVmaW5lZCh2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyBgdW5kZWZpbmVkYC5cbiAgICpcbiAgICogICAgIHZhciB0ZWE7XG4gICAqICAgICBhc3NlcnQuaXNVbmRlZmluZWQodGVhLCAnbm8gdGVhIGRlZmluZWQnKTtcbiAgICpcbiAgICogQG5hbWUgaXNVbmRlZmluZWRcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzVW5kZWZpbmVkID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZywgYXNzZXJ0LmlzVW5kZWZpbmVkLCB0cnVlKS50by5lcXVhbCh1bmRlZmluZWQpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzRGVmaW5lZCh2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyBub3QgYHVuZGVmaW5lZGAuXG4gICAqXG4gICAqICAgICB2YXIgdGVhID0gJ2N1cCBvZiBjaGFpJztcbiAgICogICAgIGFzc2VydC5pc0RlZmluZWQodGVhLCAndGVhIGhhcyBiZWVuIGRlZmluZWQnKTtcbiAgICpcbiAgICogQG5hbWUgaXNEZWZpbmVkXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc0RlZmluZWQgPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnLCBhc3NlcnQuaXNEZWZpbmVkLCB0cnVlKS50by5ub3QuZXF1YWwodW5kZWZpbmVkKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc0Z1bmN0aW9uKHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGlzIGEgZnVuY3Rpb24uXG4gICAqXG4gICAqICAgICBmdW5jdGlvbiBzZXJ2ZVRlYSgpIHsgcmV0dXJuICdjdXAgb2YgdGVhJzsgfTtcbiAgICogICAgIGFzc2VydC5pc0Z1bmN0aW9uKHNlcnZlVGVhLCAnZ3JlYXQsIHdlIGNhbiBoYXZlIHRlYSBub3cnKTtcbiAgICpcbiAgICogQG5hbWUgaXNGdW5jdGlvblxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNGdW5jdGlvbiA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2csIGFzc2VydC5pc0Z1bmN0aW9uLCB0cnVlKS50by5iZS5hKCdmdW5jdGlvbicpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzTm90RnVuY3Rpb24odmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgX25vdF8gYSBmdW5jdGlvbi5cbiAgICpcbiAgICogICAgIHZhciBzZXJ2ZVRlYSA9IFsgJ2hlYXQnLCAncG91cicsICdzaXAnIF07XG4gICAqICAgICBhc3NlcnQuaXNOb3RGdW5jdGlvbihzZXJ2ZVRlYSwgJ2dyZWF0LCB3ZSBoYXZlIGxpc3RlZCB0aGUgc3RlcHMnKTtcbiAgICpcbiAgICogQG5hbWUgaXNOb3RGdW5jdGlvblxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNOb3RGdW5jdGlvbiA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2csIGFzc2VydC5pc05vdEZ1bmN0aW9uLCB0cnVlKS50by5ub3QuYmUuYSgnZnVuY3Rpb24nKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc09iamVjdCh2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyBhbiBvYmplY3Qgb2YgdHlwZSAnT2JqZWN0JyAoYXMgcmV2ZWFsZWQgYnkgYE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmdgKS5cbiAgICogX1RoZSBhc3NlcnRpb24gZG9lcyBub3QgbWF0Y2ggc3ViY2xhc3NlZCBvYmplY3RzLl9cbiAgICpcbiAgICogICAgIHZhciBzZWxlY3Rpb24gPSB7IG5hbWU6ICdDaGFpJywgc2VydmU6ICd3aXRoIHNwaWNlcycgfTtcbiAgICogICAgIGFzc2VydC5pc09iamVjdChzZWxlY3Rpb24sICd0ZWEgc2VsZWN0aW9uIGlzIGFuIG9iamVjdCcpO1xuICAgKlxuICAgKiBAbmFtZSBpc09iamVjdFxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNPYmplY3QgPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnLCBhc3NlcnQuaXNPYmplY3QsIHRydWUpLnRvLmJlLmEoJ29iamVjdCcpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzTm90T2JqZWN0KHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGlzIF9ub3RfIGFuIG9iamVjdCBvZiB0eXBlICdPYmplY3QnIChhcyByZXZlYWxlZCBieSBgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZ2ApLlxuICAgKlxuICAgKiAgICAgdmFyIHNlbGVjdGlvbiA9ICdjaGFpJ1xuICAgKiAgICAgYXNzZXJ0LmlzTm90T2JqZWN0KHNlbGVjdGlvbiwgJ3RlYSBzZWxlY3Rpb24gaXMgbm90IGFuIG9iamVjdCcpO1xuICAgKiAgICAgYXNzZXJ0LmlzTm90T2JqZWN0KG51bGwsICdudWxsIGlzIG5vdCBhbiBvYmplY3QnKTtcbiAgICpcbiAgICogQG5hbWUgaXNOb3RPYmplY3RcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzTm90T2JqZWN0ID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZywgYXNzZXJ0LmlzTm90T2JqZWN0LCB0cnVlKS50by5ub3QuYmUuYSgnb2JqZWN0Jyk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNBcnJheSh2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyBhbiBhcnJheS5cbiAgICpcbiAgICogICAgIHZhciBtZW51ID0gWyAnZ3JlZW4nLCAnY2hhaScsICdvb2xvbmcnIF07XG4gICAqICAgICBhc3NlcnQuaXNBcnJheShtZW51LCAnd2hhdCBraW5kIG9mIHRlYSBkbyB3ZSB3YW50PycpO1xuICAgKlxuICAgKiBAbmFtZSBpc0FycmF5XG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc0FycmF5ID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZywgYXNzZXJ0LmlzQXJyYXksIHRydWUpLnRvLmJlLmFuKCdhcnJheScpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzTm90QXJyYXkodmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgX25vdF8gYW4gYXJyYXkuXG4gICAqXG4gICAqICAgICB2YXIgbWVudSA9ICdncmVlbnxjaGFpfG9vbG9uZyc7XG4gICAqICAgICBhc3NlcnQuaXNOb3RBcnJheShtZW51LCAnd2hhdCBraW5kIG9mIHRlYSBkbyB3ZSB3YW50PycpO1xuICAgKlxuICAgKiBAbmFtZSBpc05vdEFycmF5XG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc05vdEFycmF5ID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZywgYXNzZXJ0LmlzTm90QXJyYXksIHRydWUpLnRvLm5vdC5iZS5hbignYXJyYXknKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc1N0cmluZyh2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyBhIHN0cmluZy5cbiAgICpcbiAgICogICAgIHZhciB0ZWFPcmRlciA9ICdjaGFpJztcbiAgICogICAgIGFzc2VydC5pc1N0cmluZyh0ZWFPcmRlciwgJ29yZGVyIHBsYWNlZCcpO1xuICAgKlxuICAgKiBAbmFtZSBpc1N0cmluZ1xuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNTdHJpbmcgPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnLCBhc3NlcnQuaXNTdHJpbmcsIHRydWUpLnRvLmJlLmEoJ3N0cmluZycpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzTm90U3RyaW5nKHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGlzIF9ub3RfIGEgc3RyaW5nLlxuICAgKlxuICAgKiAgICAgdmFyIHRlYU9yZGVyID0gNDtcbiAgICogICAgIGFzc2VydC5pc05vdFN0cmluZyh0ZWFPcmRlciwgJ29yZGVyIHBsYWNlZCcpO1xuICAgKlxuICAgKiBAbmFtZSBpc05vdFN0cmluZ1xuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNOb3RTdHJpbmcgPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnLCBhc3NlcnQuaXNOb3RTdHJpbmcsIHRydWUpLnRvLm5vdC5iZS5hKCdzdHJpbmcnKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc051bWJlcih2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyBhIG51bWJlci5cbiAgICpcbiAgICogICAgIHZhciBjdXBzID0gMjtcbiAgICogICAgIGFzc2VydC5pc051bWJlcihjdXBzLCAnaG93IG1hbnkgY3VwcycpO1xuICAgKlxuICAgKiBAbmFtZSBpc051bWJlclxuICAgKiBAcGFyYW0ge051bWJlcn0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzTnVtYmVyID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZywgYXNzZXJ0LmlzTnVtYmVyLCB0cnVlKS50by5iZS5hKCdudW1iZXInKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc05vdE51bWJlcih2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyBfbm90XyBhIG51bWJlci5cbiAgICpcbiAgICogICAgIHZhciBjdXBzID0gJzIgY3VwcyBwbGVhc2UnO1xuICAgKiAgICAgYXNzZXJ0LmlzTm90TnVtYmVyKGN1cHMsICdob3cgbWFueSBjdXBzJyk7XG4gICAqXG4gICAqIEBuYW1lIGlzTm90TnVtYmVyXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc05vdE51bWJlciA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2csIGFzc2VydC5pc05vdE51bWJlciwgdHJ1ZSkudG8ubm90LmJlLmEoJ251bWJlcicpO1xuICB9O1xuXG4gICAvKipcbiAgICogIyMjIC5pc0Zpbml0ZSh2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyBhIGZpbml0ZSBudW1iZXIuIFVubGlrZSBgLmlzTnVtYmVyYCwgdGhpcyB3aWxsIGZhaWwgZm9yIGBOYU5gIGFuZCBgSW5maW5pdHlgLlxuICAgKlxuICAgKiAgICAgdmFyIGN1cHMgPSAyO1xuICAgKiAgICAgYXNzZXJ0LmlzRmluaXRlKGN1cHMsICdob3cgbWFueSBjdXBzJyk7XG4gICAqXG4gICAqICAgICBhc3NlcnQuaXNGaW5pdGUoTmFOKTsgLy8gdGhyb3dzXG4gICAqXG4gICAqIEBuYW1lIGlzRmluaXRlXG4gICAqIEBwYXJhbSB7TnVtYmVyfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNGaW5pdGUgPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnLCBhc3NlcnQuaXNGaW5pdGUsIHRydWUpLnRvLmJlLmZpbml0ZTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc0Jvb2xlYW4odmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgYSBib29sZWFuLlxuICAgKlxuICAgKiAgICAgdmFyIHRlYVJlYWR5ID0gdHJ1ZVxuICAgKiAgICAgICAsIHRlYVNlcnZlZCA9IGZhbHNlO1xuICAgKlxuICAgKiAgICAgYXNzZXJ0LmlzQm9vbGVhbih0ZWFSZWFkeSwgJ2lzIHRoZSB0ZWEgcmVhZHknKTtcbiAgICogICAgIGFzc2VydC5pc0Jvb2xlYW4odGVhU2VydmVkLCAnaGFzIHRlYSBiZWVuIHNlcnZlZCcpO1xuICAgKlxuICAgKiBAbmFtZSBpc0Jvb2xlYW5cbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzQm9vbGVhbiA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2csIGFzc2VydC5pc0Jvb2xlYW4sIHRydWUpLnRvLmJlLmEoJ2Jvb2xlYW4nKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc05vdEJvb2xlYW4odmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgX25vdF8gYSBib29sZWFuLlxuICAgKlxuICAgKiAgICAgdmFyIHRlYVJlYWR5ID0gJ3llcCdcbiAgICogICAgICAgLCB0ZWFTZXJ2ZWQgPSAnbm9wZSc7XG4gICAqXG4gICAqICAgICBhc3NlcnQuaXNOb3RCb29sZWFuKHRlYVJlYWR5LCAnaXMgdGhlIHRlYSByZWFkeScpO1xuICAgKiAgICAgYXNzZXJ0LmlzTm90Qm9vbGVhbih0ZWFTZXJ2ZWQsICdoYXMgdGVhIGJlZW4gc2VydmVkJyk7XG4gICAqXG4gICAqIEBuYW1lIGlzTm90Qm9vbGVhblxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNOb3RCb29sZWFuID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZywgYXNzZXJ0LmlzTm90Qm9vbGVhbiwgdHJ1ZSkudG8ubm90LmJlLmEoJ2Jvb2xlYW4nKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC50eXBlT2YodmFsdWUsIG5hbWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAncyB0eXBlIGlzIGBuYW1lYCwgYXMgZGV0ZXJtaW5lZCBieVxuICAgKiBgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZ2AuXG4gICAqXG4gICAqICAgICBhc3NlcnQudHlwZU9mKHsgdGVhOiAnY2hhaScgfSwgJ29iamVjdCcsICd3ZSBoYXZlIGFuIG9iamVjdCcpO1xuICAgKiAgICAgYXNzZXJ0LnR5cGVPZihbJ2NoYWknLCAnamFzbWluZSddLCAnYXJyYXknLCAnd2UgaGF2ZSBhbiBhcnJheScpO1xuICAgKiAgICAgYXNzZXJ0LnR5cGVPZigndGVhJywgJ3N0cmluZycsICd3ZSBoYXZlIGEgc3RyaW5nJyk7XG4gICAqICAgICBhc3NlcnQudHlwZU9mKC90ZWEvLCAncmVnZXhwJywgJ3dlIGhhdmUgYSByZWd1bGFyIGV4cHJlc3Npb24nKTtcbiAgICogICAgIGFzc2VydC50eXBlT2YobnVsbCwgJ251bGwnLCAnd2UgaGF2ZSBhIG51bGwnKTtcbiAgICogICAgIGFzc2VydC50eXBlT2YodW5kZWZpbmVkLCAndW5kZWZpbmVkJywgJ3dlIGhhdmUgYW4gdW5kZWZpbmVkJyk7XG4gICAqXG4gICAqIEBuYW1lIHR5cGVPZlxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQudHlwZU9mID0gZnVuY3Rpb24gKHZhbCwgdHlwZSwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZywgYXNzZXJ0LnR5cGVPZiwgdHJ1ZSkudG8uYmUuYSh0eXBlKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5ub3RUeXBlT2YodmFsdWUsIG5hbWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAncyB0eXBlIGlzIF9ub3RfIGBuYW1lYCwgYXMgZGV0ZXJtaW5lZCBieVxuICAgKiBgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZ2AuXG4gICAqXG4gICAqICAgICBhc3NlcnQubm90VHlwZU9mKCd0ZWEnLCAnbnVtYmVyJywgJ3N0cmluZ3MgYXJlIG5vdCBudW1iZXJzJyk7XG4gICAqXG4gICAqIEBuYW1lIG5vdFR5cGVPZlxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gdHlwZW9mIG5hbWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm5vdFR5cGVPZiA9IGZ1bmN0aW9uICh2YWwsIHR5cGUsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2csIGFzc2VydC5ub3RUeXBlT2YsIHRydWUpLnRvLm5vdC5iZS5hKHR5cGUpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmluc3RhbmNlT2Yob2JqZWN0LCBjb25zdHJ1Y3RvciwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyBhbiBpbnN0YW5jZSBvZiBgY29uc3RydWN0b3JgLlxuICAgKlxuICAgKiAgICAgdmFyIFRlYSA9IGZ1bmN0aW9uIChuYW1lKSB7IHRoaXMubmFtZSA9IG5hbWU7IH1cbiAgICogICAgICAgLCBjaGFpID0gbmV3IFRlYSgnY2hhaScpO1xuICAgKlxuICAgKiAgICAgYXNzZXJ0Lmluc3RhbmNlT2YoY2hhaSwgVGVhLCAnY2hhaSBpcyBhbiBpbnN0YW5jZSBvZiB0ZWEnKTtcbiAgICpcbiAgICogQG5hbWUgaW5zdGFuY2VPZlxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7Q29uc3RydWN0b3J9IGNvbnN0cnVjdG9yXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pbnN0YW5jZU9mID0gZnVuY3Rpb24gKHZhbCwgdHlwZSwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZywgYXNzZXJ0Lmluc3RhbmNlT2YsIHRydWUpLnRvLmJlLmluc3RhbmNlT2YodHlwZSk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAubm90SW5zdGFuY2VPZihvYmplY3QsIGNvbnN0cnVjdG9yLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgYHZhbHVlYCBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgYGNvbnN0cnVjdG9yYC5cbiAgICpcbiAgICogICAgIHZhciBUZWEgPSBmdW5jdGlvbiAobmFtZSkgeyB0aGlzLm5hbWUgPSBuYW1lOyB9XG4gICAqICAgICAgICwgY2hhaSA9IG5ldyBTdHJpbmcoJ2NoYWknKTtcbiAgICpcbiAgICogICAgIGFzc2VydC5ub3RJbnN0YW5jZU9mKGNoYWksIFRlYSwgJ2NoYWkgaXMgbm90IGFuIGluc3RhbmNlIG9mIHRlYScpO1xuICAgKlxuICAgKiBAbmFtZSBub3RJbnN0YW5jZU9mXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtDb25zdHJ1Y3Rvcn0gY29uc3RydWN0b3JcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm5vdEluc3RhbmNlT2YgPSBmdW5jdGlvbiAodmFsLCB0eXBlLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnLCBhc3NlcnQubm90SW5zdGFuY2VPZiwgdHJ1ZSlcbiAgICAgIC50by5ub3QuYmUuaW5zdGFuY2VPZih0eXBlKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pbmNsdWRlKGhheXN0YWNrLCBuZWVkbGUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBoYXlzdGFja2AgaW5jbHVkZXMgYG5lZWRsZWAuIENhbiBiZSB1c2VkIHRvIGFzc2VydCB0aGVcbiAgICogaW5jbHVzaW9uIG9mIGEgdmFsdWUgaW4gYW4gYXJyYXksIGEgc3Vic3RyaW5nIGluIGEgc3RyaW5nLCBvciBhIHN1YnNldCBvZlxuICAgKiBwcm9wZXJ0aWVzIGluIGFuIG9iamVjdC5cbiAgICpcbiAgICogICAgIGFzc2VydC5pbmNsdWRlKFsxLDIsM10sIDIsICdhcnJheSBjb250YWlucyB2YWx1ZScpO1xuICAgKiAgICAgYXNzZXJ0LmluY2x1ZGUoJ2Zvb2JhcicsICdmb28nLCAnc3RyaW5nIGNvbnRhaW5zIHN1YnN0cmluZycpO1xuICAgKiAgICAgYXNzZXJ0LmluY2x1ZGUoeyBmb286ICdiYXInLCBoZWxsbzogJ3VuaXZlcnNlJyB9LCB7IGZvbzogJ2JhcicgfSwgJ29iamVjdCBjb250YWlucyBwcm9wZXJ0eScpO1xuICAgKlxuICAgKiBTdHJpY3QgZXF1YWxpdHkgKD09PSkgaXMgdXNlZC4gV2hlbiBhc3NlcnRpbmcgdGhlIGluY2x1c2lvbiBvZiBhIHZhbHVlIGluXG4gICAqIGFuIGFycmF5LCB0aGUgYXJyYXkgaXMgc2VhcmNoZWQgZm9yIGFuIGVsZW1lbnQgdGhhdCdzIHN0cmljdGx5IGVxdWFsIHRvIHRoZVxuICAgKiBnaXZlbiB2YWx1ZS4gV2hlbiBhc3NlcnRpbmcgYSBzdWJzZXQgb2YgcHJvcGVydGllcyBpbiBhbiBvYmplY3QsIHRoZSBvYmplY3RcbiAgICogaXMgc2VhcmNoZWQgZm9yIHRoZSBnaXZlbiBwcm9wZXJ0eSBrZXlzLCBjaGVja2luZyB0aGF0IGVhY2ggb25lIGlzIHByZXNlbnRcbiAgICogYW5kIHN0cmljdGx5IGVxdWFsIHRvIHRoZSBnaXZlbiBwcm9wZXJ0eSB2YWx1ZS4gRm9yIGluc3RhbmNlOlxuICAgKlxuICAgKiAgICAgdmFyIG9iajEgPSB7YTogMX1cbiAgICogICAgICAgLCBvYmoyID0ge2I6IDJ9O1xuICAgKiAgICAgYXNzZXJ0LmluY2x1ZGUoW29iajEsIG9iajJdLCBvYmoxKTtcbiAgICogICAgIGFzc2VydC5pbmNsdWRlKHtmb286IG9iajEsIGJhcjogb2JqMn0sIHtmb286IG9iajF9KTtcbiAgICogICAgIGFzc2VydC5pbmNsdWRlKHtmb286IG9iajEsIGJhcjogb2JqMn0sIHtmb286IG9iajEsIGJhcjogb2JqMn0pO1xuICAgKlxuICAgKiBAbmFtZSBpbmNsdWRlXG4gICAqIEBwYXJhbSB7QXJyYXl8U3RyaW5nfSBoYXlzdGFja1xuICAgKiBAcGFyYW0ge01peGVkfSBuZWVkbGVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmluY2x1ZGUgPSBmdW5jdGlvbiAoZXhwLCBpbmMsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oZXhwLCBtc2csIGFzc2VydC5pbmNsdWRlLCB0cnVlKS5pbmNsdWRlKGluYyk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAubm90SW5jbHVkZShoYXlzdGFjaywgbmVlZGxlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgaGF5c3RhY2tgIGRvZXMgbm90IGluY2x1ZGUgYG5lZWRsZWAuIENhbiBiZSB1c2VkIHRvIGFzc2VydFxuICAgKiB0aGUgYWJzZW5jZSBvZiBhIHZhbHVlIGluIGFuIGFycmF5LCBhIHN1YnN0cmluZyBpbiBhIHN0cmluZywgb3IgYSBzdWJzZXQgb2ZcbiAgICogcHJvcGVydGllcyBpbiBhbiBvYmplY3QuXG4gICAqXG4gICAqICAgICBhc3NlcnQubm90SW5jbHVkZShbMSwyLDNdLCA0LCBcImFycmF5IGRvZXNuJ3QgY29udGFpbiB2YWx1ZVwiKTtcbiAgICogICAgIGFzc2VydC5ub3RJbmNsdWRlKCdmb29iYXInLCAnYmF6JywgXCJzdHJpbmcgZG9lc24ndCBjb250YWluIHN1YnN0cmluZ1wiKTtcbiAgICogICAgIGFzc2VydC5ub3RJbmNsdWRlKHsgZm9vOiAnYmFyJywgaGVsbG86ICd1bml2ZXJzZScgfSwgeyBmb286ICdiYXonIH0sICdvYmplY3QgZG9lc24ndCBjb250YWluIHByb3BlcnR5Jyk7XG4gICAqXG4gICAqIFN0cmljdCBlcXVhbGl0eSAoPT09KSBpcyB1c2VkLiBXaGVuIGFzc2VydGluZyB0aGUgYWJzZW5jZSBvZiBhIHZhbHVlIGluIGFuXG4gICAqIGFycmF5LCB0aGUgYXJyYXkgaXMgc2VhcmNoZWQgdG8gY29uZmlybSB0aGUgYWJzZW5jZSBvZiBhbiBlbGVtZW50IHRoYXQnc1xuICAgKiBzdHJpY3RseSBlcXVhbCB0byB0aGUgZ2l2ZW4gdmFsdWUuIFdoZW4gYXNzZXJ0aW5nIGEgc3Vic2V0IG9mIHByb3BlcnRpZXMgaW5cbiAgICogYW4gb2JqZWN0LCB0aGUgb2JqZWN0IGlzIHNlYXJjaGVkIHRvIGNvbmZpcm0gdGhhdCBhdCBsZWFzdCBvbmUgb2YgdGhlIGdpdmVuXG4gICAqIHByb3BlcnR5IGtleXMgaXMgZWl0aGVyIG5vdCBwcmVzZW50IG9yIG5vdCBzdHJpY3RseSBlcXVhbCB0byB0aGUgZ2l2ZW5cbiAgICogcHJvcGVydHkgdmFsdWUuIEZvciBpbnN0YW5jZTpcbiAgICpcbiAgICogICAgIHZhciBvYmoxID0ge2E6IDF9XG4gICAqICAgICAgICwgb2JqMiA9IHtiOiAyfTtcbiAgICogICAgIGFzc2VydC5ub3RJbmNsdWRlKFtvYmoxLCBvYmoyXSwge2E6IDF9KTtcbiAgICogICAgIGFzc2VydC5ub3RJbmNsdWRlKHtmb286IG9iajEsIGJhcjogb2JqMn0sIHtmb286IHthOiAxfX0pO1xuICAgKiAgICAgYXNzZXJ0Lm5vdEluY2x1ZGUoe2Zvbzogb2JqMSwgYmFyOiBvYmoyfSwge2Zvbzogb2JqMSwgYmFyOiB7YjogMn19KTtcbiAgICpcbiAgICogQG5hbWUgbm90SW5jbHVkZVxuICAgKiBAcGFyYW0ge0FycmF5fFN0cmluZ30gaGF5c3RhY2tcbiAgICogQHBhcmFtIHtNaXhlZH0gbmVlZGxlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5ub3RJbmNsdWRlID0gZnVuY3Rpb24gKGV4cCwgaW5jLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKGV4cCwgbXNnLCBhc3NlcnQubm90SW5jbHVkZSwgdHJ1ZSkubm90LmluY2x1ZGUoaW5jKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5kZWVwSW5jbHVkZShoYXlzdGFjaywgbmVlZGxlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgaGF5c3RhY2tgIGluY2x1ZGVzIGBuZWVkbGVgLiBDYW4gYmUgdXNlZCB0byBhc3NlcnQgdGhlXG4gICAqIGluY2x1c2lvbiBvZiBhIHZhbHVlIGluIGFuIGFycmF5IG9yIGEgc3Vic2V0IG9mIHByb3BlcnRpZXMgaW4gYW4gb2JqZWN0LlxuICAgKiBEZWVwIGVxdWFsaXR5IGlzIHVzZWQuXG4gICAqXG4gICAqICAgICB2YXIgb2JqMSA9IHthOiAxfVxuICAgKiAgICAgICAsIG9iajIgPSB7YjogMn07XG4gICAqICAgICBhc3NlcnQuZGVlcEluY2x1ZGUoW29iajEsIG9iajJdLCB7YTogMX0pO1xuICAgKiAgICAgYXNzZXJ0LmRlZXBJbmNsdWRlKHtmb286IG9iajEsIGJhcjogb2JqMn0sIHtmb286IHthOiAxfX0pO1xuICAgKiAgICAgYXNzZXJ0LmRlZXBJbmNsdWRlKHtmb286IG9iajEsIGJhcjogb2JqMn0sIHtmb286IHthOiAxfSwgYmFyOiB7YjogMn19KTtcbiAgICpcbiAgICogQG5hbWUgZGVlcEluY2x1ZGVcbiAgICogQHBhcmFtIHtBcnJheXxTdHJpbmd9IGhheXN0YWNrXG4gICAqIEBwYXJhbSB7TWl4ZWR9IG5lZWRsZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuZGVlcEluY2x1ZGUgPSBmdW5jdGlvbiAoZXhwLCBpbmMsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oZXhwLCBtc2csIGFzc2VydC5kZWVwSW5jbHVkZSwgdHJ1ZSkuZGVlcC5pbmNsdWRlKGluYyk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAubm90RGVlcEluY2x1ZGUoaGF5c3RhY2ssIG5lZWRsZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYGhheXN0YWNrYCBkb2VzIG5vdCBpbmNsdWRlIGBuZWVkbGVgLiBDYW4gYmUgdXNlZCB0byBhc3NlcnRcbiAgICogdGhlIGFic2VuY2Ugb2YgYSB2YWx1ZSBpbiBhbiBhcnJheSBvciBhIHN1YnNldCBvZiBwcm9wZXJ0aWVzIGluIGFuIG9iamVjdC5cbiAgICogRGVlcCBlcXVhbGl0eSBpcyB1c2VkLlxuICAgKlxuICAgKiAgICAgdmFyIG9iajEgPSB7YTogMX1cbiAgICogICAgICAgLCBvYmoyID0ge2I6IDJ9O1xuICAgKiAgICAgYXNzZXJ0Lm5vdERlZXBJbmNsdWRlKFtvYmoxLCBvYmoyXSwge2E6IDl9KTtcbiAgICogICAgIGFzc2VydC5ub3REZWVwSW5jbHVkZSh7Zm9vOiBvYmoxLCBiYXI6IG9iajJ9LCB7Zm9vOiB7YTogOX19KTtcbiAgICogICAgIGFzc2VydC5ub3REZWVwSW5jbHVkZSh7Zm9vOiBvYmoxLCBiYXI6IG9iajJ9LCB7Zm9vOiB7YTogMX0sIGJhcjoge2I6IDl9fSk7XG4gICAqXG4gICAqIEBuYW1lIG5vdERlZXBJbmNsdWRlXG4gICAqIEBwYXJhbSB7QXJyYXl8U3RyaW5nfSBoYXlzdGFja1xuICAgKiBAcGFyYW0ge01peGVkfSBuZWVkbGVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm5vdERlZXBJbmNsdWRlID0gZnVuY3Rpb24gKGV4cCwgaW5jLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKGV4cCwgbXNnLCBhc3NlcnQubm90RGVlcEluY2x1ZGUsIHRydWUpLm5vdC5kZWVwLmluY2x1ZGUoaW5jKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5uZXN0ZWRJbmNsdWRlKGhheXN0YWNrLCBuZWVkbGUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0ICdoYXlzdGFjaycgaW5jbHVkZXMgJ25lZWRsZScuXG4gICAqIENhbiBiZSB1c2VkIHRvIGFzc2VydCB0aGUgaW5jbHVzaW9uIG9mIGEgc3Vic2V0IG9mIHByb3BlcnRpZXMgaW4gYW5cbiAgICogb2JqZWN0LlxuICAgKiBFbmFibGVzIHRoZSB1c2Ugb2YgZG90LSBhbmQgYnJhY2tldC1ub3RhdGlvbiBmb3IgcmVmZXJlbmNpbmcgbmVzdGVkXG4gICAqIHByb3BlcnRpZXMuXG4gICAqICdbXScgYW5kICcuJyBpbiBwcm9wZXJ0eSBuYW1lcyBjYW4gYmUgZXNjYXBlZCB1c2luZyBkb3VibGUgYmFja3NsYXNoZXMuXG4gICAqXG4gICAqICAgICBhc3NlcnQubmVzdGVkSW5jbHVkZSh7Jy5hJzogeydiJzogJ3gnfX0sIHsnXFxcXC5hLltiXSc6ICd4J30pO1xuICAgKiAgICAgYXNzZXJ0Lm5lc3RlZEluY2x1ZGUoeydhJzogeydbYl0nOiAneCd9fSwgeydhLlxcXFxbYlxcXFxdJzogJ3gnfSk7XG4gICAqXG4gICAqIEBuYW1lIG5lc3RlZEluY2x1ZGVcbiAgICogQHBhcmFtIHtPYmplY3R9IGhheXN0YWNrXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBuZWVkbGVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm5lc3RlZEluY2x1ZGUgPSBmdW5jdGlvbiAoZXhwLCBpbmMsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oZXhwLCBtc2csIGFzc2VydC5uZXN0ZWRJbmNsdWRlLCB0cnVlKS5uZXN0ZWQuaW5jbHVkZShpbmMpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm5vdE5lc3RlZEluY2x1ZGUoaGF5c3RhY2ssIG5lZWRsZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgJ2hheXN0YWNrJyBkb2VzIG5vdCBpbmNsdWRlICduZWVkbGUnLlxuICAgKiBDYW4gYmUgdXNlZCB0byBhc3NlcnQgdGhlIGFic2VuY2Ugb2YgYSBzdWJzZXQgb2YgcHJvcGVydGllcyBpbiBhblxuICAgKiBvYmplY3QuXG4gICAqIEVuYWJsZXMgdGhlIHVzZSBvZiBkb3QtIGFuZCBicmFja2V0LW5vdGF0aW9uIGZvciByZWZlcmVuY2luZyBuZXN0ZWRcbiAgICogcHJvcGVydGllcy5cbiAgICogJ1tdJyBhbmQgJy4nIGluIHByb3BlcnR5IG5hbWVzIGNhbiBiZSBlc2NhcGVkIHVzaW5nIGRvdWJsZSBiYWNrc2xhc2hlcy5cbiAgICpcbiAgICogICAgIGFzc2VydC5ub3ROZXN0ZWRJbmNsdWRlKHsnLmEnOiB7J2InOiAneCd9fSwgeydcXFxcLmEuYic6ICd5J30pO1xuICAgKiAgICAgYXNzZXJ0Lm5vdE5lc3RlZEluY2x1ZGUoeydhJzogeydbYl0nOiAneCd9fSwgeydhLlxcXFxbYlxcXFxdJzogJ3knfSk7XG4gICAqXG4gICAqIEBuYW1lIG5vdE5lc3RlZEluY2x1ZGVcbiAgICogQHBhcmFtIHtPYmplY3R9IGhheXN0YWNrXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBuZWVkbGVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm5vdE5lc3RlZEluY2x1ZGUgPSBmdW5jdGlvbiAoZXhwLCBpbmMsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oZXhwLCBtc2csIGFzc2VydC5ub3ROZXN0ZWRJbmNsdWRlLCB0cnVlKVxuICAgICAgLm5vdC5uZXN0ZWQuaW5jbHVkZShpbmMpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmRlZXBOZXN0ZWRJbmNsdWRlKGhheXN0YWNrLCBuZWVkbGUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0ICdoYXlzdGFjaycgaW5jbHVkZXMgJ25lZWRsZScuXG4gICAqIENhbiBiZSB1c2VkIHRvIGFzc2VydCB0aGUgaW5jbHVzaW9uIG9mIGEgc3Vic2V0IG9mIHByb3BlcnRpZXMgaW4gYW5cbiAgICogb2JqZWN0IHdoaWxlIGNoZWNraW5nIGZvciBkZWVwIGVxdWFsaXR5LlxuICAgKiBFbmFibGVzIHRoZSB1c2Ugb2YgZG90LSBhbmQgYnJhY2tldC1ub3RhdGlvbiBmb3IgcmVmZXJlbmNpbmcgbmVzdGVkXG4gICAqIHByb3BlcnRpZXMuXG4gICAqICdbXScgYW5kICcuJyBpbiBwcm9wZXJ0eSBuYW1lcyBjYW4gYmUgZXNjYXBlZCB1c2luZyBkb3VibGUgYmFja3NsYXNoZXMuXG4gICAqXG4gICAqICAgICBhc3NlcnQuZGVlcE5lc3RlZEluY2x1ZGUoe2E6IHtiOiBbe3g6IDF9XX19LCB7J2EuYlswXSc6IHt4OiAxfX0pO1xuICAgKiAgICAgYXNzZXJ0LmRlZXBOZXN0ZWRJbmNsdWRlKHsnLmEnOiB7J1tiXSc6IHt4OiAxfX19LCB7J1xcXFwuYS5cXFxcW2JcXFxcXSc6IHt4OiAxfX0pO1xuICAgKlxuICAgKiBAbmFtZSBkZWVwTmVzdGVkSW5jbHVkZVxuICAgKiBAcGFyYW0ge09iamVjdH0gaGF5c3RhY2tcbiAgICogQHBhcmFtIHtPYmplY3R9IG5lZWRsZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuZGVlcE5lc3RlZEluY2x1ZGUgPSBmdW5jdGlvbihleHAsIGluYywgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihleHAsIG1zZywgYXNzZXJ0LmRlZXBOZXN0ZWRJbmNsdWRlLCB0cnVlKVxuICAgICAgLmRlZXAubmVzdGVkLmluY2x1ZGUoaW5jKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5ub3REZWVwTmVzdGVkSW5jbHVkZShoYXlzdGFjaywgbmVlZGxlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCAnaGF5c3RhY2snIGRvZXMgbm90IGluY2x1ZGUgJ25lZWRsZScuXG4gICAqIENhbiBiZSB1c2VkIHRvIGFzc2VydCB0aGUgYWJzZW5jZSBvZiBhIHN1YnNldCBvZiBwcm9wZXJ0aWVzIGluIGFuXG4gICAqIG9iamVjdCB3aGlsZSBjaGVja2luZyBmb3IgZGVlcCBlcXVhbGl0eS5cbiAgICogRW5hYmxlcyB0aGUgdXNlIG9mIGRvdC0gYW5kIGJyYWNrZXQtbm90YXRpb24gZm9yIHJlZmVyZW5jaW5nIG5lc3RlZFxuICAgKiBwcm9wZXJ0aWVzLlxuICAgKiAnW10nIGFuZCAnLicgaW4gcHJvcGVydHkgbmFtZXMgY2FuIGJlIGVzY2FwZWQgdXNpbmcgZG91YmxlIGJhY2tzbGFzaGVzLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm5vdERlZXBOZXN0ZWRJbmNsdWRlKHthOiB7YjogW3t4OiAxfV19fSwgeydhLmJbMF0nOiB7eTogMX19KVxuICAgKiAgICAgYXNzZXJ0Lm5vdERlZXBOZXN0ZWRJbmNsdWRlKHsnLmEnOiB7J1tiXSc6IHt4OiAxfX19LCB7J1xcXFwuYS5cXFxcW2JcXFxcXSc6IHt5OiAyfX0pO1xuICAgKlxuICAgKiBAbmFtZSBub3REZWVwTmVzdGVkSW5jbHVkZVxuICAgKiBAcGFyYW0ge09iamVjdH0gaGF5c3RhY2tcbiAgICogQHBhcmFtIHtPYmplY3R9IG5lZWRsZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubm90RGVlcE5lc3RlZEluY2x1ZGUgPSBmdW5jdGlvbihleHAsIGluYywgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihleHAsIG1zZywgYXNzZXJ0Lm5vdERlZXBOZXN0ZWRJbmNsdWRlLCB0cnVlKVxuICAgICAgLm5vdC5kZWVwLm5lc3RlZC5pbmNsdWRlKGluYyk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAub3duSW5jbHVkZShoYXlzdGFjaywgbmVlZGxlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCAnaGF5c3RhY2snIGluY2x1ZGVzICduZWVkbGUnLlxuICAgKiBDYW4gYmUgdXNlZCB0byBhc3NlcnQgdGhlIGluY2x1c2lvbiBvZiBhIHN1YnNldCBvZiBwcm9wZXJ0aWVzIGluIGFuXG4gICAqIG9iamVjdCB3aGlsZSBpZ25vcmluZyBpbmhlcml0ZWQgcHJvcGVydGllcy5cbiAgICpcbiAgICogICAgIGFzc2VydC5vd25JbmNsdWRlKHsgYTogMSB9LCB7IGE6IDEgfSk7XG4gICAqXG4gICAqIEBuYW1lIG93bkluY2x1ZGVcbiAgICogQHBhcmFtIHtPYmplY3R9IGhheXN0YWNrXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBuZWVkbGVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm93bkluY2x1ZGUgPSBmdW5jdGlvbihleHAsIGluYywgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihleHAsIG1zZywgYXNzZXJ0Lm93bkluY2x1ZGUsIHRydWUpLm93bi5pbmNsdWRlKGluYyk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAubm90T3duSW5jbHVkZShoYXlzdGFjaywgbmVlZGxlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCAnaGF5c3RhY2snIGluY2x1ZGVzICduZWVkbGUnLlxuICAgKiBDYW4gYmUgdXNlZCB0byBhc3NlcnQgdGhlIGFic2VuY2Ugb2YgYSBzdWJzZXQgb2YgcHJvcGVydGllcyBpbiBhblxuICAgKiBvYmplY3Qgd2hpbGUgaWdub3JpbmcgaW5oZXJpdGVkIHByb3BlcnRpZXMuXG4gICAqXG4gICAqICAgICBPYmplY3QucHJvdG90eXBlLmIgPSAyO1xuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm5vdE93bkluY2x1ZGUoeyBhOiAxIH0sIHsgYjogMiB9KTtcbiAgICpcbiAgICogQG5hbWUgbm90T3duSW5jbHVkZVxuICAgKiBAcGFyYW0ge09iamVjdH0gaGF5c3RhY2tcbiAgICogQHBhcmFtIHtPYmplY3R9IG5lZWRsZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubm90T3duSW5jbHVkZSA9IGZ1bmN0aW9uKGV4cCwgaW5jLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKGV4cCwgbXNnLCBhc3NlcnQubm90T3duSW5jbHVkZSwgdHJ1ZSkubm90Lm93bi5pbmNsdWRlKGluYyk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuZGVlcE93bkluY2x1ZGUoaGF5c3RhY2ssIG5lZWRsZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgJ2hheXN0YWNrJyBpbmNsdWRlcyAnbmVlZGxlJy5cbiAgICogQ2FuIGJlIHVzZWQgdG8gYXNzZXJ0IHRoZSBpbmNsdXNpb24gb2YgYSBzdWJzZXQgb2YgcHJvcGVydGllcyBpbiBhblxuICAgKiBvYmplY3Qgd2hpbGUgaWdub3JpbmcgaW5oZXJpdGVkIHByb3BlcnRpZXMgYW5kIGNoZWNraW5nIGZvciBkZWVwIGVxdWFsaXR5LlxuICAgKlxuICAgKiAgICAgIGFzc2VydC5kZWVwT3duSW5jbHVkZSh7YToge2I6IDJ9fSwge2E6IHtiOiAyfX0pO1xuICAgKlxuICAgKiBAbmFtZSBkZWVwT3duSW5jbHVkZVxuICAgKiBAcGFyYW0ge09iamVjdH0gaGF5c3RhY2tcbiAgICogQHBhcmFtIHtPYmplY3R9IG5lZWRsZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuZGVlcE93bkluY2x1ZGUgPSBmdW5jdGlvbihleHAsIGluYywgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihleHAsIG1zZywgYXNzZXJ0LmRlZXBPd25JbmNsdWRlLCB0cnVlKVxuICAgICAgLmRlZXAub3duLmluY2x1ZGUoaW5jKTtcbiAgfTtcblxuICAgLyoqXG4gICAqICMjIyAubm90RGVlcE93bkluY2x1ZGUoaGF5c3RhY2ssIG5lZWRsZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgJ2hheXN0YWNrJyBpbmNsdWRlcyAnbmVlZGxlJy5cbiAgICogQ2FuIGJlIHVzZWQgdG8gYXNzZXJ0IHRoZSBhYnNlbmNlIG9mIGEgc3Vic2V0IG9mIHByb3BlcnRpZXMgaW4gYW5cbiAgICogb2JqZWN0IHdoaWxlIGlnbm9yaW5nIGluaGVyaXRlZCBwcm9wZXJ0aWVzIGFuZCBjaGVja2luZyBmb3IgZGVlcCBlcXVhbGl0eS5cbiAgICpcbiAgICogICAgICBhc3NlcnQubm90RGVlcE93bkluY2x1ZGUoe2E6IHtiOiAyfX0sIHthOiB7YzogM319KTtcbiAgICpcbiAgICogQG5hbWUgbm90RGVlcE93bkluY2x1ZGVcbiAgICogQHBhcmFtIHtPYmplY3R9IGhheXN0YWNrXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBuZWVkbGVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm5vdERlZXBPd25JbmNsdWRlID0gZnVuY3Rpb24oZXhwLCBpbmMsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oZXhwLCBtc2csIGFzc2VydC5ub3REZWVwT3duSW5jbHVkZSwgdHJ1ZSlcbiAgICAgIC5ub3QuZGVlcC5vd24uaW5jbHVkZShpbmMpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm1hdGNoKHZhbHVlLCByZWdleHAsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgbWF0Y2hlcyB0aGUgcmVndWxhciBleHByZXNzaW9uIGByZWdleHBgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm1hdGNoKCdmb29iYXInLCAvXmZvby8sICdyZWdleHAgbWF0Y2hlcycpO1xuICAgKlxuICAgKiBAbmFtZSBtYXRjaFxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1JlZ0V4cH0gcmVnZXhwXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5tYXRjaCA9IGZ1bmN0aW9uIChleHAsIHJlLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKGV4cCwgbXNnLCBhc3NlcnQubWF0Y2gsIHRydWUpLnRvLm1hdGNoKHJlKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5ub3RNYXRjaCh2YWx1ZSwgcmVnZXhwLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGRvZXMgbm90IG1hdGNoIHRoZSByZWd1bGFyIGV4cHJlc3Npb24gYHJlZ2V4cGAuXG4gICAqXG4gICAqICAgICBhc3NlcnQubm90TWF0Y2goJ2Zvb2JhcicsIC9eZm9vLywgJ3JlZ2V4cCBkb2VzIG5vdCBtYXRjaCcpO1xuICAgKlxuICAgKiBAbmFtZSBub3RNYXRjaFxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1JlZ0V4cH0gcmVnZXhwXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5ub3RNYXRjaCA9IGZ1bmN0aW9uIChleHAsIHJlLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKGV4cCwgbXNnLCBhc3NlcnQubm90TWF0Y2gsIHRydWUpLnRvLm5vdC5tYXRjaChyZSk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAucHJvcGVydHkob2JqZWN0LCBwcm9wZXJ0eSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgaGFzIGEgZGlyZWN0IG9yIGluaGVyaXRlZCBwcm9wZXJ0eSBuYW1lZCBieVxuICAgKiBgcHJvcGVydHlgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LnByb3BlcnR5KHsgdGVhOiB7IGdyZWVuOiAnbWF0Y2hhJyB9fSwgJ3RlYScpO1xuICAgKiAgICAgYXNzZXJ0LnByb3BlcnR5KHsgdGVhOiB7IGdyZWVuOiAnbWF0Y2hhJyB9fSwgJ3RvU3RyaW5nJyk7XG4gICAqXG4gICAqIEBuYW1lIHByb3BlcnR5XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5wcm9wZXJ0eSA9IGZ1bmN0aW9uIChvYmosIHByb3AsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2csIGFzc2VydC5wcm9wZXJ0eSwgdHJ1ZSkudG8uaGF2ZS5wcm9wZXJ0eShwcm9wKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5ub3RQcm9wZXJ0eShvYmplY3QsIHByb3BlcnR5LCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBkb2VzIF9ub3RfIGhhdmUgYSBkaXJlY3Qgb3IgaW5oZXJpdGVkIHByb3BlcnR5IG5hbWVkXG4gICAqIGJ5IGBwcm9wZXJ0eWAuXG4gICAqXG4gICAqICAgICBhc3NlcnQubm90UHJvcGVydHkoeyB0ZWE6IHsgZ3JlZW46ICdtYXRjaGEnIH19LCAnY29mZmVlJyk7XG4gICAqXG4gICAqIEBuYW1lIG5vdFByb3BlcnR5XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5ub3RQcm9wZXJ0eSA9IGZ1bmN0aW9uIChvYmosIHByb3AsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2csIGFzc2VydC5ub3RQcm9wZXJ0eSwgdHJ1ZSlcbiAgICAgIC50by5ub3QuaGF2ZS5wcm9wZXJ0eShwcm9wKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5wcm9wZXJ0eVZhbChvYmplY3QsIHByb3BlcnR5LCB2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgaGFzIGEgZGlyZWN0IG9yIGluaGVyaXRlZCBwcm9wZXJ0eSBuYW1lZCBieVxuICAgKiBgcHJvcGVydHlgIHdpdGggYSB2YWx1ZSBnaXZlbiBieSBgdmFsdWVgLiBVc2VzIGEgc3RyaWN0IGVxdWFsaXR5IGNoZWNrXG4gICAqICg9PT0pLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LnByb3BlcnR5VmFsKHsgdGVhOiAnaXMgZ29vZCcgfSwgJ3RlYScsICdpcyBnb29kJyk7XG4gICAqXG4gICAqIEBuYW1lIHByb3BlcnR5VmFsXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5XG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5wcm9wZXJ0eVZhbCA9IGZ1bmN0aW9uIChvYmosIHByb3AsIHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZywgYXNzZXJ0LnByb3BlcnR5VmFsLCB0cnVlKVxuICAgICAgLnRvLmhhdmUucHJvcGVydHkocHJvcCwgdmFsKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5ub3RQcm9wZXJ0eVZhbChvYmplY3QsIHByb3BlcnR5LCB2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgZG9lcyBfbm90XyBoYXZlIGEgZGlyZWN0IG9yIGluaGVyaXRlZCBwcm9wZXJ0eSBuYW1lZFxuICAgKiBieSBgcHJvcGVydHlgIHdpdGggdmFsdWUgZ2l2ZW4gYnkgYHZhbHVlYC4gVXNlcyBhIHN0cmljdCBlcXVhbGl0eSBjaGVja1xuICAgKiAoPT09KS5cbiAgICpcbiAgICogICAgIGFzc2VydC5ub3RQcm9wZXJ0eVZhbCh7IHRlYTogJ2lzIGdvb2QnIH0sICd0ZWEnLCAnaXMgYmFkJyk7XG4gICAqICAgICBhc3NlcnQubm90UHJvcGVydHlWYWwoeyB0ZWE6ICdpcyBnb29kJyB9LCAnY29mZmVlJywgJ2lzIGdvb2QnKTtcbiAgICpcbiAgICogQG5hbWUgbm90UHJvcGVydHlWYWxcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHlcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm5vdFByb3BlcnR5VmFsID0gZnVuY3Rpb24gKG9iaiwgcHJvcCwgdmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnLCBhc3NlcnQubm90UHJvcGVydHlWYWwsIHRydWUpXG4gICAgICAudG8ubm90LmhhdmUucHJvcGVydHkocHJvcCwgdmFsKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5kZWVwUHJvcGVydHlWYWwob2JqZWN0LCBwcm9wZXJ0eSwgdmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGhhcyBhIGRpcmVjdCBvciBpbmhlcml0ZWQgcHJvcGVydHkgbmFtZWQgYnlcbiAgICogYHByb3BlcnR5YCB3aXRoIGEgdmFsdWUgZ2l2ZW4gYnkgYHZhbHVlYC4gVXNlcyBhIGRlZXAgZXF1YWxpdHkgY2hlY2suXG4gICAqXG4gICAqICAgICBhc3NlcnQuZGVlcFByb3BlcnR5VmFsKHsgdGVhOiB7IGdyZWVuOiAnbWF0Y2hhJyB9IH0sICd0ZWEnLCB7IGdyZWVuOiAnbWF0Y2hhJyB9KTtcbiAgICpcbiAgICogQG5hbWUgZGVlcFByb3BlcnR5VmFsXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5XG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5kZWVwUHJvcGVydHlWYWwgPSBmdW5jdGlvbiAob2JqLCBwcm9wLCB2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2csIGFzc2VydC5kZWVwUHJvcGVydHlWYWwsIHRydWUpXG4gICAgICAudG8uaGF2ZS5kZWVwLnByb3BlcnR5KHByb3AsIHZhbCk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAubm90RGVlcFByb3BlcnR5VmFsKG9iamVjdCwgcHJvcGVydHksIHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBkb2VzIF9ub3RfIGhhdmUgYSBkaXJlY3Qgb3IgaW5oZXJpdGVkIHByb3BlcnR5IG5hbWVkXG4gICAqIGJ5IGBwcm9wZXJ0eWAgd2l0aCB2YWx1ZSBnaXZlbiBieSBgdmFsdWVgLiBVc2VzIGEgZGVlcCBlcXVhbGl0eSBjaGVjay5cbiAgICpcbiAgICogICAgIGFzc2VydC5ub3REZWVwUHJvcGVydHlWYWwoeyB0ZWE6IHsgZ3JlZW46ICdtYXRjaGEnIH0gfSwgJ3RlYScsIHsgYmxhY2s6ICdtYXRjaGEnIH0pO1xuICAgKiAgICAgYXNzZXJ0Lm5vdERlZXBQcm9wZXJ0eVZhbCh7IHRlYTogeyBncmVlbjogJ21hdGNoYScgfSB9LCAndGVhJywgeyBncmVlbjogJ29vbG9uZycgfSk7XG4gICAqICAgICBhc3NlcnQubm90RGVlcFByb3BlcnR5VmFsKHsgdGVhOiB7IGdyZWVuOiAnbWF0Y2hhJyB9IH0sICdjb2ZmZWUnLCB7IGdyZWVuOiAnbWF0Y2hhJyB9KTtcbiAgICpcbiAgICogQG5hbWUgbm90RGVlcFByb3BlcnR5VmFsXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5XG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5ub3REZWVwUHJvcGVydHlWYWwgPSBmdW5jdGlvbiAob2JqLCBwcm9wLCB2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2csIGFzc2VydC5ub3REZWVwUHJvcGVydHlWYWwsIHRydWUpXG4gICAgICAudG8ubm90LmhhdmUuZGVlcC5wcm9wZXJ0eShwcm9wLCB2YWwpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm93blByb3BlcnR5KG9iamVjdCwgcHJvcGVydHksIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGhhcyBhIGRpcmVjdCBwcm9wZXJ0eSBuYW1lZCBieSBgcHJvcGVydHlgLiBJbmhlcml0ZWRcbiAgICogcHJvcGVydGllcyBhcmVuJ3QgY2hlY2tlZC5cbiAgICpcbiAgICogICAgIGFzc2VydC5vd25Qcm9wZXJ0eSh7IHRlYTogeyBncmVlbjogJ21hdGNoYScgfX0sICd0ZWEnKTtcbiAgICpcbiAgICogQG5hbWUgb3duUHJvcGVydHlcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHlcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm93blByb3BlcnR5ID0gZnVuY3Rpb24gKG9iaiwgcHJvcCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZywgYXNzZXJ0Lm93blByb3BlcnR5LCB0cnVlKVxuICAgICAgLnRvLmhhdmUub3duLnByb3BlcnR5KHByb3ApO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm5vdE93blByb3BlcnR5KG9iamVjdCwgcHJvcGVydHksIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGRvZXMgX25vdF8gaGF2ZSBhIGRpcmVjdCBwcm9wZXJ0eSBuYW1lZCBieVxuICAgKiBgcHJvcGVydHlgLiBJbmhlcml0ZWQgcHJvcGVydGllcyBhcmVuJ3QgY2hlY2tlZC5cbiAgICpcbiAgICogICAgIGFzc2VydC5ub3RPd25Qcm9wZXJ0eSh7IHRlYTogeyBncmVlbjogJ21hdGNoYScgfX0sICdjb2ZmZWUnKTtcbiAgICogICAgIGFzc2VydC5ub3RPd25Qcm9wZXJ0eSh7fSwgJ3RvU3RyaW5nJyk7XG4gICAqXG4gICAqIEBuYW1lIG5vdE93blByb3BlcnR5XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5ub3RPd25Qcm9wZXJ0eSA9IGZ1bmN0aW9uIChvYmosIHByb3AsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2csIGFzc2VydC5ub3RPd25Qcm9wZXJ0eSwgdHJ1ZSlcbiAgICAgIC50by5ub3QuaGF2ZS5vd24ucHJvcGVydHkocHJvcCk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAub3duUHJvcGVydHlWYWwob2JqZWN0LCBwcm9wZXJ0eSwgdmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGhhcyBhIGRpcmVjdCBwcm9wZXJ0eSBuYW1lZCBieSBgcHJvcGVydHlgIGFuZCBhIHZhbHVlXG4gICAqIGVxdWFsIHRvIHRoZSBwcm92aWRlZCBgdmFsdWVgLiBVc2VzIGEgc3RyaWN0IGVxdWFsaXR5IGNoZWNrICg9PT0pLlxuICAgKiBJbmhlcml0ZWQgcHJvcGVydGllcyBhcmVuJ3QgY2hlY2tlZC5cbiAgICpcbiAgICogICAgIGFzc2VydC5vd25Qcm9wZXJ0eVZhbCh7IGNvZmZlZTogJ2lzIGdvb2QnfSwgJ2NvZmZlZScsICdpcyBnb29kJyk7XG4gICAqXG4gICAqIEBuYW1lIG93blByb3BlcnR5VmFsXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5XG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5vd25Qcm9wZXJ0eVZhbCA9IGZ1bmN0aW9uIChvYmosIHByb3AsIHZhbHVlLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnLCBhc3NlcnQub3duUHJvcGVydHlWYWwsIHRydWUpXG4gICAgICAudG8uaGF2ZS5vd24ucHJvcGVydHkocHJvcCwgdmFsdWUpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm5vdE93blByb3BlcnR5VmFsKG9iamVjdCwgcHJvcGVydHksIHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBkb2VzIF9ub3RfIGhhdmUgYSBkaXJlY3QgcHJvcGVydHkgbmFtZWQgYnkgYHByb3BlcnR5YFxuICAgKiB3aXRoIGEgdmFsdWUgZXF1YWwgdG8gdGhlIHByb3ZpZGVkIGB2YWx1ZWAuIFVzZXMgYSBzdHJpY3QgZXF1YWxpdHkgY2hlY2tcbiAgICogKD09PSkuIEluaGVyaXRlZCBwcm9wZXJ0aWVzIGFyZW4ndCBjaGVja2VkLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm5vdE93blByb3BlcnR5VmFsKHsgdGVhOiAnaXMgYmV0dGVyJ30sICd0ZWEnLCAnaXMgd29yc2UnKTtcbiAgICogICAgIGFzc2VydC5ub3RPd25Qcm9wZXJ0eVZhbCh7fSwgJ3RvU3RyaW5nJywgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZyk7XG4gICAqXG4gICAqIEBuYW1lIG5vdE93blByb3BlcnR5VmFsXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5XG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5ub3RPd25Qcm9wZXJ0eVZhbCA9IGZ1bmN0aW9uIChvYmosIHByb3AsIHZhbHVlLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnLCBhc3NlcnQubm90T3duUHJvcGVydHlWYWwsIHRydWUpXG4gICAgICAudG8ubm90LmhhdmUub3duLnByb3BlcnR5KHByb3AsIHZhbHVlKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5kZWVwT3duUHJvcGVydHlWYWwob2JqZWN0LCBwcm9wZXJ0eSwgdmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGhhcyBhIGRpcmVjdCBwcm9wZXJ0eSBuYW1lZCBieSBgcHJvcGVydHlgIGFuZCBhIHZhbHVlXG4gICAqIGVxdWFsIHRvIHRoZSBwcm92aWRlZCBgdmFsdWVgLiBVc2VzIGEgZGVlcCBlcXVhbGl0eSBjaGVjay4gSW5oZXJpdGVkXG4gICAqIHByb3BlcnRpZXMgYXJlbid0IGNoZWNrZWQuXG4gICAqXG4gICAqICAgICBhc3NlcnQuZGVlcE93blByb3BlcnR5VmFsKHsgdGVhOiB7IGdyZWVuOiAnbWF0Y2hhJyB9IH0sICd0ZWEnLCB7IGdyZWVuOiAnbWF0Y2hhJyB9KTtcbiAgICpcbiAgICogQG5hbWUgZGVlcE93blByb3BlcnR5VmFsXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5XG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5kZWVwT3duUHJvcGVydHlWYWwgPSBmdW5jdGlvbiAob2JqLCBwcm9wLCB2YWx1ZSwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZywgYXNzZXJ0LmRlZXBPd25Qcm9wZXJ0eVZhbCwgdHJ1ZSlcbiAgICAgIC50by5oYXZlLmRlZXAub3duLnByb3BlcnR5KHByb3AsIHZhbHVlKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5ub3REZWVwT3duUHJvcGVydHlWYWwob2JqZWN0LCBwcm9wZXJ0eSwgdmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGRvZXMgX25vdF8gaGF2ZSBhIGRpcmVjdCBwcm9wZXJ0eSBuYW1lZCBieSBgcHJvcGVydHlgXG4gICAqIHdpdGggYSB2YWx1ZSBlcXVhbCB0byB0aGUgcHJvdmlkZWQgYHZhbHVlYC4gVXNlcyBhIGRlZXAgZXF1YWxpdHkgY2hlY2suXG4gICAqIEluaGVyaXRlZCBwcm9wZXJ0aWVzIGFyZW4ndCBjaGVja2VkLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm5vdERlZXBPd25Qcm9wZXJ0eVZhbCh7IHRlYTogeyBncmVlbjogJ21hdGNoYScgfSB9LCAndGVhJywgeyBibGFjazogJ21hdGNoYScgfSk7XG4gICAqICAgICBhc3NlcnQubm90RGVlcE93blByb3BlcnR5VmFsKHsgdGVhOiB7IGdyZWVuOiAnbWF0Y2hhJyB9IH0sICd0ZWEnLCB7IGdyZWVuOiAnb29sb25nJyB9KTtcbiAgICogICAgIGFzc2VydC5ub3REZWVwT3duUHJvcGVydHlWYWwoeyB0ZWE6IHsgZ3JlZW46ICdtYXRjaGEnIH0gfSwgJ2NvZmZlZScsIHsgZ3JlZW46ICdtYXRjaGEnIH0pO1xuICAgKiAgICAgYXNzZXJ0Lm5vdERlZXBPd25Qcm9wZXJ0eVZhbCh7fSwgJ3RvU3RyaW5nJywgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZyk7XG4gICAqXG4gICAqIEBuYW1lIG5vdERlZXBPd25Qcm9wZXJ0eVZhbFxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eVxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubm90RGVlcE93blByb3BlcnR5VmFsID0gZnVuY3Rpb24gKG9iaiwgcHJvcCwgdmFsdWUsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2csIGFzc2VydC5ub3REZWVwT3duUHJvcGVydHlWYWwsIHRydWUpXG4gICAgICAudG8ubm90LmhhdmUuZGVlcC5vd24ucHJvcGVydHkocHJvcCwgdmFsdWUpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm5lc3RlZFByb3BlcnR5KG9iamVjdCwgcHJvcGVydHksIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGhhcyBhIGRpcmVjdCBvciBpbmhlcml0ZWQgcHJvcGVydHkgbmFtZWQgYnlcbiAgICogYHByb3BlcnR5YCwgd2hpY2ggY2FuIGJlIGEgc3RyaW5nIHVzaW5nIGRvdC0gYW5kIGJyYWNrZXQtbm90YXRpb24gZm9yXG4gICAqIG5lc3RlZCByZWZlcmVuY2UuXG4gICAqXG4gICAqICAgICBhc3NlcnQubmVzdGVkUHJvcGVydHkoeyB0ZWE6IHsgZ3JlZW46ICdtYXRjaGEnIH19LCAndGVhLmdyZWVuJyk7XG4gICAqXG4gICAqIEBuYW1lIG5lc3RlZFByb3BlcnR5XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5uZXN0ZWRQcm9wZXJ0eSA9IGZ1bmN0aW9uIChvYmosIHByb3AsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2csIGFzc2VydC5uZXN0ZWRQcm9wZXJ0eSwgdHJ1ZSlcbiAgICAgIC50by5oYXZlLm5lc3RlZC5wcm9wZXJ0eShwcm9wKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5ub3ROZXN0ZWRQcm9wZXJ0eShvYmplY3QsIHByb3BlcnR5LCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBkb2VzIF9ub3RfIGhhdmUgYSBwcm9wZXJ0eSBuYW1lZCBieSBgcHJvcGVydHlgLCB3aGljaFxuICAgKiBjYW4gYmUgYSBzdHJpbmcgdXNpbmcgZG90LSBhbmQgYnJhY2tldC1ub3RhdGlvbiBmb3IgbmVzdGVkIHJlZmVyZW5jZS4gVGhlXG4gICAqIHByb3BlcnR5IGNhbm5vdCBleGlzdCBvbiB0aGUgb2JqZWN0IG5vciBhbnl3aGVyZSBpbiBpdHMgcHJvdG90eXBlIGNoYWluLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm5vdE5lc3RlZFByb3BlcnR5KHsgdGVhOiB7IGdyZWVuOiAnbWF0Y2hhJyB9fSwgJ3RlYS5vb2xvbmcnKTtcbiAgICpcbiAgICogQG5hbWUgbm90TmVzdGVkUHJvcGVydHlcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHlcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm5vdE5lc3RlZFByb3BlcnR5ID0gZnVuY3Rpb24gKG9iaiwgcHJvcCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZywgYXNzZXJ0Lm5vdE5lc3RlZFByb3BlcnR5LCB0cnVlKVxuICAgICAgLnRvLm5vdC5oYXZlLm5lc3RlZC5wcm9wZXJ0eShwcm9wKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5uZXN0ZWRQcm9wZXJ0eVZhbChvYmplY3QsIHByb3BlcnR5LCB2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgaGFzIGEgcHJvcGVydHkgbmFtZWQgYnkgYHByb3BlcnR5YCB3aXRoIHZhbHVlIGdpdmVuXG4gICAqIGJ5IGB2YWx1ZWAuIGBwcm9wZXJ0eWAgY2FuIHVzZSBkb3QtIGFuZCBicmFja2V0LW5vdGF0aW9uIGZvciBuZXN0ZWRcbiAgICogcmVmZXJlbmNlLiBVc2VzIGEgc3RyaWN0IGVxdWFsaXR5IGNoZWNrICg9PT0pLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm5lc3RlZFByb3BlcnR5VmFsKHsgdGVhOiB7IGdyZWVuOiAnbWF0Y2hhJyB9fSwgJ3RlYS5ncmVlbicsICdtYXRjaGEnKTtcbiAgICpcbiAgICogQG5hbWUgbmVzdGVkUHJvcGVydHlWYWxcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHlcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm5lc3RlZFByb3BlcnR5VmFsID0gZnVuY3Rpb24gKG9iaiwgcHJvcCwgdmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnLCBhc3NlcnQubmVzdGVkUHJvcGVydHlWYWwsIHRydWUpXG4gICAgICAudG8uaGF2ZS5uZXN0ZWQucHJvcGVydHkocHJvcCwgdmFsKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5ub3ROZXN0ZWRQcm9wZXJ0eVZhbChvYmplY3QsIHByb3BlcnR5LCB2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgZG9lcyBfbm90XyBoYXZlIGEgcHJvcGVydHkgbmFtZWQgYnkgYHByb3BlcnR5YCB3aXRoXG4gICAqIHZhbHVlIGdpdmVuIGJ5IGB2YWx1ZWAuIGBwcm9wZXJ0eWAgY2FuIHVzZSBkb3QtIGFuZCBicmFja2V0LW5vdGF0aW9uIGZvclxuICAgKiBuZXN0ZWQgcmVmZXJlbmNlLiBVc2VzIGEgc3RyaWN0IGVxdWFsaXR5IGNoZWNrICg9PT0pLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm5vdE5lc3RlZFByb3BlcnR5VmFsKHsgdGVhOiB7IGdyZWVuOiAnbWF0Y2hhJyB9fSwgJ3RlYS5ncmVlbicsICdrb25hY2hhJyk7XG4gICAqICAgICBhc3NlcnQubm90TmVzdGVkUHJvcGVydHlWYWwoeyB0ZWE6IHsgZ3JlZW46ICdtYXRjaGEnIH19LCAnY29mZmVlLmdyZWVuJywgJ21hdGNoYScpO1xuICAgKlxuICAgKiBAbmFtZSBub3ROZXN0ZWRQcm9wZXJ0eVZhbFxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eVxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubm90TmVzdGVkUHJvcGVydHlWYWwgPSBmdW5jdGlvbiAob2JqLCBwcm9wLCB2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2csIGFzc2VydC5ub3ROZXN0ZWRQcm9wZXJ0eVZhbCwgdHJ1ZSlcbiAgICAgIC50by5ub3QuaGF2ZS5uZXN0ZWQucHJvcGVydHkocHJvcCwgdmFsKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5kZWVwTmVzdGVkUHJvcGVydHlWYWwob2JqZWN0LCBwcm9wZXJ0eSwgdmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGhhcyBhIHByb3BlcnR5IG5hbWVkIGJ5IGBwcm9wZXJ0eWAgd2l0aCBhIHZhbHVlIGdpdmVuXG4gICAqIGJ5IGB2YWx1ZWAuIGBwcm9wZXJ0eWAgY2FuIHVzZSBkb3QtIGFuZCBicmFja2V0LW5vdGF0aW9uIGZvciBuZXN0ZWRcbiAgICogcmVmZXJlbmNlLiBVc2VzIGEgZGVlcCBlcXVhbGl0eSBjaGVjay5cbiAgICpcbiAgICogICAgIGFzc2VydC5kZWVwTmVzdGVkUHJvcGVydHlWYWwoeyB0ZWE6IHsgZ3JlZW46IHsgbWF0Y2hhOiAneXVtJyB9IH0gfSwgJ3RlYS5ncmVlbicsIHsgbWF0Y2hhOiAneXVtJyB9KTtcbiAgICpcbiAgICogQG5hbWUgZGVlcE5lc3RlZFByb3BlcnR5VmFsXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5XG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5kZWVwTmVzdGVkUHJvcGVydHlWYWwgPSBmdW5jdGlvbiAob2JqLCBwcm9wLCB2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2csIGFzc2VydC5kZWVwTmVzdGVkUHJvcGVydHlWYWwsIHRydWUpXG4gICAgICAudG8uaGF2ZS5kZWVwLm5lc3RlZC5wcm9wZXJ0eShwcm9wLCB2YWwpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm5vdERlZXBOZXN0ZWRQcm9wZXJ0eVZhbChvYmplY3QsIHByb3BlcnR5LCB2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgZG9lcyBfbm90XyBoYXZlIGEgcHJvcGVydHkgbmFtZWQgYnkgYHByb3BlcnR5YCB3aXRoXG4gICAqIHZhbHVlIGdpdmVuIGJ5IGB2YWx1ZWAuIGBwcm9wZXJ0eWAgY2FuIHVzZSBkb3QtIGFuZCBicmFja2V0LW5vdGF0aW9uIGZvclxuICAgKiBuZXN0ZWQgcmVmZXJlbmNlLiBVc2VzIGEgZGVlcCBlcXVhbGl0eSBjaGVjay5cbiAgICpcbiAgICogICAgIGFzc2VydC5ub3REZWVwTmVzdGVkUHJvcGVydHlWYWwoeyB0ZWE6IHsgZ3JlZW46IHsgbWF0Y2hhOiAneXVtJyB9IH0gfSwgJ3RlYS5ncmVlbicsIHsgb29sb25nOiAneXVtJyB9KTtcbiAgICogICAgIGFzc2VydC5ub3REZWVwTmVzdGVkUHJvcGVydHlWYWwoeyB0ZWE6IHsgZ3JlZW46IHsgbWF0Y2hhOiAneXVtJyB9IH0gfSwgJ3RlYS5ncmVlbicsIHsgbWF0Y2hhOiAneXVjaycgfSk7XG4gICAqICAgICBhc3NlcnQubm90RGVlcE5lc3RlZFByb3BlcnR5VmFsKHsgdGVhOiB7IGdyZWVuOiB7IG1hdGNoYTogJ3l1bScgfSB9IH0sICd0ZWEuYmxhY2snLCB7IG1hdGNoYTogJ3l1bScgfSk7XG4gICAqXG4gICAqIEBuYW1lIG5vdERlZXBOZXN0ZWRQcm9wZXJ0eVZhbFxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eVxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubm90RGVlcE5lc3RlZFByb3BlcnR5VmFsID0gZnVuY3Rpb24gKG9iaiwgcHJvcCwgdmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnLCBhc3NlcnQubm90RGVlcE5lc3RlZFByb3BlcnR5VmFsLCB0cnVlKVxuICAgICAgLnRvLm5vdC5oYXZlLmRlZXAubmVzdGVkLnByb3BlcnR5KHByb3AsIHZhbCk7XG4gIH1cblxuICAvKipcbiAgICogIyMjIC5sZW5ndGhPZihvYmplY3QsIGxlbmd0aCwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgaGFzIGEgYGxlbmd0aGAgb3IgYHNpemVgIHdpdGggdGhlIGV4cGVjdGVkIHZhbHVlLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lmxlbmd0aE9mKFsxLDIsM10sIDMsICdhcnJheSBoYXMgbGVuZ3RoIG9mIDMnKTtcbiAgICogICAgIGFzc2VydC5sZW5ndGhPZignZm9vYmFyJywgNiwgJ3N0cmluZyBoYXMgbGVuZ3RoIG9mIDYnKTtcbiAgICogICAgIGFzc2VydC5sZW5ndGhPZihuZXcgU2V0KFsxLDIsM10pLCAzLCAnc2V0IGhhcyBzaXplIG9mIDMnKTtcbiAgICogICAgIGFzc2VydC5sZW5ndGhPZihuZXcgTWFwKFtbJ2EnLDFdLFsnYicsMl0sWydjJywzXV0pLCAzLCAnbWFwIGhhcyBzaXplIG9mIDMnKTtcbiAgICpcbiAgICogQG5hbWUgbGVuZ3RoT2ZcbiAgICogQHBhcmFtIHtNaXhlZH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7TnVtYmVyfSBsZW5ndGhcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lmxlbmd0aE9mID0gZnVuY3Rpb24gKGV4cCwgbGVuLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKGV4cCwgbXNnLCBhc3NlcnQubGVuZ3RoT2YsIHRydWUpLnRvLmhhdmUubGVuZ3RoT2YobGVuKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5oYXNBbnlLZXlzKG9iamVjdCwgW2tleXNdLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBoYXMgYXQgbGVhc3Qgb25lIG9mIHRoZSBga2V5c2AgcHJvdmlkZWQuXG4gICAqIFlvdSBjYW4gYWxzbyBwcm92aWRlIGEgc2luZ2xlIG9iamVjdCBpbnN0ZWFkIG9mIGEgYGtleXNgIGFycmF5IGFuZCBpdHMga2V5c1xuICAgKiB3aWxsIGJlIHVzZWQgYXMgdGhlIGV4cGVjdGVkIHNldCBvZiBrZXlzLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lmhhc0FueUtleXMoe2ZvbzogMSwgYmFyOiAyLCBiYXo6IDN9LCBbJ2ZvbycsICdpRG9udEV4aXN0JywgJ2JheiddKTtcbiAgICogICAgIGFzc2VydC5oYXNBbnlLZXlzKHtmb286IDEsIGJhcjogMiwgYmF6OiAzfSwge2ZvbzogMzAsIGlEb250RXhpc3Q6IDk5LCBiYXo6IDEzMzd9KTtcbiAgICogICAgIGFzc2VydC5oYXNBbnlLZXlzKG5ldyBNYXAoW1t7Zm9vOiAxfSwgJ2JhciddLCBbJ2tleScsICd2YWx1ZSddXSksIFt7Zm9vOiAxfSwgJ2tleSddKTtcbiAgICogICAgIGFzc2VydC5oYXNBbnlLZXlzKG5ldyBTZXQoW3tmb286ICdiYXInfSwgJ2Fub3RoZXJLZXknXSksIFt7Zm9vOiAnYmFyJ30sICdhbm90aGVyS2V5J10pO1xuICAgKlxuICAgKiBAbmFtZSBoYXNBbnlLZXlzXG4gICAqIEBwYXJhbSB7TWl4ZWR9IG9iamVjdFxuICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0ga2V5c1xuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaGFzQW55S2V5cyA9IGZ1bmN0aW9uIChvYmosIGtleXMsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2csIGFzc2VydC5oYXNBbnlLZXlzLCB0cnVlKS50by5oYXZlLmFueS5rZXlzKGtleXMpO1xuICB9XG5cbiAgLyoqXG4gICAqICMjIyAuaGFzQWxsS2V5cyhvYmplY3QsIFtrZXlzXSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgaGFzIGFsbCBhbmQgb25seSBhbGwgb2YgdGhlIGBrZXlzYCBwcm92aWRlZC5cbiAgICogWW91IGNhbiBhbHNvIHByb3ZpZGUgYSBzaW5nbGUgb2JqZWN0IGluc3RlYWQgb2YgYSBga2V5c2AgYXJyYXkgYW5kIGl0cyBrZXlzXG4gICAqIHdpbGwgYmUgdXNlZCBhcyB0aGUgZXhwZWN0ZWQgc2V0IG9mIGtleXMuXG4gICAqXG4gICAqICAgICBhc3NlcnQuaGFzQWxsS2V5cyh7Zm9vOiAxLCBiYXI6IDIsIGJhejogM30sIFsnZm9vJywgJ2JhcicsICdiYXonXSk7XG4gICAqICAgICBhc3NlcnQuaGFzQWxsS2V5cyh7Zm9vOiAxLCBiYXI6IDIsIGJhejogM30sIHtmb286IDMwLCBiYXI6IDk5LCBiYXo6IDEzMzddKTtcbiAgICogICAgIGFzc2VydC5oYXNBbGxLZXlzKG5ldyBNYXAoW1t7Zm9vOiAxfSwgJ2JhciddLCBbJ2tleScsICd2YWx1ZSddXSksIFt7Zm9vOiAxfSwgJ2tleSddKTtcbiAgICogICAgIGFzc2VydC5oYXNBbGxLZXlzKG5ldyBTZXQoW3tmb286ICdiYXInfSwgJ2Fub3RoZXJLZXknXSwgW3tmb286ICdiYXInfSwgJ2Fub3RoZXJLZXknXSk7XG4gICAqXG4gICAqIEBuYW1lIGhhc0FsbEtleXNcbiAgICogQHBhcmFtIHtNaXhlZH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nW119IGtleXNcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lmhhc0FsbEtleXMgPSBmdW5jdGlvbiAob2JqLCBrZXlzLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnLCBhc3NlcnQuaGFzQWxsS2V5cywgdHJ1ZSkudG8uaGF2ZS5hbGwua2V5cyhrZXlzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiAjIyMgLmNvbnRhaW5zQWxsS2V5cyhvYmplY3QsIFtrZXlzXSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgaGFzIGFsbCBvZiB0aGUgYGtleXNgIHByb3ZpZGVkIGJ1dCBtYXkgaGF2ZSBtb3JlIGtleXMgbm90IGxpc3RlZC5cbiAgICogWW91IGNhbiBhbHNvIHByb3ZpZGUgYSBzaW5nbGUgb2JqZWN0IGluc3RlYWQgb2YgYSBga2V5c2AgYXJyYXkgYW5kIGl0cyBrZXlzXG4gICAqIHdpbGwgYmUgdXNlZCBhcyB0aGUgZXhwZWN0ZWQgc2V0IG9mIGtleXMuXG4gICAqXG4gICAqICAgICBhc3NlcnQuY29udGFpbnNBbGxLZXlzKHtmb286IDEsIGJhcjogMiwgYmF6OiAzfSwgWydmb28nLCAnYmF6J10pO1xuICAgKiAgICAgYXNzZXJ0LmNvbnRhaW5zQWxsS2V5cyh7Zm9vOiAxLCBiYXI6IDIsIGJhejogM30sIFsnZm9vJywgJ2JhcicsICdiYXonXSk7XG4gICAqICAgICBhc3NlcnQuY29udGFpbnNBbGxLZXlzKHtmb286IDEsIGJhcjogMiwgYmF6OiAzfSwge2ZvbzogMzAsIGJhejogMTMzN30pO1xuICAgKiAgICAgYXNzZXJ0LmNvbnRhaW5zQWxsS2V5cyh7Zm9vOiAxLCBiYXI6IDIsIGJhejogM30sIHtmb286IDMwLCBiYXI6IDk5LCBiYXo6IDEzMzd9KTtcbiAgICogICAgIGFzc2VydC5jb250YWluc0FsbEtleXMobmV3IE1hcChbW3tmb286IDF9LCAnYmFyJ10sIFsna2V5JywgJ3ZhbHVlJ11dKSwgW3tmb286IDF9XSk7XG4gICAqICAgICBhc3NlcnQuY29udGFpbnNBbGxLZXlzKG5ldyBNYXAoW1t7Zm9vOiAxfSwgJ2JhciddLCBbJ2tleScsICd2YWx1ZSddXSksIFt7Zm9vOiAxfSwgJ2tleSddKTtcbiAgICogICAgIGFzc2VydC5jb250YWluc0FsbEtleXMobmV3IFNldChbe2ZvbzogJ2Jhcid9LCAnYW5vdGhlcktleSddLCBbe2ZvbzogJ2Jhcid9XSk7XG4gICAqICAgICBhc3NlcnQuY29udGFpbnNBbGxLZXlzKG5ldyBTZXQoW3tmb286ICdiYXInfSwgJ2Fub3RoZXJLZXknXSwgW3tmb286ICdiYXInfSwgJ2Fub3RoZXJLZXknXSk7XG4gICAqXG4gICAqIEBuYW1lIGNvbnRhaW5zQWxsS2V5c1xuICAgKiBAcGFyYW0ge01peGVkfSBvYmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmdbXX0ga2V5c1xuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuY29udGFpbnNBbGxLZXlzID0gZnVuY3Rpb24gKG9iaiwga2V5cywgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZywgYXNzZXJ0LmNvbnRhaW5zQWxsS2V5cywgdHJ1ZSlcbiAgICAgIC50by5jb250YWluLmFsbC5rZXlzKGtleXMpO1xuICB9XG5cbiAgLyoqXG4gICAqICMjIyAuZG9lc05vdEhhdmVBbnlLZXlzKG9iamVjdCwgW2tleXNdLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBoYXMgbm9uZSBvZiB0aGUgYGtleXNgIHByb3ZpZGVkLlxuICAgKiBZb3UgY2FuIGFsc28gcHJvdmlkZSBhIHNpbmdsZSBvYmplY3QgaW5zdGVhZCBvZiBhIGBrZXlzYCBhcnJheSBhbmQgaXRzIGtleXNcbiAgICogd2lsbCBiZSB1c2VkIGFzIHRoZSBleHBlY3RlZCBzZXQgb2Yga2V5cy5cbiAgICpcbiAgICogICAgIGFzc2VydC5kb2VzTm90SGF2ZUFueUtleXMoe2ZvbzogMSwgYmFyOiAyLCBiYXo6IDN9LCBbJ29uZScsICd0d28nLCAnZXhhbXBsZSddKTtcbiAgICogICAgIGFzc2VydC5kb2VzTm90SGF2ZUFueUtleXMoe2ZvbzogMSwgYmFyOiAyLCBiYXo6IDN9LCB7b25lOiAxLCB0d286IDIsIGV4YW1wbGU6ICdmb28nfSk7XG4gICAqICAgICBhc3NlcnQuZG9lc05vdEhhdmVBbnlLZXlzKG5ldyBNYXAoW1t7Zm9vOiAxfSwgJ2JhciddLCBbJ2tleScsICd2YWx1ZSddXSksIFt7b25lOiAndHdvJ30sICdleGFtcGxlJ10pO1xuICAgKiAgICAgYXNzZXJ0LmRvZXNOb3RIYXZlQW55S2V5cyhuZXcgU2V0KFt7Zm9vOiAnYmFyJ30sICdhbm90aGVyS2V5J10sIFt7b25lOiAndHdvJ30sICdleGFtcGxlJ10pO1xuICAgKlxuICAgKiBAbmFtZSBkb2VzTm90SGF2ZUFueUtleXNcbiAgICogQHBhcmFtIHtNaXhlZH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nW119IGtleXNcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmRvZXNOb3RIYXZlQW55S2V5cyA9IGZ1bmN0aW9uIChvYmosIGtleXMsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2csIGFzc2VydC5kb2VzTm90SGF2ZUFueUtleXMsIHRydWUpXG4gICAgICAudG8ubm90LmhhdmUuYW55LmtleXMoa2V5cyk7XG4gIH1cblxuICAvKipcbiAgICogIyMjIC5kb2VzTm90SGF2ZUFsbEtleXMob2JqZWN0LCBba2V5c10sIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGRvZXMgbm90IGhhdmUgYXQgbGVhc3Qgb25lIG9mIHRoZSBga2V5c2AgcHJvdmlkZWQuXG4gICAqIFlvdSBjYW4gYWxzbyBwcm92aWRlIGEgc2luZ2xlIG9iamVjdCBpbnN0ZWFkIG9mIGEgYGtleXNgIGFycmF5IGFuZCBpdHMga2V5c1xuICAgKiB3aWxsIGJlIHVzZWQgYXMgdGhlIGV4cGVjdGVkIHNldCBvZiBrZXlzLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmRvZXNOb3RIYXZlQWxsS2V5cyh7Zm9vOiAxLCBiYXI6IDIsIGJhejogM30sIFsnb25lJywgJ3R3bycsICdleGFtcGxlJ10pO1xuICAgKiAgICAgYXNzZXJ0LmRvZXNOb3RIYXZlQWxsS2V5cyh7Zm9vOiAxLCBiYXI6IDIsIGJhejogM30sIHtvbmU6IDEsIHR3bzogMiwgZXhhbXBsZTogJ2Zvbyd9KTtcbiAgICogICAgIGFzc2VydC5kb2VzTm90SGF2ZUFsbEtleXMobmV3IE1hcChbW3tmb286IDF9LCAnYmFyJ10sIFsna2V5JywgJ3ZhbHVlJ11dKSwgW3tvbmU6ICd0d28nfSwgJ2V4YW1wbGUnXSk7XG4gICAqICAgICBhc3NlcnQuZG9lc05vdEhhdmVBbGxLZXlzKG5ldyBTZXQoW3tmb286ICdiYXInfSwgJ2Fub3RoZXJLZXknXSwgW3tvbmU6ICd0d28nfSwgJ2V4YW1wbGUnXSk7XG4gICAqXG4gICAqIEBuYW1lIGRvZXNOb3RIYXZlQWxsS2V5c1xuICAgKiBAcGFyYW0ge01peGVkfSBvYmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmdbXX0ga2V5c1xuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuZG9lc05vdEhhdmVBbGxLZXlzID0gZnVuY3Rpb24gKG9iaiwga2V5cywgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZywgYXNzZXJ0LmRvZXNOb3RIYXZlQWxsS2V5cywgdHJ1ZSlcbiAgICAgIC50by5ub3QuaGF2ZS5hbGwua2V5cyhrZXlzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiAjIyMgLmhhc0FueURlZXBLZXlzKG9iamVjdCwgW2tleXNdLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBoYXMgYXQgbGVhc3Qgb25lIG9mIHRoZSBga2V5c2AgcHJvdmlkZWQuXG4gICAqIFNpbmNlIFNldHMgYW5kIE1hcHMgY2FuIGhhdmUgb2JqZWN0cyBhcyBrZXlzIHlvdSBjYW4gdXNlIHRoaXMgYXNzZXJ0aW9uIHRvIHBlcmZvcm1cbiAgICogYSBkZWVwIGNvbXBhcmlzb24uXG4gICAqIFlvdSBjYW4gYWxzbyBwcm92aWRlIGEgc2luZ2xlIG9iamVjdCBpbnN0ZWFkIG9mIGEgYGtleXNgIGFycmF5IGFuZCBpdHMga2V5c1xuICAgKiB3aWxsIGJlIHVzZWQgYXMgdGhlIGV4cGVjdGVkIHNldCBvZiBrZXlzLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lmhhc0FueURlZXBLZXlzKG5ldyBNYXAoW1t7b25lOiAnb25lJ30sICd2YWx1ZU9uZSddLCBbMSwgMl1dKSwge29uZTogJ29uZSd9KTtcbiAgICogICAgIGFzc2VydC5oYXNBbnlEZWVwS2V5cyhuZXcgTWFwKFtbe29uZTogJ29uZSd9LCAndmFsdWVPbmUnXSwgWzEsIDJdXSksIFt7b25lOiAnb25lJ30sIHt0d286ICd0d28nfV0pO1xuICAgKiAgICAgYXNzZXJ0Lmhhc0FueURlZXBLZXlzKG5ldyBNYXAoW1t7b25lOiAnb25lJ30sICd2YWx1ZU9uZSddLCBbe3R3bzogJ3R3byd9LCAndmFsdWVUd28nXV0pLCBbe29uZTogJ29uZSd9LCB7dHdvOiAndHdvJ31dKTtcbiAgICogICAgIGFzc2VydC5oYXNBbnlEZWVwS2V5cyhuZXcgU2V0KFt7b25lOiAnb25lJ30sIHt0d286ICd0d28nfV0pLCB7b25lOiAnb25lJ30pO1xuICAgKiAgICAgYXNzZXJ0Lmhhc0FueURlZXBLZXlzKG5ldyBTZXQoW3tvbmU6ICdvbmUnfSwge3R3bzogJ3R3byd9XSksIFt7b25lOiAnb25lJ30sIHt0aHJlZTogJ3RocmVlJ31dKTtcbiAgICogICAgIGFzc2VydC5oYXNBbnlEZWVwS2V5cyhuZXcgU2V0KFt7b25lOiAnb25lJ30sIHt0d286ICd0d28nfV0pLCBbe29uZTogJ29uZSd9LCB7dHdvOiAndHdvJ31dKTtcbiAgICpcbiAgICogQG5hbWUgaGFzQW55RGVlcEtleXNcbiAgICogQHBhcmFtIHtNaXhlZH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBrZXlzXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5oYXNBbnlEZWVwS2V5cyA9IGZ1bmN0aW9uIChvYmosIGtleXMsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2csIGFzc2VydC5oYXNBbnlEZWVwS2V5cywgdHJ1ZSlcbiAgICAgIC50by5oYXZlLmFueS5kZWVwLmtleXMoa2V5cyk7XG4gIH1cblxuIC8qKlxuICAgKiAjIyMgLmhhc0FsbERlZXBLZXlzKG9iamVjdCwgW2tleXNdLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBoYXMgYWxsIGFuZCBvbmx5IGFsbCBvZiB0aGUgYGtleXNgIHByb3ZpZGVkLlxuICAgKiBTaW5jZSBTZXRzIGFuZCBNYXBzIGNhbiBoYXZlIG9iamVjdHMgYXMga2V5cyB5b3UgY2FuIHVzZSB0aGlzIGFzc2VydGlvbiB0byBwZXJmb3JtXG4gICAqIGEgZGVlcCBjb21wYXJpc29uLlxuICAgKiBZb3UgY2FuIGFsc28gcHJvdmlkZSBhIHNpbmdsZSBvYmplY3QgaW5zdGVhZCBvZiBhIGBrZXlzYCBhcnJheSBhbmQgaXRzIGtleXNcbiAgICogd2lsbCBiZSB1c2VkIGFzIHRoZSBleHBlY3RlZCBzZXQgb2Yga2V5cy5cbiAgICpcbiAgICogICAgIGFzc2VydC5oYXNBbGxEZWVwS2V5cyhuZXcgTWFwKFtbe29uZTogJ29uZSd9LCAndmFsdWVPbmUnXV0pLCB7b25lOiAnb25lJ30pO1xuICAgKiAgICAgYXNzZXJ0Lmhhc0FsbERlZXBLZXlzKG5ldyBNYXAoW1t7b25lOiAnb25lJ30sICd2YWx1ZU9uZSddLCBbe3R3bzogJ3R3byd9LCAndmFsdWVUd28nXV0pLCBbe29uZTogJ29uZSd9LCB7dHdvOiAndHdvJ31dKTtcbiAgICogICAgIGFzc2VydC5oYXNBbGxEZWVwS2V5cyhuZXcgU2V0KFt7b25lOiAnb25lJ31dKSwge29uZTogJ29uZSd9KTtcbiAgICogICAgIGFzc2VydC5oYXNBbGxEZWVwS2V5cyhuZXcgU2V0KFt7b25lOiAnb25lJ30sIHt0d286ICd0d28nfV0pLCBbe29uZTogJ29uZSd9LCB7dHdvOiAndHdvJ31dKTtcbiAgICpcbiAgICogQG5hbWUgaGFzQWxsRGVlcEtleXNcbiAgICogQHBhcmFtIHtNaXhlZH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBrZXlzXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5oYXNBbGxEZWVwS2V5cyA9IGZ1bmN0aW9uIChvYmosIGtleXMsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2csIGFzc2VydC5oYXNBbGxEZWVwS2V5cywgdHJ1ZSlcbiAgICAgIC50by5oYXZlLmFsbC5kZWVwLmtleXMoa2V5cyk7XG4gIH1cblxuIC8qKlxuICAgKiAjIyMgLmNvbnRhaW5zQWxsRGVlcEtleXMob2JqZWN0LCBba2V5c10sIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGNvbnRhaW5zIGFsbCBvZiB0aGUgYGtleXNgIHByb3ZpZGVkLlxuICAgKiBTaW5jZSBTZXRzIGFuZCBNYXBzIGNhbiBoYXZlIG9iamVjdHMgYXMga2V5cyB5b3UgY2FuIHVzZSB0aGlzIGFzc2VydGlvbiB0byBwZXJmb3JtXG4gICAqIGEgZGVlcCBjb21wYXJpc29uLlxuICAgKiBZb3UgY2FuIGFsc28gcHJvdmlkZSBhIHNpbmdsZSBvYmplY3QgaW5zdGVhZCBvZiBhIGBrZXlzYCBhcnJheSBhbmQgaXRzIGtleXNcbiAgICogd2lsbCBiZSB1c2VkIGFzIHRoZSBleHBlY3RlZCBzZXQgb2Yga2V5cy5cbiAgICpcbiAgICogICAgIGFzc2VydC5jb250YWluc0FsbERlZXBLZXlzKG5ldyBNYXAoW1t7b25lOiAnb25lJ30sICd2YWx1ZU9uZSddLCBbMSwgMl1dKSwge29uZTogJ29uZSd9KTtcbiAgICogICAgIGFzc2VydC5jb250YWluc0FsbERlZXBLZXlzKG5ldyBNYXAoW1t7b25lOiAnb25lJ30sICd2YWx1ZU9uZSddLCBbe3R3bzogJ3R3byd9LCAndmFsdWVUd28nXV0pLCBbe29uZTogJ29uZSd9LCB7dHdvOiAndHdvJ31dKTtcbiAgICogICAgIGFzc2VydC5jb250YWluc0FsbERlZXBLZXlzKG5ldyBTZXQoW3tvbmU6ICdvbmUnfSwge3R3bzogJ3R3byd9XSksIHtvbmU6ICdvbmUnfSk7XG4gICAqICAgICBhc3NlcnQuY29udGFpbnNBbGxEZWVwS2V5cyhuZXcgU2V0KFt7b25lOiAnb25lJ30sIHt0d286ICd0d28nfV0pLCBbe29uZTogJ29uZSd9LCB7dHdvOiAndHdvJ31dKTtcbiAgICpcbiAgICogQG5hbWUgY29udGFpbnNBbGxEZWVwS2V5c1xuICAgKiBAcGFyYW0ge01peGVkfSBvYmplY3RcbiAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGtleXNcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmNvbnRhaW5zQWxsRGVlcEtleXMgPSBmdW5jdGlvbiAob2JqLCBrZXlzLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnLCBhc3NlcnQuY29udGFpbnNBbGxEZWVwS2V5cywgdHJ1ZSlcbiAgICAgIC50by5jb250YWluLmFsbC5kZWVwLmtleXMoa2V5cyk7XG4gIH1cblxuIC8qKlxuICAgKiAjIyMgLmRvZXNOb3RIYXZlQW55RGVlcEtleXMob2JqZWN0LCBba2V5c10sIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGhhcyBub25lIG9mIHRoZSBga2V5c2AgcHJvdmlkZWQuXG4gICAqIFNpbmNlIFNldHMgYW5kIE1hcHMgY2FuIGhhdmUgb2JqZWN0cyBhcyBrZXlzIHlvdSBjYW4gdXNlIHRoaXMgYXNzZXJ0aW9uIHRvIHBlcmZvcm1cbiAgICogYSBkZWVwIGNvbXBhcmlzb24uXG4gICAqIFlvdSBjYW4gYWxzbyBwcm92aWRlIGEgc2luZ2xlIG9iamVjdCBpbnN0ZWFkIG9mIGEgYGtleXNgIGFycmF5IGFuZCBpdHMga2V5c1xuICAgKiB3aWxsIGJlIHVzZWQgYXMgdGhlIGV4cGVjdGVkIHNldCBvZiBrZXlzLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmRvZXNOb3RIYXZlQW55RGVlcEtleXMobmV3IE1hcChbW3tvbmU6ICdvbmUnfSwgJ3ZhbHVlT25lJ10sIFsxLCAyXV0pLCB7dGhpc0RvZXNOb3Q6ICdleGlzdCd9KTtcbiAgICogICAgIGFzc2VydC5kb2VzTm90SGF2ZUFueURlZXBLZXlzKG5ldyBNYXAoW1t7b25lOiAnb25lJ30sICd2YWx1ZU9uZSddLCBbe3R3bzogJ3R3byd9LCAndmFsdWVUd28nXV0pLCBbe3R3ZW50eTogJ3R3ZW50eSd9LCB7ZmlmdHk6ICdmaWZ0eSd9XSk7XG4gICAqICAgICBhc3NlcnQuZG9lc05vdEhhdmVBbnlEZWVwS2V5cyhuZXcgU2V0KFt7b25lOiAnb25lJ30sIHt0d286ICd0d28nfV0pLCB7dHdlbnR5OiAndHdlbnR5J30pO1xuICAgKiAgICAgYXNzZXJ0LmRvZXNOb3RIYXZlQW55RGVlcEtleXMobmV3IFNldChbe29uZTogJ29uZSd9LCB7dHdvOiAndHdvJ31dKSwgW3t0d2VudHk6ICd0d2VudHknfSwge2ZpZnR5OiAnZmlmdHknfV0pO1xuICAgKlxuICAgKiBAbmFtZSBkb2VzTm90SGF2ZUFueURlZXBLZXlzXG4gICAqIEBwYXJhbSB7TWl4ZWR9IG9iamVjdFxuICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0ga2V5c1xuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuZG9lc05vdEhhdmVBbnlEZWVwS2V5cyA9IGZ1bmN0aW9uIChvYmosIGtleXMsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2csIGFzc2VydC5kb2VzTm90SGF2ZUFueURlZXBLZXlzLCB0cnVlKVxuICAgICAgLnRvLm5vdC5oYXZlLmFueS5kZWVwLmtleXMoa2V5cyk7XG4gIH1cblxuIC8qKlxuICAgKiAjIyMgLmRvZXNOb3RIYXZlQWxsRGVlcEtleXMob2JqZWN0LCBba2V5c10sIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGRvZXMgbm90IGhhdmUgYXQgbGVhc3Qgb25lIG9mIHRoZSBga2V5c2AgcHJvdmlkZWQuXG4gICAqIFNpbmNlIFNldHMgYW5kIE1hcHMgY2FuIGhhdmUgb2JqZWN0cyBhcyBrZXlzIHlvdSBjYW4gdXNlIHRoaXMgYXNzZXJ0aW9uIHRvIHBlcmZvcm1cbiAgICogYSBkZWVwIGNvbXBhcmlzb24uXG4gICAqIFlvdSBjYW4gYWxzbyBwcm92aWRlIGEgc2luZ2xlIG9iamVjdCBpbnN0ZWFkIG9mIGEgYGtleXNgIGFycmF5IGFuZCBpdHMga2V5c1xuICAgKiB3aWxsIGJlIHVzZWQgYXMgdGhlIGV4cGVjdGVkIHNldCBvZiBrZXlzLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmRvZXNOb3RIYXZlQWxsRGVlcEtleXMobmV3IE1hcChbW3tvbmU6ICdvbmUnfSwgJ3ZhbHVlT25lJ10sIFsxLCAyXV0pLCB7dGhpc0RvZXNOb3Q6ICdleGlzdCd9KTtcbiAgICogICAgIGFzc2VydC5kb2VzTm90SGF2ZUFsbERlZXBLZXlzKG5ldyBNYXAoW1t7b25lOiAnb25lJ30sICd2YWx1ZU9uZSddLCBbe3R3bzogJ3R3byd9LCAndmFsdWVUd28nXV0pLCBbe3R3ZW50eTogJ3R3ZW50eSd9LCB7b25lOiAnb25lJ31dKTtcbiAgICogICAgIGFzc2VydC5kb2VzTm90SGF2ZUFsbERlZXBLZXlzKG5ldyBTZXQoW3tvbmU6ICdvbmUnfSwge3R3bzogJ3R3byd9XSksIHt0d2VudHk6ICd0d2VudHknfSk7XG4gICAqICAgICBhc3NlcnQuZG9lc05vdEhhdmVBbGxEZWVwS2V5cyhuZXcgU2V0KFt7b25lOiAnb25lJ30sIHt0d286ICd0d28nfV0pLCBbe29uZTogJ29uZSd9LCB7ZmlmdHk6ICdmaWZ0eSd9XSk7XG4gICAqXG4gICAqIEBuYW1lIGRvZXNOb3RIYXZlQWxsRGVlcEtleXNcbiAgICogQHBhcmFtIHtNaXhlZH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBrZXlzXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5kb2VzTm90SGF2ZUFsbERlZXBLZXlzID0gZnVuY3Rpb24gKG9iaiwga2V5cywgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZywgYXNzZXJ0LmRvZXNOb3RIYXZlQWxsRGVlcEtleXMsIHRydWUpXG4gICAgICAudG8ubm90LmhhdmUuYWxsLmRlZXAua2V5cyhrZXlzKTtcbiAgfVxuXG4gLyoqXG4gICAqICMjIyAudGhyb3dzKGZuLCBbZXJyb3JMaWtlL3N0cmluZy9yZWdleHBdLCBbc3RyaW5nL3JlZ2V4cF0sIFttZXNzYWdlXSlcbiAgICpcbiAgICogSWYgYGVycm9yTGlrZWAgaXMgYW4gYEVycm9yYCBjb25zdHJ1Y3RvciwgYXNzZXJ0cyB0aGF0IGBmbmAgd2lsbCB0aHJvdyBhbiBlcnJvciB0aGF0IGlzIGFuXG4gICAqIGluc3RhbmNlIG9mIGBlcnJvckxpa2VgLlxuICAgKiBJZiBgZXJyb3JMaWtlYCBpcyBhbiBgRXJyb3JgIGluc3RhbmNlLCBhc3NlcnRzIHRoYXQgdGhlIGVycm9yIHRocm93biBpcyB0aGUgc2FtZVxuICAgKiBpbnN0YW5jZSBhcyBgZXJyb3JMaWtlYC5cbiAgICogSWYgYGVyck1zZ01hdGNoZXJgIGlzIHByb3ZpZGVkLCBpdCBhbHNvIGFzc2VydHMgdGhhdCB0aGUgZXJyb3IgdGhyb3duIHdpbGwgaGF2ZSBhXG4gICAqIG1lc3NhZ2UgbWF0Y2hpbmcgYGVyck1zZ01hdGNoZXJgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LnRocm93cyhmbiwgJ0Vycm9yIHRocm93biBtdXN0IGhhdmUgdGhpcyBtc2cnKTtcbiAgICogICAgIGFzc2VydC50aHJvd3MoZm4sIC9FcnJvciB0aHJvd24gbXVzdCBoYXZlIGEgbXNnIHRoYXQgbWF0Y2hlcyB0aGlzLyk7XG4gICAqICAgICBhc3NlcnQudGhyb3dzKGZuLCBSZWZlcmVuY2VFcnJvcik7XG4gICAqICAgICBhc3NlcnQudGhyb3dzKGZuLCBlcnJvckluc3RhbmNlKTtcbiAgICogICAgIGFzc2VydC50aHJvd3MoZm4sIFJlZmVyZW5jZUVycm9yLCAnRXJyb3IgdGhyb3duIG11c3QgYmUgYSBSZWZlcmVuY2VFcnJvciBhbmQgaGF2ZSB0aGlzIG1zZycpO1xuICAgKiAgICAgYXNzZXJ0LnRocm93cyhmbiwgZXJyb3JJbnN0YW5jZSwgJ0Vycm9yIHRocm93biBtdXN0IGJlIHRoZSBzYW1lIGVycm9ySW5zdGFuY2UgYW5kIGhhdmUgdGhpcyBtc2cnKTtcbiAgICogICAgIGFzc2VydC50aHJvd3MoZm4sIFJlZmVyZW5jZUVycm9yLCAvRXJyb3IgdGhyb3duIG11c3QgYmUgYSBSZWZlcmVuY2VFcnJvciBhbmQgbWF0Y2ggdGhpcy8pO1xuICAgKiAgICAgYXNzZXJ0LnRocm93cyhmbiwgZXJyb3JJbnN0YW5jZSwgL0Vycm9yIHRocm93biBtdXN0IGJlIHRoZSBzYW1lIGVycm9ySW5zdGFuY2UgYW5kIG1hdGNoIHRoaXMvKTtcbiAgICpcbiAgICogQG5hbWUgdGhyb3dzXG4gICAqIEBhbGlhcyB0aHJvd1xuICAgKiBAYWxpYXMgVGhyb3dcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAgICogQHBhcmFtIHtFcnJvckNvbnN0cnVjdG9yfEVycm9yfSBlcnJvckxpa2VcbiAgICogQHBhcmFtIHtSZWdFeHB8U3RyaW5nfSBlcnJNc2dNYXRjaGVyXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4vSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvRXJyb3IjRXJyb3JfdHlwZXNcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LnRocm93cyA9IGZ1bmN0aW9uIChmbiwgZXJyb3JMaWtlLCBlcnJNc2dNYXRjaGVyLCBtc2cpIHtcbiAgICBpZiAoJ3N0cmluZycgPT09IHR5cGVvZiBlcnJvckxpa2UgfHwgZXJyb3JMaWtlIGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICBlcnJNc2dNYXRjaGVyID0gZXJyb3JMaWtlO1xuICAgICAgZXJyb3JMaWtlID0gbnVsbDtcbiAgICB9XG5cbiAgICB2YXIgYXNzZXJ0RXJyID0gbmV3IEFzc2VydGlvbihmbiwgbXNnLCBhc3NlcnQudGhyb3dzLCB0cnVlKVxuICAgICAgLnRvLnRocm93KGVycm9yTGlrZSwgZXJyTXNnTWF0Y2hlcik7XG4gICAgcmV0dXJuIGZsYWcoYXNzZXJ0RXJyLCAnb2JqZWN0Jyk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuZG9lc05vdFRocm93KGZuLCBbZXJyb3JMaWtlL3N0cmluZy9yZWdleHBdLCBbc3RyaW5nL3JlZ2V4cF0sIFttZXNzYWdlXSlcbiAgICpcbiAgICogSWYgYGVycm9yTGlrZWAgaXMgYW4gYEVycm9yYCBjb25zdHJ1Y3RvciwgYXNzZXJ0cyB0aGF0IGBmbmAgd2lsbCBfbm90XyB0aHJvdyBhbiBlcnJvciB0aGF0IGlzIGFuXG4gICAqIGluc3RhbmNlIG9mIGBlcnJvckxpa2VgLlxuICAgKiBJZiBgZXJyb3JMaWtlYCBpcyBhbiBgRXJyb3JgIGluc3RhbmNlLCBhc3NlcnRzIHRoYXQgdGhlIGVycm9yIHRocm93biBpcyBfbm90XyB0aGUgc2FtZVxuICAgKiBpbnN0YW5jZSBhcyBgZXJyb3JMaWtlYC5cbiAgICogSWYgYGVyck1zZ01hdGNoZXJgIGlzIHByb3ZpZGVkLCBpdCBhbHNvIGFzc2VydHMgdGhhdCB0aGUgZXJyb3IgdGhyb3duIHdpbGwgX25vdF8gaGF2ZSBhXG4gICAqIG1lc3NhZ2UgbWF0Y2hpbmcgYGVyck1zZ01hdGNoZXJgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmRvZXNOb3RUaHJvdyhmbiwgJ0FueSBFcnJvciB0aHJvd24gbXVzdCBub3QgaGF2ZSB0aGlzIG1lc3NhZ2UnKTtcbiAgICogICAgIGFzc2VydC5kb2VzTm90VGhyb3coZm4sIC9BbnkgRXJyb3IgdGhyb3duIG11c3Qgbm90IG1hdGNoIHRoaXMvKTtcbiAgICogICAgIGFzc2VydC5kb2VzTm90VGhyb3coZm4sIEVycm9yKTtcbiAgICogICAgIGFzc2VydC5kb2VzTm90VGhyb3coZm4sIGVycm9ySW5zdGFuY2UpO1xuICAgKiAgICAgYXNzZXJ0LmRvZXNOb3RUaHJvdyhmbiwgRXJyb3IsICdFcnJvciBtdXN0IG5vdCBoYXZlIHRoaXMgbWVzc2FnZScpO1xuICAgKiAgICAgYXNzZXJ0LmRvZXNOb3RUaHJvdyhmbiwgZXJyb3JJbnN0YW5jZSwgJ0Vycm9yIG11c3Qgbm90IGhhdmUgdGhpcyBtZXNzYWdlJyk7XG4gICAqICAgICBhc3NlcnQuZG9lc05vdFRocm93KGZuLCBFcnJvciwgL0Vycm9yIG11c3Qgbm90IG1hdGNoIHRoaXMvKTtcbiAgICogICAgIGFzc2VydC5kb2VzTm90VGhyb3coZm4sIGVycm9ySW5zdGFuY2UsIC9FcnJvciBtdXN0IG5vdCBtYXRjaCB0aGlzLyk7XG4gICAqXG4gICAqIEBuYW1lIGRvZXNOb3RUaHJvd1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICAgKiBAcGFyYW0ge0Vycm9yQ29uc3RydWN0b3J9IGVycm9yTGlrZVxuICAgKiBAcGFyYW0ge1JlZ0V4cHxTdHJpbmd9IGVyck1zZ01hdGNoZXJcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9FcnJvciNFcnJvcl90eXBlc1xuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuZG9lc05vdFRocm93ID0gZnVuY3Rpb24gKGZuLCBlcnJvckxpa2UsIGVyck1zZ01hdGNoZXIsIG1zZykge1xuICAgIGlmICgnc3RyaW5nJyA9PT0gdHlwZW9mIGVycm9yTGlrZSB8fCBlcnJvckxpa2UgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgIGVyck1zZ01hdGNoZXIgPSBlcnJvckxpa2U7XG4gICAgICBlcnJvckxpa2UgPSBudWxsO1xuICAgIH1cblxuICAgIG5ldyBBc3NlcnRpb24oZm4sIG1zZywgYXNzZXJ0LmRvZXNOb3RUaHJvdywgdHJ1ZSlcbiAgICAgIC50by5ub3QudGhyb3coZXJyb3JMaWtlLCBlcnJNc2dNYXRjaGVyKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5vcGVyYXRvcih2YWwxLCBvcGVyYXRvciwgdmFsMiwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBDb21wYXJlcyB0d28gdmFsdWVzIHVzaW5nIGBvcGVyYXRvcmAuXG4gICAqXG4gICAqICAgICBhc3NlcnQub3BlcmF0b3IoMSwgJzwnLCAyLCAnZXZlcnl0aGluZyBpcyBvaycpO1xuICAgKiAgICAgYXNzZXJ0Lm9wZXJhdG9yKDEsICc+JywgMiwgJ3RoaXMgd2lsbCBmYWlsJyk7XG4gICAqXG4gICAqIEBuYW1lIG9wZXJhdG9yXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbDFcbiAgICogQHBhcmFtIHtTdHJpbmd9IG9wZXJhdG9yXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbDJcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm9wZXJhdG9yID0gZnVuY3Rpb24gKHZhbCwgb3BlcmF0b3IsIHZhbDIsIG1zZykge1xuICAgIHZhciBvaztcbiAgICBzd2l0Y2gob3BlcmF0b3IpIHtcbiAgICAgIGNhc2UgJz09JzpcbiAgICAgICAgb2sgPSB2YWwgPT0gdmFsMjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICc9PT0nOlxuICAgICAgICBvayA9IHZhbCA9PT0gdmFsMjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICc+JzpcbiAgICAgICAgb2sgPSB2YWwgPiB2YWwyO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJz49JzpcbiAgICAgICAgb2sgPSB2YWwgPj0gdmFsMjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICc8JzpcbiAgICAgICAgb2sgPSB2YWwgPCB2YWwyO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJzw9JzpcbiAgICAgICAgb2sgPSB2YWwgPD0gdmFsMjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICchPSc6XG4gICAgICAgIG9rID0gdmFsICE9IHZhbDI7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnIT09JzpcbiAgICAgICAgb2sgPSB2YWwgIT09IHZhbDI7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgbXNnID0gbXNnID8gbXNnICsgJzogJyA6IG1zZztcbiAgICAgICAgdGhyb3cgbmV3IGNoYWkuQXNzZXJ0aW9uRXJyb3IoXG4gICAgICAgICAgbXNnICsgJ0ludmFsaWQgb3BlcmF0b3IgXCInICsgb3BlcmF0b3IgKyAnXCInLFxuICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICBhc3NlcnQub3BlcmF0b3JcbiAgICAgICAgKTtcbiAgICB9XG4gICAgdmFyIHRlc3QgPSBuZXcgQXNzZXJ0aW9uKG9rLCBtc2csIGFzc2VydC5vcGVyYXRvciwgdHJ1ZSk7XG4gICAgdGVzdC5hc3NlcnQoXG4gICAgICAgIHRydWUgPT09IGZsYWcodGVzdCwgJ29iamVjdCcpXG4gICAgICAsICdleHBlY3RlZCAnICsgdXRpbC5pbnNwZWN0KHZhbCkgKyAnIHRvIGJlICcgKyBvcGVyYXRvciArICcgJyArIHV0aWwuaW5zcGVjdCh2YWwyKVxuICAgICAgLCAnZXhwZWN0ZWQgJyArIHV0aWwuaW5zcGVjdCh2YWwpICsgJyB0byBub3QgYmUgJyArIG9wZXJhdG9yICsgJyAnICsgdXRpbC5pbnNwZWN0KHZhbDIpICk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuY2xvc2VUbyhhY3R1YWwsIGV4cGVjdGVkLCBkZWx0YSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBlcXVhbCBgZXhwZWN0ZWRgLCB0byB3aXRoaW4gYSArLy0gYGRlbHRhYCByYW5nZS5cbiAgICpcbiAgICogICAgIGFzc2VydC5jbG9zZVRvKDEuNSwgMSwgMC41LCAnbnVtYmVycyBhcmUgY2xvc2UnKTtcbiAgICpcbiAgICogQG5hbWUgY2xvc2VUb1xuICAgKiBAcGFyYW0ge051bWJlcn0gYWN0dWFsXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBleHBlY3RlZFxuICAgKiBAcGFyYW0ge051bWJlcn0gZGVsdGFcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmNsb3NlVG8gPSBmdW5jdGlvbiAoYWN0LCBleHAsIGRlbHRhLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKGFjdCwgbXNnLCBhc3NlcnQuY2xvc2VUbywgdHJ1ZSkudG8uYmUuY2xvc2VUbyhleHAsIGRlbHRhKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5hcHByb3hpbWF0ZWx5KGFjdHVhbCwgZXhwZWN0ZWQsIGRlbHRhLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGVxdWFsIGBleHBlY3RlZGAsIHRvIHdpdGhpbiBhICsvLSBgZGVsdGFgIHJhbmdlLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmFwcHJveGltYXRlbHkoMS41LCAxLCAwLjUsICdudW1iZXJzIGFyZSBjbG9zZScpO1xuICAgKlxuICAgKiBAbmFtZSBhcHByb3hpbWF0ZWx5XG4gICAqIEBwYXJhbSB7TnVtYmVyfSBhY3R1YWxcbiAgICogQHBhcmFtIHtOdW1iZXJ9IGV4cGVjdGVkXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBkZWx0YVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuYXBwcm94aW1hdGVseSA9IGZ1bmN0aW9uIChhY3QsIGV4cCwgZGVsdGEsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oYWN0LCBtc2csIGFzc2VydC5hcHByb3hpbWF0ZWx5LCB0cnVlKVxuICAgICAgLnRvLmJlLmFwcHJveGltYXRlbHkoZXhwLCBkZWx0YSk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuc2FtZU1lbWJlcnMoc2V0MSwgc2V0MiwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHNldDFgIGFuZCBgc2V0MmAgaGF2ZSB0aGUgc2FtZSBtZW1iZXJzIGluIGFueSBvcmRlci4gVXNlcyBhXG4gICAqIHN0cmljdCBlcXVhbGl0eSBjaGVjayAoPT09KS5cbiAgICpcbiAgICogICAgIGFzc2VydC5zYW1lTWVtYmVycyhbIDEsIDIsIDMgXSwgWyAyLCAxLCAzIF0sICdzYW1lIG1lbWJlcnMnKTtcbiAgICpcbiAgICogQG5hbWUgc2FtZU1lbWJlcnNcbiAgICogQHBhcmFtIHtBcnJheX0gc2V0MVxuICAgKiBAcGFyYW0ge0FycmF5fSBzZXQyXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5zYW1lTWVtYmVycyA9IGZ1bmN0aW9uIChzZXQxLCBzZXQyLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHNldDEsIG1zZywgYXNzZXJ0LnNhbWVNZW1iZXJzLCB0cnVlKVxuICAgICAgLnRvLmhhdmUuc2FtZS5tZW1iZXJzKHNldDIpO1xuICB9XG5cbiAgLyoqXG4gICAqICMjIyAubm90U2FtZU1lbWJlcnMoc2V0MSwgc2V0MiwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHNldDFgIGFuZCBgc2V0MmAgZG9uJ3QgaGF2ZSB0aGUgc2FtZSBtZW1iZXJzIGluIGFueSBvcmRlci5cbiAgICogVXNlcyBhIHN0cmljdCBlcXVhbGl0eSBjaGVjayAoPT09KS5cbiAgICpcbiAgICogICAgIGFzc2VydC5ub3RTYW1lTWVtYmVycyhbIDEsIDIsIDMgXSwgWyA1LCAxLCAzIF0sICdub3Qgc2FtZSBtZW1iZXJzJyk7XG4gICAqXG4gICAqIEBuYW1lIG5vdFNhbWVNZW1iZXJzXG4gICAqIEBwYXJhbSB7QXJyYXl9IHNldDFcbiAgICogQHBhcmFtIHtBcnJheX0gc2V0MlxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubm90U2FtZU1lbWJlcnMgPSBmdW5jdGlvbiAoc2V0MSwgc2V0MiwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihzZXQxLCBtc2csIGFzc2VydC5ub3RTYW1lTWVtYmVycywgdHJ1ZSlcbiAgICAgIC50by5ub3QuaGF2ZS5zYW1lLm1lbWJlcnMoc2V0Mik7XG4gIH1cblxuICAvKipcbiAgICogIyMjIC5zYW1lRGVlcE1lbWJlcnMoc2V0MSwgc2V0MiwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHNldDFgIGFuZCBgc2V0MmAgaGF2ZSB0aGUgc2FtZSBtZW1iZXJzIGluIGFueSBvcmRlci4gVXNlcyBhXG4gICAqIGRlZXAgZXF1YWxpdHkgY2hlY2suXG4gICAqXG4gICAqICAgICBhc3NlcnQuc2FtZURlZXBNZW1iZXJzKFsgeyBhOiAxIH0sIHsgYjogMiB9LCB7IGM6IDMgfSBdLCBbeyBiOiAyIH0sIHsgYTogMSB9LCB7IGM6IDMgfV0sICdzYW1lIGRlZXAgbWVtYmVycycpO1xuICAgKlxuICAgKiBAbmFtZSBzYW1lRGVlcE1lbWJlcnNcbiAgICogQHBhcmFtIHtBcnJheX0gc2V0MVxuICAgKiBAcGFyYW0ge0FycmF5fSBzZXQyXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5zYW1lRGVlcE1lbWJlcnMgPSBmdW5jdGlvbiAoc2V0MSwgc2V0MiwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihzZXQxLCBtc2csIGFzc2VydC5zYW1lRGVlcE1lbWJlcnMsIHRydWUpXG4gICAgICAudG8uaGF2ZS5zYW1lLmRlZXAubWVtYmVycyhzZXQyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiAjIyMgLm5vdFNhbWVEZWVwTWVtYmVycyhzZXQxLCBzZXQyLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgc2V0MWAgYW5kIGBzZXQyYCBkb24ndCBoYXZlIHRoZSBzYW1lIG1lbWJlcnMgaW4gYW55IG9yZGVyLlxuICAgKiBVc2VzIGEgZGVlcCBlcXVhbGl0eSBjaGVjay5cbiAgICpcbiAgICogICAgIGFzc2VydC5ub3RTYW1lRGVlcE1lbWJlcnMoWyB7IGE6IDEgfSwgeyBiOiAyIH0sIHsgYzogMyB9IF0sIFt7IGI6IDIgfSwgeyBhOiAxIH0sIHsgZjogNSB9XSwgJ25vdCBzYW1lIGRlZXAgbWVtYmVycycpO1xuICAgKlxuICAgKiBAbmFtZSBub3RTYW1lRGVlcE1lbWJlcnNcbiAgICogQHBhcmFtIHtBcnJheX0gc2V0MVxuICAgKiBAcGFyYW0ge0FycmF5fSBzZXQyXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5ub3RTYW1lRGVlcE1lbWJlcnMgPSBmdW5jdGlvbiAoc2V0MSwgc2V0MiwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihzZXQxLCBtc2csIGFzc2VydC5ub3RTYW1lRGVlcE1lbWJlcnMsIHRydWUpXG4gICAgICAudG8ubm90LmhhdmUuc2FtZS5kZWVwLm1lbWJlcnMoc2V0Mik7XG4gIH1cblxuICAvKipcbiAgICogIyMjIC5zYW1lT3JkZXJlZE1lbWJlcnMoc2V0MSwgc2V0MiwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHNldDFgIGFuZCBgc2V0MmAgaGF2ZSB0aGUgc2FtZSBtZW1iZXJzIGluIHRoZSBzYW1lIG9yZGVyLlxuICAgKiBVc2VzIGEgc3RyaWN0IGVxdWFsaXR5IGNoZWNrICg9PT0pLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LnNhbWVPcmRlcmVkTWVtYmVycyhbIDEsIDIsIDMgXSwgWyAxLCAyLCAzIF0sICdzYW1lIG9yZGVyZWQgbWVtYmVycycpO1xuICAgKlxuICAgKiBAbmFtZSBzYW1lT3JkZXJlZE1lbWJlcnNcbiAgICogQHBhcmFtIHtBcnJheX0gc2V0MVxuICAgKiBAcGFyYW0ge0FycmF5fSBzZXQyXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5zYW1lT3JkZXJlZE1lbWJlcnMgPSBmdW5jdGlvbiAoc2V0MSwgc2V0MiwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihzZXQxLCBtc2csIGFzc2VydC5zYW1lT3JkZXJlZE1lbWJlcnMsIHRydWUpXG4gICAgICAudG8uaGF2ZS5zYW1lLm9yZGVyZWQubWVtYmVycyhzZXQyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiAjIyMgLm5vdFNhbWVPcmRlcmVkTWVtYmVycyhzZXQxLCBzZXQyLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgc2V0MWAgYW5kIGBzZXQyYCBkb24ndCBoYXZlIHRoZSBzYW1lIG1lbWJlcnMgaW4gdGhlIHNhbWVcbiAgICogb3JkZXIuIFVzZXMgYSBzdHJpY3QgZXF1YWxpdHkgY2hlY2sgKD09PSkuXG4gICAqXG4gICAqICAgICBhc3NlcnQubm90U2FtZU9yZGVyZWRNZW1iZXJzKFsgMSwgMiwgMyBdLCBbIDIsIDEsIDMgXSwgJ25vdCBzYW1lIG9yZGVyZWQgbWVtYmVycycpO1xuICAgKlxuICAgKiBAbmFtZSBub3RTYW1lT3JkZXJlZE1lbWJlcnNcbiAgICogQHBhcmFtIHtBcnJheX0gc2V0MVxuICAgKiBAcGFyYW0ge0FycmF5fSBzZXQyXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5ub3RTYW1lT3JkZXJlZE1lbWJlcnMgPSBmdW5jdGlvbiAoc2V0MSwgc2V0MiwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihzZXQxLCBtc2csIGFzc2VydC5ub3RTYW1lT3JkZXJlZE1lbWJlcnMsIHRydWUpXG4gICAgICAudG8ubm90LmhhdmUuc2FtZS5vcmRlcmVkLm1lbWJlcnMoc2V0Mik7XG4gIH1cblxuICAvKipcbiAgICogIyMjIC5zYW1lRGVlcE9yZGVyZWRNZW1iZXJzKHNldDEsIHNldDIsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBzZXQxYCBhbmQgYHNldDJgIGhhdmUgdGhlIHNhbWUgbWVtYmVycyBpbiB0aGUgc2FtZSBvcmRlci5cbiAgICogVXNlcyBhIGRlZXAgZXF1YWxpdHkgY2hlY2suXG4gICAqXG4gICAqICAgICBhc3NlcnQuc2FtZURlZXBPcmRlcmVkTWVtYmVycyhbIHsgYTogMSB9LCB7IGI6IDIgfSwgeyBjOiAzIH0gXSwgWyB7IGE6IDEgfSwgeyBiOiAyIH0sIHsgYzogMyB9IF0sICdzYW1lIGRlZXAgb3JkZXJlZCBtZW1iZXJzJyk7XG4gICAqXG4gICAqIEBuYW1lIHNhbWVEZWVwT3JkZXJlZE1lbWJlcnNcbiAgICogQHBhcmFtIHtBcnJheX0gc2V0MVxuICAgKiBAcGFyYW0ge0FycmF5fSBzZXQyXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5zYW1lRGVlcE9yZGVyZWRNZW1iZXJzID0gZnVuY3Rpb24gKHNldDEsIHNldDIsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oc2V0MSwgbXNnLCBhc3NlcnQuc2FtZURlZXBPcmRlcmVkTWVtYmVycywgdHJ1ZSlcbiAgICAgIC50by5oYXZlLnNhbWUuZGVlcC5vcmRlcmVkLm1lbWJlcnMoc2V0Mik7XG4gIH1cblxuICAvKipcbiAgICogIyMjIC5ub3RTYW1lRGVlcE9yZGVyZWRNZW1iZXJzKHNldDEsIHNldDIsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBzZXQxYCBhbmQgYHNldDJgIGRvbid0IGhhdmUgdGhlIHNhbWUgbWVtYmVycyBpbiB0aGUgc2FtZVxuICAgKiBvcmRlci4gVXNlcyBhIGRlZXAgZXF1YWxpdHkgY2hlY2suXG4gICAqXG4gICAqICAgICBhc3NlcnQubm90U2FtZURlZXBPcmRlcmVkTWVtYmVycyhbIHsgYTogMSB9LCB7IGI6IDIgfSwgeyBjOiAzIH0gXSwgWyB7IGE6IDEgfSwgeyBiOiAyIH0sIHsgejogNSB9IF0sICdub3Qgc2FtZSBkZWVwIG9yZGVyZWQgbWVtYmVycycpO1xuICAgKiAgICAgYXNzZXJ0Lm5vdFNhbWVEZWVwT3JkZXJlZE1lbWJlcnMoWyB7IGE6IDEgfSwgeyBiOiAyIH0sIHsgYzogMyB9IF0sIFsgeyBiOiAyIH0sIHsgYTogMSB9LCB7IGM6IDMgfSBdLCAnbm90IHNhbWUgZGVlcCBvcmRlcmVkIG1lbWJlcnMnKTtcbiAgICpcbiAgICogQG5hbWUgbm90U2FtZURlZXBPcmRlcmVkTWVtYmVyc1xuICAgKiBAcGFyYW0ge0FycmF5fSBzZXQxXG4gICAqIEBwYXJhbSB7QXJyYXl9IHNldDJcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm5vdFNhbWVEZWVwT3JkZXJlZE1lbWJlcnMgPSBmdW5jdGlvbiAoc2V0MSwgc2V0MiwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihzZXQxLCBtc2csIGFzc2VydC5ub3RTYW1lRGVlcE9yZGVyZWRNZW1iZXJzLCB0cnVlKVxuICAgICAgLnRvLm5vdC5oYXZlLnNhbWUuZGVlcC5vcmRlcmVkLm1lbWJlcnMoc2V0Mik7XG4gIH1cblxuICAvKipcbiAgICogIyMjIC5pbmNsdWRlTWVtYmVycyhzdXBlcnNldCwgc3Vic2V0LCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgc3Vic2V0YCBpcyBpbmNsdWRlZCBpbiBgc3VwZXJzZXRgIGluIGFueSBvcmRlci4gVXNlcyBhXG4gICAqIHN0cmljdCBlcXVhbGl0eSBjaGVjayAoPT09KS4gRHVwbGljYXRlcyBhcmUgaWdub3JlZC5cbiAgICpcbiAgICogICAgIGFzc2VydC5pbmNsdWRlTWVtYmVycyhbIDEsIDIsIDMgXSwgWyAyLCAxLCAyIF0sICdpbmNsdWRlIG1lbWJlcnMnKTtcbiAgICpcbiAgICogQG5hbWUgaW5jbHVkZU1lbWJlcnNcbiAgICogQHBhcmFtIHtBcnJheX0gc3VwZXJzZXRcbiAgICogQHBhcmFtIHtBcnJheX0gc3Vic2V0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pbmNsdWRlTWVtYmVycyA9IGZ1bmN0aW9uIChzdXBlcnNldCwgc3Vic2V0LCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHN1cGVyc2V0LCBtc2csIGFzc2VydC5pbmNsdWRlTWVtYmVycywgdHJ1ZSlcbiAgICAgIC50by5pbmNsdWRlLm1lbWJlcnMoc3Vic2V0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiAjIyMgLm5vdEluY2x1ZGVNZW1iZXJzKHN1cGVyc2V0LCBzdWJzZXQsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBzdWJzZXRgIGlzbid0IGluY2x1ZGVkIGluIGBzdXBlcnNldGAgaW4gYW55IG9yZGVyLiBVc2VzIGFcbiAgICogc3RyaWN0IGVxdWFsaXR5IGNoZWNrICg9PT0pLiBEdXBsaWNhdGVzIGFyZSBpZ25vcmVkLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm5vdEluY2x1ZGVNZW1iZXJzKFsgMSwgMiwgMyBdLCBbIDUsIDEgXSwgJ25vdCBpbmNsdWRlIG1lbWJlcnMnKTtcbiAgICpcbiAgICogQG5hbWUgbm90SW5jbHVkZU1lbWJlcnNcbiAgICogQHBhcmFtIHtBcnJheX0gc3VwZXJzZXRcbiAgICogQHBhcmFtIHtBcnJheX0gc3Vic2V0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5ub3RJbmNsdWRlTWVtYmVycyA9IGZ1bmN0aW9uIChzdXBlcnNldCwgc3Vic2V0LCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHN1cGVyc2V0LCBtc2csIGFzc2VydC5ub3RJbmNsdWRlTWVtYmVycywgdHJ1ZSlcbiAgICAgIC50by5ub3QuaW5jbHVkZS5tZW1iZXJzKHN1YnNldCk7XG4gIH1cblxuICAvKipcbiAgICogIyMjIC5pbmNsdWRlRGVlcE1lbWJlcnMoc3VwZXJzZXQsIHN1YnNldCwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHN1YnNldGAgaXMgaW5jbHVkZWQgaW4gYHN1cGVyc2V0YCBpbiBhbnkgb3JkZXIuIFVzZXMgYSBkZWVwXG4gICAqIGVxdWFsaXR5IGNoZWNrLiBEdXBsaWNhdGVzIGFyZSBpZ25vcmVkLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmluY2x1ZGVEZWVwTWVtYmVycyhbIHsgYTogMSB9LCB7IGI6IDIgfSwgeyBjOiAzIH0gXSwgWyB7IGI6IDIgfSwgeyBhOiAxIH0sIHsgYjogMiB9IF0sICdpbmNsdWRlIGRlZXAgbWVtYmVycycpO1xuICAgKlxuICAgKiBAbmFtZSBpbmNsdWRlRGVlcE1lbWJlcnNcbiAgICogQHBhcmFtIHtBcnJheX0gc3VwZXJzZXRcbiAgICogQHBhcmFtIHtBcnJheX0gc3Vic2V0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pbmNsdWRlRGVlcE1lbWJlcnMgPSBmdW5jdGlvbiAoc3VwZXJzZXQsIHN1YnNldCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihzdXBlcnNldCwgbXNnLCBhc3NlcnQuaW5jbHVkZURlZXBNZW1iZXJzLCB0cnVlKVxuICAgICAgLnRvLmluY2x1ZGUuZGVlcC5tZW1iZXJzKHN1YnNldCk7XG4gIH1cblxuICAvKipcbiAgICogIyMjIC5ub3RJbmNsdWRlRGVlcE1lbWJlcnMoc3VwZXJzZXQsIHN1YnNldCwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHN1YnNldGAgaXNuJ3QgaW5jbHVkZWQgaW4gYHN1cGVyc2V0YCBpbiBhbnkgb3JkZXIuIFVzZXMgYVxuICAgKiBkZWVwIGVxdWFsaXR5IGNoZWNrLiBEdXBsaWNhdGVzIGFyZSBpZ25vcmVkLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm5vdEluY2x1ZGVEZWVwTWVtYmVycyhbIHsgYTogMSB9LCB7IGI6IDIgfSwgeyBjOiAzIH0gXSwgWyB7IGI6IDIgfSwgeyBmOiA1IH0gXSwgJ25vdCBpbmNsdWRlIGRlZXAgbWVtYmVycycpO1xuICAgKlxuICAgKiBAbmFtZSBub3RJbmNsdWRlRGVlcE1lbWJlcnNcbiAgICogQHBhcmFtIHtBcnJheX0gc3VwZXJzZXRcbiAgICogQHBhcmFtIHtBcnJheX0gc3Vic2V0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5ub3RJbmNsdWRlRGVlcE1lbWJlcnMgPSBmdW5jdGlvbiAoc3VwZXJzZXQsIHN1YnNldCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihzdXBlcnNldCwgbXNnLCBhc3NlcnQubm90SW5jbHVkZURlZXBNZW1iZXJzLCB0cnVlKVxuICAgICAgLnRvLm5vdC5pbmNsdWRlLmRlZXAubWVtYmVycyhzdWJzZXQpO1xuICB9XG5cbiAgLyoqXG4gICAqICMjIyAuaW5jbHVkZU9yZGVyZWRNZW1iZXJzKHN1cGVyc2V0LCBzdWJzZXQsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBzdWJzZXRgIGlzIGluY2x1ZGVkIGluIGBzdXBlcnNldGAgaW4gdGhlIHNhbWUgb3JkZXJcbiAgICogYmVnaW5uaW5nIHdpdGggdGhlIGZpcnN0IGVsZW1lbnQgaW4gYHN1cGVyc2V0YC4gVXNlcyBhIHN0cmljdCBlcXVhbGl0eVxuICAgKiBjaGVjayAoPT09KS5cbiAgICpcbiAgICogICAgIGFzc2VydC5pbmNsdWRlT3JkZXJlZE1lbWJlcnMoWyAxLCAyLCAzIF0sIFsgMSwgMiBdLCAnaW5jbHVkZSBvcmRlcmVkIG1lbWJlcnMnKTtcbiAgICpcbiAgICogQG5hbWUgaW5jbHVkZU9yZGVyZWRNZW1iZXJzXG4gICAqIEBwYXJhbSB7QXJyYXl9IHN1cGVyc2V0XG4gICAqIEBwYXJhbSB7QXJyYXl9IHN1YnNldFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaW5jbHVkZU9yZGVyZWRNZW1iZXJzID0gZnVuY3Rpb24gKHN1cGVyc2V0LCBzdWJzZXQsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oc3VwZXJzZXQsIG1zZywgYXNzZXJ0LmluY2x1ZGVPcmRlcmVkTWVtYmVycywgdHJ1ZSlcbiAgICAgIC50by5pbmNsdWRlLm9yZGVyZWQubWVtYmVycyhzdWJzZXQpO1xuICB9XG5cbiAgLyoqXG4gICAqICMjIyAubm90SW5jbHVkZU9yZGVyZWRNZW1iZXJzKHN1cGVyc2V0LCBzdWJzZXQsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBzdWJzZXRgIGlzbid0IGluY2x1ZGVkIGluIGBzdXBlcnNldGAgaW4gdGhlIHNhbWUgb3JkZXJcbiAgICogYmVnaW5uaW5nIHdpdGggdGhlIGZpcnN0IGVsZW1lbnQgaW4gYHN1cGVyc2V0YC4gVXNlcyBhIHN0cmljdCBlcXVhbGl0eVxuICAgKiBjaGVjayAoPT09KS5cbiAgICpcbiAgICogICAgIGFzc2VydC5ub3RJbmNsdWRlT3JkZXJlZE1lbWJlcnMoWyAxLCAyLCAzIF0sIFsgMiwgMSBdLCAnbm90IGluY2x1ZGUgb3JkZXJlZCBtZW1iZXJzJyk7XG4gICAqICAgICBhc3NlcnQubm90SW5jbHVkZU9yZGVyZWRNZW1iZXJzKFsgMSwgMiwgMyBdLCBbIDIsIDMgXSwgJ25vdCBpbmNsdWRlIG9yZGVyZWQgbWVtYmVycycpO1xuICAgKlxuICAgKiBAbmFtZSBub3RJbmNsdWRlT3JkZXJlZE1lbWJlcnNcbiAgICogQHBhcmFtIHtBcnJheX0gc3VwZXJzZXRcbiAgICogQHBhcmFtIHtBcnJheX0gc3Vic2V0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5ub3RJbmNsdWRlT3JkZXJlZE1lbWJlcnMgPSBmdW5jdGlvbiAoc3VwZXJzZXQsIHN1YnNldCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihzdXBlcnNldCwgbXNnLCBhc3NlcnQubm90SW5jbHVkZU9yZGVyZWRNZW1iZXJzLCB0cnVlKVxuICAgICAgLnRvLm5vdC5pbmNsdWRlLm9yZGVyZWQubWVtYmVycyhzdWJzZXQpO1xuICB9XG5cbiAgLyoqXG4gICAqICMjIyAuaW5jbHVkZURlZXBPcmRlcmVkTWVtYmVycyhzdXBlcnNldCwgc3Vic2V0LCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgc3Vic2V0YCBpcyBpbmNsdWRlZCBpbiBgc3VwZXJzZXRgIGluIHRoZSBzYW1lIG9yZGVyXG4gICAqIGJlZ2lubmluZyB3aXRoIHRoZSBmaXJzdCBlbGVtZW50IGluIGBzdXBlcnNldGAuIFVzZXMgYSBkZWVwIGVxdWFsaXR5XG4gICAqIGNoZWNrLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmluY2x1ZGVEZWVwT3JkZXJlZE1lbWJlcnMoWyB7IGE6IDEgfSwgeyBiOiAyIH0sIHsgYzogMyB9IF0sIFsgeyBhOiAxIH0sIHsgYjogMiB9IF0sICdpbmNsdWRlIGRlZXAgb3JkZXJlZCBtZW1iZXJzJyk7XG4gICAqXG4gICAqIEBuYW1lIGluY2x1ZGVEZWVwT3JkZXJlZE1lbWJlcnNcbiAgICogQHBhcmFtIHtBcnJheX0gc3VwZXJzZXRcbiAgICogQHBhcmFtIHtBcnJheX0gc3Vic2V0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pbmNsdWRlRGVlcE9yZGVyZWRNZW1iZXJzID0gZnVuY3Rpb24gKHN1cGVyc2V0LCBzdWJzZXQsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oc3VwZXJzZXQsIG1zZywgYXNzZXJ0LmluY2x1ZGVEZWVwT3JkZXJlZE1lbWJlcnMsIHRydWUpXG4gICAgICAudG8uaW5jbHVkZS5kZWVwLm9yZGVyZWQubWVtYmVycyhzdWJzZXQpO1xuICB9XG5cbiAgLyoqXG4gICAqICMjIyAubm90SW5jbHVkZURlZXBPcmRlcmVkTWVtYmVycyhzdXBlcnNldCwgc3Vic2V0LCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgc3Vic2V0YCBpc24ndCBpbmNsdWRlZCBpbiBgc3VwZXJzZXRgIGluIHRoZSBzYW1lIG9yZGVyXG4gICAqIGJlZ2lubmluZyB3aXRoIHRoZSBmaXJzdCBlbGVtZW50IGluIGBzdXBlcnNldGAuIFVzZXMgYSBkZWVwIGVxdWFsaXR5XG4gICAqIGNoZWNrLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm5vdEluY2x1ZGVEZWVwT3JkZXJlZE1lbWJlcnMoWyB7IGE6IDEgfSwgeyBiOiAyIH0sIHsgYzogMyB9IF0sIFsgeyBhOiAxIH0sIHsgZjogNSB9IF0sICdub3QgaW5jbHVkZSBkZWVwIG9yZGVyZWQgbWVtYmVycycpO1xuICAgKiAgICAgYXNzZXJ0Lm5vdEluY2x1ZGVEZWVwT3JkZXJlZE1lbWJlcnMoWyB7IGE6IDEgfSwgeyBiOiAyIH0sIHsgYzogMyB9IF0sIFsgeyBiOiAyIH0sIHsgYTogMSB9IF0sICdub3QgaW5jbHVkZSBkZWVwIG9yZGVyZWQgbWVtYmVycycpO1xuICAgKiAgICAgYXNzZXJ0Lm5vdEluY2x1ZGVEZWVwT3JkZXJlZE1lbWJlcnMoWyB7IGE6IDEgfSwgeyBiOiAyIH0sIHsgYzogMyB9IF0sIFsgeyBiOiAyIH0sIHsgYzogMyB9IF0sICdub3QgaW5jbHVkZSBkZWVwIG9yZGVyZWQgbWVtYmVycycpO1xuICAgKlxuICAgKiBAbmFtZSBub3RJbmNsdWRlRGVlcE9yZGVyZWRNZW1iZXJzXG4gICAqIEBwYXJhbSB7QXJyYXl9IHN1cGVyc2V0XG4gICAqIEBwYXJhbSB7QXJyYXl9IHN1YnNldFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubm90SW5jbHVkZURlZXBPcmRlcmVkTWVtYmVycyA9IGZ1bmN0aW9uIChzdXBlcnNldCwgc3Vic2V0LCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHN1cGVyc2V0LCBtc2csIGFzc2VydC5ub3RJbmNsdWRlRGVlcE9yZGVyZWRNZW1iZXJzLCB0cnVlKVxuICAgICAgLnRvLm5vdC5pbmNsdWRlLmRlZXAub3JkZXJlZC5tZW1iZXJzKHN1YnNldCk7XG4gIH1cblxuICAvKipcbiAgICogIyMjIC5vbmVPZihpbkxpc3QsIGxpc3QsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IG5vbi1vYmplY3QsIG5vbi1hcnJheSB2YWx1ZSBgaW5MaXN0YCBhcHBlYXJzIGluIHRoZSBmbGF0IGFycmF5IGBsaXN0YC5cbiAgICpcbiAgICogICAgIGFzc2VydC5vbmVPZigxLCBbIDIsIDEgXSwgJ05vdCBmb3VuZCBpbiBsaXN0Jyk7XG4gICAqXG4gICAqIEBuYW1lIG9uZU9mXG4gICAqIEBwYXJhbSB7Kn0gaW5MaXN0XG4gICAqIEBwYXJhbSB7QXJyYXk8Kj59IGxpc3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm9uZU9mID0gZnVuY3Rpb24gKGluTGlzdCwgbGlzdCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihpbkxpc3QsIG1zZywgYXNzZXJ0Lm9uZU9mLCB0cnVlKS50by5iZS5vbmVPZihsaXN0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiAjIyMgLmNoYW5nZXMoZnVuY3Rpb24sIG9iamVjdCwgcHJvcGVydHksIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGEgZnVuY3Rpb24gY2hhbmdlcyB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eS5cbiAgICpcbiAgICogICAgIHZhciBvYmogPSB7IHZhbDogMTAgfTtcbiAgICogICAgIHZhciBmbiA9IGZ1bmN0aW9uKCkgeyBvYmoudmFsID0gMjIgfTtcbiAgICogICAgIGFzc2VydC5jaGFuZ2VzKGZuLCBvYmosICd2YWwnKTtcbiAgICpcbiAgICogQG5hbWUgY2hhbmdlc1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBtb2RpZmllciBmdW5jdGlvblxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IG9yIGdldHRlciBmdW5jdGlvblxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHkgbmFtZSBfb3B0aW9uYWxfXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmNoYW5nZXMgPSBmdW5jdGlvbiAoZm4sIG9iaiwgcHJvcCwgbXNnKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDMgJiYgdHlwZW9mIG9iaiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgbXNnID0gcHJvcDtcbiAgICAgIHByb3AgPSBudWxsO1xuICAgIH1cblxuICAgIG5ldyBBc3NlcnRpb24oZm4sIG1zZywgYXNzZXJ0LmNoYW5nZXMsIHRydWUpLnRvLmNoYW5nZShvYmosIHByb3ApO1xuICB9XG5cbiAgIC8qKlxuICAgKiAjIyMgLmNoYW5nZXNCeShmdW5jdGlvbiwgb2JqZWN0LCBwcm9wZXJ0eSwgZGVsdGEsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGEgZnVuY3Rpb24gY2hhbmdlcyB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eSBieSBhbiBhbW91bnQgKGRlbHRhKS5cbiAgICpcbiAgICogICAgIHZhciBvYmogPSB7IHZhbDogMTAgfTtcbiAgICogICAgIHZhciBmbiA9IGZ1bmN0aW9uKCkgeyBvYmoudmFsICs9IDIgfTtcbiAgICogICAgIGFzc2VydC5jaGFuZ2VzQnkoZm4sIG9iaiwgJ3ZhbCcsIDIpO1xuICAgKlxuICAgKiBAbmFtZSBjaGFuZ2VzQnlcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gbW9kaWZpZXIgZnVuY3Rpb25cbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBvciBnZXR0ZXIgZnVuY3Rpb25cbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5IG5hbWUgX29wdGlvbmFsX1xuICAgKiBAcGFyYW0ge051bWJlcn0gY2hhbmdlIGFtb3VudCAoZGVsdGEpXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmNoYW5nZXNCeSA9IGZ1bmN0aW9uIChmbiwgb2JqLCBwcm9wLCBkZWx0YSwgbXNnKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDQgJiYgdHlwZW9mIG9iaiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdmFyIHRtcE1zZyA9IGRlbHRhO1xuICAgICAgZGVsdGEgPSBwcm9wO1xuICAgICAgbXNnID0gdG1wTXNnO1xuICAgIH0gZWxzZSBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMykge1xuICAgICAgZGVsdGEgPSBwcm9wO1xuICAgICAgcHJvcCA9IG51bGw7XG4gICAgfVxuXG4gICAgbmV3IEFzc2VydGlvbihmbiwgbXNnLCBhc3NlcnQuY2hhbmdlc0J5LCB0cnVlKVxuICAgICAgLnRvLmNoYW5nZShvYmosIHByb3ApLmJ5KGRlbHRhKTtcbiAgfVxuXG4gICAvKipcbiAgICogIyMjIC5kb2VzTm90Q2hhbmdlKGZ1bmN0aW9uLCBvYmplY3QsIHByb3BlcnR5LCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBhIGZ1bmN0aW9uIGRvZXMgbm90IGNoYW5nZSB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eS5cbiAgICpcbiAgICogICAgIHZhciBvYmogPSB7IHZhbDogMTAgfTtcbiAgICogICAgIHZhciBmbiA9IGZ1bmN0aW9uKCkgeyBjb25zb2xlLmxvZygnZm9vJyk7IH07XG4gICAqICAgICBhc3NlcnQuZG9lc05vdENoYW5nZShmbiwgb2JqLCAndmFsJyk7XG4gICAqXG4gICAqIEBuYW1lIGRvZXNOb3RDaGFuZ2VcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gbW9kaWZpZXIgZnVuY3Rpb25cbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBvciBnZXR0ZXIgZnVuY3Rpb25cbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5IG5hbWUgX29wdGlvbmFsX1xuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5kb2VzTm90Q2hhbmdlID0gZnVuY3Rpb24gKGZuLCBvYmosIHByb3AsIG1zZykge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAzICYmIHR5cGVvZiBvYmogPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIG1zZyA9IHByb3A7XG4gICAgICBwcm9wID0gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IEFzc2VydGlvbihmbiwgbXNnLCBhc3NlcnQuZG9lc05vdENoYW5nZSwgdHJ1ZSlcbiAgICAgIC50by5ub3QuY2hhbmdlKG9iaiwgcHJvcCk7XG4gIH1cblxuICAvKipcbiAgICogIyMjIC5jaGFuZ2VzQnV0Tm90QnkoZnVuY3Rpb24sIG9iamVjdCwgcHJvcGVydHksIGRlbHRhLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBhIGZ1bmN0aW9uIGRvZXMgbm90IGNoYW5nZSB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eSBvciBvZiBhIGZ1bmN0aW9uJ3MgcmV0dXJuIHZhbHVlIGJ5IGFuIGFtb3VudCAoZGVsdGEpXG4gICAqXG4gICAqICAgICB2YXIgb2JqID0geyB2YWw6IDEwIH07XG4gICAqICAgICB2YXIgZm4gPSBmdW5jdGlvbigpIHsgb2JqLnZhbCArPSAxMCB9O1xuICAgKiAgICAgYXNzZXJ0LmNoYW5nZXNCdXROb3RCeShmbiwgb2JqLCAndmFsJywgNSk7XG4gICAqXG4gICAqIEBuYW1lIGNoYW5nZXNCdXROb3RCeVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBtb2RpZmllciBmdW5jdGlvblxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IG9yIGdldHRlciBmdW5jdGlvblxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHkgbmFtZSBfb3B0aW9uYWxfXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBjaGFuZ2UgYW1vdW50IChkZWx0YSlcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuY2hhbmdlc0J1dE5vdEJ5ID0gZnVuY3Rpb24gKGZuLCBvYmosIHByb3AsIGRlbHRhLCBtc2cpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gNCAmJiB0eXBlb2Ygb2JqID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB2YXIgdG1wTXNnID0gZGVsdGE7XG4gICAgICBkZWx0YSA9IHByb3A7XG4gICAgICBtc2cgPSB0bXBNc2c7XG4gICAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAzKSB7XG4gICAgICBkZWx0YSA9IHByb3A7XG4gICAgICBwcm9wID0gbnVsbDtcbiAgICB9XG5cbiAgICBuZXcgQXNzZXJ0aW9uKGZuLCBtc2csIGFzc2VydC5jaGFuZ2VzQnV0Tm90QnksIHRydWUpXG4gICAgICAudG8uY2hhbmdlKG9iaiwgcHJvcCkuYnV0Lm5vdC5ieShkZWx0YSk7XG4gIH1cblxuICAvKipcbiAgICogIyMjIC5pbmNyZWFzZXMoZnVuY3Rpb24sIG9iamVjdCwgcHJvcGVydHksIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGEgZnVuY3Rpb24gaW5jcmVhc2VzIGEgbnVtZXJpYyBvYmplY3QgcHJvcGVydHkuXG4gICAqXG4gICAqICAgICB2YXIgb2JqID0geyB2YWw6IDEwIH07XG4gICAqICAgICB2YXIgZm4gPSBmdW5jdGlvbigpIHsgb2JqLnZhbCA9IDEzIH07XG4gICAqICAgICBhc3NlcnQuaW5jcmVhc2VzKGZuLCBvYmosICd2YWwnKTtcbiAgICpcbiAgICogQG5hbWUgaW5jcmVhc2VzXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IG1vZGlmaWVyIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3Qgb3IgZ2V0dGVyIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eSBuYW1lIF9vcHRpb25hbF9cbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaW5jcmVhc2VzID0gZnVuY3Rpb24gKGZuLCBvYmosIHByb3AsIG1zZykge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAzICYmIHR5cGVvZiBvYmogPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIG1zZyA9IHByb3A7XG4gICAgICBwcm9wID0gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IEFzc2VydGlvbihmbiwgbXNnLCBhc3NlcnQuaW5jcmVhc2VzLCB0cnVlKVxuICAgICAgLnRvLmluY3JlYXNlKG9iaiwgcHJvcCk7XG4gIH1cblxuICAvKipcbiAgICogIyMjIC5pbmNyZWFzZXNCeShmdW5jdGlvbiwgb2JqZWN0LCBwcm9wZXJ0eSwgZGVsdGEsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGEgZnVuY3Rpb24gaW5jcmVhc2VzIGEgbnVtZXJpYyBvYmplY3QgcHJvcGVydHkgb3IgYSBmdW5jdGlvbidzIHJldHVybiB2YWx1ZSBieSBhbiBhbW91bnQgKGRlbHRhKS5cbiAgICpcbiAgICogICAgIHZhciBvYmogPSB7IHZhbDogMTAgfTtcbiAgICogICAgIHZhciBmbiA9IGZ1bmN0aW9uKCkgeyBvYmoudmFsICs9IDEwIH07XG4gICAqICAgICBhc3NlcnQuaW5jcmVhc2VzQnkoZm4sIG9iaiwgJ3ZhbCcsIDEwKTtcbiAgICpcbiAgICogQG5hbWUgaW5jcmVhc2VzQnlcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gbW9kaWZpZXIgZnVuY3Rpb25cbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBvciBnZXR0ZXIgZnVuY3Rpb25cbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5IG5hbWUgX29wdGlvbmFsX1xuICAgKiBAcGFyYW0ge051bWJlcn0gY2hhbmdlIGFtb3VudCAoZGVsdGEpXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmluY3JlYXNlc0J5ID0gZnVuY3Rpb24gKGZuLCBvYmosIHByb3AsIGRlbHRhLCBtc2cpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gNCAmJiB0eXBlb2Ygb2JqID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB2YXIgdG1wTXNnID0gZGVsdGE7XG4gICAgICBkZWx0YSA9IHByb3A7XG4gICAgICBtc2cgPSB0bXBNc2c7XG4gICAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAzKSB7XG4gICAgICBkZWx0YSA9IHByb3A7XG4gICAgICBwcm9wID0gbnVsbDtcbiAgICB9XG5cbiAgICBuZXcgQXNzZXJ0aW9uKGZuLCBtc2csIGFzc2VydC5pbmNyZWFzZXNCeSwgdHJ1ZSlcbiAgICAgIC50by5pbmNyZWFzZShvYmosIHByb3ApLmJ5KGRlbHRhKTtcbiAgfVxuXG4gIC8qKlxuICAgKiAjIyMgLmRvZXNOb3RJbmNyZWFzZShmdW5jdGlvbiwgb2JqZWN0LCBwcm9wZXJ0eSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYSBmdW5jdGlvbiBkb2VzIG5vdCBpbmNyZWFzZSBhIG51bWVyaWMgb2JqZWN0IHByb3BlcnR5LlxuICAgKlxuICAgKiAgICAgdmFyIG9iaiA9IHsgdmFsOiAxMCB9O1xuICAgKiAgICAgdmFyIGZuID0gZnVuY3Rpb24oKSB7IG9iai52YWwgPSA4IH07XG4gICAqICAgICBhc3NlcnQuZG9lc05vdEluY3JlYXNlKGZuLCBvYmosICd2YWwnKTtcbiAgICpcbiAgICogQG5hbWUgZG9lc05vdEluY3JlYXNlXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IG1vZGlmaWVyIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3Qgb3IgZ2V0dGVyIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eSBuYW1lIF9vcHRpb25hbF9cbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuZG9lc05vdEluY3JlYXNlID0gZnVuY3Rpb24gKGZuLCBvYmosIHByb3AsIG1zZykge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAzICYmIHR5cGVvZiBvYmogPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIG1zZyA9IHByb3A7XG4gICAgICBwcm9wID0gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IEFzc2VydGlvbihmbiwgbXNnLCBhc3NlcnQuZG9lc05vdEluY3JlYXNlLCB0cnVlKVxuICAgICAgLnRvLm5vdC5pbmNyZWFzZShvYmosIHByb3ApO1xuICB9XG5cbiAgLyoqXG4gICAqICMjIyAuaW5jcmVhc2VzQnV0Tm90QnkoZnVuY3Rpb24sIG9iamVjdCwgcHJvcGVydHksIGRlbHRhLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBhIGZ1bmN0aW9uIGRvZXMgbm90IGluY3JlYXNlIGEgbnVtZXJpYyBvYmplY3QgcHJvcGVydHkgb3IgZnVuY3Rpb24ncyByZXR1cm4gdmFsdWUgYnkgYW4gYW1vdW50IChkZWx0YSkuXG4gICAqXG4gICAqICAgICB2YXIgb2JqID0geyB2YWw6IDEwIH07XG4gICAqICAgICB2YXIgZm4gPSBmdW5jdGlvbigpIHsgb2JqLnZhbCA9IDE1IH07XG4gICAqICAgICBhc3NlcnQuaW5jcmVhc2VzQnV0Tm90QnkoZm4sIG9iaiwgJ3ZhbCcsIDEwKTtcbiAgICpcbiAgICogQG5hbWUgaW5jcmVhc2VzQnV0Tm90QnlcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gbW9kaWZpZXIgZnVuY3Rpb25cbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBvciBnZXR0ZXIgZnVuY3Rpb25cbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5IG5hbWUgX29wdGlvbmFsX1xuICAgKiBAcGFyYW0ge051bWJlcn0gY2hhbmdlIGFtb3VudCAoZGVsdGEpXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmluY3JlYXNlc0J1dE5vdEJ5ID0gZnVuY3Rpb24gKGZuLCBvYmosIHByb3AsIGRlbHRhLCBtc2cpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gNCAmJiB0eXBlb2Ygb2JqID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB2YXIgdG1wTXNnID0gZGVsdGE7XG4gICAgICBkZWx0YSA9IHByb3A7XG4gICAgICBtc2cgPSB0bXBNc2c7XG4gICAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAzKSB7XG4gICAgICBkZWx0YSA9IHByb3A7XG4gICAgICBwcm9wID0gbnVsbDtcbiAgICB9XG5cbiAgICBuZXcgQXNzZXJ0aW9uKGZuLCBtc2csIGFzc2VydC5pbmNyZWFzZXNCdXROb3RCeSwgdHJ1ZSlcbiAgICAgIC50by5pbmNyZWFzZShvYmosIHByb3ApLmJ1dC5ub3QuYnkoZGVsdGEpO1xuICB9XG5cbiAgLyoqXG4gICAqICMjIyAuZGVjcmVhc2VzKGZ1bmN0aW9uLCBvYmplY3QsIHByb3BlcnR5LCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBhIGZ1bmN0aW9uIGRlY3JlYXNlcyBhIG51bWVyaWMgb2JqZWN0IHByb3BlcnR5LlxuICAgKlxuICAgKiAgICAgdmFyIG9iaiA9IHsgdmFsOiAxMCB9O1xuICAgKiAgICAgdmFyIGZuID0gZnVuY3Rpb24oKSB7IG9iai52YWwgPSA1IH07XG4gICAqICAgICBhc3NlcnQuZGVjcmVhc2VzKGZuLCBvYmosICd2YWwnKTtcbiAgICpcbiAgICogQG5hbWUgZGVjcmVhc2VzXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IG1vZGlmaWVyIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3Qgb3IgZ2V0dGVyIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eSBuYW1lIF9vcHRpb25hbF9cbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuZGVjcmVhc2VzID0gZnVuY3Rpb24gKGZuLCBvYmosIHByb3AsIG1zZykge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAzICYmIHR5cGVvZiBvYmogPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIG1zZyA9IHByb3A7XG4gICAgICBwcm9wID0gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IEFzc2VydGlvbihmbiwgbXNnLCBhc3NlcnQuZGVjcmVhc2VzLCB0cnVlKVxuICAgICAgLnRvLmRlY3JlYXNlKG9iaiwgcHJvcCk7XG4gIH1cblxuICAvKipcbiAgICogIyMjIC5kZWNyZWFzZXNCeShmdW5jdGlvbiwgb2JqZWN0LCBwcm9wZXJ0eSwgZGVsdGEsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGEgZnVuY3Rpb24gZGVjcmVhc2VzIGEgbnVtZXJpYyBvYmplY3QgcHJvcGVydHkgb3IgYSBmdW5jdGlvbidzIHJldHVybiB2YWx1ZSBieSBhbiBhbW91bnQgKGRlbHRhKVxuICAgKlxuICAgKiAgICAgdmFyIG9iaiA9IHsgdmFsOiAxMCB9O1xuICAgKiAgICAgdmFyIGZuID0gZnVuY3Rpb24oKSB7IG9iai52YWwgLT0gNSB9O1xuICAgKiAgICAgYXNzZXJ0LmRlY3JlYXNlc0J5KGZuLCBvYmosICd2YWwnLCA1KTtcbiAgICpcbiAgICogQG5hbWUgZGVjcmVhc2VzQnlcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gbW9kaWZpZXIgZnVuY3Rpb25cbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBvciBnZXR0ZXIgZnVuY3Rpb25cbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5IG5hbWUgX29wdGlvbmFsX1xuICAgKiBAcGFyYW0ge051bWJlcn0gY2hhbmdlIGFtb3VudCAoZGVsdGEpXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmRlY3JlYXNlc0J5ID0gZnVuY3Rpb24gKGZuLCBvYmosIHByb3AsIGRlbHRhLCBtc2cpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gNCAmJiB0eXBlb2Ygb2JqID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB2YXIgdG1wTXNnID0gZGVsdGE7XG4gICAgICBkZWx0YSA9IHByb3A7XG4gICAgICBtc2cgPSB0bXBNc2c7XG4gICAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAzKSB7XG4gICAgICBkZWx0YSA9IHByb3A7XG4gICAgICBwcm9wID0gbnVsbDtcbiAgICB9XG5cbiAgICBuZXcgQXNzZXJ0aW9uKGZuLCBtc2csIGFzc2VydC5kZWNyZWFzZXNCeSwgdHJ1ZSlcbiAgICAgIC50by5kZWNyZWFzZShvYmosIHByb3ApLmJ5KGRlbHRhKTtcbiAgfVxuXG4gIC8qKlxuICAgKiAjIyMgLmRvZXNOb3REZWNyZWFzZShmdW5jdGlvbiwgb2JqZWN0LCBwcm9wZXJ0eSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYSBmdW5jdGlvbiBkb2VzIG5vdCBkZWNyZWFzZXMgYSBudW1lcmljIG9iamVjdCBwcm9wZXJ0eS5cbiAgICpcbiAgICogICAgIHZhciBvYmogPSB7IHZhbDogMTAgfTtcbiAgICogICAgIHZhciBmbiA9IGZ1bmN0aW9uKCkgeyBvYmoudmFsID0gMTUgfTtcbiAgICogICAgIGFzc2VydC5kb2VzTm90RGVjcmVhc2UoZm4sIG9iaiwgJ3ZhbCcpO1xuICAgKlxuICAgKiBAbmFtZSBkb2VzTm90RGVjcmVhc2VcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gbW9kaWZpZXIgZnVuY3Rpb25cbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBvciBnZXR0ZXIgZnVuY3Rpb25cbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5IG5hbWUgX29wdGlvbmFsX1xuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5kb2VzTm90RGVjcmVhc2UgPSBmdW5jdGlvbiAoZm4sIG9iaiwgcHJvcCwgbXNnKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDMgJiYgdHlwZW9mIG9iaiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgbXNnID0gcHJvcDtcbiAgICAgIHByb3AgPSBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgQXNzZXJ0aW9uKGZuLCBtc2csIGFzc2VydC5kb2VzTm90RGVjcmVhc2UsIHRydWUpXG4gICAgICAudG8ubm90LmRlY3JlYXNlKG9iaiwgcHJvcCk7XG4gIH1cblxuICAvKipcbiAgICogIyMjIC5kb2VzTm90RGVjcmVhc2VCeShmdW5jdGlvbiwgb2JqZWN0LCBwcm9wZXJ0eSwgZGVsdGEsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGEgZnVuY3Rpb24gZG9lcyBub3QgZGVjcmVhc2VzIGEgbnVtZXJpYyBvYmplY3QgcHJvcGVydHkgb3IgYSBmdW5jdGlvbidzIHJldHVybiB2YWx1ZSBieSBhbiBhbW91bnQgKGRlbHRhKVxuICAgKlxuICAgKiAgICAgdmFyIG9iaiA9IHsgdmFsOiAxMCB9O1xuICAgKiAgICAgdmFyIGZuID0gZnVuY3Rpb24oKSB7IG9iai52YWwgPSA1IH07XG4gICAqICAgICBhc3NlcnQuZG9lc05vdERlY3JlYXNlQnkoZm4sIG9iaiwgJ3ZhbCcsIDEpO1xuICAgKlxuICAgKiBAbmFtZSBkb2VzTm90RGVjcmVhc2VCeVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBtb2RpZmllciBmdW5jdGlvblxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IG9yIGdldHRlciBmdW5jdGlvblxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHkgbmFtZSBfb3B0aW9uYWxfXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBjaGFuZ2UgYW1vdW50IChkZWx0YSlcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuZG9lc05vdERlY3JlYXNlQnkgPSBmdW5jdGlvbiAoZm4sIG9iaiwgcHJvcCwgZGVsdGEsIG1zZykge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSA0ICYmIHR5cGVvZiBvYmogPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHZhciB0bXBNc2cgPSBkZWx0YTtcbiAgICAgIGRlbHRhID0gcHJvcDtcbiAgICAgIG1zZyA9IHRtcE1zZztcbiAgICB9IGVsc2UgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDMpIHtcbiAgICAgIGRlbHRhID0gcHJvcDtcbiAgICAgIHByb3AgPSBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgQXNzZXJ0aW9uKGZuLCBtc2csIGFzc2VydC5kb2VzTm90RGVjcmVhc2VCeSwgdHJ1ZSlcbiAgICAgIC50by5ub3QuZGVjcmVhc2Uob2JqLCBwcm9wKS5ieShkZWx0YSk7XG4gIH1cblxuICAvKipcbiAgICogIyMjIC5kZWNyZWFzZXNCdXROb3RCeShmdW5jdGlvbiwgb2JqZWN0LCBwcm9wZXJ0eSwgZGVsdGEsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGEgZnVuY3Rpb24gZG9lcyBub3QgZGVjcmVhc2VzIGEgbnVtZXJpYyBvYmplY3QgcHJvcGVydHkgb3IgYSBmdW5jdGlvbidzIHJldHVybiB2YWx1ZSBieSBhbiBhbW91bnQgKGRlbHRhKVxuICAgKlxuICAgKiAgICAgdmFyIG9iaiA9IHsgdmFsOiAxMCB9O1xuICAgKiAgICAgdmFyIGZuID0gZnVuY3Rpb24oKSB7IG9iai52YWwgPSA1IH07XG4gICAqICAgICBhc3NlcnQuZGVjcmVhc2VzQnV0Tm90QnkoZm4sIG9iaiwgJ3ZhbCcsIDEpO1xuICAgKlxuICAgKiBAbmFtZSBkZWNyZWFzZXNCdXROb3RCeVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBtb2RpZmllciBmdW5jdGlvblxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IG9yIGdldHRlciBmdW5jdGlvblxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHkgbmFtZSBfb3B0aW9uYWxfXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBjaGFuZ2UgYW1vdW50IChkZWx0YSlcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuZGVjcmVhc2VzQnV0Tm90QnkgPSBmdW5jdGlvbiAoZm4sIG9iaiwgcHJvcCwgZGVsdGEsIG1zZykge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSA0ICYmIHR5cGVvZiBvYmogPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHZhciB0bXBNc2cgPSBkZWx0YTtcbiAgICAgIGRlbHRhID0gcHJvcDtcbiAgICAgIG1zZyA9IHRtcE1zZztcbiAgICB9IGVsc2UgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDMpIHtcbiAgICAgIGRlbHRhID0gcHJvcDtcbiAgICAgIHByb3AgPSBudWxsO1xuICAgIH1cblxuICAgIG5ldyBBc3NlcnRpb24oZm4sIG1zZywgYXNzZXJ0LmRlY3JlYXNlc0J1dE5vdEJ5LCB0cnVlKVxuICAgICAgLnRvLmRlY3JlYXNlKG9iaiwgcHJvcCkuYnV0Lm5vdC5ieShkZWx0YSk7XG4gIH1cblxuICAvKiFcbiAgICogIyMjIC5pZkVycm9yKG9iamVjdClcbiAgICpcbiAgICogQXNzZXJ0cyBpZiB2YWx1ZSBpcyBub3QgYSBmYWxzZSB2YWx1ZSwgYW5kIHRocm93cyBpZiBpdCBpcyBhIHRydWUgdmFsdWUuXG4gICAqIFRoaXMgaXMgYWRkZWQgdG8gYWxsb3cgZm9yIGNoYWkgdG8gYmUgYSBkcm9wLWluIHJlcGxhY2VtZW50IGZvciBOb2RlJ3NcbiAgICogYXNzZXJ0IGNsYXNzLlxuICAgKlxuICAgKiAgICAgdmFyIGVyciA9IG5ldyBFcnJvcignSSBhbSBhIGN1c3RvbSBlcnJvcicpO1xuICAgKiAgICAgYXNzZXJ0LmlmRXJyb3IoZXJyKTsgLy8gUmV0aHJvd3MgZXJyIVxuICAgKlxuICAgKiBAbmFtZSBpZkVycm9yXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlmRXJyb3IgPSBmdW5jdGlvbiAodmFsKSB7XG4gICAgaWYgKHZhbCkge1xuICAgICAgdGhyb3codmFsKTtcbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNFeHRlbnNpYmxlKG9iamVjdClcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGlzIGV4dGVuc2libGUgKGNhbiBoYXZlIG5ldyBwcm9wZXJ0aWVzIGFkZGVkIHRvIGl0KS5cbiAgICpcbiAgICogICAgIGFzc2VydC5pc0V4dGVuc2libGUoe30pO1xuICAgKlxuICAgKiBAbmFtZSBpc0V4dGVuc2libGVcbiAgICogQGFsaWFzIGV4dGVuc2libGVcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc0V4dGVuc2libGUgPSBmdW5jdGlvbiAob2JqLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnLCBhc3NlcnQuaXNFeHRlbnNpYmxlLCB0cnVlKS50by5iZS5leHRlbnNpYmxlO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzTm90RXh0ZW5zaWJsZShvYmplY3QpXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBpcyBfbm90XyBleHRlbnNpYmxlLlxuICAgKlxuICAgKiAgICAgdmFyIG5vbkV4dGVuc2libGVPYmplY3QgPSBPYmplY3QucHJldmVudEV4dGVuc2lvbnMoe30pO1xuICAgKiAgICAgdmFyIHNlYWxlZE9iamVjdCA9IE9iamVjdC5zZWFsKHt9KTtcbiAgICogICAgIHZhciBmcm96ZW5PYmplY3QgPSBPYmplY3QuZnJlZXplKHt9KTtcbiAgICpcbiAgICogICAgIGFzc2VydC5pc05vdEV4dGVuc2libGUobm9uRXh0ZW5zaWJsZU9iamVjdCk7XG4gICAqICAgICBhc3NlcnQuaXNOb3RFeHRlbnNpYmxlKHNlYWxlZE9iamVjdCk7XG4gICAqICAgICBhc3NlcnQuaXNOb3RFeHRlbnNpYmxlKGZyb3plbk9iamVjdCk7XG4gICAqXG4gICAqIEBuYW1lIGlzTm90RXh0ZW5zaWJsZVxuICAgKiBAYWxpYXMgbm90RXh0ZW5zaWJsZVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzTm90RXh0ZW5zaWJsZSA9IGZ1bmN0aW9uIChvYmosIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2csIGFzc2VydC5pc05vdEV4dGVuc2libGUsIHRydWUpLnRvLm5vdC5iZS5leHRlbnNpYmxlO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzU2VhbGVkKG9iamVjdClcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGlzIHNlYWxlZCAoY2Fubm90IGhhdmUgbmV3IHByb3BlcnRpZXMgYWRkZWQgdG8gaXRcbiAgICogYW5kIGl0cyBleGlzdGluZyBwcm9wZXJ0aWVzIGNhbm5vdCBiZSByZW1vdmVkKS5cbiAgICpcbiAgICogICAgIHZhciBzZWFsZWRPYmplY3QgPSBPYmplY3Quc2VhbCh7fSk7XG4gICAqICAgICB2YXIgZnJvemVuT2JqZWN0ID0gT2JqZWN0LnNlYWwoe30pO1xuICAgKlxuICAgKiAgICAgYXNzZXJ0LmlzU2VhbGVkKHNlYWxlZE9iamVjdCk7XG4gICAqICAgICBhc3NlcnQuaXNTZWFsZWQoZnJvemVuT2JqZWN0KTtcbiAgICpcbiAgICogQG5hbWUgaXNTZWFsZWRcbiAgICogQGFsaWFzIHNlYWxlZFxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzU2VhbGVkID0gZnVuY3Rpb24gKG9iaiwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZywgYXNzZXJ0LmlzU2VhbGVkLCB0cnVlKS50by5iZS5zZWFsZWQ7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNOb3RTZWFsZWQob2JqZWN0KVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgaXMgX25vdF8gc2VhbGVkLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmlzTm90U2VhbGVkKHt9KTtcbiAgICpcbiAgICogQG5hbWUgaXNOb3RTZWFsZWRcbiAgICogQGFsaWFzIG5vdFNlYWxlZFxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzTm90U2VhbGVkID0gZnVuY3Rpb24gKG9iaiwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZywgYXNzZXJ0LmlzTm90U2VhbGVkLCB0cnVlKS50by5ub3QuYmUuc2VhbGVkO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzRnJvemVuKG9iamVjdClcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGlzIGZyb3plbiAoY2Fubm90IGhhdmUgbmV3IHByb3BlcnRpZXMgYWRkZWQgdG8gaXRcbiAgICogYW5kIGl0cyBleGlzdGluZyBwcm9wZXJ0aWVzIGNhbm5vdCBiZSBtb2RpZmllZCkuXG4gICAqXG4gICAqICAgICB2YXIgZnJvemVuT2JqZWN0ID0gT2JqZWN0LmZyZWV6ZSh7fSk7XG4gICAqICAgICBhc3NlcnQuZnJvemVuKGZyb3plbk9iamVjdCk7XG4gICAqXG4gICAqIEBuYW1lIGlzRnJvemVuXG4gICAqIEBhbGlhcyBmcm96ZW5cbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc0Zyb3plbiA9IGZ1bmN0aW9uIChvYmosIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2csIGFzc2VydC5pc0Zyb3plbiwgdHJ1ZSkudG8uYmUuZnJvemVuO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzTm90RnJvemVuKG9iamVjdClcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGlzIF9ub3RfIGZyb3plbi5cbiAgICpcbiAgICogICAgIGFzc2VydC5pc05vdEZyb3plbih7fSk7XG4gICAqXG4gICAqIEBuYW1lIGlzTm90RnJvemVuXG4gICAqIEBhbGlhcyBub3RGcm96ZW5cbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc05vdEZyb3plbiA9IGZ1bmN0aW9uIChvYmosIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2csIGFzc2VydC5pc05vdEZyb3plbiwgdHJ1ZSkudG8ubm90LmJlLmZyb3plbjtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc0VtcHR5KHRhcmdldClcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgZG9lcyBub3QgY29udGFpbiBhbnkgdmFsdWVzLlxuICAgKiBGb3IgYXJyYXlzIGFuZCBzdHJpbmdzLCBpdCBjaGVja3MgdGhlIGBsZW5ndGhgIHByb3BlcnR5LlxuICAgKiBGb3IgYE1hcGAgYW5kIGBTZXRgIGluc3RhbmNlcywgaXQgY2hlY2tzIHRoZSBgc2l6ZWAgcHJvcGVydHkuXG4gICAqIEZvciBub24tZnVuY3Rpb24gb2JqZWN0cywgaXQgZ2V0cyB0aGUgY291bnQgb2Ygb3duXG4gICAqIGVudW1lcmFibGUgc3RyaW5nIGtleXMuXG4gICAqXG4gICAqICAgICBhc3NlcnQuaXNFbXB0eShbXSk7XG4gICAqICAgICBhc3NlcnQuaXNFbXB0eSgnJyk7XG4gICAqICAgICBhc3NlcnQuaXNFbXB0eShuZXcgTWFwKTtcbiAgICogICAgIGFzc2VydC5pc0VtcHR5KHt9KTtcbiAgICpcbiAgICogQG5hbWUgaXNFbXB0eVxuICAgKiBAYWxpYXMgZW1wdHlcbiAgICogQHBhcmFtIHtPYmplY3R8QXJyYXl8U3RyaW5nfE1hcHxTZXR9IHRhcmdldFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc0VtcHR5ID0gZnVuY3Rpb24odmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnLCBhc3NlcnQuaXNFbXB0eSwgdHJ1ZSkudG8uYmUuZW1wdHk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNOb3RFbXB0eSh0YXJnZXQpXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGNvbnRhaW5zIHZhbHVlcy5cbiAgICogRm9yIGFycmF5cyBhbmQgc3RyaW5ncywgaXQgY2hlY2tzIHRoZSBgbGVuZ3RoYCBwcm9wZXJ0eS5cbiAgICogRm9yIGBNYXBgIGFuZCBgU2V0YCBpbnN0YW5jZXMsIGl0IGNoZWNrcyB0aGUgYHNpemVgIHByb3BlcnR5LlxuICAgKiBGb3Igbm9uLWZ1bmN0aW9uIG9iamVjdHMsIGl0IGdldHMgdGhlIGNvdW50IG9mIG93blxuICAgKiBlbnVtZXJhYmxlIHN0cmluZyBrZXlzLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmlzTm90RW1wdHkoWzEsIDJdKTtcbiAgICogICAgIGFzc2VydC5pc05vdEVtcHR5KCczNCcpO1xuICAgKiAgICAgYXNzZXJ0LmlzTm90RW1wdHkobmV3IFNldChbNSwgNl0pKTtcbiAgICogICAgIGFzc2VydC5pc05vdEVtcHR5KHsga2V5OiA3IH0pO1xuICAgKlxuICAgKiBAbmFtZSBpc05vdEVtcHR5XG4gICAqIEBhbGlhcyBub3RFbXB0eVxuICAgKiBAcGFyYW0ge09iamVjdHxBcnJheXxTdHJpbmd8TWFwfFNldH0gdGFyZ2V0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzTm90RW1wdHkgPSBmdW5jdGlvbih2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2csIGFzc2VydC5pc05vdEVtcHR5LCB0cnVlKS50by5ub3QuYmUuZW1wdHk7XG4gIH07XG5cbiAgLyohXG4gICAqIEFsaWFzZXMuXG4gICAqL1xuXG4gIChmdW5jdGlvbiBhbGlhcyhuYW1lLCBhcyl7XG4gICAgYXNzZXJ0W2FzXSA9IGFzc2VydFtuYW1lXTtcbiAgICByZXR1cm4gYWxpYXM7XG4gIH0pXG4gICgnaXNPaycsICdvaycpXG4gICgnaXNOb3RPaycsICdub3RPaycpXG4gICgndGhyb3dzJywgJ3Rocm93JylcbiAgKCd0aHJvd3MnLCAnVGhyb3cnKVxuICAoJ2lzRXh0ZW5zaWJsZScsICdleHRlbnNpYmxlJylcbiAgKCdpc05vdEV4dGVuc2libGUnLCAnbm90RXh0ZW5zaWJsZScpXG4gICgnaXNTZWFsZWQnLCAnc2VhbGVkJylcbiAgKCdpc05vdFNlYWxlZCcsICdub3RTZWFsZWQnKVxuICAoJ2lzRnJvemVuJywgJ2Zyb3plbicpXG4gICgnaXNOb3RGcm96ZW4nLCAnbm90RnJvemVuJylcbiAgKCdpc0VtcHR5JywgJ2VtcHR5JylcbiAgKCdpc05vdEVtcHR5JywgJ25vdEVtcHR5Jyk7XG59O1xuIiwgIi8qIVxuICogY2hhaVxuICogQ29weXJpZ2h0KGMpIDIwMTEtMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbnZhciB1c2VkID0gW107XG5cbi8qIVxuICogQ2hhaSB2ZXJzaW9uXG4gKi9cblxuZXhwb3J0cy52ZXJzaW9uID0gJzQuMy4zJztcblxuLyohXG4gKiBBc3NlcnRpb24gRXJyb3JcbiAqL1xuXG5leHBvcnRzLkFzc2VydGlvbkVycm9yID0gcmVxdWlyZSgnYXNzZXJ0aW9uLWVycm9yJyk7XG5cbi8qIVxuICogVXRpbHMgZm9yIHBsdWdpbnMgKG5vdCBleHBvcnRlZClcbiAqL1xuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4vY2hhaS91dGlscycpO1xuXG4vKipcbiAqICMgLnVzZShmdW5jdGlvbilcbiAqXG4gKiBQcm92aWRlcyBhIHdheSB0byBleHRlbmQgdGhlIGludGVybmFscyBvZiBDaGFpLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259XG4gKiBAcmV0dXJucyB7dGhpc30gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMudXNlID0gZnVuY3Rpb24gKGZuKSB7XG4gIGlmICghfnVzZWQuaW5kZXhPZihmbikpIHtcbiAgICBmbihleHBvcnRzLCB1dGlsKTtcbiAgICB1c2VkLnB1c2goZm4pO1xuICB9XG5cbiAgcmV0dXJuIGV4cG9ydHM7XG59O1xuXG4vKiFcbiAqIFV0aWxpdHkgRnVuY3Rpb25zXG4gKi9cblxuZXhwb3J0cy51dGlsID0gdXRpbDtcblxuLyohXG4gKiBDb25maWd1cmF0aW9uXG4gKi9cblxudmFyIGNvbmZpZyA9IHJlcXVpcmUoJy4vY2hhaS9jb25maWcnKTtcbmV4cG9ydHMuY29uZmlnID0gY29uZmlnO1xuXG4vKiFcbiAqIFByaW1hcnkgYEFzc2VydGlvbmAgcHJvdG90eXBlXG4gKi9cblxudmFyIGFzc2VydGlvbiA9IHJlcXVpcmUoJy4vY2hhaS9hc3NlcnRpb24nKTtcbmV4cG9ydHMudXNlKGFzc2VydGlvbik7XG5cbi8qIVxuICogQ29yZSBBc3NlcnRpb25zXG4gKi9cblxudmFyIGNvcmUgPSByZXF1aXJlKCcuL2NoYWkvY29yZS9hc3NlcnRpb25zJyk7XG5leHBvcnRzLnVzZShjb3JlKTtcblxuLyohXG4gKiBFeHBlY3QgaW50ZXJmYWNlXG4gKi9cblxudmFyIGV4cGVjdCA9IHJlcXVpcmUoJy4vY2hhaS9pbnRlcmZhY2UvZXhwZWN0Jyk7XG5leHBvcnRzLnVzZShleHBlY3QpO1xuXG4vKiFcbiAqIFNob3VsZCBpbnRlcmZhY2VcbiAqL1xuXG52YXIgc2hvdWxkID0gcmVxdWlyZSgnLi9jaGFpL2ludGVyZmFjZS9zaG91bGQnKTtcbmV4cG9ydHMudXNlKHNob3VsZCk7XG5cbi8qIVxuICogQXNzZXJ0IGludGVyZmFjZVxuICovXG5cbnZhciBhc3NlcnQgPSByZXF1aXJlKCcuL2NoYWkvaW50ZXJmYWNlL2Fzc2VydCcpO1xuZXhwb3J0cy51c2UoYXNzZXJ0KTtcbiIsICJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vbGliL2NoYWknKTtcbiIsICIvKipcbiAqIENvcHlyaWdodCAyMDIzIHNjaHVrYWkgR21iSFxuICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFHUEwtMy4wXG4gKi9cblxuLyoqXG4gKiBQcm9wZXJ0eS1LZXlzXG4gKiBAYXV0aG9yIHNjaHVrYWkgR21iSFxuICovXG5cbmV4cG9ydCB7IGludGVybmFsU3ltYm9sLCBpbnRlcm5hbFN0YXRlU3ltYm9sLCBpbnN0YW5jZVN5bWJvbCB9O1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAdHlwZSB7c3ltYm9sfVxuICogQG1lbWJlck9mIE1vbnN0ZXJcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjQuMFxuICovXG5jb25zdCBpbnRlcm5hbFN5bWJvbCA9IFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL2ludGVybmFsXCIpO1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAdHlwZSB7c3ltYm9sfVxuICogQG1lbWJlck9mIE1vbnN0ZXJcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjUuMFxuICovXG5jb25zdCBpbnRlcm5hbFN0YXRlU3ltYm9sID0gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvc3RhdGVcIik7XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEB0eXBlIHtzeW1ib2x9XG4gKi9cbmNvbnN0IGluc3RhbmNlU3ltYm9sID0gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvaW5zdGFuY2VcIik7XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5leHBvcnQgeyBpc0l0ZXJhYmxlLCBpc1ByaW1pdGl2ZSwgaXNTeW1ib2wsIGlzQm9vbGVhbiwgaXNTdHJpbmcsIGlzT2JqZWN0LCBpc0luc3RhbmNlLCBpc0FycmF5LCBpc0Z1bmN0aW9uLCBpc0ludGVnZXIgfTtcblxuLyoqXG4gKiBXaXRoIHRoaXMgZnVuY3Rpb24geW91IGNhbiBjaGVjayBpZiBhIHZhbHVlIGlzIGl0ZXJhYmxlLlxuICpcbiAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgaW4gdGhlIGxpYnJhcnkgdG8gaGF2ZSBjb25zaXN0ZW50IG5hbWVzLlxuICpcbiAqIFlvdSBjYW4gY2FsbCB0aGUgbWV0aG9kIHZpYSB0aGUgbW9uc3RlciBuYW1lc3BhY2UgYE1vbnN0ZXIuVHlwZXMuaXNQcmltaXRpdmUoKWAuXG4gKlxuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL3R5cGVzL2lzLTEubWpzXG4gKiBAcGFyYW0geyp9IHZhbHVlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMi4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcbiAqL1xuZnVuY3Rpb24gaXNJdGVyYWJsZSh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKHZhbHVlID09PSBudWxsKSByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuIHR5cGVvZiB2YWx1ZT8uW1N5bWJvbC5pdGVyYXRvcl0gPT09IFwiZnVuY3Rpb25cIjtcbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciB0aGUgdmFsdWUgcGFzc2VkIGlzIGEgcHJpbWl0aXZlIChzdHJpbmcsIG51bWJlciwgYm9vbGVhbiwgTmFOLCB1bmRlZmluZWQsIG51bGwgb3Igc3ltYm9sKVxuICpcbiAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgaW4gdGhlIGxpYnJhcnkgdG8gaGF2ZSBjb25zaXN0ZW50IG5hbWVzLlxuICpcbiAqIEBleHRlcm5hbEV4YW1wbGUgLi4vLi4vZXhhbXBsZS90eXBlcy9pcy0yLm1qc1xuICogQHBhcmFtIHsqfSB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjAuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKi9cbmZ1bmN0aW9uIGlzUHJpbWl0aXZlKHZhbHVlKSB7XG4gICAgdmFyIHR5cGU7XG5cbiAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCB8fCB2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICB0eXBlID0gdHlwZW9mIHZhbHVlO1xuXG4gICAgaWYgKHR5cGUgPT09IFwic3RyaW5nXCIgfHwgdHlwZSA9PT0gXCJudW1iZXJcIiB8fCB0eXBlID09PSBcImJvb2xlYW5cIiB8fCB0eXBlID09PSBcInN5bWJvbFwiKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciB0aGUgdmFsdWUgcGFzc2VkIGlzIGEgc3ltYm9sXG4gKlxuICogVGhpcyBtZXRob2QgaXMgdXNlZCBpbiB0aGUgbGlicmFyeSB0byBoYXZlIGNvbnNpc3RlbnQgbmFtZXMuXG4gKlxuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL3R5cGVzL2lzLTMubWpzXG4gKiBAcGFyYW0geyp9IHZhbHVlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuOS4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcbiAqL1xuZnVuY3Rpb24gaXNTeW1ib2wodmFsdWUpIHtcbiAgICByZXR1cm4gXCJzeW1ib2xcIiA9PT0gdHlwZW9mIHZhbHVlID8gdHJ1ZSA6IGZhbHNlO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIHRoZSB2YWx1ZSBwYXNzZWQgaXMgYSBib29sZWFuLlxuICpcbiAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgaW4gdGhlIGxpYnJhcnkgdG8gaGF2ZSBjb25zaXN0ZW50IG5hbWVzLlxuICpcbiAqIEBleHRlcm5hbEV4YW1wbGUgLi4vLi4vZXhhbXBsZS90eXBlcy9pcy00Lm1qc1xuICogQHBhcmFtIHsqfSB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjAuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKi9cbmZ1bmN0aW9uIGlzQm9vbGVhbih2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSA9PT0gdHJ1ZSB8fCB2YWx1ZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIHRoZSB2YWx1ZSBwYXNzZWQgaXMgYSBzdHJpbmdcbiAqXG4gKiBUaGlzIG1ldGhvZCBpcyB1c2VkIGluIHRoZSBsaWJyYXJ5IHRvIGhhdmUgY29uc2lzdGVudCBuYW1lcy5cbiAqXG4gKiBAZXh0ZXJuYWxFeGFtcGxlIC4uLy4uL2V4YW1wbGUvdHlwZXMvaXMtNS5tanNcbiAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4wLjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UeXBlc1xuICovXG5mdW5jdGlvbiBpc1N0cmluZyh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHR5cGVvZiB2YWx1ZSAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIHRoZSB2YWx1ZSBwYXNzZWQgaXMgYSBvYmplY3RcbiAqXG4gKiBUaGlzIG1ldGhvZCBpcyB1c2VkIGluIHRoZSBsaWJyYXJ5IHRvIGhhdmUgY29uc2lzdGVudCBuYW1lcy5cbiAqXG4gKiBAZXh0ZXJuYWxFeGFtcGxlIC4uLy4uL2V4YW1wbGUvdHlwZXMvaXMtNi5tanNcbiAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4wLjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UeXBlc1xuICovXG5mdW5jdGlvbiBpc09iamVjdCh2YWx1ZSkge1xuICAgIGlmIChpc0FycmF5KHZhbHVlKSkgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChpc1ByaW1pdGl2ZSh2YWx1ZSkpIHJldHVybiBmYWxzZTtcblxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIHRoZSB2YWx1ZSBwYXNzZWQgaXMgYSBvYmplY3QgYW5kIGluc3RhbmNlIG9mIGluc3RhbmNlLlxuICpcbiAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgaW4gdGhlIGxpYnJhcnkgdG8gaGF2ZSBjb25zaXN0ZW50IG5hbWVzLlxuICpcbiAqIEBleHRlcm5hbEV4YW1wbGUgLi4vLi4vZXhhbXBsZS90eXBlcy9pcy03Lm1qc1xuICogQHBhcmFtIHsqfSB2YWx1ZVxuICogQHBhcmFtIHsqfSBpbnN0YW5jZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjUuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKi9cbmZ1bmN0aW9uIGlzSW5zdGFuY2UodmFsdWUsIGluc3RhbmNlKSB7XG4gICAgaWYgKCFpc09iamVjdCh2YWx1ZSkpIHJldHVybiBmYWxzZTtcbiAgICBpZiAoIWlzRnVuY3Rpb24oaW5zdGFuY2UpKSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKCFpbnN0YW5jZS5oYXNPd25Qcm9wZXJ0eShcInByb3RvdHlwZVwiKSkgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIGluc3RhbmNlID8gdHJ1ZSA6IGZhbHNlO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIHRoZSB2YWx1ZSBwYXNzZWQgaXMgYSBhcnJheVxuICpcbiAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgaW4gdGhlIGxpYnJhcnkgdG8gaGF2ZSBjb25zaXN0ZW50IG5hbWVzLlxuICpcbiAqIEBleHRlcm5hbEV4YW1wbGUgLi4vLi4vZXhhbXBsZS90eXBlcy9pcy04Lm1qc1xuICogQHBhcmFtIHsqfSB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjAuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2RlL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0FycmF5L2lzQXJyYXlcbiAqL1xuZnVuY3Rpb24gaXNBcnJheSh2YWx1ZSkge1xuICAgIHJldHVybiBBcnJheS5pc0FycmF5KHZhbHVlKTtcbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciB0aGUgdmFsdWUgcGFzc2VkIGlzIGEgZnVuY3Rpb25cbiAqXG4gKiBUaGlzIG1ldGhvZCBpcyB1c2VkIGluIHRoZSBsaWJyYXJ5IHRvIGhhdmUgY29uc2lzdGVudCBuYW1lcy5cbiAqXG4gKiBAZXh0ZXJuYWxFeGFtcGxlIC4uLy4uL2V4YW1wbGUvdHlwZXMvaXMtOS5tanNcbiAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4wLjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UeXBlc1xuICovXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKHZhbHVlKSB7XG4gICAgaWYgKGlzQXJyYXkodmFsdWUpKSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKGlzUHJpbWl0aXZlKHZhbHVlKSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciB0aGUgdmFsdWUgcGFzc2VkIGlzIGFuIGludGVnZXIuXG4gKlxuICogVGhpcyBtZXRob2QgaXMgdXNlZCBpbiB0aGUgbGlicmFyeSB0byBoYXZlIGNvbnNpc3RlbnQgbmFtZXMuXG4gKlxuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL3R5cGVzL2lzLTEwLm1qc1xuICogQHBhcmFtIHsqfSB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjQuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKi9cbmZ1bmN0aW9uIGlzSW50ZWdlcih2YWx1ZSkge1xuICAgIHJldHVybiBOdW1iZXIuaXNJbnRlZ2VyKHZhbHVlKTtcbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmV4cG9ydCB7IHR5cGVPZiB9O1xuXG4vKipcbiAqIFRoZSBidWlsdC1pbiB0eXBlb2YgbWV0aG9kIGlzIGtub3duIHRvIGhhdmUgc29tZSBoaXN0b3JpY2FsIHdlYWtuZXNzZXMuIFRoaXMgZnVuY3Rpb24gdHJpZXMgdG8gcHJvdmlkZSBhIGJldHRlciBhbmQgbW9yZSBhY2N1cmF0ZSByZXN1bHQuXG4gKlxuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL3R5cGVzL3R5cGVvZi5tanNcbiAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAqIEByZXR1cm4ge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuNy4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgcHJpbWl0aXZlXG4gKi9cbmZ1bmN0aW9uIHR5cGVPZih2YWx1ZSkge1xuICAgIGxldCB0eXBlID0ge30udG9TdHJpbmcuY2FsbCh2YWx1ZSkubWF0Y2goL1xccyhbYS16QS1aXSspLylbMV07XG4gICAgaWYgKFwiT2JqZWN0XCIgPT09IHR5cGUpIHtcbiAgICAgICAgY29uc3QgbmFtZSA9IHZhbHVlLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgIGlmIChuYW1lKSB7XG4gICAgICAgICAgICByZXR1cm4gbmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVzdWx0cyA9IC9eKGNsYXNzfGZ1bmN0aW9uKVxccysoXFx3KykvLmV4ZWModmFsdWUuY29uc3RydWN0b3IudG9TdHJpbmcoKSk7XG4gICAgICAgIHR5cGUgPSByZXN1bHRzICYmIHJlc3VsdHMubGVuZ3RoID4gMiA/IHJlc3VsdHNbMl0gOiBcIlwiO1xuICAgIH1cblxuICAgIHJldHVybiB0eXBlLnRvTG93ZXJDYXNlKCk7XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBpc0FycmF5LCBpc09iamVjdCB9IGZyb20gXCIuLi90eXBlcy9pcy5tanNcIjtcbmltcG9ydCB7IHR5cGVPZiB9IGZyb20gXCIuLi90eXBlcy90eXBlb2YubWpzXCI7XG5cbmV4cG9ydCB7IGV4dGVuZCB9O1xuXG4vKipcbiAqIEV4dGVuZCBjb3BpZXMgYWxsIGVudW1lcmFibGUgb3duIHByb3BlcnRpZXMgZnJvbSBvbmUgb3JcbiAqIG1vcmUgc291cmNlIG9iamVjdHMgdG8gYSB0YXJnZXQgb2JqZWN0LiBJdCByZXR1cm5zIHRoZSBtb2RpZmllZCB0YXJnZXQgb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSB0YXJnZXRcbiAqIEBwYXJhbSB7b2JqZWN0fVxuICogQHJldHVybiB7b2JqZWN0fVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4xMC4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRGF0YVxuICogQHRocm93cyB7RXJyb3J9IHVuc3VwcG9ydGVkIGFyZ3VtZW50XG4gKiBAdGhyb3dzIHtFcnJvcn0gdHlwZSBtaXNtYXRjaFxuICogQHRocm93cyB7RXJyb3J9IHVuc3VwcG9ydGVkIGFyZ3VtZW50XG4gKi9cbmZ1bmN0aW9uIGV4dGVuZCguLi5hcmdzKSB7XG4gICAgbGV0IG87XG4gICAgbGV0IGk7XG5cbiAgICBpZiAodHlwZW9mIGFyZ3MgIT09IFwib2JqZWN0XCIgfHwgYXJnc1swXSA9PT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuc3VwcG9ydGVkIGFyZ3VtZW50ICR7SlNPTi5zdHJpbmdpZnkoYXJnc1swXSl9YCk7XG4gICAgfVxuXG4gICAgZm9yIChpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgbGV0IGEgPSBhcmdzW2ldO1xuXG4gICAgICAgIGlmICghKGlzT2JqZWN0KGEpIHx8IGlzQXJyYXkoYSkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuc3VwcG9ydGVkIGFyZ3VtZW50ICR7SlNPTi5zdHJpbmdpZnkoYSl9YCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBvID0gYTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChsZXQgayBpbiBhKSB7XG4gICAgICAgICAgICBsZXQgdiA9IGE/LltrXTtcblxuICAgICAgICAgICAgaWYgKHYgPT09IG8/LltrXSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoKGlzT2JqZWN0KHYpICYmIHR5cGVPZih2KSA9PT0gXCJvYmplY3RcIikgfHwgaXNBcnJheSh2KSkge1xuICAgICAgICAgICAgICAgIGlmIChvW2tdID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzQXJyYXkodikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9ba10gPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9ba10gPSB7fTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlT2Yob1trXSkgIT09IHR5cGVPZih2KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGB0eXBlIG1pc21hdGNoOiAke0pTT04uc3RyaW5naWZ5KG9ba10pfSgke3R5cGVPZihvW2tdKX0pICE9ICR7SlNPTi5zdHJpbmdpZnkodil9KCR7dHlwZU9mKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICl9KWAsXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgb1trXSA9IGV4dGVuZChvW2tdLCB2KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgb1trXSA9IHY7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbztcbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGluc3RhbmNlU3ltYm9sIH0gZnJvbSBcIi4uL2NvbnN0YW50cy5tanNcIjtcblxuZXhwb3J0IHsgQmFzZSB9O1xuXG4vKipcbiAqIFRoaXMgaXMgdGhlIGJhc2UgY2xhc3MgZnJvbSB3aGljaCB0aGUgbW9zdCBjbGFzc2VzIGFyZSBkZXJpdmVkLlxuICpcbiAqIFRoaXMgY2xhc3MgaGFzIGJlc2lkZXMgYSBgdG9TdHJpbmdgIHdoaWNoIHJldHVybnMgdGhlIGpzb24gcmVwcmVzZW50YXRpb24gb2YgdGhlIG9iamVjdFxuICogYWxzbyBhIGZ1bmN0aW9uYWxpdHkgdG8gY2hlY2sgaWYgYW4gb2JqZWN0IGlzIGFuIGluc3RhbmNlIG9mIGEgY2xhc3MuXG4gKlxuICogVGhlcmVmb3IgdGhlIGNsYXNzIGhhcyBhIHN0YXRpYyBtZXRob2QgYCBbU3ltYm9sLmhhc0luc3RhbmNlXSh0aGF0KWAgd2hpY2ggcmV0dXJucyB0cnVlIGlmIHRoZSBvYmplY3RcbiAqIGlzIGFuIGluc3RhbmNlIG9mIHRoZSBjbGFzcy5cbiAqXG4gKiBAc2VlIFtodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9TeW1ib2wvaGFzSW5zdGFuY2VdKGRldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9TeW1ib2wvaGFzSW5zdGFuY2UpXG4gKlxuICogRGVyaXZlZCBjbGFzc2VzIHNob3VsZCBpbXBsZW1lbnQgYSBzdGF0aWMgZ2V0dGVyIGBpbnN0YW5jZVN5bWJvbGAgd2hpY2ggcmV0dXJucyBhIHVuaXF1ZSBzeW1ib2wuXG4gKlxuICogYGBgamF2YXNjcmlwdFxuICogc3RhdGljIGdldCBbaW5zdGFuY2VTeW1ib2xdKCkge1xuICogICAgcmV0dXJuIFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL3R5cGVzL2Jhc2VcIik7XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBUaGUgY2xhc3Mgd2FzIGZvcm1lcmx5IGNhbGxlZCBPYmplY3QuXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS41LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UeXBlc1xuICovXG5jbGFzcyBCYXNlIGV4dGVuZHMgT2JqZWN0IHtcbiAgICAvKipcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAgICovXG4gICAgdG9TdHJpbmcoKSB7XG4gICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh0aGlzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGBpbnN0YW5jZW9mYCBvcGVyYXRvci5cbiAgICAgKiBAcmV0dXJucyB7c3ltYm9sfVxuICAgICAqIEBzaW5jZSAyLjEuMFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgW2luc3RhbmNlU3ltYm9sXSgpIHtcbiAgICAgICAgcmV0dXJuIFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL3R5cGVzL2Jhc2VcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHBhcmFtIHRoYXRcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICAgKiBAc2luY2UgMi4xLjBcbiAgICAgKi9cbiAgICBzdGF0aWMgW1N5bWJvbC5oYXNJbnN0YW5jZV0odGhhdCkge1xuICAgICAgICBpZiAodGhhdCA9PT0gdW5kZWZpbmVkIHx8IHRoYXQgPT09IG51bGwgfHwgKHR5cGVvZiB0aGF0ICE9PSBcIm9iamVjdFwiICYmIHR5cGVvZiB0aGF0ICE9PSBcImZ1bmN0aW9uXCIpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB0aGF0Q2xhc3MgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YodGhhdCk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHRoYXRDbGFzcyA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICAgICAgICB0aGF0Q2xhc3MgPT09IG51bGwgfHxcbiAgICAgICAgICAgICh0eXBlb2YgdGhhdENsYXNzICE9PSBcIm9iamVjdFwiICYmIHR5cGVvZiB0aGF0Q2xhc3MgIT09IFwiZnVuY3Rpb25cIilcbiAgICAgICAgKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY2hlY2tJbnN0YW5jZVN5bWJvbC5hcHBseSh0aGlzLCBbdGhhdENsYXNzXSkgPT09IHRydWUpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gdGhpcyBjYWxsIHRoZSBzdGF0aWMgbWV0aG9kIG9mIHRoZSBzdXBlciBjbGFzcywgaWYgdGhlcmUgaXMgb25lXG4gICAgICAgIHJldHVybiBzdXBlcltTeW1ib2wuaGFzSW5zdGFuY2VdKHRoYXQpO1xuICAgIH1cbn1cblxuLyoqXG4gKiB0aGlzIGZ1bmN0aW9uIGNoZWNrcyBpZiB0aGUgY2xhc3MgaGFzIGEgc3RhdGljIGdldHRlciBgaW5zdGFuY2VTeW1ib2xgIGFuZCBpZiB0aGUgdmFsdWUgb2YgdGhpcyBnZXR0ZXIgaXMgZXF1YWwgdG8gdGhlXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSBvYmpcbiAqIEByZXR1cm5zIHtib29sZWFufGFueXxib29sZWFufVxuICogQHNpbmNlIDIuMS4wXG4gKi9cbmZ1bmN0aW9uIGNoZWNrSW5zdGFuY2VTeW1ib2wob2JqKSB7XG4gICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoaW5zdGFuY2VTeW1ib2wpID09PSBmYWxzZSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgY29uc3QgcHJvdG8gPSBvYmo/LmNvbnN0cnVjdG9yO1xuICAgIGlmIChwcm90byA9PT0gdW5kZWZpbmVkIHx8IHByb3RvID09PSBudWxsIHx8ICh0eXBlb2YgcHJvdG8gIT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHByb3RvICE9PSBcImZ1bmN0aW9uXCIpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAocHJvdG8uaGFzT3duUHJvcGVydHkoaW5zdGFuY2VTeW1ib2wpICE9PSB0cnVlKSB7XG4gICAgICAgIHJldHVybiBjaGVja0luc3RhbmNlU3ltYm9sLmFwcGx5KHRoaXMsIFtvYmouX19wcm90b19fXSk7XG4gICAgfVxuXG4gICAgY29uc3Qgc3ltYm9sID0gcHJvdG9baW5zdGFuY2VTeW1ib2xdO1xuICAgIGlmIChzeW1ib2wgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAob2JqLl9fcHJvdG9fXykge1xuICAgICAgICAgICAgcmV0dXJuIGNoZWNrSW5zdGFuY2VTeW1ib2wob2JqLl9fcHJvdG9fXyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc3ltYm9sID09PSB0aGlzW2luc3RhbmNlU3ltYm9sXSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gY2hlY2tJbnN0YW5jZVN5bWJvbC5hcHBseSh0aGlzLCBbb2JqLl9fcHJvdG9fX10pO1xufVxuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHtcbiAgICBpc0FycmF5LFxuICAgIGlzQm9vbGVhbixcbiAgICBpc0Z1bmN0aW9uLFxuICAgIGlzSW5zdGFuY2UsXG4gICAgaXNJbnRlZ2VyLFxuICAgIGlzSXRlcmFibGUsXG4gICAgaXNPYmplY3QsXG4gICAgaXNQcmltaXRpdmUsXG4gICAgaXNTdHJpbmcsXG4gICAgaXNTeW1ib2wsXG59IGZyb20gXCIuL2lzLm1qc1wiO1xuXG5leHBvcnQge1xuICAgIHZhbGlkYXRlSXRlcmFibGUsXG4gICAgdmFsaWRhdGVQcmltaXRpdmUsXG4gICAgdmFsaWRhdGVCb29sZWFuLFxuICAgIHZhbGlkYXRlU3RyaW5nLFxuICAgIHZhbGlkYXRlT2JqZWN0LFxuICAgIHZhbGlkYXRlSW5zdGFuY2UsXG4gICAgdmFsaWRhdGVBcnJheSxcbiAgICB2YWxpZGF0ZVN5bWJvbCxcbiAgICB2YWxpZGF0ZUZ1bmN0aW9uLFxuICAgIHZhbGlkYXRlSW50ZWdlcixcbn07XG5cbi8qKlxuICogVGhpcyBtZXRob2QgY2hlY2tzIGlmIHRoZSB0eXBlIG1hdGNoZXMgdGhlIHByaW1pdGl2ZSB0eXBlLiB0aGlzIGZ1bmN0aW9uIGlzIGlkZW50aWNhbCB0byBpc1ByaW1pdGl2ZSgpIGV4Y2VwdCB0aGF0IGEgVHlwZUVycm9yIGlzIHRocm93bi5cbiAqXG4gKiBgYGBcbiAqIDxzY3JpcHQgdHlwZT1cIm1vZHVsZVwiPlxuICogaW1wb3J0IHt2YWxpZGF0ZUl0ZXJhYmxlfSBmcm9tICdAc2NodWthaS9tb25zdGVyL3NvdXJjZS90eXBlcy92YWxpZGF0ZS5tanMnO1xuICogY29uc29sZS5sb2codmFsaWRhdGVJdGVyYWJsZSgnMicpKSAgLy8gXHUyMUE2IFR5cGVFcnJvclxuICogY29uc29sZS5sb2codmFsaWRhdGVJdGVyYWJsZShbXSkpICAvLyBcdTIxQTYgdmFsdWVcbiAqIDwvc2NyaXB0PlxuICogYGBgXG4gKlxuICogQHBhcmFtIHsqfSB2YWx1ZVxuICogQHJldHVybiB7Kn1cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMi4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgcHJpbWl0aXZlXG4gKiBAc2VlIHtAbGluayBpc1ByaW1pdGl2ZX1cbiAqIEBzZWUge0BsaW5rIE1vbnN0ZXIuVHlwZXMuaXNQcmltaXRpdmV9XG4gKiBAc2VlIHtAbGluayBNb25zdGVyLlR5cGVzI2lzUHJpbWl0aXZlfVxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZUl0ZXJhYmxlKHZhbHVlKSB7XG4gICAgaWYgKCFpc0l0ZXJhYmxlKHZhbHVlKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwidmFsdWUgaXMgbm90IGl0ZXJhYmxlXCIpO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWU7XG59XG5cbi8qKlxuICogVGhpcyBtZXRob2QgY2hlY2tzIGlmIHRoZSB0eXBlIG1hdGNoZXMgdGhlIHByaW1pdGl2ZSB0eXBlLiB0aGlzIGZ1bmN0aW9uIGlzIGlkZW50aWNhbCB0byBpc1ByaW1pdGl2ZSgpIGV4Y2VwdCB0aGF0IGEgVHlwZUVycm9yIGlzIHRocm93bi5cbiAqXG4gKiBgYGBcbiAqIDxzY3JpcHQgdHlwZT1cIm1vZHVsZVwiPlxuICogaW1wb3J0IHt2YWxpZGF0ZVByaW1pdGl2ZX0gZnJvbSAnQHNjaHVrYWkvbW9uc3Rlci9zb3VyY2UvdHlwZXMvdmFsaWRhdGUubWpzJztcbiAqIGNvbnNvbGUubG9nKHZhbGlkYXRlUHJpbWl0aXZlKCcyJykpICAvLyBcdTIxQTYgdmFsdWVcbiAqIGNvbnNvbGUubG9nKHZhbGlkYXRlUHJpbWl0aXZlKFtdKSkgIC8vIFx1MjFBNiBUeXBlRXJyb3JcbiAqIDwvc2NyaXB0PlxuICogYGBgXG4gKlxuICogQHBhcmFtIHsqfSB2YWx1ZVxuICogQHJldHVybiB7Kn1cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMC4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgcHJpbWl0aXZlXG4gKiBAc2VlIHtAbGluayBpc1ByaW1pdGl2ZX1cbiAqIEBzZWUge0BsaW5rIE1vbnN0ZXIuVHlwZXMuaXNQcmltaXRpdmV9XG4gKiBAc2VlIHtAbGluayBNb25zdGVyLlR5cGVzI2lzUHJpbWl0aXZlfVxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZVByaW1pdGl2ZSh2YWx1ZSkge1xuICAgIGlmICghaXNQcmltaXRpdmUodmFsdWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJ2YWx1ZSBpcyBub3QgYSBwcmltaXRpdmVcIik7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZTtcbn1cblxuLyoqXG4gKiBUaGlzIG1ldGhvZCBjaGVja3MgaWYgdGhlIHR5cGUgbWF0Y2hlcyB0aGUgYm9vbGVhbiB0eXBlLiB0aGlzIGZ1bmN0aW9uIGlzIGlkZW50aWNhbCB0byBpc0Jvb2xlYW4oKSBleGNlcHQgdGhhdCBhIFR5cGVFcnJvciBpcyB0aHJvd24uXG4gKlxuICogYGBgXG4gKiA8c2NyaXB0IHR5cGU9XCJtb2R1bGVcIj5cbiAqIGltcG9ydCB7dmFsaWRhdGVCb29sZWFufSBmcm9tICdAc2NodWthaS9tb25zdGVyL3NvdXJjZS90eXBlcy92YWxpZGF0ZS5tanMnO1xuICogY29uc29sZS5sb2codmFsaWRhdGVCb29sZWFuKGZhbHNlKSkgIC8vIFx1MjFBNiB2YWx1ZVxuICogY29uc29sZS5sb2codmFsaWRhdGVCb29sZWFuKCcyJykpICAvLyBcdTIxQTYgVHlwZUVycm9yXG4gKiBjb25zb2xlLmxvZyh2YWxpZGF0ZUJvb2xlYW4oW10pKSAgLy8gXHUyMUE2IFR5cGVFcnJvclxuICogPC9zY3JpcHQ+XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0geyp9IHZhbHVlXG4gKiBAcmV0dXJuIHsqfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4wLjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UeXBlc1xuXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9ICB2YWx1ZSBpcyBub3QgcHJpbWl0aXZlXG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlQm9vbGVhbih2YWx1ZSkge1xuICAgIGlmICghaXNCb29sZWFuKHZhbHVlKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwidmFsdWUgaXMgbm90IGEgYm9vbGVhblwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xufVxuXG4vKipcbiAqIFRoaXMgbWV0aG9kIGNoZWNrcyBpZiB0aGUgdHlwZSBtYXRjaGVzIHRoZSBzdHJpbmcgdHlwZS4gdGhpcyBmdW5jdGlvbiBpcyBpZGVudGljYWwgdG8gaXNTdHJpbmcoKSBleGNlcHQgdGhhdCBhIFR5cGVFcnJvciBpcyB0aHJvd24uXG4gKlxuICogYGBgXG4gKiA8c2NyaXB0IHR5cGU9XCJtb2R1bGVcIj5cbiAqIGltcG9ydCB7dmFsaWRhdGVTdHJpbmd9IGZyb20gJ0BzY2h1a2FpL21vbnN0ZXIvc291cmNlL3R5cGVzL3ZhbGlkYXRlLm1qcyc7XG4gKiBjb25zb2xlLmxvZyh2YWxpZGF0ZVN0cmluZygnMicpKSAgLy8gXHUyMUE2IHZhbHVlXG4gKiBjb25zb2xlLmxvZyh2YWxpZGF0ZVN0cmluZyhbXSkpICAvLyBcdTIxQTYgVHlwZUVycm9yXG4gKiA8L3NjcmlwdD5cbiAqIGBgYFxuICpcbiAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAqIEByZXR1cm4geyp9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjAuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIHN0cmluZ1xuICovXG5mdW5jdGlvbiB2YWxpZGF0ZVN0cmluZyh2YWx1ZSkge1xuICAgIGlmICghaXNTdHJpbmcodmFsdWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJ2YWx1ZSBpcyBub3QgYSBzdHJpbmdcIik7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZTtcbn1cblxuLyoqXG4gKiBUaGlzIG1ldGhvZCBjaGVja3MgaWYgdGhlIHR5cGUgbWF0Y2hlcyB0aGUgb2JqZWN0IHR5cGUuIHRoaXMgZnVuY3Rpb24gaXMgaWRlbnRpY2FsIHRvIGlzT2JqZWN0KCkgZXhjZXB0IHRoYXQgYSBUeXBlRXJyb3IgaXMgdGhyb3duLlxuICpcbiAqIGBgYFxuICogPHNjcmlwdCB0eXBlPVwibW9kdWxlXCI+XG4gKiBpbXBvcnQge3ZhbGlkYXRlT2JqZWN0fSBmcm9tICdAc2NodWthaS9tb25zdGVyL3NvdXJjZS90eXBlcy92YWxpZGF0ZS5tanMnO1xuICogY29uc29sZS5sb2codmFsaWRhdGVPYmplY3Qoe30pKSAgLy8gXHUyMUE2IHZhbHVlXG4gKiBjb25zb2xlLmxvZyh2YWxpZGF0ZU9iamVjdCgnMicpKSAgLy8gXHUyMUE2IFR5cGVFcnJvclxuICogY29uc29sZS5sb2codmFsaWRhdGVPYmplY3QoW10pKSAgLy8gXHUyMUE2IFR5cGVFcnJvclxuICogPC9zY3JpcHQ+XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0geyp9IHZhbHVlXG4gKiBAcmV0dXJuIHsqfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4wLjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UeXBlc1xuICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYSBvYmplY3RcbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVPYmplY3QodmFsdWUpIHtcbiAgICBpZiAoIWlzT2JqZWN0KHZhbHVlKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwidmFsdWUgaXMgbm90IGEgb2JqZWN0XCIpO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWU7XG59XG5cbi8qKlxuICogVGhpcyBtZXRob2QgY2hlY2tzIGlmIHRoZSB0eXBlIG1hdGNoZXMgdGhlIG9iamVjdCBpbnN0YW5jZS5cbiAqXG4gKiBgYGBcbiAqIDxzY3JpcHQgdHlwZT1cIm1vZHVsZVwiPlxuICogaW1wb3J0IHt2YWxpZGF0ZUluc3RhbmNlfSBmcm9tICdAc2NodWthaS9tb25zdGVyL3NvdXJjZS90eXBlcy92YWxpZGF0ZS5tanMnO1xuICogY29uc29sZS5sb2codmFsaWRhdGVJbnN0YW5jZSh7fSwgT2JqZWN0KSkgLy8gXHUyMUE2IHZhbHVlXG4gKiBjb25zb2xlLmxvZyh2YWxpZGF0ZUluc3RhbmNlKCcyJywgT2JqZWN0KSkgLy8gXHUyMUE2IFR5cGVFcnJvclxuICogY29uc29sZS5sb2codmFsaWRhdGVJbnN0YW5jZShbXSwgT2JqZWN0KSkgLy8gXHUyMUE2IFR5cGVFcnJvclxuICogPC9zY3JpcHQ+XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0geyp9IHZhbHVlXG4gKiBAcmV0dXJuIHsqfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS41LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UeXBlc1xuICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYW4gaW5zdGFuY2Ugb2ZcbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVJbnN0YW5jZSh2YWx1ZSwgaW5zdGFuY2UpIHtcbiAgICBpZiAoIWlzSW5zdGFuY2UodmFsdWUsIGluc3RhbmNlKSkge1xuICAgICAgICBsZXQgbiA9IFwiXCI7XG4gICAgICAgIGlmIChpc09iamVjdChpbnN0YW5jZSkgfHwgaXNGdW5jdGlvbihpbnN0YW5jZSkpIHtcbiAgICAgICAgICAgIG4gPSBpbnN0YW5jZT8uW1wibmFtZVwiXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChuKSB7XG4gICAgICAgICAgICBuID0gYCAke259YDtcbiAgICAgICAgfVxuXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYHZhbHVlIGlzIG5vdCBhbiBpbnN0YW5jZSBvZiR7bn1gKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xufVxuXG4vKipcbiAqIFRoaXMgbWV0aG9kIGNoZWNrcyBpZiB0aGUgdHlwZSBtYXRjaGVzIHRoZSBhcnJheSB0eXBlLiB0aGlzIGZ1bmN0aW9uIGlzIGlkZW50aWNhbCB0byBpc0FycmF5KCkgZXhjZXB0IHRoYXQgYSBUeXBlRXJyb3IgaXMgdGhyb3duLlxuICpcbiAqIGBgYFxuICogPHNjcmlwdCB0eXBlPVwibW9kdWxlXCI+XG4gKiBpbXBvcnQge3ZhbGlkYXRlQXJyYXl9IGZyb20gJ0BzY2h1a2FpL21vbnN0ZXIvc291cmNlL3R5cGVzL3ZhbGlkYXRlLm1qcyc7XG4gKiBjb25zb2xlLmxvZyh2YWxpZGF0ZUFycmF5KCcyJykpICAvLyBcdTIxQTYgVHlwZUVycm9yXG4gKiBjb25zb2xlLmxvZyh2YWxpZGF0ZUFycmF5KFtdKSkgIC8vIFx1MjFBNiB2YWx1ZVxuICogPC9zY3JpcHQ+XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0geyp9IHZhbHVlXG4gKiBAcmV0dXJuIHsqfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4wLjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UeXBlc1xuICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYW4gYXJyYXlcbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVBcnJheSh2YWx1ZSkge1xuICAgIGlmICghaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInZhbHVlIGlzIG5vdCBhbiBhcnJheVwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xufVxuXG4vKipcbiAqIFRoaXMgbWV0aG9kIGNoZWNrcyBpZiB0aGUgdHlwZSBtYXRjaGVzIHRoZSBzeW1ib2wgdHlwZS4gdGhpcyBmdW5jdGlvbiBpcyBpZGVudGljYWwgdG8gaXNTeW1ib2woKSBleGNlcHQgdGhhdCBhIFR5cGVFcnJvciBpcyB0aHJvd24uXG4gKlxuICogYGBgXG4gKiA8c2NyaXB0IHR5cGU9XCJtb2R1bGVcIj5cbiAqIGltcG9ydCB7dmFsaWRhdGVTeW1ib2x9IGZyb20gJ0BzY2h1a2FpL21vbnN0ZXIvc291cmNlL3R5cGVzL3ZhbGlkYXRlLm1qcyc7XG4gKiBjb25zb2xlLmxvZyh2YWxpZGF0ZVN5bWJvbCgnMicpKSAgLy8gXHUyMUE2IFR5cGVFcnJvclxuICogY29uc29sZS5sb2codmFsaWRhdGVTeW1ib2woKSkgIC8vIFx1MjFBNiB2YWx1ZVxuICogPC9zY3JpcHQ+XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0geyp9IHZhbHVlXG4gKiBAcmV0dXJuIHsqfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS45LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UeXBlc1xuICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYW4gc3ltYm9sXG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlU3ltYm9sKHZhbHVlKSB7XG4gICAgaWYgKCFpc1N5bWJvbCh2YWx1ZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInZhbHVlIGlzIG5vdCBhbiBzeW1ib2xcIik7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZTtcbn1cblxuLyoqXG4gKiBUaGlzIG1ldGhvZCBjaGVja3MgaWYgdGhlIHR5cGUgbWF0Y2hlcyB0aGUgZnVuY3Rpb24gdHlwZS4gdGhpcyBmdW5jdGlvbiBpcyBpZGVudGljYWwgdG8gaXNGdW5jdGlvbigpIGV4Y2VwdCB0aGF0IGEgVHlwZUVycm9yIGlzIHRocm93bi5cbiAqXG4gKiBgYGBcbiAqIDxzY3JpcHQgdHlwZT1cIm1vZHVsZVwiPlxuICogaW1wb3J0IHt2YWxpZGF0ZUZ1bmN0aW9ufSBmcm9tICdAc2NodWthaS9tb25zdGVyL3NvdXJjZS90eXBlcy92YWxpZGF0ZS5tanMnO1xuICogY29uc29sZS5sb2codmFsaWRhdGVGdW5jdGlvbigoKT0+e30pKSAvLyBcdTIxQTYgdmFsdWVcbiAqIGNvbnNvbGUubG9nKHZhbGlkYXRlRnVuY3Rpb24oJzInKSkgIC8vIFx1MjFBNiBUeXBlRXJyb3JcbiAqIGNvbnNvbGUubG9nKHZhbGlkYXRlRnVuY3Rpb24oW10pKSAgLy8gXHUyMUE2IFR5cGVFcnJvclxuICogPC9zY3JpcHQ+XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0geyp9IHZhbHVlXG4gKiBAcmV0dXJuIHsqfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4wLjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UeXBlc1xuICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYSBmdW5jdGlvblxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZUZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgaWYgKCFpc0Z1bmN0aW9uKHZhbHVlKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwidmFsdWUgaXMgbm90IGEgZnVuY3Rpb25cIik7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZTtcbn1cblxuLyoqXG4gKiBUaGlzIG1ldGhvZCBjaGVja3MgaWYgdGhlIHR5cGUgaXMgYW4gaW50ZWdlci4gdGhpcyBmdW5jdGlvbiBpcyBpZGVudGljYWwgdG8gaXNJbnRlZ2VyKCkgZXhjZXB0IHRoYXQgYSBUeXBlRXJyb3IgaXMgdGhyb3duLlxuICpcbiAqIGBgYFxuICogPHNjcmlwdCB0eXBlPVwibW9kdWxlXCI+XG4gKiBpbXBvcnQge3ZhbGlkYXRlRnVuY3Rpb259IGZyb20gJ0BzY2h1a2FpL21vbnN0ZXIvc291cmNlL3R5cGVzL3ZhbGlkYXRlLm1qcyc7XG4gKiBjb25zb2xlLmxvZyh2YWxpZGF0ZUludGVnZXIodHJ1ZSkpIC8vIFx1MjFBNiBUeXBlRXJyb3JcbiAqIGNvbnNvbGUubG9nKHZhbGlkYXRlSW50ZWdlcignMicpKSAgLy8gXHUyMUE2IFR5cGVFcnJvclxuICogY29uc29sZS5sb2codmFsaWRhdGVJbnRlZ2VyKDIpKSAgLy8gXHUyMUE2IHZhbHVlXG4gKiA8L3NjcmlwdD5cbiAqIGBgYFxuICpcbiAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAqIEByZXR1cm4geyp9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjQuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhbiBpbnRlZ2VyXG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlSW50ZWdlcih2YWx1ZSkge1xuICAgIGlmICghaXNJbnRlZ2VyKHZhbHVlKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwidmFsdWUgaXMgbm90IGFuIGludGVnZXJcIik7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZTtcbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IHZhbGlkYXRlRnVuY3Rpb24sIHZhbGlkYXRlT2JqZWN0LCB2YWxpZGF0ZVN0cmluZyB9IGZyb20gXCIuL3ZhbGlkYXRlLm1qc1wiO1xuXG5leHBvcnQgeyBnZXRHbG9iYWwsIGdldEdsb2JhbE9iamVjdCwgZ2V0R2xvYmFsRnVuY3Rpb24gfTtcblxuLyoqXG4gKiBAdHlwZSB7b2JqZWN9XG4gKiBAcHJpdmF0ZVxuICovXG5sZXQgZ2xvYmFsUmVmZXJlbmNlO1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAdGhyb3dzIHtFcnJvcn0gdW5zdXBwb3J0ZWQgZW52aXJvbm1lbnQuXG4gKi9cbihmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHR5cGVvZiBnbG9iYWxUaGlzID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgIGdsb2JhbFJlZmVyZW5jZSA9IGdsb2JhbFRoaXM7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgZ2xvYmFsUmVmZXJlbmNlID0gc2VsZjtcbiAgICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICBnbG9iYWxSZWZlcmVuY2UgPSB3aW5kb3c7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoT2JqZWN0LnByb3RvdHlwZSwgXCJfX21vbnN0ZXJfX1wiLCB7XG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICB9KTtcblxuICAgIGlmICh0eXBlb2YgX19tb25zdGVyX18gPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgX19tb25zdGVyX18uZ2xvYmFsVGhpcyA9IF9fbW9uc3Rlcl9fO1xuICAgICAgICBkZWxldGUgT2JqZWN0LnByb3RvdHlwZS5fX21vbnN0ZXJfXztcblxuICAgICAgICBnbG9iYWxSZWZlcmVuY2UgPSBnbG9iYWxUaGlzO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgICAgZ2xvYmFsUmVmZXJlbmNlID0gRnVuY3Rpb24oXCJyZXR1cm4gdGhpc1wiKSgpO1xuICAgIH0gY2F0Y2ggKGUpIHt9XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1bnN1cHBvcnRlZCBlbnZpcm9ubWVudC5cIik7XG59KSgpO1xuXG4vKipcbiAqIFJldHVybiBnbG9iYWxUaGlzXG4gKlxuICogSWYgZ2xvYmFsVGhpcyBpcyBub3QgYXZhaWxhYmxlLCBpdCB3aWxsIGJlIHBvbHlmaWxsZWRcbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjYuMFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcbiAqIEByZXR1cm5zIHtvYmplY30gZ2xvYmFsVGhpc1xuICovXG5mdW5jdGlvbiBnZXRHbG9iYWwoKSB7XG4gICAgcmV0dXJuIGdsb2JhbFJlZmVyZW5jZTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gZ2xvYmFsIG9iamVjdCBvciB0aHJvdyBFcnJvclxuICpcbiAqIFlvdSBjYW4gY2FsbCB0aGUgbWV0aG9kIHZpYSB0aGUgbW9uc3RlciBuYW1lc3BhY2UgYE1vbnN0ZXIuVHlwZXMuZ2V0R2xvYmFsT2JqZWN0KClgLlxuICpcbiAqIGBgYFxuICogPHNjcmlwdCB0eXBlPVwibW9kdWxlXCI+XG4gKiBpbXBvcnQge01vbnN0ZXJ9IGZyb20gJ0BzY2h1a2FpL21vbnN0ZXIvc291cmNlL21vbnN0ZXIubWpzJztcbiAqIE1vbnN0ZXIuVHlwZXMuZ2V0R2xvYmFsT2JqZWN0KCdkb2N1bWVudCcpXG4gKiAvLyBcdTIxQTYgeyB9XG4gKiA8L3NjcmlwdD5cbiAqIGBgYFxuICpcbiAqIEFsdGVybmF0aXZlbHksIHlvdSBjYW4gYWxzbyBpbnRlZ3JhdGUgdGhpcyBmdW5jdGlvbiBpbmRpdmlkdWFsbHkuXG4gKlxuICogYGBgXG4gKiA8c2NyaXB0IHR5cGU9XCJtb2R1bGVcIj5cbiAqIGltcG9ydCB7Z2V0R2xvYmFsT2JqZWN0fSBmcm9tICdodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL0BzY2h1a2FpL21vbnN0ZXJAMS4zMC4wL2Rpc3QvbW9kdWxlcy90eXBlcy9nbG9iYWwubWpzJztcbiAqIGdldEdsb2JhbE9iamVjdCgnZG9jdW1lbnQnKVxuICogLy8gXHUyMUE2IHsgfVxuICogPC9zY3JpcHQ+XG4gKiBgYGBcbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjYuMFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gKiBAcmV0dXJucyB7b2JqZWN9XG4gKiBAdGhyb3dzIHtFcnJvcn0gdGhlIG9iamVjdCBpcyBub3QgZGVmaW5lZFxuICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYSBvYmplY3RcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgc3RyaW5nXG4gKi9cbmZ1bmN0aW9uIGdldEdsb2JhbE9iamVjdChuYW1lKSB7XG4gICAgdmFsaWRhdGVTdHJpbmcobmFtZSk7XG4gICAgbGV0IG8gPSBnbG9iYWxSZWZlcmVuY2U/LltuYW1lXTtcbiAgICBpZiAodHlwZW9mIG8gPT09IFwidW5kZWZpbmVkXCIpIHRocm93IG5ldyBFcnJvcihgdGhlIG9iamVjdCAke25hbWV9IGlzIG5vdCBkZWZpbmVkYCk7XG4gICAgdmFsaWRhdGVPYmplY3Qobyk7XG4gICAgcmV0dXJuIG87XG59XG5cbi8qKlxuICogUmV0dXJuIGdsb2JhbCBmdW5jdGlvbiBvciB0aHJvdyBFcnJvclxuICpcbiAqIFlvdSBjYW4gY2FsbCB0aGUgbWV0aG9kIHZpYSB0aGUgbW9uc3RlciBuYW1lc3BhY2UgYE1vbnN0ZXIuVHlwZXMuZ2V0R2xvYmFsRnVuY3Rpb24oKWAuXG4gKlxuICogYGBgXG4gKiA8c2NyaXB0IHR5cGU9XCJtb2R1bGVcIj5cbiAqIGltcG9ydCB7TW9uc3Rlcn0gZnJvbSAnQHNjaHVrYWkvbW9uc3Rlci9zb3VyY2UvbW9uc3Rlci5tanMnO1xuICogY29uc29sZS5sb2coTW9uc3Rlci5UeXBlcy5nZXRHbG9iYWxGdW5jdGlvbigncGFyc2VJbnQnKSkgLy8gXHUyMUE2IGYgcGFyc2VJbnQoKSB7IH1cbiAqIDwvc2NyaXB0PlxuICogYGBgXG4gKlxuICogQWx0ZXJuYXRpdmVseSwgeW91IGNhbiBhbHNvIGludGVncmF0ZSB0aGlzIGZ1bmN0aW9uIGluZGl2aWR1YWxseS5cbiAqXG4gKiBgYGBcbiAqIDxzY3JpcHQgdHlwZT1cIm1vZHVsZVwiPlxuICogaW1wb3J0IHtnZXRHbG9iYWxGdW5jdGlvbn0gZnJvbSAnaHR0cHM6Ly9jZG4uanNkZWxpdnIubmV0L25wbS9Ac2NodWthaS9tb25zdGVyQDEuMzAuMC9kaXN0L21vZHVsZXMvdHlwZXMvZ2xvYmFsLm1qcyc7XG4gKiBjb25zb2xlLmxvZyhnZXRHbG9iYWxGdW5jdGlvbigncGFyc2VJbnQnKSkgLy8gXHUyMUE2IGYgcGFyc2VJbnQoKSB7IH1cbiAqIDwvc2NyaXB0PlxuICogYGBgXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS42LjBcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuICogQHJldHVybiB7b2JqZWN9XG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIGZ1bmN0aW9uXG4gKiBAdGhyb3dzIHtFcnJvcn0gdGhlIGZ1bmN0aW9uIGlzIG5vdCBkZWZpbmVkXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIHN0cmluZ1xuICovXG5mdW5jdGlvbiBnZXRHbG9iYWxGdW5jdGlvbihuYW1lKSB7XG4gICAgdmFsaWRhdGVTdHJpbmcobmFtZSk7XG4gICAgbGV0IGYgPSBnbG9iYWxSZWZlcmVuY2U/LltuYW1lXTtcbiAgICBpZiAodHlwZW9mIGYgPT09IFwidW5kZWZpbmVkXCIpIHRocm93IG5ldyBFcnJvcihgdGhlIGZ1bmN0aW9uICR7bmFtZX0gaXMgbm90IGRlZmluZWRgKTtcbiAgICB2YWxpZGF0ZUZ1bmN0aW9uKGYpO1xuICAgIHJldHVybiBmO1xufVxuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgZ2V0R2xvYmFsIH0gZnJvbSBcIi4uL3R5cGVzL2dsb2JhbC5tanNcIjtcbmltcG9ydCB7IGlzQXJyYXksIGlzRnVuY3Rpb24sIGlzT2JqZWN0LCBpc1ByaW1pdGl2ZSB9IGZyb20gXCIuLi90eXBlcy9pcy5tanNcIjtcbmltcG9ydCB7IHR5cGVPZiB9IGZyb20gXCIuLi90eXBlcy90eXBlb2YubWpzXCI7XG5pbXBvcnQgeyB2YWxpZGF0ZU9iamVjdCB9IGZyb20gXCIuLi90eXBlcy92YWxpZGF0ZS5tanNcIjtcblxuZXhwb3J0IHsgY2xvbmUgfTtcblxuLyoqXG4gKiBXaXRoIHRoaXMgZnVuY3Rpb24sIG9iamVjdHMgY2FuIGJlIGNsb25lZC5cbiAqIFRoZSBlbnRpcmUgb2JqZWN0IHRyZWUgaXMgcnVuIHRocm91Z2guXG4gKlxuICogUHJveHksIEVsZW1lbnQsIEhUTUxEb2N1bWVudCBhbmQgRG9jdW1lbnRGcmFnbWVudCBpbnN0YW5jZXMgYXJlIG5vdCBjbG9uZWQuXG4gKiBHbG9iYWwgb2JqZWN0cyBzdWNoIGFzIHdpbmRvd3MgYXJlIGFsc28gbm90IGNsb25lZCxcbiAqXG4gKiBJZiBhbiBvYmplY3QgaGFzIGEgbWV0aG9kIGBnZXRDbG9uZSgpYCwgdGhpcyBtZXRob2QgaXMgdXNlZCB0byBjcmVhdGUgdGhlIGNsb25lLlxuICpcbiAqIEBwYXJhbSB7Kn0gb2JqIG9iamVjdCB0byBiZSBjbG9uZWRcbiAqIEByZXR1cm5zIHsqfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4wLjBcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlV0aWxcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAdGhyb3dzIHtFcnJvcn0gdW5hYmxlIHRvIGNsb25lIG9iaiEgaXRzIHR5cGUgaXNuJ3Qgc3VwcG9ydGVkLlxuICovXG5mdW5jdGlvbiBjbG9uZShvYmopIHtcbiAgICAvLyB0eXBlb2YgbnVsbCByZXN1bHRzIGluICdvYmplY3QnLiAgaHR0cHM6Ly8yYWxpdHkuY29tLzIwMTMvMTAvdHlwZW9mLW51bGwuaHRtbFxuICAgIGlmIChudWxsID09PSBvYmopIHtcbiAgICAgICAgcmV0dXJuIG9iajtcbiAgICB9XG5cbiAgICAvLyBIYW5kbGUgdGhlIHR3byBzaW1wbGUgdHlwZXMsIG51bGwgYW5kIHVuZGVmaW5lZFxuICAgIGlmIChpc1ByaW1pdGl2ZShvYmopKSB7XG4gICAgICAgIHJldHVybiBvYmo7XG4gICAgfVxuXG4gICAgLy8gSGFuZGxlIHRoZSB0d28gc2ltcGxlIHR5cGVzLCBudWxsIGFuZCB1bmRlZmluZWRcbiAgICBpZiAoaXNGdW5jdGlvbihvYmopKSB7XG4gICAgICAgIHJldHVybiBvYmo7XG4gICAgfVxuXG4gICAgLy8gSGFuZGxlIEFycmF5XG4gICAgaWYgKGlzQXJyYXkob2JqKSkge1xuICAgICAgICBsZXQgY29weSA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gb2JqLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICBjb3B5W2ldID0gY2xvbmUob2JqW2ldKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBjb3B5O1xuICAgIH1cblxuICAgIGlmIChpc09iamVjdChvYmopKSB7XG4gICAgICAgIC8vIEhhbmRsZSBEYXRlXG4gICAgICAgIGlmIChvYmogaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICAgICAgICBsZXQgY29weSA9IG5ldyBEYXRlKCk7XG4gICAgICAgICAgICBjb3B5LnNldFRpbWUob2JqLmdldFRpbWUoKSk7XG4gICAgICAgICAgICByZXR1cm4gY29weTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKiBEbyBub3QgY2xvbmUgRE9NIG5vZGVzICovXG4gICAgICAgIGlmICh0eXBlb2YgRWxlbWVudCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBvYmogaW5zdGFuY2VvZiBFbGVtZW50KSByZXR1cm4gb2JqO1xuICAgICAgICBpZiAodHlwZW9mIEhUTUxEb2N1bWVudCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBvYmogaW5zdGFuY2VvZiBIVE1MRG9jdW1lbnQpIHJldHVybiBvYmo7XG4gICAgICAgIGlmICh0eXBlb2YgRG9jdW1lbnRGcmFnbWVudCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBvYmogaW5zdGFuY2VvZiBEb2N1bWVudEZyYWdtZW50KSByZXR1cm4gb2JqO1xuXG4gICAgICAgIC8qKiBEbyBub3QgY2xvbmUgZ2xvYmFsIG9iamVjdHMgKi9cbiAgICAgICAgaWYgKG9iaiA9PT0gZ2V0R2xvYmFsKCkpIHJldHVybiBvYmo7XG4gICAgICAgIGlmICh0eXBlb2YgZ2xvYmFsQ29udGV4dCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBvYmogPT09IGdsb2JhbENvbnRleHQpIHJldHVybiBvYmo7XG4gICAgICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiICYmIG9iaiA9PT0gd2luZG93KSByZXR1cm4gb2JqO1xuICAgICAgICBpZiAodHlwZW9mIGRvY3VtZW50ICE9PSBcInVuZGVmaW5lZFwiICYmIG9iaiA9PT0gZG9jdW1lbnQpIHJldHVybiBvYmo7XG4gICAgICAgIGlmICh0eXBlb2YgbmF2aWdhdG9yICE9PSBcInVuZGVmaW5lZFwiICYmIG9iaiA9PT0gbmF2aWdhdG9yKSByZXR1cm4gb2JqO1xuICAgICAgICBpZiAodHlwZW9mIEpTT04gIT09IFwidW5kZWZpbmVkXCIgJiYgb2JqID09PSBKU09OKSByZXR1cm4gb2JqO1xuXG4gICAgICAgIC8vIEhhbmRsZSBQcm94eS1PYmplY3RcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIHRyeS9jYXRjaCBiZWNhdXNlIHBvc3NpYmxlOiBUeXBlRXJyb3I6IEZ1bmN0aW9uIGhhcyBub24tb2JqZWN0IHByb3RvdHlwZSAndW5kZWZpbmVkJyBpbiBpbnN0YW5jZW9mIGNoZWNrXG4gICAgICAgICAgICBpZiAob2JqIGluc3RhbmNlb2YgUHJveHkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb2JqO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlKSB7fVxuXG4gICAgICAgIHJldHVybiBjbG9uZU9iamVjdChvYmopO1xuICAgIH1cblxuICAgIHRocm93IG5ldyBFcnJvcihcInVuYWJsZSB0byBjbG9uZSBvYmohIGl0cyB0eXBlIGlzbid0IHN1cHBvcnRlZC5cIik7XG59XG5cbi8qKlxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBvYmpcbiAqIEByZXR1cm5zIHtvYmplY3R9XG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBjbG9uZU9iamVjdChvYmopIHtcbiAgICB2YWxpZGF0ZU9iamVjdChvYmopO1xuXG4gICAgY29uc3QgZmt0ID0gb2JqPy5bXCJjb25zdHJ1Y3RvclwiXTtcblxuICAgIC8qKiBPYmplY3QgaGFzIGNsb25lIG1ldGhvZCAqL1xuICAgIGlmICh0eXBlT2YoZmt0KSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGNvbnN0IHByb3RvdHlwZSA9IGZrdD8ucHJvdG90eXBlO1xuICAgICAgICBpZiAodHlwZW9mIHByb3RvdHlwZSA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICAgICAgaWYgKHByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eShcImdldENsb25lXCIpICYmIHR5cGVPZihvYmouZ2V0Q2xvbmUpID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb2JqLmdldENsb25lKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBsZXQgY29weSA9IHt9O1xuICAgIGlmICh0eXBlb2Ygb2JqLmNvbnN0cnVjdG9yID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIG9iai5jb25zdHJ1Y3Rvci5jYWxsID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgY29weSA9IG5ldyBvYmouY29uc3RydWN0b3IoKTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBrZXkgaW4gb2JqKSB7XG4gICAgICAgIGlmICghb2JqLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzUHJpbWl0aXZlKG9ialtrZXldKSkge1xuICAgICAgICAgICAgY29weVtrZXldID0gb2JqW2tleV07XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvcHlba2V5XSA9IGNsb25lKG9ialtrZXldKTtcbiAgICB9XG5cbiAgICByZXR1cm4gY29weTtcbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGluc3RhbmNlU3ltYm9sIH0gZnJvbSBcIi4uL2NvbnN0YW50cy5tanNcIjtcbmltcG9ydCB7IEJhc2UgfSBmcm9tIFwiLi4vdHlwZXMvYmFzZS5tanNcIjtcbmltcG9ydCB7IHZhbGlkYXRlU3RyaW5nIH0gZnJvbSBcIi4uL3R5cGVzL3ZhbGlkYXRlLm1qc1wiO1xuaW1wb3J0IHsgY2xvbmUgfSBmcm9tIFwiLi4vdXRpbC9jbG9uZS5tanNcIjtcblxuZXhwb3J0IHsgTG9jYWxlLCBwYXJzZUxvY2FsZSB9O1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkkxOG5cbiAqIEB0eXBlIHtzeW1ib2x9XG4gKi9cbmNvbnN0IHByb3BlcnRpZXNTeW1ib2wgPSBTeW1ib2woXCJwcm9wZXJ0aWVzXCIpO1xuXG4vKipcbiAqIEB0eXBlIHtzeW1ib2x9XG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5JMThuXG4gKi9cbmNvbnN0IGxvY2FsZVN0cmluZ1N5bWJvbCA9IFN5bWJvbChcImxvY2FsZVN0cmluZ1wiKTtcblxuLyoqXG4gKiBUaGUgTG9jYWxlIGNsYXNzIGlzIGEgYmFzZSBjbGFzcyBmb3IgdGhlIGxhbmd1YWdlIGNsYXNzZXMuXG4gKlxuICogUkZDXG4gKlxuICogYGBgXG4gKiBBIExhbmd1YWdlLVRhZyBjb25zaXN0cyBvZjpcbiAqIGxhbmd0YWcgICAgICAgICAgICAgICAgICAgICAgICAgICA7IGdlbmVyYXRlZCB0YWdcbiAqICAgICAgICAgICAtb3ItIHByaXZhdGUtdXNlICAgICAgICA7IGEgcHJpdmF0ZSB1c2UgdGFnXG4gKlxuICogbGFuZ3RhZyAgICAgICA9IChsYW5ndWFnZVxuICogICAgICAgICAgICAgICAgICAgIFtcIi1cIiBzY3JpcHRdXG4gKiAgICAgICAgICAgICAgICAgICAgW1wiLVwiIHJlZ2lvbl1cbiAqICAgICAgICAgICAgICAgICAgICAqKFwiLVwiIHZhcmlhbnQpXG4gKiAgICAgICAgICAgICAgICAgICAgKihcIi1cIiBleHRlbnNpb24pXG4gKiAgICAgICAgICAgICAgICAgICAgW1wiLVwiIHByaXZhdGV1c2VdKVxuICpcbiAqIGxhbmd1YWdlICAgICAgPSBcImVuXCIsIFwiYWxlXCIsIG9yIGEgcmVnaXN0ZXJlZCB2YWx1ZVxuICpcbiAqIHNjcmlwdCAgICAgICAgPSBcIkxhdG5cIiwgXCJDeXJsXCIsIFwiSGFudFwiIElTTyAxNTkyNCBjb2Rlc1xuICpcbiAqIHJlZ2lvbiAgICAgICAgPSBcIlVTXCIsIFwiQ1NcIiwgXCJGUlwiIElTTyAzMTY2IGNvZGVzXG4gKiAgICAgICAgICAgICAgICAgXCI0MTlcIiwgXCIwMTlcIiwgIG9yIFVOIE0uNDkgY29kZXNcbiAqXG4gKiB2YXJpYW50ICAgICAgID0gXCJyb3phalwiLCBcIm5lZGlzXCIsIFwiMTk5NlwiLCBtdWx0aXBsZSBzdWJ0YWdzIGNhbiBiZSB1c2VkIGluIGEgdGFnXG4gKlxuICogZXh0ZW5zaW9uICAgICA9IHNpbmdsZSBsZXR0ZXIgZm9sbG93ZWQgYnkgYWRkaXRpb25hbCBzdWJ0YWdzOyBtb3JlIHRoYW4gb25lIGV4dGVuc2lvblxuICogICAgICAgICAgICAgICAgIG1heSBiZSB1c2VkIGluIGEgbGFuZ3VhZ2UgdGFnXG4gKlxuICogcHJpdmF0ZS11c2UgICA9IFwieC1cIiBmb2xsb3dlZCBieSBhZGRpdGlvbmFsIHN1YnRhZ3MsIGFzIG1hbnkgYXMgYXJlIHJlcXVpcmVkXG4gKiAgICAgICAgICAgICAgICAgTm90ZSB0aGF0IHRoZXNlIGNhbiBzdGFydCBhIHRhZyBvciBhcHBlYXIgYXQgdGhlIGVuZCAoYnV0IG5vdFxuICogICAgICAgICAgICAgICAgIGluIHRoZSBtaWRkbGUpXG4gKiBgYGBcbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjEzLjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5JMThuXG4gKiBAc2VlIGh0dHBzOi8vZGF0YXRyYWNrZXIuaWV0Zi5vcmcvZG9jL2h0bWwvcmZjMzA2NlxuICovXG5jbGFzcyBMb2NhbGUgZXh0ZW5kcyBCYXNlIHtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbGFuZ3VhZ2VcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3JlZ2lvbl1cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3NjcmlwdF1cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3ZhcmlhbnRzXVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbZXh0bGFuZ11cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3ByaXZhdGVVc2VdXG4gICAgICogQHRocm93cyB7RXJyb3J9IHVuc3VwcG9ydGVkIGxvY2FsZVxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGxhbmd1YWdlLCByZWdpb24sIHNjcmlwdCwgdmFyaWFudHMsIGV4dGxhbmcsIHByaXZhdGVVc2UpIHtcbiAgICAgICAgc3VwZXIoKTtcblxuICAgICAgICB0aGlzW3Byb3BlcnRpZXNTeW1ib2xdID0ge1xuICAgICAgICAgICAgbGFuZ3VhZ2U6IGxhbmd1YWdlID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiB2YWxpZGF0ZVN0cmluZyhsYW5ndWFnZSksXG4gICAgICAgICAgICBzY3JpcHQ6IHNjcmlwdCA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogdmFsaWRhdGVTdHJpbmcoc2NyaXB0KSxcbiAgICAgICAgICAgIHJlZ2lvbjogcmVnaW9uID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiB2YWxpZGF0ZVN0cmluZyhyZWdpb24pLFxuICAgICAgICAgICAgdmFyaWFudHM6IHZhcmlhbnRzID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiB2YWxpZGF0ZVN0cmluZyh2YXJpYW50cyksXG4gICAgICAgICAgICBleHRsYW5nOiBleHRsYW5nID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiB2YWxpZGF0ZVN0cmluZyhleHRsYW5nKSxcbiAgICAgICAgICAgIHByaXZhdGVVc2U6IHByaXZhdGVVc2UgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IHZhbGlkYXRlU3RyaW5nKHByaXZhdGVVc2UpLFxuICAgICAgICB9O1xuXG4gICAgICAgIGxldCBzID0gW107XG4gICAgICAgIGlmIChsYW5ndWFnZSAhPT0gdW5kZWZpbmVkKSBzLnB1c2gobGFuZ3VhZ2UpO1xuICAgICAgICBpZiAoc2NyaXB0ICE9PSB1bmRlZmluZWQpIHMucHVzaChzY3JpcHQpO1xuICAgICAgICBpZiAocmVnaW9uICE9PSB1bmRlZmluZWQpIHMucHVzaChyZWdpb24pO1xuICAgICAgICBpZiAodmFyaWFudHMgIT09IHVuZGVmaW5lZCkgcy5wdXNoKHZhcmlhbnRzKTtcbiAgICAgICAgaWYgKGV4dGxhbmcgIT09IHVuZGVmaW5lZCkgcy5wdXNoKGV4dGxhbmcpO1xuICAgICAgICBpZiAocHJpdmF0ZVVzZSAhPT0gdW5kZWZpbmVkKSBzLnB1c2gocHJpdmF0ZVVzZSk7XG5cbiAgICAgICAgaWYgKHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1bnN1cHBvcnRlZCBsb2NhbGVcIik7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzW2xvY2FsZVN0cmluZ1N5bWJvbF0gPSBzLmpvaW4oXCItXCIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgYGluc3RhbmNlb2ZgIG9wZXJhdG9yLlxuICAgICAqIEByZXR1cm5zIHtzeW1ib2x9XG4gICAgICogQHNpbmNlIDMuMjcuMFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgW2luc3RhbmNlU3ltYm9sXSgpIHtcbiAgICAgICAgcmV0dXJuIFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL2kxOG4vbG9jYWxlQEBpbnN0YW5jZVwiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAgICovXG4gICAgZ2V0IGxvY2FsZVN0cmluZygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbbG9jYWxlU3RyaW5nU3ltYm9sXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtzdHJpbmd8dW5kZWZpbmVkfVxuICAgICAqL1xuICAgIGdldCBsYW5ndWFnZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbcHJvcGVydGllc1N5bWJvbF0ubGFuZ3VhZ2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7c3RyaW5nfHVuZGVmaW5lZH1cbiAgICAgKi9cbiAgICBnZXQgcmVnaW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpc1twcm9wZXJ0aWVzU3ltYm9sXS5yZWdpb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7c3RyaW5nfHVuZGVmaW5lZH1cbiAgICAgKi9cbiAgICBnZXQgc2NyaXB0KCkge1xuICAgICAgICByZXR1cm4gdGhpc1twcm9wZXJ0aWVzU3ltYm9sXS5zY3JpcHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7c3RyaW5nfHVuZGVmaW5lZH1cbiAgICAgKi9cbiAgICBnZXQgdmFyaWFudHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzW3Byb3BlcnRpZXNTeW1ib2xdLnZhcmlhbnRzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge3N0cmluZ3x1bmRlZmluZWR9XG4gICAgICovXG4gICAgZ2V0IGV4dGxhbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzW3Byb3BlcnRpZXNTeW1ib2xdLmV4dGxhbmc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7c3RyaW5nfHVuZGVmaW5lZH1cbiAgICAgKi9cbiAgICBnZXQgcHJpdmF0ZVVzZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbcHJvcGVydGllc1N5bWJvbF0ucHJpdmF0ZVZhbHVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge3N0cmluZ31cbiAgICAgKi9cbiAgICB0b1N0cmluZygpIHtcbiAgICAgICAgcmV0dXJuIGAke3RoaXMubG9jYWxlU3RyaW5nfWA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIHN0cnVjdHVyZSBoYXMgdGhlIGZvbGxvd2luZzogbGFuZ3VhZ2UsIHNjcmlwdCwgcmVnaW9uLCB2YXJpYW50cywgZXh0bGFuZywgcHJpdmF0ZVVzZVxuICAgICAqXG4gICAgICogQHJldHVybiB7TW9uc3Rlci5JMThuLkxvY2FsZU1hcH1cbiAgICAgKi9cbiAgICBnZXRNYXAoKSB7XG4gICAgICAgIHJldHVybiBjbG9uZSh0aGlzW3Byb3BlcnRpZXNTeW1ib2xdKTtcbiAgICB9XG59XG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gTG9jYWxlTWFwXG4gKiBAcHJvcGVydHkge3N0cmluZ30gbGFuZ3VhZ2VcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBzY3JpcHRcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSByZWdpb25cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB2YXJpYW50c1xuICogQHByb3BlcnR5IHtzdHJpbmd9IGV4dGxhbmdcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBwcml2YXRlVXNlXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5JMThuXG4gKi9cblxuLyoqXG4gKiBQYXJzZSBsb2NhbCBhY2NvcmRpbmcgdG8gcmZjNDY0NiBzdGFuZGFyZFxuICpcbiAqIExpbWl0YXRpb25zOiBUaGUgcmVnZXggY2Fubm90IGhhbmRsZSBtdWx0aXBsZSB2YXJpYW50cyBvciBwcml2YXRlLlxuICpcbiAqIFlvdSBjYW4gY2FsbCB0aGUgbWV0aG9kIHZpYSB0aGlzIGZ1bmN0aW9uIGluZGl2aWR1YWxseTpcbiAqXG4gKiBgYGBqYXZhc2NyaXB0XG4gKiBpbXBvcnQge2NyZWF0ZUxvY2FsZX0gZnJvbSAnQHNjaHVrYWkvbW9uc3Rlci9zb3VyY2UvaTE4bi9sb2NhbGUubWpzJztcbiAqIGNyZWF0ZUxvY2FsZSgpXG4gKiBgYGBcbiAqXG4gKiBSRkNcbiAqXG4gKiBgYGBcbiAqICAgVGhlIHN5bnRheCBvZiB0aGUgbGFuZ3VhZ2UgdGFnIGluIEFCTkYgW1JGQzQyMzRdIGlzOlxuICpcbiAqICAgTGFuZ3VhZ2UtVGFnICA9IGxhbmd0YWdcbiAqICAgICAgICAgICAgICAgICAvIHByaXZhdGV1c2UgICAgICAgICAgICAgOyBwcml2YXRlIHVzZSB0YWdcbiAqICAgICAgICAgICAgICAgICAvIGdyYW5kZmF0aGVyZWQgICAgICAgICAgOyBncmFuZGZhdGhlcmVkIHJlZ2lzdHJhdGlvbnNcbiAqXG4gKiAgIGxhbmd0YWcgICAgICAgPSAobGFuZ3VhZ2VcbiAqICAgICAgICAgICAgICAgICAgICBbXCItXCIgc2NyaXB0XVxuICogICAgICAgICAgICAgICAgICAgIFtcIi1cIiByZWdpb25dXG4gKiAgICAgICAgICAgICAgICAgICAgKihcIi1cIiB2YXJpYW50KVxuICogICAgICAgICAgICAgICAgICAgICooXCItXCIgZXh0ZW5zaW9uKVxuICogICAgICAgICAgICAgICAgICAgIFtcIi1cIiBwcml2YXRldXNlXSlcbiAqXG4gKiAgIGxhbmd1YWdlICAgICAgPSAoMiozQUxQSEEgWyBleHRsYW5nIF0pIDsgc2hvcnRlc3QgSVNPIDYzOSBjb2RlXG4gKiAgICAgICAgICAgICAgICAgLyA0QUxQSEEgICAgICAgICAgICAgICAgIDsgcmVzZXJ2ZWQgZm9yIGZ1dHVyZSB1c2VcbiAqICAgICAgICAgICAgICAgICAvIDUqOEFMUEhBICAgICAgICAgICAgICAgOyByZWdpc3RlcmVkIGxhbmd1YWdlIHN1YnRhZ1xuICpcbiAqICAgZXh0bGFuZyAgICAgICA9ICozKFwiLVwiIDNBTFBIQSkgICAgICAgICA7IHJlc2VydmVkIGZvciBmdXR1cmUgdXNlXG4gKlxuICogICBzY3JpcHQgICAgICAgID0gNEFMUEhBICAgICAgICAgICAgICAgICA7IElTTyAxNTkyNCBjb2RlXG4gKlxuICogICByZWdpb24gICAgICAgID0gMkFMUEhBICAgICAgICAgICAgICAgICA7IElTTyAzMTY2IGNvZGVcbiAqICAgICAgICAgICAgICAgICAvIDNESUdJVCAgICAgICAgICAgICAgICAgOyBVTiBNLjQ5IGNvZGVcbiAqXG4gKiAgIHZhcmlhbnQgICAgICAgPSA1KjhhbHBoYW51bSAgICAgICAgICAgIDsgcmVnaXN0ZXJlZCB2YXJpYW50c1xuICogICAgICAgICAgICAgICAgIC8gKERJR0lUIDNhbHBoYW51bSlcbiAqXG4gKiAgIGV4dGVuc2lvbiAgICAgPSBzaW5nbGV0b24gMSooXCItXCIgKDIqOGFscGhhbnVtKSlcbiAqXG4gKiAgIHNpbmdsZXRvbiAgICAgPSAleDQxLTU3IC8gJXg1OS01QSAvICV4NjEtNzcgLyAleDc5LTdBIC8gRElHSVRcbiAqICAgICAgICAgICAgICAgICA7IFwiYVwiLVwid1wiIC8gXCJ5XCItXCJ6XCIgLyBcIkFcIi1cIldcIiAvIFwiWVwiLVwiWlwiIC8gXCIwXCItXCI5XCJcbiAqICAgICAgICAgICAgICAgICA7IFNpbmdsZSBsZXR0ZXJzOiB4L1ggaXMgcmVzZXJ2ZWQgZm9yIHByaXZhdGUgdXNlXG4gKlxuICogICBwcml2YXRldXNlICAgID0gKFwieFwiL1wiWFwiKSAxKihcIi1cIiAoMSo4YWxwaGFudW0pKVxuICpcbiAqICAgZ3JhbmRmYXRoZXJlZCA9IDEqM0FMUEhBIDEqMihcIi1cIiAoMio4YWxwaGFudW0pKVxuICogICAgICAgICAgICAgICAgICAgOyBncmFuZGZhdGhlcmVkIHJlZ2lzdHJhdGlvblxuICogICAgICAgICAgICAgICAgICAgOyBOb3RlOiBpIGlzIHRoZSBvbmx5IHNpbmdsZXRvblxuICogICAgICAgICAgICAgICAgICAgOyB0aGF0IHN0YXJ0cyBhIGdyYW5kZmF0aGVyZWQgdGFnXG4gKlxuICogICBhbHBoYW51bSAgICAgID0gKEFMUEhBIC8gRElHSVQpICAgICAgIDsgbGV0dGVycyBhbmQgbnVtYmVyc1xuICpcbiAqICAgICAgICAgICAgICAgICAgICAgICAgRmlndXJlIDE6IExhbmd1YWdlIFRhZyBBQk5GXG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gbG9jYWxlXG4gKiBAcmV0dXJucyB7TG9jYWxlfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4xNC4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuSTE4blxuICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYSBzdHJpbmdcbiAqIEB0aHJvd3Mge0Vycm9yfSB1bnN1cHBvcnRlZCBsb2NhbGVcbiAqL1xuZnVuY3Rpb24gcGFyc2VMb2NhbGUobG9jYWxlKSB7XG4gICAgbG9jYWxlID0gdmFsaWRhdGVTdHJpbmcobG9jYWxlKS5yZXBsYWNlKC9fL2csIFwiLVwiKTtcblxuICAgIGxldCBsYW5ndWFnZTtcbiAgICBsZXQgcmVnaW9uO1xuICAgIGxldCB2YXJpYW50cztcbiAgICBsZXQgcGFydHM7XG4gICAgbGV0IHNjcmlwdDtcbiAgICBsZXQgZXh0bGFuZztcbiAgICBsZXQgcmVnZXhSZWd1bGFyID0gXCIoYXJ0LWxvamJhbnxjZWwtZ2F1bGlzaHxuby1ib2t8bm8tbnlufHpoLWd1b3l1fHpoLWhha2thfHpoLW1pbnx6aC1taW4tbmFufHpoLXhpYW5nKVwiO1xuICAgIGxldCByZWdleElycmVndWxhciA9XG4gICAgICAgIFwiKGVuLUdCLW9lZHxpLWFtaXxpLWJubnxpLWRlZmF1bHR8aS1lbm9jaGlhbnxpLWhha3xpLWtsaW5nb258aS1sdXh8aS1taW5nb3xpLW5hdmFqb3xpLXB3bnxpLXRhb3xpLXRheXxpLXRzdXxzZ24tQkUtRlJ8c2duLUJFLU5MfHNnbi1DSC1ERSlcIjtcbiAgICBsZXQgcmVnZXhHcmFuZGZhdGhlcmVkID0gYCgke3JlZ2V4SXJyZWd1bGFyfXwke3JlZ2V4UmVndWxhcn0pYDtcbiAgICBsZXQgcmVnZXhQcml2YXRlVXNlID0gXCIoeCgtW0EtWmEtejAtOV17MSw4fSkrKVwiO1xuICAgIGxldCByZWdleFNpbmdsZXRvbiA9IFwiWzAtOUEtV1ktWmEtd3ktel1cIjtcbiAgICBsZXQgcmVnZXhFeHRlbnNpb24gPSBgKCR7cmVnZXhTaW5nbGV0b259KC1bQS1aYS16MC05XXsyLDh9KSspYDtcbiAgICBsZXQgcmVnZXhWYXJpYW50ID0gXCIoW0EtWmEtejAtOV17NSw4fXxbMC05XVtBLVphLXowLTldezN9KVwiO1xuICAgIGxldCByZWdleFJlZ2lvbiA9IFwiKFtBLVphLXpdezJ9fFswLTldezN9KVwiO1xuICAgIGxldCByZWdleFNjcmlwdCA9IFwiKFtBLVphLXpdezR9KVwiO1xuICAgIGxldCByZWdleEV4dGxhbmcgPSBcIihbQS1aYS16XXszfSgtW0EtWmEtel17M30pezAsMn0pXCI7XG4gICAgbGV0IHJlZ2V4TGFuZ3VhZ2UgPSBgKChbQS1aYS16XXsyLDN9KC0ke3JlZ2V4RXh0bGFuZ30pPyl8W0EtWmEtel17NH18W0EtWmEtel17NSw4fSlgO1xuICAgIGxldCByZWdleExhbmd0YWcgPSBgKCR7cmVnZXhMYW5ndWFnZX0oLSR7cmVnZXhTY3JpcHR9KT8oLSR7cmVnZXhSZWdpb259KT8oLSR7cmVnZXhWYXJpYW50fSkqKC0ke3JlZ2V4RXh0ZW5zaW9ufSkqKC0ke3JlZ2V4UHJpdmF0ZVVzZX0pPylgO1xuICAgIGxldCByZWdleExhbmd1YWdlVGFnID0gYF4oJHtyZWdleEdyYW5kZmF0aGVyZWR9fCR7cmVnZXhMYW5ndGFnfXwke3JlZ2V4UHJpdmF0ZVVzZX0pJGA7XG4gICAgbGV0IHJlZ2V4ID0gbmV3IFJlZ0V4cChyZWdleExhbmd1YWdlVGFnKTtcbiAgICBsZXQgbWF0Y2g7XG5cbiAgICBpZiAoKG1hdGNoID0gcmVnZXguZXhlYyhsb2NhbGUpKSAhPT0gbnVsbCkge1xuICAgICAgICBpZiAobWF0Y2guaW5kZXggPT09IHJlZ2V4Lmxhc3RJbmRleCkge1xuICAgICAgICAgICAgcmVnZXgubGFzdEluZGV4Kys7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAobWF0Y2ggPT09IHVuZGVmaW5lZCB8fCBtYXRjaCA9PT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1bnN1cHBvcnRlZCBsb2NhbGVcIik7XG4gICAgfVxuXG4gICAgaWYgKG1hdGNoWzZdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgbGFuZ3VhZ2UgPSBtYXRjaFs2XTtcblxuICAgICAgICBwYXJ0cyA9IGxhbmd1YWdlLnNwbGl0KFwiLVwiKTtcbiAgICAgICAgaWYgKHBhcnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgIGxhbmd1YWdlID0gcGFydHNbMF07XG4gICAgICAgICAgICBleHRsYW5nID0gcGFydHNbMV07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAobWF0Y2hbMTRdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmVnaW9uID0gbWF0Y2hbMTRdO1xuICAgIH1cblxuICAgIGlmIChtYXRjaFsxMl0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBzY3JpcHQgPSBtYXRjaFsxMl07XG4gICAgfVxuXG4gICAgaWYgKG1hdGNoWzE2XSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHZhcmlhbnRzID0gbWF0Y2hbMTZdO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgTG9jYWxlKGxhbmd1YWdlLCByZWdpb24sIHNjcmlwdCwgdmFyaWFudHMsIGV4dGxhbmcpO1xufVxuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgZ2V0R2xvYmFsIH0gZnJvbSBcIi4uL3R5cGVzL2dsb2JhbC5tanNcIjtcbmltcG9ydCB7IHZhbGlkYXRlU3RyaW5nIH0gZnJvbSBcIi4uL3R5cGVzL3ZhbGlkYXRlLm1qc1wiO1xuXG5leHBvcnQgeyBnZXREb2N1bWVudCwgZ2V0V2luZG93LCBnZXREb2N1bWVudEZyYWdtZW50RnJvbVN0cmluZywgZmluZEVsZW1lbnRXaXRoSWRVcHdhcmRzLCBnZXRDb250YWluaW5nRG9jdW1lbnQgfTtcblxuLyoqXG4gKiBUaGlzIG1ldGhvZCBmZXRjaGVzIHRoZSBkb2N1bWVudCBvYmplY3RcbiAqXG4gKiBJbiBub2RlanMgdGhpcyBmdW5jdGlvbmFsaXR5IGNhbiBiZSBwZXJmb3JtZWQgd2l0aCBbanNkb21dKGh0dHBzOi8vd3d3Lm5wbWpzLmNvbS9wYWNrYWdlL2pzZG9tKS5cbiAqXG4gKiBgYGBcbiAqIGltcG9ydCB7SlNET019IGZyb20gXCJqc2RvbVwiXG4gKiBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJvYmplY3RcIikge1xuICogICAgY29uc3Qge3dpbmRvd30gPSBuZXcgSlNET00oJycsIHtcbiAqICAgICAgICB1cmw6ICdodHRwOi8vZXhhbXBsZS5jb20vJyxcbiAqICAgICAgICBwcmV0ZW5kVG9CZVZpc3VhbDogdHJ1ZVxuICogICAgfSk7XG4gKlxuICogICAgW1xuICogICAgICAgICdzZWxmJyxcbiAqICAgICAgICAnZG9jdW1lbnQnLFxuICogICAgICAgICdEb2N1bWVudCcsXG4gKiAgICAgICAgJ05vZGUnLFxuICogICAgICAgICdFbGVtZW50JyxcbiAqICAgICAgICAnSFRNTEVsZW1lbnQnLFxuICogICAgICAgICdEb2N1bWVudEZyYWdtZW50JyxcbiAqICAgICAgICAnRE9NUGFyc2VyJyxcbiAqICAgICAgICAnWE1MU2VyaWFsaXplcicsXG4gKiAgICAgICAgJ05vZGVGaWx0ZXInLFxuICogICAgICAgICdJbnB1dEV2ZW50JyxcbiAqICAgICAgICAnQ3VzdG9tRXZlbnQnXG4gKiAgICBdLmZvckVhY2goa2V5ID0+IChnZXRHbG9iYWwoKVtrZXldID0gd2luZG93W2tleV0pKTtcbiAqIH1cbiAqIGBgYFxuICpcbiAqIEByZXR1cm5zIHtvYmplY3R9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjYuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHRocm93cyB7RXJyb3J9IG5vdCBzdXBwb3J0ZWQgZW52aXJvbm1lbnRcbiAqL1xuZnVuY3Rpb24gZ2V0RG9jdW1lbnQoKSB7XG4gICAgbGV0IGRvY3VtZW50ID0gZ2V0R2xvYmFsKCk/LltcImRvY3VtZW50XCJdO1xuICAgIGlmICh0eXBlb2YgZG9jdW1lbnQgIT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwibm90IHN1cHBvcnRlZCBlbnZpcm9ubWVudFwiKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZG9jdW1lbnQ7XG59XG5cbi8qKlxuICogVGhpcyBtZXRob2QgZmV0Y2hlcyB0aGUgd2luZG93IG9iamVjdFxuICpcbiAqIEluIG5vZGVqcyB0aGlzIGZ1bmN0aW9uYWxpdHkgY2FuIGJlIHBlcmZvcm1lZCB3aXRoIFtqc2RvbV0oaHR0cHM6Ly93d3cubnBtanMuY29tL3BhY2thZ2UvanNkb20pLlxuICpcbiAqIGBgYFxuICogaW1wb3J0IHtKU0RPTX0gZnJvbSBcImpzZG9tXCJcbiAqIGlmICh0eXBlb2Ygd2luZG93ICE9PSBcIm9iamVjdFwiKSB7XG4gKiAgICBjb25zdCB7d2luZG93fSA9IG5ldyBKU0RPTSgnJywge1xuICogICAgICAgIHVybDogJ2h0dHA6Ly9leGFtcGxlLmNvbS8nLFxuICogICAgICAgIHByZXRlbmRUb0JlVmlzdWFsOiB0cnVlXG4gKiAgICB9KTtcbiAqXG4gKiAgICBnZXRHbG9iYWwoKVsnd2luZG93J109d2luZG93O1xuICpcbiAqICAgIFtcbiAqICAgICAgICAnc2VsZicsXG4gKiAgICAgICAgJ2RvY3VtZW50JyxcbiAqICAgICAgICAnRG9jdW1lbnQnLFxuICogICAgICAgICdOb2RlJyxcbiAqICAgICAgICAnRWxlbWVudCcsXG4gKiAgICAgICAgJ0hUTUxFbGVtZW50JyxcbiAqICAgICAgICAnRG9jdW1lbnRGcmFnbWVudCcsXG4gKiAgICAgICAgJ0RPTVBhcnNlcicsXG4gKiAgICAgICAgJ1hNTFNlcmlhbGl6ZXInLFxuICogICAgICAgICdOb2RlRmlsdGVyJyxcbiAqICAgICAgICAnSW5wdXRFdmVudCcsXG4gKiAgICAgICAgJ0N1c3RvbUV2ZW50J1xuICogICAgXS5mb3JFYWNoKGtleSA9PiAoZ2V0R2xvYmFsKClba2V5XSA9IHdpbmRvd1trZXldKSk7XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBAcmV0dXJucyB7b2JqZWN0fVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS42LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0aHJvd3Mge0Vycm9yfSBub3Qgc3VwcG9ydGVkIGVudmlyb25tZW50XG4gKi9cbmZ1bmN0aW9uIGdldFdpbmRvdygpIHtcbiAgICBsZXQgd2luZG93ID0gZ2V0R2xvYmFsKCk/LltcIndpbmRvd1wiXTtcbiAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJvYmplY3RcIikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJub3Qgc3VwcG9ydGVkIGVudmlyb25tZW50XCIpO1xuICAgIH1cblxuICAgIHJldHVybiB3aW5kb3c7XG59XG5cbi8qKlxuICogVGhpcyBtZXRob2QgZmV0Y2hlcyB0aGUgZG9jdW1lbnQgb2JqZWN0XG4gKlxuICogSW4gbm9kZWpzIHRoaXMgZnVuY3Rpb25hbGl0eSBjYW4gYmUgcGVyZm9ybWVkIHdpdGggW2pzZG9tXShodHRwczovL3d3dy5ucG1qcy5jb20vcGFja2FnZS9qc2RvbSkuXG4gKlxuICogYGBgXG4gKiBpbXBvcnQge0pTRE9NfSBmcm9tIFwianNkb21cIlxuICogaWYgKHR5cGVvZiB3aW5kb3cgIT09IFwib2JqZWN0XCIpIHtcbiAqICAgIGNvbnN0IHt3aW5kb3d9ID0gbmV3IEpTRE9NKCcnLCB7XG4gKiAgICAgICAgdXJsOiAnaHR0cDovL2V4YW1wbGUuY29tLycsXG4gKiAgICAgICAgcHJldGVuZFRvQmVWaXN1YWw6IHRydWVcbiAqICAgIH0pO1xuICpcbiAqICAgIFtcbiAqICAgICAgICAnc2VsZicsXG4gKiAgICAgICAgJ2RvY3VtZW50JyxcbiAqICAgICAgICAnRG9jdW1lbnQnLFxuICogICAgICAgICdOb2RlJyxcbiAqICAgICAgICAnRWxlbWVudCcsXG4gKiAgICAgICAgJ0hUTUxFbGVtZW50JyxcbiAqICAgICAgICAnRG9jdW1lbnRGcmFnbWVudCcsXG4gKiAgICAgICAgJ0RPTVBhcnNlcicsXG4gKiAgICAgICAgJ1hNTFNlcmlhbGl6ZXInLFxuICogICAgICAgICdOb2RlRmlsdGVyJyxcbiAqICAgICAgICAnSW5wdXRFdmVudCcsXG4gKiAgICAgICAgJ0N1c3RvbUV2ZW50J1xuICogICAgXS5mb3JFYWNoKGtleSA9PiAoZ2V0R2xvYmFsKClba2V5XSA9IHdpbmRvd1trZXldKSk7XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBAcmV0dXJucyB7RG9jdW1lbnRGcmFnbWVudH1cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuNi4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdGhyb3dzIHtFcnJvcn0gbm90IHN1cHBvcnRlZCBlbnZpcm9ubWVudFxuICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYSBzdHJpbmdcbiAqL1xuZnVuY3Rpb24gZ2V0RG9jdW1lbnRGcmFnbWVudEZyb21TdHJpbmcoaHRtbCkge1xuICAgIHZhbGlkYXRlU3RyaW5nKGh0bWwpO1xuXG4gICAgY29uc3QgZG9jdW1lbnQgPSBnZXREb2N1bWVudCgpO1xuICAgIGNvbnN0IHRlbXBsYXRlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInRlbXBsYXRlXCIpO1xuICAgIHRlbXBsYXRlLmlubmVySFRNTCA9IGh0bWw7XG5cbiAgICByZXR1cm4gdGVtcGxhdGUuY29udGVudDtcbn1cblxuLyoqXG4gKiBSZWN1cnNpdmVseSBzZWFyY2hlcyB1cHdhcmRzIGZyb20gYSBnaXZlbiBlbGVtZW50IHRvIGZpbmQgYW4gYW5jZXN0b3IgZWxlbWVudFxuICogd2l0aCBhIHNwZWNpZmllZCBJRCwgY29uc2lkZXJpbmcgYm90aCBub3JtYWwgRE9NIGFuZCBzaGFkb3cgRE9NLlxuICpcbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR8U2hhZG93Um9vdH0gZWxlbWVudCAtIFRoZSBzdGFydGluZyBlbGVtZW50IG9yIHNoYWRvdyByb290IHRvIHNlYXJjaCBmcm9tLlxuICogQHBhcmFtIHtzdHJpbmd9IHRhcmdldElkIC0gVGhlIElEIG9mIHRoZSB0YXJnZXQgZWxlbWVudCB0byBmaW5kLlxuICogQHJldHVybnMge0hUTUxFbGVtZW50fG51bGx9IC0gVGhlIGFuY2VzdG9yIGVsZW1lbnQgd2l0aCB0aGUgc3BlY2lmaWVkIElELCBvciBudWxsIGlmIG5vdCBmb3VuZC5cbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHNpbmNlIDMuMjkuMFxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICovXG5mdW5jdGlvbiBmaW5kRWxlbWVudFdpdGhJZFVwd2FyZHMoZWxlbWVudCwgdGFyZ2V0SWQpIHtcbiAgICBpZiAoIWVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgdGhlIGN1cnJlbnQgZWxlbWVudCBoYXMgdGhlIHRhcmdldCBJRFxuICAgIGlmIChlbGVtZW50LmlkID09PSB0YXJnZXRJZCkge1xuICAgICAgICByZXR1cm4gZWxlbWVudDtcbiAgICB9XG5cbiAgICAvLyBTZWFyY2ggd2l0aGluIHRoZSBjdXJyZW50IGVsZW1lbnQncyBzaGFkb3cgcm9vdCwgaWYgaXQgZXhpc3RzXG4gICAgaWYgKGVsZW1lbnQuc2hhZG93Um9vdCkge1xuICAgICAgICBjb25zdCB0YXJnZXQgPSBlbGVtZW50LnNoYWRvd1Jvb3QuZ2V0RWxlbWVudEJ5SWQodGFyZ2V0SWQpO1xuICAgICAgICBpZiAodGFyZ2V0KSB7XG4gICAgICAgICAgICByZXR1cm4gdGFyZ2V0O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gSWYgdGhlIGN1cnJlbnQgZWxlbWVudCBpcyB0aGUgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LCBzZWFyY2ggd2l0aGluIHRoZSBtYWluIGRvY3VtZW50XG4gICAgaWYgKGVsZW1lbnQgPT09IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCkge1xuICAgICAgICBjb25zdCB0YXJnZXQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0YXJnZXRJZCk7XG4gICAgICAgIGlmICh0YXJnZXQpIHtcbiAgICAgICAgICAgIHJldHVybiB0YXJnZXQ7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBJZiB0aGUgY3VycmVudCBlbGVtZW50IGlzIGluc2lkZSBhIHNoYWRvdyByb290LCBzZWFyY2ggaXRzIGhvc3QncyBhbmNlc3RvcnNcbiAgICBjb25zdCByb290Tm9kZSA9IGVsZW1lbnQuZ2V0Um9vdE5vZGUoKTtcbiAgICBpZiAocm9vdE5vZGUgJiYgcm9vdE5vZGUgaW5zdGFuY2VvZiBTaGFkb3dSb290KSB7XG4gICAgICAgIHJldHVybiBmaW5kRWxlbWVudFdpdGhJZFVwd2FyZHMocm9vdE5vZGUuaG9zdCwgdGFyZ2V0SWQpO1xuICAgIH1cblxuICAgIC8vIE90aGVyd2lzZSwgc2VhcmNoIHRoZSBjdXJyZW50IGVsZW1lbnQncyBwYXJlbnRcbiAgICByZXR1cm4gZmluZEVsZW1lbnRXaXRoSWRVcHdhcmRzKGVsZW1lbnQucGFyZW50RWxlbWVudCwgdGFyZ2V0SWQpO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gKiBAcmV0dXJucyB7SFRNTEVsZW1lbnR8bnVsbH1cbiAqL1xuZnVuY3Rpb24gdHJhdmVyc2VTaGFkb3dSb290cyhlbGVtZW50KSB7XG4gICAgbGV0IGN1cnJlbnRSb290ID0gZWxlbWVudC5zaGFkb3dSb290O1xuICAgIGxldCBjdXJyZW50UGFyZW50ID0gZWxlbWVudC5wYXJlbnROb2RlO1xuXG4gICAgd2hpbGUgKFxuICAgICAgICBjdXJyZW50UGFyZW50ICYmXG4gICAgICAgIGN1cnJlbnRQYXJlbnQubm9kZVR5cGUgIT09IE5vZGUuRE9DVU1FTlRfTk9ERSAmJlxuICAgICAgICBjdXJyZW50UGFyZW50Lm5vZGVUeXBlICE9PSBOb2RlLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREVcbiAgICApIHtcbiAgICAgICAgaWYgKGN1cnJlbnRSb290ICYmIGN1cnJlbnRSb290LnBhcmVudE5vZGUpIHtcbiAgICAgICAgICAgIGN1cnJlbnRQYXJlbnQgPSBjdXJyZW50Um9vdC5wYXJlbnROb2RlO1xuICAgICAgICAgICAgY3VycmVudFJvb3QgPSBjdXJyZW50UGFyZW50LnNoYWRvd1Jvb3Q7XG4gICAgICAgIH0gZWxzZSBpZiAoY3VycmVudFBhcmVudC5wYXJlbnROb2RlKSB7XG4gICAgICAgICAgICBjdXJyZW50UGFyZW50ID0gY3VycmVudFBhcmVudC5wYXJlbnROb2RlO1xuICAgICAgICAgICAgY3VycmVudFJvb3QgPSBudWxsO1xuICAgICAgICB9IGVsc2UgaWYgKGN1cnJlbnRSb290ICYmIGN1cnJlbnRSb290Lmhvc3QgJiYgY3VycmVudFJvb3QuaG9zdC5ub2RlVHlwZSA9PT0gTm9kZS5ET0NVTUVOVF9OT0RFKSB7XG4gICAgICAgICAgICBjdXJyZW50UGFyZW50ID0gY3VycmVudFJvb3QuaG9zdDtcbiAgICAgICAgICAgIGN1cnJlbnRSb290ID0gbnVsbDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGN1cnJlbnRQYXJlbnQgPSBudWxsO1xuICAgICAgICAgICAgY3VycmVudFJvb3QgPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGN1cnJlbnRQYXJlbnQ7XG59XG5cbi8qKlxuICogUmVjdXJzaXZlbHkgc2VhcmNoZXMgdXB3YXJkcyBmcm9tIGEgZ2l2ZW4gZWxlbWVudCB0byBmaW5kIGFuIGFuY2VzdG9yIGVsZW1lbnRcbiAqXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gKiBAcmV0dXJucyB7Kn1cbiAqIEB0aHJvd3Mge0Vycm9yfSBJbnZhbGlkIGFyZ3VtZW50LiBFeHBlY3RlZCBhbiBIVE1MRWxlbWVudC5cbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHNpbmNlIDMuMzYuMFxuICovXG5mdW5jdGlvbiBnZXRDb250YWluaW5nRG9jdW1lbnQoZWxlbWVudCkge1xuICAgIGlmIChcbiAgICAgICAgIWVsZW1lbnQgfHxcbiAgICAgICAgIShlbGVtZW50IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQgfHwgZWxlbWVudCBpbnN0YW5jZW9mIGVsZW1lbnQub3duZXJEb2N1bWVudC5kZWZhdWx0Vmlldy5IVE1MRWxlbWVudClcbiAgICApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBhcmd1bWVudC4gRXhwZWN0ZWQgYW4gSFRNTEVsZW1lbnQuXCIpO1xuICAgIH1cblxuICAgIHJldHVybiB0cmF2ZXJzZVNoYWRvd1Jvb3RzKGVsZW1lbnQpIHx8IG51bGw7XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBwYXJzZUxvY2FsZSB9IGZyb20gXCIuLi9pMThuL2xvY2FsZS5tanNcIjtcbmltcG9ydCB7IGdldERvY3VtZW50IH0gZnJvbSBcIi4vdXRpbC5tanNcIjtcbmltcG9ydCB7IGdldEdsb2JhbE9iamVjdCB9IGZyb20gXCIuLi90eXBlcy9nbG9iYWwubWpzXCI7XG5cbmV4cG9ydCB7IGdldExvY2FsZU9mRG9jdW1lbnQgfTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuY29uc3QgREVGQVVMVF9MQU5HVUFHRSA9IFwiZW5cIjtcblxuLyoqXG4gKiBXaXRoIHRoaXMgZnVuY3Rpb24geW91IGNhbiByZWFkIHRoZSBsYW5ndWFnZSB2ZXJzaW9uIHNldCBieSB0aGUgZG9jdW1lbnQuXG4gKiBGb3IgdGhpcyB0aGUgYXR0cmlidXRlIGBsYW5nYCBpbiB0aGUgaHRtbCB0YWcgaXMgcmVhZC4gSWYgbm8gYXR0cmlidXRlIGlzIHNldCwgYGVuYCBpcyB1c2VkIGFzIGRlZmF1bHQuXG4gKiBBbHRlcm5hdGl2ZWx5LCB0aGUgbGFuZ3VhZ2UgdmVyc2lvbiBvZiB0aGUgYnJvd3NlciBpcyB1c2VkLlxuICpcbiAqIGBgYGh0bWxcbiAqIDxodG1sIGxhbmc9XCJlblwiPlxuICogYGBgXG4gKlxuICogWW91IGNhbiBjYWxsIHRoZSBmdW5jdGlvbiB2aWEgYGdldExvY2FsZU9mRG9jdW1lbnQoKWAuXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4xMy4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIHN0cmluZ1xuICogQHRocm93cyB7RXJyb3J9IHVuc3VwcG9ydGVkIGxvY2FsZVxuICogQHN1bW1hcnkgVHJpZXMgdG8gZGV0ZXJtaW5lIHRoZSBsb2NhbGUgdXNlZFxuICovXG5mdW5jdGlvbiBnZXRMb2NhbGVPZkRvY3VtZW50KCkge1xuICAgIGNvbnN0IGRvY3VtZW50ID0gZ2V0RG9jdW1lbnQoKTtcblxuICAgIGxldCBodG1sID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcImh0bWxcIik7XG4gICAgaWYgKGh0bWwgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCAmJiBodG1sLmhhc0F0dHJpYnV0ZShcImxhbmdcIikpIHtcbiAgICAgICAgbGV0IGxvY2FsZSA9IGh0bWwuZ2V0QXR0cmlidXRlKFwibGFuZ1wiKTtcbiAgICAgICAgaWYgKGxvY2FsZSkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBwYXJzZUxvY2FsZShsb2NhbGUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbGV0IG5hdmlnYXRvckxhbmd1YWdlID0gZ2V0TmF2aWdhdG9yTGFuZ3VhZ2UoKTtcbiAgICBpZiAobmF2aWdhdG9yTGFuZ3VhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHBhcnNlTG9jYWxlKG5hdmlnYXRvckxhbmd1YWdlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcGFyc2VMb2NhbGUoREVGQVVMVF9MQU5HVUFHRSk7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEByZXR1cm5zIHtzdHJpbmd8dW5kZWZpbmVkfCp9XG4gKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9OYXZpZ2F0b3IvbGFuZ3VhZ2VcbiAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL05hdmlnYXRvci9sYW5ndWFnZXNcbiAqL1xuY29uc3QgZ2V0TmF2aWdhdG9yTGFuZ3VhZ2UgPSAoKSA9PiB7XG4gICAgY29uc3QgbmF2aWdhdG9yID0gZ2V0R2xvYmFsT2JqZWN0KFwibmF2aWdhdG9yXCIpO1xuICAgIGlmIChuYXZpZ2F0b3IgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGlmIChuYXZpZ2F0b3IuaGFzT3duUHJvcGVydHkoXCJsYW5ndWFnZVwiKSkge1xuICAgICAgICBjb25zdCBsYW5ndWFnZSA9IG5hdmlnYXRvci5sYW5ndWFnZTtcbiAgICAgICAgaWYgKHR5cGVvZiBsYW5ndWFnZSA9PT0gXCJzdHJpbmdcIiAmJiBsYW5ndWFnZS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICByZXR1cm4gbGFuZ3VhZ2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBsYW5ndWFnZXMgPSBuYXZpZ2F0b3I/Lmxhbmd1YWdlcztcbiAgICBpZiAoQXJyYXkuaXNBcnJheShsYW5ndWFnZXMpICYmIGxhbmd1YWdlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJldHVybiBsYW5ndWFnZXNbMF07XG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbn07XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBCYXNlIH0gZnJvbSBcIi4vYmFzZS5tanNcIjtcbmltcG9ydCB7IHZhbGlkYXRlU3RyaW5nIH0gZnJvbSBcIi4vdmFsaWRhdGUubWpzXCI7XG5cbmV4cG9ydCB7IElEIH07XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEB0eXBlIHtNYXA8c3RyaW5nLCBpbnRlZ2VyPn1cbiAqL1xubGV0IGludGVybmFsQ291bnRlciA9IG5ldyBNYXAoKTtcblxuLyoqXG4gKiBXaXRoIHRoZSBpZCBjbGFzcywgc2VxdWVuY2VzIG9mIGlkcyBjYW4gYmUgY3JlYXRlZC4gZm9yIHRoaXMgcHVycG9zZSwgYW4gaW50ZXJuYWwgY291bnRlciBpcyBpbmNyZW1lbnRlZCBmb3IgZWFjaCBwcmVmaXguXG4gKiB0aHVzLCB0aGUgZmlyc3QgaWQgd2l0aCB0aGUgcHJlZml4IGBteWlkYCB3aWxsIGJlIGBteWlkMWAgYW5kIHRoZSBzZWNvbmQgaWQgYG15aWQyYC5cbiAqIFRoZSBpZHMgYXJlIHRoZSBzYW1lIGZvciBldmVyeSBjYWxsLCBmb3IgZXhhbXBsZSBvbiBhIHdlYiBwYWdlLlxuICpcbiAqIFNvIHRoZSBpZHMgY2FuIGFsc28gYmUgdXNlZCBmb3IgbmF2aWdhdGlvbi4geW91IGp1c3QgaGF2ZSB0byB0YWtlIGNhcmUgdGhhdCB0aGUgb3JkZXIgc3RheXMgdGhlIHNhbWUuXG4gKlxuICogQXMgb2YgdmVyc2lvbiAxLjYuMCB0aGVyZSBpcyB0aGUgbmV3IFJhbmRvbUlELiB0aGlzIElEIGNsYXNzIGlzIGNvbnRpbnVvdXMgZnJvbSBub3cgb24uXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4wLjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UeXBlc1xuICogQHN1bW1hcnkgQXV0b21hdGljIGdlbmVyYXRpb24gb2YgaWRzXG4gKi9cbmNsYXNzIElEIGV4dGVuZHMgQmFzZSB7XG4gICAgLyoqXG4gICAgICogY3JlYXRlIG5ldyBpZCB3aXRoIHByZWZpeFxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHByZWZpeFxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHByZWZpeCkge1xuICAgICAgICBzdXBlcigpO1xuXG4gICAgICAgIGlmIChwcmVmaXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcHJlZml4ID0gXCJpZFwiO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFsaWRhdGVTdHJpbmcocHJlZml4KTtcblxuICAgICAgICBpZiAoIWludGVybmFsQ291bnRlci5oYXMocHJlZml4KSkge1xuICAgICAgICAgICAgaW50ZXJuYWxDb3VudGVyLnNldChwcmVmaXgsIDEpO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGNvdW50ID0gaW50ZXJuYWxDb3VudGVyLmdldChwcmVmaXgpO1xuICAgICAgICB0aGlzLmlkID0gcHJlZml4ICsgY291bnQ7XG5cbiAgICAgICAgaW50ZXJuYWxDb3VudGVyLnNldChwcmVmaXgsICsrY291bnQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge3N0cmluZ31cbiAgICAgKi9cbiAgICB0b1N0cmluZygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaWQ7XG4gICAgfVxufVxuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgaXNJdGVyYWJsZSwgaXNTdHJpbmcgfSBmcm9tIFwiLi4vdHlwZXMvaXMubWpzXCI7XG5pbXBvcnQgeyB2YWxpZGF0ZUZ1bmN0aW9uLCB2YWxpZGF0ZVN0cmluZyB9IGZyb20gXCIuLi90eXBlcy92YWxpZGF0ZS5tanNcIjtcbmltcG9ydCB7IEJhc2UgfSBmcm9tIFwiLi9iYXNlLm1qc1wiO1xuXG5leHBvcnQgeyBUb2tlbkxpc3QgfTtcblxuLyoqXG4gKiBBIGBUb2tlbkxpc3RgIGFsbG93cyB5b3UgdG8gbWFuYWdlIHRva2VucyAoaW5kaXZpZHVhbCBjaGFyYWN0ZXIgc3RyaW5ncyBzdWNoIGFzIGNzcyBjbGFzc2VzIGluIGFuIGF0dHJpYnV0ZSBzdHJpbmcpLlxuICpcbiAqIFRoZSBgVG9rZW5MaXN0YCBvZmZlcnMgdmFyaW91cyBmdW5jdGlvbnMgdG8gbWFuaXB1bGF0ZSB2YWx1ZXMuIEZvciBleGFtcGxlLCB5b3UgY2FuIGFkZCwgcmVtb3ZlIG9yIHJlcGxhY2UgYSBjbGFzcyBpbiBhIENTUyBsaXN0LlxuICpcbiAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyB0aGUgW2l0ZXJhdGlvbiBwcm90b2NvbF0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvSXRlcmF0aW9uX3Byb3RvY29scykuXG4gKlxuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL3R5cGVzL3Rva2VubGlzdC0xLm1qc1xuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yLjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UeXBlc1xuICovXG5jbGFzcyBUb2tlbkxpc3QgZXh0ZW5kcyBCYXNlIHtcbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7YXJyYXl8c3RyaW5nfGl0ZXJhdGFibGV9IGluaXRcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcihpbml0KSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMudG9rZW5zID0gbmV3IFNldCgpO1xuXG4gICAgICAgIGlmICh0eXBlb2YgaW5pdCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgdGhpcy5hZGQoaW5pdCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJdGVyYXRvciBwcm90b2NvbFxuICAgICAqXG4gICAgICogQHJldHVybnMge1N5bWJvbC5pdGVyYXRvcn1cbiAgICAgKi9cbiAgICBnZXRJdGVyYXRvcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbU3ltYm9sLml0ZXJhdG9yXSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEl0ZXJhdG9yXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7e25leHQ6ICgoZnVuY3Rpb24oKTogKHt2YWx1ZTogKiwgZG9uZTogYm9vbGVhbn0pKXwqKX19XG4gICAgICovXG4gICAgW1N5bWJvbC5pdGVyYXRvcl0oKSB7XG4gICAgICAgIC8vIFVzZSBhIG5ldyBpbmRleCBmb3IgZWFjaCBpdGVyYXRvci4gVGhpcyBtYWtlcyBtdWx0aXBsZVxuICAgICAgICAvLyBpdGVyYXRpb25zIG92ZXIgdGhlIGl0ZXJhYmxlIHNhZmUgZm9yIG5vbi10cml2aWFsIGNhc2VzLFxuICAgICAgICAvLyBzdWNoIGFzIHVzZSBvZiBicmVhayBvciBuZXN0ZWQgbG9vcGluZyBvdmVyIHRoZSBzYW1lIGl0ZXJhYmxlLlxuICAgICAgICBsZXQgaW5kZXggPSAwO1xuICAgICAgICBsZXQgZW50cmllcyA9IHRoaXMuZW50cmllcygpO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBuZXh0OiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGluZGV4IDwgZW50cmllcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsgdmFsdWU6IGVudHJpZXM/LltpbmRleCsrXSwgZG9uZTogZmFsc2UgfTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4geyBkb25lOiB0cnVlIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRydWUgaWYgaXQgY29udGFpbnMgdG9rZW4sIG90aGVyd2lzZSBmYWxzZVxuICAgICAqXG4gICAgICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL3R5cGVzL3Rva2VubGlzdC0yLm1qc1xuICAgICAqIEBwYXJhbSB7YXJyYXl8c3RyaW5nfGl0ZXJhdGFibGV9IHZhbHVlXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAgICovXG4gICAgY29udGFpbnModmFsdWUpIHtcbiAgICAgICAgaWYgKGlzU3RyaW5nKHZhbHVlKSkge1xuICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS50cmltKCk7XG4gICAgICAgICAgICBsZXQgY291bnRlciA9IDA7XG4gICAgICAgICAgICB2YWx1ZS5zcGxpdChcIiBcIikuZm9yRWFjaCgodG9rZW4pID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy50b2tlbnMuaGFzKHRva2VuLnRyaW0oKSkgPT09IGZhbHNlKSByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgY291bnRlcisrO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gY291bnRlciA+IDAgPyB0cnVlIDogZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNJdGVyYWJsZSh2YWx1ZSkpIHtcbiAgICAgICAgICAgIGxldCBjb3VudGVyID0gMDtcbiAgICAgICAgICAgIGZvciAobGV0IHRva2VuIG9mIHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgdmFsaWRhdGVTdHJpbmcodG9rZW4pO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnRva2Vucy5oYXModG9rZW4udHJpbSgpKSA9PT0gZmFsc2UpIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICBjb3VudGVyKys7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gY291bnRlciA+IDAgPyB0cnVlIDogZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkIHRva2Vuc1xuICAgICAqXG4gICAgICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL3R5cGVzL3Rva2VubGlzdC0zLm1qc1xuICAgICAqIEBwYXJhbSB7YXJyYXl8c3RyaW5nfGl0ZXJhdGFibGV9IHZhbHVlXG4gICAgICogQHJldHVybnMge1Rva2VuTGlzdH1cbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHVuc3VwcG9ydGVkIHZhbHVlXG4gICAgICovXG4gICAgYWRkKHZhbHVlKSB7XG4gICAgICAgIGlmIChpc1N0cmluZyh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHZhbHVlLnNwbGl0KFwiIFwiKS5mb3JFYWNoKCh0b2tlbikgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMudG9rZW5zLmFkZCh0b2tlbi50cmltKCkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNJdGVyYWJsZSh2YWx1ZSkpIHtcbiAgICAgICAgICAgIGZvciAobGV0IHRva2VuIG9mIHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgdmFsaWRhdGVTdHJpbmcodG9rZW4pO1xuICAgICAgICAgICAgICAgIHRoaXMudG9rZW5zLmFkZCh0b2tlbi50cmltKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInVuc3VwcG9ydGVkIHZhbHVlXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogcmVtb3ZlIGFsbCB0b2tlbnNcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtUb2tlbkxpc3R9XG4gICAgICovXG4gICAgY2xlYXIoKSB7XG4gICAgICAgIHRoaXMudG9rZW5zLmNsZWFyKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgdG9rZW5cbiAgICAgKlxuICAgICAqIEBleHRlcm5hbEV4YW1wbGUgLi4vLi4vZXhhbXBsZS90eXBlcy90b2tlbmxpc3QtNC5tanNcbiAgICAgKiBAcGFyYW0ge2FycmF5fHN0cmluZ3xpdGVyYXRhYmxlfSB2YWx1ZVxuICAgICAqIEByZXR1cm5zIHtUb2tlbkxpc3R9XG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSB1bnN1cHBvcnRlZCB2YWx1ZVxuICAgICAqL1xuICAgIHJlbW92ZSh2YWx1ZSkge1xuICAgICAgICBpZiAoaXNTdHJpbmcodmFsdWUpKSB7XG4gICAgICAgICAgICB2YWx1ZS5zcGxpdChcIiBcIikuZm9yRWFjaCgodG9rZW4pID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnRva2Vucy5kZWxldGUodG9rZW4udHJpbSgpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKGlzSXRlcmFibGUodmFsdWUpKSB7XG4gICAgICAgICAgICBmb3IgKGxldCB0b2tlbiBvZiB2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHZhbGlkYXRlU3RyaW5nKHRva2VuKTtcbiAgICAgICAgICAgICAgICB0aGlzLnRva2Vucy5kZWxldGUodG9rZW4udHJpbSgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJ1bnN1cHBvcnRlZCB2YWx1ZVwiLCBcInR5cGVzL3Rva2VubGlzdC5tanNcIik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiB0aGlzIG1ldGhvZCByZXBsYWNlcyBhIHRva2VuIHdpdGggYSBuZXcgdG9rZW4uXG4gICAgICpcbiAgICAgKiBpZiB0aGUgcGFzc2VkIHRva2VuIGV4aXN0cywgaXQgaXMgcmVwbGFjZWQgd2l0aCBuZXdUb2tlbiBhbmQgVG9rZW5MaXN0IGlzIHJldHVybmVkLlxuICAgICAqIGlmIHRoZSB0b2tlbiBkb2VzIG5vdCBleGlzdCwgbmV3VG9rZW4gaXMgbm90IHNldCBhbmQgVG9rZW5MaXN0IGlzIHJldHVybmVkLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHRva2VuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5ld1Rva2VuXG4gICAgICogQHJldHVybnMge1Rva2VuTGlzdH1cbiAgICAgKi9cbiAgICByZXBsYWNlKHRva2VuLCBuZXdUb2tlbikge1xuICAgICAgICB2YWxpZGF0ZVN0cmluZyh0b2tlbik7XG4gICAgICAgIHZhbGlkYXRlU3RyaW5nKG5ld1Rva2VuKTtcbiAgICAgICAgaWYgKCF0aGlzLmNvbnRhaW5zKHRva2VuKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgYSA9IEFycmF5LmZyb20odGhpcy50b2tlbnMpO1xuICAgICAgICBsZXQgaSA9IGEuaW5kZXhPZih0b2tlbik7XG4gICAgICAgIGlmIChpID09PSAtMSkgcmV0dXJuIHRoaXM7XG5cbiAgICAgICAgYS5zcGxpY2UoaSwgMSwgbmV3VG9rZW4pO1xuICAgICAgICB0aGlzLnRva2VucyA9IG5ldyBTZXQoKTtcbiAgICAgICAgdGhpcy5hZGQoYSk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyB0b2tlbiBmcm9tIHN0cmluZy4gSWYgdG9rZW4gZG9lc24ndCBleGlzdCBpdCdzIGFkZGVkLlxuICAgICAqXG4gICAgICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL3R5cGVzL3Rva2VubGlzdC01Lm1qc1xuICAgICAqIEBwYXJhbSB7YXJyYXl8c3RyaW5nfGl0ZXJhdGFibGV9IHZhbHVlXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSB1bnN1cHBvcnRlZCB2YWx1ZVxuICAgICAqL1xuICAgIHRvZ2dsZSh2YWx1ZSkge1xuICAgICAgICBpZiAoaXNTdHJpbmcodmFsdWUpKSB7XG4gICAgICAgICAgICB2YWx1ZS5zcGxpdChcIiBcIikuZm9yRWFjaCgodG9rZW4pID0+IHtcbiAgICAgICAgICAgICAgICB0b2dnbGVWYWx1ZS5jYWxsKHRoaXMsIHRva2VuKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKGlzSXRlcmFibGUodmFsdWUpKSB7XG4gICAgICAgICAgICBmb3IgKGxldCB0b2tlbiBvZiB2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHRvZ2dsZVZhbHVlLmNhbGwodGhpcywgdG9rZW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInVuc3VwcG9ydGVkIHZhbHVlXCIsIFwidHlwZXMvdG9rZW5saXN0Lm1qc1wiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHJldHVybnMgYW4gYXJyYXkgd2l0aCBhbGwgdG9rZW5zXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7YXJyYXl9XG4gICAgICovXG4gICAgZW50cmllcygpIHtcbiAgICAgICAgcmV0dXJuIEFycmF5LmZyb20odGhpcy50b2tlbnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIGV4ZWN1dGVzIHRoZSBwcm92aWRlZCBmdW5jdGlvbiB3aXRoIGVhY2ggdmFsdWUgb2YgdGhlIHNldFxuICAgICAqXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2tcbiAgICAgKiBAcmV0dXJucyB7VG9rZW5MaXN0fVxuICAgICAqL1xuICAgIGZvckVhY2goY2FsbGJhY2spIHtcbiAgICAgICAgdmFsaWRhdGVGdW5jdGlvbihjYWxsYmFjayk7XG4gICAgICAgIHRoaXMudG9rZW5zLmZvckVhY2goY2FsbGJhY2spO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiByZXR1cm5zIHRoZSBpbmRpdmlkdWFsIHRva2VucyBzZXBhcmF0ZWQgYnkgYSBibGFuayBjaGFyYWN0ZXJcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAgICovXG4gICAgdG9TdHJpbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVudHJpZXMoKS5qb2luKFwiIFwiKTtcbiAgICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB0b2tlblxuICogQHJldHVybnMge3RvZ2dsZVZhbHVlfVxuICogQHRocm93cyB7RXJyb3J9IG11c3QgYmUgY2FsbGVkIHdpdGggVG9rZW5MaXN0LmNhbGxcbiAqL1xuZnVuY3Rpb24gdG9nZ2xlVmFsdWUodG9rZW4pIHtcbiAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgVG9rZW5MaXN0KSkgdGhyb3cgRXJyb3IoXCJtdXN0IGJlIGNhbGxlZCB3aXRoIFRva2VuTGlzdC5jYWxsXCIpO1xuICAgIHZhbGlkYXRlU3RyaW5nKHRva2VuKTtcbiAgICB0b2tlbiA9IHRva2VuLnRyaW0oKTtcbiAgICBpZiAodGhpcy5jb250YWlucyh0b2tlbikpIHtcbiAgICAgICAgdGhpcy5yZW1vdmUodG9rZW4pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgdGhpcy5hZGQodG9rZW4pO1xuICAgIHJldHVybiB0aGlzO1xufVxuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuZXhwb3J0IHtcbiAgICBERUZBVUxUX1RIRU1FLFxuICAgIEFUVFJJQlVURV9QUkVGSVgsXG4gICAgQVRUUklCVVRFX09QVElPTlMsXG4gICAgQVRUUklCVVRFX09QVElPTlNfU0VMRUNUT1IsXG4gICAgQVRUUklCVVRFX1RIRU1FX1BSRUZJWCxcbiAgICBBVFRSSUJVVEVfVEhFTUVfTkFNRSxcbiAgICBBVFRSSUJVVEVfVVBEQVRFUl9BVFRSSUJVVEVTLFxuICAgIEFUVFJJQlVURV9VUERBVEVSX1NFTEVDVF9USElTLFxuICAgIEFUVFJJQlVURV9VUERBVEVSX1JFUExBQ0UsXG4gICAgQVRUUklCVVRFX1VQREFURVJfSU5TRVJULFxuICAgIEFUVFJJQlVURV9VUERBVEVSX0lOU0VSVF9SRUZFUkVOQ0UsXG4gICAgQVRUUklCVVRFX1VQREFURVJfUkVNT1ZFLFxuICAgIEFUVFJJQlVURV9VUERBVEVSX0JJTkQsXG4gICAgQVRUUklCVVRFX1RFTVBMQVRFX1BSRUZJWCxcbiAgICBBVFRSSUJVVEVfUk9MRSxcbiAgICBBVFRSSUJVVEVfRElTQUJMRUQsXG4gICAgQVRUUklCVVRFX1ZBTFVFLFxuICAgIEFUVFJJQlVURV9PQkpFQ1RMSU5LLFxuICAgIEFUVFJJQlVURV9FUlJPUk1FU1NBR0UsXG4gICAgVEFHX1NDUklQVCxcbiAgICBUQUdfU1RZTEUsXG4gICAgVEFHX0xJTkssXG4gICAgQVRUUklCVVRFX0lELFxuICAgIEFUVFJJQlVURV9DTEFTUyxcbiAgICBBVFRSSUJVVEVfVElUTEUsXG4gICAgQVRUUklCVVRFX1NSQyxcbiAgICBBVFRSSUJVVEVfSFJFRixcbiAgICBBVFRSSUJVVEVfVFlQRSxcbiAgICBBVFRSSUJVVEVfTk9OQ0UsXG4gICAgQVRUUklCVVRFX1RSQU5TTEFURSxcbiAgICBBVFRSSUJVVEVfVEFCSU5ERVgsXG4gICAgQVRUUklCVVRFX1NQRUxMQ0hFQ0ssXG4gICAgQVRUUklCVVRFX1NMT1QsXG4gICAgQVRUUklCVVRFX1BBUlQsXG4gICAgQVRUUklCVVRFX0xBTkcsXG4gICAgQVRUUklCVVRFX0lURU1UWVBFLFxuICAgIEFUVFJJQlVURV9JVEVNU0NPUEUsXG4gICAgQVRUUklCVVRFX0lURU1SRUYsXG4gICAgQVRUUklCVVRFX0lURU1JRCxcbiAgICBBVFRSSUJVVEVfSVRFTVBST1AsXG4gICAgQVRUUklCVVRFX0lTLFxuICAgIEFUVFJJQlVURV9JTlBVVE1PREUsXG4gICAgQVRUUklCVVRFX0FDQ0VTU0tFWSxcbiAgICBBVFRSSUJVVEVfQVVUT0NBUElUQUxJWkUsXG4gICAgQVRUUklCVVRFX0FVVE9GT0NVUyxcbiAgICBBVFRSSUJVVEVfQ09OVEVOVEVESVRBQkxFLFxuICAgIEFUVFJJQlVURV9ESVIsXG4gICAgQVRUUklCVVRFX0RSQUdHQUJMRSxcbiAgICBBVFRSSUJVVEVfRU5URVJLRVlISU5ULFxuICAgIEFUVFJJQlVURV9FWFBPUlRQQVJUUyxcbiAgICBBVFRSSUJVVEVfSElEREVOLFxuICAgIG9iamVjdFVwZGF0ZXJMaW5rU3ltYm9sLFxuICAgIGN1c3RvbUVsZW1lbnRVcGRhdGVyTGlua1N5bWJvbCxcbiAgICBpbml0Q29udHJvbENhbGxiYWNrTmFtZSxcbiAgICBBVFRSSUJVVEVfU0NSSVBUX0hPU1QsXG4gICAgQVRUUklCVVRFX0lOSVRfQ0FMTEJBQ0ssXG59O1xuXG4vKipcbiAqIGRlZmF1bHQgdGhlbWVcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuY29uc3QgREVGQVVMVF9USEVNRSA9IFwibW9uc3RlclwiO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS44LjBcbiAqIEB0eXBlIHtzdHJpbmd9XG4gKi9cbmNvbnN0IEFUVFJJQlVURV9QUkVGSVggPSBcImRhdGEtbW9uc3Rlci1cIjtcblxuLyoqXG4gKiBUaGlzIGlzIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgdG8gcGFzcyBvcHRpb25zIHRvIGEgY29udHJvbFxuICpcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS44LjBcbiAqIEB0eXBlIHtzdHJpbmd9XG4gKi9cbmNvbnN0IEFUVFJJQlVURV9PUFRJT05TID0gYCR7QVRUUklCVVRFX1BSRUZJWH1vcHRpb25zYDtcblxuLyoqXG4gKiBUaGlzIGlzIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZSB0byBwYXNzIHRoZSBzY3JpcHQgaG9zdCB0byBhIGNvbnRyb2xcbiAqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDMuNDguMFxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuY29uc3QgQVRUUklCVVRFX1NDUklQVF9IT1NUID0gYCR7QVRUUklCVVRFX1BSRUZJWH1zY3JpcHQtaG9zdGA7XG5cbi8qKlxuICogVGhpcyBpcyB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlIHRvIHBhc3Mgb3B0aW9ucyB0byBhIGNvbnRyb2xcbiAqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMzAuMFxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuY29uc3QgQVRUUklCVVRFX09QVElPTlNfU0VMRUNUT1IgPSBgJHtBVFRSSUJVVEVfUFJFRklYfW9wdGlvbnMtc2VsZWN0b3JgO1xuXG4vKipcbiAqIFRoaXMgaXMgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZSB0byBwYXNzIHRoZSBjYWxsYmFjayB0byBhIGNvbnRyb2xcbiAqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDMuNDguMFxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuY29uc3QgQVRUUklCVVRFX0lOSVRfQ0FMTEJBQ0sgPSBgJHtBVFRSSUJVVEVfUFJFRklYfWluaXQtY2FsbGJhY2tgO1xuXG4vKipcbiAqIFRoaXMgaXMgdGhlIG5hbWUgb2YgdGhlIGNhbGxiYWNrIHRvIHBhc3MgdGhlIGNhbGxiYWNrIHRvIGEgY29udHJvbFxuICpcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMy40OC4wXG4gKiBAdHlwZSB7c3RyaW5nfVxuICovXG5jb25zdCBpbml0Q29udHJvbENhbGxiYWNrTmFtZSA9IGBpbml0Q3VzdG9tQ29udHJvbENhbGxiYWNrYDtcblxuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjguMFxuICovXG5jb25zdCBBVFRSSUJVVEVfVEhFTUVfUFJFRklYID0gYCR7QVRUUklCVVRFX1BSRUZJWH10aGVtZS1gO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuY29uc3QgQVRUUklCVVRFX1RIRU1FX05BTUUgPSBgJHtBVFRSSUJVVEVfVEhFTUVfUFJFRklYfW5hbWVgO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuOC4wXG4gKi9cbmNvbnN0IEFUVFJJQlVURV9VUERBVEVSX0FUVFJJQlVURVMgPSBgJHtBVFRSSUJVVEVfUFJFRklYfWF0dHJpYnV0ZXNgO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjcuMVxuICovXG5jb25zdCBBVFRSSUJVVEVfVVBEQVRFUl9TRUxFQ1RfVEhJUyA9IGAke0FUVFJJQlVURV9QUkVGSVh9c2VsZWN0LXRoaXNgO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuOC4wXG4gKi9cbmNvbnN0IEFUVFJJQlVURV9VUERBVEVSX1JFUExBQ0UgPSBgJHtBVFRSSUJVVEVfUFJFRklYfXJlcGxhY2VgO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuOC4wXG4gKi9cbmNvbnN0IEFUVFJJQlVURV9VUERBVEVSX0lOU0VSVCA9IGAke0FUVFJJQlVURV9QUkVGSVh9aW5zZXJ0YDtcblxuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjguMFxuICovXG5jb25zdCBBVFRSSUJVVEVfVVBEQVRFUl9JTlNFUlRfUkVGRVJFTkNFID0gYCR7QVRUUklCVVRFX1BSRUZJWH1pbnNlcnQtcmVmZXJlbmNlYDtcblxuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjguMFxuICovXG5jb25zdCBBVFRSSUJVVEVfVVBEQVRFUl9SRU1PVkUgPSBgJHtBVFRSSUJVVEVfUFJFRklYfXJlbW92ZWA7XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS45LjBcbiAqL1xuY29uc3QgQVRUUklCVVRFX1VQREFURVJfQklORCA9IGAke0FUVFJJQlVURV9QUkVGSVh9YmluZGA7XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNy4wXG4gKi9cbmNvbnN0IEFUVFJJQlVURV9URU1QTEFURV9QUkVGSVggPSBgJHtBVFRSSUJVVEVfUFJFRklYfXRlbXBsYXRlLXByZWZpeGA7XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4xNC4wXG4gKi9cbmNvbnN0IEFUVFJJQlVURV9ST0xFID0gYCR7QVRUUklCVVRFX1BSRUZJWH1yb2xlYDtcblxuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI0LjBcbiAqL1xuY29uc3QgQVRUUklCVVRFX0RJU0FCTEVEID0gXCJkaXNhYmxlZFwiO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjQuMFxuICovXG5jb25zdCBBVFRSSUJVVEVfVkFMVUUgPSBcInZhbHVlXCI7XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS45LjBcbiAqL1xuY29uc3QgQVRUUklCVVRFX09CSkVDVExJTksgPSBgJHtBVFRSSUJVVEVfUFJFRklYfW9iamVjdGxpbmtgO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjQuMFxuICovXG5jb25zdCBBVFRSSUJVVEVfRVJST1JNRVNTQUdFID0gYCR7QVRUUklCVVRFX1BSRUZJWH1lcnJvcmA7XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3ltYm9sfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNC4wXG4gKi9cbmNvbnN0IG9iamVjdFVwZGF0ZXJMaW5rU3ltYm9sID0gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvZG9tL0BAb2JqZWN0LXVwZGF0ZXItbGlua1wiKTtcblxuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0eXBlIHtzeW1ib2x9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI0LjBcbiAqL1xuY29uc3QgY3VzdG9tRWxlbWVudFVwZGF0ZXJMaW5rU3ltYm9sID0gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvZG9tL2N1c3RvbS1lbGVtZW50QEBvcHRpb25zLXVwZGF0ZXItbGlua1wiKTtcblxuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI1LjBcbiAqL1xuY29uc3QgVEFHX1NDUklQVCA9IFwic2NyaXB0XCI7XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNS4wXG4gKi9cbmNvbnN0IFRBR19TVFlMRSA9IFwic3R5bGVcIjtcblxuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI1LjBcbiAqL1xuY29uc3QgVEFHX0xJTksgPSBcImxpbmtcIjtcblxuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI1LjBcbiAqL1xuXG5jb25zdCBBVFRSSUJVVEVfSUQgPSBcImlkXCI7XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNS4wXG4gKi9cblxuY29uc3QgQVRUUklCVVRFX0NMQVNTID0gXCJjbGFzc1wiO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjUuMFxuICovXG5jb25zdCBBVFRSSUJVVEVfVElUTEUgPSBcInRpdGxlXCI7XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNS4wXG4gKi9cbmNvbnN0IEFUVFJJQlVURV9TUkMgPSBcInNyY1wiO1xuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI1LjBcbiAqL1xuY29uc3QgQVRUUklCVVRFX0hSRUYgPSBcImhyZWZcIjtcblxuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI1LjBcbiAqL1xuY29uc3QgQVRUUklCVVRFX1RZUEUgPSBcInR5cGVcIjtcblxuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI1LjBcbiAqL1xuY29uc3QgQVRUUklCVVRFX05PTkNFID0gXCJub25jZVwiO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjUuMFxuICovXG5jb25zdCBBVFRSSUJVVEVfVFJBTlNMQVRFID0gXCJ0cmFuc2xhdGVcIjtcblxuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI1LjBcbiAqL1xuY29uc3QgQVRUUklCVVRFX1RBQklOREVYID0gXCJ0YWJpbmRleFwiO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjUuMFxuICovXG5jb25zdCBBVFRSSUJVVEVfU1BFTExDSEVDSyA9IFwic3BlbGxjaGVja1wiO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjUuMFxuICovXG5jb25zdCBBVFRSSUJVVEVfU0xPVCA9IFwic2xvdFwiO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjUuMFxuICovXG5jb25zdCBBVFRSSUJVVEVfUEFSVCA9IFwicGFydFwiO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjUuMFxuICovXG5jb25zdCBBVFRSSUJVVEVfTEFORyA9IFwibGFuZ1wiO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjUuMFxuICovXG5jb25zdCBBVFRSSUJVVEVfSVRFTVRZUEUgPSBcIml0ZW10eXBlXCI7XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNS4wXG4gKi9cbmNvbnN0IEFUVFJJQlVURV9JVEVNU0NPUEUgPSBcIml0ZW1zY29wZVwiO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjUuMFxuICovXG5jb25zdCBBVFRSSUJVVEVfSVRFTVJFRiA9IFwiaXRlbXJlZlwiO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjUuMFxuICovXG5jb25zdCBBVFRSSUJVVEVfSVRFTUlEID0gXCJpdGVtaWRcIjtcblxuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI1LjBcbiAqL1xuY29uc3QgQVRUUklCVVRFX0lURU1QUk9QID0gXCJpdGVtcHJvcFwiO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjUuMFxuICovXG5jb25zdCBBVFRSSUJVVEVfSVMgPSBcImlzXCI7XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNS4wXG4gKi9cbmNvbnN0IEFUVFJJQlVURV9JTlBVVE1PREUgPSBcImlucHV0bW9kZVwiO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjUuMFxuICovXG5jb25zdCBBVFRSSUJVVEVfQUNDRVNTS0VZID0gXCJhY2Nlc3NrZXlcIjtcblxuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI1LjBcbiAqL1xuY29uc3QgQVRUUklCVVRFX0FVVE9DQVBJVEFMSVpFID0gXCJhdXRvY2FwaXRhbGl6ZVwiO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjUuMFxuICovXG5jb25zdCBBVFRSSUJVVEVfQVVUT0ZPQ1VTID0gXCJhdXRvZm9jdXNcIjtcblxuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI1LjBcbiAqL1xuY29uc3QgQVRUUklCVVRFX0NPTlRFTlRFRElUQUJMRSA9IFwiY29udGVudGVkaXRhYmxlXCI7XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNS4wXG4gKi9cbmNvbnN0IEFUVFJJQlVURV9ESVIgPSBcImRpclwiO1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjUuMFxuICovXG5jb25zdCBBVFRSSUJVVEVfRFJBR0dBQkxFID0gXCJkcmFnZ2FibGVcIjtcblxuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI1LjBcbiAqL1xuY29uc3QgQVRUUklCVVRFX0VOVEVSS0VZSElOVCA9IFwiZW50ZXJrZXloaW50XCI7XG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjUuMFxuICovXG5jb25zdCBBVFRSSUJVVEVfRVhQT1JUUEFSVFMgPSBcImV4cG9ydHBhcnRzXCI7XG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHR5cGUge3N0cmluZ31cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjUuMFxuICovXG5jb25zdCBBVFRSSUJVVEVfSElEREVOID0gXCJoaWRkZW5cIjtcbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGdldEdsb2JhbEZ1bmN0aW9uIH0gZnJvbSBcIi4uL3R5cGVzL2dsb2JhbC5tanNcIjtcbmltcG9ydCB7IFRva2VuTGlzdCB9IGZyb20gXCIuLi90eXBlcy90b2tlbmxpc3QubWpzXCI7XG5pbXBvcnQgeyB2YWxpZGF0ZUluc3RhbmNlLCB2YWxpZGF0ZVN0cmluZywgdmFsaWRhdGVTeW1ib2wgfSBmcm9tIFwiLi4vdHlwZXMvdmFsaWRhdGUubWpzXCI7XG5pbXBvcnQgeyBBVFRSSUJVVEVfT0JKRUNUTElOSyB9IGZyb20gXCIuL2NvbnN0YW50cy5tanNcIjtcblxuZXhwb3J0IHtcbiAgICBmaW5kQ2xvc2VzdE9iamVjdExpbmssXG4gICAgYWRkVG9PYmplY3RMaW5rLFxuICAgIHJlbW92ZU9iamVjdExpbmssXG4gICAgaGFzT2JqZWN0TGluayxcbiAgICBnZXRMaW5rZWRPYmplY3RzLFxuICAgIHRvZ2dsZUF0dHJpYnV0ZVRva2VuLFxuICAgIGFkZEF0dHJpYnV0ZVRva2VuLFxuICAgIHJlbW92ZUF0dHJpYnV0ZVRva2VuLFxuICAgIGNvbnRhaW5zQXR0cmlidXRlVG9rZW4sXG4gICAgcmVwbGFjZUF0dHJpYnV0ZVRva2VuLFxuICAgIGNsZWFyQXR0cmlidXRlVG9rZW5zLFxuICAgIGZpbmRDbG9zZXN0QnlBdHRyaWJ1dGUsXG4gICAgZmluZENsb3Nlc3RCeUNsYXNzLFxufTtcblxuLyoqXG4gKiBHZXQgdGhlIGNsb3Nlc3Qgb2JqZWN0IGxpbmsgb2YgYSBub2RlXG4gKlxuICogaWYgYSBub2RlIGlzIHNwZWNpZmllZCB3aXRob3V0IGEgb2JqZWN0IGxpbmssIGEgcmVjdXJzaXZlIHNlYXJjaCB1cHdhcmRzIGlzIHBlcmZvcm1lZCB1bnRpbCB0aGUgY29ycmVzcG9uZGluZ1xuICogb2JqZWN0IGxpbmsgaXMgZm91bmQsIG9yIHVuZGVmaW5lZCBpcyByZXR1cm5lZC5cbiAqXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gKiBAcmV0dXJuIHtIVE1MRWxlbWVudHx1bmRlZmluZWR9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjEwLjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGFuIGluc3RhbmNlIG9mIEhUTUxFbGVtZW50XG4gKi9cbmZ1bmN0aW9uIGZpbmRDbG9zZXN0T2JqZWN0TGluayhlbGVtZW50KSB7XG4gICAgcmV0dXJuIGZpbmRDbG9zZXN0QnlBdHRyaWJ1dGUoZWxlbWVudCwgQVRUUklCVVRFX09CSkVDVExJTkspO1xufVxuXG4vKipcbiAqIEFkZHMgYSBjbGFzcyBhdHRyaWJ1dGUgdG8gYW4gZWxlbWVudC5cbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjkuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHtTeW1ib2x9IHN5bWJvbFxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gYWRkVG9PYmplY3RMaW5rKGVsZW1lbnQsIHN5bWJvbCwgb2JqZWN0KSB7XG4gICAgdmFsaWRhdGVJbnN0YW5jZShlbGVtZW50LCBIVE1MRWxlbWVudCk7XG4gICAgdmFsaWRhdGVTeW1ib2woc3ltYm9sKTtcblxuICAgIGlmIChlbGVtZW50Py5bc3ltYm9sXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGVsZW1lbnRbc3ltYm9sXSA9IG5ldyBTZXQoKTtcbiAgICB9XG5cbiAgICBhZGRBdHRyaWJ1dGVUb2tlbihlbGVtZW50LCBBVFRSSUJVVEVfT0JKRUNUTElOSywgc3ltYm9sLnRvU3RyaW5nKCkpO1xuICAgIGVsZW1lbnRbc3ltYm9sXS5hZGQob2JqZWN0KTtcbiAgICByZXR1cm4gZWxlbWVudDtcbn1cblxuLyoqXG4gKiBSZW1vdmVzIGFuIG9iamVjdCBmcm9tIGFuIGVsZW1lbnRcbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjkuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHtTeW1ib2x9IHN5bWJvbFxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gcmVtb3ZlT2JqZWN0TGluayhlbGVtZW50LCBzeW1ib2wpIHtcbiAgICB2YWxpZGF0ZUluc3RhbmNlKGVsZW1lbnQsIEhUTUxFbGVtZW50KTtcbiAgICB2YWxpZGF0ZVN5bWJvbChzeW1ib2wpO1xuXG4gICAgaWYgKGVsZW1lbnQ/LltzeW1ib2xdID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgfVxuXG4gICAgcmVtb3ZlQXR0cmlidXRlVG9rZW4oZWxlbWVudCwgQVRUUklCVVRFX09CSkVDVExJTkssIHN5bWJvbC50b1N0cmluZygpKTtcbiAgICBkZWxldGUgZWxlbWVudFtzeW1ib2xdO1xuICAgIHJldHVybiBlbGVtZW50O1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiBhbiBlbGVtZW50IGhhcyBhbiBvYmplY3QgbGlua1xuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuOS4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0ge1N5bWJvbH0gc3ltYm9sXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5mdW5jdGlvbiBoYXNPYmplY3RMaW5rKGVsZW1lbnQsIHN5bWJvbCkge1xuICAgIHZhbGlkYXRlSW5zdGFuY2UoZWxlbWVudCwgSFRNTEVsZW1lbnQpO1xuICAgIHZhbGlkYXRlU3ltYm9sKHN5bWJvbCk7XG5cbiAgICBpZiAoZWxlbWVudD8uW3N5bWJvbF0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbnRhaW5zQXR0cmlidXRlVG9rZW4oZWxlbWVudCwgQVRUUklCVVRFX09CSkVDVExJTkssIHN5bWJvbC50b1N0cmluZygpKTtcbn1cblxuLyoqXG4gKiBUaGUgT2JqZWN0TGluayBjYW4gYmUgdXNlZCB0byBhdHRhY2ggb2JqZWN0cyB0byBIVE1MRWxlbWVudHMuIFRoZSBlbGVtZW50cyBhcmUga2VwdCBpbiBhIHNldCB1bmRlciBhIHVuaXF1ZVxuICogc3ltYm9sIGFuZCBjYW4gYmUgcmVhZCB2aWEgYW4gaXRlcmF0b3Ige0BzZWUge0BsaW5rIGdldExpbmtlZE9iamVjdHN9fS5cbiAqXG4gKiBJbiBhZGRpdGlvbiwgZWxlbWVudHMgd2l0aCBhbiBvYmplY3RMaW5rIHJlY2VpdmUgdGhlIGF0dHJpYnV0ZSBgZGF0YS1tb25zdGVyLW9iamVjdGxpbmtgLlxuICpcbiAqIFdpdGggdGhlIG1ldGhvZCAge0BzZWUge0BsaW5rIGFkZFRvT2JqZWN0TGlua319IHRoZSBvYmplY3RzIGNhbiBiZSBhZGRlZC5cbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjkuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHtTeW1ib2x9IHN5bWJvbFxuICogQHJldHVybiB7SXRlcmF0b3J9XG4gKiBAdGhyb3dzIHtFcnJvcn0gdGhlcmUgaXMgbm8gb2JqZWN0IGxpbmsgZm9yIHN5bWJvbFxuICovXG5mdW5jdGlvbiBnZXRMaW5rZWRPYmplY3RzKGVsZW1lbnQsIHN5bWJvbCkge1xuICAgIHZhbGlkYXRlSW5zdGFuY2UoZWxlbWVudCwgSFRNTEVsZW1lbnQpO1xuICAgIHZhbGlkYXRlU3ltYm9sKHN5bWJvbCk7XG5cbiAgICBpZiAoZWxlbWVudD8uW3N5bWJvbF0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHRoZXJlIGlzIG5vIG9iamVjdCBsaW5rIGZvciAke3N5bWJvbC50b1N0cmluZygpfWApO1xuICAgIH1cblxuICAgIHJldHVybiBlbGVtZW50Py5bc3ltYm9sXVtTeW1ib2wuaXRlcmF0b3JdKCk7XG59XG5cbi8qKlxuICogV2l0aCB0aGlzIG1ldGhvZCB0b2tlbnMgaW4gYW4gYXR0cmlidXRlIGNhbiBiZSBzd2l0Y2hlZCBvbiBvciBvZmYuIEZvciBleGFtcGxlLCBjbGFzc2VzIGNhbiBiZSBzd2l0Y2hlZCBvbiBhbmQgb2ZmIGluIHRoZSBlbGVtZW50cyBjbGFzcyBhdHRyaWJ1dGUuXG4gKlxuICogVG9rZW5zIGFyZSBhbHdheXMgc2VwYXJhdGVkIGJ5IGEgc3BhY2UuXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS45LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXlcbiAqIEBwYXJhbSB7c3RyaW5nfSB0b2tlblxuICogQHJldHVybiB7SFRNTEVsZW1lbnR9XG4gKi9cbmZ1bmN0aW9uIHRvZ2dsZUF0dHJpYnV0ZVRva2VuKGVsZW1lbnQsIGtleSwgdG9rZW4pIHtcbiAgICB2YWxpZGF0ZUluc3RhbmNlKGVsZW1lbnQsIEhUTUxFbGVtZW50KTtcbiAgICB2YWxpZGF0ZVN0cmluZyh0b2tlbik7XG4gICAgdmFsaWRhdGVTdHJpbmcoa2V5KTtcblxuICAgIGlmICghZWxlbWVudC5oYXNBdHRyaWJ1dGUoa2V5KSkge1xuICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShrZXksIHRva2VuKTtcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgfVxuXG4gICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoa2V5LCBuZXcgVG9rZW5MaXN0KGVsZW1lbnQuZ2V0QXR0cmlidXRlKGtleSkpLnRvZ2dsZSh0b2tlbikudG9TdHJpbmcoKSk7XG5cbiAgICByZXR1cm4gZWxlbWVudDtcbn1cblxuLyoqXG4gKiBUaGlzIG1ldGhvZCBjYW4gYmUgdXNlZCB0byBhZGQgYSB0b2tlbiB0byBhbiBhdHRyaWJ1dGUuIFRva2VucyBhcmUgYWx3YXlzIHNlcGFyYXRlZCBieSBhIHNwYWNlLlxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuOS4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5XG4gKiBAcGFyYW0ge3N0cmluZ30gdG9rZW5cbiAqIEByZXR1cm4ge0hUTUxFbGVtZW50fVxuICovXG5mdW5jdGlvbiBhZGRBdHRyaWJ1dGVUb2tlbihlbGVtZW50LCBrZXksIHRva2VuKSB7XG4gICAgdmFsaWRhdGVJbnN0YW5jZShlbGVtZW50LCBIVE1MRWxlbWVudCk7XG4gICAgdmFsaWRhdGVTdHJpbmcodG9rZW4pO1xuICAgIHZhbGlkYXRlU3RyaW5nKGtleSk7XG5cbiAgICBpZiAoIWVsZW1lbnQuaGFzQXR0cmlidXRlKGtleSkpIHtcbiAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoa2V5LCB0b2tlbik7XG4gICAgICAgIHJldHVybiBlbGVtZW50O1xuICAgIH1cblxuICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKGtleSwgbmV3IFRva2VuTGlzdChlbGVtZW50LmdldEF0dHJpYnV0ZShrZXkpKS5hZGQodG9rZW4pLnRvU3RyaW5nKCkpO1xuXG4gICAgcmV0dXJuIGVsZW1lbnQ7XG59XG5cbi8qKlxuICogVGhpcyBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byByZW1vdmUgdG9rZW5zIGZyb20gYW4gYXR0cmlidXRlLlxuICpcbiAqIFRva2VucyBhcmUgYWx3YXlzIHNlcGFyYXRlZCBieSBhIHNwYWNlLlxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuOS4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5XG4gKiBAcGFyYW0ge3N0cmluZ30gdG9rZW5cbiAqIEByZXR1cm4ge0hUTUxFbGVtZW50fVxuICovXG5mdW5jdGlvbiByZW1vdmVBdHRyaWJ1dGVUb2tlbihlbGVtZW50LCBrZXksIHRva2VuKSB7XG4gICAgdmFsaWRhdGVJbnN0YW5jZShlbGVtZW50LCBIVE1MRWxlbWVudCk7XG4gICAgdmFsaWRhdGVTdHJpbmcodG9rZW4pO1xuICAgIHZhbGlkYXRlU3RyaW5nKGtleSk7XG5cbiAgICBpZiAoIWVsZW1lbnQuaGFzQXR0cmlidXRlKGtleSkpIHtcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgfVxuXG4gICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoa2V5LCBuZXcgVG9rZW5MaXN0KGVsZW1lbnQuZ2V0QXR0cmlidXRlKGtleSkpLnJlbW92ZSh0b2tlbikudG9TdHJpbmcoKSk7XG5cbiAgICByZXR1cm4gZWxlbWVudDtcbn1cblxuLyoqXG4gKiBUaGlzIG1ldGhvZCBjYW4gYmUgdXNlZCB0byBkZXRlcm1pbmUgd2hldGhlciBhbiBhdHRyaWJ1dGUgaGFzIGEgdG9rZW4uXG4gKlxuICogVG9rZW5zIGFyZSBhbHdheXMgc2VwYXJhdGVkIGJ5IGEgc3BhY2UuXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS45LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXlcbiAqIEBwYXJhbSB7c3RyaW5nfSB0b2tlblxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gY29udGFpbnNBdHRyaWJ1dGVUb2tlbihlbGVtZW50LCBrZXksIHRva2VuKSB7XG4gICAgdmFsaWRhdGVJbnN0YW5jZShlbGVtZW50LCBIVE1MRWxlbWVudCk7XG4gICAgdmFsaWRhdGVTdHJpbmcodG9rZW4pO1xuICAgIHZhbGlkYXRlU3RyaW5nKGtleSk7XG5cbiAgICBpZiAoIWVsZW1lbnQuaGFzQXR0cmlidXRlKGtleSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgVG9rZW5MaXN0KGVsZW1lbnQuZ2V0QXR0cmlidXRlKGtleSkpLmNvbnRhaW5zKHRva2VuKTtcbn1cblxuLyoqXG4gKiBUb2tlbnMgYXJlIGFsd2F5cyBzZXBhcmF0ZWQgYnkgYSBzcGFjZS5cbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjkuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHtzdHJpbmd9IGtleVxuICogQHBhcmFtIHtzdHJpbmd9IGZyb21cbiAqIEBwYXJhbSB7c3RyaW5nfSB0b1xuICogQHJldHVybiB7SFRNTEVsZW1lbnR9XG4gKi9cbmZ1bmN0aW9uIHJlcGxhY2VBdHRyaWJ1dGVUb2tlbihlbGVtZW50LCBrZXksIGZyb20sIHRvKSB7XG4gICAgdmFsaWRhdGVJbnN0YW5jZShlbGVtZW50LCBIVE1MRWxlbWVudCk7XG4gICAgdmFsaWRhdGVTdHJpbmcoZnJvbSk7XG4gICAgdmFsaWRhdGVTdHJpbmcodG8pO1xuICAgIHZhbGlkYXRlU3RyaW5nKGtleSk7XG5cbiAgICBpZiAoIWVsZW1lbnQuaGFzQXR0cmlidXRlKGtleSkpIHtcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgfVxuXG4gICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoa2V5LCBuZXcgVG9rZW5MaXN0KGVsZW1lbnQuZ2V0QXR0cmlidXRlKGtleSkpLnJlcGxhY2UoZnJvbSwgdG8pLnRvU3RyaW5nKCkpO1xuXG4gICAgcmV0dXJuIGVsZW1lbnQ7XG59XG5cbi8qKlxuICogVG9rZW5zIGFyZSBhbHdheXMgc2VwYXJhdGVkIGJ5IGEgc3BhY2UuXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS45LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXlcbiAqIEByZXR1cm4ge0hUTUxFbGVtZW50fVxuICovXG5mdW5jdGlvbiBjbGVhckF0dHJpYnV0ZVRva2VucyhlbGVtZW50LCBrZXkpIHtcbiAgICB2YWxpZGF0ZUluc3RhbmNlKGVsZW1lbnQsIEhUTUxFbGVtZW50KTtcbiAgICB2YWxpZGF0ZVN0cmluZyhrZXkpO1xuXG4gICAgaWYgKCFlbGVtZW50Lmhhc0F0dHJpYnV0ZShrZXkpKSB7XG4gICAgICAgIHJldHVybiBlbGVtZW50O1xuICAgIH1cblxuICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKGtleSwgXCJcIik7XG5cbiAgICByZXR1cm4gZWxlbWVudDtcbn1cblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIHNlYXJjaGVzLCBzdGFydGluZyBmcm9tIGFuIGBIVE1MRWxlbWVtZW50YCwgZm9yIHRoZSBuZXh0IGVsZW1lbnQgdGhhdCBoYXMgYSBjZXJ0YWluIGF0dHJpYnV0ZS5cbiAqXG4gKiBgYGBodG1sXG4gKiA8ZGl2IGRhdGEtbXktYXR0cmlidXRlPVwiMlwiIGlkPVwiMlwiPlxuICogICAgIDxkaXYgaWQ9XCIxXCI+PC9kaXY+XG4gKiA8L2Rpdj5cbiAqIGBgYFxuICpcbiAqIGBgYGphdmFzY3JpcHRcbiAqIC8vIGlmIG5vIHZhbHVlIGlzIHNwZWNpZmllZCAodW5kZWZpbmVkKSwgdGhlbiBvbmx5IHRoZSBhdHRyaWJ1dGUgaXMgY2hlY2tlZC5cbiAqIGZpbmRDbG9zZXN0QnlBdHRyaWJ1dGUoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJzEnKSwnZGF0YS1teS1hdHRyaWJ1dGUnKTsgLy8gXHUyMUE2IG5vZGUgd2l0aCBpZCAyXG4gKiBmaW5kQ2xvc2VzdEJ5QXR0cmlidXRlKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCcyJyksJ2RhdGEtbXktYXR0cmlidXRlJyk7IC8vIFx1MjFBNiBub2RlIHdpdGggaWQgMlxuICpcbiAqIC8vIGlmIGEgdmFsdWUgaXMgc3BlY2lmaWVkLCBmb3IgZXhhbXBsZSBhbiBlbXB0eSBzdHJpbmcsIHRoZW4gdGhlIG5hbWUgYW5kIHRoZSB2YWx1ZSBhcmUgY2hlY2tlZC5cbiAqIGZpbmRDbG9zZXN0QnlBdHRyaWJ1dGUoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJzEnKSwnZGF0YS1teS1hdHRyaWJ1dGUnLCAnJyk7ICAvLyBcdTIxQTYgdW5kZWZpbmVkXG4gKiBmaW5kQ2xvc2VzdEJ5QXR0cmlidXRlKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCcxJyksJ2RhdGEtbXktYXR0cmlidXRlJywgJzInKTsgLy8gXHUyMUE2IG5vZGUgd2l0aCBpZCAyXG4gKiBgYGBcbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjE0LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXlcbiAqIEBwYXJhbSB7c3RyaW5nfHVuZGVmaW5lZH0gdmFsdWVcbiAqIEByZXR1cm4ge0hUTUxFbGVtZW50fHVuZGVmaW5lZH1cbiAqIEBzdW1tYXJ5IGZpbmQgY2xvc2VzdCBub2RlXG4gKi9cbmZ1bmN0aW9uIGZpbmRDbG9zZXN0QnlBdHRyaWJ1dGUoZWxlbWVudCwga2V5LCB2YWx1ZSkge1xuICAgIHZhbGlkYXRlSW5zdGFuY2UoZWxlbWVudCwgZ2V0R2xvYmFsRnVuY3Rpb24oXCJIVE1MRWxlbWVudFwiKSk7XG5cbiAgICBpZiAoZWxlbWVudC5oYXNBdHRyaWJ1dGUoa2V5KSkge1xuICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZWxlbWVudC5nZXRBdHRyaWJ1dGUoa2V5KSA9PT0gdmFsdWUpIHtcbiAgICAgICAgICAgIHJldHVybiBlbGVtZW50O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbGV0IHNlbGVjdG9yID0gdmFsaWRhdGVTdHJpbmcoa2V5KTtcbiAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkgc2VsZWN0b3IgKz0gYD0ke3ZhbGlkYXRlU3RyaW5nKHZhbHVlKX1gO1xuICAgIGxldCByZXN1bHQgPSBlbGVtZW50LmNsb3Nlc3QoYFske3NlbGVjdG9yfV1gKTtcbiAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIHNlYXJjaGVzLCBzdGFydGluZyBmcm9tIGFuIGBIVE1MRWxlbWVtZW50YCwgZm9yIHRoZSBuZXh0IGVsZW1lbnQgdGhhdCBoYXMgYSBjZXJ0YWluIGF0dHJpYnV0ZS5cbiAqXG4gKiBgYGBodG1sXG4gKiA8ZGl2IGNsYXNzPVwibXljbGFzc1wiIGlkPVwiMlwiPlxuICogICAgIDxkaXYgaWQ9XCIxXCI+PC9kaXY+XG4gKiA8L2Rpdj5cbiAqIGBgYFxuICpcbiAqIGBgYGphdmFzY3JpcHRcbiAqIC8vIGlmIG5vIHZhbHVlIGlzIHNwZWNpZmllZCAodW5kZWZpbmVkKSwgdGhlbiBvbmx5IHRoZSBhdHRyaWJ1dGUgaXMgY2hlY2tlZC5cbiAqIGZpbmRDbG9zZXN0QnlDbGFzcyhkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnMScpLCdteWNsYXNzJyk7IC8vIFx1MjFBNiBub2RlIHdpdGggaWQgMlxuICogZmluZENsb3Nlc3RCeUNsYXNzKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCcyJyksJ215Y2xhc3MnKTsgLy8gXHUyMUE2IG5vZGUgd2l0aCBpZCAyXG4gKiBgYGBcbiAqXG4gKiBgYGBcbiAqIDxzY3JpcHQgdHlwZT1cIm1vZHVsZVwiPlxuICogaW1wb3J0IHtmaW5kQ2xvc2VzdEJ5Q2xhc3N9IGZyb20gJ0BzY2h1a2FpL21vbnN0ZXIvc291cmNlL2RvbS9hdHRyaWJ1dGVzLm1qcyc7XG4gKiBmaW5kQ2xvc2VzdEJ5Q2xhc3MoKTtcbiAqIDwvc2NyaXB0PlxuICogYGBgXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNy4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0ge3N0cmluZ30gY2xhc3NOYW1lXG4gKiBAcmV0dXJuIHtIVE1MRWxlbWVudHx1bmRlZmluZWR9XG4gKiBAc3VtbWFyeSBmaW5kIGNsb3Nlc3Qgbm9kZVxuICovXG5mdW5jdGlvbiBmaW5kQ2xvc2VzdEJ5Q2xhc3MoZWxlbWVudCwgY2xhc3NOYW1lKSB7XG4gICAgdmFsaWRhdGVJbnN0YW5jZShlbGVtZW50LCBnZXRHbG9iYWxGdW5jdGlvbihcIkhUTUxFbGVtZW50XCIpKTtcblxuICAgIGlmIChlbGVtZW50Py5jbGFzc0xpc3Q/LmNvbnRhaW5zKHZhbGlkYXRlU3RyaW5nKGNsYXNzTmFtZSkpKSB7XG4gICAgICAgIHJldHVybiBlbGVtZW50O1xuICAgIH1cblxuICAgIGxldCByZXN1bHQgPSBlbGVtZW50LmNsb3Nlc3QoYC4ke2NsYXNzTmFtZX1gKTtcbiAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xufVxuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgQmFzZSB9IGZyb20gXCIuL2Jhc2UubWpzXCI7XG5pbXBvcnQgeyBpbnN0YW5jZVN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5leHBvcnQgeyBTdGFjayB9O1xuXG4vKipcbiAqIFlvdSBjYW4gY2FsbCB0aGUgbWV0aG9kIHZpYSB0aGUgbW9uc3RlciBuYW1lc3BhY2UgYG5ldyBNb25zdGVyLlR5cGVzLlF1ZXVlKClgLlxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuNC4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcbiAqL1xuY2xhc3MgU3RhY2sgZXh0ZW5kcyBCYXNlIHtcbiAgICAvKipcbiAgICAgKlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLmRhdGEgPSBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGBpbnN0YW5jZW9mYCBvcGVyYXRvci5cbiAgICAgKiBAcmV0dXJucyB7c3ltYm9sfVxuICAgICAqIEBzaW5jZSAyLjEuMFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgW2luc3RhbmNlU3ltYm9sXSgpIHtcbiAgICAgICAgcmV0dXJuIFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL3R5cGVzL3N0YWNrXCIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAgICovXG4gICAgaXNFbXB0eSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGF0YS5sZW5ndGggPT09IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogbG9va3MgYXQgdGhlIG9iamVjdCBhdCB0aGUgdG9wIG9mIHRoaXMgc3RhY2sgd2l0aG91dCByZW1vdmluZyBpdCBmcm9tIHRoZSBzdGFjay5cbiAgICAgKlxuICAgICAqIEByZXR1cm4geyp9XG4gICAgICovXG4gICAgcGVlaygpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNFbXB0eSgpKSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuZGF0YT8uW3RoaXMuZGF0YS5sZW5ndGggLSAxXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBwdXNoZXMgYW4gaXRlbSBvbnRvIHRoZSB0b3Agb2YgdGhpcyBzdGFjay5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAgICAgKiBAcmV0dXJucyB7UXVldWV9XG4gICAgICovXG4gICAgcHVzaCh2YWx1ZSkge1xuICAgICAgICB0aGlzLmRhdGEucHVzaCh2YWx1ZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHJlbW92ZSBhbGwgZW50cmllc1xuICAgICAqXG4gICAgICogQHJldHVybnMge1F1ZXVlfVxuICAgICAqL1xuICAgIGNsZWFyKCkge1xuICAgICAgICB0aGlzLmRhdGEgPSBbXTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogcmVtb3ZlcyB0aGUgb2JqZWN0IGF0IHRoZSB0b3Agb2YgdGhpcyBzdGFjayBhbmQgcmV0dXJuc1xuICAgICAqIHRoYXQgb2JqZWN0IGFzIHRoZSB2YWx1ZSBvZiB0aGlzIGZ1bmN0aW9uLiBpcyB0aGUgc3RhY2sgZW1wdHlcbiAgICAgKiB0aGUgcmV0dXJuIHZhbHVlIGlzIHVuZGVmaW5lZC5cbiAgICAgKlxuICAgICAqIEByZXR1cm4geyp9XG4gICAgICovXG4gICAgcG9wKCkge1xuICAgICAgICBpZiAodGhpcy5pc0VtcHR5KCkpIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuZGF0YS5wb3AoKTtcbiAgICB9XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBCYXNlIH0gZnJvbSBcIi4uL3R5cGVzL2Jhc2UubWpzXCI7XG5pbXBvcnQgeyBpc0FycmF5LCBpc0ludGVnZXIsIGlzT2JqZWN0LCBpc1ByaW1pdGl2ZSwgaXNTdHJpbmcgfSBmcm9tIFwiLi4vdHlwZXMvaXMubWpzXCI7XG5pbXBvcnQgeyBTdGFjayB9IGZyb20gXCIuLi90eXBlcy9zdGFjay5tanNcIjtcbmltcG9ydCB7IHZhbGlkYXRlSW50ZWdlciwgdmFsaWRhdGVCb29sZWFuLCB2YWxpZGF0ZVN0cmluZyB9IGZyb20gXCIuLi90eXBlcy92YWxpZGF0ZS5tanNcIjtcblxuZXhwb3J0IHsgUGF0aGZpbmRlciwgREVMSU1JVEVSLCBXSUxEQ0FSRCB9O1xuXG4vKipcbiAqIHBhdGggc2VwYXJhdG9yXG4gKlxuICogQHByaXZhdGVcbiAqIEB0eXBlIHtzdHJpbmd9XG4gKi9cbmNvbnN0IERFTElNSVRFUiA9IFwiLlwiO1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAdHlwZSB7c3RyaW5nfVxuICovXG5jb25zdCBXSUxEQ0FSRCA9IFwiKlwiO1xuXG4vKipcbiAqIFBhdGhmaW5kZXIgaXMgYSBjbGFzcyB0byBmaW5kIGEgcGF0aCB0byBhbiBvYmplY3QuXG4gKlxuICogV2l0aCB0aGUgaGVscCBvZiB0aGUgcGF0aGZpbmRlciwgdmFsdWVzIGNhbiBiZSByZWFkIGFuZCB3cml0dGVuIGZyb20gYW4gb2JqZWN0IGNvbnN0cnVjdC5cbiAqXG4gKiBgYGBcbiAqIG5ldyBQYXRoZmluZGVyKHtcbiAqIGE6IHtcbiAqICAgICBiOiB7XG4gKiAgICAgICAgIGY6IFtcbiAqICAgICAgICAgICAgIHtcbiAqICAgICAgICAgICAgICAgICBnOiBmYWxzZSxcbiAqICAgICAgICAgICAgIH1cbiAqICAgICAgICAgXSxcbiAqICAgICB9XG4gKiB9XG4gKiB9KS5nZXRWaWEoXCJhLmIuZi4wLmdcIik7IC8vIFx1MjFBNiBmYWxzZVxuICogYGBgXG4gKlxuICogaWYgYSB2YWx1ZSBpcyBub3QgcHJlc2VudCBvciBoYXMgdGhlIHdyb25nIHR5cGUsIGEgY29ycmVzcG9uZGluZyBleGNlcHRpb24gaXMgdGhyb3duLlxuICpcbiAqIGBgYFxuICogbmV3IFBhdGhmaW5kZXIoe30pLmdldFZpYShcImEuYi5mLjAuZ1wiKTsgLy8gXHUyMUE2IEVycm9yXG4gKiBgYGBcbiAqXG4gKiBUaGUgYFBhdGhmaW5kZXIuZXhpc3RzKClgIG1ldGhvZCBjYW4gYmUgdXNlZCB0byBjaGVjayB3aGV0aGVyIGFjY2VzcyB0byB0aGUgcGF0aCBpcyBwb3NzaWJsZS5cbiAqXG4gKiBgYGBcbiAqIG5ldyBQYXRoZmluZGVyKHt9KS5leGlzdHMoXCJhLmIuZi4wLmdcIik7IC8vIFx1MjFBNiBmYWxzZVxuICogYGBgXG4gKlxuICogcGF0aGZpbmRlciBjYW4gYWxzbyBiZSB1c2VkIHRvIGJ1aWxkIG9iamVjdCBzdHJ1Y3R1cmVzLiB0byBkbyB0aGlzLCB0aGUgYFBhdGhmaW5kZXIuc2V0VmlhKClgIG1ldGhvZCBtdXN0IGJlIHVzZWQuXG4gKlxuICogYGBgXG4gKiBvYmogPSB7fTtcbiAqIG5ldyBQYXRoZmluZGVyKG9iaikuc2V0VmlhKCdhLmIuMC5jJywgdHJ1ZSk7IC8vIFx1MjFBNiB7YTp7Yjpbe2M6dHJ1ZX1dfX1cbiAqIGBgYFxuICpcbiAqIEBleHRlcm5hbEV4YW1wbGUgLi4vLi4vZXhhbXBsZS9kYXRhL3BhdGhmaW5kZXItMS5tanNcbiAqIEBleHRlcm5hbEV4YW1wbGUgLi4vLi4vZXhhbXBsZS9kYXRhL3BhdGhmaW5kZXItMi5tanNcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuNC4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRGF0YVxuICovXG5jbGFzcyBQYXRoZmluZGVyIGV4dGVuZHMgQmFzZSB7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIHthcnJheXxvYmplY3R8TWFwfFNldH0gdmFsdWVcbiAgICAgKiBAc2luY2UgMS40LjBcbiAgICAgKiBAdGhyb3dzICB7RXJyb3J9IHRoZSBwYXJhbWV0ZXIgbXVzdCBub3QgYmUgYSBzaW1wbGUgdHlwZVxuICAgICAqKi9cbiAgICBjb25zdHJ1Y3RvcihvYmplY3QpIHtcbiAgICAgICAgc3VwZXIoKTtcblxuICAgICAgICBpZiAoaXNQcmltaXRpdmUob2JqZWN0KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidGhlIHBhcmFtZXRlciBtdXN0IG5vdCBiZSBhIHNpbXBsZSB0eXBlXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5vYmplY3QgPSBvYmplY3Q7XG4gICAgICAgIHRoaXMud2lsZENhcmQgPSBXSUxEQ0FSRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBzZXQgd2lsZGNhcmRcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB3aWxkY2FyZFxuICAgICAqIEByZXR1cm4ge1BhdGhmaW5kZXJ9XG4gICAgICogQHNpbmNlIDEuNy4wXG4gICAgICovXG4gICAgc2V0V2lsZENhcmQod2lsZGNhcmQpIHtcbiAgICAgICAgdmFsaWRhdGVTdHJpbmcod2lsZGNhcmQpO1xuICAgICAgICB0aGlzLndpbGRDYXJkID0gd2lsZGNhcmQ7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd8YXJyYXl9IHBhdGhcbiAgICAgKiBAc2luY2UgMS40LjBcbiAgICAgKiBAcmV0dXJucyB7Kn1cbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHVuc3VwcG9ydGVkIHR5cGVcbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gdGhlIGpvdXJuZXkgaXMgbm90IGF0IGl0cyBlbmRcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIHN0cmluZ1xuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGFuIGludGVnZXJcbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gdW5zdXBwb3J0ZWQgYWN0aW9uIGZvciB0aGlzIGRhdGEgdHlwZVxuICAgICAqL1xuICAgIGdldFZpYShwYXRoKSB7XG4gICAgICAgIHJldHVybiBnZXRWYWx1ZVZpYVBhdGguY2FsbCh0aGlzLCB0aGlzLm9iamVjdCwgcGF0aCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xhcnJheX0gcGF0aFxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAgICAgKiBAcmV0dXJucyB7UGF0aGZpbmRlcn1cbiAgICAgKiBAc2luY2UgMS40LjBcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHVuc3VwcG9ydGVkIHR5cGVcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIHN0cmluZ1xuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGFuIGludGVnZXJcbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gdW5zdXBwb3J0ZWQgYWN0aW9uIGZvciB0aGlzIGRhdGEgdHlwZVxuICAgICAqL1xuICAgIHNldFZpYShwYXRoLCB2YWx1ZSkge1xuICAgICAgICBzZXRWYWx1ZVZpYVBhdGguY2FsbCh0aGlzLCB0aGlzLm9iamVjdCwgcGF0aCwgdmFsdWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZWxldGUgVmlhIFBhdGhcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfGFycmF5fSBwYXRoXG4gICAgICogQHJldHVybnMge1BhdGhmaW5kZXJ9XG4gICAgICogQHNpbmNlIDEuNi4wXG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSB1bnN1cHBvcnRlZCB0eXBlXG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYSBzdHJpbmdcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhbiBpbnRlZ2VyXG4gICAgICogQHRocm93cyB7RXJyb3J9IHVuc3VwcG9ydGVkIGFjdGlvbiBmb3IgdGhpcyBkYXRhIHR5cGVcbiAgICAgKi9cbiAgICBkZWxldGVWaWEocGF0aCkge1xuICAgICAgICBkZWxldGVWYWx1ZVZpYVBhdGguY2FsbCh0aGlzLCB0aGlzLm9iamVjdCwgcGF0aCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd8YXJyYXl9IHBhdGhcbiAgICAgKiBAcmV0dXJuIHtib29sfVxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdW5zdXBwb3J0ZWQgdHlwZVxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgc3RyaW5nXG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYW4gaW50ZWdlclxuICAgICAqIEBzaW5jZSAxLjQuMFxuICAgICAqL1xuICAgIGV4aXN0cyhwYXRoKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBnZXRWYWx1ZVZpYVBhdGguY2FsbCh0aGlzLCB0aGlzLm9iamVjdCwgcGF0aCwgdHJ1ZSk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSBjYXRjaCAoZSkge31cblxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufVxuXG4vKipcbiAqXG4gKiBAcGFyYW0geyp9IHN1YmplY3RcbiAqIEBwYXJhbSB7c3RyaW5nfGFycmF5fSBwYXRoXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGNoZWNrXG4gKiBAcmV0dXJuIHtNYXB9XG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHVuc3VwcG9ydGVkIHR5cGVcbiAqIEB0aHJvd3Mge0Vycm9yfSB0aGUgam91cm5leSBpcyBub3QgYXQgaXRzIGVuZFxuICogQHRocm93cyB7RXJyb3J9IHVuc3VwcG9ydGVkIGFjdGlvbiBmb3IgdGhpcyBkYXRhIHR5cGVcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGl0ZXJhdGUoc3ViamVjdCwgcGF0aCwgY2hlY2spIHtcbiAgICBpZiAoY2hlY2sgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjaGVjayA9IGZhbHNlO1xuICAgIH1cbiAgICB2YWxpZGF0ZUJvb2xlYW4oY2hlY2spO1xuXG4gICAgY29uc3QgcmVzdWx0ID0gbmV3IE1hcCgpO1xuXG4gICAgaWYgKGlzQXJyYXkocGF0aCkpIHtcbiAgICAgICAgcGF0aCA9IHBhdGguam9pbihERUxJTUlURVIpO1xuICAgIH1cblxuICAgIGlmIChpc09iamVjdChzdWJqZWN0KSB8fCBpc0FycmF5KHN1YmplY3QpKSB7XG4gICAgICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHN1YmplY3QpKSB7XG4gICAgICAgICAgICByZXN1bHQuc2V0KGtleSwgZ2V0VmFsdWVWaWFQYXRoLmNhbGwodGhpcywgdmFsdWUsIHBhdGgsIGNoZWNrKSk7XG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICBsZXQga2V5ID0gcGF0aC5zcGxpdChERUxJTUlURVIpLnNoaWZ0KCk7XG4gICAgICAgIHJlc3VsdC5zZXQoa2V5LCBnZXRWYWx1ZVZpYVBhdGguY2FsbCh0aGlzLCBzdWJqZWN0LCBwYXRoLCBjaGVjaykpO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICpcbiAqIEBwYXJhbSB7Kn0gc3ViamVjdFxuICogQHBhcmFtIFtzdHJpbmd8YXJyYXl9IHBhdGhcbiAqIEBwYXJhbSBbYm9vbGVhbn0gY2hlY2tcbiAqIEByZXR1cm5zIHsqfVxuICogQHRocm93cyB7VHlwZUVycm9yfSB1bnN1cHBvcnRlZCB0eXBlXG4gKiBAdGhyb3dzIHtFcnJvcn0gdGhlIGpvdXJuZXkgaXMgbm90IGF0IGl0cyBlbmRcbiAqIEB0aHJvd3Mge0Vycm9yfSB1bnN1cHBvcnRlZCBhY3Rpb24gZm9yIHRoaXMgZGF0YSB0eXBlXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBnZXRWYWx1ZVZpYVBhdGgoc3ViamVjdCwgcGF0aCwgY2hlY2spIHtcbiAgICBpZiAoY2hlY2sgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjaGVjayA9IGZhbHNlO1xuICAgIH1cbiAgICB2YWxpZGF0ZUJvb2xlYW4oY2hlY2spO1xuXG4gICAgaWYgKCEoaXNBcnJheShwYXRoKSB8fCBpc1N0cmluZyhwYXRoKSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidHlwZSBlcnJvcjogcGF0aCBtdXN0IGJlIGEgc3RyaW5nIG9yIGFuIGFycmF5XCIpO1xuICAgIH1cblxuICAgIGxldCBwYXJ0cztcbiAgICBpZiAoaXNTdHJpbmcocGF0aCkpIHtcbiAgICAgICAgaWYgKHBhdGggPT09IFwiXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBzdWJqZWN0O1xuICAgICAgICB9XG5cbiAgICAgICAgcGFydHMgPSBwYXRoLnNwbGl0KERFTElNSVRFUik7XG4gICAgfVxuXG4gICAgbGV0IGN1cnJlbnQgPSBwYXJ0cy5zaGlmdCgpO1xuXG4gICAgaWYgKGN1cnJlbnQgPT09IHRoaXMud2lsZENhcmQpIHtcbiAgICAgICAgcmV0dXJuIGl0ZXJhdGUuY2FsbCh0aGlzLCBzdWJqZWN0LCBwYXJ0cy5qb2luKERFTElNSVRFUiksIGNoZWNrKTtcbiAgICB9XG5cbiAgICBpZiAoaXNPYmplY3Qoc3ViamVjdCkgfHwgaXNBcnJheShzdWJqZWN0KSkge1xuICAgICAgICBsZXQgYW5jaG9yO1xuICAgICAgICBpZiAoc3ViamVjdCBpbnN0YW5jZW9mIE1hcCB8fCBzdWJqZWN0IGluc3RhbmNlb2YgV2Vha01hcCkge1xuICAgICAgICAgICAgYW5jaG9yID0gc3ViamVjdC5nZXQoY3VycmVudCk7XG4gICAgICAgIH0gZWxzZSBpZiAoc3ViamVjdCBpbnN0YW5jZW9mIFNldCB8fCBzdWJqZWN0IGluc3RhbmNlb2YgV2Vha1NldCkge1xuICAgICAgICAgICAgY3VycmVudCA9IHBhcnNlSW50KGN1cnJlbnQpO1xuICAgICAgICAgICAgdmFsaWRhdGVJbnRlZ2VyKGN1cnJlbnQpO1xuICAgICAgICAgICAgYW5jaG9yID0gWy4uLnN1YmplY3RdPy5bY3VycmVudF07XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIFdlYWtSZWYgPT09IFwiZnVuY3Rpb25cIiAmJiBzdWJqZWN0IGluc3RhbmNlb2YgV2Vha1JlZikge1xuICAgICAgICAgICAgdGhyb3cgRXJyb3IoXCJ1bnN1cHBvcnRlZCBhY3Rpb24gZm9yIHRoaXMgZGF0YSB0eXBlXCIpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzQXJyYXkoc3ViamVjdCkpIHtcbiAgICAgICAgICAgIGN1cnJlbnQgPSBwYXJzZUludChjdXJyZW50KTtcbiAgICAgICAgICAgIHZhbGlkYXRlSW50ZWdlcihjdXJyZW50KTtcbiAgICAgICAgICAgIGFuY2hvciA9IHN1YmplY3Q/LltjdXJyZW50XTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFuY2hvciA9IHN1YmplY3Q/LltjdXJyZW50XTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc09iamVjdChhbmNob3IpIHx8IGlzQXJyYXkoYW5jaG9yKSkge1xuICAgICAgICAgICAgcmV0dXJuIGdldFZhbHVlVmlhUGF0aC5jYWxsKHRoaXMsIGFuY2hvciwgcGFydHMuam9pbihERUxJTUlURVIpLCBjaGVjayk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocGFydHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgdGhyb3cgRXJyb3IoYHRoZSBqb3VybmV5IGlzIG5vdCBhdCBpdHMgZW5kICgke3BhcnRzLmpvaW4oREVMSU1JVEVSKX0pYCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY2hlY2sgPT09IHRydWUpIHtcbiAgICAgICAgICAgIGNvbnN0IGRlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKE9iamVjdC5nZXRQcm90b3R5cGVPZihzdWJqZWN0KSwgY3VycmVudCk7XG5cbiAgICAgICAgICAgIGlmICghc3ViamVjdC5oYXNPd25Qcm9wZXJ0eShjdXJyZW50KSAmJiBkZXNjcmlwdG9yID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcihcInVua25vd24gdmFsdWVcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYW5jaG9yO1xuICAgIH1cblxuICAgIHRocm93IFR5cGVFcnJvcihgdW5zdXBwb3J0ZWQgdHlwZSAke3R5cGVvZiBzdWJqZWN0fWApO1xufVxuXG4vKipcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gc3ViamVjdFxuICogQHBhcmFtIHtzdHJpbmd8YXJyYXl9IHBhdGhcbiAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAqIEByZXR1cm5zIHt2b2lkfVxuICogQHRocm93cyB7VHlwZUVycm9yfSB1bnN1cHBvcnRlZCB0eXBlXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHVuc3VwcG9ydGVkIHR5cGVcbiAqIEB0aHJvd3Mge0Vycm9yfSB0aGUgam91cm5leSBpcyBub3QgYXQgaXRzIGVuZFxuICogQHRocm93cyB7RXJyb3J9IHVuc3VwcG9ydGVkIGFjdGlvbiBmb3IgdGhpcyBkYXRhIHR5cGVcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHNldFZhbHVlVmlhUGF0aChzdWJqZWN0LCBwYXRoLCB2YWx1ZSkge1xuICAgIGlmICghKGlzQXJyYXkocGF0aCkgfHwgaXNTdHJpbmcocGF0aCkpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcInR5cGUgZXJyb3I6IHBhdGggbXVzdCBiZSBhIHN0cmluZyBvciBhbiBhcnJheVwiKTtcbiAgICB9XG5cbiAgICBsZXQgcGFydHM7XG4gICAgaWYgKGlzQXJyYXkocGF0aCkpIHtcbiAgICAgICAgaWYgKHBhdGgubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gc3ViamVjdDtcbiAgICAgICAgfVxuXG4gICAgICAgIHBhcnRzID0gcGF0aDtcbiAgICB9IGVsc2Uge1xuICAgICAgICBwYXJ0cyA9IHBhdGguc3BsaXQoREVMSU1JVEVSKTtcbiAgICB9XG5cbiAgICBsZXQgbGFzdCA9IHBhcnRzLnBvcCgpO1xuICAgIGxldCBzdWJwYXRoID0gcGFydHMuam9pbihERUxJTUlURVIpO1xuXG4gICAgbGV0IHN0YWNrID0gbmV3IFN0YWNrKCk7XG4gICAgbGV0IGN1cnJlbnQgPSBzdWJwYXRoO1xuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBnZXRWYWx1ZVZpYVBhdGguY2FsbCh0aGlzLCBzdWJqZWN0LCBjdXJyZW50LCB0cnVlKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9IGNhdGNoIChlKSB7fVxuXG4gICAgICAgIHN0YWNrLnB1c2goY3VycmVudCk7XG4gICAgICAgIHBhcnRzLnBvcCgpO1xuICAgICAgICBjdXJyZW50ID0gcGFydHMuam9pbihERUxJTUlURVIpO1xuXG4gICAgICAgIGlmIChjdXJyZW50ID09PSBcIlwiKSBicmVhaztcbiAgICB9XG5cbiAgICB3aGlsZSAoIXN0YWNrLmlzRW1wdHkoKSkge1xuICAgICAgICBjdXJyZW50ID0gc3RhY2sucG9wKCk7XG4gICAgICAgIGxldCBvYmogPSB7fTtcblxuICAgICAgICBpZiAoIXN0YWNrLmlzRW1wdHkoKSkge1xuICAgICAgICAgICAgbGV0IG4gPSBzdGFjay5wZWVrKCkuc3BsaXQoREVMSU1JVEVSKS5wb3AoKTtcbiAgICAgICAgICAgIGlmIChpc0ludGVnZXIocGFyc2VJbnQobikpKSB7XG4gICAgICAgICAgICAgICAgb2JqID0gW107XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBzZXRWYWx1ZVZpYVBhdGguY2FsbCh0aGlzLCBzdWJqZWN0LCBjdXJyZW50LCBvYmopO1xuICAgIH1cblxuICAgIGxldCBhbmNob3IgPSBnZXRWYWx1ZVZpYVBhdGguY2FsbCh0aGlzLCBzdWJqZWN0LCBzdWJwYXRoKTtcblxuICAgIGlmICghKGlzT2JqZWN0KHN1YmplY3QpIHx8IGlzQXJyYXkoc3ViamVjdCkpKSB7XG4gICAgICAgIHRocm93IFR5cGVFcnJvcihgdW5zdXBwb3J0ZWQgdHlwZTogJHt0eXBlb2Ygc3ViamVjdH1gKTtcbiAgICB9XG5cbiAgICBpZiAoYW5jaG9yIGluc3RhbmNlb2YgTWFwIHx8IGFuY2hvciBpbnN0YW5jZW9mIFdlYWtNYXApIHtcbiAgICAgICAgYW5jaG9yLnNldChsYXN0LCB2YWx1ZSk7XG4gICAgfSBlbHNlIGlmIChhbmNob3IgaW5zdGFuY2VvZiBTZXQgfHwgYW5jaG9yIGluc3RhbmNlb2YgV2Vha1NldCkge1xuICAgICAgICBhbmNob3IuYXBwZW5kKHZhbHVlKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBXZWFrUmVmID09PSBcImZ1bmN0aW9uXCIgJiYgYW5jaG9yIGluc3RhbmNlb2YgV2Vha1JlZikge1xuICAgICAgICB0aHJvdyBFcnJvcihcInVuc3VwcG9ydGVkIGFjdGlvbiBmb3IgdGhpcyBkYXRhIHR5cGVcIik7XG4gICAgfSBlbHNlIGlmIChpc0FycmF5KGFuY2hvcikpIHtcbiAgICAgICAgbGFzdCA9IHBhcnNlSW50KGxhc3QpO1xuICAgICAgICB2YWxpZGF0ZUludGVnZXIobGFzdCk7XG4gICAgICAgIGFzc2lnblByb3BlcnR5KGFuY2hvciwgbGFzdCwgdmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGFzc2lnblByb3BlcnR5KGFuY2hvciwgbGFzdCwgdmFsdWUpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtvYmplY3R9IG9iamVjdFxuICogQHBhcmFtIHtzdHJpbmd9IGtleVxuICogQHBhcmFtIHsqfSB2YWx1ZVxuICovXG5mdW5jdGlvbiBhc3NpZ25Qcm9wZXJ0eShvYmplY3QsIGtleSwgdmFsdWUpIHtcbiAgICBpZiAoIW9iamVjdC5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgIG9iamVjdFtrZXldID0gdmFsdWU7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBkZWxldGUgb2JqZWN0W2tleV07XG4gICAgfVxuXG4gICAgb2JqZWN0W2tleV0gPSB2YWx1ZTtcbn1cblxuLyoqXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IHN1YmplY3RcbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdW5zdXBwb3J0ZWQgdHlwZVxuICogQHRocm93cyB7VHlwZUVycm9yfSB1bnN1cHBvcnRlZCB0eXBlXG4gKiBAdGhyb3dzIHtFcnJvcn0gdGhlIGpvdXJuZXkgaXMgbm90IGF0IGl0cyBlbmRcbiAqIEB0aHJvd3Mge0Vycm9yfSB1bnN1cHBvcnRlZCBhY3Rpb24gZm9yIHRoaXMgZGF0YSB0eXBlXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjYuMFxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gZGVsZXRlVmFsdWVWaWFQYXRoKHN1YmplY3QsIHBhdGgpIHtcbiAgICBpZiAoIShpc0FycmF5KHBhdGgpIHx8IGlzU3RyaW5nKHBhdGgpKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0eXBlIGVycm9yOiBwYXRoIG11c3QgYmUgYSBzdHJpbmcgb3IgYW4gYXJyYXlcIik7XG4gICAgfVxuXG4gICAgbGV0IHBhcnRzO1xuICAgIGlmIChpc0FycmF5KHBhdGgpKSB7XG4gICAgICAgIGlmIChwYXRoLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHN1YmplY3Q7XG4gICAgICAgIH1cblxuICAgICAgICBwYXJ0cyA9IHBhdGg7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcGFydHMgPSBwYXRoLnNwbGl0KERFTElNSVRFUik7XG4gICAgfVxuXG4gICAgbGV0IGxhc3QgPSBwYXJ0cy5wb3AoKTtcbiAgICBjb25zdCBzdWJwYXRoID0gcGFydHMuam9pbihERUxJTUlURVIpO1xuXG4gICAgY29uc3QgYW5jaG9yID0gZ2V0VmFsdWVWaWFQYXRoLmNhbGwodGhpcywgc3ViamVjdCwgc3VicGF0aCk7XG5cbiAgICBpZiAoYW5jaG9yIGluc3RhbmNlb2YgTWFwKSB7XG4gICAgICAgIGFuY2hvci5kZWxldGUobGFzdCk7XG4gICAgfSBlbHNlIGlmIChcbiAgICAgICAgYW5jaG9yIGluc3RhbmNlb2YgU2V0IHx8XG4gICAgICAgIGFuY2hvciBpbnN0YW5jZW9mIFdlYWtNYXAgfHxcbiAgICAgICAgYW5jaG9yIGluc3RhbmNlb2YgV2Vha1NldCB8fFxuICAgICAgICAodHlwZW9mIFdlYWtSZWYgPT09IFwiZnVuY3Rpb25cIiAmJiBhbmNob3IgaW5zdGFuY2VvZiBXZWFrUmVmKVxuICAgICkge1xuICAgICAgICB0aHJvdyBFcnJvcihcInVuc3VwcG9ydGVkIGFjdGlvbiBmb3IgdGhpcyBkYXRhIHR5cGVcIik7XG4gICAgfSBlbHNlIGlmIChpc0FycmF5KGFuY2hvcikpIHtcbiAgICAgICAgbGFzdCA9IHBhcnNlSW50KGxhc3QpO1xuICAgICAgICB2YWxpZGF0ZUludGVnZXIobGFzdCk7XG4gICAgICAgIGRlbGV0ZSBhbmNob3JbbGFzdF07XG4gICAgfSBlbHNlIHtcbiAgICAgICAgZGVsZXRlIGFuY2hvcltsYXN0XTtcbiAgICB9XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBpbnRlcm5hbFN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQgeyBleHRlbmQgfSBmcm9tIFwiLi4vZGF0YS9leHRlbmQubWpzXCI7XG5pbXBvcnQgeyBQYXRoZmluZGVyIH0gZnJvbSBcIi4uL2RhdGEvcGF0aGZpbmRlci5tanNcIjtcbmltcG9ydCB7IEJhc2UgfSBmcm9tIFwiLi9iYXNlLm1qc1wiO1xuaW1wb3J0IHsgdmFsaWRhdGVPYmplY3QgfSBmcm9tIFwiLi92YWxpZGF0ZS5tanNcIjtcblxuZXhwb3J0IHsgQmFzZVdpdGhPcHRpb25zIH07XG5cbi8qKlxuICogVGhpcyBpcyB0aGUgYmFzZSBjbGFzcyB3aXRoIG9wdGlvbnMgZnJvbSB3aGljaCBzb21lIG1vbnN0ZXIgY2xhc3NlcyBhcmUgZGVyaXZlZC5cbiAqXG4gKiBUaGlzIGNsYXNzIGlzIGFjdHVhbGx5IG9ubHkgdXNlZCBhcyBhIGJhc2UgY2xhc3MuXG4gKlxuICogQ2xhc3NlcyB0aGF0IHJlcXVpcmUgdGhlIHBvc3NpYmlsaXR5IG9mIG9wdGlvbnMgY2FuIGJlIGRlcml2ZWQgZGlyZWN0bHkgZnJvbSB0aGlzIGNsYXNzLlxuICogRGVyaXZlZCBjbGFzc2VzIGFsbW9zdCBhbHdheXMgb3ZlcnJpZGUgdGhlIGBkZWZhdWxgIGdldHRlciB3aXRoIHRoZWlyIG93biB2YWx1ZXMuXG4gKlxuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL3R5cGVzL2Jhc2V3aXRob3B0aW9ucy5tanNcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMTMuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKiBAZGVwcmVjYXRlZCBzaW5jZSAzLjE1LjAgdXNlIHtAbGluayBNb25zdGVyLlR5cGVzLkJhc2V9IHdpdGgge0BsaW5rIE1vbnN0ZXIuVHlwZXMuZXF1aXBXaXRoSW50ZXJuYWx9IGluc3RlYWQuXG4gKi9cbmNsYXNzIEJhc2VXaXRoT3B0aW9ucyBleHRlbmRzIEJhc2Uge1xuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtvYmplY3R9IG9wdGlvbnNcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKCk7XG5cbiAgICAgICAgaWYgKG9wdGlvbnMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpc1tpbnRlcm5hbFN5bWJvbF0gPSBleHRlbmQoe30sIHRoaXMuZGVmYXVsdHMsIHZhbGlkYXRlT2JqZWN0KG9wdGlvbnMpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGdldHRlciBwcm92aWRlcyB0aGUgb3B0aW9ucy4gRGVyaXZlZCBjbGFzc2VzIG92ZXJ3cml0ZVxuICAgICAqIHRoaXMgZ2V0dGVyIHdpdGggdGhlaXIgb3duIHZhbHVlcy4gSXQgaXMgZ29vZCBrYXJtYSB0byBhbHdheXMgaW5jbHVkZVxuICAgICAqIHRoZSB2YWx1ZXMgZnJvbSB0aGUgcGFyZW50IGNsYXNzLlxuICAgICAqXG4gICAgICogYGBgamF2YXNjcmlwdFxuICAgICAqIGdldCBkZWZhdWx0cygpIHtcbiAgICAgKiAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN1cGVyLmRlZmF1bHRzLCB7XG4gICAgICogICAgICAgICBteWtleTogdHJ1ZVxuICAgICAqICAgICB9KTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEByZXR1cm4ge29iamVjdH1cbiAgICAgKi9cbiAgICBnZXQgZGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBuZXN0ZWQgb3B0aW9ucyBjYW4gYmUgc3BlY2lmaWVkIGJ5IHBhdGggYGEuYi5jYFxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHBhdGhcbiAgICAgKiBAcGFyYW0geyp9IGRlZmF1bHRWYWx1ZVxuICAgICAqIEByZXR1cm4geyp9XG4gICAgICogQHNpbmNlIDEuMTAuMFxuICAgICAqL1xuICAgIGdldE9wdGlvbihwYXRoLCBkZWZhdWx0VmFsdWUpIHtcbiAgICAgICAgbGV0IHZhbHVlO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB2YWx1ZSA9IG5ldyBQYXRoZmluZGVyKHRoaXNbaW50ZXJuYWxTeW1ib2xdKS5nZXRWaWEocGF0aCk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHt9XG5cbiAgICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHJldHVybiBkZWZhdWx0VmFsdWU7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBpbnN0YW5jZVN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQgeyBoYXNPYmplY3RMaW5rLCBnZXRMaW5rZWRPYmplY3RzLCBhZGRUb09iamVjdExpbmsgfSBmcm9tIFwiLi4vZG9tL2F0dHJpYnV0ZXMubWpzXCI7XG5pbXBvcnQgeyBnZXRMb2NhbGVPZkRvY3VtZW50IH0gZnJvbSBcIi4uL2RvbS9sb2NhbGUubWpzXCI7XG5pbXBvcnQgeyBCYXNlV2l0aE9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXMvYmFzZXdpdGhvcHRpb25zLm1qc1wiO1xuaW1wb3J0IHsgTG9jYWxlIH0gZnJvbSBcIi4vbG9jYWxlLm1qc1wiO1xuaW1wb3J0IHsgVHJhbnNsYXRpb25zIH0gZnJvbSBcIi4vdHJhbnNsYXRpb25zLm1qc1wiO1xuXG5leHBvcnQgeyBQcm92aWRlciwgdHJhbnNsYXRpb25zTGlua1N5bWJvbCB9O1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkkxOG5cbiAqIEB0eXBlIHtzeW1ib2x9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAzLjkuMFxuICogQHByaXZhdGVcbiAqL1xuY29uc3QgdHJhbnNsYXRpb25zTGlua1N5bWJvbCA9IFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL2kxOG4vdHJhbnNsYXRpb25zQEBsaW5rXCIpO1xuXG4vKipcbiAqIEEgcHJvdmlkZXIgbWFrZXMgYSB0cmFuc2xhdGlvbiBvYmplY3QgYXZhaWxhYmxlLlxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMTMuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkkxOG5cbiAqIEBzZWUge0BsaW5rIGh0dHBzOi8vZGF0YXRyYWNrZXIuaWV0Zi5vcmcvZG9jL2h0bWwvcmZjMzA2Nn1cbiAqL1xuY2xhc3MgUHJvdmlkZXIgZXh0ZW5kcyBCYXNlV2l0aE9wdGlvbnMge1xuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgYGluc3RhbmNlb2ZgIG9wZXJhdG9yLlxuICAgICAqIEByZXR1cm5zIHtzeW1ib2x9XG4gICAgICogQHNpbmNlIDMuMjcuMFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgW2luc3RhbmNlU3ltYm9sXSgpIHtcbiAgICAgICAgcmV0dXJuIFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL2kxOG4vcHJvdmlkZXJAQGluc3RhbmNlXCIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TG9jYWxlfHN0cmluZ30gbG9jYWxlXG4gICAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICAgKi9cbiAgICBnZXRUcmFuc2xhdGlvbnMobG9jYWxlKSB7XG4gICAgICAgIGlmIChsb2NhbGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgbG9jYWxlID0gZ2V0TG9jYWxlT2ZEb2N1bWVudCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShuZXcgVHJhbnNsYXRpb25zKGxvY2FsZSkpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIHJlamVjdChlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtMb2NhbGV8c3RyaW5nfSBsb2NhbGVcbiAgICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gICAgICogQHJldHVybiB7UHJvdmlkZXJ9XG4gICAgICovXG4gICAgYXNzaWduVG9FbGVtZW50KGxvY2FsZSwgZWxlbWVudCkge1xuICAgICAgICBpZiAobG9jYWxlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGxvY2FsZSA9IGdldExvY2FsZU9mRG9jdW1lbnQoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghKGxvY2FsZSBpbnN0YW5jZW9mIExvY2FsZSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkxvY2FsZSBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgTG9jYWxlXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCEoZWxlbWVudCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSkge1xuICAgICAgICAgICAgZWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJib2R5XCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCEoZWxlbWVudCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRWxlbWVudCBpcyBub3QgYW4gSFRNTEVsZW1lbnRcIik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcy5nZXRUcmFuc2xhdGlvbnMobG9jYWxlKS50aGVuKChvYmopID0+IHtcbiAgICAgICAgICAgIGxldCB0cmFuc2xhdGlvbnMgPSBudWxsO1xuICAgICAgICAgICAgaWYgKGhhc09iamVjdExpbmsoZWxlbWVudCwgdHJhbnNsYXRpb25zTGlua1N5bWJvbCkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvYmplY3RzID0gZ2V0TGlua2VkT2JqZWN0cyhlbGVtZW50LCB0cmFuc2xhdGlvbnNMaW5rU3ltYm9sKTtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IG8gb2Ygb2JqZWN0cykge1xuICAgICAgICAgICAgICAgICAgICBpZiAobyBpbnN0YW5jZW9mIFRyYW5zbGF0aW9ucykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRpb25zID0gbztcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKCEodHJhbnNsYXRpb25zIGluc3RhbmNlb2YgVHJhbnNsYXRpb25zKSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJPYmplY3QgaXMgbm90IGFuIGluc3RhbmNlIG9mIFRyYW5zbGF0aW9uc1wiKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0cmFuc2xhdGlvbnMuYXNzaWduVHJhbnNsYXRpb25zKG9iaik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGFkZFRvT2JqZWN0TGluayhlbGVtZW50LCB0cmFuc2xhdGlvbnNMaW5rU3ltYm9sLCBvYmopO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gb2JqO1xuICAgICAgICB9KTtcbiAgICB9XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBpbnN0YW5jZVN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQgeyBnZXRMaW5rZWRPYmplY3RzLCBoYXNPYmplY3RMaW5rIH0gZnJvbSBcIi4uL2RvbS9hdHRyaWJ1dGVzLm1qc1wiO1xuaW1wb3J0IHsgQVRUUklCVVRFX09CSkVDVExJTksgfSBmcm9tIFwiLi4vZG9tL2NvbnN0YW50cy5tanNcIjtcbmltcG9ydCB7IGdldERvY3VtZW50IH0gZnJvbSBcIi4uL2RvbS91dGlsLm1qc1wiO1xuaW1wb3J0IHsgQmFzZSB9IGZyb20gXCIuLi90eXBlcy9iYXNlLm1qc1wiO1xuaW1wb3J0IHsgaXNPYmplY3QsIGlzU3RyaW5nIH0gZnJvbSBcIi4uL3R5cGVzL2lzLm1qc1wiO1xuaW1wb3J0IHsgdmFsaWRhdGVJbnRlZ2VyLCB2YWxpZGF0ZU9iamVjdCwgdmFsaWRhdGVTdHJpbmcgfSBmcm9tIFwiLi4vdHlwZXMvdmFsaWRhdGUubWpzXCI7XG5pbXBvcnQgeyBMb2NhbGUsIHBhcnNlTG9jYWxlIH0gZnJvbSBcIi4vbG9jYWxlLm1qc1wiO1xuaW1wb3J0IHsgdHJhbnNsYXRpb25zTGlua1N5bWJvbCB9IGZyb20gXCIuL3Byb3ZpZGVyLm1qc1wiO1xuXG5leHBvcnQgeyBUcmFuc2xhdGlvbnMsIGdldERvY3VtZW50VHJhbnNsYXRpb25zIH07XG5cbi8qKlxuICogV2l0aCB0aGlzIGNsYXNzIHlvdSBjYW4gbWFuYWdlIHRyYW5zbGF0aW9ucyBhbmQgYWNjZXNzIHRoZSBrZXlzLlxuICpcbiAqIEBleHRlcm5hbEV4YW1wbGUgLi4vLi4vZXhhbXBsZS9pMThuL3RyYW5zbGF0aW9ucy5tanNcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMTMuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkkxOG5cbiAqIEBzZWUgaHR0cHM6Ly9kYXRhdHJhY2tlci5pZXRmLm9yZy9kb2MvaHRtbC9yZmMzMDY2XG4gKi9cbmNsYXNzIFRyYW5zbGF0aW9ucyBleHRlbmRzIEJhc2Uge1xuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtMb2NhbGV9IGxvY2FsZVxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGxvY2FsZSkge1xuICAgICAgICBzdXBlcigpO1xuXG4gICAgICAgIGlmIChsb2NhbGUgaW5zdGFuY2VvZiBMb2NhbGUpIHtcbiAgICAgICAgICAgIHRoaXMubG9jYWxlID0gbG9jYWxlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5sb2NhbGUgPSBwYXJzZUxvY2FsZSh2YWxpZGF0ZVN0cmluZyhsb2NhbGUpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc3RvcmFnZSA9IG5ldyBNYXAoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGBpbnN0YW5jZW9mYCBvcGVyYXRvci5cbiAgICAgKiBAcmV0dXJucyB7c3ltYm9sfVxuICAgICAqIEBzaW5jZSAzLjI3LjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci9pMThuL3RyYW5zbGF0aW9uc0BAaW5zdGFuY2VcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmV0Y2hlcyBhIHRleHQgdXNpbmcgdGhlIHNwZWNpZmllZCBrZXkuXG4gICAgICogSWYgbm8gc3VpdGFibGUga2V5IGlzIGZvdW5kLCBgZGVmYXVsdFRleHRgIGlzIHRha2VuLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfHVuZGVmaW5lZH0gZGVmYXVsdFRleHRcbiAgICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAgICogQHRocm93cyB7RXJyb3J9IGtleSBub3QgZm91bmRcbiAgICAgKi9cbiAgICBnZXRUZXh0KGtleSwgZGVmYXVsdFRleHQpIHtcbiAgICAgICAgaWYgKCF0aGlzLnN0b3JhZ2UuaGFzKGtleSkpIHtcbiAgICAgICAgICAgIGlmIChkZWZhdWx0VGV4dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBrZXkgJHtrZXl9IG5vdCBmb3VuZGApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gdmFsaWRhdGVTdHJpbmcoZGVmYXVsdFRleHQpO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHIgPSB0aGlzLnN0b3JhZ2UuZ2V0KGtleSk7XG4gICAgICAgIGlmIChpc09iamVjdChyKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGx1cmFsUnVsZVRleHQoa2V5LCBcIm90aGVyXCIsIGRlZmF1bHRUZXh0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzLnN0b3JhZ2UuZ2V0KGtleSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBudW1iZXIgYGNvdW50YCBjYW4gYmUgcGFzc2VkIHRvIHRoaXMgbWV0aG9kLiBJbiBhZGRpdGlvbiB0byBhIG51bWJlciwgb25lIG9mIHRoZSBrZXl3b3JkcyBjYW4gYWxzbyBiZSBwYXNzZWQgZGlyZWN0bHkuXG4gICAgICogXCJ6ZXJvXCIsIFwib25lXCIsIFwidHdvXCIsIFwiZmV3XCIsIFwibWFueVwiIGFuZCBcIm90aGVyXCIuIFJlbWVtYmVyOiBub3QgZXZlcnkgbGFuZ3VhZ2UgaGFzIGFsbCBydWxlcy5cbiAgICAgKlxuICAgICAqIFRoZSBhcHByb3ByaWF0ZSB0ZXh0IGZvciB0aGlzIG51bWJlciBpcyB0aGVuIHNlbGVjdGVkLiBJZiBubyBzdWl0YWJsZSBrZXkgaXMgZm91bmQsIGBkZWZhdWx0VGV4dGAgaXMgdGFrZW4uXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5XG4gICAgICogQHBhcmFtIHtpbnRlZ2VyfGNvdW50fSBjb3VudFxuICAgICAqIEBwYXJhbSB7c3RyaW5nfHVuZGVmaW5lZH0gZGVmYXVsdFRleHRcbiAgICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAgICovXG4gICAgZ2V0UGx1cmFsUnVsZVRleHQoa2V5LCBjb3VudCwgZGVmYXVsdFRleHQpIHtcbiAgICAgICAgaWYgKCF0aGlzLnN0b3JhZ2UuaGFzKGtleSkpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWxpZGF0ZVN0cmluZyhkZWZhdWx0VGV4dCk7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgciA9IHZhbGlkYXRlT2JqZWN0KHRoaXMuc3RvcmFnZS5nZXQoa2V5KSk7XG5cbiAgICAgICAgbGV0IGtleXdvcmQ7XG4gICAgICAgIGlmIChpc1N0cmluZyhjb3VudCkpIHtcbiAgICAgICAgICAgIGtleXdvcmQgPSBjb3VudC50b0xvY2FsZVN0cmluZygpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY291bnQgPSB2YWxpZGF0ZUludGVnZXIoY291bnQpO1xuICAgICAgICAgICAgaWYgKGNvdW50ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgLy8gc3BlY2lhbCBoYW5kbGluZyBmb3IgemVybyBjb3VudFxuICAgICAgICAgICAgICAgIGlmIChyLmhhc093blByb3BlcnR5KFwiemVyb1wiKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsaWRhdGVTdHJpbmcocltcInplcm9cIl0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAga2V5d29yZCA9IG5ldyBJbnRsLlBsdXJhbFJ1bGVzKHRoaXMubG9jYWxlLnRvU3RyaW5nKCkpLnNlbGVjdCh2YWxpZGF0ZUludGVnZXIoY291bnQpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChyLmhhc093blByb3BlcnR5KGtleXdvcmQpKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsaWRhdGVTdHJpbmcocltrZXl3b3JkXSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBAZGVwcmVjYXRlZCBzaW5jZSAyMDIzLTAzLTE0XG4gICAgICAgIC8vIERFRkFVTFRfS0VZIGlzIHVuZGVmaW5lZFxuICAgICAgICAvLyBpZiAoci5oYXNPd25Qcm9wZXJ0eShERUZBVUxUX0tFWSkpIHtcbiAgICAgICAgLy8gICAgIHJldHVybiB2YWxpZGF0ZVN0cmluZyhyW0RFRkFVTFRfS0VZXSk7XG4gICAgICAgIC8vIH1cblxuICAgICAgICByZXR1cm4gdmFsaWRhdGVTdHJpbmcoZGVmYXVsdFRleHQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldCBhIHRleHQgZm9yIGEga2V5XG4gICAgICpcbiAgICAgKiBgYGBcbiAgICAgKiB0cmFuc2xhdGlvbnMuc2V0VGV4dChcInRleHQxXCIsIFwiTWFrZSBteSBkYXkhXCIpO1xuICAgICAqIC8vIHBsdXJhbCBydWxlc1xuICAgICAqIHRyYW5zbGF0aW9ucy5zZXRUZXh0KFwidGV4dDZcIiwge1xuICAgICAqICAgICBcInplcm9cIjogXCJUaGVyZSBhcmUgbm8gZmlsZXMgb24gRGlzay5cIixcbiAgICAgKiAgICAgXCJvbmVcIjogXCJUaGVyZSBpcyBvbmUgZmlsZSBvbiBEaXNrLlwiLFxuICAgICAqICAgICBcIm90aGVyXCI6IFwiVGhlcmUgYXJlIGZpbGVzIG9uIERpc2suXCJcbiAgICAgKiAgICAgXCJkZWZhdWx0XCI6IFwiVGhlcmUgYXJlIGZpbGVzIG9uIERpc2suXCJcbiAgICAgKiB9KTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXlcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xvYmplY3R9IHRleHRcbiAgICAgKiBAcmV0dXJuIHtUcmFuc2xhdGlvbnN9XG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYSBzdHJpbmcgb3Igb2JqZWN0XG4gICAgICovXG4gICAgc2V0VGV4dChrZXksIHRleHQpIHtcbiAgICAgICAgaWYgKGlzU3RyaW5nKHRleHQpIHx8IGlzT2JqZWN0KHRleHQpKSB7XG4gICAgICAgICAgICB0aGlzLnN0b3JhZ2Uuc2V0KHZhbGlkYXRlU3RyaW5nKGtleSksIHRleHQpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwidmFsdWUgaXMgbm90IGEgc3RyaW5nIG9yIG9iamVjdFwiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBjYW4gYmUgdXNlZCB0byB0cmFuc2ZlciBvdmVybGF5cyBmcm9tIGFuIG9iamVjdC4gVGhlIGtleXMgYXJlIHRyYW5zZmVycmVkLCBhbmQgdGhlIHZhbHVlcyBhcmUgZW50ZXJlZFxuICAgICAqIGFzIHRleHQuXG4gICAgICpcbiAgICAgKiBUaGUgdmFsdWVzIGNhbiBlaXRoZXIgYmUgY2hhcmFjdGVyIHN0cmluZ3Mgb3IsIGluIHRoZSBjYXNlIG9mIHRleHRzIHdpdGggcGx1cmFsIGZvcm1zLCBvYmplY3RzLiBUaGUgcGx1cmFsIGZvcm1zXG4gICAgICogbXVzdCBiZSBzdG9yZWQgYXMgdGV4dCB2aWEgYSBzdGFuZGFyZCBrZXkgXCJ6ZXJvXCIsIFwib25lXCIsIFwidHdvXCIsIFwiZmV3XCIsIFwibWFueVwiIGFuZCBcIm90aGVyXCIuXG4gICAgICpcbiAgICAgKiBBZGRpdGlvbmFsbHksIHRoZSBrZXkgZGVmYXVsdCBjYW4gYmUgc3BlY2lmaWVkLCB3aGljaCB3aWxsIGJlIHVzZWQgaWYgbm8gb3RoZXIga2V5IGZpdHMuXG4gICAgICpcbiAgICAgKiBJbiBzb21lIGxhbmd1YWdlcywgbGlrZSBmb3IgZXhhbXBsZSBpbiBHZXJtYW4sIHRoZXJlIGlzIG5vIG93biBtb3JlIG51bWJlciBhdCB0aGUgdmFsdWUgMC4gSW4gdGhlc2UgbGFuZ3VhZ2VzLFxuICAgICAqIHRoZSBmdW5jdGlvbiBhcHBsaWVzIGFkZGl0aW9uYWxseSB6ZXJvLlxuICAgICAqXG4gICAgICogYGBgXG4gICAgICogdHJhbnNsYXRpb25zLmFzc2lnblRyYW5zbGF0aW9ucyh7XG4gICAgICogICBcInRleHQxXCI6IFwiTWFrZSBteSBkYXkhXCIsXG4gICAgICogICBcInRleHQyXCI6IFwiSSdsbCBiZSBiYWNrIVwiLFxuICAgICAqICAgXCJ0ZXh0NlwiOiB7XG4gICAgICogICAgIFwiemVyb1wiOiBcIlRoZXJlIGFyZSBubyBmaWxlcyBvbiBEaXNrLlwiLFxuICAgICAqICAgICBcIm9uZVwiOiBcIlRoZXJlIGlzIG9uZSBmaWxlIG9uIERpc2suXCIsXG4gICAgICogICAgIFwib3RoZXJcIjogXCJUaGVyZSBhcmUgZmlsZXMgb24gRGlzay5cIlxuICAgICAqICAgICBcImRlZmF1bHRcIjogXCJUaGVyZSBhcmUgZmlsZXMgb24gRGlzay5cIlxuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQHBhcmFtIHtvYmplY3R9IHRyYW5zbGF0aW9uc1xuICAgICAqIEByZXR1cm4ge1RyYW5zbGF0aW9uc31cbiAgICAgKi9cbiAgICBhc3NpZ25UcmFuc2xhdGlvbnModHJhbnNsYXRpb25zKSB7XG4gICAgICAgIHZhbGlkYXRlT2JqZWN0KHRyYW5zbGF0aW9ucyk7XG5cbiAgICAgICAgaWYgKHRyYW5zbGF0aW9ucyBpbnN0YW5jZW9mIFRyYW5zbGF0aW9ucykge1xuICAgICAgICAgICAgdHJhbnNsYXRpb25zLnN0b3JhZ2UuZm9yRWFjaCgodiwgaykgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0VGV4dChrLCB2KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGNvbnN0IFtrLCB2XSBvZiBPYmplY3QuZW50cmllcyh0cmFuc2xhdGlvbnMpKSB7XG4gICAgICAgICAgICB0aGlzLnNldFRleHQoaywgdik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgdHJhbnNsYXRpb25zIGZvciB0aGUgY3VycmVudCBkb2N1bWVudC5cbiAqXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fHVuZGVmaW5lZH0gW2VsZW1lbnRdIC0gRWxlbWVudCB0byBzZWFyY2ggZm9yIHRyYW5zbGF0aW9ucy4gRGVmYXVsdDogZWxlbWVudCB3aXRoIG9iamVjdGxpbmsgQHNjaHVrYWkvbW9uc3Rlci9pMThuL3RyYW5zbGF0aW9uc0BAbGluay5cbiAqIEByZXR1cm5zIHtUcmFuc2xhdGlvbnN9XG4gKiBAdGhyb3dzIHtFcnJvcn0gRWxlbWVudCBpcyBub3QgYW4gSFRNTEVsZW1lbnQuXG4gKiBAdGhyb3dzIHtFcnJvcn0gQ2Fubm90IGZpbmQgZWxlbWVudCB3aXRoIHRyYW5zbGF0aW9ucy4gQWRkIGEgdHJhbnNsYXRpb25zIG9iamVjdCB0byB0aGUgZG9jdW1lbnQuXG4gKiBAdGhyb3dzIHtFcnJvcn0gVGhpcyBlbGVtZW50IGhhcyBubyB0cmFuc2xhdGlvbnMuXG4gKiBAdGhyb3dzIHtFcnJvcn0gTWlzc2luZyB0cmFuc2xhdGlvbnMuXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5JMThuXG4gKi9cbmZ1bmN0aW9uIGdldERvY3VtZW50VHJhbnNsYXRpb25zKGVsZW1lbnQpIHtcbiAgICBjb25zdCBkID0gZ2V0RG9jdW1lbnQoKTtcblxuICAgIGlmICghKGVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpIHtcbiAgICAgICAgZWxlbWVudCA9IGQucXVlcnlTZWxlY3RvcihgWyR7QVRUUklCVVRFX09CSkVDVExJTkt9fj1cIiR7dHJhbnNsYXRpb25zTGlua1N5bWJvbC50b1N0cmluZygpfVwiXWApO1xuICAgICAgICBpZiAoZWxlbWVudCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgZWxlbWVudCB3aXRoIHRyYW5zbGF0aW9ucy4gQWRkIGEgdHJhbnNsYXRpb25zIG9iamVjdCB0byB0aGUgZG9jdW1lbnQuXCIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCEoZWxlbWVudCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJFbGVtZW50IGlzIG5vdCBhbiBIVE1MRWxlbWVudC5cIik7XG4gICAgfVxuXG4gICAgaWYgKCFoYXNPYmplY3RMaW5rKGVsZW1lbnQsIHRyYW5zbGF0aW9uc0xpbmtTeW1ib2wpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaXMgZWxlbWVudCBoYXMgbm8gdHJhbnNsYXRpb25zLlwiKTtcbiAgICB9XG5cbiAgICBsZXQgb2JqID0gZ2V0TGlua2VkT2JqZWN0cyhlbGVtZW50LCB0cmFuc2xhdGlvbnNMaW5rU3ltYm9sKTtcblxuICAgIGZvciAoY29uc3QgdCBvZiBvYmopIHtcbiAgICAgICAgaWYgKHQgaW5zdGFuY2VvZiBUcmFuc2xhdGlvbnMpIHtcbiAgICAgICAgICAgIHJldHVybiB0O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyB0cmFuc2xhdGlvbnMuXCIpO1xufVxuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgZ2V0TG9jYWxlT2ZEb2N1bWVudCB9IGZyb20gXCIuLi9kb20vbG9jYWxlLm1qc1wiO1xuaW1wb3J0IHsgQmFzZSB9IGZyb20gXCIuLi90eXBlcy9iYXNlLm1qc1wiO1xuaW1wb3J0IHsgZ2V0R2xvYmFsLCBnZXRHbG9iYWxPYmplY3QgfSBmcm9tIFwiLi4vdHlwZXMvZ2xvYmFsLm1qc1wiO1xuaW1wb3J0IHsgSUQgfSBmcm9tIFwiLi4vdHlwZXMvaWQubWpzXCI7XG5pbXBvcnQgeyBpc0FycmF5LCBpc09iamVjdCwgaXNTdHJpbmcsIGlzUHJpbWl0aXZlIH0gZnJvbSBcIi4uL3R5cGVzL2lzLm1qc1wiO1xuaW1wb3J0IHsgZ2V0RG9jdW1lbnRUcmFuc2xhdGlvbnMsIFRyYW5zbGF0aW9ucyB9IGZyb20gXCIuLi9pMThuL3RyYW5zbGF0aW9ucy5tanNcIjtcbmltcG9ydCB7XG4gICAgdmFsaWRhdGVGdW5jdGlvbixcbiAgICB2YWxpZGF0ZUludGVnZXIsXG4gICAgdmFsaWRhdGVPYmplY3QsXG4gICAgdmFsaWRhdGVQcmltaXRpdmUsXG4gICAgdmFsaWRhdGVTdHJpbmcsXG4gICAgdmFsaWRhdGVCb29sZWFuLFxufSBmcm9tIFwiLi4vdHlwZXMvdmFsaWRhdGUubWpzXCI7XG5pbXBvcnQgeyBjbG9uZSB9IGZyb20gXCIuLi91dGlsL2Nsb25lLm1qc1wiO1xuaW1wb3J0IHsgUGF0aGZpbmRlciB9IGZyb20gXCIuL3BhdGhmaW5kZXIubWpzXCI7XG5cbmV4cG9ydCB7IFRyYW5zZm9ybWVyIH07XG5cbi8qKlxuICogVGhlIHRyYW5zZm9ybWVyIGNsYXNzIGlzIGEgc3dpc3MgYXJteSBrbmlmZSBmb3IgbWFuaXB1bGF0aW5nIHZhbHVlcy4gZXNwZWNpYWxseSBpbiBjb21iaW5hdGlvbiB3aXRoIHRoZSBwaXBlLCBwcm9jZXNzaW5nIGNoYWlucyBjYW4gYmUgYnVpbHQgdXAuXG4gKlxuICogQSBzaW1wbGUgZXhhbXBsZSBpcyB0aGUgY29udmVyc2lvbiBvZiBhbGwgY2hhcmFjdGVycyB0byBsb3dlcmNhc2UuIGZvciB0aGlzIHB1cnBvc2UgdGhlIGNvbW1hbmQgYHRvbG93ZXJgIG11c3QgYmUgdXNlZC5cbiAqXG4gKiBgYGBcbiAqIGxldCB0ID0gbmV3IFRyYW5zZm9ybWVyKCd0b2xvd2VyJykucnVuKCdBQkMnKTsgLy8gXHUyMUE2IGFiY1xuICogYGBgXG4gKlxuICogQHNlZSB7QGxpbmsgaHR0cHM6Ly9tb25zdGVyanMub3JnL2VuL2RvYy8jdHJhbnNmb3JtZXJ8TW9uc3RlciBEb2NzfVxuICpcbiAqIEBleHRlcm5hbEV4YW1wbGUgLi4vLi4vZXhhbXBsZS9kYXRhL3RyYW5zZm9ybWVyLm1qc1xuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS41LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5EYXRhXG4gKi9cbmNsYXNzIFRyYW5zZm9ybWVyIGV4dGVuZHMgQmFzZSB7XG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gZGVmaW5pdGlvblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGRlZmluaXRpb24pIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5hcmdzID0gZGlzYXNzZW1ibGUoZGVmaW5pdGlvbik7XG4gICAgICAgIHRoaXMuY29tbWFuZCA9IHRoaXMuYXJncy5zaGlmdCgpO1xuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IG5ldyBNYXAoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2tcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gY29udGV4dFxuICAgICAqIEByZXR1cm5zIHtUcmFuc2Zvcm1lcn1cbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIHN0cmluZ1xuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgZnVuY3Rpb25cbiAgICAgKi9cbiAgICBzZXRDYWxsYmFjayhuYW1lLCBjYWxsYmFjaywgY29udGV4dCkge1xuICAgICAgICB2YWxpZGF0ZVN0cmluZyhuYW1lKTtcbiAgICAgICAgdmFsaWRhdGVGdW5jdGlvbihjYWxsYmFjayk7XG5cbiAgICAgICAgaWYgKGNvbnRleHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdmFsaWRhdGVPYmplY3QoY29udGV4dCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNhbGxiYWNrcy5zZXQobmFtZSwge1xuICAgICAgICAgICAgY2FsbGJhY2s6IGNhbGxiYWNrLFxuICAgICAgICAgICAgY29udGV4dDogY29udGV4dCxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlXG4gICAgICogQHJldHVybnMgeyp9XG4gICAgICogQHRocm93cyB7RXJyb3J9IHVua25vd24gY29tbWFuZFxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdW5zdXBwb3J0ZWQgdHlwZVxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSB0eXBlIG5vdCBzdXBwb3J0ZWRcbiAgICAgKi9cbiAgICBydW4odmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHRyYW5zZm9ybS5hcHBseSh0aGlzLCBbdmFsdWVdKTtcbiAgICB9XG59XG5cbi8qKlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBjb21tYW5kXG4gKiBAcmV0dXJucyB7YXJyYXl9XG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBkaXNhc3NlbWJsZShjb21tYW5kKSB7XG4gICAgdmFsaWRhdGVTdHJpbmcoY29tbWFuZCk7XG5cbiAgICBsZXQgcGxhY2Vob2xkZXIgPSBuZXcgTWFwKCk7XG4gICAgY29uc3QgcmVnZXggPSAvKCg/PHBhdHRlcm4+XFxcXCg/PGNoYXI+LikpezF9KS9naW07XG5cbiAgICAvLyBUaGUgc2VwYXJhdG9yIGZvciBhcmdzIG11c3QgYmUgZXNjYXBlZFxuICAgIC8vIHVuZGVmaW5lZCBzdHJpbmcgd2hpY2ggc2hvdWxkIG5vdCBvY2N1ciBub3JtYWxseSBhbmQgaXMgYWxzbyBub3QgYSByZWdleFxuICAgIGxldCByZXN1bHQgPSBjb21tYW5kLm1hdGNoQWxsKHJlZ2V4KTtcblxuICAgIGZvciAobGV0IG0gb2YgcmVzdWx0KSB7XG4gICAgICAgIGxldCBnID0gbT8uW1wiZ3JvdXBzXCJdO1xuICAgICAgICBpZiAoIWlzT2JqZWN0KGcpKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBwID0gZz8uW1wicGF0dGVyblwiXTtcbiAgICAgICAgbGV0IGMgPSBnPy5bXCJjaGFyXCJdO1xuXG4gICAgICAgIGlmIChwICYmIGMpIHtcbiAgICAgICAgICAgIGxldCByID0gYF9fJHtuZXcgSUQoKS50b1N0cmluZygpfV9fYDtcbiAgICAgICAgICAgIHBsYWNlaG9sZGVyLnNldChyLCBjKTtcbiAgICAgICAgICAgIGNvbW1hbmQgPSBjb21tYW5kLnJlcGxhY2UocCwgcik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgbGV0IHBhcnRzID0gY29tbWFuZC5zcGxpdChcIjpcIik7XG5cbiAgICBwYXJ0cyA9IHBhcnRzLm1hcChmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgbGV0IHYgPSB2YWx1ZS50cmltKCk7XG4gICAgICAgIGZvciAobGV0IGsgb2YgcGxhY2Vob2xkZXIpIHtcbiAgICAgICAgICAgIHYgPSB2LnJlcGxhY2Uoa1swXSwga1sxXSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHY7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gcGFydHM7XG59XG5cbi8qKlxuICogdHJpZXMgdG8gbWFrZSBhIHN0cmluZyBvdXQgb2YgdmFsdWUgYW5kIGlmIHRoaXMgc3VjY2VlZHMgdG8gcmV0dXJuIGl0IGJhY2tcbiAqXG4gKiBAcGFyYW0geyp9IHZhbHVlXG4gKiBAcmV0dXJucyB7c3RyaW5nfVxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gY29udmVydFRvU3RyaW5nKHZhbHVlKSB7XG4gICAgaWYgKGlzT2JqZWN0KHZhbHVlKSAmJiB2YWx1ZS5oYXNPd25Qcm9wZXJ0eShcInRvU3RyaW5nXCIpKSB7XG4gICAgICAgIHZhbHVlID0gdmFsdWUudG9TdHJpbmcoKTtcbiAgICB9XG5cbiAgICB2YWxpZGF0ZVN0cmluZyh2YWx1ZSk7XG4gICAgcmV0dXJuIHZhbHVlO1xufVxuXG4vKipcbiAqXG4gKiBAcGFyYW0geyp9IHZhbHVlXG4gKiBAcmV0dXJucyB7Kn1cbiAqIEBwcml2YXRlXG4gKiBAdGhyb3dzIHtFcnJvcn0gdW5rbm93biBjb21tYW5kXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHVuc3VwcG9ydGVkIHR5cGVcbiAqIEB0aHJvd3Mge0Vycm9yfSB0eXBlIG5vdCBzdXBwb3J0ZWRcbiAqIEB0aHJvd3Mge0Vycm9yfSBtaXNzaW5nIGtleSBwYXJhbWV0ZXJcbiAqL1xuZnVuY3Rpb24gdHJhbnNmb3JtKHZhbHVlKSB7XG4gICAgY29uc3QgY29uc29sZSA9IGdldEdsb2JhbE9iamVjdChcImNvbnNvbGVcIik7XG5cbiAgICBsZXQgYXJncyA9IGNsb25lKHRoaXMuYXJncyk7XG4gICAgbGV0IGtleTtcbiAgICBsZXQgZGVmYXVsdFZhbHVlO1xuXG4gICAgbGV0IHRyYW5zbGF0aW9ucztcbiAgICBsZXQgZGF0ZTtcbiAgICBsZXQgbG9jYWxlO1xuICAgIGxldCB0aW1lc3RhbXA7XG4gICAgbGV0IG1hcDtcbiAgICBsZXQga2V5VmFsdWU7XG5cbiAgICBzd2l0Y2ggKHRoaXMuY29tbWFuZCkge1xuICAgICAgICBjYXNlIFwic3RhdGljXCI6XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5hcmdzLmpvaW4oXCI6XCIpO1xuXG4gICAgICAgIGNhc2UgXCJ0b2xvd2VyXCI6XG4gICAgICAgIGNhc2UgXCJzdHJ0b2xvd2VyXCI6XG4gICAgICAgIGNhc2UgXCJ0b2xvd2VyY2FzZVwiOlxuICAgICAgICAgICAgdmFsaWRhdGVTdHJpbmcodmFsdWUpO1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlLnRvTG93ZXJDYXNlKCk7XG5cbiAgICAgICAgY2FzZSBcImNvbnRhaW5zXCI6XG4gICAgICAgICAgICBpZiAoaXNTdHJpbmcodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlLmluY2x1ZGVzKGFyZ3NbMF0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWUuaW5jbHVkZXMoYXJnc1swXSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChpc09iamVjdCh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWUuaGFzT3duUHJvcGVydHkoYXJnc1swXSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcblxuICAgICAgICBjYXNlIFwiaGFzLWVudHJpZXNcIjpcbiAgICAgICAgY2FzZSBcImhhc2VudHJpZXNcIjpcbiAgICAgICAgICAgIGlmIChpc09iamVjdCh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gT2JqZWN0LmtleXModmFsdWUpLmxlbmd0aCA+IDA7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZS5sZW5ndGggPiAwO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgY2FzZSBcImlzdW5kZWZpbmVkXCI6XG4gICAgICAgIGNhc2UgXCJpcy11bmRlZmluZWRcIjpcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZSA9PT0gdW5kZWZpbmVkO1xuXG4gICAgICAgIGNhc2UgXCJpc251bGxcIjpcbiAgICAgICAgY2FzZSBcImlzLW51bGxcIjpcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZSA9PT0gbnVsbDtcblxuICAgICAgICBjYXNlIFwiaXNzZXRcIjpcbiAgICAgICAgY2FzZSBcImlzLXNldFwiOlxuICAgICAgICAgICAgcmV0dXJuIHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGw7XG5cbiAgICAgICAgY2FzZSBcImlzbnVtYmVyXCI6XG4gICAgICAgIGNhc2UgXCJpcy1udW1iZXJcIjpcbiAgICAgICAgICAgIHJldHVybiBpc1ByaW1pdGl2ZSh2YWx1ZSkgJiYgIWlzTmFOKHZhbHVlKTtcblxuICAgICAgICBjYXNlIFwiaXNpbnRlZ2VyXCI6XG4gICAgICAgIGNhc2UgXCJpcy1pbnRlZ2VyXCI6XG4gICAgICAgICAgICByZXR1cm4gaXNQcmltaXRpdmUodmFsdWUpICYmICFpc05hTih2YWx1ZSkgJiYgdmFsdWUgJSAxID09PSAwO1xuXG4gICAgICAgIGNhc2UgXCJpc2Zsb2F0XCI6XG4gICAgICAgIGNhc2UgXCJpcy1mbG9hdFwiOlxuICAgICAgICAgICAgcmV0dXJuIGlzUHJpbWl0aXZlKHZhbHVlKSAmJiAhaXNOYU4odmFsdWUpICYmIHZhbHVlICUgMSAhPT0gMDtcblxuICAgICAgICBjYXNlIFwiaXNvYmplY3RcIjpcbiAgICAgICAgY2FzZSBcImlzLW9iamVjdFwiOlxuICAgICAgICAgICAgcmV0dXJuIGlzT2JqZWN0KHZhbHVlKTtcblxuICAgICAgICBjYXNlIFwiaXNhcnJheVwiOlxuICAgICAgICBjYXNlIFwiaXMtYXJyYXlcIjpcbiAgICAgICAgICAgIHJldHVybiBBcnJheS5pc0FycmF5KHZhbHVlKTtcblxuICAgICAgICBjYXNlIFwibm90XCI6XG4gICAgICAgICAgICB2YWxpZGF0ZUJvb2xlYW4odmFsdWUpO1xuICAgICAgICAgICAgcmV0dXJuICF2YWx1ZTtcblxuICAgICAgICBjYXNlIFwidG91cHBlclwiOlxuICAgICAgICBjYXNlIFwic3RydG91cHBlclwiOlxuICAgICAgICBjYXNlIFwidG91cHBlcmNhc2VcIjpcbiAgICAgICAgICAgIHZhbGlkYXRlU3RyaW5nKHZhbHVlKTtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZS50b1VwcGVyQ2FzZSgpO1xuXG4gICAgICAgIGNhc2UgXCJ0b3N0cmluZ1wiOlxuICAgICAgICAgICAgcmV0dXJuIGAke3ZhbHVlfWA7XG5cbiAgICAgICAgY2FzZSBcInRvaW50ZWdlclwiOlxuICAgICAgICAgICAgbGV0IG4gPSBwYXJzZUludCh2YWx1ZSk7XG4gICAgICAgICAgICB2YWxpZGF0ZUludGVnZXIobik7XG4gICAgICAgICAgICByZXR1cm4gbjtcblxuICAgICAgICBjYXNlIFwidG8tanNvblwiOlxuICAgICAgICBjYXNlIFwidG9qc29uXCI6XG4gICAgICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodmFsdWUpO1xuXG4gICAgICAgIGNhc2UgXCJmcm9tLWpzb25cIjpcbiAgICAgICAgY2FzZSBcImZyb21qc29uXCI6XG4gICAgICAgICAgICByZXR1cm4gSlNPTi5wYXJzZSh2YWx1ZSk7XG5cbiAgICAgICAgY2FzZSBcInRyaW1cIjpcbiAgICAgICAgICAgIHZhbGlkYXRlU3RyaW5nKHZhbHVlKTtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZS50cmltKCk7XG5cbiAgICAgICAgY2FzZSBcInJhd3VybGVuY29kZVwiOlxuICAgICAgICAgICAgdmFsaWRhdGVTdHJpbmcodmFsdWUpO1xuICAgICAgICAgICAgcmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudCh2YWx1ZSlcbiAgICAgICAgICAgICAgICAucmVwbGFjZSgvIS9nLCBcIiUyMVwiKVxuICAgICAgICAgICAgICAgIC5yZXBsYWNlKC8nL2csIFwiJTI3XCIpXG4gICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xcKC9nLCBcIiUyOFwiKVxuICAgICAgICAgICAgICAgIC5yZXBsYWNlKC9cXCkvZywgXCIlMjlcIilcbiAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFwqL2csIFwiJTJBXCIpO1xuXG4gICAgICAgIGNhc2UgXCJjYWxsXCI6XG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIGNhbGxiYWNrLWRlZmluaXRpb25cbiAgICAgICAgICAgICAqIGZ1bmN0aW9uIGNhbGxiYWNrKHZhbHVlLCAuLi5hcmdzKSB7XG4gICAgICAgICAgICAgKiAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICAgICAqIH1cbiAgICAgICAgICAgICAqL1xuXG4gICAgICAgICAgICBsZXQgY2FsbGJhY2s7XG4gICAgICAgICAgICBsZXQgY2FsbGJhY2tOYW1lID0gYXJncy5zaGlmdCgpO1xuICAgICAgICAgICAgbGV0IGNvbnRleHQgPSBnZXRHbG9iYWwoKTtcblxuICAgICAgICAgICAgaWYgKGlzT2JqZWN0KHZhbHVlKSAmJiB2YWx1ZS5oYXNPd25Qcm9wZXJ0eShjYWxsYmFja05hbWUpKSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2sgPSB2YWx1ZVtjYWxsYmFja05hbWVdO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLmNhbGxiYWNrcy5oYXMoY2FsbGJhY2tOYW1lKSkge1xuICAgICAgICAgICAgICAgIGxldCBzID0gdGhpcy5jYWxsYmFja3MuZ2V0KGNhbGxiYWNrTmFtZSk7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2sgPSBzPy5bXCJjYWxsYmFja1wiXTtcbiAgICAgICAgICAgICAgICBjb250ZXh0ID0gcz8uW1wiY29udGV4dFwiXTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHdpbmRvdyA9PT0gXCJvYmplY3RcIiAmJiB3aW5kb3cuaGFzT3duUHJvcGVydHkoY2FsbGJhY2tOYW1lKSkge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrID0gd2luZG93W2NhbGxiYWNrTmFtZV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YWxpZGF0ZUZ1bmN0aW9uKGNhbGxiYWNrKTtcblxuICAgICAgICAgICAgYXJncy51bnNoaWZ0KHZhbHVlKTtcbiAgICAgICAgICAgIHJldHVybiBjYWxsYmFjay5jYWxsKGNvbnRleHQsIC4uLmFyZ3MpO1xuXG4gICAgICAgIGNhc2UgXCJwbGFpblwiOlxuICAgICAgICBjYXNlIFwicGxhaW50ZXh0XCI6XG4gICAgICAgICAgICB2YWxpZGF0ZVN0cmluZyh2YWx1ZSk7XG4gICAgICAgICAgICBsZXQgZG9jID0gbmV3IERPTVBhcnNlcigpLnBhcnNlRnJvbVN0cmluZyh2YWx1ZSwgXCJ0ZXh0L2h0bWxcIik7XG4gICAgICAgICAgICByZXR1cm4gZG9jLmJvZHkudGV4dENvbnRlbnQgfHwgXCJcIjtcblxuICAgICAgICBjYXNlIFwiaWZcIjpcbiAgICAgICAgY2FzZSBcIj9cIjpcbiAgICAgICAgICAgIHZhbGlkYXRlUHJpbWl0aXZlKHZhbHVlKTtcblxuICAgICAgICAgICAgbGV0IHRydWVTdGF0ZW1lbnQgPSBhcmdzLnNoaWZ0KCkgfHwgdW5kZWZpbmVkO1xuICAgICAgICAgICAgbGV0IGZhbHNlU3RhdGVtZW50ID0gYXJncy5zaGlmdCgpIHx8IHVuZGVmaW5lZDtcblxuICAgICAgICAgICAgaWYgKHRydWVTdGF0ZW1lbnQgPT09IFwidmFsdWVcIikge1xuICAgICAgICAgICAgICAgIHRydWVTdGF0ZW1lbnQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0cnVlU3RhdGVtZW50ID09PSBcIlxcXFx2YWx1ZVwiKSB7XG4gICAgICAgICAgICAgICAgdHJ1ZVN0YXRlbWVudCA9IFwidmFsdWVcIjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRydWVTdGF0ZW1lbnQgPT09IFwiXFxcXHVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICAgICAgdHJ1ZVN0YXRlbWVudCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRydWVTdGF0ZW1lbnQgPT09IFwiXFxcXG51bGxcIikge1xuICAgICAgICAgICAgICAgIHRydWVTdGF0ZW1lbnQgPSBudWxsO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoZmFsc2VTdGF0ZW1lbnQgPT09IFwidmFsdWVcIikge1xuICAgICAgICAgICAgICAgIGZhbHNlU3RhdGVtZW50ID0gdmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZmFsc2VTdGF0ZW1lbnQgPT09IFwiXFxcXHZhbHVlXCIpIHtcbiAgICAgICAgICAgICAgICBmYWxzZVN0YXRlbWVudCA9IFwidmFsdWVcIjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGZhbHNlU3RhdGVtZW50ID09PSBcIlxcXFx1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgICAgIGZhbHNlU3RhdGVtZW50ID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoZmFsc2VTdGF0ZW1lbnQgPT09IFwiXFxcXG51bGxcIikge1xuICAgICAgICAgICAgICAgIGZhbHNlU3RhdGVtZW50ID0gbnVsbDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGV0IGNvbmRpdGlvbiA9XG4gICAgICAgICAgICAgICAgKHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IFwiXCIgJiYgdmFsdWUgIT09IFwib2ZmXCIgJiYgdmFsdWUgIT09IFwiZmFsc2VcIiAmJiB2YWx1ZSAhPT0gZmFsc2UpIHx8XG4gICAgICAgICAgICAgICAgdmFsdWUgPT09IFwib25cIiB8fFxuICAgICAgICAgICAgICAgIHZhbHVlID09PSBcInRydWVcIiB8fFxuICAgICAgICAgICAgICAgIHZhbHVlID09PSB0cnVlO1xuICAgICAgICAgICAgcmV0dXJuIGNvbmRpdGlvbiA/IHRydWVTdGF0ZW1lbnQgOiBmYWxzZVN0YXRlbWVudDtcblxuICAgICAgICBjYXNlIFwidWNmaXJzdFwiOlxuICAgICAgICAgICAgdmFsaWRhdGVTdHJpbmcodmFsdWUpO1xuXG4gICAgICAgICAgICBsZXQgZmlyc3RjaGFyID0gdmFsdWUuY2hhckF0KDApLnRvVXBwZXJDYXNlKCk7XG4gICAgICAgICAgICByZXR1cm4gZmlyc3RjaGFyICsgdmFsdWUuc3Vic3RyKDEpO1xuICAgICAgICBjYXNlIFwidWN3b3Jkc1wiOlxuICAgICAgICAgICAgdmFsaWRhdGVTdHJpbmcodmFsdWUpO1xuXG4gICAgICAgICAgICByZXR1cm4gdmFsdWUucmVwbGFjZSgvXihbYS16XFx1MDBFMC1cXHUwMEZDXSl8XFxzKyhbYS16XFx1MDBFMC1cXHUwMEZDXSkvZywgZnVuY3Rpb24gKHYpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdi50b1VwcGVyQ2FzZSgpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgY2FzZSBcImNvdW50XCI6XG4gICAgICAgIGNhc2UgXCJsZW5ndGhcIjpcbiAgICAgICAgICAgIGlmICgoaXNTdHJpbmcodmFsdWUpIHx8IGlzT2JqZWN0KHZhbHVlKSB8fCBpc0FycmF5KHZhbHVlKSkgJiYgdmFsdWUuaGFzT3duUHJvcGVydHkoXCJsZW5ndGhcIikpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWUubGVuZ3RoO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGB1bnN1cHBvcnRlZCB0eXBlICR7dHlwZW9mIHZhbHVlfWApO1xuXG4gICAgICAgIGNhc2UgXCJ0by1iYXNlNjRcIjpcbiAgICAgICAgY2FzZSBcImJ0b2FcIjpcbiAgICAgICAgY2FzZSBcImJhc2U2NFwiOlxuICAgICAgICAgICAgcmV0dXJuIGJ0b2EoY29udmVydFRvU3RyaW5nKHZhbHVlKSk7XG5cbiAgICAgICAgY2FzZSBcImF0b2JcIjpcbiAgICAgICAgY2FzZSBcImZyb20tYmFzZTY0XCI6XG4gICAgICAgICAgICByZXR1cm4gYXRvYihjb252ZXJ0VG9TdHJpbmcodmFsdWUpKTtcblxuICAgICAgICBjYXNlIFwiZW1wdHlcIjpcbiAgICAgICAgICAgIHJldHVybiBcIlwiO1xuXG4gICAgICAgIGNhc2UgXCJ1bmRlZmluZWRcIjpcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICAgICAgY2FzZSBcImRlYnVnXCI6XG4gICAgICAgICAgICBpZiAoaXNPYmplY3QoY29uc29sZSkpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyh2YWx1ZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcblxuICAgICAgICBjYXNlIFwicHJlZml4XCI6XG4gICAgICAgICAgICB2YWxpZGF0ZVN0cmluZyh2YWx1ZSk7XG4gICAgICAgICAgICBsZXQgcHJlZml4ID0gYXJncz8uWzBdO1xuICAgICAgICAgICAgcmV0dXJuIHByZWZpeCArIHZhbHVlO1xuXG4gICAgICAgIGNhc2UgXCJzdWZmaXhcIjpcbiAgICAgICAgICAgIHZhbGlkYXRlU3RyaW5nKHZhbHVlKTtcbiAgICAgICAgICAgIGxldCBzdWZmaXggPSBhcmdzPy5bMF07XG4gICAgICAgICAgICByZXR1cm4gdmFsdWUgKyBzdWZmaXg7XG5cbiAgICAgICAgY2FzZSBcInVuaXFpZFwiOlxuICAgICAgICAgICAgcmV0dXJuIG5ldyBJRCgpLnRvU3RyaW5nKCk7XG5cbiAgICAgICAgY2FzZSBcImZpcnN0LWtleVwiOlxuICAgICAgICBjYXNlIFwibGFzdC1rZXlcIjpcbiAgICAgICAgY2FzZSBcIm50aC1sYXN0LWtleVwiOlxuICAgICAgICBjYXNlIFwibnRoLWtleVwiOlxuICAgICAgICAgICAgaWYgKCFpc09iamVjdCh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0eXBlIG5vdCBzdXBwb3J0ZWRcIik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyh2YWx1ZSkuc29ydCgpO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5jb21tYW5kID09PSBcImZpcnN0LWtleVwiKSB7XG4gICAgICAgICAgICAgICAga2V5ID0gMDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5jb21tYW5kID09PSBcImxhc3Qta2V5XCIpIHtcbiAgICAgICAgICAgICAgICBrZXkgPSBrZXlzLmxlbmd0aCAtIDE7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGtleSA9IHZhbGlkYXRlSW50ZWdlcihwYXJzZUludChhcmdzLnNoaWZ0KCkpKTtcblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbW1hbmQgPT09IFwibnRoLWxhc3Qta2V5XCIpIHtcbiAgICAgICAgICAgICAgICAgICAga2V5ID0ga2V5cy5sZW5ndGggLSBrZXkgLSAxO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZGVmYXVsdFZhbHVlID0gYXJncy5zaGlmdCgpIHx8IFwiXCI7XG5cbiAgICAgICAgICAgIGxldCB1c2VLZXkgPSBrZXlzPy5ba2V5XTtcblxuICAgICAgICAgICAgaWYgKHZhbHVlPy5bdXNlS2V5XSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZT8uW3VzZUtleV07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBkZWZhdWx0VmFsdWU7XG5cbiAgICAgICAgY2FzZSBcImtleVwiOlxuICAgICAgICBjYXNlIFwicHJvcGVydHlcIjpcbiAgICAgICAgY2FzZSBcImluZGV4XCI6XG4gICAgICAgICAgICBrZXkgPSBhcmdzLnNoaWZ0KCkgfHwgdW5kZWZpbmVkO1xuXG4gICAgICAgICAgICBpZiAoa2V5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJtaXNzaW5nIGtleSBwYXJhbWV0ZXJcIik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGRlZmF1bHRWYWx1ZSA9IGFyZ3Muc2hpZnQoKSB8fCB1bmRlZmluZWQ7XG5cbiAgICAgICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIE1hcCkge1xuICAgICAgICAgICAgICAgIGlmICghdmFsdWUuaGFzKGtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlLmdldChrZXkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoaXNPYmplY3QodmFsdWUpIHx8IGlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlPy5ba2V5XSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU/LltrZXldO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiBkZWZhdWx0VmFsdWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInR5cGUgbm90IHN1cHBvcnRlZFwiKTtcblxuICAgICAgICBjYXNlIFwicGF0aC1leGlzdHNcIjpcbiAgICAgICAgICAgIGtleSA9IGFyZ3Muc2hpZnQoKTtcbiAgICAgICAgICAgIGlmIChrZXkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIm1pc3Npbmcga2V5IHBhcmFtZXRlclwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIG5ldyBQYXRoZmluZGVyKHZhbHVlKS5leGlzdHMoa2V5KTtcblxuICAgICAgICBjYXNlIFwiY29uY2F0XCI6XG4gICAgICAgICAgICBsZXQgcGYyID0gbmV3IFBhdGhmaW5kZXIodmFsdWUpO1xuICAgICAgICAgICAgbGV0IGNvbmNhdCA9IFwiXCI7XG4gICAgICAgICAgICB3aGlsZSAoYXJncy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAga2V5ID0gYXJncy5zaGlmdCgpO1xuICAgICAgICAgICAgICAgIGlmIChrZXkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJtaXNzaW5nIGtleSBwYXJhbWV0ZXJcIik7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gYWRkIGVtcHR5IHN0cmluZ3NcbiAgICAgICAgICAgICAgICBpZiAoaXNTdHJpbmcoa2V5KSAmJiBrZXkudHJpbSgpID09PSBcIlwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbmNhdCArPSBrZXk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICghcGYyLmV4aXN0cyhrZXkpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbmNhdCArPSBrZXk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsZXQgdiA9IHBmMi5nZXRWaWEoa2V5KTtcbiAgICAgICAgICAgICAgICBpZiAoIWlzUHJpbWl0aXZlKHYpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInZhbHVlIGlzIG5vdCBwcmltaXRpdmVcIik7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY29uY2F0ICs9IHY7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBjb25jYXQ7XG4gICAgICAgIGNhc2UgXCJwYXRoXCI6XG4gICAgICAgICAgICBrZXkgPSBhcmdzLnNoaWZ0KCk7XG4gICAgICAgICAgICBpZiAoa2V5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJtaXNzaW5nIGtleSBwYXJhbWV0ZXJcIik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCBwZiA9IG5ldyBQYXRoZmluZGVyKHZhbHVlKTtcblxuICAgICAgICAgICAgaWYgKCFwZi5leGlzdHMoa2V5KSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBwZi5nZXRWaWEoa2V5KTtcblxuICAgICAgICBjYXNlIFwic3Vic3RyaW5nXCI6XG4gICAgICAgICAgICB2YWxpZGF0ZVN0cmluZyh2YWx1ZSk7XG5cbiAgICAgICAgICAgIGxldCBzdGFydCA9IHBhcnNlSW50KGFyZ3NbMF0pIHx8IDA7XG4gICAgICAgICAgICBsZXQgZW5kID0gKHBhcnNlSW50KGFyZ3NbMV0pIHx8IDApICsgc3RhcnQ7XG5cbiAgICAgICAgICAgIHJldHVybiB2YWx1ZS5zdWJzdHJpbmcoc3RhcnQsIGVuZCk7XG5cbiAgICAgICAgY2FzZSBcIm5vcFwiOlxuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuXG4gICAgICAgIGNhc2UgXCI/P1wiOlxuICAgICAgICBjYXNlIFwiZGVmYXVsdFwiOlxuICAgICAgICAgICAgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGRlZmF1bHRWYWx1ZSA9IGFyZ3Muc2hpZnQoKTtcbiAgICAgICAgICAgIGxldCBkZWZhdWx0VHlwZSA9IGFyZ3Muc2hpZnQoKTtcbiAgICAgICAgICAgIGlmIChkZWZhdWx0VHlwZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgZGVmYXVsdFR5cGUgPSBcInN0cmluZ1wiO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBzd2l0Y2ggKGRlZmF1bHRUeXBlKSB7XG4gICAgICAgICAgICAgICAgY2FzZSBcImludFwiOlxuICAgICAgICAgICAgICAgIGNhc2UgXCJpbnRlZ2VyXCI6XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZUludChkZWZhdWx0VmFsdWUpO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJmbG9hdFwiOlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VGbG9hdChkZWZhdWx0VmFsdWUpO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJ1bmRlZmluZWRcIjpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICBjYXNlIFwiYm9vbFwiOlxuICAgICAgICAgICAgICAgIGNhc2UgXCJib29sZWFuXCI6XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHRWYWx1ZSA9IGRlZmF1bHRWYWx1ZS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgICAgICAgICAgKGRlZmF1bHRWYWx1ZSAhPT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRWYWx1ZSAhPT0gXCJcIiAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRWYWx1ZSAhPT0gXCJvZmZcIiAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRWYWx1ZSAhPT0gXCJmYWxzZVwiICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlICE9PSBcImZhbHNlXCIpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0VmFsdWUgPT09IFwib25cIiB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlID09PSBcInRydWVcIiB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlID09PSBcInRydWVcIlxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJzdHJpbmdcIjpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGAke2RlZmF1bHRWYWx1ZX1gO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UoYXRvYihkZWZhdWx0VmFsdWUpKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidHlwZSBub3Qgc3VwcG9ydGVkXCIpO1xuXG4gICAgICAgIGNhc2UgXCJtYXBcIjpcbiAgICAgICAgICAgIG1hcCA9IG5ldyBNYXAoKTtcbiAgICAgICAgICAgIHdoaWxlIChhcmdzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBrZXlWYWx1ZSA9IGFyZ3Muc2hpZnQoKTtcbiAgICAgICAgICAgICAgICBpZiAoa2V5VmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJtaXNzaW5nIGtleSBwYXJhbWV0ZXJcIik7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAga2V5VmFsdWUgPSBrZXlWYWx1ZS5zcGxpdChcIj1cIik7XG4gICAgICAgICAgICAgICAgbWFwLnNldChrZXlWYWx1ZVswXSwga2V5VmFsdWVbMV0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gbWFwLmdldCh2YWx1ZSk7XG5cbiAgICAgICAgY2FzZSBcImVxdWFsc1wiOlxuICAgICAgICAgICAgaWYgKGFyZ3MubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwibWlzc2luZyB2YWx1ZSBwYXJhbWV0ZXJcIik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhbGlkYXRlUHJpbWl0aXZlKHZhbHVlKTtcblxuICAgICAgICAgICAgY29uc3QgZXF1YWxzVmFsdWUgPSBhcmdzLnNoaWZ0KCk7XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogVGhlIGhpc3Rvcnkgb2YgXHUyMDFDdHlwZW9mIG51bGxcdTIwMURcbiAgICAgICAgICAgICAqIGh0dHBzOi8vMmFsaXR5LmNvbS8yMDEzLzEwL3R5cGVvZi1udWxsLmh0bWxcbiAgICAgICAgICAgICAqIEluIEphdmFTY3JpcHQsIHR5cGVvZiBudWxsIGlzICdvYmplY3QnLCB3aGljaCBpbmNvcnJlY3RseSBzdWdnZXN0c1xuICAgICAgICAgICAgICogdGhhdCBudWxsIGlzIGFuIG9iamVjdC5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgaWYgKHZhbHVlID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgaWYgKGVxdWFsc1ZhbHVlID09PSBcIm51bGxcIikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCB0eXBlT2ZWYWx1ZSA9IHR5cGVvZiB2YWx1ZTtcblxuICAgICAgICAgICAgc3dpdGNoICh0eXBlT2ZWYWx1ZSkge1xuICAgICAgICAgICAgICAgIGNhc2UgXCJzdHJpbmdcIjpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlID09PSBlcXVhbHNWYWx1ZTtcbiAgICAgICAgICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZSA9PT0gcGFyc2VGbG9hdChlcXVhbHNWYWx1ZSk7XG4gICAgICAgICAgICAgICAgY2FzZSBcImJvb2xlYW5cIjpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlID09PSAoZXF1YWxzVmFsdWUgPT09IFwidHJ1ZVwiIHx8IGVxdWFsc1ZhbHVlID09PSBcIm9uXCIpO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJ1bmRlZmluZWRcIjpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVxdWFsc1ZhbHVlID09PSBcInVuZGVmaW5lZFwiO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInR5cGUgbm90IHN1cHBvcnRlZFwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICBjYXNlIFwibW9uZXlcIjpcbiAgICAgICAgY2FzZSBcImN1cnJlbmN5XCI6XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGxvY2FsZSA9IGdldExvY2FsZU9mRG9jdW1lbnQoKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuc3VwcG9ydGVkIGxvY2FsZSBvciBtaXNzaW5nIGZvcm1hdCAoJHtlLm1lc3NhZ2V9KWApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBjdXJyZW5jeSA9IHZhbHVlLnN1YnN0cmluZygwLCAzKTtcbiAgICAgICAgICAgIGlmICghY3VycmVuY3kpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJtaXNzaW5nIGN1cnJlbmN5IHBhcmFtZXRlclwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgbWF4aW11bUZyYWN0aW9uRGlnaXRzID0gYXJncz8uWzBdIHx8IDI7XG4gICAgICAgICAgICBjb25zdCByb3VuZGluZ0luY3JlbWVudCA9IGFyZ3M/LlsxXSB8fCA1O1xuXG4gICAgICAgICAgICBjb25zdCBuZiA9IG5ldyBJbnRsLk51bWJlckZvcm1hdChsb2NhbGUsIHtcbiAgICAgICAgICAgICAgICBzdHlsZTogXCJjdXJyZW5jeVwiLFxuICAgICAgICAgICAgICAgIGN1cnJlbmN5OiBjdXJyZW5jeSxcbiAgICAgICAgICAgICAgICBtYXhpbXVtRnJhY3Rpb25EaWdpdHM6IG1heGltdW1GcmFjdGlvbkRpZ2l0cyxcbiAgICAgICAgICAgICAgICByb3VuZGluZ0luY3JlbWVudDogcm91bmRpbmdJbmNyZW1lbnQsXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgcmV0dXJuIG5mLmZvcm1hdCh2YWx1ZS5zdWJzdHJpbmcoMykpO1xuXG4gICAgICAgIGNhc2UgXCJ0aW1lc3RhbXBcIjpcbiAgICAgICAgICAgIGRhdGUgPSBuZXcgRGF0ZSh2YWx1ZSk7XG4gICAgICAgICAgICB0aW1lc3RhbXAgPSBkYXRlLmdldFRpbWUoKTtcbiAgICAgICAgICAgIGlmIChpc05hTih0aW1lc3RhbXApKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiaW52YWxpZCBkYXRlXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRpbWVzdGFtcDtcblxuICAgICAgICBjYXNlIFwidGltZVwiOlxuICAgICAgICAgICAgZGF0ZSA9IG5ldyBEYXRlKHZhbHVlKTtcbiAgICAgICAgICAgIGlmIChpc05hTihkYXRlLmdldFRpbWUoKSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJpbnZhbGlkIGRhdGVcIik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgbG9jYWxlID0gZ2V0TG9jYWxlT2ZEb2N1bWVudCgpO1xuICAgICAgICAgICAgICAgIHJldHVybiBkYXRlLnRvTG9jYWxlVGltZVN0cmluZyhsb2NhbGUpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgdW5zdXBwb3J0ZWQgbG9jYWxlIG9yIG1pc3NpbmcgZm9ybWF0ICgke2UubWVzc2FnZX0pYCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgY2FzZSBcImRhdGV0aW1lZm9ybWF0XCI6XG4gICAgICAgICAgICBkYXRlID0gbmV3IERhdGUodmFsdWUpO1xuICAgICAgICAgICAgaWYgKGlzTmFOKGRhdGUuZ2V0VGltZSgpKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImludmFsaWQgZGF0ZVwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICBkYXRlU3R5bGU6IGFyZ3Muc2hpZnQoKSB8fCBcIm1lZGl1bVwiLFxuICAgICAgICAgICAgICAgIHRpbWVTdHlsZTogYXJncy5zaGlmdCgpIHx8IFwibWVkaXVtXCIsXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGxvY2FsZSA9IGdldExvY2FsZU9mRG9jdW1lbnQoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEludGwuRGF0ZVRpbWVGb3JtYXQobG9jYWxlLCBvcHRpb25zKS5mb3JtYXQoZGF0ZSk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnN1cHBvcnRlZCBsb2NhbGUgb3IgbWlzc2luZyBmb3JtYXQgKCR7ZS5tZXNzYWdlfSlgKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICBjYXNlIFwiZGF0ZXRpbWVcIjpcbiAgICAgICAgICAgIGRhdGUgPSBuZXcgRGF0ZSh2YWx1ZSk7XG4gICAgICAgICAgICBpZiAoaXNOYU4oZGF0ZS5nZXRUaW1lKCkpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiaW52YWxpZCBkYXRlXCIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGxvY2FsZSA9IGdldExvY2FsZU9mRG9jdW1lbnQoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZGF0ZS50b0xvY2FsZVN0cmluZyhsb2NhbGUpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgdW5zdXBwb3J0ZWQgbG9jYWxlIG9yIG1pc3NpbmcgZm9ybWF0ICgke2UubWVzc2FnZX0pYCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgY2FzZSBcImRhdGVcIjpcbiAgICAgICAgICAgIGRhdGUgPSBuZXcgRGF0ZSh2YWx1ZSk7XG4gICAgICAgICAgICBpZiAoaXNOYU4oZGF0ZS5nZXRUaW1lKCkpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiaW52YWxpZCBkYXRlXCIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGxvY2FsZSA9IGdldExvY2FsZU9mRG9jdW1lbnQoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZGF0ZS50b0xvY2FsZURhdGVTdHJpbmcobG9jYWxlKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuc3VwcG9ydGVkIGxvY2FsZSBvciBtaXNzaW5nIGZvcm1hdCAoJHtlLm1lc3NhZ2V9KWApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIGNhc2UgXCJ5ZWFyXCI6XG4gICAgICAgICAgICBkYXRlID0gbmV3IERhdGUodmFsdWUpO1xuICAgICAgICAgICAgaWYgKGlzTmFOKGRhdGUuZ2V0VGltZSgpKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImludmFsaWQgZGF0ZVwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGRhdGUuZ2V0RnVsbFllYXIoKTtcblxuICAgICAgICBjYXNlIFwibW9udGhcIjpcbiAgICAgICAgICAgIGRhdGUgPSBuZXcgRGF0ZSh2YWx1ZSk7XG4gICAgICAgICAgICBpZiAoaXNOYU4oZGF0ZS5nZXRUaW1lKCkpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiaW52YWxpZCBkYXRlXCIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gZGF0ZS5nZXRNb250aCgpICsgMTtcblxuICAgICAgICBjYXNlIFwiZGF5XCI6XG4gICAgICAgICAgICBkYXRlID0gbmV3IERhdGUodmFsdWUpO1xuICAgICAgICAgICAgaWYgKGlzTmFOKGRhdGUuZ2V0VGltZSgpKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImludmFsaWQgZGF0ZVwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGRhdGUuZ2V0RGF0ZSgpO1xuXG4gICAgICAgIGNhc2UgXCJ3ZWVrZGF5XCI6XG4gICAgICAgICAgICBkYXRlID0gbmV3IERhdGUodmFsdWUpO1xuICAgICAgICAgICAgaWYgKGlzTmFOKGRhdGUuZ2V0VGltZSgpKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImludmFsaWQgZGF0ZVwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGRhdGUuZ2V0RGF5KCk7XG5cbiAgICAgICAgY2FzZSBcImhvdXJcIjpcbiAgICAgICAgY2FzZSBcImhvdXJzXCI6XG4gICAgICAgICAgICBkYXRlID0gbmV3IERhdGUodmFsdWUpO1xuICAgICAgICAgICAgaWYgKGlzTmFOKGRhdGUuZ2V0VGltZSgpKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImludmFsaWQgZGF0ZVwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGRhdGUuZ2V0SG91cnMoKTtcblxuICAgICAgICBjYXNlIFwibWludXRlXCI6XG4gICAgICAgIGNhc2UgXCJtaW51dGVzXCI6XG4gICAgICAgICAgICBkYXRlID0gbmV3IERhdGUodmFsdWUpO1xuICAgICAgICAgICAgaWYgKGlzTmFOKGRhdGUuZ2V0VGltZSgpKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImludmFsaWQgZGF0ZVwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGRhdGUuZ2V0TWludXRlcygpO1xuXG4gICAgICAgIGNhc2UgXCJzZWNvbmRcIjpcbiAgICAgICAgY2FzZSBcInNlY29uZHNcIjpcbiAgICAgICAgICAgIGRhdGUgPSBuZXcgRGF0ZSh2YWx1ZSk7XG4gICAgICAgICAgICBpZiAoaXNOYU4oZGF0ZS5nZXRUaW1lKCkpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiaW52YWxpZCBkYXRlXCIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gZGF0ZS5nZXRTZWNvbmRzKCk7XG5cbiAgICAgICAgY2FzZSBcImkxOG5cIjpcbiAgICAgICAgY2FzZSBcInRyYW5zbGF0aW9uXCI6XG4gICAgICAgICAgICB0cmFuc2xhdGlvbnMgPSBnZXREb2N1bWVudFRyYW5zbGF0aW9ucygpO1xuICAgICAgICAgICAgaWYgKCEodHJhbnNsYXRpb25zIGluc3RhbmNlb2YgVHJhbnNsYXRpb25zKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIm1pc3NpbmcgdHJhbnNsYXRpb25zXCIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBrZXkgPSBhcmdzLnNoaWZ0KCkgfHwgdW5kZWZpbmVkO1xuICAgICAgICAgICAgaWYgKGtleSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAga2V5ID0gdmFsdWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGRlZmF1bHRWYWx1ZSA9IGFyZ3Muc2hpZnQoKSB8fCB1bmRlZmluZWQ7XG4gICAgICAgICAgICByZXR1cm4gdHJhbnNsYXRpb25zLmdldFRleHQoa2V5LCBkZWZhdWx0VmFsdWUpO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVua25vd24gY29tbWFuZCAke3RoaXMuY29tbWFuZH1gKTtcbiAgICB9XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBCYXNlIH0gZnJvbSBcIi4uL3R5cGVzL2Jhc2UubWpzXCI7XG5pbXBvcnQgeyB2YWxpZGF0ZVN0cmluZyB9IGZyb20gXCIuLi90eXBlcy92YWxpZGF0ZS5tanNcIjtcbmltcG9ydCB7IFRyYW5zZm9ybWVyIH0gZnJvbSBcIi4vdHJhbnNmb3JtZXIubWpzXCI7XG5cbmV4cG9ydCB7IFBpcGUgfTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuY29uc3QgREVMSU1JVEVSID0gXCJ8XCI7XG5cbi8qKlxuICogVGhlIHBpcGUgY2xhc3MgbWFrZXMgaXQgcG9zc2libGUgdG8gY29tYmluZSBzZXZlcmFsIHByb2Nlc3Npbmcgc3RlcHMuXG4gKlxuICogQSBwaXBlIGNvbnNpc3RzIG9mIGNvbW1hbmRzIHdob3NlIGlucHV0IGFuZCBvdXRwdXQgYXJlIGNvbm5lY3RlZCB3aXRoIHRoZSBwaXBlIHN5bWJvbCBgfGAuXG4gKlxuICogV2l0aCB0aGUgUGlwZSwgcHJvY2Vzc2luZyBzdGVwcyBjYW4gYmUgY29tYmluZWQuIEhlcmUsIHRoZSB2YWx1ZSBvZiBhbiBvYmplY3QgaXMgYWNjZXNzZWQgdmlhIHRoZSBwYXRoZmluZGVyIChwYXRoIGNvbW1hbmQpLlxuICogdGhlIHdvcmQgaXMgdGhlbiBjb252ZXJ0ZWQgdG8gdXBwZXJjYXNlIGxldHRlcnMgYW5kIGEgcHJlZml4IEhlbGxvIGlzIGFkZGVkLiB0aGUgdHdvIGJhY2tzbGFzaCBzYWZlIHRoZSBzcGFjZSBjaGFyLlxuICpcbiAqIEBleHRlcm5hbEV4YW1wbGUgIC4uLy4uL2V4YW1wbGUvZGF0YS9waXBlLm1qc1xuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS41LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5EYXRhXG4gKi9cbmNsYXNzIFBpcGUgZXh0ZW5kcyBCYXNlIHtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcGlwZSBhIHBpcGUgY29uc2lzdHMgb2YgY29tbWFuZHMgd2hvc2UgaW5wdXQgYW5kIG91dHB1dCBhcmUgY29ubmVjdGVkIHdpdGggdGhlIHBpcGUgc3ltYm9sIGB8YC5cbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9XG4gICAgICovXG4gICAgY29uc3RydWN0b3IocGlwZSkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB2YWxpZGF0ZVN0cmluZyhwaXBlKTtcblxuICAgICAgICB0aGlzLnBpcGUgPSBwaXBlLnNwbGl0KERFTElNSVRFUikubWFwKCh2KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFRyYW5zZm9ybWVyKHYpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGNhbGxiYWNrXG4gICAgICogQHBhcmFtIHtvYmplY3R9IGNvbnRleHRcbiAgICAgKiBAcmV0dXJucyB7VHJhbnNmb3JtZXJ9XG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYSBzdHJpbmdcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIGZ1bmN0aW9uXG4gICAgICovXG4gICAgc2V0Q2FsbGJhY2sobmFtZSwgY2FsbGJhY2ssIGNvbnRleHQpIHtcbiAgICAgICAgZm9yIChjb25zdCBbLCB0XSBvZiBPYmplY3QuZW50cmllcyh0aGlzLnBpcGUpKSB7XG4gICAgICAgICAgICB0LnNldENhbGxiYWNrKG5hbWUsIGNhbGxiYWNrLCBjb250ZXh0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHJ1biBhIHBpcGVcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAgICAgKiBAcmV0dXJucyB7Kn1cbiAgICAgKi9cbiAgICBydW4odmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGlwZS5yZWR1Y2UoKGFjY3VtdWxhdG9yLCB0cmFuc2Zvcm1lciwgY3VycmVudEluZGV4LCBhcnJheSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRyYW5zZm9ybWVyLnJ1bihhY2N1bXVsYXRvcik7XG4gICAgICAgIH0sIHZhbHVlKTtcbiAgICB9XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBpbnRlcm5hbFN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQgeyBleHRlbmQgfSBmcm9tIFwiLi4vZGF0YS9leHRlbmQubWpzXCI7XG5pbXBvcnQgeyBQaXBlIH0gZnJvbSBcIi4uL2RhdGEvcGlwZS5tanNcIjtcblxuaW1wb3J0IHsgQmFzZVdpdGhPcHRpb25zIH0gZnJvbSBcIi4uL3R5cGVzL2Jhc2V3aXRob3B0aW9ucy5tanNcIjtcbmltcG9ydCB7IGlzT2JqZWN0LCBpc1N0cmluZyB9IGZyb20gXCIuLi90eXBlcy9pcy5tanNcIjtcbmltcG9ydCB7IHZhbGlkYXRlQXJyYXksIHZhbGlkYXRlU3RyaW5nIH0gZnJvbSBcIi4uL3R5cGVzL3ZhbGlkYXRlLm1qc1wiO1xuXG5leHBvcnQgeyBGb3JtYXR0ZXIgfTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHR5cGUge3N5bWJvbH1cbiAqL1xuY29uc3QgaW50ZXJuYWxPYmplY3RTeW1ib2wgPSBTeW1ib2woXCJpbnRlcm5hbE9iamVjdFwiKTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHR5cGUge3N5bWJvbH1cbiAqL1xuY29uc3Qgd2F0Y2hkb2dTeW1ib2wgPSBTeW1ib2woXCJ3YXRjaGRvZ1wiKTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHR5cGUge3N5bWJvbH1cbiAqL1xuY29uc3QgbWFya2VyT3BlbkluZGV4U3ltYm9sID0gU3ltYm9sKFwibWFya2VyT3BlbkluZGV4XCIpO1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAdHlwZSB7c3ltYm9sfVxuICovXG5jb25zdCBtYXJrZXJDbG9zZUluZGV4U3ltYm9sID0gU3ltYm9sKFwibWFya2VyY2xvc2VJbmRleFwiKTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHR5cGUge3N5bWJvbH1cbiAqL1xuY29uc3Qgd29ya2luZ0RhdGFTeW1ib2wgPSBTeW1ib2woXCJ3b3JraW5nRGF0YVwiKTtcblxuLyoqXG4gKiBNZXNzYWdlcyBjYW4gYmUgZm9ybWF0dGVkIHdpdGggdGhlIGZvcm1hdHRlci4gVG8gZG8gdGhpcywgYW4gb2JqZWN0IHdpdGggdGhlIHZhbHVlcyBtdXN0IGJlIHBhc3NlZCB0byB0aGUgZm9ybWF0dGVyLiBUaGUgbWVzc2FnZSBjYW4gdGhlbiBjb250YWluIHBsYWNlaG9sZGVycy5cbiAqXG4gKiBMb29rIGF0IHRoZSBleGFtcGxlIGJlbG93LiBUaGUgcGxhY2Vob2xkZXJzIHVzZSB0aGUgbG9naWMgb2YgUGlwZS5cbiAqXG4gKiAjIyBNYXJrZXIgaW4gbWFya2VyXG4gKlxuICogTWFya2VycyBjYW4gYmUgbmVzdGVkLiBIZXJlLCB0aGUgaW5uZXIgbWFya2VyIGlzIHJlc29sdmVkIGZpcnN0IGAke3N1YmtleX0gXHUyMUE2IDEgPSAke215a2V5Mn1gIGFuZCB0aGVuIHRoZSBvdXRlciBtYXJrZXIgYCR7bXlrZXkyfWAuXG4gKlxuICogYGBgXG4gKiBjb25zdCB0ZXh0ID0gJyR7bXlrZXkke3N1YmtleX19JztcbiAqIGxldCBvYmogPSB7XG4gKiAgbXlrZXkyOiBcIjFcIixcbiAqICBzdWJrZXk6IFwiMlwiXG4gKiB9O1xuICpcbiAqIG5ldyBGb3JtYXR0ZXIob2JqKS5mb3JtYXQodGV4dCk7XG4gKiAvLyBcdTIxQTYgMVxuICogYGBgXG4gKlxuICogIyMgQ2FsbGJhY2tzXG4gKlxuICogVGhlIHZhbHVlcyBpbiBhIGZvcm1hdHRlciBjYW4gYmUgYWRqdXN0ZWQgdmlhIHRoZSBjb21tYW5kcyBvZiB0aGUgYFRyYW5zZm9ybWVyYCBvciB0aGVgUGlwZWAuXG4gKiBUaGVyZSBpcyBhbHNvIHRoZSBwb3NzaWJpbGl0eSB0byB1c2UgY2FsbGJhY2tzLlxuICpcbiAqIGNvbnN0IGZvcm1hdHRlciA9IG5ldyBGb3JtYXR0ZXIoe3g6ICcxJ30sIHtcbiAqICAgICAgICAgICAgICAgIGNhbGxiYWNrczoge1xuICogICAgICAgICAgICAgICAgICAgIHF1b3RlOiAodmFsdWUpID0+IHtcbiAqICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICdcIicgKyB2YWx1ZSArICdcIidcbiAqICAgICAgICAgICAgICAgICAgICB9XG4gKiAgICAgICAgICAgICAgICB9XG4gKiAgICAgICAgICAgIH0pO1xuICpcbiAqIGZvcm1hdHRlci5mb3JtYXQoJyR7eCB8IGNhbGw6cXVvdGV9JykpXG4gKiAvLyBcdTIxQTYgXCIxXCJcbiAqXG4gKiAjIyBNYXJrZXIgd2l0aCBwYXJhbWV0ZXJcbiAqXG4gKiBBIHN0cmluZyBjYW4gYWxzbyBicmluZyBpdHMgb3duIHZhbHVlcy4gVGhlc2UgbXVzdCB0aGVuIGJlIHNlcGFyYXRlZCBmcm9tIHRoZSBrZXkgYnkgYSBzZXBhcmF0b3IgYDo6YC5cbiAqIFRoZSB2YWx1ZXMgdGhlbXNlbHZlcyBtdXN0IGJlIHNwZWNpZmllZCBpbiBrZXkvdmFsdWUgcGFpcnMuIFRoZSBrZXkgbXVzdCBiZSBzZXBhcmF0ZWQgZnJvbSB0aGUgdmFsdWUgYnkgYSBzZXBhcmF0b3IgYD1gLlxuICpcbiAqIFdoZW4gdXNpbmcgYSBwaXBlLCB5b3UgbXVzdCBwYXkgYXR0ZW50aW9uIHRvIHRoZSBzZXBhcmF0b3JzLlxuICpcbiAqIEBleGFtcGxlXG4gKlxuICogaW1wb3J0IHtGb3JtYXR0ZXJ9IGZyb20gJ0BzY2h1a2FpL21vbnN0ZXIvc291cmNlL3RleHQvZm9ybWF0dGVyLm1qcyc7XG4gKlxuICogbmV3IEZvcm1hdHRlcih7XG4gKiAgICAgICBhOiB7XG4gKiAgICAgICAgICAgYjoge1xuICogICAgICAgICAgICAgICBjOiBcIkhlbGxvXCJcbiAqICAgICAgICAgICB9LFxuICogICAgICAgICAgIGQ6IFwid29ybGRcIixcbiAqICAgICAgIH1cbiAqICAgfSkuZm9ybWF0KFwiJHthLmIuY30gJHthLmQgfCB1Y2ZpcnN0fSFcIik7IC8vIHdpdGggcGlwZVxuICpcbiAqIC8vIFx1MjFBNiBIZWxsbyBXb3JsZCFcbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjEyLjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UZXh0XG4gKi9cbmNsYXNzIEZvcm1hdHRlciBleHRlbmRzIEJhc2VXaXRoT3B0aW9ucyB7XG4gICAgLyoqXG4gICAgICogRGVmYXVsdCB2YWx1ZXMgZm9yIHRoZSBtYXJrZXJzIGFyZSBgJHtgIGFuZCBgfWBcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBvYmplY3RcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIG9iamVjdFxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKG9iamVjdCwgb3B0aW9ucykge1xuICAgICAgICBzdXBlcihvcHRpb25zKTtcbiAgICAgICAgdGhpc1tpbnRlcm5hbE9iamVjdFN5bWJvbF0gPSBvYmplY3QgfHwge307XG4gICAgICAgIHRoaXNbbWFya2VyT3BlbkluZGV4U3ltYm9sXSA9IDA7XG4gICAgICAgIHRoaXNbbWFya2VyQ2xvc2VJbmRleFN5bWJvbF0gPSAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwcm9wZXJ0eSB7b2JqZWN0fSBtYXJrZXJcbiAgICAgKiBAcHJvcGVydHkge2FycmF5fSBtYXJrZXIub3Blbj1bXCIke1wiXVxuICAgICAqIEBwcm9wZXJ0eSB7YXJyYXl9IG1hcmtlci5jbG9zZT1bXCIke1wiXVxuICAgICAqIEBwcm9wZXJ0eSB7b2JqZWN0fSBwYXJhbWV0ZXJcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gcGFyYW1ldGVyLmRlbGltaXRlcj1cIjo6XCJcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gcGFyYW1ldGVyLmFzc2lnbm1lbnQ9XCI9XCJcbiAgICAgKiBAcHJvcGVydHkge29iamVjdH0gY2FsbGJhY2tzPXt9XG4gICAgICovXG4gICAgZ2V0IGRlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gZXh0ZW5kKHt9LCBzdXBlci5kZWZhdWx0cywge1xuICAgICAgICAgICAgbWFya2VyOiB7XG4gICAgICAgICAgICAgICAgb3BlbjogW1wiJHtcIl0sXG4gICAgICAgICAgICAgICAgY2xvc2U6IFtcIn1cIl0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcGFyYW1ldGVyOiB7XG4gICAgICAgICAgICAgICAgZGVsaW1pdGVyOiBcIjo6XCIsXG4gICAgICAgICAgICAgICAgYXNzaWdubWVudDogXCI9XCIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY2FsbGJhY2tzOiB7fSxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IG5ldyBQYXJhbWV0ZXIgQ2hhcmFjdGVyXG4gICAgICpcbiAgICAgKiBEZWZhdWx0IHZhbHVlcyBmb3IgdGhlIGNoYXJzIGFyZSBgOjpgIGFuZCBgPWBcbiAgICAgKlxuICAgICAqIGBgYFxuICAgICAqIGZvcm1hdHRlci5zZXRQYXJhbWV0ZXJDaGFycygnIycpO1xuICAgICAqIGZvcm1hdHRlci5zZXRQYXJhbWV0ZXJDaGFycygnWycsJ10nKTtcbiAgICAgKiBmb3JtYXR0ZXIuc2V0UGFyYW1ldGVyQ2hhcnMoJ2kxOG57JywnfScpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGRlbGltaXRlclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBhc3NpZ25tZW50XG4gICAgICogQHJldHVybiB7Rm9ybWF0dGVyfVxuICAgICAqIEBzaW5jZSAxLjI0LjBcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIHN0cmluZ1xuICAgICAqL1xuICAgIHNldFBhcmFtZXRlckNoYXJzKGRlbGltaXRlciwgYXNzaWdubWVudCkge1xuICAgICAgICBpZiAoZGVsaW1pdGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXNbaW50ZXJuYWxTeW1ib2xdW1wicGFyYW1ldGVyXCJdW1wiZGVsaW1pdGVyXCJdID0gdmFsaWRhdGVTdHJpbmcoZGVsaW1pdGVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChhc3NpZ25tZW50ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXNbaW50ZXJuYWxTeW1ib2xdW1wicGFyYW1ldGVyXCJdW1wiYXNzaWdubWVudFwiXSA9IHZhbGlkYXRlU3RyaW5nKGFzc2lnbm1lbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IG5ldyBNYXJrZXJcbiAgICAgKlxuICAgICAqIERlZmF1bHQgdmFsdWVzIGZvciB0aGUgbWFya2VycyBhcmUgYCR7YCBhbmQgYH1gXG4gICAgICpcbiAgICAgKiBgYGBcbiAgICAgKiBmb3JtYXR0ZXIuc2V0TWFya2VyKCcjJyk7IC8vIG9wZW4gYW5kIGNsb3NlIGFyZSBib3RoICNcbiAgICAgKiBmb3JtYXR0ZXIuc2V0TWFya2VyKCdbJywnXScpO1xuICAgICAqIGZvcm1hdHRlci5zZXRNYXJrZXIoJ2kxOG57JywnfScpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQHBhcmFtIHthcnJheXxzdHJpbmd9IG9wZW5cbiAgICAgKiBAcGFyYW0ge2FycmF5fHN0cmluZ3x1bmRlZmluZWR9IGNsb3NlXG4gICAgICogQHJldHVybiB7Rm9ybWF0dGVyfVxuICAgICAqIEBzaW5jZSAxLjEyLjBcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIHN0cmluZ1xuICAgICAqL1xuICAgIHNldE1hcmtlcihvcGVuLCBjbG9zZSkge1xuICAgICAgICBpZiAoY2xvc2UgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgY2xvc2UgPSBvcGVuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzU3RyaW5nKG9wZW4pKSBvcGVuID0gW29wZW5dO1xuICAgICAgICBpZiAoaXNTdHJpbmcoY2xvc2UpKSBjbG9zZSA9IFtjbG9zZV07XG5cbiAgICAgICAgdGhpc1tpbnRlcm5hbFN5bWJvbF1bXCJtYXJrZXJcIl1bXCJvcGVuXCJdID0gdmFsaWRhdGVBcnJheShvcGVuKTtcbiAgICAgICAgdGhpc1tpbnRlcm5hbFN5bWJvbF1bXCJtYXJrZXJcIl1bXCJjbG9zZVwiXSA9IHZhbGlkYXRlQXJyYXkoY2xvc2UpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0XG4gICAgICogQHJldHVybiB7c3RyaW5nfVxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgc3RyaW5nXG4gICAgICogQHRocm93cyB7RXJyb3J9IHRvbyBkZWVwIG5lc3RpbmdcbiAgICAgKi9cbiAgICBmb3JtYXQodGV4dCkge1xuICAgICAgICB0aGlzW3dhdGNoZG9nU3ltYm9sXSA9IDA7XG4gICAgICAgIHRoaXNbbWFya2VyT3BlbkluZGV4U3ltYm9sXSA9IDA7XG4gICAgICAgIHRoaXNbbWFya2VyQ2xvc2VJbmRleFN5bWJvbF0gPSAwO1xuICAgICAgICB0aGlzW3dvcmtpbmdEYXRhU3ltYm9sXSA9IHt9O1xuICAgICAgICByZXR1cm4gZm9ybWF0LmNhbGwodGhpcywgdGV4dCk7XG4gICAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcmV0dXJuIHtzdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIGZvcm1hdCh0ZXh0KSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICBzZWxmW3dhdGNoZG9nU3ltYm9sXSsrO1xuICAgIGlmICh0aGlzW3dhdGNoZG9nU3ltYm9sXSA+IDIwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcInRvbyBkZWVwIG5lc3RpbmdcIik7XG4gICAgfVxuXG4gICAgbGV0IG9wZW5NYXJrZXIgPSBzZWxmW2ludGVybmFsU3ltYm9sXVtcIm1hcmtlclwiXVtcIm9wZW5cIl0/Llt0aGlzW21hcmtlck9wZW5JbmRleFN5bWJvbF1dO1xuICAgIGxldCBjbG9zZU1hcmtlciA9IHNlbGZbaW50ZXJuYWxTeW1ib2xdW1wibWFya2VyXCJdW1wiY2xvc2VcIl0/Llt0aGlzW21hcmtlckNsb3NlSW5kZXhTeW1ib2xdXTtcblxuICAgIC8vIGNvbnRhaW5zIG5vIHBsYWNlaG9sZGVyc1xuICAgIGlmICh0ZXh0LmluZGV4T2Yob3Blbk1hcmtlcikgPT09IC0xIHx8IHRleHQuaW5kZXhPZihjbG9zZU1hcmtlcikgPT09IC0xKSB7XG4gICAgICAgIHJldHVybiB0ZXh0O1xuICAgIH1cblxuICAgIGxldCByZXN1bHQgPSB0b2tlbml6ZS5jYWxsKHRoaXMsIHZhbGlkYXRlU3RyaW5nKHRleHQpLCBvcGVuTWFya2VyLCBjbG9zZU1hcmtlcik7XG5cbiAgICBpZiAoc2VsZltpbnRlcm5hbFN5bWJvbF1bXCJtYXJrZXJcIl1bXCJvcGVuXCJdPy5bdGhpc1ttYXJrZXJPcGVuSW5kZXhTeW1ib2xdICsgMV0pIHtcbiAgICAgICAgdGhpc1ttYXJrZXJPcGVuSW5kZXhTeW1ib2xdKys7XG4gICAgfVxuXG4gICAgaWYgKHNlbGZbaW50ZXJuYWxTeW1ib2xdW1wibWFya2VyXCJdW1wiY2xvc2VcIl0/Llt0aGlzW21hcmtlckNsb3NlSW5kZXhTeW1ib2xdICsgMV0pIHtcbiAgICAgICAgdGhpc1ttYXJrZXJDbG9zZUluZGV4U3ltYm9sXSsrO1xuICAgIH1cblxuICAgIHJlc3VsdCA9IGZvcm1hdC5jYWxsKHNlbGYsIHJlc3VsdCk7XG5cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjEyLjBcbiAqIEBwYXJhbSB0ZXh0XG4gKiBAcmV0dXJuIHtzdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIHRva2VuaXplKHRleHQsIG9wZW5NYXJrZXIsIGNsb3NlTWFya2VyKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICBsZXQgZm9ybWF0dGVkID0gW107XG5cbiAgICBjb25zdCBwYXJhbWV0ZXJBc3NpZ25tZW50ID0gc2VsZltpbnRlcm5hbFN5bWJvbF1bXCJwYXJhbWV0ZXJcIl1bXCJhc3NpZ25tZW50XCJdO1xuICAgIGNvbnN0IHBhcmFtZXRlckRlbGltaXRlciA9IHNlbGZbaW50ZXJuYWxTeW1ib2xdW1wicGFyYW1ldGVyXCJdW1wiZGVsaW1pdGVyXCJdO1xuICAgIGNvbnN0IGNhbGxiYWNrcyA9IHNlbGZbaW50ZXJuYWxTeW1ib2xdW1wiY2FsbGJhY2tzXCJdO1xuXG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgbGV0IHN0YXJ0SW5kZXggPSB0ZXh0LmluZGV4T2Yob3Blbk1hcmtlcik7XG4gICAgICAgIC8vIG5vIG1hcmtlclxuICAgICAgICBpZiAoc3RhcnRJbmRleCA9PT0gLTEpIHtcbiAgICAgICAgICAgIGZvcm1hdHRlZC5wdXNoKHRleHQpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH0gZWxzZSBpZiAoc3RhcnRJbmRleCA+IDApIHtcbiAgICAgICAgICAgIGZvcm1hdHRlZC5wdXNoKHRleHQuc3Vic3RyaW5nKDAsIHN0YXJ0SW5kZXgpKTtcbiAgICAgICAgICAgIHRleHQgPSB0ZXh0LnN1YnN0cmluZyhzdGFydEluZGV4KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBlbmRJbmRleCA9IHRleHQuc3Vic3RyaW5nKG9wZW5NYXJrZXIubGVuZ3RoKS5pbmRleE9mKGNsb3NlTWFya2VyKTtcbiAgICAgICAgaWYgKGVuZEluZGV4ICE9PSAtMSkgZW5kSW5kZXggKz0gb3Blbk1hcmtlci5sZW5ndGg7XG4gICAgICAgIGxldCBpbnNpZGVTdGFydEluZGV4ID0gdGV4dC5zdWJzdHJpbmcob3Blbk1hcmtlci5sZW5ndGgpLmluZGV4T2Yob3Blbk1hcmtlcik7XG4gICAgICAgIGlmIChpbnNpZGVTdGFydEluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgaW5zaWRlU3RhcnRJbmRleCArPSBvcGVuTWFya2VyLmxlbmd0aDtcbiAgICAgICAgICAgIGlmIChpbnNpZGVTdGFydEluZGV4IDwgZW5kSW5kZXgpIHtcbiAgICAgICAgICAgICAgICBsZXQgcmVzdWx0ID0gdG9rZW5pemUuY2FsbChzZWxmLCB0ZXh0LnN1YnN0cmluZyhpbnNpZGVTdGFydEluZGV4KSwgb3Blbk1hcmtlciwgY2xvc2VNYXJrZXIpO1xuICAgICAgICAgICAgICAgIHRleHQgPSB0ZXh0LnN1YnN0cmluZygwLCBpbnNpZGVTdGFydEluZGV4KSArIHJlc3VsdDtcbiAgICAgICAgICAgICAgICBlbmRJbmRleCA9IHRleHQuc3Vic3RyaW5nKG9wZW5NYXJrZXIubGVuZ3RoKS5pbmRleE9mKGNsb3NlTWFya2VyKTtcbiAgICAgICAgICAgICAgICBpZiAoZW5kSW5kZXggIT09IC0xKSBlbmRJbmRleCArPSBvcGVuTWFya2VyLmxlbmd0aDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlbmRJbmRleCA9PT0gLTEpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInN5bnRheCBlcnJvciBpbiBmb3JtYXR0ZXIgdGVtcGxhdGVcIik7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQga2V5ID0gdGV4dC5zdWJzdHJpbmcob3Blbk1hcmtlci5sZW5ndGgsIGVuZEluZGV4KTtcbiAgICAgICAgbGV0IHBhcnRzID0ga2V5LnNwbGl0KHBhcmFtZXRlckRlbGltaXRlcik7XG4gICAgICAgIGxldCBjdXJyZW50UGlwZSA9IHBhcnRzLnNoaWZ0KCk7XG5cbiAgICAgICAgc2VsZlt3b3JraW5nRGF0YVN5bWJvbF0gPSBleHRlbmQoe30sIHNlbGZbaW50ZXJuYWxPYmplY3RTeW1ib2xdLCBzZWxmW3dvcmtpbmdEYXRhU3ltYm9sXSk7XG5cbiAgICAgICAgZm9yIChjb25zdCBrdiBvZiBwYXJ0cykge1xuICAgICAgICAgICAgY29uc3QgW2ssIHZdID0ga3Yuc3BsaXQocGFyYW1ldGVyQXNzaWdubWVudCk7XG4gICAgICAgICAgICBzZWxmW3dvcmtpbmdEYXRhU3ltYm9sXVtrXSA9IHY7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB0MSA9IGtleS5zcGxpdChcInxcIikuc2hpZnQoKS50cmltKCk7IC8vIHBpcGUgc3ltYm9sXG4gICAgICAgIGNvbnN0IHQyID0gdDEuc3BsaXQoXCI6OlwiKS5zaGlmdCgpLnRyaW0oKTsgLy8ga2V5IHZhbHVlIGRlbGltaXRlclxuICAgICAgICBjb25zdCB0MyA9IHQyLnNwbGl0KFwiLlwiKS5zaGlmdCgpLnRyaW0oKTsgLy8gcGF0aCBkZWxpbWl0ZXJcbiAgICAgICAgbGV0IHByZWZpeCA9IHNlbGZbd29ya2luZ0RhdGFTeW1ib2xdPy5bdDNdID8gXCJwYXRoOlwiIDogXCJzdGF0aWM6XCI7XG5cbiAgICAgICAgbGV0IGNvbW1hbmQgPSBcIlwiO1xuICAgICAgICBpZiAocHJlZml4ICYmIGtleS5pbmRleE9mKHByZWZpeCkgIT09IDAgJiYga2V5LmluZGV4T2YoXCJwYXRoOlwiKSAhPT0gMCAmJiBrZXkuaW5kZXhPZihcInN0YXRpYzpcIikgIT09IDApIHtcbiAgICAgICAgICAgIGNvbW1hbmQgPSBwcmVmaXg7XG4gICAgICAgIH1cblxuICAgICAgICBjb21tYW5kICs9IGN1cnJlbnRQaXBlO1xuXG4gICAgICAgIGNvbnN0IHBpcGUgPSBuZXcgUGlwZShjb21tYW5kKTtcblxuICAgICAgICBpZiAoaXNPYmplY3QoY2FsbGJhY2tzKSkge1xuICAgICAgICAgICAgZm9yIChjb25zdCBbbmFtZSwgY2FsbGJhY2tdIG9mIE9iamVjdC5lbnRyaWVzKGNhbGxiYWNrcykpIHtcbiAgICAgICAgICAgICAgICBwaXBlLnNldENhbGxiYWNrKG5hbWUsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGZvcm1hdHRlZC5wdXNoKHZhbGlkYXRlU3RyaW5nKHBpcGUucnVuKHNlbGZbd29ya2luZ0RhdGFTeW1ib2xdKSkpO1xuXG4gICAgICAgIHRleHQgPSB0ZXh0LnN1YnN0cmluZyhlbmRJbmRleCArIGNsb3NlTWFya2VyLmxlbmd0aCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZvcm1hdHRlZC5qb2luKFwiXCIpO1xufVxuIiwgIi8qIVxuICogTUlUIExpY2Vuc2VcbiAqIFxuICogQ29weXJpZ2h0IChjKSAyMDE3LTIwMjIgUGVjdWxpYXIgVmVudHVyZXMsIExMQ1xuICogXG4gKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4gKiBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG4gKiBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXG4gKiB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXG4gKiBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbiAqIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4gKiBcbiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluIGFsbFxuICogY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbiAqIFxuICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbiAqIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbiAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG4gKiBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRVxuICogU09GVFdBUkUuXG4gKiBcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmNvbnN0IEFSUkFZX0JVRkZFUl9OQU1FID0gXCJbb2JqZWN0IEFycmF5QnVmZmVyXVwiO1xuY2xhc3MgQnVmZmVyU291cmNlQ29udmVydGVyIHtcbiAgICBzdGF0aWMgaXNBcnJheUJ1ZmZlcihkYXRhKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoZGF0YSkgPT09IEFSUkFZX0JVRkZFUl9OQU1FO1xuICAgIH1cbiAgICBzdGF0aWMgdG9BcnJheUJ1ZmZlcihkYXRhKSB7XG4gICAgICAgIGlmICh0aGlzLmlzQXJyYXlCdWZmZXIoZGF0YSkpIHtcbiAgICAgICAgICAgIHJldHVybiBkYXRhO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkYXRhLmJ5dGVMZW5ndGggPT09IGRhdGEuYnVmZmVyLmJ5dGVMZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiBkYXRhLmJ1ZmZlcjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGF0YS5ieXRlT2Zmc2V0ID09PSAwICYmIGRhdGEuYnl0ZUxlbmd0aCA9PT0gZGF0YS5idWZmZXIuYnl0ZUxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIGRhdGEuYnVmZmVyO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnRvVWludDhBcnJheShkYXRhLmJ1ZmZlcilcbiAgICAgICAgICAgIC5zbGljZShkYXRhLmJ5dGVPZmZzZXQsIGRhdGEuYnl0ZU9mZnNldCArIGRhdGEuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgIC5idWZmZXI7XG4gICAgfVxuICAgIHN0YXRpYyB0b1VpbnQ4QXJyYXkoZGF0YSkge1xuICAgICAgICByZXR1cm4gdGhpcy50b1ZpZXcoZGF0YSwgVWludDhBcnJheSk7XG4gICAgfVxuICAgIHN0YXRpYyB0b1ZpZXcoZGF0YSwgdHlwZSkge1xuICAgICAgICBpZiAoZGF0YS5jb25zdHJ1Y3RvciA9PT0gdHlwZSkge1xuICAgICAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuaXNBcnJheUJ1ZmZlcihkYXRhKSkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyB0eXBlKGRhdGEpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmlzQXJyYXlCdWZmZXJWaWV3KGRhdGEpKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IHR5cGUoZGF0YS5idWZmZXIsIGRhdGEuYnl0ZU9mZnNldCwgZGF0YS5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiVGhlIHByb3ZpZGVkIHZhbHVlIGlzIG5vdCBvZiB0eXBlICcoQXJyYXlCdWZmZXIgb3IgQXJyYXlCdWZmZXJWaWV3KSdcIik7XG4gICAgfVxuICAgIHN0YXRpYyBpc0J1ZmZlclNvdXJjZShkYXRhKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmlzQXJyYXlCdWZmZXJWaWV3KGRhdGEpXG4gICAgICAgICAgICB8fCB0aGlzLmlzQXJyYXlCdWZmZXIoZGF0YSk7XG4gICAgfVxuICAgIHN0YXRpYyBpc0FycmF5QnVmZmVyVmlldyhkYXRhKSB7XG4gICAgICAgIHJldHVybiBBcnJheUJ1ZmZlci5pc1ZpZXcoZGF0YSlcbiAgICAgICAgICAgIHx8IChkYXRhICYmIHRoaXMuaXNBcnJheUJ1ZmZlcihkYXRhLmJ1ZmZlcikpO1xuICAgIH1cbiAgICBzdGF0aWMgaXNFcXVhbChhLCBiKSB7XG4gICAgICAgIGNvbnN0IGFWaWV3ID0gQnVmZmVyU291cmNlQ29udmVydGVyLnRvVWludDhBcnJheShhKTtcbiAgICAgICAgY29uc3QgYlZpZXcgPSBCdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9VaW50OEFycmF5KGIpO1xuICAgICAgICBpZiAoYVZpZXcubGVuZ3RoICE9PSBiVmlldy5ieXRlTGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhVmlldy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKGFWaWV3W2ldICE9PSBiVmlld1tpXSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgc3RhdGljIGNvbmNhdCguLi5hcmdzKSB7XG4gICAgICAgIGxldCBidWZmZXJzO1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShhcmdzWzBdKSAmJiAhKGFyZ3NbMV0gaW5zdGFuY2VvZiBGdW5jdGlvbikpIHtcbiAgICAgICAgICAgIGJ1ZmZlcnMgPSBhcmdzWzBdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKEFycmF5LmlzQXJyYXkoYXJnc1swXSkgJiYgYXJnc1sxXSBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICAgICAgICBidWZmZXJzID0gYXJnc1swXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmIChhcmdzW2FyZ3MubGVuZ3RoIC0gMV0gaW5zdGFuY2VvZiBGdW5jdGlvbikge1xuICAgICAgICAgICAgICAgIGJ1ZmZlcnMgPSBhcmdzLnNsaWNlKDAsIGFyZ3MubGVuZ3RoIC0gMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBidWZmZXJzID0gYXJncztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsZXQgc2l6ZSA9IDA7XG4gICAgICAgIGZvciAoY29uc3QgYnVmZmVyIG9mIGJ1ZmZlcnMpIHtcbiAgICAgICAgICAgIHNpemUgKz0gYnVmZmVyLmJ5dGVMZW5ndGg7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVzID0gbmV3IFVpbnQ4QXJyYXkoc2l6ZSk7XG4gICAgICAgIGxldCBvZmZzZXQgPSAwO1xuICAgICAgICBmb3IgKGNvbnN0IGJ1ZmZlciBvZiBidWZmZXJzKSB7XG4gICAgICAgICAgICBjb25zdCB2aWV3ID0gdGhpcy50b1VpbnQ4QXJyYXkoYnVmZmVyKTtcbiAgICAgICAgICAgIHJlcy5zZXQodmlldywgb2Zmc2V0KTtcbiAgICAgICAgICAgIG9mZnNldCArPSB2aWV3Lmxlbmd0aDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYXJnc1thcmdzLmxlbmd0aCAtIDFdIGluc3RhbmNlb2YgRnVuY3Rpb24pIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnRvVmlldyhyZXMsIGFyZ3NbYXJncy5sZW5ndGggLSAxXSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlcy5idWZmZXI7XG4gICAgfVxufVxuXG5jb25zdCBTVFJJTkdfVFlQRSA9IFwic3RyaW5nXCI7XG5jb25zdCBIRVhfUkVHRVggPSAvXlswLTlhLWZdKyQvaTtcbmNvbnN0IEJBU0U2NF9SRUdFWCA9IC9eKD86W0EtWmEtejAtOSsvXXs0fSkqKD86W0EtWmEtejAtOSsvXXsyfT09fFtBLVphLXowLTkrL117M309KT8kLztcbmNvbnN0IEJBU0U2NFVSTF9SRUdFWCA9IC9eW2EtekEtWjAtOS1fXSskLztcbmNsYXNzIFV0ZjhDb252ZXJ0ZXIge1xuICAgIHN0YXRpYyBmcm9tU3RyaW5nKHRleHQpIHtcbiAgICAgICAgY29uc3QgcyA9IHVuZXNjYXBlKGVuY29kZVVSSUNvbXBvbmVudCh0ZXh0KSk7XG4gICAgICAgIGNvbnN0IHVpbnRBcnJheSA9IG5ldyBVaW50OEFycmF5KHMubGVuZ3RoKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB1aW50QXJyYXlbaV0gPSBzLmNoYXJDb2RlQXQoaSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVpbnRBcnJheS5idWZmZXI7XG4gICAgfVxuICAgIHN0YXRpYyB0b1N0cmluZyhidWZmZXIpIHtcbiAgICAgICAgY29uc3QgYnVmID0gQnVmZmVyU291cmNlQ29udmVydGVyLnRvVWludDhBcnJheShidWZmZXIpO1xuICAgICAgICBsZXQgZW5jb2RlZFN0cmluZyA9IFwiXCI7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYnVmLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBlbmNvZGVkU3RyaW5nICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBkZWNvZGVkU3RyaW5nID0gZGVjb2RlVVJJQ29tcG9uZW50KGVzY2FwZShlbmNvZGVkU3RyaW5nKSk7XG4gICAgICAgIHJldHVybiBkZWNvZGVkU3RyaW5nO1xuICAgIH1cbn1cbmNsYXNzIFV0ZjE2Q29udmVydGVyIHtcbiAgICBzdGF0aWMgdG9TdHJpbmcoYnVmZmVyLCBsaXR0bGVFbmRpYW4gPSBmYWxzZSkge1xuICAgICAgICBjb25zdCBhcnJheUJ1ZmZlciA9IEJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b0FycmF5QnVmZmVyKGJ1ZmZlcik7XG4gICAgICAgIGNvbnN0IGRhdGFWaWV3ID0gbmV3IERhdGFWaWV3KGFycmF5QnVmZmVyKTtcbiAgICAgICAgbGV0IHJlcyA9IFwiXCI7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXJyYXlCdWZmZXIuYnl0ZUxlbmd0aDsgaSArPSAyKSB7XG4gICAgICAgICAgICBjb25zdCBjb2RlID0gZGF0YVZpZXcuZ2V0VWludDE2KGksIGxpdHRsZUVuZGlhbik7XG4gICAgICAgICAgICByZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShjb2RlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cbiAgICBzdGF0aWMgZnJvbVN0cmluZyh0ZXh0LCBsaXR0bGVFbmRpYW4gPSBmYWxzZSkge1xuICAgICAgICBjb25zdCByZXMgPSBuZXcgQXJyYXlCdWZmZXIodGV4dC5sZW5ndGggKiAyKTtcbiAgICAgICAgY29uc3QgZGF0YVZpZXcgPSBuZXcgRGF0YVZpZXcocmVzKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0ZXh0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBkYXRhVmlldy5zZXRVaW50MTYoaSAqIDIsIHRleHQuY2hhckNvZGVBdChpKSwgbGl0dGxlRW5kaWFuKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cbn1cbmNsYXNzIENvbnZlcnQge1xuICAgIHN0YXRpYyBpc0hleChkYXRhKSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgZGF0YSA9PT0gU1RSSU5HX1RZUEVcbiAgICAgICAgICAgICYmIEhFWF9SRUdFWC50ZXN0KGRhdGEpO1xuICAgIH1cbiAgICBzdGF0aWMgaXNCYXNlNjQoZGF0YSkge1xuICAgICAgICByZXR1cm4gdHlwZW9mIGRhdGEgPT09IFNUUklOR19UWVBFXG4gICAgICAgICAgICAmJiBCQVNFNjRfUkVHRVgudGVzdChkYXRhKTtcbiAgICB9XG4gICAgc3RhdGljIGlzQmFzZTY0VXJsKGRhdGEpIHtcbiAgICAgICAgcmV0dXJuIHR5cGVvZiBkYXRhID09PSBTVFJJTkdfVFlQRVxuICAgICAgICAgICAgJiYgQkFTRTY0VVJMX1JFR0VYLnRlc3QoZGF0YSk7XG4gICAgfVxuICAgIHN0YXRpYyBUb1N0cmluZyhidWZmZXIsIGVuYyA9IFwidXRmOFwiKSB7XG4gICAgICAgIGNvbnN0IGJ1ZiA9IEJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b1VpbnQ4QXJyYXkoYnVmZmVyKTtcbiAgICAgICAgc3dpdGNoIChlbmMudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgY2FzZSBcInV0ZjhcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5Ub1V0ZjhTdHJpbmcoYnVmKTtcbiAgICAgICAgICAgIGNhc2UgXCJiaW5hcnlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5Ub0JpbmFyeShidWYpO1xuICAgICAgICAgICAgY2FzZSBcImhleFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLlRvSGV4KGJ1Zik7XG4gICAgICAgICAgICBjYXNlIFwiYmFzZTY0XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuVG9CYXNlNjQoYnVmKTtcbiAgICAgICAgICAgIGNhc2UgXCJiYXNlNjR1cmxcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5Ub0Jhc2U2NFVybChidWYpO1xuICAgICAgICAgICAgY2FzZSBcInV0ZjE2bGVcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gVXRmMTZDb252ZXJ0ZXIudG9TdHJpbmcoYnVmLCB0cnVlKTtcbiAgICAgICAgICAgIGNhc2UgXCJ1dGYxNlwiOlxuICAgICAgICAgICAgY2FzZSBcInV0ZjE2YmVcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gVXRmMTZDb252ZXJ0ZXIudG9TdHJpbmcoYnVmKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIHR5cGUgb2YgZW5jb2RpbmcgJyR7ZW5jfSdgKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzdGF0aWMgRnJvbVN0cmluZyhzdHIsIGVuYyA9IFwidXRmOFwiKSB7XG4gICAgICAgIGlmICghc3RyKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEFycmF5QnVmZmVyKDApO1xuICAgICAgICB9XG4gICAgICAgIHN3aXRjaCAoZW5jLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICAgIGNhc2UgXCJ1dGY4XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuRnJvbVV0ZjhTdHJpbmcoc3RyKTtcbiAgICAgICAgICAgIGNhc2UgXCJiaW5hcnlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5Gcm9tQmluYXJ5KHN0cik7XG4gICAgICAgICAgICBjYXNlIFwiaGV4XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuRnJvbUhleChzdHIpO1xuICAgICAgICAgICAgY2FzZSBcImJhc2U2NFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLkZyb21CYXNlNjQoc3RyKTtcbiAgICAgICAgICAgIGNhc2UgXCJiYXNlNjR1cmxcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5Gcm9tQmFzZTY0VXJsKHN0cik7XG4gICAgICAgICAgICBjYXNlIFwidXRmMTZsZVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBVdGYxNkNvbnZlcnRlci5mcm9tU3RyaW5nKHN0ciwgdHJ1ZSk7XG4gICAgICAgICAgICBjYXNlIFwidXRmMTZcIjpcbiAgICAgICAgICAgIGNhc2UgXCJ1dGYxNmJlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFV0ZjE2Q29udmVydGVyLmZyb21TdHJpbmcoc3RyKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIHR5cGUgb2YgZW5jb2RpbmcgJyR7ZW5jfSdgKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzdGF0aWMgVG9CYXNlNjQoYnVmZmVyKSB7XG4gICAgICAgIGNvbnN0IGJ1ZiA9IEJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b1VpbnQ4QXJyYXkoYnVmZmVyKTtcbiAgICAgICAgaWYgKHR5cGVvZiBidG9hICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICBjb25zdCBiaW5hcnkgPSB0aGlzLlRvU3RyaW5nKGJ1ZiwgXCJiaW5hcnlcIik7XG4gICAgICAgICAgICByZXR1cm4gYnRvYShiaW5hcnkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGJ1ZikudG9TdHJpbmcoXCJiYXNlNjRcIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIEZyb21CYXNlNjQoYmFzZTY0KSB7XG4gICAgICAgIGNvbnN0IGZvcm1hdHRlZCA9IHRoaXMuZm9ybWF0U3RyaW5nKGJhc2U2NCk7XG4gICAgICAgIGlmICghZm9ybWF0dGVkKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEFycmF5QnVmZmVyKDApO1xuICAgICAgICB9XG4gICAgICAgIGlmICghQ29udmVydC5pc0Jhc2U2NChmb3JtYXR0ZWQpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQXJndW1lbnQgJ2Jhc2U2NFRleHQnIGlzIG5vdCBCYXNlNjQgZW5jb2RlZFwiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGF0b2IgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLkZyb21CaW5hcnkoYXRvYihmb3JtYXR0ZWQpKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShCdWZmZXIuZnJvbShmb3JtYXR0ZWQsIFwiYmFzZTY0XCIpKS5idWZmZXI7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIEZyb21CYXNlNjRVcmwoYmFzZTY0dXJsKSB7XG4gICAgICAgIGNvbnN0IGZvcm1hdHRlZCA9IHRoaXMuZm9ybWF0U3RyaW5nKGJhc2U2NHVybCk7XG4gICAgICAgIGlmICghZm9ybWF0dGVkKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEFycmF5QnVmZmVyKDApO1xuICAgICAgICB9XG4gICAgICAgIGlmICghQ29udmVydC5pc0Jhc2U2NFVybChmb3JtYXR0ZWQpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQXJndW1lbnQgJ2Jhc2U2NHVybCcgaXMgbm90IEJhc2U2NFVybCBlbmNvZGVkXCIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLkZyb21CYXNlNjQodGhpcy5CYXNlNjRQYWRkaW5nKGZvcm1hdHRlZC5yZXBsYWNlKC9cXC0vZywgXCIrXCIpLnJlcGxhY2UoL1xcXy9nLCBcIi9cIikpKTtcbiAgICB9XG4gICAgc3RhdGljIFRvQmFzZTY0VXJsKGRhdGEpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuVG9CYXNlNjQoZGF0YSkucmVwbGFjZSgvXFwrL2csIFwiLVwiKS5yZXBsYWNlKC9cXC8vZywgXCJfXCIpLnJlcGxhY2UoL1xcPS9nLCBcIlwiKTtcbiAgICB9XG4gICAgc3RhdGljIEZyb21VdGY4U3RyaW5nKHRleHQsIGVuY29kaW5nID0gQ29udmVydC5ERUZBVUxUX1VURjhfRU5DT0RJTkcpIHtcbiAgICAgICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgICAgICAgY2FzZSBcImFzY2lpXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuRnJvbUJpbmFyeSh0ZXh0KTtcbiAgICAgICAgICAgIGNhc2UgXCJ1dGY4XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFV0ZjhDb252ZXJ0ZXIuZnJvbVN0cmluZyh0ZXh0KTtcbiAgICAgICAgICAgIGNhc2UgXCJ1dGYxNlwiOlxuICAgICAgICAgICAgY2FzZSBcInV0ZjE2YmVcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gVXRmMTZDb252ZXJ0ZXIuZnJvbVN0cmluZyh0ZXh0KTtcbiAgICAgICAgICAgIGNhc2UgXCJ1dGYxNmxlXCI6XG4gICAgICAgICAgICBjYXNlIFwidXNjMlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBVdGYxNkNvbnZlcnRlci5mcm9tU3RyaW5nKHRleHQsIHRydWUpO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gdHlwZSBvZiBlbmNvZGluZyAnJHtlbmNvZGluZ30nYCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIFRvVXRmOFN0cmluZyhidWZmZXIsIGVuY29kaW5nID0gQ29udmVydC5ERUZBVUxUX1VURjhfRU5DT0RJTkcpIHtcbiAgICAgICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgICAgICAgY2FzZSBcImFzY2lpXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuVG9CaW5hcnkoYnVmZmVyKTtcbiAgICAgICAgICAgIGNhc2UgXCJ1dGY4XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFV0ZjhDb252ZXJ0ZXIudG9TdHJpbmcoYnVmZmVyKTtcbiAgICAgICAgICAgIGNhc2UgXCJ1dGYxNlwiOlxuICAgICAgICAgICAgY2FzZSBcInV0ZjE2YmVcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gVXRmMTZDb252ZXJ0ZXIudG9TdHJpbmcoYnVmZmVyKTtcbiAgICAgICAgICAgIGNhc2UgXCJ1dGYxNmxlXCI6XG4gICAgICAgICAgICBjYXNlIFwidXNjMlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBVdGYxNkNvbnZlcnRlci50b1N0cmluZyhidWZmZXIsIHRydWUpO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gdHlwZSBvZiBlbmNvZGluZyAnJHtlbmNvZGluZ30nYCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIEZyb21CaW5hcnkodGV4dCkge1xuICAgICAgICBjb25zdCBzdHJpbmdMZW5ndGggPSB0ZXh0Lmxlbmd0aDtcbiAgICAgICAgY29uc3QgcmVzdWx0VmlldyA9IG5ldyBVaW50OEFycmF5KHN0cmluZ0xlbmd0aCk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3RyaW5nTGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHJlc3VsdFZpZXdbaV0gPSB0ZXh0LmNoYXJDb2RlQXQoaSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdFZpZXcuYnVmZmVyO1xuICAgIH1cbiAgICBzdGF0aWMgVG9CaW5hcnkoYnVmZmVyKSB7XG4gICAgICAgIGNvbnN0IGJ1ZiA9IEJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b1VpbnQ4QXJyYXkoYnVmZmVyKTtcbiAgICAgICAgbGV0IHJlcyA9IFwiXCI7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYnVmLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICByZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxuICAgIHN0YXRpYyBUb0hleChidWZmZXIpIHtcbiAgICAgICAgY29uc3QgYnVmID0gQnVmZmVyU291cmNlQ29udmVydGVyLnRvVWludDhBcnJheShidWZmZXIpO1xuICAgICAgICBsZXQgcmVzdWx0ID0gXCJcIjtcbiAgICAgICAgY29uc3QgbGVuID0gYnVmLmxlbmd0aDtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgY29uc3QgYnl0ZSA9IGJ1ZltpXTtcbiAgICAgICAgICAgIGlmIChieXRlIDwgMTYpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgKz0gXCIwXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXN1bHQgKz0gYnl0ZS50b1N0cmluZygxNik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgc3RhdGljIEZyb21IZXgoaGV4U3RyaW5nKSB7XG4gICAgICAgIGxldCBmb3JtYXR0ZWQgPSB0aGlzLmZvcm1hdFN0cmluZyhoZXhTdHJpbmcpO1xuICAgICAgICBpZiAoIWZvcm1hdHRlZCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBBcnJheUJ1ZmZlcigwKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIUNvbnZlcnQuaXNIZXgoZm9ybWF0dGVkKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkFyZ3VtZW50ICdoZXhTdHJpbmcnIGlzIG5vdCBIRVggZW5jb2RlZFwiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZm9ybWF0dGVkLmxlbmd0aCAlIDIpIHtcbiAgICAgICAgICAgIGZvcm1hdHRlZCA9IGAwJHtmb3JtYXR0ZWR9YDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCByZXMgPSBuZXcgVWludDhBcnJheShmb3JtYXR0ZWQubGVuZ3RoIC8gMik7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZm9ybWF0dGVkLmxlbmd0aDsgaSA9IGkgKyAyKSB7XG4gICAgICAgICAgICBjb25zdCBjID0gZm9ybWF0dGVkLnNsaWNlKGksIGkgKyAyKTtcbiAgICAgICAgICAgIHJlc1tpIC8gMl0gPSBwYXJzZUludChjLCAxNik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlcy5idWZmZXI7XG4gICAgfVxuICAgIHN0YXRpYyBUb1V0ZjE2U3RyaW5nKGJ1ZmZlciwgbGl0dGxlRW5kaWFuID0gZmFsc2UpIHtcbiAgICAgICAgcmV0dXJuIFV0ZjE2Q29udmVydGVyLnRvU3RyaW5nKGJ1ZmZlciwgbGl0dGxlRW5kaWFuKTtcbiAgICB9XG4gICAgc3RhdGljIEZyb21VdGYxNlN0cmluZyh0ZXh0LCBsaXR0bGVFbmRpYW4gPSBmYWxzZSkge1xuICAgICAgICByZXR1cm4gVXRmMTZDb252ZXJ0ZXIuZnJvbVN0cmluZyh0ZXh0LCBsaXR0bGVFbmRpYW4pO1xuICAgIH1cbiAgICBzdGF0aWMgQmFzZTY0UGFkZGluZyhiYXNlNjQpIHtcbiAgICAgICAgY29uc3QgcGFkQ291bnQgPSA0IC0gKGJhc2U2NC5sZW5ndGggJSA0KTtcbiAgICAgICAgaWYgKHBhZENvdW50IDwgNCkge1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwYWRDb3VudDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgYmFzZTY0ICs9IFwiPVwiO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBiYXNlNjQ7XG4gICAgfVxuICAgIHN0YXRpYyBmb3JtYXRTdHJpbmcoZGF0YSkge1xuICAgICAgICByZXR1cm4gKGRhdGEgPT09IG51bGwgfHwgZGF0YSA9PT0gdm9pZCAwID8gdm9pZCAwIDogZGF0YS5yZXBsYWNlKC9bXFxuXFxyXFx0IF0vZywgXCJcIikpIHx8IFwiXCI7XG4gICAgfVxufVxuQ29udmVydC5ERUZBVUxUX1VURjhfRU5DT0RJTkcgPSBcInV0ZjhcIjtcblxuZnVuY3Rpb24gYXNzaWduKHRhcmdldCwgLi4uc291cmNlcykge1xuICAgIGNvbnN0IHJlcyA9IGFyZ3VtZW50c1swXTtcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBvYmogPSBhcmd1bWVudHNbaV07XG4gICAgICAgIGZvciAoY29uc3QgcHJvcCBpbiBvYmopIHtcbiAgICAgICAgICAgIHJlc1twcm9wXSA9IG9ialtwcm9wXTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzO1xufVxuZnVuY3Rpb24gY29tYmluZSguLi5idWYpIHtcbiAgICBjb25zdCB0b3RhbEJ5dGVMZW5ndGggPSBidWYubWFwKChpdGVtKSA9PiBpdGVtLmJ5dGVMZW5ndGgpLnJlZHVjZSgocHJldiwgY3VyKSA9PiBwcmV2ICsgY3VyKTtcbiAgICBjb25zdCByZXMgPSBuZXcgVWludDhBcnJheSh0b3RhbEJ5dGVMZW5ndGgpO1xuICAgIGxldCBjdXJyZW50UG9zID0gMDtcbiAgICBidWYubWFwKChpdGVtKSA9PiBuZXcgVWludDhBcnJheShpdGVtKSkuZm9yRWFjaCgoYXJyKSA9PiB7XG4gICAgICAgIGZvciAoY29uc3QgaXRlbTIgb2YgYXJyKSB7XG4gICAgICAgICAgICByZXNbY3VycmVudFBvcysrXSA9IGl0ZW0yO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlcy5idWZmZXI7XG59XG5mdW5jdGlvbiBpc0VxdWFsKGJ5dGVzMSwgYnl0ZXMyKSB7XG4gICAgaWYgKCEoYnl0ZXMxICYmIGJ5dGVzMikpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoYnl0ZXMxLmJ5dGVMZW5ndGggIT09IGJ5dGVzMi5ieXRlTGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgY29uc3QgYjEgPSBuZXcgVWludDhBcnJheShieXRlczEpO1xuICAgIGNvbnN0IGIyID0gbmV3IFVpbnQ4QXJyYXkoYnl0ZXMyKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJ5dGVzMS5ieXRlTGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGIxW2ldICE9PSBiMltpXSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuXG5leHBvcnRzLkJ1ZmZlclNvdXJjZUNvbnZlcnRlciA9IEJ1ZmZlclNvdXJjZUNvbnZlcnRlcjtcbmV4cG9ydHMuQ29udmVydCA9IENvbnZlcnQ7XG5leHBvcnRzLmFzc2lnbiA9IGFzc2lnbjtcbmV4cG9ydHMuY29tYmluZSA9IGNvbWJpbmU7XG5leHBvcnRzLmlzRXF1YWwgPSBpc0VxdWFsO1xuIiwgIi8qIVxuIENvcHlyaWdodCAoYykgUGVjdWxpYXIgVmVudHVyZXMsIExMQ1xuKi9cblxuZnVuY3Rpb24gZ2V0VVRDRGF0ZShkYXRlKSB7XHJcbiAgICByZXR1cm4gbmV3IERhdGUoZGF0ZS5nZXRUaW1lKCkgKyAoZGF0ZS5nZXRUaW1lem9uZU9mZnNldCgpICogNjAwMDApKTtcclxufVxyXG5mdW5jdGlvbiBnZXRQYXJhbWV0ZXJzVmFsdWUocGFyYW1ldGVycywgbmFtZSwgZGVmYXVsdFZhbHVlKSB7XHJcbiAgICB2YXIgX2E7XHJcbiAgICBpZiAoKHBhcmFtZXRlcnMgaW5zdGFuY2VvZiBPYmplY3QpID09PSBmYWxzZSkge1xyXG4gICAgICAgIHJldHVybiBkZWZhdWx0VmFsdWU7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gKF9hID0gcGFyYW1ldGVyc1tuYW1lXSkgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogZGVmYXVsdFZhbHVlO1xyXG59XHJcbmZ1bmN0aW9uIGJ1ZmZlclRvSGV4Q29kZXMoaW5wdXRCdWZmZXIsIGlucHV0T2Zmc2V0ID0gMCwgaW5wdXRMZW5ndGggPSAoaW5wdXRCdWZmZXIuYnl0ZUxlbmd0aCAtIGlucHV0T2Zmc2V0KSwgaW5zZXJ0U3BhY2UgPSBmYWxzZSkge1xyXG4gICAgbGV0IHJlc3VsdCA9IFwiXCI7XHJcbiAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgKG5ldyBVaW50OEFycmF5KGlucHV0QnVmZmVyLCBpbnB1dE9mZnNldCwgaW5wdXRMZW5ndGgpKSkge1xyXG4gICAgICAgIGNvbnN0IHN0ciA9IGl0ZW0udG9TdHJpbmcoMTYpLnRvVXBwZXJDYXNlKCk7XHJcbiAgICAgICAgaWYgKHN0ci5sZW5ndGggPT09IDEpIHtcclxuICAgICAgICAgICAgcmVzdWx0ICs9IFwiMFwiO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXN1bHQgKz0gc3RyO1xyXG4gICAgICAgIGlmIChpbnNlcnRTcGFjZSkge1xyXG4gICAgICAgICAgICByZXN1bHQgKz0gXCIgXCI7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHJlc3VsdC50cmltKCk7XHJcbn1cclxuZnVuY3Rpb24gY2hlY2tCdWZmZXJQYXJhbXMoYmFzZUJsb2NrLCBpbnB1dEJ1ZmZlciwgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoKSB7XHJcbiAgICBpZiAoIShpbnB1dEJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSkge1xyXG4gICAgICAgIGJhc2VCbG9jay5lcnJvciA9IFwiV3JvbmcgcGFyYW1ldGVyOiBpbnB1dEJ1ZmZlciBtdXN0IGJlIFxcXCJBcnJheUJ1ZmZlclxcXCJcIjtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgICBpZiAoIWlucHV0QnVmZmVyLmJ5dGVMZW5ndGgpIHtcclxuICAgICAgICBiYXNlQmxvY2suZXJyb3IgPSBcIldyb25nIHBhcmFtZXRlcjogaW5wdXRCdWZmZXIgaGFzIHplcm8gbGVuZ3RoXCI7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gICAgaWYgKGlucHV0T2Zmc2V0IDwgMCkge1xyXG4gICAgICAgIGJhc2VCbG9jay5lcnJvciA9IFwiV3JvbmcgcGFyYW1ldGVyOiBpbnB1dE9mZnNldCBsZXNzIHRoYW4gemVyb1wiO1xyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIGlmIChpbnB1dExlbmd0aCA8IDApIHtcclxuICAgICAgICBiYXNlQmxvY2suZXJyb3IgPSBcIldyb25nIHBhcmFtZXRlcjogaW5wdXRMZW5ndGggbGVzcyB0aGFuIHplcm9cIjtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgICBpZiAoKGlucHV0QnVmZmVyLmJ5dGVMZW5ndGggLSBpbnB1dE9mZnNldCAtIGlucHV0TGVuZ3RoKSA8IDApIHtcclxuICAgICAgICBiYXNlQmxvY2suZXJyb3IgPSBcIkVuZCBvZiBpbnB1dCByZWFjaGVkIGJlZm9yZSBtZXNzYWdlIHdhcyBmdWxseSBkZWNvZGVkIChpbmNvbnNpc3RlbnQgb2Zmc2V0IGFuZCBsZW5ndGggdmFsdWVzKVwiO1xyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIHJldHVybiB0cnVlO1xyXG59XHJcbmZ1bmN0aW9uIHV0aWxGcm9tQmFzZShpbnB1dEJ1ZmZlciwgaW5wdXRCYXNlKSB7XHJcbiAgICBsZXQgcmVzdWx0ID0gMDtcclxuICAgIGlmIChpbnB1dEJ1ZmZlci5sZW5ndGggPT09IDEpIHtcclxuICAgICAgICByZXR1cm4gaW5wdXRCdWZmZXJbMF07XHJcbiAgICB9XHJcbiAgICBmb3IgKGxldCBpID0gKGlucHV0QnVmZmVyLmxlbmd0aCAtIDEpOyBpID49IDA7IGktLSkge1xyXG4gICAgICAgIHJlc3VsdCArPSBpbnB1dEJ1ZmZlclsoaW5wdXRCdWZmZXIubGVuZ3RoIC0gMSkgLSBpXSAqIE1hdGgucG93KDIsIGlucHV0QmFzZSAqIGkpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5mdW5jdGlvbiB1dGlsVG9CYXNlKHZhbHVlLCBiYXNlLCByZXNlcnZlZCA9ICgtMSkpIHtcclxuICAgIGNvbnN0IGludGVybmFsUmVzZXJ2ZWQgPSByZXNlcnZlZDtcclxuICAgIGxldCBpbnRlcm5hbFZhbHVlID0gdmFsdWU7XHJcbiAgICBsZXQgcmVzdWx0ID0gMDtcclxuICAgIGxldCBiaWdnZXN0ID0gTWF0aC5wb3coMiwgYmFzZSk7XHJcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IDg7IGkrKykge1xyXG4gICAgICAgIGlmICh2YWx1ZSA8IGJpZ2dlc3QpIHtcclxuICAgICAgICAgICAgbGV0IHJldEJ1ZjtcclxuICAgICAgICAgICAgaWYgKGludGVybmFsUmVzZXJ2ZWQgPCAwKSB7XHJcbiAgICAgICAgICAgICAgICByZXRCdWYgPSBuZXcgQXJyYXlCdWZmZXIoaSk7XHJcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgaWYgKGludGVybmFsUmVzZXJ2ZWQgPCBpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChuZXcgQXJyYXlCdWZmZXIoMCkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0QnVmID0gbmV3IEFycmF5QnVmZmVyKGludGVybmFsUmVzZXJ2ZWQpO1xyXG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gaW50ZXJuYWxSZXNlcnZlZDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjb25zdCByZXRWaWV3ID0gbmV3IFVpbnQ4QXJyYXkocmV0QnVmKTtcclxuICAgICAgICAgICAgZm9yIChsZXQgaiA9IChpIC0gMSk7IGogPj0gMDsgai0tKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBiYXNpcyA9IE1hdGgucG93KDIsIGogKiBiYXNlKTtcclxuICAgICAgICAgICAgICAgIHJldFZpZXdbcmVzdWx0IC0gaiAtIDFdID0gTWF0aC5mbG9vcihpbnRlcm5hbFZhbHVlIC8gYmFzaXMpO1xyXG4gICAgICAgICAgICAgICAgaW50ZXJuYWxWYWx1ZSAtPSAocmV0Vmlld1tyZXN1bHQgLSBqIC0gMV0pICogYmFzaXM7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHJldEJ1ZjtcclxuICAgICAgICB9XHJcbiAgICAgICAgYmlnZ2VzdCAqPSBNYXRoLnBvdygyLCBiYXNlKTtcclxuICAgIH1cclxuICAgIHJldHVybiBuZXcgQXJyYXlCdWZmZXIoMCk7XHJcbn1cclxuZnVuY3Rpb24gdXRpbENvbmNhdEJ1ZiguLi5idWZmZXJzKSB7XHJcbiAgICBsZXQgb3V0cHV0TGVuZ3RoID0gMDtcclxuICAgIGxldCBwcmV2TGVuZ3RoID0gMDtcclxuICAgIGZvciAoY29uc3QgYnVmZmVyIG9mIGJ1ZmZlcnMpIHtcclxuICAgICAgICBvdXRwdXRMZW5ndGggKz0gYnVmZmVyLmJ5dGVMZW5ndGg7XHJcbiAgICB9XHJcbiAgICBjb25zdCByZXRCdWYgPSBuZXcgQXJyYXlCdWZmZXIob3V0cHV0TGVuZ3RoKTtcclxuICAgIGNvbnN0IHJldFZpZXcgPSBuZXcgVWludDhBcnJheShyZXRCdWYpO1xyXG4gICAgZm9yIChjb25zdCBidWZmZXIgb2YgYnVmZmVycykge1xyXG4gICAgICAgIHJldFZpZXcuc2V0KG5ldyBVaW50OEFycmF5KGJ1ZmZlciksIHByZXZMZW5ndGgpO1xyXG4gICAgICAgIHByZXZMZW5ndGggKz0gYnVmZmVyLmJ5dGVMZW5ndGg7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcmV0QnVmO1xyXG59XHJcbmZ1bmN0aW9uIHV0aWxDb25jYXRWaWV3KC4uLnZpZXdzKSB7XHJcbiAgICBsZXQgb3V0cHV0TGVuZ3RoID0gMDtcclxuICAgIGxldCBwcmV2TGVuZ3RoID0gMDtcclxuICAgIGZvciAoY29uc3QgdmlldyBvZiB2aWV3cykge1xyXG4gICAgICAgIG91dHB1dExlbmd0aCArPSB2aWV3Lmxlbmd0aDtcclxuICAgIH1cclxuICAgIGNvbnN0IHJldEJ1ZiA9IG5ldyBBcnJheUJ1ZmZlcihvdXRwdXRMZW5ndGgpO1xyXG4gICAgY29uc3QgcmV0VmlldyA9IG5ldyBVaW50OEFycmF5KHJldEJ1Zik7XHJcbiAgICBmb3IgKGNvbnN0IHZpZXcgb2Ygdmlld3MpIHtcclxuICAgICAgICByZXRWaWV3LnNldCh2aWV3LCBwcmV2TGVuZ3RoKTtcclxuICAgICAgICBwcmV2TGVuZ3RoICs9IHZpZXcubGVuZ3RoO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHJldFZpZXc7XHJcbn1cclxuZnVuY3Rpb24gdXRpbERlY29kZVRDKCkge1xyXG4gICAgY29uc3QgYnVmID0gbmV3IFVpbnQ4QXJyYXkodGhpcy52YWx1ZUhleCk7XHJcbiAgICBpZiAodGhpcy52YWx1ZUhleC5ieXRlTGVuZ3RoID49IDIpIHtcclxuICAgICAgICBjb25zdCBjb25kaXRpb24xID0gKGJ1ZlswXSA9PT0gMHhGRikgJiYgKGJ1ZlsxXSAmIDB4ODApO1xyXG4gICAgICAgIGNvbnN0IGNvbmRpdGlvbjIgPSAoYnVmWzBdID09PSAweDAwKSAmJiAoKGJ1ZlsxXSAmIDB4ODApID09PSAweDAwKTtcclxuICAgICAgICBpZiAoY29uZGl0aW9uMSB8fCBjb25kaXRpb24yKSB7XHJcbiAgICAgICAgICAgIHRoaXMud2FybmluZ3MucHVzaChcIk5lZWRsZXNzbHkgbG9uZyBmb3JtYXRcIik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgY29uc3QgYmlnSW50QnVmZmVyID0gbmV3IEFycmF5QnVmZmVyKHRoaXMudmFsdWVIZXguYnl0ZUxlbmd0aCk7XHJcbiAgICBjb25zdCBiaWdJbnRWaWV3ID0gbmV3IFVpbnQ4QXJyYXkoYmlnSW50QnVmZmVyKTtcclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy52YWx1ZUhleC5ieXRlTGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBiaWdJbnRWaWV3W2ldID0gMDtcclxuICAgIH1cclxuICAgIGJpZ0ludFZpZXdbMF0gPSAoYnVmWzBdICYgMHg4MCk7XHJcbiAgICBjb25zdCBiaWdJbnQgPSB1dGlsRnJvbUJhc2UoYmlnSW50VmlldywgOCk7XHJcbiAgICBjb25zdCBzbWFsbEludEJ1ZmZlciA9IG5ldyBBcnJheUJ1ZmZlcih0aGlzLnZhbHVlSGV4LmJ5dGVMZW5ndGgpO1xyXG4gICAgY29uc3Qgc21hbGxJbnRWaWV3ID0gbmV3IFVpbnQ4QXJyYXkoc21hbGxJbnRCdWZmZXIpO1xyXG4gICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLnZhbHVlSGV4LmJ5dGVMZW5ndGg7IGorKykge1xyXG4gICAgICAgIHNtYWxsSW50Vmlld1tqXSA9IGJ1ZltqXTtcclxuICAgIH1cclxuICAgIHNtYWxsSW50Vmlld1swXSAmPSAweDdGO1xyXG4gICAgY29uc3Qgc21hbGxJbnQgPSB1dGlsRnJvbUJhc2Uoc21hbGxJbnRWaWV3LCA4KTtcclxuICAgIHJldHVybiAoc21hbGxJbnQgLSBiaWdJbnQpO1xyXG59XHJcbmZ1bmN0aW9uIHV0aWxFbmNvZGVUQyh2YWx1ZSkge1xyXG4gICAgY29uc3QgbW9kVmFsdWUgPSAodmFsdWUgPCAwKSA/ICh2YWx1ZSAqICgtMSkpIDogdmFsdWU7XHJcbiAgICBsZXQgYmlnSW50ID0gMTI4O1xyXG4gICAgZm9yIChsZXQgaSA9IDE7IGkgPCA4OyBpKyspIHtcclxuICAgICAgICBpZiAobW9kVmFsdWUgPD0gYmlnSW50KSB7XHJcbiAgICAgICAgICAgIGlmICh2YWx1ZSA8IDApIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHNtYWxsSW50ID0gYmlnSW50IC0gbW9kVmFsdWU7XHJcbiAgICAgICAgICAgICAgICBjb25zdCByZXRCdWYgPSB1dGlsVG9CYXNlKHNtYWxsSW50LCA4LCBpKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHJldFZpZXcgPSBuZXcgVWludDhBcnJheShyZXRCdWYpO1xyXG4gICAgICAgICAgICAgICAgcmV0Vmlld1swXSB8PSAweDgwO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJldEJ1ZjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBsZXQgcmV0QnVmID0gdXRpbFRvQmFzZShtb2RWYWx1ZSwgOCwgaSk7XHJcbiAgICAgICAgICAgIGxldCByZXRWaWV3ID0gbmV3IFVpbnQ4QXJyYXkocmV0QnVmKTtcclxuICAgICAgICAgICAgaWYgKHJldFZpZXdbMF0gJiAweDgwKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCB0ZW1wQnVmID0gcmV0QnVmLnNsaWNlKDApO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgdGVtcFZpZXcgPSBuZXcgVWludDhBcnJheSh0ZW1wQnVmKTtcclxuICAgICAgICAgICAgICAgIHJldEJ1ZiA9IG5ldyBBcnJheUJ1ZmZlcihyZXRCdWYuYnl0ZUxlbmd0aCArIDEpO1xyXG4gICAgICAgICAgICAgICAgcmV0VmlldyA9IG5ldyBVaW50OEFycmF5KHJldEJ1Zik7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IHRlbXBCdWYuYnl0ZUxlbmd0aDsgaysrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0Vmlld1trICsgMV0gPSB0ZW1wVmlld1trXTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldFZpZXdbMF0gPSAweDAwO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiByZXRCdWY7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGJpZ0ludCAqPSBNYXRoLnBvdygyLCA4KTtcclxuICAgIH1cclxuICAgIHJldHVybiAobmV3IEFycmF5QnVmZmVyKDApKTtcclxufVxyXG5mdW5jdGlvbiBpc0VxdWFsQnVmZmVyKGlucHV0QnVmZmVyMSwgaW5wdXRCdWZmZXIyKSB7XHJcbiAgICBpZiAoaW5wdXRCdWZmZXIxLmJ5dGVMZW5ndGggIT09IGlucHV0QnVmZmVyMi5ieXRlTGVuZ3RoKSB7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gICAgY29uc3QgdmlldzEgPSBuZXcgVWludDhBcnJheShpbnB1dEJ1ZmZlcjEpO1xyXG4gICAgY29uc3QgdmlldzIgPSBuZXcgVWludDhBcnJheShpbnB1dEJ1ZmZlcjIpO1xyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB2aWV3MS5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGlmICh2aWV3MVtpXSAhPT0gdmlldzJbaV0pIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiB0cnVlO1xyXG59XHJcbmZ1bmN0aW9uIHBhZE51bWJlcihpbnB1dE51bWJlciwgZnVsbExlbmd0aCkge1xyXG4gICAgY29uc3Qgc3RyID0gaW5wdXROdW1iZXIudG9TdHJpbmcoMTApO1xyXG4gICAgaWYgKGZ1bGxMZW5ndGggPCBzdHIubGVuZ3RoKSB7XHJcbiAgICAgICAgcmV0dXJuIFwiXCI7XHJcbiAgICB9XHJcbiAgICBjb25zdCBkaWYgPSBmdWxsTGVuZ3RoIC0gc3RyLmxlbmd0aDtcclxuICAgIGNvbnN0IHBhZGRpbmcgPSBuZXcgQXJyYXkoZGlmKTtcclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGlmOyBpKyspIHtcclxuICAgICAgICBwYWRkaW5nW2ldID0gXCIwXCI7XHJcbiAgICB9XHJcbiAgICBjb25zdCBwYWRkaW5nU3RyaW5nID0gcGFkZGluZy5qb2luKFwiXCIpO1xyXG4gICAgcmV0dXJuIHBhZGRpbmdTdHJpbmcuY29uY2F0KHN0cik7XHJcbn1cclxuY29uc3QgYmFzZTY0VGVtcGxhdGUgPSBcIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky89XCI7XHJcbmNvbnN0IGJhc2U2NFVybFRlbXBsYXRlID0gXCJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OS1fPVwiO1xyXG5mdW5jdGlvbiB0b0Jhc2U2NChpbnB1dCwgdXNlVXJsVGVtcGxhdGUgPSBmYWxzZSwgc2tpcFBhZGRpbmcgPSBmYWxzZSwgc2tpcExlYWRpbmdaZXJvcyA9IGZhbHNlKSB7XHJcbiAgICBsZXQgaSA9IDA7XHJcbiAgICBsZXQgZmxhZzEgPSAwO1xyXG4gICAgbGV0IGZsYWcyID0gMDtcclxuICAgIGxldCBvdXRwdXQgPSBcIlwiO1xyXG4gICAgY29uc3QgdGVtcGxhdGUgPSAodXNlVXJsVGVtcGxhdGUpID8gYmFzZTY0VXJsVGVtcGxhdGUgOiBiYXNlNjRUZW1wbGF0ZTtcclxuICAgIGlmIChza2lwTGVhZGluZ1plcm9zKSB7XHJcbiAgICAgICAgbGV0IG5vblplcm9Qb3NpdGlvbiA9IDA7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbnB1dC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBpZiAoaW5wdXQuY2hhckNvZGVBdChpKSAhPT0gMCkge1xyXG4gICAgICAgICAgICAgICAgbm9uWmVyb1Bvc2l0aW9uID0gaTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlucHV0ID0gaW5wdXQuc2xpY2Uobm9uWmVyb1Bvc2l0aW9uKTtcclxuICAgIH1cclxuICAgIHdoaWxlIChpIDwgaW5wdXQubGVuZ3RoKSB7XHJcbiAgICAgICAgY29uc3QgY2hyMSA9IGlucHV0LmNoYXJDb2RlQXQoaSsrKTtcclxuICAgICAgICBpZiAoaSA+PSBpbnB1dC5sZW5ndGgpIHtcclxuICAgICAgICAgICAgZmxhZzEgPSAxO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBjaHIyID0gaW5wdXQuY2hhckNvZGVBdChpKyspO1xyXG4gICAgICAgIGlmIChpID49IGlucHV0Lmxlbmd0aCkge1xyXG4gICAgICAgICAgICBmbGFnMiA9IDE7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IGNocjMgPSBpbnB1dC5jaGFyQ29kZUF0KGkrKyk7XHJcbiAgICAgICAgY29uc3QgZW5jMSA9IGNocjEgPj4gMjtcclxuICAgICAgICBjb25zdCBlbmMyID0gKChjaHIxICYgMHgwMykgPDwgNCkgfCAoY2hyMiA+PiA0KTtcclxuICAgICAgICBsZXQgZW5jMyA9ICgoY2hyMiAmIDB4MEYpIDw8IDIpIHwgKGNocjMgPj4gNik7XHJcbiAgICAgICAgbGV0IGVuYzQgPSBjaHIzICYgMHgzRjtcclxuICAgICAgICBpZiAoZmxhZzEgPT09IDEpIHtcclxuICAgICAgICAgICAgZW5jMyA9IGVuYzQgPSA2NDtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGlmIChmbGFnMiA9PT0gMSkge1xyXG4gICAgICAgICAgICAgICAgZW5jNCA9IDY0O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChza2lwUGFkZGluZykge1xyXG4gICAgICAgICAgICBpZiAoZW5jMyA9PT0gNjQpIHtcclxuICAgICAgICAgICAgICAgIG91dHB1dCArPSBgJHt0ZW1wbGF0ZS5jaGFyQXQoZW5jMSl9JHt0ZW1wbGF0ZS5jaGFyQXQoZW5jMil9YDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGlmIChlbmM0ID09PSA2NCkge1xyXG4gICAgICAgICAgICAgICAgICAgIG91dHB1dCArPSBgJHt0ZW1wbGF0ZS5jaGFyQXQoZW5jMSl9JHt0ZW1wbGF0ZS5jaGFyQXQoZW5jMil9JHt0ZW1wbGF0ZS5jaGFyQXQoZW5jMyl9YDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIG91dHB1dCArPSBgJHt0ZW1wbGF0ZS5jaGFyQXQoZW5jMSl9JHt0ZW1wbGF0ZS5jaGFyQXQoZW5jMil9JHt0ZW1wbGF0ZS5jaGFyQXQoZW5jMyl9JHt0ZW1wbGF0ZS5jaGFyQXQoZW5jNCl9YDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgb3V0cHV0ICs9IGAke3RlbXBsYXRlLmNoYXJBdChlbmMxKX0ke3RlbXBsYXRlLmNoYXJBdChlbmMyKX0ke3RlbXBsYXRlLmNoYXJBdChlbmMzKX0ke3RlbXBsYXRlLmNoYXJBdChlbmM0KX1gO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBvdXRwdXQ7XHJcbn1cclxuZnVuY3Rpb24gZnJvbUJhc2U2NChpbnB1dCwgdXNlVXJsVGVtcGxhdGUgPSBmYWxzZSwgY3V0VGFpbFplcm9zID0gZmFsc2UpIHtcclxuICAgIGNvbnN0IHRlbXBsYXRlID0gKHVzZVVybFRlbXBsYXRlKSA/IGJhc2U2NFVybFRlbXBsYXRlIDogYmFzZTY0VGVtcGxhdGU7XHJcbiAgICBmdW5jdGlvbiBpbmRleE9mKHRvU2VhcmNoKSB7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCA2NDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmICh0ZW1wbGF0ZS5jaGFyQXQoaSkgPT09IHRvU2VhcmNoKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiA2NDtcclxuICAgIH1cclxuICAgIGZ1bmN0aW9uIHRlc3QoaW5jb21pbmcpIHtcclxuICAgICAgICByZXR1cm4gKChpbmNvbWluZyA9PT0gNjQpID8gMHgwMCA6IGluY29taW5nKTtcclxuICAgIH1cclxuICAgIGxldCBpID0gMDtcclxuICAgIGxldCBvdXRwdXQgPSBcIlwiO1xyXG4gICAgd2hpbGUgKGkgPCBpbnB1dC5sZW5ndGgpIHtcclxuICAgICAgICBjb25zdCBlbmMxID0gaW5kZXhPZihpbnB1dC5jaGFyQXQoaSsrKSk7XHJcbiAgICAgICAgY29uc3QgZW5jMiA9IChpID49IGlucHV0Lmxlbmd0aCkgPyAweDAwIDogaW5kZXhPZihpbnB1dC5jaGFyQXQoaSsrKSk7XHJcbiAgICAgICAgY29uc3QgZW5jMyA9IChpID49IGlucHV0Lmxlbmd0aCkgPyAweDAwIDogaW5kZXhPZihpbnB1dC5jaGFyQXQoaSsrKSk7XHJcbiAgICAgICAgY29uc3QgZW5jNCA9IChpID49IGlucHV0Lmxlbmd0aCkgPyAweDAwIDogaW5kZXhPZihpbnB1dC5jaGFyQXQoaSsrKSk7XHJcbiAgICAgICAgY29uc3QgY2hyMSA9ICh0ZXN0KGVuYzEpIDw8IDIpIHwgKHRlc3QoZW5jMikgPj4gNCk7XHJcbiAgICAgICAgY29uc3QgY2hyMiA9ICgodGVzdChlbmMyKSAmIDB4MEYpIDw8IDQpIHwgKHRlc3QoZW5jMykgPj4gMik7XHJcbiAgICAgICAgY29uc3QgY2hyMyA9ICgodGVzdChlbmMzKSAmIDB4MDMpIDw8IDYpIHwgdGVzdChlbmM0KTtcclxuICAgICAgICBvdXRwdXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShjaHIxKTtcclxuICAgICAgICBpZiAoZW5jMyAhPT0gNjQpIHtcclxuICAgICAgICAgICAgb3V0cHV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoY2hyMik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChlbmM0ICE9PSA2NCkge1xyXG4gICAgICAgICAgICBvdXRwdXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShjaHIzKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAoY3V0VGFpbFplcm9zKSB7XHJcbiAgICAgICAgY29uc3Qgb3V0cHV0TGVuZ3RoID0gb3V0cHV0Lmxlbmd0aDtcclxuICAgICAgICBsZXQgbm9uWmVyb1N0YXJ0ID0gKC0xKTtcclxuICAgICAgICBmb3IgKGxldCBpID0gKG91dHB1dExlbmd0aCAtIDEpOyBpID49IDA7IGktLSkge1xyXG4gICAgICAgICAgICBpZiAob3V0cHV0LmNoYXJDb2RlQXQoaSkgIT09IDApIHtcclxuICAgICAgICAgICAgICAgIG5vblplcm9TdGFydCA9IGk7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAobm9uWmVyb1N0YXJ0ICE9PSAoLTEpKSB7XHJcbiAgICAgICAgICAgIG91dHB1dCA9IG91dHB1dC5zbGljZSgwLCBub25aZXJvU3RhcnQgKyAxKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIG91dHB1dCA9IFwiXCI7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIG91dHB1dDtcclxufVxyXG5mdW5jdGlvbiBhcnJheUJ1ZmZlclRvU3RyaW5nKGJ1ZmZlcikge1xyXG4gICAgbGV0IHJlc3VsdFN0cmluZyA9IFwiXCI7XHJcbiAgICBjb25zdCB2aWV3ID0gbmV3IFVpbnQ4QXJyYXkoYnVmZmVyKTtcclxuICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiB2aWV3KSB7XHJcbiAgICAgICAgcmVzdWx0U3RyaW5nICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoZWxlbWVudCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcmVzdWx0U3RyaW5nO1xyXG59XHJcbmZ1bmN0aW9uIHN0cmluZ1RvQXJyYXlCdWZmZXIoc3RyKSB7XHJcbiAgICBjb25zdCBzdHJpbmdMZW5ndGggPSBzdHIubGVuZ3RoO1xyXG4gICAgY29uc3QgcmVzdWx0QnVmZmVyID0gbmV3IEFycmF5QnVmZmVyKHN0cmluZ0xlbmd0aCk7XHJcbiAgICBjb25zdCByZXN1bHRWaWV3ID0gbmV3IFVpbnQ4QXJyYXkocmVzdWx0QnVmZmVyKTtcclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3RyaW5nTGVuZ3RoOyBpKyspIHtcclxuICAgICAgICByZXN1bHRWaWV3W2ldID0gc3RyLmNoYXJDb2RlQXQoaSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcmVzdWx0QnVmZmVyO1xyXG59XHJcbmNvbnN0IGxvZzIgPSBNYXRoLmxvZygyKTtcclxuZnVuY3Rpb24gbmVhcmVzdFBvd2VyT2YyKGxlbmd0aCkge1xyXG4gICAgY29uc3QgYmFzZSA9IChNYXRoLmxvZyhsZW5ndGgpIC8gbG9nMik7XHJcbiAgICBjb25zdCBmbG9vciA9IE1hdGguZmxvb3IoYmFzZSk7XHJcbiAgICBjb25zdCByb3VuZCA9IE1hdGgucm91bmQoYmFzZSk7XHJcbiAgICByZXR1cm4gKChmbG9vciA9PT0gcm91bmQpID8gZmxvb3IgOiByb3VuZCk7XHJcbn1cclxuZnVuY3Rpb24gY2xlYXJQcm9wcyhvYmplY3QsIHByb3BzQXJyYXkpIHtcclxuICAgIGZvciAoY29uc3QgcHJvcCBvZiBwcm9wc0FycmF5KSB7XHJcbiAgICAgICAgZGVsZXRlIG9iamVjdFtwcm9wXTtcclxuICAgIH1cclxufVxuXG5leHBvcnQgeyBhcnJheUJ1ZmZlclRvU3RyaW5nLCBidWZmZXJUb0hleENvZGVzLCBjaGVja0J1ZmZlclBhcmFtcywgY2xlYXJQcm9wcywgZnJvbUJhc2U2NCwgZ2V0UGFyYW1ldGVyc1ZhbHVlLCBnZXRVVENEYXRlLCBpc0VxdWFsQnVmZmVyLCBuZWFyZXN0UG93ZXJPZjIsIHBhZE51bWJlciwgc3RyaW5nVG9BcnJheUJ1ZmZlciwgdG9CYXNlNjQsIHV0aWxDb25jYXRCdWYsIHV0aWxDb25jYXRWaWV3LCB1dGlsRGVjb2RlVEMsIHV0aWxFbmNvZGVUQywgdXRpbEZyb21CYXNlLCB1dGlsVG9CYXNlIH07XG4iLCAiLyohXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTQsIEdNTyBHbG9iYWxTaWduXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTUtMjAyMiwgUGVjdWxpYXIgVmVudHVyZXNcbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiBcbiAqIEF1dGhvciAyMDE0LTIwMTksIFl1cnkgU3Ryb3poZXZza3lcbiAqIFxuICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbixcbiAqIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiAqIFxuICogKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiAqICAgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4gKiBcbiAqICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4gKiAgIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vclxuICogICBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuICogXG4gKiAqIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIGNvcHlyaWdodCBob2xkZXIgbm9yIHRoZSBuYW1lcyBvZiBpdHNcbiAqICAgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb21cbiAqICAgdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbiAqIFxuICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCIgQU5EXG4gKiBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRFxuICogV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRVxuICogRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1JcbiAqIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuICogKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTO1xuICogTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OXG4gKiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVNcbiAqIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuICogXG4gKi9cblxuaW1wb3J0ICogYXMgcHZ0c3V0aWxzIGZyb20gJ3B2dHN1dGlscyc7XG5pbXBvcnQgKiBhcyBwdnV0aWxzIGZyb20gJ3B2dXRpbHMnO1xuXG5mdW5jdGlvbiBhc3NlcnRCaWdJbnQoKSB7XHJcbiAgICBpZiAodHlwZW9mIEJpZ0ludCA9PT0gXCJ1bmRlZmluZWRcIikge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkJpZ0ludCBpcyBub3QgZGVmaW5lZC4gWW91ciBlbnZpcm9ubWVudCBkb2Vzbid0IGltcGxlbWVudCBCaWdJbnQuXCIpO1xyXG4gICAgfVxyXG59XHJcbmZ1bmN0aW9uIGNvbmNhdChidWZmZXJzKSB7XHJcbiAgICBsZXQgb3V0cHV0TGVuZ3RoID0gMDtcclxuICAgIGxldCBwcmV2TGVuZ3RoID0gMDtcclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYnVmZmVycy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGNvbnN0IGJ1ZmZlciA9IGJ1ZmZlcnNbaV07XHJcbiAgICAgICAgb3V0cHV0TGVuZ3RoICs9IGJ1ZmZlci5ieXRlTGVuZ3RoO1xyXG4gICAgfVxyXG4gICAgY29uc3QgcmV0VmlldyA9IG5ldyBVaW50OEFycmF5KG91dHB1dExlbmd0aCk7XHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJ1ZmZlcnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBjb25zdCBidWZmZXIgPSBidWZmZXJzW2ldO1xyXG4gICAgICAgIHJldFZpZXcuc2V0KG5ldyBVaW50OEFycmF5KGJ1ZmZlciksIHByZXZMZW5ndGgpO1xyXG4gICAgICAgIHByZXZMZW5ndGggKz0gYnVmZmVyLmJ5dGVMZW5ndGg7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcmV0Vmlldy5idWZmZXI7XHJcbn1cclxuZnVuY3Rpb24gY2hlY2tCdWZmZXJQYXJhbXMoYmFzZUJsb2NrLCBpbnB1dEJ1ZmZlciwgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoKSB7XHJcbiAgICBpZiAoIShpbnB1dEJ1ZmZlciBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpKSB7XHJcbiAgICAgICAgYmFzZUJsb2NrLmVycm9yID0gXCJXcm9uZyBwYXJhbWV0ZXI6IGlucHV0QnVmZmVyIG11c3QgYmUgJ1VpbnQ4QXJyYXknXCI7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gICAgaWYgKCFpbnB1dEJ1ZmZlci5ieXRlTGVuZ3RoKSB7XHJcbiAgICAgICAgYmFzZUJsb2NrLmVycm9yID0gXCJXcm9uZyBwYXJhbWV0ZXI6IGlucHV0QnVmZmVyIGhhcyB6ZXJvIGxlbmd0aFwiO1xyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIGlmIChpbnB1dE9mZnNldCA8IDApIHtcclxuICAgICAgICBiYXNlQmxvY2suZXJyb3IgPSBcIldyb25nIHBhcmFtZXRlcjogaW5wdXRPZmZzZXQgbGVzcyB0aGFuIHplcm9cIjtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgICBpZiAoaW5wdXRMZW5ndGggPCAwKSB7XHJcbiAgICAgICAgYmFzZUJsb2NrLmVycm9yID0gXCJXcm9uZyBwYXJhbWV0ZXI6IGlucHV0TGVuZ3RoIGxlc3MgdGhhbiB6ZXJvXCI7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gICAgaWYgKChpbnB1dEJ1ZmZlci5ieXRlTGVuZ3RoIC0gaW5wdXRPZmZzZXQgLSBpbnB1dExlbmd0aCkgPCAwKSB7XHJcbiAgICAgICAgYmFzZUJsb2NrLmVycm9yID0gXCJFbmQgb2YgaW5wdXQgcmVhY2hlZCBiZWZvcmUgbWVzc2FnZSB3YXMgZnVsbHkgZGVjb2RlZCAoaW5jb25zaXN0ZW50IG9mZnNldCBhbmQgbGVuZ3RoIHZhbHVlcylcIjtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdHJ1ZTtcclxufVxuXG5jbGFzcyBWaWV3V3JpdGVyIHtcclxuICAgIGNvbnN0cnVjdG9yKCkge1xyXG4gICAgICAgIHRoaXMuaXRlbXMgPSBbXTtcclxuICAgIH1cclxuICAgIHdyaXRlKGJ1Zikge1xyXG4gICAgICAgIHRoaXMuaXRlbXMucHVzaChidWYpO1xyXG4gICAgfVxyXG4gICAgZmluYWwoKSB7XHJcbiAgICAgICAgcmV0dXJuIGNvbmNhdCh0aGlzLml0ZW1zKTtcclxuICAgIH1cclxufVxuXG5jb25zdCBwb3dlcnMyID0gW25ldyBVaW50OEFycmF5KFsxXSldO1xyXG5jb25zdCBkaWdpdHNTdHJpbmcgPSBcIjAxMjM0NTY3ODlcIjtcclxuY29uc3QgTkFNRSA9IFwibmFtZVwiO1xyXG5jb25zdCBWQUxVRV9IRVhfVklFVyA9IFwidmFsdWVIZXhWaWV3XCI7XHJcbmNvbnN0IElTX0hFWF9PTkxZID0gXCJpc0hleE9ubHlcIjtcclxuY29uc3QgSURfQkxPQ0sgPSBcImlkQmxvY2tcIjtcclxuY29uc3QgVEFHX0NMQVNTID0gXCJ0YWdDbGFzc1wiO1xyXG5jb25zdCBUQUdfTlVNQkVSID0gXCJ0YWdOdW1iZXJcIjtcclxuY29uc3QgSVNfQ09OU1RSVUNURUQgPSBcImlzQ29uc3RydWN0ZWRcIjtcclxuY29uc3QgRlJPTV9CRVIgPSBcImZyb21CRVJcIjtcclxuY29uc3QgVE9fQkVSID0gXCJ0b0JFUlwiO1xyXG5jb25zdCBMT0NBTCA9IFwibG9jYWxcIjtcclxuY29uc3QgRU1QVFlfU1RSSU5HID0gXCJcIjtcclxuY29uc3QgRU1QVFlfQlVGRkVSID0gbmV3IEFycmF5QnVmZmVyKDApO1xyXG5jb25zdCBFTVBUWV9WSUVXID0gbmV3IFVpbnQ4QXJyYXkoMCk7XHJcbmNvbnN0IEVORF9PRl9DT05URU5UX05BTUUgPSBcIkVuZE9mQ29udGVudFwiO1xyXG5jb25zdCBPQ1RFVF9TVFJJTkdfTkFNRSA9IFwiT0NURVQgU1RSSU5HXCI7XHJcbmNvbnN0IEJJVF9TVFJJTkdfTkFNRSA9IFwiQklUIFNUUklOR1wiO1xuXG5mdW5jdGlvbiBIZXhCbG9jayhCYXNlQ2xhc3MpIHtcclxuICAgIHZhciBfYTtcclxuICAgIHJldHVybiBfYSA9IGNsYXNzIFNvbWUgZXh0ZW5kcyBCYXNlQ2xhc3Mge1xyXG4gICAgICAgICAgICBjb25zdHJ1Y3RvciguLi5hcmdzKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2E7XHJcbiAgICAgICAgICAgICAgICBzdXBlciguLi5hcmdzKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IGFyZ3NbMF0gfHwge307XHJcbiAgICAgICAgICAgICAgICB0aGlzLmlzSGV4T25seSA9IChfYSA9IHBhcmFtcy5pc0hleE9ubHkpICE9PSBudWxsICYmIF9hICE9PSB2b2lkIDAgPyBfYSA6IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgdGhpcy52YWx1ZUhleFZpZXcgPSBwYXJhbXMudmFsdWVIZXggPyBwdnRzdXRpbHMuQnVmZmVyU291cmNlQ29udmVydGVyLnRvVWludDhBcnJheShwYXJhbXMudmFsdWVIZXgpIDogRU1QVFlfVklFVztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBnZXQgdmFsdWVIZXgoKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy52YWx1ZUhleFZpZXcuc2xpY2UoKS5idWZmZXI7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgc2V0IHZhbHVlSGV4KHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnZhbHVlSGV4VmlldyA9IG5ldyBVaW50OEFycmF5KHZhbHVlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBmcm9tQkVSKGlucHV0QnVmZmVyLCBpbnB1dE9mZnNldCwgaW5wdXRMZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHZpZXcgPSBpbnB1dEJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyID8gbmV3IFVpbnQ4QXJyYXkoaW5wdXRCdWZmZXIpIDogaW5wdXRCdWZmZXI7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWNoZWNrQnVmZmVyUGFyYW1zKHRoaXMsIHZpZXcsIGlucHV0T2Zmc2V0LCBpbnB1dExlbmd0aCkpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBjb25zdCBlbmRMZW5ndGggPSBpbnB1dE9mZnNldCArIGlucHV0TGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgdGhpcy52YWx1ZUhleFZpZXcgPSB2aWV3LnN1YmFycmF5KGlucHV0T2Zmc2V0LCBlbmRMZW5ndGgpO1xyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLnZhbHVlSGV4Vmlldy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLndhcm5pbmdzLnB1c2goXCJaZXJvIGJ1ZmZlciBsZW5ndGhcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0T2Zmc2V0O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdGhpcy5ibG9ja0xlbmd0aCA9IGlucHV0TGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGVuZExlbmd0aDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0b0JFUihzaXplT25seSA9IGZhbHNlKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuaXNIZXhPbmx5KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lcnJvciA9IFwiRmxhZyAnaXNIZXhPbmx5JyBpcyBub3Qgc2V0LCBhYm9ydFwiO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBFTVBUWV9CVUZGRVI7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoc2l6ZU9ubHkpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEFycmF5QnVmZmVyKHRoaXMudmFsdWVIZXhWaWV3LmJ5dGVMZW5ndGgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuICh0aGlzLnZhbHVlSGV4Vmlldy5ieXRlTGVuZ3RoID09PSB0aGlzLnZhbHVlSGV4Vmlldy5idWZmZXIuYnl0ZUxlbmd0aClcclxuICAgICAgICAgICAgICAgICAgICA/IHRoaXMudmFsdWVIZXhWaWV3LmJ1ZmZlclxyXG4gICAgICAgICAgICAgICAgICAgIDogdGhpcy52YWx1ZUhleFZpZXcuc2xpY2UoKS5idWZmZXI7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdG9KU09OKCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAuLi5zdXBlci50b0pTT04oKSxcclxuICAgICAgICAgICAgICAgICAgICBpc0hleE9ubHk6IHRoaXMuaXNIZXhPbmx5LFxyXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlSGV4OiBwdnRzdXRpbHMuQ29udmVydC5Ub0hleCh0aGlzLnZhbHVlSGV4VmlldyksXHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuICAgICAgICBfYS5OQU1FID0gXCJoZXhCbG9ja1wiLFxyXG4gICAgICAgIF9hO1xyXG59XG5cbmNsYXNzIExvY2FsQmFzZUJsb2NrIHtcclxuICAgIGNvbnN0cnVjdG9yKHsgYmxvY2tMZW5ndGggPSAwLCBlcnJvciA9IEVNUFRZX1NUUklORywgd2FybmluZ3MgPSBbXSwgdmFsdWVCZWZvcmVEZWNvZGUgPSBFTVBUWV9WSUVXLCB9ID0ge30pIHtcclxuICAgICAgICB0aGlzLmJsb2NrTGVuZ3RoID0gYmxvY2tMZW5ndGg7XHJcbiAgICAgICAgdGhpcy5lcnJvciA9IGVycm9yO1xyXG4gICAgICAgIHRoaXMud2FybmluZ3MgPSB3YXJuaW5ncztcclxuICAgICAgICB0aGlzLnZhbHVlQmVmb3JlRGVjb2RlVmlldyA9IHB2dHN1dGlscy5CdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9VaW50OEFycmF5KHZhbHVlQmVmb3JlRGVjb2RlKTtcclxuICAgIH1cclxuICAgIHN0YXRpYyBibG9ja05hbWUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuTkFNRTtcclxuICAgIH1cclxuICAgIGdldCB2YWx1ZUJlZm9yZURlY29kZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZUJlZm9yZURlY29kZVZpZXcuc2xpY2UoKS5idWZmZXI7XHJcbiAgICB9XHJcbiAgICBzZXQgdmFsdWVCZWZvcmVEZWNvZGUodmFsdWUpIHtcclxuICAgICAgICB0aGlzLnZhbHVlQmVmb3JlRGVjb2RlVmlldyA9IG5ldyBVaW50OEFycmF5KHZhbHVlKTtcclxuICAgIH1cclxuICAgIHRvSlNPTigpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBibG9ja05hbWU6IHRoaXMuY29uc3RydWN0b3IuTkFNRSxcclxuICAgICAgICAgICAgYmxvY2tMZW5ndGg6IHRoaXMuYmxvY2tMZW5ndGgsXHJcbiAgICAgICAgICAgIGVycm9yOiB0aGlzLmVycm9yLFxyXG4gICAgICAgICAgICB3YXJuaW5nczogdGhpcy53YXJuaW5ncyxcclxuICAgICAgICAgICAgdmFsdWVCZWZvcmVEZWNvZGU6IHB2dHN1dGlscy5Db252ZXJ0LlRvSGV4KHRoaXMudmFsdWVCZWZvcmVEZWNvZGVWaWV3KSxcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG59XHJcbkxvY2FsQmFzZUJsb2NrLk5BTUUgPSBcImJhc2VCbG9ja1wiO1xuXG5jbGFzcyBWYWx1ZUJsb2NrIGV4dGVuZHMgTG9jYWxCYXNlQmxvY2sge1xyXG4gICAgZnJvbUJFUihpbnB1dEJ1ZmZlciwgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoKSB7XHJcbiAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiVXNlciBuZWVkIHRvIG1ha2UgYSBzcGVjaWZpYyBmdW5jdGlvbiBpbiBhIGNsYXNzIHdoaWNoIGV4dGVuZHMgJ1ZhbHVlQmxvY2snXCIpO1xyXG4gICAgfVxyXG4gICAgdG9CRVIoc2l6ZU9ubHksIHdyaXRlcikge1xyXG4gICAgICAgIHRocm93IFR5cGVFcnJvcihcIlVzZXIgbmVlZCB0byBtYWtlIGEgc3BlY2lmaWMgZnVuY3Rpb24gaW4gYSBjbGFzcyB3aGljaCBleHRlbmRzICdWYWx1ZUJsb2NrJ1wiKTtcclxuICAgIH1cclxufVxyXG5WYWx1ZUJsb2NrLk5BTUUgPSBcInZhbHVlQmxvY2tcIjtcblxuY2xhc3MgTG9jYWxJZGVudGlmaWNhdGlvbkJsb2NrIGV4dGVuZHMgSGV4QmxvY2soTG9jYWxCYXNlQmxvY2spIHtcclxuICAgIGNvbnN0cnVjdG9yKHsgaWRCbG9jayA9IHt9LCB9ID0ge30pIHtcclxuICAgICAgICB2YXIgX2EsIF9iLCBfYywgX2Q7XHJcbiAgICAgICAgc3VwZXIoKTtcclxuICAgICAgICBpZiAoaWRCbG9jaykge1xyXG4gICAgICAgICAgICB0aGlzLmlzSGV4T25seSA9IChfYSA9IGlkQmxvY2suaXNIZXhPbmx5KSAhPT0gbnVsbCAmJiBfYSAhPT0gdm9pZCAwID8gX2EgOiBmYWxzZTtcclxuICAgICAgICAgICAgdGhpcy52YWx1ZUhleFZpZXcgPSBpZEJsb2NrLnZhbHVlSGV4ID8gcHZ0c3V0aWxzLkJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b1VpbnQ4QXJyYXkoaWRCbG9jay52YWx1ZUhleCkgOiBFTVBUWV9WSUVXO1xyXG4gICAgICAgICAgICB0aGlzLnRhZ0NsYXNzID0gKF9iID0gaWRCbG9jay50YWdDbGFzcykgIT09IG51bGwgJiYgX2IgIT09IHZvaWQgMCA/IF9iIDogLTE7XHJcbiAgICAgICAgICAgIHRoaXMudGFnTnVtYmVyID0gKF9jID0gaWRCbG9jay50YWdOdW1iZXIpICE9PSBudWxsICYmIF9jICE9PSB2b2lkIDAgPyBfYyA6IC0xO1xyXG4gICAgICAgICAgICB0aGlzLmlzQ29uc3RydWN0ZWQgPSAoX2QgPSBpZEJsb2NrLmlzQ29uc3RydWN0ZWQpICE9PSBudWxsICYmIF9kICE9PSB2b2lkIDAgPyBfZCA6IGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy50YWdDbGFzcyA9IC0xO1xyXG4gICAgICAgICAgICB0aGlzLnRhZ051bWJlciA9IC0xO1xyXG4gICAgICAgICAgICB0aGlzLmlzQ29uc3RydWN0ZWQgPSBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICB0b0JFUihzaXplT25seSA9IGZhbHNlKSB7XHJcbiAgICAgICAgbGV0IGZpcnN0T2N0ZXQgPSAwO1xyXG4gICAgICAgIHN3aXRjaCAodGhpcy50YWdDbGFzcykge1xyXG4gICAgICAgICAgICBjYXNlIDE6XHJcbiAgICAgICAgICAgICAgICBmaXJzdE9jdGV0IHw9IDB4MDA7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgY2FzZSAyOlxyXG4gICAgICAgICAgICAgICAgZmlyc3RPY3RldCB8PSAweDQwO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgMzpcclxuICAgICAgICAgICAgICAgIGZpcnN0T2N0ZXQgfD0gMHg4MDtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlIDQ6XHJcbiAgICAgICAgICAgICAgICBmaXJzdE9jdGV0IHw9IDB4QzA7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgIHRoaXMuZXJyb3IgPSBcIlVua25vd24gdGFnIGNsYXNzXCI7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gRU1QVFlfQlVGRkVSO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5pc0NvbnN0cnVjdGVkKVxyXG4gICAgICAgICAgICBmaXJzdE9jdGV0IHw9IDB4MjA7XHJcbiAgICAgICAgaWYgKHRoaXMudGFnTnVtYmVyIDwgMzEgJiYgIXRoaXMuaXNIZXhPbmx5KSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHJldFZpZXcgPSBuZXcgVWludDhBcnJheSgxKTtcclxuICAgICAgICAgICAgaWYgKCFzaXplT25seSkge1xyXG4gICAgICAgICAgICAgICAgbGV0IG51bWJlciA9IHRoaXMudGFnTnVtYmVyO1xyXG4gICAgICAgICAgICAgICAgbnVtYmVyICY9IDB4MUY7XHJcbiAgICAgICAgICAgICAgICBmaXJzdE9jdGV0IHw9IG51bWJlcjtcclxuICAgICAgICAgICAgICAgIHJldFZpZXdbMF0gPSBmaXJzdE9jdGV0O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiByZXRWaWV3LmJ1ZmZlcjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCF0aGlzLmlzSGV4T25seSkge1xyXG4gICAgICAgICAgICBjb25zdCBlbmNvZGVkQnVmID0gcHZ1dGlscy51dGlsVG9CYXNlKHRoaXMudGFnTnVtYmVyLCA3KTtcclxuICAgICAgICAgICAgY29uc3QgZW5jb2RlZFZpZXcgPSBuZXcgVWludDhBcnJheShlbmNvZGVkQnVmKTtcclxuICAgICAgICAgICAgY29uc3Qgc2l6ZSA9IGVuY29kZWRCdWYuYnl0ZUxlbmd0aDtcclxuICAgICAgICAgICAgY29uc3QgcmV0VmlldyA9IG5ldyBVaW50OEFycmF5KHNpemUgKyAxKTtcclxuICAgICAgICAgICAgcmV0Vmlld1swXSA9IChmaXJzdE9jdGV0IHwgMHgxRik7XHJcbiAgICAgICAgICAgIGlmICghc2l6ZU9ubHkpIHtcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgKHNpemUgLSAxKTsgaSsrKVxyXG4gICAgICAgICAgICAgICAgICAgIHJldFZpZXdbaSArIDFdID0gZW5jb2RlZFZpZXdbaV0gfCAweDgwO1xyXG4gICAgICAgICAgICAgICAgcmV0Vmlld1tzaXplXSA9IGVuY29kZWRWaWV3W3NpemUgLSAxXTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gcmV0Vmlldy5idWZmZXI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IHJldFZpZXcgPSBuZXcgVWludDhBcnJheSh0aGlzLnZhbHVlSGV4Vmlldy5ieXRlTGVuZ3RoICsgMSk7XHJcbiAgICAgICAgcmV0Vmlld1swXSA9IChmaXJzdE9jdGV0IHwgMHgxRik7XHJcbiAgICAgICAgaWYgKCFzaXplT25seSkge1xyXG4gICAgICAgICAgICBjb25zdCBjdXJWaWV3ID0gdGhpcy52YWx1ZUhleFZpZXc7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgKGN1clZpZXcubGVuZ3RoIC0gMSk7IGkrKylcclxuICAgICAgICAgICAgICAgIHJldFZpZXdbaSArIDFdID0gY3VyVmlld1tpXSB8IDB4ODA7XHJcbiAgICAgICAgICAgIHJldFZpZXdbdGhpcy52YWx1ZUhleFZpZXcuYnl0ZUxlbmd0aF0gPSBjdXJWaWV3W2N1clZpZXcubGVuZ3RoIC0gMV07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiByZXRWaWV3LmJ1ZmZlcjtcclxuICAgIH1cclxuICAgIGZyb21CRVIoaW5wdXRCdWZmZXIsIGlucHV0T2Zmc2V0LCBpbnB1dExlbmd0aCkge1xyXG4gICAgICAgIGNvbnN0IGlucHV0VmlldyA9IHB2dHN1dGlscy5CdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9VaW50OEFycmF5KGlucHV0QnVmZmVyKTtcclxuICAgICAgICBpZiAoIWNoZWNrQnVmZmVyUGFyYW1zKHRoaXMsIGlucHV0VmlldywgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gLTE7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IGludEJ1ZmZlciA9IGlucHV0Vmlldy5zdWJhcnJheShpbnB1dE9mZnNldCwgaW5wdXRPZmZzZXQgKyBpbnB1dExlbmd0aCk7XHJcbiAgICAgICAgaWYgKGludEJ1ZmZlci5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgdGhpcy5lcnJvciA9IFwiWmVybyBidWZmZXIgbGVuZ3RoXCI7XHJcbiAgICAgICAgICAgIHJldHVybiAtMTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgdGFnQ2xhc3NNYXNrID0gaW50QnVmZmVyWzBdICYgMHhDMDtcclxuICAgICAgICBzd2l0Y2ggKHRhZ0NsYXNzTWFzaykge1xyXG4gICAgICAgICAgICBjYXNlIDB4MDA6XHJcbiAgICAgICAgICAgICAgICB0aGlzLnRhZ0NsYXNzID0gKDEpO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgMHg0MDpcclxuICAgICAgICAgICAgICAgIHRoaXMudGFnQ2xhc3MgPSAoMik7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgY2FzZSAweDgwOlxyXG4gICAgICAgICAgICAgICAgdGhpcy50YWdDbGFzcyA9ICgzKTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlIDB4QzA6XHJcbiAgICAgICAgICAgICAgICB0aGlzLnRhZ0NsYXNzID0gKDQpO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9yID0gXCJVbmtub3duIHRhZyBjbGFzc1wiO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIC0xO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmlzQ29uc3RydWN0ZWQgPSAoaW50QnVmZmVyWzBdICYgMHgyMCkgPT09IDB4MjA7XHJcbiAgICAgICAgdGhpcy5pc0hleE9ubHkgPSBmYWxzZTtcclxuICAgICAgICBjb25zdCB0YWdOdW1iZXJNYXNrID0gaW50QnVmZmVyWzBdICYgMHgxRjtcclxuICAgICAgICBpZiAodGFnTnVtYmVyTWFzayAhPT0gMHgxRikge1xyXG4gICAgICAgICAgICB0aGlzLnRhZ051bWJlciA9ICh0YWdOdW1iZXJNYXNrKTtcclxuICAgICAgICAgICAgdGhpcy5ibG9ja0xlbmd0aCA9IDE7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBsZXQgY291bnQgPSAxO1xyXG4gICAgICAgICAgICBsZXQgaW50VGFnTnVtYmVyQnVmZmVyID0gdGhpcy52YWx1ZUhleFZpZXcgPSBuZXcgVWludDhBcnJheSgyNTUpO1xyXG4gICAgICAgICAgICBsZXQgdGFnTnVtYmVyQnVmZmVyTWF4TGVuZ3RoID0gMjU1O1xyXG4gICAgICAgICAgICB3aGlsZSAoaW50QnVmZmVyW2NvdW50XSAmIDB4ODApIHtcclxuICAgICAgICAgICAgICAgIGludFRhZ051bWJlckJ1ZmZlcltjb3VudCAtIDFdID0gaW50QnVmZmVyW2NvdW50XSAmIDB4N0Y7XHJcbiAgICAgICAgICAgICAgICBjb3VudCsrO1xyXG4gICAgICAgICAgICAgICAgaWYgKGNvdW50ID49IGludEJ1ZmZlci5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmVycm9yID0gXCJFbmQgb2YgaW5wdXQgcmVhY2hlZCBiZWZvcmUgbWVzc2FnZSB3YXMgZnVsbHkgZGVjb2RlZFwiO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChjb3VudCA9PT0gdGFnTnVtYmVyQnVmZmVyTWF4TGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGFnTnVtYmVyQnVmZmVyTWF4TGVuZ3RoICs9IDI1NTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCB0ZW1wQnVmZmVyVmlldyA9IG5ldyBVaW50OEFycmF5KHRhZ051bWJlckJ1ZmZlck1heExlbmd0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbnRUYWdOdW1iZXJCdWZmZXIubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBCdWZmZXJWaWV3W2ldID0gaW50VGFnTnVtYmVyQnVmZmVyW2ldO1xyXG4gICAgICAgICAgICAgICAgICAgIGludFRhZ051bWJlckJ1ZmZlciA9IHRoaXMudmFsdWVIZXhWaWV3ID0gbmV3IFVpbnQ4QXJyYXkodGFnTnVtYmVyQnVmZmVyTWF4TGVuZ3RoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aGlzLmJsb2NrTGVuZ3RoID0gKGNvdW50ICsgMSk7XHJcbiAgICAgICAgICAgIGludFRhZ051bWJlckJ1ZmZlcltjb3VudCAtIDFdID0gaW50QnVmZmVyW2NvdW50XSAmIDB4N0Y7XHJcbiAgICAgICAgICAgIGNvbnN0IHRlbXBCdWZmZXJWaWV3ID0gbmV3IFVpbnQ4QXJyYXkoY291bnQpO1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvdW50OyBpKyspXHJcbiAgICAgICAgICAgICAgICB0ZW1wQnVmZmVyVmlld1tpXSA9IGludFRhZ051bWJlckJ1ZmZlcltpXTtcclxuICAgICAgICAgICAgaW50VGFnTnVtYmVyQnVmZmVyID0gdGhpcy52YWx1ZUhleFZpZXcgPSBuZXcgVWludDhBcnJheShjb3VudCk7XHJcbiAgICAgICAgICAgIGludFRhZ051bWJlckJ1ZmZlci5zZXQodGVtcEJ1ZmZlclZpZXcpO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5ibG9ja0xlbmd0aCA8PSA5KVxyXG4gICAgICAgICAgICAgICAgdGhpcy50YWdOdW1iZXIgPSBwdnV0aWxzLnV0aWxGcm9tQmFzZShpbnRUYWdOdW1iZXJCdWZmZXIsIDcpO1xyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuaXNIZXhPbmx5ID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIHRoaXMud2FybmluZ3MucHVzaChcIlRhZyB0b28gbG9uZywgcmVwcmVzZW50ZWQgYXMgaGV4LWNvZGVkXCIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICgoKHRoaXMudGFnQ2xhc3MgPT09IDEpKSAmJlxyXG4gICAgICAgICAgICAodGhpcy5pc0NvbnN0cnVjdGVkKSkge1xyXG4gICAgICAgICAgICBzd2l0Y2ggKHRoaXMudGFnTnVtYmVyKSB7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDE6XHJcbiAgICAgICAgICAgICAgICBjYXNlIDI6XHJcbiAgICAgICAgICAgICAgICBjYXNlIDU6XHJcbiAgICAgICAgICAgICAgICBjYXNlIDY6XHJcbiAgICAgICAgICAgICAgICBjYXNlIDk6XHJcbiAgICAgICAgICAgICAgICBjYXNlIDEzOlxyXG4gICAgICAgICAgICAgICAgY2FzZSAxNDpcclxuICAgICAgICAgICAgICAgIGNhc2UgMjM6XHJcbiAgICAgICAgICAgICAgICBjYXNlIDI0OlxyXG4gICAgICAgICAgICAgICAgY2FzZSAzMTpcclxuICAgICAgICAgICAgICAgIGNhc2UgMzI6XHJcbiAgICAgICAgICAgICAgICBjYXNlIDMzOlxyXG4gICAgICAgICAgICAgICAgY2FzZSAzNDpcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmVycm9yID0gXCJDb25zdHJ1Y3RlZCBlbmNvZGluZyB1c2VkIGZvciBwcmltaXRpdmUgdHlwZVwiO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gKGlucHV0T2Zmc2V0ICsgdGhpcy5ibG9ja0xlbmd0aCk7XHJcbiAgICB9XHJcbiAgICB0b0pTT04oKSB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgLi4uc3VwZXIudG9KU09OKCksXHJcbiAgICAgICAgICAgIHRhZ0NsYXNzOiB0aGlzLnRhZ0NsYXNzLFxyXG4gICAgICAgICAgICB0YWdOdW1iZXI6IHRoaXMudGFnTnVtYmVyLFxyXG4gICAgICAgICAgICBpc0NvbnN0cnVjdGVkOiB0aGlzLmlzQ29uc3RydWN0ZWQsXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxufVxyXG5Mb2NhbElkZW50aWZpY2F0aW9uQmxvY2suTkFNRSA9IFwiaWRlbnRpZmljYXRpb25CbG9ja1wiO1xuXG5jbGFzcyBMb2NhbExlbmd0aEJsb2NrIGV4dGVuZHMgTG9jYWxCYXNlQmxvY2sge1xyXG4gICAgY29uc3RydWN0b3IoeyBsZW5CbG9jayA9IHt9LCB9ID0ge30pIHtcclxuICAgICAgICB2YXIgX2EsIF9iLCBfYztcclxuICAgICAgICBzdXBlcigpO1xyXG4gICAgICAgIHRoaXMuaXNJbmRlZmluaXRlRm9ybSA9IChfYSA9IGxlbkJsb2NrLmlzSW5kZWZpbml0ZUZvcm0pICE9PSBudWxsICYmIF9hICE9PSB2b2lkIDAgPyBfYSA6IGZhbHNlO1xyXG4gICAgICAgIHRoaXMubG9uZ0Zvcm1Vc2VkID0gKF9iID0gbGVuQmxvY2subG9uZ0Zvcm1Vc2VkKSAhPT0gbnVsbCAmJiBfYiAhPT0gdm9pZCAwID8gX2IgOiBmYWxzZTtcclxuICAgICAgICB0aGlzLmxlbmd0aCA9IChfYyA9IGxlbkJsb2NrLmxlbmd0aCkgIT09IG51bGwgJiYgX2MgIT09IHZvaWQgMCA/IF9jIDogMDtcclxuICAgIH1cclxuICAgIGZyb21CRVIoaW5wdXRCdWZmZXIsIGlucHV0T2Zmc2V0LCBpbnB1dExlbmd0aCkge1xyXG4gICAgICAgIGNvbnN0IHZpZXcgPSBwdnRzdXRpbHMuQnVmZmVyU291cmNlQ29udmVydGVyLnRvVWludDhBcnJheShpbnB1dEJ1ZmZlcik7XHJcbiAgICAgICAgaWYgKCFjaGVja0J1ZmZlclBhcmFtcyh0aGlzLCB2aWV3LCBpbnB1dE9mZnNldCwgaW5wdXRMZW5ndGgpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiAtMTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgaW50QnVmZmVyID0gdmlldy5zdWJhcnJheShpbnB1dE9mZnNldCwgaW5wdXRPZmZzZXQgKyBpbnB1dExlbmd0aCk7XHJcbiAgICAgICAgaWYgKGludEJ1ZmZlci5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgdGhpcy5lcnJvciA9IFwiWmVybyBidWZmZXIgbGVuZ3RoXCI7XHJcbiAgICAgICAgICAgIHJldHVybiAtMTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGludEJ1ZmZlclswXSA9PT0gMHhGRikge1xyXG4gICAgICAgICAgICB0aGlzLmVycm9yID0gXCJMZW5ndGggYmxvY2sgMHhGRiBpcyByZXNlcnZlZCBieSBzdGFuZGFyZFwiO1xyXG4gICAgICAgICAgICByZXR1cm4gLTE7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuaXNJbmRlZmluaXRlRm9ybSA9IGludEJ1ZmZlclswXSA9PT0gMHg4MDtcclxuICAgICAgICBpZiAodGhpcy5pc0luZGVmaW5pdGVGb3JtKSB7XHJcbiAgICAgICAgICAgIHRoaXMuYmxvY2tMZW5ndGggPSAxO1xyXG4gICAgICAgICAgICByZXR1cm4gKGlucHV0T2Zmc2V0ICsgdGhpcy5ibG9ja0xlbmd0aCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMubG9uZ0Zvcm1Vc2VkID0gISEoaW50QnVmZmVyWzBdICYgMHg4MCk7XHJcbiAgICAgICAgaWYgKHRoaXMubG9uZ0Zvcm1Vc2VkID09PSBmYWxzZSkge1xyXG4gICAgICAgICAgICB0aGlzLmxlbmd0aCA9IChpbnRCdWZmZXJbMF0pO1xyXG4gICAgICAgICAgICB0aGlzLmJsb2NrTGVuZ3RoID0gMTtcclxuICAgICAgICAgICAgcmV0dXJuIChpbnB1dE9mZnNldCArIHRoaXMuYmxvY2tMZW5ndGgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBjb3VudCA9IGludEJ1ZmZlclswXSAmIDB4N0Y7XHJcbiAgICAgICAgaWYgKGNvdW50ID4gOCkge1xyXG4gICAgICAgICAgICB0aGlzLmVycm9yID0gXCJUb28gYmlnIGludGVnZXJcIjtcclxuICAgICAgICAgICAgcmV0dXJuIC0xO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoKGNvdW50ICsgMSkgPiBpbnRCdWZmZXIubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZXJyb3IgPSBcIkVuZCBvZiBpbnB1dCByZWFjaGVkIGJlZm9yZSBtZXNzYWdlIHdhcyBmdWxseSBkZWNvZGVkXCI7XHJcbiAgICAgICAgICAgIHJldHVybiAtMTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgbGVuT2Zmc2V0ID0gaW5wdXRPZmZzZXQgKyAxO1xyXG4gICAgICAgIGNvbnN0IGxlbmd0aEJ1ZmZlclZpZXcgPSB2aWV3LnN1YmFycmF5KGxlbk9mZnNldCwgbGVuT2Zmc2V0ICsgY291bnQpO1xyXG4gICAgICAgIGlmIChsZW5ndGhCdWZmZXJWaWV3W2NvdW50IC0gMV0gPT09IDB4MDApXHJcbiAgICAgICAgICAgIHRoaXMud2FybmluZ3MucHVzaChcIk5lZWRsZXNzbHkgbG9uZyBlbmNvZGVkIGxlbmd0aFwiKTtcclxuICAgICAgICB0aGlzLmxlbmd0aCA9IHB2dXRpbHMudXRpbEZyb21CYXNlKGxlbmd0aEJ1ZmZlclZpZXcsIDgpO1xyXG4gICAgICAgIGlmICh0aGlzLmxvbmdGb3JtVXNlZCAmJiAodGhpcy5sZW5ndGggPD0gMTI3KSlcclxuICAgICAgICAgICAgdGhpcy53YXJuaW5ncy5wdXNoKFwiVW5uZWNlc3NhcnkgdXNhZ2Ugb2YgbG9uZyBsZW5ndGggZm9ybVwiKTtcclxuICAgICAgICB0aGlzLmJsb2NrTGVuZ3RoID0gY291bnQgKyAxO1xyXG4gICAgICAgIHJldHVybiAoaW5wdXRPZmZzZXQgKyB0aGlzLmJsb2NrTGVuZ3RoKTtcclxuICAgIH1cclxuICAgIHRvQkVSKHNpemVPbmx5ID0gZmFsc2UpIHtcclxuICAgICAgICBsZXQgcmV0QnVmO1xyXG4gICAgICAgIGxldCByZXRWaWV3O1xyXG4gICAgICAgIGlmICh0aGlzLmxlbmd0aCA+IDEyNylcclxuICAgICAgICAgICAgdGhpcy5sb25nRm9ybVVzZWQgPSB0cnVlO1xyXG4gICAgICAgIGlmICh0aGlzLmlzSW5kZWZpbml0ZUZvcm0pIHtcclxuICAgICAgICAgICAgcmV0QnVmID0gbmV3IEFycmF5QnVmZmVyKDEpO1xyXG4gICAgICAgICAgICBpZiAoc2l6ZU9ubHkgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgICAgICByZXRWaWV3ID0gbmV3IFVpbnQ4QXJyYXkocmV0QnVmKTtcclxuICAgICAgICAgICAgICAgIHJldFZpZXdbMF0gPSAweDgwO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiByZXRCdWY7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLmxvbmdGb3JtVXNlZCkge1xyXG4gICAgICAgICAgICBjb25zdCBlbmNvZGVkQnVmID0gcHZ1dGlscy51dGlsVG9CYXNlKHRoaXMubGVuZ3RoLCA4KTtcclxuICAgICAgICAgICAgaWYgKGVuY29kZWRCdWYuYnl0ZUxlbmd0aCA+IDEyNykge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5lcnJvciA9IFwiVG9vIGJpZyBsZW5ndGhcIjtcclxuICAgICAgICAgICAgICAgIHJldHVybiAoRU1QVFlfQlVGRkVSKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXRCdWYgPSBuZXcgQXJyYXlCdWZmZXIoZW5jb2RlZEJ1Zi5ieXRlTGVuZ3RoICsgMSk7XHJcbiAgICAgICAgICAgIGlmIChzaXplT25seSlcclxuICAgICAgICAgICAgICAgIHJldHVybiByZXRCdWY7XHJcbiAgICAgICAgICAgIGNvbnN0IGVuY29kZWRWaWV3ID0gbmV3IFVpbnQ4QXJyYXkoZW5jb2RlZEJ1Zik7XHJcbiAgICAgICAgICAgIHJldFZpZXcgPSBuZXcgVWludDhBcnJheShyZXRCdWYpO1xyXG4gICAgICAgICAgICByZXRWaWV3WzBdID0gZW5jb2RlZEJ1Zi5ieXRlTGVuZ3RoIHwgMHg4MDtcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBlbmNvZGVkQnVmLmJ5dGVMZW5ndGg7IGkrKylcclxuICAgICAgICAgICAgICAgIHJldFZpZXdbaSArIDFdID0gZW5jb2RlZFZpZXdbaV07XHJcbiAgICAgICAgICAgIHJldHVybiByZXRCdWY7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldEJ1ZiA9IG5ldyBBcnJheUJ1ZmZlcigxKTtcclxuICAgICAgICBpZiAoc2l6ZU9ubHkgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgIHJldFZpZXcgPSBuZXcgVWludDhBcnJheShyZXRCdWYpO1xyXG4gICAgICAgICAgICByZXRWaWV3WzBdID0gdGhpcy5sZW5ndGg7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiByZXRCdWY7XHJcbiAgICB9XHJcbiAgICB0b0pTT04oKSB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgLi4uc3VwZXIudG9KU09OKCksXHJcbiAgICAgICAgICAgIGlzSW5kZWZpbml0ZUZvcm06IHRoaXMuaXNJbmRlZmluaXRlRm9ybSxcclxuICAgICAgICAgICAgbG9uZ0Zvcm1Vc2VkOiB0aGlzLmxvbmdGb3JtVXNlZCxcclxuICAgICAgICAgICAgbGVuZ3RoOiB0aGlzLmxlbmd0aCxcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG59XHJcbkxvY2FsTGVuZ3RoQmxvY2suTkFNRSA9IFwibGVuZ3RoQmxvY2tcIjtcblxuY29uc3QgdHlwZVN0b3JlID0ge307XG5cbmNsYXNzIEJhc2VCbG9jayBleHRlbmRzIExvY2FsQmFzZUJsb2NrIHtcclxuICAgIGNvbnN0cnVjdG9yKHsgbmFtZSA9IEVNUFRZX1NUUklORywgb3B0aW9uYWwgPSBmYWxzZSwgcHJpbWl0aXZlU2NoZW1hLCAuLi5wYXJhbWV0ZXJzIH0gPSB7fSwgdmFsdWVCbG9ja1R5cGUpIHtcclxuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcclxuICAgICAgICB0aGlzLm5hbWUgPSBuYW1lO1xyXG4gICAgICAgIHRoaXMub3B0aW9uYWwgPSBvcHRpb25hbDtcclxuICAgICAgICBpZiAocHJpbWl0aXZlU2NoZW1hKSB7XHJcbiAgICAgICAgICAgIHRoaXMucHJpbWl0aXZlU2NoZW1hID0gcHJpbWl0aXZlU2NoZW1hO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmlkQmxvY2sgPSBuZXcgTG9jYWxJZGVudGlmaWNhdGlvbkJsb2NrKHBhcmFtZXRlcnMpO1xyXG4gICAgICAgIHRoaXMubGVuQmxvY2sgPSBuZXcgTG9jYWxMZW5ndGhCbG9jayhwYXJhbWV0ZXJzKTtcclxuICAgICAgICB0aGlzLnZhbHVlQmxvY2sgPSB2YWx1ZUJsb2NrVHlwZSA/IG5ldyB2YWx1ZUJsb2NrVHlwZShwYXJhbWV0ZXJzKSA6IG5ldyBWYWx1ZUJsb2NrKHBhcmFtZXRlcnMpO1xyXG4gICAgfVxyXG4gICAgZnJvbUJFUihpbnB1dEJ1ZmZlciwgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoKSB7XHJcbiAgICAgICAgY29uc3QgcmVzdWx0T2Zmc2V0ID0gdGhpcy52YWx1ZUJsb2NrLmZyb21CRVIoaW5wdXRCdWZmZXIsIGlucHV0T2Zmc2V0LCAodGhpcy5sZW5CbG9jay5pc0luZGVmaW5pdGVGb3JtKSA/IGlucHV0TGVuZ3RoIDogdGhpcy5sZW5CbG9jay5sZW5ndGgpO1xyXG4gICAgICAgIGlmIChyZXN1bHRPZmZzZXQgPT09IC0xKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZXJyb3IgPSB0aGlzLnZhbHVlQmxvY2suZXJyb3I7XHJcbiAgICAgICAgICAgIHJldHVybiByZXN1bHRPZmZzZXQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghdGhpcy5pZEJsb2NrLmVycm9yLmxlbmd0aClcclxuICAgICAgICAgICAgdGhpcy5ibG9ja0xlbmd0aCArPSB0aGlzLmlkQmxvY2suYmxvY2tMZW5ndGg7XHJcbiAgICAgICAgaWYgKCF0aGlzLmxlbkJsb2NrLmVycm9yLmxlbmd0aClcclxuICAgICAgICAgICAgdGhpcy5ibG9ja0xlbmd0aCArPSB0aGlzLmxlbkJsb2NrLmJsb2NrTGVuZ3RoO1xyXG4gICAgICAgIGlmICghdGhpcy52YWx1ZUJsb2NrLmVycm9yLmxlbmd0aClcclxuICAgICAgICAgICAgdGhpcy5ibG9ja0xlbmd0aCArPSB0aGlzLnZhbHVlQmxvY2suYmxvY2tMZW5ndGg7XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdE9mZnNldDtcclxuICAgIH1cclxuICAgIHRvQkVSKHNpemVPbmx5LCB3cml0ZXIpIHtcclxuICAgICAgICBjb25zdCBfd3JpdGVyID0gd3JpdGVyIHx8IG5ldyBWaWV3V3JpdGVyKCk7XHJcbiAgICAgICAgaWYgKCF3cml0ZXIpIHtcclxuICAgICAgICAgICAgcHJlcGFyZUluZGVmaW5pdGVGb3JtKHRoaXMpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBpZEJsb2NrQnVmID0gdGhpcy5pZEJsb2NrLnRvQkVSKHNpemVPbmx5KTtcclxuICAgICAgICBfd3JpdGVyLndyaXRlKGlkQmxvY2tCdWYpO1xyXG4gICAgICAgIGlmICh0aGlzLmxlbkJsb2NrLmlzSW5kZWZpbml0ZUZvcm0pIHtcclxuICAgICAgICAgICAgX3dyaXRlci53cml0ZShuZXcgVWludDhBcnJheShbMHg4MF0pLmJ1ZmZlcik7XHJcbiAgICAgICAgICAgIHRoaXMudmFsdWVCbG9jay50b0JFUihzaXplT25seSwgX3dyaXRlcik7XHJcbiAgICAgICAgICAgIF93cml0ZXIud3JpdGUobmV3IEFycmF5QnVmZmVyKDIpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlQmxvY2tCdWYgPSB0aGlzLnZhbHVlQmxvY2sudG9CRVIoc2l6ZU9ubHkpO1xyXG4gICAgICAgICAgICB0aGlzLmxlbkJsb2NrLmxlbmd0aCA9IHZhbHVlQmxvY2tCdWYuYnl0ZUxlbmd0aDtcclxuICAgICAgICAgICAgY29uc3QgbGVuQmxvY2tCdWYgPSB0aGlzLmxlbkJsb2NrLnRvQkVSKHNpemVPbmx5KTtcclxuICAgICAgICAgICAgX3dyaXRlci53cml0ZShsZW5CbG9ja0J1Zik7XHJcbiAgICAgICAgICAgIF93cml0ZXIud3JpdGUodmFsdWVCbG9ja0J1Zik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghd3JpdGVyKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBfd3JpdGVyLmZpbmFsKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBFTVBUWV9CVUZGRVI7XHJcbiAgICB9XHJcbiAgICB0b0pTT04oKSB7XHJcbiAgICAgICAgY29uc3Qgb2JqZWN0ID0ge1xyXG4gICAgICAgICAgICAuLi5zdXBlci50b0pTT04oKSxcclxuICAgICAgICAgICAgaWRCbG9jazogdGhpcy5pZEJsb2NrLnRvSlNPTigpLFxyXG4gICAgICAgICAgICBsZW5CbG9jazogdGhpcy5sZW5CbG9jay50b0pTT04oKSxcclxuICAgICAgICAgICAgdmFsdWVCbG9jazogdGhpcy52YWx1ZUJsb2NrLnRvSlNPTigpLFxyXG4gICAgICAgICAgICBuYW1lOiB0aGlzLm5hbWUsXHJcbiAgICAgICAgICAgIG9wdGlvbmFsOiB0aGlzLm9wdGlvbmFsLFxyXG4gICAgICAgIH07XHJcbiAgICAgICAgaWYgKHRoaXMucHJpbWl0aXZlU2NoZW1hKVxyXG4gICAgICAgICAgICBvYmplY3QucHJpbWl0aXZlU2NoZW1hID0gdGhpcy5wcmltaXRpdmVTY2hlbWEudG9KU09OKCk7XHJcbiAgICAgICAgcmV0dXJuIG9iamVjdDtcclxuICAgIH1cclxuICAgIHRvU3RyaW5nKGVuY29kaW5nID0gXCJhc2NpaVwiKSB7XHJcbiAgICAgICAgaWYgKGVuY29kaW5nID09PSBcImFzY2lpXCIpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMub25Bc2NpaUVuY29kaW5nKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBwdnRzdXRpbHMuQ29udmVydC5Ub0hleCh0aGlzLnRvQkVSKCkpO1xyXG4gICAgfVxyXG4gICAgb25Bc2NpaUVuY29kaW5nKCkge1xyXG4gICAgICAgIHJldHVybiBgJHt0aGlzLmNvbnN0cnVjdG9yLk5BTUV9IDogJHtwdnRzdXRpbHMuQ29udmVydC5Ub0hleCh0aGlzLnZhbHVlQmxvY2sudmFsdWVCZWZvcmVEZWNvZGVWaWV3KX1gO1xyXG4gICAgfVxyXG4gICAgaXNFcXVhbChvdGhlcikge1xyXG4gICAgICAgIGlmICh0aGlzID09PSBvdGhlcikge1xyXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiB0aGlzLmNvbnN0cnVjdG9yKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IHRoaXNSYXcgPSB0aGlzLnRvQkVSKCk7XHJcbiAgICAgICAgY29uc3Qgb3RoZXJSYXcgPSBvdGhlci50b0JFUigpO1xyXG4gICAgICAgIHJldHVybiBwdnV0aWxzLmlzRXF1YWxCdWZmZXIodGhpc1Jhdywgb3RoZXJSYXcpO1xyXG4gICAgfVxyXG59XHJcbkJhc2VCbG9jay5OQU1FID0gXCJCYXNlQmxvY2tcIjtcclxuZnVuY3Rpb24gcHJlcGFyZUluZGVmaW5pdGVGb3JtKGJhc2VCbG9jaykge1xyXG4gICAgaWYgKGJhc2VCbG9jayBpbnN0YW5jZW9mIHR5cGVTdG9yZS5Db25zdHJ1Y3RlZCkge1xyXG4gICAgICAgIGZvciAoY29uc3QgdmFsdWUgb2YgYmFzZUJsb2NrLnZhbHVlQmxvY2sudmFsdWUpIHtcclxuICAgICAgICAgICAgaWYgKHByZXBhcmVJbmRlZmluaXRlRm9ybSh2YWx1ZSkpIHtcclxuICAgICAgICAgICAgICAgIGJhc2VCbG9jay5sZW5CbG9jay5pc0luZGVmaW5pdGVGb3JtID0gdHJ1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiAhIWJhc2VCbG9jay5sZW5CbG9jay5pc0luZGVmaW5pdGVGb3JtO1xyXG59XG5cbmNsYXNzIEJhc2VTdHJpbmdCbG9jayBleHRlbmRzIEJhc2VCbG9jayB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7IHZhbHVlID0gRU1QVFlfU1RSSU5HLCAuLi5wYXJhbWV0ZXJzIH0gPSB7fSwgc3RyaW5nVmFsdWVCbG9ja1R5cGUpIHtcclxuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzLCBzdHJpbmdWYWx1ZUJsb2NrVHlwZSk7XHJcbiAgICAgICAgaWYgKHZhbHVlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZnJvbVN0cmluZyh2YWx1ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZ2V0VmFsdWUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWVCbG9jay52YWx1ZTtcclxuICAgIH1cclxuICAgIHNldFZhbHVlKHZhbHVlKSB7XHJcbiAgICAgICAgdGhpcy52YWx1ZUJsb2NrLnZhbHVlID0gdmFsdWU7XHJcbiAgICB9XHJcbiAgICBmcm9tQkVSKGlucHV0QnVmZmVyLCBpbnB1dE9mZnNldCwgaW5wdXRMZW5ndGgpIHtcclxuICAgICAgICBjb25zdCByZXN1bHRPZmZzZXQgPSB0aGlzLnZhbHVlQmxvY2suZnJvbUJFUihpbnB1dEJ1ZmZlciwgaW5wdXRPZmZzZXQsICh0aGlzLmxlbkJsb2NrLmlzSW5kZWZpbml0ZUZvcm0pID8gaW5wdXRMZW5ndGggOiB0aGlzLmxlbkJsb2NrLmxlbmd0aCk7XHJcbiAgICAgICAgaWYgKHJlc3VsdE9mZnNldCA9PT0gLTEpIHtcclxuICAgICAgICAgICAgdGhpcy5lcnJvciA9IHRoaXMudmFsdWVCbG9jay5lcnJvcjtcclxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdE9mZnNldDtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5mcm9tQnVmZmVyKHRoaXMudmFsdWVCbG9jay52YWx1ZUhleFZpZXcpO1xyXG4gICAgICAgIGlmICghdGhpcy5pZEJsb2NrLmVycm9yLmxlbmd0aClcclxuICAgICAgICAgICAgdGhpcy5ibG9ja0xlbmd0aCArPSB0aGlzLmlkQmxvY2suYmxvY2tMZW5ndGg7XHJcbiAgICAgICAgaWYgKCF0aGlzLmxlbkJsb2NrLmVycm9yLmxlbmd0aClcclxuICAgICAgICAgICAgdGhpcy5ibG9ja0xlbmd0aCArPSB0aGlzLmxlbkJsb2NrLmJsb2NrTGVuZ3RoO1xyXG4gICAgICAgIGlmICghdGhpcy52YWx1ZUJsb2NrLmVycm9yLmxlbmd0aClcclxuICAgICAgICAgICAgdGhpcy5ibG9ja0xlbmd0aCArPSB0aGlzLnZhbHVlQmxvY2suYmxvY2tMZW5ndGg7XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdE9mZnNldDtcclxuICAgIH1cclxuICAgIG9uQXNjaWlFbmNvZGluZygpIHtcclxuICAgICAgICByZXR1cm4gYCR7dGhpcy5jb25zdHJ1Y3Rvci5OQU1FfSA6ICcke3RoaXMudmFsdWVCbG9jay52YWx1ZX0nYDtcclxuICAgIH1cclxufVxyXG5CYXNlU3RyaW5nQmxvY2suTkFNRSA9IFwiQmFzZVN0cmluZ0Jsb2NrXCI7XG5cbmNsYXNzIExvY2FsUHJpbWl0aXZlVmFsdWVCbG9jayBleHRlbmRzIEhleEJsb2NrKFZhbHVlQmxvY2spIHtcclxuICAgIGNvbnN0cnVjdG9yKHsgaXNIZXhPbmx5ID0gdHJ1ZSwgLi4ucGFyYW1ldGVycyB9ID0ge30pIHtcclxuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcclxuICAgICAgICB0aGlzLmlzSGV4T25seSA9IGlzSGV4T25seTtcclxuICAgIH1cclxufVxyXG5Mb2NhbFByaW1pdGl2ZVZhbHVlQmxvY2suTkFNRSA9IFwiUHJpbWl0aXZlVmFsdWVCbG9ja1wiO1xuXG52YXIgX2EkdztcclxuY2xhc3MgUHJpbWl0aXZlIGV4dGVuZHMgQmFzZUJsb2NrIHtcclxuICAgIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMgPSB7fSkge1xyXG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMsIExvY2FsUHJpbWl0aXZlVmFsdWVCbG9jayk7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLmlzQ29uc3RydWN0ZWQgPSBmYWxzZTtcclxuICAgIH1cclxufVxyXG5fYSR3ID0gUHJpbWl0aXZlO1xyXG4oKCkgPT4ge1xyXG4gICAgdHlwZVN0b3JlLlByaW1pdGl2ZSA9IF9hJHc7XHJcbn0pKCk7XHJcblByaW1pdGl2ZS5OQU1FID0gXCJQUklNSVRJVkVcIjtcblxuZnVuY3Rpb24gbG9jYWxDaGFuZ2VUeXBlKGlucHV0T2JqZWN0LCBuZXdUeXBlKSB7XHJcbiAgICBpZiAoaW5wdXRPYmplY3QgaW5zdGFuY2VvZiBuZXdUeXBlKSB7XHJcbiAgICAgICAgcmV0dXJuIGlucHV0T2JqZWN0O1xyXG4gICAgfVxyXG4gICAgY29uc3QgbmV3T2JqZWN0ID0gbmV3IG5ld1R5cGUoKTtcclxuICAgIG5ld09iamVjdC5pZEJsb2NrID0gaW5wdXRPYmplY3QuaWRCbG9jaztcclxuICAgIG5ld09iamVjdC5sZW5CbG9jayA9IGlucHV0T2JqZWN0LmxlbkJsb2NrO1xyXG4gICAgbmV3T2JqZWN0Lndhcm5pbmdzID0gaW5wdXRPYmplY3Qud2FybmluZ3M7XHJcbiAgICBuZXdPYmplY3QudmFsdWVCZWZvcmVEZWNvZGVWaWV3ID0gaW5wdXRPYmplY3QudmFsdWVCZWZvcmVEZWNvZGVWaWV3O1xyXG4gICAgcmV0dXJuIG5ld09iamVjdDtcclxufVxyXG5mdW5jdGlvbiBsb2NhbEZyb21CRVIoaW5wdXRCdWZmZXIsIGlucHV0T2Zmc2V0ID0gMCwgaW5wdXRMZW5ndGggPSBpbnB1dEJ1ZmZlci5sZW5ndGgpIHtcclxuICAgIGNvbnN0IGluY29taW5nT2Zmc2V0ID0gaW5wdXRPZmZzZXQ7XHJcbiAgICBsZXQgcmV0dXJuT2JqZWN0ID0gbmV3IEJhc2VCbG9jayh7fSwgVmFsdWVCbG9jayk7XHJcbiAgICBjb25zdCBiYXNlQmxvY2sgPSBuZXcgTG9jYWxCYXNlQmxvY2soKTtcclxuICAgIGlmICghY2hlY2tCdWZmZXJQYXJhbXMoYmFzZUJsb2NrLCBpbnB1dEJ1ZmZlciwgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoKSkge1xyXG4gICAgICAgIHJldHVybk9iamVjdC5lcnJvciA9IGJhc2VCbG9jay5lcnJvcjtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBvZmZzZXQ6IC0xLFxyXG4gICAgICAgICAgICByZXN1bHQ6IHJldHVybk9iamVjdFxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbiAgICBjb25zdCBpbnRCdWZmZXIgPSBpbnB1dEJ1ZmZlci5zdWJhcnJheShpbnB1dE9mZnNldCwgaW5wdXRPZmZzZXQgKyBpbnB1dExlbmd0aCk7XHJcbiAgICBpZiAoIWludEJ1ZmZlci5sZW5ndGgpIHtcclxuICAgICAgICByZXR1cm5PYmplY3QuZXJyb3IgPSBcIlplcm8gYnVmZmVyIGxlbmd0aFwiO1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIG9mZnNldDogLTEsXHJcbiAgICAgICAgICAgIHJlc3VsdDogcmV0dXJuT2JqZWN0XHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuICAgIGxldCByZXN1bHRPZmZzZXQgPSByZXR1cm5PYmplY3QuaWRCbG9jay5mcm9tQkVSKGlucHV0QnVmZmVyLCBpbnB1dE9mZnNldCwgaW5wdXRMZW5ndGgpO1xyXG4gICAgaWYgKHJldHVybk9iamVjdC5pZEJsb2NrLndhcm5pbmdzLmxlbmd0aCkge1xyXG4gICAgICAgIHJldHVybk9iamVjdC53YXJuaW5ncy5jb25jYXQocmV0dXJuT2JqZWN0LmlkQmxvY2sud2FybmluZ3MpO1xyXG4gICAgfVxyXG4gICAgaWYgKHJlc3VsdE9mZnNldCA9PT0gLTEpIHtcclxuICAgICAgICByZXR1cm5PYmplY3QuZXJyb3IgPSByZXR1cm5PYmplY3QuaWRCbG9jay5lcnJvcjtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBvZmZzZXQ6IC0xLFxyXG4gICAgICAgICAgICByZXN1bHQ6IHJldHVybk9iamVjdFxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbiAgICBpbnB1dE9mZnNldCA9IHJlc3VsdE9mZnNldDtcclxuICAgIGlucHV0TGVuZ3RoIC09IHJldHVybk9iamVjdC5pZEJsb2NrLmJsb2NrTGVuZ3RoO1xyXG4gICAgcmVzdWx0T2Zmc2V0ID0gcmV0dXJuT2JqZWN0LmxlbkJsb2NrLmZyb21CRVIoaW5wdXRCdWZmZXIsIGlucHV0T2Zmc2V0LCBpbnB1dExlbmd0aCk7XHJcbiAgICBpZiAocmV0dXJuT2JqZWN0LmxlbkJsb2NrLndhcm5pbmdzLmxlbmd0aCkge1xyXG4gICAgICAgIHJldHVybk9iamVjdC53YXJuaW5ncy5jb25jYXQocmV0dXJuT2JqZWN0LmxlbkJsb2NrLndhcm5pbmdzKTtcclxuICAgIH1cclxuICAgIGlmIChyZXN1bHRPZmZzZXQgPT09IC0xKSB7XHJcbiAgICAgICAgcmV0dXJuT2JqZWN0LmVycm9yID0gcmV0dXJuT2JqZWN0LmxlbkJsb2NrLmVycm9yO1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIG9mZnNldDogLTEsXHJcbiAgICAgICAgICAgIHJlc3VsdDogcmV0dXJuT2JqZWN0XHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuICAgIGlucHV0T2Zmc2V0ID0gcmVzdWx0T2Zmc2V0O1xyXG4gICAgaW5wdXRMZW5ndGggLT0gcmV0dXJuT2JqZWN0LmxlbkJsb2NrLmJsb2NrTGVuZ3RoO1xyXG4gICAgaWYgKCFyZXR1cm5PYmplY3QuaWRCbG9jay5pc0NvbnN0cnVjdGVkICYmXHJcbiAgICAgICAgcmV0dXJuT2JqZWN0LmxlbkJsb2NrLmlzSW5kZWZpbml0ZUZvcm0pIHtcclxuICAgICAgICByZXR1cm5PYmplY3QuZXJyb3IgPSBcIkluZGVmaW5pdGUgbGVuZ3RoIGZvcm0gdXNlZCBmb3IgcHJpbWl0aXZlIGVuY29kaW5nIGZvcm1cIjtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBvZmZzZXQ6IC0xLFxyXG4gICAgICAgICAgICByZXN1bHQ6IHJldHVybk9iamVjdFxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbiAgICBsZXQgbmV3QVNOMVR5cGUgPSBCYXNlQmxvY2s7XHJcbiAgICBzd2l0Y2ggKHJldHVybk9iamVjdC5pZEJsb2NrLnRhZ0NsYXNzKSB7XHJcbiAgICAgICAgY2FzZSAxOlxyXG4gICAgICAgICAgICBpZiAoKHJldHVybk9iamVjdC5pZEJsb2NrLnRhZ051bWJlciA+PSAzNykgJiZcclxuICAgICAgICAgICAgICAgIChyZXR1cm5PYmplY3QuaWRCbG9jay5pc0hleE9ubHkgPT09IGZhbHNlKSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuT2JqZWN0LmVycm9yID0gXCJVTklWRVJTQUwgMzcgYW5kIHVwcGVyIHRhZ3MgYXJlIHJlc2VydmVkIGJ5IEFTTi4xIHN0YW5kYXJkXCI7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgIG9mZnNldDogLTEsXHJcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0OiByZXR1cm5PYmplY3RcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgc3dpdGNoIChyZXR1cm5PYmplY3QuaWRCbG9jay50YWdOdW1iZXIpIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgMDpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoKHJldHVybk9iamVjdC5pZEJsb2NrLmlzQ29uc3RydWN0ZWQpICYmXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIChyZXR1cm5PYmplY3QubGVuQmxvY2subGVuZ3RoID4gMCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuT2JqZWN0LmVycm9yID0gXCJUeXBlIFtVTklWRVJTQUwgMF0gaXMgcmVzZXJ2ZWRcIjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldDogLTEsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQ6IHJldHVybk9iamVjdFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBuZXdBU04xVHlwZSA9IHR5cGVTdG9yZS5FbmRPZkNvbnRlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDE6XHJcbiAgICAgICAgICAgICAgICAgICAgbmV3QVNOMVR5cGUgPSB0eXBlU3RvcmUuQm9vbGVhbjtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgMjpcclxuICAgICAgICAgICAgICAgICAgICBuZXdBU04xVHlwZSA9IHR5cGVTdG9yZS5JbnRlZ2VyO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAzOlxyXG4gICAgICAgICAgICAgICAgICAgIG5ld0FTTjFUeXBlID0gdHlwZVN0b3JlLkJpdFN0cmluZztcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgNDpcclxuICAgICAgICAgICAgICAgICAgICBuZXdBU04xVHlwZSA9IHR5cGVTdG9yZS5PY3RldFN0cmluZztcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgNTpcclxuICAgICAgICAgICAgICAgICAgICBuZXdBU04xVHlwZSA9IHR5cGVTdG9yZS5OdWxsO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA2OlxyXG4gICAgICAgICAgICAgICAgICAgIG5ld0FTTjFUeXBlID0gdHlwZVN0b3JlLk9iamVjdElkZW50aWZpZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDEwOlxyXG4gICAgICAgICAgICAgICAgICAgIG5ld0FTTjFUeXBlID0gdHlwZVN0b3JlLkVudW1lcmF0ZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDEyOlxyXG4gICAgICAgICAgICAgICAgICAgIG5ld0FTTjFUeXBlID0gdHlwZVN0b3JlLlV0ZjhTdHJpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDEzOlxyXG4gICAgICAgICAgICAgICAgICAgIG5ld0FTTjFUeXBlID0gdHlwZVN0b3JlLlJlbGF0aXZlT2JqZWN0SWRlbnRpZmllcjtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgMTQ6XHJcbiAgICAgICAgICAgICAgICAgICAgbmV3QVNOMVR5cGUgPSB0eXBlU3RvcmUuVElNRTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgMTU6XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuT2JqZWN0LmVycm9yID0gXCJbVU5JVkVSU0FMIDE1XSBpcyByZXNlcnZlZCBieSBBU04uMSBzdGFuZGFyZFwiO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldDogLTEsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdDogcmV0dXJuT2JqZWN0XHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIGNhc2UgMTY6XHJcbiAgICAgICAgICAgICAgICAgICAgbmV3QVNOMVR5cGUgPSB0eXBlU3RvcmUuU2VxdWVuY2U7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDE3OlxyXG4gICAgICAgICAgICAgICAgICAgIG5ld0FTTjFUeXBlID0gdHlwZVN0b3JlLlNldDtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgMTg6XHJcbiAgICAgICAgICAgICAgICAgICAgbmV3QVNOMVR5cGUgPSB0eXBlU3RvcmUuTnVtZXJpY1N0cmluZztcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgMTk6XHJcbiAgICAgICAgICAgICAgICAgICAgbmV3QVNOMVR5cGUgPSB0eXBlU3RvcmUuUHJpbnRhYmxlU3RyaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAyMDpcclxuICAgICAgICAgICAgICAgICAgICBuZXdBU04xVHlwZSA9IHR5cGVTdG9yZS5UZWxldGV4U3RyaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAyMTpcclxuICAgICAgICAgICAgICAgICAgICBuZXdBU04xVHlwZSA9IHR5cGVTdG9yZS5WaWRlb3RleFN0cmluZztcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgMjI6XHJcbiAgICAgICAgICAgICAgICAgICAgbmV3QVNOMVR5cGUgPSB0eXBlU3RvcmUuSUE1U3RyaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAyMzpcclxuICAgICAgICAgICAgICAgICAgICBuZXdBU04xVHlwZSA9IHR5cGVTdG9yZS5VVENUaW1lO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAyNDpcclxuICAgICAgICAgICAgICAgICAgICBuZXdBU04xVHlwZSA9IHR5cGVTdG9yZS5HZW5lcmFsaXplZFRpbWU7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDI1OlxyXG4gICAgICAgICAgICAgICAgICAgIG5ld0FTTjFUeXBlID0gdHlwZVN0b3JlLkdyYXBoaWNTdHJpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDI2OlxyXG4gICAgICAgICAgICAgICAgICAgIG5ld0FTTjFUeXBlID0gdHlwZVN0b3JlLlZpc2libGVTdHJpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDI3OlxyXG4gICAgICAgICAgICAgICAgICAgIG5ld0FTTjFUeXBlID0gdHlwZVN0b3JlLkdlbmVyYWxTdHJpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDI4OlxyXG4gICAgICAgICAgICAgICAgICAgIG5ld0FTTjFUeXBlID0gdHlwZVN0b3JlLlVuaXZlcnNhbFN0cmluZztcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgMjk6XHJcbiAgICAgICAgICAgICAgICAgICAgbmV3QVNOMVR5cGUgPSB0eXBlU3RvcmUuQ2hhcmFjdGVyU3RyaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAzMDpcclxuICAgICAgICAgICAgICAgICAgICBuZXdBU04xVHlwZSA9IHR5cGVTdG9yZS5CbXBTdHJpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDMxOlxyXG4gICAgICAgICAgICAgICAgICAgIG5ld0FTTjFUeXBlID0gdHlwZVN0b3JlLkRBVEU7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDMyOlxyXG4gICAgICAgICAgICAgICAgICAgIG5ld0FTTjFUeXBlID0gdHlwZVN0b3JlLlRpbWVPZkRheTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgMzM6XHJcbiAgICAgICAgICAgICAgICAgICAgbmV3QVNOMVR5cGUgPSB0eXBlU3RvcmUuRGF0ZVRpbWU7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDM0OlxyXG4gICAgICAgICAgICAgICAgICAgIG5ld0FTTjFUeXBlID0gdHlwZVN0b3JlLkR1cmF0aW9uO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDoge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld09iamVjdCA9IHJldHVybk9iamVjdC5pZEJsb2NrLmlzQ29uc3RydWN0ZWRcclxuICAgICAgICAgICAgICAgICAgICAgICAgPyBuZXcgdHlwZVN0b3JlLkNvbnN0cnVjdGVkKClcclxuICAgICAgICAgICAgICAgICAgICAgICAgOiBuZXcgdHlwZVN0b3JlLlByaW1pdGl2ZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIG5ld09iamVjdC5pZEJsb2NrID0gcmV0dXJuT2JqZWN0LmlkQmxvY2s7XHJcbiAgICAgICAgICAgICAgICAgICAgbmV3T2JqZWN0LmxlbkJsb2NrID0gcmV0dXJuT2JqZWN0LmxlbkJsb2NrO1xyXG4gICAgICAgICAgICAgICAgICAgIG5ld09iamVjdC53YXJuaW5ncyA9IHJldHVybk9iamVjdC53YXJuaW5ncztcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm5PYmplY3QgPSBuZXdPYmplY3Q7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgY2FzZSAyOlxyXG4gICAgICAgIGNhc2UgMzpcclxuICAgICAgICBjYXNlIDQ6XHJcbiAgICAgICAgZGVmYXVsdDoge1xyXG4gICAgICAgICAgICBuZXdBU04xVHlwZSA9IHJldHVybk9iamVjdC5pZEJsb2NrLmlzQ29uc3RydWN0ZWRcclxuICAgICAgICAgICAgICAgID8gdHlwZVN0b3JlLkNvbnN0cnVjdGVkXHJcbiAgICAgICAgICAgICAgICA6IHR5cGVTdG9yZS5QcmltaXRpdmU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuT2JqZWN0ID0gbG9jYWxDaGFuZ2VUeXBlKHJldHVybk9iamVjdCwgbmV3QVNOMVR5cGUpO1xyXG4gICAgcmVzdWx0T2Zmc2V0ID0gcmV0dXJuT2JqZWN0LmZyb21CRVIoaW5wdXRCdWZmZXIsIGlucHV0T2Zmc2V0LCByZXR1cm5PYmplY3QubGVuQmxvY2suaXNJbmRlZmluaXRlRm9ybSA/IGlucHV0TGVuZ3RoIDogcmV0dXJuT2JqZWN0LmxlbkJsb2NrLmxlbmd0aCk7XHJcbiAgICByZXR1cm5PYmplY3QudmFsdWVCZWZvcmVEZWNvZGVWaWV3ID0gaW5wdXRCdWZmZXIuc3ViYXJyYXkoaW5jb21pbmdPZmZzZXQsIGluY29taW5nT2Zmc2V0ICsgcmV0dXJuT2JqZWN0LmJsb2NrTGVuZ3RoKTtcclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgb2Zmc2V0OiByZXN1bHRPZmZzZXQsXHJcbiAgICAgICAgcmVzdWx0OiByZXR1cm5PYmplY3RcclxuICAgIH07XHJcbn1cclxuZnVuY3Rpb24gZnJvbUJFUihpbnB1dEJ1ZmZlcikge1xyXG4gICAgaWYgKCFpbnB1dEJ1ZmZlci5ieXRlTGVuZ3RoKSB7XHJcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gbmV3IEJhc2VCbG9jayh7fSwgVmFsdWVCbG9jayk7XHJcbiAgICAgICAgcmVzdWx0LmVycm9yID0gXCJJbnB1dCBidWZmZXIgaGFzIHplcm8gbGVuZ3RoXCI7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgb2Zmc2V0OiAtMSxcclxuICAgICAgICAgICAgcmVzdWx0XHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuICAgIHJldHVybiBsb2NhbEZyb21CRVIocHZ0c3V0aWxzLkJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b1VpbnQ4QXJyYXkoaW5wdXRCdWZmZXIpLnNsaWNlKCksIDAsIGlucHV0QnVmZmVyLmJ5dGVMZW5ndGgpO1xyXG59XG5cbmZ1bmN0aW9uIGNoZWNrTGVuKGluZGVmaW5pdGVMZW5ndGgsIGxlbmd0aCkge1xyXG4gICAgaWYgKGluZGVmaW5pdGVMZW5ndGgpIHtcclxuICAgICAgICByZXR1cm4gMTtcclxuICAgIH1cclxuICAgIHJldHVybiBsZW5ndGg7XHJcbn1cclxuY2xhc3MgTG9jYWxDb25zdHJ1Y3RlZFZhbHVlQmxvY2sgZXh0ZW5kcyBWYWx1ZUJsb2NrIHtcclxuICAgIGNvbnN0cnVjdG9yKHsgdmFsdWUgPSBbXSwgaXNJbmRlZmluaXRlRm9ybSA9IGZhbHNlLCAuLi5wYXJhbWV0ZXJzIH0gPSB7fSkge1xyXG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xyXG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcclxuICAgICAgICB0aGlzLmlzSW5kZWZpbml0ZUZvcm0gPSBpc0luZGVmaW5pdGVGb3JtO1xyXG4gICAgfVxyXG4gICAgZnJvbUJFUihpbnB1dEJ1ZmZlciwgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoKSB7XHJcbiAgICAgICAgY29uc3QgdmlldyA9IHB2dHN1dGlscy5CdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9VaW50OEFycmF5KGlucHV0QnVmZmVyKTtcclxuICAgICAgICBpZiAoIWNoZWNrQnVmZmVyUGFyYW1zKHRoaXMsIHZpZXcsIGlucHV0T2Zmc2V0LCBpbnB1dExlbmd0aCkpIHtcclxuICAgICAgICAgICAgcmV0dXJuIC0xO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnZhbHVlQmVmb3JlRGVjb2RlVmlldyA9IHZpZXcuc3ViYXJyYXkoaW5wdXRPZmZzZXQsIGlucHV0T2Zmc2V0ICsgaW5wdXRMZW5ndGgpO1xyXG4gICAgICAgIGlmICh0aGlzLnZhbHVlQmVmb3JlRGVjb2RlVmlldy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgdGhpcy53YXJuaW5ncy5wdXNoKFwiWmVybyBidWZmZXIgbGVuZ3RoXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gaW5wdXRPZmZzZXQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGxldCBjdXJyZW50T2Zmc2V0ID0gaW5wdXRPZmZzZXQ7XHJcbiAgICAgICAgd2hpbGUgKGNoZWNrTGVuKHRoaXMuaXNJbmRlZmluaXRlRm9ybSwgaW5wdXRMZW5ndGgpID4gMCkge1xyXG4gICAgICAgICAgICBjb25zdCByZXR1cm5PYmplY3QgPSBsb2NhbEZyb21CRVIodmlldywgY3VycmVudE9mZnNldCwgaW5wdXRMZW5ndGgpO1xyXG4gICAgICAgICAgICBpZiAocmV0dXJuT2JqZWN0Lm9mZnNldCA9PT0gLTEpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZXJyb3IgPSByZXR1cm5PYmplY3QucmVzdWx0LmVycm9yO1xyXG4gICAgICAgICAgICAgICAgdGhpcy53YXJuaW5ncy5jb25jYXQocmV0dXJuT2JqZWN0LnJlc3VsdC53YXJuaW5ncyk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gLTE7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY3VycmVudE9mZnNldCA9IHJldHVybk9iamVjdC5vZmZzZXQ7XHJcbiAgICAgICAgICAgIHRoaXMuYmxvY2tMZW5ndGggKz0gcmV0dXJuT2JqZWN0LnJlc3VsdC5ibG9ja0xlbmd0aDtcclxuICAgICAgICAgICAgaW5wdXRMZW5ndGggLT0gcmV0dXJuT2JqZWN0LnJlc3VsdC5ibG9ja0xlbmd0aDtcclxuICAgICAgICAgICAgdGhpcy52YWx1ZS5wdXNoKHJldHVybk9iamVjdC5yZXN1bHQpO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5pc0luZGVmaW5pdGVGb3JtICYmIHJldHVybk9iamVjdC5yZXN1bHQuY29uc3RydWN0b3IuTkFNRSA9PT0gRU5EX09GX0NPTlRFTlRfTkFNRSkge1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHRoaXMuaXNJbmRlZmluaXRlRm9ybSkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy52YWx1ZVt0aGlzLnZhbHVlLmxlbmd0aCAtIDFdLmNvbnN0cnVjdG9yLk5BTUUgPT09IEVORF9PRl9DT05URU5UX05BTUUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMudmFsdWUucG9wKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLndhcm5pbmdzLnB1c2goXCJObyBFbmRPZkNvbnRlbnQgYmxvY2sgZW5jb2RlZFwiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gY3VycmVudE9mZnNldDtcclxuICAgIH1cclxuICAgIHRvQkVSKHNpemVPbmx5LCB3cml0ZXIpIHtcclxuICAgICAgICBjb25zdCBfd3JpdGVyID0gd3JpdGVyIHx8IG5ldyBWaWV3V3JpdGVyKCk7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnZhbHVlLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIHRoaXMudmFsdWVbaV0udG9CRVIoc2l6ZU9ubHksIF93cml0ZXIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIXdyaXRlcikge1xyXG4gICAgICAgICAgICByZXR1cm4gX3dyaXRlci5maW5hbCgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gRU1QVFlfQlVGRkVSO1xyXG4gICAgfVxyXG4gICAgdG9KU09OKCkge1xyXG4gICAgICAgIGNvbnN0IG9iamVjdCA9IHtcclxuICAgICAgICAgICAgLi4uc3VwZXIudG9KU09OKCksXHJcbiAgICAgICAgICAgIGlzSW5kZWZpbml0ZUZvcm06IHRoaXMuaXNJbmRlZmluaXRlRm9ybSxcclxuICAgICAgICAgICAgdmFsdWU6IFtdLFxyXG4gICAgICAgIH07XHJcbiAgICAgICAgZm9yIChjb25zdCB2YWx1ZSBvZiB0aGlzLnZhbHVlKSB7XHJcbiAgICAgICAgICAgIG9iamVjdC52YWx1ZS5wdXNoKHZhbHVlLnRvSlNPTigpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIG9iamVjdDtcclxuICAgIH1cclxufVxyXG5Mb2NhbENvbnN0cnVjdGVkVmFsdWVCbG9jay5OQU1FID0gXCJDb25zdHJ1Y3RlZFZhbHVlQmxvY2tcIjtcblxudmFyIF9hJHY7XHJcbmNsYXNzIENvbnN0cnVjdGVkIGV4dGVuZHMgQmFzZUJsb2NrIHtcclxuICAgIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMgPSB7fSkge1xyXG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMsIExvY2FsQ29uc3RydWN0ZWRWYWx1ZUJsb2NrKTtcclxuICAgICAgICB0aGlzLmlkQmxvY2suaXNDb25zdHJ1Y3RlZCA9IHRydWU7XHJcbiAgICB9XHJcbiAgICBmcm9tQkVSKGlucHV0QnVmZmVyLCBpbnB1dE9mZnNldCwgaW5wdXRMZW5ndGgpIHtcclxuICAgICAgICB0aGlzLnZhbHVlQmxvY2suaXNJbmRlZmluaXRlRm9ybSA9IHRoaXMubGVuQmxvY2suaXNJbmRlZmluaXRlRm9ybTtcclxuICAgICAgICBjb25zdCByZXN1bHRPZmZzZXQgPSB0aGlzLnZhbHVlQmxvY2suZnJvbUJFUihpbnB1dEJ1ZmZlciwgaW5wdXRPZmZzZXQsICh0aGlzLmxlbkJsb2NrLmlzSW5kZWZpbml0ZUZvcm0pID8gaW5wdXRMZW5ndGggOiB0aGlzLmxlbkJsb2NrLmxlbmd0aCk7XHJcbiAgICAgICAgaWYgKHJlc3VsdE9mZnNldCA9PT0gLTEpIHtcclxuICAgICAgICAgICAgdGhpcy5lcnJvciA9IHRoaXMudmFsdWVCbG9jay5lcnJvcjtcclxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdE9mZnNldDtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCF0aGlzLmlkQmxvY2suZXJyb3IubGVuZ3RoKVxyXG4gICAgICAgICAgICB0aGlzLmJsb2NrTGVuZ3RoICs9IHRoaXMuaWRCbG9jay5ibG9ja0xlbmd0aDtcclxuICAgICAgICBpZiAoIXRoaXMubGVuQmxvY2suZXJyb3IubGVuZ3RoKVxyXG4gICAgICAgICAgICB0aGlzLmJsb2NrTGVuZ3RoICs9IHRoaXMubGVuQmxvY2suYmxvY2tMZW5ndGg7XHJcbiAgICAgICAgaWYgKCF0aGlzLnZhbHVlQmxvY2suZXJyb3IubGVuZ3RoKVxyXG4gICAgICAgICAgICB0aGlzLmJsb2NrTGVuZ3RoICs9IHRoaXMudmFsdWVCbG9jay5ibG9ja0xlbmd0aDtcclxuICAgICAgICByZXR1cm4gcmVzdWx0T2Zmc2V0O1xyXG4gICAgfVxyXG4gICAgb25Bc2NpaUVuY29kaW5nKCkge1xyXG4gICAgICAgIGNvbnN0IHZhbHVlcyA9IFtdO1xyXG4gICAgICAgIGZvciAoY29uc3QgdmFsdWUgb2YgdGhpcy52YWx1ZUJsb2NrLnZhbHVlKSB7XHJcbiAgICAgICAgICAgIHZhbHVlcy5wdXNoKHZhbHVlLnRvU3RyaW5nKFwiYXNjaWlcIikuc3BsaXQoXCJcXG5cIikubWFwKG8gPT4gYCAgJHtvfWApLmpvaW4oXCJcXG5cIikpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBibG9ja05hbWUgPSB0aGlzLmlkQmxvY2sudGFnQ2xhc3MgPT09IDNcclxuICAgICAgICAgICAgPyBgWyR7dGhpcy5pZEJsb2NrLnRhZ051bWJlcn1dYFxyXG4gICAgICAgICAgICA6IHRoaXMuY29uc3RydWN0b3IuTkFNRTtcclxuICAgICAgICByZXR1cm4gdmFsdWVzLmxlbmd0aFxyXG4gICAgICAgICAgICA/IGAke2Jsb2NrTmFtZX0gOlxcbiR7dmFsdWVzLmpvaW4oXCJcXG5cIil9YFxyXG4gICAgICAgICAgICA6IGAke2Jsb2NrTmFtZX0gOmA7XHJcbiAgICB9XHJcbn1cclxuX2EkdiA9IENvbnN0cnVjdGVkO1xyXG4oKCkgPT4ge1xyXG4gICAgdHlwZVN0b3JlLkNvbnN0cnVjdGVkID0gX2EkdjtcclxufSkoKTtcclxuQ29uc3RydWN0ZWQuTkFNRSA9IFwiQ09OU1RSVUNURURcIjtcblxuY2xhc3MgTG9jYWxFbmRPZkNvbnRlbnRWYWx1ZUJsb2NrIGV4dGVuZHMgVmFsdWVCbG9jayB7XHJcbiAgICBmcm9tQkVSKGlucHV0QnVmZmVyLCBpbnB1dE9mZnNldCwgaW5wdXRMZW5ndGgpIHtcclxuICAgICAgICByZXR1cm4gaW5wdXRPZmZzZXQ7XHJcbiAgICB9XHJcbiAgICB0b0JFUihzaXplT25seSkge1xyXG4gICAgICAgIHJldHVybiBFTVBUWV9CVUZGRVI7XHJcbiAgICB9XHJcbn1cclxuTG9jYWxFbmRPZkNvbnRlbnRWYWx1ZUJsb2NrLm92ZXJyaWRlID0gXCJFbmRPZkNvbnRlbnRWYWx1ZUJsb2NrXCI7XG5cbnZhciBfYSR1O1xyXG5jbGFzcyBFbmRPZkNvbnRlbnQgZXh0ZW5kcyBCYXNlQmxvY2sge1xyXG4gICAgY29uc3RydWN0b3IocGFyYW1ldGVycyA9IHt9KSB7XHJcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycywgTG9jYWxFbmRPZkNvbnRlbnRWYWx1ZUJsb2NrKTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnQ2xhc3MgPSAxO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdOdW1iZXIgPSAwO1xyXG4gICAgfVxyXG59XHJcbl9hJHUgPSBFbmRPZkNvbnRlbnQ7XHJcbigoKSA9PiB7XHJcbiAgICB0eXBlU3RvcmUuRW5kT2ZDb250ZW50ID0gX2EkdTtcclxufSkoKTtcclxuRW5kT2ZDb250ZW50Lk5BTUUgPSBFTkRfT0ZfQ09OVEVOVF9OQU1FO1xuXG52YXIgX2EkdDtcclxuY2xhc3MgTnVsbCBleHRlbmRzIEJhc2VCbG9jayB7XHJcbiAgICBjb25zdHJ1Y3RvcihwYXJhbWV0ZXJzID0ge30pIHtcclxuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzLCBWYWx1ZUJsb2NrKTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnQ2xhc3MgPSAxO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdOdW1iZXIgPSA1O1xyXG4gICAgfVxyXG4gICAgZnJvbUJFUihpbnB1dEJ1ZmZlciwgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMubGVuQmxvY2subGVuZ3RoID4gMClcclxuICAgICAgICAgICAgdGhpcy53YXJuaW5ncy5wdXNoKFwiTm9uLXplcm8gbGVuZ3RoIG9mIHZhbHVlIGJsb2NrIGZvciBOdWxsIHR5cGVcIik7XHJcbiAgICAgICAgaWYgKCF0aGlzLmlkQmxvY2suZXJyb3IubGVuZ3RoKVxyXG4gICAgICAgICAgICB0aGlzLmJsb2NrTGVuZ3RoICs9IHRoaXMuaWRCbG9jay5ibG9ja0xlbmd0aDtcclxuICAgICAgICBpZiAoIXRoaXMubGVuQmxvY2suZXJyb3IubGVuZ3RoKVxyXG4gICAgICAgICAgICB0aGlzLmJsb2NrTGVuZ3RoICs9IHRoaXMubGVuQmxvY2suYmxvY2tMZW5ndGg7XHJcbiAgICAgICAgdGhpcy5ibG9ja0xlbmd0aCArPSBpbnB1dExlbmd0aDtcclxuICAgICAgICBpZiAoKGlucHV0T2Zmc2V0ICsgaW5wdXRMZW5ndGgpID4gaW5wdXRCdWZmZXIuYnl0ZUxlbmd0aCkge1xyXG4gICAgICAgICAgICB0aGlzLmVycm9yID0gXCJFbmQgb2YgaW5wdXQgcmVhY2hlZCBiZWZvcmUgbWVzc2FnZSB3YXMgZnVsbHkgZGVjb2RlZCAoaW5jb25zaXN0ZW50IG9mZnNldCBhbmQgbGVuZ3RoIHZhbHVlcylcIjtcclxuICAgICAgICAgICAgcmV0dXJuIC0xO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gKGlucHV0T2Zmc2V0ICsgaW5wdXRMZW5ndGgpO1xyXG4gICAgfVxyXG4gICAgdG9CRVIoc2l6ZU9ubHksIHdyaXRlcikge1xyXG4gICAgICAgIGNvbnN0IHJldEJ1ZiA9IG5ldyBBcnJheUJ1ZmZlcigyKTtcclxuICAgICAgICBpZiAoIXNpemVPbmx5KSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHJldFZpZXcgPSBuZXcgVWludDhBcnJheShyZXRCdWYpO1xyXG4gICAgICAgICAgICByZXRWaWV3WzBdID0gMHgwNTtcclxuICAgICAgICAgICAgcmV0Vmlld1sxXSA9IDB4MDA7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh3cml0ZXIpIHtcclxuICAgICAgICAgICAgd3JpdGVyLndyaXRlKHJldEJ1Zik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiByZXRCdWY7XHJcbiAgICB9XHJcbiAgICBvbkFzY2lpRW5jb2RpbmcoKSB7XHJcbiAgICAgICAgcmV0dXJuIGAke3RoaXMuY29uc3RydWN0b3IuTkFNRX1gO1xyXG4gICAgfVxyXG59XHJcbl9hJHQgPSBOdWxsO1xyXG4oKCkgPT4ge1xyXG4gICAgdHlwZVN0b3JlLk51bGwgPSBfYSR0O1xyXG59KSgpO1xyXG5OdWxsLk5BTUUgPSBcIk5VTExcIjtcblxuY2xhc3MgTG9jYWxCb29sZWFuVmFsdWVCbG9jayBleHRlbmRzIEhleEJsb2NrKFZhbHVlQmxvY2spIHtcclxuICAgIGNvbnN0cnVjdG9yKHsgdmFsdWUsIC4uLnBhcmFtZXRlcnMgfSA9IHt9KSB7XHJcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XHJcbiAgICAgICAgaWYgKHBhcmFtZXRlcnMudmFsdWVIZXgpIHtcclxuICAgICAgICAgICAgdGhpcy52YWx1ZUhleFZpZXcgPSBwdnRzdXRpbHMuQnVmZmVyU291cmNlQ29udmVydGVyLnRvVWludDhBcnJheShwYXJhbWV0ZXJzLnZhbHVlSGV4KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMudmFsdWVIZXhWaWV3ID0gbmV3IFVpbnQ4QXJyYXkoMSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh2YWx1ZSkge1xyXG4gICAgICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZ2V0IHZhbHVlKCkge1xyXG4gICAgICAgIGZvciAoY29uc3Qgb2N0ZXQgb2YgdGhpcy52YWx1ZUhleFZpZXcpIHtcclxuICAgICAgICAgICAgaWYgKG9jdGV0ID4gMCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gICAgc2V0IHZhbHVlKHZhbHVlKSB7XHJcbiAgICAgICAgdGhpcy52YWx1ZUhleFZpZXdbMF0gPSB2YWx1ZSA/IDB4RkYgOiAweDAwO1xyXG4gICAgfVxyXG4gICAgZnJvbUJFUihpbnB1dEJ1ZmZlciwgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoKSB7XHJcbiAgICAgICAgY29uc3QgaW5wdXRWaWV3ID0gcHZ0c3V0aWxzLkJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b1VpbnQ4QXJyYXkoaW5wdXRCdWZmZXIpO1xyXG4gICAgICAgIGlmICghY2hlY2tCdWZmZXJQYXJhbXModGhpcywgaW5wdXRWaWV3LCBpbnB1dE9mZnNldCwgaW5wdXRMZW5ndGgpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiAtMTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy52YWx1ZUhleFZpZXcgPSBpbnB1dFZpZXcuc3ViYXJyYXkoaW5wdXRPZmZzZXQsIGlucHV0T2Zmc2V0ICsgaW5wdXRMZW5ndGgpO1xyXG4gICAgICAgIGlmIChpbnB1dExlbmd0aCA+IDEpXHJcbiAgICAgICAgICAgIHRoaXMud2FybmluZ3MucHVzaChcIkJvb2xlYW4gdmFsdWUgZW5jb2RlZCBpbiBtb3JlIHRoZW4gMSBvY3RldFwiKTtcclxuICAgICAgICB0aGlzLmlzSGV4T25seSA9IHRydWU7XHJcbiAgICAgICAgcHZ1dGlscy51dGlsRGVjb2RlVEMuY2FsbCh0aGlzKTtcclxuICAgICAgICB0aGlzLmJsb2NrTGVuZ3RoID0gaW5wdXRMZW5ndGg7XHJcbiAgICAgICAgcmV0dXJuIChpbnB1dE9mZnNldCArIGlucHV0TGVuZ3RoKTtcclxuICAgIH1cclxuICAgIHRvQkVSKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlSGV4Vmlldy5zbGljZSgpO1xyXG4gICAgfVxyXG4gICAgdG9KU09OKCkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIC4uLnN1cGVyLnRvSlNPTigpLFxyXG4gICAgICAgICAgICB2YWx1ZTogdGhpcy52YWx1ZSxcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG59XHJcbkxvY2FsQm9vbGVhblZhbHVlQmxvY2suTkFNRSA9IFwiQm9vbGVhblZhbHVlQmxvY2tcIjtcblxudmFyIF9hJHM7XHJcbmNsYXNzIEJvb2xlYW4gZXh0ZW5kcyBCYXNlQmxvY2sge1xyXG4gICAgY29uc3RydWN0b3IocGFyYW1ldGVycyA9IHt9KSB7XHJcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycywgTG9jYWxCb29sZWFuVmFsdWVCbG9jayk7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ0NsYXNzID0gMTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnTnVtYmVyID0gMTtcclxuICAgIH1cclxuICAgIGdldFZhbHVlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlQmxvY2sudmFsdWU7XHJcbiAgICB9XHJcbiAgICBzZXRWYWx1ZSh2YWx1ZSkge1xyXG4gICAgICAgIHRoaXMudmFsdWVCbG9jay52YWx1ZSA9IHZhbHVlO1xyXG4gICAgfVxyXG4gICAgb25Bc2NpaUVuY29kaW5nKCkge1xyXG4gICAgICAgIHJldHVybiBgJHt0aGlzLmNvbnN0cnVjdG9yLk5BTUV9IDogJHt0aGlzLmdldFZhbHVlfWA7XHJcbiAgICB9XHJcbn1cclxuX2EkcyA9IEJvb2xlYW47XHJcbigoKSA9PiB7XHJcbiAgICB0eXBlU3RvcmUuQm9vbGVhbiA9IF9hJHM7XHJcbn0pKCk7XHJcbkJvb2xlYW4uTkFNRSA9IFwiQk9PTEVBTlwiO1xuXG5jbGFzcyBMb2NhbE9jdGV0U3RyaW5nVmFsdWVCbG9jayBleHRlbmRzIEhleEJsb2NrKExvY2FsQ29uc3RydWN0ZWRWYWx1ZUJsb2NrKSB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7IGlzQ29uc3RydWN0ZWQgPSBmYWxzZSwgLi4ucGFyYW1ldGVycyB9ID0ge30pIHtcclxuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcclxuICAgICAgICB0aGlzLmlzQ29uc3RydWN0ZWQgPSBpc0NvbnN0cnVjdGVkO1xyXG4gICAgfVxyXG4gICAgZnJvbUJFUihpbnB1dEJ1ZmZlciwgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoKSB7XHJcbiAgICAgICAgbGV0IHJlc3VsdE9mZnNldCA9IDA7XHJcbiAgICAgICAgaWYgKHRoaXMuaXNDb25zdHJ1Y3RlZCkge1xyXG4gICAgICAgICAgICB0aGlzLmlzSGV4T25seSA9IGZhbHNlO1xyXG4gICAgICAgICAgICByZXN1bHRPZmZzZXQgPSBMb2NhbENvbnN0cnVjdGVkVmFsdWVCbG9jay5wcm90b3R5cGUuZnJvbUJFUi5jYWxsKHRoaXMsIGlucHV0QnVmZmVyLCBpbnB1dE9mZnNldCwgaW5wdXRMZW5ndGgpO1xyXG4gICAgICAgICAgICBpZiAocmVzdWx0T2Zmc2V0ID09PSAtMSlcclxuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHRPZmZzZXQ7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy52YWx1ZS5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgY3VycmVudEJsb2NrTmFtZSA9IHRoaXMudmFsdWVbaV0uY29uc3RydWN0b3IuTkFNRTtcclxuICAgICAgICAgICAgICAgIGlmIChjdXJyZW50QmxvY2tOYW1lID09PSBFTkRfT0ZfQ09OVEVOVF9OQU1FKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNJbmRlZmluaXRlRm9ybSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZXJyb3IgPSBcIkVuZE9mQ29udGVudCBpcyB1bmV4cGVjdGVkLCBPQ1RFVCBTVFJJTkcgbWF5IGNvbnNpc3RzIG9mIE9DVEVUIFNUUklOR3Mgb25seVwiO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRCbG9ja05hbWUgIT09IE9DVEVUX1NUUklOR19OQU1FKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lcnJvciA9IFwiT0NURVQgU1RSSU5HIG1heSBjb25zaXN0cyBvZiBPQ1RFVCBTVFJJTkdzIG9ubHlcIjtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuaXNIZXhPbmx5ID0gdHJ1ZTtcclxuICAgICAgICAgICAgcmVzdWx0T2Zmc2V0ID0gc3VwZXIuZnJvbUJFUihpbnB1dEJ1ZmZlciwgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoKTtcclxuICAgICAgICAgICAgdGhpcy5ibG9ja0xlbmd0aCA9IGlucHV0TGVuZ3RoO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcmVzdWx0T2Zmc2V0O1xyXG4gICAgfVxyXG4gICAgdG9CRVIoc2l6ZU9ubHksIHdyaXRlcikge1xyXG4gICAgICAgIGlmICh0aGlzLmlzQ29uc3RydWN0ZWQpXHJcbiAgICAgICAgICAgIHJldHVybiBMb2NhbENvbnN0cnVjdGVkVmFsdWVCbG9jay5wcm90b3R5cGUudG9CRVIuY2FsbCh0aGlzLCBzaXplT25seSwgd3JpdGVyKTtcclxuICAgICAgICByZXR1cm4gc2l6ZU9ubHlcclxuICAgICAgICAgICAgPyBuZXcgQXJyYXlCdWZmZXIodGhpcy52YWx1ZUhleFZpZXcuYnl0ZUxlbmd0aClcclxuICAgICAgICAgICAgOiB0aGlzLnZhbHVlSGV4Vmlldy5zbGljZSgpLmJ1ZmZlcjtcclxuICAgIH1cclxuICAgIHRvSlNPTigpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAuLi5zdXBlci50b0pTT04oKSxcclxuICAgICAgICAgICAgaXNDb25zdHJ1Y3RlZDogdGhpcy5pc0NvbnN0cnVjdGVkLFxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbn1cclxuTG9jYWxPY3RldFN0cmluZ1ZhbHVlQmxvY2suTkFNRSA9IFwiT2N0ZXRTdHJpbmdWYWx1ZUJsb2NrXCI7XG5cbnZhciBfYSRyO1xyXG5jbGFzcyBPY3RldFN0cmluZyBleHRlbmRzIEJhc2VCbG9jayB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7IGlkQmxvY2sgPSB7fSwgbGVuQmxvY2sgPSB7fSwgLi4ucGFyYW1ldGVycyB9ID0ge30pIHtcclxuICAgICAgICB2YXIgX2IsIF9jO1xyXG4gICAgICAgIChfYiA9IHBhcmFtZXRlcnMuaXNDb25zdHJ1Y3RlZCkgIT09IG51bGwgJiYgX2IgIT09IHZvaWQgMCA/IF9iIDogKHBhcmFtZXRlcnMuaXNDb25zdHJ1Y3RlZCA9ICEhKChfYyA9IHBhcmFtZXRlcnMudmFsdWUpID09PSBudWxsIHx8IF9jID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYy5sZW5ndGgpKTtcclxuICAgICAgICBzdXBlcih7XHJcbiAgICAgICAgICAgIGlkQmxvY2s6IHtcclxuICAgICAgICAgICAgICAgIGlzQ29uc3RydWN0ZWQ6IHBhcmFtZXRlcnMuaXNDb25zdHJ1Y3RlZCxcclxuICAgICAgICAgICAgICAgIC4uLmlkQmxvY2ssXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGxlbkJsb2NrOiB7XHJcbiAgICAgICAgICAgICAgICAuLi5sZW5CbG9jayxcclxuICAgICAgICAgICAgICAgIGlzSW5kZWZpbml0ZUZvcm06ICEhcGFyYW1ldGVycy5pc0luZGVmaW5pdGVGb3JtLFxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAuLi5wYXJhbWV0ZXJzLFxyXG4gICAgICAgIH0sIExvY2FsT2N0ZXRTdHJpbmdWYWx1ZUJsb2NrKTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnQ2xhc3MgPSAxO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdOdW1iZXIgPSA0O1xyXG4gICAgfVxyXG4gICAgZnJvbUJFUihpbnB1dEJ1ZmZlciwgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoKSB7XHJcbiAgICAgICAgdGhpcy52YWx1ZUJsb2NrLmlzQ29uc3RydWN0ZWQgPSB0aGlzLmlkQmxvY2suaXNDb25zdHJ1Y3RlZDtcclxuICAgICAgICB0aGlzLnZhbHVlQmxvY2suaXNJbmRlZmluaXRlRm9ybSA9IHRoaXMubGVuQmxvY2suaXNJbmRlZmluaXRlRm9ybTtcclxuICAgICAgICBpZiAoaW5wdXRMZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuaWRCbG9jay5lcnJvci5sZW5ndGggPT09IDApXHJcbiAgICAgICAgICAgICAgICB0aGlzLmJsb2NrTGVuZ3RoICs9IHRoaXMuaWRCbG9jay5ibG9ja0xlbmd0aDtcclxuICAgICAgICAgICAgaWYgKHRoaXMubGVuQmxvY2suZXJyb3IubGVuZ3RoID09PSAwKVxyXG4gICAgICAgICAgICAgICAgdGhpcy5ibG9ja0xlbmd0aCArPSB0aGlzLmxlbkJsb2NrLmJsb2NrTGVuZ3RoO1xyXG4gICAgICAgICAgICByZXR1cm4gaW5wdXRPZmZzZXQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghdGhpcy52YWx1ZUJsb2NrLmlzQ29uc3RydWN0ZWQpIHtcclxuICAgICAgICAgICAgY29uc3QgdmlldyA9IGlucHV0QnVmZmVyIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIgPyBuZXcgVWludDhBcnJheShpbnB1dEJ1ZmZlcikgOiBpbnB1dEJ1ZmZlcjtcclxuICAgICAgICAgICAgY29uc3QgYnVmID0gdmlldy5zdWJhcnJheShpbnB1dE9mZnNldCwgaW5wdXRPZmZzZXQgKyBpbnB1dExlbmd0aCk7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoYnVmLmJ5dGVMZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBhc24gPSBsb2NhbEZyb21CRVIoYnVmLCAwLCBidWYuYnl0ZUxlbmd0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGFzbi5vZmZzZXQgIT09IC0xICYmIGFzbi5vZmZzZXQgPT09IGlucHV0TGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudmFsdWVCbG9jay52YWx1ZSA9IFthc24ucmVzdWx0XTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gc3VwZXIuZnJvbUJFUihpbnB1dEJ1ZmZlciwgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoKTtcclxuICAgIH1cclxuICAgIG9uQXNjaWlFbmNvZGluZygpIHtcclxuICAgICAgICBpZiAodGhpcy52YWx1ZUJsb2NrLmlzQ29uc3RydWN0ZWQgfHwgKHRoaXMudmFsdWVCbG9jay52YWx1ZSAmJiB0aGlzLnZhbHVlQmxvY2sudmFsdWUubGVuZ3RoKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gQ29uc3RydWN0ZWQucHJvdG90eXBlLm9uQXNjaWlFbmNvZGluZy5jYWxsKHRoaXMpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gYCR7dGhpcy5jb25zdHJ1Y3Rvci5OQU1FfSA6ICR7cHZ0c3V0aWxzLkNvbnZlcnQuVG9IZXgodGhpcy52YWx1ZUJsb2NrLnZhbHVlSGV4Vmlldyl9YDtcclxuICAgIH1cclxuICAgIGdldFZhbHVlKCkge1xyXG4gICAgICAgIGlmICghdGhpcy5pZEJsb2NrLmlzQ29uc3RydWN0ZWQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMudmFsdWVCbG9jay52YWx1ZUhleFZpZXcuc2xpY2UoKS5idWZmZXI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IGFycmF5ID0gW107XHJcbiAgICAgICAgZm9yIChjb25zdCBjb250ZW50IG9mIHRoaXMudmFsdWVCbG9jay52YWx1ZSkge1xyXG4gICAgICAgICAgICBpZiAoY29udGVudCBpbnN0YW5jZW9mIE9jdGV0U3RyaW5nKSB7XHJcbiAgICAgICAgICAgICAgICBhcnJheS5wdXNoKGNvbnRlbnQudmFsdWVCbG9jay52YWx1ZUhleFZpZXcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBwdnRzdXRpbHMuQnVmZmVyU291cmNlQ29udmVydGVyLmNvbmNhdChhcnJheSk7XHJcbiAgICB9XHJcbn1cclxuX2EkciA9IE9jdGV0U3RyaW5nO1xyXG4oKCkgPT4ge1xyXG4gICAgdHlwZVN0b3JlLk9jdGV0U3RyaW5nID0gX2EkcjtcclxufSkoKTtcclxuT2N0ZXRTdHJpbmcuTkFNRSA9IE9DVEVUX1NUUklOR19OQU1FO1xuXG5jbGFzcyBMb2NhbEJpdFN0cmluZ1ZhbHVlQmxvY2sgZXh0ZW5kcyBIZXhCbG9jayhMb2NhbENvbnN0cnVjdGVkVmFsdWVCbG9jaykge1xyXG4gICAgY29uc3RydWN0b3IoeyB1bnVzZWRCaXRzID0gMCwgaXNDb25zdHJ1Y3RlZCA9IGZhbHNlLCAuLi5wYXJhbWV0ZXJzIH0gPSB7fSkge1xyXG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xyXG4gICAgICAgIHRoaXMudW51c2VkQml0cyA9IHVudXNlZEJpdHM7XHJcbiAgICAgICAgdGhpcy5pc0NvbnN0cnVjdGVkID0gaXNDb25zdHJ1Y3RlZDtcclxuICAgICAgICB0aGlzLmJsb2NrTGVuZ3RoID0gdGhpcy52YWx1ZUhleFZpZXcuYnl0ZUxlbmd0aDtcclxuICAgIH1cclxuICAgIGZyb21CRVIoaW5wdXRCdWZmZXIsIGlucHV0T2Zmc2V0LCBpbnB1dExlbmd0aCkge1xyXG4gICAgICAgIGlmICghaW5wdXRMZW5ndGgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGlucHV0T2Zmc2V0O1xyXG4gICAgICAgIH1cclxuICAgICAgICBsZXQgcmVzdWx0T2Zmc2V0ID0gLTE7XHJcbiAgICAgICAgaWYgKHRoaXMuaXNDb25zdHJ1Y3RlZCkge1xyXG4gICAgICAgICAgICByZXN1bHRPZmZzZXQgPSBMb2NhbENvbnN0cnVjdGVkVmFsdWVCbG9jay5wcm90b3R5cGUuZnJvbUJFUi5jYWxsKHRoaXMsIGlucHV0QnVmZmVyLCBpbnB1dE9mZnNldCwgaW5wdXRMZW5ndGgpO1xyXG4gICAgICAgICAgICBpZiAocmVzdWx0T2Zmc2V0ID09PSAtMSlcclxuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHRPZmZzZXQ7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgdmFsdWUgb2YgdGhpcy52YWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgY3VycmVudEJsb2NrTmFtZSA9IHZhbHVlLmNvbnN0cnVjdG9yLk5BTUU7XHJcbiAgICAgICAgICAgICAgICBpZiAoY3VycmVudEJsb2NrTmFtZSA9PT0gRU5EX09GX0NPTlRFTlRfTkFNRSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzSW5kZWZpbml0ZUZvcm0pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVycm9yID0gXCJFbmRPZkNvbnRlbnQgaXMgdW5leHBlY3RlZCwgQklUIFNUUklORyBtYXkgY29uc2lzdHMgb2YgQklUIFNUUklOR3Mgb25seVwiO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRCbG9ja05hbWUgIT09IEJJVF9TVFJJTkdfTkFNRSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXJyb3IgPSBcIkJJVCBTVFJJTkcgbWF5IGNvbnNpc3RzIG9mIEJJVCBTVFJJTkdzIG9ubHlcIjtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZUJsb2NrID0gdmFsdWUudmFsdWVCbG9jaztcclxuICAgICAgICAgICAgICAgIGlmICgodGhpcy51bnVzZWRCaXRzID4gMCkgJiYgKHZhbHVlQmxvY2sudW51c2VkQml0cyA+IDApKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lcnJvciA9IFwiVXNpbmcgb2YgXFxcInVudXNlZCBiaXRzXFxcIiBpbnNpZGUgY29uc3RydWN0aXZlIEJJVCBTVFJJTkcgYWxsb3dlZCBmb3IgbGVhc3Qgb25lIG9ubHlcIjtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aGlzLnVudXNlZEJpdHMgPSB2YWx1ZUJsb2NrLnVudXNlZEJpdHM7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdE9mZnNldDtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgaW5wdXRWaWV3ID0gcHZ0c3V0aWxzLkJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b1VpbnQ4QXJyYXkoaW5wdXRCdWZmZXIpO1xyXG4gICAgICAgIGlmICghY2hlY2tCdWZmZXJQYXJhbXModGhpcywgaW5wdXRWaWV3LCBpbnB1dE9mZnNldCwgaW5wdXRMZW5ndGgpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiAtMTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgaW50QnVmZmVyID0gaW5wdXRWaWV3LnN1YmFycmF5KGlucHV0T2Zmc2V0LCBpbnB1dE9mZnNldCArIGlucHV0TGVuZ3RoKTtcclxuICAgICAgICB0aGlzLnVudXNlZEJpdHMgPSBpbnRCdWZmZXJbMF07XHJcbiAgICAgICAgaWYgKHRoaXMudW51c2VkQml0cyA+IDcpIHtcclxuICAgICAgICAgICAgdGhpcy5lcnJvciA9IFwiVW51c2VkIGJpdHMgZm9yIEJpdFN0cmluZyBtdXN0IGJlIGluIHJhbmdlIDAtN1wiO1xyXG4gICAgICAgICAgICByZXR1cm4gLTE7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghdGhpcy51bnVzZWRCaXRzKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGJ1ZiA9IGludEJ1ZmZlci5zdWJhcnJheSgxKTtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIGlmIChidWYuYnl0ZUxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFzbiA9IGxvY2FsRnJvbUJFUihidWYsIDAsIGJ1Zi5ieXRlTGVuZ3RoKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoYXNuLm9mZnNldCAhPT0gLTEgJiYgYXNuLm9mZnNldCA9PT0gKGlucHV0TGVuZ3RoIC0gMSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy52YWx1ZSA9IFthc24ucmVzdWx0XTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnZhbHVlSGV4VmlldyA9IGludEJ1ZmZlci5zdWJhcnJheSgxKTtcclxuICAgICAgICB0aGlzLmJsb2NrTGVuZ3RoID0gaW50QnVmZmVyLmxlbmd0aDtcclxuICAgICAgICByZXR1cm4gKGlucHV0T2Zmc2V0ICsgaW5wdXRMZW5ndGgpO1xyXG4gICAgfVxyXG4gICAgdG9CRVIoc2l6ZU9ubHksIHdyaXRlcikge1xyXG4gICAgICAgIGlmICh0aGlzLmlzQ29uc3RydWN0ZWQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIExvY2FsQ29uc3RydWN0ZWRWYWx1ZUJsb2NrLnByb3RvdHlwZS50b0JFUi5jYWxsKHRoaXMsIHNpemVPbmx5LCB3cml0ZXIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoc2l6ZU9ubHkpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG5ldyBBcnJheUJ1ZmZlcih0aGlzLnZhbHVlSGV4Vmlldy5ieXRlTGVuZ3RoICsgMSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghdGhpcy52YWx1ZUhleFZpZXcuYnl0ZUxlbmd0aCkge1xyXG4gICAgICAgICAgICByZXR1cm4gRU1QVFlfQlVGRkVSO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCByZXRWaWV3ID0gbmV3IFVpbnQ4QXJyYXkodGhpcy52YWx1ZUhleFZpZXcubGVuZ3RoICsgMSk7XHJcbiAgICAgICAgcmV0Vmlld1swXSA9IHRoaXMudW51c2VkQml0cztcclxuICAgICAgICByZXRWaWV3LnNldCh0aGlzLnZhbHVlSGV4VmlldywgMSk7XHJcbiAgICAgICAgcmV0dXJuIHJldFZpZXcuYnVmZmVyO1xyXG4gICAgfVxyXG4gICAgdG9KU09OKCkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIC4uLnN1cGVyLnRvSlNPTigpLFxyXG4gICAgICAgICAgICB1bnVzZWRCaXRzOiB0aGlzLnVudXNlZEJpdHMsXHJcbiAgICAgICAgICAgIGlzQ29uc3RydWN0ZWQ6IHRoaXMuaXNDb25zdHJ1Y3RlZCxcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG59XHJcbkxvY2FsQml0U3RyaW5nVmFsdWVCbG9jay5OQU1FID0gXCJCaXRTdHJpbmdWYWx1ZUJsb2NrXCI7XG5cbnZhciBfYSRxO1xyXG5jbGFzcyBCaXRTdHJpbmcgZXh0ZW5kcyBCYXNlQmxvY2sge1xyXG4gICAgY29uc3RydWN0b3IoeyBpZEJsb2NrID0ge30sIGxlbkJsb2NrID0ge30sIC4uLnBhcmFtZXRlcnMgfSA9IHt9KSB7XHJcbiAgICAgICAgdmFyIF9iLCBfYztcclxuICAgICAgICAoX2IgPSBwYXJhbWV0ZXJzLmlzQ29uc3RydWN0ZWQpICE9PSBudWxsICYmIF9iICE9PSB2b2lkIDAgPyBfYiA6IChwYXJhbWV0ZXJzLmlzQ29uc3RydWN0ZWQgPSAhISgoX2MgPSBwYXJhbWV0ZXJzLnZhbHVlKSA9PT0gbnVsbCB8fCBfYyA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2MubGVuZ3RoKSk7XHJcbiAgICAgICAgc3VwZXIoe1xyXG4gICAgICAgICAgICBpZEJsb2NrOiB7XHJcbiAgICAgICAgICAgICAgICBpc0NvbnN0cnVjdGVkOiBwYXJhbWV0ZXJzLmlzQ29uc3RydWN0ZWQsXHJcbiAgICAgICAgICAgICAgICAuLi5pZEJsb2NrLFxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBsZW5CbG9jazoge1xyXG4gICAgICAgICAgICAgICAgLi4ubGVuQmxvY2ssXHJcbiAgICAgICAgICAgICAgICBpc0luZGVmaW5pdGVGb3JtOiAhIXBhcmFtZXRlcnMuaXNJbmRlZmluaXRlRm9ybSxcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgLi4ucGFyYW1ldGVycyxcclxuICAgICAgICB9LCBMb2NhbEJpdFN0cmluZ1ZhbHVlQmxvY2spO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdDbGFzcyA9IDE7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ051bWJlciA9IDM7XHJcbiAgICB9XHJcbiAgICBmcm9tQkVSKGlucHV0QnVmZmVyLCBpbnB1dE9mZnNldCwgaW5wdXRMZW5ndGgpIHtcclxuICAgICAgICB0aGlzLnZhbHVlQmxvY2suaXNDb25zdHJ1Y3RlZCA9IHRoaXMuaWRCbG9jay5pc0NvbnN0cnVjdGVkO1xyXG4gICAgICAgIHRoaXMudmFsdWVCbG9jay5pc0luZGVmaW5pdGVGb3JtID0gdGhpcy5sZW5CbG9jay5pc0luZGVmaW5pdGVGb3JtO1xyXG4gICAgICAgIHJldHVybiBzdXBlci5mcm9tQkVSKGlucHV0QnVmZmVyLCBpbnB1dE9mZnNldCwgaW5wdXRMZW5ndGgpO1xyXG4gICAgfVxyXG4gICAgb25Bc2NpaUVuY29kaW5nKCkge1xyXG4gICAgICAgIGlmICh0aGlzLnZhbHVlQmxvY2suaXNDb25zdHJ1Y3RlZCB8fCAodGhpcy52YWx1ZUJsb2NrLnZhbHVlICYmIHRoaXMudmFsdWVCbG9jay52YWx1ZS5sZW5ndGgpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBDb25zdHJ1Y3RlZC5wcm90b3R5cGUub25Bc2NpaUVuY29kaW5nLmNhbGwodGhpcyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBjb25zdCBiaXRzID0gW107XHJcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlSGV4ID0gdGhpcy52YWx1ZUJsb2NrLnZhbHVlSGV4VmlldztcclxuICAgICAgICAgICAgZm9yIChjb25zdCBieXRlIG9mIHZhbHVlSGV4KSB7XHJcbiAgICAgICAgICAgICAgICBiaXRzLnB1c2goYnl0ZS50b1N0cmluZygyKS5wYWRTdGFydCg4LCBcIjBcIikpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNvbnN0IGJpdHNTdHIgPSBiaXRzLmpvaW4oXCJcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBgJHt0aGlzLmNvbnN0cnVjdG9yLk5BTUV9IDogJHtiaXRzU3RyLnN1YnN0cmluZygwLCBiaXRzU3RyLmxlbmd0aCAtIHRoaXMudmFsdWVCbG9jay51bnVzZWRCaXRzKX1gO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG5fYSRxID0gQml0U3RyaW5nO1xyXG4oKCkgPT4ge1xyXG4gICAgdHlwZVN0b3JlLkJpdFN0cmluZyA9IF9hJHE7XHJcbn0pKCk7XHJcbkJpdFN0cmluZy5OQU1FID0gQklUX1NUUklOR19OQU1FO1xuXG52YXIgX2EkcDtcclxuZnVuY3Rpb24gdmlld0FkZChmaXJzdCwgc2Vjb25kKSB7XHJcbiAgICBjb25zdCBjID0gbmV3IFVpbnQ4QXJyYXkoWzBdKTtcclxuICAgIGNvbnN0IGZpcnN0VmlldyA9IG5ldyBVaW50OEFycmF5KGZpcnN0KTtcclxuICAgIGNvbnN0IHNlY29uZFZpZXcgPSBuZXcgVWludDhBcnJheShzZWNvbmQpO1xyXG4gICAgbGV0IGZpcnN0Vmlld0NvcHkgPSBmaXJzdFZpZXcuc2xpY2UoMCk7XHJcbiAgICBjb25zdCBmaXJzdFZpZXdDb3B5TGVuZ3RoID0gZmlyc3RWaWV3Q29weS5sZW5ndGggLSAxO1xyXG4gICAgY29uc3Qgc2Vjb25kVmlld0NvcHkgPSBzZWNvbmRWaWV3LnNsaWNlKDApO1xyXG4gICAgY29uc3Qgc2Vjb25kVmlld0NvcHlMZW5ndGggPSBzZWNvbmRWaWV3Q29weS5sZW5ndGggLSAxO1xyXG4gICAgbGV0IHZhbHVlID0gMDtcclxuICAgIGNvbnN0IG1heCA9IChzZWNvbmRWaWV3Q29weUxlbmd0aCA8IGZpcnN0Vmlld0NvcHlMZW5ndGgpID8gZmlyc3RWaWV3Q29weUxlbmd0aCA6IHNlY29uZFZpZXdDb3B5TGVuZ3RoO1xyXG4gICAgbGV0IGNvdW50ZXIgPSAwO1xyXG4gICAgZm9yIChsZXQgaSA9IG1heDsgaSA+PSAwOyBpLS0sIGNvdW50ZXIrKykge1xyXG4gICAgICAgIHN3aXRjaCAodHJ1ZSkge1xyXG4gICAgICAgICAgICBjYXNlIChjb3VudGVyIDwgc2Vjb25kVmlld0NvcHkubGVuZ3RoKTpcclxuICAgICAgICAgICAgICAgIHZhbHVlID0gZmlyc3RWaWV3Q29weVtmaXJzdFZpZXdDb3B5TGVuZ3RoIC0gY291bnRlcl0gKyBzZWNvbmRWaWV3Q29weVtzZWNvbmRWaWV3Q29weUxlbmd0aCAtIGNvdW50ZXJdICsgY1swXTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgdmFsdWUgPSBmaXJzdFZpZXdDb3B5W2ZpcnN0Vmlld0NvcHlMZW5ndGggLSBjb3VudGVyXSArIGNbMF07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNbMF0gPSB2YWx1ZSAvIDEwO1xyXG4gICAgICAgIHN3aXRjaCAodHJ1ZSkge1xyXG4gICAgICAgICAgICBjYXNlIChjb3VudGVyID49IGZpcnN0Vmlld0NvcHkubGVuZ3RoKTpcclxuICAgICAgICAgICAgICAgIGZpcnN0Vmlld0NvcHkgPSBwdnV0aWxzLnV0aWxDb25jYXRWaWV3KG5ldyBVaW50OEFycmF5KFt2YWx1ZSAlIDEwXSksIGZpcnN0Vmlld0NvcHkpO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICBmaXJzdFZpZXdDb3B5W2ZpcnN0Vmlld0NvcHlMZW5ndGggLSBjb3VudGVyXSA9IHZhbHVlICUgMTA7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKGNbMF0gPiAwKVxyXG4gICAgICAgIGZpcnN0Vmlld0NvcHkgPSBwdnV0aWxzLnV0aWxDb25jYXRWaWV3KGMsIGZpcnN0Vmlld0NvcHkpO1xyXG4gICAgcmV0dXJuIGZpcnN0Vmlld0NvcHk7XHJcbn1cclxuZnVuY3Rpb24gcG93ZXIyKG4pIHtcclxuICAgIGlmIChuID49IHBvd2VyczIubGVuZ3RoKSB7XHJcbiAgICAgICAgZm9yIChsZXQgcCA9IHBvd2VyczIubGVuZ3RoOyBwIDw9IG47IHArKykge1xyXG4gICAgICAgICAgICBjb25zdCBjID0gbmV3IFVpbnQ4QXJyYXkoWzBdKTtcclxuICAgICAgICAgICAgbGV0IGRpZ2l0cyA9IChwb3dlcnMyW3AgLSAxXSkuc2xpY2UoMCk7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAoZGlnaXRzLmxlbmd0aCAtIDEpOyBpID49IDA7IGktLSkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbmV3VmFsdWUgPSBuZXcgVWludDhBcnJheShbKGRpZ2l0c1tpXSA8PCAxKSArIGNbMF1dKTtcclxuICAgICAgICAgICAgICAgIGNbMF0gPSBuZXdWYWx1ZVswXSAvIDEwO1xyXG4gICAgICAgICAgICAgICAgZGlnaXRzW2ldID0gbmV3VmFsdWVbMF0gJSAxMDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoY1swXSA+IDApXHJcbiAgICAgICAgICAgICAgICBkaWdpdHMgPSBwdnV0aWxzLnV0aWxDb25jYXRWaWV3KGMsIGRpZ2l0cyk7XHJcbiAgICAgICAgICAgIHBvd2VyczIucHVzaChkaWdpdHMpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBwb3dlcnMyW25dO1xyXG59XHJcbmZ1bmN0aW9uIHZpZXdTdWIoZmlyc3QsIHNlY29uZCkge1xyXG4gICAgbGV0IGIgPSAwO1xyXG4gICAgY29uc3QgZmlyc3RWaWV3ID0gbmV3IFVpbnQ4QXJyYXkoZmlyc3QpO1xyXG4gICAgY29uc3Qgc2Vjb25kVmlldyA9IG5ldyBVaW50OEFycmF5KHNlY29uZCk7XHJcbiAgICBjb25zdCBmaXJzdFZpZXdDb3B5ID0gZmlyc3RWaWV3LnNsaWNlKDApO1xyXG4gICAgY29uc3QgZmlyc3RWaWV3Q29weUxlbmd0aCA9IGZpcnN0Vmlld0NvcHkubGVuZ3RoIC0gMTtcclxuICAgIGNvbnN0IHNlY29uZFZpZXdDb3B5ID0gc2Vjb25kVmlldy5zbGljZSgwKTtcclxuICAgIGNvbnN0IHNlY29uZFZpZXdDb3B5TGVuZ3RoID0gc2Vjb25kVmlld0NvcHkubGVuZ3RoIC0gMTtcclxuICAgIGxldCB2YWx1ZTtcclxuICAgIGxldCBjb3VudGVyID0gMDtcclxuICAgIGZvciAobGV0IGkgPSBzZWNvbmRWaWV3Q29weUxlbmd0aDsgaSA+PSAwOyBpLS0sIGNvdW50ZXIrKykge1xyXG4gICAgICAgIHZhbHVlID0gZmlyc3RWaWV3Q29weVtmaXJzdFZpZXdDb3B5TGVuZ3RoIC0gY291bnRlcl0gLSBzZWNvbmRWaWV3Q29weVtzZWNvbmRWaWV3Q29weUxlbmd0aCAtIGNvdW50ZXJdIC0gYjtcclxuICAgICAgICBzd2l0Y2ggKHRydWUpIHtcclxuICAgICAgICAgICAgY2FzZSAodmFsdWUgPCAwKTpcclxuICAgICAgICAgICAgICAgIGIgPSAxO1xyXG4gICAgICAgICAgICAgICAgZmlyc3RWaWV3Q29weVtmaXJzdFZpZXdDb3B5TGVuZ3RoIC0gY291bnRlcl0gPSB2YWx1ZSArIDEwO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICBiID0gMDtcclxuICAgICAgICAgICAgICAgIGZpcnN0Vmlld0NvcHlbZmlyc3RWaWV3Q29weUxlbmd0aCAtIGNvdW50ZXJdID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKGIgPiAwKSB7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IChmaXJzdFZpZXdDb3B5TGVuZ3RoIC0gc2Vjb25kVmlld0NvcHlMZW5ndGggKyAxKTsgaSA+PSAwOyBpLS0sIGNvdW50ZXIrKykge1xyXG4gICAgICAgICAgICB2YWx1ZSA9IGZpcnN0Vmlld0NvcHlbZmlyc3RWaWV3Q29weUxlbmd0aCAtIGNvdW50ZXJdIC0gYjtcclxuICAgICAgICAgICAgaWYgKHZhbHVlIDwgMCkge1xyXG4gICAgICAgICAgICAgICAgYiA9IDE7XHJcbiAgICAgICAgICAgICAgICBmaXJzdFZpZXdDb3B5W2ZpcnN0Vmlld0NvcHlMZW5ndGggLSBjb3VudGVyXSA9IHZhbHVlICsgMTA7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBiID0gMDtcclxuICAgICAgICAgICAgICAgIGZpcnN0Vmlld0NvcHlbZmlyc3RWaWV3Q29weUxlbmd0aCAtIGNvdW50ZXJdID0gdmFsdWU7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBmaXJzdFZpZXdDb3B5LnNsaWNlKCk7XHJcbn1cclxuY2xhc3MgTG9jYWxJbnRlZ2VyVmFsdWVCbG9jayBleHRlbmRzIEhleEJsb2NrKFZhbHVlQmxvY2spIHtcclxuICAgIGNvbnN0cnVjdG9yKHsgdmFsdWUsIC4uLnBhcmFtZXRlcnMgfSA9IHt9KSB7XHJcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XHJcbiAgICAgICAgdGhpcy5fdmFsdWVEZWMgPSAwO1xyXG4gICAgICAgIGlmIChwYXJhbWV0ZXJzLnZhbHVlSGV4KSB7XHJcbiAgICAgICAgICAgIHRoaXMuc2V0VmFsdWVIZXgoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgdGhpcy52YWx1ZURlYyA9IHZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHNldFZhbHVlSGV4KCkge1xyXG4gICAgICAgIGlmICh0aGlzLnZhbHVlSGV4Vmlldy5sZW5ndGggPj0gNCkge1xyXG4gICAgICAgICAgICB0aGlzLndhcm5pbmdzLnB1c2goXCJUb28gYmlnIEludGVnZXIgZm9yIGRlY29kaW5nLCBoZXggb25seVwiKTtcclxuICAgICAgICAgICAgdGhpcy5pc0hleE9ubHkgPSB0cnVlO1xyXG4gICAgICAgICAgICB0aGlzLl92YWx1ZURlYyA9IDA7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLmlzSGV4T25seSA9IGZhbHNlO1xyXG4gICAgICAgICAgICBpZiAodGhpcy52YWx1ZUhleFZpZXcubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fdmFsdWVEZWMgPSBwdnV0aWxzLnV0aWxEZWNvZGVUQy5jYWxsKHRoaXMpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgc2V0IHZhbHVlRGVjKHYpIHtcclxuICAgICAgICB0aGlzLl92YWx1ZURlYyA9IHY7XHJcbiAgICAgICAgdGhpcy5pc0hleE9ubHkgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLnZhbHVlSGV4VmlldyA9IG5ldyBVaW50OEFycmF5KHB2dXRpbHMudXRpbEVuY29kZVRDKHYpKTtcclxuICAgIH1cclxuICAgIGdldCB2YWx1ZURlYygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fdmFsdWVEZWM7XHJcbiAgICB9XHJcbiAgICBmcm9tREVSKGlucHV0QnVmZmVyLCBpbnB1dE9mZnNldCwgaW5wdXRMZW5ndGgsIGV4cGVjdGVkTGVuZ3RoID0gMCkge1xyXG4gICAgICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuZnJvbUJFUihpbnB1dEJ1ZmZlciwgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoKTtcclxuICAgICAgICBpZiAob2Zmc2V0ID09PSAtMSlcclxuICAgICAgICAgICAgcmV0dXJuIG9mZnNldDtcclxuICAgICAgICBjb25zdCB2aWV3ID0gdGhpcy52YWx1ZUhleFZpZXc7XHJcbiAgICAgICAgaWYgKCh2aWV3WzBdID09PSAweDAwKSAmJiAoKHZpZXdbMV0gJiAweDgwKSAhPT0gMCkpIHtcclxuICAgICAgICAgICAgdGhpcy52YWx1ZUhleFZpZXcgPSB2aWV3LnN1YmFycmF5KDEpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgaWYgKGV4cGVjdGVkTGVuZ3RoICE9PSAwKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodmlldy5sZW5ndGggPCBleHBlY3RlZExlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICgoZXhwZWN0ZWRMZW5ndGggLSB2aWV3Lmxlbmd0aCkgPiAxKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBleHBlY3RlZExlbmd0aCA9IHZpZXcubGVuZ3RoICsgMTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnZhbHVlSGV4VmlldyA9IHZpZXcuc3ViYXJyYXkoZXhwZWN0ZWRMZW5ndGggLSB2aWV3Lmxlbmd0aCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIG9mZnNldDtcclxuICAgIH1cclxuICAgIHRvREVSKHNpemVPbmx5ID0gZmFsc2UpIHtcclxuICAgICAgICBjb25zdCB2aWV3ID0gdGhpcy52YWx1ZUhleFZpZXc7XHJcbiAgICAgICAgc3dpdGNoICh0cnVlKSB7XHJcbiAgICAgICAgICAgIGNhc2UgKCh2aWV3WzBdICYgMHg4MCkgIT09IDApOlxyXG4gICAgICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHVwZGF0ZWRWaWV3ID0gbmV3IFVpbnQ4QXJyYXkodGhpcy52YWx1ZUhleFZpZXcubGVuZ3RoICsgMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdXBkYXRlZFZpZXdbMF0gPSAweDAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHVwZGF0ZWRWaWV3LnNldCh2aWV3LCAxKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnZhbHVlSGV4VmlldyA9IHVwZGF0ZWRWaWV3O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgKCh2aWV3WzBdID09PSAweDAwKSAmJiAoKHZpZXdbMV0gJiAweDgwKSA9PT0gMCkpOlxyXG4gICAgICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudmFsdWVIZXhWaWV3ID0gdGhpcy52YWx1ZUhleFZpZXcuc3ViYXJyYXkoMSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXMudG9CRVIoc2l6ZU9ubHkpO1xyXG4gICAgfVxyXG4gICAgZnJvbUJFUihpbnB1dEJ1ZmZlciwgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoKSB7XHJcbiAgICAgICAgY29uc3QgcmVzdWx0T2Zmc2V0ID0gc3VwZXIuZnJvbUJFUihpbnB1dEJ1ZmZlciwgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoKTtcclxuICAgICAgICBpZiAocmVzdWx0T2Zmc2V0ID09PSAtMSkge1xyXG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0T2Zmc2V0O1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnNldFZhbHVlSGV4KCk7XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdE9mZnNldDtcclxuICAgIH1cclxuICAgIHRvQkVSKHNpemVPbmx5KSB7XHJcbiAgICAgICAgcmV0dXJuIHNpemVPbmx5XHJcbiAgICAgICAgICAgID8gbmV3IEFycmF5QnVmZmVyKHRoaXMudmFsdWVIZXhWaWV3Lmxlbmd0aClcclxuICAgICAgICAgICAgOiB0aGlzLnZhbHVlSGV4Vmlldy5zbGljZSgpLmJ1ZmZlcjtcclxuICAgIH1cclxuICAgIHRvSlNPTigpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAuLi5zdXBlci50b0pTT04oKSxcclxuICAgICAgICAgICAgdmFsdWVEZWM6IHRoaXMudmFsdWVEZWMsXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuICAgIHRvU3RyaW5nKCkge1xyXG4gICAgICAgIGNvbnN0IGZpcnN0Qml0ID0gKHRoaXMudmFsdWVIZXhWaWV3Lmxlbmd0aCAqIDgpIC0gMTtcclxuICAgICAgICBsZXQgZGlnaXRzID0gbmV3IFVpbnQ4QXJyYXkoKHRoaXMudmFsdWVIZXhWaWV3Lmxlbmd0aCAqIDgpIC8gMyk7XHJcbiAgICAgICAgbGV0IGJpdE51bWJlciA9IDA7XHJcbiAgICAgICAgbGV0IGN1cnJlbnRCeXRlO1xyXG4gICAgICAgIGNvbnN0IGFzbjFWaWV3ID0gdGhpcy52YWx1ZUhleFZpZXc7XHJcbiAgICAgICAgbGV0IHJlc3VsdCA9IFwiXCI7XHJcbiAgICAgICAgbGV0IGZsYWcgPSBmYWxzZTtcclxuICAgICAgICBmb3IgKGxldCBieXRlTnVtYmVyID0gKGFzbjFWaWV3LmJ5dGVMZW5ndGggLSAxKTsgYnl0ZU51bWJlciA+PSAwOyBieXRlTnVtYmVyLS0pIHtcclxuICAgICAgICAgICAgY3VycmVudEJ5dGUgPSBhc24xVmlld1tieXRlTnVtYmVyXTtcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCA4OyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGlmICgoY3VycmVudEJ5dGUgJiAxKSA9PT0gMSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoYml0TnVtYmVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgZmlyc3RCaXQ6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaWdpdHMgPSB2aWV3U3ViKHBvd2VyMihiaXROdW1iZXIpLCBkaWdpdHMpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gXCItXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpZ2l0cyA9IHZpZXdBZGQoZGlnaXRzLCBwb3dlcjIoYml0TnVtYmVyKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgYml0TnVtYmVyKys7XHJcbiAgICAgICAgICAgICAgICBjdXJyZW50Qnl0ZSA+Pj0gMTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRpZ2l0cy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBpZiAoZGlnaXRzW2ldKVxyXG4gICAgICAgICAgICAgICAgZmxhZyA9IHRydWU7XHJcbiAgICAgICAgICAgIGlmIChmbGFnKVxyXG4gICAgICAgICAgICAgICAgcmVzdWx0ICs9IGRpZ2l0c1N0cmluZy5jaGFyQXQoZGlnaXRzW2ldKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGZsYWcgPT09IGZhbHNlKVxyXG4gICAgICAgICAgICByZXN1bHQgKz0gZGlnaXRzU3RyaW5nLmNoYXJBdCgwKTtcclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgfVxyXG59XHJcbl9hJHAgPSBMb2NhbEludGVnZXJWYWx1ZUJsb2NrO1xyXG5Mb2NhbEludGVnZXJWYWx1ZUJsb2NrLk5BTUUgPSBcIkludGVnZXJWYWx1ZUJsb2NrXCI7XHJcbigoKSA9PiB7XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoX2EkcC5wcm90b3R5cGUsIFwidmFsdWVIZXhcIiwge1xyXG4gICAgICAgIHNldDogZnVuY3Rpb24gKHYpIHtcclxuICAgICAgICAgICAgdGhpcy52YWx1ZUhleFZpZXcgPSBuZXcgVWludDhBcnJheSh2KTtcclxuICAgICAgICAgICAgdGhpcy5zZXRWYWx1ZUhleCgpO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnZhbHVlSGV4Vmlldy5zbGljZSgpLmJ1ZmZlcjtcclxuICAgICAgICB9LFxyXG4gICAgfSk7XHJcbn0pKCk7XG5cbnZhciBfYSRvO1xyXG5jbGFzcyBJbnRlZ2VyIGV4dGVuZHMgQmFzZUJsb2NrIHtcclxuICAgIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMgPSB7fSkge1xyXG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMsIExvY2FsSW50ZWdlclZhbHVlQmxvY2spO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdDbGFzcyA9IDE7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ051bWJlciA9IDI7XHJcbiAgICB9XHJcbiAgICB0b0JpZ0ludCgpIHtcclxuICAgICAgICBhc3NlcnRCaWdJbnQoKTtcclxuICAgICAgICByZXR1cm4gQmlnSW50KHRoaXMudmFsdWVCbG9jay50b1N0cmluZygpKTtcclxuICAgIH1cclxuICAgIHN0YXRpYyBmcm9tQmlnSW50KHZhbHVlKSB7XHJcbiAgICAgICAgYXNzZXJ0QmlnSW50KCk7XHJcbiAgICAgICAgY29uc3QgYmlnSW50VmFsdWUgPSBCaWdJbnQodmFsdWUpO1xyXG4gICAgICAgIGNvbnN0IHdyaXRlciA9IG5ldyBWaWV3V3JpdGVyKCk7XHJcbiAgICAgICAgY29uc3QgaGV4ID0gYmlnSW50VmFsdWUudG9TdHJpbmcoMTYpLnJlcGxhY2UoL14tLywgXCJcIik7XHJcbiAgICAgICAgY29uc3QgdmlldyA9IG5ldyBVaW50OEFycmF5KHB2dHN1dGlscy5Db252ZXJ0LkZyb21IZXgoaGV4KSk7XHJcbiAgICAgICAgaWYgKGJpZ0ludFZhbHVlIDwgMCkge1xyXG4gICAgICAgICAgICBjb25zdCBmaXJzdCA9IG5ldyBVaW50OEFycmF5KHZpZXcubGVuZ3RoICsgKHZpZXdbMF0gJiAweDgwID8gMSA6IDApKTtcclxuICAgICAgICAgICAgZmlyc3RbMF0gfD0gMHg4MDtcclxuICAgICAgICAgICAgY29uc3QgZmlyc3RJbnQgPSBCaWdJbnQoYDB4JHtwdnRzdXRpbHMuQ29udmVydC5Ub0hleChmaXJzdCl9YCk7XHJcbiAgICAgICAgICAgIGNvbnN0IHNlY29uZEludCA9IGZpcnN0SW50ICsgYmlnSW50VmFsdWU7XHJcbiAgICAgICAgICAgIGNvbnN0IHNlY29uZCA9IHB2dHN1dGlscy5CdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9VaW50OEFycmF5KHB2dHN1dGlscy5Db252ZXJ0LkZyb21IZXgoc2Vjb25kSW50LnRvU3RyaW5nKDE2KSkpO1xyXG4gICAgICAgICAgICBzZWNvbmRbMF0gfD0gMHg4MDtcclxuICAgICAgICAgICAgd3JpdGVyLndyaXRlKHNlY29uZCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBpZiAodmlld1swXSAmIDB4ODApIHtcclxuICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShuZXcgVWludDhBcnJheShbMF0pKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB3cml0ZXIud3JpdGUodmlldyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IHJlcyA9IG5ldyBJbnRlZ2VyKHtcclxuICAgICAgICAgICAgdmFsdWVIZXg6IHdyaXRlci5maW5hbCgpLFxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiByZXM7XHJcbiAgICB9XHJcbiAgICBjb252ZXJ0VG9ERVIoKSB7XHJcbiAgICAgICAgY29uc3QgaW50ZWdlciA9IG5ldyBJbnRlZ2VyKHsgdmFsdWVIZXg6IHRoaXMudmFsdWVCbG9jay52YWx1ZUhleFZpZXcgfSk7XHJcbiAgICAgICAgaW50ZWdlci52YWx1ZUJsb2NrLnRvREVSKCk7XHJcbiAgICAgICAgcmV0dXJuIGludGVnZXI7XHJcbiAgICB9XHJcbiAgICBjb252ZXJ0RnJvbURFUigpIHtcclxuICAgICAgICByZXR1cm4gbmV3IEludGVnZXIoe1xyXG4gICAgICAgICAgICB2YWx1ZUhleDogdGhpcy52YWx1ZUJsb2NrLnZhbHVlSGV4Vmlld1swXSA9PT0gMFxyXG4gICAgICAgICAgICAgICAgPyB0aGlzLnZhbHVlQmxvY2sudmFsdWVIZXhWaWV3LnN1YmFycmF5KDEpXHJcbiAgICAgICAgICAgICAgICA6IHRoaXMudmFsdWVCbG9jay52YWx1ZUhleFZpZXcsXHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBvbkFzY2lpRW5jb2RpbmcoKSB7XHJcbiAgICAgICAgcmV0dXJuIGAke3RoaXMuY29uc3RydWN0b3IuTkFNRX0gOiAke3RoaXMudmFsdWVCbG9jay50b1N0cmluZygpfWA7XHJcbiAgICB9XHJcbn1cclxuX2EkbyA9IEludGVnZXI7XHJcbigoKSA9PiB7XHJcbiAgICB0eXBlU3RvcmUuSW50ZWdlciA9IF9hJG87XHJcbn0pKCk7XHJcbkludGVnZXIuTkFNRSA9IFwiSU5URUdFUlwiO1xuXG52YXIgX2EkbjtcclxuY2xhc3MgRW51bWVyYXRlZCBleHRlbmRzIEludGVnZXIge1xyXG4gICAgY29uc3RydWN0b3IocGFyYW1ldGVycyA9IHt9KSB7XHJcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ0NsYXNzID0gMTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnTnVtYmVyID0gMTA7XHJcbiAgICB9XHJcbn1cclxuX2EkbiA9IEVudW1lcmF0ZWQ7XHJcbigoKSA9PiB7XHJcbiAgICB0eXBlU3RvcmUuRW51bWVyYXRlZCA9IF9hJG47XHJcbn0pKCk7XHJcbkVudW1lcmF0ZWQuTkFNRSA9IFwiRU5VTUVSQVRFRFwiO1xuXG5jbGFzcyBMb2NhbFNpZFZhbHVlQmxvY2sgZXh0ZW5kcyBIZXhCbG9jayhWYWx1ZUJsb2NrKSB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7IHZhbHVlRGVjID0gLTEsIGlzRmlyc3RTaWQgPSBmYWxzZSwgLi4ucGFyYW1ldGVycyB9ID0ge30pIHtcclxuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcclxuICAgICAgICB0aGlzLnZhbHVlRGVjID0gdmFsdWVEZWM7XHJcbiAgICAgICAgdGhpcy5pc0ZpcnN0U2lkID0gaXNGaXJzdFNpZDtcclxuICAgIH1cclxuICAgIGZyb21CRVIoaW5wdXRCdWZmZXIsIGlucHV0T2Zmc2V0LCBpbnB1dExlbmd0aCkge1xyXG4gICAgICAgIGlmICghaW5wdXRMZW5ndGgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGlucHV0T2Zmc2V0O1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBpbnB1dFZpZXcgPSBwdnRzdXRpbHMuQnVmZmVyU291cmNlQ29udmVydGVyLnRvVWludDhBcnJheShpbnB1dEJ1ZmZlcik7XHJcbiAgICAgICAgaWYgKCFjaGVja0J1ZmZlclBhcmFtcyh0aGlzLCBpbnB1dFZpZXcsIGlucHV0T2Zmc2V0LCBpbnB1dExlbmd0aCkpIHtcclxuICAgICAgICAgICAgcmV0dXJuIC0xO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBpbnRCdWZmZXIgPSBpbnB1dFZpZXcuc3ViYXJyYXkoaW5wdXRPZmZzZXQsIGlucHV0T2Zmc2V0ICsgaW5wdXRMZW5ndGgpO1xyXG4gICAgICAgIHRoaXMudmFsdWVIZXhWaWV3ID0gbmV3IFVpbnQ4QXJyYXkoaW5wdXRMZW5ndGgpO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXRMZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICB0aGlzLnZhbHVlSGV4Vmlld1tpXSA9IGludEJ1ZmZlcltpXSAmIDB4N0Y7XHJcbiAgICAgICAgICAgIHRoaXMuYmxvY2tMZW5ndGgrKztcclxuICAgICAgICAgICAgaWYgKChpbnRCdWZmZXJbaV0gJiAweDgwKSA9PT0gMHgwMClcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCB0ZW1wVmlldyA9IG5ldyBVaW50OEFycmF5KHRoaXMuYmxvY2tMZW5ndGgpO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5ibG9ja0xlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIHRlbXBWaWV3W2ldID0gdGhpcy52YWx1ZUhleFZpZXdbaV07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMudmFsdWVIZXhWaWV3ID0gdGVtcFZpZXc7XHJcbiAgICAgICAgaWYgKChpbnRCdWZmZXJbdGhpcy5ibG9ja0xlbmd0aCAtIDFdICYgMHg4MCkgIT09IDB4MDApIHtcclxuICAgICAgICAgICAgdGhpcy5lcnJvciA9IFwiRW5kIG9mIGlucHV0IHJlYWNoZWQgYmVmb3JlIG1lc3NhZ2Ugd2FzIGZ1bGx5IGRlY29kZWRcIjtcclxuICAgICAgICAgICAgcmV0dXJuIC0xO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy52YWx1ZUhleFZpZXdbMF0gPT09IDB4MDApXHJcbiAgICAgICAgICAgIHRoaXMud2FybmluZ3MucHVzaChcIk5lZWRsZXNzbHkgbG9uZyBmb3JtYXQgb2YgU0lEIGVuY29kaW5nXCIpO1xyXG4gICAgICAgIGlmICh0aGlzLmJsb2NrTGVuZ3RoIDw9IDgpXHJcbiAgICAgICAgICAgIHRoaXMudmFsdWVEZWMgPSBwdnV0aWxzLnV0aWxGcm9tQmFzZSh0aGlzLnZhbHVlSGV4VmlldywgNyk7XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuaXNIZXhPbmx5ID0gdHJ1ZTtcclxuICAgICAgICAgICAgdGhpcy53YXJuaW5ncy5wdXNoKFwiVG9vIGJpZyBTSUQgZm9yIGRlY29kaW5nLCBoZXggb25seVwiKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIChpbnB1dE9mZnNldCArIHRoaXMuYmxvY2tMZW5ndGgpO1xyXG4gICAgfVxyXG4gICAgc2V0IHZhbHVlQmlnSW50KHZhbHVlKSB7XHJcbiAgICAgICAgYXNzZXJ0QmlnSW50KCk7XHJcbiAgICAgICAgbGV0IGJpdHMgPSBCaWdJbnQodmFsdWUpLnRvU3RyaW5nKDIpO1xyXG4gICAgICAgIHdoaWxlIChiaXRzLmxlbmd0aCAlIDcpIHtcclxuICAgICAgICAgICAgYml0cyA9IFwiMFwiICsgYml0cztcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgYnl0ZXMgPSBuZXcgVWludDhBcnJheShiaXRzLmxlbmd0aCAvIDcpO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgYnl0ZXNbaV0gPSBwYXJzZUludChiaXRzLnNsaWNlKGkgKiA3LCBpICogNyArIDcpLCAyKSArIChpICsgMSA8IGJ5dGVzLmxlbmd0aCA/IDB4ODAgOiAwKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5mcm9tQkVSKGJ5dGVzLmJ1ZmZlciwgMCwgYnl0ZXMubGVuZ3RoKTtcclxuICAgIH1cclxuICAgIHRvQkVSKHNpemVPbmx5KSB7XHJcbiAgICAgICAgaWYgKHRoaXMuaXNIZXhPbmx5KSB7XHJcbiAgICAgICAgICAgIGlmIChzaXplT25seSlcclxuICAgICAgICAgICAgICAgIHJldHVybiAobmV3IEFycmF5QnVmZmVyKHRoaXMudmFsdWVIZXhWaWV3LmJ5dGVMZW5ndGgpKTtcclxuICAgICAgICAgICAgY29uc3QgY3VyVmlldyA9IHRoaXMudmFsdWVIZXhWaWV3O1xyXG4gICAgICAgICAgICBjb25zdCByZXRWaWV3ID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5ibG9ja0xlbmd0aCk7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgKHRoaXMuYmxvY2tMZW5ndGggLSAxKTsgaSsrKVxyXG4gICAgICAgICAgICAgICAgcmV0Vmlld1tpXSA9IGN1clZpZXdbaV0gfCAweDgwO1xyXG4gICAgICAgICAgICByZXRWaWV3W3RoaXMuYmxvY2tMZW5ndGggLSAxXSA9IGN1clZpZXdbdGhpcy5ibG9ja0xlbmd0aCAtIDFdO1xyXG4gICAgICAgICAgICByZXR1cm4gcmV0Vmlldy5idWZmZXI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IGVuY29kZWRCdWYgPSBwdnV0aWxzLnV0aWxUb0Jhc2UodGhpcy52YWx1ZURlYywgNyk7XHJcbiAgICAgICAgaWYgKGVuY29kZWRCdWYuYnl0ZUxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgICAgICB0aGlzLmVycm9yID0gXCJFcnJvciBkdXJpbmcgZW5jb2RpbmcgU0lEIHZhbHVlXCI7XHJcbiAgICAgICAgICAgIHJldHVybiBFTVBUWV9CVUZGRVI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IHJldFZpZXcgPSBuZXcgVWludDhBcnJheShlbmNvZGVkQnVmLmJ5dGVMZW5ndGgpO1xyXG4gICAgICAgIGlmICghc2l6ZU9ubHkpIHtcclxuICAgICAgICAgICAgY29uc3QgZW5jb2RlZFZpZXcgPSBuZXcgVWludDhBcnJheShlbmNvZGVkQnVmKTtcclxuICAgICAgICAgICAgY29uc3QgbGVuID0gZW5jb2RlZEJ1Zi5ieXRlTGVuZ3RoIC0gMTtcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKylcclxuICAgICAgICAgICAgICAgIHJldFZpZXdbaV0gPSBlbmNvZGVkVmlld1tpXSB8IDB4ODA7XHJcbiAgICAgICAgICAgIHJldFZpZXdbbGVuXSA9IGVuY29kZWRWaWV3W2xlbl07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiByZXRWaWV3O1xyXG4gICAgfVxyXG4gICAgdG9TdHJpbmcoKSB7XHJcbiAgICAgICAgbGV0IHJlc3VsdCA9IFwiXCI7XHJcbiAgICAgICAgaWYgKHRoaXMuaXNIZXhPbmx5KVxyXG4gICAgICAgICAgICByZXN1bHQgPSBwdnRzdXRpbHMuQ29udmVydC5Ub0hleCh0aGlzLnZhbHVlSGV4Vmlldyk7XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmlzRmlyc3RTaWQpIHtcclxuICAgICAgICAgICAgICAgIGxldCBzaWRWYWx1ZSA9IHRoaXMudmFsdWVEZWM7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy52YWx1ZURlYyA8PSAzOSlcclxuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBcIjAuXCI7XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy52YWx1ZURlYyA8PSA3OSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBcIjEuXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpZFZhbHVlIC09IDQwO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gXCIyLlwiO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzaWRWYWx1ZSAtPSA4MDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXN1bHQgKz0gc2lkVmFsdWUudG9TdHJpbmcoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICByZXN1bHQgPSB0aGlzLnZhbHVlRGVjLnRvU3RyaW5nKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICB9XHJcbiAgICB0b0pTT04oKSB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgLi4uc3VwZXIudG9KU09OKCksXHJcbiAgICAgICAgICAgIHZhbHVlRGVjOiB0aGlzLnZhbHVlRGVjLFxyXG4gICAgICAgICAgICBpc0ZpcnN0U2lkOiB0aGlzLmlzRmlyc3RTaWQsXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxufVxyXG5Mb2NhbFNpZFZhbHVlQmxvY2suTkFNRSA9IFwic2lkQmxvY2tcIjtcblxuY2xhc3MgTG9jYWxPYmplY3RJZGVudGlmaWVyVmFsdWVCbG9jayBleHRlbmRzIFZhbHVlQmxvY2sge1xyXG4gICAgY29uc3RydWN0b3IoeyB2YWx1ZSA9IEVNUFRZX1NUUklORywgLi4ucGFyYW1ldGVycyB9ID0ge30pIHtcclxuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcclxuICAgICAgICB0aGlzLnZhbHVlID0gW107XHJcbiAgICAgICAgaWYgKHZhbHVlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZnJvbVN0cmluZyh2YWx1ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZnJvbUJFUihpbnB1dEJ1ZmZlciwgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoKSB7XHJcbiAgICAgICAgbGV0IHJlc3VsdE9mZnNldCA9IGlucHV0T2Zmc2V0O1xyXG4gICAgICAgIHdoaWxlIChpbnB1dExlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgY29uc3Qgc2lkQmxvY2sgPSBuZXcgTG9jYWxTaWRWYWx1ZUJsb2NrKCk7XHJcbiAgICAgICAgICAgIHJlc3VsdE9mZnNldCA9IHNpZEJsb2NrLmZyb21CRVIoaW5wdXRCdWZmZXIsIHJlc3VsdE9mZnNldCwgaW5wdXRMZW5ndGgpO1xyXG4gICAgICAgICAgICBpZiAocmVzdWx0T2Zmc2V0ID09PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5ibG9ja0xlbmd0aCA9IDA7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9yID0gc2lkQmxvY2suZXJyb3I7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0T2Zmc2V0O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICh0aGlzLnZhbHVlLmxlbmd0aCA9PT0gMClcclxuICAgICAgICAgICAgICAgIHNpZEJsb2NrLmlzRmlyc3RTaWQgPSB0cnVlO1xyXG4gICAgICAgICAgICB0aGlzLmJsb2NrTGVuZ3RoICs9IHNpZEJsb2NrLmJsb2NrTGVuZ3RoO1xyXG4gICAgICAgICAgICBpbnB1dExlbmd0aCAtPSBzaWRCbG9jay5ibG9ja0xlbmd0aDtcclxuICAgICAgICAgICAgdGhpcy52YWx1ZS5wdXNoKHNpZEJsb2NrKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdE9mZnNldDtcclxuICAgIH1cclxuICAgIHRvQkVSKHNpemVPbmx5KSB7XHJcbiAgICAgICAgY29uc3QgcmV0QnVmZmVycyA9IFtdO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy52YWx1ZS5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBjb25zdCB2YWx1ZUJ1ZiA9IHRoaXMudmFsdWVbaV0udG9CRVIoc2l6ZU9ubHkpO1xyXG4gICAgICAgICAgICBpZiAodmFsdWVCdWYuYnl0ZUxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5lcnJvciA9IHRoaXMudmFsdWVbaV0uZXJyb3I7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gRU1QVFlfQlVGRkVSO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldEJ1ZmZlcnMucHVzaCh2YWx1ZUJ1Zik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBjb25jYXQocmV0QnVmZmVycyk7XHJcbiAgICB9XHJcbiAgICBmcm9tU3RyaW5nKHN0cmluZykge1xyXG4gICAgICAgIHRoaXMudmFsdWUgPSBbXTtcclxuICAgICAgICBsZXQgcG9zMSA9IDA7XHJcbiAgICAgICAgbGV0IHBvczIgPSAwO1xyXG4gICAgICAgIGxldCBzaWQgPSBcIlwiO1xyXG4gICAgICAgIGxldCBmbGFnID0gZmFsc2U7XHJcbiAgICAgICAgZG8ge1xyXG4gICAgICAgICAgICBwb3MyID0gc3RyaW5nLmluZGV4T2YoXCIuXCIsIHBvczEpO1xyXG4gICAgICAgICAgICBpZiAocG9zMiA9PT0gLTEpXHJcbiAgICAgICAgICAgICAgICBzaWQgPSBzdHJpbmcuc3Vic3RyaW5nKHBvczEpO1xyXG4gICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICBzaWQgPSBzdHJpbmcuc3Vic3RyaW5nKHBvczEsIHBvczIpO1xyXG4gICAgICAgICAgICBwb3MxID0gcG9zMiArIDE7XHJcbiAgICAgICAgICAgIGlmIChmbGFnKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBzaWRCbG9jayA9IHRoaXMudmFsdWVbMF07XHJcbiAgICAgICAgICAgICAgICBsZXQgcGx1cyA9IDA7XHJcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKHNpZEJsb2NrLnZhbHVlRGVjKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAwOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDE6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBsdXMgPSA0MDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAyOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwbHVzID0gODA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudmFsdWUgPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgY29uc3QgcGFyc2VkU0lEID0gcGFyc2VJbnQoc2lkLCAxMCk7XHJcbiAgICAgICAgICAgICAgICBpZiAoaXNOYU4ocGFyc2VkU0lEKSlcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICBzaWRCbG9jay52YWx1ZURlYyA9IHBhcnNlZFNJRCArIHBsdXM7XHJcbiAgICAgICAgICAgICAgICBmbGFnID0gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBzaWRCbG9jayA9IG5ldyBMb2NhbFNpZFZhbHVlQmxvY2soKTtcclxuICAgICAgICAgICAgICAgIGlmIChzaWQgPiBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUikge1xyXG4gICAgICAgICAgICAgICAgICAgIGFzc2VydEJpZ0ludCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpZFZhbHVlID0gQmlnSW50KHNpZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgc2lkQmxvY2sudmFsdWVCaWdJbnQgPSBzaWRWYWx1ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHNpZEJsb2NrLnZhbHVlRGVjID0gcGFyc2VJbnQoc2lkLCAxMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzTmFOKHNpZEJsb2NrLnZhbHVlRGVjKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLnZhbHVlLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNpZEJsb2NrLmlzRmlyc3RTaWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIGZsYWcgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdGhpcy52YWx1ZS5wdXNoKHNpZEJsb2NrKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gd2hpbGUgKHBvczIgIT09IC0xKTtcclxuICAgIH1cclxuICAgIHRvU3RyaW5nKCkge1xyXG4gICAgICAgIGxldCByZXN1bHQgPSBcIlwiO1xyXG4gICAgICAgIGxldCBpc0hleE9ubHkgPSBmYWxzZTtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMudmFsdWUubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgaXNIZXhPbmx5ID0gdGhpcy52YWx1ZVtpXS5pc0hleE9ubHk7XHJcbiAgICAgICAgICAgIGxldCBzaWRTdHIgPSB0aGlzLnZhbHVlW2ldLnRvU3RyaW5nKCk7XHJcbiAgICAgICAgICAgIGlmIChpICE9PSAwKVxyXG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gYCR7cmVzdWx0fS5gO1xyXG4gICAgICAgICAgICBpZiAoaXNIZXhPbmx5KSB7XHJcbiAgICAgICAgICAgICAgICBzaWRTdHIgPSBgeyR7c2lkU3RyfX1gO1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMudmFsdWVbaV0uaXNGaXJzdFNpZClcclxuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBgMi57JHtzaWRTdHJ9IC0gODB9YDtcclxuICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICByZXN1bHQgKz0gc2lkU3RyO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgIHJlc3VsdCArPSBzaWRTdHI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICB9XHJcbiAgICB0b0pTT04oKSB7XHJcbiAgICAgICAgY29uc3Qgb2JqZWN0ID0ge1xyXG4gICAgICAgICAgICAuLi5zdXBlci50b0pTT04oKSxcclxuICAgICAgICAgICAgdmFsdWU6IHRoaXMudG9TdHJpbmcoKSxcclxuICAgICAgICAgICAgc2lkQXJyYXk6IFtdLFxyXG4gICAgICAgIH07XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnZhbHVlLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIG9iamVjdC5zaWRBcnJheS5wdXNoKHRoaXMudmFsdWVbaV0udG9KU09OKCkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gb2JqZWN0O1xyXG4gICAgfVxyXG59XHJcbkxvY2FsT2JqZWN0SWRlbnRpZmllclZhbHVlQmxvY2suTkFNRSA9IFwiT2JqZWN0SWRlbnRpZmllclZhbHVlQmxvY2tcIjtcblxudmFyIF9hJG07XHJcbmNsYXNzIE9iamVjdElkZW50aWZpZXIgZXh0ZW5kcyBCYXNlQmxvY2sge1xyXG4gICAgY29uc3RydWN0b3IocGFyYW1ldGVycyA9IHt9KSB7XHJcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycywgTG9jYWxPYmplY3RJZGVudGlmaWVyVmFsdWVCbG9jayk7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ0NsYXNzID0gMTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnTnVtYmVyID0gNjtcclxuICAgIH1cclxuICAgIGdldFZhbHVlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlQmxvY2sudG9TdHJpbmcoKTtcclxuICAgIH1cclxuICAgIHNldFZhbHVlKHZhbHVlKSB7XHJcbiAgICAgICAgdGhpcy52YWx1ZUJsb2NrLmZyb21TdHJpbmcodmFsdWUpO1xyXG4gICAgfVxyXG4gICAgb25Bc2NpaUVuY29kaW5nKCkge1xyXG4gICAgICAgIHJldHVybiBgJHt0aGlzLmNvbnN0cnVjdG9yLk5BTUV9IDogJHt0aGlzLnZhbHVlQmxvY2sudG9TdHJpbmcoKSB8fCBcImVtcHR5XCJ9YDtcclxuICAgIH1cclxuICAgIHRvSlNPTigpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAuLi5zdXBlci50b0pTT04oKSxcclxuICAgICAgICAgICAgdmFsdWU6IHRoaXMuZ2V0VmFsdWUoKSxcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG59XHJcbl9hJG0gPSBPYmplY3RJZGVudGlmaWVyO1xyXG4oKCkgPT4ge1xyXG4gICAgdHlwZVN0b3JlLk9iamVjdElkZW50aWZpZXIgPSBfYSRtO1xyXG59KSgpO1xyXG5PYmplY3RJZGVudGlmaWVyLk5BTUUgPSBcIk9CSkVDVCBJREVOVElGSUVSXCI7XG5cbmNsYXNzIExvY2FsUmVsYXRpdmVTaWRWYWx1ZUJsb2NrIGV4dGVuZHMgSGV4QmxvY2soTG9jYWxCYXNlQmxvY2spIHtcclxuICAgIGNvbnN0cnVjdG9yKHsgdmFsdWVEZWMgPSAwLCAuLi5wYXJhbWV0ZXJzIH0gPSB7fSkge1xyXG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xyXG4gICAgICAgIHRoaXMudmFsdWVEZWMgPSB2YWx1ZURlYztcclxuICAgIH1cclxuICAgIGZyb21CRVIoaW5wdXRCdWZmZXIsIGlucHV0T2Zmc2V0LCBpbnB1dExlbmd0aCkge1xyXG4gICAgICAgIGlmIChpbnB1dExlbmd0aCA9PT0gMClcclxuICAgICAgICAgICAgcmV0dXJuIGlucHV0T2Zmc2V0O1xyXG4gICAgICAgIGNvbnN0IGlucHV0VmlldyA9IHB2dHN1dGlscy5CdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9VaW50OEFycmF5KGlucHV0QnVmZmVyKTtcclxuICAgICAgICBpZiAoIWNoZWNrQnVmZmVyUGFyYW1zKHRoaXMsIGlucHV0VmlldywgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoKSlcclxuICAgICAgICAgICAgcmV0dXJuIC0xO1xyXG4gICAgICAgIGNvbnN0IGludEJ1ZmZlciA9IGlucHV0Vmlldy5zdWJhcnJheShpbnB1dE9mZnNldCwgaW5wdXRPZmZzZXQgKyBpbnB1dExlbmd0aCk7XHJcbiAgICAgICAgdGhpcy52YWx1ZUhleFZpZXcgPSBuZXcgVWludDhBcnJheShpbnB1dExlbmd0aCk7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbnB1dExlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIHRoaXMudmFsdWVIZXhWaWV3W2ldID0gaW50QnVmZmVyW2ldICYgMHg3RjtcclxuICAgICAgICAgICAgdGhpcy5ibG9ja0xlbmd0aCsrO1xyXG4gICAgICAgICAgICBpZiAoKGludEJ1ZmZlcltpXSAmIDB4ODApID09PSAweDAwKVxyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IHRlbXBWaWV3ID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5ibG9ja0xlbmd0aCk7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmJsb2NrTGVuZ3RoOyBpKyspXHJcbiAgICAgICAgICAgIHRlbXBWaWV3W2ldID0gdGhpcy52YWx1ZUhleFZpZXdbaV07XHJcbiAgICAgICAgdGhpcy52YWx1ZUhleFZpZXcgPSB0ZW1wVmlldztcclxuICAgICAgICBpZiAoKGludEJ1ZmZlclt0aGlzLmJsb2NrTGVuZ3RoIC0gMV0gJiAweDgwKSAhPT0gMHgwMCkge1xyXG4gICAgICAgICAgICB0aGlzLmVycm9yID0gXCJFbmQgb2YgaW5wdXQgcmVhY2hlZCBiZWZvcmUgbWVzc2FnZSB3YXMgZnVsbHkgZGVjb2RlZFwiO1xyXG4gICAgICAgICAgICByZXR1cm4gLTE7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLnZhbHVlSGV4Vmlld1swXSA9PT0gMHgwMClcclxuICAgICAgICAgICAgdGhpcy53YXJuaW5ncy5wdXNoKFwiTmVlZGxlc3NseSBsb25nIGZvcm1hdCBvZiBTSUQgZW5jb2RpbmdcIik7XHJcbiAgICAgICAgaWYgKHRoaXMuYmxvY2tMZW5ndGggPD0gOClcclxuICAgICAgICAgICAgdGhpcy52YWx1ZURlYyA9IHB2dXRpbHMudXRpbEZyb21CYXNlKHRoaXMudmFsdWVIZXhWaWV3LCA3KTtcclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5pc0hleE9ubHkgPSB0cnVlO1xyXG4gICAgICAgICAgICB0aGlzLndhcm5pbmdzLnB1c2goXCJUb28gYmlnIFNJRCBmb3IgZGVjb2RpbmcsIGhleCBvbmx5XCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gKGlucHV0T2Zmc2V0ICsgdGhpcy5ibG9ja0xlbmd0aCk7XHJcbiAgICB9XHJcbiAgICB0b0JFUihzaXplT25seSkge1xyXG4gICAgICAgIGlmICh0aGlzLmlzSGV4T25seSkge1xyXG4gICAgICAgICAgICBpZiAoc2l6ZU9ubHkpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gKG5ldyBBcnJheUJ1ZmZlcih0aGlzLnZhbHVlSGV4Vmlldy5ieXRlTGVuZ3RoKSk7XHJcbiAgICAgICAgICAgIGNvbnN0IGN1clZpZXcgPSB0aGlzLnZhbHVlSGV4VmlldztcclxuICAgICAgICAgICAgY29uc3QgcmV0VmlldyA9IG5ldyBVaW50OEFycmF5KHRoaXMuYmxvY2tMZW5ndGgpO1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8ICh0aGlzLmJsb2NrTGVuZ3RoIC0gMSk7IGkrKylcclxuICAgICAgICAgICAgICAgIHJldFZpZXdbaV0gPSBjdXJWaWV3W2ldIHwgMHg4MDtcclxuICAgICAgICAgICAgcmV0Vmlld1t0aGlzLmJsb2NrTGVuZ3RoIC0gMV0gPSBjdXJWaWV3W3RoaXMuYmxvY2tMZW5ndGggLSAxXTtcclxuICAgICAgICAgICAgcmV0dXJuIHJldFZpZXcuYnVmZmVyO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBlbmNvZGVkQnVmID0gcHZ1dGlscy51dGlsVG9CYXNlKHRoaXMudmFsdWVEZWMsIDcpO1xyXG4gICAgICAgIGlmIChlbmNvZGVkQnVmLmJ5dGVMZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgdGhpcy5lcnJvciA9IFwiRXJyb3IgZHVyaW5nIGVuY29kaW5nIFNJRCB2YWx1ZVwiO1xyXG4gICAgICAgICAgICByZXR1cm4gRU1QVFlfQlVGRkVSO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCByZXRWaWV3ID0gbmV3IFVpbnQ4QXJyYXkoZW5jb2RlZEJ1Zi5ieXRlTGVuZ3RoKTtcclxuICAgICAgICBpZiAoIXNpemVPbmx5KSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGVuY29kZWRWaWV3ID0gbmV3IFVpbnQ4QXJyYXkoZW5jb2RlZEJ1Zik7XHJcbiAgICAgICAgICAgIGNvbnN0IGxlbiA9IGVuY29kZWRCdWYuYnl0ZUxlbmd0aCAtIDE7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspXHJcbiAgICAgICAgICAgICAgICByZXRWaWV3W2ldID0gZW5jb2RlZFZpZXdbaV0gfCAweDgwO1xyXG4gICAgICAgICAgICByZXRWaWV3W2xlbl0gPSBlbmNvZGVkVmlld1tsZW5dO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcmV0Vmlldy5idWZmZXI7XHJcbiAgICB9XHJcbiAgICB0b1N0cmluZygpIHtcclxuICAgICAgICBsZXQgcmVzdWx0ID0gXCJcIjtcclxuICAgICAgICBpZiAodGhpcy5pc0hleE9ubHkpXHJcbiAgICAgICAgICAgIHJlc3VsdCA9IHB2dHN1dGlscy5Db252ZXJ0LlRvSGV4KHRoaXMudmFsdWVIZXhWaWV3KTtcclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgcmVzdWx0ID0gdGhpcy52YWx1ZURlYy50b1N0cmluZygpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgfVxyXG4gICAgdG9KU09OKCkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIC4uLnN1cGVyLnRvSlNPTigpLFxyXG4gICAgICAgICAgICB2YWx1ZURlYzogdGhpcy52YWx1ZURlYyxcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG59XHJcbkxvY2FsUmVsYXRpdmVTaWRWYWx1ZUJsb2NrLk5BTUUgPSBcInJlbGF0aXZlU2lkQmxvY2tcIjtcblxuY2xhc3MgTG9jYWxSZWxhdGl2ZU9iamVjdElkZW50aWZpZXJWYWx1ZUJsb2NrIGV4dGVuZHMgVmFsdWVCbG9jayB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7IHZhbHVlID0gRU1QVFlfU1RSSU5HLCAuLi5wYXJhbWV0ZXJzIH0gPSB7fSkge1xyXG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xyXG4gICAgICAgIHRoaXMudmFsdWUgPSBbXTtcclxuICAgICAgICBpZiAodmFsdWUpIHtcclxuICAgICAgICAgICAgdGhpcy5mcm9tU3RyaW5nKHZhbHVlKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBmcm9tQkVSKGlucHV0QnVmZmVyLCBpbnB1dE9mZnNldCwgaW5wdXRMZW5ndGgpIHtcclxuICAgICAgICBsZXQgcmVzdWx0T2Zmc2V0ID0gaW5wdXRPZmZzZXQ7XHJcbiAgICAgICAgd2hpbGUgKGlucHV0TGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICBjb25zdCBzaWRCbG9jayA9IG5ldyBMb2NhbFJlbGF0aXZlU2lkVmFsdWVCbG9jaygpO1xyXG4gICAgICAgICAgICByZXN1bHRPZmZzZXQgPSBzaWRCbG9jay5mcm9tQkVSKGlucHV0QnVmZmVyLCByZXN1bHRPZmZzZXQsIGlucHV0TGVuZ3RoKTtcclxuICAgICAgICAgICAgaWYgKHJlc3VsdE9mZnNldCA9PT0gLTEpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuYmxvY2tMZW5ndGggPSAwO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5lcnJvciA9IHNpZEJsb2NrLmVycm9yO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdE9mZnNldDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aGlzLmJsb2NrTGVuZ3RoICs9IHNpZEJsb2NrLmJsb2NrTGVuZ3RoO1xyXG4gICAgICAgICAgICBpbnB1dExlbmd0aCAtPSBzaWRCbG9jay5ibG9ja0xlbmd0aDtcclxuICAgICAgICAgICAgdGhpcy52YWx1ZS5wdXNoKHNpZEJsb2NrKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdE9mZnNldDtcclxuICAgIH1cclxuICAgIHRvQkVSKHNpemVPbmx5LCB3cml0ZXIpIHtcclxuICAgICAgICBjb25zdCByZXRCdWZmZXJzID0gW107XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnZhbHVlLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlQnVmID0gdGhpcy52YWx1ZVtpXS50b0JFUihzaXplT25seSk7XHJcbiAgICAgICAgICAgIGlmICh2YWx1ZUJ1Zi5ieXRlTGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9yID0gdGhpcy52YWx1ZVtpXS5lcnJvcjtcclxuICAgICAgICAgICAgICAgIHJldHVybiBFTVBUWV9CVUZGRVI7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0QnVmZmVycy5wdXNoKHZhbHVlQnVmKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGNvbmNhdChyZXRCdWZmZXJzKTtcclxuICAgIH1cclxuICAgIGZyb21TdHJpbmcoc3RyaW5nKSB7XHJcbiAgICAgICAgdGhpcy52YWx1ZSA9IFtdO1xyXG4gICAgICAgIGxldCBwb3MxID0gMDtcclxuICAgICAgICBsZXQgcG9zMiA9IDA7XHJcbiAgICAgICAgbGV0IHNpZCA9IFwiXCI7XHJcbiAgICAgICAgZG8ge1xyXG4gICAgICAgICAgICBwb3MyID0gc3RyaW5nLmluZGV4T2YoXCIuXCIsIHBvczEpO1xyXG4gICAgICAgICAgICBpZiAocG9zMiA9PT0gLTEpXHJcbiAgICAgICAgICAgICAgICBzaWQgPSBzdHJpbmcuc3Vic3RyaW5nKHBvczEpO1xyXG4gICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICBzaWQgPSBzdHJpbmcuc3Vic3RyaW5nKHBvczEsIHBvczIpO1xyXG4gICAgICAgICAgICBwb3MxID0gcG9zMiArIDE7XHJcbiAgICAgICAgICAgIGNvbnN0IHNpZEJsb2NrID0gbmV3IExvY2FsUmVsYXRpdmVTaWRWYWx1ZUJsb2NrKCk7XHJcbiAgICAgICAgICAgIHNpZEJsb2NrLnZhbHVlRGVjID0gcGFyc2VJbnQoc2lkLCAxMCk7XHJcbiAgICAgICAgICAgIGlmIChpc05hTihzaWRCbG9jay52YWx1ZURlYykpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgdGhpcy52YWx1ZS5wdXNoKHNpZEJsb2NrKTtcclxuICAgICAgICB9IHdoaWxlIChwb3MyICE9PSAtMSk7XHJcbiAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcbiAgICB0b1N0cmluZygpIHtcclxuICAgICAgICBsZXQgcmVzdWx0ID0gXCJcIjtcclxuICAgICAgICBsZXQgaXNIZXhPbmx5ID0gZmFsc2U7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnZhbHVlLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlzSGV4T25seSA9IHRoaXMudmFsdWVbaV0uaXNIZXhPbmx5O1xyXG4gICAgICAgICAgICBsZXQgc2lkU3RyID0gdGhpcy52YWx1ZVtpXS50b1N0cmluZygpO1xyXG4gICAgICAgICAgICBpZiAoaSAhPT0gMClcclxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGAke3Jlc3VsdH0uYDtcclxuICAgICAgICAgICAgaWYgKGlzSGV4T25seSkge1xyXG4gICAgICAgICAgICAgICAgc2lkU3RyID0gYHske3NpZFN0cn19YDtcclxuICAgICAgICAgICAgICAgIHJlc3VsdCArPSBzaWRTdHI7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgcmVzdWx0ICs9IHNpZFN0cjtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH1cclxuICAgIHRvSlNPTigpIHtcclxuICAgICAgICBjb25zdCBvYmplY3QgPSB7XHJcbiAgICAgICAgICAgIC4uLnN1cGVyLnRvSlNPTigpLFxyXG4gICAgICAgICAgICB2YWx1ZTogdGhpcy50b1N0cmluZygpLFxyXG4gICAgICAgICAgICBzaWRBcnJheTogW10sXHJcbiAgICAgICAgfTtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMudmFsdWUubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgICAgIG9iamVjdC5zaWRBcnJheS5wdXNoKHRoaXMudmFsdWVbaV0udG9KU09OKCkpO1xyXG4gICAgICAgIHJldHVybiBvYmplY3Q7XHJcbiAgICB9XHJcbn1cclxuTG9jYWxSZWxhdGl2ZU9iamVjdElkZW50aWZpZXJWYWx1ZUJsb2NrLk5BTUUgPSBcIlJlbGF0aXZlT2JqZWN0SWRlbnRpZmllclZhbHVlQmxvY2tcIjtcblxudmFyIF9hJGw7XHJcbmNsYXNzIFJlbGF0aXZlT2JqZWN0SWRlbnRpZmllciBleHRlbmRzIEJhc2VCbG9jayB7XHJcbiAgICBjb25zdHJ1Y3RvcihwYXJhbWV0ZXJzID0ge30pIHtcclxuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzLCBMb2NhbFJlbGF0aXZlT2JqZWN0SWRlbnRpZmllclZhbHVlQmxvY2spO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdDbGFzcyA9IDE7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ051bWJlciA9IDEzO1xyXG4gICAgfVxyXG4gICAgZ2V0VmFsdWUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWVCbG9jay50b1N0cmluZygpO1xyXG4gICAgfVxyXG4gICAgc2V0VmFsdWUodmFsdWUpIHtcclxuICAgICAgICB0aGlzLnZhbHVlQmxvY2suZnJvbVN0cmluZyh2YWx1ZSk7XHJcbiAgICB9XHJcbiAgICBvbkFzY2lpRW5jb2RpbmcoKSB7XHJcbiAgICAgICAgcmV0dXJuIGAke3RoaXMuY29uc3RydWN0b3IuTkFNRX0gOiAke3RoaXMudmFsdWVCbG9jay50b1N0cmluZygpIHx8IFwiZW1wdHlcIn1gO1xyXG4gICAgfVxyXG4gICAgdG9KU09OKCkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIC4uLnN1cGVyLnRvSlNPTigpLFxyXG4gICAgICAgICAgICB2YWx1ZTogdGhpcy5nZXRWYWx1ZSgpLFxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbn1cclxuX2EkbCA9IFJlbGF0aXZlT2JqZWN0SWRlbnRpZmllcjtcclxuKCgpID0+IHtcclxuICAgIHR5cGVTdG9yZS5SZWxhdGl2ZU9iamVjdElkZW50aWZpZXIgPSBfYSRsO1xyXG59KSgpO1xyXG5SZWxhdGl2ZU9iamVjdElkZW50aWZpZXIuTkFNRSA9IFwiUmVsYXRpdmVPYmplY3RJZGVudGlmaWVyXCI7XG5cbnZhciBfYSRrO1xyXG5jbGFzcyBTZXF1ZW5jZSBleHRlbmRzIENvbnN0cnVjdGVkIHtcclxuICAgIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMgPSB7fSkge1xyXG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdDbGFzcyA9IDE7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ051bWJlciA9IDE2O1xyXG4gICAgfVxyXG59XHJcbl9hJGsgPSBTZXF1ZW5jZTtcclxuKCgpID0+IHtcclxuICAgIHR5cGVTdG9yZS5TZXF1ZW5jZSA9IF9hJGs7XHJcbn0pKCk7XHJcblNlcXVlbmNlLk5BTUUgPSBcIlNFUVVFTkNFXCI7XG5cbnZhciBfYSRqO1xyXG5jbGFzcyBTZXQgZXh0ZW5kcyBDb25zdHJ1Y3RlZCB7XHJcbiAgICBjb25zdHJ1Y3RvcihwYXJhbWV0ZXJzID0ge30pIHtcclxuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnQ2xhc3MgPSAxO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdOdW1iZXIgPSAxNztcclxuICAgIH1cclxufVxyXG5fYSRqID0gU2V0O1xyXG4oKCkgPT4ge1xyXG4gICAgdHlwZVN0b3JlLlNldCA9IF9hJGo7XHJcbn0pKCk7XHJcblNldC5OQU1FID0gXCJTRVRcIjtcblxuY2xhc3MgTG9jYWxTdHJpbmdWYWx1ZUJsb2NrIGV4dGVuZHMgSGV4QmxvY2soVmFsdWVCbG9jaykge1xyXG4gICAgY29uc3RydWN0b3IoeyAuLi5wYXJhbWV0ZXJzIH0gPSB7fSkge1xyXG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xyXG4gICAgICAgIHRoaXMuaXNIZXhPbmx5ID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLnZhbHVlID0gRU1QVFlfU1RSSU5HO1xyXG4gICAgfVxyXG4gICAgdG9KU09OKCkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIC4uLnN1cGVyLnRvSlNPTigpLFxyXG4gICAgICAgICAgICB2YWx1ZTogdGhpcy52YWx1ZSxcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG59XHJcbkxvY2FsU3RyaW5nVmFsdWVCbG9jay5OQU1FID0gXCJTdHJpbmdWYWx1ZUJsb2NrXCI7XG5cbmNsYXNzIExvY2FsU2ltcGxlU3RyaW5nVmFsdWVCbG9jayBleHRlbmRzIExvY2FsU3RyaW5nVmFsdWVCbG9jayB7XHJcbn1cclxuTG9jYWxTaW1wbGVTdHJpbmdWYWx1ZUJsb2NrLk5BTUUgPSBcIlNpbXBsZVN0cmluZ1ZhbHVlQmxvY2tcIjtcblxuY2xhc3MgTG9jYWxTaW1wbGVTdHJpbmdCbG9jayBleHRlbmRzIEJhc2VTdHJpbmdCbG9jayB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7IC4uLnBhcmFtZXRlcnMgfSA9IHt9KSB7XHJcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycywgTG9jYWxTaW1wbGVTdHJpbmdWYWx1ZUJsb2NrKTtcclxuICAgIH1cclxuICAgIGZyb21CdWZmZXIoaW5wdXRCdWZmZXIpIHtcclxuICAgICAgICB0aGlzLnZhbHVlQmxvY2sudmFsdWUgPSBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIHB2dHN1dGlscy5CdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9VaW50OEFycmF5KGlucHV0QnVmZmVyKSk7XHJcbiAgICB9XHJcbiAgICBmcm9tU3RyaW5nKGlucHV0U3RyaW5nKSB7XHJcbiAgICAgICAgY29uc3Qgc3RyTGVuID0gaW5wdXRTdHJpbmcubGVuZ3RoO1xyXG4gICAgICAgIGNvbnN0IHZpZXcgPSB0aGlzLnZhbHVlQmxvY2sudmFsdWVIZXhWaWV3ID0gbmV3IFVpbnQ4QXJyYXkoc3RyTGVuKTtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHN0ckxlbjsgaSsrKVxyXG4gICAgICAgICAgICB2aWV3W2ldID0gaW5wdXRTdHJpbmcuY2hhckNvZGVBdChpKTtcclxuICAgICAgICB0aGlzLnZhbHVlQmxvY2sudmFsdWUgPSBpbnB1dFN0cmluZztcclxuICAgIH1cclxufVxyXG5Mb2NhbFNpbXBsZVN0cmluZ0Jsb2NrLk5BTUUgPSBcIlNJTVBMRSBTVFJJTkdcIjtcblxuY2xhc3MgTG9jYWxVdGY4U3RyaW5nVmFsdWVCbG9jayBleHRlbmRzIExvY2FsU2ltcGxlU3RyaW5nQmxvY2sge1xyXG4gICAgZnJvbUJ1ZmZlcihpbnB1dEJ1ZmZlcikge1xyXG4gICAgICAgIHRoaXMudmFsdWVCbG9jay52YWx1ZUhleFZpZXcgPSBwdnRzdXRpbHMuQnVmZmVyU291cmNlQ29udmVydGVyLnRvVWludDhBcnJheShpbnB1dEJ1ZmZlcik7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgdGhpcy52YWx1ZUJsb2NrLnZhbHVlID0gcHZ0c3V0aWxzLkNvbnZlcnQuVG9VdGY4U3RyaW5nKGlucHV0QnVmZmVyKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGV4KSB7XHJcbiAgICAgICAgICAgIHRoaXMud2FybmluZ3MucHVzaChgRXJyb3IgZHVyaW5nIFwiZGVjb2RlVVJJQ29tcG9uZW50XCI6ICR7ZXh9LCB1c2luZyByYXcgc3RyaW5nYCk7XHJcbiAgICAgICAgICAgIHRoaXMudmFsdWVCbG9jay52YWx1ZSA9IHB2dHN1dGlscy5Db252ZXJ0LlRvQmluYXJ5KGlucHV0QnVmZmVyKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBmcm9tU3RyaW5nKGlucHV0U3RyaW5nKSB7XHJcbiAgICAgICAgdGhpcy52YWx1ZUJsb2NrLnZhbHVlSGV4VmlldyA9IG5ldyBVaW50OEFycmF5KHB2dHN1dGlscy5Db252ZXJ0LkZyb21VdGY4U3RyaW5nKGlucHV0U3RyaW5nKSk7XHJcbiAgICAgICAgdGhpcy52YWx1ZUJsb2NrLnZhbHVlID0gaW5wdXRTdHJpbmc7XHJcbiAgICB9XHJcbn1cclxuTG9jYWxVdGY4U3RyaW5nVmFsdWVCbG9jay5OQU1FID0gXCJVdGY4U3RyaW5nVmFsdWVCbG9ja1wiO1xuXG52YXIgX2EkaTtcclxuY2xhc3MgVXRmOFN0cmluZyBleHRlbmRzIExvY2FsVXRmOFN0cmluZ1ZhbHVlQmxvY2sge1xyXG4gICAgY29uc3RydWN0b3IocGFyYW1ldGVycyA9IHt9KSB7XHJcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ0NsYXNzID0gMTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnTnVtYmVyID0gMTI7XHJcbiAgICB9XHJcbn1cclxuX2EkaSA9IFV0ZjhTdHJpbmc7XHJcbigoKSA9PiB7XHJcbiAgICB0eXBlU3RvcmUuVXRmOFN0cmluZyA9IF9hJGk7XHJcbn0pKCk7XHJcblV0ZjhTdHJpbmcuTkFNRSA9IFwiVVRGOFN0cmluZ1wiO1xuXG5jbGFzcyBMb2NhbEJtcFN0cmluZ1ZhbHVlQmxvY2sgZXh0ZW5kcyBMb2NhbFNpbXBsZVN0cmluZ0Jsb2NrIHtcclxuICAgIGZyb21CdWZmZXIoaW5wdXRCdWZmZXIpIHtcclxuICAgICAgICB0aGlzLnZhbHVlQmxvY2sudmFsdWUgPSBwdnRzdXRpbHMuQ29udmVydC5Ub1V0ZjE2U3RyaW5nKGlucHV0QnVmZmVyKTtcclxuICAgICAgICB0aGlzLnZhbHVlQmxvY2sudmFsdWVIZXhWaWV3ID0gcHZ0c3V0aWxzLkJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b1VpbnQ4QXJyYXkoaW5wdXRCdWZmZXIpO1xyXG4gICAgfVxyXG4gICAgZnJvbVN0cmluZyhpbnB1dFN0cmluZykge1xyXG4gICAgICAgIHRoaXMudmFsdWVCbG9jay52YWx1ZSA9IGlucHV0U3RyaW5nO1xyXG4gICAgICAgIHRoaXMudmFsdWVCbG9jay52YWx1ZUhleFZpZXcgPSBuZXcgVWludDhBcnJheShwdnRzdXRpbHMuQ29udmVydC5Gcm9tVXRmMTZTdHJpbmcoaW5wdXRTdHJpbmcpKTtcclxuICAgIH1cclxufVxyXG5Mb2NhbEJtcFN0cmluZ1ZhbHVlQmxvY2suTkFNRSA9IFwiQm1wU3RyaW5nVmFsdWVCbG9ja1wiO1xuXG52YXIgX2EkaDtcclxuY2xhc3MgQm1wU3RyaW5nIGV4dGVuZHMgTG9jYWxCbXBTdHJpbmdWYWx1ZUJsb2NrIHtcclxuICAgIGNvbnN0cnVjdG9yKHsgLi4ucGFyYW1ldGVycyB9ID0ge30pIHtcclxuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnQ2xhc3MgPSAxO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdOdW1iZXIgPSAzMDtcclxuICAgIH1cclxufVxyXG5fYSRoID0gQm1wU3RyaW5nO1xyXG4oKCkgPT4ge1xyXG4gICAgdHlwZVN0b3JlLkJtcFN0cmluZyA9IF9hJGg7XHJcbn0pKCk7XHJcbkJtcFN0cmluZy5OQU1FID0gXCJCTVBTdHJpbmdcIjtcblxuY2xhc3MgTG9jYWxVbml2ZXJzYWxTdHJpbmdWYWx1ZUJsb2NrIGV4dGVuZHMgTG9jYWxTaW1wbGVTdHJpbmdCbG9jayB7XHJcbiAgICBmcm9tQnVmZmVyKGlucHV0QnVmZmVyKSB7XHJcbiAgICAgICAgY29uc3QgY29weUJ1ZmZlciA9IEFycmF5QnVmZmVyLmlzVmlldyhpbnB1dEJ1ZmZlcikgPyBpbnB1dEJ1ZmZlci5zbGljZSgpLmJ1ZmZlciA6IGlucHV0QnVmZmVyLnNsaWNlKDApO1xyXG4gICAgICAgIGNvbnN0IHZhbHVlVmlldyA9IG5ldyBVaW50OEFycmF5KGNvcHlCdWZmZXIpO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWVWaWV3Lmxlbmd0aDsgaSArPSA0KSB7XHJcbiAgICAgICAgICAgIHZhbHVlVmlld1tpXSA9IHZhbHVlVmlld1tpICsgM107XHJcbiAgICAgICAgICAgIHZhbHVlVmlld1tpICsgMV0gPSB2YWx1ZVZpZXdbaSArIDJdO1xyXG4gICAgICAgICAgICB2YWx1ZVZpZXdbaSArIDJdID0gMHgwMDtcclxuICAgICAgICAgICAgdmFsdWVWaWV3W2kgKyAzXSA9IDB4MDA7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMudmFsdWVCbG9jay52YWx1ZSA9IFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCwgbmV3IFVpbnQzMkFycmF5KGNvcHlCdWZmZXIpKTtcclxuICAgIH1cclxuICAgIGZyb21TdHJpbmcoaW5wdXRTdHJpbmcpIHtcclxuICAgICAgICBjb25zdCBzdHJMZW5ndGggPSBpbnB1dFN0cmluZy5sZW5ndGg7XHJcbiAgICAgICAgY29uc3QgdmFsdWVIZXhWaWV3ID0gdGhpcy52YWx1ZUJsb2NrLnZhbHVlSGV4VmlldyA9IG5ldyBVaW50OEFycmF5KHN0ckxlbmd0aCAqIDQpO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3RyTGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgY29uc3QgY29kZUJ1ZiA9IHB2dXRpbHMudXRpbFRvQmFzZShpbnB1dFN0cmluZy5jaGFyQ29kZUF0KGkpLCA4KTtcclxuICAgICAgICAgICAgY29uc3QgY29kZVZpZXcgPSBuZXcgVWludDhBcnJheShjb2RlQnVmKTtcclxuICAgICAgICAgICAgaWYgKGNvZGVWaWV3Lmxlbmd0aCA+IDQpXHJcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgY29uc3QgZGlmID0gNCAtIGNvZGVWaWV3Lmxlbmd0aDtcclxuICAgICAgICAgICAgZm9yIChsZXQgaiA9IChjb2RlVmlldy5sZW5ndGggLSAxKTsgaiA+PSAwOyBqLS0pXHJcbiAgICAgICAgICAgICAgICB2YWx1ZUhleFZpZXdbaSAqIDQgKyBqICsgZGlmXSA9IGNvZGVWaWV3W2pdO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnZhbHVlQmxvY2sudmFsdWUgPSBpbnB1dFN0cmluZztcclxuICAgIH1cclxufVxyXG5Mb2NhbFVuaXZlcnNhbFN0cmluZ1ZhbHVlQmxvY2suTkFNRSA9IFwiVW5pdmVyc2FsU3RyaW5nVmFsdWVCbG9ja1wiO1xuXG52YXIgX2EkZztcclxuY2xhc3MgVW5pdmVyc2FsU3RyaW5nIGV4dGVuZHMgTG9jYWxVbml2ZXJzYWxTdHJpbmdWYWx1ZUJsb2NrIHtcclxuICAgIGNvbnN0cnVjdG9yKHsgLi4ucGFyYW1ldGVycyB9ID0ge30pIHtcclxuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnQ2xhc3MgPSAxO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdOdW1iZXIgPSAyODtcclxuICAgIH1cclxufVxyXG5fYSRnID0gVW5pdmVyc2FsU3RyaW5nO1xyXG4oKCkgPT4ge1xyXG4gICAgdHlwZVN0b3JlLlVuaXZlcnNhbFN0cmluZyA9IF9hJGc7XHJcbn0pKCk7XHJcblVuaXZlcnNhbFN0cmluZy5OQU1FID0gXCJVbml2ZXJzYWxTdHJpbmdcIjtcblxudmFyIF9hJGY7XHJcbmNsYXNzIE51bWVyaWNTdHJpbmcgZXh0ZW5kcyBMb2NhbFNpbXBsZVN0cmluZ0Jsb2NrIHtcclxuICAgIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMgPSB7fSkge1xyXG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdDbGFzcyA9IDE7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ051bWJlciA9IDE4O1xyXG4gICAgfVxyXG59XHJcbl9hJGYgPSBOdW1lcmljU3RyaW5nO1xyXG4oKCkgPT4ge1xyXG4gICAgdHlwZVN0b3JlLk51bWVyaWNTdHJpbmcgPSBfYSRmO1xyXG59KSgpO1xyXG5OdW1lcmljU3RyaW5nLk5BTUUgPSBcIk51bWVyaWNTdHJpbmdcIjtcblxudmFyIF9hJGU7XHJcbmNsYXNzIFByaW50YWJsZVN0cmluZyBleHRlbmRzIExvY2FsU2ltcGxlU3RyaW5nQmxvY2sge1xyXG4gICAgY29uc3RydWN0b3IocGFyYW1ldGVycyA9IHt9KSB7XHJcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ0NsYXNzID0gMTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnTnVtYmVyID0gMTk7XHJcbiAgICB9XHJcbn1cclxuX2EkZSA9IFByaW50YWJsZVN0cmluZztcclxuKCgpID0+IHtcclxuICAgIHR5cGVTdG9yZS5QcmludGFibGVTdHJpbmcgPSBfYSRlO1xyXG59KSgpO1xyXG5QcmludGFibGVTdHJpbmcuTkFNRSA9IFwiUHJpbnRhYmxlU3RyaW5nXCI7XG5cbnZhciBfYSRkO1xyXG5jbGFzcyBUZWxldGV4U3RyaW5nIGV4dGVuZHMgTG9jYWxTaW1wbGVTdHJpbmdCbG9jayB7XHJcbiAgICBjb25zdHJ1Y3RvcihwYXJhbWV0ZXJzID0ge30pIHtcclxuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnQ2xhc3MgPSAxO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdOdW1iZXIgPSAyMDtcclxuICAgIH1cclxufVxyXG5fYSRkID0gVGVsZXRleFN0cmluZztcclxuKCgpID0+IHtcclxuICAgIHR5cGVTdG9yZS5UZWxldGV4U3RyaW5nID0gX2EkZDtcclxufSkoKTtcclxuVGVsZXRleFN0cmluZy5OQU1FID0gXCJUZWxldGV4U3RyaW5nXCI7XG5cbnZhciBfYSRjO1xyXG5jbGFzcyBWaWRlb3RleFN0cmluZyBleHRlbmRzIExvY2FsU2ltcGxlU3RyaW5nQmxvY2sge1xyXG4gICAgY29uc3RydWN0b3IocGFyYW1ldGVycyA9IHt9KSB7XHJcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ0NsYXNzID0gMTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnTnVtYmVyID0gMjE7XHJcbiAgICB9XHJcbn1cclxuX2EkYyA9IFZpZGVvdGV4U3RyaW5nO1xyXG4oKCkgPT4ge1xyXG4gICAgdHlwZVN0b3JlLlZpZGVvdGV4U3RyaW5nID0gX2EkYztcclxufSkoKTtcclxuVmlkZW90ZXhTdHJpbmcuTkFNRSA9IFwiVmlkZW90ZXhTdHJpbmdcIjtcblxudmFyIF9hJGI7XHJcbmNsYXNzIElBNVN0cmluZyBleHRlbmRzIExvY2FsU2ltcGxlU3RyaW5nQmxvY2sge1xyXG4gICAgY29uc3RydWN0b3IocGFyYW1ldGVycyA9IHt9KSB7XHJcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ0NsYXNzID0gMTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnTnVtYmVyID0gMjI7XHJcbiAgICB9XHJcbn1cclxuX2EkYiA9IElBNVN0cmluZztcclxuKCgpID0+IHtcclxuICAgIHR5cGVTdG9yZS5JQTVTdHJpbmcgPSBfYSRiO1xyXG59KSgpO1xyXG5JQTVTdHJpbmcuTkFNRSA9IFwiSUE1U3RyaW5nXCI7XG5cbnZhciBfYSRhO1xyXG5jbGFzcyBHcmFwaGljU3RyaW5nIGV4dGVuZHMgTG9jYWxTaW1wbGVTdHJpbmdCbG9jayB7XHJcbiAgICBjb25zdHJ1Y3RvcihwYXJhbWV0ZXJzID0ge30pIHtcclxuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnQ2xhc3MgPSAxO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdOdW1iZXIgPSAyNTtcclxuICAgIH1cclxufVxyXG5fYSRhID0gR3JhcGhpY1N0cmluZztcclxuKCgpID0+IHtcclxuICAgIHR5cGVTdG9yZS5HcmFwaGljU3RyaW5nID0gX2EkYTtcclxufSkoKTtcclxuR3JhcGhpY1N0cmluZy5OQU1FID0gXCJHcmFwaGljU3RyaW5nXCI7XG5cbnZhciBfYSQ5O1xyXG5jbGFzcyBWaXNpYmxlU3RyaW5nIGV4dGVuZHMgTG9jYWxTaW1wbGVTdHJpbmdCbG9jayB7XHJcbiAgICBjb25zdHJ1Y3RvcihwYXJhbWV0ZXJzID0ge30pIHtcclxuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnQ2xhc3MgPSAxO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdOdW1iZXIgPSAyNjtcclxuICAgIH1cclxufVxyXG5fYSQ5ID0gVmlzaWJsZVN0cmluZztcclxuKCgpID0+IHtcclxuICAgIHR5cGVTdG9yZS5WaXNpYmxlU3RyaW5nID0gX2EkOTtcclxufSkoKTtcclxuVmlzaWJsZVN0cmluZy5OQU1FID0gXCJWaXNpYmxlU3RyaW5nXCI7XG5cbnZhciBfYSQ4O1xyXG5jbGFzcyBHZW5lcmFsU3RyaW5nIGV4dGVuZHMgTG9jYWxTaW1wbGVTdHJpbmdCbG9jayB7XHJcbiAgICBjb25zdHJ1Y3RvcihwYXJhbWV0ZXJzID0ge30pIHtcclxuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnQ2xhc3MgPSAxO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdOdW1iZXIgPSAyNztcclxuICAgIH1cclxufVxyXG5fYSQ4ID0gR2VuZXJhbFN0cmluZztcclxuKCgpID0+IHtcclxuICAgIHR5cGVTdG9yZS5HZW5lcmFsU3RyaW5nID0gX2EkODtcclxufSkoKTtcclxuR2VuZXJhbFN0cmluZy5OQU1FID0gXCJHZW5lcmFsU3RyaW5nXCI7XG5cbnZhciBfYSQ3O1xyXG5jbGFzcyBDaGFyYWN0ZXJTdHJpbmcgZXh0ZW5kcyBMb2NhbFNpbXBsZVN0cmluZ0Jsb2NrIHtcclxuICAgIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMgPSB7fSkge1xyXG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdDbGFzcyA9IDE7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ051bWJlciA9IDI5O1xyXG4gICAgfVxyXG59XHJcbl9hJDcgPSBDaGFyYWN0ZXJTdHJpbmc7XHJcbigoKSA9PiB7XHJcbiAgICB0eXBlU3RvcmUuQ2hhcmFjdGVyU3RyaW5nID0gX2EkNztcclxufSkoKTtcclxuQ2hhcmFjdGVyU3RyaW5nLk5BTUUgPSBcIkNoYXJhY3RlclN0cmluZ1wiO1xuXG52YXIgX2EkNjtcclxuY2xhc3MgVVRDVGltZSBleHRlbmRzIFZpc2libGVTdHJpbmcge1xyXG4gICAgY29uc3RydWN0b3IoeyB2YWx1ZSwgdmFsdWVEYXRlLCAuLi5wYXJhbWV0ZXJzIH0gPSB7fSkge1xyXG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xyXG4gICAgICAgIHRoaXMueWVhciA9IDA7XHJcbiAgICAgICAgdGhpcy5tb250aCA9IDA7XHJcbiAgICAgICAgdGhpcy5kYXkgPSAwO1xyXG4gICAgICAgIHRoaXMuaG91ciA9IDA7XHJcbiAgICAgICAgdGhpcy5taW51dGUgPSAwO1xyXG4gICAgICAgIHRoaXMuc2Vjb25kID0gMDtcclxuICAgICAgICBpZiAodmFsdWUpIHtcclxuICAgICAgICAgICAgdGhpcy5mcm9tU3RyaW5nKHZhbHVlKTtcclxuICAgICAgICAgICAgdGhpcy52YWx1ZUJsb2NrLnZhbHVlSGV4VmlldyA9IG5ldyBVaW50OEFycmF5KHZhbHVlLmxlbmd0aCk7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWUubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgICAgICAgICB0aGlzLnZhbHVlQmxvY2sudmFsdWVIZXhWaWV3W2ldID0gdmFsdWUuY2hhckNvZGVBdChpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHZhbHVlRGF0ZSkge1xyXG4gICAgICAgICAgICB0aGlzLmZyb21EYXRlKHZhbHVlRGF0ZSk7XHJcbiAgICAgICAgICAgIHRoaXMudmFsdWVCbG9jay52YWx1ZUhleFZpZXcgPSBuZXcgVWludDhBcnJheSh0aGlzLnRvQnVmZmVyKCkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnQ2xhc3MgPSAxO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdOdW1iZXIgPSAyMztcclxuICAgIH1cclxuICAgIGZyb21CdWZmZXIoaW5wdXRCdWZmZXIpIHtcclxuICAgICAgICB0aGlzLmZyb21TdHJpbmcoU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBwdnRzdXRpbHMuQnVmZmVyU291cmNlQ29udmVydGVyLnRvVWludDhBcnJheShpbnB1dEJ1ZmZlcikpKTtcclxuICAgIH1cclxuICAgIHRvQnVmZmVyKCkge1xyXG4gICAgICAgIGNvbnN0IHN0ciA9IHRoaXMudG9TdHJpbmcoKTtcclxuICAgICAgICBjb25zdCBidWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIoc3RyLmxlbmd0aCk7XHJcbiAgICAgICAgY29uc3QgdmlldyA9IG5ldyBVaW50OEFycmF5KGJ1ZmZlcik7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgICAgIHZpZXdbaV0gPSBzdHIuY2hhckNvZGVBdChpKTtcclxuICAgICAgICByZXR1cm4gYnVmZmVyO1xyXG4gICAgfVxyXG4gICAgZnJvbURhdGUoaW5wdXREYXRlKSB7XHJcbiAgICAgICAgdGhpcy55ZWFyID0gaW5wdXREYXRlLmdldFVUQ0Z1bGxZZWFyKCk7XHJcbiAgICAgICAgdGhpcy5tb250aCA9IGlucHV0RGF0ZS5nZXRVVENNb250aCgpICsgMTtcclxuICAgICAgICB0aGlzLmRheSA9IGlucHV0RGF0ZS5nZXRVVENEYXRlKCk7XHJcbiAgICAgICAgdGhpcy5ob3VyID0gaW5wdXREYXRlLmdldFVUQ0hvdXJzKCk7XHJcbiAgICAgICAgdGhpcy5taW51dGUgPSBpbnB1dERhdGUuZ2V0VVRDTWludXRlcygpO1xyXG4gICAgICAgIHRoaXMuc2Vjb25kID0gaW5wdXREYXRlLmdldFVUQ1NlY29uZHMoKTtcclxuICAgIH1cclxuICAgIHRvRGF0ZSgpIHtcclxuICAgICAgICByZXR1cm4gKG5ldyBEYXRlKERhdGUuVVRDKHRoaXMueWVhciwgdGhpcy5tb250aCAtIDEsIHRoaXMuZGF5LCB0aGlzLmhvdXIsIHRoaXMubWludXRlLCB0aGlzLnNlY29uZCkpKTtcclxuICAgIH1cclxuICAgIGZyb21TdHJpbmcoaW5wdXRTdHJpbmcpIHtcclxuICAgICAgICBjb25zdCBwYXJzZXIgPSAvKFxcZHsyfSkoXFxkezJ9KShcXGR7Mn0pKFxcZHsyfSkoXFxkezJ9KShcXGR7Mn0pWi9pZztcclxuICAgICAgICBjb25zdCBwYXJzZXJBcnJheSA9IHBhcnNlci5leGVjKGlucHV0U3RyaW5nKTtcclxuICAgICAgICBpZiAocGFyc2VyQXJyYXkgPT09IG51bGwpIHtcclxuICAgICAgICAgICAgdGhpcy5lcnJvciA9IFwiV3JvbmcgaW5wdXQgc3RyaW5nIGZvciBjb252ZXJzaW9uXCI7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgeWVhciA9IHBhcnNlSW50KHBhcnNlckFycmF5WzFdLCAxMCk7XHJcbiAgICAgICAgaWYgKHllYXIgPj0gNTApXHJcbiAgICAgICAgICAgIHRoaXMueWVhciA9IDE5MDAgKyB5ZWFyO1xyXG4gICAgICAgIGVsc2VcclxuICAgICAgICAgICAgdGhpcy55ZWFyID0gMjAwMCArIHllYXI7XHJcbiAgICAgICAgdGhpcy5tb250aCA9IHBhcnNlSW50KHBhcnNlckFycmF5WzJdLCAxMCk7XHJcbiAgICAgICAgdGhpcy5kYXkgPSBwYXJzZUludChwYXJzZXJBcnJheVszXSwgMTApO1xyXG4gICAgICAgIHRoaXMuaG91ciA9IHBhcnNlSW50KHBhcnNlckFycmF5WzRdLCAxMCk7XHJcbiAgICAgICAgdGhpcy5taW51dGUgPSBwYXJzZUludChwYXJzZXJBcnJheVs1XSwgMTApO1xyXG4gICAgICAgIHRoaXMuc2Vjb25kID0gcGFyc2VJbnQocGFyc2VyQXJyYXlbNl0sIDEwKTtcclxuICAgIH1cclxuICAgIHRvU3RyaW5nKGVuY29kaW5nID0gXCJpc29cIikge1xyXG4gICAgICAgIGlmIChlbmNvZGluZyA9PT0gXCJpc29cIikge1xyXG4gICAgICAgICAgICBjb25zdCBvdXRwdXRBcnJheSA9IG5ldyBBcnJheSg3KTtcclxuICAgICAgICAgICAgb3V0cHV0QXJyYXlbMF0gPSBwdnV0aWxzLnBhZE51bWJlcigoKHRoaXMueWVhciA8IDIwMDApID8gKHRoaXMueWVhciAtIDE5MDApIDogKHRoaXMueWVhciAtIDIwMDApKSwgMik7XHJcbiAgICAgICAgICAgIG91dHB1dEFycmF5WzFdID0gcHZ1dGlscy5wYWROdW1iZXIodGhpcy5tb250aCwgMik7XHJcbiAgICAgICAgICAgIG91dHB1dEFycmF5WzJdID0gcHZ1dGlscy5wYWROdW1iZXIodGhpcy5kYXksIDIpO1xyXG4gICAgICAgICAgICBvdXRwdXRBcnJheVszXSA9IHB2dXRpbHMucGFkTnVtYmVyKHRoaXMuaG91ciwgMik7XHJcbiAgICAgICAgICAgIG91dHB1dEFycmF5WzRdID0gcHZ1dGlscy5wYWROdW1iZXIodGhpcy5taW51dGUsIDIpO1xyXG4gICAgICAgICAgICBvdXRwdXRBcnJheVs1XSA9IHB2dXRpbHMucGFkTnVtYmVyKHRoaXMuc2Vjb25kLCAyKTtcclxuICAgICAgICAgICAgb3V0cHV0QXJyYXlbNl0gPSBcIlpcIjtcclxuICAgICAgICAgICAgcmV0dXJuIG91dHB1dEFycmF5LmpvaW4oXCJcIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBzdXBlci50b1N0cmluZyhlbmNvZGluZyk7XHJcbiAgICB9XHJcbiAgICBvbkFzY2lpRW5jb2RpbmcoKSB7XHJcbiAgICAgICAgcmV0dXJuIGAke3RoaXMuY29uc3RydWN0b3IuTkFNRX0gOiAke3RoaXMudG9EYXRlKCkudG9JU09TdHJpbmcoKX1gO1xyXG4gICAgfVxyXG4gICAgdG9KU09OKCkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIC4uLnN1cGVyLnRvSlNPTigpLFxyXG4gICAgICAgICAgICB5ZWFyOiB0aGlzLnllYXIsXHJcbiAgICAgICAgICAgIG1vbnRoOiB0aGlzLm1vbnRoLFxyXG4gICAgICAgICAgICBkYXk6IHRoaXMuZGF5LFxyXG4gICAgICAgICAgICBob3VyOiB0aGlzLmhvdXIsXHJcbiAgICAgICAgICAgIG1pbnV0ZTogdGhpcy5taW51dGUsXHJcbiAgICAgICAgICAgIHNlY29uZDogdGhpcy5zZWNvbmQsXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxufVxyXG5fYSQ2ID0gVVRDVGltZTtcclxuKCgpID0+IHtcclxuICAgIHR5cGVTdG9yZS5VVENUaW1lID0gX2EkNjtcclxufSkoKTtcclxuVVRDVGltZS5OQU1FID0gXCJVVENUaW1lXCI7XG5cbnZhciBfYSQ1O1xyXG5jbGFzcyBHZW5lcmFsaXplZFRpbWUgZXh0ZW5kcyBVVENUaW1lIHtcclxuICAgIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMgPSB7fSkge1xyXG4gICAgICAgIHZhciBfYjtcclxuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcclxuICAgICAgICAoX2IgPSB0aGlzLm1pbGxpc2Vjb25kKSAhPT0gbnVsbCAmJiBfYiAhPT0gdm9pZCAwID8gX2IgOiAodGhpcy5taWxsaXNlY29uZCA9IDApO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdDbGFzcyA9IDE7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ051bWJlciA9IDI0O1xyXG4gICAgfVxyXG4gICAgZnJvbURhdGUoaW5wdXREYXRlKSB7XHJcbiAgICAgICAgc3VwZXIuZnJvbURhdGUoaW5wdXREYXRlKTtcclxuICAgICAgICB0aGlzLm1pbGxpc2Vjb25kID0gaW5wdXREYXRlLmdldFVUQ01pbGxpc2Vjb25kcygpO1xyXG4gICAgfVxyXG4gICAgdG9EYXRlKCkge1xyXG4gICAgICAgIHJldHVybiAobmV3IERhdGUoRGF0ZS5VVEModGhpcy55ZWFyLCB0aGlzLm1vbnRoIC0gMSwgdGhpcy5kYXksIHRoaXMuaG91ciwgdGhpcy5taW51dGUsIHRoaXMuc2Vjb25kLCB0aGlzLm1pbGxpc2Vjb25kKSkpO1xyXG4gICAgfVxyXG4gICAgZnJvbVN0cmluZyhpbnB1dFN0cmluZykge1xyXG4gICAgICAgIGxldCBpc1VUQyA9IGZhbHNlO1xyXG4gICAgICAgIGxldCB0aW1lU3RyaW5nID0gXCJcIjtcclxuICAgICAgICBsZXQgZGF0ZVRpbWVTdHJpbmcgPSBcIlwiO1xyXG4gICAgICAgIGxldCBmcmFjdGlvblBhcnQgPSAwO1xyXG4gICAgICAgIGxldCBwYXJzZXI7XHJcbiAgICAgICAgbGV0IGhvdXJEaWZmZXJlbmNlID0gMDtcclxuICAgICAgICBsZXQgbWludXRlRGlmZmVyZW5jZSA9IDA7XHJcbiAgICAgICAgaWYgKGlucHV0U3RyaW5nW2lucHV0U3RyaW5nLmxlbmd0aCAtIDFdID09PSBcIlpcIikge1xyXG4gICAgICAgICAgICB0aW1lU3RyaW5nID0gaW5wdXRTdHJpbmcuc3Vic3RyaW5nKDAsIGlucHV0U3RyaW5nLmxlbmd0aCAtIDEpO1xyXG4gICAgICAgICAgICBpc1VUQyA9IHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBjb25zdCBudW1iZXIgPSBuZXcgTnVtYmVyKGlucHV0U3RyaW5nW2lucHV0U3RyaW5nLmxlbmd0aCAtIDFdKTtcclxuICAgICAgICAgICAgaWYgKGlzTmFOKG51bWJlci52YWx1ZU9mKCkpKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiV3JvbmcgaW5wdXQgc3RyaW5nIGZvciBjb252ZXJzaW9uXCIpO1xyXG4gICAgICAgICAgICB0aW1lU3RyaW5nID0gaW5wdXRTdHJpbmc7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChpc1VUQykge1xyXG4gICAgICAgICAgICBpZiAodGltZVN0cmluZy5pbmRleE9mKFwiK1wiKSAhPT0gLTEpXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJXcm9uZyBpbnB1dCBzdHJpbmcgZm9yIGNvbnZlcnNpb25cIik7XHJcbiAgICAgICAgICAgIGlmICh0aW1lU3RyaW5nLmluZGV4T2YoXCItXCIpICE9PSAtMSlcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIldyb25nIGlucHV0IHN0cmluZyBmb3IgY29udmVyc2lvblwiKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGxldCBtdWx0aXBsaWVyID0gMTtcclxuICAgICAgICAgICAgbGV0IGRpZmZlcmVuY2VQb3NpdGlvbiA9IHRpbWVTdHJpbmcuaW5kZXhPZihcIitcIik7XHJcbiAgICAgICAgICAgIGxldCBkaWZmZXJlbmNlU3RyaW5nID0gXCJcIjtcclxuICAgICAgICAgICAgaWYgKGRpZmZlcmVuY2VQb3NpdGlvbiA9PT0gLTEpIHtcclxuICAgICAgICAgICAgICAgIGRpZmZlcmVuY2VQb3NpdGlvbiA9IHRpbWVTdHJpbmcuaW5kZXhPZihcIi1cIik7XHJcbiAgICAgICAgICAgICAgICBtdWx0aXBsaWVyID0gLTE7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGRpZmZlcmVuY2VQb3NpdGlvbiAhPT0gLTEpIHtcclxuICAgICAgICAgICAgICAgIGRpZmZlcmVuY2VTdHJpbmcgPSB0aW1lU3RyaW5nLnN1YnN0cmluZyhkaWZmZXJlbmNlUG9zaXRpb24gKyAxKTtcclxuICAgICAgICAgICAgICAgIHRpbWVTdHJpbmcgPSB0aW1lU3RyaW5nLnN1YnN0cmluZygwLCBkaWZmZXJlbmNlUG9zaXRpb24pO1xyXG4gICAgICAgICAgICAgICAgaWYgKChkaWZmZXJlbmNlU3RyaW5nLmxlbmd0aCAhPT0gMikgJiYgKGRpZmZlcmVuY2VTdHJpbmcubGVuZ3RoICE9PSA0KSlcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJXcm9uZyBpbnB1dCBzdHJpbmcgZm9yIGNvbnZlcnNpb25cIik7XHJcbiAgICAgICAgICAgICAgICBsZXQgbnVtYmVyID0gcGFyc2VJbnQoZGlmZmVyZW5jZVN0cmluZy5zdWJzdHJpbmcoMCwgMiksIDEwKTtcclxuICAgICAgICAgICAgICAgIGlmIChpc05hTihudW1iZXIudmFsdWVPZigpKSlcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJXcm9uZyBpbnB1dCBzdHJpbmcgZm9yIGNvbnZlcnNpb25cIik7XHJcbiAgICAgICAgICAgICAgICBob3VyRGlmZmVyZW5jZSA9IG11bHRpcGxpZXIgKiBudW1iZXI7XHJcbiAgICAgICAgICAgICAgICBpZiAoZGlmZmVyZW5jZVN0cmluZy5sZW5ndGggPT09IDQpIHtcclxuICAgICAgICAgICAgICAgICAgICBudW1iZXIgPSBwYXJzZUludChkaWZmZXJlbmNlU3RyaW5nLnN1YnN0cmluZygyLCA0KSwgMTApO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpc05hTihudW1iZXIudmFsdWVPZigpKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiV3JvbmcgaW5wdXQgc3RyaW5nIGZvciBjb252ZXJzaW9uXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIG1pbnV0ZURpZmZlcmVuY2UgPSBtdWx0aXBsaWVyICogbnVtYmVyO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGxldCBmcmFjdGlvblBvaW50UG9zaXRpb24gPSB0aW1lU3RyaW5nLmluZGV4T2YoXCIuXCIpO1xyXG4gICAgICAgIGlmIChmcmFjdGlvblBvaW50UG9zaXRpb24gPT09IC0xKVxyXG4gICAgICAgICAgICBmcmFjdGlvblBvaW50UG9zaXRpb24gPSB0aW1lU3RyaW5nLmluZGV4T2YoXCIsXCIpO1xyXG4gICAgICAgIGlmIChmcmFjdGlvblBvaW50UG9zaXRpb24gIT09IC0xKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGZyYWN0aW9uUGFydENoZWNrID0gbmV3IE51bWJlcihgMCR7dGltZVN0cmluZy5zdWJzdHJpbmcoZnJhY3Rpb25Qb2ludFBvc2l0aW9uKX1gKTtcclxuICAgICAgICAgICAgaWYgKGlzTmFOKGZyYWN0aW9uUGFydENoZWNrLnZhbHVlT2YoKSkpXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJXcm9uZyBpbnB1dCBzdHJpbmcgZm9yIGNvbnZlcnNpb25cIik7XHJcbiAgICAgICAgICAgIGZyYWN0aW9uUGFydCA9IGZyYWN0aW9uUGFydENoZWNrLnZhbHVlT2YoKTtcclxuICAgICAgICAgICAgZGF0ZVRpbWVTdHJpbmcgPSB0aW1lU3RyaW5nLnN1YnN0cmluZygwLCBmcmFjdGlvblBvaW50UG9zaXRpb24pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgIGRhdGVUaW1lU3RyaW5nID0gdGltZVN0cmluZztcclxuICAgICAgICBzd2l0Y2ggKHRydWUpIHtcclxuICAgICAgICAgICAgY2FzZSAoZGF0ZVRpbWVTdHJpbmcubGVuZ3RoID09PSA4KTpcclxuICAgICAgICAgICAgICAgIHBhcnNlciA9IC8oXFxkezR9KShcXGR7Mn0pKFxcZHsyfSkvaWc7XHJcbiAgICAgICAgICAgICAgICBpZiAoZnJhY3Rpb25Qb2ludFBvc2l0aW9uICE9PSAtMSlcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJXcm9uZyBpbnB1dCBzdHJpbmcgZm9yIGNvbnZlcnNpb25cIik7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgY2FzZSAoZGF0ZVRpbWVTdHJpbmcubGVuZ3RoID09PSAxMCk6XHJcbiAgICAgICAgICAgICAgICBwYXJzZXIgPSAvKFxcZHs0fSkoXFxkezJ9KShcXGR7Mn0pKFxcZHsyfSkvaWc7XHJcbiAgICAgICAgICAgICAgICBpZiAoZnJhY3Rpb25Qb2ludFBvc2l0aW9uICE9PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBmcmFjdGlvblJlc3VsdCA9IDYwICogZnJhY3Rpb25QYXJ0O1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWludXRlID0gTWF0aC5mbG9vcihmcmFjdGlvblJlc3VsdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgZnJhY3Rpb25SZXN1bHQgPSA2MCAqIChmcmFjdGlvblJlc3VsdCAtIHRoaXMubWludXRlKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNlY29uZCA9IE1hdGguZmxvb3IoZnJhY3Rpb25SZXN1bHQpO1xyXG4gICAgICAgICAgICAgICAgICAgIGZyYWN0aW9uUmVzdWx0ID0gMTAwMCAqIChmcmFjdGlvblJlc3VsdCAtIHRoaXMuc2Vjb25kKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLm1pbGxpc2Vjb25kID0gTWF0aC5mbG9vcihmcmFjdGlvblJlc3VsdCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgY2FzZSAoZGF0ZVRpbWVTdHJpbmcubGVuZ3RoID09PSAxMik6XHJcbiAgICAgICAgICAgICAgICBwYXJzZXIgPSAvKFxcZHs0fSkoXFxkezJ9KShcXGR7Mn0pKFxcZHsyfSkoXFxkezJ9KS9pZztcclxuICAgICAgICAgICAgICAgIGlmIChmcmFjdGlvblBvaW50UG9zaXRpb24gIT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGZyYWN0aW9uUmVzdWx0ID0gNjAgKiBmcmFjdGlvblBhcnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZWNvbmQgPSBNYXRoLmZsb29yKGZyYWN0aW9uUmVzdWx0KTtcclxuICAgICAgICAgICAgICAgICAgICBmcmFjdGlvblJlc3VsdCA9IDEwMDAgKiAoZnJhY3Rpb25SZXN1bHQgLSB0aGlzLnNlY29uZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5taWxsaXNlY29uZCA9IE1hdGguZmxvb3IoZnJhY3Rpb25SZXN1bHQpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgKGRhdGVUaW1lU3RyaW5nLmxlbmd0aCA9PT0gMTQpOlxyXG4gICAgICAgICAgICAgICAgcGFyc2VyID0gLyhcXGR7NH0pKFxcZHsyfSkoXFxkezJ9KShcXGR7Mn0pKFxcZHsyfSkoXFxkezJ9KS9pZztcclxuICAgICAgICAgICAgICAgIGlmIChmcmFjdGlvblBvaW50UG9zaXRpb24gIT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZnJhY3Rpb25SZXN1bHQgPSAxMDAwICogZnJhY3Rpb25QYXJ0O1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWlsbGlzZWNvbmQgPSBNYXRoLmZsb29yKGZyYWN0aW9uUmVzdWx0KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiV3JvbmcgaW5wdXQgc3RyaW5nIGZvciBjb252ZXJzaW9uXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBwYXJzZXJBcnJheSA9IHBhcnNlci5leGVjKGRhdGVUaW1lU3RyaW5nKTtcclxuICAgICAgICBpZiAocGFyc2VyQXJyYXkgPT09IG51bGwpXHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIldyb25nIGlucHV0IHN0cmluZyBmb3IgY29udmVyc2lvblwiKTtcclxuICAgICAgICBmb3IgKGxldCBqID0gMTsgaiA8IHBhcnNlckFycmF5Lmxlbmd0aDsgaisrKSB7XHJcbiAgICAgICAgICAgIHN3aXRjaCAoaikge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAxOlxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMueWVhciA9IHBhcnNlSW50KHBhcnNlckFycmF5W2pdLCAxMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDI6XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tb250aCA9IHBhcnNlSW50KHBhcnNlckFycmF5W2pdLCAxMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDM6XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kYXkgPSBwYXJzZUludChwYXJzZXJBcnJheVtqXSwgMTApO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA0OlxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaG91ciA9IHBhcnNlSW50KHBhcnNlckFycmF5W2pdLCAxMCkgKyBob3VyRGlmZmVyZW5jZTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgNTpcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLm1pbnV0ZSA9IHBhcnNlSW50KHBhcnNlckFycmF5W2pdLCAxMCkgKyBtaW51dGVEaWZmZXJlbmNlO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA2OlxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vjb25kID0gcGFyc2VJbnQocGFyc2VyQXJyYXlbal0sIDEwKTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiV3JvbmcgaW5wdXQgc3RyaW5nIGZvciBjb252ZXJzaW9uXCIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChpc1VUQyA9PT0gZmFsc2UpIHtcclxuICAgICAgICAgICAgY29uc3QgdGVtcERhdGUgPSBuZXcgRGF0ZSh0aGlzLnllYXIsIHRoaXMubW9udGgsIHRoaXMuZGF5LCB0aGlzLmhvdXIsIHRoaXMubWludXRlLCB0aGlzLnNlY29uZCwgdGhpcy5taWxsaXNlY29uZCk7XHJcbiAgICAgICAgICAgIHRoaXMueWVhciA9IHRlbXBEYXRlLmdldFVUQ0Z1bGxZZWFyKCk7XHJcbiAgICAgICAgICAgIHRoaXMubW9udGggPSB0ZW1wRGF0ZS5nZXRVVENNb250aCgpO1xyXG4gICAgICAgICAgICB0aGlzLmRheSA9IHRlbXBEYXRlLmdldFVUQ0RheSgpO1xyXG4gICAgICAgICAgICB0aGlzLmhvdXIgPSB0ZW1wRGF0ZS5nZXRVVENIb3VycygpO1xyXG4gICAgICAgICAgICB0aGlzLm1pbnV0ZSA9IHRlbXBEYXRlLmdldFVUQ01pbnV0ZXMoKTtcclxuICAgICAgICAgICAgdGhpcy5zZWNvbmQgPSB0ZW1wRGF0ZS5nZXRVVENTZWNvbmRzKCk7XHJcbiAgICAgICAgICAgIHRoaXMubWlsbGlzZWNvbmQgPSB0ZW1wRGF0ZS5nZXRVVENNaWxsaXNlY29uZHMoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICB0b1N0cmluZyhlbmNvZGluZyA9IFwiaXNvXCIpIHtcclxuICAgICAgICBpZiAoZW5jb2RpbmcgPT09IFwiaXNvXCIpIHtcclxuICAgICAgICAgICAgY29uc3Qgb3V0cHV0QXJyYXkgPSBbXTtcclxuICAgICAgICAgICAgb3V0cHV0QXJyYXkucHVzaChwdnV0aWxzLnBhZE51bWJlcih0aGlzLnllYXIsIDQpKTtcclxuICAgICAgICAgICAgb3V0cHV0QXJyYXkucHVzaChwdnV0aWxzLnBhZE51bWJlcih0aGlzLm1vbnRoLCAyKSk7XHJcbiAgICAgICAgICAgIG91dHB1dEFycmF5LnB1c2gocHZ1dGlscy5wYWROdW1iZXIodGhpcy5kYXksIDIpKTtcclxuICAgICAgICAgICAgb3V0cHV0QXJyYXkucHVzaChwdnV0aWxzLnBhZE51bWJlcih0aGlzLmhvdXIsIDIpKTtcclxuICAgICAgICAgICAgb3V0cHV0QXJyYXkucHVzaChwdnV0aWxzLnBhZE51bWJlcih0aGlzLm1pbnV0ZSwgMikpO1xyXG4gICAgICAgICAgICBvdXRwdXRBcnJheS5wdXNoKHB2dXRpbHMucGFkTnVtYmVyKHRoaXMuc2Vjb25kLCAyKSk7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLm1pbGxpc2Vjb25kICE9PSAwKSB7XHJcbiAgICAgICAgICAgICAgICBvdXRwdXRBcnJheS5wdXNoKFwiLlwiKTtcclxuICAgICAgICAgICAgICAgIG91dHB1dEFycmF5LnB1c2gocHZ1dGlscy5wYWROdW1iZXIodGhpcy5taWxsaXNlY29uZCwgMykpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIG91dHB1dEFycmF5LnB1c2goXCJaXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gb3V0cHV0QXJyYXkuam9pbihcIlwiKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHN1cGVyLnRvU3RyaW5nKGVuY29kaW5nKTtcclxuICAgIH1cclxuICAgIHRvSlNPTigpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAuLi5zdXBlci50b0pTT04oKSxcclxuICAgICAgICAgICAgbWlsbGlzZWNvbmQ6IHRoaXMubWlsbGlzZWNvbmQsXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxufVxyXG5fYSQ1ID0gR2VuZXJhbGl6ZWRUaW1lO1xyXG4oKCkgPT4ge1xyXG4gICAgdHlwZVN0b3JlLkdlbmVyYWxpemVkVGltZSA9IF9hJDU7XHJcbn0pKCk7XHJcbkdlbmVyYWxpemVkVGltZS5OQU1FID0gXCJHZW5lcmFsaXplZFRpbWVcIjtcblxudmFyIF9hJDQ7XHJcbmNsYXNzIERBVEUgZXh0ZW5kcyBVdGY4U3RyaW5nIHtcclxuICAgIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMgPSB7fSkge1xyXG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdDbGFzcyA9IDE7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ051bWJlciA9IDMxO1xyXG4gICAgfVxyXG59XHJcbl9hJDQgPSBEQVRFO1xyXG4oKCkgPT4ge1xyXG4gICAgdHlwZVN0b3JlLkRBVEUgPSBfYSQ0O1xyXG59KSgpO1xyXG5EQVRFLk5BTUUgPSBcIkRBVEVcIjtcblxudmFyIF9hJDM7XHJcbmNsYXNzIFRpbWVPZkRheSBleHRlbmRzIFV0ZjhTdHJpbmcge1xyXG4gICAgY29uc3RydWN0b3IocGFyYW1ldGVycyA9IHt9KSB7XHJcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ0NsYXNzID0gMTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnTnVtYmVyID0gMzI7XHJcbiAgICB9XHJcbn1cclxuX2EkMyA9IFRpbWVPZkRheTtcclxuKCgpID0+IHtcclxuICAgIHR5cGVTdG9yZS5UaW1lT2ZEYXkgPSBfYSQzO1xyXG59KSgpO1xyXG5UaW1lT2ZEYXkuTkFNRSA9IFwiVGltZU9mRGF5XCI7XG5cbnZhciBfYSQyO1xyXG5jbGFzcyBEYXRlVGltZSBleHRlbmRzIFV0ZjhTdHJpbmcge1xyXG4gICAgY29uc3RydWN0b3IocGFyYW1ldGVycyA9IHt9KSB7XHJcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ0NsYXNzID0gMTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnTnVtYmVyID0gMzM7XHJcbiAgICB9XHJcbn1cclxuX2EkMiA9IERhdGVUaW1lO1xyXG4oKCkgPT4ge1xyXG4gICAgdHlwZVN0b3JlLkRhdGVUaW1lID0gX2EkMjtcclxufSkoKTtcclxuRGF0ZVRpbWUuTkFNRSA9IFwiRGF0ZVRpbWVcIjtcblxudmFyIF9hJDE7XHJcbmNsYXNzIER1cmF0aW9uIGV4dGVuZHMgVXRmOFN0cmluZyB7XHJcbiAgICBjb25zdHJ1Y3RvcihwYXJhbWV0ZXJzID0ge30pIHtcclxuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcclxuICAgICAgICB0aGlzLmlkQmxvY2sudGFnQ2xhc3MgPSAxO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdOdW1iZXIgPSAzNDtcclxuICAgIH1cclxufVxyXG5fYSQxID0gRHVyYXRpb247XHJcbigoKSA9PiB7XHJcbiAgICB0eXBlU3RvcmUuRHVyYXRpb24gPSBfYSQxO1xyXG59KSgpO1xyXG5EdXJhdGlvbi5OQU1FID0gXCJEdXJhdGlvblwiO1xuXG52YXIgX2E7XHJcbmNsYXNzIFRJTUUgZXh0ZW5kcyBVdGY4U3RyaW5nIHtcclxuICAgIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMgPSB7fSkge1xyXG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xyXG4gICAgICAgIHRoaXMuaWRCbG9jay50YWdDbGFzcyA9IDE7XHJcbiAgICAgICAgdGhpcy5pZEJsb2NrLnRhZ051bWJlciA9IDE0O1xyXG4gICAgfVxyXG59XHJcbl9hID0gVElNRTtcclxuKCgpID0+IHtcclxuICAgIHR5cGVTdG9yZS5USU1FID0gX2E7XHJcbn0pKCk7XHJcblRJTUUuTkFNRSA9IFwiVElNRVwiO1xuXG5jbGFzcyBBbnkge1xyXG4gICAgY29uc3RydWN0b3IoeyBuYW1lID0gRU1QVFlfU1RSSU5HLCBvcHRpb25hbCA9IGZhbHNlLCB9ID0ge30pIHtcclxuICAgICAgICB0aGlzLm5hbWUgPSBuYW1lO1xyXG4gICAgICAgIHRoaXMub3B0aW9uYWwgPSBvcHRpb25hbDtcclxuICAgIH1cclxufVxuXG5jbGFzcyBDaG9pY2UgZXh0ZW5kcyBBbnkge1xyXG4gICAgY29uc3RydWN0b3IoeyB2YWx1ZSA9IFtdLCAuLi5wYXJhbWV0ZXJzIH0gPSB7fSkge1xyXG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xyXG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcclxuICAgIH1cclxufVxuXG5jbGFzcyBSZXBlYXRlZCBleHRlbmRzIEFueSB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7IHZhbHVlID0gbmV3IEFueSgpLCBsb2NhbCA9IGZhbHNlLCAuLi5wYXJhbWV0ZXJzIH0gPSB7fSkge1xyXG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xyXG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcclxuICAgICAgICB0aGlzLmxvY2FsID0gbG9jYWw7XHJcbiAgICB9XHJcbn1cblxuY2xhc3MgUmF3RGF0YSB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7IGRhdGEgPSBFTVBUWV9WSUVXIH0gPSB7fSkge1xyXG4gICAgICAgIHRoaXMuZGF0YVZpZXcgPSBwdnRzdXRpbHMuQnVmZmVyU291cmNlQ29udmVydGVyLnRvVWludDhBcnJheShkYXRhKTtcclxuICAgIH1cclxuICAgIGdldCBkYXRhKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmRhdGFWaWV3LnNsaWNlKCkuYnVmZmVyO1xyXG4gICAgfVxyXG4gICAgc2V0IGRhdGEodmFsdWUpIHtcclxuICAgICAgICB0aGlzLmRhdGFWaWV3ID0gcHZ0c3V0aWxzLkJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b1VpbnQ4QXJyYXkodmFsdWUpO1xyXG4gICAgfVxyXG4gICAgZnJvbUJFUihpbnB1dEJ1ZmZlciwgaW5wdXRPZmZzZXQsIGlucHV0TGVuZ3RoKSB7XHJcbiAgICAgICAgY29uc3QgZW5kTGVuZ3RoID0gaW5wdXRPZmZzZXQgKyBpbnB1dExlbmd0aDtcclxuICAgICAgICB0aGlzLmRhdGFWaWV3ID0gcHZ0c3V0aWxzLkJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b1VpbnQ4QXJyYXkoaW5wdXRCdWZmZXIpLnN1YmFycmF5KGlucHV0T2Zmc2V0LCBlbmRMZW5ndGgpO1xyXG4gICAgICAgIHJldHVybiBlbmRMZW5ndGg7XHJcbiAgICB9XHJcbiAgICB0b0JFUihzaXplT25seSkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmRhdGFWaWV3LnNsaWNlKCkuYnVmZmVyO1xyXG4gICAgfVxyXG59XG5cbmZ1bmN0aW9uIGNvbXBhcmVTY2hlbWEocm9vdCwgaW5wdXREYXRhLCBpbnB1dFNjaGVtYSkge1xyXG4gICAgaWYgKGlucHV0U2NoZW1hIGluc3RhbmNlb2YgQ2hvaWNlKSB7XHJcbiAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBpbnB1dFNjaGVtYS52YWx1ZS5sZW5ndGg7IGorKykge1xyXG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBjb21wYXJlU2NoZW1hKHJvb3QsIGlucHV0RGF0YSwgaW5wdXRTY2hlbWEudmFsdWVbal0pO1xyXG4gICAgICAgICAgICBpZiAocmVzdWx0LnZlcmlmaWVkKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHZlcmlmaWVkOiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdDogcm9vdFxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICB7XHJcbiAgICAgICAgICAgIGNvbnN0IF9yZXN1bHQgPSB7XHJcbiAgICAgICAgICAgICAgICB2ZXJpZmllZDogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICByZXN1bHQ6IHtcclxuICAgICAgICAgICAgICAgICAgICBlcnJvcjogXCJXcm9uZyB2YWx1ZXMgZm9yIENob2ljZSB0eXBlXCJcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIGlmIChpbnB1dFNjaGVtYS5oYXNPd25Qcm9wZXJ0eShOQU1FKSlcclxuICAgICAgICAgICAgICAgIF9yZXN1bHQubmFtZSA9IGlucHV0U2NoZW1hLm5hbWU7XHJcbiAgICAgICAgICAgIHJldHVybiBfcmVzdWx0O1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGlmIChpbnB1dFNjaGVtYSBpbnN0YW5jZW9mIEFueSkge1xyXG4gICAgICAgIGlmIChpbnB1dFNjaGVtYS5oYXNPd25Qcm9wZXJ0eShOQU1FKSlcclxuICAgICAgICAgICAgcm9vdFtpbnB1dFNjaGVtYS5uYW1lXSA9IGlucHV0RGF0YTtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICB2ZXJpZmllZDogdHJ1ZSxcclxuICAgICAgICAgICAgcmVzdWx0OiByb290XHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuICAgIGlmICgocm9vdCBpbnN0YW5jZW9mIE9iamVjdCkgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgdmVyaWZpZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICByZXN1bHQ6IHsgZXJyb3I6IFwiV3Jvbmcgcm9vdCBvYmplY3RcIiB9XHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuICAgIGlmICgoaW5wdXREYXRhIGluc3RhbmNlb2YgT2JqZWN0KSA9PT0gZmFsc2UpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICB2ZXJpZmllZDogZmFsc2UsXHJcbiAgICAgICAgICAgIHJlc3VsdDogeyBlcnJvcjogXCJXcm9uZyBBU04uMSBkYXRhXCIgfVxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbiAgICBpZiAoKGlucHV0U2NoZW1hIGluc3RhbmNlb2YgT2JqZWN0KSA9PT0gZmFsc2UpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICB2ZXJpZmllZDogZmFsc2UsXHJcbiAgICAgICAgICAgIHJlc3VsdDogeyBlcnJvcjogXCJXcm9uZyBBU04uMSBzY2hlbWFcIiB9XHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuICAgIGlmICgoSURfQkxPQ0sgaW4gaW5wdXRTY2hlbWEpID09PSBmYWxzZSkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIHZlcmlmaWVkOiBmYWxzZSxcclxuICAgICAgICAgICAgcmVzdWx0OiB7IGVycm9yOiBcIldyb25nIEFTTi4xIHNjaGVtYVwiIH1cclxuICAgICAgICB9O1xyXG4gICAgfVxyXG4gICAgaWYgKChGUk9NX0JFUiBpbiBpbnB1dFNjaGVtYS5pZEJsb2NrKSA9PT0gZmFsc2UpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICB2ZXJpZmllZDogZmFsc2UsXHJcbiAgICAgICAgICAgIHJlc3VsdDogeyBlcnJvcjogXCJXcm9uZyBBU04uMSBzY2hlbWFcIiB9XHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuICAgIGlmICgoVE9fQkVSIGluIGlucHV0U2NoZW1hLmlkQmxvY2spID09PSBmYWxzZSkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIHZlcmlmaWVkOiBmYWxzZSxcclxuICAgICAgICAgICAgcmVzdWx0OiB7IGVycm9yOiBcIldyb25nIEFTTi4xIHNjaGVtYVwiIH1cclxuICAgICAgICB9O1xyXG4gICAgfVxyXG4gICAgY29uc3QgZW5jb2RlZElkID0gaW5wdXRTY2hlbWEuaWRCbG9jay50b0JFUihmYWxzZSk7XHJcbiAgICBpZiAoZW5jb2RlZElkLmJ5dGVMZW5ndGggPT09IDApIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICB2ZXJpZmllZDogZmFsc2UsXHJcbiAgICAgICAgICAgIHJlc3VsdDogeyBlcnJvcjogXCJFcnJvciBlbmNvZGluZyBpZEJsb2NrIGZvciBBU04uMSBzY2hlbWFcIiB9XHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuICAgIGNvbnN0IGRlY29kZWRPZmZzZXQgPSBpbnB1dFNjaGVtYS5pZEJsb2NrLmZyb21CRVIoZW5jb2RlZElkLCAwLCBlbmNvZGVkSWQuYnl0ZUxlbmd0aCk7XHJcbiAgICBpZiAoZGVjb2RlZE9mZnNldCA9PT0gLTEpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICB2ZXJpZmllZDogZmFsc2UsXHJcbiAgICAgICAgICAgIHJlc3VsdDogeyBlcnJvcjogXCJFcnJvciBkZWNvZGluZyBpZEJsb2NrIGZvciBBU04uMSBzY2hlbWFcIiB9XHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuICAgIGlmIChpbnB1dFNjaGVtYS5pZEJsb2NrLmhhc093blByb3BlcnR5KFRBR19DTEFTUykgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgdmVyaWZpZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICByZXN1bHQ6IHsgZXJyb3I6IFwiV3JvbmcgQVNOLjEgc2NoZW1hXCIgfVxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbiAgICBpZiAoaW5wdXRTY2hlbWEuaWRCbG9jay50YWdDbGFzcyAhPT0gaW5wdXREYXRhLmlkQmxvY2sudGFnQ2xhc3MpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICB2ZXJpZmllZDogZmFsc2UsXHJcbiAgICAgICAgICAgIHJlc3VsdDogcm9vdFxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbiAgICBpZiAoaW5wdXRTY2hlbWEuaWRCbG9jay5oYXNPd25Qcm9wZXJ0eShUQUdfTlVNQkVSKSA9PT0gZmFsc2UpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICB2ZXJpZmllZDogZmFsc2UsXHJcbiAgICAgICAgICAgIHJlc3VsdDogeyBlcnJvcjogXCJXcm9uZyBBU04uMSBzY2hlbWFcIiB9XHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuICAgIGlmIChpbnB1dFNjaGVtYS5pZEJsb2NrLnRhZ051bWJlciAhPT0gaW5wdXREYXRhLmlkQmxvY2sudGFnTnVtYmVyKSB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgdmVyaWZpZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICByZXN1bHQ6IHJvb3RcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG4gICAgaWYgKGlucHV0U2NoZW1hLmlkQmxvY2suaGFzT3duUHJvcGVydHkoSVNfQ09OU1RSVUNURUQpID09PSBmYWxzZSkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIHZlcmlmaWVkOiBmYWxzZSxcclxuICAgICAgICAgICAgcmVzdWx0OiB7IGVycm9yOiBcIldyb25nIEFTTi4xIHNjaGVtYVwiIH1cclxuICAgICAgICB9O1xyXG4gICAgfVxyXG4gICAgaWYgKGlucHV0U2NoZW1hLmlkQmxvY2suaXNDb25zdHJ1Y3RlZCAhPT0gaW5wdXREYXRhLmlkQmxvY2suaXNDb25zdHJ1Y3RlZCkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIHZlcmlmaWVkOiBmYWxzZSxcclxuICAgICAgICAgICAgcmVzdWx0OiByb290XHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuICAgIGlmICghKElTX0hFWF9PTkxZIGluIGlucHV0U2NoZW1hLmlkQmxvY2spKSB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgdmVyaWZpZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICByZXN1bHQ6IHsgZXJyb3I6IFwiV3JvbmcgQVNOLjEgc2NoZW1hXCIgfVxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbiAgICBpZiAoaW5wdXRTY2hlbWEuaWRCbG9jay5pc0hleE9ubHkgIT09IGlucHV0RGF0YS5pZEJsb2NrLmlzSGV4T25seSkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIHZlcmlmaWVkOiBmYWxzZSxcclxuICAgICAgICAgICAgcmVzdWx0OiByb290XHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuICAgIGlmIChpbnB1dFNjaGVtYS5pZEJsb2NrLmlzSGV4T25seSkge1xyXG4gICAgICAgIGlmICgoVkFMVUVfSEVYX1ZJRVcgaW4gaW5wdXRTY2hlbWEuaWRCbG9jaykgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICB2ZXJpZmllZDogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICByZXN1bHQ6IHsgZXJyb3I6IFwiV3JvbmcgQVNOLjEgc2NoZW1hXCIgfVxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBzY2hlbWFWaWV3ID0gaW5wdXRTY2hlbWEuaWRCbG9jay52YWx1ZUhleFZpZXc7XHJcbiAgICAgICAgY29uc3QgYXNuMVZpZXcgPSBpbnB1dERhdGEuaWRCbG9jay52YWx1ZUhleFZpZXc7XHJcbiAgICAgICAgaWYgKHNjaGVtYVZpZXcubGVuZ3RoICE9PSBhc24xVmlldy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIHZlcmlmaWVkOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgIHJlc3VsdDogcm9vdFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH1cclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNjaGVtYVZpZXcubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgaWYgKHNjaGVtYVZpZXdbaV0gIT09IGFzbjFWaWV3WzFdKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHZlcmlmaWVkOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgICAgICByZXN1bHQ6IHJvb3RcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAoaW5wdXRTY2hlbWEubmFtZSkge1xyXG4gICAgICAgIGlucHV0U2NoZW1hLm5hbWUgPSBpbnB1dFNjaGVtYS5uYW1lLnJlcGxhY2UoL15cXHMrfFxccyskL2csIEVNUFRZX1NUUklORyk7XHJcbiAgICAgICAgaWYgKGlucHV0U2NoZW1hLm5hbWUpXHJcbiAgICAgICAgICAgIHJvb3RbaW5wdXRTY2hlbWEubmFtZV0gPSBpbnB1dERhdGE7XHJcbiAgICB9XHJcbiAgICBpZiAoaW5wdXRTY2hlbWEgaW5zdGFuY2VvZiB0eXBlU3RvcmUuQ29uc3RydWN0ZWQpIHtcclxuICAgICAgICBsZXQgYWRtaXNzaW9uID0gMDtcclxuICAgICAgICBsZXQgcmVzdWx0ID0ge1xyXG4gICAgICAgICAgICB2ZXJpZmllZDogZmFsc2UsXHJcbiAgICAgICAgICAgIHJlc3VsdDoge1xyXG4gICAgICAgICAgICAgICAgZXJyb3I6IFwiVW5rbm93biBlcnJvclwiLFxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICBsZXQgbWF4TGVuZ3RoID0gaW5wdXRTY2hlbWEudmFsdWVCbG9jay52YWx1ZS5sZW5ndGg7XHJcbiAgICAgICAgaWYgKG1heExlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgaWYgKGlucHV0U2NoZW1hLnZhbHVlQmxvY2sudmFsdWVbMF0gaW5zdGFuY2VvZiBSZXBlYXRlZCkge1xyXG4gICAgICAgICAgICAgICAgbWF4TGVuZ3RoID0gaW5wdXREYXRhLnZhbHVlQmxvY2sudmFsdWUubGVuZ3RoO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChtYXhMZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIHZlcmlmaWVkOiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgcmVzdWx0OiByb290XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICgoaW5wdXREYXRhLnZhbHVlQmxvY2sudmFsdWUubGVuZ3RoID09PSAwKSAmJlxyXG4gICAgICAgICAgICAoaW5wdXRTY2hlbWEudmFsdWVCbG9jay52YWx1ZS5sZW5ndGggIT09IDApKSB7XHJcbiAgICAgICAgICAgIGxldCBfb3B0aW9uYWwgPSB0cnVlO1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGlucHV0U2NoZW1hLnZhbHVlQmxvY2sudmFsdWUubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgICAgICAgICBfb3B0aW9uYWwgPSBfb3B0aW9uYWwgJiYgKGlucHV0U2NoZW1hLnZhbHVlQmxvY2sudmFsdWVbaV0ub3B0aW9uYWwgfHwgZmFsc2UpO1xyXG4gICAgICAgICAgICBpZiAoX29wdGlvbmFsKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHZlcmlmaWVkOiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdDogcm9vdFxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoaW5wdXRTY2hlbWEubmFtZSkge1xyXG4gICAgICAgICAgICAgICAgaW5wdXRTY2hlbWEubmFtZSA9IGlucHV0U2NoZW1hLm5hbWUucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgRU1QVFlfU1RSSU5HKTtcclxuICAgICAgICAgICAgICAgIGlmIChpbnB1dFNjaGVtYS5uYW1lKVxyXG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSByb290W2lucHV0U2NoZW1hLm5hbWVdO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJvb3QuZXJyb3IgPSBcIkluY29uc2lzdGVudCBvYmplY3QgbGVuZ3RoXCI7XHJcbiAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICB2ZXJpZmllZDogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICByZXN1bHQ6IHJvb3RcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtYXhMZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBpZiAoKGkgLSBhZG1pc3Npb24pID49IGlucHV0RGF0YS52YWx1ZUJsb2NrLnZhbHVlLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGlucHV0U2NoZW1hLnZhbHVlQmxvY2sudmFsdWVbaV0ub3B0aW9uYWwgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgX3Jlc3VsdCA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmVyaWZpZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQ6IHJvb3RcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIHJvb3QuZXJyb3IgPSBcIkluY29uc2lzdGVudCBsZW5ndGggYmV0d2VlbiBBU04uMSBkYXRhIGFuZCBzY2hlbWFcIjtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoaW5wdXRTY2hlbWEubmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbnB1dFNjaGVtYS5uYW1lID0gaW5wdXRTY2hlbWEubmFtZS5yZXBsYWNlKC9eXFxzK3xcXHMrJC9nLCBFTVBUWV9TVFJJTkcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5wdXRTY2hlbWEubmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHJvb3RbaW5wdXRTY2hlbWEubmFtZV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfcmVzdWx0Lm5hbWUgPSBpbnB1dFNjaGVtYS5uYW1lO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfcmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgaWYgKGlucHV0U2NoZW1hLnZhbHVlQmxvY2sudmFsdWVbMF0gaW5zdGFuY2VvZiBSZXBlYXRlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGNvbXBhcmVTY2hlbWEocm9vdCwgaW5wdXREYXRhLnZhbHVlQmxvY2sudmFsdWVbaV0sIGlucHV0U2NoZW1hLnZhbHVlQmxvY2sudmFsdWVbMF0udmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQudmVyaWZpZWQgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbnB1dFNjaGVtYS52YWx1ZUJsb2NrLnZhbHVlWzBdLm9wdGlvbmFsKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRtaXNzaW9uKys7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlucHV0U2NoZW1hLm5hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dFNjaGVtYS5uYW1lID0gaW5wdXRTY2hlbWEubmFtZS5yZXBsYWNlKC9eXFxzK3xcXHMrJC9nLCBFTVBUWV9TVFJJTkcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbnB1dFNjaGVtYS5uYW1lKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgcm9vdFtpbnB1dFNjaGVtYS5uYW1lXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKChOQU1FIGluIGlucHV0U2NoZW1hLnZhbHVlQmxvY2sudmFsdWVbMF0pICYmIChpbnB1dFNjaGVtYS52YWx1ZUJsb2NrLnZhbHVlWzBdLm5hbWUubGVuZ3RoID4gMCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGFycmF5Um9vdCA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoKExPQ0FMIGluIGlucHV0U2NoZW1hLnZhbHVlQmxvY2sudmFsdWVbMF0pICYmIChpbnB1dFNjaGVtYS52YWx1ZUJsb2NrLnZhbHVlWzBdLmxvY2FsKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5Um9vdCA9IGlucHV0RGF0YTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyYXlSb290ID0gcm9vdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBhcnJheVJvb3RbaW5wdXRTY2hlbWEudmFsdWVCbG9jay52YWx1ZVswXS5uYW1lXSA9PT0gXCJ1bmRlZmluZWRcIilcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5Um9vdFtpbnB1dFNjaGVtYS52YWx1ZUJsb2NrLnZhbHVlWzBdLm5hbWVdID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5Um9vdFtpbnB1dFNjaGVtYS52YWx1ZUJsb2NrLnZhbHVlWzBdLm5hbWVdLnB1c2goaW5wdXREYXRhLnZhbHVlQmxvY2sudmFsdWVbaV0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGNvbXBhcmVTY2hlbWEocm9vdCwgaW5wdXREYXRhLnZhbHVlQmxvY2sudmFsdWVbaSAtIGFkbWlzc2lvbl0sIGlucHV0U2NoZW1hLnZhbHVlQmxvY2sudmFsdWVbaV0pO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQudmVyaWZpZWQgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbnB1dFNjaGVtYS52YWx1ZUJsb2NrLnZhbHVlW2ldLm9wdGlvbmFsKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRtaXNzaW9uKys7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlucHV0U2NoZW1hLm5hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dFNjaGVtYS5uYW1lID0gaW5wdXRTY2hlbWEubmFtZS5yZXBsYWNlKC9eXFxzK3xcXHMrJC9nLCBFTVBUWV9TVFJJTkcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbnB1dFNjaGVtYS5uYW1lKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgcm9vdFtpbnB1dFNjaGVtYS5uYW1lXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHJlc3VsdC52ZXJpZmllZCA9PT0gZmFsc2UpIHtcclxuICAgICAgICAgICAgY29uc3QgX3Jlc3VsdCA9IHtcclxuICAgICAgICAgICAgICAgIHZlcmlmaWVkOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgIHJlc3VsdDogcm9vdFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBpZiAoaW5wdXRTY2hlbWEubmFtZSkge1xyXG4gICAgICAgICAgICAgICAgaW5wdXRTY2hlbWEubmFtZSA9IGlucHV0U2NoZW1hLm5hbWUucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgRU1QVFlfU1RSSU5HKTtcclxuICAgICAgICAgICAgICAgIGlmIChpbnB1dFNjaGVtYS5uYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHJvb3RbaW5wdXRTY2hlbWEubmFtZV07XHJcbiAgICAgICAgICAgICAgICAgICAgX3Jlc3VsdC5uYW1lID0gaW5wdXRTY2hlbWEubmFtZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gX3Jlc3VsdDtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgdmVyaWZpZWQ6IHRydWUsXHJcbiAgICAgICAgICAgIHJlc3VsdDogcm9vdFxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbiAgICBpZiAoaW5wdXRTY2hlbWEucHJpbWl0aXZlU2NoZW1hICYmXHJcbiAgICAgICAgKFZBTFVFX0hFWF9WSUVXIGluIGlucHV0RGF0YS52YWx1ZUJsb2NrKSkge1xyXG4gICAgICAgIGNvbnN0IGFzbjEgPSBsb2NhbEZyb21CRVIoaW5wdXREYXRhLnZhbHVlQmxvY2sudmFsdWVIZXhWaWV3KTtcclxuICAgICAgICBpZiAoYXNuMS5vZmZzZXQgPT09IC0xKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IF9yZXN1bHQgPSB7XHJcbiAgICAgICAgICAgICAgICB2ZXJpZmllZDogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICByZXN1bHQ6IGFzbjEucmVzdWx0XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIGlmIChpbnB1dFNjaGVtYS5uYW1lKSB7XHJcbiAgICAgICAgICAgICAgICBpbnB1dFNjaGVtYS5uYW1lID0gaW5wdXRTY2hlbWEubmFtZS5yZXBsYWNlKC9eXFxzK3xcXHMrJC9nLCBFTVBUWV9TVFJJTkcpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGlucHV0U2NoZW1hLm5hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICBkZWxldGUgcm9vdFtpbnB1dFNjaGVtYS5uYW1lXTtcclxuICAgICAgICAgICAgICAgICAgICBfcmVzdWx0Lm5hbWUgPSBpbnB1dFNjaGVtYS5uYW1lO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBfcmVzdWx0O1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gY29tcGFyZVNjaGVtYShyb290LCBhc24xLnJlc3VsdCwgaW5wdXRTY2hlbWEucHJpbWl0aXZlU2NoZW1hKTtcclxuICAgIH1cclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgdmVyaWZpZWQ6IHRydWUsXHJcbiAgICAgICAgcmVzdWx0OiByb290XHJcbiAgICB9O1xyXG59XHJcbmZ1bmN0aW9uIHZlcmlmeVNjaGVtYShpbnB1dEJ1ZmZlciwgaW5wdXRTY2hlbWEpIHtcclxuICAgIGlmICgoaW5wdXRTY2hlbWEgaW5zdGFuY2VvZiBPYmplY3QpID09PSBmYWxzZSkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIHZlcmlmaWVkOiBmYWxzZSxcclxuICAgICAgICAgICAgcmVzdWx0OiB7IGVycm9yOiBcIldyb25nIEFTTi4xIHNjaGVtYSB0eXBlXCIgfVxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbiAgICBjb25zdCBhc24xID0gbG9jYWxGcm9tQkVSKHB2dHN1dGlscy5CdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9VaW50OEFycmF5KGlucHV0QnVmZmVyKSk7XHJcbiAgICBpZiAoYXNuMS5vZmZzZXQgPT09IC0xKSB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgdmVyaWZpZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICByZXN1bHQ6IGFzbjEucmVzdWx0XHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuICAgIHJldHVybiBjb21wYXJlU2NoZW1hKGFzbjEucmVzdWx0LCBhc24xLnJlc3VsdCwgaW5wdXRTY2hlbWEpO1xyXG59XG5cbmV4cG9ydCB7IEFueSwgQmFzZUJsb2NrLCBCYXNlU3RyaW5nQmxvY2ssIEJpdFN0cmluZywgQm1wU3RyaW5nLCBCb29sZWFuLCBDaGFyYWN0ZXJTdHJpbmcsIENob2ljZSwgQ29uc3RydWN0ZWQsIERBVEUsIERhdGVUaW1lLCBEdXJhdGlvbiwgRW5kT2ZDb250ZW50LCBFbnVtZXJhdGVkLCBHZW5lcmFsU3RyaW5nLCBHZW5lcmFsaXplZFRpbWUsIEdyYXBoaWNTdHJpbmcsIEhleEJsb2NrLCBJQTVTdHJpbmcsIEludGVnZXIsIE51bGwsIE51bWVyaWNTdHJpbmcsIE9iamVjdElkZW50aWZpZXIsIE9jdGV0U3RyaW5nLCBQcmltaXRpdmUsIFByaW50YWJsZVN0cmluZywgUmF3RGF0YSwgUmVsYXRpdmVPYmplY3RJZGVudGlmaWVyLCBSZXBlYXRlZCwgU2VxdWVuY2UsIFNldCwgVElNRSwgVGVsZXRleFN0cmluZywgVGltZU9mRGF5LCBVVENUaW1lLCBVbml2ZXJzYWxTdHJpbmcsIFV0ZjhTdHJpbmcsIFZhbHVlQmxvY2ssIFZpZGVvdGV4U3RyaW5nLCBWaWV3V3JpdGVyLCBWaXNpYmxlU3RyaW5nLCBjb21wYXJlU2NoZW1hLCBmcm9tQkVSLCB2ZXJpZnlTY2hlbWEgfTtcbiIsICJleHBvcnQgdmFyIEFzblR5cGVUeXBlcztcbihmdW5jdGlvbiAoQXNuVHlwZVR5cGVzKSB7XG4gICAgQXNuVHlwZVR5cGVzW0FzblR5cGVUeXBlc1tcIlNlcXVlbmNlXCJdID0gMF0gPSBcIlNlcXVlbmNlXCI7XG4gICAgQXNuVHlwZVR5cGVzW0FzblR5cGVUeXBlc1tcIlNldFwiXSA9IDFdID0gXCJTZXRcIjtcbiAgICBBc25UeXBlVHlwZXNbQXNuVHlwZVR5cGVzW1wiQ2hvaWNlXCJdID0gMl0gPSBcIkNob2ljZVwiO1xufSkoQXNuVHlwZVR5cGVzIHx8IChBc25UeXBlVHlwZXMgPSB7fSkpO1xuZXhwb3J0IHZhciBBc25Qcm9wVHlwZXM7XG4oZnVuY3Rpb24gKEFzblByb3BUeXBlcykge1xuICAgIEFzblByb3BUeXBlc1tBc25Qcm9wVHlwZXNbXCJBbnlcIl0gPSAxXSA9IFwiQW55XCI7XG4gICAgQXNuUHJvcFR5cGVzW0FzblByb3BUeXBlc1tcIkJvb2xlYW5cIl0gPSAyXSA9IFwiQm9vbGVhblwiO1xuICAgIEFzblByb3BUeXBlc1tBc25Qcm9wVHlwZXNbXCJPY3RldFN0cmluZ1wiXSA9IDNdID0gXCJPY3RldFN0cmluZ1wiO1xuICAgIEFzblByb3BUeXBlc1tBc25Qcm9wVHlwZXNbXCJCaXRTdHJpbmdcIl0gPSA0XSA9IFwiQml0U3RyaW5nXCI7XG4gICAgQXNuUHJvcFR5cGVzW0FzblByb3BUeXBlc1tcIkludGVnZXJcIl0gPSA1XSA9IFwiSW50ZWdlclwiO1xuICAgIEFzblByb3BUeXBlc1tBc25Qcm9wVHlwZXNbXCJFbnVtZXJhdGVkXCJdID0gNl0gPSBcIkVudW1lcmF0ZWRcIjtcbiAgICBBc25Qcm9wVHlwZXNbQXNuUHJvcFR5cGVzW1wiT2JqZWN0SWRlbnRpZmllclwiXSA9IDddID0gXCJPYmplY3RJZGVudGlmaWVyXCI7XG4gICAgQXNuUHJvcFR5cGVzW0FzblByb3BUeXBlc1tcIlV0ZjhTdHJpbmdcIl0gPSA4XSA9IFwiVXRmOFN0cmluZ1wiO1xuICAgIEFzblByb3BUeXBlc1tBc25Qcm9wVHlwZXNbXCJCbXBTdHJpbmdcIl0gPSA5XSA9IFwiQm1wU3RyaW5nXCI7XG4gICAgQXNuUHJvcFR5cGVzW0FzblByb3BUeXBlc1tcIlVuaXZlcnNhbFN0cmluZ1wiXSA9IDEwXSA9IFwiVW5pdmVyc2FsU3RyaW5nXCI7XG4gICAgQXNuUHJvcFR5cGVzW0FzblByb3BUeXBlc1tcIk51bWVyaWNTdHJpbmdcIl0gPSAxMV0gPSBcIk51bWVyaWNTdHJpbmdcIjtcbiAgICBBc25Qcm9wVHlwZXNbQXNuUHJvcFR5cGVzW1wiUHJpbnRhYmxlU3RyaW5nXCJdID0gMTJdID0gXCJQcmludGFibGVTdHJpbmdcIjtcbiAgICBBc25Qcm9wVHlwZXNbQXNuUHJvcFR5cGVzW1wiVGVsZXRleFN0cmluZ1wiXSA9IDEzXSA9IFwiVGVsZXRleFN0cmluZ1wiO1xuICAgIEFzblByb3BUeXBlc1tBc25Qcm9wVHlwZXNbXCJWaWRlb3RleFN0cmluZ1wiXSA9IDE0XSA9IFwiVmlkZW90ZXhTdHJpbmdcIjtcbiAgICBBc25Qcm9wVHlwZXNbQXNuUHJvcFR5cGVzW1wiSUE1U3RyaW5nXCJdID0gMTVdID0gXCJJQTVTdHJpbmdcIjtcbiAgICBBc25Qcm9wVHlwZXNbQXNuUHJvcFR5cGVzW1wiR3JhcGhpY1N0cmluZ1wiXSA9IDE2XSA9IFwiR3JhcGhpY1N0cmluZ1wiO1xuICAgIEFzblByb3BUeXBlc1tBc25Qcm9wVHlwZXNbXCJWaXNpYmxlU3RyaW5nXCJdID0gMTddID0gXCJWaXNpYmxlU3RyaW5nXCI7XG4gICAgQXNuUHJvcFR5cGVzW0FzblByb3BUeXBlc1tcIkdlbmVyYWxTdHJpbmdcIl0gPSAxOF0gPSBcIkdlbmVyYWxTdHJpbmdcIjtcbiAgICBBc25Qcm9wVHlwZXNbQXNuUHJvcFR5cGVzW1wiQ2hhcmFjdGVyU3RyaW5nXCJdID0gMTldID0gXCJDaGFyYWN0ZXJTdHJpbmdcIjtcbiAgICBBc25Qcm9wVHlwZXNbQXNuUHJvcFR5cGVzW1wiVVRDVGltZVwiXSA9IDIwXSA9IFwiVVRDVGltZVwiO1xuICAgIEFzblByb3BUeXBlc1tBc25Qcm9wVHlwZXNbXCJHZW5lcmFsaXplZFRpbWVcIl0gPSAyMV0gPSBcIkdlbmVyYWxpemVkVGltZVwiO1xuICAgIEFzblByb3BUeXBlc1tBc25Qcm9wVHlwZXNbXCJEQVRFXCJdID0gMjJdID0gXCJEQVRFXCI7XG4gICAgQXNuUHJvcFR5cGVzW0FzblByb3BUeXBlc1tcIlRpbWVPZkRheVwiXSA9IDIzXSA9IFwiVGltZU9mRGF5XCI7XG4gICAgQXNuUHJvcFR5cGVzW0FzblByb3BUeXBlc1tcIkRhdGVUaW1lXCJdID0gMjRdID0gXCJEYXRlVGltZVwiO1xuICAgIEFzblByb3BUeXBlc1tBc25Qcm9wVHlwZXNbXCJEdXJhdGlvblwiXSA9IDI1XSA9IFwiRHVyYXRpb25cIjtcbiAgICBBc25Qcm9wVHlwZXNbQXNuUHJvcFR5cGVzW1wiVElNRVwiXSA9IDI2XSA9IFwiVElNRVwiO1xuICAgIEFzblByb3BUeXBlc1tBc25Qcm9wVHlwZXNbXCJOdWxsXCJdID0gMjddID0gXCJOdWxsXCI7XG59KShBc25Qcm9wVHlwZXMgfHwgKEFzblByb3BUeXBlcyA9IHt9KSk7XG4iLCAiaW1wb3J0ICogYXMgYXNuMWpzIGZyb20gXCJhc24xanNcIjtcbmltcG9ydCB7IEJ1ZmZlclNvdXJjZUNvbnZlcnRlciB9IGZyb20gXCJwdnRzdXRpbHNcIjtcbmV4cG9ydCBjbGFzcyBCaXRTdHJpbmcge1xuICAgIGNvbnN0cnVjdG9yKHBhcmFtcywgdW51c2VkQml0cyA9IDApIHtcbiAgICAgICAgdGhpcy51bnVzZWRCaXRzID0gMDtcbiAgICAgICAgdGhpcy52YWx1ZSA9IG5ldyBBcnJheUJ1ZmZlcigwKTtcbiAgICAgICAgaWYgKHBhcmFtcykge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBwYXJhbXMgPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZyb21OdW1iZXIocGFyYW1zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKEJ1ZmZlclNvdXJjZUNvbnZlcnRlci5pc0J1ZmZlclNvdXJjZShwYXJhbXMpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy51bnVzZWRCaXRzID0gdW51c2VkQml0cztcbiAgICAgICAgICAgICAgICB0aGlzLnZhbHVlID0gQnVmZmVyU291cmNlQ29udmVydGVyLnRvQXJyYXlCdWZmZXIocGFyYW1zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIlVuc3VwcG9ydGVkIHR5cGUgb2YgJ3BhcmFtcycgYXJndW1lbnQgZm9yIEJpdFN0cmluZ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBmcm9tQVNOKGFzbikge1xuICAgICAgICBpZiAoIShhc24gaW5zdGFuY2VvZiBhc24xanMuQml0U3RyaW5nKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkFyZ3VtZW50ICdhc24nIGlzIG5vdCBpbnN0YW5jZSBvZiBBU04uMSBCaXRTdHJpbmdcIik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy51bnVzZWRCaXRzID0gYXNuLnZhbHVlQmxvY2sudW51c2VkQml0cztcbiAgICAgICAgdGhpcy52YWx1ZSA9IGFzbi52YWx1ZUJsb2NrLnZhbHVlSGV4O1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgdG9BU04oKSB7XG4gICAgICAgIHJldHVybiBuZXcgYXNuMWpzLkJpdFN0cmluZyh7IHVudXNlZEJpdHM6IHRoaXMudW51c2VkQml0cywgdmFsdWVIZXg6IHRoaXMudmFsdWUgfSk7XG4gICAgfVxuICAgIHRvU2NoZW1hKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBhc24xanMuQml0U3RyaW5nKHsgbmFtZSB9KTtcbiAgICB9XG4gICAgdG9OdW1iZXIoKSB7XG4gICAgICAgIGxldCByZXMgPSBcIlwiO1xuICAgICAgICBjb25zdCB1aW50QXJyYXkgPSBuZXcgVWludDhBcnJheSh0aGlzLnZhbHVlKTtcbiAgICAgICAgZm9yIChjb25zdCBvY3RldCBvZiB1aW50QXJyYXkpIHtcbiAgICAgICAgICAgIHJlcyArPSBvY3RldC50b1N0cmluZygyKS5wYWRTdGFydCg4LCBcIjBcIik7XG4gICAgICAgIH1cbiAgICAgICAgcmVzID0gcmVzLnNwbGl0KFwiXCIpLnJldmVyc2UoKS5qb2luKFwiXCIpO1xuICAgICAgICBpZiAodGhpcy51bnVzZWRCaXRzKSB7XG4gICAgICAgICAgICByZXMgPSByZXMuc2xpY2UodGhpcy51bnVzZWRCaXRzKS5wYWRTdGFydCh0aGlzLnVudXNlZEJpdHMsIFwiMFwiKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcGFyc2VJbnQocmVzLCAyKTtcbiAgICB9XG4gICAgZnJvbU51bWJlcih2YWx1ZSkge1xuICAgICAgICBsZXQgYml0cyA9IHZhbHVlLnRvU3RyaW5nKDIpO1xuICAgICAgICBjb25zdCBvY3RldFNpemUgPSAoYml0cy5sZW5ndGggKyA3KSA+PiAzO1xuICAgICAgICB0aGlzLnVudXNlZEJpdHMgPSAob2N0ZXRTaXplIDw8IDMpIC0gYml0cy5sZW5ndGg7XG4gICAgICAgIGNvbnN0IG9jdGV0cyA9IG5ldyBVaW50OEFycmF5KG9jdGV0U2l6ZSk7XG4gICAgICAgIGJpdHMgPSBiaXRzLnBhZFN0YXJ0KG9jdGV0U2l6ZSA8PCAzLCBcIjBcIikuc3BsaXQoXCJcIikucmV2ZXJzZSgpLmpvaW4oXCJcIik7XG4gICAgICAgIGxldCBpbmRleCA9IDA7XG4gICAgICAgIHdoaWxlIChpbmRleCA8IG9jdGV0U2l6ZSkge1xuICAgICAgICAgICAgb2N0ZXRzW2luZGV4XSA9IHBhcnNlSW50KGJpdHMuc2xpY2UoaW5kZXggPDwgMywgKGluZGV4IDw8IDMpICsgOCksIDIpO1xuICAgICAgICAgICAgaW5kZXgrKztcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnZhbHVlID0gb2N0ZXRzLmJ1ZmZlcjtcbiAgICB9XG59XG4iLCAiaW1wb3J0ICogYXMgYXNuMWpzIGZyb20gXCJhc24xanNcIjtcbmltcG9ydCB7IEJ1ZmZlclNvdXJjZUNvbnZlcnRlciB9IGZyb20gXCJwdnRzdXRpbHNcIjtcbmV4cG9ydCBjbGFzcyBPY3RldFN0cmluZyB7XG4gICAgZ2V0IGJ5dGVMZW5ndGgoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoO1xuICAgIH1cbiAgICBnZXQgYnl0ZU9mZnNldCgpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIGNvbnN0cnVjdG9yKHBhcmFtKSB7XG4gICAgICAgIGlmICh0eXBlb2YgcGFyYW0gPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgIHRoaXMuYnVmZmVyID0gbmV3IEFycmF5QnVmZmVyKHBhcmFtKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmIChCdWZmZXJTb3VyY2VDb252ZXJ0ZXIuaXNCdWZmZXJTb3VyY2UocGFyYW0pKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5idWZmZXIgPSBCdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9BcnJheUJ1ZmZlcihwYXJhbSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChBcnJheS5pc0FycmF5KHBhcmFtKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuYnVmZmVyID0gbmV3IFVpbnQ4QXJyYXkocGFyYW0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5idWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIoMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgZnJvbUFTTihhc24pIHtcbiAgICAgICAgaWYgKCEoYXNuIGluc3RhbmNlb2YgYXNuMWpzLk9jdGV0U3RyaW5nKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkFyZ3VtZW50ICdhc24nIGlzIG5vdCBpbnN0YW5jZSBvZiBBU04uMSBPY3RldFN0cmluZ1wiKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmJ1ZmZlciA9IGFzbi52YWx1ZUJsb2NrLnZhbHVlSGV4O1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgdG9BU04oKSB7XG4gICAgICAgIHJldHVybiBuZXcgYXNuMWpzLk9jdGV0U3RyaW5nKHsgdmFsdWVIZXg6IHRoaXMuYnVmZmVyIH0pO1xuICAgIH1cbiAgICB0b1NjaGVtYShuYW1lKSB7XG4gICAgICAgIHJldHVybiBuZXcgYXNuMWpzLk9jdGV0U3RyaW5nKHsgbmFtZSB9KTtcbiAgICB9XG59XG4iLCAiZXhwb3J0ICogZnJvbSBcIi4vYml0X3N0cmluZ1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vb2N0ZXRfc3RyaW5nXCI7XG4iLCAiaW1wb3J0ICogYXMgYXNuMWpzIGZyb20gXCJhc24xanNcIjtcbmltcG9ydCB7IEFzblByb3BUeXBlcyB9IGZyb20gXCIuL2VudW1zXCI7XG5pbXBvcnQgeyBPY3RldFN0cmluZyB9IGZyb20gXCIuL3R5cGVzL2luZGV4XCI7XG5leHBvcnQgY29uc3QgQXNuQW55Q29udmVydGVyID0ge1xuICAgIGZyb21BU046ICh2YWx1ZSkgPT4gdmFsdWUgaW5zdGFuY2VvZiBhc24xanMuTnVsbCA/IG51bGwgOiB2YWx1ZS52YWx1ZUJlZm9yZURlY29kZVZpZXcsXG4gICAgdG9BU046ICh2YWx1ZSkgPT4ge1xuICAgICAgICBpZiAodmFsdWUgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgYXNuMWpzLk51bGwoKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzY2hlbWEgPSBhc24xanMuZnJvbUJFUih2YWx1ZSk7XG4gICAgICAgIGlmIChzY2hlbWEucmVzdWx0LmVycm9yKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3Ioc2NoZW1hLnJlc3VsdC5lcnJvcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNjaGVtYS5yZXN1bHQ7XG4gICAgfSxcbn07XG5leHBvcnQgY29uc3QgQXNuSW50ZWdlckNvbnZlcnRlciA9IHtcbiAgICBmcm9tQVNOOiAodmFsdWUpID0+IHZhbHVlLnZhbHVlQmxvY2sudmFsdWVIZXhWaWV3LmJ5dGVMZW5ndGggPj0gNFxuICAgICAgICA/IHZhbHVlLnZhbHVlQmxvY2sudG9TdHJpbmcoKVxuICAgICAgICA6IHZhbHVlLnZhbHVlQmxvY2sudmFsdWVEZWMsXG4gICAgdG9BU046ICh2YWx1ZSkgPT4gbmV3IGFzbjFqcy5JbnRlZ2VyKHsgdmFsdWU6ICt2YWx1ZSB9KSxcbn07XG5leHBvcnQgY29uc3QgQXNuRW51bWVyYXRlZENvbnZlcnRlciA9IHtcbiAgICBmcm9tQVNOOiAodmFsdWUpID0+IHZhbHVlLnZhbHVlQmxvY2sudmFsdWVEZWMsXG4gICAgdG9BU046ICh2YWx1ZSkgPT4gbmV3IGFzbjFqcy5FbnVtZXJhdGVkKHsgdmFsdWUgfSksXG59O1xuZXhwb3J0IGNvbnN0IEFzbkludGVnZXJBcnJheUJ1ZmZlckNvbnZlcnRlciA9IHtcbiAgICBmcm9tQVNOOiAodmFsdWUpID0+IHZhbHVlLnZhbHVlQmxvY2sudmFsdWVIZXhWaWV3LFxuICAgIHRvQVNOOiAodmFsdWUpID0+IG5ldyBhc24xanMuSW50ZWdlcih7IHZhbHVlSGV4OiB2YWx1ZSB9KSxcbn07XG5leHBvcnQgY29uc3QgQXNuSW50ZWdlckJpZ0ludENvbnZlcnRlciA9IHtcbiAgICBmcm9tQVNOOiAodmFsdWUpID0+IHZhbHVlLnRvQmlnSW50KCksXG4gICAgdG9BU046ICh2YWx1ZSkgPT4gYXNuMWpzLkludGVnZXIuZnJvbUJpZ0ludCh2YWx1ZSksXG59O1xuZXhwb3J0IGNvbnN0IEFzbkJpdFN0cmluZ0NvbnZlcnRlciA9IHtcbiAgICBmcm9tQVNOOiAodmFsdWUpID0+IHZhbHVlLnZhbHVlQmxvY2sudmFsdWVIZXhWaWV3LFxuICAgIHRvQVNOOiAodmFsdWUpID0+IG5ldyBhc24xanMuQml0U3RyaW5nKHsgdmFsdWVIZXg6IHZhbHVlIH0pLFxufTtcbmV4cG9ydCBjb25zdCBBc25PYmplY3RJZGVudGlmaWVyQ29udmVydGVyID0ge1xuICAgIGZyb21BU046ICh2YWx1ZSkgPT4gdmFsdWUudmFsdWVCbG9jay50b1N0cmluZygpLFxuICAgIHRvQVNOOiAodmFsdWUpID0+IG5ldyBhc24xanMuT2JqZWN0SWRlbnRpZmllcih7IHZhbHVlIH0pLFxufTtcbmV4cG9ydCBjb25zdCBBc25Cb29sZWFuQ29udmVydGVyID0ge1xuICAgIGZyb21BU046ICh2YWx1ZSkgPT4gdmFsdWUudmFsdWVCbG9jay52YWx1ZSxcbiAgICB0b0FTTjogKHZhbHVlKSA9PiBuZXcgYXNuMWpzLkJvb2xlYW4oeyB2YWx1ZSB9KSxcbn07XG5leHBvcnQgY29uc3QgQXNuT2N0ZXRTdHJpbmdDb252ZXJ0ZXIgPSB7XG4gICAgZnJvbUFTTjogKHZhbHVlKSA9PiB2YWx1ZS52YWx1ZUJsb2NrLnZhbHVlSGV4VmlldyxcbiAgICB0b0FTTjogKHZhbHVlKSA9PiBuZXcgYXNuMWpzLk9jdGV0U3RyaW5nKHsgdmFsdWVIZXg6IHZhbHVlIH0pLFxufTtcbmV4cG9ydCBjb25zdCBBc25Db25zdHJ1Y3RlZE9jdGV0U3RyaW5nQ29udmVydGVyID0ge1xuICAgIGZyb21BU046ICh2YWx1ZSkgPT4gbmV3IE9jdGV0U3RyaW5nKHZhbHVlLmdldFZhbHVlKCkpLFxuICAgIHRvQVNOOiAodmFsdWUpID0+IHZhbHVlLnRvQVNOKCksXG59O1xuZnVuY3Rpb24gY3JlYXRlU3RyaW5nQ29udmVydGVyKEFzbjFUeXBlKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgZnJvbUFTTjogKHZhbHVlKSA9PiB2YWx1ZS52YWx1ZUJsb2NrLnZhbHVlLFxuICAgICAgICB0b0FTTjogKHZhbHVlKSA9PiBuZXcgQXNuMVR5cGUoeyB2YWx1ZSB9KSxcbiAgICB9O1xufVxuZXhwb3J0IGNvbnN0IEFzblV0ZjhTdHJpbmdDb252ZXJ0ZXIgPSBjcmVhdGVTdHJpbmdDb252ZXJ0ZXIoYXNuMWpzLlV0ZjhTdHJpbmcpO1xuZXhwb3J0IGNvbnN0IEFzbkJtcFN0cmluZ0NvbnZlcnRlciA9IGNyZWF0ZVN0cmluZ0NvbnZlcnRlcihhc24xanMuQm1wU3RyaW5nKTtcbmV4cG9ydCBjb25zdCBBc25Vbml2ZXJzYWxTdHJpbmdDb252ZXJ0ZXIgPSBjcmVhdGVTdHJpbmdDb252ZXJ0ZXIoYXNuMWpzLlVuaXZlcnNhbFN0cmluZyk7XG5leHBvcnQgY29uc3QgQXNuTnVtZXJpY1N0cmluZ0NvbnZlcnRlciA9IGNyZWF0ZVN0cmluZ0NvbnZlcnRlcihhc24xanMuTnVtZXJpY1N0cmluZyk7XG5leHBvcnQgY29uc3QgQXNuUHJpbnRhYmxlU3RyaW5nQ29udmVydGVyID0gY3JlYXRlU3RyaW5nQ29udmVydGVyKGFzbjFqcy5QcmludGFibGVTdHJpbmcpO1xuZXhwb3J0IGNvbnN0IEFzblRlbGV0ZXhTdHJpbmdDb252ZXJ0ZXIgPSBjcmVhdGVTdHJpbmdDb252ZXJ0ZXIoYXNuMWpzLlRlbGV0ZXhTdHJpbmcpO1xuZXhwb3J0IGNvbnN0IEFzblZpZGVvdGV4U3RyaW5nQ29udmVydGVyID0gY3JlYXRlU3RyaW5nQ29udmVydGVyKGFzbjFqcy5WaWRlb3RleFN0cmluZyk7XG5leHBvcnQgY29uc3QgQXNuSUE1U3RyaW5nQ29udmVydGVyID0gY3JlYXRlU3RyaW5nQ29udmVydGVyKGFzbjFqcy5JQTVTdHJpbmcpO1xuZXhwb3J0IGNvbnN0IEFzbkdyYXBoaWNTdHJpbmdDb252ZXJ0ZXIgPSBjcmVhdGVTdHJpbmdDb252ZXJ0ZXIoYXNuMWpzLkdyYXBoaWNTdHJpbmcpO1xuZXhwb3J0IGNvbnN0IEFzblZpc2libGVTdHJpbmdDb252ZXJ0ZXIgPSBjcmVhdGVTdHJpbmdDb252ZXJ0ZXIoYXNuMWpzLlZpc2libGVTdHJpbmcpO1xuZXhwb3J0IGNvbnN0IEFzbkdlbmVyYWxTdHJpbmdDb252ZXJ0ZXIgPSBjcmVhdGVTdHJpbmdDb252ZXJ0ZXIoYXNuMWpzLkdlbmVyYWxTdHJpbmcpO1xuZXhwb3J0IGNvbnN0IEFzbkNoYXJhY3RlclN0cmluZ0NvbnZlcnRlciA9IGNyZWF0ZVN0cmluZ0NvbnZlcnRlcihhc24xanMuQ2hhcmFjdGVyU3RyaW5nKTtcbmV4cG9ydCBjb25zdCBBc25VVENUaW1lQ29udmVydGVyID0ge1xuICAgIGZyb21BU046ICh2YWx1ZSkgPT4gdmFsdWUudG9EYXRlKCksXG4gICAgdG9BU046ICh2YWx1ZSkgPT4gbmV3IGFzbjFqcy5VVENUaW1lKHsgdmFsdWVEYXRlOiB2YWx1ZSB9KSxcbn07XG5leHBvcnQgY29uc3QgQXNuR2VuZXJhbGl6ZWRUaW1lQ29udmVydGVyID0ge1xuICAgIGZyb21BU046ICh2YWx1ZSkgPT4gdmFsdWUudG9EYXRlKCksXG4gICAgdG9BU046ICh2YWx1ZSkgPT4gbmV3IGFzbjFqcy5HZW5lcmFsaXplZFRpbWUoeyB2YWx1ZURhdGU6IHZhbHVlIH0pLFxufTtcbmV4cG9ydCBjb25zdCBBc25OdWxsQ29udmVydGVyID0ge1xuICAgIGZyb21BU046ICgpID0+IG51bGwsXG4gICAgdG9BU046ICgpID0+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBhc24xanMuTnVsbCgpO1xuICAgIH0sXG59O1xuZXhwb3J0IGZ1bmN0aW9uIGRlZmF1bHRDb252ZXJ0ZXIodHlwZSkge1xuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgICBjYXNlIEFzblByb3BUeXBlcy5Bbnk6XG4gICAgICAgICAgICByZXR1cm4gQXNuQW55Q29udmVydGVyO1xuICAgICAgICBjYXNlIEFzblByb3BUeXBlcy5CaXRTdHJpbmc6XG4gICAgICAgICAgICByZXR1cm4gQXNuQml0U3RyaW5nQ29udmVydGVyO1xuICAgICAgICBjYXNlIEFzblByb3BUeXBlcy5CbXBTdHJpbmc6XG4gICAgICAgICAgICByZXR1cm4gQXNuQm1wU3RyaW5nQ29udmVydGVyO1xuICAgICAgICBjYXNlIEFzblByb3BUeXBlcy5Cb29sZWFuOlxuICAgICAgICAgICAgcmV0dXJuIEFzbkJvb2xlYW5Db252ZXJ0ZXI7XG4gICAgICAgIGNhc2UgQXNuUHJvcFR5cGVzLkNoYXJhY3RlclN0cmluZzpcbiAgICAgICAgICAgIHJldHVybiBBc25DaGFyYWN0ZXJTdHJpbmdDb252ZXJ0ZXI7XG4gICAgICAgIGNhc2UgQXNuUHJvcFR5cGVzLkVudW1lcmF0ZWQ6XG4gICAgICAgICAgICByZXR1cm4gQXNuRW51bWVyYXRlZENvbnZlcnRlcjtcbiAgICAgICAgY2FzZSBBc25Qcm9wVHlwZXMuR2VuZXJhbFN0cmluZzpcbiAgICAgICAgICAgIHJldHVybiBBc25HZW5lcmFsU3RyaW5nQ29udmVydGVyO1xuICAgICAgICBjYXNlIEFzblByb3BUeXBlcy5HZW5lcmFsaXplZFRpbWU6XG4gICAgICAgICAgICByZXR1cm4gQXNuR2VuZXJhbGl6ZWRUaW1lQ29udmVydGVyO1xuICAgICAgICBjYXNlIEFzblByb3BUeXBlcy5HcmFwaGljU3RyaW5nOlxuICAgICAgICAgICAgcmV0dXJuIEFzbkdyYXBoaWNTdHJpbmdDb252ZXJ0ZXI7XG4gICAgICAgIGNhc2UgQXNuUHJvcFR5cGVzLklBNVN0cmluZzpcbiAgICAgICAgICAgIHJldHVybiBBc25JQTVTdHJpbmdDb252ZXJ0ZXI7XG4gICAgICAgIGNhc2UgQXNuUHJvcFR5cGVzLkludGVnZXI6XG4gICAgICAgICAgICByZXR1cm4gQXNuSW50ZWdlckNvbnZlcnRlcjtcbiAgICAgICAgY2FzZSBBc25Qcm9wVHlwZXMuTnVsbDpcbiAgICAgICAgICAgIHJldHVybiBBc25OdWxsQ29udmVydGVyO1xuICAgICAgICBjYXNlIEFzblByb3BUeXBlcy5OdW1lcmljU3RyaW5nOlxuICAgICAgICAgICAgcmV0dXJuIEFzbk51bWVyaWNTdHJpbmdDb252ZXJ0ZXI7XG4gICAgICAgIGNhc2UgQXNuUHJvcFR5cGVzLk9iamVjdElkZW50aWZpZXI6XG4gICAgICAgICAgICByZXR1cm4gQXNuT2JqZWN0SWRlbnRpZmllckNvbnZlcnRlcjtcbiAgICAgICAgY2FzZSBBc25Qcm9wVHlwZXMuT2N0ZXRTdHJpbmc6XG4gICAgICAgICAgICByZXR1cm4gQXNuT2N0ZXRTdHJpbmdDb252ZXJ0ZXI7XG4gICAgICAgIGNhc2UgQXNuUHJvcFR5cGVzLlByaW50YWJsZVN0cmluZzpcbiAgICAgICAgICAgIHJldHVybiBBc25QcmludGFibGVTdHJpbmdDb252ZXJ0ZXI7XG4gICAgICAgIGNhc2UgQXNuUHJvcFR5cGVzLlRlbGV0ZXhTdHJpbmc6XG4gICAgICAgICAgICByZXR1cm4gQXNuVGVsZXRleFN0cmluZ0NvbnZlcnRlcjtcbiAgICAgICAgY2FzZSBBc25Qcm9wVHlwZXMuVVRDVGltZTpcbiAgICAgICAgICAgIHJldHVybiBBc25VVENUaW1lQ29udmVydGVyO1xuICAgICAgICBjYXNlIEFzblByb3BUeXBlcy5Vbml2ZXJzYWxTdHJpbmc6XG4gICAgICAgICAgICByZXR1cm4gQXNuVW5pdmVyc2FsU3RyaW5nQ29udmVydGVyO1xuICAgICAgICBjYXNlIEFzblByb3BUeXBlcy5VdGY4U3RyaW5nOlxuICAgICAgICAgICAgcmV0dXJuIEFzblV0ZjhTdHJpbmdDb252ZXJ0ZXI7XG4gICAgICAgIGNhc2UgQXNuUHJvcFR5cGVzLlZpZGVvdGV4U3RyaW5nOlxuICAgICAgICAgICAgcmV0dXJuIEFzblZpZGVvdGV4U3RyaW5nQ29udmVydGVyO1xuICAgICAgICBjYXNlIEFzblByb3BUeXBlcy5WaXNpYmxlU3RyaW5nOlxuICAgICAgICAgICAgcmV0dXJuIEFzblZpc2libGVTdHJpbmdDb252ZXJ0ZXI7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG59XG4iLCAiZXhwb3J0IGZ1bmN0aW9uIGlzQ29udmVydGlibGUodGFyZ2V0KSB7XG4gICAgaWYgKHR5cGVvZiB0YXJnZXQgPT09IFwiZnVuY3Rpb25cIiAmJiB0YXJnZXQucHJvdG90eXBlKSB7XG4gICAgICAgIGlmICh0YXJnZXQucHJvdG90eXBlLnRvQVNOICYmIHRhcmdldC5wcm90b3R5cGUuZnJvbUFTTikge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gaXNDb252ZXJ0aWJsZSh0YXJnZXQucHJvdG90eXBlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgcmV0dXJuICEhKHRhcmdldCAmJiB0eXBlb2YgdGFyZ2V0ID09PSBcIm9iamVjdFwiICYmIFwidG9BU05cIiBpbiB0YXJnZXQgJiYgXCJmcm9tQVNOXCIgaW4gdGFyZ2V0KTtcbiAgICB9XG59XG5leHBvcnQgZnVuY3Rpb24gaXNUeXBlT2ZBcnJheSh0YXJnZXQpIHtcbiAgICB2YXIgX2E7XG4gICAgaWYgKHRhcmdldCkge1xuICAgICAgICBjb25zdCBwcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZih0YXJnZXQpO1xuICAgICAgICBpZiAoKChfYSA9IHByb3RvID09PSBudWxsIHx8IHByb3RvID09PSB2b2lkIDAgPyB2b2lkIDAgOiBwcm90by5wcm90b3R5cGUpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5jb25zdHJ1Y3RvcikgPT09IEFycmF5KSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaXNUeXBlT2ZBcnJheShwcm90byk7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBpc0FycmF5RXF1YWwoYnl0ZXMxLCBieXRlczIpIHtcbiAgICBpZiAoIShieXRlczEgJiYgYnl0ZXMyKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmIChieXRlczEuYnl0ZUxlbmd0aCAhPT0gYnl0ZXMyLmJ5dGVMZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBjb25zdCBiMSA9IG5ldyBVaW50OEFycmF5KGJ5dGVzMSk7XG4gICAgY29uc3QgYjIgPSBuZXcgVWludDhBcnJheShieXRlczIpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYnl0ZXMxLmJ5dGVMZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoYjFbaV0gIT09IGIyW2ldKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG4iLCAiaW1wb3J0ICogYXMgYXNuMWpzIGZyb20gXCJhc24xanNcIjtcbmltcG9ydCB7IEFzblByb3BUeXBlcywgQXNuVHlwZVR5cGVzIH0gZnJvbSBcIi4vZW51bXNcIjtcbmltcG9ydCB7IGlzQ29udmVydGlibGUgfSBmcm9tIFwiLi9oZWxwZXJcIjtcbmV4cG9ydCBjbGFzcyBBc25TY2hlbWFTdG9yYWdlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5pdGVtcyA9IG5ldyBXZWFrTWFwKCk7XG4gICAgfVxuICAgIGhhcyh0YXJnZXQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXRlbXMuaGFzKHRhcmdldCk7XG4gICAgfVxuICAgIGdldCh0YXJnZXQsIGNoZWNrU2NoZW1hID0gZmFsc2UpIHtcbiAgICAgICAgY29uc3Qgc2NoZW1hID0gdGhpcy5pdGVtcy5nZXQodGFyZ2V0KTtcbiAgICAgICAgaWYgKCFzY2hlbWEpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IGdldCBzY2hlbWEgZm9yICcke3RhcmdldC5wcm90b3R5cGUuY29uc3RydWN0b3IubmFtZX0nIHRhcmdldGApO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjaGVja1NjaGVtYSAmJiAhc2NoZW1hLnNjaGVtYSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBTY2hlbWEgJyR7dGFyZ2V0LnByb3RvdHlwZS5jb25zdHJ1Y3Rvci5uYW1lfScgZG9lc24ndCBjb250YWluIEFTTi4xIHNjaGVtYS4gQ2FsbCAnQXNuU2NoZW1hU3RvcmFnZS5jYWNoZScuYCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNjaGVtYTtcbiAgICB9XG4gICAgY2FjaGUodGFyZ2V0KSB7XG4gICAgICAgIGNvbnN0IHNjaGVtYSA9IHRoaXMuZ2V0KHRhcmdldCk7XG4gICAgICAgIGlmICghc2NoZW1hLnNjaGVtYSkge1xuICAgICAgICAgICAgc2NoZW1hLnNjaGVtYSA9IHRoaXMuY3JlYXRlKHRhcmdldCwgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY3JlYXRlRGVmYXVsdCh0YXJnZXQpIHtcbiAgICAgICAgY29uc3Qgc2NoZW1hID0ge1xuICAgICAgICAgICAgdHlwZTogQXNuVHlwZVR5cGVzLlNlcXVlbmNlLFxuICAgICAgICAgICAgaXRlbXM6IHt9LFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBwYXJlbnRTY2hlbWEgPSB0aGlzLmZpbmRQYXJlbnRTY2hlbWEodGFyZ2V0KTtcbiAgICAgICAgaWYgKHBhcmVudFNjaGVtYSkge1xuICAgICAgICAgICAgT2JqZWN0LmFzc2lnbihzY2hlbWEsIHBhcmVudFNjaGVtYSk7XG4gICAgICAgICAgICBzY2hlbWEuaXRlbXMgPSBPYmplY3QuYXNzaWduKHt9LCBzY2hlbWEuaXRlbXMsIHBhcmVudFNjaGVtYS5pdGVtcyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNjaGVtYTtcbiAgICB9XG4gICAgY3JlYXRlKHRhcmdldCwgdXNlTmFtZXMpIHtcbiAgICAgICAgY29uc3Qgc2NoZW1hID0gdGhpcy5pdGVtcy5nZXQodGFyZ2V0KSB8fCB0aGlzLmNyZWF0ZURlZmF1bHQodGFyZ2V0KTtcbiAgICAgICAgY29uc3QgYXNuMVZhbHVlID0gW107XG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIHNjaGVtYS5pdGVtcykge1xuICAgICAgICAgICAgY29uc3QgaXRlbSA9IHNjaGVtYS5pdGVtc1trZXldO1xuICAgICAgICAgICAgY29uc3QgbmFtZSA9IHVzZU5hbWVzID8ga2V5IDogXCJcIjtcbiAgICAgICAgICAgIGxldCBhc24xSXRlbTtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgKGl0ZW0udHlwZSkgPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBBc24xVHlwZU5hbWUgPSBBc25Qcm9wVHlwZXNbaXRlbS50eXBlXTtcbiAgICAgICAgICAgICAgICBjb25zdCBBc24xVHlwZSA9IGFzbjFqc1tBc24xVHlwZU5hbWVdO1xuICAgICAgICAgICAgICAgIGlmICghQXNuMVR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgZ2V0IEFTTjEgY2xhc3MgYnkgbmFtZSAnJHtBc24xVHlwZU5hbWV9J2ApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBhc24xSXRlbSA9IG5ldyBBc24xVHlwZSh7IG5hbWUgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChpc0NvbnZlcnRpYmxlKGl0ZW0udHlwZSkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBpbnN0YW5jZSA9IG5ldyBpdGVtLnR5cGUoKTtcbiAgICAgICAgICAgICAgICBhc24xSXRlbSA9IGluc3RhbmNlLnRvU2NoZW1hKG5hbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoaXRlbS5vcHRpb25hbCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGl0ZW1TY2hlbWEgPSB0aGlzLmdldChpdGVtLnR5cGUpO1xuICAgICAgICAgICAgICAgIGlmIChpdGVtU2NoZW1hLnR5cGUgPT09IEFzblR5cGVUeXBlcy5DaG9pY2UpIHtcbiAgICAgICAgICAgICAgICAgICAgYXNuMUl0ZW0gPSBuZXcgYXNuMWpzLkFueSh7IG5hbWUgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBhc24xSXRlbSA9IHRoaXMuY3JlYXRlKGl0ZW0udHlwZSwgZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICBhc24xSXRlbS5uYW1lID0gbmFtZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhc24xSXRlbSA9IG5ldyBhc24xanMuQW55KHsgbmFtZSB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IG9wdGlvbmFsID0gISFpdGVtLm9wdGlvbmFsIHx8IGl0ZW0uZGVmYXVsdFZhbHVlICE9PSB1bmRlZmluZWQ7XG4gICAgICAgICAgICBpZiAoaXRlbS5yZXBlYXRlZCkge1xuICAgICAgICAgICAgICAgIGFzbjFJdGVtLm5hbWUgPSBcIlwiO1xuICAgICAgICAgICAgICAgIGNvbnN0IENvbnRhaW5lciA9IGl0ZW0ucmVwZWF0ZWQgPT09IFwic2V0XCJcbiAgICAgICAgICAgICAgICAgICAgPyBhc24xanMuU2V0XG4gICAgICAgICAgICAgICAgICAgIDogYXNuMWpzLlNlcXVlbmNlO1xuICAgICAgICAgICAgICAgIGFzbjFJdGVtID0gbmV3IENvbnRhaW5lcih7XG4gICAgICAgICAgICAgICAgICAgIG5hbWU6IFwiXCIsXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXcgYXNuMWpzLlJlcGVhdGVkKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiBhc24xSXRlbSxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGl0ZW0uY29udGV4dCAhPT0gbnVsbCAmJiBpdGVtLmNvbnRleHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGlmIChpdGVtLmltcGxpY2l0KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgaXRlbS50eXBlID09PSBcIm51bWJlclwiIHx8IGlzQ29udmVydGlibGUoaXRlbS50eXBlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQ29udGFpbmVyID0gaXRlbS5yZXBlYXRlZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gYXNuMWpzLkNvbnN0cnVjdGVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBhc24xanMuUHJpbWl0aXZlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYXNuMVZhbHVlLnB1c2gobmV3IENvbnRhaW5lcih7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25hbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZEJsb2NrOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhZ0NsYXNzOiAzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWdOdW1iZXI6IGl0ZW0uY29udGV4dCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jYWNoZShpdGVtLnR5cGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaXNSZXBlYXRlZCA9ICEhaXRlbS5yZXBlYXRlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCB2YWx1ZSA9ICFpc1JlcGVhdGVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyB0aGlzLmdldChpdGVtLnR5cGUsIHRydWUpLnNjaGVtYVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogYXNuMUl0ZW07XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IFwidmFsdWVCbG9ja1wiIGluIHZhbHVlID8gdmFsdWUudmFsdWVCbG9jay52YWx1ZSA6IHZhbHVlLnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYXNuMVZhbHVlLnB1c2gobmV3IGFzbjFqcy5Db25zdHJ1Y3RlZCh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogIWlzUmVwZWF0ZWQgPyBuYW1lIDogXCJcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25hbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZEJsb2NrOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhZ0NsYXNzOiAzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWdOdW1iZXI6IGl0ZW0uY29udGV4dCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYXNuMVZhbHVlLnB1c2gobmV3IGFzbjFqcy5Db25zdHJ1Y3RlZCh7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25hbCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGlkQmxvY2s6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWdDbGFzczogMyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWdOdW1iZXI6IGl0ZW0uY29udGV4dCxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogW2FzbjFJdGVtXSxcbiAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGFzbjFJdGVtLm9wdGlvbmFsID0gb3B0aW9uYWw7XG4gICAgICAgICAgICAgICAgYXNuMVZhbHVlLnB1c2goYXNuMUl0ZW0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHN3aXRjaCAoc2NoZW1hLnR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgQXNuVHlwZVR5cGVzLlNlcXVlbmNlOlxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgYXNuMWpzLlNlcXVlbmNlKHsgdmFsdWU6IGFzbjFWYWx1ZSwgbmFtZTogXCJcIiB9KTtcbiAgICAgICAgICAgIGNhc2UgQXNuVHlwZVR5cGVzLlNldDpcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IGFzbjFqcy5TZXQoeyB2YWx1ZTogYXNuMVZhbHVlLCBuYW1lOiBcIlwiIH0pO1xuICAgICAgICAgICAgY2FzZSBBc25UeXBlVHlwZXMuQ2hvaWNlOlxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgYXNuMWpzLkNob2ljZSh7IHZhbHVlOiBhc24xVmFsdWUsIG5hbWU6IFwiXCIgfSk7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgQVNOMSB0eXBlIGluIHVzZWApO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNldCh0YXJnZXQsIHNjaGVtYSkge1xuICAgICAgICB0aGlzLml0ZW1zLnNldCh0YXJnZXQsIHNjaGVtYSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBmaW5kUGFyZW50U2NoZW1hKHRhcmdldCkge1xuICAgICAgICBjb25zdCBwYXJlbnQgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YodGFyZ2V0KTtcbiAgICAgICAgaWYgKHBhcmVudCkge1xuICAgICAgICAgICAgY29uc3Qgc2NoZW1hID0gdGhpcy5pdGVtcy5nZXQocGFyZW50KTtcbiAgICAgICAgICAgIHJldHVybiBzY2hlbWEgfHwgdGhpcy5maW5kUGFyZW50U2NoZW1hKHBhcmVudCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxufVxuIiwgImltcG9ydCB7IEFzblNjaGVtYVN0b3JhZ2UgfSBmcm9tIFwiLi9zY2hlbWFcIjtcbmV4cG9ydCBjb25zdCBzY2hlbWFTdG9yYWdlID0gbmV3IEFzblNjaGVtYVN0b3JhZ2UoKTtcbiIsICJpbXBvcnQgKiBhcyBjb252ZXJ0ZXJzIGZyb20gXCIuL2NvbnZlcnRlcnNcIjtcbmltcG9ydCB7IEFzblR5cGVUeXBlcyB9IGZyb20gXCIuL2VudW1zXCI7XG5pbXBvcnQgeyBzY2hlbWFTdG9yYWdlIH0gZnJvbSBcIi4vc3RvcmFnZVwiO1xuZXhwb3J0IGNvbnN0IEFzblR5cGUgPSAob3B0aW9ucykgPT4gKHRhcmdldCkgPT4ge1xuICAgIGxldCBzY2hlbWE7XG4gICAgaWYgKCFzY2hlbWFTdG9yYWdlLmhhcyh0YXJnZXQpKSB7XG4gICAgICAgIHNjaGVtYSA9IHNjaGVtYVN0b3JhZ2UuY3JlYXRlRGVmYXVsdCh0YXJnZXQpO1xuICAgICAgICBzY2hlbWFTdG9yYWdlLnNldCh0YXJnZXQsIHNjaGVtYSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBzY2hlbWEgPSBzY2hlbWFTdG9yYWdlLmdldCh0YXJnZXQpO1xuICAgIH1cbiAgICBPYmplY3QuYXNzaWduKHNjaGVtYSwgb3B0aW9ucyk7XG59O1xuZXhwb3J0IGNvbnN0IEFzbkNob2ljZVR5cGUgPSAoKSA9PiBBc25UeXBlKHsgdHlwZTogQXNuVHlwZVR5cGVzLkNob2ljZSB9KTtcbmV4cG9ydCBjb25zdCBBc25TZXRUeXBlID0gKG9wdGlvbnMpID0+IEFzblR5cGUoeyB0eXBlOiBBc25UeXBlVHlwZXMuU2V0LCAuLi5vcHRpb25zIH0pO1xuZXhwb3J0IGNvbnN0IEFzblNlcXVlbmNlVHlwZSA9IChvcHRpb25zKSA9PiBBc25UeXBlKHsgdHlwZTogQXNuVHlwZVR5cGVzLlNlcXVlbmNlLCAuLi5vcHRpb25zIH0pO1xuZXhwb3J0IGNvbnN0IEFzblByb3AgPSAob3B0aW9ucykgPT4gKHRhcmdldCwgcHJvcGVydHlLZXkpID0+IHtcbiAgICBsZXQgc2NoZW1hO1xuICAgIGlmICghc2NoZW1hU3RvcmFnZS5oYXModGFyZ2V0LmNvbnN0cnVjdG9yKSkge1xuICAgICAgICBzY2hlbWEgPSBzY2hlbWFTdG9yYWdlLmNyZWF0ZURlZmF1bHQodGFyZ2V0LmNvbnN0cnVjdG9yKTtcbiAgICAgICAgc2NoZW1hU3RvcmFnZS5zZXQodGFyZ2V0LmNvbnN0cnVjdG9yLCBzY2hlbWEpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgc2NoZW1hID0gc2NoZW1hU3RvcmFnZS5nZXQodGFyZ2V0LmNvbnN0cnVjdG9yKTtcbiAgICB9XG4gICAgY29uc3QgY29weU9wdGlvbnMgPSBPYmplY3QuYXNzaWduKHt9LCBvcHRpb25zKTtcbiAgICBpZiAodHlwZW9mIGNvcHlPcHRpb25zLnR5cGUgPT09IFwibnVtYmVyXCIgJiYgIWNvcHlPcHRpb25zLmNvbnZlcnRlcikge1xuICAgICAgICBjb25zdCBkZWZhdWx0Q29udmVydGVyID0gY29udmVydGVycy5kZWZhdWx0Q29udmVydGVyKG9wdGlvbnMudHlwZSk7XG4gICAgICAgIGlmICghZGVmYXVsdENvbnZlcnRlcikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgZ2V0IGRlZmF1bHQgY29udmVydGVyIGZvciBwcm9wZXJ0eSAnJHtwcm9wZXJ0eUtleX0nIG9mICR7dGFyZ2V0LmNvbnN0cnVjdG9yLm5hbWV9YCk7XG4gICAgICAgIH1cbiAgICAgICAgY29weU9wdGlvbnMuY29udmVydGVyID0gZGVmYXVsdENvbnZlcnRlcjtcbiAgICB9XG4gICAgc2NoZW1hLml0ZW1zW3Byb3BlcnR5S2V5XSA9IGNvcHlPcHRpb25zO1xufTtcbiIsICJleHBvcnQgY2xhc3MgQXNuU2NoZW1hVmFsaWRhdGlvbkVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLnNjaGVtYXMgPSBbXTtcbiAgICB9XG59XG4iLCAiZXhwb3J0ICogZnJvbSBcIi4vc2NoZW1hX3ZhbGlkYXRpb25cIjtcbiIsICJpbXBvcnQgKiBhcyBhc24xanMgZnJvbSBcImFzbjFqc1wiO1xuaW1wb3J0IHsgQXNuUHJvcFR5cGVzLCBBc25UeXBlVHlwZXMgfSBmcm9tIFwiLi9lbnVtc1wiO1xuaW1wb3J0ICogYXMgY29udmVydGVycyBmcm9tIFwiLi9jb252ZXJ0ZXJzXCI7XG5pbXBvcnQgeyBBc25TY2hlbWFWYWxpZGF0aW9uRXJyb3IgfSBmcm9tIFwiLi9lcnJvcnNcIjtcbmltcG9ydCB7IGlzQ29udmVydGlibGUsIGlzVHlwZU9mQXJyYXkgfSBmcm9tIFwiLi9oZWxwZXJcIjtcbmltcG9ydCB7IHNjaGVtYVN0b3JhZ2UgfSBmcm9tIFwiLi9zdG9yYWdlXCI7XG5leHBvcnQgY2xhc3MgQXNuUGFyc2VyIHtcbiAgICBzdGF0aWMgcGFyc2UoZGF0YSwgdGFyZ2V0KSB7XG4gICAgICAgIGNvbnN0IGFzbjFQYXJzZWQgPSBhc24xanMuZnJvbUJFUihkYXRhKTtcbiAgICAgICAgaWYgKGFzbjFQYXJzZWQucmVzdWx0LmVycm9yKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYXNuMVBhcnNlZC5yZXN1bHQuZXJyb3IpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlcyA9IHRoaXMuZnJvbUFTTihhc24xUGFyc2VkLnJlc3VsdCwgdGFyZ2V0KTtcbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG4gICAgc3RhdGljIGZyb21BU04oYXNuMVNjaGVtYSwgdGFyZ2V0KSB7XG4gICAgICAgIHZhciBfYTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmIChpc0NvbnZlcnRpYmxlKHRhcmdldCkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IG5ldyB0YXJnZXQoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWUuZnJvbUFTTihhc24xU2NoZW1hKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHNjaGVtYSA9IHNjaGVtYVN0b3JhZ2UuZ2V0KHRhcmdldCk7XG4gICAgICAgICAgICBzY2hlbWFTdG9yYWdlLmNhY2hlKHRhcmdldCk7XG4gICAgICAgICAgICBsZXQgdGFyZ2V0U2NoZW1hID0gc2NoZW1hLnNjaGVtYTtcbiAgICAgICAgICAgIGlmIChhc24xU2NoZW1hLmNvbnN0cnVjdG9yID09PSBhc24xanMuQ29uc3RydWN0ZWQgJiYgc2NoZW1hLnR5cGUgIT09IEFzblR5cGVUeXBlcy5DaG9pY2UpIHtcbiAgICAgICAgICAgICAgICB0YXJnZXRTY2hlbWEgPSBuZXcgYXNuMWpzLkNvbnN0cnVjdGVkKHtcbiAgICAgICAgICAgICAgICAgICAgaWRCbG9jazoge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGFnQ2xhc3M6IDMsXG4gICAgICAgICAgICAgICAgICAgICAgICB0YWdOdW1iZXI6IGFzbjFTY2hlbWEuaWRCbG9jay50YWdOdW1iZXIsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiBzY2hlbWEuc2NoZW1hLnZhbHVlQmxvY2sudmFsdWUsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gc2NoZW1hLml0ZW1zKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBhc24xU2NoZW1hW2tleV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgYXNuMUNvbXBhcmVkU2NoZW1hID0gYXNuMWpzLmNvbXBhcmVTY2hlbWEoe30sIGFzbjFTY2hlbWEsIHRhcmdldFNjaGVtYSk7XG4gICAgICAgICAgICBpZiAoIWFzbjFDb21wYXJlZFNjaGVtYS52ZXJpZmllZCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc25TY2hlbWFWYWxpZGF0aW9uRXJyb3IoYERhdGEgZG9lcyBub3QgbWF0Y2ggdG8gJHt0YXJnZXQubmFtZX0gQVNOMSBzY2hlbWEuICR7YXNuMUNvbXBhcmVkU2NoZW1hLnJlc3VsdC5lcnJvcn1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHJlcyA9IG5ldyB0YXJnZXQoKTtcbiAgICAgICAgICAgIGlmIChpc1R5cGVPZkFycmF5KHRhcmdldCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoIShcInZhbHVlXCIgaW4gYXNuMVNjaGVtYS52YWx1ZUJsb2NrICYmIEFycmF5LmlzQXJyYXkoYXNuMVNjaGVtYS52YWx1ZUJsb2NrLnZhbHVlKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgZ2V0IGl0ZW1zIGZyb20gdGhlIEFTTi4xIHBhcnNlZCB2YWx1ZS4gQVNOLjEgb2JqZWN0IGlzIG5vdCBjb25zdHJ1Y3RlZC5gKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgaXRlbVR5cGUgPSBzY2hlbWEuaXRlbVR5cGU7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBpdGVtVHlwZSA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjb252ZXJ0ZXIgPSBjb252ZXJ0ZXJzLmRlZmF1bHRDb252ZXJ0ZXIoaXRlbVR5cGUpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWNvbnZlcnRlcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgZ2V0IGRlZmF1bHQgY29udmVydGVyIGZvciBhcnJheSBpdGVtIG9mICR7dGFyZ2V0Lm5hbWV9IEFTTjEgc2NoZW1hYCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRhcmdldC5mcm9tKGFzbjFTY2hlbWEudmFsdWVCbG9jay52YWx1ZSwgKGVsZW1lbnQpID0+IGNvbnZlcnRlci5mcm9tQVNOKGVsZW1lbnQpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0YXJnZXQuZnJvbShhc24xU2NoZW1hLnZhbHVlQmxvY2sudmFsdWUsIChlbGVtZW50KSA9PiB0aGlzLmZyb21BU04oZWxlbWVudCwgaXRlbVR5cGUpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBzY2hlbWEuaXRlbXMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBhc24xU2NoZW1hVmFsdWUgPSBhc24xQ29tcGFyZWRTY2hlbWEucmVzdWx0W2tleV07XG4gICAgICAgICAgICAgICAgaWYgKCFhc24xU2NoZW1hVmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IHNjaGVtYUl0ZW0gPSBzY2hlbWEuaXRlbXNba2V5XTtcbiAgICAgICAgICAgICAgICBjb25zdCBzY2hlbWFJdGVtVHlwZSA9IHNjaGVtYUl0ZW0udHlwZTtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHNjaGVtYUl0ZW1UeXBlID09PSBcIm51bWJlclwiIHx8IGlzQ29udmVydGlibGUoc2NoZW1hSXRlbVR5cGUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbnZlcnRlciA9IChfYSA9IHNjaGVtYUl0ZW0uY29udmVydGVyKSAhPT0gbnVsbCAmJiBfYSAhPT0gdm9pZCAwID8gX2EgOiAoaXNDb252ZXJ0aWJsZShzY2hlbWFJdGVtVHlwZSlcbiAgICAgICAgICAgICAgICAgICAgICAgID8gbmV3IHNjaGVtYUl0ZW1UeXBlKClcbiAgICAgICAgICAgICAgICAgICAgICAgIDogbnVsbCk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghY29udmVydGVyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDb252ZXJ0ZXIgaXMgZW1wdHlcIik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHNjaGVtYUl0ZW0ucmVwZWF0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzY2hlbWFJdGVtLmltcGxpY2l0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQ29udGFpbmVyID0gc2NoZW1hSXRlbS5yZXBlYXRlZCA9PT0gXCJzZXF1ZW5jZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gYXNuMWpzLlNlcXVlbmNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogYXNuMWpzLlNldDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXdJdGVtID0gbmV3IENvbnRhaW5lcigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0l0ZW0udmFsdWVCbG9jayA9IGFzbjFTY2hlbWFWYWx1ZS52YWx1ZUJsb2NrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld0l0ZW1Bc24gPSBhc24xanMuZnJvbUJFUihuZXdJdGVtLnRvQkVSKGZhbHNlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5ld0l0ZW1Bc24ub2Zmc2V0ID09PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBwYXJzZSB0aGUgY2hpbGQgaXRlbS4gJHtuZXdJdGVtQXNuLnJlc3VsdC5lcnJvcn1gKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEoXCJ2YWx1ZVwiIGluIG5ld0l0ZW1Bc24ucmVzdWx0LnZhbHVlQmxvY2sgJiYgQXJyYXkuaXNBcnJheShuZXdJdGVtQXNuLnJlc3VsdC52YWx1ZUJsb2NrLnZhbHVlKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2Fubm90IGdldCBpdGVtcyBmcm9tIHRoZSBBU04uMSBwYXJzZWQgdmFsdWUuIEFTTi4xIG9iamVjdCBpcyBub3QgY29uc3RydWN0ZWQuXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IG5ld0l0ZW1Bc24ucmVzdWx0LnZhbHVlQmxvY2sudmFsdWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzW2tleV0gPSBBcnJheS5mcm9tKHZhbHVlLCAoZWxlbWVudCkgPT4gY29udmVydGVyLmZyb21BU04oZWxlbWVudCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzW2tleV0gPSBBcnJheS5mcm9tKGFzbjFTY2hlbWFWYWx1ZSwgKGVsZW1lbnQpID0+IGNvbnZlcnRlci5mcm9tQVNOKGVsZW1lbnQpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCB2YWx1ZSA9IGFzbjFTY2hlbWFWYWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzY2hlbWFJdGVtLmltcGxpY2l0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IG5ld0l0ZW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzQ29udmVydGlibGUoc2NoZW1hSXRlbVR5cGUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0l0ZW0gPSBuZXcgc2NoZW1hSXRlbVR5cGUoKS50b1NjaGVtYShcIlwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFzbjFUeXBlTmFtZSA9IEFzblByb3BUeXBlc1tzY2hlbWFJdGVtVHlwZV07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFzbjFUeXBlID0gYXNuMWpzW0FzbjFUeXBlTmFtZV07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghQXNuMVR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IGdldCAnJHtBc24xVHlwZU5hbWV9JyBjbGFzcyBmcm9tIGFzbjFqcyBtb2R1bGVgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdJdGVtID0gbmV3IEFzbjFUeXBlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0l0ZW0udmFsdWVCbG9jayA9IHZhbHVlLnZhbHVlQmxvY2s7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBhc24xanMuZnJvbUJFUihuZXdJdGVtLnRvQkVSKGZhbHNlKSkucmVzdWx0O1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzW2tleV0gPSBjb252ZXJ0ZXIuZnJvbUFTTih2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzY2hlbWFJdGVtLnJlcGVhdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkoYXNuMVNjaGVtYVZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBnZXQgbGlzdCBvZiBpdGVtcyBmcm9tIHRoZSBBU04uMSBwYXJzZWQgdmFsdWUuIEFTTi4xIHZhbHVlIHNob3VsZCBiZSBpdGVyYWJsZS5cIik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNba2V5XSA9IEFycmF5LmZyb20oYXNuMVNjaGVtYVZhbHVlLCAoZWxlbWVudCkgPT4gdGhpcy5mcm9tQVNOKGVsZW1lbnQsIHNjaGVtYUl0ZW1UeXBlKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNba2V5XSA9IHRoaXMuZnJvbUFTTihhc24xU2NoZW1hVmFsdWUsIHNjaGVtYUl0ZW1UeXBlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXM7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBBc25TY2hlbWFWYWxpZGF0aW9uRXJyb3IpIHtcbiAgICAgICAgICAgICAgICBlcnJvci5zY2hlbWFzLnB1c2godGFyZ2V0Lm5hbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCAiaW1wb3J0ICogYXMgYXNuMWpzIGZyb20gXCJhc24xanNcIjtcbmltcG9ydCAqIGFzIGNvbnZlcnRlcnMgZnJvbSBcIi4vY29udmVydGVyc1wiO1xuaW1wb3J0IHsgQXNuUHJvcFR5cGVzLCBBc25UeXBlVHlwZXMgfSBmcm9tIFwiLi9lbnVtc1wiO1xuaW1wb3J0IHsgaXNDb252ZXJ0aWJsZSwgaXNBcnJheUVxdWFsIH0gZnJvbSBcIi4vaGVscGVyXCI7XG5pbXBvcnQgeyBzY2hlbWFTdG9yYWdlIH0gZnJvbSBcIi4vc3RvcmFnZVwiO1xuZXhwb3J0IGNsYXNzIEFzblNlcmlhbGl6ZXIge1xuICAgIHN0YXRpYyBzZXJpYWxpemUob2JqKSB7XG4gICAgICAgIGlmIChvYmogaW5zdGFuY2VvZiBhc24xanMuQmFzZUJsb2NrKSB7XG4gICAgICAgICAgICByZXR1cm4gb2JqLnRvQkVSKGZhbHNlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy50b0FTTihvYmopLnRvQkVSKGZhbHNlKTtcbiAgICB9XG4gICAgc3RhdGljIHRvQVNOKG9iaikge1xuICAgICAgICBpZiAob2JqICYmIHR5cGVvZiBvYmogPT09IFwib2JqZWN0XCIgJiYgaXNDb252ZXJ0aWJsZShvYmopKSB7XG4gICAgICAgICAgICByZXR1cm4gb2JqLnRvQVNOKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEob2JqICYmIHR5cGVvZiBvYmogPT09IFwib2JqZWN0XCIpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUGFyYW1ldGVyIDEgc2hvdWxkIGJlIHR5cGUgb2YgT2JqZWN0LlwiKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB0YXJnZXQgPSBvYmouY29uc3RydWN0b3I7XG4gICAgICAgIGNvbnN0IHNjaGVtYSA9IHNjaGVtYVN0b3JhZ2UuZ2V0KHRhcmdldCk7XG4gICAgICAgIHNjaGVtYVN0b3JhZ2UuY2FjaGUodGFyZ2V0KTtcbiAgICAgICAgbGV0IGFzbjFWYWx1ZSA9IFtdO1xuICAgICAgICBpZiAoc2NoZW1hLml0ZW1UeXBlKSB7XG4gICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQYXJhbWV0ZXIgMSBzaG91bGQgYmUgdHlwZSBvZiBBcnJheS5cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodHlwZW9mIHNjaGVtYS5pdGVtVHlwZSA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbnZlcnRlciA9IGNvbnZlcnRlcnMuZGVmYXVsdENvbnZlcnRlcihzY2hlbWEuaXRlbVR5cGUpO1xuICAgICAgICAgICAgICAgIGlmICghY29udmVydGVyKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IGdldCBkZWZhdWx0IGNvbnZlcnRlciBmb3IgYXJyYXkgaXRlbSBvZiAke3RhcmdldC5uYW1lfSBBU04xIHNjaGVtYWApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBhc24xVmFsdWUgPSBvYmoubWFwKChvKSA9PiBjb252ZXJ0ZXIudG9BU04obykpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYXNuMVZhbHVlID0gb2JqLm1hcCgobykgPT4gdGhpcy50b0Fzbkl0ZW0oeyB0eXBlOiBzY2hlbWEuaXRlbVR5cGUgfSwgXCJbXVwiLCB0YXJnZXQsIG8pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIHNjaGVtYS5pdGVtcykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHNjaGVtYUl0ZW0gPSBzY2hlbWEuaXRlbXNba2V5XTtcbiAgICAgICAgICAgICAgICBjb25zdCBvYmpQcm9wID0gb2JqW2tleV07XG4gICAgICAgICAgICAgICAgaWYgKG9ialByb3AgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICB8fCBzY2hlbWFJdGVtLmRlZmF1bHRWYWx1ZSA9PT0gb2JqUHJvcFxuICAgICAgICAgICAgICAgICAgICB8fCAodHlwZW9mIHNjaGVtYUl0ZW0uZGVmYXVsdFZhbHVlID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBvYmpQcm9wID09PSBcIm9iamVjdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAmJiBpc0FycmF5RXF1YWwodGhpcy5zZXJpYWxpemUoc2NoZW1hSXRlbS5kZWZhdWx0VmFsdWUpLCB0aGlzLnNlcmlhbGl6ZShvYmpQcm9wKSkpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBhc24xSXRlbSA9IEFzblNlcmlhbGl6ZXIudG9Bc25JdGVtKHNjaGVtYUl0ZW0sIGtleSwgdGFyZ2V0LCBvYmpQcm9wKTtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHNjaGVtYUl0ZW0uY29udGV4dCA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2NoZW1hSXRlbS5pbXBsaWNpdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFzY2hlbWFJdGVtLnJlcGVhdGVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgKHR5cGVvZiBzY2hlbWFJdGVtLnR5cGUgPT09IFwibnVtYmVyXCIgfHwgaXNDb252ZXJ0aWJsZShzY2hlbWFJdGVtLnR5cGUpKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0ge307XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUudmFsdWVIZXggPSBhc24xSXRlbSBpbnN0YW5jZW9mIGFzbjFqcy5OdWxsID8gYXNuMUl0ZW0udmFsdWVCZWZvcmVEZWNvZGVWaWV3IDogYXNuMUl0ZW0udmFsdWVCbG9jay50b0JFUigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzbjFWYWx1ZS5wdXNoKG5ldyBhc24xanMuUHJpbWl0aXZlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uYWw6IHNjaGVtYUl0ZW0ub3B0aW9uYWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkQmxvY2s6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhZ0NsYXNzOiAzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFnTnVtYmVyOiBzY2hlbWFJdGVtLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzbjFWYWx1ZS5wdXNoKG5ldyBhc24xanMuQ29uc3RydWN0ZWQoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25hbDogc2NoZW1hSXRlbS5vcHRpb25hbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWRCbG9jazoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFnQ2xhc3M6IDMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWdOdW1iZXI6IHNjaGVtYUl0ZW0uY29udGV4dCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGFzbjFJdGVtLnZhbHVlQmxvY2sudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXNuMVZhbHVlLnB1c2gobmV3IGFzbjFqcy5Db25zdHJ1Y3RlZCh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uYWw6IHNjaGVtYUl0ZW0ub3B0aW9uYWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWRCbG9jazoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWdDbGFzczogMyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFnTnVtYmVyOiBzY2hlbWFJdGVtLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogW2FzbjFJdGVtXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChzY2hlbWFJdGVtLnJlcGVhdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGFzbjFWYWx1ZSA9IGFzbjFWYWx1ZS5jb25jYXQoYXNuMUl0ZW0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYXNuMVZhbHVlLnB1c2goYXNuMUl0ZW0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsZXQgYXNuU2NoZW1hO1xuICAgICAgICBzd2l0Y2ggKHNjaGVtYS50eXBlKSB7XG4gICAgICAgICAgICBjYXNlIEFzblR5cGVUeXBlcy5TZXF1ZW5jZTpcbiAgICAgICAgICAgICAgICBhc25TY2hlbWEgPSBuZXcgYXNuMWpzLlNlcXVlbmNlKHsgdmFsdWU6IGFzbjFWYWx1ZSB9KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgQXNuVHlwZVR5cGVzLlNldDpcbiAgICAgICAgICAgICAgICBhc25TY2hlbWEgPSBuZXcgYXNuMWpzLlNldCh7IHZhbHVlOiBhc24xVmFsdWUgfSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEFzblR5cGVUeXBlcy5DaG9pY2U6XG4gICAgICAgICAgICAgICAgaWYgKCFhc24xVmFsdWVbMF0pIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBTY2hlbWEgJyR7dGFyZ2V0Lm5hbWV9JyBoYXMgd3JvbmcgZGF0YS4gQ2hvaWNlIGNhbm5vdCBiZSBlbXB0eS5gKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYXNuU2NoZW1hID0gYXNuMVZhbHVlWzBdO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhc25TY2hlbWE7XG4gICAgfVxuICAgIHN0YXRpYyB0b0Fzbkl0ZW0oc2NoZW1hSXRlbSwga2V5LCB0YXJnZXQsIG9ialByb3ApIHtcbiAgICAgICAgbGV0IGFzbjFJdGVtO1xuICAgICAgICBpZiAodHlwZW9mIChzY2hlbWFJdGVtLnR5cGUpID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICBjb25zdCBjb252ZXJ0ZXIgPSBzY2hlbWFJdGVtLmNvbnZlcnRlcjtcbiAgICAgICAgICAgIGlmICghY29udmVydGVyKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBQcm9wZXJ0eSAnJHtrZXl9JyBkb2Vzbid0IGhhdmUgY29udmVydGVyIGZvciB0eXBlICR7QXNuUHJvcFR5cGVzW3NjaGVtYUl0ZW0udHlwZV19IGluIHNjaGVtYSAnJHt0YXJnZXQubmFtZX0nYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoc2NoZW1hSXRlbS5yZXBlYXRlZCkge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmpQcm9wKSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUGFyYW1ldGVyICdvYmpQcm9wJyBzaG91bGQgYmUgdHlwZSBvZiBBcnJheS5cIik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGl0ZW1zID0gQXJyYXkuZnJvbShvYmpQcm9wLCAoZWxlbWVudCkgPT4gY29udmVydGVyLnRvQVNOKGVsZW1lbnQpKTtcbiAgICAgICAgICAgICAgICBjb25zdCBDb250YWluZXIgPSBzY2hlbWFJdGVtLnJlcGVhdGVkID09PSBcInNlcXVlbmNlXCJcbiAgICAgICAgICAgICAgICAgICAgPyBhc24xanMuU2VxdWVuY2VcbiAgICAgICAgICAgICAgICAgICAgOiBhc24xanMuU2V0O1xuICAgICAgICAgICAgICAgIGFzbjFJdGVtID0gbmV3IENvbnRhaW5lcih7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiBpdGVtcyxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGFzbjFJdGVtID0gY29udmVydGVyLnRvQVNOKG9ialByb3ApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaWYgKHNjaGVtYUl0ZW0ucmVwZWF0ZWQpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqUHJvcCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlBhcmFtZXRlciAnb2JqUHJvcCcgc2hvdWxkIGJlIHR5cGUgb2YgQXJyYXkuXCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBpdGVtcyA9IEFycmF5LmZyb20ob2JqUHJvcCwgKGVsZW1lbnQpID0+IHRoaXMudG9BU04oZWxlbWVudCkpO1xuICAgICAgICAgICAgICAgIGNvbnN0IENvbnRhaW5lciA9IHNjaGVtYUl0ZW0ucmVwZWF0ZWQgPT09IFwic2VxdWVuY2VcIlxuICAgICAgICAgICAgICAgICAgICA/IGFzbjFqcy5TZXF1ZW5jZVxuICAgICAgICAgICAgICAgICAgICA6IGFzbjFqcy5TZXQ7XG4gICAgICAgICAgICAgICAgYXNuMUl0ZW0gPSBuZXcgQ29udGFpbmVyKHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGl0ZW1zLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYXNuMUl0ZW0gPSB0aGlzLnRvQVNOKG9ialByb3ApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhc24xSXRlbTtcbiAgICB9XG59XG4iLCAiZXhwb3J0IGNsYXNzIEFzbkFycmF5IGV4dGVuZHMgQXJyYXkge1xuICAgIGNvbnN0cnVjdG9yKGl0ZW1zID0gW10pIHtcbiAgICAgICAgaWYgKHR5cGVvZiBpdGVtcyA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgc3VwZXIoaXRlbXMpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcykge1xuICAgICAgICAgICAgICAgIHRoaXMucHVzaChpdGVtKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cbiIsICJpbXBvcnQgKiBhcyBhc24xanMgZnJvbSBcImFzbjFqc1wiO1xuaW1wb3J0IHsgQnVmZmVyU291cmNlQ29udmVydGVyIH0gZnJvbSBcInB2dHN1dGlsc1wiO1xuaW1wb3J0IHsgQXNuUGFyc2VyIH0gZnJvbSBcIi4vcGFyc2VyXCI7XG5pbXBvcnQgeyBBc25TZXJpYWxpemVyIH0gZnJvbSBcIi4vc2VyaWFsaXplclwiO1xuZXhwb3J0IGNsYXNzIEFzbkNvbnZlcnQge1xuICAgIHN0YXRpYyBzZXJpYWxpemUob2JqKSB7XG4gICAgICAgIHJldHVybiBBc25TZXJpYWxpemVyLnNlcmlhbGl6ZShvYmopO1xuICAgIH1cbiAgICBzdGF0aWMgcGFyc2UoZGF0YSwgdGFyZ2V0KSB7XG4gICAgICAgIHJldHVybiBBc25QYXJzZXIucGFyc2UoZGF0YSwgdGFyZ2V0KTtcbiAgICB9XG4gICAgc3RhdGljIHRvU3RyaW5nKGRhdGEpIHtcbiAgICAgICAgY29uc3QgYnVmID0gQnVmZmVyU291cmNlQ29udmVydGVyLmlzQnVmZmVyU291cmNlKGRhdGEpXG4gICAgICAgICAgICA/IEJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b0FycmF5QnVmZmVyKGRhdGEpXG4gICAgICAgICAgICA6IEFzbkNvbnZlcnQuc2VyaWFsaXplKGRhdGEpO1xuICAgICAgICBjb25zdCBhc24gPSBhc24xanMuZnJvbUJFUihidWYpO1xuICAgICAgICBpZiAoYXNuLm9mZnNldCA9PT0gLTEpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IGRlY29kZSBBU04uMSBkYXRhLiAke2Fzbi5yZXN1bHQuZXJyb3J9YCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFzbi5yZXN1bHQudG9TdHJpbmcoKTtcbiAgICB9XG59XG4iLCAiZXhwb3J0ICogZnJvbSBcIi4vY29udmVydGVyc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vdHlwZXMvaW5kZXhcIjtcbmV4cG9ydCB7IEFzblByb3AsIEFzblR5cGUsIEFzbkNob2ljZVR5cGUsIEFzblNlcXVlbmNlVHlwZSwgQXNuU2V0VHlwZSB9IGZyb20gXCIuL2RlY29yYXRvcnNcIjtcbmV4cG9ydCB7IEFzblR5cGVUeXBlcywgQXNuUHJvcFR5cGVzIH0gZnJvbSBcIi4vZW51bXNcIjtcbmV4cG9ydCB7IEFzblBhcnNlciB9IGZyb20gXCIuL3BhcnNlclwiO1xuZXhwb3J0IHsgQXNuU2VyaWFsaXplciB9IGZyb20gXCIuL3NlcmlhbGl6ZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2Vycm9yc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vb2JqZWN0c1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vY29udmVydFwiO1xuIiwgIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbkNvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLlxuXG5QZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBhbmQvb3IgZGlzdHJpYnV0ZSB0aGlzIHNvZnR3YXJlIGZvciBhbnlcbnB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZC5cblxuVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiBBTkQgVEhFIEFVVEhPUiBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSFxuUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZXG5BTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBESVJFQ1QsXG5JTkRJUkVDVCwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST01cbkxPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SXG5PVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SXG5QRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLlxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi9cbi8qIGdsb2JhbCBSZWZsZWN0LCBQcm9taXNlLCBTdXBwcmVzc2VkRXJyb3IsIFN5bWJvbCAqL1xuXG52YXIgZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uKGQsIGIpIHtcbiAgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxuICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxuICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTsgfTtcbiAgcmV0dXJuIGV4dGVuZFN0YXRpY3MoZCwgYik7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gX19leHRlbmRzKGQsIGIpIHtcbiAgaWYgKHR5cGVvZiBiICE9PSBcImZ1bmN0aW9uXCIgJiYgYiAhPT0gbnVsbClcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDbGFzcyBleHRlbmRzIHZhbHVlIFwiICsgU3RyaW5nKGIpICsgXCIgaXMgbm90IGEgY29uc3RydWN0b3Igb3IgbnVsbFwiKTtcbiAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XG4gIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbn1cblxuZXhwb3J0IHZhciBfX2Fzc2lnbiA9IGZ1bmN0aW9uKCkge1xuICBfX2Fzc2lnbiA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gX19hc3NpZ24odCkge1xuICAgICAgZm9yICh2YXIgcywgaSA9IDEsIG4gPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgbjsgaSsrKSB7XG4gICAgICAgICAgcyA9IGFyZ3VtZW50c1tpXTtcbiAgICAgICAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkpIHRbcF0gPSBzW3BdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHQ7XG4gIH1cbiAgcmV0dXJuIF9fYXNzaWduLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBfX3Jlc3QocywgZSkge1xuICB2YXIgdCA9IHt9O1xuICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkgJiYgZS5pbmRleE9mKHApIDwgMClcbiAgICAgIHRbcF0gPSBzW3BdO1xuICBpZiAocyAhPSBudWxsICYmIHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzID09PSBcImZ1bmN0aW9uXCIpXG4gICAgICBmb3IgKHZhciBpID0gMCwgcCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMocyk7IGkgPCBwLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaWYgKGUuaW5kZXhPZihwW2ldKSA8IDAgJiYgT2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKHMsIHBbaV0pKVxuICAgICAgICAgICAgICB0W3BbaV1dID0gc1twW2ldXTtcbiAgICAgIH1cbiAgcmV0dXJuIHQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBfX2RlY29yYXRlKGRlY29yYXRvcnMsIHRhcmdldCwga2V5LCBkZXNjKSB7XG4gIHZhciBjID0gYXJndW1lbnRzLmxlbmd0aCwgciA9IGMgPCAzID8gdGFyZ2V0IDogZGVzYyA9PT0gbnVsbCA/IGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwga2V5KSA6IGRlc2MsIGQ7XG4gIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5kZWNvcmF0ZSA9PT0gXCJmdW5jdGlvblwiKSByID0gUmVmbGVjdC5kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYyk7XG4gIGVsc2UgZm9yICh2YXIgaSA9IGRlY29yYXRvcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIGlmIChkID0gZGVjb3JhdG9yc1tpXSkgciA9IChjIDwgMyA/IGQocikgOiBjID4gMyA/IGQodGFyZ2V0LCBrZXksIHIpIDogZCh0YXJnZXQsIGtleSkpIHx8IHI7XG4gIHJldHVybiBjID4gMyAmJiByICYmIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgciksIHI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBfX3BhcmFtKHBhcmFtSW5kZXgsIGRlY29yYXRvcikge1xuICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwga2V5KSB7IGRlY29yYXRvcih0YXJnZXQsIGtleSwgcGFyYW1JbmRleCk7IH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fZXNEZWNvcmF0ZShjdG9yLCBkZXNjcmlwdG9ySW4sIGRlY29yYXRvcnMsIGNvbnRleHRJbiwgaW5pdGlhbGl6ZXJzLCBleHRyYUluaXRpYWxpemVycykge1xuICBmdW5jdGlvbiBhY2NlcHQoZikgeyBpZiAoZiAhPT0gdm9pZCAwICYmIHR5cGVvZiBmICE9PSBcImZ1bmN0aW9uXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJGdW5jdGlvbiBleHBlY3RlZFwiKTsgcmV0dXJuIGY7IH1cbiAgdmFyIGtpbmQgPSBjb250ZXh0SW4ua2luZCwga2V5ID0ga2luZCA9PT0gXCJnZXR0ZXJcIiA/IFwiZ2V0XCIgOiBraW5kID09PSBcInNldHRlclwiID8gXCJzZXRcIiA6IFwidmFsdWVcIjtcbiAgdmFyIHRhcmdldCA9ICFkZXNjcmlwdG9ySW4gJiYgY3RvciA/IGNvbnRleHRJbltcInN0YXRpY1wiXSA/IGN0b3IgOiBjdG9yLnByb3RvdHlwZSA6IG51bGw7XG4gIHZhciBkZXNjcmlwdG9yID0gZGVzY3JpcHRvckluIHx8ICh0YXJnZXQgPyBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwgY29udGV4dEluLm5hbWUpIDoge30pO1xuICB2YXIgXywgZG9uZSA9IGZhbHNlO1xuICBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgdmFyIGNvbnRleHQgPSB7fTtcbiAgICAgIGZvciAodmFyIHAgaW4gY29udGV4dEluKSBjb250ZXh0W3BdID0gcCA9PT0gXCJhY2Nlc3NcIiA/IHt9IDogY29udGV4dEluW3BdO1xuICAgICAgZm9yICh2YXIgcCBpbiBjb250ZXh0SW4uYWNjZXNzKSBjb250ZXh0LmFjY2Vzc1twXSA9IGNvbnRleHRJbi5hY2Nlc3NbcF07XG4gICAgICBjb250ZXh0LmFkZEluaXRpYWxpemVyID0gZnVuY3Rpb24gKGYpIHsgaWYgKGRvbmUpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgYWRkIGluaXRpYWxpemVycyBhZnRlciBkZWNvcmF0aW9uIGhhcyBjb21wbGV0ZWRcIik7IGV4dHJhSW5pdGlhbGl6ZXJzLnB1c2goYWNjZXB0KGYgfHwgbnVsbCkpOyB9O1xuICAgICAgdmFyIHJlc3VsdCA9ICgwLCBkZWNvcmF0b3JzW2ldKShraW5kID09PSBcImFjY2Vzc29yXCIgPyB7IGdldDogZGVzY3JpcHRvci5nZXQsIHNldDogZGVzY3JpcHRvci5zZXQgfSA6IGRlc2NyaXB0b3Jba2V5XSwgY29udGV4dCk7XG4gICAgICBpZiAoa2luZCA9PT0gXCJhY2Nlc3NvclwiKSB7XG4gICAgICAgICAgaWYgKHJlc3VsdCA9PT0gdm9pZCAwKSBjb250aW51ZTtcbiAgICAgICAgICBpZiAocmVzdWx0ID09PSBudWxsIHx8IHR5cGVvZiByZXN1bHQgIT09IFwib2JqZWN0XCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJPYmplY3QgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgaWYgKF8gPSBhY2NlcHQocmVzdWx0LmdldCkpIGRlc2NyaXB0b3IuZ2V0ID0gXztcbiAgICAgICAgICBpZiAoXyA9IGFjY2VwdChyZXN1bHQuc2V0KSkgZGVzY3JpcHRvci5zZXQgPSBfO1xuICAgICAgICAgIGlmIChfID0gYWNjZXB0KHJlc3VsdC5pbml0KSkgaW5pdGlhbGl6ZXJzLnVuc2hpZnQoXyk7XG4gICAgICB9XG4gICAgICBlbHNlIGlmIChfID0gYWNjZXB0KHJlc3VsdCkpIHtcbiAgICAgICAgICBpZiAoa2luZCA9PT0gXCJmaWVsZFwiKSBpbml0aWFsaXplcnMudW5zaGlmdChfKTtcbiAgICAgICAgICBlbHNlIGRlc2NyaXB0b3Jba2V5XSA9IF87XG4gICAgICB9XG4gIH1cbiAgaWYgKHRhcmdldCkgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgY29udGV4dEluLm5hbWUsIGRlc2NyaXB0b3IpO1xuICBkb25lID0gdHJ1ZTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBfX3J1bkluaXRpYWxpemVycyh0aGlzQXJnLCBpbml0aWFsaXplcnMsIHZhbHVlKSB7XG4gIHZhciB1c2VWYWx1ZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAyO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGluaXRpYWxpemVycy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFsdWUgPSB1c2VWYWx1ZSA/IGluaXRpYWxpemVyc1tpXS5jYWxsKHRoaXNBcmcsIHZhbHVlKSA6IGluaXRpYWxpemVyc1tpXS5jYWxsKHRoaXNBcmcpO1xuICB9XG4gIHJldHVybiB1c2VWYWx1ZSA/IHZhbHVlIDogdm9pZCAwO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIF9fcHJvcEtleSh4KSB7XG4gIHJldHVybiB0eXBlb2YgeCA9PT0gXCJzeW1ib2xcIiA/IHggOiBcIlwiLmNvbmNhdCh4KTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBfX3NldEZ1bmN0aW9uTmFtZShmLCBuYW1lLCBwcmVmaXgpIHtcbiAgaWYgKHR5cGVvZiBuYW1lID09PSBcInN5bWJvbFwiKSBuYW1lID0gbmFtZS5kZXNjcmlwdGlvbiA/IFwiW1wiLmNvbmNhdChuYW1lLmRlc2NyaXB0aW9uLCBcIl1cIikgOiBcIlwiO1xuICByZXR1cm4gT2JqZWN0LmRlZmluZVByb3BlcnR5KGYsIFwibmFtZVwiLCB7IGNvbmZpZ3VyYWJsZTogdHJ1ZSwgdmFsdWU6IHByZWZpeCA/IFwiXCIuY29uY2F0KHByZWZpeCwgXCIgXCIsIG5hbWUpIDogbmFtZSB9KTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBfX21ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKSB7XG4gIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5tZXRhZGF0YSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gUmVmbGVjdC5tZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBfX2F3YWl0ZXIodGhpc0FyZywgX2FyZ3VtZW50cywgUCwgZ2VuZXJhdG9yKSB7XG4gIGZ1bmN0aW9uIGFkb3B0KHZhbHVlKSB7IHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIFAgPyB2YWx1ZSA6IG5ldyBQKGZ1bmN0aW9uIChyZXNvbHZlKSB7IHJlc29sdmUodmFsdWUpOyB9KTsgfVxuICByZXR1cm4gbmV3IChQIHx8IChQID0gUHJvbWlzZSkpKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIGZ1bmN0aW9uIGZ1bGZpbGxlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvci5uZXh0KHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cbiAgICAgIGZ1bmN0aW9uIHJlamVjdGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yW1widGhyb3dcIl0odmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxuICAgICAgZnVuY3Rpb24gc3RlcChyZXN1bHQpIHsgcmVzdWx0LmRvbmUgPyByZXNvbHZlKHJlc3VsdC52YWx1ZSkgOiBhZG9wdChyZXN1bHQudmFsdWUpLnRoZW4oZnVsZmlsbGVkLCByZWplY3RlZCk7IH1cbiAgICAgIHN0ZXAoKGdlbmVyYXRvciA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSkubmV4dCgpKTtcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBfX2dlbmVyYXRvcih0aGlzQXJnLCBib2R5KSB7XG4gIHZhciBfID0geyBsYWJlbDogMCwgc2VudDogZnVuY3Rpb24oKSB7IGlmICh0WzBdICYgMSkgdGhyb3cgdFsxXTsgcmV0dXJuIHRbMV07IH0sIHRyeXM6IFtdLCBvcHM6IFtdIH0sIGYsIHksIHQsIGc7XG4gIHJldHVybiBnID0geyBuZXh0OiB2ZXJiKDApLCBcInRocm93XCI6IHZlcmIoMSksIFwicmV0dXJuXCI6IHZlcmIoMikgfSwgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIChnW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXM7IH0pLCBnO1xuICBmdW5jdGlvbiB2ZXJiKG4pIHsgcmV0dXJuIGZ1bmN0aW9uICh2KSB7IHJldHVybiBzdGVwKFtuLCB2XSk7IH07IH1cbiAgZnVuY3Rpb24gc3RlcChvcCkge1xuICAgICAgaWYgKGYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJHZW5lcmF0b3IgaXMgYWxyZWFkeSBleGVjdXRpbmcuXCIpO1xuICAgICAgd2hpbGUgKGcgJiYgKGcgPSAwLCBvcFswXSAmJiAoXyA9IDApKSwgXykgdHJ5IHtcbiAgICAgICAgICBpZiAoZiA9IDEsIHkgJiYgKHQgPSBvcFswXSAmIDIgPyB5W1wicmV0dXJuXCJdIDogb3BbMF0gPyB5W1widGhyb3dcIl0gfHwgKCh0ID0geVtcInJldHVyblwiXSkgJiYgdC5jYWxsKHkpLCAwKSA6IHkubmV4dCkgJiYgISh0ID0gdC5jYWxsKHksIG9wWzFdKSkuZG9uZSkgcmV0dXJuIHQ7XG4gICAgICAgICAgaWYgKHkgPSAwLCB0KSBvcCA9IFtvcFswXSAmIDIsIHQudmFsdWVdO1xuICAgICAgICAgIHN3aXRjaCAob3BbMF0pIHtcbiAgICAgICAgICAgICAgY2FzZSAwOiBjYXNlIDE6IHQgPSBvcDsgYnJlYWs7XG4gICAgICAgICAgICAgIGNhc2UgNDogXy5sYWJlbCsrOyByZXR1cm4geyB2YWx1ZTogb3BbMV0sIGRvbmU6IGZhbHNlIH07XG4gICAgICAgICAgICAgIGNhc2UgNTogXy5sYWJlbCsrOyB5ID0gb3BbMV07IG9wID0gWzBdOyBjb250aW51ZTtcbiAgICAgICAgICAgICAgY2FzZSA3OiBvcCA9IF8ub3BzLnBvcCgpOyBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xuICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgaWYgKCEodCA9IF8udHJ5cywgdCA9IHQubGVuZ3RoID4gMCAmJiB0W3QubGVuZ3RoIC0gMV0pICYmIChvcFswXSA9PT0gNiB8fCBvcFswXSA9PT0gMikpIHsgXyA9IDA7IGNvbnRpbnVlOyB9XG4gICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDMgJiYgKCF0IHx8IChvcFsxXSA+IHRbMF0gJiYgb3BbMV0gPCB0WzNdKSkpIHsgXy5sYWJlbCA9IG9wWzFdOyBicmVhazsgfVxuICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSA2ICYmIF8ubGFiZWwgPCB0WzFdKSB7IF8ubGFiZWwgPSB0WzFdOyB0ID0gb3A7IGJyZWFrOyB9XG4gICAgICAgICAgICAgICAgICBpZiAodCAmJiBfLmxhYmVsIDwgdFsyXSkgeyBfLmxhYmVsID0gdFsyXTsgXy5vcHMucHVzaChvcCk7IGJyZWFrOyB9XG4gICAgICAgICAgICAgICAgICBpZiAodFsyXSkgXy5vcHMucG9wKCk7XG4gICAgICAgICAgICAgICAgICBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBvcCA9IGJvZHkuY2FsbCh0aGlzQXJnLCBfKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHsgb3AgPSBbNiwgZV07IHkgPSAwOyB9IGZpbmFsbHkgeyBmID0gdCA9IDA7IH1cbiAgICAgIGlmIChvcFswXSAmIDUpIHRocm93IG9wWzFdOyByZXR1cm4geyB2YWx1ZTogb3BbMF0gPyBvcFsxXSA6IHZvaWQgMCwgZG9uZTogdHJ1ZSB9O1xuICB9XG59XG5cbmV4cG9ydCB2YXIgX19jcmVhdGVCaW5kaW5nID0gT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xuICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IobSwgayk7XG4gIGlmICghZGVzYyB8fCAoXCJnZXRcIiBpbiBkZXNjID8gIW0uX19lc01vZHVsZSA6IGRlc2Mud3JpdGFibGUgfHwgZGVzYy5jb25maWd1cmFibGUpKSB7XG4gICAgICBkZXNjID0geyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbVtrXTsgfSB9O1xuICB9XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgZGVzYyk7XG59KSA6IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xuICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuICBvW2syXSA9IG1ba107XG59KTtcblxuZXhwb3J0IGZ1bmN0aW9uIF9fZXhwb3J0U3RhcihtLCBvKSB7XG4gIGZvciAodmFyIHAgaW4gbSkgaWYgKHAgIT09IFwiZGVmYXVsdFwiICYmICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobywgcCkpIF9fY3JlYXRlQmluZGluZyhvLCBtLCBwKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fdmFsdWVzKG8pIHtcbiAgdmFyIHMgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgU3ltYm9sLml0ZXJhdG9yLCBtID0gcyAmJiBvW3NdLCBpID0gMDtcbiAgaWYgKG0pIHJldHVybiBtLmNhbGwobyk7XG4gIGlmIChvICYmIHR5cGVvZiBvLmxlbmd0aCA9PT0gXCJudW1iZXJcIikgcmV0dXJuIHtcbiAgICAgIG5leHQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBpZiAobyAmJiBpID49IG8ubGVuZ3RoKSBvID0gdm9pZCAwO1xuICAgICAgICAgIHJldHVybiB7IHZhbHVlOiBvICYmIG9baSsrXSwgZG9uZTogIW8gfTtcbiAgICAgIH1cbiAgfTtcbiAgdGhyb3cgbmV3IFR5cGVFcnJvcihzID8gXCJPYmplY3QgaXMgbm90IGl0ZXJhYmxlLlwiIDogXCJTeW1ib2wuaXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gX19yZWFkKG8sIG4pIHtcbiAgdmFyIG0gPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb1tTeW1ib2wuaXRlcmF0b3JdO1xuICBpZiAoIW0pIHJldHVybiBvO1xuICB2YXIgaSA9IG0uY2FsbChvKSwgciwgYXIgPSBbXSwgZTtcbiAgdHJ5IHtcbiAgICAgIHdoaWxlICgobiA9PT0gdm9pZCAwIHx8IG4tLSA+IDApICYmICEociA9IGkubmV4dCgpKS5kb25lKSBhci5wdXNoKHIudmFsdWUpO1xuICB9XG4gIGNhdGNoIChlcnJvcikgeyBlID0geyBlcnJvcjogZXJyb3IgfTsgfVxuICBmaW5hbGx5IHtcbiAgICAgIHRyeSB7XG4gICAgICAgICAgaWYgKHIgJiYgIXIuZG9uZSAmJiAobSA9IGlbXCJyZXR1cm5cIl0pKSBtLmNhbGwoaSk7XG4gICAgICB9XG4gICAgICBmaW5hbGx5IHsgaWYgKGUpIHRocm93IGUuZXJyb3I7IH1cbiAgfVxuICByZXR1cm4gYXI7XG59XG5cbi8qKiBAZGVwcmVjYXRlZCAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkKCkge1xuICBmb3IgKHZhciBhciA9IFtdLCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKylcbiAgICAgIGFyID0gYXIuY29uY2F0KF9fcmVhZChhcmd1bWVudHNbaV0pKTtcbiAgcmV0dXJuIGFyO1xufVxuXG4vKiogQGRlcHJlY2F0ZWQgKi9cbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZEFycmF5cygpIHtcbiAgZm9yICh2YXIgcyA9IDAsIGkgPSAwLCBpbCA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBpbDsgaSsrKSBzICs9IGFyZ3VtZW50c1tpXS5sZW5ndGg7XG4gIGZvciAodmFyIHIgPSBBcnJheShzKSwgayA9IDAsIGkgPSAwOyBpIDwgaWw7IGkrKylcbiAgICAgIGZvciAodmFyIGEgPSBhcmd1bWVudHNbaV0sIGogPSAwLCBqbCA9IGEubGVuZ3RoOyBqIDwgamw7IGorKywgaysrKVxuICAgICAgICAgIHJba10gPSBhW2pdO1xuICByZXR1cm4gcjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkQXJyYXkodG8sIGZyb20sIHBhY2spIHtcbiAgaWYgKHBhY2sgfHwgYXJndW1lbnRzLmxlbmd0aCA9PT0gMikgZm9yICh2YXIgaSA9IDAsIGwgPSBmcm9tLmxlbmd0aCwgYXI7IGkgPCBsOyBpKyspIHtcbiAgICAgIGlmIChhciB8fCAhKGkgaW4gZnJvbSkpIHtcbiAgICAgICAgICBpZiAoIWFyKSBhciA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGZyb20sIDAsIGkpO1xuICAgICAgICAgIGFyW2ldID0gZnJvbVtpXTtcbiAgICAgIH1cbiAgfVxuICByZXR1cm4gdG8uY29uY2F0KGFyIHx8IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGZyb20pKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXQodikge1xuICByZXR1cm4gdGhpcyBpbnN0YW5jZW9mIF9fYXdhaXQgPyAodGhpcy52ID0gdiwgdGhpcykgOiBuZXcgX19hd2FpdCh2KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNHZW5lcmF0b3IodGhpc0FyZywgX2FyZ3VtZW50cywgZ2VuZXJhdG9yKSB7XG4gIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XG4gIHZhciBnID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pLCBpLCBxID0gW107XG4gIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcbiAgZnVuY3Rpb24gdmVyYihuKSB7IGlmIChnW25dKSBpW25dID0gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChhLCBiKSB7IHEucHVzaChbbiwgdiwgYSwgYl0pID4gMSB8fCByZXN1bWUobiwgdik7IH0pOyB9OyB9XG4gIGZ1bmN0aW9uIHJlc3VtZShuLCB2KSB7IHRyeSB7IHN0ZXAoZ1tuXSh2KSk7IH0gY2F0Y2ggKGUpIHsgc2V0dGxlKHFbMF1bM10sIGUpOyB9IH1cbiAgZnVuY3Rpb24gc3RlcChyKSB7IHIudmFsdWUgaW5zdGFuY2VvZiBfX2F3YWl0ID8gUHJvbWlzZS5yZXNvbHZlKHIudmFsdWUudikudGhlbihmdWxmaWxsLCByZWplY3QpIDogc2V0dGxlKHFbMF1bMl0sIHIpOyB9XG4gIGZ1bmN0aW9uIGZ1bGZpbGwodmFsdWUpIHsgcmVzdW1lKFwibmV4dFwiLCB2YWx1ZSk7IH1cbiAgZnVuY3Rpb24gcmVqZWN0KHZhbHVlKSB7IHJlc3VtZShcInRocm93XCIsIHZhbHVlKTsgfVxuICBmdW5jdGlvbiBzZXR0bGUoZiwgdikgeyBpZiAoZih2KSwgcS5zaGlmdCgpLCBxLmxlbmd0aCkgcmVzdW1lKHFbMF1bMF0sIHFbMF1bMV0pOyB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jRGVsZWdhdG9yKG8pIHtcbiAgdmFyIGksIHA7XG4gIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiwgZnVuY3Rpb24gKGUpIHsgdGhyb3cgZTsgfSksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XG4gIGZ1bmN0aW9uIHZlcmIobiwgZikgeyBpW25dID0gb1tuXSA/IGZ1bmN0aW9uICh2KSB7IHJldHVybiAocCA9ICFwKSA/IHsgdmFsdWU6IF9fYXdhaXQob1tuXSh2KSksIGRvbmU6IGZhbHNlIH0gOiBmID8gZih2KSA6IHY7IH0gOiBmOyB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jVmFsdWVzKG8pIHtcbiAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcbiAgdmFyIG0gPSBvW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSwgaTtcbiAgcmV0dXJuIG0gPyBtLmNhbGwobykgOiAobyA9IHR5cGVvZiBfX3ZhbHVlcyA9PT0gXCJmdW5jdGlvblwiID8gX192YWx1ZXMobykgOiBvW1N5bWJvbC5pdGVyYXRvcl0oKSwgaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGkpO1xuICBmdW5jdGlvbiB2ZXJiKG4pIHsgaVtuXSA9IG9bbl0gJiYgZnVuY3Rpb24gKHYpIHsgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHsgdiA9IG9bbl0odiksIHNldHRsZShyZXNvbHZlLCByZWplY3QsIHYuZG9uZSwgdi52YWx1ZSk7IH0pOyB9OyB9XG4gIGZ1bmN0aW9uIHNldHRsZShyZXNvbHZlLCByZWplY3QsIGQsIHYpIHsgUHJvbWlzZS5yZXNvbHZlKHYpLnRoZW4oZnVuY3Rpb24odikgeyByZXNvbHZlKHsgdmFsdWU6IHYsIGRvbmU6IGQgfSk7IH0sIHJlamVjdCk7IH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fbWFrZVRlbXBsYXRlT2JqZWN0KGNvb2tlZCwgcmF3KSB7XG4gIGlmIChPYmplY3QuZGVmaW5lUHJvcGVydHkpIHsgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvb2tlZCwgXCJyYXdcIiwgeyB2YWx1ZTogcmF3IH0pOyB9IGVsc2UgeyBjb29rZWQucmF3ID0gcmF3OyB9XG4gIHJldHVybiBjb29rZWQ7XG59O1xuXG52YXIgX19zZXRNb2R1bGVEZWZhdWx0ID0gT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCB2KSB7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBcImRlZmF1bHRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCB2YWx1ZTogdiB9KTtcbn0pIDogZnVuY3Rpb24obywgdikge1xuICBvW1wiZGVmYXVsdFwiXSA9IHY7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gX19pbXBvcnRTdGFyKG1vZCkge1xuICBpZiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSByZXR1cm4gbW9kO1xuICB2YXIgcmVzdWx0ID0ge307XG4gIGlmIChtb2QgIT0gbnVsbCkgZm9yICh2YXIgayBpbiBtb2QpIGlmIChrICE9PSBcImRlZmF1bHRcIiAmJiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobW9kLCBrKSkgX19jcmVhdGVCaW5kaW5nKHJlc3VsdCwgbW9kLCBrKTtcbiAgX19zZXRNb2R1bGVEZWZhdWx0KHJlc3VsdCwgbW9kKTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0RGVmYXVsdChtb2QpIHtcbiAgcmV0dXJuIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpID8gbW9kIDogeyBkZWZhdWx0OiBtb2QgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fY2xhc3NQcml2YXRlRmllbGRHZXQocmVjZWl2ZXIsIHN0YXRlLCBraW5kLCBmKSB7XG4gIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIGdldHRlclwiKTtcbiAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gIHJldHVybiBraW5kID09PSBcIm1cIiA/IGYgOiBraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlcikgOiBmID8gZi52YWx1ZSA6IHN0YXRlLmdldChyZWNlaXZlcik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KHJlY2VpdmVyLCBzdGF0ZSwgdmFsdWUsIGtpbmQsIGYpIHtcbiAgaWYgKGtpbmQgPT09IFwibVwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBtZXRob2QgaXMgbm90IHdyaXRhYmxlXCIpO1xuICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBzZXR0ZXJcIik7XG4gIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHdyaXRlIHByaXZhdGUgbWVtYmVyIHRvIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gIHJldHVybiAoa2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIsIHZhbHVlKSA6IGYgPyBmLnZhbHVlID0gdmFsdWUgOiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSksIHZhbHVlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZEluKHN0YXRlLCByZWNlaXZlcikge1xuICBpZiAocmVjZWl2ZXIgPT09IG51bGwgfHwgKHR5cGVvZiByZWNlaXZlciAhPT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgcmVjZWl2ZXIgIT09IFwiZnVuY3Rpb25cIikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgdXNlICdpbicgb3BlcmF0b3Igb24gbm9uLW9iamVjdFwiKTtcbiAgcmV0dXJuIHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgPT09IHN0YXRlIDogc3RhdGUuaGFzKHJlY2VpdmVyKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fYWRkRGlzcG9zYWJsZVJlc291cmNlKGVudiwgdmFsdWUsIGFzeW5jKSB7XG4gIGlmICh2YWx1ZSAhPT0gbnVsbCAmJiB2YWx1ZSAhPT0gdm9pZCAwKSB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgdmFsdWUgIT09IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9iamVjdCBleHBlY3RlZC5cIik7XG4gICAgdmFyIGRpc3Bvc2U7XG4gICAgaWYgKGFzeW5jKSB7XG4gICAgICAgIGlmICghU3ltYm9sLmFzeW5jRGlzcG9zZSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0Rpc3Bvc2UgaXMgbm90IGRlZmluZWQuXCIpO1xuICAgICAgICBkaXNwb3NlID0gdmFsdWVbU3ltYm9sLmFzeW5jRGlzcG9zZV07XG4gICAgfVxuICAgIGlmIChkaXNwb3NlID09PSB2b2lkIDApIHtcbiAgICAgICAgaWYgKCFTeW1ib2wuZGlzcG9zZSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5kaXNwb3NlIGlzIG5vdCBkZWZpbmVkLlwiKTtcbiAgICAgICAgZGlzcG9zZSA9IHZhbHVlW1N5bWJvbC5kaXNwb3NlXTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBkaXNwb3NlICE9PSBcImZ1bmN0aW9uXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJPYmplY3Qgbm90IGRpc3Bvc2FibGUuXCIpO1xuICAgIGVudi5zdGFjay5wdXNoKHsgdmFsdWU6IHZhbHVlLCBkaXNwb3NlOiBkaXNwb3NlLCBhc3luYzogYXN5bmMgfSk7XG4gIH1cbiAgZWxzZSBpZiAoYXN5bmMpIHtcbiAgICBlbnYuc3RhY2sucHVzaCh7IGFzeW5jOiB0cnVlIH0pO1xuICB9XG4gIHJldHVybiB2YWx1ZTtcbn1cblxudmFyIF9TdXBwcmVzc2VkRXJyb3IgPSB0eXBlb2YgU3VwcHJlc3NlZEVycm9yID09PSBcImZ1bmN0aW9uXCIgPyBTdXBwcmVzc2VkRXJyb3IgOiBmdW5jdGlvbiAoZXJyb3IsIHN1cHByZXNzZWQsIG1lc3NhZ2UpIHtcbiAgdmFyIGUgPSBuZXcgRXJyb3IobWVzc2FnZSk7XG4gIHJldHVybiBlLm5hbWUgPSBcIlN1cHByZXNzZWRFcnJvclwiLCBlLmVycm9yID0gZXJyb3IsIGUuc3VwcHJlc3NlZCA9IHN1cHByZXNzZWQsIGU7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gX19kaXNwb3NlUmVzb3VyY2VzKGVudikge1xuICBmdW5jdGlvbiBmYWlsKGUpIHtcbiAgICBlbnYuZXJyb3IgPSBlbnYuaGFzRXJyb3IgPyBuZXcgX1N1cHByZXNzZWRFcnJvcihlLCBlbnYuZXJyb3IsIFwiQW4gZXJyb3Igd2FzIHN1cHByZXNzZWQgZHVyaW5nIGRpc3Bvc2FsLlwiKSA6IGU7XG4gICAgZW52Lmhhc0Vycm9yID0gdHJ1ZTtcbiAgfVxuICBmdW5jdGlvbiBuZXh0KCkge1xuICAgIHdoaWxlIChlbnYuc3RhY2subGVuZ3RoKSB7XG4gICAgICB2YXIgcmVjID0gZW52LnN0YWNrLnBvcCgpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IHJlYy5kaXNwb3NlICYmIHJlYy5kaXNwb3NlLmNhbGwocmVjLnZhbHVlKTtcbiAgICAgICAgaWYgKHJlYy5hc3luYykgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZXN1bHQpLnRoZW4obmV4dCwgZnVuY3Rpb24oZSkgeyBmYWlsKGUpOyByZXR1cm4gbmV4dCgpOyB9KTtcbiAgICAgIH1cbiAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgZmFpbChlKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGVudi5oYXNFcnJvcikgdGhyb3cgZW52LmVycm9yO1xuICB9XG4gIHJldHVybiBuZXh0KCk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19leHRlbmRzLFxuICBfX2Fzc2lnbixcbiAgX19yZXN0LFxuICBfX2RlY29yYXRlLFxuICBfX3BhcmFtLFxuICBfX21ldGFkYXRhLFxuICBfX2F3YWl0ZXIsXG4gIF9fZ2VuZXJhdG9yLFxuICBfX2NyZWF0ZUJpbmRpbmcsXG4gIF9fZXhwb3J0U3RhcixcbiAgX192YWx1ZXMsXG4gIF9fcmVhZCxcbiAgX19zcHJlYWQsXG4gIF9fc3ByZWFkQXJyYXlzLFxuICBfX3NwcmVhZEFycmF5LFxuICBfX2F3YWl0LFxuICBfX2FzeW5jR2VuZXJhdG9yLFxuICBfX2FzeW5jRGVsZWdhdG9yLFxuICBfX2FzeW5jVmFsdWVzLFxuICBfX21ha2VUZW1wbGF0ZU9iamVjdCxcbiAgX19pbXBvcnRTdGFyLFxuICBfX2ltcG9ydERlZmF1bHQsXG4gIF9fY2xhc3NQcml2YXRlRmllbGRHZXQsXG4gIF9fY2xhc3NQcml2YXRlRmllbGRTZXQsXG4gIF9fY2xhc3NQcml2YXRlRmllbGRJbixcbiAgX19hZGREaXNwb3NhYmxlUmVzb3VyY2UsXG4gIF9fZGlzcG9zZVJlc291cmNlcyxcbn07XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFBlY3VsaWFyIFZlbnR1cmVzLCBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICovXG5cbmNsYXNzIEpzb25FcnJvciBleHRlbmRzIEVycm9yIHtcclxuICAgIGNvbnN0cnVjdG9yKG1lc3NhZ2UsIGlubmVyRXJyb3IpIHtcclxuICAgICAgICBzdXBlcihpbm5lckVycm9yXHJcbiAgICAgICAgICAgID8gYCR7bWVzc2FnZX0uIFNlZSB0aGUgaW5uZXIgZXhjZXB0aW9uIGZvciBtb3JlIGRldGFpbHMuYFxyXG4gICAgICAgICAgICA6IG1lc3NhZ2UpO1xyXG4gICAgICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7XHJcbiAgICAgICAgdGhpcy5pbm5lckVycm9yID0gaW5uZXJFcnJvcjtcclxuICAgIH1cclxufVxuXG5jbGFzcyBUcmFuc2Zvcm1FcnJvciBleHRlbmRzIEpzb25FcnJvciB7XHJcbiAgICBjb25zdHJ1Y3RvcihzY2hlbWEsIG1lc3NhZ2UsIGlubmVyRXJyb3IpIHtcclxuICAgICAgICBzdXBlcihtZXNzYWdlLCBpbm5lckVycm9yKTtcclxuICAgICAgICB0aGlzLnNjaGVtYSA9IHNjaGVtYTtcclxuICAgIH1cclxufVxuXG5jbGFzcyBQYXJzZXJFcnJvciBleHRlbmRzIFRyYW5zZm9ybUVycm9yIHtcclxuICAgIGNvbnN0cnVjdG9yKHNjaGVtYSwgbWVzc2FnZSwgaW5uZXJFcnJvcikge1xyXG4gICAgICAgIHN1cGVyKHNjaGVtYSwgYEpTT04gZG9lc24ndCBtYXRjaCB0byAnJHtzY2hlbWEudGFyZ2V0Lm5hbWV9JyBzY2hlbWEuICR7bWVzc2FnZX1gLCBpbm5lckVycm9yKTtcclxuICAgIH1cclxufVxuXG5jbGFzcyBWYWxpZGF0aW9uRXJyb3IgZXh0ZW5kcyBKc29uRXJyb3Ige1xyXG59XG5cbmNsYXNzIFNlcmlhbGl6ZXJFcnJvciBleHRlbmRzIEpzb25FcnJvciB7XHJcbiAgICBjb25zdHJ1Y3RvcihzY2hlbWFOYW1lLCBtZXNzYWdlLCBpbm5lckVycm9yKSB7XHJcbiAgICAgICAgc3VwZXIoYENhbm5vdCBzZXJpYWxpemUgYnkgJyR7c2NoZW1hTmFtZX0nIHNjaGVtYS4gJHttZXNzYWdlfWAsIGlubmVyRXJyb3IpO1xyXG4gICAgICAgIHRoaXMuc2NoZW1hTmFtZSA9IHNjaGVtYU5hbWU7XHJcbiAgICB9XHJcbn1cblxuY2xhc3MgS2V5RXJyb3IgZXh0ZW5kcyBQYXJzZXJFcnJvciB7XHJcbiAgICBjb25zdHJ1Y3RvcihzY2hlbWEsIGtleXMsIGVycm9ycyA9IHt9KSB7XHJcbiAgICAgICAgc3VwZXIoc2NoZW1hLCBcIlNvbWUga2V5cyBkb2Vzbid0IG1hdGNoIHRvIHNjaGVtYVwiKTtcclxuICAgICAgICB0aGlzLmtleXMgPSBrZXlzO1xyXG4gICAgICAgIHRoaXMuZXJyb3JzID0gZXJyb3JzO1xyXG4gICAgfVxyXG59XG5cbnZhciBKc29uUHJvcFR5cGVzO1xyXG4oZnVuY3Rpb24gKEpzb25Qcm9wVHlwZXMpIHtcclxuICAgIEpzb25Qcm9wVHlwZXNbSnNvblByb3BUeXBlc1tcIkFueVwiXSA9IDBdID0gXCJBbnlcIjtcclxuICAgIEpzb25Qcm9wVHlwZXNbSnNvblByb3BUeXBlc1tcIkJvb2xlYW5cIl0gPSAxXSA9IFwiQm9vbGVhblwiO1xyXG4gICAgSnNvblByb3BUeXBlc1tKc29uUHJvcFR5cGVzW1wiTnVtYmVyXCJdID0gMl0gPSBcIk51bWJlclwiO1xyXG4gICAgSnNvblByb3BUeXBlc1tKc29uUHJvcFR5cGVzW1wiU3RyaW5nXCJdID0gM10gPSBcIlN0cmluZ1wiO1xyXG59KShKc29uUHJvcFR5cGVzIHx8IChKc29uUHJvcFR5cGVzID0ge30pKTtcblxuZnVuY3Rpb24gY2hlY2tUeXBlKHZhbHVlLCB0eXBlKSB7XHJcbiAgICBzd2l0Y2ggKHR5cGUpIHtcclxuICAgICAgICBjYXNlIEpzb25Qcm9wVHlwZXMuQm9vbGVhbjpcclxuICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJib29sZWFuXCI7XHJcbiAgICAgICAgY2FzZSBKc29uUHJvcFR5cGVzLk51bWJlcjpcclxuICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJudW1iZXJcIjtcclxuICAgICAgICBjYXNlIEpzb25Qcm9wVHlwZXMuU3RyaW5nOlxyXG4gICAgICAgICAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRydWU7XHJcbn1cclxuZnVuY3Rpb24gdGhyb3dJZlR5cGVJc1dyb25nKHZhbHVlLCB0eXBlKSB7XHJcbiAgICBpZiAoIWNoZWNrVHlwZSh2YWx1ZSwgdHlwZSkpIHtcclxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBWYWx1ZSBtdXN0IGJlICR7SnNvblByb3BUeXBlc1t0eXBlXX1gKTtcclxuICAgIH1cclxufVxyXG5mdW5jdGlvbiBpc0NvbnZlcnRpYmxlKHRhcmdldCkge1xyXG4gICAgaWYgKHRhcmdldCAmJiB0YXJnZXQucHJvdG90eXBlKSB7XHJcbiAgICAgICAgaWYgKHRhcmdldC5wcm90b3R5cGUudG9KU09OICYmIHRhcmdldC5wcm90b3R5cGUuZnJvbUpTT04pIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gaXNDb252ZXJ0aWJsZSh0YXJnZXQucHJvdG90eXBlKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICByZXR1cm4gISEodGFyZ2V0ICYmIHRhcmdldC50b0pTT04gJiYgdGFyZ2V0LmZyb21KU09OKTtcclxuICAgIH1cclxufVxuXG5jbGFzcyBKc29uU2NoZW1hU3RvcmFnZSB7XHJcbiAgICBjb25zdHJ1Y3RvcigpIHtcclxuICAgICAgICB0aGlzLml0ZW1zID0gbmV3IE1hcCgpO1xyXG4gICAgfVxyXG4gICAgaGFzKHRhcmdldCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLml0ZW1zLmhhcyh0YXJnZXQpIHx8ICEhdGhpcy5maW5kUGFyZW50U2NoZW1hKHRhcmdldCk7XHJcbiAgICB9XHJcbiAgICBnZXQodGFyZ2V0KSB7XHJcbiAgICAgICAgY29uc3Qgc2NoZW1hID0gdGhpcy5pdGVtcy5nZXQodGFyZ2V0KSB8fCB0aGlzLmZpbmRQYXJlbnRTY2hlbWEodGFyZ2V0KTtcclxuICAgICAgICBpZiAoIXNjaGVtYSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgZ2V0IHNjaGVtYSBmb3IgY3VycmVudCB0YXJnZXRcIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBzY2hlbWE7XHJcbiAgICB9XHJcbiAgICBjcmVhdGUodGFyZ2V0KSB7XHJcbiAgICAgICAgY29uc3Qgc2NoZW1hID0geyBuYW1lczoge30gfTtcclxuICAgICAgICBjb25zdCBwYXJlbnRTY2hlbWEgPSB0aGlzLmZpbmRQYXJlbnRTY2hlbWEodGFyZ2V0KTtcclxuICAgICAgICBpZiAocGFyZW50U2NoZW1hKSB7XHJcbiAgICAgICAgICAgIE9iamVjdC5hc3NpZ24oc2NoZW1hLCBwYXJlbnRTY2hlbWEpO1xyXG4gICAgICAgICAgICBzY2hlbWEubmFtZXMgPSB7fTtcclxuICAgICAgICAgICAgZm9yIChjb25zdCBuYW1lIGluIHBhcmVudFNjaGVtYS5uYW1lcykge1xyXG4gICAgICAgICAgICAgICAgc2NoZW1hLm5hbWVzW25hbWVdID0gT2JqZWN0LmFzc2lnbih7fSwgcGFyZW50U2NoZW1hLm5hbWVzW25hbWVdKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBzY2hlbWEudGFyZ2V0ID0gdGFyZ2V0O1xyXG4gICAgICAgIHJldHVybiBzY2hlbWE7XHJcbiAgICB9XHJcbiAgICBzZXQodGFyZ2V0LCBzY2hlbWEpIHtcclxuICAgICAgICB0aGlzLml0ZW1zLnNldCh0YXJnZXQsIHNjaGVtYSk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9XHJcbiAgICBmaW5kUGFyZW50U2NoZW1hKHRhcmdldCkge1xyXG4gICAgICAgIGNvbnN0IHBhcmVudCA9IHRhcmdldC5fX3Byb3RvX187XHJcbiAgICAgICAgaWYgKHBhcmVudCkge1xyXG4gICAgICAgICAgICBjb25zdCBzY2hlbWEgPSB0aGlzLml0ZW1zLmdldChwYXJlbnQpO1xyXG4gICAgICAgICAgICByZXR1cm4gc2NoZW1hIHx8IHRoaXMuZmluZFBhcmVudFNjaGVtYShwYXJlbnQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxufVxuXG5jb25zdCBERUZBVUxUX1NDSEVNQSA9IFwiZGVmYXVsdFwiO1xyXG5jb25zdCBzY2hlbWFTdG9yYWdlID0gbmV3IEpzb25TY2hlbWFTdG9yYWdlKCk7XG5cbmNsYXNzIFBhdHRlcm5WYWxpZGF0aW9uIHtcclxuICAgIGNvbnN0cnVjdG9yKHBhdHRlcm4pIHtcclxuICAgICAgICB0aGlzLnBhdHRlcm4gPSBuZXcgUmVnRXhwKHBhdHRlcm4pO1xyXG4gICAgfVxyXG4gICAgdmFsaWRhdGUodmFsdWUpIHtcclxuICAgICAgICBjb25zdCBwYXR0ZXJuID0gbmV3IFJlZ0V4cCh0aGlzLnBhdHRlcm4uc291cmNlLCB0aGlzLnBhdHRlcm4uZmxhZ3MpO1xyXG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09IFwic3RyaW5nXCIpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihcIkluY29taW5nIHZhbHVlIG11c3QgYmUgc3RyaW5nXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIXBhdHRlcm4uZXhlYyh2YWx1ZSkpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihgVmFsdWUgZG9lc24ndCBtYXRjaCB0byBwYXR0ZXJuICcke3BhdHRlcm4udG9TdHJpbmcoKX0nYCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XG5cbmNsYXNzIEluY2x1c2l2ZVZhbGlkYXRpb24ge1xyXG4gICAgY29uc3RydWN0b3IobWluID0gTnVtYmVyLk1JTl9WQUxVRSwgbWF4ID0gTnVtYmVyLk1BWF9WQUxVRSkge1xyXG4gICAgICAgIHRoaXMubWluID0gbWluO1xyXG4gICAgICAgIHRoaXMubWF4ID0gbWF4O1xyXG4gICAgfVxyXG4gICAgdmFsaWRhdGUodmFsdWUpIHtcclxuICAgICAgICB0aHJvd0lmVHlwZUlzV3JvbmcodmFsdWUsIEpzb25Qcm9wVHlwZXMuTnVtYmVyKTtcclxuICAgICAgICBpZiAoISh0aGlzLm1pbiA8PSB2YWx1ZSAmJiB2YWx1ZSA8PSB0aGlzLm1heCkpIHtcclxuICAgICAgICAgICAgY29uc3QgbWluID0gdGhpcy5taW4gPT09IE51bWJlci5NSU5fVkFMVUUgPyBcIk1JTlwiIDogdGhpcy5taW47XHJcbiAgICAgICAgICAgIGNvbnN0IG1heCA9IHRoaXMubWF4ID09PSBOdW1iZXIuTUFYX1ZBTFVFID8gXCJNQVhcIiA6IHRoaXMubWF4O1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKGBWYWx1ZSBkb2Vzbid0IG1hdGNoIHRvIGRpYXBhc29uIFske21pbn0sJHttYXh9XWApO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxuXG5jbGFzcyBFeGNsdXNpdmVWYWxpZGF0aW9uIHtcclxuICAgIGNvbnN0cnVjdG9yKG1pbiA9IE51bWJlci5NSU5fVkFMVUUsIG1heCA9IE51bWJlci5NQVhfVkFMVUUpIHtcclxuICAgICAgICB0aGlzLm1pbiA9IG1pbjtcclxuICAgICAgICB0aGlzLm1heCA9IG1heDtcclxuICAgIH1cclxuICAgIHZhbGlkYXRlKHZhbHVlKSB7XHJcbiAgICAgICAgdGhyb3dJZlR5cGVJc1dyb25nKHZhbHVlLCBKc29uUHJvcFR5cGVzLk51bWJlcik7XHJcbiAgICAgICAgaWYgKCEodGhpcy5taW4gPCB2YWx1ZSAmJiB2YWx1ZSA8IHRoaXMubWF4KSkge1xyXG4gICAgICAgICAgICBjb25zdCBtaW4gPSB0aGlzLm1pbiA9PT0gTnVtYmVyLk1JTl9WQUxVRSA/IFwiTUlOXCIgOiB0aGlzLm1pbjtcclxuICAgICAgICAgICAgY29uc3QgbWF4ID0gdGhpcy5tYXggPT09IE51bWJlci5NQVhfVkFMVUUgPyBcIk1BWFwiIDogdGhpcy5tYXg7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoYFZhbHVlIGRvZXNuJ3QgbWF0Y2ggdG8gZGlhcGFzb24gKCR7bWlufSwke21heH0pYCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XG5cbmNsYXNzIExlbmd0aFZhbGlkYXRpb24ge1xyXG4gICAgY29uc3RydWN0b3IobGVuZ3RoLCBtaW5MZW5ndGgsIG1heExlbmd0aCkge1xyXG4gICAgICAgIHRoaXMubGVuZ3RoID0gbGVuZ3RoO1xyXG4gICAgICAgIHRoaXMubWluTGVuZ3RoID0gbWluTGVuZ3RoO1xyXG4gICAgICAgIHRoaXMubWF4TGVuZ3RoID0gbWF4TGVuZ3RoO1xyXG4gICAgfVxyXG4gICAgdmFsaWRhdGUodmFsdWUpIHtcclxuICAgICAgICBpZiAodGhpcy5sZW5ndGggIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICBpZiAodmFsdWUubGVuZ3RoICE9PSB0aGlzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihgVmFsdWUgbGVuZ3RoIG11c3QgYmUgZXhhY3RseSAke3RoaXMubGVuZ3RofS5gKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLm1pbkxlbmd0aCAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIGlmICh2YWx1ZS5sZW5ndGggPCB0aGlzLm1pbkxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihgVmFsdWUgbGVuZ3RoIG11c3QgYmUgbW9yZSB0aGFuICR7dGhpcy5taW5MZW5ndGh9LmApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLm1heExlbmd0aCAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIGlmICh2YWx1ZS5sZW5ndGggPiB0aGlzLm1heExlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihgVmFsdWUgbGVuZ3RoIG11c3QgYmUgbGVzcyB0aGFuICR7dGhpcy5tYXhMZW5ndGh9LmApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XG5cbmNsYXNzIEVudW1lcmF0aW9uVmFsaWRhdGlvbiB7XHJcbiAgICBjb25zdHJ1Y3RvcihlbnVtZXJhdGlvbikge1xyXG4gICAgICAgIHRoaXMuZW51bWVyYXRpb24gPSBlbnVtZXJhdGlvbjtcclxuICAgIH1cclxuICAgIHZhbGlkYXRlKHZhbHVlKSB7XHJcbiAgICAgICAgdGhyb3dJZlR5cGVJc1dyb25nKHZhbHVlLCBKc29uUHJvcFR5cGVzLlN0cmluZyk7XHJcbiAgICAgICAgaWYgKCF0aGlzLmVudW1lcmF0aW9uLmluY2x1ZGVzKHZhbHVlKSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKGBWYWx1ZSBtdXN0IGJlIG9uZSBvZiAke3RoaXMuZW51bWVyYXRpb24ubWFwKCh2KSA9PiBgJyR7dn0nYCkuam9pbihcIiwgXCIpfWApO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxuXG5jbGFzcyBKc29uVHJhbnNmb3JtIHtcclxuICAgIHN0YXRpYyBjaGVja1ZhbHVlcyhkYXRhLCBzY2hlbWFJdGVtKSB7XHJcbiAgICAgICAgY29uc3QgdmFsdWVzID0gQXJyYXkuaXNBcnJheShkYXRhKSA/IGRhdGEgOiBbZGF0YV07XHJcbiAgICAgICAgZm9yIChjb25zdCB2YWx1ZSBvZiB2YWx1ZXMpIHtcclxuICAgICAgICAgICAgZm9yIChjb25zdCB2YWxpZGF0aW9uIG9mIHNjaGVtYUl0ZW0udmFsaWRhdGlvbnMpIHtcclxuICAgICAgICAgICAgICAgIGlmICh2YWxpZGF0aW9uIGluc3RhbmNlb2YgTGVuZ3RoVmFsaWRhdGlvbiAmJiBzY2hlbWFJdGVtLnJlcGVhdGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGlvbi52YWxpZGF0ZShkYXRhKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb24udmFsaWRhdGUodmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgc3RhdGljIGNoZWNrVHlwZXModmFsdWUsIHNjaGVtYUl0ZW0pIHtcclxuICAgICAgICBpZiAoc2NoZW1hSXRlbS5yZXBlYXRlZCAmJiAhQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlZhbHVlIG11c3QgYmUgQXJyYXlcIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0eXBlb2Ygc2NoZW1hSXRlbS50eXBlID09PSBcIm51bWJlclwiKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlcyA9IEFycmF5LmlzQXJyYXkodmFsdWUpID8gdmFsdWUgOiBbdmFsdWVdO1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHYgb2YgdmFsdWVzKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvd0lmVHlwZUlzV3Jvbmcodiwgc2NoZW1hSXRlbS50eXBlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHN0YXRpYyBnZXRTY2hlbWFCeU5hbWUoc2NoZW1hLCBuYW1lID0gREVGQVVMVF9TQ0hFTUEpIHtcclxuICAgICAgICByZXR1cm4geyAuLi5zY2hlbWEubmFtZXNbREVGQVVMVF9TQ0hFTUFdLCAuLi5zY2hlbWEubmFtZXNbbmFtZV0gfTtcclxuICAgIH1cclxufVxuXG5jbGFzcyBKc29uU2VyaWFsaXplciBleHRlbmRzIEpzb25UcmFuc2Zvcm0ge1xyXG4gICAgc3RhdGljIHNlcmlhbGl6ZShvYmosIG9wdGlvbnMsIHJlcGxhY2VyLCBzcGFjZSkge1xyXG4gICAgICAgIGNvbnN0IGpzb24gPSB0aGlzLnRvSlNPTihvYmosIG9wdGlvbnMpO1xyXG4gICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShqc29uLCByZXBsYWNlciwgc3BhY2UpO1xyXG4gICAgfVxyXG4gICAgc3RhdGljIHRvSlNPTihvYmosIG9wdGlvbnMgPSB7fSkge1xyXG4gICAgICAgIGxldCByZXM7XHJcbiAgICAgICAgbGV0IHRhcmdldFNjaGVtYSA9IG9wdGlvbnMudGFyZ2V0U2NoZW1hO1xyXG4gICAgICAgIGNvbnN0IHNjaGVtYU5hbWUgPSBvcHRpb25zLnNjaGVtYU5hbWUgfHwgREVGQVVMVF9TQ0hFTUE7XHJcbiAgICAgICAgaWYgKGlzQ29udmVydGlibGUob2JqKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gb2JqLnRvSlNPTigpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShvYmopKSB7XHJcbiAgICAgICAgICAgIHJlcyA9IFtdO1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGl0ZW0gb2Ygb2JqKSB7XHJcbiAgICAgICAgICAgICAgICByZXMucHVzaCh0aGlzLnRvSlNPTihpdGVtLCBvcHRpb25zKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iaiA9PT0gXCJvYmplY3RcIikge1xyXG4gICAgICAgICAgICBpZiAodGFyZ2V0U2NoZW1hICYmICFzY2hlbWFTdG9yYWdlLmhhcyh0YXJnZXRTY2hlbWEpKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSnNvbkVycm9yKFwiQ2Fubm90IGdldCBzY2hlbWEgZm9yIGB0YXJnZXRTY2hlbWFgIHBhcmFtXCIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRhcmdldFNjaGVtYSA9ICh0YXJnZXRTY2hlbWEgfHwgb2JqLmNvbnN0cnVjdG9yKTtcclxuICAgICAgICAgICAgaWYgKHNjaGVtYVN0b3JhZ2UuaGFzKHRhcmdldFNjaGVtYSkpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHNjaGVtYSA9IHNjaGVtYVN0b3JhZ2UuZ2V0KHRhcmdldFNjaGVtYSk7XHJcbiAgICAgICAgICAgICAgICByZXMgPSB7fTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG5hbWVkU2NoZW1hID0gdGhpcy5nZXRTY2hlbWFCeU5hbWUoc2NoZW1hLCBzY2hlbWFOYW1lKTtcclxuICAgICAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIG5hbWVkU2NoZW1hKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaXRlbSA9IG5hbWVkU2NoZW1hW2tleV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG9iakl0ZW0gPSBvYmpba2V5XTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoKGl0ZW0ub3B0aW9uYWwgJiYgb2JqSXRlbSA9PT0gdW5kZWZpbmVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgKGl0ZW0uZGVmYXVsdFZhbHVlICE9PSB1bmRlZmluZWQgJiYgb2JqSXRlbSA9PT0gaXRlbS5kZWZhdWx0VmFsdWUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWl0ZW0ub3B0aW9uYWwgJiYgb2JqSXRlbSA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU2VyaWFsaXplckVycm9yKHRhcmdldFNjaGVtYS5uYW1lLCBgUHJvcGVydHkgJyR7a2V5fScgaXMgcmVxdWlyZWQuYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBpdGVtLnR5cGUgPT09IFwibnVtYmVyXCIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpdGVtLmNvbnZlcnRlcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpdGVtLnJlcGVhdGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gb2JqSXRlbS5tYXAoKGVsKSA9PiBpdGVtLmNvbnZlcnRlci50b0pTT04oZWwsIG9iaikpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBpdGVtLmNvbnZlcnRlci50b0pTT04ob2JqSXRlbSwgb2JqKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IG9iakl0ZW07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXRlbS5yZXBlYXRlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gb2JqSXRlbS5tYXAoKGVsKSA9PiB0aGlzLnRvSlNPTihlbCwgeyBzY2hlbWFOYW1lIH0pKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gdGhpcy50b0pTT04ob2JqSXRlbSwgeyBzY2hlbWFOYW1lIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2hlY2tUeXBlcyh2YWx1ZSwgaXRlbSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2hlY2tWYWx1ZXModmFsdWUsIGl0ZW0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXNbaXRlbS5uYW1lIHx8IGtleV0gPSB2YWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGUgaW5zdGFuY2VvZiBTZXJpYWxpemVyRXJyb3IpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU2VyaWFsaXplckVycm9yKHNjaGVtYS50YXJnZXQubmFtZSwgYFByb3BlcnR5ICcke2tleX0nIGlzIHdyb25nLiAke2UubWVzc2FnZX1gLCBlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJlcyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gb2JqKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVzW2tleV0gPSB0aGlzLnRvSlNPTihvYmpba2V5XSwgeyBzY2hlbWFOYW1lIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICByZXMgPSBvYmo7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiByZXM7XHJcbiAgICB9XHJcbn1cblxuY2xhc3MgSnNvblBhcnNlciBleHRlbmRzIEpzb25UcmFuc2Zvcm0ge1xyXG4gICAgc3RhdGljIHBhcnNlKGRhdGEsIG9wdGlvbnMpIHtcclxuICAgICAgICBjb25zdCBvYmogPSBKU09OLnBhcnNlKGRhdGEpO1xyXG4gICAgICAgIHJldHVybiB0aGlzLmZyb21KU09OKG9iaiwgb3B0aW9ucyk7XHJcbiAgICB9XHJcbiAgICBzdGF0aWMgZnJvbUpTT04odGFyZ2V0LCBvcHRpb25zKSB7XHJcbiAgICAgICAgY29uc3QgdGFyZ2V0U2NoZW1hID0gb3B0aW9ucy50YXJnZXRTY2hlbWE7XHJcbiAgICAgICAgY29uc3Qgc2NoZW1hTmFtZSA9IG9wdGlvbnMuc2NoZW1hTmFtZSB8fCBERUZBVUxUX1NDSEVNQTtcclxuICAgICAgICBjb25zdCBvYmogPSBuZXcgdGFyZ2V0U2NoZW1hKCk7XHJcbiAgICAgICAgaWYgKGlzQ29udmVydGlibGUob2JqKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gb2JqLmZyb21KU09OKHRhcmdldCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IHNjaGVtYSA9IHNjaGVtYVN0b3JhZ2UuZ2V0KHRhcmdldFNjaGVtYSk7XHJcbiAgICAgICAgY29uc3QgbmFtZWRTY2hlbWEgPSB0aGlzLmdldFNjaGVtYUJ5TmFtZShzY2hlbWEsIHNjaGVtYU5hbWUpO1xyXG4gICAgICAgIGNvbnN0IGtleUVycm9ycyA9IHt9O1xyXG4gICAgICAgIGlmIChvcHRpb25zLnN0cmljdFByb3BlcnR5ICYmICFBcnJheS5pc0FycmF5KHRhcmdldCkpIHtcclxuICAgICAgICAgICAgSnNvblBhcnNlci5jaGVja1N0cmljdFByb3BlcnR5KHRhcmdldCwgbmFtZWRTY2hlbWEsIHNjaGVtYSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIG5hbWVkU2NoZW1hKSB7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBpdGVtID0gbmFtZWRTY2hlbWFba2V5XTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG5hbWUgPSBpdGVtLm5hbWUgfHwga2V5O1xyXG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSB0YXJnZXRbbmFtZV07XHJcbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCAmJiAoaXRlbS5vcHRpb25hbCB8fCBpdGVtLmRlZmF1bHRWYWx1ZSAhPT0gdW5kZWZpbmVkKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKCFpdGVtLm9wdGlvbmFsICYmIHZhbHVlID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2VyRXJyb3Ioc2NoZW1hLCBgUHJvcGVydHkgJyR7bmFtZX0nIGlzIHJlcXVpcmVkLmApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdGhpcy5jaGVja1R5cGVzKHZhbHVlLCBpdGVtKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuY2hlY2tWYWx1ZXModmFsdWUsIGl0ZW0pO1xyXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiAoaXRlbS50eXBlKSA9PT0gXCJudW1iZXJcIikge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpdGVtLmNvbnZlcnRlcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXRlbS5yZXBlYXRlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqW2tleV0gPSB2YWx1ZS5tYXAoKGVsKSA9PiBpdGVtLmNvbnZlcnRlci5mcm9tSlNPTihlbCwgb2JqKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmpba2V5XSA9IGl0ZW0uY29udmVydGVyLmZyb21KU09OKHZhbHVlLCBvYmopO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvYmpba2V5XSA9IHZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld09wdGlvbnMgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC4uLm9wdGlvbnMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldFNjaGVtYTogaXRlbS50eXBlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzY2hlbWFOYW1lLFxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGl0ZW0ucmVwZWF0ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb2JqW2tleV0gPSB2YWx1ZS5tYXAoKGVsKSA9PiB0aGlzLmZyb21KU09OKGVsLCBuZXdPcHRpb25zKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvYmpba2V5XSA9IHRoaXMuZnJvbUpTT04odmFsdWUsIG5ld09wdGlvbnMpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCEoZSBpbnN0YW5jZW9mIFBhcnNlckVycm9yKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGUgPSBuZXcgUGFyc2VyRXJyb3Ioc2NoZW1hLCBgUHJvcGVydHkgJyR7a2V5fScgaXMgd3JvbmcuICR7ZS5tZXNzYWdlfWAsIGUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc3RyaWN0QWxsS2V5cykge1xyXG4gICAgICAgICAgICAgICAgICAgIGtleUVycm9yc1trZXldID0gZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IGU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKGtleUVycm9ycyk7XHJcbiAgICAgICAgaWYgKGtleXMubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBLZXlFcnJvcihzY2hlbWEsIGtleXMsIGtleUVycm9ycyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBvYmo7XHJcbiAgICB9XHJcbiAgICBzdGF0aWMgY2hlY2tTdHJpY3RQcm9wZXJ0eSh0YXJnZXQsIG5hbWVkU2NoZW1hLCBzY2hlbWEpIHtcclxuICAgICAgICBjb25zdCBqc29uUHJvcHMgPSBPYmplY3Qua2V5cyh0YXJnZXQpO1xyXG4gICAgICAgIGNvbnN0IHNjaGVtYVByb3BzID0gT2JqZWN0LmtleXMobmFtZWRTY2hlbWEpO1xyXG4gICAgICAgIGNvbnN0IGtleXMgPSBbXTtcclxuICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBqc29uUHJvcHMpIHtcclxuICAgICAgICAgICAgaWYgKHNjaGVtYVByb3BzLmluZGV4T2Yoa2V5KSA9PT0gLTEpIHtcclxuICAgICAgICAgICAgICAgIGtleXMucHVzaChrZXkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChrZXlzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgS2V5RXJyb3Ioc2NoZW1hLCBrZXlzKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cblxuZnVuY3Rpb24gZ2V0VmFsaWRhdGlvbnMoaXRlbSkge1xyXG4gICAgY29uc3QgdmFsaWRhdGlvbnMgPSBbXTtcclxuICAgIGlmIChpdGVtLnBhdHRlcm4pIHtcclxuICAgICAgICB2YWxpZGF0aW9ucy5wdXNoKG5ldyBQYXR0ZXJuVmFsaWRhdGlvbihpdGVtLnBhdHRlcm4pKTtcclxuICAgIH1cclxuICAgIGlmIChpdGVtLnR5cGUgPT09IEpzb25Qcm9wVHlwZXMuTnVtYmVyIHx8IGl0ZW0udHlwZSA9PT0gSnNvblByb3BUeXBlcy5BbnkpIHtcclxuICAgICAgICBpZiAoaXRlbS5taW5JbmNsdXNpdmUgIT09IHVuZGVmaW5lZCB8fCBpdGVtLm1heEluY2x1c2l2ZSAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIHZhbGlkYXRpb25zLnB1c2gobmV3IEluY2x1c2l2ZVZhbGlkYXRpb24oaXRlbS5taW5JbmNsdXNpdmUsIGl0ZW0ubWF4SW5jbHVzaXZlKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChpdGVtLm1pbkV4Y2x1c2l2ZSAhPT0gdW5kZWZpbmVkIHx8IGl0ZW0ubWF4RXhjbHVzaXZlICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgdmFsaWRhdGlvbnMucHVzaChuZXcgRXhjbHVzaXZlVmFsaWRhdGlvbihpdGVtLm1pbkV4Y2x1c2l2ZSwgaXRlbS5tYXhFeGNsdXNpdmUpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGl0ZW0uZW51bWVyYXRpb24gIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICB2YWxpZGF0aW9ucy5wdXNoKG5ldyBFbnVtZXJhdGlvblZhbGlkYXRpb24oaXRlbS5lbnVtZXJhdGlvbikpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGlmIChpdGVtLnR5cGUgPT09IEpzb25Qcm9wVHlwZXMuU3RyaW5nIHx8IGl0ZW0ucmVwZWF0ZWQgfHwgaXRlbS50eXBlID09PSBKc29uUHJvcFR5cGVzLkFueSkge1xyXG4gICAgICAgIGlmIChpdGVtLmxlbmd0aCAhPT0gdW5kZWZpbmVkIHx8IGl0ZW0ubWluTGVuZ3RoICE9PSB1bmRlZmluZWQgfHwgaXRlbS5tYXhMZW5ndGggIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICB2YWxpZGF0aW9ucy5wdXNoKG5ldyBMZW5ndGhWYWxpZGF0aW9uKGl0ZW0ubGVuZ3RoLCBpdGVtLm1pbkxlbmd0aCwgaXRlbS5tYXhMZW5ndGgpKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdmFsaWRhdGlvbnM7XHJcbn1cclxuY29uc3QgSnNvblByb3AgPSAob3B0aW9ucyA9IHt9KSA9PiAodGFyZ2V0LCBwcm9wZXJ0eUtleSkgPT4ge1xyXG4gICAgY29uc3QgZXJyb3JNZXNzYWdlID0gYENhbm5vdCBzZXQgdHlwZSBmb3IgJHtwcm9wZXJ0eUtleX0gcHJvcGVydHkgb2YgJHt0YXJnZXQuY29uc3RydWN0b3IubmFtZX0gc2NoZW1hYDtcclxuICAgIGxldCBzY2hlbWE7XHJcbiAgICBpZiAoIXNjaGVtYVN0b3JhZ2UuaGFzKHRhcmdldC5jb25zdHJ1Y3RvcikpIHtcclxuICAgICAgICBzY2hlbWEgPSBzY2hlbWFTdG9yYWdlLmNyZWF0ZSh0YXJnZXQuY29uc3RydWN0b3IpO1xyXG4gICAgICAgIHNjaGVtYVN0b3JhZ2Uuc2V0KHRhcmdldC5jb25zdHJ1Y3Rvciwgc2NoZW1hKTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIHNjaGVtYSA9IHNjaGVtYVN0b3JhZ2UuZ2V0KHRhcmdldC5jb25zdHJ1Y3Rvcik7XHJcbiAgICAgICAgaWYgKHNjaGVtYS50YXJnZXQgIT09IHRhcmdldC5jb25zdHJ1Y3Rvcikge1xyXG4gICAgICAgICAgICBzY2hlbWEgPSBzY2hlbWFTdG9yYWdlLmNyZWF0ZSh0YXJnZXQuY29uc3RydWN0b3IpO1xyXG4gICAgICAgICAgICBzY2hlbWFTdG9yYWdlLnNldCh0YXJnZXQuY29uc3RydWN0b3IsIHNjaGVtYSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgY29uc3QgZGVmYXVsdFNjaGVtYSA9IHtcclxuICAgICAgICB0eXBlOiBKc29uUHJvcFR5cGVzLkFueSxcclxuICAgICAgICB2YWxpZGF0aW9uczogW10sXHJcbiAgICB9O1xyXG4gICAgY29uc3QgY29weU9wdGlvbnMgPSBPYmplY3QuYXNzaWduKGRlZmF1bHRTY2hlbWEsIG9wdGlvbnMpO1xyXG4gICAgY29weU9wdGlvbnMudmFsaWRhdGlvbnMgPSBnZXRWYWxpZGF0aW9ucyhjb3B5T3B0aW9ucyk7XHJcbiAgICBpZiAodHlwZW9mIGNvcHlPcHRpb25zLnR5cGUgIT09IFwibnVtYmVyXCIpIHtcclxuICAgICAgICBpZiAoIXNjaGVtYVN0b3JhZ2UuaGFzKGNvcHlPcHRpb25zLnR5cGUpICYmICFpc0NvbnZlcnRpYmxlKGNvcHlPcHRpb25zLnR5cGUpKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtlcnJvck1lc3NhZ2V9LiBBc3NpZ25pbmcgdHlwZSBkb2Vzbid0IGhhdmUgc2NoZW1hLmApO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGxldCBzY2hlbWFOYW1lcztcclxuICAgIGlmIChBcnJheS5pc0FycmF5KG9wdGlvbnMuc2NoZW1hKSkge1xyXG4gICAgICAgIHNjaGVtYU5hbWVzID0gb3B0aW9ucy5zY2hlbWE7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICBzY2hlbWFOYW1lcyA9IFtvcHRpb25zLnNjaGVtYSB8fCBERUZBVUxUX1NDSEVNQV07XHJcbiAgICB9XHJcbiAgICBmb3IgKGNvbnN0IHNjaGVtYU5hbWUgb2Ygc2NoZW1hTmFtZXMpIHtcclxuICAgICAgICBpZiAoIXNjaGVtYS5uYW1lc1tzY2hlbWFOYW1lXSkge1xyXG4gICAgICAgICAgICBzY2hlbWEubmFtZXNbc2NoZW1hTmFtZV0gPSB7fTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgbmFtZWRTY2hlbWEgPSBzY2hlbWEubmFtZXNbc2NoZW1hTmFtZV07XHJcbiAgICAgICAgbmFtZWRTY2hlbWFbcHJvcGVydHlLZXldID0gY29weU9wdGlvbnM7XHJcbiAgICB9XHJcbn07XG5cbmV4cG9ydCB7IEpzb25FcnJvciwgSnNvblBhcnNlciwgSnNvblByb3AsIEpzb25Qcm9wVHlwZXMsIEpzb25TZXJpYWxpemVyLCBLZXlFcnJvciwgUGFyc2VyRXJyb3IsIFNlcmlhbGl6ZXJFcnJvciwgVHJhbnNmb3JtRXJyb3IsIFZhbGlkYXRpb25FcnJvciB9O1xuIiwgIi8qIVxuIENvcHlyaWdodCAoYykgUGVjdWxpYXIgVmVudHVyZXMsIExMQ1xuKi9cblxuaW1wb3J0IHsgQ29udmVydCwgQnVmZmVyU291cmNlQ29udmVydGVyLCBjb21iaW5lIH0gZnJvbSAncHZ0c3V0aWxzJztcbmV4cG9ydCB7IEJ1ZmZlclNvdXJjZUNvbnZlcnRlciB9IGZyb20gJ3B2dHN1dGlscyc7XG5pbXBvcnQgeyBBc25Qcm9wLCBBc25Qcm9wVHlwZXMsIEFzblR5cGUsIEFzblR5cGVUeXBlcywgQXNuSW50ZWdlckNvbnZlcnRlciwgQXNuU2VyaWFsaXplciwgQXNuQ29udmVydCB9IGZyb20gJ0BwZWN1bGlhci9hc24xLXNjaGVtYSc7XG5pbXBvcnQgeyBfX2RlY29yYXRlIH0gZnJvbSAndHNsaWInO1xuaW1wb3J0IHsgSnNvblByb3AsIEpzb25Qcm9wVHlwZXMgfSBmcm9tICdAcGVjdWxpYXIvanNvbi1zY2hlbWEnO1xuaW1wb3J0ICogYXMgYXNuMSBmcm9tICdhc24xanMnO1xuXG5jbGFzcyBDcnlwdG9FcnJvciBleHRlbmRzIEVycm9yIHtcbn1cblxuY2xhc3MgQWxnb3JpdGhtRXJyb3IgZXh0ZW5kcyBDcnlwdG9FcnJvciB7XG59XG5cbmNsYXNzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXJyb3IgZXh0ZW5kcyBDcnlwdG9FcnJvciB7XG4gICAgY29uc3RydWN0b3IobWV0aG9kTmFtZSkge1xuICAgICAgICBzdXBlcihgVW5zdXBwb3J0ZWQgb3BlcmF0aW9uOiAke21ldGhvZE5hbWUgPyBgJHttZXRob2ROYW1lfWAgOiBcIlwifWApO1xuICAgIH1cbn1cblxuY2xhc3MgT3BlcmF0aW9uRXJyb3IgZXh0ZW5kcyBDcnlwdG9FcnJvciB7XG59XG5cbmNsYXNzIFJlcXVpcmVkUHJvcGVydHlFcnJvciBleHRlbmRzIENyeXB0b0Vycm9yIHtcbiAgICBjb25zdHJ1Y3Rvcihwcm9wTmFtZSkge1xuICAgICAgICBzdXBlcihgJHtwcm9wTmFtZX06IE1pc3NpbmcgcmVxdWlyZWQgcHJvcGVydHlgKTtcbiAgICB9XG59XG5cbmNsYXNzIFBlbUNvbnZlcnRlciB7XG4gICAgc3RhdGljIHRvQXJyYXlCdWZmZXIocGVtKSB7XG4gICAgICAgIGNvbnN0IGJhc2U2NCA9IHBlbVxuICAgICAgICAgICAgLnJlcGxhY2UoLy17NX0oQkVHSU58RU5EKSAuKi17NX0vZywgXCJcIilcbiAgICAgICAgICAgIC5yZXBsYWNlKFwiXFxyXCIsIFwiXCIpXG4gICAgICAgICAgICAucmVwbGFjZShcIlxcblwiLCBcIlwiKTtcbiAgICAgICAgcmV0dXJuIENvbnZlcnQuRnJvbUJhc2U2NChiYXNlNjQpO1xuICAgIH1cbiAgICBzdGF0aWMgdG9VaW50OEFycmF5KHBlbSkge1xuICAgICAgICBjb25zdCBieXRlcyA9IHRoaXMudG9BcnJheUJ1ZmZlcihwZW0pO1xuICAgICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoYnl0ZXMpO1xuICAgIH1cbiAgICBzdGF0aWMgZnJvbUJ1ZmZlclNvdXJjZShidWZmZXIsIHRhZykge1xuICAgICAgICBjb25zdCBiYXNlNjQgPSBDb252ZXJ0LlRvQmFzZTY0KGJ1ZmZlcik7XG4gICAgICAgIGxldCBzbGljZWQ7XG4gICAgICAgIGxldCBvZmZzZXQgPSAwO1xuICAgICAgICBjb25zdCByb3dzID0gW107XG4gICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgICBzbGljZWQgPSBiYXNlNjQuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgPSBvZmZzZXQgKyA2NCk7XG4gICAgICAgICAgICBpZiAoc2xpY2VkLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHJvd3MucHVzaChzbGljZWQpO1xuICAgICAgICAgICAgICAgIGlmIChzbGljZWQubGVuZ3RoIDwgNjQpIHtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdXBwZXJDYXNlVGFnID0gdGFnLnRvVXBwZXJDYXNlKCk7XG4gICAgICAgIHJldHVybiBgLS0tLS1CRUdJTiAke3VwcGVyQ2FzZVRhZ30tLS0tLVxcbiR7cm93cy5qb2luKFwiXFxuXCIpfVxcbi0tLS0tRU5EICR7dXBwZXJDYXNlVGFnfS0tLS0tYDtcbiAgICB9XG4gICAgc3RhdGljIGlzUEVNKGRhdGEpIHtcbiAgICAgICAgcmV0dXJuIC8tLS0tLUJFR0lOIC4rLS0tLS1bQS1aYS16MC05K1xcL1xcK1xcPVxcc1xcbl0rLS0tLS1FTkQgListLS0tLS9pLnRlc3QoZGF0YSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXRUYWdOYW1lKHBlbSkge1xuICAgICAgICBpZiAoIXRoaXMuaXNQRU0ocGVtKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQmFkIHBhcmFtZXRlci4gSW5jb21pbmcgZGF0YSBpcyBub3QgcmlnaHQgUEVNXCIpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlcyA9IC8tLS0tLUJFR0lOICguKyktLS0tLS8uZXhlYyhwZW0pO1xuICAgICAgICBpZiAoIXJlcykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2Fubm90IGdldCB0YWcgZnJvbSBQRU1cIik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc1sxXTtcbiAgICB9XG4gICAgc3RhdGljIGhhc1RhZ05hbWUocGVtLCB0YWdOYW1lKSB7XG4gICAgICAgIGNvbnN0IHRhZyA9IHRoaXMuZ2V0VGFnTmFtZShwZW0pO1xuICAgICAgICByZXR1cm4gdGFnTmFtZS50b0xvd2VyQ2FzZSgpID09PSB0YWcudG9Mb3dlckNhc2UoKTtcbiAgICB9XG4gICAgc3RhdGljIGlzQ2VydGlmaWNhdGUocGVtKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmhhc1RhZ05hbWUocGVtLCBcImNlcnRpZmljYXRlXCIpO1xuICAgIH1cbiAgICBzdGF0aWMgaXNDZXJ0aWZpY2F0ZVJlcXVlc3QocGVtKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmhhc1RhZ05hbWUocGVtLCBcImNlcnRpZmljYXRlIHJlcXVlc3RcIik7XG4gICAgfVxuICAgIHN0YXRpYyBpc0NSTChwZW0pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFzVGFnTmFtZShwZW0sIFwieDUwOSBjcmxcIik7XG4gICAgfVxuICAgIHN0YXRpYyBpc1B1YmxpY0tleShwZW0pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFzVGFnTmFtZShwZW0sIFwicHVibGljIGtleVwiKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGlzSldLKGRhdGEpIHtcbiAgICByZXR1cm4gdHlwZW9mIGRhdGEgPT09IFwib2JqZWN0XCIgJiYgXCJrdHlcIiBpbiBkYXRhO1xufVxuXG5jbGFzcyBQcm92aWRlckNyeXB0byB7XG4gICAgYXN5bmMgZGlnZXN0KC4uLmFyZ3MpIHtcbiAgICAgICAgdGhpcy5jaGVja0RpZ2VzdC5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgcmV0dXJuIHRoaXMub25EaWdlc3QuYXBwbHkodGhpcywgYXJncyk7XG4gICAgfVxuICAgIGNoZWNrRGlnZXN0KGFsZ29yaXRobSwgZGF0YSkge1xuICAgICAgICB0aGlzLmNoZWNrQWxnb3JpdGhtTmFtZShhbGdvcml0aG0pO1xuICAgIH1cbiAgICBhc3luYyBvbkRpZ2VzdChhbGdvcml0aG0sIGRhdGEpIHtcbiAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXJyb3IoXCJkaWdlc3RcIik7XG4gICAgfVxuICAgIGFzeW5jIGdlbmVyYXRlS2V5KC4uLmFyZ3MpIHtcbiAgICAgICAgdGhpcy5jaGVja0dlbmVyYXRlS2V5LmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICByZXR1cm4gdGhpcy5vbkdlbmVyYXRlS2V5LmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH1cbiAgICBjaGVja0dlbmVyYXRlS2V5KGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcywgLi4uYXJncykge1xuICAgICAgICB0aGlzLmNoZWNrQWxnb3JpdGhtTmFtZShhbGdvcml0aG0pO1xuICAgICAgICB0aGlzLmNoZWNrR2VuZXJhdGVLZXlQYXJhbXMoYWxnb3JpdGhtKTtcbiAgICAgICAgaWYgKCEoa2V5VXNhZ2VzICYmIGtleVVzYWdlcy5sZW5ndGgpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBVc2FnZXMgY2Fubm90IGJlIGVtcHR5IHdoZW4gY3JlYXRpbmcgYSBrZXkuYCk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGFsbG93ZWRVc2FnZXM7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHRoaXMudXNhZ2VzKSkge1xuICAgICAgICAgICAgYWxsb3dlZFVzYWdlcyA9IHRoaXMudXNhZ2VzO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgYWxsb3dlZFVzYWdlcyA9IHRoaXMudXNhZ2VzLnByaXZhdGVLZXkuY29uY2F0KHRoaXMudXNhZ2VzLnB1YmxpY0tleSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jaGVja0tleVVzYWdlcyhrZXlVc2FnZXMsIGFsbG93ZWRVc2FnZXMpO1xuICAgIH1cbiAgICBjaGVja0dlbmVyYXRlS2V5UGFyYW1zKGFsZ29yaXRobSkge1xuICAgIH1cbiAgICBhc3luYyBvbkdlbmVyYXRlS2V5KGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcywgLi4uYXJncykge1xuICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FcnJvcihcImdlbmVyYXRlS2V5XCIpO1xuICAgIH1cbiAgICBhc3luYyBzaWduKC4uLmFyZ3MpIHtcbiAgICAgICAgdGhpcy5jaGVja1NpZ24uYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgIHJldHVybiB0aGlzLm9uU2lnbi5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9XG4gICAgY2hlY2tTaWduKGFsZ29yaXRobSwga2V5LCBkYXRhLCAuLi5hcmdzKSB7XG4gICAgICAgIHRoaXMuY2hlY2tBbGdvcml0aG1OYW1lKGFsZ29yaXRobSk7XG4gICAgICAgIHRoaXMuY2hlY2tBbGdvcml0aG1QYXJhbXMoYWxnb3JpdGhtKTtcbiAgICAgICAgdGhpcy5jaGVja0NyeXB0b0tleShrZXksIFwic2lnblwiKTtcbiAgICB9XG4gICAgYXN5bmMgb25TaWduKGFsZ29yaXRobSwga2V5LCBkYXRhLCAuLi5hcmdzKSB7XG4gICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkVycm9yKFwic2lnblwiKTtcbiAgICB9XG4gICAgYXN5bmMgdmVyaWZ5KC4uLmFyZ3MpIHtcbiAgICAgICAgdGhpcy5jaGVja1ZlcmlmeS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgcmV0dXJuIHRoaXMub25WZXJpZnkuYXBwbHkodGhpcywgYXJncyk7XG4gICAgfVxuICAgIGNoZWNrVmVyaWZ5KGFsZ29yaXRobSwga2V5LCBzaWduYXR1cmUsIGRhdGEsIC4uLmFyZ3MpIHtcbiAgICAgICAgdGhpcy5jaGVja0FsZ29yaXRobU5hbWUoYWxnb3JpdGhtKTtcbiAgICAgICAgdGhpcy5jaGVja0FsZ29yaXRobVBhcmFtcyhhbGdvcml0aG0pO1xuICAgICAgICB0aGlzLmNoZWNrQ3J5cHRvS2V5KGtleSwgXCJ2ZXJpZnlcIik7XG4gICAgfVxuICAgIGFzeW5jIG9uVmVyaWZ5KGFsZ29yaXRobSwga2V5LCBzaWduYXR1cmUsIGRhdGEsIC4uLmFyZ3MpIHtcbiAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXJyb3IoXCJ2ZXJpZnlcIik7XG4gICAgfVxuICAgIGFzeW5jIGVuY3J5cHQoLi4uYXJncykge1xuICAgICAgICB0aGlzLmNoZWNrRW5jcnlwdC5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgcmV0dXJuIHRoaXMub25FbmNyeXB0LmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH1cbiAgICBjaGVja0VuY3J5cHQoYWxnb3JpdGhtLCBrZXksIGRhdGEsIG9wdGlvbnMgPSB7fSwgLi4uYXJncykge1xuICAgICAgICB0aGlzLmNoZWNrQWxnb3JpdGhtTmFtZShhbGdvcml0aG0pO1xuICAgICAgICB0aGlzLmNoZWNrQWxnb3JpdGhtUGFyYW1zKGFsZ29yaXRobSk7XG4gICAgICAgIHRoaXMuY2hlY2tDcnlwdG9LZXkoa2V5LCBvcHRpb25zLmtleVVzYWdlID8gXCJlbmNyeXB0XCIgOiB2b2lkIDApO1xuICAgIH1cbiAgICBhc3luYyBvbkVuY3J5cHQoYWxnb3JpdGhtLCBrZXksIGRhdGEsIC4uLmFyZ3MpIHtcbiAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXJyb3IoXCJlbmNyeXB0XCIpO1xuICAgIH1cbiAgICBhc3luYyBkZWNyeXB0KC4uLmFyZ3MpIHtcbiAgICAgICAgdGhpcy5jaGVja0RlY3J5cHQuYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgIHJldHVybiB0aGlzLm9uRGVjcnlwdC5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9XG4gICAgY2hlY2tEZWNyeXB0KGFsZ29yaXRobSwga2V5LCBkYXRhLCBvcHRpb25zID0ge30sIC4uLmFyZ3MpIHtcbiAgICAgICAgdGhpcy5jaGVja0FsZ29yaXRobU5hbWUoYWxnb3JpdGhtKTtcbiAgICAgICAgdGhpcy5jaGVja0FsZ29yaXRobVBhcmFtcyhhbGdvcml0aG0pO1xuICAgICAgICB0aGlzLmNoZWNrQ3J5cHRvS2V5KGtleSwgb3B0aW9ucy5rZXlVc2FnZSA/IFwiZGVjcnlwdFwiIDogdm9pZCAwKTtcbiAgICB9XG4gICAgYXN5bmMgb25EZWNyeXB0KGFsZ29yaXRobSwga2V5LCBkYXRhLCAuLi5hcmdzKSB7XG4gICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkVycm9yKFwiZGVjcnlwdFwiKTtcbiAgICB9XG4gICAgYXN5bmMgZGVyaXZlQml0cyguLi5hcmdzKSB7XG4gICAgICAgIHRoaXMuY2hlY2tEZXJpdmVCaXRzLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICByZXR1cm4gdGhpcy5vbkRlcml2ZUJpdHMuYXBwbHkodGhpcywgYXJncyk7XG4gICAgfVxuICAgIGNoZWNrRGVyaXZlQml0cyhhbGdvcml0aG0sIGJhc2VLZXksIGxlbmd0aCwgb3B0aW9ucyA9IHt9LCAuLi5hcmdzKSB7XG4gICAgICAgIHRoaXMuY2hlY2tBbGdvcml0aG1OYW1lKGFsZ29yaXRobSk7XG4gICAgICAgIHRoaXMuY2hlY2tBbGdvcml0aG1QYXJhbXMoYWxnb3JpdGhtKTtcbiAgICAgICAgdGhpcy5jaGVja0NyeXB0b0tleShiYXNlS2V5LCBvcHRpb25zLmtleVVzYWdlID8gXCJkZXJpdmVCaXRzXCIgOiB2b2lkIDApO1xuICAgICAgICBpZiAobGVuZ3RoICUgOCAhPT0gMCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IE9wZXJhdGlvbkVycm9yKFwibGVuZ3RoOiBJcyBub3QgbXVsdGlwbGUgb2YgOFwiKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhc3luYyBvbkRlcml2ZUJpdHMoYWxnb3JpdGhtLCBiYXNlS2V5LCBsZW5ndGgsIC4uLmFyZ3MpIHtcbiAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXJyb3IoXCJkZXJpdmVCaXRzXCIpO1xuICAgIH1cbiAgICBhc3luYyBleHBvcnRLZXkoLi4uYXJncykge1xuICAgICAgICB0aGlzLmNoZWNrRXhwb3J0S2V5LmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICByZXR1cm4gdGhpcy5vbkV4cG9ydEtleS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9XG4gICAgY2hlY2tFeHBvcnRLZXkoZm9ybWF0LCBrZXksIC4uLmFyZ3MpIHtcbiAgICAgICAgdGhpcy5jaGVja0tleUZvcm1hdChmb3JtYXQpO1xuICAgICAgICB0aGlzLmNoZWNrQ3J5cHRvS2V5KGtleSk7XG4gICAgICAgIGlmICgha2V5LmV4dHJhY3RhYmxlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQ3J5cHRvRXJyb3IoXCJrZXk6IElzIG5vdCBleHRyYWN0YWJsZVwiKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhc3luYyBvbkV4cG9ydEtleShmb3JtYXQsIGtleSwgLi4uYXJncykge1xuICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FcnJvcihcImV4cG9ydEtleVwiKTtcbiAgICB9XG4gICAgYXN5bmMgaW1wb3J0S2V5KC4uLmFyZ3MpIHtcbiAgICAgICAgdGhpcy5jaGVja0ltcG9ydEtleS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgcmV0dXJuIHRoaXMub25JbXBvcnRLZXkuYXBwbHkodGhpcywgYXJncyk7XG4gICAgfVxuICAgIGNoZWNrSW1wb3J0S2V5KGZvcm1hdCwga2V5RGF0YSwgYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzLCAuLi5hcmdzKSB7XG4gICAgICAgIHRoaXMuY2hlY2tLZXlGb3JtYXQoZm9ybWF0KTtcbiAgICAgICAgdGhpcy5jaGVja0tleURhdGEoZm9ybWF0LCBrZXlEYXRhKTtcbiAgICAgICAgdGhpcy5jaGVja0FsZ29yaXRobU5hbWUoYWxnb3JpdGhtKTtcbiAgICAgICAgdGhpcy5jaGVja0ltcG9ydFBhcmFtcyhhbGdvcml0aG0pO1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh0aGlzLnVzYWdlcykpIHtcbiAgICAgICAgICAgIHRoaXMuY2hlY2tLZXlVc2FnZXMoa2V5VXNhZ2VzLCB0aGlzLnVzYWdlcyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgYXN5bmMgb25JbXBvcnRLZXkoZm9ybWF0LCBrZXlEYXRhLCBhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMsIC4uLmFyZ3MpIHtcbiAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXJyb3IoXCJpbXBvcnRLZXlcIik7XG4gICAgfVxuICAgIGNoZWNrQWxnb3JpdGhtTmFtZShhbGdvcml0aG0pIHtcbiAgICAgICAgaWYgKGFsZ29yaXRobS5uYW1lLnRvTG93ZXJDYXNlKCkgIT09IHRoaXMubmFtZS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQWxnb3JpdGhtRXJyb3IoXCJVbnJlY29nbml6ZWQgbmFtZVwiKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjaGVja0FsZ29yaXRobVBhcmFtcyhhbGdvcml0aG0pIHtcbiAgICB9XG4gICAgY2hlY2tEZXJpdmVkS2V5UGFyYW1zKGFsZ29yaXRobSkge1xuICAgIH1cbiAgICBjaGVja0tleVVzYWdlcyh1c2FnZXMsIGFsbG93ZWQpIHtcbiAgICAgICAgZm9yIChjb25zdCB1c2FnZSBvZiB1c2FnZXMpIHtcbiAgICAgICAgICAgIGlmIChhbGxvd2VkLmluZGV4T2YodXNhZ2UpID09PSAtMSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY3JlYXRlIGEga2V5IHVzaW5nIHRoZSBzcGVjaWZpZWQga2V5IHVzYWdlc1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBjaGVja0NyeXB0b0tleShrZXksIGtleVVzYWdlKSB7XG4gICAgICAgIHRoaXMuY2hlY2tBbGdvcml0aG1OYW1lKGtleS5hbGdvcml0aG0pO1xuICAgICAgICBpZiAoa2V5VXNhZ2UgJiYga2V5LnVzYWdlcy5pbmRleE9mKGtleVVzYWdlKSA9PT0gLTEpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBDcnlwdG9FcnJvcihga2V5IGRvZXMgbm90IG1hdGNoIHRoYXQgb2Ygb3BlcmF0aW9uYCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY2hlY2tSZXF1aXJlZFByb3BlcnR5KGRhdGEsIHByb3BOYW1lKSB7XG4gICAgICAgIGlmICghKHByb3BOYW1lIGluIGRhdGEpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUmVxdWlyZWRQcm9wZXJ0eUVycm9yKHByb3BOYW1lKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjaGVja0hhc2hBbGdvcml0aG0oYWxnb3JpdGhtLCBoYXNoQWxnb3JpdGhtcykge1xuICAgICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgaGFzaEFsZ29yaXRobXMpIHtcbiAgICAgICAgICAgIGlmIChpdGVtLnRvTG93ZXJDYXNlKCkgPT09IGFsZ29yaXRobS5uYW1lLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IE9wZXJhdGlvbkVycm9yKGBoYXNoOiBNdXN0IGJlIG9uZSBvZiAke2hhc2hBbGdvcml0aG1zLmpvaW4oXCIsIFwiKX1gKTtcbiAgICB9XG4gICAgY2hlY2tJbXBvcnRQYXJhbXMoYWxnb3JpdGhtKSB7XG4gICAgfVxuICAgIGNoZWNrS2V5Rm9ybWF0KGZvcm1hdCkge1xuICAgICAgICBzd2l0Y2ggKGZvcm1hdCkge1xuICAgICAgICAgICAgY2FzZSBcInJhd1wiOlxuICAgICAgICAgICAgY2FzZSBcInBrY3M4XCI6XG4gICAgICAgICAgICBjYXNlIFwic3BraVwiOlxuICAgICAgICAgICAgY2FzZSBcImp3a1wiOlxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiZm9ybWF0OiBJcyBpbnZhbGlkIHZhbHVlLiBNdXN0IGJlICdqd2snLCAncmF3JywgJ3Nwa2knLCBvciAncGtjczgnXCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGNoZWNrS2V5RGF0YShmb3JtYXQsIGtleURhdGEpIHtcbiAgICAgICAgaWYgKCFrZXlEYXRhKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwia2V5RGF0YTogQ2Fubm90IGJlIGVtcHR5IG9uIGVtcHR5IG9uIGtleSBpbXBvcnRpbmdcIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZvcm1hdCA9PT0gXCJqd2tcIikge1xuICAgICAgICAgICAgaWYgKCFpc0pXSyhrZXlEYXRhKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJrZXlEYXRhOiBJcyBub3QgSnNvbldlYlRva2VuXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKCFCdWZmZXJTb3VyY2VDb252ZXJ0ZXIuaXNCdWZmZXJTb3VyY2Uoa2V5RGF0YSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJrZXlEYXRhOiBJcyBub3QgQXJyYXlCdWZmZXJWaWV3IG9yIEFycmF5QnVmZmVyXCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHByZXBhcmVEYXRhKGRhdGEpIHtcbiAgICAgICAgcmV0dXJuIEJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b0FycmF5QnVmZmVyKGRhdGEpO1xuICAgIH1cbn1cblxuY2xhc3MgQWVzUHJvdmlkZXIgZXh0ZW5kcyBQcm92aWRlckNyeXB0byB7XG4gICAgY2hlY2tHZW5lcmF0ZUtleVBhcmFtcyhhbGdvcml0aG0pIHtcbiAgICAgICAgdGhpcy5jaGVja1JlcXVpcmVkUHJvcGVydHkoYWxnb3JpdGhtLCBcImxlbmd0aFwiKTtcbiAgICAgICAgaWYgKHR5cGVvZiBhbGdvcml0aG0ubGVuZ3RoICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwibGVuZ3RoOiBJcyBub3Qgb2YgdHlwZSBOdW1iZXJcIik7XG4gICAgICAgIH1cbiAgICAgICAgc3dpdGNoIChhbGdvcml0aG0ubGVuZ3RoKSB7XG4gICAgICAgICAgICBjYXNlIDEyODpcbiAgICAgICAgICAgIGNhc2UgMTkyOlxuICAgICAgICAgICAgY2FzZSAyNTY6XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJsZW5ndGg6IE11c3QgYmUgMTI4LCAxOTIsIG9yIDI1NlwiKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjaGVja0Rlcml2ZWRLZXlQYXJhbXMoYWxnb3JpdGhtKSB7XG4gICAgICAgIHRoaXMuY2hlY2tHZW5lcmF0ZUtleVBhcmFtcyhhbGdvcml0aG0pO1xuICAgIH1cbn1cblxuY2xhc3MgQWVzQ2JjUHJvdmlkZXIgZXh0ZW5kcyBBZXNQcm92aWRlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQUVTLUNCQ1wiO1xuICAgICAgICB0aGlzLnVzYWdlcyA9IFtcImVuY3J5cHRcIiwgXCJkZWNyeXB0XCIsIFwid3JhcEtleVwiLCBcInVud3JhcEtleVwiXTtcbiAgICB9XG4gICAgY2hlY2tBbGdvcml0aG1QYXJhbXMoYWxnb3JpdGhtKSB7XG4gICAgICAgIHRoaXMuY2hlY2tSZXF1aXJlZFByb3BlcnR5KGFsZ29yaXRobSwgXCJpdlwiKTtcbiAgICAgICAgaWYgKCEoYWxnb3JpdGhtLml2IGluc3RhbmNlb2YgQXJyYXlCdWZmZXIgfHwgQXJyYXlCdWZmZXIuaXNWaWV3KGFsZ29yaXRobS5pdikpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiaXY6IElzIG5vdCBvZiB0eXBlICcoQXJyYXlCdWZmZXIgb3IgQXJyYXlCdWZmZXJWaWV3KSdcIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGFsZ29yaXRobS5pdi5ieXRlTGVuZ3RoICE9PSAxNikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIml2OiBNdXN0IGhhdmUgbGVuZ3RoIDE2IGJ5dGVzXCIpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5jbGFzcyBBZXNDbWFjUHJvdmlkZXIgZXh0ZW5kcyBBZXNQcm92aWRlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQUVTLUNNQUNcIjtcbiAgICAgICAgdGhpcy51c2FnZXMgPSBbXCJzaWduXCIsIFwidmVyaWZ5XCJdO1xuICAgIH1cbiAgICBjaGVja0FsZ29yaXRobVBhcmFtcyhhbGdvcml0aG0pIHtcbiAgICAgICAgdGhpcy5jaGVja1JlcXVpcmVkUHJvcGVydHkoYWxnb3JpdGhtLCBcImxlbmd0aFwiKTtcbiAgICAgICAgaWYgKHR5cGVvZiBhbGdvcml0aG0ubGVuZ3RoICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwibGVuZ3RoOiBJcyBub3QgYSBOdW1iZXJcIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGFsZ29yaXRobS5sZW5ndGggPCAxKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgT3BlcmF0aW9uRXJyb3IoXCJsZW5ndGg6IE11c3QgYmUgbW9yZSB0aGFuIDBcIik7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmNsYXNzIEFlc0N0clByb3ZpZGVyIGV4dGVuZHMgQWVzUHJvdmlkZXIge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkFFUy1DVFJcIjtcbiAgICAgICAgdGhpcy51c2FnZXMgPSBbXCJlbmNyeXB0XCIsIFwiZGVjcnlwdFwiLCBcIndyYXBLZXlcIiwgXCJ1bndyYXBLZXlcIl07XG4gICAgfVxuICAgIGNoZWNrQWxnb3JpdGhtUGFyYW1zKGFsZ29yaXRobSkge1xuICAgICAgICB0aGlzLmNoZWNrUmVxdWlyZWRQcm9wZXJ0eShhbGdvcml0aG0sIFwiY291bnRlclwiKTtcbiAgICAgICAgaWYgKCEoYWxnb3JpdGhtLmNvdW50ZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlciB8fCBBcnJheUJ1ZmZlci5pc1ZpZXcoYWxnb3JpdGhtLmNvdW50ZXIpKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImNvdW50ZXI6IElzIG5vdCBvZiB0eXBlICcoQXJyYXlCdWZmZXIgb3IgQXJyYXlCdWZmZXJWaWV3KSdcIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGFsZ29yaXRobS5jb3VudGVyLmJ5dGVMZW5ndGggIT09IDE2KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiaXY6IE11c3QgaGF2ZSBsZW5ndGggMTYgYnl0ZXNcIik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jaGVja1JlcXVpcmVkUHJvcGVydHkoYWxnb3JpdGhtLCBcImxlbmd0aFwiKTtcbiAgICAgICAgaWYgKHR5cGVvZiBhbGdvcml0aG0ubGVuZ3RoICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwibGVuZ3RoOiBJcyBub3QgYSBOdW1iZXJcIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGFsZ29yaXRobS5sZW5ndGggPCAxKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgT3BlcmF0aW9uRXJyb3IoXCJsZW5ndGg6IE11c3QgYmUgbW9yZSB0aGFuIDBcIik7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmNsYXNzIEFlc0VjYlByb3ZpZGVyIGV4dGVuZHMgQWVzUHJvdmlkZXIge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkFFUy1FQ0JcIjtcbiAgICAgICAgdGhpcy51c2FnZXMgPSBbXCJlbmNyeXB0XCIsIFwiZGVjcnlwdFwiLCBcIndyYXBLZXlcIiwgXCJ1bndyYXBLZXlcIl07XG4gICAgfVxufVxuXG5jbGFzcyBBZXNHY21Qcm92aWRlciBleHRlbmRzIEFlc1Byb3ZpZGVyIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJBRVMtR0NNXCI7XG4gICAgICAgIHRoaXMudXNhZ2VzID0gW1wiZW5jcnlwdFwiLCBcImRlY3J5cHRcIiwgXCJ3cmFwS2V5XCIsIFwidW53cmFwS2V5XCJdO1xuICAgIH1cbiAgICBjaGVja0FsZ29yaXRobVBhcmFtcyhhbGdvcml0aG0pIHtcbiAgICAgICAgdGhpcy5jaGVja1JlcXVpcmVkUHJvcGVydHkoYWxnb3JpdGhtLCBcIml2XCIpO1xuICAgICAgICBpZiAoIShhbGdvcml0aG0uaXYgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlciB8fCBBcnJheUJ1ZmZlci5pc1ZpZXcoYWxnb3JpdGhtLml2KSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJpdjogSXMgbm90IG9mIHR5cGUgJyhBcnJheUJ1ZmZlciBvciBBcnJheUJ1ZmZlclZpZXcpJ1wiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYWxnb3JpdGhtLml2LmJ5dGVMZW5ndGggPCAxKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgT3BlcmF0aW9uRXJyb3IoXCJpdjogTXVzdCBoYXZlIGxlbmd0aCBtb3JlIHRoYW4gMCBhbmQgbGVzcyB0aGFuIDJeNjQgLSAxXCIpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghKFwidGFnTGVuZ3RoXCIgaW4gYWxnb3JpdGhtKSkge1xuICAgICAgICAgICAgYWxnb3JpdGhtLnRhZ0xlbmd0aCA9IDEyODtcbiAgICAgICAgfVxuICAgICAgICBzd2l0Y2ggKGFsZ29yaXRobS50YWdMZW5ndGgpIHtcbiAgICAgICAgICAgIGNhc2UgMzI6XG4gICAgICAgICAgICBjYXNlIDY0OlxuICAgICAgICAgICAgY2FzZSA5NjpcbiAgICAgICAgICAgIGNhc2UgMTA0OlxuICAgICAgICAgICAgY2FzZSAxMTI6XG4gICAgICAgICAgICBjYXNlIDEyMDpcbiAgICAgICAgICAgIGNhc2UgMTI4OlxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgT3BlcmF0aW9uRXJyb3IoXCJ0YWdMZW5ndGg6IE11c3QgYmUgb25lIG9mIDMyLCA2NCwgOTYsIDEwNCwgMTEyLCAxMjAgb3IgMTI4XCIpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5jbGFzcyBBZXNLd1Byb3ZpZGVyIGV4dGVuZHMgQWVzUHJvdmlkZXIge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkFFUy1LV1wiO1xuICAgICAgICB0aGlzLnVzYWdlcyA9IFtcIndyYXBLZXlcIiwgXCJ1bndyYXBLZXlcIl07XG4gICAgfVxufVxuXG5jbGFzcyBEZXNQcm92aWRlciBleHRlbmRzIFByb3ZpZGVyQ3J5cHRvIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy51c2FnZXMgPSBbXCJlbmNyeXB0XCIsIFwiZGVjcnlwdFwiLCBcIndyYXBLZXlcIiwgXCJ1bndyYXBLZXlcIl07XG4gICAgfVxuICAgIGNoZWNrQWxnb3JpdGhtUGFyYW1zKGFsZ29yaXRobSkge1xuICAgICAgICBpZiAodGhpcy5pdlNpemUpIHtcbiAgICAgICAgICAgIHRoaXMuY2hlY2tSZXF1aXJlZFByb3BlcnR5KGFsZ29yaXRobSwgXCJpdlwiKTtcbiAgICAgICAgICAgIGlmICghKGFsZ29yaXRobS5pdiBpbnN0YW5jZW9mIEFycmF5QnVmZmVyIHx8IEFycmF5QnVmZmVyLmlzVmlldyhhbGdvcml0aG0uaXYpKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJpdjogSXMgbm90IG9mIHR5cGUgJyhBcnJheUJ1ZmZlciBvciBBcnJheUJ1ZmZlclZpZXcpJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChhbGdvcml0aG0uaXYuYnl0ZUxlbmd0aCAhPT0gdGhpcy5pdlNpemUpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBpdjogTXVzdCBoYXZlIGxlbmd0aCAke3RoaXMuaXZTaXplfSBieXRlc2ApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIGNoZWNrR2VuZXJhdGVLZXlQYXJhbXMoYWxnb3JpdGhtKSB7XG4gICAgICAgIHRoaXMuY2hlY2tSZXF1aXJlZFByb3BlcnR5KGFsZ29yaXRobSwgXCJsZW5ndGhcIik7XG4gICAgICAgIGlmICh0eXBlb2YgYWxnb3JpdGhtLmxlbmd0aCAhPT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImxlbmd0aDogSXMgbm90IG9mIHR5cGUgTnVtYmVyXCIpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChhbGdvcml0aG0ubGVuZ3RoICE9PSB0aGlzLmtleVNpemVCaXRzKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgT3BlcmF0aW9uRXJyb3IoYGFsZ29yaXRobS5sZW5ndGg6IE11c3QgYmUgJHt0aGlzLmtleVNpemVCaXRzfWApO1xuICAgICAgICB9XG4gICAgfVxuICAgIGNoZWNrRGVyaXZlZEtleVBhcmFtcyhhbGdvcml0aG0pIHtcbiAgICAgICAgdGhpcy5jaGVja0dlbmVyYXRlS2V5UGFyYW1zKGFsZ29yaXRobSk7XG4gICAgfVxufVxuXG5jbGFzcyBSc2FQcm92aWRlciBleHRlbmRzIFByb3ZpZGVyQ3J5cHRvIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5oYXNoQWxnb3JpdGhtcyA9IFtcIlNIQS0xXCIsIFwiU0hBLTI1NlwiLCBcIlNIQS0zODRcIiwgXCJTSEEtNTEyXCJdO1xuICAgIH1cbiAgICBjaGVja0dlbmVyYXRlS2V5UGFyYW1zKGFsZ29yaXRobSkge1xuICAgICAgICB0aGlzLmNoZWNrUmVxdWlyZWRQcm9wZXJ0eShhbGdvcml0aG0sIFwiaGFzaFwiKTtcbiAgICAgICAgdGhpcy5jaGVja0hhc2hBbGdvcml0aG0oYWxnb3JpdGhtLmhhc2gsIHRoaXMuaGFzaEFsZ29yaXRobXMpO1xuICAgICAgICB0aGlzLmNoZWNrUmVxdWlyZWRQcm9wZXJ0eShhbGdvcml0aG0sIFwicHVibGljRXhwb25lbnRcIik7XG4gICAgICAgIGlmICghKGFsZ29yaXRobS5wdWJsaWNFeHBvbmVudCAmJiBhbGdvcml0aG0ucHVibGljRXhwb25lbnQgaW5zdGFuY2VvZiBVaW50OEFycmF5KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInB1YmxpY0V4cG9uZW50OiBNaXNzaW5nIG9yIG5vdCBhIFVpbnQ4QXJyYXlcIik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcHVibGljRXhwb25lbnQgPSBDb252ZXJ0LlRvQmFzZTY0KGFsZ29yaXRobS5wdWJsaWNFeHBvbmVudCk7XG4gICAgICAgIGlmICghKHB1YmxpY0V4cG9uZW50ID09PSBcIkF3PT1cIiB8fCBwdWJsaWNFeHBvbmVudCA9PT0gXCJBUUFCXCIpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwicHVibGljRXhwb25lbnQ6IE11c3QgYmUgWzNdIG9yIFsxLDAsMV1cIik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jaGVja1JlcXVpcmVkUHJvcGVydHkoYWxnb3JpdGhtLCBcIm1vZHVsdXNMZW5ndGhcIik7XG4gICAgICAgIGlmIChhbGdvcml0aG0ubW9kdWx1c0xlbmd0aCAlIDhcbiAgICAgICAgICAgIHx8IGFsZ29yaXRobS5tb2R1bHVzTGVuZ3RoIDwgMjU2XG4gICAgICAgICAgICB8fCBhbGdvcml0aG0ubW9kdWx1c0xlbmd0aCA+IDE2Mzg0KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiVGhlIG1vZHVsdXMgbGVuZ3RoIG11c3QgYmUgYSBtdWx0aXBsZSBvZiA4IGJpdHMgYW5kID49IDI1NiBhbmQgPD0gMTYzODRcIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY2hlY2tJbXBvcnRQYXJhbXMoYWxnb3JpdGhtKSB7XG4gICAgICAgIHRoaXMuY2hlY2tSZXF1aXJlZFByb3BlcnR5KGFsZ29yaXRobSwgXCJoYXNoXCIpO1xuICAgICAgICB0aGlzLmNoZWNrSGFzaEFsZ29yaXRobShhbGdvcml0aG0uaGFzaCwgdGhpcy5oYXNoQWxnb3JpdGhtcyk7XG4gICAgfVxufVxuXG5jbGFzcyBSc2FTc2FQcm92aWRlciBleHRlbmRzIFJzYVByb3ZpZGVyIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJSU0FTU0EtUEtDUzEtdjFfNVwiO1xuICAgICAgICB0aGlzLnVzYWdlcyA9IHtcbiAgICAgICAgICAgIHByaXZhdGVLZXk6IFtcInNpZ25cIl0sXG4gICAgICAgICAgICBwdWJsaWNLZXk6IFtcInZlcmlmeVwiXSxcbiAgICAgICAgfTtcbiAgICB9XG59XG5cbmNsYXNzIFJzYVBzc1Byb3ZpZGVyIGV4dGVuZHMgUnNhUHJvdmlkZXIge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlJTQS1QU1NcIjtcbiAgICAgICAgdGhpcy51c2FnZXMgPSB7XG4gICAgICAgICAgICBwcml2YXRlS2V5OiBbXCJzaWduXCJdLFxuICAgICAgICAgICAgcHVibGljS2V5OiBbXCJ2ZXJpZnlcIl0sXG4gICAgICAgIH07XG4gICAgfVxuICAgIGNoZWNrQWxnb3JpdGhtUGFyYW1zKGFsZ29yaXRobSkge1xuICAgICAgICB0aGlzLmNoZWNrUmVxdWlyZWRQcm9wZXJ0eShhbGdvcml0aG0sIFwic2FsdExlbmd0aFwiKTtcbiAgICAgICAgaWYgKHR5cGVvZiBhbGdvcml0aG0uc2FsdExlbmd0aCAhPT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInNhbHRMZW5ndGg6IElzIG5vdCBhIE51bWJlclwiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYWxnb3JpdGhtLnNhbHRMZW5ndGggPCAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcInNhbHRMZW5ndGg6IE11c3QgYmUgcG9zaXRpdmUgbnVtYmVyXCIpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5jbGFzcyBSc2FPYWVwUHJvdmlkZXIgZXh0ZW5kcyBSc2FQcm92aWRlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUlNBLU9BRVBcIjtcbiAgICAgICAgdGhpcy51c2FnZXMgPSB7XG4gICAgICAgICAgICBwcml2YXRlS2V5OiBbXCJkZWNyeXB0XCIsIFwidW53cmFwS2V5XCJdLFxuICAgICAgICAgICAgcHVibGljS2V5OiBbXCJlbmNyeXB0XCIsIFwid3JhcEtleVwiXSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgY2hlY2tBbGdvcml0aG1QYXJhbXMoYWxnb3JpdGhtKSB7XG4gICAgICAgIGlmIChhbGdvcml0aG0ubGFiZWxcbiAgICAgICAgICAgICYmICEoYWxnb3JpdGhtLmxhYmVsIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIgfHwgQXJyYXlCdWZmZXIuaXNWaWV3KGFsZ29yaXRobS5sYWJlbCkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwibGFiZWw6IElzIG5vdCBvZiB0eXBlICcoQXJyYXlCdWZmZXIgb3IgQXJyYXlCdWZmZXJWaWV3KSdcIik7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmNsYXNzIEVsbGlwdGljUHJvdmlkZXIgZXh0ZW5kcyBQcm92aWRlckNyeXB0byB7XG4gICAgY2hlY2tHZW5lcmF0ZUtleVBhcmFtcyhhbGdvcml0aG0pIHtcbiAgICAgICAgdGhpcy5jaGVja1JlcXVpcmVkUHJvcGVydHkoYWxnb3JpdGhtLCBcIm5hbWVkQ3VydmVcIik7XG4gICAgICAgIHRoaXMuY2hlY2tOYW1lZEN1cnZlKGFsZ29yaXRobS5uYW1lZEN1cnZlKTtcbiAgICB9XG4gICAgY2hlY2tOYW1lZEN1cnZlKG5hbWVkQ3VydmUpIHtcbiAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIHRoaXMubmFtZWRDdXJ2ZXMpIHtcbiAgICAgICAgICAgIGlmIChpdGVtLnRvTG93ZXJDYXNlKCkgPT09IG5hbWVkQ3VydmUudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBuZXcgT3BlcmF0aW9uRXJyb3IoYG5hbWVkQ3VydmU6IE11c3QgYmUgb25lIG9mICR7dGhpcy5uYW1lZEN1cnZlcy5qb2luKFwiLCBcIil9YCk7XG4gICAgfVxufVxuXG5jbGFzcyBFY2RzYVByb3ZpZGVyIGV4dGVuZHMgRWxsaXB0aWNQcm92aWRlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRUNEU0FcIjtcbiAgICAgICAgdGhpcy5oYXNoQWxnb3JpdGhtcyA9IFtcIlNIQS0xXCIsIFwiU0hBLTI1NlwiLCBcIlNIQS0zODRcIiwgXCJTSEEtNTEyXCJdO1xuICAgICAgICB0aGlzLnVzYWdlcyA9IHtcbiAgICAgICAgICAgIHByaXZhdGVLZXk6IFtcInNpZ25cIl0sXG4gICAgICAgICAgICBwdWJsaWNLZXk6IFtcInZlcmlmeVwiXSxcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5uYW1lZEN1cnZlcyA9IFtcIlAtMjU2XCIsIFwiUC0zODRcIiwgXCJQLTUyMVwiLCBcIkstMjU2XCJdO1xuICAgIH1cbiAgICBjaGVja0FsZ29yaXRobVBhcmFtcyhhbGdvcml0aG0pIHtcbiAgICAgICAgdGhpcy5jaGVja1JlcXVpcmVkUHJvcGVydHkoYWxnb3JpdGhtLCBcImhhc2hcIik7XG4gICAgICAgIHRoaXMuY2hlY2tIYXNoQWxnb3JpdGhtKGFsZ29yaXRobS5oYXNoLCB0aGlzLmhhc2hBbGdvcml0aG1zKTtcbiAgICB9XG59XG5cbmNvbnN0IEtFWV9UWVBFUyA9IFtcInNlY3JldFwiLCBcInByaXZhdGVcIiwgXCJwdWJsaWNcIl07XG5jbGFzcyBDcnlwdG9LZXkge1xuICAgIHN0YXRpYyBjcmVhdGUoYWxnb3JpdGhtLCB0eXBlLCBleHRyYWN0YWJsZSwgdXNhZ2VzKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IG5ldyB0aGlzKCk7XG4gICAgICAgIGtleS5hbGdvcml0aG0gPSBhbGdvcml0aG07XG4gICAgICAgIGtleS50eXBlID0gdHlwZTtcbiAgICAgICAga2V5LmV4dHJhY3RhYmxlID0gZXh0cmFjdGFibGU7XG4gICAgICAgIGtleS51c2FnZXMgPSB1c2FnZXM7XG4gICAgICAgIHJldHVybiBrZXk7XG4gICAgfVxuICAgIHN0YXRpYyBpc0tleVR5cGUoZGF0YSkge1xuICAgICAgICByZXR1cm4gS0VZX1RZUEVTLmluZGV4T2YoZGF0YSkgIT09IC0xO1xuICAgIH1cbiAgICBnZXQgW1N5bWJvbC50b1N0cmluZ1RhZ10oKSB7XG4gICAgICAgIHJldHVybiBcIkNyeXB0b0tleVwiO1xuICAgIH1cbn1cblxuY2xhc3MgRWNkaFByb3ZpZGVyIGV4dGVuZHMgRWxsaXB0aWNQcm92aWRlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRUNESFwiO1xuICAgICAgICB0aGlzLnVzYWdlcyA9IHtcbiAgICAgICAgICAgIHByaXZhdGVLZXk6IFtcImRlcml2ZUJpdHNcIiwgXCJkZXJpdmVLZXlcIl0sXG4gICAgICAgICAgICBwdWJsaWNLZXk6IFtdLFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLm5hbWVkQ3VydmVzID0gW1wiUC0yNTZcIiwgXCJQLTM4NFwiLCBcIlAtNTIxXCIsIFwiSy0yNTZcIl07XG4gICAgfVxuICAgIGNoZWNrQWxnb3JpdGhtUGFyYW1zKGFsZ29yaXRobSkge1xuICAgICAgICB0aGlzLmNoZWNrUmVxdWlyZWRQcm9wZXJ0eShhbGdvcml0aG0sIFwicHVibGljXCIpO1xuICAgICAgICBpZiAoIShhbGdvcml0aG0ucHVibGljIGluc3RhbmNlb2YgQ3J5cHRvS2V5KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInB1YmxpYzogSXMgbm90IGEgQ3J5cHRvS2V5XCIpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChhbGdvcml0aG0ucHVibGljLnR5cGUgIT09IFwicHVibGljXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBPcGVyYXRpb25FcnJvcihcInB1YmxpYzogSXMgbm90IGEgcHVibGljIGtleVwiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYWxnb3JpdGhtLnB1YmxpYy5hbGdvcml0aG0ubmFtZSAhPT0gdGhpcy5uYW1lKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgT3BlcmF0aW9uRXJyb3IoYHB1YmxpYzogSXMgbm90ICR7dGhpcy5uYW1lfSBrZXlgKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuY2xhc3MgRWNkaEVzUHJvdmlkZXIgZXh0ZW5kcyBFY2RoUHJvdmlkZXIge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkVDREgtRVNcIjtcbiAgICAgICAgdGhpcy5uYW1lZEN1cnZlcyA9IFtcIlgyNTUxOVwiLCBcIlg0NDhcIl07XG4gICAgfVxufVxuXG5jbGFzcyBFZERzYVByb3ZpZGVyIGV4dGVuZHMgRWxsaXB0aWNQcm92aWRlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRWREU0FcIjtcbiAgICAgICAgdGhpcy51c2FnZXMgPSB7XG4gICAgICAgICAgICBwcml2YXRlS2V5OiBbXCJzaWduXCJdLFxuICAgICAgICAgICAgcHVibGljS2V5OiBbXCJ2ZXJpZnlcIl0sXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMubmFtZWRDdXJ2ZXMgPSBbXCJFZDI1NTE5XCIsIFwiRWQ0NDhcIl07XG4gICAgfVxufVxuXG5sZXQgT2JqZWN0SWRlbnRpZmllciA9IGNsYXNzIE9iamVjdElkZW50aWZpZXIge1xuICAgIGNvbnN0cnVjdG9yKHZhbHVlKSB7XG4gICAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgfVxufTtcbl9fZGVjb3JhdGUoW1xuICAgIEFzblByb3AoeyB0eXBlOiBBc25Qcm9wVHlwZXMuT2JqZWN0SWRlbnRpZmllciB9KVxuXSwgT2JqZWN0SWRlbnRpZmllci5wcm90b3R5cGUsIFwidmFsdWVcIiwgdm9pZCAwKTtcbk9iamVjdElkZW50aWZpZXIgPSBfX2RlY29yYXRlKFtcbiAgICBBc25UeXBlKHsgdHlwZTogQXNuVHlwZVR5cGVzLkNob2ljZSB9KVxuXSwgT2JqZWN0SWRlbnRpZmllcik7XG5cbmNsYXNzIEFsZ29yaXRobUlkZW50aWZpZXIge1xuICAgIGNvbnN0cnVjdG9yKHBhcmFtcykge1xuICAgICAgICBPYmplY3QuYXNzaWduKHRoaXMsIHBhcmFtcyk7XG4gICAgfVxufVxuX19kZWNvcmF0ZShbXG4gICAgQXNuUHJvcCh7XG4gICAgICAgIHR5cGU6IEFzblByb3BUeXBlcy5PYmplY3RJZGVudGlmaWVyLFxuICAgIH0pXG5dLCBBbGdvcml0aG1JZGVudGlmaWVyLnByb3RvdHlwZSwgXCJhbGdvcml0aG1cIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIEFzblByb3Aoe1xuICAgICAgICB0eXBlOiBBc25Qcm9wVHlwZXMuQW55LFxuICAgICAgICBvcHRpb25hbDogdHJ1ZSxcbiAgICB9KVxuXSwgQWxnb3JpdGhtSWRlbnRpZmllci5wcm90b3R5cGUsIFwicGFyYW1ldGVyc1wiLCB2b2lkIDApO1xuXG5jbGFzcyBQcml2YXRlS2V5SW5mbyB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMudmVyc2lvbiA9IDA7XG4gICAgICAgIHRoaXMucHJpdmF0ZUtleUFsZ29yaXRobSA9IG5ldyBBbGdvcml0aG1JZGVudGlmaWVyKCk7XG4gICAgICAgIHRoaXMucHJpdmF0ZUtleSA9IG5ldyBBcnJheUJ1ZmZlcigwKTtcbiAgICB9XG59XG5fX2RlY29yYXRlKFtcbiAgICBBc25Qcm9wKHsgdHlwZTogQXNuUHJvcFR5cGVzLkludGVnZXIgfSlcbl0sIFByaXZhdGVLZXlJbmZvLnByb3RvdHlwZSwgXCJ2ZXJzaW9uXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBBc25Qcm9wKHsgdHlwZTogQWxnb3JpdGhtSWRlbnRpZmllciB9KVxuXSwgUHJpdmF0ZUtleUluZm8ucHJvdG90eXBlLCBcInByaXZhdGVLZXlBbGdvcml0aG1cIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIEFzblByb3AoeyB0eXBlOiBBc25Qcm9wVHlwZXMuT2N0ZXRTdHJpbmcgfSlcbl0sIFByaXZhdGVLZXlJbmZvLnByb3RvdHlwZSwgXCJwcml2YXRlS2V5XCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBBc25Qcm9wKHsgdHlwZTogQXNuUHJvcFR5cGVzLkFueSwgb3B0aW9uYWw6IHRydWUgfSlcbl0sIFByaXZhdGVLZXlJbmZvLnByb3RvdHlwZSwgXCJhdHRyaWJ1dGVzXCIsIHZvaWQgMCk7XG5cbmNsYXNzIFB1YmxpY0tleUluZm8ge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnB1YmxpY0tleUFsZ29yaXRobSA9IG5ldyBBbGdvcml0aG1JZGVudGlmaWVyKCk7XG4gICAgICAgIHRoaXMucHVibGljS2V5ID0gbmV3IEFycmF5QnVmZmVyKDApO1xuICAgIH1cbn1cbl9fZGVjb3JhdGUoW1xuICAgIEFzblByb3AoeyB0eXBlOiBBbGdvcml0aG1JZGVudGlmaWVyIH0pXG5dLCBQdWJsaWNLZXlJbmZvLnByb3RvdHlwZSwgXCJwdWJsaWNLZXlBbGdvcml0aG1cIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIEFzblByb3AoeyB0eXBlOiBBc25Qcm9wVHlwZXMuQml0U3RyaW5nIH0pXG5dLCBQdWJsaWNLZXlJbmZvLnByb3RvdHlwZSwgXCJwdWJsaWNLZXlcIiwgdm9pZCAwKTtcblxuY29uc3QgSnNvbkJhc2U2NFVybEFycmF5QnVmZmVyQ29udmVydGVyID0ge1xuICAgIGZyb21KU09OOiAodmFsdWUpID0+IENvbnZlcnQuRnJvbUJhc2U2NFVybCh2YWx1ZSksXG4gICAgdG9KU09OOiAodmFsdWUpID0+IENvbnZlcnQuVG9CYXNlNjRVcmwobmV3IFVpbnQ4QXJyYXkodmFsdWUpKSxcbn07XG5cbmNvbnN0IEFzbkludGVnZXJBcnJheUJ1ZmZlckNvbnZlcnRlciA9IHtcbiAgICBmcm9tQVNOOiAodmFsdWUpID0+IHtcbiAgICAgICAgY29uc3QgdmFsdWVIZXggPSB2YWx1ZS52YWx1ZUJsb2NrLnZhbHVlSGV4O1xuICAgICAgICByZXR1cm4gIShuZXcgVWludDhBcnJheSh2YWx1ZUhleClbMF0pXG4gICAgICAgICAgICA/IHZhbHVlLnZhbHVlQmxvY2sudmFsdWVIZXguc2xpY2UoMSlcbiAgICAgICAgICAgIDogdmFsdWUudmFsdWVCbG9jay52YWx1ZUhleDtcbiAgICB9LFxuICAgIHRvQVNOOiAodmFsdWUpID0+IHtcbiAgICAgICAgY29uc3QgdmFsdWVIZXggPSBuZXcgVWludDhBcnJheSh2YWx1ZSlbMF0gPiAxMjdcbiAgICAgICAgICAgID8gY29tYmluZShuZXcgVWludDhBcnJheShbMF0pLmJ1ZmZlciwgdmFsdWUpXG4gICAgICAgICAgICA6IHZhbHVlO1xuICAgICAgICByZXR1cm4gbmV3IGFzbjEuSW50ZWdlcih7IHZhbHVlSGV4IH0pO1xuICAgIH0sXG59O1xuXG52YXIgaW5kZXgkMyA9IC8qI19fUFVSRV9fKi9PYmplY3QuZnJlZXplKHtcbiAgX19wcm90b19fOiBudWxsLFxuICBBc25JbnRlZ2VyQXJyYXlCdWZmZXJDb252ZXJ0ZXI6IEFzbkludGVnZXJBcnJheUJ1ZmZlckNvbnZlcnRlcixcbiAgSnNvbkJhc2U2NFVybEFycmF5QnVmZmVyQ29udmVydGVyOiBKc29uQmFzZTY0VXJsQXJyYXlCdWZmZXJDb252ZXJ0ZXJcbn0pO1xuXG5jbGFzcyBSc2FQcml2YXRlS2V5IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy52ZXJzaW9uID0gMDtcbiAgICAgICAgdGhpcy5tb2R1bHVzID0gbmV3IEFycmF5QnVmZmVyKDApO1xuICAgICAgICB0aGlzLnB1YmxpY0V4cG9uZW50ID0gbmV3IEFycmF5QnVmZmVyKDApO1xuICAgICAgICB0aGlzLnByaXZhdGVFeHBvbmVudCA9IG5ldyBBcnJheUJ1ZmZlcigwKTtcbiAgICAgICAgdGhpcy5wcmltZTEgPSBuZXcgQXJyYXlCdWZmZXIoMCk7XG4gICAgICAgIHRoaXMucHJpbWUyID0gbmV3IEFycmF5QnVmZmVyKDApO1xuICAgICAgICB0aGlzLmV4cG9uZW50MSA9IG5ldyBBcnJheUJ1ZmZlcigwKTtcbiAgICAgICAgdGhpcy5leHBvbmVudDIgPSBuZXcgQXJyYXlCdWZmZXIoMCk7XG4gICAgICAgIHRoaXMuY29lZmZpY2llbnQgPSBuZXcgQXJyYXlCdWZmZXIoMCk7XG4gICAgfVxufVxuX19kZWNvcmF0ZShbXG4gICAgQXNuUHJvcCh7IHR5cGU6IEFzblByb3BUeXBlcy5JbnRlZ2VyLCBjb252ZXJ0ZXI6IEFzbkludGVnZXJDb252ZXJ0ZXIgfSlcbl0sIFJzYVByaXZhdGVLZXkucHJvdG90eXBlLCBcInZlcnNpb25cIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIEFzblByb3AoeyB0eXBlOiBBc25Qcm9wVHlwZXMuSW50ZWdlciwgY29udmVydGVyOiBBc25JbnRlZ2VyQXJyYXlCdWZmZXJDb252ZXJ0ZXIgfSksXG4gICAgSnNvblByb3AoeyBuYW1lOiBcIm5cIiwgY29udmVydGVyOiBKc29uQmFzZTY0VXJsQXJyYXlCdWZmZXJDb252ZXJ0ZXIgfSlcbl0sIFJzYVByaXZhdGVLZXkucHJvdG90eXBlLCBcIm1vZHVsdXNcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIEFzblByb3AoeyB0eXBlOiBBc25Qcm9wVHlwZXMuSW50ZWdlciwgY29udmVydGVyOiBBc25JbnRlZ2VyQXJyYXlCdWZmZXJDb252ZXJ0ZXIgfSksXG4gICAgSnNvblByb3AoeyBuYW1lOiBcImVcIiwgY29udmVydGVyOiBKc29uQmFzZTY0VXJsQXJyYXlCdWZmZXJDb252ZXJ0ZXIgfSlcbl0sIFJzYVByaXZhdGVLZXkucHJvdG90eXBlLCBcInB1YmxpY0V4cG9uZW50XCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBBc25Qcm9wKHsgdHlwZTogQXNuUHJvcFR5cGVzLkludGVnZXIsIGNvbnZlcnRlcjogQXNuSW50ZWdlckFycmF5QnVmZmVyQ29udmVydGVyIH0pLFxuICAgIEpzb25Qcm9wKHsgbmFtZTogXCJkXCIsIGNvbnZlcnRlcjogSnNvbkJhc2U2NFVybEFycmF5QnVmZmVyQ29udmVydGVyIH0pXG5dLCBSc2FQcml2YXRlS2V5LnByb3RvdHlwZSwgXCJwcml2YXRlRXhwb25lbnRcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIEFzblByb3AoeyB0eXBlOiBBc25Qcm9wVHlwZXMuSW50ZWdlciwgY29udmVydGVyOiBBc25JbnRlZ2VyQXJyYXlCdWZmZXJDb252ZXJ0ZXIgfSksXG4gICAgSnNvblByb3AoeyBuYW1lOiBcInBcIiwgY29udmVydGVyOiBKc29uQmFzZTY0VXJsQXJyYXlCdWZmZXJDb252ZXJ0ZXIgfSlcbl0sIFJzYVByaXZhdGVLZXkucHJvdG90eXBlLCBcInByaW1lMVwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgQXNuUHJvcCh7IHR5cGU6IEFzblByb3BUeXBlcy5JbnRlZ2VyLCBjb252ZXJ0ZXI6IEFzbkludGVnZXJBcnJheUJ1ZmZlckNvbnZlcnRlciB9KSxcbiAgICBKc29uUHJvcCh7IG5hbWU6IFwicVwiLCBjb252ZXJ0ZXI6IEpzb25CYXNlNjRVcmxBcnJheUJ1ZmZlckNvbnZlcnRlciB9KVxuXSwgUnNhUHJpdmF0ZUtleS5wcm90b3R5cGUsIFwicHJpbWUyXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBBc25Qcm9wKHsgdHlwZTogQXNuUHJvcFR5cGVzLkludGVnZXIsIGNvbnZlcnRlcjogQXNuSW50ZWdlckFycmF5QnVmZmVyQ29udmVydGVyIH0pLFxuICAgIEpzb25Qcm9wKHsgbmFtZTogXCJkcFwiLCBjb252ZXJ0ZXI6IEpzb25CYXNlNjRVcmxBcnJheUJ1ZmZlckNvbnZlcnRlciB9KVxuXSwgUnNhUHJpdmF0ZUtleS5wcm90b3R5cGUsIFwiZXhwb25lbnQxXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBBc25Qcm9wKHsgdHlwZTogQXNuUHJvcFR5cGVzLkludGVnZXIsIGNvbnZlcnRlcjogQXNuSW50ZWdlckFycmF5QnVmZmVyQ29udmVydGVyIH0pLFxuICAgIEpzb25Qcm9wKHsgbmFtZTogXCJkcVwiLCBjb252ZXJ0ZXI6IEpzb25CYXNlNjRVcmxBcnJheUJ1ZmZlckNvbnZlcnRlciB9KVxuXSwgUnNhUHJpdmF0ZUtleS5wcm90b3R5cGUsIFwiZXhwb25lbnQyXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBBc25Qcm9wKHsgdHlwZTogQXNuUHJvcFR5cGVzLkludGVnZXIsIGNvbnZlcnRlcjogQXNuSW50ZWdlckFycmF5QnVmZmVyQ29udmVydGVyIH0pLFxuICAgIEpzb25Qcm9wKHsgbmFtZTogXCJxaVwiLCBjb252ZXJ0ZXI6IEpzb25CYXNlNjRVcmxBcnJheUJ1ZmZlckNvbnZlcnRlciB9KVxuXSwgUnNhUHJpdmF0ZUtleS5wcm90b3R5cGUsIFwiY29lZmZpY2llbnRcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIEFzblByb3AoeyB0eXBlOiBBc25Qcm9wVHlwZXMuQW55LCBvcHRpb25hbDogdHJ1ZSB9KVxuXSwgUnNhUHJpdmF0ZUtleS5wcm90b3R5cGUsIFwib3RoZXJQcmltZUluZm9zXCIsIHZvaWQgMCk7XG5cbmNsYXNzIFJzYVB1YmxpY0tleSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMubW9kdWx1cyA9IG5ldyBBcnJheUJ1ZmZlcigwKTtcbiAgICAgICAgdGhpcy5wdWJsaWNFeHBvbmVudCA9IG5ldyBBcnJheUJ1ZmZlcigwKTtcbiAgICB9XG59XG5fX2RlY29yYXRlKFtcbiAgICBBc25Qcm9wKHsgdHlwZTogQXNuUHJvcFR5cGVzLkludGVnZXIsIGNvbnZlcnRlcjogQXNuSW50ZWdlckFycmF5QnVmZmVyQ29udmVydGVyIH0pLFxuICAgIEpzb25Qcm9wKHsgbmFtZTogXCJuXCIsIGNvbnZlcnRlcjogSnNvbkJhc2U2NFVybEFycmF5QnVmZmVyQ29udmVydGVyIH0pXG5dLCBSc2FQdWJsaWNLZXkucHJvdG90eXBlLCBcIm1vZHVsdXNcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIEFzblByb3AoeyB0eXBlOiBBc25Qcm9wVHlwZXMuSW50ZWdlciwgY29udmVydGVyOiBBc25JbnRlZ2VyQXJyYXlCdWZmZXJDb252ZXJ0ZXIgfSksXG4gICAgSnNvblByb3AoeyBuYW1lOiBcImVcIiwgY29udmVydGVyOiBKc29uQmFzZTY0VXJsQXJyYXlCdWZmZXJDb252ZXJ0ZXIgfSlcbl0sIFJzYVB1YmxpY0tleS5wcm90b3R5cGUsIFwicHVibGljRXhwb25lbnRcIiwgdm9pZCAwKTtcblxubGV0IEVjUHVibGljS2V5ID0gY2xhc3MgRWNQdWJsaWNLZXkge1xuICAgIGNvbnN0cnVjdG9yKHZhbHVlKSB7XG4gICAgICAgIHRoaXMudmFsdWUgPSBuZXcgQXJyYXlCdWZmZXIoMCk7XG4gICAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHRvSlNPTigpIHtcbiAgICAgICAgbGV0IGJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkodGhpcy52YWx1ZSk7XG4gICAgICAgIGlmIChieXRlc1swXSAhPT0gMHgwNCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IENyeXB0b0Vycm9yKFwiV3JvbmcgRUNQb2ludC4gQ3VycmVudCB2ZXJzaW9uIHN1cHBvcnRzIG9ubHkgVW5jb21wcmVzc2VkICgweDA0KSBwb2ludFwiKTtcbiAgICAgICAgfVxuICAgICAgICBieXRlcyA9IG5ldyBVaW50OEFycmF5KHRoaXMudmFsdWUuc2xpY2UoMSkpO1xuICAgICAgICBjb25zdCBzaXplID0gYnl0ZXMubGVuZ3RoIC8gMjtcbiAgICAgICAgY29uc3Qgb2Zmc2V0ID0gMDtcbiAgICAgICAgY29uc3QganNvbiA9IHtcbiAgICAgICAgICAgIHg6IENvbnZlcnQuVG9CYXNlNjRVcmwoYnl0ZXMuYnVmZmVyLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgc2l6ZSkpLFxuICAgICAgICAgICAgeTogQ29udmVydC5Ub0Jhc2U2NFVybChieXRlcy5idWZmZXIuc2xpY2Uob2Zmc2V0ICsgc2l6ZSwgb2Zmc2V0ICsgc2l6ZSArIHNpemUpKSxcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIGpzb247XG4gICAgfVxuICAgIGZyb21KU09OKGpzb24pIHtcbiAgICAgICAgaWYgKCEoXCJ4XCIgaW4ganNvbikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIng6IE1pc3NpbmcgcmVxdWlyZWQgcHJvcGVydHlcIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEoXCJ5XCIgaW4ganNvbikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInk6IE1pc3NpbmcgcmVxdWlyZWQgcHJvcGVydHlcIik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgeCA9IENvbnZlcnQuRnJvbUJhc2U2NFVybChqc29uLngpO1xuICAgICAgICBjb25zdCB5ID0gQ29udmVydC5Gcm9tQmFzZTY0VXJsKGpzb24ueSk7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gY29tYmluZShuZXcgVWludDhBcnJheShbMHgwNF0pLmJ1ZmZlciwgeCwgeSk7XG4gICAgICAgIHRoaXMudmFsdWUgPSBuZXcgVWludDhBcnJheSh2YWx1ZSkuYnVmZmVyO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59O1xuX19kZWNvcmF0ZShbXG4gICAgQXNuUHJvcCh7IHR5cGU6IEFzblByb3BUeXBlcy5PY3RldFN0cmluZyB9KVxuXSwgRWNQdWJsaWNLZXkucHJvdG90eXBlLCBcInZhbHVlXCIsIHZvaWQgMCk7XG5FY1B1YmxpY0tleSA9IF9fZGVjb3JhdGUoW1xuICAgIEFzblR5cGUoeyB0eXBlOiBBc25UeXBlVHlwZXMuQ2hvaWNlIH0pXG5dLCBFY1B1YmxpY0tleSk7XG5cbmNsYXNzIEVjUHJpdmF0ZUtleSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMudmVyc2lvbiA9IDE7XG4gICAgICAgIHRoaXMucHJpdmF0ZUtleSA9IG5ldyBBcnJheUJ1ZmZlcigwKTtcbiAgICB9XG4gICAgZnJvbUpTT04oanNvbikge1xuICAgICAgICBpZiAoIShcImRcIiBpbiBqc29uKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiZDogTWlzc2luZyByZXF1aXJlZCBwcm9wZXJ0eVwiKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnByaXZhdGVLZXkgPSBDb252ZXJ0LkZyb21CYXNlNjRVcmwoanNvbi5kKTtcbiAgICAgICAgaWYgKFwieFwiIGluIGpzb24pIHtcbiAgICAgICAgICAgIGNvbnN0IHB1YmxpY0tleSA9IG5ldyBFY1B1YmxpY0tleSgpO1xuICAgICAgICAgICAgcHVibGljS2V5LmZyb21KU09OKGpzb24pO1xuICAgICAgICAgICAgY29uc3QgYXNuID0gQXNuU2VyaWFsaXplci50b0FTTihwdWJsaWNLZXkpO1xuICAgICAgICAgICAgaWYgKFwidmFsdWVIZXhcIiBpbiBhc24udmFsdWVCbG9jaykge1xuICAgICAgICAgICAgICAgIHRoaXMucHVibGljS2V5ID0gYXNuLnZhbHVlQmxvY2sudmFsdWVIZXg7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHRvSlNPTigpIHtcbiAgICAgICAgY29uc3QgandrID0ge307XG4gICAgICAgIGp3ay5kID0gQ29udmVydC5Ub0Jhc2U2NFVybCh0aGlzLnByaXZhdGVLZXkpO1xuICAgICAgICBpZiAodGhpcy5wdWJsaWNLZXkpIHtcbiAgICAgICAgICAgIE9iamVjdC5hc3NpZ24oandrLCBuZXcgRWNQdWJsaWNLZXkodGhpcy5wdWJsaWNLZXkpLnRvSlNPTigpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gandrO1xuICAgIH1cbn1cbl9fZGVjb3JhdGUoW1xuICAgIEFzblByb3AoeyB0eXBlOiBBc25Qcm9wVHlwZXMuSW50ZWdlciwgY29udmVydGVyOiBBc25JbnRlZ2VyQ29udmVydGVyIH0pXG5dLCBFY1ByaXZhdGVLZXkucHJvdG90eXBlLCBcInZlcnNpb25cIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIEFzblByb3AoeyB0eXBlOiBBc25Qcm9wVHlwZXMuT2N0ZXRTdHJpbmcgfSlcbl0sIEVjUHJpdmF0ZUtleS5wcm90b3R5cGUsIFwicHJpdmF0ZUtleVwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgQXNuUHJvcCh7IGNvbnRleHQ6IDAsIHR5cGU6IEFzblByb3BUeXBlcy5BbnksIG9wdGlvbmFsOiB0cnVlIH0pXG5dLCBFY1ByaXZhdGVLZXkucHJvdG90eXBlLCBcInBhcmFtZXRlcnNcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIEFzblByb3AoeyBjb250ZXh0OiAxLCB0eXBlOiBBc25Qcm9wVHlwZXMuQml0U3RyaW5nLCBvcHRpb25hbDogdHJ1ZSB9KVxuXSwgRWNQcml2YXRlS2V5LnByb3RvdHlwZSwgXCJwdWJsaWNLZXlcIiwgdm9pZCAwKTtcblxuY29uc3QgQXNuSW50ZWdlcldpdGhvdXRQYWRkaW5nQ29udmVydGVyID0ge1xuICAgIGZyb21BU046ICh2YWx1ZSkgPT4ge1xuICAgICAgICBjb25zdCBieXRlcyA9IG5ldyBVaW50OEFycmF5KHZhbHVlLnZhbHVlQmxvY2sudmFsdWVIZXgpO1xuICAgICAgICByZXR1cm4gKGJ5dGVzWzBdID09PSAwKVxuICAgICAgICAgICAgPyBieXRlcy5idWZmZXIuc2xpY2UoMSlcbiAgICAgICAgICAgIDogYnl0ZXMuYnVmZmVyO1xuICAgIH0sXG4gICAgdG9BU046ICh2YWx1ZSkgPT4ge1xuICAgICAgICBjb25zdCBieXRlcyA9IG5ldyBVaW50OEFycmF5KHZhbHVlKTtcbiAgICAgICAgaWYgKGJ5dGVzWzBdID4gMTI3KSB7XG4gICAgICAgICAgICBjb25zdCBuZXdWYWx1ZSA9IG5ldyBVaW50OEFycmF5KGJ5dGVzLmxlbmd0aCArIDEpO1xuICAgICAgICAgICAgbmV3VmFsdWUuc2V0KGJ5dGVzLCAxKTtcbiAgICAgICAgICAgIHJldHVybiBuZXcgYXNuMS5JbnRlZ2VyKHsgdmFsdWVIZXg6IG5ld1ZhbHVlLmJ1ZmZlciB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IGFzbjEuSW50ZWdlcih7IHZhbHVlSGV4OiB2YWx1ZSB9KTtcbiAgICB9LFxufTtcblxudmFyIGluZGV4JDIgPSAvKiNfX1BVUkVfXyovT2JqZWN0LmZyZWV6ZSh7XG4gIF9fcHJvdG9fXzogbnVsbCxcbiAgQXNuSW50ZWdlcldpdGhvdXRQYWRkaW5nQ29udmVydGVyOiBBc25JbnRlZ2VyV2l0aG91dFBhZGRpbmdDb252ZXJ0ZXJcbn0pO1xuXG5jbGFzcyBFY1V0aWxzIHtcbiAgICBzdGF0aWMgZGVjb2RlUG9pbnQoZGF0YSwgcG9pbnRTaXplKSB7XG4gICAgICAgIGNvbnN0IHZpZXcgPSBCdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9VaW50OEFycmF5KGRhdGEpO1xuICAgICAgICBpZiAoKHZpZXcubGVuZ3RoID09PSAwKSB8fCAodmlld1swXSAhPT0gNCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIk9ubHkgdW5jb21wcmVzc2VkIHBvaW50IGZvcm1hdCBzdXBwb3J0ZWRcIik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbiA9ICh2aWV3Lmxlbmd0aCAtIDEpIC8gMjtcbiAgICAgICAgaWYgKG4gIT09IChNYXRoLmNlaWwocG9pbnRTaXplIC8gOCkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJQb2ludCBkb2VzIG5vdCBtYXRjaCBmaWVsZCBzaXplXCIpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHhiID0gdmlldy5zbGljZSgxLCBuICsgMSk7XG4gICAgICAgIGNvbnN0IHliID0gdmlldy5zbGljZShuICsgMSwgbiArIDEgKyBuKTtcbiAgICAgICAgcmV0dXJuIHsgeDogeGIsIHk6IHliIH07XG4gICAgfVxuICAgIHN0YXRpYyBlbmNvZGVQb2ludChwb2ludCwgcG9pbnRTaXplKSB7XG4gICAgICAgIGNvbnN0IHNpemUgPSBNYXRoLmNlaWwocG9pbnRTaXplIC8gOCk7XG4gICAgICAgIGlmIChwb2ludC54LmJ5dGVMZW5ndGggIT09IHNpemUgfHwgcG9pbnQueS5ieXRlTGVuZ3RoICE9PSBzaXplKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJYLFkgY29vcmRpbmF0ZXMgZG9uJ3QgbWF0Y2ggcG9pbnQgc2l6ZSBjcml0ZXJpYVwiKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB4ID0gQnVmZmVyU291cmNlQ29udmVydGVyLnRvVWludDhBcnJheShwb2ludC54KTtcbiAgICAgICAgY29uc3QgeSA9IEJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b1VpbnQ4QXJyYXkocG9pbnQueSk7XG4gICAgICAgIGNvbnN0IHJlcyA9IG5ldyBVaW50OEFycmF5KHNpemUgKiAyICsgMSk7XG4gICAgICAgIHJlc1swXSA9IDQ7XG4gICAgICAgIHJlcy5zZXQoeCwgMSk7XG4gICAgICAgIHJlcy5zZXQoeSwgc2l6ZSArIDEpO1xuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0U2l6ZShwb2ludFNpemUpIHtcbiAgICAgICAgcmV0dXJuIE1hdGguY2VpbChwb2ludFNpemUgLyA4KTtcbiAgICB9XG4gICAgc3RhdGljIGVuY29kZVNpZ25hdHVyZShzaWduYXR1cmUsIHBvaW50U2l6ZSkge1xuICAgICAgICBjb25zdCBzaXplID0gdGhpcy5nZXRTaXplKHBvaW50U2l6ZSk7XG4gICAgICAgIGNvbnN0IHIgPSBCdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9VaW50OEFycmF5KHNpZ25hdHVyZS5yKTtcbiAgICAgICAgY29uc3QgcyA9IEJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b1VpbnQ4QXJyYXkoc2lnbmF0dXJlLnMpO1xuICAgICAgICBjb25zdCByZXMgPSBuZXcgVWludDhBcnJheShzaXplICogMik7XG4gICAgICAgIHJlcy5zZXQodGhpcy5wYWRTdGFydChyLCBzaXplKSk7XG4gICAgICAgIHJlcy5zZXQodGhpcy5wYWRTdGFydChzLCBzaXplKSwgc2l6ZSk7XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxuICAgIHN0YXRpYyBkZWNvZGVTaWduYXR1cmUoZGF0YSwgcG9pbnRTaXplKSB7XG4gICAgICAgIGNvbnN0IHNpemUgPSB0aGlzLmdldFNpemUocG9pbnRTaXplKTtcbiAgICAgICAgY29uc3QgdmlldyA9IEJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b1VpbnQ4QXJyYXkoZGF0YSk7XG4gICAgICAgIGlmICh2aWV3Lmxlbmd0aCAhPT0gKHNpemUgKiAyKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW5jb3JyZWN0IHNpemUgb2YgdGhlIHNpZ25hdHVyZVwiKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCByID0gdmlldy5zbGljZSgwLCBzaXplKTtcbiAgICAgICAgY29uc3QgcyA9IHZpZXcuc2xpY2Uoc2l6ZSk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByOiB0aGlzLnRyaW1TdGFydChyKSxcbiAgICAgICAgICAgIHM6IHRoaXMudHJpbVN0YXJ0KHMpLFxuICAgICAgICB9O1xuICAgIH1cbiAgICBzdGF0aWMgdHJpbVN0YXJ0KGRhdGEpIHtcbiAgICAgICAgbGV0IGkgPSAwO1xuICAgICAgICB3aGlsZSAoKGkgPCBkYXRhLmxlbmd0aCAtIDEpICYmIChkYXRhW2ldID09PSAwKSkge1xuICAgICAgICAgICAgaSsrO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gZGF0YTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGF0YS5zbGljZShpLCBkYXRhLmxlbmd0aCk7XG4gICAgfVxuICAgIHN0YXRpYyBwYWRTdGFydChkYXRhLCBzaXplKSB7XG4gICAgICAgIGlmIChzaXplID09PSBkYXRhLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVzID0gbmV3IFVpbnQ4QXJyYXkoc2l6ZSk7XG4gICAgICAgIHJlcy5zZXQoZGF0YSwgc2l6ZSAtIGRhdGEubGVuZ3RoKTtcbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG59XG5cbmNsYXNzIEVjRHNhU2lnbmF0dXJlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5yID0gbmV3IEFycmF5QnVmZmVyKDApO1xuICAgICAgICB0aGlzLnMgPSBuZXcgQXJyYXlCdWZmZXIoMCk7XG4gICAgfVxuICAgIHN0YXRpYyBmcm9tV2ViQ3J5cHRvU2lnbmF0dXJlKHZhbHVlKSB7XG4gICAgICAgIGNvbnN0IHBvaW50U2l6ZSA9IHZhbHVlLmJ5dGVMZW5ndGggLyAyO1xuICAgICAgICBjb25zdCBwb2ludCA9IEVjVXRpbHMuZGVjb2RlU2lnbmF0dXJlKHZhbHVlLCBwb2ludFNpemUgKiA4KTtcbiAgICAgICAgY29uc3QgZWNTaWduYXR1cmUgPSBuZXcgRWNEc2FTaWduYXR1cmUoKTtcbiAgICAgICAgZWNTaWduYXR1cmUuciA9IEJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b0FycmF5QnVmZmVyKHBvaW50LnIpO1xuICAgICAgICBlY1NpZ25hdHVyZS5zID0gQnVmZmVyU291cmNlQ29udmVydGVyLnRvQXJyYXlCdWZmZXIocG9pbnQucyk7XG4gICAgICAgIHJldHVybiBlY1NpZ25hdHVyZTtcbiAgICB9XG4gICAgdG9XZWJDcnlwdG9TaWduYXR1cmUocG9pbnRTaXplKSB7XG4gICAgICAgIHBvaW50U2l6ZSAhPT0gbnVsbCAmJiBwb2ludFNpemUgIT09IHZvaWQgMCA/IHBvaW50U2l6ZSA6IChwb2ludFNpemUgPSBNYXRoLm1heCh0aGlzLnIuYnl0ZUxlbmd0aCwgdGhpcy5zLmJ5dGVMZW5ndGgpICogOCk7XG4gICAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IEVjVXRpbHMuZW5jb2RlU2lnbmF0dXJlKHRoaXMsIHBvaW50U2l6ZSk7XG4gICAgICAgIHJldHVybiBzaWduYXR1cmUuYnVmZmVyO1xuICAgIH1cbn1cbl9fZGVjb3JhdGUoW1xuICAgIEFzblByb3AoeyB0eXBlOiBBc25Qcm9wVHlwZXMuSW50ZWdlciwgY29udmVydGVyOiBBc25JbnRlZ2VyV2l0aG91dFBhZGRpbmdDb252ZXJ0ZXIgfSlcbl0sIEVjRHNhU2lnbmF0dXJlLnByb3RvdHlwZSwgXCJyXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBBc25Qcm9wKHsgdHlwZTogQXNuUHJvcFR5cGVzLkludGVnZXIsIGNvbnZlcnRlcjogQXNuSW50ZWdlcldpdGhvdXRQYWRkaW5nQ29udmVydGVyIH0pXG5dLCBFY0RzYVNpZ25hdHVyZS5wcm90b3R5cGUsIFwic1wiLCB2b2lkIDApO1xuXG5jbGFzcyBPbmVBc3ltbWV0cmljS2V5IGV4dGVuZHMgUHJpdmF0ZUtleUluZm8ge1xufVxuX19kZWNvcmF0ZShbXG4gICAgQXNuUHJvcCh7IGNvbnRleHQ6IDEsIGltcGxpY2l0OiB0cnVlLCB0eXBlOiBBc25Qcm9wVHlwZXMuQml0U3RyaW5nLCBvcHRpb25hbDogdHJ1ZSB9KVxuXSwgT25lQXN5bW1ldHJpY0tleS5wcm90b3R5cGUsIFwicHVibGljS2V5XCIsIHZvaWQgMCk7XG5cbmxldCBFZFByaXZhdGVLZXkgPSBjbGFzcyBFZFByaXZhdGVLZXkge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnZhbHVlID0gbmV3IEFycmF5QnVmZmVyKDApO1xuICAgIH1cbiAgICBmcm9tSlNPTihqc29uKSB7XG4gICAgICAgIGlmICghanNvbi5kKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJkOiBNaXNzaW5nIHJlcXVpcmVkIHByb3BlcnR5XCIpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudmFsdWUgPSBDb252ZXJ0LkZyb21CYXNlNjRVcmwoanNvbi5kKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHRvSlNPTigpIHtcbiAgICAgICAgY29uc3QgandrID0ge1xuICAgICAgICAgICAgZDogQ29udmVydC5Ub0Jhc2U2NFVybCh0aGlzLnZhbHVlKSxcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIGp3aztcbiAgICB9XG59O1xuX19kZWNvcmF0ZShbXG4gICAgQXNuUHJvcCh7IHR5cGU6IEFzblByb3BUeXBlcy5PY3RldFN0cmluZyB9KVxuXSwgRWRQcml2YXRlS2V5LnByb3RvdHlwZSwgXCJ2YWx1ZVwiLCB2b2lkIDApO1xuRWRQcml2YXRlS2V5ID0gX19kZWNvcmF0ZShbXG4gICAgQXNuVHlwZSh7IHR5cGU6IEFzblR5cGVUeXBlcy5DaG9pY2UgfSlcbl0sIEVkUHJpdmF0ZUtleSk7XG5cbmxldCBFZFB1YmxpY0tleSA9IGNsYXNzIEVkUHVibGljS2V5IHtcbiAgICBjb25zdHJ1Y3Rvcih2YWx1ZSkge1xuICAgICAgICB0aGlzLnZhbHVlID0gbmV3IEFycmF5QnVmZmVyKDApO1xuICAgICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICB0b0pTT04oKSB7XG4gICAgICAgIGNvbnN0IGpzb24gPSB7XG4gICAgICAgICAgICB4OiBDb252ZXJ0LlRvQmFzZTY0VXJsKHRoaXMudmFsdWUpLFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ganNvbjtcbiAgICB9XG4gICAgZnJvbUpTT04oanNvbikge1xuICAgICAgICBpZiAoIShcInhcIiBpbiBqc29uKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwieDogTWlzc2luZyByZXF1aXJlZCBwcm9wZXJ0eVwiKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnZhbHVlID0gQ29udmVydC5Gcm9tQmFzZTY0VXJsKGpzb24ueCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn07XG5fX2RlY29yYXRlKFtcbiAgICBBc25Qcm9wKHsgdHlwZTogQXNuUHJvcFR5cGVzLkJpdFN0cmluZyB9KVxuXSwgRWRQdWJsaWNLZXkucHJvdG90eXBlLCBcInZhbHVlXCIsIHZvaWQgMCk7XG5FZFB1YmxpY0tleSA9IF9fZGVjb3JhdGUoW1xuICAgIEFzblR5cGUoeyB0eXBlOiBBc25UeXBlVHlwZXMuQ2hvaWNlIH0pXG5dLCBFZFB1YmxpY0tleSk7XG5cbmxldCBDdXJ2ZVByaXZhdGVLZXkgPSBjbGFzcyBDdXJ2ZVByaXZhdGVLZXkge1xufTtcbl9fZGVjb3JhdGUoW1xuICAgIEFzblByb3AoeyB0eXBlOiBBc25Qcm9wVHlwZXMuT2N0ZXRTdHJpbmcgfSksXG4gICAgSnNvblByb3AoeyB0eXBlOiBKc29uUHJvcFR5cGVzLlN0cmluZywgY29udmVydGVyOiBKc29uQmFzZTY0VXJsQXJyYXlCdWZmZXJDb252ZXJ0ZXIgfSlcbl0sIEN1cnZlUHJpdmF0ZUtleS5wcm90b3R5cGUsIFwiZFwiLCB2b2lkIDApO1xuQ3VydmVQcml2YXRlS2V5ID0gX19kZWNvcmF0ZShbXG4gICAgQXNuVHlwZSh7IHR5cGU6IEFzblR5cGVUeXBlcy5DaG9pY2UgfSlcbl0sIEN1cnZlUHJpdmF0ZUtleSk7XG5cbmNvbnN0IGlkU2VjcDI1NnIxID0gXCIxLjIuODQwLjEwMDQ1LjMuMS43XCI7XG5jb25zdCBpZEVsbGlwdGljQ3VydmUgPSBcIjEuMy4xMzIuMFwiO1xuY29uc3QgaWRTZWNwMzg0cjEgPSBgJHtpZEVsbGlwdGljQ3VydmV9LjM0YDtcbmNvbnN0IGlkU2VjcDUyMXIxID0gYCR7aWRFbGxpcHRpY0N1cnZlfS4zNWA7XG5jb25zdCBpZFNlY3AyNTZrMSA9IGAke2lkRWxsaXB0aWNDdXJ2ZX0uMTBgO1xuY29uc3QgaWRWZXJzaW9uT25lID0gXCIxLjMuMzYuMy4zLjIuOC4xLjFcIjtcbmNvbnN0IGlkQnJhaW5wb29sUDE2MHIxID0gYCR7aWRWZXJzaW9uT25lfS4xYDtcbmNvbnN0IGlkQnJhaW5wb29sUDE2MHQxID0gYCR7aWRWZXJzaW9uT25lfS4yYDtcbmNvbnN0IGlkQnJhaW5wb29sUDE5MnIxID0gYCR7aWRWZXJzaW9uT25lfS4zYDtcbmNvbnN0IGlkQnJhaW5wb29sUDE5MnQxID0gYCR7aWRWZXJzaW9uT25lfS40YDtcbmNvbnN0IGlkQnJhaW5wb29sUDIyNHIxID0gYCR7aWRWZXJzaW9uT25lfS41YDtcbmNvbnN0IGlkQnJhaW5wb29sUDIyNHQxID0gYCR7aWRWZXJzaW9uT25lfS42YDtcbmNvbnN0IGlkQnJhaW5wb29sUDI1NnIxID0gYCR7aWRWZXJzaW9uT25lfS43YDtcbmNvbnN0IGlkQnJhaW5wb29sUDI1NnQxID0gYCR7aWRWZXJzaW9uT25lfS44YDtcbmNvbnN0IGlkQnJhaW5wb29sUDMyMHIxID0gYCR7aWRWZXJzaW9uT25lfS45YDtcbmNvbnN0IGlkQnJhaW5wb29sUDMyMHQxID0gYCR7aWRWZXJzaW9uT25lfS4xMGA7XG5jb25zdCBpZEJyYWlucG9vbFAzODRyMSA9IGAke2lkVmVyc2lvbk9uZX0uMTFgO1xuY29uc3QgaWRCcmFpbnBvb2xQMzg0dDEgPSBgJHtpZFZlcnNpb25PbmV9LjEyYDtcbmNvbnN0IGlkQnJhaW5wb29sUDUxMnIxID0gYCR7aWRWZXJzaW9uT25lfS4xM2A7XG5jb25zdCBpZEJyYWlucG9vbFA1MTJ0MSA9IGAke2lkVmVyc2lvbk9uZX0uMTRgO1xuY29uc3QgaWRYMjU1MTkgPSBcIjEuMy4xMDEuMTEwXCI7XG5jb25zdCBpZFg0NDggPSBcIjEuMy4xMDEuMTExXCI7XG5jb25zdCBpZEVkMjU1MTkgPSBcIjEuMy4xMDEuMTEyXCI7XG5jb25zdCBpZEVkNDQ4ID0gXCIxLjMuMTAxLjExM1wiO1xuXG52YXIgaW5kZXgkMSA9IC8qI19fUFVSRV9fKi9PYmplY3QuZnJlZXplKHtcbiAgX19wcm90b19fOiBudWxsLFxuICBBbGdvcml0aG1JZGVudGlmaWVyOiBBbGdvcml0aG1JZGVudGlmaWVyLFxuICBnZXQgQ3VydmVQcml2YXRlS2V5ICgpIHsgcmV0dXJuIEN1cnZlUHJpdmF0ZUtleTsgfSxcbiAgRWNEc2FTaWduYXR1cmU6IEVjRHNhU2lnbmF0dXJlLFxuICBFY1ByaXZhdGVLZXk6IEVjUHJpdmF0ZUtleSxcbiAgZ2V0IEVjUHVibGljS2V5ICgpIHsgcmV0dXJuIEVjUHVibGljS2V5OyB9LFxuICBnZXQgRWRQcml2YXRlS2V5ICgpIHsgcmV0dXJuIEVkUHJpdmF0ZUtleTsgfSxcbiAgZ2V0IEVkUHVibGljS2V5ICgpIHsgcmV0dXJuIEVkUHVibGljS2V5OyB9LFxuICBnZXQgT2JqZWN0SWRlbnRpZmllciAoKSB7IHJldHVybiBPYmplY3RJZGVudGlmaWVyOyB9LFxuICBPbmVBc3ltbWV0cmljS2V5OiBPbmVBc3ltbWV0cmljS2V5LFxuICBQcml2YXRlS2V5SW5mbzogUHJpdmF0ZUtleUluZm8sXG4gIFB1YmxpY0tleUluZm86IFB1YmxpY0tleUluZm8sXG4gIFJzYVByaXZhdGVLZXk6IFJzYVByaXZhdGVLZXksXG4gIFJzYVB1YmxpY0tleTogUnNhUHVibGljS2V5LFxuICBjb252ZXJ0ZXJzOiBpbmRleCQyLFxuICBpZEJyYWlucG9vbFAxNjByMTogaWRCcmFpbnBvb2xQMTYwcjEsXG4gIGlkQnJhaW5wb29sUDE2MHQxOiBpZEJyYWlucG9vbFAxNjB0MSxcbiAgaWRCcmFpbnBvb2xQMTkycjE6IGlkQnJhaW5wb29sUDE5MnIxLFxuICBpZEJyYWlucG9vbFAxOTJ0MTogaWRCcmFpbnBvb2xQMTkydDEsXG4gIGlkQnJhaW5wb29sUDIyNHIxOiBpZEJyYWlucG9vbFAyMjRyMSxcbiAgaWRCcmFpbnBvb2xQMjI0dDE6IGlkQnJhaW5wb29sUDIyNHQxLFxuICBpZEJyYWlucG9vbFAyNTZyMTogaWRCcmFpbnBvb2xQMjU2cjEsXG4gIGlkQnJhaW5wb29sUDI1NnQxOiBpZEJyYWlucG9vbFAyNTZ0MSxcbiAgaWRCcmFpbnBvb2xQMzIwcjE6IGlkQnJhaW5wb29sUDMyMHIxLFxuICBpZEJyYWlucG9vbFAzMjB0MTogaWRCcmFpbnBvb2xQMzIwdDEsXG4gIGlkQnJhaW5wb29sUDM4NHIxOiBpZEJyYWlucG9vbFAzODRyMSxcbiAgaWRCcmFpbnBvb2xQMzg0dDE6IGlkQnJhaW5wb29sUDM4NHQxLFxuICBpZEJyYWlucG9vbFA1MTJyMTogaWRCcmFpbnBvb2xQNTEycjEsXG4gIGlkQnJhaW5wb29sUDUxMnQxOiBpZEJyYWlucG9vbFA1MTJ0MSxcbiAgaWRFZDI1NTE5OiBpZEVkMjU1MTksXG4gIGlkRWQ0NDg6IGlkRWQ0NDgsXG4gIGlkRWxsaXB0aWNDdXJ2ZTogaWRFbGxpcHRpY0N1cnZlLFxuICBpZFNlY3AyNTZrMTogaWRTZWNwMjU2azEsXG4gIGlkU2VjcDI1NnIxOiBpZFNlY3AyNTZyMSxcbiAgaWRTZWNwMzg0cjE6IGlkU2VjcDM4NHIxLFxuICBpZFNlY3A1MjFyMTogaWRTZWNwNTIxcjEsXG4gIGlkVmVyc2lvbk9uZTogaWRWZXJzaW9uT25lLFxuICBpZFgyNTUxOTogaWRYMjU1MTksXG4gIGlkWDQ0ODogaWRYNDQ4XG59KTtcblxuY2xhc3MgRWNDdXJ2ZXMge1xuICAgIGNvbnN0cnVjdG9yKCkgeyB9XG4gICAgc3RhdGljIHJlZ2lzdGVyKGl0ZW0pIHtcbiAgICAgICAgY29uc3Qgb2lkID0gbmV3IE9iamVjdElkZW50aWZpZXIoKTtcbiAgICAgICAgb2lkLnZhbHVlID0gaXRlbS5pZDtcbiAgICAgICAgY29uc3QgcmF3ID0gQXNuQ29udmVydC5zZXJpYWxpemUob2lkKTtcbiAgICAgICAgdGhpcy5pdGVtcy5wdXNoKHtcbiAgICAgICAgICAgIC4uLml0ZW0sXG4gICAgICAgICAgICByYXcsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm5hbWVzLnB1c2goaXRlbS5uYW1lKTtcbiAgICB9XG4gICAgc3RhdGljIGZpbmQobmFtZU9ySWQpIHtcbiAgICAgICAgbmFtZU9ySWQgPSBuYW1lT3JJZC50b1VwcGVyQ2FzZSgpO1xuICAgICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgdGhpcy5pdGVtcykge1xuICAgICAgICAgICAgaWYgKGl0ZW0ubmFtZS50b1VwcGVyQ2FzZSgpID09PSBuYW1lT3JJZCB8fCBpdGVtLmlkLnRvVXBwZXJDYXNlKCkgPT09IG5hbWVPcklkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGl0ZW07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHN0YXRpYyBnZXQobmFtZU9ySWQpIHtcbiAgICAgICAgY29uc3QgcmVzID0gdGhpcy5maW5kKG5hbWVPcklkKTtcbiAgICAgICAgaWYgKCFyZXMpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgRUMgbmFtZWQgY3VydmUgJyR7bmFtZU9ySWR9J2ApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxufVxuRWNDdXJ2ZXMuaXRlbXMgPSBbXTtcbkVjQ3VydmVzLm5hbWVzID0gW107XG5FY0N1cnZlcy5yZWdpc3Rlcih7IG5hbWU6IFwiUC0yNTZcIiwgaWQ6IGlkU2VjcDI1NnIxLCBzaXplOiAyNTYgfSk7XG5FY0N1cnZlcy5yZWdpc3Rlcih7IG5hbWU6IFwiUC0zODRcIiwgaWQ6IGlkU2VjcDM4NHIxLCBzaXplOiAzODQgfSk7XG5FY0N1cnZlcy5yZWdpc3Rlcih7IG5hbWU6IFwiUC01MjFcIiwgaWQ6IGlkU2VjcDUyMXIxLCBzaXplOiA1MjEgfSk7XG5FY0N1cnZlcy5yZWdpc3Rlcih7IG5hbWU6IFwiSy0yNTZcIiwgaWQ6IGlkU2VjcDI1NmsxLCBzaXplOiAyNTYgfSk7XG5FY0N1cnZlcy5yZWdpc3Rlcih7IG5hbWU6IFwiYnJhaW5wb29sUDE2MHIxXCIsIGlkOiBpZEJyYWlucG9vbFAxNjByMSwgc2l6ZTogMTYwIH0pO1xuRWNDdXJ2ZXMucmVnaXN0ZXIoeyBuYW1lOiBcImJyYWlucG9vbFAxNjB0MVwiLCBpZDogaWRCcmFpbnBvb2xQMTYwdDEsIHNpemU6IDE2MCB9KTtcbkVjQ3VydmVzLnJlZ2lzdGVyKHsgbmFtZTogXCJicmFpbnBvb2xQMTkycjFcIiwgaWQ6IGlkQnJhaW5wb29sUDE5MnIxLCBzaXplOiAxOTIgfSk7XG5FY0N1cnZlcy5yZWdpc3Rlcih7IG5hbWU6IFwiYnJhaW5wb29sUDE5MnQxXCIsIGlkOiBpZEJyYWlucG9vbFAxOTJ0MSwgc2l6ZTogMTkyIH0pO1xuRWNDdXJ2ZXMucmVnaXN0ZXIoeyBuYW1lOiBcImJyYWlucG9vbFAyMjRyMVwiLCBpZDogaWRCcmFpbnBvb2xQMjI0cjEsIHNpemU6IDIyNCB9KTtcbkVjQ3VydmVzLnJlZ2lzdGVyKHsgbmFtZTogXCJicmFpbnBvb2xQMjI0dDFcIiwgaWQ6IGlkQnJhaW5wb29sUDIyNHQxLCBzaXplOiAyMjQgfSk7XG5FY0N1cnZlcy5yZWdpc3Rlcih7IG5hbWU6IFwiYnJhaW5wb29sUDI1NnIxXCIsIGlkOiBpZEJyYWlucG9vbFAyNTZyMSwgc2l6ZTogMjU2IH0pO1xuRWNDdXJ2ZXMucmVnaXN0ZXIoeyBuYW1lOiBcImJyYWlucG9vbFAyNTZ0MVwiLCBpZDogaWRCcmFpbnBvb2xQMjU2dDEsIHNpemU6IDI1NiB9KTtcbkVjQ3VydmVzLnJlZ2lzdGVyKHsgbmFtZTogXCJicmFpbnBvb2xQMzIwcjFcIiwgaWQ6IGlkQnJhaW5wb29sUDMyMHIxLCBzaXplOiAzMjAgfSk7XG5FY0N1cnZlcy5yZWdpc3Rlcih7IG5hbWU6IFwiYnJhaW5wb29sUDMyMHQxXCIsIGlkOiBpZEJyYWlucG9vbFAzMjB0MSwgc2l6ZTogMzIwIH0pO1xuRWNDdXJ2ZXMucmVnaXN0ZXIoeyBuYW1lOiBcImJyYWlucG9vbFAzODRyMVwiLCBpZDogaWRCcmFpbnBvb2xQMzg0cjEsIHNpemU6IDM4NCB9KTtcbkVjQ3VydmVzLnJlZ2lzdGVyKHsgbmFtZTogXCJicmFpbnBvb2xQMzg0dDFcIiwgaWQ6IGlkQnJhaW5wb29sUDM4NHQxLCBzaXplOiAzODQgfSk7XG5FY0N1cnZlcy5yZWdpc3Rlcih7IG5hbWU6IFwiYnJhaW5wb29sUDUxMnIxXCIsIGlkOiBpZEJyYWlucG9vbFA1MTJyMSwgc2l6ZTogNTEyIH0pO1xuRWNDdXJ2ZXMucmVnaXN0ZXIoeyBuYW1lOiBcImJyYWlucG9vbFA1MTJ0MVwiLCBpZDogaWRCcmFpbnBvb2xQNTEydDEsIHNpemU6IDUxMiB9KTtcblxuY2xhc3MgSG1hY1Byb3ZpZGVyIGV4dGVuZHMgUHJvdmlkZXJDcnlwdG8ge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkhNQUNcIjtcbiAgICAgICAgdGhpcy5oYXNoQWxnb3JpdGhtcyA9IFtcIlNIQS0xXCIsIFwiU0hBLTI1NlwiLCBcIlNIQS0zODRcIiwgXCJTSEEtNTEyXCJdO1xuICAgICAgICB0aGlzLnVzYWdlcyA9IFtcInNpZ25cIiwgXCJ2ZXJpZnlcIl07XG4gICAgfVxuICAgIGdldERlZmF1bHRMZW5ndGgoYWxnTmFtZSkge1xuICAgICAgICBzd2l0Y2ggKGFsZ05hbWUudG9VcHBlckNhc2UoKSkge1xuICAgICAgICAgICAgY2FzZSBcIlNIQS0xXCI6XG4gICAgICAgICAgICBjYXNlIFwiU0hBLTI1NlwiOlxuICAgICAgICAgICAgY2FzZSBcIlNIQS0zODRcIjpcbiAgICAgICAgICAgIGNhc2UgXCJTSEEtNTEyXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIDUxMjtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGFsZ29yaXRobSBuYW1lICcke2FsZ05hbWV9J2ApO1xuICAgICAgICB9XG4gICAgfVxuICAgIGNoZWNrR2VuZXJhdGVLZXlQYXJhbXMoYWxnb3JpdGhtKSB7XG4gICAgICAgIHRoaXMuY2hlY2tSZXF1aXJlZFByb3BlcnR5KGFsZ29yaXRobSwgXCJoYXNoXCIpO1xuICAgICAgICB0aGlzLmNoZWNrSGFzaEFsZ29yaXRobShhbGdvcml0aG0uaGFzaCwgdGhpcy5oYXNoQWxnb3JpdGhtcyk7XG4gICAgICAgIGlmIChcImxlbmd0aFwiIGluIGFsZ29yaXRobSkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBhbGdvcml0aG0ubGVuZ3RoICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImxlbmd0aDogSXMgbm90IGEgTnVtYmVyXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGFsZ29yaXRobS5sZW5ndGggPCAxKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJsZW5ndGg6IE51bWJlciBpcyBvdXQgb2YgcmFuZ2VcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgY2hlY2tJbXBvcnRQYXJhbXMoYWxnb3JpdGhtKSB7XG4gICAgICAgIHRoaXMuY2hlY2tSZXF1aXJlZFByb3BlcnR5KGFsZ29yaXRobSwgXCJoYXNoXCIpO1xuICAgICAgICB0aGlzLmNoZWNrSGFzaEFsZ29yaXRobShhbGdvcml0aG0uaGFzaCwgdGhpcy5oYXNoQWxnb3JpdGhtcyk7XG4gICAgfVxufVxuXG5jbGFzcyBQYmtkZjJQcm92aWRlciBleHRlbmRzIFByb3ZpZGVyQ3J5cHRvIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJQQktERjJcIjtcbiAgICAgICAgdGhpcy5oYXNoQWxnb3JpdGhtcyA9IFtcIlNIQS0xXCIsIFwiU0hBLTI1NlwiLCBcIlNIQS0zODRcIiwgXCJTSEEtNTEyXCJdO1xuICAgICAgICB0aGlzLnVzYWdlcyA9IFtcImRlcml2ZUJpdHNcIiwgXCJkZXJpdmVLZXlcIl07XG4gICAgfVxuICAgIGNoZWNrQWxnb3JpdGhtUGFyYW1zKGFsZ29yaXRobSkge1xuICAgICAgICB0aGlzLmNoZWNrUmVxdWlyZWRQcm9wZXJ0eShhbGdvcml0aG0sIFwiaGFzaFwiKTtcbiAgICAgICAgdGhpcy5jaGVja0hhc2hBbGdvcml0aG0oYWxnb3JpdGhtLmhhc2gsIHRoaXMuaGFzaEFsZ29yaXRobXMpO1xuICAgICAgICB0aGlzLmNoZWNrUmVxdWlyZWRQcm9wZXJ0eShhbGdvcml0aG0sIFwic2FsdFwiKTtcbiAgICAgICAgaWYgKCEoYWxnb3JpdGhtLnNhbHQgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlciB8fCBBcnJheUJ1ZmZlci5pc1ZpZXcoYWxnb3JpdGhtLnNhbHQpKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInNhbHQ6IElzIG5vdCBvZiB0eXBlICcoQXJyYXlCdWZmZXIgb3IgQXJyYXlCdWZmZXJWaWV3KSdcIik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jaGVja1JlcXVpcmVkUHJvcGVydHkoYWxnb3JpdGhtLCBcIml0ZXJhdGlvbnNcIik7XG4gICAgICAgIGlmICh0eXBlb2YgYWxnb3JpdGhtLml0ZXJhdGlvbnMgIT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJpdGVyYXRpb25zOiBJcyBub3QgYSBOdW1iZXJcIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGFsZ29yaXRobS5pdGVyYXRpb25zIDwgMSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIml0ZXJhdGlvbnM6IElzIGxlc3MgdGhhbiAxXCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGNoZWNrSW1wb3J0S2V5KGZvcm1hdCwga2V5RGF0YSwgYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzLCAuLi5hcmdzKSB7XG4gICAgICAgIHN1cGVyLmNoZWNrSW1wb3J0S2V5KGZvcm1hdCwga2V5RGF0YSwgYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgaWYgKGV4dHJhY3RhYmxlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJleHRyYWN0YWJsZTogTXVzdCBiZSAnZmFsc2UnXCIpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5jbGFzcyBIa2RmUHJvdmlkZXIgZXh0ZW5kcyBQcm92aWRlckNyeXB0byB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiSEtERlwiO1xuICAgICAgICB0aGlzLmhhc2hBbGdvcml0aG1zID0gW1wiU0hBLTFcIiwgXCJTSEEtMjU2XCIsIFwiU0hBLTM4NFwiLCBcIlNIQS01MTJcIl07XG4gICAgICAgIHRoaXMudXNhZ2VzID0gW1wiZGVyaXZlS2V5XCIsIFwiZGVyaXZlQml0c1wiXTtcbiAgICB9XG4gICAgY2hlY2tBbGdvcml0aG1QYXJhbXMoYWxnb3JpdGhtKSB7XG4gICAgICAgIHRoaXMuY2hlY2tSZXF1aXJlZFByb3BlcnR5KGFsZ29yaXRobSwgXCJoYXNoXCIpO1xuICAgICAgICB0aGlzLmNoZWNrSGFzaEFsZ29yaXRobShhbGdvcml0aG0uaGFzaCwgdGhpcy5oYXNoQWxnb3JpdGhtcyk7XG4gICAgICAgIHRoaXMuY2hlY2tSZXF1aXJlZFByb3BlcnR5KGFsZ29yaXRobSwgXCJzYWx0XCIpO1xuICAgICAgICBpZiAoIUJ1ZmZlclNvdXJjZUNvbnZlcnRlci5pc0J1ZmZlclNvdXJjZShhbGdvcml0aG0uc2FsdCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJzYWx0OiBJcyBub3Qgb2YgdHlwZSAnKEFycmF5QnVmZmVyIG9yIEFycmF5QnVmZmVyVmlldyknXCIpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY2hlY2tSZXF1aXJlZFByb3BlcnR5KGFsZ29yaXRobSwgXCJpbmZvXCIpO1xuICAgICAgICBpZiAoIUJ1ZmZlclNvdXJjZUNvbnZlcnRlci5pc0J1ZmZlclNvdXJjZShhbGdvcml0aG0uaW5mbykpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJzYWx0OiBJcyBub3Qgb2YgdHlwZSAnKEFycmF5QnVmZmVyIG9yIEFycmF5QnVmZmVyVmlldyknXCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGNoZWNrSW1wb3J0S2V5KGZvcm1hdCwga2V5RGF0YSwgYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzLCAuLi5hcmdzKSB7XG4gICAgICAgIHN1cGVyLmNoZWNrSW1wb3J0S2V5KGZvcm1hdCwga2V5RGF0YSwgYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgaWYgKGV4dHJhY3RhYmxlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJleHRyYWN0YWJsZTogTXVzdCBiZSAnZmFsc2UnXCIpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5jbGFzcyBTaGFrZVByb3ZpZGVyIGV4dGVuZHMgUHJvdmlkZXJDcnlwdG8ge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLnVzYWdlcyA9IFtdO1xuICAgICAgICB0aGlzLmRlZmF1bHRMZW5ndGggPSAwO1xuICAgIH1cbiAgICBkaWdlc3QoLi4uYXJncykge1xuICAgICAgICBhcmdzWzBdID0geyBsZW5ndGg6IHRoaXMuZGVmYXVsdExlbmd0aCwgLi4uYXJnc1swXSB9O1xuICAgICAgICByZXR1cm4gc3VwZXIuZGlnZXN0LmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH1cbiAgICBjaGVja0RpZ2VzdChhbGdvcml0aG0sIGRhdGEpIHtcbiAgICAgICAgc3VwZXIuY2hlY2tEaWdlc3QoYWxnb3JpdGhtLCBkYXRhKTtcbiAgICAgICAgY29uc3QgbGVuZ3RoID0gYWxnb3JpdGhtLmxlbmd0aCB8fCAwO1xuICAgICAgICBpZiAodHlwZW9mIGxlbmd0aCAhPT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImxlbmd0aDogSXMgbm90IGEgTnVtYmVyXCIpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChsZW5ndGggPCAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwibGVuZ3RoOiBJcyBuZWdhdGl2ZVwiKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuY2xhc3MgU2hha2UxMjhQcm92aWRlciBleHRlbmRzIFNoYWtlUHJvdmlkZXIge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcInNoYWtlMTI4XCI7XG4gICAgICAgIHRoaXMuZGVmYXVsdExlbmd0aCA9IDE2O1xuICAgIH1cbn1cblxuY2xhc3MgU2hha2UyNTZQcm92aWRlciBleHRlbmRzIFNoYWtlUHJvdmlkZXIge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcInNoYWtlMjU2XCI7XG4gICAgICAgIHRoaXMuZGVmYXVsdExlbmd0aCA9IDMyO1xuICAgIH1cbn1cblxuY2xhc3MgQ3J5cHRvIHtcbiAgICBnZXQgW1N5bWJvbC50b1N0cmluZ1RhZ10oKSB7XG4gICAgICAgIHJldHVybiBcIkNyeXB0b1wiO1xuICAgIH1cbiAgICByYW5kb21VVUlEKCkge1xuICAgICAgICBjb25zdCBiID0gdGhpcy5nZXRSYW5kb21WYWx1ZXMobmV3IFVpbnQ4QXJyYXkoMTYpKTtcbiAgICAgICAgYls2XSA9IChiWzZdICYgMHgwZikgfCAweDQwO1xuICAgICAgICBiWzhdID0gKGJbOF0gJiAweDNmKSB8IDB4ODA7XG4gICAgICAgIGNvbnN0IHV1aWQgPSBDb252ZXJ0LlRvSGV4KGIpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIHJldHVybiBgJHt1dWlkLnN1YnN0cmluZygwLCA4KX0tJHt1dWlkLnN1YnN0cmluZyg4LCAxMil9LSR7dXVpZC5zdWJzdHJpbmcoMTIsIDE2KX0tJHt1dWlkLnN1YnN0cmluZygxNiwgMjApfS0ke3V1aWQuc3Vic3RyaW5nKDIwKX1gO1xuICAgIH1cbn1cblxuY2xhc3MgUHJvdmlkZXJTdG9yYWdlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5pdGVtcyA9IHt9O1xuICAgIH1cbiAgICBnZXQoYWxnb3JpdGhtTmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5pdGVtc1thbGdvcml0aG1OYW1lLnRvTG93ZXJDYXNlKCldIHx8IG51bGw7XG4gICAgfVxuICAgIHNldChwcm92aWRlcikge1xuICAgICAgICB0aGlzLml0ZW1zW3Byb3ZpZGVyLm5hbWUudG9Mb3dlckNhc2UoKV0gPSBwcm92aWRlcjtcbiAgICB9XG4gICAgcmVtb3ZlQXQoYWxnb3JpdGhtTmFtZSkge1xuICAgICAgICBjb25zdCBwcm92aWRlciA9IHRoaXMuZ2V0KGFsZ29yaXRobU5hbWUudG9Mb3dlckNhc2UoKSk7XG4gICAgICAgIGlmIChwcm92aWRlcikge1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMuaXRlbXNbYWxnb3JpdGhtTmFtZV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHByb3ZpZGVyO1xuICAgIH1cbiAgICBoYXMobmFtZSkge1xuICAgICAgICByZXR1cm4gISF0aGlzLmdldChuYW1lKTtcbiAgICB9XG4gICAgZ2V0IGxlbmd0aCgpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKHRoaXMuaXRlbXMpLmxlbmd0aDtcbiAgICB9XG4gICAgZ2V0IGFsZ29yaXRobXMoKSB7XG4gICAgICAgIGNvbnN0IGFsZ29yaXRobXMgPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gdGhpcy5pdGVtcykge1xuICAgICAgICAgICAgY29uc3QgcHJvdmlkZXIgPSB0aGlzLml0ZW1zW2tleV07XG4gICAgICAgICAgICBhbGdvcml0aG1zLnB1c2gocHJvdmlkZXIubmFtZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFsZ29yaXRobXMuc29ydCgpO1xuICAgIH1cbn1cblxuY2xhc3MgU3VidGxlQ3J5cHRvIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5wcm92aWRlcnMgPSBuZXcgUHJvdmlkZXJTdG9yYWdlKCk7XG4gICAgfVxuICAgIHN0YXRpYyBpc0hhc2hlZEFsZ29yaXRobShkYXRhKSB7XG4gICAgICAgIHJldHVybiBkYXRhXG4gICAgICAgICAgICAmJiB0eXBlb2YgZGF0YSA9PT0gXCJvYmplY3RcIlxuICAgICAgICAgICAgJiYgXCJuYW1lXCIgaW4gZGF0YVxuICAgICAgICAgICAgJiYgXCJoYXNoXCIgaW4gZGF0YVxuICAgICAgICAgICAgPyB0cnVlXG4gICAgICAgICAgICA6IGZhbHNlO1xuICAgIH1cbiAgICBnZXQgW1N5bWJvbC50b1N0cmluZ1RhZ10oKSB7XG4gICAgICAgIHJldHVybiBcIlN1YnRsZUNyeXB0b1wiO1xuICAgIH1cbiAgICBhc3luYyBkaWdlc3QoLi4uYXJncykge1xuICAgICAgICB0aGlzLmNoZWNrUmVxdWlyZWRBcmd1bWVudHMoYXJncywgMiwgXCJkaWdlc3RcIik7XG4gICAgICAgIGNvbnN0IFthbGdvcml0aG0sIGRhdGEsIC4uLnBhcmFtc10gPSBhcmdzO1xuICAgICAgICBjb25zdCBwcmVwYXJlZEFsZ29yaXRobSA9IHRoaXMucHJlcGFyZUFsZ29yaXRobShhbGdvcml0aG0pO1xuICAgICAgICBjb25zdCBwcmVwYXJlZERhdGEgPSBCdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9BcnJheUJ1ZmZlcihkYXRhKTtcbiAgICAgICAgY29uc3QgcHJvdmlkZXIgPSB0aGlzLmdldFByb3ZpZGVyKHByZXBhcmVkQWxnb3JpdGhtLm5hbWUpO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwcm92aWRlci5kaWdlc3QocHJlcGFyZWRBbGdvcml0aG0sIHByZXBhcmVkRGF0YSwgLi4ucGFyYW1zKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgYXN5bmMgZ2VuZXJhdGVLZXkoLi4uYXJncykge1xuICAgICAgICB0aGlzLmNoZWNrUmVxdWlyZWRBcmd1bWVudHMoYXJncywgMywgXCJnZW5lcmF0ZUtleVwiKTtcbiAgICAgICAgY29uc3QgW2FsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcywgLi4ucGFyYW1zXSA9IGFyZ3M7XG4gICAgICAgIGNvbnN0IHByZXBhcmVkQWxnb3JpdGhtID0gdGhpcy5wcmVwYXJlQWxnb3JpdGhtKGFsZ29yaXRobSk7XG4gICAgICAgIGNvbnN0IHByb3ZpZGVyID0gdGhpcy5nZXRQcm92aWRlcihwcmVwYXJlZEFsZ29yaXRobS5uYW1lKTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcHJvdmlkZXIuZ2VuZXJhdGVLZXkoeyAuLi5wcmVwYXJlZEFsZ29yaXRobSwgbmFtZTogcHJvdmlkZXIubmFtZSB9LCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzLCAuLi5wYXJhbXMpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgICBhc3luYyBzaWduKC4uLmFyZ3MpIHtcbiAgICAgICAgdGhpcy5jaGVja1JlcXVpcmVkQXJndW1lbnRzKGFyZ3MsIDMsIFwic2lnblwiKTtcbiAgICAgICAgY29uc3QgW2FsZ29yaXRobSwga2V5LCBkYXRhLCAuLi5wYXJhbXNdID0gYXJncztcbiAgICAgICAgdGhpcy5jaGVja0NyeXB0b0tleShrZXkpO1xuICAgICAgICBjb25zdCBwcmVwYXJlZEFsZ29yaXRobSA9IHRoaXMucHJlcGFyZUFsZ29yaXRobShhbGdvcml0aG0pO1xuICAgICAgICBjb25zdCBwcmVwYXJlZERhdGEgPSBCdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9BcnJheUJ1ZmZlcihkYXRhKTtcbiAgICAgICAgY29uc3QgcHJvdmlkZXIgPSB0aGlzLmdldFByb3ZpZGVyKHByZXBhcmVkQWxnb3JpdGhtLm5hbWUpO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwcm92aWRlci5zaWduKHsgLi4ucHJlcGFyZWRBbGdvcml0aG0sIG5hbWU6IHByb3ZpZGVyLm5hbWUgfSwga2V5LCBwcmVwYXJlZERhdGEsIC4uLnBhcmFtcyk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICAgIGFzeW5jIHZlcmlmeSguLi5hcmdzKSB7XG4gICAgICAgIHRoaXMuY2hlY2tSZXF1aXJlZEFyZ3VtZW50cyhhcmdzLCA0LCBcInZlcmlmeVwiKTtcbiAgICAgICAgY29uc3QgW2FsZ29yaXRobSwga2V5LCBzaWduYXR1cmUsIGRhdGEsIC4uLnBhcmFtc10gPSBhcmdzO1xuICAgICAgICB0aGlzLmNoZWNrQ3J5cHRvS2V5KGtleSk7XG4gICAgICAgIGNvbnN0IHByZXBhcmVkQWxnb3JpdGhtID0gdGhpcy5wcmVwYXJlQWxnb3JpdGhtKGFsZ29yaXRobSk7XG4gICAgICAgIGNvbnN0IHByZXBhcmVkRGF0YSA9IEJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b0FycmF5QnVmZmVyKGRhdGEpO1xuICAgICAgICBjb25zdCBwcmVwYXJlZFNpZ25hdHVyZSA9IEJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b0FycmF5QnVmZmVyKHNpZ25hdHVyZSk7XG4gICAgICAgIGNvbnN0IHByb3ZpZGVyID0gdGhpcy5nZXRQcm92aWRlcihwcmVwYXJlZEFsZ29yaXRobS5uYW1lKTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcHJvdmlkZXIudmVyaWZ5KHsgLi4ucHJlcGFyZWRBbGdvcml0aG0sIG5hbWU6IHByb3ZpZGVyLm5hbWUgfSwga2V5LCBwcmVwYXJlZFNpZ25hdHVyZSwgcHJlcGFyZWREYXRhLCAuLi5wYXJhbXMpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgICBhc3luYyBlbmNyeXB0KC4uLmFyZ3MpIHtcbiAgICAgICAgdGhpcy5jaGVja1JlcXVpcmVkQXJndW1lbnRzKGFyZ3MsIDMsIFwiZW5jcnlwdFwiKTtcbiAgICAgICAgY29uc3QgW2FsZ29yaXRobSwga2V5LCBkYXRhLCAuLi5wYXJhbXNdID0gYXJncztcbiAgICAgICAgdGhpcy5jaGVja0NyeXB0b0tleShrZXkpO1xuICAgICAgICBjb25zdCBwcmVwYXJlZEFsZ29yaXRobSA9IHRoaXMucHJlcGFyZUFsZ29yaXRobShhbGdvcml0aG0pO1xuICAgICAgICBjb25zdCBwcmVwYXJlZERhdGEgPSBCdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9BcnJheUJ1ZmZlcihkYXRhKTtcbiAgICAgICAgY29uc3QgcHJvdmlkZXIgPSB0aGlzLmdldFByb3ZpZGVyKHByZXBhcmVkQWxnb3JpdGhtLm5hbWUpO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwcm92aWRlci5lbmNyeXB0KHsgLi4ucHJlcGFyZWRBbGdvcml0aG0sIG5hbWU6IHByb3ZpZGVyLm5hbWUgfSwga2V5LCBwcmVwYXJlZERhdGEsIHsga2V5VXNhZ2U6IHRydWUgfSwgLi4ucGFyYW1zKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgYXN5bmMgZGVjcnlwdCguLi5hcmdzKSB7XG4gICAgICAgIHRoaXMuY2hlY2tSZXF1aXJlZEFyZ3VtZW50cyhhcmdzLCAzLCBcImRlY3J5cHRcIik7XG4gICAgICAgIGNvbnN0IFthbGdvcml0aG0sIGtleSwgZGF0YSwgLi4ucGFyYW1zXSA9IGFyZ3M7XG4gICAgICAgIHRoaXMuY2hlY2tDcnlwdG9LZXkoa2V5KTtcbiAgICAgICAgY29uc3QgcHJlcGFyZWRBbGdvcml0aG0gPSB0aGlzLnByZXBhcmVBbGdvcml0aG0oYWxnb3JpdGhtKTtcbiAgICAgICAgY29uc3QgcHJlcGFyZWREYXRhID0gQnVmZmVyU291cmNlQ29udmVydGVyLnRvQXJyYXlCdWZmZXIoZGF0YSk7XG4gICAgICAgIGNvbnN0IHByb3ZpZGVyID0gdGhpcy5nZXRQcm92aWRlcihwcmVwYXJlZEFsZ29yaXRobS5uYW1lKTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcHJvdmlkZXIuZGVjcnlwdCh7IC4uLnByZXBhcmVkQWxnb3JpdGhtLCBuYW1lOiBwcm92aWRlci5uYW1lIH0sIGtleSwgcHJlcGFyZWREYXRhLCB7IGtleVVzYWdlOiB0cnVlIH0sIC4uLnBhcmFtcyk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICAgIGFzeW5jIGRlcml2ZUJpdHMoLi4uYXJncykge1xuICAgICAgICB0aGlzLmNoZWNrUmVxdWlyZWRBcmd1bWVudHMoYXJncywgMywgXCJkZXJpdmVCaXRzXCIpO1xuICAgICAgICBjb25zdCBbYWxnb3JpdGhtLCBiYXNlS2V5LCBsZW5ndGgsIC4uLnBhcmFtc10gPSBhcmdzO1xuICAgICAgICB0aGlzLmNoZWNrQ3J5cHRvS2V5KGJhc2VLZXkpO1xuICAgICAgICBjb25zdCBwcmVwYXJlZEFsZ29yaXRobSA9IHRoaXMucHJlcGFyZUFsZ29yaXRobShhbGdvcml0aG0pO1xuICAgICAgICBjb25zdCBwcm92aWRlciA9IHRoaXMuZ2V0UHJvdmlkZXIocHJlcGFyZWRBbGdvcml0aG0ubmFtZSk7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHByb3ZpZGVyLmRlcml2ZUJpdHMoeyAuLi5wcmVwYXJlZEFsZ29yaXRobSwgbmFtZTogcHJvdmlkZXIubmFtZSB9LCBiYXNlS2V5LCBsZW5ndGgsIHsga2V5VXNhZ2U6IHRydWUgfSwgLi4ucGFyYW1zKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgYXN5bmMgZGVyaXZlS2V5KC4uLmFyZ3MpIHtcbiAgICAgICAgdGhpcy5jaGVja1JlcXVpcmVkQXJndW1lbnRzKGFyZ3MsIDUsIFwiZGVyaXZlS2V5XCIpO1xuICAgICAgICBjb25zdCBbYWxnb3JpdGhtLCBiYXNlS2V5LCBkZXJpdmVkS2V5VHlwZSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcywgLi4ucGFyYW1zXSA9IGFyZ3M7XG4gICAgICAgIGNvbnN0IHByZXBhcmVkRGVyaXZlZEtleVR5cGUgPSB0aGlzLnByZXBhcmVBbGdvcml0aG0oZGVyaXZlZEtleVR5cGUpO1xuICAgICAgICBjb25zdCBpbXBvcnRQcm92aWRlciA9IHRoaXMuZ2V0UHJvdmlkZXIocHJlcGFyZWREZXJpdmVkS2V5VHlwZS5uYW1lKTtcbiAgICAgICAgaW1wb3J0UHJvdmlkZXIuY2hlY2tEZXJpdmVkS2V5UGFyYW1zKHByZXBhcmVkRGVyaXZlZEtleVR5cGUpO1xuICAgICAgICBjb25zdCBwcmVwYXJlZEFsZ29yaXRobSA9IHRoaXMucHJlcGFyZUFsZ29yaXRobShhbGdvcml0aG0pO1xuICAgICAgICBjb25zdCBwcm92aWRlciA9IHRoaXMuZ2V0UHJvdmlkZXIocHJlcGFyZWRBbGdvcml0aG0ubmFtZSk7XG4gICAgICAgIHByb3ZpZGVyLmNoZWNrQ3J5cHRvS2V5KGJhc2VLZXksIFwiZGVyaXZlS2V5XCIpO1xuICAgICAgICBjb25zdCBkZXJpdmVkQml0cyA9IGF3YWl0IHByb3ZpZGVyLmRlcml2ZUJpdHMoeyAuLi5wcmVwYXJlZEFsZ29yaXRobSwgbmFtZTogcHJvdmlkZXIubmFtZSB9LCBiYXNlS2V5LCBkZXJpdmVkS2V5VHlwZS5sZW5ndGggfHwgNTEyLCB7IGtleVVzYWdlOiBmYWxzZSB9LCAuLi5wYXJhbXMpO1xuICAgICAgICByZXR1cm4gdGhpcy5pbXBvcnRLZXkoXCJyYXdcIiwgZGVyaXZlZEJpdHMsIGRlcml2ZWRLZXlUeXBlLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzLCAuLi5wYXJhbXMpO1xuICAgIH1cbiAgICBhc3luYyBleHBvcnRLZXkoLi4uYXJncykge1xuICAgICAgICB0aGlzLmNoZWNrUmVxdWlyZWRBcmd1bWVudHMoYXJncywgMiwgXCJleHBvcnRLZXlcIik7XG4gICAgICAgIGNvbnN0IFtmb3JtYXQsIGtleSwgLi4ucGFyYW1zXSA9IGFyZ3M7XG4gICAgICAgIHRoaXMuY2hlY2tDcnlwdG9LZXkoa2V5KTtcbiAgICAgICAgY29uc3QgcHJvdmlkZXIgPSB0aGlzLmdldFByb3ZpZGVyKGtleS5hbGdvcml0aG0ubmFtZSk7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHByb3ZpZGVyLmV4cG9ydEtleShmb3JtYXQsIGtleSwgLi4ucGFyYW1zKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgYXN5bmMgaW1wb3J0S2V5KC4uLmFyZ3MpIHtcbiAgICAgICAgdGhpcy5jaGVja1JlcXVpcmVkQXJndW1lbnRzKGFyZ3MsIDUsIFwiaW1wb3J0S2V5XCIpO1xuICAgICAgICBjb25zdCBbZm9ybWF0LCBrZXlEYXRhLCBhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMsIC4uLnBhcmFtc10gPSBhcmdzO1xuICAgICAgICBjb25zdCBwcmVwYXJlZEFsZ29yaXRobSA9IHRoaXMucHJlcGFyZUFsZ29yaXRobShhbGdvcml0aG0pO1xuICAgICAgICBjb25zdCBwcm92aWRlciA9IHRoaXMuZ2V0UHJvdmlkZXIocHJlcGFyZWRBbGdvcml0aG0ubmFtZSk7XG4gICAgICAgIGlmIChbXCJwa2NzOFwiLCBcInNwa2lcIiwgXCJyYXdcIl0uaW5kZXhPZihmb3JtYXQpICE9PSAtMSkge1xuICAgICAgICAgICAgY29uc3QgcHJlcGFyZWREYXRhID0gQnVmZmVyU291cmNlQ29udmVydGVyLnRvQXJyYXlCdWZmZXIoa2V5RGF0YSk7XG4gICAgICAgICAgICByZXR1cm4gcHJvdmlkZXIuaW1wb3J0S2V5KGZvcm1hdCwgcHJlcGFyZWREYXRhLCB7IC4uLnByZXBhcmVkQWxnb3JpdGhtLCBuYW1lOiBwcm92aWRlci5uYW1lIH0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMsIC4uLnBhcmFtcyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpZiAoIWtleURhdGEua3R5KSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImtleURhdGE6IElzIG5vdCBKU09OXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwcm92aWRlci5pbXBvcnRLZXkoZm9ybWF0LCBrZXlEYXRhLCB7IC4uLnByZXBhcmVkQWxnb3JpdGhtLCBuYW1lOiBwcm92aWRlci5uYW1lIH0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMsIC4uLnBhcmFtcyk7XG4gICAgfVxuICAgIGFzeW5jIHdyYXBLZXkoZm9ybWF0LCBrZXksIHdyYXBwaW5nS2V5LCB3cmFwQWxnb3JpdGhtLCAuLi5hcmdzKSB7XG4gICAgICAgIGxldCBrZXlEYXRhID0gYXdhaXQgdGhpcy5leHBvcnRLZXkoZm9ybWF0LCBrZXksIC4uLmFyZ3MpO1xuICAgICAgICBpZiAoZm9ybWF0ID09PSBcImp3a1wiKSB7XG4gICAgICAgICAgICBjb25zdCBqc29uID0gSlNPTi5zdHJpbmdpZnkoa2V5RGF0YSk7XG4gICAgICAgICAgICBrZXlEYXRhID0gQ29udmVydC5Gcm9tVXRmOFN0cmluZyhqc29uKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwcmVwYXJlZEFsZ29yaXRobSA9IHRoaXMucHJlcGFyZUFsZ29yaXRobSh3cmFwQWxnb3JpdGhtKTtcbiAgICAgICAgY29uc3QgcHJlcGFyZWREYXRhID0gQnVmZmVyU291cmNlQ29udmVydGVyLnRvQXJyYXlCdWZmZXIoa2V5RGF0YSk7XG4gICAgICAgIGNvbnN0IHByb3ZpZGVyID0gdGhpcy5nZXRQcm92aWRlcihwcmVwYXJlZEFsZ29yaXRobS5uYW1lKTtcbiAgICAgICAgcmV0dXJuIHByb3ZpZGVyLmVuY3J5cHQoeyAuLi5wcmVwYXJlZEFsZ29yaXRobSwgbmFtZTogcHJvdmlkZXIubmFtZSB9LCB3cmFwcGluZ0tleSwgcHJlcGFyZWREYXRhLCB7IGtleVVzYWdlOiBmYWxzZSB9LCAuLi5hcmdzKTtcbiAgICB9XG4gICAgYXN5bmMgdW53cmFwS2V5KGZvcm1hdCwgd3JhcHBlZEtleSwgdW53cmFwcGluZ0tleSwgdW53cmFwQWxnb3JpdGhtLCB1bndyYXBwZWRLZXlBbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMsIC4uLmFyZ3MpIHtcbiAgICAgICAgY29uc3QgcHJlcGFyZWRBbGdvcml0aG0gPSB0aGlzLnByZXBhcmVBbGdvcml0aG0odW53cmFwQWxnb3JpdGhtKTtcbiAgICAgICAgY29uc3QgcHJlcGFyZWREYXRhID0gQnVmZmVyU291cmNlQ29udmVydGVyLnRvQXJyYXlCdWZmZXIod3JhcHBlZEtleSk7XG4gICAgICAgIGNvbnN0IHByb3ZpZGVyID0gdGhpcy5nZXRQcm92aWRlcihwcmVwYXJlZEFsZ29yaXRobS5uYW1lKTtcbiAgICAgICAgbGV0IGtleURhdGEgPSBhd2FpdCBwcm92aWRlci5kZWNyeXB0KHsgLi4ucHJlcGFyZWRBbGdvcml0aG0sIG5hbWU6IHByb3ZpZGVyLm5hbWUgfSwgdW53cmFwcGluZ0tleSwgcHJlcGFyZWREYXRhLCB7IGtleVVzYWdlOiBmYWxzZSB9LCAuLi5hcmdzKTtcbiAgICAgICAgaWYgKGZvcm1hdCA9PT0gXCJqd2tcIikge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBrZXlEYXRhID0gSlNPTi5wYXJzZShDb252ZXJ0LlRvVXRmOFN0cmluZyhrZXlEYXRhKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IFR5cGVFcnJvcihcIndyYXBwZWRLZXk6IElzIG5vdCBhIEpTT05cIik7XG4gICAgICAgICAgICAgICAgZXJyb3IuaW50ZXJuYWwgPSBlO1xuICAgICAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIHVud3JhcHBlZEtleUFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcywgLi4uYXJncyk7XG4gICAgfVxuICAgIGNoZWNrUmVxdWlyZWRBcmd1bWVudHMoYXJncywgc2l6ZSwgbWV0aG9kTmFtZSkge1xuICAgICAgICBpZiAoYXJncy5sZW5ndGggPCBzaXplKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBGYWlsZWQgdG8gZXhlY3V0ZSAnJHttZXRob2ROYW1lfScgb24gJ1N1YnRsZUNyeXB0byc6ICR7c2l6ZX0gYXJndW1lbnRzIHJlcXVpcmVkLCBidXQgb25seSAke2FyZ3MubGVuZ3RofSBwcmVzZW50YCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcHJlcGFyZUFsZ29yaXRobShhbGdvcml0aG0pIHtcbiAgICAgICAgaWYgKHR5cGVvZiBhbGdvcml0aG0gPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgbmFtZTogYWxnb3JpdGhtLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoU3VidGxlQ3J5cHRvLmlzSGFzaGVkQWxnb3JpdGhtKGFsZ29yaXRobSkpIHtcbiAgICAgICAgICAgIGNvbnN0IHByZXBhcmVkQWxnb3JpdGhtID0geyAuLi5hbGdvcml0aG0gfTtcbiAgICAgICAgICAgIHByZXBhcmVkQWxnb3JpdGhtLmhhc2ggPSB0aGlzLnByZXBhcmVBbGdvcml0aG0oYWxnb3JpdGhtLmhhc2gpO1xuICAgICAgICAgICAgcmV0dXJuIHByZXBhcmVkQWxnb3JpdGhtO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IC4uLmFsZ29yaXRobSB9O1xuICAgIH1cbiAgICBnZXRQcm92aWRlcihuYW1lKSB7XG4gICAgICAgIGNvbnN0IHByb3ZpZGVyID0gdGhpcy5wcm92aWRlcnMuZ2V0KG5hbWUpO1xuICAgICAgICBpZiAoIXByb3ZpZGVyKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQWxnb3JpdGhtRXJyb3IoXCJVbnJlY29nbml6ZWQgbmFtZVwiKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcHJvdmlkZXI7XG4gICAgfVxuICAgIGNoZWNrQ3J5cHRvS2V5KGtleSkge1xuICAgICAgICBpZiAoIShrZXkgaW5zdGFuY2VvZiBDcnlwdG9LZXkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBLZXkgaXMgbm90IG9mIHR5cGUgJ0NyeXB0b0tleSdgKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxudmFyIGluZGV4ID0gLyojX19QVVJFX18qL09iamVjdC5mcmVlemUoe1xuICBfX3Byb3RvX186IG51bGwsXG4gIGNvbnZlcnRlcnM6IGluZGV4JDNcbn0pO1xuXG5jb25zdCBSRVFVSVJFRF9GSUVMRFMgPSBbXCJjcnZcIiwgXCJlXCIsIFwia1wiLCBcImt0eVwiLCBcIm5cIiwgXCJ4XCIsIFwieVwiXTtcbmNsYXNzIEp3a1V0aWxzIHtcbiAgICBzdGF0aWMgYXN5bmMgdGh1bWJwcmludChoYXNoLCBqd2ssIGNyeXB0bykge1xuICAgICAgICBjb25zdCBkYXRhID0gdGhpcy5mb3JtYXQoandrLCB0cnVlKTtcbiAgICAgICAgcmV0dXJuIGNyeXB0by5zdWJ0bGUuZGlnZXN0KGhhc2gsIENvbnZlcnQuRnJvbUJpbmFyeShKU09OLnN0cmluZ2lmeShkYXRhKSkpO1xuICAgIH1cbiAgICBzdGF0aWMgZm9ybWF0KGp3aywgcmVtb3ZlID0gZmFsc2UpIHtcbiAgICAgICAgbGV0IHJlcyA9IE9iamVjdC5lbnRyaWVzKGp3ayk7XG4gICAgICAgIGlmIChyZW1vdmUpIHtcbiAgICAgICAgICAgIHJlcyA9IHJlcy5maWx0ZXIobyA9PiBSRVFVSVJFRF9GSUVMRFMuaW5jbHVkZXMob1swXSkpO1xuICAgICAgICB9XG4gICAgICAgIHJlcyA9IHJlcy5zb3J0KChba2V5QV0sIFtrZXlCXSkgPT4ga2V5QSA+IGtleUIgPyAxIDoga2V5QSA8IGtleUIgPyAtMSA6IDApO1xuICAgICAgICByZXR1cm4gT2JqZWN0LmZyb21FbnRyaWVzKHJlcyk7XG4gICAgfVxufVxuXG5leHBvcnQgeyBBZXNDYmNQcm92aWRlciwgQWVzQ21hY1Byb3ZpZGVyLCBBZXNDdHJQcm92aWRlciwgQWVzRWNiUHJvdmlkZXIsIEFlc0djbVByb3ZpZGVyLCBBZXNLd1Byb3ZpZGVyLCBBZXNQcm92aWRlciwgQWxnb3JpdGhtRXJyb3IsIENyeXB0bywgQ3J5cHRvRXJyb3IsIENyeXB0b0tleSwgRGVzUHJvdmlkZXIsIEVjQ3VydmVzLCBFY1V0aWxzLCBFY2RoRXNQcm92aWRlciwgRWNkaFByb3ZpZGVyLCBFY2RzYVByb3ZpZGVyLCBFZERzYVByb3ZpZGVyLCBFbGxpcHRpY1Byb3ZpZGVyLCBIa2RmUHJvdmlkZXIsIEhtYWNQcm92aWRlciwgSndrVXRpbHMsIE9wZXJhdGlvbkVycm9yLCBQYmtkZjJQcm92aWRlciwgUGVtQ29udmVydGVyLCBQcm92aWRlckNyeXB0bywgUHJvdmlkZXJTdG9yYWdlLCBSZXF1aXJlZFByb3BlcnR5RXJyb3IsIFJzYU9hZXBQcm92aWRlciwgUnNhUHJvdmlkZXIsIFJzYVBzc1Byb3ZpZGVyLCBSc2FTc2FQcm92aWRlciwgU2hha2UxMjhQcm92aWRlciwgU2hha2UyNTZQcm92aWRlciwgU2hha2VQcm92aWRlciwgU3VidGxlQ3J5cHRvLCBVbnN1cHBvcnRlZE9wZXJhdGlvbkVycm9yLCBpbmRleCQxIGFzIGFzbjEsIGlzSldLLCBpbmRleCBhcyBqc29uIH07XG4iLCAiLyohXG4gQ29weXJpZ2h0IChjKSBQZWN1bGlhciBWZW50dXJlcywgTExDXG4qL1xuXG5pbXBvcnQgKiBhcyBjb3JlIGZyb20gJ3dlYmNyeXB0by1jb3JlJztcbmltcG9ydCB7IEJ1ZmZlclNvdXJjZUNvbnZlcnRlciBhcyBCdWZmZXJTb3VyY2VDb252ZXJ0ZXIkMSB9IGZyb20gJ3dlYmNyeXB0by1jb3JlJztcbmV4cG9ydCB7IENyeXB0b0tleSB9IGZyb20gJ3dlYmNyeXB0by1jb3JlJztcbmltcG9ydCAqIGFzIGNyeXB0byBmcm9tICdjcnlwdG8nO1xuaW1wb3J0IGNyeXB0b19fZGVmYXVsdCBmcm9tICdjcnlwdG8nO1xuaW1wb3J0ICogYXMgcHJvY2VzcyBmcm9tICdwcm9jZXNzJztcbmltcG9ydCB7IF9fZGVjb3JhdGUgfSBmcm9tICd0c2xpYic7XG5pbXBvcnQgeyBKc29uUHJvcCwgSnNvblByb3BUeXBlcywgSnNvblNlcmlhbGl6ZXIsIEpzb25QYXJzZXIgfSBmcm9tICdAcGVjdWxpYXIvanNvbi1zY2hlbWEnO1xuaW1wb3J0IHsgQ29udmVydCwgQnVmZmVyU291cmNlQ29udmVydGVyIH0gZnJvbSAncHZ0c3V0aWxzJztcbmltcG9ydCB7IEFzblBhcnNlciwgQXNuU2VyaWFsaXplciB9IGZyb20gJ0BwZWN1bGlhci9hc24xLXNjaGVtYSc7XG5cbmNvbnN0IEpzb25CYXNlNjRVcmxDb252ZXJ0ZXIgPSB7XG4gICAgZnJvbUpTT046ICh2YWx1ZSkgPT4gQnVmZmVyLmZyb20oQ29udmVydC5Gcm9tQmFzZTY0VXJsKHZhbHVlKSksXG4gICAgdG9KU09OOiAodmFsdWUpID0+IENvbnZlcnQuVG9CYXNlNjRVcmwodmFsdWUpLFxufTtcblxuY2xhc3MgQ3J5cHRvS2V5IGV4dGVuZHMgY29yZS5DcnlwdG9LZXkge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLmRhdGEgPSBCdWZmZXIuYWxsb2MoMCk7XG4gICAgICAgIHRoaXMuYWxnb3JpdGhtID0geyBuYW1lOiBcIlwiIH07XG4gICAgICAgIHRoaXMuZXh0cmFjdGFibGUgPSBmYWxzZTtcbiAgICAgICAgdGhpcy50eXBlID0gXCJzZWNyZXRcIjtcbiAgICAgICAgdGhpcy51c2FnZXMgPSBbXTtcbiAgICAgICAgdGhpcy5rdHkgPSBcIm9jdFwiO1xuICAgICAgICB0aGlzLmFsZyA9IFwiXCI7XG4gICAgfVxufVxuX19kZWNvcmF0ZShbXG4gICAgSnNvblByb3AoeyBuYW1lOiBcImV4dFwiLCB0eXBlOiBKc29uUHJvcFR5cGVzLkJvb2xlYW4sIG9wdGlvbmFsOiB0cnVlIH0pXG5dLCBDcnlwdG9LZXkucHJvdG90eXBlLCBcImV4dHJhY3RhYmxlXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBKc29uUHJvcCh7IG5hbWU6IFwia2V5X29wc1wiLCB0eXBlOiBKc29uUHJvcFR5cGVzLlN0cmluZywgcmVwZWF0ZWQ6IHRydWUsIG9wdGlvbmFsOiB0cnVlIH0pXG5dLCBDcnlwdG9LZXkucHJvdG90eXBlLCBcInVzYWdlc1wiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgSnNvblByb3AoeyB0eXBlOiBKc29uUHJvcFR5cGVzLlN0cmluZyB9KVxuXSwgQ3J5cHRvS2V5LnByb3RvdHlwZSwgXCJrdHlcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIEpzb25Qcm9wKHsgdHlwZTogSnNvblByb3BUeXBlcy5TdHJpbmcsIG9wdGlvbmFsOiB0cnVlIH0pXG5dLCBDcnlwdG9LZXkucHJvdG90eXBlLCBcImFsZ1wiLCB2b2lkIDApO1xuXG5jbGFzcyBTeW1tZXRyaWNLZXkgZXh0ZW5kcyBDcnlwdG9LZXkge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLmt0eSA9IFwib2N0XCI7XG4gICAgICAgIHRoaXMudHlwZSA9IFwic2VjcmV0XCI7XG4gICAgfVxufVxuXG5jbGFzcyBBc3ltbWV0cmljS2V5IGV4dGVuZHMgQ3J5cHRvS2V5IHtcbn1cblxuY2xhc3MgQWVzQ3J5cHRvS2V5IGV4dGVuZHMgU3ltbWV0cmljS2V5IHtcbiAgICBnZXQgYWxnKCkge1xuICAgICAgICBzd2l0Y2ggKHRoaXMuYWxnb3JpdGhtLm5hbWUudG9VcHBlckNhc2UoKSkge1xuICAgICAgICAgICAgY2FzZSBcIkFFUy1DQkNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYEEke3RoaXMuYWxnb3JpdGhtLmxlbmd0aH1DQkNgO1xuICAgICAgICAgICAgY2FzZSBcIkFFUy1DVFJcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYEEke3RoaXMuYWxnb3JpdGhtLmxlbmd0aH1DVFJgO1xuICAgICAgICAgICAgY2FzZSBcIkFFUy1HQ01cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYEEke3RoaXMuYWxnb3JpdGhtLmxlbmd0aH1HQ01gO1xuICAgICAgICAgICAgY2FzZSBcIkFFUy1LV1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgQSR7dGhpcy5hbGdvcml0aG0ubGVuZ3RofUtXYDtcbiAgICAgICAgICAgIGNhc2UgXCJBRVMtQ01BQ1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgQSR7dGhpcy5hbGdvcml0aG0ubGVuZ3RofUNNQUNgO1xuICAgICAgICAgICAgY2FzZSBcIkFFUy1FQ0JcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYEEke3RoaXMuYWxnb3JpdGhtLmxlbmd0aH1FQ0JgO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgY29yZS5BbGdvcml0aG1FcnJvcihcIlVuc3VwcG9ydGVkIGFsZ29yaXRobSBuYW1lXCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNldCBhbGcodmFsdWUpIHtcbiAgICB9XG59XG5fX2RlY29yYXRlKFtcbiAgICBKc29uUHJvcCh7IG5hbWU6IFwia1wiLCBjb252ZXJ0ZXI6IEpzb25CYXNlNjRVcmxDb252ZXJ0ZXIgfSlcbl0sIEFlc0NyeXB0b0tleS5wcm90b3R5cGUsIFwiZGF0YVwiLCB2b2lkIDApO1xuXG5jbGFzcyBBZXNDcnlwdG8ge1xuICAgIHN0YXRpYyBhc3luYyBnZW5lcmF0ZUtleShhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgY29uc3Qga2V5ID0gbmV3IEFlc0NyeXB0b0tleSgpO1xuICAgICAgICBrZXkuYWxnb3JpdGhtID0gYWxnb3JpdGhtO1xuICAgICAgICBrZXkuZXh0cmFjdGFibGUgPSBleHRyYWN0YWJsZTtcbiAgICAgICAga2V5LnVzYWdlcyA9IGtleVVzYWdlcztcbiAgICAgICAga2V5LmRhdGEgPSBjcnlwdG9fX2RlZmF1bHQucmFuZG9tQnl0ZXMoYWxnb3JpdGhtLmxlbmd0aCA+PiAzKTtcbiAgICAgICAgcmV0dXJuIGtleTtcbiAgICB9XG4gICAgc3RhdGljIGFzeW5jIGV4cG9ydEtleShmb3JtYXQsIGtleSkge1xuICAgICAgICBpZiAoIShrZXkgaW5zdGFuY2VvZiBBZXNDcnlwdG9LZXkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJrZXk6IElzIG5vdCBBZXNDcnlwdG9LZXlcIik7XG4gICAgICAgIH1cbiAgICAgICAgc3dpdGNoIChmb3JtYXQudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgY2FzZSBcImp3a1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBKc29uU2VyaWFsaXplci50b0pTT04oa2V5KTtcbiAgICAgICAgICAgIGNhc2UgXCJyYXdcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoa2V5LmRhdGEpLmJ1ZmZlcjtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IGNvcmUuT3BlcmF0aW9uRXJyb3IoXCJmb3JtYXQ6IE11c3QgYmUgJ2p3aycgb3IgJ3JhdydcIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIGFzeW5jIGltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBsZXQga2V5O1xuICAgICAgICBzd2l0Y2ggKGZvcm1hdC50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgICAgICBjYXNlIFwiandrXCI6XG4gICAgICAgICAgICAgICAga2V5ID0gSnNvblBhcnNlci5mcm9tSlNPTihrZXlEYXRhLCB7IHRhcmdldFNjaGVtYTogQWVzQ3J5cHRvS2V5IH0pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcInJhd1wiOlxuICAgICAgICAgICAgICAgIGtleSA9IG5ldyBBZXNDcnlwdG9LZXkoKTtcbiAgICAgICAgICAgICAgICBrZXkuZGF0YSA9IEJ1ZmZlci5mcm9tKGtleURhdGEpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgY29yZS5PcGVyYXRpb25FcnJvcihcImZvcm1hdDogTXVzdCBiZSAnandrJyBvciAncmF3J1wiKTtcbiAgICAgICAgfVxuICAgICAgICBrZXkuYWxnb3JpdGhtID0gYWxnb3JpdGhtO1xuICAgICAgICBrZXkuYWxnb3JpdGhtLmxlbmd0aCA9IGtleS5kYXRhLmxlbmd0aCA8PCAzO1xuICAgICAgICBrZXkuZXh0cmFjdGFibGUgPSBleHRyYWN0YWJsZTtcbiAgICAgICAga2V5LnVzYWdlcyA9IGtleVVzYWdlcztcbiAgICAgICAgc3dpdGNoIChrZXkuYWxnb3JpdGhtLmxlbmd0aCkge1xuICAgICAgICAgICAgY2FzZSAxMjg6XG4gICAgICAgICAgICBjYXNlIDE5MjpcbiAgICAgICAgICAgIGNhc2UgMjU2OlxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgY29yZS5PcGVyYXRpb25FcnJvcihcImtleURhdGE6IElzIHdyb25nIGtleSBsZW5ndGhcIik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGtleTtcbiAgICB9XG4gICAgc3RhdGljIGFzeW5jIGVuY3J5cHQoYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgc3dpdGNoIChhbGdvcml0aG0ubmFtZS50b1VwcGVyQ2FzZSgpKSB7XG4gICAgICAgICAgICBjYXNlIFwiQUVTLUNCQ1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVuY3J5cHRBZXNDQkMoYWxnb3JpdGhtLCBrZXksIEJ1ZmZlci5mcm9tKGRhdGEpKTtcbiAgICAgICAgICAgIGNhc2UgXCJBRVMtQ1RSXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW5jcnlwdEFlc0NUUihhbGdvcml0aG0sIGtleSwgQnVmZmVyLmZyb20oZGF0YSkpO1xuICAgICAgICAgICAgY2FzZSBcIkFFUy1HQ01cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lbmNyeXB0QWVzR0NNKGFsZ29yaXRobSwga2V5LCBCdWZmZXIuZnJvbShkYXRhKSk7XG4gICAgICAgICAgICBjYXNlIFwiQUVTLUtXXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW5jcnlwdEFlc0tXKGFsZ29yaXRobSwga2V5LCBCdWZmZXIuZnJvbShkYXRhKSk7XG4gICAgICAgICAgICBjYXNlIFwiQUVTLUVDQlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVuY3J5cHRBZXNFQ0IoYWxnb3JpdGhtLCBrZXksIEJ1ZmZlci5mcm9tKGRhdGEpKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IGNvcmUuT3BlcmF0aW9uRXJyb3IoXCJhbGdvcml0aG06IElzIG5vdCByZWNvZ25pemVkXCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHN0YXRpYyBhc3luYyBkZWNyeXB0KGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIGlmICghKGtleSBpbnN0YW5jZW9mIEFlc0NyeXB0b0tleSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImtleTogSXMgbm90IEFlc0NyeXB0b0tleVwiKTtcbiAgICAgICAgfVxuICAgICAgICBzd2l0Y2ggKGFsZ29yaXRobS5uYW1lLnRvVXBwZXJDYXNlKCkpIHtcbiAgICAgICAgICAgIGNhc2UgXCJBRVMtQ0JDXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGVjcnlwdEFlc0NCQyhhbGdvcml0aG0sIGtleSwgQnVmZmVyLmZyb20oZGF0YSkpO1xuICAgICAgICAgICAgY2FzZSBcIkFFUy1DVFJcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5kZWNyeXB0QWVzQ1RSKGFsZ29yaXRobSwga2V5LCBCdWZmZXIuZnJvbShkYXRhKSk7XG4gICAgICAgICAgICBjYXNlIFwiQUVTLUdDTVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmRlY3J5cHRBZXNHQ00oYWxnb3JpdGhtLCBrZXksIEJ1ZmZlci5mcm9tKGRhdGEpKTtcbiAgICAgICAgICAgIGNhc2UgXCJBRVMtS1dcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5kZWNyeXB0QWVzS1coYWxnb3JpdGhtLCBrZXksIEJ1ZmZlci5mcm9tKGRhdGEpKTtcbiAgICAgICAgICAgIGNhc2UgXCJBRVMtRUNCXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGVjcnlwdEFlc0VDQihhbGdvcml0aG0sIGtleSwgQnVmZmVyLmZyb20oZGF0YSkpO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgY29yZS5PcGVyYXRpb25FcnJvcihcImFsZ29yaXRobTogSXMgbm90IHJlY29nbml6ZWRcIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIGFzeW5jIGVuY3J5cHRBZXNDQkMoYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgY29uc3QgY2lwaGVyID0gY3J5cHRvX19kZWZhdWx0LmNyZWF0ZUNpcGhlcml2KGBhZXMtJHtrZXkuYWxnb3JpdGhtLmxlbmd0aH0tY2JjYCwga2V5LmRhdGEsIG5ldyBVaW50OEFycmF5KGFsZ29yaXRobS5pdikpO1xuICAgICAgICBsZXQgZW5jID0gY2lwaGVyLnVwZGF0ZShkYXRhKTtcbiAgICAgICAgZW5jID0gQnVmZmVyLmNvbmNhdChbZW5jLCBjaXBoZXIuZmluYWwoKV0pO1xuICAgICAgICBjb25zdCByZXMgPSBuZXcgVWludDhBcnJheShlbmMpLmJ1ZmZlcjtcbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG4gICAgc3RhdGljIGFzeW5jIGRlY3J5cHRBZXNDQkMoYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgY29uc3QgZGVjaXBoZXIgPSBjcnlwdG9fX2RlZmF1bHQuY3JlYXRlRGVjaXBoZXJpdihgYWVzLSR7a2V5LmFsZ29yaXRobS5sZW5ndGh9LWNiY2AsIGtleS5kYXRhLCBuZXcgVWludDhBcnJheShhbGdvcml0aG0uaXYpKTtcbiAgICAgICAgbGV0IGRlYyA9IGRlY2lwaGVyLnVwZGF0ZShkYXRhKTtcbiAgICAgICAgZGVjID0gQnVmZmVyLmNvbmNhdChbZGVjLCBkZWNpcGhlci5maW5hbCgpXSk7XG4gICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShkZWMpLmJ1ZmZlcjtcbiAgICB9XG4gICAgc3RhdGljIGFzeW5jIGVuY3J5cHRBZXNDVFIoYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgY29uc3QgY2lwaGVyID0gY3J5cHRvX19kZWZhdWx0LmNyZWF0ZUNpcGhlcml2KGBhZXMtJHtrZXkuYWxnb3JpdGhtLmxlbmd0aH0tY3RyYCwga2V5LmRhdGEsIEJ1ZmZlci5mcm9tKGFsZ29yaXRobS5jb3VudGVyKSk7XG4gICAgICAgIGxldCBlbmMgPSBjaXBoZXIudXBkYXRlKGRhdGEpO1xuICAgICAgICBlbmMgPSBCdWZmZXIuY29uY2F0KFtlbmMsIGNpcGhlci5maW5hbCgpXSk7XG4gICAgICAgIGNvbnN0IHJlcyA9IG5ldyBVaW50OEFycmF5KGVuYykuYnVmZmVyO1xuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cbiAgICBzdGF0aWMgYXN5bmMgZGVjcnlwdEFlc0NUUihhbGdvcml0aG0sIGtleSwgZGF0YSkge1xuICAgICAgICBjb25zdCBkZWNpcGhlciA9IGNyeXB0b19fZGVmYXVsdC5jcmVhdGVEZWNpcGhlcml2KGBhZXMtJHtrZXkuYWxnb3JpdGhtLmxlbmd0aH0tY3RyYCwga2V5LmRhdGEsIG5ldyBVaW50OEFycmF5KGFsZ29yaXRobS5jb3VudGVyKSk7XG4gICAgICAgIGxldCBkZWMgPSBkZWNpcGhlci51cGRhdGUoZGF0YSk7XG4gICAgICAgIGRlYyA9IEJ1ZmZlci5jb25jYXQoW2RlYywgZGVjaXBoZXIuZmluYWwoKV0pO1xuICAgICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoZGVjKS5idWZmZXI7XG4gICAgfVxuICAgIHN0YXRpYyBhc3luYyBlbmNyeXB0QWVzR0NNKGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIGNvbnN0IGNpcGhlciA9IGNyeXB0b19fZGVmYXVsdC5jcmVhdGVDaXBoZXJpdihgYWVzLSR7a2V5LmFsZ29yaXRobS5sZW5ndGh9LWdjbWAsIGtleS5kYXRhLCBCdWZmZXIuZnJvbShhbGdvcml0aG0uaXYpLCB7XG4gICAgICAgICAgICBhdXRoVGFnTGVuZ3RoOiAoYWxnb3JpdGhtLnRhZ0xlbmd0aCB8fCAxMjgpID4+IDMsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoYWxnb3JpdGhtLmFkZGl0aW9uYWxEYXRhKSB7XG4gICAgICAgICAgICBjaXBoZXIuc2V0QUFEKEJ1ZmZlci5mcm9tKGFsZ29yaXRobS5hZGRpdGlvbmFsRGF0YSkpO1xuICAgICAgICB9XG4gICAgICAgIGxldCBlbmMgPSBjaXBoZXIudXBkYXRlKGRhdGEpO1xuICAgICAgICBlbmMgPSBCdWZmZXIuY29uY2F0KFtlbmMsIGNpcGhlci5maW5hbCgpLCBjaXBoZXIuZ2V0QXV0aFRhZygpXSk7XG4gICAgICAgIGNvbnN0IHJlcyA9IG5ldyBVaW50OEFycmF5KGVuYykuYnVmZmVyO1xuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cbiAgICBzdGF0aWMgYXN5bmMgZGVjcnlwdEFlc0dDTShhbGdvcml0aG0sIGtleSwgZGF0YSkge1xuICAgICAgICBjb25zdCBkZWNpcGhlciA9IGNyeXB0b19fZGVmYXVsdC5jcmVhdGVEZWNpcGhlcml2KGBhZXMtJHtrZXkuYWxnb3JpdGhtLmxlbmd0aH0tZ2NtYCwga2V5LmRhdGEsIG5ldyBVaW50OEFycmF5KGFsZ29yaXRobS5pdikpO1xuICAgICAgICBjb25zdCB0YWdMZW5ndGggPSAoYWxnb3JpdGhtLnRhZ0xlbmd0aCB8fCAxMjgpID4+IDM7XG4gICAgICAgIGNvbnN0IGVuYyA9IGRhdGEuc2xpY2UoMCwgZGF0YS5sZW5ndGggLSB0YWdMZW5ndGgpO1xuICAgICAgICBjb25zdCB0YWcgPSBkYXRhLnNsaWNlKGRhdGEubGVuZ3RoIC0gdGFnTGVuZ3RoKTtcbiAgICAgICAgaWYgKGFsZ29yaXRobS5hZGRpdGlvbmFsRGF0YSkge1xuICAgICAgICAgICAgZGVjaXBoZXIuc2V0QUFEKEJ1ZmZlci5mcm9tKGFsZ29yaXRobS5hZGRpdGlvbmFsRGF0YSkpO1xuICAgICAgICB9XG4gICAgICAgIGRlY2lwaGVyLnNldEF1dGhUYWcodGFnKTtcbiAgICAgICAgbGV0IGRlYyA9IGRlY2lwaGVyLnVwZGF0ZShlbmMpO1xuICAgICAgICBkZWMgPSBCdWZmZXIuY29uY2F0KFtkZWMsIGRlY2lwaGVyLmZpbmFsKCldKTtcbiAgICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGRlYykuYnVmZmVyO1xuICAgIH1cbiAgICBzdGF0aWMgYXN5bmMgZW5jcnlwdEFlc0tXKGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIGNvbnN0IGNpcGhlciA9IGNyeXB0b19fZGVmYXVsdC5jcmVhdGVDaXBoZXJpdihgaWQtYWVzJHtrZXkuYWxnb3JpdGhtLmxlbmd0aH0td3JhcGAsIGtleS5kYXRhLCB0aGlzLkFFU19LV19JVik7XG4gICAgICAgIGxldCBlbmMgPSBjaXBoZXIudXBkYXRlKGRhdGEpO1xuICAgICAgICBlbmMgPSBCdWZmZXIuY29uY2F0KFtlbmMsIGNpcGhlci5maW5hbCgpXSk7XG4gICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShlbmMpLmJ1ZmZlcjtcbiAgICB9XG4gICAgc3RhdGljIGFzeW5jIGRlY3J5cHRBZXNLVyhhbGdvcml0aG0sIGtleSwgZGF0YSkge1xuICAgICAgICBjb25zdCBkZWNpcGhlciA9IGNyeXB0b19fZGVmYXVsdC5jcmVhdGVEZWNpcGhlcml2KGBpZC1hZXMke2tleS5hbGdvcml0aG0ubGVuZ3RofS13cmFwYCwga2V5LmRhdGEsIHRoaXMuQUVTX0tXX0lWKTtcbiAgICAgICAgbGV0IGRlYyA9IGRlY2lwaGVyLnVwZGF0ZShkYXRhKTtcbiAgICAgICAgZGVjID0gQnVmZmVyLmNvbmNhdChbZGVjLCBkZWNpcGhlci5maW5hbCgpXSk7XG4gICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShkZWMpLmJ1ZmZlcjtcbiAgICB9XG4gICAgc3RhdGljIGFzeW5jIGVuY3J5cHRBZXNFQ0IoYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgY29uc3QgY2lwaGVyID0gY3J5cHRvX19kZWZhdWx0LmNyZWF0ZUNpcGhlcml2KGBhZXMtJHtrZXkuYWxnb3JpdGhtLmxlbmd0aH0tZWNiYCwga2V5LmRhdGEsIG5ldyBVaW50OEFycmF5KDApKTtcbiAgICAgICAgbGV0IGVuYyA9IGNpcGhlci51cGRhdGUoZGF0YSk7XG4gICAgICAgIGVuYyA9IEJ1ZmZlci5jb25jYXQoW2VuYywgY2lwaGVyLmZpbmFsKCldKTtcbiAgICAgICAgY29uc3QgcmVzID0gbmV3IFVpbnQ4QXJyYXkoZW5jKS5idWZmZXI7XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxuICAgIHN0YXRpYyBhc3luYyBkZWNyeXB0QWVzRUNCKGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIGNvbnN0IGRlY2lwaGVyID0gY3J5cHRvX19kZWZhdWx0LmNyZWF0ZURlY2lwaGVyaXYoYGFlcy0ke2tleS5hbGdvcml0aG0ubGVuZ3RofS1lY2JgLCBrZXkuZGF0YSwgbmV3IFVpbnQ4QXJyYXkoMCkpO1xuICAgICAgICBsZXQgZGVjID0gZGVjaXBoZXIudXBkYXRlKGRhdGEpO1xuICAgICAgICBkZWMgPSBCdWZmZXIuY29uY2F0KFtkZWMsIGRlY2lwaGVyLmZpbmFsKCldKTtcbiAgICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGRlYykuYnVmZmVyO1xuICAgIH1cbn1cbkFlc0NyeXB0by5BRVNfS1dfSVYgPSBCdWZmZXIuZnJvbShcIkE2QTZBNkE2QTZBNkE2QTZcIiwgXCJoZXhcIik7XG5cbmNvbnN0IGtleVN0b3JhZ2UgPSBuZXcgV2Vha01hcCgpO1xuZnVuY3Rpb24gZ2V0Q3J5cHRvS2V5KGtleSkge1xuICAgIGNvbnN0IHJlcyA9IGtleVN0b3JhZ2UuZ2V0KGtleSk7XG4gICAgaWYgKCFyZXMpIHtcbiAgICAgICAgdGhyb3cgbmV3IGNvcmUuT3BlcmF0aW9uRXJyb3IoXCJDYW5ub3QgZ2V0IENyeXB0b0tleSBmcm9tIHNlY3VyZSBzdG9yYWdlXCIpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzO1xufVxuZnVuY3Rpb24gc2V0Q3J5cHRvS2V5KHZhbHVlKSB7XG4gICAgY29uc3Qga2V5ID0gY29yZS5DcnlwdG9LZXkuY3JlYXRlKHZhbHVlLmFsZ29yaXRobSwgdmFsdWUudHlwZSwgdmFsdWUuZXh0cmFjdGFibGUsIHZhbHVlLnVzYWdlcyk7XG4gICAgT2JqZWN0LmZyZWV6ZShrZXkpO1xuICAgIGtleVN0b3JhZ2Uuc2V0KGtleSwgdmFsdWUpO1xuICAgIHJldHVybiBrZXk7XG59XG5cbmNsYXNzIEFlc0NiY1Byb3ZpZGVyIGV4dGVuZHMgY29yZS5BZXNDYmNQcm92aWRlciB7XG4gICAgYXN5bmMgb25HZW5lcmF0ZUtleShhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgY29uc3Qga2V5ID0gYXdhaXQgQWVzQ3J5cHRvLmdlbmVyYXRlS2V5KHtcbiAgICAgICAgICAgIG5hbWU6IHRoaXMubmFtZSxcbiAgICAgICAgICAgIGxlbmd0aDogYWxnb3JpdGhtLmxlbmd0aCxcbiAgICAgICAgfSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcyk7XG4gICAgICAgIHJldHVybiBzZXRDcnlwdG9LZXkoa2V5KTtcbiAgICB9XG4gICAgYXN5bmMgb25FbmNyeXB0KGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIHJldHVybiBBZXNDcnlwdG8uZW5jcnlwdChhbGdvcml0aG0sIGdldENyeXB0b0tleShrZXkpLCBuZXcgVWludDhBcnJheShkYXRhKSk7XG4gICAgfVxuICAgIGFzeW5jIG9uRGVjcnlwdChhbGdvcml0aG0sIGtleSwgZGF0YSkge1xuICAgICAgICByZXR1cm4gQWVzQ3J5cHRvLmRlY3J5cHQoYWxnb3JpdGhtLCBnZXRDcnlwdG9LZXkoa2V5KSwgbmV3IFVpbnQ4QXJyYXkoZGF0YSkpO1xuICAgIH1cbiAgICBhc3luYyBvbkV4cG9ydEtleShmb3JtYXQsIGtleSkge1xuICAgICAgICByZXR1cm4gQWVzQ3J5cHRvLmV4cG9ydEtleShmb3JtYXQsIGdldENyeXB0b0tleShrZXkpKTtcbiAgICB9XG4gICAgYXN5bmMgb25JbXBvcnRLZXkoZm9ybWF0LCBrZXlEYXRhLCBhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgY29uc3Qga2V5ID0gYXdhaXQgQWVzQ3J5cHRvLmltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIHsgbmFtZTogYWxnb3JpdGhtLm5hbWUgfSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcyk7XG4gICAgICAgIHJldHVybiBzZXRDcnlwdG9LZXkoa2V5KTtcbiAgICB9XG4gICAgY2hlY2tDcnlwdG9LZXkoa2V5LCBrZXlVc2FnZSkge1xuICAgICAgICBzdXBlci5jaGVja0NyeXB0b0tleShrZXksIGtleVVzYWdlKTtcbiAgICAgICAgaWYgKCEoZ2V0Q3J5cHRvS2V5KGtleSkgaW5zdGFuY2VvZiBBZXNDcnlwdG9LZXkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwia2V5OiBJcyBub3QgYSBBZXNDcnlwdG9LZXlcIik7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmNvbnN0IHplcm8gPSBCdWZmZXIuZnJvbShbMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMF0pO1xuY29uc3QgcmIgPSBCdWZmZXIuZnJvbShbMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMTM1XSk7XG5jb25zdCBibG9ja1NpemUgPSAxNjtcbmZ1bmN0aW9uIGJpdFNoaWZ0TGVmdChidWZmZXIpIHtcbiAgICBjb25zdCBzaGlmdGVkID0gQnVmZmVyLmFsbG9jKGJ1ZmZlci5sZW5ndGgpO1xuICAgIGNvbnN0IGxhc3QgPSBidWZmZXIubGVuZ3RoIC0gMTtcbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgbGFzdDsgaW5kZXgrKykge1xuICAgICAgICBzaGlmdGVkW2luZGV4XSA9IGJ1ZmZlcltpbmRleF0gPDwgMTtcbiAgICAgICAgaWYgKGJ1ZmZlcltpbmRleCArIDFdICYgMHg4MCkge1xuICAgICAgICAgICAgc2hpZnRlZFtpbmRleF0gKz0gMHgwMTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzaGlmdGVkW2xhc3RdID0gYnVmZmVyW2xhc3RdIDw8IDE7XG4gICAgcmV0dXJuIHNoaWZ0ZWQ7XG59XG5mdW5jdGlvbiB4b3IoYSwgYikge1xuICAgIGNvbnN0IGxlbmd0aCA9IE1hdGgubWluKGEubGVuZ3RoLCBiLmxlbmd0aCk7XG4gICAgY29uc3Qgb3V0cHV0ID0gQnVmZmVyLmFsbG9jKGxlbmd0aCk7XG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICBvdXRwdXRbaW5kZXhdID0gYVtpbmRleF0gXiBiW2luZGV4XTtcbiAgICB9XG4gICAgcmV0dXJuIG91dHB1dDtcbn1cbmZ1bmN0aW9uIGFlcyhrZXksIG1lc3NhZ2UpIHtcbiAgICBjb25zdCBjaXBoZXIgPSBjcnlwdG8uY3JlYXRlQ2lwaGVyaXYoYGFlcyR7a2V5Lmxlbmd0aCA8PCAzfWAsIGtleSwgemVybyk7XG4gICAgY29uc3QgcmVzdWx0ID0gY2lwaGVyLnVwZGF0ZShtZXNzYWdlKTtcbiAgICBjaXBoZXIuZmluYWwoKTtcbiAgICByZXR1cm4gcmVzdWx0O1xufVxuZnVuY3Rpb24gZ2V0TWVzc2FnZUJsb2NrKG1lc3NhZ2UsIGJsb2NrSW5kZXgpIHtcbiAgICBjb25zdCBibG9jayA9IEJ1ZmZlci5hbGxvYyhibG9ja1NpemUpO1xuICAgIGNvbnN0IHN0YXJ0ID0gYmxvY2tJbmRleCAqIGJsb2NrU2l6ZTtcbiAgICBjb25zdCBlbmQgPSBzdGFydCArIGJsb2NrU2l6ZTtcbiAgICBtZXNzYWdlLmNvcHkoYmxvY2ssIDAsIHN0YXJ0LCBlbmQpO1xuICAgIHJldHVybiBibG9jaztcbn1cbmZ1bmN0aW9uIGdldFBhZGRlZE1lc3NhZ2VCbG9jayhtZXNzYWdlLCBibG9ja0luZGV4KSB7XG4gICAgY29uc3QgYmxvY2sgPSBCdWZmZXIuYWxsb2MoYmxvY2tTaXplKTtcbiAgICBjb25zdCBzdGFydCA9IGJsb2NrSW5kZXggKiBibG9ja1NpemU7XG4gICAgY29uc3QgZW5kID0gbWVzc2FnZS5sZW5ndGg7XG4gICAgYmxvY2suZmlsbCgwKTtcbiAgICBtZXNzYWdlLmNvcHkoYmxvY2ssIDAsIHN0YXJ0LCBlbmQpO1xuICAgIGJsb2NrW2VuZCAtIHN0YXJ0XSA9IDB4ODA7XG4gICAgcmV0dXJuIGJsb2NrO1xufVxuZnVuY3Rpb24gZ2VuZXJhdGVTdWJrZXlzKGtleSkge1xuICAgIGNvbnN0IGwgPSBhZXMoa2V5LCB6ZXJvKTtcbiAgICBsZXQgc3Via2V5MSA9IGJpdFNoaWZ0TGVmdChsKTtcbiAgICBpZiAobFswXSAmIDB4ODApIHtcbiAgICAgICAgc3Via2V5MSA9IHhvcihzdWJrZXkxLCByYik7XG4gICAgfVxuICAgIGxldCBzdWJrZXkyID0gYml0U2hpZnRMZWZ0KHN1YmtleTEpO1xuICAgIGlmIChzdWJrZXkxWzBdICYgMHg4MCkge1xuICAgICAgICBzdWJrZXkyID0geG9yKHN1YmtleTIsIHJiKTtcbiAgICB9XG4gICAgcmV0dXJuIHsgc3Via2V5MSwgc3Via2V5MiB9O1xufVxuZnVuY3Rpb24gYWVzQ21hYyhrZXksIG1lc3NhZ2UpIHtcbiAgICBjb25zdCBzdWJrZXlzID0gZ2VuZXJhdGVTdWJrZXlzKGtleSk7XG4gICAgbGV0IGJsb2NrQ291bnQgPSBNYXRoLmNlaWwobWVzc2FnZS5sZW5ndGggLyBibG9ja1NpemUpO1xuICAgIGxldCBsYXN0QmxvY2tDb21wbGV0ZUZsYWc7XG4gICAgbGV0IGxhc3RCbG9jaztcbiAgICBpZiAoYmxvY2tDb3VudCA9PT0gMCkge1xuICAgICAgICBibG9ja0NvdW50ID0gMTtcbiAgICAgICAgbGFzdEJsb2NrQ29tcGxldGVGbGFnID0gZmFsc2U7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBsYXN0QmxvY2tDb21wbGV0ZUZsYWcgPSAobWVzc2FnZS5sZW5ndGggJSBibG9ja1NpemUgPT09IDApO1xuICAgIH1cbiAgICBjb25zdCBsYXN0QmxvY2tJbmRleCA9IGJsb2NrQ291bnQgLSAxO1xuICAgIGlmIChsYXN0QmxvY2tDb21wbGV0ZUZsYWcpIHtcbiAgICAgICAgbGFzdEJsb2NrID0geG9yKGdldE1lc3NhZ2VCbG9jayhtZXNzYWdlLCBsYXN0QmxvY2tJbmRleCksIHN1YmtleXMuc3Via2V5MSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBsYXN0QmxvY2sgPSB4b3IoZ2V0UGFkZGVkTWVzc2FnZUJsb2NrKG1lc3NhZ2UsIGxhc3RCbG9ja0luZGV4KSwgc3Via2V5cy5zdWJrZXkyKTtcbiAgICB9XG4gICAgbGV0IHggPSB6ZXJvO1xuICAgIGxldCB5O1xuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBsYXN0QmxvY2tJbmRleDsgaW5kZXgrKykge1xuICAgICAgICB5ID0geG9yKHgsIGdldE1lc3NhZ2VCbG9jayhtZXNzYWdlLCBpbmRleCkpO1xuICAgICAgICB4ID0gYWVzKGtleSwgeSk7XG4gICAgfVxuICAgIHkgPSB4b3IobGFzdEJsb2NrLCB4KTtcbiAgICByZXR1cm4gYWVzKGtleSwgeSk7XG59XG5jbGFzcyBBZXNDbWFjUHJvdmlkZXIgZXh0ZW5kcyBjb3JlLkFlc0NtYWNQcm92aWRlciB7XG4gICAgYXN5bmMgb25HZW5lcmF0ZUtleShhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgY29uc3Qga2V5ID0gYXdhaXQgQWVzQ3J5cHRvLmdlbmVyYXRlS2V5KHtcbiAgICAgICAgICAgIG5hbWU6IHRoaXMubmFtZSxcbiAgICAgICAgICAgIGxlbmd0aDogYWxnb3JpdGhtLmxlbmd0aCxcbiAgICAgICAgfSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcyk7XG4gICAgICAgIHJldHVybiBzZXRDcnlwdG9LZXkoa2V5KTtcbiAgICB9XG4gICAgYXN5bmMgb25TaWduKGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGFlc0NtYWMoZ2V0Q3J5cHRvS2V5KGtleSkuZGF0YSwgQnVmZmVyLmZyb20oZGF0YSkpO1xuICAgICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkocmVzdWx0KS5idWZmZXI7XG4gICAgfVxuICAgIGFzeW5jIG9uVmVyaWZ5KGFsZ29yaXRobSwga2V5LCBzaWduYXR1cmUsIGRhdGEpIHtcbiAgICAgICAgY29uc3Qgc2lnbmF0dXJlMiA9IGF3YWl0IHRoaXMuc2lnbihhbGdvcml0aG0sIGtleSwgZGF0YSk7XG4gICAgICAgIHJldHVybiBCdWZmZXIuZnJvbShzaWduYXR1cmUpLmNvbXBhcmUoQnVmZmVyLmZyb20oc2lnbmF0dXJlMikpID09PSAwO1xuICAgIH1cbiAgICBhc3luYyBvbkV4cG9ydEtleShmb3JtYXQsIGtleSkge1xuICAgICAgICByZXR1cm4gQWVzQ3J5cHRvLmV4cG9ydEtleShmb3JtYXQsIGdldENyeXB0b0tleShrZXkpKTtcbiAgICB9XG4gICAgYXN5bmMgb25JbXBvcnRLZXkoZm9ybWF0LCBrZXlEYXRhLCBhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgQWVzQ3J5cHRvLmltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIHsgbmFtZTogYWxnb3JpdGhtLm5hbWUgfSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcyk7XG4gICAgICAgIHJldHVybiBzZXRDcnlwdG9LZXkocmVzKTtcbiAgICB9XG4gICAgY2hlY2tDcnlwdG9LZXkoa2V5LCBrZXlVc2FnZSkge1xuICAgICAgICBzdXBlci5jaGVja0NyeXB0b0tleShrZXksIGtleVVzYWdlKTtcbiAgICAgICAgaWYgKCEoZ2V0Q3J5cHRvS2V5KGtleSkgaW5zdGFuY2VvZiBBZXNDcnlwdG9LZXkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwia2V5OiBJcyBub3QgYSBBZXNDcnlwdG9LZXlcIik7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmNsYXNzIEFlc0N0clByb3ZpZGVyIGV4dGVuZHMgY29yZS5BZXNDdHJQcm92aWRlciB7XG4gICAgYXN5bmMgb25HZW5lcmF0ZUtleShhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgY29uc3Qga2V5ID0gYXdhaXQgQWVzQ3J5cHRvLmdlbmVyYXRlS2V5KHtcbiAgICAgICAgICAgIG5hbWU6IHRoaXMubmFtZSxcbiAgICAgICAgICAgIGxlbmd0aDogYWxnb3JpdGhtLmxlbmd0aCxcbiAgICAgICAgfSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcyk7XG4gICAgICAgIHJldHVybiBzZXRDcnlwdG9LZXkoa2V5KTtcbiAgICB9XG4gICAgYXN5bmMgb25FbmNyeXB0KGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIHJldHVybiBBZXNDcnlwdG8uZW5jcnlwdChhbGdvcml0aG0sIGdldENyeXB0b0tleShrZXkpLCBuZXcgVWludDhBcnJheShkYXRhKSk7XG4gICAgfVxuICAgIGFzeW5jIG9uRGVjcnlwdChhbGdvcml0aG0sIGtleSwgZGF0YSkge1xuICAgICAgICByZXR1cm4gQWVzQ3J5cHRvLmRlY3J5cHQoYWxnb3JpdGhtLCBnZXRDcnlwdG9LZXkoa2V5KSwgbmV3IFVpbnQ4QXJyYXkoZGF0YSkpO1xuICAgIH1cbiAgICBhc3luYyBvbkV4cG9ydEtleShmb3JtYXQsIGtleSkge1xuICAgICAgICByZXR1cm4gQWVzQ3J5cHRvLmV4cG9ydEtleShmb3JtYXQsIGdldENyeXB0b0tleShrZXkpKTtcbiAgICB9XG4gICAgYXN5bmMgb25JbXBvcnRLZXkoZm9ybWF0LCBrZXlEYXRhLCBhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgQWVzQ3J5cHRvLmltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIHsgbmFtZTogYWxnb3JpdGhtLm5hbWUgfSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcyk7XG4gICAgICAgIHJldHVybiBzZXRDcnlwdG9LZXkocmVzKTtcbiAgICB9XG4gICAgY2hlY2tDcnlwdG9LZXkoa2V5LCBrZXlVc2FnZSkge1xuICAgICAgICBzdXBlci5jaGVja0NyeXB0b0tleShrZXksIGtleVVzYWdlKTtcbiAgICAgICAgaWYgKCEoZ2V0Q3J5cHRvS2V5KGtleSkgaW5zdGFuY2VvZiBBZXNDcnlwdG9LZXkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwia2V5OiBJcyBub3QgYSBBZXNDcnlwdG9LZXlcIik7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmNsYXNzIEFlc0djbVByb3ZpZGVyIGV4dGVuZHMgY29yZS5BZXNHY21Qcm92aWRlciB7XG4gICAgYXN5bmMgb25HZW5lcmF0ZUtleShhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgY29uc3Qga2V5ID0gYXdhaXQgQWVzQ3J5cHRvLmdlbmVyYXRlS2V5KHtcbiAgICAgICAgICAgIG5hbWU6IHRoaXMubmFtZSxcbiAgICAgICAgICAgIGxlbmd0aDogYWxnb3JpdGhtLmxlbmd0aCxcbiAgICAgICAgfSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcyk7XG4gICAgICAgIHJldHVybiBzZXRDcnlwdG9LZXkoa2V5KTtcbiAgICB9XG4gICAgYXN5bmMgb25FbmNyeXB0KGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIHJldHVybiBBZXNDcnlwdG8uZW5jcnlwdChhbGdvcml0aG0sIGdldENyeXB0b0tleShrZXkpLCBuZXcgVWludDhBcnJheShkYXRhKSk7XG4gICAgfVxuICAgIGFzeW5jIG9uRGVjcnlwdChhbGdvcml0aG0sIGtleSwgZGF0YSkge1xuICAgICAgICByZXR1cm4gQWVzQ3J5cHRvLmRlY3J5cHQoYWxnb3JpdGhtLCBnZXRDcnlwdG9LZXkoa2V5KSwgbmV3IFVpbnQ4QXJyYXkoZGF0YSkpO1xuICAgIH1cbiAgICBhc3luYyBvbkV4cG9ydEtleShmb3JtYXQsIGtleSkge1xuICAgICAgICByZXR1cm4gQWVzQ3J5cHRvLmV4cG9ydEtleShmb3JtYXQsIGdldENyeXB0b0tleShrZXkpKTtcbiAgICB9XG4gICAgYXN5bmMgb25JbXBvcnRLZXkoZm9ybWF0LCBrZXlEYXRhLCBhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgQWVzQ3J5cHRvLmltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIHsgbmFtZTogYWxnb3JpdGhtLm5hbWUgfSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcyk7XG4gICAgICAgIHJldHVybiBzZXRDcnlwdG9LZXkocmVzKTtcbiAgICB9XG4gICAgY2hlY2tDcnlwdG9LZXkoa2V5LCBrZXlVc2FnZSkge1xuICAgICAgICBzdXBlci5jaGVja0NyeXB0b0tleShrZXksIGtleVVzYWdlKTtcbiAgICAgICAgaWYgKCEoZ2V0Q3J5cHRvS2V5KGtleSkgaW5zdGFuY2VvZiBBZXNDcnlwdG9LZXkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwia2V5OiBJcyBub3QgYSBBZXNDcnlwdG9LZXlcIik7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmNsYXNzIEFlc0t3UHJvdmlkZXIgZXh0ZW5kcyBjb3JlLkFlc0t3UHJvdmlkZXIge1xuICAgIGFzeW5jIG9uR2VuZXJhdGVLZXkoYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKSB7XG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IEFlc0NyeXB0by5nZW5lcmF0ZUtleSh7XG4gICAgICAgICAgICBuYW1lOiB0aGlzLm5hbWUsXG4gICAgICAgICAgICBsZW5ndGg6IGFsZ29yaXRobS5sZW5ndGgsXG4gICAgICAgIH0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpO1xuICAgICAgICByZXR1cm4gc2V0Q3J5cHRvS2V5KHJlcyk7XG4gICAgfVxuICAgIGFzeW5jIG9uRXhwb3J0S2V5KGZvcm1hdCwga2V5KSB7XG4gICAgICAgIHJldHVybiBBZXNDcnlwdG8uZXhwb3J0S2V5KGZvcm1hdCwgZ2V0Q3J5cHRvS2V5KGtleSkpO1xuICAgIH1cbiAgICBhc3luYyBvbkltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBBZXNDcnlwdG8uaW1wb3J0S2V5KGZvcm1hdCwga2V5RGF0YSwgeyBuYW1lOiBhbGdvcml0aG0ubmFtZSB9LCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgcmV0dXJuIHNldENyeXB0b0tleShyZXMpO1xuICAgIH1cbiAgICBhc3luYyBvbkVuY3J5cHQoYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgcmV0dXJuIEFlc0NyeXB0by5lbmNyeXB0KGFsZ29yaXRobSwgZ2V0Q3J5cHRvS2V5KGtleSksIG5ldyBVaW50OEFycmF5KGRhdGEpKTtcbiAgICB9XG4gICAgYXN5bmMgb25EZWNyeXB0KGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIHJldHVybiBBZXNDcnlwdG8uZGVjcnlwdChhbGdvcml0aG0sIGdldENyeXB0b0tleShrZXkpLCBuZXcgVWludDhBcnJheShkYXRhKSk7XG4gICAgfVxuICAgIGNoZWNrQ3J5cHRvS2V5KGtleSwga2V5VXNhZ2UpIHtcbiAgICAgICAgc3VwZXIuY2hlY2tDcnlwdG9LZXkoa2V5LCBrZXlVc2FnZSk7XG4gICAgICAgIGlmICghKGdldENyeXB0b0tleShrZXkpIGluc3RhbmNlb2YgQWVzQ3J5cHRvS2V5KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImtleTogSXMgbm90IGEgQWVzQ3J5cHRvS2V5XCIpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5jbGFzcyBBZXNFY2JQcm92aWRlciBleHRlbmRzIGNvcmUuQWVzRWNiUHJvdmlkZXIge1xuICAgIGFzeW5jIG9uR2VuZXJhdGVLZXkoYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IGF3YWl0IEFlc0NyeXB0by5nZW5lcmF0ZUtleSh7XG4gICAgICAgICAgICBuYW1lOiB0aGlzLm5hbWUsXG4gICAgICAgICAgICBsZW5ndGg6IGFsZ29yaXRobS5sZW5ndGgsXG4gICAgICAgIH0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpO1xuICAgICAgICByZXR1cm4gc2V0Q3J5cHRvS2V5KGtleSk7XG4gICAgfVxuICAgIGFzeW5jIG9uRW5jcnlwdChhbGdvcml0aG0sIGtleSwgZGF0YSkge1xuICAgICAgICByZXR1cm4gQWVzQ3J5cHRvLmVuY3J5cHQoYWxnb3JpdGhtLCBnZXRDcnlwdG9LZXkoa2V5KSwgbmV3IFVpbnQ4QXJyYXkoZGF0YSkpO1xuICAgIH1cbiAgICBhc3luYyBvbkRlY3J5cHQoYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgcmV0dXJuIEFlc0NyeXB0by5kZWNyeXB0KGFsZ29yaXRobSwgZ2V0Q3J5cHRvS2V5KGtleSksIG5ldyBVaW50OEFycmF5KGRhdGEpKTtcbiAgICB9XG4gICAgYXN5bmMgb25FeHBvcnRLZXkoZm9ybWF0LCBrZXkpIHtcbiAgICAgICAgcmV0dXJuIEFlc0NyeXB0by5leHBvcnRLZXkoZm9ybWF0LCBnZXRDcnlwdG9LZXkoa2V5KSk7XG4gICAgfVxuICAgIGFzeW5jIG9uSW1wb3J0S2V5KGZvcm1hdCwga2V5RGF0YSwgYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKSB7XG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IEFlc0NyeXB0by5pbXBvcnRLZXkoZm9ybWF0LCBrZXlEYXRhLCB7IG5hbWU6IGFsZ29yaXRobS5uYW1lIH0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpO1xuICAgICAgICByZXR1cm4gc2V0Q3J5cHRvS2V5KHJlcyk7XG4gICAgfVxuICAgIGNoZWNrQ3J5cHRvS2V5KGtleSwga2V5VXNhZ2UpIHtcbiAgICAgICAgc3VwZXIuY2hlY2tDcnlwdG9LZXkoa2V5LCBrZXlVc2FnZSk7XG4gICAgICAgIGlmICghKGdldENyeXB0b0tleShrZXkpIGluc3RhbmNlb2YgQWVzQ3J5cHRvS2V5KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImtleTogSXMgbm90IGEgQWVzQ3J5cHRvS2V5XCIpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5jbGFzcyBEZXNDcnlwdG9LZXkgZXh0ZW5kcyBTeW1tZXRyaWNLZXkge1xuICAgIGdldCBhbGcoKSB7XG4gICAgICAgIHN3aXRjaCAodGhpcy5hbGdvcml0aG0ubmFtZS50b1VwcGVyQ2FzZSgpKSB7XG4gICAgICAgICAgICBjYXNlIFwiREVTLUNCQ1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgREVTLUNCQ2A7XG4gICAgICAgICAgICBjYXNlIFwiREVTLUVERTMtQ0JDXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGAzREVTLUNCQ2A7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBjb3JlLkFsZ29yaXRobUVycm9yKFwiVW5zdXBwb3J0ZWQgYWxnb3JpdGhtIG5hbWVcIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc2V0IGFsZyh2YWx1ZSkge1xuICAgIH1cbn1cbl9fZGVjb3JhdGUoW1xuICAgIEpzb25Qcm9wKHsgbmFtZTogXCJrXCIsIGNvbnZlcnRlcjogSnNvbkJhc2U2NFVybENvbnZlcnRlciB9KVxuXSwgRGVzQ3J5cHRvS2V5LnByb3RvdHlwZSwgXCJkYXRhXCIsIHZvaWQgMCk7XG5cbmNsYXNzIERlc0NyeXB0byB7XG4gICAgc3RhdGljIGFzeW5jIGdlbmVyYXRlS2V5KGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCBrZXkgPSBuZXcgRGVzQ3J5cHRvS2V5KCk7XG4gICAgICAgIGtleS5hbGdvcml0aG0gPSBhbGdvcml0aG07XG4gICAgICAgIGtleS5leHRyYWN0YWJsZSA9IGV4dHJhY3RhYmxlO1xuICAgICAgICBrZXkudXNhZ2VzID0ga2V5VXNhZ2VzO1xuICAgICAgICBrZXkuZGF0YSA9IGNyeXB0b19fZGVmYXVsdC5yYW5kb21CeXRlcyhhbGdvcml0aG0ubGVuZ3RoID4+IDMpO1xuICAgICAgICByZXR1cm4ga2V5O1xuICAgIH1cbiAgICBzdGF0aWMgYXN5bmMgZXhwb3J0S2V5KGZvcm1hdCwga2V5KSB7XG4gICAgICAgIHN3aXRjaCAoZm9ybWF0LnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICAgIGNhc2UgXCJqd2tcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gSnNvblNlcmlhbGl6ZXIudG9KU09OKGtleSk7XG4gICAgICAgICAgICBjYXNlIFwicmF3XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGtleS5kYXRhKS5idWZmZXI7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBjb3JlLk9wZXJhdGlvbkVycm9yKFwiZm9ybWF0OiBNdXN0IGJlICdqd2snIG9yICdyYXcnXCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHN0YXRpYyBhc3luYyBpbXBvcnRLZXkoZm9ybWF0LCBrZXlEYXRhLCBhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgbGV0IGtleTtcbiAgICAgICAgc3dpdGNoIChmb3JtYXQudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgY2FzZSBcImp3a1wiOlxuICAgICAgICAgICAgICAgIGtleSA9IEpzb25QYXJzZXIuZnJvbUpTT04oa2V5RGF0YSwgeyB0YXJnZXRTY2hlbWE6IERlc0NyeXB0b0tleSB9KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJyYXdcIjpcbiAgICAgICAgICAgICAgICBrZXkgPSBuZXcgRGVzQ3J5cHRvS2V5KCk7XG4gICAgICAgICAgICAgICAga2V5LmRhdGEgPSBCdWZmZXIuZnJvbShrZXlEYXRhKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IGNvcmUuT3BlcmF0aW9uRXJyb3IoXCJmb3JtYXQ6IE11c3QgYmUgJ2p3aycgb3IgJ3JhdydcIik7XG4gICAgICAgIH1cbiAgICAgICAga2V5LmFsZ29yaXRobSA9IGFsZ29yaXRobTtcbiAgICAgICAga2V5LmV4dHJhY3RhYmxlID0gZXh0cmFjdGFibGU7XG4gICAgICAgIGtleS51c2FnZXMgPSBrZXlVc2FnZXM7XG4gICAgICAgIHJldHVybiBrZXk7XG4gICAgfVxuICAgIHN0YXRpYyBhc3luYyBlbmNyeXB0KGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIHN3aXRjaCAoYWxnb3JpdGhtLm5hbWUudG9VcHBlckNhc2UoKSkge1xuICAgICAgICAgICAgY2FzZSBcIkRFUy1DQkNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lbmNyeXB0RGVzQ0JDKGFsZ29yaXRobSwga2V5LCBCdWZmZXIuZnJvbShkYXRhKSk7XG4gICAgICAgICAgICBjYXNlIFwiREVTLUVERTMtQ0JDXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW5jcnlwdERlc0VERTNDQkMoYWxnb3JpdGhtLCBrZXksIEJ1ZmZlci5mcm9tKGRhdGEpKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IGNvcmUuT3BlcmF0aW9uRXJyb3IoXCJhbGdvcml0aG06IElzIG5vdCByZWNvZ25pemVkXCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHN0YXRpYyBhc3luYyBkZWNyeXB0KGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIGlmICghKGtleSBpbnN0YW5jZW9mIERlc0NyeXB0b0tleSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImtleTogSXMgbm90IERlc0NyeXB0b0tleVwiKTtcbiAgICAgICAgfVxuICAgICAgICBzd2l0Y2ggKGFsZ29yaXRobS5uYW1lLnRvVXBwZXJDYXNlKCkpIHtcbiAgICAgICAgICAgIGNhc2UgXCJERVMtQ0JDXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGVjcnlwdERlc0NCQyhhbGdvcml0aG0sIGtleSwgQnVmZmVyLmZyb20oZGF0YSkpO1xuICAgICAgICAgICAgY2FzZSBcIkRFUy1FREUzLUNCQ1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmRlY3J5cHREZXNFREUzQ0JDKGFsZ29yaXRobSwga2V5LCBCdWZmZXIuZnJvbShkYXRhKSk7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBjb3JlLk9wZXJhdGlvbkVycm9yKFwiYWxnb3JpdGhtOiBJcyBub3QgcmVjb2duaXplZFwiKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzdGF0aWMgYXN5bmMgZW5jcnlwdERlc0NCQyhhbGdvcml0aG0sIGtleSwgZGF0YSkge1xuICAgICAgICBjb25zdCBjaXBoZXIgPSBjcnlwdG9fX2RlZmF1bHQuY3JlYXRlQ2lwaGVyaXYoYGRlcy1jYmNgLCBrZXkuZGF0YSwgbmV3IFVpbnQ4QXJyYXkoYWxnb3JpdGhtLml2KSk7XG4gICAgICAgIGxldCBlbmMgPSBjaXBoZXIudXBkYXRlKGRhdGEpO1xuICAgICAgICBlbmMgPSBCdWZmZXIuY29uY2F0KFtlbmMsIGNpcGhlci5maW5hbCgpXSk7XG4gICAgICAgIGNvbnN0IHJlcyA9IG5ldyBVaW50OEFycmF5KGVuYykuYnVmZmVyO1xuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cbiAgICBzdGF0aWMgYXN5bmMgZGVjcnlwdERlc0NCQyhhbGdvcml0aG0sIGtleSwgZGF0YSkge1xuICAgICAgICBjb25zdCBkZWNpcGhlciA9IGNyeXB0b19fZGVmYXVsdC5jcmVhdGVEZWNpcGhlcml2KGBkZXMtY2JjYCwga2V5LmRhdGEsIG5ldyBVaW50OEFycmF5KGFsZ29yaXRobS5pdikpO1xuICAgICAgICBsZXQgZGVjID0gZGVjaXBoZXIudXBkYXRlKGRhdGEpO1xuICAgICAgICBkZWMgPSBCdWZmZXIuY29uY2F0KFtkZWMsIGRlY2lwaGVyLmZpbmFsKCldKTtcbiAgICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGRlYykuYnVmZmVyO1xuICAgIH1cbiAgICBzdGF0aWMgYXN5bmMgZW5jcnlwdERlc0VERTNDQkMoYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgY29uc3QgY2lwaGVyID0gY3J5cHRvX19kZWZhdWx0LmNyZWF0ZUNpcGhlcml2KGBkZXMtZWRlMy1jYmNgLCBrZXkuZGF0YSwgQnVmZmVyLmZyb20oYWxnb3JpdGhtLml2KSk7XG4gICAgICAgIGxldCBlbmMgPSBjaXBoZXIudXBkYXRlKGRhdGEpO1xuICAgICAgICBlbmMgPSBCdWZmZXIuY29uY2F0KFtlbmMsIGNpcGhlci5maW5hbCgpXSk7XG4gICAgICAgIGNvbnN0IHJlcyA9IG5ldyBVaW50OEFycmF5KGVuYykuYnVmZmVyO1xuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cbiAgICBzdGF0aWMgYXN5bmMgZGVjcnlwdERlc0VERTNDQkMoYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgY29uc3QgZGVjaXBoZXIgPSBjcnlwdG9fX2RlZmF1bHQuY3JlYXRlRGVjaXBoZXJpdihgZGVzLWVkZTMtY2JjYCwga2V5LmRhdGEsIG5ldyBVaW50OEFycmF5KGFsZ29yaXRobS5pdikpO1xuICAgICAgICBsZXQgZGVjID0gZGVjaXBoZXIudXBkYXRlKGRhdGEpO1xuICAgICAgICBkZWMgPSBCdWZmZXIuY29uY2F0KFtkZWMsIGRlY2lwaGVyLmZpbmFsKCldKTtcbiAgICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGRlYykuYnVmZmVyO1xuICAgIH1cbn1cblxuY2xhc3MgRGVzQ2JjUHJvdmlkZXIgZXh0ZW5kcyBjb3JlLkRlc1Byb3ZpZGVyIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5rZXlTaXplQml0cyA9IDY0O1xuICAgICAgICB0aGlzLml2U2l6ZSA9IDg7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiREVTLUNCQ1wiO1xuICAgIH1cbiAgICBhc3luYyBvbkdlbmVyYXRlS2V5KGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCBrZXkgPSBhd2FpdCBEZXNDcnlwdG8uZ2VuZXJhdGVLZXkoe1xuICAgICAgICAgICAgbmFtZTogdGhpcy5uYW1lLFxuICAgICAgICAgICAgbGVuZ3RoOiB0aGlzLmtleVNpemVCaXRzLFxuICAgICAgICB9LCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgcmV0dXJuIHNldENyeXB0b0tleShrZXkpO1xuICAgIH1cbiAgICBhc3luYyBvbkVuY3J5cHQoYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgcmV0dXJuIERlc0NyeXB0by5lbmNyeXB0KGFsZ29yaXRobSwgZ2V0Q3J5cHRvS2V5KGtleSksIG5ldyBVaW50OEFycmF5KGRhdGEpKTtcbiAgICB9XG4gICAgYXN5bmMgb25EZWNyeXB0KGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIHJldHVybiBEZXNDcnlwdG8uZGVjcnlwdChhbGdvcml0aG0sIGdldENyeXB0b0tleShrZXkpLCBuZXcgVWludDhBcnJheShkYXRhKSk7XG4gICAgfVxuICAgIGFzeW5jIG9uRXhwb3J0S2V5KGZvcm1hdCwga2V5KSB7XG4gICAgICAgIHJldHVybiBEZXNDcnlwdG8uZXhwb3J0S2V5KGZvcm1hdCwgZ2V0Q3J5cHRvS2V5KGtleSkpO1xuICAgIH1cbiAgICBhc3luYyBvbkltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCBrZXkgPSBhd2FpdCBEZXNDcnlwdG8uaW1wb3J0S2V5KGZvcm1hdCwga2V5RGF0YSwgeyBuYW1lOiB0aGlzLm5hbWUsIGxlbmd0aDogdGhpcy5rZXlTaXplQml0cyB9LCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgaWYgKGtleS5kYXRhLmxlbmd0aCAhPT0gKHRoaXMua2V5U2l6ZUJpdHMgPj4gMykpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBjb3JlLk9wZXJhdGlvbkVycm9yKFwia2V5RGF0YTogV3Jvbmcga2V5IHNpemVcIik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNldENyeXB0b0tleShrZXkpO1xuICAgIH1cbiAgICBjaGVja0NyeXB0b0tleShrZXksIGtleVVzYWdlKSB7XG4gICAgICAgIHN1cGVyLmNoZWNrQ3J5cHRvS2V5KGtleSwga2V5VXNhZ2UpO1xuICAgICAgICBpZiAoIShnZXRDcnlwdG9LZXkoa2V5KSBpbnN0YW5jZW9mIERlc0NyeXB0b0tleSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJrZXk6IElzIG5vdCBhIERlc0NyeXB0b0tleVwiKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuY2xhc3MgRGVzRWRlM0NiY1Byb3ZpZGVyIGV4dGVuZHMgY29yZS5EZXNQcm92aWRlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMua2V5U2l6ZUJpdHMgPSAxOTI7XG4gICAgICAgIHRoaXMuaXZTaXplID0gODtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJERVMtRURFMy1DQkNcIjtcbiAgICB9XG4gICAgYXN5bmMgb25HZW5lcmF0ZUtleShhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgY29uc3Qga2V5ID0gYXdhaXQgRGVzQ3J5cHRvLmdlbmVyYXRlS2V5KHtcbiAgICAgICAgICAgIG5hbWU6IHRoaXMubmFtZSxcbiAgICAgICAgICAgIGxlbmd0aDogdGhpcy5rZXlTaXplQml0cyxcbiAgICAgICAgfSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcyk7XG4gICAgICAgIHJldHVybiBzZXRDcnlwdG9LZXkoa2V5KTtcbiAgICB9XG4gICAgYXN5bmMgb25FbmNyeXB0KGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIHJldHVybiBEZXNDcnlwdG8uZW5jcnlwdChhbGdvcml0aG0sIGdldENyeXB0b0tleShrZXkpLCBuZXcgVWludDhBcnJheShkYXRhKSk7XG4gICAgfVxuICAgIGFzeW5jIG9uRGVjcnlwdChhbGdvcml0aG0sIGtleSwgZGF0YSkge1xuICAgICAgICByZXR1cm4gRGVzQ3J5cHRvLmRlY3J5cHQoYWxnb3JpdGhtLCBnZXRDcnlwdG9LZXkoa2V5KSwgbmV3IFVpbnQ4QXJyYXkoZGF0YSkpO1xuICAgIH1cbiAgICBhc3luYyBvbkV4cG9ydEtleShmb3JtYXQsIGtleSkge1xuICAgICAgICByZXR1cm4gRGVzQ3J5cHRvLmV4cG9ydEtleShmb3JtYXQsIGdldENyeXB0b0tleShrZXkpKTtcbiAgICB9XG4gICAgYXN5bmMgb25JbXBvcnRLZXkoZm9ybWF0LCBrZXlEYXRhLCBhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgY29uc3Qga2V5ID0gYXdhaXQgRGVzQ3J5cHRvLmltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIHsgbmFtZTogdGhpcy5uYW1lLCBsZW5ndGg6IHRoaXMua2V5U2l6ZUJpdHMgfSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcyk7XG4gICAgICAgIGlmIChrZXkuZGF0YS5sZW5ndGggIT09ICh0aGlzLmtleVNpemVCaXRzID4+IDMpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgY29yZS5PcGVyYXRpb25FcnJvcihcImtleURhdGE6IFdyb25nIGtleSBzaXplXCIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzZXRDcnlwdG9LZXkoa2V5KTtcbiAgICB9XG4gICAgY2hlY2tDcnlwdG9LZXkoa2V5LCBrZXlVc2FnZSkge1xuICAgICAgICBzdXBlci5jaGVja0NyeXB0b0tleShrZXksIGtleVVzYWdlKTtcbiAgICAgICAgaWYgKCEoZ2V0Q3J5cHRvS2V5KGtleSkgaW5zdGFuY2VvZiBEZXNDcnlwdG9LZXkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwia2V5OiBJcyBub3QgYSBEZXNDcnlwdG9LZXlcIik7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIGdldEp3a0FsZ29yaXRobShhbGdvcml0aG0pIHtcbiAgICBzd2l0Y2ggKGFsZ29yaXRobS5uYW1lLnRvVXBwZXJDYXNlKCkpIHtcbiAgICAgICAgY2FzZSBcIlJTQS1PQUVQXCI6IHtcbiAgICAgICAgICAgIGNvbnN0IG1kU2l6ZSA9IC8oXFxkKykkLy5leGVjKGFsZ29yaXRobS5oYXNoLm5hbWUpWzFdO1xuICAgICAgICAgICAgcmV0dXJuIGBSU0EtT0FFUCR7bWRTaXplICE9PSBcIjFcIiA/IGAtJHttZFNpemV9YCA6IFwiXCJ9YDtcbiAgICAgICAgfVxuICAgICAgICBjYXNlIFwiUlNBU1NBLVBLQ1MxLVYxXzVcIjpcbiAgICAgICAgICAgIHJldHVybiBgUlMkey8oXFxkKykkLy5leGVjKGFsZ29yaXRobS5oYXNoLm5hbWUpWzFdfWA7XG4gICAgICAgIGNhc2UgXCJSU0EtUFNTXCI6XG4gICAgICAgICAgICByZXR1cm4gYFBTJHsvKFxcZCspJC8uZXhlYyhhbGdvcml0aG0uaGFzaC5uYW1lKVsxXX1gO1xuICAgICAgICBjYXNlIFwiUlNBLVBLQ1MxXCI6XG4gICAgICAgICAgICByZXR1cm4gYFJTMWA7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICB0aHJvdyBuZXcgY29yZS5PcGVyYXRpb25FcnJvcihcImFsZ29yaXRobTogSXMgbm90IHJlY29nbml6ZWRcIik7XG4gICAgfVxufVxuXG5jbGFzcyBSc2FQcml2YXRlS2V5IGV4dGVuZHMgQXN5bW1ldHJpY0tleSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMudHlwZSA9IFwicHJpdmF0ZVwiO1xuICAgIH1cbiAgICBnZXRLZXkoKSB7XG4gICAgICAgIGNvbnN0IGtleUluZm8gPSBBc25QYXJzZXIucGFyc2UodGhpcy5kYXRhLCBjb3JlLmFzbjEuUHJpdmF0ZUtleUluZm8pO1xuICAgICAgICByZXR1cm4gQXNuUGFyc2VyLnBhcnNlKGtleUluZm8ucHJpdmF0ZUtleSwgY29yZS5hc24xLlJzYVByaXZhdGVLZXkpO1xuICAgIH1cbiAgICB0b0pTT04oKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IHRoaXMuZ2V0S2V5KCk7XG4gICAgICAgIGNvbnN0IGpzb24gPSB7XG4gICAgICAgICAgICBrdHk6IFwiUlNBXCIsXG4gICAgICAgICAgICBhbGc6IGdldEp3a0FsZ29yaXRobSh0aGlzLmFsZ29yaXRobSksXG4gICAgICAgICAgICBrZXlfb3BzOiB0aGlzLnVzYWdlcyxcbiAgICAgICAgICAgIGV4dDogdGhpcy5leHRyYWN0YWJsZSxcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oanNvbiwgSnNvblNlcmlhbGl6ZXIudG9KU09OKGtleSkpO1xuICAgIH1cbiAgICBmcm9tSlNPTihqc29uKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IEpzb25QYXJzZXIuZnJvbUpTT04oanNvbiwgeyB0YXJnZXRTY2hlbWE6IGNvcmUuYXNuMS5Sc2FQcml2YXRlS2V5IH0pO1xuICAgICAgICBjb25zdCBrZXlJbmZvID0gbmV3IGNvcmUuYXNuMS5Qcml2YXRlS2V5SW5mbygpO1xuICAgICAgICBrZXlJbmZvLnByaXZhdGVLZXlBbGdvcml0aG0uYWxnb3JpdGhtID0gXCIxLjIuODQwLjExMzU0OS4xLjEuMVwiO1xuICAgICAgICBrZXlJbmZvLnByaXZhdGVLZXlBbGdvcml0aG0ucGFyYW1ldGVycyA9IG51bGw7XG4gICAgICAgIGtleUluZm8ucHJpdmF0ZUtleSA9IEFzblNlcmlhbGl6ZXIuc2VyaWFsaXplKGtleSk7XG4gICAgICAgIHRoaXMuZGF0YSA9IEJ1ZmZlci5mcm9tKEFzblNlcmlhbGl6ZXIuc2VyaWFsaXplKGtleUluZm8pKTtcbiAgICB9XG59XG5cbmNsYXNzIFJzYVB1YmxpY0tleSBleHRlbmRzIEFzeW1tZXRyaWNLZXkge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLnR5cGUgPSBcInB1YmxpY1wiO1xuICAgIH1cbiAgICBnZXRLZXkoKSB7XG4gICAgICAgIGNvbnN0IGtleUluZm8gPSBBc25QYXJzZXIucGFyc2UodGhpcy5kYXRhLCBjb3JlLmFzbjEuUHVibGljS2V5SW5mbyk7XG4gICAgICAgIHJldHVybiBBc25QYXJzZXIucGFyc2Uoa2V5SW5mby5wdWJsaWNLZXksIGNvcmUuYXNuMS5Sc2FQdWJsaWNLZXkpO1xuICAgIH1cbiAgICB0b0pTT04oKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IHRoaXMuZ2V0S2V5KCk7XG4gICAgICAgIGNvbnN0IGpzb24gPSB7XG4gICAgICAgICAgICBrdHk6IFwiUlNBXCIsXG4gICAgICAgICAgICBhbGc6IGdldEp3a0FsZ29yaXRobSh0aGlzLmFsZ29yaXRobSksXG4gICAgICAgICAgICBrZXlfb3BzOiB0aGlzLnVzYWdlcyxcbiAgICAgICAgICAgIGV4dDogdGhpcy5leHRyYWN0YWJsZSxcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oanNvbiwgSnNvblNlcmlhbGl6ZXIudG9KU09OKGtleSkpO1xuICAgIH1cbiAgICBmcm9tSlNPTihqc29uKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IEpzb25QYXJzZXIuZnJvbUpTT04oanNvbiwgeyB0YXJnZXRTY2hlbWE6IGNvcmUuYXNuMS5Sc2FQdWJsaWNLZXkgfSk7XG4gICAgICAgIGNvbnN0IGtleUluZm8gPSBuZXcgY29yZS5hc24xLlB1YmxpY0tleUluZm8oKTtcbiAgICAgICAga2V5SW5mby5wdWJsaWNLZXlBbGdvcml0aG0uYWxnb3JpdGhtID0gXCIxLjIuODQwLjExMzU0OS4xLjEuMVwiO1xuICAgICAgICBrZXlJbmZvLnB1YmxpY0tleUFsZ29yaXRobS5wYXJhbWV0ZXJzID0gbnVsbDtcbiAgICAgICAga2V5SW5mby5wdWJsaWNLZXkgPSBBc25TZXJpYWxpemVyLnNlcmlhbGl6ZShrZXkpO1xuICAgICAgICB0aGlzLmRhdGEgPSBCdWZmZXIuZnJvbShBc25TZXJpYWxpemVyLnNlcmlhbGl6ZShrZXlJbmZvKSk7XG4gICAgfVxufVxuXG5jbGFzcyBSc2FDcnlwdG8ge1xuICAgIHN0YXRpYyBhc3luYyBnZW5lcmF0ZUtleShhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgY29uc3QgcHJpdmF0ZUtleSA9IG5ldyBSc2FQcml2YXRlS2V5KCk7XG4gICAgICAgIHByaXZhdGVLZXkuYWxnb3JpdGhtID0gYWxnb3JpdGhtO1xuICAgICAgICBwcml2YXRlS2V5LmV4dHJhY3RhYmxlID0gZXh0cmFjdGFibGU7XG4gICAgICAgIHByaXZhdGVLZXkudXNhZ2VzID0ga2V5VXNhZ2VzLmZpbHRlcigodXNhZ2UpID0+IHRoaXMucHJpdmF0ZUtleVVzYWdlcy5pbmRleE9mKHVzYWdlKSAhPT0gLTEpO1xuICAgICAgICBjb25zdCBwdWJsaWNLZXkgPSBuZXcgUnNhUHVibGljS2V5KCk7XG4gICAgICAgIHB1YmxpY0tleS5hbGdvcml0aG0gPSBhbGdvcml0aG07XG4gICAgICAgIHB1YmxpY0tleS5leHRyYWN0YWJsZSA9IHRydWU7XG4gICAgICAgIHB1YmxpY0tleS51c2FnZXMgPSBrZXlVc2FnZXMuZmlsdGVyKCh1c2FnZSkgPT4gdGhpcy5wdWJsaWNLZXlVc2FnZXMuaW5kZXhPZih1c2FnZSkgIT09IC0xKTtcbiAgICAgICAgY29uc3QgcHVibGljRXhwb25lbnQgPSBCdWZmZXIuY29uY2F0KFtcbiAgICAgICAgICAgIEJ1ZmZlci5hbGxvYyg0IC0gYWxnb3JpdGhtLnB1YmxpY0V4cG9uZW50LmJ5dGVMZW5ndGgsIDApLFxuICAgICAgICAgICAgQnVmZmVyLmZyb20oYWxnb3JpdGhtLnB1YmxpY0V4cG9uZW50KSxcbiAgICAgICAgXSkucmVhZEludDMyQkUoMCk7XG4gICAgICAgIGNvbnN0IGtleXMgPSBjcnlwdG9fX2RlZmF1bHQuZ2VuZXJhdGVLZXlQYWlyU3luYyhcInJzYVwiLCB7XG4gICAgICAgICAgICBtb2R1bHVzTGVuZ3RoOiBhbGdvcml0aG0ubW9kdWx1c0xlbmd0aCxcbiAgICAgICAgICAgIHB1YmxpY0V4cG9uZW50LFxuICAgICAgICAgICAgcHVibGljS2V5RW5jb2Rpbmc6IHtcbiAgICAgICAgICAgICAgICBmb3JtYXQ6IFwiZGVyXCIsXG4gICAgICAgICAgICAgICAgdHlwZTogXCJzcGtpXCIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcHJpdmF0ZUtleUVuY29kaW5nOiB7XG4gICAgICAgICAgICAgICAgZm9ybWF0OiBcImRlclwiLFxuICAgICAgICAgICAgICAgIHR5cGU6IFwicGtjczhcIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICBwcml2YXRlS2V5LmRhdGEgPSBrZXlzLnByaXZhdGVLZXk7XG4gICAgICAgIHB1YmxpY0tleS5kYXRhID0ga2V5cy5wdWJsaWNLZXk7XG4gICAgICAgIGNvbnN0IHJlcyA9IHtcbiAgICAgICAgICAgIHByaXZhdGVLZXksXG4gICAgICAgICAgICBwdWJsaWNLZXksXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxuICAgIHN0YXRpYyBhc3luYyBleHBvcnRLZXkoZm9ybWF0LCBrZXkpIHtcbiAgICAgICAgc3dpdGNoIChmb3JtYXQudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgY2FzZSBcImp3a1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBKc29uU2VyaWFsaXplci50b0pTT04oa2V5KTtcbiAgICAgICAgICAgIGNhc2UgXCJwa2NzOFwiOlxuICAgICAgICAgICAgY2FzZSBcInNwa2lcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoa2V5LmRhdGEpLmJ1ZmZlcjtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IGNvcmUuT3BlcmF0aW9uRXJyb3IoXCJmb3JtYXQ6IE11c3QgYmUgJ2p3aycsICdwa2NzOCcgb3IgJ3Nwa2knXCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHN0YXRpYyBhc3luYyBpbXBvcnRLZXkoZm9ybWF0LCBrZXlEYXRhLCBhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgc3dpdGNoIChmb3JtYXQudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgY2FzZSBcImp3a1wiOiB7XG4gICAgICAgICAgICAgICAgY29uc3QgandrID0ga2V5RGF0YTtcbiAgICAgICAgICAgICAgICBpZiAoandrLmQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYXNuS2V5ID0gSnNvblBhcnNlci5mcm9tSlNPTihrZXlEYXRhLCB7IHRhcmdldFNjaGVtYTogY29yZS5hc24xLlJzYVByaXZhdGVLZXkgfSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmltcG9ydFByaXZhdGVLZXkoYXNuS2V5LCBhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYXNuS2V5ID0gSnNvblBhcnNlci5mcm9tSlNPTihrZXlEYXRhLCB7IHRhcmdldFNjaGVtYTogY29yZS5hc24xLlJzYVB1YmxpY0tleSB9KTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW1wb3J0UHVibGljS2V5KGFzbktleSwgYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwic3BraVwiOiB7XG4gICAgICAgICAgICAgICAgY29uc3Qga2V5SW5mbyA9IEFzblBhcnNlci5wYXJzZShuZXcgVWludDhBcnJheShrZXlEYXRhKSwgY29yZS5hc24xLlB1YmxpY0tleUluZm8pO1xuICAgICAgICAgICAgICAgIGNvbnN0IGFzbktleSA9IEFzblBhcnNlci5wYXJzZShrZXlJbmZvLnB1YmxpY0tleSwgY29yZS5hc24xLlJzYVB1YmxpY0tleSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW1wb3J0UHVibGljS2V5KGFzbktleSwgYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJwa2NzOFwiOiB7XG4gICAgICAgICAgICAgICAgY29uc3Qga2V5SW5mbyA9IEFzblBhcnNlci5wYXJzZShuZXcgVWludDhBcnJheShrZXlEYXRhKSwgY29yZS5hc24xLlByaXZhdGVLZXlJbmZvKTtcbiAgICAgICAgICAgICAgICBjb25zdCBhc25LZXkgPSBBc25QYXJzZXIucGFyc2Uoa2V5SW5mby5wcml2YXRlS2V5LCBjb3JlLmFzbjEuUnNhUHJpdmF0ZUtleSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW1wb3J0UHJpdmF0ZUtleShhc25LZXksIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBjb3JlLk9wZXJhdGlvbkVycm9yKFwiZm9ybWF0OiBNdXN0IGJlICdqd2snLCAncGtjczgnIG9yICdzcGtpJ1wiKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzdGF0aWMgYXN5bmMgc2lnbihhbGdvcml0aG0sIGtleSwgZGF0YSkge1xuICAgICAgICBzd2l0Y2ggKGFsZ29yaXRobS5uYW1lLnRvVXBwZXJDYXNlKCkpIHtcbiAgICAgICAgICAgIGNhc2UgXCJSU0EtUFNTXCI6XG4gICAgICAgICAgICBjYXNlIFwiUlNBU1NBLVBLQ1MxLVYxXzVcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5zaWduUnNhKGFsZ29yaXRobSwga2V5LCBkYXRhKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IGNvcmUuT3BlcmF0aW9uRXJyb3IoXCJhbGdvcml0aG06IElzIG5vdCByZWNvZ25pemVkXCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHN0YXRpYyBhc3luYyB2ZXJpZnkoYWxnb3JpdGhtLCBrZXksIHNpZ25hdHVyZSwgZGF0YSkge1xuICAgICAgICBzd2l0Y2ggKGFsZ29yaXRobS5uYW1lLnRvVXBwZXJDYXNlKCkpIHtcbiAgICAgICAgICAgIGNhc2UgXCJSU0EtUFNTXCI6XG4gICAgICAgICAgICBjYXNlIFwiUlNBU1NBLVBLQ1MxLVYxXzVcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy52ZXJpZnlTU0EoYWxnb3JpdGhtLCBrZXksIGRhdGEsIHNpZ25hdHVyZSk7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBjb3JlLk9wZXJhdGlvbkVycm9yKFwiYWxnb3JpdGhtOiBJcyBub3QgcmVjb2duaXplZFwiKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzdGF0aWMgYXN5bmMgZW5jcnlwdChhbGdvcml0aG0sIGtleSwgZGF0YSkge1xuICAgICAgICBzd2l0Y2ggKGFsZ29yaXRobS5uYW1lLnRvVXBwZXJDYXNlKCkpIHtcbiAgICAgICAgICAgIGNhc2UgXCJSU0EtT0FFUFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVuY3J5cHRPQUVQKGFsZ29yaXRobSwga2V5LCBkYXRhKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IGNvcmUuT3BlcmF0aW9uRXJyb3IoXCJhbGdvcml0aG06IElzIG5vdCByZWNvZ25pemVkXCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHN0YXRpYyBhc3luYyBkZWNyeXB0KGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIHN3aXRjaCAoYWxnb3JpdGhtLm5hbWUudG9VcHBlckNhc2UoKSkge1xuICAgICAgICAgICAgY2FzZSBcIlJTQS1PQUVQXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGVjcnlwdE9BRVAoYWxnb3JpdGhtLCBrZXksIGRhdGEpO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgY29yZS5PcGVyYXRpb25FcnJvcihcImFsZ29yaXRobTogSXMgbm90IHJlY29nbml6ZWRcIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIGltcG9ydFByaXZhdGVLZXkoYXNuS2V5LCBhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgY29uc3Qga2V5SW5mbyA9IG5ldyBjb3JlLmFzbjEuUHJpdmF0ZUtleUluZm8oKTtcbiAgICAgICAga2V5SW5mby5wcml2YXRlS2V5QWxnb3JpdGhtLmFsZ29yaXRobSA9IFwiMS4yLjg0MC4xMTM1NDkuMS4xLjFcIjtcbiAgICAgICAga2V5SW5mby5wcml2YXRlS2V5QWxnb3JpdGhtLnBhcmFtZXRlcnMgPSBudWxsO1xuICAgICAgICBrZXlJbmZvLnByaXZhdGVLZXkgPSBBc25TZXJpYWxpemVyLnNlcmlhbGl6ZShhc25LZXkpO1xuICAgICAgICBjb25zdCBrZXkgPSBuZXcgUnNhUHJpdmF0ZUtleSgpO1xuICAgICAgICBrZXkuZGF0YSA9IEJ1ZmZlci5mcm9tKEFzblNlcmlhbGl6ZXIuc2VyaWFsaXplKGtleUluZm8pKTtcbiAgICAgICAga2V5LmFsZ29yaXRobSA9IE9iamVjdC5hc3NpZ24oe30sIGFsZ29yaXRobSk7XG4gICAgICAgIGtleS5hbGdvcml0aG0ucHVibGljRXhwb25lbnQgPSBuZXcgVWludDhBcnJheShhc25LZXkucHVibGljRXhwb25lbnQpO1xuICAgICAgICBrZXkuYWxnb3JpdGhtLm1vZHVsdXNMZW5ndGggPSBhc25LZXkubW9kdWx1cy5ieXRlTGVuZ3RoIDw8IDM7XG4gICAgICAgIGtleS5leHRyYWN0YWJsZSA9IGV4dHJhY3RhYmxlO1xuICAgICAgICBrZXkudXNhZ2VzID0ga2V5VXNhZ2VzO1xuICAgICAgICByZXR1cm4ga2V5O1xuICAgIH1cbiAgICBzdGF0aWMgaW1wb3J0UHVibGljS2V5KGFzbktleSwgYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKSB7XG4gICAgICAgIGNvbnN0IGtleUluZm8gPSBuZXcgY29yZS5hc24xLlB1YmxpY0tleUluZm8oKTtcbiAgICAgICAga2V5SW5mby5wdWJsaWNLZXlBbGdvcml0aG0uYWxnb3JpdGhtID0gXCIxLjIuODQwLjExMzU0OS4xLjEuMVwiO1xuICAgICAgICBrZXlJbmZvLnB1YmxpY0tleUFsZ29yaXRobS5wYXJhbWV0ZXJzID0gbnVsbDtcbiAgICAgICAga2V5SW5mby5wdWJsaWNLZXkgPSBBc25TZXJpYWxpemVyLnNlcmlhbGl6ZShhc25LZXkpO1xuICAgICAgICBjb25zdCBrZXkgPSBuZXcgUnNhUHVibGljS2V5KCk7XG4gICAgICAgIGtleS5kYXRhID0gQnVmZmVyLmZyb20oQXNuU2VyaWFsaXplci5zZXJpYWxpemUoa2V5SW5mbykpO1xuICAgICAgICBrZXkuYWxnb3JpdGhtID0gT2JqZWN0LmFzc2lnbih7fSwgYWxnb3JpdGhtKTtcbiAgICAgICAga2V5LmFsZ29yaXRobS5wdWJsaWNFeHBvbmVudCA9IG5ldyBVaW50OEFycmF5KGFzbktleS5wdWJsaWNFeHBvbmVudCk7XG4gICAgICAgIGtleS5hbGdvcml0aG0ubW9kdWx1c0xlbmd0aCA9IGFzbktleS5tb2R1bHVzLmJ5dGVMZW5ndGggPDwgMztcbiAgICAgICAga2V5LmV4dHJhY3RhYmxlID0gZXh0cmFjdGFibGU7XG4gICAgICAgIGtleS51c2FnZXMgPSBrZXlVc2FnZXM7XG4gICAgICAgIHJldHVybiBrZXk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXRDcnlwdG9BbGdvcml0aG0oYWxnKSB7XG4gICAgICAgIHN3aXRjaCAoYWxnLmhhc2gubmFtZS50b1VwcGVyQ2FzZSgpKSB7XG4gICAgICAgICAgICBjYXNlIFwiU0hBLTFcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJSU0EtU0hBMVwiO1xuICAgICAgICAgICAgY2FzZSBcIlNIQS0yNTZcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJSU0EtU0hBMjU2XCI7XG4gICAgICAgICAgICBjYXNlIFwiU0hBLTM4NFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIlJTQS1TSEEzODRcIjtcbiAgICAgICAgICAgIGNhc2UgXCJTSEEtNTEyXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiUlNBLVNIQTUxMlwiO1xuICAgICAgICAgICAgY2FzZSBcIlNIQTMtMjU2XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiUlNBLVNIQTMtMjU2XCI7XG4gICAgICAgICAgICBjYXNlIFwiU0hBMy0zODRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJSU0EtU0hBMy0zODRcIjtcbiAgICAgICAgICAgIGNhc2UgXCJTSEEzLTUxMlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIlJTQS1TSEEzLTUxMlwiO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgY29yZS5PcGVyYXRpb25FcnJvcihcImFsZ29yaXRobS5oYXNoOiBJcyBub3QgcmVjb2duaXplZFwiKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzdGF0aWMgc2lnblJzYShhbGdvcml0aG0sIGtleSwgZGF0YSkge1xuICAgICAgICBjb25zdCBjcnlwdG9BbGcgPSB0aGlzLmdldENyeXB0b0FsZ29yaXRobShrZXkuYWxnb3JpdGhtKTtcbiAgICAgICAgY29uc3Qgc2lnbmVyID0gY3J5cHRvX19kZWZhdWx0LmNyZWF0ZVNpZ24oY3J5cHRvQWxnKTtcbiAgICAgICAgc2lnbmVyLnVwZGF0ZShCdWZmZXIuZnJvbShkYXRhKSk7XG4gICAgICAgIGlmICgha2V5LnBlbSkge1xuICAgICAgICAgICAga2V5LnBlbSA9IGAtLS0tLUJFR0lOIFBSSVZBVEUgS0VZLS0tLS1cXG4ke2tleS5kYXRhLnRvU3RyaW5nKFwiYmFzZTY0XCIpfVxcbi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS1gO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICBrZXk6IGtleS5wZW0sXG4gICAgICAgIH07XG4gICAgICAgIGlmIChhbGdvcml0aG0ubmFtZS50b1VwcGVyQ2FzZSgpID09PSBcIlJTQS1QU1NcIikge1xuICAgICAgICAgICAgb3B0aW9ucy5wYWRkaW5nID0gY3J5cHRvX19kZWZhdWx0LmNvbnN0YW50cy5SU0FfUEtDUzFfUFNTX1BBRERJTkc7XG4gICAgICAgICAgICBvcHRpb25zLnNhbHRMZW5ndGggPSBhbGdvcml0aG0uc2FsdExlbmd0aDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzaWduYXR1cmUgPSBzaWduZXIuc2lnbihvcHRpb25zKTtcbiAgICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KHNpZ25hdHVyZSkuYnVmZmVyO1xuICAgIH1cbiAgICBzdGF0aWMgdmVyaWZ5U1NBKGFsZ29yaXRobSwga2V5LCBkYXRhLCBzaWduYXR1cmUpIHtcbiAgICAgICAgY29uc3QgY3J5cHRvQWxnID0gdGhpcy5nZXRDcnlwdG9BbGdvcml0aG0oa2V5LmFsZ29yaXRobSk7XG4gICAgICAgIGNvbnN0IHNpZ25lciA9IGNyeXB0b19fZGVmYXVsdC5jcmVhdGVWZXJpZnkoY3J5cHRvQWxnKTtcbiAgICAgICAgc2lnbmVyLnVwZGF0ZShCdWZmZXIuZnJvbShkYXRhKSk7XG4gICAgICAgIGlmICgha2V5LnBlbSkge1xuICAgICAgICAgICAga2V5LnBlbSA9IGAtLS0tLUJFR0lOIFBVQkxJQyBLRVktLS0tLVxcbiR7a2V5LmRhdGEudG9TdHJpbmcoXCJiYXNlNjRcIil9XFxuLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tYDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAga2V5OiBrZXkucGVtLFxuICAgICAgICB9O1xuICAgICAgICBpZiAoYWxnb3JpdGhtLm5hbWUudG9VcHBlckNhc2UoKSA9PT0gXCJSU0EtUFNTXCIpIHtcbiAgICAgICAgICAgIG9wdGlvbnMucGFkZGluZyA9IGNyeXB0b19fZGVmYXVsdC5jb25zdGFudHMuUlNBX1BLQ1MxX1BTU19QQURESU5HO1xuICAgICAgICAgICAgb3B0aW9ucy5zYWx0TGVuZ3RoID0gYWxnb3JpdGhtLnNhbHRMZW5ndGg7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgb2sgPSBzaWduZXIudmVyaWZ5KG9wdGlvbnMsIHNpZ25hdHVyZSk7XG4gICAgICAgIHJldHVybiBvaztcbiAgICB9XG4gICAgc3RhdGljIGVuY3J5cHRPQUVQKGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICBrZXk6IGAtLS0tLUJFR0lOIFBVQkxJQyBLRVktLS0tLVxcbiR7a2V5LmRhdGEudG9TdHJpbmcoXCJiYXNlNjRcIil9XFxuLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tYCxcbiAgICAgICAgICAgIHBhZGRpbmc6IGNyeXB0b19fZGVmYXVsdC5jb25zdGFudHMuUlNBX1BLQ1MxX09BRVBfUEFERElORyxcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKGFsZ29yaXRobS5sYWJlbCkgO1xuICAgICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoY3J5cHRvX19kZWZhdWx0LnB1YmxpY0VuY3J5cHQob3B0aW9ucywgZGF0YSkpLmJ1ZmZlcjtcbiAgICB9XG4gICAgc3RhdGljIGRlY3J5cHRPQUVQKGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICBrZXk6IGAtLS0tLUJFR0lOIFBSSVZBVEUgS0VZLS0tLS1cXG4ke2tleS5kYXRhLnRvU3RyaW5nKFwiYmFzZTY0XCIpfVxcbi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS1gLFxuICAgICAgICAgICAgcGFkZGluZzogY3J5cHRvX19kZWZhdWx0LmNvbnN0YW50cy5SU0FfUEtDUzFfT0FFUF9QQURESU5HLFxuICAgICAgICB9O1xuICAgICAgICBpZiAoYWxnb3JpdGhtLmxhYmVsKSA7XG4gICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShjcnlwdG9fX2RlZmF1bHQucHJpdmF0ZURlY3J5cHQob3B0aW9ucywgZGF0YSkpLmJ1ZmZlcjtcbiAgICB9XG59XG5Sc2FDcnlwdG8ucHVibGljS2V5VXNhZ2VzID0gW1widmVyaWZ5XCIsIFwiZW5jcnlwdFwiLCBcIndyYXBLZXlcIl07XG5Sc2FDcnlwdG8ucHJpdmF0ZUtleVVzYWdlcyA9IFtcInNpZ25cIiwgXCJkZWNyeXB0XCIsIFwidW53cmFwS2V5XCJdO1xuXG5jbGFzcyBSc2FTc2FQcm92aWRlciBleHRlbmRzIGNvcmUuUnNhU3NhUHJvdmlkZXIge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLmhhc2hBbGdvcml0aG1zID0gW1xuICAgICAgICAgICAgXCJTSEEtMVwiLCBcIlNIQS0yNTZcIiwgXCJTSEEtMzg0XCIsIFwiU0hBLTUxMlwiLFxuICAgICAgICAgICAgXCJzaGFrZTEyOFwiLCBcInNoYWtlMjU2XCIsXG4gICAgICAgICAgICBcIlNIQTMtMjU2XCIsIFwiU0hBMy0zODRcIiwgXCJTSEEzLTUxMlwiXG4gICAgICAgIF07XG4gICAgfVxuICAgIGFzeW5jIG9uR2VuZXJhdGVLZXkoYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKSB7XG4gICAgICAgIGNvbnN0IGtleXMgPSBhd2FpdCBSc2FDcnlwdG8uZ2VuZXJhdGVLZXkoe1xuICAgICAgICAgICAgLi4uYWxnb3JpdGhtLFxuICAgICAgICAgICAgbmFtZTogdGhpcy5uYW1lLFxuICAgICAgICB9LCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHByaXZhdGVLZXk6IHNldENyeXB0b0tleShrZXlzLnByaXZhdGVLZXkpLFxuICAgICAgICAgICAgcHVibGljS2V5OiBzZXRDcnlwdG9LZXkoa2V5cy5wdWJsaWNLZXkpLFxuICAgICAgICB9O1xuICAgIH1cbiAgICBhc3luYyBvblNpZ24oYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgcmV0dXJuIFJzYUNyeXB0by5zaWduKGFsZ29yaXRobSwgZ2V0Q3J5cHRvS2V5KGtleSksIG5ldyBVaW50OEFycmF5KGRhdGEpKTtcbiAgICB9XG4gICAgYXN5bmMgb25WZXJpZnkoYWxnb3JpdGhtLCBrZXksIHNpZ25hdHVyZSwgZGF0YSkge1xuICAgICAgICByZXR1cm4gUnNhQ3J5cHRvLnZlcmlmeShhbGdvcml0aG0sIGdldENyeXB0b0tleShrZXkpLCBuZXcgVWludDhBcnJheShzaWduYXR1cmUpLCBuZXcgVWludDhBcnJheShkYXRhKSk7XG4gICAgfVxuICAgIGFzeW5jIG9uRXhwb3J0S2V5KGZvcm1hdCwga2V5KSB7XG4gICAgICAgIHJldHVybiBSc2FDcnlwdG8uZXhwb3J0S2V5KGZvcm1hdCwgZ2V0Q3J5cHRvS2V5KGtleSkpO1xuICAgIH1cbiAgICBhc3luYyBvbkltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCBrZXkgPSBhd2FpdCBSc2FDcnlwdG8uaW1wb3J0S2V5KGZvcm1hdCwga2V5RGF0YSwgeyAuLi5hbGdvcml0aG0sIG5hbWU6IHRoaXMubmFtZSB9LCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgcmV0dXJuIHNldENyeXB0b0tleShrZXkpO1xuICAgIH1cbiAgICBjaGVja0NyeXB0b0tleShrZXksIGtleVVzYWdlKSB7XG4gICAgICAgIHN1cGVyLmNoZWNrQ3J5cHRvS2V5KGtleSwga2V5VXNhZ2UpO1xuICAgICAgICBjb25zdCBpbnRlcm5hbEtleSA9IGdldENyeXB0b0tleShrZXkpO1xuICAgICAgICBpZiAoIShpbnRlcm5hbEtleSBpbnN0YW5jZW9mIFJzYVByaXZhdGVLZXkgfHwgaW50ZXJuYWxLZXkgaW5zdGFuY2VvZiBSc2FQdWJsaWNLZXkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwia2V5OiBJcyBub3QgUlNBIENyeXB0b0tleVwiKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuY2xhc3MgUnNhUHNzUHJvdmlkZXIgZXh0ZW5kcyBjb3JlLlJzYVBzc1Byb3ZpZGVyIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5oYXNoQWxnb3JpdGhtcyA9IFtcbiAgICAgICAgICAgIFwiU0hBLTFcIiwgXCJTSEEtMjU2XCIsIFwiU0hBLTM4NFwiLCBcIlNIQS01MTJcIixcbiAgICAgICAgICAgIFwic2hha2UxMjhcIiwgXCJzaGFrZTI1NlwiLFxuICAgICAgICAgICAgXCJTSEEzLTI1NlwiLCBcIlNIQTMtMzg0XCIsIFwiU0hBMy01MTJcIlxuICAgICAgICBdO1xuICAgIH1cbiAgICBhc3luYyBvbkdlbmVyYXRlS2V5KGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCBrZXlzID0gYXdhaXQgUnNhQ3J5cHRvLmdlbmVyYXRlS2V5KHtcbiAgICAgICAgICAgIC4uLmFsZ29yaXRobSxcbiAgICAgICAgICAgIG5hbWU6IHRoaXMubmFtZSxcbiAgICAgICAgfSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcyk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBwcml2YXRlS2V5OiBzZXRDcnlwdG9LZXkoa2V5cy5wcml2YXRlS2V5KSxcbiAgICAgICAgICAgIHB1YmxpY0tleTogc2V0Q3J5cHRvS2V5KGtleXMucHVibGljS2V5KSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgYXN5bmMgb25TaWduKGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIHJldHVybiBSc2FDcnlwdG8uc2lnbihhbGdvcml0aG0sIGdldENyeXB0b0tleShrZXkpLCBuZXcgVWludDhBcnJheShkYXRhKSk7XG4gICAgfVxuICAgIGFzeW5jIG9uVmVyaWZ5KGFsZ29yaXRobSwga2V5LCBzaWduYXR1cmUsIGRhdGEpIHtcbiAgICAgICAgcmV0dXJuIFJzYUNyeXB0by52ZXJpZnkoYWxnb3JpdGhtLCBnZXRDcnlwdG9LZXkoa2V5KSwgbmV3IFVpbnQ4QXJyYXkoc2lnbmF0dXJlKSwgbmV3IFVpbnQ4QXJyYXkoZGF0YSkpO1xuICAgIH1cbiAgICBhc3luYyBvbkV4cG9ydEtleShmb3JtYXQsIGtleSkge1xuICAgICAgICByZXR1cm4gUnNhQ3J5cHRvLmV4cG9ydEtleShmb3JtYXQsIGdldENyeXB0b0tleShrZXkpKTtcbiAgICB9XG4gICAgYXN5bmMgb25JbXBvcnRLZXkoZm9ybWF0LCBrZXlEYXRhLCBhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgY29uc3Qga2V5ID0gYXdhaXQgUnNhQ3J5cHRvLmltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIHsgLi4uYWxnb3JpdGhtLCBuYW1lOiB0aGlzLm5hbWUgfSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcyk7XG4gICAgICAgIHJldHVybiBzZXRDcnlwdG9LZXkoa2V5KTtcbiAgICB9XG4gICAgY2hlY2tDcnlwdG9LZXkoa2V5LCBrZXlVc2FnZSkge1xuICAgICAgICBzdXBlci5jaGVja0NyeXB0b0tleShrZXksIGtleVVzYWdlKTtcbiAgICAgICAgY29uc3QgaW50ZXJuYWxLZXkgPSBnZXRDcnlwdG9LZXkoa2V5KTtcbiAgICAgICAgaWYgKCEoaW50ZXJuYWxLZXkgaW5zdGFuY2VvZiBSc2FQcml2YXRlS2V5IHx8IGludGVybmFsS2V5IGluc3RhbmNlb2YgUnNhUHVibGljS2V5KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImtleTogSXMgbm90IFJTQSBDcnlwdG9LZXlcIik7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmNsYXNzIFNoYUNyeXB0byB7XG4gICAgc3RhdGljIHNpemUoYWxnb3JpdGhtKSB7XG4gICAgICAgIHN3aXRjaCAoYWxnb3JpdGhtLm5hbWUudG9VcHBlckNhc2UoKSkge1xuICAgICAgICAgICAgY2FzZSBcIlNIQS0xXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIDE2MDtcbiAgICAgICAgICAgIGNhc2UgXCJTSEEtMjU2XCI6XG4gICAgICAgICAgICBjYXNlIFwiU0hBMy0yNTZcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gMjU2O1xuICAgICAgICAgICAgY2FzZSBcIlNIQS0zODRcIjpcbiAgICAgICAgICAgIGNhc2UgXCJTSEEzLTM4NFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiAzODQ7XG4gICAgICAgICAgICBjYXNlIFwiU0hBLTUxMlwiOlxuICAgICAgICAgICAgY2FzZSBcIlNIQTMtNTEyXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIDUxMjtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5yZWNvZ25pemVkIG5hbWVcIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIGdldEFsZ29yaXRobU5hbWUoYWxnb3JpdGhtKSB7XG4gICAgICAgIHN3aXRjaCAoYWxnb3JpdGhtLm5hbWUudG9VcHBlckNhc2UoKSkge1xuICAgICAgICAgICAgY2FzZSBcIlNIQS0xXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwic2hhMVwiO1xuICAgICAgICAgICAgY2FzZSBcIlNIQS0yNTZcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJzaGEyNTZcIjtcbiAgICAgICAgICAgIGNhc2UgXCJTSEEtMzg0XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwic2hhMzg0XCI7XG4gICAgICAgICAgICBjYXNlIFwiU0hBLTUxMlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcInNoYTUxMlwiO1xuICAgICAgICAgICAgY2FzZSBcIlNIQTMtMjU2XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwic2hhMy0yNTZcIjtcbiAgICAgICAgICAgIGNhc2UgXCJTSEEzLTM4NFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcInNoYTMtMzg0XCI7XG4gICAgICAgICAgICBjYXNlIFwiU0hBMy01MTJcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJzaGEzLTUxMlwiO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbnJlY29nbml6ZWQgbmFtZVwiKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzdGF0aWMgZGlnZXN0KGFsZ29yaXRobSwgZGF0YSkge1xuICAgICAgICBjb25zdCBoYXNoQWxnID0gdGhpcy5nZXRBbGdvcml0aG1OYW1lKGFsZ29yaXRobSk7XG4gICAgICAgIGNvbnN0IGhhc2ggPSBjcnlwdG9fX2RlZmF1bHQuY3JlYXRlSGFzaChoYXNoQWxnKVxuICAgICAgICAgICAgLnVwZGF0ZShCdWZmZXIuZnJvbShkYXRhKSkuZGlnZXN0KCk7XG4gICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShoYXNoKS5idWZmZXI7XG4gICAgfVxufVxuXG5jbGFzcyBSc2FPYWVwUHJvdmlkZXIgZXh0ZW5kcyBjb3JlLlJzYU9hZXBQcm92aWRlciB7XG4gICAgYXN5bmMgb25HZW5lcmF0ZUtleShhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgY29uc3Qga2V5cyA9IGF3YWl0IFJzYUNyeXB0by5nZW5lcmF0ZUtleSh7XG4gICAgICAgICAgICAuLi5hbGdvcml0aG0sXG4gICAgICAgICAgICBuYW1lOiB0aGlzLm5hbWUsXG4gICAgICAgIH0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcHJpdmF0ZUtleTogc2V0Q3J5cHRvS2V5KGtleXMucHJpdmF0ZUtleSksXG4gICAgICAgICAgICBwdWJsaWNLZXk6IHNldENyeXB0b0tleShrZXlzLnB1YmxpY0tleSksXG4gICAgICAgIH07XG4gICAgfVxuICAgIGFzeW5jIG9uRW5jcnlwdChhbGdvcml0aG0sIGtleSwgZGF0YSkge1xuICAgICAgICBjb25zdCBpbnRlcm5hbEtleSA9IGdldENyeXB0b0tleShrZXkpO1xuICAgICAgICBjb25zdCBkYXRhVmlldyA9IG5ldyBVaW50OEFycmF5KGRhdGEpO1xuICAgICAgICBjb25zdCBrZXlTaXplID0gTWF0aC5jZWlsKGludGVybmFsS2V5LmFsZ29yaXRobS5tb2R1bHVzTGVuZ3RoID4+IDMpO1xuICAgICAgICBjb25zdCBoYXNoU2l6ZSA9IFNoYUNyeXB0by5zaXplKGludGVybmFsS2V5LmFsZ29yaXRobS5oYXNoKSA+PiAzO1xuICAgICAgICBjb25zdCBkYXRhTGVuZ3RoID0gZGF0YVZpZXcuYnl0ZUxlbmd0aDtcbiAgICAgICAgY29uc3QgcHNMZW5ndGggPSBrZXlTaXplIC0gZGF0YUxlbmd0aCAtIDIgKiBoYXNoU2l6ZSAtIDI7XG4gICAgICAgIGlmIChkYXRhTGVuZ3RoID4ga2V5U2l6ZSAtIDIgKiBoYXNoU2l6ZSAtIDIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkRhdGEgdG9vIGxhcmdlXCIpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG1lc3NhZ2UgPSBuZXcgVWludDhBcnJheShrZXlTaXplKTtcbiAgICAgICAgY29uc3Qgc2VlZCA9IG1lc3NhZ2Uuc3ViYXJyYXkoMSwgaGFzaFNpemUgKyAxKTtcbiAgICAgICAgY29uc3QgZGF0YUJsb2NrID0gbWVzc2FnZS5zdWJhcnJheShoYXNoU2l6ZSArIDEpO1xuICAgICAgICBkYXRhQmxvY2suc2V0KGRhdGFWaWV3LCBoYXNoU2l6ZSArIHBzTGVuZ3RoICsgMSk7XG4gICAgICAgIGNvbnN0IGxhYmVsSGFzaCA9IGNyeXB0b19fZGVmYXVsdC5jcmVhdGVIYXNoKGludGVybmFsS2V5LmFsZ29yaXRobS5oYXNoLm5hbWUucmVwbGFjZShcIi1cIiwgXCJcIikpXG4gICAgICAgICAgICAudXBkYXRlKGNvcmUuQnVmZmVyU291cmNlQ29udmVydGVyLnRvVWludDhBcnJheShhbGdvcml0aG0ubGFiZWwgfHwgbmV3IFVpbnQ4QXJyYXkoMCkpKVxuICAgICAgICAgICAgLmRpZ2VzdCgpO1xuICAgICAgICBkYXRhQmxvY2suc2V0KGxhYmVsSGFzaCwgMCk7XG4gICAgICAgIGRhdGFCbG9ja1toYXNoU2l6ZSArIHBzTGVuZ3RoXSA9IDE7XG4gICAgICAgIGNyeXB0b19fZGVmYXVsdC5yYW5kb21GaWxsU3luYyhzZWVkKTtcbiAgICAgICAgY29uc3QgZGF0YUJsb2NrTWFzayA9IHRoaXMubWdmMShpbnRlcm5hbEtleS5hbGdvcml0aG0uaGFzaCwgc2VlZCwgZGF0YUJsb2NrLmxlbmd0aCk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGF0YUJsb2NrLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBkYXRhQmxvY2tbaV0gXj0gZGF0YUJsb2NrTWFza1tpXTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzZWVkTWFzayA9IHRoaXMubWdmMShpbnRlcm5hbEtleS5hbGdvcml0aG0uaGFzaCwgZGF0YUJsb2NrLCBzZWVkLmxlbmd0aCk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VlZC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgc2VlZFtpXSBePSBzZWVkTWFza1tpXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWludGVybmFsS2V5LnBlbSkge1xuICAgICAgICAgICAgaW50ZXJuYWxLZXkucGVtID0gYC0tLS0tQkVHSU4gUFVCTElDIEtFWS0tLS0tXFxuJHtpbnRlcm5hbEtleS5kYXRhLnRvU3RyaW5nKFwiYmFzZTY0XCIpfVxcbi0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLWA7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcGtjczAgPSBjcnlwdG9fX2RlZmF1bHQucHVibGljRW5jcnlwdCh7XG4gICAgICAgICAgICBrZXk6IGludGVybmFsS2V5LnBlbSxcbiAgICAgICAgICAgIHBhZGRpbmc6IGNyeXB0b19fZGVmYXVsdC5jb25zdGFudHMuUlNBX05PX1BBRERJTkcsXG4gICAgICAgIH0sIEJ1ZmZlci5mcm9tKG1lc3NhZ2UpKTtcbiAgICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KHBrY3MwKS5idWZmZXI7XG4gICAgfVxuICAgIGFzeW5jIG9uRGVjcnlwdChhbGdvcml0aG0sIGtleSwgZGF0YSkge1xuICAgICAgICBjb25zdCBpbnRlcm5hbEtleSA9IGdldENyeXB0b0tleShrZXkpO1xuICAgICAgICBjb25zdCBrZXlTaXplID0gTWF0aC5jZWlsKGludGVybmFsS2V5LmFsZ29yaXRobS5tb2R1bHVzTGVuZ3RoID4+IDMpO1xuICAgICAgICBjb25zdCBoYXNoU2l6ZSA9IFNoYUNyeXB0by5zaXplKGludGVybmFsS2V5LmFsZ29yaXRobS5oYXNoKSA+PiAzO1xuICAgICAgICBjb25zdCBkYXRhTGVuZ3RoID0gZGF0YS5ieXRlTGVuZ3RoO1xuICAgICAgICBpZiAoZGF0YUxlbmd0aCAhPT0ga2V5U2l6ZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQmFkIGRhdGFcIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFpbnRlcm5hbEtleS5wZW0pIHtcbiAgICAgICAgICAgIGludGVybmFsS2V5LnBlbSA9IGAtLS0tLUJFR0lOIFBSSVZBVEUgS0VZLS0tLS1cXG4ke2ludGVybmFsS2V5LmRhdGEudG9TdHJpbmcoXCJiYXNlNjRcIil9XFxuLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLWA7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHBrY3MwID0gY3J5cHRvX19kZWZhdWx0LnByaXZhdGVEZWNyeXB0KHtcbiAgICAgICAgICAgIGtleTogaW50ZXJuYWxLZXkucGVtLFxuICAgICAgICAgICAgcGFkZGluZzogY3J5cHRvX19kZWZhdWx0LmNvbnN0YW50cy5SU0FfTk9fUEFERElORyxcbiAgICAgICAgfSwgQnVmZmVyLmZyb20oZGF0YSkpO1xuICAgICAgICBjb25zdCB6ID0gcGtjczBbMF07XG4gICAgICAgIGNvbnN0IHNlZWQgPSBwa2NzMC5zdWJhcnJheSgxLCBoYXNoU2l6ZSArIDEpO1xuICAgICAgICBjb25zdCBkYXRhQmxvY2sgPSBwa2NzMC5zdWJhcnJheShoYXNoU2l6ZSArIDEpO1xuICAgICAgICBpZiAoeiAhPT0gMCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRGVjcnlwdGlvbiBmYWlsZWRcIik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc2VlZE1hc2sgPSB0aGlzLm1nZjEoaW50ZXJuYWxLZXkuYWxnb3JpdGhtLmhhc2gsIGRhdGFCbG9jaywgc2VlZC5sZW5ndGgpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNlZWQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHNlZWRbaV0gXj0gc2VlZE1hc2tbaV07XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZGF0YUJsb2NrTWFzayA9IHRoaXMubWdmMShpbnRlcm5hbEtleS5hbGdvcml0aG0uaGFzaCwgc2VlZCwgZGF0YUJsb2NrLmxlbmd0aCk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGF0YUJsb2NrLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBkYXRhQmxvY2tbaV0gXj0gZGF0YUJsb2NrTWFza1tpXTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBsYWJlbEhhc2ggPSBjcnlwdG9fX2RlZmF1bHQuY3JlYXRlSGFzaChpbnRlcm5hbEtleS5hbGdvcml0aG0uaGFzaC5uYW1lLnJlcGxhY2UoXCItXCIsIFwiXCIpKVxuICAgICAgICAgICAgLnVwZGF0ZShjb3JlLkJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b1VpbnQ4QXJyYXkoYWxnb3JpdGhtLmxhYmVsIHx8IG5ldyBVaW50OEFycmF5KDApKSlcbiAgICAgICAgICAgIC5kaWdlc3QoKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBoYXNoU2l6ZTsgaSsrKSB7XG4gICAgICAgICAgICBpZiAobGFiZWxIYXNoW2ldICE9PSBkYXRhQmxvY2tbaV0pIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJEZWNyeXB0aW9uIGZhaWxlZFwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsZXQgcHNFbmQgPSBoYXNoU2l6ZTtcbiAgICAgICAgZm9yICg7IHBzRW5kIDwgZGF0YUJsb2NrLmxlbmd0aDsgcHNFbmQrKykge1xuICAgICAgICAgICAgY29uc3QgcHN6ID0gZGF0YUJsb2NrW3BzRW5kXTtcbiAgICAgICAgICAgIGlmIChwc3ogPT09IDEpIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChwc3ogIT09IDApIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJEZWNyeXB0aW9uIGZhaWxlZFwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAocHNFbmQgPT09IGRhdGFCbG9jay5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkRlY3J5cHRpb24gZmFpbGVkXCIpO1xuICAgICAgICB9XG4gICAgICAgIHBrY3MwID0gZGF0YUJsb2NrLnN1YmFycmF5KHBzRW5kICsgMSk7XG4gICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShwa2NzMCkuYnVmZmVyO1xuICAgIH1cbiAgICBhc3luYyBvbkV4cG9ydEtleShmb3JtYXQsIGtleSkge1xuICAgICAgICByZXR1cm4gUnNhQ3J5cHRvLmV4cG9ydEtleShmb3JtYXQsIGdldENyeXB0b0tleShrZXkpKTtcbiAgICB9XG4gICAgYXN5bmMgb25JbXBvcnRLZXkoZm9ybWF0LCBrZXlEYXRhLCBhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgY29uc3Qga2V5ID0gYXdhaXQgUnNhQ3J5cHRvLmltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIHsgLi4uYWxnb3JpdGhtLCBuYW1lOiB0aGlzLm5hbWUgfSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcyk7XG4gICAgICAgIHJldHVybiBzZXRDcnlwdG9LZXkoa2V5KTtcbiAgICB9XG4gICAgY2hlY2tDcnlwdG9LZXkoa2V5LCBrZXlVc2FnZSkge1xuICAgICAgICBzdXBlci5jaGVja0NyeXB0b0tleShrZXksIGtleVVzYWdlKTtcbiAgICAgICAgY29uc3QgaW50ZXJuYWxLZXkgPSBnZXRDcnlwdG9LZXkoa2V5KTtcbiAgICAgICAgaWYgKCEoaW50ZXJuYWxLZXkgaW5zdGFuY2VvZiBSc2FQcml2YXRlS2V5IHx8IGludGVybmFsS2V5IGluc3RhbmNlb2YgUnNhUHVibGljS2V5KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImtleTogSXMgbm90IFJTQSBDcnlwdG9LZXlcIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgbWdmMShhbGdvcml0aG0sIHNlZWQsIGxlbmd0aCA9IDApIHtcbiAgICAgICAgY29uc3QgaGFzaFNpemUgPSBTaGFDcnlwdG8uc2l6ZShhbGdvcml0aG0pID4+IDM7XG4gICAgICAgIGNvbnN0IG1hc2sgPSBuZXcgVWludDhBcnJheShsZW5ndGgpO1xuICAgICAgICBjb25zdCBjb3VudGVyID0gbmV3IFVpbnQ4QXJyYXkoNCk7XG4gICAgICAgIGNvbnN0IGNodW5rcyA9IE1hdGguY2VpbChsZW5ndGggLyBoYXNoU2l6ZSk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2h1bmtzOyBpKyspIHtcbiAgICAgICAgICAgIGNvdW50ZXJbMF0gPSBpID4+PiAyNDtcbiAgICAgICAgICAgIGNvdW50ZXJbMV0gPSAoaSA+Pj4gMTYpICYgMjU1O1xuICAgICAgICAgICAgY291bnRlclsyXSA9IChpID4+PiA4KSAmIDI1NTtcbiAgICAgICAgICAgIGNvdW50ZXJbM10gPSBpICYgMjU1O1xuICAgICAgICAgICAgY29uc3Qgc3VibWFzayA9IG1hc2suc3ViYXJyYXkoaSAqIGhhc2hTaXplKTtcbiAgICAgICAgICAgIGxldCBjaHVuayA9IGNyeXB0b19fZGVmYXVsdC5jcmVhdGVIYXNoKGFsZ29yaXRobS5uYW1lLnJlcGxhY2UoXCItXCIsIFwiXCIpKVxuICAgICAgICAgICAgICAgIC51cGRhdGUoc2VlZClcbiAgICAgICAgICAgICAgICAudXBkYXRlKGNvdW50ZXIpXG4gICAgICAgICAgICAgICAgLmRpZ2VzdCgpO1xuICAgICAgICAgICAgaWYgKGNodW5rLmxlbmd0aCA+IHN1Ym1hc2subGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgY2h1bmsgPSBjaHVuay5zdWJhcnJheSgwLCBzdWJtYXNrLmxlbmd0aCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdWJtYXNrLnNldChjaHVuayk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1hc2s7XG4gICAgfVxufVxuXG5jbGFzcyBSc2FFc1Byb3ZpZGVyIGV4dGVuZHMgY29yZS5Qcm92aWRlckNyeXB0byB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUlNBRVMtUEtDUzEtdjFfNVwiO1xuICAgICAgICB0aGlzLnVzYWdlcyA9IHtcbiAgICAgICAgICAgIHB1YmxpY0tleTogW1wiZW5jcnlwdFwiLCBcIndyYXBLZXlcIl0sXG4gICAgICAgICAgICBwcml2YXRlS2V5OiBbXCJkZWNyeXB0XCIsIFwidW53cmFwS2V5XCJdLFxuICAgICAgICB9O1xuICAgIH1cbiAgICBhc3luYyBvbkdlbmVyYXRlS2V5KGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCBrZXlzID0gYXdhaXQgUnNhQ3J5cHRvLmdlbmVyYXRlS2V5KHtcbiAgICAgICAgICAgIC4uLmFsZ29yaXRobSxcbiAgICAgICAgICAgIG5hbWU6IHRoaXMubmFtZSxcbiAgICAgICAgfSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcyk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBwcml2YXRlS2V5OiBzZXRDcnlwdG9LZXkoa2V5cy5wcml2YXRlS2V5KSxcbiAgICAgICAgICAgIHB1YmxpY0tleTogc2V0Q3J5cHRvS2V5KGtleXMucHVibGljS2V5KSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgY2hlY2tHZW5lcmF0ZUtleVBhcmFtcyhhbGdvcml0aG0pIHtcbiAgICAgICAgdGhpcy5jaGVja1JlcXVpcmVkUHJvcGVydHkoYWxnb3JpdGhtLCBcInB1YmxpY0V4cG9uZW50XCIpO1xuICAgICAgICBpZiAoIShhbGdvcml0aG0ucHVibGljRXhwb25lbnQgJiYgYWxnb3JpdGhtLnB1YmxpY0V4cG9uZW50IGluc3RhbmNlb2YgVWludDhBcnJheSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJwdWJsaWNFeHBvbmVudDogTWlzc2luZyBvciBub3QgYSBVaW50OEFycmF5XCIpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHB1YmxpY0V4cG9uZW50ID0gQ29udmVydC5Ub0Jhc2U2NChhbGdvcml0aG0ucHVibGljRXhwb25lbnQpO1xuICAgICAgICBpZiAoIShwdWJsaWNFeHBvbmVudCA9PT0gXCJBdz09XCIgfHwgcHVibGljRXhwb25lbnQgPT09IFwiQVFBQlwiKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInB1YmxpY0V4cG9uZW50OiBNdXN0IGJlIFszXSBvciBbMSwwLDFdXCIpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY2hlY2tSZXF1aXJlZFByb3BlcnR5KGFsZ29yaXRobSwgXCJtb2R1bHVzTGVuZ3RoXCIpO1xuICAgICAgICBzd2l0Y2ggKGFsZ29yaXRobS5tb2R1bHVzTGVuZ3RoKSB7XG4gICAgICAgICAgICBjYXNlIDEwMjQ6XG4gICAgICAgICAgICBjYXNlIDIwNDg6XG4gICAgICAgICAgICBjYXNlIDQwOTY6XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJtb2R1bHVzTGVuZ3RoOiBNdXN0IGJlIDEwMjQsIDIwNDgsIG9yIDQwOTZcIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgYXN5bmMgb25FbmNyeXB0KGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLnRvQ3J5cHRvT3B0aW9ucyhrZXkpO1xuICAgICAgICBjb25zdCBlbmMgPSBjcnlwdG8ucHVibGljRW5jcnlwdChvcHRpb25zLCBuZXcgVWludDhBcnJheShkYXRhKSk7XG4gICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShlbmMpLmJ1ZmZlcjtcbiAgICB9XG4gICAgYXN5bmMgb25EZWNyeXB0KGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLnRvQ3J5cHRvT3B0aW9ucyhrZXkpO1xuICAgICAgICBjb25zdCBkZWMgPSBjcnlwdG8ucHJpdmF0ZURlY3J5cHQob3B0aW9ucywgbmV3IFVpbnQ4QXJyYXkoZGF0YSkpO1xuICAgICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoZGVjKS5idWZmZXI7XG4gICAgfVxuICAgIGFzeW5jIG9uRXhwb3J0S2V5KGZvcm1hdCwga2V5KSB7XG4gICAgICAgIHJldHVybiBSc2FDcnlwdG8uZXhwb3J0S2V5KGZvcm1hdCwgZ2V0Q3J5cHRvS2V5KGtleSkpO1xuICAgIH1cbiAgICBhc3luYyBvbkltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCBrZXkgPSBhd2FpdCBSc2FDcnlwdG8uaW1wb3J0S2V5KGZvcm1hdCwga2V5RGF0YSwgeyAuLi5hbGdvcml0aG0sIG5hbWU6IHRoaXMubmFtZSB9LCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgcmV0dXJuIHNldENyeXB0b0tleShrZXkpO1xuICAgIH1cbiAgICBjaGVja0NyeXB0b0tleShrZXksIGtleVVzYWdlKSB7XG4gICAgICAgIHN1cGVyLmNoZWNrQ3J5cHRvS2V5KGtleSwga2V5VXNhZ2UpO1xuICAgICAgICBjb25zdCBpbnRlcm5hbEtleSA9IGdldENyeXB0b0tleShrZXkpO1xuICAgICAgICBpZiAoIShpbnRlcm5hbEtleSBpbnN0YW5jZW9mIFJzYVByaXZhdGVLZXkgfHwgaW50ZXJuYWxLZXkgaW5zdGFuY2VvZiBSc2FQdWJsaWNLZXkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwia2V5OiBJcyBub3QgUlNBIENyeXB0b0tleVwiKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICB0b0NyeXB0b09wdGlvbnMoa2V5KSB7XG4gICAgICAgIGNvbnN0IHR5cGUgPSBrZXkudHlwZS50b1VwcGVyQ2FzZSgpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAga2V5OiBgLS0tLS1CRUdJTiAke3R5cGV9IEtFWS0tLS0tXFxuJHtnZXRDcnlwdG9LZXkoa2V5KS5kYXRhLnRvU3RyaW5nKFwiYmFzZTY0XCIpfVxcbi0tLS0tRU5EICR7dHlwZX0gS0VZLS0tLS1gLFxuICAgICAgICAgICAgcGFkZGluZzogY3J5cHRvLmNvbnN0YW50cy5SU0FfUEtDUzFfUEFERElORyxcbiAgICAgICAgfTtcbiAgICB9XG59XG5cbmNvbnN0IG5hbWVkT0lEcyA9IHtcbiAgICBcIjEuMi44NDAuMTAwNDUuMy4xLjdcIjogXCJQLTI1NlwiLFxuICAgIFwiUC0yNTZcIjogXCIxLjIuODQwLjEwMDQ1LjMuMS43XCIsXG4gICAgXCIxLjMuMTMyLjAuMzRcIjogXCJQLTM4NFwiLFxuICAgIFwiUC0zODRcIjogXCIxLjMuMTMyLjAuMzRcIixcbiAgICBcIjEuMy4xMzIuMC4zNVwiOiBcIlAtNTIxXCIsXG4gICAgXCJQLTUyMVwiOiBcIjEuMy4xMzIuMC4zNVwiLFxuICAgIFwiMS4zLjEzMi4wLjEwXCI6IFwiSy0yNTZcIixcbiAgICBcIkstMjU2XCI6IFwiMS4zLjEzMi4wLjEwXCIsXG4gICAgXCJicmFpbnBvb2xQMTYwcjFcIjogXCIxLjMuMzYuMy4zLjIuOC4xLjEuMVwiLFxuICAgIFwiMS4zLjM2LjMuMy4yLjguMS4xLjFcIjogXCJicmFpbnBvb2xQMTYwcjFcIixcbiAgICBcImJyYWlucG9vbFAxNjB0MVwiOiBcIjEuMy4zNi4zLjMuMi44LjEuMS4yXCIsXG4gICAgXCIxLjMuMzYuMy4zLjIuOC4xLjEuMlwiOiBcImJyYWlucG9vbFAxNjB0MVwiLFxuICAgIFwiYnJhaW5wb29sUDE5MnIxXCI6IFwiMS4zLjM2LjMuMy4yLjguMS4xLjNcIixcbiAgICBcIjEuMy4zNi4zLjMuMi44LjEuMS4zXCI6IFwiYnJhaW5wb29sUDE5MnIxXCIsXG4gICAgXCJicmFpbnBvb2xQMTkydDFcIjogXCIxLjMuMzYuMy4zLjIuOC4xLjEuNFwiLFxuICAgIFwiMS4zLjM2LjMuMy4yLjguMS4xLjRcIjogXCJicmFpbnBvb2xQMTkydDFcIixcbiAgICBcImJyYWlucG9vbFAyMjRyMVwiOiBcIjEuMy4zNi4zLjMuMi44LjEuMS41XCIsXG4gICAgXCIxLjMuMzYuMy4zLjIuOC4xLjEuNVwiOiBcImJyYWlucG9vbFAyMjRyMVwiLFxuICAgIFwiYnJhaW5wb29sUDIyNHQxXCI6IFwiMS4zLjM2LjMuMy4yLjguMS4xLjZcIixcbiAgICBcIjEuMy4zNi4zLjMuMi44LjEuMS42XCI6IFwiYnJhaW5wb29sUDIyNHQxXCIsXG4gICAgXCJicmFpbnBvb2xQMjU2cjFcIjogXCIxLjMuMzYuMy4zLjIuOC4xLjEuN1wiLFxuICAgIFwiMS4zLjM2LjMuMy4yLjguMS4xLjdcIjogXCJicmFpbnBvb2xQMjU2cjFcIixcbiAgICBcImJyYWlucG9vbFAyNTZ0MVwiOiBcIjEuMy4zNi4zLjMuMi44LjEuMS44XCIsXG4gICAgXCIxLjMuMzYuMy4zLjIuOC4xLjEuOFwiOiBcImJyYWlucG9vbFAyNTZ0MVwiLFxuICAgIFwiYnJhaW5wb29sUDMyMHIxXCI6IFwiMS4zLjM2LjMuMy4yLjguMS4xLjlcIixcbiAgICBcIjEuMy4zNi4zLjMuMi44LjEuMS45XCI6IFwiYnJhaW5wb29sUDMyMHIxXCIsXG4gICAgXCJicmFpbnBvb2xQMzIwdDFcIjogXCIxLjMuMzYuMy4zLjIuOC4xLjEuMTBcIixcbiAgICBcIjEuMy4zNi4zLjMuMi44LjEuMS4xMFwiOiBcImJyYWlucG9vbFAzMjB0MVwiLFxuICAgIFwiYnJhaW5wb29sUDM4NHIxXCI6IFwiMS4zLjM2LjMuMy4yLjguMS4xLjExXCIsXG4gICAgXCIxLjMuMzYuMy4zLjIuOC4xLjEuMTFcIjogXCJicmFpbnBvb2xQMzg0cjFcIixcbiAgICBcImJyYWlucG9vbFAzODR0MVwiOiBcIjEuMy4zNi4zLjMuMi44LjEuMS4xMlwiLFxuICAgIFwiMS4zLjM2LjMuMy4yLjguMS4xLjEyXCI6IFwiYnJhaW5wb29sUDM4NHQxXCIsXG4gICAgXCJicmFpbnBvb2xQNTEycjFcIjogXCIxLjMuMzYuMy4zLjIuOC4xLjEuMTNcIixcbiAgICBcIjEuMy4zNi4zLjMuMi44LjEuMS4xM1wiOiBcImJyYWlucG9vbFA1MTJyMVwiLFxuICAgIFwiYnJhaW5wb29sUDUxMnQxXCI6IFwiMS4zLjM2LjMuMy4yLjguMS4xLjE0XCIsXG4gICAgXCIxLjMuMzYuMy4zLjIuOC4xLjEuMTRcIjogXCJicmFpbnBvb2xQNTEydDFcIixcbn07XG5mdW5jdGlvbiBnZXRPaWRCeU5hbWVkQ3VydmUkMShuYW1lZEN1cnZlKSB7XG4gICAgY29uc3Qgb2lkID0gbmFtZWRPSURzW25hbWVkQ3VydmVdO1xuICAgIGlmICghb2lkKSB7XG4gICAgICAgIHRocm93IG5ldyBjb3JlLk9wZXJhdGlvbkVycm9yKGBDYW5ub3QgY29udmVydCBXZWJDcnlwdG8gbmFtZWQgY3VydmUgJyR7bmFtZWRDdXJ2ZX0nIHRvIE9JRGApO1xuICAgIH1cbiAgICByZXR1cm4gb2lkO1xufVxuXG5jbGFzcyBFY1ByaXZhdGVLZXkgZXh0ZW5kcyBBc3ltbWV0cmljS2V5IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy50eXBlID0gXCJwcml2YXRlXCI7XG4gICAgfVxuICAgIGdldEtleSgpIHtcbiAgICAgICAgY29uc3Qga2V5SW5mbyA9IEFzblBhcnNlci5wYXJzZSh0aGlzLmRhdGEsIGNvcmUuYXNuMS5Qcml2YXRlS2V5SW5mbyk7XG4gICAgICAgIHJldHVybiBBc25QYXJzZXIucGFyc2Uoa2V5SW5mby5wcml2YXRlS2V5LCBjb3JlLmFzbjEuRWNQcml2YXRlS2V5KTtcbiAgICB9XG4gICAgdG9KU09OKCkge1xuICAgICAgICBjb25zdCBrZXkgPSB0aGlzLmdldEtleSgpO1xuICAgICAgICBjb25zdCBqc29uID0ge1xuICAgICAgICAgICAga3R5OiBcIkVDXCIsXG4gICAgICAgICAgICBjcnY6IHRoaXMuYWxnb3JpdGhtLm5hbWVkQ3VydmUsXG4gICAgICAgICAgICBrZXlfb3BzOiB0aGlzLnVzYWdlcyxcbiAgICAgICAgICAgIGV4dDogdGhpcy5leHRyYWN0YWJsZSxcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oanNvbiwgSnNvblNlcmlhbGl6ZXIudG9KU09OKGtleSkpO1xuICAgIH1cbiAgICBmcm9tSlNPTihqc29uKSB7XG4gICAgICAgIGlmICghanNvbi5jcnYpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBjb3JlLk9wZXJhdGlvbkVycm9yKGBDYW5ub3QgZ2V0IG5hbWVkIGN1cnZlIGZyb20gSldLLiBQcm9wZXJ0eSAnY3J2JyBpcyByZXF1aXJlZGApO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGtleUluZm8gPSBuZXcgY29yZS5hc24xLlByaXZhdGVLZXlJbmZvKCk7XG4gICAgICAgIGtleUluZm8ucHJpdmF0ZUtleUFsZ29yaXRobS5hbGdvcml0aG0gPSBcIjEuMi44NDAuMTAwNDUuMi4xXCI7XG4gICAgICAgIGtleUluZm8ucHJpdmF0ZUtleUFsZ29yaXRobS5wYXJhbWV0ZXJzID0gQXNuU2VyaWFsaXplci5zZXJpYWxpemUobmV3IGNvcmUuYXNuMS5PYmplY3RJZGVudGlmaWVyKGdldE9pZEJ5TmFtZWRDdXJ2ZSQxKGpzb24uY3J2KSkpO1xuICAgICAgICBjb25zdCBrZXkgPSBKc29uUGFyc2VyLmZyb21KU09OKGpzb24sIHsgdGFyZ2V0U2NoZW1hOiBjb3JlLmFzbjEuRWNQcml2YXRlS2V5IH0pO1xuICAgICAgICBrZXlJbmZvLnByaXZhdGVLZXkgPSBBc25TZXJpYWxpemVyLnNlcmlhbGl6ZShrZXkpO1xuICAgICAgICB0aGlzLmRhdGEgPSBCdWZmZXIuZnJvbShBc25TZXJpYWxpemVyLnNlcmlhbGl6ZShrZXlJbmZvKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cblxuY2xhc3MgRWNQdWJsaWNLZXkgZXh0ZW5kcyBBc3ltbWV0cmljS2V5IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy50eXBlID0gXCJwdWJsaWNcIjtcbiAgICB9XG4gICAgZ2V0S2V5KCkge1xuICAgICAgICBjb25zdCBrZXlJbmZvID0gQXNuUGFyc2VyLnBhcnNlKHRoaXMuZGF0YSwgY29yZS5hc24xLlB1YmxpY0tleUluZm8pO1xuICAgICAgICByZXR1cm4gbmV3IGNvcmUuYXNuMS5FY1B1YmxpY0tleShrZXlJbmZvLnB1YmxpY0tleSk7XG4gICAgfVxuICAgIHRvSlNPTigpIHtcbiAgICAgICAgY29uc3Qga2V5ID0gdGhpcy5nZXRLZXkoKTtcbiAgICAgICAgY29uc3QganNvbiA9IHtcbiAgICAgICAgICAgIGt0eTogXCJFQ1wiLFxuICAgICAgICAgICAgY3J2OiB0aGlzLmFsZ29yaXRobS5uYW1lZEN1cnZlLFxuICAgICAgICAgICAga2V5X29wczogdGhpcy51c2FnZXMsXG4gICAgICAgICAgICBleHQ6IHRoaXMuZXh0cmFjdGFibGUsXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKGpzb24sIEpzb25TZXJpYWxpemVyLnRvSlNPTihrZXkpKTtcbiAgICB9XG4gICAgZnJvbUpTT04oanNvbikge1xuICAgICAgICBpZiAoIWpzb24uY3J2KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgY29yZS5PcGVyYXRpb25FcnJvcihgQ2Fubm90IGdldCBuYW1lZCBjdXJ2ZSBmcm9tIEpXSy4gUHJvcGVydHkgJ2NydicgaXMgcmVxdWlyZWRgKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBrZXkgPSBKc29uUGFyc2VyLmZyb21KU09OKGpzb24sIHsgdGFyZ2V0U2NoZW1hOiBjb3JlLmFzbjEuRWNQdWJsaWNLZXkgfSk7XG4gICAgICAgIGNvbnN0IGtleUluZm8gPSBuZXcgY29yZS5hc24xLlB1YmxpY0tleUluZm8oKTtcbiAgICAgICAga2V5SW5mby5wdWJsaWNLZXlBbGdvcml0aG0uYWxnb3JpdGhtID0gXCIxLjIuODQwLjEwMDQ1LjIuMVwiO1xuICAgICAgICBrZXlJbmZvLnB1YmxpY0tleUFsZ29yaXRobS5wYXJhbWV0ZXJzID0gQXNuU2VyaWFsaXplci5zZXJpYWxpemUobmV3IGNvcmUuYXNuMS5PYmplY3RJZGVudGlmaWVyKGdldE9pZEJ5TmFtZWRDdXJ2ZSQxKGpzb24uY3J2KSkpO1xuICAgICAgICBrZXlJbmZvLnB1YmxpY0tleSA9IEFzblNlcmlhbGl6ZXIudG9BU04oa2V5KS52YWx1ZUhleDtcbiAgICAgICAgdGhpcy5kYXRhID0gQnVmZmVyLmZyb20oQXNuU2VyaWFsaXplci5zZXJpYWxpemUoa2V5SW5mbykpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG5cbmNsYXNzIFNoYTFQcm92aWRlciBleHRlbmRzIGNvcmUuUHJvdmlkZXJDcnlwdG8ge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlNIQS0xXCI7XG4gICAgICAgIHRoaXMudXNhZ2VzID0gW107XG4gICAgfVxuICAgIGFzeW5jIG9uRGlnZXN0KGFsZ29yaXRobSwgZGF0YSkge1xuICAgICAgICByZXR1cm4gU2hhQ3J5cHRvLmRpZ2VzdChhbGdvcml0aG0sIGRhdGEpO1xuICAgIH1cbn1cblxuY2xhc3MgU2hhMjU2UHJvdmlkZXIgZXh0ZW5kcyBjb3JlLlByb3ZpZGVyQ3J5cHRvIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJTSEEtMjU2XCI7XG4gICAgICAgIHRoaXMudXNhZ2VzID0gW107XG4gICAgfVxuICAgIGFzeW5jIG9uRGlnZXN0KGFsZ29yaXRobSwgZGF0YSkge1xuICAgICAgICByZXR1cm4gU2hhQ3J5cHRvLmRpZ2VzdChhbGdvcml0aG0sIGRhdGEpO1xuICAgIH1cbn1cblxuY2xhc3MgU2hhMzg0UHJvdmlkZXIgZXh0ZW5kcyBjb3JlLlByb3ZpZGVyQ3J5cHRvIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJTSEEtMzg0XCI7XG4gICAgICAgIHRoaXMudXNhZ2VzID0gW107XG4gICAgfVxuICAgIGFzeW5jIG9uRGlnZXN0KGFsZ29yaXRobSwgZGF0YSkge1xuICAgICAgICByZXR1cm4gU2hhQ3J5cHRvLmRpZ2VzdChhbGdvcml0aG0sIGRhdGEpO1xuICAgIH1cbn1cblxuY2xhc3MgU2hhNTEyUHJvdmlkZXIgZXh0ZW5kcyBjb3JlLlByb3ZpZGVyQ3J5cHRvIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJTSEEtNTEyXCI7XG4gICAgICAgIHRoaXMudXNhZ2VzID0gW107XG4gICAgfVxuICAgIGFzeW5jIG9uRGlnZXN0KGFsZ29yaXRobSwgZGF0YSkge1xuICAgICAgICByZXR1cm4gU2hhQ3J5cHRvLmRpZ2VzdChhbGdvcml0aG0sIGRhdGEpO1xuICAgIH1cbn1cblxuY2xhc3MgU2hhMzI1NlByb3ZpZGVyIGV4dGVuZHMgY29yZS5Qcm92aWRlckNyeXB0byB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiU0hBMy0yNTZcIjtcbiAgICAgICAgdGhpcy51c2FnZXMgPSBbXTtcbiAgICB9XG4gICAgYXN5bmMgb25EaWdlc3QoYWxnb3JpdGhtLCBkYXRhKSB7XG4gICAgICAgIHJldHVybiBTaGFDcnlwdG8uZGlnZXN0KGFsZ29yaXRobSwgZGF0YSk7XG4gICAgfVxufVxuXG5jbGFzcyBTaGEzMzg0UHJvdmlkZXIgZXh0ZW5kcyBjb3JlLlByb3ZpZGVyQ3J5cHRvIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJTSEEzLTM4NFwiO1xuICAgICAgICB0aGlzLnVzYWdlcyA9IFtdO1xuICAgIH1cbiAgICBhc3luYyBvbkRpZ2VzdChhbGdvcml0aG0sIGRhdGEpIHtcbiAgICAgICAgcmV0dXJuIFNoYUNyeXB0by5kaWdlc3QoYWxnb3JpdGhtLCBkYXRhKTtcbiAgICB9XG59XG5cbmNsYXNzIFNoYTM1MTJQcm92aWRlciBleHRlbmRzIGNvcmUuUHJvdmlkZXJDcnlwdG8ge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlNIQTMtNTEyXCI7XG4gICAgICAgIHRoaXMudXNhZ2VzID0gW107XG4gICAgfVxuICAgIGFzeW5jIG9uRGlnZXN0KGFsZ29yaXRobSwgZGF0YSkge1xuICAgICAgICByZXR1cm4gU2hhQ3J5cHRvLmRpZ2VzdChhbGdvcml0aG0sIGRhdGEpO1xuICAgIH1cbn1cblxuY2xhc3MgRWNDcnlwdG8ge1xuICAgIHN0YXRpYyBhc3luYyBnZW5lcmF0ZUtleShhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgY29uc3QgcHJpdmF0ZUtleSA9IG5ldyBFY1ByaXZhdGVLZXkoKTtcbiAgICAgICAgcHJpdmF0ZUtleS5hbGdvcml0aG0gPSBhbGdvcml0aG07XG4gICAgICAgIHByaXZhdGVLZXkuZXh0cmFjdGFibGUgPSBleHRyYWN0YWJsZTtcbiAgICAgICAgcHJpdmF0ZUtleS51c2FnZXMgPSBrZXlVc2FnZXMuZmlsdGVyKCh1c2FnZSkgPT4gdGhpcy5wcml2YXRlS2V5VXNhZ2VzLmluZGV4T2YodXNhZ2UpICE9PSAtMSk7XG4gICAgICAgIGNvbnN0IHB1YmxpY0tleSA9IG5ldyBFY1B1YmxpY0tleSgpO1xuICAgICAgICBwdWJsaWNLZXkuYWxnb3JpdGhtID0gYWxnb3JpdGhtO1xuICAgICAgICBwdWJsaWNLZXkuZXh0cmFjdGFibGUgPSB0cnVlO1xuICAgICAgICBwdWJsaWNLZXkudXNhZ2VzID0ga2V5VXNhZ2VzLmZpbHRlcigodXNhZ2UpID0+IHRoaXMucHVibGljS2V5VXNhZ2VzLmluZGV4T2YodXNhZ2UpICE9PSAtMSk7XG4gICAgICAgIGNvbnN0IGtleXMgPSBjcnlwdG9fX2RlZmF1bHQuZ2VuZXJhdGVLZXlQYWlyU3luYyhcImVjXCIsIHtcbiAgICAgICAgICAgIG5hbWVkQ3VydmU6IHRoaXMuZ2V0T3BlblNTTE5hbWVkQ3VydmUoYWxnb3JpdGhtLm5hbWVkQ3VydmUpLFxuICAgICAgICAgICAgcHVibGljS2V5RW5jb2Rpbmc6IHtcbiAgICAgICAgICAgICAgICBmb3JtYXQ6IFwiZGVyXCIsXG4gICAgICAgICAgICAgICAgdHlwZTogXCJzcGtpXCIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcHJpdmF0ZUtleUVuY29kaW5nOiB7XG4gICAgICAgICAgICAgICAgZm9ybWF0OiBcImRlclwiLFxuICAgICAgICAgICAgICAgIHR5cGU6IFwicGtjczhcIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICBwcml2YXRlS2V5LmRhdGEgPSBrZXlzLnByaXZhdGVLZXk7XG4gICAgICAgIHB1YmxpY0tleS5kYXRhID0ga2V5cy5wdWJsaWNLZXk7XG4gICAgICAgIGNvbnN0IHJlcyA9IHtcbiAgICAgICAgICAgIHByaXZhdGVLZXksXG4gICAgICAgICAgICBwdWJsaWNLZXksXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxuICAgIHN0YXRpYyBhc3luYyBzaWduKGFsZ29yaXRobSwga2V5LCBkYXRhKSB7XG4gICAgICAgIGNvbnN0IGNyeXB0b0FsZyA9IFNoYUNyeXB0by5nZXRBbGdvcml0aG1OYW1lKGFsZ29yaXRobS5oYXNoKTtcbiAgICAgICAgY29uc3Qgc2lnbmVyID0gY3J5cHRvX19kZWZhdWx0LmNyZWF0ZVNpZ24oY3J5cHRvQWxnKTtcbiAgICAgICAgc2lnbmVyLnVwZGF0ZShCdWZmZXIuZnJvbShkYXRhKSk7XG4gICAgICAgIGlmICgha2V5LnBlbSkge1xuICAgICAgICAgICAga2V5LnBlbSA9IGAtLS0tLUJFR0lOIFBSSVZBVEUgS0VZLS0tLS1cXG4ke2tleS5kYXRhLnRvU3RyaW5nKFwiYmFzZTY0XCIpfVxcbi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS1gO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICBrZXk6IGtleS5wZW0sXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IHNpZ25lci5zaWduKG9wdGlvbnMpO1xuICAgICAgICBjb25zdCBlY1NpZ25hdHVyZSA9IEFzblBhcnNlci5wYXJzZShzaWduYXR1cmUsIGNvcmUuYXNuMS5FY0RzYVNpZ25hdHVyZSk7XG4gICAgICAgIGNvbnN0IHNpZ25hdHVyZVJhdyA9IGNvcmUuRWNVdGlscy5lbmNvZGVTaWduYXR1cmUoZWNTaWduYXR1cmUsIGNvcmUuRWNDdXJ2ZXMuZ2V0KGtleS5hbGdvcml0aG0ubmFtZWRDdXJ2ZSkuc2l6ZSk7XG4gICAgICAgIHJldHVybiBzaWduYXR1cmVSYXcuYnVmZmVyO1xuICAgIH1cbiAgICBzdGF0aWMgYXN5bmMgdmVyaWZ5KGFsZ29yaXRobSwga2V5LCBzaWduYXR1cmUsIGRhdGEpIHtcbiAgICAgICAgY29uc3QgY3J5cHRvQWxnID0gU2hhQ3J5cHRvLmdldEFsZ29yaXRobU5hbWUoYWxnb3JpdGhtLmhhc2gpO1xuICAgICAgICBjb25zdCBzaWduZXIgPSBjcnlwdG9fX2RlZmF1bHQuY3JlYXRlVmVyaWZ5KGNyeXB0b0FsZyk7XG4gICAgICAgIHNpZ25lci51cGRhdGUoQnVmZmVyLmZyb20oZGF0YSkpO1xuICAgICAgICBpZiAoIWtleS5wZW0pIHtcbiAgICAgICAgICAgIGtleS5wZW0gPSBgLS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS1cXG4ke2tleS5kYXRhLnRvU3RyaW5nKFwiYmFzZTY0XCIpfVxcbi0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLWA7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgIGtleToga2V5LnBlbSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgZWNTaWduYXR1cmUgPSBuZXcgY29yZS5hc24xLkVjRHNhU2lnbmF0dXJlKCk7XG4gICAgICAgIGNvbnN0IG5hbWVkQ3VydmUgPSBjb3JlLkVjQ3VydmVzLmdldChrZXkuYWxnb3JpdGhtLm5hbWVkQ3VydmUpO1xuICAgICAgICBjb25zdCBzaWduYXR1cmVQb2ludCA9IGNvcmUuRWNVdGlscy5kZWNvZGVTaWduYXR1cmUoc2lnbmF0dXJlLCBuYW1lZEN1cnZlLnNpemUpO1xuICAgICAgICBlY1NpZ25hdHVyZS5yID0gQnVmZmVyU291cmNlQ29udmVydGVyLnRvQXJyYXlCdWZmZXIoc2lnbmF0dXJlUG9pbnQucik7XG4gICAgICAgIGVjU2lnbmF0dXJlLnMgPSBCdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9BcnJheUJ1ZmZlcihzaWduYXR1cmVQb2ludC5zKTtcbiAgICAgICAgY29uc3QgZWNTaWduYXR1cmVSYXcgPSBCdWZmZXIuZnJvbShBc25TZXJpYWxpemVyLnNlcmlhbGl6ZShlY1NpZ25hdHVyZSkpO1xuICAgICAgICBjb25zdCBvayA9IHNpZ25lci52ZXJpZnkob3B0aW9ucywgZWNTaWduYXR1cmVSYXcpO1xuICAgICAgICByZXR1cm4gb2s7XG4gICAgfVxuICAgIHN0YXRpYyBhc3luYyBkZXJpdmVCaXRzKGFsZ29yaXRobSwgYmFzZUtleSwgbGVuZ3RoKSB7XG4gICAgICAgIGNvbnN0IGNyeXB0b0FsZyA9IHRoaXMuZ2V0T3BlblNTTE5hbWVkQ3VydmUoYmFzZUtleS5hbGdvcml0aG0ubmFtZWRDdXJ2ZSk7XG4gICAgICAgIGNvbnN0IGVjZGggPSBjcnlwdG9fX2RlZmF1bHQuY3JlYXRlRUNESChjcnlwdG9BbGcpO1xuICAgICAgICBjb25zdCBhc25Qcml2YXRlS2V5ID0gQXNuUGFyc2VyLnBhcnNlKGJhc2VLZXkuZGF0YSwgY29yZS5hc24xLlByaXZhdGVLZXlJbmZvKTtcbiAgICAgICAgY29uc3QgYXNuRWNQcml2YXRlS2V5ID0gQXNuUGFyc2VyLnBhcnNlKGFzblByaXZhdGVLZXkucHJpdmF0ZUtleSwgY29yZS5hc24xLkVjUHJpdmF0ZUtleSk7XG4gICAgICAgIGVjZGguc2V0UHJpdmF0ZUtleShCdWZmZXIuZnJvbShhc25FY1ByaXZhdGVLZXkucHJpdmF0ZUtleSkpO1xuICAgICAgICBjb25zdCBhc25QdWJsaWNLZXkgPSBBc25QYXJzZXIucGFyc2UoYWxnb3JpdGhtLnB1YmxpYy5kYXRhLCBjb3JlLmFzbjEuUHVibGljS2V5SW5mbyk7XG4gICAgICAgIGNvbnN0IGJpdHMgPSBlY2RoLmNvbXB1dGVTZWNyZXQoQnVmZmVyLmZyb20oYXNuUHVibGljS2V5LnB1YmxpY0tleSkpO1xuICAgICAgICBpZiAobGVuZ3RoID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gYml0cztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoYml0cykuYnVmZmVyLnNsaWNlKDAsIGxlbmd0aCA+PiAzKTtcbiAgICB9XG4gICAgc3RhdGljIGFzeW5jIGV4cG9ydEtleShmb3JtYXQsIGtleSkge1xuICAgICAgICBzd2l0Y2ggKGZvcm1hdC50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgICAgICBjYXNlIFwiandrXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIEpzb25TZXJpYWxpemVyLnRvSlNPTihrZXkpO1xuICAgICAgICAgICAgY2FzZSBcInBrY3M4XCI6XG4gICAgICAgICAgICBjYXNlIFwic3BraVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShrZXkuZGF0YSkuYnVmZmVyO1xuICAgICAgICAgICAgY2FzZSBcInJhd1wiOiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcHVibGljS2V5SW5mbyA9IEFzblBhcnNlci5wYXJzZShrZXkuZGF0YSwgY29yZS5hc24xLlB1YmxpY0tleUluZm8pO1xuICAgICAgICAgICAgICAgIHJldHVybiBwdWJsaWNLZXlJbmZvLnB1YmxpY0tleTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IGNvcmUuT3BlcmF0aW9uRXJyb3IoXCJmb3JtYXQ6IE11c3QgYmUgJ2p3aycsICdyYXcnLCBwa2NzOCcgb3IgJ3Nwa2knXCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHN0YXRpYyBhc3luYyBpbXBvcnRLZXkoZm9ybWF0LCBrZXlEYXRhLCBhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgc3dpdGNoIChmb3JtYXQudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgY2FzZSBcImp3a1wiOiB7XG4gICAgICAgICAgICAgICAgY29uc3QgandrID0ga2V5RGF0YTtcbiAgICAgICAgICAgICAgICBpZiAoandrLmQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYXNuS2V5ID0gSnNvblBhcnNlci5mcm9tSlNPTihrZXlEYXRhLCB7IHRhcmdldFNjaGVtYTogY29yZS5hc24xLkVjUHJpdmF0ZUtleSB9KTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW1wb3J0UHJpdmF0ZUtleShhc25LZXksIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhc25LZXkgPSBKc29uUGFyc2VyLmZyb21KU09OKGtleURhdGEsIHsgdGFyZ2V0U2NoZW1hOiBjb3JlLmFzbjEuRWNQdWJsaWNLZXkgfSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmltcG9ydFB1YmxpY0tleShhc25LZXksIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInJhd1wiOiB7XG4gICAgICAgICAgICAgICAgY29uc3QgYXNuS2V5ID0gbmV3IGNvcmUuYXNuMS5FY1B1YmxpY0tleShrZXlEYXRhKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5pbXBvcnRQdWJsaWNLZXkoYXNuS2V5LCBhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInNwa2lcIjoge1xuICAgICAgICAgICAgICAgIGNvbnN0IGtleUluZm8gPSBBc25QYXJzZXIucGFyc2UobmV3IFVpbnQ4QXJyYXkoa2V5RGF0YSksIGNvcmUuYXNuMS5QdWJsaWNLZXlJbmZvKTtcbiAgICAgICAgICAgICAgICBjb25zdCBhc25LZXkgPSBuZXcgY29yZS5hc24xLkVjUHVibGljS2V5KGtleUluZm8ucHVibGljS2V5KTtcbiAgICAgICAgICAgICAgICB0aGlzLmFzc2VydEtleVBhcmFtZXRlcnMoa2V5SW5mby5wdWJsaWNLZXlBbGdvcml0aG0ucGFyYW1ldGVycywgYWxnb3JpdGhtLm5hbWVkQ3VydmUpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmltcG9ydFB1YmxpY0tleShhc25LZXksIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwicGtjczhcIjoge1xuICAgICAgICAgICAgICAgIGNvbnN0IGtleUluZm8gPSBBc25QYXJzZXIucGFyc2UobmV3IFVpbnQ4QXJyYXkoa2V5RGF0YSksIGNvcmUuYXNuMS5Qcml2YXRlS2V5SW5mbyk7XG4gICAgICAgICAgICAgICAgY29uc3QgYXNuS2V5ID0gQXNuUGFyc2VyLnBhcnNlKGtleUluZm8ucHJpdmF0ZUtleSwgY29yZS5hc24xLkVjUHJpdmF0ZUtleSk7XG4gICAgICAgICAgICAgICAgdGhpcy5hc3NlcnRLZXlQYXJhbWV0ZXJzKGtleUluZm8ucHJpdmF0ZUtleUFsZ29yaXRobS5wYXJhbWV0ZXJzLCBhbGdvcml0aG0ubmFtZWRDdXJ2ZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW1wb3J0UHJpdmF0ZUtleShhc25LZXksIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBjb3JlLk9wZXJhdGlvbkVycm9yKFwiZm9ybWF0OiBNdXN0IGJlICdqd2snLCAncmF3JywgJ3BrY3M4JyBvciAnc3BraSdcIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIGFzc2VydEtleVBhcmFtZXRlcnMocGFyYW1ldGVycywgbmFtZWRDdXJ2ZSkge1xuICAgICAgICBpZiAoIXBhcmFtZXRlcnMpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBjb3JlLkNyeXB0b0Vycm9yKFwiS2V5IGluZm8gZG9lc24ndCBoYXZlIHJlcXVpcmVkIHBhcmFtZXRlcnNcIik7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IG5hbWVkQ3VydmVJZGVudGlmaWVyID0gXCJcIjtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIG5hbWVkQ3VydmVJZGVudGlmaWVyID0gQXNuUGFyc2VyLnBhcnNlKHBhcmFtZXRlcnMsIGNvcmUuYXNuMS5PYmplY3RJZGVudGlmaWVyKS52YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IGNvcmUuQ3J5cHRvRXJyb3IoXCJDYW5ub3QgcmVhZCBrZXkgaW5mbyBwYXJhbWV0ZXJzXCIpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChnZXRPaWRCeU5hbWVkQ3VydmUkMShuYW1lZEN1cnZlKSAhPT0gbmFtZWRDdXJ2ZUlkZW50aWZpZXIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBjb3JlLkNyeXB0b0Vycm9yKFwiS2V5IGluZm8gcGFyYW1ldGVyIGRvZXNuJ3QgbWF0Y2ggdG8gbmFtZWQgY3VydmVcIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIGFzeW5jIGltcG9ydFByaXZhdGVLZXkoYXNuS2V5LCBhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgY29uc3Qga2V5SW5mbyA9IG5ldyBjb3JlLmFzbjEuUHJpdmF0ZUtleUluZm8oKTtcbiAgICAgICAga2V5SW5mby5wcml2YXRlS2V5QWxnb3JpdGhtLmFsZ29yaXRobSA9IFwiMS4yLjg0MC4xMDA0NS4yLjFcIjtcbiAgICAgICAga2V5SW5mby5wcml2YXRlS2V5QWxnb3JpdGhtLnBhcmFtZXRlcnMgPSBBc25TZXJpYWxpemVyLnNlcmlhbGl6ZShuZXcgY29yZS5hc24xLk9iamVjdElkZW50aWZpZXIoZ2V0T2lkQnlOYW1lZEN1cnZlJDEoYWxnb3JpdGhtLm5hbWVkQ3VydmUpKSk7XG4gICAgICAgIGtleUluZm8ucHJpdmF0ZUtleSA9IEFzblNlcmlhbGl6ZXIuc2VyaWFsaXplKGFzbktleSk7XG4gICAgICAgIGNvbnN0IGtleSA9IG5ldyBFY1ByaXZhdGVLZXkoKTtcbiAgICAgICAga2V5LmRhdGEgPSBCdWZmZXIuZnJvbShBc25TZXJpYWxpemVyLnNlcmlhbGl6ZShrZXlJbmZvKSk7XG4gICAgICAgIGtleS5hbGdvcml0aG0gPSBPYmplY3QuYXNzaWduKHt9LCBhbGdvcml0aG0pO1xuICAgICAgICBrZXkuZXh0cmFjdGFibGUgPSBleHRyYWN0YWJsZTtcbiAgICAgICAga2V5LnVzYWdlcyA9IGtleVVzYWdlcztcbiAgICAgICAgcmV0dXJuIGtleTtcbiAgICB9XG4gICAgc3RhdGljIGFzeW5jIGltcG9ydFB1YmxpY0tleShhc25LZXksIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCBrZXlJbmZvID0gbmV3IGNvcmUuYXNuMS5QdWJsaWNLZXlJbmZvKCk7XG4gICAgICAgIGtleUluZm8ucHVibGljS2V5QWxnb3JpdGhtLmFsZ29yaXRobSA9IFwiMS4yLjg0MC4xMDA0NS4yLjFcIjtcbiAgICAgICAgY29uc3QgbmFtZWRDdXJ2ZSA9IGdldE9pZEJ5TmFtZWRDdXJ2ZSQxKGFsZ29yaXRobS5uYW1lZEN1cnZlKTtcbiAgICAgICAga2V5SW5mby5wdWJsaWNLZXlBbGdvcml0aG0ucGFyYW1ldGVycyA9IEFzblNlcmlhbGl6ZXIuc2VyaWFsaXplKG5ldyBjb3JlLmFzbjEuT2JqZWN0SWRlbnRpZmllcihuYW1lZEN1cnZlKSk7XG4gICAgICAgIGtleUluZm8ucHVibGljS2V5ID0gYXNuS2V5LnZhbHVlO1xuICAgICAgICBjb25zdCBrZXkgPSBuZXcgRWNQdWJsaWNLZXkoKTtcbiAgICAgICAga2V5LmRhdGEgPSBCdWZmZXIuZnJvbShBc25TZXJpYWxpemVyLnNlcmlhbGl6ZShrZXlJbmZvKSk7XG4gICAgICAgIGtleS5hbGdvcml0aG0gPSBPYmplY3QuYXNzaWduKHt9LCBhbGdvcml0aG0pO1xuICAgICAgICBrZXkuZXh0cmFjdGFibGUgPSBleHRyYWN0YWJsZTtcbiAgICAgICAga2V5LnVzYWdlcyA9IGtleVVzYWdlcztcbiAgICAgICAgcmV0dXJuIGtleTtcbiAgICB9XG4gICAgc3RhdGljIGdldE9wZW5TU0xOYW1lZEN1cnZlKGN1cnZlKSB7XG4gICAgICAgIHN3aXRjaCAoY3VydmUudG9VcHBlckNhc2UoKSkge1xuICAgICAgICAgICAgY2FzZSBcIlAtMjU2XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwicHJpbWUyNTZ2MVwiO1xuICAgICAgICAgICAgY2FzZSBcIkstMjU2XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwic2VjcDI1NmsxXCI7XG4gICAgICAgICAgICBjYXNlIFwiUC0zODRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJzZWNwMzg0cjFcIjtcbiAgICAgICAgICAgIGNhc2UgXCJQLTUyMVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcInNlY3A1MjFyMVwiO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gY3VydmU7XG4gICAgICAgIH1cbiAgICB9XG59XG5FY0NyeXB0by5wdWJsaWNLZXlVc2FnZXMgPSBbXCJ2ZXJpZnlcIl07XG5FY0NyeXB0by5wcml2YXRlS2V5VXNhZ2VzID0gW1wic2lnblwiLCBcImRlcml2ZUtleVwiLCBcImRlcml2ZUJpdHNcIl07XG5cbmNsYXNzIEVjZHNhUHJvdmlkZXIgZXh0ZW5kcyBjb3JlLkVjZHNhUHJvdmlkZXIge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWVkQ3VydmVzID0gY29yZS5FY0N1cnZlcy5uYW1lcztcbiAgICAgICAgdGhpcy5oYXNoQWxnb3JpdGhtcyA9IFtcbiAgICAgICAgICAgIFwiU0hBLTFcIiwgXCJTSEEtMjU2XCIsIFwiU0hBLTM4NFwiLCBcIlNIQS01MTJcIixcbiAgICAgICAgICAgIFwic2hha2UxMjhcIiwgXCJzaGFrZTI1NlwiLFxuICAgICAgICAgICAgXCJTSEEzLTI1NlwiLCBcIlNIQTMtMzg0XCIsIFwiU0hBMy01MTJcIlxuICAgICAgICBdO1xuICAgIH1cbiAgICBhc3luYyBvbkdlbmVyYXRlS2V5KGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCBrZXlzID0gYXdhaXQgRWNDcnlwdG8uZ2VuZXJhdGVLZXkoe1xuICAgICAgICAgICAgLi4uYWxnb3JpdGhtLFxuICAgICAgICAgICAgbmFtZTogdGhpcy5uYW1lLFxuICAgICAgICB9LCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHByaXZhdGVLZXk6IHNldENyeXB0b0tleShrZXlzLnByaXZhdGVLZXkpLFxuICAgICAgICAgICAgcHVibGljS2V5OiBzZXRDcnlwdG9LZXkoa2V5cy5wdWJsaWNLZXkpLFxuICAgICAgICB9O1xuICAgIH1cbiAgICBhc3luYyBvblNpZ24oYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgcmV0dXJuIEVjQ3J5cHRvLnNpZ24oYWxnb3JpdGhtLCBnZXRDcnlwdG9LZXkoa2V5KSwgbmV3IFVpbnQ4QXJyYXkoZGF0YSkpO1xuICAgIH1cbiAgICBhc3luYyBvblZlcmlmeShhbGdvcml0aG0sIGtleSwgc2lnbmF0dXJlLCBkYXRhKSB7XG4gICAgICAgIHJldHVybiBFY0NyeXB0by52ZXJpZnkoYWxnb3JpdGhtLCBnZXRDcnlwdG9LZXkoa2V5KSwgbmV3IFVpbnQ4QXJyYXkoc2lnbmF0dXJlKSwgbmV3IFVpbnQ4QXJyYXkoZGF0YSkpO1xuICAgIH1cbiAgICBhc3luYyBvbkV4cG9ydEtleShmb3JtYXQsIGtleSkge1xuICAgICAgICByZXR1cm4gRWNDcnlwdG8uZXhwb3J0S2V5KGZvcm1hdCwgZ2V0Q3J5cHRvS2V5KGtleSkpO1xuICAgIH1cbiAgICBhc3luYyBvbkltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCBrZXkgPSBhd2FpdCBFY0NyeXB0by5pbXBvcnRLZXkoZm9ybWF0LCBrZXlEYXRhLCB7IC4uLmFsZ29yaXRobSwgbmFtZTogdGhpcy5uYW1lIH0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpO1xuICAgICAgICByZXR1cm4gc2V0Q3J5cHRvS2V5KGtleSk7XG4gICAgfVxuICAgIGNoZWNrQ3J5cHRvS2V5KGtleSwga2V5VXNhZ2UpIHtcbiAgICAgICAgc3VwZXIuY2hlY2tDcnlwdG9LZXkoa2V5LCBrZXlVc2FnZSk7XG4gICAgICAgIGNvbnN0IGludGVybmFsS2V5ID0gZ2V0Q3J5cHRvS2V5KGtleSk7XG4gICAgICAgIGlmICghKGludGVybmFsS2V5IGluc3RhbmNlb2YgRWNQcml2YXRlS2V5IHx8IGludGVybmFsS2V5IGluc3RhbmNlb2YgRWNQdWJsaWNLZXkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwia2V5OiBJcyBub3QgRUMgQ3J5cHRvS2V5XCIpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5jbGFzcyBFY2RoUHJvdmlkZXIgZXh0ZW5kcyBjb3JlLkVjZGhQcm92aWRlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZWRDdXJ2ZXMgPSBjb3JlLkVjQ3VydmVzLm5hbWVzO1xuICAgIH1cbiAgICBhc3luYyBvbkdlbmVyYXRlS2V5KGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCBrZXlzID0gYXdhaXQgRWNDcnlwdG8uZ2VuZXJhdGVLZXkoe1xuICAgICAgICAgICAgLi4uYWxnb3JpdGhtLFxuICAgICAgICAgICAgbmFtZTogdGhpcy5uYW1lLFxuICAgICAgICB9LCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHByaXZhdGVLZXk6IHNldENyeXB0b0tleShrZXlzLnByaXZhdGVLZXkpLFxuICAgICAgICAgICAgcHVibGljS2V5OiBzZXRDcnlwdG9LZXkoa2V5cy5wdWJsaWNLZXkpLFxuICAgICAgICB9O1xuICAgIH1cbiAgICBhc3luYyBvbkV4cG9ydEtleShmb3JtYXQsIGtleSkge1xuICAgICAgICByZXR1cm4gRWNDcnlwdG8uZXhwb3J0S2V5KGZvcm1hdCwgZ2V0Q3J5cHRvS2V5KGtleSkpO1xuICAgIH1cbiAgICBhc3luYyBvbkltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCBrZXkgPSBhd2FpdCBFY0NyeXB0by5pbXBvcnRLZXkoZm9ybWF0LCBrZXlEYXRhLCB7IC4uLmFsZ29yaXRobSwgbmFtZTogdGhpcy5uYW1lIH0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpO1xuICAgICAgICByZXR1cm4gc2V0Q3J5cHRvS2V5KGtleSk7XG4gICAgfVxuICAgIGNoZWNrQ3J5cHRvS2V5KGtleSwga2V5VXNhZ2UpIHtcbiAgICAgICAgc3VwZXIuY2hlY2tDcnlwdG9LZXkoa2V5LCBrZXlVc2FnZSk7XG4gICAgICAgIGNvbnN0IGludGVybmFsS2V5ID0gZ2V0Q3J5cHRvS2V5KGtleSk7XG4gICAgICAgIGlmICghKGludGVybmFsS2V5IGluc3RhbmNlb2YgRWNQcml2YXRlS2V5IHx8IGludGVybmFsS2V5IGluc3RhbmNlb2YgRWNQdWJsaWNLZXkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwia2V5OiBJcyBub3QgRUMgQ3J5cHRvS2V5XCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFzeW5jIG9uRGVyaXZlQml0cyhhbGdvcml0aG0sIGJhc2VLZXksIGxlbmd0aCkge1xuICAgICAgICBjb25zdCBiaXRzID0gYXdhaXQgRWNDcnlwdG8uZGVyaXZlQml0cyh7IC4uLmFsZ29yaXRobSwgcHVibGljOiBnZXRDcnlwdG9LZXkoYWxnb3JpdGhtLnB1YmxpYykgfSwgZ2V0Q3J5cHRvS2V5KGJhc2VLZXkpLCBsZW5ndGgpO1xuICAgICAgICByZXR1cm4gYml0cztcbiAgICB9XG59XG5cbmNvbnN0IGVkT0lEcyA9IHtcbiAgICBbY29yZS5hc24xLmlkRWQ0NDhdOiBcIkVkNDQ4XCIsXG4gICAgXCJlZDQ0OFwiOiBjb3JlLmFzbjEuaWRFZDQ0OCxcbiAgICBbY29yZS5hc24xLmlkWDQ0OF06IFwiWDQ0OFwiLFxuICAgIFwieDQ0OFwiOiBjb3JlLmFzbjEuaWRYNDQ4LFxuICAgIFtjb3JlLmFzbjEuaWRFZDI1NTE5XTogXCJFZDI1NTE5XCIsXG4gICAgXCJlZDI1NTE5XCI6IGNvcmUuYXNuMS5pZEVkMjU1MTksXG4gICAgW2NvcmUuYXNuMS5pZFgyNTUxOV06IFwiWDI1NTE5XCIsXG4gICAgXCJ4MjU1MTlcIjogY29yZS5hc24xLmlkWDI1NTE5LFxufTtcbmZ1bmN0aW9uIGdldE9pZEJ5TmFtZWRDdXJ2ZShuYW1lZEN1cnZlKSB7XG4gICAgY29uc3Qgb2lkID0gZWRPSURzW25hbWVkQ3VydmUudG9Mb3dlckNhc2UoKV07XG4gICAgaWYgKCFvaWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IGNvcmUuT3BlcmF0aW9uRXJyb3IoYENhbm5vdCBjb252ZXJ0IFdlYkNyeXB0byBuYW1lZCBjdXJ2ZSAnJHtuYW1lZEN1cnZlfScgdG8gT0lEYCk7XG4gICAgfVxuICAgIHJldHVybiBvaWQ7XG59XG5cbmNsYXNzIEVkUHJpdmF0ZUtleSBleHRlbmRzIEFzeW1tZXRyaWNLZXkge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLnR5cGUgPSBcInByaXZhdGVcIjtcbiAgICB9XG4gICAgZ2V0S2V5KCkge1xuICAgICAgICBjb25zdCBrZXlJbmZvID0gQXNuUGFyc2VyLnBhcnNlKHRoaXMuZGF0YSwgY29yZS5hc24xLlByaXZhdGVLZXlJbmZvKTtcbiAgICAgICAgcmV0dXJuIEFzblBhcnNlci5wYXJzZShrZXlJbmZvLnByaXZhdGVLZXksIGNvcmUuYXNuMS5DdXJ2ZVByaXZhdGVLZXkpO1xuICAgIH1cbiAgICB0b0pTT04oKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IHRoaXMuZ2V0S2V5KCk7XG4gICAgICAgIGNvbnN0IGpzb24gPSB7XG4gICAgICAgICAgICBrdHk6IFwiT0tQXCIsXG4gICAgICAgICAgICBjcnY6IHRoaXMuYWxnb3JpdGhtLm5hbWVkQ3VydmUsXG4gICAgICAgICAgICBrZXlfb3BzOiB0aGlzLnVzYWdlcyxcbiAgICAgICAgICAgIGV4dDogdGhpcy5leHRyYWN0YWJsZSxcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oanNvbiwgSnNvblNlcmlhbGl6ZXIudG9KU09OKGtleSkpO1xuICAgIH1cbiAgICBmcm9tSlNPTihqc29uKSB7XG4gICAgICAgIGlmICghanNvbi5jcnYpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBjb3JlLk9wZXJhdGlvbkVycm9yKGBDYW5ub3QgZ2V0IG5hbWVkIGN1cnZlIGZyb20gSldLLiBQcm9wZXJ0eSAnY3J2JyBpcyByZXF1aXJlZGApO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGtleUluZm8gPSBuZXcgY29yZS5hc24xLlByaXZhdGVLZXlJbmZvKCk7XG4gICAgICAgIGtleUluZm8ucHJpdmF0ZUtleUFsZ29yaXRobS5hbGdvcml0aG0gPSBnZXRPaWRCeU5hbWVkQ3VydmUoanNvbi5jcnYpO1xuICAgICAgICBjb25zdCBrZXkgPSBKc29uUGFyc2VyLmZyb21KU09OKGpzb24sIHsgdGFyZ2V0U2NoZW1hOiBjb3JlLmFzbjEuQ3VydmVQcml2YXRlS2V5IH0pO1xuICAgICAgICBrZXlJbmZvLnByaXZhdGVLZXkgPSBBc25TZXJpYWxpemVyLnNlcmlhbGl6ZShrZXkpO1xuICAgICAgICB0aGlzLmRhdGEgPSBCdWZmZXIuZnJvbShBc25TZXJpYWxpemVyLnNlcmlhbGl6ZShrZXlJbmZvKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cblxuY2xhc3MgRWRQdWJsaWNLZXkgZXh0ZW5kcyBBc3ltbWV0cmljS2V5IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy50eXBlID0gXCJwdWJsaWNcIjtcbiAgICB9XG4gICAgZ2V0S2V5KCkge1xuICAgICAgICBjb25zdCBrZXlJbmZvID0gQXNuUGFyc2VyLnBhcnNlKHRoaXMuZGF0YSwgY29yZS5hc24xLlB1YmxpY0tleUluZm8pO1xuICAgICAgICByZXR1cm4ga2V5SW5mby5wdWJsaWNLZXk7XG4gICAgfVxuICAgIHRvSlNPTigpIHtcbiAgICAgICAgY29uc3Qga2V5ID0gdGhpcy5nZXRLZXkoKTtcbiAgICAgICAgY29uc3QganNvbiA9IHtcbiAgICAgICAgICAgIGt0eTogXCJPS1BcIixcbiAgICAgICAgICAgIGNydjogdGhpcy5hbGdvcml0aG0ubmFtZWRDdXJ2ZSxcbiAgICAgICAgICAgIGtleV9vcHM6IHRoaXMudXNhZ2VzLFxuICAgICAgICAgICAgZXh0OiB0aGlzLmV4dHJhY3RhYmxlLFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihqc29uLCB7XG4gICAgICAgICAgICB4OiBDb252ZXJ0LlRvQmFzZTY0VXJsKGtleSlcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGZyb21KU09OKGpzb24pIHtcbiAgICAgICAgaWYgKCFqc29uLmNydikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IGNvcmUuT3BlcmF0aW9uRXJyb3IoYENhbm5vdCBnZXQgbmFtZWQgY3VydmUgZnJvbSBKV0suIFByb3BlcnR5ICdjcnYnIGlzIHJlcXVpcmVkYCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFqc29uLngpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBjb3JlLk9wZXJhdGlvbkVycm9yKGBDYW5ub3QgZ2V0IHByb3BlcnR5IGZyb20gSldLLiBQcm9wZXJ0eSAneCcgaXMgcmVxdWlyZWRgKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBrZXlJbmZvID0gbmV3IGNvcmUuYXNuMS5QdWJsaWNLZXlJbmZvKCk7XG4gICAgICAgIGtleUluZm8ucHVibGljS2V5QWxnb3JpdGhtLmFsZ29yaXRobSA9IGdldE9pZEJ5TmFtZWRDdXJ2ZShqc29uLmNydik7XG4gICAgICAgIGtleUluZm8ucHVibGljS2V5ID0gQ29udmVydC5Gcm9tQmFzZTY0VXJsKGpzb24ueCk7XG4gICAgICAgIHRoaXMuZGF0YSA9IEJ1ZmZlci5mcm9tKEFzblNlcmlhbGl6ZXIuc2VyaWFsaXplKGtleUluZm8pKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuXG5jbGFzcyBFZENyeXB0byB7XG4gICAgc3RhdGljIGFzeW5jIGdlbmVyYXRlS2V5KGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCBwcml2YXRlS2V5ID0gbmV3IEVkUHJpdmF0ZUtleSgpO1xuICAgICAgICBwcml2YXRlS2V5LmFsZ29yaXRobSA9IGFsZ29yaXRobTtcbiAgICAgICAgcHJpdmF0ZUtleS5leHRyYWN0YWJsZSA9IGV4dHJhY3RhYmxlO1xuICAgICAgICBwcml2YXRlS2V5LnVzYWdlcyA9IGtleVVzYWdlcy5maWx0ZXIoKHVzYWdlKSA9PiB0aGlzLnByaXZhdGVLZXlVc2FnZXMuaW5kZXhPZih1c2FnZSkgIT09IC0xKTtcbiAgICAgICAgY29uc3QgcHVibGljS2V5ID0gbmV3IEVkUHVibGljS2V5KCk7XG4gICAgICAgIHB1YmxpY0tleS5hbGdvcml0aG0gPSBhbGdvcml0aG07XG4gICAgICAgIHB1YmxpY0tleS5leHRyYWN0YWJsZSA9IHRydWU7XG4gICAgICAgIHB1YmxpY0tleS51c2FnZXMgPSBrZXlVc2FnZXMuZmlsdGVyKCh1c2FnZSkgPT4gdGhpcy5wdWJsaWNLZXlVc2FnZXMuaW5kZXhPZih1c2FnZSkgIT09IC0xKTtcbiAgICAgICAgY29uc3QgdHlwZSA9IGFsZ29yaXRobS5uYW1lZEN1cnZlLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIGNvbnN0IGtleXMgPSBjcnlwdG9fX2RlZmF1bHQuZ2VuZXJhdGVLZXlQYWlyU3luYyh0eXBlLCB7XG4gICAgICAgICAgICBwdWJsaWNLZXlFbmNvZGluZzoge1xuICAgICAgICAgICAgICAgIGZvcm1hdDogXCJkZXJcIixcbiAgICAgICAgICAgICAgICB0eXBlOiBcInNwa2lcIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBwcml2YXRlS2V5RW5jb2Rpbmc6IHtcbiAgICAgICAgICAgICAgICBmb3JtYXQ6IFwiZGVyXCIsXG4gICAgICAgICAgICAgICAgdHlwZTogXCJwa2NzOFwiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIHByaXZhdGVLZXkuZGF0YSA9IGtleXMucHJpdmF0ZUtleTtcbiAgICAgICAgcHVibGljS2V5LmRhdGEgPSBrZXlzLnB1YmxpY0tleTtcbiAgICAgICAgY29uc3QgcmVzID0ge1xuICAgICAgICAgICAgcHJpdmF0ZUtleSxcbiAgICAgICAgICAgIHB1YmxpY0tleSxcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG4gICAgc3RhdGljIGFzeW5jIHNpZ24oYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgaWYgKCFrZXkucGVtKSB7XG4gICAgICAgICAgICBrZXkucGVtID0gYC0tLS0tQkVHSU4gUFJJVkFURSBLRVktLS0tLVxcbiR7a2V5LmRhdGEudG9TdHJpbmcoXCJiYXNlNjRcIil9XFxuLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLWA7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgIGtleToga2V5LnBlbSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgc2lnbmF0dXJlID0gY3J5cHRvX19kZWZhdWx0LnNpZ24obnVsbCwgQnVmZmVyLmZyb20oZGF0YSksIG9wdGlvbnMpO1xuICAgICAgICByZXR1cm4gY29yZS5CdWZmZXJTb3VyY2VDb252ZXJ0ZXIudG9BcnJheUJ1ZmZlcihzaWduYXR1cmUpO1xuICAgIH1cbiAgICBzdGF0aWMgYXN5bmMgdmVyaWZ5KGFsZ29yaXRobSwga2V5LCBzaWduYXR1cmUsIGRhdGEpIHtcbiAgICAgICAgaWYgKCFrZXkucGVtKSB7XG4gICAgICAgICAgICBrZXkucGVtID0gYC0tLS0tQkVHSU4gUFVCTElDIEtFWS0tLS0tXFxuJHtrZXkuZGF0YS50b1N0cmluZyhcImJhc2U2NFwiKX1cXG4tLS0tLUVORCBQVUJMSUMgS0VZLS0tLS1gO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICBrZXk6IGtleS5wZW0sXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IG9rID0gY3J5cHRvX19kZWZhdWx0LnZlcmlmeShudWxsLCBCdWZmZXIuZnJvbShkYXRhKSwgb3B0aW9ucywgQnVmZmVyLmZyb20oc2lnbmF0dXJlKSk7XG4gICAgICAgIHJldHVybiBvaztcbiAgICB9XG4gICAgc3RhdGljIGFzeW5jIGRlcml2ZUJpdHMoYWxnb3JpdGhtLCBiYXNlS2V5LCBsZW5ndGgpIHtcbiAgICAgICAgY29uc3QgcHVibGljS2V5ID0gY3J5cHRvX19kZWZhdWx0LmNyZWF0ZVB1YmxpY0tleSh7XG4gICAgICAgICAgICBrZXk6IGFsZ29yaXRobS5wdWJsaWMuZGF0YSxcbiAgICAgICAgICAgIGZvcm1hdDogXCJkZXJcIixcbiAgICAgICAgICAgIHR5cGU6IFwic3BraVwiLFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgcHJpdmF0ZUtleSA9IGNyeXB0b19fZGVmYXVsdC5jcmVhdGVQcml2YXRlS2V5KHtcbiAgICAgICAgICAgIGtleTogYmFzZUtleS5kYXRhLFxuICAgICAgICAgICAgZm9ybWF0OiBcImRlclwiLFxuICAgICAgICAgICAgdHlwZTogXCJwa2NzOFwiLFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgYml0cyA9IGNyeXB0b19fZGVmYXVsdC5kaWZmaWVIZWxsbWFuKHtcbiAgICAgICAgICAgIHB1YmxpY0tleSxcbiAgICAgICAgICAgIHByaXZhdGVLZXksXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoYml0cykuYnVmZmVyLnNsaWNlKDAsIGxlbmd0aCA+PiAzKTtcbiAgICB9XG4gICAgc3RhdGljIGFzeW5jIGV4cG9ydEtleShmb3JtYXQsIGtleSkge1xuICAgICAgICBzd2l0Y2ggKGZvcm1hdC50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgICAgICBjYXNlIFwiandrXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIEpzb25TZXJpYWxpemVyLnRvSlNPTihrZXkpO1xuICAgICAgICAgICAgY2FzZSBcInBrY3M4XCI6XG4gICAgICAgICAgICBjYXNlIFwic3BraVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShrZXkuZGF0YSkuYnVmZmVyO1xuICAgICAgICAgICAgY2FzZSBcInJhd1wiOiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcHVibGljS2V5SW5mbyA9IEFzblBhcnNlci5wYXJzZShrZXkuZGF0YSwgY29yZS5hc24xLlB1YmxpY0tleUluZm8pO1xuICAgICAgICAgICAgICAgIHJldHVybiBwdWJsaWNLZXlJbmZvLnB1YmxpY0tleTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IGNvcmUuT3BlcmF0aW9uRXJyb3IoXCJmb3JtYXQ6IE11c3QgYmUgJ2p3aycsICdyYXcnLCBwa2NzOCcgb3IgJ3Nwa2knXCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHN0YXRpYyBhc3luYyBpbXBvcnRLZXkoZm9ybWF0LCBrZXlEYXRhLCBhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgc3dpdGNoIChmb3JtYXQudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgY2FzZSBcImp3a1wiOiB7XG4gICAgICAgICAgICAgICAgY29uc3QgandrID0ga2V5RGF0YTtcbiAgICAgICAgICAgICAgICBpZiAoandrLmQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYXNuS2V5ID0gSnNvblBhcnNlci5mcm9tSlNPTihrZXlEYXRhLCB7IHRhcmdldFNjaGVtYTogY29yZS5hc24xLkN1cnZlUHJpdmF0ZUtleSB9KTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW1wb3J0UHJpdmF0ZUtleShhc25LZXksIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWp3ay54KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwia2V5RGF0YTogQ2Fubm90IGdldCByZXF1aXJlZCAneCcgZmlsZWRcIik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW1wb3J0UHVibGljS2V5KENvbnZlcnQuRnJvbUJhc2U2NFVybChqd2sueCksIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInJhd1wiOiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW1wb3J0UHVibGljS2V5KGtleURhdGEsIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwic3BraVwiOiB7XG4gICAgICAgICAgICAgICAgY29uc3Qga2V5SW5mbyA9IEFzblBhcnNlci5wYXJzZShuZXcgVWludDhBcnJheShrZXlEYXRhKSwgY29yZS5hc24xLlB1YmxpY0tleUluZm8pO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmltcG9ydFB1YmxpY0tleShrZXlJbmZvLnB1YmxpY0tleSwgYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJwa2NzOFwiOiB7XG4gICAgICAgICAgICAgICAgY29uc3Qga2V5SW5mbyA9IEFzblBhcnNlci5wYXJzZShuZXcgVWludDhBcnJheShrZXlEYXRhKSwgY29yZS5hc24xLlByaXZhdGVLZXlJbmZvKTtcbiAgICAgICAgICAgICAgICBjb25zdCBhc25LZXkgPSBBc25QYXJzZXIucGFyc2Uoa2V5SW5mby5wcml2YXRlS2V5LCBjb3JlLmFzbjEuQ3VydmVQcml2YXRlS2V5KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5pbXBvcnRQcml2YXRlS2V5KGFzbktleSwgYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IGNvcmUuT3BlcmF0aW9uRXJyb3IoXCJmb3JtYXQ6IE11c3QgYmUgJ2p3aycsICdyYXcnLCAncGtjczgnIG9yICdzcGtpJ1wiKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzdGF0aWMgaW1wb3J0UHJpdmF0ZUtleShhc25LZXksIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCBrZXkgPSBuZXcgRWRQcml2YXRlS2V5KCk7XG4gICAgICAgIGtleS5mcm9tSlNPTih7XG4gICAgICAgICAgICBjcnY6IGFsZ29yaXRobS5uYW1lZEN1cnZlLFxuICAgICAgICAgICAgZDogQ29udmVydC5Ub0Jhc2U2NFVybChhc25LZXkuZCksXG4gICAgICAgIH0pO1xuICAgICAgICBrZXkuYWxnb3JpdGhtID0gT2JqZWN0LmFzc2lnbih7fSwgYWxnb3JpdGhtKTtcbiAgICAgICAga2V5LmV4dHJhY3RhYmxlID0gZXh0cmFjdGFibGU7XG4gICAgICAgIGtleS51c2FnZXMgPSBrZXlVc2FnZXM7XG4gICAgICAgIHJldHVybiBrZXk7XG4gICAgfVxuICAgIHN0YXRpYyBhc3luYyBpbXBvcnRQdWJsaWNLZXkoYXNuS2V5LCBhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgY29uc3Qga2V5ID0gbmV3IEVkUHVibGljS2V5KCk7XG4gICAgICAgIGtleS5mcm9tSlNPTih7XG4gICAgICAgICAgICBjcnY6IGFsZ29yaXRobS5uYW1lZEN1cnZlLFxuICAgICAgICAgICAgeDogQ29udmVydC5Ub0Jhc2U2NFVybChhc25LZXkpLFxuICAgICAgICB9KTtcbiAgICAgICAga2V5LmFsZ29yaXRobSA9IE9iamVjdC5hc3NpZ24oe30sIGFsZ29yaXRobSk7XG4gICAgICAgIGtleS5leHRyYWN0YWJsZSA9IGV4dHJhY3RhYmxlO1xuICAgICAgICBrZXkudXNhZ2VzID0ga2V5VXNhZ2VzO1xuICAgICAgICByZXR1cm4ga2V5O1xuICAgIH1cbn1cbkVkQ3J5cHRvLnB1YmxpY0tleVVzYWdlcyA9IFtcInZlcmlmeVwiXTtcbkVkQ3J5cHRvLnByaXZhdGVLZXlVc2FnZXMgPSBbXCJzaWduXCIsIFwiZGVyaXZlS2V5XCIsIFwiZGVyaXZlQml0c1wiXTtcblxuY2xhc3MgRWREc2FQcm92aWRlciBleHRlbmRzIGNvcmUuRWREc2FQcm92aWRlciB7XG4gICAgYXN5bmMgb25HZW5lcmF0ZUtleShhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgY29uc3Qga2V5cyA9IGF3YWl0IEVkQ3J5cHRvLmdlbmVyYXRlS2V5KHtcbiAgICAgICAgICAgIG5hbWU6IHRoaXMubmFtZSxcbiAgICAgICAgICAgIG5hbWVkQ3VydmU6IGFsZ29yaXRobS5uYW1lZEN1cnZlLnJlcGxhY2UoL15lZC9pLCBcIkVkXCIpLFxuICAgICAgICB9LCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHByaXZhdGVLZXk6IHNldENyeXB0b0tleShrZXlzLnByaXZhdGVLZXkpLFxuICAgICAgICAgICAgcHVibGljS2V5OiBzZXRDcnlwdG9LZXkoa2V5cy5wdWJsaWNLZXkpLFxuICAgICAgICB9O1xuICAgIH1cbiAgICBhc3luYyBvblNpZ24oYWxnb3JpdGhtLCBrZXksIGRhdGEpIHtcbiAgICAgICAgcmV0dXJuIEVkQ3J5cHRvLnNpZ24oYWxnb3JpdGhtLCBnZXRDcnlwdG9LZXkoa2V5KSwgbmV3IFVpbnQ4QXJyYXkoZGF0YSkpO1xuICAgIH1cbiAgICBhc3luYyBvblZlcmlmeShhbGdvcml0aG0sIGtleSwgc2lnbmF0dXJlLCBkYXRhKSB7XG4gICAgICAgIHJldHVybiBFZENyeXB0by52ZXJpZnkoYWxnb3JpdGhtLCBnZXRDcnlwdG9LZXkoa2V5KSwgbmV3IFVpbnQ4QXJyYXkoc2lnbmF0dXJlKSwgbmV3IFVpbnQ4QXJyYXkoZGF0YSkpO1xuICAgIH1cbiAgICBhc3luYyBvbkV4cG9ydEtleShmb3JtYXQsIGtleSkge1xuICAgICAgICByZXR1cm4gRWRDcnlwdG8uZXhwb3J0S2V5KGZvcm1hdCwgZ2V0Q3J5cHRvS2V5KGtleSkpO1xuICAgIH1cbiAgICBhc3luYyBvbkltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBjb25zdCBrZXkgPSBhd2FpdCBFZENyeXB0by5pbXBvcnRLZXkoZm9ybWF0LCBrZXlEYXRhLCB7IC4uLmFsZ29yaXRobSwgbmFtZTogdGhpcy5uYW1lIH0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpO1xuICAgICAgICByZXR1cm4gc2V0Q3J5cHRvS2V5KGtleSk7XG4gICAgfVxufVxuXG5jbGFzcyBFY2RoRXNQcm92aWRlciBleHRlbmRzIGNvcmUuRWNkaEVzUHJvdmlkZXIge1xuICAgIGFzeW5jIG9uR2VuZXJhdGVLZXkoYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKSB7XG4gICAgICAgIGNvbnN0IGtleXMgPSBhd2FpdCBFZENyeXB0by5nZW5lcmF0ZUtleSh7XG4gICAgICAgICAgICBuYW1lOiB0aGlzLm5hbWUsXG4gICAgICAgICAgICBuYW1lZEN1cnZlOiBhbGdvcml0aG0ubmFtZWRDdXJ2ZS50b1VwcGVyQ2FzZSgpLFxuICAgICAgICB9LCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHByaXZhdGVLZXk6IHNldENyeXB0b0tleShrZXlzLnByaXZhdGVLZXkpLFxuICAgICAgICAgICAgcHVibGljS2V5OiBzZXRDcnlwdG9LZXkoa2V5cy5wdWJsaWNLZXkpLFxuICAgICAgICB9O1xuICAgIH1cbiAgICBhc3luYyBvbkRlcml2ZUJpdHMoYWxnb3JpdGhtLCBiYXNlS2V5LCBsZW5ndGgpIHtcbiAgICAgICAgY29uc3QgYml0cyA9IGF3YWl0IEVkQ3J5cHRvLmRlcml2ZUJpdHMoeyAuLi5hbGdvcml0aG0sIHB1YmxpYzogZ2V0Q3J5cHRvS2V5KGFsZ29yaXRobS5wdWJsaWMpIH0sIGdldENyeXB0b0tleShiYXNlS2V5KSwgbGVuZ3RoKTtcbiAgICAgICAgcmV0dXJuIGJpdHM7XG4gICAgfVxuICAgIGFzeW5jIG9uRXhwb3J0S2V5KGZvcm1hdCwga2V5KSB7XG4gICAgICAgIHJldHVybiBFZENyeXB0by5leHBvcnRLZXkoZm9ybWF0LCBnZXRDcnlwdG9LZXkoa2V5KSk7XG4gICAgfVxuICAgIGFzeW5jIG9uSW1wb3J0S2V5KGZvcm1hdCwga2V5RGF0YSwgYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IGF3YWl0IEVkQ3J5cHRvLmltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIHsgLi4uYWxnb3JpdGhtLCBuYW1lOiB0aGlzLm5hbWUgfSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcyk7XG4gICAgICAgIHJldHVybiBzZXRDcnlwdG9LZXkoa2V5KTtcbiAgICB9XG59XG5cbmNsYXNzIFBia2RmQ3J5cHRvS2V5IGV4dGVuZHMgQ3J5cHRvS2V5IHtcbn1cblxuY2xhc3MgUGJrZGYyUHJvdmlkZXIgZXh0ZW5kcyBjb3JlLlBia2RmMlByb3ZpZGVyIHtcbiAgICBhc3luYyBvbkRlcml2ZUJpdHMoYWxnb3JpdGhtLCBiYXNlS2V5LCBsZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHNhbHQgPSBjb3JlLkJ1ZmZlclNvdXJjZUNvbnZlcnRlci50b0FycmF5QnVmZmVyKGFsZ29yaXRobS5zYWx0KTtcbiAgICAgICAgICAgIGNvbnN0IGhhc2ggPSBhbGdvcml0aG0uaGFzaC5uYW1lLnJlcGxhY2UoXCItXCIsIFwiXCIpO1xuICAgICAgICAgICAgY3J5cHRvX19kZWZhdWx0LnBia2RmMihnZXRDcnlwdG9LZXkoYmFzZUtleSkuZGF0YSwgQnVmZmVyLmZyb20oc2FsdCksIGFsZ29yaXRobS5pdGVyYXRpb25zLCBsZW5ndGggPj4gMywgaGFzaCwgKGVyciwgZGVyaXZlZEJpdHMpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShuZXcgVWludDhBcnJheShkZXJpdmVkQml0cykuYnVmZmVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGFzeW5jIG9uSW1wb3J0S2V5KGZvcm1hdCwga2V5RGF0YSwgYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKSB7XG4gICAgICAgIGlmIChmb3JtYXQgPT09IFwicmF3XCIpIHtcbiAgICAgICAgICAgIGNvbnN0IGtleSA9IG5ldyBQYmtkZkNyeXB0b0tleSgpO1xuICAgICAgICAgICAga2V5LmRhdGEgPSBCdWZmZXIuZnJvbShrZXlEYXRhKTtcbiAgICAgICAgICAgIGtleS5hbGdvcml0aG0gPSB7IG5hbWU6IHRoaXMubmFtZSB9O1xuICAgICAgICAgICAga2V5LmV4dHJhY3RhYmxlID0gZmFsc2U7XG4gICAgICAgICAgICBrZXkudXNhZ2VzID0ga2V5VXNhZ2VzO1xuICAgICAgICAgICAgcmV0dXJuIHNldENyeXB0b0tleShrZXkpO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IG5ldyBjb3JlLk9wZXJhdGlvbkVycm9yKFwiZm9ybWF0OiBNdXN0IGJlICdyYXcnXCIpO1xuICAgIH1cbiAgICBjaGVja0NyeXB0b0tleShrZXksIGtleVVzYWdlKSB7XG4gICAgICAgIHN1cGVyLmNoZWNrQ3J5cHRvS2V5KGtleSwga2V5VXNhZ2UpO1xuICAgICAgICBpZiAoIShnZXRDcnlwdG9LZXkoa2V5KSBpbnN0YW5jZW9mIFBia2RmQ3J5cHRvS2V5KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImtleTogSXMgbm90IFBCS0RGIENyeXB0b0tleVwiKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuY2xhc3MgSG1hY0NyeXB0b0tleSBleHRlbmRzIENyeXB0b0tleSB7XG4gICAgZ2V0IGFsZygpIHtcbiAgICAgICAgY29uc3QgaGFzaCA9IHRoaXMuYWxnb3JpdGhtLmhhc2gubmFtZS50b1VwcGVyQ2FzZSgpO1xuICAgICAgICByZXR1cm4gYEhTJHtoYXNoLnJlcGxhY2UoXCJTSEEtXCIsIFwiXCIpfWA7XG4gICAgfVxuICAgIHNldCBhbGcodmFsdWUpIHtcbiAgICB9XG59XG5fX2RlY29yYXRlKFtcbiAgICBKc29uUHJvcCh7IG5hbWU6IFwia1wiLCBjb252ZXJ0ZXI6IEpzb25CYXNlNjRVcmxDb252ZXJ0ZXIgfSlcbl0sIEhtYWNDcnlwdG9LZXkucHJvdG90eXBlLCBcImRhdGFcIiwgdm9pZCAwKTtcblxuY2xhc3MgSG1hY1Byb3ZpZGVyIGV4dGVuZHMgY29yZS5IbWFjUHJvdmlkZXIge1xuICAgIGFzeW5jIG9uR2VuZXJhdGVLZXkoYWxnb3JpdGhtLCBleHRyYWN0YWJsZSwga2V5VXNhZ2VzKSB7XG4gICAgICAgIGNvbnN0IGxlbmd0aCA9IChhbGdvcml0aG0ubGVuZ3RoIHx8IHRoaXMuZ2V0RGVmYXVsdExlbmd0aChhbGdvcml0aG0uaGFzaC5uYW1lKSkgPj4gMyA8PCAzO1xuICAgICAgICBjb25zdCBrZXkgPSBuZXcgSG1hY0NyeXB0b0tleSgpO1xuICAgICAgICBrZXkuYWxnb3JpdGhtID0ge1xuICAgICAgICAgICAgLi4uYWxnb3JpdGhtLFxuICAgICAgICAgICAgbGVuZ3RoLFxuICAgICAgICAgICAgbmFtZTogdGhpcy5uYW1lLFxuICAgICAgICB9O1xuICAgICAgICBrZXkuZXh0cmFjdGFibGUgPSBleHRyYWN0YWJsZTtcbiAgICAgICAga2V5LnVzYWdlcyA9IGtleVVzYWdlcztcbiAgICAgICAga2V5LmRhdGEgPSBjcnlwdG9fX2RlZmF1bHQucmFuZG9tQnl0ZXMobGVuZ3RoID4+IDMpO1xuICAgICAgICByZXR1cm4gc2V0Q3J5cHRvS2V5KGtleSk7XG4gICAgfVxuICAgIGFzeW5jIG9uU2lnbihhbGdvcml0aG0sIGtleSwgZGF0YSkge1xuICAgICAgICBjb25zdCBjcnlwdG9BbGcgPSBTaGFDcnlwdG8uZ2V0QWxnb3JpdGhtTmFtZShrZXkuYWxnb3JpdGhtLmhhc2gpO1xuICAgICAgICBjb25zdCBobWFjID0gY3J5cHRvX19kZWZhdWx0LmNyZWF0ZUhtYWMoY3J5cHRvQWxnLCBnZXRDcnlwdG9LZXkoa2V5KS5kYXRhKVxuICAgICAgICAgICAgLnVwZGF0ZShCdWZmZXIuZnJvbShkYXRhKSkuZGlnZXN0KCk7XG4gICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShobWFjKS5idWZmZXI7XG4gICAgfVxuICAgIGFzeW5jIG9uVmVyaWZ5KGFsZ29yaXRobSwga2V5LCBzaWduYXR1cmUsIGRhdGEpIHtcbiAgICAgICAgY29uc3QgY3J5cHRvQWxnID0gU2hhQ3J5cHRvLmdldEFsZ29yaXRobU5hbWUoa2V5LmFsZ29yaXRobS5oYXNoKTtcbiAgICAgICAgY29uc3QgaG1hYyA9IGNyeXB0b19fZGVmYXVsdC5jcmVhdGVIbWFjKGNyeXB0b0FsZywgZ2V0Q3J5cHRvS2V5KGtleSkuZGF0YSlcbiAgICAgICAgICAgIC51cGRhdGUoQnVmZmVyLmZyb20oZGF0YSkpLmRpZ2VzdCgpO1xuICAgICAgICByZXR1cm4gaG1hYy5jb21wYXJlKEJ1ZmZlci5mcm9tKHNpZ25hdHVyZSkpID09PSAwO1xuICAgIH1cbiAgICBhc3luYyBvbkltcG9ydEtleShmb3JtYXQsIGtleURhdGEsIGFsZ29yaXRobSwgZXh0cmFjdGFibGUsIGtleVVzYWdlcykge1xuICAgICAgICBsZXQga2V5O1xuICAgICAgICBzd2l0Y2ggKGZvcm1hdC50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgICAgICBjYXNlIFwiandrXCI6XG4gICAgICAgICAgICAgICAga2V5ID0gSnNvblBhcnNlci5mcm9tSlNPTihrZXlEYXRhLCB7IHRhcmdldFNjaGVtYTogSG1hY0NyeXB0b0tleSB9KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJyYXdcIjpcbiAgICAgICAgICAgICAgICBrZXkgPSBuZXcgSG1hY0NyeXB0b0tleSgpO1xuICAgICAgICAgICAgICAgIGtleS5kYXRhID0gQnVmZmVyLmZyb20oa2V5RGF0YSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBjb3JlLk9wZXJhdGlvbkVycm9yKFwiZm9ybWF0OiBNdXN0IGJlICdqd2snIG9yICdyYXcnXCIpO1xuICAgICAgICB9XG4gICAgICAgIGtleS5hbGdvcml0aG0gPSB7XG4gICAgICAgICAgICBoYXNoOiB7IG5hbWU6IGFsZ29yaXRobS5oYXNoLm5hbWUgfSxcbiAgICAgICAgICAgIG5hbWU6IHRoaXMubmFtZSxcbiAgICAgICAgICAgIGxlbmd0aDoga2V5LmRhdGEubGVuZ3RoIDw8IDMsXG4gICAgICAgIH07XG4gICAgICAgIGtleS5leHRyYWN0YWJsZSA9IGV4dHJhY3RhYmxlO1xuICAgICAgICBrZXkudXNhZ2VzID0ga2V5VXNhZ2VzO1xuICAgICAgICByZXR1cm4gc2V0Q3J5cHRvS2V5KGtleSk7XG4gICAgfVxuICAgIGFzeW5jIG9uRXhwb3J0S2V5KGZvcm1hdCwga2V5KSB7XG4gICAgICAgIHN3aXRjaCAoZm9ybWF0LnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICAgIGNhc2UgXCJqd2tcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gSnNvblNlcmlhbGl6ZXIudG9KU09OKGdldENyeXB0b0tleShrZXkpKTtcbiAgICAgICAgICAgIGNhc2UgXCJyYXdcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoZ2V0Q3J5cHRvS2V5KGtleSkuZGF0YSkuYnVmZmVyO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgY29yZS5PcGVyYXRpb25FcnJvcihcImZvcm1hdDogTXVzdCBiZSAnandrJyBvciAncmF3J1wiKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjaGVja0NyeXB0b0tleShrZXksIGtleVVzYWdlKSB7XG4gICAgICAgIHN1cGVyLmNoZWNrQ3J5cHRvS2V5KGtleSwga2V5VXNhZ2UpO1xuICAgICAgICBpZiAoIShnZXRDcnlwdG9LZXkoa2V5KSBpbnN0YW5jZW9mIEhtYWNDcnlwdG9LZXkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwia2V5OiBJcyBub3QgSE1BQyBDcnlwdG9LZXlcIik7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmNsYXNzIEhrZGZDcnlwdG9LZXkgZXh0ZW5kcyBDcnlwdG9LZXkge1xufVxuXG5jbGFzcyBIa2RmUHJvdmlkZXIgZXh0ZW5kcyBjb3JlLkhrZGZQcm92aWRlciB7XG4gICAgYXN5bmMgb25JbXBvcnRLZXkoZm9ybWF0LCBrZXlEYXRhLCBhbGdvcml0aG0sIGV4dHJhY3RhYmxlLCBrZXlVc2FnZXMpIHtcbiAgICAgICAgaWYgKGZvcm1hdC50b0xvd2VyQ2FzZSgpICE9PSBcInJhd1wiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgY29yZS5PcGVyYXRpb25FcnJvcihcIk9wZXJhdGlvbiBub3Qgc3VwcG9ydGVkXCIpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGtleSA9IG5ldyBIa2RmQ3J5cHRvS2V5KCk7XG4gICAgICAgIGtleS5kYXRhID0gQnVmZmVyLmZyb20oa2V5RGF0YSk7XG4gICAgICAgIGtleS5hbGdvcml0aG0gPSB7IG5hbWU6IHRoaXMubmFtZSB9O1xuICAgICAgICBrZXkuZXh0cmFjdGFibGUgPSBleHRyYWN0YWJsZTtcbiAgICAgICAga2V5LnVzYWdlcyA9IGtleVVzYWdlcztcbiAgICAgICAgcmV0dXJuIHNldENyeXB0b0tleShrZXkpO1xuICAgIH1cbiAgICBhc3luYyBvbkRlcml2ZUJpdHMocGFyYW1zLCBiYXNlS2V5LCBsZW5ndGgpIHtcbiAgICAgICAgY29uc3QgaGFzaCA9IHBhcmFtcy5oYXNoLm5hbWUucmVwbGFjZShcIi1cIiwgXCJcIik7XG4gICAgICAgIGNvbnN0IGhhc2hMZW5ndGggPSBjcnlwdG9fX2RlZmF1bHQuY3JlYXRlSGFzaChoYXNoKS5kaWdlc3QoKS5sZW5ndGg7XG4gICAgICAgIGNvbnN0IGJ5dGVMZW5ndGggPSBsZW5ndGggLyA4O1xuICAgICAgICBjb25zdCBpbmZvID0gQnVmZmVyU291cmNlQ29udmVydGVyJDEudG9VaW50OEFycmF5KHBhcmFtcy5pbmZvKTtcbiAgICAgICAgY29uc3QgUFJLID0gY3J5cHRvX19kZWZhdWx0LmNyZWF0ZUhtYWMoaGFzaCwgQnVmZmVyU291cmNlQ29udmVydGVyJDEudG9VaW50OEFycmF5KHBhcmFtcy5zYWx0KSlcbiAgICAgICAgICAgIC51cGRhdGUoQnVmZmVyU291cmNlQ29udmVydGVyJDEudG9VaW50OEFycmF5KGdldENyeXB0b0tleShiYXNlS2V5KS5kYXRhKSlcbiAgICAgICAgICAgIC5kaWdlc3QoKTtcbiAgICAgICAgY29uc3QgYmxvY2tzID0gW0J1ZmZlci5hbGxvYygwKV07XG4gICAgICAgIGNvbnN0IGJsb2NrQ291bnQgPSBNYXRoLmNlaWwoYnl0ZUxlbmd0aCAvIGhhc2hMZW5ndGgpICsgMTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCBibG9ja0NvdW50OyArK2kpIHtcbiAgICAgICAgICAgIGJsb2Nrcy5wdXNoKGNyeXB0b19fZGVmYXVsdC5jcmVhdGVIbWFjKGhhc2gsIFBSSylcbiAgICAgICAgICAgICAgICAudXBkYXRlKEJ1ZmZlci5jb25jYXQoW2Jsb2Nrc1tpIC0gMV0sIGluZm8sIEJ1ZmZlci5mcm9tKFtpXSldKSlcbiAgICAgICAgICAgICAgICAuZGlnZXN0KCkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBCdWZmZXIuY29uY2F0KGJsb2Nrcykuc2xpY2UoMCwgYnl0ZUxlbmd0aCk7XG4gICAgfVxuICAgIGNoZWNrQ3J5cHRvS2V5KGtleSwga2V5VXNhZ2UpIHtcbiAgICAgICAgc3VwZXIuY2hlY2tDcnlwdG9LZXkoa2V5LCBrZXlVc2FnZSk7XG4gICAgICAgIGlmICghKGdldENyeXB0b0tleShrZXkpIGluc3RhbmNlb2YgSGtkZkNyeXB0b0tleSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJrZXk6IElzIG5vdCBIS0RGIENyeXB0b0tleVwiKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuY2xhc3MgU2hha2VDcnlwdG8ge1xuICAgIHN0YXRpYyBkaWdlc3QoYWxnb3JpdGhtLCBkYXRhKSB7XG4gICAgICAgIGNvbnN0IGhhc2ggPSBjcnlwdG9fX2RlZmF1bHQuY3JlYXRlSGFzaChhbGdvcml0aG0ubmFtZS50b0xvd2VyQ2FzZSgpLCB7IG91dHB1dExlbmd0aDogYWxnb3JpdGhtLmxlbmd0aCB9KVxuICAgICAgICAgICAgLnVwZGF0ZShCdWZmZXIuZnJvbShkYXRhKSkuZGlnZXN0KCk7XG4gICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShoYXNoKS5idWZmZXI7XG4gICAgfVxufVxuXG5jbGFzcyBTaGFrZTEyOFByb3ZpZGVyIGV4dGVuZHMgY29yZS5TaGFrZTEyOFByb3ZpZGVyIHtcbiAgICBhc3luYyBvbkRpZ2VzdChhbGdvcml0aG0sIGRhdGEpIHtcbiAgICAgICAgcmV0dXJuIFNoYWtlQ3J5cHRvLmRpZ2VzdChhbGdvcml0aG0sIGRhdGEpO1xuICAgIH1cbn1cblxuY2xhc3MgU2hha2UyNTZQcm92aWRlciBleHRlbmRzIGNvcmUuU2hha2UyNTZQcm92aWRlciB7XG4gICAgYXN5bmMgb25EaWdlc3QoYWxnb3JpdGhtLCBkYXRhKSB7XG4gICAgICAgIHJldHVybiBTaGFrZUNyeXB0by5kaWdlc3QoYWxnb3JpdGhtLCBkYXRhKTtcbiAgICB9XG59XG5cbmNsYXNzIFN1YnRsZUNyeXB0byBleHRlbmRzIGNvcmUuU3VidGxlQ3J5cHRvIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdmFyIF9hO1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLnByb3ZpZGVycy5zZXQobmV3IEFlc0NiY1Byb3ZpZGVyKCkpO1xuICAgICAgICB0aGlzLnByb3ZpZGVycy5zZXQobmV3IEFlc0N0clByb3ZpZGVyKCkpO1xuICAgICAgICB0aGlzLnByb3ZpZGVycy5zZXQobmV3IEFlc0djbVByb3ZpZGVyKCkpO1xuICAgICAgICB0aGlzLnByb3ZpZGVycy5zZXQobmV3IEFlc0NtYWNQcm92aWRlcigpKTtcbiAgICAgICAgdGhpcy5wcm92aWRlcnMuc2V0KG5ldyBBZXNLd1Byb3ZpZGVyKCkpO1xuICAgICAgICB0aGlzLnByb3ZpZGVycy5zZXQobmV3IEFlc0VjYlByb3ZpZGVyKCkpO1xuICAgICAgICBjb25zdCBjaXBoZXJzID0gY3J5cHRvLmdldENpcGhlcnMoKTtcbiAgICAgICAgaWYgKGNpcGhlcnMuaW5jbHVkZXMoXCJkZXMtY2JjXCIpKSB7XG4gICAgICAgICAgICB0aGlzLnByb3ZpZGVycy5zZXQobmV3IERlc0NiY1Byb3ZpZGVyKCkpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucHJvdmlkZXJzLnNldChuZXcgRGVzRWRlM0NiY1Byb3ZpZGVyKCkpO1xuICAgICAgICB0aGlzLnByb3ZpZGVycy5zZXQobmV3IFJzYVNzYVByb3ZpZGVyKCkpO1xuICAgICAgICB0aGlzLnByb3ZpZGVycy5zZXQobmV3IFJzYVBzc1Byb3ZpZGVyKCkpO1xuICAgICAgICB0aGlzLnByb3ZpZGVycy5zZXQobmV3IFJzYU9hZXBQcm92aWRlcigpKTtcbiAgICAgICAgdGhpcy5wcm92aWRlcnMuc2V0KG5ldyBSc2FFc1Byb3ZpZGVyKCkpO1xuICAgICAgICB0aGlzLnByb3ZpZGVycy5zZXQobmV3IEVjZHNhUHJvdmlkZXIoKSk7XG4gICAgICAgIHRoaXMucHJvdmlkZXJzLnNldChuZXcgRWNkaFByb3ZpZGVyKCkpO1xuICAgICAgICB0aGlzLnByb3ZpZGVycy5zZXQobmV3IFNoYTFQcm92aWRlcigpKTtcbiAgICAgICAgdGhpcy5wcm92aWRlcnMuc2V0KG5ldyBTaGEyNTZQcm92aWRlcigpKTtcbiAgICAgICAgdGhpcy5wcm92aWRlcnMuc2V0KG5ldyBTaGEzODRQcm92aWRlcigpKTtcbiAgICAgICAgdGhpcy5wcm92aWRlcnMuc2V0KG5ldyBTaGE1MTJQcm92aWRlcigpKTtcbiAgICAgICAgdGhpcy5wcm92aWRlcnMuc2V0KG5ldyBQYmtkZjJQcm92aWRlcigpKTtcbiAgICAgICAgdGhpcy5wcm92aWRlcnMuc2V0KG5ldyBIbWFjUHJvdmlkZXIoKSk7XG4gICAgICAgIHRoaXMucHJvdmlkZXJzLnNldChuZXcgSGtkZlByb3ZpZGVyKCkpO1xuICAgICAgICBjb25zdCBub2RlTWFqb3JWZXJzaW9uID0gKF9hID0gL152KFxcZCspLy5leGVjKHByb2Nlc3MudmVyc2lvbikpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYVsxXTtcbiAgICAgICAgaWYgKG5vZGVNYWpvclZlcnNpb24gJiYgcGFyc2VJbnQobm9kZU1ham9yVmVyc2lvbiwgMTApID49IDEyKSB7XG4gICAgICAgICAgICB0aGlzLnByb3ZpZGVycy5zZXQobmV3IFNoYWtlMTI4UHJvdmlkZXIoKSk7XG4gICAgICAgICAgICB0aGlzLnByb3ZpZGVycy5zZXQobmV3IFNoYWtlMjU2UHJvdmlkZXIoKSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaGFzaGVzID0gY3J5cHRvLmdldEhhc2hlcygpO1xuICAgICAgICBpZiAoaGFzaGVzLmluY2x1ZGVzKFwic2hhMy0yNTZcIikpIHtcbiAgICAgICAgICAgIHRoaXMucHJvdmlkZXJzLnNldChuZXcgU2hhMzI1NlByb3ZpZGVyKCkpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoYXNoZXMuaW5jbHVkZXMoXCJzaGEzLTM4NFwiKSkge1xuICAgICAgICAgICAgdGhpcy5wcm92aWRlcnMuc2V0KG5ldyBTaGEzMzg0UHJvdmlkZXIoKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGhhc2hlcy5pbmNsdWRlcyhcInNoYTMtNTEyXCIpKSB7XG4gICAgICAgICAgICB0aGlzLnByb3ZpZGVycy5zZXQobmV3IFNoYTM1MTJQcm92aWRlcigpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobm9kZU1ham9yVmVyc2lvbiAmJiBwYXJzZUludChub2RlTWFqb3JWZXJzaW9uLCAxMCkgPj0gMTQpIHtcbiAgICAgICAgICAgIHRoaXMucHJvdmlkZXJzLnNldChuZXcgRWREc2FQcm92aWRlcigpKTtcbiAgICAgICAgICAgIHRoaXMucHJvdmlkZXJzLnNldChuZXcgRWNkaEVzUHJvdmlkZXIoKSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmNsYXNzIENyeXB0byBleHRlbmRzIGNvcmUuQ3J5cHRvIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5zdWJ0bGUgPSBuZXcgU3VidGxlQ3J5cHRvKCk7XG4gICAgfVxuICAgIGdldFJhbmRvbVZhbHVlcyhhcnJheSkge1xuICAgICAgICBpZiAoIUFycmF5QnVmZmVyLmlzVmlldyhhcnJheSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJGYWlsZWQgdG8gZXhlY3V0ZSAnZ2V0UmFuZG9tVmFsdWVzJyBvbiAnQ3J5cHRvJzogcGFyYW1ldGVyIDEgaXMgbm90IG9mIHR5cGUgJ0FycmF5QnVmZmVyVmlldydcIik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYnVmZmVyID0gQnVmZmVyLmZyb20oYXJyYXkuYnVmZmVyLCBhcnJheS5ieXRlT2Zmc2V0LCBhcnJheS5ieXRlTGVuZ3RoKTtcbiAgICAgICAgY3J5cHRvX19kZWZhdWx0LnJhbmRvbUZpbGxTeW5jKGJ1ZmZlcik7XG4gICAgICAgIHJldHVybiBhcnJheTtcbiAgICB9XG59XG5cbmV4cG9ydCB7IENyeXB0byB9O1xuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgZ2V0R2xvYmFsIH0gZnJvbSBcIi4uL3R5cGVzL2dsb2JhbC5tanNcIjtcblxuZXhwb3J0IHsgcmFuZG9tIH07XG5cbi8qKlxuICogdGhpcyBmdW5jdGlvbiB1c2VzIGNyeXB0IGFuZCByZXR1cm5zIGEgcmFuZG9tIG51bWJlci5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gbWluIHN0YXJ0aW5nIHZhbHVlIG9mIHRoZSBkZWZpbml0aW9uIHNldCAoZGVmYXVsdCBpcyAwKVxuICogQHBhcmFtIHtudW1iZXJ9IG1heCBlbmQgdmFsdWUgb2YgdGhlIGRlZmluaXRpb24gc2V0IChkZWZhdWx0IGlzIDEwMDAwMDAwMDApXG4gKiBAcmV0dXJucyB7bnVtYmVyfVxuICogQG1lbWJlck9mIE1vbnN0ZXIuTWF0aFxuICogQHRocm93cyB7RXJyb3J9IG1pc3NpbmcgY3J5cHRcbiAqIEB0aHJvd3Mge0Vycm9yfSB3ZSBjYW5ub3QgZ2VuZXJhdGUgbnVtYmVycyBsYXJnZXIgdGhhbiA1MyBiaXRzLlxuICogQHRocm93cyB7RXJyb3J9IHRoZSBkaXN0YW5jZSBpcyB0b28gc21hbGwgdG8gY3JlYXRlIGEgcmFuZG9tIG51bWJlci5cblxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4wLjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKi9cbmZ1bmN0aW9uIHJhbmRvbShtaW4sIG1heCkge1xuICAgIGlmIChtaW4gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBtaW4gPSAwO1xuICAgIH1cbiAgICBpZiAobWF4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgbWF4ID0gTUFYO1xuICAgIH1cblxuICAgIGlmIChtYXggPCBtaW4pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwibWF4IG11c3QgYmUgZ3JlYXRlciB0aGFuIG1pblwiKTtcbiAgICB9XG5cbiAgICByZXR1cm4gTWF0aC5yb3VuZChjcmVhdGUobWluLCBtYXgpKTtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHR5cGUge251bWJlcn1cbiAqL1xudmFyIE1BWCA9IDEwMDAwMDAwMDA7XG5cbk1hdGgubG9nMiA9XG4gICAgTWF0aC5sb2cyIHx8XG4gICAgZnVuY3Rpb24gKG4pIHtcbiAgICAgICAgcmV0dXJuIE1hdGgubG9nKG4pIC8gTWF0aC5sb2coMik7XG4gICAgfTtcblxuLyoqXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IG1pblxuICogQHBhcmFtIHtudW1iZXJ9IG1heFxuICogQHJldHVybnMge251bWJlcn1cbiAqIEBwcml2YXRlXG4gKiBAdGhyb3dzIHtFcnJvcn0gbWlzc2luZyBjcnlwdFxuICogQHRocm93cyB7RXJyb3J9IHdlIGNhbm5vdCBnZW5lcmF0ZSBudW1iZXJzIGxhcmdlciB0aGFuIDUzIGJpdHMuXG4gKiBAdGhyb3dzIHtFcnJvcn0gdGhlIGRpc3RhbmNlIGlzIHRvbyBzbWFsbCB0byBjcmVhdGUgYSByYW5kb20gbnVtYmVyLlxuICovXG5mdW5jdGlvbiBjcmVhdGUobWluLCBtYXgpIHtcbiAgICBsZXQgY3J5cHQ7XG4gICAgbGV0IGdsb2JhbFJlZmVyZW5jZSA9IGdldEdsb2JhbCgpO1xuXG4gICAgY3J5cHQgPSBnbG9iYWxSZWZlcmVuY2U/LltcImNyeXB0b1wiXSB8fCBnbG9iYWxSZWZlcmVuY2U/LltcIm1zQ3J5cHRvXCJdIHx8IGdsb2JhbFJlZmVyZW5jZT8uW1wiY3J5cHRvXCJdIHx8IHVuZGVmaW5lZDtcblxuICAgIGlmICh0eXBlb2YgY3J5cHQgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwibWlzc2luZyBjcnlwdFwiKTtcbiAgICB9XG5cbiAgICBsZXQgcnZhbCA9IDA7XG4gICAgY29uc3QgcmFuZ2UgPSBtYXggLSBtaW47XG4gICAgaWYgKHJhbmdlIDwgMikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0aGUgZGlzdGFuY2UgaXMgdG9vIHNtYWxsIHRvIGNyZWF0ZSBhIHJhbmRvbSBudW1iZXIuXCIpO1xuICAgIH1cblxuICAgIGNvbnN0IGJpdHNOZWVkZWQgPSBNYXRoLmNlaWwoTWF0aC5sb2cyKHJhbmdlKSk7XG4gICAgaWYgKGJpdHNOZWVkZWQgPiA1Mykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ3ZSBjYW5ub3QgZ2VuZXJhdGUgbnVtYmVycyBsYXJnZXIgdGhhbiA1MyBiaXRzLlwiKTtcbiAgICB9XG4gICAgY29uc3QgYnl0ZXNOZWVkZWQgPSBNYXRoLmNlaWwoYml0c05lZWRlZCAvIDgpO1xuICAgIGNvbnN0IG1hc2sgPSBNYXRoLnBvdygyLCBiaXRzTmVlZGVkKSAtIDE7XG5cbiAgICBjb25zdCBieXRlQXJyYXkgPSBuZXcgVWludDhBcnJheShieXRlc05lZWRlZCk7XG4gICAgY3J5cHQuZ2V0UmFuZG9tVmFsdWVzKGJ5dGVBcnJheSk7XG5cbiAgICBsZXQgcCA9IChieXRlc05lZWRlZCAtIDEpICogODtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJ5dGVzTmVlZGVkOyBpKyspIHtcbiAgICAgICAgcnZhbCArPSBieXRlQXJyYXlbaV0gKiBNYXRoLnBvdygyLCBwKTtcbiAgICAgICAgcCAtPSA4O1xuICAgIH1cblxuICAgIHJ2YWwgPSBydmFsICYgbWFzaztcblxuICAgIGlmIChydmFsID49IHJhbmdlKSB7XG4gICAgICAgIHJldHVybiBjcmVhdGUobWluLCBtYXgpO1xuICAgIH1cblxuICAgIGlmIChydmFsIDwgbWluKSB7XG4gICAgICAgIHJ2YWwgKz0gbWluO1xuICAgIH1cblxuICAgIHJldHVybiBydmFsO1xufVxuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgSUQgfSBmcm9tIFwiLi4vdHlwZXMvaWQubWpzXCI7XG5pbXBvcnQgeyBpc09iamVjdCB9IGZyb20gXCIuLi90eXBlcy9pcy5tanNcIjtcbmltcG9ydCB7IHZhbGlkYXRlU3RyaW5nIH0gZnJvbSBcIi4uL3R5cGVzL3ZhbGlkYXRlLm1qc1wiO1xuXG5leHBvcnQgeyB0cmltU3BhY2VzIH07XG5cbi8qKlxuICogVGhpcyBzcGVjaWFsIHRyaW0gZnVuY3Rpb24gYWxsb3dzIHRvIHRyaW0gc3BhY2VzIHRoYXQgaGF2ZSBiZWVuIHByb3RlY3RlZCBieSBhIHNwZWNpYWwgZXNjYXBlIGNoYXJhY3Rlci5cbiAqXG4gKiBgYGBcbiAqIDxzY3JpcHQgdHlwZT1cIm1vZHVsZVwiPlxuICogaW1wb3J0IHt0cmltU3BhY2VzfSBmcm9tICdAc2NodWthaS9tb25zdGVyL3NvdXJjZS91dGlsL3RyaW1zcGFjZXMubWpzJztcbiAqIHRyaW1TcGFjZXMoJyBoZWxsbyBcXFxcICcpXG4gKiA8L3NjcmlwdD5cbiAqIGBgYFxuICpcbiAqIEhpbnQ6IE9uZSBzdHJva2UgaXMgZXNjYXBlZCBieSB0aGUgamF2YXNjcmlwdCBpbnRlcnByZXRlciwgdGhlIHNlY29uZCBzdHJva2UgZXNjYXBlcyB0aGUgc3Ryb2tlLlxuICpcbiAqIGBgYHRleHRcbiAqIGFcXCBiICBcdTIxQTYgYSBiXG4gKiBhXFxcXCBiIFx1MjFBNiBhXFwgYlxuICogYGBgXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNC4wXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5VdGlsXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlXG4gKiBAcmV0dXJuIHtzdHJpbmd9XG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIHN0cmluZ1xuICovXG5mdW5jdGlvbiB0cmltU3BhY2VzKHZhbHVlKSB7XG4gICAgdmFsaWRhdGVTdHJpbmcodmFsdWUpO1xuXG4gICAgbGV0IHBsYWNlaG9sZGVyID0gbmV3IE1hcCgpO1xuICAgIGNvbnN0IHJlZ2V4ID0gLygoPzxwYXR0ZXJuPlxcXFwoPzxjaGFyPi4pKXsxfSkvZ2ltO1xuXG4gICAgLy8gVGhlIHNlcGFyYXRvciBmb3IgYXJncyBtdXN0IGJlIGVzY2FwZWRcbiAgICAvLyB1bmRlZmluZWQgc3RyaW5nIHdoaWNoIHNob3VsZCBub3Qgb2NjdXIgbm9ybWFsbHkgYW5kIGlzIGFsc28gbm90IGEgcmVnZXhcbiAgICBsZXQgcmVzdWx0ID0gdmFsdWUubWF0Y2hBbGwocmVnZXgpO1xuXG4gICAgZm9yIChsZXQgbSBvZiByZXN1bHQpIHtcbiAgICAgICAgbGV0IGcgPSBtPy5bXCJncm91cHNcIl07XG4gICAgICAgIGlmICghaXNPYmplY3QoZykpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHAgPSBnPy5bXCJwYXR0ZXJuXCJdO1xuICAgICAgICBsZXQgYyA9IGc/LltcImNoYXJcIl07XG5cbiAgICAgICAgaWYgKHAgJiYgYykge1xuICAgICAgICAgICAgbGV0IHIgPSBgX18ke25ldyBJRCgpLnRvU3RyaW5nKCl9X19gO1xuICAgICAgICAgICAgcGxhY2Vob2xkZXIuc2V0KHIsIGMpO1xuICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKHAsIHIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdmFsdWUgPSB2YWx1ZS50cmltKCk7XG4gICAgcGxhY2Vob2xkZXIuZm9yRWFjaCgodiwgaykgPT4ge1xuICAgICAgICB2YWx1ZSA9IHZhbHVlLnJlcGxhY2UoaywgYFxcXFwke3Z9YCk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gdmFsdWU7XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBCYXNlIH0gZnJvbSBcIi4vYmFzZS5tanNcIjtcbmltcG9ydCB7IGluc3RhbmNlU3ltYm9sIH0gZnJvbSBcIi4uL2NvbnN0YW50cy5tanNcIjtcblxuZXhwb3J0IHsgUXVldWUgfTtcblxuLyoqXG4gKiBBIHF1ZXVlIGlzIGEgbGlzdCBvZiBpdGVtcyB0aGF0IGFyZSBwcm9jZXNzZWQgb25lIGFmdGVyIGFub3RoZXIgKGZpcnN0IGluLCBmaXJzdCBvdXQpLlxuICpcbiAqIFdpdGggYSBxdWV1ZSB5b3UgY2FuIGFkZCBpdGVtcyB0byB0aGUgZW5kIG9mIHRoZSBsaXN0IGBRdWV1ZS5hZGQoKWAgYW5kIHJlbW92ZSBpdGVtcyBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGxpc3QgYFF1ZXVlLnBvcCgpYC5cbiAqXG4gKiBXaXRoIGBRdWV1ZS5wZWVrKClgIHlvdSBjYW4gZ2V0IHRoZSBmaXJzdCBpdGVtIHdpdGhvdXQgcmVtb3ZpbmcgaXQgZnJvbSB0aGUgbGlzdC5cbiAqXG4gKiBZb3UgY2FuIGNyZWF0ZSB0aGUgaW5zdGFuY2UgdmlhIGBuZXcgUXVldWUoKWAuXG4gKlxuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL3R5cGVzL3F1ZXVlLm1qc1xuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS40LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UeXBlc1xuICogQHN1bW1hcnkgQSBRdWV1ZSAoRmlmbylcbiAqL1xuY2xhc3MgUXVldWUgZXh0ZW5kcyBCYXNlIHtcbiAgICAvKipcbiAgICAgKlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLmRhdGEgPSBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGBpbnN0YW5jZW9mYCBvcGVyYXRvci5cbiAgICAgKiBAcmV0dXJucyB7c3ltYm9sfVxuICAgICAqIEBzaW5jZSAyLjEuMFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgW2luc3RhbmNlU3ltYm9sXSgpIHtcbiAgICAgICAgcmV0dXJuIFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL3R5cGVzL3F1ZXVlXCIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAgICovXG4gICAgaXNFbXB0eSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGF0YS5sZW5ndGggPT09IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVhZCB0aGUgZWxlbWVudCBhdCB0aGUgZnJvbnQgb2YgdGhlIHF1ZXVlIHdpdGhvdXQgcmVtb3ZpbmcgaXQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHsqfVxuICAgICAqL1xuICAgIHBlZWsoKSB7XG4gICAgICAgIGlmICh0aGlzLmlzRW1wdHkoKSkge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzLmRhdGFbMF07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkIGEgbmV3IGVsZW1lbnQgdG8gdGhlIGVuZCBvZiB0aGUgcXVldWUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlXG4gICAgICogQHJldHVybnMge1F1ZXVlfVxuICAgICAqL1xuICAgIGFkZCh2YWx1ZSkge1xuICAgICAgICB0aGlzLmRhdGEucHVzaCh2YWx1ZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHJlbW92ZSBhbGwgZW50cmllc1xuICAgICAqXG4gICAgICogQHJldHVybnMge1F1ZXVlfVxuICAgICAqL1xuICAgIGNsZWFyKCkge1xuICAgICAgICB0aGlzLmRhdGEgPSBbXTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlIHRoZSBlbGVtZW50IGF0IHRoZSBmcm9udCBvZiB0aGUgcXVldWVcbiAgICAgKiBJZiB0aGUgcXVldWUgaXMgZW1wdHksIHJldHVybiB1bmRlZmluZWQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHsqfVxuICAgICAqL1xuICAgIHBvbGwoKSB7XG4gICAgICAgIGlmICh0aGlzLmlzRW1wdHkoKSkge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5kYXRhLnNoaWZ0KCk7XG4gICAgfVxufVxuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgUXVldWUgfSBmcm9tIFwiLi9xdWV1ZS5tanNcIjtcbmltcG9ydCB7IGludGVybmFsU3ltYm9sIH0gZnJvbSBcIi4uL2NvbnN0YW50cy5tanNcIjtcbmltcG9ydCB7IHZhbGlkYXRlT2JqZWN0IH0gZnJvbSBcIi4vdmFsaWRhdGUubWpzXCI7XG5cbmV4cG9ydCB7IFVuaXF1ZVF1ZXVlIH07XG5cbi8qKlxuICogQW4gVW5pcXVlUXVldWUgaXMgYSBxdWV1ZSB0aGF0IGNvbnRhaW5zIGl0ZW1zIG9ubHkgb25jZS5cbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjQuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKiBAc3VtbWFyeSBBIHF1ZXVlIGZvciB1bmlxdWUgdmFsdWVzXG4gKi9cbmNsYXNzIFVuaXF1ZVF1ZXVlIGV4dGVuZHMgUXVldWUge1xuICAgIC8qKlxuICAgICAqXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXNbaW50ZXJuYWxTeW1ib2xdID0ge1xuICAgICAgICAgICAgdW5pcXVlOiBuZXcgV2Vha1NldCgpLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZCBhIG5ldyBlbGVtZW50IHRvIHRoZSBlbmQgb2YgdGhlIHF1ZXVlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtvYmplY3R9IHZhbHVlXG4gICAgICogQHJldHVybnMge1F1ZXVlfVxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgb2JqZWN0XG4gICAgICovXG4gICAgYWRkKHZhbHVlKSB7XG4gICAgICAgIHZhbGlkYXRlT2JqZWN0KHZhbHVlKTtcblxuICAgICAgICBpZiAoIXRoaXNbaW50ZXJuYWxTeW1ib2xdLnVuaXF1ZS5oYXModmFsdWUpKSB7XG4gICAgICAgICAgICB0aGlzW2ludGVybmFsU3ltYm9sXS51bmlxdWUuYWRkKHZhbHVlKTtcbiAgICAgICAgICAgIHN1cGVyLmFkZCh2YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiByZW1vdmUgYWxsIGVudHJpZXNcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtRdWV1ZX1cbiAgICAgKi9cbiAgICBjbGVhcigpIHtcbiAgICAgICAgc3VwZXIuY2xlYXIoKTtcbiAgICAgICAgdGhpc1tpbnRlcm5hbFN5bWJvbF0udW5pcXVlID0gbmV3IFdlYWtTZXQoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlIHRoZSBlbGVtZW50IGF0IHRoZSBmcm9udCBvZiB0aGUgcXVldWVcbiAgICAgKiBJZiB0aGUgcXVldWUgaXMgZW1wdHksIHJldHVybiB1bmRlZmluZWQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtvYmplY3R9XG4gICAgICovXG4gICAgcG9sbCgpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNFbXB0eSgpKSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIGxldCB2YWx1ZSA9IHRoaXMuZGF0YS5zaGlmdCgpO1xuICAgICAgICB0aGlzW2ludGVybmFsU3ltYm9sXS51bmlxdWUuZGVsZXRlKHZhbHVlKTtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IEJhc2UgfSBmcm9tIFwiLi9iYXNlLm1qc1wiO1xuaW1wb3J0IHsgaXNPYmplY3QgfSBmcm9tIFwiLi9pcy5tanNcIjtcbmltcG9ydCB7IFRva2VuTGlzdCB9IGZyb20gXCIuL3Rva2VubGlzdC5tanNcIjtcbmltcG9ydCB7IFVuaXF1ZVF1ZXVlIH0gZnJvbSBcIi4vdW5pcXVlcXVldWUubWpzXCI7XG5pbXBvcnQgeyBpbnN0YW5jZVN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5leHBvcnQgeyBPYnNlcnZlciB9O1xuXG4vKipcbiAqIEFuIG9ic2VydmVyIG1hbmFnZXMgYSBjYWxsYmFjayBmdW5jdGlvblxuICpcbiAqIFRoZSB1cGRhdGUgbWV0aG9kIGlzIGNhbGxlZCB3aXRoIHRoZSBzdWJqZWN0IG9iamVjdCBhcyB0aGlzIHBvaW50ZXIuIEZvciB0aGlzIHJlYXNvbiB0aGUgY2FsbGJhY2sgc2hvdWxkIG5vdFxuICogYmUgYW4gYXJyb3cgZnVuY3Rpb24sIGJlY2F1c2UgaXQgZ2V0cyB0aGlzIHBvaW50ZXIgb2YgaXRzIG93biBjb250ZXh0LlxuICpcbiAqIGBgYGpzXG4gKiBuZXcgT2JzZXJ2ZXIoKCk9PntcbiAqICAgICAvLyB0aGlzIGlzIG5vdCBzdWJqZWN0XG4gKiB9KVxuICpcbiAqIG5ldyBPYnNlcnZlcihmdW5jdGlvbigpIHtcbiAqICAgICAvLyB0aGlzIGlzIHN1YmplY3RcbiAqIH0pXG4gKiBgYGBcbiAqXG4gKiBBZGRpdGlvbmFsIGFyZ3VtZW50cyBjYW4gYmUgcGFzc2VkIHRvIHRoZSBjYWxsYmFjay4gVG8gZG8gdGhpcywgc2ltcGx5IHNwZWNpZnkgdGhlbS5cbiAqXG4gKiBgYGBqc1xuICogT2JzZXJ2ZXIoZnVuY3Rpb24oYSwgYiwgYykge1xuICogICAgIGNvbnNvbGUubG9nKGEsIGIsIGMpOyAvLyBcdTIxQTYgXCJhXCIsIDIsIHRydWVcbiAqIH0sIFwiYVwiLCAyLCB0cnVlKVxuICogYGBgXG4gKlxuICogVGhlIGNhbGxiYWNrIGZ1bmN0aW9uIG11c3QgaGF2ZSBhcyBtYW55IHBhcmFtZXRlcnMgYXMgYXJndW1lbnRzIGFyZSBnaXZlbi5cbiAqXG4gKiBAZXh0ZXJuYWxFeGFtcGxlIC4uLy4uL2V4YW1wbGUvdHlwZXMvb2JzZXJ2ZXIubWpzXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjAuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKi9cbmNsYXNzIE9ic2VydmVyIGV4dGVuZHMgQmFzZSB7XG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBjYWxsYmFja1xuICAgICAqIEBwYXJhbSB7Kn0gYXJnc1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGNhbGxiYWNrLCAuLi5hcmdzKSB7XG4gICAgICAgIHN1cGVyKCk7XG5cbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJvYnNlcnZlciBjYWxsYmFjayBtdXN0IGJlIGEgZnVuY3Rpb25cIik7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNhbGxiYWNrID0gY2FsbGJhY2s7XG4gICAgICAgIHRoaXMuYXJndW1lbnRzID0gYXJncztcbiAgICAgICAgdGhpcy50YWdzID0gbmV3IFRva2VuTGlzdCgpO1xuICAgICAgICB0aGlzLnF1ZXVlID0gbmV3IFVuaXF1ZVF1ZXVlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMi4xLjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci90eXBlcy9vYnNlcnZlclwiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0YWdcbiAgICAgKiBAcmV0dXJucyB7T2JzZXJ2ZXJ9XG4gICAgICovXG4gICAgYWRkVGFnKHRhZykge1xuICAgICAgICB0aGlzLnRhZ3MuYWRkKHRhZyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHRhZ1xuICAgICAqIEByZXR1cm5zIHtPYnNlcnZlcn1cbiAgICAgKi9cbiAgICByZW1vdmVUYWcodGFnKSB7XG4gICAgICAgIHRoaXMudGFncy5yZW1vdmUodGFnKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9XG4gICAgICovXG4gICAgZ2V0VGFncygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudGFncy5lbnRyaWVzKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdGFnXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAgICovXG4gICAgaGFzVGFnKHRhZykge1xuICAgICAgICByZXR1cm4gdGhpcy50YWdzLmNvbnRhaW5zKHRhZyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gc3ViamVjdFxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlfVxuICAgICAqL1xuICAgIHVwZGF0ZShzdWJqZWN0KSB7XG4gICAgICAgIGxldCBzZWxmID0gdGhpcztcblxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICAgICAgaWYgKCFpc09iamVjdChzdWJqZWN0KSkge1xuICAgICAgICAgICAgICAgIHJlamVjdChcInN1YmplY3QgbXVzdCBiZSBhbiBvYmplY3RcIik7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBzZWxmLnF1ZXVlLmFkZChzdWJqZWN0KTtcblxuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gdGhlIHF1ZXVlIGFuZCB0aGUgc2V0dGltZW91dCBlbnN1cmUgdGhhdCBhbiBvYmplY3QgaXMgbm90XG4gICAgICAgICAgICAgICAgICAgIC8vIGluZm9ybWVkIG9mIHRoZSBzYW1lIGNoYW5nZSBtb3JlIHRoYW4gb25jZS5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYucXVldWUuaXNFbXB0eSgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBsZXQgcyA9IHNlbGYucXVldWUucG9sbCgpO1xuICAgICAgICAgICAgICAgICAgICBsZXQgcmVzdWx0ID0gc2VsZi5jYWxsYmFjay5hcHBseShzLCBzZWxmLmFyZ3VtZW50cyk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzT2JqZWN0KHJlc3VsdCkgJiYgcmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LnRoZW4ocmVzb2x2ZSkuY2F0Y2gocmVqZWN0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LCAwKTtcbiAgICAgICAgfSk7XG4gICAgfVxufVxuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgQmFzZSB9IGZyb20gXCIuL2Jhc2UubWpzXCI7XG5pbXBvcnQgeyBPYnNlcnZlciB9IGZyb20gXCIuL29ic2VydmVyLm1qc1wiO1xuaW1wb3J0IHsgdmFsaWRhdGVJbnN0YW5jZSB9IGZyb20gXCIuL3ZhbGlkYXRlLm1qc1wiO1xuXG5leHBvcnQgeyBPYnNlcnZlckxpc3QgfTtcblxuLyoqXG4gKiBXaXRoIHRoZSBoZWxwIG9mIHRoZSBPYnNlcnZlckxpc3QgY2xhc3MsIG9ic2VydmVyIGNhbiBiZSBtYW5hZ2VkLlxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMC4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcbiAqL1xuY2xhc3MgT2JzZXJ2ZXJMaXN0IGV4dGVuZHMgQmFzZSB7XG4gICAgLyoqXG4gICAgICpcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5vYnNlcnZlcnMgPSBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7T2JzZXJ2ZXJ9IG9ic2VydmVyXG4gICAgICogQHJldHVybiB7T2JzZXJ2ZXJMaXN0fVxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGFuIGluc3RhbmNlIG9mIE9ic2VydmVyXG4gICAgICovXG4gICAgYXR0YWNoKG9ic2VydmVyKSB7XG4gICAgICAgIHZhbGlkYXRlSW5zdGFuY2Uob2JzZXJ2ZXIsIE9ic2VydmVyKTtcblxuICAgICAgICB0aGlzLm9ic2VydmVycy5wdXNoKG9ic2VydmVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge09ic2VydmVyfSBvYnNlcnZlclxuICAgICAqIEByZXR1cm4ge09ic2VydmVyTGlzdH1cbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhbiBpbnN0YW5jZSBvZiBPYnNlcnZlclxuICAgICAqL1xuICAgIGRldGFjaChvYnNlcnZlcikge1xuICAgICAgICB2YWxpZGF0ZUluc3RhbmNlKG9ic2VydmVyLCBPYnNlcnZlcik7XG5cbiAgICAgICAgdmFyIGkgPSAwO1xuICAgICAgICB2YXIgbCA9IHRoaXMub2JzZXJ2ZXJzLmxlbmd0aDtcbiAgICAgICAgZm9yICg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICAgIGlmICh0aGlzLm9ic2VydmVyc1tpXSA9PT0gb2JzZXJ2ZXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9ic2VydmVycy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7T2JzZXJ2ZXJ9IG9ic2VydmVyXG4gICAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhbiBpbnN0YW5jZSBvZiBPYnNlcnZlclxuICAgICAqL1xuICAgIGNvbnRhaW5zKG9ic2VydmVyKSB7XG4gICAgICAgIHZhbGlkYXRlSW5zdGFuY2Uob2JzZXJ2ZXIsIE9ic2VydmVyKTtcbiAgICAgICAgdmFyIGkgPSAwO1xuICAgICAgICB2YXIgbCA9IHRoaXMub2JzZXJ2ZXJzLmxlbmd0aDtcbiAgICAgICAgZm9yICg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICAgIGlmICh0aGlzLm9ic2VydmVyc1tpXSA9PT0gb2JzZXJ2ZXIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0gc3ViamVjdFxuICAgICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAgICovXG4gICAgbm90aWZ5KHN1YmplY3QpIHtcbiAgICAgICAgbGV0IHBvbWlzZXMgPSBbXTtcblxuICAgICAgICBsZXQgaSA9IDA7XG4gICAgICAgIGxldCBsID0gdGhpcy5vYnNlcnZlcnMubGVuZ3RoO1xuICAgICAgICBmb3IgKDsgaSA8IGw7IGkrKykge1xuICAgICAgICAgICAgcG9taXNlcy5wdXNoKHRoaXMub2JzZXJ2ZXJzW2ldLnVwZGF0ZShzdWJqZWN0KSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocG9taXNlcyk7XG4gICAgfVxufVxuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgQmFzZSB9IGZyb20gXCIuL2Jhc2UubWpzXCI7XG5pbXBvcnQgeyBpc0FycmF5LCBpc09iamVjdCwgaXNQcmltaXRpdmUgfSBmcm9tIFwiLi9pcy5tanNcIjtcbmltcG9ydCB7IE9ic2VydmVyIH0gZnJvbSBcIi4vb2JzZXJ2ZXIubWpzXCI7XG5pbXBvcnQgeyBPYnNlcnZlckxpc3QgfSBmcm9tIFwiLi9vYnNlcnZlcmxpc3QubWpzXCI7XG5pbXBvcnQgeyB2YWxpZGF0ZU9iamVjdCB9IGZyb20gXCIuL3ZhbGlkYXRlLm1qc1wiO1xuaW1wb3J0IHsgZXh0ZW5kIH0gZnJvbSBcIi4uL2RhdGEvZXh0ZW5kLm1qc1wiO1xuaW1wb3J0IHsgaW5zdGFuY2VTeW1ib2wgfSBmcm9tIFwiLi4vY29uc3RhbnRzLm1qc1wiO1xuZXhwb3J0IHsgUHJveHlPYnNlcnZlciB9O1xuXG4vKipcbiAqIEFuIG9ic2VydmVyIG1hbmFnZXMgYSBjYWxsYmFjayBmdW5jdGlvblxuICpcbiAqIFdpdGggdGhlIFByb3h5T2JzZXJ2ZXIgeW91IGNhbiBhdHRhY2ggb2JzZXJ2ZXIgZm9yIG9ic2VydmF0aW9uLlxuICogV2l0aCBlYWNoIGNoYW5nZSBhdCB0aGUgb2JqZWN0IHRvIGJlIG9ic2VydmVkIGFuIHVwZGF0ZSB0YWtlcyBwbGFjZS5cbiAqXG4gKiBUaGlzIGFsc28gYXBwbGllcyB0byBuZXN0ZWQgb2JqZWN0cy5cbiAqXG4gKiBAZXh0ZXJuYWxFeGFtcGxlIC4uLy4uL2V4YW1wbGUvdHlwZXMvcHJveHlvYnNlcnZlci5tanNcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMC4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcbiAqL1xuY2xhc3MgUHJveHlPYnNlcnZlciBleHRlbmRzIEJhc2Uge1xuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtvYmplY3R9IG9iamVjdFxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgb2JqZWN0XG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob2JqZWN0KSB7XG4gICAgICAgIHN1cGVyKCk7XG5cbiAgICAgICAgdGhpcy5yZWFsU3ViamVjdCA9IHZhbGlkYXRlT2JqZWN0KG9iamVjdCk7XG4gICAgICAgIHRoaXMuc3ViamVjdCA9IG5ldyBQcm94eShvYmplY3QsIGdldEhhbmRsZXIuY2FsbCh0aGlzKSk7XG5cbiAgICAgICAgdGhpcy5vYmplY3RNYXAgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICB0aGlzLm9iamVjdE1hcC5zZXQodGhpcy5yZWFsU3ViamVjdCwgdGhpcy5zdWJqZWN0KTtcblxuICAgICAgICB0aGlzLnByb3h5TWFwID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgdGhpcy5wcm94eU1hcC5zZXQodGhpcy5zdWJqZWN0LCB0aGlzLnJlYWxTdWJqZWN0KTtcblxuICAgICAgICB0aGlzLm9ic2VydmVycyA9IG5ldyBPYnNlcnZlckxpc3QoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGBpbnN0YW5jZW9mYCBvcGVyYXRvci5cbiAgICAgKiBAcmV0dXJucyB7c3ltYm9sfVxuICAgICAqIEBzaW5jZSAyLjEuMFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgW2luc3RhbmNlU3ltYm9sXSgpIHtcbiAgICAgICAgcmV0dXJuIFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL3R5cGVzL3Byb3h5LW9ic2VydmVyXCIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIHtvYmplY3R9XG4gICAgICovXG4gICAgZ2V0U3ViamVjdCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3ViamVjdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAc2luY2UgMS4yNC4wXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9ialxuICAgICAqIEByZXR1cm4ge01vbnN0ZXIuVHlwZXMuUHJveHlPYnNlcnZlcn1cbiAgICAgKi9cbiAgICBzZXRTdWJqZWN0KG9iaikge1xuICAgICAgICBsZXQgaTtcbiAgICAgICAgbGV0IGsgPSBPYmplY3Qua2V5cyh0aGlzLnN1YmplY3QpO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgay5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMuc3ViamVjdFtrW2ldXTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc3ViamVjdCA9IGV4dGVuZCh0aGlzLnN1YmplY3QsIG9iaik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgcmVhbCBvYmplY3RcbiAgICAgKlxuICAgICAqIENoYW5nZXMgdG8gdGhpcyBvYmplY3QgYXJlIG5vdCBub3RpY2VkIGJ5IHRoZSBvYnNlcnZlcnMsIHNvIHlvdSBjYW4gbWFrZSBhIGxhcmdlIG51bWJlciBvZiBjaGFuZ2VzIGFuZCBpbmZvcm0gdGhlIG9ic2VydmVycyBsYXRlci5cbiAgICAgKiBcbiAgICAgKiBAcmV0dXJucyB7b2JqZWN0fVxuICAgICAqL1xuICAgIGdldFJlYWxTdWJqZWN0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5yZWFsU3ViamVjdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBhdHRhY2ggYSBuZXcgb2JzZXJ2ZXJcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7T2JzZXJ2ZXJ9IG9ic2VydmVyXG4gICAgICogQHJldHVybnMge1Byb3h5T2JzZXJ2ZXJ9XG4gICAgICovXG4gICAgYXR0YWNoT2JzZXJ2ZXIob2JzZXJ2ZXIpIHtcbiAgICAgICAgdGhpcy5vYnNlcnZlcnMuYXR0YWNoKG9ic2VydmVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogZGV0YWNoIGEgb2JzZXJ2ZXJcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7T2JzZXJ2ZXJ9IG9ic2VydmVyXG4gICAgICogQHJldHVybnMge1Byb3h5T2JzZXJ2ZXJ9XG4gICAgICovXG4gICAgZGV0YWNoT2JzZXJ2ZXIob2JzZXJ2ZXIpIHtcbiAgICAgICAgdGhpcy5vYnNlcnZlcnMuZGV0YWNoKG9ic2VydmVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogbm90aWZ5IGFsbCBvYnNlcnZlclxuICAgICAqXG4gICAgICogQHJldHVybnMge1Byb21pc2V9XG4gICAgICovXG4gICAgbm90aWZ5T2JzZXJ2ZXJzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5vYnNlcnZlcnMubm90aWZ5KHRoaXMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7T2JzZXJ2ZXJ9IG9ic2VydmVyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAgICovXG4gICAgY29udGFpbnNPYnNlcnZlcihvYnNlcnZlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5vYnNlcnZlcnMuY29udGFpbnMob2JzZXJ2ZXIpO1xuICAgIH1cbn1cblxuLyoqXG4gKlxuICogQHJldHVybnMge3tkZWZpbmVQcm9wZXJ0eTogKGZ1bmN0aW9uKCo9LCAqPSwgKj0pOiAqKSwgc2V0UHJvdG90eXBlT2Y6IChmdW5jdGlvbigqLCAqPSk6IGJvb2xlYW4pLCBzZXQ6IChmdW5jdGlvbigqLCAqLCAqLCAqKTogYm9vbGVhbiksIGdldDogKChmdW5jdGlvbigqPSwgKj0sICo9KTogKHVuZGVmaW5lZCkpfCopLCBkZWxldGVQcm9wZXJ0eTogKChmdW5jdGlvbigqLCAqKTogKGJvb2xlYW4pKXwqKX19XG4gKiBAcHJpdmF0ZVxuICogQHNlZSB7QGxpbmsgaHR0cHM6Ly9naXRsYWIuc2NodWthaS5jb20vLS9zbmlwcGV0cy80OX1cbiAqL1xuZnVuY3Rpb24gZ2V0SGFuZGxlcigpIHtcbiAgICBjb25zdCBwcm94eSA9IHRoaXM7XG5cbiAgICAvLyBodHRwczovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzkuMC8jc2VjLXByb3h5LW9iamVjdC1pbnRlcm5hbC1tZXRob2RzLWFuZC1pbnRlcm5hbC1zbG90c1xuICAgIGNvbnN0IGhhbmRsZXIgPSB7XG4gICAgICAgIC8vIGh0dHBzOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvOS4wLyNzZWMtcHJveHktb2JqZWN0LWludGVybmFsLW1ldGhvZHMtYW5kLWludGVybmFsLXNsb3RzLWdldC1wLXJlY2VpdmVyXG4gICAgICAgIGdldDogZnVuY3Rpb24gKHRhcmdldCwga2V5LCByZWNlaXZlcikge1xuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBSZWZsZWN0LmdldCh0YXJnZXQsIGtleSwgcmVjZWl2ZXIpO1xuXG4gICAgICAgICAgICBpZiAodHlwZW9mIGtleSA9PT0gXCJzeW1ib2xcIikge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGlzUHJpbWl0aXZlKHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gc2V0IHZhbHVlIGFzIHByb3h5IGlmIG9iamVjdCBvciBhcnJheVxuICAgICAgICAgICAgaWYgKGlzQXJyYXkodmFsdWUpIHx8IGlzT2JqZWN0KHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIGlmIChwcm94eS5vYmplY3RNYXAuaGFzKHZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcHJveHkub2JqZWN0TWFwLmdldCh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwcm94eS5wcm94eU1hcC5oYXModmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBsZXQgcCA9IG5ldyBQcm94eSh2YWx1ZSwgaGFuZGxlcik7XG4gICAgICAgICAgICAgICAgICAgIHByb3h5Lm9iamVjdE1hcC5zZXQodmFsdWUsIHApO1xuICAgICAgICAgICAgICAgICAgICBwcm94eS5wcm94eU1hcC5zZXQocCwgdmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfSxcblxuICAgICAgICAvLyBodHRwczovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzkuMC8jc2VjLXByb3h5LW9iamVjdC1pbnRlcm5hbC1tZXRob2RzLWFuZC1pbnRlcm5hbC1zbG90cy1zZXQtcC12LXJlY2VpdmVyXG4gICAgICAgIHNldDogZnVuY3Rpb24gKHRhcmdldCwga2V5LCB2YWx1ZSwgcmVjZWl2ZXIpIHtcbiAgICAgICAgICAgIGlmIChwcm94eS5wcm94eU1hcC5oYXModmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBwcm94eS5wcm94eU1hcC5nZXQodmFsdWUpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAocHJveHkucHJveHlNYXAuaGFzKHRhcmdldCkpIHtcbiAgICAgICAgICAgICAgICB0YXJnZXQgPSBwcm94eS5wcm94eU1hcC5nZXQodGFyZ2V0KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGV0IGN1cnJlbnQgPSBSZWZsZWN0LmdldCh0YXJnZXQsIGtleSwgcmVjZWl2ZXIpO1xuICAgICAgICAgICAgaWYgKHByb3h5LnByb3h5TWFwLmhhcyhjdXJyZW50KSkge1xuICAgICAgICAgICAgICAgIGN1cnJlbnQgPSBwcm94eS5wcm94eU1hcC5nZXQoY3VycmVudCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChjdXJyZW50ID09PSB2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgcmVzdWx0O1xuICAgICAgICAgICAgbGV0IGRlc2NyaXB0b3IgPSBSZWZsZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIGtleSk7XG5cbiAgICAgICAgICAgIGlmIChkZXNjcmlwdG9yID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBkZXNjcmlwdG9yID0ge1xuICAgICAgICAgICAgICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGRlc2NyaXB0b3JbXCJ2YWx1ZVwiXSA9IHZhbHVlO1xuICAgICAgICAgICAgcmVzdWx0ID0gUmVmbGVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgZGVzY3JpcHRvcik7XG5cbiAgICAgICAgICAgIGlmICh0eXBlb2Yga2V5ICE9PSBcInN5bWJvbFwiKSB7XG4gICAgICAgICAgICAgICAgcHJveHkub2JzZXJ2ZXJzLm5vdGlmeShwcm94eSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH0sXG5cbiAgICAgICAgLy8gaHR0cHM6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy85LjAvI3NlYy1wcm94eS1vYmplY3QtaW50ZXJuYWwtbWV0aG9kcy1hbmQtaW50ZXJuYWwtc2xvdHMtZGVsZXRlLXBcbiAgICAgICAgZGVsZXRlUHJvcGVydHk6IGZ1bmN0aW9uICh0YXJnZXQsIGtleSkge1xuICAgICAgICAgICAgaWYgKGtleSBpbiB0YXJnZXQpIHtcbiAgICAgICAgICAgICAgICBkZWxldGUgdGFyZ2V0W2tleV07XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGtleSAhPT0gXCJzeW1ib2xcIikge1xuICAgICAgICAgICAgICAgICAgICBwcm94eS5vYnNlcnZlcnMubm90aWZ5KHByb3h5KTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfSxcblxuICAgICAgICAvLyBodHRwczovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzkuMC8jc2VjLXByb3h5LW9iamVjdC1pbnRlcm5hbC1tZXRob2RzLWFuZC1pbnRlcm5hbC1zbG90cy1kZWZpbmVvd25wcm9wZXJ0eS1wLWRlc2NcbiAgICAgICAgZGVmaW5lUHJvcGVydHk6IGZ1bmN0aW9uICh0YXJnZXQsIGtleSwgZGVzY3JpcHRvcikge1xuICAgICAgICAgICAgbGV0IHJlc3VsdCA9IFJlZmxlY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIGRlc2NyaXB0b3IpO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBrZXkgIT09IFwic3ltYm9sXCIpIHtcbiAgICAgICAgICAgICAgICBwcm94eS5vYnNlcnZlcnMubm90aWZ5KHByb3h5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH0sXG5cbiAgICAgICAgLy8gaHR0cHM6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy85LjAvI3NlYy1wcm94eS1vYmplY3QtaW50ZXJuYWwtbWV0aG9kcy1hbmQtaW50ZXJuYWwtc2xvdHMtc2V0cHJvdG90eXBlb2YtdlxuICAgICAgICBzZXRQcm90b3R5cGVPZjogZnVuY3Rpb24gKHRhcmdldCwga2V5KSB7XG4gICAgICAgICAgICBsZXQgcmVzdWx0ID0gUmVmbGVjdC5zZXRQcm90b3R5cGVPZihvYmplY3QxLCBrZXkpO1xuXG4gICAgICAgICAgICBpZiAodHlwZW9mIGtleSAhPT0gXCJzeW1ib2xcIikge1xuICAgICAgICAgICAgICAgIHByb3h5Lm9ic2VydmVycy5ub3RpZnkocHJveHkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9LFxuICAgIH07XG5cbiAgICByZXR1cm4gaGFuZGxlcjtcbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGludGVybmFsU3RhdGVTeW1ib2wsIGludGVybmFsU3ltYm9sIH0gZnJvbSBcIi4uL2NvbnN0YW50cy5tanNcIjtcbmltcG9ydCB7IGV4dGVuZCB9IGZyb20gXCIuLi9kYXRhL2V4dGVuZC5tanNcIjtcbmltcG9ydCB7IEJhc2VXaXRoT3B0aW9ucyB9IGZyb20gXCIuLi90eXBlcy9iYXNld2l0aG9wdGlvbnMubWpzXCI7XG5pbXBvcnQgeyBnZXRHbG9iYWxPYmplY3QgfSBmcm9tIFwiLi4vdHlwZXMvZ2xvYmFsLm1qc1wiO1xuaW1wb3J0IHsgSUQgfSBmcm9tIFwiLi4vdHlwZXMvaWQubWpzXCI7XG5pbXBvcnQgeyBpc1N0cmluZyB9IGZyb20gXCIuLi90eXBlcy9pcy5tanNcIjtcbmltcG9ydCB7IE9ic2VydmVyIH0gZnJvbSBcIi4uL3R5cGVzL29ic2VydmVyLm1qc1wiO1xuaW1wb3J0IHsgUHJveHlPYnNlcnZlciB9IGZyb20gXCIuLi90eXBlcy9wcm94eW9ic2VydmVyLm1qc1wiO1xuaW1wb3J0IHsgQVRUUklCVVRFX0NMQVNTLCBBVFRSSUJVVEVfSUQsIEFUVFJJQlVURV9USVRMRSB9IGZyb20gXCIuL2NvbnN0YW50cy5tanNcIjtcbmltcG9ydCB7IGluc3RhbmNlU3ltYm9sIH0gZnJvbSBcIi4uL2NvbnN0YW50cy5tanNcIjtcblxuZXhwb3J0IHsgUmVzb3VyY2UsIEtFWV9ET0NVTUVOVCwgS0VZX1FVRVJZLCByZWZlcmVuY2VTeW1ib2wgfTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuY29uc3QgS0VZX0RPQ1VNRU5UID0gXCJkb2N1bWVudFwiO1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAdHlwZSB7c3RyaW5nfVxuICovXG5jb25zdCBLRVlfUVVFUlkgPSBcInF1ZXJ5XCI7XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEB0eXBlIHtzdHJpbmd9XG4gKi9cbmNvbnN0IEtFWV9USU1FT1VUID0gXCJ0aW1lb3V0XCI7XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEB0eXBlIHtzeW1ib2x9XG4gKi9cbmNvbnN0IHJlZmVyZW5jZVN5bWJvbCA9IFN5bWJvbChcInJlZmVyZW5jZVwiKTtcblxuLyoqXG4gKiBUaGlzIGNsYXNzIGlzIHRoZSBiYXNlIGNsYXNzIGZvciBhbGwgcmVzb3VyY2VzIHRvIGJlIGxvYWRlZC5cbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI1LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEBzdW1tYXJ5IEEgUmVzb3VyY2UgY2xhc3NcbiAqL1xuY2xhc3MgUmVzb3VyY2UgZXh0ZW5kcyBCYXNlV2l0aE9wdGlvbnMge1xuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYmplY3R8dW5kZWZpbmVkfSBvcHRpb25zXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgICAgICBzdXBlcihvcHRpb25zKTtcblxuICAgICAgICBsZXQgdXJpID0gdGhpcy5nZXRPcHRpb24odGhpcy5jb25zdHJ1Y3Rvci5nZXRVUkxBdHRyaWJ1dGUoKSk7XG5cbiAgICAgICAgaWYgKHVyaSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJtaXNzaW5nIHNvdXJjZVwiKTtcbiAgICAgICAgfSBlbHNlIGlmICh1cmkgaW5zdGFuY2VvZiBVUkwpIHtcbiAgICAgICAgICAgIHVyaSA9IHVyaS50b1N0cmluZygpO1xuICAgICAgICB9IGVsc2UgaWYgKCFpc1N0cmluZyh1cmkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1bnN1cHBvcnRlZCB1cmwgdHlwZVwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXNbaW50ZXJuYWxTeW1ib2xdW3RoaXMuY29uc3RydWN0b3IuZ2V0VVJMQXR0cmlidXRlKCldID0gdXJpO1xuICAgICAgICB0aGlzW2ludGVybmFsU3RhdGVTeW1ib2xdID0gbmV3IFByb3h5T2JzZXJ2ZXIoe1xuICAgICAgICAgICAgbG9hZGVkOiBmYWxzZSxcbiAgICAgICAgICAgIGVycm9yOiB1bmRlZmluZWQsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXNbcmVmZXJlbmNlU3ltYm9sXSA9IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgICAqL1xuICAgIGlzQ29ubmVjdGVkKCkge1xuICAgICAgICBpZiAodGhpc1tyZWZlcmVuY2VTeW1ib2xdIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzW3JlZmVyZW5jZVN5bWJvbF0uaXNDb25uZWN0ZWQ7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgb3ZlcnJpZGRlbiBieSB0aGUgc3BlY2lhbCBjbGFzc2VzIGFuZCBjcmVhdGVzIHRoZSBET00gb2JqZWN0LlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGFsc28gY2FsbGVkIGltcGxpY2l0bHksIGlmIG5vdCB5ZXQgZG9uZSBleHBsaWNpdGx5LCBieSBjYWxsaW5nIGBjb25uZWN0KClgLlxuICAgICAqXG4gICAgICogQHRocm93cyB7RXJyb3J9IHRoaXMgbWV0aG9kIG11c3QgYmUgaW1wbGVtZW50ZWQgYnkgZGVyaXZlZCBjbGFzc2VzXG4gICAgICogQHJldHVybiB7TW9uc3Rlci5ET00uUmVzb3VyY2V9XG4gICAgICovXG4gICAgY3JlYXRlKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0aGlzIG1ldGhvZCBtdXN0IGJlIGltcGxlbWVudGVkIGJ5IGRlcml2ZWQgY2xhc3Nlc1wiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBhcHBlbmRzIHRoZSBIVE1MRWxlbWVudCB0byB0aGUgc3BlY2lmaWVkIGRvY3VtZW50LlxuICAgICAqIElmIHRoZSBlbGVtZW50IGhhcyBub3QgeWV0IGJlZW4gY3JlYXRlZCwgYGNyZWF0ZSgpYCBpcyBjYWxsZWQgaW1wbGljaXRseS5cbiAgICAgKlxuICAgICAqIHRocm93cyB7RXJyb3J9IHRhcmdldCBub3QgZm91bmRcbiAgICAgKiBAcmV0dXJuIHtNb25zdGVyLkRPTS5SZXNvdXJjZX1cbiAgICAgKi9cbiAgICBjb25uZWN0KCkge1xuICAgICAgICBpZiAoISh0aGlzW3JlZmVyZW5jZVN5bWJvbF0gaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpIHtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRlKCk7XG4gICAgICAgIH1cblxuICAgICAgICBhcHBlbmRUb0RvY3VtZW50LmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwcm9wZXJ0eSB7RG9jdW1lbnR9IGRvY3VtZW50IHRoZSBkb2N1bWVudCBvYmplY3QgaW50byB3aGljaCB0aGUgbm9kZSBpcyB0byBiZSBhcHBlbmRlZFxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBzcmMvaHJlZiB1cmwgdG8gdGhlIGNvcnJlc3BvbmRpbmcgcmVzb3VyY2VcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gcXVlcnkgZGVmaW5lcyB0aGUgbG9jYXRpb24gd2hlcmUgdGhlIHJlc291cmNlIGlzIHRvIGJlIGhvb2tlZCBpbnRvIHRoZSBkb20uXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd9IGlkIGVsZW1lbnQgYXR0cmlidXRlIGlkXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd9IHRpdGxlIGVsZW1lbnQgYXR0cmlidXRlIHRpdGxlXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd9IGNsYXNzIGVsZW1lbnQgYXR0cmlidXRlIGNsYXNzXG4gICAgICogQHByb3BlcnR5IHtpbnR9IHRpbWVvdXQgdGltZW91dFxuICAgICAqL1xuICAgIGdldCBkZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIGV4dGVuZCh7fSwgc3VwZXIuZGVmYXVsdHMsIHtcbiAgICAgICAgICAgIFt0aGlzLmNvbnN0cnVjdG9yLmdldFVSTEF0dHJpYnV0ZSgpXTogdW5kZWZpbmVkLFxuICAgICAgICAgICAgW0tFWV9ET0NVTUVOVF06IGdldEdsb2JhbE9iamVjdChcImRvY3VtZW50XCIpLFxuICAgICAgICAgICAgW0tFWV9RVUVSWV06IFwiaGVhZFwiLFxuICAgICAgICAgICAgW0tFWV9USU1FT1VUXTogMTAwMDAsXG4gICAgICAgICAgICBbQVRUUklCVVRFX0lEXTogbmV3IElEKFwicmVzb3VyY2VcIikudG9TdHJpbmcoKSxcbiAgICAgICAgICAgIFtBVFRSSUJVVEVfQ0xBU1NdOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBbQVRUUklCVVRFX1RJVExFXTogdW5kZWZpbmVkLFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBXaXRoIGBhdmFpbGFibGUoKWAgeW91IGNhbiBjaGVjayBpZiBhIHJlc291cmNlIGlzIGF2YWlsYWJsZS5cbiAgICAgKiBUaGlzIGlzIHRoZSBjYXNlIHdoZW4gdGhlIHRhZyBpcyBpbmNsdWRlZCBhbmQgdGhlIHJlc291cmNlIGlzIGxvYWRlZC5cbiAgICAgKlxuICAgICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAgICovXG4gICAgYXZhaWxhYmxlKCkge1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICAgICAgaWYgKCEoc2VsZltyZWZlcmVuY2VTeW1ib2xdIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXCJubyBlbGVtZW50XCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFzZWxmLmlzQ29ubmVjdGVkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChcImVsZW1lbnQgbm90IGNvbm5lY3RlZFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzZWxmW2ludGVybmFsU3RhdGVTeW1ib2xdLmdldFN1YmplY3QoKVtcImxvYWRlZFwiXSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgaWYgKHNlbGZbaW50ZXJuYWxTdGF0ZVN5bWJvbF0uZ2V0U3ViamVjdCgpW1wiZXJyb3JcIl0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChzZWxmW2ludGVybmFsU3RhdGVTeW1ib2xdLmdldFN1YmplY3QoKVtcImVycm9yXCJdKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgICAgIGNvbnN0IHRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICByZWplY3QoXCJ0aW1lb3V0XCIpO1xuICAgICAgICAgICAgfSwgc2VsZi5nZXRPcHRpb24oXCJ0aW1lb3V0XCIpKTtcblxuICAgICAgICAgICAgY29uc3Qgb2JzZXJ2ZXIgPSBuZXcgT2JzZXJ2ZXIoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgICAgICAgICAgICBzZWxmW2ludGVybmFsU3RhdGVTeW1ib2xdLmRldGFjaE9ic2VydmVyKG9ic2VydmVyKTtcbiAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgc2VsZltpbnRlcm5hbFN0YXRlU3ltYm9sXS5hdHRhY2hPYnNlcnZlcihvYnNlcnZlcik7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge3N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0VVJMQXR0cmlidXRlKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0aGlzIG1ldGhvZCBtdXN0IGJlIGltcGxlbWVudGVkIGJ5IGRlcml2ZWQgY2xhc3Nlc1wiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtzeW1ib2x9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBbaW5zdGFuY2VTeW1ib2xdKCkge1xuICAgICAgICByZXR1cm4gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvZG9tL3Jlc291cmNlXCIpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHJldHVybiB7UHJvbWlzZX1cbiAqIHRocm93cyB7RXJyb3J9IHRhcmdldCBub3QgZm91bmRcbiAqL1xuZnVuY3Rpb24gYXBwZW5kVG9Eb2N1bWVudCgpIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgIGNvbnN0IHRhcmdldE5vZGUgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHNlbGYuZ2V0T3B0aW9uKEtFWV9RVUVSWSwgXCJoZWFkXCIpKTtcbiAgICBpZiAoISh0YXJnZXROb2RlIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcInRhcmdldCBub3QgZm91bmRcIik7XG4gICAgfVxuXG4gICAgYWRkRXZlbnRzLmNhbGwoc2VsZik7XG4gICAgdGFyZ2V0Tm9kZS5hcHBlbmRDaGlsZChzZWxmW3JlZmVyZW5jZVN5bWJvbF0pO1xuXG4gICAgcmV0dXJuIHNlbGY7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEByZXR1cm4ge2FkZEV2ZW50c31cbiAqL1xuZnVuY3Rpb24gYWRkRXZlbnRzKCkge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgY29uc3Qgb25FcnJvciA9ICgpID0+IHtcbiAgICAgICAgc2VsZltyZWZlcmVuY2VTeW1ib2xdLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJlcnJvclwiLCBvbkVycm9yKTtcbiAgICAgICAgc2VsZltyZWZlcmVuY2VTeW1ib2xdLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJsb2FkXCIsIG9uTG9hZCk7XG5cbiAgICAgICAgc2VsZltpbnRlcm5hbFN0YXRlU3ltYm9sXS5zZXRTdWJqZWN0KHtcbiAgICAgICAgICAgIGxvYWRlZDogdHJ1ZSxcbiAgICAgICAgICAgIGVycm9yOiBgJHtzZWxmW3JlZmVyZW5jZVN5bWJvbF1bc2VsZi5jb25zdHJ1Y3Rvci5nZXRVUkxBdHRyaWJ1dGUoKV19IGlzIG5vdCBhdmFpbGFibGVgLFxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm47XG4gICAgfTtcblxuICAgIGNvbnN0IG9uTG9hZCA9ICgpID0+IHtcbiAgICAgICAgc2VsZltyZWZlcmVuY2VTeW1ib2xdLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJlcnJvclwiLCBvbkVycm9yKTtcbiAgICAgICAgc2VsZltyZWZlcmVuY2VTeW1ib2xdLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJsb2FkXCIsIG9uTG9hZCk7XG4gICAgICAgIHNlbGZbaW50ZXJuYWxTdGF0ZVN5bWJvbF0uZ2V0U3ViamVjdCgpW1wibG9hZGVkXCJdID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH07XG5cbiAgICBzZWxmW3JlZmVyZW5jZVN5bWJvbF0uYWRkRXZlbnRMaXN0ZW5lcihcImxvYWRcIiwgb25Mb2FkLCBmYWxzZSk7XG4gICAgc2VsZltyZWZlcmVuY2VTeW1ib2xdLmFkZEV2ZW50TGlzdGVuZXIoXCJlcnJvclwiLCBvbkVycm9yLCBmYWxzZSk7XG5cbiAgICByZXR1cm4gc2VsZjtcbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IEJhc2UgfSBmcm9tIFwiLi9iYXNlLm1qc1wiO1xuaW1wb3J0IHsgaXNTdHJpbmcgfSBmcm9tIFwiLi9pcy5tanNcIjtcbmltcG9ydCB7IHZhbGlkYXRlQXJyYXksIHZhbGlkYXRlU3RyaW5nIH0gZnJvbSBcIi4vdmFsaWRhdGUubWpzXCI7XG5pbXBvcnQgeyBpbnN0YW5jZVN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5leHBvcnQgeyBNZWRpYVR5cGUsIHBhcnNlTWVkaWFUeXBlIH07XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEB0eXBlIHtzeW1ib2x9XG4gKi9cbmNvbnN0IGludGVybmFsID0gU3ltYm9sKFwiaW50ZXJuYWxcIik7XG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gUGFyYW1ldGVyXG4gKiBAcHJvcGVydHkge3N0cmluZ30ga2V5XG4gKiBAcHJvcGVydHkge3N0cmluZ30gdmFsdWVcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKi9cblxuLyoqXG4gKiBZb3UgY2FuIGNyZWF0ZSBhbiBvYmplY3QgdmlhIHRoZSBtb25zdGVyIG5hbWVzcGFjZSBgbmV3IE1vbnN0ZXIuVHlwZXMuTWVkaWFUeXBlKClgLlxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuOC4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcbiAqL1xuY2xhc3MgTWVkaWFUeXBlIGV4dGVuZHMgQmFzZSB7XG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gdHlwZVxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBzdWJ0eXBlXG4gICAgICogQHBhcmFtIHtNb25zdGVyLlR5cGVzLlBhcmFtZXRlcltdfSBwYXJhbWV0ZXJcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0eXBlLCBzdWJ0eXBlLCBwYXJhbWV0ZXIpIHtcbiAgICAgICAgc3VwZXIoKTtcblxuICAgICAgICB0aGlzW2ludGVybmFsXSA9IHtcbiAgICAgICAgICAgIHR5cGU6IHZhbGlkYXRlU3RyaW5nKHR5cGUpLnRvTG93ZXJDYXNlKCksXG4gICAgICAgICAgICBzdWJ0eXBlOiB2YWxpZGF0ZVN0cmluZyhzdWJ0eXBlKS50b0xvd2VyQ2FzZSgpLFxuICAgICAgICAgICAgcGFyYW1ldGVyOiBbXSxcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAocGFyYW1ldGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXNbaW50ZXJuYWxdW1wicGFyYW1ldGVyXCJdID0gdmFsaWRhdGVBcnJheShwYXJhbWV0ZXIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMi4xLjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci90eXBlcy9tZWRpYS10eXBlXCIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbaW50ZXJuYWxdLnR5cGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldCBzdWJ0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpc1tpbnRlcm5hbF0uc3VidHlwZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtNb25zdGVyLlR5cGVzLlBhcmFtZXRlcltdfVxuICAgICAqL1xuICAgIGdldCBwYXJhbWV0ZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzW2ludGVybmFsXS5wYXJhbWV0ZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKlxuICAgICAqIEByZXR1cm4ge01hcH1cbiAgICAgKi9cbiAgICBnZXQgcGFyYW1ldGVyKCkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBuZXcgTWFwKCk7XG5cbiAgICAgICAgdGhpc1tpbnRlcm5hbF1bXCJwYXJhbWV0ZXJcIl0uZm9yRWFjaCgocCkgPT4ge1xuICAgICAgICAgICAgbGV0IHZhbHVlID0gcC52YWx1ZTtcblxuICAgICAgICAgICAgLy8gaW50ZXJuYWxseSBzcGVjaWFsIHZhbHVlcyBhcmUgcGFydGx5IHN0b3JlZCB3aXRoIHF1b3RlcywgdGhpcyBmdW5jdGlvbiByZW1vdmVzIHRoZW0uXG4gICAgICAgICAgICBpZiAodmFsdWUuc3RhcnRzV2l0aCgnXCInKSAmJiB2YWx1ZS5lbmRzV2l0aCgnXCInKSkge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gdmFsdWUuc3Vic3RyaW5nKDEsIHZhbHVlLmxlbmd0aCAtIDEpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXN1bHQuc2V0KHAua2V5LCB2YWx1ZSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAgICovXG4gICAgdG9TdHJpbmcoKSB7XG4gICAgICAgIGxldCBwYXJhbWV0ZXIgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgYSBvZiB0aGlzW2ludGVybmFsXS5wYXJhbWV0ZXIpIHtcbiAgICAgICAgICAgIHBhcmFtZXRlci5wdXNoKGAke2Eua2V5fT0ke2EudmFsdWV9YCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYCR7dGhpc1tpbnRlcm5hbF0udHlwZX0vJHt0aGlzW2ludGVybmFsXS5zdWJ0eXBlfSR7XG4gICAgICAgICAgICBwYXJhbWV0ZXIubGVuZ3RoID4gMCA/IGA7JHtwYXJhbWV0ZXIuam9pbihcIjtcIil9YCA6IFwiXCJcbiAgICAgICAgfWA7XG4gICAgfVxufVxuXG4vKipcbiAqIFlvdSBjYW4gY2FsbCB0aGUgZnVuY3Rpb24gdmlhIHRoZSBtb25zdGVyIG5hbWVzcGFjZSBgTW9uc3Rlci5UeXBlcy5wYXJzZU1lZGlhVHlwZSgpYC5cbiAqXG4gKiBgYGBcbiAqIDxzY3JpcHQgdHlwZT1cIm1vZHVsZVwiPlxuICogaW1wb3J0IHtNb25zdGVyfSBmcm9tICdAc2NodWthaS9tb25zdGVyL3NvdXJjZS9tb25zdGVyLm1qcyc7XG4gKiBjb25zb2xlLmxvZyhNb25zdGVyLlR5cGVzLnBhcnNlTWVkaWFUeXBlKCkpXG4gKiA8L3NjcmlwdD5cbiAqIGBgYFxuICpcbiAqIEFsdGVybmF0aXZlbHksIHlvdSBjYW4gYWxzbyBpbnRlZ3JhdGUgdGhpcyBmdW5jdGlvbiBpbmRpdmlkdWFsbHkuXG4gKlxuICogYGBgXG4gKiA8c2NyaXB0IHR5cGU9XCJtb2R1bGVcIj5cbiAqIGltcG9ydCB7cGFyc2VNZWRpYVR5cGV9IGZyb20gJ0BzY2h1a2FpL21vbnN0ZXIvc291cmNlL3R5cGVzL2RhdGF1cmwubWpzJztcbiAqIGNvbnNvbGUubG9nKHBhcnNlTWVkaWFUeXBlKCkpXG4gKiA8L3NjcmlwdD5cbiAqIGBgYFxuICpcbiAqIFNwZWNpZmljYXRpb246XG4gKlxuICogYGBgXG4gKiBkYXRhdXJsICAgIDo9IFwiZGF0YTpcIiBbIG1lZGlhdHlwZSBdIFsgXCI7YmFzZTY0XCIgXSBcIixcIiBkYXRhXG4gKiBtZWRpYXR5cGUgIDo9IFsgdHlwZSBcIi9cIiBzdWJ0eXBlIF0gKiggXCI7XCIgcGFyYW1ldGVyIClcbiAqIGRhdGEgICAgICAgOj0gKnVybGNoYXJcbiAqIHBhcmFtZXRlciAgOj0gYXR0cmlidXRlIFwiPVwiIHZhbHVlXG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbWVkaWF0eXBlXG4gKiBAcmV0dXJuIHtNb25zdGVyLlR5cGVzLk1lZGlhVHlwZX1cbiAqIEBzZWUgaHR0cHM6Ly9kYXRhdHJhY2tlci5pZXRmLm9yZy9kb2MvaHRtbC9yZmMyMDQ1I3NlY3Rpb24tNS4xXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHRoZSBtaW1ldHlwZSBjYW4gbm90IGJlIHBhcnNlZFxuICogQHRocm93cyB7VHlwZUVycm9yfSBibGFuayB2YWx1ZSBpcyBub3QgYWxsb3dlZFxuICogQHRocm93cyB7VHlwZUVycm9yfSBtYWxmb3JtZWQgZGF0YSB1cmxcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKi9cbmZ1bmN0aW9uIHBhcnNlTWVkaWFUeXBlKG1lZGlhdHlwZSkge1xuICAgIGNvbnN0IHJlZ2V4ID1cbiAgICAgICAgLyg/PHR5cGU+W0EtWmEtel0rfFxcKilcXC8oPzxzdWJ0eXBlPihbYS16QS1aMC05LlxcK19cXC1dKyl8XFwqfCkoPzxwYXJhbWV0ZXI+XFxzKjtcXHMqKFthLXpBLVowLTldKylcXHMqKD1cXHMqKFwiP1tBLVphLXowLTlfXFwtXStcIj8pKT8pKi9nO1xuICAgIGNvbnN0IHJlc3VsdCA9IHJlZ2V4LmV4ZWModmFsaWRhdGVTdHJpbmcobWVkaWF0eXBlKSk7XG5cbiAgICBjb25zdCBncm91cHMgPSByZXN1bHQ/LltcImdyb3Vwc1wiXTtcbiAgICBpZiAoZ3JvdXBzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInRoZSBtaW1ldHlwZSBjYW4gbm90IGJlIHBhcnNlZFwiKTtcbiAgICB9XG5cbiAgICBjb25zdCB0eXBlID0gZ3JvdXBzPy5bXCJ0eXBlXCJdO1xuICAgIGNvbnN0IHN1YnR5cGUgPSBncm91cHM/LltcInN1YnR5cGVcIl07XG4gICAgY29uc3QgcGFyYW1ldGVyID0gZ3JvdXBzPy5bXCJwYXJhbWV0ZXJcIl07XG5cbiAgICBpZiAoc3VidHlwZSA9PT0gXCJcIiB8fCB0eXBlID09PSBcIlwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJibGFuayB2YWx1ZSBpcyBub3QgYWxsb3dlZFwiKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IE1lZGlhVHlwZSh0eXBlLCBzdWJ0eXBlLCBwYXJzZVBhcmFtZXRlcihwYXJhbWV0ZXIpKTtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4xOC4wXG4gKiBAcGFyYW0ge1N0cmluZ30gcGFyYW1ldGVyXG4gKiBAcmV0dXJuIHtNb25zdGVyLlR5cGVzLlBhcmFtZXRlcltdfHVuZGVmaW5lZH1cbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKi9cbmZ1bmN0aW9uIHBhcnNlUGFyYW1ldGVyKHBhcmFtZXRlcikge1xuICAgIGlmICghaXNTdHJpbmcocGFyYW1ldGVyKSkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGxldCByZXN1bHQgPSBbXTtcblxuICAgIHBhcmFtZXRlci5zcGxpdChcIjtcIikuZm9yRWFjaCgoZW50cnkpID0+IHtcbiAgICAgICAgZW50cnkgPSBlbnRyeS50cmltKCk7XG4gICAgICAgIGlmIChlbnRyeSA9PT0gXCJcIikge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qga3YgPSBlbnRyeS5zcGxpdChcIj1cIik7XG5cbiAgICAgICAgbGV0IGtleSA9IHZhbGlkYXRlU3RyaW5nKGt2Py5bMF0pLnRyaW0oKTtcbiAgICAgICAgbGV0IHZhbHVlID0gdmFsaWRhdGVTdHJpbmcoa3Y/LlsxXSkudHJpbSgpO1xuXG4gICAgICAgIC8vIGlmIHZhbHVlcyBhcmUgcXVvdGVkLCB0aGV5IHJlbWFpbiBzbyBpbnRlcm5hbGx5XG4gICAgICAgIHJlc3VsdC5wdXNoKHtcbiAgICAgICAgICAgIGtleToga2V5LFxuICAgICAgICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIHJldHVybiByZXN1bHQ7XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBCYXNlIH0gZnJvbSBcIi4vYmFzZS5tanNcIjtcbmltcG9ydCB7IGlzU3RyaW5nIH0gZnJvbSBcIi4vaXMubWpzXCI7XG5pbXBvcnQgeyBNZWRpYVR5cGUsIHBhcnNlTWVkaWFUeXBlIH0gZnJvbSBcIi4vbWVkaWF0eXBlLm1qc1wiO1xuaW1wb3J0IHsgdmFsaWRhdGVCb29sZWFuLCB2YWxpZGF0ZUluc3RhbmNlLCB2YWxpZGF0ZVN0cmluZyB9IGZyb20gXCIuL3ZhbGlkYXRlLm1qc1wiO1xuaW1wb3J0IHsgaW5zdGFuY2VTeW1ib2wgfSBmcm9tIFwiLi4vY29uc3RhbnRzLm1qc1wiO1xuZXhwb3J0IHsgRGF0YVVybCwgcGFyc2VEYXRhVVJMIH07XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEB0eXBlIHtzeW1ib2x9XG4gKi9cbmNvbnN0IGludGVybmFsID0gU3ltYm9sKFwiaW50ZXJuYWxcIik7XG5cbi8qKlxuICogWW91IGNhbiBjcmVhdGUgYW4gb2JqZWN0IHZpYSB0aGUgbW9uc3RlciBuYW1lc3BhY2UgYG5ldyBNb25zdGVyLlR5cGVzLkRhdGFVcmwoKWAuXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS44LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UeXBlc1xuICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVFRQL0Jhc2ljc19vZl9IVFRQL0RhdGFfVVJJc1xuICogQHNlZSBodHRwczovL2RhdGF0cmFja2VyLmlldGYub3JnL2RvYy9odG1sL3JmYzIzOTdcbiAqL1xuY2xhc3MgRGF0YVVybCBleHRlbmRzIEJhc2Uge1xuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGNvbnRlbnRcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xNb25zdGVyLlR5cGVzLk1lZGlhVHlwZX0gbWVkaWF0eXBlXG4gICAgICogQHBhcmFtIHtib29sZWFufSBiYXNlNjQ9dHJ1ZVxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGNvbnRlbnQsIG1lZGlhdHlwZSwgYmFzZTY0KSB7XG4gICAgICAgIHN1cGVyKCk7XG5cbiAgICAgICAgaWYgKGlzU3RyaW5nKG1lZGlhdHlwZSkpIHtcbiAgICAgICAgICAgIG1lZGlhdHlwZSA9IHBhcnNlTWVkaWFUeXBlKG1lZGlhdHlwZSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzW2ludGVybmFsXSA9IHtcbiAgICAgICAgICAgIGNvbnRlbnQ6IHZhbGlkYXRlU3RyaW5nKGNvbnRlbnQpLFxuICAgICAgICAgICAgbWVkaWF0eXBlOiB2YWxpZGF0ZUluc3RhbmNlKG1lZGlhdHlwZSwgTWVkaWFUeXBlKSxcbiAgICAgICAgICAgIGJhc2U2NDogdmFsaWRhdGVCb29sZWFuKGJhc2U2NCA9PT0gdW5kZWZpbmVkID8gdHJ1ZSA6IGJhc2U2NCksXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMi4xLjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci90eXBlcy9kYXRhLXVybFwiKTtcbiAgICB9XG5cbiAgICBnZXQgY29udGVudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbaW50ZXJuYWxdLmJhc2U2NCA/IGF0b2IodGhpc1tpbnRlcm5hbF0uY29udGVudCkgOiB0aGlzW2ludGVybmFsXS5jb250ZW50O1xuICAgIH1cblxuICAgIGdldCBtZWRpYXR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzW2ludGVybmFsXS5tZWRpYXR5cGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAgICogQHNlZSBodHRwczovL2RhdGF0cmFja2VyLmlldGYub3JnL2RvYy9odG1sL3JmYzIzOTdcbiAgICAgKi9cbiAgICB0b1N0cmluZygpIHtcbiAgICAgICAgbGV0IGNvbnRlbnQgPSB0aGlzW2ludGVybmFsXS5jb250ZW50O1xuXG4gICAgICAgIGlmICh0aGlzW2ludGVybmFsXS5iYXNlNjQgPT09IHRydWUpIHtcbiAgICAgICAgICAgIGNvbnRlbnQgPSBgO2Jhc2U2NCwke2NvbnRlbnR9YDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnRlbnQgPSBgLCR7ZW5jb2RlVVJJQ29tcG9uZW50KGNvbnRlbnQpfWA7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYGRhdGE6JHt0aGlzW2ludGVybmFsXS5tZWRpYXR5cGUudG9TdHJpbmcoKX0ke2NvbnRlbnR9YDtcbiAgICB9XG59XG5cbi8qKlxuICogWW91IGNhbiBjYWxsIHRoZSBmdW5jdGlvbiB2aWEgdGhlIG1vbnN0ZXIgbmFtZXNwYWNlIGBNb25zdGVyLlR5cGVzLnBhcnNlRGF0YVVSTCgpYC5cbiAqXG4gKiBTcGVjaWZpY2F0aW9uOlxuICpcbiAqIGBgYFxuICogZGF0YXVybCAgICA6PSBcImRhdGE6XCIgWyBtZWRpYXR5cGUgXSBbIFwiO2Jhc2U2NFwiIF0gXCIsXCIgZGF0YVxuICogbWVkaWF0eXBlICA6PSBbIHR5cGUgXCIvXCIgc3VidHlwZSBdICooIFwiO1wiIHBhcmFtZXRlciApXG4gKiBkYXRhICAgICAgIDo9ICp1cmxjaGFyXG4gKiBwYXJhbWV0ZXIgIDo9IGF0dHJpYnV0ZSBcIj1cIiB2YWx1ZVxuICogYGBgXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGRhdGF1cmxcbiAqIEByZXR1cm4ge01vbnN0ZXIuVHlwZXMuRGF0YVVybH1cbiAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRUUC9CYXNpY3Nfb2ZfSFRUUC9EYXRhX1VSSXNcbiAqIEBzZWUgaHR0cHM6Ly9kYXRhdHJhY2tlci5pZXRmLm9yZy9kb2MvaHRtbC9yZmMyMzk3XG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IGluY29ycmVjdCBvciBtaXNzaW5nIGRhdGEgcHJvdG9jb2xcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gbWFsZm9ybWVkIGRhdGEgdXJsXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UeXBlc1xuICovXG5mdW5jdGlvbiBwYXJzZURhdGFVUkwoZGF0YXVybCkge1xuICAgIHZhbGlkYXRlU3RyaW5nKGRhdGF1cmwpO1xuXG4gICAgZGF0YXVybCA9IGRhdGF1cmwudHJpbSgpO1xuXG4gICAgaWYgKGRhdGF1cmwuc3Vic3RyaW5nKDAsIDUpICE9PSBcImRhdGE6XCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImluY29ycmVjdCBvciBtaXNzaW5nIGRhdGEgcHJvdG9jb2xcIik7XG4gICAgfVxuXG4gICAgZGF0YXVybCA9IGRhdGF1cmwuc3Vic3RyaW5nKDUpO1xuXG4gICAgbGV0IHAgPSBkYXRhdXJsLmluZGV4T2YoXCIsXCIpO1xuICAgIGlmIChwID09PSAtMSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwibWFsZm9ybWVkIGRhdGEgdXJsXCIpO1xuICAgIH1cblxuICAgIGxldCBjb250ZW50ID0gZGF0YXVybC5zdWJzdHJpbmcocCArIDEpO1xuICAgIGxldCBtZWRpYXR5cGVBbmRCYXNlNjQgPSBkYXRhdXJsLnN1YnN0cmluZygwLCBwKS50cmltKCk7XG4gICAgbGV0IG1lZGlhdHlwZSA9IFwidGV4dC9wbGFpbjtjaGFyc2V0PVVTLUFTQ0lJXCI7XG4gICAgbGV0IGJhc2U2NEZsYWcgPSBmYWxzZTtcblxuICAgIGlmIChtZWRpYXR5cGVBbmRCYXNlNjQgIT09IFwiXCIpIHtcbiAgICAgICAgbWVkaWF0eXBlID0gbWVkaWF0eXBlQW5kQmFzZTY0O1xuICAgICAgICBpZiAobWVkaWF0eXBlQW5kQmFzZTY0LmVuZHNXaXRoKFwiYmFzZTY0XCIpKSB7XG4gICAgICAgICAgICBsZXQgaSA9IG1lZGlhdHlwZUFuZEJhc2U2NC5sYXN0SW5kZXhPZihcIjtcIik7XG4gICAgICAgICAgICBtZWRpYXR5cGUgPSBtZWRpYXR5cGVBbmRCYXNlNjQuc3Vic3RyaW5nKDAsIGkpO1xuICAgICAgICAgICAgYmFzZTY0RmxhZyA9IHRydWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb250ZW50ID0gZGVjb2RlVVJJQ29tcG9uZW50KGNvbnRlbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgbWVkaWF0eXBlID0gcGFyc2VNZWRpYVR5cGUobWVkaWF0eXBlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBjb250ZW50ID0gZGVjb2RlVVJJQ29tcG9uZW50KGNvbnRlbnQpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgRGF0YVVybChjb250ZW50LCBtZWRpYXR5cGUsIGJhc2U2NEZsYWcpO1xufVxuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgQmFzZSB9IGZyb20gXCIuLi90eXBlcy9iYXNlLm1qc1wiO1xuaW1wb3J0IHsgZ2V0R2xvYmFsT2JqZWN0IH0gZnJvbSBcIi4uL3R5cGVzL2dsb2JhbC5tanNcIjtcbmltcG9ydCB7IHZhbGlkYXRlU3RyaW5nIH0gZnJvbSBcIi4uL3R5cGVzL3ZhbGlkYXRlLm1qc1wiO1xuaW1wb3J0IHsgQVRUUklCVVRFX1RIRU1FX05BTUUsIERFRkFVTFRfVEhFTUUgfSBmcm9tIFwiLi9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQgeyBpbnN0YW5jZVN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5leHBvcnQgeyBUaGVtZSwgZ2V0RG9jdW1lbnRUaGVtZSB9O1xuXG4vKipcbiAqIFRoZSBUaGVtZSBjbGFzcyBwcm92aWRlcyB0aGUgZnVuY3Rpb25hbGl0eSBmb3IgdGhlIHRoZW1lLlxuICpcbiAqIEBleHRlcm5hbEV4YW1wbGUgLi4vLi4vZXhhbXBsZS9kb20vdGhlbWUubWpzXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjcuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHN1bW1hcnkgQSB0aGVtZSBjbGFzc1xuICovXG5jbGFzcyBUaGVtZSBleHRlbmRzIEJhc2Uge1xuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIG5hbWVcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIHN0cmluZ1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKG5hbWUpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdmFsaWRhdGVTdHJpbmcobmFtZSk7XG4gICAgICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMi4xLjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci9kb20vdGhlbWVcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgICAqL1xuICAgIGdldE5hbWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm5hbWU7XG4gICAgfVxufVxuXG4vKipcbiAqIFRoZSB0aGVtaW5nIHVzZWQgaW4gdGhlIGRvY3VtZW50IGNhbiBiZSBkZWZpbmVkIHZpYSB0aGUgaHRtbC10YWcuXG4gKiBUaGUgdGhlbWluZyBpcyBzcGVjaWZpZWQgdmlhIHRoZSBhdHRyaWJ1dGUgYGRhdGEtbW9uc3Rlci10aGVtZS1uYW1lYC5cbiAqXG4gKiBBcyBuYW1lIGZvciBhIHRoZW1lIGFsbCBjaGFyYWN0ZXJzIGFyZSB2YWxpZCwgd2hpY2ggYXJlIGFsc28gYWxsb3dlZCBmb3IgYSBIVE1MRWxlbWVudC1JRC5cbiAqXG4gKiBgYGBcbiAqIDxodG1sIGRhdGEtbW9uc3Rlci10aGVtZS1uYW1lPVwibXktdGhlbWVcIj5cbiAqIGBgYFxuICpcbiAqIHRoZSBkZWZhdWx0IHRoZW1lIG5hbWUgaXMgYG1vbnN0ZXJgLlxuICpcbiAqIEByZXR1cm4ge1RoZW1lfVxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjcuMFxuICovXG5mdW5jdGlvbiBnZXREb2N1bWVudFRoZW1lKCkge1xuICAgIGxldCBkb2N1bWVudCA9IGdldEdsb2JhbE9iamVjdChcImRvY3VtZW50XCIpO1xuICAgIGxldCBuYW1lID0gREVGQVVMVF9USEVNRTtcblxuICAgIGxldCBlbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcImh0bWxcIik7XG4gICAgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICBsZXQgdGhlbWUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZShBVFRSSUJVVEVfVEhFTUVfTkFNRSk7XG4gICAgICAgIGlmICh0aGVtZSkge1xuICAgICAgICAgICAgbmFtZSA9IHRoZW1lO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBUaGVtZShuYW1lKTtcbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IEJhc2UgfSBmcm9tIFwiLi4vdHlwZXMvYmFzZS5tanNcIjtcbmltcG9ydCB7IGdldEdsb2JhbEZ1bmN0aW9uLCBnZXRHbG9iYWxPYmplY3QgfSBmcm9tIFwiLi4vdHlwZXMvZ2xvYmFsLm1qc1wiO1xuaW1wb3J0IHsgdmFsaWRhdGVJbnN0YW5jZSwgdmFsaWRhdGVTdHJpbmcgfSBmcm9tIFwiLi4vdHlwZXMvdmFsaWRhdGUubWpzXCI7XG5pbXBvcnQgeyBBVFRSSUJVVEVfVEVNUExBVEVfUFJFRklYIH0gZnJvbSBcIi4vY29uc3RhbnRzLm1qc1wiO1xuaW1wb3J0IHsgZ2V0RG9jdW1lbnRUaGVtZSB9IGZyb20gXCIuL3RoZW1lLm1qc1wiO1xuaW1wb3J0IHsgaW5zdGFuY2VTeW1ib2wgfSBmcm9tIFwiLi4vY29uc3RhbnRzLm1qc1wiO1xuZXhwb3J0IHsgVGVtcGxhdGUgfTtcblxuLyoqXG4gKiBUaGUgdGVtcGxhdGUgY2xhc3MgcHJvdmlkZXMgbWV0aG9kcyBmb3IgY3JlYXRpbmcgdGVtcGxhdGVzLlxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuNi4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAc3VtbWFyeSBBIHRlbXBsYXRlIGNsYXNzXG4gKi9cbmNsYXNzIFRlbXBsYXRlIGV4dGVuZHMgQmFzZSB7XG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0hUTUxUZW1wbGF0ZUVsZW1lbnR9IHRlbXBsYXRlXG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYW4gaW5zdGFuY2Ugb2ZcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIGZ1bmN0aW9uXG4gICAgICogQHRocm93cyB7RXJyb3J9IHRoZSBmdW5jdGlvbiBpcyBub3QgZGVmaW5lZFxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRlbXBsYXRlKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIGNvbnN0IEhUTUxUZW1wbGF0ZUVsZW1lbnQgPSBnZXRHbG9iYWxGdW5jdGlvbihcIkhUTUxUZW1wbGF0ZUVsZW1lbnRcIik7XG4gICAgICAgIHZhbGlkYXRlSW5zdGFuY2UodGVtcGxhdGUsIEhUTUxUZW1wbGF0ZUVsZW1lbnQpO1xuICAgICAgICB0aGlzLnRlbXBsYXRlID0gdGVtcGxhdGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMi4xLjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci9kb20vcmVzb3VyY2UvdGVtcGxhdGVcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7SFRNTFRlbXBsYXRlRWxlbWVudH1cbiAgICAgKi9cbiAgICBnZXRUZW1wbGF0ZUVsZW1lbnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRlbXBsYXRlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHJldHVybiB7RG9jdW1lbnRGcmFnbWVudH1cbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhbiBpbnN0YW5jZSBvZlxuICAgICAqL1xuICAgIGNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRlbXBsYXRlLmNvbnRlbnQuY2xvbmVOb2RlKHRydWUpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBUaGlzIG1ldGhvZCBsb2FkcyBhIHRlbXBsYXRlIHdpdGggdGhlIGdpdmVuIElEIGFuZCByZXR1cm5zIGl0LlxuICpcbiAqIFRvIGRvIHRoaXMsIGl0IGZpcnN0IHJlYWRzIHRoZSB0aGVtZSBvZiB0aGUgZG9jdW1lbnQgYW5kIGxvb2tzIGZvciB0aGUgYGRhdGEtbW9uc3Rlci10aGVtZS1uYW1lYCBhdHRyaWJ1dGUgaW4gdGhlIEhUTUwgdGFnLlxuICpcbiAqIGBgYFxuICogPGh0bWwgZGF0YS1tb25zdGVyLXRoZW1lLW5hbWU9XCJteS10aGVtZVwiPlxuICogYGBgXG4gKlxuICogSWYgbm8gdGhlbWUgd2FzIHNwZWNpZmllZCwgdGhlIGRlZmF1bHQgdGhlbWUgaXMgYG1vbnN0ZXJgLlxuICpcbiAqIE5vdyBpdCBpcyBsb29rZWQgaWYgdGhlcmUgaXMgYSB0ZW1wbGF0ZSB3aXRoIHRoZSBnaXZlbiBJRCBhbmQgdGhlbWUgYGlkLXRoZW1lYCBhbmQgaWYgeWVzIGl0IGlzIHJldHVybmVkLlxuICogSWYgdGhlcmUgaXMgbm8gdGVtcGxhdGUgYSBzZWFyY2ggZm9yIGEgdGVtcGxhdGUgd2l0aCB0aGUgZ2l2ZW4gSUQgYGlkYCBpcyBkb25lLiBJZiB0aGlzIGlzIGFsc28gbm90IGZvdW5kLCBhbiBlcnJvciBpcyB0aHJvd24uXG4gKlxuICogWW91IGNhbiBjYWxsIHRoZSBtZXRob2QgdmlhIHRoZSBtb25zdGVyIG5hbWVzcGFjZSBgTW9uc3Rlci5ET00uZmluZERvY3VtZW50VGVtcGxhdGUoKWAuXG4gKlxuICogYGBgXG4gKiA8c2NyaXB0IHR5cGU9XCJtb2R1bGVcIj5cbiAqIGltcG9ydCB7ZmluZFRlbXBsYXRlfSBmcm9tICdAc2NodWthaS9tb25zdGVyL3NvdXJjZS9kb20vdGVtcGxhdGUubWpzJztcbiAqIGZpbmREb2N1bWVudFRlbXBsYXRlKClcbiAqIDwvc2NyaXB0PlxuICogYGBgXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiBpbXBvcnQgeyBmaW5kRG9jdW1lbnRUZW1wbGF0ZSB9IGZyb20gXCJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL0BzY2h1a2FpL21vbnN0ZXJAbGF0ZXN0L3NvdXJjZS9kb20vdGVtcGxhdGUubWpzXCI7XG4gKlxuICogY29uc3QgdGVtcGxhdGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwidGVtcGxhdGVcIik7XG4gKiB0ZW1wbGF0ZS5pZCA9IFwibXlUZW1wbGF0ZVwiO1xuICogdGVtcGxhdGUuaW5uZXJIVE1MID0gXCI8cD5teSBkZWZhdWx0IHRlbXBsYXRlPC9wPlwiO1xuICogZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCh0ZW1wbGF0ZSk7XG4gKlxuICogY29uc3QgdGhlbWVkVGVtcGxhdGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwidGVtcGxhdGVcIik7XG4gKiB0aGVtZWRUZW1wbGF0ZS5pZCA9IFwibXlUZW1wbGF0ZS1teVRoZW1lXCI7XG4gKiB0aGVtZWRUZW1wbGF0ZS5pbm5lckhUTUwgPSBcIjxwPm15IHRoZW1lZCB0ZW1wbGF0ZTwvcD5cIjtcbiAqIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodGhlbWVkVGVtcGxhdGUpO1xuICpcbiAqIC8vIGxvYWRzIHRoZSB0ZW1wbGUgYW5kIHNpbmNlIG5vIHRoZW1lIGlzIHNldCB0aGUgZGVmYXVsdCB0ZW1wbGF0ZVxuICogY29uc3QgdGVtcGxhdGUxID0gZmluZERvY3VtZW50VGVtcGxhdGUoXCJteVRlbXBsYXRlXCIpO1xuICogY29uc29sZS5sb2codGVtcGxhdGUxLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKSk7XG4gKiAvLyBcdTIxQTYgJzxwPm15IGRlZmF1bHQgdGVtcGxhdGU8L3A+J1xuICpcbiAqIC8vIG5vdyB3ZSBzZXQgb3VyIG93biB0aGVtZVxuICogZG9jdW1lbnRcbiAqIC5xdWVyeVNlbGVjdG9yKFwiaHRtbFwiKVxuICogLnNldEF0dHJpYnV0ZShcImRhdGEtbW9uc3Rlci10aGVtZS1uYW1lXCIsIFwibXlUaGVtZVwiKTtcbiAqXG4gKiAvLyBub3cgd2UgZG9uJ3QgZ2V0IHRoZSBkZWZhdWx0IHRlbXBsYXRlLFxuICogLy8gYnV0IHRoZSB0ZW1wbGF0ZSB3aXRoIHRoZSB0aGVtZSBpbiB0aGUgaWRcbiAqIGNvbnN0IHRlbXBsYXRlMiA9IGZpbmREb2N1bWVudFRlbXBsYXRlKFwibXlUZW1wbGF0ZVwiKTtcbiAqIGNvbnNvbGUubG9nKHRlbXBsYXRlMi5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCkpO1xuICogLy8gXHUyMUE2ICc8cD5teSB0aGVtZWQgdGVtcGxhdGU8L3A+J1xuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBpZFxuICogQHBhcmFtIHtOb2RlfSBjdXJyZW50Tm9kZVxuICogQHJldHVybiB7TW9uc3Rlci5ET00uVGVtcGxhdGV9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjcuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHRocm93cyB7RXJyb3J9IHRlbXBsYXRlIGlkIG5vdCBmb3VuZC5cbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgc3RyaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaW5kRG9jdW1lbnRUZW1wbGF0ZShpZCwgY3VycmVudE5vZGUpIHtcbiAgICB2YWxpZGF0ZVN0cmluZyhpZCk7XG5cbiAgICBjb25zdCBkb2N1bWVudCA9IGdldEdsb2JhbE9iamVjdChcImRvY3VtZW50XCIpO1xuICAgIGNvbnN0IEhUTUxUZW1wbGF0ZUVsZW1lbnQgPSBnZXRHbG9iYWxGdW5jdGlvbihcIkhUTUxUZW1wbGF0ZUVsZW1lbnRcIik7XG4gICAgY29uc3QgRG9jdW1lbnRGcmFnbWVudCA9IGdldEdsb2JhbEZ1bmN0aW9uKFwiRG9jdW1lbnRGcmFnbWVudFwiKTtcbiAgICBjb25zdCBEb2N1bWVudCA9IGdldEdsb2JhbEZ1bmN0aW9uKFwiRG9jdW1lbnRcIik7XG5cbiAgICBsZXQgcHJlZml4SUQ7XG5cbiAgICBpZiAoIShjdXJyZW50Tm9kZSBpbnN0YW5jZW9mIERvY3VtZW50IHx8IGN1cnJlbnROb2RlIGluc3RhbmNlb2YgRG9jdW1lbnRGcmFnbWVudCkpIHtcbiAgICAgICAgaWYgKGN1cnJlbnROb2RlIGluc3RhbmNlb2YgTm9kZSkge1xuICAgICAgICAgICAgaWYgKGN1cnJlbnROb2RlLmhhc0F0dHJpYnV0ZShBVFRSSUJVVEVfVEVNUExBVEVfUFJFRklYKSkge1xuICAgICAgICAgICAgICAgIHByZWZpeElEID0gY3VycmVudE5vZGUuZ2V0QXR0cmlidXRlKEFUVFJJQlVURV9URU1QTEFURV9QUkVGSVgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjdXJyZW50Tm9kZSA9IGN1cnJlbnROb2RlLmdldFJvb3ROb2RlKCk7XG5cbiAgICAgICAgICAgIGlmICghKGN1cnJlbnROb2RlIGluc3RhbmNlb2YgRG9jdW1lbnQgfHwgY3VycmVudE5vZGUgaW5zdGFuY2VvZiBEb2N1bWVudEZyYWdtZW50KSkge1xuICAgICAgICAgICAgICAgIGN1cnJlbnROb2RlID0gY3VycmVudE5vZGUub3duZXJEb2N1bWVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghKGN1cnJlbnROb2RlIGluc3RhbmNlb2YgRG9jdW1lbnQgfHwgY3VycmVudE5vZGUgaW5zdGFuY2VvZiBEb2N1bWVudEZyYWdtZW50KSkge1xuICAgICAgICAgICAgY3VycmVudE5vZGUgPSBkb2N1bWVudDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGxldCB0ZW1wbGF0ZTtcbiAgICBsZXQgdGhlbWUgPSBnZXREb2N1bWVudFRoZW1lKCk7XG5cbiAgICBpZiAocHJlZml4SUQpIHtcbiAgICAgICAgbGV0IHRoZW1lZFByZWZpeElEID0gYCR7cHJlZml4SUR9LSR7aWR9LSR7dGhlbWUuZ2V0TmFtZSgpfWA7XG5cbiAgICAgICAgLy8gY3VycmVudCArIHRoZW1lZFByZWZpeElEXG4gICAgICAgIHRlbXBsYXRlID0gY3VycmVudE5vZGUuZ2V0RWxlbWVudEJ5SWQodGhlbWVkUHJlZml4SUQpO1xuICAgICAgICBpZiAodGVtcGxhdGUgaW5zdGFuY2VvZiBIVE1MVGVtcGxhdGVFbGVtZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFRlbXBsYXRlKHRlbXBsYXRlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGRvY3VtZW50ICsgdGhlbWVkUHJlZml4SURcbiAgICAgICAgdGVtcGxhdGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGVtZWRQcmVmaXhJRCk7XG4gICAgICAgIGlmICh0ZW1wbGF0ZSBpbnN0YW5jZW9mIEhUTUxUZW1wbGF0ZUVsZW1lbnQpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgVGVtcGxhdGUodGVtcGxhdGUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbGV0IHRoZW1lZElEID0gYCR7aWR9LSR7dGhlbWUuZ2V0TmFtZSgpfWA7XG5cbiAgICAvLyBjdXJyZW50ICsgdGhlbWVkSURcbiAgICB0ZW1wbGF0ZSA9IGN1cnJlbnROb2RlLmdldEVsZW1lbnRCeUlkKHRoZW1lZElEKTtcbiAgICBpZiAodGVtcGxhdGUgaW5zdGFuY2VvZiBIVE1MVGVtcGxhdGVFbGVtZW50KSB7XG4gICAgICAgIHJldHVybiBuZXcgVGVtcGxhdGUodGVtcGxhdGUpO1xuICAgIH1cblxuICAgIC8vIGRvY3VtZW50ICsgdGhlbWVkSURcbiAgICB0ZW1wbGF0ZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRoZW1lZElEKTtcbiAgICBpZiAodGVtcGxhdGUgaW5zdGFuY2VvZiBIVE1MVGVtcGxhdGVFbGVtZW50KSB7XG4gICAgICAgIHJldHVybiBuZXcgVGVtcGxhdGUodGVtcGxhdGUpO1xuICAgIH1cblxuICAgIC8vIGN1cnJlbnQgKyBJRFxuICAgIHRlbXBsYXRlID0gY3VycmVudE5vZGUuZ2V0RWxlbWVudEJ5SWQoaWQpO1xuICAgIGlmICh0ZW1wbGF0ZSBpbnN0YW5jZW9mIEhUTUxUZW1wbGF0ZUVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUZW1wbGF0ZSh0ZW1wbGF0ZSk7XG4gICAgfVxuXG4gICAgLy8gZG9jdW1lbnQgKyBJRFxuICAgIHRlbXBsYXRlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpO1xuICAgIGlmICh0ZW1wbGF0ZSBpbnN0YW5jZW9mIEhUTUxUZW1wbGF0ZUVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUZW1wbGF0ZSh0ZW1wbGF0ZSk7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IEVycm9yKGB0ZW1wbGF0ZSAke2lkfSBub3QgZm91bmQuYCk7XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBpc0FycmF5LCBpc09iamVjdCB9IGZyb20gXCIuLi90eXBlcy9pcy5tanNcIjtcbmltcG9ydCB7IHR5cGVPZiB9IGZyb20gXCIuLi90eXBlcy90eXBlb2YubWpzXCI7XG5cbmV4cG9ydCB7IGRpZmYgfTtcblxuLyoqXG4gKiBXaXRoIHRoZSBkaWZmIGZ1bmN0aW9uIHlvdSBjYW4gcGVyZm9ybSB0aGUgY2hhbmdlIG9mIG9uZSBvYmplY3QgdG8gYW5vdGhlci4gVGhlIHJlc3VsdCBzaG93cyB0aGUgY2hhbmdlcyBvZiB0aGUgc2Vjb25kIG9iamVjdCB0byB0aGUgZmlyc3Qgb2JqZWN0LlxuICpcbiAqIFRoZSBvcGVyYXRvciBgYWRkYCBtZWFucyB0aGF0IHNvbWV0aGluZyBoYXMgYmVlbiBhZGRlZCB0byB0aGUgc2Vjb25kIG9iamVjdC4gYGRlbGV0ZWAgbWVhbnMgdGhhdCBzb21ldGhpbmcgaGFzIGJlZW4gZGVsZXRlZCBmcm9tIHRoZSBzZWNvbmQgb2JqZWN0IGNvbXBhcmVkIHRvIHRoZSBmaXJzdCBvYmplY3QuXG4gKlxuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL2RhdGEvZGlmZi5tanNcbiAqIEBwYXJhbSB7Kn0gZmlyc3RcbiAqIEBwYXJhbSB7Kn0gc2Vjb25kXG4gKiBAcmV0dXJuIHthcnJheX1cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuNi4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRGF0YVxuICovXG5mdW5jdGlvbiBkaWZmKGZpcnN0LCBzZWNvbmQpIHtcbiAgICByZXR1cm4gZG9EaWZmKGZpcnN0LCBzZWNvbmQpO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0gYVxuICogQHBhcmFtIGJcbiAqIEBwYXJhbSB0eXBlXG4gKiBAcmV0dXJuIHtTZXQ8c3RyaW5nPnxTZXQ8bnVtYmVyPn1cbiAqL1xuZnVuY3Rpb24gZ2V0S2V5cyhhLCBiLCB0eXBlKSB7XG4gICAgaWYgKGlzQXJyYXkodHlwZSkpIHtcbiAgICAgICAgY29uc3Qga2V5cyA9IGEubGVuZ3RoID4gYi5sZW5ndGggPyBuZXcgQXJyYXkoYS5sZW5ndGgpIDogbmV3IEFycmF5KGIubGVuZ3RoKTtcbiAgICAgICAga2V5cy5maWxsKDApO1xuICAgICAgICByZXR1cm4gbmV3IFNldChrZXlzLm1hcCgoXywgaSkgPT4gaSkpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgU2V0KE9iamVjdC5rZXlzKGEpLmNvbmNhdChPYmplY3Qua2V5cyhiKSkpO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0gYVxuICogQHBhcmFtIGJcbiAqIEBwYXJhbSBwYXRoXG4gKiBAcGFyYW0gZGlmZlxuICogQHJldHVybiB7YXJyYXl9XG4gKi9cbmZ1bmN0aW9uIGRvRGlmZihhLCBiLCBwYXRoLCBkaWZmKSB7XG4gICAgbGV0IHR5cGVBID0gdHlwZU9mKGEpO1xuICAgIGxldCB0eXBlQiA9IHR5cGVPZihiKTtcblxuICAgIGNvbnN0IGN1cnJQYXRoID0gcGF0aCB8fCBbXTtcbiAgICBjb25zdCBjdXJyRGlmZiA9IGRpZmYgfHwgW107XG5cbiAgICBpZiAodHlwZUEgPT09IHR5cGVCICYmICh0eXBlQSA9PT0gXCJvYmplY3RcIiB8fCB0eXBlQSA9PT0gXCJhcnJheVwiKSkge1xuICAgICAgICBnZXRLZXlzKGEsIGIsIHR5cGVBKS5mb3JFYWNoKCh2KSA9PiB7XG4gICAgICAgICAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChhLCB2KSkge1xuICAgICAgICAgICAgICAgIGN1cnJEaWZmLnB1c2goYnVpbGRSZXN1bHQoYVt2XSwgYlt2XSwgXCJhZGRcIiwgY3VyclBhdGguY29uY2F0KHYpKSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgdikpIHtcbiAgICAgICAgICAgICAgICBjdXJyRGlmZi5wdXNoKGJ1aWxkUmVzdWx0KGFbdl0sIGJbdl0sIFwiZGVsZXRlXCIsIGN1cnJQYXRoLmNvbmNhdCh2KSkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBkb0RpZmYoYVt2XSwgYlt2XSwgY3VyclBhdGguY29uY2F0KHYpLCBjdXJyRGlmZik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IG8gPSBnZXRPcGVyYXRvcihhLCBiLCB0eXBlQSwgdHlwZUIpO1xuICAgICAgICBpZiAobyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBjdXJyRGlmZi5wdXNoKGJ1aWxkUmVzdWx0KGEsIGIsIG8sIHBhdGgpKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBjdXJyRGlmZjtcbn1cblxuLyoqXG4gKlxuICogQHBhcmFtIHsqfSBhXG4gKiBAcGFyYW0geyp9IGJcbiAqIEBwYXJhbSB7c3RyaW5nfSBvcGVyYXRvclxuICogQHBhcmFtIHthcnJheX0gcGF0aFxuICogQHJldHVybiB7e3BhdGg6IGFycmF5LCBvcGVyYXRvcjogc3RyaW5nfX1cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGJ1aWxkUmVzdWx0KGEsIGIsIG9wZXJhdG9yLCBwYXRoKSB7XG4gICAgY29uc3QgcmVzdWx0ID0ge1xuICAgICAgICBvcGVyYXRvcixcbiAgICAgICAgcGF0aCxcbiAgICB9O1xuXG4gICAgaWYgKG9wZXJhdG9yICE9PSBcImFkZFwiKSB7XG4gICAgICAgIHJlc3VsdC5maXJzdCA9IHtcbiAgICAgICAgICAgIHZhbHVlOiBhLFxuICAgICAgICAgICAgdHlwZTogdHlwZW9mIGEsXG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKGlzT2JqZWN0KGEpKSB7XG4gICAgICAgICAgICBjb25zdCBuYW1lID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKGEpPy5jb25zdHJ1Y3Rvcj8ubmFtZTtcbiAgICAgICAgICAgIGlmIChuYW1lICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQuZmlyc3QuaW5zdGFuY2UgPSBuYW1lO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG9wZXJhdG9yID09PSBcImFkZFwiIHx8IG9wZXJhdG9yID09PSBcInVwZGF0ZVwiKSB7XG4gICAgICAgIHJlc3VsdC5zZWNvbmQgPSB7XG4gICAgICAgICAgICB2YWx1ZTogYixcbiAgICAgICAgICAgIHR5cGU6IHR5cGVvZiBiLFxuICAgICAgICB9O1xuXG4gICAgICAgIGlmIChpc09iamVjdChiKSkge1xuICAgICAgICAgICAgY29uc3QgbmFtZSA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihiKT8uY29uc3RydWN0b3I/Lm5hbWU7XG4gICAgICAgICAgICBpZiAobmFtZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0LnNlY29uZC5pbnN0YW5jZSA9IG5hbWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IGFcbiAqIEBwYXJhbSB7Kn0gYlxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gaXNOb3RFcXVhbChhLCBiKSB7XG4gICAgaWYgKHR5cGVvZiBhICE9PSB0eXBlb2YgYikge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAoYSBpbnN0YW5jZW9mIERhdGUgJiYgYiBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgICAgcmV0dXJuIGEuZ2V0VGltZSgpICE9PSBiLmdldFRpbWUoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYSAhPT0gYjtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSBhXG4gKiBAcGFyYW0geyp9IGJcbiAqIEByZXR1cm4ge3N0cmluZ3x1bmRlZmluZWR9XG4gKi9cbmZ1bmN0aW9uIGdldE9wZXJhdG9yKGEsIGIpIHtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7c3RyaW5nfHVuZGVmaW5lZH1cbiAgICAgKi9cbiAgICBsZXQgb3BlcmF0b3I7XG5cbiAgICAvKipcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGxldCB0eXBlQSA9IHR5cGVvZiBhO1xuXG4gICAgLyoqXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBsZXQgdHlwZUIgPSB0eXBlb2YgYjtcblxuICAgIGlmICh0eXBlQSA9PT0gXCJ1bmRlZmluZWRcIiAmJiB0eXBlQiAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICBvcGVyYXRvciA9IFwiYWRkXCI7XG4gICAgfSBlbHNlIGlmICh0eXBlQSAhPT0gXCJ1bmRlZmluZWRcIiAmJiB0eXBlQiA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICBvcGVyYXRvciA9IFwiZGVsZXRlXCI7XG4gICAgfSBlbHNlIGlmIChpc05vdEVxdWFsKGEsIGIpKSB7XG4gICAgICAgIG9wZXJhdG9yID0gXCJ1cGRhdGVcIjtcbiAgICB9XG5cbiAgICByZXR1cm4gb3BlcmF0b3I7XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBpc0FycmF5LCBpc09iamVjdCB9IGZyb20gXCIuLi90eXBlcy9pcy5tanNcIjtcbmltcG9ydCB7IHZhbGlkYXRlSW5zdGFuY2UsIHZhbGlkYXRlU3RyaW5nIH0gZnJvbSBcIi4uL3R5cGVzL3ZhbGlkYXRlLm1qc1wiO1xuaW1wb3J0IHsgZ2V0RG9jdW1lbnQgfSBmcm9tIFwiLi91dGlsLm1qc1wiO1xuXG5leHBvcnQgeyBmaXJlRXZlbnQsIGZpcmVDdXN0b21FdmVudCwgZmluZFRhcmdldEVsZW1lbnRGcm9tRXZlbnQgfTtcblxuLyoqXG4gKiBUaGUgZnVuY3Rpb24gc2VuZHMgYW4gZXZlbnRcbiAqXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fEhUTUxDb2xsZWN0aW9ufE5vZGVMaXN0fSBlbGVtZW50XG4gKiBAcGFyYW0ge3N0cmluZ30gdHlwZVxuICogQHJldHVybiB7dm9pZH1cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMTAuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgSFRNTEVsZW1lbnQgb3IgSFRNTENvbGxlY3Rpb25cbiAqIEBzdW1tYXJ5IENvbnN0cnVjdCBhbmQgc2VuZCBhbmQgZXZlbnRcbiAqL1xuZnVuY3Rpb24gZmlyZUV2ZW50KGVsZW1lbnQsIHR5cGUpIHtcbiAgICBjb25zdCBkb2N1bWVudCA9IGdldERvY3VtZW50KCk7XG5cbiAgICBpZiAoZWxlbWVudCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSB7XG4gICAgICAgIGlmICh0eXBlID09PSBcImNsaWNrXCIpIHtcbiAgICAgICAgICAgIGVsZW1lbnQuY2xpY2soKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FdmVudC9FdmVudFxuICAgICAgICBsZXQgZXZlbnQgPSBuZXcgRXZlbnQodmFsaWRhdGVTdHJpbmcodHlwZSksIHtcbiAgICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgICBjYW5jZWxhYmxlOiB0cnVlLFxuICAgICAgICAgICAgY29tcG9zZWQ6IHRydWUsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGVsZW1lbnQuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgfSBlbHNlIGlmIChlbGVtZW50IGluc3RhbmNlb2YgSFRNTENvbGxlY3Rpb24gfHwgZWxlbWVudCBpbnN0YW5jZW9mIE5vZGVMaXN0KSB7XG4gICAgICAgIGZvciAobGV0IGUgb2YgZWxlbWVudCkge1xuICAgICAgICAgICAgZmlyZUV2ZW50KGUsIHR5cGUpO1xuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInZhbHVlIGlzIG5vdCBhbiBpbnN0YW5jZSBvZiBIVE1MRWxlbWVudCBvciBIVE1MQ29sbGVjdGlvblwiKTtcbiAgICB9XG59XG5cbi8qKlxuICogWW91IGNhbiBjYWxsIHRoZSBmdW5jdGlvbiB2aWEgdGhlIG1vbnN0ZXIgbmFtZXNwYWNlIGBuZXcgTW9uc3Rlci5ET00uZmlyZUN1c3RvbUV2ZW50KClgLlxuICpcbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR8SFRNTENvbGxlY3Rpb258Tm9kZUxpc3R9IGVsZW1lbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlXG4gKiBAcmV0dXJuIHt2b2lkfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yOS4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhbiBpbnN0YW5jZSBvZiBIVE1MRWxlbWVudCBvciBIVE1MQ29sbGVjdGlvblxuICogQHN1bW1hcnkgQ29uc3RydWN0IGFuZCBzZW5kIGFuZCBldmVudFxuICovXG5mdW5jdGlvbiBmaXJlQ3VzdG9tRXZlbnQoZWxlbWVudCwgdHlwZSwgZGV0YWlsKSB7XG4gICAgY29uc3QgZG9jdW1lbnQgPSBnZXREb2N1bWVudCgpO1xuXG4gICAgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICBpZiAoIWlzT2JqZWN0KGRldGFpbCkpIHtcbiAgICAgICAgICAgIGRldGFpbCA9IHsgZGV0YWlsIH07XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgZXZlbnQgPSBuZXcgQ3VzdG9tRXZlbnQodmFsaWRhdGVTdHJpbmcodHlwZSksIHtcbiAgICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgICBjYW5jZWxhYmxlOiB0cnVlLFxuICAgICAgICAgICAgY29tcG9zZWQ6IHRydWUsXG4gICAgICAgICAgICBkZXRhaWwsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGVsZW1lbnQuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgfSBlbHNlIGlmIChlbGVtZW50IGluc3RhbmNlb2YgSFRNTENvbGxlY3Rpb24gfHwgZWxlbWVudCBpbnN0YW5jZW9mIE5vZGVMaXN0KSB7XG4gICAgICAgIGZvciAobGV0IGUgb2YgZWxlbWVudCkge1xuICAgICAgICAgICAgZmlyZUN1c3RvbUV2ZW50KGUsIHR5cGUsIGRldGFpbCk7XG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwidmFsdWUgaXMgbm90IGFuIGluc3RhbmNlIG9mIEhUTUxFbGVtZW50IG9yIEhUTUxDb2xsZWN0aW9uXCIpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGdldHMgdGhlIHBhdGggYEV2ZW50LmNvbXBvc2VkUGF0aCgpYCBmcm9tIGFuIGV2ZW50IGFuZCB0cmllcyB0byBmaW5kIHRoZSBuZXh0IGVsZW1lbnRcbiAqIHVwIHRoZSB0cmVlIGBlbGVtZW50LmNsb3Nlc3QoKWAgd2l0aCB0aGUgYXR0cmlidXRlIGFuZCB2YWx1ZS4gSWYgbm8gdmFsdWUsIG9yIGEgdmFsdWUgdGhhdCBpcyB1bmRlZmluZWQgb3IgbnVsbCxcbiAqIGlzIHNwZWNpZmllZCwgb25seSB0aGUgYXR0cmlidXRlIGlzIHNlYXJjaGVkLlxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMTQuMFxuICogQHBhcmFtIHtFdmVudH0gZXZlbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBhdHRyaWJ1dGVOYW1lXG4gKiBAcGFyYW0ge3N0cmluZ3xudWxsfHVuZGVmaW5lZH0gYXR0cmlidXRlVmFsdWVcbiAqIEB0aHJvd3Mge0Vycm9yfSB1bnN1cHBvcnRlZCBldmVudFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIHN0cmluZ1xuICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgSFRNTEVsZW1lbnRcbiAqIEBzdW1tYXJ5IEhlbHAgZnVuY3Rpb24gdG8gZmluZCB0aGUgYXBwcm9wcmlhdGUgY29udHJvbFxuICovXG5mdW5jdGlvbiBmaW5kVGFyZ2V0RWxlbWVudEZyb21FdmVudChldmVudCwgYXR0cmlidXRlTmFtZSwgYXR0cmlidXRlVmFsdWUpIHtcbiAgICB2YWxpZGF0ZUluc3RhbmNlKGV2ZW50LCBFdmVudCk7XG5cbiAgICBpZiAodHlwZW9mIGV2ZW50LmNvbXBvc2VkUGF0aCAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcInVuc3VwcG9ydGVkIGV2ZW50XCIpO1xuICAgIH1cblxuICAgIGNvbnN0IHBhdGggPSBldmVudC5jb21wb3NlZFBhdGgoKTtcblxuICAgIC8vIGNsb3Nlc3QgY2Fubm90IGJlIHVzZWQgaGVyZSwgYmVjYXVzZSBjbG9zZXN0IGlzIG5vdCBjb3JyZWN0IGZvciBzbG90dGVkIGVsZW1lbnRzXG4gICAgaWYgKGlzQXJyYXkocGF0aCkpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwYXRoLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBvID0gcGF0aFtpXTtcblxuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIG8gaW5zdGFuY2VvZiBIVE1MRWxlbWVudCAmJlxuICAgICAgICAgICAgICAgIG8uaGFzQXR0cmlidXRlKGF0dHJpYnV0ZU5hbWUpICYmXG4gICAgICAgICAgICAgICAgKGF0dHJpYnV0ZVZhbHVlID09PSB1bmRlZmluZWQgfHwgby5nZXRBdHRyaWJ1dGUoYXR0cmlidXRlTmFtZSkgPT09IGF0dHJpYnV0ZVZhbHVlKVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG87XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xufVxuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgaW50ZXJuYWxTeW1ib2wgfSBmcm9tIFwiLi4vY29uc3RhbnRzLm1qc1wiO1xuaW1wb3J0IHsgZGlmZiB9IGZyb20gXCIuLi9kYXRhL2RpZmYubWpzXCI7XG5pbXBvcnQgeyBQYXRoZmluZGVyIH0gZnJvbSBcIi4uL2RhdGEvcGF0aGZpbmRlci5tanNcIjtcbmltcG9ydCB7IFBpcGUgfSBmcm9tIFwiLi4vZGF0YS9waXBlLm1qc1wiO1xuaW1wb3J0IHtcbiAgICBBVFRSSUJVVEVfRVJST1JNRVNTQUdFLFxuICAgIEFUVFJJQlVURV9VUERBVEVSX0FUVFJJQlVURVMsXG4gICAgQVRUUklCVVRFX1VQREFURVJfQklORCxcbiAgICBBVFRSSUJVVEVfVVBEQVRFUl9JTlNFUlQsXG4gICAgQVRUUklCVVRFX1VQREFURVJfSU5TRVJUX1JFRkVSRU5DRSxcbiAgICBBVFRSSUJVVEVfVVBEQVRFUl9SRU1PVkUsXG4gICAgQVRUUklCVVRFX1VQREFURVJfUkVQTEFDRSxcbiAgICBBVFRSSUJVVEVfVVBEQVRFUl9TRUxFQ1RfVEhJUyxcbn0gZnJvbSBcIi4vY29uc3RhbnRzLm1qc1wiO1xuXG5pbXBvcnQgeyBCYXNlIH0gZnJvbSBcIi4uL3R5cGVzL2Jhc2UubWpzXCI7XG5pbXBvcnQgeyBpc0FycmF5LCBpc0luc3RhbmNlLCBpc0l0ZXJhYmxlIH0gZnJvbSBcIi4uL3R5cGVzL2lzLm1qc1wiO1xuaW1wb3J0IHsgT2JzZXJ2ZXIgfSBmcm9tIFwiLi4vdHlwZXMvb2JzZXJ2ZXIubWpzXCI7XG5pbXBvcnQgeyBQcm94eU9ic2VydmVyIH0gZnJvbSBcIi4uL3R5cGVzL3Byb3h5b2JzZXJ2ZXIubWpzXCI7XG5pbXBvcnQgeyB2YWxpZGF0ZUFycmF5LCB2YWxpZGF0ZUluc3RhbmNlIH0gZnJvbSBcIi4uL3R5cGVzL3ZhbGlkYXRlLm1qc1wiO1xuaW1wb3J0IHsgY2xvbmUgfSBmcm9tIFwiLi4vdXRpbC9jbG9uZS5tanNcIjtcbmltcG9ydCB7IHRyaW1TcGFjZXMgfSBmcm9tIFwiLi4vdXRpbC90cmltc3BhY2VzLm1qc1wiO1xuaW1wb3J0IHsgYWRkVG9PYmplY3RMaW5rIH0gZnJvbSBcIi4vYXR0cmlidXRlcy5tanNcIjtcbmltcG9ydCB7IGZpbmRUYXJnZXRFbGVtZW50RnJvbUV2ZW50IH0gZnJvbSBcIi4vZXZlbnRzLm1qc1wiO1xuaW1wb3J0IHsgZmluZERvY3VtZW50VGVtcGxhdGUgfSBmcm9tIFwiLi90ZW1wbGF0ZS5tanNcIjtcblxuZXhwb3J0IHsgVXBkYXRlciwgYWRkT2JqZWN0V2l0aFVwZGF0ZXJUb0VsZW1lbnQgfTtcblxuLyoqXG4gKiBUaGUgdXBkYXRlciBjbGFzcyBjb25uZWN0cyBhbiBvYmplY3Qgd2l0aCB0aGUgZG9tLiBJbiB0aGlzIHdheSwgc3RydWN0dXJlcyBhbmQgY29udGVudHMgaW4gdGhlIERPTSBjYW4gYmUgcHJvZ3JhbW1hdGljYWxseSBhZGFwdGVkIHZpYSBhdHRyaWJ1dGVzLlxuICpcbiAqIEZvciBleGFtcGxlLCB0byBpbmNsdWRlIGEgc3RyaW5nIGZyb20gYW4gb2JqZWN0LCB0aGUgYXR0cmlidXRlIGBkYXRhLW1vbnN0ZXItcmVwbGFjZWAgY2FuIGJlIHVzZWQuXG4gKiBhIGZ1cnRoZXIgZXhwbGFuYXRpb24gY2FuIGJlIGZvdW5kIHVuZGVyIFttb25zdGVyanMub3JnXShodHRwczovL21vbnN0ZXJqcy5vcmcvKVxuICpcbiAqIENoYW5nZXMgdG8gYXR0cmlidXRlcyBhcmUgbWFkZSBvbmx5IHdoZW4gdGhlIGRpcmVjdCB2YWx1ZXMgYXJlIGNoYW5nZWQuIElmIHlvdSB3YW50IHRvIGFzc2lnbiBjaGFuZ2VzIHRvIG90aGVyIHZhbHVlc1xuICogYXMgd2VsbCwgeW91IGhhdmUgdG8gaW5zZXJ0IHRoZSBhdHRyaWJ1dGUgYGRhdGEtbW9uc3Rlci1zZWxlY3QtdGhpc2AuIFRoaXMgc2hvdWxkIGJlIGRvbmUgd2l0aCBjYXJlLCBhcyBpdCBjYW4gcmVkdWNlIHBlcmZvcm1hbmNlLlxuICpcbiAqIEBleHRlcm5hbEV4YW1wbGUgLi4vLi4vZXhhbXBsZS9kb20vdXBkYXRlci5tanNcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuOC4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdGhyb3dzIHtFcnJvcn0gdGhlIHZhbHVlIGlzIG5vdCBpdGVyYWJsZVxuICogQHRocm93cyB7RXJyb3J9IHBpcGVzIGFyZSBub3QgYWxsb3dlZCB3aGVuIGNsb25pbmcgYSBub2RlLlxuICogQHRocm93cyB7RXJyb3J9IG5vIHRlbXBsYXRlIHdhcyBmb3VuZCB3aXRoIHRoZSBzcGVjaWZpZWQga2V5LlxuICogQHRocm93cyB7RXJyb3J9IHRoZSBtYXhpbXVtIGRlcHRoIGZvciB0aGUgcmVjdXJzaW9uIGlzIHJlYWNoZWQuXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIG9iamVjdFxuICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgSFRNTEVsZW1lbnRcbiAqIEBzdW1tYXJ5IFRoZSB1cGRhdGVyIGNsYXNzIGNvbm5lY3RzIGFuIG9iamVjdCB3aXRoIHRoZSBkb21cbiAqL1xuY2xhc3MgVXBkYXRlciBleHRlbmRzIEJhc2Uge1xuICAgIC8qKlxuICAgICAqIEBzaW5jZSAxLjguMFxuICAgICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVsZW1lbnRcbiAgICAgKiBAcGFyYW0ge29iamVjdHxQcm94eU9ic2VydmVyfHVuZGVmaW5lZH0gc3ViamVjdFxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgb2JqZWN0XG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgSFRNTEVsZW1lbnRcbiAgICAgKiBAc2VlIHtAbGluayBNb25zdGVyLkRPTS5maW5kRG9jdW1lbnRUZW1wbGF0ZX1cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihlbGVtZW50LCBzdWJqZWN0KSB7XG4gICAgICAgIHN1cGVyKCk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEB0eXBlIHtIVE1MRWxlbWVudH1cbiAgICAgICAgICovXG4gICAgICAgIGlmIChzdWJqZWN0ID09PSB1bmRlZmluZWQpIHN1YmplY3QgPSB7fTtcbiAgICAgICAgaWYgKCFpc0luc3RhbmNlKHN1YmplY3QsIFByb3h5T2JzZXJ2ZXIpKSB7XG4gICAgICAgICAgICBzdWJqZWN0ID0gbmV3IFByb3h5T2JzZXJ2ZXIoc3ViamVjdCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzW2ludGVybmFsU3ltYm9sXSA9IHtcbiAgICAgICAgICAgIGVsZW1lbnQ6IHZhbGlkYXRlSW5zdGFuY2UoZWxlbWVudCwgSFRNTEVsZW1lbnQpLFxuICAgICAgICAgICAgbGFzdDoge30sXG4gICAgICAgICAgICBjYWxsYmFja3M6IG5ldyBNYXAoKSxcbiAgICAgICAgICAgIGV2ZW50VHlwZXM6IFtcImtleXVwXCIsIFwiY2xpY2tcIiwgXCJjaGFuZ2VcIiwgXCJkcm9wXCIsIFwidG91Y2hlbmRcIiwgXCJpbnB1dFwiXSxcbiAgICAgICAgICAgIHN1YmplY3Q6IHN1YmplY3QsXG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpc1tpbnRlcm5hbFN5bWJvbF0uY2FsbGJhY2tzLnNldChcImNoZWNrc3RhdGVcIiwgZ2V0Q2hlY2tTdGF0ZUNhbGxiYWNrLmNhbGwodGhpcykpO1xuXG4gICAgICAgIHRoaXNbaW50ZXJuYWxTeW1ib2xdLnN1YmplY3QuYXR0YWNoT2JzZXJ2ZXIoXG4gICAgICAgICAgICBuZXcgT2JzZXJ2ZXIoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHMgPSB0aGlzW2ludGVybmFsU3ltYm9sXS5zdWJqZWN0LmdldFJlYWxTdWJqZWN0KCk7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBkaWZmUmVzdWx0ID0gZGlmZih0aGlzW2ludGVybmFsU3ltYm9sXS5sYXN0LCBzKTtcbiAgICAgICAgICAgICAgICB0aGlzW2ludGVybmFsU3ltYm9sXS5sYXN0ID0gY2xvbmUocyk7XG5cbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IFssIGNoYW5nZV0gb2YgT2JqZWN0LmVudHJpZXMoZGlmZlJlc3VsdCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVtb3ZlRWxlbWVudC5jYWxsKHRoaXMsIGNoYW5nZSk7XG4gICAgICAgICAgICAgICAgICAgIGluc2VydEVsZW1lbnQuY2FsbCh0aGlzLCBjaGFuZ2UpO1xuICAgICAgICAgICAgICAgICAgICB1cGRhdGVDb250ZW50LmNhbGwodGhpcywgY2hhbmdlKTtcbiAgICAgICAgICAgICAgICAgICAgdXBkYXRlQXR0cmlidXRlcy5jYWxsKHRoaXMsIGNoYW5nZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGVmYXVsdHM6ICdrZXl1cCcsICdjbGljaycsICdjaGFuZ2UnLCAnZHJvcCcsICd0b3VjaGVuZCdcbiAgICAgKlxuICAgICAqIEBzZWUge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2RlL2RvY3MvV2ViL0V2ZW50c31cbiAgICAgKiBAc2luY2UgMS45LjBcbiAgICAgKiBAcGFyYW0ge0FycmF5fSB0eXBlc1xuICAgICAqIEByZXR1cm4ge1VwZGF0ZXJ9XG4gICAgICovXG4gICAgc2V0RXZlbnRUeXBlcyh0eXBlcykge1xuICAgICAgICB0aGlzW2ludGVybmFsU3ltYm9sXS5ldmVudFR5cGVzID0gdmFsaWRhdGVBcnJheSh0eXBlcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFdpdGggdGhpcyBtZXRob2QsIHRoZSBldmVudGxpc3RlbmVycyBhcmUgaG9va2VkIGluIGFuZCB0aGUgbWFnaWMgYmVnaW5zLlxuICAgICAqXG4gICAgICogYGBgXG4gICAgICogdXBkYXRlci5ydW4oKS50aGVuKCgpID0+IHtcbiAgICAgKiAgIHVwZGF0ZXIuZW5hYmxlRXZlbnRQcm9jZXNzaW5nKCk7XG4gICAgICogfSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBAc2luY2UgMS45LjBcbiAgICAgKiBAcmV0dXJuIHtVcGRhdGVyfVxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSB0aGUgYmluZCBhcmd1bWVudCBtdXN0IHN0YXJ0IGFzIGEgdmFsdWUgd2l0aCBhIHBhdGhcbiAgICAgKi9cbiAgICBlbmFibGVFdmVudFByb2Nlc3NpbmcoKSB7XG4gICAgICAgIHRoaXMuZGlzYWJsZUV2ZW50UHJvY2Vzc2luZygpO1xuXG4gICAgICAgIGZvciAoY29uc3QgdHlwZSBvZiB0aGlzW2ludGVybmFsU3ltYm9sXS5ldmVudFR5cGVzKSB7XG4gICAgICAgICAgICAvLyBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FdmVudFRhcmdldC9hZGRFdmVudExpc3RlbmVyXG4gICAgICAgICAgICB0aGlzW2ludGVybmFsU3ltYm9sXS5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgZ2V0Q29udHJvbEV2ZW50SGFuZGxlci5jYWxsKHRoaXMpLCB7XG4gICAgICAgICAgICAgICAgY2FwdHVyZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBwYXNzaXZlOiB0cnVlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCB0dXJucyBvZmYgdGhlIG1hZ2ljIG9yIHdobyBsb3ZlcyBpdCBtb3JlIHByb2ZhbmUgaXQgcmVtb3ZlcyB0aGUgZXZlbnRMaXN0ZW5lci5cbiAgICAgKlxuICAgICAqIEBzaW5jZSAxLjkuMFxuICAgICAqIEByZXR1cm4ge1VwZGF0ZXJ9XG4gICAgICovXG4gICAgZGlzYWJsZUV2ZW50UHJvY2Vzc2luZygpIHtcbiAgICAgICAgZm9yIChjb25zdCB0eXBlIG9mIHRoaXNbaW50ZXJuYWxTeW1ib2xdLmV2ZW50VHlwZXMpIHtcbiAgICAgICAgICAgIHRoaXNbaW50ZXJuYWxTeW1ib2xdLmVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcih0eXBlLCBnZXRDb250cm9sRXZlbnRIYW5kbGVyLmNhbGwodGhpcykpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIHJ1biBtZXRob2QgbXVzdCBiZSBjYWxsZWQgZm9yIHRoZSB1cGRhdGUgdG8gc3RhcnQgd29ya2luZy5cbiAgICAgKiBUaGUgbWV0aG9kIGVuc3VyZXMgdGhhdCBjaGFuZ2VzIGFyZSBkZXRlY3RlZC5cbiAgICAgKlxuICAgICAqIGBgYFxuICAgICAqIHVwZGF0ZXIucnVuKCkudGhlbigoKSA9PiB7XG4gICAgICogICB1cGRhdGVyLmVuYWJsZUV2ZW50UHJvY2Vzc2luZygpO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQHN1bW1hcnkgTGV0IHRoZSBtYWdpYyBiZWdpblxuICAgICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAgICovXG4gICAgcnVuKCkge1xuICAgICAgICAvLyB0aGUga2V5IF9faW5pdF9faGFzIG5vIGZ1cnRoZXIgbWVhbmluZyBhbmQgaXMgb25seVxuICAgICAgICAvLyB1c2VkIHRvIGNyZWF0ZSB0aGUgZGlmZiBmb3IgZW1wdHkgb2JqZWN0cy5cbiAgICAgICAgdGhpc1tpbnRlcm5hbFN5bWJvbF0ubGFzdCA9IHsgX19pbml0X186IHRydWUgfTtcbiAgICAgICAgcmV0dXJuIHRoaXNbaW50ZXJuYWxTeW1ib2xdLnN1YmplY3Qubm90aWZ5T2JzZXJ2ZXJzKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgdmFsdWVzIG9mIGJvdW5kIGVsZW1lbnRzIGFuZCBjaGFuZ2VzIHRoZW0gaW4gc3ViamVjdFxuICAgICAqXG4gICAgICogQHNpbmNlIDEuMjcuMFxuICAgICAqIEByZXR1cm4ge01vbnN0ZXIuRE9NLlVwZGF0ZXJ9XG4gICAgICovXG4gICAgcmV0cmlldmUoKSB7XG4gICAgICAgIHJldHJpZXZlRnJvbUJpbmRpbmdzLmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIElmIHlvdSBoYXZlIHBhc3NlZCBhIFByb3h5T2JzZXJ2ZXIgaW4gdGhlIGNvbnN0cnVjdG9yLCB5b3Ugd2lsbCBnZXQgdGhlIG9iamVjdCB0aGF0IHRoZSBQcm94eU9ic2VydmVyIG1hbmFnZXMgaGVyZS5cbiAgICAgKiBIb3dldmVyLCBpZiB5b3UgcGFzc2VkIGEgc2ltcGxlIG9iamVjdCwgaGVyZSB5b3Ugd2lsbCBnZXQgYSBwcm94eSBmb3IgdGhhdCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBGb3IgY2hhbmdlcyB0aGUgUHJveHlPYnNlcnZlciBtdXN0IGJlIHVzZWQuXG4gICAgICpcbiAgICAgKiBAc2luY2UgMS44LjBcbiAgICAgKiBAcmV0dXJuIHtQcm94eX1cbiAgICAgKi9cbiAgICBnZXRTdWJqZWN0KCkge1xuICAgICAgICByZXR1cm4gdGhpc1tpbnRlcm5hbFN5bWJvbF0uc3ViamVjdC5nZXRTdWJqZWN0KCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgY2FuIGJlIHVzZWQgdG8gcmVnaXN0ZXIgY29tbWFuZHMgdGhhdCBjYW4gYmUgY2FsbGVkIHZpYSBjYWxsOiBpbnN0cnVjdGlvbi5cbiAgICAgKiBUaGlzIGNhbiBiZSB1c2VkIHRvIHByb3ZpZGUgYSBwaXBlIHdpdGggaXRzIG93biBmdW5jdGlvbmFsaXR5LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBjYWxsYmFja1xuICAgICAqIEByZXR1cm5zIHtUcmFuc2Zvcm1lcn1cbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIHN0cmluZ1xuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgZnVuY3Rpb25cbiAgICAgKi9cbiAgICBzZXRDYWxsYmFjayhuYW1lLCBjYWxsYmFjaykge1xuICAgICAgICB0aGlzW2ludGVybmFsU3ltYm9sXS5jYWxsYmFja3Muc2V0KG5hbWUsIGNhbGxiYWNrKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjkuMFxuICogQHJldHVybiB7ZnVuY3Rpb25cbiAqIEB0aGlzIFVwZGF0ZXJcbiAqL1xuZnVuY3Rpb24gZ2V0Q2hlY2tTdGF0ZUNhbGxiYWNrKCkge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChjdXJyZW50KSB7XG4gICAgICAgIC8vIHRoaXMgaXMgYSByZWZlcmVuY2UgdG8gdGhlIGN1cnJlbnQgb2JqZWN0ICh0aGVyZWZvcmUgbm8gYXJyYXkgZnVuY3Rpb24gaGVyZSlcbiAgICAgICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBIVE1MSW5wdXRFbGVtZW50KSB7XG4gICAgICAgICAgICBpZiAoW1wicmFkaW9cIiwgXCJjaGVja2JveFwiXS5pbmRleE9mKHRoaXMudHlwZSkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGAke3RoaXMudmFsdWV9YCA9PT0gYCR7Y3VycmVudH1gID8gXCJ0cnVlXCIgOiB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcyBpbnN0YW5jZW9mIEhUTUxPcHRpb25FbGVtZW50KSB7XG4gICAgICAgICAgICBpZiAoaXNBcnJheShjdXJyZW50KSAmJiBjdXJyZW50LmluZGV4T2YodGhpcy52YWx1ZSkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwidHJ1ZVwiO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgfTtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5jb25zdCBzeW1ib2wgPSBTeW1ib2woXCJAc2NodWthaS9tb25zdGVyL3VwZGF0ZXJAQEV2ZW50SGFuZGxlclwiKTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHJldHVybiB7ZnVuY3Rpb259XG4gKiBAdGhpcyBVcGRhdGVyXG4gKiBAdGhyb3dzIHtFcnJvcn0gdGhlIGJpbmQgYXJndW1lbnQgbXVzdCBzdGFydCBhcyBhIHZhbHVlIHdpdGggYSBwYXRoXG4gKi9cbmZ1bmN0aW9uIGdldENvbnRyb2xFdmVudEhhbmRsZXIoKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICBpZiAoc2VsZltzeW1ib2xdKSB7XG4gICAgICAgIHJldHVybiBzZWxmW3N5bWJvbF07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHRocm93cyB7RXJyb3J9IHRoZSBiaW5kIGFyZ3VtZW50IG11c3Qgc3RhcnQgYXMgYSB2YWx1ZSB3aXRoIGEgcGF0aC5cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gdW5zdXBwb3J0ZWQgb2JqZWN0XG4gICAgICogQHBhcmFtIHtFdmVudH0gZXZlbnRcbiAgICAgKi9cbiAgICBzZWxmW3N5bWJvbF0gPSAoZXZlbnQpID0+IHtcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IGZpbmRUYXJnZXRFbGVtZW50RnJvbUV2ZW50KGV2ZW50LCBBVFRSSUJVVEVfVVBEQVRFUl9CSU5EKTtcblxuICAgICAgICBpZiAoZWxlbWVudCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICByZXRyaWV2ZUFuZFNldFZhbHVlLmNhbGwoc2VsZiwgZWxlbWVudCk7XG4gICAgfTtcblxuICAgIHJldHVybiBzZWxmW3N5bWJvbF07XG59XG5cbi8qKlxuICogQHRocm93cyB7RXJyb3J9IHRoZSBiaW5kIGFyZ3VtZW50IG11c3Qgc3RhcnQgYXMgYSB2YWx1ZSB3aXRoIGEgcGF0aFxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudFxuICogQHJldHVybiB2b2lkXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHJldHJpZXZlQW5kU2V0VmFsdWUoZWxlbWVudCkge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgY29uc3QgcGF0aGZpbmRlciA9IG5ldyBQYXRoZmluZGVyKHNlbGZbaW50ZXJuYWxTeW1ib2xdLnN1YmplY3QuZ2V0U3ViamVjdCgpKTtcblxuICAgIGxldCBwYXRoID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoQVRUUklCVVRFX1VQREFURVJfQklORCk7XG4gICAgaWYgKHBhdGggPT09IG51bGwpIHRocm93IG5ldyBFcnJvcihcInRoZSBiaW5kIGFyZ3VtZW50IG11c3Qgc3RhcnQgYXMgYSB2YWx1ZSB3aXRoIGEgcGF0aFwiKTtcblxuICAgIGlmIChwYXRoLmluZGV4T2YoXCJwYXRoOlwiKSAhPT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0aGUgYmluZCBhcmd1bWVudCBtdXN0IHN0YXJ0IGFzIGEgdmFsdWUgd2l0aCBhIHBhdGhcIik7XG4gICAgfVxuXG4gICAgcGF0aCA9IHBhdGguc3Vic3RyaW5nKDUpO1xuXG4gICAgbGV0IHZhbHVlO1xuXG4gICAgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MSW5wdXRFbGVtZW50KSB7XG4gICAgICAgIHN3aXRjaCAoZWxlbWVudC50eXBlKSB7XG4gICAgICAgICAgICBjYXNlIFwiY2hlY2tib3hcIjpcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IGVsZW1lbnQuY2hlY2tlZCA/IGVsZW1lbnQudmFsdWUgOiB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHZhbHVlID0gZWxlbWVudC52YWx1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZWxlbWVudCBpbnN0YW5jZW9mIEhUTUxUZXh0QXJlYUVsZW1lbnQpIHtcbiAgICAgICAgdmFsdWUgPSBlbGVtZW50LnZhbHVlO1xuICAgIH0gZWxzZSBpZiAoZWxlbWVudCBpbnN0YW5jZW9mIEhUTUxTZWxlY3RFbGVtZW50KSB7XG4gICAgICAgIHN3aXRjaCAoZWxlbWVudC50eXBlKSB7XG4gICAgICAgICAgICBjYXNlIFwic2VsZWN0LW9uZVwiOlxuICAgICAgICAgICAgICAgIHZhbHVlID0gZWxlbWVudC52YWx1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJzZWxlY3QtbXVsdGlwbGVcIjpcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IGVsZW1lbnQudmFsdWU7XG5cbiAgICAgICAgICAgICAgICBsZXQgb3B0aW9ucyA9IGVsZW1lbnQ/LnNlbGVjdGVkT3B0aW9ucztcbiAgICAgICAgICAgICAgICBpZiAob3B0aW9ucyA9PT0gdW5kZWZpbmVkKSBvcHRpb25zID0gZWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiOnNjb3BlIG9wdGlvbjpjaGVja2VkXCIpO1xuICAgICAgICAgICAgICAgIHZhbHVlID0gQXJyYXkuZnJvbShvcHRpb25zKS5tYXAoKHsgdmFsdWUgfSkgPT4gdmFsdWUpO1xuXG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICAvLyB2YWx1ZXMgZnJvbSBjdXN0b21lbGVtZW50c1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIChlbGVtZW50Py5jb25zdHJ1Y3Rvcj8ucHJvdG90eXBlICYmXG4gICAgICAgICAgICAhIU9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoZWxlbWVudC5jb25zdHJ1Y3Rvci5wcm90b3R5cGUsIFwidmFsdWVcIik/LltcImdldFwiXSkgfHxcbiAgICAgICAgZWxlbWVudC5oYXNPd25Qcm9wZXJ0eShcInZhbHVlXCIpXG4gICAgKSB7XG4gICAgICAgIHZhbHVlID0gZWxlbWVudD8uW1widmFsdWVcIl07XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidW5zdXBwb3J0ZWQgb2JqZWN0XCIpO1xuICAgIH1cblxuICAgIGNvbnN0IGNvcHkgPSBjbG9uZShzZWxmW2ludGVybmFsU3ltYm9sXS5zdWJqZWN0LmdldFJlYWxTdWJqZWN0KCkpO1xuICAgIGNvbnN0IHBmID0gbmV3IFBhdGhmaW5kZXIoY29weSk7XG4gICAgcGYuc2V0VmlhKHBhdGgsIHZhbHVlKTtcblxuICAgIGNvbnN0IGRpZmZSZXN1bHQgPSBkaWZmKGNvcHksIHNlbGZbaW50ZXJuYWxTeW1ib2xdLnN1YmplY3QuZ2V0UmVhbFN1YmplY3QoKSk7XG5cbiAgICBpZiAoZGlmZlJlc3VsdC5sZW5ndGggPiAwKSB7XG4gICAgICAgIHBhdGhmaW5kZXIuc2V0VmlhKHBhdGgsIHZhbHVlKTtcbiAgICB9XG59XG5cbi8qKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNy4wXG4gKiBAcmV0dXJuIHZvaWRcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHJldHJpZXZlRnJvbUJpbmRpbmdzKCkge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgaWYgKHNlbGZbaW50ZXJuYWxTeW1ib2xdLmVsZW1lbnQubWF0Y2hlcyhgWyR7QVRUUklCVVRFX1VQREFURVJfQklORH1dYCkpIHtcbiAgICAgICAgcmV0cmlldmVBbmRTZXRWYWx1ZS5jYWxsKHNlbGYsIHNlbGZbaW50ZXJuYWxTeW1ib2xdLmVsZW1lbnQpO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgWywgZWxlbWVudF0gb2Ygc2VsZltpbnRlcm5hbFN5bWJvbF0uZWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKGBbJHtBVFRSSUJVVEVfVVBEQVRFUl9CSU5EfV1gKS5lbnRyaWVzKCkpIHtcbiAgICAgICAgcmV0cmlldmVBbmRTZXRWYWx1ZS5jYWxsKHNlbGYsIGVsZW1lbnQpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS44LjBcbiAqIEBwYXJhbSB7b2JqZWN0fSBjaGFuZ2VcbiAqIEByZXR1cm4ge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIHJlbW92ZUVsZW1lbnQoY2hhbmdlKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICBmb3IgKGNvbnN0IFssIGVsZW1lbnRdIG9mIHNlbGZbaW50ZXJuYWxTeW1ib2xdLmVsZW1lbnRcbiAgICAgICAgLnF1ZXJ5U2VsZWN0b3JBbGwoYDpzY29wZSBbJHtBVFRSSUJVVEVfVVBEQVRFUl9SRU1PVkV9XWApXG4gICAgICAgIC5lbnRyaWVzKCkpIHtcbiAgICAgICAgZWxlbWVudC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGVsZW1lbnQpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS44LjBcbiAqIEBwYXJhbSB7b2JqZWN0fSBjaGFuZ2VcbiAqIEByZXR1cm4ge3ZvaWR9XG4gKiBAdGhyb3dzIHtFcnJvcn0gdGhlIHZhbHVlIGlzIG5vdCBpdGVyYWJsZVxuICogQHRocm93cyB7RXJyb3J9IHBpcGVzIGFyZSBub3QgYWxsb3dlZCB3aGVuIGNsb25pbmcgYSBub2RlLlxuICogQHRocm93cyB7RXJyb3J9IG5vIHRlbXBsYXRlIHdhcyBmb3VuZCB3aXRoIHRoZSBzcGVjaWZpZWQga2V5LlxuICogQHRocm93cyB7RXJyb3J9IHRoZSBtYXhpbXVtIGRlcHRoIGZvciB0aGUgcmVjdXJzaW9uIGlzIHJlYWNoZWQuXG4gKiBAdGhpcyBVcGRhdGVyXG4gKi9cbmZ1bmN0aW9uIGluc2VydEVsZW1lbnQoY2hhbmdlKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgY29uc3Qgc3ViamVjdCA9IHNlbGZbaW50ZXJuYWxTeW1ib2xdLnN1YmplY3QuZ2V0UmVhbFN1YmplY3QoKTtcblxuICAgIGxldCBtZW0gPSBuZXcgV2Vha1NldCgpO1xuICAgIGxldCB3ZCA9IDA7XG5cbiAgICBjb25zdCBjb250YWluZXIgPSBzZWxmW2ludGVybmFsU3ltYm9sXS5lbGVtZW50O1xuXG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgbGV0IGZvdW5kID0gZmFsc2U7XG4gICAgICAgIHdkKys7XG5cbiAgICAgICAgbGV0IHAgPSBjbG9uZShjaGFuZ2U/LltcInBhdGhcIl0pO1xuICAgICAgICBpZiAoIWlzQXJyYXkocCkpIHJldHVybiBzZWxmO1xuXG4gICAgICAgIHdoaWxlIChwLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnQgPSBwLmpvaW4oXCIuXCIpO1xuXG4gICAgICAgICAgICBsZXQgaXRlcmF0b3IgPSBuZXcgU2V0KCk7XG4gICAgICAgICAgICBjb25zdCBxdWVyeSA9IGBbJHtBVFRSSUJVVEVfVVBEQVRFUl9JTlNFUlR9Kj1cInBhdGg6JHtjdXJyZW50fVwiXWA7XG5cbiAgICAgICAgICAgIGNvbnN0IGUgPSBjb250YWluZXIucXVlcnlTZWxlY3RvckFsbChxdWVyeSk7XG5cbiAgICAgICAgICAgIGlmIChlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBpdGVyYXRvciA9IG5ldyBTZXQoWy4uLmVdKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGNvbnRhaW5lci5tYXRjaGVzKHF1ZXJ5KSkge1xuICAgICAgICAgICAgICAgIGl0ZXJhdG9yLmFkZChjb250YWluZXIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IFssIGNvbnRhaW5lckVsZW1lbnRdIG9mIGl0ZXJhdG9yLmVudHJpZXMoKSkge1xuICAgICAgICAgICAgICAgIGlmIChtZW0uaGFzKGNvbnRhaW5lckVsZW1lbnQpKSBjb250aW51ZTtcbiAgICAgICAgICAgICAgICBtZW0uYWRkKGNvbnRhaW5lckVsZW1lbnQpO1xuXG4gICAgICAgICAgICAgICAgZm91bmQgPSB0cnVlO1xuXG4gICAgICAgICAgICAgICAgY29uc3QgYXR0cmlidXRlcyA9IGNvbnRhaW5lckVsZW1lbnQuZ2V0QXR0cmlidXRlKEFUVFJJQlVURV9VUERBVEVSX0lOU0VSVCk7XG4gICAgICAgICAgICAgICAgaWYgKGF0dHJpYnV0ZXMgPT09IG51bGwpIGNvbnRpbnVlO1xuXG4gICAgICAgICAgICAgICAgbGV0IGRlZiA9IHRyaW1TcGFjZXMoYXR0cmlidXRlcyk7XG4gICAgICAgICAgICAgICAgbGV0IGkgPSBkZWYuaW5kZXhPZihcIiBcIik7XG4gICAgICAgICAgICAgICAgbGV0IGtleSA9IHRyaW1TcGFjZXMoZGVmLnN1YnN0cigwLCBpKSk7XG4gICAgICAgICAgICAgICAgbGV0IHJlZlByZWZpeCA9IGAke2tleX0tYDtcbiAgICAgICAgICAgICAgICBsZXQgY21kID0gdHJpbVNwYWNlcyhkZWYuc3Vic3RyKGkpKTtcblxuICAgICAgICAgICAgICAgIC8vIHRoaXMgY2FzZSBpcyBhY3R1YWxseSBleGNsdWRlZCBieSB0aGUgcXVlcnkgYnV0IGlzIG5ldmVydGhlbGVzcyBjaGVja2VkIGFnYWluIGhlcmVcbiAgICAgICAgICAgICAgICBpZiAoY21kLmluZGV4T2YoXCJ8XCIpID4gMCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJwaXBlcyBhcmUgbm90IGFsbG93ZWQgd2hlbiBjbG9uaW5nIGEgbm9kZS5cIik7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgbGV0IHBpcGUgPSBuZXcgUGlwZShjbWQpO1xuICAgICAgICAgICAgICAgIHNlbGZbaW50ZXJuYWxTeW1ib2xdLmNhbGxiYWNrcy5mb3JFYWNoKChmLCBuKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHBpcGUuc2V0Q2FsbGJhY2sobiwgZik7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICBsZXQgdmFsdWU7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyRWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoQVRUUklCVVRFX0VSUk9STUVTU0FHRSk7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gcGlwZS5ydW4oc3ViamVjdCk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICBjb250YWluZXJFbGVtZW50LnNldEF0dHJpYnV0ZShBVFRSSUJVVEVfRVJST1JNRVNTQUdFLCBlLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGxldCBkYXRhUGF0aCA9IGNtZC5zcGxpdChcIjpcIikucG9wKCk7XG5cbiAgICAgICAgICAgICAgICBsZXQgaW5zZXJ0UG9pbnQ7XG4gICAgICAgICAgICAgICAgaWYgKGNvbnRhaW5lckVsZW1lbnQuaGFzQ2hpbGROb2RlcygpKSB7XG4gICAgICAgICAgICAgICAgICAgIGluc2VydFBvaW50ID0gY29udGFpbmVyRWxlbWVudC5sYXN0Q2hpbGQ7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKCFpc0l0ZXJhYmxlKHZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0aGUgdmFsdWUgaXMgbm90IGl0ZXJhYmxlXCIpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGxldCBhdmFpbGFibGUgPSBuZXcgU2V0KCk7XG5cbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IFtpLCBvYmpdIG9mIE9iamVjdC5lbnRyaWVzKHZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgcmVmID0gcmVmUHJlZml4ICsgaTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGN1cnJlbnRQYXRoID0gYCR7ZGF0YVBhdGh9LiR7aX1gO1xuXG4gICAgICAgICAgICAgICAgICAgIGF2YWlsYWJsZS5hZGQocmVmKTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHJlZkVsZW1lbnQgPSBjb250YWluZXJFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoYFske0FUVFJJQlVURV9VUERBVEVSX0lOU0VSVF9SRUZFUkVOQ0V9PVwiJHtyZWZ9XCJdYCk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlZkVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaW5zZXJ0UG9pbnQgPSByZWZFbGVtZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBhcHBlbmROZXdEb2N1bWVudEZyYWdtZW50KGNvbnRhaW5lckVsZW1lbnQsIGtleSwgcmVmLCBjdXJyZW50UGF0aCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgbGV0IG5vZGVzID0gY29udGFpbmVyRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKFxuICAgICAgICAgICAgICAgICAgICBgWyR7QVRUUklCVVRFX1VQREFURVJfSU5TRVJUX1JFRkVSRU5DRX0qPVwiJHtyZWZQcmVmaXh9XCJdYCxcbiAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBbLCBub2RlXSBvZiBPYmplY3QuZW50cmllcyhub2RlcykpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFhdmFpbGFibGUuaGFzKG5vZGUuZ2V0QXR0cmlidXRlKEFUVFJJQlVURV9VUERBVEVSX0lOU0VSVF9SRUZFUkVOQ0UpKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250YWluZXJFbGVtZW50LnJlbW92ZUNoaWxkKG5vZGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRhaW5lckVsZW1lbnQuc2V0QXR0cmlidXRlKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVFRSSUJVVEVfRVJST1JNRVNTQUdFLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgJHtjb250YWluZXJFbGVtZW50LmdldEF0dHJpYnV0ZShBVFRSSUJVVEVfRVJST1JNRVNTQUdFKX0sICR7ZS5tZXNzYWdlfWAudHJpbSgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHAucG9wKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZm91bmQgPT09IGZhbHNlKSBicmVhaztcbiAgICAgICAgaWYgKHdkKysgPiAyMDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInRoZSBtYXhpbXVtIGRlcHRoIGZvciB0aGUgcmVjdXJzaW9uIGlzIHJlYWNoZWQuXCIpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG4vKipcbiAqXG4gKiBAcHJpdmF0ZVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS44LjBcbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGNvbnRhaW5lclxuICogQHBhcmFtIHtzdHJpbmd9IGtleVxuICogQHBhcmFtIHtzdHJpbmd9IHJlZlxuICogQHBhcmFtIHtzdHJpbmd9IHBhdGhcbiAqIEB0aHJvd3Mge0Vycm9yfSBubyB0ZW1wbGF0ZSB3YXMgZm91bmQgd2l0aCB0aGUgc3BlY2lmaWVkIGtleS5cbiAqL1xuZnVuY3Rpb24gYXBwZW5kTmV3RG9jdW1lbnRGcmFnbWVudChjb250YWluZXIsIGtleSwgcmVmLCBwYXRoKSB7XG4gICAgbGV0IHRlbXBsYXRlID0gZmluZERvY3VtZW50VGVtcGxhdGUoa2V5LCBjb250YWluZXIpO1xuXG4gICAgbGV0IG5vZGVzID0gdGVtcGxhdGUuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpO1xuICAgIGZvciAoY29uc3QgWywgbm9kZV0gb2YgT2JqZWN0LmVudHJpZXMobm9kZXMuY2hpbGROb2RlcykpIHtcbiAgICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICAgICAgYXBwbHlSZWN1cnNpdmUobm9kZSwga2V5LCBwYXRoKTtcbiAgICAgICAgICAgIG5vZGUuc2V0QXR0cmlidXRlKEFUVFJJQlVURV9VUERBVEVSX0lOU0VSVF9SRUZFUkVOQ0UsIHJlZik7XG4gICAgICAgIH1cblxuICAgICAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQobm9kZSk7XG4gICAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjEwLjBcbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IG5vZGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXlcbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoXG4gKiBAcmV0dXJuIHt2b2lkfVxuICovXG5mdW5jdGlvbiBhcHBseVJlY3Vyc2l2ZShub2RlLCBrZXksIHBhdGgpIHtcbiAgICBpZiAobm9kZSBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSB7XG4gICAgICAgIGlmIChub2RlLmhhc0F0dHJpYnV0ZShBVFRSSUJVVEVfVVBEQVRFUl9SRVBMQUNFKSkge1xuICAgICAgICAgICAgbGV0IHZhbHVlID0gbm9kZS5nZXRBdHRyaWJ1dGUoQVRUUklCVVRFX1VQREFURVJfUkVQTEFDRSk7XG4gICAgICAgICAgICBub2RlLnNldEF0dHJpYnV0ZShBVFRSSUJVVEVfVVBEQVRFUl9SRVBMQUNFLCB2YWx1ZS5yZXBsYWNlQWxsKGBwYXRoOiR7a2V5fWAsIGBwYXRoOiR7cGF0aH1gKSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobm9kZS5oYXNBdHRyaWJ1dGUoQVRUUklCVVRFX1VQREFURVJfQVRUUklCVVRFUykpIHtcbiAgICAgICAgICAgIGxldCB2YWx1ZSA9IG5vZGUuZ2V0QXR0cmlidXRlKEFUVFJJQlVURV9VUERBVEVSX0FUVFJJQlVURVMpO1xuICAgICAgICAgICAgbm9kZS5zZXRBdHRyaWJ1dGUoQVRUUklCVVRFX1VQREFURVJfQVRUUklCVVRFUywgdmFsdWUucmVwbGFjZUFsbChgcGF0aDoke2tleX1gLCBgcGF0aDoke3BhdGh9YCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChjb25zdCBbLCBjaGlsZF0gb2YgT2JqZWN0LmVudHJpZXMobm9kZS5jaGlsZE5vZGVzKSkge1xuICAgICAgICAgICAgYXBwbHlSZWN1cnNpdmUoY2hpbGQsIGtleSwgcGF0aCk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuOC4wXG4gKiBAcGFyYW0ge29iamVjdH0gY2hhbmdlXG4gKiBAcmV0dXJuIHt2b2lkfVxuICogQHRoaXMgVXBkYXRlclxuICovXG5mdW5jdGlvbiB1cGRhdGVDb250ZW50KGNoYW5nZSkge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIGNvbnN0IHN1YmplY3QgPSBzZWxmW2ludGVybmFsU3ltYm9sXS5zdWJqZWN0LmdldFJlYWxTdWJqZWN0KCk7XG5cbiAgICBsZXQgcCA9IGNsb25lKGNoYW5nZT8uW1wicGF0aFwiXSk7XG4gICAgcnVuVXBkYXRlQ29udGVudC5jYWxsKHRoaXMsIHRoaXNbaW50ZXJuYWxTeW1ib2xdLmVsZW1lbnQsIHAsIHN1YmplY3QpO1xuXG4gICAgY29uc3Qgc2xvdHMgPSB0aGlzW2ludGVybmFsU3ltYm9sXS5lbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCJzbG90XCIpO1xuICAgIGlmIChzbG90cy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGZvciAoY29uc3QgWywgc2xvdF0gb2YgT2JqZWN0LmVudHJpZXMoc2xvdHMpKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IFssIGVsZW1lbnRdIG9mIE9iamVjdC5lbnRyaWVzKHNsb3QuYXNzaWduZWROb2RlcygpKSkge1xuICAgICAgICAgICAgICAgIHJ1blVwZGF0ZUNvbnRlbnQuY2FsbCh0aGlzLCBlbGVtZW50LCBwLCBzdWJqZWN0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS44LjBcbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGNvbnRhaW5lclxuICogQHBhcmFtIHthcnJheX0gcGFydHNcbiAqIEBwYXJhbSB7b2JqZWN0fSBzdWJqZWN0XG4gKiBAcmV0dXJuIHt2b2lkfVxuICovXG5mdW5jdGlvbiBydW5VcGRhdGVDb250ZW50KGNvbnRhaW5lciwgcGFydHMsIHN1YmplY3QpIHtcbiAgICBpZiAoIWlzQXJyYXkocGFydHMpKSByZXR1cm47XG4gICAgaWYgKCEoY29udGFpbmVyIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKSByZXR1cm47XG4gICAgcGFydHMgPSBjbG9uZShwYXJ0cyk7XG5cbiAgICBsZXQgbWVtID0gbmV3IFdlYWtTZXQoKTtcblxuICAgIHdoaWxlIChwYXJ0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnQgPSBwYXJ0cy5qb2luKFwiLlwiKTtcbiAgICAgICAgcGFydHMucG9wKCk7XG5cbiAgICAgICAgLy8gVW5mb3J0dW5hdGVseSwgc3RhdGljIGRhdGEgaXMgYWx3YXlzIGNoYW5nZWQgYXMgd2VsbCwgc2luY2UgaXQgaXMgbm90IHBvc3NpYmxlIHRvIHJlYWN0IHRvIGNoYW5nZXMgaGVyZS5cbiAgICAgICAgY29uc3QgcXVlcnkgPSBgWyR7QVRUUklCVVRFX1VQREFURVJfUkVQTEFDRX1ePVwicGF0aDoke2N1cnJlbnR9XCJdLCBbJHtBVFRSSUJVVEVfVVBEQVRFUl9SRVBMQUNFfV49XCJzdGF0aWM6XCJdLCBbJHtBVFRSSUJVVEVfVVBEQVRFUl9SRVBMQUNFfV49XCJpMThuOlwiXWA7XG4gICAgICAgIGNvbnN0IGUgPSBjb250YWluZXIucXVlcnlTZWxlY3RvckFsbChgJHtxdWVyeX1gKTtcblxuICAgICAgICBjb25zdCBpdGVyYXRvciA9IG5ldyBTZXQoWy4uLmVdKTtcblxuICAgICAgICBpZiAoY29udGFpbmVyLm1hdGNoZXMocXVlcnkpKSB7XG4gICAgICAgICAgICBpdGVyYXRvci5hZGQoY29udGFpbmVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAdHlwZSB7SFRNTEVsZW1lbnR9XG4gICAgICAgICAqL1xuICAgICAgICBmb3IgKGNvbnN0IFtlbGVtZW50XSBvZiBpdGVyYXRvci5lbnRyaWVzKCkpIHtcbiAgICAgICAgICAgIGlmIChtZW0uaGFzKGVsZW1lbnQpKSByZXR1cm47XG4gICAgICAgICAgICBtZW0uYWRkKGVsZW1lbnQpO1xuXG4gICAgICAgICAgICBjb25zdCBhdHRyaWJ1dGVzID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoQVRUUklCVVRFX1VQREFURVJfUkVQTEFDRSk7XG4gICAgICAgICAgICBsZXQgY21kID0gdHJpbVNwYWNlcyhhdHRyaWJ1dGVzKTtcblxuICAgICAgICAgICAgbGV0IHBpcGUgPSBuZXcgUGlwZShjbWQpO1xuICAgICAgICAgICAgdGhpc1tpbnRlcm5hbFN5bWJvbF0uY2FsbGJhY2tzLmZvckVhY2goKGYsIG4pID0+IHtcbiAgICAgICAgICAgICAgICBwaXBlLnNldENhbGxiYWNrKG4sIGYpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGxldCB2YWx1ZTtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoQVRUUklCVVRFX0VSUk9STUVTU0FHRSk7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBwaXBlLnJ1bihzdWJqZWN0KTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShBVFRSSUJVVEVfRVJST1JNRVNTQUdFLCBlLm1lc3NhZ2UpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICAgICAgICAgIHdoaWxlIChlbGVtZW50LmZpcnN0Q2hpbGQpIHtcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5yZW1vdmVDaGlsZChlbGVtZW50LmZpcnN0Q2hpbGQpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuYXBwZW5kQ2hpbGQodmFsdWUpO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoXG4gICAgICAgICAgICAgICAgICAgICAgICBBVFRSSUJVVEVfRVJST1JNRVNTQUdFLFxuICAgICAgICAgICAgICAgICAgICAgICAgYCR7ZWxlbWVudC5nZXRBdHRyaWJ1dGUoQVRUUklCVVRFX0VSUk9STUVTU0FHRSl9LCAke2UubWVzc2FnZX1gLnRyaW0oKSxcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGVsZW1lbnQuaW5uZXJIVE1MID0gdmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuOC4wXG4gKiBAcGFyYW0ge3N0cmluZ30gcGF0aFxuICogQHBhcmFtIHtvYmplY3R9IGNoYW5nZVxuICogQHJldHVybiB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gdXBkYXRlQXR0cmlidXRlcyhjaGFuZ2UpIHtcbiAgICBjb25zdCBzdWJqZWN0ID0gdGhpc1tpbnRlcm5hbFN5bWJvbF0uc3ViamVjdC5nZXRSZWFsU3ViamVjdCgpO1xuICAgIGxldCBwID0gY2xvbmUoY2hhbmdlPy5bXCJwYXRoXCJdKTtcbiAgICBydW5VcGRhdGVBdHRyaWJ1dGVzLmNhbGwodGhpcywgdGhpc1tpbnRlcm5hbFN5bWJvbF0uZWxlbWVudCwgcCwgc3ViamVjdCk7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGNvbnRhaW5lclxuICogQHBhcmFtIHthcnJheX0gcGFydHNcbiAqIEBwYXJhbSB7b2JqZWN0fSBzdWJqZWN0XG4gKiBAcmV0dXJuIHt2b2lkfVxuICogQHRoaXMgVXBkYXRlclxuICovXG5mdW5jdGlvbiBydW5VcGRhdGVBdHRyaWJ1dGVzKGNvbnRhaW5lciwgcGFydHMsIHN1YmplY3QpIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgIGlmICghaXNBcnJheShwYXJ0cykpIHJldHVybjtcbiAgICBwYXJ0cyA9IGNsb25lKHBhcnRzKTtcblxuICAgIGxldCBtZW0gPSBuZXcgV2Vha1NldCgpO1xuXG4gICAgd2hpbGUgKHBhcnRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc3QgY3VycmVudCA9IHBhcnRzLmpvaW4oXCIuXCIpO1xuICAgICAgICBwYXJ0cy5wb3AoKTtcblxuICAgICAgICBsZXQgaXRlcmF0b3IgPSBuZXcgU2V0KCk7XG5cbiAgICAgICAgY29uc3QgcXVlcnkgPSBgWyR7QVRUUklCVVRFX1VQREFURVJfU0VMRUNUX1RISVN9XVske0FUVFJJQlVURV9VUERBVEVSX0FUVFJJQlVURVN9XSwgWyR7QVRUUklCVVRFX1VQREFURVJfQVRUUklCVVRFU30qPVwicGF0aDoke2N1cnJlbnR9XCJdLCBbJHtBVFRSSUJVVEVfVVBEQVRFUl9BVFRSSUJVVEVTfV49XCJzdGF0aWM6XCJdLCBbJHtBVFRSSUJVVEVfVVBEQVRFUl9BVFRSSUJVVEVTfV49XCJpMThuOlwiXWA7XG5cbiAgICAgICAgY29uc3QgZSA9IGNvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKHF1ZXJ5KTtcblxuICAgICAgICBpZiAoZS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBpdGVyYXRvciA9IG5ldyBTZXQoWy4uLmVdKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjb250YWluZXIubWF0Y2hlcyhxdWVyeSkpIHtcbiAgICAgICAgICAgIGl0ZXJhdG9yLmFkZChjb250YWluZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChjb25zdCBbZWxlbWVudF0gb2YgaXRlcmF0b3IuZW50cmllcygpKSB7XG4gICAgICAgICAgICBpZiAobWVtLmhhcyhlbGVtZW50KSkgcmV0dXJuO1xuICAgICAgICAgICAgbWVtLmFkZChlbGVtZW50KTtcblxuICAgICAgICAgICAgLy8gdGhpcyBjYXNlIG9jY3VycyB3aGVuIHRoZSBBVFRSSUJVVEVfVVBEQVRFUl9TRUxFQ1RfVEhJUyBhdHRyaWJ1dGUgaXMgc2V0XG4gICAgICAgICAgICBpZiAoIWVsZW1lbnQuaGFzQXR0cmlidXRlKEFUVFJJQlVURV9VUERBVEVSX0FUVFJJQlVURVMpKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGF0dHJpYnV0ZXMgPSBlbGVtZW50LmdldEF0dHJpYnV0ZShBVFRSSUJVVEVfVVBEQVRFUl9BVFRSSUJVVEVTKTtcblxuICAgICAgICAgICAgZm9yIChsZXQgWywgZGVmXSBvZiBPYmplY3QuZW50cmllcyhhdHRyaWJ1dGVzLnNwbGl0KFwiLFwiKSkpIHtcbiAgICAgICAgICAgICAgICBkZWYgPSB0cmltU3BhY2VzKGRlZik7XG4gICAgICAgICAgICAgICAgbGV0IGkgPSBkZWYuaW5kZXhPZihcIiBcIik7XG4gICAgICAgICAgICAgICAgbGV0IG5hbWUgPSB0cmltU3BhY2VzKGRlZi5zdWJzdHIoMCwgaSkpO1xuICAgICAgICAgICAgICAgIGxldCBjbWQgPSB0cmltU3BhY2VzKGRlZi5zdWJzdHIoaSkpO1xuXG4gICAgICAgICAgICAgICAgbGV0IHBpcGUgPSBuZXcgUGlwZShjbWQpO1xuXG4gICAgICAgICAgICAgICAgc2VsZltpbnRlcm5hbFN5bWJvbF0uY2FsbGJhY2tzLmZvckVhY2goKGYsIG4pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcGlwZS5zZXRDYWxsYmFjayhuLCBmLCBlbGVtZW50KTtcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIGxldCB2YWx1ZTtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnJlbW92ZUF0dHJpYnV0ZShBVFRSSUJVVEVfRVJST1JNRVNTQUdFKTtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBwaXBlLnJ1bihzdWJqZWN0KTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKEFUVFJJQlVURV9FUlJPUk1FU1NBR0UsIGUubWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUobmFtZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChlbGVtZW50LmdldEF0dHJpYnV0ZShuYW1lKSAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUobmFtZSwgdmFsdWUpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGhhbmRsZUlucHV0Q29udHJvbEF0dHJpYnV0ZVVwZGF0ZS5jYWxsKHRoaXMsIGVsZW1lbnQsIG5hbWUsIHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtIVE1MRWxlbWVudHwqfSBlbGVtZW50XG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfHVuZGVmaW5lZH0gdmFsdWVcbiAqIEByZXR1cm4ge3ZvaWR9XG4gKiBAdGhpcyBVcGRhdGVyXG4gKi9cblxuZnVuY3Rpb24gaGFuZGxlSW5wdXRDb250cm9sQXR0cmlidXRlVXBkYXRlKGVsZW1lbnQsIG5hbWUsIHZhbHVlKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICBpZiAoZWxlbWVudCBpbnN0YW5jZW9mIEhUTUxTZWxlY3RFbGVtZW50KSB7XG4gICAgICAgIHN3aXRjaCAoZWxlbWVudC50eXBlKSB7XG4gICAgICAgICAgICBjYXNlIFwic2VsZWN0LW11bHRpcGxlXCI6XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBbaW5kZXgsIG9wdF0gb2YgT2JqZWN0LmVudHJpZXMoZWxlbWVudC5vcHRpb25zKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUuaW5kZXhPZihvcHQudmFsdWUpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgb3B0LnNlbGVjdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdC5zZWxlY3RlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwic2VsZWN0LW9uZVwiOlxuICAgICAgICAgICAgICAgIC8vIE9ubHkgb25lIHZhbHVlIG1heSBiZSBzZWxlY3RlZFxuXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBbaW5kZXgsIG9wdF0gb2YgT2JqZWN0LmVudHJpZXMoZWxlbWVudC5vcHRpb25zKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAob3B0LnZhbHVlID09PSB2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5zZWxlY3RlZEluZGV4ID0gaW5kZXg7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfSBlbHNlIGlmIChlbGVtZW50IGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCkge1xuICAgICAgICBzd2l0Y2ggKGVsZW1lbnQudHlwZSkge1xuICAgICAgICAgICAgY2FzZSBcInJhZGlvXCI6XG4gICAgICAgICAgICAgICAgaWYgKG5hbWUgPT09IFwiY2hlY2tlZFwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50LmNoZWNrZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5jaGVja2VkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY2FzZSBcImNoZWNrYm94XCI6XG4gICAgICAgICAgICAgICAgaWYgKG5hbWUgPT09IFwiY2hlY2tlZFwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50LmNoZWNrZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5jaGVja2VkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJ0ZXh0XCI6XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGlmIChuYW1lID09PSBcInZhbHVlXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC52YWx1ZSA9IHZhbHVlID09PSB1bmRlZmluZWQgPyBcIlwiIDogdmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MVGV4dEFyZWFFbGVtZW50KSB7XG4gICAgICAgIGlmIChuYW1lID09PSBcInZhbHVlXCIpIHtcbiAgICAgICAgICAgIGVsZW1lbnQudmFsdWUgPSB2YWx1ZSA9PT0gdW5kZWZpbmVkID8gXCJcIiA6IHZhbHVlO1xuICAgICAgICB9XG4gICAgfVxufVxuXG4vKipcbiAqIEBwYXJhbSB7Tm9kZUxpc3R8SFRNTEVsZW1lbnR8U2V0PEhUTUxFbGVtZW50Pn0gZWxlbWVudHNcbiAqIEBwYXJhbSB7U3ltYm9sfSBzeW1ib2xcbiAqIEBwYXJhbSB7b2JqZWN0fSBvYmplY3RcbiAqIEByZXR1cm4ge1Byb21pc2VbXX1cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjMuMFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IGVsZW1lbnRzIGlzIG5vdCBhbiBpbnN0YW5jZSBvZiBOb2RlTGlzdCwgSFRNTEVsZW1lbnQgb3IgU2V0XG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHRoZSBjb250ZXh0IG9mIHRoZSBmdW5jdGlvbiBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgSFRNTEVsZW1lbnRcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gc3ltYm9sIG11c3QgYmUgYW4gaW5zdGFuY2Ugb2YgU3ltYm9sXG4gKi9cbmZ1bmN0aW9uIGFkZE9iamVjdFdpdGhVcGRhdGVyVG9FbGVtZW50KGVsZW1lbnRzLCBzeW1ib2wsIG9iamVjdCkge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIGlmICghKHNlbGYgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInRoZSBjb250ZXh0IG9mIHRoaXMgZnVuY3Rpb24gbXVzdCBiZSBhbiBpbnN0YW5jZSBvZiBIVE1MRWxlbWVudFwiKTtcbiAgICB9XG5cbiAgICBpZiAoISh0eXBlb2Ygc3ltYm9sID09PSBcInN5bWJvbFwiKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwic3ltYm9sIG11c3QgYmUgYW4gaW5zdGFuY2Ugb2YgU3ltYm9sXCIpO1xuICAgIH1cblxuICAgIGNvbnN0IHVwZGF0ZXJzID0gbmV3IFNldCgpO1xuXG4gICAgaWYgKGVsZW1lbnRzIGluc3RhbmNlb2YgTm9kZUxpc3QpIHtcbiAgICAgICAgZWxlbWVudHMgPSBuZXcgU2V0KFsuLi5lbGVtZW50c10pO1xuICAgIH0gZWxzZSBpZiAoZWxlbWVudHMgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICBlbGVtZW50cyA9IG5ldyBTZXQoW2VsZW1lbnRzXSk7XG4gICAgfSBlbHNlIGlmIChlbGVtZW50cyBpbnN0YW5jZW9mIFNldCkge1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYGVsZW1lbnRzIGlzIG5vdCBhIHZhbGlkIHR5cGUuIChhY3R1YWw6ICR7dHlwZW9mIGVsZW1lbnRzfSlgKTtcbiAgICB9XG5cbiAgICBsZXQgcmVzdWx0ID0gW107XG5cbiAgICBlbGVtZW50cy5mb3JFYWNoKChlbGVtZW50KSA9PiB7XG4gICAgICAgIGlmICghKGVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpIHJldHVybjtcbiAgICAgICAgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MVGVtcGxhdGVFbGVtZW50KSByZXR1cm47XG5cbiAgICAgICAgY29uc3QgdSA9IG5ldyBVcGRhdGVyKGVsZW1lbnQsIG9iamVjdCk7XG4gICAgICAgIHVwZGF0ZXJzLmFkZCh1KTtcblxuICAgICAgICByZXN1bHQucHVzaChcbiAgICAgICAgICAgIHUucnVuKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHUuZW5hYmxlRXZlbnRQcm9jZXNzaW5nKCk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICB9KTtcblxuICAgIGlmICh1cGRhdGVycy5zaXplID4gMCkge1xuICAgICAgICBhZGRUb09iamVjdExpbmsoc2VsZiwgc3ltYm9sLCB1cGRhdGVycyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbiIsICJpbXBvcnQgeyBpc1N0cmluZyB9IGZyb20gXCIuLi90eXBlcy9pcy5tanNcIjtcbmltcG9ydCB7IHZhbGlkYXRlU3RyaW5nIH0gZnJvbSBcIi4uL3R5cGVzL3ZhbGlkYXRlLm1qc1wiO1xuXG5leHBvcnQgeyBnZXRTbG90dGVkRWxlbWVudHMsIGdldFNsb3R0ZWROb2RlcyB9O1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge1N0cmluZ3x1bmRlZmluZWR9IHF1ZXJ5XG4gKiBAcGFyYW0ge1N0cmluZ3x1bmRlZmluZWR8bnVsbH0gbmFtZSBuYW1lIG9mIHRoZSBzbG90IChpZiB0aGUgcGFyYW1ldGVyIGlzIHVuZGVmaW5lZCwgYWxsIHNsb3RzIGFyZSBzZWFyY2hlZCwgaWYgdGhlIHBhcmFtZXRlciBoYXMgdGhlIHZhbHVlIG51bGwsIGFsbCBzbG90cyB3aXRob3V0IGEgbmFtZSBhcmUgc2VhcmNoZWQuIGlmIGEgc3RyaW5nIGlzIHNwZWNpZmllZCwgdGhlIHNsb3RzIHdpdGggdGhpcyBuYW1lIGFyZSBzZWFyY2hlZC4pXG4gKiBAcmV0dXJuIHsqfVxuICogQHRoaXMgQ3VzdG9tRWxlbWVudFxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMy4zMy4wXG4gKiBAdGhyb3dzIHtFcnJvcn0gcXVlcnkgbXVzdCBiZSBhIHN0cmluZ1xuICovXG5mdW5jdGlvbiBnZXRTbG90dGVkTm9kZXMocXVlcnksIG5hbWUpIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICBjb25zdCByZXN1bHQgPSBuZXcgU2V0KCk7XG5cbiAgICBpZiAoIXNlbGYuc2hhZG93Um9vdCkge1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIGxldCBzZWxlY3RvciA9IFwic2xvdFwiO1xuICAgIGlmIChuYW1lICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKG5hbWUgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHNlbGVjdG9yICs9IFwiOm5vdChbbmFtZV0pXCI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzZWxlY3RvciArPSBgW25hbWU9JHt2YWxpZGF0ZVN0cmluZyhuYW1lKX1dYDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHNsb3RzID0gc2VsZi5zaGFkb3dSb290LnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpO1xuXG4gICAgZm9yIChjb25zdCBbLCBzbG90XSBvZiBPYmplY3QuZW50cmllcyhzbG90cykpIHtcbiAgICAgICAgc2xvdC5hc3NpZ25lZE5vZGVzKCkuZm9yRWFjaChmdW5jdGlvbiAobm9kZSkge1xuICAgICAgICAgICAgaWYgKG5vZGUgPT09IG51bGwgfHwgbm9kZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoaXNTdHJpbmcocXVlcnkpKSB7XG4gICAgICAgICAgICAgICAgbm9kZS5xdWVyeVNlbGVjdG9yQWxsKHF1ZXJ5KS5mb3JFYWNoKGZ1bmN0aW9uIChuKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hZGQobik7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICBpZiAobm9kZS5tYXRjaGVzKHF1ZXJ5KSkge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQuYWRkKG5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAocXVlcnkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInF1ZXJ5IG11c3QgYmUgYSBzdHJpbmdcIik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlc3VsdC5hZGQobm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7U3RyaW5nfHVuZGVmaW5lZH0gcXVlcnlcbiAqIEBwYXJhbSB7U3RyaW5nfHVuZGVmaW5lZHxudWxsfSBuYW1lIG5hbWUgb2YgdGhlIHNsb3QgKGlmIHRoZSBwYXJhbWV0ZXIgaXMgdW5kZWZpbmVkLCBhbGwgc2xvdHMgYXJlIHNlYXJjaGVkLCBpZiB0aGUgcGFyYW1ldGVyIGhhcyB0aGUgdmFsdWUgbnVsbCwgYWxsIHNsb3RzIHdpdGhvdXQgYSBuYW1lIGFyZSBzZWFyY2hlZC4gaWYgYSBzdHJpbmcgaXMgc3BlY2lmaWVkLCB0aGUgc2xvdHMgd2l0aCB0aGlzIG5hbWUgYXJlIHNlYXJjaGVkLilcbiAqIEByZXR1cm4geyp9XG4gKiBAdGhpcyBDdXN0b21FbGVtZW50XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjIzLjBcbiAqIEB0aHJvd3Mge0Vycm9yfSBxdWVyeSBtdXN0IGJlIGEgc3RyaW5nXG4gKi9cbmZ1bmN0aW9uIGdldFNsb3R0ZWRFbGVtZW50cyhxdWVyeSwgbmFtZSkge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIGNvbnN0IHJlc3VsdCA9IG5ldyBTZXQoKTtcblxuICAgIGlmICghKHNlbGYuc2hhZG93Um9vdCBpbnN0YW5jZW9mIFNoYWRvd1Jvb3QpKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgbGV0IHNlbGVjdG9yID0gXCJzbG90XCI7XG4gICAgaWYgKG5hbWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAobmFtZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgc2VsZWN0b3IgKz0gXCI6bm90KFtuYW1lXSlcIjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNlbGVjdG9yICs9IGBbbmFtZT0ke3ZhbGlkYXRlU3RyaW5nKG5hbWUpfV1gO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY29uc3Qgc2xvdHMgPSBzZWxmLnNoYWRvd1Jvb3QucXVlcnlTZWxlY3RvckFsbChzZWxlY3Rvcik7XG5cbiAgICBmb3IgKGNvbnN0IFssIHNsb3RdIG9mIE9iamVjdC5lbnRyaWVzKHNsb3RzKSkge1xuICAgICAgICBzbG90LmFzc2lnbmVkRWxlbWVudHMoKS5mb3JFYWNoKGZ1bmN0aW9uIChub2RlKSB7XG4gICAgICAgICAgICBpZiAoIShub2RlIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKSByZXR1cm47XG5cbiAgICAgICAgICAgIGlmIChpc1N0cmluZyhxdWVyeSkpIHtcbiAgICAgICAgICAgICAgICBub2RlLnF1ZXJ5U2VsZWN0b3JBbGwocXVlcnkpLmZvckVhY2goZnVuY3Rpb24gKG4pIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmFkZChuKTtcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIGlmIChub2RlLm1hdGNoZXMocXVlcnkpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hZGQobm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChxdWVyeSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwicXVlcnkgbXVzdCBiZSBhIHN0cmluZ1wiKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0LmFkZChub2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmV4cG9ydCB7IGV4dHJhY3RLZXlzIH07XG5cbi8qKlxuICogRXh0cmFjdHMgdGhlIGtleXMgZnJvbSB0aGUgZ2l2ZW4gb2JqZWN0IGFuZCByZXR1cm5zIGEgbWFwIHdpdGggdGhlIGtleXMgYW5kIHZhbHVlcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtvYmplY3R9IG9ialxuICogQHBhcmFtIHtzdHJpbmd9IGtleVByZWZpeFxuICogQHBhcmFtIHtzdHJpbmd9IGtleVNlcGFyYXRvclxuICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlU2VwYXJhdG9yXG4gKiBAcmV0dXJucyB7TWFwPGFueSwgYW55Pn1cbiAqL1xuZnVuY3Rpb24gZXh0cmFjdEtleXMob2JqLCBrZXlQcmVmaXggPSBcIlwiLCBrZXlTZXBhcmF0b3IgPSBcIi1cIiwgdmFsdWVTZXBhcmF0b3IgPSBcIi5cIikge1xuICAgIGNvbnN0IHJlc3VsdE1hcCA9IG5ldyBNYXAoKTtcblxuICAgIGZ1bmN0aW9uIGhlbHBlcihjdXJyZW50T2JqLCBjdXJyZW50S2V5UHJlZml4LCBjdXJyZW50VmFsdWVQcmVmaXgpIHtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gY3VycmVudE9iaikge1xuICAgICAgICAgICAgaWYgKGN1cnJlbnRPYmpba2V5XSAhPT0gbnVsbCAmJiB0eXBlb2YgY3VycmVudE9ialtrZXldID09PSBcIm9iamVjdFwiICYmICFBcnJheS5pc0FycmF5KGN1cnJlbnRPYmpba2V5XSkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBuZXdLZXlQcmVmaXggPSBjdXJyZW50S2V5UHJlZml4XG4gICAgICAgICAgICAgICAgICAgID8gY3VycmVudEtleVByZWZpeCArIGtleVNlcGFyYXRvciArIGtleS50b0xvd2VyQ2FzZSgpXG4gICAgICAgICAgICAgICAgICAgIDoga2V5LnRvTG93ZXJDYXNlKCk7XG4gICAgICAgICAgICAgICAgY29uc3QgbmV3VmFsdWVQcmVmaXggPSBjdXJyZW50VmFsdWVQcmVmaXggPyBjdXJyZW50VmFsdWVQcmVmaXggKyB2YWx1ZVNlcGFyYXRvciArIGtleSA6IGtleTtcbiAgICAgICAgICAgICAgICBoZWxwZXIoY3VycmVudE9ialtrZXldLCBuZXdLZXlQcmVmaXgsIG5ld1ZhbHVlUHJlZml4KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZmluYWxLZXkgPSBjdXJyZW50S2V5UHJlZml4XG4gICAgICAgICAgICAgICAgICAgID8gY3VycmVudEtleVByZWZpeCArIGtleVNlcGFyYXRvciArIGtleS50b0xvd2VyQ2FzZSgpXG4gICAgICAgICAgICAgICAgICAgIDoga2V5LnRvTG93ZXJDYXNlKCk7XG4gICAgICAgICAgICAgICAgY29uc3QgZmluYWxWYWx1ZSA9IGN1cnJlbnRWYWx1ZVByZWZpeCA/IGN1cnJlbnRWYWx1ZVByZWZpeCArIHZhbHVlU2VwYXJhdG9yICsga2V5IDoga2V5O1xuICAgICAgICAgICAgICAgIHJlc3VsdE1hcC5zZXQoZmluYWxLZXksIGZpbmFsVmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgaGVscGVyKG9iaiwga2V5UHJlZml4LCBrZXlQcmVmaXgpO1xuICAgIHJldHVybiByZXN1bHRNYXA7XG59XG5cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IFBhdGhmaW5kZXIgfSBmcm9tIFwiLi4vLi4vZGF0YS9wYXRoZmluZGVyLm1qc1wiO1xuaW1wb3J0IHsgaXNGdW5jdGlvbiB9IGZyb20gXCIuLi8uLi90eXBlcy9pcy5tanNcIjtcbmltcG9ydCB7IGF0dHJpYnV0ZU9ic2VydmVyU3ltYm9sIH0gZnJvbSBcIi4uL2N1c3RvbWVsZW1lbnQubWpzXCI7XG5pbXBvcnQgeyBleHRyYWN0S2V5cyB9IGZyb20gXCIuL2V4dHJhY3Qta2V5cy5tanNcIjtcblxuZXhwb3J0IHsgc2V0T3B0aW9uRnJvbUF0dHJpYnV0ZSB9O1xuXG4vKipcbiAqIFNldCB0aGUgZ2l2ZW4gb3B0aW9ucyBvYmplY3QgYmFzZWQgb24gdGhlIGF0dHJpYnV0ZXMgb2YgdGhlIGN1cnJlbnQgRE9NIGVsZW1lbnQuXG4gKiBUaGUgZnVuY3Rpb24gbG9va3MgZm9yIGF0dHJpYnV0ZXMgd2l0aCB0aGUgcHJlZml4ICdkYXRhLW1vbnN0ZXItb3B0aW9uLScsIGFuZCBtYXBzIHRoZW0gdG9cbiAqIHByb3BlcnRpZXMgaW4gdGhlIG9wdGlvbnMgb2JqZWN0LiBJdCByZXBsYWNlcyB0aGUgZGFzaGVzIHdpdGggZG90cyB0byBmb3JtIHRoZSBwcm9wZXJ0eSBwYXRoLlxuICogRm9yIGV4YW1wbGUsIHRoZSBhdHRyaWJ1dGUgJ2RhdGEtbW9uc3Rlci1vcHRpb24tdXJsJyBtYXBzIHRvIHRoZSAndXJsJyBwcm9wZXJ0eSBpbiB0aGUgb3B0aW9ucyBvYmplY3QuXG4gKlxuICogV2l0aCB0aGUgbWFwcGluZyBwYXJhbWV0ZXIsIHRoZSBhdHRyaWJ1dGUgdmFsdWUgY2FuIGJlIG1hcHBlZCB0byBhIGRpZmZlcmVudCB2YWx1ZS5cbiAqIEZvciBleGFtcGxlLCB0aGUgYXR0cmlidXRlICdkYXRhLW1vbnN0ZXItb3B0aW9uLWZvbycgbWFwcyB0byB0aGUgJ2JhcicgcHJvcGVydHkgaW4gdGhlIG9wdGlvbnMgb2JqZWN0LlxuICpcbiAqIFRoZSBtYXBwaW5nIG9iamVjdCB3b3VsZCBsb29rIGxpa2UgdGhpczpcbiAqIHtcbiAqICAgICdmb28nOiAodmFsdWUpID0+IHZhbHVlICsgJ2JhcidcbiAqICAgIC8vIHRoZSB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlICdkYXRhLW1vbnN0ZXItb3B0aW9uLWZvbycgaXMgYXBwZW5kZWQgd2l0aCAnYmFyJ1xuICogICAgLy8gYW5kIGFzc2lnbmVkIHRvIHRoZSAnYmFyJyBwcm9wZXJ0eSBpbiB0aGUgb3B0aW9ucyBvYmplY3QuXG4gKiAgICAvLyBlLmcuIDxkaXYgZGF0YS1tb25zdGVyLW9wdGlvbi1mb289XCJmb29cIj48L2Rpdj5cbiAqICAgICdiYXIuYmF6JzogKHZhbHVlKSA9PiB2YWx1ZSArICdiYXInXG4gKiAgICAvLyB0aGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZSAnZGF0YS1tb25zdGVyLW9wdGlvbi1iYXItYmF6JyBpcyBhcHBlbmRlZCB3aXRoICdiYXInXG4gKiAgICAvLyBhbmQgYXNzaWduZWQgdG8gdGhlICdiYXIuYmF6JyBwcm9wZXJ0eSBpbiB0aGUgb3B0aW9ucyBvYmplY3QuXG4gKiAgICAvLyBlLmcuIDxkaXYgZGF0YS1tb25zdGVyLW9wdGlvbi1iYXItYmF6PVwiZm9vXCI+PC9kaXY+XG4gKiB9XG4gKlxuICogQHNpbmNlIDMuNDUuMFxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudCAtIFRoZSBET00gZWxlbWVudCB0byBiZSB1c2VkIGFzIHRoZSBzb3VyY2Ugb2YgdGhlIGF0dHJpYnV0ZXMuXG4gKiBAcGFyYW0ge09iamVjdH0gbmFtZSAtIFRoZSBhdHRyaWJ1dGUgb2JqZWN0IHRvIGJlIHVzZWQgYXMgdGhlIHNvdXJjZSBvZiB0aGUgYXR0cmlidXRlcy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gVGhlIG9wdGlvbnMgb2JqZWN0IHRvIGJlIGluaXRpYWxpemVkLlxuICogQHBhcmFtIHtPYmplY3R9IG1hcHBpbmcgLSBBIG1hcHBpbmcgYmV0d2VlbiB0aGUgYXR0cmlidXRlIHZhbHVlIGFuZCB0aGUgcHJvcGVydHkgdmFsdWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gcHJlZml4IC0gVGhlIHByZWZpeCBvZiB0aGUgYXR0cmlidXRlcyB0byBiZSBjb25zaWRlcmVkLlxuICogQHJldHVybnMge09iamVjdH0gLSBUaGUgaW5pdGlhbGl6ZWQgb3B0aW9ucyBvYmplY3QuXG4gKiBAdGhpcyBIVE1MRWxlbWVudCAtIFRoZSBjb250ZXh0IG9mIHRoZSBET00gZWxlbWVudC5cbiAqL1xuZnVuY3Rpb24gc2V0T3B0aW9uRnJvbUF0dHJpYnV0ZShlbGVtZW50LCBuYW1lLCBvcHRpb25zLCBtYXBwaW5nID0ge30sIHByZWZpeCA9IFwiZGF0YS1tb25zdGVyLW9wdGlvbi1cIikge1xuICAgIGlmICghKGVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpIHJldHVybiBvcHRpb25zO1xuICAgIGlmICghZWxlbWVudC5oYXNBdHRyaWJ1dGVzKCkpIHJldHVybiBvcHRpb25zO1xuXG4gICAgY29uc3Qga2V5TWFwID0gZXh0cmFjdEtleXMob3B0aW9ucyk7XG4gICAgY29uc3QgZmluZGVyID0gbmV3IFBhdGhmaW5kZXIob3B0aW9ucyk7XG5cbiAgICAvLyBjaGVjayBpZiB0aGUgYXR0cmlidXRlIG5hbWUgaXMgYSB2YWxpZCBvcHRpb24uXG4gICAgLy8gdGhlIG1hcHBpbmcgYmV0d2VlbiB0aGUgYXR0cmlidXRlIGlzIHNpbXBsZS4gVGhlIGRhc2ggaXMgcmVwbGFjZWQgYnkgYSBkb3QuXG4gICAgLy8gZS5nLiBkYXRhLW1vbnN0ZXItdXJsID0+IHVybFxuICAgIGNvbnN0IG9wdGlvbk5hbWUgPSBrZXlNYXAuZ2V0KG5hbWUuc3Vic3RyaW5nKHByZWZpeC5sZW5ndGgpLnRvTG93ZXJDYXNlKCkpO1xuICAgIGlmICghZmluZGVyLmV4aXN0cyhvcHRpb25OYW1lKSkgcmV0dXJuO1xuXG4gICAgaWYgKCFlbGVtZW50Lmhhc0F0dHJpYnV0ZShuYW1lKSkge1xuICAgICAgICByZXR1cm4gb3B0aW9ucztcbiAgICB9XG5cbiAgICBsZXQgdmFsdWUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZShuYW1lKTtcbiAgICBpZiAobWFwcGluZy5oYXNPd25Qcm9wZXJ0eShvcHRpb25OYW1lKSAmJiBpc0Z1bmN0aW9uKG1hcHBpbmdbb3B0aW9uTmFtZV0pKSB7XG4gICAgICAgIHZhbHVlID0gbWFwcGluZ1tvcHRpb25OYW1lXSh2YWx1ZSk7XG4gICAgfVxuXG4gICAgY29uc3QgdHlwZU9mT3B0aW9uVmFsdWUgPSB0eXBlb2YgZmluZGVyLmdldFZpYShvcHRpb25OYW1lKTtcbiAgICBpZiAodHlwZU9mT3B0aW9uVmFsdWUgPT09IFwiYm9vbGVhblwiKSB7XG4gICAgICAgIHZhbHVlID0gdmFsdWUgPT09IFwidHJ1ZVwiO1xuICAgIH0gZWxzZSBpZiAodHlwZU9mT3B0aW9uVmFsdWUgPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgdmFsdWUgPSBOdW1iZXIodmFsdWUpO1xuICAgIH0gZWxzZSBpZiAodHlwZU9mT3B0aW9uVmFsdWUgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgdmFsdWUgPSBTdHJpbmcodmFsdWUpO1xuICAgIH0gZWxzZSBpZiAodHlwZU9mT3B0aW9uVmFsdWUgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgdmFsdWUgPSBKU09OLnBhcnNlKHZhbHVlKTtcbiAgICB9XG5cbiAgICBmaW5kZXIuc2V0VmlhKG9wdGlvbk5hbWUsIHZhbHVlKTtcblxuICAgIHJldHVybiBvcHRpb25zO1xufVxuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgZmluZEVsZW1lbnRXaXRoSWRVcHdhcmRzIH0gZnJvbSBcIi4vdXRpbC5tanNcIjtcbmltcG9ydCB7IGludGVybmFsU3ltYm9sIH0gZnJvbSBcIi4uL2NvbnN0YW50cy5tanNcIjtcbmltcG9ydCB7IGV4dGVuZCB9IGZyb20gXCIuLi9kYXRhL2V4dGVuZC5tanNcIjtcbmltcG9ydCB7IFBhdGhmaW5kZXIgfSBmcm9tIFwiLi4vZGF0YS9wYXRoZmluZGVyLm1qc1wiO1xuaW1wb3J0IHsgRm9ybWF0dGVyIH0gZnJvbSBcIi4uL3RleHQvZm9ybWF0dGVyLm1qc1wiO1xuXG5pbXBvcnQgeyBwYXJzZURhdGFVUkwgfSBmcm9tIFwiLi4vdHlwZXMvZGF0YXVybC5tanNcIjtcbmltcG9ydCB7IGdldEdsb2JhbE9iamVjdCB9IGZyb20gXCIuLi90eXBlcy9nbG9iYWwubWpzXCI7XG5pbXBvcnQgeyBpc0FycmF5LCBpc0Z1bmN0aW9uLCBpc0l0ZXJhYmxlLCBpc09iamVjdCwgaXNTdHJpbmcgfSBmcm9tIFwiLi4vdHlwZXMvaXMubWpzXCI7XG5pbXBvcnQgeyBPYnNlcnZlciB9IGZyb20gXCIuLi90eXBlcy9vYnNlcnZlci5tanNcIjtcbmltcG9ydCB7IFByb3h5T2JzZXJ2ZXIgfSBmcm9tIFwiLi4vdHlwZXMvcHJveHlvYnNlcnZlci5tanNcIjtcbmltcG9ydCB7IHZhbGlkYXRlRnVuY3Rpb24sIHZhbGlkYXRlSW5zdGFuY2UsIHZhbGlkYXRlT2JqZWN0LCB2YWxpZGF0ZVN0cmluZyB9IGZyb20gXCIuLi90eXBlcy92YWxpZGF0ZS5tanNcIjtcbmltcG9ydCB7IGNsb25lIH0gZnJvbSBcIi4uL3V0aWwvY2xvbmUubWpzXCI7XG5pbXBvcnQgeyBhZGRBdHRyaWJ1dGVUb2tlbiwgZ2V0TGlua2VkT2JqZWN0cywgaGFzT2JqZWN0TGluayB9IGZyb20gXCIuL2F0dHJpYnV0ZXMubWpzXCI7XG5pbXBvcnQge1xuICAgIEFUVFJJQlVURV9ESVNBQkxFRCxcbiAgICBBVFRSSUJVVEVfRVJST1JNRVNTQUdFLFxuICAgIEFUVFJJQlVURV9PUFRJT05TLFxuICAgIEFUVFJJQlVURV9JTklUX0NBTExCQUNLLFxuICAgIEFUVFJJQlVURV9PUFRJT05TX1NFTEVDVE9SLFxuICAgIEFUVFJJQlVURV9TQ1JJUFRfSE9TVCxcbiAgICBjdXN0b21FbGVtZW50VXBkYXRlckxpbmtTeW1ib2wsXG4gICAgaW5pdENvbnRyb2xDYWxsYmFja05hbWUsXG59IGZyb20gXCIuL2NvbnN0YW50cy5tanNcIjtcbmltcG9ydCB7IGZpbmREb2N1bWVudFRlbXBsYXRlLCBUZW1wbGF0ZSB9IGZyb20gXCIuL3RlbXBsYXRlLm1qc1wiO1xuaW1wb3J0IHsgYWRkT2JqZWN0V2l0aFVwZGF0ZXJUb0VsZW1lbnQgfSBmcm9tIFwiLi91cGRhdGVyLm1qc1wiO1xuaW1wb3J0IHsgaW5zdGFuY2VTeW1ib2wgfSBmcm9tIFwiLi4vY29uc3RhbnRzLm1qc1wiO1xuaW1wb3J0IHsgZ2V0RG9jdW1lbnRUcmFuc2xhdGlvbnMsIFRyYW5zbGF0aW9ucyB9IGZyb20gXCIuLi9pMThuL3RyYW5zbGF0aW9ucy5tanNcIjtcbmltcG9ydCB7IGdldFNsb3R0ZWRFbGVtZW50cyB9IGZyb20gXCIuL3Nsb3R0ZWQubWpzXCI7XG5pbXBvcnQgeyBpbml0T3B0aW9uc0Zyb21BdHRyaWJ1dGVzIH0gZnJvbSBcIi4vdXRpbC9pbml0LW9wdGlvbnMtZnJvbS1hdHRyaWJ1dGVzLm1qc1wiO1xuaW1wb3J0IHsgc2V0T3B0aW9uRnJvbUF0dHJpYnV0ZSB9IGZyb20gXCIuL3V0aWwvc2V0LW9wdGlvbi1mcm9tLWF0dHJpYnV0ZS5tanNcIjtcblxuZXhwb3J0IHtcbiAgICBDdXN0b21FbGVtZW50LFxuICAgIGluaXRNZXRob2RTeW1ib2wsXG4gICAgYXNzZW1ibGVNZXRob2RTeW1ib2wsXG4gICAgYXR0cmlidXRlT2JzZXJ2ZXJTeW1ib2wsXG4gICAgcmVnaXN0ZXJDdXN0b21FbGVtZW50LFxuICAgIGdldFNsb3R0ZWRFbGVtZW50cyxcbn07XG5cbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3ltYm9sfVxuICovXG5jb25zdCBpbml0TWV0aG9kU3ltYm9sID0gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvZG9tL0BAaW5pdE1ldGhvZFN5bWJvbFwiKTtcblxuLyoqXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0eXBlIHtzeW1ib2x9XG4gKi9cbmNvbnN0IGFzc2VtYmxlTWV0aG9kU3ltYm9sID0gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvZG9tL0BAYXNzZW1ibGVNZXRob2RTeW1ib2xcIik7XG5cbi8qKlxuICogdGhpcyBzeW1ib2wgaG9sZHMgdGhlIGF0dHJpYnV0ZSBvYnNlcnZlciBjYWxsYmFja3MuIFRoZSBrZXkgaXMgdGhlIGF0dHJpYnV0ZSBuYW1lLlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdHlwZSB7c3ltYm9sfVxuICovXG5jb25zdCBhdHRyaWJ1dGVPYnNlcnZlclN5bWJvbCA9IFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL2RvbS9AQGF0dHJpYnV0ZU9ic2VydmVyXCIpO1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAdHlwZSB7c3ltYm9sfVxuICovXG5jb25zdCBhdHRyaWJ1dGVNdXRhdGlvbk9ic2VydmVyU3ltYm9sID0gU3ltYm9sKFwiQHNjaHVrYWkvbW9uc3Rlci9kb20vQEBtdXRhdGlvbk9ic2VydmVyXCIpO1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAdHlwZSB7c3ltYm9sfVxuICovXG5jb25zdCBzY3JpcHRIb3N0RWxlbWVudFN5bWJvbCA9IFN5bWJvbChcInNjcmlwdEhvc3RFbGVtZW50XCIpO1xuXG4vKipcbiAqIEhUTUxFbGVtZW50XG4gKiBAZXh0ZXJuYWwgSFRNTEVsZW1lbnRcbiAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0hUTUxFbGVtZW50XG4gKlxuICogQHN0YXJ0dW1sIGN1c3RvbWVsZW1lbnQtc2VxdWVuY2VkaWFncmFtLnBuZ1xuICogc2tpbnBhcmFtIG1vbm9jaHJvbWUgdHJ1ZVxuICogc2tpbnBhcmFtIHNoYWRvd2luZyBmYWxzZVxuICpcbiAqIGF1dG9udW1iZXJcbiAqXG4gKiBTY3JpcHQgLT4gRE9NOiBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbXktZWxlbWVudCcpXG4gKiBET00gLT4gQ3VzdG9tRWxlbWVudDogY29uc3RydWN0b3IoKVxuICogQ3VzdG9tRWxlbWVudCAtPiBDdXN0b21FbGVtZW50OiBbaW5pdE1ldGhvZFN5bWJvbF0oKVxuICpcbiAqIEN1c3RvbUVsZW1lbnQgLS0+IERPTTogRWxlbWVudFxuICogRE9NIC0tPiBTY3JpcHQgOiBlbGVtZW50XG4gKlxuICpcbiAqIFNjcmlwdCAtPiBET006IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2JvZHknKS5hcHBlbmQoZWxlbWVudClcbiAqXG4gKiBET00gLT4gQ3VzdG9tRWxlbWVudCA6IGNvbm5lY3RlZENhbGxiYWNrKClcbiAqXG4gKiBub3RlIHJpZ2h0IEN1c3RvbUVsZW1lbnQ6IGlzIG9ubHkgY2FsbGVkIGF0XFxudGhlIGZpcnN0IGNvbm5lY3Rpb25cbiAqIEN1c3RvbUVsZW1lbnQgLT4gQ3VzdG9tRWxlbWVudCA6IFthc3NlbWJsZU1ldGhvZFN5bWJvbF0oKVxuICpcbiAqIC4uLiAuLi5cbiAqXG4gKiBhdXRvbnVtYmVyXG4gKlxuICogU2NyaXB0IC0+IERPTTogZG9jdW1lbnQucXVlcnlTZWxlY3RvcignbW9uc3Rlci1jb25maXJtLWJ1dHRvbicpLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoZWxlbWVudClcbiAqIERPTSAtPiBDdXN0b21FbGVtZW50OiBkaXNjb25uZWN0ZWRDYWxsYmFjaygpXG4gKlxuICpcbiAqIEBlbmR1bWxcbiAqXG4gKiBAc3RhcnR1bWwgY3VzdG9tZWxlbWVudC1jbGFzcy5wbmdcbiAqIHNraW5wYXJhbSBtb25vY2hyb21lIHRydWVcbiAqIHNraW5wYXJhbSBzaGFkb3dpbmcgZmFsc2VcbiAqIEhUTUxFbGVtZW50IDx8LS0gQ3VzdG9tRWxlbWVudFxuICogQGVuZHVtbFxuICovXG5cbi8qKlxuICogVGhlIGBDdXN0b21FbGVtZW50YCBjbGFzcyBwcm92aWRlcyBhIHdheSB0byBkZWZpbmUgYSBuZXcgSFRNTCBlbGVtZW50IHVzaW5nIHRoZSBwb3dlciBvZiBDdXN0b20gRWxlbWVudHMuXG4gKlxuICogKipJTVBPUlRBTlQ6KiogQWZ0ZXIgZGVmaW5pbmcgYSBgQ3VzdG9tRWxlbWVudGAsIHRoZSBgcmVnaXN0ZXJDdXN0b21FbGVtZW50YCBtZXRob2QgbXVzdCBiZSBjYWxsZWQgd2l0aCB0aGUgbmV3IGNsYXNzIG5hbWVcbiAqIHRvIG1ha2UgdGhlIHRhZyBkZWZpbmVkIHZpYSB0aGUgYGdldFRhZ2AgbWV0aG9kIGtub3duIHRvIHRoZSBET00uXG4gKlxuICogWW91IGNhbiBjcmVhdGUgYW4gaW5zdGFuY2Ugb2YgdGhlIG9iamVjdCB2aWEgdGhlIGBkb2N1bWVudC5jcmVhdGVFbGVtZW50KClgIGZ1bmN0aW9uLlxuICpcbiAqICMjIEludGVyYWN0aW9uXG4gKlxuICogPGltZyBzcmM9XCIuL2ltYWdlcy9jdXN0b21lbGVtZW50LXNlcXVlbmNlZGlhZ3JhbS5wbmdcIj5cbiAqXG4gKiAjIyBTdHlsaW5nXG4gKlxuICogVG8gZGlzcGxheSBjdXN0b20gZWxlbWVudHMgb3B0aW1hbGx5LCB0aGUgYDpkZWZpbmVkYCBwc2V1ZG8tY2xhc3MgY2FuIGJlIHVzZWQuIFRvIHByZXZlbnQgY3VzdG9tIGVsZW1lbnRzIGZyb20gYmVpbmcgZGlzcGxheWVkIGFuZCBmbGlja2VyaW5nIHVudGlsIHRoZSBjb250cm9sIGlzIHJlZ2lzdGVyZWQsXG4gKiBpdCBpcyByZWNvbW1lbmRlZCB0byBjcmVhdGUgYSBDU1MgZGlyZWN0aXZlLlxuICpcbiAqIEluIHRoZSBzaW1wbGVzdCBjYXNlLCB5b3UgY2FuIHNpbXBseSBoaWRlIHRoZSBjb250cm9sOlxuICpcbiAqIGBgYGh0bWxcbiAqIDxzdHlsZT5cbiAqIG15LWN1c3RvbS1lbGVtZW50Om5vdCg6ZGVmaW5lZCkge1xuICogICAgIGRpc3BsYXk6IG5vbmU7XG4gKiB9XG4gKlxuICogbXktY3VzdG9tLWVsZW1lbnQ6ZGVmaW5lZCB7XG4gKiAgICAgZGlzcGxheTogZmxleDtcbiAqIH1cbiAqIDwvc3R5bGU+XG4gKiBgYGBcbiAqXG4gKiBBbHRlcm5hdGl2ZWx5LCB5b3UgY2FuIGRpc3BsYXkgYSBsb2FkZXI6XG4gKlxuICogYGBgY3NzXG4gKiBteS1jdXN0b20tZWxlbWVudDpub3QoOmRlZmluZWQpIHtcbiAqICAgICBkaXNwbGF5OiBmbGV4O1xuICogICAgIGJveC1zaGFkb3c6IDAgNHB4IDEwcHggMCByZ2JhKDMzLCAzMywgMzMsIDAuMTUpO1xuICogICAgIGJvcmRlci1yYWRpdXM6IDRweDtcbiAqICAgICBoZWlnaHQ6IDIwMHB4O1xuICogICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAqICAgICBvdmVyZmxvdzogaGlkZGVuO1xuICogfVxuICpcbiAqIG15LWN1c3RvbS1lbGVtZW50Om5vdCg6ZGVmaW5lZCk6OmJlZm9yZSB7XG4gKiAgICAgY29udGVudDogJyc7XG4gKiAgICAgZGlzcGxheTogYmxvY2s7XG4gKiAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICogICAgIGxlZnQ6IC0xNTBweDtcbiAqICAgICB0b3A6IDA7XG4gKiAgICAgaGVpZ2h0OiAxMDAlO1xuICogICAgIHdpZHRoOiAxNTBweDtcbiAqICAgICBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQodG8gcmlnaHQsIHRyYW5zcGFyZW50IDAlLCAjRThFOEU4IDUwJSwgdHJhbnNwYXJlbnQgMTAwJSk7XG4gKiAgICAgYW5pbWF0aW9uOiBsb2FkIDFzIGN1YmljLWJlemllcigwLjQsIDAuMCwgMC4yLCAxKSBpbmZpbml0ZTtcbiAqIH1cbiAqXG4gKiBAa2V5ZnJhbWVzIGxvYWQge1xuICogICAgIGZyb20ge1xuICogICAgICAgICBsZWZ0OiAtMTUwcHg7XG4gKiAgICAgfVxuICogICAgIHRvIHtcbiAqICAgICAgICAgbGVmdDogMTAwJTtcbiAqICAgICB9XG4gKiB9XG4gKlxuICogbXktY3VzdG9tLWVsZW1lbnQ6ZGVmaW5lZCB7XG4gKiAgICAgZGlzcGxheTogZmxleDtcbiAqIH1cbiAqIGBgYFxuICpcbiAqIE1vcmUgaW5mb3JtYXRpb24gYWJvdXQgQ3VzdG9tIEVsZW1lbnRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgW01ETiBXZWIgRG9jc10oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvV2ViX0NvbXBvbmVudHMvVXNpbmdfY3VzdG9tX2VsZW1lbnRzKS5cbiAqIEFuZCBpbiB0aGUgW0hUTUwgU3RhbmRhcmRdKGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL2N1c3RvbS1lbGVtZW50cy5odG1sI2N1c3RvbS1lbGVtZW50cykgb3IgaW4gdGhlIFtXSEFUV0cgV2lraV0oaHR0cHM6Ly93aWtpLndoYXR3Zy5vcmcvd2lraS9DdXN0b21fRWxlbWVudHMpLlxuICpcbiAqIEBleHRlcm5hbEV4YW1wbGUgLi4vLi4vZXhhbXBsZS9kb20vdGhlbWUubWpzXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjcuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQGV4dGVuZHMgZXh0ZXJuYWw6SFRNTEVsZW1lbnRcbiAqIEBzdW1tYXJ5IEEgYmFzZSBjbGFzcyBmb3IgSFRNTDUgY3VzdG9tIGNvbnRyb2xzLlxuICovXG5jbGFzcyBDdXN0b21FbGVtZW50IGV4dGVuZHMgSFRNTEVsZW1lbnQge1xuICAgIC8qKlxuICAgICAqIEEgbmV3IG9iamVjdCBpcyBjcmVhdGVkLiBGaXJzdCB0aGUgYGluaXRPcHRpb25zYCBtZXRob2QgaXMgY2FsbGVkLiBIZXJlIHRoZVxuICAgICAqIG9wdGlvbnMgY2FuIGJlIGRlZmluZWQgaW4gZGVyaXZlZCBjbGFzc2VzLiBTdWJzZXF1ZW50bHksIHRoZSBzaGFkb3dSb290IGlzIGluaXRpYWxpemVkLlxuICAgICAqXG4gICAgICogSU1QT1JUQU5UOiBDdXN0b21Db250cm9scyBpbnN0YW5jZXMgYXJlIG5vdCBjcmVhdGVkIHZpYSB0aGUgY29uc3RydWN0b3IsIGJ1dCBlaXRoZXIgdmlhIGEgdGFnIGluIHRoZSBIVE1MIG9yIHZpYSA8Y29kZT5kb2N1bWVudC5jcmVhdGVFbGVtZW50KCk8L2NvZGU+LlxuICAgICAqXG4gICAgICogQHRocm93cyB7RXJyb3J9IHRoZSBvcHRpb25zIGF0dHJpYnV0ZSBkb2VzIG5vdCBjb250YWluIGEgdmFsaWQganNvbiBkZWZpbml0aW9uLlxuICAgICAqIEBzaW5jZSAxLjcuMFxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuXG4gICAgICAgIHRoaXNbYXR0cmlidXRlT2JzZXJ2ZXJTeW1ib2xdID0ge307XG4gICAgICAgIHRoaXNbaW50ZXJuYWxTeW1ib2xdID0gbmV3IFByb3h5T2JzZXJ2ZXIoe1xuICAgICAgICAgICAgb3B0aW9uczogaW5pdE9wdGlvbnNGcm9tQXR0cmlidXRlcyh0aGlzLCBleHRlbmQoe30sIHRoaXMuZGVmYXVsdHMpKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXNbaW5pdE1ldGhvZFN5bWJvbF0oKTtcbiAgICAgICAgaW5pdE9wdGlvbk9ic2VydmVyLmNhbGwodGhpcyk7XG4gICAgICAgIHRoaXNbc2NyaXB0SG9zdEVsZW1lbnRTeW1ib2xdID0gW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMi4xLjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci9kb20vY3VzdG9tLWVsZW1lbnRAQGluc3RhbmNlXCIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGRldGVybWluZXMgd2hpY2ggYXR0cmlidXRlcyBhcmUgdG8gYmVcbiAgICAgKiBtb25pdG9yZWQgYnkgYGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjaygpYC4gVW5mb3J0dW5hdGVseSwgdGhpcyBtZXRob2QgaXMgc3RhdGljLlxuICAgICAqIFRoZXJlZm9yZSwgdGhlIGBvYnNlcnZlZEF0dHJpYnV0ZXNgIHByb3BlcnR5IGNhbm5vdCBiZSBjaGFuZ2VkIGR1cmluZyBydW50aW1lLlxuICAgICAqXG4gICAgICogQHJldHVybiB7c3RyaW5nW119XG4gICAgICogQHNpbmNlIDEuMTUuMFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgb2JzZXJ2ZWRBdHRyaWJ1dGVzKCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0gYXR0cmlidXRlXG4gICAgICogQHBhcmFtIGNhbGxiYWNrXG4gICAgICogQHJldHVybnMge01vbnN0ZXIuRE9NLkN1c3RvbUVsZW1lbnR9XG4gICAgICovXG4gICAgYWRkQXR0cmlidXRlT2JzZXJ2ZXIoYXR0cmlidXRlLCBjYWxsYmFjaykge1xuICAgICAgICB2YWxpZGF0ZUZ1bmN0aW9uKGNhbGxiYWNrKTtcbiAgICAgICAgdGhpc1thdHRyaWJ1dGVPYnNlcnZlclN5bWJvbF1bYXR0cmlidXRlXSA9IGNhbGxiYWNrO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSBhdHRyaWJ1dGVcbiAgICAgKiBAcmV0dXJucyB7TW9uc3Rlci5ET00uQ3VzdG9tRWxlbWVudH1cbiAgICAgKi9cbiAgICByZW1vdmVBdHRyaWJ1dGVPYnNlcnZlcihhdHRyaWJ1dGUpIHtcbiAgICAgICAgZGVsZXRlIHRoaXNbYXR0cmlidXRlT2JzZXJ2ZXJTeW1ib2xdW2F0dHJpYnV0ZV07XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBgZGVmYXVsdHNgIHByb3BlcnR5IGRlZmluZXMgdGhlIGRlZmF1bHQgdmFsdWVzIGZvciBhIGNvbnRyb2wuIElmIHlvdSB3YW50IHRvIG92ZXJyaWRlIHRoZXNlLFxuICAgICAqIHlvdSBjYW4gdXNlIHZhcmlvdXMgbWV0aG9kcywgd2hpY2ggYXJlIGRlc2NyaWJlZCBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhdmFpbGFibGUgYXRcbiAgICAgKiB7QGxpbmsgaHR0cHM6Ly9tb25zdGVyanMub3JnZW5kb2Njb25maWd1cmF0ZS1hLW1vbnN0ZXItY29udHJvbH0uXG4gICAgICpcbiAgICAgKiBUaGUgaW5kaXZpZHVhbCBjb25maWd1cmF0aW9uIHZhbHVlcyBhcmUgbGlzdGVkIGJlbG93OlxuICAgICAqXG4gICAgICogTW9yZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgc2hhZG93Um9vdCBjYW4gYmUgZm91bmQgaW4gdGhlIFtNRE4gV2ViIERvY3NdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FbGVtZW50L2F0dGFjaFNoYWRvdyksXG4gICAgICogaW4gdGhlIFtIVE1MIFN0YW5kYXJkXShodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9jdXN0b20tZWxlbWVudHMuaHRtbCNjdXN0b20tZWxlbWVudHMpIG9yIGluIHRoZSBbV0hBVFdHIFdpa2ldKGh0dHBzOi8vd2lraS53aGF0d2cub3JnL3dpa2kvQ3VzdG9tX0VsZW1lbnRzKS5cbiAgICAgKlxuICAgICAqIE1vcmUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHRlbXBsYXRlIGVsZW1lbnQgY2FuIGJlIGZvdW5kIGluIHRoZSBbTUROIFdlYiBEb2NzXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVE1ML0VsZW1lbnQvdGVtcGxhdGUpLlxuICAgICAqXG4gICAgICogTW9yZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgc2xvdCBlbGVtZW50IGNhbiBiZSBmb3VuZCBpbiB0aGUgW01ETiBXZWIgRG9jc10oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9FbGVtZW50L3Nsb3QpLlxuICAgICAqXG4gICAgICogQHByb3BlcnR5IHtib29sZWFufSBkaXNhYmxlZD1mYWxzZSBTcGVjaWZpZXMgd2hldGhlciB0aGUgY29udHJvbCBpcyBkaXNhYmxlZC4gV2hlbiBwcmVzZW50LCBpdCBtYWtlcyB0aGUgZWxlbWVudCBub24tbXV0YWJsZSwgbm9uLWZvY3VzYWJsZSwgYW5kIG5vbi1zdWJtaXR0YWJsZSB3aXRoIHRoZSBmb3JtLlxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBzaGFkb3dNb2RlPW9wZW4gU3BlY2lmaWVzIHRoZSBtb2RlIG9mIHRoZSBzaGFkb3cgcm9vdC4gV2hlbiBzZXQgdG8gYG9wZW5gLCBlbGVtZW50cyBpbiB0aGUgc2hhZG93IHJvb3QgYXJlIGFjY2Vzc2libGUgZnJvbSBKYXZhU2NyaXB0IG91dHNpZGUgdGhlIHJvb3QsIHdoaWxlIHNldHRpbmcgaXQgdG8gYGNsb3NlZGAgZGVuaWVzIGFjY2VzcyB0byB0aGUgcm9vdCdzIG5vZGVzIGZyb20gSmF2YVNjcmlwdCBvdXRzaWRlIGl0LlxuICAgICAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gZGVsZWdhdGVzRm9jdXM9dHJ1ZSBTcGVjaWZpZXMgdGhlIGJlaGF2aW9yIG9mIHRoZSBjb250cm9sIHdpdGggcmVzcGVjdCB0byBmb2N1c2FiaWxpdHkuIFdoZW4gc2V0IHRvIGB0cnVlYCwgaXQgbWl0aWdhdGVzIGN1c3RvbSBlbGVtZW50IGlzc3VlcyBhcm91bmQgZm9jdXNhYmlsaXR5LiBXaGVuIGEgbm9uLWZvY3VzYWJsZSBwYXJ0IG9mIHRoZSBzaGFkb3cgRE9NIGlzIGNsaWNrZWQsIHRoZSBmaXJzdCBmb2N1c2FibGUgcGFydCBpcyBnaXZlbiBmb2N1cywgYW5kIHRoZSBzaGFkb3cgaG9zdCBpcyBnaXZlbiBhbnkgYXZhaWxhYmxlIDpmb2N1cyBzdHlsaW5nLlxuICAgICAqIEBwcm9wZXJ0eSB7T2JqZWN0fSB0ZW1wbGF0ZXMgU3BlY2lmaWVzIHRoZSB0ZW1wbGF0ZXMgdXNlZCBieSB0aGUgY29udHJvbC5cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gdGVtcGxhdGVzLm1haW49dW5kZWZpbmVkIFNwZWNpZmllcyB0aGUgbWFpbiB0ZW1wbGF0ZSB1c2VkIGJ5IHRoZSBjb250cm9sLlxuICAgICAqIEBwcm9wZXJ0eSB7T2JqZWN0fSB0ZW1wbGF0ZU1hcHBpbmcgU3BlY2lmaWVzIHRoZSBtYXBwaW5nIG9mIHRlbXBsYXRlcy5cbiAgICAgKiBAc2luY2UgMS44LjBcbiAgICAgKi9cbiAgICBnZXQgZGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBkaXNhYmxlZDogZmFsc2UsXG4gICAgICAgICAgICBzaGFkb3dNb2RlOiBcIm9wZW5cIixcbiAgICAgICAgICAgIGRlbGVnYXRlc0ZvY3VzOiB0cnVlLFxuICAgICAgICAgICAgdGVtcGxhdGVzOiB7XG4gICAgICAgICAgICAgICAgbWFpbjogdW5kZWZpbmVkLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRlbXBsYXRlTWFwcGluZzoge30sXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgdXBkYXRlcyB0aGUgbGFiZWxzIG9mIHRoZSBlbGVtZW50LlxuICAgICAqIFRoZSBsYWJlbHMgYXJlIGRlZmluZWQgaW4gdGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIFRoZSBrZXkgb2YgdGhlIGxhYmVsIGlzIHVzZWQgdG8gcmV0cmlldmUgdGhlIHRyYW5zbGF0aW9uIGZyb20gdGhlIGRvY3VtZW50LlxuICAgICAqIElmIHRoZSB0cmFuc2xhdGlvbiBpcyBkaWZmZXJlbnQgZnJvbSB0aGUgbGFiZWwsIHRoZSBsYWJlbCBpcyB1cGRhdGVkLlxuICAgICAqXG4gICAgICogQmVmb3JlIHlvdSBjYW4gdXNlIHRoaXMgbWV0aG9kLCB5b3UgbXVzdCBoYXZlIGxvYWRlZCB0aGUgdHJhbnNsYXRpb25zLlxuICAgICAqXG4gICAgICogQHJldHVybnMge01vbnN0ZXIuRE9NLkN1c3RvbUVsZW1lbnR9XG4gICAgICogQHRocm93cyB7RXJyb3J9ICBDYW5ub3QgZmluZCBlbGVtZW50IHdpdGggdHJhbnNsYXRpb25zLiBBZGQgYSB0cmFuc2xhdGlvbnMgb2JqZWN0IHRvIHRoZSBkb2N1bWVudC5cbiAgICAgKi9cbiAgICB1cGRhdGVJMThuKCkge1xuICAgICAgICBjb25zdCB0cmFuc2xhdGlvbnMgPSBnZXREb2N1bWVudFRyYW5zbGF0aW9ucygpO1xuICAgICAgICBpZiAoIXRyYW5zbGF0aW9ucykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgbGFiZWxzID0gdGhpcy5nZXRPcHRpb24oXCJsYWJlbHNcIik7XG4gICAgICAgIGlmICghKGlzT2JqZWN0KGxhYmVscykgfHwgaXNJdGVyYWJsZShsYWJlbHMpKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBsYWJlbHMpIHtcbiAgICAgICAgICAgIGNvbnN0IGRlZiA9IGxhYmVsc1trZXldO1xuXG4gICAgICAgICAgICBpZiAoaXNTdHJpbmcoZGVmKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRleHQgPSB0cmFuc2xhdGlvbnMuZ2V0VGV4dChrZXksIGRlZik7XG4gICAgICAgICAgICAgICAgaWYgKHRleHQgIT09IGRlZikge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldE9wdGlvbihgbGFiZWxzLiR7a2V5fWAsIHRleHQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNPYmplY3QoZGVmKSkge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgayBpbiBkZWYpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZCA9IGRlZltrXTtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCB0ZXh0ID0gdHJhbnNsYXRpb25zLmdldFBsdXJhbFJ1bGVUZXh0KGtleSwgaywgZCk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghaXNTdHJpbmcodGV4dCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgbGFiZWxzIGRlZmluaXRpb25cIik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHRleHQgIT09IGQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0T3B0aW9uKGBsYWJlbHMuJHtrZXl9LiR7a31gLCB0ZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBsYWJlbHMgZGVmaW5pdGlvblwiKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYGdldFRhZygpYCBtZXRob2QgcmV0dXJucyB0aGUgdGFnIG5hbWUgYXNzb2NpYXRlZCB3aXRoIHRoZSBjdXN0b20gZWxlbWVudC4gVGhpcyBtZXRob2Qgc2hvdWxkIGJlIG92ZXJ3cml0dGVuXG4gICAgICogYnkgdGhlIGRlcml2ZWQgY2xhc3MuXG4gICAgICpcbiAgICAgKiBOb3RlIHRoYXQgdGhlcmUgaXMgbm8gY2hlY2sgb24gdGhlIG5hbWUgb2YgdGhlIHRhZyBpbiB0aGlzIGNsYXNzLiBJdCBpcyB0aGUgcmVzcG9uc2liaWxpdHkgb2ZcbiAgICAgKiB0aGUgZGV2ZWxvcGVyIHRvIGFzc2lnbiBhbiBhcHByb3ByaWF0ZSB0YWcgbmFtZS4gSWYgdGhlIG5hbWUgaXMgbm90IHZhbGlkLCB0aGVcbiAgICAgKiBgcmVnaXN0ZXJDdXN0b21FbGVtZW50KClgIG1ldGhvZCB3aWxsIGlzc3VlIGFuIGVycm9yLlxuICAgICAqXG4gICAgICogQHNlZSBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9jdXN0b20tZWxlbWVudHMuaHRtbCN2YWxpZC1jdXN0b20tZWxlbWVudC1uYW1lXG4gICAgICogQHRocm93cyB7RXJyb3J9IFRoaXMgbWV0aG9kIG11c3QgYmUgb3ZlcnJpZGRlbiBieSB0aGUgZGVyaXZlZCBjbGFzcy5cbiAgICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSB0YWcgbmFtZSBhc3NvY2lhdGVkIHdpdGggdGhlIGN1c3RvbSBlbGVtZW50LlxuICAgICAqIEBzaW5jZSAxLjcuMFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRUYWcoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZSBtZXRob2QgYGdldFRhZygpYCBtdXN0IGJlIG92ZXJyaWRkZW4gYnkgdGhlIGRlcml2ZWQgY2xhc3MuXCIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBgZ2V0Q1NTU3R5bGVTaGVldCgpYCBtZXRob2QgcmV0dXJucyBhIGBDU1NTdHlsZVNoZWV0YCBvYmplY3QgdGhhdCBkZWZpbmVzIHRoZSBzdHlsZXMgZm9yIHRoZSBjdXN0b20gZWxlbWVudC5cbiAgICAgKiBJZiB0aGUgZW52aXJvbm1lbnQgZG9lcyBub3Qgc3VwcG9ydCB0aGUgYENTU1N0eWxlU2hlZXRgIGNvbnN0cnVjdG9yLCB0aGVuIGFuIG9iamVjdCBjYW4gYmUgYnVpbHQgdXNpbmcgdGhlIHByb3ZpZGVkIGRldG91ci5cbiAgICAgKlxuICAgICAqIElmIGB1bmRlZmluZWRgIGlzIHJldHVybmVkLCB0aGVuIHRoZSBzaGFkb3cgcm9vdCBkb2VzIG5vdCByZWNlaXZlIGEgc3R5bGVzaGVldC5cbiAgICAgKlxuICAgICAqIEV4YW1wbGUgdXNhZ2U6XG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIHN0YXRpYyBnZXRDU1NTdHlsZVNoZWV0KCkge1xuICAgICAqICAgICBjb25zdCBzaGVldCA9IG5ldyBDU1NTdHlsZVNoZWV0KCk7XG4gICAgICogICAgIHNoZWV0LnJlcGxhY2VTeW5jKFwicCB7IGNvbG9yOiByZWQ7IH1cIik7XG4gICAgICogICAgIHJldHVybiBzaGVldDtcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBJZiB0aGUgZW52aXJvbm1lbnQgZG9lcyBub3Qgc3VwcG9ydCB0aGUgYENTU1N0eWxlU2hlZXRgIGNvbnN0cnVjdG9yLFxuICAgICAqIHlvdSBjYW4gdXNlIHRoZSBmb2xsb3dpbmcgd29ya2Fyb3VuZCB0byBjcmVhdGUgdGhlIHN0eWxlc2hlZXQ6XG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IGRvYyA9IGRvY3VtZW50LmltcGxlbWVudGF0aW9uLmNyZWF0ZUhUTUxEb2N1bWVudCgndGl0bGUnKTtcbiAgICAgKiBsZXQgc3R5bGUgPSBkb2MuY3JlYXRlRWxlbWVudChcInN0eWxlXCIpO1xuICAgICAqIHN0eWxlLmlubmVySFRNTCA9IFwicCB7IGNvbG9yOiByZWQ7IH1cIjtcbiAgICAgKiBzdHlsZS5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShcIlwiKSk7XG4gICAgICogZG9jLmhlYWQuYXBwZW5kQ2hpbGQoc3R5bGUpO1xuICAgICAqIHJldHVybiBkb2Muc3R5bGVTaGVldHNbMF07XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtDU1NTdHlsZVNoZWV0fENTU1N0eWxlU2hlZXRbXXxzdHJpbmd8dW5kZWZpbmVkfSBBIGBDU1NTdHlsZVNoZWV0YCBvYmplY3Qgb3IgYW4gYXJyYXkgb2Ygc3VjaCBvYmplY3RzIHRoYXQgZGVmaW5lIHRoZSBzdHlsZXMgZm9yIHRoZSBjdXN0b20gZWxlbWVudCwgb3IgYHVuZGVmaW5lZGAgaWYgbm8gc3R5bGVzaGVldCBzaG91bGQgYmUgYXBwbGllZC5cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0Q1NTU3R5bGVTaGVldCgpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBhdHRhY2ggYSBuZXcgb2JzZXJ2ZXJcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7T2JzZXJ2ZXJ9IG9ic2VydmVyXG4gICAgICogQHJldHVybnMge0N1c3RvbUVsZW1lbnR9XG4gICAgICovXG4gICAgYXR0YWNoT2JzZXJ2ZXIob2JzZXJ2ZXIpIHtcbiAgICAgICAgdGhpc1tpbnRlcm5hbFN5bWJvbF0uYXR0YWNoT2JzZXJ2ZXIob2JzZXJ2ZXIpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBkZXRhY2ggYSBvYnNlcnZlclxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYnNlcnZlcn0gb2JzZXJ2ZXJcbiAgICAgKiBAcmV0dXJucyB7Q3VzdG9tRWxlbWVudH1cbiAgICAgKi9cbiAgICBkZXRhY2hPYnNlcnZlcihvYnNlcnZlcikge1xuICAgICAgICB0aGlzW2ludGVybmFsU3ltYm9sXS5kZXRhY2hPYnNlcnZlcihvYnNlcnZlcik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7T2JzZXJ2ZXJ9IG9ic2VydmVyXG4gICAgICogQHJldHVybnMge1Byb3h5T2JzZXJ2ZXJ9XG4gICAgICovXG4gICAgY29udGFpbnNPYnNlcnZlcihvYnNlcnZlcikge1xuICAgICAgICByZXR1cm4gdGhpc1tpbnRlcm5hbFN5bWJvbF0uY29udGFpbnNPYnNlcnZlcihvYnNlcnZlcik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogbmVzdGVkIG9wdGlvbnMgY2FuIGJlIHNwZWNpZmllZCBieSBwYXRoIGBhLmIuY2BcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoXG4gICAgICogQHBhcmFtIHsqfSBkZWZhdWx0VmFsdWVcbiAgICAgKiBAcmV0dXJuIHsqfVxuICAgICAqIEBzaW5jZSAxLjEwLjBcbiAgICAgKi9cbiAgICBnZXRPcHRpb24ocGF0aCwgZGVmYXVsdFZhbHVlKSB7XG4gICAgICAgIGxldCB2YWx1ZTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdmFsdWUgPSBuZXcgUGF0aGZpbmRlcih0aGlzW2ludGVybmFsU3ltYm9sXS5nZXRSZWFsU3ViamVjdCgpW1wib3B0aW9uc1wiXSkuZ2V0VmlhKHBhdGgpO1xuICAgICAgICB9IGNhdGNoIChlKSB7fVxuXG4gICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSByZXR1cm4gZGVmYXVsdFZhbHVlO1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IG9wdGlvbiBhbmQgaW5mb3JtIGVsZW1lbnRzXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcGF0aFxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAgICAgKiBAcmV0dXJuIHtDdXN0b21FbGVtZW50fVxuICAgICAqIEBzaW5jZSAxLjE0LjBcbiAgICAgKi9cbiAgICBzZXRPcHRpb24ocGF0aCwgdmFsdWUpIHtcbiAgICAgICAgbmV3IFBhdGhmaW5kZXIodGhpc1tpbnRlcm5hbFN5bWJvbF0uZ2V0U3ViamVjdCgpW1wib3B0aW9uc1wiXSkuc2V0VmlhKHBhdGgsIHZhbHVlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHNpbmNlIDEuMTUuMFxuICAgICAqIEBwYXJhbSB7c3RyaW5nfG9iamVjdH0gb3B0aW9uc1xuICAgICAqIEByZXR1cm4ge0N1c3RvbUVsZW1lbnR9XG4gICAgICovXG4gICAgc2V0T3B0aW9ucyhvcHRpb25zKSB7XG4gICAgICAgIGlmIChpc1N0cmluZyhvcHRpb25zKSkge1xuICAgICAgICAgICAgb3B0aW9ucyA9IHBhcnNlT3B0aW9uc0pTT04uY2FsbCh0aGlzLCBvcHRpb25zKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgICAgICBleHRlbmQoc2VsZltpbnRlcm5hbFN5bWJvbF0uZ2V0U3ViamVjdCgpW1wib3B0aW9uc1wiXSwgc2VsZi5kZWZhdWx0cywgb3B0aW9ucyk7XG5cbiAgICAgICAgcmV0dXJuIHNlbGY7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSXMgY2FsbGVkIG9uY2UgdmlhIHRoZSBjb25zdHJ1Y3RvclxuICAgICAqXG4gICAgICogQHJldHVybiB7Q3VzdG9tRWxlbWVudH1cbiAgICAgKiBAc2luY2UgMS44LjBcbiAgICAgKi9cbiAgICBbaW5pdE1ldGhvZFN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBvbmNlIHdoZW4gdGhlIG9iamVjdCBpcyBpbmNsdWRlZCBpbiB0aGUgRE9NIGZvciB0aGUgZmlyc3QgdGltZS4gSXQgcGVyZm9ybXMgdGhlIGZvbGxvd2luZyBhY3Rpb25zOlxuICAgICAqIDEuIEV4dHJhY3RzIHRoZSBvcHRpb25zIGZyb20gdGhlIGF0dHJpYnV0ZXMgYW5kIHRoZSBzY3JpcHQgdGFnIG9mIHRoZSBlbGVtZW50IGFuZCBzZXRzIHRoZW0uXG4gICAgICogMi4gSW5pdGlhbGl6ZXMgdGhlIHNoYWRvdyByb290IGFuZCBpdHMgQ1NTIHN0eWxlc2hlZXQgKGlmIHNwZWNpZmllZCkuXG4gICAgICogMy4gSW5pdGlhbGl6ZXMgdGhlIEhUTUwgY29udGVudCBvZiB0aGUgZWxlbWVudC5cbiAgICAgKiA0LiBJbml0aWFsaXplcyB0aGUgY3VzdG9tIGVsZW1lbnRzIGluc2lkZSB0aGUgc2hhZG93IHJvb3QgYW5kIHRoZSBzbG90dGVkIGVsZW1lbnRzLlxuICAgICAqIDUuIEF0dGFjaGVzIGEgbXV0YXRpb24gb2JzZXJ2ZXIgdG8gb2JzZXJ2ZSBjaGFuZ2VzIHRvIHRoZSBhdHRyaWJ1dGVzIG9mIHRoZSBlbGVtZW50LlxuICAgICAqXG4gICAgICogQHJldHVybiB7Q3VzdG9tRWxlbWVudH0gLSBUaGUgdXBkYXRlZCBjdXN0b20gZWxlbWVudC5cbiAgICAgKiBAc2luY2UgMS44LjBcbiAgICAgKi9cbiAgICBbYXNzZW1ibGVNZXRob2RTeW1ib2xdKCkge1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICAgICAgbGV0IGVsZW1lbnRzO1xuICAgICAgICBsZXQgbm9kZUxpc3Q7XG5cbiAgICAgICAgLy8gRXh0cmFjdCBvcHRpb25zIGZyb20gYXR0cmlidXRlcyBhbmQgc2V0IHRoZW1cbiAgICAgICAgY29uc3QgQXR0cmlidXRlT3B0aW9ucyA9IGdldE9wdGlvbnNGcm9tQXR0cmlidXRlcy5jYWxsKHNlbGYpO1xuICAgICAgICBpZiAoaXNPYmplY3QoQXR0cmlidXRlT3B0aW9ucykgJiYgT2JqZWN0LmtleXMoQXR0cmlidXRlT3B0aW9ucykubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgc2VsZi5zZXRPcHRpb25zKEF0dHJpYnV0ZU9wdGlvbnMpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRXh0cmFjdCBvcHRpb25zIGZyb20gc2NyaXB0IHRhZyBhbmQgc2V0IHRoZW1cbiAgICAgICAgY29uc3QgU2NyaXB0T3B0aW9ucyA9IGdldE9wdGlvbnNGcm9tU2NyaXB0VGFnLmNhbGwoc2VsZik7XG4gICAgICAgIGlmIChpc09iamVjdChTY3JpcHRPcHRpb25zKSAmJiBPYmplY3Qua2V5cyhTY3JpcHRPcHRpb25zKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBzZWxmLnNldE9wdGlvbnMoU2NyaXB0T3B0aW9ucyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJbml0aWFsaXplIHRoZSBzaGFkb3cgcm9vdCBhbmQgaXRzIENTUyBzdHlsZXNoZWV0XG4gICAgICAgIGlmIChzZWxmLmdldE9wdGlvbihcInNoYWRvd01vZGVcIiwgZmFsc2UpICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBpbml0U2hhZG93Um9vdC5jYWxsKHNlbGYpO1xuICAgICAgICAgICAgICAgIGVsZW1lbnRzID0gc2VsZi5zaGFkb3dSb290LmNoaWxkTm9kZXM7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgYWRkQXR0cmlidXRlVG9rZW4oc2VsZiwgQVRUUklCVVRFX0VSUk9STUVTU0FHRSwgZS50b1N0cmluZygpKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBpbml0Q1NTU3R5bGVzaGVldC5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIGFkZEF0dHJpYnV0ZVRva2VuKHNlbGYsIEFUVFJJQlVURV9FUlJPUk1FU1NBR0UsIGUudG9TdHJpbmcoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiB0aGUgZWxlbWVudHMgYXJlIG5vdCBmb3VuZCBpbnNpZGUgdGhlIHNoYWRvdyByb290LCBpbml0aWFsaXplIHRoZSBIVE1MIGNvbnRlbnQgb2YgdGhlIGVsZW1lbnRcbiAgICAgICAgaWYgKCEoZWxlbWVudHMgaW5zdGFuY2VvZiBOb2RlTGlzdCkpIHtcbiAgICAgICAgICAgIGluaXRIdG1sQ29udGVudC5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgZWxlbWVudHMgPSB0aGlzLmNoaWxkTm9kZXM7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJbml0aWFsaXplIHRoZSBjdXN0b20gZWxlbWVudHMgaW5zaWRlIHRoZSBzaGFkb3cgcm9vdCBhbmQgdGhlIHNsb3R0ZWQgZWxlbWVudHNcbiAgICAgICAgaW5pdEZyb21DYWxsYmFja0hvc3QuY2FsbCh0aGlzKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIG5vZGVMaXN0ID0gbmV3IFNldChbLi4uZWxlbWVudHMsIC4uLmdldFNsb3R0ZWRFbGVtZW50cy5jYWxsKHNlbGYpXSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIG5vZGVMaXN0ID0gZWxlbWVudHM7XG4gICAgICAgIH1cbiAgICAgICAgYWRkT2JqZWN0V2l0aFVwZGF0ZXJUb0VsZW1lbnQuY2FsbChcbiAgICAgICAgICAgIHNlbGYsXG4gICAgICAgICAgICBub2RlTGlzdCxcbiAgICAgICAgICAgIGN1c3RvbUVsZW1lbnRVcGRhdGVyTGlua1N5bWJvbCxcbiAgICAgICAgICAgIGNsb25lKHNlbGZbaW50ZXJuYWxTeW1ib2xdLmdldFJlYWxTdWJqZWN0KClbXCJvcHRpb25zXCJdKSxcbiAgICAgICAgKTtcblxuICAgICAgICAvLyBBdHRhY2ggYSBtdXRhdGlvbiBvYnNlcnZlciB0byBvYnNlcnZlIGNoYW5nZXMgdG8gdGhlIGF0dHJpYnV0ZXMgb2YgdGhlIGVsZW1lbnRcbiAgICAgICAgYXR0YWNoQXR0cmlidXRlQ2hhbmdlTXV0YXRpb25PYnNlcnZlci5jYWxsKHRoaXMpO1xuXG4gICAgICAgIHJldHVybiBzZWxmO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBldmVyeSB0aW1lIHRoZSBlbGVtZW50IGlzIGluc2VydGVkIGludG8gdGhlIERPTS4gSXQgY2hlY2tzIGlmIHRoZSBjdXN0b20gZWxlbWVudFxuICAgICAqIGhhcyBhbHJlYWR5IGJlZW4gaW5pdGlhbGl6ZWQgYW5kIGlmIG5vdCwgY2FsbHMgdGhlIGFzc2VtYmxlTWV0aG9kIHRvIGluaXRpYWxpemUgaXQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgICAqIEBzaW5jZSAxLjcuMFxuICAgICAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0VsZW1lbnQvY29ubmVjdGVkQ2FsbGJhY2tcbiAgICAgKi9cbiAgICBjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIG9iamVjdCBoYXMgYWxyZWFkeSBiZWVuIGluaXRpYWxpemVkXG4gICAgICAgIGlmICghaGFzT2JqZWN0TGluayhzZWxmLCBjdXN0b21FbGVtZW50VXBkYXRlckxpbmtTeW1ib2wpKSB7XG4gICAgICAgICAgICAvLyBJZiBub3QsIGNhbGwgdGhlIGFzc2VtYmxlTWV0aG9kIHRvIGluaXRpYWxpemUgdGhlIG9iamVjdFxuICAgICAgICAgICAgc2VsZlthc3NlbWJsZU1ldGhvZFN5bWJvbF0oKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbGxlZCBldmVyeSB0aW1lIHRoZSBlbGVtZW50IGlzIHJlbW92ZWQgZnJvbSB0aGUgRE9NLiBVc2VmdWwgZm9yIHJ1bm5pbmcgY2xlYW4gdXAgY29kZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm4ge3ZvaWR9XG4gICAgICogQHNpbmNlIDEuNy4wXG4gICAgICovXG4gICAgZGlzY29ubmVjdGVkQ2FsbGJhY2soKSB7fVxuXG4gICAgLyoqXG4gICAgICogVGhlIGN1c3RvbSBlbGVtZW50IGhhcyBiZWVuIG1vdmVkIGludG8gYSBuZXcgZG9jdW1lbnQgKGUuZy4gc29tZW9uZSBjYWxsZWQgZG9jdW1lbnQuYWRvcHROb2RlKGVsKSkuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgICAqIEBzaW5jZSAxLjcuMFxuICAgICAqL1xuICAgIGFkb3B0ZWRDYWxsYmFjaygpIHt9XG5cbiAgICAvKipcbiAgICAgKiBDYWxsZWQgd2hlbiBhbiBvYnNlcnZlZCBhdHRyaWJ1dGUgaGFzIGJlZW4gYWRkZWQsIHJlbW92ZWQsIHVwZGF0ZWQsIG9yIHJlcGxhY2VkLiBBbHNvIGNhbGxlZCBmb3IgaW5pdGlhbFxuICAgICAqIHZhbHVlcyB3aGVuIGFuIGVsZW1lbnQgaXMgY3JlYXRlZCBieSB0aGUgcGFyc2VyLCBvciB1cGdyYWRlZC4gTm90ZTogb25seSBhdHRyaWJ1dGVzIGxpc3RlZCBpbiB0aGUgb2JzZXJ2ZWRBdHRyaWJ1dGVzXG4gICAgICogcHJvcGVydHkgd2lsbCByZWNlaXZlIHRoaXMgY2FsbGJhY2suXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gYXR0ck5hbWVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gb2xkVmFsXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5ld1ZhbFxuICAgICAqIEByZXR1cm4ge3ZvaWR9XG4gICAgICogQHNpbmNlIDEuMTUuMFxuICAgICAqL1xuICAgIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhhdHRyTmFtZSwgb2xkVmFsLCBuZXdWYWwpIHtcbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICAgICAgaWYgKGF0dHJOYW1lLnN0YXJ0c1dpdGgoXCJkYXRhLW1vbnN0ZXItb3B0aW9uLVwiKSkge1xuICAgICAgICAgICAgc2V0T3B0aW9uRnJvbUF0dHJpYnV0ZShzZWxmLCBhdHRyTmFtZSwgdGhpc1tpbnRlcm5hbFN5bWJvbF0uZ2V0U3ViamVjdCgpW1wib3B0aW9uc1wiXSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjYWxsYmFjayA9IHNlbGZbYXR0cmlidXRlT2JzZXJ2ZXJTeW1ib2xdPy5bYXR0ck5hbWVdO1xuICAgICAgICBpZiAoaXNGdW5jdGlvbihjYWxsYmFjaykpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2suY2FsbChzZWxmLCBuZXdWYWwsIG9sZFZhbCk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgYWRkQXR0cmlidXRlVG9rZW4oc2VsZiwgQVRUUklCVVRFX0VSUk9STUVTU0FHRSwgZS50b1N0cmluZygpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtOb2RlfSBub2RlXG4gICAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhbiBpbnN0YW5jZSBvZlxuICAgICAqIEBzaW5jZSAxLjE5LjBcbiAgICAgKi9cbiAgICBoYXNOb2RlKG5vZGUpIHtcbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICAgICAgaWYgKGNvbnRhaW5DaGlsZE5vZGUuY2FsbChzZWxmLCB2YWxpZGF0ZUluc3RhbmNlKG5vZGUsIE5vZGUpKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIShzZWxmLnNoYWRvd1Jvb3QgaW5zdGFuY2VvZiBTaGFkb3dSb290KSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNvbnRhaW5DaGlsZE5vZGUuY2FsbChzZWxmLnNoYWRvd1Jvb3QsIG5vZGUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbGxzIGEgY2FsbGJhY2sgZnVuY3Rpb24gaWYgaXQgZXhpc3RzLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAgICAgKiBAcGFyYW0geyp9IGFyZ3NcbiAgICAgKiBAcmV0dXJucyB7Kn1cbiAgICAgKi9cbiAgICBjYWxsQ2FsbGJhY2sobmFtZSwgYXJncykge1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICAgICAgcmV0dXJuIGNhbGxDb250cm9sQ2FsbGJhY2suY2FsbChzZWxmLCBuYW1lLCAuLi5hcmdzKTtcbiAgICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IGNhbGxCYWNrRnVuY3Rpb25OYW1lXG4gKiBAcGFyYW0geyp9ICBhcmdzXG4gKiBAcmV0dXJuIHthbnl9XG4gKi9cbmZ1bmN0aW9uIGNhbGxDb250cm9sQ2FsbGJhY2soY2FsbEJhY2tGdW5jdGlvbk5hbWUsIC4uLmFyZ3MpIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgIGlmICghaXNTdHJpbmcoY2FsbEJhY2tGdW5jdGlvbk5hbWUpIHx8IGNhbGxCYWNrRnVuY3Rpb25OYW1lID09PSBcIlwiKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoY2FsbEJhY2tGdW5jdGlvbk5hbWUgaW4gc2VsZikge1xuICAgICAgICByZXR1cm4gc2VsZltjYWxsQmFja0Z1bmN0aW9uTmFtZV0oc2VsZiwgLi4uYXJncyk7XG4gICAgfVxuXG4gICAgaWYgKCFzZWxmLmhhc0F0dHJpYnV0ZShBVFRSSUJVVEVfU0NSSVBUX0hPU1QpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoc2VsZltzY3JpcHRIb3N0RWxlbWVudFN5bWJvbF0ubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGNvbnN0IHRhcmdldElkID0gc2VsZi5nZXRBdHRyaWJ1dGUoQVRUUklCVVRFX1NDUklQVF9IT1NUKTtcbiAgICAgICAgaWYgKCF0YXJnZXRJZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbGlzdCA9IHRhcmdldElkLnNwbGl0KFwiLFwiKTtcbiAgICAgICAgZm9yIChjb25zdCBpZCBvZiBsaXN0KSB7XG4gICAgICAgICAgICBjb25zdCBob3N0ID0gZmluZEVsZW1lbnRXaXRoSWRVcHdhcmRzKHNlbGYsIHRhcmdldElkKTtcbiAgICAgICAgICAgIGlmICghKGhvc3QgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgc2VsZltzY3JpcHRIb3N0RWxlbWVudFN5bWJvbF0ucHVzaChob3N0KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgaG9zdCBvZiBzZWxmW3NjcmlwdEhvc3RFbGVtZW50U3ltYm9sXSkge1xuICAgICAgICBpZiAoY2FsbEJhY2tGdW5jdGlvbk5hbWUgaW4gaG9zdCkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaG9zdFtjYWxsQmFja0Z1bmN0aW9uTmFtZV0oc2VsZiwgLi4uYXJncyk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgYWRkQXR0cmlidXRlVG9rZW4oc2VsZiwgQVRUUklCVVRFX0VSUk9STUVTU0FHRSwgZS50b1N0cmluZygpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFkZEF0dHJpYnV0ZVRva2VuKHNlbGYsIEFUVFJJQlVURV9FUlJPUk1FU1NBR0UsIGBjYWxsYmFjayAke2NhbGxCYWNrRnVuY3Rpb25OYW1lfSBub3QgZm91bmRgKTtcbn1cblxuLyoqXG4gKiBJbml0aWFsaXplcyB0aGUgY3VzdG9tIGVsZW1lbnQgYmFzZWQgb24gdGhlIHByb3ZpZGVkIGNhbGxiYWNrIGZ1bmN0aW9uLlxuICpcbiAqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIHdoZW4gdGhlIGVsZW1lbnQgaXMgYXR0YWNoZWQgdG8gdGhlIERPTS4gSXQgY2hlY2tzIGlmIHRoZVxuICogYGRhdGEtbW9uc3Rlci1vcHRpb24tY2FsbGJhY2tgIGF0dHJpYnV0ZSBpcyBzZXQsIGFuZCBpZiBub3QsIHRoZSBkZWZhdWx0IGNhbGxiYWNrXG4gKiBgaW5pdEN1c3RvbUNvbnRyb2xDYWxsYmFja2AgaXMgY2FsbGVkLiBUaGUgY2FsbGJhY2sgZnVuY3Rpb24gaXMgc2VhcmNoZWQgZm9yIGluIHRoaXNcbiAqIGVsZW1lbnQgYW5kIGluIHRoZSBob3N0IGVsZW1lbnQuIElmIHRoZSBjYWxsYmFjayBpcyBmb3VuZCwgaXQgaXMgY2FsbGVkIHdpdGggdGhlIGVsZW1lbnRcbiAqIGFzIGEgcGFyYW1ldGVyLlxuICpcbiAqIEB0aGlzIEN1c3RvbUVsZW1lbnRcbiAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0N1c3RvbUVsZW1lbnRSZWdpc3RyeS9kZWZpbmUjcHJvdmlkaW5nX2FfY29uc3RydWN0aW9uX2NhbGxiYWNrXG4gKiBAc2luY2UgMS44LjBcbiAqL1xuZnVuY3Rpb24gaW5pdEZyb21DYWxsYmFja0hvc3QoKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICAvLyBTZXQgdGhlIGRlZmF1bHQgY2FsbGJhY2sgZnVuY3Rpb24gbmFtZVxuICAgIGxldCBjYWxsQmFja0Z1bmN0aW9uTmFtZSA9IGluaXRDb250cm9sQ2FsbGJhY2tOYW1lO1xuXG4gICAgLy8gSWYgdGhlIGBkYXRhLW1vbnN0ZXItb3B0aW9uLWNhbGxiYWNrYCBhdHRyaWJ1dGUgaXMgc2V0LCB1c2UgaXRzIHZhbHVlIGFzIHRoZSBjYWxsYmFjayBmdW5jdGlvbiBuYW1lXG4gICAgaWYgKHNlbGYuaGFzQXR0cmlidXRlKEFUVFJJQlVURV9JTklUX0NBTExCQUNLKSkge1xuICAgICAgICBjYWxsQmFja0Z1bmN0aW9uTmFtZSA9IHNlbGYuZ2V0QXR0cmlidXRlKEFUVFJJQlVURV9JTklUX0NBTExCQUNLKTtcbiAgICB9XG5cbiAgICAvLyBDYWxsIHRoZSBjYWxsYmFjayBmdW5jdGlvbiB3aXRoIHRoZSBlbGVtZW50IGFzIGEgcGFyYW1ldGVyIGlmIGl0IGV4aXN0c1xuICAgIGNhbGxDb250cm9sQ2FsbGJhY2suY2FsbChzZWxmLCBjYWxsQmFja0Z1bmN0aW9uTmFtZSk7XG59XG5cbi8qKlxuICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIHdoZW4gdGhlIGVsZW1lbnQgaXMgZmlyc3QgY3JlYXRlZC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHRoaXMgQ3VzdG9tRWxlbWVudFxuICovXG5mdW5jdGlvbiBhdHRhY2hBdHRyaWJ1dGVDaGFuZ2VNdXRhdGlvbk9ic2VydmVyKCkge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgaWYgKHR5cGVvZiBzZWxmW2F0dHJpYnV0ZU11dGF0aW9uT2JzZXJ2ZXJTeW1ib2xdICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBzZWxmW2F0dHJpYnV0ZU11dGF0aW9uT2JzZXJ2ZXJTeW1ib2xdID0gbmV3IE11dGF0aW9uT2JzZXJ2ZXIoZnVuY3Rpb24gKG11dGF0aW9ucywgb2JzZXJ2ZXIpIHtcbiAgICAgICAgZm9yIChjb25zdCBtdXRhdGlvbiBvZiBtdXRhdGlvbnMpIHtcbiAgICAgICAgICAgIGlmIChtdXRhdGlvbi50eXBlID09PSBcImF0dHJpYnV0ZXNcIikge1xuICAgICAgICAgICAgICAgIHNlbGYuYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKFxuICAgICAgICAgICAgICAgICAgICBtdXRhdGlvbi5hdHRyaWJ1dGVOYW1lLFxuICAgICAgICAgICAgICAgICAgICBtdXRhdGlvbi5vbGRWYWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgbXV0YXRpb24udGFyZ2V0LmdldEF0dHJpYnV0ZShtdXRhdGlvbi5hdHRyaWJ1dGVOYW1lKSxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICB0cnkge1xuICAgICAgICBzZWxmW2F0dHJpYnV0ZU11dGF0aW9uT2JzZXJ2ZXJTeW1ib2xdLm9ic2VydmUoc2VsZiwge1xuICAgICAgICAgICAgYXR0cmlidXRlczogdHJ1ZSxcbiAgICAgICAgICAgIGF0dHJpYnV0ZU9sZFZhbHVlOiB0cnVlLFxuICAgICAgICB9KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGFkZEF0dHJpYnV0ZVRva2VuKHNlbGYsIEFUVFJJQlVURV9FUlJPUk1FU1NBR0UsIGUudG9TdHJpbmcoKSk7XG4gICAgfVxufVxuXG4vKipcbiAqIEB0aGlzIEN1c3RvbUVsZW1lbnRcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge05vZGV9IG5vZGVcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIGNvbnRhaW5DaGlsZE5vZGUobm9kZSkge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgaWYgKHNlbGYuY29udGFpbnMobm9kZSkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBbLCBlXSBvZiBPYmplY3QuZW50cmllcyhzZWxmLmNoaWxkTm9kZXMpKSB7XG4gICAgICAgIGlmIChlLmNvbnRhaW5zKG5vZGUpKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnRhaW5DaGlsZE5vZGUuY2FsbChlLCBub2RlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4xNS4wXG4gKiBAcHJpdmF0ZVxuICogQHRoaXMgQ3VzdG9tRWxlbWVudFxuICovXG5mdW5jdGlvbiBpbml0T3B0aW9uT2JzZXJ2ZXIoKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICBsZXQgbGFzdERpc2FibGVkVmFsdWUgPSB1bmRlZmluZWQ7XG4gICAgc2VsZi5hdHRhY2hPYnNlcnZlcihcbiAgICAgICAgbmV3IE9ic2VydmVyKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IGZsYWcgPSBzZWxmLmdldE9wdGlvbihcImRpc2FibGVkXCIpO1xuXG4gICAgICAgICAgICBpZiAoZmxhZyA9PT0gbGFzdERpc2FibGVkVmFsdWUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxhc3REaXNhYmxlZFZhbHVlID0gZmxhZztcblxuICAgICAgICAgICAgaWYgKCEoc2VsZi5zaGFkb3dSb290IGluc3RhbmNlb2YgU2hhZG93Um9vdCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHF1ZXJ5ID1cbiAgICAgICAgICAgICAgICBcImJ1dHRvbiwgY29tbWFuZCwgZmllbGRzZXQsIGtleWdlbiwgb3B0Z3JvdXAsIG9wdGlvbiwgc2VsZWN0LCB0ZXh0YXJlYSwgaW5wdXQsIFtkYXRhLW1vbnN0ZXItb2JqZWN0bGlua11cIjtcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnRzID0gc2VsZi5zaGFkb3dSb290LnF1ZXJ5U2VsZWN0b3JBbGwocXVlcnkpO1xuXG4gICAgICAgICAgICBsZXQgbm9kZUxpc3Q7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIG5vZGVMaXN0ID0gbmV3IFNldChbLi4uZWxlbWVudHMsIC4uLmdldFNsb3R0ZWRFbGVtZW50cy5jYWxsKHNlbGYsIHF1ZXJ5KV0pO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIG5vZGVMaXN0ID0gZWxlbWVudHM7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiBbLi4ubm9kZUxpc3RdKSB7XG4gICAgICAgICAgICAgICAgaWYgKGZsYWcgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoQVRUUklCVVRFX0RJU0FCTEVELCBcIlwiKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnJlbW92ZUF0dHJpYnV0ZShBVFRSSUJVVEVfRElTQUJMRUQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSksXG4gICAgKTtcblxuICAgIHNlbGYuYXR0YWNoT2JzZXJ2ZXIoXG4gICAgICAgIG5ldyBPYnNlcnZlcihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAvLyBub3QgaW5pdGlhbGlzZWRcbiAgICAgICAgICAgIGlmICghaGFzT2JqZWN0TGluayhzZWxmLCBjdXN0b21FbGVtZW50VXBkYXRlckxpbmtTeW1ib2wpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gaW5mb3JtIGV2ZXJ5IGVsZW1lbnRcbiAgICAgICAgICAgIGNvbnN0IHVwZGF0ZXJzID0gZ2V0TGlua2VkT2JqZWN0cyhzZWxmLCBjdXN0b21FbGVtZW50VXBkYXRlckxpbmtTeW1ib2wpO1xuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGxpc3Qgb2YgdXBkYXRlcnMpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHVwZGF0ZXIgb2YgbGlzdCkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgZCA9IGNsb25lKHNlbGZbaW50ZXJuYWxTeW1ib2xdLmdldFJlYWxTdWJqZWN0KClbXCJvcHRpb25zXCJdKTtcbiAgICAgICAgICAgICAgICAgICAgT2JqZWN0LmFzc2lnbih1cGRhdGVyLmdldFN1YmplY3QoKSwgZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KSxcbiAgICApO1xuXG4gICAgLy8gZGlzYWJsZWRcbiAgICBzZWxmW2F0dHJpYnV0ZU9ic2VydmVyU3ltYm9sXVtBVFRSSUJVVEVfRElTQUJMRURdID0gKCkgPT4ge1xuICAgICAgICBpZiAoc2VsZi5oYXNBdHRyaWJ1dGUoQVRUUklCVVRFX0RJU0FCTEVEKSkge1xuICAgICAgICAgICAgc2VsZi5zZXRPcHRpb24oQVRUUklCVVRFX0RJU0FCTEVELCB0cnVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNlbGYuc2V0T3B0aW9uKEFUVFJJQlVURV9ESVNBQkxFRCwgdW5kZWZpbmVkKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICAvLyBkYXRhLW1vbnN0ZXItb3B0aW9uc1xuICAgIHNlbGZbYXR0cmlidXRlT2JzZXJ2ZXJTeW1ib2xdW0FUVFJJQlVURV9PUFRJT05TXSA9ICgpID0+IHtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IGdldE9wdGlvbnNGcm9tQXR0cmlidXRlcy5jYWxsKHNlbGYpO1xuICAgICAgICBpZiAoaXNPYmplY3Qob3B0aW9ucykgJiYgT2JqZWN0LmtleXMob3B0aW9ucykubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgc2VsZi5zZXRPcHRpb25zKG9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIC8vIGRhdGEtbW9uc3Rlci1vcHRpb25zLXNlbGVjdG9yXG4gICAgc2VsZlthdHRyaWJ1dGVPYnNlcnZlclN5bWJvbF1bQVRUUklCVVRFX09QVElPTlNfU0VMRUNUT1JdID0gKCkgPT4ge1xuICAgICAgICBjb25zdCBvcHRpb25zID0gZ2V0T3B0aW9uc0Zyb21TY3JpcHRUYWcuY2FsbChzZWxmKTtcbiAgICAgICAgaWYgKGlzT2JqZWN0KG9wdGlvbnMpICYmIE9iamVjdC5rZXlzKG9wdGlvbnMpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHNlbGYuc2V0T3B0aW9ucyhvcHRpb25zKTtcbiAgICAgICAgfVxuICAgIH07XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEByZXR1cm4ge29iamVjdH1cbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgb2JqZWN0XG4gKi9cbmZ1bmN0aW9uIGdldE9wdGlvbnNGcm9tU2NyaXB0VGFnKCkge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgaWYgKCFzZWxmLmhhc0F0dHJpYnV0ZShBVFRSSUJVVEVfT1BUSU9OU19TRUxFQ1RPUikpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cblxuICAgIGNvbnN0IG5vZGUgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHNlbGYuZ2V0QXR0cmlidXRlKEFUVFJJQlVURV9PUFRJT05TX1NFTEVDVE9SKSk7XG4gICAgaWYgKCEobm9kZSBpbnN0YW5jZW9mIEhUTUxTY3JpcHRFbGVtZW50KSkge1xuICAgICAgICBhZGRBdHRyaWJ1dGVUb2tlbihcbiAgICAgICAgICAgIHNlbGYsXG4gICAgICAgICAgICBBVFRSSUJVVEVfRVJST1JNRVNTQUdFLFxuICAgICAgICAgICAgYHRoZSBzZWxlY3RvciAke0FUVFJJQlVURV9PUFRJT05TX1NFTEVDVE9SfSBmb3Igb3B0aW9ucyB3YXMgc3BlY2lmaWVkICgke3NlbGYuZ2V0QXR0cmlidXRlKFxuICAgICAgICAgICAgICAgIEFUVFJJQlVURV9PUFRJT05TX1NFTEVDVE9SLFxuICAgICAgICAgICAgKX0pIGJ1dCBub3QgZm91bmQuYCxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cblxuICAgIGxldCBvYmogPSB7fTtcblxuICAgIHRyeSB7XG4gICAgICAgIG9iaiA9IHBhcnNlT3B0aW9uc0pTT04uY2FsbCh0aGlzLCBub2RlLnRleHRDb250ZW50LnRyaW0oKSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBhZGRBdHRyaWJ1dGVUb2tlbihcbiAgICAgICAgICAgIHNlbGYsXG4gICAgICAgICAgICBBVFRSSUJVVEVfRVJST1JNRVNTQUdFLFxuICAgICAgICAgICAgYHdoZW4gYW5hbHl6aW5nIHRoZSBjb25maWd1cmF0aW9uIGZyb20gdGhlIHNjcmlwdCB0YWcgdGhlcmUgd2FzIGFuIGVycm9yLiAke2V9YCxcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gb2JqO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcmV0dXJuIHtvYmplY3R9XG4gKi9cbmZ1bmN0aW9uIGdldE9wdGlvbnNGcm9tQXR0cmlidXRlcygpIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgIGlmICh0aGlzLmhhc0F0dHJpYnV0ZShBVFRSSUJVVEVfT1BUSU9OUykpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiBwYXJzZU9wdGlvbnNKU09OLmNhbGwoc2VsZiwgdGhpcy5nZXRBdHRyaWJ1dGUoQVRUUklCVVRFX09QVElPTlMpKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgYWRkQXR0cmlidXRlVG9rZW4oXG4gICAgICAgICAgICAgICAgc2VsZixcbiAgICAgICAgICAgICAgICBBVFRSSUJVVEVfRVJST1JNRVNTQUdFLFxuICAgICAgICAgICAgICAgIGB0aGUgb3B0aW9ucyBhdHRyaWJ1dGUgJHtBVFRSSUJVVEVfT1BUSU9OU30gZG9lcyBub3QgY29udGFpbiBhIHZhbGlkIGpzb24gZGVmaW5pdGlvbiAoYWN0dWFsOiAke3RoaXMuZ2V0QXR0cmlidXRlKFxuICAgICAgICAgICAgICAgICAgICBBVFRSSUJVVEVfT1BUSU9OUyxcbiAgICAgICAgICAgICAgICApfSkuJHtlfWAsXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHt9O1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0gZGF0YVxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBwYXJzZU9wdGlvbnNKU09OKGRhdGEpIHtcbiAgICBsZXQgb2JqID0ge307XG5cbiAgICBpZiAoIWlzU3RyaW5nKGRhdGEpKSB7XG4gICAgICAgIHJldHVybiBvYmo7XG4gICAgfVxuXG4gICAgLy8gdGhlIGNvbmZpZ3VyYXRpb24gY2FuIGJlIHNwZWNpZmllZCBhcyBhIGRhdGEgdXJsLlxuICAgIHRyeSB7XG4gICAgICAgIGxldCBkYXRhVXJsID0gcGFyc2VEYXRhVVJMKGRhdGEpO1xuICAgICAgICBkYXRhID0gZGF0YVVybC5jb250ZW50O1xuICAgIH0gY2F0Y2ggKGUpIHt9XG5cbiAgICB0cnkge1xuICAgICAgICBvYmogPSBKU09OLnBhcnNlKGRhdGEpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgdGhyb3cgZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsaWRhdGVPYmplY3Qob2JqKTtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHJldHVybiB7aW5pdEh0bWxDb250ZW50fVxuICovXG5mdW5jdGlvbiBpbml0SHRtbENvbnRlbnQoKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgbGV0IHRlbXBsYXRlID0gZmluZERvY3VtZW50VGVtcGxhdGUodGhpcy5jb25zdHJ1Y3Rvci5nZXRUYWcoKSk7XG4gICAgICAgIHRoaXMuYXBwZW5kQ2hpbGQodGVtcGxhdGUuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGxldCBodG1sID0gdGhpcy5nZXRPcHRpb24oXCJ0ZW1wbGF0ZXMubWFpblwiLCBcIlwiKTtcbiAgICAgICAgaWYgKGlzU3RyaW5nKGh0bWwpICYmIGh0bWwubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uc3QgbWFwcGluZyA9IHRoaXMuZ2V0T3B0aW9uKFwidGVtcGxhdGVNYXBwaW5nXCIsIHt9KTtcbiAgICAgICAgICAgIGlmIChpc09iamVjdChtYXBwaW5nKSkge1xuICAgICAgICAgICAgICAgIGh0bWwgPSBuZXcgRm9ybWF0dGVyKG1hcHBpbmcpLmZvcm1hdChodG1sKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuaW5uZXJIVE1MID0gaHRtbDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcmV0dXJuIHtDdXN0b21FbGVtZW50fVxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdGhpcyBDdXN0b21FbGVtZW50XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjE2LjBcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGFuIGluc3RhbmNlIG9mXG4gKi9cbmZ1bmN0aW9uIGluaXRDU1NTdHlsZXNoZWV0KCkge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgaWYgKCEodGhpcy5zaGFkb3dSb290IGluc3RhbmNlb2YgU2hhZG93Um9vdCkpIHtcbiAgICAgICAgcmV0dXJuIHNlbGY7XG4gICAgfVxuXG4gICAgY29uc3Qgc3R5bGVTaGVldCA9IHRoaXMuY29uc3RydWN0b3IuZ2V0Q1NTU3R5bGVTaGVldCgpO1xuXG4gICAgaWYgKHN0eWxlU2hlZXQgaW5zdGFuY2VvZiBDU1NTdHlsZVNoZWV0KSB7XG4gICAgICAgIGlmIChzdHlsZVNoZWV0LmNzc1J1bGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuc2hhZG93Um9vdC5hZG9wdGVkU3R5bGVTaGVldHMgPSBbc3R5bGVTaGVldF07XG4gICAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGlzQXJyYXkoc3R5bGVTaGVldCkpIHtcbiAgICAgICAgY29uc3QgYXNzaWduID0gW107XG4gICAgICAgIGZvciAobGV0IHMgb2Ygc3R5bGVTaGVldCkge1xuICAgICAgICAgICAgaWYgKGlzU3RyaW5nKHMpKSB7XG4gICAgICAgICAgICAgICAgbGV0IHRyaW1lZFN0eWxlU2hlZXQgPSBzLnRyaW0oKTtcbiAgICAgICAgICAgICAgICBpZiAodHJpbWVkU3R5bGVTaGVldCAhPT0gXCJcIikge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHlsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzdHlsZVwiKTtcbiAgICAgICAgICAgICAgICAgICAgc3R5bGUuaW5uZXJIVE1MID0gdHJpbWVkU3R5bGVTaGVldDtcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5zaGFkb3dSb290LnByZXBlbmQoc3R5bGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFsaWRhdGVJbnN0YW5jZShzLCBDU1NTdHlsZVNoZWV0KTtcblxuICAgICAgICAgICAgaWYgKHMuY3NzUnVsZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGFzc2lnbi5wdXNoKHMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGFzc2lnbi5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aGlzLnNoYWRvd1Jvb3QuYWRvcHRlZFN0eWxlU2hlZXRzID0gYXNzaWduO1xuICAgICAgICB9XG4gICAgfSBlbHNlIGlmIChpc1N0cmluZyhzdHlsZVNoZWV0KSkge1xuICAgICAgICBsZXQgdHJpbWVkU3R5bGVTaGVldCA9IHN0eWxlU2hlZXQudHJpbSgpO1xuICAgICAgICBpZiAodHJpbWVkU3R5bGVTaGVldCAhPT0gXCJcIikge1xuICAgICAgICAgICAgY29uc3Qgc3R5bGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3R5bGVcIik7XG4gICAgICAgICAgICBzdHlsZS5pbm5lckhUTUwgPSBzdHlsZVNoZWV0O1xuICAgICAgICAgICAgc2VsZi5zaGFkb3dSb290LnByZXBlbmQoc3R5bGUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHNlbGY7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEByZXR1cm4ge0N1c3RvbUVsZW1lbnR9XG4gKiBAdGhyb3dzIHtFcnJvcn0gaHRtbCBpcyBub3Qgc2V0LlxuICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRWxlbWVudC9hdHRhY2hTaGFkb3dcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS44LjBcbiAqL1xuZnVuY3Rpb24gaW5pdFNoYWRvd1Jvb3QoKSB7XG4gICAgbGV0IHRlbXBsYXRlO1xuICAgIGxldCBodG1sO1xuXG4gICAgdHJ5IHtcbiAgICAgICAgdGVtcGxhdGUgPSBmaW5kRG9jdW1lbnRUZW1wbGF0ZSh0aGlzLmNvbnN0cnVjdG9yLmdldFRhZygpKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGh0bWwgPSB0aGlzLmdldE9wdGlvbihcInRlbXBsYXRlcy5tYWluXCIsIFwiXCIpO1xuICAgICAgICBpZiAoIWlzU3RyaW5nKGh0bWwpIHx8IGh0bWwgPT09IHVuZGVmaW5lZCB8fCBodG1sID09PSBcIlwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJodG1sIGlzIG5vdCBzZXQuXCIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5hdHRhY2hTaGFkb3coe1xuICAgICAgICBtb2RlOiB0aGlzLmdldE9wdGlvbihcInNoYWRvd01vZGVcIiwgXCJvcGVuXCIpLFxuICAgICAgICBkZWxlZ2F0ZXNGb2N1czogdGhpcy5nZXRPcHRpb24oXCJkZWxlZ2F0ZXNGb2N1c1wiLCB0cnVlKSxcbiAgICB9KTtcblxuICAgIGlmICh0ZW1wbGF0ZSBpbnN0YW5jZW9mIFRlbXBsYXRlKSB7XG4gICAgICAgIHRoaXMuc2hhZG93Um9vdC5hcHBlbmRDaGlsZCh0ZW1wbGF0ZS5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBjb25zdCBtYXBwaW5nID0gdGhpcy5nZXRPcHRpb24oXCJ0ZW1wbGF0ZU1hcHBpbmdcIiwge30pO1xuICAgIGlmIChpc09iamVjdChtYXBwaW5nKSkge1xuICAgICAgICBodG1sID0gbmV3IEZvcm1hdHRlcihtYXBwaW5nKS5mb3JtYXQoaHRtbCk7XG4gICAgfVxuXG4gICAgdGhpcy5zaGFkb3dSb290LmlubmVySFRNTCA9IGh0bWw7XG4gICAgcmV0dXJuIHRoaXM7XG59XG5cbi8qKlxuICogVGhpcyBtZXRob2QgcmVnaXN0ZXJzIGEgbmV3IGVsZW1lbnQuIFRoZSBzdHJpbmcgcmV0dXJuZWQgYnkgYEN1c3RvbUVsZW1lbnQuZ2V0VGFnKClgIGlzIHVzZWQgYXMgdGhlIHRhZy5cbiAqXG4gKiBAcGFyYW0ge0N1c3RvbUVsZW1lbnR9IGVsZW1lbnRcbiAqIEByZXR1cm4ge3ZvaWR9XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjcuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHRocm93cyB7RE9NRXhjZXB0aW9ufSBGYWlsZWQgdG8gZXhlY3V0ZSAnZGVmaW5lJyBvbiAnQ3VzdG9tRWxlbWVudFJlZ2lzdHJ5JzogaXMgbm90IGEgdmFsaWQgY3VzdG9tIGVsZW1lbnQgbmFtZVxuICovXG5mdW5jdGlvbiByZWdpc3RlckN1c3RvbUVsZW1lbnQoZWxlbWVudCkge1xuICAgIHZhbGlkYXRlRnVuY3Rpb24oZWxlbWVudCk7XG4gICAgY29uc3QgY3VzdG9tRWxlbWVudHMgPSBnZXRHbG9iYWxPYmplY3QoXCJjdXN0b21FbGVtZW50c1wiKTtcbiAgICBpZiAoY3VzdG9tRWxlbWVudHMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJjdXN0b21FbGVtZW50cyBpcyBub3Qgc3VwcG9ydGVkLlwiKTtcbiAgICB9XG5cbiAgICBpZiAoY3VzdG9tRWxlbWVudHMuZ2V0KGVsZW1lbnQuZ2V0VGFnKCkpICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGN1c3RvbUVsZW1lbnRzLmRlZmluZShlbGVtZW50LmdldFRhZygpLCBlbGVtZW50KTtcbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IFBhdGhmaW5kZXIgfSBmcm9tIFwiLi4vLi4vZGF0YS9wYXRoZmluZGVyLm1qc1wiO1xuaW1wb3J0IHsgaXNGdW5jdGlvbiB9IGZyb20gXCIuLi8uLi90eXBlcy9pcy5tanNcIjtcbmltcG9ydCB7IGF0dHJpYnV0ZU9ic2VydmVyU3ltYm9sIH0gZnJvbSBcIi4uL2N1c3RvbWVsZW1lbnQubWpzXCI7XG5pbXBvcnQgeyBleHRyYWN0S2V5cyB9IGZyb20gXCIuL2V4dHJhY3Qta2V5cy5tanNcIjtcblxuZXhwb3J0IHsgaW5pdE9wdGlvbnNGcm9tQXR0cmlidXRlcyB9O1xuXG4vKipcbiAqIEluaXRpYWxpemVzIHRoZSBnaXZlbiBvcHRpb25zIG9iamVjdCBiYXNlZCBvbiB0aGUgYXR0cmlidXRlcyBvZiB0aGUgY3VycmVudCBET00gZWxlbWVudC5cbiAqIFRoZSBmdW5jdGlvbiBsb29rcyBmb3IgYXR0cmlidXRlcyB3aXRoIHRoZSBwcmVmaXggJ2RhdGEtbW9uc3Rlci1vcHRpb24tJywgYW5kIG1hcHMgdGhlbSB0b1xuICogcHJvcGVydGllcyBpbiB0aGUgb3B0aW9ucyBvYmplY3QuIEl0IHJlcGxhY2VzIHRoZSBkYXNoZXMgd2l0aCBkb3RzIHRvIGZvcm0gdGhlIHByb3BlcnR5IHBhdGguXG4gKiBGb3IgZXhhbXBsZSwgdGhlIGF0dHJpYnV0ZSAnZGF0YS1tb25zdGVyLW9wdGlvbi11cmwnIG1hcHMgdG8gdGhlICd1cmwnIHByb3BlcnR5IGluIHRoZSBvcHRpb25zIG9iamVjdC5cbiAqXG4gKiBXaXRoIHRoZSBtYXBwaW5nIHBhcmFtZXRlciwgdGhlIGF0dHJpYnV0ZSB2YWx1ZSBjYW4gYmUgbWFwcGVkIHRvIGEgZGlmZmVyZW50IHZhbHVlLlxuICogRm9yIGV4YW1wbGUsIHRoZSBhdHRyaWJ1dGUgJ2RhdGEtbW9uc3Rlci1vcHRpb24tZm9vJyBtYXBzIHRvIHRoZSAnYmFyJyBwcm9wZXJ0eSBpbiB0aGUgb3B0aW9ucyBvYmplY3QuXG4gKlxuICogVGhlIG1hcHBpbmcgb2JqZWN0IHdvdWxkIGxvb2sgbGlrZSB0aGlzOlxuICoge1xuICogICAgJ2Zvbyc6ICh2YWx1ZSkgPT4gdmFsdWUgKyAnYmFyJ1xuICogICAgLy8gdGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUgJ2RhdGEtbW9uc3Rlci1vcHRpb24tZm9vJyBpcyBhcHBlbmRlZCB3aXRoICdiYXInXG4gKiAgICAvLyBhbmQgYXNzaWduZWQgdG8gdGhlICdiYXInIHByb3BlcnR5IGluIHRoZSBvcHRpb25zIG9iamVjdC5cbiAqICAgIC8vIGUuZy4gPGRpdiBkYXRhLW1vbnN0ZXItb3B0aW9uLWZvbz1cImZvb1wiPjwvZGl2PlxuICogICAgJ2Jhci5iYXonOiAodmFsdWUpID0+IHZhbHVlICsgJ2JhcidcbiAqICAgIC8vIHRoZSB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlICdkYXRhLW1vbnN0ZXItb3B0aW9uLWJhci1iYXonIGlzIGFwcGVuZGVkIHdpdGggJ2JhcidcbiAqICAgIC8vIGFuZCBhc3NpZ25lZCB0byB0aGUgJ2Jhci5iYXonIHByb3BlcnR5IGluIHRoZSBvcHRpb25zIG9iamVjdC5cbiAqICAgIC8vIGUuZy4gPGRpdiBkYXRhLW1vbnN0ZXItb3B0aW9uLWJhci1iYXo9XCJmb29cIj48L2Rpdj5cbiAqIH1cbiAqXG4gKiBAc2luY2UgMy4zOC4wXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50IC0gVGhlIERPTSBlbGVtZW50IHRvIGJlIHVzZWQgYXMgdGhlIHNvdXJjZSBvZiB0aGUgYXR0cmlidXRlcy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gVGhlIG9wdGlvbnMgb2JqZWN0IHRvIGJlIGluaXRpYWxpemVkLlxuICogQHBhcmFtIHtPYmplY3R9IG1hcHBpbmcgLSBBIG1hcHBpbmcgYmV0d2VlbiB0aGUgYXR0cmlidXRlIHZhbHVlIGFuZCB0aGUgcHJvcGVydHkgdmFsdWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gcHJlZml4IC0gVGhlIHByZWZpeCBvZiB0aGUgYXR0cmlidXRlcyB0byBiZSBjb25zaWRlcmVkLlxuICogQHJldHVybnMge09iamVjdH0gLSBUaGUgaW5pdGlhbGl6ZWQgb3B0aW9ucyBvYmplY3QuXG4gKiBAdGhpcyBIVE1MRWxlbWVudCAtIFRoZSBjb250ZXh0IG9mIHRoZSBET00gZWxlbWVudC5cbiAqL1xuZnVuY3Rpb24gaW5pdE9wdGlvbnNGcm9tQXR0cmlidXRlcyhlbGVtZW50LCBvcHRpb25zLCBtYXBwaW5nID0ge30sIHByZWZpeCA9IFwiZGF0YS1tb25zdGVyLW9wdGlvbi1cIikge1xuICAgIGlmICghKGVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpIHJldHVybiBvcHRpb25zO1xuICAgIGlmICghZWxlbWVudC5oYXNBdHRyaWJ1dGVzKCkpIHJldHVybiBvcHRpb25zO1xuXG4gICAgY29uc3Qga2V5TWFwID0gZXh0cmFjdEtleXMob3B0aW9ucyk7XG5cbiAgICBjb25zdCBmaW5kZXIgPSBuZXcgUGF0aGZpbmRlcihvcHRpb25zKTtcblxuICAgIGVsZW1lbnQuZ2V0QXR0cmlidXRlTmFtZXMoKS5mb3JFYWNoKChuYW1lKSA9PiB7XG4gICAgICAgIGlmICghbmFtZS5zdGFydHNXaXRoKHByZWZpeCkpIHJldHVybjtcblxuICAgICAgICAvLyBjaGVjayBpZiB0aGUgYXR0cmlidXRlIG5hbWUgaXMgYSB2YWxpZCBvcHRpb24uXG4gICAgICAgIC8vIHRoZSBtYXBwaW5nIGJldHdlZW4gdGhlIGF0dHJpYnV0ZSBpcyBzaW1wbGUuIFRoZSBkYXNoIGlzIHJlcGxhY2VkIGJ5IGEgZG90LlxuICAgICAgICAvLyBlLmcuIGRhdGEtbW9uc3Rlci11cmwgPT4gdXJsXG4gICAgICAgIGNvbnN0IG9wdGlvbk5hbWUgPSBrZXlNYXAuZ2V0KG5hbWUuc3Vic3RyaW5nKHByZWZpeC5sZW5ndGgpLnRvTG93ZXJDYXNlKCkpO1xuICAgICAgICBpZiAoIWZpbmRlci5leGlzdHMob3B0aW9uTmFtZSkpIHJldHVybjtcblxuICAgICAgICBpZiAoZWxlbWVudC5oYXNBdHRyaWJ1dGUobmFtZSkpIHtcbiAgICAgICAgICAgIGxldCB2YWx1ZSA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKG5hbWUpO1xuICAgICAgICAgICAgaWYgKG1hcHBpbmcuaGFzT3duUHJvcGVydHkob3B0aW9uTmFtZSkgJiYgaXNGdW5jdGlvbihtYXBwaW5nW29wdGlvbk5hbWVdKSkge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gbWFwcGluZ1tvcHRpb25OYW1lXSh2YWx1ZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCBvcHRpb25WYWx1ZSA9IGZpbmRlci5nZXRWaWEob3B0aW9uTmFtZSk7XG4gICAgICAgICAgICBpZiAob3B0aW9uVmFsdWUgPT09IG51bGwgfHwgb3B0aW9uVmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIG9wdGlvblZhbHVlID0gdmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICBjb25zdCB0eXBlT2ZPcHRpb25WYWx1ZSA9IHR5cGVvZiBvcHRpb25WYWx1ZTtcbiAgICAgICAgICAgIGlmIChvcHRpb25WYWx1ZSA9PT0gbnVsbCB8fCBvcHRpb25WYWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBudWxsO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlT2ZPcHRpb25WYWx1ZSA9PT0gXCJib29sZWFuXCIpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IHZhbHVlID09PSBcInRydWVcIjtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZU9mT3B0aW9uVmFsdWUgPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IE51bWJlcih2YWx1ZSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVPZk9wdGlvblZhbHVlID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBTdHJpbmcodmFsdWUpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlT2ZPcHRpb25WYWx1ZSA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gSlNPTi5wYXJzZSh2YWx1ZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZpbmRlci5zZXRWaWEob3B0aW9uTmFtZSwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gb3B0aW9ucztcbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGdldERvY3VtZW50LCBnZXRXaW5kb3cgfSBmcm9tIFwiLi91dGlsLm1qc1wiO1xuXG5leHBvcnQgeyBkb21SZWFkeSwgd2luZG93UmVhZHkgfTtcblxuLyoqXG4gKiBUaGlzIHZhcmlhYmxlIGlzIGEgcHJvbWlzZSB0aGF0IGlzIGZ1bGZpbGxlZCBhcyBzb29uIGFzIHRoZSBkb20gaXMgYXZhaWxhYmxlLlxuICpcbiAqIFRoZSBET01Db250ZW50TG9hZGVkIGV2ZW50IGlzIGZpcmVkIHdoZW4gdGhlIG9yaWdpbmFsIEhUTUwgZG9jdW1lbnQgaXMgZnVsbHkgbG9hZGVkIGFuZCBwYXJzZWRcbiAqIHdpdGhvdXQgd2FpdGluZyBmb3Igc3R5bGVzaGVldHMsIGltYWdlcywgYW5kIHN1YmZyYW1lcyB0byBmaW5pc2ggbG9hZGluZy5cbiAqXG4gKiBkb2N1bWVudC5yZWFkeVN0YXRlIGNoYW5nZXMgdG8gaW50ZXJhY3RpdmVcbiAqIHdpbmRvdydzIERPTUNvbnRlbnRMb2FkZWQgZXZlbnQgZ2V0cyBmaXJlZFxuICogZG9jdW1lbnQucmVhZHlTdGF0ZSBjaGFuZ2VzIHRvIGNvbXBsZXRlXG4gKiB3aW5kb3cncyBsb2FkIGV2ZW50IGdldHMgZmlyZWQgbG9hZFxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMzEuMFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAc3VtbWFyeSB2YXJpYWJsZSB0byBjaGVjayBpZiBkb20gaXMgcmVhZHlcbiAqIEB0eXBlIHtQcm9taXNlfVxuICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRG9jdW1lbnQvRE9NQ29udGVudExvYWRlZF9ldmVudFxuICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRG9jdW1lbnQvcmVhZHlTdGF0ZVxuICovXG5jb25zdCBkb21SZWFkeSA9IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgY29uc3QgZG9jdW1lbnQgPSBnZXREb2N1bWVudCgpO1xuXG4gICAgaWYgKGRvY3VtZW50LnJlYWR5U3RhdGUgPT09IFwibG9hZGluZ1wiKSB7XG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJET01Db250ZW50TG9hZGVkXCIsIHJlc29sdmUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc29sdmUoKTtcbiAgICB9XG59KTtcblxuLyoqXG4gKiBUaGlzIHZhcmlhYmxlIGlzIGEgcHJvbWlzZSB0aGF0IGlzIGZ1bGZpbGxlZCBhcyBzb29uIGFzIHRoZSB3aW5kb3dzIGlzIGF2YWlsYWJsZS5cbiAqXG4gKiBUaGUgbG9hZCBldmVudCBmaXJlcyB3aGVuIHRoZSBlbnRpcmUgcGFnZSBpcyBsb2FkZWQsIGluY2x1ZGluZyBhbGwgZGVwZW5kZW50IHJlc291cmNlcyBzdWNoIGFzIHN0eWxlc2hlZXRzLFxuICogYXNzZXRzLCBhbmQgaW1hZ2VzLiBVbmxpa2UgRE9NQ29udGVudExvYWRlZCwgd2hpY2ggZmlyZXMgYXMgc29vbiBhcyB0aGUgRE9NIG9mIHRoZSBwYWdlIGlzIGxvYWRlZCxcbiAqIHdpdGhvdXQgd2FpdGluZyBmb3IgdGhlIHJlc291cmNlcyB0byBmaW5pc2ggbG9hZGluZy5cbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjMxLjBcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQHN1bW1hcnkgdmFyaWFibGUgdG8gY2hlY2sgaWYgd2luZG93IGlzIHJlYWR5XG4gKiBAdHlwZSB7UHJvbWlzZX1cbiAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1dpbmRvdy9sb2FkX2V2ZW50XG4gKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9Eb2N1bWVudC9yZWFkeVN0YXRlXG4gKi9cbmNvbnN0IHdpbmRvd1JlYWR5ID0gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICBjb25zdCBkb2N1bWVudCA9IGdldERvY3VtZW50KCk7XG4gICAgY29uc3Qgd2luZG93ID0gZ2V0V2luZG93KCk7XG5cbiAgICBpZiAoZG9jdW1lbnQucmVhZHlTdGF0ZSA9PT0gXCJjb21wbGV0ZVwiKSB7XG4gICAgICAgIHJlc29sdmUoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcImxvYWRcIiwgcmVzb2x2ZSk7XG4gICAgfVxufSk7XG4iLCAiKGZ1bmN0aW9uICgpIHtcbiAgICAndXNlIHN0cmljdCc7XG5cbiAgICBjb25zdCByZWZNYXAgPSBuZXcgV2Vha01hcCgpO1xuICAgIGNvbnN0IHZhbGlkaXR5TWFwID0gbmV3IFdlYWtNYXAoKTtcbiAgICBjb25zdCBoaWRkZW5JbnB1dE1hcCA9IG5ldyBXZWFrTWFwKCk7XG4gICAgY29uc3QgaW50ZXJuYWxzTWFwID0gbmV3IFdlYWtNYXAoKTtcbiAgICBjb25zdCB2YWxpZGF0aW9uTWVzc2FnZU1hcCA9IG5ldyBXZWFrTWFwKCk7XG4gICAgY29uc3QgZm9ybXNNYXAgPSBuZXcgV2Vha01hcCgpO1xuICAgIGNvbnN0IHNoYWRvd0hvc3RzTWFwID0gbmV3IFdlYWtNYXAoKTtcbiAgICBjb25zdCBmb3JtRWxlbWVudHNNYXAgPSBuZXcgV2Vha01hcCgpO1xuICAgIGNvbnN0IHJlZlZhbHVlTWFwID0gbmV3IFdlYWtNYXAoKTtcbiAgICBjb25zdCB1cGdyYWRlTWFwID0gbmV3IFdlYWtNYXAoKTtcbiAgICBjb25zdCBzaGFkb3dSb290TWFwID0gbmV3IFdlYWtNYXAoKTtcbiAgICBjb25zdCB2YWxpZGF0aW9uQW5jaG9yTWFwID0gbmV3IFdlYWtNYXAoKTtcbiAgICBjb25zdCBkb2N1bWVudEZyYWdtZW50TWFwID0gbmV3IFdlYWtNYXAoKTtcbiAgICBjb25zdCBjb25uZWN0ZWRDYWxsYmFja01hcCA9IG5ldyBXZWFrTWFwKCk7XG4gICAgY29uc3QgdmFsaWRpdHlVcGdyYWRlTWFwID0gbmV3IFdlYWtNYXAoKTtcblxuICAgIGNvbnN0IGFvbSA9IHtcbiAgICAgICAgYXJpYUF0b21pYzogJ2FyaWEtYXRvbWljJyxcbiAgICAgICAgYXJpYUF1dG9Db21wbGV0ZTogJ2FyaWEtYXV0b2NvbXBsZXRlJyxcbiAgICAgICAgYXJpYUJ1c3k6ICdhcmlhLWJ1c3knLFxuICAgICAgICBhcmlhQ2hlY2tlZDogJ2FyaWEtY2hlY2tlZCcsXG4gICAgICAgIGFyaWFDb2xDb3VudDogJ2FyaWEtY29sY291bnQnLFxuICAgICAgICBhcmlhQ29sSW5kZXg6ICdhcmlhLWNvbGluZGV4JyxcbiAgICAgICAgYXJpYUNvbEluZGV4VGV4dDogJ2FyaWEtY29saW5kZXh0ZXh0JyxcbiAgICAgICAgYXJpYUNvbFNwYW46ICdhcmlhLWNvbHNwYW4nLFxuICAgICAgICBhcmlhQ3VycmVudDogJ2FyaWEtY3VycmVudCcsXG4gICAgICAgIGFyaWFEaXNhYmxlZDogJ2FyaWEtZGlzYWJsZWQnLFxuICAgICAgICBhcmlhRXhwYW5kZWQ6ICdhcmlhLWV4cGFuZGVkJyxcbiAgICAgICAgYXJpYUhhc1BvcHVwOiAnYXJpYS1oYXNwb3B1cCcsXG4gICAgICAgIGFyaWFIaWRkZW46ICdhcmlhLWhpZGRlbicsXG4gICAgICAgIGFyaWFJbnZhbGlkOiAnYXJpYS1pbnZhbGlkJyxcbiAgICAgICAgYXJpYUtleVNob3J0Y3V0czogJ2FyaWEta2V5c2hvcnRjdXRzJyxcbiAgICAgICAgYXJpYUxhYmVsOiAnYXJpYS1sYWJlbCcsXG4gICAgICAgIGFyaWFMZXZlbDogJ2FyaWEtbGV2ZWwnLFxuICAgICAgICBhcmlhTGl2ZTogJ2FyaWEtbGl2ZScsXG4gICAgICAgIGFyaWFNb2RhbDogJ2FyaWEtbW9kYWwnLFxuICAgICAgICBhcmlhTXVsdGlMaW5lOiAnYXJpYS1tdWx0aWxpbmUnLFxuICAgICAgICBhcmlhTXVsdGlTZWxlY3RhYmxlOiAnYXJpYS1tdWx0aXNlbGVjdGFibGUnLFxuICAgICAgICBhcmlhT3JpZW50YXRpb246ICdhcmlhLW9yaWVudGF0aW9uJyxcbiAgICAgICAgYXJpYVBsYWNlaG9sZGVyOiAnYXJpYS1wbGFjZWhvbGRlcicsXG4gICAgICAgIGFyaWFQb3NJblNldDogJ2FyaWEtcG9zaW5zZXQnLFxuICAgICAgICBhcmlhUHJlc3NlZDogJ2FyaWEtcHJlc3NlZCcsXG4gICAgICAgIGFyaWFSZWFkT25seTogJ2FyaWEtcmVhZG9ubHknLFxuICAgICAgICBhcmlhUmVsZXZhbnQ6ICdhcmlhLXJlbGV2YW50JyxcbiAgICAgICAgYXJpYVJlcXVpcmVkOiAnYXJpYS1yZXF1aXJlZCcsXG4gICAgICAgIGFyaWFSb2xlRGVzY3JpcHRpb246ICdhcmlhLXJvbGVkZXNjcmlwdGlvbicsXG4gICAgICAgIGFyaWFSb3dDb3VudDogJ2FyaWEtcm93Y291bnQnLFxuICAgICAgICBhcmlhUm93SW5kZXg6ICdhcmlhLXJvd2luZGV4JyxcbiAgICAgICAgYXJpYVJvd0luZGV4VGV4dDogJ2FyaWEtcm93aW5kZXh0ZXh0JyxcbiAgICAgICAgYXJpYVJvd1NwYW46ICdhcmlhLXJvd3NwYW4nLFxuICAgICAgICBhcmlhU2VsZWN0ZWQ6ICdhcmlhLXNlbGVjdGVkJyxcbiAgICAgICAgYXJpYVNldFNpemU6ICdhcmlhLXNldHNpemUnLFxuICAgICAgICBhcmlhU29ydDogJ2FyaWEtc29ydCcsXG4gICAgICAgIGFyaWFWYWx1ZU1heDogJ2FyaWEtdmFsdWVtYXgnLFxuICAgICAgICBhcmlhVmFsdWVNaW46ICdhcmlhLXZhbHVlbWluJyxcbiAgICAgICAgYXJpYVZhbHVlTm93OiAnYXJpYS12YWx1ZW5vdycsXG4gICAgICAgIGFyaWFWYWx1ZVRleHQ6ICdhcmlhLXZhbHVldGV4dCcsXG4gICAgICAgIHJvbGU6ICdyb2xlJ1xuICAgIH07XG4gICAgY29uc3QgaW5pdEFvbSA9IChyZWYsIGludGVybmFscykgPT4ge1xuICAgICAgICBmb3IgKGxldCBrZXkgaW4gYW9tKSB7XG4gICAgICAgICAgICBpbnRlcm5hbHNba2V5XSA9IG51bGw7XG4gICAgICAgICAgICBsZXQgY2xvc3VyZVZhbHVlID0gbnVsbDtcbiAgICAgICAgICAgIGNvbnN0IGF0dHJpYnV0ZU5hbWUgPSBhb21ba2V5XTtcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShpbnRlcm5hbHMsIGtleSwge1xuICAgICAgICAgICAgICAgIGdldCgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNsb3N1cmVWYWx1ZTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHNldCh2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICBjbG9zdXJlVmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlZi5pc0Nvbm5lY3RlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVmLnNldEF0dHJpYnV0ZShhdHRyaWJ1dGVOYW1lLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB1cGdyYWRlTWFwLnNldChyZWYsIGludGVybmFscyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBmdW5jdGlvbiBpbml0Tm9kZShub2RlKSB7XG4gICAgICAgIGNvbnN0IGludGVybmFscyA9IGludGVybmFsc01hcC5nZXQobm9kZSk7XG4gICAgICAgIGNvbnN0IHsgZm9ybSB9ID0gaW50ZXJuYWxzO1xuICAgICAgICBpbml0Rm9ybShub2RlLCBmb3JtLCBpbnRlcm5hbHMpO1xuICAgICAgICBpbml0TGFiZWxzKG5vZGUsIGludGVybmFscy5sYWJlbHMpO1xuICAgIH1cbiAgICBjb25zdCB3YWxrRmllbGRzZXQgPSAobm9kZSwgZmlyc3RSZW5kZXIgPSBmYWxzZSkgPT4ge1xuICAgICAgICBjb25zdCB3YWxrZXIgPSBkb2N1bWVudC5jcmVhdGVUcmVlV2Fsa2VyKG5vZGUsIE5vZGVGaWx0ZXIuU0hPV19FTEVNRU5ULCB7XG4gICAgICAgICAgICBhY2NlcHROb2RlKG5vZGUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxzTWFwLmhhcyhub2RlKSA/XG4gICAgICAgICAgICAgICAgICAgIE5vZGVGaWx0ZXIuRklMVEVSX0FDQ0VQVCA6IE5vZGVGaWx0ZXIuRklMVEVSX1NLSVA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBsZXQgY3VycmVudCA9IHdhbGtlci5uZXh0Tm9kZSgpO1xuICAgICAgICBjb25zdCBpc0NhbGxOZWNlc3NhcnkgPSAoIWZpcnN0UmVuZGVyIHx8IG5vZGUuZGlzYWJsZWQpO1xuICAgICAgICB3aGlsZSAoY3VycmVudCkge1xuICAgICAgICAgICAgaWYgKGN1cnJlbnQuZm9ybURpc2FibGVkQ2FsbGJhY2sgJiYgaXNDYWxsTmVjZXNzYXJ5KSB7XG4gICAgICAgICAgICAgICAgc2V0RGlzYWJsZWQoY3VycmVudCwgbm9kZS5kaXNhYmxlZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjdXJyZW50ID0gd2Fsa2VyLm5leHROb2RlKCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIGNvbnN0IGRpc2FibGVkT3JOYW1lT2JzZXJ2ZXJDb25maWcgPSB7IGF0dHJpYnV0ZXM6IHRydWUsIGF0dHJpYnV0ZUZpbHRlcjogWydkaXNhYmxlZCcsICduYW1lJ10gfTtcbiAgICBjb25zdCBkaXNhYmxlZE9yTmFtZU9ic2VydmVyID0gbXV0YXRpb25PYnNlcnZlckV4aXN0cygpID8gbmV3IE11dGF0aW9uT2JzZXJ2ZXIoKG11dGF0aW9uc0xpc3QpID0+IHtcbiAgICAgICAgZm9yIChjb25zdCBtdXRhdGlvbiBvZiBtdXRhdGlvbnNMaXN0KSB7XG4gICAgICAgICAgICBjb25zdCB0YXJnZXQgPSBtdXRhdGlvbi50YXJnZXQ7XG4gICAgICAgICAgICBpZiAobXV0YXRpb24uYXR0cmlidXRlTmFtZSA9PT0gJ2Rpc2FibGVkJykge1xuICAgICAgICAgICAgICAgIGlmICh0YXJnZXQuY29uc3RydWN0b3JbJ2Zvcm1Bc3NvY2lhdGVkJ10pIHtcbiAgICAgICAgICAgICAgICAgICAgc2V0RGlzYWJsZWQodGFyZ2V0LCB0YXJnZXQuaGFzQXR0cmlidXRlKCdkaXNhYmxlZCcpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodGFyZ2V0LmxvY2FsTmFtZSA9PT0gJ2ZpZWxkc2V0Jykge1xuICAgICAgICAgICAgICAgICAgICB3YWxrRmllbGRzZXQodGFyZ2V0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobXV0YXRpb24uYXR0cmlidXRlTmFtZSA9PT0gJ25hbWUnKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRhcmdldC5jb25zdHJ1Y3RvclsnZm9ybUFzc29jaWF0ZWQnXSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBpbnRlcm5hbHMgPSBpbnRlcm5hbHNNYXAuZ2V0KHRhcmdldCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gcmVmVmFsdWVNYXAuZ2V0KHRhcmdldCk7XG4gICAgICAgICAgICAgICAgICAgIGludGVybmFscy5zZXRGb3JtVmFsdWUodmFsdWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0pIDoge307XG4gICAgZnVuY3Rpb24gb2JzZXJ2ZXJDYWxsYmFjayhtdXRhdGlvbkxpc3QpIHtcbiAgICAgICAgbXV0YXRpb25MaXN0LmZvckVhY2gobXV0YXRpb25SZWNvcmQgPT4ge1xuICAgICAgICAgICAgY29uc3QgeyBhZGRlZE5vZGVzLCByZW1vdmVkTm9kZXMgfSA9IG11dGF0aW9uUmVjb3JkO1xuICAgICAgICAgICAgY29uc3QgYWRkZWQgPSBBcnJheS5mcm9tKGFkZGVkTm9kZXMpO1xuICAgICAgICAgICAgY29uc3QgcmVtb3ZlZCA9IEFycmF5LmZyb20ocmVtb3ZlZE5vZGVzKTtcbiAgICAgICAgICAgIGFkZGVkLmZvckVhY2gobm9kZSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGludGVybmFsc01hcC5oYXMobm9kZSkgJiYgbm9kZS5jb25zdHJ1Y3RvclsnZm9ybUFzc29jaWF0ZWQnXSkge1xuICAgICAgICAgICAgICAgICAgICBpbml0Tm9kZShub2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHVwZ3JhZGVNYXAuaGFzKG5vZGUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGludGVybmFscyA9IHVwZ3JhZGVNYXAuZ2V0KG5vZGUpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhb21LZXlzID0gT2JqZWN0LmtleXMoYW9tKTtcbiAgICAgICAgICAgICAgICAgICAgYW9tS2V5c1xuICAgICAgICAgICAgICAgICAgICAgICAgLmZpbHRlcihrZXkgPT4gaW50ZXJuYWxzW2tleV0gIT09IG51bGwpXG4gICAgICAgICAgICAgICAgICAgICAgICAuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5zZXRBdHRyaWJ1dGUoYW9tW2tleV0sIGludGVybmFsc1trZXldKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHVwZ3JhZGVNYXAuZGVsZXRlKG5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodmFsaWRpdHlVcGdyYWRlTWFwLmhhcyhub2RlKSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBpbnRlcm5hbHMgPSB2YWxpZGl0eVVwZ3JhZGVNYXAuZ2V0KG5vZGUpO1xuICAgICAgICAgICAgICAgICAgICBub2RlLnNldEF0dHJpYnV0ZSgnaW50ZXJuYWxzLXZhbGlkJywgaW50ZXJuYWxzLnZhbGlkaXR5LnZhbGlkLnRvU3RyaW5nKCkpO1xuICAgICAgICAgICAgICAgICAgICBub2RlLnNldEF0dHJpYnV0ZSgnaW50ZXJuYWxzLWludmFsaWQnLCAoIWludGVybmFscy52YWxpZGl0eS52YWxpZCkudG9TdHJpbmcoKSk7XG4gICAgICAgICAgICAgICAgICAgIG5vZGUuc2V0QXR0cmlidXRlKCdhcmlhLWludmFsaWQnLCAoIWludGVybmFscy52YWxpZGl0eS52YWxpZCkudG9TdHJpbmcoKSk7XG4gICAgICAgICAgICAgICAgICAgIHZhbGlkaXR5VXBncmFkZU1hcC5kZWxldGUobm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChub2RlLmxvY2FsTmFtZSA9PT0gJ2Zvcm0nKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGZvcm1FbGVtZW50cyA9IGZvcm1FbGVtZW50c01hcC5nZXQobm9kZSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHdhbGtlciA9IGRvY3VtZW50LmNyZWF0ZVRyZWVXYWxrZXIobm9kZSwgTm9kZUZpbHRlci5TSE9XX0VMRU1FTlQsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFjY2VwdE5vZGUobm9kZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbHNNYXAuaGFzKG5vZGUpICYmICEoZm9ybUVsZW1lbnRzICYmIGZvcm1FbGVtZW50cy5oYXMobm9kZSkpID9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTm9kZUZpbHRlci5GSUxURVJfQUNDRVBUIDogTm9kZUZpbHRlci5GSUxURVJfU0tJUDtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIGxldCBjdXJyZW50ID0gd2Fsa2VyLm5leHROb2RlKCk7XG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChjdXJyZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpbml0Tm9kZShjdXJyZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnQgPSB3YWxrZXIubmV4dE5vZGUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAobm9kZS5sb2NhbE5hbWUgPT09ICdmaWVsZHNldCcpIHtcbiAgICAgICAgICAgICAgICAgICAgZGlzYWJsZWRPck5hbWVPYnNlcnZlci5vYnNlcnZlPy4obm9kZSwgZGlzYWJsZWRPck5hbWVPYnNlcnZlckNvbmZpZyk7XG4gICAgICAgICAgICAgICAgICAgIHdhbGtGaWVsZHNldChub2RlLCB0cnVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJlbW92ZWQuZm9yRWFjaChub2RlID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBpbnRlcm5hbHMgPSBpbnRlcm5hbHNNYXAuZ2V0KG5vZGUpO1xuICAgICAgICAgICAgICAgIGlmIChpbnRlcm5hbHMgJiYgaGlkZGVuSW5wdXRNYXAuZ2V0KGludGVybmFscykpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVtb3ZlSGlkZGVuSW5wdXRzKGludGVybmFscyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChzaGFkb3dIb3N0c01hcC5oYXMobm9kZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2JzZXJ2ZXIgPSBzaGFkb3dIb3N0c01hcC5nZXQobm9kZSk7XG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGZyYWdtZW50T2JzZXJ2ZXJDYWxsYmFjayhtdXRhdGlvbkxpc3QpIHtcbiAgICAgICAgbXV0YXRpb25MaXN0LmZvckVhY2gobXV0YXRpb24gPT4ge1xuICAgICAgICAgICAgY29uc3QgeyByZW1vdmVkTm9kZXMgfSA9IG11dGF0aW9uO1xuICAgICAgICAgICAgcmVtb3ZlZE5vZGVzLmZvckVhY2gobm9kZSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb2JzZXJ2ZXIgPSBkb2N1bWVudEZyYWdtZW50TWFwLmdldChtdXRhdGlvbi50YXJnZXQpO1xuICAgICAgICAgICAgICAgIGlmIChpbnRlcm5hbHNNYXAuaGFzKG5vZGUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHVwZ3JhZGVJbnRlcm5hbHMobm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG9ic2VydmVyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgY29uc3QgZGVmZXJVcGdyYWRlID0gKGZyYWdtZW50KSA9PiB7XG4gICAgICAgIGNvbnN0IG9ic2VydmVyID0gbmV3IE11dGF0aW9uT2JzZXJ2ZXIoZnJhZ21lbnRPYnNlcnZlckNhbGxiYWNrKTtcbiAgICAgICAgb2JzZXJ2ZXIub2JzZXJ2ZT8uKGZyYWdtZW50LCB7IGNoaWxkTGlzdDogdHJ1ZSB9KTtcbiAgICAgICAgZG9jdW1lbnRGcmFnbWVudE1hcC5zZXQoZnJhZ21lbnQsIG9ic2VydmVyKTtcbiAgICB9O1xuICAgIG11dGF0aW9uT2JzZXJ2ZXJFeGlzdHMoKSA/IG5ldyBNdXRhdGlvbk9ic2VydmVyKG9ic2VydmVyQ2FsbGJhY2spIDoge307XG4gICAgY29uc3Qgb2JzZXJ2ZXJDb25maWcgPSB7XG4gICAgICAgIGNoaWxkTGlzdDogdHJ1ZSxcbiAgICAgICAgc3VidHJlZTogdHJ1ZVxuICAgIH07XG5cbiAgICBjb25zdCBzZXREaXNhYmxlZCA9IChyZWYsIGRpc2FibGVkKSA9PiB7XG4gICAgICAgIHJlZi50b2dnbGVBdHRyaWJ1dGUoJ2ludGVybmFscy1kaXNhYmxlZCcsIGRpc2FibGVkKTtcbiAgICAgICAgaWYgKGRpc2FibGVkKSB7XG4gICAgICAgICAgICByZWYuc2V0QXR0cmlidXRlKCdhcmlhLWRpc2FibGVkJywgJ3RydWUnKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJlZi5yZW1vdmVBdHRyaWJ1dGUoJ2FyaWEtZGlzYWJsZWQnKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVmLmZvcm1EaXNhYmxlZENhbGxiYWNrKSB7XG4gICAgICAgICAgICByZWYuZm9ybURpc2FibGVkQ2FsbGJhY2suYXBwbHkocmVmLCBbZGlzYWJsZWRdKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgY29uc3QgcmVtb3ZlSGlkZGVuSW5wdXRzID0gKGludGVybmFscykgPT4ge1xuICAgICAgICBjb25zdCBoaWRkZW5JbnB1dHMgPSBoaWRkZW5JbnB1dE1hcC5nZXQoaW50ZXJuYWxzKTtcbiAgICAgICAgaGlkZGVuSW5wdXRzLmZvckVhY2goaGlkZGVuSW5wdXQgPT4ge1xuICAgICAgICAgICAgaGlkZGVuSW5wdXQucmVtb3ZlKCk7XG4gICAgICAgIH0pO1xuICAgICAgICBoaWRkZW5JbnB1dE1hcC5zZXQoaW50ZXJuYWxzLCBbXSk7XG4gICAgfTtcbiAgICBjb25zdCBjcmVhdGVIaWRkZW5JbnB1dCA9IChyZWYsIGludGVybmFscykgPT4ge1xuICAgICAgICBjb25zdCBpbnB1dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lucHV0Jyk7XG4gICAgICAgIGlucHV0LnR5cGUgPSAnaGlkZGVuJztcbiAgICAgICAgaW5wdXQubmFtZSA9IHJlZi5nZXRBdHRyaWJ1dGUoJ25hbWUnKTtcbiAgICAgICAgcmVmLmFmdGVyKGlucHV0KTtcbiAgICAgICAgaGlkZGVuSW5wdXRNYXAuZ2V0KGludGVybmFscykucHVzaChpbnB1dCk7XG4gICAgICAgIHJldHVybiBpbnB1dDtcbiAgICB9O1xuICAgIGNvbnN0IGluaXRSZWYgPSAocmVmLCBpbnRlcm5hbHMpID0+IHtcbiAgICAgICAgaGlkZGVuSW5wdXRNYXAuc2V0KGludGVybmFscywgW10pO1xuICAgICAgICBkaXNhYmxlZE9yTmFtZU9ic2VydmVyLm9ic2VydmU/LihyZWYsIGRpc2FibGVkT3JOYW1lT2JzZXJ2ZXJDb25maWcpO1xuICAgIH07XG4gICAgY29uc3QgaW5pdExhYmVscyA9IChyZWYsIGxhYmVscykgPT4ge1xuICAgICAgICBpZiAobGFiZWxzLmxlbmd0aCkge1xuICAgICAgICAgICAgQXJyYXkuZnJvbShsYWJlbHMpLmZvckVhY2gobGFiZWwgPT4gbGFiZWwuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCByZWYuY2xpY2suYmluZChyZWYpKSk7XG4gICAgICAgICAgICBsZXQgZmlyc3RMYWJlbElkID0gbGFiZWxzWzBdLmlkO1xuICAgICAgICAgICAgaWYgKCFsYWJlbHNbMF0uaWQpIHtcbiAgICAgICAgICAgICAgICBmaXJzdExhYmVsSWQgPSBgJHtsYWJlbHNbMF0uaHRtbEZvcn1fTGFiZWxgO1xuICAgICAgICAgICAgICAgIGxhYmVsc1swXS5pZCA9IGZpcnN0TGFiZWxJZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlZi5zZXRBdHRyaWJ1dGUoJ2FyaWEtbGFiZWxsZWRieScsIGZpcnN0TGFiZWxJZCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIGNvbnN0IHNldEZvcm1WYWxpZGl0eSA9IChmb3JtKSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRyb2xWYWxpZGl0eSA9IEFycmF5LmZyb20oZm9ybS5lbGVtZW50cylcbiAgICAgICAgICAgIC5maWx0ZXIoKGVsZW1lbnQpID0+ICFlbGVtZW50LnRhZ05hbWUuaW5jbHVkZXMoJy0nKSAmJiBlbGVtZW50LnZhbGlkaXR5KVxuICAgICAgICAgICAgLm1hcCgoZWxlbWVudCkgPT4gZWxlbWVudC52YWxpZGl0eS52YWxpZCk7XG4gICAgICAgIGNvbnN0IHBvbHlmaWxsZWRFbGVtZW50cyA9IGZvcm1FbGVtZW50c01hcC5nZXQoZm9ybSkgfHwgW107XG4gICAgICAgIGNvbnN0IHBvbHlmaWxsZWRWYWxpZGl0eSA9IEFycmF5LmZyb20ocG9seWZpbGxlZEVsZW1lbnRzKVxuICAgICAgICAgICAgLmZpbHRlcihjb250cm9sID0+IGNvbnRyb2wuaXNDb25uZWN0ZWQpXG4gICAgICAgICAgICAubWFwKChjb250cm9sKSA9PiBpbnRlcm5hbHNNYXAuZ2V0KGNvbnRyb2wpLnZhbGlkaXR5LnZhbGlkKTtcbiAgICAgICAgY29uc3QgaGFzSW52YWxpZCA9IFsuLi5uYXRpdmVDb250cm9sVmFsaWRpdHksIC4uLnBvbHlmaWxsZWRWYWxpZGl0eV0uaW5jbHVkZXMoZmFsc2UpO1xuICAgICAgICBmb3JtLnRvZ2dsZUF0dHJpYnV0ZSgnaW50ZXJuYWxzLWludmFsaWQnLCBoYXNJbnZhbGlkKTtcbiAgICAgICAgZm9ybS50b2dnbGVBdHRyaWJ1dGUoJ2ludGVybmFscy12YWxpZCcsICFoYXNJbnZhbGlkKTtcbiAgICB9O1xuICAgIGNvbnN0IGZvcm1JbnB1dENhbGxiYWNrID0gKGV2ZW50KSA9PiB7XG4gICAgICAgIHNldEZvcm1WYWxpZGl0eShmaW5kUGFyZW50Rm9ybShldmVudC50YXJnZXQpKTtcbiAgICB9O1xuICAgIGNvbnN0IGZvcm1DaGFuZ2VDYWxsYmFjayA9IChldmVudCkgPT4ge1xuICAgICAgICBzZXRGb3JtVmFsaWRpdHkoZmluZFBhcmVudEZvcm0oZXZlbnQudGFyZ2V0KSk7XG4gICAgfTtcbiAgICBjb25zdCB3aXJlU3VibWl0TG9naWMgPSAoZm9ybSkgPT4ge1xuICAgICAgICBjb25zdCBTVUJNSVRfQlVUVE9OX1NFTEVDVE9SID0gJzppcyhidXR0b25bdHlwZT1zdWJtaXRdLCBpbnB1dFt0eXBlPXN1Ym1pdF0sIGJ1dHRvbjpub3QoW3R5cGVdKSk6bm90KFtkaXNhYmxlZF0pJztcbiAgICAgICAgbGV0IHN1Ym1pdEJ1dHRvblNlbGVjdG9yID0gYCR7U1VCTUlUX0JVVFRPTl9TRUxFQ1RPUn06bm90KFtmb3JtXSlgO1xuICAgICAgICBpZiAoZm9ybS5pZCkge1xuICAgICAgICAgICAgc3VibWl0QnV0dG9uU2VsZWN0b3IgKz0gYCwke1NVQk1JVF9CVVRUT05fU0VMRUNUT1J9W2Zvcm09JyR7Zm9ybS5pZH0nXWA7XG4gICAgICAgIH1cbiAgICAgICAgZm9ybS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldDtcbiAgICAgICAgICAgIGlmICh0YXJnZXQuY2xvc2VzdChzdWJtaXRCdXR0b25TZWxlY3RvcikpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBlbGVtZW50cyA9IGZvcm1FbGVtZW50c01hcC5nZXQoZm9ybSk7XG4gICAgICAgICAgICAgICAgaWYgKGZvcm0ubm9WYWxpZGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChlbGVtZW50cy5zaXplKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5vZGVzID0gQXJyYXkuZnJvbShlbGVtZW50cyk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbGlkaXR5TGlzdCA9IG5vZGVzXG4gICAgICAgICAgICAgICAgICAgICAgICAucmV2ZXJzZSgpXG4gICAgICAgICAgICAgICAgICAgICAgICAubWFwKG5vZGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW50ZXJuYWxzID0gaW50ZXJuYWxzTWFwLmdldChub2RlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbHMucmVwb3J0VmFsaWRpdHkoKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIGlmICh2YWxpZGl0eUxpc3QuaW5jbHVkZXMoZmFsc2UpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIGNvbnN0IGZvcm1SZXNldENhbGxiYWNrID0gKGV2ZW50KSA9PiB7XG4gICAgICAgIGNvbnN0IGVsZW1lbnRzID0gZm9ybUVsZW1lbnRzTWFwLmdldChldmVudC50YXJnZXQpO1xuICAgICAgICBpZiAoZWxlbWVudHMgJiYgZWxlbWVudHMuc2l6ZSkge1xuICAgICAgICAgICAgZWxlbWVudHMuZm9yRWFjaChlbGVtZW50ID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZWxlbWVudC5jb25zdHJ1Y3Rvci5mb3JtQXNzb2NpYXRlZCAmJiBlbGVtZW50LmZvcm1SZXNldENhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuZm9ybVJlc2V0Q2FsbGJhY2suYXBwbHkoZWxlbWVudCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIGNvbnN0IGluaXRGb3JtID0gKHJlZiwgZm9ybSwgaW50ZXJuYWxzKSA9PiB7XG4gICAgICAgIGlmIChmb3JtKSB7XG4gICAgICAgICAgICBjb25zdCBmb3JtRWxlbWVudHMgPSBmb3JtRWxlbWVudHNNYXAuZ2V0KGZvcm0pO1xuICAgICAgICAgICAgaWYgKGZvcm1FbGVtZW50cykge1xuICAgICAgICAgICAgICAgIGZvcm1FbGVtZW50cy5hZGQocmVmKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IGluaXRTZXQgPSBuZXcgU2V0KCk7XG4gICAgICAgICAgICAgICAgaW5pdFNldC5hZGQocmVmKTtcbiAgICAgICAgICAgICAgICBmb3JtRWxlbWVudHNNYXAuc2V0KGZvcm0sIGluaXRTZXQpO1xuICAgICAgICAgICAgICAgIHdpcmVTdWJtaXRMb2dpYyhmb3JtKTtcbiAgICAgICAgICAgICAgICBmb3JtLmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2V0JywgZm9ybVJlc2V0Q2FsbGJhY2spO1xuICAgICAgICAgICAgICAgIGZvcm0uYWRkRXZlbnRMaXN0ZW5lcignaW5wdXQnLCBmb3JtSW5wdXRDYWxsYmFjayk7XG4gICAgICAgICAgICAgICAgZm9ybS5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCBmb3JtQ2hhbmdlQ2FsbGJhY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9ybXNNYXAuc2V0KGZvcm0sIHsgcmVmLCBpbnRlcm5hbHMgfSk7XG4gICAgICAgICAgICBpZiAocmVmLmNvbnN0cnVjdG9yWydmb3JtQXNzb2NpYXRlZCddICYmIHJlZi5mb3JtQXNzb2NpYXRlZENhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlZi5mb3JtQXNzb2NpYXRlZENhbGxiYWNrLmFwcGx5KHJlZiwgW2Zvcm1dKTtcbiAgICAgICAgICAgICAgICB9LCAwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHNldEZvcm1WYWxpZGl0eShmb3JtKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgY29uc3QgZmluZFBhcmVudEZvcm0gPSAoZWxlbSkgPT4ge1xuICAgICAgICBsZXQgcGFyZW50ID0gZWxlbS5wYXJlbnROb2RlO1xuICAgICAgICBpZiAocGFyZW50ICYmIHBhcmVudC50YWdOYW1lICE9PSAnRk9STScpIHtcbiAgICAgICAgICAgIHBhcmVudCA9IGZpbmRQYXJlbnRGb3JtKHBhcmVudCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBhcmVudDtcbiAgICB9O1xuICAgIGNvbnN0IHRocm93SWZOb3RGb3JtQXNzb2NpYXRlZCA9IChyZWYsIG1lc3NhZ2UsIEVycm9yVHlwZSA9IERPTUV4Y2VwdGlvbikgPT4ge1xuICAgICAgICBpZiAoIXJlZi5jb25zdHJ1Y3RvclsnZm9ybUFzc29jaWF0ZWQnXSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yVHlwZShtZXNzYWdlKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgY29uc3Qgb3ZlcnJpZGVGb3JtTWV0aG9kID0gKGZvcm0sIHJldHVyblZhbHVlLCBtZXRob2QpID0+IHtcbiAgICAgICAgY29uc3QgZWxlbWVudHMgPSBmb3JtRWxlbWVudHNNYXAuZ2V0KGZvcm0pO1xuICAgICAgICBpZiAoZWxlbWVudHMgJiYgZWxlbWVudHMuc2l6ZSkge1xuICAgICAgICAgICAgZWxlbWVudHMuZm9yRWFjaChlbGVtZW50ID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBpbnRlcm5hbHMgPSBpbnRlcm5hbHNNYXAuZ2V0KGVsZW1lbnQpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhbGlkID0gaW50ZXJuYWxzW21ldGhvZF0oKTtcbiAgICAgICAgICAgICAgICBpZiAoIXZhbGlkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVyblZhbHVlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJldHVyblZhbHVlO1xuICAgIH07XG4gICAgY29uc3QgdXBncmFkZUludGVybmFscyA9IChyZWYpID0+IHtcbiAgICAgICAgaWYgKHJlZi5jb25zdHJ1Y3RvclsnZm9ybUFzc29jaWF0ZWQnXSkge1xuICAgICAgICAgICAgY29uc3QgaW50ZXJuYWxzID0gaW50ZXJuYWxzTWFwLmdldChyZWYpO1xuICAgICAgICAgICAgY29uc3QgeyBsYWJlbHMsIGZvcm0gfSA9IGludGVybmFscztcbiAgICAgICAgICAgIGluaXRMYWJlbHMocmVmLCBsYWJlbHMpO1xuICAgICAgICAgICAgaW5pdEZvcm0ocmVmLCBmb3JtLCBpbnRlcm5hbHMpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBtdXRhdGlvbk9ic2VydmVyRXhpc3RzKCkge1xuICAgICAgICByZXR1cm4gdHlwZW9mIE11dGF0aW9uT2JzZXJ2ZXIgIT09ICd1bmRlZmluZWQnO1xuICAgIH1cblxuICAgIGNsYXNzIFZhbGlkaXR5U3RhdGUge1xuICAgICAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgICAgIHRoaXMuYmFkSW5wdXQgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuY3VzdG9tRXJyb3IgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMucGF0dGVybk1pc21hdGNoID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLnJhbmdlT3ZlcmZsb3cgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMucmFuZ2VVbmRlcmZsb3cgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuc3RlcE1pc21hdGNoID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLnRvb0xvbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMudG9vU2hvcnQgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMudHlwZU1pc21hdGNoID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLnZhbGlkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMudmFsdWVNaXNzaW5nID0gZmFsc2U7XG4gICAgICAgICAgICBPYmplY3Quc2VhbCh0aGlzKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBzZXRWYWxpZCA9ICh2YWxpZGl0eU9iamVjdCkgPT4ge1xuICAgICAgICB2YWxpZGl0eU9iamVjdC5iYWRJbnB1dCA9IGZhbHNlO1xuICAgICAgICB2YWxpZGl0eU9iamVjdC5jdXN0b21FcnJvciA9IGZhbHNlO1xuICAgICAgICB2YWxpZGl0eU9iamVjdC5wYXR0ZXJuTWlzbWF0Y2ggPSBmYWxzZTtcbiAgICAgICAgdmFsaWRpdHlPYmplY3QucmFuZ2VPdmVyZmxvdyA9IGZhbHNlO1xuICAgICAgICB2YWxpZGl0eU9iamVjdC5yYW5nZVVuZGVyZmxvdyA9IGZhbHNlO1xuICAgICAgICB2YWxpZGl0eU9iamVjdC5zdGVwTWlzbWF0Y2ggPSBmYWxzZTtcbiAgICAgICAgdmFsaWRpdHlPYmplY3QudG9vTG9uZyA9IGZhbHNlO1xuICAgICAgICB2YWxpZGl0eU9iamVjdC50b29TaG9ydCA9IGZhbHNlO1xuICAgICAgICB2YWxpZGl0eU9iamVjdC50eXBlTWlzbWF0Y2ggPSBmYWxzZTtcbiAgICAgICAgdmFsaWRpdHlPYmplY3QudmFsaWQgPSB0cnVlO1xuICAgICAgICB2YWxpZGl0eU9iamVjdC52YWx1ZU1pc3NpbmcgPSBmYWxzZTtcbiAgICAgICAgcmV0dXJuIHZhbGlkaXR5T2JqZWN0O1xuICAgIH07XG4gICAgY29uc3QgcmVjb25jaWxlVmFsaWRpdHkgPSAodmFsaWRpdHlPYmplY3QsIG5ld1N0YXRlLCBmb3JtKSA9PiB7XG4gICAgICAgIHZhbGlkaXR5T2JqZWN0LnZhbGlkID0gaXNWYWxpZChuZXdTdGF0ZSk7XG4gICAgICAgIE9iamVjdC5rZXlzKG5ld1N0YXRlKS5mb3JFYWNoKGtleSA9PiB2YWxpZGl0eU9iamVjdFtrZXldID0gbmV3U3RhdGVba2V5XSk7XG4gICAgICAgIGlmIChmb3JtKSB7XG4gICAgICAgICAgICBzZXRGb3JtVmFsaWRpdHkoZm9ybSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHZhbGlkaXR5T2JqZWN0O1xuICAgIH07XG4gICAgY29uc3QgaXNWYWxpZCA9ICh2YWxpZGl0eVN0YXRlKSA9PiB7XG4gICAgICAgIGxldCB2YWxpZCA9IHRydWU7XG4gICAgICAgIGZvciAobGV0IGtleSBpbiB2YWxpZGl0eVN0YXRlKSB7XG4gICAgICAgICAgICBpZiAoa2V5ICE9PSAndmFsaWQnICYmIHZhbGlkaXR5U3RhdGVba2V5XSAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICB2YWxpZCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2YWxpZDtcbiAgICB9O1xuXG4gICAgY29uc3QgY3VzdG9tU3RhdGVNYXAgPSBuZXcgV2Vha01hcCgpO1xuICAgIGZ1bmN0aW9uIGFkZFN0YXRlKHJlZiwgc3RhdGVOYW1lKSB7XG4gICAgICAgIHJlZi50b2dnbGVBdHRyaWJ1dGUoc3RhdGVOYW1lLCB0cnVlKTtcbiAgICAgICAgaWYgKHJlZi5wYXJ0KSB7XG4gICAgICAgICAgICByZWYucGFydC5hZGQoc3RhdGVOYW1lKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjbGFzcyBDdXN0b21TdGF0ZVNldCBleHRlbmRzIFNldCB7XG4gICAgICAgIHN0YXRpYyBnZXQgaXNQb2x5ZmlsbGVkKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3RydWN0b3IocmVmKSB7XG4gICAgICAgICAgICBzdXBlcigpO1xuICAgICAgICAgICAgaWYgKCFyZWYgfHwgIXJlZi50YWdOYW1lIHx8IHJlZi50YWdOYW1lLmluZGV4T2YoJy0nKSA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbGxlZ2FsIGNvbnN0cnVjdG9yJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjdXN0b21TdGF0ZU1hcC5zZXQodGhpcywgcmVmKTtcbiAgICAgICAgfVxuICAgICAgICBhZGQoc3RhdGUpIHtcbiAgICAgICAgICAgIGlmICghL14tLS8udGVzdChzdGF0ZSkgfHwgdHlwZW9mIHN0YXRlICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oYEZhaWxlZCB0byBleGVjdXRlICdhZGQnIG9uICdDdXN0b21TdGF0ZVNldCc6IFRoZSBzcGVjaWZpZWQgdmFsdWUgJHtzdGF0ZX0gbXVzdCBzdGFydCB3aXRoICctLScuYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBzdXBlci5hZGQoc3RhdGUpO1xuICAgICAgICAgICAgY29uc3QgcmVmID0gY3VzdG9tU3RhdGVNYXAuZ2V0KHRoaXMpO1xuICAgICAgICAgICAgY29uc3Qgc3RhdGVOYW1lID0gYHN0YXRlJHtzdGF0ZX1gO1xuICAgICAgICAgICAgaWYgKHJlZi5pc0Nvbm5lY3RlZCkge1xuICAgICAgICAgICAgICAgIGFkZFN0YXRlKHJlZiwgc3RhdGVOYW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBhZGRTdGF0ZShyZWYsIHN0YXRlTmFtZSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG4gICAgICAgIGNsZWFyKCkge1xuICAgICAgICAgICAgZm9yIChsZXQgW2VudHJ5XSBvZiB0aGlzLmVudHJpZXMoKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGVsZXRlKGVudHJ5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN1cGVyLmNsZWFyKCk7XG4gICAgICAgIH1cbiAgICAgICAgZGVsZXRlKHN0YXRlKSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBzdXBlci5kZWxldGUoc3RhdGUpO1xuICAgICAgICAgICAgY29uc3QgcmVmID0gY3VzdG9tU3RhdGVNYXAuZ2V0KHRoaXMpO1xuICAgICAgICAgICAgaWYgKHJlZi5pc0Nvbm5lY3RlZCkge1xuICAgICAgICAgICAgICAgIHJlZi50b2dnbGVBdHRyaWJ1dGUoYHN0YXRlJHtzdGF0ZX1gLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgaWYgKHJlZi5wYXJ0KSB7XG4gICAgICAgICAgICAgICAgICAgIHJlZi5wYXJ0LnJlbW92ZShgc3RhdGUke3N0YXRlfWApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZWYudG9nZ2xlQXR0cmlidXRlKGBzdGF0ZSR7c3RhdGV9YCwgZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVmLnBhcnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZi5wYXJ0LnJlbW92ZShgc3RhdGUke3N0YXRlfWApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZEdldChyZWNlaXZlciwgc3RhdGUsIGtpbmQsIGYpIHtcbiAgICAgICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xuICAgICAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCByZWFkIHByaXZhdGUgbWVtYmVyIGZyb20gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcbiAgICAgICAgcmV0dXJuIGtpbmQgPT09IFwibVwiID8gZiA6IGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyKSA6IGYgPyBmLnZhbHVlIDogc3RhdGUuZ2V0KHJlY2VpdmVyKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZFNldChyZWNlaXZlciwgc3RhdGUsIHZhbHVlLCBraW5kLCBmKSB7XG4gICAgICAgIGlmIChraW5kID09PSBcIm1cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgbWV0aG9kIGlzIG5vdCB3cml0YWJsZVwiKTtcbiAgICAgICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xuICAgICAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCB3cml0ZSBwcml2YXRlIG1lbWJlciB0byBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICAgICAgICByZXR1cm4gKGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyLCB2YWx1ZSkgOiBmID8gZi52YWx1ZSA9IHZhbHVlIDogc3RhdGUuc2V0KHJlY2VpdmVyLCB2YWx1ZSkpLCB2YWx1ZTtcbiAgICB9XG5cbiAgICB2YXIgX0hUTUxGb3JtQ29udHJvbHNDb2xsZWN0aW9uX2VsZW1lbnRzO1xuICAgIGNsYXNzIEhUTUxGb3JtQ29udHJvbHNDb2xsZWN0aW9uIHtcbiAgICAgICAgY29uc3RydWN0b3IoZWxlbWVudHMpIHtcbiAgICAgICAgICAgIF9IVE1MRm9ybUNvbnRyb2xzQ29sbGVjdGlvbl9lbGVtZW50cy5zZXQodGhpcywgdm9pZCAwKTtcbiAgICAgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQodGhpcywgX0hUTUxGb3JtQ29udHJvbHNDb2xsZWN0aW9uX2VsZW1lbnRzLCBlbGVtZW50cywgXCJmXCIpO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBlbGVtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGxldCBlbGVtZW50ID0gZWxlbWVudHNbaV07XG4gICAgICAgICAgICAgICAgdGhpc1tpXSA9IGVsZW1lbnQ7XG4gICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQuaGFzQXR0cmlidXRlKCduYW1lJykpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpc1tlbGVtZW50LmdldEF0dHJpYnV0ZSgnbmFtZScpXSA9IGVsZW1lbnQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgT2JqZWN0LmZyZWV6ZSh0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgbGVuZ3RoKCkge1xuICAgICAgICAgICAgcmV0dXJuIF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX0hUTUxGb3JtQ29udHJvbHNDb2xsZWN0aW9uX2VsZW1lbnRzLCBcImZcIikubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICAgIFsoX0hUTUxGb3JtQ29udHJvbHNDb2xsZWN0aW9uX2VsZW1lbnRzID0gbmV3IFdlYWtNYXAoKSwgU3ltYm9sLml0ZXJhdG9yKV0oKSB7XG4gICAgICAgICAgICByZXR1cm4gX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfSFRNTEZvcm1Db250cm9sc0NvbGxlY3Rpb25fZWxlbWVudHMsIFwiZlwiKVtTeW1ib2wuaXRlcmF0b3JdKCk7XG4gICAgICAgIH1cbiAgICAgICAgaXRlbShpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpc1tpXSA9PSBudWxsID8gbnVsbCA6IHRoaXNbaV07XG4gICAgICAgIH1cbiAgICAgICAgbmFtZWRJdGVtKG5hbWUpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzW25hbWVdID09IG51bGwgPyBudWxsIDogdGhpc1tuYW1lXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhdGNoRm9ybVByb3RvdHlwZSgpIHtcbiAgICAgICAgY29uc3QgY2hlY2tWYWxpZGl0eSA9IEhUTUxGb3JtRWxlbWVudC5wcm90b3R5cGUuY2hlY2tWYWxpZGl0eTtcbiAgICAgICAgSFRNTEZvcm1FbGVtZW50LnByb3RvdHlwZS5jaGVja1ZhbGlkaXR5ID0gY2hlY2tWYWxpZGl0eU92ZXJyaWRlO1xuICAgICAgICBjb25zdCByZXBvcnRWYWxpZGl0eSA9IEhUTUxGb3JtRWxlbWVudC5wcm90b3R5cGUucmVwb3J0VmFsaWRpdHk7XG4gICAgICAgIEhUTUxGb3JtRWxlbWVudC5wcm90b3R5cGUucmVwb3J0VmFsaWRpdHkgPSByZXBvcnRWYWxpZGl0eU92ZXJyaWRlO1xuICAgICAgICBmdW5jdGlvbiBjaGVja1ZhbGlkaXR5T3ZlcnJpZGUoLi4uYXJncykge1xuICAgICAgICAgICAgbGV0IHJldHVyblZhbHVlID0gY2hlY2tWYWxpZGl0eS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgICAgIHJldHVybiBvdmVycmlkZUZvcm1NZXRob2QodGhpcywgcmV0dXJuVmFsdWUsICdjaGVja1ZhbGlkaXR5Jyk7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gcmVwb3J0VmFsaWRpdHlPdmVycmlkZSguLi5hcmdzKSB7XG4gICAgICAgICAgICBsZXQgcmV0dXJuVmFsdWUgPSByZXBvcnRWYWxpZGl0eS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgICAgIHJldHVybiBvdmVycmlkZUZvcm1NZXRob2QodGhpcywgcmV0dXJuVmFsdWUsICdyZXBvcnRWYWxpZGl0eScpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHsgZ2V0IH0gPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKEhUTUxGb3JtRWxlbWVudC5wcm90b3R5cGUsICdlbGVtZW50cycpO1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoSFRNTEZvcm1FbGVtZW50LnByb3RvdHlwZSwgJ2VsZW1lbnRzJywge1xuICAgICAgICAgICAgZ2V0KC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBlbGVtZW50cyA9IGdldC5jYWxsKHRoaXMsIC4uLmFyZ3MpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHBvbHlmaWxsZWRFbGVtZW50cyA9IEFycmF5LmZyb20oZm9ybUVsZW1lbnRzTWFwLmdldCh0aGlzKSB8fCBbXSk7XG4gICAgICAgICAgICAgICAgaWYgKHBvbHlmaWxsZWRFbGVtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVsZW1lbnRzO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBvcmRlcmVkRWxlbWVudHMgPSBBcnJheS5mcm9tKGVsZW1lbnRzKS5jb25jYXQocG9seWZpbGxlZEVsZW1lbnRzKS5zb3J0KChhLCBiKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChhLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbihiKSAmIDIgPyAxIDogLTE7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBIVE1MRm9ybUNvbnRyb2xzQ29sbGVjdGlvbihvcmRlcmVkRWxlbWVudHMpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgY2xhc3MgRWxlbWVudEludGVybmFscyB7XG4gICAgICAgIHN0YXRpYyBnZXQgaXNQb2x5ZmlsbGVkKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3RydWN0b3IocmVmKSB7XG4gICAgICAgICAgICBpZiAoIXJlZiB8fCAhcmVmLnRhZ05hbWUgfHwgcmVmLnRhZ05hbWUuaW5kZXhPZignLScpID09PSAtMSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0lsbGVnYWwgY29uc3RydWN0b3InKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHJvb3ROb2RlID0gcmVmLmdldFJvb3ROb2RlKCk7XG4gICAgICAgICAgICBjb25zdCB2YWxpZGl0eSA9IG5ldyBWYWxpZGl0eVN0YXRlKCk7XG4gICAgICAgICAgICB0aGlzLnN0YXRlcyA9IG5ldyBDdXN0b21TdGF0ZVNldChyZWYpO1xuICAgICAgICAgICAgcmVmTWFwLnNldCh0aGlzLCByZWYpO1xuICAgICAgICAgICAgdmFsaWRpdHlNYXAuc2V0KHRoaXMsIHZhbGlkaXR5KTtcbiAgICAgICAgICAgIGludGVybmFsc01hcC5zZXQocmVmLCB0aGlzKTtcbiAgICAgICAgICAgIGluaXRBb20ocmVmLCB0aGlzKTtcbiAgICAgICAgICAgIGluaXRSZWYocmVmLCB0aGlzKTtcbiAgICAgICAgICAgIE9iamVjdC5zZWFsKHRoaXMpO1xuICAgICAgICAgICAgaWYgKHJvb3ROb2RlIGluc3RhbmNlb2YgRG9jdW1lbnRGcmFnbWVudCkge1xuICAgICAgICAgICAgICAgIGRlZmVyVXBncmFkZShyb290Tm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY2hlY2tWYWxpZGl0eSgpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlZiA9IHJlZk1hcC5nZXQodGhpcyk7XG4gICAgICAgICAgICB0aHJvd0lmTm90Rm9ybUFzc29jaWF0ZWQocmVmLCBgRmFpbGVkIHRvIGV4ZWN1dGUgJ2NoZWNrVmFsaWRpdHknIG9uICdFbGVtZW50SW50ZXJuYWxzJzogVGhlIHRhcmdldCBlbGVtZW50IGlzIG5vdCBhIGZvcm0tYXNzb2NpYXRlZCBjdXN0b20gZWxlbWVudC5gKTtcbiAgICAgICAgICAgIGlmICghdGhpcy53aWxsVmFsaWRhdGUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHZhbGlkaXR5ID0gdmFsaWRpdHlNYXAuZ2V0KHRoaXMpO1xuICAgICAgICAgICAgaWYgKCF2YWxpZGl0eS52YWxpZCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhbGlkaXR5RXZlbnQgPSBuZXcgRXZlbnQoJ2ludmFsaWQnLCB7XG4gICAgICAgICAgICAgICAgICAgIGJ1YmJsZXM6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBjYW5jZWxhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBjb21wb3NlZDogZmFsc2VcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZWYuZGlzcGF0Y2hFdmVudCh2YWxpZGl0eUV2ZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB2YWxpZGl0eS52YWxpZDtcbiAgICAgICAgfVxuICAgICAgICBnZXQgZm9ybSgpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlZiA9IHJlZk1hcC5nZXQodGhpcyk7XG4gICAgICAgICAgICB0aHJvd0lmTm90Rm9ybUFzc29jaWF0ZWQocmVmLCBgRmFpbGVkIHRvIHJlYWQgdGhlICdmb3JtJyBwcm9wZXJ0eSBmcm9tICdFbGVtZW50SW50ZXJuYWxzJzogVGhlIHRhcmdldCBlbGVtZW50IGlzIG5vdCBhIGZvcm0tYXNzb2NpYXRlZCBjdXN0b20gZWxlbWVudC5gKTtcbiAgICAgICAgICAgIGxldCBmb3JtO1xuICAgICAgICAgICAgaWYgKHJlZi5jb25zdHJ1Y3RvclsnZm9ybUFzc29jaWF0ZWQnXSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgIGZvcm0gPSBmaW5kUGFyZW50Rm9ybShyZWYpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGZvcm07XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGxhYmVscygpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlZiA9IHJlZk1hcC5nZXQodGhpcyk7XG4gICAgICAgICAgICB0aHJvd0lmTm90Rm9ybUFzc29jaWF0ZWQocmVmLCBgRmFpbGVkIHRvIHJlYWQgdGhlICdsYWJlbHMnIHByb3BlcnR5IGZyb20gJ0VsZW1lbnRJbnRlcm5hbHMnOiBUaGUgdGFyZ2V0IGVsZW1lbnQgaXMgbm90IGEgZm9ybS1hc3NvY2lhdGVkIGN1c3RvbSBlbGVtZW50LmApO1xuICAgICAgICAgICAgY29uc3QgaWQgPSByZWYuZ2V0QXR0cmlidXRlKCdpZCcpO1xuICAgICAgICAgICAgY29uc3QgaG9zdFJvb3QgPSByZWYuZ2V0Um9vdE5vZGUoKTtcbiAgICAgICAgICAgIGlmIChob3N0Um9vdCAmJiBpZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBob3N0Um9vdC5xdWVyeVNlbGVjdG9yQWxsKGBbZm9yPVwiJHtpZH1cIl1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuICAgICAgICByZXBvcnRWYWxpZGl0eSgpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlZiA9IHJlZk1hcC5nZXQodGhpcyk7XG4gICAgICAgICAgICB0aHJvd0lmTm90Rm9ybUFzc29jaWF0ZWQocmVmLCBgRmFpbGVkIHRvIGV4ZWN1dGUgJ3JlcG9ydFZhbGlkaXR5JyBvbiAnRWxlbWVudEludGVybmFscyc6IFRoZSB0YXJnZXQgZWxlbWVudCBpcyBub3QgYSBmb3JtLWFzc29jaWF0ZWQgY3VzdG9tIGVsZW1lbnQuYCk7XG4gICAgICAgICAgICBpZiAoIXRoaXMud2lsbFZhbGlkYXRlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCB2YWxpZCA9IHRoaXMuY2hlY2tWYWxpZGl0eSgpO1xuICAgICAgICAgICAgY29uc3QgYW5jaG9yID0gdmFsaWRhdGlvbkFuY2hvck1hcC5nZXQodGhpcyk7XG4gICAgICAgICAgICBpZiAoYW5jaG9yICYmICFyZWYuY29uc3RydWN0b3JbJ2Zvcm1Bc3NvY2lhdGVkJ10pIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKGBGYWlsZWQgdG8gZXhlY3V0ZSAncmVwb3J0VmFsaWRpdHknIG9uICdFbGVtZW50SW50ZXJuYWxzJzogVGhlIHRhcmdldCBlbGVtZW50IGlzIG5vdCBhIGZvcm0tYXNzb2NpYXRlZCBjdXN0b20gZWxlbWVudC5gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghdmFsaWQgJiYgYW5jaG9yKSB7XG4gICAgICAgICAgICAgICAgcmVmLmZvY3VzKCk7XG4gICAgICAgICAgICAgICAgYW5jaG9yLmZvY3VzKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdmFsaWQ7XG4gICAgICAgIH1cbiAgICAgICAgc2V0Rm9ybVZhbHVlKHZhbHVlKSB7XG4gICAgICAgICAgICBjb25zdCByZWYgPSByZWZNYXAuZ2V0KHRoaXMpO1xuICAgICAgICAgICAgdGhyb3dJZk5vdEZvcm1Bc3NvY2lhdGVkKHJlZiwgYEZhaWxlZCB0byBleGVjdXRlICdzZXRGb3JtVmFsdWUnIG9uICdFbGVtZW50SW50ZXJuYWxzJzogVGhlIHRhcmdldCBlbGVtZW50IGlzIG5vdCBhIGZvcm0tYXNzb2NpYXRlZCBjdXN0b20gZWxlbWVudC5gKTtcbiAgICAgICAgICAgIHJlbW92ZUhpZGRlbklucHV0cyh0aGlzKTtcbiAgICAgICAgICAgIGlmICh2YWx1ZSAhPSBudWxsICYmICEodmFsdWUgaW5zdGFuY2VvZiBGb3JtRGF0YSkpIHtcbiAgICAgICAgICAgICAgICBpZiAocmVmLmdldEF0dHJpYnV0ZSgnbmFtZScpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGhpZGRlbklucHV0ID0gY3JlYXRlSGlkZGVuSW5wdXQocmVmLCB0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgaGlkZGVuSW5wdXQudmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSAhPSBudWxsICYmIHZhbHVlIGluc3RhbmNlb2YgRm9ybURhdGEpIHtcbiAgICAgICAgICAgICAgICBBcnJheS5mcm9tKHZhbHVlKS5yZXZlcnNlKCkuZm9yRWFjaCgoW2Zvcm1EYXRhS2V5LCBmb3JtRGF0YVZhbHVlXSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGZvcm1EYXRhVmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBoaWRkZW5JbnB1dCA9IGNyZWF0ZUhpZGRlbklucHV0KHJlZiwgdGhpcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBoaWRkZW5JbnB1dC5uYW1lID0gZm9ybURhdGFLZXk7XG4gICAgICAgICAgICAgICAgICAgICAgICBoaWRkZW5JbnB1dC52YWx1ZSA9IGZvcm1EYXRhVmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlZlZhbHVlTWFwLnNldChyZWYsIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICBzZXRWYWxpZGl0eSh2YWxpZGl0eUNoYW5nZXMsIHZhbGlkYXRpb25NZXNzYWdlLCBhbmNob3IpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlZiA9IHJlZk1hcC5nZXQodGhpcyk7XG4gICAgICAgICAgICB0aHJvd0lmTm90Rm9ybUFzc29jaWF0ZWQocmVmLCBgRmFpbGVkIHRvIGV4ZWN1dGUgJ3NldFZhbGlkaXR5JyBvbiAnRWxlbWVudEludGVybmFscyc6IFRoZSB0YXJnZXQgZWxlbWVudCBpcyBub3QgYSBmb3JtLWFzc29jaWF0ZWQgY3VzdG9tIGVsZW1lbnQuYCk7XG4gICAgICAgICAgICBpZiAoIXZhbGlkaXR5Q2hhbmdlcykge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ZhaWxlZCB0byBleGVjdXRlIFxcJ3NldFZhbGlkaXR5XFwnIG9uIFxcJ0VsZW1lbnRJbnRlcm5hbHNcXCc6IDEgYXJndW1lbnQgcmVxdWlyZWQsIGJ1dCBvbmx5IDAgcHJlc2VudC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhbGlkYXRpb25BbmNob3JNYXAuc2V0KHRoaXMsIGFuY2hvcik7XG4gICAgICAgICAgICBjb25zdCB2YWxpZGl0eSA9IHZhbGlkaXR5TWFwLmdldCh0aGlzKTtcbiAgICAgICAgICAgIGNvbnN0IHZhbGlkaXR5Q2hhbmdlc09iaiA9IHt9O1xuICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gdmFsaWRpdHlDaGFuZ2VzKSB7XG4gICAgICAgICAgICAgICAgdmFsaWRpdHlDaGFuZ2VzT2JqW2tleV0gPSB2YWxpZGl0eUNoYW5nZXNba2V5XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChPYmplY3Qua2V5cyh2YWxpZGl0eUNoYW5nZXNPYmopLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHNldFZhbGlkKHZhbGlkaXR5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGNoZWNrID0geyAuLi52YWxpZGl0eSwgLi4udmFsaWRpdHlDaGFuZ2VzT2JqIH07XG4gICAgICAgICAgICBkZWxldGUgY2hlY2sudmFsaWQ7XG4gICAgICAgICAgICBjb25zdCB7IHZhbGlkIH0gPSByZWNvbmNpbGVWYWxpZGl0eSh2YWxpZGl0eSwgY2hlY2ssIHRoaXMuZm9ybSk7XG4gICAgICAgICAgICBpZiAoIXZhbGlkICYmICF2YWxpZGF0aW9uTWVzc2FnZSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oYEZhaWxlZCB0byBleGVjdXRlICdzZXRWYWxpZGl0eScgb24gJ0VsZW1lbnRJbnRlcm5hbHMnOiBUaGUgc2Vjb25kIGFyZ3VtZW50IHNob3VsZCBub3QgYmUgZW1wdHkgaWYgb25lIG9yIG1vcmUgZmxhZ3MgaW4gdGhlIGZpcnN0IGFyZ3VtZW50IGFyZSB0cnVlLmApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFsaWRhdGlvbk1lc3NhZ2VNYXAuc2V0KHRoaXMsIHZhbGlkID8gJycgOiB2YWxpZGF0aW9uTWVzc2FnZSk7XG4gICAgICAgICAgICBpZiAocmVmLmlzQ29ubmVjdGVkKSB7XG4gICAgICAgICAgICAgICAgcmVmLnRvZ2dsZUF0dHJpYnV0ZSgnaW50ZXJuYWxzLWludmFsaWQnLCAhdmFsaWQpO1xuICAgICAgICAgICAgICAgIHJlZi50b2dnbGVBdHRyaWJ1dGUoJ2ludGVybmFscy12YWxpZCcsIHZhbGlkKTtcbiAgICAgICAgICAgICAgICByZWYuc2V0QXR0cmlidXRlKCdhcmlhLWludmFsaWQnLCBgJHshdmFsaWR9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YWxpZGl0eVVwZ3JhZGVNYXAuc2V0KHJlZiwgdGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHNoYWRvd1Jvb3QoKSB7XG4gICAgICAgICAgICBjb25zdCByZWYgPSByZWZNYXAuZ2V0KHRoaXMpO1xuICAgICAgICAgICAgY29uc3Qgc2hhZG93Um9vdCA9IHNoYWRvd1Jvb3RNYXAuZ2V0KHJlZik7XG4gICAgICAgICAgICBpZiAoc2hhZG93Um9vdCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBzaGFkb3dSb290O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHZhbGlkYXRpb25NZXNzYWdlKCkge1xuICAgICAgICAgICAgY29uc3QgcmVmID0gcmVmTWFwLmdldCh0aGlzKTtcbiAgICAgICAgICAgIHRocm93SWZOb3RGb3JtQXNzb2NpYXRlZChyZWYsIGBGYWlsZWQgdG8gcmVhZCB0aGUgJ3ZhbGlkYXRpb25NZXNzYWdlJyBwcm9wZXJ0eSBmcm9tICdFbGVtZW50SW50ZXJuYWxzJzogVGhlIHRhcmdldCBlbGVtZW50IGlzIG5vdCBhIGZvcm0tYXNzb2NpYXRlZCBjdXN0b20gZWxlbWVudC5gKTtcbiAgICAgICAgICAgIHJldHVybiB2YWxpZGF0aW9uTWVzc2FnZU1hcC5nZXQodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHZhbGlkaXR5KCkge1xuICAgICAgICAgICAgY29uc3QgcmVmID0gcmVmTWFwLmdldCh0aGlzKTtcbiAgICAgICAgICAgIHRocm93SWZOb3RGb3JtQXNzb2NpYXRlZChyZWYsIGBGYWlsZWQgdG8gcmVhZCB0aGUgJ3ZhbGlkaXR5JyBwcm9wZXJ0eSBmcm9tICdFbGVtZW50SW50ZXJuYWxzJzogVGhlIHRhcmdldCBlbGVtZW50IGlzIG5vdCBhIGZvcm0tYXNzb2NpYXRlZCBjdXN0b20gZWxlbWVudC5gKTtcbiAgICAgICAgICAgIGNvbnN0IHZhbGlkaXR5ID0gdmFsaWRpdHlNYXAuZ2V0KHRoaXMpO1xuICAgICAgICAgICAgcmV0dXJuIHZhbGlkaXR5O1xuICAgICAgICB9XG4gICAgICAgIGdldCB3aWxsVmFsaWRhdGUoKSB7XG4gICAgICAgICAgICBjb25zdCByZWYgPSByZWZNYXAuZ2V0KHRoaXMpO1xuICAgICAgICAgICAgdGhyb3dJZk5vdEZvcm1Bc3NvY2lhdGVkKHJlZiwgYEZhaWxlZCB0byByZWFkIHRoZSAnd2lsbFZhbGlkYXRlJyBwcm9wZXJ0eSBmcm9tICdFbGVtZW50SW50ZXJuYWxzJzogVGhlIHRhcmdldCBlbGVtZW50IGlzIG5vdCBhIGZvcm0tYXNzb2NpYXRlZCBjdXN0b20gZWxlbWVudC5gKTtcbiAgICAgICAgICAgIGlmICgocmVmLmRpc2FibGVkIHx8IHJlZi5oYXNBdHRyaWJ1dGUoJ2Rpc2FibGVkJykpIHx8XG4gICAgICAgICAgICAgICAgcmVmLmhhc0F0dHJpYnV0ZSgncmVhZG9ubHknKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIGZ1bmN0aW9uIGlzRWxlbWVudEludGVybmFsc1N1cHBvcnRlZCgpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnIHx8ICF3aW5kb3cuRWxlbWVudEludGVybmFscyB8fCAhSFRNTEVsZW1lbnQucHJvdG90eXBlLmF0dGFjaEludGVybmFscykge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGNsYXNzIEVsZW1lbnRJbnRlcm5hbHNGZWF0dXJlRGV0ZWN0aW9uIGV4dGVuZHMgSFRNTEVsZW1lbnQge1xuICAgICAgICAgICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgICAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgICAgICAgICB0aGlzLmludGVybmFscyA9IHRoaXMuYXR0YWNoSW50ZXJuYWxzKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmFuZG9tTmFtZSA9IGBlbGVtZW50LWludGVybmFscy1mZWF0dXJlLWRldGVjdGlvbi0ke01hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnJlcGxhY2UoL1teYS16XSsvZywgJycpfWA7XG4gICAgICAgIGN1c3RvbUVsZW1lbnRzLmRlZmluZShyYW5kb21OYW1lLCBFbGVtZW50SW50ZXJuYWxzRmVhdHVyZURldGVjdGlvbik7XG4gICAgICAgIGNvbnN0IGZlYXR1cmVEZXRlY3Rpb25FbGVtZW50ID0gbmV3IEVsZW1lbnRJbnRlcm5hbHNGZWF0dXJlRGV0ZWN0aW9uKCk7XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICAnc2hhZG93Um9vdCcsXG4gICAgICAgICAgICAnZm9ybScsXG4gICAgICAgICAgICAnd2lsbFZhbGlkYXRlJyxcbiAgICAgICAgICAgICd2YWxpZGl0eScsXG4gICAgICAgICAgICAndmFsaWRhdGlvbk1lc3NhZ2UnLFxuICAgICAgICAgICAgJ2xhYmVscycsXG4gICAgICAgICAgICAnc2V0Rm9ybVZhbHVlJyxcbiAgICAgICAgICAgICdzZXRWYWxpZGl0eScsXG4gICAgICAgICAgICAnY2hlY2tWYWxpZGl0eScsXG4gICAgICAgICAgICAncmVwb3J0VmFsaWRpdHknXG4gICAgICAgIF0uZXZlcnkocHJvcCA9PiBwcm9wIGluIGZlYXR1cmVEZXRlY3Rpb25FbGVtZW50LmludGVybmFscyk7XG4gICAgfVxuICAgIGlmICghaXNFbGVtZW50SW50ZXJuYWxzU3VwcG9ydGVkKCkpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB3aW5kb3cuRWxlbWVudEludGVybmFscyA9IEVsZW1lbnRJbnRlcm5hbHM7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBDdXN0b21FbGVtZW50UmVnaXN0cnkgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBjb25zdCBkZWZpbmUgPSBDdXN0b21FbGVtZW50UmVnaXN0cnkucHJvdG90eXBlLmRlZmluZTtcbiAgICAgICAgICAgIEN1c3RvbUVsZW1lbnRSZWdpc3RyeS5wcm90b3R5cGUuZGVmaW5lID0gZnVuY3Rpb24gKG5hbWUsIGNvbnN0cnVjdG9yLCBvcHRpb25zKSB7XG4gICAgICAgICAgICAgICAgaWYgKGNvbnN0cnVjdG9yLmZvcm1Bc3NvY2lhdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbm5lY3RlZENhbGxiYWNrID0gY29uc3RydWN0b3IucHJvdG90eXBlLmNvbm5lY3RlZENhbGxiYWNrO1xuICAgICAgICAgICAgICAgICAgICBjb25zdHJ1Y3Rvci5wcm90b3R5cGUuY29ubmVjdGVkQ2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWNvbm5lY3RlZENhbGxiYWNrTWFwLmhhcyh0aGlzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbm5lY3RlZENhbGxiYWNrTWFwLnNldCh0aGlzLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5oYXNBdHRyaWJ1dGUoJ2Rpc2FibGVkJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0RGlzYWJsZWQodGhpcywgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbm5lY3RlZENhbGxiYWNrICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0ZWRDYWxsYmFjay5hcHBseSh0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHVwZ3JhZGVJbnRlcm5hbHModGhpcyk7XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRlZmluZS5jYWxsKHRoaXMsIG5hbWUsIGNvbnN0cnVjdG9yLCBvcHRpb25zKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBIVE1MRWxlbWVudCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIEhUTUxFbGVtZW50LnByb3RvdHlwZS5hdHRhY2hJbnRlcm5hbHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLnRhZ05hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHt9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0aGlzLnRhZ05hbWUuaW5kZXhPZignLScpID09PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBleGVjdXRlICdhdHRhY2hJbnRlcm5hbHMnIG9uICdIVE1MRWxlbWVudCc6IFVuYWJsZSB0byBhdHRhY2ggRWxlbWVudEludGVybmFscyB0byBub24tY3VzdG9tIGVsZW1lbnRzLmApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoaW50ZXJuYWxzTWFwLmhhcyh0aGlzKSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKGBET01FeGNlcHRpb246IEZhaWxlZCB0byBleGVjdXRlICdhdHRhY2hJbnRlcm5hbHMnIG9uICdIVE1MRWxlbWVudCc6IEVsZW1lbnRJbnRlcm5hbHMgZm9yIHRoZSBzcGVjaWZpZWQgZWxlbWVudCB3YXMgYWxyZWFkeSBhdHRhY2hlZC5gKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBFbGVtZW50SW50ZXJuYWxzKHRoaXMpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIEVsZW1lbnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBmdW5jdGlvbiBhdHRhY2hTaGFkb3dPYnNlcnZlciguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2hhZG93Um9vdCA9IGF0dGFjaFNoYWRvdy5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgICAgICAgICBzaGFkb3dSb290TWFwLnNldCh0aGlzLCBzaGFkb3dSb290KTtcbiAgICAgICAgICAgICAgICBpZiAobXV0YXRpb25PYnNlcnZlckV4aXN0cygpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG9ic2VydmVyID0gbmV3IE11dGF0aW9uT2JzZXJ2ZXIob2JzZXJ2ZXJDYWxsYmFjayk7XG4gICAgICAgICAgICAgICAgICAgIGlmICh3aW5kb3cuU2hhZHlET00pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9ic2VydmUodGhpcywgb2JzZXJ2ZXJDb25maWcpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub2JzZXJ2ZShzaGFkb3dSb290LCBvYnNlcnZlckNvbmZpZyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgc2hhZG93SG9zdHNNYXAuc2V0KHRoaXMsIG9ic2VydmVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNoYWRvd1Jvb3Q7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBhdHRhY2hTaGFkb3cgPSBFbGVtZW50LnByb3RvdHlwZS5hdHRhY2hTaGFkb3c7XG4gICAgICAgICAgICBFbGVtZW50LnByb3RvdHlwZS5hdHRhY2hTaGFkb3cgPSBhdHRhY2hTaGFkb3dPYnNlcnZlcjtcbiAgICAgICAgfVxuICAgICAgICBpZiAobXV0YXRpb25PYnNlcnZlckV4aXN0cygpKSB7XG4gICAgICAgICAgICBjb25zdCBkb2N1bWVudE9ic2VydmVyID0gbmV3IE11dGF0aW9uT2JzZXJ2ZXIob2JzZXJ2ZXJDYWxsYmFjayk7XG4gICAgICAgICAgICBkb2N1bWVudE9ic2VydmVyLm9ic2VydmUoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LCBvYnNlcnZlckNvbmZpZyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBIVE1MRm9ybUVsZW1lbnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBwYXRjaEZvcm1Qcm90b3R5cGUoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgIXdpbmRvdy5DdXN0b21TdGF0ZVNldCkge1xuICAgICAgICAgICAgd2luZG93LkN1c3RvbVN0YXRlU2V0ID0gQ3VzdG9tU3RhdGVTZXQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgIXdpbmRvdy5DdXN0b21TdGF0ZVNldCkge1xuICAgICAgICB3aW5kb3cuQ3VzdG9tU3RhdGVTZXQgPSBDdXN0b21TdGF0ZVNldDtcbiAgICAgICAgY29uc3QgYXR0YWNoSW50ZXJuYWxzID0gSFRNTEVsZW1lbnQucHJvdG90eXBlLmF0dGFjaEludGVybmFscztcbiAgICAgICAgSFRNTEVsZW1lbnQucHJvdG90eXBlLmF0dGFjaEludGVybmFscyA9IGZ1bmN0aW9uICguLi5hcmdzKSB7XG4gICAgICAgICAgICBjb25zdCBpbnRlcm5hbHMgPSBhdHRhY2hJbnRlcm5hbHMuY2FsbCh0aGlzLCBhcmdzKTtcbiAgICAgICAgICAgIGludGVybmFscy5zdGF0ZXMgPSBuZXcgQ3VzdG9tU3RhdGVTZXQodGhpcyk7XG4gICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxzO1xuICAgICAgICB9O1xuICAgIH1cblxufSkoKTtcbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGV4dGVuZCB9IGZyb20gXCIuLi9kYXRhL2V4dGVuZC5tanNcIjtcbmltcG9ydCB7IGFkZEF0dHJpYnV0ZVRva2VuIH0gZnJvbSBcIi4vYXR0cmlidXRlcy5tanNcIjtcbmltcG9ydCB7IEFUVFJJQlVURV9FUlJPUk1FU1NBR0UgfSBmcm9tIFwiLi9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQgeyBDdXN0b21FbGVtZW50LCBhdHRyaWJ1dGVPYnNlcnZlclN5bWJvbCB9IGZyb20gXCIuL2N1c3RvbWVsZW1lbnQubWpzXCI7XG5pbXBvcnQgeyBpbnN0YW5jZVN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5cbmV4cG9ydCB7IEN1c3RvbUNvbnRyb2wgfTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHR5cGUge3N5bWJvbH1cbiAqL1xuY29uc3QgYXR0YWNoZWRJbnRlcm5hbFN5bWJvbCA9IFN5bWJvbChcImF0dGFjaGVkSW50ZXJuYWxcIik7XG5cbi8qKlxuICogVGhpcyBpcyBhIGJhc2UgY2xhc3MgZm9yIGNyZWF0aW5nIGN1c3RvbSBjb250cm9scyB1c2luZyB0aGUgcG93ZXIgb2YgQ3VzdG9tRWxlbWVudC5cbiAqXG4gKiBBZnRlciBkZWZpbmluZyBhIGBDdXN0b21FbGVtZW50YCwgdGhlIGByZWdpc3RlckN1c3RvbUVsZW1lbnRgIG1ldGhvZCBtdXN0IGJlIGNhbGxlZCB3aXRoIHRoZSBuZXcgY2xhc3MgbmFtZS4gT25seSB0aGVuXG4gKiB3aWxsIHRoZSB0YWcgZGVmaW5lZCB2aWEgdGhlIGBnZXRUYWdgIG1ldGhvZCBiZSBtYWRlIGtub3duIHRvIHRoZSBET00uXG4gKlxuICogPGltZyBzcmM9XCIuL2ltYWdlcy9jdXN0b21jb250cm9sLWNsYXNzLnBuZ1wiPlxuICpcbiAqIFRoaXMgY29udHJvbCB1c2VzIGBhdHRhY2hJbnRlcm5hbHMoKWAgdG8gaW50ZWdyYXRlIHRoZSBjb250cm9sIGludG8gYSBmb3JtLiBJZiB0aGUgdGFyZ2V0IGVudmlyb25tZW50IGRvZXMgbm90IHN1cHBvcnRcbiAqIHRoaXMgbWV0aG9kLCB0aGUgW3BvbHlmaWxsXShodHRwczovL3d3dy5ucG1qcy5jb20vcGFja2FnZS9lbGVtZW50LWludGVybmFscy1wb2x5ZmlsbCkgY2FuIGJlIHVzZWQuXG4gKlxuICogWW91IGNhbiBjcmVhdGUgdGhlIG9iamVjdCB1c2luZyB0aGUgZnVuY3Rpb24gYGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoKWAuXG4gKlxuICogVGhpcyBjb250cm9sIHVzZXMgYGF0dGFjaEludGVybmFscygpYCB0byBpbnRlZ3JhdGUgdGhlIGNvbnRyb2wgaW50byBhIGZvcm0uIElmIHRoZSB0YXJnZXQgZW52aXJvbm1lbnQgZG9lcyBub3Qgc3VwcG9ydFxuICogdGhpcyBtZXRob2QsIHRoZSBQb2x5ZmlsbCBmb3IgYXR0YWNoSW50ZXJuYWxzKCkgY2FuIGJlIHVzZWQ6IHtAbGluayBodHRwczovL3d3dy5ucG1qcy5jb20vcGFja2FnZS9lbGVtZW50LWludGVybmFscy1wb2x5ZmlsbHxlbGVtZW50LWludGVybmFscy1wb2x5ZmlsbH0uXG4gKlxuICogTGVhcm4gbW9yZSBhYm91dCBXSUNHIFdlYiBDb21wb25lbnRzOiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL1dJQ0cvd2ViY29tcG9uZW50c3xXSUNHIFdlYiBDb21wb25lbnRzfS5cbiAqXG4gKiBSZWFkIHRoZSBIVE1MIHNwZWNpZmljYXRpb24gZm9yIEN1c3RvbSBFbGVtZW50czoge0BsaW5rIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL2N1c3RvbS1lbGVtZW50cy5odG1sI2N1c3RvbS1lbGVtZW50c3xDdXN0b20gRWxlbWVudHN9LlxuICpcbiAqIFJlYWQgdGhlIEhUTUwgc3BlY2lmaWNhdGlvbiBmb3IgQ3VzdG9tIEVsZW1lbnQgUmVhY3Rpb25zOiB7QGxpbmsgaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9kZXYvY3VzdG9tLWVsZW1lbnRzLmh0bWwjY3VzdG9tLWVsZW1lbnQtcmVhY3Rpb25zfEN1c3RvbSBFbGVtZW50IFJlYWN0aW9uc30uXG4gKlxuICogQHN1bW1hcnkgQSBiYXNlIGNsYXNzIGZvciBjdXN0b20gY29udHJvbHMgYmFzZWQgb24gQ3VzdG9tRWxlbWVudC5cbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjE0LjBcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTVxuICogQGV4dGVuZHMgTW9uc3Rlci5ET00uQ3VzdG9tRWxlbWVudFxuICovXG5jbGFzcyBDdXN0b21Db250cm9sIGV4dGVuZHMgQ3VzdG9tRWxlbWVudCB7XG4gICAgLyoqXG4gICAgICogVGhlIGNvbnN0cnVjdG9yIG1ldGhvZCBvZiBDdXN0b21Db250cm9sLCB3aGljaCBpcyBjYWxsZWQgd2hlbiBjcmVhdGluZyBhIG5ldyBpbnN0YW5jZS5cbiAgICAgKiBJdCBjaGVja3Mgd2hldGhlciB0aGUgZWxlbWVudCBzdXBwb3J0cyBgYXR0YWNoSW50ZXJuYWxzKClgIGFuZCBpbml0aWFsaXplcyBhbiBpbnRlcm5hbCBmb3JtLWFzc29jaWF0ZWQgZWxlbWVudFxuICAgICAqIGlmIHN1cHBvcnRlZC4gQWRkaXRpb25hbGx5LCBpdCBpbml0aWFsaXplcyBhIE11dGF0aW9uT2JzZXJ2ZXIgdG8gd2F0Y2ggZm9yIGF0dHJpYnV0ZSBjaGFuZ2VzLlxuICAgICAqXG4gICAgICogU2VlIHRoZSBsaW5rcyBiZWxvdyBmb3IgbW9yZSBpbmZvcm1hdGlvbjpcbiAgICAgKiB7QGxpbmsgaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2UvY3VzdG9tLWVsZW1lbnRzLmh0bWwjZG9tLWN1c3RvbWVsZW1lbnRyZWdpc3RyeS1kZWZpbmV8Q3VzdG9tRWxlbWVudFJlZ2lzdHJ5LmRlZmluZSgpfVxuICAgICAqIHtAbGluayBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9jdXN0b20tZWxlbWVudHMuaHRtbCNkb20tY3VzdG9tZWxlbWVudHJlZ2lzdHJ5LWdldHxDdXN0b21FbGVtZW50UmVnaXN0cnkuZ2V0KCl9XG4gICAgICogYW5kIHtAbGluayBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRWxlbWVudEludGVybmFsc3xFbGVtZW50SW50ZXJuYWxzfVxuICAgICAqXG4gICAgICogQGluaGVyaXRkb2NcbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gdGhlIEVsZW1lbnRJbnRlcm5hbHMgaXMgbm90IHN1cHBvcnRlZCBhbmQgYSBwb2x5ZmlsbCBpcyBuZWNlc3NhcnlcbiAgICAgKiBAc2luY2UgMS43LjBcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoKTtcblxuICAgICAgICAvLyBjaGVjayBpZiBlbGVtZW50IHN1cHBvcnRzIGBhdHRhY2hJbnRlcm5hbHMoKWBcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzW1wiYXR0YWNoSW50ZXJuYWxzXCJdID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRoaXNbYXR0YWNoZWRJbnRlcm5hbFN5bWJvbF0gPSB0aGlzLmF0dGFjaEludGVybmFscygpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gYGF0dGFjaEludGVybmFscygpYCBpcyBub3Qgc3VwcG9ydGVkLCBzbyBhIHBvbHlmaWxsIGlzIG5lY2Vzc2FyeVxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoXCJ0aGUgRWxlbWVudEludGVybmFscyBpcyBub3Qgc3VwcG9ydGVkIGFuZCBhIHBvbHlmaWxsIGlzIG5lY2Vzc2FyeVwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGluaXRpYWxpemUgYSBNdXRhdGlvbk9ic2VydmVyIHRvIHdhdGNoIGZvciBhdHRyaWJ1dGUgY2hhbmdlc1xuICAgICAgICBpbml0T2JzZXJ2ZXIuY2FsbCh0aGlzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGBpbnN0YW5jZW9mYCBvcGVyYXRvci5cbiAgICAgKiBAcmV0dXJucyB7c3ltYm9sfVxuICAgICAqIEBzaW5jZSAyLjEuMFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgW2luc3RhbmNlU3ltYm9sXSgpIHtcbiAgICAgICAgcmV0dXJuIFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL2RvbS9jdXN0b20tY29udHJvbEBAaW5zdGFuY2VcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgZGV0ZXJtaW5lcyB3aGljaCBhdHRyaWJ1dGVzIGFyZSB0byBiZSBtb25pdG9yZWQgYnkgYGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjaygpYC5cbiAgICAgKlxuICAgICAqIEByZXR1cm4ge3N0cmluZ1tdfVxuICAgICAqIEBzaW5jZSAxLjE1LjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IG9ic2VydmVkQXR0cmlidXRlcygpIHtcbiAgICAgICAgcmV0dXJuIHN1cGVyLm9ic2VydmVkQXR0cmlidXRlcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBZGRpbmcgYSBzdGF0aWMgYGZvcm1Bc3NvY2lhdGVkYCBwcm9wZXJ0eSwgd2l0aCBhIHRydWUgdmFsdWUsIG1ha2VzIGFuIGF1dG9ub21vdXMgY3VzdG9tIGVsZW1lbnQgYSBmb3JtLWFzc29jaWF0ZWQgY3VzdG9tIGVsZW1lbnQuXG4gICAgICpcbiAgICAgKiBAc2VlIFthdHRhY2hJbnRlcm5hbHMoKV17QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0hUTUxFbGVtZW50L2F0dGFjaEludGVybmFsc31cbiAgICAgKiBAc2VlIFtDdXN0b20gRWxlbWVudHMgRmFjZSBFeGFtcGxlXXtAbGluayBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9jdXN0b20tZWxlbWVudHMuaHRtbCNjdXN0b20tZWxlbWVudHMtZmFjZS1leGFtcGxlfVxuICAgICAqIEBzaW5jZSAxLjE0LjBcbiAgICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgICAqL1xuICAgIHN0YXRpYyBmb3JtQXNzb2NpYXRlZCA9IHRydWU7XG5cbiAgICAvKipcbiAgICAgKiBAaW5oZXJpdGRvY1xuICAgICAqIEBzaW5jZSAxLjE0LjBcbiAgICAgKiovXG4gICAgZ2V0IGRlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gZXh0ZW5kKHt9LCBzdXBlci5kZWZhdWx0cyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTXVzdCBiZSBvdmVycmlkZGVuIGJ5IGEgZGVyaXZlZCBjbGFzcyBhbmQgcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgY29udHJvbC5cbiAgICAgKlxuICAgICAqIFRoaXMgaXMgYSBtZXRob2Qgb2YgW2ludGVybmFsIEFQSV0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0VsZW1lbnRJbnRlcm5hbHMpLCB3aGljaCBpcyBhIHBhcnQgb2YgdGhlIHdlYiBzdGFuZGFyZCBmb3IgY3VzdG9tIGVsZW1lbnRzLlxuICAgICAqXG4gICAgICogQHNpbmNlIDEuMTQuMFxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSB0aGUgdmFsdWUgZ2V0dGVyIG11c3QgYmUgb3ZlcndyaXR0ZW4gYnkgdGhlIGRlcml2ZWQgY2xhc3NcbiAgICAgKi9cbiAgICBnZXQgdmFsdWUoKSB7XG4gICAgICAgIHRocm93IEVycm9yKFwidGhlIHZhbHVlIGdldHRlciBtdXN0IGJlIG92ZXJ3cml0dGVuIGJ5IHRoZSBkZXJpdmVkIGNsYXNzXCIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE11c3QgYmUgb3ZlcnJpZGRlbiBieSBhIGRlcml2ZWQgY2xhc3MgYW5kIHNldCB0aGUgdmFsdWUgb2YgdGhlIGNvbnRyb2wuXG4gICAgICpcbiAgICAgKiBUaGlzIGlzIGEgbWV0aG9kIG9mIFtpbnRlcm5hbCBBUEldKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FbGVtZW50SW50ZXJuYWxzKSwgd2hpY2ggaXMgYSBwYXJ0IG9mIHRoZSB3ZWIgc3RhbmRhcmQgZm9yIGN1c3RvbSBlbGVtZW50cy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNldC5cbiAgICAgKiBAc2luY2UgMS4xNC4wXG4gICAgICogQHRocm93cyB7RXJyb3J9IHRoZSB2YWx1ZSBzZXR0ZXIgbXVzdCBiZSBvdmVyd3JpdHRlbiBieSB0aGUgZGVyaXZlZCBjbGFzc1xuICAgICAqL1xuICAgIHNldCB2YWx1ZSh2YWx1ZSkge1xuICAgICAgICB0aHJvdyBFcnJvcihcInRoZSB2YWx1ZSBzZXR0ZXIgbXVzdCBiZSBvdmVyd3JpdHRlbiBieSB0aGUgZGVyaXZlZCBjbGFzc1wiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGlzIGEgbWV0aG9kIG9mIFtpbnRlcm5hbCBhcGldKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FbGVtZW50SW50ZXJuYWxzKVxuICAgICAqXG4gICAgICogQHJldHVybiB7Tm9kZUxpc3R9XG4gICAgICogQHNpbmNlIDEuMTQuMFxuICAgICAqIEBzZWUge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FbGVtZW50SW50ZXJuYWxzL2xhYmVsc31cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gdGhlIEVsZW1lbnRJbnRlcm5hbHMgaXMgbm90IHN1cHBvcnRlZCBhbmQgYSBwb2x5ZmlsbCBpcyBuZWNlc3NhcnlcbiAgICAgKi9cbiAgICBnZXQgbGFiZWxzKCkge1xuICAgICAgICByZXR1cm4gZ2V0SW50ZXJuYWwuY2FsbCh0aGlzKT8ubGFiZWxzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgaXMgYSBtZXRob2Qgb2YgW2ludGVybmFsIGFwaV0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0VsZW1lbnRJbnRlcm5hbHMpXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtzdHJpbmd8bnVsbH1cbiAgICAgKi9cbiAgICBnZXQgbmFtZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKFwibmFtZVwiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGlzIGEgbWV0aG9kIG9mIFtpbnRlcm5hbCBhcGldKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FbGVtZW50SW50ZXJuYWxzKVxuICAgICAqXG4gICAgICogQHJldHVybiB7c3RyaW5nfVxuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci5nZXRUYWcoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGlzIGEgbWV0aG9kIG9mIFtpbnRlcm5hbCBhcGldKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FbGVtZW50SW50ZXJuYWxzKVxuICAgICAqXG4gICAgICogQHJldHVybiB7VmFsaWRpdHlTdGF0ZX1cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gdGhlIEVsZW1lbnRJbnRlcm5hbHMgaXMgbm90IHN1cHBvcnRlZCBhbmQgYSBwb2x5ZmlsbCBpcyBuZWNlc3NhcnlcbiAgICAgKiBAc2VlIFtWYWxpZGl0eVN0YXRlXXtAbGluayBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvVmFsaWRpdHlTdGF0ZX1cbiAgICAgKiBAc2VlIFt2YWxpZGl0eV17QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL3ZhbGlkaXR5fVxuICAgICAqL1xuICAgIGdldCB2YWxpZGl0eSgpIHtcbiAgICAgICAgcmV0dXJuIGdldEludGVybmFsLmNhbGwodGhpcyk/LnZhbGlkaXR5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgaXMgYSBtZXRob2Qgb2YgW2ludGVybmFsIGFwaV0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0VsZW1lbnRJbnRlcm5hbHMpXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAgICogQHNpbmNlIDEuMTQuMFxuICAgICAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0VsZW1lbnRJbnRlcm5hbHMvdmFsaWRhdGlvbk1lc3NhZ2VcbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gdGhlIEVsZW1lbnRJbnRlcm5hbHMgaXMgbm90IHN1cHBvcnRlZCBhbmQgYSBwb2x5ZmlsbCBpcyBuZWNlc3NhcnlcbiAgICAgKi9cbiAgICBnZXQgdmFsaWRhdGlvbk1lc3NhZ2UoKSB7XG4gICAgICAgIHJldHVybiBnZXRJbnRlcm5hbC5jYWxsKHRoaXMpPy52YWxpZGF0aW9uTWVzc2FnZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGlzIGEgbWV0aG9kIG9mIFtpbnRlcm5hbCBhcGldKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FbGVtZW50SW50ZXJuYWxzKVxuICAgICAqXG4gICAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICAgKiBAc2luY2UgMS4xNC4wXG4gICAgICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRWxlbWVudEludGVybmFscy93aWxsVmFsaWRhdGVcbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gdGhlIEVsZW1lbnRJbnRlcm5hbHMgaXMgbm90IHN1cHBvcnRlZCBhbmQgYSBwb2x5ZmlsbCBpcyBuZWNlc3NhcnlcbiAgICAgKi9cbiAgICBnZXQgd2lsbFZhbGlkYXRlKCkge1xuICAgICAgICByZXR1cm4gZ2V0SW50ZXJuYWwuY2FsbCh0aGlzKT8ud2lsbFZhbGlkYXRlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgaXMgYSBtZXRob2Qgb2YgW2ludGVybmFsIGFwaV0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0VsZW1lbnRJbnRlcm5hbHMpXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgICAqIEBzaW5jZSAxLjE0LjBcbiAgICAgKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FbGVtZW50SW50ZXJuYWxzL3N0YXRlc1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSB0aGUgRWxlbWVudEludGVybmFscyBpcyBub3Qgc3VwcG9ydGVkIGFuZCBhIHBvbHlmaWxsIGlzIG5lY2Vzc2FyeVxuICAgICAqL1xuICAgIGdldCBzdGF0ZXMoKSB7XG4gICAgICAgIHJldHVybiBnZXRJbnRlcm5hbC5jYWxsKHRoaXMpPy5zdGF0ZXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBpcyBhIG1ldGhvZCBvZiBbaW50ZXJuYWwgYXBpXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRWxlbWVudEludGVybmFscylcbiAgICAgKlxuICAgICAqIEByZXR1cm4ge0hUTUxGb250RWxlbWVudHxudWxsfVxuICAgICAqIEBzaW5jZSAxLjE0LjBcbiAgICAgKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FbGVtZW50SW50ZXJuYWxzL2Zvcm1cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gdGhlIEVsZW1lbnRJbnRlcm5hbHMgaXMgbm90IHN1cHBvcnRlZCBhbmQgYSBwb2x5ZmlsbCBpcyBuZWNlc3NhcnlcbiAgICAgKi9cbiAgICBnZXQgZm9ybSgpIHtcbiAgICAgICAgcmV0dXJuIGdldEludGVybmFsLmNhbGwodGhpcyk/LmZvcm07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBpcyBhIG1ldGhvZCBvZiBbaW50ZXJuYWwgYXBpXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRWxlbWVudEludGVybmFscylcbiAgICAgKlxuICAgICAqIGBgYFxuICAgICAqIC8vIFVzZSB0aGUgY29udHJvbCdzIG5hbWUgYXMgdGhlIGJhc2UgbmFtZSBmb3Igc3VibWl0dGVkIGRhdGFcbiAgICAgKiBjb25zdCBuID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ25hbWUnKTtcbiAgICAgKiBjb25zdCBlbnRyaWVzID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgICogZW50cmllcy5hcHBlbmQobiArICctZmlyc3QtbmFtZScsIHRoaXMuZmlyc3ROYW1lXyk7XG4gICAgICogZW50cmllcy5hcHBlbmQobiArICctbGFzdC1uYW1lJywgdGhpcy5sYXN0TmFtZV8pO1xuICAgICAqIHRoaXMuc2V0Rm9ybVZhbHVlKGVudHJpZXMpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQHBhcmFtIHtGaWxlfHN0cmluZ3xGb3JtRGF0YX0gdmFsdWVcbiAgICAgKiBAcGFyYW0ge0ZpbGV8c3RyaW5nfEZvcm1EYXRhfSBzdGF0ZVxuICAgICAqIEBzaW5jZSAxLjE0LjBcbiAgICAgKiBAcmV0dXJuIHt1bmRlZmluZWR9XG4gICAgICogQHRocm93cyB7RE9NRXhjZXB0aW9ufSBOb3RTdXBwb3J0ZWRFcnJvclxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSB0aGUgRWxlbWVudEludGVybmFscyBpcyBub3Qgc3VwcG9ydGVkIGFuZCBhIHBvbHlmaWxsIGlzIG5lY2Vzc2FyeVxuICAgICAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0VsZW1lbnRJbnRlcm5hbHMvc2V0Rm9ybVZhbHVlXG4gICAgICovXG4gICAgc2V0Rm9ybVZhbHVlKHZhbHVlLCBzdGF0ZSkge1xuICAgICAgICBnZXRJbnRlcm5hbC5jYWxsKHRoaXMpLnNldEZvcm1WYWx1ZSh2YWx1ZSwgc3RhdGUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtvYmplY3R9IGZsYWdzXG4gICAgICogQHBhcmFtIHtzdHJpbmd8dW5kZWZpbmVkfSBtZXNzYWdlXG4gICAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gYW5jaG9yXG4gICAgICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRWxlbWVudEludGVybmFscy9zZXRWYWxpZGl0eVxuICAgICAqIEBzaW5jZSAxLjE0LjBcbiAgICAgKiBAcmV0dXJuIHt1bmRlZmluZWR9XG4gICAgICogQHRocm93cyB7RE9NRXhjZXB0aW9ufSBOb3RTdXBwb3J0ZWRFcnJvclxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSB0aGUgRWxlbWVudEludGVybmFscyBpcyBub3Qgc3VwcG9ydGVkIGFuZCBhIHBvbHlmaWxsIGlzIG5lY2Vzc2FyeVxuICAgICAqL1xuICAgIHNldFZhbGlkaXR5KGZsYWdzLCBtZXNzYWdlLCBhbmNob3IpIHtcbiAgICAgICAgZ2V0SW50ZXJuYWwuY2FsbCh0aGlzKS5zZXRWYWxpZGl0eShmbGFncywgbWVzc2FnZSwgYW5jaG9yKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGlzIGEgbWV0aG9kIG9mIFtpbnRlcm5hbCBhcGldKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FbGVtZW50SW50ZXJuYWxzKVxuICAgICAqXG4gICAgICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRWxlbWVudEludGVybmFscy9jaGVja1ZhbGlkaXR5XG4gICAgICogQHNpbmNlIDEuMTQuMFxuICAgICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAgICogQHRocm93cyB7RE9NRXhjZXB0aW9ufSBOb3RTdXBwb3J0ZWRFcnJvclxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSB0aGUgRWxlbWVudEludGVybmFscyBpcyBub3Qgc3VwcG9ydGVkIGFuZCBhIHBvbHlmaWxsIGlzIG5lY2Vzc2FyeVxuICAgICAqL1xuICAgIGNoZWNrVmFsaWRpdHkoKSB7XG4gICAgICAgIHJldHVybiBnZXRJbnRlcm5hbC5jYWxsKHRoaXMpPy5jaGVja1ZhbGlkaXR5KCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBpcyBhIG1ldGhvZCBvZiBbaW50ZXJuYWwgYXBpXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRWxlbWVudEludGVybmFscylcbiAgICAgKlxuICAgICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAgICogQHNpbmNlIDEuMTQuMFxuICAgICAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0VsZW1lbnRJbnRlcm5hbHMvcmVwb3J0VmFsaWRpdHlcbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gdGhlIEVsZW1lbnRJbnRlcm5hbHMgaXMgbm90IHN1cHBvcnRlZCBhbmQgYSBwb2x5ZmlsbCBpcyBuZWNlc3NhcnlcbiAgICAgKiBAdGhyb3dzIHtET01FeGNlcHRpb259IE5vdFN1cHBvcnRlZEVycm9yXG4gICAgICovXG4gICAgcmVwb3J0VmFsaWRpdHkoKSB7XG4gICAgICAgIHJldHVybiBnZXRJbnRlcm5hbC5jYWxsKHRoaXMpPy5yZXBvcnRWYWxpZGl0eSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIGBmb3JtYCBhdHRyaWJ1dGUgb2YgdGhlIGN1c3RvbSBjb250cm9sIHRvIHRoZSBgaWRgIG9mIHRoZSBwYXNzZWQgZm9ybSBlbGVtZW50LlxuICAgICAqIElmIG5vIGZvcm0gZWxlbWVudCBpcyBwYXNzZWQsIHJlbW92ZXMgdGhlIGBmb3JtYCBhdHRyaWJ1dGUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0hUTUxGb3JtRWxlbWVudH0gZm9ybSAtIFRoZSBmb3JtIGVsZW1lbnQgdG8gYXNzb2NpYXRlIHdpdGggdGhlIGNvbnRyb2xcbiAgICAgKi9cbiAgICBmb3JtQXNzb2NpYXRlZENhbGxiYWNrKGZvcm0pIHtcbiAgICAgICAgaWYgKGZvcm0pIHtcbiAgICAgICAgICAgIGlmIChmb3JtLmlkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUoXCJmb3JtXCIsIGZvcm0uaWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5yZW1vdmVBdHRyaWJ1dGUoXCJmb3JtXCIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyBvciByZW1vdmVzIHRoZSBgZGlzYWJsZWRgIGF0dHJpYnV0ZSBvZiB0aGUgY3VzdG9tIGNvbnRyb2wgYmFzZWQgb24gdGhlIHBhc3NlZCB2YWx1ZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gZGlzYWJsZWQgLSBXaGV0aGVyIG9yIG5vdCB0aGUgY29udHJvbCBzaG91bGQgYmUgZGlzYWJsZWRcbiAgICAgKi9cbiAgICBmb3JtRGlzYWJsZWRDYWxsYmFjayhkaXNhYmxlZCkge1xuICAgICAgICBpZiAoZGlzYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKFwiZGlzYWJsZWRcIiwgXCJcIik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnJlbW92ZUF0dHJpYnV0ZShcImRpc2FibGVkXCIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0YXRlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG1vZGVcbiAgICAgKi9cbiAgICBmb3JtU3RhdGVSZXN0b3JlQ2FsbGJhY2soc3RhdGUsIG1vZGUpIHt9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqL1xuICAgIGZvcm1SZXNldENhbGxiYWNrKCkge1xuICAgICAgICB0aGlzLnZhbHVlID0gXCJcIjtcbiAgICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEByZXR1cm4ge29iamVjdH1cbiAqIEB0aHJvd3Mge0Vycm9yfSB0aGUgRWxlbWVudEludGVybmFscyBpcyBub3Qgc3VwcG9ydGVkIGFuZCBhIHBvbHlmaWxsIGlzIG5lY2Vzc2FyeVxuICogQHRoaXMgQ3VzdG9tQ29udHJvbFxuICovXG5mdW5jdGlvbiBnZXRJbnRlcm5hbCgpIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgIGlmICghKGF0dGFjaGVkSW50ZXJuYWxTeW1ib2wgaW4gdGhpcykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRWxlbWVudEludGVybmFscyBpcyBub3Qgc3VwcG9ydGVkIGFuZCBhIHBvbHlmaWxsIGlzIG5lY2Vzc2FyeVwiKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc2VsZlthdHRhY2hlZEludGVybmFsU3ltYm9sXTtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHJldHVybiB7b2JqZWN0fVxuICogQHRoaXMgQ3VzdG9tQ29udHJvbFxuICovXG5mdW5jdGlvbiBpbml0T2JzZXJ2ZXIoKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICAvLyB2YWx1ZVxuICAgIHNlbGZbYXR0cmlidXRlT2JzZXJ2ZXJTeW1ib2xdW1widmFsdWVcIl0gPSAoKSA9PiB7XG4gICAgICAgIHNlbGYuc2V0T3B0aW9uKFwidmFsdWVcIiwgc2VsZi5nZXRBdHRyaWJ1dGUoXCJ2YWx1ZVwiKSk7XG4gICAgfTtcbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IHJhbmRvbSB9IGZyb20gXCIuLi9tYXRoL3JhbmRvbS5tanNcIjtcbmltcG9ydCB7IGdldEdsb2JhbCB9IGZyb20gXCIuL2dsb2JhbC5tanNcIjtcbmltcG9ydCB7IElEIH0gZnJvbSBcIi4vaWQubWpzXCI7XG5cbmV4cG9ydCB7IFJhbmRvbUlEIH07XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKi9cbmxldCBpbnRlcm5hbENvdW50ZXIgPSAwO1xuXG4vKipcbiAqIFRoZSBgUmFuZG9tSURgIGNsYXNzIHByb3ZpZGVzIGEgdW5pcXVlIElEIGZvciBhbiBpdGVtLlxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuNi4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcbiAqIEBzdW1tYXJ5IGNsYXNzIHRvIGdlbmVyYXRlIHJhbmRvbSBudW1iZXJzXG4gKi9cbmNsYXNzIFJhbmRvbUlEIGV4dGVuZHMgSUQge1xuICAgIC8qKlxuICAgICAqIGNyZWF0ZSBuZXcgb2JqZWN0XG4gICAgICovXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCk7XG5cbiAgICAgICAgaW50ZXJuYWxDb3VudGVyICs9IDE7XG5cbiAgICAgICAgdGhpcy5pZCA9XG4gICAgICAgICAgICBnZXRHbG9iYWwoKVxuICAgICAgICAgICAgICAgIC5idG9hKHJhbmRvbSgxLCAxMDAwMCkpXG4gICAgICAgICAgICAgICAgLnJlcGxhY2UoLz0vZywgXCJcIilcbiAgICAgICAgICAgICAgICAvKiogTm8gbnVtYmVycyBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBJRCwgYmVjYXVzZSBvZiBwb3NzaWJsZSBwcm9ibGVtcyB3aXRoIERPTSAqL1xuICAgICAgICAgICAgICAgIC5yZXBsYWNlKC9eWzAtOV0rLywgXCJYXCIpICsgaW50ZXJuYWxDb3VudGVyO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGludGVybmFsU3ltYm9sIH0gZnJvbSBcIi4uL2NvbnN0YW50cy5tanNcIjtcbmltcG9ydCB7IHJhbmRvbSB9IGZyb20gXCIuLi9tYXRoL3JhbmRvbS5tanNcIjtcbmltcG9ydCB7IGlzT2JqZWN0IH0gZnJvbSBcIi4uL3R5cGVzL2lzLm1qc1wiO1xuaW1wb3J0IHsgQmFzZSB9IGZyb20gXCIuL2Jhc2UubWpzXCI7XG5pbXBvcnQgeyBnZXRHbG9iYWxPYmplY3QgfSBmcm9tIFwiLi9nbG9iYWwubWpzXCI7XG5cbmV4cG9ydCB7IFVVSUQgfTtcblxuLyoqXG4gKiBUaGUgVVVJRCBjbGFzcyBtYWtlcyBpdCBwb3NzaWJsZSB0byBnZXQgYSB1bmlxdWUgVVVJRCBmb3IgYW4gb2JqZWN0LlxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjUuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKiBAdGhyb3dzIHtFcnJvcn0gdW5zdXBwb3J0ZWRcbiAqL1xuY2xhc3MgVVVJRCBleHRlbmRzIEJhc2Uge1xuICAgIC8qKlxuICAgICAqXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCk7XG5cbiAgICAgICAgbGV0IHV1aWQgPSBjcmVhdGVXaXRoQ3J5cHRvKCk7XG5cbiAgICAgICAgaWYgKHV1aWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdXVpZCA9IGNyZWF0ZVdpdGhSYW5kb20oKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh1dWlkID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInVuc3VwcG9ydGVkXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpc1tpbnRlcm5hbFN5bWJvbF0gPSB7XG4gICAgICAgICAgICB2YWx1ZTogdXVpZCxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEByZXR1cm4ge3N0cmluZ31cbiAgICAgKi9cbiAgICB0b1N0cmluZygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbaW50ZXJuYWxTeW1ib2xdW1widmFsdWVcIl07XG4gICAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcmV0dXJuIHtzdHJpbmd8dW5kZWZpbmVkfVxuICovXG5mdW5jdGlvbiBjcmVhdGVXaXRoUmFuZG9tKCkge1xuICAgIHJldHVybiBcInh4eHh4eHh4LXh4eHgtNHh4eC15eHh4LXh4eHh4eHh4eHh4eFwiLnJlcGxhY2UoL1t4eV0vZywgZnVuY3Rpb24gKGMpIHtcbiAgICAgICAgY29uc3QgciA9IChyYW5kb20oMCwgNjUwMDApICogMTYpIHwgMDtcbiAgICAgICAgY29uc3QgdiA9IGMgPT09IFwieFwiID8gciA6IChyICYgMHgzKSB8IDB4ODtcbiAgICAgICAgcmV0dXJuIHYudG9TdHJpbmcoMTYpWzBdO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcmV0dXJuIHtzdHJpbmd8dW5kZWZpbmVkfVxuICovXG5mdW5jdGlvbiBjcmVhdGVXaXRoQ3J5cHRvKCkge1xuICAgIGNvbnN0IGNyeXB0ID0gZ2V0R2xvYmFsT2JqZWN0KFwiY3J5cHRvXCIpO1xuICAgIGlmICghaXNPYmplY3QoY3J5cHQpKSByZXR1cm47XG4gICAgaWYgKHR5cGVvZiBjcnlwdD8uW1wicmFuZG9tVVVJRFwiXSkgcmV0dXJuO1xuICAgIHJldHVybiBjcnlwdC5yYW5kb21VVUlEKCk7XG59XG4iLCAiaWYgKHR5cGVvZiB3aW5kb3cgPT09ICdvYmplY3QnKSB7XG5cbiAgICAoZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGxldCBzYXlzd2hvID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciB1YSA9IG5hdmlnYXRvci51c2VyQWdlbnQsIHRlbSxcbiAgICAgICAgICAgICAgICBNID0gdWEubWF0Y2goLyhvcGVyYXxjaHJvbWV8c2FmYXJpfGZpcmVmb3h8bXNpZXx0cmlkZW50KD89XFwvKSlcXC8/XFxzKihcXGQrKS9pKSB8fCBbXTtcbiAgICAgICAgICAgIGlmICgvdHJpZGVudC9pLnRlc3QoTVsxXSkpIHtcbiAgICAgICAgICAgICAgICB0ZW0gPSAvXFxicnZbIDpdKyhcXGQrKS9nLmV4ZWModWEpIHx8IFtdO1xuICAgICAgICAgICAgICAgIHJldHVybiAnSUUgJyArICh0ZW1bMV0gfHwgJycpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKE1bMV0gPT09ICdDaHJvbWUnKSB7XG4gICAgICAgICAgICAgICAgdGVtID0gdWEubWF0Y2goL1xcYihPUFJ8RWRnZSlcXC8oXFxkKykvKTtcbiAgICAgICAgICAgICAgICBpZiAodGVtICE9IG51bGwpIHJldHVybiB0ZW0uc2xpY2UoMSkuam9pbignICcpLnJlcGxhY2UoJ09QUicsICdPcGVyYScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgTSA9IE1bMl0gPyBbTVsxXSwgTVsyXV0gOiBbbmF2aWdhdG9yLmFwcE5hbWUsIG5hdmlnYXRvci5hcHBWZXJzaW9uLCAnLT8nXTtcbiAgICAgICAgICAgIGlmICgodGVtID0gdWEubWF0Y2goL3ZlcnNpb25cXC8oXFxkKykvaSkpICE9IG51bGwpIE0uc3BsaWNlKDEsIDEsIHRlbVsxXSk7XG4gICAgICAgICAgICByZXR1cm4gTS5qb2luKCcgJyk7XG4gICAgICAgIH0pKCk7XG5cblxuICAgICAgICBsZXQgZWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2gxJylcbiAgICAgICAgZWxlbWVudC5pbm5lckhUTUwgKz0gXCIgXCIgKyBzYXlzd2hvO1xuXG4gICAgfSkoKTtcblxuXG59XG4iLCAiaW1wb3J0IGNoYWkgZnJvbSAnLi9pbmRleC5qcyc7XG5cbmV4cG9ydCBjb25zdCBleHBlY3QgPSBjaGFpLmV4cGVjdDtcbmV4cG9ydCBjb25zdCB2ZXJzaW9uID0gY2hhaS52ZXJzaW9uO1xuZXhwb3J0IGNvbnN0IEFzc2VydGlvbiA9IGNoYWkuQXNzZXJ0aW9uO1xuZXhwb3J0IGNvbnN0IEFzc2VydGlvbkVycm9yID0gY2hhaS5Bc3NlcnRpb25FcnJvcjtcbmV4cG9ydCBjb25zdCB1dGlsID0gY2hhaS51dGlsO1xuZXhwb3J0IGNvbnN0IGNvbmZpZyA9IGNoYWkuY29uZmlnO1xuZXhwb3J0IGNvbnN0IHVzZSA9IGNoYWkudXNlO1xuZXhwb3J0IGNvbnN0IHNob3VsZCA9IGNoYWkuc2hvdWxkO1xuZXhwb3J0IGNvbnN0IGFzc2VydCA9IGNoYWkuYXNzZXJ0O1xuZXhwb3J0IGNvbnN0IGNvcmUgPSBjaGFpLmNvcmU7XG5cbmV4cG9ydCBkZWZhdWx0IGNoYWk7XG4iLCAiaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7Rm9ybWF0dGVyfSBmcm9tIFwiLi4vLi4vLi4vc291cmNlL3RleHQvZm9ybWF0dGVyLm1qc1wiO1xuXG5cbmRlc2NyaWJlKCdGb3JtYXR0ZXInLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAvLyBodHRwczovL2dpdGxhYi5zY2h1a2FpLmNvbS9vc3MvbGlicmFyaWVzL2phdmFzY3JpcHQvbW9uc3Rlci8tL2lzc3Vlcy80N1xuICAgIGRlc2NyaWJlKCdleGFtcGxlcycsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBpdCgncmZjIGV4YW1wbGUgc2hvdWxkIHJ1bicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgRm9ybWF0dGVyKHtcblxuICAgICAgICAgICAgICAgIGE6IHtcbiAgICAgICAgICAgICAgICAgICAgYjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgYzogXCJIZWxsb1wiXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGQ6IFwiV29ybGRcIixcbiAgICAgICAgICAgICAgICAgICAgZTogMVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgfSkuZm9ybWF0KFwiJHthLmIuY30gJHthLmQgfCB0b3VwcGVyfSFcIikpLnRvLmJlLmVxdWFsKCdIZWxsbyBXT1JMRCEnKTtcbiAgICAgICAgfSlcblxuICAgICAgICBpdCgnZG9jIGV4YW1wbGUgc2hvdWxkIHJ1bicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgRm9ybWF0dGVyKHtcblxuICAgICAgICAgICAgICAgIGE6IHtcbiAgICAgICAgICAgICAgICAgICAgYjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgYzogXCJIZWxsb1wiXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGQ6IFwid29ybGRcIixcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIH0pLmZvcm1hdChcIiR7YS5iLmN9ICR7YS5kIHwgdWNmaXJzdH0hXCIpKS50by5iZS5lcXVhbCgnSGVsbG8gV29ybGQhJyk7XG4gICAgICAgIH0pXG5cblxuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnc2V0IG1hcmtlcigpJywgZnVuY3Rpb24gKCkge1xuXG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWycjYSMnLCAnIycsIHVuZGVmaW5lZCwgJ3Rlc3QnXSxcbiAgICAgICAgICAgIFsne2F9JywgJ3snLCAnfScsICd0ZXN0J10sXG4gICAgICAgICAgICBbJ2kxOG57YX0nLCAnaTE4bnsnLCAnfScsICd0ZXN0J10sXG5cbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGMgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBkID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGl0KCdmb3JtYXQgJyArIGEgKyAnIHdpdGggbWFya2VyICcgKyBiICsgJyBhbmQgJyArIGMgKyAnIHNob3VsZCByZXR1cm4gICcgKyBiLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgICAgICBleHBlY3QoXG4gICAgICAgICAgICAgICAgICAgIG5ldyBGb3JtYXR0ZXIoe1xuICAgICAgICAgICAgICAgICAgICAgICAgYTogXCJ0ZXN0XCJcbiAgICAgICAgICAgICAgICAgICAgfSkuc2V0TWFya2VyKGIsIGMpLmZvcm1hdChhKVxuICAgICAgICAgICAgICAgICkudG8uZXF1YWwoZClcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuXG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCdleGFtcGxlcygpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIFtcbiAgICAgICAgICAgIFsnJHthIHwgdG9qc29ufScsIFwie1xcXCJiXFxcIjp7XFxcImNcXFwiOlxcXCJIZWxsb1xcXCJ9LFxcXCJkXFxcIjpcXFwiV29ybGRcXFwiLFxcXCJlXFxcIjoxfVwiXSxcbiAgICAgICAgICAgIFsnY2xpY2sgJHthLmR9IHRpbWVzJywgXCJjbGljayBXb3JsZCB0aW1lc1wiXSxcbiAgICAgICAgICAgIFsnICR7YS5iLmN9ICcsICcgSGVsbG8gJ10sXG4gICAgICAgICAgICBbJyAke2EuYi5jfScsICcgSGVsbG8nXSxcbiAgICAgICAgICAgIFsnJHthLmIuY30gJywgJ0hlbGxvICddLFxuICAgICAgICAgICAgWycke2EuYi5jfScsICdIZWxsbyddLFxuICAgICAgICAgICAgWycke2EuYi5jfSR7YS5iLmN9JywgJ0hlbGxvSGVsbG8nXSxcbiAgICAgICAgICAgIFsnJHthLmIuY30gJHthLmIuY30nLCAnSGVsbG8gSGVsbG8nXSxcbiAgICAgICAgICAgIFsnJHthLmIuY30gJHthLmIuY30gJywgJ0hlbGxvIEhlbGxvICddLFxuICAgICAgICAgICAgWycgJHthLmIuY30gJHthLmIuY30gJywgJyBIZWxsbyBIZWxsbyAnXSxcbiAgICAgICAgICAgIFsnICR7YS5iLmN9ICR7YS5kfSAnLCAnIEhlbGxvIFdvcmxkICddLFxuICAgICAgICAgICAgWycgJHthLmIuY30gJHthLmIuYyB8IHRvdXBwZXIgfCBsZW5ndGggfCB0b3N0cmluZ30gJywgJyBIZWxsbyA1ICddLFxuXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ2Zvcm1hdCAnICsgYSArICcgc2hvdWxkIHJldHVybiAnICsgYiwgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICAgICAgbGV0IG9iaiA9IHtcbiAgICAgICAgICAgICAgICAgICAgYToge1xuICAgICAgICAgICAgICAgICAgICAgICAgYjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGM6IFwiSGVsbG9cIlxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGQ6IFwiV29ybGRcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGU6IDFcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuXG4gICAgICAgICAgICAgICAgZXhwZWN0KG5ldyBGb3JtYXR0ZXIob2JqKS5mb3JtYXQoYSkpLmlzLmVxdWFsKGIpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdNYXJrZXIgaW4gbWFya2VyJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGxldCB0ZXh0ID0gJyR7bXlrZXkke3N1YmtleX19JztcbiAgICAgICAgbGV0IGV4cGVjdGVkID0gJzEnO1xuXG4gICAgICAgIGl0KCdmb3JtYXQgJyArIHRleHQgKyAnIHNob3VsZCAnICsgZXhwZWN0ZWQsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgbGV0IG9iaiA9IHtcbiAgICAgICAgICAgICAgICBteWtleTI6IFwiMVwiLFxuICAgICAgICAgICAgICAgIHN1YmtleTogXCIyXCJcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGV4cGVjdChuZXcgRm9ybWF0dGVyKG9iaikuZm9ybWF0KHRleHQpKS5pcy5lcXVhbChleHBlY3RlZClcblxuICAgICAgICB9KTtcblxuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnc2V0UGFyYW1ldGVyQ2hhcnMoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBpdCgnc2V0UGFyYW1ldGVyQ2hhcnMoKSBzaG91bGQgcmV0dXJuIEluc3RhbmNlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KG5ldyBGb3JtYXR0ZXIoe30pLnNldFBhcmFtZXRlckNoYXJzKCdhJywgJ2InKSkuaXMuaW5zdGFuY2VvZihGb3JtYXR0ZXIpO1xuXG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxuXG4gICAgZGVzY3JpYmUoJ3dpdGggY2FsbGJhY2tzJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdhZGQgY2FsbGJhY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zdCBmb3JtYXR0ZXIgPSBuZXcgRm9ybWF0dGVyKHtcbiAgICAgICAgICAgICAgICB4OiAnMSdcbiAgICAgICAgICAgIH0sIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFja3M6IHtcbiAgICAgICAgICAgICAgICAgICAgbXk6ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiIVwiICsgdmFsdWUgKyBcIiFcIlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGV4cGVjdChmb3JtYXR0ZXIuZm9ybWF0KCcke3ggfCBjYWxsOm15fScpKS5pcy5lcXVhbCgnITEhJyk7XG5cbiAgICAgICAgfSk7XG5cblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ01hcmtlciBpbiBtYXJrZXIgd2l0aCBwYXJhbWV0ZXInLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgbGV0IHRleHQgPSAnJHtteWtleTo6bXlrZXk9JHtzdWJrZXl9fSc7XG4gICAgICAgIGxldCBleHBlY3RlZCA9ICcyJztcblxuICAgICAgICBpdCgnZm9ybWF0ICcgKyB0ZXh0ICsgJyBzaG91bGQgJyArIGV4cGVjdGVkLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIGxldCBvYmogPSB7XG4gICAgICAgICAgICAgICAgc3Via2V5OiBcIjJcIlxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgZXhwZWN0KG5ldyBGb3JtYXR0ZXIob2JqKS5mb3JtYXQodGV4dCkpLmlzLmVxdWFsKGV4cGVjdGVkKVxuXG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2V4Y2VwdGlvbnMnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWycke2EuYi54fScsIFR5cGVFcnJvcl0sXG4gICAgICAgICAgICBbJyR7YS5iLmQgfCB0b3VwcGVyIHwgbGVuZ3RofScsIFR5cGVFcnJvcl0sXG4gICAgICAgICAgICBbJyR7YS5iLmR9JywgVHlwZUVycm9yXSwgIC8vIGEuYi5kIHJldHVybiB1bmRlZmluZWQgYnkgcGF0aGZpbmRlciBcbiAgICAgICAgICAgIFsnJHthLmIuZCB8IHRvbG93ZXJ9JywgVHlwZUVycm9yXSwgIC8vIGEuYi5kIHJldHVybiB1bmRlZmluZWQgYnkgcGF0aGZpbmRlciBcbiAgICAgICAgICAgIFsnJHthIHwgfScsIEVycm9yXSxcblxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGl0KCdmb3JtYXQgJyArIGEgKyAnIHNob3VsZCB0aHJvdyAnICsgdHlwZW9mIGIsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgIGV4cGVjdCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBuZXcgRm9ybWF0dGVyKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGI6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGM6IFwidGVzdFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZDogNFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfSkuZm9ybWF0KGEpXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApLnRvLnRocm93KGIpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cblxuXG5cbiAgICBkZXNjcmliZSgnRm9ybWF0dGVyJywgKCkgPT4ge1xuICAgICAgICBpdCgnc2hvdWxkIGZvcm1hdCBhIGJhc2ljIHN0cmluZyB3aXRoIG9iamVjdCB2YWx1ZXMnLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBmb3JtYXR0ZXIgPSBuZXcgRm9ybWF0dGVyKHtuYW1lOiAnSm9obicsIGFnZTogMzB9KTtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGZvcm1hdHRlci5mb3JtYXQoJ015IG5hbWUgaXMgJHtuYW1lfSBhbmQgSSBhbSAke2FnZSB8IHRvc3RyaW5nfSB5ZWFycyBvbGQuJyk7XG5cbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHQpLnRvLmVxdWFsKCdNeSBuYW1lIGlzIEpvaG4gYW5kIEkgYW0gMzAgeWVhcnMgb2xkLicpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIGZvcm1hdCBhIHN0cmluZyB3aXRoIG5lc3RlZCBtYXJrZXJzJywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdGV4dCA9ICcke215a2V5JHtzdWJrZXl9fSc7XG4gICAgICAgICAgICBjb25zdCBvYmogPSB7bXlrZXkyOiAnMScsIHN1YmtleTogJzInfTtcbiAgICAgICAgICAgIGNvbnN0IGZvcm1hdHRlciA9IG5ldyBGb3JtYXR0ZXIob2JqKTtcblxuICAgICAgICAgICAgZXhwZWN0KGZvcm1hdHRlci5mb3JtYXQodGV4dCkpLnRvLmVxdWFsKCcxJyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgZm9ybWF0IGEgc3RyaW5nIHdpdGggY3VzdG9tIG1hcmtlcnMnLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBmb3JtYXR0ZXIgPSBuZXcgRm9ybWF0dGVyKHtuYW1lOiAnSm9obicsIGFnZTogMzB9KTtcbiAgICAgICAgICAgIGZvcm1hdHRlci5zZXRNYXJrZXIoJ1snLCAnXScpO1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gZm9ybWF0dGVyLmZvcm1hdCgnTXkgbmFtZSBpcyBbbmFtZV0gYW5kIEkgYW0gW2FnZSB8IHRvc3RyaW5nXSB5ZWFycyBvbGQuJyk7XG5cbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHQpLnRvLmVxdWFsKCdNeSBuYW1lIGlzIEpvaG4gYW5kIEkgYW0gMzAgeWVhcnMgb2xkLicpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIGZvcm1hdCBhIHN0cmluZyB1c2luZyBjYWxsYmFjaycsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGZvcm1hdHRlciA9IG5ldyBGb3JtYXR0ZXIoe3g6ICcxJ30sIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFja3M6IHtcbiAgICAgICAgICAgICAgICAgICAgcXVvdGU6ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICdcIicgKyB2YWx1ZSArICdcIic7XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBleHBlY3QoZm9ybWF0dGVyLmZvcm1hdCgnJHt4IHwgY2FsbDpxdW90ZX0nKSkudG8uZXF1YWwoJ1wiMVwiJyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgZm9ybWF0IGEgc3RyaW5nIHdpdGggcGFyYW1ldGVycycsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG9iaiA9IHtcbiAgICAgICAgICAgICAgICBhOiB7XG4gICAgICAgICAgICAgICAgICAgIGI6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGM6ICdIZWxsbycsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGQ6ICd3b3JsZCcsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBmb3JtYXR0ZXIgPSBuZXcgRm9ybWF0dGVyKG9iaik7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBmb3JtYXR0ZXIuZm9ybWF0KCcke2EuYi5jfSAke2EuZCB8IHVjZmlyc3R9IScpO1xuXG4gICAgICAgICAgICBleHBlY3QocmVzdWx0KS50by5lcXVhbCgnSGVsbG8gV29ybGQhJyk7XG4gICAgICAgIH0pO1xuICAgICAgICBcbiAgICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBhIHRvbyBkZWVwIG5lc3RpbmcgZXJyb3InLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBmb3JtYXR0ZXIgPSBuZXcgRm9ybWF0dGVyKHtuYW1lOiAnSm9obid9KTtcbiAgICAgICAgICAgIGNvbnN0IG5lc3RlZFRleHQgPSAnJHtuYW1lJHtuYW1lJHtuYW1lJHtuYW1lJHtuYW1lJHtuYW1lJHtuYW1lJHtuYW1lJHtuYW1lJHtuYW1lJHtuYW1lJHtuYW1lJHtuYW1lJHtuYW1lJHtuYW1lJHtuYW1lJHtuYW1lJHtuYW1lJHtuYW1lfX19fX19fX19fX19fX19fX19JztcbiAgICAgICAgICAgIGV4cGVjdCgoKSA9PiBmb3JtYXR0ZXIuZm9ybWF0KG5lc3RlZFRleHQpKS50by50aHJvdygnc3ludGF4IGVycm9yIGluIGZvcm1hdHRlciB0ZW1wbGF0ZScpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHRocm93IGEgdG9vIGRlZXAgbmVzdGluZyBlcnJvcicsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGlucHV0T2JqID0ge1xuICAgICAgICAgICAgICAgIG15a2V5OiAnJHtteWtleX0nLFxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3QgZm9ybWF0dGVyID0gbmV3IEZvcm1hdHRlcihpbnB1dE9iaik7XG5cbiAgICAgICAgICAgIGNvbnN0IHRleHQgPSAnJHtteWtleX0nO1xuICAgICAgICAgICAgbGV0IGZvcm1hdHRlZFRleHQgPSB0ZXh0O1xuXG4gICAgICAgICAgICAvLyBDcmVhdGUgYSBzdHJpbmcgd2l0aCAyMSBsZXZlbHMgb2YgbmVzdGluZ1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCAyMTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgZm9ybWF0dGVkVGV4dCA9ICckeycgKyBmb3JtYXR0ZWRUZXh0ICsgJ30nO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBleHBlY3QoKCkgPT4gZm9ybWF0dGVyLmZvcm1hdChmb3JtYXR0ZWRUZXh0KSkudG8udGhyb3coJ3RvbyBkZWVwIG5lc3RpbmcnKTtcbiAgICAgICAgfSk7XG4gICAgICAgIFxuICAgIH0pO1xuXG5cbn0pOyIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmV4cG9ydCB7IGdlbmVyYXRlUmFuZ2VDb21wYXJpc29uRXhwcmVzc2lvbiB9O1xuXG4vKipcbiAqIFRoZSBgZ2VuZXJhdGVSYW5nZUNvbXBhcmlzb25FeHByZXNzaW9uKClgIGZ1bmN0aW9uIGlzIGZ1bmN0aW9uIHRoYXQgZ2VuZXJhdGVzIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uXG4gKiBvZiBhIGNvbXBhcmlzb24gZXhwcmVzc2lvbiBiYXNlZCBvbiBhIHJhbmdlIG9mIHZhbHVlcy4gSXQgdGFrZXMgdGhyZWUgYXJndW1lbnRzOlxuICpcbiAqIC0gZXhwcmVzc2lvbiAocmVxdWlyZWQpOiBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIHJhbmdlIG9mIHZhbHVlcyBpbiB0aGUgZm9ybWF0IG9mIHN0YXJ0MS1lbmQxLHN0YXJ0Mi1lbmQyLHZhbHVlMy4uLi5cbiAqIC0gdmFsdWVOYW1lIChyZXF1aXJlZCk6IGEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgbmFtZSBvZiB0aGUgdmFsdWUgdGhhdCBpcyBiZWluZyBjb21wYXJlZCB0byB0aGUgcmFuZ2Ugb2YgdmFsdWVzLlxuICogLSBvcHRpb25zIChvcHRpb25hbCk6IGFuIG9iamVjdCBjb250YWluaW5nIGFkZGl0aW9uYWwgb3B0aW9ucyB0byBjdXN0b21pemUgdGhlIGNvbXBhcmlzb24gZXhwcmVzc2lvbi5cbiAqXG4gKiBUaGUgZ2VuZXJhdGVSYW5nZUNvbXBhcmlzb25FeHByZXNzaW9uKCkgZnVuY3Rpb24gcmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgY29tcGFyaXNvbiBleHByZXNzaW9uLlxuICpcbiAqICMjIE9wdGlvbnNcbiAqIFRoZSBvcHRpb25zIHBhcmFtZXRlciBpcyBhbiBvYmplY3QgdGhhdCBjYW4gaGF2ZSB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gKlxuICogdXJsRW5jb2RlIChib29sZWFuLCBkZWZhdWx0OiBmYWxzZSk6IGlmIHNldCB0byB0cnVlLCBVUkwgZW5jb2RlcyB0aGUgY29tcGFyaXNvbiBvcGVyYXRvcnMuXG4gKiBhbmRPcCAoc3RyaW5nLCBkZWZhdWx0OiAnJiYnKTogdGhlIGxvZ2ljYWwgQU5EIG9wZXJhdG9yIHRvIHVzZSBpbiB0aGUgZXhwcmVzc2lvbi5cbiAqIG9yT3AgKHN0cmluZywgZGVmYXVsdDogJ3x8Jyk6IHRoZSBsb2dpY2FsIE9SIG9wZXJhdG9yIHRvIHVzZSBpbiB0aGUgZXhwcmVzc2lvbi5cbiAqIGVxT3AgKHN0cmluZywgZGVmYXVsdDogJz09Jyk6IHRoZSBlcXVhbGl0eSBvcGVyYXRvciB0byB1c2UgaW4gdGhlIGV4cHJlc3Npb24uXG4gKiBnZU9wIChzdHJpbmcsIGRlZmF1bHQ6ICc+PScpOiB0aGUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIG9wZXJhdG9yIHRvIHVzZSBpbiB0aGUgZXhwcmVzc2lvbi5cbiAqIGxlT3AgKHN0cmluZywgZGVmYXVsdDogJzw9Jyk6IHRoZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gb3BlcmF0b3IgdG8gdXNlIGluIHRoZSBleHByZXNzaW9uLlxuICpcbiAqIEV4YW1wbGVzXG4gKlxuICogYGBgamF2YXNjcmlwdFxuICogY29uc3QgZXhwcmVzc2lvbiA9ICcwLTEwLDIwLTMwJztcbiAqIGNvbnN0IHZhbHVlTmFtZSA9ICdhZ2UnO1xuICogY29uc3Qgb3B0aW9ucyA9IHsgdXJsRW5jb2RlOiB0cnVlLCBhbmRPcDogJ2FuZCcsIG9yT3A6ICdvcicsIGVxT3A6ICc9JywgZ2VPcDogJz49JywgbGVPcDogJzw9JyB9O1xuICogY29uc3QgY29tcGFyaXNvbkV4cHJlc3Npb24gPSBnZW5lcmF0ZVJhbmdlQ29tcGFyaXNvbkV4cHJlc3Npb24oZXhwcmVzc2lvbiwgdmFsdWVOYW1lLCBvcHRpb25zKTtcbiAqXG4gKiBjb25zb2xlLmxvZyhjb21wYXJpc29uRXhwcmVzc2lvbik7IC8vIGFnZSUzRSUzRDAlMjBhbmQlMjBhZ2UlM0MlM0QxMCUyMG9yJTIwYWdlJTNFJTNEMjAlMjBhbmQlMjBhZ2UlM0MlM0QzMFxuICogYGBgXG4gKlxuICogSW4gdGhpcyBleGFtcGxlLCB0aGUgZ2VuZXJhdGVSYW5nZUNvbXBhcmlzb25FeHByZXNzaW9uKCkgZnVuY3Rpb24gZ2VuZXJhdGVzIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjb21wYXJpc29uXG4gKiBleHByZXNzaW9uIGZvciB0aGUgZXhwcmVzc2lvbiBhbmQgdmFsdWVOYW1lIHBhcmFtZXRlcnMgd2l0aCB0aGUgc3BlY2lmaWVkIG9wdGlvbnMuIFRoZSByZXN1bHRpbmcgY29tcGFyaXNvblxuICogZXhwcmVzc2lvbiBpcyAnYWdlPj0wIGFuZCBhZ2U8PTEwIG9yIGFnZT49MjAgYW5kIGFnZTw9MzAnLCBVUkwgZW5jb2RlZCBhY2NvcmRpbmcgdG8gdGhlIHVybEVuY29kZSBvcHRpb24uXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGV4cHJlc3Npb24gLSBUaGUgc3RyaW5nIGV4cHJlc3Npb24gdG8gZ2VuZXJhdGUgdGhlIGNvbXBhcmlzb24gZm9yLlxuICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB2YWx1ZSB0byBjb21wYXJlIGFnYWluc3QuXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIC0gVGhlIG9wdGlvbmFsIHBhcmFtZXRlcnMuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLnVybEVuY29kZT1mYWxzZV0gLSBXaGV0aGVyIHRvIGVuY29kZSBjb21wYXJpc29uIG9wZXJhdG9ycyBmb3IgdXNlIGluIGEgVVJMLlxuICogQHBhcmFtIHtzdHJpbmd9IFtvcHRpb25zLmFuZE9wPScmJiddIC0gVGhlIGxvZ2ljYWwgQU5EIG9wZXJhdG9yIHRvIHVzZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0aW9ucy5vck9wPSd8fCddIC0gVGhlIGxvZ2ljYWwgT1Igb3BlcmF0b3IgdG8gdXNlLlxuICogQHBhcmFtIHtzdHJpbmd9IFtvcHRpb25zLmVxT3A9Jz09J10gLSBUaGUgY29tcGFyaXNvbiBvcGVyYXRvciBmb3IgZXF1YWxpdHkgdG8gdXNlLlxuICogQHBhcmFtIHtzdHJpbmd9IFtvcHRpb25zLmdlT3A9Jz49J10gLSBUaGUgY29tcGFyaXNvbiBvcGVyYXRvciBmb3IgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRvIHVzZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0aW9ucy5sZU9wPSc8PSddIC0gVGhlIGNvbXBhcmlzb24gb3BlcmF0b3IgZm9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byB0byB1c2UuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZ2VuZXJhdGVkIGNvbXBhcmlzb24gZXhwcmVzc2lvbi5cbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgaW5wdXQgaXMgaW52YWxpZC5cbiAqIEBtZW1iZXJPZiBNb25zdGVyLlRleHRcbiAqIEBzdW1tYXJ5IEdlbmVyYXRlcyBhIGNvbXBhcmlzb24gZXhwcmVzc2lvbiBiYXNlZCBvbiBhIHJhbmdlIG9mIHZhbHVlcy5cbiAqL1xuZnVuY3Rpb24gZ2VuZXJhdGVSYW5nZUNvbXBhcmlzb25FeHByZXNzaW9uKGV4cHJlc3Npb24sIHZhbHVlTmFtZSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3QgeyB1cmxFbmNvZGUgPSBmYWxzZSwgYW5kT3AgPSBcIiYmXCIsIG9yT3AgPSBcInx8XCIsIGVxT3AgPSBcIj09XCIsIGdlT3AgPSBcIj49XCIsIGxlT3AgPSBcIjw9XCIgfSA9IG9wdGlvbnM7XG4gICAgY29uc3QgcmFuZ2VzID0gZXhwcmVzc2lvbi5zcGxpdChcIixcIik7XG4gICAgbGV0IGNvbXBhcmlzb24gPSBcIlwiO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IHJhbmdlID0gcmFuZ2VzW2ldLnRyaW0oKTtcbiAgICAgICAgaWYgKHJhbmdlID09PSBcIlwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgcmFuZ2UgJyR7cmFuZ2V9J2ApO1xuICAgICAgICB9IGVsc2UgaWYgKHJhbmdlLmluY2x1ZGVzKFwiLVwiKSkge1xuICAgICAgICAgICAgY29uc3QgW3N0YXJ0LCBlbmRdID0gcmFuZ2Uuc3BsaXQoXCItXCIpLm1hcCgocykgPT4gKHMgPT09IFwiXCIgPyBudWxsIDogcGFyc2VGbG9hdChzKSkpO1xuICAgICAgICAgICAgaWYgKChzdGFydCAhPT0gbnVsbCAmJiBpc05hTihzdGFydCkpIHx8IChlbmQgIT09IG51bGwgJiYgaXNOYU4oZW5kKSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgdmFsdWUgaW4gcmFuZ2UgJyR7cmFuZ2V9J2ApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHN0YXJ0ICE9PSBudWxsICYmIGVuZCAhPT0gbnVsbCAmJiBzdGFydCA+IGVuZCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCByYW5nZSAnJHtyYW5nZX0nYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBjb21wU3RhcnQgPVxuICAgICAgICAgICAgICAgIHN0YXJ0ICE9PSBudWxsID8gYCR7dmFsdWVOYW1lfSR7dXJsRW5jb2RlID8gZW5jb2RlVVJJQ29tcG9uZW50KGdlT3ApIDogZ2VPcH0ke3N0YXJ0fWAgOiBcIlwiO1xuICAgICAgICAgICAgY29uc3QgY29tcEVuZCA9IGVuZCAhPT0gbnVsbCA/IGAke3ZhbHVlTmFtZX0ke3VybEVuY29kZSA/IGVuY29kZVVSSUNvbXBvbmVudChsZU9wKSA6IGxlT3B9JHtlbmR9YCA6IFwiXCI7XG4gICAgICAgICAgICBjb25zdCBjb21wUmFuZ2UgPSBgJHtjb21wU3RhcnR9JHtjb21wU3RhcnQgJiYgY29tcEVuZCA/IGAgJHthbmRPcH0gYCA6IFwiXCJ9JHtjb21wRW5kfWA7XG4gICAgICAgICAgICBjb21wYXJpc29uICs9IHJhbmdlcy5sZW5ndGggPiAxID8gYCgke2NvbXBSYW5nZX0pYCA6IGNvbXBSYW5nZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gcGFyc2VGbG9hdChyYW5nZSk7XG4gICAgICAgICAgICBpZiAoaXNOYU4odmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHZhbHVlICcke3JhbmdlfSdgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGNvbXBWYWx1ZSA9IGAke3ZhbHVlTmFtZX0ke3VybEVuY29kZSA/IGVuY29kZVVSSUNvbXBvbmVudChlcU9wKSA6IGVxT3B9JHt2YWx1ZX1gO1xuICAgICAgICAgICAgY29tcGFyaXNvbiArPSByYW5nZXMubGVuZ3RoID4gMSA/IGAoJHtjb21wVmFsdWV9KWAgOiBjb21wVmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGkgPCByYW5nZXMubGVuZ3RoIC0gMSkge1xuICAgICAgICAgICAgY29tcGFyaXNvbiArPSBgICR7b3JPcH0gYDtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gY29tcGFyaXNvbjtcbn1cbiIsICJpbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuaW1wb3J0IHtnZW5lcmF0ZVJhbmdlQ29tcGFyaXNvbkV4cHJlc3Npb259IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvdGV4dC91dGlsLm1qc1wiO1xuXG5kZXNjcmliZSgnZ2VuZXJhdGVSYW5nZUNvbXBhcmlzb25FeHByZXNzaW9uJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgY29ycmVjdCBjb21wYXJpc29uIGV4cHJlc3Npb24gZm9yIHNpbmdsZSB2YWx1ZXMnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGV4cHJlc3Npb24gPSAnMSwzLDUnO1xuICAgICAgICBjb25zdCB2YWx1ZU5hbWUgPSAneCc7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGdlbmVyYXRlUmFuZ2VDb21wYXJpc29uRXhwcmVzc2lvbihleHByZXNzaW9uLCB2YWx1ZU5hbWUpO1xuICAgICAgICBleHBlY3QocmVzdWx0KS50by5lcXVhbCgnKHg9PTEpIHx8ICh4PT0zKSB8fCAoeD09NSknKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgY29ycmVjdCBjb21wYXJpc29uIGV4cHJlc3Npb24gZm9yIHJhbmdlcycsICgpID0+IHtcbiAgICAgICAgY29uc3QgZXhwcmVzc2lvbiA9ICcxLTMsNi04JztcbiAgICAgICAgY29uc3QgdmFsdWVOYW1lID0gJ3gnO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBnZW5lcmF0ZVJhbmdlQ29tcGFyaXNvbkV4cHJlc3Npb24oZXhwcmVzc2lvbiwgdmFsdWVOYW1lKTtcbiAgICAgICAgZXhwZWN0KHJlc3VsdCkudG8uZXF1YWwoJyh4Pj0xICYmIHg8PTMpIHx8ICh4Pj02ICYmIHg8PTgpJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGNvcnJlY3QgY29tcGFyaXNvbiBleHByZXNzaW9uIGZvciBtaXhlZCByYW5nZXMgYW5kIHNpbmdsZSB2YWx1ZXMnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGV4cHJlc3Npb24gPSAnMS0zLDUsNy05JztcbiAgICAgICAgY29uc3QgdmFsdWVOYW1lID0gJ3gnO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBnZW5lcmF0ZVJhbmdlQ29tcGFyaXNvbkV4cHJlc3Npb24oZXhwcmVzc2lvbiwgdmFsdWVOYW1lKTtcbiAgICAgICAgZXhwZWN0KHJlc3VsdCkudG8uZXF1YWwoJyh4Pj0xICYmIHg8PTMpIHx8ICh4PT01KSB8fCAoeD49NyAmJiB4PD05KScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBhbiBlcnJvciBmb3IgaW52YWxpZCByYW5nZScsICgpID0+IHtcbiAgICAgICAgY29uc3QgZXhwcmVzc2lvbiA9ICcxLTMsNS00JztcbiAgICAgICAgY29uc3QgdmFsdWVOYW1lID0gJ3gnO1xuICAgICAgICBleHBlY3QoKCkgPT4gZ2VuZXJhdGVSYW5nZUNvbXBhcmlzb25FeHByZXNzaW9uKGV4cHJlc3Npb24sIHZhbHVlTmFtZSkpLnRvLnRocm93KGBJbnZhbGlkIHJhbmdlICc1LTQnYCk7XG4gICAgfSk7XG5cblxuICAgIGl0KCdzaG91bGQgdGhyb3cgYW4gZXJyb3IgZm9yIGludmFsaWQgdmFsdWUnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGV4cHJlc3Npb24gPSAnMS0zLGEnO1xuICAgICAgICBjb25zdCB2YWx1ZU5hbWUgPSAneCc7XG4gICAgICAgIGV4cGVjdCgoKSA9PiBnZW5lcmF0ZVJhbmdlQ29tcGFyaXNvbkV4cHJlc3Npb24oZXhwcmVzc2lvbiwgdmFsdWVOYW1lKSkudG8udGhyb3coJ0ludmFsaWQgdmFsdWUnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgY29ycmVjdCBjb21wYXJpc29uIGV4cHJlc3Npb24gd2l0aCBjdXN0b20gb3BlcmF0b3JzJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBleHByZXNzaW9uID0gJzEtMyw1JztcbiAgICAgICAgY29uc3QgdmFsdWVOYW1lID0gJ3gnO1xuICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgYW5kT3A6ICdBTkQnLFxuICAgICAgICAgICAgb3JPcDogJ09SJyxcbiAgICAgICAgICAgIGVxT3A6ICc9PT0nLFxuICAgICAgICAgICAgZ2VPcDogJz49JyxcbiAgICAgICAgICAgIGxlT3A6ICc8PScsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGdlbmVyYXRlUmFuZ2VDb21wYXJpc29uRXhwcmVzc2lvbihleHByZXNzaW9uLCB2YWx1ZU5hbWUsIG9wdGlvbnMpO1xuICAgICAgICBleHBlY3QocmVzdWx0KS50by5lcXVhbCgnKHg+PTEgQU5EIHg8PTMpIE9SICh4PT09NSknKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgY29ycmVjdCBjb21wYXJpc29uIGV4cHJlc3Npb24gd2l0aCB1cmxFbmNvZGUgb3B0aW9uJywgKCkgPT4ge1xuICAgICAgICBjb25zdCB0ZXN0Q2FzZXMgPSBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZXhwcmVzc2lvbjogJzEsMyw1JyxcbiAgICAgICAgICAgICAgICB2YWx1ZU5hbWU6ICd4JyxcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogJyh4JTNEJTNEMSkgfHwgKHglM0QlM0QzKSB8fCAoeCUzRCUzRDUpJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZXhwcmVzc2lvbjogJy0xMCcsXG4gICAgICAgICAgICAgICAgdmFsdWVOYW1lOiAneCcsXG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6ICd4JTNDJTNEMTAnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBleHByZXNzaW9uOiAnMTAtJyxcbiAgICAgICAgICAgICAgICB2YWx1ZU5hbWU6ICd4JyxcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogJ3glM0UlM0QxMCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGV4cHJlc3Npb246ICcxLTMsNi04JyxcbiAgICAgICAgICAgICAgICB2YWx1ZU5hbWU6ICd5JyxcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogJyh5JTNFJTNEMSAmJiB5JTNDJTNEMykgfHwgKHklM0UlM0Q2ICYmIHklM0MlM0Q4KScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGV4cHJlc3Npb246ICcxLTMsNSw3LTknLFxuICAgICAgICAgICAgICAgIHZhbHVlTmFtZTogJ3onLFxuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiAnKHolM0UlM0QxICYmIHolM0MlM0QzKSB8fCAoeiUzRCUzRDUpIHx8ICh6JTNFJTNENyAmJiB6JTNDJTNEOSknLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgXTtcblxuICAgICAgICB0ZXN0Q2FzZXMuZm9yRWFjaCgoe2V4cHJlc3Npb24sIHZhbHVlTmFtZSwgZXhwZWN0ZWR9KSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBnZW5lcmF0ZVJhbmdlQ29tcGFyaXNvbkV4cHJlc3Npb24oZXhwcmVzc2lvbiwgdmFsdWVOYW1lLCB7dXJsRW5jb2RlOiB0cnVlfSk7XG4gICAgICAgICAgICBleHBlY3QocmVzdWx0KS50by5lcXVhbChleHBlY3RlZCk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBjb3JyZWN0IGNvbXBhcmlzb24gZXhwcmVzc2lvbiBmb3Igb3Blbi1lbmRlZCByYW5nZXMgd2l0aCB1cmxFbmNvZGUgb3B0aW9uJywgKCkgPT4ge1xuICAgICAgICBjb25zdCB0ZXN0Q2FzZXMgPSBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZXhwcmVzc2lvbjogJzEwLScsXG4gICAgICAgICAgICAgICAgdmFsdWVOYW1lOiAneCcsXG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6ICd4JTNFJTNEMTAnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBleHByZXNzaW9uOiAnLTEwJyxcbiAgICAgICAgICAgICAgICB2YWx1ZU5hbWU6ICd5JyxcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogJ3klM0MlM0QxMCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICBdO1xuXG4gICAgICAgIHRlc3RDYXNlcy5mb3JFYWNoKCh7ZXhwcmVzc2lvbiwgdmFsdWVOYW1lLCBleHBlY3RlZH0pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGdlbmVyYXRlUmFuZ2VDb21wYXJpc29uRXhwcmVzc2lvbihleHByZXNzaW9uLCB2YWx1ZU5hbWUsIHt1cmxFbmNvZGU6IHRydWV9KTtcbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHQpLnRvLmVxdWFsKGV4cGVjdGVkKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cblxufSk7XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5leHBvcnQgeyBwYXJzZUJyYWNrZXRlZEtleVZhbHVlSGFzaCwgY3JlYXRlQnJhY2tldGVkS2V5VmFsdWVIYXNoIH07XG5cbi8qKlxuICogUGFyc2VzIGEgc3RyaW5nIGNvbnRhaW5pbmcgYnJhY2tldGVkIGtleS12YWx1ZSBwYWlycyBhbmQgcmV0dXJucyBhbiBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBwYXJzZWQgcmVzdWx0LlxuICpcbiAqIC0gVGhlIHN0cmluZyBzdGFydHMgd2l0aCBhIGhhc2ggc3ltYm9sICMuXG4gKiAtIEFmdGVyIHRoZSBoYXNoIHN5bWJvbCwgdGhlcmUgYXJlIG9uZSBvciBtb3JlIHNlbGVjdG9yIHN0cmluZ3MsIHNlcGFyYXRlZCBieSBhIHNlbWljb2xvbiA7LlxuICogLSBFYWNoIHNlbGVjdG9yIHN0cmluZyBoYXMgdGhlIGZvcm1hdCBzZWxlY3Rvck5hbWUoa2V5MT12YWx1ZTEsa2V5Mj12YWx1ZTIsLi4uKS5cbiAqIC0gVGhlIHNlbGVjdG9yIG5hbWUgaXMgYSBzdHJpbmcgb2Ygb25lIG9yIG1vcmUgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMuXG4gKiAtIFRoZSBrZXktdmFsdWUgcGFpcnMgYXJlIHNlcGFyYXRlZCBieSBjb21tYXMgLCBhbmQgYXJlIG9mIHRoZSBmb3JtIGtleT12YWx1ZS5cbiAqIC0gVGhlIGtleSBpcyBhIHN0cmluZyBvZiBvbmUgb3IgbW9yZSBhbHBoYW51bWVyaWMgY2hhcmFjdGVycy5cbiAqIC0gVGhlIHZhbHVlIGNhbiBiZSBhbiBlbXB0eSBzdHJpbmcgb3IgYSBzdHJpbmcgb2Ygb25lIG9yIG1vcmUgY2hhcmFjdGVycy5cbiAqIC0gSWYgdGhlIHZhbHVlIGNvbnRhaW5zIGNvbW1hcywgaXQgbXVzdCBiZSBlbmNsb3NlZCBpbiBkb3VibGUgcXVvdGVzIFwiLlxuICogLSBUaGUgZW50aXJlIGtleS12YWx1ZSBwYWlyIG11c3QgYmUgVVJMLWVuY29kZWQuXG4gKiAtIFRoZSBjbG9zaW5nIHBhcmVudGhlc2lzICkgZm9yIGVhY2ggc2VsZWN0b3IgbXVzdCBiZSBwcmVzZW50LCBldmVuIGlmIHRoZXJlIGFyZSBubyBrZXktdmFsdWUgcGFpcnMuXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiBgYGBqYXZhc2NyaXB0XG4gKiAvLyBFeGFtcGxlIDE6XG4gKiBjb25zdCBoYXNoU3RyaW5nID0gJyNzZWxlY3RvcjEoa2V5MT12YWx1ZTEsa2V5Mj12YWx1ZTIpO3NlbGVjdG9yMihrZXkzPXZhbHVlMyknO1xuICogY29uc3QgcmVzdWx0ID0gcGFyc2VCcmFja2V0ZWRLZXlWYWx1ZUhhc2goaGFzaFN0cmluZyk7XG4gKiAvLyByZXN1bHQgPT4geyBzZWxlY3RvcjE6IHsga2V5MTogXCJ2YWx1ZTFcIiwga2V5MjogXCJ2YWx1ZTJcIiB9LCBzZWxlY3RvcjI6IHsga2V5MzogXCJ2YWx1ZTNcIiB9IH1cbiAqIGBgYFxuICpcbiAqIEBleGFtcGxlXG4gKlxuICogYGBgamF2YXNjcmlwdFxuICogLy8gRXhhbXBsZSAyOlxuICogY29uc3QgaGFzaFN0cmluZyA9ICcjc2VsZWN0b3IxKGtleTE9dmFsdWUxLGtleTI9dmFsdWUyKTtzZWxlY3RvcjIoJztcbiAqIGNvbnN0IHJlc3VsdCA9IHBhcnNlQnJhY2tldGVkS2V5VmFsdWVIYXNoKGhhc2hTdHJpbmcpO1xuICogLy8gcmVzdWx0ID0+IHt9XG4gKiBgYGBcbiAqXG4gKiBAc2luY2UgMy4zNy4wXG4gKiBAcGFyYW0ge3N0cmluZ30gaGFzaFN0cmluZyAtIFRoZSBzdHJpbmcgdG8gcGFyc2UsIGNvbnRhaW5pbmcgYnJhY2tldGVkIGtleS12YWx1ZSBwYWlycy5cbiAqIEByZXR1cm5zIHtPYmplY3R9IC0gQW4gb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgcGFyc2VkIHJlc3VsdCwgd2l0aCBrZXlzIHJlcHJlc2VudGluZyB0aGUgc2VsZWN0b3JzIGFuZCB2YWx1ZXMgcmVwcmVzZW50aW5nIHRoZSBrZXktdmFsdWUgcGFpcnMgYXNzb2NpYXRlZCB3aXRoIGVhY2ggc2VsZWN0b3IuXG4gKiAgICAgICAgICAgICAgICAgICAgLSBSZXR1cm5zIGFuIGVtcHR5IG9iamVjdCBpZiB0aGVyZSB3YXMgYW4gZXJyb3IgZHVyaW5nIHBhcnNpbmcuICovXG5mdW5jdGlvbiBwYXJzZUJyYWNrZXRlZEtleVZhbHVlSGFzaChoYXNoU3RyaW5nKSB7XG4gICAgY29uc3Qgc2VsZWN0b3JzID0ge307XG4gICAgLy9jb25zdCBzZWxlY3RvclN0YWNrID0gW107XG4gICAgLy9jb25zdCBrZXlWYWx1ZVN0YWNrID0gW107XG5cbiAgICBjb25zdCB0cmltbWVkSGFzaFN0cmluZyA9IGhhc2hTdHJpbmcudHJpbSgpO1xuICAgIGNvbnN0IGNsZWFuZWRIYXNoU3RyaW5nID0gdHJpbW1lZEhhc2hTdHJpbmcuY2hhckF0KDApID09PSBcIiNcIiA/IHRyaW1tZWRIYXNoU3RyaW5nLnNsaWNlKDEpIDogdHJpbW1lZEhhc2hTdHJpbmc7XG5cbiAgICAvL2NvbnN0IHNlbGVjdG9ycyA9IChrZXlWYWx1ZVN0YWNrLmxlbmd0aCA+IDApID8gcmVzdWx0W3NlbGVjdG9yU3RhY2tbc2VsZWN0b3JTdGFjay5sZW5ndGggLSAxXV0gOiByZXN1bHQ7XG4gICAgbGV0IGN1cnJlbnRTZWxlY3RvciA9IFwiXCI7XG5cbiAgICBmdW5jdGlvbiBhZGRUb1Jlc3VsdChrZXksIHZhbHVlKSB7XG4gICAgICAgIGlmIChjdXJyZW50U2VsZWN0b3IgJiYga2V5KSB7XG4gICAgICAgICAgICBpZiAoIXNlbGVjdG9yc1tjdXJyZW50U2VsZWN0b3JdKSB7XG4gICAgICAgICAgICAgICAgc2VsZWN0b3JzW2N1cnJlbnRTZWxlY3Rvcl0gPSB7fTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgc2VsZWN0b3JzW2N1cnJlbnRTZWxlY3Rvcl1ba2V5XSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbGV0IGN1cnJlbnRLZXkgPSBcIlwiO1xuICAgIGxldCBjdXJyZW50VmFsdWUgPSBcIlwiO1xuICAgIGxldCBpbktleSA9IHRydWU7XG4gICAgbGV0IGluVmFsdWUgPSBmYWxzZTtcbiAgICBsZXQgaW5RdW90ZWRWYWx1ZSA9IGZhbHNlO1xuICAgIGxldCBpblNlbGVjdG9yID0gdHJ1ZTtcbiAgICBsZXQgZXNjYXBlZCA9IGZhbHNlO1xuICAgIGxldCBxdW90ZWRWYWx1ZVN0YXJ0Q2hhciA9IFwiXCI7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNsZWFuZWRIYXNoU3RyaW5nLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGMgPSBjbGVhbmVkSGFzaFN0cmluZ1tpXTtcbiAgICAgICAgY29uc3QgbmV4dENoYXIgPSBjbGVhbmVkSGFzaFN0cmluZz8uW2kgKyAxXTtcblxuICAgICAgICBpZiAoYyA9PT0gXCJcXFxcXCIgJiYgIWVzY2FwZWQpIHtcbiAgICAgICAgICAgIGVzY2FwZWQgPSB0cnVlO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZXNjYXBlZCkge1xuICAgICAgICAgICAgaWYgKGluU2VsZWN0b3IpIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50U2VsZWN0b3IgKz0gYztcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaW5LZXkpIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50S2V5ICs9IGM7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGluVmFsdWUpIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50VmFsdWUgKz0gYztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVzY2FwZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGluUXVvdGVkVmFsdWUgJiYgcXVvdGVkVmFsdWVTdGFydENoYXIgIT09IGMpIHtcbiAgICAgICAgICAgIGlmIChpblNlbGVjdG9yKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudFNlbGVjdG9yICs9IGM7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGluS2V5KSB7XG4gICAgICAgICAgICAgICAgY3VycmVudEtleSArPSBjO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChpblZhbHVlKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudFZhbHVlICs9IGM7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGMgPT09IFwiO1wiICYmIGluU2VsZWN0b3IpIHtcbiAgICAgICAgICAgIGluU2VsZWN0b3IgPSB0cnVlO1xuICAgICAgICAgICAgY3VycmVudFNlbGVjdG9yID0gXCJcIjtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGluU2VsZWN0b3IgPT09IHRydWUgJiYgYyAhPT0gXCIoXCIpIHtcbiAgICAgICAgICAgIGN1cnJlbnRTZWxlY3RvciArPSBjO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYyA9PT0gXCIoXCIgJiYgaW5TZWxlY3Rvcikge1xuICAgICAgICAgICAgaW5TZWxlY3RvciA9IGZhbHNlO1xuICAgICAgICAgICAgaW5LZXkgPSB0cnVlO1xuXG4gICAgICAgICAgICBjdXJyZW50S2V5ID0gXCJcIjtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGluS2V5ID09PSB0cnVlICYmIGMgIT09IFwiPVwiKSB7XG4gICAgICAgICAgICBjdXJyZW50S2V5ICs9IGM7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjID09PSBcIj1cIiAmJiBpbktleSkge1xuICAgICAgICAgICAgaW5LZXkgPSBmYWxzZTtcbiAgICAgICAgICAgIGluVmFsdWUgPSB0cnVlO1xuXG4gICAgICAgICAgICBpZiAobmV4dENoYXIgPT09ICdcIicgfHwgbmV4dENoYXIgPT09IFwiJ1wiKSB7XG4gICAgICAgICAgICAgICAgaW5RdW90ZWRWYWx1ZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgcXVvdGVkVmFsdWVTdGFydENoYXIgPSBuZXh0Q2hhcjtcbiAgICAgICAgICAgICAgICBpKys7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGN1cnJlbnRWYWx1ZSA9IFwiXCI7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpblZhbHVlID09PSB0cnVlKSB7XG4gICAgICAgICAgICBpZiAoaW5RdW90ZWRWYWx1ZSkge1xuICAgICAgICAgICAgICAgIGlmIChjID09PSBxdW90ZWRWYWx1ZVN0YXJ0Q2hhcikge1xuICAgICAgICAgICAgICAgICAgICBpblF1b3RlZFZhbHVlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGN1cnJlbnRWYWx1ZSArPSBjO1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoYyA9PT0gXCIsXCIpIHtcbiAgICAgICAgICAgICAgICBpblZhbHVlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgaW5LZXkgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGNvbnN0IGRlY29kZWRDdXJyZW50VmFsdWUgPSBkZWNvZGVVUklDb21wb25lbnQoY3VycmVudFZhbHVlKTtcbiAgICAgICAgICAgICAgICBhZGRUb1Jlc3VsdChjdXJyZW50S2V5LCBkZWNvZGVkQ3VycmVudFZhbHVlKTtcbiAgICAgICAgICAgICAgICBjdXJyZW50S2V5ID0gXCJcIjtcbiAgICAgICAgICAgICAgICBjdXJyZW50VmFsdWUgPSBcIlwiO1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoYyA9PT0gXCIpXCIpIHtcbiAgICAgICAgICAgICAgICBpblZhbHVlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgLy9pbktleSA9IHRydWU7XG4gICAgICAgICAgICAgICAgaW5TZWxlY3RvciA9IHRydWU7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBkZWNvZGVkQ3VycmVudFZhbHVlID0gZGVjb2RlVVJJQ29tcG9uZW50KGN1cnJlbnRWYWx1ZSk7XG4gICAgICAgICAgICAgICAgYWRkVG9SZXN1bHQoY3VycmVudEtleSwgZGVjb2RlZEN1cnJlbnRWYWx1ZSk7XG4gICAgICAgICAgICAgICAgY3VycmVudEtleSA9IFwiXCI7XG4gICAgICAgICAgICAgICAgY3VycmVudFZhbHVlID0gXCJcIjtcbiAgICAgICAgICAgICAgICBjdXJyZW50U2VsZWN0b3IgPSBcIlwiO1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjdXJyZW50VmFsdWUgKz0gYztcblxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaW5TZWxlY3Rvcikge1xuICAgICAgICByZXR1cm4gc2VsZWN0b3JzO1xuICAgIH1cblxuICAgIHJldHVybiB7fTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgaGFzaCBzZWxlY3RvciBzdHJpbmcgZnJvbSBhbiBvYmplY3QuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCAtIFRoZSBvYmplY3QgY29udGFpbmluZyBzZWxlY3RvcnMgYW5kIGtleS12YWx1ZSBwYWlycy5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gYWRkSGFzaFByZWZpeCAtIFdoZXRoZXIgdG8gYWRkIHRoZSBoYXNoIHByZWZpeCAjIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHN0cmluZy5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBoYXNoIHNlbGVjdG9yIHN0cmluZy5cbiAqIEBzaW5jZSAzLjM3LjBcbiAqL1xuZnVuY3Rpb24gY3JlYXRlQnJhY2tldGVkS2V5VmFsdWVIYXNoKG9iamVjdCwgYWRkSGFzaFByZWZpeCA9IHRydWUpIHtcbiAgICBpZiAoIW9iamVjdCkge1xuICAgICAgICByZXR1cm4gYWRkSGFzaFByZWZpeCA/IFwiI1wiIDogXCJcIjtcbiAgICB9XG5cbiAgICBsZXQgaGFzaFN0cmluZyA9IFwiXCI7XG5cbiAgICBmdW5jdGlvbiBlbmNvZGVLZXlWYWx1ZShrZXksIHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBlbmNvZGVVUklDb21wb25lbnQoa2V5KSArIFwiPVwiICsgZW5jb2RlVVJJQ29tcG9uZW50KHZhbHVlKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHNlbGVjdG9yIGluIG9iamVjdCkge1xuICAgICAgICBpZiAob2JqZWN0Lmhhc093blByb3BlcnR5KHNlbGVjdG9yKSkge1xuICAgICAgICAgICAgY29uc3Qga2V5VmFsdWVQYWlycyA9IG9iamVjdFtzZWxlY3Rvcl07XG4gICAgICAgICAgICBsZXQgc2VsZWN0b3JTdHJpbmcgPSBzZWxlY3RvcjtcbiAgICAgICAgICAgIGxldCBrZXlWYWx1ZVN0cmluZyA9IFwiXCI7XG5cbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIGtleVZhbHVlUGFpcnMpIHtcbiAgICAgICAgICAgICAgICBpZiAoa2V5VmFsdWVQYWlycy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0ga2V5VmFsdWVQYWlyc1trZXldO1xuICAgICAgICAgICAgICAgICAgICBrZXlWYWx1ZVN0cmluZyArPSBrZXlWYWx1ZVN0cmluZy5sZW5ndGggPT09IDAgPyBcIlwiIDogXCIsXCI7XG4gICAgICAgICAgICAgICAgICAgIGtleVZhbHVlU3RyaW5nICs9IGVuY29kZUtleVZhbHVlKGtleSwgdmFsdWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGtleVZhbHVlU3RyaW5nLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBzZWxlY3RvclN0cmluZyArPSBcIihcIiArIGtleVZhbHVlU3RyaW5nICsgXCIpXCI7XG4gICAgICAgICAgICAgICAgaGFzaFN0cmluZyArPSBoYXNoU3RyaW5nLmxlbmd0aCA9PT0gMCA/IFwiXCIgOiBcIjtcIjtcbiAgICAgICAgICAgICAgICBoYXNoU3RyaW5nICs9IHNlbGVjdG9yU3RyaW5nO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGFkZEhhc2hQcmVmaXggPyBcIiNcIiArIGhhc2hTdHJpbmcgOiBoYXNoU3RyaW5nO1xufVxuIiwgIi8vIHRlc3QuanNcbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiO1xuaW1wb3J0IHtcbiAgICBwYXJzZUJyYWNrZXRlZEtleVZhbHVlSGFzaCxcbiAgICBjcmVhdGVCcmFja2V0ZWRLZXlWYWx1ZUhhc2hcbn0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS90ZXh0L2JyYWNrZXRlZC1rZXktdmFsdWUtaGFzaC5tanNcIjtcblxuZGVzY3JpYmUoXCJwYXJzZUJyYWNrZXRlZEtleVZhbHVlSGFzaFwiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgcmV0dXJuIGFuIGVtcHR5IG9iamVjdCBmb3IgYW4gZW1wdHkgc3RyaW5nXCIsICgpID0+IHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSBcIlwiO1xuICAgICAgICBjb25zdCBleHBlY3RlZFJlc3VsdCA9IHt9O1xuICAgICAgICBleHBlY3QocGFyc2VCcmFja2V0ZWRLZXlWYWx1ZUhhc2goaW5wdXQpKS50by5kZWVwLmVxdWFsKGV4cGVjdGVkUmVzdWx0KTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIHBhcnNlIGEgc2luZ2xlIHNlbGVjdG9yIHdpdGggb25lIGtleS12YWx1ZSBwYWlyXCIsICgpID0+IHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSBcIiNzZWxlY3RvcjEoa2V5MT12YWx1ZTEpXCI7XG4gICAgICAgIGNvbnN0IGV4cGVjdGVkUmVzdWx0ID0ge1xuICAgICAgICAgICAgc2VsZWN0b3IxOiB7XG4gICAgICAgICAgICAgICAga2V5MTogXCJ2YWx1ZTFcIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICAgIGV4cGVjdChwYXJzZUJyYWNrZXRlZEtleVZhbHVlSGFzaChpbnB1dCkpLnRvLmRlZXAuZXF1YWwoZXhwZWN0ZWRSZXN1bHQpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgcGFyc2UgbXVsdGlwbGUgc2VsZWN0b3JzIHdpdGggbXVsdGlwbGUga2V5LXZhbHVlIHBhaXJzXCIsICgpID0+IHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSBcIiNzZWxlY3RvcjEoa2V5MT12YWx1ZTEsa2V5Mj12YWx1ZTIpO3NlbGVjdG9yMihrZXkzPXZhbHVlMyxrZXk0PXZhbHVlNClcIjtcbiAgICAgICAgY29uc3QgZXhwZWN0ZWRSZXN1bHQgPSB7XG4gICAgICAgICAgICBzZWxlY3RvcjE6IHtcbiAgICAgICAgICAgICAgICBrZXkxOiBcInZhbHVlMVwiLFxuICAgICAgICAgICAgICAgIGtleTI6IFwidmFsdWUyXCIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2VsZWN0b3IyOiB7XG4gICAgICAgICAgICAgICAga2V5MzogXCJ2YWx1ZTNcIixcbiAgICAgICAgICAgICAgICBrZXk0OiBcInZhbHVlNFwiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgICAgZXhwZWN0KHBhcnNlQnJhY2tldGVkS2V5VmFsdWVIYXNoKGlucHV0KSkudG8uZGVlcC5lcXVhbChleHBlY3RlZFJlc3VsdCk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBkZWNvZGUgVVJMLWVuY29kZWQgdmFsdWVzXCIsICgpID0+IHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSBcIiNzZWxlY3RvcjEoa2V5MT12YWx1ZTElMkN3aXRoJTIwY29tbWEpXCI7XG4gICAgICAgIGNvbnN0IGV4cGVjdGVkUmVzdWx0ID0ge1xuICAgICAgICAgICAgc2VsZWN0b3IxOiB7XG4gICAgICAgICAgICAgICAga2V5MTogXCJ2YWx1ZTEsd2l0aCBjb21tYVwiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gcGFyc2VCcmFja2V0ZWRLZXlWYWx1ZUhhc2goaW5wdXQpO1xuICAgICAgICBleHBlY3QocmVzdWx0LnNlbGVjdG9yMS5rZXkxKS50by5lcXVhbChleHBlY3RlZFJlc3VsdC5zZWxlY3RvcjEua2V5MSk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBoYW5kbGUgaW5wdXQgd2l0aG91dCBhIGxlYWRpbmcgaGFzaFwiLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGlucHV0ID0gXCJzZWxlY3RvcjEoa2V5MT12YWx1ZTEpXCI7XG4gICAgICAgIGNvbnN0IGV4cGVjdGVkUmVzdWx0ID0ge1xuICAgICAgICAgICAgc2VsZWN0b3IxOiB7XG4gICAgICAgICAgICAgICAga2V5MTogXCJ2YWx1ZTFcIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICAgIGV4cGVjdChwYXJzZUJyYWNrZXRlZEtleVZhbHVlSGFzaChpbnB1dCkpLnRvLmRlZXAuZXF1YWwoZXhwZWN0ZWRSZXN1bHQpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgcmV0dXJuIGFuIGVtcHR5IG9iamVjdCBmb3IgaW52YWxpZCBpbnB1dFwiLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGlucHV0ID0gXCIjc2VsZWN0b3IxKGtleTE9dmFsdWUxLGtleTJcIjtcbiAgICAgICAgY29uc3QgZXhwZWN0ZWRSZXN1bHQgPSB7fTtcbiAgICAgICAgZXhwZWN0KHBhcnNlQnJhY2tldGVkS2V5VmFsdWVIYXNoKGlucHV0KSkudG8uZGVlcC5lcXVhbChleHBlY3RlZFJlc3VsdCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBhbiBlbXB0eSBvYmplY3QgZm9yIGFuIGVtcHR5IGlucHV0IHN0cmluZycsICgpID0+IHtcbiAgICAgICAgY29uc3QgaGFzaFN0cmluZyA9ICcnO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBwYXJzZUJyYWNrZXRlZEtleVZhbHVlSGFzaChoYXNoU3RyaW5nKTtcbiAgICAgICAgZXhwZWN0KHJlc3VsdCkudG8uZGVlcC5lcXVhbCh7fSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBhbiBlbXB0eSBvYmplY3QgZm9yIGFuIGludmFsaWQgaW5wdXQgc3RyaW5nJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBoYXNoU3RyaW5nID0gJyNpbnZhbGlkJztcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gcGFyc2VCcmFja2V0ZWRLZXlWYWx1ZUhhc2goaGFzaFN0cmluZyk7XG4gICAgICAgIGV4cGVjdChyZXN1bHQpLnRvLmRlZXAuZXF1YWwoe30pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwYXJzZSBhIHNpbXBsZSBpbnB1dCBzdHJpbmcgd2l0aCBvbmUgc2VsZWN0b3IgYW5kIG9uZSBrZXktdmFsdWUgcGFpcicsICgpID0+IHtcbiAgICAgICAgY29uc3QgaGFzaFN0cmluZyA9ICcjc2VsZWN0b3Ioa2V5PXZhbHVlKSc7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHBhcnNlQnJhY2tldGVkS2V5VmFsdWVIYXNoKGhhc2hTdHJpbmcpO1xuICAgICAgICBleHBlY3QocmVzdWx0KS50by5kZWVwLmVxdWFsKHtzZWxlY3Rvcjoge2tleTogJ3ZhbHVlJ319KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcGFyc2UgYW4gaW5wdXQgc3RyaW5nIHdpdGggbXVsdGlwbGUgc2VsZWN0b3JzIGFuZCBrZXktdmFsdWUgcGFpcnMnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGhhc2hTdHJpbmcgPSAnI3NlbGVjdG9yMShrZXkxPXZhbHVlMSk7c2VsZWN0b3IyKGtleTI9dmFsdWUyKSc7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHBhcnNlQnJhY2tldGVkS2V5VmFsdWVIYXNoKGhhc2hTdHJpbmcpO1xuICAgICAgICBleHBlY3QocmVzdWx0KS50by5kZWVwLmVxdWFsKHtzZWxlY3RvcjE6IHtrZXkxOiAndmFsdWUxJ30sIHNlbGVjdG9yMjoge2tleTI6ICd2YWx1ZTInfX0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgZW1wdHkgdmFsdWVzJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBoYXNoU3RyaW5nID0gJyNzZWxlY3RvcihrZXkxPSxrZXkyPSknO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBwYXJzZUJyYWNrZXRlZEtleVZhbHVlSGFzaChoYXNoU3RyaW5nKTtcbiAgICAgICAgZXhwZWN0KHJlc3VsdCkudG8uZGVlcC5lcXVhbCh7c2VsZWN0b3I6IHtrZXkxOiAnJywga2V5MjogJyd9fSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhbmRsZSBwZXJjZW50LWVuY29kZWQgdmFsdWVzJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBoYXNoU3RyaW5nID0gJyNzZWxlY3RvcihrZXkxPXZhbHVlJTIwMSxrZXkyPXZhbHVlJTJDMiknO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBwYXJzZUJyYWNrZXRlZEtleVZhbHVlSGFzaChoYXNoU3RyaW5nKTtcbiAgICAgICAgZXhwZWN0KHJlc3VsdCkudG8uZGVlcC5lcXVhbCh7c2VsZWN0b3I6IHtrZXkxOiAndmFsdWUgMScsIGtleTI6ICd2YWx1ZSwyJ319KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGFuZGxlIGRvdWJsZS1xdW90ZWQgdmFsdWVzIHdpdGggY29tbWFzJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBoYXNoU3RyaW5nID0gJyNzZWxlY3RvcihrZXkxPVwidmFsdWUsMVwiLGtleTI9XCJ2YWx1ZSwyXCIpJztcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gcGFyc2VCcmFja2V0ZWRLZXlWYWx1ZUhhc2goaGFzaFN0cmluZyk7XG4gICAgICAgIGV4cGVjdChyZXN1bHQpLnRvLmRlZXAuZXF1YWwoe3NlbGVjdG9yOiB7a2V5MTogJ3ZhbHVlLDEnLCBrZXkyOiAndmFsdWUsMid9fSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGlnbm9yZSBsZWFkaW5nIGhhc2ggc3ltYm9sICgjKScsICgpID0+IHtcbiAgICAgICAgY29uc3QgaGFzaFN0cmluZyA9ICdzZWxlY3RvcihrZXk9dmFsdWUpJztcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gcGFyc2VCcmFja2V0ZWRLZXlWYWx1ZUhhc2goaGFzaFN0cmluZyk7XG4gICAgICAgIGV4cGVjdChyZXN1bHQpLnRvLmRlZXAuZXF1YWwoe3NlbGVjdG9yOiB7a2V5OiAndmFsdWUnfX0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBpZ25vcmUgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGUgc3BhY2UnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGhhc2hTdHJpbmcgPSAnICAjc2VsZWN0b3Ioa2V5PXZhbHVlKSAgJztcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gcGFyc2VCcmFja2V0ZWRLZXlWYWx1ZUhhc2goaGFzaFN0cmluZyk7XG4gICAgICAgIGV4cGVjdChyZXN1bHQpLnRvLmRlZXAuZXF1YWwoe3NlbGVjdG9yOiB7a2V5OiAndmFsdWUnfX0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gYW4gZW1wdHkgb2JqZWN0IGlmIHRoZSBpbnB1dCBzdHJpbmcgZW5kcyBwcmVtYXR1cmVseScsICgpID0+IHtcbiAgICAgICAgY29uc3QgaGFzaFN0cmluZyA9ICcjc2VsZWN0b3Ioa2V5PXZhbHVlJztcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gcGFyc2VCcmFja2V0ZWRLZXlWYWx1ZUhhc2goaGFzaFN0cmluZyk7XG4gICAgICAgIGV4cGVjdChyZXN1bHQpLnRvLmRlZXAuZXF1YWwoe30pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gYW4gZW1wdHkgb2JqZWN0IGlmIGEgc2VsZWN0b3IgaXMgbWlzc2luZycsICgpID0+IHtcbiAgICAgICAgY29uc3QgaGFzaFN0cmluZyA9ICcjKGtleT12YWx1ZSknO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBwYXJzZUJyYWNrZXRlZEtleVZhbHVlSGFzaChoYXNoU3RyaW5nKTtcbiAgICAgICAgZXhwZWN0KHJlc3VsdCkudG8uZGVlcC5lcXVhbCh7fSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBhbiBlbXB0eSBvYmplY3QgaWYgYSBrZXkgaXMgbWlzc2luZycsICgpID0+IHtcbiAgICAgICAgY29uc3QgaGFzaFN0cmluZyA9ICcjc2VsZWN0b3IoPXZhbHVlKSc7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHBhcnNlQnJhY2tldGVkS2V5VmFsdWVIYXNoKGhhc2hTdHJpbmcpO1xuICAgICAgICBleHBlY3QocmVzdWx0KS50by5kZWVwLmVxdWFsKHt9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGFuIGVtcHR5IG9iamVjdCBpZmEgdmFsdWUgaXMgbWlzc2luZycsICgpID0+IHtcbiAgICAgICAgY29uc3QgaGFzaFN0cmluZyA9ICcjc2VsZWN0b3Ioa2V5PSknO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBwYXJzZUJyYWNrZXRlZEtleVZhbHVlSGFzaChoYXNoU3RyaW5nKTtcbiAgICAgICAgZXhwZWN0KHJlc3VsdCkudG8uZGVlcC5lcXVhbCh7XG4gICAgICAgICAgICBzZWxlY3Rvcjoge1xuICAgICAgICAgICAgICAgIGtleTogJycsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGFuIGVtcHR5IG9iamVjdCBpZiB0aGVyZSBpcyBubyBjbG9zaW5nIHBhcmVudGhlc2lzIGZvciBhIHNlbGVjdG9yJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBoYXNoU3RyaW5nID0gJyNzZWxlY3RvcihrZXk9dmFsdWU7JztcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gcGFyc2VCcmFja2V0ZWRLZXlWYWx1ZUhhc2goaGFzaFN0cmluZyk7XG4gICAgICAgIGV4cGVjdChyZXN1bHQpLnRvLmRlZXAuZXF1YWwoe30pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gYW4gZW1wdHkgb2JqZWN0IGlmIHRoZXJlIGlzIG5vIHNlbWljb2xvbiBhZnRlciBhIHNlbGVjdG9yJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBoYXNoU3RyaW5nID0gJyNzZWxlY3RvcihrZXk9dmFsdWUpc2VsZWN0b3IyKGtleTI9dmFsdWUyKSc7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHBhcnNlQnJhY2tldGVkS2V5VmFsdWVIYXNoKGhhc2hTdHJpbmcpO1xuICAgICAgICBleHBlY3QocmVzdWx0KS50by5kZWVwLmVxdWFsKHtcbiAgICAgICAgICAgIHNlbGVjdG9yOiB7XG4gICAgICAgICAgICAgICAga2V5OiAndmFsdWUnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNlbGVjdG9yMjoge1xuICAgICAgICAgICAgICAgIGtleTI6ICd2YWx1ZTInLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnY3JlYXRlQnJhY2tldGVkS2V5VmFsdWVIYXNoJywgKCkgPT4ge1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBhbiBoYXNoIHN0cmluZyBmb3IgYSBzaW1wbGUgb2JqZWN0JywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgaW5wdXQgPSB7XG4gICAgICAgICAgICAgICAgJy5leGFtcGxlJzoge1xuICAgICAgICAgICAgICAgICAgICAnY29sb3InOiAncmVkJyxcbiAgICAgICAgICAgICAgICAgICAgJ2ZvbnQtc2l6ZSc6ICcxNHB4J1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgJy5vdGhlcic6IHtcbiAgICAgICAgICAgICAgICAgICAgJ2JhY2tncm91bmQnOiAnYmx1ZSdcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBjcmVhdGVCcmFja2V0ZWRLZXlWYWx1ZUhhc2goaW5wdXQpO1xuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdCkudG8uZGVlcC5lcXVhbChcIiMuZXhhbXBsZShjb2xvcj1yZWQsZm9udC1zaXplPTE0cHgpOy5vdGhlcihiYWNrZ3JvdW5kPWJsdWUpXCIpO1xuICAgICAgICB9KTtcbiAgICAgICAgXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGEgdXJsLWVuY29kZWQgaGFzaCBzdHJpbmcgZm9yIGEgc2ltcGxlIG9iamVjdCcsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGlucHV0ID0ge1xuICAgICAgICAgICAgICAgICcuZXhhbXBsZSc6IHtcbiAgICAgICAgICAgICAgICAgICAgJ2NvbG9yJzogJ3JcImVkJyxcbiAgICAgICAgICAgICAgICAgICAgJ2ZvbnQtc2l6ZSc6ICcxNHB4J1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgJy5vdGhlcic6IHtcbiAgICAgICAgICAgICAgICAgICAgJ2JhY2tncm91bmQnOiAnYmx1ZSdcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBjcmVhdGVCcmFja2V0ZWRLZXlWYWx1ZUhhc2goaW5wdXQsIHRydWUpO1xuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdCkudG8uZGVlcC5lcXVhbChcIiMuZXhhbXBsZShjb2xvcj1yJTIyZWQsZm9udC1zaXplPTE0cHgpOy5vdGhlcihiYWNrZ3JvdW5kPWJsdWUpXCIpO1xuICAgICAgICB9KTtcbiAgICAgICAgXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGFuIGVtcHR5IHN0cmluZyBmb3IgYW4gZW1wdHkgb2JqZWN0JywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgaW5wdXQgPSB7fTtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGNyZWF0ZUJyYWNrZXRlZEtleVZhbHVlSGFzaChpbnB1dCxmYWxzZSk7XG4gICAgICAgICAgICBleHBlY3QocmVzdWx0KS50by5kZWVwLmVxdWFsKFwiXCIpO1xuICAgICAgICB9KTtcbiAgICAgICAgXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGFuIGVtcHR5IHN0cmluZyBmb3IgYW4gZW1wdHkgb2JqZWN0JywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgaW5wdXQgPSB7fTtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGNyZWF0ZUJyYWNrZXRlZEtleVZhbHVlSGFzaChpbnB1dCxmYWxzZSk7XG4gICAgICAgICAgICBleHBlY3QocmVzdWx0KS50by5kZWVwLmVxdWFsKFwiXCIpO1xuICAgICAgICB9KTtcbiAgICAgICAgXG4gICAgfSk7XG5cblxufSk7XG4iLCAiLyoqIG5vZGVqcyBkb2VzbnQgc3VwcG9ydCB3aW5kb3cuY3J5cHQgKi9cbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5cbmRlc2NyaWJlKCdNYXRoJywgZnVuY3Rpb24gKCkge1xuXG4gICAgbGV0IHJhbmRvbSA9ICgpID0+IHt9XG4gICAgXG4gICAgYmVmb3JlKGZ1bmN0aW9uIChkb25lKSB7XG5cbiAgICAgICAgbGV0IHByb21pc2VzID0gW11cbiAgICAgICAgaWYgKCFnbG9iYWxUaGlzWydjcnlwdG8nXSkge1xuICAgICAgICAgICAgcHJvbWlzZXMucHVzaChpbXBvcnQoXCJAcGVjdWxpYXIvd2ViY3J5cHRvXCIpLnRoZW4obSA9PiB7XG4gICAgICAgICAgICAgICAgZ2xvYmFsVGhpc1snY3J5cHRvJ10gPSBuZXcgbS5DcnlwdG8oKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH0pKVxuICAgICAgICB9XG5cbiAgICAgICAgcHJvbWlzZXMucHVzaChpbXBvcnQoXCIuLi8uLi8uLi9zb3VyY2UvbWF0aC9yYW5kb20ubWpzXCIpLnRoZW4obSA9PiB7XG4gICAgICAgICAgICByYW5kb20gPSBtLnJhbmRvbTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9KSlcblxuXG4gICAgICAgIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICB9KTtcblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJy5yYW5kb20oKScsIGZ1bmN0aW9uICgpIHtcblxuXG4gICAgICAgIGl0KCdhIGdyZWF0ZXIgYiBzaG91bGQgdGhyb3cgZXJyb3IgJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KCgpID0+IHJhbmRvbSgxMCwgMikpLnRvLnRocm93KEVycm9yKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJyBzaG91bGQgcmV0dXJuIGEgbnVtYmVyICcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCByID0gcmFuZG9tKCk7XG4gICAgICAgICAgICBleHBlY3QocikudGhhdC5pcy5hKCdudW1iZXInKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJyBzaG91bGQgcmV0dXJuIGEgbnVtYmVyICcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdCgoKSA9PiByYW5kb20oNSwgNikpLnRvLnRocm93KEVycm9yKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJyBzaG91bGQgdGhyb3cgRXJyb3Igd2UgY2Fubm90IGdlbmVyYXRlIG51bWJlcnMgbGFyZ2VyIHRoYW4gNTMgYml0cy4nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QoKCkgPT4gcmFuZG9tKC05OTk5OTk5OTksIDk5OTk5OTk5OTk5OTk5OTk5OTk5KSkudG8udGhyb3coRXJyb3IpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnIHNob3VsZCB0aHJvdyBFcnJvciB3ZSBjYW5ub3QgZ2VuZXJhdGUgbnVtYmVycyBsYXJnZXIgdGhhbiA1MyBiaXRzLicsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgIFsxLCAxMDBdLFxuICAgICAgICAgICAgICAgIFs1MDAsIDYwMF0sXG4gICAgICAgICAgICAgICAgWzEwMCwgMTAwMF1cbiAgICAgICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICAgICAgbGV0IHIgPSByYW5kb20oYSwgYik7XG5cbiAgICAgICAgICAgICAgICBpdChyICsgJyBzaG91bGQgcmV0dXJuIHZhbHVlIGJldHdlZW4gJyArIGEgKyAnICcgKyBiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChyID49IGEpLnRvLmJlLnRydWU7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChyIDw9IGIpLnRvLmJlLnRydWU7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgIFsxLCAxMDBdLFxuICAgICAgICAgICAgICAgIFs1MDAsIDYwMF0sXG4gICAgICAgICAgICAgICAgWzEwMCwgMTAwMF1cbiAgICAgICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICAgICAgbGV0IHN1bSA9IDA7XG4gICAgICAgICAgICAgICAgY29uc3Qgcm91bmRzID0gNTAwXG5cbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbWF4ID0gcm91bmRzOyBpIDwgbWF4OyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgc3VtICs9IHJhbmRvbShhLCBiKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBsZXQgYXZnID0gc3VtIC8gcm91bmRzO1xuXG4gICAgICAgICAgICAgICAgaXQoYXZnICsgJyBzaG91bGQgYmV0d2VlbiAnICsgYSArICcgJyArIGIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KGF2ZyA+IGEpLnRvLmJlLnRydWVcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KGF2ZyA8IGIpLnRvLmJlLnRydWVcbiAgICAgICAgICAgICAgICB9KVxuXG5cbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgfSlcblxuXG4gICAgfSlcblxuXG59KSIsICJpbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuaW1wb3J0IHt0cmltU3BhY2VzfSBmcm9tIFwiLi4vLi4vLi4vc291cmNlL3V0aWwvdHJpbXNwYWNlcy5tanNcIjtcblxuXG5kZXNjcmliZSgndHJpbVNwYWNlcycsIGZ1bmN0aW9uICgpIHtcbiAgICBbXG4gICAgICAgIC8vIG9uZSBzdHJva2UgaXMgZXNjcGVkIGJ5IHRoZSBqYXZhc2NyaXB0IGludGVycHJldGVyLCB0aGUgc2Vjb25kIHN0cm9rZSBlc2NhcGVzIHRoZSBzdHJva2VcbiAgICAgICAgWycgdmFsdWUgJywgJ3ZhbHVlJ10sXG4gICAgICAgIFsnIHZhbHVlXFxcXCAnLCAndmFsdWVcXFxcICddLFxuICAgICAgICBbJ1xcXFwgdmFsdWVcXFxcICcsICdcXFxcIHZhbHVlXFxcXCAnXSxcbiAgICAgICAgWydcXCB2YWx1ZVxcICcsICd2YWx1ZSddLCAgIFxuICAgICAgICBbXCIgICB2YWx1ZSBcXCBcIiwgJ3ZhbHVlJ10sIFxuXG4gICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICBpdCgndHJpbVNwYWNlcygnICsgSlNPTi5zdHJpbmdpZnkoYSkgKyAnKSBzaG91bGQgcmV0dXJuICcgKyBKU09OLnN0cmluZ2lmeShiKSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KHRyaW1TcGFjZXMoYSkpLnRvLmJlLmVxdWFsKGIpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbn0pO1xuICAgICIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7aW50ZXJuYWxTeW1ib2x9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQge0Jhc2V9IGZyb20gXCIuLi90eXBlcy9iYXNlLm1qc1wiO1xuaW1wb3J0IHtnZXRHbG9iYWxGdW5jdGlvbn0gZnJvbSBcIi4uL3R5cGVzL2dsb2JhbC5tanNcIjtcbmltcG9ydCB7aXNGdW5jdGlvbiwgaXNJbnRlZ2VyfSBmcm9tIFwiLi4vdHlwZXMvaXMubWpzXCI7XG5pbXBvcnQge1F1ZXVlfSBmcm9tIFwiLi4vdHlwZXMvcXVldWUubWpzXCI7XG5pbXBvcnQge3ZhbGlkYXRlRnVuY3Rpb24sIHZhbGlkYXRlSW50ZWdlcn0gZnJvbSBcIi4uL3R5cGVzL3ZhbGlkYXRlLm1qc1wiO1xuXG5leHBvcnQge1Byb2Nlc3Npbmd9O1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmNsYXNzIENhbGxiYWNrIHtcbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGNhbGxiYWNrXG4gICAgICogQHBhcmFtIHtpbnR8dW5kZWZpbmVkfSB0aW1lXG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYSBmdW5jdGlvblxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGFuIGludGVnZXJcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGNhbGxiYWNrLCB0aW1lKSB7XG4gICAgICAgIHRoaXNbaW50ZXJuYWxTeW1ib2xdID0ge1xuICAgICAgICAgICAgY2FsbGJhY2s6IHZhbGlkYXRlRnVuY3Rpb24oY2FsbGJhY2spLFxuICAgICAgICAgICAgdGltZTogdmFsaWRhdGVJbnRlZ2VyKHRpbWUgPz8gMCksXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0gIHsqfSBkYXRhXG4gICAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICAgKi9cbiAgICBydW4oZGF0YSkge1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGdldEdsb2JhbEZ1bmN0aW9uKFwic2V0VGltZW91dFwiKSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShzZWxmW2ludGVybmFsU3ltYm9sXS5jYWxsYmFjayhkYXRhKSk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSwgc2VsZltpbnRlcm5hbFN5bWJvbF0udGltZSk7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cblxuLyoqXG4gKiBUaGlzIGNsYXNzIGFsbG93cyB0byBleGVjdXRlIHNldmVyYWwgZnVuY3Rpb25zIGluIG9yZGVyLlxuICpcbiAqIEZ1bmN0aW9ucyBhbmQgdGltZW91dHMgY2FuIGJlIHBhc3NlZC4gSWYgYSB0aW1lb3V0IGlzIHBhc3NlZCwgaXQgYXBwbGllcyB0byBhbGwgZnVydGhlciBmdW5jdGlvbnMuXG4gKiBJbiB0aGUgZXhhbXBsZVxuICpcbiAqIGB0aW1lb3V0MSwgZnVuY3Rpb24xLCBmdW5jdGlvbjIsIGZ1bmN0aW9uMywgdGltZW91dDIsIGZ1bmN0aW9uNGBcbiAqXG4gKiB0aGUgdGltZW91dDEgaXMgdmFsaWQgZm9yIHRoZSBmdW5jdGlvbnMgMSwgMiBhbmQgMyBhbmQgdGhlIHRpbWVvdXQyIGZvciB0aGUgZnVuY3Rpb240LlxuICpcbiAqIFNvIHRoZSBleGVjdXRpb24gdGltZSBpcyB0aW1lb3V0MSt0aW1lb3V0MSt0aW1lb3V0MSt0aW1lb3V0MlxuICpcbiAqIFRoZSByZXN1bHQgb2YgYHJ1bigpYCBpcyBhIHByb21pc2UuXG4gKlxuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL3V0aWwvcHJvY2Vzc2luZy5tanNcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjIxLjBcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlV0aWxcbiAqIEBzdW1tYXJ5IENsYXNzIHRvIGJlIGFibGUgdG8gZXhlY3V0ZSBmdW5jdGlvbiBjaGFpbnNcbiAqL1xuY2xhc3MgUHJvY2Vzc2luZyBleHRlbmRzIEJhc2Uge1xuICAgIC8qKlxuICAgICAqIENyZWF0ZSBuZXcgUHJvY2Vzc2luZ1xuICAgICAqXG4gICAgICogRnVuY3Rpb25zIGFuZCB0aW1lb3V0cyBjYW4gYmUgcGFzc2VkLiBJZiBhIHRpbWVvdXQgaXMgcGFzc2VkLCBpdCBhcHBsaWVzIHRvIGFsbCBmdXJ0aGVyIGZ1bmN0aW9ucy5cbiAgICAgKiBJbiB0aGUgZXhhbXBsZVxuICAgICAqXG4gICAgICogYHRpbWVvdXQxLCBmdW5jdGlvbjEsIGZ1bmN0aW9uMiwgZnVuY3Rpb24zLCB0aW1lb3V0MiwgZnVuY3Rpb240YFxuICAgICAqXG4gICAgICogdGhlIHRpbWVvdXQxIGlzIHZhbGlkIGZvciB0aGUgZnVuY3Rpb25zIDEsIDIgYW5kIDMgYW5kIHRoZSB0aW1lb3V0MiBmb3IgdGhlIGZ1bmN0aW9uNC5cbiAgICAgKlxuICAgICAqIFNvIHRoZSBleGVjdXRpb24gdGltZSBpcyB0aW1lb3V0MSt0aW1lb3V0MSt0aW1lb3V0MSt0aW1lb3V0MlxuICAgICAqXG4gICAgICogQHRocm93IHtUeXBlRXJyb3J9IHRoZSBhcmd1bWVudHMgbXVzdCBiZSBlaXRoZXIgaW50ZWdlciBvciBmdW5jdGlvbnNcbiAgICAgKiBAcGFyYW0gey4uLihpbnR8ZnVuY3Rpb24pfSBhcmdzXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoLi4uYXJncykge1xuICAgICAgICBzdXBlcigpO1xuXG4gICAgICAgIHRoaXNbaW50ZXJuYWxTeW1ib2xdID0ge1xuICAgICAgICAgICAgcXVldWU6IG5ldyBRdWV1ZSgpLFxuICAgICAgICB9O1xuXG4gICAgICAgIGxldCB0aW1lID0gMDtcblxuICAgICAgICBpZiAodHlwZW9mIGFyZ3MgIT09IFwib2JqZWN0XCIgfHwgYXJnc1swXSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInRoZSBhcmd1bWVudHMgbXVzdCBiZSBlaXRoZXIgaW50ZWdlciBvciBmdW5jdGlvbnNcIik7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGNvbnN0IFssIGFyZ10gb2YgT2JqZWN0LmVudHJpZXMoYXJncykpIHtcbiAgICAgICAgICAgIGlmIChpc0ludGVnZXIoYXJnKSAmJiBhcmcgPj0gMCkge1xuICAgICAgICAgICAgICAgIHRpbWUgPSBhcmc7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGlzRnVuY3Rpb24oYXJnKSkge1xuICAgICAgICAgICAgICAgIHRoaXNbaW50ZXJuYWxTeW1ib2xdLnF1ZXVlLmFkZChuZXcgQ2FsbGJhY2soYXJnLCB0aW1lKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJ0aGUgYXJndW1lbnRzIG11c3QgYmUgZWl0aGVyIGludGVnZXIgb3IgZnVuY3Rpb25zXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkcyBhIGZ1bmN0aW9uIHdpdGggdGhlIGRlc2lyZWQgdGltZW91dFxuICAgICAqIElmIG5vIHRpbWVvdXQgaXMgc3BlY2lmaWVkLCB0aGUgdGltZW91dCBvZiB0aGUgcHJldmlvdXMgZnVuY3Rpb24gaXMgdXNlZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGNhbGxiYWNrXG4gICAgICogQHBhcmFtIHtpbnR8dW5kZWZpbmVkfSB0aW1lXG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYSBmdW5jdGlvblxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGFuIGludGVnZXJcbiAgICAgKi9cbiAgICBhZGQoY2FsbGJhY2ssIHRpbWUpIHtcbiAgICAgICAgdGhpc1tpbnRlcm5hbFN5bWJvbF0ucXVldWUuYWRkKG5ldyBDYWxsYmFjayhjYWxsYmFjaywgdGltZSkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeGVjdXRlcyB0aGUgZGVmaW5lZCBmdW5jdGlvbnMgaW4gb3JkZXIuXG4gICAgICpcbiAgICAgKiBAcGFyYW0geyp9IGRhdGFcbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgICAqL1xuICAgIHJ1bihkYXRhKSB7XG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgICAgICBpZiAoc2VsZltpbnRlcm5hbFN5bWJvbF0ucXVldWUuaXNFbXB0eSgpKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGRhdGEpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY2FsbGJhY2sgPSBzZWxmW2ludGVybmFsU3ltYm9sXS5xdWV1ZS5wb2xsKCk7XG5cbiAgICAgICAgaWYgKGNhbGxiYWNrID09PSBudWxsIHx8IGNhbGxiYWNrID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoZGF0YSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gY2FsbGJhY2sucnVuKGRhdGEpXG4gICAgICAgICAgICAudGhlbigocmVzdWx0KSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNlbGYucnVuKHJlc3VsdCk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7UHJvY2Vzc2luZ30gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS91dGlsL3Byb2Nlc3NpbmcubWpzXCI7XG5cblxuZGVzY3JpYmUoJ1Byb2Nlc3NpbmcnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBkZXNjcmliZSgncnVuIGluc3RhbmNlJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdzaG91bGQgcnVuIG1hbnkgZnVuY3Rpb24nLCBmdW5jdGlvbiAoZG9uZSkge1xuXG4gICAgICAgICAgICBsZXQgY291bnRlciA9IDA7XG4gICAgICAgICAgICBsZXQgdCA9ICtuZXcgRGF0ZSgpO1xuXG4gICAgICAgICAgICBjb25zdCBkZXNpcmVkRGVsYXkgPSAyMDA7XG4gICAgICAgICAgICB0aGlzLnRpbWVvdXQoZGVzaXJlZERlbGF5KzEwMCk7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIC8vIGRlbGF5IDEyIFxuICAgICAgICAgICAgbmV3IFByb2Nlc3NpbmcoKHYpID0+IHtcbiAgICAgICAgICAgICAgICBjb3VudGVyKys7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHY7XG4gICAgICAgICAgICB9LCAodikgPT4ge1xuICAgICAgICAgICAgICAgIGNvdW50ZXIrK1xuICAgICAgICAgICAgICAgIHJldHVybiB2O1xuICAgICAgICAgICAgfSwgZnVuY3Rpb24gKHYpIHtcbiAgICAgICAgICAgICAgICBjb3VudGVyKytcbiAgICAgICAgICAgICAgICByZXR1cm4gdjtcbiAgICAgICAgICAgIH0sIGRlc2lyZWREZWxheSxmdW5jdGlvbiAodikge1xuICAgICAgICAgICAgICAgIGNvdW50ZXIrK1xuICAgICAgICAgICAgICAgIHJldHVybiB2O1xuICAgICAgICAgICAgfSkucnVuKCd0ZXN0JykudGhlbigodikgPT4ge1xuXG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KGNvdW50ZXIpLnRvLmJlLmVxdWFsKDQpO1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QodiA9PT0gJ3Rlc3QnKS50by5iZS50cnVlO1xuICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayBkZWxheVxuICAgICAgICAgICAgICAgICAgICBleHBlY3QoK25ldyBEYXRlKCkgPiB0ICsgZGVzaXJlZERlbGF5KzEpLnRvLmJlLnRydWU7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZG9uZShlKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICB9KVxuXG5cbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBydW4gb25lIGZ1bmN0aW9uJywgZnVuY3Rpb24gKGRvbmUpIHtcblxuICAgICAgICAgICAgbGV0IGNvdW50ZXIgPSAwO1xuXG4gICAgICAgICAgICBuZXcgUHJvY2Vzc2luZygodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICBjb3VudGVyKytcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICB9KS5ydW4oJ3Rlc3QnKS50aGVuKCh2KSA9PiB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KHYgPT09ICd0ZXN0JykudG8uYmUudHJ1ZTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBkb25lKGUpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICAgICAgfSkuY2F0Y2goZSA9PiBkb25lKGUpKTtcblxuXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgcnVuIG5vIGZ1bmN0aW9uJywgZnVuY3Rpb24gKGRvbmUpIHtcblxuICAgICAgICAgICAgbGV0IGNvdW50ZXIgPSAwO1xuXG4gICAgICAgICAgICBuZXcgUHJvY2Vzc2luZygpLnJ1bigndGVzdCcpLnRoZW4oKHYpID0+IHtcblxuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdCh2ID09PSAndGVzdCcpLnRvLmJlLnRydWU7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZG9uZShlKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBkb25lKClcbiAgICAgICAgICAgIH0pLmNhdGNoKGUgPT4gZG9uZShlKSk7XG5cblxuICAgICAgICB9KTtcblxuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnY3JlYXRlIG5ldyBpbnN0YW5jZScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBhIFByb2Nlc3Npbmcgb2JqZWN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KG5ldyBQcm9jZXNzaW5nKCkpLnRvLmJlLmEoJ29iamVjdCcpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBhIFByb2Nlc3Npbmcgb2JqZWN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KG5ldyBQcm9jZXNzaW5nKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIH0pKS50by5iZS5hKCdvYmplY3QnKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBUeXBlRXJyb3InLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QoKCkgPT4gbmV3IFByb2Nlc3NpbmcodHJ1ZSkpLnRvLnRocm93KFR5cGVFcnJvcik7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgdGhyb3cgVHlwZUVycm9yJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KCgpID0+IG5ldyBQcm9jZXNzaW5nKFwidGVzdFwiKSkudG8udGhyb3coVHlwZUVycm9yKTtcbiAgICAgICAgfSk7XG5cblxuICAgIH0pO1xuXG59KTsiLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBpbnRlcm5hbFN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5cbmltcG9ydCB7IEJhc2UgfSBmcm9tIFwiLi4vdHlwZXMvYmFzZS5tanNcIjtcbmltcG9ydCB7IGlzSW50ZWdlciB9IGZyb20gXCIuLi90eXBlcy9pcy5tanNcIjtcbmltcG9ydCB7IHZhbGlkYXRlRnVuY3Rpb24sIHZhbGlkYXRlSW50ZWdlciB9IGZyb20gXCIuLi90eXBlcy92YWxpZGF0ZS5tanNcIjtcblxuZXhwb3J0IHsgRGVhZE1hbnNTd2l0Y2ggfTtcblxuLyoqXG4gKiBUaGUgZGVhZCBtYW4ncyBzd2l0Y2ggYWxsb3dzIHRvIHNldCBhIHRpbWVyIHdoaWNoIGNhbiBiZSByZXNldCBhZ2FpbiBhbmQgYWdhaW4gd2l0aGluIGEgZGVmaW5lZCBwZXJpb2Qgb2YgdGltZS5cbiAqXG4gKiBAZXh0ZXJuYWxFeGFtcGxlIC4uLy4uL2V4YW1wbGUvdXRpbC9kZWFkbWFuc3N3aXRjaC5tanNcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI5LjBcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlV0aWxcbiAqIEBzdW1tYXJ5IENsYXNzIHRvIGJlIGFibGUgdG8gZXhlY3V0ZSBmdW5jdGlvbiBjaGFpbnNcbiAqL1xuY2xhc3MgRGVhZE1hbnNTd2l0Y2ggZXh0ZW5kcyBCYXNlIHtcbiAgICAvKipcbiAgICAgKiBDcmVhdGUgbmV3IGRlYWQgbWFuJ3Mgc3dpdGNoXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0ludGVnZXJ9IGRlbGF5XG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2tcbiAgICAgKiBAdGhyb3cge1R5cGVFcnJvcn0gdGhlIGFyZ3VtZW50cyBtdXN0IGJlIGVpdGhlciBpbnRlZ2VyIG9yIGZ1bmN0aW9uc1xuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGFuIGludGVnZXJcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihkZWxheSwgY2FsbGJhY2spIHtcbiAgICAgICAgc3VwZXIoKTtcblxuICAgICAgICBpbml0LmNhbGwodGhpcywgdmFsaWRhdGVJbnRlZ2VyKGRlbGF5KSwgdmFsaWRhdGVGdW5jdGlvbihjYWxsYmFjaykpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtJbnRlZ2VyfHVuZGVmaW5lZH0gW2RlbGF5XVxuICAgICAqL1xuICAgIHRvdWNoKGRlbGF5KSB7XG4gICAgICAgIGlmICh0aGlzW2ludGVybmFsU3ltYm9sXVtcImlzQWxyZWFkeVJ1blwiXSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiaGFzIGFscmVhZHkgcnVuXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzSW50ZWdlcihkZWxheSkpIHtcbiAgICAgICAgICAgIHRoaXNbaW50ZXJuYWxTeW1ib2xdW1wiZGVsYXlcIl0gPSBkZWxheTtcbiAgICAgICAgfSBlbHNlIGlmIChkZWxheSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1bnN1cHBvcnRlZCBhcmd1bWVudFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNsZWFyVGltZW91dCh0aGlzW2ludGVybmFsU3ltYm9sXVtcInRpbWVyXCJdKTtcblxuICAgICAgICBpbml0Q2FsbGJhY2suY2FsbCh0aGlzKTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gaW5pdENhbGxiYWNrKCkge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgc2VsZltpbnRlcm5hbFN5bWJvbF1bXCJ0aW1lclwiXSA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBzZWxmW2ludGVybmFsU3ltYm9sXVtcImlzQWxyZWFkeVJ1blwiXSA9IHRydWU7XG4gICAgICAgIHNlbGZbaW50ZXJuYWxTeW1ib2xdW1wiY2FsbGJhY2tcIl0oKTtcbiAgICB9LCBzZWxmW2ludGVybmFsU3ltYm9sXVtcImRlbGF5XCJdKTtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtpbnRlZ2VyfSBkZWxheVxuICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2tcbiAqL1xuZnVuY3Rpb24gaW5pdChkZWxheSwgY2FsbGJhY2spIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgIHNlbGZbaW50ZXJuYWxTeW1ib2xdID0ge1xuICAgICAgICBjYWxsYmFjayxcbiAgICAgICAgZGVsYXksXG4gICAgICAgIGlzQWxyZWFkeVJ1bjogZmFsc2UsXG4gICAgICAgIHRpbWVyOiB1bmRlZmluZWQsXG4gICAgfTtcblxuICAgIGluaXRDYWxsYmFjay5jYWxsKHNlbGYpO1xufVxuIiwgImltcG9ydCB7RGVhZE1hbnNTd2l0Y2h9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvdXRpbC9kZWFkbWFuc3N3aXRjaC5tanNcIjtcblxuXG5kZXNjcmliZSgnRGVhZE1hbnNTd2l0Y2gnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBkZXNjcmliZSgncnVuIGluc3RhbmNlJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdzaG91bGQgcnVuJywgZnVuY3Rpb24gKGRvbmUpIHtcblxuICAgICAgICAgICAgY29uc3QgbXMxID0gIERhdGUubm93KCk7XG5cbiAgICAgICAgICAgIG5ldyBEZWFkTWFuc1N3aXRjaCgxMDAsICgpID0+IHtcblxuICAgICAgICAgICAgICAgIGNvbnN0IG1zMiA9ICBEYXRlLm5vdygpO1xuXG4gICAgICAgICAgICAgICAgY29uc3QgZGlmZiA9IG1zMiAtIG1zMTtcbiAgICAgICAgICAgICAgICBpZiAoZGlmZiA8IDEwMCkge1xuICAgICAgICAgICAgICAgICAgICBkb25lKCd0byBzaG9ydCAnICsgZGlmZik7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgfSlcblxuXG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3J1biBpbnN0YW5jZSBhbmQgdG91Y2gnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBydW4nLCBmdW5jdGlvbiAoZG9uZSkge1xuXG4gICAgICAgICAgICBjb25zdCBtczEgPSBEYXRlLm5vdygpO1xuXG4gICAgICAgICAgICBjb25zdCBkZWFkbWFuc3N3aXRjaCA9IG5ldyBEZWFkTWFuc1N3aXRjaCgxMDAsICgpID0+IHtcblxuICAgICAgICAgICAgICAgIGNvbnN0IG1zMiA9IERhdGUubm93KCk7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBkaWZmID0gbXMyIC0gbXMxO1xuXG4gICAgICAgICAgICAgICAgaWYgKG1zMSA+IG1zMikge1xuICAgICAgICAgICAgICAgICAgICBkb25lKG5ldyBFcnJvcigndGltaW5nIGVycm9yJykpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKGRpZmYgPCA2MDApIHtcbiAgICAgICAgICAgICAgICAgICAgZG9uZShuZXcgRXJyb3IoJ3RvIHNob3J0ICcgKyBkaWZmKSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgLy8gICAwIG1zOiBpbml0KCkgLT4gd2FpdCAxMDAgbXMgXG4gICAgICAgICAgICAvLyAgNTAgbXM6IHRvdWNoKCkgLT4gd2FpdCAxMDAgbXNcbiAgICAgICAgICAgIC8vICAgICAgICAgIC0+IHdhaXQgMTAwXG4gICAgICAgICAgICAvLyAxMDAgbXM6IHRvdWNoKDUwMCkgLT4gd2FpdCA1MDAgbXNcbiAgICAgICAgICAgIC8vICAgICAgICAgIC0+IHdhaXQgNTAwXG4gICAgICAgICAgICAvLyA2MDAgbXM6IGV4ZWN1dGUgY2FsbGJhY2tcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGRlYWRtYW5zc3dpdGNoLnRvdWNoKClcblxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBkZWFkbWFuc3N3aXRjaC50b3VjaCg1MDApXG4gICAgICAgICAgICAgICAgfSwgNTApXG5cbiAgICAgICAgICAgIH0sIDUwKVxuXG5cbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbn0pOyIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IEJhc2UgfSBmcm9tIFwiLi4vdHlwZXMvYmFzZS5tanNcIjtcbmltcG9ydCB7IGlzRnVuY3Rpb24gfSBmcm9tIFwiLi4vdHlwZXMvaXMubWpzXCI7XG5cbmV4cG9ydCB7IENvbXBhcmF0b3IgfTtcblxuLyoqXG4gKiBUaGUgY29tcGFyYXRvciBhbGxvd3MgYSBjb21wYXJpc29uIGZ1bmN0aW9uIHRvIGJlIGFic3RyYWN0ZWQuXG4gKlxuICogVGhlIGZvbGxvd2luZyBhcmUgc29tZSBleGFtcGxlcyBvZiB0aGUgYXBwbGljYXRpb24gb2YgdGhlIGNsYXNzLlxuICpcbiAqIGBgYFxuICogbmV3IENvbXBhcmF0b3IoKS5sZXNzVGhhbk9yRXF1YWwoMiwgNSkgLy8gXHUyMUE2IHRydWVcbiAqIG5ldyBDb21wYXJhdG9yKCkuZ3JlYXRlclRoYW4oNCwgMikgLy8gXHUyMUE2IHRydWVcbiAqIG5ldyBDb21wYXJhdG9yKCkuZXF1YWwoNCwgNCkgLy8gXHUyMUE2IHRydWVcbiAqIG5ldyBDb21wYXJhdG9yKCkuZXF1YWwoNCwgNSkgLy8gXHUyMUE2IGZhbHNlXG4gKiBgYGBcbiAqXG4gKiBZb3UgY2FuIGFsc28gcGFzcyB5b3VyIG93biBjb21wYXJpc29uIGZ1bmN0aW9uLCBhbmQgdGh1cyBkZWZpbmUgdGhlIGNvbXBhcmlzb24gZnVuY3Rpb24uXG4gKlxuICogYGBgXG4gKiBuZXcgQ29tcGFyYXRvcihmdW5jdGlvbiAoYSwgYikge1xuICogICAgICBpZiAoYS52ID09PSBiLnYpIHJldHVybiAwO1xuICogICAgICAgICByZXR1cm4gYS52IDwgYi52ID8gLTEgOiAxO1xuICogICAgICB9KS5lcXVhbCh7djogMn0sIHt2OiAyfSk7ICAvLyBcdTIxQTYgdHJ1ZVxuICogYGBgXG4gKlxuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL3V0aWwvY29tcGFyYXRvci5tanNcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMy4wXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5VdGlsXG4gKi9cbmNsYXNzIENvbXBhcmF0b3IgZXh0ZW5kcyBCYXNlIHtcbiAgICAvKipcbiAgICAgKiBjcmVhdGUgbmV3IGNvbXBhcmF0b3JcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7TW9uc3Rlci5VdGlsfmV4YW1wbGVDYWxsYmFja30gW2NhbGxiYWNrXSBDb21wYXJhdG9yIGNhbGxiYWNrXG4gICAgICogQHRocm93IHtUeXBlRXJyb3J9IHVuc3VwcG9ydGVkIHR5cGVcbiAgICAgKiBAdGhyb3cge1R5cGVFcnJvcn0gaW1wcmFjdGljYWwgY29tcGFyaXNvblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGNhbGxiYWNrKSB7XG4gICAgICAgIHN1cGVyKCk7XG5cbiAgICAgICAgaWYgKGlzRnVuY3Rpb24oY2FsbGJhY2spKSB7XG4gICAgICAgICAgICB0aGlzLmNvbXBhcmUgPSBjYWxsYmFjaztcbiAgICAgICAgfSBlbHNlIGlmIChjYWxsYmFjayAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwidW5zdXBwb3J0ZWQgdHlwZVwiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIGRlZmF1bHQgY29tcGFyZSBmdW5jdGlvblxuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgKiBAcGFyYW0geyp9IGFcbiAgICAgICAgICAgICAqIEBwYXJhbSB7Kn0gYlxuICAgICAgICAgICAgICogQHJldHVybiB7aW50ZWdlcn0gLTEsIDAgb3IgMVxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICB0aGlzLmNvbXBhcmUgPSBmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgYSAhPT0gdHlwZW9mIGIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImltcHJhY3RpY2FsIGNvbXBhcmlzb25cIiwgXCJ0eXBlcy9jb21wYXJhdG9yLm1qc1wiKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoYSA9PT0gYikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGEgPCBiID8gLTEgOiAxO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIGNoYW5nZXMgdGhlIG9yZGVyIG9mIHRoZSBvcGVyYXRvcnNcbiAgICAgKlxuICAgICAqIEByZXR1cm4ge0NvbXBhcmF0b3J9XG4gICAgICovXG4gICAgcmV2ZXJzZSgpIHtcbiAgICAgICAgY29uc3Qgb3JpZ2luYWwgPSB0aGlzLmNvbXBhcmU7XG4gICAgICAgIHRoaXMuY29tcGFyZSA9IChhLCBiKSA9PiBvcmlnaW5hbChiLCBhKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIHR3byB2YXJpYWJsZXMgYXJlIGVxdWFsLlxuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSBhXG4gICAgICogQHBhcmFtIHsqfSBiXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgICAqL1xuICAgIGVxdWFsKGEsIGIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29tcGFyZShhLCBiKSA9PT0gMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgdmFyaWFibGUgYGFgIGlzIGdyZWF0ZXIgdGhhbiBgYmBcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Kn0gYVxuICAgICAqIEBwYXJhbSB7Kn0gYlxuICAgICAqXG4gICAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBncmVhdGVyVGhhbihhLCBiKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbXBhcmUoYSwgYikgPiAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiB2YXJpYWJsZSBgYWAgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIGBiYFxuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSBhXG4gICAgICogQHBhcmFtIHsqfSBiXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgICAqL1xuICAgIGdyZWF0ZXJUaGFuT3JFcXVhbChhLCBiKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdyZWF0ZXJUaGFuKGEsIGIpIHx8IHRoaXMuZXF1YWwoYSwgYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIHZhcmlhYmxlIGBhYCBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gYGJgXG4gICAgICpcbiAgICAgKiBAcGFyYW0geyp9IGFcbiAgICAgKiBAcGFyYW0geyp9IGJcbiAgICAgKlxuICAgICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAgICovXG4gICAgbGVzc1RoYW5PckVxdWFsKGEsIGIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubGVzc1RoYW4oYSwgYikgfHwgdGhpcy5lcXVhbChhLCBiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgdmFyaWFibGUgYSBpcyBsZXNzIHRoYW4gYlxuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSBhXG4gICAgICogQHBhcmFtIHsqfSBiXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgICAqL1xuICAgIGxlc3NUaGFuKGEsIGIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29tcGFyZShhLCBiKSA8IDA7XG4gICAgfVxufVxuXG4vKipcbiAqIFRoaXMgaXMgdGhlIGRlc2NyaXB0aW9uIGZvciB0aGUgY2FsbGJhY2sgZnVuY3Rpb24gdXNlZCBieSB0aGUgb3BlcmF0b3JcbiAqXG4gKiBgYGBcbiAqIG5ldyBDb21wYXJhdG9yKGZ1bmN0aW9uIChhLCBiKSB7XG4gKiAgICAgIGlmIChhLnYgPT09IGIudikgcmV0dXJuIDA7XG4gKiAgICAgICAgIHJldHVybiBhLnYgPCBiLnYgPyAtMSA6IDE7XG4gKiAgICAgIH0pLmVxdWFsKHt2OiAyfSwge3Y6IDJ9KTsgIC8vIFx1MjFBNiB0cnVlXG4gKiBgYGBcbiAqXG4gKiBAY2FsbGJhY2sgTW9uc3Rlci5VdGlsfmV4YW1wbGVDYWxsYmFja1xuICogQHBhcmFtIHsqfSBhXG4gKiBAcGFyYW0geyp9IGJcbiAqIEByZXR1cm4ge2ludGVnZXJ9IC0xLCAwIG9yIDFcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlV0aWxcbiAqIEBzZWUgTW9uc3Rlci5VdGlsLkNvbXBhcmF0b3JcbiAqL1xuIiwgImltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge0NvbXBhcmF0b3J9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvdXRpbC9jb21wYXJhdG9yLm1qc1wiO1xuXG5cbmRlc2NyaWJlKCdDb21wYXJhdG9yJywgZnVuY3Rpb24gKCkge1xuXG4gICAgZGVzY3JpYmUoJ2NyZWF0ZSBuZXcgaW5zdGFuY2UnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gYSBjb21wYXJhdG9yIG9iamVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgQ29tcGFyYXRvcigpKS50by5iZS5hKCdvYmplY3QnKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gYSBjb21wYXJhdG9yIG9iamVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgQ29tcGFyYXRvcihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB9KSkudG8uYmUuYSgnb2JqZWN0Jyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgdGhyb3cgVHlwZUVycm9yJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KCgpID0+IG5ldyBDb21wYXJhdG9yKHRydWUpKS50by50aHJvdyhUeXBlRXJyb3IpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHRocm93IFR5cGVFcnJvcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdCgoKSA9PiBuZXcgQ29tcGFyYXRvcihcInRlc3RcIikpLnRvLnRocm93KFR5cGVFcnJvcik7XG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdlcXVhbCgpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIFtcbiAgICAgICAgICAgIFsndGVzdDEnLCBcInRlc3RcIiwgZmFsc2VdLFxuICAgICAgICAgICAgWzUuMSwgNSwgZmFsc2VdLFxuICAgICAgICAgICAgWzUuMSwgNS4xLCB0cnVlXSxcbiAgICAgICAgICAgIFt0cnVlLCB0cnVlLCB0cnVlXSxcbiAgICAgICAgICAgIFtmYWxzZSwgdHJ1ZSwgZmFsc2VdLFxuICAgICAgICAgICAgW2ZhbHNlLCBmYWxzZSwgdHJ1ZV0sXG4gICAgICAgICAgICBbLTQsIC00LCB0cnVlXSxcbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGMgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ3Nob3VsZCBjb21wYXJlICcgKyBhICsgJyBhbmQgJyArIGIgKyAnIHJldHVybiAnICsgYywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGV4cGVjdChuZXcgQ29tcGFyYXRvcigpLmVxdWFsKGEsIGIpKS5pcy5lcXVhbChjKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnZXF1YWwoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBbXG4gICAgICAgICAgICBbJ3Rlc3QxJywgdHJ1ZV0sXG4gICAgICAgICAgICBbJ3Rlc3QxJywgNV0sXG4gICAgICAgICAgICBbJ3Rlc3QxJywgbnVsbF0sXG4gICAgICAgICAgICBbJ3Rlc3QxJywgcGFyc2VJbnQoXCJhXCIpXSxcbiAgICAgICAgICAgIFtmYWxzZSwgNV0sXG4gICAgICAgICAgICBbdW5kZWZpbmVkLCBudWxsXSxcbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpdCgnc2hvdWxkIGNvbXBhcmUgJyArIGEgKyAnIGFuZCAnICsgYiArICcgdGhyb3cgVHlwZUVycm9yJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGV4cGVjdCgoKSA9PiBuZXcgQ29tcGFyYXRvcigpLmVxdWFsKGEsIGIpKS50by50aHJvdyhUeXBlRXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnZ3JlYXRlclRoYW4oKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBbXG4gICAgICAgICAgICBbJ3Rlc3QxJywgXCJ0ZXN0XCIsIHRydWVdLFxuICAgICAgICAgICAgWzUuMSwgNSwgdHJ1ZV0sXG4gICAgICAgICAgICBbNS4xLCA1LjEsIGZhbHNlXSxcbiAgICAgICAgICAgIFt0cnVlLCB0cnVlLCBmYWxzZV0sXG4gICAgICAgICAgICBbZmFsc2UsIHRydWUsIGZhbHNlXSxcbiAgICAgICAgICAgIFtmYWxzZSwgZmFsc2UsIGZhbHNlXSxcbiAgICAgICAgICAgIFstNCwgLTQsIGZhbHNlXSxcbiAgICAgICAgICAgIFstNCwgNCwgZmFsc2VdLFxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYyA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpdCgnc2hvdWxkIGNvbXBhcmUgJyArIGEgKyAnIGFuZCAnICsgYiArICcgcmV0dXJuICcgKyBjLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KG5ldyBDb21wYXJhdG9yKCkuZ3JlYXRlclRoYW4oYSwgYikpLmlzLmVxdWFsKGMpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdyZXZlcnNlKCkuZ3JlYXRlclRoYW4oKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBbXG4gICAgICAgICAgICBbJ3Rlc3QxJywgXCJ0ZXN0XCIsIHRydWVdLFxuICAgICAgICAgICAgWzUuMSwgNSwgdHJ1ZV0sXG4gICAgICAgICAgICBbNS4xLCA1LjEsIGZhbHNlXSxcbiAgICAgICAgICAgIFt0cnVlLCB0cnVlLCBmYWxzZV0sXG4gICAgICAgICAgICBbZmFsc2UsIHRydWUsIGZhbHNlXSxcbiAgICAgICAgICAgIFtmYWxzZSwgZmFsc2UsIGZhbHNlXSxcbiAgICAgICAgICAgIFstNCwgLTQsIGZhbHNlXSxcbiAgICAgICAgICAgIFstNCwgNCwgZmFsc2VdLFxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYyA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpdCgnc2hvdWxkIGNvbXBhcmUgJyArIGEgKyAnIGFuZCAnICsgYiArICcgcmV0dXJuICcgKyBjLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KG5ldyBDb21wYXJhdG9yKCkucmV2ZXJzZSgpLmdyZWF0ZXJUaGFuKGEsIGIpKS5pcy5lcXVhbChjKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnZ3JlYXRlclRoYW5PckVxdWFsKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWyd0ZXN0MScsIFwidGVzdFwiLCB0cnVlXSxcbiAgICAgICAgICAgIFs1LjEsIDUsIHRydWVdLFxuICAgICAgICAgICAgWzUuMSwgNS4xLCB0cnVlXSxcbiAgICAgICAgICAgIFt0cnVlLCB0cnVlLCB0cnVlXSxcbiAgICAgICAgICAgIFtmYWxzZSwgdHJ1ZSwgZmFsc2VdLFxuICAgICAgICAgICAgW2ZhbHNlLCBmYWxzZSwgdHJ1ZV0sXG4gICAgICAgICAgICBbLTQsIC00LCB0cnVlXSxcbiAgICAgICAgICAgIFstNCwgNCwgZmFsc2VdLFxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYyA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpdCgnc2hvdWxkIGNvbXBhcmUgJyArIGEgKyAnIGFuZCAnICsgYiArICcgcmV0dXJuICcgKyBjLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KG5ldyBDb21wYXJhdG9yKCkuZ3JlYXRlclRoYW5PckVxdWFsKGEsIGIpKS5pcy5lcXVhbChjKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnbGVzc1RoYW4oKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBbXG4gICAgICAgICAgICBbJ3Rlc3QxJywgXCJ0ZXN0XCIsIHRydWVdLFxuICAgICAgICAgICAgWzUuMSwgNSwgdHJ1ZV0sXG4gICAgICAgICAgICBbNS4xLCA1LjEsIGZhbHNlXSxcbiAgICAgICAgICAgIFt0cnVlLCB0cnVlLCBmYWxzZV0sXG4gICAgICAgICAgICBbZmFsc2UsIHRydWUsIGZhbHNlXSxcbiAgICAgICAgICAgIFtmYWxzZSwgZmFsc2UsIGZhbHNlXSxcbiAgICAgICAgICAgIFstNCwgLTQsIGZhbHNlXSxcbiAgICAgICAgICAgIFstNCwgNCwgZmFsc2VdLFxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYyA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpdCgnc2hvdWxkIGNvbXBhcmUgJyArIGEgKyAnIGFuZCAnICsgYiArICcgcmV0dXJuICcgKyBjLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KG5ldyBDb21wYXJhdG9yKCkubGVzc1RoYW4oYSwgYikpLmlzLmVxdWFsKGMpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdkb2N1bWVudGF0aW9ucycsIGZ1bmN0aW9uICgpIHtcblxuXG4gICAgICAgIGl0KCdzaG91bGQgcnVuIC4uLicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgQ29tcGFyYXRvcigpLmxlc3NUaGFuT3JFcXVhbCgyLCA1KSkudG8uYmUudHJ1ZTtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgQ29tcGFyYXRvcigpLmdyZWF0ZXJUaGFuKDQsIDIpKS50by5iZS50cnVlO1xuICAgICAgICAgICAgZXhwZWN0KG5ldyBDb21wYXJhdG9yKCkuZXF1YWwoNCwgNCkpLnRvLmJlLnRydWU7XG4gICAgICAgICAgICBleHBlY3QobmV3IENvbXBhcmF0b3IoKS5lcXVhbCg0LCA1KSkudG8uYmUuZmFsc2U7XG4gICAgICAgIH0pO1xuXG5cbiAgICAgICAgaXQoJ3Nob3VsZCBydW4gd2l0aCBvd24gZnVuY3Rpb24gLi4uJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KG5ldyBDb21wYXJhdG9yKGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICAgICAgICAgICAgaWYgKGEudiA9PT0gYi52KSByZXR1cm4gMDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYS52IDwgYi52ID8gLTEgOiAxO1xuICAgICAgICAgICAgfSkuZXF1YWwoe3Y6IDJ9LCB7djogMn0pKS50by5iZS50cnVlO1xuICAgICAgICB9KTtcblxuXG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCdsZXNzVGhhbk9yRXF1YWwoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBbXG4gICAgICAgICAgICBbJ3Rlc3QxJywgXCJ0ZXN0XCIsIHRydWVdLFxuICAgICAgICAgICAgWzUuMSwgNSwgdHJ1ZV0sXG4gICAgICAgICAgICBbNS4xLCA1LjEsIHRydWVdLFxuICAgICAgICAgICAgW3RydWUsIHRydWUsIHRydWVdLFxuICAgICAgICAgICAgW2ZhbHNlLCB0cnVlLCBmYWxzZV0sXG4gICAgICAgICAgICBbZmFsc2UsIGZhbHNlLCB0cnVlXSxcbiAgICAgICAgICAgIFstNCwgLTQsIHRydWVdLFxuICAgICAgICAgICAgWy00LCA0LCBmYWxzZV0sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBjID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGl0KCdzaG91bGQgY29tcGFyZSAnICsgYSArICcgYW5kICcgKyBiICsgJyByZXR1cm4gJyArIGMsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBleHBlY3QobmV3IENvbXBhcmF0b3IoKS5sZXNzVGhhbk9yRXF1YWwoYSwgYikpLmlzLmVxdWFsKGMpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICB9KTtcblxuXG59KTsiLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyB2YWxpZGF0ZU9iamVjdCB9IGZyb20gXCIuLi90eXBlcy92YWxpZGF0ZS5tanNcIjtcblxuZXhwb3J0IHsgZGVlcEZyZWV6ZSB9O1xuXG4vKipcbiAqIERlZXAgZnJlZXplIGEgb2JqZWN0XG4gKlxuICogQHBhcmFtIHtvYmplY3R9IG9iamVjdCBvYmplY3QgdG8gYmUgZnJlZXplXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjAuMFxuICogQHJldHVybnMge29iamVjdH1cbiAqIEBtZW1iZXJPZiBNb25zdGVyLlV0aWxcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIG9iamVjdFxuICovXG5mdW5jdGlvbiBkZWVwRnJlZXplKG9iamVjdCkge1xuICAgIHZhbGlkYXRlT2JqZWN0KG9iamVjdCk7XG5cbiAgICAvLyBSZXRyaWV2ZSB0aGUgZGVmaW5lZCBwcm9wZXJ0eSBuYW1lcyBvZiB0aGUgb2JqZWN0XG4gICAgdmFyIHByb3BOYW1lcyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKG9iamVjdCk7XG5cbiAgICAvLyBGcmVlemUgcHJvcGVydGllcyBiZWZvcmUgZnJlZXppbmcgeW91cnNlbGZcbiAgICBmb3IgKGxldCBuYW1lIG9mIHByb3BOYW1lcykge1xuICAgICAgICBsZXQgdmFsdWUgPSBvYmplY3RbbmFtZV07XG5cbiAgICAgICAgb2JqZWN0W25hbWVdID0gdmFsdWUgJiYgdHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiID8gZGVlcEZyZWV6ZSh2YWx1ZSkgOiB2YWx1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gT2JqZWN0LmZyZWV6ZShvYmplY3QpO1xufVxuIiwgImltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge2RlZXBGcmVlemV9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvdXRpbC9mcmVlemUubWpzXCI7XG5cblxuZGVzY3JpYmUoJ2RlZXBGcmVlemUnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBkZXNjcmliZSgnZGVlcEZyZWV6ZSBhbiBvYmplY3QnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBmcmVlemUgb2JqZWN0JywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBsZXQgb2JqMSA9IHtcbiAgICAgICAgICAgICAgICBhOiB7XG4gICAgICAgICAgICAgICAgICAgIGI6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGM6MVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgbGV0IG9iajIgPSB7XG4gICAgICAgICAgICAgICAgYToge1xuICAgICAgICAgICAgICAgICAgICBiOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjOjJcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGV4cGVjdChvYmoyKS50by5ub3QuZXFsKG9iajEpXG4gICAgICAgICAgICBvYmoxLmEuYi5jID0gMjtcbiAgICAgICAgICAgIGV4cGVjdChvYmoyKS50by5lcWwob2JqMSk7XG5cbiAgICAgICAgICAgIGNvbnN0IG9iajFGcmVlemVkID0gZGVlcEZyZWV6ZShvYmoxKTtcblxuICAgICAgICAgICAgZXhwZWN0KG9iajIpLnRvLmVxbChvYmoxRnJlZXplZCk7XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZGUvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvT2JqZWN0L2ZyZWV6ZVxuICAgICAgICAgICAgICAgIC8vIG5vIGNoYW5nZSB0byB0aGUgb2JqZWN0LCBleGNlcHRpb24gZGVwZW5kcyBvbiBtb2RlIChzdHJpY3QgRVMgMjAxNSwgZXRjKVxuICAgICAgICAgICAgICAgIG9iajFGcmVlemVkLmEuYi5jID0gMyAgICBcbiAgICAgICAgICAgIH0gY2F0Y2ggKF8pIHtcblxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBleHBlY3Qob2JqMikudG8uZXFsKG9iajFGcmVlemVkKTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgXG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cblxufSk7IiwgImltcG9ydCB7Y2xvbmV9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvdXRpbC9jbG9uZS5tanNcIjtcbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5cbmRlc2NyaWJlKCdDbG9uZScsIGZ1bmN0aW9uICgpIHtcblxuICAgIGNsYXNzIEEge1xuICAgICAgICBjb25zdHJ1Y3RvcihiKSB7XG4gICAgICAgICAgICB0aGlzLmIgPSBiXG4gICAgICAgIH1cblxuICAgICAgICBhKCkge1xuXG4gICAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgY2xhc3MgQiB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGIpIHtcbiAgICAgICAgICAgIHRoaXMuYiA9IGJcbiAgICAgICAgfVxuXG4gICAgICAgIGEoKSB7XG5cbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgZ2V0Q2xvbmUoKSB7XG4gICAgICAgICAgICByZXR1cm4gXCJET05FXCJcbiAgICAgICAgfVxuICAgICAgICBcbiAgICB9XG5cbiAgICBkZXNjcmliZSgnLmNsb25lKEIpIHdpdGggZ2V0Q2xvbmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCcuY2xvbmUoQikgc2hvdWxkIG9iamVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBiID0gbmV3IEIoe1xuICAgICAgICAgICAgICAgIHg6IHtcbiAgICAgICAgICAgICAgICAgICAgeTogMSwgZDogbmV3IEEoMSksIHo6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgbGV0IHIgPSBjbG9uZShiKTtcbiAgICAgICAgICAgIGV4cGVjdChiKS50by5iZS5pbnN0YW5jZU9mKEIpXG4gICAgICAgICAgICBleHBlY3Qocikubm90LmVxdWFsKGIpO1xuICAgICAgICAgICAgZXhwZWN0KEpTT04uc3RyaW5naWZ5KHIpKS5lcXVhbChKU09OLnN0cmluZ2lmeSgnRE9ORScpKTtcblxuICAgICAgICB9KTtcbiAgICB9KVxuICAgIFxuICAgIGRlc2NyaWJlKCcuY2xvbmUoQSknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCcuY2xvbmUoQSkgc2hvdWxkIG9iamVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBhID0gbmV3IEEoe1xuICAgICAgICAgICAgICAgIHg6IHtcbiAgICAgICAgICAgICAgICAgICAgeTogMSwgZDogbmV3IEEoMSksIHo6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgbGV0IGIgPSBjbG9uZShhKTtcbiAgICAgICAgICAgIGV4cGVjdChhKS50by5iZS5pbnN0YW5jZU9mKEEpXG4gICAgICAgICAgICBleHBlY3QoYikudG8uYmUuaW5zdGFuY2VPZihBKVxuICAgICAgICAgICAgZXhwZWN0KGIpLm5vdC5lcXVhbChhKTtcbiAgICAgICAgICAgIGV4cGVjdChKU09OLnN0cmluZ2lmeShhKSkuZXF1YWwoSlNPTi5zdHJpbmdpZnkoYikpO1xuXG4gICAgICAgIH0pO1xuICAgIH0pXG5cbiAgICAvLyBub2RlanMgZG9lcyBub3QgaGF2ZSBhIERPTVxuICAgIGlmICh0eXBlb2YgRG9jdW1lbnRGcmFnbWVudCA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICBkZXNjcmliZSgnLmNsb25lKERvY3VtZW50RnJhZ21lbnQpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaXQoJy5jbG9uZShEb2N1bWVudEZyYWdtZW50KSBzaG91bGQgc2FtZSBEb2N1bWVudEZyYWdtZW50JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGxldCBhID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpO1xuICAgICAgICAgICAgICAgIGxldCBiID0gY2xvbmUoYSk7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGIpLmVxdWFsKGEpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgZGVzY3JpYmUoJy5jbG9uZShudWxsKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gdHlwZW9mIG51bGwgcmVzdWx0cyBpbiAnb2JqZWN0Jy4gIGh0dHBzOi8vMmFsaXR5LmNvbS8yMDEzLzEwL3R5cGVvZi1udWxsLmh0bWxcbiAgICAgICAgaXQoJy5jbG9uZShudWxsKSBzaG91bGQgIG51bGwnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgYSA9IG51bGxcbiAgICAgICAgICAgIGxldCBiID0gY2xvbmUoYSk7XG4gICAgICAgICAgICBleHBlY3QoYikuZXF1YWwoYSk7XG4gICAgICAgICAgICBleHBlY3QoYikudG8uYmUubnVsbDtcbiAgICAgICAgICAgIGV4cGVjdChhKS50by5iZS5udWxsO1xuICAgICAgICB9KTtcbiAgICB9KVxuXG4gICAgZGVzY3JpYmUoJy5jbG9uZSh1bmRlZmluZWQpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnLmNsb25lKHVuZGVmaW5lZCkgc2hvdWxkICB1bmRlZmluZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgYSA9IHVuZGVmaW5lZFxuICAgICAgICAgICAgbGV0IGIgPSBjbG9uZShhKTtcbiAgICAgICAgICAgIGV4cGVjdChhID09PSBiKS50by5iZS50cnVlXG4gICAgICAgICAgICBleHBlY3QodHlwZW9mIGIgPT09ICd1bmRlZmluZWQnKS50by5iZS50cnVlXG4gICAgICAgICAgICBleHBlY3QoYSA9PT0gdW5kZWZpbmVkKS50by5iZS50cnVlXG4gICAgICAgICAgICBleHBlY3QoYiA9PT0gdW5kZWZpbmVkKS50by5iZS50cnVlXG4gICAgICAgIH0pO1xuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnLmNsb25lKG9iamVjdCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJy5jbG9uZSh7fSkgc2hvdWxkICBvYmplY3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgYSA9IHt9XG4gICAgICAgICAgICBsZXQgYiA9IGNsb25lKGEpO1xuICAgICAgICAgICAgZXhwZWN0KHR5cGVvZiBiID09PSAnb2JqZWN0JykudG8uYmUudHJ1ZVxuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnLmNsb25lKHt4OjF9KSBzaG91bGQgIG9iamVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBhID0ge3g6IDF9XG4gICAgICAgICAgICBsZXQgYiA9IGNsb25lKGEpO1xuICAgICAgICAgICAgZXhwZWN0KGEueCkuaXMuZXF1YWwoYi54KVxuICAgICAgICB9KTtcbiAgICB9KVxuICAgIGRlc2NyaWJlKCcuY2xvbmUoZnVuY3Rpb24pJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCcuY2xvbmUoZnVuY3Rpb24pIHNob3VsZCAgZnVuY3Rpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgYSA9ICgpID0+IHtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCBiID0gY2xvbmUoYSk7XG4gICAgICAgICAgICBleHBlY3QodHlwZW9mIGIgPT09ICdmdW5jdGlvbicpLnRvLmJlLnRydWVcbiAgICAgICAgfSk7XG5cbiAgICB9KVxuXG4gICAgZGVzY3JpYmUoJy5jbG9uZSgpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIFtcbiAgICAgICAgICAgIFsndGVzdDEnLCAnc3RyaW5nJ10sXG4gICAgICAgICAgICBbdW5kZWZpbmVkLCAndW5kZWZpbmVkJ10sXG4gICAgICAgICAgICBbbnVsbCwgJ29iamVjdCddLCAvLyB0eXBlb2YgbnVsbCByZXN1bHRzIGluICdvYmplY3QnLiAgaHR0cHM6Ly8yYWxpdHkuY29tLzIwMTMvMTAvdHlwZW9mLW51bGwuaHRtbFxuICAgICAgICAgICAgWygpID0+IHtcbiAgICAgICAgICAgIH0sICdmdW5jdGlvbiddLFxuICAgICAgICAgICAgWzIsICdudW1iZXInXSxcbiAgICAgICAgICAgIFtmYWxzZSwgJ2Jvb2xlYW4nXSxcbiAgICAgICAgICAgIFt0cnVlLCAnYm9vbGVhbiddLFxuICAgICAgICAgICAgWzQuNSwgJ251bWJlciddLFxuICAgICAgICAgICAgW3t9LCAnb2JqZWN0J10sXG4gICAgICAgICAgICBbWzEsIDIsIDNdLCAnb2JqZWN0J10sIC8vIGFycmF5IGlzdCBhdWNoIHR5cGUgb2JqZWN0XG4gICAgICAgICAgICBbU3ltYm9sKFwiZm9vXCIpLCAnc3ltYm9sJ10sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcblxuXG4gICAgICAgICAgICBpdCgnLmNsb25lKCcgKyBKU09OLnN0cmluZ2lmeShhKSArICcpIHNob3VsZCAgJyArIGIgKyAnICcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBsZXQgYyA9IGNsb25lKGEpO1xuICAgICAgICAgICAgICAgIGV4cGVjdCh0eXBlb2YgYykuaXMuZXF1YWwoYik7XG4gICAgICAgICAgICB9KTtcblxuXG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxufSk7XG5cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGdldEdsb2JhbE9iamVjdCB9IGZyb20gXCIuLi8uLi90eXBlcy9nbG9iYWwubWpzXCI7XG5pbXBvcnQgeyBIYW5kbGVyIH0gZnJvbSBcIi4uL2hhbmRsZXIubWpzXCI7XG5pbXBvcnQgeyBMb2dFbnRyeSB9IGZyb20gXCIuLi9sb2dlbnRyeS5tanNcIjtcbmltcG9ydCB7IFRSQUNFLCBXQVJOLCBERUJVRywgRVJST1IsIEZBVEFMLCBJTkZPIH0gZnJvbSBcIi4uL2xvZ2dlci5tanNcIjtcblxuZXhwb3J0IHsgQ29uc29sZUhhbmRsZXIgfTtcblxuLyoqXG4gKiBZb3UgY2FuIGNyZWF0ZSBhbiBvYmplY3Qgb2YgdGhlIGNsYXNzIHNpbXBseSBieSB1c2luZyB0aGUgbmFtZXNwYWNlIGBuZXcgTW9uc3Rlci5Mb2dnaW5nLkhhbmRsZXIuQ29uc29sZUhhbmRsZXIoKWAuXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS41LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5Mb2dnaW5nLkhhbmRsZXJcbiAqL1xuY2xhc3MgQ29uc29sZUhhbmRsZXIgZXh0ZW5kcyBIYW5kbGVyIHtcbiAgICAvKipcbiAgICAgKiBUaGlzIGlzIHRoZSBjZW50cmFsIGxvZyBmdW5jdGlvbi4gdGhpcyBtZXRob2QgbXVzdCBiZVxuICAgICAqIG92ZXJ3cml0dGVuIGJ5IGRlcml2ZWQgaGFuZGxlcnMgd2l0aCB0aGVpciBvd24gbG9naWMuXG4gICAgICpcbiAgICAgKiBBTEwgPiBUUkFDRSA+IERFQlVHID4gSU5GTyA+IFdBUk4gPiBFUlJPUiA+IEZBVEFMID4gT0ZGICAoQUxMID0gMHhmZjtPRkYgPSAweDAwO1xuICAgICAqXG4gICAgICogQHBhcmFtIHtMb2dFbnRyeX0gZW50cnlcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBsb2coZW50cnkpIHtcbiAgICAgICAgaWYgKHN1cGVyLmxvZyhlbnRyeSkpIHtcbiAgICAgICAgICAgIGxldCBjb25zb2xlID0gZ2V0R2xvYmFsT2JqZWN0KFwiY29uc29sZVwiKTtcbiAgICAgICAgICAgIGlmICghY29uc29sZSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgICAgICBpZiAoIWNvbnNvbGUuZXJyb3IpIGNvbnNvbGUuZXJyb3IgPSBjb25zb2xlLmxvZztcbiAgICAgICAgICAgIGlmICghY29uc29sZS53YXJuKSBjb25zb2xlLndhcm4gPSBjb25zb2xlLmxvZztcblxuICAgICAgICAgICAgc3dpdGNoIChlbnRyeS5nZXRMb2dMZXZlbCgpKSB7XG4gICAgICAgICAgICAgICAgY2FzZSBUUkFDRTpcbiAgICAgICAgICAgICAgICBjYXNlIERFQlVHOlxuICAgICAgICAgICAgICAgIGNhc2UgSU5GTzpcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coZW50cnkudG9TdHJpbmcoKSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgRkFUQUw6XG4gICAgICAgICAgICAgICAgY2FzZSBFUlJPUjpcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlbnRyeS50b1N0cmluZygpKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBXQVJOOlxuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oZW50cnkudG9TdHJpbmcoKSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGVudHJ5LnRvU3RyaW5nKCkpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufVxuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgQmFzZSB9IGZyb20gXCIuLi90eXBlcy9iYXNlLm1qc1wiO1xuaW1wb3J0IHsgdmFsaWRhdGVJbnN0YW5jZSwgdmFsaWRhdGVJbnRlZ2VyIH0gZnJvbSBcIi4uL3R5cGVzL3ZhbGlkYXRlLm1qc1wiO1xuaW1wb3J0IHsgTG9nRW50cnkgfSBmcm9tIFwiLi9sb2dlbnRyeS5tanNcIjtcbmltcG9ydCB7IEFMTCwgREVCVUcsIEVSUk9SLCBGQVRBTCwgSU5GTywgT0ZGLCBUUkFDRSwgV0FSTiB9IGZyb20gXCIuL2xvZ2dlci5tanNcIjtcblxuZXhwb3J0IHsgSGFuZGxlciB9O1xuXG4vKipcbiAqIFRoZSBsb2cgaGFuZGxlciBpcyB0aGUgaW50ZXJmYWNlIGJldHdlZW4gdGhlIGxvZyBlbnRyaWVzIGFuZCB0aGUgbG9nIGxpc3RlbmVycy5cbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjUuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkxvZ2dpbmdcbiAqL1xuY2xhc3MgSGFuZGxlciBleHRlbmRzIEJhc2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBMb2dsZXZlbFxuICAgICAgICAgKlxuICAgICAgICAgKiBAdHlwZSB7aW50ZWdlcn1cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMubG9nbGV2ZWwgPSBPRkY7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBpcyB0aGUgY2VudHJhbCBsb2cgZnVuY3Rpb24uIHRoaXMgbWV0aG9kIG11c3QgYmVcbiAgICAgKiBvdmVyd3JpdHRlbiBieSBkZXJpdmVkIGhhbmRsZXJzIHdpdGggdGhlaXIgb3duIGxvZ2ljLlxuICAgICAqXG4gICAgICogQUxMID4gVFJBQ0UgPiBERUJVRyA+IElORk8gPiBXQVJOID4gRVJST1IgPiBGQVRBTCA+IE9GRiAgKEFMTCA9IDB4ZmY7T0ZGID0gMHgwMDtcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7TG9nRW50cnl9IGVudHJ5XG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAgICovXG4gICAgbG9nKGVudHJ5KSB7XG4gICAgICAgIHZhbGlkYXRlSW5zdGFuY2UoZW50cnksIExvZ0VudHJ5KTtcblxuICAgICAgICBpZiAodGhpcy5sb2dsZXZlbCA8IGVudHJ5LmdldExvZ0xldmVsKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHNldCBsb2dsZXZlbFxuICAgICAqXG4gICAgICogQHBhcmFtIHtpbnRlZ2VyfSBsb2dsZXZlbFxuICAgICAqIEByZXR1cm5zIHtIYW5kbGVyfVxuICAgICAqIEBzaW5jZSAxLjUuMFxuICAgICAqL1xuICAgIHNldExvZ0xldmVsKGxvZ2xldmVsKSB7XG4gICAgICAgIHZhbGlkYXRlSW50ZWdlcihsb2dsZXZlbCk7XG4gICAgICAgIHRoaXMubG9nbGV2ZWwgPSBsb2dsZXZlbDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogZ2V0IGxvZ2xldmVsXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7aW50ZWdlcn1cbiAgICAgKiBAc2luY2UgMS41LjBcbiAgICAgKi9cbiAgICBnZXRMb2dMZXZlbCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubG9nbGV2ZWw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogIFNldCBsb2cgbGV2ZWwgdG8gQWxsXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7SGFuZGxlcn1cbiAgICAgKiBAc2luY2UgMS41LjBcbiAgICAgKi9cbiAgICBzZXRBbGwoKSB7XG4gICAgICAgIHRoaXMuc2V0TG9nTGV2ZWwoQUxMKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IGxvZyBsZXZlbCB0byBUcmFjZVxuICAgICAqXG4gICAgICogQHJldHVybnMge0hhbmRsZXJ9XG4gICAgICogQHNpbmNlIDEuNS4wXG4gICAgICovXG4gICAgc2V0VHJhY2UoKSB7XG4gICAgICAgIHRoaXMuc2V0TG9nTGV2ZWwoVFJBQ0UpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgbG9nIGxldmVsIHRvIERlYnVnXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7SGFuZGxlcn1cbiAgICAgKiBAc2luY2UgMS41LjBcbiAgICAgKi9cbiAgICBzZXREZWJ1ZygpIHtcbiAgICAgICAgdGhpcy5zZXRMb2dMZXZlbChERUJVRyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldCBsb2cgbGV2ZWwgdG8gSW5mb1xuICAgICAqXG4gICAgICogQHJldHVybnMge0hhbmRsZXJ9XG4gICAgICogQHNpbmNlIDEuNS4wXG4gICAgICovXG4gICAgc2V0SW5mbygpIHtcbiAgICAgICAgdGhpcy5zZXRMb2dMZXZlbChJTkZPKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IGxvZyBsZXZlbCB0byBXYXJuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxuICAgICAqIEBzaW5jZSAxLjUuMFxuICAgICAqL1xuICAgIHNldFdhcm4oKSB7XG4gICAgICAgIHRoaXMuc2V0TG9nTGV2ZWwoV0FSTik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldCBsb2cgbGV2ZWwgdG8gRXJyb3JcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtIYW5kbGVyfVxuICAgICAqIEBzaW5jZSAxLjUuMFxuICAgICAqL1xuICAgIHNldEVycm9yKCkge1xuICAgICAgICB0aGlzLnNldExvZ0xldmVsKEVSUk9SKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IGxvZyBsZXZlbCB0byBGYXRhbFxuICAgICAqXG4gICAgICogQHJldHVybnMge0hhbmRsZXJ9XG4gICAgICogQHNpbmNlIDEuNS4wXG4gICAgICovXG4gICAgc2V0RmF0YWwoKSB7XG4gICAgICAgIHRoaXMuc2V0TG9nTGV2ZWwoRkFUQUwpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgbG9nIGxldmVsIHRvIE9mZlxuICAgICAqXG4gICAgICogQHJldHVybnMge0hhbmRsZXJ9XG4gICAgICogQHNpbmNlIDEuNS4wXG4gICAgICovXG4gICAgc2V0T2ZmKCkge1xuICAgICAgICB0aGlzLnNldExvZ0xldmVsKE9GRik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IEJhc2UgfSBmcm9tIFwiLi4vdHlwZXMvYmFzZS5tanNcIjtcbmltcG9ydCB7IHZhbGlkYXRlSW50ZWdlciB9IGZyb20gXCIuLi90eXBlcy92YWxpZGF0ZS5tanNcIjtcblxuZXhwb3J0IHsgTG9nRW50cnkgfTtcblxuLyoqXG4gKiBBIGxvZyBlbnRyeSBmb3IgdGhlIGxvZ2dlclxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuNS4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuTG9nZ2luZ1xuICovXG5jbGFzcyBMb2dFbnRyeSBleHRlbmRzIEJhc2Uge1xuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtJbnRlZ2VyfSBsb2dsZXZlbFxuICAgICAqIEBwYXJhbSB7Li4uKn0gYXJnc1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGxvZ2xldmVsLCAuLi5hcmdzKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHZhbGlkYXRlSW50ZWdlcihsb2dsZXZlbCk7XG5cbiAgICAgICAgdGhpcy5sb2dsZXZlbCA9IGxvZ2xldmVsO1xuICAgICAgICB0aGlzLmFyZ3VtZW50cyA9IGFyZ3M7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7aW50ZWdlcnJ9XG4gICAgICovXG4gICAgZ2V0TG9nTGV2ZWwoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxvZ2xldmVsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHJldHVybnMge2FycmF5fVxuICAgICAqL1xuICAgIGdldEFyZ3VtZW50cygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXJndW1lbnRzO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IEhhbmRsZXIgfSBmcm9tIFwiLi4vbG9nZ2luZy9oYW5kbGVyLm1qc1wiO1xuaW1wb3J0IHsgTG9nRW50cnkgfSBmcm9tIFwiLi4vbG9nZ2luZy9sb2dlbnRyeS5tanNcIjtcblxuaW1wb3J0IHsgQmFzZSB9IGZyb20gXCIuLi90eXBlcy9iYXNlLm1qc1wiO1xuaW1wb3J0IHsgdmFsaWRhdGVJbnRlZ2VyLCB2YWxpZGF0ZU9iamVjdCwgdmFsaWRhdGVTdHJpbmcgfSBmcm9tIFwiLi4vdHlwZXMvdmFsaWRhdGUubWpzXCI7XG5cbmV4cG9ydCB7IExvZ2dlciwgQUxMLCBUUkFDRSwgREVCVUcsIElORk8sIFdBUk4sIEVSUk9SLCBGQVRBTCwgT0ZGIH07XG5cbi8qKlxuICogQUxMID4gVFJBQ0UgPiBERUJVRyA+IElORk8gPiBXQVJOID4gRVJST1IgPiBGQVRBTCA+IE9GRlxuICogQHR5cGUge251bWJlcn1cbiAqIEBtZW1iZXJPZiBNb25zdGVyLkxvZ2dpbmdcbiAqL1xuY29uc3QgQUxMID0gMjU1O1xuLyoqXG4gKiBBTEwgPiBUUkFDRSA+IERFQlVHID4gSU5GTyA+IFdBUk4gPiBFUlJPUiA+IEZBVEFMID4gT0ZGXG4gKiBAdHlwZSB7bnVtYmVyfVxuICogQG1lbWJlck9mIE1vbnN0ZXIuTG9nZ2luZ1xuICovXG5jb25zdCBUUkFDRSA9IDY0O1xuLyoqXG4gKiBBTEwgPiBUUkFDRSA+IERFQlVHID4gSU5GTyA+IFdBUk4gPiBFUlJPUiA+IEZBVEFMID4gT0ZGXG4gKiBAdHlwZSB7bnVtYmVyfVxuICogQG1lbWJlck9mIE1vbnN0ZXIuTG9nZ2luZ1xuICovXG5jb25zdCBERUJVRyA9IDMyO1xuLyoqXG4gKiBBTEwgPiBUUkFDRSA+IERFQlVHID4gSU5GTyA+IFdBUk4gPiBFUlJPUiA+IEZBVEFMID4gT0ZGXG4gKiBAdHlwZSB7bnVtYmVyfVxuICogQG1lbWJlck9mIE1vbnN0ZXIuTG9nZ2luZ1xuICovXG5jb25zdCBJTkZPID0gMTY7XG4vKipcbiAqIEFMTCA+IFRSQUNFID4gREVCVUcgPiBJTkZPID4gV0FSTiA+IEVSUk9SID4gRkFUQUwgPiBPRkZcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5Mb2dnaW5nXG4gKi9cbmNvbnN0IFdBUk4gPSA4O1xuLyoqXG4gKiBBTEwgPiBUUkFDRSA+IERFQlVHID4gSU5GTyA+IFdBUk4gPiBFUlJPUiA+IEZBVEFMID4gT0ZGXG4gKiBAdHlwZSB7bnVtYmVyfVxuICogQG1lbWJlck9mIE1vbnN0ZXIuTG9nZ2luZ1xuICovXG5jb25zdCBFUlJPUiA9IDQ7XG4vKipcbiAqIEFMTCA+IFRSQUNFID4gREVCVUcgPiBJTkZPID4gV0FSTiA+IEVSUk9SID4gRkFUQUwgPiBPRkZcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5Mb2dnaW5nXG4gKi9cbmNvbnN0IEZBVEFMID0gMjtcbi8qKlxuICogQUxMID4gVFJBQ0UgPiBERUJVRyA+IElORk8gPiBXQVJOID4gRVJST1IgPiBGQVRBTCA+IE9GRlxuICogQHR5cGUge251bWJlcn1cbiAqIEBtZW1iZXJPZiBNb25zdGVyLkxvZ2dpbmdcbiAqL1xuY29uc3QgT0ZGID0gMDtcblxuLyoqXG4gKiBUaGUgbG9nZ2VyIGlzIGEgY2xhc3MgdGhhdCB0YWtlcyBjYXJlIG9mIGxvZ2dpbmcuXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS41LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5Mb2dnaW5nXG4gKi9cbmNsYXNzIExvZ2dlciBleHRlbmRzIEJhc2Uge1xuICAgIC8qKlxuICAgICAqXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMuaGFuZGxlciA9IG5ldyBTZXQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7SGFuZGxlcn0gaGFuZGxlclxuICAgICAqIEByZXR1cm5zIHtMb2dnZXJ9XG4gICAgICogQHRocm93cyB7RXJyb3J9IHRoZSBoYW5kbGVyIG11c3QgYmUgYW4gaW5zdGFuY2Ugb2YgSGFuZGxlclxuICAgICAqL1xuICAgIGFkZEhhbmRsZXIoaGFuZGxlcikge1xuICAgICAgICB2YWxpZGF0ZU9iamVjdChoYW5kbGVyKTtcbiAgICAgICAgaWYgKCEoaGFuZGxlciBpbnN0YW5jZW9mIEhhbmRsZXIpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0aGUgaGFuZGxlciBtdXN0IGJlIGFuIGluc3RhbmNlIG9mIEhhbmRsZXJcIik7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmhhbmRsZXIuYWRkKGhhbmRsZXIpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7SGFuZGxlcn0gaGFuZGxlclxuICAgICAqIEByZXR1cm5zIHtMb2dnZXJ9XG4gICAgICogQHRocm93cyB7RXJyb3J9IHRoZSBoYW5kbGVyIG11c3QgYmUgYW4gaW5zdGFuY2Ugb2YgSGFuZGxlclxuICAgICAqL1xuICAgIHJlbW92ZUhhbmRsZXIoaGFuZGxlcikge1xuICAgICAgICB2YWxpZGF0ZU9iamVjdChoYW5kbGVyKTtcbiAgICAgICAgaWYgKCEoaGFuZGxlciBpbnN0YW5jZW9mIEhhbmRsZXIpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0aGUgaGFuZGxlciBtdXN0IGJlIGFuIGluc3RhbmNlIG9mIEhhbmRsZXJcIik7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmhhbmRsZXIuZGVsZXRlKGhhbmRsZXIpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBsb2cgVHJhY2UgbWVzc2FnZVxuICAgICAqXG4gICAgICogQUxMID4gVFJBQ0UgPiBERUJVRyA+IElORk8gPiBXQVJOID4gRVJST1IgPiBGQVRBTCA+IE9GRiAgKEFMTCA9IDB4ZmY7T0ZGID0gMHgwMDtcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Kn0gYXJndW1lbnRzXG4gICAgICogQHJldHVybnMge0xvZ2dlcn1cbiAgICAgKiBAc2luY2UgMS41LjBcbiAgICAgKi9cbiAgICBsb2dUcmFjZSguLi5hcmdzKSB7XG4gICAgICAgIGlmICh0eXBlb2YgYXJncyAhPT0gXCJvYmplY3RcIiB8fCBhcmdzWzBdID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0aGUgZmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhbiBvYmplY3RcIik7XG4gICAgICAgIH1cblxuICAgICAgICB0cmlnZ2VyTG9nLmFwcGx5KHRoaXMsIFtUUkFDRSwgLi4uYXJnc10pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBsb2cgRGVidWcgbWVzc2FnZVxuICAgICAqXG4gICAgICogQUxMID4gVFJBQ0UgPiBERUJVRyA+IElORk8gPiBXQVJOID4gRVJST1IgPiBGQVRBTCA+IE9GRiAgKEFMTCA9IDB4ZmY7T0ZGID0gMHgwMDtcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Kn0gYXJndW1lbnRzXG4gICAgICogQHJldHVybnMge0xvZ2dlcn1cbiAgICAgKiBAc2luY2UgMS41LjBcbiAgICAgKi9cbiAgICBsb2dEZWJ1ZyguLi5hcmdzKSB7XG4gICAgICAgIGlmICh0eXBlb2YgYXJncyAhPT0gXCJvYmplY3RcIiB8fCBhcmdzWzBdID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0aGUgZmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhbiBvYmplY3RcIik7XG4gICAgICAgIH1cblxuICAgICAgICB0cmlnZ2VyTG9nLmFwcGx5KHRoaXMsIFtERUJVRywgLi4uYXJnc10pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBsb2cgSW5mbyBtZXNzYWdlXG4gICAgICpcbiAgICAgKiBBTEwgPiBUUkFDRSA+IERFQlVHID4gSU5GTyA+IFdBUk4gPiBFUlJPUiA+IEZBVEFMID4gT0ZGICAoQUxMID0gMHhmZjtPRkYgPSAweDAwO1xuICAgICAqXG4gICAgICpcbiAgICAgKiBAcGFyYW0geyp9IGFyZ3VtZW50c1xuICAgICAqIEByZXR1cm5zIHtMb2dnZXJ9XG4gICAgICogQHNpbmNlIDEuNS4wXG4gICAgICovXG4gICAgbG9nSW5mbyguLi5hcmdzKSB7XG4gICAgICAgIGlmICh0eXBlb2YgYXJncyAhPT0gXCJvYmplY3RcIiB8fCBhcmdzWzBdID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0aGUgZmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhbiBvYmplY3RcIik7XG4gICAgICAgIH1cblxuICAgICAgICB0cmlnZ2VyTG9nLmFwcGx5KHRoaXMsIFtJTkZPLCAuLi5hcmdzXSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIGxvZyBXYXJuIG1lc3NhZ2VcbiAgICAgKlxuICAgICAqIEFMTCA+IFRSQUNFID4gREVCVUcgPiBJTkZPID4gV0FSTiA+IEVSUk9SID4gRkFUQUwgPiBPRkYgIChBTEwgPSAweGZmO09GRiA9IDB4MDA7XG4gICAgICpcbiAgICAgKiBAcGFyYW0geyp9IGFyZ3VtZW50c1xuICAgICAqIEByZXR1cm5zIHtMb2dnZXJ9XG4gICAgICogQHNpbmNlIDEuNS4wXG4gICAgICovXG4gICAgbG9nV2FybiguLi5hcmdzKSB7XG4gICAgICAgIGlmICh0eXBlb2YgYXJncyAhPT0gXCJvYmplY3RcIiB8fCBhcmdzWzBdID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0aGUgZmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhbiBvYmplY3RcIik7XG4gICAgICAgIH1cblxuICAgICAgICB0cmlnZ2VyTG9nLmFwcGx5KHRoaXMsIFtXQVJOLCAuLi5hcmdzXSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIGxvZyBFcnJvciBtZXNzYWdlXG4gICAgICpcbiAgICAgKiBBTEwgPiBUUkFDRSA+IERFQlVHID4gSU5GTyA+IFdBUk4gPiBFUlJPUiA+IEZBVEFMID4gT0ZGICAoQUxMID0gMHhmZjtPRkYgPSAweDAwO1xuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSBhcmd1bWVudHNcbiAgICAgKiBAcmV0dXJucyB7TG9nZ2VyfVxuICAgICAqIEBzaW5jZSAxLjUuMFxuICAgICAqL1xuICAgIGxvZ0Vycm9yKC4uLmFyZ3MpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBhcmdzICE9PSBcIm9iamVjdFwiIHx8IGFyZ3NbMF0gPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInRoZSBmaXJzdCBhcmd1bWVudCBtdXN0IGJlIGFuIG9iamVjdFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRyaWdnZXJMb2cuYXBwbHkodGhpcywgW0VSUk9SLCAuLi5hcmdzXSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIGxvZyBGYXRhbCBtZXNzYWdlXG4gICAgICpcbiAgICAgKiBBTEwgPiBUUkFDRSA+IERFQlVHID4gSU5GTyA+IFdBUk4gPiBFUlJPUiA+IEZBVEFMID4gT0ZGICAoQUxMID0gMHhmZjtPRkYgPSAweDAwO1xuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSBhcmd1bWVudHNcbiAgICAgKiBAcmV0dXJucyB7TG9nZ2VyfVxuICAgICAqIEBzaW5jZSAxLjUuMFxuICAgICAqL1xuICAgIGxvZ0ZhdGFsKC4uLmFyZ3MpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBhcmdzICE9PSBcIm9iamVjdFwiIHx8IGFyZ3NbMF0gPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInRoZSBmaXJzdCBhcmd1bWVudCBtdXN0IGJlIGFuIG9iamVjdFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRyaWdnZXJMb2cuYXBwbHkodGhpcywgW0ZBVEFMLCAuLi5hcmdzXSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIExhYmVsc1xuICAgICAqXG4gICAgICogQHBhcmFtIHtpbnRlZ2VyfSBsZXZlbFxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAgICovXG4gICAgZ2V0TGFiZWwobGV2ZWwpIHtcbiAgICAgICAgdmFsaWRhdGVJbnRlZ2VyKGxldmVsKTtcblxuICAgICAgICBpZiAobGV2ZWwgPT09IEFMTCkgcmV0dXJuIFwiQUxMXCI7XG4gICAgICAgIGlmIChsZXZlbCA9PT0gVFJBQ0UpIHJldHVybiBcIlRSQUNFXCI7XG4gICAgICAgIGlmIChsZXZlbCA9PT0gREVCVUcpIHJldHVybiBcIkRFQlVHXCI7XG4gICAgICAgIGlmIChsZXZlbCA9PT0gSU5GTykgcmV0dXJuIFwiSU5GT1wiO1xuICAgICAgICBpZiAobGV2ZWwgPT09IFdBUk4pIHJldHVybiBcIldBUk5cIjtcbiAgICAgICAgaWYgKGxldmVsID09PSBFUlJPUikgcmV0dXJuIFwiRVJST1JcIjtcbiAgICAgICAgaWYgKGxldmVsID09PSBGQVRBTCkgcmV0dXJuIFwiRkFUQUxcIjtcbiAgICAgICAgaWYgKGxldmVsID09PSBPRkYpIHJldHVybiBcIk9GRlwiO1xuXG4gICAgICAgIHJldHVybiBcInVua25vd25cIjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBMZXZlbFxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGxhYmVsXG4gICAgICogQHJldHVybnMge2ludGVnZXJ9XG4gICAgICovXG4gICAgZ2V0TGV2ZWwobGFiZWwpIHtcbiAgICAgICAgdmFsaWRhdGVTdHJpbmcobGFiZWwpO1xuXG4gICAgICAgIGlmIChsYWJlbCA9PT0gXCJBTExcIikgcmV0dXJuIEFMTDtcbiAgICAgICAgaWYgKGxhYmVsID09PSBcIlRSQUNFXCIpIHJldHVybiBUUkFDRTtcbiAgICAgICAgaWYgKGxhYmVsID09PSBcIkRFQlVHXCIpIHJldHVybiBERUJVRztcbiAgICAgICAgaWYgKGxhYmVsID09PSBcIklORk9cIikgcmV0dXJuIElORk87XG4gICAgICAgIGlmIChsYWJlbCA9PT0gXCJXQVJOXCIpIHJldHVybiBXQVJOO1xuICAgICAgICBpZiAobGFiZWwgPT09IFwiRVJST1JcIikgcmV0dXJuIEVSUk9SO1xuICAgICAgICBpZiAobGFiZWwgPT09IFwiRkFUQUxcIikgcmV0dXJuIEZBVEFMO1xuICAgICAgICBpZiAobGFiZWwgPT09IFwiT0ZGXCIpIHJldHVybiBPRkY7XG5cbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxufVxuXG4vKipcbiAqIExvZyB0cmlnZ2VyblxuICpcbiAqIEBwYXJhbSB7aW50ZWdlcn0gbG9nbGV2ZWxcbiAqIEBwYXJhbSB7Kn0gYXJnc1xuICogQHJldHVybnMge0xvZ2dlcn1cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHRyaWdnZXJMb2cobG9nbGV2ZWwsIC4uLmFyZ3MpIHtcbiAgICB2YXIgbG9nZ2VyID0gdGhpcztcblxuICAgIGZvciAobGV0IGhhbmRsZXIgb2YgbG9nZ2VyLmhhbmRsZXIpIHtcbiAgICAgICAgaGFuZGxlci5sb2cobmV3IExvZ0VudHJ5KGxvZ2xldmVsLCBhcmdzKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGxvZ2dlcjtcbn1cbiIsICJpbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIjtcbmltcG9ydCB7Q29uc29sZUhhbmRsZXJ9IGZyb20gXCIuLi8uLi8uLi8uLi9zb3VyY2UvbG9nZ2luZy9oYW5kbGVyL2NvbnNvbGUubWpzXCI7XG5pbXBvcnQge0xvZ0VudHJ5fSBmcm9tIFwiLi4vLi4vLi4vLi4vc291cmNlL2xvZ2dpbmcvbG9nZW50cnkubWpzXCI7XG5pbXBvcnQge1RSQUNFLCBXQVJOLCBERUJVRywgRVJST1IsIEZBVEFMLCBJTkZPfSBmcm9tIFwiLi4vLi4vLi4vLi4vc291cmNlL2xvZ2dpbmcvbG9nZ2VyLm1qc1wiO1xuXG5kZXNjcmliZSgnTG9nZ2luZycsIGZ1bmN0aW9uICgpIHtcblxuICAgIGRlc2NyaWJlKCdDb25zb2xlSGFuZGxlcicsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBpdCgnc2hvdWxkIGNyZWF0ZSBDb25zb2xlSGFuZGxlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgQ29uc29sZUhhbmRsZXIoKSkudG8uYmUuaW5zdGFuY2VvZihDb25zb2xlSGFuZGxlcilcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBsb2cgdG8gY29uc29sZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgQ29uc29sZUhhbmRsZXIoKS5zZXRBbGwoKS5sb2cobmV3IExvZ0VudHJ5KEZBVEFMLCBbMSwgdHJ1ZSwgJ2ZhdGFsJ10pKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBsb2cgdG8gY29uc29sZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgQ29uc29sZUhhbmRsZXIoKS5zZXRBbGwoKS5sb2cobmV3IExvZ0VudHJ5KFRSQUNFLCBbMSwgdHJ1ZSwgJ3RyYWNlJ10pKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBsb2cgdG8gY29uc29sZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgQ29uc29sZUhhbmRsZXIoKS5zZXRBbGwoKS5sb2cobmV3IExvZ0VudHJ5KFdBUk4sIFsxLCB0cnVlLCAnd2FybiddKSkpLnRvLmJlLnRydWU7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgbG9nIHRvIGNvbnNvbGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IENvbnNvbGVIYW5kbGVyKCkuc2V0QWxsKCkubG9nKG5ldyBMb2dFbnRyeShERUJVRywgWzEsIHRydWUsICdkZWJ1ZyddKSkpLnRvLmJlLnRydWU7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgbG9nIHRvIGNvbnNvbGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IENvbnNvbGVIYW5kbGVyKCkuc2V0QWxsKCkubG9nKG5ldyBMb2dFbnRyeShFUlJPUiwgWzEsIHRydWUsICdlcnJvciddKSkpLnRvLmJlLnRydWU7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgbG9nIHRvIGNvbnNvbGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IENvbnNvbGVIYW5kbGVyKCkuc2V0QWxsKCkubG9nKG5ldyBMb2dFbnRyeShJTkZPLCBbMSwgdHJ1ZSwgJ2luZm8nXSkpKS50by5iZS50cnVlO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuXG59KTsiLCAiaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7TG9nZ2VyLCBPRkYsIEFMTCwgVFJBQ0UsIERFQlVHLCBJTkZPLCBXQVJOLCBFUlJPUiwgRkFUQUx9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvbG9nZ2luZy9sb2dnZXIubWpzXCI7XG5cblxuZGVzY3JpYmUoJ0xvZ2dpbmcnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBkZXNjcmliZSgnbmV3IExvZ2dlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gaW5zdGFuY2VvZiBMb2dnZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IExvZ2dlcigpKS50by5pbnN0YW5jZU9mKExvZ2dlcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ0xvZ2dlci5sb2dUcmFjZSgpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBpbnN0YW5jZW9mIExvZ2dlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgTG9nZ2VyKCkubG9nVHJhY2UoXCJ0ZXN0XCIpKS50by5pbnN0YW5jZU9mKExvZ2dlcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICAgIFxuICAgIGRlc2NyaWJlKCdMb2dnZXIubG9nRGVidWcoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gaW5zdGFuY2VvZiBMb2dnZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IExvZ2dlcigpLmxvZ0RlYnVnKFwidGVzdFwiKSkudG8uaW5zdGFuY2VPZihMb2dnZXIpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgICBcbiAgICBkZXNjcmliZSgnTG9nZ2VyLmxvZ0luZm8oKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gaW5zdGFuY2VvZiBMb2dnZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IExvZ2dlcigpLmxvZ0luZm8oXCJ0ZXN0XCIpKS50by5pbnN0YW5jZU9mKExvZ2dlcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICAgIFxuICAgIGRlc2NyaWJlKCdMb2dnZXIubG9nV2FybigpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBpbnN0YW5jZW9mIExvZ2dlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgTG9nZ2VyKCkubG9nV2FybihcInRlc3RcIikpLnRvLmluc3RhbmNlT2YoTG9nZ2VyKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gICAgXG4gICAgZGVzY3JpYmUoJ0xvZ2dlci5sb2dFcnJvcigpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBpbnN0YW5jZW9mIExvZ2dlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgTG9nZ2VyKCkubG9nRXJyb3IoXCJ0ZXN0XCIpKS50by5pbnN0YW5jZU9mKExvZ2dlcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICAgIFxuICAgIGRlc2NyaWJlKCdMb2dnZXIubG9nRmF0YWwoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gaW5zdGFuY2VvZiBMb2dnZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IExvZ2dlcigpLmxvZ0ZhdGFsKFwidGVzdFwiKSkudG8uaW5zdGFuY2VPZihMb2dnZXIpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgICBcbiAgICBkZXNjcmliZSgnTG9nZ2VyLmdldExldmVsKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIFtcbiAgICAgICAgICAgIFsnQUxMJywgQUxMXSxcbiAgICAgICAgICAgIFsnVFJBQ0UnLCBUUkFDRV0sXG4gICAgICAgICAgICBbJ0RFQlVHJywgREVCVUddLFxuICAgICAgICAgICAgWydJTkZPJywgSU5GT10sXG4gICAgICAgICAgICBbJ1dBUk4nLCBXQVJOXSxcbiAgICAgICAgICAgIFsnRVJST1InLCBFUlJPUl0sXG4gICAgICAgICAgICBbJ0ZBVEFMJywgRkFUQUxdLFxuICAgICAgICAgICAgWydPRkYnLCBPRkZdLFxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGl0KGEgKyAnIHNob3VsZCByZXR1cm4gJyArIGIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBleHBlY3QobmV3IExvZ2dlcigpLmdldExldmVsKGEpKS50by5iZS5lcXVhbHMoYik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gICAgZGVzY3JpYmUoJ0xvZ2dlci5nZXRMYWJlbCgpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBbXG4gICAgICAgICAgICBbJ0FMTCcsIEFMTF0sXG4gICAgICAgICAgICBbJ1RSQUNFJywgVFJBQ0VdLFxuICAgICAgICAgICAgWydERUJVRycsIERFQlVHXSxcbiAgICAgICAgICAgIFsnSU5GTycsIElORk9dLFxuICAgICAgICAgICAgWydXQVJOJywgV0FSTl0sXG4gICAgICAgICAgICBbJ0VSUk9SJywgRVJST1JdLFxuICAgICAgICAgICAgWydGQVRBTCcsIEZBVEFMXSxcbiAgICAgICAgICAgIFsnT0ZGJywgT0ZGXSxcbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpdChhICsgJyBzaG91bGQgcmV0dXJuICcgKyBiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KG5ldyBMb2dnZXIoKS5nZXRMYWJlbChiKSkudG8uYmUuZXF1YWxzKGEpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xufSk7IiwgImltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiO1xuaW1wb3J0IHtBTEwsIFRSQUNFLCBERUJVRywgSU5GTywgV0FSTiwgRVJST1IsIEZBVEFMLCBPRkZ9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvbG9nZ2luZy9sb2dnZXIubWpzXCI7XG5pbXBvcnQge0hhbmRsZXJ9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvbG9nZ2luZy9oYW5kbGVyLm1qc1wiO1xuaW1wb3J0IHtMb2dFbnRyeX0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS9sb2dnaW5nL2xvZ2VudHJ5Lm1qc1wiO1xuXG5kZXNjcmliZSgnTG9nZ2luZycsIGZ1bmN0aW9uICgpIHtcblxuICAgIGRlc2NyaWJlKCdIYW5kbGVyLnNldExvZ0xldmVsKCkuZ2V0TG9nTGV2ZWwoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBbXG4gICAgICAgICAgICBbQUxMXSwgW1RSQUNFXSwgW0RFQlVHXSwgW0lORk9dLCBbV0FSTl0sIFtFUlJPUl0sIFtGQVRBTF0sIFtPRkZdLFxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ3RoZSBmdW5jdGlvbiBzaG91bGQgcmV0dXJuIHRoZSBzZXQgdmFsdWUgJyArIGEsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBleHBlY3QobmV3IEhhbmRsZXIoKS5zZXRMb2dMZXZlbChhKS5nZXRMb2dMZXZlbCgpKS50by5iZS5lcXVhbChhKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuXG4gICAgZGVzY3JpYmUoJ0hhbmRsZXIubG9nKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGluc3RhbmNlb2YgSGFuZGxlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgSGFuZGxlcigpLmxvZyhuZXcgTG9nRW50cnkoMCwgXCJ0ZXN0XCIpKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnSGFuZGxlci5sb2coKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBsZXQgaGFuZGxlcjtcblxuICAgICAgICBjbGFzcyBUZXN0SGFuZGxlciBleHRlbmRzIEhhbmRsZXIge1xuICAgICAgICAgICAgbG9nKGVudHJ5KSB7XG4gICAgICAgICAgICAgICAgc3VwZXIubG9nKGVudHJ5KTtcblxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgaGFuZGxlciA9IG5ldyBUZXN0SGFuZGxlcigpO1xuICAgICAgICB9KVxuXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGluc3RhbmNlb2YgSGFuZGxlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgSGFuZGxlcigpLmxvZyhuZXcgTG9nRW50cnkoMCwgXCJ0ZXN0XCIpKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgfSk7XG5cblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJy5sb2coKSB3aXRoIGxvZ2xldmVsJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGxldCBUZXN0SGFuZGxlcjtcblxuICAgICAgICBiZWZvcmUoKCkgPT4ge1xuICAgICAgICAgICAgVGVzdEhhbmRsZXIgPSBjbGFzcyBleHRlbmRzIEhhbmRsZXIge1xuICAgICAgICAgICAgICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICAgICAgICAgICAgICBzdXBlcigpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNhbGxzID0gMDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBsb2cobG9nbGV2ZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHN1cGVyLmxvZyhsb2dsZXZlbCkgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2FsbHMrK1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgWyAvLyBBTEwgPiBUUkFDRSA+IERFQlVHID4gSU5GTyA+IFdBUk4gPiBFUlJPUiA+IEZBVEFMID4gT0ZGICAoQUxMID0gMHhmZjtPRkYgPSAweDAwO1xuICAgICAgICAgICAgW0FMTCwgNl0sXG4gICAgICAgICAgICBbVFJBQ0UsIDZdLFxuICAgICAgICAgICAgW0RFQlVHLCA1XSxcbiAgICAgICAgICAgIFtJTkZPLCA0XSxcbiAgICAgICAgICAgIFtXQVJOLCAzXSxcbiAgICAgICAgICAgIFtFUlJPUiwgMl0sXG4gICAgICAgICAgICBbRkFUQUwsIDFdLFxuICAgICAgICAgICAgW09GRiwgMF1cbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpdCgnaXMubG9nKCcgKyBhICsgJykgc2hvdWxkIGxvZyAnICsgYiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGxldCBoYW5kbGVyID0gbmV3IFRlc3RIYW5kbGVyKCkuc2V0TG9nTGV2ZWwoYSk7XG4gICAgICAgICAgICAgICAgaGFuZGxlci5sb2cobmV3IExvZ0VudHJ5KFRSQUNFKSk7XG4gICAgICAgICAgICAgICAgaGFuZGxlci5sb2cobmV3IExvZ0VudHJ5KERFQlVHKSk7XG4gICAgICAgICAgICAgICAgaGFuZGxlci5sb2cobmV3IExvZ0VudHJ5KElORk8pKTtcbiAgICAgICAgICAgICAgICBoYW5kbGVyLmxvZyhuZXcgTG9nRW50cnkoV0FSTikpO1xuICAgICAgICAgICAgICAgIGhhbmRsZXIubG9nKG5ldyBMb2dFbnRyeShFUlJPUikpO1xuICAgICAgICAgICAgICAgIGhhbmRsZXIubG9nKG5ldyBMb2dFbnRyeShGQVRBTCkpO1xuXG4gICAgICAgICAgICAgICAgZXhwZWN0KGhhbmRsZXIuY2FsbHMpLmlzLmVxdWFsKGIpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnSGFuZGxlci5zZXRMb2dMZXZlbCgpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBpbnN0YW5jZW9mIEhhbmRsZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IEhhbmRsZXIoKS5zZXRMb2dMZXZlbChBTEwpKS50by5pbnN0YW5jZU9mKEhhbmRsZXIpO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdIYW5kbGVyLmdldExvZ0xldmVsKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCduZXcgbG9nZ2VyIHNob3VsZCBiZSAwJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KG5ldyBIYW5kbGVyKCkuZ2V0TG9nTGV2ZWwoKSkudG8uYmUuZXF1YWwoT0ZGKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnSGFuZGxlci5zZXRBbGwoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJyBzaG91bGQgaW5zdGFuY2VvZiBIYW5kbGVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KG5ldyBIYW5kbGVyKCkuc2V0QWxsKCkpLnRvLmluc3RhbmNlT2YoSGFuZGxlcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICAgIGRlc2NyaWJlKCdIYW5kbGVyLnNldFRyYWNlKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCduZXcgbG9nZ2VyIHNob3VsZCBpbnN0YW5jZW9mIEhhbmRsZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IEhhbmRsZXIoKS5zZXRUcmFjZSgpKS50by5pbnN0YW5jZU9mKEhhbmRsZXIpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgICBkZXNjcmliZSgnSGFuZGxlci5zZXREZWJ1ZygpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnIHNob3VsZCBpbnN0YW5jZW9mIEhhbmRsZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IEhhbmRsZXIoKS5zZXREZWJ1ZygpKS50by5pbnN0YW5jZU9mKEhhbmRsZXIpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgICBkZXNjcmliZSgnSGFuZGxlci5zZXRJbmZvKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGluc3RhbmNlb2YgSGFuZGxlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgSGFuZGxlcigpLnNldEluZm8oKSkudG8uaW5zdGFuY2VPZihIYW5kbGVyKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gICAgZGVzY3JpYmUoJ0hhbmRsZXIuc2V0V2FybigpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnIHNob3VsZCBpbnN0YW5jZW9mIEhhbmRsZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IEhhbmRsZXIoKS5zZXRXYXJuKCkpLnRvLmluc3RhbmNlT2YoSGFuZGxlcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICAgIGRlc2NyaWJlKCdIYW5kbGVyLnNldEVycm9yKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGluc3RhbmNlb2YgSGFuZGxlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgSGFuZGxlcigpLnNldEVycm9yKCkpLnRvLmluc3RhbmNlT2YoSGFuZGxlcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICAgIGRlc2NyaWJlKCdIYW5kbGVyLnNldEZhdGFsKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGluc3RhbmNlb2YgSGFuZGxlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgSGFuZGxlcigpLnNldEZhdGFsKCkpLnRvLmluc3RhbmNlT2YoSGFuZGxlcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICAgIGRlc2NyaWJlKCdIYW5kbGVyLnNldE9mZigpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBpbnN0YW5jZW9mIEhhbmRsZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IEhhbmRsZXIoKS5zZXRPZmYoKSkudG8uaW5zdGFuY2VPZihIYW5kbGVyKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG59KTsiLCAiaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7TG9nRW50cnl9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvbG9nZ2luZy9sb2dlbnRyeS5tanNcIjtcblxuXG5kZXNjcmliZSgnTG9nJywgZnVuY3Rpb24gKCkge1xuXG4gICAgZGVzY3JpYmUoJ25ldyBMb2cnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGluc3RhbmNlb2YgTG9nJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KG5ldyBMb2dFbnRyeSgxLCAnYScsICdiJywgJ2MnKSkudG8uaW5zdGFuY2VPZihMb2dFbnRyeSk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ0xvZy5sb2dsZXZlbCcsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBsZXQgbG9nO1xuXG4gICAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbG9nID0gbmV3IExvZ0VudHJ5KDEsIGZhbHNlLCAndGVzdCcsIDk5LCB7YTogdHJ1ZX0pO1xuICAgICAgICB9KVxuXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGxvZ2xldmVsIDEnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobG9nLmdldExvZ0xldmVsKCkpLnRvLmJlLmVxdWFsKDEpXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGFyZ3VtZW50cycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChsb2cuZ2V0QXJndW1lbnRzKCkpLnRvLmhhdmUuZGVlcC5tZW1iZXJzKFtmYWxzZSwgJ3Rlc3QnLCA5OSwge2E6IHRydWV9XSlcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbn0pOyIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGluc3RhbmNlU3ltYm9sIH0gZnJvbSBcIi4uL2NvbnN0YW50cy5tanNcIjtcbmltcG9ydCB7IGlzSW50ZWdlciwgaXNTdHJpbmcsIGlzT2JqZWN0IH0gZnJvbSBcIi4uL3R5cGVzL2lzLm1qc1wiO1xuaW1wb3J0IHsgQmFzZVdpdGhPcHRpb25zIH0gZnJvbSBcIi4uL3R5cGVzL2Jhc2V3aXRob3B0aW9ucy5tanNcIjtcbmltcG9ydCB7IE9ic2VydmFibGVRdWV1ZSB9IGZyb20gXCIuLi90eXBlcy9vYnNlcnZhYmxlcXVldWUubWpzXCI7XG5pbXBvcnQgeyBNZXNzYWdlIH0gZnJvbSBcIi4vd2ViY29ubmVjdC9tZXNzYWdlLm1qc1wiO1xuXG5leHBvcnQgeyBXZWJDb25uZWN0IH07XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEB0eXBlIHtTeW1ib2x9XG4gKi9cbmNvbnN0IHJlY2VpdmVRdWV1ZVN5bWJvbCA9IFN5bWJvbChcInJlY2VpdmVRdWV1ZVwiKTtcbi8qKlxuICogQHByaXZhdGVcbiAqIEB0eXBlIHtTeW1ib2x9XG4gKi9cbmNvbnN0IHNlbmRRdWV1ZVN5bWJvbCA9IFN5bWJvbChcInNlbmRRdWV1ZVwiKTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHR5cGUge1N5bWJvbH1cbiAqXG4gKiBoaW50OiB0aGlzIG5hbWUgaXMgdXNlZCBpbiB0aGUgdGVzdHMuIGlmIHlvdSB3YW50IHRvIGNoYW5nZSBpdCwgcGxlYXNlIGNoYW5nZSBpdCBpbiB0aGUgdGVzdHMgYXMgd2VsbC5cbiAqL1xuY29uc3QgY29ubmVjdGlvblN5bWJvbCA9IFN5bWJvbChcImNvbm5lY3Rpb25cIik7XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEB0eXBlIHtzeW1ib2x9XG4gKi9cbmNvbnN0IG1hbnVhbENsb3NlU3ltYm9sID0gU3ltYm9sKFwibWFudWFsQ2xvc2VcIik7XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEBzZWUgaHR0cHM6Ly93d3cucmZjLWVkaXRvci5vcmcvcmZjL3JmYzY0NTUuaHRtbCNzZWN0aW9uLTcuNC4xXG4gKiBAdHlwZSB7e1wiMTAwMFwiOiBzdHJpbmcsIFwiMTAxMVwiOiBzdHJpbmcsIFwiMTAxMFwiOiBzdHJpbmcsIFwiMTAwOFwiOiBzdHJpbmcsIFwiMTAwN1wiOiBzdHJpbmcsIFwiMTAwNlwiOiBzdHJpbmcsIFwiMTAwNVwiOiBzdHJpbmcsIFwiMTAwNFwiOiBzdHJpbmcsIFwiMTAxNVwiOiBzdHJpbmcsIFwiMTAwM1wiOiBzdHJpbmcsIFwiMTAwMlwiOiBzdHJpbmcsIFwiMTAwMVwiOiBzdHJpbmcsIFwiMTAwOVwiOiBzdHJpbmd9fVxuICovXG5jb25zdCBjb25uZWN0aW9uU3RhdHVzQ29kZSA9IHtcbiAgICAxMDAwOiBcIk5vcm1hbCBjbG9zdXJlXCIsXG4gICAgMTAwMTogXCJHb2luZyBhd2F5XCIsXG4gICAgMTAwMjogXCJQcm90b2NvbCBlcnJvclwiLFxuICAgIDEwMDM6IFwiVW5zdXBwb3J0ZWQgZGF0YVwiLFxuICAgIDEwMDQ6IFwiUmVzZXJ2ZWRcIixcbiAgICAxMDA1OiBcIk5vIHN0YXR1cyBjb2RlXCIsXG4gICAgMTAwNjogXCJDb25uZWN0aW9uIGNsb3NlZCBhYm5vcm1hbGx5XCIsXG4gICAgMTAwNzogXCJJbnZhbGlkIGZyYW1lIHBheWxvYWQgZGF0YVwiLFxuICAgIDEwMDg6IFwiUG9saWN5IHZpb2xhdGlvblwiLFxuICAgIDEwMDk6IFwiTWVzc2FnZSB0b28gYmlnXCIsXG4gICAgMTAxMDogXCJNYW5kYXRvcnkgZXh0ZW5zaW9uXCIsXG4gICAgMTAxMTogXCJJbnRlcm5hbCBzZXJ2ZXIgZXJyb3JcIixcbiAgICAxMDE1OiBcIlRMUyBoYW5kc2hha2VcIixcbn07XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEB0aGlzIHtXZWJDb25uZWN0fVxuICogQHRocm93cyB7RXJyb3J9IE5vIHVybCBkZWZpbmVkIGZvciB3ZWJzb2NrZXQgZGF0YXNvdXJjZS5cbiAqL1xuZnVuY3Rpb24gY29ubmVjdFNlcnZlcihyZXNvbHZlLCByZWplY3QpIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgIGNvbnN0IHVybCA9IHNlbGYuZ2V0T3B0aW9uKFwidXJsXCIpO1xuICAgIGlmICghdXJsKSB7XG4gICAgICAgIHJlamVjdChcIk5vIHVybCBkZWZpbmVkIGZvciB3ZWJjb25uZWN0LlwiKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxldCBwcm9taXNlQWxscmVkeVJlc29sdmVkID0gZmFsc2U7XG5cbiAgICBsZXQgY29ubmVjdGlvblRpbWVvdXQgPSBzZWxmLmdldE9wdGlvbihcImNvbm5lY3Rpb24udGltZW91dFwiKTtcbiAgICBpZiAoIWlzSW50ZWdlcihjb25uZWN0aW9uVGltZW91dCkgfHwgY29ubmVjdGlvblRpbWVvdXQgPCAxMDApIHtcbiAgICAgICAgY29ubmVjdGlvblRpbWVvdXQgPSA1MDAwO1xuICAgIH1cblxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBpZiAocHJvbWlzZUFsbHJlZHlSZXNvbHZlZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHJlamVjdChuZXcgRXJyb3IoXCJDb25uZWN0aW9uIHRpbWVvdXRcIikpO1xuICAgIH0sIGNvbm5lY3Rpb25UaW1lb3V0KTtcblxuICAgIGxldCByZWNvbm5lY3RUaW1lb3V0ID0gc2VsZi5nZXRPcHRpb24oXCJjb25uZWN0aW9uLnJlY29ubmVjdC50aW1lb3V0XCIpO1xuICAgIGlmICghaXNJbnRlZ2VyKHJlY29ubmVjdFRpbWVvdXQpIHx8IHJlY29ubmVjdFRpbWVvdXQgPCAxMDAwKSByZWNvbm5lY3RUaW1lb3V0ID0gMTAwMDtcbiAgICBsZXQgcmVjb25uZWN0QXR0ZW1wdHMgPSBzZWxmLmdldE9wdGlvbihcImNvbm5lY3Rpb24ucmVjb25uZWN0LmF0dGVtcHRzXCIpO1xuICAgIGlmICghaXNJbnRlZ2VyKHJlY29ubmVjdEF0dGVtcHRzKSB8fCByZWNvbm5lY3RBdHRlbXB0cyA8IDEpIHJlY29ubmVjdEF0dGVtcHRzID0gMTtcbiAgICBsZXQgcmVjb25uZWN0RW5hYmxlZCA9IHNlbGYuZ2V0T3B0aW9uKFwiY29ubmVjdGlvbi5yZWNvbm5lY3QuZW5hYmxlZFwiKTtcbiAgICBpZiAocmVjb25uZWN0RW5hYmxlZCAhPT0gdHJ1ZSkgcmVjb25uZWN0RW5hYmxlZCA9IGZhbHNlO1xuXG4gICAgc2VsZlttYW51YWxDbG9zZVN5bWJvbF0gPSBmYWxzZTtcbiAgICBzZWxmW2Nvbm5lY3Rpb25TeW1ib2xdLnJlY29ubmVjdENvdW50ZXIrKztcblxuICAgIGlmIChzZWxmW2Nvbm5lY3Rpb25TeW1ib2xdLnNvY2tldCAmJiBzZWxmW2Nvbm5lY3Rpb25TeW1ib2xdLnNvY2tldC5yZWFkeVN0YXRlIDwgMikge1xuICAgICAgICBzZWxmW2Nvbm5lY3Rpb25TeW1ib2xdLnNvY2tldC5jbG9zZSgpO1xuICAgIH1cbiAgICBzZWxmW2Nvbm5lY3Rpb25TeW1ib2xdLnNvY2tldCA9IG51bGw7XG4gICAgc2VsZltjb25uZWN0aW9uU3ltYm9sXS5zb2NrZXQgPSBuZXcgV2ViU29ja2V0KHVybCk7XG5cbiAgICBzZWxmW2Nvbm5lY3Rpb25TeW1ib2xdLnNvY2tldC5vbm1lc3NhZ2UgPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgaWYgKGV2ZW50LmRhdGEgaW5zdGFuY2VvZiBCbG9iKSB7XG4gICAgICAgICAgICBjb25zdCByZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpO1xuICAgICAgICAgICAgcmVhZGVyLmFkZEV2ZW50TGlzdGVuZXIoXCJsb2FkZW5kXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBzZWxmW3JlY2VpdmVRdWV1ZVN5bWJvbF0uYWRkKG5ldyBNZXNzYWdlKHJlYWRlci5yZXN1bHQpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmVhZGVyLnJlYWRBc1RleHQobmV3IE1lc3NhZ2UoZXZlbnQuZGF0YSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2VsZltyZWNlaXZlUXVldWVTeW1ib2xdLmFkZChNZXNzYWdlLmZyb21KU09OKGV2ZW50LmRhdGEpKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBzZWxmW2Nvbm5lY3Rpb25TeW1ib2xdLnNvY2tldC5vbm9wZW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNlbGZbY29ubmVjdGlvblN5bWJvbF0ucmVjb25uZWN0Q291bnRlciA9IDA7XG4gICAgICAgIGlmICh0eXBlb2YgcmVzb2x2ZSA9PT0gXCJmdW5jdGlvblwiICYmICFwcm9taXNlQWxscmVkeVJlc29sdmVkKSB7XG4gICAgICAgICAgICBwcm9taXNlQWxscmVkeVJlc29sdmVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBzZWxmW2Nvbm5lY3Rpb25TeW1ib2xdLnNvY2tldC5jbG9zZSA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICBpZiAoc2VsZlttYW51YWxDbG9zZVN5bWJvbF0pIHtcbiAgICAgICAgICAgIHNlbGZbbWFudWFsQ2xvc2VTeW1ib2xdID0gZmFsc2U7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocmVjb25uZWN0RW5hYmxlZCAmJiB0aGlzW2Nvbm5lY3Rpb25TeW1ib2xdLnJlY29ubmVjdENvdW50ZXIgPCByZWNvbm5lY3RBdHRlbXB0cykge1xuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgc2VsZi5jb25uZWN0KCk7XG4gICAgICAgICAgICB9LCByZWNvbm5lY3RUaW1lb3V0ICogdGhpc1tjb25uZWN0aW9uU3ltYm9sXS5yZWNvbm5lY3RDb3VudGVyKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBzZWxmW2Nvbm5lY3Rpb25TeW1ib2xdLnNvY2tldC5vbmVycm9yID0gKGVycm9yKSA9PiB7XG4gICAgICAgIGlmIChyZWNvbm5lY3RFbmFibGVkICYmIHNlbGZbY29ubmVjdGlvblN5bWJvbF0ucmVjb25uZWN0Q291bnRlciA8IHJlY29ubmVjdEF0dGVtcHRzKSB7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICBzZWxmLmNvbm5lY3QoKTtcbiAgICAgICAgICAgIH0sIHJlY29ubmVjdFRpbWVvdXQgKiB0aGlzW2Nvbm5lY3Rpb25TeW1ib2xdLnJlY29ubmVjdENvdW50ZXIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiByZWplY3QgPT09IFwiZnVuY3Rpb25cIiAmJiAhcHJvbWlzZUFsbHJlZHlSZXNvbHZlZCkge1xuICAgICAgICAgICAgICAgIHByb21pc2VBbGxyZWR5UmVzb2x2ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xufVxuXG4vKipcbiAqIFRoZSBSZXN0QVBJIGlzIGEgY2xhc3MgdGhhdCBlbmFibGVzIGEgUkVTVCBBUEkgc2VydmVyLlxuICpcbiAqIEBleHRlcm5hbEV4YW1wbGUgLi4vLi4vZXhhbXBsZS9uZXQvd2ViY29ubmVjdC5tanNcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDMuMS4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuTmV0XG4gKiBAc3VtbWFyeSBUaGUgTG9jYWxTdG9yYWdlIGNsYXNzIGVuY2Fwc3VsYXRlcyB0aGUgYWNjZXNzIHRvIGRhdGEgb2JqZWN0cy5cbiAqL1xuY2xhc3MgV2ViQ29ubmVjdCBleHRlbmRzIEJhc2VXaXRoT3B0aW9ucyB7XG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIG9wdGlvbnMgY29udGFpbnMgZGVmaW5pdGlvbnMgZm9yIHRoZSB3ZWJjb25uZWN0LlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgaWYgKGlzU3RyaW5nKG9wdGlvbnMpKSB7XG4gICAgICAgICAgICBvcHRpb25zID0geyB1cmw6IG9wdGlvbnMgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHN1cGVyKG9wdGlvbnMpO1xuXG4gICAgICAgIHRoaXNbcmVjZWl2ZVF1ZXVlU3ltYm9sXSA9IG5ldyBPYnNlcnZhYmxlUXVldWUoKTtcbiAgICAgICAgdGhpc1tzZW5kUXVldWVTeW1ib2xdID0gbmV3IE9ic2VydmFibGVRdWV1ZSgpO1xuXG4gICAgICAgIHRoaXNbY29ubmVjdGlvblN5bWJvbF0gPSB7fTtcbiAgICAgICAgdGhpc1tjb25uZWN0aW9uU3ltYm9sXS5zb2NrZXQgPSBudWxsO1xuICAgICAgICB0aGlzW2Nvbm5lY3Rpb25TeW1ib2xdLnJlY29ubmVjdENvdW50ZXIgPSAwO1xuICAgICAgICB0aGlzW21hbnVhbENsb3NlU3ltYm9sXSA9IGZhbHNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHJldHVybnMge1Byb21pc2V9XG4gICAgICovXG4gICAgY29ubmVjdCgpIHtcbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbm5lY3RTZXJ2ZXIuY2FsbCh0aGlzLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBpc0Nvbm5lY3RlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbY29ubmVjdGlvblN5bWJvbF0/LnNvY2tldD8ucmVhZHlTdGF0ZSA9PT0gMTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGBpbnN0YW5jZW9mYCBvcGVyYXRvci5cbiAgICAgKiBAcmV0dXJucyB7c3ltYm9sfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgW2luc3RhbmNlU3ltYm9sXSgpIHtcbiAgICAgICAgcmV0dXJuIFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL25ldC93ZWJjb25uZWN0XCIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB1cmw9dW5kZWZpbmVkIERlZmluZXMgdGhlIHJlc291cmNlIHRoYXQgeW91IHdpc2ggdG8gZmV0Y2guXG4gICAgICogQHByb3BlcnR5IHtPYmplY3R9IGNvbm5lY3Rpb25cbiAgICAgKiBAcHJvcGVydHkge09iamVjdH0gY29ubmVjdGlvbi50aW1lb3V0PTUwMDAgRGVmaW5lcyB0aGUgdGltZW91dCBmb3IgdGhlIGNvbm5lY3Rpb24uXG4gICAgICogQHByb3BlcnR5IHtOdW1iZXJ9IGNvbm5lY3Rpb24ucmVjb25uZWN0LnRpbWVvdXQgVGhlIHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzIGZvciB0aGUgcmVjb25uZWN0LlxuICAgICAqIEBwcm9wZXJ0eSB7TnVtYmVyfSBjb25uZWN0aW9uLnJlY29ubmVjdC5hdHRlbXB0cyBUaGUgbWF4aW11bSBudW1iZXIgb2YgcmVjb25uZWN0cy5cbiAgICAgKiBAcHJvcGVydHkge0Jvb2x9IGNvbm5lY3Rpb24ucmVjb25uZWN0LmVuYWJsZWQgSWYgdGhlIHJlY29ubmVjdCBpcyBlbmFibGVkLlxuICAgICAqL1xuICAgIGdldCBkZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN1cGVyLmRlZmF1bHRzLCB7XG4gICAgICAgICAgICB1cmw6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGNvbm5lY3Rpb246IHtcbiAgICAgICAgICAgICAgICB0aW1lb3V0OiA1MDAwLFxuICAgICAgICAgICAgICAgIHJlY29ubmVjdDoge1xuICAgICAgICAgICAgICAgICAgICB0aW1lb3V0OiAxMDAwLFxuICAgICAgICAgICAgICAgICAgICBhdHRlbXB0czogMSxcbiAgICAgICAgICAgICAgICAgICAgZW5hYmxlZDogZmFsc2UsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGNsb3NlcyB0aGUgY29ubmVjdGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBbY29kZT0xMDAwXSBUaGUgY2xvc2UgY29kZS5cbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gW3JlYXNvbj1cIlwiXSBUaGUgY2xvc2UgcmVhc29uLlxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlfVxuICAgICAqIEBzZWUgaHR0cHM6Ly93d3cucmZjLWVkaXRvci5vcmcvcmZjL3JmYzY0NTUuaHRtbCNzZWN0aW9uLTcuNC4xXG4gICAgICovXG4gICAgY2xvc2Uoc3RhdHVzQ29kZSwgcmVhc29uKSB7XG4gICAgICAgIGlmICghaXNJbnRlZ2VyKHN0YXR1c0NvZGUpIHx8IHN0YXR1c0NvZGUgPCAxMDAwIHx8IHN0YXR1c0NvZGUgPiA0OTk5KSB7XG4gICAgICAgICAgICBzdGF0dXNDb2RlID0gMTAwMDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlzU3RyaW5nKHJlYXNvbikpIHtcbiAgICAgICAgICAgIHJlYXNvbiA9IFwiXCI7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB0aGlzW21hbnVhbENsb3NlU3ltYm9sXSA9IHRydWU7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXNbY29ubmVjdGlvblN5bWJvbF0uc29ja2V0KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXNbY29ubmVjdGlvblN5bWJvbF0uc29ja2V0LmNsb3NlKHN0YXR1c0NvZGUsIHJlYXNvbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQb2xscyB0aGUgcmVjZWl2ZSBxdWV1ZSBmb3IgbmV3IG1lc3NhZ2VzLlxuICAgICAqXG4gICAgICogQHJldHVybnMge01lc3NhZ2V9XG4gICAgICovXG4gICAgcG9sbCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbcmVjZWl2ZVF1ZXVlU3ltYm9sXS5wb2xsKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQXJlIHRoZXJlIGFueSBtZXNzYWdlcyBpbiB0aGUgcmVjZWl2ZSBxdWV1ZT9cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgICAqL1xuICAgIGRhdGFSZWNlaXZlZCgpIHtcbiAgICAgICAgcmV0dXJuICF0aGlzW3JlY2VpdmVRdWV1ZVN5bWJvbF0uaXNFbXB0eSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCBNZXNzYWdlIGZyb20gdGhlIHJlY2VpdmUgcXVldWUsIGJ1dCBkbyBub3QgcmVtb3ZlIGl0LlxuICAgICAqXG4gICAgICogQHJldHVybnMge09iamVjdH1cbiAgICAgKi9cbiAgICBwZWVrKCkge1xuICAgICAgICByZXR1cm4gdGhpc1tyZWNlaXZlUXVldWVTeW1ib2xdLnBlZWsoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBdHRhY2ggYSBuZXcgb2JzZXJ2ZXJcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7T2JzZXJ2ZXJ9IG9ic2VydmVyXG4gICAgICogQHJldHVybnMge1Byb3h5T2JzZXJ2ZXJ9XG4gICAgICovXG4gICAgYXR0YWNoT2JzZXJ2ZXIob2JzZXJ2ZXIpIHtcbiAgICAgICAgdGhpc1tyZWNlaXZlUXVldWVTeW1ib2xdLmF0dGFjaE9ic2VydmVyKG9ic2VydmVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGV0YWNoIGEgb2JzZXJ2ZXJcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7T2JzZXJ2ZXJ9IG9ic2VydmVyXG4gICAgICogQHJldHVybnMge1Byb3h5T2JzZXJ2ZXJ9XG4gICAgICovXG4gICAgZGV0YWNoT2JzZXJ2ZXIob2JzZXJ2ZXIpIHtcbiAgICAgICAgdGhpc1tyZWNlaXZlUXVldWVTeW1ib2xdLmRldGFjaE9ic2VydmVyKG9ic2VydmVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtPYnNlcnZlcn0gb2JzZXJ2ZXJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBjb250YWluc09ic2VydmVyKG9ic2VydmVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzW3JlY2VpdmVRdWV1ZVN5bWJvbF0uY29udGFpbnNPYnNlcnZlcihvYnNlcnZlcik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtNZXNzYWdlfE9iamVjdH0gbWVzc2FnZVxuICAgICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAgICovXG4gICAgc2VuZChtZXNzYWdlKSB7XG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAoc2VsZltjb25uZWN0aW9uU3ltYm9sXS5zb2NrZXQucmVhZHlTdGF0ZSAhPT0gMSkge1xuICAgICAgICAgICAgICAgIHJlamVjdChcInRoZSBzb2NrZXQgaXMgbm90IHJlYWR5XCIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBzZWxmW2Nvbm5lY3Rpb25TeW1ib2xdLnNvY2tldC5zZW5kKEpTT04uc3RyaW5naWZ5KG1lc3NhZ2UpKTtcbiAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgfSk7XG4gICAgfVxufVxuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgUXVldWUgfSBmcm9tIFwiLi9xdWV1ZS5tanNcIjtcbmltcG9ydCB7IGluc3RhbmNlU3ltYm9sLCBpbnRlcm5hbFN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQgeyBPYnNlcnZlckxpc3QgfSBmcm9tIFwiLi9vYnNlcnZlcmxpc3QubWpzXCI7XG5cbmV4cG9ydCB7IE9ic2VydmFibGVRdWV1ZSB9O1xuXG4vKipcbiAqIEFuIG9ic2VydmFibGUgcXVldWUgaXMgYSBsaXN0IG9mIGl0ZW1zIHRoYXQgYXJlIHByb2Nlc3NlZCBvbmUgYWZ0ZXIgYW5vdGhlciAoZmlyc3QgaW4sIGZpcnN0IG91dCkuXG4gKlxuICogYFF1ZXVlLmFkZCgpYCBhbmQgYFF1ZXVlLmNsZWFyKClgIG5vdGlmeSBhbGwgb2JzZXJ2ZXJzLlxuICpcbiAqIEBleHRlcm5hbEV4YW1wbGUgLi4vLi4vZXhhbXBsZS90eXBlcy9xdWV1ZS5tanNcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDMuMy4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcbiAqIEBzdW1tYXJ5IEFuIG9ic2VydmFibGUgUXVldWUgKEZpZm8pXG4gKi9cbmNsYXNzIE9ic2VydmFibGVRdWV1ZSBleHRlbmRzIFF1ZXVlIHtcbiAgICAvKipcbiAgICAgKlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzW2ludGVybmFsU3ltYm9sXSA9IHtcbiAgICAgICAgICAgIG9ic2VydmVyczogbmV3IE9ic2VydmVyTGlzdCgpLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgYGluc3RhbmNlb2ZgIG9wZXJhdG9yLlxuICAgICAqIEByZXR1cm5zIHtzeW1ib2x9XG4gICAgICogQHNpbmNlIDIuMS4wXG4gICAgICovXG4gICAgc3RhdGljIGdldCBbaW5zdGFuY2VTeW1ib2xdKCkge1xuICAgICAgICByZXR1cm4gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvdHlwZXMvb2JzZXJ2YWJsZXF1ZXVlXCIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZCBhIG5ldyBlbGVtZW50IHRvIHRoZSBlbmQgb2YgdGhlIHF1ZXVlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZVxuICAgICAqIEByZXR1cm5zIHtRdWV1ZX1cbiAgICAgKi9cbiAgICBhZGQodmFsdWUpIHtcbiAgICAgICAgc3VwZXIuYWRkKHZhbHVlKTtcbiAgICAgICAgdGhpcy5ub3RpZnlPYnNlcnZlcnMoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogcmVtb3ZlIGFsbCBlbnRyaWVzXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7UXVldWV9XG4gICAgICovXG4gICAgY2xlYXIoKSB7XG4gICAgICAgIHN1cGVyLmNsZWFyKCk7XG4gICAgICAgIHRoaXMubm90aWZ5T2JzZXJ2ZXJzKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEF0dGFjaCBhIG5ldyBvYnNlcnZlclxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYnNlcnZlcn0gb2JzZXJ2ZXJcbiAgICAgKiBAcmV0dXJucyB7UHJveHlPYnNlcnZlcn1cbiAgICAgKi9cbiAgICBhdHRhY2hPYnNlcnZlcihvYnNlcnZlcikge1xuICAgICAgICB0aGlzW2ludGVybmFsU3ltYm9sXS5vYnNlcnZlcnMuYXR0YWNoKG9ic2VydmVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGV0YWNoIGEgb2JzZXJ2ZXJcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7T2JzZXJ2ZXJ9IG9ic2VydmVyXG4gICAgICogQHJldHVybnMge1Byb3h5T2JzZXJ2ZXJ9XG4gICAgICovXG4gICAgZGV0YWNoT2JzZXJ2ZXIob2JzZXJ2ZXIpIHtcbiAgICAgICAgdGhpc1tpbnRlcm5hbFN5bWJvbF0ub2JzZXJ2ZXJzLmRldGFjaChvYnNlcnZlcik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE5vdGlmeSBhbGwgb2JzZXJ2ZXJcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlfVxuICAgICAqL1xuICAgIG5vdGlmeU9ic2VydmVycygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbaW50ZXJuYWxTeW1ib2xdLm9ic2VydmVycy5ub3RpZnkodGhpcyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtPYnNlcnZlcn0gb2JzZXJ2ZXJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBjb250YWluc09ic2VydmVyKG9ic2VydmVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzW2ludGVybmFsU3ltYm9sXS5vYnNlcnZlcnMuY29udGFpbnMob2JzZXJ2ZXIpO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IEJhc2UgfSBmcm9tIFwiLi4vLi4vdHlwZXMvYmFzZS5tanNcIjtcbmltcG9ydCB7IHZhbGlkYXRlT2JqZWN0LCB2YWxpZGF0ZVN0cmluZyB9IGZyb20gXCIuLi8uLi90eXBlcy92YWxpZGF0ZS5tanNcIjtcblxuZXhwb3J0IHsgTWVzc2FnZSB9O1xuXG5jb25zdCBkYXRhU3ltYm9sID0gU3ltYm9sKFwiQEBkYXRhXCIpO1xuXG4vKipcbiAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhIFdlYlNvY2tldCBtZXNzYWdlLlxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDMuNC4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuTmV0LldlYlNvY2tldFxuICogQHN1bW1hcnkgVGhlIE1lc3NhZ2UgY2xhc3MgZW5jYXBzdWxhdGVzIGEgV2ViU29ja2V0IG1lc3NhZ2UuXG4gKi9cbmNsYXNzIE1lc3NhZ2UgZXh0ZW5kcyBCYXNlIHtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gZGF0YVxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgb2JqZWN0XG4gICAgICovXG4gICAgY29uc3RydWN0b3IoZGF0YSkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzW2RhdGFTeW1ib2xdID0gdmFsaWRhdGVPYmplY3QoZGF0YSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgcmF3IG1lc3NhZ2UuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7b2JqZWN0fVxuICAgICAqL1xuICAgIGdldERhdGEoKSB7XG4gICAgICAgIHJldHVybiB0aGlzW2RhdGFTeW1ib2xdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIHsqfVxuICAgICAqL1xuICAgIHRvSlNPTigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbZGF0YVN5bWJvbF07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGpzb25cbiAgICAgKiBAcmV0dXJucyB7TWVzc2FnZX1cbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIHN0cmluZ1xuICAgICAqL1xuICAgIHN0YXRpYyBmcm9tSlNPTihqc29uKSB7XG4gICAgICAgIHZhbGlkYXRlU3RyaW5nKGpzb24pO1xuICAgICAgICByZXR1cm4gbmV3IE1lc3NhZ2UoSlNPTi5wYXJzZShqc29uKSk7XG4gICAgfVxufVxuIiwgImltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge1dlYkNvbm5lY3R9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvbmV0L3dlYmNvbm5lY3QubWpzXCI7XG5pbXBvcnQge01lc3NhZ2V9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvbmV0L3dlYmNvbm5lY3QvbWVzc2FnZS5tanNcIjtcbmltcG9ydCB7T2JzZXJ2ZXJ9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvdHlwZXMvb2JzZXJ2ZXIubWpzXCI7XG5pbXBvcnQge2luaXRXZWJTb2NrZXR9IGZyb20gXCIuLi8uLi91dGlsL3dlYnNvY2tldC5tanNcIjtcblxuY29uc3QgdGVzdFVybCA9IFwid3NzOi8vd3MucG9zdG1hbi1lY2hvLmNvbS9yYXdcIlxuXG5kZXNjcmliZSgnV2Vic29ja2V0JywgZnVuY3Rpb24gKCkge1xuXG4gICAgbGV0IGRzID0gdW5kZWZpbmVkXG5cbiAgICBiZWZvcmUoZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgaW5pdFdlYlNvY2tldCgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgZG9uZSgpXG4gICAgICAgIH0pLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICBkb25lKGUpXG4gICAgICAgIH0pXG4gICAgfSk7XG5cbiAgICBhZnRlckVhY2goZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgaWYgKGRzKSB7XG4gICAgICAgICAgICBkcy5jbG9zZSgpXG4gICAgICAgIH1cblxuICAgICAgICAvLyB3aXRob3V0IHRoaXMsIHRoZSBub2RlIHRlc3Qgd2lsbCBoYW5nIFxuICAgICAgICBmb3IgKGNvbnN0IHN5bSBvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKGRzKSkge1xuICAgICAgICAgICAgaWYgKHN5bS50b1N0cmluZygpID09PSAnU3ltYm9sKGNvbm5lY3Rpb24pJykge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgZHNbc3ltXT8uc29ja2V0Py50ZXJtaW5hdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgZHNbc3ltXT8uc29ja2V0Py5bJ3Rlcm1pbmF0ZSddKClcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBkb25lKClcbiAgICB9KTtcblxuXG4gICAgaXQoJ3Nob3VsZCB0cmFuc2Zvcm0gZGF0YScsIGZ1bmN0aW9uIChkb25lKSB7XG5cbiAgICAgICAgZHMgPSBuZXcgV2ViQ29ubmVjdCgge1xuICAgICAgICAgICAgdXJsOiB0ZXN0VXJsLFxuICAgICAgICB9KVxuXG4gICAgICAgIGRzLmNvbm5lY3QoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgZHMuYXR0YWNoT2JzZXJ2ZXIobmV3IE9ic2VydmVyKCgpPT4ge1xuICAgICAgICAgICAgICAgZG9uZSgpXG4gICAgICAgICAgICB9KSlcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgZHMuc2VuZCh7XG4gICAgICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBcIkhlbGxvIFdvcmxkXCJcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuXG4gICAgICAgIH0pLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICBkb25lKGUpXG4gICAgICAgIH0pXG5cblxuICAgIH0pXG5cbiAgICBpdCgnc2hvdWxkIGNvbm5lY3QnLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICBkcyA9IG5ldyBXZWJDb25uZWN0KHtcbiAgICAgICAgICAgIHVybDogdGVzdFVybCxcbiAgICAgICAgICAgIHJlY29ubmVjdDoge1xuICAgICAgICAgICAgICAgIGVuYWJsZWQ6IGZhbHNlXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBkcy5jb25uZWN0KCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICBkb25lKClcbiAgICAgICAgfSkuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIGRvbmUoZSlcbiAgICAgICAgfSlcblxuXG4gICAgfSlcblxuICAgIGl0KCdzaG91bGQgc2VuZCBtZXNzYWdlJywgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgZHMgPSBuZXcgV2ViQ29ubmVjdCh7XG4gICAgICAgICAgICB1cmw6IHRlc3RVcmwsXG4gICAgICAgICAgICByZWNvbm5lY3Q6IHtcbiAgICAgICAgICAgICAgICBlbmFibGVkOiBmYWxzZVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgZHMuY29ubmVjdCgpLnRoZW4oKCkgPT4ge1xuXG4gICAgICAgICAgICBkcy5hdHRhY2hPYnNlcnZlcihuZXcgT2JzZXJ2ZXIoKCk9PiB7XG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgZXhwZWN0KGRzLmRhdGFSZWNlaXZlZCgpKS50by5iZS50cnVlXG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbXNnID0gZHMucG9sbCgpXG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChtc2cpLnRvLmJlLmluc3RhbmNlT2YoTWVzc2FnZSlcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZGF0YSA9IG1zZy5nZXREYXRhKClcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KGRhdGEpLnRvLmJlLmRlZXAuZXF1YWwoe21lc3NhZ2U6IFwiSGVsbG8gV29ybGRcIn0pXG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICBkb25lKGUpXG4gICAgICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkb25lKClcbiAgICAgICAgICAgIH0pKVxuXG4gICAgICAgICAgICBkcy5zZW5kKHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogXCJIZWxsbyBXb3JsZFwiXG4gICAgICAgICAgICB9KVxuXG4gICAgICAgIH0pLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICBkb25lKGUpXG4gICAgICAgIH0pXG5cblxuICAgIH0pLnRpbWVvdXQoMTAwMDApO1xuXG59KTtcbiIsICJpbXBvcnQge2dldEdsb2JhbH0gZnJvbSBcIi4uLy4uL3NvdXJjZS90eXBlcy9nbG9iYWwubWpzXCI7XG5cbmZ1bmN0aW9uIGluaXRXZWJTb2NrZXQoKSB7XG4gICAgaWYgKHR5cGVvZiB3aW5kb3cgPT09IFwib2JqZWN0XCIgJiYgd2luZG93WydXZWJTb2NrZXQnXSkgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuXG4gICAgcmV0dXJuIGltcG9ydChcIndzXCIpLnRoZW4oKHdzKSA9PiB7XG4gICAgICAgIGdldEdsb2JhbCgpLldlYlNvY2tldCA9IGNsYXNzIGV4dGVuZHMgd3NbJ1dlYlNvY2tldCddIHtcbiAgICAgICAgICAgIGNvbnN0cnVjdG9yKHVybCwgcHJvdG9jb2xzKSB7XG4gICAgICAgICAgICAgICAgc3VwZXIodXJsLCBwcm90b2NvbHMsIHtcbiAgICAgICAgICAgICAgICAgICAgaGFuZHNoYWtlVGltZW91dDogMTAwMCxcbiAgICAgICAgICAgICAgICAgICAgbWF4UGF5bG9hZDogMTAyNCAqIDEwMjQgKiAxMDI0LFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBcbiAgICB9KTtcblxuXG59XG5cbmV4cG9ydCB7aW5pdFdlYlNvY2tldH0iLCAiaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7TWVzc2FnZX0gZnJvbSBcIi4uLy4uLy4uLy4uL3NvdXJjZS9uZXQvd2ViY29ubmVjdC9tZXNzYWdlLm1qc1wiO1xuXG5kZXNjcmliZSgnTWVzc2FnZScsIGZ1bmN0aW9uICgpIHtcblxuICAgIGl0KCdjb25zdHJ1Y3Qgd2l0aG91dGggcGFyYW1ldGVycyBzaG91bGQgdGhyb3cnLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICBcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIG5ldyBNZXNzYWdlKCk7XG4gICAgICAgICAgICBkb25lKG5ldyBFcnJvcignc2hvdWxkIHRocm93JykpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgIH0pXG4gICAgXG4gICAgaXQoJ2Zyb20ganNvbiBzaG91bGQgJyAsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgIGNvbnN0IGpzb24gPSB7XG4gICAgICAgICAgICBcImlkXCI6IFwiMTIzXCIsXG4gICAgICAgICAgICBcInR5cGVcIjogXCJ0ZXN0XCIsXG4gICAgICAgICAgICBcImRhdGFcIjoge1xuICAgICAgICAgICAgICAgIFwidGVzdFwiOiBcInRlc3RcIlxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG1lc3NhZ2UgPSBNZXNzYWdlLmZyb21KU09OKEpTT04uc3RyaW5naWZ5KGpzb24pKTtcbiAgICAgICAgY29uc3QgZGF0YSA9IG1lc3NhZ2UuZ2V0RGF0YSgpO1xuICAgICAgICBleHBlY3QoZGF0YS5pZCkudG8uZXF1YWwoanNvbi5pZCk7XG4gICAgICAgIGV4cGVjdChkYXRhLnR5cGUpLnRvLmVxdWFsKGpzb24udHlwZSk7XG4gICAgICAgIGV4cGVjdChkYXRhLmRhdGEpLnRvLmRlZXAuZXF1YWwoanNvbi5kYXRhKTtcbiAgICAgICAgZG9uZSgpO1xuICAgIH0pXG4gICAgXG4gICAgaXQgKFwidG8ganNvbiBzaG91bGRcIiwgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgY29uc3Qgb2JqID0ge1xuICAgICAgICAgICAgXCJpZFwiOiBcIjEyM1wiLFxuICAgICAgICAgICAgXCJ0eXBlXCI6IFwidGVzdFwiLFxuICAgICAgICAgICAgXCJkYXRhXCI6IHtcbiAgICAgICAgICAgICAgICBcInRlc3RcIjogXCJ0ZXN0XCJcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBtZXNzYWdlID0gbmV3IE1lc3NhZ2Uob2JqKTtcbiAgICAgICAgY29uc3QgZGF0YSA9IEpTT04uc3RyaW5naWZ5KG1lc3NhZ2UpO1xuICAgICAgICBleHBlY3QoZGF0YSkudG8uZXF1YWwoJ3tcImlkXCI6XCIxMjNcIixcInR5cGVcIjpcInRlc3RcIixcImRhdGFcIjp7XCJ0ZXN0XCI6XCJ0ZXN0XCJ9fScpO1xuICAgICAgICBkb25lKCk7XG4gICAgfSlcblxuXG5cbn0pO1xuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgQmFzZSB9IGZyb20gXCIuL2Jhc2UubWpzXCI7XG5pbXBvcnQgeyBpbnN0YW5jZVN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5cbmV4cG9ydCB7IFZlcnNpb24sIGdldE1vbnN0ZXJWZXJzaW9uIH07XG5cbi8qKlxuICogVGhlIHZlcnNpb24gb2JqZWN0IGNvbnRhaW5zIGEgc2VtYW50aWMgdmVyc2lvbiBudW1iZXJcbiAqXG4gKiBAZXh0ZXJuYWxFeGFtcGxlIC4uLy4uL2V4YW1wbGUvdHlwZXMvdmVyc2lvbi0xLm1qc1xuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4wLjBcbiAqIEBhdXRob3Igc2NodWthaSBHbWJIXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcbiAqIEBzdW1tYXJ5IFRoZSB2ZXJzaW9uIG9iamVjdCBjb250YWlucyBhIHNlbWF0aWMgdmVyc2lvbiBudW1iZXJcbiAqL1xuY2xhc3MgVmVyc2lvbiBleHRlbmRzIEJhc2Uge1xuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIG1ham9yXG4gICAgICogQHBhcmFtIG1pbm9yXG4gICAgICogQHBhcmFtIHBhdGNoXG4gICAgICogQHRocm93cyB7RXJyb3J9IG1ham9yIGlzIG5vdCBhIG51bWJlclxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBtaW5vciBpcyBub3QgYSBudW1iZXJcbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gcGF0Y2ggaXMgbm90IGEgbnVtYmVyXG4gICAgICovXG4gICAgY29uc3RydWN0b3IobWFqb3IsIG1pbm9yLCBwYXRjaCkge1xuICAgICAgICBzdXBlcigpO1xuXG4gICAgICAgIGlmICh0eXBlb2YgbWFqb3IgPT09IFwic3RyaW5nXCIgJiYgbWlub3IgPT09IHVuZGVmaW5lZCAmJiBwYXRjaCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBsZXQgcGFydHMgPSBtYWpvci50b1N0cmluZygpLnNwbGl0KFwiLlwiKTtcbiAgICAgICAgICAgIG1ham9yID0gcGFyc2VJbnQocGFydHNbMF0gfHwgMCk7XG4gICAgICAgICAgICBtaW5vciA9IHBhcnNlSW50KHBhcnRzWzFdIHx8IDApO1xuICAgICAgICAgICAgcGF0Y2ggPSBwYXJzZUludChwYXJ0c1syXSB8fCAwKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChtYWpvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJtYWpvciB2ZXJzaW9uIGlzIHVuZGVmaW5lZFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChtaW5vciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBtaW5vciA9IDA7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocGF0Y2ggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcGF0Y2ggPSAwO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5tYWpvciA9IHBhcnNlSW50KG1ham9yKTtcbiAgICAgICAgdGhpcy5taW5vciA9IHBhcnNlSW50KG1pbm9yKTtcbiAgICAgICAgdGhpcy5wYXRjaCA9IHBhcnNlSW50KHBhdGNoKTtcblxuICAgICAgICBpZiAoaXNOYU4odGhpcy5tYWpvcikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIm1ham9yIGlzIG5vdCBhIG51bWJlclwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc05hTih0aGlzLm1pbm9yKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwibWlub3IgaXMgbm90IGEgbnVtYmVyXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzTmFOKHRoaXMucGF0Y2gpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJwYXRjaCBpcyBub3QgYSBudW1iZXJcIik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGBpbnN0YW5jZW9mYCBvcGVyYXRvci5cbiAgICAgKiBAcmV0dXJucyB7c3ltYm9sfVxuICAgICAqIEBzaW5jZSAyLjEuMFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgW2luc3RhbmNlU3ltYm9sXSgpIHtcbiAgICAgICAgcmV0dXJuIFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL3R5cGVzL3ZlcnNpb25cIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgICAqL1xuICAgIHRvU3RyaW5nKCkge1xuICAgICAgICByZXR1cm4gYCR7dGhpcy5tYWpvcn0uJHt0aGlzLm1pbm9yfS4ke3RoaXMucGF0Y2h9YDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiByZXR1cm5zIDAgaWYgZXF1YWwsIC0xIGlmIHRoZSBvYmplY3QgdmVyc2lvbiBpcyBsZXNzIGFuZCAxIGlmIGdyZWF0ZXJcbiAgICAgKiB0aGFuIHRoZSBjb21wYXJlZCB2ZXJzaW9uXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xWZXJzaW9ufSB2ZXJzaW9uIFZlcnNpb24gdG8gY29tcGFyZVxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9XG4gICAgICovXG4gICAgY29tcGFyZVRvKHZlcnNpb24pIHtcbiAgICAgICAgaWYgKHZlcnNpb24gaW5zdGFuY2VvZiBWZXJzaW9uKSB7XG4gICAgICAgICAgICB2ZXJzaW9uID0gdmVyc2lvbi50b1N0cmluZygpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiB2ZXJzaW9uICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0eXBlIGV4Y2VwdGlvblwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh2ZXJzaW9uID09PSB0aGlzLnRvU3RyaW5nKCkpIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGEgPSBbdGhpcy5tYWpvciwgdGhpcy5taW5vciwgdGhpcy5wYXRjaF07XG4gICAgICAgIGxldCBiID0gdmVyc2lvbi5zcGxpdChcIi5cIik7XG4gICAgICAgIGxldCBsZW4gPSBNYXRoLm1heChhLmxlbmd0aCwgYi5sZW5ndGgpO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGlmICgoYVtpXSAmJiAhYltpXSAmJiBwYXJzZUludChhW2ldKSA+IDApIHx8IHBhcnNlSW50KGFbaV0pID4gcGFyc2VJbnQoYltpXSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoKGJbaV0gJiYgIWFbaV0gJiYgcGFyc2VJbnQoYltpXSkgPiAwKSB8fCBwYXJzZUludChhW2ldKSA8IHBhcnNlSW50KGJbaV0pKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxufVxuXG5sZXQgbW9uc3RlclZlcnNpb247XG5cbi8qKlxuICogVmVyc2lvbiBvZiBtb25zdGVyXG4gKlxuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL3R5cGVzL3ZlcnNpb24tMi5tanNcbiAqIEByZXR1cm5zIHtNb25zdGVyLlR5cGVzLlZlcnNpb259XG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjAuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBhdXRob3Igc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3RlclxuICovXG5mdW5jdGlvbiBnZXRNb25zdGVyVmVyc2lvbigpIHtcbiAgICBpZiAobW9uc3RlclZlcnNpb24gaW5zdGFuY2VvZiBWZXJzaW9uKSB7XG4gICAgICAgIHJldHVybiBtb25zdGVyVmVyc2lvbjtcbiAgICB9XG5cbiAgICAvKiogZG9uJ3QgdG91Y2gsIHJlcGxhY2VkIGJ5IG1ha2Ugd2l0aCBwYWNrYWdlLmpzb24gdmVyc2lvbiAqL1xuICAgIG1vbnN0ZXJWZXJzaW9uID0gbmV3IFZlcnNpb24oXCIzLjUxLjRcIik7XG5cbiAgICByZXR1cm4gbW9uc3RlclZlcnNpb247XG59XG4iLCAiaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7VmVyc2lvbiwgZ2V0TW9uc3RlclZlcnNpb259IGZyb20gXCIuLi8uLi9zb3VyY2UvdHlwZXMvdmVyc2lvbi5tanNcIjtcblxuZGVzY3JpYmUoJ01vbnN0ZXInLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBkZXNjcmliZSgnLmdldE1vbnN0ZXJWZXJzaW9uKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCBtb25zdGVyVmVyc2lvblxuXG4gICAgICAgIC8qKiBkb25cdTAwQjR0IHRvdWNoLCByZXBsYWNlZCBieSBtYWtlIHdpdGggcGFja2FnZS5qc29uIHZlcnNpb24gKi9cbiAgICAgICAgbW9uc3RlclZlcnNpb24gPSBuZXcgVmVyc2lvbihcIjMuNTEuNFwiKVxuXG4gICAgICAgIGxldCBtID0gZ2V0TW9uc3RlclZlcnNpb24oKTtcblxuICAgICAgICBpdCgnc2hvdWxkICcgKyBtb25zdGVyVmVyc2lvbiArICcgaXMgJyArIG0sIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChtLmNvbXBhcmVUbyhtb25zdGVyVmVyc2lvbikpLmlzLmVxdWFsKDApO1xuICAgICAgICB9KTtcblxuICAgIH0pO1xuXG59KTtcbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGdldFdpbmRvdyB9IGZyb20gXCIuL3V0aWwubWpzXCI7XG5pbXBvcnQgeyB2YWxpZGF0ZVN0cmluZyB9IGZyb20gXCIuLi90eXBlcy92YWxpZGF0ZS5tanNcIjtcblxuZXhwb3J0IHsgY29udmVydFRvUGl4ZWxzLCBnZXREZXZpY2VEUEkgfTtcblxuLyoqXG4gKiBTdG9yZXMgdGhlIERQSSBvZiB0aGUgZGV2aWNlLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcmV0dXJucyB7bnVtYmVyfVxuICogQHNpbmNlIDMuMzQuMFxuICogQHR5cGUge251bWJlcnxmdW5jdGlvbn1cbiAqL1xubGV0IENVUlJFTlRfREVWSUNFX0RQSSA9IGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgaSA9IDA7XG4gICAgZm9yIChpID0gNTY7IGkgPCAyMDAwOyBpKyspIHtcbiAgICAgICAgaWYgKGdldFdpbmRvdygpLm1hdGNoTWVkaWEoYChtYXgtcmVzb2x1dGlvbjogJHtpfWRwaSlgKS5tYXRjaGVzID09PSB0cnVlKSB7XG4gICAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gaTtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgRFBJIG9mIHRoZSBkZXZpY2UuXG4gKlxuICogQHNpbmNlIDMuMzQuMFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAcmV0dXJucyB7bnVtYmVyfVxuICovXG5mdW5jdGlvbiBnZXREZXZpY2VEUEkoKSB7XG4gICAgLy8gb25seSBjYWxsIHRoZSBmdW5jdGlvbiBvbmNlXG4gICAgaWYgKHR5cGVvZiBDVVJSRU5UX0RFVklDRV9EUEkgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICBDVVJSRU5UX0RFVklDRV9EUEkgPSBDVVJSRU5UX0RFVklDRV9EUEkoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZ2V0V2luZG93KCkuZGV2aWNlUGl4ZWxSYXRpbyAqIENVUlJFTlRfREVWSUNFX0RQSTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIENTUyB2YWx1ZSB0byBwaXhlbHMuXG4gKlxuICogQXMgRXhhbXBsZTpcbiAqXG4gKiBgYGBqc1xuICogY29udmVydFRvUGl4ZWxzKCcxZW0nKSAvLyByZXR1cm5zIHRoZSBjdXJyZW50IGZvbnQgc2l6ZSBpbiBwaXhlbHNcbiAqIGNvbnZlcnRUb1BpeGVscygnMXJlbScpIC8vIHJldHVybnMgdGhlIGN1cnJlbnQgcm9vdCBmb250IHNpemUgaW4gcGl4ZWxzXG4gKiBjb252ZXJ0VG9QaXhlbHMoJzFweCcpIC8vIHJldHVybnMgMVxuICogY29udmVydFRvUGl4ZWxzKCcxMDAlJykgLy8gcmV0dXJucyB0aGUgY3VycmVudCB3aWR0aCBvZiB0aGUgcGFyZW50IGVsZW1lbnQgaW4gcGl4ZWxzXG4gKiBgYGBcbiAqXG4gKiBGb2xsb3dpbmcgdW5pdHMgYXJlIHN1cHBvcnRlZDpcbiAqIC0gcHhcbiAqIC0gZW1cbiAqIC0gcmVtXG4gKiAtICVcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdmFsdWVcbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IFtwYXJlbnRFbGVtZW50PWRvY3VtZW50LmRvY3VtZW50RWxlbWVudF1cbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IFtmb250U2l6ZUVsZW1lbnQ9ZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50XVxuICogQHJldHVybnMge251bWJlcn1cbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDMuMzQuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEB0aHJvd3Mge0Vycm9yfSBVbnN1cHBvcnRlZCB1bml0XG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEB0aHJvd3Mge0Vycm9yfSBJbnZhbGlkIHZhbHVlIGZvcm1hdFxuICovXG5cbmZ1bmN0aW9uIGNvbnZlcnRUb1BpeGVscyh2YWx1ZSwgcGFyZW50RWxlbWVudCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCwgZm9udFNpemVFbGVtZW50ID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50KSB7XG4gICAgdmFsaWRhdGVTdHJpbmcodmFsdWUpO1xuXG4gICAgY29uc3QgcmVnZXggPSAvXigtP1tcXGQuXSspKC4qKSQvO1xuICAgIGNvbnN0IG1hdGNoUmVzdWx0ID0gdmFsdWUubWF0Y2gocmVnZXgpO1xuXG4gICAgaWYgKCFtYXRjaFJlc3VsdCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgdmFsdWUgZm9ybWF0OiAke3ZhbHVlfWApO1xuICAgIH1cblxuICAgIGNvbnN0IFssIG51bSwgdW5pdF0gPSBtYXRjaFJlc3VsdDtcbiAgICBjb25zdCBudW1iZXIgPSBwYXJzZUZsb2F0KG51bSk7XG4gICAgY29uc3QgZHBpID0gZ2V0RGV2aWNlRFBJKCk7XG5cbiAgICBpZiAodW5pdCA9PT0gXCJweFwiKSB7XG4gICAgICAgIHJldHVybiBudW1iZXI7XG4gICAgfSBlbHNlIGlmICh1bml0ID09PSBcImVtXCIpIHtcbiAgICAgICAgY29uc3QgZm9udFNpemUgPSBwYXJzZUZsb2F0KHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGZvbnRTaXplRWxlbWVudCkuZm9udFNpemUpO1xuICAgICAgICByZXR1cm4gbnVtYmVyICogZm9udFNpemU7XG4gICAgfSBlbHNlIGlmICh1bml0ID09PSBcInJlbVwiKSB7XG4gICAgICAgIGNvbnN0IHJvb3RGb250U2l6ZSA9IHBhcnNlRmxvYXQod2luZG93LmdldENvbXB1dGVkU3R5bGUocGFyZW50RWxlbWVudCkuZm9udFNpemUpO1xuICAgICAgICByZXR1cm4gbnVtYmVyICogcm9vdEZvbnRTaXplO1xuICAgIH0gZWxzZSBpZiAodW5pdCA9PT0gXCIlXCIpIHtcbiAgICAgICAgY29uc3QgcGFyZW50V2lkdGggPSBwYXJzZUZsb2F0KHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHBhcmVudEVsZW1lbnQpLndpZHRoKTtcbiAgICAgICAgcmV0dXJuIChudW1iZXIgKiBwYXJlbnRXaWR0aCkgLyAxMDA7XG4gICAgfSBlbHNlIGlmICh1bml0ID09PSBcImluXCIpIHtcbiAgICAgICAgcmV0dXJuIG51bWJlciAqIGRwaTtcbiAgICB9IGVsc2UgaWYgKHVuaXQgPT09IFwiY21cIikge1xuICAgICAgICByZXR1cm4gKG51bWJlciAqIGRwaSkgLyAyLjU0O1xuICAgIH0gZWxzZSBpZiAodW5pdCA9PT0gXCJtbVwiKSB7XG4gICAgICAgIHJldHVybiAobnVtYmVyICogZHBpKSAvIDI1LjQ7XG4gICAgfSBlbHNlIGlmICh1bml0ID09PSBcInB0XCIpIHtcbiAgICAgICAgcmV0dXJuIChudW1iZXIgKiBkcGkpIC8gNzI7XG4gICAgfSBlbHNlIGlmICh1bml0ID09PSBcInBjXCIpIHtcbiAgICAgICAgcmV0dXJuIChudW1iZXIgKiBkcGkpIC8gNjtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIHVuaXQ6ICR7dW5pdH1gKTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHtleHBlY3R9IGZyb20gJ2NoYWknO1xuaW1wb3J0IHtjb252ZXJ0VG9QaXhlbHMsIGdldERldmljZURQSX0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS9kb20vZGltZW5zaW9uLm1qc1wiO1xuaW1wb3J0IHtnZXRXaW5kb3d9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvZG9tL3V0aWwubWpzXCI7XG5pbXBvcnQge2luaXRKU0RPTSwgaXNCcm93c2VyLCBKU0RPTUV4cG9ydCBhcyBKU0RPTX0gZnJvbSBcIi4uLy4uL3V0aWwvanNkb20ubWpzXCI7XG5pbXBvcnQge2dldEdsb2JhbH0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS90eXBlcy9nbG9iYWwubWpzXCI7XG5pbXBvcnQge2RldGVjdFJ1bnRpbWVFbnZpcm9ubWVudH0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS91dGlsL3J1bnRpbWUubWpzXCI7XG5cblxuZnVuY3Rpb24gZ2V0TW9ja1dpbmRvdyhkcGkpIHtcblxuICAgIGlmKGRldGVjdFJ1bnRpbWVFbnZpcm9ubWVudCgpID09PSAnYnJvd3NlcicpIHtcbiAgICAgICAgcmV0dXJuIGdldFdpbmRvdygpO1xuICAgIH1cbiAgICBcbiAgICBcbiAgICBjb25zdCBkb20gPSBuZXcgSlNET00oJycsIHtcbiAgICAgICAgcHJldGVuZFRvQmVWaXN1YWw6IHRydWUsXG4gICAgICAgIHJlc291cmNlczogJ3VzYWJsZScsXG4gICAgfSk7XG5cbiAgICBkb20ud2luZG93Lm1hdGNoTWVkaWEgPSAocXVlcnkpID0+IHtcbiAgICAgICAgY29uc3QgZHBpUmVnZXggPSAvXFwobWF4LXJlc29sdXRpb246IChcXGQrKWRwaVxcKS87XG4gICAgICAgIGNvbnN0IG1hdGNoID0gcXVlcnkubWF0Y2goZHBpUmVnZXgpO1xuXG4gICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgICAgY29uc3QgbWF4RHBpID0gcGFyc2VJbnQobWF0Y2hbMV0sIDEwKTtcbiAgICAgICAgICAgIHJldHVybiB7bWF0Y2hlczogZHBpIDw9IG1heERwaX07XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge21hdGNoZXM6IGZhbHNlfTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIGRvbS53aW5kb3c7XG59XG5cbmRlc2NyaWJlKCdkaW1lbnNpb24nLCAoKSA9PiB7XG4gICAgbGV0IGN1cnJlbnRFbnZpcm9ubWVudDtcblxuICAgIGJlZm9yZShmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICBpbml0SlNET00oKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIC8vY2hhaURvbShnZXREb2N1bWVudCgpKTtcbiAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgfSk7XG4gICAgfSlcblxuICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuXG4gICAgICAgIGNvbnN0IHRlc3REcGkgPSA5NjtcbiAgICAgICAgY29uc3QgdGVzdFdpbmRvdyA9IGdldE1vY2tXaW5kb3codGVzdERwaSk7XG4gICAgICAgIGdldEdsb2JhbCgpLndpbmRvdyA9IHRlc3RXaW5kb3c7XG5cbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICAgIGRlbGV0ZSBnZXRHbG9iYWwoKS53aW5kb3c7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnY29udmVydFRvUGl4ZWxzJywgKCkgPT4ge1xuICAgICAgICBpdCgnc2hvdWxkIGNvcnJlY3RseSBjb252ZXJ0IHB4IHZhbHVlcycsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGNvbnZlcnRUb1BpeGVscygnMTAwcHgnKTtcbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHQpLnRvLmVxdWFsKDEwMCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KFwic2hvdWxkIHRocm93IGFuIGVycm9yIHdoZW4gdGhlIGlucHV0IHZhbHVlIGhhcyBhbiBpbnZhbGlkIGZvcm1hdFwiLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBpbnZhbGlkVmFsdWUgPSBcImludmFsaWRfdmFsdWVcIjtcblxuICAgICAgICAgICAgY29uc3QgZXJyb3JGbiA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb252ZXJ0VG9QaXhlbHMoaW52YWxpZFZhbHVlKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGV4cGVjdChlcnJvckZuKS50by50aHJvdyhFcnJvciwgYEludmFsaWQgdmFsdWUgZm9ybWF0OiAke2ludmFsaWRWYWx1ZX1gKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoXCJzaG91bGQgaGFuZGxlIG5lZ2F0aXZlIHZhbHVlcyBjb3JyZWN0bHlcIiwgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgbmVnYXRpdmVWYWx1ZSA9IFwiLTEwcHhcIjtcbiAgICAgICAgICAgIGNvbnN0IGV4cGVjdGVkUmVzdWx0ID0gLTEwO1xuXG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBjb252ZXJ0VG9QaXhlbHMobmVnYXRpdmVWYWx1ZSk7XG5cbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHQpLnRvLmVxdWFsKGV4cGVjdGVkUmVzdWx0KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBjb3JyZWN0bHkgY29udmVydCBlbSB2YWx1ZXMnLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0ZXN0RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgdGVzdEVsZW1lbnQuc3R5bGUuZm9udFNpemUgPSAnMTZweCc7XG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRlc3RFbGVtZW50KTtcblxuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gY29udmVydFRvUGl4ZWxzKCcyZW0nLCB0ZXN0RWxlbWVudCwgdGVzdEVsZW1lbnQpO1xuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdCkudG8uZXF1YWwoMzIpO1xuXG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKHRlc3RFbGVtZW50KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBjb3JyZWN0bHkgY29udmVydCByZW0gdmFsdWVzJywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdGVzdEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIHRlc3RFbGVtZW50LnN0eWxlLmZvbnRTaXplID0gJzE2cHgnO1xuICAgICAgICAgICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmFwcGVuZENoaWxkKHRlc3RFbGVtZW50KTtcblxuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gY29udmVydFRvUGl4ZWxzKCcycmVtJywgdGVzdEVsZW1lbnQpO1xuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdCkudG8uZXF1YWwoMzIpO1xuXG4gICAgICAgICAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQucmVtb3ZlQ2hpbGQodGVzdEVsZW1lbnQpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIGNvcnJlY3RseSBjb252ZXJ0IHBlcmNlbnRhZ2UgdmFsdWVzJywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdGVzdEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIHRlc3RFbGVtZW50LnN0eWxlLndpZHRoID0gJzUwMHB4JztcbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodGVzdEVsZW1lbnQpO1xuXG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBjb252ZXJ0VG9QaXhlbHMoJzUwJScsIHRlc3RFbGVtZW50KTtcbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHQpLnRvLmVxdWFsKDI1MCk7XG5cbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQodGVzdEVsZW1lbnQpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHRocm93IGFuIGVycm9yIGZvciB1bnN1cHBvcnRlZCB1bml0cycsICgpID0+IHtcbiAgICAgICAgICAgIGV4cGVjdCgoKSA9PiBjb252ZXJ0VG9QaXhlbHMoJzEwdW5zdXBwb3J0ZWRVbml0JykpLnRvLnRocm93KCdVbnN1cHBvcnRlZCB1bml0OiB1bnN1cHBvcnRlZFVuaXQnKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cblxuICAgIGRlc2NyaWJlKCdnZXREZXZpY2VEUEknLCAoKSA9PiB7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIHRoZSBjb3JyZWN0IGRldmljZSBEUEknLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0ZXN0RHBpID0gOTY7XG4gICAgICAgICAgICBjb25zdCB0ZXN0V2luZG93ID0gZ2V0TW9ja1dpbmRvdyh0ZXN0RHBpKTtcbiAgICAgICAgICAgIGdldEdsb2JhbCgpLndpbmRvdyA9IHRlc3RXaW5kb3c7XG5cbiAgICAgICAgICAgIGNvbnN0IGRldmljZURwaSA9IGdldERldmljZURQSSgpO1xuICAgICAgICAgICAgZXhwZWN0KGRldmljZURwaSkudG8uZXF1YWwodGVzdERwaSAqIHRlc3RXaW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyk7XG5cbiAgICAgICAgICAgIGRlbGV0ZSBnZXRHbG9iYWwoKS53aW5kb3c7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgY2FjaGUgdGhlIHJlc3VsdCBhbmQgcmV0dXJuIHRoZSBzYW1lIHZhbHVlJywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdGVzdERwaSA9IDk2O1xuICAgICAgICAgICAgY29uc3QgdGVzdFdpbmRvdyA9IGdldE1vY2tXaW5kb3codGVzdERwaSk7XG4gICAgICAgICAgICBnZXRHbG9iYWwoKS53aW5kb3cgPSB0ZXN0V2luZG93O1xuXG4gICAgICAgICAgICBjb25zdCBkZXZpY2VEcGkxID0gZ2V0RGV2aWNlRFBJKCk7XG4gICAgICAgICAgICBjb25zdCBkZXZpY2VEcGkyID0gZ2V0RGV2aWNlRFBJKCk7XG4gICAgICAgICAgICBleHBlY3QoZGV2aWNlRHBpMSkudG8uZXF1YWwoZGV2aWNlRHBpMik7XG5cbiAgICAgICAgICAgIGRlbGV0ZSBnZXRHbG9iYWwoKS53aW5kb3c7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG59KTsiLCAiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQge2V4dGVuZH0gZnJvbSBcIi4uLy4uL3NvdXJjZS9kYXRhL2V4dGVuZC5tanNcIjtcbmltcG9ydCB7Z2V0R2xvYmFsfSBmcm9tIFwiLi4vLi4vc291cmNlL3R5cGVzL2dsb2JhbC5tanNcIjtcblxuZXhwb3J0IGNvbnN0IGlzQnJvd3NlciA9IG5ldyBGdW5jdGlvbihcInRyeSB7cmV0dXJuIHRoaXM9PT13aW5kb3c7fWNhdGNoKGUpeyByZXR1cm4gZmFsc2U7fVwiKTtcbmV4cG9ydCBjb25zdCBpc05vZGUgPSBuZXcgRnVuY3Rpb24oXCJ0cnkge3JldHVybiB0aGlzPT09Z2xvYmFsO31jYXRjaChlKXtyZXR1cm4gZmFsc2U7fVwiKTtcblxubGV0IEpTRE9NRXhwb3J0ID0gbnVsbDtcblxuLyoqXG4gKiB0aGlzIGhlbHBlciBmdW5jdGlvbiBjcmVhdGVzIHRoZSBkb20gc3RhY2sgaW4gdGhlIG5vZGUgZW52aXJvbm1lbnRcbiAqXG4gKiBAcmV0dXJuIHtQcm9taXNlPHVua25vd24+fFByb21pc2U8dm9pZD59XG4gKi9cbmZ1bmN0aW9uIGluaXRKU0RPTShvcHRpb25zKSB7XG4gICAgaWYgKHR5cGVvZiB3aW5kb3cgPT09IFwib2JqZWN0XCIgJiYgd2luZG93WydET01QYXJzZXInXSkgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuXG4gICAgY29uc3QgZyA9IGdldEdsb2JhbCgpO1xuXG4gICAgb3B0aW9ucyA9IGV4dGVuZCh7fSwge1xuICAgICAgICBwcmV0ZW5kVG9CZVZpc3VhbDogdHJ1ZSxcbiAgICAgICAgY29udGVudFR5cGU6IFwidGV4dC9odG1sXCIsXG4gICAgICAgIGluY2x1ZGVOb2RlTG9jYXRpb25zOiB0cnVlLFxuICAgICAgICBzdG9yYWdlUXVvdGE6IDEwMDAwMDAwLFxuICAgICAgICBydW5TY3JpcHRzOiBcImRhbmdlcm91c2x5XCIsXG4gICAgICAgIHJlc291cmNlczogXCJ1c2FibGVcIlxuICAgIH0sIG9wdGlvbnMgfHwge30pXG5cbiAgICByZXR1cm4gaW1wb3J0KFwianNkb21cIikudGhlbigoe0pTRE9NfSkgPT4ge1xuICAgICAgICBKU0RPTUV4cG9ydCA9IEpTRE9NO1xuICAgICAgICBjb25zdCB7d2luZG93fSA9IG5ldyBKU0RPTShgPGh0bWw+XG48aGVhZD5cbjwvaGVhZD5cbjxib2R5PlxuPGRpdiBpZD1cIm1vY2tzXCI+PC9kaXY+XG48L2JvZHk+YCwgb3B0aW9ucyk7XG5cbiAgICAgICAgZ1snd2luZG93J10gPSB3aW5kb3c7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT5cbiAgICAgICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwibG9hZFwiLCAoKSA9PiB7XG5cbiAgICAgICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgICAgICdzZWxmJyxcbiAgICAgICAgICAgICAgICAgICAgJ0hUTUxDb2xsZWN0aW9uJyxcbiAgICAgICAgICAgICAgICAgICAgJ05vZGVMaXN0JyxcbiAgICAgICAgICAgICAgICAgICAgJ0VsZW1lbnRJbnRlcm5hbHMnLFxuICAgICAgICAgICAgICAgICAgICAnSFRNTERvY3VtZW50JyxcbiAgICAgICAgICAgICAgICAgICAgJ0hUTUxGb3JtRWxlbWVudCcsXG4gICAgICAgICAgICAgICAgICAgICdIVE1MSW5wdXRFbGVtZW50JyxcbiAgICAgICAgICAgICAgICAgICAgJ0hUTUxTZWxlY3RFbGVtZW50JyxcbiAgICAgICAgICAgICAgICAgICAgJ0hUTUxUZXh0QXJlYUVsZW1lbnQnLFxuICAgICAgICAgICAgICAgICAgICAnZG9jdW1lbnQnLFxuICAgICAgICAgICAgICAgICAgICAnRG9jdW1lbnQnLFxuICAgICAgICAgICAgICAgICAgICAnTm9kZScsXG4gICAgICAgICAgICAgICAgICAgICdTaGFkb3dSb290JyxcbiAgICAgICAgICAgICAgICAgICAgJ0V2ZW50VGFyZ2V0JyxcbiAgICAgICAgICAgICAgICAgICAgJ0V2ZW50JyxcbiAgICAgICAgICAgICAgICAgICAgJ0N1c3RvbUV2ZW50JyxcbiAgICAgICAgICAgICAgICAgICAgJ0VsZW1lbnQnLFxuICAgICAgICAgICAgICAgICAgICAnSFRNTEVsZW1lbnQnLFxuICAgICAgICAgICAgICAgICAgICAnSFRNTERpdkVsZW1lbnQnLFxuICAgICAgICAgICAgICAgICAgICAnY3VzdG9tRWxlbWVudHMnLFxuICAgICAgICAgICAgICAgICAgICAnRG9jdW1lbnRGcmFnbWVudCcsXG4gICAgICAgICAgICAgICAgICAgICdET01QYXJzZXInLFxuICAgICAgICAgICAgICAgICAgICAnS2V5Ym9hcmRFdmVudCcsXG4gICAgICAgICAgICAgICAgICAgICdDU1NTdHlsZVNoZWV0JyxcbiAgICAgICAgICAgICAgICAgICAgJ0hUTUxTY3JpcHRFbGVtZW50JyxcbiAgICAgICAgICAgICAgICAgICAgJ011dGF0aW9uT2JzZXJ2ZXInLFxuICAgICAgICAgICAgICAgICAgICAnSFRNTFRlbXBsYXRlRWxlbWVudCcsXG4gICAgICAgICAgICAgICAgICAgICdYTUxTZXJpYWxpemVyJyxcbiAgICAgICAgICAgICAgICAgICAgJ05vZGVGaWx0ZXInLFxuICAgICAgICAgICAgICAgICAgICAnbmF2aWdhdG9yJyxcbiAgICAgICAgICAgICAgICAgICAgJ0lucHV0RXZlbnQnLFxuICAgICAgICAgICAgICAgICAgICAnQmxvYicsXG4gICAgICAgICAgICAgICAgICAgICdDdXN0b21FdmVudCdcbiAgICAgICAgICAgICAgICBdLmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgZ1trZXldID0gd2luZG93W2tleV1cbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICk7XG5cblxuICAgIH0pO1xufVxuXG5leHBvcnQge2luaXRKU0RPTSwgSlNET01FeHBvcnR9IFxuXG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlV0aWxcbiAqIEB0eXBlIHtzdHJpbmd9XG4gKi9cbmNvbnN0IEVOVl9BV1NfTEFNQkRBID0gXCJhd3MtbGFtYmRhXCI7XG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlV0aWxcbiAqIEB0eXBlIHtzdHJpbmd9XG4gKi9cbmNvbnN0IEVOVl9HT09HTEVfRlVOQ1RJT05TID0gXCJnb29nbGUtZnVuY3Rpb25zXCI7XG4vKipcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlV0aWxcbiAqIEB0eXBlIHtzdHJpbmd9XG4gKi9cbmNvbnN0IEVOVl9FTEVDVFJPTiA9IFwiZWxlY3Ryb25cIjtcbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuVXRpbFxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuY29uc3QgRU5WX05PREUgPSBcIm5vZGVcIjtcbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuVXRpbFxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuY29uc3QgRU5WX0JST1dTRVIgPSBcImJyb3dzZXJcIjtcbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuVXRpbFxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuY29uc3QgRU5WX1dFQl9XT1JLRVIgPSBcIndlYi13b3JrZXJcIjtcbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuVXRpbFxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuY29uc3QgRU5WX0RFTk8gPSBcImRlbm9cIjtcbi8qKlxuICogQG1lbWJlck9mIE1vbnN0ZXIuVXRpbFxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuY29uc3QgRU5WX1VOS05PV04gPSBcInVua25vd25cIjtcblxuLyoqXG4gKiBEZXRlY3RzIGFuZCByZXR1cm5zIHRoZSBjdXJyZW50IHJ1bnRpbWUgZW52aXJvbm1lbnQuXG4gKlxuICogLSAnYXdzLWxhbWJkYSc6IEFXUyBMYW1iZGEgZW52aXJvbm1lbnRcbiAqIC0gJ2dvb2dsZS1mdW5jdGlvbnMnOiBHb29nbGUgQ2xvdWQgRnVuY3Rpb25zIGVudmlyb25tZW50XG4gKiAtICdlbGVjdHJvbic6IEVsZWN0cm9uIGVudmlyb25tZW50XG4gKiAtICdub2RlJzogTm9kZS5qcyBlbnZpcm9ubWVudFxuICogLSAnYnJvd3Nlcic6IEJyb3dzZXIgZW52aXJvbm1lbnRcbiAqIC0gJ3dlYi13b3JrZXInOiBXZWIgV29ya2VyIGVudmlyb25tZW50XG4gKiAtICdkZW5vJzogRGVubyBlbnZpcm9ubWVudFxuICogLSAncmVhY3QtbmF0aXZlJzogUmVhY3QgTmF0aXZlIGVudmlyb25tZW50XG4gKiAtICd1bmtub3duJzogVW5rbm93biBlbnZpcm9ubWVudFxuICpcbiAqIEBzaW5jZSAzLjM0LjBcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlV0aWxcbiAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBkZXRlY3RlZCBydW50aW1lIGVudmlyb25tZW50LiBQb3NzaWJsZSB2YWx1ZXMgYXJlOlxuICovXG5mdW5jdGlvbiBkZXRlY3RSdW50aW1lRW52aXJvbm1lbnQoKSB7XG4gICAgLy8gQVdTIExhbWJkYSBlbnZpcm9ubWVudFxuICAgIGlmICh0eXBlb2YgcHJvY2VzcyAhPT0gXCJ1bmRlZmluZWRcIiAmJiBwcm9jZXNzLmVudiAhPSBudWxsICYmIHByb2Nlc3MuZW52LkFXU19MQU1CREFfRlVOQ1RJT05fTkFNRSkge1xuICAgICAgICByZXR1cm4gRU5WX0FXU19MQU1CREE7XG4gICAgfVxuXG4gICAgLy8gR29vZ2xlIENsb3VkIEZ1bmN0aW9ucyBlbnZpcm9ubWVudFxuICAgIGlmICh0eXBlb2YgcHJvY2VzcyAhPT0gXCJ1bmRlZmluZWRcIiAmJiBwcm9jZXNzLmVudiAhPSBudWxsICYmIHByb2Nlc3MuZW52LkZVTkNUSU9OX05BTUUpIHtcbiAgICAgICAgcmV0dXJuIEVOVl9HT09HTEVfRlVOQ1RJT05TO1xuICAgIH1cblxuICAgIC8vIE5vZGUuanMgZW52aXJvbm1lbnRcbiAgICBpZiAodHlwZW9mIHByb2Nlc3MgIT09IFwidW5kZWZpbmVkXCIgJiYgcHJvY2Vzcy52ZXJzaW9ucyAhPSBudWxsICYmIHByb2Nlc3MudmVyc2lvbnMubm9kZSAhPSBudWxsKSB7XG4gICAgICAgIC8vIEVsZWN0cm9uIGVudmlyb25tZW50XG4gICAgICAgIGlmIChwcm9jZXNzLnZlcnNpb25zLmVsZWN0cm9uICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBFTlZfRUxFQ1RST047XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIEVOVl9OT0RFO1xuICAgIH1cblxuICAgIC8vIEJyb3dzZXIgZW52aXJvbm1lbnRcbiAgICBpZiAoXG4gICAgICAgIHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgdHlwZW9mIHdpbmRvdy5kb2N1bWVudCAhPT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICB0eXBlb2YgbmF2aWdhdG9yICE9PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgIHR5cGVvZiBuYXZpZ2F0b3IudXNlckFnZW50ID09PSBcInN0cmluZ1wiXG4gICAgKSB7XG4gICAgICAgIC8vIFdlYiBXb3JrZXIgZW52aXJvbm1lbnRcbiAgICAgICAgaWYgKHR5cGVvZiBzZWxmID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBpbXBvcnRTY3JpcHRzID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBFTlZfV0VCX1dPUktFUjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gRU5WX0JST1dTRVI7XG4gICAgfVxuXG4gICAgLy8gRGVubyBlbnZpcm9ubWVudFxuICAgIGlmICh0eXBlb2YgRGVubyAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICByZXR1cm4gRU5WX0RFTk87XG4gICAgfVxuXG4gICAgLy8gVW5rbm93biBlbnZpcm9ubWVudFxuICAgIHJldHVybiBFTlZfVU5LTk9XTjtcbn1cblxuZXhwb3J0IHtcbiAgICBFTlZfQVdTX0xBTUJEQSxcbiAgICBFTlZfR09PR0xFX0ZVTkNUSU9OUyxcbiAgICBFTlZfRUxFQ1RST04sXG4gICAgRU5WX05PREUsXG4gICAgRU5WX0JST1dTRVIsXG4gICAgRU5WX1dFQl9XT1JLRVIsXG4gICAgRU5WX0RFTk8sXG4gICAgRU5WX1VOS05PV04sXG4gICAgZGV0ZWN0UnVudGltZUVudmlyb25tZW50LFxufTtcbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGV4dGVuZCB9IGZyb20gXCIuLi8uLi8uLi9kYXRhL2V4dGVuZC5tanNcIjtcbmltcG9ydCB7IExpbmsgfSBmcm9tIFwiLi4vbGluay5tanNcIjtcbmltcG9ydCB7IGluc3RhbmNlU3ltYm9sIH0gZnJvbSBcIi4uLy4uLy4uL2NvbnN0YW50cy5tanNcIjtcbmV4cG9ydCB7IFN0eWxlc2hlZXQgfTtcblxuLyoqXG4gKiBUaGlzIGNsYXNzIGlzIHVzZWQgYnkgdGhlIHJlc291cmNlIG1hbmFnZXIgdG8gZW1iZWQgZXh0ZXJuYWwgcmVzb3VyY2VzLlxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjUuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTS5SZXNvdXJjZVxuICogQHN1bW1hcnkgQSBSZXNvdXJjZSBjbGFzc1xuICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVE1ML0VsZW1lbnQvbGlua1xuICovXG5jbGFzcyBTdHlsZXNoZWV0IGV4dGVuZHMgTGluayB7XG4gICAgLyoqXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd9IHJlbCB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9FbGVtZW50L2xpbmsjYXR0ci1yZWx9XG4gICAgICovXG4gICAgZ2V0IGRlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gZXh0ZW5kKHt9LCBzdXBlci5kZWZhdWx0cywge1xuICAgICAgICAgICAgcmVsOiBcInN0eWxlc2hlZXRcIixcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMi4xLjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci9kb20vcmVzb3VyY2UvbGluay9zdHlsZXNoZWV0XCIpO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGV4dGVuZCB9IGZyb20gXCIuLi8uLi9kYXRhL2V4dGVuZC5tanNcIjtcbmltcG9ydCB7XG4gICAgQVRUUklCVVRFX0NMQVNTLFxuICAgIEFUVFJJQlVURV9IUkVGLFxuICAgIEFUVFJJQlVURV9JRCxcbiAgICBBVFRSSUJVVEVfTk9OQ0UsXG4gICAgQVRUUklCVVRFX1NSQyxcbiAgICBBVFRSSUJVVEVfVElUTEUsXG4gICAgQVRUUklCVVRFX1RZUEUsXG4gICAgVEFHX0xJTkssXG59IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQgeyBLRVlfRE9DVU1FTlQsIHJlZmVyZW5jZVN5bWJvbCwgUmVzb3VyY2UgfSBmcm9tIFwiLi4vcmVzb3VyY2UubWpzXCI7XG5pbXBvcnQgeyBpbnN0YW5jZVN5bWJvbCB9IGZyb20gXCIuLi8uLi9jb25zdGFudHMubWpzXCI7XG5leHBvcnQgeyBMaW5rIH07XG5cbi8qKlxuICogVGhpcyBjbGFzcyBpcyB1c2VkIGJ5IHRoZSByZXNvdXJjZSBtYW5hZ2VyIHRvIGVtYmVkIGV4dGVybmFsIHJlc291cmNlcy5cbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI1LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET00uUmVzb3VyY2VcbiAqIEBzdW1tYXJ5IEEgUmVzb3VyY2UgY2xhc3NcbiAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9FbGVtZW50L2xpbmtcbiAqL1xuY2xhc3MgTGluayBleHRlbmRzIFJlc291cmNlIHtcbiAgICAvKipcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gYXMge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUTUwvRWxlbWVudC9saW5rI2F0dHItYXN9XG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd9IGNyb3NzT3JpZ2luPWFub255bW91cyB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9FbGVtZW50L3NjcmlwdCNhdHRyLWNyb3Nzb3JpZ2lufVxuICAgICAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gZGlzYWJsZWRcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gaHJlZiB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9FbGVtZW50L2xpbmsjYXR0ci1ocmVmfVxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBocmVmbGFuZyB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9FbGVtZW50L2xpbmsjYXR0ci1ocmVmbGFuZ31cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gaW1hZ2VzaXplcyB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9FbGVtZW50L2xpbmsjYXR0ci1pbWFnZXNpemVzfVxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBpbWFnZXNyY3NldCB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9FbGVtZW50L2xpbmsjYXR0ci1pbWFnZXNyY3NldH1cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gaW50ZWdyaXR5IHtAbGluayBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVE1ML0VsZW1lbnQvbGluayNhdHRyLWludGVncml0eX1cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gbWVkaWEge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUTUwvRWxlbWVudC9saW5rI2F0dHItbWVkaWF9XG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd9IHByZWZldGNoIHtAbGluayBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVE1ML0VsZW1lbnQvbGluayNhdHRyLXByZWZldGNofVxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSByZWZlcnJlcnBvbGljeSB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9FbGVtZW50L2xpbmsjYXR0ci1yZWZlcnJlcnBvbGljeX1cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gcmVsIHtAbGluayBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVE1ML0VsZW1lbnQvbGluayNhdHRyLXJlbH1cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gdHlwZSB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9FbGVtZW50L2xpbmsjYXR0ci10eXBlfVxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBzaXplcyB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9FbGVtZW50L2xpbmsjYXR0ci1zaXplc31cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gbm9uY2Uge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUTUwvRWxlbWVudC9zY3JpcHQjYXR0ci1ub25jZX1cbiAgICAgKi9cbiAgICBnZXQgZGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBleHRlbmQoe30sIHN1cGVyLmRlZmF1bHRzLCB7XG4gICAgICAgICAgICBhczogdW5kZWZpbmVkLFxuICAgICAgICAgICAgY3Jvc3NPcmlnaW46IFwiYW5vbnltb3VzXCIsXG4gICAgICAgICAgICBkaXNhYmxlZDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgaHJlZjogdW5kZWZpbmVkLFxuICAgICAgICAgICAgaHJlZmxhbmc6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGltYWdlc2l6ZXM6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGltYWdlc3Jjc2V0OiB1bmRlZmluZWQsXG4gICAgICAgICAgICBpbnRlZ3JpdHk6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIG1lZGlhOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBwcmVmZXRjaDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgcmVmZXJyZXJwb2xpY3k6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHJlbDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgc2l6ZXM6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHR5cGU6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIG5vbmNlOiB1bmRlZmluZWQsXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgYGluc3RhbmNlb2ZgIG9wZXJhdG9yLlxuICAgICAqIEByZXR1cm5zIHtzeW1ib2x9XG4gICAgICogQHNpbmNlIDIuMS4wXG4gICAgICovXG4gICAgc3RhdGljIGdldCBbaW5zdGFuY2VTeW1ib2xdKCkge1xuICAgICAgICByZXR1cm4gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvZG9tL3Jlc291cmNlL2xpbmtcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtNb25zdGVyLkRPTS5SZXNvdXJjZS5MaW5rfVxuICAgICAqL1xuICAgIGNyZWF0ZSgpIHtcbiAgICAgICAgY3JlYXRlRWxlbWVudC5jYWxsKHRoaXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldFVSTEF0dHJpYnV0ZSgpIHtcbiAgICAgICAgcmV0dXJuIEFUVFJJQlVURV9IUkVGO1xuICAgIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHJldHVybiB7TW9uc3Rlci5ET00uUmVzb3VyY2UuTGlua31cbiAqL1xuZnVuY3Rpb24gY3JlYXRlRWxlbWVudCgpIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgIGNvbnN0IGRvY3VtZW50ID0gc2VsZi5nZXRPcHRpb24oS0VZX0RPQ1VNRU5UKTtcbiAgICBzZWxmW3JlZmVyZW5jZVN5bWJvbF0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFRBR19MSU5LKTtcblxuICAgIGZvciAobGV0IGtleSBvZiBbXG4gICAgICAgIFwiYXNcIixcbiAgICAgICAgXCJjcm9zc09yaWdpblwiLFxuICAgICAgICBcImRpc2FibGVkXCIsXG4gICAgICAgIFwiaHJlZlwiLFxuICAgICAgICBcImhyZWZsYW5nXCIsXG4gICAgICAgIFwiaW1hZ2VzaXplc1wiLFxuICAgICAgICBcImltYWdlc3Jjc2V0XCIsXG4gICAgICAgIFwiaW50ZWdyaXR5XCIsXG4gICAgICAgIFwibWVkaWFcIixcbiAgICAgICAgXCJwcmVmZXRjaFwiLFxuICAgICAgICBcInJlZmVycmVycG9saWN5XCIsXG4gICAgICAgIFwic2l6ZXNcIixcbiAgICAgICAgXCJyZWxcIixcbiAgICAgICAgXCJ0eXBlXCIsXG4gICAgICAgIEFUVFJJQlVURV9IUkVGLFxuICAgICAgICBBVFRSSUJVVEVfSUQsXG4gICAgICAgIEFUVFJJQlVURV9DTEFTUyxcbiAgICAgICAgQVRUUklCVVRFX1RJVExFLFxuICAgICAgICBBVFRSSUJVVEVfTk9OQ0UsXG4gICAgXSkge1xuICAgICAgICBpZiAoc2VsZi5nZXRPcHRpb24oa2V5KSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBzZWxmW3JlZmVyZW5jZVN5bWJvbF1ba2V5XSA9IHNlbGYuZ2V0T3B0aW9uKGtleSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gc2VsZjtcbn1cbiIsICIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBjaGFpIGZyb20gXCJjaGFpXCJcbmltcG9ydCB7U3R5bGVzaGVldH0gZnJvbSBcIi4uLy4uLy4uLy4uLy4uL3NvdXJjZS9kb20vcmVzb3VyY2UvbGluay9zdHlsZXNoZWV0Lm1qc1wiO1xuaW1wb3J0IHtEYXRhVXJsfSBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vc291cmNlL3R5cGVzL2RhdGF1cmwubWpzXCI7XG5pbXBvcnQge0lEfSBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vc291cmNlL3R5cGVzL2lkLm1qc1wiO1xuaW1wb3J0IHtjaGFpRG9tfSBmcm9tIFwiLi4vLi4vLi4vLi4vdXRpbC9jaGFpLWRvbS5tanNcIjtcbmltcG9ydCB7Y2xlYW51cERPTUZyb21UZXN0aW5nLCBpbml0TXV0YXRpb25PYnNlcnZlckZvclRlc3Rpbmd9IGZyb20gXCIuLi8uLi8uLi8uLi91dGlsL2NsZWFudXBkb20ubWpzXCI7XG5pbXBvcnQge2luaXRKU0RPTX0gZnJvbSBcIi4uLy4uLy4uLy4uL3V0aWwvanNkb20ubWpzXCI7XG5cbmxldCBleHBlY3QgPSBjaGFpLmV4cGVjdDtcblxuY2hhaS51c2UoY2hhaURvbSk7XG5cbmxldCBodG1sMSA9IGBcblxuYDtcblxuXG5kZXNjcmliZSgnU3R5bGVzaGVldCcsIGZ1bmN0aW9uICgpIHtcblxuICAgIGJlZm9yZShmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICBpbml0SlNET00oe1xuICAgICAgICAgICAgcnVuU2NyaXB0czogXCJkYW5nZXJvdXNseVwiLFxuICAgICAgICAgICAgcmVzb3VyY2VzOiBcInVzYWJsZVwiXG4gICAgICAgIH0pLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgZG9uZSgpXG4gICAgICAgIH0pLmNhdGNoKGUgPT4gZG9uZShlKSk7XG4gICAgfSk7XG5cbiAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAgaW5pdE11dGF0aW9uT2JzZXJ2ZXJGb3JUZXN0aW5nKClcbiAgICB9KVxuXG4gICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgICAgY2xlYW51cERPTUZyb21UZXN0aW5nKCk7XG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCdTdHlsZXNoZWV0KCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdjb25uZWN0KCkuYXZhaWxhYmxlKCknLCBmdW5jdGlvbiAoZG9uZSkge1xuXG4gICAgICAgICAgICBjb25zdCBzdHlsZXNoZWV0ID0gbmV3IFN0eWxlc2hlZXQoe1xuICAgICAgICAgICAgICAgIGhyZWY6IG5ldyBEYXRhVXJsKCcnLCAndGV4dC9jc3MnKS50b1N0cmluZygpLFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHN0eWxlc2hlZXQuY29ubmVjdCgpLmF2YWlsYWJsZSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGlkID0gc3R5bGVzaGVldC5nZXRPcHRpb24oJ2lkJylcbiAgICAgICAgICAgICAgICBkb25lKClcbiAgICAgICAgICAgIH0pLmNhdGNoKGUgPT4gZG9uZShlKSk7XG5cbiAgICAgICAgfSlcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdFeHRlcm5hbCBTdHlsZXNoZWV0JywgKCkgPT4ge1xuXG4gICAgICAgIGxldCBpZCA9IG5ldyBJRCgnU3R5bGVzaGVldCcpLnRvU3RyaW5nKCk7XG4gICAgICAgIGxldCBzdHlsZXNoZWV0LCB1cmwgPSAnaHR0cHM6Ly9tb25zdGVyanMub3JnL2Fzc2V0cy9lbXB0eS5jc3M/JyArIGlkO1xuXG4gICAgICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuXG4gICAgICAgICAgICBzdHlsZXNoZWV0ID0gbmV3IFN0eWxlc2hlZXQoe1xuICAgICAgICAgICAgICAgIGhyZWY6IHVybCxcbiAgICAgICAgICAgICAgICBpZDogaWQsXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnYXBwZW5kIGFuZCByZW1vdmUgU3R5bGVzaGVldCAnLCAoZG9uZSkgPT4ge1xuXG4gICAgICAgICAgICBleHBlY3Qoc3R5bGVzaGVldC5pc0Nvbm5lY3RlZCgpKS50by5iZS5mYWxzZTtcblxuICAgICAgICAgICAgc3R5bGVzaGVldC5jb25uZWN0KCkuYXZhaWxhYmxlKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KHN0eWxlc2hlZXQuaXNDb25uZWN0ZWQoKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgICAgICAgICBleHBlY3QoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW2hyZWY9XCInICsgdXJsICsgJ1wiXScpKS50by5leGlzdDtcblxuICAgICAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKS5yZW1vdmUoKTtcbiAgICAgICAgICAgICAgICBleHBlY3Qoc3R5bGVzaGVldC5pc0Nvbm5lY3RlZCgpKS50by5iZS5mYWxzZTtcbiAgICAgICAgICAgICAgICBleHBlY3QoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW2hyZWY9XCInICsgdXJsICsgJ1wiXScpKS5ub3QudG8uZXhpc3Q7XG5cbiAgICAgICAgICAgICAgICBzdHlsZXNoZWV0LmNvbm5lY3QoKS5hdmFpbGFibGUoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KHN0eWxlc2hlZXQuaXNDb25uZWN0ZWQoKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ1tocmVmPVwiJyArIHVybCArICdcIl0nKSkudG8uZXhpc3Q7XG5cbiAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpLnJlbW92ZSgpO1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW2hyZWY9XCInICsgdXJsICsgJ1wiXScpKS5ub3QudG8uZXhpc3Q7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChzdHlsZXNoZWV0LmlzQ29ubmVjdGVkKCkpLnRvLmJlLmZhbHNlO1xuXG4gICAgICAgICAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICAgICAgICAgIH0pLmNhdGNoKGUgPT4gZG9uZShlKSk7XG5cblxuICAgICAgICAgICAgfSkuY2F0Y2goZSA9PiBkb25lKGUpKTtcblxuXG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxuXG59KTsiLCAiLyoqKioqKioqXG5cbiBDb252ZXJ0IGNoYWktZG9tIDEuOC4xIHRvIGVzIG1vZHVsZSwgd2l0aG91dCBhbnkgb3RoZXIgbW9kaWZpY2F0aW9uLlxuIEZyb20gaHR0cHM6Ly9naXRodWIuY29tL25hdGhhbmJva3RhZS9jaGFpLWRvbS9ibG9iLzg2YzM0MjMvY2hhaS1kb20uanNcbiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL25hdGhhbmJva3RhZS9jaGFpLWRvbS9pc3N1ZXMvMzhcblxuIFVzYWdlOlxuIGltcG9ydCB7IGNoYWlEb20gfSBmcm9tICc8cGF0aC10bz4vY2hhaS1kb20nO1xuIGNoYWkudXNlKGNoYWlEb20pO1xuXG4gQ29weXJpZ2h0IChjKSAyMDE1IE5hdGhhbiBCbGFjayBhbmQgb3RoZXIgY29udHJpYnV0b3JzXG5cbiBUaGlzIHdvcmsgaXMgbGljZW5zZWQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBNSVQgbGljZW5zZS4gRm9yIGEgY29weSwgc2VlIDxodHRwczovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL01JVD4uXG5cbiAqKioqKioqKioqL1xuXG5leHBvcnQgZnVuY3Rpb24gY2hhaURvbShjaGFpLCB1dGlscykge1xuICAgIGxldCBmbGFnID0gdXRpbHMuZmxhZyxcblxuICAgICAgICBlbFRvU3RyaW5nID0gZnVuY3Rpb24oZWwpIHtcbiAgICAgICAgICAgIGxldCBkZXNjXG4gICAgICAgICAgICBpZiAoaXNOb2RlTGlzdChlbCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoZWwubGVuZ3RoID09PSAwKSByZXR1cm4gJ2VtcHR5IE5vZGVMaXN0J1xuICAgICAgICAgICAgICAgIGRlc2MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChlbCwgMCwgNSkubWFwKGVsVG9TdHJpbmcpLmpvaW4oJywgJylcbiAgICAgICAgICAgICAgICByZXR1cm4gZWwubGVuZ3RoID4gNSA/IGRlc2MgKyAnLi4uICgrJyArIChlbC5sZW5ndGggLSA1KSArICcgbW9yZSknIDogZGVzY1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFpc0hUTUxFbGVtZW50KGVsKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBTdHJpbmcoZWwpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGRlc2MgPSBlbC50YWdOYW1lLnRvTG93ZXJDYXNlKClcbiAgICAgICAgICAgIGlmIChlbC5pZCkge1xuICAgICAgICAgICAgICAgIGRlc2MgKz0gJyMnICsgZWwuaWRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChlbC5jbGFzc05hbWUpIHtcbiAgICAgICAgICAgICAgICBkZXNjICs9ICcuJyArIFN0cmluZyhlbC5jbGFzc05hbWUpLnJlcGxhY2UoL1xccysvZywgJy4nKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQXJyYXkucHJvdG90eXBlLmZvckVhY2guY2FsbChlbC5hdHRyaWJ1dGVzLCBmdW5jdGlvbihhdHRyKSB7XG4gICAgICAgICAgICAgICAgaWYgKGF0dHIubmFtZSAhPT0gJ2NsYXNzJyAmJiBhdHRyLm5hbWUgIT09ICdpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVzYyArPSAnWycgKyBhdHRyLm5hbWUgKyAoYXR0ci52YWx1ZSA/ICc9XCInICsgYXR0ci52YWx1ZSArICdcIl0nIDogJ10nKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICByZXR1cm4gZGVzY1xuICAgICAgICB9LFxuXG4gICAgICAgIGF0dHJBc3NlcnQgPSBmdW5jdGlvbihuYW1lLCB2YWwpIHtcbiAgICAgICAgICAgIHZhciBlbCA9IGZsYWcodGhpcywgJ29iamVjdCcpLCBhY3R1YWwgPSBlbC5nZXRBdHRyaWJ1dGUobmFtZSlcblxuICAgICAgICAgICAgaWYgKCFmbGFnKHRoaXMsICduZWdhdGUnKSB8fCB1bmRlZmluZWQgPT09IHZhbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgICAgICAgICAgICAhIWVsLmF0dHJpYnV0ZXNbbmFtZV1cbiAgICAgICAgICAgICAgICAgICAgLCAnZXhwZWN0ZWQgJyArIGVsVG9TdHJpbmcoZWwpICsgJyB0byBoYXZlIGFuIGF0dHJpYnV0ZSAje2V4cH0nXG4gICAgICAgICAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKGVsKSArICcgbm90IHRvIGhhdmUgYW4gYXR0cmlidXRlICN7ZXhwfSdcbiAgICAgICAgICAgICAgICAgICAgLCBuYW1lXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodW5kZWZpbmVkICE9PSB2YWwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICAgICAgICAgICAgdmFsID09PSBhY3R1YWxcbiAgICAgICAgICAgICAgICAgICAgLCAnZXhwZWN0ZWQgJyArIGVsVG9TdHJpbmcoZWwpICsgJyB0byBoYXZlIGFuIGF0dHJpYnV0ZSAnICsgdXRpbHMuaW5zcGVjdChuYW1lKSArICcgd2l0aCB0aGUgdmFsdWUgI3tleHB9LCBidXQgdGhlIHZhbHVlIHdhcyAje2FjdH0nXG4gICAgICAgICAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKGVsKSArICcgbm90IHRvIGhhdmUgYW4gYXR0cmlidXRlICcgKyB1dGlscy5pbnNwZWN0KG5hbWUpICsgJyB3aXRoIHRoZSB2YWx1ZSAje2FjdH0nXG4gICAgICAgICAgICAgICAgICAgICwgdmFsXG4gICAgICAgICAgICAgICAgICAgICwgYWN0dWFsXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmbGFnKHRoaXMsICdvYmplY3QnLCBhY3R1YWwpXG4gICAgICAgIH0sXG5cbiAgICAgICAgaXNIVE1MRWxlbWVudCA9IGZ1bmN0aW9uKGVsKSB7XG4gICAgICAgICAgICByZXR1cm4gZWwubm9kZVR5cGUgPT09IDEgLy8gd2luZG93Lk5vZGUuRUxFTUVOVF9OT0RFXG4gICAgICAgIH0sXG5cbiAgICAgICAgaXNOb2RlTGlzdCA9IGZ1bmN0aW9uKG9iaikge1xuICAgICAgICAgICAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmopID09PSAnW29iamVjdCBOb2RlTGlzdF0nXG4gICAgICAgIH1cblxuICAgIHV0aWxzLmVsVG9TdHJpbmcgPSBlbFRvU3RyaW5nXG4gICAgY2hhaS5Bc3NlcnRpb24uYWRkTWV0aG9kKCdhdHRyJywgYXR0ckFzc2VydClcbiAgICBjaGFpLkFzc2VydGlvbi5hZGRNZXRob2QoJ2F0dHJpYnV0ZScsIGF0dHJBc3NlcnQpXG5cbiAgICBjaGFpLkFzc2VydGlvbi5hZGRNZXRob2QoJ2NsYXNzJywgZnVuY3Rpb24oY2xhc3NOYW1lKSB7XG4gICAgICAgIHZhciBlbCA9IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgICAgZWwuY2xhc3NMaXN0LmNvbnRhaW5zKGNsYXNzTmFtZSlcbiAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKGVsKSArICcgdG8gaGF2ZSBjbGFzcyAje2V4cH0nXG4gICAgICAgICAgICAsICdleHBlY3RlZCAnICsgZWxUb1N0cmluZyhlbCkgKyAnIG5vdCB0byBoYXZlIGNsYXNzICN7ZXhwfSdcbiAgICAgICAgICAgICwgY2xhc3NOYW1lXG4gICAgICAgIClcbiAgICB9KVxuXG4gICAgY2hhaS5Bc3NlcnRpb24uYWRkTWV0aG9kKCdpZCcsIGZ1bmN0aW9uKGlkKSB7XG4gICAgICAgIHZhciBlbCA9IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgICAgZWwuaWQgPT0gaWRcbiAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKGVsKSArICcgdG8gaGF2ZSBpZCAje2V4cH0nXG4gICAgICAgICAgICAsICdleHBlY3RlZCAnICsgZWxUb1N0cmluZyhlbCkgKyAnIG5vdCB0byBoYXZlIGlkICN7ZXhwfSdcbiAgICAgICAgICAgICwgaWRcbiAgICAgICAgKVxuICAgIH0pXG5cbiAgICBjaGFpLkFzc2VydGlvbi5hZGRNZXRob2QoJ2h0bWwnLCBmdW5jdGlvbihodG1sKSB7XG4gICAgICAgIHZhciBlbCA9IGZsYWcodGhpcywgJ29iamVjdCcpLCBhY3R1YWwgPSBmbGFnKHRoaXMsICdvYmplY3QnKS5pbm5lckhUTUxcblxuICAgICAgICBpZiAoZmxhZyh0aGlzLCAnY29udGFpbnMnKSkge1xuICAgICAgICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgICAgICAgYWN0dWFsLmluZGV4T2YoaHRtbCkgPj0gMFxuICAgICAgICAgICAgICAgICwgJ2V4cGVjdGVkICN7YWN0fSB0byBjb250YWluIEhUTUwgI3tleHB9J1xuICAgICAgICAgICAgICAgICwgJ2V4cGVjdGVkICN7YWN0fSBub3QgdG8gY29udGFpbiBIVE1MICN7ZXhwfSdcbiAgICAgICAgICAgICAgICAsIGh0bWxcbiAgICAgICAgICAgICAgICAsIGFjdHVhbFxuICAgICAgICAgICAgKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgICAgICAgYWN0dWFsID09PSBodG1sXG4gICAgICAgICAgICAgICAgLCAnZXhwZWN0ZWQgJyArIGVsVG9TdHJpbmcoZWwpICsgJyB0byBoYXZlIEhUTUwgI3tleHB9LCBidXQgdGhlIEhUTUwgd2FzICN7YWN0fSdcbiAgICAgICAgICAgICAgICAsICdleHBlY3RlZCAnICsgZWxUb1N0cmluZyhlbCkgKyAnIG5vdCB0byBoYXZlIEhUTUwgI3tleHB9J1xuICAgICAgICAgICAgICAgICwgaHRtbFxuICAgICAgICAgICAgICAgICwgYWN0dWFsXG4gICAgICAgICAgICApXG4gICAgICAgIH1cbiAgICB9KVxuXG4gICAgY2hhaS5Bc3NlcnRpb24uYWRkQ2hhaW5hYmxlTWV0aG9kKCd0cmltbWVkJywgbnVsbCwgZnVuY3Rpb24oKSB7XG4gICAgICAgIGZsYWcodGhpcywgJ3RyaW0tdGV4dCcsIHRydWUpXG4gICAgfSlcblxuICAgIGNoYWkuQXNzZXJ0aW9uLmFkZE1ldGhvZCgndGV4dCcsIGZ1bmN0aW9uKHRleHQpIHtcbiAgICAgICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpLCBjb250YWlucyA9IGZsYWcodGhpcywgJ2NvbnRhaW5zJyksXG4gICAgICAgICAgICB0cmltID0gZmxhZyh0aGlzLCAndHJpbS10ZXh0JyksIGFjdHVhbCwgcmVzdWx0XG5cbiAgICAgICAgaWYgKGlzTm9kZUxpc3Qob2JqKSkge1xuICAgICAgICAgICAgYWN0dWFsID0gQXJyYXkucHJvdG90eXBlLm1hcC5jYWxsKG9iaiwgZnVuY3Rpb24oZWwpIHsgcmV0dXJuIHRyaW0gPyBlbC50ZXh0Q29udGVudC50cmltKCkgOiBlbC50ZXh0Q29udGVudCB9KVxuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodGV4dCkpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBjb250YWlucyA/XG4gICAgICAgICAgICAgICAgICAgIHRleHRbZmxhZyh0aGlzLCAnbmVnYXRlJykgPyAnc29tZScgOiAnZXZlcnknXShmdW5jdGlvbih0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gQXJyYXkucHJvdG90eXBlLnNvbWUuY2FsbChvYmosIGZ1bmN0aW9uKGVsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICh0cmltID8gZWwudGV4dENvbnRlbnQudHJpbSgpIDogZWwudGV4dENvbnRlbnQpID09PSB0XG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICA6XG4gICAgICAgICAgICAgICAgICAgIHV0aWxzLmVxbChhY3R1YWwsIHRleHQpXG5cbiAgICAgICAgICAgICAgICBhY3R1YWwgPSBhY3R1YWwuam9pbigpXG4gICAgICAgICAgICAgICAgdGV4dCA9IHRleHQuam9pbigpXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGFjdHVhbCA9IGFjdHVhbC5qb2luKCcnKVxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGNvbnRhaW5zID8gYWN0dWFsLmluZGV4T2YodGV4dCkgPj0gMCA6IGFjdHVhbCA9PT0gdGV4dFxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYWN0dWFsID0gdHJpbSA/IG9iai50ZXh0Q29udGVudC50cmltKCkgOiBvYmoudGV4dENvbnRlbnRcbiAgICAgICAgICAgIHJlc3VsdCA9IGNvbnRhaW5zID8gYWN0dWFsLmluZGV4T2YodGV4dCkgPj0gMCA6IGFjdHVhbCA9PT0gdGV4dFxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIG9iakRlc2MgPSBlbFRvU3RyaW5nKG9iaiksIHRleHRNc2cgPSB0cmltID8gJ3RyaW1tZWQgdGV4dCcgOiAndGV4dCdcbiAgICAgICAgaWYgKGNvbnRhaW5zKSB7XG4gICAgICAgICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICAgICAgICByZXN1bHRcbiAgICAgICAgICAgICAgICAsICdleHBlY3RlZCAnICsgb2JqRGVzYyArICcgdG8gY29udGFpbiAje2V4cH0sIGJ1dCB0aGUgJyArIHRleHRNc2cgKyAnIHdhcyAje2FjdH0nXG4gICAgICAgICAgICAgICAgLCAnZXhwZWN0ZWQgJyArIG9iakRlc2MgKyAnIG5vdCB0byBjb250YWluICN7ZXhwfSwgYnV0IHRoZSAnICsgdGV4dE1zZyArICcgd2FzICN7YWN0fSdcbiAgICAgICAgICAgICAgICAsIHRleHRcbiAgICAgICAgICAgICAgICAsIGFjdHVhbFxuICAgICAgICAgICAgKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgICAgICAgcmVzdWx0XG4gICAgICAgICAgICAgICAgLCAnZXhwZWN0ZWQgJyArIG9iakRlc2MgKyAnIHRvIGhhdmUgJyArIHRleHRNc2cgKyAnICN7ZXhwfSwgYnV0IHRoZSAnICsgdGV4dE1zZyArICcgd2FzICN7YWN0fSdcbiAgICAgICAgICAgICAgICAsICdleHBlY3RlZCAnICsgb2JqRGVzYyArICcgbm90IHRvIGhhdmUgJyArIHRleHRNc2cgKyAnICN7ZXhwfSdcbiAgICAgICAgICAgICAgICAsIHRleHRcbiAgICAgICAgICAgICAgICAsIGFjdHVhbFxuICAgICAgICAgICAgKVxuICAgICAgICB9XG4gICAgfSlcblxuICAgIGNoYWkuQXNzZXJ0aW9uLmFkZE1ldGhvZCgndmFsdWUnLCBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICB2YXIgZWwgPSBmbGFnKHRoaXMsICdvYmplY3QnKSwgYWN0dWFsID0gZmxhZyh0aGlzLCAnb2JqZWN0JykudmFsdWVcbiAgICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgICBmbGFnKHRoaXMsICdvYmplY3QnKS52YWx1ZSA9PT0gdmFsdWVcbiAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKGVsKSArICcgdG8gaGF2ZSB2YWx1ZSAje2V4cH0sIGJ1dCB0aGUgdmFsdWUgd2FzICN7YWN0fSdcbiAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKGVsKSArICcgbm90IHRvIGhhdmUgdmFsdWUgI3tleHB9J1xuICAgICAgICAgICAgLCB2YWx1ZVxuICAgICAgICAgICAgLCBhY3R1YWxcbiAgICAgICAgKVxuICAgIH0pXG5cbiAgICBjaGFpLkFzc2VydGlvbi5vdmVyd3JpdGVQcm9wZXJ0eSgnZXhpc3QnLCBmdW5jdGlvbihfc3VwZXIpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAgICAgICBpZiAoaXNOb2RlTGlzdChvYmopKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgICAgICAgICAgIG9iai5sZW5ndGggPiAwXG4gICAgICAgICAgICAgICAgICAgICwgJ2V4cGVjdGVkIGFuIGVtcHR5IE5vZGVMaXN0IHRvIGhhdmUgbm9kZXMnXG4gICAgICAgICAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKG9iaikgKyAnIHRvIG5vdCBleGlzdCcpXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9KVxuXG4gICAgY2hhaS5Bc3NlcnRpb24ub3ZlcndyaXRlUHJvcGVydHkoJ2VtcHR5JywgZnVuY3Rpb24oX3N1cGVyKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgICAgICAgaWYgKGlzSFRNTEVsZW1lbnQob2JqKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgICAgICAgICAgICBvYmouY2hpbGRyZW4ubGVuZ3RoID09PSAwXG4gICAgICAgICAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKG9iaikgKyAnIHRvIGJlIGVtcHR5J1xuICAgICAgICAgICAgICAgICAgICAsICdleHBlY3RlZCAnICsgZWxUb1N0cmluZyhvYmopICsgJyB0byBub3QgYmUgZW1wdHknKVxuICAgICAgICAgICAgfSBlbHNlIGlmIChpc05vZGVMaXN0KG9iaikpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICAgICAgICAgICAgb2JqLmxlbmd0aCA9PT0gMFxuICAgICAgICAgICAgICAgICAgICAsICdleHBlY3RlZCAnICsgZWxUb1N0cmluZyhvYmopICsgJyB0byBiZSBlbXB0eSdcbiAgICAgICAgICAgICAgICAgICAgLCAnZXhwZWN0ZWQgJyArIGVsVG9TdHJpbmcob2JqKSArICcgdG8gbm90IGJlIGVtcHR5JylcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cylcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0pXG5cbiAgICBjaGFpLkFzc2VydGlvbi5vdmVyd3JpdGVDaGFpbmFibGVNZXRob2QoJ2xlbmd0aCcsXG4gICAgICAgIGZ1bmN0aW9uKF9zdXBlcikge1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgICAgICAgICAgIGlmIChpc05vZGVMaXN0KG9iaikgfHwgaXNIVE1MRWxlbWVudChvYmopKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBhY3R1YWxMZW5ndGggPSBvYmouY2hpbGRyZW4gPyBvYmouY2hpbGRyZW4ubGVuZ3RoIDogb2JqLmxlbmd0aFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICAgICAgICAgICAgICAgIGFjdHVhbExlbmd0aCA9PT0gbGVuZ3RoXG4gICAgICAgICAgICAgICAgICAgICAgICAsICdleHBlY3RlZCAnICsgZWxUb1N0cmluZyhvYmopICsgJyB0byBoYXZlICN7ZXhwfSBjaGlsZHJlbiBidXQgaXQgaGFkICN7YWN0fSBjaGlsZHJlbidcbiAgICAgICAgICAgICAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKG9iaikgKyAnIHRvIG5vdCBoYXZlICN7ZXhwfSBjaGlsZHJlbidcbiAgICAgICAgICAgICAgICAgICAgICAgICwgbGVuZ3RoXG4gICAgICAgICAgICAgICAgICAgICAgICAsIGFjdHVhbExlbmd0aFxuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cylcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGZ1bmN0aW9uKF9zdXBlcikge1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIF9zdXBlci5jYWxsKHRoaXMpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICApXG5cblxuICAgIGNoYWkuQXNzZXJ0aW9uLm92ZXJ3cml0ZU1ldGhvZCgnbWF0Y2gnLCBmdW5jdGlvbihfc3VwZXIpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKHNlbGVjdG9yKSB7XG4gICAgICAgICAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0JylcbiAgICAgICAgICAgIGlmIChpc0hUTUxFbGVtZW50KG9iaikpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICAgICAgICAgICAgb2JqLm1hdGNoZXMoc2VsZWN0b3IpXG4gICAgICAgICAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKG9iaikgKyAnIHRvIG1hdGNoICN7ZXhwfSdcbiAgICAgICAgICAgICAgICAgICAgLCAnZXhwZWN0ZWQgJyArIGVsVG9TdHJpbmcob2JqKSArICcgdG8gbm90IG1hdGNoICN7ZXhwfSdcbiAgICAgICAgICAgICAgICAgICAgLCBzZWxlY3RvclxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNOb2RlTGlzdChvYmopKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgICAgICAgICAgICghIW9iai5sZW5ndGggJiYgQXJyYXkucHJvdG90eXBlLmV2ZXJ5LmNhbGwob2JqLCBmdW5jdGlvbihlbCkgeyByZXR1cm4gZWwubWF0Y2hlcyhzZWxlY3RvcikgfSkpXG4gICAgICAgICAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKG9iaikgKyAnIHRvIG1hdGNoICN7ZXhwfSdcbiAgICAgICAgICAgICAgICAgICAgLCAnZXhwZWN0ZWQgJyArIGVsVG9TdHJpbmcob2JqKSArICcgdG8gbm90IG1hdGNoICN7ZXhwfSdcbiAgICAgICAgICAgICAgICAgICAgLCBzZWxlY3RvclxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cylcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0pXG5cbiAgICBjaGFpLkFzc2VydGlvbi5vdmVyd3JpdGVDaGFpbmFibGVNZXRob2QoJ2NvbnRhaW4nLFxuICAgICAgICBmdW5jdGlvbihfc3VwZXIpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbihzdWJpdGVtKSB7XG4gICAgICAgICAgICAgICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAgICAgICAgICAgaWYgKGlzSFRNTEVsZW1lbnQob2JqKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHN1Yml0ZW0gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAhIW9iai5xdWVyeVNlbGVjdG9yKHN1Yml0ZW0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLCAnZXhwZWN0ZWQgJyArIGVsVG9TdHJpbmcob2JqKSArICcgdG8gY29udGFpbiAje2V4cH0nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLCAnZXhwZWN0ZWQgJyArIGVsVG9TdHJpbmcob2JqKSArICcgdG8gbm90IGNvbnRhaW4gI3tleHB9J1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICwgc3ViaXRlbSlcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iai5jb250YWlucyhzdWJpdGVtKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKG9iaikgKyAnIHRvIGNvbnRhaW4gJyArIGVsVG9TdHJpbmcoc3ViaXRlbSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAsICdleHBlY3RlZCAnICsgZWxUb1N0cmluZyhvYmopICsgJyB0byBub3QgY29udGFpbiAnICsgZWxUb1N0cmluZyhzdWJpdGVtKSlcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBmdW5jdGlvbihfc3VwZXIpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICBfc3VwZXIuY2FsbCh0aGlzKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgKVxuXG4gICAgY2hhaS5Bc3NlcnRpb24uYWRkTWV0aG9kKCdkZXNjZW5kYW50JywgZnVuY3Rpb24oc3ViaXRlbSkge1xuICAgICAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0JyksIGFjdHVhbCA9IHN1Yml0ZW1cblxuICAgICAgICBpZiAodHlwZW9mIHN1Yml0ZW0gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBhY3R1YWwgPSBvYmoucXVlcnlTZWxlY3RvcihzdWJpdGVtKVxuICAgICAgICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgICAgICAgISFhY3R1YWxcbiAgICAgICAgICAgICAgICAsICdleHBlY3RlZCAnICsgZWxUb1N0cmluZyhvYmopICsgJyB0byBoYXZlIGRlc2NlbmRhbnQgI3tleHB9J1xuICAgICAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKG9iaikgKyAnIHRvIG5vdCBoYXZlIGRlc2NlbmRhbnQgI3tleHB9J1xuICAgICAgICAgICAgICAgICwgc3ViaXRlbSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgICAgICAgIG9iai5jb250YWlucyhzdWJpdGVtKVxuICAgICAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKG9iaikgKyAnIHRvIGNvbnRhaW4gJyArIGVsVG9TdHJpbmcoc3ViaXRlbSlcbiAgICAgICAgICAgICAgICAsICdleHBlY3RlZCAnICsgZWxUb1N0cmluZyhvYmopICsgJyB0byBub3QgY29udGFpbiAnICsgZWxUb1N0cmluZyhzdWJpdGVtKSlcbiAgICAgICAgfVxuXG4gICAgICAgIGZsYWcodGhpcywgJ29iamVjdCcsIGFjdHVhbClcbiAgICB9KVxuXG4gICAgY2hhaS5Bc3NlcnRpb24uYWRkTWV0aG9kKCdkZXNjZW5kYW50cycsIGZ1bmN0aW9uKHNlbGVjdG9yKSB7XG4gICAgICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKSxcbiAgICAgICAgICAgIGFjdHVhbCA9IG9iai5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKVxuICAgICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICAgICEhYWN0dWFsLmxlbmd0aFxuICAgICAgICAgICAgLCAnZXhwZWN0ZWQgJyArIGVsVG9TdHJpbmcob2JqKSArICcgdG8gaGF2ZSBkZXNjZW5kYW50cyAje2V4cH0nXG4gICAgICAgICAgICAsICdleHBlY3RlZCAnICsgZWxUb1N0cmluZyhvYmopICsgJyB0byBub3QgaGF2ZSBkZXNjZW5kYW50cyAje2V4cH0nXG4gICAgICAgICAgICAsIHNlbGVjdG9yKVxuICAgICAgICBmbGFnKHRoaXMsICdvYmplY3QnLCBhY3R1YWwpXG4gICAgfSlcblxuICAgIGNoYWkuQXNzZXJ0aW9uLmFkZFByb3BlcnR5KCdkaXNwbGF5ZWQnLCBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGVsID0gZmxhZyh0aGlzLCAnb2JqZWN0JyksXG4gICAgICAgICAgICBhY3R1YWwgPSBkb2N1bWVudC5ib2R5LmNvbnRhaW5zKGVsKSA/IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsKS5kaXNwbGF5IDogZWwuc3R5bGUuZGlzcGxheVxuXG4gICAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgICAgYWN0dWFsICE9PSAnbm9uZSdcbiAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKGVsKSArICcgdG8gYmUgZGlzcGxheWVkLCBidXQgaXQgd2FzIG5vdCdcbiAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKGVsKSArICcgdG8gbm90IGJlIGRpc3BsYXllZCwgYnV0IGl0IHdhcyBhcyAnICsgYWN0dWFsXG4gICAgICAgICAgICAsIGFjdHVhbFxuICAgICAgICApXG4gICAgfSlcblxuICAgIGNoYWkuQXNzZXJ0aW9uLmFkZFByb3BlcnR5KCd2aXNpYmxlJywgZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBlbCA9IGZsYWcodGhpcywgJ29iamVjdCcpLFxuICAgICAgICAgICAgYWN0dWFsID0gZG9jdW1lbnQuYm9keS5jb250YWlucyhlbCkgPyB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlbCkudmlzaWJpbGl0eSA6IGVsLnN0eWxlLnZpc2liaWxpdHlcblxuICAgICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICAgIGFjdHVhbCAhPT0gJ2hpZGRlbicgJiYgYWN0dWFsICE9PSAnY29sbGFwc2UnXG4gICAgICAgICAgICAsICdleHBlY3RlZCAnICsgZWxUb1N0cmluZyhlbCkgKyAnIHRvIGJlIHZpc2libGUsIGJ1dCBpdCB3YXMgJyArIChhY3R1YWwgPT09ICdoaWRkZW4nID8gJ2hpZGRlbicgOiAnY29sbGFwc2VkJylcbiAgICAgICAgICAgICwgJ2V4cGVjdGVkICcgKyBlbFRvU3RyaW5nKGVsKSArICcgdG8gbm90IGJlIHZpc2libGUsIGJ1dCBpdCB3YXMnXG4gICAgICAgICAgICAsIGFjdHVhbFxuICAgICAgICApXG4gICAgfSlcbn0iLCAiJ3VzZSBzdHJpY3QnO1xuXG5cbmxldCBhZGRlZE5vZGVzLCBtdXRhdGlvbm9ic2VydmVyO1xuXG5mdW5jdGlvbiBpbml0KCkge1xuXG4gICAgYWRkZWROb2RlcyA9IFtdO1xuICAgIG11dGF0aW9ub2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcihmdW5jdGlvbiAobXV0YXRpb25zKSB7XG4gICAgICAgIG11dGF0aW9ucy5mb3JFYWNoKGZ1bmN0aW9uIChtdXRhdGlvbikge1xuICAgICAgICAgICAgaWYgKG11dGF0aW9uLnR5cGUgPT09ICdjaGlsZExpc3QnICYmIG11dGF0aW9uLnJlbW92ZWROb2Rlcykge1xuXG4gICAgICAgICAgICAgICAgbXV0YXRpb24uYWRkZWROb2Rlcy5mb3JFYWNoKChuKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChuIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFkZGVkTm9kZXMucHVzaChuKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH0pO1xufVxuXG4vKipcbiAqXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbml0TXV0YXRpb25PYnNlcnZlckZvclRlc3RpbmcoKSB7XG5cbiAgICBpZiAobXV0YXRpb25vYnNlcnZlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGluaXQoKVxuICAgIH1cblxuICAgIG11dGF0aW9ub2JzZXJ2ZXIub2JzZXJ2ZShkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdoZWFkJyksIHtjaGlsZExpc3Q6IHRydWV9KTtcbn1cblxuLyoqXG4gKlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2xlYW51cERPTUZyb21UZXN0aW5nKCkge1xuICAgIG11dGF0aW9ub2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xuXG4gICAgZm9yIChjb25zdCBuIG9mIGFkZGVkTm9kZXMpIHtcbiAgICAgICAgbi5yZW1vdmUoKTtcbiAgICB9XG59IiwgIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IGNoYWkgZnJvbSBcImNoYWlcIlxuaW1wb3J0IHtMaW5rfSBmcm9tIFwiLi4vLi4vLi4vLi4vc291cmNlL2RvbS9yZXNvdXJjZS9saW5rLm1qc1wiO1xuaW1wb3J0IHtEYXRhVXJsfSBmcm9tIFwiLi4vLi4vLi4vLi4vc291cmNlL3R5cGVzL2RhdGF1cmwubWpzXCI7XG5pbXBvcnQge0lEfSBmcm9tIFwiLi4vLi4vLi4vLi4vc291cmNlL3R5cGVzL2lkLm1qc1wiO1xuaW1wb3J0IHtjaGFpRG9tfSBmcm9tIFwiLi4vLi4vLi4vdXRpbC9jaGFpLWRvbS5tanNcIjtcbmltcG9ydCB7Y2xlYW51cERPTUZyb21UZXN0aW5nLCBpbml0TXV0YXRpb25PYnNlcnZlckZvclRlc3Rpbmd9IGZyb20gXCIuLi8uLi8uLi91dGlsL2NsZWFudXBkb20ubWpzXCI7XG5pbXBvcnQge2luaXRKU0RPTX0gZnJvbSBcIi4uLy4uLy4uL3V0aWwvanNkb20ubWpzXCI7XG5cbmxldCBleHBlY3QgPSBjaGFpLmV4cGVjdDtcblxuY2hhaS51c2UoY2hhaURvbSk7XG5cblxuXG5kZXNjcmliZSgnTGluaycsIGZ1bmN0aW9uICgpIHtcblxuICAgIGJlZm9yZShmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICBpbml0SlNET00oKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgICBpbml0TXV0YXRpb25PYnNlcnZlckZvclRlc3RpbmcoKVxuICAgIH0pXG5cbiAgICBhZnRlckVhY2goKCkgPT4ge1xuICAgICAgICBjbGVhbnVwRE9NRnJvbVRlc3RpbmcoKTtcbiAgICB9KVxuXG4gICAgZGVzY3JpYmUoJ0xpbmsoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy50aW1lb3V0KDUwMDApO1xuXG4gICAgICAgIGl0KCdjb25uZWN0KCkuYXZhaWxhYmxlKCknLCBmdW5jdGlvbiAoZG9uZSkge1xuXG4gICAgICAgICAgICBjb25zdCBsaW5rID0gbmV3IExpbmsoe1xuICAgICAgICAgICAgICAgIGhyZWY6IG5ldyBEYXRhVXJsKCcnLCAndGV4dC9jc3MnKS50b1N0cmluZygpLFxuICAgICAgICAgICAgICAgIHJlbDogJ3N0eWxlc2hlZXQnXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgbGluay5jb25uZWN0KCkuYXZhaWxhYmxlKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgZG9uZSgpXG4gICAgICAgICAgICB9KS5jYXRjaChlID0+IGRvbmUoZSkpO1xuXG4gICAgICAgIH0pXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnRXh0ZXJuYWwgTGluaycsICgpID0+IHtcbiAgICAgICAgdGhpcy50aW1lb3V0KDUwMDApO1xuXG4gICAgICAgIGxldCBpZCA9IG5ldyBJRCgnbGluaycpLnRvU3RyaW5nKCk7XG4gICAgICAgIGxldCBsaW5rLCB1cmwgPSAnaHR0cHM6Ly9tb25zdGVyanMub3JnL2Fzc2V0cy9lbXB0eS5jc3M/JyArIGlkO1xuXG4gICAgICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuXG4gICAgICAgICAgICBsaW5rID0gbmV3IExpbmsoe1xuICAgICAgICAgICAgICAgIGhyZWY6IHVybCxcbiAgICAgICAgICAgICAgICBpZDogaWQsXG4gICAgICAgICAgICAgICAgcmVsOiAnc3R5bGVzaGVldCdcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdhcHBlbmQgYW5kIHJlbW92ZSBMaW5rICcsIChkb25lKSA9PiB7XG5cbiAgICAgICAgICAgIGV4cGVjdChsaW5rLmlzQ29ubmVjdGVkKCkpLnRvLmJlLmZhbHNlO1xuXG4gICAgICAgICAgICBsaW5rLmNvbm5lY3QoKS5hdmFpbGFibGUoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICBleHBlY3QobGluay5pc0Nvbm5lY3RlZCgpKS50by5iZS50cnVlO1xuICAgICAgICAgICAgICAgIGV4cGVjdChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbaHJlZj1cIicgKyB1cmwgKyAnXCJdJykpLnRvLmV4aXN0O1xuXG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpLnJlbW92ZSgpO1xuICAgICAgICAgICAgICAgIGV4cGVjdChsaW5rLmlzQ29ubmVjdGVkKCkpLnRvLmJlLmZhbHNlO1xuICAgICAgICAgICAgICAgIGV4cGVjdChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbaHJlZj1cIicgKyB1cmwgKyAnXCJdJykpLm5vdC50by5leGlzdDtcblxuICAgICAgICAgICAgICAgIGxpbmsuY29ubmVjdCgpLmF2YWlsYWJsZSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QobGluay5pc0Nvbm5lY3RlZCgpKS50by5iZS50cnVlO1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW2hyZWY9XCInICsgdXJsICsgJ1wiXScpKS50by5leGlzdDtcblxuICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkucmVtb3ZlKCk7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbaHJlZj1cIicgKyB1cmwgKyAnXCJdJykpLm5vdC50by5leGlzdDtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KGxpbmsuaXNDb25uZWN0ZWQoKSkudG8uYmUuZmFsc2U7XG5cbiAgICAgICAgICAgICAgICAgICAgZG9uZSgpXG4gICAgICAgICAgICAgICAgfSkuY2F0Y2goZSA9PiBkb25lKGUpKTtcblxuXG4gICAgICAgICAgICB9KS5jYXRjaChlID0+IGRvbmUoZSkpO1xuXG5cbiAgICAgICAgfSk7XG5cblxuICAgIH0pO1xuXG5cbn0pOyIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGV4dGVuZCB9IGZyb20gXCIuLi8uLi9kYXRhL2V4dGVuZC5tanNcIjtcbmltcG9ydCB7XG4gICAgQVRUUklCVVRFX0NMQVNTLFxuICAgIEFUVFJJQlVURV9JRCxcbiAgICBBVFRSSUJVVEVfTk9OQ0UsXG4gICAgQVRUUklCVVRFX1NSQyxcbiAgICBBVFRSSUJVVEVfVElUTEUsXG4gICAgQVRUUklCVVRFX1RZUEUsXG4gICAgVEFHX1NDUklQVCxcbn0gZnJvbSBcIi4uL2NvbnN0YW50cy5tanNcIjtcbmltcG9ydCB7IEtFWV9ET0NVTUVOVCwgcmVmZXJlbmNlU3ltYm9sLCBSZXNvdXJjZSB9IGZyb20gXCIuLi9yZXNvdXJjZS5tanNcIjtcbmltcG9ydCB7IGluc3RhbmNlU3ltYm9sIH0gZnJvbSBcIi4uLy4uL2NvbnN0YW50cy5tanNcIjtcbmV4cG9ydCB7IFNjcmlwdCB9O1xuXG4vKipcbiAqIFRoaXMgY2xhc3MgaXMgdXNlZCBieSB0aGUgcmVzb3VyY2UgbWFuYWdlciB0byBlbWJlZCBzY3JpcHRzLlxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjUuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRPTS5SZXNvdXJjZVxuICogQHN1bW1hcnkgQSBSZXNvdXJjZSBjbGFzc1xuICovXG5jbGFzcyBTY3JpcHQgZXh0ZW5kcyBSZXNvdXJjZSB7XG4gICAgLyoqXG4gICAgICogQHByb3BlcnR5IHtib29sZWFufSBhc3luYz10cnVlIHtAbGluayBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVE1ML0VsZW1lbnQvc2NyaXB0I2F0dHItYXN5bmN9XG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd9IGNyb3NzT3JpZ2luPWFub255bW91cyB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9FbGVtZW50L3NjcmlwdCNhdHRyLWNyb3Nzb3JpZ2lufVxuICAgICAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gZGVmZXI9ZmFsc2Uge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUTUwvRWxlbWVudC9zY3JpcHQjYXR0ci1kZWZlcn1cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gaW50ZWdyaXR5IHtAbGluayBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVE1ML0VsZW1lbnQvc2NyaXB0I2F0dHItaW50ZWdyaXR5fVxuICAgICAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gbm9tb2R1bGUge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUTUwvRWxlbWVudC9zY3JpcHQjYXR0ci1ub21vZHVsZX1cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gbm9uY2Uge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUTUwvRWxlbWVudC9zY3JpcHQjYXR0ci1ub25jZX1cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gcmVmZXJyZXJwb2xpY3kge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUTUwvRWxlbWVudC9zY3JpcHQjYXR0ci1yZWZlcnJlcnBvbGljeX1cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gdHlwZSB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9FbGVtZW50L3NjcmlwdCNhdHRyLXR5cGV9XG4gICAgICovXG4gICAgZ2V0IGRlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gZXh0ZW5kKHt9LCBzdXBlci5kZWZhdWx0cywge1xuICAgICAgICAgICAgYXN5bmM6IHRydWUsXG4gICAgICAgICAgICBjcm9zc09yaWdpbjogXCJhbm9ueW1vdXNcIixcbiAgICAgICAgICAgIGRlZmVyOiBmYWxzZSxcbiAgICAgICAgICAgIGludGVncml0eTogdW5kZWZpbmVkLFxuICAgICAgICAgICAgbm9tb2R1bGU6IGZhbHNlLFxuICAgICAgICAgICAgbm9uY2U6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHJlZmVycmVycG9saWN5OiB1bmRlZmluZWQsXG4gICAgICAgICAgICB0eXBlOiBcInRleHQvamF2YXNjcmlwdFwiLFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGBpbnN0YW5jZW9mYCBvcGVyYXRvci5cbiAgICAgKiBAcmV0dXJucyB7c3ltYm9sfVxuICAgICAqIEBzaW5jZSAyLjEuMFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgW2luc3RhbmNlU3ltYm9sXSgpIHtcbiAgICAgICAgcmV0dXJuIFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL2RvbS9yZXNvdXJjZS9zY3JpcHRcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtNb25zdGVyLkRPTS5SZXNvdXJjZS5TY3JpcHR9XG4gICAgICovXG4gICAgY3JlYXRlKCkge1xuICAgICAgICBjcmVhdGVFbGVtZW50LmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge3N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0VVJMQXR0cmlidXRlKCkge1xuICAgICAgICByZXR1cm4gQVRUUklCVVRFX1NSQztcbiAgICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEByZXR1cm4ge01vbnN0ZXIuRE9NLlJlc291cmNlLlNjcmlwdH1cbiAqL1xuZnVuY3Rpb24gY3JlYXRlRWxlbWVudCgpIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgIGNvbnN0IGRvY3VtZW50ID0gc2VsZi5nZXRPcHRpb24oS0VZX0RPQ1VNRU5UKTtcbiAgICBzZWxmW3JlZmVyZW5jZVN5bWJvbF0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFRBR19TQ1JJUFQpO1xuXG4gICAgZm9yIChsZXQga2V5IG9mIFtcbiAgICAgICAgXCJjcm9zc09yaWdpblwiLFxuICAgICAgICBcImRlZmVyXCIsXG4gICAgICAgIFwiYXN5bmNcIixcbiAgICAgICAgXCJpbnRlZ3JpdHlcIixcbiAgICAgICAgXCJub21vZHVsZVwiLFxuICAgICAgICBBVFRSSUJVVEVfTk9OQ0UsXG4gICAgICAgIFwicmVmZXJyZXJwb2xpY3lcIixcbiAgICAgICAgQVRUUklCVVRFX1RZUEUsXG4gICAgICAgIEFUVFJJQlVURV9TUkMsXG4gICAgICAgIEFUVFJJQlVURV9JRCxcbiAgICAgICAgQVRUUklCVVRFX0NMQVNTLFxuICAgICAgICBBVFRSSUJVVEVfVElUTEUsXG4gICAgXSkge1xuICAgICAgICBpZiAoc2VsZi5nZXRPcHRpb24oa2V5KSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBzZWxmW3JlZmVyZW5jZVN5bWJvbF1ba2V5XSA9IHNlbGYuZ2V0T3B0aW9uKGtleSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gc2VsZjtcbn1cbiIsICIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBjaGFpIGZyb20gXCJjaGFpXCJcbmltcG9ydCB7U2NyaXB0fSBmcm9tIFwiLi4vLi4vLi4vLi4vc291cmNlL2RvbS9yZXNvdXJjZS9zY3JpcHQubWpzXCI7XG5pbXBvcnQge0RhdGFVcmx9IGZyb20gXCIuLi8uLi8uLi8uLi9zb3VyY2UvdHlwZXMvZGF0YXVybC5tanNcIjtcbmltcG9ydCB7SUR9IGZyb20gXCIuLi8uLi8uLi8uLi9zb3VyY2UvdHlwZXMvaWQubWpzXCI7XG5pbXBvcnQge2NoYWlEb219IGZyb20gXCIuLi8uLi8uLi91dGlsL2NoYWktZG9tLm1qc1wiO1xuaW1wb3J0IHtjbGVhbnVwRE9NRnJvbVRlc3RpbmcsIGluaXRNdXRhdGlvbk9ic2VydmVyRm9yVGVzdGluZ30gZnJvbSBcIi4uLy4uLy4uL3V0aWwvY2xlYW51cGRvbS5tanNcIjtcbmltcG9ydCB7aW5pdEpTRE9NfSBmcm9tIFwiLi4vLi4vLi4vdXRpbC9qc2RvbS5tanNcIjtcblxubGV0IGV4cGVjdCA9IGNoYWkuZXhwZWN0O1xuXG5jaGFpLnVzZShjaGFpRG9tKTtcblxubGV0IGh0bWwxID0gYFxuXG5gO1xuXG5cbmRlc2NyaWJlKCdTY3JpcHQnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBiZWZvcmUoZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgaW5pdEpTRE9NKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICBkb25lKClcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAgaW5pdE11dGF0aW9uT2JzZXJ2ZXJGb3JUZXN0aW5nKClcbiAgICB9KVxuXG4gICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgICAgY2xlYW51cERPTUZyb21UZXN0aW5nKCk7XG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCdTY3JpcHQoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3NldEV2ZW50VHlwZXMoKScsIGZ1bmN0aW9uIChkb25lKSB7XG5cbiAgICAgICAgICAgIGNvbnN0IHNjcmlwdCA9IG5ldyBTY3JpcHQoe1xuICAgICAgICAgICAgICAgIHNyYzogbmV3IERhdGFVcmwoJycsICd0ZXh0L2phdmFzY3JpcHQnKS50b1N0cmluZygpLFxuICAgICAgICAgICAgICAgIGFzeW5jOiB0cnVlLFxuICAgICAgICAgICAgICAgIGNyb3NzT3JpZ2luOiAnYW5vbnltb3VzJyxcbiAgICAgICAgICAgICAgICBkZWZlcjogZmFsc2UsXG4gICAgICAgICAgICAgICAgaW50ZWdyaXR5OiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgbm9tb2R1bGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIG5vbmNlOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgcmVmZXJyZXJwb2xpY3k6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICB0eXBlOiAndGV4dC9qYXZhc2NyaXB0J1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHNjcmlwdC5jb25uZWN0KCkuYXZhaWxhYmxlKCkudGhlbigoKSA9PiB7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBpZCA9IHNjcmlwdC5nZXRPcHRpb24oJ2lkJylcbiAgICAgICAgICAgICAgICBkb25lKClcbiAgICAgICAgICAgIH0pLmNhdGNoKGUgPT4gZG9uZShlKSk7XG5cbiAgICAgICAgfSlcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdFeHRlcm5hbCBKUycsICgpID0+IHtcblxuICAgICAgICBsZXQgaWQgPSBuZXcgSUQoJ3NjcmlwdCcpLnRvU3RyaW5nKCk7XG4gICAgICAgIGxldCBzZXJ2ZXIsIHNjcmlwdCwgdXJsID0gJ2h0dHBzOi8vbW9uc3RlcmpzLm9yZy9hc3NldHMvZW1wdHkuanM/JyArIGlkO1xuXG4gICAgICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuXG4gICAgICAgICAgICBzY3JpcHQgPSBuZXcgU2NyaXB0KHtcbiAgICAgICAgICAgICAgICBzcmM6IHVybCxcbiAgICAgICAgICAgICAgICBhc3luYzogdHJ1ZSxcbiAgICAgICAgICAgICAgICBjcm9zc09yaWdpbjogJ2Fub255bW91cycsXG4gICAgICAgICAgICAgICAgZGVmZXI6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGludGVncml0eTogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgIG5vbW9kdWxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBub25jZTogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgIHJlZmVycmVycG9saWN5OiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgdHlwZTogJ3RleHQvamF2YXNjcmlwdCcsXG4gICAgICAgICAgICAgICAgaWQ6IGlkXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnYXBwZW5kIGFuZCByZW1vdmUgc2NyaXB0ICcsIChkb25lKSA9PiB7XG5cbiAgICAgICAgICAgIGV4cGVjdChzY3JpcHQuaXNDb25uZWN0ZWQoKSkudG8uYmUuZmFsc2U7XG5cbiAgICAgICAgICAgIHNjcmlwdC5jb25uZWN0KCkuYXZhaWxhYmxlKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KHNjcmlwdC5pc0Nvbm5lY3RlZCgpKS50by5iZS50cnVlO1xuICAgICAgICAgICAgICAgIGV4cGVjdChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbc3JjPVwiJyArIHVybCArICdcIl0nKSkudG8uZXhpc3Q7XG5cbiAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkucmVtb3ZlKCk7XG4gICAgICAgICAgICAgICAgZXhwZWN0KHNjcmlwdC5pc0Nvbm5lY3RlZCgpKS50by5iZS5mYWxzZTtcbiAgICAgICAgICAgICAgICBleHBlY3QoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW3NyYz1cIicgKyB1cmwgKyAnXCJdJykpLm5vdC50by5leGlzdDtcblxuICAgICAgICAgICAgICAgIHNjcmlwdC5jb25uZWN0KCkuYXZhaWxhYmxlKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChzY3JpcHQuaXNDb25uZWN0ZWQoKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ1tzcmM9XCInICsgdXJsICsgJ1wiXScpKS50by5leGlzdDtcblxuICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkucmVtb3ZlKCk7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbc3JjPVwiJyArIHVybCArICdcIl0nKSkubm90LnRvLmV4aXN0O1xuICAgICAgICAgICAgICAgICAgICBleHBlY3Qoc2NyaXB0LmlzQ29ubmVjdGVkKCkpLnRvLmJlLmZhbHNlO1xuXG4gICAgICAgICAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICAgICAgICAgIH0pLmNhdGNoKGUgPT4gZG9uZShlKSk7XG5cblxuICAgICAgICAgICAgfSkuY2F0Y2goZSA9PiBkb25lKGUpKTtcblxuXG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxuXG59KTsiLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBpbnRlcm5hbFN0YXRlU3ltYm9sIH0gZnJvbSBcIi4uLy4uL2NvbnN0YW50cy5tanNcIjtcbmltcG9ydCB7IGV4dGVuZCB9IGZyb20gXCIuLi8uLi9kYXRhL2V4dGVuZC5tanNcIjtcbmltcG9ydCB7IGdldEdsb2JhbEZ1bmN0aW9uIH0gZnJvbSBcIi4uLy4uL3R5cGVzL2dsb2JhbC5tanNcIjtcbmltcG9ydCB7XG4gICAgQVRUUklCVVRFX0NMQVNTLFxuICAgIEFUVFJJQlVURV9FUlJPUk1FU1NBR0UsXG4gICAgQVRUUklCVVRFX0lELFxuICAgIEFUVFJJQlVURV9TUkMsXG4gICAgQVRUUklCVVRFX1RJVExFLFxuICAgIEFUVFJJQlVURV9UWVBFLFxuICAgIFRBR19TQ1JJUFQsXG59IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQgeyBLRVlfRE9DVU1FTlQsIEtFWV9RVUVSWSwgcmVmZXJlbmNlU3ltYm9sLCBSZXNvdXJjZSB9IGZyb20gXCIuLi9yZXNvdXJjZS5tanNcIjtcbmltcG9ydCB7IGluc3RhbmNlU3ltYm9sIH0gZnJvbSBcIi4uLy4uL2NvbnN0YW50cy5tanNcIjtcbmV4cG9ydCB7IERhdGEgfTtcblxuLyoqXG4gKiBUaGlzIGNsYXNzIGlzIHVzZWQgYnkgdGhlIHJlc291cmNlIG1hbmFnZXIgdG8gZW1iZWQgZGF0YS5cbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI1LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET00uUmVzb3VyY2VcbiAqIEBzdW1tYXJ5IEEgRGF0YSBSZXNvdXJjZSBjbGFzc1xuICovXG5jbGFzcyBEYXRhIGV4dGVuZHMgUmVzb3VyY2Uge1xuICAgIC8qKlxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBtb2RlPWNvcnMgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL2ZldGNoXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd9IGNyZWRlbnRpYWxzPXNhbWUtb3JpZ2luIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9mZXRjaFxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB0eXBlPWFwcGxpY2F0aW9uL2pzb24ge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUTUwvRWxlbWVudC9zY3JpcHQjYXR0ci10eXBlfVxuICAgICAqL1xuICAgIGdldCBkZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIGV4dGVuZCh7fSwgc3VwZXIuZGVmYXVsdHMsIHtcbiAgICAgICAgICAgIG1vZGU6IFwiY29yc1wiLFxuICAgICAgICAgICAgY3JlZGVudGlhbHM6IFwic2FtZS1vcmlnaW5cIixcbiAgICAgICAgICAgIHR5cGU6IFwiYXBwbGljYXRpb24vanNvblwiLFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEByZXR1cm4ge01vbnN0ZXIuRE9NLlJlc291cmNlLkRhdGF9XG4gICAgICovXG4gICAgY3JlYXRlKCkge1xuICAgICAgICBjcmVhdGVFbGVtZW50LmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGFwcGVuZHMgdGhlIEhUTUxFbGVtZW50IHRvIHRoZSBzcGVjaWZpZWQgZG9jdW1lbnRcbiAgICAgKlxuICAgICAqIHRocm93cyB7RXJyb3J9IHRhcmdldCBub3QgZm91bmRcbiAgICAgKiBAcmV0dXJuIHtNb25zdGVyLkRPTS5SZXNvdXJjZX1cbiAgICAgKi9cbiAgICBjb25uZWN0KCkge1xuICAgICAgICBpZiAoISh0aGlzW3JlZmVyZW5jZVN5bWJvbF0gaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpIHtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRlKCk7XG4gICAgICAgIH1cblxuICAgICAgICBhcHBlbmRUb0RvY3VtZW50LmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgYGluc3RhbmNlb2ZgIG9wZXJhdG9yLlxuICAgICAqIEByZXR1cm5zIHtzeW1ib2x9XG4gICAgICogQHNpbmNlIDIuMS4wXG4gICAgICovXG4gICAgc3RhdGljIGdldCBbaW5zdGFuY2VTeW1ib2xdKCkge1xuICAgICAgICByZXR1cm4gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvZG9tL3Jlc291cmNlL2RhdGFcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7c3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRVUkxBdHRyaWJ1dGUoKSB7XG4gICAgICAgIHJldHVybiBBVFRSSUJVVEVfU1JDO1xuICAgIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHJldHVybiB7TW9uc3Rlci5ET00uUmVzb3VyY2UuRGF0YX1cbiAqL1xuZnVuY3Rpb24gY3JlYXRlRWxlbWVudCgpIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgIGNvbnN0IGRvY3VtZW50ID0gc2VsZi5nZXRPcHRpb24oS0VZX0RPQ1VNRU5UKTtcbiAgICBzZWxmW3JlZmVyZW5jZVN5bWJvbF0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFRBR19TQ1JJUFQpO1xuXG4gICAgZm9yIChsZXQga2V5IG9mIFtBVFRSSUJVVEVfVFlQRSwgQVRUUklCVVRFX0lELCBBVFRSSUJVVEVfQ0xBU1MsIEFUVFJJQlVURV9USVRMRV0pIHtcbiAgICAgICAgaWYgKHNlbGYuZ2V0T3B0aW9uKGtleSkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgc2VsZltyZWZlcmVuY2VTeW1ib2xdW2tleV0gPSBzZWxmLmdldE9wdGlvbihrZXkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHNlbGY7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEByZXR1cm4ge1Byb21pc2V9XG4gKiB0aHJvd3Mge0Vycm9yfSB0YXJnZXQgbm90IGZvdW5kXG4gKi9cbmZ1bmN0aW9uIGFwcGVuZFRvRG9jdW1lbnQoKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICBjb25zdCB0YXJnZXROb2RlID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihzZWxmLmdldE9wdGlvbihLRVlfUVVFUlksIFwiaGVhZFwiKSk7XG4gICAgaWYgKCEodGFyZ2V0Tm9kZSBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0YXJnZXQgbm90IGZvdW5kXCIpO1xuICAgIH1cblxuICAgIHRhcmdldE5vZGUuYXBwZW5kQ2hpbGQoc2VsZltyZWZlcmVuY2VTeW1ib2xdKTtcblxuICAgIGdldEdsb2JhbEZ1bmN0aW9uKFwiZmV0Y2hcIikoc2VsZi5nZXRPcHRpb24oQVRUUklCVVRFX1NSQyksIHtcbiAgICAgICAgbWV0aG9kOiBcIkdFVFwiLCAvLyAqR0VULCBQT1NULCBQVVQsIERFTEVURSwgZXRjLlxuICAgICAgICBtb2RlOiBzZWxmLmdldE9wdGlvbihcIm1vZGVcIiwgXCJjb3JzXCIpLCAvLyBuby1jb3JzLCAqY29ycywgc2FtZS1vcmlnaW5cbiAgICAgICAgY2FjaGU6IFwibm8tY2FjaGVcIiwgLy8gKmRlZmF1bHQsIG5vLWNhY2hlLCByZWxvYWQsIGZvcmNlLWNhY2hlLCBvbmx5LWlmLWNhY2hlZFxuICAgICAgICBjcmVkZW50aWFsczogc2VsZi5nZXRPcHRpb24oXCJjcmVkZW50aWFsc1wiLCBcInNhbWUtb3JpZ2luXCIpLCAvLyBpbmNsdWRlLCAqc2FtZS1vcmlnaW4sIG9taXRcbiAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgQWNjZXB0OiBzZWxmLmdldE9wdGlvbihcInR5cGVcIiwgXCJhcHBsaWNhdGlvbi9qc29uXCIpLFxuICAgICAgICB9LFxuICAgICAgICByZWRpcmVjdDogXCJmb2xsb3dcIiwgLy8gbWFudWFsLCAqZm9sbG93LCBlcnJvclxuICAgICAgICByZWZlcnJlclBvbGljeTogXCJuby1yZWZlcnJlclwiLCAvLyBuby1yZWZlcnJlcixcbiAgICB9KVxuICAgICAgICAudGhlbigocmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgIHJldHVybiByZXNwb25zZS50ZXh0KCk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKCh0ZXh0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0ZXh0Tm9kZSA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHRleHQpO1xuICAgICAgICAgICAgc2VsZltyZWZlcmVuY2VTeW1ib2xdLmFwcGVuZENoaWxkKHRleHROb2RlKTtcblxuICAgICAgICAgICAgc2VsZltpbnRlcm5hbFN0YXRlU3ltYm9sXS5nZXRTdWJqZWN0KClbXCJsb2FkZWRcIl0gPSB0cnVlO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIHNlbGZbaW50ZXJuYWxTdGF0ZVN5bWJvbF0uc2V0U3ViamVjdCh7XG4gICAgICAgICAgICAgICAgbG9hZGVkOiB0cnVlLFxuICAgICAgICAgICAgICAgIGVycm9yOiBlLnRvU3RyaW5nKCksXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgdGFyZ2V0Tm9kZS5zZXRBdHRyaWJ1dGUoQVRUUklCVVRFX0VSUk9STUVTU0FHRSwgZS50b1N0cmluZygpKTtcbiAgICAgICAgfSk7XG5cbiAgICByZXR1cm4gc2VsZjtcbn1cbiIsICIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBjaGFpIGZyb20gXCJjaGFpXCJcbmltcG9ydCB7RGF0YX0gZnJvbSBcIi4uLy4uLy4uLy4uL3NvdXJjZS9kb20vcmVzb3VyY2UvZGF0YS5tanNcIjtcbmltcG9ydCB7RGF0YVVybH0gZnJvbSBcIi4uLy4uLy4uLy4uL3NvdXJjZS90eXBlcy9kYXRhdXJsLm1qc1wiO1xuaW1wb3J0IHtJRH0gZnJvbSBcIi4uLy4uLy4uLy4uL3NvdXJjZS90eXBlcy9pZC5tanNcIjtcbmltcG9ydCB7Y2hhaURvbX0gZnJvbSBcIi4uLy4uLy4uL3V0aWwvY2hhaS1kb20ubWpzXCI7XG5pbXBvcnQge2NsZWFudXBET01Gcm9tVGVzdGluZywgaW5pdE11dGF0aW9uT2JzZXJ2ZXJGb3JUZXN0aW5nfSBmcm9tIFwiLi4vLi4vLi4vdXRpbC9jbGVhbnVwZG9tLm1qc1wiO1xuaW1wb3J0IHtpbml0SlNET019IGZyb20gXCIuLi8uLi8uLi91dGlsL2pzZG9tLm1qc1wiO1xuXG5sZXQgZXhwZWN0ID0gY2hhaS5leHBlY3Q7XG5cbmNoYWkudXNlKGNoYWlEb20pO1xuXG5sZXQgaHRtbDEgPSBgXG5cbmA7XG5cblxuZGVzY3JpYmUoJ0RhdGEnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBsZXQgZmV0Y2hSZWZlcmVuY2UsIHJldHVyblN0YXR1cywgbXV0YXRpb25vYnNlcnZlciwgYWRkZWROb2RlcyA9IFtdO1xuXG5cbiAgICBiZWZvcmUoZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgaW5pdEpTRE9NKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICBkb25lKClcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBiZWZvcmVFYWNoKCgpID0+IHtcblxuICAgICAgICBpbml0TXV0YXRpb25PYnNlcnZlckZvclRlc3RpbmcoKVxuXG4gICAgICAgIHJldHVyblN0YXR1cyA9IDIwMDtcbiAgICAgICAgZmV0Y2hSZWZlcmVuY2UgPSBnbG9iYWxUaGlzWydmZXRjaCddO1xuICAgICAgICBnbG9iYWxUaGlzWydmZXRjaCddID0gZnVuY3Rpb24gKHVybCwgb3B0aW9ucykge1xuXG4gICAgICAgICAgICBpZiAoIXVybCkgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHVybCcpXG5cbiAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZSh7XG4gICAgICAgICAgICAgICAgICAgIHRleHQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYTogXCJ0ZXN0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHN0YXR1czogcmV0dXJuU3RhdHVzXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KVxuXG4gICAgICAgIH07XG5cblxuICAgIH0pXG5cbiAgICBhZnRlckVhY2goKCkgPT4ge1xuICAgICAgICBnbG9iYWxUaGlzWydmZXRjaCddID0gZmV0Y2hSZWZlcmVuY2U7XG4gICAgICAgIGNsZWFudXBET01Gcm9tVGVzdGluZygpO1xuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnRGF0YSgpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2V0RXZlbnRUeXBlcygpJywgZnVuY3Rpb24gKGRvbmUpIHtcblxuICAgICAgICAgICAgY29uc3QgZGF0YSA9IG5ldyBEYXRhKHtcbiAgICAgICAgICAgICAgICBzcmM6IG5ldyBEYXRhVXJsKCcnLCAndGV4dC9qYXZhc2NyaXB0JykudG9TdHJpbmcoKVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGRhdGEuY29ubmVjdCgpLmF2YWlsYWJsZSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICAgICAgfSkuY2F0Y2goZSA9PiBkb25lKGUpKTtcblxuICAgICAgICB9KVxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ0V4dGVybmFsIERhdGEnLCAoKSA9PiB7XG5cbiAgICAgICAgbGV0IGlkID0gbmV3IElEKCdkYXRhJykudG9TdHJpbmcoKTtcbiAgICAgICAgbGV0IHNlcnZlciwgZGF0YSwgdXJsID0gJ2h0dHBzOi8vbW9uc3RlcmpzLm9yZy9hc3NldHMvZW1wdHkuanM/JyArIGlkO1xuXG4gICAgICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuXG4gICAgICAgICAgICBkYXRhID0gbmV3IERhdGEoe1xuICAgICAgICAgICAgICAgIHNyYzogdXJsLFxuICAgICAgICAgICAgICAgIGlkOiBpZFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ2RhdGEgaXMgbm90IGNvbm5lY3RlZCcsICgpID0+IHtcbiAgICAgICAgICAgIGV4cGVjdChkYXRhLmlzQ29ubmVjdGVkKCkpLnRvLmJlLmZhbHNlO1xuICAgICAgICB9KVxuXG4gICAgICAgIGl0KCdjb25uZWN0IGFuZCBjaGVjayBhdmFpbGFiaWxpdHknLCAoZG9uZSkgPT4ge1xuXG4gICAgICAgICAgICBkYXRhLmNvbm5lY3QoKS5hdmFpbGFibGUoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICBleHBlY3QoZGF0YS5pc0Nvbm5lY3RlZCgpLCAnaXNDb25uZWN0ZWQgMScpLnRvLmJlLnRydWU7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ1t0eXBlPVwiYXBwbGljYXRpb24vanNvblwiXScpLCAnZXhpc3RzIDEnKS50by5leGlzdDtcblxuICAgICAgICAgICAgICAgIGNvbnN0IGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkucGFyZW50RWxlbWVudDtcblxuXG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpLnJlbW92ZSgpO1xuXG4gICAgICAgICAgICAgICAgZXhwZWN0KGRhdGEuaXNDb25uZWN0ZWQoKSwgJ2lzQ29ubmVjdGVkIDInKS50by5iZS5mYWxzZTtcbiAgICAgICAgICAgICAgICBleHBlY3QoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW3R5cGU9XCJhcHBsaWNhdGlvbi9qc29uXCJdJyksICdleGlzdHMgMicpLm5vdC50by5leGlzdDtcblxuICAgICAgICAgICAgICAgIGRhdGEuY29ubmVjdCgpLmF2YWlsYWJsZSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QoZGF0YS5pc0Nvbm5lY3RlZCgpLCAnaXNDb25uZWN0ZWQgMycpLnRvLmJlLnRydWU7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbdHlwZT1cImFwcGxpY2F0aW9uL2pzb25cIl0nKSwgJ2V4aXN0cyAzJykudG8uZXhpc3Q7XG5cbiAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpLnJlbW92ZSgpO1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW3R5cGU9XCJhcHBsaWNhdGlvbi9qc29uXCJdJyksICdleGlzdHMgNCcpLm5vdC50by5leGlzdDtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KGRhdGEuaXNDb25uZWN0ZWQoKSwgJ2lzQ29ubmVjdGVkIDQnKS50by5iZS5mYWxzZTtcblxuICAgICAgICAgICAgICAgICAgICBkb25lKClcbiAgICAgICAgICAgICAgICB9KS5jYXRjaChlID0+IGRvbmUoZSkpO1xuXG5cbiAgICAgICAgICAgIH0pLmNhdGNoKGUgPT4gZG9uZShlKSk7XG5cblxuICAgICAgICB9KTtcblxuXG4gICAgfSk7XG5cblxufSk7IiwgImltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5cbmltcG9ydCB7aW5pdEpTRE9NfSBmcm9tIFwiLi4vLi4vLi4vdXRpbC9qc2RvbS5tanNcIjtcblxuZGVzY3JpYmUoJ2luaXRPcHRpb25zRnJvbUF0dHJpYnV0ZXMnLCAoKSA9PiB7XG4gICAgbGV0IGVsZW1lbnQ7XG4gICAgbGV0IG9wdGlvbnM7XG4gICAgbGV0IGluaXRPcHRpb25zRnJvbUF0dHJpYnV0ZXM7XG5cbiAgICBiZWZvcmUoIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICBpbml0SlNET00oKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIGltcG9ydChcIi4uLy4uLy4uLy4uL3NvdXJjZS9kb20vdXRpbC9pbml0LW9wdGlvbnMtZnJvbS1hdHRyaWJ1dGVzLm1qc1wiKS50aGVuKChtKSA9PiB7XG4gICAgICAgICAgICAgICAgaW5pdE9wdGlvbnNGcm9tQXR0cmlidXRlcyA9IG1bJ2luaXRPcHRpb25zRnJvbUF0dHJpYnV0ZXMnXTtcbiAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICB9KVxuICAgICAgICB9KVxuICAgIH0pO1xuXG4gICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICAgIG9wdGlvbnMgPSB7dXJsOiBcIlwiLCBrZXk6IHtzdWJrZXk6IFwiXCIsIGNhc2VTZW5zaXRpdmU6IHRydWV9fTtcbiAgICAgICAgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBpbml0aWFsaXplIG9wdGlvbnMgd2l0aCBtYXRjaGluZyBhdHRyaWJ1dGVzJywgKCkgPT4ge1xuICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgnZGF0YS1tb25zdGVyLW9wdGlvbi11cmwnLCAnaHR0cHM6Ly9leGFtcGxlLmNvbScpO1xuICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgnZGF0YS1tb25zdGVyLW9wdGlvbi1rZXktc3Via2V5JywgJ3Rlc3QnKTtcblxuICAgICAgICBjb25zdCByZXN1bHQgPSBpbml0T3B0aW9uc0Zyb21BdHRyaWJ1dGVzKGVsZW1lbnQsIG9wdGlvbnMpO1xuXG4gICAgICAgIGV4cGVjdChyZXN1bHQudXJsKS50by5lcXVhbCgnaHR0cHM6Ly9leGFtcGxlLmNvbScpO1xuICAgICAgICBleHBlY3QocmVzdWx0LmtleS5zdWJrZXkpLnRvLmVxdWFsKCd0ZXN0Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIG5vdCBtb2RpZnkgb3B0aW9ucyB3aXRob3V0IG1hdGNoaW5nIGF0dHJpYnV0ZXMnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGluaXRPcHRpb25zRnJvbUF0dHJpYnV0ZXMoZWxlbWVudCwgb3B0aW9ucyk7XG5cbiAgICAgICAgZXhwZWN0KHJlc3VsdC51cmwpLnRvLmVxdWFsKCcnKTtcbiAgICAgICAgZXhwZWN0KHJlc3VsdC5rZXkuc3Via2V5KS50by5lcXVhbCgnJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGlnbm9yZSBhdHRyaWJ1dGVzIHdpdGhvdXQgdGhlIGNvcnJlY3QgcHJlZml4JywgKCkgPT4ge1xuICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgnZGF0YS1zb21lLW9wdGlvbi11cmwnLCAnaHR0cHM6Ly9leGFtcGxlLmNvbScpO1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGluaXRPcHRpb25zRnJvbUF0dHJpYnV0ZXMoZWxlbWVudCwgb3B0aW9ucyk7XG5cbiAgICAgICAgZXhwZWN0KHJlc3VsdC51cmwpLnRvLmVxdWFsKCcnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaWdub3JlIGF0dHJpYnV0ZXMgd2l0aCBpbnZhbGlkIG9wdGlvbiBwYXRocycsICgpID0+IHtcbiAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2RhdGEtbW9uc3Rlci1vcHRpb24tbm9uZXhpc3RlbnQnLCAndmFsdWUnKTtcblxuICAgICAgICBjb25zdCByZXN1bHQgPSBpbml0T3B0aW9uc0Zyb21BdHRyaWJ1dGVzKGVsZW1lbnQsIG9wdGlvbnMpO1xuXG4gICAgICAgIGV4cGVjdChyZXN1bHQpLnRvLmRlZXAuZXF1YWwob3B0aW9ucyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGFwcGx5IG1hcHBpbmcgZm9yIGEgc2luZ2xlIGF0dHJpYnV0ZScsICgpID0+IHtcbiAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2RhdGEtbW9uc3Rlci1vcHRpb24tdXJsJywgJ2V4YW1wbGUnKTtcbiAgICAgICAgY29uc3QgbWFwcGluZyA9IHtcbiAgICAgICAgICAgICd1cmwnOiAodmFsdWUpID0+ICdodHRwczovLycgKyB2YWx1ZSArICcuY29tJ1xuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGluaXRPcHRpb25zRnJvbUF0dHJpYnV0ZXMoZWxlbWVudCwgb3B0aW9ucywgbWFwcGluZyk7XG5cbiAgICAgICAgZXhwZWN0KHJlc3VsdC51cmwpLnRvLmVxdWFsKCdodHRwczovL2V4YW1wbGUuY29tJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGFwcGx5IG1hcHBpbmcgZm9yIGEgbmVzdGVkIGF0dHJpYnV0ZScsICgpID0+IHtcbiAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2RhdGEtbW9uc3Rlci1vcHRpb24ta2V5LXN1YmtleScsICcxMjMnKTtcbiAgICAgICAgY29uc3QgbWFwcGluZyA9IHtcbiAgICAgICAgICAgICdrZXkuc3Via2V5JzogKHZhbHVlKSA9PiBwYXJzZUludCh2YWx1ZSwgMTApICogMlxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGluaXRPcHRpb25zRnJvbUF0dHJpYnV0ZXMoZWxlbWVudCwgb3B0aW9ucywgbWFwcGluZyk7XG5cbiAgICAgICAgZXhwZWN0KHJlc3VsdC5rZXkuc3Via2V5KS50by5lcXVhbChcIjI0NlwiKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYXBwbHkgbXVsdGlwbGUgbWFwcGluZ3MnLCAoKSA9PiB7XG4gICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdkYXRhLW1vbnN0ZXItb3B0aW9uLXVybCcsICdleGFtcGxlJyk7XG4gICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdkYXRhLW1vbnN0ZXItb3B0aW9uLWtleS1zdWJrZXknLCAnMTIzJyk7XG4gICAgICAgIGNvbnN0IG1hcHBpbmcgPSB7XG4gICAgICAgICAgICAndXJsJzogKHZhbHVlKSA9PiAnaHR0cHM6Ly8nICsgdmFsdWUgKyAnLmNvbScsXG4gICAgICAgICAgICAna2V5LnN1YmtleSc6ICh2YWx1ZSkgPT4gcGFyc2VJbnQodmFsdWUsIDEwKSAqIDJcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCByZXN1bHQgPSBpbml0T3B0aW9uc0Zyb21BdHRyaWJ1dGVzKGVsZW1lbnQsIG9wdGlvbnMsIG1hcHBpbmcpO1xuXG4gICAgICAgIGV4cGVjdChyZXN1bHQudXJsKS50by5lcXVhbCgnaHR0cHM6Ly9leGFtcGxlLmNvbScpO1xuICAgICAgICBleHBlY3QocmVzdWx0LmtleS5zdWJrZXkpLnRvLmVxdWFsKFwiMjQ2XCIpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBpZ25vcmUgbWFwcGluZ3MgZm9yIG5vbi1leGlzdGluZyBhdHRyaWJ1dGVzJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBtYXBwaW5nID0ge1xuICAgICAgICAgICAgJ3VybCc6ICh2YWx1ZSkgPT4gJ2h0dHBzOi8vJyArIHZhbHVlICsgJy5jb20nXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gaW5pdE9wdGlvbnNGcm9tQXR0cmlidXRlcyhlbGVtZW50LCBvcHRpb25zLCBtYXBwaW5nKTtcblxuICAgICAgICBleHBlY3QocmVzdWx0LnVybCkudG8uZXF1YWwoJycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBpZ25vcmUgbWFwcGluZ3MgZm9yIGludmFsaWQgb3B0aW9uIHBhdGhzJywgKCkgPT4ge1xuICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgnZGF0YS1tb25zdGVyLW9wdGlvbi1ub25leGlzdGVudCcsICd2YWx1ZScpO1xuICAgICAgICBjb25zdCBtYXBwaW5nID0ge1xuICAgICAgICAgICAgJ25vbmV4aXN0ZW50JzogKHZhbHVlKSA9PiB2YWx1ZSArICdiYXInXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gaW5pdE9wdGlvbnNGcm9tQXR0cmlidXRlcyhlbGVtZW50LCBvcHRpb25zLCBtYXBwaW5nKTtcblxuICAgICAgICBleHBlY3QocmVzdWx0KS50by5kZWVwLmVxdWFsKG9wdGlvbnMpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBhcHBseSBtYXBwaW5nIG9ubHkgdG8gc3BlY2lmaWVkIGF0dHJpYnV0ZXMnLCAoKSA9PiB7XG4gICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdkYXRhLW1vbnN0ZXItb3B0aW9uLXVybCcsICdleGFtcGxlJyk7XG4gICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdkYXRhLW1vbnN0ZXItb3B0aW9uLWtleS1zdWJrZXknLCAnMTIzJyk7XG4gICAgICAgIGNvbnN0IG1hcHBpbmcgPSB7XG4gICAgICAgICAgICAndXJsJzogKHZhbHVlKSA9PiAnaHR0cHM6Ly8nICsgdmFsdWUgKyAnLmNvbSdcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCByZXN1bHQgPSBpbml0T3B0aW9uc0Zyb21BdHRyaWJ1dGVzKGVsZW1lbnQsIG9wdGlvbnMsIG1hcHBpbmcpO1xuXG4gICAgICAgIGV4cGVjdChyZXN1bHQudXJsKS50by5lcXVhbCgnaHR0cHM6Ly9leGFtcGxlLmNvbScpO1xuICAgICAgICBleHBlY3QocmVzdWx0LmtleS5zdWJrZXkpLnRvLmVxdWFsKCcxMjMnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgbm90IGFwcGx5IG1hcHBpbmcgaWYgbm90IGEgZnVuY3Rpb24nLCAoKSA9PiB7XG4gICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdkYXRhLW1vbnN0ZXItb3B0aW9uLXVybCcsICdleGFtcGxlJyk7XG4gICAgICAgIGNvbnN0IG1hcHBpbmcgPSB7XG4gICAgICAgICAgICAndXJsJzogJ2h0dHBzOi8vZXhhbXBsZS5jb20nXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gaW5pdE9wdGlvbnNGcm9tQXR0cmlidXRlcyhlbGVtZW50LCBvcHRpb25zLCBtYXBwaW5nKTtcblxuICAgICAgICBleHBlY3QocmVzdWx0LnVybCkudG8uZXF1YWwoJ2V4YW1wbGUnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYXBwbHkgbWFwcGluZyB3aXRoIGN1c3RvbSBwcmVmaXgnLCAoKSA9PiB7XG4gICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdkYXRhLWN1c3RvbS1vcHRpb24tdXJsJywgJ2V4YW1wbGUnKTtcbiAgICAgICAgY29uc3QgbWFwcGluZyA9IHtcbiAgICAgICAgICAgICd1cmwnOiAodmFsdWUpID0+ICdodHRwczovLycgKyB2YWx1ZSArICcuY29tJ1xuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGluaXRPcHRpb25zRnJvbUF0dHJpYnV0ZXMoZWxlbWVudCwgb3B0aW9ucywgbWFwcGluZywgJ2RhdGEtY3VzdG9tLW9wdGlvbi0nKTtcblxuICAgICAgICBleHBlY3QocmVzdWx0LnVybCkudG8uZXF1YWwoJ2h0dHBzOi8vZXhhbXBsZS5jb20nKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgbm90IGFwcGx5IG1hcHBpbmcgd2l0aCBpbmNvcnJlY3QgY3VzdG9tIHByZWZpeCcsICgpID0+IHtcbiAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2RhdGEtY3VzdG9tLW9wdGlvbi11cmwnLCAnZXhhbXBsZScpO1xuICAgICAgICBjb25zdCBtYXBwaW5nID0ge1xuICAgICAgICAgICAgJ3VybCc6ICh2YWx1ZSkgPT4gJ2h0dHBzOi8vJyArIHZhbHVlICsgJy5jb20nXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gaW5pdE9wdGlvbnNGcm9tQXR0cmlidXRlcyhlbGVtZW50LCBvcHRpb25zLCBtYXBwaW5nKTtcblxuICAgICAgICBleHBlY3QocmVzdWx0LnVybCkudG8uZXF1YWwoJycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBhcHBseSBjYXNlIHNlbnNpdGl2ZSBtYXBwaW5nJywgKCkgPT4ge1xuICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgnZGF0YS1tb25zdGVyLW9wdGlvbi1rZXktY2FzZVNlbnNpdGl2ZScsICdmYWxzZScpO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBpbml0T3B0aW9uc0Zyb21BdHRyaWJ1dGVzKGVsZW1lbnQsIG9wdGlvbnMpO1xuXG4gICAgICAgIGV4cGVjdChyZXN1bHQua2V5LmNhc2VTZW5zaXRpdmUpLnRvLmVxdWFsKGZhbHNlKTtcbiAgICB9KTtcblxufSk7XG4iLCAiaW1wb3J0IHtleHBlY3R9IGZyb20gJ2NoYWknO1xuaW1wb3J0IHtleHRyYWN0S2V5c30gZnJvbSBcIi4uLy4uLy4uLy4uL3NvdXJjZS9kb20vdXRpbC9leHRyYWN0LWtleXMubWpzXCI7XG5cblxuZGVzY3JpYmUoJ2V4dHJhY3RLZXlzJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgZXh0cmFjdCBrZXlzIGZyb20gdGhlIGdpdmVuIG9iamVjdCcsICgpID0+IHtcbiAgICAgICAgY29uc3Qgb2JqID0ge1xuICAgICAgICAgICAgZmlyc3ROYW1lOiAnSm9obicsXG4gICAgICAgICAgICBsYXN0TmFtZTogJ0RvZScsXG4gICAgICAgICAgICBhZGRyZXNzOiB7XG4gICAgICAgICAgICAgICAgc3RyZWV0OiAnMTIzIE1haW4gU3QnLFxuICAgICAgICAgICAgICAgIGNpdHk6ICdOZXcgWW9yaycsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGV4cGVjdGVkID0gbmV3IE1hcChbXG4gICAgICAgICAgICBbJ2ZpcnN0bmFtZScsICdmaXJzdE5hbWUnXSxcbiAgICAgICAgICAgIFsnbGFzdG5hbWUnLCAnbGFzdE5hbWUnXSxcbiAgICAgICAgICAgIFsnYWRkcmVzcy1zdHJlZXQnLCAnYWRkcmVzcy5zdHJlZXQnXSxcbiAgICAgICAgICAgIFsnYWRkcmVzcy1jaXR5JywgJ2FkZHJlc3MuY2l0eSddLFxuICAgICAgICBdKTtcblxuICAgICAgICBjb25zdCByZXN1bHQgPSBleHRyYWN0S2V5cyhvYmopO1xuXG4gICAgICAgIGV4cGVjdChKU09OLnN0cmluZ2lmeShBcnJheS5mcm9tKHJlc3VsdCkpKS50by5lcXVhbChKU09OLnN0cmluZ2lmeShBcnJheS5mcm9tKGV4cGVjdGVkKSkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB1c2UgY3VzdG9tIGtleSBhbmQgdmFsdWUgc2VwYXJhdG9ycycsICgpID0+IHtcbiAgICAgICAgY29uc3Qgb2JqID0ge1xuICAgICAgICAgICAgZmlyc3ROYW1lOiAnSm9obicsXG4gICAgICAgICAgICBsYXN0TmFtZTogJ0RvZScsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgZXhwZWN0ZWQgPSBuZXcgTWFwKFtcbiAgICAgICAgICAgIFsncHJlZml4K2ZpcnN0bmFtZScsICdwcmVmaXgrZmlyc3ROYW1lJ10sXG4gICAgICAgICAgICBbJ3ByZWZpeCtsYXN0bmFtZScsICdwcmVmaXgrbGFzdE5hbWUnXSxcbiAgICAgICAgXSk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gZXh0cmFjdEtleXMob2JqLCAncHJlZml4JywgJysnLCAnKycpO1xuXG4gICAgICAgIGV4cGVjdChKU09OLnN0cmluZ2lmeShBcnJheS5mcm9tKHJlc3VsdCkpKS50by5lcXVhbChKU09OLnN0cmluZ2lmeShBcnJheS5mcm9tKGV4cGVjdGVkKSkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2NoZWNrIGlmIHZhbHVlIGlzIG51bGwnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IG9iaiA9IHtcbiAgICAgICAgICAgIGZpcnN0TmFtZTogJ0pvaG4nLFxuICAgICAgICAgICAgbGFzdE5hbWU6ICdEb2UnLFxuICAgICAgICAgICAgYWRkcmVzczogbnVsbCxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBleHBlY3RlZCA9IG5ldyBNYXAoW1xuICAgICAgICAgICAgWydmaXJzdG5hbWUnLCAnZmlyc3ROYW1lJ10sXG4gICAgICAgICAgICBbJ2xhc3RuYW1lJywgJ2xhc3ROYW1lJ10sXG4gICAgICAgICAgICBbJ2FkZHJlc3MnLCAnYWRkcmVzcyddLFxuICAgICAgICAgICAgXG4gICAgICAgIF0pO1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGV4dHJhY3RLZXlzKG9iaik7XG5cbiAgICAgICAgZXhwZWN0KEpTT04uc3RyaW5naWZ5KEFycmF5LmZyb20ocmVzdWx0KSkpLnRvLmVxdWFsKEpTT04uc3RyaW5naWZ5KEFycmF5LmZyb20oZXhwZWN0ZWQpKSk7XG4gICAgfSk7XG5cbiAgICAvLyBBZGQgbW9yZSB0ZXN0IGNhc2VzIGFzIG5lZWRlZFxufSk7XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBpbnRlcm5hbFN5bWJvbCB9IGZyb20gXCIuLi8uLi9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQgeyBCYXNlIH0gZnJvbSBcIi4uLy4uL3R5cGVzL2Jhc2UubWpzXCI7XG5pbXBvcnQgeyBnZXRHbG9iYWwsIGdldEdsb2JhbEZ1bmN0aW9uIH0gZnJvbSBcIi4uLy4uL3R5cGVzL2dsb2JhbC5tanNcIjtcbmltcG9ydCB7IGlzRnVuY3Rpb24gfSBmcm9tIFwiLi4vLi4vdHlwZXMvaXMubWpzXCI7XG5pbXBvcnQgeyB2YWxpZGF0ZUluc3RhbmNlLCB2YWxpZGF0ZVN0cmluZyB9IGZyb20gXCIuLi8uLi90eXBlcy92YWxpZGF0ZS5tanNcIjtcblxuZXhwb3J0IHsgRmFjdG9yeSB9O1xuXG4vKipcbiAqIEEgZmFjdG9yeSBmb3IgY3JlYXRpbmcgd29ya2VyIGluc3RhbmNlcy5cbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI1LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET00uV29ya2VyXG4gKiBAc3VtbWFyeSBBIHNtYWxsIGZhY3RvcnkgdG8gY3JlYXRlIHdvcmtlclxuICovXG5jbGFzcyBGYWN0b3J5IGV4dGVuZHMgQmFzZSB7XG4gICAgLyoqXG4gICAgICpcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpc1tpbnRlcm5hbFN5bWJvbF0gPSB7XG4gICAgICAgICAgICB3b3JrZXI6IG5ldyBXZWFrTWFwKCksXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHdvcmtlciBmcm9tIGEgVVJMXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xVUkx9IHVybFxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IG1lc3NhZ2VIYW5kbGVyXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gZXJyb3JIYW5kbGVyXG4gICAgICogQHJldHVybiB7V29ya2VyfVxuICAgICAqL1xuICAgIGNyZWF0ZUZyb21VUkwgPSBmdW5jdGlvbiAodXJsLCBtZXNzYWdlSGFuZGxlciwgZXJyb3JIYW5kbGVyKSB7XG4gICAgICAgIGlmICh1cmwgaW5zdGFuY2VvZiBVUkwpIHtcbiAgICAgICAgICAgIHVybCA9IHVybC50b1N0cmluZygpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgd29ya2VyQ2xhc3MgPSBnZXRHbG9iYWxGdW5jdGlvbihcIldvcmtlclwiKTtcbiAgICAgICAgdmFyIHdvcmtlciA9IG5ldyB3b3JrZXJDbGFzcyh2YWxpZGF0ZVN0cmluZyh1cmwpKTtcblxuICAgICAgICBpZiAoaXNGdW5jdGlvbihtZXNzYWdlSGFuZGxlcikpIHtcbiAgICAgICAgICAgIHdvcmtlci5vbm1lc3NhZ2UgPSAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlSGFuZGxlci5jYWxsKHdvcmtlciwgZXZlbnQpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc0Z1bmN0aW9uKGVycm9ySGFuZGxlcikpIHtcbiAgICAgICAgICAgIHdvcmtlci5vbmVycm9yID0gKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLmNhbGwod29ya2VyLCBldmVudCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHdvcmtlcjtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHdvcmtlciBmcm9tIGEgc2NyaXB0XG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gY29udGVudFxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IG1lc3NhZ2VIYW5kbGVyXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gZXJyb3JIYW5kbGVyXG4gICAgICogQHJldHVybiB7V29ya2VyfVxuICAgICAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZGUvZG9jcy9XZWIvQVBJL1VSTC9jcmVhdGVPYmplY3RVUkxcbiAgICAgKi9cbiAgICBjcmVhdGVGcm9tU2NyaXB0ID0gZnVuY3Rpb24gKGNvbnRlbnQsIG1lc3NhZ2VIYW5kbGVyLCBlcnJvckhhbmRsZXIpIHtcbiAgICAgICAgY29uc3QgYmxvYkZ1bmN0aW9uID0gbmV3IGdldEdsb2JhbEZ1bmN0aW9uKFwiQmxvYlwiKTtcbiAgICAgICAgY29uc3QgYmxvYiA9IG5ldyBibG9iRnVuY3Rpb24oW3ZhbGlkYXRlU3RyaW5nKGNvbnRlbnQpXSwge1xuICAgICAgICAgICAgdHlwZTogXCJzY3JpcHQvamF2YXNjcmlwdFwiLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCB1cmwgPSBnZXRHbG9iYWxGdW5jdGlvbihcIlVSTFwiKS5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgICAgIGNvbnN0IHdvcmtlciA9IHRoaXMuY3JlYXRlRnJvbVVSTCh1cmwsIG1lc3NhZ2VIYW5kbGVyLCBlcnJvckhhbmRsZXIpO1xuXG4gICAgICAgIHRoaXNbaW50ZXJuYWxTeW1ib2xdW1wid29ya2VyXCJdLnNldCh3b3JrZXIsIHVybCk7XG5cbiAgICAgICAgcmV0dXJuIHdvcmtlcjtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogVGVybWluYXRlIHRoZSB3b3JrZXIgYW5kIGNhbGwgcmV2b2tlT2JqZWN0VVJMIGlmIG5lY2Vzc2FyeS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB3b3JrZXJcbiAgICAgKiBAcmV0dXJuIHtNb25zdGVyLkRPTS5Xb3JrZXIuRmFjdG9yeX1cbiAgICAgKi9cbiAgICB0ZXJtaW5hdGUod29ya2VyKSB7XG4gICAgICAgIGNvbnN0IHdvcmtlckNsYXNzID0gZ2V0R2xvYmFsRnVuY3Rpb24oXCJXb3JrZXJcIik7XG4gICAgICAgIHZhbGlkYXRlSW5zdGFuY2Uod29ya2VyLCB3b3JrZXJDbGFzcyk7XG5cbiAgICAgICAgd29ya2VyLnRlcm1pbmF0ZSgpO1xuXG4gICAgICAgIGlmICh0aGlzW2ludGVybmFsU3ltYm9sXVtcIndvcmtlclwiXS5oYXMod29ya2VyKSkge1xuICAgICAgICAgICAgY29uc3QgdXJsID0gdGhpc1tpbnRlcm5hbFN5bWJvbF1bXCJ3b3JrZXJcIl0uZ2V0KHdvcmtlcik7XG4gICAgICAgICAgICBVUkwucmV2b2tlT2JqZWN0VVJMKHVybCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4iLCAiaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcblxuaW1wb3J0IHtGYWN0b3J5fSBmcm9tIFwiLi4vLi4vLi4vLi4vc291cmNlL2RvbS93b3JrZXIvZmFjdG9yeS5tanNcIjtcbmltcG9ydCB7Z2V0R2xvYmFsfSBmcm9tIFwiLi4vLi4vLi4vLi4vc291cmNlL3R5cGVzL2dsb2JhbC5tanNcIjtcbmltcG9ydCB7aW5pdEpTRE9NLCBpc05vZGV9IGZyb20gXCIuLi8uLi8uLi91dGlsL2pzZG9tLm1qc1wiO1xuXG5jb25zdCBnbG9iYWwgPSBnZXRHbG9iYWwoKTtcblxuZGVzY3JpYmUoJ1dvcmtlcicsIGZ1bmN0aW9uICgpIHtcblxuICAgIGJlZm9yZShmdW5jdGlvbiAoZG9uZSkge1xuXG4gICAgICAgIGlmIChpc05vZGUoKSkge1xuICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGdsb2JhbFsnVVJMJ10sICdjcmVhdGVPYmplY3RVUkwnLCB7XG4gICAgICAgICAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgdmFsdWU6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiL2V4YW1wbGUubWpzXCJcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICBnbG9iYWxbJ1dvcmtlciddID0gY2xhc3Mge1xuICAgICAgICAgICAgICAgIHRlcm1pbmF0ZSgpIHtcbiAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgb25lcnJvcigpIHtcbiAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgb25tZXNzYWdlKCkge1xuICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCBhID0gdHlwZW9mIGdsb2JhbFsnV29ya2VyJ107XG4gICAgICAgICAgICBsZXQgYTEgPSB0eXBlb2YgV29ya2VyO1xuXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBqc2RvbSA9IGluaXRKU0RPTSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICB9KTtcblxuXG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCdGYWN0b3J5JywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdjcmVhdGUgd29ya2VyJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBjb25zdCBmYWN0b3J5ID0gbmV3IEZhY3RvcnkoKTtcbiAgICAgICAgICAgIGNvbnN0IHdvcmtlciA9IGZhY3RvcnkuY3JlYXRlRnJvbVNjcmlwdCgnY29uc29sZS5sb2coXCJoZWxsbyB3b3JsZFwiKTsnKVxuICAgICAgICAgICAgZXhwZWN0KHdvcmtlcikuaXMuaW5zdGFuY2VvZihXb3JrZXIpO1xuXG4gICAgICAgICAgICBleHBlY3QoZmFjdG9yeS50ZXJtaW5hdGUod29ya2VyKSkuaXMuaW5zdGFuY2VvZihGYWN0b3J5KVxuXG5cbiAgICAgICAgfSk7XG5cbiAgICB9KTtcblxuXG59KTsiLCAiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgY2hhaSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge1VwZGF0ZXJ9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvZG9tL3VwZGF0ZXIubWpzXCI7XG5pbXBvcnQge0lEfSBmcm9tIFwiLi4vLi4vLi4vc291cmNlL3R5cGVzL2lkLm1qc1wiO1xuaW1wb3J0IHtPYnNlcnZlcn0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS90eXBlcy9vYnNlcnZlci5tanNcIjtcbmltcG9ydCB7UHJveHlPYnNlcnZlcn0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS90eXBlcy9wcm94eW9ic2VydmVyLm1qc1wiO1xuaW1wb3J0IHtjaGFpRG9tfSBmcm9tIFwiLi4vLi4vdXRpbC9jaGFpLWRvbS5tanNcIjtcbmltcG9ydCB7aW5pdEpTRE9NfSBmcm9tIFwiLi4vLi4vdXRpbC9qc2RvbS5tanNcIjtcblxubGV0IGV4cGVjdCA9IGNoYWkuZXhwZWN0O1xuXG5jaGFpLnVzZShjaGFpRG9tKTtcblxubGV0IGh0bWwxID0gYFxuICAgIDx0ZW1wbGF0ZSBpZD1cImN1cnJlbnRcIj5cbiAgICAgICAgPGxpIGRhdGEtbW9uc3Rlci1yZXBsYWNlPVwicGF0aDpjdXJyZW50IHwgdG9qc29uXCI+PC9saT5cbiAgICA8L3RlbXBsYXRlPlxuICAgIDxkaXYgaWQ9XCJ0ZXN0MVwiPlxuICAgICAgICA8dWwgZGF0YS1tb25zdGVyLWluc2VydD1cImN1cnJlbnQgcGF0aDphLmJcIj5cbiAgICAgICAgPC91bD5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGlkPVwidGVzdDJcIj5cbiAgICAgICAgPHVsIGRhdGEtbW9uc3Rlci1pbnNlcnQ9XCJjdXJyZW50IHBhdGg6YS5iIHwgZG9pdFwiPlxuICAgICAgICA8L3VsPlxuICAgIDwvZGl2PlxuICAgIDxkaXYgaWQ9XCJ0ZXN0M1wiPlxuICAgICAgICA8ZGl2IGRhdGEtbW9uc3Rlci1hdHRyaWJ1dGVzPVwiY2xhc3MgcGF0aDphLmJcIj5cbiAgICAgICAgICAgIDxpbnB1dCBkYXRhLW1vbnN0ZXItYXR0cmlidXRlcz1cInZhbHVlIHBhdGg6YS5jXCIgaWQ9XCJpbnB1dDFcIj5cbiAgICAgICAgICAgIDxpbnB1dCBkYXRhLW1vbnN0ZXItYXR0cmlidXRlcz1cImNoZWNrZWQgcGF0aDphLmNoZWNrYm94XCIgdHlwZT1cImNoZWNrYm94XCIgbmFtZT1cImNoZWNrYm94XCIgaWQ9XCJjaGVja2JveFwiPlxuICAgICAgICAgICAgPGlucHV0IGRhdGEtbW9uc3Rlci1hdHRyaWJ1dGVzPVwidmFsdWUgcGF0aDphLnRleHRcIiB0eXBlPVwidGV4dFwiIG5hbWU9XCJ0ZXh0XCIgaWQ9XCJ0ZXh0XCI+XG4gICAgICAgICAgICA8aW5wdXQgZGF0YS1tb25zdGVyLWF0dHJpYnV0ZXM9XCJjaGVja2VkIHBhdGg6YS5yYWRpb1wiIHR5cGU9XCJyYWRpb1wiIG5hbWU9XCJyYWRpb1wiIHZhbHVlPVwicjFcIiBpZD1cInJhZGlvXCI+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cInJhZGlvXCIgbmFtZT1cInJhZGlvXCIgdmFsdWU9XCJyMlwiIGlkPVwicjJcIj5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwicmFkaW9cIiBuYW1lPVwicmFkaW9cIiB2YWx1ZT1cInJ4XCIgaWQ9XCJyeFwiPlxuXG4gICAgICAgICAgICA8c2VsZWN0IGRhdGEtbW9uc3Rlci1hdHRyaWJ1dGVzPVwidmFsdWUgcGF0aDphLnNlbGVjdFwiIG5hbWU9XCJzZWxlY3RcIiBpZD1cInNlbGVjdFwiPlxuICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJvdGhlci12YWx1ZVwiPnZhbHVlMTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIDxvcHRpb24+dmFsdWUyPC9vcHRpb24+XG4gICAgICAgICAgICA8L3NlbGVjdD5cblxuICAgICAgICAgICAgPHNlbGVjdCBkYXRhLW1vbnN0ZXItYXR0cmlidXRlcz1cInZhbHVlIHBhdGg6YS5tdWx0aXNlbGVjdFwiIG5hbWU9XCJtdWx0aXNlbGVjdFwiIG11bHRpcGxlIGlkPVwibXVsdGlzZWxlY3RcIj5cbiAgICAgICAgICAgICAgICA8b3B0aW9uPnZhbHVlMTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIDxvcHRpb24+dmFsdWUyPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgPG9wdGlvbj52YWx1ZTM8L29wdGlvbj5cbiAgICAgICAgICAgICAgICA8b3B0aW9uPnZhbHVlNDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJvdGhlci12YWx1ZTVcIj52YWx1ZTU8L29wdGlvbj5cbiAgICAgICAgICAgIDwvc2VsZWN0PlxuXG4gICAgICAgICAgICA8dGV4dGFyZWEgbmFtZT1cInRleHRhcmVhXCIgaWQ9XCJ0ZXh0YXJlYVwiIGRhdGEtbW9uc3Rlci1hdHRyaWJ1dGVzPVwidmFsdWUgcGF0aDphLnRleHRhcmVhXCI+PC90ZXh0YXJlYT5cblxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cblxuYDtcblxubGV0IGh0bWwyID0gYFxuICAgIDxkaXYgaWQ9XCJ0ZXN0MVwiPlxuICAgICAgICA8ZGl2IGRhdGEtbW9uc3Rlci1yZXBsYWNlPVwicGF0aDp0ZXh0IHwgdG9sb3dlclwiPjwvZGl2PlxuICAgICAgICA8ZGl2IGRhdGEtbW9uc3Rlci1yZXBsYWNlPVwicGF0aDp0ZXh0IHwgY2FsbDpteWZvcm1hdHRlclwiPjwvZGl2PlxuICAgICAgICA8ZGl2IGRhdGEtbW9uc3Rlci1yZXBsYWNlPVwic3RhdGljOmhlbGxvXFxcXCBcIj48L2Rpdj5cbiAgICA8L2Rpdj5cbmA7XG5cbmxldCBodG1sMyA9IGBcblxuICAgIDx0ZW1wbGF0ZSBpZD1cIm15aW5uZXJpZFwiPlxuICAgICAgICA8c3BhbiBkYXRhLW1vbnN0ZXItcmVwbGFjZT1cInBhdGg6bXlpbm5lcmlkIHwgdG9qc29uXCI+PC9zcGFuPlxuICAgIDwvdGVtcGxhdGU+XG5cbiAgICA8dGVtcGxhdGUgaWQ9XCJteWlkXCI+XG4gICAgICAgIDxwIGRhdGEtbW9uc3Rlci1pbnNlcnQ9XCJteWlubmVyaWQgcGF0aDphLmJcIj48L3A+XG4gICAgPC90ZW1wbGF0ZT5cblxuICAgIDxkaXYgaWQ9XCJ0ZXN0MVwiPlxuICAgICAgICA8ZGl2IGRhdGEtbW9uc3Rlci1pbnNlcnQ9XCJteWlkIHBhdGg6YS5iXCI+PC9kaXY+XG4gICAgPC9kaXY+XG5cbmA7XG5cbmxldCBodG1sNCA9IGBcbiAgICA8ZGl2PlxuICAgICAgICA8Zm9ybSBpZD1cImZvcm0xXCI+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgdmFsdWU9XCJjaGVja2VkXCIgbmFtZT1cImNoZWNrYm94XCIgZGF0YS1tb25zdGVyLWJpbmQ9XCJwYXRoOnN0YXRlXCI+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBuYW1lPVwidGV4dFwiPlxuICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJyYWRpb1wiIG5hbWU9XCJyYWRpb1wiIHZhbHVlPVwicjFcIiBpZD1cInIxXCIgZGF0YS1tb25zdGVyLWJpbmQ9XCJwYXRoOnJhZGlvXCI+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cInJhZGlvXCIgbmFtZT1cInJhZGlvXCIgdmFsdWU9XCJyMlwiIGlkPVwicjJcIiBkYXRhLW1vbnN0ZXItYmluZD1cInBhdGg6cmFkaW9cIj5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwicmFkaW9cIiBuYW1lPVwicmFkaW9cIiB2YWx1ZT1cInJ4XCIgaWQ9XCJyeFwiIGRhdGEtY29tbWVudD1cIm5vdCBjYWxsZWQgYmVjYXVzZSBubyBiaW5kIGF0dHJpYnV0ZVwiPlxuICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJidXR0b25cIiBuYW1lPVwiYnV0dG9uXCI+XG5cbiAgICAgICAgICAgIDxzZWxlY3QgbmFtZT1cInNlbGVjdDFcIiBpZD1cInNlbGVjdDFcIiBkYXRhLW1vbnN0ZXItYmluZD1cInBhdGg6c2VsZWN0XCI+XG4gICAgICAgICAgICAgICAgPG9wdGlvbj52YWx1ZTE8L29wdGlvbj5cbiAgICAgICAgICAgICAgICA8b3B0aW9uPnZhbHVlMjwvb3B0aW9uPlxuICAgICAgICAgICAgPC9zZWxlY3Q+XG5cbiAgICAgICAgICAgIDxzZWxlY3QgbmFtZT1cInNlbGVjdDJcIiBtdWx0aXBsZSBpZD1cInNlbGVjdDJcIiBkYXRhLW1vbnN0ZXItYmluZD1cInBhdGg6bXVsdGlzZWxlY3RcIj5cbiAgICAgICAgICAgICAgICA8b3B0aW9uPnZhbHVlMTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIDxvcHRpb24+dmFsdWUyPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgPG9wdGlvbj52YWx1ZTM8L29wdGlvbj5cbiAgICAgICAgICAgICAgICA8b3B0aW9uPnZhbHVlNDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIDxvcHRpb24+dmFsdWU1PC9vcHRpb24+XG4gICAgICAgICAgICA8L3NlbGVjdD5cblxuICAgICAgICAgICAgPHRleHRhcmVhIG5hbWU9XCJ0ZXh0YXJlYVwiIGlkPVwidGV4dGFyZWFcIiBkYXRhLW1vbnN0ZXItYmluZD1cInBhdGg6dGV4dGFyZWFcIj5cbiAgICAgICAgICAgIFxuICAgICAgICA8L3RleHRhcmVhPlxuXG4gICAgICAgIDwvZm9ybT5cbiAgICA8L2Rpdj5cblxuYDtcblxuXG5kZXNjcmliZSgnRE9NJywgZnVuY3Rpb24gKCkge1xuXG4gICAgYmVmb3JlKGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgIGluaXRKU0RPTSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgZG9uZSgpXG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICAgIGxldCBtb2NrcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpO1xuICAgICAgICBtb2Nrcy5pbm5lckhUTUwgPSBodG1sMTtcbiAgICB9KVxuXG4gICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgICAgbGV0IG1vY2tzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vY2tzJyk7XG4gICAgICAgIG1vY2tzLmlubmVySFRNTCA9IFwiXCI7XG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCdVcGRhdGVyKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGRlc2NyaWJlKCd0ZXN0IEdldHRlciAmJiBTZXR0ZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpdCgnc2V0RXZlbnRUeXBlcygpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGxldCBlbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Rlc3QxJylcbiAgICAgICAgICAgICAgICBleHBlY3QobmV3IFVwZGF0ZXIoZWxlbWVudCkuc2V0RXZlbnRUeXBlcyhbJ3RvdWNoJ10pKS50by5iZS5pbnN0YW5jZW9mKFVwZGF0ZXIpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIGl0KCdnZXRTdWJqZWN0KCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbGV0IGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGVzdDEnKVxuICAgICAgICAgICAgICAgIGxldCBzdWJqZWN0ID0ge2E6IDF9O1xuICAgICAgICAgICAgICAgIGV4cGVjdChuZXcgVXBkYXRlcihlbGVtZW50LCBzdWJqZWN0KS5nZXRTdWJqZWN0KCkuYSkudG8uYmUuZXF1YWwoMSk7XG4gICAgICAgICAgICB9KVxuICAgICAgICB9KTtcblxuICAgICAgICBkZXNjcmliZSgndGVzdCBjb250cm9sIG1ldGhvZHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpdCgnZW5hYmxlRXZlbnRQcm9jZXNzaW5nKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbGV0IGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGVzdDEnKVxuICAgICAgICAgICAgICAgIGV4cGVjdChuZXcgVXBkYXRlcihlbGVtZW50KS5lbmFibGVFdmVudFByb2Nlc3NpbmcoKSkudG8uYmUuaW5zdGFuY2VvZihVcGRhdGVyKTtcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGl0KCdkaXNhYmxlRXZlbnRQcm9jZXNzaW5nKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbGV0IGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGVzdDEnKVxuICAgICAgICAgICAgICAgIGV4cGVjdChuZXcgVXBkYXRlcihlbGVtZW50KS5kaXNhYmxlRXZlbnRQcm9jZXNzaW5nKCkpLnRvLmJlLmluc3RhbmNlb2YoVXBkYXRlcik7XG4gICAgICAgICAgICB9KVxuICAgICAgICB9KTtcblxuICAgICAgICBkZXNjcmliZSgndGVzdCBFcnJvcnMnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIGl0KCdzaG91bGQgdGhyb3cgdmFsdWUgaXMgbm90IGFuIGluc3RhbmNlIG9mIEhUTUxFbGVtZW50IEVycm9yJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGV4cGVjdCgoKSA9PiBuZXcgVXBkYXRlcigpKS50by50aHJvdyhUeXBlRXJyb3IpXG4gICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICBpdCgnc2hvdWxkIHRocm93IHZhbHVlIGlzIHdyb25nJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICAgICAgbGV0IGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGVzdDEnKVxuICAgICAgICAgICAgICAgIGV4cGVjdCgoKSA9PiBuZXcgVXBkYXRlcihlbGVtZW50LCBudWxsKSkudG8udGhyb3coVHlwZUVycm9yKVxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBFcnJvcjogdGhlIHZhbHVlIGlzIG5vdCBpdGVyYWJsZScsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICAgICAgbGV0IGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGVzdDEnKVxuXG4gICAgICAgICAgICAgICAgbGV0IHUgPSBuZXcgVXBkYXRlcihcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgYToge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHg6IFtdXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApO1xuXG5cbiAgICAgICAgICAgICAgICB1LnJ1bigpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBkb25lKG5ldyBFcnJvcihcInNob3VsZCBuZXZlciBjYWxsZWQhXCIpKTtcbiAgICAgICAgICAgICAgICB9KS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QoZSkuaXMuaW5zdGFuY2VPZihFcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChlICsgXCJcIikudG8uYmUuZXF1YWwoJ0Vycm9yOiB0aGUgdmFsdWUgaXMgbm90IGl0ZXJhYmxlJyk7XG4gICAgICAgICAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICAgICAgICB9KVxuXG5cbiAgICAgICAgICAgIH0pO1xuXG5cbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnVXBkYXRlcigpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBkZXNjcmliZSgnbmV3IFVwZGF0ZXInLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGRvY3VtZW50IG9iamVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBsZXQgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0ZXN0MScpXG5cbiAgICAgICAgICAgICAgICBsZXQgZCA9IG5ldyBVcGRhdGVyKFxuICAgICAgICAgICAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgICAgICAgICAgICB7fVxuICAgICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgICBleHBlY3QodHlwZW9mIGQpLmlzLmVxdWFsKCdvYmplY3QnKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdVcGRhdGVyKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGRlc2NyaWJlKCdSZXBlYXQnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIGl0KCdzaG91bGQgYnVpbGQgNiBsaSBlbGVtZW50cycsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICAgICAgbGV0IGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGVzdDEnKVxuXG4gICAgICAgICAgICAgICAgbGV0IGQgPSBuZXcgVXBkYXRlcihcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgYToge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGI6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge2k6ICcwJ30sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtpOiAnMSd9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7aTogJzInfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge2k6ICczJ30sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtpOiAnNCd9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7aTogJzUnfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgZC5ydW4oKS50aGVuKCgpID0+IHtcblxuICAgICAgICAgICAgICAgICAgICBleHBlY3QodHlwZW9mIGQpLmlzLmVxdWFsKCdvYmplY3QnKTtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCA2OyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdChlbGVtZW50KS5jb250YWluLmh0bWwoJzxsaSBkYXRhLW1vbnN0ZXItcmVwbGFjZT1cInBhdGg6YS5iLicgKyBpICsgJyB8IHRvanNvblwiIGRhdGEtbW9uc3Rlci1pbnNlcnQtcmVmZXJlbmNlPVwiY3VycmVudC0nICsgaSArICdcIj57XCJpXCI6XCInICsgaSArICdcIn08L2xpPicpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgICAgIH0pLmNhdGNoKFxuICAgICAgICAgICAgICAgICAgICBlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRvbmUobmV3IEVycm9yKGUpKVxuICAgICAgICAgICAgICAgICAgICB9KVxuXG5cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ1VwZGF0ZXIoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAgICAgIGxldCBtb2NrcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpO1xuICAgICAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gaHRtbDQ7XG4gICAgICAgIH0pXG5cbiAgICAgICAgZGVzY3JpYmUoJ0V2ZW50aGFuZGxpbmcnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIGxldCB1cGRhdGVyLCBmb3JtMSwgcHJveHlvYnNlcnZlcjtcbiAgICAgICAgICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgICAgICAgICAgIHByb3h5b2JzZXJ2ZXIgPSBuZXcgUHJveHlPYnNlcnZlcih7fSlcbiAgICAgICAgICAgICAgICB1cGRhdGVyID0gbmV3IFVwZGF0ZXIoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2Zvcm0xJyksIHByb3h5b2JzZXJ2ZXIpO1xuICAgICAgICAgICAgICAgIGZvcm0xID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2Zvcm0xJyk7XG5cbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIC8vIGhlcmUgY2xpY2sgZXZlbnRzIGFyZSB0aHJvd24gb24gdGhlIGNoZWNrYm94IGFuZCB0aGUgc2V0dGluZyBvZiB0aGUgdmFsdWUgaXMgb2JzZXJ2ZWQgdmlhIHRoZSBwcm94eW9ic2VydmVyLlxuICAgICAgICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgY2hlY2tib3ggY2xpY2sgZXZlbnRzJywgZnVuY3Rpb24gKGRvbmUpIHtcblxuICAgICAgICAgICAgICAgIHVwZGF0ZXIuZW5hYmxlRXZlbnRQcm9jZXNzaW5nKCk7XG5cbiAgICAgICAgICAgICAgICBsZXQgc3ViamVjdCA9IHVwZGF0ZXIuZ2V0U3ViamVjdCgpO1xuICAgICAgICAgICAgICAgIGV4cGVjdChzdWJqZWN0KS5pcy5lcXVhbChwcm94eW9ic2VydmVyLmdldFN1YmplY3QoKSk7XG5cbiAgICAgICAgICAgICAgICBsZXQgZXhwZWN0ZWQgPSBbJ2NoZWNrZWQnLCB1bmRlZmluZWQsICdjaGVja2VkJ107XG4gICAgICAgICAgICAgICAgLy8gaGVyZSB0aGUgbm90YXRpb24gd2l0aCBmdW5jdGlvbiBpcyBpbXBvcnRhbnQsIGJlY2F1c2UgdGhlIHBvaW50ZXIgaXMgc2V0LlxuICAgICAgICAgICAgICAgIHByb3h5b2JzZXJ2ZXIuYXR0YWNoT2JzZXJ2ZXIobmV3IE9ic2VydmVyKGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgICAgICBsZXQgZSA9IGV4cGVjdGVkLnNoaWZ0KCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlID09PSB1bmRlZmluZWQgJiYgZXhwZWN0ZWQubGVuZ3RoID09PSAwKSBkb25lKG5ldyBFcnJvcigndG8gbWFueSBjYWxscycpKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5nZXRTdWJqZWN0KClbJ3N0YXRlJ10gIT09IGUpIGRvbmUobmV3IEVycm9yKHRoaXMuZ2V0U3ViamVjdCgpWydzdGF0ZSddICsgJyBzaG91bGQgJyArIGUpKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGV4cGVjdGVkLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtMS5xdWVyeVNlbGVjdG9yKCdbbmFtZT1jaGVja2JveF0nKS5jbGljaygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSwgMTApXG5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBmb3JtMS5xdWVyeVNlbGVjdG9yKCdbbmFtZT1jaGVja2JveF0nKS5jbGljaygpO1xuICAgICAgICAgICAgICAgIH0sIDEwKVxuXG5cbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGl0KCdzaG91bGQgaGFuZGxlIHJhZGlvIGNsaWNrIGV2ZW50cyAxJywgZnVuY3Rpb24gKGRvbmUpIHtcblxuICAgICAgICAgICAgICAgIHVwZGF0ZXIuZW5hYmxlRXZlbnRQcm9jZXNzaW5nKCk7XG5cbiAgICAgICAgICAgICAgICBsZXQgc3ViamVjdCA9IHVwZGF0ZXIuZ2V0U3ViamVjdCgpO1xuICAgICAgICAgICAgICAgIGV4cGVjdChzdWJqZWN0KS5pcy5lcXVhbChwcm94eW9ic2VydmVyLmdldFN1YmplY3QoKSk7XG5cbiAgICAgICAgICAgICAgICBsZXQgZXhwZWN0ZWQgPSBbJ3IxJywgJ3IyJywgJ3IxJ107XG4gICAgICAgICAgICAgICAgbGV0IGNsaWNrVGFyZ2V0cyA9IFsncjInLCAncjEnXVxuICAgICAgICAgICAgICAgIC8vIGhlcmUgdGhlIG5vdGF0aW9uIHdpdGggZnVuY3Rpb24gaXMgaW1wb3J0YW50LCBiZWNhdXNlIHRoZSB0aGlzIHBvaW50ZXIgaXMgc2V0LlxuICAgICAgICAgICAgICAgIHByb3h5b2JzZXJ2ZXIuYXR0YWNoT2JzZXJ2ZXIobmV3IE9ic2VydmVyKGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgICAgICBsZXQgZSA9IGV4cGVjdGVkLnNoaWZ0KCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlID09PSB1bmRlZmluZWQgJiYgZXhwZWN0ZWQubGVuZ3RoID09PSAwKSBkb25lKG5ldyBFcnJvcigndG8gbWFueSBjYWxscycpKTtcblxuICAgICAgICAgICAgICAgICAgICBsZXQgdiA9IHRoaXMuZ2V0U3ViamVjdCgpWydyYWRpbyddO1xuICAgICAgICAgICAgICAgICAgICBpZiAodiAhPT0gZSkgZG9uZShuZXcgRXJyb3IodiArICcgc2hvdWxkICcgKyBlKSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChleHBlY3RlZC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGNsaWNrVGFyZ2V0cy5zaGlmdCgpKS5jbGljaygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSwgMTApXG5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncjEnKS5jbGljaygpO1xuICAgICAgICAgICAgICAgIH0sIDEwKVxuXG4gICAgICAgICAgICAgICAgLy8gbm8gaGFuZGxlciAvLyBiaW5kXG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdyeCcpLmNsaWNrKCk7XG4gICAgICAgICAgICAgICAgfSwgMjApXG5cbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGl0KCdzaG91bGQgaGFuZGxlIHNlbGVjdCBjbGljayBldmVudHMgMicsIGZ1bmN0aW9uIChkb25lKSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgc2VsZWN0RWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZWxlY3QxJyk7XG5cbiAgICAgICAgICAgICAgICB1cGRhdGVyLmVuYWJsZUV2ZW50UHJvY2Vzc2luZygpO1xuXG4gICAgICAgICAgICAgICAgbGV0IHN1YmplY3QgPSB1cGRhdGVyLmdldFN1YmplY3QoKTtcbiAgICAgICAgICAgICAgICBleHBlY3Qoc3ViamVjdCkuaXMuZXF1YWwocHJveHlvYnNlcnZlci5nZXRTdWJqZWN0KCkpO1xuXG4gICAgICAgICAgICAgICAgbGV0IGV4cGVjdGVkID0gWyd2YWx1ZTInLCAndmFsdWUxJywgJ3ZhbHVlMiddO1xuICAgICAgICAgICAgICAgIC8vIGhlcmUgdGhlIG5vdGF0aW9uIHdpdGggZnVuY3Rpb24gaXMgaW1wb3J0YW50LCBiZWNhdXNlIHRoZSB0aGlzIHBvaW50ZXIgaXMgc2V0LlxuICAgICAgICAgICAgICAgIHByb3h5b2JzZXJ2ZXIuYXR0YWNoT2JzZXJ2ZXIobmV3IE9ic2VydmVyKGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgICAgICBsZXQgZSA9IGV4cGVjdGVkLnNoaWZ0KCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlID09PSB1bmRlZmluZWQgJiYgZXhwZWN0ZWQubGVuZ3RoID09PSAwKSBkb25lKG5ldyBFcnJvcigndG8gbWFueSBjYWxscycpKTtcblxuICAgICAgICAgICAgICAgICAgICBsZXQgdiA9IHRoaXMuZ2V0U3ViamVjdCgpWydzZWxlY3QnXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHYgIT09IGUpIGRvbmUobmV3IEVycm9yKHYgKyAnIHNob3VsZCAnICsgZSkpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXhwZWN0ZWQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RFbGVtZW50LnNlbGVjdGVkSW5kZXggPSBzZWxlY3RFbGVtZW50LnNlbGVjdGVkSW5kZXggPT09IDEgPyAwIDogMTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RFbGVtZW50LmNsaWNrKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9LCAxMClcblxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHNldCB2YWx1ZSBhbmQgc2ltdWxhdGUgY2xpY2sgZXZlbnQgZm9yIGJ1YmJsZVxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RFbGVtZW50LnNlbGVjdGVkSW5kZXggPSAxO1xuICAgICAgICAgICAgICAgICAgICBzZWxlY3RFbGVtZW50LmNsaWNrKCk7XG5cbiAgICAgICAgICAgICAgICB9LCAyMClcblxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGl0KCdzaG91bGQgaGFuZGxlIHRleHRhcmVhIGV2ZW50cycsIGZ1bmN0aW9uIChkb25lKSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgdGV4dGFyZWFFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3RleHRhcmVhJyk7XG5cbiAgICAgICAgICAgICAgICB1cGRhdGVyLmVuYWJsZUV2ZW50UHJvY2Vzc2luZygpO1xuXG4gICAgICAgICAgICAgICAgbGV0IHN1YmplY3QgPSB1cGRhdGVyLmdldFN1YmplY3QoKTtcbiAgICAgICAgICAgICAgICBleHBlY3Qoc3ViamVjdCkuaXMuZXF1YWwocHJveHlvYnNlcnZlci5nZXRTdWJqZWN0KCkpO1xuXG4gICAgICAgICAgICAgICAgbGV0IGV4cGVjdGVkID0gWyd0ZXN0WCcsICdsb3JlbSBpcHN1bScsICcnXTtcbiAgICAgICAgICAgICAgICBsZXQgdGVzdFZhbHVlcyA9IFtcImxvcmVtIGlwc3VtXCIsIFwiXCJdO1xuICAgICAgICAgICAgICAgIC8vIGhlcmUgdGhlIG5vdGF0aW9uIHdpdGggZnVuY3Rpb24gaXMgaW1wb3J0YW50LCBiZWNhdXNlIHRoZSB0aGlzIHBvaW50ZXIgaXMgc2V0LlxuICAgICAgICAgICAgICAgIHByb3h5b2JzZXJ2ZXIuYXR0YWNoT2JzZXJ2ZXIobmV3IE9ic2VydmVyKGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgICAgICBsZXQgZSA9IGV4cGVjdGVkLnNoaWZ0KCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlID09PSB1bmRlZmluZWQgJiYgZXhwZWN0ZWQubGVuZ3RoID09PSAwKSBkb25lKG5ldyBFcnJvcigndG8gbWFueSBjYWxscycpKTtcblxuICAgICAgICAgICAgICAgICAgICBsZXQgdiA9IHRoaXMuZ2V0U3ViamVjdCgpWyd0ZXh0YXJlYSddO1xuICAgICAgICAgICAgICAgICAgICBpZiAoSlNPTi5zdHJpbmdpZnkodikgIT09IEpTT04uc3RyaW5naWZ5KGUpKSBkb25lKG5ldyBFcnJvcihKU09OLnN0cmluZ2lmeSh2KSArICcgc2hvdWxkICcgKyBKU09OLnN0cmluZ2lmeShlKSkpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXhwZWN0ZWQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0YXJlYUVsZW1lbnQudmFsdWUgPSB0ZXN0VmFsdWVzLnNoaWZ0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dGFyZWFFbGVtZW50LmNsaWNrKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9LCAxMClcblxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gc2V0IHZhbHVlIGFuZCBzaW11bGF0ZSBjbGljayBldmVudCBmb3IgYnViYmxlXG4gICAgICAgICAgICAgICAgICAgIHRleHRhcmVhRWxlbWVudC52YWx1ZSA9IFwidGVzdFhcIjtcbiAgICAgICAgICAgICAgICAgICAgdGV4dGFyZWFFbGVtZW50LmNsaWNrKCk7XG5cbiAgICAgICAgICAgICAgICB9LCAyMClcblxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGl0KCdzaG91bGQgaGFuZGxlIG11bHRpcGxlIHNlbGVjdCBldmVudHMnLCBmdW5jdGlvbiAoZG9uZSkge1xuXG4gICAgICAgICAgICAgICAgbGV0IHNlbGVjdEVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2VsZWN0MicpO1xuXG4gICAgICAgICAgICAgICAgdXBkYXRlci5lbmFibGVFdmVudFByb2Nlc3NpbmcoKTtcblxuICAgICAgICAgICAgICAgIGxldCBzdWJqZWN0ID0gdXBkYXRlci5nZXRTdWJqZWN0KCk7XG4gICAgICAgICAgICAgICAgZXhwZWN0KHN1YmplY3QpLmlzLmVxdWFsKHByb3h5b2JzZXJ2ZXIuZ2V0U3ViamVjdCgpKTtcblxuICAgICAgICAgICAgICAgIGxldCBleHBlY3RlZCA9IFtcbiAgICAgICAgICAgICAgICAgICAgWyd2YWx1ZTEnXSxcbiAgICAgICAgICAgICAgICAgICAgWyd2YWx1ZTInLCAndmFsdWUzJywgJ3ZhbHVlNCddLFxuICAgICAgICAgICAgICAgICAgICBbJ3ZhbHVlMScsICd2YWx1ZTQnXSxcbiAgICAgICAgICAgICAgICBdO1xuXG4gICAgICAgICAgICAgICAgbGV0IHRlc3RTZWxlY3Rpb25zID0gW1xuICAgICAgICAgICAgICAgICAgICBbZmFsc2UsIHRydWUsIHRydWUsIHRydWVdLFxuICAgICAgICAgICAgICAgICAgICBbdHJ1ZSwgZmFsc2UsIGZhbHNlLCB0cnVlXSxcbiAgICAgICAgICAgICAgICBdXG5cbiAgICAgICAgICAgICAgICAvLyBoZXJlIHRoZSBub3RhdGlvbiB3aXRoIGZ1bmN0aW9uIGlzIGltcG9ydGFudCwgYmVjYXVzZSB0aGUgdGhpcyBwb2ludGVyIGlzIHNldC5cbiAgICAgICAgICAgICAgICBwcm94eW9ic2VydmVyLmF0dGFjaE9ic2VydmVyKG5ldyBPYnNlcnZlcihmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgbGV0IGUgPSBleHBlY3RlZC5zaGlmdCgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZSA9PT0gdW5kZWZpbmVkICYmIGV4cGVjdGVkLmxlbmd0aCA9PT0gMCkgZG9uZShuZXcgRXJyb3IoJ3RvIG1hbnkgY2FsbHMnKSk7XG5cbiAgICAgICAgICAgICAgICAgICAgbGV0IHYgPSB0aGlzLmdldFN1YmplY3QoKVsnbXVsdGlzZWxlY3QnXTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoSlNPTi5zdHJpbmdpZnkodikgIT09IEpTT04uc3RyaW5naWZ5KGUpKSBkb25lKG5ldyBFcnJvcihKU09OLnN0cmluZ2lmeSh2KSArICcgc2hvdWxkICcgKyBKU09OLnN0cmluZ2lmeShlKSkpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXhwZWN0ZWQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgdiA9IHRlc3RTZWxlY3Rpb25zLnNoaWZ0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0RWxlbWVudC5vcHRpb25zWzBdLnNlbGVjdGVkID0gdlswXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RFbGVtZW50Lm9wdGlvbnNbMV0uc2VsZWN0ZWQgPSB2WzFdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdEVsZW1lbnQub3B0aW9uc1syXS5zZWxlY3RlZCA9IHZbMl07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0RWxlbWVudC5vcHRpb25zWzNdLnNlbGVjdGVkID0gdlszXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RFbGVtZW50LmNsaWNrKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9LCAxMClcblxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0RWxlbWVudC5vcHRpb25zWzBdLnNlbGVjdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0RWxlbWVudC5vcHRpb25zWzFdLnNlbGVjdGVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdEVsZW1lbnQub3B0aW9uc1syXS5zZWxlY3RlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICBzZWxlY3RFbGVtZW50Lm9wdGlvbnNbM10uc2VsZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0RWxlbWVudC5jbGljaygpO1xuXG4gICAgICAgICAgICAgICAgfSwgMjApXG5cblxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgfSlcblxuXG4gICAgZGVzY3JpYmUoJ1VwZGF0ZXIoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAgICAgIGxldCBtb2NrcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpO1xuICAgICAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gaHRtbDI7XG4gICAgICAgIH0pXG5cbiAgICAgICAgZGVzY3JpYmUoJ1JlcGxhY2UnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIGl0KCdzaG91bGQgYWRkIGxvd2VyIGhlbGxvIGFuZCBIRUxMT3llcyEnLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICAgICAgICAgIGxldCBlbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Rlc3QxJylcblxuICAgICAgICAgICAgICAgIGxldCBkID0gbmV3IFVwZGF0ZXIoXG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQsXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHQ6IFwiSEFMTE9cIlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgIGQuc2V0Q2FsbGJhY2soJ215Zm9ybWF0dGVyJywgZnVuY3Rpb24gKGEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGEgKyAneWVzISdcbiAgICAgICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGQucnVuKCkudGhlbigoKSA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdCh0eXBlb2YgZCkuaXMuZXF1YWwoJ29iamVjdCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0KGVsZW1lbnQpLmNvbnRhaW4uaHRtbCgnPGRpdiBkYXRhLW1vbnN0ZXItcmVwbGFjZT1cInBhdGg6dGV4dCB8IHRvbG93ZXJcIj5oYWxsbzwvZGl2PicpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0KGVsZW1lbnQpLmNvbnRhaW4uaHRtbCgnPGRpdiBkYXRhLW1vbnN0ZXItcmVwbGFjZT1cInBhdGg6dGV4dCB8IGNhbGw6bXlmb3JtYXR0ZXJcIj5IQUxMT3llcyE8L2Rpdj4nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdChlbGVtZW50KS5jb250YWluLmh0bWwoJzxkaXYgZGF0YS1tb25zdGVyLXJlcGxhY2U9XCJzdGF0aWM6aGVsbG9cXFxcIFwiPmhlbGxvIDwvZGl2PicpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZG9uZSgpO1xuICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaChcbiAgICAgICAgICAgICAgICAgICAgICAgIGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbmUobmV3IEVycm9yKGUpKVxuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICB9LCAxMDApXG5cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuXG4gICAgZGVzY3JpYmUoJ1VwZGF0ZXIoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAgICAgIGxldCBtb2NrcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpO1xuICAgICAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gaHRtbDM7XG4gICAgICAgIH0pXG5cbiAgICAgICAgZGVzY3JpYmUoJ1JlcGxhY2UnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIGl0KCdzaG91bGQgJywgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgICAgICAgICBsZXQgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0ZXN0MScpXG5cbiAgICAgICAgICAgICAgICBsZXQgZCA9IG5ldyBVcGRhdGVyKFxuICAgICAgICAgICAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYjogW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7aTogJzAnfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApO1xuXG5cbiAgICAgICAgICAgICAgICBkLnJ1bigpLnRoZW4oKCkgPT4ge1xuXG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdCh0eXBlb2YgZCkuaXMuZXF1YWwoJ29iamVjdCcpO1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QoZWxlbWVudCkuY29udGFpbi5odG1sKCc8ZGl2IGRhdGEtbW9uc3Rlci1pbnNlcnQ9XCJteWlkIHBhdGg6YS5iXCI+Jyk7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChlbGVtZW50KS5jb250YWluLmh0bWwoJzxwIGRhdGEtbW9uc3Rlci1pbnNlcnQ9XCJteWlubmVyaWQgcGF0aDphLmJcIiBkYXRhLW1vbnN0ZXItaW5zZXJ0LXJlZmVyZW5jZT1cIm15aWQtMFwiPicpO1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QoZWxlbWVudCkuY29udGFpbi5odG1sKCc8c3BhbiBkYXRhLW1vbnN0ZXItcmVwbGFjZT1cInBhdGg6YS5iLjAgfCB0b2pzb25cIiBkYXRhLW1vbnN0ZXItaW5zZXJ0LXJlZmVyZW5jZT1cIm15aW5uZXJpZC0wXCI+e1wiaVwiOlwiMFwifTwvc3Bhbj4nKTtcblxuICAgICAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICAgICAgfSkuY2F0Y2goXG4gICAgICAgICAgICAgICAgICAgIGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgZG9uZShuZXcgRXJyb3IoZSkpXG4gICAgICAgICAgICAgICAgICAgIH0pXG5cblxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnVXBkYXRlcigpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBkZXNjcmliZSgnQXR0cmlidXRlcycsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgaXQoJ3Nob3VsZCBjaGFuZ2UgYXR0cmlidXRlcycsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICAgICAgbGV0IGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGVzdDMnKVxuXG4gICAgICAgICAgICAgICAgbGV0IHRleHQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGV4dCcpXG4gICAgICAgICAgICAgICAgZXhwZWN0KHRleHQudmFsdWUpLnRvLmJlLmVxdWFsKFwiXCIpO1xuXG4gICAgICAgICAgICAgICAgbGV0IHJhZGlvID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3JhZGlvJylcbiAgICAgICAgICAgICAgICBleHBlY3QocmFkaW8uY2hlY2tlZCkudG8uYmUuZmFsc2U7XG5cbiAgICAgICAgICAgICAgICBsZXQgY2hlY2tib3ggPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY2hlY2tib3gnKVxuICAgICAgICAgICAgICAgIGV4cGVjdChjaGVja2JveC5jaGVja2VkKS50by5iZS5mYWxzZTtcblxuICAgICAgICAgICAgICAgIGxldCBzZWxlY3QgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2VsZWN0JylcbiAgICAgICAgICAgICAgICBleHBlY3Qoc2VsZWN0LnNlbGVjdGVkSW5kZXgpLnRvLmJlLmVxdWFsKDApO1xuXG4gICAgICAgICAgICAgICAgbGV0IG11bHRpc2VsZWN0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ211bHRpc2VsZWN0JylcbiAgICAgICAgICAgICAgICBleHBlY3QobXVsdGlzZWxlY3Quc2VsZWN0ZWRJbmRleCkudG8uYmUuZXF1YWwoLTEpO1xuXG4gICAgICAgICAgICAgICAgbGV0IHRleHRhcmVhID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3RleHRhcmVhJylcbiAgICAgICAgICAgICAgICBleHBlY3QodGV4dGFyZWEudmFsdWUpLnRvLmJlLmVxdWFsKFwiXCIpO1xuXG5cbiAgICAgICAgICAgICAgICBsZXQgZCA9IG5ldyBVcGRhdGVyKFxuICAgICAgICAgICAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYjogXCJkaXYtY2xhc3NcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjOiBcImhlbGxvXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dDogXCJoZWxsb1wiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhZGlvOiBcInRydWVcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0YXJlYTogXCJ0ZXN0XCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbXVsdGlzZWxlY3Q6IFsndmFsdWUzJywgJ3ZhbHVlNCcsICdvdGhlci12YWx1ZTUnXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3Q6IFwidmFsdWUyXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tib3g6IFwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApO1xuXG5cbiAgICAgICAgICAgICAgICBkLnJ1bigpLnRoZW4oKCkgPT4ge1xuXG5cbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KGVsZW1lbnQpLmNvbnRhaW4uaHRtbCgnPGRpdiBkYXRhLW1vbnN0ZXItYXR0cmlidXRlcz1cImNsYXNzIHBhdGg6YS5iXCIgY2xhc3M9XCJkaXYtY2xhc3NcIj4nKTtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KGVsZW1lbnQpLmNvbnRhaW4uaHRtbCgnPGlucHV0IGRhdGEtbW9uc3Rlci1hdHRyaWJ1dGVzPVwidmFsdWUgcGF0aDphLmNcIiBpZD1cImlucHV0MVwiIHZhbHVlPVwiaGVsbG9cIj4nKTtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KGVsZW1lbnQpLmNvbnRhaW4uaHRtbCgnPHRleHRhcmVhIG5hbWU9XCJ0ZXh0YXJlYVwiIGlkPVwidGV4dGFyZWFcIiBkYXRhLW1vbnN0ZXItYXR0cmlidXRlcz1cInZhbHVlIHBhdGg6YS50ZXh0YXJlYVwiIHZhbHVlPVwidGVzdFwiPicpO1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QoZWxlbWVudCkuY29udGFpbi5odG1sKCc8aW5wdXQgZGF0YS1tb25zdGVyLWF0dHJpYnV0ZXM9XCJjaGVja2VkIHBhdGg6YS5yYWRpb1wiIHR5cGU9XCJyYWRpb1wiIG5hbWU9XCJyYWRpb1wiIHZhbHVlPVwicjFcIiBpZD1cInJhZGlvXCIgY2hlY2tlZD1cInRydWVcIj4nKTtcblxuICAgICAgICAgICAgICAgICAgICBleHBlY3QodGV4dC52YWx1ZSwgJ3RleHQgY29udHJvbCcpLnRvLmJlLmVxdWFsKGQuZ2V0U3ViamVjdCgpWydhJ11bJ2MnXSk7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChyYWRpby5jaGVja2VkLCAncmFkaW8gY29udHJvbCcpLnRvLmJlLmVxdWFsKHRydWUpO1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QodGV4dGFyZWEudmFsdWUsICd0ZXh0YXJlYSBjb250cm9sJykudG8uYmUuZXF1YWwoZC5nZXRTdWJqZWN0KClbJ2EnXVsndGV4dGFyZWEnXSk7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChzZWxlY3Quc2VsZWN0ZWRJbmRleCwgJ3NlbGVjdCBjb250cm9sJykudG8uYmUuZXF1YWwoMSk7IC8vIFswPT5vdGhlci12YWx1ZSwgMT0+dmFsdWUyXVxuXG4gICAgICAgICAgICAgICAgICAgIGxldCBtdWx0aXNlbGVjdFNlbGVjdGVkT3B0aW9ucyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IFtpbmRleCwgb2JqXSBvZiBPYmplY3QuZW50cmllcyhtdWx0aXNlbGVjdC5zZWxlY3RlZE9wdGlvbnMpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtdWx0aXNlbGVjdFNlbGVjdGVkT3B0aW9ucy5wdXNoKG9iai52YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuXG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChKU09OLnN0cmluZ2lmeShtdWx0aXNlbGVjdFNlbGVjdGVkT3B0aW9ucyksICdtdWx0aXNlbGVjdCBjb250cm9sJykudG8uYmUuZXF1YWwoSlNPTi5zdHJpbmdpZnkoZC5nZXRTdWJqZWN0KClbJ2EnXVsnbXVsdGlzZWxlY3QnXSkpO1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QoY2hlY2tib3guY2hlY2tlZCwgJ2NoZWNrYm94IGNvbnRyb2wnKS50by5iZS50cnVlO1xuXG4gICAgICAgICAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICAgICAgICB9KS5jYXRjaChcbiAgICAgICAgICAgICAgICAgICAgZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkb25lKG5ldyBFcnJvcihlKSlcbiAgICAgICAgICAgICAgICAgICAgfSlcblxuXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnR2V0IEF0dHJpYnV0ZSBQaXBlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgaWQsIG1vY2tzO1xuICAgICAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAgICAgIG1vY2tzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vY2tzJyk7XG4gICAgICAgICAgICBpZCA9IG5ldyBJRCgnbW9uc3RlcicpO1xuICAgICAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gYCA8ZGl2IGlkPVwiYCArIGlkICsgYFwiXG4gICAgICAgICAgICBkYXRhLW1vbnN0ZXItcmVwbGFjZT1cInBhdGg6YSB8IGlmOnZhbHVlOlxcXFwgXCI+PC9kaXY+YFxuICAgICAgICB9KVxuXG4gICAgICAgIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICAgICAgICBtb2Nrcy5pbm5lckhUTUwgPSBcIlwiO1xuICAgICAgICB9KVxuXG4gICAgICAgIGl0KCdzaG91bGQgaW5jbHVkZSBzcGFjZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IGRpdiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkLnRvU3RyaW5nKCkpXG5cbiAgICAgICAgICAgIGNvbnN0IHBpcGUgPSBkaXYuZ2V0QXR0cmlidXRlKCdkYXRhLW1vbnN0ZXItcmVwbGFjZScpO1xuICAgICAgICAgICAgZXhwZWN0KHBpcGUubGVuZ3RoKS50by5iZS5lcXVhbCgyMCk7XG5cbiAgICAgICAgfSk7XG4gICAgfSk7XG5cblxuICAgIGRlc2NyaWJlKCdtYW51ZWwgdXBkYXRlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgaWQsIG1vY2tzO1xuXG4gICAgICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgICAgICAgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgICAgIGlkID0gbmV3IElEKCdtb25zdGVyJykudG9TdHJpbmcoKTtcbiAgICAgICAgICAgIG1vY2tzLmlubmVySFRNTCA9IGA8aW5wdXQgaWQ9XCJgICsgaWQgKyBgXCJkYXRhLW1vbnN0ZXItYmluZD1cInBhdGg6bXl2YWx1ZVwiPmBcbiAgICAgICAgfSlcblxuICAgICAgICBhZnRlckVhY2goKCkgPT4ge1xuICAgICAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gXCJcIjtcbiAgICAgICAgfSlcblxuICAgICAgICBpdCgnc2hvdWxkIGdldCB2YWx1ZScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpLnZhbHVlID0gXCJoZWxsb1wiO1xuICAgICAgICAgICAgY29uc3QgdXBkYXRlciA9IG5ldyBVcGRhdGVyKG1vY2tzKTtcbiAgICAgICAgICAgIGNvbnN0IHN1YmplY3QgPSB1cGRhdGVyLmdldFN1YmplY3QoKTtcblxuICAgICAgICAgICAgZXhwZWN0KHN1YmplY3QpLnRvLm5vdC5oYXZlLnByb3BlcnR5KCdteXZhbHVlJyk7XG4gICAgICAgICAgICB1cGRhdGVyLnJldHJpZXZlKCk7XG4gICAgICAgICAgICBleHBlY3Qoc3ViamVjdCkudG8uaGF2ZS5wcm9wZXJ0eSgnbXl2YWx1ZScpO1xuICAgICAgICB9KTtcblxuXG4gICAgfSk7XG5cblxuICAgIC8qKlxuICAgICAqIGh0dHBzOi8vZ2l0bGFiLnNjaHVrYWkuY29tL29zcy9saWJyYXJpZXMvamF2YXNjcmlwdC9tb25zdGVyLy0vaXNzdWVzLzExMlxuICAgICAqL1xuICAgIGRlc2NyaWJlKCdVcGRhdGVyKCkgMjAyMjAxMDcnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICAgICAgICBsZXQgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgICAgIC8vIGxhbmd1YWdlPUhUTUxcbiAgICAgICAgICAgIG1vY2tzLmlubmVySFRNTCA9IGBcblxuICAgICAgICAgICAgICAgIDxkaXYgaWQ9XCJjb250YWluZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBkYXRhLW1vbnN0ZXItcmVwbGFjZT1cInBhdGg6Y29udGVudFwiPjwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG5cbiAgICAgICAgICAgIGA7XG4gICAgICAgIH0pXG5cbiAgICAgICAgZGVzY3JpYmUoJ0J1Z2ZpeCAjMTEyJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBpdCgnc2hvdWxkIGFkZCAnLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICAgICAgICAgIGxldCBjb250YWluZXJFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NvbnRhaW5lcicpO1xuICAgICAgICAgICAgICAgIGxldCBuZXdFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICAgICAgbmV3RWxlbWVudC5pbm5lckhUTUwgPSAneWVhaCEgPGI+VGVzdDwvYj4hJztcblxuICAgICAgICAgICAgICAgIGNvbnN0IGNvbnRhaW5lckhUTUwgPSBjb250YWluZXJFbGVtZW50LmlubmVySFRNTDtcbiAgICAgICAgICAgICAgICBjb25zdCBuZXdIVE1MID0gbmV3RWxlbWVudC5pbm5lckhUTUw7XG5cbiAgICAgICAgICAgICAgICBsZXQgZCA9IG5ldyBVcGRhdGVyKFxuICAgICAgICAgICAgICAgICAgICBjb250YWluZXJFbGVtZW50LFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50OiBuZXdFbGVtZW50XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBkLnJ1bigpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBlY3QoY29udGFpbmVyRWxlbWVudCkuY29udGFpbi5odG1sKCc8ZGl2PnllYWghIDxiPlRlc3Q8L2I+ITwvZGl2PicpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkb25lKGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIH0sIDEwMClcblxuICAgICAgICAgICAgICAgIC8vIGQuc2V0Q2FsbGJhY2soJ215Zm9ybWF0dGVyJywgZnVuY3Rpb24gKGEpIHtcbiAgICAgICAgICAgICAgICAvLyAgICAgcmV0dXJuIGEgKyAneWVzISdcbiAgICAgICAgICAgICAgICAvLyB9KVxuICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgLy8gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gICAgIGQucnVuKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgICAvLyAgICAgICAgIGV4cGVjdCh0eXBlb2YgZCkuaXMuZXF1YWwoJ29iamVjdCcpO1xuICAgICAgICAgICAgICAgIC8vICAgICAgICAgZXhwZWN0KGVsZW1lbnQpLmNvbnRhaW4uaHRtbCgnPGRpdiBkYXRhLW1vbnN0ZXItcmVwbGFjZT1cInBhdGg6dGV4dCB8IHRvbG93ZXJcIj5oYWxsbzwvZGl2PicpO1xuICAgICAgICAgICAgICAgIC8vICAgICAgICAgZXhwZWN0KGVsZW1lbnQpLmNvbnRhaW4uaHRtbCgnPGRpdiBkYXRhLW1vbnN0ZXItcmVwbGFjZT1cInBhdGg6dGV4dCB8IGNhbGw6bXlmb3JtYXR0ZXJcIj5IQUxMT3llcyE8L2Rpdj4nKTtcbiAgICAgICAgICAgICAgICAvLyAgICAgICAgIGV4cGVjdChlbGVtZW50KS5jb250YWluLmh0bWwoJzxkaXYgZGF0YS1tb25zdGVyLXJlcGxhY2U9XCJzdGF0aWM6aGVsbG9cXFxcIFwiPmhlbGxvIDwvZGl2PicpO1xuICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgLy8gICAgICAgICByZXR1cm4gZG9uZSgpO1xuICAgICAgICAgICAgICAgIC8vICAgICB9KS5jYXRjaChcbiAgICAgICAgICAgICAgICAvLyAgICAgICAgIGUgPT4ge1xuICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgIGRvbmUobmV3IEVycm9yKGUpKVxuICAgICAgICAgICAgICAgIC8vICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAvLyB9LCAxMDApXG5cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuXG59KTsiLCAiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuXG5pbXBvcnQge0xvY2FsZX0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS9pMThuL2xvY2FsZS5tanNcIjtcbmltcG9ydCB7Z2V0TG9jYWxlT2ZEb2N1bWVudH0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS9kb20vbG9jYWxlLm1qc1wiO1xuaW1wb3J0IHtpbml0SlNET019IGZyb20gXCIuLi8uLi91dGlsL2pzZG9tLm1qc1wiO1xuXG5kZXNjcmliZSgnQXR0cmlidXRlcycsIGZ1bmN0aW9uICgpIHtcbiAgICBiZWZvcmUoZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgaW5pdEpTRE9NKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICBkb25lKClcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnZ2V0TG9jYWxlT2ZEb2N1bWVudCcsIGZ1bmN0aW9uICgpIHtcblxuXG4gICAgICAgIFtcbiAgICAgICAgICAgIFtcImRlXCJdLFxuICAgICAgICAgICAgW1wic2wtSVQtbmVkaXNcIl0sXG4gICAgICAgICAgICBbXCJlbi1HQlwiXSxcblxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcblxuXG4gICAgICAgICAgICBpdCgncmV0dXJuIGxhbmd1YWdlICcgKyBhLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbGV0IGh0bWwgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaHRtbCcpO1xuICAgICAgICAgICAgICAgIGxldCBub2RlID0gaHRtbC5pdGVtKDApO1xuXG4gICAgICAgICAgICAgICAgbm9kZS5zZXRBdHRyaWJ1dGUoJ2xhbmcnLCBhKTtcbiAgICAgICAgICAgICAgICBleHBlY3QoZ2V0TG9jYWxlT2ZEb2N1bWVudCgpLnRvU3RyaW5nKCkpLnRvLmJlLmVxdWFsKGEpO1xuICAgICAgICAgICAgfSlcblxuXG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxuXG4gICAgaXQoJ3JldHVybiBsYW5ndWFnZSBlbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbGV0IGh0bWwgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaHRtbCcpO1xuICAgICAgICBsZXQgbm9kZSA9IGh0bWwuaXRlbSgwKTtcbiAgICAgICAgbGV0IGxhbmc9IG5vZGUuZ2V0QXR0cmlidXRlKCdsYW5nJyk7XG5cbiAgICAgICAgbm9kZS5yZW1vdmVBdHRyaWJ1dGUoJ2xhbmcnKTtcbiAgICAgICAgY29uc3QgbG9jYWxlID0gZ2V0TG9jYWxlT2ZEb2N1bWVudCgpO1xuICAgICAgICBleHBlY3QobG9jYWxlKS50by5iZS5pbnN0YW5jZU9mKExvY2FsZSk7XG4gICAgICAgIGV4cGVjdChsb2NhbGUubG9jYWxlU3RyaW5nKS50by5iZS5lcXVhbChuYXZpZ2F0b3IubGFuZ3VhZ2UpO1xuXG4gICAgICAgIG5vZGUuc2V0QXR0cmlidXRlKCdsYW5nJywgbGFuZyk7XG4gICAgICAgIFxuICAgIH0pXG5cblxufSkiLCAiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQge2dldERvY3VtZW50RnJhZ21lbnRGcm9tU3RyaW5nfSBmcm9tIFwiLi4vLi4vLi4vc291cmNlL2RvbS91dGlsLm1qc1wiO1xuaW1wb3J0IHtpbml0SlNET019IGZyb20gXCIuLi8uLi91dGlsL2pzZG9tLm1qc1wiO1xuaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7VGhlbWUsIGdldERvY3VtZW50VGhlbWV9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvZG9tL3RoZW1lLm1qc1wiO1xuXG5kZXNjcmliZSgnVGhlbWUnLCBmdW5jdGlvbiAoKSB7XG4gICAgYmVmb3JlKGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgIGluaXRKU0RPTSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgZG9uZSgpXG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ25ldyBUaGVtZSgpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBUaGVtZSBvYmplY3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IFRoZW1lKCdteS10aGVtZScpKS5pcy5hLmluc3RhbmNlT2YoVGhlbWUpO1xuICAgICAgICB9KTtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gVGhlbWUtTmFtZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgVGhlbWUoJ215LXRoZW1lJykuZ2V0TmFtZSgpKS5pcy5lcXVhbCgnbXktdGhlbWUnKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGl0KCdzaG91bGQgdGhyb3cgRXJyb3IgYmVjYXVzZSBlbXB0eSBhcmd1bWVudCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdCgoKSA9PiBuZXcgVGhlbWUoKSkudG8udGhyb3coVHlwZUVycm9yKVxuICAgICAgICB9KTtcbiAgICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBFcnJvciBiZWNhdXNlIG5vIHN0cmluZyBhcmd1bWVudCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdCgoKSA9PiBuZXcgVGhlbWUoMikpLnRvLnRocm93KFR5cGVFcnJvcilcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnZ2V0RG9jdW1lbnRUaGVtZSgpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBUaGVtZSBvYmplY3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QoZ2V0RG9jdW1lbnRUaGVtZSgpKS5pcy5hLmluc3RhbmNlT2YoVGhlbWUpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBEZWZhdWx0IFRoZW1lIG5hbWUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QoZ2V0RG9jdW1lbnRUaGVtZSgpLmdldE5hbWUoKSkuaXMuZXF1YWwoJ21vbnN0ZXInKTtcbiAgICAgICAgfSk7XG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdnZXREb2N1bWVudFRoZW1lKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdodG1sJykuc2V0QXR0cmlidXRlKCdkYXRhLW1vbnN0ZXItdGhlbWUtbmFtZScsICd0ZXN0dGhlbWUnKTtcbiAgICAgICAgfSlcblxuICAgICAgICBhZnRlckVhY2goKCkgPT4ge1xuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignaHRtbCcpLnJlbW92ZUF0dHJpYnV0ZSgnZGF0YS1tb25zdGVyLXRoZW1lLW5hbWUnKTtcbiAgICAgICAgfSlcblxuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiB0ZXN0dGhlbWUgVGhlbWUgbmFtZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChnZXREb2N1bWVudFRoZW1lKCkuZ2V0TmFtZSgpKS5pcy5lcXVhbCgndGVzdHRoZW1lJyk7XG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG59KTtcblxuXG4iLCAiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgY2hhaSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge2ludGVybmFsU3ltYm9sfSBmcm9tIFwiLi4vLi4vLi4vc291cmNlL2NvbnN0YW50cy5tanNcIjtcbmltcG9ydCB7QVRUUklCVVRFX09QVElPTlN9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvZG9tL2NvbnN0YW50cy5tanNcIjtcbmltcG9ydCB7Z2V0RG9jdW1lbnR9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvZG9tL3V0aWwubWpzXCI7XG5pbXBvcnQge1Byb3h5T2JzZXJ2ZXJ9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvdHlwZXMvcHJveHlvYnNlcnZlci5tanNcIjtcbmltcG9ydCB7YWRkT2JqZWN0V2l0aFVwZGF0ZXJUb0VsZW1lbnR9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvZG9tL3VwZGF0ZXIubWpzXCI7XG5pbXBvcnQge2NoYWlEb219IGZyb20gXCIuLi8uLi91dGlsL2NoYWktZG9tLm1qc1wiO1xuaW1wb3J0IHtpbml0SlNET019IGZyb20gXCIuLi8uLi91dGlsL2pzZG9tLm1qc1wiO1xuXG5cbmxldCBleHBlY3QgPSBjaGFpLmV4cGVjdDtcbmNoYWkudXNlKGNoYWlEb20pO1xuXG5sZXQgaHRtbDEgPSBgXG4gICAgPGRpdiBpZD1cInRlc3QxXCI+XG4gICAgPC9kaXY+XG5gO1xuXG5sZXQgaHRtbDIgPSBgXG4gICAgPGlucHV0IGRhdGEtbW9uc3Rlci1iaW5kPVwicGF0aDphXCIgaWQ9XCJ0ZXN0MlwiIGRhdGEtbW9uc3Rlci1hdHRyaWJ1dGVzPVwidmFsdWUgcGF0aDphXCI+XG5gO1xuXG4vLyBkZWZpbmVkIGluIGNvbnN0YW50cy5tanNcbmNvbnN0IHVwZGF0ZXJTeW1ib2xLZXkgPSBcIkBzY2h1a2FpL21vbnN0ZXIvZG9tL2N1c3RvbS1lbGVtZW50QEBvcHRpb25zLXVwZGF0ZXItbGlua1wiXG5jb25zdCB1cGRhdGVyU3ltYm9sU3ltYm9sID0gU3ltYm9sLmZvcih1cGRhdGVyU3ltYm9sS2V5KTtcblxuXG5cbmRlc2NyaWJlKCdET00nLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBsZXQgQ3VzdG9tRWxlbWVudCwgcmVnaXN0ZXJDdXN0b21FbGVtZW50LCBUZXN0Q29tcG9uZW50LCBkb2N1bWVudCwgVGVzdENvbXBvbmVudDIsYXNzaWduVXBkYXRlclRvRWxlbWVudDtcblxuXG4gICAgZGVzY3JpYmUoXCJhc3NpZ25VcGRhdGVyVG9FbGVtZW50XCIsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBiZWZvcmUoZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgICAgIGluaXRKU0RPTSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGltcG9ydChcIi4uLy4uLy4uL3NvdXJjZS9kb20vY3VzdG9tZWxlbWVudC5tanNcIikudGhlbigobSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgQ3VzdG9tRWxlbWVudCA9IG1bJ0N1c3RvbUVsZW1lbnQnXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFzc2lnblVwZGF0ZXJUb0VsZW1lbnQ9IGZ1bmN0aW9uIChlbGVtZW50cywgb2JqZWN0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFkZE9iamVjdFdpdGhVcGRhdGVyVG9FbGVtZW50LmNhbGwodGhpcywgZWxlbWVudHMsIHVwZGF0ZXJTeW1ib2xTeW1ib2wsIG9iamVjdCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnQgPSBnZXREb2N1bWVudCgpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBkb25lKClcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZG9uZShlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG5cbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pXG5cbiAgICAgICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICAgICAgICBsZXQgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgICAgIG1vY2tzLmlubmVySFRNTCA9IGh0bWwyO1xuICAgICAgICB9KVxuXG4gICAgICAgIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICAgICAgICBsZXQgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgICAgIG1vY2tzLmlubmVySFRNTCA9IFwiXCI7XG4gICAgICAgIH0pXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoaXMgdGVzdCB0cnkgdG8gc2ltdWxhdGUgdGhlIGJ1ZyB0aGF0IHdhcyBmb3VuZCBpbiB0aGUgYXNzaWduVXBkYXRlclRvRWxlbWVudCBmdW5jdGlvbi5cbiAgICAgICAgICogVGhlIGJ1ZyB3YXMgdGhhdCB0aGUgdXBkYXRlciB3YXMgbm90IGFzc2lnbmVkIHRvIHRoZSBlbGVtZW50IHdoZW4gdGhlIGVsZW1lbnQgd2FzIGNyZWF0ZWQuXG4gICAgICAgICAqIFxuICAgICAgICAgKiB1bmZvcnR1bmF0ZWx5LCB0aGlzIHRlc3QgZG9lcyBub3QgcmVwcm9kdWNlIHRoZSBidWcuXG4gICAgICAgICAqL1xuICAgICAgICBpdChcInNob3VsZCBhc3NpZ24gYW4gdXBkYXRlciB0byBhbiBlbGVtZW50XCIsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICBsZXQgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0ZXN0MicpO1xuXG4gICAgICAgICAgICBleHBlY3QoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJtb2Nrc1wiKS5pbm5lckhUTUwpLnRvLmVxdWFsKGh0bWwyKTtcblxuICAgICAgICAgICAgY29uc3QgYSA9IHthOiAxfTtcbiAgICAgICAgICAgIGNvbnN0IGIgPSB7YjogMn07XG5cbiAgICAgICAgICAgIGNvbnN0IGFwID0gbmV3IFByb3h5T2JzZXJ2ZXIoYSk7XG4gICAgICAgICAgICBjb25zdCBicCA9IG5ldyBQcm94eU9ic2VydmVyKGIpO1xuXG4gICAgICAgICAgICBjb25zdCB4ID0gYXAuZ2V0U3ViamVjdCgpXG4gICAgICAgICAgICBjb25zdCB5ID0gYnAuZ2V0U3ViamVjdCgpXG5cbiAgICAgICAgICAgIGNvbnN0IHNldCA9IG5ldyBTZXQoKTtcbiAgICAgICAgICAgIHNldC5hZGQoZWxlbWVudCk7XG5cbiAgICAgICAgICAgIGFzc2lnblVwZGF0ZXJUb0VsZW1lbnQuY2FsbChlbGVtZW50LCBzZXQsIGFwKTtcbiAgICAgICAgICAgIGFzc2lnblVwZGF0ZXJUb0VsZW1lbnQuY2FsbChlbGVtZW50LCBzZXQsIGJwKTtcblxuICAgICAgICAgICAgZXhwZWN0KEpTT04uc3RyaW5naWZ5KHgpKS50by5lcXVhbCgne1wiYVwiOjF9Jyk7XG4gICAgICAgICAgICBleHBlY3QoSlNPTi5zdHJpbmdpZnkoeSkpLnRvLmVxdWFsKCd7XCJiXCI6Mn0nKTtcblxuICAgICAgICAgICAgY29uc3Qgc3kgPSB1cGRhdGVyU3ltYm9sU3ltYm9sO1xuICAgICAgICAgICAgXG4gICAgICAgICAgICBsZXQgdiA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiZGF0YS1tb25zdGVyLW9iamVjdGxpbmtcIik7XG4gICAgICAgICAgICBleHBlY3QodikudG8uZXF1YWwoJ1N5bWJvbCgnK3VwZGF0ZXJTeW1ib2xLZXkrJyknKTtcblxuICAgICAgICAgICAgY29uc3QgdXBkYXRlciA9IGVsZW1lbnRbc3ldO1xuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHYgb2YgdXBkYXRlcikge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgdSBvZiB2KSB7XG4gICAgICAgICAgICAgICAgICAgIHUucnVuKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB1LmVuYWJsZUV2ZW50UHJvY2Vzc2luZygpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGV4cGVjdCh1cGRhdGVyKS50by5iZS5hbi5pbnN0YW5jZW9mKFNldCk7XG4gICAgICAgICAgICBleHBlY3QodXBkYXRlcikudG8uYmUuYShcIlNldFwiKTtcblxuICAgICAgICAgICAgeC5hID0gMztcbiAgICAgICAgICAgIGJwLmdldFN1YmplY3QoKS5iID0gNDtcblxuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG5cbiAgICAgICAgICAgICAgICBsZXQgbW9ja0hUTUwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcIm1vY2tzXCIpO1xuXG4gICAgICAgICAgICAgICAgLy8gaHRtbCBleHBleHRlZDpcbiAgICAgICAgICAgICAgICAvLyA8aW5wdXQgZGF0YS1tb25zdGVyLWJpbmQ9XCJwYXRoOmFcIiBpZD1cInRlc3QyXCIgZGF0YS1tb25zdGVyLWF0dHJpYnV0ZXM9XCJ2YWx1ZSBwYXRoOmFcIiBkYXRhLW1vbnN0ZXItb2JqZWN0bGluaz1cIlN5bWJvbChAc2NodWthaS9tb25zdGVyL2RvbS9AQG9iamVjdC11cGRhdGVyLWxpbmspXCIgdmFsdWU9XCIzXCI+XG5cbiAgICAgICAgICAgICAgICBleHBlY3QobW9ja0hUTUwucXVlcnlTZWxlY3RvcihcIiN0ZXN0MlwiKSkudG8uaGF2ZS52YWx1ZSgnMycpXG4gICAgICAgICAgICAgICAgZXhwZWN0KG1vY2tIVE1MLnF1ZXJ5U2VsZWN0b3IoXCIjdGVzdDJcIikpLnRvLmhhdmUuYXR0cmlidXRlKCdkYXRhLW1vbnN0ZXItb2JqZWN0bGluaycsICdTeW1ib2woJyt1cGRhdGVyU3ltYm9sS2V5KycpJylcbiAgICAgICAgICAgICAgICAvL2V4cGVjdChtb2NrSFRNTCkudG8uaGF2ZS5odG1sKHJlc3VsdEhUTUwpO1xuXG4gICAgICAgICAgICAgICAgZXhwZWN0KGVsZW1lbnQudmFsdWUpLnRvLmVxdWFsKFwiM1wiKTtcblxuICAgICAgICAgICAgICAgIGV4cGVjdChKU09OLnN0cmluZ2lmeShhcC5nZXRSZWFsU3ViamVjdCgpKSkudG8uZXF1YWwoJ3tcImFcIjozfScpO1xuICAgICAgICAgICAgICAgIGV4cGVjdChKU09OLnN0cmluZ2lmeShicC5nZXRSZWFsU3ViamVjdCgpKSkudG8uZXF1YWwoJ3tcImJcIjo0fScpO1xuICAgICAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICAgICAgfSwgMTApXG5cbiAgICAgICAgfSlcblxuICAgIH0pXG5cblxuICAgIGRlc2NyaWJlKCdDdXN0b21FbGVtZW50KCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgYmVmb3JlKGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICBpbml0SlNET00oKS50aGVuKCgpID0+IHtcblxuICAgICAgICAgICAgICAgIGltcG9ydChcIi4uLy4uLy4uL3NvdXJjZS9kb20vY3VzdG9tZWxlbWVudC5tanNcIikudGhlbigobSkgPT4ge1xuXG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBDdXN0b21FbGVtZW50ID0gbVsnQ3VzdG9tRWxlbWVudCddO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVnaXN0ZXJDdXN0b21FbGVtZW50ID0gbVsncmVnaXN0ZXJDdXN0b21FbGVtZW50J107XG4gICAgICAgICAgICAgICAgICAgICAgICBUZXN0Q29tcG9uZW50ID0gY2xhc3MgZXh0ZW5kcyBDdXN0b21FbGVtZW50IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0aWMgZ2V0VGFnKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJtb25zdGVyLXRlc3RjbGFzc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICByZWdpc3RlckN1c3RvbUVsZW1lbnQoVGVzdENvbXBvbmVudClcblxuICAgICAgICAgICAgICAgICAgICAgICAgVGVzdENvbXBvbmVudDIgPSBjbGFzcyBleHRlbmRzIEN1c3RvbUVsZW1lbnQge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRpYyBnZXRUYWcoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm1vbnN0ZXItdGVzdGNsYXNzMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBAcmV0dXJuIHtPYmplY3R9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0IGRlZmF1bHRzKCkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdXBlci5kZWZhdWx0cywge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVtb3Rlc3Q6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBsYXRlczoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1haW46ICc8aDE+PC9oMT48YXJ0aWNsZT48cD50ZXN0PC9wPjxkaXYgaWQ9XCJjb250YWluZXJcIj48L2Rpdj48L2FydGljbGU+J1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgcmVnaXN0ZXJDdXN0b21FbGVtZW50KFRlc3RDb21wb25lbnQyKVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBkb2N1bWVudCA9IGdldERvY3VtZW50KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBkb25lKClcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZG9uZShlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG5cbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pXG5cbiAgICAgICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICAgICAgICBsZXQgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgICAgIG1vY2tzLmlubmVySFRNTCA9IGh0bWwxO1xuICAgICAgICB9KVxuXG4gICAgICAgIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICAgICAgICBsZXQgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgICAgIG1vY2tzLmlubmVySFRNTCA9IFwiXCI7XG4gICAgICAgIH0pXG5cbiAgICAgICAgZGVzY3JpYmUoJ0N1c3RvbUVsZW1lbnQoKSB3aXRoIENvbmZpZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGl0KCdzaG91bGQgcmVhZCBjb25maWcgZnJvbSB0YWcnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgICAgICAgICBtb2Nrcy5pbm5lckhUTUwgPSBgXG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgPHNjcmlwdCBpZD1cImNvbmZpZzFcIiB0eXBlPVwiYXBwbGljYXRpb24vanNvblwiPlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgXCJkZW1vdGVzdFwiOjE0MjVcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgPC9zY3JpcHQ+XG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgPG1vbnN0ZXItdGVzdGNsYXNzMiBpZD1cInRoaXNpc2F0ZXN0XCIgZGF0YS1tb25zdGVyLW9wdGlvbnMtc2VsZWN0b3I9XCIjY29uZmlnMVwiPlxuICAgICAgICAgICAgICAgIDwvbW9uc3Rlci10ZXN0Y2xhc3MyPlxuICAgICAgICAgICAgICAgIGA7XG5cbiAgICAgICAgICAgICAgICBsZXQgbW9uc3RlciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0aGlzaXNhdGVzdCcpO1xuICAgICAgICAgICAgICAgIGV4cGVjdChtb25zdGVyLmdldE9wdGlvbignZGVtb3Rlc3QnKSkuaXMuZXFsKDE0MjUpO1xuXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZGVzY3JpYmUoJ2NyZWF0ZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGN1c3RvbS1lbGVtZW50IG9iamVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBsZXQgZCA9IG5ldyBUZXN0Q29tcG9uZW50KCk7XG4gICAgICAgICAgICAgICAgZXhwZWN0KHR5cGVvZiBkKS5pcy5lcXVhbCgnb2JqZWN0Jyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZGVzY3JpYmUoJ2Nvbm5lY3QgZW1wdHkgZWxlbWVudCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGl0KCdkb2N1bWVudCBzaG91bGQgY29udGFpbiBtb25zdGVyLXRlc3RjbGFzcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBsZXQgZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ21vbnN0ZXItdGVzdGNsYXNzJyk7XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Rlc3QxJykuYXBwZW5kQ2hpbGQoZCk7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdtb25zdGVyLXRlc3RjbGFzcycpLmxlbmd0aCkuaXMuZXF1YWwoMSk7XG4gICAgICAgICAgICAgICAgLy8gbm8gZGF0YS1tb25zdGVyLW9iamVjdGxpbms9XCJTeW1ib2wobW9uc3RlclVwZGF0ZXIpXCIgYmVjYXVzZSBpdCBoYXMgbm90aGluZyB0byB1cGRhdGVcbiAgICAgICAgICAgICAgICAvLyBidXQgZGF0YS1tb25zdGVyLWVycm9yPVwiRXJyb3I6IGh0bWwgaXMgbm90IHNldC5cIlxuICAgICAgICAgICAgICAgIGV4cGVjdChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGVzdDEnKSkuY29udGFpbi5odG1sKCc8bW9uc3Rlci10ZXN0Y2xhc3MgZGF0YS1tb25zdGVyLWVycm9yPVwiRXJyb3I6IGh0bWwgaXMgbm90IHNldC5cIj48L21vbnN0ZXItdGVzdGNsYXNzPicpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGRlc2NyaWJlKCdjb25uZWN0IGVsZW1lbnQgd2l0aCBodG1sJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaXQoJ2RvY3VtZW50IHNob3VsZCBjb250YWluIG1vbnN0ZXItdGVzdGNsYXNzMicsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICAgICAgbGV0IGQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdtb25zdGVyLXRlc3RjbGFzczInKTtcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGVzdDEnKS5hcHBlbmRDaGlsZChkKTtcblxuICAgICAgICAgICAgICAgIC8vIGluc2VydCBET00gcnVuIGluIGV4dHJhIHByb2Nlc3MgdmlhIHNldFRpbWVvdXQhXG4gICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBleHBlY3QoZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ21vbnN0ZXItdGVzdGNsYXNzMicpLmxlbmd0aCkuaXMuZXF1YWwoMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBleHBlY3QoZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ21vbnN0ZXItdGVzdGNsYXNzMicpLml0ZW0oMCkuc2hhZG93Um9vdC5pbm5lckhUTUwpLmlzLmVxdWFsKCc8aDE+PC9oMT48YXJ0aWNsZT48cD50ZXN0PC9wPjxkaXYgaWQ9XCJjb250YWluZXJcIj48L2Rpdj48L2FydGljbGU+Jyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBleHBlY3QoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Rlc3QxJykpLmNvbnRhaW4uaHRtbCgnPG1vbnN0ZXItdGVzdGNsYXNzMiBkYXRhLW1vbnN0ZXItb2JqZWN0bGluaz1cIlN5bWJvbCgnK3VwZGF0ZXJTeW1ib2xLZXkrJylcIj48L21vbnN0ZXItdGVzdGNsYXNzMj4nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkb25lKCk7XG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRvbmUoZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIH0sIDEwKTtcblxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGRlc2NyaWJlKCdPcHRpb25zIGNoYW5nZScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgaXQoJ2RlbGVnYXRlc0ZvY3VzIHNob3VsZCBjaGFuZ2UgZnJvbSB0cnVlIHRvIGZhbHNlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGxldCBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbW9uc3Rlci10ZXN0Y2xhc3MnKVxuXG4gICAgICAgICAgICAgICAgY29uc3QgbyA9IGVsZW1lbnRbaW50ZXJuYWxTeW1ib2xdLnJlYWxTdWJqZWN0O1xuICAgICAgICAgICAgICAgIGV4cGVjdChPYmplY3QuaXMoZWxlbWVudFtpbnRlcm5hbFN5bWJvbF0ucmVhbFN1YmplY3QsIG8pKS50by5iZS50cnVlO1xuXG4gICAgICAgICAgICAgICAgZXhwZWN0KGVsZW1lbnRbaW50ZXJuYWxTeW1ib2xdLnJlYWxTdWJqZWN0Lm9wdGlvbnMuZGVsZWdhdGVzRm9jdXMpLnRvLmJlLnRydWU7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGVsZW1lbnRbaW50ZXJuYWxTeW1ib2xdLnN1YmplY3Qub3B0aW9ucy5kZWxlZ2F0ZXNGb2N1cykudG8uYmUudHJ1ZTtcbiAgICAgICAgICAgICAgICBleHBlY3QoZWxlbWVudC5nZXRPcHRpb24oJ2RlbGVnYXRlc0ZvY3VzJykpLnRvLmJlLnRydWU7XG4gICAgICAgICAgICAgICAgZXhwZWN0KE9iamVjdC5pcyhlbGVtZW50W2ludGVybmFsU3ltYm9sXS5yZWFsU3ViamVjdCwgbykpLnRvLmJlLnRydWU7XG5cbiAgICAgICAgICAgICAgICAvLyBlbGVtZW50LnNldEF0dHJpYnV0ZShBVFRSSUJVVEVfT1BUSU9OUywgSlNPTi5zdHJpbmdpZnkoe2RlbGVnYXRlc0ZvY3VzOiBmYWxzZX0pKTtcbiAgICAgICAgICAgICAgICAvLyBleHBlY3QoT2JqZWN0LmlzKGVsZW1lbnRbaW50ZXJuYWxTeW1ib2xdLnJlYWxTdWJqZWN0LCBvKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgIC8vIGV4cGVjdChlbGVtZW50LmdldE9wdGlvbignZGVsZWdhdGVzRm9jdXMnKSkudG8uYmUuZmFsc2U7XG4gICAgICAgICAgICAgICAgLy8gZXhwZWN0KGVsZW1lbnRbaW50ZXJuYWxTeW1ib2xdLnJlYWxTdWJqZWN0Lm9wdGlvbnMuZGVsZWdhdGVzRm9jdXMpLnRvLmJlLmZhbHNlO1xuICAgICAgICAgICAgICAgIC8vIGV4cGVjdChPYmplY3QuaXMoZWxlbWVudFtpbnRlcm5hbFN5bWJvbF0ucmVhbFN1YmplY3QsIG8pKS50by5iZS50cnVlO1xuXG4gICAgICAgICAgICB9KVxuXG5cbiAgICAgICAgfSlcblxuICAgICAgICBkZXNjcmliZSgnc2V0T3B0aW9ucygpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgIFsnc2hhZG93TW9kZScsICd4MSddLFxuICAgICAgICAgICAgICAgIFsndGVtcGxhdGVzLm1haW4nLCAneDInXSwgLy8gaXMgZXhwbGljaXRseSBzZXQgdG8gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgWydkZWxlZ2F0ZXNGb2N1cycsICd4NCddLFxuICAgICAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cblxuICAgICAgICAgICAgICAgIGxldCBrZXkgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgICAgICBsZXQgbmV3VmFsdWUgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgICAgIGxldCB0ZXh0ID0ga2V5ICsgJyBzaG91bGQgcmV0dXJuICcgKyBuZXdWYWx1ZTtcbiAgICAgICAgICAgICAgICBpZiAobmV3VmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICB0ZXh0ID0ga2V5ICsgJyB3YXMgbm90IHNldCwgdGhlcmVmb3JlIGRlZmF1bHQgJyArIG5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgIH1cblxuXG4gICAgICAgICAgICAgICAgaXQodGV4dCwgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICAgICAgICAgIGxldCBkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbW9uc3Rlci10ZXN0Y2xhc3MnKTtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KGQuZ2V0T3B0aW9uKGtleSkpLnRvLmJlLm5vdC5lcXVhbChuZXdWYWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIGxldCB4ID0gZC5zZXRPcHRpb24oa2V5LCBuZXdWYWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChkLmdldE9wdGlvbihrZXkpKS50by5iZS5lcXVhbChuZXdWYWx1ZSk7XG4gICAgICAgICAgICAgICAgfSlcblxuXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KTtcblxuICAgICAgICBkZXNjcmliZSgnZ2V0T3B0aW9ucygpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgWydzaGFkb3dNb2RlJywgJ29wZW4nXSxcbiAgICAgICAgICAgICAgICBbJ3RlbXBsYXRlcy5tYWluJywgdW5kZWZpbmVkXSwgLy8gaXMgZXhwbGljaXRseSBzZXQgdG8gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgWydkZWxlZ2F0ZXNGb2N1cycsIHRydWVdLFxuICAgICAgICAgICAgICAgIFsneC55LnonLCB0cnVlLCB0cnVlXSwgLy8geC55LnogaXNudCBzZXQsIGRlZmF1bHRWYWx1ZSBpcyB1c2VkXG4gICAgICAgICAgICAgICAgWyd4JywgdHJ1ZSwgdHJ1ZV0gLy8geCBpc250IHNldCwgZGVmYXVsdFZhbHVlIGlzIHVzZWRcbiAgICAgICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG5cbiAgICAgICAgICAgICAgICBsZXQga2V5ID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICAgICAgbGV0IHZhbHVlID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICAgICAgbGV0IGRlZmF1bHRWYWx1ZSA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICAgICAgbGV0IHRleHQgPSBrZXkgKyAnIHNob3VsZCByZXR1cm4gJyArIHZhbHVlO1xuICAgICAgICAgICAgICAgIGlmIChkZWZhdWx0VmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICB0ZXh0ID0ga2V5ICsgJyB3YXMgbm90IHNldCwgdGhlcmVmb3JlIGRlZmF1bHQgJyArIGRlZmF1bHRWYWx1ZTtcbiAgICAgICAgICAgICAgICB9XG5cblxuICAgICAgICAgICAgICAgIGl0KHRleHQsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgICAgICBsZXQgZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ21vbnN0ZXItdGVzdGNsYXNzJyk7XG4gICAgICAgICAgICAgICAgICAgIGxldCB4ID0gZC5nZXRPcHRpb24oa2V5LCBkZWZhdWx0VmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QoeCkudG8uYmUuZXF1YWwodmFsdWUpO1xuICAgICAgICAgICAgICAgIH0pXG5cblxuICAgICAgICAgICAgfSlcbiAgICAgICAgfSlcblxuICAgICAgICAvKipcbiAgICAgICAgICogQGxpbmsgaHR0cHM6Ly9naXRsYWIuc2NodWthaS5jb20vb3NzL2xpYnJhcmllcy9qYXZhc2NyaXB0L21vbnN0ZXIvLS9pc3N1ZXMvMTEzXG4gICAgICAgICAqL1xuICAgICAgICBkZXNjcmliZSgnQXNzaWduIENTU1N0eWxlIGFzIEFycmF5IHdpdGggd3JvbmcgdHlwZScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgY29uc3QgaHRtbFRBRyA9ICdtb25zdGVyLXRlc3RjbGFzcy14MSc7XG5cbiAgICAgICAgICAgIGxldCBtb2NrcywgVGVzdENvbXBvbmVudFgxO1xuICAgICAgICAgICAgYmVmb3JlRWFjaCgoKSA9PiB7XG5cbiAgICAgICAgICAgICAgICBtb2NrcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpO1xuICAgICAgICAgICAgICAgIG1vY2tzLmlubmVySFRNTCA9IGh0bWwxO1xuXG5cbiAgICAgICAgICAgICAgICBUZXN0Q29tcG9uZW50WDEgPSBjbGFzcyBleHRlbmRzIEN1c3RvbUVsZW1lbnQge1xuICAgICAgICAgICAgICAgICAgICBzdGF0aWMgZ2V0VGFnKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGh0bWxUQUdcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHN0YXRpYyBnZXRDU1NTdHlsZVNoZWV0KCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFt0cnVlXTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICAgICAgICAgKiBAcmV0dXJuIHtPYmplY3R9XG4gICAgICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgICAgICBnZXQgZGVmYXVsdHMoKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdXBlci5kZWZhdWx0cywge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBsYXRlczoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYWluOiAnPGgxPnRlc3Q8L2gxPidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmVnaXN0ZXJDdXN0b21FbGVtZW50KFRlc3RDb21wb25lbnRYMSlcblxuXG4gICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICBpdChodG1sVEFHICsgXCIgc2hvdWxkIHRocm93IEV4Y2VwdGlvblwiLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICAgICAgICAgIGxldCBkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChodG1sVEFHKTtcblxuICAgICAgICAgICAgICAgIGxldCBkaXYgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGVzdDEnKTtcbiAgICAgICAgICAgICAgICBkaXYuYXBwZW5kKGQpO1xuXG5cbiAgICAgICAgICAgICAgICBleHBlY3QoZGl2KS5jb250YWluLmh0bWwoJ2RhdGEtbW9uc3Rlci1lcnJvcj1cIlR5cGVFcnJvcjogdmFsdWUgaXMgbm90IGFuIGluc3RhbmNlIG9mIENTU1N0eWxlU2hlZXRcIicpO1xuICAgICAgICAgICAgICAgIGRvbmUoKTtcblxuICAgICAgICAgICAgfSlcblxuXG4gICAgICAgIH0pXG5cblxuICAgICAgICAvKipcbiAgICAgICAgICogQGxpbmsgaHR0cHM6Ly9naXRsYWIuc2NodWthaS5jb20vb3NzL2xpYnJhcmllcy9qYXZhc2NyaXB0L21vbnN0ZXIvLS9pc3N1ZXMvMTEzXG4gICAgICAgICAqL1xuICAgICAgICBkZXNjcmliZSgnQXNzaWduIENTU1N0eWxlIGFzIEFycmF5IGFuZCBDU1NTdHlsZXNoZWV0JywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBjb25zdCBodG1sVEFHID0gJ21vbnN0ZXItdGVzdGNsYXNzLXgxMTMtMic7XG5cbiAgICAgICAgICAgIGxldCBtb2NrcywgVGVzdENvbXBvbmVudFgxMTNYMjtcbiAgICAgICAgICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuXG4gICAgICAgICAgICAgICAgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgICAgICAgICBtb2Nrcy5pbm5lckhUTUwgPSBodG1sMTtcblxuICAgICAgICAgICAgICAgIFRlc3RDb21wb25lbnRYMTEzWDIgPSBjbGFzcyBleHRlbmRzIEN1c3RvbUVsZW1lbnQge1xuICAgICAgICAgICAgICAgICAgICBzdGF0aWMgZ2V0VGFnKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGh0bWxUQUdcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICAgICAgICAgKiBAcmV0dXJuIHtPYmplY3R9XG4gICAgICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgICAgICBnZXQgZGVmYXVsdHMoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3VwZXIuZGVmYXVsdHMsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wbGF0ZXM6IHttYWluOiAnPGgxPnRlc3Q8L2gxPid9LFxuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgfVxuXG5cbiAgICAgICAgICAgICAgICAgICAgc3RhdGljIGdldENTU1N0eWxlU2hlZXQoKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHMgPSAobmV3IENTU1N0eWxlU2hlZXQoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHMuaW5zZXJ0UnVsZSgnYSB7IGNvbG9yIDogcmVkfScpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gW3NdO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmVnaXN0ZXJDdXN0b21FbGVtZW50KFRlc3RDb21wb25lbnRYMTEzWDIpXG5cblxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgaXQoaHRtbFRBRyArIFwiIHNob3VsZCB0aHJvdyBFeGNlcHRpb24gMlwiLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICAgICAgICAgIGxldCBkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChodG1sVEFHKTtcblxuICAgICAgICAgICAgICAgIGxldCBkaXYgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGVzdDEnKTtcbiAgICAgICAgICAgICAgICBkaXYuYXBwZW5kKGQpO1xuXG4gICAgICAgICAgICAgICAgZXhwZWN0KGQuc2hhZG93Um9vdC5pbm5lckhUTUwpLmlzLmVxKCc8aDE+dGVzdDwvaDE+Jyk7XG4gICAgICAgICAgICAgICAgZG9uZSgpO1xuXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAbGluayBodHRwczovL2dpdGxhYi5zY2h1a2FpLmNvbS9vc3MvbGlicmFyaWVzL2phdmFzY3JpcHQvbW9uc3Rlci8tL2lzc3Vlcy8xMTNcbiAgICAgICAgICovXG4gICAgICAgIGRlc2NyaWJlKCdBc3NpZ24gQ1NTU3R5bGUgYXMgQXJyYXkgYW5kIENTUyBhcyBzdHJpbmcnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIGNvbnN0IGh0bWxUQUcgPSAnbW9uc3Rlci10ZXN0Y2xhc3MteDExMy0yMSc7XG5cbiAgICAgICAgICAgIGxldCBtb2NrcywgVGVzdENvbXBvbmVudFgxMTNYMjI7XG4gICAgICAgICAgICBiZWZvcmVFYWNoKCgpID0+IHtcblxuICAgICAgICAgICAgICAgIG1vY2tzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vY2tzJyk7XG4gICAgICAgICAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gaHRtbDE7XG5cbiAgICAgICAgICAgICAgICBUZXN0Q29tcG9uZW50WDExM1gyMiA9IGNsYXNzIGV4dGVuZHMgQ3VzdG9tRWxlbWVudCB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXRpYyBnZXRUYWcoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaHRtbFRBR1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgICAgICAgICAqIEByZXR1cm4ge09iamVjdH1cbiAgICAgICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgICAgIGdldCBkZWZhdWx0cygpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdXBlci5kZWZhdWx0cywge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBsYXRlczoge21haW46ICc8aDE+dGVzdDwvaDE+J30sXG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICB9XG5cblxuICAgICAgICAgICAgICAgICAgICBzdGF0aWMgZ2V0Q1NTU3R5bGVTaGVldCgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAnYSB7IGNvbG9yOnJlZCB9JztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJlZ2lzdGVyQ3VzdG9tRWxlbWVudChUZXN0Q29tcG9uZW50WDExM1gyMilcblxuXG4gICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICBpdChodG1sVEFHICsgXCIgc2hvdWxkIGVxIDxzdHlsZT5hIHsgY29sb3I6cmVkIH08L3N0eWxlPjxoMT50ZXN0PC9oMT5cIiwgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgICAgICAgICBsZXQgZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoaHRtbFRBRyk7XG5cbiAgICAgICAgICAgICAgICBsZXQgZGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Rlc3QxJyk7XG4gICAgICAgICAgICAgICAgZGl2LmFwcGVuZChkKTtcblxuXG4gICAgICAgICAgICAgICAgZXhwZWN0KGQuc2hhZG93Um9vdC5pbm5lckhUTUwpLmlzLmVxKCc8c3R5bGU+YSB7IGNvbG9yOnJlZCB9PC9zdHlsZT48aDE+dGVzdDwvaDE+Jyk7XG4gICAgICAgICAgICAgICAgZG9uZSgpO1xuXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KVxuICAgICAgICAvKipcbiAgICAgICAgICogQGxpbmsgaHR0cHM6Ly9naXRsYWIuc2NodWthaS5jb20vb3NzL2xpYnJhcmllcy9qYXZhc2NyaXB0L21vbnN0ZXIvLS9pc3N1ZXMvMTEzXG4gICAgICAgICAqL1xuICAgICAgICBkZXNjcmliZSgnQXNzaWduIENTU1N0eWxlIGFzIEFycmF5IGFuZCBDU1MgYXMgc3RyaW5nJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBjb25zdCBodG1sVEFHID0gJ21vbnN0ZXItdGVzdGNsYXNzLXgxMTMtMjInO1xuXG4gICAgICAgICAgICBsZXQgbW9ja3MsIFRlc3RDb21wb25lbnRYMTEzWDIyMztcbiAgICAgICAgICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuXG4gICAgICAgICAgICAgICAgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgICAgICAgICBtb2Nrcy5pbm5lckhUTUwgPSBodG1sMTtcblxuICAgICAgICAgICAgICAgIFRlc3RDb21wb25lbnRYMTEzWDIyMyA9IGNsYXNzIGV4dGVuZHMgQ3VzdG9tRWxlbWVudCB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXRpYyBnZXRUYWcoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaHRtbFRBR1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgICAgICAgICAqIEByZXR1cm4ge09iamVjdH1cbiAgICAgICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgICAgIGdldCBkZWZhdWx0cygpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdXBlci5kZWZhdWx0cywge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBsYXRlczoge21haW46ICc8aDE+dGVzdDwvaDE+J30sXG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICB9XG5cblxuICAgICAgICAgICAgICAgICAgICBzdGF0aWMgZ2V0Q1NTU3R5bGVTaGVldCgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbJ2EgeyBjb2xvcjpyZWQgfSddO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmVnaXN0ZXJDdXN0b21FbGVtZW50KFRlc3RDb21wb25lbnRYMTEzWDIyMylcblxuXG4gICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICBpdChodG1sVEFHICsgXCIgc2hvdWxkIGVxIDxzdHlsZT5hIHsgY29sb3I6cmVkIH08L3N0eWxlPjxoMT50ZXN0PC9oMT5cIiwgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgICAgICAgICBsZXQgZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoaHRtbFRBRyk7XG5cbiAgICAgICAgICAgICAgICBsZXQgZGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Rlc3QxJyk7XG4gICAgICAgICAgICAgICAgZGl2LmFwcGVuZChkKTtcblxuXG4gICAgICAgICAgICAgICAgZXhwZWN0KGQuc2hhZG93Um9vdC5pbm5lckhUTUwpLmlzLmVxKCc8c3R5bGU+YSB7IGNvbG9yOnJlZCB9PC9zdHlsZT48aDE+dGVzdDwvaDE+Jyk7XG4gICAgICAgICAgICAgICAgZG9uZSgpO1xuXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KVxuXG4gICAgICAgIGRlc2NyaWJlKCdoYXNOb2RlKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIGxldCBtb2NrcztcbiAgICAgICAgICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuXG4gICAgICAgICAgICAgICAgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgICAgICAgICBtb2Nrcy5pbm5lckhUTUwgPSBodG1sMTtcblxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgaXQoXCJoYXNOb2RlIG1vbnN0ZXItdGVzdGNsYXNzIHNob3VsZCByZXR1cm4gLi4uXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBsZXQgZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ21vbnN0ZXItdGVzdGNsYXNzJyk7XG5cbiAgICAgICAgICAgICAgICBsZXQgcDEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdwJyk7XG4gICAgICAgICAgICAgICAgbGV0IHQxID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoJ3Rlc3QxJyk7XG4gICAgICAgICAgICAgICAgcDEuYXBwZW5kQ2hpbGQodDEpO1xuXG4gICAgICAgICAgICAgICAgbGV0IHAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgICAgICBsZXQgdCA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCd0ZXN0Jyk7XG4gICAgICAgICAgICAgICAgcC5hcHBlbmRDaGlsZChwMSk7XG4gICAgICAgICAgICAgICAgcC5hcHBlbmRDaGlsZCh0KTtcbiAgICAgICAgICAgICAgICBkLmFwcGVuZENoaWxkKHApO1xuXG4gICAgICAgICAgICAgICAgbGV0IGRpdiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0ZXN0MScpO1xuICAgICAgICAgICAgICAgIGRpdi5hcHBlbmQoZCk7XG5cblxuICAgICAgICAgICAgICAgIGxldCBuMSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3AnKTtcblxuICAgICAgICAgICAgICAgIGV4cGVjdChkLmhhc05vZGUobjEpKS50by5iZS5mYWxzZTtcbiAgICAgICAgICAgICAgICBleHBlY3QoZC5oYXNOb2RlKHQpKS50by5iZS50cnVlO1xuICAgICAgICAgICAgICAgIGV4cGVjdChkLmhhc05vZGUocCkpLnRvLmJlLnRydWU7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGQuaGFzTm9kZShwMSkpLnRvLmJlLnRydWU7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGQuaGFzTm9kZSh0MSkpLnRvLmJlLnRydWU7XG5cbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGl0KFwiaGFzTm9kZSBtb25zdGVyLXRlc3RjbGFzczIgc2hvdWxkIHJldHVybiAuLi5cIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGxldCBkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbW9uc3Rlci10ZXN0Y2xhc3MyJyk7XG5cbiAgICAgICAgICAgICAgICBsZXQgcDEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdwJyk7XG4gICAgICAgICAgICAgICAgbGV0IHQxID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoJ3Rlc3QxJyk7XG4gICAgICAgICAgICAgICAgcDEuYXBwZW5kQ2hpbGQodDEpO1xuXG4gICAgICAgICAgICAgICAgbGV0IHAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgICAgICBsZXQgdCA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCd0ZXN0Jyk7XG4gICAgICAgICAgICAgICAgcC5hcHBlbmRDaGlsZChwMSk7XG4gICAgICAgICAgICAgICAgcC5hcHBlbmRDaGlsZCh0KTtcblxuXG4gICAgICAgICAgICAgICAgbGV0IGRpdiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0ZXN0MScpO1xuICAgICAgICAgICAgICAgIGRpdi5hcHBlbmQoZCk7XG5cbiAgICAgICAgICAgICAgICBsZXQgYSA9IGQuc2hhZG93Um9vdC5nZXRFbGVtZW50QnlJZCgnY29udGFpbmVyJyk7XG5cbiAgICAgICAgICAgICAgICBkLnNoYWRvd1Jvb3QuZ2V0RWxlbWVudEJ5SWQoJ2NvbnRhaW5lcicpLmFwcGVuZENoaWxkKHApO1xuXG4gICAgICAgICAgICAgICAgbGV0IG4xID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgncCcpO1xuXG4gICAgICAgICAgICAgICAgZXhwZWN0KGQuaGFzTm9kZShuMSkpLnRvLmJlLmZhbHNlO1xuICAgICAgICAgICAgICAgIGV4cGVjdChkLmhhc05vZGUodCkpLnRvLmJlLnRydWU7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGQuaGFzTm9kZShwKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgICAgICAgICBleHBlY3QoZC5oYXNOb2RlKHAxKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgICAgICAgICBleHBlY3QoZC5oYXNOb2RlKHQxKSkudG8uYmUudHJ1ZTtcblxuICAgICAgICAgICAgfSlcblxuXG4gICAgICAgIH0pXG5cbiAgICB9KTtcbn0pIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgZXh0ZW5kIH0gZnJvbSBcIi4uL2RhdGEvZXh0ZW5kLm1qc1wiO1xuaW1wb3J0IHsgQmFzZVdpdGhPcHRpb25zIH0gZnJvbSBcIi4uL3R5cGVzL2Jhc2V3aXRob3B0aW9ucy5tanNcIjtcbmltcG9ydCB7IGdldEdsb2JhbE9iamVjdCB9IGZyb20gXCIuLi90eXBlcy9nbG9iYWwubWpzXCI7XG5pbXBvcnQgeyBpc0FycmF5IH0gZnJvbSBcIi4uL3R5cGVzL2lzLm1qc1wiO1xuaW1wb3J0IHsgU3RhY2sgfSBmcm9tIFwiLi4vdHlwZXMvc3RhY2subWpzXCI7XG5pbXBvcnQgeyB2YWxpZGF0ZUluc3RhbmNlLCB2YWxpZGF0ZVN0cmluZyB9IGZyb20gXCIuLi90eXBlcy92YWxpZGF0ZS5tanNcIjtcbmltcG9ydCB7IGluc3RhbmNlU3ltYm9sIH0gZnJvbSBcIi4uL2NvbnN0YW50cy5tanNcIjtcbmV4cG9ydCB7IEZvY3VzTWFuYWdlciB9O1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAdHlwZSB7c3RyaW5nfVxuICovXG5jb25zdCBLRVlfRE9DVU1FTlQgPSBcImRvY3VtZW50XCI7XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEB0eXBlIHtzdHJpbmd9XG4gKi9cbmNvbnN0IEtFWV9DT05URVhUID0gXCJjb250ZXh0XCI7XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEB0eXBlIHtTeW1ib2x9XG4gKi9cbmNvbnN0IHN0YWNrU3ltYm9sID0gU3ltYm9sKFwic3RhY2tcIik7XG5cbi8qKlxuICogV2l0aCB0aGUgZm9jdXMgbWFuYWdlciB0aGUgZm9jdXMgY2FuIGJlIHN0b3JlZCBpbiBhIGRvY3VtZW50LCByZWNhbGxlZCBhbmQgbW92ZWQuXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNS4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRE9NXG4gKiBAdGhyb3dzIHtFcnJvcn0gdW5zdXBwb3J0ZWQgbG9jYWxlXG4gKiBAc3VtbWFyeSBIYW5kbGUgdGhlIGZvY3VzXG4gKi9cbmNsYXNzIEZvY3VzTWFuYWdlciBleHRlbmRzIEJhc2VXaXRoT3B0aW9ucyB7XG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge09iamVjdHx1bmRlZmluZWR9IG9wdGlvbnNcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgICAgICB2YWxpZGF0ZUluc3RhbmNlKHRoaXMuZ2V0T3B0aW9uKEtFWV9ET0NVTUVOVCksIEhUTUxEb2N1bWVudCk7XG5cbiAgICAgICAgdGhpc1tzdGFja1N5bWJvbF0gPSBuZXcgU3RhY2soKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGBpbnN0YW5jZW9mYCBvcGVyYXRvci5cbiAgICAgKiBAcmV0dXJucyB7c3ltYm9sfVxuICAgICAqIEBzaW5jZSAyLjEuMFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgW2luc3RhbmNlU3ltYm9sXSgpIHtcbiAgICAgICAgcmV0dXJuIFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL2RvbS9mb2N1c21hbmFnZXJcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHByb3BlcnR5IHtIVE1MRG9jdW1lbnR9IGRvY3VtZW50IHRoZSBkb2N1bWVudCBvYmplY3QgaW50byB3aGljaCB0aGUgbm9kZSBpcyB0byBiZSBhcHBlbmRlZFxuICAgICAqL1xuICAgIGdldCBkZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIGV4dGVuZCh7fSwgc3VwZXIuZGVmYXVsdHMsIHtcbiAgICAgICAgICAgIFtLRVlfRE9DVU1FTlRdOiBnZXRHbG9iYWxPYmplY3QoXCJkb2N1bWVudFwiKSxcbiAgICAgICAgICAgIFtLRVlfQ09OVEVYVF06IHVuZGVmaW5lZCxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtZW1iZXJzIHRoZSBjdXJyZW50IGZvY3VzIG9uIGEgc3RhY2suXG4gICAgICogU2V2ZXJhbCBmb2N1cyBjYW4gYmUgc3RvcmVkLlxuICAgICAqXG4gICAgICogQHJldHVybiB7TW9uc3Rlci5ET00uRm9jdXNNYW5hZ2VyfVxuICAgICAqL1xuICAgIHN0b3JlRm9jdXMoKSB7XG4gICAgICAgIGNvbnN0IGFjdGl2ZSA9IHRoaXMuZ2V0QWN0aXZlKCk7XG4gICAgICAgIGlmIChhY3RpdmUgaW5zdGFuY2VvZiBOb2RlKSB7XG4gICAgICAgICAgICB0aGlzW3N0YWNrU3ltYm9sXS5wdXNoKGFjdGl2ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGxhc3QgZm9jdXMgb24gdGhlIHN0YWNrIGlzIHNldCBhZ2FpblxuICAgICAqXG4gICAgICogQHJldHVybiB7TW9uc3Rlci5ET00uRm9jdXNNYW5hZ2VyfVxuICAgICAqL1xuICAgIHJlc3RvcmVGb2N1cygpIHtcbiAgICAgICAgY29uc3QgbGFzdCA9IHRoaXNbc3RhY2tTeW1ib2xdLnBvcCgpO1xuICAgICAgICBpZiAobGFzdCBpbnN0YW5jZW9mIE5vZGUpIHtcbiAgICAgICAgICAgIHRoaXMuZm9jdXMobGFzdCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Tm9kZX0gZWxlbWVudFxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gcHJldmVudFNjcm9sbFxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGFuIGluc3RhbmNlIG9mXG4gICAgICogQHJldHVybiB7TW9uc3Rlci5ET00uRm9jdXNNYW5hZ2VyfVxuICAgICAqL1xuICAgIGZvY3VzKGVsZW1lbnQsIHByZXZlbnRTY3JvbGwpIHtcbiAgICAgICAgdmFsaWRhdGVJbnN0YW5jZShlbGVtZW50LCBOb2RlKTtcblxuICAgICAgICBlbGVtZW50LmZvY3VzKHtcbiAgICAgICAgICAgIHByZXZlbnRTY3JvbGw6IHByZXZlbnRTY3JvbGwgPz8gZmFsc2UsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHJldHVybiB7RWxlbWVudH1cbiAgICAgKi9cbiAgICBnZXRBY3RpdmUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9wdGlvbihLRVlfRE9DVU1FTlQpLmFjdGl2ZUVsZW1lbnQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VsZWN0IGFsbCBlbGVtZW50cyB0aGF0IGNhbiBiZSBmb2N1c2VkXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3x1bmRlZmluZWR9IHF1ZXJ5XG4gICAgICogQHJldHVybiB7YXJyYXl9XG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYW4gaW5zdGFuY2Ugb2ZcbiAgICAgKi9cbiAgICBnZXRGb2N1c2FibGUocXVlcnkpIHtcbiAgICAgICAgbGV0IGNvbnRleHRFbGVtZW50ID0gdGhpcy5nZXRPcHRpb24oS0VZX0NPTlRFWFQpO1xuICAgICAgICBpZiAoY29udGV4dEVsZW1lbnQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgY29udGV4dEVsZW1lbnQgPSB0aGlzLmdldE9wdGlvbihLRVlfRE9DVU1FTlQpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFsaWRhdGVJbnN0YW5jZShjb250ZXh0RWxlbWVudCwgTm9kZSk7XG5cbiAgICAgICAgaWYgKHF1ZXJ5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHZhbGlkYXRlU3RyaW5nKHF1ZXJ5KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICAuLi5jb250ZXh0RWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKFxuICAgICAgICAgICAgICAgICdkZXRhaWxzLCBidXR0b24sIGlucHV0LCBbdGFiaW5kZXhdOm5vdChbdGFiaW5kZXg9XCItMVwiXSksIHNlbGVjdCwgdGV4dGFyZWEsIGFbaHJlZl0sIGJvZHknLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgXS5maWx0ZXIoKGVsZW1lbnQpID0+IHtcbiAgICAgICAgICAgIGlmIChxdWVyeSAhPT0gdW5kZWZpbmVkICYmICFlbGVtZW50Lm1hdGNoZXMocXVlcnkpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoZWxlbWVudC5oYXNBdHRyaWJ1dGUoXCJkaXNhYmxlZFwiKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgaWYgKGVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiYXJpYS1oaWRkZW5cIikgPT09IFwidHJ1ZVwiKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgICAgIGNvbnN0IHJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICAgICAgaWYgKHJlY3Qud2lkdGggPT09IDApIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIGlmIChyZWN0LmhlaWdodCA9PT0gMCkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHF1ZXJ5XG4gICAgICogQHJldHVybiB7TW9uc3Rlci5ET00uRm9jdXNNYW5hZ2VyfVxuICAgICAqL1xuICAgIGZvY3VzTmV4dChxdWVyeSkge1xuICAgICAgICBjb25zdCBjdXJyZW50ID0gdGhpcy5nZXRBY3RpdmUoKTtcbiAgICAgICAgY29uc3QgZm9jdXNhYmxlID0gdGhpcy5nZXRGb2N1c2FibGUocXVlcnkpO1xuXG4gICAgICAgIGlmICghaXNBcnJheShmb2N1c2FibGUpIHx8IGZvY3VzYWJsZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGN1cnJlbnQgaW5zdGFuY2VvZiBOb2RlKSB7XG4gICAgICAgICAgICBsZXQgaW5kZXggPSBmb2N1c2FibGUuaW5kZXhPZihjdXJyZW50KTtcblxuICAgICAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZvY3VzKGZvY3VzYWJsZVtpbmRleCArIDFdIHx8IGZvY3VzYWJsZVswXSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuZm9jdXMoZm9jdXNhYmxlWzBdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZm9jdXMoZm9jdXNhYmxlWzBdKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBxdWVyeVxuICAgICAqIEByZXR1cm4ge01vbnN0ZXIuRE9NLkZvY3VzTWFuYWdlcn1cbiAgICAgKi9cbiAgICBmb2N1c1ByZXYocXVlcnkpIHtcbiAgICAgICAgY29uc3QgY3VycmVudCA9IHRoaXMuZ2V0QWN0aXZlKCk7XG4gICAgICAgIGNvbnN0IGZvY3VzYWJsZSA9IHRoaXMuZ2V0Rm9jdXNhYmxlKHF1ZXJ5KTtcblxuICAgICAgICBpZiAoIWlzQXJyYXkoZm9jdXNhYmxlKSB8fCBmb2N1c2FibGUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjdXJyZW50IGluc3RhbmNlb2YgTm9kZSkge1xuICAgICAgICAgICAgbGV0IGluZGV4ID0gZm9jdXNhYmxlLmluZGV4T2YoY3VycmVudCk7XG5cbiAgICAgICAgICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5mb2N1cyhmb2N1c2FibGVbaW5kZXggLSAxXSB8fCBmb2N1c2FibGVbZm9jdXNhYmxlLmxlbmd0aCAtIDFdKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5mb2N1cyhmb2N1c2FibGVbZm9jdXNhYmxlLmxlbmd0aCAtIDFdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZm9jdXMoZm9jdXNhYmxlW2ZvY3VzYWJsZS5sZW5ndGggLSAxXSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4iLCAiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIjtcbmltcG9ydCB7Rm9jdXNNYW5hZ2VyfSBmcm9tIFwiLi4vLi4vLi4vc291cmNlL2RvbS9mb2N1c21hbmFnZXIubWpzXCI7XG5pbXBvcnQge2NsZWFudXBET01Gcm9tVGVzdGluZywgaW5pdE11dGF0aW9uT2JzZXJ2ZXJGb3JUZXN0aW5nfSBmcm9tIFwiLi4vLi4vdXRpbC9jbGVhbnVwZG9tLm1qc1wiO1xuaW1wb3J0IHtpbml0SlNET019IGZyb20gXCIuLi8uLi91dGlsL2pzZG9tLm1qc1wiO1xuXG5kZXNjcmliZSgnRm9jdXNNYW5hZ2VyJywgZnVuY3Rpb24gKCkge1xuICAgIGJlZm9yZShmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICBpbml0SlNET00oKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgICBpbml0TXV0YXRpb25PYnNlcnZlckZvclRlc3RpbmcoKVxuICAgIH0pXG5cbiAgICBhZnRlckVhY2goKCkgPT4ge1xuICAgICAgICBjbGVhbnVwRE9NRnJvbVRlc3RpbmcoKTtcbiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vY2tzJykuaW5uZXJIVE1MID0gJydcbiAgICB9KVxuXG4gICAgZGVzY3JpYmUoJ25ldycsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBpdCgnc2hvdWxkIGluc3RhbmNlIG9mIEZvY3VzTWFuYWdlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgRm9jdXNNYW5hZ2VyKCkpLmlzLmluc3RhbmNlb2YoRm9jdXNNYW5hZ2VyKTtcbiAgICAgICAgfSlcblxuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnc3RvcmUgYW5kIHJlc3RvcmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCBtYW5hZ2VyO1xuXG4gICAgICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgICAgICAgbWFuYWdlciA9IG5ldyBGb2N1c01hbmFnZXIoKTtcbiAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpLmlubmVySFRNTCA9IGBcbiAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cInRlc3RpdFwiIGlkPVwidHgxXCI+XG4gICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJ0ZXN0aXRcIiBpZD1cInR4MlwiPlxuICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwidGVzdGl0XCIgaWQ9XCJ0eDNcIiBkaXNhYmxlZD5cbiAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cInRlc3RpdFwiIGlkPVwidHg0XCI+XG4gICAgICAgICAgICA8cCBjbGFzcz1cInRlc3RpdFwiIHRhYmluZGV4PVwiMlwiIGlkPVwidHg1XCI+aGVsbG88L3A+XG4gICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJ0ZXN0aXRcIiBpZD1cInR4NlwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPlxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInRlc3RpdFwiIGlkPVwidHg3XCI+PC9idXR0b24+XG4gICAgICAgICAgICBgO1xuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IFssIGVsZW1lbnRdIG9mIE9iamVjdC5lbnRyaWVzKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy50ZXN0aXQnKSkpIHtcbiAgICAgICAgICAgICAgICBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCA9ICgpID0+ICh7XG4gICAgICAgICAgICAgICAgICAgIHdpZHRoOiAyMDAsXG4gICAgICAgICAgICAgICAgICAgIGhlaWdodDogMjAwLFxuICAgICAgICAgICAgICAgICAgICB0b3A6IDAsXG4gICAgICAgICAgICAgICAgICAgIGxlZnQ6IDAsXG4gICAgICAgICAgICAgICAgICAgIHJpZ2h0OiAyMDAsXG4gICAgICAgICAgICAgICAgICAgIGJvdHRvbTogMjAwLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH0pXG5cbiAgICAgICAgaXQoJ3J1biBpc3QnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIG1hbmFnZXIuZm9jdXMoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3R4MScpKTtcbiAgICAgICAgICAgIG1hbmFnZXIuc3RvcmVGb2N1cygpO1xuXG4gICAgICAgICAgICBjb25zdCBlMSA9IG1hbmFnZXIuZ2V0QWN0aXZlKCk7XG4gICAgICAgICAgICBleHBlY3QoZTEuZ2V0QXR0cmlidXRlKCdpZCcpLCAnZXJyb3IxJykudG8uYmUuZXF1YWwoJ3R4MScpO1xuXG4gICAgICAgICAgICBtYW5hZ2VyLmZvY3VzKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0eDInKSk7XG5cbiAgICAgICAgICAgIG1hbmFnZXIuc3RvcmVGb2N1cygpO1xuICAgICAgICAgICAgZXhwZWN0KG1hbmFnZXIuZ2V0QWN0aXZlKCkuZ2V0QXR0cmlidXRlKCdpZCcpLCAnZXJyb3IyJykudG8uYmUuZXF1YWwoJ3R4MicpO1xuICAgICAgICAgICAgbWFuYWdlci5mb2N1c05leHQoKTtcbiAgICAgICAgICAgIGV4cGVjdChtYW5hZ2VyLmdldEFjdGl2ZSgpLmdldEF0dHJpYnV0ZSgnaWQnKSwgJ2Vycm9yMycpLnRvLmJlLmVxdWFsKCd0eDQnKTtcbiAgICAgICAgICAgIG1hbmFnZXIuZm9jdXNOZXh0KCk7XG4gICAgICAgICAgICBleHBlY3QobWFuYWdlci5nZXRBY3RpdmUoKS5nZXRBdHRyaWJ1dGUoJ2lkJyksICdlcnJvcjQnKS50by5iZS5lcXVhbCgndHg1Jyk7XG4gICAgICAgICAgICBtYW5hZ2VyLnJlc3RvcmVGb2N1cygpO1xuICAgICAgICAgICAgZXhwZWN0KG1hbmFnZXIuZ2V0QWN0aXZlKCkuZ2V0QXR0cmlidXRlKCdpZCcpLCAnZXJyb3I1JykudG8uYmUuZXF1YWwoJ3R4MicpO1xuICAgICAgICAgICAgbWFuYWdlci5yZXN0b3JlRm9jdXMoKTtcbiAgICAgICAgICAgIGV4cGVjdChtYW5hZ2VyLmdldEFjdGl2ZSgpLmdldEF0dHJpYnV0ZSgnaWQnKSwgJ2Vycm9yNicpLnRvLmJlLmVxdWFsKCd0eDEnKTtcbiAgICAgICAgICAgIG1hbmFnZXIucmVzdG9yZUZvY3VzKCk7XG4gICAgICAgICAgICBleHBlY3QobWFuYWdlci5nZXRBY3RpdmUoKS5nZXRBdHRyaWJ1dGUoJ2lkJyksICdlcnJvcjcnKS50by5iZS5lcXVhbCgndHgxJyk7XG4gICAgICAgIH0pXG5cblxuICAgIH0pXG5cbiAgICBkZXNjcmliZSgncmV0dXJudHlwZScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBsZXQgZm9jdXNtYW5hZ2VyO1xuXG4gICAgICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgICAgICAgZm9jdXNtYW5hZ2VyID0gbmV3IEZvY3VzTWFuYWdlcigpO1xuICAgICAgICB9KVxuXG4gICAgICAgIGl0KCdjaGVjayByZXR1cm5zJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBleHBlY3QoZm9jdXNtYW5hZ2VyLmdldEZvY3VzYWJsZSgpKS5pcy5pbnN0YW5jZW9mKEFycmF5KTtcbiAgICAgICAgICAgIGV4cGVjdChmb2N1c21hbmFnZXIuZ2V0QWN0aXZlKCkpLmlzLmluc3RhbmNlb2YoSFRNTEVsZW1lbnQpO1xuICAgICAgICAgICAgZXhwZWN0KGZvY3VzbWFuYWdlci5mb2N1c05leHQoKSkuaXMuaW5zdGFuY2VvZihGb2N1c01hbmFnZXIpO1xuICAgICAgICAgICAgZXhwZWN0KGZvY3VzbWFuYWdlci5mb2N1c1ByZXYoKSkuaXMuaW5zdGFuY2VvZihGb2N1c01hbmFnZXIpO1xuICAgICAgICAgICAgZXhwZWN0KGZvY3VzbWFuYWdlci5zdG9yZUZvY3VzKCkpLmlzLmluc3RhbmNlb2YoRm9jdXNNYW5hZ2VyKTtcbiAgICAgICAgICAgIGV4cGVjdChmb2N1c21hbmFnZXIuZm9jdXMoZG9jdW1lbnQuYm9keSkpLmlzLmluc3RhbmNlb2YoRm9jdXNNYW5hZ2VyKTtcbiAgICAgICAgICAgIGV4cGVjdChmb2N1c21hbmFnZXIucmVzdG9yZUZvY3VzKCkpLmlzLmluc3RhbmNlb2YoRm9jdXNNYW5hZ2VyKTtcblxuICAgICAgICB9KVxuXG4gICAgfSlcblxuXG59KTsiLCAiaW1wb3J0IHtcbiAgICBmaW5kRWxlbWVudFdpdGhJZFVwd2FyZHNcbn0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS9kb20vdXRpbC5tanNcIjtcblxuaW1wb3J0IHtleHBlY3R9IGZyb20gJ2NoYWknO1xuaW1wb3J0IHtpbml0SlNET019IGZyb20gXCIuLi8uLi91dGlsL2pzZG9tLm1qc1wiO1xuXG5mdW5jdGlvbiBzZXR1cFRlc3RFbnZpcm9ubWVudCgpIHtcblxuXG4gICAgY2xhc3MgVGVzdENvbXBvbmVudCBleHRlbmRzIEhUTUxFbGVtZW50IHtcbiAgICAgICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgICAgICBzdXBlcigpO1xuICAgICAgICAgICAgdGhpcy5hdHRhY2hTaGFkb3coe21vZGU6ICdvcGVuJ30pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFjdXN0b21FbGVtZW50cy5nZXQoJ3Rlc3QtY29tcG9uZW50JykpIHtcbiAgICAgICAgY3VzdG9tRWxlbWVudHMuZGVmaW5lKCd0ZXN0LWNvbXBvbmVudCcsIFRlc3RDb21wb25lbnQpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gY2xlYW51cFRlc3RFbnZpcm9ubWVudCgpIHtcbiAgICBsZXQgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICBtb2Nrcy5pbm5lckhUTUwgPSBcIlwiO1xufVxuXG5kZXNjcmliZSgnZmluZEVsZW1lbnRXaXRoSWRVcHdhcmRzJywgKCkgPT4ge1xuICAgIGJlZm9yZSgoZG9uZSkgPT4ge1xuICAgICAgICBpbml0SlNET00oKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIHNldHVwVGVzdEVudmlyb25tZW50KCk7XG4gICAgICAgICAgICBkb25lKClcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBhZnRlcigoKSA9PiB7XG4gICAgICAgIGNsZWFudXBUZXN0RW52aXJvbm1lbnQoKTtcbiAgICB9KTtcblxuICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgICAvLyBTZXQgdXAgdGhlIERPTVxuXG4gICAgICAgIGxldCBtb2NrcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpO1xuICAgICAgICBtb2Nrcy5pbm5lckhUTUwgPSBgXG4gICAgICAgICAgICA8ZGl2IGlkPVwiY29udGFpbmVyXCI+XG4gICAgICAgIDxkaXYgaWQ9XCJwYXJlbnRcIj5cbiAgICAgICAgICA8ZGl2IGlkPVwiY2hpbGRcIj48L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5gO1xuXG4gICAgICAgIGNvbnN0IHNoYWRvd0hvc3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChzaGFkb3dIb3N0KTtcbiAgICAgICAgY29uc3Qgc2hhZG93Um9vdCA9IHNoYWRvd0hvc3QuYXR0YWNoU2hhZG93KHttb2RlOiAnb3Blbid9KTtcbiAgICAgICAgY29uc3QgaW5uZXJFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgIGlubmVyRWxlbWVudC5pZCA9ICdpbm5lcic7XG4gICAgICAgIHNoYWRvd1Jvb3QuYXBwZW5kQ2hpbGQoaW5uZXJFbGVtZW50KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmluZCB0aGUgZWxlbWVudCB3aXRoIHRoZSB0YXJnZXQgSUQgaW4gdGhlIG5vcm1hbCBET00nLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGNoaWxkID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NoaWxkJyk7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGZpbmRFbGVtZW50V2l0aElkVXB3YXJkcyhjaGlsZCwgJ3BhcmVudCcpO1xuICAgICAgICBleHBlY3QocmVzdWx0KS50by5lcXVhbChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncGFyZW50JykpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmaW5kIHRoZSBlbGVtZW50IHdpdGggdGhlIHRhcmdldCBJRCBpbiB0aGUgc2hhZG93IERPTScsICgpID0+IHtcbiAgICAgICAgY29uc3QgaW5uZXJFbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZGl2W3NoYWRvd3Jvb3RdID4gZGl2Jyk7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGZpbmRFbGVtZW50V2l0aElkVXB3YXJkcyhpbm5lckVsZW1lbnQsICdpbm5lcicpO1xuICAgICAgICBleHBlY3QocmVzdWx0KS50by5lcXVhbChpbm5lckVsZW1lbnQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gbnVsbCBpZiB0aGUgZWxlbWVudCB3aXRoIHRoZSB0YXJnZXQgSUQgaXMgbm90IGZvdW5kJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBjaGlsZCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjaGlsZCcpO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBmaW5kRWxlbWVudFdpdGhJZFVwd2FyZHMoY2hpbGQsICdub25leGlzdGVudCcpO1xuICAgICAgICBleHBlY3QocmVzdWx0KS50by5iZS5udWxsO1xuICAgIH0pO1xufSk7XG4iLCAiJ3VzZSBzdHJpY3QnO1xuXG5cbmltcG9ydCB7aW5pdEpTRE9NfSBmcm9tIFwiLi4vLi4vdXRpbC9qc2RvbS5tanNcIjtcblxubGV0IHdpbmRvd1JlYWR5O1xubGV0IGRvbVJlYWR5O1xuXG5kZXNjcmliZSgnUmVhZHknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBiZWZvcmUoZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgaW5pdEpTRE9NKCkudGhlbigoKSA9PiB7XG5cbiAgICAgICAgICAgIGltcG9ydChcIi4uLy4uLy4uL3NvdXJjZS9kb20vcmVhZHkubWpzXCIpLnRoZW4oKG0pID0+IHtcbiAgICAgICAgICAgICAgICBkb21SZWFkeSA9IG1bJ2RvbVJlYWR5J107XG4gICAgICAgICAgICAgICAgd2luZG93UmVhZHkgPSBtWyd3aW5kb3dSZWFkeSddO1xuICAgICAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgfSk7XG5cblxuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnZG9tUmVhZHknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ3Jlc29sdmUgcHJvbWlzZScsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICBkb21SZWFkeS50aGVuKGRvbmUpLmNhdGNoKGUgPT4gZG9uZShlKSk7XG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnd2luZG93UmVhZHknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ3Jlc29sdmUgcHJvbWlzZScsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICB3aW5kb3dSZWFkeS50aGVuKGRvbmUpLmNhdGNoKGUgPT4gZG9uZShlKSk7XG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cblxufSk7IiwgImltcG9ydCB7XG4gICAgZ2V0RG9jdW1lbnQsIGdldFdpbmRvdywgZ2V0RG9jdW1lbnRGcmFnbWVudEZyb21TdHJpbmdcbn0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS9kb20vdXRpbC5tanNcIjtcblxuaW1wb3J0IHtnZXRDb250YWluaW5nRG9jdW1lbnR9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvZG9tL3V0aWwubWpzXCI7XG5cbmltcG9ydCB7aW5pdEpTRE9NfSBmcm9tIFwiLi4vLi4vdXRpbC9qc2RvbS5tanNcIjtcblxuaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcblxuXG5kZXNjcmliZSgnRE9NJywgZnVuY3Rpb24gKCkge1xuICAgIGJlZm9yZShhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGluaXRKU0RPTSgpO1xuICAgIH0pXG4gICAgZGVzY3JpYmUoJ2dldERvY3VtZW50KCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGRvY3VtZW50IG9iamVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBkID0gZ2V0RG9jdW1lbnQoKTtcbiAgICAgICAgICAgIGV4cGVjdCh0eXBlb2YgZCkuaXMuZXF1YWwoJ29iamVjdCcpO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdnZXRXaW5kb3coKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gZG9jdW1lbnQgb2JqZWN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGV0IGQgPSBnZXRXaW5kb3coKTtcbiAgICAgICAgICAgIGV4cGVjdCh0eXBlb2YgZCkuaXMuZXF1YWwoJ29iamVjdCcpO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdnZXREb2N1bWVudEZyYWdtZW50RnJvbVN0cmluZygpJywgZnVuY3Rpb24gKCkge1xuXG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWyc8ZGl2PjwvZGl2PiddLFxuICAgICAgICAgICAgWyc8ZGl2PjxkaXY+MjwvZGl2PjwvZGl2PiddLFxuICAgICAgICAgICAgWyc8ZGl2PjxkaXY+MjwvZGl2PicsICc8ZGl2PjxkaXY+MjwvZGl2PjwvZGl2PiddLCAvLyB0ZXN0IGludmFsaWQgaHRtbFxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGlmICghYikgYiA9IGE7XG5cbiAgICAgICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGRvY3VtZW50RnJhZ21lbnQgb2JqZWN0ICcgKyBhLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbGV0IGZyYWdtZW50ID0gZ2V0RG9jdW1lbnRGcmFnbWVudEZyb21TdHJpbmcoYSk7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGZyYWdtZW50KS50by5iZS5pbnN0YW5jZU9mKERvY3VtZW50RnJhZ21lbnQpO1xuXG4gICAgICAgICAgICAgICAgdmFyIGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgICAgIGRpdi5hcHBlbmRDaGlsZChmcmFnbWVudC5jbG9uZU5vZGUodHJ1ZSkpO1xuICAgICAgICAgICAgICAgIGV4cGVjdChkaXYuaW5uZXJIVE1MKS50by5iZS5lcXVhbChiKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cblxuICAgIGRlc2NyaWJlKCdnZXRDb250YWluaW5nRG9jdW1lbnQnLCAoKSA9PiB7XG4gICAgICAgIGxldCAganNEb21Eb2N1bWVudDtcblxuICAgICAgICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICAgICAgICAganNEb21Eb2N1bWVudCA9IGdldERvY3VtZW50KCk7XG4gICAgICAgICB9KTtcbiAgICAgICAgLy9cbiAgICAgICAgLy8gYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgICAgLy8gICAgIGRvbS53aW5kb3cuY2xvc2UoKTtcbiAgICAgICAgLy8gfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBhbiBlcnJvciB3aGVuIGNhbGxlZCB3aXRoIGFuIGludmFsaWQgYXJndW1lbnQnLCAoKSA9PiB7XG4gICAgICAgICAgICBleHBlY3QoKCkgPT4gZ2V0Q29udGFpbmluZ0RvY3VtZW50KG51bGwpKS50by50aHJvdygnSW52YWxpZCBhcmd1bWVudC4gRXhwZWN0ZWQgYW4gSFRNTEVsZW1lbnQuJyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIHRoZSBjb3JyZWN0IGNvbnRhaW5pbmcgZG9jdW1lbnQgZm9yIGFuIGVsZW1lbnQgaW4gdGhlIG1haW4gZG9jdW1lbnQnLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBlbGVtZW50ID0ganNEb21Eb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIGNvbnN0IGNvbnRhaW5pbmdEb2N1bWVudCA9IGdldENvbnRhaW5pbmdEb2N1bWVudChlbGVtZW50KTtcblxuICAgICAgICAgICAgZXhwZWN0KGNvbnRhaW5pbmdEb2N1bWVudCkudG8ubnVsbDtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gdGhlIGNvcnJlY3QgY29udGFpbmluZyBkb2N1bWVudCBmb3IgYW4gZWxlbWVudCBpbnNpZGUgYSBzaGFkb3cgcm9vdCcsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGhvc3QgPSBqc0RvbURvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgY29uc3Qgc2hhZG93Um9vdCA9IGhvc3QuYXR0YWNoU2hhZG93KHsgbW9kZTogJ29wZW4nIH0pO1xuICAgICAgICAgICAgY29uc3QgZWxlbWVudCA9IGpzRG9tRG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuICAgICAgICAgICAgc2hhZG93Um9vdC5hcHBlbmRDaGlsZChlbGVtZW50KTtcblxuICAgICAgICAgICAgY29uc3QgY29udGFpbmluZ0RvY3VtZW50ID0gZ2V0Q29udGFpbmluZ0RvY3VtZW50KGVsZW1lbnQpO1xuICAgICAgICAgICAgZXhwZWN0KGNvbnRhaW5pbmdEb2N1bWVudCkudG8ubm90Lm51bGw7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIHRoZSBjb3JyZWN0IGNvbnRhaW5pbmcgZG9jdW1lbnQgZm9yIGFuIGVsZW1lbnQgaW5zaWRlIGEgbmVzdGVkIHNoYWRvdyByb290JywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgb3V0ZXJIb3N0ID0ganNEb21Eb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIGNvbnN0IG91dGVyU2hhZG93Um9vdCA9IG91dGVySG9zdC5hdHRhY2hTaGFkb3coeyBtb2RlOiAnb3BlbicgfSk7XG5cbiAgICAgICAgICAgIGNvbnN0IGlubmVySG9zdCA9IGpzRG9tRG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBvdXRlclNoYWRvd1Jvb3QuYXBwZW5kQ2hpbGQoaW5uZXJIb3N0KTtcblxuICAgICAgICAgICAgY29uc3QgaW5uZXJTaGFkb3dSb290ID0gaW5uZXJIb3N0LmF0dGFjaFNoYWRvdyh7IG1vZGU6ICdvcGVuJyB9KTtcblxuICAgICAgICAgICAgY29uc3QgZWxlbWVudCA9IGpzRG9tRG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuICAgICAgICAgICAgaW5uZXJTaGFkb3dSb290LmFwcGVuZENoaWxkKGVsZW1lbnQpO1xuXG4gICAgICAgICAgICBjb25zdCBjb250YWluaW5nRG9jdW1lbnQgPSBnZXRDb250YWluaW5nRG9jdW1lbnQoZWxlbWVudCk7XG4gICAgICAgICAgICBleHBlY3QoY29udGFpbmluZ0RvY3VtZW50KS50by5ub3QubnVsbDtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gbnVsbCB3aGVuIHRoZSBlbGVtZW50IGlzIG5vdCBhdHRhY2hlZCB0byBhbnkgZG9jdW1lbnQnLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBkZXRhY2hlZEVsZW1lbnQgPSBqc0RvbURvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgZGV0YWNoZWRFbGVtZW50LnJlbW92ZSgpO1xuXG4gICAgICAgICAgICBjb25zdCBjb250YWluaW5nRG9jdW1lbnQgPSBnZXRDb250YWluaW5nRG9jdW1lbnQoZGV0YWNoZWRFbGVtZW50KTtcbiAgICAgICAgICAgIGV4cGVjdChjb250YWluaW5nRG9jdW1lbnQpLnRvLmJlLm51bGw7XG4gICAgICAgIH0pO1xuICAgIH0pOyAgICBcbiAgICBcbn0pOyIsICIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBjaGFpIGZyb20gXCJjaGFpXCJcbi8vIGltcG9ydCB7aW50ZXJuYWxTeW1ib2x9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvY29uc3RhbnRzLm1qc1wiO1xuLy8gaW1wb3J0IHtBVFRSSUJVVEVfT1BUSU9OU30gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS9kb20vY29uc3RhbnRzLm1qc1wiO1xuaW1wb3J0IHtnZXREb2N1bWVudH0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS9kb20vdXRpbC5tanNcIjtcbi8vIGltcG9ydCB7UHJveHlPYnNlcnZlcn0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS90eXBlcy9wcm94eW9ic2VydmVyLm1qc1wiO1xuLy8gaW1wb3J0IHthZGRPYmplY3RXaXRoVXBkYXRlclRvRWxlbWVudH0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS9kb20vdXBkYXRlci5tanNcIjtcbmltcG9ydCB7Y2hhaURvbX0gZnJvbSBcIi4uLy4uL3V0aWwvY2hhaS1kb20ubWpzXCI7XG5pbXBvcnQge2luaXRKU0RPTX0gZnJvbSBcIi4uLy4uL3V0aWwvanNkb20ubWpzXCI7XG5cblxubGV0IGV4cGVjdCA9IGNoYWkuZXhwZWN0O1xuY2hhaS51c2UoY2hhaURvbSk7XG5cbi8vIGxldCBodG1sMSA9IGBcbi8vICAgICA8ZGl2IGlkPVwic2NyaXB0aG9zdFwiPlxuLy8gICAgIDwvZGl2PlxuLy8gICAgXG4vLyAgICAgPGRpdj5cbi8vICAgICA8XG4vLyA8L2Rpdj5cbi8vIGA7XG5cblxuLy8gZGVmaW5lZCBpbiBjb25zdGFudHMubWpzXG4vLyBjb25zdCB1cGRhdGVyU3ltYm9sS2V5ID0gXCJAc2NodWthaS9tb25zdGVyL2RvbS9jdXN0b20tZWxlbWVudEBAb3B0aW9ucy11cGRhdGVyLWxpbmtcIlxuLy8gY29uc3QgdXBkYXRlclN5bWJvbFN5bWJvbCA9IFN5bWJvbC5mb3IodXBkYXRlclN5bWJvbEtleSk7XG5cblxuXG5kZXNjcmliZSgnRE9NJywgZnVuY3Rpb24gKCkge1xuXG4gICAgbGV0IEN1c3RvbUVsZW1lbnQsIHJlZ2lzdGVyQ3VzdG9tRWxlbWVudCwgVGVzdENvbXBvbmVudCwgZG9jdW1lbnQsIFRlc3RDb21wb25lbnQyLGFzc2lnblVwZGF0ZXJUb0VsZW1lbnQ7XG5cbiAgICBkZXNjcmliZSgnaW5pdEZyb21TY3JpcHRIb3N0KCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgY29uc3QgcmFuZG9tVGFnTnVtYmVyID0gXCJtb25zdGVyLXRlc3RcIitNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAxMDAwMDAwKTtcbiAgICAgICAgXG4gICAgICAgIGJlZm9yZShmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICAgICAgaW5pdEpTRE9NKCkudGhlbigoKSA9PiB7XG5cbiAgICAgICAgICAgICAgICBpbXBvcnQoXCIuLi8uLi8uLi9zb3VyY2UvZG9tL2N1c3RvbWVsZW1lbnQubWpzXCIpLnRoZW4oKG0pID0+IHtcblxuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgQ3VzdG9tRWxlbWVudCA9IG1bJ0N1c3RvbUVsZW1lbnQnXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2lzdGVyQ3VzdG9tRWxlbWVudCA9IG1bJ3JlZ2lzdGVyQ3VzdG9tRWxlbWVudCddO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBUZXN0Q29tcG9uZW50MiA9IGNsYXNzIGV4dGVuZHMgQ3VzdG9tRWxlbWVudCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGljIGdldFRhZygpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJhbmRvbVRhZ051bWJlcjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIEByZXR1cm4ge09iamVjdH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXQgZGVmYXVsdHMoKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN1cGVyLmRlZmF1bHRzLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXN0OiAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcGxhdGVzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFpbjogJzxoMT48L2gxPjxhcnRpY2xlPjxwPnRlc3Q8L3A+PGRpdiBpZD1cImNvbnRhaW5lclwiPjwvZGl2PjwvYXJ0aWNsZT4nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICByZWdpc3RlckN1c3RvbUVsZW1lbnQoVGVzdENvbXBvbmVudDIpXG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50ID0gZ2V0RG9jdW1lbnQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkb25lKGUpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cblxuICAgICAgICAgICAgICAgIH0pLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGRvbmUoZSk7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuXG4gICAgICAgIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICAgICAgICBsZXQgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgICAgIG1vY2tzLmlubmVySFRNTCA9IFwiXCI7XG4gICAgICAgIH0pXG5cbiAgICAgICAgZGVzY3JpYmUoJ2NhbGwgY2FsbGJhY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpdCgnc2hvdWxkIG5vdCBmb3VuZCBjYWxsYmFjayBhbmQgYWRkIGVycm9yIGF0dHJpYnV0ZScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgIGxldCBtb2NrcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpO1xuICAgICAgICAgICAgICAgIG1vY2tzLmlubmVySFRNTCA9IGA8ZGl2IGlkPVwiY2FsbC1iYWNrLWhvc3RcIj48L2Rpdj48ZGl2IGlkPVwiY29udGFpbmVyXCI+PC9kaXY+YDtcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICBsZXQgY29udHJvbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQocmFuZG9tVGFnTnVtYmVyKTtcbiAgICAgICAgICAgICAgICBjb250cm9sLnNldEF0dHJpYnV0ZSgnZGF0YS1tb25zdGVyLXNjcmlwdC1ob3N0JywgXCJjYWxsLWJhY2staG9zdFwiKTtcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY29udGFpbmVyJykuYXBwZW5kQ2hpbGQoY29udHJvbCk7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGNvbnRyb2wuZ2V0T3B0aW9uKCd0ZXN0JykpLmlzLmVxbCgwKTtcbiAgICAgICAgICAgICAgICBleHBlY3QoY29udHJvbC5oYXNBdHRyaWJ1dGUoJ2RhdGEtbW9uc3Rlci1lcnJvcicpKS5pcy50cnVlO1xuXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgaXQoJ3Nob3VsZCBmb3VuZCBjYWxsYmFjayBpbml0Q3VzdG9tQ29udHJvbENhbGxiYWNrJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICAgICAgbGV0IG1vY2tzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vY2tzJyk7XG4gICAgICAgICAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gYDxkaXYgaWQ9XCJjYWxsLWJhY2staG9zdFwiPjwvZGl2PjxkaXYgaWQ9XCJjb250YWluZXJcIj48L2Rpdj5gO1xuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjYWxsLWJhY2staG9zdCcpO1xuICAgICAgICAgICAgICAgIGNvbnRhaW5lci5pbml0Q3VzdG9tQ29udHJvbENhbGxiYWNrID0gZnVuY3Rpb24gKGNvbnRyb2wpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udHJvbC5zZXRPcHRpb24oJ3Rlc3QnLCAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgbGV0IGNvbnRyb2wgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHJhbmRvbVRhZ051bWJlcik7XG4gICAgICAgICAgICAgICAgY29udHJvbC5zZXRBdHRyaWJ1dGUoJ2RhdGEtbW9uc3Rlci1zY3JpcHQtaG9zdCcsIFwiY2FsbC1iYWNrLWhvc3RcIik7XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NvbnRhaW5lcicpLmFwcGVuZENoaWxkKGNvbnRyb2wpO1xuICAgICAgICAgICAgICAgIGV4cGVjdChjb250cm9sLmdldE9wdGlvbigndGVzdCcpKS5pcy5lcWwoMSk7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGNvbnRyb2wuaGFzQXR0cmlidXRlKCdkYXRhLW1vbnN0ZXItZXJyb3InKSkuaXMuZmFsc2U7XG5cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgXG4gICAgICAgICAgICBpdCgnc2hvdWxkIGZvdW5kIGNhbGxiYWNrIGluaXRDdXN0b21Db250cm9sQ2FsbGJhY2sgZnJvbSBzZWxmJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICAgICAgbGV0IG1vY2tzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vY2tzJyk7XG4gICAgICAgICAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gYDxkaXYgaWQ9XCJjYWxsLWJhY2staG9zdFwiPjwvZGl2PjxkaXYgaWQ9XCJjb250YWluZXJcIj48L2Rpdj5gO1xuXG4gICAgICAgICAgICAgICAgbGV0IGNvbnRyb2wgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHJhbmRvbVRhZ051bWJlcik7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGNvbnRyb2wuZ2V0T3B0aW9uKCd0ZXN0JykpLmlzLmVxbCgwKTtcbiAgICAgICAgICAgICAgICBjb250cm9sLmluaXRDdXN0b21Db250cm9sQ2FsbGJhY2sgPSBmdW5jdGlvbiAoY29udHJvbCkge1xuICAgICAgICAgICAgICAgICAgICBjb250cm9sLnNldE9wdGlvbigndGVzdCcsIDIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICBjb250cm9sLnNldEF0dHJpYnV0ZSgnZGF0YS1tb25zdGVyLXNjcmlwdC1ob3N0JywgXCJjYWxsLWJhY2staG9zdFwiKTtcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY29udGFpbmVyJykuYXBwZW5kQ2hpbGQoY29udHJvbCk7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGNvbnRyb2wuZ2V0T3B0aW9uKCd0ZXN0JykpLmlzLmVxbCgyKTtcbiAgICAgICAgICAgICAgICBleHBlY3QoY29udHJvbC5oYXNBdHRyaWJ1dGUoJ2RhdGEtbW9uc3Rlci1lcnJvcicpKS5pcy5mYWxzZTtcblxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pXG5cbiAgICB9KTtcbn0pIiwgImltcG9ydCB7ZXhwZWN0fSBmcm9tICdjaGFpJztcbmltcG9ydCB7Z2V0U2xvdHRlZE5vZGVzfSBmcm9tIFwiLi4vLi4vLi4vc291cmNlL2RvbS9zbG90dGVkLm1qc1wiO1xuXG5cbmRlc2NyaWJlKCdnZXRTbG90dGVkTm9kZXMnLCAoKSA9PiB7XG5cblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGFuIGVtcHR5IFNldCBpZiB0aGVyZSBpcyBubyBTaGFkb3dSb290JywgKCkgPT4ge1xuICAgICAgICBleHBlY3QoZ2V0U2xvdHRlZE5vZGVzKS5pcy5hKCdmdW5jdGlvbicpO1xuICAgIH0pO1xuXG5cbn0pO1xuXG4iLCAiXG5pbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuXG5pbXBvcnQge1xuICAgIGFkZEF0dHJpYnV0ZVRva2VuLFxuICAgIGFkZFRvT2JqZWN0TGluayxcbiAgICBjbGVhckF0dHJpYnV0ZVRva2VucyxcbiAgICBjb250YWluc0F0dHJpYnV0ZVRva2VuLFxuICAgIGZpbmRDbG9zZXN0QnlBdHRyaWJ1dGUsXG4gICAgZmluZENsb3Nlc3RPYmplY3RMaW5rLFxuICAgIGdldExpbmtlZE9iamVjdHMsXG4gICAgaGFzT2JqZWN0TGluayxcbiAgICByZW1vdmVBdHRyaWJ1dGVUb2tlbixcbiAgICByZW1vdmVPYmplY3RMaW5rLFxuICAgIHJlcGxhY2VBdHRyaWJ1dGVUb2tlbixcbiAgICB0b2dnbGVBdHRyaWJ1dGVUb2tlbixcbiAgICBmaW5kQ2xvc2VzdEJ5Q2xhc3Ncbn0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS9kb20vYXR0cmlidXRlcy5tanNcIjtcblxuaW1wb3J0IHtpbml0SlNET019IGZyb20gXCIuLi8uLi91dGlsL2pzZG9tLm1qc1wiO1xuXG5sZXQgaHRtbDEsIGh0bWwyLCBodG1sMztcblxuZGVzY3JpYmUoJ0F0dHJpYnV0ZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgYmVmb3JlKGZ1bmN0aW9uIChkb25lKSB7XG5cbiAgICAgICAgaHRtbDEgPSBgPGRpdiBpZD1cInRlc3QxXCI+PC9kaXY+YDtcbiAgICAgICAgaHRtbDIgPSBgPGRpdiBpZD1cInRlc3QxXCI+XG4gICAgPGRpdiBpZD1cInN1YjFcIj5cbiAgICAgICAgPGRpdiBpZD1cInN1YjJcIj5cbiAgICAgICAgICAgIDxkaXYgaWQ9XCJzdWIzXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBpZD1cInN1YjRcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD1cInN1YjVcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbjwvZGl2PlxuYDtcbiAgICAgICAgXG4gICAgICAgIGh0bWwzID0gYDxkaXYgZGF0YS1tb25zdGVyLXJvbGU9XCJ0ZXN0MVwiPlxuICAgIDxkaXYgZGF0YS1tb25zdGVyLXJvbGU9XCJzdWIxXCIgaWQ9XCJhMVwiIGNsYXNzPVwic3ViMVwiPlxuICAgICAgICA8ZGl2IGRhdGEtbW9uc3Rlci1yb2xlPVwic3ViMlwiIGlkPVwiYTJcIiBjbGFzcz1cInN1YjJcIj5cbiAgICAgICAgICAgIDxkaXYgZGF0YS1tb25zdGVyLXJvbGU9XCJzdWIzXCIgaWQ9XCJhM1wiIGNsYXNzPVwic3ViM1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgZGF0YS1tb25zdGVyLXJvbGU9XCJzdWI0XCIgaWQ9XCJhNFwiIGNsYXNzPVwic3ViNFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGRhdGEtbW9uc3Rlci1yb2xlPVwic3ViNVwiIGlkPVwiYTVcIiBjbGFzcz1cInN1YjVcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbjwvZGl2PlxuYDtcblxuXG4gICAgICAgIGluaXRKU0RPTSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgZG9uZSgpXG4gICAgICAgIH0pLmNhdGNoKGUgPT4gZG9uZShlKSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnT2JqZWN0TGluaycsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBjb25zdCBzeW1ib2wgPSBTeW1ib2woJ215dGVzdCcpO1xuXG4gICAgICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgICAgICAgbGV0IG1vY2tzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vY2tzJyk7XG4gICAgICAgICAgICBtb2Nrcy5pbm5lckhUTUwgPSBodG1sMTtcbiAgICAgICAgfSlcblxuICAgICAgICBhZnRlckVhY2goKCkgPT4ge1xuICAgICAgICAgICAgbGV0IG1vY2tzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vY2tzJyk7XG4gICAgICAgICAgICBtb2Nrcy5pbm5lckhUTUwgPSBcIlwiO1xuICAgICAgICB9KVxuXG4gICAgICAgIGl0KCdzaG91bGQgaGFuZGxlIG9iamVjdC1saW5rcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBvYmogPSB7YTogMX07XG4gICAgICAgICAgICBsZXQgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0ZXN0MScpO1xuICAgICAgICAgICAgZXhwZWN0KGhhc09iamVjdExpbmsoZWxlbWVudCwgc3ltYm9sKSkudG8uYmUuZmFsc2U7XG4gICAgICAgICAgICBhZGRUb09iamVjdExpbmsoZWxlbWVudCwgc3ltYm9sLCBvYmopO1xuICAgICAgICAgICAgZXhwZWN0KGhhc09iamVjdExpbmsoZWxlbWVudCwgc3ltYm9sKSkudG8uYmUudHJ1ZTtcblxuICAgICAgICAgICAgbGV0IG8gPSBnZXRMaW5rZWRPYmplY3RzKGVsZW1lbnQsIHN5bWJvbCkubmV4dCgpO1xuICAgICAgICAgICAgZXhwZWN0KG8udmFsdWUpLnRvLmVxdWFsKG9iaik7XG5cbiAgICAgICAgICAgIHJlbW92ZU9iamVjdExpbmsoZWxlbWVudCwgc3ltYm9sKTtcbiAgICAgICAgICAgIGV4cGVjdChoYXNPYmplY3RMaW5rKGVsZW1lbnQsIHN5bWJvbCkpLnRvLmJlLmZhbHNlO1xuICAgICAgICAgICAgZXhwZWN0KCgpID0+IGdldExpbmtlZE9iamVjdHMoZWxlbWVudCwgc3ltYm9sKSkudG8udGhyb3coRXJyb3IpO1xuICAgICAgICB9KVxuXG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdmaW5kQ2xvc2VzdE9iamVjdExpbmsoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBjb25zdCBzeW1ib2wgPSBTeW1ib2woJ215dGVzdCcpO1xuXG4gICAgICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgICAgICAgbGV0IG1vY2tzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vY2tzJyk7XG4gICAgICAgICAgICBtb2Nrcy5pbm5lckhUTUwgPSBodG1sMjtcbiAgICAgICAgfSlcblxuICAgICAgICBhZnRlckVhY2goKCkgPT4ge1xuICAgICAgICAgICAgbGV0IG1vY2tzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vY2tzJyk7XG4gICAgICAgICAgICBtb2Nrcy5pbm5lckhUTUwgPSBcIlwiO1xuICAgICAgICB9KVxuXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIG9iamVjdGxpbmsnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIGxldCBzdWI0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3N1YjQnKVxuICAgICAgICAgICAgbGV0IHN1YjIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc3ViMicpXG5cbiAgICAgICAgICAgIGxldCBvYmogPSB7fTtcblxuICAgICAgICAgICAgZXhwZWN0KGhhc09iamVjdExpbmsoc3ViMiwgc3ltYm9sKSkudG8uYmUuZmFsc2U7XG4gICAgICAgICAgICBhZGRUb09iamVjdExpbmsoc3ViMiwgc3ltYm9sLCBvYmopO1xuICAgICAgICAgICAgZXhwZWN0KGhhc09iamVjdExpbmsoc3ViMiwgc3ltYm9sKSkudG8uYmUudHJ1ZTtcblxuICAgICAgICAgICAgbGV0IGVsZW1lbnQgPSBmaW5kQ2xvc2VzdE9iamVjdExpbmsoc3ViNCk7XG4gICAgICAgICAgICBleHBlY3QoZWxlbWVudCkuaXMuaW5zdGFuY2VPZihIVE1MRGl2RWxlbWVudCk7XG4gICAgICAgICAgICBleHBlY3QoZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2lkJykpLnRvLmJlLmVxdWFsKCdzdWIyJyk7XG5cbiAgICAgICAgfSk7XG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdBdHRyaWJ1dGVzJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAgICAgIGxldCBtb2NrcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpO1xuICAgICAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gaHRtbDM7XG4gICAgICAgIH0pXG5cbiAgICAgICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgICAgICAgIGxldCBtb2NrcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpO1xuICAgICAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gXCJcIjtcbiAgICAgICAgfSlcblxuICAgICAgICBkZXNjcmliZSgnZmluZCBjbG9zZXN0IEF0dHJpYnV0ZXMnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICBbJ2E1JywgJ2RhdGEtbW9uc3Rlci1yb2xlJywgdW5kZWZpbmVkLCAnc3ViNSddLFxuICAgICAgICAgICAgICAgIFsnYTUnLCAnZGF0YS1tb25zdGVyLXJvbGUnLCAnc3ViMycsICdzdWIzJ10sXG4gICAgICAgICAgICAgICAgWydhNScsICdkYXRhLW1vbnN0ZXItcm9sZScsICdzdWIxJywgJ3N1YjEnXSxcbiAgICAgICAgICAgICAgICBbJ2E0JywgJ2RhdGEtbW9uc3Rlci1yb2xlJywgJ3N1YjEnLCAnc3ViMSddLFxuICAgICAgICAgICAgICAgIFsnYTMnLCAnZGF0YS1tb25zdGVyLXJvbGUnLCAnc3ViMScsICdzdWIxJ10sXG4gICAgICAgICAgICAgICAgWydhMicsICdkYXRhLW1vbnN0ZXItcm9sZScsIHVuZGVmaW5lZCwgJ3N1YjInXSxcbiAgICAgICAgICAgICAgICBbJ2E1JywgJ2RhdGEtbW9uc3Rlci1yb2xlJywgJ3N1YjUnLCAnc3ViNSddXG4gICAgICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgICAgICBsZXQgYyA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgICAgIGxldCBkID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgICAgICBpdCgnZmluZENsb3Nlc3RCeUF0dHJpYnV0ZSgnICsgYSArICcsICcgKyBiICsgJywnICsgYyArICcpIHNob3VsZCByZXR1cm4gJyArIGQsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KGZpbmRDbG9zZXN0QnlBdHRyaWJ1dGUoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYSksIGIsIGMpLmdldEF0dHJpYnV0ZSgnZGF0YS1tb25zdGVyLXJvbGUnKSkudG8uYmUuZXF1YWwoZCk7XG4gICAgICAgICAgICAgICAgfSlcblxuXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7IFxuICAgICAgICBcbiAgICAgICAgZGVzY3JpYmUoJ2ZpbmQgY2xvc2VzdCBFbGVtZW50IHdpdGggY2xhc3MnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICBbJ2E1JywgICdzdWIzJywgJ3N1YjMnXSxcbiAgICAgICAgICAgICAgICBbJ2E1JywgICdzdWIxJywgJ3N1YjEnXSxcbiAgICAgICAgICAgICAgICBbJ2E0JywgICdzdWIxJywgJ3N1YjEnXSxcbiAgICAgICAgICAgICAgICBbJ2EzJywgICdzdWIxJywgJ3N1YjEnXSxcbiAgICAgICAgICAgICAgICBbJ2E1JywgICdzdWI1JywgJ3N1YjUnXVxuICAgICAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICAgICAgbGV0IGMgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgICAgICBpdCgnZmluZENsb3Nlc3RCeUNsYXNzKCcgKyBhICsgJywgJyArIGIgKyAnKSBzaG91bGQgcmV0dXJuICcgKyBjLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChmaW5kQ2xvc2VzdEJ5Q2xhc3MoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYSksIGIpLmdldEF0dHJpYnV0ZSgnY2xhc3MnKSkudG8uYmUuZXF1YWwoYyk7XG4gICAgICAgICAgICAgICAgfSlcblxuXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnQXR0cmlidXRlcycsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAgICAgIGxldCBtb2NrcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpO1xuICAgICAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gaHRtbDE7XG4gICAgICAgIH0pXG5cbiAgICAgICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgICAgICAgIGxldCBtb2NrcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpO1xuICAgICAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gXCJcIjtcbiAgICAgICAgfSlcblxuICAgICAgICBjb25zdCBhdHJpYnV0ZUtleSA9ICdkYXRhLXRlc3QnO1xuXG4gICAgICAgIGl0KCd0b2dnbGVBdHRyaWJ1dGVUb2tlbihlbGVtZW50LCBrZXksIHZhbHVlKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBlbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Rlc3QxJyk7XG4gICAgICAgICAgICBleHBlY3QoZWxlbWVudC5oYXNBdHRyaWJ1dGUoYXRyaWJ1dGVLZXkpKS50by5iZS5mYWxzZTtcbiAgICAgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKGF0cmlidXRlS2V5LCAnYXBwbGUgYmFuYW5uYScpXG4gICAgICAgICAgICB0b2dnbGVBdHRyaWJ1dGVUb2tlbihlbGVtZW50LCBhdHJpYnV0ZUtleSwgJ3BpbmFwcGxlJyk7XG4gICAgICAgICAgICBleHBlY3QoZWxlbWVudC5nZXRBdHRyaWJ1dGUoYXRyaWJ1dGVLZXkpKS50by5iZS5lcXVhbCgnYXBwbGUgYmFuYW5uYSBwaW5hcHBsZScpO1xuICAgICAgICAgICAgdG9nZ2xlQXR0cmlidXRlVG9rZW4oZWxlbWVudCwgYXRyaWJ1dGVLZXksICdwaW5hcHBsZScpO1xuICAgICAgICAgICAgZXhwZWN0KGVsZW1lbnQuZ2V0QXR0cmlidXRlKGF0cmlidXRlS2V5KSkudG8uYmUuZXF1YWwoJ2FwcGxlIGJhbmFubmEnKTtcbiAgICAgICAgfSlcblxuICAgICAgICBpdCgnYWRkQXR0cmlidXRlVG9rZW4oZWxlbWVudCwga2V5LCB2YWx1ZSknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0ZXN0MScpO1xuICAgICAgICAgICAgZXhwZWN0KGVsZW1lbnQuaGFzQXR0cmlidXRlKGF0cmlidXRlS2V5KSkudG8uYmUuZmFsc2U7XG4gICAgICAgICAgICBhZGRBdHRyaWJ1dGVUb2tlbihlbGVtZW50LCBhdHJpYnV0ZUtleSwgJ3BpbmFwcGxlJyk7XG4gICAgICAgICAgICBleHBlY3QoZWxlbWVudC5nZXRBdHRyaWJ1dGUoYXRyaWJ1dGVLZXkpKS50by5iZS5lcXVhbCgncGluYXBwbGUnKTtcbiAgICAgICAgICAgIGFkZEF0dHJpYnV0ZVRva2VuKGVsZW1lbnQsIGF0cmlidXRlS2V5LCAnYmFuYW5uYScpO1xuICAgICAgICAgICAgZXhwZWN0KGVsZW1lbnQuZ2V0QXR0cmlidXRlKGF0cmlidXRlS2V5KSkudG8uYmUuZXF1YWwoJ3BpbmFwcGxlIGJhbmFubmEnKTtcbiAgICAgICAgfSlcblxuICAgICAgICBpdCgncmVtb3ZlQXR0cmlidXRlVG9rZW4oZWxlbWVudCwga2V5LCB2YWx1ZSknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0ZXN0MScpO1xuICAgICAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoYXRyaWJ1dGVLZXksICdhcHBsZSBiYW5hbm5hIGxlbW1vbicpXG4gICAgICAgICAgICByZW1vdmVBdHRyaWJ1dGVUb2tlbihlbGVtZW50LCBhdHJpYnV0ZUtleSwgJ3BpbmFwcGxlJyk7XG4gICAgICAgICAgICBleHBlY3QoZWxlbWVudC5nZXRBdHRyaWJ1dGUoYXRyaWJ1dGVLZXkpKS50by5iZS5lcXVhbCgnYXBwbGUgYmFuYW5uYSBsZW1tb24nKTtcbiAgICAgICAgICAgIHJlbW92ZUF0dHJpYnV0ZVRva2VuKGVsZW1lbnQsIGF0cmlidXRlS2V5LCAnYmFuYW5uYScpO1xuICAgICAgICAgICAgZXhwZWN0KGVsZW1lbnQuZ2V0QXR0cmlidXRlKGF0cmlidXRlS2V5KSkudG8uYmUuZXF1YWwoJ2FwcGxlIGxlbW1vbicpO1xuXG4gICAgICAgIH0pXG5cbiAgICAgICAgaXQoJ2NvbnRhaW5zQXR0cmlidXRlVG9rZW4oZWxlbWVudCwga2V5LCB2YWx1ZSknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0ZXN0MScpO1xuICAgICAgICAgICAgZXhwZWN0KGNvbnRhaW5zQXR0cmlidXRlVG9rZW4oZWxlbWVudCwgYXRyaWJ1dGVLZXksICdwaW5hcHBsZScpKS50by5iZS5mYWxzZTtcbiAgICAgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKGF0cmlidXRlS2V5LCAnYXBwbGUgYmFuYW5uYScpXG4gICAgICAgICAgICBleHBlY3QoY29udGFpbnNBdHRyaWJ1dGVUb2tlbihlbGVtZW50LCBhdHJpYnV0ZUtleSwgJ3BpbmFwcGxlJykpLnRvLmJlLmZhbHNlO1xuICAgICAgICAgICAgZXhwZWN0KGNvbnRhaW5zQXR0cmlidXRlVG9rZW4oZWxlbWVudCwgYXRyaWJ1dGVLZXksICdiYW5hbm5hJykpLnRvLmJlLnRydWU7XG4gICAgICAgICAgICBleHBlY3QoY29udGFpbnNBdHRyaWJ1dGVUb2tlbihlbGVtZW50LCBhdHJpYnV0ZUtleSwgJ2FwcGxlJykpLnRvLmJlLnRydWU7XG5cbiAgICAgICAgfSlcblxuICAgICAgICBpdCgnIHJlcGxhY2VBdHRyaWJ1dGVUb2tlbihlbGVtZW50LCBrZXksIHZhbHVlKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBlbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Rlc3QxJyk7XG4gICAgICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShhdHJpYnV0ZUtleSwgJ2FwcGxlIGJhbmFubmEgdG9tYXRvJylcbiAgICAgICAgICAgIHJlcGxhY2VBdHRyaWJ1dGVUb2tlbihlbGVtZW50LCBhdHJpYnV0ZUtleSwgJ3RvbWF0bycsICdsZW1tb24nKTtcbiAgICAgICAgICAgIGV4cGVjdChlbGVtZW50LmdldEF0dHJpYnV0ZShhdHJpYnV0ZUtleSkpLnRvLmJlLmVxdWFsKCdhcHBsZSBiYW5hbm5hIGxlbW1vbicpO1xuICAgICAgICAgICAgcmVwbGFjZUF0dHJpYnV0ZVRva2VuKGVsZW1lbnQsIGF0cmlidXRlS2V5LCAnYmFuYW5uYScsICdwZWFyJyk7XG4gICAgICAgICAgICBleHBlY3QoZWxlbWVudC5nZXRBdHRyaWJ1dGUoYXRyaWJ1dGVLZXkpKS50by5iZS5lcXVhbCgnYXBwbGUgcGVhciBsZW1tb24nKTtcbiAgICAgICAgfSlcblxuICAgICAgICBpdCgnY2xlYXJBdHRyaWJ1dGVUb2tlbnMoZWxlbWVudCwga2V5KScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBlbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Rlc3QxJyk7XG4gICAgICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShhdHJpYnV0ZUtleSwgJ2FwcGxlIGJhbmFubmEnKVxuICAgICAgICAgICAgY2xlYXJBdHRyaWJ1dGVUb2tlbnMoZWxlbWVudCwgYXRyaWJ1dGVLZXkpO1xuICAgICAgICAgICAgZXhwZWN0KGVsZW1lbnQuZ2V0QXR0cmlidXRlKGF0cmlidXRlS2V5KSkudG8uYmUuZXF1YWwoJycpO1xuXG4gICAgICAgIH0pXG5cblxuICAgIH0pXG59KSIsICIndXNlIHN0cmljdCc7XG5cblxuaW1wb3J0IHtpbml0SlNET019IGZyb20gXCIuLi8uLi91dGlsL2pzZG9tLm1qc1wiO1xuaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmxldCBSZXNvdXJjZSxEZXJpdmVkUmVzb3VyY2U7XG5cblxuXG5kZXNjcmliZSgnUmVzb3VyY2UnLCBmdW5jdGlvbigpIHtcblxuICAgIGJlZm9yZShmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICBpbml0SlNET00oKS50aGVuKCgpID0+IHtcblxuICAgICAgICAgICAgaW1wb3J0KFwiLi4vLi4vLi4vc291cmNlL2RvbS9yZXNvdXJjZS5tanNcIikudGhlbigobSkgPT4ge1xuICAgICAgICAgICAgICAgIFJlc291cmNlID0gbVsnUmVzb3VyY2UnXTtcblxuXG4gICAgICAgICAgICAgICAgRGVyaXZlZFJlc291cmNlID0gY2xhc3MgIGV4dGVuZHMgUmVzb3VyY2Uge1xuICAgICAgICAgICAgICAgICAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN1cGVyKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImRhdGEtdXJsXCI6IFwiaHR0cDovL2V4YW1wbGUuY29tXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHN0YXRpYyBnZXRVUkxBdHRyaWJ1dGUoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJ2RhdGEtdXJsJztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgZG9uZSgpXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICB9KTtcblxuXG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCdEZXJpdmVkUmVzb3VyY2UnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBpbnN0YW5jZW9mIFJlc291cmNlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KG5ldyBEZXJpdmVkUmVzb3VyY2UoKSkudG8uYmUuYW4uaW5zdGFuY2VvZihSZXNvdXJjZSk7XG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cblxufSk7IiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgZXh0ZW5kIH0gZnJvbSBcIi4uL2RhdGEvZXh0ZW5kLm1qc1wiO1xuaW1wb3J0IHsgQmFzZSB9IGZyb20gXCIuLi90eXBlcy9iYXNlLm1qc1wiO1xuaW1wb3J0IHsgZ2V0R2xvYmFsT2JqZWN0IH0gZnJvbSBcIi4uL3R5cGVzL2dsb2JhbC5tanNcIjtcbmltcG9ydCB7IGVxdWlwV2l0aEludGVybmFsIH0gZnJvbSBcIi4uL3R5cGVzL2ludGVybmFsLm1qc1wiO1xuaW1wb3J0IHsgaXNBcnJheSB9IGZyb20gXCIuLi90eXBlcy9pcy5tanNcIjtcbmltcG9ydCB7IEFUVFJJQlVURV9IUkVGLCBBVFRSSUJVVEVfU1JDIH0gZnJvbSBcIi4vY29uc3RhbnRzLm1qc1wiO1xuaW1wb3J0IHsgUmVzb3VyY2UgfSBmcm9tIFwiLi9yZXNvdXJjZS5tanNcIjtcbmltcG9ydCB7IERhdGEgfSBmcm9tIFwiLi9yZXNvdXJjZS9kYXRhLm1qc1wiO1xuaW1wb3J0IHsgU3R5bGVzaGVldCB9IGZyb20gXCIuL3Jlc291cmNlL2xpbmsvc3R5bGVzaGVldC5tanNcIjtcbmltcG9ydCB7IFNjcmlwdCB9IGZyb20gXCIuL3Jlc291cmNlL3NjcmlwdC5tanNcIjtcblxuZXhwb3J0IHsgUmVzb3VyY2VNYW5hZ2VyIH07XG5cbi8qKlxuICogVGhlIFJlc291cmNlTWFuYWdlciBpcyBhIHNpbmdsZXRvbiB0aGF0IG1hbmFnZXMgYWxsIHJlc291cmNlcy5cbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI1LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEBzdW1tYXJ5IEEgUmVzb3VyY2UgY2xhc3NcbiAqL1xuY2xhc3MgUmVzb3VyY2VNYW5hZ2VyIGV4dGVuZHMgQmFzZSB7XG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICAgICAqIHRocm93IHtFcnJvcn0gdW5zdXBwb3J0ZWQgZG9jdW1lbnQgdHlwZVxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICAgIGVxdWlwV2l0aEludGVybmFsLmNhbGwodGhpcyk7XG5cbiAgICAgICAgaWYgKCEodGhpcy5nZXRPcHRpb24oXCJkb2N1bWVudFwiKSBpbnN0YW5jZW9mIERvY3VtZW50KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidW5zdXBwb3J0ZWQgZG9jdW1lbnQgdHlwZVwiKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBkZXByZWNhdGVkIHNpbmNlIDMuMTUuMCB1c2UgZ2V0SW50ZXJuYWwgaW5zdGVhZFxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBiYXNldXJsXG4gICAgICovXG4gICAgZ2V0T3B0aW9uKGtleSkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRJbnRlcm5hbChrZXkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBiYXNldXJsXG4gICAgICovXG4gICAgZ2V0QmFzZVVSTCgpIHtcbiAgICAgICAgdGhpcy5nZXRPcHRpb24oXCJkb2N1bWVudFwiKT8uYmFzZVVSTDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gYmFzZXVybFxuICAgICAqIEBkZXByZWNhdGVkIHNpbmNlIDMuMTUuMCB1c2UgaW50ZXJuYWxEZWZhdWx0cyBpbnN0ZWFkXG4gICAgICovXG4gICAgZ2V0IGRlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5pbnRlcm5hbERlZmF1bHRzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHByb3BlcnR5IHtIVE1MRG9jdW1lbnR9IGRvY3VtZW50PWRvY3VtZW50IERvY3VtZW50XG4gICAgICogQHByb3BlcnR5IHtPYmplY3R9IHJlc291cmNlc1xuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXl9IHJlc291cmNlcy5zY3JpcHRzPVtdIGFycmF5IHdpdGgge0BsaW5rIE1vbnN0ZXIuRE9NLlJlc291cmNlLlNjcmlwdH0gb2JqZWN0c1xuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXl9IHJlc291cmNlcy5zdHlsZXNoZWV0cz1bXSBhcnJheSB3aXRoIHtAbGluayBNb25zdGVyLkRPTS5SZXNvdXJjZS5MaW5rLlN0eWxlc2hlZXR9IG9iamVjdHNcbiAgICAgKiBAcHJvcGVydHkge0FycmF5fSByZXNvdXJjZXMuZGF0YT1bXSBhcnJheSB3aXRoIHtAbGluayBNb25zdGVyLkRPTS5SZXNvdXJjZS5EYXRhfSBvYmplY3RzXG4gICAgICovXG4gICAgZ2V0IGludGVybmFsRGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFxuICAgICAgICAgICAge30sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQ6IGdldEdsb2JhbE9iamVjdChcImRvY3VtZW50XCIpLFxuICAgICAgICAgICAgICAgIHJlc291cmNlczoge1xuICAgICAgICAgICAgICAgICAgICBzY3JpcHRzOiBbXSxcbiAgICAgICAgICAgICAgICAgICAgc3R5bGVzaGVldHM6IFtdLFxuICAgICAgICAgICAgICAgICAgICBkYXRhOiBbXSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBcHBlbmQgVGFncyB0byBET01cbiAgICAgKlxuICAgICAqIEByZXR1cm4ge01vbnN0ZXIuRE9NLlJlc291cmNlTWFuYWdlcn1cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gdW5zdXBwb3J0ZWQgcmVzb3VyY2UgZGVmaW5pdGlvblxuICAgICAqL1xuICAgIGNvbm5lY3QoKSB7XG4gICAgICAgIHJ1blJlc291cmNlTWV0aG9kLmNhbGwodGhpcywgXCJjb25uZWN0XCIpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVjayBpZiBhdmFpbGFibGVcbiAgICAgKlxuICAgICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAgICogQHRocm93cyB7RXJyb3J9IHVuc3VwcG9ydGVkIHJlc291cmNlIGRlZmluaXRpb25cbiAgICAgKi9cbiAgICBhdmFpbGFibGUoKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChydW5SZXNvdXJjZU1ldGhvZC5jYWxsKHRoaXMsIFwiYXZhaWxhYmxlXCIpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSBzY3JpcHRcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfFVSTH0gdXJsXG4gICAgICogQHBhcmFtIFtPYmplY3R8dW5kZWZpbmVkfSBvcHRpb25zXG4gICAgICogQHJldHVybiB7TW9uc3Rlci5ET00uUmVzb3VyY2VNYW5hZ2VyfVxuICAgICAqIEBzZWUgTW9uc3Rlci5ET00uUmVzb3VyY2UuU2NyaXB0XG4gICAgICovXG4gICAgYWRkU2NyaXB0KHVybCwgb3B0aW9ucykge1xuICAgICAgICByZXR1cm4gYWRkUmVzb3VyY2UuY2FsbCh0aGlzLCBcInNjcmlwdHNcIiwgdXJsLCBvcHRpb25zKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBZGQgU3R5bGVzaGVldFxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd8VVJMfSB1cmxcbiAgICAgKiBAcGFyYW0gW09iamVjdHx1bmRlZmluZWR9IG9wdGlvbnNcbiAgICAgKiBAcmV0dXJuIHtNb25zdGVyLkRPTS5SZXNvdXJjZU1hbmFnZXJ9XG4gICAgICogQHNlZSBNb25zdGVyLkRPTS5SZXNvdXJjZS5MaW5rLlN0eWxlc2hlZXRcbiAgICAgKi9cbiAgICBhZGRTdHlsZXNoZWV0KHVybCwgb3B0aW9ucykge1xuICAgICAgICByZXR1cm4gYWRkUmVzb3VyY2UuY2FsbCh0aGlzLCBcInN0eWxlc2hlZXRzXCIsIHVybCwgb3B0aW9ucyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkIERhdGEgVGFnXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xVUkx9IHVybFxuICAgICAqIEBwYXJhbSBbT2JqZWN0fHVuZGVmaW5lZH0gb3B0aW9uc1xuICAgICAqIEByZXR1cm4ge01vbnN0ZXIuRE9NLlJlc291cmNlTWFuYWdlcn1cbiAgICAgKiBAc2VlIE1vbnN0ZXIuRE9NLlJlc291cmNlLkRhdGFcbiAgICAgKi9cbiAgICBhZGREYXRhKHVybCwgb3B0aW9ucykge1xuICAgICAgICByZXR1cm4gYWRkUmVzb3VyY2UuY2FsbCh0aGlzLCBcImRhdGFcIiwgdXJsLCBvcHRpb25zKTtcbiAgICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXRob2RcbiAqIEByZXR1cm4ge0FycmF5fVxuICovXG5mdW5jdGlvbiBydW5SZXNvdXJjZU1ldGhvZChtZXRob2QpIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgIGNvbnN0IHJlc3VsdCA9IFtdO1xuXG4gICAgZm9yIChjb25zdCB0eXBlIG9mIFtcInNjcmlwdHNcIiwgXCJzdHlsZXNoZWV0c1wiLCBcImRhdGFcIl0pIHtcbiAgICAgICAgY29uc3QgcmVzb3VyY2VzID0gc2VsZi5nZXRPcHRpb24oYHJlc291cmNlcy4ke3R5cGV9YCk7XG4gICAgICAgIGlmICghaXNBcnJheShyZXNvdXJjZXMpKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoY29uc3QgcmVzb3VyY2Ugb2YgcmVzb3VyY2VzKSB7XG4gICAgICAgICAgICBpZiAoIShyZXNvdXJjZSBpbnN0YW5jZW9mIFJlc291cmNlKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInVuc3VwcG9ydGVkIHJlc291cmNlIGRlZmluaXRpb25cIik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKHJlc291cmNlW21ldGhvZF0oKSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdHlwZVxuICogQHBhcmFtIHtzdHJpbmd8VVJMfSB1cmxcbiAqIEBwYXJhbSBbT2JqZWN0fHVuZGVmaW5lZH0gb3B0aW9uc1xuICogQHJldHVybiB7TW9uc3Rlci5ET00uUmVzb3VyY2VNYW5hZ2VyfVxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gYWRkUmVzb3VyY2UodHlwZSwgdXJsLCBvcHRpb25zKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICBpZiAodXJsIGluc3RhbmNlb2YgVVJMKSB7XG4gICAgICAgIHVybCA9IHVybC50b1N0cmluZygpO1xuICAgIH1cblxuICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gICAgbGV0IHJlc291cmNlO1xuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgICBjYXNlIFwic2NyaXB0c1wiOlxuICAgICAgICAgICAgcmVzb3VyY2UgPSBuZXcgU2NyaXB0KGV4dGVuZCh7fSwgb3B0aW9ucywgeyBbQVRUUklCVVRFX1NSQ106IHVybCB9KSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcInN0eWxlc2hlZXRzXCI6XG4gICAgICAgICAgICByZXNvdXJjZSA9IG5ldyBTdHlsZXNoZWV0KGV4dGVuZCh7fSwgb3B0aW9ucywgeyBbQVRUUklCVVRFX0hSRUZdOiB1cmwgfSkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJkYXRhXCI6XG4gICAgICAgICAgICByZXNvdXJjZSA9IG5ldyBEYXRhKGV4dGVuZCh7fSwgb3B0aW9ucywgeyBbQVRUUklCVVRFX1NSQ106IHVybCB9KSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgdW5zdXBwb3J0ZWQgdHlwZSAke3R5cGV9YCk7XG4gICAgfVxuXG4gICAgc2VsZi5nZXRPcHRpb24oXCJyZXNvdXJjZXNcIik/Llt0eXBlXS5wdXNoKHJlc291cmNlKTtcbiAgICByZXR1cm4gc2VsZjtcbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5pbXBvcnQgeyBpbnRlcm5hbFN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQgeyBleHRlbmQgfSBmcm9tIFwiLi4vZGF0YS9leHRlbmQubWpzXCI7XG5pbXBvcnQgeyBQYXRoZmluZGVyIH0gZnJvbSBcIi4uL2RhdGEvcGF0aGZpbmRlci5tanNcIjtcbmltcG9ydCB7IHBhcnNlRGF0YVVSTCB9IGZyb20gXCIuL2RhdGF1cmwubWpzXCI7XG5pbXBvcnQgeyBpc1N0cmluZyB9IGZyb20gXCIuL2lzLm1qc1wiO1xuaW1wb3J0IHsgT2JzZXJ2ZXIgfSBmcm9tIFwiLi9vYnNlcnZlci5tanNcIjtcbmltcG9ydCB7IFByb3h5T2JzZXJ2ZXIgfSBmcm9tIFwiLi9wcm94eW9ic2VydmVyLm1qc1wiO1xuaW1wb3J0IHsgdmFsaWRhdGVPYmplY3QgfSBmcm9tIFwiLi92YWxpZGF0ZS5tanNcIjtcbmltcG9ydCB7IGlzT2JqZWN0IH0gZnJvbSBcIi4vaXMubWpzXCI7XG5cbmV4cG9ydCB7IGVxdWlwV2l0aEludGVybmFsIH07XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEB0eXBlIHtzdHJpbmd9XG4gKi9cbmNvbnN0IHByb3BlcnR5TmFtZSA9IFwiaW50ZXJuYWxEZWZhdWx0c1wiO1xuXG4vKipcbiAqIFRoaXMgZnVuY3Rpb24gZXh0ZW5kcyB0aGUgZ2l2ZW4gb2JqZWN0IHdpdGggdGhlIGZvbGxvd2luZyBtZXRob2RzOlxuICpcbiAqIC0gYXR0YWNoSW50ZXJuYWxPYnNlcnZlclxuICogLSBkZXRhY2hJbnRlcm5hbE9ic2VydmVyXG4gKiAtIGNvbnRhaW5zSW50ZXJuYWxPYnNlcnZlclxuICogLSBzZXRJbnRlcm5hbFxuICogLSBzZXRJbnRlcm5hbHNcbiAqIC0gZ2V0SW50ZXJuYWxcbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAzLjE1LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UeXBlc1xuICovXG5mdW5jdGlvbiBlcXVpcFdpdGhJbnRlcm5hbCgpIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICB2YWxpZGF0ZU9iamVjdChzZWxmKTtcblxuICAgIGlmICghaGFzR2V0dGVyKHNlbGYsIHByb3BlcnR5TmFtZSkpIHtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHNlbGYsIHByb3BlcnR5TmFtZSwge1xuICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHt9O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgY29uc3QgZGVmYXVsdHMgPSBleHRlbmQoe30sIHNlbGZbcHJvcGVydHlOYW1lXSB8fCB7fSk7XG4gICAgc2VsZltpbnRlcm5hbFN5bWJvbF0gPSBuZXcgUHJveHlPYnNlcnZlcihkZWZhdWx0cyk7XG5cbiAgICAvKipcbiAgICAgKiBBdHRhY2ggYSBuZXcgb2JzZXJ2ZXJcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7T2JzZXJ2ZXJ9IG9ic2VydmVyXG4gICAgICogQHJldHVybnMge1Byb3h5T2JzZXJ2ZXJ9XG4gICAgICovXG4gICAgc2VsZltcImF0dGFjaEludGVybmFsT2JzZXJ2ZXJcIl0gPSAob2JzZXJ2ZXIpID0+IHtcbiAgICAgICAgc2VsZltpbnRlcm5hbFN5bWJvbF0uYXR0YWNoT2JzZXJ2ZXIob2JzZXJ2ZXIpO1xuICAgICAgICByZXR1cm4gc2VsZjtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGV0YWNoIGEgb2JzZXJ2ZXJcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7T2JzZXJ2ZXJ9IG9ic2VydmVyXG4gICAgICogQHJldHVybnMge1Byb3h5T2JzZXJ2ZXJ9XG4gICAgICovXG4gICAgc2VsZltcImRldGFjaEludGVybmFsT2JzZXJ2ZXJcIl0gPSAob2JzZXJ2ZXIpID0+IHtcbiAgICAgICAgc2VsZltpbnRlcm5hbFN5bWJvbF0uZGV0YWNoT2JzZXJ2ZXIob2JzZXJ2ZXIpO1xuICAgICAgICByZXR1cm4gc2VsZjtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ2hlY2sgaWYgYSBvYnNlcnZlciBpcyBhdHRhY2hlZFxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYnNlcnZlcn0gb2JzZXJ2ZXJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBzZWxmW1wiY29udGFpbnNJbnRlcm5hbE9ic2VydmVyXCJdID0gKG9ic2VydmVyKSA9PiB7XG4gICAgICAgIHJldHVybiBzZWxmW2ludGVybmFsU3ltYm9sXS5jb250YWluc09ic2VydmVyKG9ic2VydmVyKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogU2V0IGFuIGludGVybmFsIHZhbHVlLCBuZXN0ZWQgaW50ZXJuYWxzIGNhbiBiZSBzcGVjaWZpZWQgYnkgcGF0aCBgYS5iLmNgXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcGF0aFxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAgICAgKiBAcmV0dXJuIHtEYXRhc291cmNlfVxuICAgICAqL1xuICAgIHNlbGZbXCJzZXRJbnRlcm5hbFwiXSA9IChwYXRoLCB2YWx1ZSkgPT4ge1xuICAgICAgICBuZXcgUGF0aGZpbmRlcihzZWxmW2ludGVybmFsU3ltYm9sXS5nZXRTdWJqZWN0KCkpLnNldFZpYShwYXRoLCB2YWx1ZSk7XG4gICAgICAgIHJldHVybiBzZWxmO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBzZXQgbXVsdGlwbGUgaW50ZXJuYWxzIGF0IG9uY2VcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfG9iamVjdH0gb3B0aW9uc1xuICAgICAqIEByZXR1cm4ge0RhdGFzb3VyY2V9XG4gICAgICogQHRocm93cyB7RXJyb3J9IHRoZSBvcHRpb25zIGRvZXMgbm90IGNvbnRhaW4gYSB2YWxpZCBqc29uIGRlZmluaXRpb25cbiAgICAgKi9cbiAgICBzZWxmW1wic2V0SW50ZXJuYWxzXCJdID0gKG9wdGlvbnMpID0+IHtcbiAgICAgICAgaWYgKGlzU3RyaW5nKG9wdGlvbnMpKSB7XG4gICAgICAgICAgICBvcHRpb25zID0gcGFyc2VPcHRpb25zSlNPTihvcHRpb25zKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGV4dGVuZChzZWxmW2ludGVybmFsU3ltYm9sXS5nZXRTdWJqZWN0KCksIGRlZmF1bHRzLCBvcHRpb25zKTtcbiAgICAgICAgcmV0dXJuIHNlbGY7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIG5lc3RlZCBpbnRlcm5hbHMgY2FuIGJlIHNwZWNpZmllZCBieSBwYXRoIGBhLmIuY2BcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoXG4gICAgICogQHBhcmFtIHsqfSBkZWZhdWx0VmFsdWVcbiAgICAgKiBAcmV0dXJuIHsqfVxuICAgICAqL1xuICAgIHNlbGZbXCJnZXRJbnRlcm5hbFwiXSA9IChwYXRoLCBkZWZhdWx0VmFsdWUpID0+IHtcbiAgICAgICAgbGV0IHZhbHVlO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB2YWx1ZSA9IG5ldyBQYXRoZmluZGVyKHNlbGZbaW50ZXJuYWxTeW1ib2xdLmdldFJlYWxTdWJqZWN0KCkpLmdldFZpYShwYXRoKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge31cblxuICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkgcmV0dXJuIGRlZmF1bHRWYWx1ZTtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH07XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSBvYmpcbiAqIEBwYXJhbSBwcm9wXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5mdW5jdGlvbiBoYXNHZXR0ZXIob2JqLCBwcm9wKSB7XG4gICAgd2hpbGUgKGlzT2JqZWN0KG9iaikpIHtcbiAgICAgICAgaWYgKE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqLCBwcm9wKT8uW1wiZ2V0XCJdKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBvYmogPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSBkYXRhXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cbmZ1bmN0aW9uIHBhcnNlT3B0aW9uc0pTT04oZGF0YSkge1xuICAgIGxldCBvYmogPSB7fTtcblxuICAgIGlmICghaXNTdHJpbmcoZGF0YSkpIHtcbiAgICAgICAgcmV0dXJuIG9iajtcbiAgICB9XG5cbiAgICAvLyB0aGUgY29uZmlndXJhdGlvbiBjYW4gYmUgc3BlY2lmaWVkIGFzIGEgZGF0YSB1cmwuXG4gICAgdHJ5IHtcbiAgICAgICAgbGV0IGRhdGFVcmwgPSBwYXJzZURhdGFVUkwoZGF0YSk7XG4gICAgICAgIGRhdGEgPSBkYXRhVXJsLmNvbnRlbnQ7XG4gICAgfSBjYXRjaCAoZSkge31cblxuICAgIHRyeSB7XG4gICAgICAgIG9iaiA9IEpTT04ucGFyc2UoZGF0YSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICB0aHJvdyBlO1xuICAgIH1cblxuICAgIHJldHVybiB2YWxpZGF0ZU9iamVjdChvYmopO1xufVxuIiwgIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcblxuaW1wb3J0IHtSZXNvdXJjZU1hbmFnZXJ9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvZG9tL3Jlc291cmNlbWFuYWdlci5tanNcIjtcbmltcG9ydCB7Y2xlYW51cERPTUZyb21UZXN0aW5nLCBpbml0TXV0YXRpb25PYnNlcnZlckZvclRlc3Rpbmd9IGZyb20gXCIuLi8uLi91dGlsL2NsZWFudXBkb20ubWpzXCI7XG5pbXBvcnQge2luaXRKU0RPTX0gZnJvbSBcIi4uLy4uL3V0aWwvanNkb20ubWpzXCI7XG5cbmRlc2NyaWJlKCdSZXNvdXJjZU1hbmFnZXInLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBsZXQgZmV0Y2hSZWZlcmVuY2UsIHJldHVyblN0YXR1cztcblxuICAgIGJlZm9yZShmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICBpbml0SlNET00oKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICB9KS5jYXRjaChlID0+IGRvbmUoZSkpO1xuICAgIH0pO1xuXG4gICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgICAgZ2xvYmFsVGhpc1snZmV0Y2gnXSA9IGZldGNoUmVmZXJlbmNlO1xuICAgICAgICBjbGVhbnVwRE9NRnJvbVRlc3RpbmcoKTtcbiAgICB9KVxuXG4gICAgYmVmb3JlRWFjaCgoKSA9PiB7XG5cbiAgICAgICAgaW5pdE11dGF0aW9uT2JzZXJ2ZXJGb3JUZXN0aW5nKClcblxuICAgICAgICByZXR1cm5TdGF0dXMgPSAyMDA7XG4gICAgICAgIGZldGNoUmVmZXJlbmNlID0gZ2xvYmFsVGhpc1snZmV0Y2gnXTtcbiAgICAgICAgZ2xvYmFsVGhpc1snZmV0Y2gnXSA9IGZ1bmN0aW9uICh1cmwsIG9wdGlvbnMpIHtcblxuICAgICAgICAgICAgaWYgKCF1cmwpIHRocm93IG5ldyBFcnJvcignbWlzc2luZyB1cmwnKVxuXG4gICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgICAgIHJlc29sdmUoe1xuICAgICAgICAgICAgICAgICAgICB0ZXh0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGE6IFwidGVzdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBzdGF0dXM6IHJldHVyblN0YXR1c1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSlcblxuICAgICAgICB9O1xuXG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCduZXcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCduZXcgUmVzb3VyY2VNYW5hZ2VyKCkgc2hvdWxkIHJldHVybiBSZXNvdXJjZU1hbmFnZXIgb2JqZWN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGV0IGQgPSBuZXcgUmVzb3VyY2VNYW5hZ2VyKCk7XG4gICAgICAgICAgICBleHBlY3QoZCkudG8uYmUuaW5zdGFuY2VPZihSZXNvdXJjZU1hbmFnZXIpO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdsb2FkIHJlc291cmNlcycsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBsZXQgbWFuYWdlcjtcblxuICAgICAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAgICAgIG1hbmFnZXIgPSBuZXcgUmVzb3VyY2VNYW5hZ2VyKCk7XG4gICAgICAgIH0pXG5cbiAgICAgICAgaXQoJ2FkZCBzY3JpcHQgc2hvdWxkIGluc3RhbmNlIG9mIFJlc291cmNlTWFuYWdlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChtYW5hZ2VyLmFkZFNjcmlwdCgnL2V4YW1wbGUuanMnKSkudG8uYmUuaW5zdGFuY2VPZihSZXNvdXJjZU1hbmFnZXIpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnYWRkIHN0eWxlIHNob3VsZCBpbnN0YW5jZSBvZiBSZXNvdXJjZU1hbmFnZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobWFuYWdlci5hZGRTdHlsZXNoZWV0KCcvc3R5bGUuanMnKSkudG8uYmUuaW5zdGFuY2VPZihSZXNvdXJjZU1hbmFnZXIpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnYWRkIGRhdGEgc2hvdWxkIGluc3RhbmNlIG9mIFJlc291cmNlTWFuYWdlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChtYW5hZ2VyLmFkZERhdGEoJy9kYXRhLmpzb24nKSkudG8uYmUuaW5zdGFuY2VPZihSZXNvdXJjZU1hbmFnZXIpO1xuICAgICAgICB9KTtcblxuICAgICAgICBkZXNjcmliZSgnY29ubmVjdCByZXNvdXJjZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpdCgnYWRkIHNjcmlwdCBhbmQgY29ubmVjdCBzaG91bGQgaW5zdGFuY2Ugb2YgUmVzb3VyY2VNYW5hZ2VyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGV4cGVjdChtYW5hZ2VyLmFkZFNjcmlwdCgnL2V4YW1wbGUuanMnKS5jb25uZWN0KCkpLnRvLmJlLmluc3RhbmNlT2YoUmVzb3VyY2VNYW5hZ2VyKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpdCgnYWRkIHN0eWxlIGFuZCBjb25uZWN0IHNob3VsZCBpbnN0YW5jZSBvZiBSZXNvdXJjZU1hbmFnZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KG1hbmFnZXIuYWRkU3R5bGVzaGVldCgnL3N0eWxlLmpzJykuY29ubmVjdCgpKS50by5iZS5pbnN0YW5jZU9mKFJlc291cmNlTWFuYWdlcik7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaXQoJ2FkZCBkYXRhIGFuZCBjb25uZWN0ICBzaG91bGQgaW5zdGFuY2Ugb2YgUmVzb3VyY2VNYW5hZ2VyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGV4cGVjdChtYW5hZ2VyLmFkZERhdGEoJy9kYXRhLmpzb24nKS5jb25uZWN0KCkpLnRvLmJlLmluc3RhbmNlT2YoUmVzb3VyY2VNYW5hZ2VyKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuXG5cbiAgICAgICAgZGVzY3JpYmUoJ2NoZWNrIGF2YWlsYWJpbGl0eSByZXNvdXJjZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpdCgnYWRkIHNjcmlwdCBhbmQgY2hlY2sgYXZhaWxhYmlsaXR5IHNob3VsZCByZXR1cm4gUHJvbWlzZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBleHBlY3QobWFuYWdlci5hZGRTY3JpcHQoJy9leGFtcGxlLmpzJykuYXZhaWxhYmxlKCkpLnRvLmJlLmluc3RhbmNlT2YoUHJvbWlzZSk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaXQoJ2FkZCBzdHlsZSBhbmQgY2hlY2sgYXZhaWxhYmlsaXR5IHNob3VsZCBzaG91bGQgcmV0dXJuIFByb21pc2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KG1hbmFnZXIuYWRkU3R5bGVzaGVldCgnL3N0eWxlLmpzJykuYXZhaWxhYmxlKCkpLnRvLmJlLmluc3RhbmNlT2YoUHJvbWlzZSk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaXQoJ2FkZCBkYXRhIGFuZCBjaGVjayBhdmFpbGFiaWxpdHkgIHNob3VsZCBzaG91bGQgcmV0dXJuIFByb21pc2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KG1hbmFnZXIuYWRkRGF0YSgnL2RhdGEuanNvbicpLmF2YWlsYWJsZSgpKS50by5iZS5pbnN0YW5jZU9mKFByb21pc2UpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pXG5cbiAgICAgICAgZGVzY3JpYmUoJ2NoZWNrIGF2YWlsYWJpbGl0eSBleGFtcGxlLmpzb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpdCgnYWRkIGRhdGEgYW5kIGNoZWNrIGNvbnRlbnQnLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICAgICAgICAgIG1hbmFnZXIuYWRkRGF0YSgnaHR0cHM6Ly9leGFtcGxlLmNvbS9leGFtcGxlLmpzb24nKS5jb25uZWN0KCkuYXZhaWxhYmxlKCkudGhlbihyID0+IHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2h0bWwnKS5vdXRlckhUTUwpLmNvbnRhaW5zKCc+e1wiYVwiOlwidGVzdFwifTwvc2NyaXB0PjwvaGVhZD4nKTtcbiAgICAgICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgICAgIH0pLmNhdGNoKGUgPT4gZG9uZShlKSk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICB9KVxuXG4gICAgfSk7XG5cblxufSk7IiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgQmFzZSB9IGZyb20gXCIuLi90eXBlcy9iYXNlLm1qc1wiO1xuaW1wb3J0IHsgZ2V0R2xvYmFsRnVuY3Rpb24gfSBmcm9tIFwiLi4vdHlwZXMvZ2xvYmFsLm1qc1wiO1xuaW1wb3J0IHsgUHJveHlPYnNlcnZlciB9IGZyb20gXCIuLi90eXBlcy9wcm94eW9ic2VydmVyLm1qc1wiO1xuaW1wb3J0IHsgdmFsaWRhdGVJbnN0YW5jZSwgdmFsaWRhdGVTdHJpbmcgfSBmcm9tIFwiLi4vdHlwZXMvdmFsaWRhdGUubWpzXCI7XG5cbmV4cG9ydCB7IEFUVFJJQlVURVBSRUZJWCwgQXNzZW1ibGVyIH07XG5cbi8qKlxuICogYXR0cmlidXRlIHByZWZpeFxuICpcbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqL1xuY29uc3QgQVRUUklCVVRFUFJFRklYID0gXCJkYXRhLW1vbnN0ZXItXCI7XG5cbi8qKlxuICogQXNzZW1ibGVyIGNsYXNzXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS42LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5ET01cbiAqIEBzdW1tYXJ5IEFsbG93cyB5b3UgdG8gYnVpbGQgYW4gaHRtbCBmcmFnbWVudFxuICovXG5jbGFzcyBBc3NlbWJsZXIgZXh0ZW5kcyBCYXNlIHtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0RvY3VtZW50RnJhZ21lbnR9IGZyYWdtZW50XG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYW4gaW5zdGFuY2Ugb2ZcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIGZ1bmN0aW9uXG4gICAgICogQHRocm93cyB7RXJyb3J9IHRoZSBmdW5jdGlvbiBpcyBub3QgZGVmaW5lZFxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGZyYWdtZW50KSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMuYXR0cmlidXRlUHJlZml4ID0gQVRUUklCVVRFUFJFRklYO1xuICAgICAgICB2YWxpZGF0ZUluc3RhbmNlKGZyYWdtZW50LCBnZXRHbG9iYWxGdW5jdGlvbihcIkRvY3VtZW50RnJhZ21lbnRcIikpO1xuICAgICAgICB0aGlzLmZyYWdtZW50ID0gZnJhZ21lbnQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcHJlZml4XG4gICAgICogQHJldHVybnMge0Fzc2VtYmxlcn1cbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIHN0cmluZ1xuICAgICAqL1xuICAgIHNldEF0dHJpYnV0ZVByZWZpeChwcmVmaXgpIHtcbiAgICAgICAgdmFsaWRhdGVTdHJpbmcocHJlZml4KTtcbiAgICAgICAgdGhpcy5hdHRyaWJ1dGVQcmVmaXggPSBwcmVmaXg7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHJldHVybnMge3N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRBdHRyaWJ1dGVQcmVmaXgoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmF0dHJpYnV0ZVByZWZpeDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7UHJveHlPYnNlcnZlcnx1bmRlZmluZWR9IGRhdGFcbiAgICAgKiBAcmV0dXJuIHtEb2N1bWVudEZyYWdtZW50fVxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGFuIGluc3RhbmNlIG9mXG4gICAgICovXG4gICAgY3JlYXRlRG9jdW1lbnRGcmFnbWVudChkYXRhKSB7XG4gICAgICAgIGlmIChkYXRhID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGRhdGEgPSBuZXcgUHJveHlPYnNlcnZlcih7fSk7XG4gICAgICAgIH1cblxuICAgICAgICB2YWxpZGF0ZUluc3RhbmNlKGRhdGEsIFByb3h5T2JzZXJ2ZXIpO1xuICAgICAgICBsZXQgZnJhZ21lbnQgPSB0aGlzLmZyYWdtZW50LmNsb25lTm9kZSh0cnVlKTtcbiAgICAgICAgcmV0dXJuIGZyYWdtZW50O1xuICAgIH1cbn1cbiIsICJpbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuXG5pbXBvcnQge0FUVFJJQlVURVBSRUZJWCwgQXNzZW1ibGVyfSBmcm9tIFwiLi4vLi4vLi4vc291cmNlL2RvbS9hc3NlbWJsZXIubWpzXCI7XG5pbXBvcnQge2luaXRKU0RPTX0gZnJvbSBcIi4uLy4uL3V0aWwvanNkb20ubWpzXCI7XG5cbmRlc2NyaWJlKCdBc3NlbWJsZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgYmVmb3JlKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaW5pdEpTRE9NKCk7XG4gICAgfSlcbiAgICBkZXNjcmliZSgnY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiA8ZGl2Pk9uZTwvZGl2PjxkaXY+VHdvPC9kaXY+JywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBsZXQgZnJhZ21lbnQgPSBkb2N1bWVudC5jcmVhdGVSYW5nZSgpLmNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudCgnPGRpdj5PbmU8L2Rpdj48ZGl2PlR3bzwvZGl2PicpO1xuXG4gICAgICAgICAgICBsZXQgZiA9IG5ldyBBc3NlbWJsZXIoZnJhZ21lbnQpO1xuXG4gICAgICAgICAgICAvLyBjb252ZXJ0IHRvIHN0cmluZ1xuICAgICAgICAgICAgbGV0IGNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKGYuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpLmNsb25lTm9kZSh0cnVlKSk7XG5cbiAgICAgICAgICAgIGV4cGVjdChjb250YWluZXIuaW5uZXJIVE1MKS50by5iZS5lcXVhbCgnPGRpdj5PbmU8L2Rpdj48ZGl2PlR3bzwvZGl2PicpO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdjcmVhdGVEb2N1bWVudEZyYWdtZW50KCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIERvY3VtZW50RnJhZ21lbnQgb2JqZWN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGV0IGQgPSBuZXcgQXNzZW1ibGVyKGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKSk7XG4gICAgICAgICAgICBleHBlY3QoZC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCkpLnRvLmJlLmluc3RhbmNlT2YoRG9jdW1lbnRGcmFnbWVudCk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ25ldycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ25ldyBSZW5kZXJlcigpIHNob3VsZCByZXR1cm4gQXNzZW1ibGVyIG9iamVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBkID0gbmV3IEFzc2VtYmxlcihkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCkpO1xuICAgICAgICAgICAgZXhwZWN0KGQpLnRvLmJlLmluc3RhbmNlT2YoQXNzZW1ibGVyKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnZ2V0QXR0cmlidXRlUHJlZml4KCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuICcgKyBBVFRSSUJVVEVQUkVGSVgsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBkID0gbmV3IEFzc2VtYmxlcihkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCkpO1xuICAgICAgICAgICAgZXhwZWN0KGQuZ2V0QXR0cmlidXRlUHJlZml4KCkpLnRvLmJlLmVxdWFsKEFUVFJJQlVURVBSRUZJWCk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3NldEF0dHJpYnV0ZVByZWZpeCgpLmdldEF0dHJpYnV0ZVByZWZpeCgpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBzYW1lIHZhbHVlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGV0IGQgPSBuZXcgQXNzZW1ibGVyKGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKSk7XG4gICAgICAgICAgICBleHBlY3QoZC5zZXRBdHRyaWJ1dGVQcmVmaXgoJ3Rlc3QwMScpLmdldEF0dHJpYnV0ZVByZWZpeCgpKS50by5iZS5lcXVhbCgndGVzdDAxJyk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG5cbn0pOyIsICIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBjaGFpIGZyb20gXCJjaGFpXCJcbmltcG9ydCB7QVRUUklCVVRFX09QVElPTlN9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvZG9tL2NvbnN0YW50cy5tanNcIjtcbmltcG9ydCB7Z2V0RG9jdW1lbnR9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvZG9tL3V0aWwubWpzXCI7XG5pbXBvcnQge2NoYWlEb219IGZyb20gXCIuLi8uLi91dGlsL2NoYWktZG9tLm1qc1wiO1xuaW1wb3J0IHtjbGVhbnVwRE9NRnJvbVRlc3RpbmcsIGluaXRNdXRhdGlvbk9ic2VydmVyRm9yVGVzdGluZ30gZnJvbSBcIi4uLy4uL3V0aWwvY2xlYW51cGRvbS5tanNcIjtcbmltcG9ydCB7aW5pdEpTRE9NfSBmcm9tIFwiLi4vLi4vdXRpbC9qc2RvbS5tanNcIjtcblxubGV0IGV4cGVjdCA9IGNoYWkuZXhwZWN0O1xuY2hhaS51c2UoY2hhaURvbSk7XG5cbmxldCBodG1sMSA9IGBcbiAgICA8ZGl2IGlkPVwidGVzdDFcIj5cbiAgICA8L2Rpdj5cbmA7XG5cbmRlc2NyaWJlKCdET00nLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBsZXQgQ3VzdG9tQ29udHJvbCwgcmVnaXN0ZXJDdXN0b21FbGVtZW50LCBUZXN0Q29tcG9uZW50LCBkb2N1bWVudCwganNkb21GbGFnO1xuXG4gICAgYmVmb3JlKGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgIGluaXRKU0RPTSgpLnRoZW4oKCkgPT4ge1xuXG4gICAgICAgICAgICBpbXBvcnQoXCJlbGVtZW50LWludGVybmFscy1wb2x5ZmlsbFwiKS50aGVuKChtKSA9PiB7XG4gICAgICAgICAgICAgICAgbS5wb2x5ZmlsbCgpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIC8vIGpzZG9tIGRvZXMgbm90IHN1cHBvcnQgRWxlbWVudEludGVybmFsc1xuICAgICAgICAgICAganNkb21GbGFnID0gbmF2aWdhdG9yLnVzZXJBZ2VudC5pbmNsdWRlcyhcImpzZG9tXCIpO1xuXG4gICAgICAgICAgICBpbXBvcnQoXCIuLi8uLi8uLi9zb3VyY2UvZG9tL2N1c3RvbWVsZW1lbnQubWpzXCIpLnRoZW4oKG0pID0+IHtcbiAgICAgICAgICAgICAgICByZWdpc3RlckN1c3RvbUVsZW1lbnQgPSBtWydyZWdpc3RlckN1c3RvbUVsZW1lbnQnXTtcblxuXG4gICAgICAgICAgICAgICAgaW1wb3J0KFwiLi4vLi4vLi4vc291cmNlL2RvbS9jdXN0b21jb250cm9sLm1qc1wiKS50aGVuKChtKSA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnQgPSBnZXREb2N1bWVudCgpO1xuXG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBDdXN0b21Db250cm9sID0gbVsnQ3VzdG9tQ29udHJvbCddO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBUZXN0Q29tcG9uZW50ID0gY2xhc3MgZXh0ZW5kcyBDdXN0b21Db250cm9sIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0aWMgZ2V0VGFnKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJtb25zdGVyLWN1c3RvbWNvbnRyb2xcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2lzdGVyQ3VzdG9tRWxlbWVudChUZXN0Q29tcG9uZW50KVxuXG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkb25lKGUpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cblxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnQ3VzdG9tQ29udHJvbCgpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgICAgICAgaW5pdE11dGF0aW9uT2JzZXJ2ZXJGb3JUZXN0aW5nKClcbiAgICAgICAgICAgIGxldCBtb2NrcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpO1xuICAgICAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gaHRtbDE7XG4gICAgICAgIH0pXG5cbiAgICAgICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgICAgICAgIGxldCBtb2NrcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpO1xuICAgICAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gXCJcIjtcbiAgICAgICAgICAgIGNsZWFudXBET01Gcm9tVGVzdGluZygpO1xuXG4gICAgICAgIH0pXG5cbiAgICAgICAgZGVzY3JpYmUoJ2NyZWF0ZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGN1c3RvbS1lbGVtZW50IG9iamVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgZCA9IG5ldyBUZXN0Q29tcG9uZW50KCk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QoZSkudG8uYmUubm90Lm51bGw7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZXhwZWN0KHR5cGVvZiBkKS5pcy5lcXVhbCgndW5kZWZpbmVkJyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZGVzY3JpYmUoJ2Nvbm5lY3QgZW1wdHkgZWxlbWVudCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGl0KCdkb2N1bWVudCBzaG91bGQgY29udGFpbiBtb25zdGVyLWN1c3RvbWNvbnRyb2wnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ21vbnN0ZXItY3VzdG9tY29udHJvbCcpO1xuICAgICAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0ZXN0MScpLmFwcGVuZENoaWxkKGQpO1xuICAgICAgICAgICAgICAgIGV4cGVjdChkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnbW9uc3Rlci1jdXN0b21jb250cm9sJykubGVuZ3RoKS5pcy5lcXVhbCgxKTtcbiAgICAgICAgICAgICAgICAvLyBubyBkYXRhLW1vbnN0ZXItb2JqZWN0bGluaz1cIlN5bWJvbChtb25zdGVyVXBkYXRlcilcIiBiZWNhdXNlIGl0IGhhcyBub3RoaW5nIHRvIHVwZGF0ZSBcbiAgICAgICAgICAgICAgICBleHBlY3QoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Rlc3QxJykpLmNvbnRhaW4uaHRtbCgnPG1vbnN0ZXItY3VzdG9tY29udHJvbCBkYXRhLW1vbnN0ZXItZXJyb3I9XCJFcnJvcjogaHRtbCBpcyBub3Qgc2V0LlwiPjwvbW9uc3Rlci1jdXN0b21jb250cm9sPicpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gZGVzY3JpYmUoJ09wdGlvbnMgY2hhbmdlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAvL1xuICAgICAgICAvLyAgICAgaXQoJ2RlbGVnYXRlc0ZvY3VzIHNob3VsZCBjaGFuZ2UgZnJvbSB0cnVlIHRvIGZhbHNlJywgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgLy8gICAgICAgICBsZXQgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ21vbnN0ZXItY3VzdG9tY29udHJvbCcpXG4gICAgICAgIC8vXG4gICAgICAgIC8vICAgICAgICAgZXhwZWN0KGVsZW1lbnQuZ2V0T3B0aW9uKCdkZWxlZ2F0ZXNGb2N1cycpKS50by5iZS50cnVlO1xuICAgICAgICAvLyAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAvLyAgICAgICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShBVFRSSUJVVEVfT1BUSU9OUywgSlNPTi5zdHJpbmdpZnkoe2RlbGVnYXRlc0ZvY3VzOiBmYWxzZX0pKTtcbiAgICAgICAgLy8gICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIC8vICAgICAgICAgICAgICAgICBleHBlY3QoZWxlbWVudC5nZXRPcHRpb24oJ2RlbGVnYXRlc0ZvY3VzJykpLnRvLmJlLmZhbHNlO1xuICAgICAgICAvLyAgICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAvLyAgICAgICAgICAgICB9LCAxMCk7XG4gICAgICAgIC8vICAgICAgICAgfSwgMTApO1xuICAgICAgICAvL1xuICAgICAgICAvL1xuICAgICAgICAvLyAgICAgfSkudGltZW91dCgxMDApO1xuICAgICAgICAvL1xuICAgICAgICAvLyB9KVxuXG4gICAgICAgIGRlc2NyaWJlKCdUZXN0IEVsZW1lbnRJbnRlcm5hbHMnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIGxldCBmb3JtO1xuXG4gICAgICAgICAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAgICAgICAgICBmb3JtID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZm9ybScpO1xuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgaXQoJ2Zvcm1Bc3NvY2lhdGVkJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICAgICAgbGV0IGQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdtb25zdGVyLWN1c3RvbWNvbnRyb2wnKTtcbiAgICAgICAgICAgICAgICBmb3JtLmFwcGVuZENoaWxkKGQpO1xuXG4gICAgICAgICAgICAgICAgZXhwZWN0KGQuY29uc3RydWN0b3IuZm9ybUFzc29jaWF0ZWQpLnRvLmJlLnRydWU7XG5cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpdCgnZm9ybScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgIGxldCBkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbW9uc3Rlci1jdXN0b21jb250cm9sJyk7XG4gICAgICAgICAgICAgICAgZm9ybS5hcHBlbmRDaGlsZChkKTtcblxuICAgICAgICAgICAgICAgIGV4cGVjdChkLmZvcm0pLnRvLmJlLmluc3RhbmNlb2YoSFRNTEZvcm1FbGVtZW50KVxuXG4gICAgICAgICAgICAgICAgLy8gaWYgKGpzZG9tRmxhZykge1xuICAgICAgICAgICAgICAgIC8vICAgICBleHBlY3QoKCkgPT4gZC5mb3JtKS50by50aHJvdyhFcnJvcik7XG4gICAgICAgICAgICAgICAgLy8gfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyAgICAgZXhwZWN0KGQuZm9ybSkudG8uYmUuaW5zdGFuY2VvZihIVE1MRm9ybUVsZW1lbnQpXG4gICAgICAgICAgICAgICAgLy8gfVxuXG5cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpdCgndmFsdWUgZ2V0dGVyJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICAgICAgbGV0IGQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdtb25zdGVyLWN1c3RvbWNvbnRyb2wnKTtcbiAgICAgICAgICAgICAgICBmb3JtLmFwcGVuZENoaWxkKGQpO1xuXG4gICAgICAgICAgICAgICAgZXhwZWN0KCgpID0+IGQudmFsdWUpLnRvLnRocm93KEVycm9yKTtcblxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGl0KCd2YWx1ZSBzZXR0ZXInLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ21vbnN0ZXItY3VzdG9tY29udHJvbCcpO1xuICAgICAgICAgICAgICAgIGZvcm0uYXBwZW5kQ2hpbGQoZCk7XG5cbiAgICAgICAgICAgICAgICBleHBlY3QoKCkgPT4gZC52YWx1ZSA9IDQpLnRvLnRocm93KEVycm9yKTtcblxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGl0KCdzZXRGb3JtVmFsdWUnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ21vbnN0ZXItY3VzdG9tY29udHJvbCcpO1xuICAgICAgICAgICAgICAgIGZvcm0uYXBwZW5kQ2hpbGQoZCk7XG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaXQoJ25hbWUgZ2V0dGVyJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICAgICAgbGV0IGQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdtb25zdGVyLWN1c3RvbWNvbnRyb2wnKTtcbiAgICAgICAgICAgICAgICBmb3JtLmFwcGVuZENoaWxkKGQpO1xuXG4gICAgICAgICAgICAgICAgZXhwZWN0KGQubmFtZSkudG8uYmUubnVsbDtcblxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGl0KCd0eXBlIGdldHRlcicsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgIGxldCBkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbW9uc3Rlci1jdXN0b21jb250cm9sJyk7XG4gICAgICAgICAgICAgICAgZm9ybS5hcHBlbmRDaGlsZChkKTtcblxuICAgICAgICAgICAgICAgIGV4cGVjdChkLnR5cGUpLnRvLmJlLmVxdWFsKCdtb25zdGVyLWN1c3RvbWNvbnRyb2wnKTtcblxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGl0KCd2YWxpZGl0eSBnZXR0ZXInLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ21vbnN0ZXItY3VzdG9tY29udHJvbCcpO1xuICAgICAgICAgICAgICAgIGZvcm0uYXBwZW5kQ2hpbGQoZCk7XG5cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpdCgndmFsaWRhdGlvbk1lc3NhZ2UgZ2V0dGVyJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICAgICAgbGV0IGQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdtb25zdGVyLWN1c3RvbWNvbnRyb2wnKTtcbiAgICAgICAgICAgICAgICBmb3JtLmFwcGVuZENoaWxkKGQpO1xuXG5cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpdCgnd2lsbFZhbGlkYXRlIGdldHRlcicsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgIGxldCBkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbW9uc3Rlci1jdXN0b21jb250cm9sJyk7XG4gICAgICAgICAgICAgICAgZm9ybS5hcHBlbmRDaGlsZChkKTtcblxuXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGl0KCdjaGVja1ZhbGlkaXR5KCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ21vbnN0ZXItY3VzdG9tY29udHJvbCcpO1xuICAgICAgICAgICAgICAgIGZvcm0uYXBwZW5kQ2hpbGQoZCk7XG5cblxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGl0KCdyZXBvcnRWYWxpZGl0eSgpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICAgICAgbGV0IGQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdtb25zdGVyLWN1c3RvbWNvbnRyb2wnKTtcbiAgICAgICAgICAgICAgICBmb3JtLmFwcGVuZENoaWxkKGQpO1xuXG5cbiAgICAgICAgICAgIH0pO1xuXG5cbiAgICAgICAgICAgIGl0KCdzZXRWYWxpZGl0eSgpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICAgICAgbGV0IGQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdtb25zdGVyLWN1c3RvbWNvbnRyb2wnKTtcbiAgICAgICAgICAgICAgICBmb3JtLmFwcGVuZENoaWxkKGQpO1xuICAgICAgICAgICAgICAgIGV4cGVjdChkLnNldFZhbGlkaXR5KHsndmFsdWVNaXNzaW5nJzogdHJ1ZX0sIFwibXkgbWVzc2FnZVwiKSkudG8uYmUudW5kZWZpbmVkO1xuXG4gICAgICAgICAgICB9KTtcblxuXG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG59KTtcblxuXG4iLCAiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuaW1wb3J0IHtBVFRSSUJVVEVfVEhFTUVfTkFNRX0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS9kb20vY29uc3RhbnRzLm1qc1wiO1xuXG5pbXBvcnQge2ZpbmREb2N1bWVudFRlbXBsYXRlLCBUZW1wbGF0ZX0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS9kb20vdGVtcGxhdGUubWpzXCI7XG5pbXBvcnQge2luaXRKU0RPTX0gZnJvbSBcIi4uLy4uL3V0aWwvanNkb20ubWpzXCI7XG5cblxuZGVzY3JpYmUoJ1RlbXBsYXRlJywgZnVuY3Rpb24gKCkge1xuXG4gICAgYmVmb3JlKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaW5pdEpTRE9NKCk7XG4gICAgfSlcblxuICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgICBsZXQgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gYFxuICAgICAgICAgICAgPHRlbXBsYXRlIGlkPVwibXl0ZW1wbGF0ZVwiPjwvdGVtcGxhdGU+YDtcbiAgICB9KVxuXG4gICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgICAgbGV0IG1vY2tzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vY2tzJyk7XG4gICAgICAgIG1vY2tzLmlubmVySFRNTCA9IFwiXCI7XG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCdjcmVhdGUgSFRNTEZyYWdtZW50JywgZnVuY3Rpb24gKCkge1xuICAgICAgICBbXG4gICAgICAgICAgICBbXCI8ZGl2PmZpcnN0PC9kaXY+PGRpdj5zZWNvbmQ8L2Rpdj5cIl0sXG4gICAgICAgICAgICBbXCI8ZGl2PmZpcnN0PC9kaXY+XCJdLFxuICAgICAgICAgICAgW1wiPGRpdj5maXJzdDwvZGl2PjxwPnNlY29uZDwvcD5cIl1cblxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ25ldyBUZW1wbGF0ZSgpLmdldE5ld0RvY3VtZW50RnJhZ21lbnRBc1N0cmluZygpIHNob3VsZCByZXR1cm4gc3RyaW5nJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGxldCB0ZW1wbGF0ZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RlbXBsYXRlJyk7XG4gICAgICAgICAgICAgICAgdGVtcGxhdGUuaW5uZXJIVE1MID0gYTtcbiAgICAgICAgICAgICAgICBsZXQgdCA9IG5ldyBUZW1wbGF0ZSh0ZW1wbGF0ZSk7XG5cblxuICAgICAgICAgICAgICAgIHZhciBjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgICAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQodC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCkpO1xuICAgICAgICAgICAgICAgIGV4cGVjdChjb250YWluZXIuaW5uZXJIVE1MKS50by5iZS5lcXVhbChhKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdjcmVhdGUgaW5zdGFuY2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCduZXcgVGVtcGxhdGUoKSBzaG91bGQgcmV0dXJuIGRvY3VtZW50IG9iamVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBkID0gbmV3IFRlbXBsYXRlKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RlbXBsYXRlJykpO1xuICAgICAgICAgICAgZXhwZWN0KGQpLnRvLmJlLmluc3RhbmNlT2YoVGVtcGxhdGUpO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCcuZ2V0VGVtcGxhdGVFbGVtZW50KCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCduZXcgVGVtcGxhdGUoKS5nZXRUZW1wbGF0ZUVsZW1lbnQoKSBzaG91bGQgcmV0dXJuIEhUTUxUZW1wbGF0ZUVsZW1lbnQgb2JqZWN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGV0IGQgPSBuZXcgVGVtcGxhdGUoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndGVtcGxhdGUnKSk7XG4gICAgICAgICAgICBleHBlY3QoZC5nZXRUZW1wbGF0ZUVsZW1lbnQoKSkudG8uYmUuaW5zdGFuY2VPZihIVE1MVGVtcGxhdGVFbGVtZW50KTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnLmZpbmREb2N1bWVudFRlbXBsYXRlKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgdGhyb3cgVGVtcGxhdGUgbm90IGZvdW5kJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY29uc3QgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBleHBlY3QoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGZpbmREb2N1bWVudFRlbXBsYXRlKFwibm93YXlcIiwgZGl2KVxuICAgICAgICAgICAgfSkudG8udGhyb3dzKEVycm9yKTtcbiAgICAgICAgfSlcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCcuZmluZERvY3VtZW50VGVtcGxhdGUoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZGVzY3JpYmUoJ1RlbXBsYXRlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaXQoJ3Nob3VsZCBmaW5kIHRlbXBsYXRlIG92ZXIgb3duZXJEb2N1bWVudCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgICAgICBkaXYucmVtb3ZlKCk7XG4gICAgICAgICAgICAgICAgbGV0IHQgPSBmaW5kRG9jdW1lbnRUZW1wbGF0ZShcIm15dGVtcGxhdGVcIiwgZGl2KTtcbiAgICAgICAgICAgICAgICBleHBlY3QodCkuaXMuaW5zdGFuY2VvZihUZW1wbGF0ZSk7XG5cbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGRlc2NyaWJlKCdUaG1lbmVkIFRlbXBsYXRlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGV0IG1lbUF0dHJpYnV0ZVZhbHVlO1xuXG4gICAgICAgICAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgICAgICAgICBtb2Nrcy5pbm5lckhUTUwgPSBgXG4gICAgICAgICAgICAgICAgICAgIDx0ZW1wbGF0ZSBpZD1cIm15dGVtcGxhdGVcIj48cD4xPC9wPjwvdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgIDx0ZW1wbGF0ZSBpZD1cIm15dGVtcGxhdGUtbW9uc3RlclwiPjxwPjI8L3A+PC90ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgPHRlbXBsYXRlIGlkPVwibXl0ZW1wbGF0ZS10ZXN0dGhlbWVcIj48cD40PC9wPjwvdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgIDx0ZW1wbGF0ZSBpZD1cIm15cHJlZml4LW15dGVtcGxhdGUtbW9uc3RlclwiPjxwPjM8L3A+PC90ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICBgO1xuXG4gICAgICAgICAgICAgICAgbGV0IGh0bWwgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdodG1sJyk7XG4gICAgICAgICAgICAgICAgaWYgKGh0bWwuaGFzQXR0cmlidXRlKEFUVFJJQlVURV9USEVNRV9OQU1FKSkge1xuICAgICAgICAgICAgICAgICAgICBtZW1BdHRyaWJ1dGVWYWx1ZSA9IGh0bWwuZ2V0QXR0cmlidXRlKEFUVFJJQlVURV9USEVNRV9OQU1FKVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgICAgICAgICBtb2Nrcy5pbm5lckhUTUwgPSBcIlwiO1xuXG4gICAgICAgICAgICAgICAgbGV0IGh0bWwgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdodG1sJyk7XG5cbiAgICAgICAgICAgICAgICBpZiAoaHRtbC5oYXNBdHRyaWJ1dGUoQVRUUklCVVRFX1RIRU1FX05BTUUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGh0bWwucmVtb3ZlQXR0cmlidXRlKEFUVFJJQlVURV9USEVNRV9OQU1FKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAobWVtQXR0cmlidXRlVmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgaHRtbC5zZXRBdHRyaWJ1dGUoQVRUUklCVVRFX1RIRU1FX05BTUUsIG1lbUF0dHJpYnV0ZVZhbHVlKVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgfSlcblxuXG4gICAgICAgICAgICBpdCgnc2hvdWxkIGZpbmQgdGVtcGxhdGUgb3ZlciBvd25lckRvY3VtZW50JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGxldCBodG1sID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignaHRtbCcpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgICAgIGRpdi5zZXRBdHRyaWJ1dGUoJ2RhdGEtbW9uc3Rlci10ZW1wbGF0ZS1wcmVmaXgnLCAnbXlwcmVmaXgnKVxuICAgICAgICAgICAgICAgIGRpdi5yZW1vdmUoKTtcbiAgICAgICAgICAgICAgICBsZXQgdDEgPSBmaW5kRG9jdW1lbnRUZW1wbGF0ZShcIm15dGVtcGxhdGVcIiwgZGl2KTtcbiAgICAgICAgICAgICAgICBleHBlY3QodDEpLmlzLmluc3RhbmNlb2YoVGVtcGxhdGUpO1xuICAgICAgICAgICAgICAgIGV4cGVjdCh0MS5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCkudGV4dENvbnRlbnQpLmlzLmVxdWFsKFwiM1wiKTtcblxuICAgICAgICAgICAgICAgIGRpdi5yZW1vdmVBdHRyaWJ1dGUoJ2RhdGEtbW9uc3Rlci10ZW1wbGF0ZS1wcmVmaXgnKVxuICAgICAgICAgICAgICAgIGxldCB0MiA9IGZpbmREb2N1bWVudFRlbXBsYXRlKFwibXl0ZW1wbGF0ZVwiLCBkaXYpO1xuICAgICAgICAgICAgICAgIGV4cGVjdCh0MikuaXMuaW5zdGFuY2VvZihUZW1wbGF0ZSk7XG4gICAgICAgICAgICAgICAgZXhwZWN0KHQyLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKS50ZXh0Q29udGVudCkuaXMuZXF1YWwoXCIyXCIpO1xuXG4gICAgICAgICAgICAgICAgaHRtbC5zZXRBdHRyaWJ1dGUoQVRUUklCVVRFX1RIRU1FX05BTUUsJ3Rlc3R0aGVtZScpO1xuICAgICAgICAgICAgICAgIGxldCBhPSBodG1sLm91dGVySFRNTDtcbiAgICAgICAgICAgICAgICBsZXQgdDMgPSBmaW5kRG9jdW1lbnRUZW1wbGF0ZShcIm15dGVtcGxhdGVcIiwgZGl2KTtcbiAgICAgICAgICAgICAgICBleHBlY3QodDMpLmlzLmluc3RhbmNlb2YoVGVtcGxhdGUpO1xuICAgICAgICAgICAgICAgIGV4cGVjdCh0My5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCkudGV4dENvbnRlbnQpLmlzLmVxdWFsKFwiNFwiKTtcblxuXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KTtcblxuXG4gICAgfSk7XG59KTsiLCAiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuXG5pbXBvcnQge2ZpcmVFdmVudCwgZmluZFRhcmdldEVsZW1lbnRGcm9tRXZlbnQsIGZpcmVDdXN0b21FdmVudH0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS9kb20vZXZlbnRzLm1qc1wiO1xuaW1wb3J0IHtpbml0SlNET019IGZyb20gXCIuLi8uLi91dGlsL2pzZG9tLm1qc1wiO1xuXG5kZXNjcmliZSgnRXZlbnRzJywgZnVuY3Rpb24gKCkge1xuXG4gICAgYmVmb3JlKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYXdhaXQgaW5pdEpTRE9NKCk7XG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCdmaW5kVGFyZ2V0RWxlbWVudEZyb21FdmVudCgpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdmaW5kIG9iamVjdCcsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICBsZXQgY29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBjb250YWluZXIuc2V0QXR0cmlidXRlKCdkYXRhLW1vbnN0ZXInLCAnaGVsbG8nKTtcbiAgICAgICAgICAgIGxldCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZChkaXYpO1xuICAgICAgICAgICAgZGl2LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgbGV0IGUgPSBmaW5kVGFyZ2V0RWxlbWVudEZyb21FdmVudChldmVudCwgJ2RhdGEtbW9uc3RlcicpO1xuICAgICAgICAgICAgICAgIGV4cGVjdChlLmdldEF0dHJpYnV0ZSgnZGF0YS1tb25zdGVyJykpLnRvLmJlLmVxdWFsKCdoZWxsbycpXG4gICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGZpcmVFdmVudChkaXYsICdjbGljaycpO1xuICAgICAgICAgICAgfSwgMClcblxuICAgICAgICB9KTtcblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2ZpcmVFdmVudCgpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIGZpcmUgYSBjbGljayBldmVudCcsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICBsZXQgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBkaXYuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIGZpcmVFdmVudChkaXYsICdjbGljaycpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIGZpcmUgYSB0b3VjaCBldmVudCcsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICBsZXQgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBkaXYuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2gnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIGZpcmVFdmVudChkaXYsICd0b3VjaCcpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIGZpcmUgYSB0b3VjaCBldmVudCBvbiBjb2xsZWN0aW9uJywgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgICAgIGxldCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIGRpdi5hZGRFdmVudExpc3RlbmVyKCd0b3VjaCcsICgpID0+IHtcbiAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICBkaXYuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JykpO1xuICAgICAgICAgICAgbGV0IGNvbGxlY3Rpb24gPSBkaXYucXVlcnlTZWxlY3RvckFsbCgnZGl2Jyk7XG5cblxuICAgICAgICAgICAgZmlyZUV2ZW50KGNvbGxlY3Rpb24sICd0b3VjaCcpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIGZpcmUgYSB0b3VjaCBldmVudCcsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICBsZXQgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBkaXYuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2gnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgZGl2LmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpKTtcbiAgICAgICAgICAgIGxldCBjb2xsZWN0aW9uID0gZGl2LnF1ZXJ5U2VsZWN0b3JBbGwoJ2RpdicpO1xuXG5cbiAgICAgICAgICAgIGZpcmVFdmVudChjb2xsZWN0aW9uLCAndG91Y2gnKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdCgoKSA9PiBmaXJlRXZlbnQoe30sICd0b3VjaCcpKS50by50aHJvdyhFcnJvcik7XG5cbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnZmlyZUN1c3RvbUV2ZW50KCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgZmlyZSBhIGNsaWNrIGV2ZW50JywgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgICAgIGxldCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIGRpdi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgZmlyZUN1c3RvbUV2ZW50KGRpdiwgJ2NsaWNrJyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgZmlyZSBhIHRvdWNoIGV2ZW50JywgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgICAgIGxldCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIGRpdi5hZGRFdmVudExpc3RlbmVyKCd0b3VjaCcsICgpID0+IHtcbiAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgZmlyZUN1c3RvbUV2ZW50KGRpdiwgJ3RvdWNoJyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgZmlyZSBhIHRvdWNoIGV2ZW50IG9uIGNvbGxlY3Rpb24xJywgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgICAgIGxldCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIGRpdi5hZGRFdmVudExpc3RlbmVyKCd0b3VjaCcsIChlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGUuZGV0YWlsLmRldGFpbCAhPT0gJ2hlbGxvIHdvcmxkJykge1xuICAgICAgICAgICAgICAgICAgICBkb25lKCdlcnJvcicpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICBkaXYuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JykpO1xuICAgICAgICAgICAgbGV0IGNvbGxlY3Rpb24gPSBkaXYucXVlcnlTZWxlY3RvckFsbCgnZGl2Jyk7XG5cbiAgICAgICAgICAgIGZpcmVDdXN0b21FdmVudChjb2xsZWN0aW9uLCAndG91Y2gnLCBcImhlbGxvIHdvcmxkXCIpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIGZpcmUgYSB0b3VjaCBldmVudCBvbiBjb2xsZWN0aW9uMicsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICBsZXQgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBkaXYuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2gnLCAoZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChlLmRldGFpbC5hICE9PSAnaGVsbG8gd29ybGQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGRvbmUoJ2Vycm9yJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGRpdi5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKSk7XG4gICAgICAgICAgICBsZXQgY29sbGVjdGlvbiA9IGRpdi5xdWVyeVNlbGVjdG9yQWxsKCdkaXYnKTtcblxuICAgICAgICAgICAgZmlyZUN1c3RvbUV2ZW50KGNvbGxlY3Rpb24sICd0b3VjaCcsIHthOiBcImhlbGxvIHdvcmxkXCJ9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBmaXJlIGEgdG91Y2ggZXZlbnQnLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICAgICAgbGV0IGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgZGl2LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGRpdi5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKSk7XG4gICAgICAgICAgICBsZXQgY29sbGVjdGlvbiA9IGRpdi5xdWVyeVNlbGVjdG9yQWxsKCdkaXYnKTtcblxuXG4gICAgICAgICAgICBmaXJlQ3VzdG9tRXZlbnQoY29sbGVjdGlvbiwgJ3RvdWNoJyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3InLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QoKCkgPT4gZmlyZUN1c3RvbUV2ZW50KHt9LCAndG91Y2gnKSkudG8udGhyb3coRXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuXG59KTsiLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBpbnN0YW5jZVN5bWJvbCB9IGZyb20gXCIuLi8uLi9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQgeyBpc09iamVjdCB9IGZyb20gXCIuLi8uLi90eXBlcy9pcy5tanNcIjtcbmltcG9ydCB7IERhdGFzb3VyY2UgfSBmcm9tIFwiLi4vZGF0YXNvdXJjZS5tanNcIjtcblxuZXhwb3J0IHsgRG9tU3RvcmFnZSB9O1xuXG4vKipcbiAqIFRoZSBEb21TdG9yYWdlIGlzIGEgY2xhc3MgdGhhdCBzdG9yZXMgZGF0YSBpbiBtZW1vcnkuXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRGF0YS5EYXRhc291cmNlXG4gKi9cbmNsYXNzIERvbVN0b3JhZ2UgZXh0ZW5kcyBEYXRhc291cmNlIHtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIG9wdGlvbnMgY29udGFpbnMgZGVmaW5pdGlvbnMgZm9yIHRoZSBkYXRhc291cmNlLlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgc3VwZXIoKTtcblxuICAgICAgICBpZiAoaXNPYmplY3Qob3B0aW9ucykpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0T3B0aW9ucyhvcHRpb25zKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgYGluc3RhbmNlb2ZgIG9wZXJhdG9yLlxuICAgICAqIEByZXR1cm5zIHtzeW1ib2x9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBbaW5zdGFuY2VTeW1ib2xdKCkge1xuICAgICAgICByZXR1cm4gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvZGF0YS9kYXRhc291cmNlL3N0b3JhZ2UvZG9tLXN0b3JhZ2VcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHByb3BlcnR5IHtPYmplY3R9IGRlZmF1bHRzXG4gICAgICogQHByb3BlcnR5IHtPYmplY3R9IGRlZmF1bHRzLnJlYWRcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gZGVmYXVsdHMucmVhZC5zZWxlY3RvclxuICAgICAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBkZWZhdWx0cy53cml0ZVxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBkZWZhdWx0cy53cml0ZS5zZWxlY3RvclxuICAgICAqL1xuICAgIGdldCBkZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN1cGVyLmRlZmF1bHRzLCB7XG4gICAgICAgICAgICByZWFkOiB7XG4gICAgICAgICAgICAgICAgc2VsZWN0b3I6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB3cml0ZToge1xuICAgICAgICAgICAgICAgIHNlbGVjdG9yOiB1bmRlZmluZWQsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBUaGUgcmVhZCBzZWxlY3RvciBpcyBub3QgZGVmaW5lZFxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBUaGVyZSBhcmUgbm8gc3RvcmFnZSBlbGVtZW50XG4gICAgICovXG4gICAgcmVhZCgpIHtcbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICAgICAgbGV0IHNlbGVjdG9yID0gc2VsZi5nZXRPcHRpb24oXCJyZWFkLnNlbGVjdG9yXCIsIHVuZGVmaW5lZCk7XG4gICAgICAgIGlmICghc2VsZWN0b3IpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZSByZWFkIHNlbGVjdG9yIGlzIG5vdCBkZWZpbmVkXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHN0b3JhZ2UgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKTtcbiAgICAgICAgaWYgKCFzdG9yYWdlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGVyZSBhcmUgbm8gc3RvcmFnZSBlbGVtZW50XCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgbGV0IGRhdGEgPSBKU09OLnBhcnNlKHN0b3JhZ2UuaW5uZXJIVE1MKTtcbiAgICAgICAgICAgICAgICBzZWxmLnNldChkYXRhKTtcbiAgICAgICAgICAgICAgICByZXNvbHZlKGRhdGEpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIHJlamVjdChlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gVGhlIHdyaXRlIHNlbGVjdG9yIGlzIG5vdCBkZWZpbmVkXG4gICAgICogQHRocm93cyB7RXJyb3J9IFRoZXJlIGFyZSBubyBzdG9yYWdlIGVsZW1lbnRcbiAgICAgKi9cbiAgICB3cml0ZSgpIHtcbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICAgICAgbGV0IHNlbGVjdG9yID0gc2VsZi5nZXRPcHRpb24oXCJ3cml0ZS5zZWxlY3RvclwiKTtcbiAgICAgICAgaWYgKCFzZWxlY3Rvcikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhlIHdyaXRlIHNlbGVjdG9yIGlzIG5vdCBkZWZpbmVkXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHN0b3JhZ2UgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKTtcbiAgICAgICAgaWYgKCFzdG9yYWdlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGVyZSBhcmUgbm8gc3RvcmFnZSBlbGVtZW50XCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgc3RvcmFnZS5pbm5lckhUTUwgPSBKU09OLnN0cmluZ2lmeShzZWxmLmdldCgpKTtcbiAgICAgICAgICAgICAgICByZXNvbHZlKHN0b3JhZ2UpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIHJlamVjdChlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxufVxuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgaW50ZXJuYWxTeW1ib2wgfSBmcm9tIFwiLi4vY29uc3RhbnRzLm1qc1wiO1xuaW1wb3J0IHsgaW5zdGFuY2VTeW1ib2wgfSBmcm9tIFwiLi4vY29uc3RhbnRzLm1qc1wiO1xuaW1wb3J0IHsgQmFzZSB9IGZyb20gXCIuLi90eXBlcy9iYXNlLm1qc1wiO1xuaW1wb3J0IHsgcGFyc2VEYXRhVVJMIH0gZnJvbSBcIi4uL3R5cGVzL2RhdGF1cmwubWpzXCI7XG5pbXBvcnQgeyBpc1N0cmluZyB9IGZyb20gXCIuLi90eXBlcy9pcy5tanNcIjtcbmltcG9ydCB7IFByb3h5T2JzZXJ2ZXIgfSBmcm9tIFwiLi4vdHlwZXMvcHJveHlvYnNlcnZlci5tanNcIjtcbmltcG9ydCB7IHZhbGlkYXRlT2JqZWN0IH0gZnJvbSBcIi4uL3R5cGVzL3ZhbGlkYXRlLm1qc1wiO1xuaW1wb3J0IHsgZXh0ZW5kIH0gZnJvbSBcIi4vZXh0ZW5kLm1qc1wiO1xuaW1wb3J0IHsgUGF0aGZpbmRlciB9IGZyb20gXCIuL3BhdGhmaW5kZXIubWpzXCI7XG5cbmV4cG9ydCB7IERhdGFzb3VyY2UgfTtcblxuLyoqXG4gKiBUaGlzIGNhbGxiYWNrIGNhbiBiZSBwYXNzZWQgdG8gYSBkYXRhc291cmNlIGFuZCBpcyB1c2VkIHRvIGFkYXB0IGRhdGEgc3RydWN0dXJlcy5cbiAqXG4gKiBAY2FsbGJhY2sgTW9uc3Rlci5EYXRhLkRhdGFzb3VyY2V+ZXhhbXBsZUNhbGxiYWNrXG4gKiBAcGFyYW0geyp9IHZhbHVlIFZhbHVlXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5ICBLZXlcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRhdGFcbiAqIEBzZWUgTW9uc3Rlci5EYXRhLkRhdGFzb3VyY2VcbiAqL1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAdHlwZSB7c3ltYm9sfVxuICogQG1lbWJlck9mIE1vbnN0ZXIuRGF0YVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNC4wXG4gKi9cbmNvbnN0IGludGVybmFsRGF0YVN5bWJvbCA9IFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL2RhdGEvZGF0YXNvdXJjZS9AQGRhdGFcIik7XG5cbi8qKlxuICogVGhlIGRhdGFzb3VyY2UgY2xhc3MgaXMgdGhlIGJhc2lzIGZvciBkZWFsaW5nIHdpdGggZGlmZmVyZW50IGRhdGEgc291cmNlcy5cbiAqIEl0IHByb3ZpZGVzIGEgdW5pZmllZCBpbnRlcmZhY2UgZm9yIGFjY2Vzc2luZyBkYXRhXG4gKiBAZXh0ZXJuYWxFeGFtcGxlIC4uLy4uL2V4YW1wbGUvZGF0YS9kYXRhc291cmNlLm1qc1xuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yMi4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRGF0YVxuICogQHN1bW1hcnkgVGhlIGRhdGFzb3VyY2UgY2xhc3MgZW5jYXBzdWxhdGVzIHRoZSBhY2Nlc3MgdG8gZGF0YSBvYmplY3RzLlxuICovXG5jbGFzcyBEYXRhc291cmNlIGV4dGVuZHMgQmFzZSB7XG4gICAgLyoqXG4gICAgICogY3JlYXRlcyBhIG5ldyBkYXRhc291cmNlXG4gICAgICpcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoKTtcblxuICAgICAgICB0aGlzW2ludGVybmFsU3ltYm9sXSA9IG5ldyBQcm94eU9ic2VydmVyKHtcbiAgICAgICAgICAgIG9wdGlvbnM6IGV4dGVuZCh7fSwgdGhpcy5kZWZhdWx0cyksXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXNbaW50ZXJuYWxEYXRhU3ltYm9sXSA9IG5ldyBQcm94eU9ic2VydmVyKHt9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBhdHRhY2ggYSBuZXcgb2JzZXJ2ZXJcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7T2JzZXJ2ZXJ9IG9ic2VydmVyXG4gICAgICogQHJldHVybnMge0RhdGFzb3VyY2V9XG4gICAgICovXG4gICAgYXR0YWNoT2JzZXJ2ZXIob2JzZXJ2ZXIpIHtcbiAgICAgICAgdGhpc1tpbnRlcm5hbERhdGFTeW1ib2xdLmF0dGFjaE9ic2VydmVyKG9ic2VydmVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogZGV0YWNoIGEgb2JzZXJ2ZXJcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7T2JzZXJ2ZXJ9IG9ic2VydmVyXG4gICAgICogQHJldHVybnMge0RhdGFzb3VyY2V9XG4gICAgICovXG4gICAgZGV0YWNoT2JzZXJ2ZXIob2JzZXJ2ZXIpIHtcbiAgICAgICAgdGhpc1tpbnRlcm5hbERhdGFTeW1ib2xdLmRldGFjaE9ic2VydmVyKG9ic2VydmVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtPYnNlcnZlcn0gb2JzZXJ2ZXJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBjb250YWluc09ic2VydmVyKG9ic2VydmVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzW2ludGVybmFsRGF0YVN5bWJvbF0uY29udGFpbnNPYnNlcnZlcihvYnNlcnZlcik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGVyaXZlZCBjbGFzc2VzIGNhbiBvdmVycmlkZSBhbmQgZXh0ZW5kIHRoaXMgbWV0aG9kIGFzIGZvbGxvd3MuXG4gICAgICpcbiAgICAgKiBgYGBcbiAgICAgKiBnZXQgZGVmYXVsdHMoKSB7XG4gICAgICogICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN1cGVyLmRlZmF1bHRzLCB7XG4gICAgICogICAgICAgIG15VmFsdWU6dHJ1ZVxuICAgICAqICAgIH0pO1xuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBnZXQgZGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgb3B0aW9uXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcGF0aFxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAgICAgKiBAcmV0dXJuIHtEYXRhc291cmNlfVxuICAgICAqL1xuICAgIHNldE9wdGlvbihwYXRoLCB2YWx1ZSkge1xuICAgICAgICBuZXcgUGF0aGZpbmRlcih0aGlzW2ludGVybmFsU3ltYm9sXS5nZXRTdWJqZWN0KClbXCJvcHRpb25zXCJdKS5zZXRWaWEocGF0aCwgdmFsdWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xvYmplY3R9IG9wdGlvbnNcbiAgICAgKiBAcmV0dXJuIHtEYXRhc291cmNlfVxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSB0aGUgb3B0aW9ucyBkb2VzIG5vdCBjb250YWluIGEgdmFsaWQganNvbiBkZWZpbml0aW9uXG4gICAgICovXG4gICAgc2V0T3B0aW9ucyhvcHRpb25zKSB7XG4gICAgICAgIGlmIChpc1N0cmluZyhvcHRpb25zKSkge1xuICAgICAgICAgICAgb3B0aW9ucyA9IHBhcnNlT3B0aW9uc0pTT04ob3B0aW9ucyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICAgICAgZXh0ZW5kKHNlbGZbaW50ZXJuYWxTeW1ib2xdLmdldFN1YmplY3QoKVtcIm9wdGlvbnNcIl0sIHNlbGYuZGVmYXVsdHMsIG9wdGlvbnMpO1xuXG4gICAgICAgIHJldHVybiBzZWxmO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIG5lc3RlZCBvcHRpb25zIGNhbiBiZSBzcGVjaWZpZWQgYnkgcGF0aCBgYS5iLmNgXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcGF0aFxuICAgICAqIEBwYXJhbSB7Kn0gZGVmYXVsdFZhbHVlXG4gICAgICogQHJldHVybiB7Kn1cbiAgICAgKi9cbiAgICBnZXRPcHRpb24ocGF0aCwgZGVmYXVsdFZhbHVlKSB7XG4gICAgICAgIGxldCB2YWx1ZTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdmFsdWUgPSBuZXcgUGF0aGZpbmRlcih0aGlzW2ludGVybmFsU3ltYm9sXS5nZXRSZWFsU3ViamVjdCgpW1wib3B0aW9uc1wiXSkuZ2V0VmlhKHBhdGgpO1xuICAgICAgICB9IGNhdGNoIChlKSB7fVxuXG4gICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSByZXR1cm4gZGVmYXVsdFZhbHVlO1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHRocm93cyB7RXJyb3J9IHRoaXMgbWV0aG9kIG11c3QgYmUgaW1wbGVtZW50ZWQgYnkgZGVyaXZlZCBjbGFzc2VzLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAgICovXG4gICAgcmVhZCgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidGhpcyBtZXRob2QgbXVzdCBiZSBpbXBsZW1lbnRlZCBieSBkZXJpdmVkIGNsYXNzZXNcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHRocm93cyB7RXJyb3J9IHRoaXMgbWV0aG9kIG11c3QgYmUgaW1wbGVtZW50ZWQgYnkgZGVyaXZlZCBjbGFzc2VzLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAgICovXG4gICAgd3JpdGUoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcInRoaXMgbWV0aG9kIG11c3QgYmUgaW1wbGVtZW50ZWQgYnkgZGVyaXZlZCBjbGFzc2VzXCIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgcmVhbCBvYmplY3RcbiAgICAgKlxuICAgICAqIEByZXR1cm4ge09iamVjdHxBcnJheX1cbiAgICAgKi9cbiAgICBnZXQoKSB7XG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgICAgICByZXR1cm4gc2VsZltpbnRlcm5hbERhdGFTeW1ib2xdLmdldFJlYWxTdWJqZWN0KCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtPYmplY3R8QXJyYXl9IGRhdGFcbiAgICAgKiBAcmV0dXJuIHtEYXRhc291cmNlfVxuICAgICAqL1xuICAgIHNldChkYXRhKSB7XG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgICAgICBzZWxmW2ludGVybmFsRGF0YVN5bWJvbF0uc2V0U3ViamVjdChkYXRhKTtcbiAgICAgICAgcmV0dXJuIHNlbGY7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMi4xLjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci9kYXRhL2RhdGFzb3VyY2VcIik7XG4gICAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0gZGF0YVxuICogQHJldHVybiB7T2JqZWN0fVxuICogQHRocm93cyB7RXJyb3J9IHRoZSBvcHRpb25zIGRvZXMgbm90IGNvbnRhaW4gYSB2YWxpZCBqc29uIGRlZmluaXRpb25cbiAqL1xuZnVuY3Rpb24gcGFyc2VPcHRpb25zSlNPTihkYXRhKSB7XG4gICAgaWYgKGlzU3RyaW5nKGRhdGEpKSB7XG4gICAgICAgIC8vIHRoZSBjb25maWd1cmF0aW9uIGNhbiBiZSBzcGVjaWZpZWQgYXMgYSBkYXRhIHVybC5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGxldCBkYXRhVXJsID0gcGFyc2VEYXRhVVJMKGRhdGEpO1xuICAgICAgICAgICAgZGF0YSA9IGRhdGFVcmwuY29udGVudDtcbiAgICAgICAgfSBjYXRjaCAoZSkge31cblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbGV0IG9iaiA9IEpTT04ucGFyc2UoZGF0YSk7XG4gICAgICAgICAgICB2YWxpZGF0ZU9iamVjdChvYmopO1xuICAgICAgICAgICAgcmV0dXJuIG9iajtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB0aGUgb3B0aW9ucyBkb2VzIG5vdCBjb250YWluIGEgdmFsaWQganNvbiBkZWZpbml0aW9uIChhY3R1YWw6ICR7ZGF0YX0pLmApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHt9O1xufVxuIiwgImltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge0RvbVN0b3JhZ2V9IGZyb20gXCIuLi8uLi8uLi8uLi9zb3VyY2UvZGF0YS9kYXRhc291cmNlL2RvbS5tanNcIjtcblxuXG5kZXNjcmliZSgnU2VydmVEb21yJywgZnVuY3Rpb24gKCkge1xuXG4gICAgaXQoJ3Nob3VsZCBpbml0JywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGNvbnN0IGRvbSA9IG5ldyBEb21TdG9yYWdlKHtcbiAgICAgICAgICAgIFxuICAgICAgICB9KVxuXG4gICAgICAgIGV4cGVjdChkb20pLnRvLmJlLm5vdC5udWxsXG5cblxuICAgIH0pXG5cbn0pO1xuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgaW50ZXJuYWxTeW1ib2wsIGluc3RhbmNlU3ltYm9sIH0gZnJvbSBcIi4uLy4uLy4uL2NvbnN0YW50cy5tanNcIjtcbmltcG9ydCB7IGdldEdsb2JhbE9iamVjdCB9IGZyb20gXCIuLi8uLi8uLi90eXBlcy9nbG9iYWwubWpzXCI7XG5pbXBvcnQgeyBEYXRhc291cmNlIH0gZnJvbSBcIi4uLy4uL2RhdGFzb3VyY2UubWpzXCI7XG5pbXBvcnQgeyBTdG9yYWdlLCBzdG9yYWdlT2JqZWN0U3ltYm9sIH0gZnJvbSBcIi4uL3N0b3JhZ2UubWpzXCI7XG5cbmV4cG9ydCB7IExvY2FsU3RvcmFnZSB9O1xuXG4vKipcbiAqIFRoZSBMb2NhbFN0b3JhZ2UgRGF0YXNvdXJjZSBwcm92aWRlcyBhIGRhdGEgc3RvcmUgaW4gdGhlIGJyb3dzZXIgbG9jYWxTdG9yYWdlLlxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjIuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRhdGEuRGF0YXNvdXJjZS5TdG9yYWdlXG4gKiBAc3VtbWFyeSBUaGUgTG9jYWxTdG9yYWdlIGNsYXNzIGVuY2Fwc3VsYXRlcyB0aGUgYWNjZXNzIHRvIGRhdGEgb2JqZWN0cy5cbiAqL1xuY2xhc3MgTG9jYWxTdG9yYWdlIGV4dGVuZHMgU3RvcmFnZSB7XG4gICAgLyoqXG4gICAgICogQHRocm93cyB7RXJyb3J9IHRoaXMgbWV0aG9kIG11c3QgYmUgaW1wbGVtZW50ZWQgYnkgZGVyaXZlZCBjbGFzc2VzLlxuICAgICAqIEByZXR1cm4ge2V4dGVybmFsOmxvY2FsU3RvcmFnZX1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIFtzdG9yYWdlT2JqZWN0U3ltYm9sXSgpIHtcbiAgICAgICAgcmV0dXJuIGdldEdsb2JhbE9iamVjdChcImxvY2FsU3RvcmFnZVwiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGBpbnN0YW5jZW9mYCBvcGVyYXRvci5cbiAgICAgKiBAcmV0dXJucyB7c3ltYm9sfVxuICAgICAqIEBzaW5jZSAyLjEuMFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgW2luc3RhbmNlU3ltYm9sXSgpIHtcbiAgICAgICAgcmV0dXJuIFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL2RhdGEvZGF0YXNvdXJjZS9zdG9yYWdlL2xvY2Fsc3RvcmFnZVwiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgY2xvbmVcbiAgICAgKiBAcmV0dXJuIHtMb2NhbFN0b3JhZ2V9XG4gICAgICovXG4gICAgZ2V0Q2xvbmUoKSB7XG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgICAgICByZXR1cm4gbmV3IExvY2FsU3RvcmFnZShzZWxmW2ludGVybmFsU3ltYm9sXS5nZXRSZWFsU3ViamVjdCgpW1wib3B0aW9uc1wiXS5rZXkpO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGludGVybmFsU3ltYm9sLCBpbnN0YW5jZVN5bWJvbCB9IGZyb20gXCIuLi8uLi9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQgeyB2YWxpZGF0ZVN0cmluZyB9IGZyb20gXCIuLi8uLi90eXBlcy92YWxpZGF0ZS5tanNcIjtcbmltcG9ydCB7IERhdGFzb3VyY2UgfSBmcm9tIFwiLi4vZGF0YXNvdXJjZS5tanNcIjtcblxuZXhwb3J0IHsgU3RvcmFnZSwgc3RvcmFnZU9iamVjdFN5bWJvbCB9O1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAdHlwZSB7c3ltYm9sfVxuICovXG5jb25zdCBzdG9yYWdlT2JqZWN0U3ltYm9sID0gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvZGF0YS9kYXRhc291cmNlL3N0b3JhZ2UvQEBzdG9yYWdlT2JqZWN0XCIpO1xuXG4vKipcbiAqIFRoZSBjbGFzcyByZXByZXNlbnRzIGEgcmVjb3JkLlxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjIuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRhdGEuRGF0YXNvdXJjZVxuICogQHN1bW1hcnkgVGhlIFN0b3JhZ2UgY2xhc3MgZW5jYXBzdWxhdGVzIHRoZSBhY2Nlc3MgdG8gZGF0YSBvYmplY3RzIG92ZXIgV2ViU3RvcmFnZUFQSS5cbiAqL1xuY2xhc3MgU3RvcmFnZSBleHRlbmRzIERhdGFzb3VyY2Uge1xuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBMb2NhbFN0b3JhZ2UgS2V5XG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSB2YWx1ZSBpcyBub3QgYSBzdHJpbmdcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihrZXkpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5zZXRPcHRpb24oXCJrZXlcIiwgdmFsaWRhdGVTdHJpbmcoa2V5KSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMi4xLjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci9kYXRhL2RhdGFzb3VyY2Uvc3RvcmFnZVwiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30ga2V5PXVuZGVmaW5lZCBMb2NhbFN0b3JhZ2UgS2V5XG4gICAgICovXG4gICAgZ2V0IGRlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3VwZXIuZGVmYXVsdHMsIHtcbiAgICAgICAgICAgIGtleTogdW5kZWZpbmVkLFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gdGhpcyBtZXRob2QgbXVzdCBiZSBpbXBsZW1lbnRlZCBieSBkZXJpdmVkIGNsYXNzZXMuXG4gICAgICogQHJldHVybiB7ZXh0ZXJuYWw6U3RvcmFnZX1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIFtzdG9yYWdlT2JqZWN0U3ltYm9sXSgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidGhpcyBtZXRob2QgbXVzdCBiZSBpbXBsZW1lbnRlZCBieSBkZXJpdmVkIGNsYXNzZXNcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gdGhlIG9wdGlvbnMgZG9lcyBub3QgY29udGFpbiBhIHZhbGlkIGpzb24gZGVmaW5pdGlvblxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgb2JqZWN0XG4gICAgICogQHRocm93cyB7RXJyb3J9IHRoZSBkYXRhIGNhbm5vdCBiZSByZWFkXG4gICAgICovXG4gICAgcmVhZCgpIHtcbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICAgICAgY29uc3Qgc3RvcmFnZSA9IHNlbGZbc3RvcmFnZU9iamVjdFN5bWJvbF0oKTtcblxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICAgICAgICAgIGNvbnN0IGRhdGEgPSBKU09OLnBhcnNlKHN0b3JhZ2UuZ2V0SXRlbShzZWxmLmdldE9wdGlvbihcImtleVwiKSkpO1xuICAgICAgICAgICAgc2VsZi5zZXQoZGF0YSA/PyB7fSk7XG4gICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0b3JhZ2V9XG4gICAgICogQHRocm93cyB7RXJyb3J9IHRoZSBkYXRhIGNhbm5vdCBiZSB3cml0dGVuXG4gICAgICovXG4gICAgd3JpdGUoKSB7XG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgICAgIGNvbnN0IHN0b3JhZ2UgPSBzZWxmW3N0b3JhZ2VPYmplY3RTeW1ib2xdKCk7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlKSB7XG4gICAgICAgICAgICBjb25zdCBkYXRhID0gc2VsZi5nZXQoKTtcbiAgICAgICAgICAgIGlmIChkYXRhID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBzdG9yYWdlLnJlbW92ZUl0ZW0oc2VsZi5nZXRPcHRpb24oXCJrZXlcIikpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzdG9yYWdlLnNldEl0ZW0oc2VsZi5nZXRPcHRpb24oXCJrZXlcIiksIEpTT04uc3RyaW5naWZ5KGRhdGEpKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdG9yYWdlfVxuICAgICAqL1xuICAgIGdldENsb25lKCkge1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICAgICAgcmV0dXJuIG5ldyBTdG9yYWdlKHNlbGZbaW50ZXJuYWxTeW1ib2xdLmdldFJlYWxTdWJqZWN0KClbXCJvcHRpb25zXCJdLmtleSk7XG4gICAgfVxufVxuIiwgImZ1bmN0aW9uIGNyZWF0ZVN0b3JhZ2UoKSB7XG4gICAgbGV0IFVOU0VUID0gU3ltYm9sKCk7XG4gICAgbGV0IHMgPSB7fSxcbiAgICAgICAgbm9vcENhbGxiYWNrID0gKCkgPT4ge1xuICAgICAgICB9LFxuICAgICAgICBfaXRlbUluc2VydGlvbkNhbGxiYWNrID0gbm9vcENhbGxiYWNrO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHMsICdzZXRJdGVtJywge1xuICAgICAgICBnZXQ6ICgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiAoaywgdiA9IFVOU0VUKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHYgPT09IFVOU0VUKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYEZhaWxlZCB0byBleGVjdXRlICdzZXRJdGVtJyBvbiAnU3RvcmFnZSc6IDIgYXJndW1lbnRzIHJlcXVpcmVkLCBidXQgb25seSAxIHByZXNlbnQuYCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGsgPSBrICsgJyc7XG4gICAgICAgICAgICAgICAgaWYgKCFzLmhhc093blByb3BlcnR5KGspKSB7XG4gICAgICAgICAgICAgICAgICAgIF9pdGVtSW5zZXJ0aW9uQ2FsbGJhY2socy5sZW5ndGgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBzW2tdID0gdiArICcnO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShzLCAnZ2V0SXRlbScsIHtcbiAgICAgICAgZ2V0OiAoKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gayA9PiB7XG4gICAgICAgICAgICAgICAgayA9IGsgKyAnJztcbiAgICAgICAgICAgICAgICBpZiAocy5oYXNPd25Qcm9wZXJ0eShrKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc1trXTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHMsICdyZW1vdmVJdGVtJywge1xuICAgICAgICBnZXQ6ICgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBrID0+IHtcbiAgICAgICAgICAgICAgICBrID0gayArICcnO1xuICAgICAgICAgICAgICAgIGlmIChzLmhhc093blByb3BlcnR5KGspKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBzW2tdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocywgJ2NsZWFyJywge1xuICAgICAgICBnZXQ6ICgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgayBpbiBzKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzLmhhc093blByb3BlcnR5KGspKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgc1trXTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocywgJ2xlbmd0aCcsIHtcbiAgICAgICAgZ2V0OiAoKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gT2JqZWN0LmtleXMocykubGVuZ3RoO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHMsIFwia2V5XCIsIHtcbiAgICAgICAgdmFsdWU6IGsgPT4ge1xuICAgICAgICAgICAgbGV0IGtleSA9IE9iamVjdC5rZXlzKHMpW2tdO1xuICAgICAgICAgICAgcmV0dXJuICgha2V5KSA/IG51bGwgOiBrZXk7XG4gICAgICAgIH0sXG4gICAgfSk7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHMsICdpdGVtSW5zZXJ0aW9uQ2FsbGJhY2snLCB7XG4gICAgICAgIGdldDogKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIF9pdGVtSW5zZXJ0aW9uQ2FsbGJhY2s7XG4gICAgICAgIH0sXG4gICAgICAgIHNldDogdiA9PiB7XG4gICAgICAgICAgICBpZiAoIXYgfHwgdHlwZW9mIHYgIT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgIHYgPSBub29wQ2FsbGJhY2s7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBfaXRlbUluc2VydGlvbkNhbGxiYWNrID0gdjtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBzO1xufVxuXG5cbmV4cG9ydCB7Y3JlYXRlU3RvcmFnZX07IiwgIlwidXNlIHN0cmljdFwiO1xuXG5pbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuaW1wb3J0IHtMb2NhbFN0b3JhZ2V9IGZyb20gXCIuLi8uLi8uLi8uLi8uLi9zb3VyY2UvZGF0YS9kYXRhc291cmNlL3N0b3JhZ2UvbG9jYWxzdG9yYWdlLm1qc1wiO1xuaW1wb3J0IHtjcmVhdGVTdG9yYWdlfSBmcm9tIFwiLi4vLi4vLi4vLi4vdXRpbC9sb2NhbHN0b3JhZ2UubWpzXCI7XG5cblxubGV0IGxvY2FsU3RvcmFnZVJlZmVyZW5jZTtcblxuZGVzY3JpYmUoJ0xvY2FsU3RvcmFnZScsIGZ1bmN0aW9uICgpIHtcblxuICAgIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICAgIGdsb2JhbFRoaXNbJ2xvY2FsU3RvcmFnZSddID0gbG9jYWxTdG9yYWdlUmVmZXJlbmNlO1xuICAgIH0pO1xuXG4gICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgbG9jYWxTdG9yYWdlUmVmZXJlbmNlID0gZ2xvYmFsVGhpc1snbG9jYWxTdG9yYWdlJ11cbiAgICAgICAgZ2xvYmFsVGhpc1snbG9jYWxTdG9yYWdlJ10gPSBjcmVhdGVTdG9yYWdlKCk7XG5cbiAgICB9KVxuXG4gICAgaXQoJ3Nob3VsZCBpbnN0YW5jZSBvZiBMb2NhbFN0b3JhZ2UgJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBleHBlY3QobmV3IExvY2FsU3RvcmFnZSgnbXlrZXknKSkudG8uYmUuaW5zdGFuY2VvZihMb2NhbFN0b3JhZ2UpXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgncncnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ3JlYWQgc2hvdWxkIHJldHVybiBvYmplY3QnLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICAgICAgY29uc3QgZHMgPSBuZXcgTG9jYWxTdG9yYWdlKCdteWtleScpXG4gICAgICAgICAgICBkcy5yZWFkKCkudGhlbihkYXRhID0+IHtcbiAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICB9KS5jYXRjaChlID0+IGRvbmUoZSkpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnd3JpdGUgc2hvdWxkICcsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICBjb25zdCBkcyA9IG5ldyBMb2NhbFN0b3JhZ2UoJ215a2V5JylcbiAgICAgICAgICAgIGRzLndyaXRlKCkudGhlbihkYXRhID0+IHtcbiAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICB9KS5jYXRjaChlID0+IGRvbmUoZSkpO1xuICAgICAgICB9KTtcblxuXG4gICAgfSlcblxuXG59KSIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGludGVybmFsU3ltYm9sLCBpbnN0YW5jZVN5bWJvbCB9IGZyb20gXCIuLi8uLi8uLi9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQgeyBnZXRHbG9iYWxPYmplY3QgfSBmcm9tIFwiLi4vLi4vLi4vdHlwZXMvZ2xvYmFsLm1qc1wiO1xuaW1wb3J0IHsgRGF0YXNvdXJjZSB9IGZyb20gXCIuLi8uLi9kYXRhc291cmNlLm1qc1wiO1xuaW1wb3J0IHsgU3RvcmFnZSwgc3RvcmFnZU9iamVjdFN5bWJvbCB9IGZyb20gXCIuLi9zdG9yYWdlLm1qc1wiO1xuXG5leHBvcnQgeyBTZXNzaW9uU3RvcmFnZSB9O1xuXG4vKipcbiAqIFRoZSBTZXNzaW9uU3RvcmFnZSBjbGFzcyBwcm92aWRlcyBhIGRhdGEgc291cmNlIHRoYXQgdXNlcyB0aGUgU2Vzc2lvblN0b3JhZ2UgQVBJIG9uIHRoZSBjbGllbnQuXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yMi4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRGF0YS5EYXRhc291cmNlLlN0b3JhZ2VcbiAqIEBzdW1tYXJ5IFRoZSBMb2NhbFN0b3JhZ2UgY2xhc3MgZW5jYXBzdWxhdGVzIHRoZSBhY2Nlc3MgdG8gZGF0YSBvYmplY3RzLlxuICovXG5jbGFzcyBTZXNzaW9uU3RvcmFnZSBleHRlbmRzIFN0b3JhZ2Uge1xuICAgIC8qKlxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSB0aGlzIG1ldGhvZCBtdXN0IGJlIGltcGxlbWVudGVkIGJ5IGRlcml2ZWQgY2xhc3Nlcy5cbiAgICAgKiBAcmV0dXJuIHtleHRlcm5hbDpzZXNzaW9uU3RvcmFnZX1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIFtzdG9yYWdlT2JqZWN0U3ltYm9sXSgpIHtcbiAgICAgICAgcmV0dXJuIGdldEdsb2JhbE9iamVjdChcInNlc3Npb25TdG9yYWdlXCIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgYGluc3RhbmNlb2ZgIG9wZXJhdG9yLlxuICAgICAqIEByZXR1cm5zIHtzeW1ib2x9XG4gICAgICogQHNpbmNlIDIuMS4wXG4gICAgICovXG4gICAgc3RhdGljIGdldCBbaW5zdGFuY2VTeW1ib2xdKCkge1xuICAgICAgICByZXR1cm4gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvZGF0YS9kYXRhc291cmNlL3N0b3JhZ2Uvc2Vzc2lvbi1zdG9yYWdlXCIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBDbG9uZVxuICAgICAqXG4gICAgICogQHJldHVybiB7U2Vzc2lvblN0b3JhZ2V9XG4gICAgICovXG4gICAgZ2V0Q2xvbmUoKSB7XG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgICAgICByZXR1cm4gbmV3IFNlc3Npb25TdG9yYWdlKHNlbGZbaW50ZXJuYWxTeW1ib2xdLmdldFJlYWxTdWJqZWN0KClbXCJvcHRpb25zXCJdLmtleSk7XG4gICAgfVxufVxuIiwgIlwidXNlIHN0cmljdFwiO1xuXG5pbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuaW1wb3J0IHtTZXNzaW9uU3RvcmFnZX0gZnJvbSBcIi4uLy4uLy4uLy4uLy4uL3NvdXJjZS9kYXRhL2RhdGFzb3VyY2Uvc3RvcmFnZS9zZXNzaW9uc3RvcmFnZS5tanNcIjtcbmltcG9ydCB7Y3JlYXRlU3RvcmFnZX0gZnJvbSBcIi4uLy4uLy4uLy4uL3V0aWwvbG9jYWxzdG9yYWdlLm1qc1wiO1xuXG5cbmxldCBzdG9yYWdlUmVmZXJlbmNlO1xuXG5kZXNjcmliZSgnU2Vzc2lvblN0b3JhZ2UnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBhZnRlckVhY2goKCkgPT4ge1xuICAgICAgICBnbG9iYWxUaGlzWydzZXNzaW9uU3RvcmFnZSddID0gc3RvcmFnZVJlZmVyZW5jZTtcbiAgICB9KTtcblxuICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIHN0b3JhZ2VSZWZlcmVuY2UgPSBnbG9iYWxUaGlzWydzZXNzaW9uU3RvcmFnZSddXG4gICAgICAgIGdsb2JhbFRoaXNbJ3Nlc3Npb25TdG9yYWdlJ10gPSBjcmVhdGVTdG9yYWdlKCk7XG5cbiAgICB9KVxuXG4gICAgaXQoJ3Nob3VsZCBpbnN0YW5jZSBvZiBTZXNzaW9uU3RvcmFnZSAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGV4cGVjdChuZXcgU2Vzc2lvblN0b3JhZ2UoJ215a2V5JykpLnRvLmJlLmluc3RhbmNlb2YoU2Vzc2lvblN0b3JhZ2UpXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgncncnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ3JlYWQgc2hvdWxkIHJldHVybiBvYmplY3QnLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICAgICAgY29uc3QgZHMgPSBuZXcgU2Vzc2lvblN0b3JhZ2UoJ215a2V5JylcbiAgICAgICAgICAgIGRzLnJlYWQoKS50aGVuKGRhdGEgPT4ge1xuICAgICAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICAgIH0pLmNhdGNoKGUgPT4gZG9uZShlKSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCd3cml0ZSBzaG91bGQgJywgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgICAgIGNvbnN0IGRzID0gbmV3IFNlc3Npb25TdG9yYWdlKCdteWtleScpXG4gICAgICAgICAgICBkcy53cml0ZSgpLnRoZW4oZGF0YSA9PiB7XG4gICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgfSkuY2F0Y2goZSA9PiBkb25lKGUpKTtcbiAgICAgICAgfSk7XG5cblxuICAgIH0pXG5cblxufSkiLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBpbnRlcm5hbFN5bWJvbCwgaW5zdGFuY2VTeW1ib2wgfSBmcm9tIFwiLi4vLi4vY29uc3RhbnRzLm1qc1wiO1xuaW1wb3J0IHsgaXNPYmplY3QgfSBmcm9tIFwiLi4vLi4vdHlwZXMvaXMubWpzXCI7XG5pbXBvcnQgeyBEYXRhc291cmNlIH0gZnJvbSBcIi4uL2RhdGFzb3VyY2UubWpzXCI7XG5pbXBvcnQgeyBQYXRoZmluZGVyIH0gZnJvbSBcIi4uL3BhdGhmaW5kZXIubWpzXCI7XG5pbXBvcnQgeyBQaXBlIH0gZnJvbSBcIi4uL3BpcGUubWpzXCI7XG5cbmV4cG9ydCB7IFNlcnZlciB9O1xuXG4vKipcbiAqIEJhc2UgY2xhc3MgZm9yIGFsbCBzZXJ2ZXIgZGF0YXNvdXJjZXNcbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAzLjQuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRhdGEuRGF0YXNvdXJjZVxuICogQHN1bW1hcnkgVGhlIFNlcnZlciBjbGFzcyBlbmNhcHN1bGF0ZXMgdGhlIGFjY2VzcyB0byBhIHNlcnZlciBkYXRhc291cmNlXG4gKi9cbmNsYXNzIFNlcnZlciBleHRlbmRzIERhdGFzb3VyY2Uge1xuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgYGluc3RhbmNlb2ZgIG9wZXJhdG9yLlxuICAgICAqIEByZXR1cm5zIHtzeW1ib2x9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBbaW5zdGFuY2VTeW1ib2xdKCkge1xuICAgICAgICByZXR1cm4gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvZGF0YS9kYXRhc291cmNlL3NlcnZlclwiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIHByZXBhcmVzIHRoZSBkYXRhIHRoYXQgY29tZXMgZnJvbSB0aGUgc2VydmVyLlxuICAgICAqIFNob3VsZCBub3QgYmUgY2FsbGVkIGRpcmVjdGx5LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gcGF5bG9hZFxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9XG4gICAgICovXG4gICAgdHJhbnNmb3JtU2VydmVyUGF5bG9hZChwYXlsb2FkKSB7XG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgICAgICBwYXlsb2FkID0gZG9UcmFuc2Zvcm0uY2FsbChzZWxmLCBcInJlYWRcIiwgcGF5bG9hZCk7XG5cbiAgICAgICAgY29uc3QgZGF0YVBhdGggPSBzZWxmLmdldE9wdGlvbihcInJlYWQucGF0aFwiKTtcbiAgICAgICAgaWYgKGRhdGFQYXRoKSB7XG4gICAgICAgICAgICBwYXlsb2FkID0gbmV3IFBhdGhmaW5kZXIocGF5bG9hZCkuZ2V0VmlhKGRhdGFQYXRoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgcHJlcGFyZXMgdGhlIGRhdGEgZm9yIHdyaXRpbmcgYW5kIHNob3VsZCBub3QgYmUgY2FsbGVkIGRpcmVjdGx5LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gcGF5bG9hZFxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9XG4gICAgICovXG4gICAgcHJlcGFyZVNlcnZlclBheWxvYWQocGF5bG9hZCkge1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgICAgICBwYXlsb2FkID0gZG9UcmFuc2Zvcm0uY2FsbChzZWxmLCBcIndyaXRlXCIsIHBheWxvYWQpO1xuXG4gICAgICAgIGxldCBzaGVhdGhpbmdPYmplY3QgPSBzZWxmLmdldE9wdGlvbihcIndyaXRlLnNoZWF0aGluZy5vYmplY3RcIik7XG4gICAgICAgIGxldCBzaGVhdGhpbmdQYXRoID0gc2VsZi5nZXRPcHRpb24oXCJ3cml0ZS5zaGVhdGhpbmcucGF0aFwiKTtcblxuICAgICAgICBpZiAoc2hlYXRoaW5nT2JqZWN0ICYmIHNoZWF0aGluZ1BhdGgpIHtcbiAgICAgICAgICAgIGNvbnN0IHN1YiA9IHBheWxvYWQ7XG4gICAgICAgICAgICBwYXlsb2FkID0gc2hlYXRoaW5nT2JqZWN0O1xuICAgICAgICAgICAgbmV3IFBhdGhmaW5kZXIocGF5bG9hZCkuc2V0VmlhKHNoZWF0aGluZ1BhdGgsIHN1Yik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSBzZWxmXG4gKiBAcGFyYW0gb2JqXG4gKiBAcmV0dXJucyB7Kn1cbiAqL1xuZnVuY3Rpb24gZG9UcmFuc2Zvcm0odHlwZSwgb2JqKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgbGV0IHRyYW5zZm9ybWF0aW9uID0gc2VsZi5nZXRPcHRpb24oYCR7dHlwZX0ubWFwcGluZy50cmFuc2Zvcm1lcmApO1xuICAgIGlmICh0cmFuc2Zvcm1hdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNvbnN0IHBpcGUgPSBuZXcgUGlwZSh0cmFuc2Zvcm1hdGlvbik7XG4gICAgICAgIGNvbnN0IGNhbGxiYWNrcyA9IHNlbGYuZ2V0T3B0aW9uKGAke3R5cGV9Lm1hcHBpbmcuY2FsbGJhY2tzYCk7XG5cbiAgICAgICAgaWYgKGlzT2JqZWN0KGNhbGxiYWNrcykpIHtcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIGNhbGxiYWNrcykge1xuICAgICAgICAgICAgICAgIGlmIChjYWxsYmFja3MuaGFzT3duUHJvcGVydHkoa2V5KSAmJiB0eXBlb2YgY2FsbGJhY2tzW2tleV0gPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgICAgICAgICBwaXBlLnNldENhbGxiYWNrKGtleSwgY2FsbGJhY2tzW2tleV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIG9iaiA9IHBpcGUucnVuKG9iaik7XG4gICAgfVxuXG4gICAgcmV0dXJuIG9iajtcbn1cbiIsICJpbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuaW1wb3J0IHtTZXJ2ZXJ9IGZyb20gXCIuLi8uLi8uLi8uLi9zb3VyY2UvZGF0YS9kYXRhc291cmNlL3NlcnZlci5tanNcIjtcblxuXG5kZXNjcmliZSgnU2VydmVyJywgZnVuY3Rpb24gKCkge1xuXG4gICAgaXQoJ3Nob3VsZCB0cmFuc2Zvcm0gZGF0YScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBsZXQgd3JpdGVDYWxsYmFja0NhbGxlZCA9IGZhbHNlXG4gICAgICAgIGxldCByZWFkQ2FsbGJhY2tDYWxsZWQgPSBmYWxzZVxuXG4gICAgICAgIGNvbnN0IHNlcnZlciA9IG5ldyBTZXJ2ZXIoe1xuICAgICAgICAgICAgd3JpdGU6IHtcbiAgICAgICAgICAgICAgICBtYXBwaW5nOiB7XG4gICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybWVyOiBcImNhbGw6b25Xcml0ZVwiLFxuICAgICAgICAgICAgICAgICAgICBjYWxsYmFja3M6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uV3JpdGU6IChkYXRhKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVDYWxsYmFja0NhbGxlZCA9IHRydWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBzaGVhdGhpbmc6IHtcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkZW1vOiAxLFxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHh5ejogdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHBhdGg6IFwiZGF0YS54eXpcIixcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlYWQ6IHtcbiAgICAgICAgICAgICAgICBtYXBwaW5nOiB7XG4gICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybWVyOiBcImNhbGw6b25SZWFkXCIsXG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrczoge1xuICAgICAgICAgICAgICAgICAgICAgICAgb25SZWFkOiAoZGF0YSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWRDYWxsYmFja0NhbGxlZCA9IHRydWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBwYXRoOiAnZGF0YS54eXonLFxuICAgICAgICAgICAgfVxuICAgICAgICB9KVxuXG4gICAgICAgIGV4cGVjdChzZXJ2ZXIudHJhbnNmb3JtU2VydmVyUGF5bG9hZCh7ZGVtbzogMSwgZGF0YToge3h5ejogMn19KSkudG8uZGVlcC5lcXVhbCh7ZGVtbzogMSwgZGF0YToge3h5ejogMn19KVxuICAgICAgICBleHBlY3Qoc2VydmVyLnByZXBhcmVTZXJ2ZXJQYXlsb2FkKHtkZW1vOiAxLCBkYXRhOiB7eHl6OiAyfX0pKS50by5kZWVwLmVxdWFsKHtkZW1vOiAxLCBkYXRhOiB7eHl6OiAyfX0pXG5cblxuICAgIH0pXG5cbn0pO1xuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgaW50ZXJuYWxTeW1ib2wsIGluc3RhbmNlU3ltYm9sIH0gZnJvbSBcIi4uLy4uLy4uL2NvbnN0YW50cy5tanNcIjtcbmltcG9ydCB7IGlzU3RyaW5nLCBpc09iamVjdCB9IGZyb20gXCIuLi8uLi8uLi90eXBlcy9pcy5tanNcIjtcbmltcG9ydCB7IFdlYkNvbm5lY3QgYXMgTmV0V2ViQ29ubmVjdCB9IGZyb20gXCIuLi8uLi8uLi9uZXQvd2ViY29ubmVjdC5tanNcIjtcbmltcG9ydCB7IE1lc3NhZ2UgfSBmcm9tIFwiLi4vLi4vLi4vbmV0L3dlYmNvbm5lY3QvbWVzc2FnZS5tanNcIjtcbmltcG9ydCB7IFNlcnZlciB9IGZyb20gXCIuLi9zZXJ2ZXIubWpzXCI7XG5cbmV4cG9ydCB7IFdlYkNvbm5lY3QgfTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHR5cGUge1N5bWJvbH1cbiAqXG4gKiBoaW50OiB0aGlzIG5hbWUgaXMgdXNlZCBpbiB0aGUgdGVzdHMuIGlmIHlvdSB3YW50IHRvIGNoYW5nZSBpdCwgcGxlYXNlIGNoYW5nZSBpdCBpbiB0aGUgdGVzdHMgYXMgd2VsbC5cbiAqL1xuY29uc3Qgd2ViQ29ubmVjdFN5bWJvbCA9IFN5bWJvbChcImNvbm5lY3Rpb25cIik7XG5cbi8qKlxuICogVGhlIFJlc3RBUEkgaXMgYSBjbGFzcyB0aGF0IGVuYWJsZXMgYSBSRVNUIEFQSSBzZXJ2ZXIuXG4gKlxuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi8uLi8uLi9leGFtcGxlL2RhdGEvZGF0YXNvdXJjZS9zZXJ2ZXIvd2ViY29ubmVjdC5tanNcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDMuMS4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRGF0YS5EYXRhc291cmNlLlNlcnZlclxuICogQHN1bW1hcnkgVGhlIExvY2FsU3RvcmFnZSBjbGFzcyBlbmNhcHN1bGF0ZXMgdGhlIGFjY2VzcyB0byBkYXRhIG9iamVjdHMuXG4gKi9cbmNsYXNzIFdlYkNvbm5lY3QgZXh0ZW5kcyBTZXJ2ZXIge1xuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXSBvcHRpb25zIGNvbnRhaW5zIGRlZmluaXRpb25zIGZvciB0aGUgZGF0YXNvdXJjZS5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKCk7XG5cbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICAgICAgaWYgKGlzU3RyaW5nKG9wdGlvbnMpKSB7XG4gICAgICAgICAgICBvcHRpb25zID0geyB1cmw6IG9wdGlvbnMgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghaXNPYmplY3Qob3B0aW9ucykpIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgdGhpcy5zZXRPcHRpb25zKG9wdGlvbnMpO1xuICAgICAgICB0aGlzW3dlYkNvbm5lY3RTeW1ib2xdID0gbmV3IE5ldFdlYkNvbm5lY3Qoe1xuICAgICAgICAgICAgdXJsOiBzZWxmLmdldE9wdGlvbihcInVybFwiKSxcbiAgICAgICAgICAgIGNvbm5lY3Rpb246IHtcbiAgICAgICAgICAgICAgICB0aW1lb3V0OiBzZWxmLmdldE9wdGlvbihcImNvbm5lY3Rpb24udGltZW91dFwiKSxcbiAgICAgICAgICAgICAgICByZWNvbm5lY3Q6IHtcbiAgICAgICAgICAgICAgICAgICAgdGltZW91dDogc2VsZi5nZXRPcHRpb24oXCJjb25uZWN0aW9uLnJlY29ubmVjdC50aW1lb3V0XCIpLFxuICAgICAgICAgICAgICAgICAgICBhdHRlbXB0czogc2VsZi5nZXRPcHRpb24oXCJjb25uZWN0aW9uLnJlY29ubmVjdC5hdHRlbXB0c1wiKSxcbiAgICAgICAgICAgICAgICAgICAgZW5hYmxlZDogc2VsZi5nZXRPcHRpb24oXCJjb25uZWN0aW9uLnJlY29ubmVjdC5lbmFibGVkXCIpLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlfVxuICAgICAqL1xuICAgIGNvbm5lY3QoKSB7XG4gICAgICAgIHJldHVybiB0aGlzW3dlYkNvbm5lY3RTeW1ib2xdLmNvbm5lY3QoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBpc0Nvbm5lY3RlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbd2ViQ29ubmVjdFN5bWJvbF0uaXNDb25uZWN0ZWQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGBpbnN0YW5jZW9mYCBvcGVyYXRvci5cbiAgICAgKiBAcmV0dXJucyB7c3ltYm9sfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgW2luc3RhbmNlU3ltYm9sXSgpIHtcbiAgICAgICAgcmV0dXJuIFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL2RhdGEvZGF0YXNvdXJjZS9zZXJ2ZXIvd2ViY29ubmVjdFwiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gdXJsPXVuZGVmaW5lZCBEZWZpbmVzIHRoZSByZXNvdXJjZSB0aGF0IHlvdSB3aXNoIHRvIGZldGNoLlxuICAgICAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBjb25uZWN0aW9uXG4gICAgICogQHByb3BlcnR5IHtPYmplY3R9IGNvbm5lY3Rpb24udGltZW91dD01MDAwIERlZmluZXMgdGhlIHRpbWVvdXQgZm9yIHRoZSBjb25uZWN0aW9uLlxuICAgICAqIEBwcm9wZXJ0eSB7TnVtYmVyfSBjb25uZWN0aW9uLnJlY29ubmVjdC50aW1lb3V0IFRoZSB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcyBmb3IgdGhlIHJlY29ubmVjdC5cbiAgICAgKiBAcHJvcGVydHkge051bWJlcn0gY29ubmVjdGlvbi5yZWNvbm5lY3QuYXR0ZW1wdHMgVGhlIG1heGltdW0gbnVtYmVyIG9mIHJlY29ubmVjdHMuXG4gICAgICogQHByb3BlcnR5IHtCb29sfSBjb25uZWN0aW9uLnJlY29ubmVjdC5lbmFibGVkIElmIHRoZSByZWNvbm5lY3QgaXMgZW5hYmxlZC5cbiAgICAgKiBAcHJvcGVydHkge09iamVjdH0gd3JpdGU9e30gT3B0aW9uc1xuICAgICAqIEBwcm9wZXJ0eSB7T2JqZWN0fSB3cml0ZS5tYXBwaW5nIHRoZSBtYXBwaW5nIGlzIGFwcGxpZWQgYmVmb3JlIHdyaXRpbmcuXG4gICAgICogQHByb3BlcnR5IHtTdHJpbmd9IHdyaXRlLm1hcHBpbmcudHJhbnNmb3JtZXIgVHJhbnNmb3JtZXIgdG8gc2VsZWN0IHRoZSBhcHByb3ByaWF0ZSBlbnRyaWVzXG4gICAgICogQHByb3BlcnR5IHtNb25zdGVyLkRhdGEuRGF0YXNvdXJjZX5leGFtcGxlQ2FsbGJhY2tbXX0gd3JpdGUubWFwcGluZy5jYWxsYmFjayB3aXRoIHRoZSBoZWxwIG9mIHRoZSBjYWxsYmFjaywgdGhlIHN0cnVjdHVyZXMgY2FuIGJlIGFkanVzdGVkIGJlZm9yZSB3cml0aW5nLlxuICAgICAqIEBwcm9wZXJ0eSB7T2JqZWN0fSB3cml0ZS5zaGVhdGhpbmdcbiAgICAgKiBAcHJvcGVydHkge09iamVjdH0gd3JpdGUuc2hlYXRoaW5nLm9iamVjdCBPYmplY3QgdG8gYmUgd3JhcHBlZFxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB3cml0ZS5zaGVhdGhpbmcucGF0aCBQYXRoIHRvIHRoZSBkYXRhXG4gICAgICogQHByb3BlcnR5IHtPYmplY3R9IHJlYWQ9e30gT3B0aW9uc1xuICAgICAqIEBwcm9wZXJ0eSB7U3RyaW5nfSByZWFkLnBhdGggUGF0aCB0byBkYXRhXG4gICAgICogQHByb3BlcnR5IHtPYmplY3R9IHJlYWQubWFwcGluZyB0aGUgbWFwcGluZyBpcyBhcHBsaWVkIGFmdGVyIHJlYWRpbmcuXG4gICAgICogQHByb3BlcnR5IHtTdHJpbmd9IHJlYWQubWFwcGluZy50cmFuc2Zvcm1lciBUcmFuc2Zvcm1lciB0byBzZWxlY3QgdGhlIGFwcHJvcHJpYXRlIGVudHJpZXNcbiAgICAgKiBAcHJvcGVydHkge01vbnN0ZXIuRGF0YS5EYXRhc291cmNlfmV4YW1wbGVDYWxsYmFja1tdfSByZWFkLm1hcHBpbmcuY2FsbGJhY2sgd2l0aCB0aGUgaGVscCBvZiB0aGUgY2FsbGJhY2ssIHRoZSBzdHJ1Y3R1cmVzIGNhbiBiZSBhZGp1c3RlZCBhZnRlciByZWFkaW5nLlxuICAgICAqL1xuICAgIGdldCBkZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN1cGVyLmRlZmF1bHRzLCB7XG4gICAgICAgICAgICB1cmw6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHdyaXRlOiB7XG4gICAgICAgICAgICAgICAgbWFwcGluZzoge1xuICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm1lcjogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgICAgICBjYWxsYmFja3M6IHt9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgc2hlYXRoaW5nOiB7XG4gICAgICAgICAgICAgICAgICAgIG9iamVjdDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgICAgICBwYXRoOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByZWFkOiB7XG4gICAgICAgICAgICAgICAgbWFwcGluZzoge1xuICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm1lcjogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgICAgICBjYWxsYmFja3M6IHt9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcGF0aDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGNvbm5lY3Rpb246IHtcbiAgICAgICAgICAgICAgICB0aW1lb3V0OiA1MDAwLFxuICAgICAgICAgICAgICAgIHJlY29ubmVjdDoge1xuICAgICAgICAgICAgICAgICAgICB0aW1lb3V0OiAxMDAwLFxuICAgICAgICAgICAgICAgICAgICBhdHRlbXB0czogMSxcbiAgICAgICAgICAgICAgICAgICAgZW5hYmxlZDogZmFsc2UsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGNsb3NlcyB0aGUgY29ubmVjdGlvbi5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlfVxuICAgICAqL1xuICAgIGNsb3NlKCkge1xuICAgICAgICByZXR1cm4gdGhpc1t3ZWJDb25uZWN0U3ltYm9sXS5jbG9zZSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAgICovXG4gICAgcmVhZCgpIHtcbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHdoaWxlICh0aGlzW3dlYkNvbm5lY3RTeW1ib2xdLmRhdGFSZWNlaXZlZCgpID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgbGV0IG9iaiA9IHRoaXNbd2ViQ29ubmVjdFN5bWJvbF0ucG9sbCgpO1xuICAgICAgICAgICAgICAgIGlmICghaXNPYmplY3Qob2JqKSkge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKFwiVGhlIHJlY2VpdmVkIGRhdGEgaXMgbm90IGFuIG9iamVjdC5cIikpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgTWVzc2FnZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihcIlRoZSByZWNlaXZlZCBkYXRhIGlzIG5vdCBhIE1lc3NhZ2UuXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIG9iaiA9IG9iai5nZXREYXRhKCk7XG4gICAgICAgICAgICAgICAgb2JqID0gc2VsZi50cmFuc2Zvcm1TZXJ2ZXJQYXlsb2FkLmNhbGwoc2VsZiwgb2JqKTtcbiAgICAgICAgICAgICAgICBzZWxmLnNldChvYmopO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXNvbHZlKHNlbGYuZ2V0KCkpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgICAqL1xuICAgIHdyaXRlKCkge1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICAgICAgbGV0IG9iaiA9IHNlbGYucHJlcGFyZVNlcnZlclBheWxvYWQoc2VsZi5nZXQoKSk7XG4gICAgICAgIHJldHVybiBzZWxmW3dlYkNvbm5lY3RTeW1ib2xdLnNlbmQob2JqKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtSZXN0QVBJfVxuICAgICAqL1xuICAgIGdldENsb25lKCkge1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICAgICAgcmV0dXJuIG5ldyBXZWJDb25uZWN0KHNlbGZbaW50ZXJuYWxTeW1ib2xdLmdldFJlYWxTdWJqZWN0KClbXCJvcHRpb25zXCJdKTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7V2ViQ29ubmVjdH0gZnJvbSBcIi4uLy4uLy4uLy4uLy4uL3NvdXJjZS9kYXRhL2RhdGFzb3VyY2Uvc2VydmVyL3dlYmNvbm5lY3QubWpzXCI7XG5pbXBvcnQge2luaXRXZWJTb2NrZXR9IGZyb20gXCIuLi8uLi8uLi8uLi91dGlsL3dlYnNvY2tldC5tanNcIjtcblxuY29uc3QgdGVzdFVybCA9IFwid3NzOi8vd3MucG9zdG1hbi1lY2hvLmNvbS9yYXdcIlxuXG4vLyBjb25zdCBnID0gZ2V0R2xvYmFsKCk7XG4vLyBnWydXZWJTb2NrZXQnXSA9IFdTO1xuXG5cbmRlc2NyaWJlKCdXZWJzb2NrZXQnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBsZXQgZHMgPSB1bmRlZmluZWRcblxuICAgIGJlZm9yZShmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICBpbml0V2ViU29ja2V0KCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICBkb25lKClcbiAgICAgICAgfSkuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIGRvbmUoZSlcbiAgICAgICAgfSlcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICBpZiAoZHMpIHtcbiAgICAgICAgICAgIGRzLmNsb3NlKClcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHdvcmthcm91bmQ6IHdpdGhvdXQgdGhpcywgdGhlIG5vZGUgdGVzdCB3aWxsIGhhbmcgXG4gICAgICAgIGZvciAoY29uc3Qgc3ltIG9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMoZHMpKSB7XG4gICAgICAgICAgICBpZiAoc3ltLnRvU3RyaW5nKCkgPT09ICdTeW1ib2woY29ubmVjdGlvbiknKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IGRzW3N5bV1cbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHN5bTIgb2YgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhjb25uZWN0aW9uKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoc3ltMi50b1N0cmluZygpID09PSAnU3ltYm9sKGNvbm5lY3Rpb24pJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc29ja2V0ID0gY29ubmVjdGlvbltzeW0yXT8uc29ja2V0O1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNvY2tldCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygc29ja2V0Py50ZXJtaW5hdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc29ja2V0Py5bJ3Rlcm1pbmF0ZSddKClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBkb25lKClcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2V0IGNsb25lJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGRzID0gbmV3IFdlYkNvbm5lY3QodGVzdFVybClcbiAgICAgICAgY29uc3QgY2xvbmUgPSBkcy5nZXRDbG9uZSgpXG5cbiAgICAgICAgZXhwZWN0KGNsb25lKS50by5iZS5hbi5pbnN0YW5jZW9mKFdlYkNvbm5lY3QpXG5cblxuICAgIH0pXG5cbiAgICBpdCgnc2hvdWxkIHRyYW5zZm9ybSBkYXRhJywgZnVuY3Rpb24gKGRvbmUpIHtcblxuICAgICAgICBsZXQgd3JpdGVDYWxsYmFja0NhbGxlZCA9IGZhbHNlXG4gICAgICAgIGxldCByZWFkQ2FsbGJhY2tDYWxsZWQgPSBmYWxzZVxuXG4gICAgICAgIGRzID0gbmV3IFdlYkNvbm5lY3Qoe1xuICAgICAgICAgICAgdXJsOiB0ZXN0VXJsLFxuICAgICAgICAgICAgd3JpdGU6IHtcbiAgICAgICAgICAgICAgICBtYXBwaW5nOiB7XG4gICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybWVyOiBcImNhbGw6b25Xcml0ZVwiLFxuICAgICAgICAgICAgICAgICAgICBjYWxsYmFja3M6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uV3JpdGU6IChkYXRhKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVDYWxsYmFja0NhbGxlZCA9IHRydWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBzaGVhdGhpbmc6IHtcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkZW1vOiAxLFxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHh5ejogdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHBhdGg6IFwiZGF0YS54eXpcIixcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlYWQ6IHtcbiAgICAgICAgICAgICAgICBtYXBwaW5nOiB7XG4gICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybWVyOiBcImNhbGw6b25SZWFkXCIsXG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrczoge1xuICAgICAgICAgICAgICAgICAgICAgICAgb25SZWFkOiAoZGF0YSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWRDYWxsYmFja0NhbGxlZCA9IHRydWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBwYXRoOiAnZGF0YS54eXonLFxuICAgICAgICAgICAgfVxuICAgICAgICB9KVxuXG4gICAgICAgIGRzLmNvbm5lY3QoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIGRzLnNldCh7XG4gICAgICAgICAgICAgICAgZW52ZWxvcDoge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBcIkhlbGxvIFdvcmxkXCJcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICBkcy53cml0ZSgpLnRoZW4oKCkgPT4ge1xuXG4gICAgICAgICAgICAgICAgZHMuc2V0KHt9KVxuICAgICAgICAgICAgICAgIGV4cGVjdChkcy5nZXQoKSkudG8uYmUuZGVlcC5lcXVhbCh7fSk7XG5cbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcblxuXG4gICAgICAgICAgICAgICAgICAgIGRzLnJlYWQoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdChkcy5nZXQoKSkudG8uYmUuZGVlcC5lcXVhbCh7ZW52ZWxvcDp7bWVzc2FnZTogXCJIZWxsbyBXb3JsZFwifX0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0KHdyaXRlQ2FsbGJhY2tDYWxsZWQpLnRvLmJlLnRydWVcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdChyZWFkQ2FsbGJhY2tDYWxsZWQpLnRvLmJlLnRydWVcbiAgICAgICAgICAgICAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgZG9uZShlKVxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIH0sIDIwMClcblxuICAgICAgICAgICAgfSkuY2F0Y2goKGVycikgPT4ge1xuICAgICAgICAgICAgICAgIGRvbmUobmV3IEVycm9yKGVycikpO1xuICAgICAgICAgICAgfSlcblxuXG4gICAgICAgIH0pLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICBkb25lKGUpXG4gICAgICAgIH0pXG5cblxuICAgIH0pXG5cbiAgICBpdCgnc2hvdWxkIGNvbm5lY3QnLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICBkcyA9IG5ldyBXZWJDb25uZWN0KHtcbiAgICAgICAgICAgIHVybDogdGVzdFVybCxcbiAgICAgICAgICAgIHJlY29ubmVjdDoge1xuICAgICAgICAgICAgICAgIGVuYWJsZWQ6IGZhbHNlXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBkcy5jb25uZWN0KCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICBkb25lKClcbiAgICAgICAgfSkuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIGRvbmUoZSlcbiAgICAgICAgfSlcblxuXG4gICAgfSlcblxuICAgIGl0KCdzaG91bGQgc2VuZCBtZXNzYWdlJywgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgZHMgPSBuZXcgV2ViQ29ubmVjdCh7XG4gICAgICAgICAgICB1cmw6IHRlc3RVcmwsXG4gICAgICAgICAgICByZWNvbm5lY3Q6IHtcbiAgICAgICAgICAgICAgICBlbmFibGVkOiBmYWxzZVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgZHMuY29ubmVjdCgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgZHMuc2V0KHtcbiAgICAgICAgICAgICAgICBlbnZlbG9wOiB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IFwiSGVsbG8gV29ybGRcIlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGRzLndyaXRlKCkudGhlbigoKSA9PiB7XG5cbiAgICAgICAgICAgICAgICBkcy5zZXQoe30pXG4gICAgICAgICAgICAgICAgZXhwZWN0KGRzLmdldCgpKS50by5iZS5kZWVwLmVxdWFsKHt9KTtcblxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuXG4gICAgICAgICAgICAgICAgICAgIGRzLnJlYWQoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KGRzLmdldCgpKS50by5iZS5kZWVwLmVxdWFsKHtlbnZlbG9wOnttZXNzYWdlOiBcIkhlbGxvIFdvcmxkXCJ9fSk7XG4gICAgICAgICAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICAgICAgICAgIH0pLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGRvbmUoZSlcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIH0sNTAwKVxuICAgICAgICAgICAgICAgIFxuXG4gICAgICAgICAgICB9KS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgZG9uZShuZXcgRXJyb3IoZXJyKSk7XG4gICAgICAgICAgICB9KVxuXG5cbiAgICAgICAgfSkuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIGRvbmUoZSlcbiAgICAgICAgfSlcblxuXG4gICAgfSkudGltZW91dCgxMDAwMCk7XG5cbn0pO1xuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgaW50ZXJuYWxTeW1ib2wsIGluc3RhbmNlU3ltYm9sIH0gZnJvbSBcIi4uLy4uLy4uL2NvbnN0YW50cy5tanNcIjtcbmltcG9ydCB7IGlzT2JqZWN0LCBpc0Z1bmN0aW9uIH0gZnJvbSBcIi4uLy4uLy4uL3R5cGVzL2lzLm1qc1wiO1xuaW1wb3J0IHsgU2VydmVyIH0gZnJvbSBcIi4uL3NlcnZlci5tanNcIjtcbmltcG9ydCB7IFdyaXRlRXJyb3IgfSBmcm9tIFwiLi9yZXN0YXBpL3dyaXRlZXJyb3IubWpzXCI7XG5pbXBvcnQgeyBEYXRhRmV0Y2hFcnJvciB9IGZyb20gXCIuL3Jlc3RhcGkvZGF0YS1mZXRjaC1lcnJvci5tanNcIjtcblxuZXhwb3J0IHsgUmVzdEFQSSB9O1xuXG4vKipcbiAqIEB0eXBlIHtzeW1ib2x9XG4gKiBAbWVtYmVyT2YgTW9uc3RlclxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMy4xMi4wXG4gKi9cbmNvbnN0IHJhd0RhdGFTeW1ib2wgPSBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci9kYXRhL2RhdGFzb3VyY2Uvc2VydmVyL3Jlc3RhcGkvcmF3ZGF0YVwiKTtcblxuLyoqXG4gKiBUaGUgUmVzdEFQSSBpcyBhIGNsYXNzIHRoYXQgZW5hYmxlcyBhIFJFU1QgQVBJIHNlcnZlci5cbiAqXG4gKiBAZXh0ZXJuYWxFeGFtcGxlIC4uLy4uLy4uLy4uL2V4YW1wbGUvZGF0YS9kYXRhc291cmNlL3NlcnZlci9yZXN0YXBpLm1qc1xuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yMi4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRGF0YS5EYXRhc291cmNlLlNlcnZlclxuICogQHN1bW1hcnkgVGhlIFJlc3RBUEkgaXMgYSBjbGFzcyB0aGF0IGJpbmRzIGEgUkVTVCBBUEkgc2VydmVyLlxuICovXG5jbGFzcyBSZXN0QVBJIGV4dGVuZHMgU2VydmVyIHtcbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc10gb3B0aW9ucyBjb250YWlucyBkZWZpbml0aW9ucyBmb3IgdGhlIGRhdGFzb3VyY2UuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgICAgICBzdXBlcigpO1xuXG4gICAgICAgIGlmIChpc09iamVjdChvcHRpb25zKSkge1xuICAgICAgICAgICAgdGhpcy5zZXRPcHRpb25zKG9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMi4xLjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci9kYXRhL2RhdGFzb3VyY2Uvc2VydmVyL3Jlc3RhcGlcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHByb3BlcnR5IHtPYmplY3R9IHdyaXRlPXt9IE9wdGlvbnNcbiAgICAgKiBAcHJvcGVydHkge09iamVjdH0gd3JpdGUuaW5pdD17fSBBbiBvcHRpb25zIG9iamVjdCBjb250YWluaW5nIGFueSBjdXN0b20gc2V0dGluZ3MgdGhhdCB5b3Ugd2FudCB0byBhcHBseSB0byB0aGUgcmVxdWVzdC4gVGhlIHBhcmFtZXRlcnMgYXJlIGlkZW50aWNhbCB0byB0aG9zZSBvZiB0aGUge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9SZXF1ZXN0L1JlcXVlc3R8UmVxdWVzdCBjb25zdHJ1Y3Rvcn1cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gd3JpdGUuaW5pdC5tZXRob2Q9UE9TVFxuICAgICAqIEBwcm9wZXJ0eSB7T2JqZWN0fSB3cml0ZS5pbml0LmhlYWRlcnMgT2JqZWN0IGNvbnRhaW5pbmcgYW55IGN1c3RvbSBoZWFkZXJzIHRoYXQgeW91IHdhbnQgdG8gYXBwbHkgdG8gdGhlIHJlcXVlc3QuXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd9IHdyaXRlLnJlc3BvbnNlQ2FsbGJhY2sgQ2FsbGJhY2sgZnVuY3Rpb24gdG8gYmUgZXhlY3V0ZWQgYWZ0ZXIgdGhlIHJlcXVlc3QgaGFzIGJlZW4gY29tcGxldGVkLlxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB3cml0ZS5hY2NlcHRlZFN0YXR1cz1bMjAwLDIwMV1cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gd3JpdGUudXJsIFVSTFxuICAgICAqIEBwcm9wZXJ0eSB7T2JqZWN0fSB3cml0ZS5tYXBwaW5nIHRoZSBtYXBwaW5nIGlzIGFwcGxpZWQgYmVmb3JlIHdyaXRpbmcuXG4gICAgICogQHByb3BlcnR5IHtTdHJpbmd9IHdyaXRlLm1hcHBpbmcudHJhbnNmb3JtZXIgVHJhbnNmb3JtZXIgdG8gc2VsZWN0IHRoZSBhcHByb3ByaWF0ZSBlbnRyaWVzXG4gICAgICogQHByb3BlcnR5IHtNb25zdGVyLkRhdGEuRGF0YXNvdXJjZX5leGFtcGxlQ2FsbGJhY2tbXX0gd3JpdGUubWFwcGluZy5jYWxsYmFjayB3aXRoIHRoZSBoZWxwIG9mIHRoZSBjYWxsYmFjaywgdGhlIHN0cnVjdHVyZXMgY2FuIGJlIGFkanVzdGVkIGJlZm9yZSB3cml0aW5nLlxuICAgICAqIEBwcm9wZXJ0eSB7T2JqZWN0fSB3cml0ZS5yZXBvcnRcbiAgICAgKiBAcHJvcGVydHkge1N0cmluZ30gd3JpdGUucmVwb3J0LnBhdGggUGF0aCB0byB2YWxpZGF0aW9uc1xuICAgICAqIEBwcm9wZXJ0eSB7T2JqZWN0fSB3cml0ZS5zaGVhdGhpbmdcbiAgICAgKiBAcHJvcGVydHkge09iamVjdH0gd3JpdGUuc2hlYXRoaW5nLm9iamVjdCBPYmplY3QgdG8gYmUgd3JhcHBlZFxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB3cml0ZS5zaGVhdGhpbmcucGF0aCBQYXRoIHRvIHRoZSBkYXRhXG4gICAgICogQHByb3BlcnR5IHtPYmplY3R9IHJlYWQ9e30gT3B0aW9uc1xuICAgICAqIEBwcm9wZXJ0eSB7T2JqZWN0fSByZWFkLmluaXQ9e30gQW4gb3B0aW9ucyBvYmplY3QgY29udGFpbmluZyBhbnkgY3VzdG9tIHNldHRpbmdzIHRoYXQgeW91IHdhbnQgdG8gYXBwbHkgdG8gdGhlIHJlcXVlc3QuIFRoZSBwYXJhbWV0ZXJzIGFyZSBpZGVudGljYWwgdG8gdGhvc2Ugb2YgdGhlIHtAbGluayBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvUmVxdWVzdC9SZXF1ZXN0fFJlcXVlc3QgY29uc3RydWN0b3J9XG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd9IHJlYWQuaW5pdC5tZXRob2Q9R0VUXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd9IHJlYWQuYWNjZXB0ZWRTdGF0dXM9WzIwMF1cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gcmVhZC51cmwgVVJMXG4gICAgICogQHByb3BlcnR5IHtPYmplY3R9IHJlYWQubWFwcGluZyB0aGUgbWFwcGluZyBpcyBhcHBsaWVkIGFmdGVyIHJlYWRpbmcuXG4gICAgICogQHByb3BlcnR5IHtTdHJpbmd9IHJlYWQubWFwcGluZy50cmFuc2Zvcm1lciBUcmFuc2Zvcm1lciB0byBzZWxlY3QgdGhlIGFwcHJvcHJpYXRlIGVudHJpZXNcbiAgICAgKiBAcHJvcGVydHkge01vbnN0ZXIuRGF0YS5EYXRhc291cmNlfmV4YW1wbGVDYWxsYmFja1tdfSByZWFkLm1hcHBpbmcuY2FsbGJhY2sgd2l0aCB0aGUgaGVscCBvZiB0aGUgY2FsbGJhY2ssIHRoZSBzdHJ1Y3R1cmVzIGNhbiBiZSBhZGp1c3RlZCBhZnRlciByZWFkaW5nLlxuICAgICAqL1xuICAgIGdldCBkZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN1cGVyLmRlZmF1bHRzLCB7XG4gICAgICAgICAgICB3cml0ZToge1xuICAgICAgICAgICAgICAgIGluaXQ6IHtcbiAgICAgICAgICAgICAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHJlc3BvbnNlQ2FsbGJhY2s6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICBhY2NlcHRlZFN0YXR1czogWzIwMCwgMjAxXSxcbiAgICAgICAgICAgICAgICB1cmw6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICBtYXBwaW5nOiB7XG4gICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybWVyOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrczogW10sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBzaGVhdGhpbmc6IHtcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0OiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgIHBhdGg6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHJlcG9ydDoge1xuICAgICAgICAgICAgICAgICAgICBwYXRoOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByZWFkOiB7XG4gICAgICAgICAgICAgICAgaW5pdDoge1xuICAgICAgICAgICAgICAgICAgICBtZXRob2Q6IFwiR0VUXCIsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICByZXNwb25zZUNhbGxiYWNrOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgYWNjZXB0ZWRTdGF0dXM6IFsyMDBdLFxuICAgICAgICAgICAgICAgIHVybDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgIG1hcHBpbmc6IHtcbiAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtZXI6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tzOiBbXSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gdGhlIG9wdGlvbnMgZG9lcyBub3QgY29udGFpbiBhIHZhbGlkIGpzb24gZGVmaW5pdGlvblxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgb2JqZWN0XG4gICAgICogQHRocm93cyB7RXJyb3J9IHRoZSBkYXRhIGNhbm5vdCBiZSByZWFkXG4gICAgICovXG4gICAgcmVhZCgpIHtcbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICAgICAgbGV0IGluaXQgPSBzZWxmLmdldE9wdGlvbihcInJlYWQuaW5pdFwiKTtcbiAgICAgICAgaWYgKCFpc09iamVjdChpbml0KSkgaW5pdCA9IHt9O1xuICAgICAgICBpZiAoIWluaXRbXCJtZXRob2RcIl0pIGluaXRbXCJtZXRob2RcIl0gPSBcIkdFVFwiO1xuXG4gICAgICAgIGxldCBjYWxsYmFjayA9IHNlbGYuZ2V0T3B0aW9uKFwicmVhZC5yZXNwb25zZUNhbGxiYWNrXCIpO1xuICAgICAgICBpZiAoIWNhbGxiYWNrKVxuICAgICAgICAgICAgY2FsbGJhY2sgPSAob2JqKSA9PiB7XG4gICAgICAgICAgICAgICAgc2VsZi5zZXQoc2VsZi50cmFuc2Zvcm1TZXJ2ZXJQYXlsb2FkLmNhbGwoc2VsZiwgb2JqKSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgIHJldHVybiBmZXRjaERhdGEuY2FsbCh0aGlzLCBpbml0LCBcInJlYWRcIiwgY2FsbGJhY2spO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAgICogQHRocm93cyB7V3JpdGVFcnJvcn0gdGhlIGRhdGEgY2Fubm90IGJlIHdyaXR0ZW5cbiAgICAgKi9cbiAgICB3cml0ZSgpIHtcbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICAgICAgbGV0IGluaXQgPSBzZWxmLmdldE9wdGlvbihcIndyaXRlLmluaXRcIik7XG4gICAgICAgIGlmICghaXNPYmplY3QoaW5pdCkpIGluaXQgPSB7fTtcbiAgICAgICAgaWYgKHR5cGVvZiBpbml0W1wiaGVhZGVyc1wiXSAhPT0gXCJvYmplY3RcIikge1xuICAgICAgICAgICAgaW5pdFtcImhlYWRlcnNcIl0gPSB7XG4gICAgICAgICAgICAgICAgXCJDb250ZW50LVR5cGVcIjogXCJhcHBsaWNhdGlvbi9qc29uXCIsXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGlmICghaW5pdFtcIm1ldGhvZFwiXSkgaW5pdFtcIm1ldGhvZFwiXSA9IFwiUE9TVFwiO1xuXG4gICAgICAgIGxldCBvYmogPSBzZWxmLnByZXBhcmVTZXJ2ZXJQYXlsb2FkKHNlbGYuZ2V0KCkpO1xuICAgICAgICBpbml0W1wiYm9keVwiXSA9IEpTT04uc3RyaW5naWZ5KG9iaik7XG5cbiAgICAgICAgbGV0IGNhbGxiYWNrID0gc2VsZi5nZXRPcHRpb24oXCJ3cml0ZS5yZXNwb25zZUNhbGxiYWNrXCIpO1xuICAgICAgICByZXR1cm4gZmV0Y2hEYXRhLmNhbGwodGhpcywgaW5pdCwgXCJ3cml0ZVwiLCBjYWxsYmFjayk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7UmVzdEFQSX1cbiAgICAgKi9cbiAgICBnZXRDbG9uZSgpIHtcbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgICAgIHJldHVybiBuZXcgUmVzdEFQSShcbiAgICAgICAgICAgIHNlbGZbaW50ZXJuYWxTeW1ib2xdLmdldFJlYWxTdWJqZWN0KClbXCJvcHRpb25zXCJdLnJlYWQsXG4gICAgICAgICAgICBzZWxmW2ludGVybmFsU3ltYm9sXS5nZXRSZWFsU3ViamVjdCgpW1wib3B0aW9uc1wiXS53cml0ZSxcbiAgICAgICAgKTtcbiAgICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSBpbml0XG4gKiBAcGFyYW0ga2V5XG4gKiBAcGFyYW0gY2FsbGJhY2tcbiAqIEByZXR1cm5zIHtQcm9taXNlPHN0cmluZz59XG4gKi9cbmZ1bmN0aW9uIGZldGNoRGF0YShpbml0LCBrZXksIGNhbGxiYWNrKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgbGV0IHJlc3BvbnNlO1xuXG4gICAgcmV0dXJuIGZldGNoKHNlbGYuZ2V0T3B0aW9uKGAke2tleX0udXJsYCksIGluaXQpXG4gICAgICAgIC50aGVuKChyZXNwKSA9PiB7XG4gICAgICAgICAgICByZXNwb25zZSA9IHJlc3A7XG5cbiAgICAgICAgICAgIGNvbnN0IGFjY2VwdGVkU3RhdHVzID0gc2VsZi5nZXRPcHRpb24oYCR7a2V5fS5hY2NlcHRlZFN0YXR1c2AsIFsyMDBdKTtcblxuICAgICAgICAgICAgaWYgKGFjY2VwdGVkU3RhdHVzLmluZGV4T2YocmVzcC5zdGF0dXMpID09PSAtMSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBEYXRhRmV0Y2hFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgYHRoZSByZXNwb25zZSBkb2VzIG5vdCBjb250YWluIGEgYWNjZXB0ZWQgc3RhdHVzIChhY3R1YWw6ICR7cmVzcC5zdGF0dXN9KS5gLFxuICAgICAgICAgICAgICAgICAgICByZXNwb25zZSxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gcmVzcC50ZXh0KCk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKChib2R5KSA9PiB7XG4gICAgICAgICAgICBsZXQgb2JqO1xuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIG9iaiA9IEpTT04ucGFyc2UoYm9keSk7XG5cbiAgICAgICAgICAgICAgICByZXNwb25zZVtyYXdEYXRhU3ltYm9sXSA9IG9iajtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBpZiAoYm9keS5sZW5ndGggPiAxMDApIHtcbiAgICAgICAgICAgICAgICAgICAgYm9keSA9IGAke2JvZHkuc3Vic3RyaW5nKDAsIDk3KX0uLi5gO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBEYXRhRmV0Y2hFcnJvcihgdGhlIHJlc3BvbnNlIGRvZXMgbm90IGNvbnRhaW4gYSB2YWxpZCBqc29uIChhY3R1YWw6ICR7Ym9keX0pLmAsIHJlc3BvbnNlKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGNhbGxiYWNrICYmIGlzRnVuY3Rpb24oY2FsbGJhY2spKSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2sob2JqKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgICAgICB9KTtcbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGludGVybmFsU3ltYm9sLCBpbnN0YW5jZVN5bWJvbCB9IGZyb20gXCIuLi8uLi8uLi8uLi9jb25zdGFudHMubWpzXCI7XG5cbmV4cG9ydCB7IFdyaXRlRXJyb3IgfTtcblxuLyoqXG4gKiBFcnJvciBtZXNzYWdlIGZvciBBUEkgcmVxdWVzdHMgd2l0aCBleHRlbnNpb24gb2YgcmVxdWVzdCBhbmQgdmFsaWRhdGlvbi5cbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjI0LjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5EYXRhLkRhdGFzb3VyY2UuU2VydmVyLlJlc3RBUElcbiAqIEBzdW1tYXJ5IHRoZSBlcnJvciBpcyB0aHJvd24gYnkgdGhlIHJlc3QgYXBpIGluIGNhc2Ugb2YgZXJyb3JcbiAqL1xuY2xhc3MgV3JpdGVFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlXG4gICAgICogQHBhcmFtIHtSZXNwb25zZX0gcmVzcG9uc2VcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihtZXNzYWdlLCByZXNwb25zZSwgdmFsaWRhdGlvbikge1xuICAgICAgICBzdXBlcihtZXNzYWdlKTtcbiAgICAgICAgdGhpc1tpbnRlcm5hbFN5bWJvbF0gPSB7XG4gICAgICAgICAgICByZXNwb25zZTogcmVzcG9uc2UsXG4gICAgICAgICAgICB2YWxpZGF0aW9uOiB2YWxpZGF0aW9uLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgYGluc3RhbmNlb2ZgIG9wZXJhdG9yLlxuICAgICAqIEByZXR1cm5zIHtzeW1ib2x9XG4gICAgICogQHNpbmNlIDIuMS4wXG4gICAgICovXG4gICAgc3RhdGljIGdldCBbaW5zdGFuY2VTeW1ib2xdKCkge1xuICAgICAgICByZXR1cm4gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvZGF0YS9kYXRhc291cmNlL3NlcnZlci9yZXN0YXBpL3dyaXRlZXJyb3JcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7UmVzcG9uc2V9XG4gICAgICovXG4gICAgZ2V0UmVzcG9uc2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzW2ludGVybmFsU3ltYm9sXVtcInJlc3BvbnNlXCJdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge09iamVjdH1cbiAgICAgKi9cbiAgICBnZXRWYWxpZGF0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpc1tpbnRlcm5hbFN5bWJvbF1bXCJ2YWxpZGF0aW9uXCJdO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGludGVybmFsU3ltYm9sLCBpbnN0YW5jZVN5bWJvbCB9IGZyb20gXCIuLi8uLi8uLi8uLi9jb25zdGFudHMubWpzXCI7XG5cbmV4cG9ydCB7IERhdGFGZXRjaEVycm9yIH07XG5cbi8qKlxuICogRXJyb3IgbWVzc2FnZSBmb3IgQVBJIHJlcXVlc3RzXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMy40My4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuRGF0YS5EYXRhc291cmNlLlNlcnZlci5SZXN0QVBJXG4gKiBAc3VtbWFyeSB0aGUgZXJyb3IgaXMgdGhyb3duIGJ5IHRoZSByZXN0IGFwaSBpbiBjYXNlIG9mIGVycm9yXG4gKi9cbmNsYXNzIERhdGFGZXRjaEVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2VcbiAgICAgKiBAcGFyYW0ge1Jlc3BvbnNlfSByZXNwb25zZVxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKG1lc3NhZ2UsIHJlc3BvbnNlKSB7XG4gICAgICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgICAgICB0aGlzW2ludGVybmFsU3ltYm9sXSA9IHtcbiAgICAgICAgICAgIHJlc3BvbnNlOiByZXNwb25zZSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGBpbnN0YW5jZW9mYCBvcGVyYXRvci5cbiAgICAgKiBAcmV0dXJucyB7c3ltYm9sfVxuICAgICAqIEBzaW5jZSAyLjEuMFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgW2luc3RhbmNlU3ltYm9sXSgpIHtcbiAgICAgICAgcmV0dXJuIFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL2RhdGEvZGF0YXNvdXJjZS9zZXJ2ZXIvcmVzdGFwaS9kYXRhZmV0Y2hlcnJvckBAaW5zdGFuY2VcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7UmVzcG9uc2V9XG4gICAgICovXG4gICAgZ2V0UmVzcG9uc2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzW2ludGVybmFsU3ltYm9sXVtcInJlc3BvbnNlXCJdO1xuICAgIH1cbn1cbiIsICJcInVzZSBzdHJpY3RcIjtcblxuaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7UmVzdEFQSX0gZnJvbSBcIi4uLy4uLy4uLy4uLy4uL3NvdXJjZS9kYXRhL2RhdGFzb3VyY2Uvc2VydmVyL3Jlc3RhcGkubWpzXCI7XG5pbXBvcnQge3ZhbGlkYXRlT2JqZWN0fSBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vc291cmNlL3R5cGVzL3ZhbGlkYXRlLm1qc1wiO1xuXG5kZXNjcmliZSgnUmVzdEFQSScsIGZ1bmN0aW9uICgpIHtcblxuICAgIGxldCBmZXRjaFJlZmVyZW5jZTtcbiAgICBsZXQgcmV0dXJuU3RhdHVzO1xuXG4gICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgICAgZ2xvYmFsVGhpc1snZmV0Y2gnXSA9IGZldGNoUmVmZXJlbmNlO1xuICAgIH0pO1xuXG4gICAgYmVmb3JlRWFjaCgoKSA9PiB7XG5cbiAgICAgICAgcmV0dXJuU3RhdHVzID0gMjAwO1xuICAgICAgICBmZXRjaFJlZmVyZW5jZSA9IGdsb2JhbFRoaXNbJ2ZldGNoJ107XG4gICAgICAgIGdsb2JhbFRoaXNbJ2ZldGNoJ10gPSBmdW5jdGlvbiAob3B0aW9ucykge1xuXG4gICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgICAgIHJlc29sdmUoe1xuICAgICAgICAgICAgICAgICAgICB0ZXh0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhOiBcInRlc3RcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBzdGF0dXM6IHJldHVyblN0YXR1c1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSlcblxuICAgICAgICB9O1xuXG4gICAgfSlcblxuICAgIGl0KCdzaG91bGQgaW5zdGFuY2Ugb2YgUmVzdEFQSSAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGV4cGVjdChuZXcgUmVzdEFQSSgnaHR0cHM6Ly9tb25zdGVyanMub3JnL2Fzc2V0cy93b3JsZC5qc29uJykpLnRvLmJlLmluc3RhbmNlb2YoUmVzdEFQSSlcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdydycsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBpdCgncmVhZCBzaG91bGQgcmV0dXJuIG9iamVjdCcsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICBjb25zdCBkcyA9IG5ldyBSZXN0QVBJKHt1cmw6ICdodHRwczovL21vbnN0ZXJqcy5vcmcvYXNzZXRzL3dvcmxkLmpzb24nfSlcbiAgICAgICAgICAgIGRzLnJlYWQoKS50aGVuKGRhdGEgPT4ge1xuICAgICAgICAgICAgICAgIHZhbGlkYXRlT2JqZWN0KGRhdGEpO1xuICAgICAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICAgIH0pLmNhdGNoKGUgPT4gZG9uZShlKSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCd3cml0ZSBzaG91bGQgJywgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgICAgIGNvbnN0IGRzID0gbmV3IFJlc3RBUEkoe1xuICAgICAgICAgICAgICAgICAgICByZWFkOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB1cmw6ICdodHRwczovL21vbnN0ZXJqcy5vcmcvYXNzZXRzL3dvcmxkLmpzb24nXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHdyaXRlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB1cmw6ICdodHRwczovL21vbnN0ZXJqcy5vcmcvYXNzZXRzL3dvcmxkLmpzb24nLFxuICAgICAgICAgICAgICAgICAgICAgICAgYWNjZXB0ZWRTdGF0dXM6IFs5OV1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIGRzLndyaXRlKCkudGhlbihkYXRhID0+IHtcbiAgICAgICAgICAgICAgICBkb25lKFwic2hvdWxkIG5vdCBiZSBoZXJlXCIpO1xuICAgICAgICAgICAgfSkuY2F0Y2goZSA9PiBkb25lKCkpO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuXG4gICAgZGVzY3JpYmUoJ3J3IHdpdGggZXJyb3JzJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdyZWFkIHNob3VsZCB0aHJvdyBleGNlcHRpb24nLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICAgICAgcmV0dXJuU3RhdHVzID0gNDAwOyAvLyBmZXRjaCByZXNwb25zZSB3aXRoIDQwMFxuXG4gICAgICAgICAgICBjb25zdCBkcyA9IG5ldyBSZXN0QVBJKHt1cmw6ICdodHRwczovL21vbnN0ZXJqcy5vcmcvYXNzZXRzL3dvcmxkLmpzb24nfSlcbiAgICAgICAgICAgIGRzLnJlYWQoKS50aGVuKGRhdGEgPT4ge1xuICAgICAgICAgICAgICAgIGRvbmUoXCJzaG91bGQgbm90IHJ1bi5cIik7XG4gICAgICAgICAgICB9KS5jYXRjaChlID0+IGRvbmUoKSk7IC8vIHNob3VsZCB0aHJvdyBleGNlcHRpb24gYmVjYXVzZSByZXR1cm5TdGF0dXM9NDAwXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCd3cml0ZSBzaG91bGQgJywgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgICAgIHJldHVyblN0YXR1cyA9IDQwMDsgLy8gZmV0Y2ggcmVzcG9uc2Ugd2l0aCA0MDBcbiAgICAgICAgICAgIGNvbnN0IGRzID0gbmV3IFJlc3RBUEkoe3VybDogJ2h0dHBzOi8vbW9uc3RlcmpzLm9yZy9hc3NldHMvd29ybGQuanNvbid9LCB7dXJsOiAnaHR0cHM6Ly9tb25zdGVyanMub3JnL2Fzc2V0cy93b3JsZC5qc29uJ30pXG4gICAgICAgICAgICBkcy53cml0ZSgpLnRoZW4oZGF0YSA9PiB7XG4gICAgICAgICAgICAgICAgdmFsaWRhdGVPYmplY3QoZGF0YSk7XG4gICAgICAgICAgICAgICAgZG9uZShcImVycm9yXCIpO1xuICAgICAgICAgICAgfSkuY2F0Y2goZSA9PiBkb25lKCkpOyAvLyBzaG91bGQgdGhyb3cgZXhjZXB0aW9uIGJlY2F1c2UgcmV0dXJuU3RhdHVzPTQwMFxuICAgICAgICB9KTtcblxuXG4gICAgfSlcblxuXG59KVxuIiwgIlwidXNlIHN0cmljdFwiO1xuXG5pbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuaW1wb3J0IHtEYXRhc291cmNlfSBmcm9tIFwiLi4vLi4vLi4vc291cmNlL2RhdGEvZGF0YXNvdXJjZS5tanNcIjtcblxuXG5kZXNjcmliZSgnRGF0YXNvdXJjZScsIGZ1bmN0aW9uICgpIHtcblxuXG4gICAgaXQoJ3Nob3VsZCBpbnN0YW5jZSBvZiBEYXRhc291cmNlICcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZXhwZWN0KG5ldyBEYXRhc291cmNlKCkpLnRvLmJlLmluc3RhbmNlb2YoRGF0YXNvdXJjZSlcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdPcHRpb25zJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2V0T3B0aW9uIHNob3VsZCBjaGFuZ2UgdmFsdWUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zdCBkYXRhc291cmNlID0gbmV3IERhdGFzb3VyY2UoKTtcbiAgICAgICAgICAgIGV4cGVjdChkYXRhc291cmNlLmdldE9wdGlvbignZGVmYXVsdCcpKS50by5iZS51bmRlZmluZWRcbiAgICAgICAgICAgIGRhdGFzb3VyY2Uuc2V0T3B0aW9uKCdkZWZhdWx0JywgdHJ1ZSlcbiAgICAgICAgICAgIGV4cGVjdChkYXRhc291cmNlLmdldE9wdGlvbignZGVmYXVsdCcpKS50by5iZS50cnVlXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzZXRPcHRpb25zIHNob3VsZCBzZXQgYWxsIHZhbHVlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IGRhdGFzb3VyY2UgPSBuZXcgRGF0YXNvdXJjZSgpO1xuICAgICAgICAgICAgZXhwZWN0KGRhdGFzb3VyY2UuZ2V0T3B0aW9uKCdkZWZhdWx0JykpLnRvLmJlLnVuZGVmaW5lZFxuICAgICAgICAgICAgZGF0YXNvdXJjZS5zZXRPcHRpb25zKHtkZWZhdWx0OiB0cnVlfSlcbiAgICAgICAgICAgIGV4cGVjdChkYXRhc291cmNlLmdldE9wdGlvbignZGVmYXVsdCcpKS50by5iZS50cnVlXG4gICAgICAgIH0pO1xuXG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCdydycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgZGF0YXNvdXJjZSA9IG5ldyBEYXRhc291cmNlKCk7XG4gICAgICAgIGl0KCdyZWFkIHNob3VsZCB0aHJvdyBleGVwdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdCgoKSA9PiBkYXRhc291cmNlLnJlYWQoKSkudG8udGhyb3coRXJyb3IpO1xuICAgICAgICB9KTtcbiAgICAgICAgXG4gICAgICAgIGl0KCd3cml0ZSBzaG91bGQgdGhyb3cgZXhlcHRpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QoKCkgPT4gZGF0YXNvdXJjZS5yZWFkKCkpLnRvLnRocm93KEVycm9yKTtcbiAgICAgICAgfSk7XG5cblxuICAgIH0pXG4gICAgXG4gICAgZGVzY3JpYmUoJ2dldC9zZXQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGRhdGFzb3VyY2UgPSBuZXcgRGF0YXNvdXJjZSgpO1xuICAgICAgICBpdCgnZ2V0IHNob3VsZCByZXR1cm4gdW5kZWZpbmVkJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KCBkYXRhc291cmNlLmdldCgpKS50by5iZS5lcWwoe30pO1xuICAgICAgICB9KTtcbiAgICAgICAgXG4gICAgICAgIGl0KCd3cml0ZSBzaG91bGQgdGhyb3cgZXhlcHRpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QoIGRhdGFzb3VyY2UuZ2V0KCkpLnRvLmJlLmVxbCh7fSk7XG4gICAgICAgICAgICBleHBlY3QoIGRhdGFzb3VyY2Uuc2V0KHthOidteXZhbHVlJ30pKS50by5iZS5pbnN0YW5jZW9mKERhdGFzb3VyY2UpO1xuICAgICAgICAgICAgZXhwZWN0KCBkYXRhc291cmNlLmdldCgpKS50by5iZS5lcWwoe2E6J215dmFsdWUnfSk7XG4gICAgICAgIH0pO1xuXG5cbiAgICB9KVxuXG5cbn0pIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgaXNGdW5jdGlvbiwgaXNPYmplY3QsIGlzU3RyaW5nIH0gZnJvbSBcIi4uL3R5cGVzL2lzLm1qc1wiO1xuaW1wb3J0IHsgdmFsaWRhdGVTdHJpbmcgfSBmcm9tIFwiLi4vdHlwZXMvdmFsaWRhdGUubWpzXCI7XG5pbXBvcnQgeyBjbG9uZSB9IGZyb20gXCIuLi91dGlsL2Nsb25lLm1qc1wiO1xuaW1wb3J0IHsgREVMSU1JVEVSLCBQYXRoZmluZGVyLCBXSUxEQ0FSRCB9IGZyb20gXCIuL3BhdGhmaW5kZXIubWpzXCI7XG5cbmV4cG9ydCB7IGJ1aWxkTWFwLCBQQVJFTlQsIGFzc2VtYmxlUGFydHMgfTtcblxuLyoqXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQG1lbWJlck9mIE1vbnN0ZXIuRGF0YVxuICovXG5jb25zdCBQQVJFTlQgPSBcIl5cIjtcblxuLyoqXG4gKiBNYXBzIGNhbiBiZSBlYXNpbHkgY3JlYXRlZCBmcm9tIGRhdGEgb2JqZWN0cyB3aXRoIHRoZSBoZWxwIG9mIHRoZSBmdW5jdGlvbiBgYnVpbGRNYXAoKWAuXG4gKlxuICogVGhlIHBhdGggY2FuIGJlIHNwZWNpZmllZCBhcyBlaXRoZXIgYSBzaW1wbGUgZGVmaW5pdGlvbiBhLmIuYyBvciBhIHRlbXBsYXRlICR7YS5iLmN9LlxuICogS2V5IGFuZCB2YWx1ZSBjYW4gYmUgZWl0aGVyIGEgZGVmaW5pdGlvbiBvciBhIHRlbXBsYXRlLiBUaGUga2V5IGRvZXMgbm90IGhhdmUgdG8gYmUgZGVmaW5lZC5cbiAqIFRoZSB0ZW1wbGF0ZXMgZGV0ZXJtaW5lIHRoZSBhcHBlYXJhbmNlIG9mIHRoZSBrZXlzIGFuZCB0aGUgdmFsdWUgb2YgdGhlIG1hcC4gRWl0aGVyIGEgc2luZ2xlIHZhbHVlXG4gKiBpZCBjYW4gYmUgdGFrZW4gb3IgYSBjb21wb3NpdGUga2V5ICR7aWR9ICR7bmFtZX0gY2FuIGJlIHVzZWQuXG4gKlxuICogSWYgeW91IHdhbnQgdG8gYWNjZXNzIHZhbHVlcyBvZiB0aGUgcGFyZW50IGRhdGEgc2V0LCB5b3UgaGF2ZSB0byB1c2UgdGhlIF4gY2hhcmFjdGVyLCBmb3IgZXhhbXBsZSAke2lkfSAke14ubmFtZX0uXG4gKlxuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL2RhdGEvYnVpbGRtYXAubWpzXG4gKiBAcGFyYW0geyp9IHN1YmplY3QgLSBUaGUgZGF0YSBvYmplY3QgZnJvbSB3aGljaCB0aGUgbWFwIHdpbGwgYmUgY3JlYXRlZFxuICogQHBhcmFtIHtzdHJpbmd8TW9uc3Rlci5EYXRhfmV4YW1wbGVTZWxlY3RvckNhbGxiYWNrfSBzZWxlY3RvciAtIFRoZSBwYXRoIHRvIHRoZSBkYXRhIG9iamVjdCwgb3IgYSBjYWxsYmFjayB0aGF0IHJldHVybnMgYSBtYXAuXG4gKiBAcGFyYW0ge3N0cmluZ30gW3ZhbHVlVGVtcGxhdGVdIC0gQSB0ZW1wbGF0ZSBmb3IgdGhlIHZhbHVlIG9mIHRoZSBtYXAuXG4gKiBAcGFyYW0ge3N0cmluZ30gW2tleVRlbXBsYXRlXSAtIEEgdGVtcGxhdGUgZm9yIHRoZSBrZXkgb2YgdGhlIG1hcC5cbiAqIEBwYXJhbSB7TW9uc3Rlci5EYXRhfmV4YW1wbGVGaWx0ZXJDYWxsYmFja30gW2ZpbHRlcl0gLSBBIGNhbGxiYWNrIGZ1bmN0aW9uIHRvIGZpbHRlciBvdXQgdmFsdWVzLlxuICogQHJldHVybiB7Kn0gLSBUaGUgY3JlYXRlZCBtYXAuXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5EYXRhXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IC0gSWYgdGhlIHZhbHVlIGlzIG5laXRoZXIgYSBzdHJpbmcgbm9yIGEgZnVuY3Rpb24uXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IC0gSWYgdGhlIHNlbGVjdG9yIGNhbGxiYWNrIGRvZXMgbm90IHJldHVybiBhIG1hcC5cbiAqKi9cbmZ1bmN0aW9uIGJ1aWxkTWFwKHN1YmplY3QsIHNlbGVjdG9yLCB2YWx1ZVRlbXBsYXRlLCBrZXlUZW1wbGF0ZSwgZmlsdGVyKSB7XG4gICAgcmV0dXJuIGFzc2VtYmxlUGFydHMoc3ViamVjdCwgc2VsZWN0b3IsIGZpbHRlciwgZnVuY3Rpb24gKHYsIGssIG0pIHtcbiAgICAgICAgayA9IGJ1aWxkKHYsIGtleVRlbXBsYXRlLCBrKTtcbiAgICAgICAgdiA9IGJ1aWxkKHYsIHZhbHVlVGVtcGxhdGUpO1xuICAgICAgICB0aGlzLnNldChrLCB2KTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBUaGUgYXNzZW1ibGVQYXJ0cyBmdW5jdGlvbiBpcyBhIHByaXZhdGUgZnVuY3Rpb24gdGhhdCBoZWxwcyBpbiBidWlsZGluZyBhIG1hcCBmcm9tIGEgc3ViamVjdCBvYmplY3QgYmFzZWQgb24gYSBwcm92aWRlZFxuICogc2VsZWN0b3IuIFRoZSBzZWxlY3RvciBjYW4gZWl0aGVyIGJlIGEgc3RyaW5nIG9yIGEgY2FsbGJhY2sgZnVuY3Rpb24uIFRoaXMgZnVuY3Rpb24gaXMgbWVhbnQgdG8gYmUgdXNlZCBhcyBhXG4gKiBoZWxwZXIgZnVuY3Rpb24gYnkgb3RoZXIgZnVuY3Rpb25zIGluIHRoZSBtb2R1bGUuXG4gKlxuICogVGhlIGZ1bmN0aW9uIHRha2VzIGZvdXIgcGFyYW1ldGVyczpcbiAqXG4gKiBzdWJqZWN0OiBUaGUgc3ViamVjdCBvYmplY3QgZnJvbSB3aGljaCB0aGUgbWFwIGlzIHRvIGJlIGJ1aWx0XG4gKiBzZWxlY3RvcjogVGhlIHNlbGVjdG9yIHRvIGRldGVybWluZSB0aGUgc3RydWN0dXJlIG9mIHRoZSBtYXAuIEl0IGNhbiBiZSBhIHN0cmluZyBvciBhIGNhbGxiYWNrIGZ1bmN0aW9uLlxuICogZmlsdGVyIChvcHRpb25hbCk6IEEgY2FsbGJhY2sgZnVuY3Rpb24gdGhhdCBjYW4gYmUgdXNlZCB0byBmaWx0ZXIgdmFsdWVzIGJhc2VkIG9uIHNvbWUgY3JpdGVyaWEuXG4gKiBjYWxsYmFjazogQSBmdW5jdGlvbiB0byBiZSBjYWxsZWQgZm9yIGVhY2ggZWxlbWVudCBpbiB0aGUgbWFwLlxuICogSWYgdGhlIHNlbGVjdG9yIHBhcmFtZXRlciBpcyBhIGNhbGxiYWNrIGZ1bmN0aW9uLCBpdCBpcyBleGVjdXRlZCBwYXNzaW5nIHRoZSBzdWJqZWN0IGFzIGl0cyBhcmd1bWVudCxcbiAqIGFuZCB0aGUgcmVzdWx0aW5nIHZhbHVlIG11c3QgYmUgYW4gaW5zdGFuY2Ugb2YgTWFwLiBPdGhlcndpc2UsIGlmIHRoZSBzZWxlY3RvciBwYXJhbWV0ZXIgaXMgYSBzdHJpbmcsXG4gKiBidWlsZEZsYXRNYXAgaXMgY2FsbGVkIHRvIGJ1aWxkIGEgZmxhdCBtYXAgd2l0aCBrZXlzIGFuZCB2YWx1ZXMgZXh0cmFjdGVkIGZyb20gdGhlIHN1YmplY3Qgb2JqZWN0IGJhc2VkIG9uIHRoZSBzZWxlY3Rvci5cbiAqXG4gKiBJZiB0aGUgZmlsdGVyIHBhcmFtZXRlciBpcyBwcm92aWRlZCwgaXQgd2lsbCBiZSB1c2VkIHRvIGZpbHRlciBvdXQgY2VydGFpbiBlbGVtZW50cyBmcm9tIHRoZSBtYXAsIGJhc2VkIG9uIHNvbWVcbiAqIGNyaXRlcmlhLiBUaGUgY2FsbGJhY2sgd2lsbCBiZSBwYXNzZWQgdGhlIHZhbHVlLCBrZXksIGFuZCBtYXAgb2JqZWN0LCBhbmQgaWYgaXQgcmV0dXJucyBmYWxzZSwgdGhlIGVsZW1lbnQgd2lsbCBiZSBza2lwcGVkLlxuICpcbiAqIEZvciBlYWNoIGVsZW1lbnQgaW4gdGhlIG1hcCwgdGhlIGNhbGxiYWNrIGZ1bmN0aW9uIGlzIGNhbGxlZCB3aXRoIHRoZSBmb2xsb3dpbmcgcGFyYW1ldGVyczpcbiAqXG4gKiB2OiBUaGUgdmFsdWUgb2YgdGhlIGVsZW1lbnRcbiAqIGs6IFRoZSBrZXkgb2YgdGhlIGVsZW1lbnRcbiAqIG06IFRoZSBtYXAgb2JqZWN0XG4gKiBUaGUgZnVuY3Rpb24gcmV0dXJucyBhIG5ldyBtYXAgd2l0aCB0aGUgcHJvY2Vzc2VkIHZhbHVlcy4gSWYgbWFwIGlzIG5vdCBhbiBpbnN0YW5jZSBvZiBNYXAsIGFuIGVtcHR5IG1hcCB3aWxsIGJlIHJldHVybmVkLlxuICpcbiAqIEV4YW1wbGUgVXNhZ2U6XG4gKlxuICogYGBgamF2YXNjcmlwdFxuICogY29uc3Qgb2JqID0ge1xuICogICBuYW1lOiBcIkpvaG5cIixcbiAqICAgYWdlOiAzMCxcbiAqICAgYWRkcmVzczoge1xuICogICAgIGNpdHk6IFwiTmV3IFlvcmtcIixcbiAqICAgICBzdGF0ZTogXCJOWVwiLFxuICogICAgIGNvdW50cnk6IFwiVVNBXCIsXG4gKiAgIH0sXG4gKiB9O1xuICpcbiAqIGNvbnN0IHNlbGVjdG9yID0gXCJhZGRyZXNzXCI7XG4gKlxuICogY29uc3QgbWFwID0gYXNzZW1ibGVQYXJ0cyhvYmosIHNlbGVjdG9yLCBudWxsLCBmdW5jdGlvbiAodiwgaywgbSkge1xuICogICB0aGlzLnNldChrLCB2KTtcbiAqIH0pO1xuICpcbiAqIGNvbnNvbGUubG9nKG1hcCk7XG4gKiAvLyBPdXRwdXQ6IE1hcCgzKSB7XG4gKiAvLyAgIFwiYWRkcmVzcy5jaXR5XCIgPT4gXCJOZXcgWW9ya1wiLFxuICogLy8gICBcImFkZHJlc3Muc3RhdGVcIiA9PiBcIk5ZXCIsXG4gKiAvLyAgIFwiYWRkcmVzcy5jb3VudHJ5XCIgPT4gXCJVU0FcIlxuICogLy8gfVxuICogYGBgXG4gKlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHN1YmplY3QgLSBUaGUgc3ViamVjdCBvYmplY3QgZnJvbSB3aGljaCB0aGUgbWFwIGlzIHRvIGJlIGJ1aWx0LlxuICogQHBhcmFtIHtzdHJpbmd8TW9uc3Rlci5EYXRhfmV4YW1wbGVTZWxlY3RvckNhbGxiYWNrfSBzZWxlY3RvciAtIFRoZSBzZWxlY3RvciB0byBkZXRlcm1pbmUgdGhlIHN0cnVjdHVyZSBvZiB0aGUgbWFwLiBJdCBjYW4gYmUgYSBzdHJpbmcgb3IgYSBjYWxsYmFjayBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7TW9uc3Rlci5EYXRhfmV4YW1wbGVGaWx0ZXJDYWxsYmFja30gW2ZpbHRlcl0gLSBBIGNhbGxiYWNrIGZ1bmN0aW9uIHRoYXQgY2FuIGJlIHVzZWQgdG8gZmlsdGVyIHZhbHVlcyBiYXNlZCBvbiBzb21lIGNyaXRlcmlhLlxuICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2sgLSBBIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCBmb3IgZWFjaCBlbGVtZW50IGluIHRoZSBtYXAuXG4gKiBAcmV0dXJuIHtNYXB9IC0gQSBuZXcgbWFwIHdpdGggdGhlIHByb2Nlc3NlZCB2YWx1ZXMuXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IC0gV2hlbiBzZWxlY3RvciBpcyBuZWl0aGVyIGEgc3RyaW5nIG5vciBhIGZ1bmN0aW9uLlxuICogQG1lbWJlck9mIE1vbnN0ZXIuRGF0YVxuICovXG5mdW5jdGlvbiBhc3NlbWJsZVBhcnRzKHN1YmplY3QsIHNlbGVjdG9yLCBmaWx0ZXIsIGNhbGxiYWNrKSB7XG4gICAgY29uc3QgcmVzdWx0ID0gbmV3IE1hcCgpO1xuXG4gICAgbGV0IG1hcDtcbiAgICBpZiAoaXNGdW5jdGlvbihzZWxlY3RvcikpIHtcbiAgICAgICAgbWFwID0gc2VsZWN0b3Ioc3ViamVjdCk7XG4gICAgICAgIGlmICghKG1hcCBpbnN0YW5jZW9mIE1hcCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJ0aGUgc2VsZWN0b3IgY2FsbGJhY2sgbXVzdCByZXR1cm4gYSBtYXBcIik7XG4gICAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGlzU3RyaW5nKHNlbGVjdG9yKSkge1xuICAgICAgICBtYXAgPSBuZXcgTWFwKCk7XG4gICAgICAgIGJ1aWxkRmxhdE1hcC5jYWxsKG1hcCwgc3ViamVjdCwgc2VsZWN0b3IpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJzZWxlY3RvciBpcyBuZWl0aGVyIGEgc3RyaW5nIG5vciBhIGZ1bmN0aW9uXCIpO1xuICAgIH1cblxuICAgIGlmICghKG1hcCBpbnN0YW5jZW9mIE1hcCkpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICBtYXAuZm9yRWFjaCgodiwgaywgbSkgPT4ge1xuICAgICAgICBpZiAoaXNGdW5jdGlvbihmaWx0ZXIpKSB7XG4gICAgICAgICAgICBpZiAoZmlsdGVyLmNhbGwobSwgdiwgaykgIT09IHRydWUpIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNhbGxiYWNrLmNhbGwocmVzdWx0LCB2LCBrLCBtKTtcbiAgICB9KTtcblxuICAgIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSBzdWJqZWN0XG4gKiBAcGFyYW0gc2VsZWN0b3JcbiAqIEBwYXJhbSBrZXlcbiAqIEBwYXJhbSBwYXJlbnRNYXBcbiAqIEByZXR1cm4geyp9XG4gKi9cbmZ1bmN0aW9uIGJ1aWxkRmxhdE1hcChzdWJqZWN0LCBzZWxlY3Rvciwga2V5LCBwYXJlbnRNYXApIHtcbiAgICBjb25zdCByZXN1bHQgPSB0aGlzO1xuICAgIGNvbnN0IGN1cnJlbnRNYXAgPSBuZXcgTWFwKCk7XG5cbiAgICBjb25zdCByZXN1bHRMZW5ndGggPSByZXN1bHQuc2l6ZTtcblxuICAgIGlmIChrZXkgPT09IHVuZGVmaW5lZCkga2V5ID0gW107XG5cbiAgICBsZXQgcGFydHMgPSBzZWxlY3Rvci5zcGxpdChERUxJTUlURVIpO1xuICAgIGxldCBjdXJyZW50ID0gXCJcIjtcbiAgICBsZXQgY3VycmVudFBhdGggPSBbXTtcbiAgICBkbyB7XG4gICAgICAgIGN1cnJlbnQgPSBwYXJ0cy5zaGlmdCgpO1xuICAgICAgICBjdXJyZW50UGF0aC5wdXNoKGN1cnJlbnQpO1xuXG4gICAgICAgIGlmIChjdXJyZW50ID09PSBXSUxEQ0FSRCkge1xuICAgICAgICAgICAgbGV0IGZpbmRlciA9IG5ldyBQYXRoZmluZGVyKHN1YmplY3QpO1xuICAgICAgICAgICAgbGV0IG1hcDtcblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBtYXAgPSBmaW5kZXIuZ2V0VmlhKGN1cnJlbnRQYXRoLmpvaW4oREVMSU1JVEVSKSk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgbGV0IGEgPSBlO1xuICAgICAgICAgICAgICAgIG1hcCA9IG5ldyBNYXAoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZm9yIChjb25zdCBbaywgb10gb2YgbWFwKSB7XG4gICAgICAgICAgICAgICAgbGV0IGNvcHlLZXkgPSBjbG9uZShrZXkpO1xuXG4gICAgICAgICAgICAgICAgY3VycmVudFBhdGgubWFwKChhKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvcHlLZXkucHVzaChhID09PSBXSUxEQ0FSRCA/IGsgOiBhKTtcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIGxldCBrayA9IGNvcHlLZXkuam9pbihERUxJTUlURVIpO1xuICAgICAgICAgICAgICAgIGxldCBzdWIgPSBidWlsZEZsYXRNYXAuY2FsbChyZXN1bHQsIG8sIHBhcnRzLmpvaW4oREVMSU1JVEVSKSwgY29weUtleSwgbyk7XG5cbiAgICAgICAgICAgICAgICBpZiAoaXNPYmplY3Qoc3ViKSAmJiBwYXJlbnRNYXAgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICBzdWJbUEFSRU5UXSA9IHBhcmVudE1hcDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjdXJyZW50TWFwLnNldChraywgc3ViKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0gd2hpbGUgKHBhcnRzLmxlbmd0aCA+IDApO1xuXG4gICAgLy8gbm8gc2V0IGluIGNoaWxkIHJ1blxuICAgIGlmIChyZXN1bHRMZW5ndGggPT09IHJlc3VsdC5zaXplKSB7XG4gICAgICAgIGZvciAoY29uc3QgW2ssIG9dIG9mIGN1cnJlbnRNYXApIHtcbiAgICAgICAgICAgIHJlc3VsdC5zZXQoaywgbyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gc3ViamVjdDtcbn1cblxuLyoqXG4gKiBXaXRoIHRoZSBoZWxwIG9mIHRoaXMgZmlsdGVyIGNhbGxiYWNrLCB2YWx1ZXMgY2FuIGJlIGZpbHRlcmVkIG91dC4gT25seSBpZiB0aGUgZmlsdGVyIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZSwgdGhlIHZhbHVlIGlzIHRha2VuIGZvciB0aGUgbWFwLlxuICpcbiAqIEBjYWxsYmFjayBNb25zdGVyLkRhdGF+ZXhhbXBsZUZpbHRlckNhbGxiYWNrXG4gKiBAcGFyYW0geyp9IHZhbHVlIFZhbHVlXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5ICBLZXlcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRhdGFcbiAqIEBzZWUge0BsaW5rIE1vbnN0ZXIuRGF0YS5idWlsZE1hcH1cbiAqL1xuXG4vKipcbiAqIEFsdGVybmF0aXZlbHkgdG8gYSBzdHJpbmcgc2VsZWN0b3IgYSBjYWxsYmFjayBjYW4gYmUgc3BlY2lmaWVkLiB0aGlzIG11c3QgcmV0dXJuIGEgbWFwLlxuICpcbiAqIEBleGFtcGxlXG4gKiBpbXBvcnQge2J1aWxkTWFwfSBmcm9tICdAc2NodWthaS9tb25zdGVyL3NvdXJjZS9kYXRhL2J1aWxkbWFwLm1qcyc7XG4gKlxuICogbGV0IG9iaiA9IHtcbiAqICAgICAgICAgICAgICAgIFwiZGF0YVwiOiBbXG4gKiAgICAgICAgICAgICAgICAgICAge1xuICogICAgICAgICAgICAgICAgICAgICAgICBcImlkXCI6IDEwLFxuICogICAgICAgICAgICAgICAgICAgICAgICBcIm5hbWVcIjogXCJDYXNzYW5kcmFcIixcbiAqICAgICAgICAgICAgICAgICAgICAgICAgXCJlbnJpY2htZW50XCI6IHtcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhcmlhbnRzOiBbXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBza3U6IDEsIGxhYmVsOiBcIlhYU1wiLCBwcmljZTogW1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnMTIuMTIgXHUyMEFDJ30sXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICcxMi4xMiBcdTIwQUMnfVxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNrdTogMiwgbGFiZWw6IFwiWFNcIiwgcHJpY2U6IFtcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt2azogJzIyLjEyIFx1MjBBQyd9LFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnMjIuMTIgXHUyMEFDJ31cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBza3U6IDMsIGxhYmVsOiBcIlNcIiwgcHJpY2U6IFtcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt2azogJzMyLjEyIFx1MjBBQyd9LFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnMzIuMTIgXHUyMEFDJ31cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBza3U6IDQsIGxhYmVsOiBcIkxcIiwgcHJpY2U6IFtcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt2azogJzQyLjEyIFx1MjBBQyd9LFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnNDIuMTIgXHUyMEFDJ31cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIF1cbiAqXG4gKiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAqICAgICAgICAgICAgICAgICAgICB9LFxuICogICAgICAgICAgICAgICAgICAgIHtcbiAqICAgICAgICAgICAgICAgICAgICAgICAgXCJpZFwiOiAyMCxcbiAqICAgICAgICAgICAgICAgICAgICAgICAgXCJuYW1lXCI6IFwiWWVzc2V5IVwiLFxuICogICAgICAgICAgICAgICAgICAgICAgICBcImVucmljaG1lbnRcIjoge1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyaWFudHM6IFtcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNrdTogMSwgbGFiZWw6IFwiWFhTXCIsIHByaWNlOiBbXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICcxMi4xMiBcdTIwQUMnfSxcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt2azogJzEyLjEyIFx1MjBBQyd9XG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF1cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2t1OiAyLCBsYWJlbDogXCJYU1wiLCBwcmljZTogW1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnMjIuMTIgXHUyMEFDJ30sXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICcyMi4xMiBcdTIwQUMnfVxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNrdTogMywgbGFiZWw6IFwiU1wiLCBwcmljZTogW1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnMzIuMTIgXHUyMEFDJ30sXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICczMi4xMiBcdTIwQUMnfVxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNrdTogNCwgbGFiZWw6IFwiTFwiLCBwcmljZTogW1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnNDIuMTIgXHUyMEFDJ30sXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICc0Mi4xMiBcdTIwQUMnfVxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuICpcbiAqICAgICAgICAgICAgICAgICAgICAgICAgfVxuICogICAgICAgICAgICAgICAgICAgIH1cbiAqICAgICAgICAgICAgICAgIF1cbiAqICAgICAgICAgICAgfTtcbiAqXG4gKiBsZXQgY2FsbGJhY2sgPSBmdW5jdGlvbiAoc3ViamVjdCkge1xuICogICAgICAgICAgICAgICAgbGV0IG0gPSBuZXcgTWFwO1xuICpcbiAqICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW2ksIGJdIG9mIE9iamVjdC5lbnRyaWVzKHN1YmplY3QuZGF0YSkpIHtcbiAqXG4gKiAgICAgICAgICAgICAgICAgICAgbGV0IGtleTEgPSBpO1xuICpcbiAqICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IFtqLCBjXSBvZiBPYmplY3QuZW50cmllcyhiLmVucmljaG1lbnQudmFyaWFudHMpKSB7XG4gKiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBrZXkyID0gajtcbiAqXG4gKiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW2ssIGRdIG9mIE9iamVjdC5lbnRyaWVzKGMucHJpY2UpKSB7XG4gKlxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGtleTMgPSBrO1xuICpcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQubmFtZSA9IGIubmFtZTtcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQubGFiZWwgPSBjLmxhYmVsO1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgZC5pZCA9IFtrZXkxLCBrZXkyLCBrZXkzXS5qb2luKCcuJyk7XG4gKlxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgbS5zZXQoZC5pZCwgZCk7XG4gKiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAqXG4gKiAgICAgICAgICAgICAgICAgICAgfVxuICogICAgICAgICAgICAgICAgfVxuICogICAgICAgICAgICAgICAgcmV0dXJuIG07XG4gKiAgICAgICAgICAgIH1cbiAqXG4gKiBsZXQgbWFwID0gYnVpbGRNYXAob2JqLCBjYWxsYmFjaywgJyR7bmFtZX0gJHt2a30nLCAnJHtpZH0nKVxuICpcbiAqIC8vIFx1MjFBNiBNYXAoMykge1xuICogLy8gIFwiMC4wLjBcIjpcIkNhc3NhbmRyYSAxMi4xMiBcdTIwQUNcIixcbiAqIC8vICBcIjAuMC4xXCI6XCJDYXNzYW5kcmEgMTIuMTIgXHUyMEFDXCIsXG4gKiAvLyAgXCIwLjEuMFwiOlwiQ2Fzc2FuZHJhIDIyLjEyIFx1MjBBQ1wiLFxuICogLy8gIFwiMC4xLjFcIjpcIkNhc3NhbmRyYSAyMi4xMiBcdTIwQUNcIixcbiAqIC8vICBcIjAuMi4wXCI6XCJDYXNzYW5kcmEgMzIuMTIgXHUyMEFDXCIsXG4gKiAvLyAgXCIwLjIuMVwiOlwiQ2Fzc2FuZHJhIDMyLjEyIFx1MjBBQ1wiLFxuICogLy8gIFwiMC4zLjBcIjpcIkNhc3NhbmRyYSA0Mi4xMiBcdTIwQUNcIixcbiAqIC8vICBcIjAuMy4xXCI6XCJDYXNzYW5kcmEgNDIuMTIgXHUyMEFDXCIsXG4gKiAvLyAgXCIxLjAuMFwiOlwiWWVzc2V5ISAxMi4xMiBcdTIwQUNcIixcbiAqIC8vICBcIjEuMC4xXCI6XCJZZXNzZXkhIDEyLjEyIFx1MjBBQ1wiLFxuICogLy8gIFwiMS4xLjBcIjpcIlllc3NleSEgMjIuMTIgXHUyMEFDXCIsXG4gKiAvLyAgXCIxLjEuMVwiOlwiWWVzc2V5ISAyMi4xMiBcdTIwQUNcIixcbiAqIC8vICBcIjEuMi4wXCI6XCJZZXNzZXkhIDMyLjEyIFx1MjBBQ1wiLFxuICogLy8gIFwiMS4yLjFcIjpcIlllc3NleSEgMzIuMTIgXHUyMEFDXCIsXG4gKiAvLyAgXCIxLjMuMFwiOlwiWWVzc2V5ISA0Mi4xMiBcdTIwQUNcIixcbiAqIC8vICBcIjEuMy4xXCI6XCJZZXNzZXkhIDQyLjEyIFx1MjBBQ1wiXG4gKiAvLyB9XG4gKlxuICogQGNhbGxiYWNrIE1vbnN0ZXIuRGF0YX5leGFtcGxlU2VsZWN0b3JDYWxsYmFja1xuICogQHBhcmFtIHsqfSBzdWJqZWN0IHN1YmplY3RcbiAqIEByZXR1cm4gTWFwXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjE3LjBcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRhdGFcbiAqIEBzZWUge0BsaW5rIE1vbnN0ZXIuRGF0YS5idWlsZE1hcH1cbiAqL1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHN1YmplY3RcbiAqIEBwYXJhbSB7c3RyaW5nfHVuZGVmaW5lZH0gZGVmaW5pdGlvblxuICogQHBhcmFtIHsqfSBkZWZhdWx0VmFsdWVcbiAqIEByZXR1cm4geyp9XG4gKi9cbmZ1bmN0aW9uIGJ1aWxkKHN1YmplY3QsIGRlZmluaXRpb24sIGRlZmF1bHRWYWx1ZSkge1xuICAgIGlmIChkZWZpbml0aW9uID09PSB1bmRlZmluZWQpIHJldHVybiBkZWZhdWx0VmFsdWUgPyBkZWZhdWx0VmFsdWUgOiBzdWJqZWN0O1xuICAgIHZhbGlkYXRlU3RyaW5nKGRlZmluaXRpb24pO1xuXG4gICAgY29uc3QgcmVnZXhwID0gLyg/PHBsYWNlaG9sZGVyPlxcJHsoPzxwYXRoPlthLXpcXF5BLVouXFwtXzAtOV0qKX0pL2dtO1xuICAgIGNvbnN0IGFycmF5ID0gWy4uLmRlZmluaXRpb24ubWF0Y2hBbGwocmVnZXhwKV07XG5cbiAgICBsZXQgZmluZGVyID0gbmV3IFBhdGhmaW5kZXIoc3ViamVjdCk7XG5cbiAgICBpZiAoYXJyYXkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiBmaW5kZXIuZ2V0VmlhKGRlZmluaXRpb24pO1xuICAgIH1cblxuICAgIGFycmF5LmZvckVhY2goKGEpID0+IHtcbiAgICAgICAgbGV0IGdyb3VwcyA9IGE/LltcImdyb3Vwc1wiXTtcbiAgICAgICAgbGV0IHBsYWNlaG9sZGVyID0gZ3JvdXBzPy5bXCJwbGFjZWhvbGRlclwiXTtcbiAgICAgICAgaWYgKHBsYWNlaG9sZGVyID09PSB1bmRlZmluZWQpIHJldHVybjtcblxuICAgICAgICBsZXQgcGF0aCA9IGdyb3Vwcz8uW1wicGF0aFwiXTtcblxuICAgICAgICBsZXQgdiA9IGZpbmRlci5nZXRWaWEocGF0aCk7XG4gICAgICAgIGlmICh2ID09PSB1bmRlZmluZWQpIHYgPSBkZWZhdWx0VmFsdWU7XG5cbiAgICAgICAgZGVmaW5pdGlvbiA9IGRlZmluaXRpb24ucmVwbGFjZUFsbChwbGFjZWhvbGRlciwgdik7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gZGVmaW5pdGlvbjtcbn1cbiIsICJcInVzZSBzdHJpY3RcIjtcblxuaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7YnVpbGRNYXB9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvZGF0YS9idWlsZG1hcC5tanNcIjtcblxuXG5kZXNjcmliZSgnYnVpbGRNYXAnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBsZXQgY29udmVydE1hcFJlc3VsdCA9IGZ1bmN0aW9uIChyKSB7XG4gICAgICAgIGlmIChyIGluc3RhbmNlb2YgTWFwKSB7XG4gICAgICAgICAgICByID0gT2JqZWN0LmZyb21FbnRyaWVzKHIpO1xuICAgICAgICAgICAgaWYgKHIgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAgICAgICAgIHIgPSByLm1hcCgoZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29udmVydE1hcFJlc3VsdChlKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgciA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW2ssIG9dIG9mIE9iamVjdC5lbnRyaWVzKHIpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJba10gPSBjb252ZXJ0TWFwUmVzdWx0KG8pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByO1xuICAgIH1cblxuICAgIGRlc2NyaWJlKCdidWlsZCBNYXAgd2l0aCBjYWxsYmFjaycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ2RlZmluaXRpb24gc2hvdWxkIHJldHVybiBtYXAgd2l0aCBzdWIgYW5kIHBhcmVudCBrZXlzJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBsZXQgb2JqID0ge1xuICAgICAgICAgICAgICAgIFwiZGF0YVwiOiBbXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiaWRcIjogMTAsXG4gICAgICAgICAgICAgICAgICAgICAgICBcIm5hbWVcIjogXCJDYXNzYW5kcmFcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiZW5yaWNobWVudFwiOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyaWFudHM6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2t1OiAxLCBsYWJlbDogXCJYWFNcIiwgcHJpY2U6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICcxMi4xMiBcdTIwQUMnfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICcxMi4xMiBcdTIwQUMnfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBza3U6IDIsIGxhYmVsOiBcIlhTXCIsIHByaWNlOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnMjIuMTIgXHUyMEFDJ30sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnMjIuMTIgXHUyMEFDJ31cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2t1OiAzLCBsYWJlbDogXCJTXCIsIHByaWNlOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnMzIuMTIgXHUyMEFDJ30sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnMzIuMTIgXHUyMEFDJ31cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2t1OiA0LCBsYWJlbDogXCJMXCIsIHByaWNlOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnNDIuMTIgXHUyMEFDJ30sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnNDIuMTIgXHUyMEFDJ31cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF1cblxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBcImlkXCI6IDIwLFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJuYW1lXCI6IFwiWWVzc2V5IVwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJlbnJpY2htZW50XCI6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXJpYW50czogW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBza3U6IDEsIGxhYmVsOiBcIlhYU1wiLCBwcmljZTogW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt2azogJzEyLjEyIFx1MjBBQyd9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt2azogJzEyLjEyIFx1MjBBQyd9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNrdTogMiwgbGFiZWw6IFwiWFNcIiwgcHJpY2U6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICcyMi4xMiBcdTIwQUMnfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICcyMi4xMiBcdTIwQUMnfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBza3U6IDMsIGxhYmVsOiBcIlNcIiwgcHJpY2U6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICczMi4xMiBcdTIwQUMnfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICczMi4xMiBcdTIwQUMnfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBza3U6IDQsIGxhYmVsOiBcIkxcIiwgcHJpY2U6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICc0Mi4xMiBcdTIwQUMnfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICc0Mi4xMiBcdTIwQUMnfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBsZXQgY2FsbGJhY2sgPSBmdW5jdGlvbiAoc3ViamVjdCkge1xuICAgICAgICAgICAgICAgIGxldCBtID0gbmV3IE1hcDtcblxuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW2ksIGJdIG9mIE9iamVjdC5lbnRyaWVzKHN1YmplY3QuZGF0YSkpIHtcblxuICAgICAgICAgICAgICAgICAgICBsZXQga2V5MSA9IGk7XG5cbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBbaiwgY10gb2YgT2JqZWN0LmVudHJpZXMoYi5lbnJpY2htZW50LnZhcmlhbnRzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGtleTIgPSBqO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IFtrLCBkXSBvZiBPYmplY3QuZW50cmllcyhjLnByaWNlKSkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGtleTMgPSBrO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZC5uYW1lID0gYi5uYW1lO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQubGFiZWwgPSBjLmxhYmVsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQuaWQgPSBba2V5MSwga2V5Miwga2V5M10uam9pbignLicpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbS5zZXQoZC5pZCwgZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gbTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGV0IG1hcCA9IGJ1aWxkTWFwKG9iaiwgY2FsbGJhY2ssICcke25hbWV9ICR7bGFiZWx9JywgJyR7aWR9JylcbiAgICAgICAgICAgIGxldCBpID0gY29udmVydE1hcFJlc3VsdChtYXApO1xuXG4gICAgICAgICAgICBleHBlY3QoSlNPTi5zdHJpbmdpZnkoaSkpLnRvLmJlLmVxdWFsKCd7XCIwLjAuMFwiOlwiQ2Fzc2FuZHJhIFhYU1wiLFwiMC4wLjFcIjpcIkNhc3NhbmRyYSBYWFNcIixcIjAuMS4wXCI6XCJDYXNzYW5kcmEgWFNcIixcIjAuMS4xXCI6XCJDYXNzYW5kcmEgWFNcIixcIjAuMi4wXCI6XCJDYXNzYW5kcmEgU1wiLFwiMC4yLjFcIjpcIkNhc3NhbmRyYSBTXCIsXCIwLjMuMFwiOlwiQ2Fzc2FuZHJhIExcIixcIjAuMy4xXCI6XCJDYXNzYW5kcmEgTFwiLFwiMS4wLjBcIjpcIlllc3NleSEgWFhTXCIsXCIxLjAuMVwiOlwiWWVzc2V5ISBYWFNcIixcIjEuMS4wXCI6XCJZZXNzZXkhIFhTXCIsXCIxLjEuMVwiOlwiWWVzc2V5ISBYU1wiLFwiMS4yLjBcIjpcIlllc3NleSEgU1wiLFwiMS4yLjFcIjpcIlllc3NleSEgU1wiLFwiMS4zLjBcIjpcIlllc3NleSEgTFwiLFwiMS4zLjFcIjpcIlllc3NleSEgTFwifScpO1xuXG4gICAgICAgIH0pXG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCdidWlsZCBzdWJtYXAgd2l0aCAqJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnZGVmaW5pdGlvbiBzaG91bGQgcmV0dXJuIHtcIjEwXCI6XCJDYXNzYW5kcmEgMTBcIixcIjIwXCI6XCJZZXNzZXkhIDIwXCJ9JywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBsZXQgb2JqID0ge1xuICAgICAgICAgICAgICAgIFwiZGF0YVwiOiBbXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiaWRcIjogMTAsXG4gICAgICAgICAgICAgICAgICAgICAgICBcIm5hbWVcIjogXCJDYXNzYW5kcmFcIlxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBcImlkXCI6IDIwLFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJuYW1lXCI6IFwiWWVzc2V5IVwiLFxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgbGV0IG1hcCA9IGJ1aWxkTWFwKG9iaiwgJ2RhdGEuKicsICcke25hbWV9ICR7aWR9JywgJyR7aWR9JylcbiAgICAgICAgICAgIGxldCBpID0gY29udmVydE1hcFJlc3VsdChtYXApO1xuICAgICAgICAgICAgZXhwZWN0KEpTT04uc3RyaW5naWZ5KGkpKS50by5iZS5lcXVhbCgne1wiMTBcIjpcIkNhc3NhbmRyYSAxMFwiLFwiMjBcIjpcIlllc3NleSEgMjBcIn0nKTtcblxuICAgICAgICB9KVxuICAgIH0pXG5cblxuICAgIGRlc2NyaWJlKCdidWlsZCBzdWJtYXAgd2l0aCAqKicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ2RlZmluaXRpb24gc2hvdWxkIHJldHVybiBNYXAnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIGxldCBvYmogPSB7XG4gICAgICAgICAgICAgICAgXCJkYXRhXCI6IFtcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgXCJpZFwiOiAxMCxcbiAgICAgICAgICAgICAgICAgICAgICAgIFwibmFtZVwiOiBcIkNhc3NhbmRyYVwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJlbnJpY2htZW50XCI6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXJpYW50czogW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBza3U6IDEsIGxhYmVsOiBcIlhYU1wiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpY2U6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICcxMi4xMiBcdTIwQUMnLCBpZDogMX0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnMTIuMTIgXHUyMEFDJywgaWQ6IDJ9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNrdTogMiwgbGFiZWw6IFwiWFNcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaWNlOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnMjIuMTIgXHUyMEFDJywgaWQ6IDN9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt2azogJzIyLjEyIFx1MjBBQycsIGlkOiA0fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBza3U6IDMsIGxhYmVsOiBcIlNcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaWNlOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnMzIuMTIgXHUyMEFDJywgaWQ6IDV9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt2azogJzMyLjEyIFx1MjBBQycsIGlkOiA2fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBza3U6IDQsIGxhYmVsOiBcIkxcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaWNlOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnNDIuMTIgXHUyMEFDJywgaWQ6IDd9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt2azogJzQyLjEyIFx1MjBBQycsIGlkOiA4fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiaWRcIjogMjAsXG4gICAgICAgICAgICAgICAgICAgICAgICBcIm5hbWVcIjogXCJZZXNzZXkhXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBcImVucmljaG1lbnRcIjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhcmlhbnRzOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNrdTogMSwgbGFiZWw6IFwiWFhTXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmljZTogW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt2azogJzEyLjEyIFx1MjBBQycsIGlkOiA5fSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICcxMi4xMiBcdTIwQUMnLCBpZDogMTB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNrdTogMiwgbGFiZWw6IFwiWFNcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaWNlOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnMjIuMTIgXHUyMEFDJywgaWQ6IDExfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICcyMi4xMiBcdTIwQUMnLCBpZDogMTJ9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNrdTogMywgbGFiZWw6IFwiU1wiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpY2U6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICczMi4xMiBcdTIwQUMnLCBpZDogMTN9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt2azogJzMyLjEyIFx1MjBBQycsIGlkOiAxNH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2t1OiA0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw6IFwiTFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpY2U6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dms6ICc0Mi4xMiBcdTIwQUMnLCBpZDogMTV9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt2azogJzQyLjEyIFx1MjBBQycsIGlkOiAxNn0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZrOiAnNDQuMTIgXHUyMEFDJywgaWQ6IDE3fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBsZXQgbWFwID0gYnVpbGRNYXAob2JqLCAnZGF0YS4qLmVucmljaG1lbnQudmFyaWFudHMuKi5wcmljZS4qJywgJyR7dmt9ICR7Xi5sYWJlbH0gJHteLl4ubmFtZX0nLCAnJHteLl4uc2t1fScpXG4gICAgICAgICAgICBsZXQgaSA9IGNvbnZlcnRNYXBSZXN1bHQobWFwKTtcbiAgICAgICAgICAgIGV4cGVjdChKU09OLnN0cmluZ2lmeShpKSkudG8uYmUuZXF1YWwoJ3tcImRhdGEuMC5lbnJpY2htZW50LnZhcmlhbnRzLjAucHJpY2UuMFwiOlwiMTIuMTIgXHUyMEFDIFhYUyBDYXNzYW5kcmFcIixcImRhdGEuMC5lbnJpY2htZW50LnZhcmlhbnRzLjAucHJpY2UuMVwiOlwiMTIuMTIgXHUyMEFDIFhYUyBDYXNzYW5kcmFcIixcImRhdGEuMC5lbnJpY2htZW50LnZhcmlhbnRzLjEucHJpY2UuMFwiOlwiMjIuMTIgXHUyMEFDIFhTIENhc3NhbmRyYVwiLFwiZGF0YS4wLmVucmljaG1lbnQudmFyaWFudHMuMS5wcmljZS4xXCI6XCIyMi4xMiBcdTIwQUMgWFMgQ2Fzc2FuZHJhXCIsXCJkYXRhLjAuZW5yaWNobWVudC52YXJpYW50cy4yLnByaWNlLjBcIjpcIjMyLjEyIFx1MjBBQyBTIENhc3NhbmRyYVwiLFwiZGF0YS4wLmVucmljaG1lbnQudmFyaWFudHMuMi5wcmljZS4xXCI6XCIzMi4xMiBcdTIwQUMgUyBDYXNzYW5kcmFcIixcImRhdGEuMC5lbnJpY2htZW50LnZhcmlhbnRzLjMucHJpY2UuMFwiOlwiNDIuMTIgXHUyMEFDIEwgQ2Fzc2FuZHJhXCIsXCJkYXRhLjAuZW5yaWNobWVudC52YXJpYW50cy4zLnByaWNlLjFcIjpcIjQyLjEyIFx1MjBBQyBMIENhc3NhbmRyYVwiLFwiZGF0YS4xLmVucmljaG1lbnQudmFyaWFudHMuMC5wcmljZS4wXCI6XCIxMi4xMiBcdTIwQUMgWFhTIFllc3NleSFcIixcImRhdGEuMS5lbnJpY2htZW50LnZhcmlhbnRzLjAucHJpY2UuMVwiOlwiMTIuMTIgXHUyMEFDIFhYUyBZZXNzZXkhXCIsXCJkYXRhLjEuZW5yaWNobWVudC52YXJpYW50cy4xLnByaWNlLjBcIjpcIjIyLjEyIFx1MjBBQyBYUyBZZXNzZXkhXCIsXCJkYXRhLjEuZW5yaWNobWVudC52YXJpYW50cy4xLnByaWNlLjFcIjpcIjIyLjEyIFx1MjBBQyBYUyBZZXNzZXkhXCIsXCJkYXRhLjEuZW5yaWNobWVudC52YXJpYW50cy4yLnByaWNlLjBcIjpcIjMyLjEyIFx1MjBBQyBTIFllc3NleSFcIixcImRhdGEuMS5lbnJpY2htZW50LnZhcmlhbnRzLjIucHJpY2UuMVwiOlwiMzIuMTIgXHUyMEFDIFMgWWVzc2V5IVwiLFwiZGF0YS4xLmVucmljaG1lbnQudmFyaWFudHMuMy5wcmljZS4wXCI6XCI0Mi4xMiBcdTIwQUMgTCBZZXNzZXkhXCIsXCJkYXRhLjEuZW5yaWNobWVudC52YXJpYW50cy4zLnByaWNlLjFcIjpcIjQyLjEyIFx1MjBBQyBMIFllc3NleSFcIixcImRhdGEuMS5lbnJpY2htZW50LnZhcmlhbnRzLjMucHJpY2UuMlwiOlwiNDQuMTIgXHUyMEFDIEwgWWVzc2V5IVwifScpO1xuXG4gICAgICAgIH0pXG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCdleGFtcGxlY29kZScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBpdCgnc2hvdWxkIGV4ZWN1dGUgZXhhbXBsZSBjb2RlJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBsZXQgb2JqID0ge1xuICAgICAgICAgICAgICAgIFwiZGF0YVwiOiBbXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiaWRcIjogMTAsXG4gICAgICAgICAgICAgICAgICAgICAgICBcIm5hbWVcIjogXCJDYXNzYW5kcmFcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiYWRkcmVzc1wiOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJzdHJlZXRcIjogXCI0OTMtNDEwNSBWdWxwdXRhdGUgU3RyZWV0XCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJjaXR5XCI6IFwiU2F1bXVyXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJ6aXBcIjogXCI1MjYyOFwiXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiaWRcIjogMjAsXG4gICAgICAgICAgICAgICAgICAgICAgICBcIm5hbWVcIjogXCJIb2xseVwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJhZGRyZXNzXCI6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcInN0cmVldFwiOiBcIjE3NjIgRWdldCBSZC5cIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImNpdHlcIjogXCJTY2h3YWxiYWNoXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJ6aXBcIjogXCI5NTIzNDBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBcImlkXCI6IDMwLFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJuYW1lXCI6IFwiR3V5XCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBcImFkZHJlc3NcIjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwic3RyZWV0XCI6IFwiOTU3LTM4OCBTb2xsaWNpdHVkaW4gQXZlbnVlXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJjaXR5XCI6IFwiUGFuY2hpXHUwMEUwXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJ6aXBcIjogXCI0MjA3MjlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgbGV0IG1hcDtcbiAgICAgICAgICAgIG1hcCA9IGJ1aWxkTWFwKG9iaiwgJ2RhdGEuKicsICcke25hbWV9ICgke2FkZHJlc3MuemlwfSAke2FkZHJlc3MuY2l0eX0pJywgJ2lkJylcbiAgICAgICAgICAgIGV4cGVjdChtYXApLnRvLmJlLmluc3RhbmNlT2YoTWFwKTtcblxuICAgICAgICAgICAgbWFwID0gYnVpbGRNYXAob2JqLCAnZGF0YS4qJywgJyR7bmFtZX0gKCR7YWRkcmVzcy56aXB9ICR7YWRkcmVzcy5jaXR5fSknKVxuICAgICAgICAgICAgZXhwZWN0KG1hcCkudG8uYmUuaW5zdGFuY2VPZihNYXApO1xuXG4gICAgICAgICAgICBtYXAgPSBidWlsZE1hcChvYmosICdkYXRhLionLCAnJHtuYW1lfSAoJHthZGRyZXNzLnppcH0gJHthZGRyZXNzLmNpdHl9KScsICdpZCcsIGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuICh2YWx1ZVsnaWQnXSA+PSAyMCkgPyB0cnVlIDogZmFsc2VcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICBleHBlY3QobWFwKS50by5iZS5pbnN0YW5jZU9mKE1hcCk7XG4gICAgICAgIH0pO1xuXG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCdidWlsZG1hcCgpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGxldCBvYmoxID0ge1xuICAgICAgICAgICAgZGF0YXNldDoge1xuICAgICAgICAgICAgICAgIFwiMTAwODJcIjoge1xuICAgICAgICAgICAgICAgICAgICBuYW1lOiBcIlRlc3QgMVwiLFxuICAgICAgICAgICAgICAgICAgICBhZGRyZXNzOiBcIkhlcmUgMVwiXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBcIjEwMDg0XCI6IHtcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogXCJUZXN0IDJcIixcbiAgICAgICAgICAgICAgICAgICAgYWRkcmVzczogXCJIZXJlIDJcIlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBNYXAgSW5zdGFuY2UuJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KGJ1aWxkTWFwKHt9LCAnJykpLnRvLmJlLmluc3RhbmNlT2YoTWFwKTtcbiAgICAgICAgfSk7XG5cblxuICAgICAgICBbXG4gICAgICAgICAgICBbb2JqMSwgJ2RhdGFzZXQuKicsICdhZGRyZXNzJywgJ3tcImRhdGFzZXQuMTAwODJcIjpcIkhlcmUgMVwiLFwiZGF0YXNldC4xMDA4NFwiOlwiSGVyZSAyXCJ9J10sXG4gICAgICAgICAgICBbb2JqMSwgJ3gnLCB1bmRlZmluZWQsICd7fSddLFxuICAgICAgICAgICAgW29iajEsICdkYXRhc2V0LionLCAnbmFtZScsICd7XCJkYXRhc2V0LjEwMDgyXCI6XCJUZXN0IDFcIixcImRhdGFzZXQuMTAwODRcIjpcIlRlc3QgMlwifSddLFxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYyA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGQgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ2J1aWxkTWFwKCcgKyBKU09OLnN0cmluZ2lmeShhKSArICcsJyArIEpTT04uc3RyaW5naWZ5KGIpICsgJywnICsgSlNPTi5zdHJpbmdpZnkoYykgKyAnKSBzaG91bGQgcmV0dXJuICcgKyBKU09OLnN0cmluZ2lmeShkKSArICcgJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGxldCB0ID0gYnVpbGRNYXAoYSwgYiwgYyk7XG4gICAgICAgICAgICAgICAgbGV0IG0gPSBKU09OLnN0cmluZ2lmeShjb252ZXJ0TWFwUmVzdWx0KHQpKTtcbiAgICAgICAgICAgICAgICBleHBlY3QobSkudG8uYmUuZXF1YWwoZCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cblxuICAgIH0pO1xufSk7XG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XG5cbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge1RyYW5zZm9ybWVyfSBmcm9tIFwiLi4vLi4vLi4vc291cmNlL2RhdGEvdHJhbnNmb3JtZXIubWpzXCI7XG5pbXBvcnQge0VtYmVkfSBmcm9tIFwiLi4vLi4vLi4vc291cmNlL2kxOG4vcHJvdmlkZXJzL2VtYmVkLm1qc1wiO1xuaW1wb3J0IHtpbml0SlNET019IGZyb20gXCIuLi8uLi91dGlsL2pzZG9tLm1qc1wiO1xuXG5kZXNjcmliZSgnVHJhbnNmb3JtZXInLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBiZWZvcmUoZnVuY3Rpb24gKGRvbmUpIHtcblxuICAgICAgICBsZXQgcHJvbWlzZXMgPSBbXVxuICAgICAgICBwcm9taXNlcy5wdXNoKGluaXRKU0RPTSgpKTtcbiAgICAgICAgaWYgKCFnbG9iYWxUaGlzWydjcnlwdG8nXSkge1xuICAgICAgICAgICAgcHJvbWlzZXMucHVzaChpbXBvcnQoXCJAcGVjdWxpYXIvd2ViY3J5cHRvXCIpLnRoZW4obSA9PiB7XG4gICAgICAgICAgICAgICAgZ2xvYmFsVGhpc1snY3J5cHRvJ10gPSBuZXcgbS5DcnlwdG8oKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH0pKVxuICAgICAgICB9XG5cbiAgICAgICAgUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgZG9uZSgpXG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cblxuICAgIGRlc2NyaWJlKCdUcmFuc2Zvcm1lci5ydW4oKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBbXG4gICAgICAgICAgICBbJ2RhdGV0aW1lZm9ybWF0JywgXCIyMDIzLTAyLTA0IDA4OjAyOjAxXCIsIFwiMDQuMDIuMjAyMywgMDg6MDI6MDFcIl0sXG4gICAgICAgICAgICBbJ2RhdGV0aW1lZm9ybWF0Omxvbmc6c2hvcnQnLCBcIjIwMjMtMDItMDQgMDg6MDI6MDFcIixcIjQuIEZlYnJ1YXIgMjAyMyB1bSAwODowMlwiXSxcbiAgICAgICAgICAgIFsnZGF0ZXRpbWVmb3JtYXQ6c2hvcnQ6c2hvcnQnLCBcIjIwMjMtMDItMDQgMDg6MDI6MDFcIiwgXCIwNC4wMi4yMywgMDg6MDJcIl0sXG4gICAgICAgICAgICBbJ2VxdWFsczphJywgXCJhXCIsIHRydWVdLFxuICAgICAgICAgICAgWydlcXVhbHM6YScsIFwiYlwiLCBmYWxzZV0sXG4gICAgICAgICAgICBbJ2VxdWFsczozJywgMywgdHJ1ZV0sXG4gICAgICAgICAgICBbJ2VxdWFsczozJywgNiwgZmFsc2VdLFxuICAgICAgICAgICAgWydlcXVhbHM6b24nLCB0cnVlLCB0cnVlXSxcbiAgICAgICAgICAgIFsnZXF1YWxzOnRydWUnLCB0cnVlLCB0cnVlXSxcbiAgICAgICAgICAgIFsnZXF1YWxzOm9uJywgZmFsc2UsIGZhbHNlXSxcbiAgICAgICAgICAgIFsnZXF1YWxzOnRydWUnLCBmYWxzZSwgZmFsc2VdLFxuICAgICAgICAgICAgWydlcXVhbHM6b2ZmJywgZmFsc2UsIHRydWVdLFxuICAgICAgICAgICAgWydlcXVhbHM6ZmFsc2UnLCBmYWxzZSwgdHJ1ZV0sXG4gICAgICAgICAgICBbJ2VxdWFsczpvZmYnLCBmYWxzZSwgdHJ1ZV0sXG4gICAgICAgICAgICBbJ2VxdWFsczpmYWxzZScsIHRydWUsIGZhbHNlXSxcbiAgICAgICAgICAgIFsnZXF1YWxzOjMnLCAzLCB0cnVlXSxcbiAgICAgICAgICAgIFsnZXF1YWxzOjMnLCA2LCBmYWxzZV0sXG4gICAgICAgICAgICBbJ2VxdWFsczp1bmRlZmluZWQnLCB1bmRlZmluZWQsIHRydWVdLFxuICAgICAgICAgICAgWydlcXVhbHM6dW5kZWZpbmVkJywgMywgZmFsc2VdLFxuICAgICAgICAgICAgWydlcXVhbHM6bnVsbCcsIG51bGwsIHRydWVdLFxuICAgICAgICAgICAgWydlcXVhbHM6bnVsbCcsIDMsIGZhbHNlXSxcbiAgICAgICAgICAgIFsnZXF1YWxzOjMnLCA2LCBmYWxzZV0sXG4gICAgICAgICAgICBbJ2N1cnJlbmN5JywgXCJFVVIwXCIsIFwiMCwwMFx1MDBBMFx1MjBBQ1wiXSxcbiAgICAgICAgICAgIFsnY3VycmVuY3k6MToyJywgXCJFVVIxNC4yNVwiLCBcIjE0LDJcdTAwQTBcdTIwQUNcIl0sIFxuICAgICAgICAgICAgWydjdXJyZW5jeScsIFwiRVVSMTQuMjVcIiwgXCIxNCwyNVx1MDBBMFx1MjBBQ1wiXSxcbiAgICAgICAgICAgIFsnZGF0ZXRpbWUnLCBcIjIwMjMtMDItMTQgMTQ6MTI6MTBcIiwgXCIxNC4yLjIwMjMsIDE0OjEyOjEwXCJdLFxuICAgICAgICAgICAgWydkYXRldGltZScsIFwiMjAyMy0wMi0xNCAwODowMjowMVwiLCBcIjE0LjIuMjAyMywgMDg6MDI6MDFcIl0sXG4gICAgICAgICAgICBbJ2hhcy1lbnRyaWVzJywge30sIGZhbHNlXSxcbiAgICAgICAgICAgIFsnaGFzLWVudHJpZXMnLCB7YTo0fSwgdHJ1ZV0sXG4gICAgICAgICAgICBbJ2hhcy1lbnRyaWVzJywgW10sIGZhbHNlXSxcbiAgICAgICAgICAgIFsnaGFzLWVudHJpZXMnLCBcIlwiLCBmYWxzZV0sXG4gICAgICAgICAgICBbJ2hhcy1lbnRyaWVzJywgWzEsMiwzXSwgdHJ1ZV0sXG4gICAgICAgICAgICBbJ2hhcy1lbnRyaWVzJywgWzFdLCB0cnVlXSxcbiAgICAgICAgICAgIFsnaGFzLWVudHJpZXMnLCBbXCIxXCJdLCB0cnVlXSxcbiAgICAgICAgICAgIFsnaGFzLWVudHJpZXMnLCBbdHJ1ZV0sIHRydWVdLFxuICAgICAgICAgICAgWydjb250YWluczp4JywgXCJhc2Qgd3hkIHNkZlwiLCB0cnVlXSxcbiAgICAgICAgICAgIFsnY29udGFpbnM6eCcsIFwiYXNkIHdkIHNkZlwiLCBmYWxzZV0sXG4gICAgICAgICAgICBbJ2NvbnRhaW5zOmInLCBbXCJhXCIsXCJiXCIsXCJjXCJdLCB0cnVlXSxcbiAgICAgICAgICAgIFsnY29udGFpbnM6eCcsIFtcImFcIixcImJcIixcImNcIl0sIGZhbHNlXSxcbiAgICAgICAgICAgIFsnaXN1bmRlZmluZWQnLCBcImFcIiwgZmFsc2VdLFxuICAgICAgICAgICAgWydpc3VuZGVmaW5lZCcsIG51bGwsIGZhbHNlXSxcbiAgICAgICAgICAgIFsnaXN1bmRlZmluZWQnLCB1bmRlZmluZWQsIHRydWVdLFxuICAgICAgICAgICAgWydpc251bGwnLCBcImFcIiwgZmFsc2VdLFxuICAgICAgICAgICAgWydpc251bGwnLCBudWxsLCB0cnVlXSxcbiAgICAgICAgICAgIFsnaXNzZXQnLCBudWxsLCBmYWxzZV0sXG4gICAgICAgICAgICBbJ2lzc2V0JywgdW5kZWZpbmVkLCBmYWxzZV0sXG4gICAgICAgICAgICBbJ2lzc2V0JywgXCJcIiwgdHJ1ZV0sXG4gICAgICAgICAgICBbJ2lzbnVtYmVyJywgXCJhXCIsIGZhbHNlXSxcbiAgICAgICAgICAgIFsnaXNudW1iZXInLCA0LCB0cnVlXSxcbiAgICAgICAgICAgIFsnaXNudW1iZXInLCA0LjUsIHRydWVdLFxuICAgICAgICAgICAgWydpc2ludGVnZXInLCA0LjUsIGZhbHNlXSxcbiAgICAgICAgICAgIFsnaXNpbnRlZ2VyJywgNCwgdHJ1ZV0sXG4gICAgICAgICAgICBbJ2lzZmxvYXQnLCA1LjYsIHRydWVdLFxuICAgICAgICAgICAgWydpc2Zsb2F0JywgNSwgZmFsc2VdLFxuICAgICAgICAgICAgWydpc29iamVjdCcsIDQsIGZhbHNlXSxcbiAgICAgICAgICAgIFsnaXNvYmplY3QnLCB7fSwgdHJ1ZV0sXG4gICAgICAgICAgICBbJ2lzYXJyYXknLCBbe31dLCB0cnVlXSxcbiAgICAgICAgICAgIFsnaXNhcnJheScsIFwiYVwiLCBmYWxzZV0sXG4gICAgICAgICAgICBbJ25vdCcsIHRydWUsIGZhbHNlXSxcbiAgICAgICAgICAgIFsnbm90JywgZmFsc2UsIHRydWVdLFxuICAgICAgICAgICAgWydtYXA6YT00OmI9NTpjPTYnLCBcImFcIiwgXCI0XCJdLFxuICAgICAgICAgICAgWydkYXRlJywgXCIyMDIzLTAyLTE0XCIsIFwiMTQuMi4yMDIzXCJdLFxuICAgICAgICAgICAgWyd5ZWFyJywgXCIyMDIzLTAyLTE0XCIsIDIwMjNdLFxuICAgICAgICAgICAgWydtb250aCcsIFwiMjAyMy0wMi0xNFwiLCAyXSxcbiAgICAgICAgICAgIFsnZGF5JywgXCIyMDIzLTAyLTE0XCIsIDE0XSxcbiAgICAgICAgICAgIFsnd2Vla2RheScsIFwiMjAyMy0wMi0xNFwiLCAyXSxcbiAgICAgICAgICAgIFsnbWludXRlcycsIFwiMjAyMy0wMi0xNCAwNjoxMjoyMVwiLCAxMl0sXG4gICAgICAgICAgICBbJ3NlY29uZHMnLCBcIjIwMjMtMDItMTQgMDY6MTI6MjFcIiwgMjFdLFxuICAgICAgICAgICAgWydob3VycycsIFwiMjAyMy0wMi0xNCAwNjoxMjoyMVwiLCA2XSxcbiAgICAgICAgICAgIFsndGltZScsIFwiMjAyMy0wMi0xNCAwNjoxMjoyMVwiLCBcIjA2OjEyOjIxXCJdLFxuICAgICAgICAgICAgWyd0aW1lc3RhbXAnLCBcIjIwMjMtMDItMTRcIiwgMTY3NjMzMjgwMDAwMF0sXG4gICAgICAgICAgICBbJ2NvbmNhdDphLmIuYzp0ZXN0OmEuYi5kJywge2E6IHtiOiB7YzogNCwgZDogNn19fSwgXCI0dGVzdDZcIl0sXG4gICAgICAgICAgICBbJ2NvbmNhdDphLmIuYzpcXFxcIFxcXFwgOmEuYi5kJywge2E6IHtiOiB7YzogNCwgZDogNn19fSwgXCI0ICA2XCJdLFxuICAgICAgICAgICAgWydjb25jYXQ6YS5iLmM6LDphLmIuZCcsIHthOiB7Yjoge2M6IDQsIGQ6IDZ9fX0sIFwiNCw2XCJdLFxuICAgICAgICAgICAgWydjb25jYXQ6YS5iLmM6LDpcXFxcIDphLmIuZCcsIHthOiB7Yjoge2M6IDQsIGQ6IDZ9fX0sIFwiNCwgNlwiXSxcbiAgICAgICAgICAgIFsnPz86YScsIG51bGwsICdhJ10sXG4gICAgICAgICAgICBbJz8/OmEnLCB1bmRlZmluZWQsICdhJ10sXG4gICAgICAgICAgICBbJz8/OmEnLCAndHJ1ZScsICd0cnVlJ10sXG4gICAgICAgICAgICBbJz8/OmEnLCBmYWxzZSwgZmFsc2VdLFxuICAgICAgICAgICAgWycgaWY6YTogJywgZmFsc2UsIHVuZGVmaW5lZF0sIC8vIHdpdGhvdXQgXFxcXFxuICAgICAgICAgICAgWycgaWY6YTpcXFxcICcsIGZhbHNlLCBcIiBcIl0sXG4gICAgICAgICAgICBbJyBpZjphOlxcXFwgJywgdHJ1ZSwgXCJhXCJdLFxuICAgICAgICAgICAgWydkZWZhdWx0OnllcycsIG51bGwsICd5ZXMnXSxcbiAgICAgICAgICAgIFsnZGVmYXVsdDp5ZXMnLCB1bmRlZmluZWQsICd5ZXMnXSxcbiAgICAgICAgICAgIFsnZGVmYXVsdDoxOmJvb2wnLCB1bmRlZmluZWQsIHRydWVdLFxuICAgICAgICAgICAgWydkZWZhdWx0Om9uOmJvb2wnLCB1bmRlZmluZWQsIHRydWVdLFxuICAgICAgICAgICAgWydkZWZhdWx0OnRydWU6Ym9vbCcsIHVuZGVmaW5lZCwgdHJ1ZV0sXG4gICAgICAgICAgICBbJ2RlZmF1bHQ6eWVzOmJvb2wnLCB1bmRlZmluZWQsIHRydWVdLFxuICAgICAgICAgICAgWydkZWZhdWx0OnVuZGVmaW5lZDpib29sJywgdW5kZWZpbmVkLCBmYWxzZV0sXG4gICAgICAgICAgICBbJ2RlZmF1bHQ6ZmFsc2U6Ym9vbCcsIHVuZGVmaW5lZCwgZmFsc2VdLFxuICAgICAgICAgICAgWydkZWZhdWx0OjE6aW50JywgdW5kZWZpbmVkLCAxXSxcbiAgICAgICAgICAgIFsnZGVmYXVsdDoxOnN0cmluZycsIHVuZGVmaW5lZCwgJzEnXSxcbiAgICAgICAgICAgIFsnZmlyc3Qta2V5Jywge2E6IDEsIGM6IDMsIGI6IDJ9LCAxXSxcbiAgICAgICAgICAgIFsnbGFzdC1rZXknLCB7YTogMSwgYzogMywgYjogMn0sIDNdLFxuICAgICAgICAgICAgWydudGgtbGFzdC1rZXk6MCcsIHthOiAxLCBjOiAzLCBiOiAyfSwgM10sXG4gICAgICAgICAgICBbJ250aC1sYXN0LWtleToxJywge2E6IDEsIGM6IDMsIGI6IDJ9LCAyXSxcbiAgICAgICAgICAgIFsnbnRoLWxhc3Qta2V5OjInLCB7YTogMSwgYzogMywgYjogMn0sIDFdLFxuICAgICAgICAgICAgWydudGgta2V5OjInLCB7YTogMSwgYjogMiwgYzogM30sIDNdLFxuICAgICAgICAgICAgWydudGgta2V5OjAnLCB7YzogMywgYTogMSwgYjogMn0sIDFdLFxuICAgICAgICAgICAgWydudGgta2V5OjInLCB7YTogMSwgYzogMywgYjogMn0sIDNdLFxuICAgICAgICAgICAgWydwcmVmaXg6SGVsbG9cXFxcICcsICd0ZXN0JywgXCJIZWxsbyB0ZXN0XCJdLFxuICAgICAgICAgICAgWyd0b2pzb24nLCB7YTogNH0sIFwie1xcXCJhXFxcIjo0fVwiXSxcbiAgICAgICAgICAgIFsncHJlZml4OmFcXFxcXFxcXDogJywgJ3Rlc3QnLCBcImFcXFxcdGVzdFwiXSxcbiAgICAgICAgICAgIFsncHJlZml4OmFcXFxcICcsICd0ZXN0JywgXCJhIHRlc3RcIl0sXG4gICAgICAgICAgICBbJ3N0YXRpYzphYmM6YTpiOngnLCBcInRlc3RcIiwgXCJhYmM6YTpiOnhcIl0sXG4gICAgICAgICAgICBbJ3RvbG93ZXJjYXNlJywgXCJBOmI6Q3NlNFwiLCBcImE6Yjpjc2U0XCJdLFxuICAgICAgICAgICAgWyd0b3VwcGVyJywgXCJBOmI6Q3NlNFwiLCBcIkE6QjpDU0U0XCJdLFxuICAgICAgICAgICAgWyd0b3N0cmluZycsIDUsIFwiNVwiXSxcbiAgICAgICAgICAgIFsndG9zdHJpbmcnLCBbMSwgMiwgMywge31dLCBcIjEsMiwzLFtvYmplY3QgT2JqZWN0XVwiXSxcbiAgICAgICAgICAgIFsndG9pbnRlZ2VyJywgXCI1XCIsIDVdLFxuICAgICAgICAgICAgWyd0cmltJywgXCIgNSBcIiwgXCI1XCJdLFxuICAgICAgICAgICAgWyd0cmltJywgXCIgYVwiLCBcImFcIl0sXG4gICAgICAgICAgICBbJ3RyaW0nLCBcIiBcIiwgXCJcIl0sXG4gICAgICAgICAgICBbJ3Jhd3VybGVuY29kZScsIFwiXHUwMEZDXHUwMEY2XHUwMEU0XCIsIFwiJUMzJUJDJUMzJUI2JUMzJUE0XCJdLFxuICAgICAgICAgICAgWydjYWxsOnRlc3RjYWxsYmFjazo0OjU6NicsIFwidGVzdFwiLCBcInRlc3Q0NTZcIl0sXG4gICAgICAgICAgICBbJ3BsYWluJywgJ3Q8YnI+ZXN0JywgXCJ0ZXN0XCJdLFxuICAgICAgICAgICAgWydpZjphOmInLCB0cnVlLCBcImFcIl0sXG4gICAgICAgICAgICBbJ2lmOmE6YicsICdvbicsIFwiYVwiXSxcbiAgICAgICAgICAgIFsnaWY6YTpiJywgJ3RydWUnLCBcImFcIl0sXG4gICAgICAgICAgICBbJ2lmOmE6YicsICdmYWxzZScsIFwiYlwiXSxcbiAgICAgICAgICAgIFsnaWY6YTpiJywgOSwgXCJhXCJdLFxuICAgICAgICAgICAgWydpZjphOmInLCAnJywgXCJiXCJdLFxuICAgICAgICAgICAgWydpZjphOmInLCB1bmRlZmluZWQsIFwiYlwiXSxcbiAgICAgICAgICAgIFsnaWY6YTpiJywgZmFsc2UsIFwiYlwiXSxcbiAgICAgICAgICAgIFsndWNmaXJzdCcsICdjYXInLCBcIkNhclwiXSxcbiAgICAgICAgICAgIFsndWNmaXJzdCcsICdjQXInLCBcIkNBclwiXSxcbiAgICAgICAgICAgIFsnZGVmYXVsdDp0ZXN0JywgJ2EnLCBcImFcIl0sXG4gICAgICAgICAgICBbJ2RlZmF1bHQ6dGVzdCcsIHVuZGVmaW5lZCwgXCJ0ZXN0XCJdLFxuICAgICAgICAgICAgWydmcm9tanNvbicsICd7fScsIHt9XSxcbiAgICAgICAgICAgIFsnZnJvbWpzb24nLCAne1wiYVwiOjF9Jywge2E6IDF9XSxcbiAgICAgICAgICAgIFsndWN3b3JkcycsICdjQXIgcnVucycsIFwiQ0FyIFJ1bnNcIl0sXG4gICAgICAgICAgICBbJ3RvaW50ZWdlcicsICc2JywgNl0sXG4gICAgICAgICAgICBbJ2xlbmd0aCcsICd0ZXN0JywgNF0sXG4gICAgICAgICAgICBbJ3RvLWJhc2U2NCcsICdIZWxsbyBXb3JsZCEnLCBcIlNHVnNiRzhnVjI5eWJHUWhcIl0sXG4gICAgICAgICAgICBbJ2Zyb20tYmFzZTY0JywgJ1NHVnNiRzhnVjI5eWJHUWgnLCBcIkhlbGxvIFdvcmxkIVwiXSxcbiAgICAgICAgICAgIFsndG8tYmFzZTY0JywgJ3Rlc3QnLCBcImRHVnpkQT09XCJdLFxuICAgICAgICAgICAgWydmcm9tLWJhc2U2NCcsIFwiZEdWemRBPT1cIiwgJ3Rlc3QnXSxcbiAgICAgICAgICAgIFsncHJlZml4OmEnLCAndGVzdCcsIFwiYXRlc3RcIl0sXG4gICAgICAgICAgICBbJ3N1ZmZpeDphJywgJ3Rlc3QnLCBcInRlc3RhXCJdLFxuICAgICAgICAgICAgWydpbmRleDphJywge2E6IDR9LCA0XSxcbiAgICAgICAgICAgIFsnaW5kZXg6MicsIFsyLCA0LCA3XSwgN10sXG4gICAgICAgICAgICBbJ2luZGV4Ong6dGVzdCcsIFsyLCA0LCA3XSwgJ3Rlc3QnXSxcbiAgICAgICAgICAgIFsncGF0aDphLmIuYycsIHthOiB7Yjoge2M6IDR9fX0sIDRdLFxuICAgICAgICAgICAgWydwYXRoOmEuYi5kJywge2E6IHtiOiB7YzogNH19fSwgdW5kZWZpbmVkXSxcbiAgICAgICAgICAgIFsnaW5kZXg6YScsIG5ldyBNYXAoKS5zZXQoJ2EnLCA1KSwgNV0sXG4gICAgICAgICAgICBbJ3N1YnN0cmluZzoyOjQnLCAnYWJjZGVmZ2hpamtsbW5vcCcsICdjZGVmJ10sXG4gICAgICAgICAgICBbJ25vcCcsICdhYmNkZWZnaGlqa2xtbm9wJywgJ2FiY2RlZmdoaWprbG1ub3AnXSxcblxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYyA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpdCgnVHJhbnNmb3JtZXIucnVuKCcgKyBKU09OLnN0cmluZ2lmeShhKSArICcpLnJ1bignICsgSlNPTi5zdHJpbmdpZnkoYikgKyAnKSBzaG91bGQgcmV0dXJuICcgKyBKU09OLnN0cmluZ2lmeShjKSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGxldCB0ID0gbmV3IFRyYW5zZm9ybWVyKGEpO1xuXG4gICAgICAgICAgICAgICAgdC5zZXRDYWxsYmFjaygndGVzdGNhbGxiYWNrJywgZnVuY3Rpb24gKGEsIGIsIGMsIGQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGEgKyBiICsgYyArIGQ7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICBjb25zdCByID0gdC5ydW4oYik7XG4gICAgICAgICAgICAgICAgZXhwZWN0KHIpLnRvLmJlLmVxbChjKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ1RyYW5zZm9ybWVyLnJ1bigpIHRocm93cyBFcnJvcicsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBbXG4gICAgICAgICAgICBbJ3RvbG93ZXJjYXNlJywgW11dLFxuICAgICAgICAgICAgWyd0b2xvd2VyY2FzZScsIHt9XSxcbiAgICAgICAgICAgIFsndG9sb3dlcmNhc2UnLCA0LjVdLFxuICAgICAgICAgICAgWyd0b3VwcGVyJywgdHJ1ZV0sXG4gICAgICAgICAgICBbJ3RvdXBwZXInLCA1XSxcbiAgICAgICAgICAgIFsndG9pbnRlZ2VyJywgXCJhXCJdLFxuICAgICAgICAgICAgWyd0cmltJywgNV0sXG4gICAgICAgICAgICBbJ3RyaW0nLCB0cnVlXSxcbiAgICAgICAgICAgIFsndHJpbScsIHt9XSxcbiAgICAgICAgICAgIFsndHJpbScsIFtdXSxcbiAgICAgICAgICAgIFsncmF3dXJsZW5jb2RlJywgW11dLFxuICAgICAgICAgICAgWydpZjphOmInLCB7fV0sXG4gICAgICAgICAgICBbJ3Vjd29yZHMnLCB7fV0sXG4gICAgICAgICAgICBbJ3Vjd29yZHMnLCBmYWxzZV0sXG4gICAgICAgICAgICBbJ3Vjd29yZHMnLCA0XSxcbiAgICAgICAgICAgIFsncGF0aDphLmIuYycsIFwiXCIsIDRdLFxuICAgICAgICAgICAgWyd0b2ludGVnZXInLCB7fV0sXG4gICAgICAgICAgICBbJ2Jhc2U2NCcsIHt9XSxcbiAgICAgICAgICAgIFsnZnJvbWpzb24nLCAnJ10sXG4gICAgICAgICAgICBbJ3ByZWZpeCcsIHt9XSxcbiAgICAgICAgICAgIFsnc3VmZml4Jywge31dLFxuICAgICAgICAgICAgWydpbmRleCcsIFwidGVzdFwiXSxcbiAgICAgICAgICAgIFsneHh4eHh4JywgXCJ0ZXN0XCJdLCAvLyB1bnN1cHBvcnRlZCBjb21tYW5kXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ1RyYW5zZm9ybWVyLnJ1bignICsgSlNPTi5zdHJpbmdpZnkoYSkgKyAnKS5ydW4oJyArIEpTT04uc3RyaW5naWZ5KGIpICsgJykgc2hvdWxkIHRocm93IEVycm9yICcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBsZXQgdCA9IG5ldyBUcmFuc2Zvcm1lcihhKTtcbiAgICAgICAgICAgICAgICBleHBlY3QoKCkgPT4gdC5ydW4oYikpLnRvLnRocm93KEVycm9yKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cblxuICAgIGRlc2NyaWJlKCduZXcgVHJhbnNmb3JtZXIoKS5ydW4oXCJ1bmlxaWRcIiknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIFN0cmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCB0ID0gbmV3IFRyYW5zZm9ybWVyKCd1bmlxaWQnKTtcbiAgICAgICAgICAgIGV4cGVjdCh0LnJ1bihcIlwiKSkudG8uYmUuYSgnc3RyaW5nJyk7XG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnbmV3IFRyYW5zZm9ybWVyKCkucnVuKFwiZGVmYXVsdDpleUppSWpveGZRPT06b2JqZWN0XCIpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBPYmplY3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgdCA9IG5ldyBUcmFuc2Zvcm1lcignZGVmYXVsdDpleUppSWpveGZRPT06b2JqZWN0Jyk7XG4gICAgICAgICAgICBleHBlY3QodC5ydW4odW5kZWZpbmVkKSkudG8uZXFsKHtiOiAxfSk7XG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cblxuICAgIGRlc2NyaWJlKCduZXcgVHJhbnNmb3JtZXIoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gaW5zdGFuY2VvZiBUcmFuc2Zvcm1lcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgVHJhbnNmb3JtZXIoXCJcIikpLnRvLmluc3RhbmNlT2YoVHJhbnNmb3JtZXIpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBpbnN0YW5jZW9mIFRyYW5zZm9ybWVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KG5ldyBUcmFuc2Zvcm1lcihcInN1ZmZpeDphYmNcIikpLnRvLmluc3RhbmNlT2YoVHJhbnNmb3JtZXIpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnZmFsc2UgYXMgYXJndW1lbnQgc2hvdWxkIHRocm93IFR5cGVFcnJvcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgbmV3IFRyYW5zZm9ybWVyKGZhbHNlKVxuICAgICAgICAgICAgfSkudG8udGhyb3coVHlwZUVycm9yKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ29iamVjdCBhcyBhcmd1bWVudCBzaG91bGQgdGhyb3cgVHlwZUVycm9yJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KCgpID0+IHtcbiAgICAgICAgICAgICAgICBuZXcgVHJhbnNmb3JtZXIoe30pXG4gICAgICAgICAgICB9KS50by50aHJvdyhUeXBlRXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuXG4gICAgZGVzY3JpYmUoJ2kxOG4nLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgbGV0IGh0bWwxID0gYFxuPGRpdiBpZD1cIm1vY2stdHJhbnNsYXRpb25zXCI+PC9kaXY+XG48c2NyaXB0IHR5cGU9XCJhcHBsaWNhdGlvbi9qc29uXCIgZGF0YS1tb25zdGVyLXJvbGU9XCJ0cmFuc2xhdGlvbnNcIj5cbiAgICB7XG4gICAgICAgIFwidGVzdDFcIjogXCJ4eXpcIixcbiAgICAgICAgXCJ0ZXN0M1wiOiB7XG4gICAgICAgICAgICBcIm90aGVyXCI6IFwieHl6XCJcbiAgICAgICAgfVxuICAgIH1cbjwvc2NyaXB0PiAgXG5gO1xuXG4gICAgICAgIGJlZm9yZUVhY2goKGRvbmUpID0+IHtcbiAgICAgICAgICAgIGxldCBtb2NrcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpO1xuICAgICAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gaHRtbDE7XG4gICAgICAgICAgICBsZXQgZWxlbSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrLXRyYW5zbGF0aW9ucycpO1xuICAgICAgICAgICAgRW1iZWQuYXNzaWduVHJhbnNsYXRpb25zVG9FbGVtZW50KGVsZW0pLnRoZW4oKG8pID0+IHtcbiAgICAgICAgICAgICAgICBkb25lKClcbiAgICAgICAgICAgIH0pXG5cblxuICAgICAgICB9KVxuXG4gICAgICAgIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICAgICAgICBsZXQgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgICAgIG1vY2tzLmlubmVySFRNTCA9IFwiXCI7XG4gICAgICAgIH0pXG5cbiAgICAgICAgYmVmb3JlKGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICBpbml0SlNET00oKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICBkb25lKClcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICBbXG4gICAgICAgICAgICBbJ2kxOG46dGVzdDEnLCBcIlwiLCBcInh5elwiXSxcbiAgICAgICAgICAgIFsnaTE4bjonLCBcInRlc3QxXCIsIFwieHl6XCJdLCAvLyBrZXkgYnkgdmFsdWVcbiAgICAgICAgICAgIFsnaTE4bjo6JywgXCJ0ZXN0MVwiLCBcInh5elwiXSwgLy8ga2V5IGJ5IHZhbHVlIG5vIGRlZmF1bHRcbiAgICAgICAgICAgIFsnaTE4bjo6ZWVlJywgXCJ0ZXN0MlwiLCBcImVlZVwiXSwgLy8ga2V5IGJ5IHZhbHVlIHdpdGggZGVmYXVsdFxuICAgICAgICAgICAgWydpMThuOjpkZGQnLCBcInRlc3QyXCIsIFwiZGRkXCJdLCAvLyBrZXkgYnkgdmFsdWUgYW5kIGRlZmF1bHRcblxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYyA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpdCgnc2hvdWxkIHRyYW5zZm9ybSgnICsgYSArICcpLnJ1bignICsgYiArICcpIHJldHVybiAnICsgSlNPTi5zdHJpbmdpZnkoYyksIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB0ID0gbmV3IFRyYW5zZm9ybWVyKGEpO1xuICAgICAgICAgICAgICAgIGV4cGVjdCh0LnJ1bihiKSkudG8uYmUuZXFsKGMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pXG4gICAgfSlcblxuXG59KTsiLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBpbnRlcm5hbFN5bWJvbCB9IGZyb20gXCIuLi8uLi9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQgeyBleHRlbmQgfSBmcm9tIFwiLi4vLi4vZGF0YS9leHRlbmQubWpzXCI7XG5pbXBvcnQgeyBnZXREb2N1bWVudCB9IGZyb20gXCIuLi8uLi9kb20vdXRpbC5tanNcIjtcbmltcG9ydCB7IGlzU3RyaW5nIH0gZnJvbSBcIi4uLy4uL3R5cGVzL2lzLm1qc1wiO1xuaW1wb3J0IHsgdmFsaWRhdGVPYmplY3QsIHZhbGlkYXRlU3RyaW5nIH0gZnJvbSBcIi4uLy4uL3R5cGVzL3ZhbGlkYXRlLm1qc1wiO1xuaW1wb3J0IHsgcGFyc2VMb2NhbGUgfSBmcm9tIFwiLi4vbG9jYWxlLm1qc1wiO1xuaW1wb3J0IHsgUHJvdmlkZXIgfSBmcm9tIFwiLi4vcHJvdmlkZXIubWpzXCI7XG5pbXBvcnQgeyBUcmFuc2xhdGlvbnMgfSBmcm9tIFwiLi4vdHJhbnNsYXRpb25zLm1qc1wiO1xuXG5leHBvcnQgeyBFbWJlZCB9O1xuXG4vKipcbiAqIFRoZSBFbWJlZCBwcm92aWRlciByZXRyaWV2ZXMgYSBKU09OIGZpbGUgZnJvbSB0aGUgZ2l2ZW4gU2NyaXB0IFRhZy5cbiAqXG4gKiBAZXh0ZXJuYWxFeGFtcGxlIC4uLy4uLy4uL2V4YW1wbGUvaTE4bi9wcm92aWRlcnMvZW1iZWQubWpzXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjEzLjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5JMThuLlByb3ZpZGVyc1xuICogQHNlZSB7QGxpbmsgaHR0cHM6Ly9kYXRhdHJhY2tlci5pZXRmLm9yZy9kb2MvaHRtbC9yZmMzMDY2fVxuICogQHR1dG9yaWFsIGkxOG4tbG9jYWxlLWFuZC1mb3JtYXR0ZXJcbiAqL1xuY2xhc3MgRW1iZWQgZXh0ZW5kcyBQcm92aWRlciB7XG4gICAgLyoqXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxzY3JpcHQgaWQ9XCJ0cmFuc2xhdGlvbnNcIiB0eXBlPVwiYXBwbGljYXRpb24vanNvblwiPlxuICAgICAqIHtcbiAgICAgKiAgICAgXCJoZWxsb1wiOiBcIkhhbGxvXCJcbiAgICAgKiB9XG4gICAgICogPC9zY3JpcHQ+XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKlxuICAgICAqIGBgYGphdmFzY3JpcHRcbiAgICAgKiBuZXcgRW1iZWQoJ3RyYW5zbGF0aW9ucycpXG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fHN0cmluZ30gZWxlbWVudE9ySWRcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGVsZW1lbnRPcklkLCBvcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnMpO1xuXG4gICAgICAgIGlmIChvcHRpb25zID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlbGVtZW50T3JJZCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSB7XG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIEBwcm9wZXJ0eSB7SFRNTEVsZW1lbnR8c3RyaW5nfVxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICB0aGlzLnRyYW5zbGF0ZUVsZW1lbnQgPSBlbGVtZW50T3JJZDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogQHByb3BlcnR5IHtIVE1MRWxlbWVudHxzdHJpbmd9XG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIHRoaXMudHJhbnNsYXRlRWxlbWVudCA9IGdldERvY3VtZW50KCkuZ2V0RWxlbWVudEJ5SWQodmFsaWRhdGVTdHJpbmcoZWxlbWVudE9ySWQpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAcHJpdmF0ZVxuICAgICAgICAgKiBAcHJvcGVydHkge09iamVjdH0gb3B0aW9uc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpc1tpbnRlcm5hbFN5bWJvbF0gPSBleHRlbmQoe30sIHN1cGVyLmRlZmF1bHRzLCB0aGlzLmRlZmF1bHRzLCB2YWxpZGF0ZU9iamVjdChvcHRpb25zKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGVmYXVsdHNcbiAgICAgKlxuICAgICAqIEBzZWUge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9GZXRjaF9BUEl9XG4gICAgICovXG4gICAgZ2V0IGRlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gZXh0ZW5kKHt9LCBzdXBlci5kZWZhdWx0cyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0xvY2FsZXxzdHJpbmd9IGxvY2FsZVxuICAgICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAgICovXG4gICAgZ2V0VHJhbnNsYXRpb25zKGxvY2FsZSkge1xuICAgICAgICBpZiAoaXNTdHJpbmcobG9jYWxlKSkge1xuICAgICAgICAgICAgbG9jYWxlID0gcGFyc2VMb2NhbGUobG9jYWxlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy50cmFuc2xhdGVFbGVtZW50ID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihcIlRleHQgbm90IGZvdW5kXCIpKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghKHRoaXMudHJhbnNsYXRlRWxlbWVudCBpbnN0YW5jZW9mIEhUTUxTY3JpcHRFbGVtZW50KSkge1xuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoXCJFbGVtZW50IGlzIG5vdCBhIHNjcmlwdCB0YWdcIikpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMudHJhbnNsYXRlRWxlbWVudC50eXBlICE9PSBcImFwcGxpY2F0aW9uL2pzb25cIikge1xuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoXCJFbGVtZW50IGlzIG5vdCBhIHNjcmlwdCB0YWcgd2l0aCB0eXBlIGFwcGxpY2F0aW9uL2pzb25cIikpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGV0IHRyYW5zbGF0aW9ucyA9IG51bGw7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHRyYW5zbGF0aW9ucyA9IEpTT04ucGFyc2UodGhpcy50cmFuc2xhdGVFbGVtZW50LmlubmVySFRNTC50cmltKCkpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIHJlamVjdChlKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0cmFuc2xhdGlvbnMgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKFwiVHJhbnNsYXRpb25zIG5vdCBmb3VuZCBvciBpbnZhbGlkXCIpKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHQgPSBuZXcgVHJhbnNsYXRpb25zKGxvY2FsZSk7XG4gICAgICAgICAgICB0LmFzc2lnblRyYW5zbGF0aW9ucyh0cmFuc2xhdGlvbnMpO1xuXG4gICAgICAgICAgICByZXNvbHZlKHQpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbml0aWFsaXplcyB0aGUgdHJhbnNsYXRpb25zIGZvciB0aGUgY3VycmVudCBkb2N1bWVudC5cbiAgICAgKlxuICAgICAqIGBzY3JpcHRbZGF0YS1tb25zdGVyLXJvbGU9dHJhbnNsYXRpb25zXWAgaXMgc2VhcmNoZWQgZm9yIGFuZCB0aGUgdHJhbnNsYXRpb25zIGFyZSBhc3NpZ25lZCB0byB0aGUgZWxlbWVudC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBlbGVtZW50XG4gICAgICogQHJldHVybnMge1Byb21pc2U8dW5rbm93bltdPn1cbiAgICAgKi9cbiAgICBzdGF0aWMgYXNzaWduVHJhbnNsYXRpb25zVG9FbGVtZW50KGVsZW1lbnQpIHtcbiAgICAgICAgY29uc3QgZCA9IGdldERvY3VtZW50KCk7XG5cbiAgICAgICAgaWYgKCEoZWxlbWVudCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSkge1xuICAgICAgICAgICAgZWxlbWVudCA9IGQucXVlcnlTZWxlY3RvcihcImJvZHlcIik7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBsaXN0ID0gZC5xdWVyeVNlbGVjdG9yQWxsKFwic2NyaXB0W2RhdGEtbW9uc3Rlci1yb2xlPXRyYW5zbGF0aW9uc11cIik7XG4gICAgICAgIGlmIChsaXN0ID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwcm9taXNlcyA9IFtdO1xuXG4gICAgICAgIGxpc3QuZm9yRWFjaCgodHJhbnNsYXRpb25FbGVtZW50KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwID0gbmV3IEVtYmVkKHRyYW5zbGF0aW9uRWxlbWVudCk7XG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKHAuYXNzaWduVG9FbGVtZW50KHVuZGVmaW5lZCwgZWxlbWVudCkpO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xuICAgIH1cbn1cbiIsICJcInVzZSBzdHJpY3RcIjtcblxuaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7ZGlmZn0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS9kYXRhL2RpZmYubWpzXCI7XG5pbXBvcnQge1F1ZXVlfSBmcm9tIFwiLi4vLi4vLi4vc291cmNlL3R5cGVzL3F1ZXVlLm1qc1wiO1xuXG5kZXNjcmliZSgnRGlmZicsIGZ1bmN0aW9uICgpIHtcblxuICAgIGRlc2NyaWJlKCdEaWZmIHNwZWNpYWwgY2FzZXMnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgdmFyIG9iajEsIG9iajI7XG5cbiAgICAgICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICAgICAgICBvYmoxID0ge1xuICAgICAgICAgICAgICAgIFwiY291bnRcIjogMSxcbiAgICAgICAgICAgICAgICBcInJlYXNvblwiOiBudWxsLFxuICAgICAgICAgICAgICAgIFwiaW5mb1wiOiBcInRlc3RcIixcbiAgICAgICAgICAgICAgICBcImV4Y2hhbmdlXCI6IFtdXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgb2JqMiA9IHtcbiAgICAgICAgICAgICAgICBcImNvdW50XCI6IDIsXG4gICAgICAgICAgICAgICAgXCJyZWFzb25cIjogbnVsbCxcbiAgICAgICAgICAgICAgICBcImluZm9cIjogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgIFwiZXhjaGFuZ2VcIjogW11cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ0RpZmYgdmFsdWUgd2l0aCBudWxsICcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBkID0gZGlmZihvYmoxLCBvYmoyKTtcbiAgICAgICAgICAgIGV4cGVjdChKU09OLnN0cmluZ2lmeShkKSkuaXMuZXF1YWwoJ1t7XCJvcGVyYXRvclwiOlwidXBkYXRlXCIsXCJwYXRoXCI6W1wiY291bnRcIl0sXCJmaXJzdFwiOntcInZhbHVlXCI6MSxcInR5cGVcIjpcIm51bWJlclwifSxcInNlY29uZFwiOntcInZhbHVlXCI6MixcInR5cGVcIjpcIm51bWJlclwifX0se1wib3BlcmF0b3JcIjpcImRlbGV0ZVwiLFwicGF0aFwiOltcImluZm9cIl0sXCJmaXJzdFwiOntcInZhbHVlXCI6XCJ0ZXN0XCIsXCJ0eXBlXCI6XCJzdHJpbmdcIn19XScpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnRGlmZiBpZGVudGljYWwgdmFsdWUgd2l0aCBudWxsICcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBkID0gZGlmZihvYmoxLCBvYmoxKTtcbiAgICAgICAgICAgIGV4cGVjdChKU09OLnN0cmluZ2lmeShkKSkuaXMuZXF1YWwoJ1tdJyk7XG4gICAgICAgIH0pO1xuXG5cbiAgICB9KVxuXG4gICAgY29uc3QgZGF0ZTEgPSBuZXcgRGF0ZTtcblxuICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2RlL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0RhdGUvcGFyc2VcbiAgICBjb25zdCBkYXRlMiA9IERhdGUucGFyc2UoJzAxIEphbiAxOTcwIDAwOjAwOjAwIEdNVCcpO1xuICAgIGNvbnN0IGRhdGUzID0gRGF0ZS5wYXJzZSgnMDQgRGVjIDE5OTUgMDA6MTI6MDAgR01UJyk7IC8vIE51bWJlclxuICAgIGNvbnN0IGRhdGU0ID0gRGF0ZS5wYXJzZSgnMDQgRGVjIDE5OTUgMDA6MTI6MDEgR01UJyk7IC8vIE51bWJlclxuXG4gICAgY29uc3QgZGF0ZTUgPSBuZXcgRGF0ZShEYXRlLnBhcnNlKCcwNCBEZWMgMTk5NSAwMDoxMjowMSBHTVQnKSk7IC8vIERhdGVcbiAgICBjb25zdCBkYXRlNiA9IG5ldyBEYXRlKERhdGUucGFyc2UoJzA0IERlYyAxOTk1IDAwOjEyOjAyIEdNVCcpKTsgLy8gRGF0ZVxuXG4gICAgW1xuXG4gICAgICAgIFtcbiAgICAgICAgICAgIHt9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGE6IG5ldyBRdWV1ZSgpXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgJ1t7XCJvcGVyYXRvclwiOlwiYWRkXCIsXCJwYXRoXCI6W1wiYVwiXSxcInNlY29uZFwiOntcInZhbHVlXCI6e1wiZGF0YVwiOltdfSxcInR5cGVcIjpcIm9iamVjdFwiLFwiaW5zdGFuY2VcIjpcIlF1ZXVlXCJ9fV0nXG4gICAgICAgIF0sXG5cbiAgICAgICAgW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGE6IHtcbiAgICAgICAgICAgICAgICAgICAgYjogMVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgYzoge1xuICAgICAgICAgICAgICAgICAgICBkOiAyXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhOiB7XG4gICAgICAgICAgICAgICAgICAgIGU6IDNcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGY6IHtcbiAgICAgICAgICAgICAgICAgICAgZDogMlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAnW3tcIm9wZXJhdG9yXCI6XCJkZWxldGVcIixcInBhdGhcIjpbXCJhXCIsXCJiXCJdLFwiZmlyc3RcIjp7XCJ2YWx1ZVwiOjEsXCJ0eXBlXCI6XCJudW1iZXJcIn19LHtcIm9wZXJhdG9yXCI6XCJhZGRcIixcInBhdGhcIjpbXCJhXCIsXCJlXCJdLFwic2Vjb25kXCI6e1widmFsdWVcIjozLFwidHlwZVwiOlwibnVtYmVyXCJ9fSx7XCJvcGVyYXRvclwiOlwiZGVsZXRlXCIsXCJwYXRoXCI6W1wiY1wiXSxcImZpcnN0XCI6e1widmFsdWVcIjp7XCJkXCI6Mn0sXCJ0eXBlXCI6XCJvYmplY3RcIixcImluc3RhbmNlXCI6XCJPYmplY3RcIn19LHtcIm9wZXJhdG9yXCI6XCJhZGRcIixcInBhdGhcIjpbXCJmXCJdLFwic2Vjb25kXCI6e1widmFsdWVcIjp7XCJkXCI6Mn0sXCJ0eXBlXCI6XCJvYmplY3RcIixcImluc3RhbmNlXCI6XCJPYmplY3RcIn19XSdcbiAgICAgICAgXSxcblxuICAgICAgICBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYTogZGF0ZTEsXG4gICAgICAgICAgICAgICAgYzogZGF0ZTRcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYTogZGF0ZTIsXG4gICAgICAgICAgICAgICAgYjogZGF0ZTNcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAnW3tcIm9wZXJhdG9yXCI6XCJ1cGRhdGVcIixcInBhdGhcIjpbXCJhXCJdLFwiZmlyc3RcIjp7XCJ2YWx1ZVwiOlwiJyArIGRhdGUxLnRvSVNPU3RyaW5nKCkgKyAnXCIsXCJ0eXBlXCI6XCJvYmplY3RcIixcImluc3RhbmNlXCI6XCJEYXRlXCJ9LFwic2Vjb25kXCI6e1widmFsdWVcIjowLFwidHlwZVwiOlwibnVtYmVyXCJ9fSx7XCJvcGVyYXRvclwiOlwiZGVsZXRlXCIsXCJwYXRoXCI6W1wiY1wiXSxcImZpcnN0XCI6e1widmFsdWVcIjo4MTgwMzU5MjEwMDAsXCJ0eXBlXCI6XCJudW1iZXJcIn19LHtcIm9wZXJhdG9yXCI6XCJhZGRcIixcInBhdGhcIjpbXCJiXCJdLFwic2Vjb25kXCI6e1widmFsdWVcIjo4MTgwMzU5MjAwMDAsXCJ0eXBlXCI6XCJudW1iZXJcIn19XSdcbiAgICAgICAgXSxcblxuICAgICAgICBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYTogZGF0ZTVcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYjogZGF0ZTZcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAnW3tcIm9wZXJhdG9yXCI6XCJkZWxldGVcIixcInBhdGhcIjpbXCJhXCJdLFwiZmlyc3RcIjp7XCJ2YWx1ZVwiOlwiMTk5NS0xMi0wNFQwMDoxMjowMS4wMDBaXCIsXCJ0eXBlXCI6XCJvYmplY3RcIixcImluc3RhbmNlXCI6XCJEYXRlXCJ9fSx7XCJvcGVyYXRvclwiOlwiYWRkXCIsXCJwYXRoXCI6W1wiYlwiXSxcInNlY29uZFwiOntcInZhbHVlXCI6XCIxOTk1LTEyLTA0VDAwOjEyOjAyLjAwMFpcIixcInR5cGVcIjpcIm9iamVjdFwiLFwiaW5zdGFuY2VcIjpcIkRhdGVcIn19XSdcbiAgICAgICAgXSxcbiAgICAgICAgW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGE6IGRhdGUxXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGE6IGRhdGUxXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgJ1tdJ1xuICAgICAgICBdLFxuICAgICAgICBbXG4gICAgICAgICAgICB7fSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhOiBkYXRlM1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICdbe1wib3BlcmF0b3JcIjpcImFkZFwiLFwicGF0aFwiOltcImFcIl0sXCJzZWNvbmRcIjp7XCJ2YWx1ZVwiOjgxODAzNTkyMDAwMCxcInR5cGVcIjpcIm51bWJlclwifX1dJ1xuICAgICAgICBdLFxuXG4gICAgICAgIFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhOiBkYXRlMlxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhOiBkYXRlM1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICdbe1wib3BlcmF0b3JcIjpcInVwZGF0ZVwiLFwicGF0aFwiOltcImFcIl0sXCJmaXJzdFwiOntcInZhbHVlXCI6MCxcInR5cGVcIjpcIm51bWJlclwifSxcInNlY29uZFwiOntcInZhbHVlXCI6ODE4MDM1OTIwMDAwLFwidHlwZVwiOlwibnVtYmVyXCJ9fV0nXG4gICAgICAgIF0sXG5cbiAgICAgICAgW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGE6IDFcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYTogMlxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICdbe1wib3BlcmF0b3JcIjpcInVwZGF0ZVwiLFwicGF0aFwiOltcImFcIl0sXCJmaXJzdFwiOntcInZhbHVlXCI6MSxcInR5cGVcIjpcIm51bWJlclwifSxcInNlY29uZFwiOntcInZhbHVlXCI6MixcInR5cGVcIjpcIm51bWJlclwifX1dJ1xuICAgICAgICBdLFxuXG4gICAgICAgIFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhOiAxXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHg6IDFcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAnW3tcIm9wZXJhdG9yXCI6XCJkZWxldGVcIixcInBhdGhcIjpbXCJhXCJdLFwiZmlyc3RcIjp7XCJ2YWx1ZVwiOjEsXCJ0eXBlXCI6XCJudW1iZXJcIn19LHtcIm9wZXJhdG9yXCI6XCJhZGRcIixcInBhdGhcIjpbXCJ4XCJdLFwic2Vjb25kXCI6e1widmFsdWVcIjoxLFwidHlwZVwiOlwibnVtYmVyXCJ9fV0nXG4gICAgICAgIF0sXG5cbiAgICAgICAgW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGE6IDFcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYTogMixcbiAgICAgICAgICAgICAgICB4OiAxXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgJ1t7XCJvcGVyYXRvclwiOlwidXBkYXRlXCIsXCJwYXRoXCI6W1wiYVwiXSxcImZpcnN0XCI6e1widmFsdWVcIjoxLFwidHlwZVwiOlwibnVtYmVyXCJ9LFwic2Vjb25kXCI6e1widmFsdWVcIjoyLFwidHlwZVwiOlwibnVtYmVyXCJ9fSx7XCJvcGVyYXRvclwiOlwiYWRkXCIsXCJwYXRoXCI6W1wieFwiXSxcInNlY29uZFwiOntcInZhbHVlXCI6MSxcInR5cGVcIjpcIm51bWJlclwifX1dJ1xuICAgICAgICBdLFxuICAgICAgICBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYTogbnVsbFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHt9LFxuICAgICAgICAgICAgJ1t7XCJvcGVyYXRvclwiOlwiZGVsZXRlXCIsXCJwYXRoXCI6W1wiYVwiXSxcImZpcnN0XCI6e1widmFsdWVcIjpudWxsLFwidHlwZVwiOlwib2JqZWN0XCJ9fV0nXG4gICAgICAgIF0sXG4gICAgICAgIFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhOiBudWxsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGE6IG51bGxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAnW10nXG4gICAgICAgIF0sXG4gICAgICAgIFtcbiAgICAgICAgICAgIHt9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGE6IG51bGxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAnW3tcIm9wZXJhdG9yXCI6XCJhZGRcIixcInBhdGhcIjpbXCJhXCJdLFwic2Vjb25kXCI6e1widmFsdWVcIjpudWxsLFwidHlwZVwiOlwib2JqZWN0XCJ9fV0nXG4gICAgICAgIF0sIFtcbiAgICAgICAge30sXG4gICAgICAgIHthOiB1bmRlZmluZWR9LFxuICAgICAgICAnW3tcIm9wZXJhdG9yXCI6XCJhZGRcIixcInBhdGhcIjpbXCJhXCJdLFwic2Vjb25kXCI6e1widHlwZVwiOlwidW5kZWZpbmVkXCJ9fV0nXG4gICAgXVxuXG5cbiAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuICAgICAgICBsZXQgYyA9IGRhdGEuc2hpZnQoKVxuXG5cbiAgICAgICAgaXQoJ0RpZmYgc2hvdWxkIHJlc3VsdCAnICsgYywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGV0IGQgPSBkaWZmKGEsIGIpO1xuICAgICAgICAgICAgZXhwZWN0KEpTT04uc3RyaW5naWZ5KGQpKS5pcy5lcXVhbChjKTtcbiAgICAgICAgfSk7XG5cblxuICAgIH0pO1xuXG59KSIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IGlzQXJyYXksIGlzT2JqZWN0IH0gZnJvbSBcIi4uL3R5cGVzL2lzLm1qc1wiO1xuaW1wb3J0IHsgTm9kZSB9IGZyb20gXCIuLi90eXBlcy9ub2RlLm1qc1wiO1xuaW1wb3J0IHsgTm9kZUxpc3QgfSBmcm9tIFwiLi4vdHlwZXMvbm9kZWxpc3QubWpzXCI7XG5pbXBvcnQgeyBhc3NlbWJsZVBhcnRzIH0gZnJvbSBcIi4vYnVpbGRtYXAubWpzXCI7XG5pbXBvcnQgeyBleHRlbmQgfSBmcm9tIFwiLi9leHRlbmQubWpzXCI7XG5cbmV4cG9ydCB7IGJ1aWxkVHJlZSB9O1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAdHlwZSB7c3ltYm9sfVxuICovXG5jb25zdCBwYXJlbnRTeW1ib2wgPSBTeW1ib2woXCJwYXJlbnRcIik7XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEB0eXBlIHtzeW1ib2x9XG4gKi9cbmNvbnN0IHJvb3RTeW1ib2wgPSBTeW1ib2woXCJyb290XCIpO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IGJ1aWxkVHJlZU9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7YXJyYXl9IG9wdGlvbnMucm9vdFJlZmVyZW5jZXM9W251bGwsIHVuZGVmaW5lZF0gZGVmaW5lcyB0aGUgdmFsdWVzIGZvciBlbGVtZW50cyB3aXRob3V0IHBhcmVudHNcbiAqIEBwcm9wZXJ0eSB7TW9uc3Rlci5EYXRhfmV4YW1wbGVGaWx0ZXJDYWxsYmFja30gb3B0aW9ucy5maWx0ZXIgZmlsdGVyaW5nIG9mIHRoZSB2YWx1ZXNcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkRhdGFcbiAqL1xuXG4vKipcbiAqIENyZWF0ZXMgYSB0cmVlIHN0cnVjdHVyZSBmcm9tIGEgZ2l2ZW4gc3ViamVjdCB1c2luZyBhIHNlbGVjdG9yIGFuZCBzcGVjaWZpZWQgSUQgYW5kIHBhcmVudCBJRCBrZXlzLlxuICpcbiAqIFRoZSBidWlsZFRyZWUgZnVuY3Rpb24gaXMgYSBwb3dlcmZ1bCB0b29sIGZvciBjcmVhdGluZyB0cmVlLWxpa2UgZGF0YSBzdHJ1Y3R1cmVzIGZyb20gcGxhaW4gSmF2YVNjcmlwdFxuICogb2JqZWN0cy4gSXQgdGFrZXMgaW4gZm91ciByZXF1aXJlZCBwYXJhbWV0ZXJzOiB0aGUgc3ViamVjdCBvYmplY3QgdGhhdCB5b3Ugd2FudCB0byB0dXJuIGludG8gYSB0cmVlLCBhXG4gKiBzZWxlY3RvciB0aGF0IGlkZW50aWZpZXMgd2hpY2ggcGFydHMgb2YgdGhlIHN1YmplY3QgdG8gdXNlIHdoZW4gYnVpbGRpbmcgdGhlIHRyZWUsIGFuZCB0d28ga2V5c1xuICogKGlkS2V5IGFuZCBwYXJlbnRJREtleSkgdGhhdCBzcGVjaWZ5IHdoaWNoIHByb3BlcnRpZXMgaW4gdGhlIHN1YmplY3QgcmVwcmVzZW50IHRoZSB1bmlxdWUgaWRlbnRpZmllcnNcbiAqIGFuZCBwYXJlbnQtY2hpbGQgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIG5vZGVzIGluIHRoZSB0cmVlLlxuICpcbiAqIE9wdGlvbmFsbHksIHlvdSBjYW4gYWxzbyBwYXNzIGluIGFuIG9wdGlvbnMgb2JqZWN0IHRvIGZ1cnRoZXIgY29uZmlndXJlIHRoZSBiZWhhdmlvciBvZiB0aGUgZnVuY3Rpb24sXG4gKiBzdWNoIGFzIHNwZWNpZnlpbmcgd2hpY2ggdmFsdWVzIHNob3VsZCBiZSB0cmVhdGVkIGFzIHJvb3RzIG9mIHRoZSB0cmVlLCBvciBwcm92aWRpbmcgYSBjdXN0b20gZmlsdGVyXG4gKiBmdW5jdGlvbiB0byBvbmx5IGluY2x1ZGUgY2VydGFpbiBub2RlcyBpbiB0aGUgZmluYWwgb3V0cHV0LlxuICpcbiAqIFRoZSBidWlsZFRyZWUgZnVuY3Rpb24gd29ya3MgYnkgZmlyc3QgdXNpbmcgdGhlIGFzc2VtYmxlUGFydHMgaGVscGVyIGZ1bmN0aW9uIHRvIGV4dHJhY3QgdGhlIHJlbGV2YW50XG4gKiBwYXJ0cyBvZiB0aGUgc3ViamVjdCBiYXNlZCBvbiB0aGUgc2VsZWN0b3IsIGFuZCB0aGVuIGl0ZXJhdGVzIG92ZXIgdGhlIHJlc3VsdGluZyBtYXAgdG8gY3JlYXRlIE5vZGVcbiAqIG9iamVjdHMgYW5kIG9yZ2FuaXplIHRoZW0gaW50byBwYXJlbnQtY2hpbGQgcmVsYXRpb25zaGlwcyBiYXNlZCBvbiB0aGUgdmFsdWVzIG9mIHRoZSBpZEtleSBhbmQgcGFyZW50SURLZXkgcHJvcGVydGllcy5cbiAqXG4gKiBUaGUgcmVzdWx0aW5nIE5vZGVMaXN0IHJlcHJlc2VudHMgdGhlIHRyZWUgc3RydWN0dXJlLCB3aXRoIGVhY2ggTm9kZSBvYmplY3QgY29udGFpbmluZyB0aGUgb3JpZ2luYWxcbiAqIG9iamVjdCBkYXRhIGFzIHdlbGwgYXMgYWRkaXRpb25hbCBtZXRhZGF0YSBhYm91dCBpdHMgcG9zaXRpb24gaW4gdGhlIHRyZWUuIFlvdSBjYW4gdGhlbiB1c2UgdGhlIGNoaWxkTm9kZXNcbiAqIHByb3BlcnR5IG9mIGVhY2ggTm9kZSB0byBhY2Nlc3MgaXRzIGNoaWxkcmVuLCBvciB0aGUgcGFyZW50IHByb3BlcnR5IHRvIGFjY2VzcyBpdHMgcGFyZW50LlxuICpcbiAqIE92ZXJhbGwsIHRoZSBidWlsZFRyZWUgZnVuY3Rpb24gaXMgYSBmbGV4aWJsZSBhbmQgcG93ZXJmdWwgd2F5IHRvIHRyYW5zZm9ybSBmbGF0IGRhdGEgaW50byBoaWVyYXJjaGljYWxcbiAqIHN0cnVjdHVyZXMsIGFuZCBjYW4gYmUgZXNwZWNpYWxseSB1c2VmdWwgaW4gc2NlbmFyaW9zIHN1Y2ggYXMgZGlzcGxheWluZyBmb2xkZXIgc3RydWN0dXJlcyBvclxuICogdmlzdWFsaXppbmcgY29tcGxleCBkYXRhIHJlbGF0aW9uc2hpcHMuXG4gKlxuICogTGV0J3Mgc2F5IHlvdSBoYXZlIGFuIGFycmF5IG9mIGRhdGEgb2JqZWN0cyByZXByZXNlbnRpbmcgYSBmaWxlIHN5c3RlbSBkaXJlY3Rvcnkgc3RydWN0dXJlLCBhbmQgeW91IHdhbnRcbiAqIHRvIHR1cm4gaXQgaW50byBhIHRyZWUtbGlrZSBzdHJ1Y3R1cmUgd2hlcmUgZWFjaCBub2RlIHJlcHJlc2VudHMgYSBmb2xkZXIgb3IgZmlsZSwgYW5kIGNoaWxkIG5vZGVzXG4gKiByZXByZXNlbnQgdGhlIGNvbnRlbnRzIG9mIHRoZSBmb2xkZXI6XG4gKlxuICogYGBgamF2YXNjcmlwdFxuICogY29uc3QgZmlsZVN5c3RlbSA9IFtcbiAqICAgeyBpZDogJ2ZvbGRlcjEnLCBuYW1lOiAnRm9sZGVyIDEnLCB0eXBlOiAnZm9sZGVyJywgcGFyZW50OiBudWxsIH0sXG4gKiAgIHsgaWQ6ICdmaWxlMScsIG5hbWU6ICdGaWxlIDEnLCB0eXBlOiAnZmlsZScsIHBhcmVudDogJ2ZvbGRlcjEnIH0sXG4gKiAgIHsgaWQ6ICdmaWxlMicsIG5hbWU6ICdGaWxlIDInLCB0eXBlOiAnZmlsZScsIHBhcmVudDogJ2ZvbGRlcjEnIH0sXG4gKiAgIHsgaWQ6ICdzdWJmb2xkZXIxJywgbmFtZTogJ1N1YmZvbGRlciAxJywgdHlwZTogJ2ZvbGRlcicsIHBhcmVudDogJ2ZvbGRlcjEnIH0sXG4gKiAgIHsgaWQ6ICdmaWxlMycsIG5hbWU6ICdGaWxlIDMnLCB0eXBlOiAnZmlsZScsIHBhcmVudDogJ3N1YmZvbGRlcjEnIH0sXG4gKiAgIHsgaWQ6ICdmaWxlNCcsIG5hbWU6ICdGaWxlIDQnLCB0eXBlOiAnZmlsZScsIHBhcmVudDogJ3N1YmZvbGRlcjEnIH0sXG4gKiAgIHsgaWQ6ICdzdWJmb2xkZXIyJywgbmFtZTogJ1N1YmZvbGRlciAyJywgdHlwZTogJ2ZvbGRlcicsIHBhcmVudDogJ2ZvbGRlcjEnIH0sXG4gKiAgIHsgaWQ6ICdmaWxlNScsIG5hbWU6ICdGaWxlIDUnLCB0eXBlOiAnZmlsZScsIHBhcmVudDogJ3N1YmZvbGRlcjInIH0sXG4gKiAgIHsgaWQ6ICdmaWxlNicsIG5hbWU6ICdGaWxlIDYnLCB0eXBlOiAnZmlsZScsIHBhcmVudDogJ3N1YmZvbGRlcjInIH0sXG4gKiAgIHsgaWQ6ICdmb2xkZXIyJywgbmFtZTogJ0ZvbGRlciAyJywgdHlwZTogJ2ZvbGRlcicsIHBhcmVudDogbnVsbCB9LFxuICogICB7IGlkOiAnZmlsZTcnLCBuYW1lOiAnRmlsZSA3JywgdHlwZTogJ2ZpbGUnLCBwYXJlbnQ6ICdmb2xkZXIyJyB9LFxuICogICB7IGlkOiAnZmlsZTgnLCBuYW1lOiAnRmlsZSA4JywgdHlwZTogJ2ZpbGUnLCBwYXJlbnQ6ICdmb2xkZXIyJyB9LFxuICogICB7IGlkOiAnc3ViZm9sZGVyMycsIG5hbWU6ICdTdWJmb2xkZXIgMycsIHR5cGU6ICdmb2xkZXInLCBwYXJlbnQ6ICdmb2xkZXIyJyB9LFxuICogICB7IGlkOiAnZmlsZTknLCBuYW1lOiAnRmlsZSA5JywgdHlwZTogJ2ZpbGUnLCBwYXJlbnQ6ICdzdWJmb2xkZXIzJyB9LFxuICogICB7IGlkOiAnZmlsZTEwJywgbmFtZTogJ0ZpbGUgMTAnLCB0eXBlOiAnZmlsZScsIHBhcmVudDogJ3N1YmZvbGRlcjMnIH0sXG4gKiBdO1xuICpcbiAqIGNvbnN0IHRyZWUgPSBidWlsZFRyZWUoZmlsZVN5c3RlbSwgJ2lkJywgJ2lkJywgJ3BhcmVudCcsIHsgcm9vdFJlZmVyZW5jZXM6IFtudWxsXSB9KTtcbiAqXG4gKiBjb25zb2xlLmxvZyh0cmVlLnRvU3RyaW5nKCkpO1xuICogYGBgXG4gKlxuICogVGhlIGJ1aWxkVHJlZSBmdW5jdGlvbiB0YWtlcyBpbiB0aGUgYXJyYXkgb2YgZGF0YSBvYmplY3RzLCBhcyB3ZWxsIGFzIHNvbWUgY29uZmlndXJhdGlvbiBvcHRpb25zIHNwZWNpZnlpbmdcbiAqIHRoZSBrZXlzIHRvIHVzZSBmb3IgaWRlbnRpZnlpbmcgbm9kZXMgYW5kIHRoZWlyIHBhcmVudC1jaGlsZCByZWxhdGlvbnNoaXBzLiBJbiB0aGlzIGV4YW1wbGUsIHdlIHVzZSB0aGUgaWRcbiAqIGtleSB0byBpZGVudGlmeSBub2RlcywgYW5kIHRoZSBwYXJlbnQga2V5IHRvIHNwZWNpZnkgdGhlIHBhcmVudCBvZiBlYWNoIG5vZGUuXG4gKlxuICogVGhlIHJlc3VsdGluZyB0cmVlIG9iamVjdCBpcyBhIG5lc3RlZCB0cmVlIHN0cnVjdHVyZSwgd2hlcmUgZWFjaCBub2RlIGlzIGFuIG9iamVjdCByZXByZXNlbnRpbmcgYSBmaWxlIG9yXG4gKiBmb2xkZXIsIGFuZCBoYXMgY2hpbGQgbm9kZXMgcmVwcmVzZW50aW5nIGl0cyBjb250ZW50cy4gVGhlIHRvU3RyaW5nIG1ldGhvZCBvZiB0aGUgdHJlZSBvYmplY3RcbiAqIGNhbiBiZSB1c2VkIHRvIHByaW50IG91dCB0aGUgdHJlZSBpbiBhIHJlYWRhYmxlIGZvcm1hdDpcbiAqXG4gKiBgYGBtYXJrZG93blxuICogLSBGb2xkZXIgMVxuICogICAtIEZpbGUgMVxuICogICAtIEZpbGUgMlxuICogICAtIFN1YmZvbGRlciAxXG4gKiAgICAgLSBGaWxlIDNcbiAqICAgICAtIEZpbGUgNFxuICogICAtIFN1YmZvbGRlciAyXG4gKiAgICAgLSBGaWxlIDVcbiAqICAgICAtIEZpbGUgNlxuICogLSBGb2xkZXIgMlxuICogICAtIEZpbGUgN1xuICogICAtIEZpbGUgOFxuICogICAtIFN1YmZvbGRlciAzXG4gKiAgICAgLSBGaWxlIDlcbiAqICAgICAtIEZpbGUgMTBcbiAqIGBgYFxuICpcbiAqIEBtZW1iZXJvZiBNb25zdGVyLkRhdGFcbiAqXG4gKiBAcGFyYW0geyp9IHN1YmplY3QgLSBUaGUgb2JqZWN0IG9yIGFycmF5IHRvIGJ1aWxkIHRoZSB0cmVlIGZyb20uXG4gKiBAcGFyYW0ge3N0cmluZ3xNb25zdGVyLkRhdGF+ZXhhbXBsZVNlbGVjdG9yQ2FsbGJhY2t9IHNlbGVjdG9yIC0gRWl0aGVyIGEgc3RyaW5nIHRvIHNwZWNpZnkgYSBwcm9wZXJ0eSBvZiBlYWNoIG9iamVjdCB0byB1c2UgYXMgYSBzZWxlY3Rvciwgb3IgYSBzZWxlY3RvciBmdW5jdGlvbiB0byBnZW5lcmF0ZSBhIG1hcCBvZiBvYmplY3RzLlxuICogQHBhcmFtIHtzdHJpbmd9IGlkS2V5IC0gVGhlIHByb3BlcnR5IGtleSB0byB1c2UgYXMgdGhlIHVuaXF1ZSBJRCBvZiBlYWNoIG5vZGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gcGFyZW50SURLZXkgLSBUaGUgcHJvcGVydHkga2V5IHRvIHVzZSBhcyB0aGUgcGFyZW50IElEIG9mIGVhY2ggbm9kZS5cbiAqIEBwYXJhbSB7b2JqZWN0fSBbb3B0aW9uc10gLSBBZGRpdGlvbmFsIG9wdGlvbnMgdG8gbW9kaWZ5IHRoZSBmdW5jdGlvbiBiZWhhdmlvci5cbiAqIEBwYXJhbSB7QXJyYXk8Kj59IFtvcHRpb25zLnJvb3RSZWZlcmVuY2VzPVtudWxsLCB1bmRlZmluZWRdXSAtIEFuIGFycmF5IG9mIHZhbHVlcyB0byB0cmVhdCBhcyByb290IHJlZmVyZW5jZXMgd2hlbiBjcmVhdGluZyB0aGUgdHJlZS5cbiAqIEBwYXJhbSB7ZnVuY3Rpb259IFtvcHRpb25zLmZpbHRlcl0gLSBBIGZpbHRlciBmdW5jdGlvbiB0byBhcHBseSB0byBlYWNoIG5vZGUuXG4gKlxuICogQHJldHVybiB7Kn0gVGhlIHJlc3VsdGluZyB0cmVlIHN0cnVjdHVyZSBhcyBhIE5vZGVMaXN0LlxuICpcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gc2VsZWN0b3IgaXMgbmVpdGhlciBhIHN0cmluZyBub3IgYSBmdW5jdGlvbi5cbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdGhlIHNlbGVjdG9yIGNhbGxiYWNrIG11c3QgcmV0dXJuIGEgbWFwLlxuICogQHRocm93cyB7RXJyb3J9IHRoZSBvYmplY3QgaGFzIG5vIHZhbHVlIGZvciB0aGUgc3BlY2lmaWVkIGlkLlxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICpcbiAqIEBzaW5jZSAxLjI2LjBcbiAqL1xuZnVuY3Rpb24gYnVpbGRUcmVlKHN1YmplY3QsIHNlbGVjdG9yLCBpZEtleSwgcGFyZW50SURLZXksIG9wdGlvbnMpIHtcbiAgICBjb25zdCBub2RlcyA9IG5ldyBNYXAoKTtcblxuICAgIGlmICghaXNPYmplY3Qob3B0aW9ucykpIHtcbiAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgIH1cblxuICAgIG9wdGlvbnMgPSBleHRlbmQoXG4gICAgICAgIHt9LFxuICAgICAgICB7XG4gICAgICAgICAgICByb290UmVmZXJlbmNlczogW251bGwsIHVuZGVmaW5lZF0sXG4gICAgICAgICAgICBmaWx0ZXI6IHVuZGVmaW5lZCxcbiAgICAgICAgfSxcbiAgICAgICAgb3B0aW9ucyxcbiAgICApO1xuXG4gICAgY29uc3QgZmlsdGVyID0gb3B0aW9ucz8uZmlsdGVyO1xuICAgIGxldCByb290UmVmZXJlbmNlcyA9IG9wdGlvbnMucm9vdFJlZmVyZW5jZXM7XG4gICAgaWYgKCFpc0FycmF5KHJvb3RSZWZlcmVuY2VzKSkge1xuICAgICAgICByb290UmVmZXJlbmNlcyA9IFtyb290UmVmZXJlbmNlc107XG4gICAgfVxuXG4gICAgY29uc3QgY2hpbGRNYXAgPSBhc3NlbWJsZVBhcnRzKHN1YmplY3QsIHNlbGVjdG9yLCBmaWx0ZXIsIGZ1bmN0aW9uIChvLCBrLCBtKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IG8/LltpZEtleV07XG4gICAgICAgIGxldCByZWYgPSBvPy5bcGFyZW50SURLZXldO1xuICAgICAgICBpZiAocm9vdFJlZmVyZW5jZXMuaW5kZXhPZihyZWYpICE9PSAtMSkgcmVmID0gcm9vdFN5bWJvbDtcblxuICAgICAgICBpZiAoa2V5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInRoZSBvYmplY3QgaGFzIG5vIHZhbHVlIGZvciB0aGUgc3BlY2lmaWVkIGlkXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgb1twYXJlbnRTeW1ib2xdID0gcmVmO1xuXG4gICAgICAgIGNvbnN0IG5vZGUgPSBuZXcgTm9kZShvKTtcbiAgICAgICAgdGhpcy5oYXMocmVmKSA/IHRoaXMuZ2V0KHJlZikuYWRkKG5vZGUpIDogdGhpcy5zZXQocmVmLCBuZXcgTm9kZUxpc3QoKS5hZGQobm9kZSkpO1xuICAgICAgICBub2Rlcy5zZXQoa2V5LCBub2RlKTtcbiAgICB9KTtcblxuICAgIG5vZGVzLmZvckVhY2goKG5vZGUpID0+IHtcbiAgICAgICAgbGV0IGlkID0gbm9kZT8uW1widmFsdWVcIl0/LltpZEtleV07XG5cbiAgICAgICAgaWYgKGNoaWxkTWFwLmhhcyhpZCkpIHtcbiAgICAgICAgICAgIG5vZGUuY2hpbGROb2RlcyA9IGNoaWxkTWFwLmdldChpZCk7XG4gICAgICAgICAgICBjaGlsZE1hcC5kZWxldGUoaWQpO1xuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICBjb25zdCBsaXN0ID0gbmV3IE5vZGVMaXN0KCk7XG5cbiAgICBjaGlsZE1hcC5mb3JFYWNoKChzKSA9PiB7XG4gICAgICAgIGlmIChzIGluc3RhbmNlb2YgU2V0KSB7XG4gICAgICAgICAgICBzLmZvckVhY2goKG4pID0+IHtcbiAgICAgICAgICAgICAgICBsaXN0LmFkZChuKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gbGlzdDtcbn1cbiIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IEJhc2UgfSBmcm9tIFwiLi9iYXNlLm1qc1wiO1xuaW1wb3J0IHsgaXNQcmltaXRpdmUgfSBmcm9tIFwiLi9pcy5tanNcIjtcbmltcG9ydCB7IE5vZGVMaXN0IH0gZnJvbSBcIi4vbm9kZWxpc3QubWpzXCI7XG5pbXBvcnQgeyB2YWxpZGF0ZUluc3RhbmNlIH0gZnJvbSBcIi4vdmFsaWRhdGUubWpzXCI7XG5pbXBvcnQgeyBpbnN0YW5jZVN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5cbmV4cG9ydCB7IE5vZGUgfTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHR5cGUge3N5bWJvbH1cbiAqL1xuY29uc3QgaW50ZXJuYWxWYWx1ZVN5bWJvbCA9IFN5bWJvbChcImludGVybmFsRGF0YVwiKTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHR5cGUge3N5bWJvbH1cbiAqL1xuY29uc3QgdHJlZVN0cnVjdHVyZVN5bWJvbCA9IFN5bWJvbChcInRyZWVTdHJ1Y3R1cmVcIik7XG5cbi8qKlxuICogWW91IGNhbiBjcmVhdGUgdGhlIGluc3RhbmNlIHZpYSB0aGUgbW9uc3RlciBuYW1lc3BhY2UgYG5ldyBNb25zdGVyLlR5cGVzLk5vZGUoKWAuXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNi4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcbiAqIEBzdW1tYXJ5IEEgTm9kZSBDbGFzc1xuICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9kZS9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9JdGVyYXRpb25fcHJvdG9jb2xzXG4gKi9cbmNsYXNzIE5vZGUgZXh0ZW5kcyBCYXNlIHtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0geyp9IFt2YWx1ZV1cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih2YWx1ZSkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzW2ludGVybmFsVmFsdWVTeW1ib2xdID0gdmFsdWU7XG5cbiAgICAgICAgdGhpc1t0cmVlU3RydWN0dXJlU3ltYm9sXSA9IHtcbiAgICAgICAgICAgIHBhcmVudDogbnVsbCxcbiAgICAgICAgICAgIGNoaWxkTm9kZXM6IG5ldyBOb2RlTGlzdCgpLFxuICAgICAgICAgICAgbGV2ZWw6IDAsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMi4xLjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci90eXBlcy9ub2RlXCIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwcm9wZXJ0eSB7Kn1cbiAgICAgKi9cbiAgICBnZXQgdmFsdWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzW2ludGVybmFsVmFsdWVTeW1ib2xdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwcm9wZXJ0eSB7Kn1cbiAgICAgKi9cbiAgICBzZXQgdmFsdWUodmFsdWUpIHtcbiAgICAgICAgdGhpc1tpbnRlcm5hbFZhbHVlU3ltYm9sXSA9IHZhbHVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwcm9wZXJ0eSB7TW9uc3Rlci5UeXBlcy5Ob2RlfG51bGx9XG4gICAgICovXG4gICAgZ2V0IHBhcmVudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbdHJlZVN0cnVjdHVyZVN5bWJvbF0ucGFyZW50O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwcm9wZXJ0eSB7aW50ZWdlcn1cbiAgICAgKi9cbiAgICBnZXQgbGV2ZWwoKSB7XG4gICAgICAgIHJldHVybiB0aGlzW3RyZWVTdHJ1Y3R1cmVTeW1ib2xdLmxldmVsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHByb3BlcnR5IHtOb2RlTGlzdH1cbiAgICAgKi9cbiAgICBnZXQgY2hpbGROb2RlcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbdHJlZVN0cnVjdHVyZVN5bWJvbF0uY2hpbGROb2RlcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwcm9wZXJ0eSB7Tm9kZUxpc3R9XG4gICAgICovXG4gICAgc2V0IGNoaWxkTm9kZXMoY2hpbGROb2Rlcykge1xuICAgICAgICB0aGlzW3RyZWVTdHJ1Y3R1cmVTeW1ib2xdLmNoaWxkTm9kZXMgPSB2YWxpZGF0ZUluc3RhbmNlKGNoaWxkTm9kZXMsIE5vZGVMaXN0KTtcbiAgICAgICAgc2V0Q2hpbGRMZXZlbEFuZFBhcmVudC5jYWxsKHRoaXMsIHRoaXMsIDEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge01vbnN0ZXIuVHlwZXMuTm9kZX1cbiAgICAgKiBAcGFyYW0ge05vZGV9IG5vZGVcbiAgICAgKi9cbiAgICBhcHBlbmRDaGlsZChub2RlKSB7XG4gICAgICAgIHRoaXNbdHJlZVN0cnVjdHVyZVN5bWJvbF0uY2hpbGROb2Rlcy5hZGQodmFsaWRhdGVJbnN0YW5jZShub2RlLCBOb2RlKSk7XG4gICAgICAgIG5vZGVbdHJlZVN0cnVjdHVyZVN5bWJvbF0ucGFyZW50ID0gdGhpcztcblxuICAgICAgICBub2RlW3RyZWVTdHJ1Y3R1cmVTeW1ib2xdLmxldmVsID0gdGhpcy5sZXZlbCArIDE7XG4gICAgICAgIHNldENoaWxkTGV2ZWxBbmRQYXJlbnQuY2FsbCh0aGlzLCBub2RlLCAxKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TW9uc3Rlci5UeXBlcy5Ob2RlfVxuICAgICAqIEBwYXJhbSB7Tm9kZX0gbm9kZVxuICAgICAqL1xuICAgIHJlbW92ZUNoaWxkKG5vZGUpIHtcbiAgICAgICAgdGhpc1t0cmVlU3RydWN0dXJlU3ltYm9sXS5jaGlsZE5vZGVzLnJlbW92ZSh2YWxpZGF0ZUluc3RhbmNlKG5vZGUsIE5vZGUpKTtcbiAgICAgICAgbm9kZVt0cmVlU3RydWN0dXJlU3ltYm9sXS5wYXJlbnQgPSBudWxsO1xuXG4gICAgICAgIG5vZGVbdHJlZVN0cnVjdHVyZVN5bWJvbF0ubGV2ZWwgPSAwO1xuICAgICAgICBzZXRDaGlsZExldmVsQW5kUGFyZW50LmNhbGwodGhpcywgbm9kZSwgLTEpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAgICovXG4gICAgaGFzQ2hpbGROb2RlcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbdHJlZVN0cnVjdHVyZVN5bWJvbF0uY2hpbGROb2Rlcy5sZW5ndGggPiAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge01vbnN0ZXIuVHlwZXMuTm9kZX1cbiAgICAgKiBAcGFyYW0ge05vZGV9IG5vZGVcbiAgICAgKi9cbiAgICBoYXNDaGlsZChub2RlKSB7XG4gICAgICAgIHJldHVybiB0aGlzW3RyZWVTdHJ1Y3R1cmVTeW1ib2xdLmNoaWxkTm9kZXMuaGFzKHZhbGlkYXRlSW5zdGFuY2Uobm9kZSwgTm9kZSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBzaW5jZSAxLjI4LjBcbiAgICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAgICovXG4gICAgdG9TdHJpbmcoKSB7XG4gICAgICAgIGxldCBwYXJ0cyA9IFtdO1xuICAgICAgICBpZiAodGhpc1tpbnRlcm5hbFZhbHVlU3ltYm9sXSkge1xuICAgICAgICAgICAgbGV0IGxhYmVsID0gdGhpc1tpbnRlcm5hbFZhbHVlU3ltYm9sXTtcbiAgICAgICAgICAgIGlmICghaXNQcmltaXRpdmUobGFiZWwpKSBsYWJlbCA9IEpTT04uc3RyaW5naWZ5KHRoaXNbaW50ZXJuYWxWYWx1ZVN5bWJvbF0pO1xuXG4gICAgICAgICAgICBwYXJ0cy5wdXNoKGxhYmVsKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGhpcy5oYXNDaGlsZE5vZGVzKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBwYXJ0cy5qb2luKFwiXFxuXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGNvdW50ID0gdGhpcy5jaGlsZE5vZGVzLmxlbmd0aDtcbiAgICAgICAgbGV0IGNvdW50ZXIgPSAwO1xuXG4gICAgICAgIGZvciAoY29uc3Qgbm9kZSBvZiB0aGlzLmNoaWxkTm9kZXMpIHtcbiAgICAgICAgICAgIGNvdW50ZXIrKztcbiAgICAgICAgICAgIGNvbnN0IHByZWZpeCA9IChjb3VudCA9PT0gY291bnRlciA/IFwiXHUyNTE0XCIgOiBcIlx1MjUxQ1wiKS5wYWRTdGFydCgyICogbm9kZS5sZXZlbCwgXCIgfFwiKTtcbiAgICAgICAgICAgIHBhcnRzLnB1c2gocHJlZml4ICsgbm9kZS50b1N0cmluZygpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBwYXJ0cy5qb2luKFwiXFxuXCIpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtOb2RlfSBub2RlXG4gKiBAcGFyYW0ge2ludH0gb3BlcmFuZFxuICogQHJldHVybiB7c2V0Q2hpbGRMZXZlbEFuZFBhcmVudH1cbiAqL1xuZnVuY3Rpb24gc2V0Q2hpbGRMZXZlbEFuZFBhcmVudChub2RlLCBvcGVyYW5kKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICBpZiAobm9kZSAhPT0gdGhpcykge1xuICAgICAgICBub2RlW3RyZWVTdHJ1Y3R1cmVTeW1ib2xdLnBhcmVudCA9IHRoaXM7XG4gICAgfVxuXG4gICAgbm9kZVt0cmVlU3RydWN0dXJlU3ltYm9sXS5jaGlsZE5vZGVzLmZvckVhY2goZnVuY3Rpb24gKGNoaWxkKSB7XG4gICAgICAgIGNoaWxkW3RyZWVTdHJ1Y3R1cmVTeW1ib2xdLnBhcmVudCA9IG5vZGU7XG4gICAgICAgIGNoaWxkW3RyZWVTdHJ1Y3R1cmVTeW1ib2xdLmxldmVsID0gbm9kZVt0cmVlU3RydWN0dXJlU3ltYm9sXS5sZXZlbCArIG9wZXJhbmQ7XG4gICAgICAgIHNldENoaWxkTGV2ZWxBbmRQYXJlbnQuY2FsbChzZWxmLCBjaGlsZCwgb3BlcmFuZCk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXM7XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBpc0FycmF5LCBpc0luc3RhbmNlIH0gZnJvbSBcIi4vaXMubWpzXCI7XG5pbXBvcnQgeyBOb2RlIH0gZnJvbSBcIi4vbm9kZS5tanNcIjtcbmltcG9ydCB7IHZhbGlkYXRlSW5zdGFuY2UgfSBmcm9tIFwiLi92YWxpZGF0ZS5tanNcIjtcbmltcG9ydCB7IGluc3RhbmNlU3ltYm9sIH0gZnJvbSBcIi4uL2NvbnN0YW50cy5tanNcIjtcbmV4cG9ydCB7IE5vZGVMaXN0IH07XG5cbi8qKlxuICogWW91IGNhbiBjcmVhdGUgdGhlIGluc3RhbmNlIHZpYSB0aGUgbW9uc3RlciBuYW1lc3BhY2UgYG5ldyBNb25zdGVyLlR5cGVzLk5vZGVMaXN0KClgLlxuICpcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMjYuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLlR5cGVzXG4gKiBAc3VtbWFyeSBBIE5vZGVMaXN0IGNsYXNzXG4gKi9cbmNsYXNzIE5vZGVMaXN0IGV4dGVuZHMgU2V0IHtcbiAgICAvKipcbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gaW52YWxpZCB2YWx1ZSB0eXBlXG4gICAgICogQHBhcmFtIHtOb2RlTGlzdHxOb2RlfEFycmF5PE5vZGU+fXZhbHVlc1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHZhbHVlcykge1xuICAgICAgICBzdXBlcigpO1xuXG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgICAgIGlmICh2YWx1ZXMgPT09IHVuZGVmaW5lZCkgcmV0dXJuO1xuXG4gICAgICAgIGlmIChpc0FycmF5KHZhbHVlcykpIHtcbiAgICAgICAgICAgIHZhbHVlcy5mb3JFYWNoKCh2YWx1ZSkgPT4gc2VsZi5hZGQodmFsdWUpKTtcbiAgICAgICAgfSBlbHNlIGlmIChpc0luc3RhbmNlKHZhbHVlcywgTm9kZUxpc3QpKSB7XG4gICAgICAgICAgICB2YWx1ZXMuZm9yRWFjaCgodmFsdWUpID0+IHNlbGYuYWRkKHZhbHVlKSk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNJbnN0YW5jZSh2YWx1ZXMsIE5vZGUpKSB7XG4gICAgICAgICAgICBzZWxmLmFkZCh2YWx1ZXMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiaW52YWxpZCB2YWx1ZSB0eXBlXCIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMi4xLjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci90eXBlcy9ub2RlLWxpc3RcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge05vZGV9IG5vZGVcbiAgICAgKiBAcmV0dXJuIHtNb25zdGVyLlR5cGVzLk5vZGVMaXN0fVxuICAgICAqL1xuICAgIGFkZChub2RlKSB7XG4gICAgICAgIHN1cGVyLmFkZCh2YWxpZGF0ZUluc3RhbmNlKG5vZGUsIE5vZGUpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOb2RlfSBub2RlXG4gICAgICogQHJldHVybnMge05vZGVMaXN0fVxuICAgICAqL1xuICAgIHJlbW92ZShub2RlKSB7XG4gICAgICAgIHN1cGVyLmRlbGV0ZSh2YWxpZGF0ZUluc3RhbmNlKG5vZGUsIE5vZGUpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOb2RlfSBub2RlXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAgICovXG4gICAgaGFzKG5vZGUpIHtcbiAgICAgICAgcmV0dXJuIHN1cGVyLmhhcyh2YWxpZGF0ZUluc3RhbmNlKG5vZGUsIE5vZGUpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyB7Tm9kZUxpc3R9XG4gICAgICovXG4gICAgY2xlYXIoKSB7XG4gICAgICAgIHN1cGVyLmNsZWFyKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIHtOb2RlTGlzdH1cbiAgICAgKi9cbiAgICB0b0FycmF5KCkge1xuICAgICAgICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyB7Tm9kZUxpc3R9XG4gICAgICovXG4gICAgdG9KU09OKCkge1xuICAgICAgICByZXR1cm4gdGhpcy50b0FycmF5KCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMge05vZGVMaXN0fVxuICAgICAqL1xuICAgIHRvU3RyaW5nKCkge1xuICAgICAgICBsZXQgcGFydHMgPSBbXTtcblxuICAgICAgICBmb3IgKGNvbnN0IG5vZGUgb2YgdGhpcy50b0FycmF5KCkpIHtcbiAgICAgICAgICAgIHBhcnRzLnB1c2gobm9kZS50b1N0cmluZygpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBwYXJ0cy5qb2luKFwiXFxuXCIpO1xuICAgIH1cblxuICAgIGdldCBsZW5ndGgoKSB7XG4gICAgICAgIHJldHVybiBzdXBlci5zaXplO1xuICAgIH1cbn1cbiIsICJcInVzZSBzdHJpY3RcIjtcblxuaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7YnVpbGRUcmVlfSBmcm9tIFwiLi4vLi4vLi4vc291cmNlL2RhdGEvYnVpbGR0cmVlLm1qc1wiO1xuaW1wb3J0IHtOb2RlTGlzdH0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS90eXBlcy9ub2RlbGlzdC5tanNcIjtcblxuXG5kZXNjcmliZSgnYnVpbGRUcmVlJywgZnVuY3Rpb24gKCkge1xuXG4gICAgZGVzY3JpYmUoJ2V4YW1wbGUnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBydW4gZXhhbXBsZScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgY29uc3Qgb2JqZWN0cyA9IHtcbiAgICAgICAgICAgICAgICBkYXRhc2V0OiB7XG4gICAgICAgICAgICAgICAgICAgIFwiMVwiOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZDogXCIxXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiBcInZlaGljbGVcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudDogbnVsbFxuXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIFwiMlwiOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZDogXCIyXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiBcImNhclwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50OiBcIjFcIlxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBcIjNcIjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWQ6IFwiM1wiLFxuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogXCJ0cnVja1wiLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50OiBcIjFcIlxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBcIjRcIjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWQ6IFwiNFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogXCJtb3RvcmN5Y2xlXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IFwiMVwiXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIFwiNVwiOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZDogXCI1XCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiBcIlNVVlwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50OiBcIjJcIlxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBcIjZcIjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWQ6IFwiNlwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogXCJzcG9ydHMgY2FyXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IFwiMlwiXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IG5vZGVzID0gYnVpbGRUcmVlKG9iamVjdHMsICdkYXRhc2V0LionLCAnaWQnLCAncGFyZW50Jyk7XG5cbiAgICAgICAgICAgIGV4cGVjdChub2RlcykudG8uYmUuaW5zdGFuY2VPZihOb2RlTGlzdCk7XG4gICAgICAgICAgICBleHBlY3Qobm9kZXMubGVuZ3RoKS50by5lcXVhbCgxKTtcbiAgICAgICAgICAgIGV4cGVjdChub2Rlcy50b1N0cmluZygpKS50by5iZS5lcXVhbCgne1wiaWRcIjpcIjFcIixcIm5hbWVcIjpcInZlaGljbGVcIixcInBhcmVudFwiOm51bGx9XFxuIFx1MjUxQ3tcImlkXCI6XCIyXCIsXCJuYW1lXCI6XCJjYXJcIixcInBhcmVudFwiOlwiMVwifVxcbiB8IFx1MjUxQ3tcImlkXCI6XCI1XCIsXCJuYW1lXCI6XCJTVVZcIixcInBhcmVudFwiOlwiMlwifVxcbiB8IFx1MjUxNHtcImlkXCI6XCI2XCIsXCJuYW1lXCI6XCJzcG9ydHMgY2FyXCIsXCJwYXJlbnRcIjpcIjJcIn1cXG4gXHUyNTFDe1wiaWRcIjpcIjNcIixcIm5hbWVcIjpcInRydWNrXCIsXCJwYXJlbnRcIjpcIjFcIn1cXG4gXHUyNTE0e1wiaWRcIjpcIjRcIixcIm5hbWVcIjpcIm1vdG9yY3ljbGVcIixcInBhcmVudFwiOlwiMVwifScgKTtcblxuXG4gICAgICAgIH0pXG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCdidWlsZFRyZWUoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBsZXQgb2JqMSA9IHtcbiAgICAgICAgICAgIGRhdGFzZXQ6IHtcbiAgICAgICAgICAgICAgICBcIjFcIjoge1xuICAgICAgICAgICAgICAgICAgICBpZDogXCIxXCIsXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6IFwiVGVzdCAxXCIsXG4gICAgICAgICAgICAgICAgICAgIGFkZHJlc3M6IFwiSGVyZSAxXCIsXG4gICAgICAgICAgICAgICAgICAgIHBhcmVudDogbnVsbFxuXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBcIjJcIjoge1xuICAgICAgICAgICAgICAgICAgICBpZDogXCIyXCIsXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6IFwiVGVzdCAyXCIsXG4gICAgICAgICAgICAgICAgICAgIGFkZHJlc3M6IFwiSGVyZSAyXCIsXG4gICAgICAgICAgICAgICAgICAgIHBhcmVudDogXCIxXCJcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIFwiM1wiOiB7XG4gICAgICAgICAgICAgICAgICAgIGlkOiBcIjNcIixcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogXCJUZXN0IDNcIixcbiAgICAgICAgICAgICAgICAgICAgYWRkcmVzczogXCJIZXJlIDNcIixcbiAgICAgICAgICAgICAgICAgICAgcGFyZW50OiBcIjJcIlxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgXCI0XCI6IHtcbiAgICAgICAgICAgICAgICAgICAgaWQ6IFwiNFwiLFxuICAgICAgICAgICAgICAgICAgICBuYW1lOiBcIlRlc3QgNFwiLFxuICAgICAgICAgICAgICAgICAgICBhZGRyZXNzOiBcIkhlcmUgNFwiLFxuICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IFwiMlwiXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBcIjVcIjoge1xuICAgICAgICAgICAgICAgICAgICBpZDogXCI1XCIsXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6IFwiVGVzdCA1XCIsXG4gICAgICAgICAgICAgICAgICAgIGFkZHJlc3M6IFwiSGVyZSA1XCIsXG4gICAgICAgICAgICAgICAgICAgIHBhcmVudDogXCIxXCJcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIFwiNlwiOiB7XG4gICAgICAgICAgICAgICAgICAgIGlkOiBcIjZcIixcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogXCJUZXN0IDZcIixcbiAgICAgICAgICAgICAgICAgICAgYWRkcmVzczogXCJIZXJlIDZcIixcbiAgICAgICAgICAgICAgICAgICAgcGFyZW50OiBcIjRcIlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBOb2RlIEluc3RhbmNlLicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChidWlsZFRyZWUoe30sICcnKSkudG8uYmUuaW5zdGFuY2VPZihOb2RlTGlzdCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIFtcbiAgICAgICAgICAgIFtvYmoxLCAnZGF0YXNldC4qJywgJ3tcImlkXCI6XCIxXCIsXCJuYW1lXCI6XCJUZXN0IDFcIixcImFkZHJlc3NcIjpcIkhlcmUgMVwiLFwicGFyZW50XCI6bnVsbH1cXG4gXHUyNTFDe1wiaWRcIjpcIjJcIixcIm5hbWVcIjpcIlRlc3QgMlwiLFwiYWRkcmVzc1wiOlwiSGVyZSAyXCIsXCJwYXJlbnRcIjpcIjFcIn1cXG4gfCBcdTI1MUN7XCJpZFwiOlwiM1wiLFwibmFtZVwiOlwiVGVzdCAzXCIsXCJhZGRyZXNzXCI6XCJIZXJlIDNcIixcInBhcmVudFwiOlwiMlwifVxcbiB8IFx1MjUxNHtcImlkXCI6XCI0XCIsXCJuYW1lXCI6XCJUZXN0IDRcIixcImFkZHJlc3NcIjpcIkhlcmUgNFwiLFwicGFyZW50XCI6XCIyXCJ9XFxuIHwgfCBcdTI1MTR7XCJpZFwiOlwiNlwiLFwibmFtZVwiOlwiVGVzdCA2XCIsXCJhZGRyZXNzXCI6XCJIZXJlIDZcIixcInBhcmVudFwiOlwiNFwifVxcbiBcdTI1MTR7XCJpZFwiOlwiNVwiLFwibmFtZVwiOlwiVGVzdCA1XCIsXCJhZGRyZXNzXCI6XCJIZXJlIDVcIixcInBhcmVudFwiOlwiMVwifSddLFxuICAgICAgICAgICAgW29iajEsICd4JywgJyddLFxuICAgICAgICAgICAgW29iajEsICdkYXRhc2V0LionLCAne1wiaWRcIjpcIjFcIixcIm5hbWVcIjpcIlRlc3QgMVwiLFwiYWRkcmVzc1wiOlwiSGVyZSAxXCIsXCJwYXJlbnRcIjpudWxsfVxcbiBcdTI1MUN7XCJpZFwiOlwiMlwiLFwibmFtZVwiOlwiVGVzdCAyXCIsXCJhZGRyZXNzXCI6XCJIZXJlIDJcIixcInBhcmVudFwiOlwiMVwifVxcbiB8IFx1MjUxQ3tcImlkXCI6XCIzXCIsXCJuYW1lXCI6XCJUZXN0IDNcIixcImFkZHJlc3NcIjpcIkhlcmUgM1wiLFwicGFyZW50XCI6XCIyXCJ9XFxuIHwgXHUyNTE0e1wiaWRcIjpcIjRcIixcIm5hbWVcIjpcIlRlc3QgNFwiLFwiYWRkcmVzc1wiOlwiSGVyZSA0XCIsXCJwYXJlbnRcIjpcIjJcIn1cXG4gfCB8IFx1MjUxNHtcImlkXCI6XCI2XCIsXCJuYW1lXCI6XCJUZXN0IDZcIixcImFkZHJlc3NcIjpcIkhlcmUgNlwiLFwicGFyZW50XCI6XCI0XCJ9XFxuIFx1MjUxNHtcImlkXCI6XCI1XCIsXCJuYW1lXCI6XCJUZXN0IDVcIixcImFkZHJlc3NcIjpcIkhlcmUgNVwiLFwicGFyZW50XCI6XCIxXCJ9J10sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBjID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGl0KCdidWlsZFRyZWUoJyArIEpTT04uc3RyaW5naWZ5KGEpICsgJywnICsgSlNPTi5zdHJpbmdpZnkoYikgKyAnKSBzaG91bGQgcmV0dXJuICcgKyBKU09OLnN0cmluZ2lmeShjKSArICcgJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGxldCBub2RlbGlzdCA9IGJ1aWxkVHJlZShhLCBiLCAnaWQnLCAncGFyZW50Jyk7XG4gICAgICAgICAgICAgICAgZXhwZWN0KG5vZGVsaXN0LnRvU3RyaW5nKCkpLnRvLmJlLmVxbChjKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnYnVpbGRUcmVlKCkgdGVzdCAyJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiAyXG4gICAgICAgICAqICAgIDFcbiAgICAgICAgICogICAgM1xuICAgICAgICAgKiA0XG4gICAgICAgICAqICAgIDZcbiAgICAgICAgICogNVxuICAgICAgICAgKlxuICAgICAgICAgKi9cbiAgICAgICAgbGV0IG9iajEgPSB7XG4gICAgICAgICAgICBkYXRhc2V0OiB7XG4gICAgICAgICAgICAgICAgXCIxXCI6IHtcbiAgICAgICAgICAgICAgICAgICAgaWQ6IFwiMVwiLFxuICAgICAgICAgICAgICAgICAgICBuYW1lOiBcIlRlc3QgMVwiLFxuICAgICAgICAgICAgICAgICAgICBhZGRyZXNzOiBcIkhlcmUgMVwiLFxuICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IFwiMlwiXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBcIjJcIjoge1xuICAgICAgICAgICAgICAgICAgICBpZDogXCIyXCIsXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6IFwiVGVzdCAyXCIsXG4gICAgICAgICAgICAgICAgICAgIGFkZHJlc3M6IFwiSGVyZSAyXCIsXG4gICAgICAgICAgICAgICAgICAgIHBhcmVudDogXCIwXCJcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIFwiM1wiOiB7XG4gICAgICAgICAgICAgICAgICAgIGlkOiBcIjNcIixcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogXCJUZXN0IDNcIixcbiAgICAgICAgICAgICAgICAgICAgYWRkcmVzczogXCJIZXJlIDNcIixcbiAgICAgICAgICAgICAgICAgICAgcGFyZW50OiBcIjJcIlxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgXCI0XCI6IHtcbiAgICAgICAgICAgICAgICAgICAgaWQ6IFwiNFwiLFxuICAgICAgICAgICAgICAgICAgICBuYW1lOiBcIlRlc3QgNFwiLFxuICAgICAgICAgICAgICAgICAgICBhZGRyZXNzOiBcIkhlcmUgNFwiLFxuICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IFwiMFwiXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBcIjVcIjoge1xuICAgICAgICAgICAgICAgICAgICBpZDogXCI1XCIsXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6IFwiVGVzdCA1XCIsXG4gICAgICAgICAgICAgICAgICAgIGFkZHJlc3M6IFwiSGVyZSA1XCIsXG4gICAgICAgICAgICAgICAgICAgIHBhcmVudDogXCIwXCJcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIFwiNlwiOiB7XG4gICAgICAgICAgICAgICAgICAgIGlkOiBcIjZcIixcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogXCJUZXN0IDZcIixcbiAgICAgICAgICAgICAgICAgICAgYWRkcmVzczogXCJIZXJlIDZcIixcbiAgICAgICAgICAgICAgICAgICAgcGFyZW50OiBcIjRcIlxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgXCI3XCI6IHtcbiAgICAgICAgICAgICAgICAgICAgaWQ6IFwiN1wiLFxuICAgICAgICAgICAgICAgICAgICBuYW1lOiBcIlRlc3QgN1wiLFxuICAgICAgICAgICAgICAgICAgICBhZGRyZXNzOiBcIkhlcmUgN1wiLFxuICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IFwiMVwiXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIE5vZGUgSW5zdGFuY2UuJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KGJ1aWxkVHJlZSh7fSwgJycpKS50by5iZS5pbnN0YW5jZU9mKE5vZGVMaXN0KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgW29iajEsICdkYXRhc2V0LionLCAne1wiaWRcIjpcIjJcIixcIm5hbWVcIjpcIlRlc3QgMlwiLFwiYWRkcmVzc1wiOlwiSGVyZSAyXCIsXCJwYXJlbnRcIjpcIjBcIn1cXG4gXHUyNTFDe1wiaWRcIjpcIjFcIixcIm5hbWVcIjpcIlRlc3QgMVwiLFwiYWRkcmVzc1wiOlwiSGVyZSAxXCIsXCJwYXJlbnRcIjpcIjJcIn1cXG4gfCBcdTI1MTR7XCJpZFwiOlwiN1wiLFwibmFtZVwiOlwiVGVzdCA3XCIsXCJhZGRyZXNzXCI6XCJIZXJlIDdcIixcInBhcmVudFwiOlwiMVwifVxcbiBcdTI1MTR7XCJpZFwiOlwiM1wiLFwibmFtZVwiOlwiVGVzdCAzXCIsXCJhZGRyZXNzXCI6XCJIZXJlIDNcIixcInBhcmVudFwiOlwiMlwifVxcbntcImlkXCI6XCI0XCIsXCJuYW1lXCI6XCJUZXN0IDRcIixcImFkZHJlc3NcIjpcIkhlcmUgNFwiLFwicGFyZW50XCI6XCIwXCJ9XFxuIFx1MjUxNHtcImlkXCI6XCI2XCIsXCJuYW1lXCI6XCJUZXN0IDZcIixcImFkZHJlc3NcIjpcIkhlcmUgNlwiLFwicGFyZW50XCI6XCI0XCJ9XFxue1wiaWRcIjpcIjVcIixcIm5hbWVcIjpcIlRlc3QgNVwiLFwiYWRkcmVzc1wiOlwiSGVyZSA1XCIsXCJwYXJlbnRcIjpcIjBcIn0nXSxcbiAgICAgICAgICAgIFtvYmoxLCAneCcsICcnXSxcbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGMgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ2J1aWxkVHJlZSgnICsgSlNPTi5zdHJpbmdpZnkoYSkgKyAnLCcgKyBKU09OLnN0cmluZ2lmeShiKSArICcpIHNob3VsZCByZXR1cm4gJyArIEpTT04uc3RyaW5naWZ5KGMpICsgJyAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbGV0IG5vZGVsaXN0ID0gYnVpbGRUcmVlKGEsIGIsICdpZCcsICdwYXJlbnQnLCB7XG4gICAgICAgICAgICAgICAgICAgIHJvb3RSZWZlcmVuY2VzOiBbJzAnXVxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgZXhwZWN0KG5vZGVsaXN0LnRvU3RyaW5nKCkpLnRvLmJlLmVxdWFsKGMpO1xuXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cblxuICAgIH0pO1xuXG5cbn0pO1xuIiwgIlwidXNlIHN0cmljdFwiO1xuXG5pbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuaW1wb3J0IHtQYXRoZmluZGVyfSBmcm9tIFwiLi4vLi4vLi4vc291cmNlL2RhdGEvcGF0aGZpbmRlci5tanNcIjtcblxuZGVzY3JpYmUoJ1BhdGhmaW5kZXInLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBsZXQgY29udmVydE1hcFJlc3VsdCA9IGZ1bmN0aW9uIChyKSB7XG4gICAgICAgIGlmIChyIGluc3RhbmNlb2YgTWFwKSB7XG4gICAgICAgICAgICByID0gT2JqZWN0LmZyb21FbnRyaWVzKHIpO1xuICAgICAgICAgICAgaWYgKHIgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAgICAgICAgIHIgPSByLm1hcCgoZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29udmVydE1hcFJlc3VsdChlKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgciA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW2ssIG9dIG9mIE9iamVjdC5lbnRyaWVzKHIpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJba10gPSBjb252ZXJ0TWFwUmVzdWx0KG8pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByO1xuICAgIH1cblxuXG4gICAgZGVzY3JpYmUoJ3dpdGggV2lsZGNhcmQgYW5kIEl0ZXJhdGlvbnMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCBwZiwgb2JqO1xuXG4gICAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgb2JqID0ge1xuICAgICAgICAgICAgICAgIGE6IFtcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgYjogW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYzogXCIxLTFcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjOiBcIjEtMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGQ6ICchJ1xuXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGI6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGM6IFwiMi0xXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYzogXCIyLTJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgICAgICAgICBkOiAnPydcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBmID0gbmV3IFBhdGhmaW5kZXIob2JqKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWydhLiouYi4qJywgJ3tcIjBcIjp7XCIwXCI6e1wiY1wiOlwiMS0xXCJ9LFwiMVwiOntcImNcIjpcIjEtMlwifX0sXCIxXCI6e1wiMFwiOntcImNcIjpcIjItMVwifSxcIjFcIjp7XCJjXCI6XCIyLTJcIn19fSddLFxuICAgICAgICAgICAgWydhLiouYicsICd7XCIwXCI6W3tcImNcIjpcIjEtMVwifSx7XCJjXCI6XCIxLTJcIn1dLFwiMVwiOlt7XCJjXCI6XCIyLTFcIn0se1wiY1wiOlwiMi0yXCJ9XX0nXSxcbiAgICAgICAgICAgIFsnYS4xLmInLCAnW3tcImNcIjpcIjItMVwifSx7XCJjXCI6XCIyLTJcIn1dJ10sXG4gICAgICAgICAgICBbJ2EuMC5iJywgJ1t7XCJjXCI6XCIxLTFcIn0se1wiY1wiOlwiMS0yXCJ9XSddLFxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG5cblxuICAgICAgICAgICAgaXQoJy5zZXRWaWEoJyArIGEgKyAnKSBzaG91bGQgcmVzdWx0IGluICcgKyBiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbGV0IHIgPSBwZi5nZXRWaWEoYSk7XG4gICAgICAgICAgICAgICAgbGV0IGkgPSBjb252ZXJ0TWFwUmVzdWx0KHIpO1xuICAgICAgICAgICAgICAgIGV4cGVjdChKU09OLnN0cmluZ2lmeShpKSkuaXMuZXF1YWwoYik7XG4gICAgICAgICAgICB9KTtcblxuXG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxuXG4gICAgZGVzY3JpYmUoJ2FwaSB0ZXN0cycsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBsZXQgcGF0aGZpbmRlciwgb2JqZWN0O1xuXG5cbiAgICAgICAgY2xhc3MgQSB7XG4gICAgICAgICAgICBnZXQgYSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gMVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgYmVmb3JlRWFjaCgoKSA9PiB7XG5cbiAgICAgICAgICAgIG9iamVjdCA9IHtcbiAgICAgICAgICAgICAgICBhOiB7XG4gICAgICAgICAgICAgICAgICAgIGI6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGM6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA0LCBcInRlc3QxXCIsIGZhbHNlLCB1bmRlZmluZWQsIHBhcnNlSW50KFwiYVwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGQ6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgZjogW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZzogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGg6IDMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGk6IFtcInRlc3QyXCJdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGo6IHt9LFxuICAgICAgICAgICAgICAgICAgICAgICAgazogKG5ldyBNYXApLnNldCgnbScsIHtuOiAzfSksXG4gICAgICAgICAgICAgICAgICAgICAgICBsOiAobmV3IFNldCkuYWRkKHtuOiA0fSlcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgYjogbmV3IEFcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHBhdGhmaW5kZXIgPSBuZXcgUGF0aGZpbmRlcihvYmplY3QpO1xuXG5cbiAgICAgICAgfSk7XG5cbiAgICAgICAgZGVzY3JpYmUoJ2NyZWF0ZSBuZXcgb2JqZWN0JywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgWzEyXSxcbiAgICAgICAgICAgICAgICBbdW5kZWZpbmVkXSxcbiAgICAgICAgICAgICAgICBbbnVsbF0sXG4gICAgICAgICAgICAgICAgW1widGVzdFwiXVxuICAgICAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgICAgIGxldCBsYWJlbCA9IHR5cGVvZiBhO1xuICAgICAgICAgICAgICAgIGlmIChhID09PSBudWxsKSBsYWJlbCA9ICdudWxsJztcblxuXG4gICAgICAgICAgICAgICAgaXQobGFiZWwgKyAnIHNob3VsZCB0aHJvdyBlcnJvcicsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgICAgICBleHBlY3QoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFBhdGhmaW5kZXIoYSlcbiAgICAgICAgICAgICAgICAgICAgfSkudG8udGhyb3coRXJyb3IpXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSlcblxuICAgICAgICBkZXNjcmliZSgnLnNldFZpYSh4KScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgbGV0IHBmLCBvYmo7XG5cbiAgICAgICAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIG9iaiA9IHt9XG4gICAgICAgICAgICAgICAgcGYgPSBuZXcgUGF0aGZpbmRlcihvYmopO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICBbJ2EuYi4wLjAuYycsIHRydWUsICd7XCJhXCI6e1wiYlwiOltbe1wiY1wiOnRydWV9XV19fSddLFxuICAgICAgICAgICAgICAgIFsnYS5iLjAuYycsIHRydWUsICd7XCJhXCI6e1wiYlwiOlt7XCJjXCI6dHJ1ZX1dfX0nXSxcbiAgICAgICAgICAgICAgICBbJ2EuYi4zLmMnLCB0cnVlLCAne1wiYVwiOntcImJcIjpbbnVsbCxudWxsLG51bGwse1wiY1wiOnRydWV9XX19J10sXG4gICAgICAgICAgICAgICAgWydhLmIuYycsIHRydWUsICd7XCJhXCI6e1wiYlwiOntcImNcIjp0cnVlfX19J11cbiAgICAgICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgICAgIGxldCBjID0gZGF0YS5zaGlmdCgpXG5cblxuICAgICAgICAgICAgICAgIGl0KCcuc2V0VmlhKCcgKyBhICsgJywgJyArIGIgKyAnKSBzaG91bGQgcmVzdWx0IGluICcgKyBjLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHBmLnNldFZpYShhLCBiKVxuICAgICAgICAgICAgICAgICAgICBleHBlY3QoSlNPTi5zdHJpbmdpZnkob2JqKSkuaXMuZXF1YWwoYyk7XG4gICAgICAgICAgICAgICAgfSk7XG5cblxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgfSlcblxuICAgICAgICBkZXNjcmliZSgnLnNldFZpYSgpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBsZXQgYTtcbiAgICAgICAgICAgIGxldCBiO1xuICAgICAgICAgICAgbGV0IGM7XG5cbiAgICAgICAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGEgPSBcImEueFwiO1xuICAgICAgICAgICAgICAgIGIgPSBcInRydWVcIjtcbiAgICAgICAgICAgICAgICBjID0gXCJhLnkuZFwiO1xuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgaXQoJy5zZXRWaWEoJyArIGEgKyAnLCAnICsgYiArICcpIHNob3VsZCByZXR1cm4gUGF0aGZpbmRlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBleHBlY3QocGF0aGZpbmRlci5zZXRWaWEoYSwgYikpLmlzLmluc3RhbmNlT2YoUGF0aGZpbmRlcik7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaXQoJy5zZXRWaWEoJyArIGEgKyAnLCAnICsgYiArICcpIHNob3VsZCBjaGFuZ2Ugb2JqZWN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHBhdGhmaW5kZXIuc2V0VmlhKGEsIGIpO1xuICAgICAgICAgICAgICAgIGV4cGVjdChKU09OLnN0cmluZ2lmeShvYmplY3QpKS5pcy5lcXVhbCgne1wiYVwiOntcImJcIjp7XCJjXCI6WzQsXCJ0ZXN0MVwiLGZhbHNlLG51bGwsbnVsbF0sXCJlXCI6ZmFsc2UsXCJmXCI6W3tcImdcIjpmYWxzZSxcImhcIjozLFwiaVwiOltcInRlc3QyXCJdfV0sXCJqXCI6e30sXCJrXCI6e30sXCJsXCI6e319LFwieFwiOlwidHJ1ZVwifSxcImJcIjp7fX0nKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpdCgnLnNldFZpYSgnICsgYyArICcsICcgKyBiICsgJykgc2hvdWxkIGNoYW5nZSBvYmplY3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcGF0aGZpbmRlci5zZXRWaWEoYywgYik7XG4gICAgICAgICAgICAgICAgZXhwZWN0KEpTT04uc3RyaW5naWZ5KG9iamVjdCkpLmlzLmVxdWFsKCd7XCJhXCI6e1wiYlwiOntcImNcIjpbNCxcInRlc3QxXCIsZmFsc2UsbnVsbCxudWxsXSxcImVcIjpmYWxzZSxcImZcIjpbe1wiZ1wiOmZhbHNlLFwiaFwiOjMsXCJpXCI6W1widGVzdDJcIl19XSxcImpcIjp7fSxcImtcIjp7fSxcImxcIjp7fX0sXCJ5XCI6e1wiZFwiOlwidHJ1ZVwifX0sXCJiXCI6e319Jyk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICB9KTtcblxuXG4gICAgICAgIGRlc2NyaWJlKCcuZXhpc3RzKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgWydhLmIuYy4xJywgdHJ1ZV0sXG4gICAgICAgICAgICAgICAgWydiLmEnLCB0cnVlXSxcbiAgICAgICAgICAgICAgICBbJ2EuYi54JywgZmFsc2VdLFxuICAgICAgICAgICAgICAgIFsnYS54JywgZmFsc2VdLFxuICAgICAgICAgICAgICAgIFsnYS5iLnEnLCBmYWxzZV0sXG4gICAgICAgICAgICAgICAgWydhLmIuYy4wJywgdHJ1ZV0sXG4gICAgICAgICAgICAgICAgWydhLmIuZCcsIHRydWVdLFxuICAgICAgICAgICAgICAgIFsnYS5iLmYuMC5nJywgdHJ1ZV0sXG4gICAgICAgICAgICAgICAgWydhLmIuZi4wLmkuMCcsIHRydWVdLFxuICAgICAgICAgICAgICAgIFsnYS5iLmYuMC5pLjInLCBmYWxzZV0sXG4gICAgICAgICAgICAgICAgWydhLmIuZScsIHRydWVdLFxuICAgICAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG5cblxuICAgICAgICAgICAgICAgIGl0KCcuZXhpc3RzKCcgKyBhICsgJykgc2hvdWxkIHJldHVybiAnICsgYiArICcgJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QocGF0aGZpbmRlci5leGlzdHMoYSkpLmlzLmVxdWFsKGIpO1xuICAgICAgICAgICAgICAgIH0pO1xuXG5cbiAgICAgICAgICAgIH0pO1xuXG5cbiAgICAgICAgfSk7XG5cbiAgICAgICAgZGVzY3JpYmUoJy5kZWxldGVWaWEoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICBbJ2EuYi5lJywgJ3tcImFcIjp7XCJiXCI6e1wiY1wiOls0LFwidGVzdDFcIixmYWxzZSxudWxsLG51bGxdLFwiZlwiOlt7XCJnXCI6ZmFsc2UsXCJoXCI6MyxcImlcIjpbXCJ0ZXN0MlwiXX1dLFwialwiOnt9LFwia1wiOnt9LFwibFwiOnt9fX0sXCJiXCI6e319J10sXG4gICAgICAgICAgICAgICAgWydhLmIuZicsICd7XCJhXCI6e1wiYlwiOntcImNcIjpbNCxcInRlc3QxXCIsZmFsc2UsbnVsbCxudWxsXSxcImVcIjpmYWxzZSxcImpcIjp7fSxcImtcIjp7fSxcImxcIjp7fX19LFwiYlwiOnt9fSddLFxuICAgICAgICAgICAgICAgIFsnYS5iLmonLCAne1wiYVwiOntcImJcIjp7XCJjXCI6WzQsXCJ0ZXN0MVwiLGZhbHNlLG51bGwsbnVsbF0sXCJlXCI6ZmFsc2UsXCJmXCI6W3tcImdcIjpmYWxzZSxcImhcIjozLFwiaVwiOltcInRlc3QyXCJdfV0sXCJrXCI6e30sXCJsXCI6e319fSxcImJcIjp7fX0nXSxcblxuICAgICAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgICAgICBpdCgnLmRlbGV0ZVZpYSgnICsgYSArICcpIHNob3VsZCByZXR1cm4gJyArIGIgKyAnICcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgcGF0aGZpbmRlci5kZWxldGVWaWEoYSlcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KEpTT04uc3RyaW5naWZ5KG9iamVjdCkpLmlzLmVxdWFsKGIpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGRlc2NyaWJlKCcuZ2V0VmlhKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBkZXNjcmliZSgnLmdldFZpYSgpJywgZnVuY3Rpb24gKCkge1xuXG5cbiAgICAgICAgICAgICAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgICAgICBvYmplY3QgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA0LCBcInRlc3QxXCIsIGZhbHNlLCB1bmRlZmluZWQsIHBhcnNlSW50KFwiYVwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZzogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaDogMyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpOiBbXCJ0ZXN0MlwiXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqOiB7fSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgazogKG5ldyBNYXApLnNldCgnbScsIHtuOiAzfSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGw6IChuZXcgU2V0KS5hZGQoe246IDR9KSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbzogW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3A6IHtxOiAxLCByOiB0cnVlfX0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7cDoge3E6IDIsIHI6IHRydWV9fSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtwOiB7cTogMywgcjogdHJ1ZX19LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3A6IHtxOiA0LCByOiB0cnVlfX0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7cDoge3E6IDUsIHI6IHRydWV9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0OiB7YTogMX0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1OiB7YTogMn0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2OiB7YTogM30sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiB7YTogNH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICBwYXRoZmluZGVyID0gbmV3IFBhdGhmaW5kZXIob2JqZWN0KTtcblxuXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgICAgIFsnYS4qJywgJ1tbXCJiXCIse1wiY1wiOls0LFwidGVzdDFcIixmYWxzZSxudWxsLG51bGxdLFwiZVwiOmZhbHNlLFwiZlwiOlt7XCJnXCI6ZmFsc2UsXCJoXCI6MyxcImlcIjpbXCJ0ZXN0MlwiXX1dLFwialwiOnt9LFwia1wiOnt9LFwibFwiOnt9LFwib1wiOlt7XCJwXCI6e1wicVwiOjEsXCJyXCI6dHJ1ZX19LHtcInBcIjp7XCJxXCI6MixcInJcIjp0cnVlfX0se1wicFwiOntcInFcIjozLFwiclwiOnRydWV9fSx7XCJwXCI6e1wicVwiOjQsXCJyXCI6dHJ1ZX19LHtcInBcIjp7XCJxXCI6NSxcInJcIjp0cnVlfX1dLFwic1wiOntcInRcIjp7XCJhXCI6MX0sXCJ1XCI6e1wiYVwiOjJ9LFwidlwiOntcImFcIjozfSxcInhcIjp7XCJhXCI6NH19fV1dJ10sXG4gICAgICAgICAgICAgICAgICAgIFsnYS5iLnMuKi5hJywgJ1tbXCJ0XCIsMV0sW1widVwiLDJdLFtcInZcIiwzXSxbXCJ4XCIsNF1dJ10sXG4gICAgICAgICAgICAgICAgICAgIFsnYS5iLnMuKicsICdbW1widFwiLHtcImFcIjoxfV0sW1widVwiLHtcImFcIjoyfV0sW1widlwiLHtcImFcIjozfV0sW1wieFwiLHtcImFcIjo0fV1dJ10sXG4gICAgICAgICAgICAgICAgICAgIFsnYS5iLm8uKi5wLnEnLCAnW1tcIjBcIiwxXSxbXCIxXCIsMl0sW1wiMlwiLDNdLFtcIjNcIiw0XSxbXCI0XCIsNV1dJ10sXG4gICAgICAgICAgICAgICAgICAgIFsnYS5iLm8uKi5wLnInLCAnW1tcIjBcIix0cnVlXSxbXCIxXCIsdHJ1ZV0sW1wiMlwiLHRydWVdLFtcIjNcIix0cnVlXSxbXCI0XCIsdHJ1ZV1dJ10sXG4gICAgICAgICAgICAgICAgICAgIFsnYS5iLm8uKi5wJywgJ1tbXCIwXCIse1wicVwiOjEsXCJyXCI6dHJ1ZX1dLFtcIjFcIix7XCJxXCI6MixcInJcIjp0cnVlfV0sW1wiMlwiLHtcInFcIjozLFwiclwiOnRydWV9XSxbXCIzXCIse1wicVwiOjQsXCJyXCI6dHJ1ZX1dLFtcIjRcIix7XCJxXCI6NSxcInJcIjp0cnVlfV1dJ11cbiAgICAgICAgICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICAgICAgICAgIGl0KCcuZ2V0VmlhKCcgKyBhICsgJykgc2hvdWxkIHJlc3VsdCAnICsgYiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHIgPSBwYXRoZmluZGVyLmdldFZpYShhKVxuICAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0KEpTT04uc3RyaW5naWZ5KEFycmF5LmZyb20ocikpKS5pcy5lcXVhbChiKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgaXQoJy5nZXRWaWEoKSBzaG91bGQgcmVzdWx0ICcsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgIGxldCBwID0gbmV3IFBhdGhmaW5kZXIoe1xuICAgICAgICAgICAgICAgICAgICBhOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB4OiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge2M6IDF9LCB7YzogMn1cbiAgICAgICAgICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgICAgICAgICB5OiB0cnVlXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGI6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHg6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7YzogMSwgZDogZmFsc2V9LCB7YzogMn1cbiAgICAgICAgICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgICAgICAgICB5OiB0cnVlXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICBsZXQgciA9IHAuZ2V0VmlhKFwiKi54LiouY1wiKVxuXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gbWFwVG9PYmoobWFwKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBvYmogPSB7fVxuICAgICAgICAgICAgICAgICAgICBtYXAuZm9yRWFjaChmdW5jdGlvbiAodiwgaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHYgaW5zdGFuY2VvZiBNYXApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmpba10gPSBtYXBUb09iaih2KVxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmpba10gPSB2XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9ialxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGV4cGVjdChKU09OLnN0cmluZ2lmeShtYXBUb09iaihyKSkpLmlzLmVxdWFsKCd7XCJhXCI6e1wiMFwiOjEsXCIxXCI6Mn0sXCJiXCI6e1wiMFwiOjEsXCIxXCI6Mn19Jyk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaXQoJy5nZXRWaWEoYS5iLmwuMC5uKSB3aXRoIG1hcCBzaG91bGQgcmV0dXJuIDQgJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGV4cGVjdChwYXRoZmluZGVyLmdldFZpYSgnYS5iLmwuMC5uJykpLmlzLmVxdWFsKDQpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICBbJ2EuYi5rLm0ubicsIDNdLFxuICAgICAgICAgICAgICAgIFsnYS5iLmwuMC5uJywgNF0sXG4gICAgICAgICAgICAgICAgWydhLngnLCB1bmRlZmluZWRdLFxuICAgICAgICAgICAgICAgIFsnYS5iLnEnLCB1bmRlZmluZWRdLFxuICAgICAgICAgICAgICAgIFsnYS5iLmMuMScsIFwidGVzdDFcIl0sXG4gICAgICAgICAgICAgICAgWydhLmIuYy4wJywgNF0sXG4gICAgICAgICAgICAgICAgWydhLmIuZCcsIHVuZGVmaW5lZF0sXG4gICAgICAgICAgICAgICAgWydhLmIuZi4wLmcnLCBmYWxzZV0sXG4gICAgICAgICAgICAgICAgWydhLmIuZi4wLmkuMCcsIFwidGVzdDJcIl0sXG4gICAgICAgICAgICAgICAgWydhLmIuZScsIGZhbHNlXSxcbiAgICAgICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuXG5cbiAgICAgICAgICAgICAgICBpdCgnLmdldFZpYSgnICsgYSArICcpIHNob3VsZCByZXR1cm4gJyArIGIgKyAnICcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KHBhdGhmaW5kZXIuZ2V0VmlhKGEpKS5pcy5lcXVhbChiKTtcbiAgICAgICAgICAgICAgICB9KTtcblxuXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgIFsnYS5iLmQuZSddLFxuICAgICAgICAgICAgICAgIFsnYS5iLmQueCddLFxuICAgICAgICAgICAgICAgIFsnYS5iLmwuZS5uJ10sXG4gICAgICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgICAgICBpdCgnLmdldFZpYSgnICsgYSArICcpIHNob3VsZCB0aHJvdyBFcnJvciAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdCgoKSA9PiBwYXRoZmluZGVyLmdldFZpYShhKSkudG8udGhyb3coRXJyb3IpXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG59KTtcblxuIiwgIlwidXNlIHN0cmljdFwiO1xuXG5pbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuaW1wb3J0IHtQaXBlfSBmcm9tIFwiLi4vLi4vLi4vc291cmNlL2RhdGEvcGlwZS5tanNcIjtcbmltcG9ydCB7aW5pdEpTRE9NfSBmcm9tIFwiLi4vLi4vdXRpbC9qc2RvbS5tanNcIjtcbmltcG9ydCB7RW1iZWR9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvaTE4bi9wcm92aWRlcnMvZW1iZWQubWpzXCI7XG5cblxuZGVzY3JpYmUoJ1BpcGUnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBiZWZvcmUoZnVuY3Rpb24gKGRvbmUpIHtcblxuICAgICAgICBsZXQgcHJvbWlzZXMgPSBbXVxuICAgICAgICBpZiAoIWdsb2JhbFRoaXNbJ2NyeXB0byddKSB7XG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKGltcG9ydChcIkBwZWN1bGlhci93ZWJjcnlwdG9cIikudGhlbihtID0+IHtcbiAgICAgICAgICAgICAgICBnbG9iYWxUaGlzWydjcnlwdG8nXSA9IG5ldyBtLkNyeXB0bygpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfSkpXG4gICAgICAgIH1cblxuICAgICAgICBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7XG4gICAgICAgICAgICBkb25lKClcbiAgICAgICAgfSk7XG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdydW4gZGlmZmVyZW50IHBpcGVzJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBbXG4gICAgICAgICAgICBbJ3BhdGg6YiB8IGlmOng6XFxcXCAnLCB7YTogdHJ1ZX0sICcgJ10sICAgLy8gJ1xcXFwgJy5sZW5ndGggXHUyMUE2IDJcbiAgICAgICAgICAgIFsncGF0aDphIHwgaWY6eDpcXFxcICcsIHthOiB0cnVlfSwgJ3gnXSxcbiAgICAgICAgICAgIFsnbm9wJywgJ2FiY2RlZmdoaWprbG1ub3AnLCAnYWJjZGVmZ2hpamtsbW5vcCddLFxuXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBjID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGl0KCdQaXBlLnJ1bignICsgSlNPTi5zdHJpbmdpZnkoYSkgKyAnKS5ydW4oJyArIEpTT04uc3RyaW5naWZ5KGIpICsgJykgc2hvdWxkIHJldHVybiAnICsgSlNPTi5zdHJpbmdpZnkoYyksIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBsZXQgdCA9IG5ldyBQaXBlKGEpO1xuXG4gICAgICAgICAgICAgICAgY29uc3QgciA9IHQucnVuKGIpO1xuICAgICAgICAgICAgICAgIGV4cGVjdChyKS50by5iZS5lcWwoYyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cblxuICAgIH0pO1xuXG5cbiAgICBkZXNjcmliZSgnbmV3IFBpcGUgc2hvdWxkIGNyZWF0ZSBuZXcgSW5zdGFuY2UnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gSW5zdGFuY2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IFBpcGUoJycpKS50by5iZS5pbnN0YW5jZU9mKFBpcGUpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBJbnN0YW5jZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgUGlwZSgnaW5kZXg6YXx0b3VwcGVyIHxwcmVmaXg6YScpLnJ1bih7YTogXCJ0ZXN0XCJ9KSkudG8uYmUuZXF1YWwoJ2FURVNUJyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIFtcbiAgICAgICAgICAgIFsnaW5kZXg6YXx0b3VwcGVyIHxwcmVmaXg6YScsIHthOiBcInRlc3RcIn0sICdhVEVTVCddLFxuICAgICAgICAgICAgWydwYXRoOmEuYi5jLmQgfCB0b3VwcGVyIHwgcHJlZml4OkhlbGxvXFxcXCAnLCB7XG4gICAgICAgICAgICAgICAgYToge1xuICAgICAgICAgICAgICAgICAgICBiOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZDogXCJ3b3JsZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LCAnSGVsbG8gV09STEQnXSxcbiAgICAgICAgICAgIFsncGF0aDphLmIuY3xpbmRleDpkfHRvdXBwZXIgfHN1ZmZpeDp4Jywge2E6IHtiOiB7Yzoge2Q6IFwidGVzdFwifX19fSwgJ1RFU1R4J10sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBjID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGl0KCduZXcgUGlwZSgnICsgSlNPTi5zdHJpbmdpZnkoYSkgKyAnKS5ydW4oJyArIEpTT04uc3RyaW5naWZ5KGIpICsgJykgc2hvdWxkIHJldHVybiAnICsgSlNPTi5zdHJpbmdpZnkoYykgKyAnICcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBsZXQgdCA9IG5ldyBQaXBlKGEpO1xuICAgICAgICAgICAgICAgIGV4cGVjdCh0LnJ1bihiKSkudG8uYmUuZXF1YWwoYyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ25ldyBQaXBlIGFuZCBsb2NhbGUnLCBmdW5jdGlvbiAoKSB7XG5cblxuICAgICAgICBsZXQgaHRtbDEgPSBgXG48ZGl2IGlkPVwibW9jay10cmFuc2xhdGlvbnNcIj48L2Rpdj5cbjxzY3JpcHQgdHlwZT1cImFwcGxpY2F0aW9uL2pzb25cIiBkYXRhLW1vbnN0ZXItcm9sZT1cInRyYW5zbGF0aW9uc1wiPlxuICAgIHtcbiAgICAgICAgXCI1MVwiOiBcInh5elwiLFxuICAgICAgICBcIjUyXCI6IFwiYWJjXCIsXG4gICAgICAgIFwiNTNcIjogXCJkZWZcIlxuICAgIH1cbjwvc2NyaXB0PiAgXG5gO1xuXG4gICAgICAgIGJlZm9yZUVhY2goKGRvbmUpID0+IHtcbiAgICAgICAgICAgIGxldCBtb2NrcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpO1xuICAgICAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gaHRtbDE7XG4gICAgICAgICAgICBsZXQgZWxlbSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrLXRyYW5zbGF0aW9ucycpO1xuICAgICAgICAgICAgRW1iZWQuYXNzaWduVHJhbnNsYXRpb25zVG9FbGVtZW50KGVsZW0pLnRoZW4oKG8pID0+IHtcbiAgICAgICAgICAgICAgICBkb25lKClcbiAgICAgICAgICAgIH0pLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAgICAgZG9uZShlKVxuICAgICAgICAgICAgfSlcblxuXG4gICAgICAgIH0pXG5cbiAgICAgICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgICAgICAgIGxldCBtb2NrcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpO1xuICAgICAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gXCJcIjtcbiAgICAgICAgfSlcblxuICAgICAgICBiZWZvcmUoZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgICAgIGluaXRKU0RPTSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIFtcbiAgICAgICAgICAgIFsncGF0aDpzdGF0dXMgfCB0b3N0cmluZyB8IGkxOG4nLCB7c3RhdHVzOiA1MX0sIFwieHl6XCJdXG5cblxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IHBpcGUgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBvYmogPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBleHBlY3RlZCA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpdCgnc2hvdWxkIHRyYW5zZm9ybSgnICsgcGlwZSArICcpLnJ1bignICsgSlNPTi5zdHJpbmdpZnkob2JqKSArICcpIHJldHVybiAnICsgSlNPTi5zdHJpbmdpZnkoZXhwZWN0ZWQpLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbGV0IHQgPSBuZXcgUGlwZShwaXBlKTtcbiAgICAgICAgICAgICAgICBleHBlY3QodC5ydW4ob2JqKSkudG8uYmUuZXF1YWwoZXhwZWN0ZWQpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pXG5cblxuICAgIH0pXG5cblxufSk7XG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XG5cbmltcG9ydCB7ZXh0ZW5kfSBmcm9tIFwiLi4vLi4vLi4vc291cmNlL2RhdGEvZXh0ZW5kLm1qc1wiO1xuaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcblxuY2xhc3MgTW9ja0ZvckV4dGVuZHMge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgIH1cbn1cblxuXG5kZXNjcmliZSgnZXh0ZW5kJywgZnVuY3Rpb24gKCkge1xuXG4gICAgW1xuICAgICAgICBbXG4gICAgICAgICAgICd7XCJ0aGVrZXlcIjp7fX0nLHt9LHt0aGVrZXk6bmV3IE1vY2tGb3JFeHRlbmRzfSBcbiAgICAgICAgXSxcbiAgICAgICAgW1xuICAgICAgICAgICAgJ3tcImFcIjp7XCJiXCI6W1wiMVwiLFwiMlwiLFwiM1wiXX19JyxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhOiB7XG4gICAgICAgICAgICAgICAgICAgIGI6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiMVwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgXCIyXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBcIjNcIlxuICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhOiB7XG4gICAgICAgICAgICAgICAgICAgIGI6IFtdXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgXSwgICAgICAgIFtcbiAgICAgICAgICAgICd7XCJhXCI6e1wiYlwiOjEsXCJkXCI6MX19JyxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhOiB7XG4gICAgICAgICAgICAgICAgICAgIGI6IDFcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGE6IHtcbiAgICAgICAgICAgICAgICAgICAgZDogMVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgIF0sXG5cbiAgICAgICAgW1xuICAgICAgICAgICAgJ3tcImFcIjp7XCJiXCI6MSxcImRcIjp7XCJ4XCI6W1wiY2FyXCJdLFwiZlwiOnRydWUsXCJnXCI6W119fX0nLFxuICAgICAgICAgICAge30sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYToge1xuICAgICAgICAgICAgICAgICAgICBiOiAxLFxuICAgICAgICAgICAgICAgICAgICBkOiB7eDogW1wiY2FyXCJdfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYToge1xuICAgICAgICAgICAgICAgICAgICBkOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgZzogW11cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgIF1cblxuICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgIGxldCBkID0gZGF0YS5zaGlmdCgpXG4gICAgICAgIGxldCBhID0gZGF0YVxuXG4gICAgICAgIGl0KCcuZXh0ZW5kKCcgKyBKU09OLnN0cmluZ2lmeShhKSArICcpIHNob3VsZCByZXN1bHQgaW4gJyArIGQsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCB4ID0gZXh0ZW5kLmFwcGx5KHRoaXMsIGEpO1xuICAgICAgICAgICAgZXhwZWN0KEpTT04uc3RyaW5naWZ5KHgpKS5pcy5lcXVhbChkKTtcbiAgICAgICAgfSk7XG5cblxuICAgIH0pO1xuXG5cbiAgICBbXG5cblxuICAgICAgICBbXG4gICAgICAgICAgICB7fSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhOiB7XG4gICAgICAgICAgICAgICAgICAgIGI6IDEsXG4gICAgICAgICAgICAgICAgICAgIGQ6IFtcImNhclwiXVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYToge1xuICAgICAgICAgICAgICAgICAgICBkOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgZzogW11cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhOiB7fVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhOiBbXVxuICAgICAgICAgICAgfVxuICAgICAgICBdXG5cbiAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICBsZXQgYSA9IGRhdGFcblxuICAgICAgICBpdCgnLmV4dGVuZCgnICsgSlNPTi5zdHJpbmdpZnkoYSkgKyAnKSBzaG91bGQgdGhyb3cgRXJyb3IgJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KCgpID0+IGV4dGVuZC5hcHBseSh0aGlzLCBhKSkudG8udGhyb3coRXJyb3IpO1xuICAgICAgICB9KTtcblxuXG4gICAgfSk7XG5cbn0pIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgQmFzZSB9IGZyb20gXCIuLi90eXBlcy9iYXNlLm1qc1wiO1xuaW1wb3J0IHsgaW5zdGFuY2VTeW1ib2wgfSBmcm9tIFwiLi4vY29uc3RhbnRzLm1qc1wiO1xuXG5leHBvcnQgeyBBYnN0cmFjdENvbnN0cmFpbnQgfTtcblxuLyoqXG4gKiBDb25zdHJhaW50cyBhcmUgdXNlZCB0byBkZWZpbmUgY29uZGl0aW9ucyB0aGF0IG11c3QgYmUgbWV0IGJ5IHRoZSB2YWx1ZSBvZiBhIHZhcmlhYmxlLlxuICpcbiAqIFRoZSB1bmlmb3JtIEFQSSBvZiB0aGUgY29uc3RyYWludHMgYWxsb3dzIGNoYWlucyB0byBiZSBmb3JtZWQuXG4gKlxuICogVGhlIGFic3RyYWN0IGNvbnN0cmFpbnQgZGVmaW5lcyB0aGUgYXBpIGZvciBhbGwgY29uc3RyYWludHMuIG1haW5seSB0aGUgbWV0aG9kIGlzVmFsaWQoKSBpcyBkZWZpbmVkLlxuICpcbiAqIERlcml2ZWQgY2xhc3NlcyBtdXN0IGltcGxlbWVudCB0aGUgbWV0aG9kIGlzVmFsaWQoKS5cbiAqXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjMuMFxuICogQGNvcHlyaWdodCBzY2h1a2FpIEdtYkhcbiAqIEBtZW1iZXJPZiBNb25zdGVyLkNvbnN0cmFpbnRzXG4gKiBAc3VtbWFyeSBUaGUgYWJzdHJhY3QgY29uc3RyYWludFxuICovXG5jbGFzcyBBYnN0cmFjdENvbnN0cmFpbnQgZXh0ZW5kcyBCYXNlIHtcbiAgICAvKipcbiAgICAgKlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHRoaXMgbWV0aG9kIG11c3QgcmV0dXJuIGEgcHJvbWlzZSBjb250YWluaW5nIHRoZSByZXN1bHQgb2YgdGhlIGNoZWNrLlxuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZVxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlfVxuICAgICAqL1xuICAgIGlzVmFsaWQodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGBpbnN0YW5jZW9mYCBvcGVyYXRvci5cbiAgICAgKiBAcmV0dXJucyB7c3ltYm9sfVxuICAgICAqIEBzaW5jZSAyLjEuMFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgW2luc3RhbmNlU3ltYm9sXSgpIHtcbiAgICAgICAgcmV0dXJuIFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL2NvbnN0cmFpbnRzL2Fic3RyYWN0LWNvbnN0cmFpbnRcIik7XG4gICAgfVxufVxuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgQWJzdHJhY3RDb25zdHJhaW50IH0gZnJvbSBcIi4vYWJzdHJhY3QubWpzXCI7XG5pbXBvcnQgeyBpbnN0YW5jZVN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5leHBvcnQgeyBJbnZhbGlkIH07XG5cbi8qKlxuICogQ29uc3RyYWludHMgYXJlIHVzZWQgdG8gZGVmaW5lIGNvbmRpdGlvbnMgdGhhdCBtdXN0IGJlIG1ldCBieSB0aGUgdmFsdWUgb2YgYSB2YXJpYWJsZS5cbiAqXG4gKiBUaGUgdW5pZm9ybSBBUEkgb2YgdGhlIGNvbnN0cmFpbnRzIGFsbG93cyBjaGFpbnMgdG8gYmUgZm9ybWVkLlxuICpcbiAqIFRoZSBpbnZhbGlkIGNvbnN0cmFpbnQgYWxsb3dzIGFuIGFsd2F5cyBpbnZhbGlkIHF1ZXJ5IHRvIGJlIHBlcmZvcm1lZC4gdGhpcyBjb25zdHJhaW50IGlzIG1haW5seSBpbnRlbmRlZCBmb3IgdGVzdGluZy5cbiAqXG4gKiBAZXh0ZXJuYWxFeGFtcGxlIC4uLy4uL2V4YW1wbGUvY29uc3RyYWludHMvaW52YWxpZC5tanNcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMy4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuQ29uc3RyYWludHNcbiAqIEBzdW1tYXJ5IEEgY29uc3RyYWludCB0aGF0IGFsd2F5cyBpbnZhbGlkXG4gKi9cbmNsYXNzIEludmFsaWQgZXh0ZW5kcyBBYnN0cmFjdENvbnN0cmFpbnQge1xuICAgIC8qKlxuICAgICAqIHRoaXMgbWV0aG9kIHJldHVybiBhIHJlamVjdGVkIHByb21pc2VcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZX1cbiAgICAgKi9cbiAgICBpc1ZhbGlkKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMi4xLjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci9jb25zdHJhaW50cy9pbnZhbGlkXCIpO1xuICAgIH1cbn1cbiIsICJpbXBvcnQge0ludmFsaWR9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvY29uc3RyYWludHMvaW52YWxpZC5tanNcIjtcbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5cbmRlc2NyaWJlKCdJbnZhbGlkJywgZnVuY3Rpb24gKCkge1xuXG4gICAgZGVzY3JpYmUoJy5pc1ZhbGlkKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCBpc3ZhbGlkID0gbmV3IEludmFsaWQoKVxuXG4gICAgICAgIGl0KCdzaG91bGQgcmVzb2x2ZSBwcm9taXNlJywgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgICAgIGlzdmFsaWQuaXNWYWxpZCgpLmNhdGNoKGUgPT4ge1xuICAgICAgICAgICAgICAgIGV4cGVjdChlKS50by5iZS51bmRlZmluZWRcbiAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICB9KVxuICAgICAgICB9KTtcblxuICAgIH0pO1xuXG59KTtcblxuIiwgImltcG9ydCB7QmFzZX0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS90eXBlcy9iYXNlLm1qc1wiO1xuaW1wb3J0IHtBYnN0cmFjdE9wZXJhdG9yfSBmcm9tIFwiLi4vLi4vLi4vc291cmNlL2NvbnN0cmFpbnRzL2Fic3RyYWN0b3BlcmF0b3IubWpzXCI7XG5pbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuXG5jbGFzcyBBYnN0cmFjdENvbnN0cmFpbnRNb2NrIGV4dGVuZHMgQmFzZSB7XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICBpc1ZhbGlkKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCh2YWx1ZSk7XG4gICAgfVxufVxuXG5cbmRlc2NyaWJlKCdBYnN0cmFjdE9wZXJhdG9yJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgdGhyb3cgYW4gZXJyb3Igd2hlbiB0aGUgY29uc3RyYWludCBpcyBub3QgY2FsbCB3aXRoIHBhcmFtZXRlcicsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBuZXcgQWJzdHJhY3RPcGVyYXRvcigpXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBub3QgYW4gZXJyb3Igd2hlbiB0aGUgY29uc3RyYWludCBpcyBub3QgY2FsbCB3aXRoIHBhcmFtZXRlcicsIGZ1bmN0aW9uIChkb25lKSB7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IGMgPSBuZXcgQWJzdHJhY3RPcGVyYXRvcihuZXcgQWJzdHJhY3RDb25zdHJhaW50TW9jaygpLCBuZXcgQWJzdHJhY3RDb25zdHJhaW50TW9jaygpKSAgICBcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICB9XG4gICAgICAgIFxuICAgIFxuXG4gICAgfSk7XG59KTtcblxuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgQWJzdHJhY3RDb25zdHJhaW50IH0gZnJvbSBcIi4vYWJzdHJhY3QubWpzXCI7XG5pbXBvcnQgeyBpbnN0YW5jZVN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5leHBvcnQgeyBBYnN0cmFjdE9wZXJhdG9yIH07XG5cbi8qKlxuICogQ29uc3RyYWludHMgYXJlIHVzZWQgdG8gZGVmaW5lIGNvbmRpdGlvbnMgdGhhdCBtdXN0IGJlIG1ldCBieSB0aGUgdmFsdWUgb2YgYSB2YXJpYWJsZS5cbiAqXG4gKiBUaGUgdW5pZm9ybSBBUEkgb2YgdGhlIGNvbnN0cmFpbnRzIGFsbG93cyBjaGFpbnMgdG8gYmUgZm9ybWVkLlxuICpcbiAqIE9wZXJhdG9ycyBhbGxvdyB5b3UgdG8gbGluayBjb25zdHJhaW50cyB0b2dldGhlci4gZm9yIGV4YW1wbGUsIHlvdSBjYW4gY2hlY2sgd2hldGhlciBhIHZhbHVlIGlzXG4gKiBhbiBvYmplY3Qgb3IgYW4gYXJyYXkuIGVhY2ggb3BlcmF0b3IgaGFzIHR3byBvcGVyYW5kcyB0aGF0IGFyZSBsaW5rZWQgdG9nZXRoZXIuXG4gKlxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4zLjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5Db25zdHJhaW50c1xuICogQHN1bW1hcnkgVGhlIGFic3RyYWN0IG9wZXJhdG9yIGNvbnN0cmFpbnRcbiAqL1xuY2xhc3MgQWJzdHJhY3RPcGVyYXRvciBleHRlbmRzIEFic3RyYWN0Q29uc3RyYWludCB7XG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0Fic3RyYWN0Q29uc3RyYWludH0gb3BlcmFudEFcbiAgICAgKiBAcGFyYW0ge0Fic3RyYWN0Q29uc3RyYWludH0gb3BlcmFudEJcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IFwicGFyYW1ldGVycyBtdXN0IGJlIGZyb20gdHlwZSBBYnN0cmFjdENvbnN0cmFpbnRcIlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKG9wZXJhbnRBLCBvcGVyYW50Qikge1xuICAgICAgICBzdXBlcigpO1xuXG4gICAgICAgIGlmICghKG9wZXJhbnRBIGluc3RhbmNlb2YgQWJzdHJhY3RDb25zdHJhaW50ICYmIG9wZXJhbnRCIGluc3RhbmNlb2YgQWJzdHJhY3RDb25zdHJhaW50KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInBhcmFtZXRlcnMgbXVzdCBiZSBmcm9tIHR5cGUgQWJzdHJhY3RDb25zdHJhaW50XCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5vcGVyYW50QSA9IG9wZXJhbnRBO1xuICAgICAgICB0aGlzLm9wZXJhbnRCID0gb3BlcmFudEI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMi4xLjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci9jb25zdHJhaW50cy9hYnN0cmFjdC1vcGVyYXRvclwiKTtcbiAgICB9XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBBYnN0cmFjdENvbnN0cmFpbnQgfSBmcm9tIFwiLi9hYnN0cmFjdC5tanNcIjtcbmltcG9ydCB7IGluc3RhbmNlU3ltYm9sIH0gZnJvbSBcIi4uL2NvbnN0YW50cy5tanNcIjtcbmV4cG9ydCB7IFZhbGlkIH07XG5cbi8qKlxuICogQ29uc3RyYWludHMgYXJlIHVzZWQgdG8gZGVmaW5lIGNvbmRpdGlvbnMgdGhhdCBtdXN0IGJlIG1ldCBieSB0aGUgdmFsdWUgb2YgYSB2YXJpYWJsZS5cbiAqXG4gKiBUaGUgdW5pZm9ybSBBUEkgb2YgdGhlIGNvbnN0cmFpbnRzIGFsbG93cyBjaGFpbnMgdG8gYmUgZm9ybWVkLlxuICpcbiAqIFRoZSB2YWxpZCBjb25zdHJhaW50IGFsbG93cyBhbiBhbHdheXMgdmFsaWQgcXVlcnkgdG8gYmUgcGVyZm9ybWVkLiB0aGlzIGNvbnN0cmFpbnQgaXMgbWFpbmx5IGludGVuZGVkIGZvciB0ZXN0aW5nLlxuICpcbiAqIEBleHRlcm5hbEV4YW1wbGUgLi4vLi4vZXhhbXBsZS9jb25zdHJhaW50cy92YWxpZC5tanNcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMy4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuQ29uc3RyYWludHNcbiAqIEBzdW1tYXJ5IEEgY29uc3RyYWludCB0aGF0IGFsd2F5cyB2YWxpZFxuICovXG5jbGFzcyBWYWxpZCBleHRlbmRzIEFic3RyYWN0Q29uc3RyYWludCB7XG4gICAgLyoqXG4gICAgICogdGhpcyBtZXRob2QgcmV0dXJuIGEgcHJvbWlzZSBjb250YWluaW5nIHRoZSByZXN1bHQgb2YgdGhlIGNoZWNrLlxuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZVxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlfVxuICAgICAqL1xuICAgIGlzVmFsaWQodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMi4xLjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci9jb25zdHJhaW50cy92YWxpZFwiKTtcbiAgICB9XG59XG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBBYnN0cmFjdE9wZXJhdG9yIH0gZnJvbSBcIi4vYWJzdHJhY3RvcGVyYXRvci5tanNcIjtcbmltcG9ydCB7IGluc3RhbmNlU3ltYm9sIH0gZnJvbSBcIi4uL2NvbnN0YW50cy5tanNcIjtcbmV4cG9ydCB7IE9yT3BlcmF0b3IgfTtcblxuLyoqXG4gKiBDb25zdHJhaW50cyBhcmUgdXNlZCB0byBkZWZpbmUgY29uZGl0aW9ucyB0aGF0IG11c3QgYmUgbWV0IGJ5IHRoZSB2YWx1ZSBvZiBhIHZhcmlhYmxlLlxuICpcbiAqIFRoZSB1bmlmb3JtIEFQSSBvZiB0aGUgY29uc3RyYWludHMgYWxsb3dzIGNoYWlucyB0byBiZSBmb3JtZWQuXG4gKlxuICogVGhlIE9yT3BlcmF0b3IgaXMgdXNlZCB0byBsaW5rIHNldmVyYWwgY29uc3RyYWludHMuIFRoZSBjb25zdHJhaW50IGlzIGZ1bGZpbGxlZCBpZiBvbmUgb2YgdGhlIGNvbnN0cmFpbnRzIGlzIGZ1bGZpbGxlZC5cbiAqXG4gKiBAZXh0ZXJuYWxFeGFtcGxlIC4uLy4uL2V4YW1wbGUvY29uc3RyYWludHMvb3JvcGVyYXRvci5tanNcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMy4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuQ29uc3RyYWludHNcbiAqIEBzdW1tYXJ5IEEgb3Igb3BlcmF0b3JcbiAqL1xuY2xhc3MgT3JPcGVyYXRvciBleHRlbmRzIEFic3RyYWN0T3BlcmF0b3Ige1xuICAgIC8qKlxuICAgICAqIHRoaXMgbWV0aG9kIHJldHVybiBhIHByb21pc2UgY29udGFpbmluZyB0aGUgcmVzdWx0IG9mIHRoZSBjaGVjay5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZX1cbiAgICAgKi9cbiAgICBpc1ZhbGlkKHZhbHVlKSB7XG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICAgICAgbGV0IGE7XG4gICAgICAgICAgICBsZXQgYjtcblxuICAgICAgICAgICAgc2VsZi5vcGVyYW50QVxuICAgICAgICAgICAgICAgIC5pc1ZhbGlkKHZhbHVlKVxuICAgICAgICAgICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgYSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAvKiogYiBoYXMgYWxyZWFkeSBiZWVuIGV2YWx1YXRlZCBhbmQgd2FzIG5vdCB0cnVlICovXG4gICAgICAgICAgICAgICAgICAgIGlmIChiID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgc2VsZi5vcGVyYW50QlxuICAgICAgICAgICAgICAgIC5pc1ZhbGlkKHZhbHVlKVxuICAgICAgICAgICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgYiA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAvKiogYiBoYXMgYWxyZWFkeSBiZWVuIGV2YWx1YXRlZCBhbmQgd2FzIG5vdCB0cnVlICovXG4gICAgICAgICAgICAgICAgICAgIGlmIChhID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMi4xLjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci9jb25zdHJhaW50cy9vci1vcGVyYXRvclwiKTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHtWYWxpZH0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS9jb25zdHJhaW50cy92YWxpZC5tanNcIjtcbmltcG9ydCB7SW52YWxpZH0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS9jb25zdHJhaW50cy9pbnZhbGlkLm1qc1wiO1xuaW1wb3J0IHtPck9wZXJhdG9yfSBmcm9tIFwiLi4vLi4vLi4vc291cmNlL2NvbnN0cmFpbnRzL29yb3BlcmF0b3IubWpzXCI7XG5cbmRlc2NyaWJlKCdPck9wZXJhdG9yJywgZnVuY3Rpb24gKCkge1xuXG4gICAgZGVzY3JpYmUoJy5pc1ZhbGlkKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgW25ldyBWYWxpZCgpLCBuZXcgVmFsaWQoKSwgdHJ1ZV0sXG4gICAgICAgICAgICBbbmV3IFZhbGlkKCksIG5ldyBJbnZhbGlkKCksIHRydWVdLFxuICAgICAgICAgICAgW25ldyBJbnZhbGlkKCksIG5ldyBWYWxpZCgpLCB0cnVlXSxcbiAgICAgICAgICAgIFtuZXcgSW52YWxpZCgpLCBuZXcgSW52YWxpZCgpLCBmYWxzZV1cbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGMgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ2NvbnN0cmFpbnQuaXNWYWxpZCgpIHNob3VsZCByZXR1cm4gJyArIGMsIGZ1bmN0aW9uIChkb25lKSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgY29uc3RyYWludCA9IG5ldyBPck9wZXJhdG9yKGEsIGIpO1xuICAgICAgICAgICAgICAgIGNvbnN0cmFpbnQuaXNWYWxpZCgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjID09PSB0cnVlID8gZG9uZSgpIDogZG9uZShuZXcgRXJyb3IoKSk7XG4gICAgICAgICAgICAgICAgfSkuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjID09PSB0cnVlID8gZG9uZShuZXcgRXJyb3IoKSkgOiBkb25lKCk7XG4gICAgICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgfSk7XG5cbiAgICB9KTtcbn0pO1xuXG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBpc09iamVjdCB9IGZyb20gXCIuLi90eXBlcy9pcy5tanNcIjtcbmltcG9ydCB7IEFic3RyYWN0Q29uc3RyYWludCB9IGZyb20gXCIuL2Fic3RyYWN0Lm1qc1wiO1xuaW1wb3J0IHsgaW5zdGFuY2VTeW1ib2wgfSBmcm9tIFwiLi4vY29uc3RhbnRzLm1qc1wiO1xuZXhwb3J0IHsgSXNPYmplY3QgfTtcblxuLyoqXG4gKiBDb25zdHJhaW50cyBhcmUgdXNlZCB0byBkZWZpbmUgY29uZGl0aW9ucyB0aGF0IG11c3QgYmUgbWV0IGJ5IHRoZSB2YWx1ZSBvZiBhIHZhcmlhYmxlLlxuICpcbiAqIFRoZSB1bmlmb3JtIEFQSSBvZiB0aGUgY29uc3RyYWludHMgYWxsb3dzIGNoYWlucyB0byBiZSBmb3JtZWQuXG4gKlxuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL2NvbnN0cmFpbnRzL2lzb2JqZWN0Lm1qc1xuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4zLjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5Db25zdHJhaW50c1xuICogQHN1bW1hcnkgQSBjb25zdHJhaW50IHRvIGNoZWNrIGlmIGEgdmFsdWUgaXMgYW4gb2JqZWN0XG4gKi9cbmNsYXNzIElzT2JqZWN0IGV4dGVuZHMgQWJzdHJhY3RDb25zdHJhaW50IHtcbiAgICAvKipcbiAgICAgKiB0aGlzIG1ldGhvZCByZXR1cm4gYSBwcm9taXNlIGNvbnRhaW5pbmcgdGhlIHJlc3VsdCBvZiB0aGUgY2hlY2suXG4gICAgICpcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlXG4gICAgICogQHJldHVybnMge1Byb21pc2V9XG4gICAgICovXG4gICAgaXNWYWxpZCh2YWx1ZSkge1xuICAgICAgICBpZiAoaXNPYmplY3QodmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMi4xLjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci9jb25zdHJhaW50L2lzLW9iamVjdFwiKTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHtJc09iamVjdH0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS9jb25zdHJhaW50cy9pc29iamVjdC5tanNcIjtcbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5cbmRlc2NyaWJlKCdJc09iamVjdCcsIGZ1bmN0aW9uICgpIHtcblxuICAgIGRlc2NyaWJlKCcuaXNWYWxpZCgpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgY29uc3RyYWludCA9IG5ldyBJc09iamVjdCgpXG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZXNvbHZlIHByb21pc2UnLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICAgICAgY29uc3RyYWludC5pc1ZhbGlkKHt9KS50aGVuKHIgPT4ge1xuICAgICAgICAgICAgICAgIGV4cGVjdChyKS5pcy5hKCdvYmplY3QnKTtcbiAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICB9KS5jYXRjaChlID0+IHtcbiAgICAgICAgICAgICAgICBkb25lKG5ldyBFcnJvcihcInNob3VsZCBub3QgcmVhY2hlZDogXCIgKyBlKSk7XG4gICAgICAgICAgICB9KVxuICAgICAgICB9KTtcblxuICAgIH0pO1xuXG59KTtcblxuIiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgQWJzdHJhY3RPcGVyYXRvciB9IGZyb20gXCIuL2Fic3RyYWN0b3BlcmF0b3IubWpzXCI7XG5pbXBvcnQgeyBpbnN0YW5jZVN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5leHBvcnQgeyBBbmRPcGVyYXRvciB9O1xuXG4vKipcbiAqIENvbnN0cmFpbnRzIGFyZSB1c2VkIHRvIGRlZmluZSBjb25kaXRpb25zIHRoYXQgbXVzdCBiZSBtZXQgYnkgdGhlIHZhbHVlIG9mIGEgdmFyaWFibGUuXG4gKlxuICogVGhlIHVuaWZvcm0gQVBJIG9mIHRoZSBjb25zdHJhaW50cyBhbGxvd3MgY2hhaW5zIHRvIGJlIGZvcm1lZC5cbiAqXG4gKiBUaGUgQW5kT3BlcmF0b3IgaXMgdXNlZCB0byBsaW5rIHNldmVyYWwgY29uc3RyYWludHMuIFRoZSBjb25zdHJhaW50IGlzIGZ1bGZpbGxlZCBpZiBhbGwgY29uc3RyYWludHMgb2YgdGhlIG9wZXJhdG9ycyBhcmUgZnVsZmlsbGVkLlxuICpcbiAqIEBleHRlcm5hbEV4YW1wbGUgLi4vLi4vZXhhbXBsZS9jb25zdHJhaW50cy9hbmRvcGVyYXRvci5tanNcbiAqIEBsaWNlbnNlIEFHUEx2M1xuICogQHNpbmNlIDEuMy4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuQ29uc3RyYWludHNcbiAqIEBzdW1tYXJ5IEEgYW5kIG9wZXJhdG9yIGNvbnN0cmFpbnRcbiAqL1xuY2xhc3MgQW5kT3BlcmF0b3IgZXh0ZW5kcyBBYnN0cmFjdE9wZXJhdG9yIHtcbiAgICAvKipcbiAgICAgKiB0aGlzIG1ldGhvZCByZXR1cm4gYSBwcm9taXNlIGNvbnRhaW5pbmcgdGhlIHJlc3VsdCBvZiB0aGUgY2hlY2suXG4gICAgICpcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlXG4gICAgICogQHJldHVybnMge1Byb21pc2V9XG4gICAgICovXG4gICAgaXNWYWxpZCh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoW3RoaXMub3BlcmFudEEuaXNWYWxpZCh2YWx1ZSksIHRoaXMub3BlcmFudEIuaXNWYWxpZCh2YWx1ZSldKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGBpbnN0YW5jZW9mYCBvcGVyYXRvci5cbiAgICAgKiBAcmV0dXJucyB7c3ltYm9sfVxuICAgICAqIEBzaW5jZSAyLjEuMFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgW2luc3RhbmNlU3ltYm9sXSgpIHtcbiAgICAgICAgcmV0dXJuIFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL2NvbnN0cmFpbnRzL2FuZC1vcGVyYXRvclwiKTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHtWYWxpZH0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS9jb25zdHJhaW50cy92YWxpZC5tanNcIjtcbmltcG9ydCB7SW52YWxpZH0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS9jb25zdHJhaW50cy9pbnZhbGlkLm1qc1wiO1xuaW1wb3J0IHtBbmRPcGVyYXRvcn0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS9jb25zdHJhaW50cy9hbmRvcGVyYXRvci5tanNcIjtcblxuZGVzY3JpYmUoJ0FuZE9wZXJhdG9yJywgZnVuY3Rpb24gKCkge1xuXG4gICAgZGVzY3JpYmUoJy5pc1ZhbGlkKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgW25ldyBWYWxpZCgpLCBuZXcgVmFsaWQoKSwgdHJ1ZV0sXG4gICAgICAgICAgICBbbmV3IFZhbGlkKCksIG5ldyBJbnZhbGlkKCksIGZhbHNlXSxcbiAgICAgICAgICAgIFtuZXcgSW52YWxpZCgpLCBuZXcgVmFsaWQoKSwgZmFsc2VdLFxuICAgICAgICAgICAgW25ldyBJbnZhbGlkKCksIG5ldyBJbnZhbGlkKCksIGZhbHNlXVxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYyA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpdCgnY29uc3RyYWludC5pc1ZhbGlkKCkgc2hvdWxkIHJldHVybiAnICsgYywgZnVuY3Rpb24gKGRvbmUpIHtcblxuICAgICAgICAgICAgICAgIGxldCBjb25zdHJhaW50ID0gbmV3IEFuZE9wZXJhdG9yKGEsIGIpO1xuICAgICAgICAgICAgICAgIGNvbnN0cmFpbnQuaXNWYWxpZCgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjID09PSB0cnVlID8gZG9uZSgpIDogZG9uZShuZXcgRXJyb3IoKSk7XG4gICAgICAgICAgICAgICAgfSkuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjID09PSB0cnVlID8gZG9uZShuZXcgRXJyb3IoKSkgOiBkb25lKCk7XG4gICAgICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgfSk7XG5cbiAgICB9KTtcbn0pO1xuXG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBpc0FycmF5IH0gZnJvbSBcIi4uL3R5cGVzL2lzLm1qc1wiO1xuaW1wb3J0IHsgQWJzdHJhY3RDb25zdHJhaW50IH0gZnJvbSBcIi4vYWJzdHJhY3QubWpzXCI7XG5pbXBvcnQgeyBpbnN0YW5jZVN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5leHBvcnQgeyBJc0FycmF5IH07XG5cbi8qKlxuICogQ29uc3RyYWludHMgYXJlIHVzZWQgdG8gZGVmaW5lIGNvbmRpdGlvbnMgdGhhdCBtdXN0IGJlIG1ldCBieSB0aGUgdmFsdWUgb2YgYSB2YXJpYWJsZS5cbiAqXG4gKiBUaGUgdW5pZm9ybSBBUEkgb2YgdGhlIGNvbnN0cmFpbnRzIGFsbG93cyBjaGFpbnMgdG8gYmUgZm9ybWVkLlxuICpcbiAqIEBleHRlcm5hbEV4YW1wbGUgLi4vLi4vZXhhbXBsZS9jb25zdHJhaW50cy9pc2FycmF5Lm1qc1xuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4zLjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5Db25zdHJhaW50c1xuICogQHN1bW1hcnkgQSBjb25zdHJhaW50IHRvIGNoZWNrIGlmIGEgdmFsdWUgaXMgYW4gYXJyYXlcbiAqL1xuY2xhc3MgSXNBcnJheSBleHRlbmRzIEFic3RyYWN0Q29uc3RyYWludCB7XG4gICAgLyoqXG4gICAgICogdGhpcyBtZXRob2QgcmV0dXJuIGEgcHJvbWlzZSBjb250YWluaW5nIHRoZSByZXN1bHQgb2YgdGhlIGNoZWNrLlxuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZVxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlfVxuICAgICAqL1xuICAgIGlzVmFsaWQodmFsdWUpIHtcbiAgICAgICAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBgaW5zdGFuY2VvZmAgb3BlcmF0b3IuXG4gICAgICogQHJldHVybnMge3N5bWJvbH1cbiAgICAgKiBAc2luY2UgMi4xLjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci9jb25zdHJhaW50L2lzLWFycmF5XCIpO1xuICAgIH1cbn1cbiIsICJpbXBvcnQge0lzQXJyYXl9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvY29uc3RyYWludHMvaXNhcnJheS5tanNcIjtcbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5cbmRlc2NyaWJlKCdJc0FycmF5JywgZnVuY3Rpb24gKCkge1xuXG4gICAgZGVzY3JpYmUoJy5pc1ZhbGlkKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCBjb25zdHJhaW50ID0gbmV3IElzQXJyYXkoKVxuXG4gICAgICAgIGl0KCdzaG91bGQgcmVzb2x2ZSBwcm9taXNlJywgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgICAgIGNvbnN0cmFpbnQuaXNWYWxpZChbMSwyLDNdKS50aGVuKHIgPT4ge1xuICAgICAgICAgICAgICAgIGV4cGVjdChyKS5pcy5hKCdhcnJheScpO1xuICAgICAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICAgIH0pLmNhdGNoKGUgPT4ge1xuICAgICAgICAgICAgICAgIGRvbmUobmV3IEVycm9yKFwic2hvdWxkIG5vdCByZWFjaGVkOiBcIiArIGUpKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cbn0pO1xuXG4iLCAiaW1wb3J0IHtWYWxpZH0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS9jb25zdHJhaW50cy92YWxpZC5tanNcIjtcbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5cbmRlc2NyaWJlKCdWYWxpZCcsIGZ1bmN0aW9uICgpIHtcblxuICAgIGRlc2NyaWJlKCcuaXNWYWxpZCgpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgY29uc3RyYWludCA9IG5ldyBWYWxpZCgpXG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZXNvbHZlIHByb21pc2UnLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICAgICAgY29uc3RyYWludC5pc1ZhbGlkKHt9KS50aGVuKHIgPT4ge1xuICAgICAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICAgIH0pLmNhdGNoKGUgPT4ge1xuICAgICAgICAgICAgICAgIGRvbmUobmV3IEVycm9yKFwic2hvdWxkIG5vdCByZWFjaGVkOiBcIiArIGUpKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cbn0pO1xuXG4iLCAiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuaW1wb3J0IHtOb2RlfSBmcm9tIFwiLi4vLi4vLi4vc291cmNlL3R5cGVzL25vZGUubWpzXCI7XG5pbXBvcnQge05vZGVMaXN0fSBmcm9tIFwiLi4vLi4vLi4vc291cmNlL3R5cGVzL25vZGVsaXN0Lm1qc1wiO1xuXG5kZXNjcmliZSgnTm9kZUxpc3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgZGVzY3JpYmUoJyNjb25zdHJ1Y3RvcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCBjcmVhdGUgYW4gZW1wdHkgTm9kZUxpc3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgbm9kZUxpc3QgPSBuZXcgTm9kZUxpc3QoKTtcblxuICAgICAgICAgICAgZXhwZWN0KG5vZGVMaXN0LnNpemUpLnRvLmVxdWFsKDApO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIGNyZWF0ZSBhIE5vZGVMaXN0IGZyb20gYW4gYXJyYXknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgbm9kZUxpc3QgPSBuZXcgTm9kZUxpc3QoW1xuICAgICAgICAgICAgICAgIG5ldyBOb2RlKCdkaXYnKSxcbiAgICAgICAgICAgICAgICBuZXcgTm9kZSgnZGl2JyksXG4gICAgICAgICAgICAgICAgbmV3IE5vZGUoJ2RpdicpXG4gICAgICAgICAgICBdKTtcblxuICAgICAgICAgICAgZXhwZWN0KG5vZGVMaXN0LnNpemUpLnRvLmVxdWFsKDMpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIGNyZWF0ZSBhIE5vZGVMaXN0IGZyb20gYSBOb2RlTGlzdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBub2RlTGlzdCA9IG5ldyBOb2RlTGlzdChbXG4gICAgICAgICAgICAgICAgbmV3IE5vZGUoJ2RpdicpLFxuICAgICAgICAgICAgICAgIG5ldyBOb2RlKCdkaXYnKSxcbiAgICAgICAgICAgICAgICBuZXcgTm9kZSgnZGl2JylcbiAgICAgICAgICAgIF0pO1xuXG4gICAgICAgICAgICBsZXQgbm9kZUxpc3QyID0gbmV3IE5vZGVMaXN0KG5vZGVMaXN0KTtcblxuICAgICAgICAgICAgZXhwZWN0KG5vZGVMaXN0Mi5zaXplKS50by5lcXVhbCgzKTtcbiAgICAgICAgfSk7XG4gICAgICAgIFxuICAgIH0pO1xuICAgIFxuICAgICBcbiAgICBpdCgnY3JlYXRlIE5vZGVMaXN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICBleHBlY3QobmV3IE5vZGVMaXN0KCkpLmlzLmluc3RhbmNlb2YoTm9kZUxpc3QpO1xuICAgIH0pXG5cbiAgICBpdCgnYWRkIE5vZGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGV4cGVjdChuZXcgTm9kZUxpc3QoKS5hZGQobmV3IE5vZGUoKSkpLnRvLmJlLmluc3RhbmNlb2YoTm9kZUxpc3QpO1xuICAgIH0pXG5cbiAgICBpdCgncmVtb3ZlIE5vZGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGV4cGVjdChuZXcgTm9kZUxpc3QoKS5yZW1vdmUobmV3IE5vZGUoKSkpLnRvLmJlLmluc3RhbmNlb2YoTm9kZUxpc3QpO1xuICAgIH0pXG5cbiAgICBpdCgnaGFzIHVua25vd24gTm9kZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZXhwZWN0KG5ldyBOb2RlTGlzdCgpLmhhcyhuZXcgTm9kZSkpLnRvLmJlLmZhbHNlO1xuICAgIH0pXG5cbiAgICBpdCgnaGFzIGFkZGVkIE5vZGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IG4gPSBuZXcgTm9kZTtcbiAgICAgICAgZXhwZWN0KG5ldyBOb2RlTGlzdCgpLmFkZChuKS5oYXMobikpLnRvLmJlLnRydWU7XG4gICAgfSlcbiAgICBcbiAgICBpdCgndG9TdHJpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IG4gPSBuZXcgTm9kZTtcbiAgICAgICAgZXhwZWN0KG5ldyBOb2RlTGlzdCgpLmFkZChuZXcgTm9kZSgnYScpLmFwcGVuZENoaWxkKG5ldyBOb2RlKCdiJykpKS50b1N0cmluZygpKS50by5iZS5lcXVhbCgnYVxcbiBcdTI1MTRiJyk7XG4gICAgfSlcblxuICAgIGl0KCd0aHJvdyBleGNlcHRpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGV4cGVjdCgoKSA9PiBuZXcgTm9kZUxpc3QoKS5hZGQoMSkpLnRvLnRocm93KEVycm9yKTtcbiAgICB9KVxuXG5cbn0pOyIsICJcInVzZSBzdHJpY3RcIjtcblxuaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7QmFzZX0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS90eXBlcy9iYXNlLm1qc1wiO1xuaW1wb3J0IHtpbnN0YW5jZVN5bWJvbH0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS9jb25zdGFudHMubWpzXCI7XG5cblxuXG5jbGFzcyBCYXNlRGlmZmVyZW50UmVhbG0gZXh0ZW5kcyBPYmplY3Qge1xuICAgIFxuXG4gICAgc3RhdGljIGdldCBbaW5zdGFuY2VTeW1ib2xdKCkge1xuICAgICAgICByZXR1cm4gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvdHlwZXMvYmFzZVwiKTtcbiAgICB9XG5cblxufVxuXG5jbGFzcyBTdWJjbGFzcyBleHRlbmRzIEJhc2VEaWZmZXJlbnRSZWFsbSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXQgW2luc3RhbmNlU3ltYm9sXSgpIHtcbiAgICAgICAgcmV0dXJuIFN5bWJvbC5mb3IoXCJAc2NodWthaS9tb25zdGVyL3R5cGVzL3N1YmNsYXNzXCIpO1xuICAgIH1cbn1cblxuZGVzY3JpYmUoJ0Jhc2UnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBkZXNjcmliZSgnbmV3IEJhc2UnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ2lzIGluc3RhbmNlIG9mIEJhc2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IEJhc2UpLnRvLmJlLmluc3RhbmNlT2YoQmFzZSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdpcyBpbnN0YW5jZSBvZiBPYmplY3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IEJhc2UpLnRvLmJlLmluc3RhbmNlT2YoT2JqZWN0KTtcbiAgICAgICAgfSk7XG5cbiAgICB9KVxuICAgIFxuICAgIGRlc2NyaWJlKCdpbnN0YW5jb2YnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ2lzIGluc3RhbmNlIG9mIEJhc2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IEJhc2UpLnRvLmJlLmluc3RhbmNlT2YoQmFzZSk7XG4gICAgICAgIH0pO1xuICAgICAgICBcbiAgICAgICAgaXQoJ3N1YmNsYXNzIGluc3RhbmNlb2YnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGlmIChuZXcgU3ViY2xhc3MgaW5zdGFuY2VvZiBCYXNlKSB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KHRydWUpLnRvLmJlLnRydWU7XG4gICAgICAgICAgICB9IGVsc2UgIHtcbiAgICAgICAgICAgICAgICBleHBlY3QoZmFsc2UpLnRvLmJlLnRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgXG4gICAgICAgIH0pO1xuXG5cbiAgICB9KVxuXG59KSIsICIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge01lZGlhVHlwZSwgcGFyc2VNZWRpYVR5cGV9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvdHlwZXMvbWVkaWF0eXBlLm1qc1wiO1xuXG5kZXNjcmliZSgnRGF0YXVybCcsIGZ1bmN0aW9uICgpIHtcblxuICAgIFtcbiAgICAgICAgW1wiKi8qXCIsXCIqXCIsJyonXSxcbiAgICAgICAgW1widGV4dC8qXCIsXCJ0ZXh0XCIsJyonXSxcbiAgICAgICAgW1wiKi90ZXN0XCIsXCIqXCIsJ3Rlc3QnXSxcbiAgICAgICAgW1wiaW1hZ2UvcG5nXCIsIFwiaW1hZ2VcIiwgXCJwbmdcIl0sXG4gICAgICAgIFtcImF1ZGlvL21wM1wiLCBcImF1ZGlvXCIsIFwibXAzXCJdLFxuICAgICAgICBbXCJ2aWRlby9tcGVnXCIsIFwidmlkZW9cIiwgXCJtcGVnXCJdLFxuICAgICAgICBbXCJ0ZXh0L3BsYWluXCIsIFwidGV4dFwiLCBcInBsYWluXCJdLFxuICAgICAgICBbXCJ0ZXh0L2h0bWxcIiwgXCJ0ZXh0XCIsIFwiaHRtbFwiXSxcbiAgICAgICAgW1widGV4dC9odG1sO2NoYXJzZXQ9VVMtQVNDSUlcIiwgXCJ0ZXh0XCIsIFwiaHRtbFwiXSxcbiAgICAgICAgW1widGV4dC9odG1sO2NoYXJzZXQ9XFxcIlVTLUFTQ0lJXFxcIlwiLCBcInRleHRcIiwgXCJodG1sXCJdLFxuXG4gICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgbGV0IGMgPSBkYXRhLnNoaWZ0KClcblxuXG4gICAgICAgIGl0KCdwYXJzZU1lZGlhVHlwZSgnICsgYSArICcpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBjb25zdCBkID0gcGFyc2VNZWRpYVR5cGUoYSk7XG5cbiAgICAgICAgICAgIGV4cGVjdChkKS5pcy5pbnN0YW5jZW9mKE1lZGlhVHlwZSk7XG4gICAgICAgICAgICBleHBlY3QoZC50b1N0cmluZygpKS50by5iZS5lcXVhbChhKTtcbiAgICAgICAgICAgIGV4cGVjdChkLnR5cGUpLnRvLmJlLmVxdWFsKGIpO1xuICAgICAgICAgICAgZXhwZWN0KGQuc3VidHlwZSkudG8uYmUuZXF1YWwoYyk7XG4gICAgICAgICAgICBleHBlY3QoZC5wYXJhbWV0ZXIpLmlzLmluc3RhbmNlb2YoTWFwKVxuICAgICAgICB9KVxuXG4gICAgfSk7XG5cbiAgICBbXG4gICAgICAgIFtcInZpZGVvL1wiXSxcbiAgICAgICAgW1widGV4dFwiXSxcbiAgICAgICAgW1wiL21wM1wiXSxcbiAgICAgICAgW1widGV4dC9odG1sO2NoYXJzZXRVUy1BU0NJSVwiXSxcbiAgICAgICAgW1widGV4dC9odG1sO2NoYXJzZXRcXFwiVVMtQVNDSUlcXFwiXCJdLFxuXG4gICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICBpdCgnJyArIGEgKyAnIHNob3VsZCB0aHJvdyBleGNlcHRpb24nLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIGV4cGVjdCgoKT0+e3BhcnNlTWVkaWFUeXBlKGEpfSkudGhyb3coVHlwZUVycm9yKTtcbiAgICAgICAgICAgIFxuICAgICAgICB9KVxuXG4gICAgfSk7XG5cblxufSk7IiwgImltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge1Rva2VuTGlzdH0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS90eXBlcy90b2tlbmxpc3QubWpzXCI7XG5cblxuZGVzY3JpYmUoJ1Rva2VuTGlzdCcsIGZ1bmN0aW9uICgpIHtcblxuICAgIGRlc2NyaWJlKCcudG9TdHJpbmcoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbGV0IHRva2VuTGlzdCA9IG5ldyBUb2tlbkxpc3QoKVxuICAgICAgICBsZXQgcmVzdWx0ID0gdG9rZW5MaXN0LnRvU3RyaW5nKCk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gYSBzdHJpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QocmVzdWx0KS50by5iZS5hKCdzdHJpbmcnKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3NldCBhbmQgcmVtb3ZlIHJldHVybiBhIHN0cmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHQpLnRvLmJlLmEoJ3N0cmluZycpO1xuICAgICAgICB9KTtcblxuXG4gICAgfSk7XG5cblxuICAgIGRlc2NyaWJlKCdpbml0IHdpdGggc3RyaW5nIGl0ZXJhYmxlJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCduZXcgVG9rZW5MaXN0KCcgKyB0eXBlb2YgYSArICcpIHRocm93IFR5cGVFcnJvciAnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIGxldCB0b2tlbnMgPSBbXCJhYmNcIiwgXCJkZWZcIiwgXCJnaGlcIl1cbiAgICAgICAgICAgIGxldCBsaXN0ID0gbmV3IFRva2VuTGlzdCh0b2tlbnMpO1xuICAgICAgICAgICAgZXhwZWN0KGxpc3QudG9TdHJpbmcoKSkuaXMuZXF1YWwoXCJhYmMgZGVmIGdoaVwiKTtcbiAgICAgICAgfSk7XG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdpbml0IHdpdGggaXRlcmFibGUgd2l0aG91dCBzdHJpbmcgdmFsdWVzJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCduZXcgVG9rZW5MaXN0KCcgKyB0eXBlb2YgYSArICcpIHRocm93IFR5cGVFcnJvciAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgdG9rZW5zID0gW1wiYWJjXCIsIDQsIFwiZ2hpXCJdXG4gICAgICAgICAgICBleHBlY3QoKCkgPT4gbmV3IFRva2VuTGlzdCh0b2tlbnMpKS50by50aHJvdyhUeXBlRXJyb3IpO1xuICAgICAgICB9KTtcblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2luaXQgdmFsdWVzJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIFtcbiAgICAgICAgICAgIC8vIGN1cnJlbnQsIGV4cGVjdGVkLCB0eXBlcnJvclxuICAgICAgICAgICAgWyd0ZXN0MScsIFwidGVzdDFcIiwgZmFsc2VdLFxuICAgICAgICAgICAgWyd0ZXN0MSB0ZXN0MicsIFwidGVzdDEgdGVzdDJcIiwgZmFsc2VdLFxuICAgICAgICAgICAgW3VuZGVmaW5lZCwgXCJcIiwgZmFsc2VdLFxuICAgICAgICAgICAgW251bGwsIHVuZGVmaW5lZCwgdHJ1ZV0sXG4gICAgICAgICAgICBbcGFyc2VJbnQoXCJhXCIpLCB1bmRlZmluZWQsIHRydWVdLCAvLyBOYU5cbiAgICAgICAgICAgIFsoKSA9PiB7XG4gICAgICAgICAgICB9LCB1bmRlZmluZWQsIHRydWVdLFxuICAgICAgICAgICAgWzIsIHVuZGVmaW5lZCwgdHJ1ZV0sXG4gICAgICAgICAgICBbZmFsc2UsIHVuZGVmaW5lZCwgdHJ1ZV0sXG4gICAgICAgICAgICBbdHJ1ZSwgdW5kZWZpbmVkLCB0cnVlXSxcbiAgICAgICAgICAgIFs0LjUsIHVuZGVmaW5lZCwgdHJ1ZV0sXG4gICAgICAgICAgICBbe30sIHVuZGVmaW5lZCwgdHJ1ZV0sXG4gICAgICAgICAgICBbW1wiMVwiLCBcIjJcIiwgXCIzXCJdLCAnMSAyIDMnLCBmYWxzZV0sIC8vIGl0ZXJhYmxlIHN0cmluZ3NcbiAgICAgICAgICAgIFtbMSwgMiwgM10sIHVuZGVmaW5lZCwgdHJ1ZV0sXG4gICAgICAgICAgICBbU3ltYm9sKFwiZm9vXCIpLCBmYWxzZSwgdHJ1ZV0sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBjID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGlmIChjID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgaXQoJ25ldyBUb2tlbkxpc3QoJyArIHR5cGVvZiBhICsgJykgdGhyb3cgVHlwZUVycm9yICcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KCgpID0+IG5ldyBUb2tlbkxpc3QoYSkpLnRvLnRocm93KFR5cGVFcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGl0KCduZXcgVG9rZW5MaXN0KCcgKyB0eXBlb2YgYSArICcpIHNob3VsZCByZXR1cm4gJyArIGIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KG5ldyBUb2tlbkxpc3QoYSkudG9TdHJpbmcoKSkuaXMuZXF1YWwoYilcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgfVxuXG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnaXRlcmF0b3IgcHJvdG9jb2wnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgbGV0IGxpc3Q7XG4gICAgICAgIGl0KCcuYWRkKCcgKyBcInNlY29uZFwiICsgJykgc2hvdWxkIHJldHVybiBUb2tlbkxpc3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsaXN0ID0gbmV3IFRva2VuTGlzdChcInN0YXJ0XCIpO1xuICAgICAgICAgICAgZXhwZWN0KGxpc3QuZ2V0SXRlcmF0b3IoKSkudG8uYmUuYW4oJ29iamVjdCcpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnLmFkZCgnICsgXCJzZWNvbmRcIiArICcpIHNob3VsZCByZXR1cm4gVG9rZW5MaXN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGlzdCA9IG5ldyBUb2tlbkxpc3QoXCJzdGFydCBlbmRcIik7XG4gICAgICAgICAgICBleHBlY3QoWy4uLmxpc3RdKS50by5iZS5hbignYXJyYXknKTtcbiAgICAgICAgICAgIGV4cGVjdChbLi4ubGlzdF0pLnRvLmJlLmFuKCdhcnJheScpLnRvLmluY2x1ZGUoJ3N0YXJ0JykudG8uaW5jbHVkZSgnZW5kJyk7XG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCcuZW50cmllcygpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGxldCBsaXN0O1xuICAgICAgICBpdCgnLmVudHJpZXMoKSBzaG91bGQgcmV0dXJuIEFycmF5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGlzdCA9IG5ldyBUb2tlbkxpc3QoXCJzdGFydFwiKTtcbiAgICAgICAgICAgIGV4cGVjdChsaXN0LmVudHJpZXMoKSkudG8uYmUuYW4oJ2FycmF5Jyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCcuZW50cmllcygpIHNob3VsZCByZXR1cm4gQXJyYXknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsaXN0ID0gbmV3IFRva2VuTGlzdChcInN0YXJ0IGVuZFwiKS5lbnRyaWVzKCk7XG4gICAgICAgICAgICBleHBlY3QobGlzdCkudG8uYmUuYW4oJ2FycmF5JykudG8uaW5jbHVkZSgnc3RhcnQnKS50by5pbmNsdWRlKCdlbmQnKTtcbiAgICAgICAgfSk7XG5cblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJy5mb3JFYWNoKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgbGV0IGxpc3Q7XG4gICAgICAgIGl0KCcuZm9yRWFjaCgpIHNob3VsZCBpdGVyYXRlIG92ZXIgdG9rZW5saXN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGlzdCA9IG5ldyBUb2tlbkxpc3QoXCJhYWEgYmJiIGNjYyBkZGQgZWVlIGZmZlwiKTtcblxuICAgICAgICAgICAgbGV0IHJlc3VsdCA9IFwiXCJcbiAgICAgICAgICAgIGxpc3QuZm9yRWFjaCgoYSkgPT4ge1xuICAgICAgICAgICAgICAgIHJlc3VsdCArPSBcIiFcIiArIGEgKyBcIiFcIjtcbiAgICAgICAgICAgICAgICBleHBlY3QoYSkudG8uYmUuYW4oJ3N0cmluZycpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBleHBlY3QocmVzdWx0KS5pcy5lcXVhbChcIiFhYWEhIWJiYiEhY2NjISFkZGQhIWVlZSEhZmZmIVwiKVxuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnLmVudHJpZXMoKSBzaG91bGQgcmV0dXJuIEFycmF5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGlzdCA9IG5ldyBUb2tlbkxpc3QoXCJzdGFydCBlbmRcIikuZW50cmllcygpO1xuICAgICAgICAgICAgZXhwZWN0KGxpc3QpLnRvLmJlLmFuKCdhcnJheScpLnRvLmluY2x1ZGUoJ3N0YXJ0JykudG8uaW5jbHVkZSgnZW5kJyk7XG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdjb250YWlucyB2YWx1ZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCBsaXN0XG4gICAgICAgIGl0KCduZXcgVG9rZW5MaXN0KHN0YXJ0LCBtaWRkbGUgZW5kKSBzaG91bGQgY29udGFpbiBtaWRkbGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsaXN0ID0gbmV3IFRva2VuTGlzdChcInN0YXJ0IG1pZGRsZSBlbmRcIik7XG4gICAgICAgICAgICBleHBlY3QobGlzdC5jb250YWlucygnc3RhcnQnKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgICAgIGV4cGVjdChsaXN0LmNvbnRhaW5zKCdtaWRkbGUnKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgICAgIGV4cGVjdChsaXN0LmNvbnRhaW5zKCdlbmQnKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgICAgIGV4cGVjdChsaXN0LmNvbnRhaW5zKFsnZW5kJywgJ3N0YXJ0JywgJ21pZGRsZSddKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ25ldyBUb2tlbkxpc3Qoc3RhcnQsIG1pZGRsZSBlbmQpIHNob3VsZCBub3QgY29udGFpbiB4eXonLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsaXN0ID0gbmV3IFRva2VuTGlzdChcInN0YXJ0IG1pZGRsZSBlbmRcIik7XG4gICAgICAgICAgICBleHBlY3QobGlzdC5jb250YWlucygneHl6JykpLnRvLmJlLmZhbHNlO1xuICAgICAgICAgICAgZXhwZWN0KGxpc3QuY29udGFpbnMoWydlbmQnLCAnc3RhcnQnLCAnbWlkZGxlJywgJ3h5eiddKSkudG8uYmUuZmFsc2U7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCduZXcgVG9rZW5MaXN0KHN0YXJ0LCBtaWRkbGUgZW5kKSBzaG91bGQgbm90IGNvbnRhaW4gdW5kZWZpbmVkIG51bGwgTmFOJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGlzdCA9IG5ldyBUb2tlbkxpc3QoXCJzdGFydCBtaWRkbGUgZW5kXCIpO1xuICAgICAgICAgICAgZXhwZWN0KGxpc3QuY29udGFpbnModW5kZWZpbmVkKSkudG8uYmUuZmFsc2U7XG4gICAgICAgICAgICBleHBlY3QobGlzdC5jb250YWlucyhwYXJzZUludChcImFcIikpKS50by5iZS5mYWxzZTsgLy8gTmFOXG4gICAgICAgICAgICBleHBlY3QobGlzdC5jb250YWlucyhudWxsKSkudG8uYmUuZmFsc2U7IC8vIE5hTlxuICAgICAgICB9KTtcbiAgICB9KVxuXG4gICAgZGVzY3JpYmUoJ3RvZ2dsZSB2YWx1ZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCBsaXN0XG4gICAgICAgIGl0KCduZXcgVG9rZW5MaXN0KHN0YXJ0IG1pZGRsZSBlbmQpLnRvZ2dsZShuZXctdmFsdWUpIHNob3VsZCBjb250YWluIG5ldy12YWx1ZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxpc3QgPSBuZXcgVG9rZW5MaXN0KFwic3RhcnQgbWlkZGxlIGVuZFwiKTtcbiAgICAgICAgICAgIGV4cGVjdChsaXN0LnRvZ2dsZSgnbmV3LXZhbHVlJykudG9TdHJpbmcoKSkuaXMuZXF1YWwoXCJzdGFydCBtaWRkbGUgZW5kIG5ldy12YWx1ZVwiKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ25ldyBUb2tlbkxpc3Qoc3RhcnQgbWlkZGxlIGVuZCkudG9nZ2xlKG1pZGRsZSkgc2hvdWxkIG5vdCBjb250YWluIG1pZGRsZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxpc3QgPSBuZXcgVG9rZW5MaXN0KFwic3RhcnQgbWlkZGxlIGVuZFwiKTtcbiAgICAgICAgICAgIGV4cGVjdChsaXN0LnRvZ2dsZSgnbWlkZGxlJykudG9TdHJpbmcoKSkuaXMuZXF1YWwoXCJzdGFydCBlbmRcIik7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCduZXcgVG9rZW5MaXN0KCkudG9nZ2xlKCkgc2hvdWxkIC4uLicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgVG9rZW5MaXN0KFwiYWJjIGRlZiBnaGlcIikudG9nZ2xlKFwiZGVmIHh5elwiKS50b1N0cmluZygpKS50by5lcXVhbChcImFiYyBnaGkgeHl6XCIpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnbmV3IFRva2VuTGlzdCgpLnRvZ2dsZSgpIHNob3VsZCAuLi4nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IFRva2VuTGlzdChcImFiYyBkZWYgZ2hpXCIpLnRvZ2dsZShbXCJhYmNcIiwgXCJ4eXpcIl0pLnRvU3RyaW5nKCkpLnRvLmVxdWFsKFwiZGVmIGdoaSB4eXpcIik7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCduZXcgVG9rZW5MaXN0KCkudG9nZ2xlKCkgc2hvdWxkIC4uLicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgVG9rZW5MaXN0KFwiYWJjIGRlZiBnaGlcIikudG9nZ2xlKHVuZGVmaW5lZCkudG9TdHJpbmcoKSkudG8uZXF1YWwoXCJhYmMgZGVmIGdoaVwiKTtcbiAgICAgICAgfSk7XG5cbiAgICB9KVxuXG4gICAgZGVzY3JpYmUoJ21hbmlwdWxhdGUgdmFsdWVzJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGxldCBsaXN0XG5cbiAgICAgICAgaXQoJ3Jlc3VsdCBUb2tlbkxpc3QoXCInICsgXCJzdGFydFwiICsgJ1wiKSBzaG91bGQgYmUgXCInICsgXCJzdGFydFwiICsgJ1wiJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGlzdCA9IG5ldyBUb2tlbkxpc3QoXCJzdGFydFwiKTtcbiAgICAgICAgICAgIGV4cGVjdChsaXN0LnRvU3RyaW5nKCkpLmlzLmVxdWFsKFwic3RhcnRcIilcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJy5hZGQoJyArIFwic2Vjb25kXCIgKyAnKSBzaG91bGQgcmV0dXJuIFRva2VuTGlzdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxpc3QgPSBuZXcgVG9rZW5MaXN0KFwic3RhcnRcIik7XG4gICAgICAgICAgICBleHBlY3QobGlzdC5hZGQoXCJzZWNvbmRcIikpLnRvLmJlLmFuLmluc3RhbmNlb2YoVG9rZW5MaXN0KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJy5hZGQoJyArIFwic2Vjb25kXCIgKyAnKS50b1N0cmluZygpIHNob3VsZCByZXR1cm4gXCJzdGFydCBzZWNvbmRcIiAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsaXN0ID0gbmV3IFRva2VuTGlzdChcInN0YXJ0XCIpO1xuICAgICAgICAgICAgZXhwZWN0KGxpc3QuYWRkKFwic2Vjb25kXCIpLnRvU3RyaW5nKCkpLmlzLmVxdWFsKFwic3RhcnQgc2Vjb25kXCIpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnLmFkZCgnICsgXCJzZWNvbmQgdGhpcmRcIiArICcpLnRvU3RyaW5nKCkgc2hvdWxkIHJldHVybiBcInN0YXJ0IHNlY29uZCB0aGlyZFwiICcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxpc3QgPSBuZXcgVG9rZW5MaXN0KFwic3RhcnRcIik7XG4gICAgICAgICAgICBleHBlY3QobGlzdC5hZGQoXCJzZWNvbmQgdGhpcmRcIikudG9TdHJpbmcoKSkuaXMuZXF1YWwoXCJzdGFydCBzZWNvbmQgdGhpcmRcIik7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCcuYWRkKCcgKyBcIltzZWNvbmQsdGhpcmRdXCIgKyAnKS50b1N0cmluZygpIHNob3VsZCByZXR1cm4gXCJzdGFydCBzZWNvbmQgdGhpcmRcIiAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsaXN0ID0gbmV3IFRva2VuTGlzdChcInN0YXJ0XCIpO1xuICAgICAgICAgICAgZXhwZWN0KGxpc3QuYWRkKFtcInNlY29uZFwiLCBcInRoaXJkXCJdKS50b1N0cmluZygpKS5pcy5lcXVhbChcInN0YXJ0IHNlY29uZCB0aGlyZFwiKTtcbiAgICAgICAgfSk7XG5cblxuICAgICAgICBpdCgnLmNsZWFyKCkudG9TdHJpbmcoKSBzaG91bGQgXCJcIiAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsaXN0ID0gbmV3IFRva2VuTGlzdChcInN0YXJ0XCIpO1xuICAgICAgICAgICAgZXhwZWN0KGxpc3QuYWRkKFtcInNlY29uZFwiLCBcInRoaXJkXCJdKS5jbGVhcigpLnRvU3RyaW5nKCkpLmlzLmVxdWFsKFwiXCIpO1xuICAgICAgICB9KTtcblxuXG4gICAgICAgIGl0KCduZXcgVG9rZW5MaXN0KFwic3RhcnQgc2Vjb25kIHRoaXJkIGVuZFwiKS5yZW1vdmUoJyArIFwic2Vjb25kXCIgKyAnKSBzaG91bGQgcmV0dXJuIFRva2VuTGlzdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxpc3QgPSBuZXcgVG9rZW5MaXN0KFwic3RhcnQgc2Vjb25kIHRoaXJkIGVuZFwiKTtcbiAgICAgICAgICAgIGV4cGVjdChsaXN0LnJlbW92ZShcInNlY29uZFwiKSkudG8uYmUuYW4uaW5zdGFuY2VvZihUb2tlbkxpc3QpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnbmV3IFRva2VuTGlzdChcInN0YXJ0IHNlY29uZCB0aGlyZCBlbmRcIikucmVtb3ZlKCcgKyBcInNlY29uZFwiICsgJykudG9TdHJpbmcoKSBzaG91bGQgcmV0dXJuIFwic3RhcnQgdGhpcmQgZW5kXCIgJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGlzdCA9IG5ldyBUb2tlbkxpc3QoXCJzdGFydCBzZWNvbmQgdGhpcmQgZW5kXCIpO1xuICAgICAgICAgICAgZXhwZWN0KGxpc3QucmVtb3ZlKFwic2Vjb25kXCIpLnRvU3RyaW5nKCkpLmlzLmVxdWFsKFwic3RhcnQgdGhpcmQgZW5kXCIpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnbmV3IFRva2VuTGlzdChcInN0YXJ0IHNlY29uZCB0aGlyZCBlbmRcIikucmVtb3ZlKCcgKyBcInNlY29uZCB0aGlyZFwiICsgJykudG9TdHJpbmcoKSBzaG91bGQgcmV0dXJuIFwic3RhcnQgZW5kXCIgJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGlzdCA9IG5ldyBUb2tlbkxpc3QoXCJzdGFydCBzZWNvbmQgdGhpcmQgZW5kXCIpO1xuICAgICAgICAgICAgZXhwZWN0KGxpc3QucmVtb3ZlKFwic2Vjb25kIHRoaXJkXCIpLnRvU3RyaW5nKCkpLmlzLmVxdWFsKFwic3RhcnQgZW5kXCIpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnbmV3IFRva2VuTGlzdChcInN0YXJ0IHNlY29uZCB0aGlyZCBlbmRcIikucmVtb3ZlKCcgKyBcIltzZWNvbmQsdGhpcmRdXCIgKyAnKS50b1N0cmluZygpIHNob3VsZCByZXR1cm4gXCJzdGFydCBlbmRcIiAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsaXN0ID0gbmV3IFRva2VuTGlzdChcInN0YXJ0IHNlY29uZCB0aGlyZCBlbmRcIik7XG4gICAgICAgICAgICBleHBlY3QobGlzdC5yZW1vdmUoW1wic2Vjb25kXCIsIFwidGhpcmRcIl0pLnRvU3RyaW5nKCkpLmlzLmVxdWFsKFwic3RhcnQgZW5kXCIpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnbmV3IFRva2VuTGlzdChcInN0YXJ0IHNlY29uZCB0aGlyZCBlbmRcIikucmVwbGFjZShzZWNvbmQsIHh5eikudG9TdHJpbmcoKSBzaG91bGQgcmV0dXJuIFwic3RhcnQgeHl6IHRoaXJkIGVuZFwiICcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxpc3QgPSBuZXcgVG9rZW5MaXN0KFwic3RhcnQgc2Vjb25kIHRoaXJkIGVuZFwiKTtcbiAgICAgICAgICAgIGV4cGVjdChsaXN0LnJlcGxhY2UoXCJzZWNvbmRcIiwgXCJ4eXpcIikpLnRvLmJlLmluc3RhbmNlT2YoVG9rZW5MaXN0KTtcbiAgICAgICAgICAgIGV4cGVjdChsaXN0LnRvU3RyaW5nKCkpLmlzLmVxdWFsKFwic3RhcnQgeHl6IHRoaXJkIGVuZFwiKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ25ldyBUb2tlbkxpc3QoXCJzdGFydCBzZWNvbmQgdGhpcmQgZW5kXCIpLnJlcGxhY2UoZW5kLCB4eXopLnRvU3RyaW5nKCkgc2hvdWxkIHJldHVybiBcInN0YXJ0IHNlY29uZCB0aGlyZCB4eXpcIiAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsaXN0ID0gbmV3IFRva2VuTGlzdChcInN0YXJ0IHNlY29uZCB0aGlyZCBlbmRcIik7XG4gICAgICAgICAgICBleHBlY3QobGlzdC5yZXBsYWNlKFwiZW5kXCIsIFwieHl6XCIpKS50by5iZS5pbnN0YW5jZU9mKFRva2VuTGlzdCk7XG4gICAgICAgICAgICBleHBlY3QobGlzdC50b1N0cmluZygpKS5pcy5lcXVhbChcInN0YXJ0IHNlY29uZCB0aGlyZCB4eXpcIik7XG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxuXG59KTtcblxuIiwgImltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge2V4dGVuZH0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS9kYXRhL2V4dGVuZC5tanNcIjtcbmltcG9ydCB7aXNPYmplY3R9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvdHlwZXMvaXMubWpzXCI7XG5pbXBvcnQge09ic2VydmVyfSBmcm9tIFwiLi4vLi4vLi4vc291cmNlL3R5cGVzL29ic2VydmVyLm1qc1wiO1xuXG5pbXBvcnQge1Byb3h5T2JzZXJ2ZXJ9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvdHlwZXMvcHJveHlvYnNlcnZlci5tanNcIjtcblxuZGVzY3JpYmUoJ1Byb3h5T2JzZXJ2ZXInLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBkZXNjcmliZSgnY3JlYXRlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBpbnN0YW5jZW9mIFByb3h5T2JzZXJ2ZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgbyA9IG5ldyBQcm94eU9ic2VydmVyKHt9KTtcbiAgICAgICAgICAgIGV4dGVuZChvLmdldFN1YmplY3QoKSwge2E6IDR9KTtcbiAgICAgICAgICAgIGV4cGVjdChvLmdldFJlYWxTdWJqZWN0KCkpLmlzLmVxbCh7YTogNH0pO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdzZXRTdWJqZWN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHJ1biBvYnNlcnZlcicsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICBsZXQgbyA9IG5ldyBQcm94eU9ic2VydmVyKHthOiAxfSk7XG4gICAgICAgICAgICBleHBlY3Qoby5nZXRSZWFsU3ViamVjdCgpKS5pcy5lcWwoe2E6IDF9KTtcbiAgICAgICAgICAgIGxldCBjb3VudGVyID0gMDtcbiAgICAgICAgICAgIG8uYXR0YWNoT2JzZXJ2ZXIobmV3IE9ic2VydmVyKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNPYmplY3QodGhpcykgJiYgdGhpcyBpbnN0YW5jZW9mIFByb3h5T2JzZXJ2ZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgY291bnRlcisrO1xuICAgICAgICAgICAgICAgICAgICAvLyBvbmx5IG9uZSBjaGFuZ2UgYXMgbm90aWZ5IHJ1bnMgbGF0ZXJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvdW50ZXIgPT09IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBkb25lKFwiY2FsbGVkIGZvciBlcnJvclwiKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGRvbmUobmV3IEVycm9yKFwidGhpcyBpcyBub3QgUHJveHlPYnNlcnZlclwiKSlcbiAgICAgICAgICAgIH0pKVxuXG4gICAgICAgICAgICBvLmdldFN1YmplY3QoKS5jID0gNDtcbiAgICAgICAgICAgIGV4cGVjdChvLmdldFJlYWxTdWJqZWN0KCkpLmlzLmVxbCh7YTogMSwgYzogNH0pO1xuXG4gICAgICAgICAgICBvLnNldFN1YmplY3Qoe2I6IDJ9KTtcbiAgICAgICAgICAgIGV4cGVjdChvLmdldFJlYWxTdWJqZWN0KCkpLmlzLmVxbCh7YjogMn0pO1xuXG4gICAgICAgICAgICBvLmdldFN1YmplY3QoKS5kID0gNTtcbiAgICAgICAgICAgIGV4cGVjdChvLmdldFJlYWxTdWJqZWN0KCkpLmlzLmVxbCh7YjogMiwgZDogNX0pO1xuXG5cbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnY3JlYXRlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBpbnN0YW5jZW9mIFByb3h5T2JzZXJ2ZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgbyA9IG5ldyBQcm94eU9ic2VydmVyKHt9KTtcbiAgICAgICAgICAgIGV4cGVjdChvKS5pcy5pbnN0YW5jZU9mKFByb3h5T2JzZXJ2ZXIpO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdwcm94eSBvYmplY3RzJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnUHJveHkgb2JqZWN0cyBzaG91bGQgbm90IGJlIHJlY29tbWl0dGVkJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGV0IG8gPSBuZXcgUHJveHlPYnNlcnZlcih7YToge2I6IHRydWV9fSk7XG4gICAgICAgICAgICBvLmdldFN1YmplY3QoKS5hLmIgPSBvLmdldFN1YmplY3QoKTtcbiAgICAgICAgICAgIG8uZ2V0U3ViamVjdCgpLmEuYi5hLmIgPSBmYWxzZTtcbiAgICAgICAgICAgIC8vZXhwZWN0KG8uZ2V0U3ViamVjdCgpPT09cC5nZXRTdWJqZWN0KCkpLnRvLmJlLnRydWU7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ25vdGlmeSBvYnNlcnZlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCBpbmZvcm0gb2JzZXJ2ZXInLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICAgICAgbGV0IGNvdW50ZXIgPSAwO1xuICAgICAgICAgICAgLy8gdGhlIG1ldGhvZCBpcyBjYWxsZWQgdHdpY2UsIG9uY2UgZm9yIGRlZmluZVByb3BlcnR5IGFuZCBmb3Igc2V0IHRyYXBcbiAgICAgICAgICAgIGxldCBvID0gbmV3IE9ic2VydmVyKGZ1bmN0aW9uIChhKSB7XG4gICAgICAgICAgICAgICAgaWYgKGlzT2JqZWN0KHRoaXMpICYmIHRoaXMgaW5zdGFuY2VvZiBQcm94eU9ic2VydmVyKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvdW50ZXIrKztcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvdW50ZXIgPT09IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZG9uZShuZXcgRXJyb3IoXCJ0aGlzIGlzIG5vdCBQcm94eU9ic2VydmVyXCIpKVxuICAgICAgICAgICAgfSwgdHJ1ZSlcblxuICAgICAgICAgICAgbGV0IHJlYWxTdWJqZWN0ID0ge1xuICAgICAgICAgICAgICAgIGE6IHtcbiAgICAgICAgICAgICAgICAgICAgYjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgYzogdHJ1ZVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBkOiA1XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgcCA9IG5ldyBQcm94eU9ic2VydmVyKHJlYWxTdWJqZWN0KTtcbiAgICAgICAgICAgIGV4cGVjdChwKS5pcy5pbnN0YW5jZU9mKFByb3h5T2JzZXJ2ZXIpO1xuICAgICAgICAgICAgZXhwZWN0KHAuYXR0YWNoT2JzZXJ2ZXIobykpLmlzLmluc3RhbmNlT2YoUHJveHlPYnNlcnZlcik7XG5cbiAgICAgICAgICAgIGxldCBzID0gcC5nZXRTdWJqZWN0KCk7XG4gICAgICAgICAgICBsZXQgciA9IHAuZ2V0UmVhbFN1YmplY3QoKTtcblxuICAgICAgICAgICAgcy5hLmQgPSBmYWxzZTtcbiAgICAgICAgICAgIHMuYS5iLmQgPSAyO1xuXG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQHNlZSBodHRwczovL2dpdGxhYi5zY2h1a2FpLmNvbS9vc3MvbGlicmFyaWVzL2phdmFzY3JpcHQvbW9uc3Rlci8tL2lzc3Vlcy80M1xuICAgICAqL1xuICAgIGRlc2NyaWJlKCdSZWZsZWN0JywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdjaGVjayBSZWZsZWN0LnNldCgpIHdpdGggU3ViamVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCByO1xuXG4gICAgICAgICAgICBjb25zdCBvYmogPSAobmV3IFByb3h5T2JzZXJ2ZXIoe30pKS5nZXRTdWJqZWN0KCk7XG5cbiAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICBcInllcyFcIixcbiAgICAgICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgXCJub1wiXG4gICAgICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgb2JqWydkYXRhJ10gPSB2YWx1ZVxuICAgICAgICAgICAgICAgIH0pLnRvLm5vdC50aHJvdygpO1xuICAgICAgICAgICAgICAgIC8vciA9IFJlZmxlY3Quc2V0KG9iaiwgJ2RhdGEnLCB2YWx1ZSlcbiAgICAgICAgICAgICAgICAvL2V4cGVjdChyKS50by5iZS50cnVlO1xuICAgICAgICAgICAgfSlcblxuXG4gICAgICAgIH0pO1xuXG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWyd0aGF0Jywge3RoYXQ6ICdjaGVja2VkMSd9XSxcbiAgICAgICAgICAgIFsndGhhdCcsIG5ldyBQcm94eSh7dGhhdDogJ2NoZWNrZWQyJ30sIHt9KV0sXG4gICAgICAgICAgICBbJ3RoYXQnLCAobmV3IFByb3h5T2JzZXJ2ZXIoe3RoYXQ6ICdjaGVja2VkMyd9KSkuZ2V0UmVhbFN1YmplY3QoKV0sXG4gICAgICAgICAgICBbJ3RoYXQnLCAobmV3IFByb3h5T2JzZXJ2ZXIoe3RoYXQ6ICdjaGVja2VkNCd9KSkuZ2V0U3ViamVjdCgpXVxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGtleSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IHRhcmdldCA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpdCgnY2hlY2sgUmVmbGVjdC5zZXQoJyArIGtleSArICcsJyArIEpTT04uc3RyaW5naWZ5KHRhcmdldCkgKyAnKSBzaG91bGQgd3JpdGFibGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbGV0IHZhbHVlO1xuXG4gICAgICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgICAgICBcIjFcIixcbiAgICAgICAgICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgICAgICB0cnVlLFxuICAgICAgICAgICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgIHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAodmFsdWVzKSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChSZWZsZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldCwga2V5KVsnd3JpdGFibGUnXSwgJ3dyaXRhYmxlIGZvciAnICsgdmFsdWUgKyAnIHNob3VsZCByZXR1cm4gdHJ1ZScpLnRvLmJlLnRydWU7XG5cbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KFJlZmxlY3Quc2V0KHRhcmdldCwga2V5LCB2YWx1ZSksICdzZXQgZm9yICcgKyB2YWx1ZSArICcgc2hvdWxkIHJldHVybiB0cnVlJykudG8uYmUudHJ1ZTtcblxuICAgICAgICAgICAgICAgICAgICBleHBlY3QoUmVmbGVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoXG4gICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQsIGtleSlbJ3dyaXRhYmxlJ10sICd3cml0YWJsZSBmb3IgJyArIHZhbHVlICsgJyBzaG91bGQgcmV0dXJuIHRydWUnKS50by5iZS50cnVlO1xuXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KVxuICAgICAgICB9KVxuXG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdub3RpZnkgb2JzZXJ2ZXIgd2l0aCBjaGFuZ2VzJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGxldCBvcmlnaW5hbCwgb2JzZXJ2ZXIsIHByb3h5O1xuXG4gICAgICAgIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBvcmlnaW5hbCA9IHt9O1xuICAgICAgICAgICAgcHJveHkgPSBuZXcgUHJveHlPYnNlcnZlcihvcmlnaW5hbCk7XG5cbiAgICAgICAgfSk7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWydhJywgNCwgSlNPTi5zdHJpbmdpZnkoe2E6IDR9KV0sXG4gICAgICAgICAgICBbJ2InLCA5LCBKU09OLnN0cmluZ2lmeSh7YTogNCwgYjogOX0pXVxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYyA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpdCgnc2V0IGtleSAnICsgYSArICcgdmFsdWUgJyArIGIgKyAnIGV4cGVjdCAnICsgYywgZnVuY3Rpb24gKGRvbmUpIHtcblxuICAgICAgICAgICAgICAgIGxldCBjb3VudGVyID0gMDtcbiAgICAgICAgICAgICAgICBvYnNlcnZlciA9IG5ldyBPYnNlcnZlcihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvdW50ZXIrKztcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KEpTT04uc3RyaW5naWZ5KHRoaXMuZ2V0UmVhbFN1YmplY3QoKSkpLmlzLmVxdWFsKGMpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoY291bnRlciA9PT0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kZXRhY2hPYnNlcnZlcihvYnNlcnZlcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICAgICAgcHJveHkuYXR0YWNoT2JzZXJ2ZXIob2JzZXJ2ZXIpXG4gICAgICAgICAgICAgICAgbGV0IHN1YmplY3QgPSBwcm94eS5nZXRTdWJqZWN0KClcblxuICAgICAgICAgICAgICAgIHN1YmplY3RbYV0gPSBiO1xuXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCdub3RpZnkgb2JzZXJ2ZXIgJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIHByb21pc2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgcHJveHkgPSBuZXcgUHJveHlPYnNlcnZlcih7fSk7XG4gICAgICAgICAgICBsZXQgb2JzZXJ2ZXIgPSBuZXcgT2JzZXJ2ZXIoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIHByb3h5LmF0dGFjaE9ic2VydmVyKG9ic2VydmVyKVxuICAgICAgICAgICAgZXhwZWN0KHByb3h5Lm5vdGlmeU9ic2VydmVycygpKS5pcy5pbnN0YW5jZU9mKFByb21pc2UpO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxufSlcblxuIiwgImltcG9ydCB7XG4gICAgVmVyc2lvblxufSBmcm9tIFwiLi4vLi4vLi4vc291cmNlL3R5cGVzL3ZlcnNpb24ubWpzXCJcblxuaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcblxuZGVzY3JpYmUoJ1ZlcnNpb24nLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBkZXNjcmliZSgnLmNvbXBhcmVUbygpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIFtcbiAgICAgICAgICAgIFsnMS4yLjMnLCAnMS4yLjMnLCAwXSxcbiAgICAgICAgICAgIFsnMS4yLjInLCAnMS4yLjMnLCAtMV0sXG4gICAgICAgICAgICBbJzInLCAnMi4wLjAnLCAwXSxcbiAgICAgICAgICAgIFsnMS4yLjQnLCAnMS4yLjMnLCAxXVxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYyA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpdCgnc2hvdWxkIHJldHVybiAnICsgYyArICcgd2hlbiB0aGUgdmFsdWUgJyArIGEgKyAnIGlzICcgKyBiICsgJycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBleHBlY3QobmV3IFZlcnNpb24oYSkuY29tcGFyZVRvKGIpKS50by5iZS5lcXVhbChjKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJy50b1N0cmluZygpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIFtcbiAgICAgICAgICAgIFsnMS4xLjEnLCAnMi4zJywgMywgJzEuMi4zJ10sXG4gICAgICAgICAgICBbJzEuMi40JywgJzEuMi4zJywgNSwgJzEuMS41J11cbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGMgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBkID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGl0KCdzaG91bGQgcmV0dXJuICcgKyBkLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KG5ldyBWZXJzaW9uKGEsIGIsIGMpLnRvU3RyaW5nKCkpLnRvLmJlLmVxdWFsKGQpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH0pXG5cbn0pO1xuXG4iLCAiaW1wb3J0IHtnZXRHbG9iYWwsIGdldEdsb2JhbE9iamVjdCwgZ2V0R2xvYmFsRnVuY3Rpb259IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvdHlwZXMvZ2xvYmFsLm1qc1wiO1xuaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcblxuZGVzY3JpYmUoJ0dsb2JhbCcsIGZ1bmN0aW9uICgpIHtcbiAgICBkZXNjcmliZSgnZ2V0R2xvYmFsJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGdsb2JhbCBvYmplY3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgdCA9IHR5cGVvZiBnZXRHbG9iYWwoKTtcbiAgICAgICAgICAgIGV4cGVjdCh0KS50by5iZS5lcXVhbCgnb2JqZWN0JylcbiAgICAgICAgfSk7XG5cbiAgICB9KTtcbiAgICBkZXNjcmliZSgnZ2V0R2xvYmFsRnVuY3Rpb24nLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gZ2xvYmFsIGZ1bmN0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGV0IHQgPSB0eXBlb2YgZ2V0R2xvYmFsRnVuY3Rpb24oJ3BhcnNlSW50Jyk7XG4gICAgICAgICAgICBleHBlY3QodCkudG8uYmUuZXF1YWwoJ2Z1bmN0aW9uJylcbiAgICAgICAgfSk7XG5cbiAgICB9KTtcbiAgICBkZXNjcmliZSgnZ2V0R2xvYmFsT2JqZWN0JywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGdsb2JhbCBvYmplY3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgdCA9IHR5cGVvZiBnZXRHbG9iYWxPYmplY3QoJ0pTT04nKTtcbiAgICAgICAgICAgIGV4cGVjdCh0KS50by5iZS5lcXVhbCgnb2JqZWN0JylcbiAgICAgICAgfSk7XG5cbiAgICB9KTtcbn0pO1xuXG4iLCAiaW1wb3J0IHtPYnNlcnZlckxpc3R9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvdHlwZXMvb2JzZXJ2ZXJsaXN0Lm1qc1wiO1xuaW1wb3J0IHtPYnNlcnZlcn0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS90eXBlcy9vYnNlcnZlci5tanNcIjtcbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5cbmRlc2NyaWJlKCdPYnNlcnZlckxpc3QnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBkZXNjcmliZSgnLmF0dGFjaCgpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGluc3RhbmNlb2YgT2JzZXJ2ZXJMaXN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGV0IG9ic2VydmVyTGlzdCA9IG5ldyBPYnNlcnZlckxpc3QoKVxuICAgICAgICAgICAgbGV0IHJlc3VsdCA9IG9ic2VydmVyTGlzdC5hdHRhY2gobmV3IE9ic2VydmVyKCgpID0+IHtcbiAgICAgICAgICAgIH0pKVxuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdCkudG8uYmUuaW5zdGFuY2VPZihPYnNlcnZlckxpc3QpXG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCcuZGV0YWNoKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gaW5zdGFuY2VvZiBPYnNlcnZlckxpc3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgb2JzZXJ2ZXJMaXN0ID0gbmV3IE9ic2VydmVyTGlzdCgpXG4gICAgICAgICAgICBsZXQgcmVzdWx0ID0gb2JzZXJ2ZXJMaXN0LmRldGFjaChuZXcgT2JzZXJ2ZXIoKCkgPT4ge1xuICAgICAgICAgICAgfSkpXG4gICAgICAgICAgICBleHBlY3QocmVzdWx0KS50by5iZS5pbnN0YW5jZU9mKE9ic2VydmVyTGlzdClcbiAgICAgICAgfSk7XG5cblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJy5ub3RpZnkoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBjb25zdCByZXN1bHRWYWx1ZSA9IFwiWWVzIVwiO1xuICAgICAgICBsZXQgbztcbiAgICAgICAgbGV0IG9ic2VydmVyTGlzdDtcblxuICAgICAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAgICAgIG8gPSBuZXcgT2JzZXJ2ZXIoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHRWYWx1ZVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIG9ic2VydmVyTGlzdCA9IG5ldyBPYnNlcnZlckxpc3QoKVxuICAgICAgICAgICAgb2JzZXJ2ZXJMaXN0LmF0dGFjaChvKVxuXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgaW5zdGFuY2VvZiBQcm9taXNlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KG9ic2VydmVyTGlzdC5ub3RpZnkoe30pKS50by5iZS5pbnN0YW5jZU9mKFByb21pc2UpXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuICcgKyByZXN1bHRWYWx1ZSwgZnVuY3Rpb24gKGRvbmUpIHtcblxuICAgICAgICAgICAgbGV0IG9iaiA9IHt9XG5cbiAgICAgICAgICAgIG9ic2VydmVyTGlzdC5ub3RpZnkob2JqKS50aGVuKHIgPT4ge1xuICAgICAgICAgICAgICAgIGV4cGVjdChyKS50by5iZS5hbignYXJyYXknKS50aGF0LmluY2x1ZGVzKHJlc3VsdFZhbHVlKTtcbiAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICB9KS5jYXRjaChlID0+IHtcbiAgICAgICAgICAgICAgICBkb25lKG5ldyBFcnJvcihlKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJy5jb250YWlucygpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGxldCBvMSA9IG5ldyBPYnNlcnZlcigoKSA9PiB7XG4gICAgICAgIH0pO1xuICAgICAgICBsZXQgbzIgPSBuZXcgT2JzZXJ2ZXIoKCkgPT4ge1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIG5vdCBjb250YWluIG8xIGFuZCBvMicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBvYnNlcnZlckxpc3QgPSBuZXcgT2JzZXJ2ZXJMaXN0KClcblxuICAgICAgICAgICAgZXhwZWN0KG9ic2VydmVyTGlzdC5jb250YWlucyhvMSkpLnRvLmJlLmZhbHNlO1xuICAgICAgICAgICAgZXhwZWN0KG9ic2VydmVyTGlzdC5jb250YWlucyhvMikpLnRvLmJlLmZhbHNlO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIGNvbnRhaW4gbzIgYW5kIG5vdCBvMScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBvYnNlcnZlckxpc3QgPSBuZXcgT2JzZXJ2ZXJMaXN0KClcbiAgICAgICAgICAgIG9ic2VydmVyTGlzdC5hdHRhY2gobzIpXG4gICAgICAgICAgICBleHBlY3Qob2JzZXJ2ZXJMaXN0LmNvbnRhaW5zKG8xKSkudG8uYmUuZmFsc2U7XG4gICAgICAgICAgICBleHBlY3Qob2JzZXJ2ZXJMaXN0LmNvbnRhaW5zKG8yKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBjb250YWluIG8xIGFuZCBub3QgbzInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgb2JzZXJ2ZXJMaXN0ID0gbmV3IE9ic2VydmVyTGlzdCgpXG4gICAgICAgICAgICBvYnNlcnZlckxpc3QuYXR0YWNoKG8xKVxuICAgICAgICAgICAgZXhwZWN0KG9ic2VydmVyTGlzdC5jb250YWlucyhvMSkpLnRvLmJlLnRydWU7XG4gICAgICAgICAgICBleHBlY3Qob2JzZXJ2ZXJMaXN0LmNvbnRhaW5zKG8yKSkudG8uYmUuZmFsc2U7XG4gICAgICAgIH0pO1xuXG5cbiAgICAgICAgaXQoJ3Nob3VsZCBjb250YWluIG8yIGFuZCBvMScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBvYnNlcnZlckxpc3QgPSBuZXcgT2JzZXJ2ZXJMaXN0KClcbiAgICAgICAgICAgIG9ic2VydmVyTGlzdC5hdHRhY2gobzIpLmF0dGFjaChvMSlcbiAgICAgICAgICAgIGV4cGVjdChvYnNlcnZlckxpc3QuY29udGFpbnMobzEpKS50by5iZS50cnVlO1xuICAgICAgICAgICAgZXhwZWN0KG9ic2VydmVyTGlzdC5jb250YWlucyhvMikpLnRvLmJlLnRydWU7XG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxuXG59KTtcblxuIiwgIlwidXNlIHN0cmljdFwiO1xuXG5pbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuaW1wb3J0IHtlcXVpcFdpdGhJbnRlcm5hbH0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS90eXBlcy9pbnRlcm5hbC5tanNcIjtcbmltcG9ydCB7T2JzZXJ2ZXJ9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvdHlwZXMvb2JzZXJ2ZXIubWpzXCI7XG5cbmNsYXNzIFNvbWVSYW5kb21DbGFzczEgZXh0ZW5kcyBPYmplY3Qge1xuXG4gICAgZG9pdCgpIHtcbiAgICAgICAgcmV0dXJuIFwiZG9uZVwiO1xuICAgIH1cbn1cblxuY2xhc3MgU29tZVJhbmRvbUNsYXNzMiBleHRlbmRzIE9iamVjdCB7XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgZXF1aXBXaXRoSW50ZXJuYWwuY2FsbCh0aGlzKTtcbiAgICB9XG5cbiAgICBnZXQgZGVmYXVsdEludGVybmFsKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdGVzdDogXCJ0ZXN0XCJcbiAgICAgICAgfVxuICAgIH1cblxufVxuXG5kZXNjcmliZSgnQmFzZSBpbmplY3Qgd2l0aCBvcHRpb25zJywgZnVuY3Rpb24gKCkge1xuXG4gICAgZGVzY3JpYmUoJ25ldyBTb21lUmFuZG9tQ2xhc3MnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ2lzIGluc3RhbmNlIG9mIFNvbWVSYW5kb21DbGFzczEnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IFNvbWVSYW5kb21DbGFzczIpLm5vdC50by5iZS5pbnN0YW5jZU9mKFNvbWVSYW5kb21DbGFzczEpO1xuICAgICAgICAgICAgZXhwZWN0KG5ldyBTb21lUmFuZG9tQ2xhc3MyKS50by5iZS5pbnN0YW5jZU9mKFNvbWVSYW5kb21DbGFzczIpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnaXMgaW5zdGFuY2Ugb2YgU29tZVJhbmRvbUNsYXNzMicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgU29tZVJhbmRvbUNsYXNzMSkudG8uYmUuaW5zdGFuY2VPZihTb21lUmFuZG9tQ2xhc3MxKTtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgU29tZVJhbmRvbUNsYXNzMSkubm90LnRvLmJlLmluc3RhbmNlT2YoU29tZVJhbmRvbUNsYXNzMik7XG4gICAgICAgIH0pO1xuXG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCdFeHRlbmRzIFNvbWVSYW5kb21DbGFzcyB3aXRoIGludGVybmFscycsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBpdCgnYXR0YWNoIGFuZCBub3RpZnkgaW50ZXJuYWwgb2JzZXJ2ZXInLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICAgICAgY29uc3QgYyA9IG5ldyBTb21lUmFuZG9tQ2xhc3MyO1xuICAgICAgICAgICAgYy5hdHRhY2hJbnRlcm5hbE9ic2VydmVyKG5ldyBPYnNlcnZlcigoKSA9PiB7XG4gICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICBjLnNldEludGVybmFsKFwidGVzdFwiLCBcInRlc3RcIik7XG5cbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ2F0dGFjaCBhbmQgcmVtb3ZlIGludGVybmFsIG9ic2VydmVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY29uc3QgYyA9IG5ldyBTb21lUmFuZG9tQ2xhc3MyO1xuXG5cbiAgICAgICAgICAgIGNvbnN0IG9ic2VydmVyID0gbmV3IE9ic2VydmVyKCgpID0+IHtcblxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGV4cGVjdChjLmNvbnRhaW5zSW50ZXJuYWxPYnNlcnZlcihvYnNlcnZlcikpLnRvLmJlLmZhbHNlO1xuICAgICAgICAgICAgYy5hdHRhY2hJbnRlcm5hbE9ic2VydmVyKG9ic2VydmVyKTtcbiAgICAgICAgICAgIGV4cGVjdChjLmNvbnRhaW5zSW50ZXJuYWxPYnNlcnZlcihvYnNlcnZlcikpLnRvLmJlLnRydWU7XG4gICAgICAgICAgICBjLmRldGFjaEludGVybmFsT2JzZXJ2ZXIob2JzZXJ2ZXIpO1xuICAgICAgICAgICAgZXhwZWN0KGMuY29udGFpbnNJbnRlcm5hbE9ic2VydmVyKG9ic2VydmVyKSkudG8uYmUuZmFsc2U7XG5cbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoXCJnZXRJbnRlcm5hbCBhbmQgc2V0SW50ZXJuYWxcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY29uc3QgYyA9IG5ldyBTb21lUmFuZG9tQ2xhc3MyO1xuICAgICAgICAgICAgZXhwZWN0KGMuc2V0SW50ZXJuYWwoXCJ0ZXN0XCIsIFwieWVhaFwiKSkudG8uYmUuaW5zdGFuY2VPZihTb21lUmFuZG9tQ2xhc3MyKTtcbiAgICAgICAgICAgIGV4cGVjdChjLmdldEludGVybmFsKFwidGVzdFwiKSkudG8uYmUuZXF1YWwoXCJ5ZWFoXCIpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdChcImRlYWwgd2l0aCBkZWZhdWx0IHZhbHVlc1wiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zdCB0ZXN0Q2xhc3MgPSBjbGFzcyBleHRlbmRzIE9iamVjdCB7XG4gICAgICAgICAgICAgICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgICAgICAgICAgICAgIHN1cGVyKCk7XG4gICAgICAgICAgICAgICAgICAgIGVxdWlwV2l0aEludGVybmFsLmNhbGwodGhpcyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZ2V0IGludGVybmFsRGVmYXVsdHMoKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXN0OiBcInh5elwiXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cblxuICAgICAgICAgICAgY29uc3QgYyA9IG5ldyB0ZXN0Q2xhc3M7XG4gICAgICAgICAgICBleHBlY3QoYy5nZXRJbnRlcm5hbChcInRlc3RcIikpLnRvLmJlLmVxdWFsKFwieHl6XCIpO1xuICAgICAgICAgICAgZXhwZWN0KGMuZ2V0SW50ZXJuYWwoXCJ0ZXN0MlwiLCBcImFiY1wiKSkudG8uYmUuZXF1YWwoXCJhYmNcIik7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KFwiZGVhbCB3aXRoIGRlZmF1bHRzIGZyb20gZGVmYXVsdHNcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY29uc3QgdGVzdENsYXNzID0gY2xhc3MgZXh0ZW5kcyBPYmplY3Qge1xuICAgICAgICAgICAgICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICAgICAgICAgICAgICBzdXBlcigpO1xuICAgICAgICAgICAgICAgICAgICBlcXVpcFdpdGhJbnRlcm5hbC5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGdldCBpbnRlcm5hbERlZmF1bHRzKCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGVzdDogXCJ4eXpcIlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCB0ZXN0Q2xhc3MyID0gY2xhc3MgZXh0ZW5kcyB0ZXN0Q2xhc3Mge1xuICAgICAgICAgICAgICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICAgICAgICAgICAgICBzdXBlcigpO1xuICAgICAgICAgICAgICAgICAgICBlcXVpcFdpdGhJbnRlcm5hbC5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGdldCBpbnRlcm5hbERlZmF1bHRzKCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3VwZXIuaW50ZXJuYWxEZWZhdWx0cywge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGVzdDI6IFwiYWJjXCJcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGMgPSBuZXcgdGVzdENsYXNzMjtcbiAgICAgICAgICAgIGV4cGVjdChjLmdldEludGVybmFsKFwidGVzdFwiKSkudG8uYmUuZXF1YWwoXCJ4eXpcIik7XG4gICAgICAgICAgICBleHBlY3QoYy5nZXRJbnRlcm5hbChcInRlc3QyXCIpKS50by5iZS5lcXVhbChcImFiY1wiKTtcbiAgICAgICAgfSk7XG4gICAgICAgIFxuICAgICAgICBpdChcInNldCBtdWx0aXBsZSB2YWx1ZXNcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY29uc3QgYyA9IG5ldyBTb21lUmFuZG9tQ2xhc3MyO1xuICAgICAgICAgICAgZXhwZWN0KGMuc2V0SW50ZXJuYWxzKHtcbiAgICAgICAgICAgICAgICB0ZXN0OiBcInllYWhcIixcbiAgICAgICAgICAgICAgICB0ZXN0MjogXCJ5ZWFoMlwiXG4gICAgICAgICAgICB9KSkudG8uYmUuaW5zdGFuY2VPZihTb21lUmFuZG9tQ2xhc3MyKTtcbiAgICAgICAgICAgIGV4cGVjdChjLmdldEludGVybmFsKFwidGVzdFwiKSkudG8uYmUuZXF1YWwoXCJ5ZWFoXCIpO1xuICAgICAgICAgICAgZXhwZWN0KGMuZ2V0SW50ZXJuYWwoXCJ0ZXN0MlwiKSkudG8uYmUuZXF1YWwoXCJ5ZWFoMlwiKTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgYy5zZXRJbnRlcm5hbHMoe1xuICAgICAgICAgICAgICAgIHRlc3QyOiBcInllYWgyLW5ld1wiLFxuICAgICAgICAgICAgICAgIHRlc3QzOiBcInllYWgzXCJcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgXG4gICAgICAgICAgICBleHBlY3QoYy5nZXRJbnRlcm5hbChcInRlc3RcIikpLnRvLmJlLmVxdWFsKFwieWVhaFwiKTtcbiAgICAgICAgICAgIGV4cGVjdChjLmdldEludGVybmFsKFwidGVzdDJcIikpLnRvLmJlLmVxdWFsKFwieWVhaDItbmV3XCIpO1xuICAgICAgICAgICAgZXhwZWN0KGMuZ2V0SW50ZXJuYWwoXCJ0ZXN0M1wiKSkudG8uYmUuZXF1YWwoXCJ5ZWFoM1wiKTtcbiAgICAgICAgfSk7XG5cbiAgICB9KTtcblxuXG59KSIsICJpbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuaW1wb3J0IHtPYnNlcnZhYmxlUXVldWV9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvdHlwZXMvb2JzZXJ2YWJsZXF1ZXVlLm1qc1wiO1xuaW1wb3J0IHtPYnNlcnZlcn0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS90eXBlcy9vYnNlcnZlci5tanNcIjtcblxuZGVzY3JpYmUoJ09ic2VydmFibGVRdWV1ZScsIGZ1bmN0aW9uICgpIHtcbiAgICBkZXNjcmliZSgnT2JzZXJ2ZXInLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBub3RpZnknLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICAgICAgbGV0IHF1ZXVlID0gbmV3IE9ic2VydmFibGVRdWV1ZTtcbiAgICAgICAgICAgIGxldCBvID0gbmV3IE9ic2VydmVyKChxKSA9PiB7XG4gICAgICAgICAgICAgICAgZG9uZSgpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHF1ZXVlLmF0dGFjaE9ic2VydmVyKG8pO1xuICAgICAgICAgICAgZXhwZWN0KHF1ZXVlLmFkZCgnYScpKS50by5iZS5pbnN0YW5jZU9mKE9ic2VydmFibGVRdWV1ZSk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xufSkiLCAiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuaW1wb3J0IHtwYXJzZURhdGFVUkx9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvdHlwZXMvZGF0YXVybC5tanNcIjtcblxuZGVzY3JpYmUoJ0RhdGF1cmwnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBbXG4gICAgICAgIFtcIiBkYXRhOnRleHQvaHRtbCwlM0NoMSUzRUhlbGxvJTJDJTIwV29ybGQhJTNDJTJGaDElM0VcIl0sXG4gICAgICAgIFtcImRhdGE6dGV4dC9odG1sO2NoYXJzZXQ9VVMtQVNDSUksJTNDaDElM0VIZWxsbyElM0MlMkZoMSUzRVwiXSxcbiAgICAgICAgW1wiZGF0YTosQSUyMGJyaWVmJTIwbm90ZVwiLCAnZGF0YTp0ZXh0L3BsYWluO2NoYXJzZXQ9VVMtQVNDSUksQSUyMGJyaWVmJTIwbm90ZSddLFxuICAgICAgICBbXCJkYXRhOmltYWdlL3BuZztiYXNlNjQsaVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUJBQUFBQVFBUU1BQUFBbFBXMGlBQUFBQmxCTVZFVUFBQUQvLy8rbDJaL2RBQUFBTTBsRVFWUjRuR1A0LzUvaC8xK0cvNThaRHJBejNEL01jSDh5dzgzTkREZU5HZTRVZzlDOXp3ejNnVkxNREEvQTZQOS9BRkdHRnlqT1hadFFBQUFBQUVsRlRrU3VRbUNDXCJdLFxuICAgICAgICBbXCIgZGF0YTosSGVsbG8lMkMlMjBXb3JsZCFcIiwgJ2RhdGE6dGV4dC9wbGFpbjtjaGFyc2V0PVVTLUFTQ0lJLEhlbGxvJTJDJTIwV29ybGQhJ10sXG4gICAgICAgIFtcIiAgIGRhdGE6aW1hZ2UvcG5nO2Jhc2U2NCxpVkJPUncwS0dnb0FBQUFOU1VoRVVnQUFBQWdBQUFBSUJBTUFBQUEySWFPNEFBQUFGVkJNVkVYazVPVG41K2Z0N2UzMTlmWDI5dmI1K2ZuLy8vKytHVW1WQUFBQUxVbEVRVlFJSFdOSUNuWUxabkFMVGdwbU1HWUlGV1lJWlRBMlpGQXpUVEZsU0RGVk13VnlRaG1Bd3NZTUFLRGFCeTBheFgvaUFBQUFBRWxGVGtTdVFtQ0MgICBcIl0sXG4gICAgICAgIFtcIiBkYXRhOixIZWxsbyBXb3JsZCFcIiwgJ2RhdGE6dGV4dC9wbGFpbjtjaGFyc2V0PVVTLUFTQ0lJLEhlbGxvJTIwV29ybGQhJ10sXG4gICAgICAgIFtcImRhdGE6aW1hZ2UvcG5nO2Jhc2U2NCxpVkJPUncwS0dnb0FBQUFOU1VoRVVnQUFBQWdBQUFBSUJBTUFBQUEySWFPNEFBQUFGVkJNVkVYazVPVG41K2Z0N2UzMTlmWDI5dmI1K2ZuLy8vKytHVW1WQUFBQUxVbEVRVlFJSFdOSUNuWUxabkFMVGdwbU1HWUlGV1lJWlRBMlpGQXpUVEZsU0RGVk13VnlRaG1Bd3NZTUFLRGFCeTBheFgvaUFBQUFBRWxGVGtTdVFtQ0NcIl0sXG4gICAgICAgIFtcIiBkYXRhOnRleHQvcGxhaW47YmFzZTY0LFNHVnNiRzhzSUZkdmNteGtJUSUzRCUzRFwiXVxuXG5cbiAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgIGlmIChiID09PSB1bmRlZmluZWQpIGIgPSBhLnRyaW0oKTtcblxuXG4gICAgICAgIGl0KCdwYXJzZURhdGFVUkwoJyArIGEgKyAnKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgZXhwZWN0KHBhcnNlRGF0YVVSTChhKS50b1N0cmluZygpKS50by5iZS5lcXVhbChiKTtcbiAgICAgICAgfSlcblxuICAgIH0pO1xuXG4gICAgW1xuICAgICAgICBbXCJkYXRheGJhc2U2NFwiXSxcbiAgICAgICAgW1wiZGF0YTpIZWxsb1dvcmxkXCJdLFxuICAgICAgICBbXCJkYXRhOnRleHQvaHRtbDtjaGFyc2V0PSwlM0NoMSUzRUhlbGxvISUzQyUyRmgxJTNFXCJdLFxuICAgICAgICBbXCJkYXRhOnRleHQvaHRtbDtjaGFyc2V0LCUzQ2gxJTNFSGVsbG8hJTNDJTJGaDElM0VcIiwgXCJkYXRhOmJhc2U2NCxpVkJPUncwS0dnb0FBQUFOU1VoRVVnQUFBQkFBQUFBUUFRTUFBQUFsUFcwaUFBQUFCbEJNVkVVQUFBRC8vLytsMlovZEFBQUFNMGxFUVZSNG5HUDQvNS9oLzErRy81OFpEckF6M0QvTWNIOHl3ODNORERlTkdlNFVnOUM5end6M2dWTE1EQS9BNlA5L0FGR0dGeWpPWFp0UUFBQUFBRWxGVGtTdVFtQ0NcIl0sXG4gICAgICAgIFtcIlwiXSxcbiAgICAgICAgW1wiaHR0cDovL3dpa2lwZWRpYS5vcmdcIl0sXG4gICAgICAgIFtcImJhc2U2NFwiXSxcbiAgICAgICAgW1wiaVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUJBQUFBQVFBUU1BQUFBbFBXMGlBQUFBQmxCTVZFVUFBQUQvLy8rbDJaL2RBQUFBTTBsRVFWUjRuR1A0LzUvaC8xK0cvNThaRHJBejNEL01jSDh5dzgzTkREZU5HZTRVZzlDOXp3ejNnVkxNREEvQTZQOS9BRkdHRnlqT1hadFFBQUFBQUVsRlRrU3VRbUNDXCJdXG5cbiAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuXG5cbiAgICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBleGNlcHRpb24gcGFyc2VEYXRhVVJMKCcgKyBhICsgJyknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIGV4cGVjdCgoKSA9PiBwYXJzZURhdGFVUkwoYSkpLnRocm93KFR5cGVFcnJvcilcbiAgICAgICAgfSlcblxuICAgIH0pO1xuXG5cbn0pOyIsICIvKipcbiAqIENvcHlyaWdodCBzY2h1a2FpIEdtYkggYW5kIGNvbnRyaWJ1dG9ycyAyMDIzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTm9kZSBtb2R1bGU6IEBzY2h1a2FpL21vbnN0ZXJcbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQUdQTHYzIExpY2Vuc2UuXG4gKiBMaWNlbnNlIHRleHQgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAuZW4uaHRtbFxuICovXG5cbmltcG9ydCB7IHZhbGlkYXRlU3RyaW5nIH0gZnJvbSBcIi4vdmFsaWRhdGUubWpzXCI7XG5cbmV4cG9ydCB7IHRvQmluYXJ5LCBmcm9tQmluYXJ5IH07XG5cbi8qKlxuICogWW91IGNhbiBjYWxsIHRoZSBmdW5jdGlvbiB2aWEgdGhlIG1vbnN0ZXIgbmFtZXNwYWNlIGBNb25zdGVyLlR5cGVzLnRvQmluYXJ5KClgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBiaW5hcnlcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgc3RyaW5nXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UeXBlc1xuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4xOC4wXG4gKi9cbmZ1bmN0aW9uIHRvQmluYXJ5KHN0cmluZykge1xuICAgIGNvbnN0IGNvZGVVbml0cyA9IG5ldyBVaW50MTZBcnJheSh2YWxpZGF0ZVN0cmluZyhzdHJpbmcpLmxlbmd0aCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb2RlVW5pdHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29kZVVuaXRzW2ldID0gc3RyaW5nLmNoYXJDb2RlQXQoaSk7XG4gICAgfVxuXG4gICAgY29uc3QgY2hhckNvZGVzID0gbmV3IFVpbnQ4QXJyYXkoY29kZVVuaXRzLmJ1ZmZlcik7XG4gICAgbGV0IHJlc3VsdCA9IFwiXCI7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNoYXJDb2Rlcy5ieXRlTGVuZ3RoOyBpKyspIHtcbiAgICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoY2hhckNvZGVzW2ldKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIFlvdSBjYW4gY2FsbCB0aGUgZnVuY3Rpb24gdmlhIHRoZSBtb25zdGVyIG5hbWVzcGFjZSBgTW9uc3Rlci5UeXBlcy5mcm9tQmluYXJ5KClgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBiaW5hcnlcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgc3RyaW5nXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5UeXBlc1xuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4xOC4wXG4gKi9cbmZ1bmN0aW9uIGZyb21CaW5hcnkoYmluYXJ5KSB7XG4gICAgY29uc3QgYnl0ZXMgPSBuZXcgVWludDhBcnJheSh2YWxpZGF0ZVN0cmluZyhiaW5hcnkpLmxlbmd0aCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBieXRlc1tpXSA9IGJpbmFyeS5jaGFyQ29kZUF0KGkpO1xuICAgIH1cbiAgICBjb25zdCBjaGFyQ29kZXMgPSBuZXcgVWludDE2QXJyYXkoYnl0ZXMuYnVmZmVyKTtcbiAgICBsZXQgcmVzdWx0ID0gXCJcIjtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNoYXJDb2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShjaGFyQ29kZXNbaV0pO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuIiwgIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7ZnJvbUJpbmFyeSwgdG9CaW5hcnl9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvdHlwZXMvYmluYXJ5Lm1qc1wiO1xuXG5kZXNjcmliZSgnQmluYXJ5JywgZnVuY3Rpb24gKCkge1xuXG4gICAgW1xuICAgICAgICBbJ2EnLCAnYVxcdTAwMDAnXSxcbiAgICAgICAgWydcdTI2MzknLCAnOSYnXSxcbiAgICAgICAgWydJXHUwMEYxdFx1MDBFQnJuXHUwMEUydGlcdTAwRjRuXHUwMEUwbGl6XHUwMEU2dGlcdTAwRjhuJywgJ0lcXHUwMDAwXHUwMEYxXFx1MDAwMHRcXHUwMDAwXHUwMEVCXFx1MDAwMHJcXHUwMDAwblxcdTAwMDBcdTAwRTJcXHUwMDAwdFxcdTAwMDBpXFx1MDAwMFx1MDBGNFxcdTAwMDBuXFx1MDAwMFx1MDBFMFxcdTAwMDBsXFx1MDAwMGlcXHUwMDAwelxcdTAwMDBcdTAwRTZcXHUwMDAwdFxcdTAwMDBpXFx1MDAwMFx1MDBGOFxcdTAwMDBuXFx1MDAwMCddXG5cbiAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgIGl0KCdmcm9tQmluYXJ5KHRvQmluYXJ5KCcgKyBhICsgJykpIHNob3VsZCB3b3JrJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGV0IHIgPSB0b0JpbmFyeShhKTtcbiAgICAgICAgICAgIGV4cGVjdChyKS50by5iZS5lcXVhbChiKTtcbiAgICAgICAgICAgIGV4cGVjdChmcm9tQmluYXJ5KHIpKS50by5iZS5lcXVhbChhKTtcbiAgICAgICAgfSlcblxuICAgIH0pO1xuXG5cbn0pOyIsICJpbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuXG5pbXBvcnQge09ic2VydmVyfSBmcm9tIFwiLi4vLi4vLi4vc291cmNlL3R5cGVzL29ic2VydmVyLm1qc1wiO1xuXG5cbmRlc2NyaWJlKCdPYnNlcnZlcicsIGZ1bmN0aW9uICgpIHtcblxuICAgIGxldCBjYWxsYmFjayA9IGZ1bmN0aW9uICgpIHtcbiAgICB9O1xuXG4gICAgbGV0IG9ic2VydmVyID0gbmV3IE9ic2VydmVyKGNhbGxiYWNrKVxuXG4gICAgZGVzY3JpYmUoJy5hZGRUYWcoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBbXG4gICAgICAgICAgICBbJ3Rlc3QxJ10sXG4gICAgICAgICAgICBbJ3Rlc3QyJ10sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpdCgnYWRkVGFnKCcgKyBhICsgJykgc2hvdWxkIHJldHVybiBpbnN0YW5jZW9mIE9ic2VydmVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGV4cGVjdChvYnNlcnZlci5hZGRUYWcoYSkpLmlzLmluc3RhbmNlT2YoT2JzZXJ2ZXIpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCcucmVtb3ZlVGFnKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWyd0ZXN0MSddLFxuICAgICAgICAgICAgWyd0ZXN0MiddLFxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ3JlbW92ZVRhZygnICsgYSArICcpIHNob3VsZCByZXR1cm4gaW5zdGFuY2VvZiBPYnNlcnZlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBleHBlY3Qob2JzZXJ2ZXIucmVtb3ZlVGFnKGEpKS5pcy5pbnN0YW5jZU9mKE9ic2VydmVyKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnLmhhc1RhZygpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIFtcbiAgICAgICAgICAgIFsndGVzdDEnLCB0cnVlXSxcbiAgICAgICAgICAgIFsndGVzdDInLCB0cnVlXSxcbiAgICAgICAgICAgIFsndGVzdDMnLCBmYWxzZV0sXG4gICAgICAgICAgICBbJ3Rlc3Q0JywgZmFsc2VdLFxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IHRlbXBPYnNlcnZlciA9IG5ldyBPYnNlcnZlcihjYWxsYmFjaylcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGl0KCdvYnNlcnZlci5oYXN0VGFnKCcgKyBhICsgJykgc2hvdWxkIHJldHVybiAnICsgYiwgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICAgICAgaWYgKGIgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGVtcE9ic2VydmVyLmFkZFRhZyhhKVxuICAgICAgICAgICAgICAgICAgICBleHBlY3QodGVtcE9ic2VydmVyLmhhc1RhZyhhKSkuaXMuYmUudHJ1ZVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdCh0ZW1wT2JzZXJ2ZXIuaGFzVGFnKGEpKS5pcy5iZS5mYWxzZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJy51cGRhdGUoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBsZXQgb2JqID0ge31cbiAgICAgICAgaXQoJ29ic2VydmVyLnVwZGF0ZSgnICsgb2JqICsgJykgaXMgJyArIDEgKyAzICsgNiwgZnVuY3Rpb24gKGRvbmUpIHtcblxuICAgICAgICAgICAgbGV0IHRlbXBPYnNlcnZlciA9IG5ldyBPYnNlcnZlcihmdW5jdGlvbiAoYSwgYiwgYykge1xuICAgICAgICAgICAgICAgIHJldHVybiBhICsgYiArIGNcbiAgICAgICAgICAgIH0sIDEsIDMsIDYpXG5cblxuICAgICAgICAgICAgdGVtcE9ic2VydmVyLnVwZGF0ZShvYmopLnRoZW4oYSA9PiB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGEpLmlzLmVxdWFsKDEgKyAzICsgNilcbiAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdydW4gZnVuY3Rpb24gLnVwZGF0ZSgpIHNldmVyYWwgdGltZXMnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgbGV0IG9iaiA9IHt9XG4gICAgICAgIGl0KCdvYnNlcnZlci51cGRhdGUoJyArIG9iaiArICcpIGlzICcgKyAxICsgMyArIDYsIGZ1bmN0aW9uIChkb25lKSB7XG5cbiAgICAgICAgICAgIGxldCBjb3VudGVyID0gMDtcbiAgICAgICAgICAgIGxldCB0ZW1wT2JzZXJ2ZXIgPSBuZXcgT2JzZXJ2ZXIoZnVuY3Rpb24gKGEsIGIsIGMpIHtcbiAgICAgICAgICAgICAgICBjb3VudGVyKys7XG4gICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICB0ZW1wT2JzZXJ2ZXIudXBkYXRlKG9iaik7XG4gICAgICAgICAgICB0ZW1wT2JzZXJ2ZXIudXBkYXRlKG9iaik7XG4gICAgICAgICAgICB0ZW1wT2JzZXJ2ZXIudXBkYXRlKG9iaik7XG4gICAgICAgICAgICB0ZW1wT2JzZXJ2ZXIudXBkYXRlKG9iaik7XG4gICAgICAgICAgICB0ZW1wT2JzZXJ2ZXIudXBkYXRlKG9iaikudGhlbihfID0+IHtcbiAgICAgICAgICAgICAgICBkb25lKClcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnLmdldFRhZ3MoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBbXG4gICAgICAgICAgICBbWyd0ZXN0MScsICd0ZXN0MicsICd0ZXN0MycsICd0ZXN0NCddLCA0XSxcbiAgICAgICAgICAgIFtbJ3Rlc3QxJywgJ3Rlc3QxJywgJ3Rlc3QzJywgJ3Rlc3Q0J10sIDNdLCAvLyBkb3VibGUgdGVzdDEgKHNldCBpcyB1bmlxdWV1ZSlcbiAgICAgICAgICAgIFtbJ3Rlc3QxJywgJ3Rlc3QxJywgJ3Rlc3QxJywgJ3Rlc3Q0J10sIDJdLCAvLyBtdWx0aXBsZSB0ZXN0MSAoc2V0IGlzIHVuaXF1ZXVlKVxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IHRlbXBPYnNlcnZlciA9IG5ldyBPYnNlcnZlcihjYWxsYmFjaylcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBtYXggPSBhLmxlbmd0aDsgaSA8IG1heDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdGVtcE9ic2VydmVyLmFkZFRhZyhhW2ldKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaXQoJ29ic2VydmVyLmdldFRhZ3MoJyArIGEgKyAnKSBpcyBhcnJheScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBleHBlY3QodGVtcE9ic2VydmVyLmdldFRhZ3MoKSkudG8uYmUuYW4oJ2FycmF5JylcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpdCgnb2JzZXJ2ZXIuZ2V0VGFncygnICsgYSArICcpIHNob3VsZCByZXR1cm4gJyArIGIgKyBcIiB0YWdzXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBleHBlY3QodGVtcE9ic2VydmVyLmdldFRhZ3MoKS5sZW5ndGgpLmlzLmVxdWFsKGIpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cbn0pO1xuXG4iLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyB2YWxpZGF0ZVN0cmluZyB9IGZyb20gXCIuL3ZhbGlkYXRlLm1qc1wiO1xuXG5leHBvcnQgeyBlc2NhcGVTdHJpbmcgfTtcblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIHByZWZpeGVzIGFsbCBzcGVjaWFsIGNoYXJhY3RlcnMgdGhhdCBtYXkgYXBwZWFyIGluIGEgcmVnZXggd2l0aCBhIHNsYXNoLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZVxuICogQHJldHVybiB7c3RyaW5nfVxuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNi4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgc3RyaW5nXG4gKi9cbmZ1bmN0aW9uIGVzY2FwZVN0cmluZyh2YWx1ZSkge1xuICAgIHJldHVybiB2YWxpZGF0ZVN0cmluZyh2YWx1ZSkucmVwbGFjZSgvW3xcXFxce30oKVtcXF1eJCsqPy5dL2csIFwiXFxcXCQmXCIpLnJlcGxhY2UoLy0vZywgXCJcXFxceDJkXCIpO1xufVxuIiwgIlxuaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7ZXNjYXBlU3RyaW5nfSBmcm9tIFwiLi4vLi4vLi4vc291cmNlL3R5cGVzL3JlZ2V4Lm1qc1wiXG5pbXBvcnQge2luaXRKU0RPTX0gZnJvbSBcIi4uLy4uL3V0aWwvanNkb20ubWpzXCI7XG5cblxuZGVzY3JpYmUoJ2VzY2FwZVN0cmluZycsIGZ1bmN0aW9uICgpIHtcblxuICAgIGJlZm9yZShmdW5jdGlvbiAoZG9uZSkge1xuXG4gICAgICAgIGxldCBwcm9taXNlcyA9IFtdXG4gICAgICAgIHByb21pc2VzLnB1c2goaW5pdEpTRE9NKCkpO1xuICAgICAgICBpZighZ2xvYmFsVGhpc1snY3J5cHRvJ10pIHtcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2goaW1wb3J0KFwiQHBlY3VsaWFyL3dlYmNyeXB0b1wiKS50aGVuKG0gPT4ge1xuICAgICAgICAgICAgICAgIGdsb2JhbFRoaXNbJ2NyeXB0byddID0gbmV3IG0uQ3J5cHRvKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9KSlcbiAgICAgICAgfVxuXG5cbiAgICAgICAgUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgZG9uZSgpXG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG4gICAgXG4gICAgW1xuICAgICAgICBbJ3Rlc3QxJywgJ3Rlc3QxJ10sXG4gICAgICAgIFsnJHsnLCAnXFxcXCRcXFxceyddLFxuICAgICAgICBbJ2kxOG57JywgJ2kxOG5cXFxceyddLFxuICAgICAgICBbJy8vJywgJy8vJ10sXG4gICAgICAgIFsnXFxcXCcsICdcXFxcXFxcXCddLFxuICAgICAgIFxuICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgaXQoJ2VzY2FwZVN0cmluZygnICsgYSArICcpIHNob3VsZCByZXR1cm4gJyArIGIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChlc2NhcGVTdHJpbmcoYSkpLmlzLmVxdWFsKGIpXG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG5cbn0pO1xuXG4iLCAiaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcblxuZGVzY3JpYmUoJ1JhbmRvbUlEJywgZnVuY3Rpb24gKCkge1xuXG4gICAgY2xhc3MgUmFuZG9tSUQge31cbiAgICBcbiAgICBiZWZvcmUoZnVuY3Rpb24gKGRvbmUpIHtcblxuICAgICAgICBsZXQgcHJvbWlzZXMgPSBbXVxuICAgICAgICBpZighZ2xvYmFsVGhpc1snY3J5cHRvJ10pIHtcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2goaW1wb3J0KFwiQHBlY3VsaWFyL3dlYmNyeXB0b1wiKS50aGVuKG0gPT4ge1xuICAgICAgICAgICAgICAgIGdsb2JhbFRoaXNbJ2NyeXB0byddID0gbmV3IG0uQ3J5cHRvKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9KSlcbiAgICAgICAgfVxuXG4gICAgICAgIHByb21pc2VzLnB1c2goaW1wb3J0KFwiLi4vLi4vLi4vc291cmNlL3R5cGVzL3JhbmRvbWlkLm1qc1wiKS50aGVuKG0gPT4ge1xuICAgICAgICAgICAgUmFuZG9tSUQgPSBtLlJhbmRvbUlEO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pKVxuXG4gICAgICAgIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICB9KTtcblxuICAgIH0pOyAgICBcbiAgICBcbiAgICBkZXNjcmliZSgnLnRvU3RyaW5nKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCBpZCA9IG5ldyBSYW5kb21JRCgpXG4gICAgICAgIGxldCByZXN1bHQgPSBpZC50b1N0cmluZygpO1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGEgc3RyaW5nJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdCkuaXMuYSgnc3RyaW5nJylcbiAgICAgICAgfSk7XG5cbiAgICB9KTtcblxufSk7XG5cbiIsICJpbXBvcnQge0lEfSBmcm9tIFwiLi4vLi4vLi4vc291cmNlL3R5cGVzL2lkLm1qc1wiO1xuaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7aW5pdEpTRE9NfSBmcm9tIFwiLi4vLi4vdXRpbC9qc2RvbS5tanNcIjtcblxuZGVzY3JpYmUoJ0lEJywgZnVuY3Rpb24gKCkge1xuXG4gICAgYmVmb3JlKGZ1bmN0aW9uIChkb25lKSB7XG5cbiAgICAgICAgbGV0IHByb21pc2VzID0gW11cbiAgICAgICAgaWYoIWdsb2JhbFRoaXNbJ2NyeXB0byddKSB7XG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKGltcG9ydChcIkBwZWN1bGlhci93ZWJjcnlwdG9cIikudGhlbihtID0+IHtcbiAgICAgICAgICAgICAgICBnbG9iYWxUaGlzWydjcnlwdG8nXSA9IG5ldyBtLkNyeXB0bygpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfSkpXG4gICAgICAgIH1cblxuXG4gICAgICAgIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICB9KTtcblxuICAgIH0pOyAgICBcbiAgICBcbiAgICBkZXNjcmliZSgnLnRvU3RyaW5nKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCBpZCA9IG5ldyBJRCgpXG4gICAgICAgIGxldCByZXN1bHQgPSBpZC50b1N0cmluZygpO1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGEgc3RyaW5nJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdCkuaXMuYSgnc3RyaW5nJylcbiAgICAgICAgfSk7XG4gICAgICAgIFxuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBhIHN0cmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgSUQoJ3RleHQxNDI1aWQnKS50b1N0cmluZygpKS5pcy5lcXVhbCgndGV4dDE0MjVpZDEnKVxuICAgICAgICAgICAgZXhwZWN0KG5ldyBJRCgndGV4dDE0MjVpZCcpLnRvU3RyaW5nKCkpLmlzLmVxdWFsKCd0ZXh0MTQyNWlkMicpXG4gICAgICAgICAgICBleHBlY3QobmV3IElEKCd0ZXh0MTQyNWlkJykudG9TdHJpbmcoKSkuaXMuZXF1YWwoJ3RleHQxNDI1aWQzJylcbiAgICAgICAgfSk7XG5cbiAgICB9KTtcblxufSk7XG5cbiIsICJpbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuXG5kZXNjcmliZSgnVVVJRCcsIGZ1bmN0aW9uICgpIHtcblxuICAgIGNsYXNzIFVVSUQge31cbiAgICBcbiAgICBiZWZvcmUoZnVuY3Rpb24gKGRvbmUpIHtcblxuICAgICAgICBsZXQgcHJvbWlzZXMgPSBbXVxuICAgICAgICBcbiAgICAgICAgaWYoIWdsb2JhbFRoaXNbJ2NyeXB0byddKSB7XG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKGltcG9ydChcIkBwZWN1bGlhci93ZWJjcnlwdG9cIikudGhlbihtID0+IHtcbiAgICAgICAgICAgICAgICBnbG9iYWxUaGlzWydjcnlwdG8nXSA9IG5ldyBtLkNyeXB0bygpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfSkpXG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIFxuICAgICAgICBwcm9taXNlcy5wdXNoKGltcG9ydChcIi4uLy4uLy4uL3NvdXJjZS90eXBlcy91dWlkLm1qc1wiKS50aGVuKG0gPT4ge1xuICAgICAgICAgICAgVVVJRCA9IG0uVVVJRDtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9KSlcbiAgICAgICAgXG4gICAgICAgIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICB9KTtcblxuICAgIH0pOyAgICBcbiAgICBcbiAgICBkZXNjcmliZSgnLnRvU3RyaW5nKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGEgc3RyaW5nJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGV0IHV1aWQgPSBuZXcgVVVJRCgpXG4gICAgICAgICAgICBsZXQgcmVzdWx0ID0gdXVpZC50b1N0cmluZygpO1xuXG4gICAgICAgICAgICBleHBlY3QocmVzdWx0KS5pcy5hKCdzdHJpbmcnKVxuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdC5sZW5ndGgpLmlzLmVxdWFsKDM2KVxuICAgICAgICB9KTtcblxuICAgICAgICBpdCgndGVzdCBmb3JtYXQnLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgICAgICAgbGV0IHV1aWQgPSBuZXcgVVVJRCgpXG4gICAgICAgICAgICBsZXQgcmVzdWx0ID0gdXVpZC50b1N0cmluZygpO1xuXG4gICAgICAgICAgICBjb25zdCByZWdleEV4cCA9IC9eW0EtRlxcZF17OH0tW0EtRlxcZF17NH0tNFtBLUZcXGRdezN9LVs4OUFCXVtBLUZcXGRdezN9LVtBLUZcXGRdezEyfSQvaTtcblxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCAyMDAwOyBpKyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCB1ID0gbmV3IFVVSUQoKS50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHIgPSByZWdleEV4cC50ZXN0KHUpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHIgIT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICAgICAgZG9uZSgnbm8gdXVpZCAnICsgdSArICcgPT4gJyArIHIpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBkb25lKCk7XG5cbiAgICAgICAgfSk7XG5cbiAgICB9KTtcblxufSk7XG5cbiIsICJpbXBvcnQge1xuICAgIGlzUHJpbWl0aXZlLFxuICAgIGlzQm9vbGVhbixcbiAgICBpc1N0cmluZyxcbiAgICBpc09iamVjdCxcbiAgICBpc0FycmF5LFxuICAgIGlzSW5zdGFuY2UsXG4gICAgaXNGdW5jdGlvbixcbiAgICBpc0l0ZXJhYmxlLFxuICAgIGlzSW50ZWdlcixcbiAgICBpc1N5bWJvbFxufSBmcm9tIFwiLi4vLi4vLi4vc291cmNlL3R5cGVzL2lzLm1qc1wiO1xuXG5cbmltcG9ydCB7SUR9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvdHlwZXMvaWQubWpzXCJcblxuaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7aW5pdEpTRE9NfSBmcm9tIFwiLi4vLi4vdXRpbC9qc2RvbS5tanNcIjtcblxuZGVzY3JpYmUoJ0lzJywgZnVuY3Rpb24gKCkge1xuXG4gICAgYmVmb3JlKGZ1bmN0aW9uIChkb25lKSB7XG5cbiAgICAgICAgbGV0IHByb21pc2VzID0gW11cbiAgICAgICAgaWYoIWdsb2JhbFRoaXNbJ2NyeXB0byddKSB7XG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKGltcG9ydChcIkBwZWN1bGlhci93ZWJjcnlwdG9cIikudGhlbihtID0+IHtcbiAgICAgICAgICAgICAgICBnbG9iYWxUaGlzWydjcnlwdG8nXSA9IG5ldyBtLkNyeXB0bygpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfSkpXG4gICAgICAgIH1cblxuXG4gICAgICAgIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIGRvbmUoKVxuICAgICAgICB9KTtcblxuICAgIH0pOyAgICBcbiAgICBcbiAgICBkZXNjcmliZSgnLmlzUHJpbWl0aXZlKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWyd0ZXN0MScsIHRydWVdLFxuICAgICAgICAgICAgW3VuZGVmaW5lZCwgdHJ1ZV0sXG4gICAgICAgICAgICBbbnVsbCwgdHJ1ZV0sXG4gICAgICAgICAgICBbKCkgPT4ge1xuICAgICAgICAgICAgfSwgZmFsc2VdLFxuICAgICAgICAgICAgWzIsIHRydWVdLFxuICAgICAgICAgICAgW3BhcnNlSW50KFwiYVwiKSwgdHJ1ZV0sXG4gICAgICAgICAgICBbZmFsc2UsIHRydWVdLFxuICAgICAgICAgICAgW3RydWUsIHRydWVdLFxuICAgICAgICAgICAgWzQuNSwgdHJ1ZV0sXG4gICAgICAgICAgICBbe30sIGZhbHNlXSxcbiAgICAgICAgICAgIFtbMSwgMiwgM10sIGZhbHNlXSxcbiAgICAgICAgICAgIFtTeW1ib2woXCJmb29cIiksIHRydWVdLFxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGl0KCdpcy5pc1ByaW1pdGl2ZSgnICsgdHlwZW9mIGEgKyAnKSBzaG91bGQgcmV0dXJuICcgKyBiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGlzUHJpbWl0aXZlKGEpKS5pcy5lcXVhbChiKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcbiAgICBkZXNjcmliZSgnLmlzU3ltYm9sKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWyd0ZXN0MScsIGZhbHNlXSxcbiAgICAgICAgICAgIFt1bmRlZmluZWQsIGZhbHNlXSxcbiAgICAgICAgICAgIFtudWxsLCBmYWxzZV0sXG4gICAgICAgICAgICBbKCkgPT4ge1xuICAgICAgICAgICAgfSwgZmFsc2VdLFxuICAgICAgICAgICAgWzIsIGZhbHNlXSxcbiAgICAgICAgICAgIFtwYXJzZUludChcImFcIiksIGZhbHNlXSxcbiAgICAgICAgICAgIFtmYWxzZSwgZmFsc2VdLFxuICAgICAgICAgICAgW3RydWUsIGZhbHNlXSxcbiAgICAgICAgICAgIFs0LjUsIGZhbHNlXSxcbiAgICAgICAgICAgIFt7fSwgZmFsc2VdLFxuICAgICAgICAgICAgW1sxLCAyLCAzXSwgZmFsc2VdLFxuICAgICAgICAgICAgW1N5bWJvbChcImZvb1wiKSwgdHJ1ZV0sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ2lzLmlzU3ltYm9sKCcgKyB0eXBlb2YgYSArICcpIHNob3VsZCByZXR1cm4gJyArIGIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBleHBlY3QoaXNTeW1ib2woYSkpLmlzLmVxdWFsKGIpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJy5pc0ludGVnZXIoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBbXG4gICAgICAgICAgICBbJ3Rlc3QxJywgZmFsc2VdLFxuICAgICAgICAgICAgW3VuZGVmaW5lZCwgZmFsc2VdLFxuICAgICAgICAgICAgW251bGwsIGZhbHNlXSxcbiAgICAgICAgICAgIFsoKSA9PiB7XG4gICAgICAgICAgICB9LCBmYWxzZV0sXG4gICAgICAgICAgICBbMiwgdHJ1ZV0sXG4gICAgICAgICAgICBbcGFyc2VJbnQoXCJhXCIpLCBmYWxzZV0sXG4gICAgICAgICAgICBbZmFsc2UsIGZhbHNlXSxcbiAgICAgICAgICAgIFt0cnVlLCBmYWxzZV0sXG4gICAgICAgICAgICBbNC41LCBmYWxzZV0sXG4gICAgICAgICAgICBbe30sIGZhbHNlXSxcbiAgICAgICAgICAgIFtbMSwgMiwgM10sIGZhbHNlXSxcbiAgICAgICAgICAgIFtTeW1ib2woXCJmb29cIiksIGZhbHNlXSxcbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpdCgnaXMuaXNJbnRlZ2VyKCcgKyB0eXBlb2YgYSArICcpIHNob3VsZCByZXR1cm4gJyArIGIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBleHBlY3QoaXNJbnRlZ2VyKGEpKS5pcy5lcXVhbChiKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCcuaXNJdGVyYWJsZSgpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIFtcbiAgICAgICAgICAgIFsndGVzdDEnLCB0cnVlXSxcbiAgICAgICAgICAgIFt1bmRlZmluZWQsIGZhbHNlXSxcbiAgICAgICAgICAgIFtudWxsLCBmYWxzZV0sXG4gICAgICAgICAgICBbKCkgPT4ge1xuICAgICAgICAgICAgfSwgZmFsc2VdLFxuICAgICAgICAgICAgW3BhcnNlSW50KFwiYVwiKSwgZmFsc2VdLFxuICAgICAgICAgICAgWzIsIGZhbHNlXSxcbiAgICAgICAgICAgIFtmYWxzZSwgZmFsc2VdLFxuICAgICAgICAgICAgW3RydWUsIGZhbHNlXSxcbiAgICAgICAgICAgIFs0LjUsIGZhbHNlXSxcbiAgICAgICAgICAgIFt7fSwgZmFsc2VdLFxuICAgICAgICAgICAgW1sxLCAyLCAzXSwgdHJ1ZV0sXG4gICAgICAgICAgICBbU3ltYm9sKFwiZm9vXCIpLCBmYWxzZV0sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ2lzLmlzSXRlcmFibGUoJyArIHR5cGVvZiBhICsgJykgc2hvdWxkIHJldHVybiAnICsgYiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGV4cGVjdChpc0l0ZXJhYmxlKGEpKS5pcy5lcXVhbChiKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCcuaXNCb29sZWFuKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWyd0ZXN0MScsIGZhbHNlXSxcbiAgICAgICAgICAgIFt1bmRlZmluZWQsIGZhbHNlXSxcbiAgICAgICAgICAgIFtudWxsLCBmYWxzZV0sXG4gICAgICAgICAgICBbKCkgPT4ge1xuICAgICAgICAgICAgfSwgZmFsc2VdLFxuICAgICAgICAgICAgWzIsIGZhbHNlXSxcbiAgICAgICAgICAgIFtmYWxzZSwgdHJ1ZV0sXG4gICAgICAgICAgICBbcGFyc2VJbnQoXCJhXCIpLCBmYWxzZV0sXG4gICAgICAgICAgICBbdHJ1ZSwgdHJ1ZV0sXG4gICAgICAgICAgICBbNC41LCBmYWxzZV0sXG4gICAgICAgICAgICBbe30sIGZhbHNlXSxcbiAgICAgICAgICAgIFtbMSwgMiwgM10sIGZhbHNlXSxcbiAgICAgICAgICAgIFtTeW1ib2woXCJmb29cIiksIGZhbHNlXSxcbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpdCgnaXMuaXNCb29sZWFuKCcgKyB0eXBlb2YgYSArICcpIHNob3VsZCByZXR1cm4gJyArIGIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBleHBlY3QoaXNCb29sZWFuKGEpKS5pcy5lcXVhbChiKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCcuaXNTdHJpbmcoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBbXG4gICAgICAgICAgICBbJ3Rlc3QxJywgdHJ1ZV0sXG4gICAgICAgICAgICBbdW5kZWZpbmVkLCBmYWxzZV0sXG4gICAgICAgICAgICBbbnVsbCwgZmFsc2VdLFxuICAgICAgICAgICAgWygpID0+IHtcbiAgICAgICAgICAgIH0sIGZhbHNlXSxcbiAgICAgICAgICAgIFsyLCBmYWxzZV0sXG4gICAgICAgICAgICBbZmFsc2UsIGZhbHNlXSxcbiAgICAgICAgICAgIFtwYXJzZUludChcImFcIiksIGZhbHNlXSxcbiAgICAgICAgICAgIFt0cnVlLCBmYWxzZV0sXG4gICAgICAgICAgICBbNC41LCBmYWxzZV0sXG4gICAgICAgICAgICBbe30sIGZhbHNlXSxcbiAgICAgICAgICAgIFtbMSwgMiwgM10sIGZhbHNlXSxcbiAgICAgICAgICAgIFtTeW1ib2woXCJmb29cIiksIGZhbHNlXSxcbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpdCgnaXMuaXNTdHJpbmcoJyArIHR5cGVvZiBhICsgJykgc2hvdWxkIHJldHVybiAnICsgYiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGV4cGVjdChpc1N0cmluZyhhKSkuaXMuZXF1YWwoYilcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnLmlzSW5zdGFuY2UoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBbXG4gICAgICAgICAgICBbbmV3IElEKCksIElELCAgdHJ1ZV0sXG4gICAgICAgICAgICBbbmV3IElEKCksICgpPT57fSwgIGZhbHNlXSxcbiAgICAgICAgICAgIFsndGVzdDEnLCB1bmRlZmluZWQsIGZhbHNlXSxcbiAgICAgICAgICAgIFt1bmRlZmluZWQsIHVuZGVmaW5lZCwgZmFsc2VdLFxuICAgICAgICAgICAgW251bGwsIHVuZGVmaW5lZCwgZmFsc2VdLFxuICAgICAgICAgICAgWygpID0+IHtcbiAgICAgICAgICAgIH0sIHVuZGVmaW5lZCwgZmFsc2VdLFxuICAgICAgICAgICAgWzIsIHVuZGVmaW5lZCwgZmFsc2VdLFxuICAgICAgICAgICAgW2ZhbHNlLCB1bmRlZmluZWQsIGZhbHNlXSxcbiAgICAgICAgICAgIFtwYXJzZUludChcImFcIiksIHVuZGVmaW5lZCwgZmFsc2VdLFxuICAgICAgICAgICAgW3RydWUsIHVuZGVmaW5lZCwgZmFsc2VdLFxuICAgICAgICAgICAgWzQuNSwgdW5kZWZpbmVkLCBmYWxzZV0sXG4gICAgICAgICAgICBbe30sIHVuZGVmaW5lZCwgZmFsc2VdLFxuICAgICAgICAgICAgW1sxLCAyLCAzXSwgdW5kZWZpbmVkLCBmYWxzZV0sXG4gICAgICAgICAgICBbU3ltYm9sKFwiZm9vXCIpLCB1bmRlZmluZWQsIGZhbHNlXSxcbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGMgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ2lzLmlzSW5zdGFuY2UoJyArIEpTT04uc3RyaW5naWZ5KGEpICsgJykgc2hvdWxkIHJldHVybiAnICsgdHlwZW9mIGIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBleHBlY3QoaXNJbnN0YW5jZShhLCBiKSkuaXMuZXF1YWwoYylcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgICBcbiAgICBcbiAgICBkZXNjcmliZSgnLmlzT2JqZWN0KCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWyd0ZXN0MScsIGZhbHNlXSxcbiAgICAgICAgICAgIFt1bmRlZmluZWQsIGZhbHNlXSxcbiAgICAgICAgICAgIFtudWxsLCBmYWxzZV0sXG4gICAgICAgICAgICBbKCkgPT4ge1xuICAgICAgICAgICAgfSwgZmFsc2VdLFxuICAgICAgICAgICAgWzIsIGZhbHNlXSxcbiAgICAgICAgICAgIFtmYWxzZSwgZmFsc2VdLFxuICAgICAgICAgICAgW3BhcnNlSW50KFwiYVwiKSwgZmFsc2VdLFxuICAgICAgICAgICAgW3RydWUsIGZhbHNlXSxcbiAgICAgICAgICAgIFs0LjUsIGZhbHNlXSxcbiAgICAgICAgICAgIFt7fSwgdHJ1ZV0sXG4gICAgICAgICAgICBbWzEsIDIsIDNdLCBmYWxzZV0sXG4gICAgICAgICAgICBbU3ltYm9sKFwiZm9vXCIpLCBmYWxzZV0sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaXQoJ2lzLmlzT2JqZWN0KCcgKyBKU09OLnN0cmluZ2lmeShhKSArICcpIHNob3VsZCByZXR1cm4gJyArIGIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBleHBlY3QoaXNPYmplY3QoYSkpLmlzLmVxdWFsKGIpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cblxuICAgIH0pO1xuXG5cbiAgICBkZXNjcmliZSgnLmlzQXJyYXkoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBbXG4gICAgICAgICAgICBbJ3Rlc3QxJywgZmFsc2VdLFxuICAgICAgICAgICAgW3VuZGVmaW5lZCwgZmFsc2VdLFxuICAgICAgICAgICAgW251bGwsIGZhbHNlXSxcbiAgICAgICAgICAgIFsoKSA9PiB7XG4gICAgICAgICAgICB9LCBmYWxzZV0sXG4gICAgICAgICAgICBbMiwgZmFsc2VdLFxuICAgICAgICAgICAgW2ZhbHNlLCBmYWxzZV0sXG4gICAgICAgICAgICBbcGFyc2VJbnQoXCJhXCIpLCBmYWxzZV0sXG4gICAgICAgICAgICBbdHJ1ZSwgZmFsc2VdLFxuICAgICAgICAgICAgWzQuNSwgZmFsc2VdLFxuICAgICAgICAgICAgW3t9LCBmYWxzZV0sXG4gICAgICAgICAgICBbWzEsIDIsIDNdLCB0cnVlXSxcbiAgICAgICAgICAgIFtTeW1ib2woXCJmb29cIiksIGZhbHNlXSxcbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpdCgnaXMuaXNBcnJheSgnICsgdHlwZW9mIGEgKyAnKSBzaG91bGQgcmV0dXJuICcgKyBiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGlzQXJyYXkoYSkpLmlzLmVxdWFsKGIpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnLmlzRnVuY3Rpb24oKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBbXG4gICAgICAgICAgICBbJ3Rlc3QxJywgZmFsc2VdLFxuICAgICAgICAgICAgW3VuZGVmaW5lZCwgZmFsc2VdLFxuICAgICAgICAgICAgW251bGwsIGZhbHNlXSxcbiAgICAgICAgICAgIFsoKSA9PiB7XG4gICAgICAgICAgICB9LCB0cnVlXSxcbiAgICAgICAgICAgIFsyLCBmYWxzZV0sXG4gICAgICAgICAgICBbZmFsc2UsIGZhbHNlXSxcbiAgICAgICAgICAgIFtwYXJzZUludChcImFcIiksIGZhbHNlXSxcbiAgICAgICAgICAgIFt0cnVlLCBmYWxzZV0sXG4gICAgICAgICAgICBbNC41LCBmYWxzZV0sXG4gICAgICAgICAgICBbe30sIGZhbHNlXSxcbiAgICAgICAgICAgIFtbMSwgMiwgM10sIGZhbHNlXSxcbiAgICAgICAgICAgIFtTeW1ib2woXCJmb29cIiksIGZhbHNlXSxcbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpdCgnaXMuaXNGdW5jdGlvbignICsgdHlwZW9mIGEgKyAnKSBzaG91bGQgcmV0dXJuICcgKyBiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGlzRnVuY3Rpb24oYSkpLmlzLmVxdWFsKGIpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbn0pO1xuXG4iLCAiaW1wb3J0IHtcbiAgICB2YWxpZGF0ZVByaW1pdGl2ZSxcbiAgICB2YWxpZGF0ZUJvb2xlYW4sXG4gICAgdmFsaWRhdGVTdHJpbmcsXG4gICAgdmFsaWRhdGVPYmplY3QsXG4gICAgdmFsaWRhdGVBcnJheSxcbiAgICB2YWxpZGF0ZUZ1bmN0aW9uLFxuICAgIHZhbGlkYXRlSW50ZWdlcixcbiAgICB2YWxpZGF0ZUluc3RhbmNlLFxuICAgIHZhbGlkYXRlSXRlcmFibGUsXG4gICAgdmFsaWRhdGVTeW1ib2xcbn0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS90eXBlcy92YWxpZGF0ZS5tanNcIlxuXG5pbXBvcnQge0Jhc2V9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvdHlwZXMvYmFzZS5tanNcIlxuaW1wb3J0IHtJRH0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS90eXBlcy9pZC5tanNcIlxuXG5pbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuXG5kZXNjcmliZSgndmFsaWRhdGUnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBkZXNjcmliZSgnLnZhbGlkYXRlUHJpbWl0aXZlKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWyd0ZXN0MScsIHRydWVdLFxuICAgICAgICAgICAgW3VuZGVmaW5lZCwgdHJ1ZV0sXG4gICAgICAgICAgICBbbnVsbCwgdHJ1ZV0sXG4gICAgICAgICAgICBbKCkgPT4ge1xuICAgICAgICAgICAgfSwgZmFsc2VdLFxuICAgICAgICAgICAgWzIsIHRydWVdLFxuICAgICAgICAgICAgW2ZhbHNlLCB0cnVlXSxcbiAgICAgICAgICAgIFt0cnVlLCB0cnVlXSxcbiAgICAgICAgICAgIFs0LjUsIHRydWVdLFxuICAgICAgICAgICAgW3t9LCBmYWxzZV0sXG4gICAgICAgICAgICBbWzEsIDIsIDNdLCBmYWxzZV0sXG4gICAgICAgICAgICBbU3ltYm9sKFwiZm9vXCIpLCB0cnVlXSxcbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpZiAoYiA9PT0gZmFsc2UpIHtcblxuICAgICAgICAgICAgICAgIGl0KCcudmFsaWRhdGVQcmltaXRpdmUoJyArIHR5cGVvZiBhICsgJykgc2hvdWxkIHRocm93IFR5cGVFeGNlcHRpb24gJyArIGIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KCgpID0+IHZhbGlkYXRlUHJpbWl0aXZlKGEpKS50by50aHJvdyhUeXBlRXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGl0KCcudmFsaWRhdGVQcmltaXRpdmUoJyArIHR5cGVvZiBhICsgJykgc2hvdWxkIG5vdCB0aHJvdyBUeXBlRXhjZXB0aW9uICcgKyBiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdCh2YWxpZGF0ZVByaW1pdGl2ZShhKSkudG8uYmUuZXF1YWwoYSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgfSk7XG5cblxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJy52YWxpZGF0ZUludGVnZXIoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBbXG4gICAgICAgICAgICBbJ3Rlc3QxJywgZmFsc2VdLFxuICAgICAgICAgICAgW3VuZGVmaW5lZCwgZmFsc2VdLFxuICAgICAgICAgICAgW251bGwsIGZhbHNlXSxcbiAgICAgICAgICAgIFsoKSA9PiB7XG4gICAgICAgICAgICB9LCBmYWxzZV0sXG4gICAgICAgICAgICBbMiwgdHJ1ZV0sXG4gICAgICAgICAgICBbZmFsc2UsIGZhbHNlXSxcbiAgICAgICAgICAgIFt0cnVlLCBmYWxzZV0sXG4gICAgICAgICAgICBbNC41LCBmYWxzZV0sXG4gICAgICAgICAgICBbe30sIGZhbHNlXSxcbiAgICAgICAgICAgIFtbMSwgMiwgM10sIGZhbHNlXSxcbiAgICAgICAgICAgIFtTeW1ib2woXCJmb29cIiksIGZhbHNlXSxcbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpZiAoYiA9PT0gZmFsc2UpIHtcblxuICAgICAgICAgICAgICAgIGl0KCcudmFsaWRhdGVJbnRlZ2VyKCcgKyB0eXBlb2YgYSArICcpIHNob3VsZCB0aHJvdyBUeXBlRXhjZXB0aW9uICcgKyBiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdCgoKSA9PiB2YWxpZGF0ZUludGVnZXIoYSkpLnRvLnRocm93KFR5cGVFcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaXQoJy52YWxpZGF0ZUludGVnZXIoJyArIHR5cGVvZiBhICsgJykgc2hvdWxkIG5vdCB0aHJvdyBUeXBlRXhjZXB0aW9uICcgKyBiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdCh2YWxpZGF0ZUludGVnZXIoYSkpLnRvLmJlLmVxdWFsKGEpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcbiAgICBcbiAgICBkZXNjcmliZSgnLnZhbGlkYXRlU3ltYm9sKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWyd0ZXN0MScsIGZhbHNlXSxcbiAgICAgICAgICAgIFt1bmRlZmluZWQsIGZhbHNlXSxcbiAgICAgICAgICAgIFtudWxsLCBmYWxzZV0sXG4gICAgICAgICAgICBbKCkgPT4ge1xuICAgICAgICAgICAgfSwgZmFsc2VdLFxuICAgICAgICAgICAgWzIsIGZhbHNlXSxcbiAgICAgICAgICAgIFtmYWxzZSwgZmFsc2VdLFxuICAgICAgICAgICAgW3RydWUsIGZhbHNlXSxcbiAgICAgICAgICAgIFs0LjUsIGZhbHNlXSxcbiAgICAgICAgICAgIFt7fSwgZmFsc2VdLFxuICAgICAgICAgICAgW1sxLCAyLCAzXSwgZmFsc2VdLFxuICAgICAgICAgICAgW1N5bWJvbChcImZvb1wiKSwgdHJ1ZV0sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaWYgKGIgPT09IGZhbHNlKSB7XG5cbiAgICAgICAgICAgICAgICBpdCgnLnZhbGlkYXRlU3ltYm9sKCcgKyB0eXBlb2YgYSArICcpIHNob3VsZCB0aHJvdyBUeXBlRXhjZXB0aW9uICcgKyBiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdCgoKSA9PiB2YWxpZGF0ZVN5bWJvbChhKSkudG8udGhyb3coVHlwZUVycm9yKTtcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpdCgnLnZhbGlkYXRlU3ltYm9sKCcgKyB0eXBlb2YgYSArICcpIHNob3VsZCBub3QgdGhyb3cgVHlwZUV4Y2VwdGlvbiAnICsgYiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QodmFsaWRhdGVTeW1ib2woYSkpLnRvLmJlLmVxdWFsKGEpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCcudmFsaWRhdGVJdGVyYWJsZSgpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIFtcbiAgICAgICAgICAgIFsndGVzdDEnLCB0cnVlXSxcbiAgICAgICAgICAgIFt1bmRlZmluZWQsIGZhbHNlXSxcbiAgICAgICAgICAgIFtudWxsLCBmYWxzZV0sXG4gICAgICAgICAgICBbKCkgPT4ge1xuICAgICAgICAgICAgfSwgZmFsc2VdLFxuICAgICAgICAgICAgWzIsIGZhbHNlXSxcbiAgICAgICAgICAgIFtmYWxzZSwgZmFsc2VdLFxuICAgICAgICAgICAgW3RydWUsIGZhbHNlXSxcbiAgICAgICAgICAgIFs0LjUsIGZhbHNlXSxcbiAgICAgICAgICAgIFt7fSwgZmFsc2VdLFxuICAgICAgICAgICAgW1sxLCAyLCAzXSwgdHJ1ZV0sXG4gICAgICAgICAgICBbU3ltYm9sKFwiZm9vXCIpLCBmYWxzZV0sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaWYgKGIgPT09IGZhbHNlKSB7XG5cbiAgICAgICAgICAgICAgICBpdCgnLnZhbGlkYXRlSXRlcmFibGUoJyArIHR5cGVvZiBhICsgJykgc2hvdWxkIHRocm93IFR5cGVFeGNlcHRpb24gJyArIGIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRlSXRlcmFibGUoYSlcbiAgICAgICAgICAgICAgICAgICAgfSkudG8udGhyb3coVHlwZUVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgO1xuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGl0KCcudmFsaWRhdGVJdGVyYWJsZSgnICsgdHlwZW9mIGEgKyAnKSBzaG91bGQgbm90IHRocm93IFR5cGVFeGNlcHRpb24gJyArIGIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KHZhbGlkYXRlSXRlcmFibGUoYSkpLnRvLmJlLmVxdWFsKGEpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH0pO1xuXG5cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCcudmFsaWRhdGVCb29sZWFuKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWyd0ZXN0MScsIGZhbHNlXSxcbiAgICAgICAgICAgIFt1bmRlZmluZWQsIGZhbHNlXSxcbiAgICAgICAgICAgIFtudWxsLCBmYWxzZV0sXG4gICAgICAgICAgICBbKCkgPT4ge1xuICAgICAgICAgICAgfSwgZmFsc2VdLFxuICAgICAgICAgICAgWzIsIGZhbHNlXSxcbiAgICAgICAgICAgIFtmYWxzZSwgdHJ1ZV0sXG4gICAgICAgICAgICBbdHJ1ZSwgdHJ1ZV0sXG4gICAgICAgICAgICBbNC41LCBmYWxzZV0sXG4gICAgICAgICAgICBbe30sIGZhbHNlXSxcbiAgICAgICAgICAgIFtbMSwgMiwgM10sIGZhbHNlXSxcbiAgICAgICAgICAgIFtTeW1ib2woXCJmb29cIiksIGZhbHNlXSxcbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuXG4gICAgICAgICAgICBpZiAoYiA9PT0gZmFsc2UpIHtcblxuICAgICAgICAgICAgICAgIGl0KCcudmFsaWRhdGVCb29sZWFuKCcgKyB0eXBlb2YgYSArICcpIHNob3VsZCB0aHJvdyBUeXBlRXhjZXB0aW9uICcgKyBiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZUJvb2xlYW4oYSlcbiAgICAgICAgICAgICAgICAgICAgfSkudG8udGhyb3coVHlwZUVycm9yKTtcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpdCgnLnZhbGlkYXRlQm9vbGVhbignICsgdHlwZW9mIGEgKyAnKSBzaG91bGQgbm90IHRocm93IFR5cGVFeGNlcHRpb24gJyArIGIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KHZhbGlkYXRlQm9vbGVhbihhKSkudG8uYmUuZXF1YWwoYSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cblxuICAgICAgICB9KTtcblxuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnLnZhbGlkYXRlU3RyaW5nKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWyd0ZXN0MScsIHRydWVdLFxuICAgICAgICAgICAgW3VuZGVmaW5lZCwgZmFsc2VdLFxuICAgICAgICAgICAgW251bGwsIGZhbHNlXSxcbiAgICAgICAgICAgIFsoKSA9PiB7XG4gICAgICAgICAgICB9LCBmYWxzZV0sXG4gICAgICAgICAgICBbMiwgZmFsc2VdLFxuICAgICAgICAgICAgW2ZhbHNlLCBmYWxzZV0sXG4gICAgICAgICAgICBbdHJ1ZSwgZmFsc2VdLFxuICAgICAgICAgICAgWzQuNSwgZmFsc2VdLFxuICAgICAgICAgICAgW3t9LCBmYWxzZV0sXG4gICAgICAgICAgICBbWzEsIDIsIDNdLCBmYWxzZV0sXG4gICAgICAgICAgICBbU3ltYm9sKFwiZm9vXCIpLCBmYWxzZV0sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaWYgKGIgPT09IGZhbHNlKSB7XG5cbiAgICAgICAgICAgICAgICBpdCgnLnZhbGlkYXRlU3RyaW5nKCcgKyB0eXBlb2YgYSArICcpIHNob3VsZCB0aHJvdyBUeXBlRXhjZXB0aW9uICcgKyBiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZVN0cmluZyhhKVxuICAgICAgICAgICAgICAgICAgICB9KS50by50aHJvdyhUeXBlRXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICA7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaXQoJy52YWxpZGF0ZVN0cmluZygnICsgdHlwZW9mIGEgKyAnKSBzaG91bGQgbm90IHRocm93IFR5cGVFeGNlcHRpb24gJyArIGIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KHZhbGlkYXRlU3RyaW5nKGEpKS50by5iZS5lcXVhbChhKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICB9KTtcblxuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnLnZhbGlkYXRlT2JqZWN0KCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWyd0ZXN0MScsIGZhbHNlXSxcbiAgICAgICAgICAgIFt1bmRlZmluZWQsIGZhbHNlXSxcbiAgICAgICAgICAgIFtudWxsLCBmYWxzZV0sXG4gICAgICAgICAgICBbKCkgPT4ge1xuICAgICAgICAgICAgfSwgZmFsc2VdLFxuICAgICAgICAgICAgWzIsIGZhbHNlXSxcbiAgICAgICAgICAgIFtmYWxzZSwgZmFsc2VdLFxuICAgICAgICAgICAgW3RydWUsIGZhbHNlXSxcbiAgICAgICAgICAgIFs0LjUsIGZhbHNlXSxcbiAgICAgICAgICAgIFt7fSwgdHJ1ZV0sXG4gICAgICAgICAgICBbWzEsIDIsIDNdLCBmYWxzZV0sXG4gICAgICAgICAgICBbU3ltYm9sKFwiZm9vXCIpLCBmYWxzZV0sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaWYgKGIgPT09IGZhbHNlKSB7XG5cbiAgICAgICAgICAgICAgICBpdCgnLnZhbGlkYXRlT2JqZWN0KCcgKyB0eXBlb2YgYSArICcpIHNob3VsZCB0aHJvdyBUeXBlRXhjZXB0aW9uICcgKyBiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZU9iamVjdChhKVxuICAgICAgICAgICAgICAgICAgICB9KS50by50aHJvdyhUeXBlRXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICA7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaXQoJy52YWxpZGF0ZU9iamVjdCgnICsgdHlwZW9mIGEgKyAnKSBzaG91bGQgbm90IHRocm93IFR5cGVFeGNlcHRpb24gJyArIGIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KHZhbGlkYXRlT2JqZWN0KGEpKS50by5iZS5lcXVhbChhKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICB9KTtcblxuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnLnZhbGlkYXRlSW5zdGFuY2UoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBbXG4gICAgICAgICAgICBbJ3Rlc3QxJywgT2JqZWN0XSxcbiAgICAgICAgICAgIFt1bmRlZmluZWQsIE9iamVjdF0sXG4gICAgICAgICAgICBbbnVsbCwgT2JqZWN0XSxcbiAgICAgICAgICAgIFsoKSA9PiB7XG4gICAgICAgICAgICB9LCBPYmplY3RdLFxuICAgICAgICAgICAgWzIsIE9iamVjdF0sXG4gICAgICAgICAgICBbZmFsc2UsIE9iamVjdF0sXG4gICAgICAgICAgICBbdHJ1ZSwgT2JqZWN0XSxcbiAgICAgICAgICAgIFs0LjUsIE9iamVjdF0sXG4gICAgICAgICAgICBbe30sIEJhc2VdLFxuICAgICAgICAgICAgW1sxLCAyLCAzXSwgT2JqZWN0XSxcbiAgICAgICAgICAgIFtTeW1ib2woXCJmb29cIiksIE9iamVjdF0sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcblxuXG4gICAgICAgICAgICBpdCgnLnZhbGlkYXRlSW5zdGFuY2UoJyArIHR5cGVvZiBhICsgJykgc2hvdWxkIHRocm93IFR5cGVFeGNlcHRpb24gJyAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBleHBlY3QoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZUluc3RhbmNlKGEsIGIpXG4gICAgICAgICAgICAgICAgfSkudG8udGhyb3coVHlwZUVycm9yKTtcbiAgICAgICAgICAgICAgICA7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICB9KTtcblxuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnLnZhbGlkYXRlSW5zdGFuY2UoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBbXG4gICAgICAgICAgICBbe30sIE9iamVjdCwgdHJ1ZV0sXG4gICAgICAgICAgICBbbmV3IEJhc2UsIEJhc2UsIHRydWVdLFxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGl0KCcudmFsaWRhdGVJbnN0YW5jZSgnICsgdHlwZW9mIGEgKyAnKSBzaG91bGQgbm90IHRocm93IFR5cGVFeGNlcHRpb24gJyAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBleHBlY3QodmFsaWRhdGVJbnN0YW5jZShhLCBiKSkudG8uYmUuZXF1YWwoYSk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICB9KTtcblxuXG4gICAgfSk7XG5cblxuICAgIGRlc2NyaWJlKCcudmFsaWRhdGVBcnJheSgpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIFtcbiAgICAgICAgICAgIFsndGVzdDEnLCBmYWxzZV0sXG4gICAgICAgICAgICBbdW5kZWZpbmVkLCBmYWxzZV0sXG4gICAgICAgICAgICBbbnVsbCwgZmFsc2VdLFxuICAgICAgICAgICAgWygpID0+IHtcbiAgICAgICAgICAgIH0sIGZhbHNlXSxcbiAgICAgICAgICAgIFsyLCBmYWxzZV0sXG4gICAgICAgICAgICBbZmFsc2UsIGZhbHNlXSxcbiAgICAgICAgICAgIFt0cnVlLCBmYWxzZV0sXG4gICAgICAgICAgICBbNC41LCBmYWxzZV0sXG4gICAgICAgICAgICBbe30sIGZhbHNlXSxcbiAgICAgICAgICAgIFtbMSwgMiwgM10sIHRydWVdLFxuICAgICAgICAgICAgW1N5bWJvbChcImZvb1wiKSwgZmFsc2VdLFxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGlmIChiID09PSBmYWxzZSkge1xuXG4gICAgICAgICAgICAgICAgaXQoJy52YWxpZGF0ZUFycmF5KCcgKyB0eXBlb2YgYSArICcpIHNob3VsZCB0aHJvdyBUeXBlRXhjZXB0aW9uICcgKyBiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZUFycmF5KGEpXG4gICAgICAgICAgICAgICAgICAgIH0pLnRvLnRocm93KFR5cGVFcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIDtcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpdCgnLnZhbGlkYXRlQXJyYXkoJyArIHR5cGVvZiBhICsgJykgc2hvdWxkIG5vdCB0aHJvdyBUeXBlRXhjZXB0aW9uICcgKyBiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdCh2YWxpZGF0ZUFycmF5KGEpKS50by5iZS5lcXVhbChhKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cblxuXG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJy52YWxpZGF0ZUZ1bmN0aW9uKCknLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgW1xuICAgICAgICAgICAgWyd0ZXN0MScsIGZhbHNlXSxcbiAgICAgICAgICAgIFt1bmRlZmluZWQsIGZhbHNlXSxcbiAgICAgICAgICAgIFtudWxsLCBmYWxzZV0sXG4gICAgICAgICAgICBbKCkgPT4ge1xuICAgICAgICAgICAgfSwgdHJ1ZV0sXG4gICAgICAgICAgICBbMiwgZmFsc2VdLFxuICAgICAgICAgICAgW2ZhbHNlLCBmYWxzZV0sXG4gICAgICAgICAgICBbdHJ1ZSwgZmFsc2VdLFxuICAgICAgICAgICAgWzQuNSwgZmFsc2VdLFxuICAgICAgICAgICAgW3t9LCBmYWxzZV0sXG4gICAgICAgICAgICBbWzEsIDIsIDNdLCBmYWxzZV0sXG4gICAgICAgICAgICBbU3ltYm9sKFwiZm9vXCIpLCBmYWxzZV0sXG4gICAgICAgIF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICAgICBsZXQgYSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGIgPSBkYXRhLnNoaWZ0KClcblxuICAgICAgICAgICAgaWYgKGIgPT09IGZhbHNlKSB7XG5cbiAgICAgICAgICAgICAgICBpdCgnLnZhbGlkYXRlRnVuY3Rpb24oJyArIHR5cGVvZiBhICsgJykgc2hvdWxkIHRocm93IFR5cGVFeGNlcHRpb24gJyArIGIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRlRnVuY3Rpb24oYSlcbiAgICAgICAgICAgICAgICAgICAgfSkudG8udGhyb3coVHlwZUVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgO1xuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGl0KCcudmFsaWRhdGVGdW5jdGlvbignICsgdHlwZW9mIGEgKyAnKSBzaG91bGQgbm90IHRocm93IFR5cGVFeGNlcHRpb24gJyArIGIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KHZhbGlkYXRlRnVuY3Rpb24oYSkpLnRvLmJlLmVxdWFsKGEpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG5cbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbn0pO1xuXG4iLCAiaW1wb3J0IHtTdGFja30gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS90eXBlcy9zdGFjay5tanNcIjtcbmltcG9ydCB7XG4gICAgdHlwZU9mXG59IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvdHlwZXMvdHlwZW9mLm1qc1wiXG5cbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5cbmRlc2NyaWJlKCd0eXBlT2YnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBkZXNjcmliZSgnLnR5cGVPZigpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIFtcbiAgICAgICAgICAgIFt0cnVlLCAnYm9vbGVhbiddLFxuICAgICAgICAgICAgW251bGwsICdudWxsJ10sXG4gICAgICAgICAgICBbdW5kZWZpbmVkLCAndW5kZWZpbmVkJ10sXG4gICAgICAgICAgICBbUHJvbWlzZS5yZXNvbHZlKCksICdwcm9taXNlJ10sXG4gICAgICAgICAgICBbbmV3IFdlYWtNYXAoKSwgJ3dlYWttYXAnXSxcbiAgICAgICAgICAgIFtuZXcgTWFwKCksICdtYXAnXSxcbiAgICAgICAgICAgIFtOYU4sICdudW1iZXInXSxcbiAgICAgICAgICAgIFtmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgfSwgJ2dlbmVyYXRvcmZ1bmN0aW9uJ10sXG4gICAgICAgICAgICBbNSwgJ251bWJlciddLFxuICAgICAgICAgICAgW2Z1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIH0sICdmdW5jdGlvbiddLFxuICAgICAgICAgICAgWy9hLywgJ3JlZ2V4cCddLFxuICAgICAgICAgICAgW25ldyBEYXRlKCksICdkYXRlJ10sXG4gICAgICAgICAgICBbe30sICdvYmplY3QnXSxcbiAgICAgICAgICAgIFtbXSwgJ2FycmF5J10sXG4gICAgICAgICAgICBbJycsICdzdHJpbmcnXSxcbiAgICAgICAgICAgIFtuZXcgRXJyb3IsICdlcnJvciddLFxuICAgICAgICAgICAgW25ldyBTdGFjaywgJ3N0YWNrJ11cblxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGl0KCdzaG91bGQgcmV0dXJuICcgKyBiICsgJyB3aGVuIHRoZSB2YWx1ZSAnICsgdHlwZU9mKGEpLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KHR5cGVPZihhKSkudG8uYmUuZXF1YWwoYik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICB9KTtcblxuXG59KTtcblxuIiwgImltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge1VuaXF1ZVF1ZXVlfSBmcm9tIFwiLi4vLi4vLi4vc291cmNlL3R5cGVzL3VuaXF1ZXF1ZXVlLm1qc1wiO1xuXG5cbmRlc2NyaWJlKCdVbmlxdWVRdWV1ZScsIGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgcXVldWU7XG4gICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICAgIHF1ZXVlID0gbmV3IFVuaXF1ZVF1ZXVlO1xuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnaXNFbXB0eSgpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdmaXJzdCBpdCBzaG91bGQgZW1wdHknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QocXVldWUuaXNFbXB0eSgpKS50by5iZS50cnVlO1xuICAgICAgICB9KTtcblxuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnYWRkIHNlcXVlbmNlIHBlZWsgYW5kIHBvbGwnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ3Jlc3VsdCBhLGEsYSxiJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KHF1ZXVlLmFkZCh7YTogMX0pKS50by5iZS5pbnN0YW5jZU9mKFVuaXF1ZVF1ZXVlKTtcbiAgICAgICAgICAgIGV4cGVjdChxdWV1ZS5pc0VtcHR5KCkpLnRvLmJlLmZhbHNlO1xuICAgICAgICAgICAgZXhwZWN0KHF1ZXVlLmFkZCh7YTogMn0pKS50by5iZS5pbnN0YW5jZU9mKFVuaXF1ZVF1ZXVlKTtcbiAgICAgICAgICAgIGV4cGVjdChxdWV1ZS5hZGQoe2E6IDN9KSkudG8uYmUuaW5zdGFuY2VPZihVbmlxdWVRdWV1ZSk7XG4gICAgICAgICAgICBleHBlY3QocXVldWUucGVlaygpKS50by5kZWVwLmVxdWFsKHthOjF9KTtcbiAgICAgICAgICAgIGV4cGVjdChxdWV1ZS5wZWVrKCkpLnRvLmRlZXAuZXF1YWwoe2E6MX0pO1xuICAgICAgICAgICAgZXhwZWN0KHF1ZXVlLnBvbGwoKSkudG8uZGVlcC5lcXVhbCh7YToxfSk7XG4gICAgICAgICAgICBleHBlY3QocXVldWUucG9sbCgpKS50by5kZWVwLmVxdWFsKHthOjJ9KTtcbiAgICAgICAgICAgIGV4cGVjdChxdWV1ZS5pc0VtcHR5KCkpLnRvLmJlLmZhbHNlO1xuICAgICAgICAgICAgZXhwZWN0KHF1ZXVlLnBlZWsoKSkudG8uZGVlcC5lcXVhbCh7YTozfSk7XG4gICAgICAgICAgICBleHBlY3QocXVldWUucG9sbCgpKS50by5kZWVwLmVxdWFsKHthOjN9KTtcbiAgICAgICAgICAgIGV4cGVjdChxdWV1ZS5pc0VtcHR5KCkpLnRvLmJlLnRydWU7XG4gICAgICAgIH0pO1xuXG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCdhZGQgYW5kIGNsZWFyJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdzaG91bGQgZW1wdHknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QocXVldWUuaXNFbXB0eSgpKS50by5iZS50cnVlO1xuICAgICAgICAgICAgZXhwZWN0KHF1ZXVlLmFkZCh7YTogMX0pKS50by5iZS5pbnN0YW5jZU9mKFVuaXF1ZVF1ZXVlKTtcbiAgICAgICAgICAgIGV4cGVjdChxdWV1ZS5pc0VtcHR5KCkpLnRvLmJlLmZhbHNlO1xuICAgICAgICAgICAgZXhwZWN0KHF1ZXVlLmNsZWFyKCkpLnRvLmJlLmluc3RhbmNlT2YoVW5pcXVlUXVldWUpO1xuICAgICAgICAgICAgZXhwZWN0KHF1ZXVlLmlzRW1wdHkoKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgfSk7XG5cbiAgICB9KVxuICAgIFxuICAgIGRlc2NyaWJlKCdhZGQgbm8gb2JqZWN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KCgpPT57cXVldWUuYWRkKFtdKX0pLnRvLnRocm93KFR5cGVFcnJvcilcbiAgICAgICAgICAgIGV4cGVjdCgoKT0+e3F1ZXVlLmFkZCgxKX0pLnRvLnRocm93KFR5cGVFcnJvcilcbiAgICAgICAgICAgIGV4cGVjdCgoKT0+e3F1ZXVlLmFkZCh0cnVlKX0pLnRvLnRocm93KFR5cGVFcnJvcilcbiAgICAgICAgICAgIGV4cGVjdCgoKT0+e3F1ZXVlLmFkZCgpfSkudG8udGhyb3coVHlwZUVycm9yKVxuICAgICAgICAgICAgZXhwZWN0KCgpPT57cXVldWUuYWRkKFN5bWJvbChcIjFcIikpfSkudG8udGhyb3coVHlwZUVycm9yKVxuICAgICAgICAgICAgZXhwZWN0KCgpPT57cXVldWUuYWRkKGZ1bmN0aW9uKCl7fSl9KS50by50aHJvdyhUeXBlRXJyb3IpXG4gICAgICAgIH0pO1xuXG4gICAgfSlcbn0pIiwgImltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge1N0YWNrfSBmcm9tIFwiLi4vLi4vLi4vc291cmNlL3R5cGVzL3N0YWNrLm1qc1wiO1xuXG5cbmRlc2NyaWJlKCdTdGFjaycsIGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgc3RhY2s7XG4gICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICAgIHN0YWNrID0gbmV3IFN0YWNrO1xuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnaXNFbXB0eSgpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdmaXJzdCBpdCBzaG91bGQgZW1wdHknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3Qoc3RhY2suaXNFbXB0eSgpKS50by5iZS50cnVlO1xuICAgICAgICB9KTtcblxuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnYWRkIHNlcXVlbmNlIHBlZWsgYW5kIHB1bGwnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ3Jlc3VsdCBhLGEsYSxiJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KHN0YWNrLnB1c2goJ2EnKSkudG8uYmUuaW5zdGFuY2VPZihTdGFjayk7XG4gICAgICAgICAgICBleHBlY3Qoc3RhY2suaXNFbXB0eSgpKS50by5iZS5mYWxzZTtcbiAgICAgICAgICAgIGV4cGVjdChzdGFjay5wdXNoKCdiJykpLnRvLmJlLmluc3RhbmNlT2YoU3RhY2spO1xuICAgICAgICAgICAgZXhwZWN0KHN0YWNrLnB1c2goJ2MnKSkudG8uYmUuaW5zdGFuY2VPZihTdGFjayk7XG4gICAgICAgICAgICBleHBlY3Qoc3RhY2sucGVlaygpKS50by5iZS5lcXVhbCgnYycpO1xuICAgICAgICAgICAgZXhwZWN0KHN0YWNrLnBlZWsoKSkudG8uYmUuZXF1YWwoJ2MnKTtcbiAgICAgICAgICAgIGV4cGVjdChzdGFjay5wb3AoKSkudG8uYmUuZXF1YWwoJ2MnKTtcbiAgICAgICAgICAgIGV4cGVjdChzdGFjay5wZWVrKCkpLnRvLmJlLmVxdWFsKCdiJyk7XG4gICAgICAgICAgICBleHBlY3Qoc3RhY2suaXNFbXB0eSgpKS50by5iZS5mYWxzZTtcbiAgICAgICAgfSk7XG5cbiAgICB9KVxuXG4gICAgZGVzY3JpYmUoJ2FkZCBhbmQgY2xlYXInLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBlbXB0eScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChzdGFjay5pc0VtcHR5KCkpLnRvLmJlLnRydWU7XG4gICAgICAgICAgICBleHBlY3Qoc3RhY2sucHVzaCgnYScpKS50by5iZS5pbnN0YW5jZU9mKFN0YWNrKTtcbiAgICAgICAgICAgIGV4cGVjdChzdGFjay5pc0VtcHR5KCkpLnRvLmJlLmZhbHNlO1xuICAgICAgICAgICAgZXhwZWN0KHN0YWNrLmNsZWFyKCkpLnRvLmJlLmluc3RhbmNlT2YoU3RhY2spO1xuICAgICAgICAgICAgZXhwZWN0KHN0YWNrLmlzRW1wdHkoKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgfSk7XG5cbiAgICB9KVxufSkiLCAiXCJ1c2Ugc3RyaWN0XCI7XG5cbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge0Jhc2VXaXRoT3B0aW9uc30gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS90eXBlcy9iYXNld2l0aG9wdGlvbnMubWpzXCI7XG5cblxuZGVzY3JpYmUoJ0Jhc2VXaXRoT3B0aW9ucycsIGZ1bmN0aW9uICgpIHtcblxuICAgIGRlc2NyaWJlKCduZXcgQmFzZVdpdGhPcHRpb25zJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdpcyBpbnN0YW5jZSBvZiBCYXNlV2l0aE9wdGlvbnMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IEJhc2VXaXRoT3B0aW9ucykudG8uYmUuaW5zdGFuY2VPZihCYXNlV2l0aE9wdGlvbnMpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnaXMgaW5zdGFuY2Ugb2YgT2JqZWN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KG5ldyBCYXNlV2l0aE9wdGlvbnMpLnRvLmJlLmluc3RhbmNlT2YoT2JqZWN0KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ2dldCBvcHRpb24gaXMgdHJ1ZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChuZXcgQmFzZVdpdGhPcHRpb25zKHthOiB0cnVlfSkuZ2V0T3B0aW9uKCdhJykpLnRvLmJlLnRydWU7XG4gICAgICAgIH0pO1xuXG4gICAgfSlcblxufSkiLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBpbnRlcm5hbFN5bWJvbCB9IGZyb20gXCIuLi9jb25zdGFudHMubWpzXCI7XG5cbmltcG9ydCB7IEJhc2UgfSBmcm9tIFwiLi9iYXNlLm1qc1wiO1xuaW1wb3J0IHsgaXNJbnN0YW5jZSB9IGZyb20gXCIuL2lzLm1qc1wiO1xuaW1wb3J0IHsgTm9kZSB9IGZyb20gXCIuL25vZGUubWpzXCI7XG5pbXBvcnQgeyBOb2RlTGlzdCB9IGZyb20gXCIuL25vZGVsaXN0Lm1qc1wiO1xuaW1wb3J0IHsgdmFsaWRhdGVJbnN0YW5jZSB9IGZyb20gXCIuL3ZhbGlkYXRlLm1qc1wiO1xuXG5leHBvcnQgeyBOb2RlUmVjdXJzaXZlSXRlcmF0b3IgfTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHR5cGUge3N5bWJvbH1cbiAqL1xuY29uc3QgaXNOb2RlTGlzdFN5bWJvbCA9IFN5bWJvbChcImlzTm9kZUxpc3RcIik7XG5cbi8qKlxuICogWW91IGNhbiBjcmVhdGUgdGhlIGluc3RhbmNlIHZpYSB0aGUgbW9uc3RlciBuYW1lc3BhY2UgYG5ldyBNb25zdGVyLlR5cGVzLk5vZGVSZWN1cnNpdmVJdGVyYXRvcigpYC5cbiAqXG4gKiBAZXh0ZXJuYWxFeGFtcGxlIC4uLy4uL2V4YW1wbGUvdHlwZXMvbm9kZXJlY3Vyc2l2ZWl0ZXJhdG9yLm1qc1xuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNi4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuVHlwZXNcbiAqIEBzdW1tYXJ5IEFuIGl0ZXJhdG9yIHRvIHJ1biByZWN1cnNpdmVseSB0aHJvdWdoIGEgdHJlZSBvZiBub2Rlc1xuICovXG5jbGFzcyBOb2RlUmVjdXJzaXZlSXRlcmF0b3IgZXh0ZW5kcyBCYXNlIHtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge05vZGV9IFtkYXRhXVxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKG5vZGUpIHtcbiAgICAgICAgc3VwZXIoKTtcblxuICAgICAgICB0aGlzW2lzTm9kZUxpc3RTeW1ib2xdID0gZmFsc2U7XG5cbiAgICAgICAgLy8gaXRlcmF0b3IgaXMgYSBub2RlbGlzdFxuICAgICAgICBpZiAoaXNJbnN0YW5jZShub2RlLCBOb2RlTGlzdCkpIHtcbiAgICAgICAgICAgIGxldCBjaGlsZHJlbiA9IG5vZGU7XG4gICAgICAgICAgICBub2RlID0gbmV3IE5vZGUoKTtcbiAgICAgICAgICAgIG5vZGUuY2hpbGROb2RlcyA9IGNoaWxkcmVuO1xuICAgICAgICAgICAgdGhpc1tpc05vZGVMaXN0U3ltYm9sXSA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzW2ludGVybmFsU3ltYm9sXSA9IHZhbGlkYXRlSW5zdGFuY2Uobm9kZSwgTm9kZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL09wZXJhdG9ycy95aWVsZFxuICAgICAqL1xuICAgIFtTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24qICgpIHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBlbmQgb2YgdGhlIGdlbmVyYXRvciBmdW5jdGlvbiBpcyByZWFjaGVkLiBJbiB0aGlzIGNhc2UsIGV4ZWN1dGlvbiBvZiB0aGUgZ2VuZXJhdG9yXG4gICAgICAgICAqIGVuZHMgYW5kIGFuIEl0ZXJhdG9yUmVzdWx0IGlzIHJldHVybmVkIHRvIHRoZSBjYWxsZXIgaW4gd2hpY2ggdGhlIHZhbHVlIGlzIHVuZGVmaW5lZCBhbmQgZG9uZSBpcyB0cnVlLlxuICAgICAgICAgKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL09wZXJhdG9ycy95aWVsZFxuICAgICAgICAgKi9cbiAgICAgICAgaWYgKHRoaXNbaW50ZXJuYWxTeW1ib2xdID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGl0ZXJhdG9yIGlzIGEgbm9kZWxpc3QgYW5kIHRoZSBtYWluIG5vZGUgaXMgb25seSBhIHBsYWNlaG9sZGVyXG4gICAgICAgIGlmICh0aGlzW2lzTm9kZUxpc3RTeW1ib2xdICE9PSB0cnVlKSB7XG4gICAgICAgICAgICB5aWVsZCB0aGlzW2ludGVybmFsU3ltYm9sXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzW2ludGVybmFsU3ltYm9sXS5oYXNDaGlsZE5vZGVzKCkpIHtcbiAgICAgICAgICAgIGxldCBjaGlsZE5vZGVzID0gdGhpc1tpbnRlcm5hbFN5bWJvbF0uY2hpbGROb2RlcztcblxuICAgICAgICAgICAgZm9yIChsZXQgbm9kZSBvZiBjaGlsZE5vZGVzKSB7XG4gICAgICAgICAgICAgICAgeWllbGQqIG5ldyBOb2RlUmVjdXJzaXZlSXRlcmF0b3Iobm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm47XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGNhbGxiYWNrXG4gICAgICogQHJldHVybiB7TW9uc3Rlci5UeXBlcy5Ob2RlUmVjdXJzaXZlSXRlcmF0b3J9XG4gICAgICovXG4gICAgZm9yRWFjaChjYWxsYmFjaykge1xuICAgICAgICBmb3IgKGNvbnN0IG5vZGUgb2YgdGhpcykge1xuICAgICAgICAgICAgY2FsbGJhY2sobm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuIiwgIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7Tm9kZX0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS90eXBlcy9ub2RlLm1qc1wiO1xuaW1wb3J0IHtOb2RlTGlzdH0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS90eXBlcy9ub2RlbGlzdC5tanNcIjtcbmltcG9ydCB7Tm9kZVJlY3Vyc2l2ZUl0ZXJhdG9yfSBmcm9tIFwiLi4vLi4vLi4vc291cmNlL3R5cGVzL25vZGVyZWN1cnNpdmVpdGVyYXRvci5tanNcIjtcblxuZGVzY3JpYmUoJ05vZGVMaXN0JywgZnVuY3Rpb24gKCkge1xuICAgIGRlc2NyaWJlKCcjY29uc3RydWN0b3InLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgY3JlYXRlIGFuIGVtcHR5IE5vZGVMaXN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGV0IG5vZGVMaXN0ID0gbmV3IE5vZGVMaXN0KCk7XG5cbiAgICAgICAgICAgIGV4cGVjdChub2RlTGlzdC5zaXplKS50by5lcXVhbCgwKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBjcmVhdGUgYSBOb2RlTGlzdCBmcm9tIGFuIGFycmF5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGV0IG5vZGVMaXN0ID0gbmV3IE5vZGVMaXN0KFtcbiAgICAgICAgICAgICAgICBuZXcgTm9kZSgnZGl2JyksXG4gICAgICAgICAgICAgICAgbmV3IE5vZGUoJ2RpdicpLFxuICAgICAgICAgICAgICAgIG5ldyBOb2RlKCdkaXYnKVxuICAgICAgICAgICAgXSk7XG5cbiAgICAgICAgICAgIGV4cGVjdChub2RlTGlzdC5zaXplKS50by5lcXVhbCgzKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBjcmVhdGUgYSBOb2RlTGlzdCBmcm9tIGEgTm9kZUxpc3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgbm9kZUxpc3QgPSBuZXcgTm9kZUxpc3QoW1xuICAgICAgICAgICAgICAgIG5ldyBOb2RlKCdkaXYnKSxcbiAgICAgICAgICAgICAgICBuZXcgTm9kZSgnZGl2JyksXG4gICAgICAgICAgICAgICAgbmV3IE5vZGUoJ2RpdicpXG4gICAgICAgICAgICBdKTtcblxuICAgICAgICAgICAgbGV0IG5vZGVMaXN0MiA9IG5ldyBOb2RlTGlzdChub2RlTGlzdCk7XG5cbiAgICAgICAgICAgIGV4cGVjdChub2RlTGlzdDIuc2l6ZSkudG8uZXF1YWwoMyk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ2NyZWF0ZSBOb2RlTGlzdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZXhwZWN0KG5ldyBOb2RlTGlzdCgpKS5pcy5pbnN0YW5jZW9mKE5vZGVMaXN0KTtcbiAgICB9KVxuXG4gICAgaXQoJ2FkZCBOb2RlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBleHBlY3QobmV3IE5vZGVMaXN0KCkuYWRkKG5ldyBOb2RlKCkpKS50by5iZS5pbnN0YW5jZW9mKE5vZGVMaXN0KTtcbiAgICB9KVxuXG4gICAgaXQoJ3JlbW92ZSBOb2RlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBleHBlY3QobmV3IE5vZGVMaXN0KCkucmVtb3ZlKG5ldyBOb2RlKCkpKS50by5iZS5pbnN0YW5jZW9mKE5vZGVMaXN0KTtcbiAgICB9KVxuXG4gICAgaXQoJ2hhcyB1bmtub3duIE5vZGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGV4cGVjdChuZXcgTm9kZUxpc3QoKS5oYXMobmV3IE5vZGUpKS50by5iZS5mYWxzZTtcbiAgICB9KVxuXG4gICAgaXQoJ2hhcyBhZGRlZCBOb2RlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBuID0gbmV3IE5vZGU7XG4gICAgICAgIGV4cGVjdChuZXcgTm9kZUxpc3QoKS5hZGQobikuaGFzKG4pKS50by5iZS50cnVlO1xuICAgIH0pXG5cbiAgICBpdCgndGhyb3cgZXhjZXB0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBleHBlY3QoKCkgPT4gbmV3IE5vZGVMaXN0KCkuYWRkKDEpKS50by50aHJvdyhFcnJvcik7XG4gICAgfSlcblxuICAgIGl0KCdjaGVjayBsZXZlbCcsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBjb25zdCByb290ID0gbmV3IE5vZGUoJ3Jvb3QnKTtcblxuICAgICAgICBjb25zdCBuMSA9IG5ldyBOb2RlKCduMScpO1xuICAgICAgICBjb25zdCBuMiA9IG5ldyBOb2RlKCduMicpO1xuICAgICAgICBjb25zdCBuMyA9IG5ldyBOb2RlKCduMycpO1xuICAgICAgICBjb25zdCBuNCA9IG5ldyBOb2RlKCduNCcpO1xuXG4gICAgICAgIGNvbnN0IG4xMSA9IG5ldyBOb2RlKCduMTEnKTtcbiAgICAgICAgY29uc3QgbjEyID0gbmV3IE5vZGUoJ24xMicpO1xuICAgICAgICBjb25zdCBuMTMgPSBuZXcgTm9kZSgnbjEzJyk7XG5cbiAgICAgICAgY29uc3QgbjIxID0gbmV3IE5vZGUoJ24yMScpO1xuICAgICAgICBjb25zdCBuMjIgPSBuZXcgTm9kZSgnbjIyJyk7XG4gICAgICAgIGNvbnN0IG4yMyA9IG5ldyBOb2RlKCduMjMnKTtcblxuICAgICAgICBjb25zdCBuNDEgPSBuZXcgTm9kZSgnbjQxJyk7XG4gICAgICAgIGNvbnN0IG40MiA9IG5ldyBOb2RlKCduNDInKTtcblxuICAgICAgICBjb25zdCBuNDExID0gbmV3IE5vZGUoJ240MTEnKTtcbiAgICAgICAgY29uc3QgbjQxMiA9IG5ldyBOb2RlKCduNDEyJyk7XG4gICAgICAgIGNvbnN0IG40MTMgPSBuZXcgTm9kZSgnbjQxMycpO1xuXG4gICAgICAgIGNvbnN0IG40MTIxID0gbmV3IE5vZGUoJ240MTIxJyk7XG5cbiAgICAgICAgcm9vdC5hcHBlbmRDaGlsZChuMSkuYXBwZW5kQ2hpbGQobjIpLmFwcGVuZENoaWxkKG4zKS5hcHBlbmRDaGlsZChuNCk7XG4gICAgICAgIG4xLmFwcGVuZENoaWxkKG4xMSkuYXBwZW5kQ2hpbGQobjEyKS5hcHBlbmRDaGlsZChuMTMpO1xuICAgICAgICBuMi5hcHBlbmRDaGlsZChuMjEpLmFwcGVuZENoaWxkKG4yMikuYXBwZW5kQ2hpbGQobjIzKTtcbiAgICAgICAgbjQuYXBwZW5kQ2hpbGQobjQxKS5hcHBlbmRDaGlsZChuNDIpO1xuICAgICAgICBuNDEuYXBwZW5kQ2hpbGQobjQxMSkuYXBwZW5kQ2hpbGQobjQxMikuYXBwZW5kQ2hpbGQobjQxMyk7XG4gICAgICAgIG40MTIuYXBwZW5kQ2hpbGQobjQxMjEpO1xuXG4gICAgICAgIGxldCBpdGVyYXRvciA9IG5ldyBOb2RlUmVjdXJzaXZlSXRlcmF0b3Iocm9vdCk7XG5cbiAgICAgICAgbGV0IHJlc3VsdCA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IG4gb2YgaXRlcmF0b3IpIHtcbiAgICAgICAgICAgIGV4cGVjdChuKS50by5iZS5hbi5pbnN0YW5jZW9mKE5vZGUpO1xuICAgICAgICAgICAgcmVzdWx0LnB1c2gobi52YWx1ZSArIFwiOlwiICsgbi5sZXZlbCk7XG4gICAgICAgIH1cblxuXG4gICAgICAgIGV4cGVjdChyZXN1bHQpLnRvLmRlZXAuZXF1YWwoW1xuICAgICAgICAgICAgJ3Jvb3Q6MCcsXG4gICAgICAgICAgICAnbjE6MScsXG4gICAgICAgICAgICAnbjExOjInLFxuICAgICAgICAgICAgJ24xMjoyJyxcbiAgICAgICAgICAgICduMTM6MicsXG4gICAgICAgICAgICAnbjI6MScsXG4gICAgICAgICAgICAnbjIxOjInLFxuICAgICAgICAgICAgJ24yMjoyJyxcbiAgICAgICAgICAgICduMjM6MicsXG4gICAgICAgICAgICAnbjM6MScsXG4gICAgICAgICAgICAnbjQ6MScsXG4gICAgICAgICAgICAnbjQxOjInLFxuICAgICAgICAgICAgJ240MTE6MycsXG4gICAgICAgICAgICAnbjQxMjozJyxcbiAgICAgICAgICAgICduNDEyMTo0JyxcbiAgICAgICAgICAgICduNDEzOjMnLFxuICAgICAgICAgICAgJ240MjoyJ1xuXG4gICAgICAgIF0pO1xuXG4gICAgICAgIG40MTIxLmFwcGVuZENoaWxkKG5ldyBOb2RlKCduNDEyMTEnKSk7XG5cbiAgICAgICAgaXRlcmF0b3IgPSBuZXcgTm9kZVJlY3Vyc2l2ZUl0ZXJhdG9yKHJvb3QpO1xuICAgICAgICByZXN1bHQgPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBuIG9mIGl0ZXJhdG9yKSB7XG4gICAgICAgICAgICBleHBlY3QobikudG8uYmUuYW4uaW5zdGFuY2VvZihOb2RlKTtcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKG4udmFsdWUgKyBcIjpcIiArIG4ubGV2ZWwpO1xuICAgICAgICB9XG5cbiAgICAgICAgZXhwZWN0KHJlc3VsdCkudG8uZGVlcC5lcXVhbChbXG4gICAgICAgICAgICAncm9vdDowJyxcbiAgICAgICAgICAgICduMToxJyxcbiAgICAgICAgICAgICduMTE6MicsXG4gICAgICAgICAgICAnbjEyOjInLFxuICAgICAgICAgICAgJ24xMzoyJyxcbiAgICAgICAgICAgICduMjoxJyxcbiAgICAgICAgICAgICduMjE6MicsXG4gICAgICAgICAgICAnbjIyOjInLFxuICAgICAgICAgICAgJ24yMzoyJyxcbiAgICAgICAgICAgICduMzoxJyxcbiAgICAgICAgICAgICduNDoxJyxcbiAgICAgICAgICAgICduNDE6MicsXG4gICAgICAgICAgICAnbjQxMTozJyxcbiAgICAgICAgICAgICduNDEyOjMnLFxuICAgICAgICAgICAgJ240MTIxOjQnLFxuICAgICAgICAgICAgJ240MTIxMTo1JyxcbiAgICAgICAgICAgICduNDEzOjMnLFxuICAgICAgICAgICAgJ240MjoyJ1xuXG4gICAgICAgIF0pO1xuXG5cbiAgICAgICAgY29uc3QgYmIgPSBuZXcgTm9kZSgnYmInKSAvLyBiaWcgYmFuZ1xuXG4gICAgICAgIGJiLmFwcGVuZENoaWxkKHJvb3QpO1xuICAgICAgICBpdGVyYXRvciA9IG5ldyBOb2RlUmVjdXJzaXZlSXRlcmF0b3IoYmIpO1xuXG4gICAgICAgIHJlc3VsdCA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IG4gb2YgaXRlcmF0b3IpIHtcbiAgICAgICAgICAgIGV4cGVjdChuKS50by5iZS5hbi5pbnN0YW5jZW9mKE5vZGUpO1xuICAgICAgICAgICAgcmVzdWx0LnB1c2gobi52YWx1ZSArIFwiOlwiICsgbi5sZXZlbCk7XG4gICAgICAgIH1cblxuICAgICAgICBleHBlY3QocmVzdWx0KS50by5kZWVwLmVxdWFsKFtcbiAgICAgICAgICAgICdiYjowJyxcbiAgICAgICAgICAgICdyb290OjEnLFxuICAgICAgICAgICAgJ24xOjInLFxuICAgICAgICAgICAgJ24xMTozJyxcbiAgICAgICAgICAgICduMTI6MycsXG4gICAgICAgICAgICAnbjEzOjMnLFxuICAgICAgICAgICAgJ24yOjInLFxuICAgICAgICAgICAgJ24yMTozJyxcbiAgICAgICAgICAgICduMjI6MycsXG4gICAgICAgICAgICAnbjIzOjMnLFxuICAgICAgICAgICAgJ24zOjInLFxuICAgICAgICAgICAgJ240OjInLFxuICAgICAgICAgICAgJ240MTozJyxcbiAgICAgICAgICAgICduNDExOjQnLFxuICAgICAgICAgICAgJ240MTI6NCcsXG4gICAgICAgICAgICAnbjQxMjE6NScsXG4gICAgICAgICAgICAnbjQxMjExOjYnLFxuICAgICAgICAgICAgJ240MTM6NCcsXG4gICAgICAgICAgICAnbjQyOjMnXG5cbiAgICAgICAgXSk7XG5cbiAgICB9KVxuXG4gICAgZGVzY3JpYmUoJ0xldmVscycsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBpdCgnbjIgc2hvdWxkIGxldmVsIDInLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIGNvbnN0IG4wID0gbmV3IE5vZGUoJ2FiYycpO1xuXG4gICAgICAgICAgICBjb25zdCBuMSA9IG5ldyBOb2RlKCdkZWYnKTtcbiAgICAgICAgICAgIG4wLmFwcGVuZENoaWxkKG4xKVxuXG4gICAgICAgICAgICBjb25zdCBuMiA9IG5ldyBOb2RlKCdnaGknKTtcbiAgICAgICAgICAgIG4xLmFwcGVuZENoaWxkKG4yKTtcblxuICAgICAgICAgICAgY29uc3QgbjMgPSBuZXcgTm9kZSgnamtsJyk7XG4gICAgICAgICAgICBuMi5hcHBlbmRDaGlsZChuMyk7XG5cbiAgICAgICAgICAgIGV4cGVjdChuMC5sZXZlbCkudG8uYmUuZXF1YWwoMCk7XG4gICAgICAgICAgICBleHBlY3QobjEubGV2ZWwpLnRvLmJlLmVxdWFsKDEpO1xuICAgICAgICAgICAgZXhwZWN0KG4yLmxldmVsKS50by5iZS5lcXVhbCgyKTtcbiAgICAgICAgICAgIGV4cGVjdChuMy5sZXZlbCkudG8uYmUuZXF1YWwoMyk7XG5cbiAgICAgICAgfSk7XG4gICAgfSk7XG5cblxuICAgIGRlc2NyaWJlKCd0b1N0cmluZygpJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdzaG91bGQgb3V0cHV0IGVtcHR5IHN0cmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IG5vZGUgPSBuZXcgTm9kZSgpO1xuICAgICAgICAgICAgZXhwZWN0KG5vZGUudG9TdHJpbmcoKSkuaXMuZXF1YWwoJycpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIG91dHB1dCBzdHJpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zdCBuMCA9IG5ldyBOb2RlKCdhYmMnKTtcblxuICAgICAgICAgICAgY29uc3QgbjEgPSBuZXcgTm9kZSgnZGVmJyk7XG4gICAgICAgICAgICBuMC5hcHBlbmRDaGlsZChuMSlcblxuICAgICAgICAgICAgY29uc3QgbjExID0gbmV3IE5vZGUoJ2doaScpO1xuICAgICAgICAgICAgbjAuYXBwZW5kQ2hpbGQobjExKVxuXG4gICAgICAgICAgICBjb25zdCBuMiA9IG5ldyBOb2RlKCdqa2wnKTtcbiAgICAgICAgICAgIG4xLmFwcGVuZENoaWxkKG4yKTtcblxuICAgICAgICAgICAgY29uc3QgbjMgPSBuZXcgTm9kZSgnbW5vJyk7XG4gICAgICAgICAgICBuMS5hcHBlbmRDaGlsZChuMyk7XG5cbiAgICAgICAgICAgIGNvbnN0IG40ID0gbmV3IE5vZGUoJ3BxcicpO1xuICAgICAgICAgICAgbjIuYXBwZW5kQ2hpbGQobjQpO1xuXG4gICAgICAgICAgICBleHBlY3QobjIubGV2ZWwpLnRvLmJlLmVxdWFsKDIpXG5cbiAgICAgICAgICAgIGNvbnNvbGUubG9nKG4wLnRvU3RyaW5nKCkpO1xuICAgICAgICAgICAgLy8gZXhwZWN0KG4wLnRvU3RyaW5nKCkpLmlzLmVxdWFsKCcnKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cblxufSk7IiwgImltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge1F1ZXVlfSBmcm9tIFwiLi4vLi4vLi4vc291cmNlL3R5cGVzL3F1ZXVlLm1qc1wiO1xuXG5kZXNjcmliZSgnUXVldWUnLCBmdW5jdGlvbiAoKSB7XG4gICAgbGV0IHF1ZXVlO1xuICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgICBxdWV1ZSA9IG5ldyBRdWV1ZTtcbiAgICB9KVxuXG4gICAgZGVzY3JpYmUoJ2lzRW1wdHkoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBpdCgnZmlyc3QgaXQgc2hvdWxkIGVtcHR5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KHF1ZXVlLmlzRW1wdHkoKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgfSk7XG5cbiAgICB9KVxuXG4gICAgZGVzY3JpYmUoJ2FkZCBzZXF1ZW5jZSBwZWVrIGFuZCBwb2xsJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGl0KCdyZXN1bHQgYSxhLGEsYicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChxdWV1ZS5hZGQoJ2EnKSkudG8uYmUuaW5zdGFuY2VPZihRdWV1ZSk7XG4gICAgICAgICAgICBleHBlY3QocXVldWUuaXNFbXB0eSgpKS50by5iZS5mYWxzZTtcbiAgICAgICAgICAgIGV4cGVjdChxdWV1ZS5hZGQoJ2InKSkudG8uYmUuaW5zdGFuY2VPZihRdWV1ZSk7XG4gICAgICAgICAgICBleHBlY3QocXVldWUuYWRkKCdjJykpLnRvLmJlLmluc3RhbmNlT2YoUXVldWUpO1xuICAgICAgICAgICAgZXhwZWN0KHF1ZXVlLnBlZWsoKSkudG8uYmUuZXF1YWwoJ2EnKTtcbiAgICAgICAgICAgIGV4cGVjdChxdWV1ZS5wZWVrKCkpLnRvLmJlLmVxdWFsKCdhJyk7XG4gICAgICAgICAgICBleHBlY3QocXVldWUucG9sbCgpKS50by5iZS5lcXVhbCgnYScpO1xuICAgICAgICAgICAgZXhwZWN0KHF1ZXVlLnBlZWsoKSkudG8uYmUuZXF1YWwoJ2InKTtcbiAgICAgICAgICAgIGV4cGVjdChxdWV1ZS5pc0VtcHR5KCkpLnRvLmJlLmZhbHNlO1xuICAgICAgICB9KTtcblxuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnYWRkIGFuZCBjbGVhcicsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBpdCgnc2hvdWxkIGVtcHR5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KHF1ZXVlLmlzRW1wdHkoKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgICAgIGV4cGVjdChxdWV1ZS5hZGQoJ2EnKSkudG8uYmUuaW5zdGFuY2VPZihRdWV1ZSk7XG4gICAgICAgICAgICBleHBlY3QocXVldWUuaXNFbXB0eSgpKS50by5iZS5mYWxzZTtcbiAgICAgICAgICAgIGV4cGVjdChxdWV1ZS5jbGVhcigpKS50by5iZS5pbnN0YW5jZU9mKFF1ZXVlKTtcbiAgICAgICAgICAgIGV4cGVjdChxdWV1ZS5pc0VtcHR5KCkpLnRvLmJlLnRydWU7XG4gICAgICAgIH0pO1xuXG4gICAgfSlcblxuXG4gICAgXG59KSIsICIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge05vZGV9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvdHlwZXMvbm9kZS5tanNcIjtcbmltcG9ydCB7Tm9kZUxpc3R9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvdHlwZXMvbm9kZWxpc3QubWpzXCI7XG5pbXBvcnQge05vZGVSZWN1cnNpdmVJdGVyYXRvcn0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS90eXBlcy9ub2RlcmVjdXJzaXZlaXRlcmF0b3IubWpzXCI7XG5cbmRlc2NyaWJlKCdOb2RlUmVjdXJzaXZlSXRlcmF0b3InLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGV4ZXB0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBleHBlY3QoKCkgPT4gbmV3IE5vZGVSZWN1cnNpdmVJdGVyYXRvcigpKS50by50aHJvdyhFcnJvcilcbiAgICB9KTtcbiAgICBpdCgnc2hvdWxkIGJlIGEgZnVuY3Rpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGV4cGVjdChOb2RlUmVjdXJzaXZlSXRlcmF0b3IpLnRvLmJlLmEoJ2Z1bmN0aW9uJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGJlIGEgY29uc3RydWN0b3InLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGV4cGVjdChuZXcgTm9kZVJlY3Vyc2l2ZUl0ZXJhdG9yKG5ldyBOb2RlKSkudG8uYmUuYW4uaW5zdGFuY2VvZihOb2RlUmVjdXJzaXZlSXRlcmF0b3IpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9PcGVyYXRvcnMveWllbGRcbiAgICAgKi9cbiAgICBpdCgndW5kZWZpbmVkIHNob3VsZCBub3QgcmVzdWx0IGluIHVuZGVmaW5lZCBub2RlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBpdGVyYXRvciA9IG5ldyBOb2RlUmVjdXJzaXZlSXRlcmF0b3IobmV3IE5vZGUpO1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IG4gb2YgaXRlcmF0b3IpIHtcbiAgICAgICAgICAgIGV4cGVjdChuKS50by5iZS5hbi5pbnN0YW5jZW9mKE5vZGUpO1xuICAgICAgICAgICAgcmVzdWx0LnB1c2gobi52YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBleHBlY3QocmVzdWx0KS50by5kZWVwLmVxdWFsKFt1bmRlZmluZWRdKTtcblxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBpdGVyYXRlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBub2RlID1cbiAgICAgICAgICAgIG5ldyBOb2RlKCcxJylcbiAgICAgICAgbm9kZS5hcHBlbmRDaGlsZChcbiAgICAgICAgICAgIChuZXcgTm9kZSgnMicpKS5hcHBlbmRDaGlsZChuZXcgTm9kZSgnMi4xJykpLmFwcGVuZENoaWxkKG5ldyBOb2RlKCcyLjInKSkuYXBwZW5kQ2hpbGQobmV3IE5vZGUoJzIuMycpKSkuYXBwZW5kQ2hpbGQobmV3IE5vZGUoJzMnKSkuYXBwZW5kQ2hpbGQobmV3IE5vZGUoJzQnKS5hcHBlbmRDaGlsZChuZXcgTm9kZSgnNC4xJykpLmFwcGVuZENoaWxkKG5ldyBOb2RlKCc0LjInKSkpO1xuXG4gICAgICAgIGNvbnN0IGl0ZXJhdG9yID0gbmV3IE5vZGVSZWN1cnNpdmVJdGVyYXRvcihub2RlKTtcblxuICAgICAgICBjb25zdCByZXN1bHQgPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBuIG9mIGl0ZXJhdG9yKSB7XG4gICAgICAgICAgICBleHBlY3QobikudG8uYmUuYW4uaW5zdGFuY2VvZihOb2RlKTtcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKG4udmFsdWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgZXhwZWN0KHJlc3VsdCkudG8uZGVlcC5lcXVhbChbJzEnLCAnMicsICcyLjEnLCAnMi4yJywgJzIuMycsICczJywgJzQnLCAnNC4xJywgJzQuMiddKTtcblxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBpdGVyYXRlIG5vZGVsaXN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBub2RlTGlzdCA9IG5ldyBOb2RlTGlzdCgpO1xuXG4gICAgICAgIG5vZGVMaXN0LmFkZChcbiAgICAgICAgICAgIChuZXcgTm9kZSgnMicpKS5hcHBlbmRDaGlsZChuZXcgTm9kZSgnMi4xJykpLmFwcGVuZENoaWxkKG5ldyBOb2RlKCcyLjInKSkuYXBwZW5kQ2hpbGQobmV3IE5vZGUoJzIuMycpKS5hcHBlbmRDaGlsZChuZXcgTm9kZSgnMycpKS5hcHBlbmRDaGlsZChuZXcgTm9kZSgnNCcpLmFwcGVuZENoaWxkKG5ldyBOb2RlKCc0LjEnKSkuYXBwZW5kQ2hpbGQobmV3IE5vZGUoJzQuMicpKSkpO1xuXG4gICAgICAgIG5vZGVMaXN0LmFkZChuZXcgTm9kZSgneCcpKTtcblxuICAgICAgICBjb25zdCBpdGVyYXRvciA9IG5ldyBOb2RlUmVjdXJzaXZlSXRlcmF0b3Iobm9kZUxpc3QpO1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IG4gb2YgaXRlcmF0b3IpIHtcbiAgICAgICAgICAgIGV4cGVjdChuKS50by5iZS5hbi5pbnN0YW5jZW9mKE5vZGUpO1xuICAgICAgICAgICAgcmVzdWx0LnB1c2gobi52YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIGV4cGVjdChyZXN1bHQpLnRvLmRlZXAuZXF1YWwoWycyJywgJzIuMScsICcyLjInLCAnMi4zJywgJzMnLCAnNCcsICc0LjEnLCAnNC4yJywgJ3gnXSk7XG5cbiAgICB9KTtcblxufSk7IiwgIi8qKlxuICogQ29weXJpZ2h0IHNjaHVrYWkgR21iSCBhbmQgY29udHJpYnV0b3JzIDIwMjMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBOb2RlIG1vZHVsZTogQHNjaHVrYWkvbW9uc3RlclxuICogVGhpcyBmaWxlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBR1BMdjMgTGljZW5zZS5cbiAqIExpY2Vuc2UgdGV4dCBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLTMuMC5lbi5odG1sXG4gKi9cblxuaW1wb3J0IHsgaW5zdGFuY2VTeW1ib2wsIGludGVybmFsU3ltYm9sIH0gZnJvbSBcIi4uL2NvbnN0YW50cy5tanNcIjtcbmltcG9ydCB7IGV4dGVuZCB9IGZyb20gXCIuLi9kYXRhL2V4dGVuZC5tanNcIjtcblxuaW1wb3J0IHsgRm9ybWF0dGVyIGFzIFRleHRGb3JtYXR0ZXIgfSBmcm9tIFwiLi4vdGV4dC9mb3JtYXR0ZXIubWpzXCI7XG5pbXBvcnQgeyB2YWxpZGF0ZUluc3RhbmNlLCB2YWxpZGF0ZVN0cmluZyB9IGZyb20gXCIuLi90eXBlcy92YWxpZGF0ZS5tanNcIjtcbmltcG9ydCB7IFRyYW5zbGF0aW9ucyB9IGZyb20gXCIuL3RyYW5zbGF0aW9ucy5tanNcIjtcblxuZXhwb3J0IHsgRm9ybWF0dGVyIH07XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEB0eXBlIHtzeW1ib2x9XG4gKi9cbmNvbnN0IGludGVybmFsVHJhbnNsYXRpb25TeW1ib2wgPSBTeW1ib2woXCJpbnRlcm5hbFRyYW5zbGF0aW9uXCIpO1xuXG4vKipcbiAqIFRoZSBGb3JtYXR0ZXIgZXh0ZW5kcyB0aGUgVGV4dC5Gb3JtYXR0ZXIgd2l0aCB0aGUgcG9zc2liaWxpdHkgdG8gcmVwbGFjZSB0aGUga2V5IGJ5IGEgdHJhbnNsYXRpb24uXG4gKlxuICogQGV4dGVybmFsRXhhbXBsZSAuLi8uLi9leGFtcGxlL2kxOG4vZm9ybWF0dGVyLm1qc1xuICogQGxpY2Vuc2UgQUdQTHYzXG4gKiBAc2luY2UgMS4yNi4wXG4gKiBAY29weXJpZ2h0IHNjaHVrYWkgR21iSFxuICogQG1lbWJlck9mIE1vbnN0ZXIuSTE4blxuICovXG5jbGFzcyBGb3JtYXR0ZXIgZXh0ZW5kcyBUZXh0Rm9ybWF0dGVyIHtcbiAgICAvKipcbiAgICAgKiBEZWZhdWx0IHZhbHVlcyBmb3IgdGhlIG1hcmtlcnMgYXJlIGAke2AgYW5kIGB9YFxuICAgICAqXG4gICAgICogQHBhcmFtIHtvYmplY3R9IG9iamVjdFxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gdmFsdWUgaXMgbm90IGEgb2JqZWN0XG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob2JqZWN0LCB0cmFuc2xhdGlvbiwgb3B0aW9ucykge1xuICAgICAgICBzdXBlcihvYmplY3QsIG9wdGlvbnMpO1xuICAgICAgICB0aGlzW2ludGVybmFsVHJhbnNsYXRpb25TeW1ib2xdID0gdmFsaWRhdGVJbnN0YW5jZSh0cmFuc2xhdGlvbiwgVHJhbnNsYXRpb25zKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGBpbnN0YW5jZW9mYCBvcGVyYXRvci5cbiAgICAgKiBAcmV0dXJucyB7c3ltYm9sfVxuICAgICAqIEBzaW5jZSAzLjI3LjBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFtpbnN0YW5jZVN5bWJvbF0oKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2wuZm9yKFwiQHNjaHVrYWkvbW9uc3Rlci9pMThuL2Zvcm1hdHRlckBAaW5zdGFuY2VcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHByb3BlcnR5IHtvYmplY3R9IG1hcmtlclxuICAgICAqIEBwcm9wZXJ0eSB7YXJyYXl9IG1hcmtlci5vcGVuPVtcImkxOG57XCIsXCIke1wiXVxuICAgICAqIEBwcm9wZXJ0eSB7YXJyYXl9IG1hcmtlci5jbG9zZT1bXCIke1wiXVxuICAgICAqIEBwcm9wZXJ0eSB7b2JqZWN0fSBwYXJhbWV0ZXJcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gcGFyYW1ldGVyLmRlbGltaXRlcj1cIjo6XCJcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gcGFyYW1ldGVyLmFzc2lnbm1lbnQ9XCI9XCJcbiAgICAgKiBAcHJvcGVydHkge29iamVjdH0gY2FsbGJhY2tzXG4gICAgICogQHByb3BlcnR5IHtmdW5jdGlvbn0gY2FsbGJhY2tzLmkxOG49KCk9Pnt9XG4gICAgICovXG4gICAgZ2V0IGRlZmF1bHRzKCkge1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICAgICAgcmV0dXJuIGV4dGVuZCh7fSwgc3VwZXIuZGVmYXVsdHMsIHtcbiAgICAgICAgICAgIGNhbGxiYWNrczoge1xuICAgICAgICAgICAgICAgIGkxOG46ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2VsZltpbnRlcm5hbFRyYW5zbGF0aW9uU3ltYm9sXS5nZXRUZXh0KHZhbGlkYXRlU3RyaW5nKHZhbHVlKSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBtYXJrZXI6IHtcbiAgICAgICAgICAgICAgICBvcGVuOiBbXCJpMThue1wiLCBcIiR7XCJdLFxuICAgICAgICAgICAgICAgIGNsb3NlOiBbXCJ9XCJdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdGV4dFxuICAgICAqIEByZXR1cm4ge3N0cmluZ31cbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHZhbHVlIGlzIG5vdCBhIHN0cmluZ1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSB0b28gZGVlcCBuZXN0aW5nXG4gICAgICogQHRocm93cyB7RXJyb3J9IGtleSBub3QgZm91bmRcbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gdGhlIGNsb3NpbmcgbWFya2VyIGlzIG1pc3NpbmdcbiAgICAgKi9cbiAgICBmb3JtYXQodGV4dCkge1xuICAgICAgICB2YWxpZGF0ZVN0cmluZyh0ZXh0KTtcblxuICAgICAgICBjb25zdCBvcGVuTWFya2VyID0gdGhpc1tpbnRlcm5hbFN5bWJvbF1bXCJtYXJrZXJcIl1bXCJvcGVuXCJdPy5bMF07XG4gICAgICAgIGNvbnN0IGNsb3NlTWFya2VyID0gdGhpc1tpbnRlcm5hbFN5bWJvbF1bXCJtYXJrZXJcIl1bXCJjbG9zZVwiXT8uWzBdO1xuXG4gICAgICAgIGlmICh0ZXh0LmluZGV4T2Yob3Blbk1hcmtlcikgPT09IDApIHtcbiAgICAgICAgICAgIHRleHQgPSB0ZXh0LnN1YnN0cmluZyhvcGVuTWFya2VyLmxlbmd0aCk7XG5cbiAgICAgICAgICAgIGlmICh0ZXh0LmluZGV4T2YoY2xvc2VNYXJrZXIpID09PSB0ZXh0Lmxlbmd0aCAtIGNsb3NlTWFya2VyLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHRleHQgPSB0ZXh0LnN1YnN0cmluZygwLCB0ZXh0Lmxlbmd0aCAtIGNsb3NlTWFya2VyLmxlbmd0aCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInRoZSBjbG9zaW5nIG1hcmtlciBpcyBtaXNzaW5nXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcGFydHMgPSB2YWxpZGF0ZVN0cmluZyh0ZXh0KS5zcGxpdChcIjo6XCIpO1xuICAgICAgICBjb25zdCB0cmFuc2xhdGlvbktleSA9IHBhcnRzLnNoaWZ0KCkudHJpbSgpOyAvLyBrZXkgdmFsdWUgZGVsaW1pdGVyXG4gICAgICAgIGNvbnN0IHBhcmFtZXRlciA9IHBhcnRzLmpvaW4oXCI6OlwiKS50cmltKCk7XG5cbiAgICAgICAgbGV0IGFzc2VtYmxlZFRleHQgPSBgJHtvcGVuTWFya2VyfXN0YXRpYzoke3RyYW5zbGF0aW9uS2V5fSB8IGNhbGw6aTE4bmA7XG4gICAgICAgIGlmIChwYXJhbWV0ZXIubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgYXNzZW1ibGVkVGV4dCArPSBgOjoke3BhcmFtZXRlcn1gO1xuICAgICAgICB9XG4gICAgICAgIGFzc2VtYmxlZFRleHQgKz0gY2xvc2VNYXJrZXI7XG4gICAgICAgIHJldHVybiBzdXBlci5mb3JtYXQoYXNzZW1ibGVkVGV4dCk7XG4gICAgfVxufVxuIiwgImltcG9ydCB7ZXhwZWN0fSBmcm9tIFwiY2hhaVwiXG5pbXBvcnQge0Zvcm1hdHRlcn0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS9pMThuL2Zvcm1hdHRlci5tanNcIjtcbmltcG9ydCB7VHJhbnNsYXRpb25zfSBmcm9tIFwiLi4vLi4vLi4vc291cmNlL2kxOG4vdHJhbnNsYXRpb25zLm1qc1wiO1xuXG5cbmRlc2NyaWJlKCdGb3JtYXR0ZXInLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBkZXNjcmliZSgnZXhhbXBsZScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBpdCgnc2hvdWxkIHJ1biB3aXRoIG1hcmtlcicsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgY29uc3QgdHJhbnNsYXRpb25zID0gbmV3IFRyYW5zbGF0aW9ucygnZW4nKVxuICAgICAgICAgICAgICAgIC5hc3NpZ25UcmFuc2xhdGlvbnMoe1xuICAgICAgICAgICAgICAgICAgICB0aGVrZXk6IFwiJHthbmltYWx9IGhhcyBlYXRlbiB0aGUgJHtmb29kfSFcIlxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBjb25zdCBmID0gbmV3IEZvcm1hdHRlcih7fSwgdHJhbnNsYXRpb25zKTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgZXhwZWN0KGYuZm9ybWF0KFwiaTE4bnt0aGVrZXk6OmFuaW1hbD1kb2c6OmZvb2Q9Y2FrZX1cIikpLnRvLmJlLmVxdWFsKCdkb2cgaGFzIGVhdGVuIHRoZSBjYWtlIScpO1xuICAgICAgICAgICAgLy8gXHUyMUE2IGRvZyBoYXMgZWF0ZW4gdGhlIGNha2UhICAgICAgICAgICAgICAgIFxuXG4gICAgICAgIH0pO1xuICAgICAgICBcbiAgICAgICAgaXQoJ3Nob3VsZCBydW4gd2l0aG91dCBtYXJrZXInLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIGNvbnN0IHRyYW5zbGF0aW9ucyA9IG5ldyBUcmFuc2xhdGlvbnMoJ2VuJylcbiAgICAgICAgICAgICAgICAuYXNzaWduVHJhbnNsYXRpb25zKHtcbiAgICAgICAgICAgICAgICAgICAgdGhla2V5OiBcIiR7YW5pbWFsfSBoYXMgZWF0ZW4gdGhlICR7Zm9vZH0hXCJcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8gbWlzc2luZyBtYXJrZXJcbiAgICAgICAgICAgIGV4cGVjdChuZXcgRm9ybWF0dGVyKHt9LCB0cmFuc2xhdGlvbnMpLmZvcm1hdChcInRoZWtleTo6YW5pbWFsPWRvZzo6Zm9vZD1jYWtlXCIpKS50by5iZS5lcXVhbCgnZG9nIGhhcyBlYXRlbiB0aGUgY2FrZSEnKTtcbiAgICAgICAgICAgIC8vIFx1MjFBNiBkb2cgaGFzIGVhdGVuIHRoZSBjYWtlISAgICAgICAgICAgICAgICBcblxuICAgICAgICB9KTtcbiAgICB9KTtcblxuXG4gICAgZGVzY3JpYmUoJ2Zvcm1hdCcsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBbXG4gICAgICAgICAgICBbJ2kxOG57dHJhbnNsYXRpb25rZXk6OmE9Mzo6Yj01fScsICd0ZXN0IGlzIDMgYW5kIDUnXSxcblxuICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEpIHtcblxuICAgICAgICAgICAgbGV0IGEgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBiID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGl0KCdmb3JtYXQgJyArIGEgKyAnIHNob3VsZCAnICsgYiwgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICAgICAgY29uc3QgdHJhbnNsYXRpb25zID0gbmV3IFRyYW5zbGF0aW9ucygnZGUnKS5hc3NpZ25UcmFuc2xhdGlvbnMoe1xuICAgICAgICAgICAgICAgICAgICB0cmFuc2xhdGlvbmtleTogXCJ0ZXN0IGlzICR7YX0gYW5kICR7Yn1cIlxuICAgICAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgICAgICBleHBlY3QoXG4gICAgICAgICAgICAgICAgICAgIG5ldyBGb3JtYXR0ZXIoe30sIHRyYW5zbGF0aW9ucykuZm9ybWF0KGEpXG4gICAgICAgICAgICAgICAgKS50by5lcXVhbChiKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG5cbiAgICB9KVxuXG5cbn0pXG47IiwgIlxuXG5pbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuaW1wb3J0IHtwYXJzZUxvY2FsZSwgTG9jYWxlfSBmcm9tIFwiLi4vLi4vLi4vc291cmNlL2kxOG4vbG9jYWxlLm1qc1wiO1xuXG5cbmRlc2NyaWJlKCdMb2NhbGUnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICBkZXNjcmliZSgnbmV3IGluc3RhbmNlJywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIFtcbiAgICAgICAgICAgIC8vIGxhbmd1YWdlLCByZWdpb24sIHNjcmlwdCwgdmFyaWFudHMsIGV4dGxhbmcsIHByaXZhdGVVc2VcbiAgICAgICAgICAgIC8vIGh0dHBzOi8vd3d3LnJmYy1lZGl0b3Iub3JnL3JmYy9yZmM1NjQ2Lmh0bWxcbiAgICAgICAgICAgIFsnemgnLCB1bmRlZmluZWQsICdIYW50JywgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgJ3poLUhhbnQnXSwgLy8gemgtSGFudCAoQ2hpbmVzZSB3cml0dGVuIHVzaW5nIHRoZSBUcmFkaXRpb25hbCBDaGluZXNlIHNjcmlwdClcbiAgICAgICAgICAgIFsnZGUnLCAnQ0gnLCB1bmRlZmluZWQsICcxOTAxJywgdW5kZWZpbmVkLCB1bmRlZmluZWQsICdkZS1DSC0xOTAxJ10sICAvLyBkZS1DSC0xOTAxIChHZXJtYW4gYXMgdXNlZCBpbiBTd2l0emVybGFuZCB1c2luZyB0aGUgMTkwMSB2YXJpYW50IFtvcnRob2dyYXBoeV0pXG4gICAgICAgICAgICBbJ3NsJywgJ0lUJywgdW5kZWZpbmVkLCAnbmVkaXMnLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgJ3NsLUlULW5lZGlzJ10sICAvLyBzbC1JVC1uZWRpcyAoU2xvdmVuaWFuIGFzIHVzZWQgaW4gSXRhbHksIE5hZGl6YSBkaWFsZWN0KVxuICAgICAgICAgICAgWydoeScsICdJVCcsICdMYXRuJywgJ2FyZXZlbGEnLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgJ2h5LUxhdG4tSVQtYXJldmVsYSddLCAvLyBoeS1MYXRuLUlULWFyZXZlbGEgKEVhc3Rlcm4gQXJtZW5pYW4gd3JpdHRlbiBpbiBMYXRpbiBzY3JpcHQsIGFzIHVzZWQgaW4gSXRhbHkpXG4gICAgICAgICAgICBbJ3poJywgJ0NOJywgJ0hhbnMnLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCAnemgtSGFucy1DTiddLCAvLyB6aC1IYW5zLUNOIChDaGluZXNlIHdyaXR0ZW4gdXNpbmcgdGhlIFNpbXBsaWZpZWQgc2NyaXB0IGFzIHVzZWQgaW4gIG1haW5sYW5kIENoaW5hKVxuICAgICAgICAgICAgWydzcicsICdSUycsICdMYXRuJywgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgJ3NyLUxhdG4tUlMnXSwgLy8gc3ItTGF0bi1SUyAoU2VyYmlhbiB3cml0dGVuIHVzaW5nIHRoZSBMYXRpbiBzY3JpcHQgYXMgdXNlZCBpbiBTZXJiaWEpXG5cbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGMgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBkID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgZSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGYgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBnID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGl0KCduZXcgTG9jYWxlKCcgKyBhICsgJywnICsgYiArICcsJyArIGMgKyAnLCcgKyBkICsgJywnICsgZSArICcsJyArIGYgKyAnKSBzaG91bGQgcmV0dXJuICcgKyBnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgICAgICBleHBlY3QobmV3IExvY2FsZShhLCBiLCBjLCBkLCBlLCBmKS50b1N0cmluZygpKS5pcy5lcXVhbChnKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgncGFyc2VMb2NhbGUoKScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBbXG5cbiAgICAgICAgICAgIC8vIGxhbmd1YWdlLCByZWdpb24sIHNjcmlwdCwgdmFyaWFudHMsIGV4dGxhbmcsIHByaXZhdGVVc2VcbiAgICAgICAgICAgIC8vIGh0dHBzOi8vd3d3LnJmYy1lZGl0b3Iub3JnL3JmYy9yZmM1NjQ2Lmh0bWxcbiAgICAgICAgICAgIFsnemgnLCB1bmRlZmluZWQsICdIYW50JywgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgJ3poLUhhbnQnXSwgLy8gemgtSGFudCAoQ2hpbmVzZSB3cml0dGVuIHVzaW5nIHRoZSBUcmFkaXRpb25hbCBDaGluZXNlIHNjcmlwdClcbiAgICAgICAgICAgIFsnZGUnLCAnQ0gnLCB1bmRlZmluZWQsICcxOTAxJywgdW5kZWZpbmVkLCB1bmRlZmluZWQsICdkZS1DSC0xOTAxJ10sICAvLyBkZS1DSC0xOTAxIChHZXJtYW4gYXMgdXNlZCBpbiBTd2l0emVybGFuZCB1c2luZyB0aGUgMTkwMSB2YXJpYW50IFtvcnRob2dyYXBoeV0pXG4gICAgICAgICAgICBbJ3NsJywgJ0lUJywgdW5kZWZpbmVkLCAnbmVkaXMnLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgJ3NsLUlULW5lZGlzJ10sICAvLyBzbC1JVC1uZWRpcyAoU2xvdmVuaWFuIGFzIHVzZWQgaW4gSXRhbHksIE5hZGl6YSBkaWFsZWN0KVxuICAgICAgICAgICAgWydoeScsICdJVCcsICdMYXRuJywgJ2FyZXZlbGEnLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgJ2h5LUxhdG4tSVQtYXJldmVsYSddLCAvLyBoeS1MYXRuLUlULWFyZXZlbGEgKEVhc3Rlcm4gQXJtZW5pYW4gd3JpdHRlbiBpbiBMYXRpbiBzY3JpcHQsIGFzIHVzZWQgaW4gSXRhbHkpXG4gICAgICAgICAgICBbJ3poJywgJ0NOJywgJ0hhbnMnLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCAnemgtSGFucy1DTiddLCAvLyB6aC1IYW5zLUNOIChDaGluZXNlIHdyaXR0ZW4gdXNpbmcgdGhlIFNpbXBsaWZpZWQgc2NyaXB0IGFzIHVzZWQgaW4gIG1haW5sYW5kIENoaW5hKVxuICAgICAgICAgICAgWydzcicsICdSUycsICdMYXRuJywgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgJ3NyLUxhdG4tUlMnXSwgLy8gc3ItTGF0bi1SUyAoU2VyYmlhbiB3cml0dGVuIHVzaW5nIHRoZSBMYXRpbiBzY3JpcHQgYXMgdXNlZCBpbiBTZXJiaWEpXG5cbiAgICAgICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgIGxldCBhID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgYiA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGMgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBkID0gZGF0YS5zaGlmdCgpXG4gICAgICAgICAgICBsZXQgZSA9IGRhdGEuc2hpZnQoKVxuICAgICAgICAgICAgbGV0IGYgPSBkYXRhLnNoaWZ0KClcbiAgICAgICAgICAgIGxldCBnID0gZGF0YS5zaGlmdCgpXG5cbiAgICAgICAgICAgIGl0KCduZXcgTG9jYWxlKCcgKyBhICsgJywnICsgYiArICcsJyArIGMgKyAnLCcgKyBkICsgJywnICsgZSArICcsJyArIGYgKyAnKSBzaG91bGQgcmV0dXJuICcgKyBnLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBsb2NhbGUgPSBwYXJzZUxvY2FsZShnKVxuICAgICAgICAgICAgICAgIGV4cGVjdChsb2NhbGUubG9jYWxlU3RyaW5nKS50by5iZS5lcXVhbChnKTtcbiAgICAgICAgICAgICAgICBleHBlY3QobG9jYWxlLmxhbmd1YWdlKS50by5iZS5lcXVhbChhKTtcbiAgICAgICAgICAgICAgICBleHBlY3QobG9jYWxlLnJlZ2lvbikudG8uYmUuZXF1YWwoYik7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGxvY2FsZS5zY3JpcHQpLnRvLmJlLmVxdWFsKGMpO1xuICAgICAgICAgICAgICAgIGV4cGVjdChsb2NhbGUudmFyaWFudHMpLnRvLmJlLmVxdWFsKGQpO1xuICAgICAgICAgICAgICAgIGV4cGVjdChsb2NhbGUuZXh0bGFuZykudG8uYmUuZXF1YWwoZSk7XG4gICAgICAgICAgICAgICAgZXhwZWN0KGxvY2FsZS5wcml2YXRlVXNlKS50by5iZS5lcXVhbChmKTtcblxuICAgICAgICAgICAgICAgIGV4cGVjdChuZXcgTG9jYWxlKGEsIGIsIGMsIGQsIGUsIGYpLnRvU3RyaW5nKCkpLmlzLmVxdWFsKGcpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICB9KTtcblxuXG59KTsiLCAiaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcbmltcG9ydCB7QVRUUklCVVRFX09CSkVDVExJTkt9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvZG9tL2NvbnN0YW50cy5tanNcIjtcbmltcG9ydCB7Z2V0TGlua2VkT2JqZWN0c30gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS9kb20vYXR0cmlidXRlcy5tanNcIjtcbmltcG9ydCB7UHJvdmlkZXJ9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvaTE4bi9wcm92aWRlci5tanNcIjtcbmltcG9ydCB7aW5pdEpTRE9NfSBmcm9tIFwiLi4vLi4vdXRpbC9qc2RvbS5tanNcIjtcbmltcG9ydCB7Z2V0RG9jdW1lbnRUcmFuc2xhdGlvbnMsIFRyYW5zbGF0aW9uc30gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS9pMThuL3RyYW5zbGF0aW9ucy5tanNcIjtcblxuZGVzY3JpYmUoJ1Byb3ZpZGVyJywgZnVuY3Rpb24gKCkge1xuXG5cbiAgICBsZXQgaHRtbDEgPSBgXG4gICAgPGRpdiBpZD1cInRlc3QxXCI+XG4gICAgPC9kaXY+XG5gO1xuXG4gICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICAgIGxldCBtb2NrcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpO1xuICAgICAgICBtb2Nrcy5pbm5lckhUTUwgPSBodG1sMTtcblxuXG4gICAgfSlcblxuICAgIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICAgIGxldCBtb2NrcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2NrcycpO1xuICAgICAgICBtb2Nrcy5pbm5lckhUTUwgPSBcIlwiO1xuICAgIH0pXG5cbiAgICBiZWZvcmUoZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgaW5pdEpTRE9NKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICBkb25lKClcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnUHJvdmlkZXIgYW5kIERvbScsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBjb25zdCB0cmFuc2xhdGlvbnNMaW5rU3ltYm9sID0gU3ltYm9sLmZvcihcIkBzY2h1a2FpL21vbnN0ZXIvaTE4bi90cmFuc2xhdGlvbnNAQGxpbmtcIik7XG5cbiAgICAgICAgaXQoJ2Fzc2lnblRvRWxlbWVudCcsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICBjb25zdCBlbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Rlc3QxJyk7XG4gICAgICAgICAgICBjb25zdCBwID0gbmV3IFByb3ZpZGVyKCk7XG4gICAgICAgICAgICBjb25zdCByID0gcC5hc3NpZ25Ub0VsZW1lbnQodW5kZWZpbmVkLCBlbGVtZW50KTtcblxuICAgICAgICAgICAgci50aGVuKChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcyA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKEFUVFJJQlVURV9PQkpFQ1RMSU5LKTtcbiAgICAgICAgICAgICAgICBpZiAocyA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBkb25lKG5ldyBFcnJvcihcIkF0dHJpYnV0ZSBub3Qgc2V0XCIpKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IGkgPSBnZXRMaW5rZWRPYmplY3RzKGVsZW1lbnQsIHRyYW5zbGF0aW9uc0xpbmtTeW1ib2wpXG4gICAgICAgICAgICAgICAgaWYgKGkgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgZG9uZShuZXcgRXJyb3IoXCJObyBsaW5rZWQgb2JqZWN0IGZvdW5kXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsZXQgY291bnRlciA9IDA7XG5cbiAgICAgICAgICAgICAgICBmb3IgKGxldCB2IG9mIGkpIHtcbiAgICAgICAgICAgICAgICAgICAgY291bnRlcisrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChjb3VudGVyICE9PSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGRvbmUobmV3IEVycm9yKFwiTm8gbGlua2VkIG9iamVjdCBmb3VuZFwiKSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCBkb2NUcmFucyA9IGdldERvY3VtZW50VHJhbnNsYXRpb25zKGVsZW1lbnQpXG4gICAgICAgICAgICAgICAgZXhwZWN0KGRvY1RyYW5zKS5pcy5pbnN0YW5jZW9mKFRyYW5zbGF0aW9ucyk7XG5cblxuICAgICAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICAgIH0pLmNhdGNoKGUgPT4gZG9uZShlKSk7XG5cbiAgICAgICAgfSk7XG5cbiAgICB9KTtcblxuXG59KTsiLCAiLyoqXG4gKiBDb3B5cmlnaHQgc2NodWthaSBHbWJIIGFuZCBjb250cmlidXRvcnMgMjAyMy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIE5vZGUgbW9kdWxlOiBAc2NodWthaS9tb25zdGVyXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFHUEx2MyBMaWNlbnNlLlxuICogTGljZW5zZSB0ZXh0IGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwtMy4wLmVuLmh0bWxcbiAqL1xuXG5pbXBvcnQgeyBpbnRlcm5hbFN5bWJvbCB9IGZyb20gXCIuLi8uLi9jb25zdGFudHMubWpzXCI7XG5pbXBvcnQgeyBleHRlbmQgfSBmcm9tIFwiLi4vLi4vZGF0YS9leHRlbmQubWpzXCI7XG5pbXBvcnQgeyBGb3JtYXR0ZXIgfSBmcm9tIFwiLi4vLi4vdGV4dC9mb3JtYXR0ZXIubWpzXCI7XG5pbXBvcnQgeyBnZXRHbG9iYWxGdW5jdGlvbiB9IGZyb20gXCIuLi8uLi90eXBlcy9nbG9iYWwubWpzXCI7XG5pbXBvcnQgeyBpc0luc3RhbmNlLCBpc1N0cmluZyB9IGZyb20gXCIuLi8uLi90eXBlcy9pcy5tanNcIjtcbmltcG9ydCB7IHZhbGlkYXRlT2JqZWN0LCB2YWxpZGF0ZVN0cmluZyB9IGZyb20gXCIuLi8uLi90eXBlcy92YWxpZGF0ZS5tanNcIjtcbmltcG9ydCB7IHBhcnNlTG9jYWxlIH0gZnJvbSBcIi4uL2xvY2FsZS5tanNcIjtcbmltcG9ydCB7IFByb3ZpZGVyIH0gZnJvbSBcIi4uL3Byb3ZpZGVyLm1qc1wiO1xuaW1wb3J0IHsgVHJhbnNsYXRpb25zIH0gZnJvbSBcIi4uL3RyYW5zbGF0aW9ucy5tanNcIjtcblxuZXhwb3J0IHsgRmV0Y2ggfTtcblxuLyoqXG4gKiBUaGUgZmV0Y2ggcHJvdmlkZXIgcmV0cmlldmVzIGEgSlNPTiBmaWxlIGZyb20gdGhlIGdpdmVuIFVSTCBhbmQgcmV0dXJucyBhIHRyYW5zbGF0aW9uIG9iamVjdC5cbiAqXG4gKiBAZXh0ZXJuYWxFeGFtcGxlIC4uLy4uLy4uL2V4YW1wbGUvaTE4bi9wcm92aWRlcnMvZmV0Y2gubWpzXG4gKiBAbGljZW5zZSBBR1BMdjNcbiAqIEBzaW5jZSAxLjEzLjBcbiAqIEBjb3B5cmlnaHQgc2NodWthaSBHbWJIXG4gKiBAbWVtYmVyT2YgTW9uc3Rlci5JMThuLlByb3ZpZGVyc1xuICogQHNlZSB7QGxpbmsgaHR0cHM6Ly9kYXRhdHJhY2tlci5pZXRmLm9yZy9kb2MvaHRtbC9yZmMzMDY2fVxuICogQHR1dG9yaWFsIGkxOG4tbG9jYWxlLWFuZC1mb3JtYXR0ZXJcbiAqL1xuY2xhc3MgRmV0Y2ggZXh0ZW5kcyBQcm92aWRlciB7XG4gICAgLyoqXG4gICAgICogQXMgb3B0aW9ucyB0aGUga2V5IGBmZXRjaGAgY2FuIGJlIHBhc3NlZC4gVGhpcyBjb25maWcgb2JqZWN0IGlzIHBhc3NlZCB0byB0aGUgZmV0Y2ggbWV0aG9kIGFzIGluaXQuXG4gICAgICpcbiAgICAgKiBUaGUgdXJsIG1heSBjb250YWluIHBsYWNlaG9sZGVycyAobGFuZ3VhZ2UsIHNjcmlwdCwgcmVnaW9uLCB2YXJpYW50cywgZXh0bGFuZywgcHJpdmF0ZVVzZSksIHNvIHlvdSBjYW4gc3BlY2lmeSBvbmUgdXJsIGZvciBhbGwgdHJhbnNsYXRpb25zLlxuICAgICAqXG4gICAgICogYGBgXG4gICAgICogbmV3IEZldGNoKCdodHRwczovL3d3dy5leGFtcGxlLmNvbS9hc3NldHMvJHtsYW5ndWFnZX0uanNvbicpXG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xVUkx9IHVybFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIHNlZSB7QGxpbmsgTW9uc3Rlci5JMThuLlByb3ZpZGVycy5GZXRjaCNkZWZhdWx0c31cbiAgICAgKiBAc2VlIHtAbGluayBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvZmV0Y2h9XG4gICAgICovXG4gICAgY29uc3RydWN0b3IodXJsLCBvcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnMpO1xuXG4gICAgICAgIGlmIChpc0luc3RhbmNlKHVybCwgVVJMKSkge1xuICAgICAgICAgICAgdXJsID0gdXJsLnRvU3RyaW5nKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAob3B0aW9ucyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBvcHRpb25zID0ge307XG4gICAgICAgIH1cblxuICAgICAgICB2YWxpZGF0ZVN0cmluZyh1cmwpO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAcHJvcGVydHkge3N0cmluZ31cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMudXJsID0gdXJsO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAcHJpdmF0ZVxuICAgICAgICAgKiBAcHJvcGVydHkge09iamVjdH0gb3B0aW9uc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpc1tpbnRlcm5hbFN5bWJvbF0gPSBleHRlbmQoe30sIHN1cGVyLmRlZmF1bHRzLCB0aGlzLmRlZmF1bHRzLCB2YWxpZGF0ZU9iamVjdChvcHRpb25zKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGVmYXVsdHNcbiAgICAgKlxuICAgICAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBmZXRjaFxuICAgICAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBmZXRjaC5tZXRob2Q9R0VUXG4gICAgICogQHByb3BlcnR5IHtTdHJpbmd9IGZldGNoLm1vZGU9Y29yc1xuICAgICAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBmZXRjaC5jYWNoZT1uby1jYWNoZVxuICAgICAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBmZXRjaC5jcmVkZW50aWFscz1vbWl0XG4gICAgICogQHByb3BlcnR5IHtTdHJpbmd9IGZldGNoLnJlZGlyZWN0PWZvbGxvd1xuICAgICAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBmZXRjaC5yZWZlcnJlclBvbGljeT1uby1yZWZlcnJlclxuICAgICAqXG4gICAgICogQHNlZSB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0ZldGNoX0FQSX1cbiAgICAgKi9cbiAgICBnZXQgZGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBleHRlbmQoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZmV0Y2g6IHtcbiAgICAgICAgICAgICAgICAgICAgbWV0aG9kOiBcIkdFVFwiLCAvLyAqR0VULCBQT1NULCBQVVQsIERFTEVURSwgZXRjLlxuICAgICAgICAgICAgICAgICAgICBtb2RlOiBcImNvcnNcIiwgLy8gbm8tY29ycywgKmNvcnMsIHNhbWUtb3JpZ2luXG4gICAgICAgICAgICAgICAgICAgIGNhY2hlOiBcIm5vLWNhY2hlXCIsIC8vICpkZWZhdWx0LCBuby1jYWNoZSwgcmVsb2FkLCBmb3JjZS1jYWNoZSwgb25seS1pZi1jYWNoZWRcbiAgICAgICAgICAgICAgICAgICAgY3JlZGVudGlhbHM6IFwib21pdFwiLCAvLyBpbmNsdWRlLCAqc2FtZS1vcmlnaW4sIG9taXRcbiAgICAgICAgICAgICAgICAgICAgcmVkaXJlY3Q6IFwiZm9sbG93XCIsIC8vIG1hbnVhbCwgKmZvbGxvdywgZXJyb3JcbiAgICAgICAgICAgICAgICAgICAgcmVmZXJyZXJQb2xpY3k6IFwibm8tcmVmZXJyZXJcIiwgLy8gbm8tcmVmZXJyZXIsICpuby1yZWZlcnJlci13aGVuLWRvd25ncmFkZSwgb3JpZ2luLCBvcmlnaW4td2hlbi1jcm9zcy1vcmlnaW4sIHNhbWUtb3JpZ2luLCBzdHJpY3Qtb3JpZ2luLCBzdHJpY3Qtb3JpZ2luLXdoZW4tY3Jvc3Mtb3JpZ2luLCB1bnNhZmUtdXJsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzdXBlci5kZWZhdWx0cyxcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7TG9jYWxlfHN0cmluZ30gbG9jYWxlXG4gICAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICAgKi9cbiAgICBnZXRUcmFuc2xhdGlvbnMobG9jYWxlKSB7XG4gICAgICAgIGlmIChpc1N0cmluZyhsb2NhbGUpKSB7XG4gICAgICAgICAgICBsb2NhbGUgPSBwYXJzZUxvY2FsZShsb2NhbGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGZvcm1hdHRlciA9IG5ldyBGb3JtYXR0ZXIobG9jYWxlLmdldE1hcCgpKTtcblxuICAgICAgICByZXR1cm4gZ2V0R2xvYmFsRnVuY3Rpb24oXCJmZXRjaFwiKShmb3JtYXR0ZXIuZm9ybWF0KHRoaXMudXJsKSwgdGhpcy5nZXRPcHRpb24oXCJmZXRjaFwiLCB7fSkpXG4gICAgICAgICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmpzb24oKSlcbiAgICAgICAgICAgIC50aGVuKChkYXRhKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBUcmFuc2xhdGlvbnMobG9jYWxlKS5hc3NpZ25UcmFuc2xhdGlvbnMoZGF0YSk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcblxuXG5pbXBvcnQge0ZldGNofSBmcm9tIFwiLi4vLi4vLi4vLi4vc291cmNlL2kxOG4vcHJvdmlkZXJzL2ZldGNoLm1qc1wiO1xuaW1wb3J0IHtUcmFuc2xhdGlvbnN9IGZyb20gXCIuLi8uLi8uLi8uLi9zb3VyY2UvaTE4bi90cmFuc2xhdGlvbnMubWpzXCI7XG5pbXBvcnQge2dldEdsb2JhbH0gZnJvbSBcIi4uLy4uLy4uLy4uL3NvdXJjZS90eXBlcy9nbG9iYWwubWpzXCI7XG5cblxuY29uc3QgZ2xvYmFsID0gZ2V0R2xvYmFsKCk7XG5sZXQgZmV0Y2hSZWZlcmVuY2U7XG5cblxuZGVzY3JpYmUoJ1RyYW5zbGF0aW9uIFByb3ZpZGVyIEZldGNoJywgZnVuY3Rpb24gKCkge1xuXG5cbiAgICBhZnRlckVhY2goKCkgPT4ge1xuICAgICAgICBnbG9iYWxbJ2ZldGNoJ10gPSBmZXRjaFJlZmVyZW5jZTtcbiAgICB9KTtcblxuICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuXG4gICAgICAgIGZldGNoUmVmZXJlbmNlID0gZ2xvYmFsWydmZXRjaCddO1xuICAgICAgICBnbG9iYWxbJ2ZldGNoJ10gPSBmdW5jdGlvbiAodXJsLCBvcHRpb25zKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgICAgIHJlc29sdmUoe1xuICAgICAgICAgICAgICAgICAgICBqc29uOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGE6IFwidGVzdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgfTtcblxuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnZmV0Y2ggbW9jayBkYXRhIGFuZCBjcmVhdGUgdHJhbnNsYXRpb24nLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaXQoJ2ZldGNoJywgZnVuY3Rpb24gKGRvbmUpIHtcblxuICAgICAgICAgICAgbGV0IHAgPSAobmV3IEZldGNoKG5ldyBVUkwoJ2h0dHA6Ly9leGFtcGxlLmNvbScpKSkuZ2V0VHJhbnNsYXRpb25zKCdlbicpO1xuXG4gICAgICAgICAgICBleHBlY3QocCkuaXMuaW5zdGFuY2VvZihQcm9taXNlKTtcblxuICAgICAgICAgICAgcC50aGVuKHIgPT4ge1xuXG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KHIpLmlzLmluc3RhbmNlb2YoVHJhbnNsYXRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgZG9uZShlKTtcbiAgICAgICAgICAgICAgICB9XG5cblxuICAgICAgICAgICAgfSkuY2F0Y2goZSA9PiB7XG4gICAgICAgICAgICAgICAgZG9uZShlKTtcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgfSk7XG5cbiAgICB9KTtcblxuXG59KTsiLCAiaW1wb3J0IHtleHBlY3R9IGZyb20gXCJjaGFpXCJcblxuXG5pbXBvcnQge0VtYmVkfSBmcm9tIFwiLi4vLi4vLi4vLi4vc291cmNlL2kxOG4vcHJvdmlkZXJzL2VtYmVkLm1qc1wiO1xuaW1wb3J0IHtUcmFuc2xhdGlvbnN9IGZyb20gXCIuLi8uLi8uLi8uLi9zb3VyY2UvaTE4bi90cmFuc2xhdGlvbnMubWpzXCI7XG5pbXBvcnQge2dldEdsb2JhbH0gZnJvbSBcIi4uLy4uLy4uLy4uL3NvdXJjZS90eXBlcy9nbG9iYWwubWpzXCI7XG5pbXBvcnQge2luaXRKU0RPTX0gZnJvbSBcIi4uLy4uLy4uL3V0aWwvanNkb20ubWpzXCI7XG5cblxuY29uc3QgZ2xvYmFsID0gZ2V0R2xvYmFsKCk7XG5cbmNvbnN0IGh0bWwxID0gYFxuPHNjcmlwdCBpZD1cInRlbXBsb2NhbGVcIiB0eXBlPVwiYXBwbGljYXRpb24vanNvblwiPlxue1xuICAgICAgICBcImtleVwiOiBcInRyYW5zbGF0aW9uXCJcbn1cbjwvc2NyaXB0PlxuYDtcblxuZGVzY3JpYmUoJ1RyYW5zbGF0aW9uIFByb3ZpZGVyIEVtYmVkJywgZnVuY3Rpb24gKCkge1xuXG4gICAgYmVmb3JlKGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgIGluaXRKU0RPTSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgZG9uZSgpXG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG5cbiAgICBhZnRlckVhY2goKCkgPT4ge1xuICAgICAgICBsZXQgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gXCJcIjtcbiAgICB9KTtcblxuICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgICBsZXQgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgbW9ja3MuaW5uZXJIVE1MID0gaHRtbDE7XG5cbiAgICB9KVxuXG4gICAgZGVzY3JpYmUoJ2dldCBtb2NrIGRhdGEgYW5kIGNyZWF0ZSB0cmFuc2xhdGlvbicsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBpdCgnZW1iZWQnLCBmdW5jdGlvbiAoZG9uZSkge1xuXG4gICAgICAgICAgICBjb25zdCBlID0gbmV3IEVtYmVkKCd0ZW1wbG9jYWxlJyk7XG4gICAgICAgICAgICBsZXQgcCA9IGUuZ2V0VHJhbnNsYXRpb25zKCdlbicpO1xuICAgICAgICAgICAgZXhwZWN0KHApLmlzLmluc3RhbmNlb2YoUHJvbWlzZSk7XG5cbiAgICAgICAgICAgIHAudGhlbihyID0+IHtcblxuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdChyKS5pcy5pbnN0YW5jZW9mKFRyYW5zbGF0aW9ucyk7XG4gXG4gICAgICAgICAgICAgICAgICAgIGxldCB0ID0gci5nZXRUZXh0KCdrZXknKVxuICAgICAgICAgICAgICAgICAgICBleHBlY3QodCkuaXMuZXF1YWwoJ3RyYW5zbGF0aW9uJyk7XG5cblxuICAgICAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICBkb25lKGUpO1xuICAgICAgICAgICAgICAgIH1cblxuXG4gICAgICAgICAgICB9KS5jYXRjaChlID0+IHtcbiAgICAgICAgICAgICAgICBkb25lKGUpO1xuICAgICAgICAgICAgfSlcblxuICAgICAgICB9KTtcblxuICAgIH0pO1xuXG5cbn0pOyIsICJpbXBvcnQge2V4cGVjdH0gZnJvbSBcImNoYWlcIlxuaW1wb3J0IHtwYXJzZUxvY2FsZX0gZnJvbSBcIi4uLy4uLy4uL3NvdXJjZS9pMThuL2xvY2FsZS5tanNcIjtcbmltcG9ydCB7RW1iZWR9IGZyb20gXCIuLi8uLi8uLi9zb3VyY2UvaTE4bi9wcm92aWRlcnMvZW1iZWQubWpzXCI7XG5pbXBvcnQge1xuICAgIFRyYW5zbGF0aW9ucyxcbiAgICBnZXREb2N1bWVudFRyYW5zbGF0aW9uc1xuICAgIFxufSBmcm9tIFwiLi4vLi4vLi4vc291cmNlL2kxOG4vdHJhbnNsYXRpb25zLm1qc1wiO1xuaW1wb3J0IHtpbml0SlNET019IGZyb20gXCIuLi8uLi91dGlsL2pzZG9tLm1qc1wiO1xuXG5kZXNjcmliZSgnVHJhbnNsYXRpb25zJywgZnVuY3Rpb24gKCkge1xuXG4gICAgZGVzY3JpYmUoJ0luc3RhbmNlIGFuZCBJbml0JywgZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGxldCB0cmFuc2xhdGlvbjtcblxuICAgICAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAgICAgIHRyYW5zbGF0aW9uID0gbmV3IFRyYW5zbGF0aW9ucyhwYXJzZUxvY2FsZSgnZW4tR0InKSk7XG5cbiAgICAgICAgICAgIHRyYW5zbGF0aW9uLmFzc2lnblRyYW5zbGF0aW9ucyh7XG4gICAgICAgICAgICAgICAgdGVzdDE6IFwiYWJjXCIsXG4gICAgICAgICAgICAgICAgdGVzdDI6IHsnb3RoZXInOiAneHl6J31cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuXG4gICAgICAgIGl0KCdjcmVhdGUgaW5zdGFuY2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QobmV3IFRyYW5zbGF0aW9ucyhwYXJzZUxvY2FsZSgnZW4tR0InKSkpLmlzLmluc3RhbmNlb2YoVHJhbnNsYXRpb25zKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ2luaXQgdHJhbnNsYXRpb25zJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KHRyYW5zbGF0aW9uLmFzc2lnblRyYW5zbGF0aW9ucyh7XG4gICAgICAgICAgICAgICAgdGVzdDE6IFwiYWJjXCIsXG4gICAgICAgICAgICAgICAgdGVzdDI6IHsnb3RoZXInOiAneHl6J31cbiAgICAgICAgICAgIH0pKS5pcy5pbnN0YW5jZW9mKFRyYW5zbGF0aW9ucyk7XG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnZ2V0VGV4dCcsIGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBsZXQgdHJhbnNsYXRpb247XG5cbiAgICAgICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICAgICAgICB0cmFuc2xhdGlvbiA9IG5ldyBUcmFuc2xhdGlvbnMocGFyc2VMb2NhbGUoJ2VuLUdCJykpO1xuXG4gICAgICAgICAgICB0cmFuc2xhdGlvbi5hc3NpZ25UcmFuc2xhdGlvbnMoe1xuICAgICAgICAgICAgICAgIHRlc3QxOiBcImFiY1wiLFxuICAgICAgICAgICAgICAgIHRlc3QyOiB7J290aGVyJzogJ3h5eid9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSlcblxuICAgICAgICBpdCgnY3JlYXRlLCBzZXQgYW5kIGdldCBlbi1HQicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdCh0cmFuc2xhdGlvbi5nZXRUZXh0KCd0ZXN0MScpKS5pcy5lcXVhbCgnYWJjJyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdjcmVhdGUsIHNldCBhbmQgZ2V0ICBlbi1HQiB3aXRoIHBsdXJhbHJ1bGVzJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KHRyYW5zbGF0aW9uLmdldFRleHQoJ3Rlc3QyJykpLmlzLmVxdWFsKCd4eXonKVxuICAgICAgICB9KTtcblxuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogaW5pdERvY3VtZW50VHJhbnNsYXRpb25cbiAgICAgKi9cblxuICAgIGRlc2NyaWJlKFwidGVzdCBpbml0RG9jdW1lbnRUcmFuc2xhdGlvbiBcIiwgZnVuY3Rpb24gKCkge1xuXG5cbiAgICAgICAgbGV0IGh0bWwxID0gYDxkaXYgaWQ9XCJtb2NrLXRyYW5zbGF0aW9uc1wiPjwvZGl2PlxuICAgIFxuPHNjcmlwdCB0eXBlPVwiYXBwbGljYXRpb24vanNvblwiIGRhdGEtbW9uc3Rlci1yb2xlPVwidHJhbnNsYXRpb25zXCI+XG4gICAge1xuICAgICAgICBcInRlc3QxXCI6IFwiYWJjXCIsXG4gICAgICAgIFwidGVzdDJcIjoge1xuICAgICAgICAgICAgXCJvdGhlclwiOiBcInh5elwiXG4gICAgICAgIH1cbiAgICB9XG48L3NjcmlwdD5cblxuPHNjcmlwdCB0eXBlPVwiYXBwbGljYXRpb24vanNvblwiIGRhdGEtbW9uc3Rlci1yb2xlPVwidHJhbnNsYXRpb25zXCI+XG4gICAge1xuICAgICAgICBcInRlc3QxXCI6IFwieHl6XCIsXG4gICAgICAgIFwidGVzdDNcIjoge1xuICAgICAgICAgICAgXCJvdGhlclwiOiBcInh5elwiXG4gICAgICAgIH1cbiAgICB9XG48L3NjcmlwdD4gICAgXG4gICAgXG5gO1xuXG4gICAgICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgICAgICAgbGV0IG1vY2tzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vY2tzJyk7XG4gICAgICAgICAgICBtb2Nrcy5pbm5lckhUTUwgPSBodG1sMTtcblxuICAgICAgICB9KVxuXG4gICAgICAgIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICAgICAgICBsZXQgbW9ja3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9ja3MnKTtcbiAgICAgICAgICAgIG1vY2tzLmlubmVySFRNTCA9IFwiXCI7XG4gICAgICAgIH0pXG5cbiAgICAgICAgYmVmb3JlKGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgICAgICBpbml0SlNET00oKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICBkb25lKClcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuXG4gICAgICAgIGl0KCdJbml0IHRyYW5zbGF0aW9ucycsIGZ1bmN0aW9uIChkb25lKSB7XG5cbiAgICAgICAgICAgIGxldCBlbGVtID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vY2stdHJhbnNsYXRpb25zJyk7XG4gICAgICAgICAgICBFbWJlZC5hc3NpZ25UcmFuc2xhdGlvbnNUb0VsZW1lbnQoZWxlbSkudGhlbigobykgPT4ge1xuXG4gICAgICAgICAgICAgICAgbGV0IG1vY2tzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vY2tzJyk7XG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgLy8gbm8gZXhjZXB0aW9uIGJlY2F1c2Ugb2YgZGVmYXVsdFxuICAgICAgICAgICAgICAgIGV4cGVjdChnZXREb2N1bWVudFRyYW5zbGF0aW9ucyhlbGVtKS5nZXRUZXh0KCduby1rZXknLCd3aXRoLWRlZmF1bHQnKSlcbiAgICAgICAgICAgICAgICAgICAgLmlzLmVxdWFsKCd3aXRoLWRlZmF1bHQnKTtcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICBleHBlY3QoZ2V0RG9jdW1lbnRUcmFuc2xhdGlvbnMoZWxlbSkuZ2V0VGV4dCgndGVzdDEnKSlcbiAgICAgICAgICAgICAgICAgICAgLmlzLmVxdWFsKCd4eXonKTtcblxuICAgICAgICAgICAgICAgIGRvbmUoKTtcblxuICAgICAgICAgICAgfSkuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgICAgZG9uZShlKTtcbiAgICAgICAgICAgIH0pXG5cblxuICAgICAgICB9KTtcbiAgICB9KVxuXG5cbn0pOyJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFlQSxlQUFTLFVBQVc7QUFDbEIsWUFBSSxXQUFXLENBQUMsRUFBRSxNQUFNLEtBQUssU0FBUztBQUV0QyxpQkFBUyxhQUFjLEtBQUssS0FBSztBQUMvQixpQkFBTyxLQUFLLEdBQUcsRUFBRSxRQUFRLFNBQVUsS0FBSztBQUN0QyxnQkFBSSxDQUFDLENBQUMsU0FBUyxRQUFRLEdBQUc7QUFBRyxrQkFBSSxHQUFHLElBQUksSUFBSSxH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QTtBQUFBLE1BQ0o7QUFBQSxNQUNBO0FBQUEsUUFDSTtBQUFBLFVBQ0ksR0FBRztBQUFBLFFBQ1A7QUFBQSxRQUNBO0FBQUEsVUFDSSxHQUFHO0FBQUEsUUFDUDtBQUFBLFFBQ0E7QUFBQSxNQUNKO0FBQUEsTUFDQTtBQUFBLFFBQ0ksQ0FBQztBQUFBLFFBQ0Q7QUFBQSxVQUNJLEdBQUc7QUFBQSxRQUNQO0FBQUEsUUFDQTtBQUFBLE1BQ0o7QUFBQSxNQUVBO0FBQUEsUUFDSTtBQUFBLFVBQ0ksR0FBRztBQUFBLFFBQ1A7QUFBQSxRQUNBO0FBQUEsVUFDSSxHQUFHO0FBQUEsUUFDUDtBQUFBLFFBQ0E7QUFBQSxNQUNKO0FBQUEsTUFFQTtBQUFBLFFBQ0k7QUFBQSxVQUNJLEdBQUc7QUFBQSxRQUNQO0FBQUEsUUFDQTtBQUFBLFVBQ0ksR0FBRztBQUFBLFFBQ1A7QUFBQSxRQUNBO0FBQUEsTUFDSjtBQUFBLE1BRUE7QUFBQSxRQUNJO0FBQUEsVUFDSSxHQUFHO0FBQUEsUUFDUDtBQUFBLFFBQ0E7QUFBQSxVQUNJLEdBQUc7QUFBQSxRQUNQO0FBQUEsUUFDQTtBQUFBLE1BQ0o7QUFBQSxNQUVBO0FBQUEsUUFDSTtBQUFBLFVBQ0ksR0FBRztBQUFBLFFBQ1A7QUFBQSxRQUNBO0FBQUEsVUFDSSxHQUFHO0FBQUEsVUFDSCxHQUFHO0FBQUEsUUFDUDtBQUFBLFFBQ0E7QUFBQSxNQUNKO0FBQUEsTUFDQTtBQUFBLFFBQ0k7QUFBQSxVQUNJLEdBQUc7QUFBQSxRQUNQO0FBQUEsUUFDQSxDQUFDO0FBQUEsUUFDRDtBQUFBLE1BQ0o7QUFBQSxNQUNBO0FBQUEsUUFDSTtBQUFBLFVBQ0ksR0FBRztBQUFBLFFBQ1A7QUFBQSxRQUNBO0FBQUEsVUFDSSxHQUFHO0FBQUEsUUFDUDtBQUFBLFFBQ0E7QUFBQSxNQUNKO0FBQUEsTUFDQTtBQUFBLFFBQ0ksQ0FBQztBQUFBLFFBQ0Q7QUFBQSxVQUNJLEdBQUc7QUFBQSxRQUNQO0FBQUEsUUFDQTtBQUFBLE1BQ0o7QUFBQSxNQUFHO0FBQUEsUUFDSCxDQUFDO0FBQUEsUUFD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QUEsSUFDTCxDQUFDO0FBQUEsRUFHTCxDQUFDOyIsCiAgIm5hbWVzIjogWyJBc3NlcnRpb25FcnJvciIsICJleHRlbmQiLCAiZ2xvYmFsIiwgIkFzc2VydGlvbkVycm9yIiwgImdsb2JhbCIsICJleHBvcnRzIiwgIm9iaiIsICJ0cnVuY2F0ZSIsICJnZXRBcnJheU5hbWUiLCAiaXNOYU4iLCAiZXNjYXBlIiwgImdldFByb21pc2VWYWx1ZSIsICJCb29sZWFuIiwgIldlYWtTZXQiLCAiV2Vha01hcCIsICJEYXRhVmlldyIsICJBcnJheUJ1ZmZlciIsICJpbnNwZWN0Q3VzdG9tIiwgImNvbmZpZyIsICJjb25maWciLCAiaXNQcmltaXRpdmUiLCAiY29uZmlnIiwgImNoYWkiLCAiY29uZmlnIiwgImNoYWkiLCAiY2hhaSIsICJjaGFpIiwgImNoYWkiLCAiY2hhaSIsICJhIiwgImlzTmFOIiwgImdldE9wZXJhdG9yIiwgImlzT2JqZWN0IiwgImNvbmZpZyIsICJ1dGlsIiwgIkFzc2VydGlvbkVycm9yIiwgIkFzc2VydGlvbiIsICJjaGFpIiwgIkFzc2VydGlvbiIsICJBc3NlcnRpb25FcnJvciIsICJhIiwgIm1hdGNoSWR4IiwgImNoYWkiLCAidXRpbCIsICJjaGFpIiwgInV0aWwiLCAiQXNzZXJ0aW9uIiwgInNob3VsZCIsICJjaGFpIiwgInV0aWwiLCAiQXNzZXJ0aW9uIiwgImFzc2VydCIsICJ1dGlsIiwgImNvbmZpZyIsICJjb3JlIiwgImV4cGVjdCIsICJzaG91bGQiLCAiYXNzZXJ0IiwgInJlcXVpcmVfY2hhaSIsICJhIiwgInN5bWJvbCIsICJkb2N1bWVudCIsICJ3aW5kb3ciLCAiZG9jdW1lbnQiLCAiaW5pdF9sb2NhbGUiLCAibmF2aWdhdG9yIiwgImluaXQiLCAiYSIsICJpbml0X2NvbnN0YW50cyIsICJzeW1ib2wiLCAiaW5pdF9jb25zdGFudHMiLCAiaW5pdF9sb2NhbGUiLCAiZCIsICJpbml0X2NvbnN0YW50cyIsICJjb25zb2xlIiwgImNvbmNhdCIsICJpbml0X2xvY2FsZSIsICJERUxJTUlURVIiLCAic2VsZiIsICJCdWZmZXJTb3VyY2VDb252ZXJ0ZXIiLCAiYSIsICJDb252ZXJ0IiwgImNvbWJpbmUiLCAicmV0QnVmIiwgInJldFZpZXciLCAiQm9vbGVhbiIsICJTZXQiLCAiX2EiLCAicmV0VmlldyIsICJ0ZW1wQnVmZmVyVmlldyIsICJBc25UeXBlVHlwZXMiLCAiQXNuUHJvcFR5cGVzIiwgImltcG9ydF9wdnRzdXRpbHMiLCAiQm9vbGVhbiIsICJfYSIsICJTZXQiLCAiZGVmYXVsdENvbnZlcnRlciIsICJfYSIsICJTZXQiLCAiU2V0IiwgImltcG9ydF9wdnRzdXRpbHMiLCAiZCIsICJpc0NvbnZlcnRpYmxlIiwgInNjaGVtYVN0b3JhZ2UiLCAiaW5pdF9pbmRleF9lcyIsICJKc29uUHJvcFR5cGVzIiwgImltcG9ydF9wdnRzdXRpbHMiLCAiT2JqZWN0SWRlbnRpZmllciIsICJpbml0X2luZGV4X2VzIiwgImZvcm1hdCIsICJFY1B1YmxpY0tleSIsICJFZFByaXZhdGVLZXkiLCAiRWRQdWJsaWNLZXkiLCAiQ3VydmVQcml2YXRlS2V5IiwgIkNyeXB0byIsICJhIiwgInByb2Nlc3MiLCAiaW1wb3J0X3B2dHN1dGlscyIsICJDcnlwdG9LZXkiLCAiQWVzQ2JjUHJvdmlkZXIiLCAiQWVzQ21hY1Byb3ZpZGVyIiwgIkFlc0N0clByb3ZpZGVyIiwgIkFlc0djbVByb3ZpZGVyIiwgIkFlc0t3UHJvdmlkZXIiLCAiQWVzRWNiUHJvdmlkZXIiLCAiUnNhUHJpdmF0ZUtleSIsICJSc2FQdWJsaWNLZXkiLCAiUnNhU3NhUHJvdmlkZXIiLCAiUnNhUHNzUHJvdmlkZXIiLCAiUnNhT2FlcFByb3ZpZGVyIiwgIkVjUHJpdmF0ZUtleSIsICJFY1B1YmxpY0tleSIsICJFY2RzYVByb3ZpZGVyIiwgIkVjZGhQcm92aWRlciIsICJFZFByaXZhdGVLZXkiLCAiRWRQdWJsaWNLZXkiLCAiRWREc2FQcm92aWRlciIsICJFY2RoRXNQcm92aWRlciIsICJQYmtkZjJQcm92aWRlciIsICJIbWFjUHJvdmlkZXIiLCAiSGtkZlByb3ZpZGVyIiwgIlNoYWtlMTI4UHJvdmlkZXIiLCAiU2hha2UyNTZQcm92aWRlciIsICJTdWJ0bGVDcnlwdG8iLCAiaW5pdF9pbmRleF9lcyIsICJjcnlwdG9fX2RlZmF1bHQiLCAiZm9ybWF0IiwgIl9hIiwgImdsb2JhbFJlZmVyZW5jZSIsICJzZWxmIiwgInNlbGYiLCAiaW5pdF9jb25zdGFudHMiLCAiYSIsICJpbnRlcm5hbCIsICJkb2N1bWVudCIsICJpbml0X2NvbnN0YW50cyIsICJkb2N1bWVudCIsICJIVE1MVGVtcGxhdGVFbGVtZW50IiwgIkRvY3VtZW50RnJhZ21lbnQiLCAiRG9jdW1lbnQiLCAiaW5pdF9jb25zdGFudHMiLCAiYSIsICJkaWZmIiwgImRvY3VtZW50IiwgInNlbGYiLCAidmFsdWUiLCAiZSIsICJpIiwgInN5bWJvbCIsICJpbml0X2NvbnN0YW50cyIsICJzZWxmIiwgInNlbGYiLCAiZCIsICJjdXN0b21FbGVtZW50cyIsICJpbml0X2NvbnN0YW50cyIsICJkb2N1bWVudCIsICJ3aW5kb3ciLCAibm9kZSIsICJhZGRlZE5vZGVzIiwgImEiLCAiZGVmaW5lIiwgInNlbGYiLCAiaW5pdF9jb25zdGFudHMiLCAiaW50ZXJuYWxDb3VudGVyIiwgImNoYWkiLCAiYSIsICJkIiwgInJhbmRvbSIsICJhIiwgImEiLCAic2VsZiIsICJzZWxmIiwgImRpZmYiLCAiYSIsICJhIiwgImEiLCAiY29uc29sZSIsICJhIiwgImEiLCAiaGFuZGxlciIsICJzZWxmIiwgInZlcnNpb24iLCAiYSIsICJtb25zdGVyVmVyc2lvbiIsICJ3aW5kb3ciLCAiaW5pdF9jb25zdGFudHMiLCAic2VsZiIsICJkb2N1bWVudCIsICJjaGFpIiwgImluaXQiLCAiZXhwZWN0IiwgImV4cGVjdCIsICJleHBlY3QiLCAiaW5pdF9jb25zdGFudHMiLCAiY3JlYXRlRWxlbWVudCIsICJzZWxmIiwgImRvY3VtZW50IiwgImV4cGVjdCIsICJleHBlY3QiLCAiaW5pdF9jb25zdGFudHMiLCAiY3JlYXRlRWxlbWVudCIsICJhcHBlbmRUb0RvY3VtZW50IiwgInNlbGYiLCAiZG9jdW1lbnQiLCAiZXhwZWN0IiwgImZldGNoUmVmZXJlbmNlIiwgIm11dGF0aW9ub2JzZXJ2ZXIiLCAiYWRkZWROb2RlcyIsICJleHBlY3QiLCAiZSIsICJpbml0T3B0aW9uc0Zyb21BdHRyaWJ1dGVzIiwgImdsb2JhbCIsICJhIiwgImV4cGVjdCIsICJkIiwgInYiLCAiYSIsICJpbml0X2xvY2FsZSIsICJhIiwgImluaXRfY29uc3RhbnRzIiwgImV4cGVjdCIsICJodG1sMSIsICJodG1sMiIsICJDdXN0b21FbGVtZW50IiwgInJlZ2lzdGVyQ3VzdG9tRWxlbWVudCIsICJkb2N1bWVudCIsICJhIiwgInYiLCAiZCIsICJLRVlfRE9DVU1FTlQiLCAid2luZG93UmVhZHkiLCAiZG9tUmVhZHkiLCAiZCIsICJhIiwgImV4cGVjdCIsICJDdXN0b21FbGVtZW50IiwgInJlZ2lzdGVyQ3VzdG9tRWxlbWVudCIsICJkb2N1bWVudCIsICJjb250cm9sIiwgImh0bWwxIiwgImh0bWwyIiwgImh0bWwzIiwgInN5bWJvbCIsICJhIiwgImQiLCAiUmVzb3VyY2UiLCAic2VsZiIsICJwYXJzZU9wdGlvbnNKU09OIiwgImluaXRfY29uc3RhbnRzIiwgInNlbGYiLCAiZmV0Y2hSZWZlcmVuY2UiLCAiZCIsICJkIiwgImluaXRfY29uc3RhbnRzIiwgImV4cGVjdCIsICJodG1sMSIsICJDdXN0b21Db250cm9sIiwgInJlZ2lzdGVyQ3VzdG9tRWxlbWVudCIsICJkb2N1bWVudCIsICJtIiwgImQiLCAiaW5pdF9jb25zdGFudHMiLCAiYSIsICJkIiwgInBhcnNlT3B0aW9uc0pTT04iLCAic2VsZiIsICJzZWxmIiwgInNlbGYiLCAic2VsZiIsICJzZWxmIiwgInNlbGYiLCAiV2ViQ29ubmVjdCIsICJzZWxmIiwgInRlc3RVcmwiLCAiV2ViQ29ubmVjdCIsICJjbG9uZSIsICJzZWxmIiwgImluaXQiLCAiZmV0Y2hSZWZlcmVuY2UiLCAicmVzb2x2ZSIsICJyZWplY3QiLCAiYSIsICJpIiwgImQiLCAiYSIsICJkIiwgImEiLCAiYiIsICJjIiwgImQiLCAiaHRtbDEiLCAiZCIsICJhIiwgIk5vZGVMaXN0IiwgInNlbGYiLCAiTm9kZSIsICJOb2RlIiwgIk5vZGVMaXN0IiwgInNlbGYiLCAiTm9kZSIsICJOb2RlTGlzdCIsICJOb2RlTGlzdCIsICJhIiwgImEiLCAiYSIsICJodG1sMSIsICJkIiwgImEiLCAic2VsZiIsICJhIiwgImEiLCAiYSIsICJOb2RlTGlzdCIsICJOb2RlIiwgImEiLCAiZCIsICJhIiwgImEiLCAiYSIsICJkIiwgImEiLCAiYSIsICJhIiwgImEiLCAiUmFuZG9tSUQiLCAiVVVJRCIsICJhIiwgImEiLCAiYSIsICJOb2RlTGlzdCIsICJOb2RlIiwgIk5vZGVMaXN0IiwgIk5vZGUiLCAiTm9kZSIsICJOb2RlTGlzdCIsICJGb3JtYXR0ZXIiLCAic2VsZiIsICJGb3JtYXR0ZXIiLCAiYSIsICJhIiwgImQiLCAiaW5pdF9jb25zdGFudHMiLCAiaHRtbDEiLCAidHJhbnNsYXRpb25zTGlua1N5bWJvbCIsICJnbG9iYWwiLCAiZ2xvYmFsIiwgImh0bWwxIiwgImUiLCAiaHRtbDEiXQp9Cg==